
VBO with VB.NET
Posted Saturday, 18 July, 2009 - 13:01 by remopini inHi all
I'm trying to switch from Display Lists to VBOs.
Here's my code:
FLOAT_SIZE = 8 BYTE_SIZE = 1 vertices = New Double() {-25.0F, +25.0F, +25.0F, _ +25.0F, +25.0F, +25.0F, _ +25.0F, -25.0F, +25.0F, _ -25.0F, -25.0F, +25.0F, _ -25.0F, +25.0F, -25.0F, _ +25.0F, +25.0F, -25.0F, _ +25.0F, -25.0F, -25.0F, _ -25.0F, -25.0F, -25.0F} indices = New Byte() {0, 1, 2, 3, _ 4, 5, 1, 0, _ 3, 2, 6, 7, _ 5, 4, 7, 6, _ 1, 5, 6, 2, _ 4, 0, 3, 7} GL.GenBuffers(1, vertexbuffer) GL.BindBuffer(BufferTarget.ArrayBuffer, vertexbuffer) GL.BufferData(BufferTarget.ArrayBuffer, FLOAT_SIZE * vertices.Count, vertices, BufferUsageHint.StaticDraw) GL.GenBuffers(1, indexbuffer) GL.BindBuffer(BufferTarget.ArrayBuffer, indexbuffer) GL.BufferData(BufferTarget.ArrayBuffer, BYTE_SIZE * indices.Count, indices, BufferUsageHint.StaticDraw)
...
Public Sub Render() GL.Clear(ClearBufferMask.ColorBufferBit Or ClearBufferMask.DepthBufferBit) GL.LoadIdentity() GL.Rotate(alpha, 0, 0, 1) 'vertex buffer objects '--------------------- GL.EnableClientState(EnableCap.VertexArray) GL.BindBuffer(BufferTarget.ArrayBuffer, vertexbuffer) GL.VertexPointer(3, VertexPointerType.Double, 0, IntPtr.Zero) GL.BindBuffer(BufferTarget.ArrayBuffer, indexbuffer) GL.DrawElements(BeginMode.Quads, 24, DrawElementsType.UnsignedByte, IntPtr.Zero) 'old fashioned way '----------------- 'GL.Begin(BeginMode.Quads) 'For i = 0 To indices.Count - 1 ' GL.Vertex3(vertices(indices(i) * 3 + 0), vertices(indices(i) * 3 + 1), vertices(indices(i) * 3 + 2)) 'Next 'GL.End() alpha += 0.5 GlControl1.SwapBuffers() End Sub
If I use the "old fashioned way", it works fine, however, the VBO way crashes (memory access exception)...what am I missing?
Cheers
Remo


Comments
Re: VBO with VB.NET
1)
FLOAT_SIZE * vertices.Countis not correct as long as you are using Double for verteces2) For the index buffer you have to use BufferTarget.ElementArrayBuffer bind point instead of BufferTarget.ArrayBuffer
Re: VBO with VB.NET
1) FLOAT_SIZE = 8. This should either be DOUBLE_SIZE = 8 or SINGLE_SIZE = 4. Doesn't VB.Net have a SizeOf operator, i.e.
SizeOf(Double)?2) BufferTarget.ElementArrayBuffer is the real issue. The code should work as soon as you change that.
Re: VBO with VB.NET
Ok, the change to BufferTarget.ElementArrayBuffer did the trick.
VB.NET actually DOES have a Sizeof(Double) function, it's hidden in the System.Runtime.InteropServices.Marshal class.
So the "final" initialization parts look like this:
And the actual Render looks like this:
Thank you for the help :)
Cheers
Remo
PS: The vertex array has been changed to type Single() of course...
Re: VBO with VB.NET
I now added the same logic for texture coordinates:
texcoord is an array of Single() containing u1, v1, u2, v2, ...
I then draw all of it like so:
From the result, I can see, that the texture coordinates must be wrong, however, when I do it the old fashioned way (Display lists), the coordinates are correct... I guess I'm missing something yet again...
Cheers
Remo
Re: VBO with VB.NET
Did you forget to enable client state for texture coordinates?
GL.EnableClientState(EnableCap.TextureCoordArray)Re: VBO with VB.NET
You can only use 1 BufferTarget.ArrayBuffer, so you must format your data in one of those ways:
t[x] = TexCoord
v[x] = Vertex position
1) t0, t1, t2, t3, ... tn, v0, v1, v2, v3, ... vn
2) t0, v0, t1, v1, t2, v2, ..., tn, vn
The GL.***Pointer() command's stride and offset parameters are used to specify the used layout.
You might want to check out the documentation: http://www.opentk.com/doc/chapter/2/opengl/geometry
Re: VBO with VB.NET
I don't think that is strictly necessary. You can keep your data on different arrays -
GL.DrawElements()will use all of them, as long as they are enabled and bound (withGL.[Vertex|Normal|TexCoord|*]Pointer).Re: VBO with VB.NET
If you can get multiple ArrayBuffers to work at the same time you're my hero, I tried that and it didn't work at all. The second GL.BindBuffer(BufferTarget.ArrayBuffer, ..) call would simply replace the binding done in the first.
Re: VBO with VB.NET
Ha, Inertia, that was pretty naive to think that all vertex attributes have to be interleaved. Actually, interleaving is just an alternative to having separate vertex buffers for separate attributes. In my engine I preferred the second choice for it's simplicity and better modularity: there is no need to manager all buffers at once, you just need to bind some of them sequentially calling gl*Pointer function after each bind.
Check out the following discussion:
http://www.opengl.org/discussion_boards/ubbthreads.php?ubb=showflat&Numb...
Briefly, you just need to have a proper array buffer bound on calling gl*Pointer. After that you can safely call glDraw* even if there's no buffer attached to the BufferTarget.ArrayBuffer at all.
Re: VBO with VB.NET
Actually, KVARK provided the solution:
I was missing a GL.EnableClientState(EnableCap.TextureCoordArray)
This now works using three completely different arrays (vertex, indices, texture coords), so it is obviously possible to use more than one array.
I guess that makes me Inertia's hero :)
Thank you all for helping me out here.
Cheers
Remo