LWJGL 3、VAO 和 Shader 不渲染

LWJGL 3, VAO and Shader not rendering

我正在使用 LWJGL 3 和带有 VAO 的着色器。我当前的实现在使用着色器时不绘制 VAO。然而,当不使用着色器时 VAO 将绘制,但 VAO 将是白色的。我的问题是我在着色器设置中缺少什么阻止我在使用着色器时看到 VAO?

主要Class.
着色器和 VAO 设置在 gameStart() 方法中。

public class Test {

/** Window Properties **/
private int 
    HEIGHT = 800,
    WIDTH = 1200,
    RESIZABLE = GL11.GL_FALSE,
    REFRESH_RATE = 60;

private String TITLE = "test";

// The window handler
private long window;

// callback reference instances
private GLFWErrorCallback errorCallback;
private GLFWKeyCallback   keyCallback;

private void preWindowSetup() {
    // Setup an error callback
    GLFW.glfwSetErrorCallback(errorCallback = errorCallbackPrint(System.err));

    // Initialize GLFW
    if (GLFW.glfwInit() != GL11.GL_TRUE)
        exit();
}

private void windowSetup() {
    // Configure Window Properties
    glfwDefaultWindowHints();
    GLFW.glfwWindowHint(GLFW_VISIBLE, GL_FALSE); // Keep the window hidden
    glfwWindowHint(GLFW_RESIZABLE, RESIZABLE); // Do not allow resizing
    glfwWindowHint(GLFW_REFRESH_RATE, REFRESH_RATE); // Refresh rate

    // Create the window
    window = glfwCreateWindow(WIDTH, HEIGHT, TITLE, NULL, NULL);
    if ( window == NULL )
        exit();

    // Get the resolution of the primary monitor
    ByteBuffer vidmode = glfwGetVideoMode(glfwGetPrimaryMonitor());
    // Center our window
    glfwSetWindowPos(
        window,
        (GLFWvidmode.width(vidmode) - WIDTH) / 2,
        (GLFWvidmode.height(vidmode) - HEIGHT) / 2
    );
}

private void callbackSetup() {
    // Setup a key callback. It will be called every time a key is pressed, repeated or released.
    glfwSetKeyCallback(window, keyCallback = new GLFWKeyCallback() {
        @Override
        public void invoke(long window, int key, int scancode, int action, int mods) {//TODO Dispatch key events
            if (key == GLFW_KEY_ESCAPE && action == GLFW_RELEASE)
                Tasker.executeASyncTask("GLFW_MAIN_THREAD");
        }
    });
}

public void initGL() {
    preWindowSetup();
    windowSetup();
    callbackSetup();

    glfwMakeContextCurrent(window);     // Make the OpenGL context current
    glfwShowWindow(window);             // Make the window visible
    GLContext.createFromCurrent();      // Bind lwjgl with GLFW

    // Initialize openGl
    GL11.glViewport(0, 0, WIDTH, HEIGHT);
    GL11.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
    GL11.glMatrixMode(GL11.GL_PROJECTION);
    GL11.glLoadIdentity();
    GL11.glOrtho(0, WIDTH, 0, HEIGHT, 1, -1);
    GL11.glMatrixMode(GL11.GL_MODELVIEW);

    // Enable alpha transparency (for overlay image)
    GL11.glEnable(GL11.GL_BLEND);
    GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
    GL11.glEnable(GL11.GL_DEPTH_TEST);
    GL11.glDepthFunc(GL11.GL_LEQUAL);
    GL11.glShadeModel(GL11.GL_SMOOTH);
}

public void gameStart() {

    System.out.println("LWJGL Version: ["+Sys.getVersion()+"]");
    System.out.println("OpenGL Version: ["+GL11.glGetString(GL11.GL_VERSION)+"]");

    // ===============================================================================================

    // =================== Shader Setup =====================
    String vertPath = "src/test/java/org/ajgl/test/graphics/shaders/VertexShaderTest.glsl";
    String fragPath = "src/test/java/org/ajgl/test/graphics/shaders/FragmentShaderTest.glsl";

    int sahderVert = GL20.glCreateShader(GL20.GL_VERTEX_SHADER);
    GL20.glShaderSource(sahderVert, Shader.loadShader(vertPath));
    GL20.glCompileShader(sahderVert);

    int sahderFrag = GL20.glCreateShader(GL20.GL_FRAGMENT_SHADER);
    GL20.glShaderSource(sahderFrag, Shader.loadShader(fragPath));
    GL20.glCompileShader(sahderFrag);
    // =================== Shader Setup =====================

    // =================== Shader Check =====================
    int status = GL20.glGetShaderi(sahderVert, GL20.GL_COMPILE_STATUS);
    if (status != GL11.GL_TRUE) {
        throw new RuntimeException(GL20.glGetShaderInfoLog(sahderVert));
    }

    int statusN = GL20.glGetShaderi(sahderFrag, GL20.GL_COMPILE_STATUS);
    if (statusN != GL11.GL_TRUE) {
        throw new RuntimeException(GL20.glGetShaderInfoLog(sahderFrag));
    }
    // =================== Shader Check =====================

    // =================== Shader Program ===================
    int programID = GL20.glCreateProgram();

    GL20.glAttachShader(programID, sahderVert);
    GL20.glAttachShader(programID, sahderFrag);

    GL20.glBindAttribLocation(programID, 0, "position");
    GL20.glBindAttribLocation(programID, 1, "color");

    GL20.glLinkProgram(programID);
    // =================== Shader Program ===================

    // =============== Shader Program Check =================
    int statusP = GL20.glGetProgrami(programID, GL20.GL_LINK_STATUS);
    if (statusP != GL11.GL_TRUE) {
        throw new RuntimeException(GL20.glGetProgramInfoLog(programID));
    }
    // =============== Shader Program Check =================

    // =================== VAO Setup ========================
    FloatBuffer vertexBufferVAO = BufferUtils.createFloatBuffer(9);
    vertexBufferVAO.put(new float[]{600,10,0, 550,50,0, 500,10,0});
    vertexBufferVAO.flip();

    FloatBuffer colorBufferVAO = BufferUtils.createFloatBuffer(9);
    colorBufferVAO.put(new float[]{1,0,0, 0,1,0, 0,0,1});
    colorBufferVAO.flip();

    int vaoID = GL30.glGenVertexArrays();
    GL30.glBindVertexArray(vaoID);
    {
        int vertHandle = GL15.glGenBuffers();
        GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, vertHandle);
        GL15.glBufferData(GL15.GL_ARRAY_BUFFER, vertexBufferVAO, GL15.GL_STATIC_DRAW);
        GL20.glVertexAttribPointer(0, 3, GL11.GL_FLOAT, false, 0, 0);

        int colorHandle = GL15.glGenBuffers();
        GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, colorHandle);
        GL15.glBufferData(GL15.GL_ARRAY_BUFFER, colorBufferVAO, GL15.GL_STATIC_DRAW);
        GL20.glVertexAttribPointer(1, 3, GL11.GL_FLOAT, false, 0, 0);
        GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
    }
    GL30.glBindVertexArray(0);

    // =================== VAO Setup ========================

    // ===============================================================================================

    while ( glfwWindowShouldClose(window) == GL_FALSE ) {
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

        // Run Cycles
        input();

        GL20.glUseProgram(programID);

        GL30.glBindVertexArray(vaoID);
        {
            GL20.glEnableVertexAttribArray(0);
            GL20.glEnableVertexAttribArray(1);

            GL11.glDrawArrays(GL11.GL_TRIANGLES, 0, 3);

            GL20.glDisableVertexAttribArray(0);
            GL20.glDisableVertexAttribArray(1);
        }
        GL30.glBindVertexArray(0);

        GL20.glUseProgram(0);

        // Display Buffer swap
        glfwSwapBuffers(window);
    }

    // Release window and window call backs
    glfwDestroyWindow(window);
    keyCallback.release();
    exit();
}

private void input() {
    glfwPollEvents();
    Tasker.executeASyncTask("GLFW_MAIN_THREAD");
}

public void exit() {
    // Terminate GLFW and release the GLFWerrorfun
    glfwTerminate();
    errorCallback.release();
    System.exit(1);
}

public static void main(String[] args) {
    Test test = new Test();
    test.initGL();
    test.gameStart();
}

}


着色器 class.

public class Shader {

    public static CharSequence loadShader(String path) {
        StringBuilder shaderSource = new StringBuilder();
        int shaderID = 0;

        try {
            BufferedReader reader = new BufferedReader(new FileReader(path));
            String line;
            while ((line = reader.readLine()) != null) {
                shaderSource.append(line).append("\n");
            }
            reader.close();
        } catch (IOException e) {
            System.err.println("Could not read file.");
            e.printStackTrace();
            System.exit(-1);
        }

        return shaderSource;
    }
}


顶点和片段着色器。

// Vertex Shader
#version 400

in vec3 position;
in vec3 color;

out vec3 Color;

void main()
{
    Color = color;
    gl_Position = vec4(position, 1.0);
}

// Fragment shader
#version 400

in vec3 Color;

out vec4 fragColor;

void main()
{
    fragColor = vec4(Color, 1.0);
}

我使用此站点找到了问题的解决方案 here。问题是我没有使用 link 中所说的设备坐标。相反,我使用的是笛卡尔坐标系。

修复。

FloatBuffer vertexBufferVAO = BufferUtils.createFloatBuffer(9);
**vertexBufferVAO.put(new float[]{{-0.95f,-0.95f,0, -0.5f,-0.95f,0, -0.95f,-0.5f,0});
vertexBufferVAO.flip();