我正尝试在 OpenGL 中为我的项目实现光能传递。首先,我需要能够绘制一个平面(代表墙壁)。然后能够使用一种方法将该平面 segmentation 为该平面内的小块或更小的四边形。
困难在于当我绘制另一个平原(另一面墙)时,如果高度和宽度不相同,则顶点未对齐,从而创建我想要避免的 T 顶点。
我在想类似的事情
void drawPlaneMethod(float width, float height, int numberOfSubDivisions) {}
但是我可能需要使用比率或相关的东西。我不关心 Z 轴坐标,因为我可以在构建平面后旋转它们。高度和宽度上的 segmentation 数量必须与另一面墙成比例。
如果这不可能,那么我可以通过使用相同高度和宽度的平面来做到这一点,但是它看起来不切实际,因为我最终得到了一个高天花板。如果不仔细创建许多平面来代表一堵墙,我就无法制作 window 和门。
然后我必须面对另一个问题,即能够在每个补丁上存储信息,例如颜色、光能传递值等。我正在考虑使用对象数组(补丁)并表示平面索引来访问补丁对象。由于我不太擅长使用 C++,我发现很难使用任何类型的数组(我猜二维数组是理想的)。
对这个问题有什么见解吗?
PS:我正在使用 glBegin(GL_QUADS),一旦我完成了我的项目的基础知识,我可以稍后更改为 VBO。
最佳答案
通常,您会希望在 3D 建模应用程序中创建更复杂的几何体( window 、门、楼梯),然后将其导出并导入到您的应用程序中。
如果您以这种方式构建几何体,您还可以强制所有平面/四边形的所有边都连接起来 - 当您将它们全部平均划分为相同数量的面时,新顶点自然会在边处相交:
假设您有一个带有一些基本算术运算符的 3D vector 类...
using Position3 = std::array<float, 3>; //math operators left as excercise :)
您可以将一个平面/四边形简单地表示为其 4 个顶点位置的数组...
using Plane = std::array<Position3, 4>;
假设顶点按逆时针顺序排列。 如果我们想将一个四边形 segmentation 为四个四边形,我们将需要 5 个新顶点,我们称它们为 p1 到 5:
这些并不难计算:
Position3 e1 = plane[1] - plane[0];
Position3 e2 = plane[2] - plane[3];
Position3 e3 = plane[3] - plane[0];
Position3 e4 = plane[2] - plane[1];
Position3 p1 = e1 * 0.5f + plane[0];
Position3 p2 = e2 * 0.5f + plane[3];
Position3 p3 = e3 * 0.5f + plane[0];
Position3 p4 = e4 * 0.5f + plane[1];
Position3 e5 = p2 - p1;
Position3 p5 = e5 * 0.5f + p1;
从这些和我们原来的顶点我们可以构建 4 个新的四边形:
{{ plane[0], p1, p5, p3 },
{ p1, plane[1], p4, p5 },
{ p5, p4, plane[2], p2 },
{ p3, p5, p2, plane[3] }}
现在,通过一个简单的递归函数,我们可以将任何平面四边形分成 4、16、64……更小的四边形。
如果您还希望能够将其划分为 NxN 个较小的四边形,则需要计算每条边上的 N-1 个点,例如对于 3x3 e1 * 1/3
,e1 * 2/3
等等。迭代方法在那里可能会更容易,如果需要,您甚至可以在几何着色器中实现它。
这是在四边形上运行我的小示例算法 (full source here) 的结果:
如果您尝试在 GPU 上实现光能传递,如果您使用 hardware tesselation,您可能甚至不必自己实现任何这些.
关于c++ - OpenGL C++ Plain Subdivison in QUADS (Radiosity) patches on arrays,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19780788/