2

你如何在 Direct-x 中创建一个带有网格的球体?我正在使用 C++,程序只能在 Windows 上运行。

当前所有内容都通过 IDiRECT3DDEVICE9 对象呈现。

4

2 回答 2

6

您可以使用该D3DXCreateSphere功能。

于 2009-11-08T05:16:13.460 回答
6

有很多方法可以创建一个球体。

一种是使用极坐标生成球体切片。

struct Vertex
{
    float x, y, z;
    float nx, ny, nz;
};

鉴于该结构,您将按如下方式生成球体(我没有对此进行测试,所以我可能有点错误)。

std::vector< Vertex > verts;
int count   = 0;
while( count < numSlices )
{
    const float phi = M_PI / numSlices;
    int count2  = 0;
    while( count2 < numSegments )
    {
        const float theta   =  M_2PI / numSegments
        const float xzRadius = fabsf( sphereRadius * cosf( phi ) );

        Vertex v;
        v.x = xzRadius * cosf( theta );
        v.y = sphereRadius * sinf( phi );
        v.z = xzRadius * sinf( theta );

        const float fRcpLen = 1.0f / sqrtf( (v.x * v.x) + (v.y * v.y) + (v.z * v.z) );
        v.nx    = v.x * fRcpLen;
        v.ny    = v.y * fRcpLen;
        v.nz    = v.z * fRcpLen;

            verts.push_back( v );
        count2++;
    }
    count++;
}

我相信这就是 D3DXCreateSphere 的做法。当然,上面的代码不会形成面孔,但如果您下定决心,那并不是特别复杂的代码:)

另一种在我看来更有趣的方法是通过表面细分。

如果您从一个具有与上述代码相同的法线定义的立方体开始,您可以递归地细分每一边。基本上你会找到脸部的中心。生成从中心到新点的向量。规范化它。将顶点向外推到球体的半径,如下所示(假设 vn* 是归一化的法线):

v.x = v.nx * sphereRadius;
v.y = v.ny * sphereRadius;
v.z = v.nz * sphereRadius;

然后,对要细分的面的每条边的中点重复此过程。

现在您可以将每个面拆分为 4 个新的四边形面。然后,您可以将这些四边形中的每一个细分为 4 个新的四边形,依此类推,直到达到所需的细化级别。

就我个人而言,我发现这个过程在球体上提供了比第一种方法更好的顶点分布。

于 2009-11-08T08:23:56.013 回答