VBO生成块的vert(体素引擎,Cpp)
VBO Generate Verts for Chunks (Voxel Engine, Cpp)
我正在制作体素引擎,我正在使用VBO。我的问题是我不知道如何生成顶点。
我需要为一个块生成顶点,所以从X,Y,Z坐标创建一个立方体块(带有一个VBO)。
我该怎么做?
首先你需要为体素创建/加载数据。下面的代码可以用来生成一个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
相关文章:
- .cpp和.h文件中的模板专用化声明
- 为什么两个不同的未命名名称空间可以共存于一个cpp文件中
- Linux的Cpp上的计时器
- 如何运行位于boost/libs/python/example/tutorial目录中的hello.cpp和Jamfil
- 命名空间中具有.h和.cpp文件的类
- 内置函数可查看CPP中的成员变量
- 无法编译 rtmidi 测试 cmidiin.cpp 文件, 非法指令
- Cpp-Tuple使用带有变量的get
- C++-试图将函数指针推回到另一个CPP文件中的矢量时出错
- 有充分的理由在h文件中使用include保护而不是cpp文件吗
- 如何通过cpp程序运行shell脚本
- 使用2个键的cpp-stl::优先级队列排序不正确
- cpp二进制搜索问题,计算给定数组中输入元素的出现次数
- 如何在cpp文件之间切换窗口?在Qt中
- 当使用带有VS2019或VSCode的虚幻引擎4.24.2时,我如何修复这些错误的Intellisense错误
- 在 .h 文件中的类中声明静态变量和在.cpp文件中声明"global"变量有什么区别
- Unity在虚幻引擎4中的"Vector3.Slerp"等效C++?
- 我需要知道编译器如何在cpp中使用析构函数
- 光子引擎原生 OSX cpp SDK 4.1.5
- VBO生成块的vert(体素引擎,Cpp)