
VBOs won't render
Posted Wednesday, 1 September, 2010 - 21:23 by tcsavage inHaving tried to implement VBO in my application (where I was just using immediate mode before) for a while, I am getting increasingly frustrated by my situation.
Places I've looked for help include this thread on a VBO example http://www.opentk.com/node/425 and the Static VBO example.
This situation is as follows, there are no compile errors or warnings or even any runtime errors I can detect. It looks like the VBOs are populated correctly but when it comes to render time, I see nothing. There are some extra debug graphics (rendered in immediate mode) which do display but nothing I can do will make my VBOs draw.
I know my graphics card can support them (I've looked at various examples and my driver utility agrees) but I cannot get them to render in my application.
Here's the VBO class I'm using in it's entirety (mainly copied from the aforementioned thread):
using System; using OpenTK; using OpenTK.Graphics; using OpenTK.Graphics.OpenGL; namespace Angelfall.Framework { sealed class VertexBuffer { public int id; int Id { get { // Create an id on first use. if (id == 0) { GraphicsContext.Assert (); GL.GenBuffers (1, out id); if (id == 0) throw new Exception ("Could not create VBO."); } return id; } } int length; public VertexBuffer () { } public void SetData (Vertex[] data) { if (data == null) throw new ArgumentNullException ("data"); this.length = data.Length; int size = 0; GL.BindBuffer (BufferTarget.ArrayBuffer, Id); GL.BufferData (BufferTarget.ArrayBuffer, new IntPtr (data.Length * BlittableValueType.StrideOf(data)), data, BufferUsageHint.StaticDraw); GL.GetBufferParameter(BufferTarget.ArrayBuffer, BufferParameterName.BufferSize, out size); if (data.Length * BlittableValueType.StrideOf(data) != size) throw new ApplicationException("Vertex data not uploaded correctly"); } public void Render () { GL.EnableClientState (ArrayCap.VertexArray); GL.EnableClientState (ArrayCap.NormalArray); GL.EnableClientState (ArrayCap.TextureCoordArray); GL.BindBuffer (BufferTarget.ArrayBuffer, Id); GL.VertexPointer (3, VertexPointerType.Float, Vertex.Stride, new IntPtr (0)); GL.NormalPointer (NormalPointerType.Float, Vertex.Stride, new IntPtr (Vector3.SizeInBytes)); GL.TexCoordPointer (2, TexCoordPointerType.Float, Vertex.Stride, new IntPtr (2 * Vector3.SizeInBytes)); GL.DrawArrays (BeginMode.Triangles, 0, this.length); } } }
and this is my vertex struct in its entirety (not originally copied but modified to fit with the example):
using System; using System.Runtime.Serialization; using System.Xml; using System.Runtime.InteropServices; using OpenTK; namespace Angelfall.Framework { /// <summary> /// Defines spatial position, normal and UV coordinates for a vertex. /// </summary> [Serializable()] public struct Vertex { /// <summary> /// Position of vertex relative to mesh origin. /// </summary> public Vector3 position; /// <summary> /// Vertex normal. /// </summary> public Vector3 normal; /// <summary> /// UV texture coordinates. /// </summary> public Vector2 texCoord; public static readonly int Stride = Marshal.SizeOf(default(Vertex)); /// <summary> /// Construct from position. /// Normal and UV set to 0. /// </summary> /// <param name="Position"> /// Position vector. <see cref="Vector3"/> /// </param> public Vertex(Vector3 Position) { // Set position to something fun. this.position = Position; this.normal = Vector3.Zero; this.texCoord = Vector2.Zero; } /// <summary> /// Constuct vertex from position, normal and UV. /// </summary> /// <param name="Position"> /// <see cref="Vector3"/> position /// </param> /// <param name="Normal"> /// <see cref="Vector3"/> normal /// </param> /// <param name="TexCoord"> /// <see cref="Vector2"/> UV texture coordinates. /// </param> public Vertex(Vector3 Position, Vector3 Normal, Vector2 TexCoord) { // Set vectors. this.position = Position; this.normal = Normal; this.texCoord = TexCoord; } public override string ToString () { return string.Format("[Vertex] {0}, {1}, {2}", position.ToString(), normal.ToString(), texCoord.ToString()); } } }
I know it's a bit of a long shot but if any mistakes jump out at anyone or if there are any suggestions, please let me know.
If anyone wants to see more code, I can provide it but I would think this would be enough.
This one's been annoying me for a long time. Any ideas?

