c – OpenGL 4.2 glBindAttribLocation无效值?

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

void glBindAttribLocation(GLuint程序,GLuint索引,const GLchar *名称);

>如果index等于或大于MAX_VERTEX_ATTRIBS,则生成INVALID_VALUE.
>如果program不是OpenGL生成的值,则生成INVALID_VALUE.

从下面的程序可以看出,条件1没有设置,因为索引是20而GL_MAX_VERTEX_ATTRIBS是34921.条件2不符合,因为程序是由OpenGL使用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:

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

最佳答案
这是我第二次回忆起现在几个月内被问到的这个问题.最后一次被问及,虽然现在不是很明显,这是同一个问题,但是here.

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

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

int max_attribs;
glGetIntegerv (GL_MAX_VERTEX_ATTRIBS, &max_attribs);

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

转载注明原文:c – OpenGL 4.2 glBindAttribLocation无效值? - 代码日志