尽管有 vao,但 glVertexAttribPointer 导致无效操作错误
Posted
技术标签:
【中文标题】尽管有 vao,但 glVertexAttribPointer 导致无效操作错误【英文标题】:glVertexAttribPointer causing Invalid Operation error despite having vao 【发布时间】:2015-03-03 00:19:04 【问题描述】:可能是一个简单的问题,因为我可能搞砸了一些愚蠢的事情。
我一直在尝试在空闲时间让渲染系统在我的旧笔记本电脑上运行。我遇到了问题,并认为这与我的程序的原始设计有关,但现在我不太确定是不是这样。我已将渲染调用简化为一个简单的渲染三角形示例,但仍然出现错误。
void RenderSystem::Render()
glClear( GL_COLOR_BUFFER_BIT );
GLuint vao;
glGenVertexArrays(1, &vao);
glBindVertexArray( vao );
glUseProgram( shaderProgram );
CheckForError();
glEnableVertexAttribArray( coord3dAttrib );
CheckForError();
GLfloat triangle[] =
0.0, 0.8, 0.0,
-0.8, -0.8, 0.0,
0.8, -0.8, 0.0,
;
glVertexAttribPointer(
coord3dAttrib,
3,
GL_FLOAT,
GL_FALSE,
0,
triangle
);
CheckForError();
glDrawArrays(GL_TRIANGLES, 0 , 3);
CheckForError();
glDisableVertexAttribArray( coord3dAttrib );
CheckForError();
SDL_GL_SwapWindow( window );
忽略过多的 CheckForError 函数调用——这只是为了查明是哪个函数导致了错误。它肯定发生在我调用 glVertexAttribPointer 之后。
值得注意的是,所有着色器和程序都已正确编译。上下文已初始化并由 SDL2 处理,并且在上下文初始化方面没有错误。我得到的唯一奇怪的错误是调用 SDL_GL_SetSwapInterval(0) 以关闭 vsync 时枚举数无效。
此外,这台笔记本电脑是一台旧笔记本电脑,我开始考虑这样一个事实,即这台电脑的驱动程序/硬件可能太旧而无法实际执行这种更现代的 GL 渲染风格。在这种情况下,有没有一种好方法来测试我应该在这个硬件上运行哪个版本的 GL? (我在 Crunchbang,一个 linux debian 发行版。Iirc,我已经正确设置并安装了很多驱动程序和头文件,所以我认为它应该可以工作,但如果驱动程序问题导致这种情况,我会进一步研究。 )
有什么线索吗?我假设我错过了一些基本的东西,因为我上次使用 OpenGL 已经有一段时间了。
【问题讨论】:
VAO 不需要指向 VBO 的数据吗? 我真的不确定。我曾经有一个 VBO,但当我想简化渲染过程时将其删除。我会尝试添加一个 VBO,但是当我之前有一个时,它仍然会导致无效操作错误。当我删除所有这些以尝试渲染一个简单的三角形时,它仍然给了我错误。我在网上看到了一些关于在没有 VAO 时如何发生此错误的帖子,并重新添加了 VAO 初始化调用,以查看它是否可以修复错误。 在核心配置文件中让顶点属性指针指向客户端内存是无效的。 "如果指针不为 NULL,则必须将非零命名缓冲区对象绑定到 GL_ARRAY_BUFFER 目标(请参阅 glBindBuffer),否则会生成错误。指针被视为缓冲区对象数据存储中的字节偏移量。缓冲区对象绑定 (GL_ARRAY_BUFFER_BINDING) 保存为索引索引的通用顶点属性数组状态 (GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING)。” 对于兼容性配置文件,这种行为是放宽的,但我不知道你有什么样的配置文件。跨度> 对,当你这样说的时候,它更有意义。我正在尝试访问硬件无法访问的内存池。 【参考方案1】:我认为你的绑定有问题。您只需为 VAO 生成一个名称,绑定并设置您的缓冲区,然后使用分配的名称稍后绑定它。
因此,您应该执行以下操作。
以某种初始化方法(当您设置缓冲区时)为您的 VAO 变量生成名称:
GLuint vao; // make this accessible in global scope or through some class
glGenVertexArrays(1, &vao);
像以前一样在渲染方法中调用绑定函数,使用之前分配给变量vao
的name:
glUseProgram( shaderProgram );
glBindVertexArray( vao );
我想这可能是你的答案,最后,这就是我习惯于在书籍和教程中看到 VAO 的处理方式。
【讨论】:
以上是关于尽管有 vao,但 glVertexAttribPointer 导致无效操作错误的主要内容,如果未能解决你的问题,请参考以下文章