cf tuto3GL_reflect.cpp
lister les uniforms utilisés par un program
en plus des glGetUniformLocation( ), l'objet openGL program maintient la liste complètes des uniforms, leur noms, leur type, leur valeur et bien sur leur identifiant / location. glGetActiveUniform( ) permet de récupérer ces informations, mais il faut d'abord obtenir le nombre total d'uniform avec glGetProgram( ) :
GLuint progam= ... ;
GLint n= 0;
glGetProgramiv(program, GL_ACTIVE_UNIFORMS, &n);
GLint length_max= 0;
glGetProgramiv(program, GL_ACTIVE_UNIFORM_MAX_LENGTH, &length_max);
char *name= new char [length_max];
for(int index= 0; index < n; index++)
{
GLint glsl_size;
GLenum glsl_type;
glGetActiveUniform(program, index, length_max, NULL, &glsl_size, &glsl_type, name);
GLint location= glGetUniformLocation(program, name);
printf(
"uniform %d '%s': location %d, type %x, array_size %d\n", index, name, location, glsl_type, glsl_size);
}
delete [] name;
void printf(Text &text, const int px, const int py, const char *format,...)
affiche un texte a la position x, y. meme utilisation que printf().
récupérer la valeur actuelle d'un uniform est plus long, puisque la fonction qui renvoie la valeur dépend du type de l'uniform. pour les types les plus courants, on peut écrire quelquechose comme ça :
void print_uniform( const GLuint program, const int index, const char *name, const GLenum type )
{
int ivalue= 0;
float fvalues[16]= {};
switch(type)
{
case GL_BOOL:
glGetUniformiv(program, index, &ivalue);
printf(
" uniform '%s', type bool (%x), value= %s\n", name, type, ivalue ?
"true" :
"false");
break;
case GL_INT:
glGetUniformiv(program, index, &ivalue);
printf(
" uniform '%s', type int (%x), value= %d\n", name, type, ivalue);
break;
case GL_FLOAT:
glGetUniformfv(program, index, fvalues);
printf(
" uniform '%s', type float (%x), value= %f\n", name, type, fvalues[0]);
break;
case GL_FLOAT_VEC2:
glGetUniformfv(program, index, fvalues);
printf(
" uniform '%s', type vec2 (%x), values= %f %f\n", name, type, fvalues[0], fvalues[1]);
break;
case GL_FLOAT_VEC3:
glGetUniformfv(program, index, fvalues);
printf(
" uniform '%s', type vec3 (%x), values= %f %f %f\n", name, type, fvalues[0], fvalues[1], fvalues[2]);
break;
case GL_FLOAT_VEC4:
glGetUniformfv(program, index, fvalues);
printf(
" uniform '%s', type vec4 (%x), values= %f %f %f %f\n", name, type, fvalues[0], fvalues[1], fvalues[2], fvalues[3]);
break;
case GL_FLOAT_MAT4:
glGetUniformfv(program, index, fvalues);
printf(
" uniform '%s', type mat4 (%x), values=\n");
for(int r= 0; r < 4; r++)
{
for(int c= 0; c < 4; c++)
printf(
"%f ", fvalues[c*4 + r]);
}
break;
default:
printf(
" uniform '%s', type %x, type unknown\n", name, type);
break;
}
}
on peut utiliser cette fonction à chaque draw, pour vérifier que tous les uniforms ont bien une valeur correcte ou la modifier pour n'afficher un message que lorsqu'un uniform est égal à zero, ce qui peut signifier que l'application ne lui a pas donné de valeur...
exemple complet, avec un affichage mieux formaté et la gestion des tableaux d'uniforms, dans tuto3GL_reflect.cpp
lister les attributs utilisés par un program / vertex shader
la démarche est la même que pour les uniforms, il faut récupérer le nombre total d'attributs, la longueur max des noms, cf glGetProgram( ).
GLuint progam= ... ;
GLint n= 0;
glGetProgramiv(program, GL_ACTIVE_ATTRIBUTES, &n);
GLint length_max= 0;
glGetProgramiv(program, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &length_max);
char *name= new char [length_max];
for(int index= 0; index < n; index++)
{
GLint glsl_size;
GLenum glsl_type;
glGetActiveAttrib(program, index, length_max, NULL, &glsl_size, &glsl_type, name);
GLint location= glGetAttribLocation(program, name);
printf(
"attribute %d '%s': location %d, type %x, array_size %d\n", index, name, location, glsl_type, glsl_size);
}
delete [] name;
exemple complet dans tuto3GL_reflect.cpp
il est également possible récupérer quel buffer est associé à un attribut, cf glGetVertexAttrib( ) pour vérifier que tout est cohérent au moment du glDraw( ). c'est le vertex array object qui conserve ces informations, cf configurer un format de sommet, vertex array object.
GLint buffer= 0;
glGetVertexAttribiv(index, GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING, &buffer);
printf(
"attribute %d: buffer %d\n", index, buffer);