OpenGL 4.2 glBindAttribLocation无效值?

时间:2013-09-29 00:58:04

标签: c++ opengl shader opengl-4

我正在使用OpenGL 4.2,我无法弄清楚为什么我在这个程序中收到GL_INVALID_VALUE错误。当我调用glBindAttribLocation时出错。根据{{​​3}},只有两个原因可以从glBindAttribLocation生成GL_INVALID_VALUE。

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

  1. 如果index等于或大于MAX_VERTEX_ATTRIBS,则会生成INVALID_VALUE。
  2. 如果程序不是OpenGL生成的值,则生成INVALID_VALUE。
  3. 从下面的程序中可以看出,由于index20GL_MAX_VERTEX_ATTRIBS34921,因此未设置条件1。不满足条件2,因为OpenGL使用program生成glCreateProgram()。那我怎么可能得到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;
    }
    

    终端输出

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

    另外要验证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:
    

    注意:根据OpenGL 4 reference page。 “glBindAttribLocation可以在任何顶点着色器对象绑定到指定的程序对象之前调用。也允许将通用属性索引绑定到从未在顶点着色器中使用的属性变量名称。”因此,没有加载着色器且DoesNotExist不存在的事实不是问题。

1 个答案:

答案 0 :(得分:10)

这是我第二次回忆起现在几个月内被问到的这个问题。最后一次被问到这个问题时,here是{{3}}。

归结为:GL_MAX_VERTEX_ATTRIBS,因为编译器认为它是一个预处理器令牌,它定义了一个ID,可以用来向OpenGL驱动程序询问运行时实现定义的限制。当您尝试直接打印此值时,您唯一要做的就是打印所有OpenGL实现用于查询此特定限制的通用ID。

要获得实际依赖于实现的限制,您需要在运行时执行此操作:

int max_attribs;
glGetIntegerv (GL_MAX_VERTEX_ATTRIBS, &max_attribs);

顺便说一句,OpenGL实现只需要提供至少16个每顶点属性;大多数只给你最小,这解释了为什么20是超出界限。