我无法使用open gl和glfw(LWJGL)将模型渲染到窗口

时间:2018-06-18 16:14:56

标签: java opengl lwjgl glfw

我正在努力熟悉Java的LWJGL库,我一直在线学习一些教程,似乎无法获得模型。

我正在使用OpenGL 2.1(这似乎已经过时但我不确定如何更新它,我知道它与您拥有的硬件相关,我使用的是MacBook Pro 2017型号,如果有人对此感兴趣的话我的规格)

如果有人可以查看我的代码并告诉我我做错了什么我真的很感激! (现在正在渲染的所有内容都是红色窗口)

从我研究过的这些代码中得到的代码应该是一个由两个三角形组成的正方形,使用顶点和片段着色器在渐变中着色,但是没有渲染任何东西。

public class Main {

private long window;
    private int width = 1280, height = 720;

    public void run() {
    System.out.println("LWJGL " + Version.getVersion() + "!");

    init();
    loop();

    glfwFreeCallbacks(window);
    glfwDestroyWindow(window);

    glfwTerminate();
    glfwSetErrorCallback(null).free();
    }

    private void init() {
    GLFWErrorCallback.createPrint(System.err).set();

    if (!glfwInit()) throw new IllegalStateException("Unable to initialize GLFW");

    glfwDefaultWindowHints(); 
    glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE); 
    glfwWindowHint(GLFW_RESIZABLE, GLFW_TRUE); 

    window = glfwCreateWindow(width, height, "TESTING", NULL, NULL);
    if (window == NULL) throw new RuntimeException("Failed to create the GLFW window");

    glfwSetKeyCallback(window, (window, key, scancode, action, mods) -> {
        if (key == GLFW_KEY_ESCAPE && action == GLFW_RELEASE) glfwSetWindowShouldClose(window, true); /
    });

    try (MemoryStack stack = stackPush()) {
        IntBuffer pWidth = stack.mallocInt(1); // int*
        IntBuffer pHeight = stack.mallocInt(1); // int*

        glfwGetWindowSize(window, pWidth, pHeight);

        GLFWVidMode vidmode = glfwGetVideoMode(glfwGetPrimaryMonitor());

        glfwSetWindowPos(window, (vidmode.width() - pWidth.get(0)) / 2, (vidmode.height() - pHeight.get(0)) / 2);
    }
    glfwMakeContextCurrent(window);
    glfwSwapInterval(1);

    glfwShowWindow(window);
    }

    private void loop() {
    GL.createCapabilities();

      GL11.glClearColor(1.0f, 0.0f, 0.0f, 0.0f);

    Renderer renderer = new Renderer();
    Loader loader = new Loader();
        StaticShader shader = new StaticShader();


    float[] vertices = {
            -0.5f, 0.5f, 0f,
            -0.5f, -0.5f, 0f,
            0.5f, -0.5f, 0f,
            0.5f, 0.5f, 0f,
          };

    int[] indicies = {
        0,1,3,
        3,1,2
    };

    RawModel model = loader.loadToVAO(vertices, indicies);

    while (!glfwWindowShouldClose(window)) {
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

        glfwSwapBuffers(window);

        renderer.prepare();
        shader.start();
        renderer.render(model);
        shader.stop();

        glfwPollEvents();
    }
     loader.cleanUp();
     shader.cleanUp();
    }

    public static void main(String[] args) {
    new Main().run();
    }

}

public class RawModel {

    private int vaoID;
    private int vertexCount;

    public RawModel(int vaoID, int vertexCount) {
    this.vaoID = vaoID;
    this.vertexCount = vertexCount;
    }

    public int getVaoID() {
    return vaoID;
    }

    public int getVertexCount() {
    return vertexCount;
    }

}

public class Renderer {

    public void prepare() {
        GL11.glClearColor(1, 0, 0, 1);
        GL11.glClear(GL11.GL_COLOR_BUFFER_BIT);
    }

    public void render(RawModel model){
            GL30.glBindVertexArray(model.getVaoID());
            GL20.glEnableVertexAttribArray(0);
            //System.out.println(model.getVertexCount());
            GL11.glDrawElements(GL11.GL_TRIANGLES, model.getVertexCount(), GL11.GL_UNSIGNED_INT, 0);
            GL20.glDisableVertexAttribArray(0);
            GL30.glBindVertexArray(0);
        }
}

public class Loader {

    private List<Integer> vaos = new ArrayList<Integer>();
    private List<Integer> vbos = new ArrayList<Integer>();

    public RawModel loadToVAO(float[] positions,int[] indicies) {
        int vaoID = createVAO();
        bindIndecesBuffer(indicies); 
        storeDataInAttributeList(0, positions);
        unbindVAO();
        return new RawModel(vaoID, indicies.length);
    }

    private void bindIndecesBuffer(int[] indices) {
        int vboID = GL15.glGenBuffers();
        vbos.add(vboID);
        GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, vboID);
        IntBuffer buffer = storeDatainIntBuffer(indices);
        GL15.glBufferData(GL15.GL_ELEMENT_ARRAY_BUFFER, buffer, GL15.GL_STATIC_DRAW);
    }

    private IntBuffer storeDatainIntBuffer(int[] data) {
        IntBuffer buffer = BufferUtils.createIntBuffer(data.length);
        buffer.put(data);
        buffer.flip();
        return buffer;
    }

    public void cleanUp() {
        for (int vao : vaos) {
            GL30.glDeleteVertexArrays(vao);
        }
        for (int vbo : vbos) {
            GL15.glDeleteBuffers(vbo);
        }
    }


    private int createVAO() {
        int vaoID = GL30.glGenVertexArrays();
        vaos.add(vaoID);
        GL30.glBindVertexArray(vaoID);
        return vaoID;
    }


    private void storeDataInAttributeList(int attributeNumber, float[] data) {
        int vboID = GL15.glGenBuffers();
        vbos.add(vboID);
        GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, vboID);
        FloatBuffer buffer = storeDataInFloatBuffer(data);
        GL15.glBufferData(GL15.GL_ARRAY_BUFFER, buffer, GL15.GL_STATIC_DRAW);
        GL20.glVertexAttribPointer(attributeNumber, 3, GL11.GL_FLOAT, false, 0, 0);
        GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
    }

    private void unbindVAO() {
        GL30.glBindVertexArray(0);
    }

    private FloatBuffer storeDataInFloatBuffer(float[] data) {
        FloatBuffer buffer = BufferUtils.createFloatBuffer(data.length);
        buffer.put(data);
        buffer.flip();
        return buffer;
    }

}

public abstract class ShaderProgram {

    private int programID;
    private int vertexShaderID;
    private int fragmentShaderID;

    public ShaderProgram(String vertexFile,String fragmentFile){
        vertexShaderID = loadShader(vertexFile,GL20.GL_VERTEX_SHADER);
        fragmentShaderID = loadShader(fragmentFile,GL20.GL_FRAGMENT_SHADER);
        programID = GL20.glCreateProgram();
        GL20.glAttachShader(programID, vertexShaderID);
        GL20.glAttachShader(programID, fragmentShaderID);
        bindAttributes();
        GL20.glLinkProgram(programID);
        GL20.glValidateProgram(programID);
    }

    public void start(){
        GL20.glUseProgram(programID);
    }

    public void stop(){
        GL20.glUseProgram(0);
    }

    public void cleanUp(){
        stop();
        GL20.glDetachShader(programID, vertexShaderID);
        GL20.glDetachShader(programID, fragmentShaderID);
        GL20.glDeleteShader(vertexShaderID);
        GL20.glDeleteShader(fragmentShaderID);
        GL20.glDeleteProgram(programID);
    }

    protected abstract void bindAttributes();

    protected void bindAttribute(int attribute, String variableName){
        GL20.glBindAttribLocation(programID, attribute, variableName);
    }

    private static int loadShader(String file, int type){
        StringBuilder shaderSource = new StringBuilder();
        try{
            BufferedReader reader = new BufferedReader(new FileReader(file));
            String line;
            while((line = reader.readLine())!=null){
                shaderSource.append(line).append("//\n");
            }
            reader.close();
        }catch(IOException e){
            e.printStackTrace();
            System.exit(-1);
        }
        int shaderID = GL20.glCreateShader(type);
        GL20.glShaderSource(shaderID, shaderSource);
        GL20.glCompileShader(shaderID);
        if(GL20.glGetShaderi(shaderID, GL20.GL_COMPILE_STATUS )== GL11.GL_FALSE){
            System.out.println(GL20.glGetShaderInfoLog(shaderID, 500));
            System.err.println("Could not compile shader!");
            System.exit(-1);
        }
        return shaderID;
    }

}

public class StaticShader extends ShaderProgram {

    private static final String VERTEX_FILE = "src/shaderEngine/vertexShader.txt";
    private static final String FRAGMENT_FILE = "src/shaderEngine/fragmentShader.txt";

    public StaticShader() {
        super(VERTEX_FILE, FRAGMENT_FILE);
    }

    @Override
    protected void bindAttributes() {
        super.bindAttribute(0, "position");
    }

}

//VERTEX SHADER

#version 120

attribute vec3 position;

varying vec3 colour;

void main(void){

    gl_Position = vec4(position,1.0);
    colour = vec3(position.x+0.5,0.0,position.y+0.5);
}

//FRAGMENT SHADER

#version 120

varying vec3 colour;

void main(void){

    gl_FragColor = vec4(colour,1.0);

}

1 个答案:

答案 0 :(得分:1)

您的代码使用Vertex Array Objects (VAOs)进行渲染。正如lwjgl的GL30语法所建议的那样,这是OpenGL 3.0的功能。仅当您的实现碰巧实现了GL_ARB_vertex_array_object OpenGL extension时,才能在GL 2.1上下文中运行此代码。

  

我使用OpenGL 2.1(这似乎已经过时了,但是我不太确定如何更新它,我知道它与您拥有的硬件有关,如果有人感兴趣,我会使用MacBook Pro 2017型号我的规格)

YOu仅限于OpenGL 2.1,因为您使用的是旧版 GL上下文。如果要在OSX上使用较新的OpenGL,则必须在上下文创建时请求GL 3.2 核心配置文件上下文。还应注意,Apple将支持的最新GL版本是GL 4.1,并且Apple实际上宣布已弃用OpenGL,并可能将其从OSX的将来版本中完全删除。