jueves, 29 de marzo de 2012

Graficacion 3D "Unidad 3"

Enlace 1:
Configuración:
instalación:
Hardware:

El API de OpenGL 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.

Windows:

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.

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.

Tutorial:

Qué es OpenGL?

Es una interfaz software de hardware gráfico. Es un motor 3D cuyas rutinas están integradas en tarjetas gráficas 3D.

OpenGL como máquina de estados:

Cuando se activan o configuran varios estados de la máquina, sus efectos perdurarán hasta que sean desactivados.

El pipeline de renderizado de OpenGL:

La mayor parte de las implementaciones de ogl siguen un mismo orden en sus operaciones, una serie de plataformas de proceso que, en su conjunto crean lo que se suele llamar el “OpenGL Rendering Pipeline”.




Escribir código basado en OpenGL:

Sintaxis:

Todas las funciones de ogl comienzan con el prefijo “gl” y las constantes con “GL_”. Como ejemplos, la función glClearColor() y la constante GL_COLOR_BUFFER_BIT.
En ogl existen 8 tipos distintos de datos, de una forma muy parecida a los tipos de datos de C o C++. Además, ogl viene con sus propias definiciones de estos datos (typedef en C).

Sufijo
Tipo de dato
Corresponde en C al tipo...
Definición en ogl del tipo
b
Entero 8-bits
signed char
GLbyte
s
Entero 16-bits
short
GLshort
i
Entero 32-bits
int o long
GLint, GLsizei
f
Punto flotante 32-bits
float
GLfloat, GLclampf
d
Punto flotante 64-bits
double
GLdouble, GLclampd
ub
Entero sin signo 8-bits
unsigned char
GLubyte, GLboolean
us
Entero sin signo 16-bits
unsigned short
GLushort
ui
Entero sin signo 32-bits
unsigned int
GLuint,GLenum, GLbitfield



Librerías relacionadas con OpenGL:


OpenGL contiene un conjunto de poderosos pero primitivos comandos de muy bajo nivel. Además la apertura de una ventana donde pintar, en el sistema grafico que utilicemos (win32, X11, etc.), no entra en el ámbito de OpenGL. Por eso las siguientes librerías son muy utilizadas en la programación de aplicaciones de ogl:
OpenGL Utility Library (GLU): contiene bastantes rutinas que usan ogl a bajo nivel para realizar tareas como transformaciones de matrices, para tener una orientación especifica, subdivisión de polígonos, etc.
GLX y WGL: GLX da soporte para máquinas que utilicen X Windows System, para inicializar una ventana, etc. WGL sería el equivalente para sistemas Microsoft.
OpenGL Utility Toolkit (GLUT): es un sistema de ventanas, escrito por Mark Kilgard, que es independiente del sistema de ventanas usado, dándonos funciones tipo abrir_ventana().

Hello Word:

#include <GL/glut.h>
void reshape(int width, int height){ glViewport(0, 0, width, height); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(-1, 1, -1, 1, -1, 1); glMatrixMode(GL_MODELVIEW);} void display(){ glClear(GL_COLOR_BUFFER_BIT); glColor3f(1,1,1); glLoadIdentity(); glBegin(GL_TRIANGLES); glVertex3f(-1,-1,0); glVertex3f(1,-1,0); glVertex3f(0,1,0); glEnd(); glFlush();} void init(){ glClearColor(0,0,0,0);} int main(int argc, char **argv){ glutInit(&argc, argv); glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB); glutInitWindowPosition(50, 50); glutInitWindowSize(500, 500); glutCreateWindow("Hello OpenGL"); init(); glutDisplayFunc(display); glutReshapeFunc(reshape); glutMainLoop(); return 0;}

Dibujando en 3D:

El dibujo 3D en OpenGL se basa en la composición de pequeños elementos, con los que se va construyendo la escena deseada. Estos elementos se llaman primitivas. Todas las primitivas de ogl son objetos de una o dos dimensiones, abarcando desde simples puntos y líneas, a polígonos complejos. Las primitivas se componen de vértices, que no son más que puntos 3D. En este capítulo se pretende presentar las herramientas necesarias para dibujar objetos en 3D a partir de estas formas más sencillas. Para ello hay que deshacerse de la mentalidad en 2D de la computación gráfica clásica y definir el nuevo espacio de trabajo, ya en 3D.

Moviendonos por nuestro espacio en 3D:

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

Enlace 2:

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: m = [a1 ,a2 ,a3 ,a4 ,a5 ,a6 ,a7 ,a8 ,a9 ,a10, a11, a12, a13, a14, a15, a16]
es interpretada internamente por OpenGL como:

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.
void glGetFloatv(enum value, float *data); Permite obtener una copia de aquello que se indica en value. Por ejemplo si se pasan como parámetros MODELVIEW_MATRIX y un apuntador a un arreglo de flotantes tamaño 16 se obtiene una copia de dicha matriz a través del arreglo.

Enlace 3:

Proyección:

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);

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)


glu ofrece una versión alternativa, mucho más fácil de entender:

void gluPerspective(GLdouble fov, GLdouble aspect, 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.

Enlace 4:

Enlace 5:

4.1 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.

4.2 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.

4.2.1 El modelador.

Se recogen las transformaciones del observador y del modelado.

4.2.1.2 Transformaciones del modelo.

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.

4.2.2 Transformaciones de la 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.

4.2.3 Transformaciones de la vista.

Proyectar lo que hemos dibujado en 3D al 2D de la pantalla, en la ventana en la que estamos trabajando. Esta es la denominada transformación de la vista.

4.3 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.

4.3.1 El canal de transformaciones.

Beben modificarse dos matrices: la matriz del Modelador y la matriz de Proyección. Para activar una de las dos matrices utilizamos la función glMatrixMode. Hay dos parámetros posibles:

glMatrixMode(GL_PROJECTION);
 
y
 
glMatrixMode(GL_PROJECTION);
 
 
4.3.2 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.

4.3.2.1 Translacion.

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.

4.3.2.2 Rotacion.

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.

4.3.2.3 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.

4.3.3 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. 

4.3.3.1 Proyección ortográfica.

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.

4.3.3.2 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.

 

No hay comentarios:

Publicar un comentario