Initializing and drawing a mesh using OpenTK

Posted by Boreal on Game Development See other posts from Game Development or by Boreal
Published on 2012-03-20T04:56:54Z Indexed on 2012/03/20 11:39 UTC
Read the original article Hit count: 1028

Filed under:
|
|

I'm implementing a "Mesh" class to use in my OpenTK game. You pass in a vertex array and an index array, and then you can call Mesh.Draw() to draw it using a shader.

I've heard VBO's and VAO's are the way to go for this approach, but nowhere have I found a guide that shows how to get Data > Video Memory > Shader.

Can someone give me a quick rundown of how this works?

EDIT: So far, I have this:

struct Vertex
{
    public Vector3 position;
    public Vector3 normal;
    public Vector3 color;

    public static int memSize = 9 * sizeof(float);
    public static byte[] memOffset = { 0, 3 * sizeof(float), 6 * sizeof(float) };
}

class Mesh
{
    private uint vbo;
    private uint ibo;

    // stores the numbers of vertices and indices
    private int numVertices;
    private int numIndices;

    public Mesh(int numVertices, Vertex[] vertices, int numIndices, ushort[] indices)
    {
        // set numbers
        this.numVertices = numVertices;
        this.numIndices = numIndices;

        // generate buffers
        GL.GenBuffers(1, out vbo);
        GL.GenBuffers(1, out ibo);
        GL.BindBuffer(BufferTarget.ArrayBuffer, vbo);
        GL.BindBuffer(BufferTarget.ElementArrayBuffer, ibo);

        // send data to the buffers
        GL.BufferData(BufferTarget.ArrayBuffer, new IntPtr(Vertex.memSize * numVertices), vertices, BufferUsageHint.StaticDraw);
        GL.BufferData(BufferTarget.ElementArrayBuffer, new IntPtr(sizeof(ushort) * numIndices), indices, BufferUsageHint.StaticDraw);
    }

    public void Render()
    {
        // bind buffers
        GL.BindBuffer(BufferTarget.ArrayBuffer, vbo);
        GL.BindBuffer(BufferTarget.ElementArrayBuffer, ibo);

        // define offsets
        GL.VertexPointer(3, VertexPointerType.Float, Vertex.memSize, new IntPtr(Vertex.memOffset[0]));
        GL.NormalPointer(NormalPointerType.Float, Vertex.memSize, new IntPtr(Vertex.memOffset[1]));
        GL.ColorPointer(3, ColorPointerType.Float, Vertex.memSize, new IntPtr(Vertex.memOffset[2]));

        // draw
        GL.DrawElements(BeginMode.Triangles, numIndices, DrawElementsType.UnsignedInt, (IntPtr)0);
    }
}

class Application : GameWindow
{
    Mesh triangle;

    protected override void OnLoad(EventArgs e)
    {
        base.OnLoad(e);

        GL.ClearColor(0.1f, 0.2f, 0.5f, 0.0f);
        GL.Enable(EnableCap.DepthTest);

        GL.Enable(EnableCap.VertexArray);
        GL.Enable(EnableCap.NormalArray);
        GL.Enable(EnableCap.ColorArray);

        Vertex v0 = new Vertex();
        v0.position = new Vector3(-1.0f, -1.0f, 4.0f);
        v0.normal = new Vector3(0.0f, 0.0f, -1.0f);
        v0.color = new Vector3(1.0f, 1.0f, 0.0f);

        Vertex v1 = new Vertex();
        v1.position = new Vector3(1.0f, -1.0f, 4.0f);
        v1.normal = new Vector3(0.0f, 0.0f, -1.0f);
        v1.color = new Vector3(1.0f, 0.0f, 0.0f);

        Vertex v2 = new Vertex();
        v2.position = new Vector3(0.0f, 1.0f, 4.0f);
        v2.normal = new Vector3(0.0f, 0.0f, -1.0f);
        v2.color = new Vector3(0.2f, 0.9f, 1.0f);

        Vertex[] va = { v0, v1, v2 };
        ushort[] ia = { 0, 1, 2 };

        triangle = new Mesh(3, va, 3, ia);
    }

    protected override void OnRenderFrame(FrameEventArgs e)
    {
        base.OnRenderFrame(e);

        GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);

        Matrix4 modelview = Matrix4.LookAt(Vector3.Zero, Vector3.UnitZ, Vector3.UnitY);
        GL.MatrixMode(MatrixMode.Modelview);
        GL.LoadMatrix(ref modelview);

        triangle.Render();

        SwapBuffers();
    }
}

It doesn't draw anything.

© Game Development or respective owner

Related posts about c#

Related posts about vbo