【问题标题】:VBO Generate Verts for Chunks (Voxel Engine, Cpp)VBO 为块生成顶点(体素引擎,Cpp)
【发布时间】:2014-05-02 11:38:31
【问题描述】:

我正在开发体素引擎,并且正在使用 VBO。 我的问题是我不知道如何生成顶点。

我需要为一个块生成顶点,所以从 X、Y、Z 坐标创建一个立方体块(带有一个 VBO)。

我该怎么做?

【问题讨论】:

  • 您可能想看看行进立方体或类似的东西。你在使用 OpenGL 吗?另外,你是否已经为chunk生成了数据,如果有,这个数据是什么格式的?
  • 我正在使用 OpenGL 并且从未为块生成任何数据,我对 VBO 非常陌生。 :)
  • 只是为了澄清VBO(Vertex Buffer Object)与生成顶点无关。 VBO 只是存储。不是每次绘制调用都发送顶点数据,而是将其存储在 VBO 中。然后您只需将顶点数据从 CPU 空间传输到 GPU 空间一次,而不是每次绘制调用。
  • 我知道,但我不知道如何为 VBO 生成顶点:/
  • 没有人??我还是没弄明白:/

标签: c++ vbo voxel


【解决方案1】:

首先,您需要为体素创建/加载数据。像下面这样的东西可以用来生成一个 10x10x10 的二进制体素字段:

注意:所有代码都未经测试,可能不是最优的。

class Field {
    bool data[10*10*10];
public:
    bool& at(int i, int j, int k) { return data[i*10*10 + j*10 + k]; }
};


Field aField;
for (int i = 0; i < 10; ++i) {
    for (int j = 0; j < 10; ++j) {
        for (int k = 0; k < 10; ++k) {
            aField.at(i, j, k) = !(rand() % 2);
        }
    }
}

我假设你在使用 Minecraft 风格的体素,否则你可能想使用Marching Cubes 之类的东西来处理二进制体素字段并将结果传递给顶点缓冲区代码。

下一步是为字段中的每个占用体素绘制与立方体相关联的面。为此,我们需要创建所有顶点和(在本例中)三角形索引的列表。

std::vector< std::array<GLfloat, 3> > vecVerts;
std::vector< std::array<GLuint, 3> > vecTris;
for (int i,j,k from 0 to 10) {
    if (aField.at(i,j,k)) {
        // Add vertices for eight corners of cube
        vecVerts.emplace_back(dWidth*(i  ), dWidth*(j  ), dWidth*(k  ));
        vecVerts.emplace_back(dWidth*(i+1), dWidth*(j  ), dWidth*(k  ));
        vecVerts.emplace_back(dWidth*(i  ), dWidth*(j+1), dWidth*(k  ));
        vecVerts.emplace_back(dWidth*(i+1), dWidth*(j+1), dWidth*(k  ));
        vecVerts.emplace_back(dWidth*(i  ), dWidth*(j  ), dWidth*(k+1));
        vecVerts.emplace_back(dWidth*(i+1), dWidth*(j  ), dWidth*(k+1));
        vecVerts.emplace_back(dWidth*(i  ), dWidth*(j+1), dWidth*(k+1));
        vecVerts.emplace_back(dWidth*(i+1), dWidth*(j+1), dWidth*(k+1));

        // Add triangle coordinates for each triangle
        vecTris.emplace_back(0, 1, 3); vecTris.emplace_back(0, 2, 3);
        vecTris.emplace_back(4, 5, 7); vecTris.emplace_back(4, 6, 7);
        /* todo: add remaining triangles, should be 8 more */
    }
}

上面的代码将在内存中创建两个数组来存储您的顶点位置和三角形的索引。您会注意到代码总是为每个体素绘制 12 个三角形,最好检查是否存在相邻的被占用体素并删除这些体素之间的面,但我会留给您。我还建议您考虑使用glm::vec3 来存储顶点数据,而不仅仅是一个数组。

我们现在可以将数组传递给 OpenGL:

GLuint unVertexArray;
glGenVertexArrays(1, &unVertexArray);
glBindVertexArray(unVertexArray);

GLuint unVertexBuffer;
glGenBuffers(1, &unVertexBuffer);
glBindBuffer(GL_ARRAY_BUFFER, unVertexBuffer);
glBufferData(GL_ARRAY_BUFFER, 3*vecVerts.size()*sizeof(GLfloat),
    &vecVerts[0][0], GL_STATIC_DRAW);

glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);

GLuint unIndiciesBuffer;
glGenBuffers(1, &unIndicesBuffer);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, unIndicesBuffer);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, 3*vecTris.size()*sizeof(GLuint),
    &vecTris[0][0], GL_STATIC_DRAW);

glBindVertexArray(0);

最后,绘制我们的数组:

glBindVertexArray(unVertexArray);
glDrawElements(GL_TRIANGLES, 3*vecTris.size(), GL_UNSIGNED_INT, NULL);
glBindVertexArray(0);

我可能(几乎可以肯定我)在这里忘记了一些事情,但这应该为您提供您需要做什么的大致轮廓。对于上面使用的大多数gl调用的正确解释,有许多在线参考,例如http://arcsynthesis.org/gltut/index.html

【讨论】:

  • 哇。非常感谢!
猜你喜欢
  • 2015-06-07
  • 1970-01-01
  • 2013-02-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-03-05
  • 2023-03-05
相关资源
最近更新 更多