LWJGL3 shader, triangle not showing up

2019-09-11 06:50发布

I'm new to OpenGL and LWJGL3 and I'm trying to render a triangle. However, it isn't showing up, only the white, empty window. I guess it's a pretty small piece that I somehow forgot or where I just made a mistake. I don't find it after searching for hours now though. Here's the code:

MainLoop:

import static org.lwjgl.opengl.GL11.*;
import static org.lwjgl.opengl.GL15.*;
import static org.lwjgl.opengl.GL20.*;
import static org.lwjgl.opengl.GL30.*;
import static org.lwjgl.glfw.GLFW.*;

public class MainLoop {

private DisplayManager displayManager;
private Shader shader;

public MainLoop() {
    displayManager = new DisplayManager();
    displayManager.createDisplay();
    shader = new Shader("src/shader.vert", "src/shader.frag");
}

private void start() {

    float positions[] = {
        -0.5f, 0.0f, 0.0f,
         0.5f, 0.0f, 0.0f,
         0.0f, 0.5f, 0.0f
    };

    int vao = glGenVertexArrays();
    glBindVertexArray(vao);

    int positionVbo = glGenBuffers();
    glBindBuffer(GL_ARRAY_BUFFER, positionVbo);
    glBufferData(GL_ARRAY_BUFFER, BufferUtils.createFloatBuffer(positions), GL_STATIC_DRAW);
    glEnableVertexAttribArray(0);
    glVertexAttribPointer(0, 3, GL_FLOAT, false, 0, 0);

    while(!displayManager.isCloseRequested()) {
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        glBindVertexArray(vao);

        render();
        update();

        displayManager.swapBuffers();
    }

    shader.cleanUp();
    displayManager.destroyDisplay();
}

private void update() {
    glfwPollEvents();
}

private void render() {
    shader.bind();

    //rendering stuff
    glDrawArrays(GL_TRIANGLES, 0, 3);

    shader.unbind();
}

public static void main(String[] args) {
    new MainLoop().start();
}
}

Shader:

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

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;


public class Shader {
    private int program;

    public Shader(final String vertexShaderFilePath, final String fragmentShaderFilePath) {
        int vertexShader   = createShader(loadShaderSource(vertexShaderFilePath), GL_VERTEX_SHADER);
        int fragmentShader = createShader(loadShaderSource(fragmentShaderFilePath), GL_FRAGMENT_SHADER);

        program = glCreateProgram();
        glAttachShader(vertexShader, program);
        glAttachShader(fragmentShader, program);
        glLinkProgram(program);
        glValidateProgram(program); //just during development

        glDeleteShader(vertexShader);
        glDeleteShader(fragmentShader);
    }

    private String loadShaderSource(final String shaderFilePath) {
        String shaderSourceString = "";
        try {
            shaderSourceString = new String(Files.readAllBytes(Paths.get(shaderFilePath)));
        } catch (IOException e) {
            e.printStackTrace();
        }

        return shaderSourceString;
    }

    private int createShader(final String shaderSourceString, final int type) {
        int shader = glCreateShader(type);
        glShaderSource(shader, shaderSourceString);
        glCompileShader(shader);
        checkShaderCompileError(shader);

        return shader;
    }

    private void checkShaderCompileError(int shader) {
        if(glGetShaderi(shader, GL_COMPILE_STATUS) == GL_FALSE) {
            System.err.println("Could not compile shader.");
            System.err.println(glGetShaderInfoLog(program));
            System.exit(-1);
        }
    }

    public void bind() {
        glUseProgram(program);
    }

    public void unbind() {
        glUseProgram(0);
    }

    public void cleanUp() {
        glDeleteProgram(program);
    }
}

BufferUtils:

import java.nio.FloatBuffer;

public class BufferUtils {

    public static FloatBuffer createFloatBuffer(float[] array) {
        FloatBuffer buffer = org.lwjgl.BufferUtils.createFloatBuffer(array.length);
        buffer.put(array);
        buffer.flip();
        return buffer;
    }
}

shader.vert:

#version 410 core

layout (location = 0) in vec3 vertex_position;

void main(void)
{
    gl_Position = vec4(vertex_position, 1.0);
}

shader.frag:

#version 410 core

out vec4 frag_color;

void main(void)
{
    frag_color = vec4(1.0, 0.0, 1.0, 1.0);
}

EDIT: and here's the DisplayManager:

import static org.lwjgl.glfw.GLFW.*;
import static org.lwjgl.system.MemoryUtil.*;
import static org.lwjgl.opengl.GL11.*;
import static org.lwjgl.opengl.GLContext.*;

import java.nio.ByteBuffer;

import org.lwjgl.glfw.GLFWvidmode;

public class DisplayManager {

    private static final int WIDTH  = 1280;
    private static final int HEIGHT = 800;

    private long window;
    private Keyboard keyCallback;

    public void createDisplay() {

        // initialize GLFW
        if(glfwInit() != GL_TRUE) {
            System.err.println("GLFW failed to initialize.");
            System.exit(-1);
        }

        // set window hints
        glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
        glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2);
        glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
        glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
        glfwWindowHint(GLFW_RESIZABLE, GL_TRUE);
        glfwWindowHint(GLFW_SAMPLES, 4); //16 for production

        // create window
        window = glfwCreateWindow(WIDTH, HEIGHT, "OpenGL", NULL, NULL);
        if(window == NULL) {
            System.err.println("GLFW window failed to create.");
            glfwTerminate();
            System.exit(-1);
        }
        ByteBuffer videoMode = glfwGetVideoMode(glfwGetPrimaryMonitor());
        glfwSetWindowPos(window, (GLFWvidmode.width(videoMode) - WIDTH) / 2, (GLFWvidmode.height(videoMode) - HEIGHT) / 2);

        // set callback mechanisms
        glfwSetKeyCallback(window, setKeyCallback(new Keyboard()));

        // set context and show window
        glfwMakeContextCurrent(window);
        createFromCurrent();
        glfwSwapInterval(1); // v-sync
        glfwShowWindow(window);

        // openGL functions
        glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
        glEnable(GL_DEPTH);
    }

    public void destroyDisplay() {
        glfwDestroyWindow(window);
        glfwTerminate();
    }

    public boolean isCloseRequested() {
        if(glfwWindowShouldClose(window) == GL_TRUE) {
            return true;
        }
        return false;
    }

    public void swapBuffers() {
        glfwSwapBuffers(window);
    }

    public Keyboard getKeyCallback() {
        return keyCallback;
    }

    public Keyboard setKeyCallback(Keyboard keyCallback) {
        this.keyCallback = keyCallback;
        return keyCallback;
    }
}

Does anybody spot what's going wrong?

Thanks in advance!

1条回答
别忘想泡老子
2楼-- · 2019-09-11 06:58

I finally found the error, the order of parameters for the call glAttachShader(shader, program); were mixed up. You first have to pass the program and then the shader id like so: glAttachShader(program, shader);. Thank you for your answers though!

查看更多
登录 后发表回答