IZG cviˇcen´ı 6. - Zobrazov´an´ı 3D sc´eny a z´aklady OpenGL Tom´aˇs Milet ´ Ustav poˇ c´ıtaˇ cov´ e grafiky a multim´ edi´ı Fakulta informaˇ cn´ıch technologi´ı Vysok´ e uˇ cen´ı technick´ e Brno
IZG cviˇ cen´ı 6. - Zobrazov´ an´ı 3D sc´ eny a z´ aklady OpenGL
1 / 38
Zobrazov´an´ı 3D sc´eny
• Jak je reprezentov´ ana sc´ena? • Jak ji zobrazit na monitor? • Co je to OpenGL?
IZG cviˇ cen´ı 6. - Zobrazov´ an´ı 3D sc´ eny a z´ aklady OpenGL
2 / 38
Reprezentace sc´eny • Povrchov´ a reprezentace - vektorov´a data.
IZG cviˇ cen´ı 6. - Zobrazov´ an´ı 3D sc´ eny a z´ aklady OpenGL
3 / 38
Reprezentace sc´eny • OpenGL pracuje s vrcholy - Vertexy • Jeden Vertex m˚ uˇze obsahovat nˇekolik r˚ uzn´ych atribut˚ u
(pozice, barva, ˇcas, hmotnost, texturovac´ı koordin´aty,...) • Nˇ ekolik Vertex˚ u tvoˇr´ı jedno primitivum - bod, u´seˇcka,
troj´uheln´ık,...
Jeden Vertex obsahuje 5 atributu 1. atribut je složen ze 3 složek ... Vertex Buffer Object (VBO) obsahuje seznam Vertexu IZG cviˇ cen´ı 6. - Zobrazov´ an´ı 3D sc´ eny a z´ aklady OpenGL
4 / 38
Zobrazen´ı sc´eny • Jak pˇrev´ est vektorov´a data na rastrov´y obr´azek?
Rasterizace! • Jak h´ ybat s objekty? Transformace!
Transformace/ Projekce
Rasterizace
3D vektorová grafika
2D vektorová grafika
Per Fragment Operace/ Zápis do Framebufferu
Zpracování fragmentů
fragmenty
IZG cviˇ cen´ı 6. - Zobrazov´ an´ı 3D sc´ eny a z´ aklady OpenGL
5 / 38
Zobrazen´ı sc´eny
• Novˇ ejˇs´ı GPU maj´ı nˇekter´e ˇc´asti programovateln´e.
Transformace/ Projekce 3D vektorová grafika
Per Fragment Operace/ Zápis do Framebufferu
Rasterizace
Vertex Shader Programovatelné
2D vektorová grafika
Zpracování fragmentů Fragment Shader fragmenty
IZG cviˇ cen´ı 6. - Zobrazov´ an´ı 3D sc´ eny a z´ aklady OpenGL
6 / 38
Pˇr´ıklad - Vertex Shaderu - jazyk GLSL
Position Vertex Atributy Coord
View
*
*
VS
*
gl_Position vIntensity vCoord
...
Vertexy
Projecion
Model
Uniformy
Primitive assembly
Primitiva
#version 330 //atributy in vec3 Position;//souradnice vertexu in vec2 Coord;//texturovaci koordinaty vertexu //uniformy uniform mat4 Model,View,Projection;//transformacni matice //preposilani do fragment shaderu out vec2 vCoord; out float vIntensity; void main(){ gl_Position=Projection*View*Model*vec4(Position,1);//transformace pozice vCoord=Coord;//preposlani texturovacich koordinat do fragment shaderu vIntensity=.5;//nejaka intenzita } IZG cviˇ cen´ı 6. - Zobrazov´ an´ı 3D sc´ eny a z´ aklady OpenGL
7 / 38
Interpolace
fragmenty
IZG cviˇ cen´ı 6. - Zobrazov´ an´ı 3D sc´ eny a z´ aklady OpenGL
8 / 38
Barycentrick´e koordin´aty
IZG cviˇ cen´ı 6. - Zobrazov´ an´ı 3D sc´ eny a z´ aklady OpenGL
9 / 38
Pˇr´ıklad - Fragment Shaderu - jazyk GLSL Texture
Uniformy
Rasterizér
fragmenty
FS
*
fragColor
atributy jsou interpolované z vertexů V1, V2, V3 podle pozice fragmentu v trojúhelníku
#version 330 //vystupy z vertex shaderu in vec2 vCoord;//preposlano z vertex shaderu a interpolovano in float vIntensity; //uniformy uniform sampler2D Texture; out vec4 fragColor;//sem budeme zapisovat barvu fragmentu void main(){ fragColor=vIntensity*texture(Texture,vCoord);//vycteni dat z textury } IZG cviˇ cen´ı 6. - Zobrazov´ an´ı 3D sc´ eny a z´ aklady OpenGL
10 / 38
OpenGL
• OpenGL je API pro 3D grafiku • OpenGL neum´ı vytvoˇrit okno - je potˇreba zvl´ aˇstn´ıch
knihoven • OpenGL um´ı pouze pˇrev´ est 3D objekty na 2D rastrov´y obr´azek
IZG cviˇ cen´ı 6. - Zobrazov´ an´ı 3D sc´ eny a z´ aklady OpenGL
11 / 38
OpenGL • OpenGL je architektura klient server • Aplikace bˇ eˇz´ı na CPU a vyuˇz´ıv´a OpenGL pro pˇr´ıstup k
GPU
IZG cviˇ cen´ı 6. - Zobrazov´ an´ı 3D sc´ eny a z´ aklady OpenGL
12 / 38
OpenGL API • Jednoduche rozhran´ı • Pouze C funkce • Data jsou jen ˇ c´ısla a pole ˇ • Z´ adn´e struct, class • Stavov´ y stroj • Vˇ etˇsina pˇr´ıkaz˚ u nastavuje stav pipeline • Stav se s´ am nemˇen´ı • OpenGL (Rendering) Context • Hlavn´ı objekt OGL • Mimo OpenGL (WGL/GLX) • Zapouzdˇruje data, stav, napojen´ı na v´ ystup
IZG cviˇ cen´ı 6. - Zobrazov´ an´ı 3D sc´ eny a z´ aklady OpenGL
13 / 38
OpenGL pipeline
Vertex Buffer Object, Vertex Shader, Primitive assembly, Rasterizace, Fragment Shader, Per Fragment Operace, Framebuffer. IZG cviˇ cen´ı 6. - Zobrazov´ an´ı 3D sc´ eny a z´ aklady OpenGL
14 / 38
OpenGL - vykreslov´an´ı
1 2 3 4
Vytvoˇren´ı okna s OpenGL kontextem (SDL) Nahr´an´ı dat na GPU Nastaven´ı pipeline Vykreslen´ı dat do framebufferu
IZG cviˇ cen´ı 6. - Zobrazov´ an´ı 3D sc´ eny a z´ aklady OpenGL
15 / 38
Nahr´an´ı dat na GPU - VBO
• Vrcholov´ a data (Vertexy) nahrajeme do Vertex Buffer
Object(VBO) • VBO obsahuje seznam Vertexu s atributy 1 2 3 4
Vytvoˇren´ı jm´ena VBO Vytvoˇren´ı VBO Alokov´an´ı dat VBO Nahr´an´ı dat do VBO
IZG cviˇ cen´ı 6. - Zobrazov´ an´ı 3D sc´ eny a z´ aklady OpenGL
16 / 38
VBO pˇr´ıklad float Data[]={0,0};//data, ktera budeme vkladat do bufferu GLuint VBO;//identifikator VBO glGenBuffers(1,&VBO);//vygenerujeme si identifikator glBindBuffer(GL_ARRAY_BUFFER,VBO);//aktivujeme a vytvorime VBO //alokujeme buffer a nahrajeme do nej data glBufferData(GL_ARRAY_BUFFER,sizeof(Data),Data,GL_STATIC_DRAW);
Zmˇena dat ve VBO. float*ptr;//ukazatel na data ptr=glMapBuffer(GL_ARRAY_BUFFER,GL_READ_WRITE);//ziskame jej ptr[0]=0.5;//nastavime hodnotu prvniho prvku glUnmapBuffer(GL_ARRAY_BUFFER);//odmapujeme buffer
Nebo pomoci glBufferSubData. glBufferSubData(GL_ARRAY_BUFFER, sizeof(float),//nahrajeme nova s offsetem jeden float sizeof(float),//nahrajeme jen jeden float Data);//data IZG cviˇ cen´ı 6. - Zobrazov´ an´ı 3D sc´ eny a z´ aklady OpenGL
17 / 38
Nastaven´ı pipeline pro vykreslov´an´ı
1 2 3
Zapnout shader program Nastavit uniformn´ı promˇenn´e Nastavit, odkud se budou br´at data pro vertexy
IZG cviˇ cen´ı 6. - Zobrazov´ an´ı 3D sc´ eny a z´ aklady OpenGL
18 / 38
Uniformn´ı promˇenn´e
• Uniformn´ı promˇ enn´e jsou konstantn´ı pro stovky primitiv
(textury, matice, ...) • Nastavuj´ı se pˇred vykreslov´ an´ım • Nastavuj´ı se pˇres ID z´ıskan´ e z Shader Programu //"Intensity" je identifikator uniformni promenne v Shader Programu GLuint IntensityID=glGetUniformLocation(Program,"Intensity");//ziskani ID glUniform1f(IntensityID,.4);//nastaveni uniformni promenne
IZG cviˇ cen´ı 6. - Zobrazov´ an´ı 3D sc´ eny a z´ aklady OpenGL
19 / 38
Nastaven´ı dat • Vertexy a jejich atributy jsou uloˇ zeny ve VBO(s) • Nˇ ekter´e atributy m˚ uˇzou b´yt zvl´aˇst’ v jin´ych VBO • Nˇ ekter´e atributy m˚ uˇzou b´yt prokl´adan´e 1 2 3
Nav´azat spr´avny VBO Povolit dan´y atribut Nastavit, jak je dan´y atribut ve VBO uloˇzen
glBindBuffer(GL_ARRAY_BUFFER,VBO);//aktivujeme spravny VBO //"Position" je identifikator atributu ve Vertex Shaderu GLuint attribPos=glGetAttribLocation(Program,"Position");//ziskame ID pozice glEnableVertexAttribArray(attribPos);//aktivujeme attribPos atribut glVertexAttribPointer( attribPos,//ID atributu 3,//pocet slozek atributu 3D vektor GL_FLOAT,//float type GL_FALSE,//nenormalizujeme sizeof(float)*5,//velikost vsech atributu v tomto VBO pro jeden vertex (GLvoid*)(sizeof(float)*2));//offset v atributech IZG cviˇ cen´ı 6. - Zobrazov´ an´ı 3D sc´ eny a z´ aklady OpenGL
20 / 38
Nastaven´ı dat - pˇr´ıklad
B
stride
2x float
1x float
A
3x float
3x float
informace o jednom vrcholu
C
D
pointer B pointer C pointer D VBO 0
1
2
3
4
5
...
IZG cviˇ cen´ı 6. - Zobrazov´ an´ı 3D sc´ eny a z´ aklady OpenGL
21 / 38
Nastaven´ı dat - pˇr´ıklad Vertex Shader: #version 330 in vec3 A;//souradnice vertexu in float B;//cas in vec3 C;//barva in vec2 D;//texturovaci koordinaty void main(){ //... }
Aplikace: GLint At=glGetAttribLocation(Shader,"A"); //... glEnableVertexAttribArray(At); //... glVertexAttribPointer(At,3,GL_FLOAT,GL_FALSE,sizeof(float)*9,(GLvoid*)0); glVertexAttribPointer(Bt,1,GL_FLOAT,GL_FALSE,sizeof(float)*9, (GLvoid*)(sizeof(float)*3)); glVertexAttribPointer(Ct,3,GL_FLOAT,GL_FALSE,sizeof(float)*9, (GLvoid*)(sizeof(float)*4)); glVertexAttribPointer(Dt,2,GL_FLOAT,GL_FALSE,sizeof(float)*9, (GLvoid*)(sizeof(float)*7)); IZG cviˇ cen´ı 6. - Zobrazov´ an´ı 3D sc´ eny a z´ aklady OpenGL
22 / 38
Vykreslen´ı dat Nastaven´ı dat 2 zavol´ an´ı vykresluj´ıc´ıho pˇr´ıkazu Aplikace: 1
glBindBuffer(GL_ARRAY_BUFFER,VBO);//navazani VBO GLint At=glGetAttribLocation(Shader,"Position");//ziskani ID z shaderu GLint Bt=glGetAttribLocation(Shader,"Coord");//ziskani ID z shaderu glEnableVertexAttribArray(At);//povoleni atributu pozice glEnableVertexAttribArray(Bt);//povoleni atributu tex. koordinat glVertexAttribPointer(At,3,GL_FLOAT,GL_FALSE,//nastaveni pointru pozice sizeof(float)*5,(GLvoid*)(sizeof(float)*0)); glVertexAttribPointer(Bt,2,GL_FLOAT,GL_FALSE,//nastaveni pointru koordinat sizeof(float)*5,(GLvoid*)(sizeof(float)*3)); glDrawArrays(//vykresleni GL_TRIANGLES,//typ primitiva 0,//prvni Vertex 3);//pocet Vertexu pro vykresleni 3 -> 1 trojuhelnik IZG cviˇ cen´ı 6. - Zobrazov´ an´ı 3D sc´ eny a z´ aklady OpenGL
23 / 38
´ Ukol
Budete upravovat pouze soubory ”main.c”, vertex shader ”sun.vp”a fragment shader ”sun.fp” 1 Nahran´ ı dat slunce na GPU a vykresleni (main.c) 2 Pokˇ riven´ı povrchu slunce a obarven´ı slunce (sun.vp, sun.fp) 3 Rozpohybov´ an´ı pokˇriven´ı a obarven´ı slunce (main.c, sun.vp, sun.fp)
IZG cviˇ cen´ı 6. - Zobrazov´ an´ı 3D sc´ eny a z´ aklady OpenGL
24 / 38
´ Ukol - aplikace po spuˇstˇen´ı
IZG cviˇ cen´ı 6. - Zobrazov´ an´ı 3D sc´ eny a z´ aklady OpenGL
25 / 38
´ Ukol 1.) - vykreslen´ı koule Soubor main.c //STUDENT DOPLNI 1.a) - nahrani pole Data na GPU //napoveda: glGenBuffers, glBindBuffer, glBufferData
//STUDENT DOPLNI 1.b) - ziskani cisla atributu do //AttribPosition z shader programu //napoveda: glGetAttribLocation
//STUDENT DOPLNI 1.c) - nastaveni ukazatelu na data a vykresleni slunce //musite: //1. nabindovat buffer //2. povolit vertex atribut //3. nastavit jak se data budou z bufferu cist //4. vykreslit trojuhelniky //napoveda: glBindBuffer,glEnableVertexAttribArray, glVertexAttribPointer, glDrawArrays IZG cviˇ cen´ı 6. - Zobrazov´ an´ı 3D sc´ eny a z´ aklady OpenGL
26 / 38
´ Ukol - aplikace po splnˇen´ı 1. u´kolu
IZG cviˇ cen´ı 6. - Zobrazov´ an´ı 3D sc´ eny a z´ aklady OpenGL
27 / 38
´ Ukol 1.) - voliteln´y, zobrazen´ı wireframe
Soubor main.c glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);
IZG cviˇ cen´ı 6. - Zobrazov´ an´ı 3D sc´ eny a z´ aklady OpenGL
28 / 38
´ Ukol - aplikace po splnˇen´ı voliteln´eho u´kolu
IZG cviˇ cen´ı 6. - Zobrazov´ an´ı 3D sc´ eny a z´ aklady OpenGL
29 / 38
´ Ukol 2.) - pouˇzit´ı textury jako v´yˇskov´e mapy Soubor sun.vp float r=1-0.03*Noise(Position*100+100,1.,1.7,.7,6u); //STUDENT UPRAVI 2.a) - posunuti vertexu podle sumu //Vertexy sunce lezi na kouli o polomeru 1 se stredem v (0,0,0) //Pozice vertexu je ulozena v promenne Position //pouzijte prom. r gl_Position=p*v*m*vec4(Position,1);
Soubor sun.fp float t=Noise(vPosition*100+100,1.,1.7,.7,6u); //STUDENT UPRAVI 2.b) - obarveni fragmentu podle sumu //vyuzijte prom. t a smichejte dve barvy (1,1,.4) (.4,0,0) pomoci //funkce mix fColor=vec4(1,0,0,0);//every fragment will be red
IZG cviˇ cen´ı 6. - Zobrazov´ an´ı 3D sc´ eny a z´ aklady OpenGL
30 / 38
´ Ukol - aplikace po splnˇen´ı 2. u´kolu
IZG cviˇ cen´ı 6. - Zobrazov´ an´ı 3D sc´ eny a z´ aklady OpenGL
31 / 38
´ Ukol - aplikace po splnˇen´ı 2. u´kolu
IZG cviˇ cen´ı 6. - Zobrazov´ an´ı 3D sc´ eny a z´ aklady OpenGL
32 / 38
´ Ukol 3.) - rozpohybov´an´ı slunce
Soubor main.c //STUDENT DOPLNI 3.a) - ziskani cisla uniformu z shader programu pro cas //napoveda: glGetUniformLocation
//STUDENT DOPLNI 3.b) - nastaveni uniformni promenne cas pomici prom. Time //napoveda: glUniform1f
IZG cviˇ cen´ı 6. - Zobrazov´ an´ı 3D sc´ eny a z´ aklady OpenGL
33 / 38
´ Ukol 3.) - rozpohybov´an´ı slunce Soubor sun.vp //STUDENT DOPLNI 3.c) - vytvoreni uniformni promenne pro cas (typ float)
//STUDENT UPRAVI 3.d) - pricteni k Position*100+100 vektor casu float r=1-0.03*Noise(Position*100+100,1.,1.7,.7,6u);
Soubor sun.fp //STUDENT DOPLNI 3.e) - vytvoreni uniformni promenne pro cas (typ float)
//STUDENT UPRAVI 3.f) - pricteni k Position*100+100 vektor casu float t=Noise(vPosition*100+100,1.,1.7,.7,6u);
IZG cviˇ cen´ı 6. - Zobrazov´ an´ı 3D sc´ eny a z´ aklady OpenGL
34 / 38
´ Ukol - v´ysledn´a aplikace
IZG cviˇ cen´ı 6. - Zobrazov´ an´ı 3D sc´ eny a z´ aklady OpenGL
35 / 38
´ Ukol - v´ysledn´a aplikace
IZG cviˇ cen´ı 6. - Zobrazov´ an´ı 3D sc´ eny a z´ aklady OpenGL
36 / 38
Zdroje informac´ı
• http://www.opengl.org/sdk/docs/ • http://www.opengl.org/documentation/glsl/
IZG cviˇ cen´ı 6. - Zobrazov´ an´ı 3D sc´ eny a z´ aklady OpenGL
37 / 38
Konec
Dˇekuji za pozornost
Ot´azky?
IZG cviˇ cen´ı 6. - Zobrazov´ an´ı 3D sc´ eny a z´ aklady OpenGL
38 / 38