Icono del sitio Shakaran

GLSL básico desde cero


Introducción – Conceptos

GLSL es el acrónimo de OpenGL Shading Language (Lenguaje Sombreador de OpenGL), una tecnología parte del API estandar OpenGL, que permite especificar segmentos de programas gráficos que serán ejecutados sobre el GPU. Su contrapartida en DirectX es el HLSL.

GLUT es un sistema de ventanas independientes para escribir programas OpenGL. Implementa una API de ventanas sencilla, las cuales hacen que el aprendizaje acerca de explorar la programación de OpenGL sea muy fácil.

Logo de GLEW

GLEW (OpenGL Extension Wrangler Library, es decir, Biblioteca disputadora de extensiones OpenGL) es un plataforma cruzada (entorno de ejecución) de extensiones de código abierto C/C++ para cargar librerias que ayuden en la consulta y extensiones OpenGL. GLEW suministra mecanimos eficientes en tiempo de ejecución para determinar que extensiones OpenGL están soportadas en la plataforma objetivo.

Instalación

Para instalar las librerias necesarias en Ubuntu Intrepid 8.10 necesitamos instalar las bibliotecas de ejecución de GLEW y GLUT (la más actual al momento de escribir es la 1.5 para GLEW y 3 para GLUT) y desarrollo de GLEW y GLUT.

Desde Synaptic buscar los paquetes libglew1.5, libglew-dev, freeglut3, freeglut3-dev o desde una simple linea en el terminal:

$ sudo apt-get install libglew1.5 libglew-dev freeglut3 freeglut3-dev

Código sencillo de ejemplo

Crearemos un fichero init.c con el siguiente código (a continuación lo explico):

/* init.c
Inicializa GLEW y hace varias pruebas sobre sus primitivas

Linea de compilación:
gcc init.c -o init -lGLEW -lGLU -lGL -lglut
*/
#include < stdio.h >
#include < stdlib.h >

#include < GL/glew.h > // Proporciona funcionalidad a gl y glu
#include < GL/glut.h > // Proporciona funcionalidad a glut

int main(int argc,char **argv) 
{
    glutInit(&argc,argv); //Inicializa la biblioteca GLUT
    glutCreateWindow("Prueba GLEW"); //Crea una ventana y da paso un contexto OpenGL

    GLenum err=glewInit(); // Crea un contexto de render válido para OpenGL
    if(GLEW_OK!=err)
    {// Problema: fallo de glewInit, algo esta seriamente mal.
        fprintf(stderr,"Error: %s\n",glewGetErrorString(err)); //Mostrar el error
        exit(EXIT_FAILURE);
    }

    //Mostramos la versión de GLEW
    fprintf(stdout,"Estado: Usando GLEW %s\n",glewGetString(GLEW_VERSION));

    if(glewIsSupported("GL_VERSION_2_0"))
    {
        printf("Listo para OpenGL 2.0\n");
        //Más código aquí
    }
    else
    {
        printf("OpenGL 2.0 no soportado\n");
        exit(EXIT_FAILURE);
    }

    glutMainLoop();

    return 0;
}

Lo primero que necesitamos es incluir las bibliotecas estandar de entrada y salida de C (stdio.h) para mostrar mensajes y la biblioteca estándar (stdlib.h) para funciones como exit() con constantes como EXIT_FAILURE.

Despues añadimos las bibliotecas de GLEW y GLUT, glew.h y glut.h respectivamente.

Creamos un main y llamamos a la primitiva glutInit() con los argumentos de nuestro main para que se inicialice la biblioteca GLUT, a continuación creamos una ventana que da paso al contexto OpenGL con la primitiva glutCreateWindow() pasandole como argumento el nombre que tendrá la ventana, en nuestro caso “Prueba GLEW”.

Una vez se ha creado el contexto OpenGL, ya podemos iniciar GLEW con la primitiva glewInit() que nos devolvera un valor de tipo GLenum que nos informará de posibles estados de error.

Despues comprobaremos si hubo error comparando dicho error con la constante GLEW_OK y si hay error, llamaremos a la primitiva glewGetString() para convertir el error a un mensaje y mostrarlo por la salida de errores estándar.

Si por el contrario todo va bien comprobamos si OpenGL 2.0 esta soportado por nuestro sistema y tarjeta gráfica, para ello invocamos a glewIsSupported() pasandole como argumento la constante que identifica a OpenGL 2.0 que es GL_VERSION_2_0. Si no hay fallos, ya podremos añadir más codigo (como Shaders) y hacer nuestras operaciones con OpenGL.

Si no mostraremos un error. Y por último devolvemos el control del programa a GLUT con glutMainLoop() que esperará que ocurran eventos en nuestro programa para reaccionar.

Compilación

Escribiremos lo siguiente en el terminal para crear el ejecutable:

$ gcc init.c -o init -lGLEW -lGLU -lGL -lglut

Observad, que incluimos las opciones -GLEW, -lGLU -lGL -lglut por cada biblioteca que utilizamos. Sin ellas no sería posible la compilación.

Para ejecutar el programa:

$ ./init

Errores frecuentes

1) Error: Error: Missing GL version

Despues de invocar a glutInit() debe crearse un contexto OpenGL, es decir, debemos invocar alguna función que realice las inicializaciones previas de OpenGL y este quede iniciado.

En nuestro ejemplo llamamos a glutCreateWindow() con lo que creamos una ventana que inicia dicho contexto. Puede ser que hayas omitido esta línea de código y por ello te aparezca este mensaje.

2) error: #error gl.h included before glew.h
error: #error glext.h included before glew.h

Has incluido antes glut.h que glew.h, recuerda el orden. Una manera fácil y nemotécnica es pensar que glew es escribirlos en orden alfabético, ya que glew.h empieza por gle y glut.h por glu.

3) error: GL/glut.h: No existe el fichero ó directorio

¿Has comprobado que tienes todos los paquetes intalados que se recomiendan en el artículo? Problablemente te falten.

4) ¿Tu fallo no esta aqui?

Explicalo en los comentarios o mandame un email y trataré ayudarte en lo que este a mi alcance.

Conclusiones

Este artículo esta realizado bajo mi propia experiencia y escrito para una lectura “amigable”, no me considero ningún experto, luego puede haber incoherencias o errores en el artículo y códigos mostrados.

Por otro lado, este artículo se centra más en el tema pÅ•áctico y la filosofía “show me the code“, si estás interesado en el tema y quieres profundizar aún mas en algunos conceptos teóricos, pero de manera informal y amigable, te recomiendo el artículo de mi colega Greenbyte: Programación de GLSL Shaders


Salir de la versión móvil