目前我正在尝试使用多个缓冲区绘制多个对象。
我不确定是否以适当的方式切换缓冲区以进行绘制,并且无法弄清楚如何进行绘制。
我有2个阵列:
quad_strip2
包含34个元素(要绘制的对象),每个元素QUAD_STRIP
使用52个顶点(总共1767个顶点)。 quad_strip3
包含48个元素,其中包含26个QUAD_STRIP
个顶点(总共1247个顶点)。 初始化代码
gl.GenBuffers(2, Buffers);
//SKIPED MATRICES AND SHADERS INITIALIZATION
float[] quad_strip2 = new float[]
{
// COUNT OF ELEMENTS: 34
// COUNT OF VERTICES: 52
-19.66171f, 8.161709f, 2f, //0
-19.66171f, 8.161709f, 4f, //1
........
-19.66171f, -6.838291f, 35f, //1767
};
float[] quad_strip3 = new float[]
{
// COUNT OF ELEMENTS: 48
// COUNT OF VERTICES: 26
-0.8537037f, 7.25f, 2f, //0
-0.8537037f, 7.25f, 4f, //1
........
-20f, -3.25f, 34.45f, //1247
};
//bind first buffer
gl.BindBuffer(OpenGL.GL_ARRAY_BUFFER, Buffers[0]);
//fill buffer with vertices
unsafe
{
fixed (float* verts = quad_strip2)
{
var prt = new IntPtr(verts);
gl.BufferData(OpenGL.GL_ARRAY_BUFFER, quad_strip2.Length * sizeof(float), prt,
OpenGL.GL_STATIC_DRAW);
}
}
//bind second buffer
gl.BindBuffer(OpenGL.GL_ARRAY_BUFFER, Buffers[1]);
//fill buffer
unsafe
{
fixed (float* verts = quad_strip3)
{
var prt = new IntPtr(verts);
gl.BufferData(OpenGL.GL_ARRAY_BUFFER, quad_strip3.Length * sizeof(float), prt,
OpenGL.GL_STATIC_DRAW);
}
}
gl.VertexAttribPointer((uint)Attrib_IDs.vPosition, 3, OpenGL.GL_FLOAT, false, 0, new IntPtr(0));
gl.EnableVertexAttribArray((uint)Attrib_IDs.vPosition);
绘图代码
//SKIPED FILLING VERTEX SHADER WITH MATRIXES
//DRAW ARRAYS
//binf first array and draw it
gl.BindVertexArray(Buffers[0]);
for (int i = 0; i < 34; i++)
{
gl.DrawArrays(OpenGL.GL_QUAD_STRIP, i * 52, 52);
}
//binf second array and draw it
gl.BindVertexArray(Buffers[1]);
shaderProgram.SetUniform3(gl, "color", 0, 0.4f, 1);
for (int i = 0; i < 48; i++)
{
gl.DrawArrays(OpenGL.GL_QUAD_STRIP, i * 26, 26);
}
//DRAW WIREFRAMES
shaderProgram.SetUniform3(gl, "color", 0, 0, 0);
gl.Enable(OpenGL.GL_POLYGON_OFFSET_FILL);
gl.PolygonOffset(1.0f, 1.0f);
gl.PolygonMode(FaceMode.FrontAndBack, PolygonMode.Lines);
gl.BindVertexArray(Buffers[0]);
for (int i = 0; i < 34; i++)
{
gl.DrawArrays(OpenGL.GL_QUAD_STRIP, i * 52, 52);
}
gl.BindVertexArray(Buffers[1]);
for (int i = 0; i < 48; i++)
{
gl.DrawArrays(OpenGL.GL_QUAD_STRIP, i * 26, 26);
}
gl.PolygonMode(FaceMode.FrontAndBack, PolygonMode.Filled);
结果我有这样的输出,这看起来不像我需要得到的。
答案 0 :(得分:2)
在绘图代码中的每个VertexAttribPointer
调用后,您需要BindBuffer
个调用。 VertexAttribPointer
适用于当前绑定的缓冲区。您当前的代码在init代码中只有一个VertexAttribPointer
调用,这在调用Buffers[1]
时发生。因此,所有绘制调用都将使用该缓冲区中的顶点数据。
BindVertexArray
。顶点数组对象(VAO)是顶点缓冲区(VBO)中不同类型的对象,您不能仅使用VBO的id进行BindVertexArray
调用。为了使这一切在没有VAO的情况下正常工作,您可以从初始化代码中删除VertexAttribPointer
调用。然后向您的绘图代码添加两个VertexAttribPointer
次调用,并将BindVertexArray
替换为BindBuffer
,将其结构如下:
gl.BindBuffer(OpenGL.GL_ARRAY_BUFFER, Buffers[0]);
gl.VertexAttribPointer((uint)Attrib_IDs.vPosition, 3, OpenGL.GL_FLOAT, false, 0, new IntPtr(0));
for (int i = 0; i < 34; i++)
{
gl.DrawArrays(OpenGL.GL_QUAD_STRIP, i * 52, 52);
}
gl.BindBuffer(OpenGL.GL_ARRAY_BUFFER, Buffers[1]);
gl.VertexAttribPointer((uint)Attrib_IDs.vPosition, 3, OpenGL.GL_FLOAT, false, 0, new IntPtr(0));
shaderProgram.SetUniform3(gl, "color", 0, 0.4f, 1);
for (int i = 0; i < 48; i++)
{
gl.DrawArrays(OpenGL.GL_QUAD_STRIP, i * 26, 26);
}
另一个选择是你真正使用顶点阵列对象(VAO)。为了实现这一点,您必须在init代码(glGenVertexArrays
)中创建这些对象,并在为每个缓冲区设置状态时绑定它们。它们允许您在设置期间设置所有状态,然后在准备绘制时仅进行单个绑定调用。您可以通过一些搜索找到代码示例。