使用 Direct x 创建球形网格?

发布于 2024-08-11 04:59:54 字数 103 浏览 3 评论 0原文

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

当前所有内容都是通过 IDiRECT3DDEVICE9 对象渲染的。

How do you go about creating a sphere with meshes in Direct-x? I'm using C++ and the program will be run on windows, only.

Everything is currently rendered through an IDiRECT3DDEVICE9 object.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

孤星 2024-08-18 04:59:54

您可以使用 D3DXCreateSphere 函数。

You could use the D3DXCreateSphere function.

痴情换悲伤 2024-08-18 04:59:54

创建球体的方法有很多种。

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

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 个新的四边形,依此类推,直到达到所需的细化级别。

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

There are lots of ways to create a sphere.

One is to use polar coordinates to generate slices of the sphere.

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

Given that struct you'd generate the sphere as follows (I haven't tested this so I may have got it slightly wrong).

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++;
}

This is how D3DXCreateSphere does it i believe. Of course the code above does not form the faces but thats not a particularly complex bit of code if you set your mind to it :)

The other, and more interesting in my opinion, way is through surface subdivision.

If you start with a cube that has normals defined the same way as the above code you can recursively subdivide each side. Basically you find the center of the face. Generate a vector from the center to the new point. Normalise it. Push the vert out to the radius of the sphere as follows (Assuming v.n* is the normalised normal):

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

You then repeat this process for the mid point of each edge of the face you are subdividing.

Now you can split each face into 4 new quadrilateral faces. You can then subdivide each of those quads into 4 new quads and so on until you get to the refinement level you require.

Personally I find this process provides a nicer vertex distribution on the sphere than the first method.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文