OpenGL:glVertexAttribPointer() 在新的 NVIDIA 驱动程序上因步幅大于 2048 而出现“无效值”失败

Posted

技术标签:

【中文标题】OpenGL:glVertexAttribPointer() 在新的 NVIDIA 驱动程序上因步幅大于 2048 而出现“无效值”失败【英文标题】:OpenGL: glVertexAttribPointer() fails with "Invalid value" for stride bigger than 2048 on new NVIDIA drivers 【发布时间】:2014-01-01 02:26:40 【问题描述】:

是否有其他人认识到,使用新的 NVIDIA 驱动程序(从 331.58 WHQL 及更高版本)不再可能以大于 2048 的步幅调用 glVertexAttribPointer()?该调用创建 OpenGL 错误 Invalid value (1281)

例如,在使用驱动程序 331.58 WHQL 时调用 testStride(2049); 后,以下最小 GLUT 示例将生成 OpenGL 错误 1281

#include <iostream>
#include <GL/glut.h>
#include <windows.h>

using namespace std;

PFNGLVERTEXATTRIBPOINTERPROC glVertexAttribPointer = 0;

void testStride(const GLsizei stride)

    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, stride, 0);
    GLenum code = glGetError();
    if (code != GL_NO_ERROR)
         std::cerr << "glVertexAttribPointer() with a stride of " << stride << " failed with code " << code << std::endl;
    else std::cout << "glVertexAttribPointer() with a stride of " << stride << " succeeded" << std::endl;


void render(void)

    testStride(2048); // Works well with driver version 311.06 and 331.58
    testStride(2049); // Does not work with driver version 331.58 but works well with driver version 311.06


int main(int argc, char* argv[])

    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_SINGLE | GLUT_RGBA);
    glutCreateWindow("Window");
    glutDisplayFunc(render);

    glVertexAttribPointer = (PFNGLVERTEXATTRIBPOINTERPROC) wglGetProcAddress("glVertexAttribPointer");

    glutMainLoop();
    return 0;

你的意见是什么?我做错什么了吗?

@Christian Rau:非常感谢您的提示。我立即用 glVertexAttribPointer() 替换了 glVertexPointer() 调用,仍然得到相同的结果。

【问题讨论】:

您使用的是哪个版本的 OpenGL?由于glVertexPointer() 自版本 3.1 起已被弃用 我使用的是 OpenGL 2.0 版。它已被弃用,但新驱动程序不应该仍然兼容吗? @Vallentin 他们在使用兼容性配置文件时必须,这是使用 GLUT 创建上下文时的默认设置。但有趣的是,glVertexAttribPointer 也会发生这种情况,尽管很有可能glVertexPointer 只不过是glVertexAttribPointer 的包装器)。 2 KiB 的步幅是巨大的。这足以存储 128 个vec4 顶点属性。我能问一下你为什么需要这么大的步幅吗? @denim “因此,大于 2048 的值是完全有效的。” - 不,仅此一个还不够充分的理由。仅仅因为该变量可以容纳一个大到 32000 的数字,并不意味着该函数是为该域合理定义的。对于可以定义函数的每个可能的值范围,您没有单独的类型。我们不需要这个函数在内部对值做什么。 【参考方案1】:

OpenGL 4.4 添加了GL_MAX_VERTEX_ATTRIB_STRIDE,这正是它听起来的样子:对允许使用的最大步幅的硬性、实现定义的限制。它同样适用于separate attribute formats 和旧式glVertexAttribPointer

【讨论】:

以上是关于OpenGL:glVertexAttribPointer() 在新的 NVIDIA 驱动程序上因步幅大于 2048 而出现“无效值”失败的主要内容,如果未能解决你的问题,请参考以下文章

[OpenGL红宝书]第一章 OpenGL概述

OpenGL版本与OpenGL扩展机制

glfw 包含了opengl吗

qt opengl的图形怎么刷新

OpenGL是啥?

OpenGL 4 采用