关于OpenGL VBO的问题

时间:2013-02-03 21:36:18

标签: java opengl lwjgl vbo

我正在尝试制作一个具有立方体地形的基本游戏,类似于Minecraft经典。我的第一个问题:

如何在VBO中存储多维数据集列表,然后在更改数据时重建列表?我目前正在渲染这样的立方体:

vertices = BufferUtils.createFloatBuffer(3 * 4 * 6);
    vertices.put(new float[] {
            -1.0f, -1.0f, 1.0f,
            1.0f, -1.0f, 1.0f,
            1.0f, 1.0f, 1.0f,
            -1.0f, 1.0f, 1.0f,

            -1.0f, -1.0f, -1.0f,
            -1.0f, 1.0f, -1.0f,
            1.0f, 1.0f, -1.0f,
            1.0f, -1.0f, -1.0f,

            -1.0f, 1.0f, -1.0f,
            -1.0f, 1.0f, 1.0f,
            1.0f, 1.0f, 1.0f,
            1.0f, 1.0f, -1.0f,

            -1.0f, -1.0f, -1.0f,
            1.0f, -1.0f, -1.0f,
            1.0f, -1.0f, 1.0f,
            -1.0f, -1.0f, 1.0f,

            1.0f, -1.0f, -1.0f,
            1.0f, 1.0f, -1.0f,
            1.0f, 1.0f, 1.0f,
            1.0f, -1.0f, 1.0f,

            -1.0f, -1.0f, -1.0f,
            -1.0f, -1.0f, 1.0f,
            -1.0f, 1.0f, 1.0f,
            -1.0f, 1.0f, -1.0f});
    vertices.rewind();

    vertexBufferID = createVBOID();
    bufferData(vertexBufferID, vertices);

         public static int createVBOID() {
        if (GLContext.getCapabilities().GL_ARB_vertex_buffer_object) {
            IntBuffer buffer = BufferUtils.createIntBuffer(1);
            ARBVertexBufferObject.glGenBuffersARB(buffer);
            return buffer.get(0);
        }
        return 0;
    }

 public static void bufferData(int id, FloatBuffer buffer) {
        ARBVertexBufferObject.glBindBufferARB(ARBVertexBufferObject.GL_ARRAY_BUFFER_ARB, id);
        ARBVertexBufferObject.glBufferDataARB(ARBVertexBufferObject.GL_ARRAY_BUFFER_ARB, buffer, ARBVertexBufferObject.GL_DYNAMIC_DRAW_ARB);
    } 

public void renderGL() {
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glClearColor(0.0f, 0.0f, 0.0f, 0.5f);
    glViewport(0, 0, Display.getWidth(), Display.getHeight());
    glLoadIdentity();

    glRotatef(xrot, 1.0f, 0.0f, 0.0f);
    glRotatef(yrot, 0.f, 1.0f, 0.0f);
    glTranslated(-xpos, -ypos - 19, -zpos - 5);

    glEnableClientState(GL_VERTEX_ARRAY);
    ARBVertexBufferObject.glBindBufferARB(ARBVertexBufferObject.GL_ARRAY_BUFFER_ARB, vertexBufferID);
    glVertexPointer(3, GL_FLOAT, 0, 0);

    for (int y = 0; y < 16; y++) {
        for (int x = 0; x < 16; x++) {
            for (int z = 0; z < 16; z++) {
                glPushMatrix();
                glTranslatef(x, y, z);
                glDrawArrays(GL_QUADS, 0, 24);
                glPopMatrix();
            }
        }

    }
    glDisableClientState(GL_VERTEX_ARRAY);
}

我知道我需要使用glMapBufferglUnMapBuffer来修改VBO,但是如何存储多维数据集并在需要时删除它们?我应该使用ArrayList吗?另外,我被告知我渲染立方体的方法是错误的,因为每个人都说我只用新坐标渲染一个立方体。他们说我的顶点数据保持不变,它们的含义是什么?

基本上我的问题是, 1.如何使用数组来保存多维数据集列表并将其加载到VBO中,然后删除一些多维数据集? 2.如何更改顶点数据,以便渲染不同的多维数据集,而不是一遍又一遍?

2 个答案:

答案 0 :(得分:0)

  1. as antonijn写道,你可以将1个立方体作为VBO并翻译其模型视图矩阵
    • 翻译有时较慢(当立方体太多时)。
    • 甚至可以在着色器内通过一些均匀的偏移来完成平移,这种偏移比矩阵平移稍微快一点
  2. 更快的方法是在VBO中拥有所有多维数据集
    • 它浪费了记忆,但立方体不是那么大(仅6面)
  3. 我会将多维数据集永久存储在CPU可访问的内存中
    • 当场景更改时将其复制到VBO进行渲染。
    • 不要在CPU&lt; - &gt; GPU之间转发和转发数据
    • 仅将数据从CPU复制到GPU。
  4. 最好使用非索引的VBO(drawarrays不是drawelements)
    • 索引不是很好支持
    • 通常会减慢甚至在坏车手上崩溃的事情
  5. 代码查看:https://stackoverflow.com/a/18672821/2521214 但该帖子使用VAO + VBO用于GLSL目的,因此如果您不使用GLSL,则需要进行一些更改。

答案 1 :(得分:-1)

大多数情况下,你有一个场景的CPU表示(在你的情况下是一个立方体列表)和一个GPU表示(它是顶点缓冲区等)。

在您的情况下,立方体仅由其位置定义。它们都具有相同的尺寸等等。以下是一些如何渲染多个立方体的选项:

  1. 在顶点着色器中定义一个统一的位置变量,并将其添加到顶点位置。如果不使用着色器,请在模型视图矩阵中将偏移指定为平移矩阵。使用不同的矩阵/偏移数次渲染相同的顶点缓冲区。

  2. 让GPU在其几何着色器中创建立方体。因此,您只需在顶点缓冲区中指定立方体的位置。映射顶点缓冲区时,您将获得指向可以将新数据复制到的数据的指针。

  3. 使用实例化。为着色器提供一组位置,并以实例模式渲染多维数据集。使用实例ID确定偏移向量。