尽管有 vao,glVertexAttribPointer 仍导致无效操作错误
glVertexAttribPointer causing Invalid Operation error despite having vao
可能是一个简短的问题,因为我可能搞砸了一些愚蠢的事情。
我一直在尝试在空闲时间让渲染系统在我的旧笔记本电脑上运行。我遇到了问题,并认为它与我的程序的原始设计有关,但现在我不太确定是否是这样。我已将渲染调用缩减为一个简单的渲染三角形示例,但仍然出现错误。
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) 关闭垂直同步时的无效枚举数。
此外,这台笔记本电脑是一台旧笔记本电脑,我开始考虑这样一个事实,即这台计算机的驱动程序/硬件可能太旧,无法真正进行这种更现代的 GL 渲染。在这种情况下,有没有一种好的方法可以测试我应该在这个硬件上 运行 哪个版本的 GL? (我在 C运行chbang,一个 linux debian 发行版。Iirc,我已经正确设置并安装了很多驱动程序和头文件,所以我认为它应该可以工作,但如果驱动程序问题导致这个,我再研究一下。)
有线索吗?我假设我缺少一些基本的东西,因为自从我上次使用 OpenGL 以来已经有一段时间了。
我认为你的绑定有误。您只需为 VAO 生成一个名称,绑定并设置您的缓冲区,然后使用分配的名称稍后绑定它。
因此,您应该执行以下操作。
在某些初始化方法中为您的 VAO 变量生成名称(当您设置缓冲区时):
GLuint vao; // make this accessible in global scope or through some class
glGenVertexArrays(1, &vao);
像以前一样调用绑定函数,在你的渲染方法中,使用之前分配给变量的 name vao
:
glUseProgram( shaderProgram );
glBindVertexArray( vao );
我想这可能是你的答案,最后,这就是我在书籍和教程中看到的 VAO 处理方式。
可能是一个简短的问题,因为我可能搞砸了一些愚蠢的事情。
我一直在尝试在空闲时间让渲染系统在我的旧笔记本电脑上运行。我遇到了问题,并认为它与我的程序的原始设计有关,但现在我不太确定是否是这样。我已将渲染调用缩减为一个简单的渲染三角形示例,但仍然出现错误。
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) 关闭垂直同步时的无效枚举数。
此外,这台笔记本电脑是一台旧笔记本电脑,我开始考虑这样一个事实,即这台计算机的驱动程序/硬件可能太旧,无法真正进行这种更现代的 GL 渲染。在这种情况下,有没有一种好的方法可以测试我应该在这个硬件上 运行 哪个版本的 GL? (我在 C运行chbang,一个 linux debian 发行版。Iirc,我已经正确设置并安装了很多驱动程序和头文件,所以我认为它应该可以工作,但如果驱动程序问题导致这个,我再研究一下。)
有线索吗?我假设我缺少一些基本的东西,因为自从我上次使用 OpenGL 以来已经有一段时间了。
我认为你的绑定有误。您只需为 VAO 生成一个名称,绑定并设置您的缓冲区,然后使用分配的名称稍后绑定它。
因此,您应该执行以下操作。
在某些初始化方法中为您的 VAO 变量生成名称(当您设置缓冲区时):
GLuint vao; // make this accessible in global scope or through some class glGenVertexArrays(1, &vao);
像以前一样调用绑定函数,在你的渲染方法中,使用之前分配给变量的 name
vao
:glUseProgram( shaderProgram ); glBindVertexArray( vao );
我想这可能是你的答案,最后,这就是我在书籍和教程中看到的 VAO 处理方式。