0

我目前正在尝试制作一个具有立方体地形的基本游戏,类似于 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. 我怎样才能改变我的顶点数据,以便我渲染不同的立方体,而不是一遍又一遍地渲染一个立方体?

4

2 回答 2

0
  1. 正如 antonijn 所写,您可以将 1 个立方体作为 VBO 并转换其模型视图矩阵
    • 翻译有时较慢(当立方体太多时)。
    • 翻译甚至可以在着色器内部通过一些统一的偏移量来完成,这比矩阵翻译快一点
  2. 更快的方法是在 VBO 中拥有所有的立方体
    • 它浪费内存,但立方体没有那么大(仅限 6 个面)
  3. 我会将多维数据集永久存储在 CPU 可访问内存中
    • 当场景更改时,将其复制到 VBO 进行渲染。
    • 不要在 CPU<->GPU 之间来回传输数据
    • 仅将数据从 CPU 复制到 GPU。
  4. 也最好使用非索引 VBO(drawarrays 不是 drawelements)
    • 索引不是很好支持
    • 经常会减慢速度,甚至在坏驱动程序上崩溃

代码请看这里:https ://stackoverflow.com/a/18672821/2521214 但该帖子使用 VAO+VBO 用于 GLSL 目的,因此如果您不使用 GLSL,则需要进行一些更改。

于 2013-09-13T15:19:37.777 回答
-1

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

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

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

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

  3. 使用实例化。为着色器提供一组位置并以实例化模式渲染立方体。使用实例 id 来确定偏移向量。

于 2013-02-03T22:00:23.340 回答