数组中QUADS(Radiosity)补丁中的OpenGL C ++ Plain Subdivision

时间:2013-11-05 02:04:55

标签: c++ opengl

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

当我绘制另一个平面(另一面墙)时,如果高度和宽度不相同,顶点没有对齐,创建我想要避免的T顶点,则难以绘制它们。

我在想像

这样的东西
void drawPlaneMethod(float width, float height, int numberOfSubDivisions) {}

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

如果这是不可能的,那么我可以通过使用相同高度和宽度的平面来做到这一点,但是当我结束高度的天花板时它看起来不切实际。而且我不能制造窗户,门而不必仔细地创造许多飞机来代表一面墙。

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

对此问题的任何见解?

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

1 个答案:

答案 0 :(得分:3)

通常,您需要在3D建模应用程序中创建更复杂的几何体(窗户,门,楼梯),从那里导出并将其导入您的应用程序。

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

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

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

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

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

假设顶点是逆时针顺序。 如果我们想将四边形细分为四个四边形,我们将需要5个新顶点,让我们称它们为p1到5:

excuse my paint skills

这些不难计算:

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个点,例如:适用于e1 * 1/3e1 * 2/3的3x3,依此类推。迭代方法在那里可能会更容易,如果需要,甚至可以在几何着色器中实现它。

这是在quad上运行我的小示例算法(full source here)的结果:

如果您尝试在GPU上实现光能传递,如果使用hardware tesselation,您甚至可能不必自己实施任何光能传递。