/* * tg_image_textura.c * * Este programa ilustra o uso da funcao * glTex* para aplicar transformacoes geometricas * sobre uma imagem, aproveitando as facilidades * de interpolação e tratamento de sobreposição de amostras * * Ting (26/07/08) */ // #define _USE_MATH_DEFINES #include // Header File For The GLUT Library #include // Header File For The OpenGL32 Library #include // Header File For The GLu32 Library #include // Header file for standard file i/o. #include // Header file for malloc/free. #include // Header file for math functions. /* ascii code for the escape key */ #define ESCAPE 27 /* ascii code for the escape key */ #define ESCAPE 27 /* dimensoes da imagem */ #define ALTURA 256 #define LARGURA 256 GLubyte imagem[LARGURA][ALTURA]; GLubyte tg_imagem[LARGURA][ALTURA][3]; int win; // id da janela principal int swin1, swin2; // id das subjanelas do glut double m[3][3]; /*********************************************************************/ // Linhas: y; Colunas:x ([y][x]) void makeCheckImage(void) { int i, j, c; for (i = 0; i < LARGURA; i++) { for (j = 0; j < ALTURA; j++) { c = (((i&0x8)==0)^((j&0x8)==0))*255; imagem[i][j] = (GLubyte) c; } } } /************************************************************************/ // OpenGL functions // void init(void) { glClearColor (0.0, 0.0, 0.0, 0.0); glShadeModel(GL_FLAT); makeCheckImage(); m[0][0] = m[1][1] = m[2][2] = 1.0; m[0][1] = m[0][2] = m[1][0] = m[1][2] = m[2][0] = m[2][1] = 0.0; glPixelStorei(GL_UNPACK_ALIGNMENT, 1); /* definir forma de mapeamento da textura */ glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); /* gerar mipmaps para evitar distorções */ gluBuild2DMipmaps (GL_TEXTURE_2D, GL_RGB, ALTURA, LARGURA, GL_LUMINANCE, GL_UNSIGNED_BYTE, imagem); /* setar o modo de texturização: GL_REPLACE (substitui os valores * do pixel), GL_DECAL (pondera com o parâmetro alfa da cor), * GL_MODULATE (multiplica o valor-destino com o valor-fonte) */ glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); } void main_display(void) { glClearColor(0.8, 0.8, 0.8, 0.0); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glColor3f(0.f, 0.f, 0.f); } void display_swin1() { // Desenhar os pixels da imagem glutSetWindow(swin1); glDisable(GL_DITHER); glClear(GL_COLOR_BUFFER_BIT); glRasterPos2i(0, 0); glDrawPixels(LARGURA, ALTURA, GL_LUMINANCE, GL_UNSIGNED_BYTE, imagem); glFlush(); } void display_swin2() { // Desenhar os pixels da imagem da transformada glutSetWindow(swin2); glClearColor(1.0, 0.0, 0.0, 0.0); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); /* habilitar a texturização */ glEnable(GL_TEXTURE_2D); glBegin(GL_POLYGON); glTexCoord2f (0,0); glVertex2f(m[2][0],m[2][1]); glTexCoord2f (1.0,0); glVertex2f(m[0][0]+m[2][0],m[0][1]+m[2][1]); glTexCoord2f(1.0,1.0); glVertex2f(m[0][0]+m[1][0]+m[2][0],m[0][1]+m[1][1]+m[2][1]); glTexCoord2f(1.0,0); glVertex2f(m[1][0]+m[2][0],m[1][1]+m[2][1]); glEnd(); glFlush(); glDisable(GL_TEXTURE_2D); } void main_reshape(int w, int h) { glViewport(0, 0, (GLsizei) w, (GLsizei) h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluOrtho2D(0.0, (GLdouble) w, 0.0, (GLdouble) h); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); /* redefinir a posição e as dimensões da sub-janela 1 */ glutSetWindow(swin1); glutPositionWindow(0, 0); glutReshapeWindow(LARGURA, ALTURA); /* redefinir a posição e as dimensões da sub-janela 2 */ glutSetWindow(swin2); glutPositionWindow(LARGURA, 0); glutReshapeWindow(LARGURA, ALTURA); } void reshape_swin1(int w, int h) { glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluOrtho2D(0.0, (GLfloat) LARGURA, 0.0, (GLfloat) ALTURA); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); } void reshape_swin2(int w, int h) { glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluOrtho2D(0.0, (GLfloat)1.0, 0.0, (GLfloat) 1.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); } void keyboard(unsigned char key, int x, int y) { switch (key) { case 's': // Scaling m[0][0] = m[1][1] = 1.5; m[2][2] = 1.0; m[0][1] = m[0][2] = m[1][0] = m[1][2] = m[2][0] = m[2][1] = 0.0; break; case 'r': // Rotation m[0][0] = m[1][1] = cos (M_PI_4); m[0][1] = sin (M_PI_4); m[1][0] = -m[0][1]; m[2][2] = 1.0; m[2][0] = -0.5*m[0][0] - 0.5*m[1][0] + 0.5; m[2][1] = -0.5*m[0][1] - 0.5*m[1][1] + 0.5; m[0][2] = m[1][2] = 0.0; break; case 'h': // Shearing m[0][0] = m[1][1] = m[2][2] = 1.0; m[1][0] = 0.4; m[0][1] = 0.6; m[0][2] = m[1][2] = m[2][0] = m[2][1] = 0.0; break; case 't': // Translation m[0][2] = m[1][2] = m[0][1] = m[1][0] = 0; m[0][0] = m[1][1] = m[2][2] = 1.0; m[2][0] = 0.2; m[2][1] = 0.2; break; case 27: exit(0); } // Forcar um evento que chame "display" // Atualizar o conteudo das sub-janelas display_swin2(); //glutPostRedisplay(); } /************************************************************************/ // Main configuration // int main(int argc, char** argv) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB ); glutInitWindowSize(LARGURA*2, ALTURA); glutInitWindowPosition(0,0); win = glutCreateWindow(argv[0]); glutDisplayFunc(main_display); glutReshapeFunc(main_reshape); glutKeyboardFunc(keyboard); swin1 = glutCreateSubWindow(win,0,0,LARGURA,ALTURA); glutReshapeFunc(reshape_swin1); glutDisplayFunc(display_swin1); glutKeyboardFunc(keyboard); swin2 = glutCreateSubWindow(win,LARGURA,0,LARGURA,ALTURA); glutReshapeFunc(reshape_swin2); glutDisplayFunc(display_swin2); glutKeyboardFunc(keyboard); init(); glutMainLoop(); return 0; }