在 OpenGL4 中使用 VBOs/VAOs 渲染
Rendering using VBOs/VAOs in OpenGL4
我正在尝试将一些 old-style OpenGL 代码更新为现代 OpenGL4。
我有一个巨大的纹理和 pre-tessellated 立方体模型要渲染。
而不是那个,我现在得到这个:
那是一片白底 semi-arbitrary 黑色三角形。
我的 VAO/VBO 构建代码:
// Normal buffer
GL.GenBuffers(1, out VBONormals);
GL.BindBuffer(BufferTarget.ArrayBuffer, VBONormals);
GL.BufferData(BufferTarget.ArrayBuffer, (IntPtr)(Normals.Length * Vector3.SizeInBytes),
Normals, BufferUsageHint.StaticDraw);
GL.BindBuffer(BufferTarget.ArrayBuffer, 0);
// TexCoord buffer
GL.GenBuffers(1, out VBOTexCoords);
GL.BindBuffer(BufferTarget.ArrayBuffer, VBOTexCoords);
GL.BufferData(BufferTarget.ArrayBuffer, (IntPtr)(TexCoords.Length * Vector3.SizeInBytes),
TexCoords, BufferUsageHint.StaticDraw);
GL.BindBuffer(BufferTarget.ArrayBuffer, 0);
// Vertex buffer
GL.GenBuffers(1, out VBO);
GL.BindBuffer(BufferTarget.ArrayBuffer, VBO);
GL.BufferData(BufferTarget.ArrayBuffer, (IntPtr)(Positions.Length * Vector3.SizeInBytes),
Positions, BufferUsageHint.StaticDraw);
GL.BindBuffer(BufferTarget.ArrayBuffer, 0);
// Index buffer
GL.GenBuffers(1, out VBOIndices);
GL.BindBuffer(BufferTarget.ElementArrayBuffer, VBOIndices);
GL.BufferData(BufferTarget.ElementArrayBuffer, (IntPtr)(Indices.Length * sizeof(uint)),
Indices, BufferUsageHint.StaticDraw);
GL.BindBuffer(BufferTarget.ElementArrayBuffer, 0);
GL.GenVertexArrays(1, out VAO);
GL.BindVertexArray(VAO);
GL.BindBuffer(BufferTarget.ArrayBuffer, VBO);
GL.VertexAttribPointer(0, 3, VertexAttribPointerType.Float, false, 0, 0);
GL.BindBuffer(BufferTarget.ArrayBuffer, VBONormals);
GL.VertexAttribPointer(1, 3, VertexAttribPointerType.Float, false, 0, 0);
GL.BindBuffer(BufferTarget.ArrayBuffer, VBOTexCoords);
GL.VertexAttribPointer(2, 3, VertexAttribPointerType.Float, false, 0, 0);
GL.EnableVertexAttribArray(0);
GL.EnableVertexAttribArray(1);
GL.EnableVertexAttribArray(2);
GL.BindBuffer(BufferTarget.ElementArrayBuffer, VBOIndices);
// Clean up
GL.BindVertexArray(0);
GL.DisableVertexAttribArray(0);
GL.DisableVertexAttribArray(1);
GL.DisableVertexAttribArray(2);
GL.BindBuffer(BufferTarget.ArrayBuffer, 0);
GL.BindBuffer(BufferTarget.ElementArrayBuffer, 0);
和渲染代码:
VBOTexture.Bind();
GL.BindVertexArray(VAO);
//GL.DrawRangeElements(PrimitiveType.Triangles, 0, Positions.Length, Indices.Length, DrawElementsType.UnsignedInt, IntPtr.Zero);
GL.DrawArrays(PrimitiveType.Triangles, 0, Indices.Length);
顶点着色器:
#version 430 core
layout (location = 0) in vec3 position;
layout (location = 1) in vec3 normal;
layout (location = 2) in vec3 texcoord;
layout (location = 1) uniform mat4 projection;
layout (location = 0) out vec3 f_color;
void main()
{
f_color = normal;
gl_Position = projection * vec4(position, 1.0);
}
片段着色器:
#version 430 core
layout (binding = 0) uniform sampler2D tex;
layout (location = 0) in vec3 f_color;
out vec4 color;
void main()
{
vec4 tcolor = texture2D(tex, gl_TexCoord[0].st);
float dist = 0.0;
if (gl_TexCoord[0].x < 0.5)
{
dist = gl_TexCoord[0].x;
}
else
{
dist = 1.0 - gl_TexCoord[0].x;
}
if (gl_TexCoord[0].y < 0.5)
{
dist *= gl_TexCoord[0].y;
}
else
{
dist *= 1.0 - gl_TexCoord[0].y;
}
dist *= 32;
dist = min(1, dist);
color = vec4(tcolor[0] * dist, tcolor[1] * dist, tcolor[2] * dist, tcolor[3]);
}
请注意,将绘制调用切换到 commented-out 会产生相同的结果。
另请注意:原始代码完全相同,只是减去 VAO 块,并使用此进行渲染:
GL.PushClientAttrib(ClientAttribMask.ClientVertexArrayBit);
GL.BindBuffer(BufferTarget.ArrayBuffer, VBONormals);
GL.NormalPointer(NormalPointerType.Float, Vector3.SizeInBytes, IntPtr.Zero);
GL.EnableClientState(ArrayCap.NormalArray);
GL.BindBuffer(BufferTarget.ArrayBuffer, VBOTexCoords);
GL.TexCoordPointer(2, TexCoordPointerType.Float, Vector2.SizeInBytes, IntPtr.Zero);
GL.EnableClientState(ArrayCap.TextureCoordArray);
GL.BindBuffer(BufferTarget.ArrayBuffer, VBO);
GL.VertexPointer(3, VertexPointerType.Float, Vector3.SizeInBytes, IntPtr.Zero);
GL.EnableClientState(ArrayCap.VertexArray);
GL.BindBuffer(BufferTarget.ElementArrayBuffer, VBOIndices);
GL.DrawElements(PrimitiveType.Quads, Indices.Length, DrawElementsType.UnsignedInt, IntPtr.Zero);
GL.PopClientAttrib();
(除了出于不相关的原因我还将纹理坐标从 Vector2 切换到 Vector3)
我哪里做错了?
您的旧代码使用 drawElements
,但您的新代码使用 drawArrays
。
VBOTexture.Bind();
GL.BindVertexArray(VAO);
//GL.DrawRangeElements(PrimitiveType.Triangles, 0, Positions.Length, Indices.Length, DrawElementsType.UnsignedInt, IntPtr.Zero);
GL.DrawElements(PrimitiveType.Quads, Indices.Length, DrawElementsType.UnsignedInt, IntPtr.Zero);
我正在尝试将一些 old-style OpenGL 代码更新为现代 OpenGL4。
我有一个巨大的纹理和 pre-tessellated 立方体模型要渲染。
而不是那个,我现在得到这个:
那是一片白底 semi-arbitrary 黑色三角形。
我的 VAO/VBO 构建代码:
// Normal buffer
GL.GenBuffers(1, out VBONormals);
GL.BindBuffer(BufferTarget.ArrayBuffer, VBONormals);
GL.BufferData(BufferTarget.ArrayBuffer, (IntPtr)(Normals.Length * Vector3.SizeInBytes),
Normals, BufferUsageHint.StaticDraw);
GL.BindBuffer(BufferTarget.ArrayBuffer, 0);
// TexCoord buffer
GL.GenBuffers(1, out VBOTexCoords);
GL.BindBuffer(BufferTarget.ArrayBuffer, VBOTexCoords);
GL.BufferData(BufferTarget.ArrayBuffer, (IntPtr)(TexCoords.Length * Vector3.SizeInBytes),
TexCoords, BufferUsageHint.StaticDraw);
GL.BindBuffer(BufferTarget.ArrayBuffer, 0);
// Vertex buffer
GL.GenBuffers(1, out VBO);
GL.BindBuffer(BufferTarget.ArrayBuffer, VBO);
GL.BufferData(BufferTarget.ArrayBuffer, (IntPtr)(Positions.Length * Vector3.SizeInBytes),
Positions, BufferUsageHint.StaticDraw);
GL.BindBuffer(BufferTarget.ArrayBuffer, 0);
// Index buffer
GL.GenBuffers(1, out VBOIndices);
GL.BindBuffer(BufferTarget.ElementArrayBuffer, VBOIndices);
GL.BufferData(BufferTarget.ElementArrayBuffer, (IntPtr)(Indices.Length * sizeof(uint)),
Indices, BufferUsageHint.StaticDraw);
GL.BindBuffer(BufferTarget.ElementArrayBuffer, 0);
GL.GenVertexArrays(1, out VAO);
GL.BindVertexArray(VAO);
GL.BindBuffer(BufferTarget.ArrayBuffer, VBO);
GL.VertexAttribPointer(0, 3, VertexAttribPointerType.Float, false, 0, 0);
GL.BindBuffer(BufferTarget.ArrayBuffer, VBONormals);
GL.VertexAttribPointer(1, 3, VertexAttribPointerType.Float, false, 0, 0);
GL.BindBuffer(BufferTarget.ArrayBuffer, VBOTexCoords);
GL.VertexAttribPointer(2, 3, VertexAttribPointerType.Float, false, 0, 0);
GL.EnableVertexAttribArray(0);
GL.EnableVertexAttribArray(1);
GL.EnableVertexAttribArray(2);
GL.BindBuffer(BufferTarget.ElementArrayBuffer, VBOIndices);
// Clean up
GL.BindVertexArray(0);
GL.DisableVertexAttribArray(0);
GL.DisableVertexAttribArray(1);
GL.DisableVertexAttribArray(2);
GL.BindBuffer(BufferTarget.ArrayBuffer, 0);
GL.BindBuffer(BufferTarget.ElementArrayBuffer, 0);
和渲染代码:
VBOTexture.Bind();
GL.BindVertexArray(VAO);
//GL.DrawRangeElements(PrimitiveType.Triangles, 0, Positions.Length, Indices.Length, DrawElementsType.UnsignedInt, IntPtr.Zero);
GL.DrawArrays(PrimitiveType.Triangles, 0, Indices.Length);
顶点着色器:
#version 430 core
layout (location = 0) in vec3 position;
layout (location = 1) in vec3 normal;
layout (location = 2) in vec3 texcoord;
layout (location = 1) uniform mat4 projection;
layout (location = 0) out vec3 f_color;
void main()
{
f_color = normal;
gl_Position = projection * vec4(position, 1.0);
}
片段着色器:
#version 430 core
layout (binding = 0) uniform sampler2D tex;
layout (location = 0) in vec3 f_color;
out vec4 color;
void main()
{
vec4 tcolor = texture2D(tex, gl_TexCoord[0].st);
float dist = 0.0;
if (gl_TexCoord[0].x < 0.5)
{
dist = gl_TexCoord[0].x;
}
else
{
dist = 1.0 - gl_TexCoord[0].x;
}
if (gl_TexCoord[0].y < 0.5)
{
dist *= gl_TexCoord[0].y;
}
else
{
dist *= 1.0 - gl_TexCoord[0].y;
}
dist *= 32;
dist = min(1, dist);
color = vec4(tcolor[0] * dist, tcolor[1] * dist, tcolor[2] * dist, tcolor[3]);
}
请注意,将绘制调用切换到 commented-out 会产生相同的结果。
另请注意:原始代码完全相同,只是减去 VAO 块,并使用此进行渲染:
GL.PushClientAttrib(ClientAttribMask.ClientVertexArrayBit);
GL.BindBuffer(BufferTarget.ArrayBuffer, VBONormals);
GL.NormalPointer(NormalPointerType.Float, Vector3.SizeInBytes, IntPtr.Zero);
GL.EnableClientState(ArrayCap.NormalArray);
GL.BindBuffer(BufferTarget.ArrayBuffer, VBOTexCoords);
GL.TexCoordPointer(2, TexCoordPointerType.Float, Vector2.SizeInBytes, IntPtr.Zero);
GL.EnableClientState(ArrayCap.TextureCoordArray);
GL.BindBuffer(BufferTarget.ArrayBuffer, VBO);
GL.VertexPointer(3, VertexPointerType.Float, Vector3.SizeInBytes, IntPtr.Zero);
GL.EnableClientState(ArrayCap.VertexArray);
GL.BindBuffer(BufferTarget.ElementArrayBuffer, VBOIndices);
GL.DrawElements(PrimitiveType.Quads, Indices.Length, DrawElementsType.UnsignedInt, IntPtr.Zero);
GL.PopClientAttrib();
(除了出于不相关的原因我还将纹理坐标从 Vector2 切换到 Vector3)
我哪里做错了?
您的旧代码使用 drawElements
,但您的新代码使用 drawArrays
。
VBOTexture.Bind();
GL.BindVertexArray(VAO);
//GL.DrawRangeElements(PrimitiveType.Triangles, 0, Positions.Length, Indices.Length, DrawElementsType.UnsignedInt, IntPtr.Zero);
GL.DrawElements(PrimitiveType.Quads, Indices.Length, DrawElementsType.UnsignedInt, IntPtr.Zero);