martes, 13 de marzo de 2012

INVESTIGACION

PROYECCION ORTOGONAL.
El tipo de proyección que hemos utilizado hasta ahora es una proyección ortogonal. Una proyección ortogonal define un volumen de la vista de tipo paralelepipédico tal y como se muestra en la siguiente figura. La principal característica de esta proyección es que el tamaño de los objetos es independiente de la distancia a la que estén del observador, por ejemplo, dos cilindros del mismo tamaño, uno a cinco unidades y el otro a diez unidades de distancia del observador se proyectarán con el mismo tamaño


Para definir una proyección ortogonal en OpenGL hay que dar los siguiente pasos:

glMatrix(GL_PROJECTION); /* Voy a manejar la matriz de proyección */
glLoadIdentity(); /* Cargo inicialmente la identidad */
/* Y ahora defino la proyección ortogonal */

void glOrtho(izquierda, derecha, abajo, arriba, cerca, lejos);
Si lo que deseamos es trabajar con una proyección ortogonal 2D:

void gluOrtho2D(izquierda, derecha, abajo, arriba);

que no es más que una proyección ortogonal donde el plan delantero está en -1 y el trasero en 1.

PROYECCIÓN PERSPECTIVA.
La proyección ortogonal no da sensación de profundidad porque el tamaño de los objetos no depende de su distancia al observador. Para conseguir este efecto necesitamos definir una proyección perspectiva. Esta proyección define un volumen de la vista que es una prisma truncado de base rectangular, como el de la siguiente figura



La función OpenGL que establece este tipo de perspectiva es:



void glFrustum(izquierda, derecha, abajo, arriba, cerca, lejos);




este modo de definir la proyección perspectiva no es demasiado intuitivo, es más sencillo establecerla con un esquema como el que se muestra en la siguiente figura:

y la función OpenGL que la establece es:



void gluPerspective(fovy, aspecto, cerca, lejos);




donde fovy es el ángulo de apertura del objetivo de la cámara, en grados, y aspecto es la relación ancho/alto de la base de la pirámide.



EJEMPLOS DE TRASLACION, ROTACION Y ESCALACION OPENGL
En esteprograma se puede realizar las tres funciones de traslacion, rotacion y escalacion.

RESUMEN

OPERACIONES CON MATRICES: DIBUJANDO EL CAMINO
La transformación de las coordenadas se realiza internamente en OpenGL a partir de las matrices de transformación y de las coordenadas de modelado del objeto. Sin embargo, para representar el rastro que dibuja la tortuga al desplazarse, se realizará explícitamente la transformación de la coordenada en la que se encuentra la tortuga. De esta forma se actúa directamente en la matriz de transformación.

LA PILA DE MATRICES
En la función display() se encuentran las llamadas a dos funciones de matrices que todavía no han sido comentadas. Se trata de glPushMatrix() y glPopMatrix(). Para comprender su funcionamiento, primero se va a experimentar que es lo que ocurre cuando no están dichas llamadas. Para ello se comentan en la función display() ambas llamadas:
void display(void) {
...
// glPushMatrix();
...
glTranslatef(0.0, 0.0, .5);
...
// glPopMatrix();
glutSwapBuffers();
}
La razón de este movimiento es que en la función display está incluida una llamada a glTranslatef() que se utiliza para posicionar uno de los objetos. Como se ha explicado anteriormente, las funciones de traslación multiplican la matriz actual por una matriz de traslación creada con los argumentos que se le pasan, por tanto, sucesivas llamadas a la función display() provocan sucesivas multiplicaciones de la matriz actual con el efecto que se observa de incrementar la traslación.
Para solucionar este problema OpenGL dispone de unos stacks o pilas de matrices, que permiten almacenar y recuperar una matriz anterior. Aunque OpenGL dispone de pilas para las matrices GL_MODELVIEW y GL_PROJECTION, sólo se suele utilizar la pila de GL_MODELVIEW.
Una pila es un almacén con funcionamiento LIFO, el último en entrar es el primero en salir, por lo que suele comparar a una pila de platos en la que sólo se puede dejar uno encima de la pila o coger el superior que es el último depositado. La pila de matrices tiene el mismo funcionamiento sustituyendo los platos por matrices. La matriz superior de la pila es sobre la que se aplican las distintas transformaciones, multiplicándola por la matriz que generan las distintas funciones.
La función glPushMatrix() realiza una copia de la matriz superior y la pone encima de la pila, de tal forma que las dos matrices superiores son iguales. En la figura 1 se observa la pila en la situación inicial con una sola matriz, al llamar a la función glPushMatrix() se duplica la matriz superior. Las siguientes transformaciones que se realizan se aplican sólo a la matriz superior de la pila, quedando la anterior con los valores que tenía en el momento de llamar a la función glPushMatrix().
La función glPopMatrix() elimina la matriz superior, quedando en la parte superior de la pila la matriz que estaba en el momento de llamar a la función glPushMatrix().

DIBUJANDO UN RASTRO
Una característica de Logo es que la tortuga al avanzar va dibujando el camino por el que ha pasado. Hasta ahora la aplicación va transformando las coordenadas del objeto para situarlo en la nueva posición según las instrucciones introducidas pero no muestra la ruta seguida.
Para mostrar la ruta es necesario almacenar los puntos por los que pasa la tortuga. El rastro consistirá en una línea que una estos puntos.
Necesitaremos realizar tres operaciones: calcular la coordendas donde se encuentra la tortuga, almacenar dicha coordenada y dibujar el rastro.
Para almacenar los puntos se utiliza una variable para indicar el número de puntos y tres vectores para las coordenadas x, y, z.
int np = 0;
float px [10000];
float py [10000];
float pz [10000];
Para calcular las coordenadas de la tortuga es necesario conocer la matriz de transformación de modelado. Debido a que en OpenGL, la matriz de modelado se almacena junto con la de visualización en la matriz GL_MODELVIEW, es necesario guardar de modo independiente esta matriz de modelado. Para ello definimos la variable mModel, como una variable global, ya que va a ser accedida en distinos puntos de la aplicación: GLdouble mModel[16]
Para operar con la matriz mModel, se cargará en la pila de matrices de GL_MODELVIEW despues de realizar un PushMatrix(), de modo que no altere la matriz actual. En la función main() se inicializa esta matriz con el código:
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
glGetDoublev (GL_MODELVIEW_MATRIX, mModel);
glPopMatrix();

MOSTRAR TEXTO
Las instrucciones introducidas se muestran en la ventana MSDOS. Se pueden mostrar en la ventana gráfica. Para ello es necesario cambiar las matrices de transformación. La siguiente función realiza la representación del texto:
void text(GLuint x, GLuint y, GLfloat scale, char* format, ...) {
va_list args;
char buffer[255], *p;
GLfloat font_scale = 119.05f + 33.33f;
va_start(args, format);
vsprintf(buffer, format, args);
va_end(args);
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
gluOrtho2D(0, glutGet(GLUT_WINDOW_WIDTH), 0,
glutGet(GLUT_WINDOW_HEIGHT));
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
glPushAttrib(GL_ENABLE_BIT);
glDisable(GL_LIGHTING);
glDisable(GL_TEXTURE_2D);
glDisable(GL_DEPTH_TEST);
glTranslatef(x, y, 0.0);
glScalef(scale/font_scale, scale/font_scale, scale/font_scale);
for(p = buffer; *p; p++)
glutStrokeCharacter(GLUT_STROKE_ROMAN, *p);
glPopAttrib();
glPopMatrix();
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
}
                             
PUNTOS A REALIZAR
Utilizando los comandos de logo representar una esfera compuesta por un conjunto de circunferencias en el espacio.
Utilizando los comandos de logo realizar la representación de una helicoidal.


VIEWPORT
Aplicaciones
·         Tener varias áreas de dibujo y proyección en una ventana
·         Mantener la proporción del aspecto

SINTAXIS
glViewport(Xminimo, Yminimo,Anco,Alto)


CODIGO
#include <GL/glut.h>

GLfloat anguloCuboX = 0.0f;
GLfloat anguloCuboY = 0.0f;
GLfloat anguloEsfera = 0.0f;

GLint ancho=400;
GLint alto=400;

int hazPerspectiva = 0;

void reshape(int width, int height)
{
    glViewport(0, 0, width, height);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
   
    if(hazPerspectiva)
 gluPerspective(60.0f, (GLfloat)width/(GLfloat)height, 1.0f, 20.0f);
    else

 glOrtho(-4,4, -4, 4, 1, 10);
    glMatrixMode(GL_MODELVIEW);

    ancho = width;
    alto = height;
}

void drawCube(void)
{
    glColor3f(1.0f, 0.0f, 0.0f);
    glBegin(GL_QUADS);       //cara frontal
    glVertex3f(-1.0f, -1.0f,  1.0f);
    glVertex3f( 1.0f, -1.0f,  1.0f);
    glVertex3f( 1.0f,  1.0f,  1.0f);
    glVertex3f(-1.0f,  1.0f,  1.0f);

    glEnd();
    glColor3f(0.0f, 1.0f, 0.0f);
    glBegin(GL_QUADS);       //cara trasera
    glVertex3f( 1.0f, -1.0f, -1.0f);
    glVertex3f(-1.0f, -1.0f, -1.0f);
    glVertex3f(-1.0f,  1.0f, -1.0f);
    glVertex3f( 1.0f,  1.0f, -1.0f);

    glEnd();
    glColor3f(0.0f, 0.0f, 1.0f);
    glBegin(GL_QUADS);       //cara lateral izq
    glVertex3f(-1.0f,-1.0f, -1.0f);
    glVertex3f(-1.0f,-1.0f,  1.0f);
    glVertex3f(-1.0f, 1.0f,  1.0f);
    glVertex3f(-1.0f, 1.0f, -1.0f);
    glEnd();

    glColor3f(1.0f, 1.0f, 0.0f);
    glBegin(GL_QUADS);       //cara lateral dcha
    glVertex3f(1.0f, -1.0f,  1.0f);
    glVertex3f(1.0f, -1.0f, -1.0f);
    glVertex3f(1.0f,  1.0f, -1.0f);
    glVertex3f(1.0f,  1.0f,  1.0f);
    glEnd();
    glColor3f(0.0f,      1.0f, 1.0f);
    glBegin(GL_QUADS);       //cara arriba
    glVertex3f(-1.0f, 1.0f,  1.0f);
    glVertex3f( 1.0f, 1.0f,  1.0f);
    glVertex3f( 1.0f, 1.0f, -1.0f);
    glVertex3f(-1.0f, 1.0f, -1.0f);
    glEnd();

    glColor3f(1.0f, 0.0f, 1.0f);
    glBegin(GL_QUADS);       //cara abajo
    glVertex3f( 1.0f,-1.0f, -1.0f);
    glVertex3f( 1.0f,-1.0f,  1.0f);
    glVertex3f(-1.0f,-1.0f,  1.0f);
    glVertex3f(-1.0f,-1.0f, -1.0f);
    glEnd();
}

void display()
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glLoadIdentity();

    glTranslatef(0.0f, 0.0f, -5.0f);

    glRotatef(anguloCuboX, 1.0f, 0.0f, 0.0f);
    glRotatef(anguloCuboY, 0.0f, 1.0f, 0.0f);

    drawCube();

    glLoadIdentity();

    glTranslatef(0.0f, 0.0f, -5.0f);
    glRotatef(anguloEsfera, 0.0f, 1.0f, 0.0f);
    glTranslatef(3.0f, 0.0f, 0.0f);

    glColor3f(1.0f, 1.0f, 1.0f);
    glutWireSphere(0.5f, 8, 8);

    glFlush();
    glutSwapBuffers();

    anguloCuboX+=0.1f;
    anguloCuboY+=0.1f;
    anguloEsfera+=0.2f;
}

void init()
{
    glClearColor(0,0,0,0);
    glEnable(GL_DEPTH_TEST);
    ancho = 400;
    alto = 400;
}
 

void idle()
{
    display();
}

void keyboard(unsigned char key, int x, int y)
{
    switch(key)
    {
    case 'p':
    case 'P':
 hazPerspectiva=1;
 reshape(ancho,alto);
 break;

    case 'o':
    case 'O':
 hazPerspectiva=0;
 reshape(ancho,alto);
 break;

    case 27:   // escape
 //exit(0);
      break;
    }
}

int main(int argc, char **argv)
{
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
    glutInitWindowPosition(100, 100);
    glutInitWindowSize(ancho, alto);
    glutCreateWindow("Cubo 1");
    init();
    glutDisplayFunc(display);
    glutReshapeFunc(reshape);
    glutIdleFunc(idle);
    glutKeyboardFunc(keyboard);
    glutMainLoop();
    return 0;
}


RESULTADO

No hay comentarios:

Publicar un comentario