domingo, 29 de enero de 2012

OpenGL

OpenGL (Open Graphics Library) es una especificación estándar que define una API (Interfaz de programación de aplicaciones), multilenguaje y multiplataforma para escribir aplicaciones que produzcan gráficos 2D y 3D. La interfaz consiste en más de 250 funciones diferentes que pueden usarse para dibujar escenas tridimensionales complejas a partir de primitivas geométricas simples, tales como puntos, líneas y triángulos. Fue desarrollada originalmente por Silicon Graphics Inc. (SGI) en 1992 y se usa ampliamente en CAD, realidad virtual, representación científica, visualización de información y simulación de vuelo. También se usa en desarrollo de videojuegos, donde compite con Direct3D en plataformas Microsoft Windows.


Como instalar OpenGL

Paso 1


Instalar el compilador de C.


Una de las cosas que mas me sorprendió es que Ubuntu, no viene con el compilador de C, en su instalación de default (hasta ahora es el único Gnu/Linux donde me ha pasado esto), así que tienes que instalarlo desde los repositorios.
En Ubuntu solo es cuestión de instalarte los paquetes ya sea vía apt-get o via synaptic lo que te acomode mejor, al caso debes de instalar los siguientes paquetes:

  • build-essential
  • g++
  • g77
  • gcc
  • make

Estos paquetes no vienen solos, es decir probablemente necesites descargar muchos paquetes mas para satisfacer las dependencias de estos, sin embargo dado que tanto synaptic como apt-get, pueden satisfacer sus dependencia de manera automática solo debemos indicarle estos paquetes. tanto de gcc, como de g++ y g77, hay varias versiones de los paquetes, sin embargo el paquete sin números siempre es un paquete con la versión mas actual.
En resumen lo único que un usuario novato debe de teclear es:
  $sudo apt-get install build-essential g++ g77 gcc make

Paso 1.5 Probamos la instalación del compilador de C


En nuestro editor de textos plano favorito tecleamos un programa de C, básico por ejemplo un clásico hola mundo: hello.c Lo guardamos por ejemplo con el nombre de hello.c y vamos a compilarlo.
Con la siguiente instrucción:
$gcc hello.c -o hello
Podemos observa que la sintaxis para compilar un programa en C, es la siguiente:
$gcc [archivo fuente.c] -o [nombre de mi ejeculable]

2 Instalamos las librerias necesarias para OpenGL

Ahora necesitaremos instalar los siguientes paquetes:
freeglut3 freeglut3-dbg freeglut3-dev ftgl-dev gle-doc glut-doc glutg3 glutg3-dev libglu1-mesa libglu1-mesa-dev libgl1-mesa libgl1-mesa-dev libgl1-mesa-dri libglut3 libglut3-dev mesa-common-dev mesa-demos mesa-swrast-source mesa-utils
No se cuales sean los esenciales, yo siempre he instalado con todos, pero se que así funciona, muchos de ellos son dependencias, así que no igual lo único que debes de tener en cuenta es tratar de instalar freeglut-dev.
Importante: Si piensas tener tu computadora con Aceleración Gráfica (por ejemplo para tener Beryl), es decir instalar los drivers propietarios de ATI o de nVidia, debes hacerlo antes de hacer esta instalación, se pueden tener ambas funcionando pero poner el driver gráfico debe ser anterior a la instalación de OpenGL. De la contrario nuestros programas de OpenGL no tendrán aceleración
Para saber si nuestra computadora tiene o no aceleración Gráfica puedes ejecutar el comando glxinfo y ver la salida, en el renglón donde dice direct rendering: un “Yes”, significa que tenemos Aceleración gráfica. Una forma de filtrarlo es:
   $glxinfo | grep rendering
Por supuesto que tener o no Aceleración Gráfica es totalmente dependiente de tu hardware. Por lo que no se puede escribir una guía general, sin embargo hay muchísima información en la red sobre esto, mi experiencia es que si tu computadora tiene tarjeta de vídeo Intel o nVidia, no debes tener ningún problema, las ATI, en cambio debes de investigar un poco antes de hacerlas funcionar.

2.5Probar la instalación de OpenGL y glut

Nos tecleamos un programa sencillo de glut y OpenGL, por ejemplo este: ventana.c
Y ahora vamos intentar la compilación:
$gcc ventana.c -o ventana -lglut
Y debemos ver una ventana negra.
Si en al linea de comandos ven un warning que dice algo así como:

libGL warning: 3D driver claims to not support visual 0x5b
Pero la ejecución de el programa continua, no deben de preocuparse, este warning solo significa que no esta correctamente configurado su driver de la tarjeta de vídeo, pero es algo que no debe de afectar sus programas escritos en OpenGL, mas que en el performance, y no es un problema de su programa si no del driver de la computadora.
Obviamente el caso ideal es tener tanto el OpenGL como la aceleración gráfica funcionando al mismo tiempo, si ya tenían la aceleración gráfica y siguen este método no deben de tener ningún problema y ni siquiera les debe marcar ese molesto warning.
Usuarios de Red Hat y similares la receta es la misma, solo que deberán de tratar de instalar el freeglut-devel***.rpm, donde *** usualmente son la distribución, la arquitectura y versión del paquete, se recomienda que instalen el paquete que viene en sus discos, usualmente este paquete tiene muchas dependencias, así que la ayuda de un gestor de paquetes como yump o synaptic sin duda les ayudara.
En un post posterior hablare de como tener un IDE funcional que nos de mas ayuda a compilar programas de OpenGL en Linux, en particular en Ubuntu la idea es que el final de mi serie de post del tema se pueda tener un entorno de programación cómodo y funcional en Ubuntu, como para que puedan con ayuda de algún libro como el libro rojo autoaprender a programar con OpenGL.

CODIGO
/*cubetex.c           */
/* Rotating cube with texture mapping */
/* mouse buttons control direction of
/* rotation, keyboard allows start/top/quit */
/* E. Angel, Interactive Computer Graphics */
/* A Top-Down Approach with OpenGL, Third Edition */
/* Addison-Wesley Longman, 2003 */
#include <stdlib.h>
#include <GL/glut.h>
GLfloat planes[]= {-1.0, 0.0, 1.0, 0.0};
GLfloat planet[]= {0.0, -1.0,  0.0, 1.0};
 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[][4] = {{0.0,0.0,0.0,0.5},{1.0,0.0,0.0,0.5},
 {1.0,1.0,0.0,0.5}, {0.0,1.0,0.0,0.5}, {0.0,0.0,1.0,0.5},
 {1.0,0.0,1.0,0.5}, {1.0,1.0,1.0,0.5}, {0.0,1.0,1.0,0.5}};
void polygon(int a, int b, int c , int d)
{
/* draw a polygon via list of vertices */
  glBegin(GL_POLYGON);
 glColor4fv(colors[a]);
 glTexCoord2f(0.0,0.0);
 glVertex3fv(vertices[a]);
 glColor4fv(colors[b]);
 glTexCoord2f(0.0,1.0);
 glVertex3fv(vertices[b]);
 glColor4fv(colors[c]);
 glTexCoord2f(1.0,1.0);
 glVertex3fv(vertices[c]);
 glColor4fv(colors[d]);
 glTexCoord2f(1.0,0.0);
 glVertex3fv(vertices[d]);
 glEnd();
                          }
void colorcube(void)
{
/* 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(void)
{
/* 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();
 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;
 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);
}
void key(unsigned char k, int x, int y)
{
 if(k == '1') glutIdleFunc(spinCube);
 if(k == '2') glutIdleFunc(NULL);
 if(k == 'q') exit(0);
}
void
main(int argc, char **argv)
{
   GLubyte image[64][64][3];
   int i, j, r, c;
   for(i=0;i<64;i++)
   {
     for(j=0;j<64;j++)
     {
       c = ((((i&0x8)==0)^((j&0x8))==0))*255;
       image[i][j][0]= (GLubyte) c;
       image[i][j][1]= (GLubyte) c;
       image[i][j][2]= (GLubyte) c;
     }
   }
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
    glutInitWindowSize(500, 500);
    glutCreateWindow("colorcube");
/* need both double buffering and z buffer */
    glutReshapeFunc(myReshape);
    glutDisplayFunc(display);
   glutIdleFunc(spinCube);
   glutMouseFunc(mouse);
   glEnable(GL_DEPTH_TEST);
   glEnable(GL_TEXTURE_2D);
   glTexImage2D(GL_TEXTURE_2D,0,3,64,64,0,GL_RGB,GL_UNSIGNED_BYTE, image);
   glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT);
   glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT);
   glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
   glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
   glutKeyboardFunc(key);
   glClearColor(1.0,1.0,1.0,1.0);
   glutMainLoop();
}



No hay comentarios:

Publicar un comentario