LWJGL3着色器,三角形不显示

时间:2015-08-28 12:25:54

标签: java opengl shader lwjgl

我是OpenGL和LWJGL3的新手,我试图渲染一个三角形。但是,它不会显示,只有白色的空窗口。我想这是一个非常小的片段,我不知何故忘记了或者我犯了错误。我现在搜索了几个小时后才发现它。这是代码:

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

着色器:

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

编辑:这是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;
    }
}

有没有人发现出了什么问题?

提前致谢!

1 个答案:

答案 0 :(得分:0)

我终于找到了错误,调用glAttachShader(shader, program);的参数顺序混淆了。首先必须传递程序,然后是着色器ID,如下所示:glAttachShader(program, shader);。谢谢你的答案!