Rendering Seminář 1. Tomáš Milet, Tomáš Starka Ústav počítačové grafiky a multimédíı Fakulta informačních technologíı Vysoké učení technické Brno Rendering Seminář 1. 1 / 28
OpenGL OpenGL je architektura klient server Aplikace běží na CPU a využívá OpenGL pro přístup k GPU Rendering Seminář 1. 2 / 28
Reprezentace scény Povrchová reprezentace - vektorová data. Rendering Seminář 1. 3 / 28
Atlas textur http://www.scriptspot.com/3ds-max/scripts/ texture-atlas-generator Rendering Seminář 1. 4 / 28
Vy sledek Rendering Semina r 1. 5 / 28
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 Rendering Seminář 1. 6 / 28
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 Rendering Seminář 1. 7 / 28
VAO - použití glvertexattribbinding(gluint attribindex,gluint bindingindex); Vertex Shader layout(location = 0) vec4 position; layout(location = 2)ivec2 gridid; layout(location = 7)float velocity; void main(){... } Vertex Array Object... States Buffer, Offset, Stride,Type, Size,... Buffer, Offset, Stride,Type, Size,...... Buffer, Offset, Stride,Type, Size,... glvertexattribformat(glunit bindingindex,glint size,glenum type, GLboolean normalized, GLuint relativeoffset); glbindvertexbuffer(gluint bindingindex, GLuint buffer, GLintptr offset, GLsizei stride); Rendering Seminář 1. 8 / 28
VAO - příklad použití Aplikace - inicializace glgenvertexarrays(1,&vao);//vygenerovani jmena VAO glbindvertexarray(vao);//aktivovani VAO //nyni nastavime buffery a atributy glgenbuffers(1,&vbo); glbindbuffer(gl_array_buffer,vbo); glbufferdata(gl_array_buffer,sizeof(data),data,gl_static_draw); glgenbuffers(1,&ebo); glbindbuffer(gl_element_array_buffer,ebo); glbufferdata(gl_element_array_buffer,sizeof(index),index,gl_static_draw); glbindbuffer(gl_array_buffer,vbo); glenablevertexattribarray(vpos); glvertexattribpointer(vpos,2,gl_float,gl_false,sizeof(float)*5, (GLvoid*)(sizeof(float)*0)); glenablevertexattribarray(vcol); glvertexattribpointer(vcol,3,gl_float,gl_false,sizeof(float)*5, (GLvoid*)(sizeof(float)*2)); glbindvertexarray(0);//deaktivujeme VAO po tomto bode uz jej neovlivnujeme Rendering Seminář 1. 9 / 28
Nahrání rastrových dat - Textur Textura je rastrový obrázek, který se namapuje na geometrii. V OpenGL je to objekt. //vytvoreni jmena textury glgentextures(1,&tcolor);//vygenerovani jmeno textury pro barvu glbindtexture(gl_texture_2d,tcolor);//navazeme a vytvorime texturu //nastaveni parametru textury gltexparameteri(gl_texture_2d,gl_texture_mag_filter,gl_nearest); gltexparameteri(gl_texture_2d,gl_texture_min_filter,gl_nearest); //alokace a nahrani dat na GPU glteximage2d(gl_texture_2d,0,//alokujeme misto GL_RGBA32F,//format ulozeni na GPU (4*float pro pixel) WIDTH,HEIGHT,0,GL_RGBA,//format ulozeni dan na CPU GL_UNSIGNED_BYTE,//typ dat na CPU Data);//data na CPU Rendering Seminář 1. 10 / 28
Shader - vytvoření shaderu //rezervace id shaderu GLuint shader = glcreateshader(type); //pripojeni zdrojaku k shaderu glshadersource(shader,1,&string,null); //kompilace zdrojaku glcompileshader(shader); Rendering Seminář 1. 11 / 28
Shader Program - vytvoření programu GLuint program = glcreateprogram(); glattachshader(program,shader);... gllinkprogram(program); Rendering Seminář 1. 12 / 28
Vykreslení gluseprogram(program); glbindtextureunit(unit,texture); gluniform4fv(...) glbindvertexarray(vao);//aktivujeme VAO gldrawelements(gl_triangles,6,gl_unsigned_int,null); glbindvertexarray(0);//deaktivujeme VAO Rendering Seminář 1. 13 / 28
Shader Object Shader je jedna část shader programu Pro shader je potřeba rezervovat id, nahrát do něj zdrojové soubory a zkompilovat Shadery je možné sdílet mezi vícero shader programy 6 typu shaderu pro každou programovatelnou část Rendering Seminář 1. 14 / 28
Shader - vytvoření shaderu GLint getshaderparam(gluint id,glenum pname){ GLint params; glgetshaderiv(id,pname,¶ms);//ziskani parametru shaderu return params; } GLuint createshader(gluint type,std::string source){ GLuint id = glcreateshader(type);//rezervace id shaderu const char*string=source.c_str(); glshadersource(id,1,&string,null);//pripojeni zdrojaku k shaderu glcompileshader(id);//kompilace zdrojaku GLboolean compilestatus = getshaderparam(id,gl_compile_status); if(!compilestatus){ GLuint length = getshaderparam(id,gl_info_log_length); if(length){ std::string info(length, ); glgetshaderinfolog(id,length,null,(glchar*)info.c_str());//ziskani logu std::cerr<<info<<std::endl; } gldeleteshader(id);//uvolneni id shaderu id = 0; } return id; } Rendering Seminář 1. 15 / 28
Shader Program Object Shader program reprezentuje kolekci shaderů Pro program je potřeba rezervovat id, připojit shadery a slinkovat Ne všechny části pipeline musí být přítomny Rendering Seminář 1. 16 / 28
Shader Program - vytvoření programu template<typename...> void attachshaders(gluint){} template<typename... ARGS> void attachshaders(gluint program,gluint shader,args...args){ glattachshader(program,shader); attachshaders(program,args...); } template<typename... ARGS> GLuint createprogram(args...shaders){ GLuint id = glcreateprogram(); attachshaders(id,shaders...); gllinkprogram(id); glvalidateprogram(id); GLboolean linkstatus; glgetprogramiv(id,gl_link_status,(glint*)&linkstatus); if(!linkstatus){ GLuint length; glgetprogramiv(id,gl_info_log_length,(glint*)&length); if(length){ std::string info(length, ); glgetprograminfolog(id,length,null,(glchar*)info.c_str());//ziskani logu std::cerr<<info<<std::endl; } gldeleteprogram(id); id=0; } return id; } Rendering Seminář 1. 17 / 28
Zdroje informací https://www.opengl.org/sdk/docs/man/ www.khronos.org/files/ opengl45-quick-reference-card.pdf http://www.opengl.org/documentation/glsl/ http://www.geeks3d.com/20140321/ opengl-approaching-zero-driver-overhead/ Rendering Seminář 1. 18 / 28
Konec Děkuji za pozornost Otázky? Rendering Seminář 1. 19 / 28