Tuesday, November 27, 2007

Mi carro con Degradados de colores

Mi carro con Degradados de colores
Dibujado de un carro en OpenGL utilizando ????
PDF File
Jose Angel Espinoza Portillo
Tarea 7 • Graficacion • 31 Octubre 2007



Bases
Se utilizara el mismo proyecto de la tarea 6 con la modificación que se le agregara el código necesario para que pueda ser mostrado con colores degradados.
OpenGL para dibujar una figura, necesita que se le proporcionen los vértices de la misma, y si quieres que la superficie de esta figura tenga algún color antes de escribir el primer vértice se debe especificar el color que tendrá con la función glColor3f especificando los valores de Rojo, Verde y Azul en niveles del 0 al 1.
Pero si se quiere hacer un degradado es tan fácil como asignarle u color diferente a cada nodo antes de cada glVertex3fv poner un glColor3f especificando el color del nodo y al momento de renderizar la aplicación el OpenGL automáticamente dibuja el degradado.




Implementación
Optimizaciones para dar un buen aspecto

Cada nodo es miembro de mas de una sola figura, así que para fines de presentación cada que se dibuje una figura que utilice un nodo compartido, este nodo tendrá el mismo color que tiene en las demás figuras a las que pertenece. Y para que no haya confusiones se hace esto con una matriz, en la cual se le asigna el color del nodo en sus valores de RVA (RGB en ingles) y mandando a dibujar. Esta matriz esta representada en el código de la siguiente manera.

v2[0][0] = 0.0; v2[0][1] = 0.0; v2[0][2] = 0.0;
v2[1][0] = 0.0; v2[1][1] = 0.0; v2[1][2] = 1.0;
v2[2][0] = 0.0; v2[2][1] = 1.0; v2[2][2] = 1.0;
v2[3][0] = 1.0; v2[3][1] = 0.0; v2[3][2] = 0.0;

v2[4][0] = 1.0; v2[4][1] = 0.0; v2[4][2] = 1.0;
v2[5][0] = 1.0; v2[5][1] = 1.0; v2[5][2] = 0.0;
v2[6][0] = 1.0; v2[6][1] = 1.0; v2[6][2] = 1.0;
v2[7][0] = 0.0; v2[7][1] = 0.0; v2[7][2] = 0.5;

v2[8][0] = 0.0; v2[8][1] = 0.5; v2[8][2] = 0.0;
v2[9][0] = 0.0; v2[9][1] = 0.5; v2[9][2] = 0.5;
v2[10][0] = 0.5; v2[10][1] = 0.0; v2[10][2] = 0.0;
v2[11][0] = 0.5; v2[11][1] = 0.0; v2[11][2] = 0.5;

v2[12][0] = 0.5; v2[12][1] = 0.5; v2[12][2] = 0.0;
v2[13][0] = 0.5; v2[13][1] = 0.5; v2[13][2] = 0.5;
v2[14][0] = 0.3; v2[14][1] = 1.0; v2[14][2] = 0.8;
v2[15][0] = 0.0; v2[15][1] = 0.0; v2[15][2] = 1.0;

Así se asigna para v2[n][0] el valore de rojo y para v2[n][1] y v2[n][2] los valores de Verde y Azul respectivamente. Este código se ingresa en el el constructor de la clase junto a v1.

Dibujado

A la hora del dibujado se implementa la explicacion dada en area de Bases, pero referenciando el numero de el nodo que se esta dibujando, como lo veremos a continuacion:

glBegin(GL_QUADS);
glColor3fv( &v1[0][0] );
glVertex3fv( &v1[0][0] );
glColor3fv( &v1[1][0] );
glVertex3fv( &v1[1][0] );
glColor3fv(&v1[2][0] );
glVertex3fv( &v1[2][0] );
glColor3fv( &v1[3][0]);
glVertex3fv( &v1[3][0] );

glColor3fv( &v1[8][0] );
glVertex3fv( &v1[8][0] );
glColor3fv( &v1[9][0] );
glVertex3fv( &v1[9][0] );
glColor3fv( &v1[10][0] );
glVertex3fv( &v1[10][0] );
glColor3fv( &v1[11][0] );
glVertex3fv( &v1[11][0] );

glColor3fv( &v1[12][0] );
glVertex3fv( &v1[12][0] );
glColor3fv( &v1[13][0] );
glVertex3fv( &v1[13][0] );
glColor3fv( &v1[14][0] );
glVertex3fv( &v1[14][0] );
glColor3fv( &v1[15][0] );
glVertex3fv( &v1[15][0] );

glColor3fv( &v1[0][0] );
glVertex3fv( &v1[0][0] );
glColor3fv( &v1[3][0] );
glVertex3fv( &v1[3][0] );
glColor3fv( &v1[15][0] );
glVertex3fv( &v1[15][0] );
glColor3fv( &v1[12][0] );
glVertex3fv( &v1[12][0] );

glColor3fv( &v1[8][0] );
glVertex3fv( &v1[8][0] );
glColor3fv( &v1[4][0] );
glVertex3fv( &v1[4][0] );
glColor3fv( &v1[7][0] );
glVertex3fv( &v1[7][0] );
glColor3fv( &v1[11][0] );
glVertex3fv( &v1[11][0] );

glColor3fv( &v1[0][0] );
glVertex3fv( &v1[0][0] );
glColor3fv( &v1[1][0] );
glVertex3fv( &v1[1][0] );
glColor3fv( &v1[13][0] );
glVertex3fv( &v1[13][0] );
glColor3fv( &v1[12][0] );
glVertex3fv( &v1[12][0] );

glColor3fv( &v1[4][0] );
glVertex3fv( &v1[4][0] );
glColor3fv( &v1[5][0] );
glVertex3fv( &v1[5][0] );
glColor3fv( &v1[9][0] );
glVertex3fv( &v1[9][0] );
glColor3fv( &v1[8][0] );
glVertex3fv( &v1[8][0] );

glColor3fv( &v1[1][0] );
glVertex3fv( &v1[1][0] );
glColor3fv( &v1[2][0] );
glVertex3fv( &v1[2][0] );
glColor3fv( &v1[14][0] );
glVertex3fv( &v1[14][0] );
glColor3fv( &v1[13][0] );
glVertex3fv( &v1[13][0] );

glColor3fv( &v1[5][0] );
glVertex3fv( &v1[5][0] );
glColor3fv( &v1[6][0] );
glVertex3fv( &v1[6][0] );
glColor3fv( &v1[10][0] );
glVertex3fv( &v1[10][0] );
glColor3fv( &v1[9][0] );
glVertex3fv( &v1[9][0] );

glColor3fv( &v1[2][0] );
glVertex3fv( &v1[2][0] );
glColor3fv( &v1[3][0] );
glVertex3fv( &v1[3][0] );
glColor3fv( &v1[15][0] );
glVertex3fv( &v1[15][0] );
glColor3fv( &v1[14][0] );
glVertex3fv( &v1[14][0] );

glColor3fv( &v1[10][0] );
glVertex3fv( &v1[10][0] );
glColor3fv( &v1[11][0] );
glVertex3fv( &v1[11][0] );
glColor3fv( &v1[7][0] );
glVertex3fv( &v1[7][0] );
glColor3fv( &v1[6][0] );
glVertex3fv( &v1[6][0] );
glEnd();

Mi carro en Perspectiva

Mi carro en Perspectiva
Dibujado de un carro en OpenGL y su proyección en Perspectiva
PDF File
Jose Angel Espinoza Portillo
Tarea 5 • Graficacion • 31 Octubre 2007


Trabajo realizado
Se utilizaron unos códigos implementados en una tarea anterior donde ya esa declarada la estructura de datos para los nodos que dan la forma del carro y de las caras del mismo, ademas de un conjunto de funciones ya implementadas donde podemos modificar el código para utilizarlo para nuestros fines en este reporte.

Archivos los archivos importantes para este reporte son
painter.cpp: Donde se encuentra la interfaz de la ventana de visualización.
quad.cpp: Es en este archivo donde se visualiza el modelo y también donde se dibujan y modifican las matrices de transformación implementadas.

Trabajo a realizar
Para que un objeto pueda tener una proyección en perspectiva hay que generar el efecto de que una cámara lo esta rodeando. Esta es una transformación que se puede efectuar en la matriz del objeto o en la matriz de proyección. Pero se elige hacer la modificación directamente en el modelo, ya que es preferible modificar el modelo que la proyección ya que tiene mas espacio en su pila de matrices y hay menos posibilidades de errores.
Para eso se utilizara un método de entrada no utilizado antes en este curso. Que es el teclado para dar comandos, se designan algunas teclas para que se mueva hacia arriba, abajo y ambos lados al igual que un zoom para determinar el acercamiento o alejamiento del objeto desde el punto de vista.

El código
Modificaciones que se tienen que hacer a el código anterior.
Para poder implementar una vista en perspectiva, se tienen que eliminar a toda relación con la visualización ortográfica empezando por las funciones glOrtho que están ubicadas por todo el archivo quad.cpp.
Se declaran algunas variables las cuales definen la altura del punto de visión y el ángulo de rotación del mismo, ademas de una variable step la cual define la cantidad de moviendo que hay entre un estado y otro.
Se modifica la función keyPressEvent, la cual es la que responde a las entradas de comandos quedando como se muestra a continuación:

void Quad::keyPressEvent ( QKeyEvent * e )
{
float step = 10;
switch ( tolower(e->key()) ) {
case '+':
signo = 1;
break;
case '-':
signo = -1;
break;
case 'a':
azi -= step;
break;
case 's':
ele -= step;
break;
case 'd':
azi += step;
break;
case 'w':
ele += step;
break;
case 'z':
zoom += 1;
break;
case 'x':
zoom -= 1;
break;
}
repaint();
}

paintGL
En esta función se debe de hacer la transformación de el ángulo de visión y dibujar el objeto al final para que la transformación de perspectiva surja efecto. Para esto primero hay que hacer:

glMatrixMode (GL_PROJECTION);
glLoadIdentity ();

gluPerspective(30,1,0.01,100);

que carga la matriz defaul a GL_PROJECTION la carga y la asigna una perspectiva.
Luego se hacen los cálculos de el punto donde estará el ojo de visión y aplicarle la transformación a el GL_MODEL con el gluLookAt de la siguiente manera.

glMatrixMode(GL_MODELVIEW);
glLoadIdentity (); /* clear the matrix */
eye[0] = zoom *sin(azi*PI/180) * cos(ele*PI/180);
eye[1] = zoom *sin(ele*PI/180) ;
eye[2] = zoom *cos(azi*PI/180) * cos(ele*PI/180);
printf("%f %f %f\n",eye[0],eye[1],eye[2]);
gluLookAt(eye[0],eye[1],eye[2],0,0,0,0,1,0);

recordando que zoom, azi y ele están controlados por las teclas presionadas.
Esto debe de estar antes de dibujar el objeto ya que esto definirá la posición en que se dibujara el objeto en el espacio y en la pantalla.

Labels: ,