Anuncios Google

Lecciones 1-15 y Practica 00

Tutoriales de Programaciones

01.- ¿Qué hace OpenGL?:

OpenGL sirve para dibujar “en tiempo real” objetos en tres dimensiones. Estos objetos al iluminarlos (Luces) pueden tener unas características físicas de refracción de la luz (Normales y Materiales), también se les pueden pegar diferentes clases de texturas para mayor realismo.

Estos pueden ser representados en un sistema ortográfico u de perspectiva y través de una cámara. Pueden ser trasladados, rotados, escalados, etc...


02.- ¿Qué no hace OpenGL?:

OpenGL no gestiona el teclado ni el ratón, ni las ventanas, ni es capaz de cargar imágenes para las texturas, ni sonidos ni músicas.

Tampoco es capaz de escribir directamente en pantalla, ni de proyectar sombras, ni de calcular colisiones, ni de usar huesos (Bones) para animar modelos, etc...

La mayor parte de las carencias de OpenGL las supliremos con las librerías SDL, y el resto con programación.


03.- Los Archivos de Inclusión y Tipos OpenGL:

Solo necesitamos incluir dos archivos de cabecera “#include <GL/gl.h>” y “#include <GL/glu.h>”. En ellos vienen incluidos los siguientes tipos de datos que usaremos preferentemente cuando programemos para funciones OpenGL:


04.- El Sistema de coordenadas Cartesianas:

La base del dibujo 3D es el punto, este se representa por sus coordenadas en los ejes Ancho “X”, Alto “Y” y Profundo “Z”. Con dos puntos se representa una línea y con tres un triángulo...

Ejemplo del punto (10,5,3)


05.- Definir la Ventana de Visualización:

Aunque los ejes de coordenadas “X” e “Y” sean infinitos, no lo es así la pantalla. Además esta utiliza Píxeles y no Puntos. Hay que dejar claro que “1 Pixel” no tiene por que ser igual a  “1 Punto”. Con la siguiente función OpenGL especificamos como los Puntos de los ejes de coordenadas “X” e “Y” serán representados en la pantalla en Píxeles.

void glViewport( GLint X, GLint Y, GLsizei Ancho, GLsizei Alto );

Modo 1: X -100, Y -100, Ancho 200, Alto 200
 
Modo 2: X    0, Y    0, Ancho 200, Alto 200
 
Modo 3: X -100, Y  100, Ancho 200, Alto 200

 


06.- La Vista Ortográfica:

Este tipo de vista es la más simple de calcular pero no se ajusta a la realidad, en ella todos los rayos de proyección son paralelos entre si. Esto se traduce en que el tamaño de un objeto será siempre el mismo sin importar la distancia del observador. Pero este tipo de vista es útil por ejemplo, para pintar texto en pantalla, pintar menús, o simplemente dibujar objetos en 2D en los cuales no nos interese la profundidad “Z”.

glOrtho( GLdouble Izquierda, GLdouble Derecha, GLdouble Abajo, GLdouble Arriba, GLdouble Cerca, GLdouble Lejos );

La forma de cargar la matriz de proyección en modo ortográfico es la siguiente:

glMatrixMode( GL_PROJECTION );
glLoadIdentity();
glOrtho( 0, 640, 0, 480, -1, 1 );

OpenGL utiliza una matriz llamada “GL_PROJECTION” matriz de proyección para calcular la vista en el mundo 3D. Las diferentes operaciones y transformaciones de esta matriz darán como resultado la visión espacial desde un punto dado, normalmente la cámara. Ni sé ni quiero entrar en detalles sobre esta matriz puesto que OpenGL en sus librerías GL y GLU incluye funciones para operar con ella de forma cómoda.

 

 

 

 

 

 

 


07.- La Vista en Perspectiva:

Este tipo de proyección es con la que vemos normalmente el mundo que nos rodea. Los rayos de proyección convergen en un único punto llamado “Punto de Fuga” que es la pupila de nuestro ojo. Estos rayos tienen un ángulo determinado de apertura o campo de visión, y con esto todos los objetos son proyectados en el “Plano de Proyección” que es la ventana de visualización que definimos con la función “glViewport()”.

gluPerspective( GLdouble Apertura, GLdouble Aspecto, GLdouble Z_Cerca, GLdouble Z_Lejos );

Apertura: Es el ángulo de apertura en grados del eje “Y” del Punto de Fuga.
Aspecto: Es la relación entre la Anchura y Altura. Ósea Anchura / Altura.
Z_Cerca: Es el valor mínimo del eje “Z”, Plano de corte cercano.
Z_Lejos: Es el valor máximo del eje “Z”. Plano de corte lejano.

La forma de cargar la matriz de proyección en modo de perspectiva es la siguiente:

glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective( 45.0f, 640.0f/480.0f, .5f , -1000.0f );

 


08.- La Cámara:

Y para terminar todo lo referente a la matriz de proyección nos falta la cámara. Cuando nos movemos por el espacio tendríamos que mover todos los objetos para dar la sensación de movimiento. Pero es más sencillo mover la matriz de proyección y está se encargará de calcular la nueva proyección. Para hacer esto de forma fácil la librería GLU incluye la siguiente función llamada “gluLookAt();”. Esta función transforma la matriz de proyección a través de la posición del ojo, el punto de enfoque y un vector que indica la inclinación de la cámara. Este vector de inclinación es normalmente ( 0, 1, 0 ), que corresponde con la posición normal en la que se usa una cámara.

 

void gluLookAt( 
  GLdouble Ojo_X, GLdouble Ojo_Y, GLdouble Ojo_Z,
  GLdouble Enfoque_X, GLdouble Enfoque_Y, GLdouble Enfoque_Z,
  GLdouble Inc_X, GLdouble Inc_Y, GLdouble Inc_Z
);


09.- Primera toma de contacto con los Buffers:

La librería OpenGL utiliza varios tipos de buffers, pero ahora nos vamos a centrar en los dos más importantes.

El primero es el buffer de color “GL_COLOR_BUFFER_BIT”, en el se almacenan los colores de cada píxel de la ventana de visualización. Cuando OpenGL dibuja objetos los almacena en este buffer, pero este buffer en su configuración típica es doble. El motivo es simple, evitar que veamos como se forman los dibujos en la pantalla. Cuando se ha terminado de dibujar todo se conmuta el buffer “SDL_GL_SwapBuffers();” volcándolo a la pantalla. Ahora podemos seguir dibujando en la otra parte del buffer, y así tantas veces como queramos, normalmente entre 15 y 30 veces por segundo que es la velocidad necesaria para que nuestros ojos vean una composición en movimiento y no una serie de imágenes estáticas (Efecto Cinematográfico). Recomendablemente debemos limpiar el buffer con un color de fondo antes de dibujar de nuevo. Esto se define con la función “glClearColor( GLfloat Red, GLfloat Green, GLfloat Blue, GLfloat Alpha );”. La función “glColorMask();” permite activar o desactivar la escritura en el buffer de color por componentes usando el boleano “true | false”;

glClearColor( GLfloat Red, GLfloat Green, GLfloat Blue, GLfloat Alpha );
glClear( GL_COLOR_BUFFER_BIT );
glColorMask( GLboolean Red, GLboolean Green, GLboolean Blue, GLboolean Alpha );

El segundo buffer es el de profundidad “GL_DEPTH_BUFFER_BIT” y su función es importantísima, cada vez que se dibuja un píxel guarda la coordenada “Z” de profundidad respecto a la cámara. Ahora cuando se pinte un nuevo píxel puede comprobar si este está por delante o por detrás del anterior, evitando dibujar objetos lejanos por encima de objetos cercanos. Al igual que el buffer de color es recomendable limpiarlo antes de dibujar de nuevo, este valor se define con la función “glClearDepth( GLfloat z );”. Además tenemos que definir el tipo de comparación que realizará este buffer con la función “glDepthFunc( GLenum funcion );” :

glClearDepth( GLfloat z );       // Define el valor para limpiar.
glClear( GL_DEPTH_BUFFER_BIT );  // Limpia el buffer con "z".
glEnable(  GL_DEPTH_TEST );      // Activa el buffer de profundidad.
glDisable( GL_DEPTH_TEST );      // Desactiva el buffer.

glDepthFunc( GLenum funcion );
  funcion:
    - GL_NEVER    Siempre false.
    - GL_LESS     True si Z de referencia <  Z de profundidad.
    - GL_EQUAL    True si Z de referencia =  Z de profundidad.
    - GL_LEQUAL   True si Z de referencia <= Z de profundidad. ( Normal )
    - GL_GREATER  True si Z de referencia >  Z de profundidad.
    - GL_NOTEQUAL True si Z de referencia != Z de profundidad.
    - GL_GEQUAL   True si Z de referencia => Z de profundidad.
    - GL_ALWAYS   Siempre true.

El conjunto de todas estas funciones quedaría así, véase que la función que realmente realiza la limpieza de los buffers es “glClear();”, pero antes es necesario definir todas las funciones anteriores:

glClearColor( GLfloat Red, GLfloat Green, GLfloat Blue, GLfloat Alpha );
glClearDepth( GLfloat z );
glDepthFunc( GLenum funcion );
glColorMask( GLboolean Red, GLboolean Green, GLboolean Blue, GLboolean Alpha );
glEnable( GL_DEPTH_TEST );
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );

Ejemplo típico:

glClearColor( 0.0f, 0.0f, 0.0f, 0.0f);
glClearDepth( 1.0f );
glDepthFunc( GL_LEQUAL );
glColorMask( true, true, true, true );
glEnable( GL_DEPTH_TEST );
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );


10.- El Color de los Vértices en OpenGL:

En OpenGL el color se representa por sus componentes roja, verde, azul y opcionalmente alfa que es la transparencia. Ahora vamos a estudiar como aplicar un color a un punto o vértice. En la imagen izquierda tenemos un pentágono en el cual cada vértice tiene un color distinto, obsérvese como se produce un efecto de degradado entre los diferentes colores.

Cada componente de color tiene un rango que depende del tipo del dato, en el caso de GLubyte el rango vá de [ 0 a 255 ]. Si fuera tipo GLbyte sería [ -127 a 128 ] y si es GLfloat de [ 0.0 a 1.0 ].

void glColor3ub( GLubyte Rojo, GLubyte Verde, GLubyte Azul );
void glColor4ub( GLubyte Rojo, GLubyte Verde, GLubyte Azul, GLubyte Alfa );
void glColor3f( GLfloat Rojo, GLfloat Verde, GLfloat Azul );
void glColor4f( GLfloat Rojo, GLfloat Verde, GLfloat Azul, GLfloat Alfa );
void glColor4fv( GLfloat *Color );

Después de definir el color es necesario definir el vértice. Al igual que con el color la función para vértices sigue una estructura definida que es típica de las funciones OpenGL. Vamos a aprovechar para explicar un poco esta estructura común a muchas funciones OpenGL:

retorno: Como en cualquier function de C o C++.
 
librería: Puede ser “gl” o “glu” dependiendo de donde esté definida.
 
nombre: Es el nombre de la función, “Color”, “Vertex2, “Normal”...
 
#parámetros: Es el número de parámetros de entrada de la función, “2”, “3” o “4” normalmente.
 
tipo parámetros: El tipo OpenGL de los parámetros, “GLbyte”, “GLubyte”, “GLint”, “GLfloat” ... si hay una "v" ejemplo "4fv" el tipo es un puntero a un vector.
 
parámetros: Los parámetros propiamente dichos.

El ejemplo de arriba, pentágono de colores:

glcolor3ub( 255, 255, 255 ); // BLANCO
glvertex3i( -10,  15,   0 );
glcolor3ub(   0,   0, 255 ); // AZUL
glvertex3i( -10,  -5,   0 );
glcolor3ub(   0, 255,   0 ); // VERDE
glvertex3i(   0, -10,   0 );
glcolor3ub( 255,   0,   0 ); // ROJO
glvertex3i(  10,  -5,   0 );
glcolor3ub(   0,   0,   0 ); // NEGRO
glvertex3i(  10,   5,   0 );


11.- El Orden de los Vértices si altera el Resultado:

En el ejemplo anterior los vértices siguen un orden específico, esto no es por casualidad. En OpenGL el orden de los vértices si altera el resultado. Tres puntos definen un triángulo, pero un triángulo tiene dos caras. Como podemos aplicar diferentes características a cada cara, tenemos que poder diferenciar las caras frontales de las traseras. El método consiste en dibujar los vértices en sentido horario para una cara y antihorario para la otra. Para definir esto se utiliza la función “glFontFace();”:

Definición de las Caras Frontales.
glFrontFace( GL_CCW ); // Sentido Antihorario.
glFrontFace( GL_CW  ); // Sentido Horario.

Ahora que ya sabemos cuales son las caras frontales y cuales las traseras, podemos especificar cuales no queremos que se dibujen cuando no nos sea necesario. Imagínate dibujar las caras interiores de un cubo ¿Quién las va ha ver?, pero si dibujamos una hoja de un árbol tiene que verse por los dos lados.

glCullFace( GL_enum Parámetros );
   Parámetros:
      - GL_FRONT        //  NO CALCULA LAS CARAS FRONTALES.
      - GL_BACK         //  NO CALCULA LAS CARAS TRASERAS.

glEnable(  GL_CULL_FACE );    // ACTIVA EL CORTE DE CARAS.
glDisable( GL_CULL_FACE );    // DESACTIVA EL CORTE DE CARAS.

Nosotros utilizaremos como caras frontales las de sentido antihorario. Pero aún hay más. También podemos decir como se dibujarán las caras de un polígono con la función “glPolygonMode();” ver tabla inferior:

glPolygonMode( GL_enum Parámetros, GL_enum Modo );
  Parámetros:
     - GL_FRONT           // CARA FRONTAL.
     - GL_BACK            // CARA TRASERA.
     - GL_FRONT_AND_BACK  // AMBAS CARAS.
  Modo:
     - GL_FILL    // RELLENO.
     - GL_LINE    // LINEAS.
     - GL_POINT   // PUNTOS.

Visto todo lo anterior la configuración típica resultante sería la siguiente:

glFrontFace( GL_CCW );
glCullFace( GL_BACK );
glPolygonMode( GL_FRONT_AND_BACK, GL_FILL);
glEnable( GL_CULL_FACE );


12.- Transformando Vértices en Figuras Geométricas:

Bueno, hasta ahora hemos aprendido mucho sobre vértices pero aún nos falta. ¿Cuántas figuras podrías dibujar con cuatro vértices? 1 Cuadrado, 2 Triángulos, 1 Triángulo y 1 Punto, 4 Líneas, 2 Líneas y 1 Punto, 1 Línea y 2 Puntos, 4 Puntos...

Nos queda claro que los vértices por sí solos no dibujan nada, tenemos que decirle a OpenGL qué queremos que dibuje.

Para ese fin una de las funciones que tiene OpenGL es la función “glBegin();” y “glEnd();”. En la primera hay que definir el tipo de primitiva que queremos dibujar, luego dibujamos los vértices y terminamos con la segunda.

La función glBegin() - glEnd():

glBegin( GLenum Parámetros );  Dibuja diferentes tipos de primitivas.
  Parámetros:
    - GL_POINTS         Dibuja puntos.
    - GL_LINES          Dibuja líneas usando dos puntos.
    - GL_LINE_STRIP     Dibuja líneas con dos puntos iniciales, los siguientes
                        puntos continúan la línea.
    - GL_LINE_LOOP      Dibuja líneas  como (GL_LINE_STRIP) pero cierra  el  último
                        punto con el primero.
    - GL_TRIANGLES      Dibuja triángulos con 3 puntos.
    - GL_TRIANGLE_STRIP Dibuja triángulos encadenados. Con los trés primeros puntos
                        hace el primer triángulo, luego con cada nuevo punto y  los
                        dos anteriores crea los siguientes.
    - GL_TRIANGLE_FAN   Dibuja triángulos usando  el primer punto de  todos  y  los
                        dos últimos. El primer punto de cada triángulo es  común  y
                                  es el primero de todos.
    - GL_QUADS          Dibuja un Rectángulo usando 4 puntos.
    - GL_QUAD_STRIP     Dibuja un Rectángulos usando los 2 puntos anteriores  y los
                        2 posteriores.
    - GL_POLYGON        Dibuja un Polígono Convexo de "n" puntos.

glEnd();     Termina de dibujar puntos.

El ejemplo pentágono de colores:

glBegin( GL_POLYGON );
  glcolor3ub( 255, 255, 255 ); // BLANCO
  glvertex3i( -10,  15,   0 );
  glcolor3ub(   0,   0, 255 ); // AZUL
  glvertex3i( -10,  -5,   0 );
  glcolor3ub(   0, 255,   0 ); // VERDE
  glvertex3i(   0, -10,   0 );
  glcolor3ub( 255,   0,   0 ); // ROJO
  glvertex3i(  10,  -5,   0 );
  glcolor3ub(   0,   0,   0 ); // NEGRO
  glvertex3i(  10,   5,   0 );
glEnd();


13.- Puntos y Líneas:

En el caso de dibujar puntos y líneas tenemos unas funciones encargadas de definir sus propiedades, el grosor y en el caso de líneas podemos aplicar un patrón de bits. Esto significa que podremos definir líneas que sigan un patrón de puntos y rallas según los bits de una variable tipo GLushort. Los bits en “true” dibujan ralla y los que estén en “false” hueco.

Cambiar el grosor de puntos y líneas:

glPointSize( GLfloat tamaño );  // Establece el tamaño de los puntos
glLineWidth( GLfloat grosor );  // Establece el grosor de las líneas

Ejemplo de un triángulo usando Líneas con Patrón:

GLushort patron = 0x5555;          // Patrón de la Línea, usando los BITS.
GLint    factor = 5;               // Factor de repetición del Patrón.
glEnable( GL_LINE_STIPPLE );       // Activación de líneas usando Patrones.
  glLineStipple( factor, patron ); // Configuración de la Línea.
  glBegin( GL_LINE_LOOP  );
    glcolor3ub(   0,   0, 255 ); // AZUL
    glvertex3i(   0,   1,   0 );
    glcolor3ub(   0, 255,   0 ); // VERDE
    glvertex3i(  -1,  -1,   0 );
    glcolor3ub( 255,   0,   0 ); // ROJO
    glvertex3i(   1,   1,   0 );
  glEnd();
glDisable( GL_LINE_STIPPLE );


14.- Pequeñas puntualizaciones:

Ahora vamos con un ejercicio completo en el cual hay algunas funciones que aún no hemos explicado como por ejemplo “glShadeModel();”, “glHint();” y  “glEnable( GL_COLOR_MATERIAL );”. Aún no quiero explicarlas a fondo porque afectan a temas que veremos más adelante.

glShadeModel( GLenum Parámetro );

GL_FLAT                ||          GL_SMOOTH

Si quiero recordaros que la función “SDL_GL_SwapBuffers();” es la encargada de volcar el buffer de color a la pantalla. Todas las funciones que empiecen por el prefijo “SDL_” son propias de la librería SDL que no es motivo de estudio en este tutorial.


15.- Nuestro Primer Ejercicio OpenGL:

// -----------------------------------------------------------------------------
// Práctica 00
// -----------------------------------------------------------------------------
// Aquí está implementada la forma más simple plosible de iniciar SDL con Opengl
// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
// LINKER:
// -lmingw32 -lSDLmain -lSDL -lopengl32 -lglu32 -mwindows
// -----------------------------------------------------------------------------
#include <SDL/SDL.h>
#include <GL/gl.h>
#include <GL/glu.h>
#define MOVER   0.2f
#define V_Ancho 640
#define V_Alto  480
#define FOTOGRAMAS   25    // Fotogramas por segundo.
#define N_Ventana "Curso OpenGL con SDL"
class c_sdl_con_opengl {
  public:
    c_sdl_con_opengl() {
      // -- INICIACION SDL -----------------------------------------------------
      atexit( SDL_Quit );
      if( SDL_Init( SDL_INIT_VIDEO | SDL_INIT_TIMER ) < 0 ) exit(1);
      pantalla = SDL_SetVideoMode( V_Ancho, V_Alto, 16, SDL_OPENGL
                 | SDL_GL_DOUBLEBUFFER | SDL_HWPALETTE | SDL_HWSURFACE | SDL_HWACCEL );
      if( pantalla == NULL ) exit(1);
      SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); // -- Activa el Doble Buffer    --
      SDL_WM_SetCaption( N_Ventana, NULL );        // -- Pone nombre a la ventana. --
      if ( SDL_EnableKeyRepeat( 1, SDL_DEFAULT_REPEAT_INTERVAL ) ) exit(1);
      // -- INICIACION OPENGL --------------------------------------------------
      glClearColor( 0, 0, 0, 0 );    // Borrado del Buffer Color.
      glClearDepth( 1.0f );          // Borrado del Buffer Depth.
      glDepthFunc( GL_LEQUAL );      // Función de Borrado Buffer Depth.
      glEnable ( GL_DEPTH_TEST );    // Activamos el Test de Profundidad.
      glFrontFace( GL_CCW );         // GL_CCW   o GL_CW.
      glCullFace( GL_BACK );         // GL_FRONT o GL_BACK.
      glEnable( GL_CULL_FACE );      // NO DIBUJA LAS CARAS TRASERAS
      glShadeModel( GL_SMOOTH );     // Activamos el Sombreado Suave, (GL_FLAT) Plano.
      glPolygonMode( GL_FRONT_AND_BACK, GL_FILL);
      glHint( GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST );
      glViewport( 0, 0, V_Ancho, V_Alto );
      glMatrixMode( GL_PROJECTION ); // Selecciona la Matriz de Proyección.
      glLoadIdentity();
      gluPerspective( 45.0f, (GLfloat)V_Ancho/(GLfloat)V_Ancho, 0.5f , -1000.0f );
      glMatrixMode( GL_MODELVIEW );  // Selecciona la Matriz de Modelado.
      glLoadIdentity();
      // -- INICIACION DE LAS VARIABLES ----------------------------------------
      terminar = false;
      cox = 0.0f; coy = 0.0f; coz = -5.0f;
      cex = cox;  cey = coy;  cez = coz + 1;
      frames = Uint32( 1000 / FOTOGRAMAS );
      tiempo = SDL_GetTicks() + frames;
    };
    ~c_sdl_con_opengl() {
      SDL_FreeSurface( pantalla );
      pantalla = NULL;
      SDL_Quit();
    };
    void empieza( void ) {
      glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
      glLoadIdentity();
      gluLookAt( cox, coy, coz, cex, cey, cez, 0.0f, 1.0f, 0.0f );
    };
    bool termina( void ) {
      leer_teclado();
      espera_frame();
      SDL_GL_SwapBuffers();
      return terminar;
    };
  private:
    void leer_teclado(void) {
      while( SDL_PollEvent( &evento ) ) {
        switch( evento.type ) {
          case SDL_QUIT: { terminar = true; break; }
          case SDL_KEYDOWN:
            if( evento.key.keysym.sym == SDLK_ESCAPE ) { terminar = true; break; }
        }
      }
      SDL_PumpEvents();
      teclado = SDL_GetKeyState( NULL );
      if (teclado[SDLK_UP]   ) coz += MOVER;
      if (teclado[SDLK_DOWN] ) coz -= MOVER;
      if (teclado[SDLK_LEFT] ) cox += MOVER;
      if (teclado[SDLK_RIGHT]) cox -= MOVER;
      cex = cox; cez = coz + 1;
    };
    void espera_frame( void ) {
      t_espera = tiempo - SDL_GetTicks();
      if ( ( t_espera > 0 ) && ( t_espera < frames ) ) SDL_Delay( t_espera );
      else tiempo = SDL_GetTicks();
      tiempo += frames;
    }
    SDL_Surface *pantalla; // Superficie Pantalla.
    SDL_Event evento;      // Eventos del Teclado y Ratón.
    Uint8 *teclado;        // Teclado.
    bool terminar;
    GLfloat cox, coy, coz, cex, cey, cez;
    Uint32 frames, tiempo, t_espera;
};
// -- INICIO DE MAIN -----------------------------------------------------------
int main(int argc, char *argv[]) {
 
  GLfloat angulo = 0;
  c_sdl_con_opengl *sdl_con_opengl = new c_sdl_con_opengl;
 
  do { sdl_con_opengl->empieza();
 
    glRotatef( angulo, 1, 1, 0 );
    angulo += 1; if ( angulo >= 360 ) angulo = 0;
 
    glBegin( GL_TRIANGLE_STRIP );
      // CARA FRONTAL --------------------------------------------
      glColor3f(   1.0f,  1.0f,  0.0f );
      glVertex3f( -1.0f, -1.0f,  1.0f );  // Izq.    Abajo  Frente
      glColor3f(   1.0f,  0.0f,  0.0f );
      glVertex3f(  1.0f, -1.0f,  1.0f );  // Derecha Abajo  Frente
      glColor3f(   1.0f,  1.0f,  1.0f );
      glVertex3f(  0.0f,  1.0f,  0.0f );  // Centro  Arriba Centro
      // CARA DERECHA --------------------------------------------
      glColor3f(   0.0f,  1.0f,  0.0f );
      glVertex3f(  1.0f, -1.0f, -1.0f );  // Derecha Abajo  Fondo
      // CARA TRASERA --------------------------------------------
      glColor3f(   0.0f,  0.0f,  1.0f );
      glVertex3f( -1.0f, -1.0f, -1.0f );  // Izq.    Abajo  Fondo
      // BASE, CUADRADO FORMADO POR DOS TRIANGULOS ---------------
      glColor3f(   1.0f,  0.0f,  0.0f );
      glVertex3f(  1.0f, -1.0f,  1.0f );  // Derecha Abajo  Frente
      glColor3f(   1.0f,  1.0f,  0.0f );
      glVertex3f( -1.0f, -1.0f,  1.0f );  // Izq.    Abajo  Frente
      // CARA IZQUIERDA -------------------------------------------
      glColor3f(   1.0f,  1.0f,  1.0f );
      glVertex3f(  0.0f,  1.0f,  0.0f );  // Centro  Arriba Centro
      glColor3f(   0.0f,  0.0f,  1.0f );
      glVertex3f( -1.0f, -1.0f, -1.0f );  // Izq.    Abajo  Fondo
    glEnd( );
 
    glBegin( GL_LINE_LOOP );
      glColor3ub(  255,   0,   0 );  // ROJO
      glVertex3i(   -1,   1,   0 );  // Izquierda - Arriba
      glColor3ub(  255, 255,   0 );  // AMARILLO
      glVertex3i(    1,   1,   0 );  // Derecha   - Arriba
      glColor3ub(    0, 255,   0 );  // VERDE
      glVertex3i(    1,  -1,   0 );  // Derecha   - Abajo
      glColor3ub(    0,   0, 255 );  // AZUL
      glVertex3i(   -1,  -1,   0 );  // Izquierda - Abajo
    glEnd();
 
  } while ( !sdl_con_opengl->termina() );
  delete sdl_con_opengl;
  return EXIT_SUCCESS;
};


Práctica Nº 00 - Más simple imposible.

En esta práctica esta abordada la forma más simple posible de iniciar SDL con OpenGL dentro de una clase. Miraros bien el tutorial adjunto a esta práctica.

Descargar Práctica nº00  (Sólo usuarios registrados)

4.704545
Tu voto: Ninguno Votos totales: 4.7 (44 votos)

Anuncios Google

Comentarios

Opciones de visualización de comentarios

Seleccione la forma que prefiera para mostrar los comentarios y haga clic en «Guardar las opciones» para activar los cambios.

Gracias por el tutorial

Muy interesante el tutorial, recien empiezo a retomar opengl con interes para usarlo con SDL

Genial

Muchas gracias, me podre a intentra seguirlo. Una sugerencia es que sigas con algo de XNA. un saludo

Imagen de mpm88

Se ve bien

Pero ya me dio meio

Imagen de iRVing_Prog

ohh :O

muy bueno, excelente para aprender mas sobre la programacion (en general el unico motivo es programar xD)

SALUDOS.!

+3 :P no tengo mas


 

WooW pipagerardo, cuento

WooW pipagerardo, cuento tiempo sin verte por aqui!!

Espero más tutos tuyos! Felicidades!!!

Imagen de -Prince-

¡WOHOHOHOHOHOHOHOHOHOHOHO!

¡El mejor tuto de SB de la historia! ¡WAAAU! Intenté aprender OpenGL, pero me costaba... demasiado. :P Me pondré con esto para las vacaciones. ;)

Imagen de DRmack

Me arrodillo ante ti

Madre mia como se nota que te lo has currado. Eres un crack.

Saludos y sigue asi.

Imagen de P22

Por fin empieza a dársele

Por fin empieza a dársele imporancia a la programación en la sección de PC.

Muchas gracias eres el amo. +100 SB

Imagen de Churristian8

siempre

Siempre se le ha dado importancia :-P
Otra cosa es que hubiera voluntarios para desarrollarlo.

Imagen de P22

A eso me refería :p

A eso me refería :p

Imagen de Pana

Me he quedado noqueado :S.

Me he quedado noqueado :S. Para ti 50 scenebitos :).

Opciones de visualización de comentarios

Seleccione la forma que prefiera para mostrar los comentarios y haga clic en «Guardar las opciones» para activar los cambios.