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