Documente Academic
Documente Profesional
Documente Cultură
Texturarea n OpenGL
1. Definirea texturilor
n OpenGL se pot defini mai multe texturi (n general, la iniializarea programului) i
fiecare suprafa se textureaz folosind una din acestea. Fiecare textur (obiect textur texture object) are un nume unic n program i este definit printr-un set de date care permit
aplicarea acesteia pe suprafeele obiectului: adresa imaginii texturii, funcia de texturare
(modulare, nlocuire, combinare) i proprietile texturii (filtrri, mod de repetare etc.).
Texturarea poate fi validat sau invalidat prin apelul funciei glEnable(), respectiv
glDisable(), cu argument una din constantele GL_TEXTURE_1D sau GL_TEXTURE_2D pentru
texturi unidimensionale sau bidimensionale.
Posibilitatea de a manevra mai multe texturi n timpul execuiei, fr s fie necesar
ncrcarea sau generarea imaginii texturii de fiecare dat, mbuntete performanele de
texturare. Deoarece OpenGL este o interfa de programare scris n limbajul C, obiectele
textur sunt definite prin date i funcii separate, care trebuie specificate ntr-o anumit ordine:
1. generarea numelor texturilor;
2. crearea obiectelor de textur i conectarea lor (bind) la numele texturilor;
3. activarea unei texturi, pentru aplicarea acesteia primitivelor geometrice care urmeaz.
Numele texturilor
Numele texturilor sunt numere ntregi fr semn (de tipul GLuint) care sunt memorate
ntr-un vector transmis ca argument funciei:
void glGenTextures(GLsizei n, GLuint *textureNames);
Aceast funcie creeaz un vector de nume de texturi, unice n program, pe care le memoreaz
n vectorul textureNames. Numele create nu sunt neaprat numere succesive. Funcia
glGenTextures() creeaz numai numele texturilor i le marcheaz ca utilizate, dar obiectele
textur se creeaz numai la conectarea (bind) acestora.
Crearea texturilor
Funcia glBindTexture() se folosete att pentru crearea, ct i pentru utilizarea unei
texturi. Prototipul ei este:
void glBindTexture(GLenum target, GLuint textName);
Parametrul target poate avea ca valoare una din constantele simbolice GL_TEXTURE_1D sau
GL_TEXTURE_2D pentru texturi unidimensionale, respectiv bidimensionale. Argumentul
texName este numele unei texturi, generat de funcia glGenTextures() i memorat n vectorul
de nume ale texturilor. Atunci cnd este apelat prima oar pentru un nume de textur, funcia
glBindTexture() creeaz un nou obiect textur, cu toate datele referitoare la imaginea i
proprietile texturii implicate. Dup apelul funciei glBindTexture(), textura cu numele dat
ca argument devine textur curent i toate operaiile ulterioare, att pentru definirea unor
Laborator EGC - 11
proprieti ale texturii, ct i pentru aplicaia texturii, folosesc textura curent. Textura curent
se schimb prin apelul funciei glBindTexture().
Crearea imaginii de textur
Imaginea texturii este un tablou unidimensional sau bidimensional de texeli, fiecare
texel avnd una, dou, trei sau patru componente. Semnificaia componentelor texelilor se
stabilete la crearea imaginii texturii prin definirea formatului intern al imaginii printr-un
argument al uneia din funciile glTexImage1D(), glTexImage2D().
Texturile unidimensionale au o utilizare restrns. Ele sunt folosite pentru texturarea n
benzi, pentru care variaia culorii are o singur direcie. n continuare se vor prezenta texturile
bidimensionale, care sunt cel mai frecvent folosite. Funcia glTexImage2D() are urmtorul
prototip:
void glTexImage2D(GLenum target, GLint level,
GLint internalFormat, GLsizei width,
GLsizei height, GLint border,
GLenum format, GLenum type, const GLvoid *pixels);
glTexCoord1d(GLdouble s);
glTexCoord2d(GLdouble s, GLdouble t);
glTexCoord3d(GLdouble s, GLdouble t, GLdouble r);
glTexCoord4d(GLdouble s, GLdouble t, GLdouble r, GLdouble q);
glTexCoord1f(GLfloat s);
glTexCoord2f(GLfloat s, GLfloat t);
Laborator EGC - 11
aceste valori depesc intervalul [0,1], atunci textura poate fi repetat pe suprafa sau limitat
la intervalul [0,1]. Proprietatea unei texturi de a fi repetat sau limitat se stabilete prin apelul
uneia din funciile:
void glTexParameterf(GLenum target, GLenum pname, GLfloat param);
void glTexParameteri(GLenum target, GLenum pname, GLfloat param);
n aceste funcii, parametrul target reprezint tipul texturii i poate lua una din
constantele simbolice GL_TEXTURE_1D sau GL_TEXTURE_2D. Parametrul pname specific
numele simbolic al unei proprieti a texturii i poate lua una din constantele:
GL_TEXTURE_MIN_FILTER,
GL_TEXTURE_MAX_FILTER,
GL_TEXTURE_WRAP_S,
GL_TEXTURE_WRAP_T. Primele dou valori se refer la opiunile de filtrare ale texturii.
Urmtoarele valori seteaz proprietatea de repetare a texturii pentru coordonata s , respectiv t .
n acest caz, parametrul param poate fi GL_REPEAT pentru repetarea texturii, sau GL_CLAMP
pentru limitarea texturii n intervalul [0,1]. Mai multe aspecte privind definirea i folosirea
texturilor n OpenGL vor fi detaliate n exemplele care urmeaz.
Exemplul 1.
n acest exemplu este prezentat programul prin care se aplic texturi n tabl de ah
unor suprafee n spaiu. Imaginea capturat din fereastra afiat la execuia acestui program
este dat n fig. 18.
Laborator EGC - 11
glTexCoord2f(0.0,
glEnd();
glPopMatrix();
glPushMatrix();
glTranslated(0, 0, -8);
glRotated(-70, 1, 0, 0);
glBegin(GL_QUADS);
glTexCoord2f(0.0,
glTexCoord2f(0.5,
glTexCoord2f(0.5,
glTexCoord2f(0.0,
glEnd();
glPopMatrix();
0.0);
0.0);
1.0);
1.0);
n mod obinuit, imaginile texturilor se citesc din fiiere, dar texturile simple n tabl
de ah se pot genera prin program. Funcia MakeImages() creeaz dou tablouri de 64 64
locaii, fiecare fiind un vector cu patru componente R, G, B, A. n primul tablou (image4) este
creat o tabl cu 16 16 ptrate alternante de culoare alb sau neagr, fiecare ptrat de
dimensiune 4 4 texeli. n al doilea tablou (image8) este creat cu 8 8 ptrate alternante de
culoare alb i neagr, fiecare ptrat de dimensiune 8 8 texeli.
Texturile sunt definite n funcia init(). Mai nti se creeaz numele a dou texturi n
vectorul texName[2], prin funcia glGenTextures(). Pentru crearea i definirea proprietilor
fiecrei texturi, se conecteaz mai nti textura specificat prin numele ei (funcia
glBindTexture()) i apoi se specific proprietile texturii.
n funcia display() se utilizeaz texturile definite pentru texturarea unor primitive
geometrice. Textura care se aplic este textura curent, activat prin numele ei dat ca argument
funciei de conectare glBindTexture(). Ca urmare, primele dou suprafee sunt texturate cu
textura cu numele texName[1], iar a treia suprafa este texturat cu textura cu numele
texName[0], ceea ce se poate observa n imaginea din figura 18. ntr-un bloc glBegin()
glEnd() se transmit vrfurile unei primitive geometrice; pentru fiecare vrf se definesc mai
nti coordonatele de texturare (cu glTexCoord2f()) i apoi coordonatele spaiale ale vrfului
(cu glVertex3f()).
Exemplul 2
n acest exemplu se evideniaz folosirea stivei matricelor de texturare i modul de
repetare sau limitare a texturii. Programul este o versiune uor modificat a programului din
exemplul precedent. n continuare sunt redate (parial) numai funciile care s-au modificat:
init(), display() i reshape().
void init(void)
{
glClearColor (0.0, 0.0, 0.8, 1.0);
glShadeModel(GL_FLAT);
glEnable(GL_DEPTH_TEST);
glEnable(GL_CULL_FACE);
//texturare
MakeImages();
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glGenTextures(2, texName);
Laborator EGC - 11
void reshape(int w, int h)
{
glViewport(0, 0, (GLsizei) w, (GLsizei) h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(60.0, (GLfloat) w/(GLfloat) h, 0.1, 4000.0);
glMatrixMode(GL_TEXTURE);
glLoadIdentity();
glScaled(2,2,2);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
n funcia
reshape()
se selecteaz
stiva matricelor de texturare
(glMatrixMode(GL_TEXTURE)) i se introduce n vrful stivei o matrice de scalare
(glScaled(2.0, 2.0, 2.0)). Aceast transformare se aplic coordonatelor de texturare ale
celor dou suprafee desenate i deci aceste coordonate capt valorile (0,0), (0,2), (2,2), (2,0).
La depirea intervalului [0,1], textura este repetat sau limitat, n funcie de valoarea
parametrilor GL_TEXTURE_WRAP_S i GL_TEXTURE_WRAP_T a texturii. Prima textur este
limitat pe ambele coordonate s i t , cea de-a doua textur este limitat pe coordonata s i
repetat pe coordonata t . Imaginea din figura 19 evideniaz acest mod de aplicare a
texturilor.
Exemplul 4
S se textureze un poligon cu imaginea unei table de ah (image8 din exemplul 1). O
parte a acestei texturi se va nlocui cu o alt textur, ca n fig. 22. Se va concepe programul
astfel nct nlocuirea s se realizeze la apsarea unei taste i apsnd o alt tast s se revin
la imaginea iniial.
Laborator EGC - 11
Soluie. n program notm imaginea unei table de ah prin checkImage (image8 din exemplul
1) i imaginea de adugat prin subImage (image4 din exemplul 1 n care consider, rou cu
negru n loc de alb cu negru). Programul care realizeaz cerinele problemei, i care trebuie
completat, este urmtorul:
#include <GL/glut.h>
/* Creaz texturile tabl de ah */
#define checkImageWidth 64
#define checkImageHeight 64
#define subImageWidth 16
#define subImageHeight 16
static GLubyte checkImage[checkImageHeight][checkImageWidth][4];
static GLubyte subImage[subImageHeight][subImageWidth][4];
static GLuint texName;
void makeCheckImages(void)
{
int i, j, c;
for (i = 0; i < checkImageHeight; i++) {
for (j = 0; j < checkImageWidth; j++) {
c = ((((i&0x8)==0)^((j&0x8))==0))*255;
checkImage[i][j][0] = (GLubyte) c;
checkImage[i][j][1] = (GLubyte) c;
checkImage[i][j][2] = (GLubyte) c;
checkImage[i][j][3] = (GLubyte) 255;
}
}
for (i = 0; i < subImageHeight; i++) {
for (j = 0; j < subImageWidth; j++) {
c = ((((i&0x4)==0)^((j&0x4))==0))*255;
subImage[i][j][0] = (GLubyte) c;
subImage[i][j][1] = (GLubyte) 0;
subImage[i][j][2] = (GLubyte) 0;
subImage[i][j][3] = (GLubyte) 255;
}
}
}
10
11
Laborator EGC - 11
glTexSubImage2D(GL_TEXTURE_2D, 0, 12, 44,
subImageWidth, subImageHeight, GL_RGBA,
GL_UNSIGNED_BYTE, subImage);
glutPostRedisplay();
break;
.......
}
}
12