سؤال

I have a class and I'm trying to render a single triangle with it but it keeps failing and i Don't know why, can anybody spot the problem? I've tried using static and dynamic vbo but i keep getting a memory issue.

The Error i receive is:

" An unhandled exception of type 'System.AccessViolationException' occurred in OpenTK.dll

Additional information: Attempted to read or write protected memory. This is often an indication that other memory is corrupt. "

My usage is:

        var m = new Mesh();

        m.Vertices = new float[] { 
            0, 0, 0, 
            5, 0, 0, 
            5, 5, 0
        };


        m._Indices = new ushort[] { 0, 1, 2 };
        m.Init();

my class is

namespace lolGL
{
    using System;
    using OpenTK.Graphics.OpenGL;
    using OpenTK;

    public class Mesh : Entity
    {
        public ushort[] _Indices = null;

        int m_vertexBuffer = 0;
        int m_indexBuffer = 0;

        bool use16BitIndices
        {
            get { return Vertices.Length <= 65536; }
        }

        public Mesh() { }

        public void Init()
        {
            GL.GenBuffers(1, out m_vertexBuffer);
            GL.BindBuffer(BufferTarget.ArrayBuffer, m_vertexBuffer);
            GL.BufferData(BufferTarget.ArrayBuffer, new IntPtr(BlittableValueType.StrideOf<float>(Vertices) * Vertices.Length), Vertices, BufferUsageHint.StaticDraw);

            GL.GenBuffers(1, out m_indexBuffer);
            GL.BindBuffer(BufferTarget.ElementArrayBuffer, m_indexBuffer);

            int indexSize = use16BitIndices ? sizeof(short) : sizeof(int);

            GL.BufferData(BufferTarget.ElementArrayBuffer, new IntPtr(indexSize * _Indices.Length), _Indices, BufferUsageHint.StaticDraw);
            GL.BindBuffer(BufferTarget.ElementArrayBuffer, 0);
        }

        public override void Render(OpenTK.FrameEventArgs e)
        {
            GL.BindBuffer(BufferTarget.ArrayBuffer, m_vertexBuffer);
            GL.BindBuffer(BufferTarget.ArrayBuffer, m_indexBuffer);

            GL.EnableClientState(ArrayCap.VertexArray);
            GL.VertexPointer(3, VertexPointerType.Float, Vector3.SizeInBytes, 0);

            if (use16BitIndices)
                GL.DrawElements(BeginMode.TriangleStrip, _Indices.Length, DrawElementsType.UnsignedShort, 0);
            else
                GL.DrawElements(BeginMode.TriangleStrip, _Indices.Length, DrawElementsType.UnsignedInt, 0);

            GL.Disable(EnableCap.VertexArray);

            GL.BindBuffer(BufferTarget.ArrayBuffer, 0);
            GL.BindBuffer(BufferTarget.ElementArrayBuffer, 0);

        }

        public override void EmptyBuffer()
        {
            Vertices = null;
            _Indices = null;
        }

        public override void Dispose()
        {
            EmptyBuffer();
        }

        public override void Delete()
        {
            if (m_indexBuffer != 0)
                GL.DeleteBuffers(1, ref m_indexBuffer);

            if (m_vertexBuffer != 0)
                GL.DeleteBuffers(1, ref m_vertexBuffer);

            Dispose();
        }

        public override void ApplyColorMap(int[] colors)
        {
            throw new NotImplementedException();
        }
    }
}
هل كانت مفيدة؟

المحلول

In the Render function, you're binding the index buffer to the wrong target.

GL.BindBuffer(BufferTarget.ArrayBuffer, m_indexBuffer);

Should be:

GL.BindBuffer(BufferTarget.ElementArrayBuffer, m_indexBuffer);

Based on the way you're unbinding at the end, this was probably just a typo.

Also, unrelated but that whole thing you're doing with use16BitIndices is wrong. It's not the length of the array that matters, it's the size of each element in the array. If you have over 65536 vertices, you're going to need indices with a value greater than 65536 (which a ushort can't handle). You need to upload an int[] in that case.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top