LWJGL Невозможно использовать смещения, когда объект массива буфера отключен

Я просмотрел много постов и не могу найти, что не так с моим кодом. Я связал свой VBO, однако он не работает и выдает мне эту ошибку:

Exception in thread "main" org.lwjgl.opengl.OpenGLException: Cannot use
offsets when Array Buffer Object is disabled
at org.lwjgl.opengl.GLChecks.ensureArrayVBOenabled(GLChecks.java:77)
at org.lwjgl.opengl.GL20.glVertexAttribPointer(GL20.java:892)
at glsl.Main.main(Main.java:117)

Я не понимаю, что здесь не так. Я посмотрел везде и не могу понять, что с этим не так. Я пробовал с и без glEnable(GL_ARRAY_BUFFER_BINDING);

package glsl;

import java.nio.FloatBuffer;
import java.util.Scanner;

import org.lwjgl.BufferUtils;
import org.lwjgl.opengl.*;

import static org.lwjgl.opengl.GL20.*;
import static org.lwjgl.opengl.GL11.*;
import static org.lwjgl.opengl.GL15.*;

public class Main
{
    private static int initShaderProgram()
    {
        int shaderProgram = glCreateProgram();

        int vertexShader = getShader(GL_VERTEX_SHADER, "/shader.vert");
        glAttachShader(shaderProgram, vertexShader);

        int fragmentShader = getShader(GL_FRAGMENT_SHADER, "/shader.frag");
        glAttachShader(shaderProgram, fragmentShader);

        glLinkProgram(shaderProgram);
        checkError(shaderProgram, GL_LINK_STATUS, true);
        glValidateProgram(shaderProgram);
        checkError(shaderProgram, GL_VALIDATE_STATUS, true);

        return shaderProgram;
    }

    private static int getShader(int shaderType, String shaderName)
    {
        int shader = glCreateShader(shaderType);

        String shaderText = "";
        Scanner scan = new Scanner(Main.class.getResourceAsStream(shaderName));
        while(scan.hasNextLine())
            shaderText = shaderText.concat(scan.nextLine().concat("\n"));
        scan.close();

        System.out.println("\n");
        System.out.println(shaderName+" source: --------------------------------------------");
        System.out.println("\n"+shaderText);
        System.out.println("\n");

        glShaderSource(shader, shaderText);
        glCompileShader(shader);

        checkError(shader, GL_COMPILE_STATUS, false);

        return shader;
    }

    private static void checkError(int shader, int status, boolean isProgram)
    {
        if(!isProgram)
        {
            if(glGetShaderi(shader, status) == org.lwjgl.opengl.GL11.GL_FALSE)
            {
                System.err.println("Shader broken: " + glGetShaderInfoLog(shader, GL_INFO_LOG_LENGTH));
                System.exit(1);
            }
        }else
        {
            if(glGetProgrami(shader, status) == org.lwjgl.opengl.GL11.GL_FALSE)
            {
                System.err.println("Shader broken: " + glGetProgramInfoLog(shader, GL_INFO_LOG_LENGTH));
                System.exit(1);
            }
        }
    }

    public static void main(String[] args)
    {
        try
        {
            Display.setDisplayMode(new DisplayMode(800, 600));
            Display.create();
        }catch(org.lwjgl.LWJGLException e)
        {
            System.exit(1);
        }

        glEnable(GL_ARRAY_BUFFER_BINDING);

        int shaderProgram = initShaderProgram();

        String attribute_name = "coord2d";
        int attribute_coord2d = glGetAttribLocation(shaderProgram, attribute_name);

        int vboTriangle;
        float[] triangleVerticesArray = 
        {
            -1, -1,
            0, 1f,
            1, -1
        };
        FloatBuffer triangleVertices = (FloatBuffer) BufferUtils.createFloatBuffer(triangleVerticesArray.length).put(triangleVerticesArray).flip();

        vboTriangle = glGenBuffers();
        glBindBuffer(GL_ARRAY_BUFFER, vboTriangle);
        glBufferData(GL_ARRAY_BUFFER, triangleVertices, GL_STATIC_DRAW);
        glBindBuffer(GL_ARRAY_BUFFER, 0);

        while(!Display.isCloseRequested())
        {
            glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
            glClear(GL_COLOR_BUFFER_BIT);

            glUseProgram(shaderProgram);

            glEnableVertexAttribArray(attribute_coord2d);
            glBindBuffer(GL_VERTEX_ARRAY, vboTriangle);

            glVertexAttribPointer(attribute_coord2d, 2, GL_FLOAT, false, 0, 0l);

            glBindBuffer(GL_VERTEX_ARRAY, 0);
            glDisableVertexAttribArray(attribute_coord2d);

            glUseProgram(0);

            Display.update();
            Display.sync(60);
        }

        cleanup(shaderProgram, new int[]{vboTriangle});
    }

    private static void cleanup(int shaderProgram, int[] vbos)
    {
        for(int i = 0; i < vbos.length; i++)
            glDeleteBuffers(vbos[i]);

        glDeleteProgram(shaderProgram);
        Display.destroy();
    }
}

1 ответ

Решение

Вам нужно установить указатели с помощью VAO, объекта Vertex Array.

int vaoID = glGenVertexArrays();

Затем вам нужно связать его и установить указатели с VBO, объектами Vertex Array.

glBindVertexArray(vaoID);
glEnableVertexAttribArray(indexLocation);

glBindBuffer(GL_ARRAY_BUFFER, vboID);
glVertexAttribPointer(indexLocation, 2, GL_FLOAT, false, 0, 0);

glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);

Затем при каждом рендеринге связывайте VAO и выполняйте команду рисования.

glBindVertexArray(vaoID);
glDrawArrays(GL_TRIANGLES, 0, 3);
glBindVertexArray(0);

Затем, наконец, вам нужно избавиться от объекта VAO.

glBindVertexArray(0);
glDeleteVertexArrays(vaoID);

Надеюсь это поможет.

Другие вопросы по тегам