Informácie ku cvičeniam 5 a 6
Odporúčam navštíviť nasledujúce stránky:- http://nehe.gamedev.net/
- OpenGL API Documentation Overview
- Computer Programming Tutorials - OpenGL Tutorials
Niekoľko pomôcok k OpenGL
Pri práci s OpenGL je potrebné si uvedomiť, že každý príkaz sa aplikuje okamžite, či už sa jedná o maticové transformácie, vykresľovanie alebo zmena iných vlastností. Od momentu, kedy sa nejaká vlastnosť nastaví, používa sa, až kým sa opäť nezmení. Ďalší dôležitý fakt je ten, že OpenGL používa pravotočívú vzťažnú sústavu, kde bod [0,0,0] je stred obrazovky, os x rastie smerom doprava, os y smerom hore a os z smerom k pozorovateľovi (viac napríklad tu)
Nastavenie farby
glColor3f(R,G,B);
Nastavenie (zresetovanie) aktívnej matice na identitu
glLoadIdentity();
Posun (translácia) a otočenie (rotácia)
glTranslatef(OS_X,OS_Y,OS_Z); glRotatef(UHOL,OS_X,OS_Y,OS_Z);
Uloženie aktívnej matice do zásobníka a jej následne vytiahnutie
glPushMatrix(); ... kreslenie, zmena matice ... glPopMatrix();
Vykreslenie trojuholníka
glBegin(GL_TRIANGLES); glVertex3f(X,Y,Z); glVertex3f(X,Y,Z); glVertex3f(X,Y,Z); glEnd();
Vykreslenie štvoruholníka
glBegin(GL_QUADS); glVertex3f(X,Y,Z); glVertex3f(X,Y,Z); glVertex3f(X,Y,Z); glVertex3f(X,Y,Z); glEnd();
Zneviditeľnenie odvrátených strán
glCullFace(GL_BACK); glEnable(GL_CULL_FACE);
Aktivácia Z-buffera
ugli_set(AGL_Z_DEPTH,16); ... ugli_gfx ... glDepthFunc(GL_LEQUAL); glEnable(GL_DEPTH_TEST);
Natiahnutie textúry
ugli_texture_filters(GL_LINEAR_MIPMAP_LINEAR,GL_LINEAR_MIPMAP_LINEAR); GLuint stena=ugli_texture("stena.jpg",1); GLuint podstava=ugli_texture("podstava.jpg",1);
Nastavenie aktívnej textúry
glBindTexture(GL_TEXTURE_2D,podstava);
Nastavenie koordinátov textúry pre konkrétny vrchol
glTexCoord2f(X,Y);
Používanie multitextúr
glActiveTextureARB(GL_TEXTURE0_ARB); glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D,prva); glActiveTextureARB(GL_TEXTURE1_ARB); glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D,druha); ... kód ... glMultiTexCoord2fARB(GL_TEXTURE0_ARB,X1,Y1); glMultiTexCoord2fARB(GL_TEXTURE1_ARB,X2,Y2); glVertex3f(X,Y,Z);
Zapnutie hmly
GLfloat fogColor[4]={1.0f,1.0f,1.0f,1.0f}; glClearColor(fogColor[0],fogColor[1],fogColor[2],fogColor[3]); // TYPE = GL_EXP alebo GL_EXP2 alebo GL_LINEAR glFogi(GL_FOG_MODE,TYPE); glFogfv(GL_FOG_COLOR,fogColor); glFogf(GL_FOG_DENSITY,0.5f); glHint(GL_FOG_HINT,GL_DONT_CARE); glFogf(GL_FOG_START,NEAR); glFogf(GL_FOG_END,NEAR); glEnable(GL_FOG);
Nastavenie parametrov pre konkrétne svetlo
GLfloat farba_ambient[4]={1.0f,1.0f,1.0f,1.0f}; GLfloat farba_diffuse[4]={1.0f,1.0f,1.0f,1.0f}; GLfloat pozicia[4]={X,Y,Z,1.0f}; glLightfv(GL_LIGHT0,GL_AMBIENT,farba_ambient); glLightfv(GL_LIGHT0,GL_DIFFUSE,farba_diffuse); glLightfv(GL_LIGHT0,GL_POSITION,pozicia); glEnable(GL_LIGHT0);
Zapnutie osvetlenia
glEnable(GL_LIGHTING);
Zapnutie normalizácie normál
glEnable(GL_NORMALIZE);
Zadanie normály pre vrchol alebo celú stenu
glNormal3f(X,Y,Z);
Načítanie a zobrazenie objektu zo súboru
OBJEKT o=ugli_load_object("socha.ugro"); ... ugli_loop, glLoadIdentity() ... for(int ax=-13;ax<=13;ax+=2){ for(int az=-13;az<=13;az+=2){ if(abs(ax+az)%7==abs(ax-az)%5){ glTranslatef(ax,0,az); ugli_draw_object(&o); glTranslatef(-ax,0,-az); } } }
Konverzia objektu do buffrov pre rozšírenie GL_ARB_vertex_buffer_object a ich vykreslenie
/* Overime, ci je podporovane toto rozsirenie */ ugli_ext_vbo(); GLfloat *buf_v,*buf_m,*buf_n; /* Buffer pre vertexy - tri suradnice pre kazdy vrchol */ buf_v=(GLfloat *)malloc(sizeof(GLfloat)*3*o.stena.size()*3); /* Buffer pre mapovanie textury - dve suradnice pre kazdy vrchol */ buf_m=(GLfloat *)malloc(sizeof(GLfloat)*2*o.stena.size()*3); /* Buffer pre normaly - tri suradnice pre kazdy vrchol */ buf_n=(GLfloat *)malloc(sizeof(GLfloat)*3*o.stena.size()*3); /* Ideme skonvertovat objekt do buffrov vhodnych pre graficku kartu */ int num=0; for(uint32_t j=0;j < o.stena.size();j++){ for(uint32_t i=0;i < o.stena[j].pocetBodov;i++){ BOD v=o.stena[j].bod[i]; buf_v[num*3+0]=v.x; buf_v[num*3+1]=v.y; buf_v[num*3+2]=v.z; buf_m[num*2+0]=v.u; buf_m[num*2+1]=v.v; buf_n[num*3+0]=o.stena[j].nx; buf_n[num*3+1]=o.stena[j].ny; buf_n[num*3+2]=o.stena[j].nz; num++; } } /* Zadefinujeme identifikatory, ktore budu ukazovat na nase buffre, podobne, ako je to pri texturach */ GLuint array_v,array_m,array_n; /* Napchame buffre do pamate grafickej karty */ glGenBuffersARB(1,&array_v); glBindBufferARB(GL_ARRAY_BUFFER_ARB,array_v); glBufferDataARB(GL_ARRAY_BUFFER_ARB,num*3*sizeof(GLfloat),buf_v,GL_STATIC_DRAW_ARB); glGenBuffersARB(1,&array_m); glBindBufferARB(GL_ARRAY_BUFFER_ARB,array_m); glBufferDataARB(GL_ARRAY_BUFFER_ARB,num*2*sizeof(GLfloat),buf_m,GL_STATIC_DRAW_ARB); glGenBuffersARB(1,&array_n); glBindBufferARB(GL_ARRAY_BUFFER_ARB,array_n); glBufferDataARB(GL_ARRAY_BUFFER_ARB,num*3*sizeof(GLfloat),buf_n,GL_STATIC_DRAW_ARB); /* Buffre uz nie su potrebne, kedze ich obsah uz bol prekopirovany do grafickej karty */ free(buf_v); free(buf_m); free(buf_n); /* Aktivujeme buffer s vertexami */ glEnableClientState(GL_VERTEX_ARRAY); glBindBufferARB(GL_ARRAY_BUFFER_ARB,array_v); glVertexPointer(3,GL_FLOAT,0,(char *)NULL); /* Aktivujeme buffer s mapovacimi koordinatmi pre textury */ glEnableClientState(GL_TEXTURE_COORD_ARRAY); glBindBufferARB(GL_ARRAY_BUFFER_ARB,array_m); glTexCoordPointer(2,GL_FLOAT,0,(char *)NULL); /* Aktivujeme buffer s normalami */ glEnableClientState(GL_NORMAL_ARRAY); glBindBufferARB(GL_ARRAY_BUFFER_ARB,array_n); glNormalPointer(GL_FLOAT,0,(char *)NULL); ... ugli_loop, glLoadIdentity() ... /* Hotovo, mozeme vykreslovat */ glDrawArrays(GL_TRIANGLES,OD_KTOREJ_STENY,DO_KTOREJ_STENY);