Transformaciones con OpenGL
Pipeline:Transformaciones
Transformaciones! Las operaciones con matrices en OpenGL glmatrixmode( GLenum mode ); mode: GL_MODELVIEW, GL_PROJECTION, GL_TEXTURE Es utilizada para definir las coordenadas de vision, se asigna una matriz de 4x4 De igual manera, se define la proyección, como la imagen es proyectada sobre la pantalla, una matriz de 4X4
Transformaciones! Una alternativa, podemos asignar otros valores a los elementos de una matriz glloadidentity(); La matriz inicial, una matriz identidad de 4x4 glloadmatrix{f,d}( const TYPE* m ); glmultmatrix{f,d}( const TYPE* m ); glpushmatrix(); glpopmatrix(); Las operaciones de stack son muy utiles para construir estructuras jerarquicas. Ejemplo Hacer el render de un carro con cuatro ruedas
! glloadmatrix*( element16); glmatrixmode(gl_modelview); glfloat elems[16]; GLint k; for( k=0; k<16; k++) elems [k] = float (k); glloadmatrixf(elems);
M= 0.0 4.0 8.0 12.0 1.0 5.0 9.0 13.0 2.0 6.0 10.0 14.0 3.0 7.0 11.0 15.0
Composicion de Matrices! glmultmatrix*(otroelements16); M= MxM1 glmatrixmode(gl_modelview); glloadidentity( ); glmultmatrixf( elemsm2); glmultmatrixf( elemsm1); M=M2xM1
Transformaciones! OpenGL ofrece transformaciones preconstruidas : gltranslate{f,d}( TYPE x, TYPE, y, TYPE z ); Efecto de gltranslate()
Transformationes glrotate{f,d}( TYPE angle, TYPE x, TYPE y, TYPE z ); Efecto de glrotatef(45.0, 0.0, 0.0, 1.0)
Transformaciones glscale{f,d}( TYPE x, TYPE y, TYPE z); El efecto de glscalef(2.0, -0.5, 1.0)
Transformaciones! Rotando primero o Translación primero :
Transformaciones! Transformaciones de Visión Hay que seleccionar un sistema de Visión o de Camara Center-orientation-up system Aplicando glulookat.» glulookat( cx, cy, cz, atx, aty, atz, upx, upy, upz );» ( cx, cy, cz ) es la ubicación de la cámara» ( atx, aty, atz ) hacia donde ve la cámara» ( upx, upy, upz ) es el vector de orientación de la cámara Coordenadas Polares
Transformaciones! Transformaciones de Proyección: Proyección en Perspectiva glfrustum( GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble near, GLdouble far );
Transformaciones gluperspective( GLdouble fovy, GLdouble aspect, GLdouble near, GLdouble far );
Transformaciones! Transformación de Proyección: Proyección Ortogonal (Orthogonal projection) glortho( GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble near, GLdouble far ); gluortho2d( GLdouble left, GLdouble right, GLdouble bottom, GLdouble top );
Transformaciones! Transformación de Viewport glviewport( GLint x, GLint y, GLsizei w, GLsizei h );
Transformaciones! Nota: Por default, el observador esta situado en el origen, y mira hacia el eje negativo del eje-z
Ejemplo
Rotando un cubo con Interpolacion de Color #include <stdlib.h> #include <GL/glut.h> GLfloat vertices[][3] = {{-1.0,-1.0,-1.0}, {1.0,-1.0,-1.0}, {1.0,1.0,-1.0}, {-1.0,1.0,-1.0}, {-1.0,-1.0,1.0}, {1.0,-1.0,1.0}, {1.0,1.0,1.0}, {-1.0,1.0,1.0}}; GLfloat colors[][3] = {{0.0,0.0,0.0},{1.0,0.0,0.0}, {1.0,1.0,0.0}, {0.0,1.0,0.0}, {0.0,0.0,1.0}, {1.0,0.0,1.0}, {1.0,1.0,1.0}, {0.0,1.0,1.0}};
void polygon(int a, int b, int c, int d) { /* draw a polygon via list of vertices */ glbegin(gl_polygon); glcolor3fv(colors[a]); glvertex3fv(vertices[a]); glcolor3fv(colors[b]); glvertex3fv(vertices[b]); glcolor3fv(colors[c]); glvertex3fv(vertices[c]); glcolor3fv(colors[d]); glvertex3fv(vertices[d]); glend(); }
void colorcube() { /* map vertices to faces */ polygon(0,3,2,1); polygon(2,3,7,6); polygon(0,4,7,3); polygon(1,2,6,5); polygon(4,5,6,7); polygon(0,1,5,4); }
static GLfloat theta[] = {0.0,0.0,0.0}; static GLint axis = 2; void display() { /* display callback, clear frame buffer and z buffer, rotate cube and draw, swap buffers */ glclear(gl_color_buffer_bit GL_DEPTH_BUFFER_BIT); glloadidentity(); glrotatef(theta[0], 1.0, 0.0, 0.0); glrotatef(theta[1], 0.0, 1.0, 0.0); glrotatef(theta[2], 0.0, 0.0, 1.0); colorcube(); glflush(); glutswapbuffers(); }
void spincube() { /* idle callback, spin cube 2 degrees about selected axis */ theta[axis] += 2.0; if( theta[axis] > 360.0 ) theta[axis] -= 360.0; /* display(); */ glutpostredisplay(); } void mouse(int btn, int state, int x, int y) { /* mouse callback, selects an axis about which to rotate */ if(btn==glut_left_button && state == GLUT_DOWN) axis = 0; if(btn==glut_middle_button && state == GLUT_DOWN) axis = 1; if(btn==glut_right_button && state == GLUT_DOWN) axis = 2; }
void myreshape(int w, int h) { glviewport(0, 0, w, h); } glmatrixmode(gl_projection); glloadidentity(); if (w <= h) glortho(-2.0, 2.0, -2.0 * (GLfloat) h / (GLfloat) w, 2.0 * (GLfloat) h / (GLfloat) w, -10.0, 10.0); else glortho(-2.0 * (GLfloat) w / (GLfloat) h, 2.0 * (GLfloat) w / (GLfloat) h, -2.0, 2.0, -10.0, 10.0); glmatrixmode(gl_modelview);
int main(int argc, char **argv) { glutinit(&argc, argv); /* need both double buffering and z buffer */ } glutinitdisplaymode(glut_double GLUT_RGB GLUT_DEPTH); glutinitwindowsize(500, 500); glutcreatewindow("colorcube"); glutreshapefunc(myreshape); glutdisplayfunc(display); glutidlefunc(spincube); glutmousefunc(mouse); glenable(gl_depth_test); /* Enable hidden-surface removal */ glutmainloop();
Ejemplo! planet.c Control: d y a A ESC
#include <GL/glut.h> static GLfloat year=0.0f, day=0.0f; void init() { glclearcolor(0.0, 0.0, 0.0, 0.0); } void GL_reshape(GLsizei w, GLsizei h) // GLUT reshape function { glviewport(0, 0, w, h); // viewport transformation glmatrixmode(gl_projection); // projection transformation glloadidentity(); gluperspective(60.0, (GLfloat)w/(GLfloat)h, 1.0, 20.0); glmatrixmode(gl_modelview); // viewing and modeling transformation glloadidentity(); glulookat(0.0, 3.0, 5.0, // eye 0.0, 0.0, 0.0, // center 0.0, 1.0, 0.0); // up }
void GL_display() // GLUT display function { // clear the buffer glclear(gl_color_buffer_bit); } glcolor3f(1.0, 1.0, 1.0); glpushmatrix(); glutwiresphere(1.0, 20, 16); // the Sun glrotatef(year, 0.0, 1.0, 0.0); gltranslatef(3.0, 0.0, 0.0); glrotatef(day, 0.0, 1.0, 0.0); glutwiresphere(0.5, 10, 8); // the Planet glpopmatrix(); // swap the front and back buffers glutswapbuffers();
void GL_idle() // GLUT idle function { day += 10.0; if(day > 360.0) day -= 360.0; year += 1.0; if(year > 360.0) year -= 360.0; } // recall GL_display() function glutpostredisplay();
void GL_keyboard(unsigned char key, int x, int y) // GLUT keyboard function { switch(key) { case 'd': day += 10.0; if(day > 360.0) day -= 360.0; glutpostredisplay(); break; case 'y': year += 1.0; if(year > 360.0) year -= 360.0; glutpostredisplay(); break; case 'a': glutidlefunc(gl_idle); // assign idle function break; case 'A': glutidlefunc(0); break; case 27: exit(0); } }
int main(int argc, char** argv) { glutinit(&argc, argv); } glutinitwindowsize(500, 500); glutinitwindowposition(0, 0); glutinitdisplaymode(glut_double GLUT_RGB); glutcreatewindow("planet"); init(); glutdisplayfunc(gl_display); glutreshapefunc(gl_reshape); glutkeyboardfunc(gl_keyboard); glutmainloop(); return 0;
Tarea
! Para poder ejecutar el código que simula un perro corriendo, el código esta en la carpeta C-Dog ubicada en el sitio del curso. Enfocarse en las transformaciones en el código proporcionado.! La tarea consiste en modificar el movimiento del perro para que pueda correr de manera mas adecuada! Fecha de entrega 30 de marzo
Preguntas?