martes, 27 de marzo de 2012

La representación de los objetos en tres dimensiones



La representación de los objetos en tres dimensiones sobre una  superficie plana, de manera que ofrezcan una sensación de volumen se  llama  Perspectiva. Se representan los objetos sobre tres ejes XYZ. En el eje Z,  se representa la altura. En el eje Y, se representa la anchura y en el eje X,  se representa la longitud.

 Los distintos tipos de perspectivas dependen de la inclinación de los  planos Los sistema más utilizados son la isométrica, la caballera y la cónica.  Estudiaremos en este curso las dos primeras.

Perspectiva Isométrica. En ella los ejes quedan separados por un mismo  ángulo (120º). Las medidas siempre se refieren a los tres ejes que tienen su  origen en un único punto.

Perspectiva Caballera. En ella  los ejes X y Z  tienen un ángulo de 90º y el  eje Y con respecto a Z tiene una inclinación de 135º. En es te caso las  medidas  en los ejes X y Z son las reales y las del eje Y tiene un coeficiente  de reducción de 0.5.

DIBUJAR EN PERSPECTIVA

En ambas perspectivas, el sistema más sencillo es llevar las tres  vistas principales sobre los planos formados por los ejes:
     Alzado en el plano XZ.
     Planta en el plano XY.
     Perfil en el plano YZ.
Cada una de las aristas que forman las vistas se prolonga paralelamente  al eje que corresponda:
    Horizontal paralelo al eje de las X.
    Vertical paralelo al eje de las Z.
    Profundidad paralelo al eje de las Y

Transformaciones en OpenGL

En algunos tutoriales anteriores de OpenGL se han mencionado de manera fragmentaria los conceptos de transformaciones:

·         En los “Hola Mundo 3d en OpenGL” y “Hola Complicado Mundo OpenGL-win32” se utilizaron algunas transformaciones de proyección y viewport para ajustar la inicialización de la ventana, pero sin entrar mucho en detalle acerca de su funcionamiento.


Este tutorial explora los diferentes tipos de transformaciones en OpenGL, a saber:

·         Proyección: Trasforman una escena 3d “abstracta”, en una imagen plana que puede ser visualizada en una pantalla.
·         Viewport: Ajustan el producto de la proyección a las dimensiones de un rectángulo contenedor (ventana).
·         De vista: Que definen y afectan la posición desde la cual se visualizan las escenas tridimensionales.
·         Modelado: Sirven para manipular los objetos en la escena, permitiendo trasladarlos, rotarlos y deformarlos (escalarlos).
·         Modelo-Vista: Son la combinación de las dos transformaciones anteriores, que desde un punto de vista práctico son semejantes.


·         void glMatrixMode( enum mode ); Permite seleccionar la matriz sobre la cual se realizaran las operaciones, los posibles valores de mode son TEXTURE, MODELVIEW, COLOR o PROJECTION . Por ahora las más interesantes son MODELVIEW y PROJECTION, las otras se verán en su momento.

·         Void glLoadMatrix{fd} (T m[16]); Recibe una matriz de 4×4 que reemplaza la actual seleccionada. El arreglo es ordenado en forma de una matriz que tiene orden Y, a diferencia de las matrices convencionales que tienen orden X, lo que quiere decir que tiene la forma.

·         void glMultMatrix{fd}( T m[16] ); Multiplica la matriz actual por la matriz m[16] y reemplaza la matriz actual con el resultado de la operación. La operación resultante sería algo así como A’ = A M , donde A es la matriz actual, M es la matriz suministrada y A’ es la nueva matriz que resulta de la operación y que reemplaza a A.

·         void glLoadTransposeMatrix{fd}( T m[16] ); Realiza una función similar a LoadMatrix(), con la diferencia que trabaja sobre una matriz en orden X así.

·         void glMultTransposeMatrix{fd}( T m[16] ); Misma funcionalidad que MultMatrix() , solo que actúa en base al la matriz en orden X, o sea la transpuesta.

·         void glLoadIdentity( void ); Remplaza la matriz actual por la matriz identidad de tamaño 4×4.
Estas operaciones afectan directamente las matrices mencionadas anteriormente, debido a que las operaciones de “alto nivel” (trasladar, rotar, escalar) que existen mas adelante se concatenan, es decir su efecto se acumula sobre matriz actual, existen dos operaciones que permiten guardar la matriz actual en una pila y restaurarla cuando sea necesario, estas son:

·         void glPushMatrix( void ); Coloca una copia de la matriz actual en la parte superior de la pila correspondiente.

·         void glPopMatrix( void ); Saca el elemento superior de la pila, que pasa a reemplazar a la matriz actual.
Estas dos operaciones son muy utilizadas, debido a que permiten realizar transformaciones sobre objetos diferentes, manteniendo algunas de las anteriores sin modificar.

Proyección

Como ya se ha visto en tutoriales anteriores, OpenGL maneja 2 tipos de proyección, en perspectiva y ortográfica, donde la primera corresponde a la visión “realista” de la escena, mientras que la segunda es una “plana” que no deforma las dimensiones de los objetos dependiendo de su distancia a la cámara.

Ortográfica: Para ajustar la proyección ortográfica se utiliza el siguiente grupo de funciones:

glOrtho(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble near, GLdouble far);

gluOrtho2D(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top);

Perspectiva: Existen dos manera de manejar la proyección en perspectiva, a través de de una función gl o mediante la librería glu (una tercera puede ser realizar los cálculos de la matriz “manualmente”. En el primer caso:

glFrustrum(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble near, GLdouble far)



Transformaciones ModelView

Una tarea muy común en la creación de gráficos 2d, 3d y videojuegos es la de mover objetos par crear cierta animación. La primera idea que se nos viene a la cabeza en el caso de OpeGL es que todo modelo está formado por primitivas, toda primitiva por puntos y finalmente todo punto por una tripleta de coordenadas XYZ, así que si se cambian las coordenadas todo de ahí hacia arriba se mueve.

void glRotate[fd](GLfloat angle, GLfloat x, GLfloat y, GLfloat z);

Hay que tener en cuenta las siguientes características a la hora de utilizar estas funciones:

·         Estas tres operaciones afectan la matriz actual seleccionada, bien sea MODELVIEW o PROJECTION, generalmente para propósitos de rotar objetos dentro de la escena se utiliza la matriz MODELVIEW.

·         El eje coordenado de referencia para las operaciones tanto en MODELVIEW como en PROJECTION se denomina “eye coordinates”, que traduce coordenadas de “ojo” o mejor “vista”. Este es un sistema inamovible y en ausencia de cualquier transformación, la “cámara” está situada en (0,0,0) apuntando hacia la dirección Z negativa, con el vector “arriba” en el sentido Y positivo.

·         Cada operación que afecta la matriz MODELVIEW crea otro sistema coordenado para los objetos que se dibujen después de realizada la trasformación, dicho sistema difiere del “básico”, es decir de las llamadas coordenadas de vista (eye coordinates) dependiendo de todo el conjunto de transformaciones realizadas desde el momento en que la matriz MODELVIEW dejo de ser la identidad.

·         Una consecuencia de lo anterior es que las operaciones no son conmutativas, es decir que un llamado de glRotatef(), seguido de uno de glTranslatef() produce un efecto diferente a llamar las operaciones en orden inverso. Esto se ve mejor ilustrado en el gráfico:


·         Es importante aprender a utilizar correctamente glPushMatrix(), glPopMatrix() y otras operaciones que permitan salvar y restaurar estados de matriz, debido a que permiten realizar translaciones y rotaciones especificas para un cierto objeto, sin alterar los otros.

Hardware

En realidad, el API de ogl está pensado para trabajar bajo el respaldo de un hardware capaz de realizar las operaciones necesarias para el renderizado, pero si no se dispone de ese hardware, estas operaciones se calcularan por medio de un software contra la CPU del sistema. Así que los requerimientos hardware son escasos, aunque cuanto mayor sea las capacidades de la maquina, mayor será el rendimiento de las aplicaciones ogl.

Windows

En principio, cualquier versión de windows viene con las librerías necesarias para ejecutar cualquier aplicación que utilice OpenGL. Para el desarrollo de las mismas, el Microsoft Visual Studio, y en particular Visual C++ trae también todo lo necesario. Puedes consegir, además, la última versión de la GLUT en la web de Nate Robins.

Linux
Para visualizar aplicaciones OpenGL en XFree86 necesitarás instalar un paquete para el soporte de las librerías Mesa (que es el equivalente en software libre de OpenGL) y de las utilidades GLU y GLUT. Para realizar desarrollo necesitarás, a mayores, los paquetes equivalentes en modo dev.

En el caso de la distribución Ubuntu los paquetes necesarios para desarrollo y visualización son los siguientes:
 - Freeglut3-dev
 - libgl1-mesa-dev
 - libglu1-mesa-dev
 - libglut3.dev


Coordenadas oculares
Las coordenadas oculares se sitúan en el punto de vista del observador, sin importar las transformaciones que tengan lugar. Por tanto, estas coordenadas representan un sistema virtual de coordenadas fijo usado como marco de referencia común.
Transformaciones
Las transformaciones son las que hacen posible la proyección de coordenadas 3D sobre superficies 2D. También son las encargadas de mover, rotar y escalar objetos.
El modelador
En esta sección se recogen las transformaciones del observador y del modelado puesto que, como se verá en el apartado, constituyen, al fin y al cabo, la misma transformación.

Transformaciones del observador
La transformación del observador es la primera que se aplica a la escena, y se usa para determinar el punto más ventajoso de la escena. Por defecto, el punto de vista está en el origen (0,0,0) mirando en dirección negativa del eje z. La transformación del observador permite colocar y apuntar la cámara donde y hacia donde se quiera.
Transformaciones del modelo
Estas transformaciones se usan para situar, rotar y escalar los objetos de la escena. La apariencia final de los objetos depende en gran medida del orden con el que se hayan aplicado las transformaciones.
Transformaciones de la proyección
 La transformación de proyección se aplica a la orientación final del modelador. Esta proyección define el volumen de visualización y establece los planos de trabajo
 Los dos tipos de proyección más utilizados son la ortográfica y la perspectiva, que veremos más adelante.
Transformaciones de la vista
 En el momento en que se ha terminado todo el proceso de transformaciones, solo queda un último paso: proyectar lo que hemos dibujado en 3D al 2D de la pantalla, en la ventana en la que estamos trabajando.
Matrices
 Las matemáticas que hay tras estas transformaciones se simplifican gracias a las matrices. Cada una de las transformaciones de las que se acaba de hablar puede conseguirse multiplicando una matriz que contenga los vértices por una matriz que describa la transformación.
El canal de transformaciones
Para poder llevar a cabo todas las transformaciones de las que se acaba de hablar, deben modificarse dos matrices: la matriz del Modelador y la matriz de Proyección.
La matriz del modelador
La matriz del modelador es una matriz 4x4 que representa el sistema de coordenadas transformado que se está usando para colocar y orientar los objetos.

La matriz de proyección
La matriz de proyección especifica el tamaño y la forma del volumen de visualización. El volumen de visualización es aquel cuyo contenido es el que se representa en pantalla.
Proyecciones ortográficas
Una proyección ortográfica es cuadrada en todas sus caras. Esto produce una proyección paralela, útil para aplicaciones de tipo CAD o dibujos arquitectónicos, o también para tomar medidas, ya que las dimensiones de lo que representan no se ven alteradas por la proyección.
Proyecciones perspectivas
Una proyección en perspectiva reduce y estirar los objetos más alejados del observador. Es importante saber que las medidas de la proyección de un objeto no tienen por qué coincidir con las del objeto real, ya que han sido defo

viernes, 23 de marzo de 2012

MODIFICACIÓN DEL CUBO EN 3D


#include <GL/glut.h>

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

GLint ancho=600;
GLint alto=600;

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);
 glTranslatef(-3,0,0);
    glRotatef(anguloCuboX, 1.0f, 0.0f, 0.0f);
    glRotatef(anguloCuboY, 0.0f, 1.0f, 0.0f);
glScalef(0.5f, 0.5f, 0.5f);
    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 = 600;
    alto = 600;
}


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(display);
    glutKeyboardFunc(keyboard);
    glutMainLoop();
    return 0;
}

Corrida





PELOTA QUE REBOTA EN 2D




#include <gl/glut.h>
#include <Math.h>    
#define PI 3.14159265f   

char title[] = "Pelota que Rebota 2D";
int windowWidth  = 640;    
int windowHeight = 480;    
int windowPosX   = 50;    
int windowPosY   = 50;    
 
GLfloat ballRadius = 0.2f;  
GLfloat xPos = 0.0f;      
GLfloat yPos = 0.0f;
GLfloat xPosMax, xPosMin, yPosMax, yPosMin;
GLdouble xLeft, xRight, yBottom, yTop;    
GLfloat xSpeed = 0.004f;
GLfloat ySpeed = -.007f;
int refreshMillis = 5;    
     

void initGL() {
   glClearColor(0.0, 0.0, 0.1f, 1.0);
}
 
void display() {

   glClear(GL_COLOR_BUFFER_BIT);  
 
   glLoadIdentity();              
   glTranslatef(xPos, yPos, 0.0f);
 
   glBegin(GL_TRIANGLE_FAN);
      glColor3f(0.0f, 0.0f, 1.0f);
      glVertex2f(0.0f, 0.0f);      
      int numSegments = 100;
      GLfloat angle;
      for (int i = 0; i <= numSegments; i++) {
         angle = i * 2.0f * PI / numSegments;
         glVertex2f(cos(angle) * ballRadius, sin(angle) * ballRadius);
      }
   glEnd();
   glutSwapBuffers();  
   xPos += xSpeed;
   yPos += ySpeed;
 
   if (xPos > xPosMax) {
      xPos = xPosMax;
      xSpeed = -xSpeed;
   } else if (xPos < xPosMin) {
      xPos = xPosMin;
      xSpeed = -xSpeed;
   }
   if (yPos > yPosMax) {
      yPos = yPosMax;
      ySpeed = -ySpeed;
   } else if (yPos < yPosMin) {
      yPos = yPosMin;
      ySpeed = -ySpeed;
   }

}
void reshape(GLsizei weight, GLsizei height) {
   if (height == 0) height = 1;              
   GLfloat aspect = (GLfloat)weight / height;  
 
   glViewport(0, 0, weight, height);
    
   glMatrixMode(GL_PROJECTION);
   glLoadIdentity();          
   if (weight <= height) {
      xLeft   = -1.0;
      xRight  = 1.0;
      yBottom = -1.0 / aspect;
      yTop    = 1.0 / aspect;
   } else {
      xLeft   = -1.0 * aspect;
      xRight  = 1.0 * aspect;
      yBottom = -1.0;
      yTop    = 1.0;
   }
   gluOrtho2D(xLeft, xRight, yBottom, yTop);
   xPosMin = xLeft + ballRadius;
   yPosMax = yTop - ballRadius;  
   xPosMax = xRight - ballRadius;
   yPosMin = yBottom + ballRadius;
 
 
   glMatrixMode(GL_MODELVIEW);
   glLoadIdentity();          
}
void Timer(int value) {
glutPostRedisplay();  
glutTimerFunc(refreshMillis, Timer, 0);
}

int main(int argc, char** argv) {
   glutInit(&argc, argv);          
   glutInitDisplayMode(GLUT_DOUBLE);
   glutInitWindowSize(windowWidth, windowHeight);
   glutInitWindowPosition(windowPosX, windowPosY);
   glutCreateWindow(title);    
   glutDisplayFunc(display);    
   glutReshapeFunc(reshape);    
   glutTimerFunc(0, Timer, 0);  
   initGL();                    
   glutMainLoop();              
   return 0;
}

Corrida





martes, 13 de marzo de 2012

Cubo 3D


#include <GLglut.h>

GLfloat anguloCuboY;

void drawCube(void)
{
      glColor3f(1.0f, 0.0f, 0.0f);
    glBegin(GL_QUADS);       //cara frontal
glVertex3f(  0.0f,  0.0f,0.0f);  //0
glVertex3f(100.0f,  0.0f,0.0f); //1
glVertex3f(100.0f,100.0f,0.0f); //2
glVertex3f(  0.0f,100.0f,0.0f);   //3

    glEnd();

    glColor3f(0.0f, 1.0f, 0.0f);

    glBegin(GL_QUADS);       //cara trasera
    glVertex3f(  0.0f,100.0f,-100.0f); //6
glVertex3f(100.0f,100.0f,-100.0f); //5
glVertex3f(100.0f,  0.0f,-100.0f); //4
glVertex3f(  0.0f,  0.0f,-100.0f); //7

    glEnd();

    glColor3f(0.0f, 0.0f, 1.0f);
    glBegin(GL_QUADS);       //cara lateral izq
    glVertex3f(100.0f,  0.0f,   0.0f); //1
glVertex3f(100.0f,  0.0f,-100.0f); //4
glVertex3f(100.0f,100.0f,-100.0f); //5
glVertex3f(100.0f,100.0f,   0.0f); //2

    glEnd();

    glColor3f(1.0f, 1.0f, 0.0f);
    glBegin(GL_QUADS);       //cara lateral dcha
    glVertex3f(0.0f,100.0f,   0.0f);   //3
    glVertex3f(0.0f,100.0f,-100.0f); //6
glVertex3f(0.0f,  0.0f,-100.0f); //7
glVertex3f(0.0f,  0.0f,   0.0f);  //0

    glEnd();

    glColor3f(0.0f,1.0f, 1.0f);
    glBegin(GL_QUADS);       //cara arriba
   
glVertex3f(100.0f,100.0f,-100.0f); //5
glVertex3f(  0.0f,100.0f,-100.0f); //6
glVertex3f(  0.0f,100.0f,   0.0f);   //3
glVertex3f(100.0f,100.0f,   0.0f); //2

    glEnd();

    glColor3f(1.0f, 0.0f, 1.0f);
    glBegin(GL_QUADS);       //cara abajo
     glVertex3f( 0.0f,0.0f,-100.0f); //7
glVertex3f(100.0f,0.0f,-100.0f); //4
glVertex3f(100.0f,0.0f,   0.0f); //1
glVertex3f(  0.0f,0.0f,   0.0f);  //0

    glEnd();

}

void myinit(void)
{

/* attributes */


glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-150,150,-150,150,1,500.0);

glMatrixMode(GL_MODELVIEW);


}
void init()
{
    glClearColor(0,0,0,0);
    glEnable(GL_DEPTH_TEST);

}

void display(void)
{
glClear(GL_COLOR_BUFFER_BIT| GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glTranslatef(0.0f,0.0f,-150.0f);
   
    glRotatef(45,0.0f,0.0f,1.0f);
glRotatef(anguloCuboY, 1.0f,1.0f,0.0f);

drawCube();

    glFlush();

anguloCuboY+=0.1f;

}

int main(int argc, char** argv)
{
        glutInit(&argc, argv);
   
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
        glutInitWindowSize(650, 650);
        glutCreateWindow("Cubo 3D");
         init();
        glutDisplayFunc(display);
myinit();
glutIdleFunc(display);
        glutMainLoop();
return 0;
}





domingo, 4 de marzo de 2012

Proyección Ortogonal


Coordenadas oculares

Las coordenadas oculares se sitúan en el punto de vista del observador, sin importar las transformaciones que tengan lugar. Por tanto, estas coordenadas representan un sistema virtual de coordenadas fijo usado como marco de referencia común. 

Transformaciones

También son las encargadas de mover, rotar y escalar objetos. En realidad, estas transformaciones no se aplican a los modelos en sí, si no al sistema de coordenadas, de forma que si se quiere rotar un objeto, no lo se le rota, sino que se rota el eje sobre el que se sitúa.

En esta sección se recogen las transformaciones del observador y del modelado puesto que, como se verá en el apartado 4.2.1.3, constituyen, al fin y al cabo, la misma transformación.

Transformaciones del observador

La transformación del observador es la primera que se aplica a la escena, y se usa para determinar el punto más ventajoso de la escena. Por defecto, el punto de vista está en el origen (0,0,0) mirando en dirección negativa del eje z.

 Transformaciones del modelo

Estas transformaciones se usan para situar, rotar y escalar los objetos de la escena. La apariencia final de los objetos depende en gran medida del orden con el que se hayan aplicado las transformaciones. 

Transformaciones de la proyección

 La transformación de proyección se aplica a la orientación final del modelador. Esta proyección define el volumen de visualización y establece los planos de trabajo. A efectos prácticos, esta translación especifica cómo se traslada una escena finalizada a la imagen final de la pantalla.

 Matrices

 Cada una de las transformaciones de las que se acaba de hablar puede conseguirse multiplicando una matriz que contenga los vértices por una matriz que describa la transformación. Por tanto todas las transformaciones ejecutables con ogl pueden describirse como la multiplicación de dos o más matrices.

 El canal de transformaciones

 OpenGL proporciona muchas funciones de alto nivel que hacen muy sencillo la construcción de matrices para transformaciones. Éstas se aplican sobre la matriz que este activa en ese instante. Para activar una de las dos matrices utilizamos la función glMatrixMode. Hay dos parámetros posibles:

glMatrixMode(GL_PROJECTION);

activa la matriz de proyección, y

glMatrixMode(GL_MODELVIEW);

activa la del modelador. 

La matriz del modelador

La matriz del modelador es una matriz 4x4 que representa el sistema de coordenadas transformado que se está usando para colocar y orientar los objetos. Si se multiplica la matriz del vértice (de tamaño 1x4) por ésta se obtiene otra matriz 1x4 con los vértices transformados sobre ese sistema de coordenadas.

 Translación

Imaginemos que se quiere dibujar un cubo con la función de la librería GLUT glutSolidCube, que lleva como parámetro el lado del cubo. Si se escribe el siguiente código:

glutSolidCube(5);

se obtiene un cubo centrado en el origen (0,0,0) y con el lado de la arista 5.

glTranslatef(10.0f, 0.0f, 0.0f);
glutSolidCube(5);

La “f” añadida a la función indica que se usarán flotantes. Los parámetros de glTranslate son las unidades a desplazar en el eje x, y y z, respectivamente. Pueden ser valores negativos, para trasladar en el sentido contrario.

Rotación

Para rotar, tenemos también una función de alto nivel que construye la matriz de transformación y la multiplica por la matriz activa, glRotate. Lleva como parámetros el ángulo a rotar (en grados, sentido horario), y después x, y y z del vector sobre el cual se quiere rotar el objeto. Una rotación simple, sobre el eje y, de 10º sería

glRotatef(10, 0.0f, 1.0f, 0.0f);

 Escalado

Una transformación de escala incrementa el tamaño de nuestro objeto expandiendo todos los vértices a lo largo de los tres ejes por los factores especificados. La función glScale lleva como parámetros la escala en x, y y z, respectivamente. El valor 1.0f es la referencia de la escala, de tal forma que la siguiente línea:

glScalef(1.0f, 1.0f, 1.0f);

no modificaría el objeto en absoluto. Un valor de 2.0f sería el doble, y 0.5f sería la mitad. Por ejemplo, para ensanchar un objeto a lo largo de su eje z, de tal forma que quedase cuatro veces más “alargado” en este eje, sería:

glScalef(1.0f, 1.0f, 4.0f);

La matriz de proyección

La matriz de proyección especifica el tamaño y la forma del volumen de visualización. Está delimitado por una serie de planos de trabajo. De estos planos, los más importantes son los planos de corte, que son los que nos acotan el volumen de visualización por delante y por detrás. Todo lo que esté más adelante del plano de corte más alejado de la cámara (zfar) no se representa.

 Proyecciones ortográficas

Una proyección ortográfica es cuadrada en todas sus caras. Esto produce una proyección paralela, útil para aplicaciones de tipo CAD o dibujos arquitectónicos, o también para tomar medidas, ya que las dimensiones de lo que representan no se ven alteradas por la proyección.

Para definir la matriz de proyección ortográfica y multiplicarla por la matriz activa (que debería ser en ese momento la de proyección, GL_PROJECTION), se utiliza la función glOrtho, que se define de la siguiente forma:

glOrtho(limiteIzquierdo, limiteDerecho, limiteAbajo, limiteArriba, znear, zfar)

siendo todos flotantes.


Proyecciones perspectivas

Una proyección en perspectiva reduce y estirar los objetos más alejados del observador. Es importante saber que las medidas de la proyección de un objeto no tienen por qué coincidir con las del objeto real, ya que han sido deformadas.


Ejemplo: una escena simple

Código

El siguiente código es un programa que usa OpenGL mediante la librería GLUT. Primero se lista el código completo y luego se comenta línea por línea. Con él se aplicará lo aprendido en el anterior capítulo y el presente, además de nuevas funciones de la librería GLUT.

#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;
}






1. ¿Puede diferenciar entre los dos tipos de proyección?

La ortogonal aun que pareciera que es 3D en realidad solo es 2D  tiene un único ángulo de visión y en perspectiva la profundidad con que se ve la imagen depende del ángulo de visión.

2. ¿Entiende para que se usan las matrices y como las maneja opengl? explíquelo.

Se usan para hacer operaciones con vectores y dependiendo que se desee lograr se utiliza una propiedad diferente de las matrices, ya sea rotación, traslación, etc..

3. ¿Qué es la matriz identidad y para que se utiliza en opengl?

Cumple con la propiedad de ser el elemento neutro del producto de matrices, podría ser utilizada multiplicándola con un escalar y hacer una estalación con otra matriz vectores

5. explique las diferencias

La diferencia sería que el primer cubo sin rotar se ve como si fuera en 2D por que solo se ve una cara  y en perspectiva, ya nos podríamos dar cuenta de la profundidad del objeto y verlo en 3D