Programas de sombreado

OpenGL ES está diseñado para recopilar los datos que describen una escena en 3D y manipularlos de tal forma que la escena se represente en forma de cuadrícula de píxeles en una pantalla 2D. El canal de OpenGL ES se refiere a las fases que atraviesan los datos de la escena en 3D hasta obtener una transformación de 3D en 2D.

En las versiones de OpenGL ES anteriores a la versión 2.0, las operaciones que tienen lugar en cada fase del canal son fijas. Puede establecer los parámetros que afectan a estas operaciones fijas, pero no puede definir operaciones nuevas. Por ejemplo, puede especificar si su modelo debe girar y cuánto debe hacerlo. Pero no puede definir un tipo de rotación nuevo que distorsione el modelo al girar.

En OpenGL ES 2.0 puede definir operaciones personalizadas del canal que actúan sobre los vértices y los fragmentos. Puede definir estas operaciones en el idioma de sombreado de GL. Debe definir tanto un programa de sombreado de vértices como un programa de sombreado de fragmentos.

Cree un objeto de sombreado, añada el código fuente en GLSL que especifica el sombreado y, a continuación, compílelo. La biblioteca GLUtils incluye un método glLoadShader() muy cómodo que puede utilizar para realizar todas estas tareas en una única llamada.

Práctica recomendada: trabajar con los programas de sombreado

Práctica recomendada

Descripción

Carga de programas de sombreado

Los tutoriales y código de ejemplo que muestran cómo utilizar los programas de sombreado de OpenGL ES, a menudo almacenan los programas en variables de cadena. Almacenar programas de sombreado en variables de cadena es útil para aprender al principio porque hace que el código sea más corto y más sencillo. Sin embargo, cuando escriba código de producción, debe almacenar sus programas de sombreado en archivos.

Busque los errores de compilación del programa de sombreado

Los programas de sombreado a menudo presentan errores de compilación. Debe comprobar siempre los errores de compilación y anotar todos los mensajes de error relacionados para ayudarle a solucionar los problemas. Es muy útil registrar todos los mensajes con el registro del evento, o incluso con una ventana de diálogo modal.

El método GLUtils.glLoadShader() devuelve 0 cuando el sombreado no realiza la compilación correctamente. El método acepta un parámetro de matriz de cadena, en el que se almacena cualquier mensaje de error de compilación. Debe comprobar siempre el valor devuelto y pasar una matriz de cadena para almacenar los mensajes de error.

String[] infolog = new String[2];
int vertexShader = GLUtils.glLoadShader(gl,
                                        GL20.GL_VERTEX_SHADER,
                                        vertexShaderSource,
                                        infolog,
                                        0);
int fragShader   = GLUtils.glLoadShader(gl,
                                        GL20.GL_FRAGMENT_SHADER,
                                        fragShaderSource,
                                        infolog,
                                        1);
if (vertexShader == 0)
{
   throw new IllegalStateException("Vertex shader error: " 
                                   + infolog[0]);                             
}                 
if (fragShader == 0)
{
   throw new IllegalStateException("Fragment shader error: " 
                                   + infolog[1]);                             
}

Compruebe el estado del enlace del programa de sombreado

Compruebe el GL_LINK_STATUS de los programas de sombreado para asegurarse de que están vinculados correctamente. Si aparece GL_LINK_STATUS == GL_FALSE, significa que se produjo un error de enlace y puede recuperar el mensaje de error llamando a GL20.glGetProgramInfoLog() antes que eliminar el programa de sombreado.

int program = gl.glCreateProgram();
if(program == 0)
{
   throw new 
    IllegalStateException("Error creating shader program");
}
gl.glAttachShader(program,vertexShader);
gl.glAttachShader(program,fragmentShader);
gl.glLinkProgram(program);
int[] linked = new int[1];
gl.glGetProgramiv(program,GL20.GL_LINK_STATUS,linked,0);
if(linked[0] == GL20.GL_FALSE)
{
   String log = gl.glGetProgramInfoLog(program);
   gl.glDeleteProgram(program);
   throw new 
    IllegalStateException("Program link error: " + log);
}

Elimine los objetos de sombreado después de vincular un programa de sombreado

Una vez el programa de sombreado está vinculado correctamente, no tiene por qué permanecer guardado en la memoria. Debe eliminar los objetos de sombreado de vértice y fragmento llamando a GL20.glDeleteShader().

gl.glDeleteShader(vertexShader);
gl.glDeleteShader(fragShader);

¿Le ha resultado útil esta información? Envíenos sus comentarios.