代码之家  ›  专栏  ›  技术社区  ›  user189327

用直接X创建球面网格?

  •  2
  • user189327  · 技术社区  · 15 年前

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

    所有内容当前都是通过IDirect3dDevice9对象呈现的。

    2 回复  |  直到 15 年前
        1
  •  6
  •   GManNickG    15 年前

    你可以用 D3DXCreateSphere 功能。

        2
  •  5
  •   Goz    15 年前

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

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

    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的工作方式。当然,上面的代码并不能构成人脸,但是如果你下定决心的话,那就不是一个特别复杂的代码了。)

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

    如果您从一个具有与上述代码定义相同的法线的多维数据集开始,您可以递归地细分每一侧。基本上你可以找到脸部的中心。生成从中心到新点的向量。正常化。将顶点向外推到球体的半径,如下所示(假设v.n*是标准化的法线):

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

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

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

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