在本书的示例代码中"introduction to 3d game programming with directx 11"
In an example code of the book "introduction to 3d game programming with directx 11"
void GeometryGenerator::Subdivide(MeshData& meshData)
{
// Save a copy of the input geometry.
MeshData inputCopy = meshData;
meshData.Vertices.resize(0);
meshData.Indices.resize(0);
// v1
// *
// /
// /
// m0*-----*m1
// / /
// / /
// *-----*-----*
// v0 m2 v2
UINT numTris = inputCopy.Indices.size()/3;
for(UINT i = 0; i < numTris; ++i)
{
Vertex v0 = inputCopy.Vertices[ inputCopy.Indices[i*3+0] ];
Vertex v1 = inputCopy.Vertices[ inputCopy.Indices[i*3+1] ];
Vertex v2 = inputCopy.Vertices[ inputCopy.Indices[i*3+2] ];
//
// Generate the midpoints.
//
Vertex m0, m1, m2;
// For subdivision, we just care about the position component. We
// derive the other
// vertex components in CreateGeosphere.
m0.Position = XMFLOAT3(
0.5f*(v0.Position.x + v1.Position.x),
0.5f*(v0.Position.y + v1.Position.y),
0.5f*(v0.Position.z + v1.Position.z));
m1.Position = XMFLOAT3(
0.5f*(v1.Position.x + v2.Position.x),
0.5f*(v1.Position.y + v2.Position.y),
0.5f*(v1.Position.z + v2.Position.z));
m2.Position = XMFLOAT3(
0.5f*(v0.Position.x + v2.Position.x),
0.5f*(v0.Position.y + v2.Position.y),
0.5f*(v0.Position.z + v2.Position.z));
//
// Add new geometry.
//
meshData.Vertices.push_back(v0); // 0
meshData.Vertices.push_back(v1); // 1
meshData.Vertices.push_back(v2); // 2
meshData.Vertices.push_back(m0); // 3
meshData.Vertices.push_back(m1); // 4
meshData.Vertices.push_back(m2); // 5
meshData.Indices.push_back(i*6+0);
meshData.Indices.push_back(i*6+3);
meshData.Indices.push_back(i*6+5);
meshData.Indices.push_back(i*6+3);
meshData.Indices.push_back(i*6+4);
meshData.Indices.push_back(i*6+5);
meshData.Indices.push_back(i*6+5);
meshData.Indices.push_back(i*6+4);
meshData.Indices.push_back(i*6+2);
meshData.Indices.push_back(i*6+3);
meshData.Indices.push_back(i*6+1);
meshData.Indices.push_back(i*6+4);
}
}
此函数位于"GeometryGenerator.cpp"文件中,可以细分网格。在调用此函数之前,将创建一个二十面体,并将其作为参数meshData进行传输。MeshData的成员"顶点"answers"索引"是STL的向量。
在我看来,在这个函数调用那些系列的函数meshData.Vertices.push_back之后,在循环的下一次迭代中,一些顶点可能会被重复存储。
任何人都可以回答
- 是否我错了
- 为什么作者编写这样的代码
- 或者如果我的想法是正确的,是否有更有效的方法
感谢所有读到我糟糕英语的人。
我是否错了
我很确定你是对的,尤其是关于重复顶点!
为什么作者制作这样的代码
除了作者自己,没有人能回答这个问题。我猜他/她只是监督了重复问题。。。
或者如果我的想法是正确的,是否有更有效的方法。
只要算法不正确,我就不在乎效率!
首先,我们需要避免顶点重复。我只是将现有的顶点保持原样(因此只有clear
索引),并在末尾添加新的顶点。为此,我将边存储在一个临时std::映射中,将一对索引(边)映射到新创建的索引(总是先使用较小的索引,以避免(10,12)
与(12,10)
的问题,后者标识相同的边…)。
然后对于v0,v1,v2,我会使用索引,而不是顶点本身。m0、m1、m2首先在地图中查找,如果找到,则使用,否则,创建一个新的顶点,将其添加到顶点向量中,并在地图中添加一个条目。
UINT v0 = copiedIndices[i*3+0];
// ...
UINT m0;
auto key = std::make_pair(v0, v1); // TODO: order indices!!!
auto entry = myMap.find(key);
if(entry != myMap.end())
{
m0 = entry->second;
}
else
{
meshData.Vertices.push_back(newVertex);
m0 = meshData.Vertices.size() - 1;
myMap.insert(key, m0);
}
然后你将添加你的新三角形,只需按如下索引:
meshdata.indices.pushback(v0); // one of the original indices
meshdata.indices.pushback(m0); // one of the new ones
meshdata.indices.pushback(m2);
// ...
- 如果有另一个三角形与v1-v2边相邻,则v1、v2和m1将相加两次,依此类推
- 谁知道呢?也许在这之后会有一个额外的重复数据消除过程
- 可以使用几何体着色器或直线镶嵌在GPU上执行此操作。请参见此示例
相关文章:
- 无法将结构注册为增强几何体3D点
- OpenGL大的3D纹理(>2GB)非常慢
- 是什么导致了Unity 3D中的"错误线程异常"?
- 如何声明一个可以在整个程序中使用的全局 2d 3d 4d .. 数组(堆版本)变量?
- CPU 瓶颈;处理具有许多非静态对象的 3D 场景渲染的简单方法
- 如何使用Qt 3D库加载和显示搅拌机.obj源文件场景
- 如何从 3D 曲面网格中删除自相交三角形?
- CUDA 使用共享内存平铺 3D 卷积实现
- 检查框内的 3D 点
- 如何在 3D OpenGL 场景上绘制 SDL 2D 矩形?
- Frank Luna 在他的书"使用 DirectX12 进行 3D 游戏编程"的介绍中盒子示例的问题
- 使用 C++在 OpenGL 中对 3D 多边形进行纹理处理
- 使用 C++在 OpenGL 中移动自动旋转的 3D 多边形
- 是否可以使用 DirectX 3D 11 绘制由三角形组成的圆?
- 如何使用条件计算 3D 网格中从一个点到另一个点的所有路径
- 在 OpenGL 中使用键盘移动 3D 形状,C++
- 是否可以制作没有内部分割的cgal 3d多多马因网格?
- 我想通过OpenGL创建3D金字塔
- 如何在C++中仅使用迭代器正确迭代 3D 向量?
- 在本书的示例代码中"introduction to 3d game programming with directx 11"