0

我正在尝试为我的项目在 OpenGL 中实现 Radiosity。首先,我需要能够绘制一个平面(代表墙壁)。然后能够通过使用一种方法将该平面细分为该平面内的补丁或较小的四边形。

困难是在我绘制另一个平原(另一面墙)时以某种方式绘制它们,如果高度和宽度不同,则顶点未对齐创建我想避免的 T 顶点。

我在想类似的东西

void drawPlaneMethod(float width, float height, int numberOfSubDivisions) {}

但是我可能需要使用比率或相关的东西。我不关心 Z 轴坐标,因为我可以在构建平面后旋转它们。高度和宽度上的细分数量必须与另一面墙成比例。

如果这是不可能的,那么我可以通过使用相同高度和宽度的平面来做到这一点,但是它看起来不切实际,因为我最终得到了一个高天花板。我不能制作窗户和门,而不必仔细创建许多平面来代表一堵墙。

然后我必须面对另一个问题,即能够在每个补丁上存储信息,例如颜色、光能传递值等。我正在考虑使用对象数组(补丁)并表示平面索引来访问补丁对象。由于我对 c++ 不是很好,我发现很难使用任何类型的数组(我猜二维数组是理想的)。

对这个问题有任何见解吗?

PS:我正在使用 glBegin(GL_QUADS),一旦我完成了项目的基础知识,我可以稍后为 VBO 进行更改。

4

1 回答 1

4

通常,您会希望在 3D 建模应用程序中创建更复杂的几何图形(窗户、门、楼梯),然后从那里导出并将其导入您的应用程序。

如果您以这种方式构建几何图形,您还可以强制所有平面/四边形的所有边都连接 - 当您将它们全部均匀地划分为相同数量的面时,新顶点将自然地在边处相遇:

假设您有一个带有一些基本算术运算符的 3D 矢量类......

using Position3 = std::array<float, 3>; //math operators left as excercise :)

您可以将平面/四边形简单地表示为其 4 个顶点位置的数组...

using Plane = std::array<Position3, 4>;

假设顶点按逆时针顺序排列。如果我们想将一个四边形细分为四个四边形,我们将需要 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/3e1 * 2/3依此类推。迭代方法可能会更容易,如果你愿意,你甚至可以在几何着色器中实现它。

这是在四边形上 运行我的小示例算法(此处为完整源代码)的结果:

但是,如果您尝试在 GPU 上实现光能传递,如果您使用硬件镶嵌,您甚至可能不必自己实现任何这些。

于 2013-11-05T03:23:38.120 回答