顶点着色器 VAO 是不是需要 VBO?
Posted
技术标签:
【中文标题】顶点着色器 VAO 是不是需要 VBO?【英文标题】:Does a Vertex Shader VAO need a VBO?顶点着色器 VAO 是否需要 VBO? 【发布时间】:2016-11-17 03:09:32 【问题描述】:我正在尝试使用带有顶点着色器的 VAO。这有效,但前提是我将 bufferData 的长度设置为 0。我的理解是,当使用顶点着色器时,不需要 VBO,因为我的着色器正在生成四边形的顶点。如果我尝试在不绑定缓冲区的情况下创建 VAO,它也会崩溃。
正如我所提到的,这可行,但我很担心,因为在 Apple 的 Instruments 中,OpenGL 专家报告了一个严重错误:
Draw Call Exceeded Array Buffer Bounds
No Buffer Data - DYFKNoBufferData
这是生成 VAO 的代码:
glGenVertexArrays(1, &vaoID); // Create our Vertex Array Object
glBindVertexArray(avoid); // Bind VAO
GLfloat vertices[12]; // Vertices for our square
vertices[0] = -0.5; vertices[1] = 0.5; vertices[2] = 0.0; // Top left corner
vertices[3] = -0.5; vertices[4] = -0.5; vertices[5] = 0.0; // Bottom left corner
vertices[6] = 0.5; vertices[7] = 0.5; vertices[8] = 0.0; // Top Right corner
vertices[9] = 0.5; vertices[10] = -0.5; vertices[11] = 0.0; // Bottom right corner
glGenBuffers(1, &fboTextureVboID); // Create our Vertex Buffer Object
glBindBuffer(GL_ARRAY_BUFFER, fboTextureVboID); // Bind VBO
// As long as I set the buffer data length to 0
// then my glDrawArrays(GL_TRIANGLE_STRIP, 0, 4) call works
// otherwise I get EXC_BAD_ACCESS
glBufferData(GL_ARRAY_BUFFER, 0, vertices, GL_STATIC_DRAW);
// configure vertex attributes
glEnableVertexAttribArray (...
glVertexAttribPointer(...
...
glEnableVertexAttribArray(0); // Make our Vertex Array Object Inactive
glBindVertexArray(0); // Make our Vertex Buffer Object Inactive
绘图:
glUseProgram(vertexShaderProgram);
glBindVertexArray(vaoID);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
我可以放心地忽略 Apple 的错误吗?我正在尝试为顶点着色器使用 VAO,因为我想消除我的绘图代码中的所有顶点属性绑定。或者有没有更好的方法来使用带或不带 VAO 的着色器?
编辑:
这是我的顶点着色器源代码:
#version 300 es
uniform lowp mat4 uProjectionMatrix;
in lowp vec4 a_position;
in lowp vec2 a_texCoord;
out lowp vec2 v_texCoord;
void main()
gl_Position = uProjectionMatrix * a_position;
v_texCoord = a_texCoord;
及片段着色器来源:
#version 300 es
precision mediump float;
uniform lowp sampler2D uTexture;
in lowp vec2 v_texCoord;
out lowp vec4 fragmentColor;
void main()
fragmentColor = texture( uTexture, v_texCoord );
【问题讨论】:
"所以实际上不需要几何图形来绘制" 嗯...为什么不需要绘制数据?您是否打算通过使用gl_VertexID
来发明顶点数据?我并不是说这是错误的,但如果您的想法是您的顶点着色器不需要任何用户定义的输入,您应该在您的问题中这么说。
"禁用我们的顶点数组对象" 这不是那个调用的作用。 "Disable our Vertex Buffer Object" 这也不是 that 调用的作用。
根据post,顶点可以只是着色器的一部分。
抱歉,我应该写 "Make our Vertex Buffer Object inactive" - 这就是我的意思 - 我会编辑帖子。
您更新的 cmets 仍然没有描述这些函数的实际作用。
【参考方案1】:
你可以选择两件事之一。
拥有一个没有附加缓冲区对象的 VAO 是完全合法的。但是,这并不意味着“创建一个缓冲区对象,但不要在其中放入任何东西”。这意味着不要将缓冲区对象附加到 VAO。您只需调用glGenVertexArrays
来生成顶点数组,您就完成了。
没有呼叫glEnableVertexAttribArrays
。没有电话到glVertexAttribPointer
。如果您根本不使用顶点数组,则根本不应该进行这些调用。
拥有一个包含缓冲区对象的 VAO 也是完全合法的。这些工作正常。
你不能做的是创建一个没有分配的缓冲区对象,然后尝试将它用于顶点数据。如果您只删除 glBufferData
,就会发生这种情况。
所以你必须选择道路的一侧或另一侧。您的 VAO 要么使用一个或多个缓冲区,要么不使用。如果它使用缓冲区,则这些缓冲区必须具有存储空间。如果没有,那么它不会在意。
【讨论】:
您说只需使用glGenVertexArrays
,我就完成了。问题是这对我不起作用。除非我将它与 glBufferData 绑定,否则它会在 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4)
调用时崩溃。
@JeshuaLacock:你真的在使用 OpenGL ES 3.0 吗?您是否尝试在 VS 中使用输入变量?
是的,我使用的是 OpenGL ES 3.0。我正在尝试将顶点属性数组和制服与顶点着色器一起使用。
你说不给glEnableVertexAttribArrays
和glVertexAttribPointer
打电话,但我在我的代码中表明了这一点。
"但我在我的代码中展示了这一点。" 我可以看到您的代码调用了这些函数。我的观点是,OpenGL ES 3.0 中的任何内容都不需要您设置任何属性数组才能进行渲染。所以这些电话不是你应该需要的。以上是关于顶点着色器 VAO 是不是需要 VBO?的主要内容,如果未能解决你的问题,请参考以下文章