Académique Documents
Professionnel Documents
Culture Documents
Texturas
Computao Grfica
Aulas prticas
Maro de 2010
ndice
ndice...................................................................................... ndice...................................................................................... 1 ................................................................ ................................................................ ......................................... 1. Introduo ......................................................................... 2 1.1 Descrio .............................................................................................2 1.2 Aces .................................................................................................2 ......................................................... 2. Texturas em OpenGL ......................................................... 3 2.1 2.2 2.3 2.4 Introduo............................................................................................3 Criao de texturas ...............................................................................4 Aplicao de texturas ............................................................................5 Parmetros/propriedades.......................................................................5
2.4.1 Ler uma Imagem ............................................................................................ 6 2.4.2 Modo de mapeamento ................................................................................... 6 2.4.3 Parmetros da textura (filtros e repeties) ....................................................... 7 2.4.4 Construir a textura .......................................................................................... 8 2.4.5 Aplicao de texturas..................................................................................... 9
2.5 Objectos Esfricos...............................................................................11 ................................................................ 3. Implementao ................................................................ 12 3.1 O que est implementado ...................................................................12 3.2 O que se pretende implementar ...........................................................12 3.3 Cdigo fornecido................................................................................12
Jh, bc, db
1. Introduo
Este trabalho tem como objectivo principal o estudo e a aplicao de texturas. Em concreto, pretende-se efectuar a integrao destes efeitos cena (mesa+chaleira+quadro) da aula anterior.
1.1
Descrio
Assume-se que so aplicadas texturas distintas a cada um dos objectos: mesa chaleira quadro Assume-se ainda que aplicada a cada uma das paredes uma textura (plano XY e plano YZ) assim como ao cho (plano XZ).
1.2
Aces
Alm disso numa das paredes (plano YZ) a textura deve ser definida custa de um azulejo (que se repete um determinado nmero de vezes). O quadro mostra, sucessivamente, um determinada imagem. assim, deve ser possvel ao utilizador: Modificar a posio do observador (tal como na aula anterior) Setas: Up, Down, Left, Right Alterar a imagem no quadro No programa apresentado: r ou R alterna entre as vrias imagens. Alterar o nmero de azulejos na parede No programa apresentado: t ou T incrementa o nmero de azulejos.
Jh, bc, db
2. Texturas em OpenGL
2.1 Introduo
No contexto de Computao Grfica, o mapeamento de texturas 2D consiste na aplicao de uma imagem sobre as faces de um objecto 3D. Uma textura uma imagem rectangular. Cada um dos pixeis de uma textura denominado de textel (por analogia com pixel de uma imagem). Em OpenGL existe o conceito de "objectos textura geridos pelo prprio OpenGL. No objectos textura", entanto, da responsabilidade do utilizador carregar as texturas a partir de ficheiros de imagem para um array na memria e, a parir desta, proceder criao de um objecto textura. O OpenGL copia e guarda a informao num formato conveniente, e devolve um identificador de textura para uso posterior. Em OpenGL podem ser criadas e coexistir vrias texturas, existindo no entanto a noo de "textura activa isto , a textura que est a ser usada no momento da textura activa", definio/alterao dos seus parmetros ou a que deve ser usada quando se procede ao desenho de um objecto com texturas. Sendo assim, as texturas em OpenGl no tm propriedades globais, mas sim cada uma possui as suas prprias propriedades. Antes de desenhar um objecto com uma textura, basta activar a textura correspondente, usando para o efeito o seu identificador, e depois proceder ao desenho do objecto. O uso de texturas requer a execuo de dois passos distintos: a criao e a aplicao da textura. Assume-se neste trabalho tratarem-se de texturas 2D.
Jh, bc, db
2.2
Criao de texturas
Para a sua criao devem-se realizar os seguintes passos:
textura
associandoassociando-o ando
ao
identificador
glBindTexture(GL_TEXTURE_2D, texture);
Jh, bc, db
2.3
Aplicao de texturas
Para a aplicao da textura preciso especificar a textura desejada e criar uma relao entre os vrtices da textura e o vrtice do polgono sobre os quais se desenha mapear a textura escolhida. Por exemplo:
glBindTexture(GL_TEXTURE_2D, texture); // activar a textura desejada glBegin(GL_QUADS); glTexCoord2f(0.0, 0.0); glVertex3f(x1, y1, z1); glTexCoord2f(1.0, 0.0); glVertex3f(x2, y2, z2); glTexCoord2f(1.0, 1.0); glVertex3f(x3, y3, z3); glTexCoord2f(0.0, 1.0); glVertex3f(x4, y4, z4); glEnd();
2.4
Parmetros/propriedades
Depois de se proceder identificao de um objecto textura (atravs da criao de um nome) para representar a imagem de textura.
Jh, bc, db
Jh, bc, db
1. Filtros
Caso as dimenses da textura no coincidam com as dimenses do objecto deve-se proceder a uma ampliao (MAG MAGNIFICATION) ou a uma reduo (MIN MINIMIZATION) da MAG MIN textura. Neste caso o OpenGL permite considerar dois tipos principais de tcnica na reduo/aumento da imagem: NEAREST/LINEAR. No primeiro (NEAREST) considerado simplesmente o pixel mais prximo, No segundo (LINEAR) efectuada uma mdia com os pixeis adjacentes. Assim o LINEAR mais perfeito, mas obviamente mais pesado computacionalmente. Os seguintes comandos implementam a reduo e ampliao LINEAR
2. Repetio/Corte Outra das propriedades possvel de especificar relaciona-se com a repetio da mesma textura na superfcie do objecto. O OpenGl permite distinguir essa repetio nas direces horizontal e vertical. Assim, caso de deseje efectuar a repetio (REPEAT da textura na horizontal e na REPEAT) REPEAT vertical deve-se efectuar (S a direco horizontal e T vertical) S
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
Caso no se deseje efectuar a repetio (CLAMP e a textura aplicada seja CLAMP), CLAMP apenas a original, faz-se
Jh, bc, db
Jh, bc, db
2.4. 2.4.5
Aplicao de texturas
Como se disse, em OpenGl existe o conceito de textura activa. Ou seja, depois de definidas as vrias texturas estas podem ser aplicadas a um objecto, activando a textura desejada para o efeito. Sempre que se deseje aplicar com um textura deve-se chamar a funo glBindTexture que permite definir a textura corrente (activa) Depois de activada definir (activa). (selecciona) a textura procede-se a sua aplicao ao objecto. Para a aplicao da textura preciso criar uma relao entre os vrtices da textura e os vrtices dos polgonos sobre os quais se desenha mapear a textura escolhida. Na figura seguinte as letras A, B, C e D definem os vrtices da textura e os vrtices A1, B1, C1 e D1 os vrtices de polgono 3D onde deve ser mapeada esta textura. O processo de mapeamento de texturas em OpenGL consiste em "aplicar" a imagem 2D sobre o polgono 3D de forma que os pontos A, B, C e D sejam mapeados sobre os pontos A1, B1, C1 e D1.
Para permitir a construo desta correspondncia entre a imagem 2D e o polgono 3D usa-se a funo glTexCoord2f antes da definio do ponto 3D. Por exemplo,
Jh, bc, db
glBindTexture(GL_TEXTURE_2D, texture); // activar a textura desejada glBegin(GL_QUADS); glTexCoord2f(0.0, 0.0); glVertex3f(x, y, z); glTexCoord2f(1.0,0.0); glVertex3f(x, y, z); glTexCoord2f(1.0, 1.0); glVertex3f(x, y, z); glTexCoord2f(0.0, 1.0); glVertex3f(x, y, z); glEnd();
Repeat/Clamp
Para que as aces de Repeat/Clamp necessrio que as dimenses da textura sejam superiores s do objecto. Para tal deve ser especificado coordenadas de textura superiores a 1. Por exemplo, considere-se uma textura base, como se ilustra a seguir:
Jh, bc, db
10
2.5
Objectos Esfricos
Para activar a aplicao da textura a um objecto tridimensional esfrico deve-se usar o conceito de qudricas em OpenGL. Segue-se, sem explicaes, o cdigo de como o conseguir:
glBindTexture(GL_TEXTURE_2D, textura); GLUquadricObj* s = gluNewQuadric ( ); gluQuadricDrawStyle ( s, GLU_FILL ); gluQuadricNormals ( s, GLU_SMOOTH ); gluQuadricTexture ( s, GL_TRUE ); gluSphere ( s, raioEsfera, numLONG, numLAT); gluDeleteQuadric ( s ); // seleco da textura a aplicar
Jh, bc, db
11
3. Implementao
3.1
3.2
3.3
Cdigo fornecido
#include #include #include #include <stdio.h> <math.h> "RgbImage.h" <GL/glut.h>
//--------------------------------- Definir cores #define BLACK 0.0, 0.0, 0.0, 1.0 #define PI 3.14159 //================================================================================ //===========================================================Variaveis e constantes //------------------------------------------------------------ Sistema Coordenadas GLfloat xC=15.0, yC=15.0, zC=30.0; GLint wScreen=800, hScreen=600; GLfloat mesa=3.0; GLfloat bule=1.3; GLfloat quad=6.0; GLfloat mesaP[]= {4, 0, 10}; GLfloat buleP[]= {4, 0, 10}; GLfloat quadP[]= {4, 4, 0.1};
//------------------------------------------------------------ Observador
Jh, bc, db
12
//------------------------------------------------------------ Texturas GLint repete=4; GLint maxR =20; GLint numQuadro =5; //================================================================================ //=========================================================================== INIT //------------------------------------------------------------ Texturas GLuint texture[4]; GLuint tex; RgbImage imag; void criaDefineTexturas() { //----------------------------------------- Mesa glGenTextures(1, &texture[0]); glBindTexture(GL_TEXTURE_2D, texture[0]); imag.LoadBmpFile("mesa.bmp"); glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); glTexImage2D(GL_TEXTURE_2D, 0, 3, imag.GetNumCols(), imag.GetNumRows(), 0, GL_RGB, GL_UNSIGNED_BYTE, imag.ImageData()); //----------------------------------------- Chaleira glGenTextures(1, &texture[1]); glBindTexture(GL_TEXTURE_2D, texture[1]); imag.LoadBmpFile("chaleira.bmp"); glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); glTexImage2D(GL_TEXTURE_2D, 0, 3, imag.GetNumCols(), imag.GetNumRows(), 0, GL_RGB, GL_UNSIGNED_BYTE, imag.ImageData()); //----------------------------------------- Parede z=0 glGenTextures(1, &texture[2]); glBindTexture(GL_TEXTURE_2D, texture[2]); imag.LoadBmpFile("parede.bmp"); glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); glTexImage2D(GL_TEXTURE_2D, 0, 3, imag.GetNumCols(), imag.GetNumRows(), 0, GL_RGB, GL_UNSIGNED_BYTE, imag.ImageData()); //----------------------------------------- Quadro1 glGenTextures(1, &texture[3]); glBindTexture(GL_TEXTURE_2D, texture[3]); imag.LoadBmpFile("jh.bmp"); glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); glTexImage2D(GL_TEXTURE_2D, 0, 3, imag.GetNumCols(),
Jh, bc, db
13
imag.GetNumRows(), 0, GL_RGB, GL_UNSIGNED_BYTE, imag.ImageData()); //???????????????????????????????????????????????? // Definicao das texturas //???????????????????????????????????????????????? } void init(void) { glClearColor(BLACK); glShadeModel(GL_SMOOTH); criaDefineTexturas( ); glEnable(GL_TEXTURE_2D); glEnable(GL_DEPTH_TEST); } void resizeWindow(GLsizei w, GLsizei h) { wScreen=w; hScreen=h; glutPostRedisplay(); } void drawScene(){ //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~Mesa glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D,texture[0]); glPushMatrix(); glTranslatef( mesaP[0], mesaP[1]+mesa/2, mesaP[2]); glRotatef ( 90, -1, 0, 0); GLUquadricObj* y = gluNewQuadric ( ); gluQuadricDrawStyle ( y, GLU_FILL ); gluQuadricNormals ( y, GLU_SMOOTH ); gluQuadricTexture ( y, GL_TRUE ); gluSphere ( y, 0.5*mesa, 150, 150); gluDeleteQuadric ( y ); glPopMatrix(); glDisable(GL_TEXTURE_2D); //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~Chaleira glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D,texture[1]); glPushMatrix(); glTranslatef(buleP[0], buleP[1]+mesa+bule/2, buleP[2]); glutSolidTeapot(bule); glPopMatrix(); glDisable(GL_TEXTURE_2D); //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~Quadro glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D,texture[3]); glPushMatrix(); glTranslatef(quadP[0], quadP[1], quadP[2]); glBegin(GL_QUADS); glTexCoord2f(0.0f,0.0f); glVertex3i( quad, 0, glTexCoord2f(1.0f,0.0f); glVertex3i( 0, 0, glTexCoord2f(1.0f,1.0f); glVertex3i( 0, quad, glTexCoord2f(0.0f,1.0f); glVertex3i( quad, quad, glEnd(); glPopMatrix(); glDisable(GL_TEXTURE_2D); //????????????????????????????????????????? // Actualizao da imagem do quadro //?????????????????????????????????????????? //????????????????????????????????????????? // Textura da parede x=0 (plano YZ) // Deve-se repetir um padrao //??????????????????????????????????????????
Jh, bc, db
14
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~Parede glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D,texture[2]); glPushMatrix(); glBegin(GL_QUADS); glTexCoord2f(0.0f,0.0f); glVertex3i( 0, 0, glTexCoord2f(1.0f,0.0f); glVertex3i( xC, 0, glTexCoord2f(1.0f,1.0f); glVertex3i( xC, yC, glTexCoord2f(0.0f,1.0f); glVertex3i( 0, yC, glEnd(); glPopMatrix(); glDisable(GL_TEXTURE_2D); } void display(void){
z=0
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~[ Apagar ] glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~[ Janela Visualizacao ] glViewport (0,0,wScreen, hScreen); //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~[ Projeccao] glMatrixMode(GL_PROJECTION); glLoadIdentity(); switch (defineProj) { case 1: gluPerspective(104.0, wScreen/hScreen, 0.1, zC); break; default: glOrtho (-xC,xC,-yC,yC,-zC,zC); break; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~[ Modelo+View(camera/observador) ] glMatrixMode(GL_MODELVIEW); glLoadIdentity(); gluLookAt(obsP[0], obsP[1], obsP[2], 0,0,0, 0, 1, 0); //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~[ Objectos ] drawScene(); //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~Actualizacao glutSwapBuffers(); } //======================================================= EVENTOS void keyboard(unsigned char key, int x, int y){ switch (key) { //--------------------------- Textura Repeticao case 'r': case 'R': break; //?????????????????????????????????????? // Implementar repeticao da textura //?????????????????????????????????????? //--------------------------- Textura do quadro case 't': case 'T': break; //?????????????????????????????????????? // Implementar alternar o quadro //?????????????????????????????????????? //--------------------------- Projeccao case 'q': case 'Q': defineProj=defineProj+1;
Jh, bc, db
15
defineProj=defineProj%2; glutPostRedisplay(); break; //--------------------------- Escape case 27: exit(0); break; } } void teclasNotAscii(int key, int x, int y){ if(key == GLUT_KEY_UP) if(key == GLUT_KEY_DOWN) if(key == GLUT_KEY_LEFT) if(key == GLUT_KEY_RIGHT) glutPostRedisplay(); } //======================================================= MAIN int main(int argc, char** argv){ glutInit(&argc, argv); glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH ); glutInitWindowSize (wScreen, hScreen); glutInitWindowPosition (100, 100); glutCreateWindow ("{jh,pjmm}@dei.uc.pt-CG (left,right,up,down, 'q') "); init(); glutSpecialFunc(teclasNotAscii); glutDisplayFunc(display); glutReshapeFunc(resizeWindow); glutKeyboardFunc(keyboard); glutMainLoop(); return 0; }
Jh, bc, db
16