Search code examples
c#openglglfwopentk

OpenGL invalid operation on glDrawArrays()


I'm running a C# project with the Pencil.Gaming library, which is the C# binding of GLFW which uses OpenTK to wrap OpenGL functions. I am trying to draw an array of Vertices in a vbo, and once I get to GL.DrawArrays, it gives me a System.AccessViolationException and an Invalid Operation error when I call GL.GetError(). Below is my code for the Mesh class and a screencap of the error is Visual Studio. The object I am trying to draw and a copy of my Vertex class is also below.

static Mesh mesh;
mesh = new Mesh();

Vertex[] data = new Vertex[] {new Vertex(new Vector3(-1,-1,0)),
                              new Vertex(new Vector3(0,1,0)),
                              new Vertex(new Vector3(1,-1,0))};

mesh.addVertices(data);
mesh.draw();

The Vertex Class:

struct Vertex
{
    public static readonly int SIZE = 3;

    private Vector3 position;

    public Vertex(Vector3 position)
    {
        this.position = position;
    }
}

GL.DrawArrays() Error

The Mesh class:

using System;
using Pencil.Gaming.Graphics;
using Pencil.Gaming.MathUtils;

namespace Practicalis.Rendering
{
    class Mesh
    {
        private int size;
        private int vbo;

        public Mesh()
        {
            size = 0;

            GL.GenBuffers(size, out vbo);
        }

        public void addVertices(Vertex[] vertices)
        {
            size = vertices.Length * sizeof(float);

            GL.BindBuffer(BufferTarget.ArrayBuffer, vbo);
            GL.BufferData(BufferTarget.ArrayBuffer, (IntPtr)size, (IntPtr)vbo, BufferUsageHint.StaticDraw);
        }

        public void draw()
        {
            GL.EnableVertexAttribArray(0);

            GL.BindBuffer(BufferTarget.ArrayBuffer, vbo);
            GL.VertexAttribPointer(0, 3, VertexAttribPointerType.Float, false, Vertex.SIZE * 4, 0);

            Console.WriteLine(GL.GetError());
            GL.DrawArrays(BeginMode.Triangles, 0, size);

            GL.DisableVertexAttribArray(0);
        }
    }
}

Solution

  • In the add vertice function, I wasn't passing in my actual Vertex array, just the pointer to vbo. The proper function is below.

    public void addVertices(Vertex[] vertices)
    {
        size = vertices.Length * Vector3.SizeInBytes;
        Vector3[] vertsData = new Vector3[vertices.Length];
    
        GL.BindBuffer(BufferTarget.ArrayBuffer, vbo);
    
        for (int i = 0; i < vertices.Length; i++)
            vertsData[i] = vertices[i].Position;
    
        GL.BufferData(BufferTarget.ArrayBuffer, (IntPtr)size, vertsData, BufferUsageHint.StaticDraw);
    }