java - 我正在尝试在 OpenGL (LWJGL) 中使用 vbo 渲染模型

标签 java opengl lwjgl wavefront

我正在尝试通过导入 .obj 文件来渲染模型。我成功导入并准备了要在 FloatBuffers/IntegerBuffers 中呈现的数据,但无法设法呈现它。有人可以帮助我吗?

这是呈现和初始化 VBO 的类

private int vertexBufferID;
private int indexBufferID;
private int numberIndices;

public void init() {
    try{
        InputStream objInputStream = new FileInputStream("./res/obj/Terrain.obj");
        Obj obj = ObjReader.read(objInputStream);

        obj = ObjUtils.convertToRenderable(obj);

        IntBuffer indices = ObjData.getFaceVertexIndices(obj, 3);
        FloatBuffer vertices = ObjData.getVertices(obj);
//      FloatBuffer texCoords = ObjData.getTexCoords(obj, 2);
//      FloatBuffer normals = ObjData.getNormals(obj);

        vertexBufferID = GL15.glGenBuffers();
        GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, vertexBufferID);
        GL15.glBufferData(GL15.GL_ARRAY_BUFFER, vertices, GL15.GL_STATIC_DRAW);
        GL20.glVertexAttribPointer(0, 3, GL11.GL_FLOAT, false, 0, 0);
        GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);

        GL30.glBindVertexArray(0);

        indexBufferID = GL15.glGenBuffers();
        GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, indexBufferID);
        GL15.glBufferData(GL15.GL_ELEMENT_ARRAY_BUFFER, indices, GL15.GL_STATIC_DRAW);
        GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, 0);
    }catch(IOException e)
    {
        e.printStackTrace();
    }
}

public void render() {
    GL11.glEnableClientState(GL11.GL_VERTEX_ARRAY);
    GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, vertexBufferID);
    GL11.glVertexPointer(3, GL11.GL_FLOAT, 0, 0);

    GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, indexBufferID);
    GL11.glDrawElements(GL11.GL_TRIANGLES, numberIndices, GL11.GL_UNSIGNED_INT, 0);
}

我没有收到错误代码,只是对象没有被渲染。我能够使用显示列表呈现对象。

最佳答案

我现在已经解决了这个问题,现在可以导入 .obj 文件并使用 vbo/vao 渲染它们。我正在使用 "Obj - a simple Wavefront OBJ file loader and writer"准备要渲染的数据。

加载和准备 .obj 文件的代码

        InputStream objInputStream = new FileInputStream(pathTObjFile);
        Obj obj = ObjReader.read(objInputStream);

        obj = ObjUtils.convertToRenderable(obj);

        IntBuffer indices = ObjData.getFaceVertexIndices(obj, 3);
        FloatBuffer vertices = ObjData.getVertices(obj);

现在数据存储在 2 个 VBO 中,顶点的 VBO 存储在 VAO 中:

        vaoId = GL30.glGenVertexArrays();

顶点数组对象 ID (vaoID) 是一个整数,如果我们调用 VAO,它就会被调用。

        GL30.glBindVertexArray(vaoId);

为了能够对 VAO 执行任何操作,我们必须绑定(bind)或“选择”它。

        vboId = GL15.glGenBuffers();

VBO 也有一个 ID 可以用来调用。我们在这里创建顶点缓冲区对象 ID (vboId)

        GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, vboId);
        GL15.glBufferData(GL15.GL_ARRAY_BUFFER, vertices, GL15.GL_STATIC_DRAW);

现在我们选择 VBO 并将顶点存储在其中。

        GL20.glVertexAttribPointer(0, 3, GL11.GL_FLOAT, false, 0, 0);

        GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);

        GL30.glBindVertexArray(0);

首先我们将VBO放在VAO的第一个属性列表中(一个VAO有16个列表),然后解除VAO和VBO的绑定(bind)。

        vboiId = GL15.glGenBuffers();
        GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, vboiId);
        GL15.glBufferData(GL15.GL_ELEMENT_ARRAY_BUFFER, indices, GL15.GL_STATIC_DRAW);

        GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, 0); 


        indicesCount = indices.capacity();

在初始化结束时,我们为索引创建了 vbo,这样顶点就可以相互连接,以正确的方式创建面。因此,我们绑定(bind) vboiId 并将索引数据存储在其中。然后我们再次解除绑定(bind) VBO 并保存存储在 VBO 中的索引数,因为我们必须告诉它 OpenGL 以便稍后能够渲染它。

渲染对象:

    GL30.glBindVertexArray(vaoId);
    GL20.glEnableVertexAttribArray(0);
    GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, vboiId);

要渲染对象,我们必须在其中绑定(bind) VAO 和 VBO。我们还必须为指数选择 IBO。这是通过上面的代码片段完成的。

    GL11.glDrawElements(GL11.GL_TRIANGLES, indicesCount, GL11.GL_UNSIGNED_INT, 0);

现在我们绘制对象

    GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, 0);
    GL20.glDisableVertexAttribArray(0);
    GL30.glBindVertexArray(0);

再次取消选择 VBO 和 VAO。

这里是整个代码组合

private int vboiId;
private int vaoId;
private int vboId;
private int indicesCount;

public void init() {

    try{

        InputStream objInputStream = 
            new FileInputStream("./res/obj/Terrain.obj");
        Obj obj = ObjReader.read(objInputStream);

        obj = ObjUtils.convertToRenderable(obj);

        IntBuffer indices = ObjData.getFaceVertexIndices(obj, 3);
        FloatBuffer vertices = ObjData.getVertices(obj);
        FloatBuffer texCoords = ObjData.getTexCoords(obj, 2);
        FloatBuffer normals = ObjData.getNormals(obj);



        indicesCount = indices.capacity();


        vaoId = GL30.glGenVertexArrays();
        GL30.glBindVertexArray(vaoId);


        vboId = GL15.glGenBuffers();
        GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, vboId);
        GL15.glBufferData(GL15.GL_ARRAY_BUFFER, vertices, GL15.GL_STATIC_DRAW);

        GL20.glVertexAttribPointer(0, 3, GL11.GL_FLOAT, false, 0, 0);

        GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);


        GL30.glBindVertexArray(0);


        vboiId = GL15.glGenBuffers();
        GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, vboiId);
        GL15.glBufferData(GL15.GL_ELEMENT_ARRAY_BUFFER, indices, GL15.GL_STATIC_DRAW);

        GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, 0);
    }catch(IOException e)
    {
        e.printStackTrace();
    }


}

public void render() {
    GL11.glClear(GL11.GL_COLOR_BUFFER_BIT);


    GL30.glBindVertexArray(vaoId);
    GL20.glEnableVertexAttribArray(0);


    GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, vboiId);


    GL11.glDrawElements(GL11.GL_TRIANGLES, indicesCount, GL11.GL_UNSIGNED_INT, 0);


    GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, 0);
    GL20.glDisableVertexAttribArray(0);
    GL30.glBindVertexArray(0);
}

有关更多详细信息,我强烈建议您阅读 The quad with Draw Array , The Quad with Draw Elements如果您想更详细地了解 Main Page 上的 OpenGL 3.2 及更高版本教程LWJGL Wiki 的。 有关如何使用我使用的 Obj 加载器的信息,请查找 The sample projects using this loader

我的代码基本上由这些网站上的代码混合而成。

编辑:如果您尝试渲染多个对象,则必须在渲染第一个对象之前清除颜色(Render 方法的第一行)

关于java - 我正在尝试在 OpenGL (LWJGL) 中使用 vbo 渲染模型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48957104/

相关文章:

c++ - 食人魔 3d : RenderTexture bigger than RenderWindow

c - 仅使用 C 语言的 OPENGL 3D 世界中的物理

linux - Linux 中的 OpenGL 离屏渲染很慢

java - 相互检查两个日历,看看它们是否相隔一周以上

java - 模拟一个列表并尝试迭代它

java - Selenium Chromedriver 超时窗口关闭

java - 设计: Emailing System in Java

java - 初始化后 OpenGL 窗口卡住

java - 模型矩阵畸形结果上的 Opengl 翻译

java - 尝试从波前.obj文件加载纹理时,为什么在使用索引渲染(glDrawElements)时纹理显示不正确?