2013-09-29 2 views
3

J'utilise OpenGL 4.2 et je n'arrive pas à comprendre pourquoi j'obtiens une erreur GL_INVALID_VALUE dans ce programme. J'obtiens une erreur lorsque j'appelle glBindAttribLocation. Selon le OpenGL 4 reference page, il n'y a que deux raisons pour lesquelles GL_INVALID_VALUE doit être généré à partir de glBindAttribLocation.OpenGL 4.2 glBindAttribLocation valeur non valide?

void glBindAttribLocation(GLuint program, GLuint index, const GLchar *name);

  1. INVALID_VALUE est généré si l'indice est égal ou supérieur à MAX_VERTEX_ATTRIBS.
  2. INVALID_VALUE est généré si le programme n'est pas une valeur générée par OpenGL.

Comme vous pouvez le voir dans le programme ci-dessous, condition 1 n'est pas réglé depuis index est 20 et GL_MAX_VERTEX_ATTRIBS est 34921. La condition 2 n'est pas satisfaite car program est généré par OpenGL à l'aide de glCreateProgram(). Alors, comment pourrais-je obtenir une erreur GL_INVALID_VALUE?

// test.cpp 
#include <GL/glew.h> 
#include <GL/glut.h> 
#include <iostream> 

int main(int argc, char* argv[]) 
{ 
    glutInit(&argc, argv); 
    glutCreateWindow("Test"); 
    glewInit(); 

    std::cout << "Max Vertex Attributes : " << GL_MAX_VERTEX_ATTRIBS << std::endl; 
    // create program 
    GLuint program = glCreateProgram(); 
    if (program == 0) 
     std::cout << "Program error" << std::endl; 

    // clear existing errors   
    if (glGetError() != GL_NO_ERROR) 
     std::cout << "Pre-existing error" << std::endl; 

    // bind attribute location to index 20 
    glBindAttribLocation(program, 20U, "DoesNotExist"); 

    // why is this generating an INVALID_VALUE error? 
    if (glGetError() == GL_INVALID_VALUE) 
     std::cout << "Invalid value error" << std::endl; 

    glDeleteProgram(program); 
    return 0; 
} 

sortie Terminal

$ g++ test.cpp -lGLEW -lglut 
$ ./a.out 
Max Vertex Attributes : 34921 
Invalid value error 

également vérifier OpenGL 4,2

$ glxinfo | grep OpenGL 
OpenGL vendor string: NVIDIA Corporation 
OpenGL renderer string: GeForce GT 540M/PCIe/SSE2 
OpenGL version string: 4.2.0 NVIDIA 304.64 
OpenGL shading language version string: 4.20 NVIDIA via Cg compiler 
OpenGL extensions: 

Remarque: Selon le reference page. "glBindAttribLocation peut être appelée avant que tous les objets de vertex shader ne soient liés à l'objet programme spécifié Il est également permis de lier un index d'attribut générique à un nom de variable d'attribut qui n'est jamais utilisé dans un vertex shader." Donc le fait qu'il n'y a pas de shaders et que DoesNotExist n'existe pas n'est pas le problème.

+0

peut être un bug de pilote, mais pourquoi faites-vous cela? Je ne vois aucun point ... aussi avec 4.2 vous avez un emplacement d'attribut explicite. – yngccc

+0

Ceci est juste un programme factice pour répliquer un bogue dans un programme beaucoup plus grand. Je suis conscient que dans 4.2 je peux définir mes emplacements d'attributs dans mon shader mais j'ai structuré mon programme de telle manière que la liaison des emplacements soit optimale. En outre, ceci est répétable sur mon autre machine exécutant OpenGL 4.2 avec une Nvidia 560 GTX. Je vais essayer de mettre à jour les pilotes – jodag

Répondre

9

C'est la deuxième fois que je me souviens de cette question posée dans quelques mois maintenant. La dernière fois que cela a été demandé, bien qu'il ne soit pas immédiatement apparent que c'est la même question, c'était here. Il se résume à ceci: GL_MAX_VERTEX_ATTRIBS car le compilateur voit qu'il s'agit d'un jeton de pré-processeur qui définit un ID que vous pouvez utiliser pour demander au pilote OpenGL sa limite définie par l'implémentation au moment de l'exécution. Lorsque vous essayez d'imprimer cette valeur directement, la seule chose que vous faites est d'imprimer l'ID universel que toutes les implémentations OpenGL utilisent pour interroger cette limite particulière.

Pour obtenir la limite en fonction de la mise en œuvre effective, vous devez le faire à l'exécution:

int max_attribs; 
glGetIntegerv (GL_MAX_VERTEX_ATTRIBS, &max_attribs); 

Soit dit en passant, les implémentations OpenGL ne sont tenus de fournir un minimum de 16 par vertex attributs; la plupart ne vous donnent que le minimum, ce qui explique pourquoi 20 est hors-limites.

+0

Wonderful! J'ai testé et vous avez raison, GL_MAX_VERTEX_ATTRIBS est en réalité 16. – jodag

+1

Maintenant vient la partie difficile: utilisez-vous vraiment 20 attributs par sommet?:) Si oui, vous devrez trouver des moyens de simplifier radicalement la structure de vos données de vertex. Notez que des choses comme 'mat4' occupent 4 slots attrib de vertex. –

+0

Haha, je n'aurai pas besoin de 20 attributs par vertex, en partie parce que j'utilise un seul VBO avec plusieurs programmes avec différents vertex shaders. Aucun vertex shader n'a plus de 4 attributs de vertex. – jodag

Questions connexes