使用vaos和vbos在LWJGL3中呈现四边形时出现问题

b09cbbtk  于 2021-07-06  发布在  Java
关注(0)|答案(1)|浏览(338)

(这是我第二次问这个问题。上一次我得到了一个没有解决它的答案(那里的答案引用了一段代码,这段代码是我试图修复这个问题时意外留下的)。我还稍微改变了问题本身——我改变了代码顺序,把我认为错误的部分放在更高的位置,并补充说我正在使用macos,这可能是它不起作用的原因)。
所以,我刚开始学习lwjgl3,我混合使用了一些教程和示例代码,用vaos和vbos制作了一个矩形到洋红色屏幕的东西。没有错误,但矩形没有出现在屏幕上(我只能看到一个洋红色屏幕)。我试过使用旧的lwjgl管道( glBegin() 以及 glEnd() )它确实起作用了,所以我试着在渲染代码和加载到vaos和vbos时改变一些随机的东西。我也尝试过绑定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, 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, 0, 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, 0f,
            -0.5f, -0.5f, 0f,
            0.5f, -0.5f, 0f,
            // Right top triangle
            0.5f, -0.5f, 0f,
            0.5f, 0.5f, 0f,
            -0.5f, 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, 0, 900, 300);

    }

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

下面是window类:

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

ocebsuys1#

既然您使用的是macos,我建议您设置一个3.2核心概要opengl上下文。请参见os x上的opengl开发:

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

相关问题