Busquedas

Programación de GLSL Shaders
Miércoles, 19 de Noviembre de 2008 00:00

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

 

 

 

 

TAGS: , , , , , , , , , , , , , ,

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
Comentarios (12)
12 Viernes, 09 de Enero de 2009 00:53
greenbite
Primero establece tu glookat o el frustrum
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.
11 Lunes, 05 de Enero de 2009 01:40
angel
hola me pueden ayudar es q estoy aprendiendo opengl y ya e logrado crear una mini engine pero quiere desplasarme por el espacio estilo counter strike e intentado con
GLFloat camara[16];
glLoadMatrixf(camara)
y cosas asi pero no pasa nada..
10 Viernes, 28 de Noviembre de 2008 20:56
lele
muy chevere, guardare la pagina para leerlo
9 Viernes, 21 de Noviembre de 2008 02:34
shakaran
Si tengo la maldición de la ATI. Pero bueno probare el ejemplo este finde en el portatil de mi padre que tiene una nVidia.

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
8 Viernes, 21 de Noviembre de 2008 01:24
greenbite
En cuanto a lo del fichero de configuración esta hecho aposta, 0 significa no aliasing, 2 significa aa a 2x y 4 aa a 4x. El hecho de que sigas percibiendo aliasing es porque tienes una ATI y no tiene muy bueno soporte que digamos en gnu/linux. Yo con una nvidia si que noto bastante la diferencia entre 0 y 4. Además como sabrás el antialiasing mejora el problema discretización de la información tomando más muestras por texel para hacer una ponderción adecuada donde se necesita. Si elevas la resolución se verá mejor, porque sino aunque este a 4 no hace milagros ya que no hay suficientes pixels en pantalla como para representar discretamente unos datos continuos.

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
7 Jueves, 20 de Noviembre de 2008 22:22
shakaran
Con el enlace simbolico ya me ejecuta el ejemplo.

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.
6 Jueves, 20 de Noviembre de 2008 09:17
greenbite
en cuanto a los errores de compilacion, puede que te falten librerias.

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)
5 Jueves, 20 de Noviembre de 2008 09:14
greenbite
Shakaran uso la libGLEW.so.1.4 porque lo hice hace tiempo.

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
4 Miércoles, 19 de Noviembre de 2008 23:36
shakaran
Muy buen artículo. Estoy teniendo algunos warnings y errores a la hora de compilar el archivo:

$ 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
3 Miércoles, 19 de Noviembre de 2008 23:10
greenbite
Tank you no hombre Thank you.

Estoy ya dormio, me voy a acostar que el dia ha sido muy largo.
2 Miércoles, 19 de Noviembre de 2008 23:08
greenbite
La programación de Shaders son útilizados ampliamente en plataformas de nueva generación, como PC, Xbox 360 o PS3. (No Wii ojo que usa un fixed pipeline).

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
1 Miércoles, 19 de Noviembre de 2008 22:57
franute
Muy bueno ñor, ahora mismo no tengo tiempo de terminar de leerlo pero lo dejo en cosas urgentes porque tengo ganas de terminar de leerlo, un saludo!

Agrega tu comentario

Tu nombre:
Comentario: