OpenGL绘制三角形不显示+ glClearColor未设置屏幕颜色

时间:2018-12-01 19:03:44

标签: java opengl glsl lwjgl

我有一个项目正在处理它在创建窗口,创建顶点和着色器,着色器程序,MemoryBuffer等方面的工作...到目前为止,我已经遇到了很多错误,并且运行时没有错误代码。 glClearColor()调用不会设置屏幕颜色,并且不会绘制三角形。 教程我在关注: Jeremy Barthe suggestion

主要:

public class DungeonRunners {
private double lastTick;

private float timeCount;

private int fps;
private int fpsCount;
private int ups;
private int upsCount;

public static void main(String[] args) {
    System.out.println("LWJGL Version: " + Version.getVersion());
    int width = 1240;
    int height = 720;
    boolean legacyGL = false;
    for (int i = 0; i < args.length; i++) {
        String arg = args[i];
        switch (arg) {
            case "width:":
                try {
                    width = Integer.parseInt(args[i+1]);
                    i++;
                } catch (NumberFormatException ignored) { }
                break;
            case "height:":
                try {
                    height = Integer.parseInt(args[i+1]);
                } catch (NumberFormatException ignored) { }
                break;
            case "-useLegacyGL":
                legacyGL = true;
                break;
        }
    }
    DungeonRunners dungeonRunners = new DungeonRunners();
    dungeonRunners.start(width, height, legacyGL);
}

private void start(int width, int height, Boolean legacyGL) {
    GLFW.glfwInit();
    if(!legacyGL) {
        GLFW.glfwDefaultWindowHints();
        GLFW.glfwWindowHint(GLFW.GLFW_CONTEXT_VERSION_MAJOR, 3);
        GLFW.glfwWindowHint(GLFW.GLFW_CONTEXT_VERSION_MINOR, 2);
        GLFW.glfwWindowHint(GLFW.GLFW_OPENGL_PROFILE, GLFW.GLFW_OPENGL_CORE_PROFILE);
        GLFW.glfwWindowHint(GLFW.GLFW_OPENGL_FORWARD_COMPAT, GLFW.GLFW_TRUE);
    } else {
        GLFW.glfwDefaultWindowHints();
        GLFW.glfwWindowHint(GLFW.GLFW_CONTEXT_VERSION_MAJOR, 2);
        GLFW.glfwWindowHint(GLFW.GLFW_CONTEXT_VERSION_MINOR, 1);

    }
    GLFW.glfwWindowHint(GLFW.GLFW_VISIBLE, GLFW.GLFW_FALSE);
    long window = GLFW.glfwCreateWindow(width, height, "Dungeon Runners", MemoryUtil.NULL, MemoryUtil.NULL);
    GLFW.glfwMakeContextCurrent(window);
    GL.createCapabilities(true);
    RenderEngine engine = new RenderEngine(legacyGL);
    GLFW.glfwWindowHint(GLFW.GLFW_RESIZABLE, GLFW.GLFW_TRUE);
    GLFW.glfwShowWindow(window);
    try ( MemoryStack stack = MemoryStack.stackPush() ) {
        IntBuffer pWidth = stack.mallocInt(1);
        IntBuffer pHeight = stack.mallocInt(1);
        GLFW.glfwGetWindowSize(window, pWidth, pHeight);
        GLFWVidMode vidmode = GLFW.glfwGetVideoMode(GLFW.glfwGetPrimaryMonitor());
        assert vidmode != null;
        GLFW.glfwSetWindowPos(
                window,
                (vidmode.width() - pWidth.get(0)) / 2,
                (vidmode.height() - pHeight.get(0)) / 2
        );
    }
    while(!GLFW.glfwWindowShouldClose(window)) {
        update();
        engine.frame();
        GLFW.glfwPollEvents();
    }
    engine.clean();
    GL.destroy();
    GLFW.glfwDestroyWindow(window);
    GLFW.glfwTerminate();
    try {
        Objects.requireNonNull(GLFW.glfwSetErrorCallback(null)).free();
    } catch(NullPointerException e) {
        System.exit(-1);
    }
}

private void update() {
    if (timeCount > 1f) {
        fps = fpsCount;
        fpsCount = 0;

        ups = upsCount;
        upsCount = 0;

        timeCount -= 1f;
    }
}

private float getDelta() {
    double time = getTime();
    float delta = (float) (time - lastTick);
    lastTick = time;
    timeCount += delta;
    return delta;
}

private double getTime() {
    return System.nanoTime() / 1000000000.0;
}

private void updateFPS() {
    fpsCount++;
}

private void updateUPS() {
    upsCount++;
}
}

RenderEngine:

public class RenderEngine {

private int shaderProgram;
private int vao = GL30.glGenVertexArrays();
private int fragmentShader;
private int vertexShader;
private List<Integer> vbos = new ArrayList<>();
private String vertexShaderCode =
        "#version 150 core\n"+
                "\n"+
                "in vec3 position;\n"+
                "in vec3 color;\n"+
                "\n"+
                "out vec3 vertexColor;\n"+
                "\n"+
                "uniform mat4 model;\n"+
                "uniform mat4 view;\n"+
                "uniform mat4 projection;\n"+
                "\n"+
                "void main() {\n"+
                "    vertexColor = color;\n"+
                "    mat4 mvp = projection * view * model;\n"+
                "    gl_Position = mvp * vec4(position, 1.0);\n"+
                "}";
private String fragmentShaderCode =
        "#version 150 core\n"+
        "\n"+
        "in vec3 vertexColor;\n"+
        "\n"+
        "out vec4 fragColor;\n"+
        "\n"+
        "void main() {\n"+
        "    fragColor = vec4(vertexColor, 1.0);\n"+
        "}";
private String legacyVertexShaderCode =
        "#version 120\n"+
                "\n"+
                "attribute vec3 position;\n"+
                "attribute vec3 color;\n"+
                "\n"+
                "varying vec3 vertexColor;\n"+
                "\n"+
                "uniform mat4 model;\n"+
                "uniform mat4 view;\n"+
                "uniform mat4 projection;\n"+
                "\n"+
                "void main() {\n"+
                "    vertexColor = color;\n"+
                "    mat4 mvp = projection * view * model;\n"+
                "    gl_Position = mvp * vec4(position, 1.0);\n"+
                "}";
private String legacyFragmentShaderCode =
        "#version 120\n"+
        "\n"+
        "varying vec3 vertexColor;\n"+
        "\n"+
        "void main() {\n"+
        "    gl_FragColor = vec4(vertexColor, 1.0);\n"+
        "}";

public RenderEngine(Boolean legacyGL) {
    GL30.glBindVertexArray(vao);
    setVertexAttribs();
    setupShaders(legacyGL);
    GL20.glUseProgram(shaderProgram);
    setUniformVars();
    bindImage();
}

private void bindImage() {
    MemoryStack stack = MemoryStack.stackPush();
    FloatBuffer vertices = stack.mallocFloat(3*6);
    vertices.put(-0.6f).put(-0.4f).put(0f).put(1f).put(0f).put(0f);
    vertices.put(0.6f).put(-0.4f).put(0f).put(0f).put(1f).put(0f);
    vertices.put(0f).put(0.6f).put(0f).put(0f).put(0f).put(1f);
    vertices.flip();
    int vbo = GL15.glGenBuffers();
    vbos.add(vbo);
    GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, vbo);
    GL15.glBufferData(GL15.GL_ARRAY_BUFFER, vertices, GL15.GL_STATIC_DRAW);
    MemoryStack.stackPop();
}

public void frame() {
    GL11.glClearColor(1, 0, 0, 0);
    GL11.glClear(GL11.GL_COLOR_BUFFER_BIT);
    bindImage();
    GL11.glDrawArrays(GL11.GL_TRIANGLES, 0, 3);
}

public void clean() {
    GL30.glDeleteVertexArrays(vao);
    for(int vbo : vbos)
        GL15.glDeleteBuffers(vbo);
    GL20.glDeleteShader(vertexShader);
    GL20.glDeleteShader(fragmentShader);
    GL20.glDeleteProgram(shaderProgram);
}

private void setUniformVars() {
    int uniModel = GL20.glGetUniformLocation(shaderProgram, "model");
    UtilMatrix4f model = new UtilMatrix4f();
    GL20.glUniformMatrix4fv(uniModel, false, model.getBuffer());

    int uniView = GL20.glGetUniformLocation(shaderProgram, "view");
    UtilMatrix4f view = new UtilMatrix4f();
    GL20.glUniformMatrix4fv(uniView, false, view.getBuffer());

    int uniProjection = GL20.glGetUniformLocation(shaderProgram, "projection");
    float ratio = 640f/480f;
    UtilMatrix4f projection = UtilMatrix4f.orthographic(-ratio, ratio, -1f, 1f, -1f, 1f);
    GL20.glUniformMatrix4fv(uniProjection, false, projection.getBuffer());
}

private void setVertexAttribs() {
    int floatSize = 4;
    int posAttrib = GL20.glGetAttribLocation(shaderProgram, "position");
    GL20.glEnableVertexAttribArray(posAttrib);
    GL20.glVertexAttribPointer(posAttrib, 3, GL11.GL_FLOAT, false, 6*floatSize, 0);
    int colAttrib = GL20.glGetAttribLocation(shaderProgram, "color");
    GL20.glEnableVertexAttribArray(colAttrib);
    GL20.glVertexAttribPointer(colAttrib, 3, GL11.GL_FLOAT, false, 6*floatSize, 3*floatSize);
}

private void setupShaders(boolean legacyGL) {
    vertexShader = GL20.glCreateShader(GL20.GL_VERTEX_SHADER);
    if (legacyGL)
        GL20.glShaderSource(vertexShader, legacyVertexShaderCode);
    else
        GL20.glShaderSource(vertexShader, vertexShaderCode);
    GL20.glCompileShader(vertexShader);
    int status = GL20.glGetShaderi(vertexShader, GL20.GL_COMPILE_STATUS);
    if (status != GL11.GL_TRUE) {
        throw new RuntimeException(GL20.glGetShaderInfoLog(vertexShader));
    }
    fragmentShader = GL20.glCreateShader(GL20.GL_FRAGMENT_SHADER);
    if (legacyGL)
        GL20.glShaderSource(fragmentShader, legacyFragmentShaderCode);
    else
        GL20.glShaderSource(fragmentShader, fragmentShaderCode);
    GL20.glCompileShader(fragmentShader);
    status = GL20.glGetShaderi(fragmentShader, GL20.GL_COMPILE_STATUS);
    if (status != GL11.GL_TRUE) {
        throw new RuntimeException(GL20.glGetShaderInfoLog(fragmentShader));
    }
    shaderProgram = GL20.glCreateProgram();
    GL20.glAttachShader(shaderProgram, vertexShader);
    GL20.glAttachShader(shaderProgram, fragmentShader);
    GL30.glBindFragDataLocation(shaderProgram, 0, "fragColor");
    GL20.glLinkProgram(shaderProgram);
    status = GL20.glGetProgrami(shaderProgram, GL20.GL_LINK_STATUS);
    if (status != GL11.GL_TRUE) {
        throw new RuntimeException(GL20.glGetProgramInfoLog(shaderProgram));
    }
}
}

1 个答案:

答案 0 :(得分:2)

glfwSwapBuffers丢失,以使呈现“可见”:

while(!GLFW.glfwWindowShouldClose(window)) {
    update();
    engine.frame();
    GLFW.glfwSwapBuffers(window);
    GLFW.glfwPollEvents();
}

链接着色器程序并绑定顶点数组对象后,必须获取顶点属性的位置:

setupShaders(legacyGL);
bindImage();
GL30.glBindVertexArray(vao);
setVertexAttribs();
GL20.glUseProgram(shaderProgram);
setUniformVars();

请注意,glGetAttribLocation要求提供活动程序资源的索引,并且当glLinkProgram喜欢着色器程序时,将确定活动程序资源。
此外,如果应将最后一个参数视为缓冲区对象数据存储区中的字节偏移(当然,尤其是在核心模式下),则在调用glBindBuffer之前,已命名的顶点缓冲区必须由glVertexAttribPointer绑定。