Spent the morning tweaking the exporter a little bit and
recovering from the mistakes made yesterday. That darn exporter still isn't
working right. Or maybe it's something in MAX. I ran some experiments running a
mesh from max to 3ds to milshape and back and that whole process seemed to
straighten out my mesh problems. I don't know exactly what in max wonking me up
though. It appears that if I separate an object into parts, then export them as
frames, there's a funny transform at some level that's screwing things up. I
also think that I may have to do some heirarchy modification in max. Maybe
that's it.
Anyways, on to plan b. I created a billboard quad class that we can use to
animate textures. Woohoo. Now we have explosions as a billboarded quad. That'll
change before the final release, but it'll have to do for the demo. For the
final release, we'll probably have the animated sprite, particles, and some ship
pieces. It'll be cool. Trust me 

Sometimes I miss OpenGL. I miss the glPushMatrix() and glPushAttrib(). For point
sprites, we set about 10 attributes. I don't want to have to save off 10 local
vars just to be a nice render state citizen. Also, what happens when a frame in
our list of frames wants to reset one of those states. Ugh.. To this end, I
cobbled up a quick render state manager. Check it out:
// Data type for the pushing and popping.
typedef std::stack<DWORD> DWORDStack;
typedef std::map<D3DRENDERSTATETYPE, DWORDStack> DWORDStackMap;
static DWORDStackMap g_RenderStates;
HRESULT PushRenderState(D3DRENDERSTATETYPE state)
{
DWORD dwVal = 0;
HRESULT hr = g_pDevice->GetRenderState(state, &dwVal);
if(SUCCEEDED(hr))
g_RenderStates[state].push(dwVal);
return hr;
}
HRESULT PopRenderState(D3DRENDERSTATETYPE state)
{
if(!g_RenderStates[state].empty())
{
DWORD dwVal = g_RenderStates[state].top();
g_RenderStates[state].pop();
return g_pDevice->SetRenderState(state, dwVal);
}
return E_INVALIDARG;
}
HRESULT SetRenderState(D3DRENDERSTATETYPE state, DWORD dwVal)
{
return g_pDevice->SetRenderState(state, dwVal);
}
HRESULT PushAndSetRenderState(D3DRENDERSTATETYPE state, DWORD dwNewVal)
{
HRESULT hr = PushRenderState(state);
if(SUCCEEDED(hr))
{
hr = SetRenderState(state, dwNewVal);
}
return hr;
}
That last function is for my convenience 
Look at how clean the point sprite stuff is now...
PushAndSetRenderState(D3DRS_ZENABLE, FALSE);
PushAndSetRenderState(D3DRS_ZWRITEENABLE, FALSE);
PushAndSetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
PushAndSetRenderState(D3DRS_SRCBLEND, D3DBLEND_ONE);
PushAndSetRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE);
PushAndSetRenderState(D3DRS_POINTSPRITEENABLE, TRUE);
PushAndSetRenderState(D3DRS_POINTSCALEENABLE, TRUE);
PushAndSetRenderState(D3DRS_POINTSIZE, FtoDW(1.0f));
PushAndSetRenderState(D3DRS_POINTSIZE_MIN, FtoDW(1.00f));
PushAndSetRenderState(D3DRS_POINTSCALE_A, FtoDW(0.00f));
PushAndSetRenderState(D3DRS_POINTSCALE_B, FtoDW(1.00f));
PushAndSetRenderState(D3DRS_POINTSCALE_C, FtoDW(0.00f));
:
:
PopRenderState(D3DRS_ZENABLE);
PopRenderState(D3DRS_ZWRITEENABLE);
PopRenderState(D3DRS_ALPHABLENDENABLE);
PopRenderState(D3DRS_SRCBLEND);
PopRenderState(D3DRS_DESTBLEND);
PopRenderState(D3DRS_POINTSPRITEENABLE);
PopRenderState(D3DRS_POINTSCALEENABLE);
PopRenderState(D3DRS_POINTSIZE);
PopRenderState(D3DRS_POINTSIZE_MIN);
PopRenderState(D3DRS_POINTSCALE_A);
PopRenderState(D3DRS_POINTSCALE_B);
PopRenderState(D3DRS_POINTSCALE_C);
Now, if only the render states were bit masks like OpenGL's attributes.
I added in the new explosion that Scott gave me it's pretty sweet. I also added
a light to the explosion so that it gives out a yellow light. Check it out...

Well, after basketball, I'm a little pooped. I'll finish some more stuff
tonight. Now that we have the explosion, I'll do more work with the weapons.
I'll probably implement a thick line so that we can do cool animated beam
effects and vapor trails as well as the laser shot Alex wanted.