LWJGL禁用阵列缓冲区对象时不能使用偏移量

时间:2015-02-19 11:55:40

标签: java opengl shader lwjgl vertex-buffer-objects

我看过很多帖子,但找不到我的代码有什么问题。 我绑定了我的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 个答案:

答案 0 :(得分:1)

您需要使用VAO(顶点数组对象)设置指针。

int vaoID = glGenVertexArrays();

然后你需要绑定它,并用VBO,Vertex Array Objects设置指针。

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);

希望这有帮助。