#pragma once #include #include #include #define L4VERTEX_FVF (D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_DIFFUSE | D3DFVF_NORMAL) #define L4POINTVERTEX_FVF (D3DFVF_XYZ) #define L4VERTEX_2D_FVF (D3DFVF_XYZRHW | D3DFVF_DIFFUSE) #define L4VERTEX_2D_TEX_FVF (D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_TEX1) #define PASS_OPAQUE 0 #define PASS_DECAL 1 #define PASS_ALPHABLEND 2 #define PASS_SPHERE 3 #define PASS_SKY 4 #define PASS_TOTAL_COUNT 5 struct L4VERTEX { float x, y, z; float nx, ny, nz; DWORD color; float u, v; }; struct L4POINTVERTEX { float x, y, z; }; struct L4VERTEX_2D { float x, y, z, rhw; DWORD color; }; struct L4VERTEX_2D_TEX { float x, y, z, rhw; DWORD color; float u, v; }; struct L4TEXOP { enum WrapType { REPEAT, CLAMP, SELECT } wrap_u, wrap_v; LPDIRECT3DTEXTURE9 texture; bool doScroll; float scrollUDelta; float scrollVDelta; }; struct L4RAMP { float r0, g0, b0; float r1, g1, b1; }; struct L4DRAWOP { D3DMATERIAL9 material; L4TEXOP texture; bool alphaTest; bool drawAsDecal; bool drawAsSky; }; class d3d_OBJECT { public: d3d_OBJECT(LPDIRECT3DDEVICE9 device, int vertCount); d3d_OBJECT(LPDIRECT3DDEVICE9 device, LPD3DXMESH mesh, DWORD *adjacencyBuffer, int drawOpCount); ~d3d_OBJECT(); inline LPDIRECT3DDEVICE9 GetDevice() { return mDevice; } inline int GetVertCount() { return mVertCount; } inline int GetDrawOpCount() { return mDrawOpCount; } inline L4DRAWOP* GetDrawOp(int index) { return &(mDrawOps[index]); } void Draw(int pass, const D3DXMATRIX *viewTransform, Time targetRenderFrame); inline void SetRadius(float radius) { mRadius = radius; } inline void SetOrigin(L4POINTVERTEX origin) { mOrigin = origin; } inline void SetImmune(bool immune) { mImmune = immune; } inline void SetLocalToWorld(D3DXMATRIX localToWorld) { mLocalToWorld = localToWorld; } inline float GetRadius() { return mRadius; } inline L4POINTVERTEX GetOrigin() { return mOrigin; } inline bool GetImmune() { return mImmune; } inline D3DXMATRIX GetLocalToWorld() { return mLocalToWorld; } inline LPD3DXMESH GetMesh() { return mMesh; } inline d3d_OBJECT* GetNext(int pass) { return mNext[pass + 1]; } inline d3d_OBJECT* GetPrevious( int pass) { return mPrev[pass + 1]; } inline void SetNext(d3d_OBJECT *next, int pass) { mNext[pass + 1] = next; } inline void SetPrevious(d3d_OBJECT *previous, int pass) { mPrev[pass + 1] = previous; } static void ResetState(LPDIRECT3DDEVICE9 device); static d3d_OBJECT* LoadObject(LPDIRECT3DDEVICE9 device, char *fileName); static L4TEXOP LoadTexture(LPDIRECT3DDEVICE9 device, const char *fileName); private: static d3d_OBJECT* LoadSpheres(LPDIRECT3DDEVICE9 device, char *fileName); LPDIRECT3DDEVICE9 mDevice; inline void SetVB(LPDIRECT3DVERTEXBUFFER9 buffer) { mVB = buffer; } void DrawMesh(int pass, const D3DXMATRIX *viewTransform, Time targetRenderFrame); void DrawSpheres(int pass, const D3DXMATRIX *viewTransform); long mID; // vertex based int mVertCount; LPDIRECT3DVERTEXBUFFER9 mVB; // mesh based LPD3DXMESH mMesh; int mDrawOpCount; L4DRAWOP* mDrawOps; bool mImmune; D3DXMATRIX mLocalToWorld; L4POINTVERTEX mOrigin; float mRadius; d3d_OBJECT *mNext[PASS_TOTAL_COUNT + 1]; d3d_OBJECT *mPrev[PASS_TOTAL_COUNT + 1]; void SetTextureScrolling(const L4TEXOP *texture, Time targetRenderFrame); void SetTextureAddressing(L4TEXOP::WrapType wrap_u, L4TEXOP::WrapType wrap_v); void SetTexture(LPDIRECT3DTEXTURE9 texture); // state information for optimizing renderstate changes static bool mLastTextureScrollState; static L4TEXOP::WrapType mLastWrapU; static L4TEXOP::WrapType mLastWrapV; static bool mLastTexturingState; static long mNextID; static stdext::hash_map< std::string , L4TEXOP > mTextureCache; }; extern int gNumBatches;