当前位置: 首页 > 知识库问答 >
问题:

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

戚英逸
2023-03-14

(这是我第二次问这个问题了。上次我得到了一个没有解决问题的答案(那里的答案提到了我试图修复这个问题时偶然留下的一点代码)。我还稍微改变了问题本身——我改变了代码的顺序,把我认为错误更高的部分放在前面,并补充说我正在使用macOS,这可能是它不起作用的原因)。

所以,我刚刚开始学习LWJGL 3,我混合使用了一些html" target="_blank">教程和示例代码来制作一些东西,应该使用VAOs和VBOs将矩形渲染到洋红屏幕上。没有错误,但矩形没有出现在屏幕上(我只能看到一个洋红色屏幕)。我尝试使用旧的LWJGL管道(glBegin()glEnd()),它确实有效,因此我尝试更改渲染代码中的随机内容,以及加载到VAOs和VBOs。我也试图绑定VBO,但它没有改变任何事情。我也试过调试,似乎有一个VAO和一个VBO被创建了。

有人能看看我的代码,看看是否有问题吗?在这里(抱歉,如果有点乱。就像我说的,我不认为问题出在Main或Window类中,但我对LWJGL一无所知,所以无论如何我想把它放在这里。如果你有时间,也请看看它们。否则,如果你能看看加载器和渲染器类,我将不胜感激):

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

原始模型类:

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

共有1个答案

潘慈
2023-03-14

由于您使用的是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);
 类似资料:
  • 我已经试着让这段代码工作了一段时间,但我仍然不知道我做错了什么。(LWJGL-Java) 我曾尝试在网上查看其他人的代码,但我找不到任何重大区别。事实上,我学会了将OpenGL与C结合使用,所以我的大脑可能会被它卡住,这可能就是我找不到错误的原因。 这是init(调用一次) 这是渲染函数: 着色器: 顶点: Framgent公司:

  • 背景信息: 我正在使用OpenGL和LWJGL 3在屏幕上绘制一些四边形。我需要知道鼠标何时在四轴上。当我将四边形渲染到屏幕上时,我使用OpenGL坐标,X和Y的范围是从-1到1,而(0,0)在屏幕的中心。当我得到我使用的鼠标位置时 这给了我从0到窗口宽度或高度的坐标,在左上角(标题栏下方)有(0,0)。然后取鼠标坐标并计算OpenGL坐标。 例如,如果我的窗口大小为(800,600),而我的鼠标

  • 我正在做一个minecraft-ish游戏,我在vbos上做了更多的工作。然而在一个vbo中绘制多个面时,我似乎有点问题。 以下是我的vbo生成代码: 下面是我用来绘制vbo的代码: 这是我想要的结果(在每个vbo中使用一个四边形): 不幸的是,我还是新来的,所以你必须点击这个链接:/ 下面是我在每个vbo中使用多个四边形得到的结果: 形象 那么为什么我要在一个vbo中绘制多个四边形呢?一个词:性

  • 在我的理解中:一个VAO代表一个特定的状态。如果我绑定了一个VAO,添加一些VBO和元素缓冲区,用于索引和东西,我可以保存我想绘制和激活的对象的某个状态,然后在我想渲染东西的时候轻松地绘制它们。对吧? 所以VBO保存实际数据,而VAO只是一个“包装器-对象”,保存指向我为它定义的所有缓冲区的指针? 更改VAOs成本很高(更改VBO也是如此?!)。目前,我加载网格,并将它们组合到模型中。每个模型都使

  • 在过去的几天里,我一直在尝试将纹理缩放为Quad(OpenGL 3)... 但由于某些原因,我只得到渲染到四元网格上的图像左上角像素,我使用平滑的UTIL加载和绑定纹理。。。。 代码如下: 主要游戏。Java语言 着色器程序。Java语言 顶点着色器: 片段着色器: 装载机。Java语言 模型Java语言 vbo. java 这是我想要渲染的图像(它是测试图像)(PNG格式)一头奶牛: 这是我得到

  • 我在使用LWJGL和GLSL着色器在Java中渲染Master Cheif时遇到了一些问题,其中存在一些闪烁、多边形不相似和奇怪的颜色。我的一生都不知道为什么。 着色器:https://github.com/marko5049/LucidEngine/tree/master/src/res/shaders 主着色器:LightingMain ShdaowMapping Smapler过滤器 所有代