C++ OpenGL 4.2 glBindAttribLocation无效值?

C++ OpenGL 4.2 glBindAttribLocation无效值?,c++,opengl,shader,opengl-4,C++,Opengl,Shader,Opengl 4,我使用的是OpenGL4.2,我不明白为什么我在这个程序中会出现GLU无效值错误。调用GLBindAttriblLocation时出错。根据,只有两个原因可以说明为什么应该从glbindAttriblLocation生成GL_INVALID_值 void glBindAttribLocation(GLuint程序、GLuint索引、const GLchar*name) 如果索引等于或大于最大顶点属性,则生成无效的顶点值 如果程序不是OpenGL生成的值,则生成无效的_值 从下面的程序中可以看到,

我使用的是OpenGL4.2,我不明白为什么我在这个程序中会出现GLU无效值错误。调用GLBindAttriblLocation时出错。根据,只有两个原因可以说明为什么应该从glbindAttriblLocation生成GL_INVALID_值

void glBindAttribLocation(GLuint程序、GLuint索引、const GLchar*name)

  • 如果索引等于或大于最大顶点属性,则生成无效的顶点值
  • 如果程序不是OpenGL生成的值,则生成无效的_值
  • 从下面的程序中可以看到,由于
    索引
    20
    GL\u MAX\u VERTEX\u ATTRIBS
    34921,因此未设置条件1。由于OpenGL使用
    glCreateProgram()
    生成
    程序,因此不满足条件2。那么,我怎么可能得到
    GL\u INVALID\u值
    错误呢

    // 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;
    }
    
    还需要验证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:
    

    注意:根据。“在将任何顶点着色器对象绑定到指定的程序对象之前,可以调用GLBindAttributeLocation。还允许将通用属性索引绑定到顶点着色器中从未使用过的属性变量名。”因此,没有加载着色器且不存在纹理列表这一事实并不是问题。

    这是我在几个月后第二次想起这个问题。上一次被问到这个问题时,虽然不是很明显这是同一个问题,但还是被问到了

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

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

    int max_attribs;
    glGetIntegerv (GL_MAX_VERTEX_ATTRIBS, &max_attribs);
    

    顺便说一句,OpenGL实现只需要提供至少16个逐顶点属性;大多数只给你最小值,这就解释了为什么20是不允许的。

    可能是一个驱动程序错误,但你为什么要这样做?我看不出有什么意义。。。在4.2中,你也有明确的属性位置。这只是一个虚拟程序,在一个更大的程序中复制一个bug。我知道,在4.2中,我可以在着色器中定义属性位置,但我已经以这样一种方式构建了我的程序,即绑定位置是最佳的。此外,这在我的另一台运行OpenGL 4.2和Nvidia 560 GTX的机器上也是可以重复的。我会尝试更新驱动程序的!我测试过了,你说得对,GL_MAX_VERTEX_ATTRIBS实际上是16。现在是最难的部分:你真的使用了20个逐顶点属性吗?:)如果是这样的话,您需要找出方法来大幅简化顶点数据结构。请注意,像
    mat4
    这样的东西占用了4个顶点属性槽。哈哈,我不需要20个逐顶点属性,部分原因是我使用一个VBO和多个具有不同顶点着色器的程序。没有一个顶点着色器具有超过4个顶点属性。哎呀,我指的是单VAO而不是VBother上面的代码片段为我返回了一个非常大的数字(可能是对于不总是设置的属性发生的情况)。我的猜测是GL_MAX_VERTEX_ATTRIBS并非总是在所有平台上设置。
    int max_attribs;
    glGetIntegerv (GL_MAX_VERTEX_ATTRIBS, &max_attribs);