| Un Shader es un programa que se ejecuta sobre la GPU en las etapas programables del pipeline y nos permite implementar efectos gráficos muy interesantes. A día de hoy hay tres tipos de Shaders: de vértices, de fragmentos y geométricos: Los de vértices nos permiten aplicar operaciones a los vértices que son enviados a la GPU permitiéndonos hacer efectos cómo Skinning, Displacement Mapping ... Los de fragmentos nos permiten aplicar transformaciones a los pixels en la etapa de fragmentos permitiéndonos hacer efectos como Normal Mapping, Blur, Bloom, Phong shading, DoF ,.. Los novedosos shaders geométricos nos permiten aplicar transformaciones a las primitivas(un conjunto de vértices) permitiendo hacer efectos como real-time tesellation, destrucción de mesh .... GLSL es el lenguaje de descripción de Shaders de OpenGL y en este artículo veremos cómo cargarlos, aplicarlos y pasarles parámetros. Además podréis descargar un ejemplo programado para Gnu/Linux. | |
| | programación gráfica | | | |
| 1. Introducción a OpenGL y su pipeline de rendering | | | OpenGL esta diseñado como una maquina de estados y los gráficos se generan mediante la computación de una serie de etapas. Este conjunto de etapas y las conexiones que existen entre ellas es el llamado pipeline de rendering. Un esquema muy simplificado del pipeline predefinido por en OpenGL (el llamado fixed pipeline) es el siguiente: | | | | | | Antes de que se pudieran usar funciones programables en el pipeline de rendering, los desarrolladores tenían que usar las funciones predefinidas. La etapa predefinida de vértices consiste en la realización de cómputos sobre el clip-space, para cada vértice, normal u otra operación común por vértice como el color, la generación de las coordenadas de textura, la transformación de normales o la normalización. La etapa predefinida de fragmentos se encarga de tareas como interpolar valores (colores o coordenadas de textura), acceso a texturas, aplicación de texturas (environment mapping y cube mapping), niebla y todas las demás computaciones para cada fragmento. Estos métodos predefinidos permiten al programador representar muchos modelos básicos de iluminación y efectos, como light mapping, reflexiones o sombras, usando multitexturas y multiples pasadas, pero esto se traduce en un aumento del numero de vértices que se envían a la gráfica (dos pasadas = x2 vértices, cuatro pasadas = x4 vértices, etc.). La adición de funciones programables al pipeline de rendering supone una mayor flexibilidad, ahora todas las funciones predefinidas por vértice y por fragmento se pueden remplazar por funciones propias que realicen otra serie de cálculos más específicos. | | |
| | | Esto permite a los desarrolladores delegar cómputos a la gráfica para la creación de efectos como displacement mapping, morphing, sistemas de partículas, y eso solo en la etapa de vértices. En la etapa de fragmentos se pueden programar funciones que nos permitan representar efectos como Per-pixel lighting, toon shading, parallax mapping, bump mapping, filtros propios de texturas, color kernel applications y todo lo que involucre el tratamiento de fragmentos. Ahora las funciones predefinidas son remplazadas por nuestros propios programas, y esto añade numerosas ventajas. Por ejemplo muchas funcionalidades predefinidas se pueden deshabilitar para Shaders simples, produciendo así un incremento en el rendimiento. O por el contrario se pueden hacer cálculos más complejos produciendo así resultados de mayor calidad. Otro campo de aplicación para las funciones programables es usar la GPU como coprocesador de la CPU. El trabajo en este área no ha hecho nada mas que comenzar pero ya se está usando en la industria para simular procesadores de sonido, simulaciones de fluidos, geometría computacional, computación científica y muchas otras aplicaciones. Para obtener más información sobre este tema podeis ver el artículo que escribí anteriormente: " ¿Que es Cuda?" | | | 2. Que es un Shader y como funciona | | | El lenguaje GLSL es el acrónimo de OpenGL Shading Language, y es un lenguaje de alto nivel basado en C. Fue creado por OpenGL ARB para aportar a los desarrolladores un control directo sobre el pipeline gráfico sin la necesidad de usar lenguaje ensamblador o lenguajes específicos de hardware. Llamamos Shader de OpenGL a un programa escrito en el lenguaje GLSL que se puede añadir al pipeline de procesamiento y permite añadir nuevas funcionalidades. Existen dos tipos de Shaders, los vertex Shaders y los fragments Shaders, aunque en general cuando hablamos de Shader nos estamos refiriendo a una combinación de ambos, que mediante la realización de cómputos sobre vértices y sobre fragmentos respectivamente nos proporcionaran la manera de programar funciones propias para aumentar las capacidades del ciclo de producción de gráficos. Los vertex Shaders se ejecutan en unidades de vértices y esta operan con los vértices que van llegando y sus datos asociados. El procesador de vértices suele hacer operaciones gráficas tradicionales como: • Vertex transformation
• Normal transformation and normalization
• Texture coordinate generation
• Texture coordinate transformation
• Lighting
• Color material application
| | |  | Los fragment Shaders se ejecutan en unidades de fragmentos y estas operan con fragmentos. Las tareas habituales que se hacen en esta etapa son: • Operations on interpolated values
• Texture access
• Texture application
• Fog
• Color sum
• Pixel zoom
• Scale and bias
• Color table lookup
• Convolution
• Color matrix
| | |  | | | En cuanto a los Shaders Geometricos hay muy poca información actualmente debido a lo relativamente nuevos que son. Para más información os remito al "Real-Time Rendering Tercera Edición". En lineas generales nos permiten aplicar transformaciones a las primitivas(un conjunto de vértices) permitiendo hacer efectos como real-time tesellation, destrucción de mesh .... | | | 3. Puesta en marcha de GLSL | | | Lo primero antes de empezar a cargar y usar Shaders, es definir una serie de constantes y punteros a funciones que se usaran después. Para ello en su programa principal debe definir lo siguiente: #define glXGetProcAddress(x) (*glXGetProcAddressARB)((const Glubyte*)x) PFNGLCREATEPROGRAMOBJECTARBPROC glCreateProgramObjectARB = NULL; PFNGLCREATESHADEROBJECTARBPROC glCreateShaderObjectARB = NULL; PFNGLSHADERSOURCEARBPROC glShaderSourceARB = NULL; PFNGLCOMPILESHADERARBPROC glCompileShaderARB = NULL; PFNGLGETOBJECTPARAMETERIVARBPROC glGetObjectParameterivARB = NULL; PFNGLATTACHOBJECTARBPROC glAttachObjectARB = NULL; PFNGLGETINFOLOGARBPROC glGetInfoLogARB = NULL; PFNGLLINKPROGRAMARBPROC glLinkProgramARB = NULL; PFNGLUSEPROGRAMOBJECTARBPROC glUseProgramObjectARB = NULL; PFNGLGETUNIFORMLOCATIONARBPROC glGetUniformLocationARB = NULL; PFNGLUNIFORM1FARBPROC glUniform1f = NULL; Una vez definidos los prototipos pero antes de empezar a usar las funciones de la librería GLEW de manera normal debemos asociar las constantes. glCreateProgramObjectARB = (PFNGLCREATEPROGRAMOBJECTARBPROC) glXGetProcAddress("glCreateProgramObjectARB"); glCreateShaderObjectARB = (PFNGLCREATESHADEROBJECTARBPROC) glXGetProcAddress("glCreateShaderObjectARB"); glShaderSourceARB = (PFNGLSHADERSOURCEARBPROC) glXGetProcAddress("glShaderSourceARB"); glCompileShaderARB = (PFNGLCOMPILESHADERARBPROC) glXGetProcAddress("glCompileShaderARB"); glGetObjectParameterivARB = (PFNGLGETOBJECTPARAMETERIVARBPROC) glXGetProcAddress("glGetObjectParameterivARB"); glAttachObjectARB = (PFNGLATTACHOBJECTARBPROC) glXGetProcAddress("glAttachObjectARB"); glGetInfoLogARB = (PFNGLGETINFOLOGARBPROC) glXGetProcAddress("glGetInfoLogARB"); glLinkProgramARB = (PFNGLLINKPROGRAMARBPROC) glXGetProcAddress("glLinkProgramARB"); glUseProgramObjectARB = (PFNGLUSEPROGRAMOBJECTARBPROC) glXGetProcAddress("glUseProgramObjectARB"); glGetUniformLocationARB=(PFNGLGETUNIFORMLOCATIONARBPROC) glXGetProcAddress("glGetUniformLocationARB"); glUniform1f = (PFNGLUNIFORM1FARBPROC) glXGetProcAddress("glUniform1fARB"); Por ultimo debemos comprobar si nuestro hardware soporta el uso de las extensiones ARB y Shaders GLSL, para ello lo haríamos de la siguiente forma: glewInit(); if (GLEW_ARB_vertex_shader && GLEW_ARB_fragment_shader) { “Todo correcto, su tarjeta gráfica soporta vertex y fragment shaders” } else { “Su tarjeta gráfica no soporta shaders” }
| | | 4. Carga de Shaders | 4.1. Carga
| | | Los Shaders tienen que ser leídos del fichero fuente que los contiene en el disco duro, y para ello tendremos dos cadenas: vs y fs donde almacenaremos respectivamente el contenido del vertex Shader y del fragment Shader. Además declaramos manejadores para objetos ARB, cuyos nombres serán v, f y p respectivamente para el vertex Shader, el fragment Shader y el Shader completo que contiene a ambos. char *vs,*fs; GLhandleARB v,f,p; v = glCreateShaderObjectARB(GL_VERTEX_SHADER_ARB); f = glCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB); p = glCreateProgramObjectARB(); Leemos el código fuente de el vertex y el fragment Shader, para ello nos ayudamos de la función TexFileRead (se detalla en el ejemplo de más adelante). vs = TextFileRead(vertex_shader_ruta); fs = TextFileRead(fragment_shader_ruta); glShaderSourceARB(v, 1, &vs,NULL); glShaderSourceARB(f, 1, &fs,NULL); free(vs);free(fs); Compilamos el vertex y el fragment Shader glCompileShaderARB(v); glCompileShaderARB(f); Por ultimo asociamos el vertex y el fragment Shader a nuestro Shader completo, que hemos llamado p y lo enlazamos. glAttachObjectARB(p,f); glAttachObjectARB(p,v); glLinkProgramARB(p); A partir de este momento podemos usar el Shader que ha sido cargado en p. | | | 4.2. Obtener información
| | | Podemos obtener el estado de enlazamiento y la información de un determinado Shader que ya ha sido cargado con las siguientes llamadas a funciones: glGetObjectParameterivARB(m_program,GL_OBJECT_LINK_STATUS_ARB,&resul); glGetObjectParameterivARB(m_program,GL_OBJECT_INFO_LOG_LENGTH_ARB,&length); glGetInfoLogARB(program,length,&laux,infoLog); | | | 4.3. Descarga
| | | Antes de eliminar la instancia de un Shader debemos desligar todos los objetos: void glDetachObjectARB(GLhandleARB container, GLhandleARB attached) Después borraremos el objeto con la siguiente función: void glDeleteObjectARB(GLhandleARB object) | | | 5. Aplicación de Shaders | 5.1. Usar un Shader
| | | Debemos activar el Shader para que pase a formar parte del pipeline de rendering, y después usaremos las primitivas de OpenGL para representar lo que queramos: glUseProgramObjectARB(program); “Renderizamos lo que queramos con las primitivas de OpenGL” glUseProgramObjectARB(0); Por ultimo cuando le pasamos el atributo “0” a esta función, el Shader es desactivado y sacado del pipeline de rendering y a partir de entonces se usara el pipeline habitual de OpenGL. Para concluir podríamos resumir el proceso de carga de la siguiente forma: | | |  | | | | A continuación en los siguientes apartados se detallara el proceso de comunicación entre una aplicación y el objeto que contiene al Shader. | | | 5.2. Usando variables Uniforms
| | | Los cuantificadores Uniforms son usados en el lenguaje GLSL para declarar variables globales cuyos valores son los mismos durante todo el proceso desde que es activado el Shader. Todas las variables Uniform son de solo lectura y deben ser inicializadas externamente durante el enlazamiento o a través de la API de OpenGL después de haber enlazado el Shader. Pasar variables desde aplicaciones OpenGL a objetos GLSL se hace mediante llamadas a glUniform, y es importante que el objeto ya haya sido enlazado, ya que sino la llamada no tendrá efecto. Las llamadas a glUniform no usan strings para los nombres de variables, en su lugar usan enteros que se pueden obtener usando: GLint glGetUniformLocationARB(GLhandleARB program, const GlcharARB *name) Se pueden hacer varias llamadas a glUniform: • glUniform{1|2|3|4}{f|i}ARB se usa para pasar valores simples. • glUniform{1|2|3|4}{f|i}vARB se usa para pasar un array de valores. • glUniformMatrix{2|3|4}fvARB se usa para pasar mat2, mat3, mat4, o arrays de ellos. Un ejemplo de esto sería: int location = glGetUniformLocationARB(program,”bumpSize”); glUniform1fARB(location, mybumpSizeVariable); Le estamos asociando a la variable “bumpSize” del Shader el valor de nuestra variable mybumpSizeVariable. | | | 5.3. Usando texturas
| | | Para pasar información de texturas desde aplicaciones OpenGL a objetos GSL debemos especificar el numero de unidad de textura que usamos (no el objeto de textura) y además asociar la textura que queramos a esa unidad con las funciones de la API de OpenGL. Esta tarea podemos hacerla con la llamada: glUniform1i(location,texture_unit); También podemos obtener el numero máximo de texturas que un objeto de programa soporta mediante la llamada: glGetInteger( GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS_ARB); Un ejemplo de uso de texturas sería: glActiveTextureARB(GL_TEXTURE0_ARB); glBindTexture(GL_TEXTURE_2D,textura_color); int location = glGetUniformLocationARB(shader_compilado,"myTexture" ); glUniform1iARB(location,0); Le estamos indicando que active la unidad de textura 0, después asociamos nuestra textura a esa unidad, y por ultimo mediante una llamada glUniform le decimos al objeto GLSL que la variable del Shader “myTexture” usara la unidad 0, que es a la cual nosotros hemos asignado nuestra textura. | | | 5.4. Usando Vertex Attributes
| | | El cuantificador Attribute se usa para declarar variables a las que OpenGL pasa valores en cada llamada a primitiva de vértices o como parte de un array de vértices. Son variables de solo lectura, y solo tiene sentido usarlos en Vertex Shaders. Los cuantificadores Attribute sólo pueden usar tipos float, vectores float o matrices. Todos los Vertex Attributes del estándar de OpenGL tienen nombres predefinidos para la fácil comunicación entre programas OpenGL y los objetos GLSL. Cada vez que se llama a funciones como glNormal, glTexCoord, o glColor se envía un Vertex Attribute predefinido al Vertex Shader. Los arrays de vértices (como glTexCoordPointer o glNormalPointer) también pueden usarlos. Nosotros nos centraremos en los atributos genéricos y como trabajan de la misma forma que los predefinidos, pero añadiendo además una flexibilidad que nos permitirá asignarles nombres descriptivos y tipos de datos complejos (como mat4, normal o vec). Los atributos de vértices se asocian a 'slots' libres y estos slots pueden obtenerse mediante una llamada a la API de OpenGL (el programa debe estar enlazado o sino no funcionara): GLint glGetAttribLocationARB(GLhandleARB program, const GlcharARB *name) Por ejemplo: int location = glGetAttribLocationARB(myProgram,”tangent”); Este método siempre devolverá un slot libre, a no ser que todos estén ocupados. En ese caso podemos forzar el uso de un determinado slot con la función glBindAttribLocationARB, no obstante se recomienda que OpenGL nos asigne uno libre de manera automática para mayor seguridad. Una vez que establecemos un slot, podremos enviar atributos al Shader como si fueran atributos estándar y vértices. Hay dos formas de hacerlo: de manera inmediata o mediante arrays de vértices. Modo inmediato: Usando glVertexAttrib*ARB entre glBegin/glEnd: int location = glGetAttribLocationARB(myProgram,”myattrib”); glBegin(GL_TRIANGLES); glVertexAttrib3fARB(location,0,1,0); glVertex3f(0,0,0); glVertexAttrib3fARB(location,1,0,0); glVertex3f(0,0,0); glVertexAttrib3fARB(location,0,1,1); glVertex3f(0,0,0); glEnd(); Arrays de vértices: Para usar arrays de vértices debemos habilitar primero los estados del cliente y el servidor: glActiveTextureARB(GL_TEXTURE5_ARB); glClientActiveTextureARB(GL_TEXTURE5_ARB); glEnableClientState(GL_VERTEX_ARRAY); glEnableClientState(GL_NORMAL_ARRAY); glVertexPointer(3,GL_FLOAT,0,geometry); glNormalPointer(GL_FLOAT,0,normals); “PINTAR ALGO” glDisableClientState(GL_VERTEX_ARRAY); glDisableClientState(GL_NORMAL_ARRAY); glActiveTextureARB(GL_TEXTURE0_ARB); glClientActiveTextureARB(GL_TEXTURE0_ARB); En este otro ejemplo podremos ver como se hace para atributos genericos: glActiveTextureARB(GL_TEXTURE5_ARB); glClientActiveTextureARB(GL_TEXTURE5_ARB); int location = glGetAttribLocationARB(myProgram,”myattrib”); glEnableVertexAttribArrayARB(location); glVertexAttribPointerARB(location,size,type,false,0,myarray); “PINTAR ALGO” glDisableVertexAttribArrayARB(location); glActiveTextureARB(GL_TEXTURE0_ARB); glClientActiveTextureARB(GL_TEXTURE0_ARB); El objetivo de este ejemplo es ver como se usan los arrays de atributos de vértices. La función mas compleja de este ejemplo es glVertexAttribPointerARB, y lo importante es aprender que esta trabaja de la misma forma que glNormalPointer pero de manera genérica. | | | 6. Desarrollo con GLEW | | | | En este apartado me he centrado en el caso de Gnu/Linux puesto que no hay disponible mucha información sobre como programar shaders en este sistema operativo. Para usuarios de Windows hay disponible mucha información sobre este apartado. En cuanto a programadores de sistemas Mac Os X no he probado a desarrollar Shaders en esta plataforma. No obstante si alguién quiere contribuir aportando información sobre el proceso en Windows o Mac OS X estaré encantado de añadirlo al artículo. | | | 6.1. Instalando Librerías
| | | Para programar en OpenGL usando GLSL se usa la librería GLEW (OpenGL Extension Wrangler). Deberá disponer de: • Runtime enviroment de OpenGL Extension Wrangler • Development enviroment de OpenGL Extension Wrangler Si instala las librerías en un GNU/Linux basado en Debian, los nombres que podrá encontrar en su repositorio serán algo como: • libglew[VERSION] • libglew[VERSION]-dev
| | | 6.2. Programación
| | | Cuando usted vaya a utilizar la librería GLEW en un programa, un aspecto a tener en cuenta es que deberá sustituir “#include <GL/gl.h>” de la librería estándar por el de esta librería : “#include <GL/glew.h>”. Debería quedar algo así: #include <GL/glew.h> #include <GL/glxew.h> #include <GL/glu.h> | | | 6.3. Compilación
| | | A la hora de compilar un programa en el que se ha usado la librería GLEW, debe añadir el FLAG “-lGLEW” para que su compilador encuentre las librerías necesarias. Para un programa escrito en C++ que usará SDL, OpenGL y GLSL con GLEW se quedaría algo así: g++ FUENTE.CPP -o BINARIO -lGL -lGLU -lGLEW -lm `sdl-config --cflags --libs` | | | 7. IDE's de Programación de Shaders | | | Programar Shaders requiere un amplio conocimiento del lenguaje GLSL y no es objeto de este documento abarcar tales aspectos, no obstante para el lector que quiera profundizar en este apartado, además de consultar la bibliografía que se incluye al final, podrá consultar los siguientes enlaces de interés: Junto con la documentación necesaria, es muy recomendable usar un IDE destinado a la programación de Shaders usando el lenguaje GLSL, por ejemplo “Shader Designer” de TyphoonLabs, que cuenta con versiones para GNU/Linux y MS Windows.
| | |  | | | No obstante, este programa no es el único que podemos encontrar, ya que existen otros IDE's disponibles para diferentes sistemas operativos entre los que se encuentran por ejemplo: RenderMonkey, Lumina, Quartz Composer, Demoniak 3D o glslDevil. | | | 8. Ejemplo completo | | | En el ejemplo incluido se ha usado el formato propio MGC de descripción de objetos, y este a su vez usa el formato OREJ de descripción de mallas tridimensionales. Primero debemos compilarlo, para ello nos situamos en el directorio del ejemplo: $ make Después podremos seleccionar nuestra configuración gráfica editando el fichero “config” Por ultimo para ejecutarlo: $ ./sdlglsl_example1 Si todo ha ido bien debería ver algo como esto: | | |  | | | Arriba a la izquierda se nos muestran los FPS. El primer objeto no usa Shaders, y se renderiza usando el pipeline habitual de OpenGL. El segundo objeto usa un Shader para hacer un sombreado Toon(tipo dibujo). El tercer objeto usa un Shader que simula Rayos X Por ultimo el cuarto objeto usa un Shader que implementa el sombreado Phong Podrá encontrar los respectivos Shaders en el directorio “datos/shaders” dentro del directorio del ejemplo. Además podrá encontrar el exportador del formato OREJ para Blender en el directorio “exportador_OREJ”. | | | | | | 9. Bibliografía | En cuanto a la bibliografía recomiendo especialmente el Orange Book y para programación de Shaders más avanzada el Shader X3. | | |  | | | Podeis obtener información sobre estos libros y otros relaccionados en el artículo sobre "Cómo hacer un Game Engine 3D: Por donde empezar" | | | 10. Descarga | | | - Descargar documento en pdf aquí.
| | | | 11. Proximos artículos relaccionados
| | | | Quién se haya quedado con ganas de leer más información sobre programación gráfica puede hecharle un vistazo al anterior artículo que escribí: "Cómo hacer un Game Engine 3D: Por donde empezar" En cuanto a los próximos artículos hablaré sobre cómo hacer efectos completos partiendo de la base de que este tutorial de puesta en marcha de Shaders ya se ha leído Tengo previsto hacer próximamente un artículo sobre en qué nivel(vértices,geométrico o fragmentos) implementar las ecuaciones de iluminación que vemos a menudo en los libros. Ya que dependiendo de en qué etapa se trate esta , conseguiremos diferentes resultados en los sombreados cómo por ejemplo: Flat, Gouraud, Phong .... Dejo para el futuro también tratar el tema las diferentes formas de hacer Bump Mapping: Normal Mapping, Parallax Mapping, Relief Mapping y mapas de altura de vértices Estos métodos se programan haciendo uso intensivo de la programación de Shaders. |
| Si te gustó el articulo sientete libre de subscribete al feed rss |
|
y luego estan facil como aplicar gltranslatef(x,y,z) o glrotatef(grado,x,y,z).
De todas formas para una vista tipo counter strike. tendras que hacerte algoritmos para que el raton aplique rotate en el eje que corresponda y con las teclas w,s,a,d aplique translate en la direcion que estes mirando.
Tengo hecho algo por ahi de eso, a ver si tengo tiempo y pronto posteo algo.
GLFloat camara[16];
glLoadMatrixf(camara)
y cosas asi pero no pasa nada..
Sobre la discretización, no podías haberlo expresado mejor ;) Yo aún estoy aprendiendo y sólo tengo nociones básicas, así que siempre son bienvenidas las explicaciones.
Lo de los warnings le echaré un vistazo a ver si puedo arreglarlos para mi PC y si me hago con ellos te lo comento por si interesa, pero vamos no tienen mucha importancia en el ejemplillo, mejor que gastes tu tiempo en deleitarnos con más explicaciones o sobre tu motor gráfico.
Saludos
En cuanto a lo de los erroes, en mi ordenador no da warnigns ni errores y eso que tengo activado el -wall al compilar. No se a que se debe.
De todas formas es un ejemplillo de nada. No voy a tocarlo porque no es mas que eso, en el motor gráfico que estoy haciendo no lo tengo así, pero eso es otra historia....
un saludete
He instalado todas las librerias (solo me faltaban las de debugger) y aun asi me da los mismos warnings y errores de compilacion. Si ya se que funciona, pero si te interesa dejarlo bien hecho deberías revisarlo, para saber el porque de esos warnings, al menos de los errores.
Por otro lado he visto que hay bastante aliasing en los monos. Mirando un poco el código he visto que hay un fichero de config donde hay un parametro de anti-aliasing y esta a 0, pero poniendolo a 2 o 4 se me ve igual, ¿me puedes orientar un poco al respecto?
Saludos
PD: Los comentarios no se notifican al mail? Lo de comentarios por rss me parece bien, pero cuando te suscribes a muchos, llenas el google reader de entradillas.
instala esto:
-Librerias de SDL:
libsdl (versión disponible en la distribución)
libsdl-dev (paquete de desarrollo en la version disponible)
libsdl-gfx (versión disponible en la distribución)
libsdl-gfx-dev (paquete de desarrollo en la version disponible)
libsdl-image (versión disponible en la distribución)
libsdl-image-dev (paquete de desarrollo en la version disponible)
libsdl-mixer (versión disponible en la distribución)
libsdl-mixer-dev (paquete de desarrollo en la version disponible)
libsmpeg (versión disponible en la distribución)
libsmpeg-dev (paquete de desarrollo en la version disponible)
-Librerias de OpenGl:
freeglut3 (versión disponible en la distribución)
freeglut3-dev (paquete de desarrollo en la version disponible)
freeglut3-dbg (paquete de desarrollo en la version disponible)
glutg3 (versión disponible en la distribución)
glutg3-dev (paquete de desarrollo en la version disponible)
libglut3 (versión disponible en la distribución)
libglut3-dev (paquete de desarrollo en la version disponible)
libgl1-mesa-dev (paquete de desarrollo en la version disponible)
libgl1-mesa-dri (versión disponible en la distribución)
libgl1-mesa-dri-dbg (paquete de desarrollo en la version disponible)
libgl1-mesa-glx (versión disponible en la distribución)
libglut1-mesa (versión disponible en la distribución)
libglut1-mesa-dev (paquete de desarrollo en la version disponible)
libglui-dev (paquete de desarrollo en la version disponible)
-Libreria libGlew para soporte de Shaders GLSL (Consultar Instalación):
libglew (versión disponible en la distribución)
libglew-dev (paquete de desarrollo en la version disponible)
Para arreglarlo puedes usar el truquillo de hacer un enlace simbólico de la 1.5 pero con el nombre de la 1.4 para que te lo pille.
#ln -s /usr/lib/libGLEW.so.1.5 /usr/lib/libGLEW.so.1.4
$ make
g++ src/main.cpp src/setup.cpp src/utils.cpp src/imagenes.cpp src/orej.cpp src/sprites.cpp src/objeto_mgc.cpp -o3 -mmmx -msse -msse2 -m3dnow -o sdlglsl_example1 -lGL -lGLU -lGLEW -lm `sdl-config --cflags --libs` -lSDL_image -lSDL_gfx
src/main.cpp:45: error: ‘’ has incomplete type
src/main.cpp:45: error: invalid use of ‘GLvoid’
src/main.cpp: In function ‘void CargarDatos()’:
src/main.cpp:76: aviso: conversión obsoleta de una constante de cadena a ‘char*’
src/main.cpp:77: aviso: conversión obsoleta de una constante de cadena a ‘char*’
src/main.cpp:78: aviso: conversión obsoleta de una constante de cadena a ‘char*’
src/main.cpp:79: aviso: conversión obsoleta de una constante de cadena a ‘char*’
src/main.cpp:96: aviso: conversión obsoleta de una constante de cadena a ‘char*’
src/main.cpp:98: aviso: conversión obsoleta de una constante de cadena a ‘char*’
src/main.cpp:99: aviso: conversión obsoleta de una constante de cadena a ‘char*’
src/main.cpp:100: aviso: conversión obsoleta de una constante de cadena a ‘char*’
src/main.cpp:101: aviso: conversión obsoleta de una constante de cadena a ‘char*’
src/main.cpp:102: aviso: conversión obsoleta de una constante de cadena a ‘char*’
src/main.cpp:103: aviso: conversión obsoleta de una constante de cadena a ‘char*’
src/main.cpp:104: aviso: conversión obsoleta de una constante de cadena a ‘char*’
src/main.cpp:105: aviso: conversión obsoleta de una constante de cadena a ‘char*’
src/main.cpp:106: aviso: conversión obsoleta de una constante de cadena a ‘char*’
src/main.cpp:107: aviso: conversión obsoleta de una constante de cadena a ‘char*’
src/main.cpp:108: aviso: conversión obsoleta de una constante de cadena a ‘char*’
src/main.cpp: In function ‘void BuclePrincipal()’:
src/main.cpp:45: error: faltan argumentos para function ‘void render()’
src/main.cpp:141: error: en este punto en el fichero
make: *** [all] Error 1
Por otro lado, creo que utilizas libglew1.4 y puesto que en intrepid viene la 1.5, para tener la 1.4 hay que desinstalar y forzar el paquete. No se si tengas algun motivo concreto (rendimiento, API, etc) para utilizar la versión anterior, pero sino, tal vez sería mejor utilizar la más reciente.
Al ejecutar me arroja lo siguiente (puesto que uso la 1.5):
./sdlglsl_example1
./sdlglsl_example1: error while loading shared libraries: libGLEW.so.1.4: cannot open shared object file: No such file or directory
Si puedes echalé un vistazo.
Saludos
Estoy ya dormio, me voy a acostar que el dia ha sido muy largo.
Para aprender que son los Shaders y enterarte de este temilla de gráficos que se que te gusta mucho te recomiendo que solo leas los puntos 1, 2, 7, 8 y 11, Así tardas menos. Y deja los demás puntos para cuando quieras implementar algo que requiera usar Shaders y ponerse a picar código. En ese momento si te será útil como guia paso a paso.
un saludete y Tank you Fran