Reputation: 728
Currently I'am trying to draw multiple object using number of buffers.
I'am not sure that I switch buffers for drawing in proper way and cannot figure out how to do it.
I have 2 arrays:
quad_strip2
in amount contains 34 elements (objects to draw) and each of element for it's QUAD_STRIP
use 52 vertices (1767 vertices in total). quad_strip3
contains 48 elements with 26 vertices for QUAD_STRIP
(1247 vertices in total). Initialization code
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);
Drawing code
//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);
As result I have such output, which is not looks like what I need to get.
Upvotes: 0
Views: 993
Reputation: 54592
You need a VertexAttribPointer
call after each of the BindBuffer
calls in your drawing code. VertexAttribPointer
applies to the currently bound buffer. Your current code has only one VertexAttribPointer
call in the init code, which happened while Buffers[1]
was called. So all your draw calls will use vertex data from that buffer.
EDIT: I also just notice that you use BindVertexArray
in your draw code. Vertex array objects (VAO) are different kinds of objects from vertex buffers (VBO), and you can't just use the id of a VBO for a BindVertexArray
call. To get this all working without VAOs for now, you can remove the VertexAttribPointer
call from the init code. Then add two VertexAttribPointer
calls to your draw code, and replace the BindVertexArray
with BindBuffer
, to structure it like this:
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);
}
The other option is that you really use Vertex Array Objects (VAO) all the way. For that to work, you have to create those objects in the init code (glGenVertexArrays
), and bind them while setting up the state for each buffer. They allow you to set up all your state during setup, and then only make a single bind call when you get ready to draw. You should be able to find code examples for that with some searching.
Upvotes: 2