Jump to content

  • Log In with Google      Sign In   
  • Create Account

C# OpenTK - VBO problem :(


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
2 replies to this topic

#1 MrOMGWTF   Members   -  Reputation: 440

Like
0Likes
Like

Posted 21 October 2012 - 07:58 AM

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 ;_;

Edited by MrOMGWTF, 21 October 2012 - 08:06 AM.


Sponsor:

#2 Scourage   Members   -  Reputation: 763

Like
0Likes
Like

Posted 22 October 2012 - 08:52 AM

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!

Edited by Scourage, 22 October 2012 - 08:54 AM.


Halfway down the trail to Hell...

#3 MrOMGWTF   Members   -  Reputation: 440

Like
0Likes
Like

Posted 27 October 2012 - 07:16 AM

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




Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS