Listar los Uniforms y Attributes activos en GLSL

Cuando se programa empleando GLSL, un factor importantísimo y de sumo cuidado, está relacionado con la asignación entre los valores presentes en OpenGL y GLSL. Este proceso de binding se hace con las variables del tipo attribute, es decir las variables de diversos valores que recibe el vertex shader. Así, es posible consultar la ubicación (posición del binding) donde esta una variable en nuestro código. Esta operación se hace con la función glGetAttribLocation, que retorna dicha ubicación. La ubicación se puede asignar empleando la directiva layout(location = NUM), donde NUM es la posición de la ubicación, dentro del shader. Ahora, si el valor de retorno es -1, significa que hay una variable del tipo attribute que no está siendo empleada. Este proceso lo realiza el driver como parte de una optimización en el código. Las variables del tipo uniform, funcionan de manera similar (a excepción del uso del location).

Cuando una variable no está siendo empleada dentro del shader o no afecta el valor del fragmento final, entonces esta variable no debería estar presente. Muchas veces, por errores de programación o durante el proceso de desarrollo esta situación suele ocurrir. Resulta importante determinar cuándo ocurre está situación para tener ¡¡códigos perfectos!! 🙂

Entonces, ¿cómo saber cuándo no está siendo empleado una variable del tipo uniform o del tipo attribute?

Para ello, veamos una simple función que lista todos los valores activos de este tipo de variables de nuestro código. Vamos a asumir que el programa en GLSL utiliza como id una variable llamada m_uIdProgram del tipo unsigned int.

Primero, inicializaremos unas variables simples donde se almacenarán el número de variables activas del tipo attribute y del tipo uniform (iNumAttrib y iNumUniform), y la longitud máxima en caracteres del nombre de dichas variables.

GLint iMaxLengthU, iMaxLengthA, iNumAttrib, iNumUniform;
glGetProgramiv(m_uIdProgram, GL_ACTIVE_ATTRIBUTES, &iNumAttrib);
glGetProgramiv(m_uIdProgram, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &iMaxLengthA);
glGetProgramiv(m_uIdProgram, GL_ACTIVE_UNIFORMS, &iNumUniform);
glGetProgramiv(m_uIdProgram, GL_ACTIVE_UNIFORM_MAX_LENGTH, &iMaxLengthU);

Luego, realizaremos un ciclo por todas las variables attribute activas, tomando información como su longitud en caracteres, el tamaño de la variable, el tipo de dato y su nombre asignado. Todo ello, con la invocación a la función glGetAttribLocation. Posteriormente, empleando el nombre de la variable es posible obtener su ubicación (i.e. location). Por último, se imprime por pantalla en un formato “Ubicación | Nombre”.

GLchar* name = new GLchar[iMaxLengthA];
GLint written, size, location;
GLenum type;
for(int i = 0; i < iNumAttrib; i++)
{
  glGetActiveAttrib(m_uIdProgram, i, iMaxLengthA, &written, &size, &type, name);
  location = glGetAttribLocation(m_uIdProgram, name);
  std::cout << setw(5) << location << " | " << name << "," << std::endl;
}
delete name;

Para este punto, se muestran todas las variables del tipo attribute que están activas en nuestro programa en GLSL. Para conocer las variables del tipo uniform, se itera por todas las variables (ciclo hasta iNumUniform), y se utiliza el mismo código con una pequeña modificación en las líneas 6 y 7 del código anterior:

glGetActiveUniform(m_uIdProgram, i, iMaxLengthU, &written, &size, &type, name);
location = glGetUniformLocation(m_uIdProgram, name);

Este proceso también puede ser realizado de otra forma empleando las instrucciones glGetProgramInterface y glGetProgramResourceName pero depende si el hardware gráfico lo soporta ya que son instrucciones relativamente recientes (desde la versión 4.3 de OpenGL como extensión).

La función para listar las variables activas del tipo uniform y del tipo attribute en GLSL está disponible en este enlace de GitHubGist.

Resumen: Listar las variables activas attributes y uniform en GLSL te ayudará mucho a saber el status de tus shaders, ¡¡no lo olvides!!

Anuncios

Acerca de smittynpro

Escribiendo algunas cosas de computación gráfica
Esta entrada fue publicada en Código y etiquetada , , , . Guarda el enlace permanente.

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión /  Cambiar )

Google photo

Estás comentando usando tu cuenta de Google. Cerrar sesión /  Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión /  Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión /  Cambiar )

Conectando a %s