// aaaarrgghhh!!! meshes are horrible!!! struct spheredef { LPDIRECT3DVERTEXBUFFER9 vb; LPDIRECT3DINDEXBUFFER9 ib; int numverts; int numindexes; }; spheredef sd_Jupiter; spheredef sd_Sattelite; HRESULT D3D_BuildSphere (spheredef *sd, int slices, int stacks, float radius) { HRESULT hr = S_OK; // prevent overflowing the index buffer while (slices * stacks * 6 > 65534) { slices--; stacks--; } float drho = D3DX_PI / (float) stacks; float dtheta = (D3DX_PI / (float) slices) * 2.0f; float ds = 1.0f / (float) slices; float dt = 1.0f / (float) stacks; float t = 1.0f; float s = 0.0f; hr = d3d_Device->CreateVertexBuffer ( sizeof (float) * 8 * stacks * (slices + 1) * 2, 0, 0, D3DPOOL_MANAGED, &sd->vb, NULL ); if (FAILED (hr)) return hr; hr = d3d_Device->CreateIndexBuffer ( sizeof (unsigned short) * slices * stacks * 6, 0, D3DFMT_INDEX16, D3DPOOL_MANAGED, &sd->ib, NULL ); if (FAILED (hr)) return hr; float *sv = NULL; unsigned short *ndx = NULL; sd->vb->Lock (0, 0, (void **) &sv, 0); sd->ib->Lock (0, 0, (void **) &ndx, 0); sd->numindexes = 0; sd->numverts = 0; int stripverts = (slices + 1) * 2; for (int i = 0; i < stacks; i++, t -= dt, sd->numverts += stripverts) { float rho = (float) i * drho; float srho = (float) (sin (rho)); float crho = (float) (cos (rho)); float srhodrho = (float) (sin (rho + drho)); float crhodrho = (float) (cos (rho + drho)); s = 0.0f; // each of these is a triangle strip for (int j = 0; j <= slices; j++, s += ds, sv += 16) { float theta = (j == slices) ? 0.0f : j * dtheta; float stheta = (float) (-sin (theta)); float ctheta = (float) (cos (theta)); sv[0] = stheta * srho * radius; sv[1] = ctheta * srho * radius; sv[2] = crho * radius; sv[3] = stheta * srho; sv[4] = ctheta * srho; sv[5] = crho; VectorNormalize (&sv[3]); sv[6] = s; sv[7] = t; sv[8] = stheta * srhodrho * radius; sv[9] = ctheta * srhodrho * radius; sv[10] = crhodrho * radius; sv[11] = stheta * srhodrho; sv[12] = ctheta * srhodrho; sv[13] = crhodrho; VectorNormalize (&sv[3]); sv[14] = s; sv[15] = (t - dt); } // and unwind the strip into it's component indexes for (int j = 2; j < stripverts; j++, ndx += 3, sd->numindexes += 3) { ndx[0] = sd->numverts + j - 2; if (j & 1) { ndx[1] = sd->numverts + j; ndx[2] = sd->numverts + j - 1; } else { ndx[1] = sd->numverts + j - 1; ndx[2] = sd->numverts + j; } } } sd->vb->Unlock (); sd->ib->Unlock (); return S_OK; } void D3D_DestroySphere (spheredef *sd) { if (sd->ib) { sd->ib->Release (); sd->ib = NULL; } if (sd->vb) { sd->vb->Release (); sd->vb = NULL; } }