我试图将本教程中的信息(Advanced-OpenGL/Instancing)和这些答案(How to render using 2 VBO)(New API Clarification)结合在一起,以便渲染正方形的示例,通过ArrayBuffer将每个示例的模型矩阵提供给着色器。我以下面的代码结束。我切片并测试了任何部分,问题似乎是模型矩阵本身没有正确传递到着色器。我正在使用Visual Studio中的OpenTK。
为了简单和调试,池只包含一个正方形,所以我仍然没有除数问题或其他我仍然不能处理的有趣的事情。
我的顶点数据数组包含位置的3个浮点数和颜色的4个浮点数(Stride=7倍浮点大小)。
我使用附加代码得到的结果是:
- 如果我删除顶点着色器中的模型倍增,我会得到我所期望的,一个红色正方形(渲染为两个三角形)和一个绿色边框(渲染为线环)。
- 如果我更改着色器并乘以模型矩阵,我会在屏幕中心上方看到一条红线,它的长度会随着时间的推移而变化。动画很有意义,因为模拟旋转的是正方形,因此Angular 会定期更新,因此计算的模型矩阵也会发生变化。另一个很好的结果,因为我实际上是在将动态数据发送到着色器。然而,我不能让我原来的正方形旋转和平移。
有什么线索吗?非常感谢。
顶点明暗器:
# version 430 core
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec4 aCol;
layout (location = 2) in mat4 imodel;
out vec4 fColor;
uniform mat4 view;
uniform mat4 projection;
void main() {
fColor = aCol;
gl_Position = vec4(aPos, 1.0) * imodel * view * projection;
}
片段着色器:
# version 430 core
in vec4 fColor;
out vec4 FragColor;
void main() {
FragColor = fColor;
}
OnLoad代码段(初始化):
InstanceVBO = GL.GenBuffer();
GL.GenBuffers(2, VBO);
GL.BindBuffer(BufferTarget.ArrayBuffer, VBO[0]);
GL.BufferData(BufferTarget.ArrayBuffer,
7 * LineLoopVertCount * sizeof(float),
LineLoopVertData, BufferUsageHint.StaticDraw);
GL.BindBuffer(BufferTarget.ArrayBuffer, VBO[1]);
GL.BufferData(BufferTarget.ArrayBuffer,
7 * TrianglesVertCount * sizeof(float),
TrianglesVertData, BufferUsageHint.StaticDraw);
GL.BindBuffer(BufferTarget.ArrayBuffer, 0);
// VAO SETUP
VAO = GL.GenVertexArray();
GL.BindVertexArray(VAO);
// Position
GL.EnableVertexAttribArray(0);
GL.VertexAttribFormat(0, 3, VertexAttribType.Float, false, 0);
GL.VertexArrayAttribBinding(VAO, 0, 0);
// COlor
GL.EnableVertexAttribArray(1);
GL.VertexAttribFormat(1, 4, VertexAttribType.Float, false, 3 * sizeof(float));
GL.VertexArrayAttribBinding(VAO, 1, 0);
int vec4Size = 4;
GL.EnableVertexAttribArray(2);
GL.VertexAttribFormat(2, 4, VertexAttribType.Float, false, 0 * vec4Size * sizeof(float));
GL.VertexAttribFormat(3, 4, VertexAttribType.Float, false, 1 * vec4Size * sizeof(float));
GL.VertexAttribFormat(4, 4, VertexAttribType.Float, false, 2 * vec4Size * sizeof(float));
GL.VertexAttribFormat(5, 4, VertexAttribType.Float, false, 3 * vec4Size * sizeof(float));
GL.VertexAttribDivisor(2, 1);
GL.VertexAttribDivisor(3, 1);
GL.VertexAttribDivisor(4, 1);
GL.VertexAttribDivisor(5, 1);
GL.VertexArrayAttribBinding(VAO, 2, 1);
GL.BindVertexArray(0);
OnFrameRender代码片断:
shader.Use();
shader.SetMatrix4("view", cameraViewMatrix);
shader.SetMatrix4("projection", cameraProjectionMatrix);
int mat4Size = 16;
for (int i = 0; i < simulation.poolCount; i++)
{
modelMatrix[i] = Matrix4.CreateFromAxisAngle(
this.RotationAxis, simulation.pool[i].Angle);
modelMatrix[i] = matrix[i] * Matrix4.CreateTranslation(new Vector3(
simulation.pool[i].Position.X,
simulation.pool[i].Position.Y,
0f));
//modelMatrix[i] = Matrix4.Identity;
}
// Copy model matrices into the VBO
// ----------------------------------------
GL.BindBuffer(BufferTarget.ArrayBuffer, InstanceVBO);
GL.BufferData(BufferTarget.ArrayBuffer,
simulation.poolCount * mat4Size * sizeof(float),
modelMatrix, BufferUsageHint.DynamicDraw);
GL.BindBuffer(BufferTarget.ArrayBuffer, 0);
// ----------------------------------------
GL.BindVertexArray(VAO);
GL.BindVertexBuffer(1, InstanceVBO, IntPtr.Zero, mat4Size * sizeof(float));
GL.BindVertexBuffer(0, VBO[0], IntPtr.Zero, 7 * sizeof(float));
GL.DrawArraysInstanced(PrimitiveType.LineLoop, 0, LineLoopVertCount, simulation.poolCount);
GL.BindVertexBuffer(0, lifeFormVBO[1], IntPtr.Zero, lifeFormTrianglesFStride * sizeof(float));
GL.DrawArraysInstanced(PrimitiveType.Triangles, 0, TrianglesVertCount, simulation.poolCount);
GL.BindVertexArray(0);
1条答案
按热度按时间jpfvwuh41#
这里有很多错误之处。
首先,您没有启用2之后的任何属性数组,即使着色器显示您的读数也是3-5。同样,您不需要为2之后的任何数组设置属性绑定。
但您更大的问题是使用
glVertexAttribDivisor
。对于你想要做的事情来说,这是一个“错误的功能”。这是设置除数的旧API。在单独的属性格式中,除数是缓冲区绑定的一部分,而不是顶点属性。因此,需要用
glVertexBindingDivisor
设置除数,给它的索引是您打算将缓冲区绑定到的索引。它应该是1。因此,您的代码应该如下所示: