C# OpenTK - VBO problem :(

Started by
1 comment, last by MrOMGWTF 11 years, 5 months ago
I've spent like freaking 1 hour trying to fix this problem, nothing worked.. eh..
After implementing my VBO class, I decided to give it a try. But somehow, nothing renders on the screen!
My VBO is a one simple triangle. I have no idea why isn't it working. It's OpenTK.
Here's my code for VBO:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using OpenTK.Graphics.OpenGL;
using OpenTK;
using System.Runtime.InteropServices;

namespace CentipedeRenderer
{
public class VBO
{
public int VertID = -1;
public int IndicesID = -1;
public int VertCount;
public int IndicesCount;

public void Create(List<Vector3> vertices, List<uint> indices)
{
VertCount = vertices.Count;
IndicesCount = indices.Count;
Free();
GL.GenBuffers(1, out VertID);
GL.GenBuffers(1, out IndicesID);
//pass the indices
GL.BindBuffer(BufferTarget.ElementArrayBuffer, IndicesID);
GL.BufferData<uint>(BufferTarget.ElementArrayBuffer,
(IntPtr)(indices.Count * sizeof(uint)),
indices.ToArray(),
BufferUsageHint.StaticDraw
);

//pass the vertices
GL.BindBuffer(BufferTarget.ArrayBuffer, VertID);
GL.BufferData<Vector3>(BufferTarget.ArrayBuffer,
(IntPtr)(vertices.Count * Vector3.SizeInBytes),
vertices.ToArray(),
BufferUsageHint.StaticDraw
);
}

public void Draw()
{
GL.EnableClientState(ArrayCap.VertexArray);
GL.BindBuffer(BufferTarget.ArrayBuffer, VertID);
GL.VertexPointer(3, VertexPointerType.Float, Vector3.SizeInBytes, 0);


GL.BindBuffer(BufferTarget.ElementArrayBuffer, IndicesID);

GL.DrawElements(BeginMode.Triangles, 3, DrawElementsType.UnsignedInt, 0);
}

public void Free()
{
GL.DeleteBuffers(2, new int[] { VertID, IndicesID } );
}
}
}


And code where I test the VBO:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using OpenTK;
using OpenTK.Graphics.OpenGL;

namespace CentipedeRenderer
{
public class Renderer
{
public static Renderer GRen; // Global RENderer
public Scene Scene;

VBO testvbo;

public Renderer()
{
GL.Enable(EnableCap.DepthTest);
Matrix4 proj = Matrix4.CreatePerspectiveFieldOfView(MathHelper.PiOver4, (1280.0f / 720.0f), 1.0f, 100.0f);
GL.MatrixMode(MatrixMode.Modelview);
GL.LoadMatrix(ref proj);
testvbo = new VBO();
List<Vector3> verts = new List<Vector3>();
List<uint> indies = new List<uint>();

verts.Add(new Vector3(0.0f, 0.0f, -5.0f));
verts.Add(new Vector3(0.5f, 1.0f, -5.0f));
verts.Add(new Vector3(1.0f, 0.0f, -5.0f));

indies.Add(0);
indies.Add(1);
indies.Add(2);

testvbo.Create(verts, indies);
}

public void Render()
{
GL.Clear(ClearBufferMask.ColorBufferBit);
testvbo.Draw();
}
}
}


The syntax is similar to OpenGL's one, so even if you don't know OpenTK, I think you could help me :)

Thanks

@edit
OH MYYYY GOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOD
I'M LOADING THE PROJECTION MATRIX IN TO THE MODELVIEW MATRIX
FUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU

@edit2:
GUESS WHAT
I FIXED THAT
.
.
.
AND IT STILL DOESN'T WORK ;_;
Advertisement
There's a couple of things that strike me as odd:

-you're recreating the VBO every render call. Not a big deal in this particular case, but you will want to fill it up once and then just render it each frame.
-you're not loading a model view matrix. I recommend just starting with an identity matrix.
-looks like you're drawing your triangles in clockwise order, but they should be counter clockwise, either swap the verts or the indices to make it draw in counter clockwise order

Here's my VBO class from a project that is similar to yours. Maybe you can use this to help troubleshoot, or just use however you want


using System;
using System.Runtime.InteropServices;
using OpenTK;
using OpenTK.Graphics;
using OpenTK.Graphics.OpenGL;
namespace SimEngine
{
[StructLayout(LayoutKind.Sequential)]
public struct Vertex
{
public Vector3 Position;
public Vector3 Normal;
public Vector2 TexCoord;
public static readonly int Stride = Marshal.SizeOf(default(Vertex));
}
public class VertexBuffer
{
public int myVertexId;
public int myIndexId;
public BeginMode myMode=BeginMode.Triangles;
public uint myVertexLength;
public uint myIndexLength;
int myDataOffset = 0;
int myByteOffset = 0;
public enum IndexType { USHORT, UINT};
IndexType myIndexType;
public VertexBuffer()
{
init();
}
public bool init()
{
GL.GenBuffers(1, out myVertexId);
GL.GenBuffers(1, out myIndexId);
return true;
}
public int vertexOffset
{
get { return myDataOffset; }
set { myDataOffset = value; myByteOffset = myDataOffset * Vertex.Stride; }
}
public void SetVertexData(Vertex[] data)
{
SetVertexData(data, (uint)data.Length);
}
public void SetVertexData(Vertex[] data, uint count)
{
if (data == null)
throw new ArgumentNullException("vertex data not found");
myVertexLength = count;
GL.BindBuffer(BufferTarget.ArrayBuffer, myVertexId);
GL.BufferData(BufferTarget.ArrayBuffer, new IntPtr(data.Length * Vertex.Stride), data, BufferUsageHint.StaticDraw);
}
public void SetIndexData(ushort[] data)
{
SetIndexData(data, (ushort)data.Length);
}
public void SetIndexData(ushort[] data, uint count)
{
if (data == null)
throw new ArgumentNullException("index data not found");

myIndexType = IndexType.USHORT;
myIndexLength = count;
GL.BindBuffer(BufferTarget.ElementArrayBuffer, myIndexId);
GL.BufferData(BufferTarget.ElementArrayBuffer, new IntPtr(data.Length * sizeof(ushort)), data, BufferUsageHint.DynamicDraw);
}
public void SetIndexData(uint[] data)
{
SetIndexData(data, (ushort)data.Length);
}
public void SetIndexData(uint[] data, uint count)
{
if (data == null)
throw new ArgumentNullException("index data not found");
myIndexType = IndexType.UINT;
myIndexLength = count;
GL.BindBuffer(BufferTarget.ElementArrayBuffer, myIndexId);
GL.BufferData(BufferTarget.ElementArrayBuffer, new IntPtr(data.Length * sizeof(uint)), data, BufferUsageHint.DynamicDraw);
}
public void renderRange(int offset, int count)
{
//we're binding the normals as colors here for visualizing the triangles
GL.EnableClientState(ArrayCap.VertexArray);
GL.EnableClientState(ArrayCap.NormalArray);
GL.EnableClientState(ArrayCap.TextureCoordArray);
GL.BindBuffer(BufferTarget.ArrayBuffer, myVertexId);
GL.BindBuffer(BufferTarget.ElementArrayBuffer, myIndexId);
GL.VertexPointer(3, VertexPointerType.Float, Vertex.Stride, new IntPtr(0 + myByteOffset));
GL.NormalPointer(NormalPointerType.Float, Vertex.Stride, new IntPtr(Vector3.SizeInBytes + myByteOffset));
GL.TexCoordPointer(2, TexCoordPointerType.Float, Vertex.Stride, new IntPtr(2 * Vector3.SizeInBytes + myByteOffset));
if (myIndexType == IndexType.USHORT)
GL.DrawRangeElements(myMode, 0, myIndexLength, count, DrawElementsType.UnsignedShort, new IntPtr(offset * 2));
else
GL.DrawRangeElements(myMode, 0, myIndexLength, count, DrawElementsType.UnsignedInt, new IntPtr(offset * 4));
GL.BindBuffer(BufferTarget.ArrayBuffer, 0);
GL.BindBuffer(BufferTarget.ElementArrayBuffer, 0);
GL.DisableClientState(ArrayCap.VertexArray);
GL.DisableClientState(ArrayCap.NormalArray);
GL.DisableClientState(ArrayCap.TextureCoordArray);
Draw.checkError("VBO::renderRange");
}

public void render()
{
//we're binding the normals as colors here for visualizing the triangles
GL.EnableClientState(ArrayCap.VertexArray);
GL.EnableClientState(ArrayCap.NormalArray);
GL.EnableClientState(ArrayCap.TextureCoordArray);
GL.BindBuffer(BufferTarget.ArrayBuffer, myVertexId);
GL.BindBuffer(BufferTarget.ElementArrayBuffer, myIndexId);
GL.VertexPointer(3, VertexPointerType.Float, Vertex.Stride, new IntPtr(0 + myByteOffset));
GL.NormalPointer(NormalPointerType.Float, Vertex.Stride, new IntPtr(Vector3.SizeInBytes + myByteOffset));
GL.TexCoordPointer(2, TexCoordPointerType.Float, Vertex.Stride, new IntPtr(2 * Vector3.SizeInBytes + myByteOffset));
int batchSize = 63000; //multiple of 4 and 3
int count, rendered;
rendered = 0;
if (myIndexLength <= batchSize)
{
count = (int)myIndexLength;
}
else
{
count = batchSize;
}
while (rendered < myIndexLength)
{
if(myIndexType==IndexType.USHORT)
GL.DrawRangeElements(myMode, 0, myIndexLength, count, DrawElementsType.UnsignedShort, new IntPtr(rendered * 4));
else
GL.DrawRangeElements(myMode, 0, myIndexLength, count, DrawElementsType.UnsignedInt, new IntPtr(rendered * 4));
rendered += count;
if (myIndexLength - rendered < batchSize)
{
count = (int)myIndexLength - rendered;
}
}
GL.BindBuffer(BufferTarget.ArrayBuffer, 0);
GL.BindBuffer(BufferTarget.ElementArrayBuffer, 0);
GL.DisableClientState(ArrayCap.VertexArray);
GL.DisableClientState(ArrayCap.NormalArray);
GL.DisableClientState(ArrayCap.TextureCoordArray);
Draw.checkError("VBO::render");
}
}
}


*edited for formating and took my copyright notice off, this code is free!

[size="3"]Halfway down the trail to Hell...
GL.Clear(ClearBufferMask.ColorBufferBit);

this.

this. line.

Is it right? Nope, chuck testa!
I just forgot to clean up the depth buffer :s

After changing it to this:
GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);

IT FREAKIN' WORKS

This topic is closed to new replies.

Advertisement