tags:

views:

297

answers:

2

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.

+5  A: 

You could use the D3DXCreateSphere function.

GMan
So I've done this and I feel that it was working (in blind faith), however, it would not have a texture to it, correct? Upon the flurry of other things being displayed at the same time, I do not see anything. Can I add a texture to this? Or how can I ensure that it has dispalyed correctly?
4501
I'm not sure if `D3DXCreateSphere` generates texture coordinates. There is a tutorial here [1] that demonstrates how to do so. [1] http://www.mvps.org/directx/articles/spheremap.htm
GMan
I think that regardless I'm gonna run into problems with the CreateSphere function going into that fail-if statement, no?
4501
Actually, I think if it returns 0 then it succeeded. Try using the `FAILED` macro. (Or: `if (/* create sphere */ != D3D_OK)`
GMan
You're correct, I've checked the HRESULT and it seems to have succeeded. Not sure why it followed into that loop then. Cool, thanks! I'll keep doing my research with it :)
4501
+4  A: 

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.

Goz
My apologies, this is my first time doing this type of programming. You're throwing around a lot of math that I simply do not understand, could you possibly elaborate a bit?
4501
what would you like me to elaborate upon?
Goz