Dibujo OpenTK OpenGL / con Índices: Intento de leer o escribir en la memoria protegida Edición

Euan Hollidge:

Estoy tratando de mostrar un quad (o dos triángulos) con C # y OpenGL. A continuación se muestra el código para mi clase de malla. En lo que tiene tanto la creación de los OISCIV y VAO, así como la función que se utilizará para representar la malla.

using System;
using System.Collections.Generic;
using System.Text;
using OpenTK.Graphics.OpenGL;
using BuildMe.Core;
using OpenTK;

namespace BuildMe.Render
{
    class Mesh
    {

        private Vector3[] verts;
        private uint[] indices;
        private int instances;
        private int VAO;

        public uint[] Indices { get => indices; set => indices = value; }
        public int Instances { get => instances; set => instances = value; }
        public Vector3[] Verts { get => verts; set => verts = value; }

        public Mesh(Vector3[] verts, uint[] indices, int instances)
        {
            this.verts = verts;
            this.indices = indices;
            this.instances = instances;
            this.VAO = CreateVAO();
            StoreVAOData();
        }

        private int CreateVAO()
        {
            int VAO = GL.GenVertexArray();
            RenderLoop.VAOs.Add(VAO);
            return (VAO);
        }

        private void StoreVAOData()
        {
            GL.BindVertexArray(VAO);

            LoadVerts();
            LoadIndices();

            GL.BindVertexArray(0);
        }

        private void LoadVerts()
        {
            int vbo = GL.GenBuffer();
            GL.BindBuffer(BufferTarget.ArrayBuffer, vbo);
            GL.BufferData(BufferTarget.ArrayBuffer, Vector3.SizeInBytes * verts.Length, verts, BufferUsageHint.StaticDraw);
            GL.VertexAttribPointer(0, 3, VertexAttribPointerType.Float, false, Vector3.SizeInBytes, 0);
            GL.BindBuffer(BufferTarget.ArrayBuffer, 0);
            RenderLoop.VBOs.Add(vbo);
        }

        private void LoadIndices()
        {
            int vbo = GL.GenBuffer();
            GL.BindBuffer(BufferTarget.ElementArrayBuffer, vbo);
            GL.BufferData(BufferTarget.ElementArrayBuffer, sizeof(int) * indices.Length, indices, BufferUsageHint.StaticDraw);
            GL.VertexAttribPointer(0, 1, VertexAttribPointerType.UnsignedInt, false, sizeof(int), 0);
            GL.BindBuffer(BufferTarget.ElementArrayBuffer, 0);
            RenderLoop.VBOs.Add(vbo);
        }

        public int GetVAO()
        {
            return (VAO);
        }

        public void Render()
        {
            GL.BindVertexArray(this.GetVAO());
            GL.EnableVertexAttribArray(0);
            GL.EnableVertexAttribArray(1);
            GL.DrawElements(PrimitiveType.Triangles, this.Indices.Length, DrawElementsType.UnsignedInt, 0);
            GL.DisableVertexAttribArray(0);
            GL.DisableVertexAttribArray(1);
            GL.BindVertexArray(0);
        }

    }
}

Aquí es donde yo llamo la función para hacer la malla.

        private void Render(object sender, FrameEventArgs e)
        {
            GL.EnableClientState(ArrayCap.VertexArray);
            GL.EnableClientState(ArrayCap.IndexArray);
            GL.Color3(Color.Green);
            foreach (Mesh mesh in SceneMeshes)
                mesh.Render();
        }

El error que estoy recibiendo por es si ayuda. Pero creo que sólo significa que he declarado ya sea los OISCIV mal o estoy usando las funciones erróneas para hacerlo.

An unhandled exception of type 'System.AccessViolationException' occurred in OpenTK.dll
Attempted to read or write protected memory. This is often an indication that other memory is corrupt.

Gracias de antemano.

Rabbid76:

EnableClientStatey VertexAttribPointerno interactúan entre sí. Si desea utilizar las capacidades del lado del cliente, entonces usted tiene que utilizar VertexPointer(ver glVertexPointer):

GL.VertexAttribPointer(0, 3, VertexAttribPointerType.Float, false, Vector3.SizeInBytes, 0);

GL.VertexPointer(3, VertexAttribPointerType.Float, Vector3.SizeInBytes, 0);

GL.EnableClientState(ArrayCap.IndexArray);no hace lo que usted espera. ArrayCap.IndexArrayse entiende para los atributos de índice de color.
El tampón de índice se unido a la diana BufferTarget.ElementArrayBuffer. No es un atributo y no tiene que ser activado.
Además el búfer de índice se afirma en el objeto de matriz vértice. La instrucción GL.BindBuffer(BufferTarget.ElementArrayBuffer, 0);se rompería la unión:

private void LoadIndices()
{
    int ibo = GL.GenBuffer();
    GL.BindBuffer(BufferTarget.ElementArrayBuffer, ibo);
    GL.BufferData(BufferTarget.ElementArrayBuffer, sizeof(int) * indices.Length, indices, BufferUsageHint.StaticDraw);
    // GL.VertexAttribPointer(...) <--- REMOVE
    // GL.BindBuffer(BufferTarget.ElementArrayBuffer, 0); // <--- REMOVE
    RenderLoop.VBOs.Add(ibo);
}

La capacidad del cliente se establece en la tabla de objeto Vertex . Por lo tanto, se puede afirmar en LoadVerts():

private void LoadVerts()
{
    int vbo = GL.GenBuffer();
    GL.BindBuffer(BufferTarget.ArrayBuffer, vbo);
    GL.BufferData(BufferTarget.ArrayBuffer, Vector3.SizeInBytes * verts.Length, verts, BufferUsageHint.StaticDraw);
    // GL.VertexAttribPointer(...); <---- REMOVE
    GL.VertexPointer(3, VertexAttribPointerType.Float, Vector3.SizeInBytes, 0); // <--- ADD
    GL.EnableClientState(ArrayCap.VertexArray); // <--- ADD
    GL.BindBuffer(BufferTarget.ArrayBuffer, 0);
    RenderLoop.VBOs.Add(vbo);
}

Todas las especificaciones necesarias se indica en la tabla de objeto Vertex, por lo que es suficiente para obligar a la VAO, antes de la llamada sorteo:

public void Render()
{
    GL.BindVertexArray(this.GetVAO());
    GL.DrawElements(PrimitiveType.Triangles, this.Indices.Length, DrawElementsType.UnsignedInt, 0);
    GL.BindVertexArray(0);
}
private void Render(object sender, FrameEventArgs e)
{
    GL.Color3(Color.Green);
    foreach (Mesh mesh in SceneMeshes)
        mesh.Render();
}

Supongo que te gusta

Origin http://10.200.1.11:23101/article/api/json?id=405869&siteId=1
Recomendado
Clasificación