IZG cvičení 6. - Zobrazování 3D scény a základy OpenGL Tomáš Milet Ústav počítačové grafiky a multimédíı Fakulta informačních technologíı Vysoké učení technické Brno IZG cvičení 6. - Zobrazování 3D scény a základy OpenGL 1 / 38
Zobrazování 3D scény Jak je reprezentována scéna? Jak ji zobrazit na monitor? Co je to OpenGL? IZG cvičení 6. - Zobrazování 3D scény a základy OpenGL 2 / 38
Reprezentace scény Povrchová reprezentace - vektorová data. IZG cvičení 6. - Zobrazování 3D scény a základy OpenGL 3 / 38
Reprezentace scény OpenGL pracuje s vrcholy - Vertexy Jeden Vertex může obsahovat několik různých atributů (pozice, barva, čas, hmotnost, texturovací koordináty,...) Několik Vertexů tvoří jedno primitivum - bod, úsečka, trojúhelník,... Jeden Vertex obsahuje 5 atributu 1. atribut je složen ze 3 složek... Vertex Buffer Object (VBO) obsahuje seznam Vertexu IZG cvičení 6. - Zobrazování 3D scény a základy OpenGL 4 / 38
Zobrazení scény Jak převést vektorová data na rastrový obrázek? Rasterizace! Jak hýbat 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čení 6. - Zobrazování 3D scény a základy OpenGL 5 / 38
Zobrazení scény Novější GPU mají některé části programovatelné. Transformace/ Projekce Rasterizace 3D vektorová grafika Vertex Shader Programovatelné 2D vektorová grafika Per Fragment Operace/ Zápis do Framebufferu Zpracování fragmentů Fragment Shader fragmenty IZG cvičení 6. - Zobrazování 3D scény a základy OpenGL 6 / 38
Příklad - Vertex Shaderu - jazyk GLSL Vertexy Position Vertex Atributy Coord Uniformy Model View Projecion * * * VS gl_position vintensity vcoord... 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čení 6. - Zobrazování 3D scény a základy OpenGL 7 / 38
Interpolace fragmenty IZG cvičení 6. - Zobrazování 3D scény a základy OpenGL 8 / 38
Barycentrické koordináty IZG cvičení 6. - Zobrazování 3D scény a základy OpenGL 9 / 38
Příklad - Fragment Shaderu - jazyk GLSL Uniformy Texture 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čení 6. - Zobrazování 3D scény a základy OpenGL 10 / 38
OpenGL OpenGL je API pro 3D grafiku OpenGL neumí vytvořit okno - je potřeba zvláštních knihoven OpenGL umí pouze převést 3D objekty na 2D rastrový obrázek IZG cvičení 6. - Zobrazování 3D scény a základy OpenGL 11 / 38
OpenGL OpenGL je architektura klient server Aplikace běží na CPU a využívá OpenGL pro přístup k GPU IZG cvičení 6. - Zobrazování 3D scény a základy OpenGL 12 / 38
OpenGL API Jednoduche rozhraní Pouze C funkce Data jsou jen čísla a pole Žádné struct, class Stavový stroj Většina příkazů nastavuje stav pipeline Stav se sám nemění OpenGL (Rendering) Context Hlavní objekt OGL Mimo OpenGL (WGL/GLX) Zapouzdřuje data, stav, napojení na výstup IZG cvičení 6. - Zobrazování 3D scény a základy OpenGL 13 / 38
OpenGL pipeline Vertex Buffer Object, Vertex Shader, Primitive assembly, Rasterizace, Fragment Shader, Per Fragment Operace, Framebuffer. IZG cvičení 6. - Zobrazování 3D scény a základy OpenGL 14 / 38
OpenGL - vykreslování 1 Vytvoření okna s OpenGL kontextem (SDL) 2 Nahrání dat na GPU 3 Nastavení pipeline 4 Vykreslení dat do framebufferu IZG cvičení 6. - Zobrazování 3D scény a základy OpenGL 15 / 38
Nahrání dat na GPU - VBO Vrcholová data (Vertexy) nahrajeme do Vertex Buffer Object(VBO) VBO obsahuje seznam Vertexu s atributy 1 Vytvoření jména VBO 2 Vytvoření VBO 3 Alokování dat VBO 4 Nahrání dat do VBO IZG cvičení 6. - Zobrazování 3D scény a základy OpenGL 16 / 38
VBO pří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ěna 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čení 6. - Zobrazování 3D scény a základy OpenGL 17 / 38
Nastavení pipeline pro vykreslování 1 Zapnout shader program 2 Nastavit uniformní proměnné 3 Nastavit, odkud se budou brát data pro vertexy IZG cvičení 6. - Zobrazování 3D scény a základy OpenGL 18 / 38
Uniformní proměnné Uniformní proměnné jsou konstantní pro stovky primitiv (textury, matice,...) Nastavují se před vykreslováním Nastavují se přes ID získané 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čení 6. - Zobrazování 3D scény a základy OpenGL 19 / 38
Nastavení dat Vertexy a jejich atributy jsou uloženy ve VBO(s) Některé atributy můžou být zvlášt v jiných VBO Některé atributy můžou být prokládané 1 Navázat správny VBO 2 Povolit daný atribut 3 Nastavit, jak je daný atribut ve VBO uložen 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čení 6. - Zobrazování 3D scény a základy OpenGL 20 / 38
Nastavení dat - příklad informace o jednom vrcholu 3x float 1x float 3x float 2x float A B stride C D pointer B pointer C pointer D VBO 0 1 2 3 4 5... IZG cvičení 6. - Zobrazování 3D scény a základy OpenGL 21 / 38
Nastavení dat - pří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čení 6. - Zobrazování 3D scény a základy OpenGL 22 / 38
Vykreslení dat 1 Nastavení dat 2 zavolání vykreslujícího příkazu Aplikace: 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čení 6. - Zobrazování 3D scény a základy OpenGL 23 / 38
Úkol 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řivení povrchu slunce a obarvení slunce (sun.vp, sun.fp) 3 Rozpohybování pokřivení a obarvení slunce (main.c, sun.vp, sun.fp) IZG cvičení 6. - Zobrazování 3D scény a základy OpenGL 24 / 38
Úkol - aplikace po spuštění IZG cvičení 6. - Zobrazování 3D scény a základy OpenGL 25 / 38
Úkol 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čení 6. - Zobrazování 3D scény a základy OpenGL 26 / 38
Úkol - aplikace po splnění 1. úkolu IZG cvičení 6. - Zobrazování 3D scény a základy OpenGL 27 / 38
Úkol 1.) - volitelný, zobrazení wireframe Soubor main.c glpolygonmode(gl_front_and_back,gl_line); IZG cvičení 6. - Zobrazování 3D scény a základy OpenGL 28 / 38
Úkol - aplikace po splnění volitelného úkolu IZG cvičení 6. - Zobrazování 3D scény a základy OpenGL 29 / 38
Úkol 2.) - použití textury jako výškové 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čení 6. - Zobrazování 3D scény a základy OpenGL 30 / 38
Úkol - aplikace po splnění 2. úkolu IZG cvičení 6. - Zobrazování 3D scény a základy OpenGL 31 / 38
Úkol - aplikace po splnění 2. úkolu IZG cvičení 6. - Zobrazování 3D scény a základy OpenGL 32 / 38
Úkol 3.) - rozpohybování 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čení 6. - Zobrazování 3D scény a základy OpenGL 33 / 38
Úkol 3.) - rozpohybování 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čení 6. - Zobrazování 3D scény a základy OpenGL 34 / 38
Úkol - výsledná aplikace IZG cvičení 6. - Zobrazování 3D scény a základy OpenGL 35 / 38
Úkol - výsledná aplikace IZG cvičení 6. - Zobrazování 3D scény a základy OpenGL 36 / 38
Zdroje informací http://www.opengl.org/sdk/docs/ http://www.opengl.org/documentation/glsl/ IZG cvičení 6. - Zobrazování 3D scény a základy OpenGL 37 / 38
Konec Děkuji za pozornost Otázky? IZG cvičení 6. - Zobrazování 3D scény a základy OpenGL 38 / 38