使用VAO和VBO在LWJGL 3中渲染四边形的问题

问题描述

(这是我第二次问这个问题。上次我得到一个不能解决问题的答案(该答案引用了我修复该问题的一次尝试中遗留的一些代码)。我还稍稍更改了问题本身-我更改了代码顺序,以使该部分放在我认为错误较高的位置,并补充说明我正在使用macOS,这可能是它不起作用的原因。)

因此,我刚刚开始学习LWJGL 3,我使用了一些教程和示例代码的混合物来制作一些东西,这些东西应该使用VAO和VBO将矩形渲染为品红色屏幕。没有错误,但矩形未显示在屏幕上(我所看到的只是洋红色屏幕)。我尝试使用旧的LWJGL管道(glBegin()glEnd()),但它确实起作用,因此我尝试更改渲染代码中的随机内容以及将其加载到VAO和VBO。我也尝试绑定VBO,但没有任何改变。我还尝试了调试,似乎创建了一个VAO和一个VBO。

有人可以看一下我的代码,看看是否有问题吗?这里是(对不起,如果有点混乱。就像我说的那样,我不认为问题出在Main或Window类中,但是我不了解LWJGL,所以我还是想把它放在这里。如果有时间,请同时查看它们。否则,如果您可以查看Loader和Renderer类,我将不胜感激:

(顺便说一句,我正在使用macOS,并且确实有-XstartOnFirstThread)。

原始模型类:

package engine.io;
 
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;
    }
}

加载程序类:

package engine.io;
 
import java.nio.FloatBuffer;
import java.util.ArrayList;
import java.util.List;

import org.lwjgl.BufferUtils;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL15;
import org.lwjgl.opengl.GL20;
import org.lwjgl.opengl.GL30;
import org.lwjgl.system.MemoryUtil;

public class Loader {
        
    private List<Integer> vaos = new ArrayList<Integer>();
    private List<Integer> vbos = new ArrayList<Integer>();
     
    public RawModel loadToVAO(float[] positions) {
        int vaoID = createVAO();
        storeDataInAttributeList(0,positions);
        unbindVAO();
        return new RawModel(vaoID,positions.length/3);
    }
     
    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);
        GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER,0);
    }
     
    private void unbindVAO() {
        GL30.glBindVertexArray(0);
    }
     
    private FloatBuffer storeDataInFloatBuffer(float[] data) {
        FloatBuffer buffer = MemoryUtil.memAllocFloat(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);
        }
    }
}

渲染器类:

package engine.io;
    
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL15;
import org.lwjgl.opengl.GL20;
import org.lwjgl.opengl.GL30;

public class Renderer {

    public void prepare() {
        GL11.glClear(GL11.GL_COLOR_BUFFER_BIT);
        GL11.glClearColor(1f,0f,1f,1f);
    }
     
    public void render(RawModel model) {
        GL30.glBindVertexArray(model.getVaoID());
        GL20.glEnableVertexAttribArray(0);
        GL11.glDrawArrays(GL11.GL_TRIANGLES,model.getVertexCount());
        GL20.glDisableVertexAttribArray(0);
        GL30.glBindVertexArray(0);
    }
}

这是主要班级:

import org.lwjgl.*;
import org.lwjgl.glfw.*;
import org.lwjgl.opengl.*;
import org.lwjgl.system.*;

import engine.io.Loader;
import engine.io.RawModel;
import engine.io.Renderer;
import engine.io.Window;

import java.nio.*;

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

public class Main {
 
    private Window window;
     
    Loader loader = new Loader();
    Renderer renderer = new Renderer();
     
    float[] vertices = {
            // Left bottom triangle
            -0.5f,0.5f,-0.5f,// Right top triangle
            0.5f,0f
    };
     
    RawModel model;
     
    public void run() {
        setup();
        loop();
         
        loader.cleanUp();
 
        glfwFreeCallbacks(window.getWindowNum());
        glfwDestroyWindow(window.getWindowNum());
         
        glfwTerminate();
        glfwSetErrorCallback(null).free();
    }
 
    private void loop() {
        while ( !glfwWindowShouldClose(window.getWindowNum()) ) {
            glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // clear the framebuffer
             
            renderer.render(model);
             
            glfwSwapBuffers(window.getWindowNum()); // swap the color buffers
             
            glfwPollEvents();
        }
    }
 
    public void setup() {
        window = new Window(900,300,"Flappy Bird");
        window.create();
         
        GL.createCapabilities();
        GLFW.glfwMakeContextCurrent(window.getWindowNum());
 
        model = loader.loadToVAO(vertices);
        renderer.prepare();
         
        GL11.glViewport(0,900,300);
        
    }
     
    public static void main(String[] args) {
        new Main().run();
    }
}

这是窗口类:

package engine.io;
 
import static org.lwjgl.glfw.GLFW.*;
import static org.lwjgl.opengl.GL11.*;
import static org.lwjgl.system.MemoryStack.stackPush;
import static org.lwjgl.system.MemoryUtil.*;

import java.nio.IntBuffer;

//import static org.lwjgl.glfw.GLFW.*;
import org.lwjgl.glfw.GLFW;
import org.lwjgl.glfw.GLFWErrorCallback;
import org.lwjgl.glfw.GLFWVidMode;
import org.lwjgl.system.MemoryStack;

public class Window {
    private int width,height;
    private String title;
    private long window;
 
    public Window(int width,int height,String title) {
        this.width = width;
        this.height = height;
        this.title = title;
    }
 
    public void create() {
        GLFWErrorCallback.createPrint(System.err).set();
 
        if (!glfwInit())
            throw new IllegalStateException("Unable to initialize GLFW");
 
        // Configure GLFW
        glfwDefaultWindowHints(); // optional,the current window hints are already the default
        glfwWindowHint(GLFW_VISIBLE,GLFW_FALSE); // the window will stay hidden after creation
        glfwWindowHint(GLFW_RESIZABLE,GLFW_TRUE); // the window will be resizable
 
        // Create the window
        window = glfwCreateWindow(width,height,"Flappy Bird",NULL,NULL);
        if (window == NULL)
            throw new RuntimeException("Failed to create the GLFW window");
 
        // Get the thread stack and push a new frame
        try (MemoryStack stack = stackPush()) {
            IntBuffer pWidth = stack.mallocInt(1); // int*
            IntBuffer pHeight = stack.mallocInt(1); // int*
 
            // Get the window size passed to glfwCreateWindow
            glfwGetWindowSize(window,pWidth,pHeight);
 
            // Get the resolution of the primary monitor
            GLFWVidMode vidmode = glfwGetVideoMode(glfwGetPrimaryMonitor());
 
            // Center the window
            glfwSetWindowPos(window,(vidmode.width() - pWidth.get(0)) / 2,(vidmode.height() - pHeight.get(0)) / 2);
        } // the stack frame is popped automatically
            // Setup a key callback. It will be called every time a key is pressed,repeated
            // or released.
        glfwSetKeyCallback(window,(window,key,scancode,action,mods) -> {
            if (key == GLFW_KEY_ESCAPE && action == GLFW_RELEASE)
                glfwSetWindowShouldClose(window,true); // We will detect this in the rendering loop
        });
 
        // Make the OpenGL context current
        glfwMakeContextCurrent(window);
        // Enable v-sync
        glfwSwapInterval(1);
 
        // Make the window visible
        glfwShowWindow(window);
 
    }
         
    public long getWindowNum() {
        return window;
    }
}

解决方法

由于您使用的是MacOS,因此建议您设置3.2核心配置文件OpenGL Context。参见OpenGL Development on OS X

glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR,3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR,2);
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT,true);
glfwWindowHint(GLFW_OPENGL_PROFILE,GLFW_OPENGL_CORE_PROFILE);

// Create the window
window = glfwCreateWindow(width,height,"Flappy Bird",NULL,NULL);

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...