You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

831 lines
31 KiB

/*==LICENSE==*
CyanWorlds.com Engine - MMOG client, server and tools
Copyright (C) 2011 Cyan Worlds, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
You can contact Cyan Worlds, Inc. by email legal@cyan.com
or by snail mail at:
Cyan Worlds, Inc.
14617 N Newport Hwy
Mead, WA 99021
*==LICENSE==*/
#ifndef _plDX9Pipeline_h
#define _plDX9Pipeline_h
#include "plPipeline.h"
#include "plDXSettings.h"
#include "../plSurface/plLayerInterface.h"
#include "hsMatrix44.h"
#include "plFogEnvironment.h"
#include "hsG3DDeviceSelector.h"
#include "hsGeometry3.h"
#include "hsTemplates.h"
#include "hsColorRGBA.h"
#include "hsGDeviceRef.h"
#include "hsPoint2.h"
class plAccessSpan;
class plAuxSpan;
class plVertexSpan;
#include "plPlates.h" // Used to define plDXPlateManager
//// Defines and Konstants and Other Nifty Stuff //////////////////////////////
class plDXLightRef;
class plDXVertexBufferRef;
class plDXIndexBufferRef;
class plDXTextureRef;
class plDXCubeTextureRef;
class plDXVertexShader;
class plDXPixelShader;
class plShader;
class plVisMgr;
//#define HS_D3D_USE_SPECULAR
class hsGMaterial;
class plMipmap;
class plLightInfo;
class plCullTree;
class plShadowSlave;
class plShadowCaster;
struct D3DXMATRIX;
#ifdef HS_DEBUGGING
#define HS_CHECK_RELEASE
#endif
#ifndef PLASMA_EXTERNAL_RELEASE
#define PROFILE_POOL_MEM(pool, size, add, id) plDXPipeline::ProfilePoolMem(pool, size, add, id);
#else
#define PROFILE_POOL_MEM(pool, size, add, id)
#endif // PLASMA_EXTERNAL_RELEASE
extern void D3DSURF_MEMNEW(IDirect3DSurface9* surf);
extern void D3DSURF_MEMNEW(IDirect3DTexture9* tex);
extern void D3DSURF_MEMNEW(IDirect3DCubeTexture9* cTex);
extern void D3DSURF_MEMDEL(IDirect3DSurface9* surf);
extern void D3DSURF_MEMDEL(IDirect3DTexture9* tex);
extern void D3DSURF_MEMDEL(IDirect3DCubeTexture9* cTex);
extern void plReleaseObject(IUnknown* x);
#define ReleaseObject(x) if(x){ plReleaseObject(x); x=NULL; }
typedef LPDIRECT3D9 (WINAPI * Direct3DCreateProc)( UINT sdkVersion );
//// Helper Classes ///////////////////////////////////////////////////////////
//// The RenderPrimFunc lets you have one function which does a lot of stuff
// around the actual call to render whatever type of primitives you have, instead
// of duplicating everything because the one line to render is different.
class plRenderPrimFunc
{
public:
virtual hsBool RenderPrims() const = 0; // return true on error
};
//// DX-specific Plate Manager implementation
class plDXPlateManager : public plPlateManager
{
friend class plDXPipeline;
public:
virtual ~plDXPlateManager();
protected:
const long PLD3D_PLATEFVF;
struct plPlateVertex
{
hsPoint3 fPoint;
UInt32 fColor;
hsPoint3 fUV;
};
IDirect3DDevice9 *fD3DDevice;
IDirect3DVertexBuffer9 *fVertBuffer;
plDXPlateManager( plDXPipeline *pipe, IDirect3DDevice9 *device );
void ICreateGeometry(plDXPipeline* pipe);
void IReleaseGeometry();
virtual void IDrawToDevice( plPipeline *pipe );
};
//// Class Definition /////////////////////////////////////////////////////////
class plDebugTextManager;
struct D3DEnum_DriverInfo;
struct D3DEnum_DeviceInfo;
struct D3DEnum_ModeInfo;
class plGeometrySpan;
class plDrawableSpans;
class plSpan;
class plIcicle;
class hsG3DDeviceModeRecord;
class plDXDeviceRef;
class plParticleSpan;
class plCubicEnvironmap;
class plDXRenderTargetRef;
class plStatusLogDrawer;
class plBinkPlayer;
class plDXPipeline : public plPipeline
{
protected:
enum {
kCapsNone = 0x00000000,
kCapsCompressTextures = 0x00000001,
kCapsMipmap = 0x00000002,
kCapsHWTransform = 0x00000004,
kCapsHWLighting = 0x00000008,
kCapsZBias = 0x00000010,
kCapsLinearFog = 0x00000020,
kCapsExpFog = 0x00000040,
kCapsExp2Fog = 0x00000080,
kCapsRangeFog = 0x00000100,
kCapsTexBoundToStage = 0x00000200,
kCapsLODWatch = 0x00000400,
kCapsFSAntiAlias = 0x00000800,
kCapsLuminanceTextures = 0x00001000,
kCapsDoesSmallTextures = 0x00002000,
kCapsDoesWFog = 0x00004000,
kCapsPixelFog = 0x00008000,
kCapsHasBadYonStuff = 0x00010000,
kCapsNpotTextures = 0x00020000,
kCapsCubicTextures = 0x00040000,
kCapsCubicMipmap = 0x00080000
};
enum {
kKNone = 0x0,
kKTNT = 0x1
};
plDebugTextManager* fDebugTextMgr;
plDXPlateManager* fPlateMgr;
// The main D3D interfaces
LPDIRECT3D9 fD3DObject; // The main D3D object
LPDIRECT3DDEVICE9 fD3DDevice; // The D3D rendering device
IDirect3DSurface9* fD3DMainSurface;
IDirect3DSurface9* fD3DDepthSurface;
IDirect3DSurface9* fD3DBackBuff;
IDirect3DSurface9* fSharedDepthSurface[2];
D3DFORMAT fSharedDepthFormat[2];
// Dynamic buffers
UInt32 fVtxRefTime;
UInt32 fNextDynVtx;
UInt32 fDynVtxSize;
IDirect3DVertexBuffer9* fDynVtxBuff;
hsBool fManagedAlloced;
hsBool fAllocUnManaged;
// States
plDXGeneralSettings fSettings;
plDXTweakSettings fTweaks;
plDXStencilSettings fStencil;
hsBool fDeviceLost;
hsBool fDevWasLost;
hsTArray<const plCullPoly*> fCullPolys;
hsTArray<const plCullPoly*> fCullHoles;
plDrawableSpans* fCullProxy;
plDXVertexBufferRef* fVtxBuffRefList;
plDXIndexBufferRef* fIdxBuffRefList;
plDXTextureRef* fTextureRefList;
plTextFont* fTextFontRefList;
plDXRenderTargetRef* fRenderTargetRefList;
plDXVertexShader* fVShaderRefList;
plDXPixelShader* fPShaderRefList;
hsGMaterial* fCurrMaterial;
plLayerInterface* fCurrLay;
UInt32 fCurrLayerIdx, fCurrNumLayers, fCurrRenderLayer;
UInt32 fCurrLightingMethod; // Based on plSpan flags
D3DCULL fCurrCullMode;
hsGMatState fMatOverOn;
hsGMatState fMatOverOff;
hsTArray<hsGMaterial*> fOverrideMat;
hsGMaterial* fHoldMat;
hsBool fCurrD3DLiteState;
hsMatrix44 fBumpDuMatrix;
hsMatrix44 fBumpDvMatrix;
hsMatrix44 fBumpDwMatrix;
hsTArray<plLayerInterface*> fOverLayerStack;
plLayerInterface* fOverBaseLayer;
plLayerInterface* fOverAllLayer;
hsTArray<plLayerInterface*> fPiggyBackStack;
Int32 fMatPiggyBacks;
Int32 fActivePiggyBacks;
UINT fCurrentAdapter;
D3DEnum_DriverInfo* fCurrentDriver;
D3DEnum_DeviceInfo* fCurrentDevice;
D3DEnum_ModeInfo* fCurrentMode;
hsGDeviceRef* fLayerRef[ 8 ];
hsGMatState fLayerState[ 8 ]; // base stage (0) state is held in base class
hsGMatState fOldLayerState[ 8 ];
hsBool fLayerTransform[ 8 ];
float fLayerLODBias[ 8 ];
UInt32 fLayerUVWSrcs[ 8 ];
UInt32 fLayerXformFlags[ 8 ];
UInt32 fLastEndingStage;
hsBool fTexturing;
hsBool fForceMatHandle;
UInt32 fInSceneDepth;
UInt32 fTextUseTime; // inc'd every frame - stat gather only
static UInt32 fTexManaged;
static UInt32 fTexUsed;
static UInt32 fVtxManaged;
static UInt32 fVtxUsed;
UInt32 fEvictTime;
UInt32 fManagedSeen;
UInt32 fManagedCutoff;
double fTime; // World time.
UInt32 fFrame; // inc'd every time the camera moves.
UInt32 fRenderCnt; // inc'd every begin scene.
// View stuff
plDXViewSettings fView;
hsBitVector fDebugFlags;
UInt32 fDebugSpanGraphY;
// Fog
plDXFogSettings fCurrFog;
// Light
plDXLightSettings fLights;
// Shadows
hsTArray<plShadowSlave*> fShadows;
hsTArray<plRenderTarget*> fRenderTargetPool512;
hsTArray<plRenderTarget*> fRenderTargetPool256;
hsTArray<plRenderTarget*> fRenderTargetPool128;
hsTArray<plRenderTarget*> fRenderTargetPool64;
hsTArray<plRenderTarget*> fRenderTargetPool32;
enum { kMaxRenderTargetNext = 10 };
UInt32 fRenderTargetNext[kMaxRenderTargetNext];
plDXTextureRef* fULutTextureRef;
plRenderTarget* fBlurScratchRTs[kMaxRenderTargetNext];
plRenderTarget* fBlurDestRTs[kMaxRenderTargetNext];
IDirect3DVertexBuffer9* fBlurVBuffers[kMaxRenderTargetNext];
UInt32 fBlurVSHandle;
hsTArray<plClothingOutfit*> fClothingOutfits;
hsTArray<plClothingOutfit*> fPrevClothingOutfits;
// Debug stuff
plDrawableSpans *fBoundsSpans;
hsGMaterial *fBoundsMat;
hsTArray<UInt32> fBSpansToDelete;
plStatusLogDrawer *fLogDrawer;
hsBool fVSync;
hsBool fForceDeviceReset;
void IBeginAllocUnManaged();
void IEndAllocUnManaged();
void ICheckTextureUsage();
void ICheckVtxUsage();
inline void ICheckVBUsage(plDXVertexBufferRef* vRef);
hsBool IRefreshDynVertices(plGBufferGroup* group, plDXVertexBufferRef* vRef);
hsBool ICheckAuxBuffers(const plAuxSpan* span);
hsBool ICheckDynBuffers(plDrawableSpans* drawable, plGBufferGroup* group, const plSpan* span);
void ICheckStaticVertexBuffer(plDXVertexBufferRef* vRef, plGBufferGroup* owner, UInt32 idx);
void ICheckIndexBuffer(plDXIndexBufferRef* iRef);
void IFillStaticVertexBufferRef(plDXVertexBufferRef *ref, plGBufferGroup *group, UInt32 idx);
void IFillIndexBufferRef(plDXIndexBufferRef* iRef, plGBufferGroup* owner, UInt32 idx);
void ISetupVertexBufferRef(plGBufferGroup* owner, UInt32 idx, plDXVertexBufferRef* vRef);
void ISetupIndexBufferRef(plGBufferGroup* owner, UInt32 idx, plDXIndexBufferRef* iRef);
void ICreateDynamicBuffers();
void IReleaseDynamicBuffers();
void IAddBoundsSpan( plDrawableSpans *ice, const hsBounds3Ext *bounds, UInt32 bndColor = 0xffff0000 );
void IAddNormalsSpan( plDrawableSpans *ice, plIcicle *span, plDXVertexBufferRef *vRef, UInt32 bndColor );
// Rendering
hsBool IFlipSurface();
long IGetBufferD3DFormat(UInt8 format) const;
UInt32 IGetBufferFormatSize(UInt8 format) const;
void IGetVisibleSpans( plDrawableSpans* drawable, hsTArray<Int16>& visList, plVisMgr* visMgr );
void IRenderSpans( plDrawableSpans *ice, const hsTArray<Int16>& visList );
hsBool ILoopOverLayers(const plRenderPrimFunc& render, hsGMaterial* material, const plSpan& span);
void IRenderBufferSpan( const plIcicle& span,
hsGDeviceRef *vb, hsGDeviceRef *ib,
hsGMaterial *material,
UInt32 vStart, UInt32 vLength, UInt32 iStart, UInt32 iLength );
void IRenderAuxSpan(const plSpan& span, const plAuxSpan* aux);
void IRenderAuxSpans(const plSpan& span);
// Fog
void IGetVSFogSet(float* const set) const;
void ISetFogParameters(const plSpan* span, const plLayerInterface* baseLay);
// Lighting
hsGDeviceRef *IMakeLightRef( plLightInfo *owner );
void IScaleD3DLight( plDXLightRef *ref, hsScalar scale);
void ICalcLighting( const plLayerInterface *currLayer, const plSpan *currSpan );
void IDisableSpanLights();
void IRestoreSpanLights();
void ISelectLights( plSpan *span, int numLights, hsBool proj );
void IEnableLights( plSpan *span );
void IMakeLightLists(plVisMgr* visMgr);
void ICheckLighting(plDrawableSpans* drawable, hsTArray<Int16>& visList, plVisMgr* visMgr);
inline void inlEnsureLightingOff();
inline void inlEnsureLightingOn();
void IRenderProjection(const plRenderPrimFunc& render, plLightInfo* li);
void IRenderProjections(const plRenderPrimFunc& render);
void IRenderProjectionEach(const plRenderPrimFunc& render, hsGMaterial* material, int iPass, const plSpan& span);
void IRenderOverWire(const plRenderPrimFunc& render, hsGMaterial* material, const plSpan& span);
hsBool ISkipBumpMap(hsGMaterial* newMat, UInt32& layer, const plSpan* currSpan) const;
void ISetBumpMatrices(const plLayerInterface* layer, const plSpan* span);
const hsMatrix44& IGetBumpMatrix(UInt32 miscFlags) const;
// Materials
const hsGMatState& ICompositeLayerState(int which, plLayerInterface* layer);
Int32 IHandleMaterial(hsGMaterial* newMat, UInt32 which, const plSpan* currSpan);
void IHandleFirstTextureStage( plLayerInterface* layer );
void IHandleShadeMode();
void IHandleZMode();
void IHandleMiscMode();
void IHandleTextureStage(UInt32 stage, plLayerInterface* layer);
void IHandleFirstStageBlend();
void IHandleBumpEnv(int stage, UInt32 blendFlags);
void IHandleStageBlend(int stage);
void IHandleStageClamp(int stage);
void IHandleStageTransform(int stage, plLayerInterface* layer);
void IHandleTextureMode(plLayerInterface* layer);
void IUseTextureRef(int stage, hsGDeviceRef* dRef, plLayerInterface* layer);
void IStageStop(UInt32 stage);
UInt32 ILayersAtOnce(hsGMaterial* mat, UInt32 which);
hsBool ICanEatLayer(plLayerInterface* lay);
void ISetLayer(UInt32 lay);
void IBottomLayer();
// Push special effects
plLayerInterface* IPushOverBaseLayer(plLayerInterface* li);
plLayerInterface* IPopOverBaseLayer(plLayerInterface* li);
plLayerInterface* IPushOverAllLayer(plLayerInterface* li);
plLayerInterface* IPopOverAllLayer(plLayerInterface* li);
int ISetNumActivePiggyBacks();
void IPushPiggyBacks(hsGMaterial* mat);
void IPopPiggyBacks();
void IPushProjPiggyBack(plLayerInterface* li);
void IPopProjPiggyBacks();
void ISetPipeConsts(plShader* shader);
HRESULT ISetShaders(plShader* vShader, plShader* pShader);
// Stenciling
virtual hsBool StencilEnable( hsBool enable );
virtual void StencilSetCompareFunc( UInt8 func, UInt32 refValue );
virtual void StencilSetMask( UInt32 mask, UInt32 writeMask );
virtual void StencilSetOps( UInt8 passOp, UInt8 failOp, UInt8 passButZFailOp );
virtual hsBool StencilGetCaps( plStencilCaps *caps );
hsGDeviceRef *MakeTextureRef( plLayerInterface* layer, plMipmap *b );
void IReloadTexture( plDXTextureRef *ref );
void IFillD3DTexture( plDXTextureRef *ref );
void IFillD3DCubeTexture( plDXCubeTextureRef *ref );
void IGetD3DTextureFormat( plBitmap *b, D3DFORMAT &formatType, UInt32& texSize );
void IFormatTextureData( UInt32 formatType, UInt32 numPix, hsRGBAColor32* const src, void *dst );
void *IGetPixelScratch( UInt32 size );
hsGDeviceRef *IMakeCubicTextureRef( plLayerInterface* layer, plCubicEnvironmap *cubic );
hsBool IProcessMipmapLevels( plMipmap *mipmap, UInt32 &numLevels,
UInt32 *&levelSizes, UInt32 &totalSize,
UInt32 &numPixels, void *&textureData, hsBool noMip );
IDirect3DTexture9 *IMakeD3DTexture( plDXTextureRef *ref, D3DFORMAT formatType );
IDirect3DCubeTexture9 *IMakeD3DCubeTexture( plDXTextureRef *ref, D3DFORMAT formatType );
// Visualization of active occluders
void IMakeOcclusionSnap();
hsBool IAvatarSort(plDrawableSpans* d, const hsTArray<Int16>& visList);
void IBlendVertsIntoBuffer( plSpan* span,
hsMatrix44* matrixPalette, int numMatrices,
const UInt8 *src, UInt8 format, UInt32 srcStride,
UInt8 *dest, UInt32 destStride, UInt32 count, UInt16 localUVWChans );
hsBool ISoftwareVertexBlend( plDrawableSpans* drawable, const hsTArray<Int16>& visList );
void ILinkDevRef( plDXDeviceRef *ref, plDXDeviceRef **refList );
void IUnlinkDevRef( plDXDeviceRef *ref );
// Properties
inline DWORD inlGetD3DColor( const hsColorRGBA &c ) const;
inline D3DCOLORVALUE inlPlToD3DColor(const hsColorRGBA& c, float a) const;
// Error handling
void IAddErrorMessage( char *errStr );
void ISetErrorMessage( char *errStr = nil );
void IGetD3DError();
void IShowErrorMessage( char *errStr = nil );
hsBool ICreateFail( char *errStr );
// FPU mode check
void IFPUCheck();
// Device initialization
void IInvalidateState();
void IInitDeviceState();
void IClearMembers();
void ISetCaps();
void IRestrictCaps( const hsG3DDeviceRecord& devRec );
void ISetGraphicsCapability(UInt32 v);
hsBool IFindDepthFormat(D3DPRESENT_PARAMETERS& params);
hsBool IFindCompressedFormats();
hsBool IFindLuminanceFormats();
hsBool ITextureFormatAllowed( D3DFORMAT format );
void ISetCurrentDriver( D3DEnum_DriverInfo *driv );
void ISetCurrentDevice( D3DEnum_DeviceInfo *dev );
void ISetCurrentMode( D3DEnum_ModeInfo *mode );
hsBool ICreateMaster();
hsBool ICreateDevice(hsBool windowed);
hsBool ICreateNormalSurfaces();
hsBool ICreateDeviceObjects();
void IReleaseDeviceObjects();
hsBool ICreateDynDeviceObjects();
void IReleaseDynDeviceObjects();
void IReleaseShaders();
hsBool IResetDevice();
// View and clipping
void ISetViewport();
void IUpdateViewVectors() const;
void IRefreshCullTree();
void ISetAnisotropy(hsBool on);
// Transforms
D3DXMATRIX& IMatrix44ToD3DMatrix( D3DXMATRIX& dst, const hsMatrix44& src );
void ITransformsToD3D();
hsMatrix44 IGetCameraToNDC();
void IProjectionMatrixToD3D();
void IWorldToCameraToD3D();
void ILocalToWorldToD3D();
void ISavageYonHack();
void ISetLocalToWorld( const hsMatrix44& l2w, const hsMatrix44& w2l );
void ISetCullMode(hsBool flip=false);
hsBool inline IIsViewLeftHanded();
hsBool IGetClearViewPort(D3DRECT& r);
plViewTransform& IGetViewTransform() { return fView.fTransform; }
void IUpdateViewFlags();
void ISetupTransforms(plDrawableSpans* drawable, const plSpan& span, hsMatrix44& lastL2W);
// Plate management
friend plDXPlateManager;
friend plBinkPlayer;
void IDrawPlate( plPlate *plate );
void ISetRenderTarget( plRenderTarget *target );
hsBool IPrepRenderTargetInfo( plRenderTarget *owner, D3DFORMAT &surfFormat,
D3DFORMAT &depthFormat, D3DRESOURCETYPE &resType );
hsBool IFindRenderTargetInfo( plRenderTarget *owner, D3DFORMAT &surfFormat, D3DRESOURCETYPE &resType );
// From a D3DFORMAT enumeration, return the string literal for it
static const char *IGetDXFormatName( D3DFORMAT format );
/////// Shadow internals
// Generation
void IClearShadowSlaves();
void IPreprocessShadows();
hsBool IPrepShadowCaster(const plShadowCaster* caster);
void IRenderShadowCasterSpan(plShadowSlave* slave, plDrawableSpans* drawable, const plIcicle& span);
void ISetupShadowCastTextureStages(plShadowSlave* slave);
hsBool IRenderShadowCaster(plShadowSlave* slave);
void ISetupShadowLight(plShadowSlave* slave);
plDXLightRef* INextShadowLight(plShadowSlave* slave);
hsBool IPushShadowCastState(plShadowSlave* slave);
hsBool IPopShadowCastState(plShadowSlave* slave);
plDXTextureRef* IGetULutTextureRef();
hsBool ICreateBlurVBuffers();
void IReleaseBlurVBuffers();
void IMakeRenderTargetPools();
void IResetRenderTargetPools();
plRenderTarget* IFindRenderTarget(UInt32& w, UInt32& h, hsBool ortho);
void IReleaseRenderTargetPools();
// Selection
void IAttachSlaveToReceivers(int iSlave, plDrawableSpans* drawable, const hsTArray<Int16>& visList);
void IAttachShadowsToReceivers(plDrawableSpans* drawable, const hsTArray<Int16>& visList);
hsBool IAcceptsShadow(const plSpan* span, plShadowSlave* slave);
hsBool IReceivesShadows(const plSpan* span, hsGMaterial* mat);
void ISetShadowFromGroup(plDrawableSpans* drawable, const plSpan* span, plLightInfo* liInfo);
// Application
void IRenderShadowsOntoSpan(const plRenderPrimFunc& render, const plSpan* span, hsGMaterial* mat);
void ISetupShadowRcvTextureStages(hsGMaterial* mat);
void ISetShadowLightState(hsGMaterial* mat);
void IDisableLightsForShadow();
void IEnableShadowLight(plShadowSlave* slave);
void ISetupShadowSlaveTextures(plShadowSlave* slave);
// Postprocess (blurring)
hsBool ISetBlurQuadToRender(plRenderTarget* smap);
void IRenderBlurBackToShadowMap(plRenderTarget* smap, plRenderTarget* scratch, plRenderTarget* dst);
void IRenderBlurFromShadowMap(plRenderTarget* scratchRT, plRenderTarget* smap, hsScalar scale);
void IBlurSetRenderTarget(plRenderTarget* rt);
int IGetScratchRenderTarget(plRenderTarget* smap);
void IBlurShadowMap(plShadowSlave* slave);
// Avatar Texture Rendering
double fAvRTShrinkValidSince;
hsTArray<plRenderTarget*> fAvRTPool;
UInt16 fAvRTWidth;
UInt32 fAvNextFreeRT;
void IFillAvRTPool();
hsBool IFillAvRTPool(UInt16 numRTs, UInt16 width); // Returns true if we successfully filled the pool. Otherwise cleans up.
void IReleaseAvRTPool();
plRenderTarget* IGetNextAvRT();
void IFreeAvRT(plRenderTarget* tex);
void IPreprocessAvatarTextures();
void IDrawClothingQuad(hsScalar x, hsScalar y, hsScalar w, hsScalar h, hsScalar uOff, hsScalar vOff, plMipmap *tex);
void IClearClothingOutfits(hsTArray<plClothingOutfit*>* outfits);
void IPrintDeviceInitError();
void IResetToDefaults(D3DPRESENT_PARAMETERS *params);
public:
plDXPipeline( hsWinRef hWnd, const hsG3DDeviceModeRecord *devMode );
virtual ~plDXPipeline();
CLASSNAME_REGISTER( plDXPipeline );
GETINTERFACE_ANY( plDXPipeline, plPipeline );
virtual IDirect3DDevice9* GetD3DDevice() const { return fD3DDevice; }
// Typical 3D device
virtual hsBool PreRender(plDrawable* drawable, hsTArray<Int16>& visList, plVisMgr* visMgr=nil);
virtual hsBool PrepForRender(plDrawable* drawable, hsTArray<Int16>& visList, plVisMgr* visMgr=nil);
virtual void Render(plDrawable* d, const hsTArray<Int16>& visList);
virtual void Draw(plDrawable* d);
virtual void PushRenderRequest(plRenderRequest* req);
virtual void PopRenderRequest(plRenderRequest* req);
void ResetDisplayDevice(int Width, int Height, int ColorDepth, hsBool Windowed, int NumAASamples, int MaxAnisotropicSamples, hsBool VSync = false );
virtual void ClearRenderTarget( plDrawable* d );
virtual void ClearRenderTarget( const hsColorRGBA* col = nil, const hsScalar* depth = nil );
virtual void SetClear(const hsColorRGBA* col=nil, const hsScalar* depth=nil);
virtual hsColorRGBA GetClearColor() const;
virtual hsScalar GetClearDepth() const;
virtual hsGDeviceRef* MakeRenderTargetRef( plRenderTarget *owner );
virtual hsGDeviceRef* SharedRenderTargetRef(plRenderTarget* sharer, plRenderTarget *owner);
virtual void PushRenderTarget( plRenderTarget *target );
virtual plRenderTarget* PopRenderTarget();
virtual hsBool BeginRender();
virtual hsBool EndRender();
virtual void RenderScreenElements();
virtual hsBool BeginDrawable(plDrawable* d);
virtual hsBool EndDrawable(plDrawable* d);
virtual void BeginVisMgr(plVisMgr* visMgr);
virtual void EndVisMgr(plVisMgr* visMgr);
virtual hsBool IsFullScreen() const { return fSettings.fFullscreen; }
virtual UInt32 Width() const { return fView.fTransform.GetViewPortWidth(); }
virtual UInt32 Height() const { return fView.fTransform.GetViewPortHeight(); }
virtual UInt32 ColorDepth() const { return fSettings.fColorDepth; }
virtual void Resize( UInt32 width, UInt32 height );
// Culling. Might be used in Update before bothering to do any serious computation.
virtual hsBool TestVisibleWorld(const hsBounds3Ext& wBnd);
virtual hsBool TestVisibleWorld(const plSceneObject* sObj);
virtual hsBool HarvestVisible(plSpaceTree* space, hsTArray<Int16>& visList);
virtual hsBool SubmitOccluders(const hsTArray<const plCullPoly*>& polyList);
// Debug flags
virtual void SetDebugFlag( UInt32 flag, hsBool on );
virtual hsBool IsDebugFlagSet( UInt32 flag ) const;
// These are also only for debugging.
virtual void SetMaxCullNodes(UInt16 n) { fView.fCullMaxNodes = n; }
virtual UInt16 GetMaxCullNodes() const { return fView.fCullMaxNodes; }
virtual hsBool CheckResources();
virtual void LoadResources(); // Tells us where it's a good time to load in unmanaged resources.
// Properties
virtual void SetProperty( UInt32 prop, hsBool on ) { on ? fSettings.fProperties |= prop : fSettings.fProperties &= ~prop; }
virtual hsBool GetProperty( UInt32 prop ) const { return ( fSettings.fProperties & prop ) ? true : false; }
virtual UInt32 GetMaxLayersAtOnce() const { return fSettings.fMaxLayersAtOnce; }
// Drawable type mask
virtual void SetDrawableTypeMask( UInt32 mask ) { fView.fDrawableTypeMask = mask; }
virtual UInt32 GetDrawableTypeMask() const { return fView.fDrawableTypeMask; }
virtual void SetSubDrawableTypeMask( UInt32 mask ) { fView.fSubDrawableTypeMask = mask; }
virtual UInt32 GetSubDrawableTypeMask() const { return fView.fSubDrawableTypeMask; }
// Create a debug text font object
virtual plTextFont *MakeTextFont( char *face, UInt16 size );
// Create and/or Refresh geometry buffers
virtual void CheckVertexBufferRef(plGBufferGroup* owner, UInt32 idx);
virtual void CheckIndexBufferRef(plGBufferGroup* owner, UInt32 idx);
virtual hsBool OpenAccess(plAccessSpan& dst, plDrawableSpans* d, const plVertexSpan* span, hsBool readOnly);
virtual hsBool CloseAccess(plAccessSpan& acc);
virtual void CheckTextureRef(plLayerInterface* lay);
static void FreeManagedTexture(UInt32 sz) { hsAssert(fTexManaged >= sz, "Freeing mem we don't have"); fTexManaged -= sz; }
static void AllocManagedTexture(UInt32 sz) { fTexManaged += sz; }
static void FreeManagedVertex(UInt32 sz) { hsAssert(fVtxManaged >= sz, "Freeing mem we don't have"); fVtxManaged -= sz; }
static void AllocManagedVertex(UInt32 sz) { fVtxManaged += sz; }
#ifndef PLASMA_EXTERNAL_RELEASE
static void ProfilePoolMem(D3DPOOL poolType, UInt32 size, hsBool add, char *id);
#endif // PLASMA_EXTERNAL_RELEASE
// From a D3DFORMAT enumeration, return the bit depth associated with it.
static short GetDXBitDepth( D3DFORMAT format );
// Default fog settings
virtual void SetDefaultFogEnviron( plFogEnvironment *fog ) { fView.fDefaultFog = *fog; fCurrFog.fEnvPtr = nil; }
virtual const plFogEnvironment &GetDefaultFogEnviron() const { return fView.fDefaultFog; }
// View state
virtual hsPoint3 GetViewPositionWorld() const { return GetViewTransform().GetPosition(); }
virtual hsVector3 GetViewAcrossWorld() const { return GetViewTransform().GetAcross(); }
virtual hsVector3 GetViewUpWorld() const { return GetViewTransform().GetUp(); }
virtual hsVector3 GetViewDirWorld() const { return GetViewTransform().GetDirection(); }
virtual void GetViewAxesWorld(hsVector3 axes[3] /* ac,up,at */ ) const;
virtual void GetFOV(hsScalar& fovX, hsScalar& fovY) const;
virtual void SetFOV(hsScalar fovX, hsScalar fovY);
virtual void GetSize(hsScalar& width, hsScalar& height) const;
virtual void SetSize(hsScalar width, hsScalar height);
virtual void GetDepth(hsScalar& hither, hsScalar& yon) const;
virtual void SetDepth(hsScalar hither, hsScalar yon);
virtual hsScalar GetZBiasScale() const;
virtual void SetZBiasScale(hsScalar scale);
virtual const hsMatrix44& GetWorldToCamera() const;
virtual const hsMatrix44& GetCameraToWorld() const;
virtual void SetWorldToCamera(const hsMatrix44& w2c, const hsMatrix44& c2w);
virtual void SetViewTransform(const plViewTransform& trans);
virtual const plViewTransform& GetViewTransform() const { return fView.fTransform; }
virtual const hsMatrix44& GetWorldToLocal() const;
virtual const hsMatrix44& GetLocalToWorld() const;
virtual void ScreenToWorldPoint( int n, UInt32 stride, Int32 *scrX, Int32 *scrY,
hsScalar dist, UInt32 strideOut, hsPoint3 *worldOut );
virtual void RefreshMatrices();
virtual void RefreshScreenMatrices();
virtual void RegisterLight(plLightInfo* light);
virtual void UnRegisterLight(plLightInfo* light);
// Overrides, always push returns whatever is necessary to restore on pop.
virtual hsGMaterial* PushOverrideMaterial(hsGMaterial* mat);
virtual void PopOverrideMaterial(hsGMaterial* restore);
virtual hsGMaterial* GetOverrideMaterial() const;
virtual plLayerInterface* AppendLayerInterface(plLayerInterface* li, hsBool onAllLayers = false);
virtual plLayerInterface* RemoveLayerInterface(plLayerInterface* li, hsBool onAllLayers = false);
virtual plLayerInterface* PushPiggyBackLayer(plLayerInterface* li);
virtual plLayerInterface* PopPiggyBackLayer(plLayerInterface* li);
virtual UInt32 GetMaterialOverrideOn(hsGMatState::StateIdx category) const;
virtual UInt32 GetMaterialOverrideOff(hsGMatState::StateIdx category) const;
virtual hsGMatState PushMaterialOverride(const hsGMatState& state, hsBool on);
virtual hsGMatState PushMaterialOverride(hsGMatState::StateIdx cat, UInt32 which, hsBool on);
virtual void PopMaterialOverride(const hsGMatState& restore, hsBool on);
virtual const hsGMatState& GetMaterialOverride(hsBool on) const;
virtual hsColorOverride PushColorOverride(const hsColorOverride& over);
virtual void PopColorOverride(const hsColorOverride& restore);
virtual const hsColorOverride& GetColorOverride() const;
virtual void SubmitShadowSlave(plShadowSlave* slave);
virtual void SubmitClothingOutfit(plClothingOutfit* co);
virtual hsBool SetGamma(hsScalar eR, hsScalar eG, hsScalar eB);
virtual hsBool SetGamma(const UInt16* const tabR, const UInt16* const tabG, const UInt16* const tabB);
virtual hsBool CaptureScreen( plMipmap *dest, bool flipVertical = false, UInt16 desiredWidth = 0, UInt16 desiredHeight = 0 );
virtual plMipmap* ExtractMipMap(plRenderTarget* targ);
/// Error handling
virtual const char *GetErrorString();
hsBool ManagedAlloced() const { return fManagedAlloced; }
virtual void GetSupportedColorDepths(hsTArray<int> &ColorDepths);
virtual void GetSupportedDisplayModes(std::vector<plDisplayMode> *res, int ColorDepth = 32 );
virtual int GetMaxAnisotropicSamples();
virtual int GetMaxAntiAlias(int Width, int Height, int ColorDepth);
};
//// Direct3D Inlines //////////////////////////////////////////////////////
// ??.?? - Some mild optimizations PBG
// MMW - take advantage of the 32 bit float representation on a PC
#define CONVERT_FLOAT_TO_BYTE_COLOR( f, dest ) \
{ \
LONG const floatBitsOne = 0x3f800000; \
LONG const floatBits = *( (LONG const *)( &f ) ); \
if( floatBits <= 0 ) dest = 0; \
else if( floatBits >= floatBitsOne ) dest = 255; \
else \
{ \
LONG const times256 = floatBits + ( 8 << 23 ); \
dest = (DWORD)( *( (float const *)( &times256 ) ) ); \
} \
}
inline DWORD plDXPipeline::inlGetD3DColor( const hsColorRGBA &col ) const
{
DWORD dr, dg, db, da;
CONVERT_FLOAT_TO_BYTE_COLOR( col.r, dr );
CONVERT_FLOAT_TO_BYTE_COLOR( col.g, dg );
CONVERT_FLOAT_TO_BYTE_COLOR( col.b, db );
CONVERT_FLOAT_TO_BYTE_COLOR( col.a, da );
return( ( da << 24 ) | ( dr << 16 ) | ( dg << 8 ) | db );
}
#endif // _plDX9Pipeline_h