3

我正在使用 OpenGL 4.2,但我无法弄清楚为什么我在该程序中收到 GL_INVALID_VALUE 错误。调用 glBindAttribLocation 时出现错误。根据OpenGL 4 参考页,应该从 glBindAttribLocation 生成 GL_INVALID_VALUE 只有两个原因。

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

  1. 如果索引等于或大于 MAX_VERTEX_ATTRIBS,则生成 INVALID_VALUE。
  2. 如果程序不是 OpenGL 生成的值,则会生成 INVALID_VALUE。

从下面的程序可以看出,条件 1 没有设置,因为indexis20GL_MAX_VERTEX_ATTRIBSis 34921。条件 2 不满足,因为programOpenGL 使用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:

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

4

1 回答 1

10

这是我几个月来第二次回忆起这个问题。上次问这个问题时,虽然不是很明显这是同一个问题,但在这里

它归结为:GL_MAX_VERTEX_ATTRIBS正如编译器所见,它是一个预处理器标记,它定义了一个 ID,您可以使用该 ID 在运行时询问 OpenGL 驱动程序其实现定义的限制。当您尝试直接打印此值时,您唯一要做的就是打印所有 OpenGL 实现用于查询此特定限制的通用 ID。

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

int max_attribs;
glGetIntegerv (GL_MAX_VERTEX_ATTRIBS, &max_attribs);

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

于 2013-09-29T01:12:49.787 回答