Simple VBO Example

Mar 23, 2012 at 5:32 AM

I have been struggling the past day or so getting Vertex Buffer Objects working. After looking at the latest source I noticed that the gl.DrawElements method was recently changed to accept a uint array as well as a pointer to the indices. I threw together a quick simple VBO sample that uses the uint[] parameter in a WPF project.

Here is the MainWindow.xaml:

http://pastebin.com/fmTxbzNQ

Here is the MainWindow.xaml.cs

http://pastebin.com/6uiEh4QM

 

For those curious without looking at the entire files:

/// Variable declarations
float[] vertices = new float[]
	{                 
		0, 0, 0, // 0 bottom back left 
		1, 0, 0, // 1 bottom front left
		1, 1, 0, // 2 top front left
		0, 1, 0, // 3 top back left
		1, 0, 1, // 4 bottom front right
		1, 1, 1, // 5 top front right
	};

uint[] indices = new uint[] 
	{ 
		0, 1, 2, // left bottom triangle
		2, 3, 0, // left top triangle
		1, 4, 5, // front bottom triangle
		5, 1, 2, // front top triangle
	};
// used for storing the id of the vbo
uint[] vertexBufferObjectIds = new uint[1];

/// SETUP CODE

// create the buffer id
gl.GenBuffers(1, vertexBufferObjectIds);
// bind the buffer type to the id
gl.BindBuffer(OpenGL.GL_ARRAY_BUFFER, vertexBufferObjectIds[0]);
// I'm not sure if there is a better way to get a pointer to a float array, a quick Google search turned up this unsafe way
unsafe
{
	fixed (float* verts = vertices)
	{
		var ptr = new IntPtr(verts);
		// fill the buffer to the currently binded buffer
		gl.BufferData(OpenGL.GL_ARRAY_BUFFER, vertices.Length * sizeof(float), ptr, OpenGL.GL_STATIC_DRAW);
	}
}

///DRAW CODE

// bind to the buffer id we obtained earlier
gl.BindBuffer(OpenGL.GL_ARRAY_BUFFER, vertexBufferObjectIds[0]);
// enable proper vbo client state
gl.EnableClientState(OpenGL.GL_VERTEX_ARRAY);
gl.EnableVertexAttribArray(0);
gl.VertexAttribPointer(0, 3, OpenGL.GL_FLOAT, false, 0, new IntPtr(0));
// draw the current bound buffer with the specified indices
gl.DrawElements(OpenGL.GL_TRIANGLES, indices.Length, indices);

 

Hopefully someone else finds this useful, I know it would have saved me at least 4 hours of time looking around for a solution. Depending on if I stick with SharpGL for my project I may end up creating a few more samples using color, normal, and texture attributes.

Coordinator
Mar 26, 2012 at 10:35 AM

Hi Josiah,

If you're OK with it then I'll promote this to a full sample, credited to you - what do you think?

Dave

Mar 26, 2012 at 2:15 PM

That sounds great. I may try to put together a Shader + VBO sample as well. Hopefully someone could find it useful!

Jul 22, 2012 at 12:44 PM
Edited Jul 22, 2012 at 12:57 PM

Hi,

instead of using the unsafe method, I used GC to provide the pointer.

What is better practice?

 

IntPtr pointer = GCHandle.Alloc(Data, GCHandleType.Pinned).AddrOfPinnedObject();
GL.BindBuffer(target, buffer);
GL.BufferData(target, Data.Length * sizeof(float), pointer, OpenGL.GL_STATIC_DRAW);
Coordinator
Jul 29, 2012 at 5:56 PM

Personally my preference is for the safe method, generally unsafe blocks should be reserved for situations where they cannot be avoided OR they provide a significant performance increase. For the same, I'll take the core code and then modify it with this section above, thanks guys!

Coordinator
Jul 29, 2012 at 5:57 PM
This discussion has been copied to a work item. Click here to go to the work item and continue the discussion.
Sep 30, 2013 at 8:10 AM
Hello,

can anyone telle me why this code dosenot work anymore (gl.DrawElements takes 4 variables).

and haow can I make it works.