1
0
mirror of https://foundry.openuru.org/gitblit/r/CWE-ou-minkata.git synced 2025-07-18 19:29:09 +00:00

Move all the DirectX-specific stuff into a folder.

This actually allows us to compile plPipeline on *nix (although linking
will fail).
This commit is contained in:
Darryl Pogue
2013-07-21 00:50:00 -07:00
parent 509bf10a66
commit 04d88377ad
24 changed files with 79 additions and 61 deletions

View File

@ -0,0 +1,171 @@
/*==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==*/
///////////////////////////////////////////////////////////////////////////////
// //
// plDXBufferRefs.h - Hardware Vertex and Index Buffer DeviceRef //
// Definitions //
// Cyan, Inc. //
// //
//// Version History //////////////////////////////////////////////////////////
// //
// 4.25.2001 mcn - Created. //
// //
///////////////////////////////////////////////////////////////////////////////
#ifndef _plDXBufferRefs_h
#define _plDXBufferRefs_h
#include "hsMatrix44.h"
#include "hsGeometry3.h"
#include "hsTemplates.h"
#include "plDXDeviceRef.h"
struct IDirect3DVertexShader9;
//// Definitions //////////////////////////////////////////////////////////////
class plDXVertexBufferRef : public plDXDeviceRef
{
public:
IDirect3DVertexBuffer9* fD3DBuffer;
uint32_t fCount;
uint32_t fIndex;
uint32_t fVertexSize;
int32_t fOffset;
uint8_t fFormat;
plGBufferGroup* fOwner;
uint8_t* fData;
IDirect3DDevice9* fDevice; // For releasing the VertexShader
uint32_t fRefTime;
enum {
kRebuiltSinceUsed = 0x10, // kDirty = 0x1 is in hsGDeviceRef
kVolatile = 0x20,
kSkinned = 0x40
};
bool HasFlag(uint32_t f) const { return 0 != (fFlags & f); }
void SetFlag(uint32_t f, bool on) { if(on) fFlags |= f; else fFlags &= ~f; }
bool RebuiltSinceUsed() const { return HasFlag(kRebuiltSinceUsed); }
void SetRebuiltSinceUsed(bool b) { SetFlag(kRebuiltSinceUsed, b); }
bool Volatile() const { return HasFlag(kVolatile); }
void SetVolatile(bool b) { SetFlag(kVolatile, b); }
bool Skinned() const { return HasFlag(kSkinned); }
void SetSkinned(bool b) { SetFlag(kSkinned, b); }
bool Expired(uint32_t t) const { return Volatile() && (IsDirty() || (fRefTime != t)); }
void SetRefTime(uint32_t t) { fRefTime = t; }
void Link( plDXVertexBufferRef **back ) { plDXDeviceRef::Link( (plDXDeviceRef **)back ); }
plDXVertexBufferRef* GetNext() { return (plDXVertexBufferRef *)fNext; }
plDXVertexBufferRef() :
fD3DBuffer(nil),
fCount(0),
fIndex(0),
fVertexSize(0),
fOffset(0),
fOwner(nil),
fData(nil),
fFormat(0),
fRefTime(0),
fDevice(nil)
{
}
virtual ~plDXVertexBufferRef();
void Release();
};
class plDXIndexBufferRef : public plDXDeviceRef
{
public:
IDirect3DIndexBuffer9* fD3DBuffer;
uint32_t fCount;
uint32_t fIndex;
int32_t fOffset;
plGBufferGroup* fOwner;
uint32_t fRefTime;
D3DPOOL fPoolType;
enum {
kRebuiltSinceUsed = 0x10, // kDirty = 0x1 is in hsGDeviceRef
kVolatile = 0x20
};
bool HasFlag(uint32_t f) const { return 0 != (fFlags & f); }
void SetFlag(uint32_t f, bool on) { if(on) fFlags |= f; else fFlags &= ~f; }
bool RebuiltSinceUsed() const { return HasFlag(kRebuiltSinceUsed); }
void SetRebuiltSinceUsed(bool b) { SetFlag(kRebuiltSinceUsed, b); }
bool Volatile() const { return HasFlag(kVolatile); }
void SetVolatile(bool b) { SetFlag(kVolatile, b); }
bool Expired(uint32_t t) const { return Volatile() && (IsDirty() || (fRefTime != t)); }
void SetRefTime(uint32_t t) { fRefTime = t; }
void Link( plDXIndexBufferRef **back ) { plDXDeviceRef::Link( (plDXDeviceRef **)back ); }
plDXIndexBufferRef* GetNext() { return (plDXIndexBufferRef *)fNext; }
plDXIndexBufferRef() :
fD3DBuffer(nil),
fCount(0),
fIndex(0),
fOffset(0),
fOwner(nil),
fRefTime(0),
fPoolType(D3DPOOL_MANAGED)
{
}
virtual ~plDXIndexBufferRef();
void Release();
};
#endif // _plDXBufferRefs_h

View File

@ -0,0 +1,82 @@
/*==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==*/
///////////////////////////////////////////////////////////////////////////////
// //
// plDXDeviceRef.h - Header for the generic DX DeviceRef type //
// Cyan, Inc. //
// //
//// Version History //////////////////////////////////////////////////////////
// //
// 4.25.2001 mcn - Created. //
// //
///////////////////////////////////////////////////////////////////////////////
#ifndef _plDXDeviceRef_h
#define _plDXDeviceRef_h
#include "HeadSpin.h"
#include "plPipeline/hsGDeviceRef.h"
//// Definition ///////////////////////////////////////////////////////////////
class plDXDeviceRef : public hsGDeviceRef
{
protected:
plDXDeviceRef *fNext;
plDXDeviceRef **fBack;
public:
void Unlink( void );
void Link( plDXDeviceRef **back );
plDXDeviceRef *GetNext( void ) { return fNext; }
bool IsLinked( void ) { return fBack != nil; }
virtual void Release( void ) { }
plDXDeviceRef();
virtual ~plDXDeviceRef();
};
#endif // _plDXDeviceRef_h

View File

@ -0,0 +1,523 @@
/*==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==*/
///////////////////////////////////////////////////////////////////////////////
// //
// plDXDeviceRefs.cpp - Functions for the various DX DeviceRef classes //
// Cyan, Inc. //
// //
//// Version History //////////////////////////////////////////////////////////
// //
// 4.25.2001 mcn - Created. //
// //
///////////////////////////////////////////////////////////////////////////////
#include "HeadSpin.h"
#include "hsWindows.h"
#include <d3d9.h>
#include <ddraw.h>
#include "plPipeline/hsWinRef.h"
#include "plDXPipeline.h"
#include "plDXDeviceRef.h"
#include "plDXBufferRefs.h"
#include "plDXLightRef.h"
#include "plDXTextureRef.h"
#include "plDXRenderTargetRef.h"
#include "plPipeline/plGBufferGroup.h"
#include "plDrawable/plGeometrySpan.h"
#include "plDrawable/plDrawableSpans.h"
#include "plGLight/plLightInfo.h"
#include "plPipeline/plRenderTarget.h"
#include "plPipeline/plCubicRenderTarget.h"
#include "plPipeline/plDynamicEnvMap.h"
#include "plProfile.h"
#include "plStatusLog/plStatusLog.h"
plProfile_CreateMemCounter("Vertices", "Memory", MemVertex);
plProfile_CreateMemCounter("Indices", "Memory", MemIndex);
plProfile_CreateMemCounter("Textures", "Memory", MemTexture);
///////////////////////////////////////////////////////////////////////////////
//// Generic plDXDeviceRef Functions /////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
plDXDeviceRef::plDXDeviceRef()
{
fNext = nil;
fBack = nil;
}
plDXDeviceRef::~plDXDeviceRef()
{
if( fNext != nil || fBack != nil )
Unlink();
}
void plDXDeviceRef::Unlink( void )
{
hsAssert( fBack, "plDXDeviceRef not in list" );
if( fNext )
fNext->fBack = fBack;
*fBack = fNext;
fBack = nil;
fNext = nil;
}
void plDXDeviceRef::Link( plDXDeviceRef **back )
{
hsAssert( fNext == nil && fBack == nil, "Trying to link a plDXDeviceRef that's already linked" );
fNext = *back;
if( *back )
(*back)->fBack = &fNext;
fBack = back;
*back = this;
}
///////////////////////////////////////////////////////////////////////////////
//// plDXVertex/IndexBufferRef Funktions /////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
//// Destructors //////////////////////////////////////////////////////////////
plDXVertexBufferRef::~plDXVertexBufferRef()
{
Release();
}
plDXIndexBufferRef::~plDXIndexBufferRef()
{
Release();
}
//// Releases /////////////////////////////////////////////////////////////////
void plDXVertexBufferRef::Release( void )
{
if( fD3DBuffer != nil )
{
ReleaseObject(fD3DBuffer);
if (!Volatile())
{
plProfile_DelMem(MemVertex, fCount * fVertexSize);
PROFILE_POOL_MEM(D3DPOOL_MANAGED, fCount * fVertexSize, false, "VtxBuff");
plDXPipeline::FreeManagedVertex(fCount * fVertexSize);
}
}
delete [] fData;
fData = nil;
SetDirty( true );
}
void plDXIndexBufferRef::Release( void )
{
if( fD3DBuffer != nil )
{
plProfile_DelMem(MemIndex, fCount * sizeof(uint16_t));
PROFILE_POOL_MEM(fPoolType, fCount * sizeof(uint16_t), false, "IndexBuff");
ReleaseObject( fD3DBuffer );
}
SetDirty( true );
}
///////////////////////////////////////////////////////////////////////////////
//// plDXTextureRef Funktions ////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
//// Set //////////////////////////////////////////////////////////////////////
plDXTextureRef& plDXTextureRef::Set( D3DFORMAT ft, uint32_t ml, uint32_t mw, uint32_t mh, uint32_t np,
uint32_t sz, uint32_t manSize, uint32_t* lSz, void* pd, bool ed, bool renderTarget )
{
if( fDataSize > 0 )
plProfile_DelMem(MemTexture, fDataSize + sizeof(plDXTextureRef));
if( ( fFormatType != ft || fMMLvs != ml || fMaxWidth != mw || fMaxHeight != mh ) && fD3DTexture != nil )
ReleaseObject( fD3DTexture );
if( !fD3DTexture )
fUseTime = 0;
fFormatType = ft;
fMMLvs = ml;
fMaxWidth = mw;
fMaxHeight = mh;
fNumPix = np;
fDataSize = manSize;
if( fLevelSizes != nil )
delete [] fLevelSizes;
if( lSz )
fLevelSizes = lSz;
else
{
fLevelSizes = new uint32_t[1];
fLevelSizes[0] = sz;
}
fData = pd;
fFlags = ( ed ? kExternData : 0 ) | ( renderTarget ? kRenderTarget : 0 );
plProfile_NewMem(MemTexture, fDataSize + sizeof(plDXTextureRef));
return *this;
}
//// Constructor & Destructor /////////////////////////////////////////////////
plDXTextureRef::plDXTextureRef( D3DFORMAT ft, uint32_t ml, uint32_t mw, uint32_t mh, uint32_t np,
uint32_t sz, uint32_t manSize, uint32_t* lSz, void* pd, bool ed, bool renderTarget )
: fD3DTexture(nullptr), fLevelSizes(nullptr), fOwner(nullptr)
{
Set( ft, ml, mw, mh, np, sz, manSize, lSz, pd, ed, renderTarget );
}
plDXTextureRef::~plDXTextureRef()
{
Release();
delete [] fLevelSizes;
}
//// Release //////////////////////////////////////////////////////////////////
void plDXTextureRef::Release( void )
{
plProfile_DelMem(MemTexture, fDataSize + sizeof(plDXTextureRef));
plProfile_Extern(ManagedMem);
PROFILE_POOL_MEM(D3DPOOL_MANAGED, fDataSize, false, (fOwner ? fOwner->GetKey() ? fOwner->GetKey()->GetUoid().GetObjectName().c_str() : "(UnknownTexture)" : "(UnknownTexture)"));
plDXPipeline::FreeManagedTexture(fDataSize);
fDataSize = 0;
ReleaseObject( fD3DTexture );
SetDirty( true );
}
///////////////////////////////////////////////////////////////////////////////
//// plDXLightRef Funktions //////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
//// UpdateD3DInfo ////////////////////////////////////////////////////////////
#define SET_D3DCOLORVALUE( v, color ) { v.r = color.r; v.g = color.g; v.b = color.b; v.a = color.a; }
void plDXLightRef::UpdateD3DInfo( IDirect3DDevice9 *dev, plDXLightSettings *settings )
{
plDirectionalLightInfo *dirOwner;
plOmniLightInfo *omniOwner;
plSpotLightInfo *spotOwner;
const float maxRange = 32767.f;
/// Properties that are set for all types
fD3DDevice = dev;
fParentSettings = settings;
memset( &fD3DInfo, 0, sizeof( D3DLIGHT9 ) );
SET_D3DCOLORVALUE( fD3DInfo.Diffuse, fOwner->GetDiffuse() );
SET_D3DCOLORVALUE( fD3DInfo.Ambient, fOwner->GetAmbient() );
SET_D3DCOLORVALUE( fD3DInfo.Specular, fOwner->GetSpecular() );
if( ( omniOwner = plOmniLightInfo::ConvertNoRef( fOwner ) ) != nil )
{
fD3DInfo.Type = D3DLIGHT_POINT;
hsPoint3 position = omniOwner->GetWorldPosition();
fD3DInfo.Position.x = position.fX;
fD3DInfo.Position.y = position.fY;
fD3DInfo.Position.z = position.fZ;
if( omniOwner->GetRadius() == 0 )
fD3DInfo.Range = maxRange;
else
fD3DInfo.Range = omniOwner->GetRadius();
fD3DInfo.Attenuation0 = omniOwner->GetConstantAttenuation();
fD3DInfo.Attenuation1 = omniOwner->GetLinearAttenuation();
fD3DInfo.Attenuation2 = omniOwner->GetQuadraticAttenuation();
// If the light is a spot, but it has a projected texture, then
// the cone attenuation is handled by the texture. We're only using
// the D3D light for distance attenuation and the N*L term. So
// we can just leave the D3D light as the cheaper and more stable
// Omni light. This sort of obviates the change below. - mf
if( !omniOwner->GetProjection()
&& (spotOwner = plSpotLightInfo::ConvertNoRef(fOwner)) )
{
fD3DInfo.Type = D3DLIGHT_SPOT;
hsVector3 direction = spotOwner->GetWorldDirection();
fD3DInfo.Direction.x = direction.fX;
fD3DInfo.Direction.y = direction.fY;
fD3DInfo.Direction.z = direction.fZ;
fD3DInfo.Falloff = spotOwner->GetFalloff();
fD3DInfo.Theta = spotOwner->GetSpotInner() * 2;
// fD3DInfo.Phi = spotOwner->GetProjection() ? M_PI : spotOwner->GetSpotOuter() * 2;
// D3D doesn't seem to like a Phi of PI, even though that's supposed to be the
// largest legal value. Symptom is an erratic, intermitant, unpredictable failure
// of the light to light, with bizarreness like lighting one object but not the object
// next to it, alternating which object it fails on each frame (or less often).
// So, whatever. - mf
fD3DInfo.Phi = spotOwner->GetSpotOuter() * 2;
}
}
else if( ( dirOwner = plDirectionalLightInfo::ConvertNoRef( fOwner ) ) != nil )
{
fD3DInfo.Type = D3DLIGHT_DIRECTIONAL;
hsVector3 direction = dirOwner->GetWorldDirection();
fD3DInfo.Direction.x = direction.fX;
fD3DInfo.Direction.y = direction.fY;
fD3DInfo.Direction.z = direction.fZ;
}
else
{
hsAssert( false, "Unrecognized light type passed to plDXLightRef::UpdateD3DInfo()" );
return;
}
fD3DDevice->SetLight( fD3DIndex, &fD3DInfo );
fScale = 1.f;
}
//// Destructor ///////////////////////////////////////////////////////////////
plDXLightRef::~plDXLightRef()
{
Release();
}
//// Release //////////////////////////////////////////////////////////////////
void plDXLightRef::Release( void )
{
// Ensure that this light is disabled
if( fD3DDevice )
{
fD3DDevice->LightEnable( fD3DIndex, false );
fD3DDevice = nil;
}
if( fParentSettings )
{
fParentSettings->fEnabledFlags.SetBit( fD3DIndex, false );
fParentSettings->ReleaseD3DIndex( fD3DIndex );
fParentSettings = nil;
}
fD3DIndex = 0;
SetDirty( true );
}
///////////////////////////////////////////////////////////////////////////////
//// plDXRenderTargetRef Functions ///////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
//// Constructor //////////////////////////////////////////////////////////////
plDXRenderTargetRef::plDXRenderTargetRef( D3DFORMAT tp, uint32_t ml, plRenderTarget *owner, bool releaseDepthOnDelete )
: plDXTextureRef( tp, ml, owner->GetWidth(), owner->GetHeight(),
owner->GetWidth() * owner->GetHeight(),
owner->GetWidth() * owner->GetHeight() * ( owner->GetPixelSize() >> 3 ),
0,
nil,
nil, true, true )
{
fD3DColorSurface = nil;
fD3DDepthSurface = nil;
fReleaseDepth = releaseDepthOnDelete;
fOwner = owner;
if( owner->GetFlags() & plRenderTarget::kIsTexture )
fFlags |= kOffscreenRT;
if( owner->GetFlags() & plRenderTarget::kIsProjected )
{
if( owner->GetFlags() & plRenderTarget::kIsOrtho )
fFlags |= kOrthoProjection;
else
fFlags |= kPerspProjection;
}
if( plCubicRenderTarget::ConvertNoRef( owner ) != nil )
fFlags |= kCubicMap;
}
//// Set //////////////////////////////////////////////////////////////////////
plDXRenderTargetRef& plDXRenderTargetRef::Set( D3DFORMAT tp, uint32_t ml, plRenderTarget *owner )
{
fOwner = owner;
plDXTextureRef::Set( tp, ml, owner->GetWidth(), owner->GetHeight(),
owner->GetWidth() * owner->GetHeight(),
owner->GetWidth() * owner->GetHeight() * ( owner->GetPixelSize() >> 3 ),
0,
nil,
nil, true, true );
if( owner->GetFlags() & plRenderTarget::kIsTexture )
fFlags |= kOffscreenRT;
if( owner->GetFlags() & plRenderTarget::kIsProjected )
{
if( owner->GetFlags() & plRenderTarget::kIsOrtho )
fFlags |= kOrthoProjection;
else
fFlags |= kPerspProjection;
}
if( plCubicRenderTarget::ConvertNoRef( owner ) != nil )
fFlags |= kCubicMap;
return *this;
}
//// SetTexture ///////////////////////////////////////////////////////////////
void plDXRenderTargetRef::SetTexture( IDirect3DSurface9 *surface, IDirect3DSurface9 *depth )
{
fD3DColorSurface = surface;
fD3DTexture = nil;
fD3DDepthSurface = depth;
}
void plDXRenderTargetRef::SetTexture( IDirect3DTexture9 *surface, IDirect3DSurface9 *depth )
{
fD3DTexture = surface;
fD3DColorSurface = nil;
fD3DDepthSurface = depth;
}
void plDXRenderTargetRef::SetTexture( IDirect3DCubeTexture9 *surface, IDirect3DSurface9 *depth )
{
int i;
IDirect3DSurface9 *surf;
plDXRenderTargetRef *ref;
plCubicRenderTarget *cubic;
D3DCUBEMAP_FACES faces[ 6 ] = { D3DCUBEMAP_FACE_NEGATIVE_X, // Left
D3DCUBEMAP_FACE_POSITIVE_X, // Right
D3DCUBEMAP_FACE_POSITIVE_Z, // Front
D3DCUBEMAP_FACE_NEGATIVE_Z, // Back
D3DCUBEMAP_FACE_POSITIVE_Y, // Top
D3DCUBEMAP_FACE_NEGATIVE_Y }; // Bottom
fD3DTexture = surface;
fD3DDepthSurface = depth;
fD3DColorSurface = nil;
/// Get the faces and assign to each of the child targets
cubic = plCubicRenderTarget::ConvertNoRef( fOwner );
for( i = 0; i < 6; i++ )
{
if( surface->GetCubeMapSurface( faces[ i ], 0, &surf ) != D3D_OK )
{
hsAssert( false, "Unable to get cube map surface" );
continue;
}
ref = (plDXRenderTargetRef *)cubic->GetFace( i )->GetDeviceRef();
ref->SetTexture( surf, depth );
}
}
//// Destructor ///////////////////////////////////////////////////////////////
plDXRenderTargetRef::~plDXRenderTargetRef()
{
Release();
}
//// Release //////////////////////////////////////////////////////////////////
void plDXRenderTargetRef::Release( void )
{
int i;
plCubicRenderTarget *cubic;
plDXRenderTargetRef *ref;
/// Get rid of the children's deviceRefs
if( fFlags & kCubicMap )
{
cubic = plCubicRenderTarget::ConvertNoRef( fOwner );
for( i = 0; i < 6; i++ )
{
ref = (plDXRenderTargetRef *)cubic->GetFace( i )->GetDeviceRef();
ref->Release();
ref->SetDirty( true );
}
// No need to call D3DSURF_MEMDEL on our fD3DTexture. It'll get
// accounted for by our children's surfaces.
}
else
{
// We do internal accounting here. Actual release of fD3DTexture
// happens in plDXTextureRef::Release()
D3DSURF_MEMDEL((IDirect3DTexture9*)fD3DTexture);
}
D3DSURF_MEMDEL(fD3DColorSurface);
ReleaseObject( fD3DColorSurface );
if( fReleaseDepth )
{
// TODO:
// We don't know who all is sharing this depth surface, so we can't
// confidently say this memory is free now. We're reffing and releasing
// it properly as far as DirectX is concerned, but our internal memory
// counter is ignoring it.
//D3DSURF_MEMDEL(fD3DDepthSurface);
ReleaseObject( fD3DDepthSurface );
}
plDXTextureRef::Release();
SetDirty( true );
}

View File

@ -0,0 +1,899 @@
/*==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==*/
#include "plDXEnumerate.h"
#include <ddraw.h>
#include "plPipeline/hsGDDrawDllLoad.h"
#include "plPipeline/hsG3DDeviceSelector.h"
//// Local Typedefs ///////////////////////////////////////////////////////////
typedef LPDIRECT3D9 (WINAPI * Direct3DCreateProc)( UINT sdkVersion );
const uint8_t hsGDirect3DTnLEnumerate::kNumDisplayFormats = 6;
const D3DFORMAT hsGDirect3DTnLEnumerate::kDisplayFormats[] =
{
D3DFMT_A1R5G5B5,
D3DFMT_A2B10G10R10,
D3DFMT_A8R8G8B8,
D3DFMT_R5G6B5,
D3DFMT_X1R5G5B5,
D3DFMT_X8R8G8B8,
};
HRESULT hsGDirect3DTnLEnumerate::SelectFromDevMode(const hsG3DDeviceRecord* devRec, const hsG3DDeviceMode* devMode)
{
int i;
for( i = 0; i < GetNumDrivers(); i++ )
{
if( !stricmp(GetDriver(i)->fAdapterInfo.Description, devRec->GetDriverDesc()) )
{
int j;
for( j = 0; j < GetDriver(i)->fDevices.GetCount(); j++ )
{
if( !stricmp(GetDriver(i)->fDevices[j].fStrName, devRec->GetDeviceDesc()) )
{
SetCurrentDriver(GetDriver(i));
SetCurrentDevice(&GetDriver(i)->fDevices[j]);
D3DEnum_SelectDefaultMode(
devMode->GetWidth(),
devMode->GetHeight(),
devMode->GetColorDepth());
return false;
}
}
}
}
char errStr[256];
sprintf(errStr, "Can't find requested device - %s:%s:%s:%s:%s",
devRec->GetG3DDeviceTypeName(),
devRec->GetDriverDesc(),
devRec->GetDriverName(),
devRec->GetDriverVersion(),
devRec->GetDeviceDesc());
DWORD enumFlags = 0;
int width = devMode->GetWidth();
int height = devMode->GetHeight();
int colorDepth = devMode->GetColorDepth();
// for a window, take whatever colordepth we can get.
if( !colorDepth )
enumFlags |= D3DENUM_CANWINDOW;
enumFlags |= D3DENUM_TNLHAL;
#ifdef HS_ALLOW_D3D_REF_DRIVER
enumFlags |= D3DENUM_REFERENCERAST;
#endif
D3DEnum_SelectDefaultDriver(enumFlags);
// If we didn't get what we want, try for anything.
if( !GetCurrentDriver() || !GetCurrentDevice() )
{
enumFlags = colorDepth ? 0 : D3DENUM_CANWINDOW;
D3DEnum_SelectDefaultDriver(enumFlags);
}
if( !GetCurrentDriver() || !GetCurrentDevice() )
D3DEnum_SelectDefaultDriver(0);
if( !GetCurrentDriver() || !GetCurrentDevice() )
{
if( !*GetEnumeErrorStr() )
SetEnumeErrorStr("Error finding device");
return true;
}
D3DEnum_SelectDefaultMode(width, height, colorDepth);
if( !GetCurrentMode() )
{
if( !*GetEnumeErrorStr() )
SetEnumeErrorStr("Error finding mode");
return true;
}
return false;
}
HRESULT hsGDirect3DTnLEnumerate::D3DEnum_SelectDefaultMode(int width, int height, int depth)
{
hsAssert(GetCurrentDriver() && GetCurrentDevice(), "Must have selected device already");
BOOL windowed = false;
if (depth == 0)
{
// Legacy code writes out 0 bit depth to mean windowed
windowed = true;
depth = 32;
}
D3DEnum_DeviceInfo* device = GetCurrentDevice();
int i;
for( i = 0; i < device->fModes.GetCount(); i++ )
{
D3DEnum_ModeInfo* mode = &device->fModes[i];
if (mode->fWindowed != windowed)
continue;
if( depth )
{
if( width < mode->fDDmode.Width )
continue;
if( height < mode->fDDmode.Height )
continue;
}
if( depth < mode->fBitDepth )
continue;
if( GetCurrentMode() )
{
D3DEnum_ModeInfo* curMode = GetCurrentDriver()->fCurrentMode;
if( depth )
{
if( curMode->fDDmode.Width > mode->fDDmode.Width )
continue;
if( curMode->fDDmode.Height > mode->fDDmode.Height )
continue;
}
if( curMode->fBitDepth > mode->fBitDepth )
continue;
}
SetCurrentMode(mode);
}
return S_OK;
}
//-----------------------------------------------------------------------------
// Name: D3DEnum_SelectDefaultDriver()
// Desc: Picks a default driver according to the passed in flags.
//-----------------------------------------------------------------------------
HRESULT hsGDirect3DTnLEnumerate::D3DEnum_SelectDefaultDriver( DWORD dwFlags )
{
// If a specific driver was requested, perform that search here
if( dwFlags & D3DENUM_MASK )
{
int i;
for( i = 0; i < fDrivers.GetCount(); i++ )
{
D3DEnum_DriverInfo* pDriver = &fDrivers[i];
int j;
for( j = 0; j < pDriver->fDevices.GetCount(); j++ )
{
D3DEnum_DeviceInfo* pDevice = &pDriver->fDevices[j];
BOOL bFound = FALSE;
if( pDevice->fDDType == D3DDEVTYPE_REF )
{
if( dwFlags & D3DENUM_REFERENCERAST )
bFound = TRUE;
}
else if( pDevice->fDDType == D3DDEVTYPE_HAL &&
pDevice->fDDCaps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT )
{
if( dwFlags & D3DENUM_TNLHAL )
bFound = TRUE;
}
else
{
if( dwFlags & D3DENUM_CANWINDOW )
{
if( (pDriver == &fDrivers[0])
&&( pDevice->fDDCaps.Caps2 & DDCAPS2_CANRENDERWINDOWED ) )
{
if( ( pDevice->fDDCaps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT )
^ !(dwFlags & D3DENUM_TNLHAL) )
bFound = TRUE;
}
}
else
if( dwFlags & D3DENUM_PRIMARYHAL )
{
if( pDriver == &fDrivers[0] )
bFound = TRUE;
}
else
if( dwFlags & D3DENUM_SECONDARYHAL )
{
if( pDriver != &fDrivers[0] )
bFound = TRUE;
}
}
if( bFound )
{
SetCurrentDriver(pDriver);
SetCurrentDevice(pDevice);
return S_OK;
}
}
}
return D3DENUMERR_NOTFOUND;
}
int i;
for( i = 0; i < fDrivers.GetCount(); i++ )
{
D3DEnum_DriverInfo* pDriver = &fDrivers[i];
int j;
for( j = 0; j < pDriver->fDevices.GetCount(); j++ )
{
D3DEnum_DeviceInfo* pDevice = &pDriver->fDevices[j];
if( !pDevice->fIsHardware )
continue;
SetCurrentDriver(pDriver);
SetCurrentDevice(pDevice);
return S_OK;
}
}
// No compatible devices were found. Return an error code
return D3DENUMERR_NOCOMPATIBLEDEVICES;
}
//// Constructor //////////////////////////////////////////////////////////////
//
// Inits the enumeration and builds our list of devices/whatever.
hsGDirect3DTnLEnumerate::hsGDirect3DTnLEnumerate()
{
memset( &fEnumeErrorStr[0], 0x00, sizeof(fEnumeErrorStr) );
fCurrentDriver = NULL; // The selected DD driver
fDrivers.Reset(); // List of DD drivers
/// New DX Enumeration
// Get a pointer to the creation function
if( hsGDDrawDllLoad::GetD3DDll() == nil )
{
strcpy( fEnumeErrorStr, "Cannot load Direct3D driver!" );
return;
}
Direct3DCreateProc procPtr;
procPtr = (Direct3DCreateProc)GetProcAddress( hsGDDrawDllLoad::GetD3DDll(), "Direct3DCreate9" );
if( procPtr == nil )
{
strcpy( fEnumeErrorStr, "Cannot load D3D Create Proc!" );
return;
}
// Create a D3D object to use
IDirect3D9 *pD3D = procPtr( D3D_SDK_VERSION );
if( pD3D == nil )
{
strcpy( fEnumeErrorStr, "Cannot load DirectX!" );
return;
}
/// Loop through the "adapters" (we don't call them drivers anymore)
UINT iAdapter;
for( iAdapter = 0; iAdapter < pD3D->GetAdapterCount(); iAdapter++ )
{
D3DEnum_DriverInfo* newDriver = fDrivers.Push();
ZeroMemory( newDriver, sizeof( *newDriver ) );
// Copy data to a device info structure
D3DADAPTER_IDENTIFIER9 adapterInfo;
pD3D->GetAdapterIdentifier( iAdapter, 0, &adapterInfo );
pD3D->GetAdapterDisplayMode( iAdapter, &newDriver->fDesktopMode );
memcpy( &newDriver->fAdapterInfo, &adapterInfo, sizeof( adapterInfo ) );
strncpy( newDriver->fStrName, adapterInfo.Driver, 39 );
strncpy( newDriver->fStrDesc, adapterInfo.Description, 39 );
newDriver->fGuid = adapterInfo.DeviceIdentifier;
newDriver->fMemory = 16 * 1024 * 1024; /// Simulate 16 MB
/// Do the mode and device enumeration for this adapter
IEnumAdapterDevices( pD3D, iAdapter, newDriver );
}
// Cleanup
pD3D->Release();
}
//// IEnumAdapterDevices //////////////////////////////////////////////////////
//
// DirectX: Enumerates all the modes for a given adapter, then using the
// two faked modes for HAL and REF, attaches the modes to each "device" that
// can support them.
void hsGDirect3DTnLEnumerate::IEnumAdapterDevices( IDirect3D9 *pD3D, UINT iAdapter, D3DEnum_DriverInfo *drivInfo )
{
// A bit backwards from DX8... First we have to go through our list of formats and check for validity.
// Then we can enum through the modes for each format.
const DWORD numDeviceTypes = 2;
const TCHAR* strDeviceDescs[] = { "HAL", "REF" };
const D3DDEVTYPE deviceTypes[] = { D3DDEVTYPE_HAL, D3DDEVTYPE_REF };
BOOL *formatWorks = new BOOL[kNumDisplayFormats + 1]; // One for each format
DWORD *behavior = new DWORD[kNumDisplayFormats + 1];
UINT iDevice;
for (iDevice = 0; iDevice < numDeviceTypes; iDevice++)
{
D3DEnum_DeviceInfo *deviceInfo = drivInfo->fDevices.Push();
ZeroMemory(deviceInfo, sizeof(*deviceInfo));
pD3D->GetDeviceCaps(iAdapter, deviceTypes[iDevice], &deviceInfo->fDDCaps);
strncpy(deviceInfo->fStrName, strDeviceDescs[iDevice], 39);
deviceInfo->fDDType = deviceTypes[iDevice];
deviceInfo->fIsHardware = deviceInfo->fDDCaps.DevCaps & D3DDEVCAPS_HWRASTERIZATION;
/// Loop through the formats, checking each against this device to see
/// if it will work. If so, add all modes matching that format
uint8_t iFormat;
for (iFormat = 0; iFormat < kNumDisplayFormats + 1; iFormat++ )
{
// the desktop format gets to be first, everything else is nudged over one.
D3DFORMAT currFormat = (iFormat == 0 ? drivInfo->fDesktopMode.Format : kDisplayFormats[iFormat - 1]);
formatWorks[iFormat] = FALSE;
int bitDepth = IGetDXBitDepth(currFormat);
if (bitDepth == 0)
continue; // Don't like this mode, skip it
/// Can it be used as a render target?
if (FAILED(pD3D->CheckDeviceType(iAdapter, deviceTypes[iDevice],
currFormat,
currFormat,
FALSE)))
continue; // Nope--skip it
if (deviceInfo->fDDCaps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT)
{
/// Confirm that HW vertex processing works on this device
if (deviceInfo->fDDCaps.DevCaps & D3DDEVCAPS_PUREDEVICE)
{
#if 0
behavior[iFormat] = D3DCREATE_HARDWARE_VERTEXPROCESSING |
D3DCREATE_PUREDEVICE;
#else
behavior[iFormat] = D3DCREATE_HARDWARE_VERTEXPROCESSING;
#endif
if (SUCCEEDED(IConfirmDevice(&deviceInfo->fDDCaps, behavior[iFormat],
currFormat)))
{
formatWorks[iFormat] = TRUE;
}
}
if (!formatWorks[iFormat])
{
/// HW vertex & Pure didn't work--just try HW vertex
behavior[iFormat] = D3DCREATE_HARDWARE_VERTEXPROCESSING;
if (SUCCEEDED(IConfirmDevice(&deviceInfo->fDDCaps, behavior[iFormat],
currFormat)))
{
formatWorks[iFormat] = TRUE;
}
}
if (!formatWorks[iFormat])
{
/// HW vertex didn't work--can we do mixed?
behavior[iFormat] = D3DCREATE_MIXED_VERTEXPROCESSING;
if (SUCCEEDED(IConfirmDevice(&deviceInfo->fDDCaps, behavior[iFormat],
currFormat)))
{
formatWorks[iFormat] = TRUE;
}
}
}
if (!formatWorks[iFormat])
{
/// Egads. Try SW vertex processing
behavior[iFormat] = D3DCREATE_SOFTWARE_VERTEXPROCESSING;
if (SUCCEEDED(IConfirmDevice(&deviceInfo->fDDCaps, behavior[iFormat],
currFormat)))
{
formatWorks[iFormat] = TRUE;
}
}
if (formatWorks[iFormat])
{
/// Now go through all the modes. If a given mode has a format that works,
/// add it to the device
UINT numAdapterModes = pD3D->GetAdapterModeCount(iAdapter, currFormat);
DWORD iMode;
for (iMode = 0; iMode < numAdapterModes; iMode++)
{
// TODO: Check for modes that only differ by refresh rate and exclude duplicates.
/// Get the mode attributes
D3DDISPLAYMODE dispMode;
pD3D->EnumAdapterModes(iAdapter, currFormat, iMode, &dispMode);
{
/// Add it to our driver's global mode list
D3DEnum_ModeInfo *modeInfo = drivInfo->fModes.Push();
ZeroMemory( modeInfo, sizeof( *modeInfo ) );
modeInfo->fDDmode = dispMode;
sprintf( modeInfo->fStrDesc, TEXT( "%ld x %ld x %ld" ), dispMode.Width, dispMode.Height, bitDepth );
modeInfo->fBitDepth = bitDepth;
// Add it to the device
modeInfo->fDDBehavior = behavior[ iFormat ];
IFindDepthFormats( pD3D, iAdapter, deviceInfo->fDDType, modeInfo );
IFindFSAATypes( pD3D, iAdapter, deviceInfo->fDDType, modeInfo );
ICheckCubicRenderTargets( pD3D, iAdapter, deviceInfo->fDDType, modeInfo );
deviceInfo->fModes.Append( *modeInfo );
// Special check for the desktop, which we know is the first entry, because we put it there.
if (iFormat == 0)
{
/// Check if the device can window and/or is compatible with the desktop display mode
deviceInfo->fCompatibleWithDesktop = TRUE;
// As of DirectX 9, any device supports windowed mode
//if (deviceInfo->fDDCaps.Caps2 & D3DCAPS2_CANRENDERWINDOWED)
{
deviceInfo->fCanWindow = TRUE;
/// Add a fake mode to represent windowed. Silly, but here for legacy
D3DEnum_ModeInfo *pModeInfo = drivInfo->fModes.Push();
ZeroMemory(pModeInfo, sizeof(*pModeInfo));
pModeInfo->fDDmode = dispMode;
pModeInfo->fDDBehavior = behavior[iFormat];
pModeInfo->fBitDepth = bitDepth;
sprintf(pModeInfo->fStrDesc, TEXT("Windowed"));
pModeInfo->fWindowed = true;
IFindDepthFormats(pD3D, iAdapter, deviceInfo->fDDType, pModeInfo);
IFindFSAATypes(pD3D, iAdapter, deviceInfo->fDDType, pModeInfo);
ICheckCubicRenderTargets(pD3D, iAdapter, deviceInfo->fDDType, pModeInfo);
deviceInfo->fModes.Append( *pModeInfo );
}
}
}
}
}
}
}
delete [] formatWorks;
delete [] behavior;
}
//// IFindDepthFormats ////////////////////////////////////////////////////////
// DirectX: Given a device and mode, find ALL available depth/stencil
// formats and add them to the mode info struct.
bool hsGDirect3DTnLEnumerate::IFindDepthFormats( IDirect3D9 *pD3D, UINT iAdapter, D3DDEVTYPE deviceType,
D3DEnum_ModeInfo *modeInfo )
{
D3DFORMAT formats[] = { D3DFMT_D16, D3DFMT_D24X8, D3DFMT_D32,
D3DFMT_D15S1, D3DFMT_D24X4S4, D3DFMT_D24S8, D3DFMT_UNKNOWN };
/// Try 'em
for( int i = 0; formats[ i ] != D3DFMT_UNKNOWN; i++ )
{
if( SUCCEEDED( pD3D->CheckDeviceFormat( iAdapter, deviceType, modeInfo->fDDmode.Format,
D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_SURFACE,
formats[ i ] ) ) )
{
if( SUCCEEDED( pD3D->CheckDepthStencilMatch( iAdapter, deviceType,
modeInfo->fDDmode.Format, modeInfo->fDDmode.Format, formats[ i ] ) ) )
{
modeInfo->fDepthFormats.Append( formats[ i ] );
}
}
}
return( modeInfo->fDepthFormats.GetCount() > 0 ? true : false );
}
//// IFindFSAATypes ///////////////////////////////////////////////////////////
// DirectX: Given a device and mode, find ALL available multisample types
// and add them to the mode info struct.
bool hsGDirect3DTnLEnumerate::IFindFSAATypes( IDirect3D9 *pD3D, UINT iAdapter, D3DDEVTYPE deviceType,
D3DEnum_ModeInfo *modeInfo )
{
/// Try 'em
for (int type = 2; type <= 16; type++)
{
if (SUCCEEDED(pD3D->CheckDeviceMultiSampleType(iAdapter, deviceType, modeInfo->fDDmode.Format,
modeInfo->fWindowed ? TRUE : FALSE,
(D3DMULTISAMPLE_TYPE)type, NULL)))
{
modeInfo->fFSAATypes.Append((D3DMULTISAMPLE_TYPE)type);
}
}
return (modeInfo->fFSAATypes.GetCount() > 0 ? true : false);
}
//// ICheckCubicRenderTargets /////////////////////////////////////////////////
bool hsGDirect3DTnLEnumerate::ICheckCubicRenderTargets( IDirect3D9 *pD3D, UINT iAdapter, D3DDEVTYPE deviceType,
D3DEnum_ModeInfo *modeInfo )
{
if( SUCCEEDED( pD3D->CheckDeviceFormat( iAdapter, deviceType, modeInfo->fDDmode.Format,
D3DUSAGE_RENDERTARGET, D3DRTYPE_CUBETEXTURE,
modeInfo->fDDmode.Format ) ) )
{
modeInfo->fCanRenderToCubic = true;
return true;
}
modeInfo->fCanRenderToCubic = false;
return false;
}
//// IConfirmDevice ///////////////////////////////////////////////////////////
//
// Nice, encapsulated way of testing for specific caps on a particular device
HRESULT hsGDirect3DTnLEnumerate::IConfirmDevice( D3DCAPS9* pCaps, DWORD dwBehavior,
D3DFORMAT Format )
{
short bits;
bits = IGetDXBitDepth( Format );
if( bits == 16 || bits == 24 || bits == 32 )
return S_OK;
return E_FAIL;
}
//-----------------------------------------------------------------------------
// Name: ~hsGDirect3DTnLEnumerate()
// Desc:
//-----------------------------------------------------------------------------
hsGDirect3DTnLEnumerate::~hsGDirect3DTnLEnumerate()
{
D3DEnum_FreeResources();
}
//-----------------------------------------------------------------------------
// Name: D3DEnum_FreeResources()
// Desc: Frees all resources used for driver enumeration
//-----------------------------------------------------------------------------
VOID hsGDirect3DTnLEnumerate::D3DEnum_FreeResources()
{
}
//-----------------------------------------------------------------------------
// Name: SetEnumeErrorStr()
// Desc:
//-----------------------------------------------------------------------------
void hsGDirect3DTnLEnumerate::SetEnumeErrorStr(const char* s)
{
hsStrncpy(fEnumeErrorStr, s, 128);
}
//// IGetDXBitDepth //////////////////////////////////////////////////////////
//
// From a D3DFORMAT enumeration, return the bit depth associated with it.
// Copied from hsGDirect3DDevice to prevent inclusion of that class in
// the RenderMenu project (for some reason, VC can't figure out we're only
// calling one static function!)
short hsGDirect3DTnLEnumerate::IGetDXBitDepth( D3DFORMAT format )
{
#define ReturnDepth(type, depth) if (format == type) return depth
ReturnDepth(D3DFMT_UNKNOWN, 0);
ReturnDepth(D3DFMT_A8R8G8B8, 32);
ReturnDepth(D3DFMT_X8R8G8B8, 32);
ReturnDepth(D3DFMT_R5G6B5, 16);
ReturnDepth(D3DFMT_X1R5G5B5, 16);
ReturnDepth(D3DFMT_A1R5G5B5, 16);
// Supported by DX9, but we don't currently support it. Can add support if needed.
//ReturnDepth(D3DFMT_A2B10G10R10, 32);
// Unsupported translation format--return 0
return 0;
}
///////////////////////////////////////////////////////////////////////////////
//// Direct3D DeviceSelector Code ///////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
//// IGetD3DCardInfo /////////////////////////////////////////////////////////
// Given two enum structs, strips out and produces the vendor ID, device ID
// and the driver name. Returns true if processed, false otherwise.
bool hsG3DDeviceSelector::IGetD3DCardInfo( hsG3DDeviceRecord &record, // In
void *driverInfo,
void *deviceInfo,
uint32_t *vendorID, uint32_t *deviceID, // Out
char **driverString, char **descString )
{
D3DEnum_DriverInfo *driverD3DInfo = (D3DEnum_DriverInfo *)driverInfo;
D3DEnum_DeviceInfo *deviceD3DInfo = (D3DEnum_DeviceInfo *)deviceInfo;
D3DADAPTER_IDENTIFIER9 *adapterInfo;
adapterInfo = &driverD3DInfo->fAdapterInfo;
/// Print out to our demo data file
plDemoDebugFile::Write( "DeviceSelector detected DX Direct3D device. Info:" );
plDemoDebugFile::Write( " Driver Description", (char *)adapterInfo->Description );
plDemoDebugFile::Write( " Driver Name", (char *)adapterInfo->Driver );
plDemoDebugFile::Write( " Vendor ID", (int32_t)adapterInfo->VendorId );
plDemoDebugFile::Write( " Device ID", (int32_t)adapterInfo->DeviceId );
plDemoDebugFile::Write( " Version", (char *)record.GetDriverVersion() );
plDemoDebugFile::Write( " Memory size (in MB)", record.GetMemoryBytes() / ( 1024 * 1024 ) );
plDemoDebugFile::Write( " Memory size (in bytes)", record.GetMemoryBytes() );
*vendorID = adapterInfo->VendorId;
*deviceID = adapterInfo->DeviceId;
*driverString = adapterInfo->Driver;
*descString = adapterInfo->Description;
return true;
}
//// IInitDirect3D ////////////////////////////////////////////////////////////
bool hsG3DDeviceSelector::IInitDirect3D( void )
{
if( hsGDDrawDllLoad::GetD3DDll() == nil )
{
strcpy( fErrorString, "Cannot load Direct3D driver!" );
return false;
}
Direct3DCreateProc procPtr;
procPtr = (Direct3DCreateProc)GetProcAddress( hsGDDrawDllLoad::GetD3DDll(), "Direct3DCreate9" );
if( procPtr == nil )
{
strcpy( fErrorString, "Cannot load D3D Create Proc!" );
return false;
}
// Create a D3D object to use
IDirect3D9 *pD3D = procPtr( D3D_SDK_VERSION );
if( pD3D == nil )
{
strcpy( fErrorString, "Cannot load DirectX!" );
return false;
}
pD3D->Release();
fErrorString[ 0 ] = 0;
return true;
}
//// ITryDirect3DTnL //////////////////////////////////////////////////////////
void hsG3DDeviceSelector::ITryDirect3DTnL(hsWinRef winRef)
{
hsGDirect3DTnLEnumerate d3dEnum;
int i;
for( i = 0; i < d3dEnum.GetNumDrivers(); i++ )
{
ITryDirect3DTnLDriver(d3dEnum.GetDriver(i));
}
}
//// ITryDirect3DDriver ///////////////////////////////////////////////////////
//
// New DirectX Way
void hsG3DDeviceSelector::ITryDirect3DTnLDriver(D3DEnum_DriverInfo* drivInfo)
{
hsG3DDeviceRecord devRec;
devRec.Clear();
devRec.SetG3DDeviceType( kDevTypeDirect3DTnL );
devRec.SetDriverName( drivInfo->fAdapterInfo.Driver );
devRec.SetDriverDesc( drivInfo->fAdapterInfo.Description );
char buff[ 256 ];
sprintf( buff, "%d.%02d.%02d.%04d",
HIWORD( drivInfo->fAdapterInfo.DriverVersion.u.HighPart ),
LOWORD( drivInfo->fAdapterInfo.DriverVersion.u.HighPart ),
HIWORD( drivInfo->fAdapterInfo.DriverVersion.u.LowPart ),
LOWORD( drivInfo->fAdapterInfo.DriverVersion.u.LowPart ) );
devRec.SetDriverVersion(buff);
devRec.SetMemoryBytes(drivInfo->fMemory);
int i;
for( i = 0; i < drivInfo->fDevices.GetCount(); i++ )
{
/// 9.6.2000 mcn - Changed here so we can do fudging here, rather
/// than passing all the messy driver data to the function
hsG3DDeviceRecord currDevRec = devRec;
/// Done first now, so we can alter the D3D type later
ITryDirect3DTnLDevice( &drivInfo->fDevices[i], currDevRec );
/// Check the vendor ID to see if it's 3dfx (#0x121a). If it is, don't add it.
/// (we don't support 3dfx D3D devices) -mcn
/// 11.25.2000 mcn - Knew this was going to come back and bite me. Now we just
/// append (3dfx) to the end of the device description, so that our latter test
/// can throw it out or not, depending on whether we're "strong".
if( drivInfo->fAdapterInfo.VendorId == 0x121a &&
( currDevRec.GetG3DHALorHEL() == hsG3DDeviceSelector::kHHD3DHALDev ||
currDevRec.GetG3DHALorHEL() == hsG3DDeviceSelector::kHHD3DTnLHalDev ) )
{
if( drivInfo->fAdapterInfo.DeviceId >= 0x00000009 )
{
currDevRec.SetG3DHALorHEL( kHHD3D3dfxVoodoo5Dev );
plDemoDebugFile::Write( " Tagging device as a 3dfx Voodoo5 or above" );
}
else
{
currDevRec.SetG3DHALorHEL( kHHD3D3dfxDev );
plDemoDebugFile::Write( " Tagging device as a non-V5 3dfx card" );
}
}
IFudgeDirectXDevice( currDevRec, (D3DEnum_DriverInfo *)drivInfo, (D3DEnum_DeviceInfo *)&drivInfo->fDevices[ i ] );
if( currDevRec.GetModes().GetCount() )
fRecords.Append( currDevRec );
}
}
//// ITryDirect3DTnLDevice ////////////////////////////////////////////////////
//
// New DirectX Way
void hsG3DDeviceSelector::ITryDirect3DTnLDevice(D3DEnum_DeviceInfo* devInfo, hsG3DDeviceRecord& devRec)
{
devRec.SetDeviceDesc(devInfo->fStrName);
if( devInfo->fDDType == D3DDEVTYPE_REF )
devRec.SetG3DHALorHEL( kHHD3DRefDev );
else if( devInfo->fDDType == D3DDEVTYPE_HAL )
{
if( devInfo->fDDCaps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT )
{
devRec.SetG3DHALorHEL( kHHD3DTnLHalDev );
devRec.SetCap( kCapsHWTransform );
}
else
devRec.SetG3DHALorHEL( kHHD3DHALDev );
}
if( devInfo->fDDCaps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP )
devRec.SetCap( kCapsCubicTextures );
devRec.SetLayersAtOnce( devInfo->fDDCaps.MaxSimultaneousTextures );
if( devInfo->fDDCaps.TextureFilterCaps & D3DPTFILTERCAPS_MIPFLINEAR )
devRec.SetCap( kCapsMipmap );
if( devInfo->fDDCaps.TextureCaps & D3DPTEXTURECAPS_MIPCUBEMAP )
devRec.SetCap( kCapsCubicMipmap );
if( devInfo->fDDCaps.TextureCaps & D3DPTEXTURECAPS_PERSPECTIVE )
devRec.SetCap(kCapsPerspective);
if( devInfo->fIsHardware )
devRec.SetCap( kCapsHardware );
if( devInfo->fDDCaps.RasterCaps & D3DPRASTERCAPS_DITHER )
devRec.SetCap(kCapsDither);
if( devInfo->fDDCaps.RasterCaps & D3DPRASTERCAPS_WBUFFER )
devRec.SetCap(kCapsWBuffer);
if( devInfo->fDDCaps.RasterCaps & D3DPRASTERCAPS_FOGTABLE )
{
devRec.SetCap( kCapsFogLinear );
devRec.SetCap( kCapsFogExp );
devRec.SetCap( kCapsFogExp2 );
devRec.SetCap( kCapsPixelFog );
}
else
{
devRec.SetCap( kCapsFogLinear );
}
if( devInfo->fDDCaps.RasterCaps & D3DPRASTERCAPS_FOGRANGE )
devRec.SetCap( kCapsFogRange );
if( devInfo->fDDCaps.MaxAnisotropy <= 1 )
devRec.SetMaxAnisotropicSamples( 0 );
else
devRec.SetMaxAnisotropicSamples( (uint8_t)devInfo->fDDCaps.MaxAnisotropy );
if (D3DSHADER_VERSION_MAJOR(devInfo->fDDCaps.PixelShaderVersion) > 0)
devRec.SetCap(kCapsPixelShader);
/// Assume these by default
devRec.SetCap( kCapsCompressTextures );
devRec.SetCap( kCapsDoesSmallTextures );
#if 1 // mf - want to leave this one off by default
// if( devInfo->fCanAntialias )
// devRec.SetCap( kCapsAntiAlias );
#endif // mf - want to leave this one off by default
hsG3DDeviceMode devMode;
int i, j;
const struct
{
D3DFORMAT fmt; uint16_t depth;
} depths[] = { { D3DFMT_D16, 0x0010 }, { D3DFMT_D24X8, 0x0018 }, { D3DFMT_D32, 0x0020 },
{ D3DFMT_D15S1, 0x010f }, { D3DFMT_D24X4S4, 0x0418 }, { D3DFMT_D24S8, 0x0818 }, { D3DFMT_UNKNOWN, 0 } };
for( i = 0; i < devInfo->fModes.GetCount(); i++ )
{
D3DEnum_ModeInfo* modeInfo = &devInfo->fModes[i];
devMode.Clear();
devMode.SetWidth( modeInfo->fDDmode.Width );
devMode.SetHeight( modeInfo->fDDmode.Height );
devMode.SetColorDepth( modeInfo->fBitDepth );
if( modeInfo->fCanRenderToCubic )
devMode.SetCanRenderToCubics( true );
else
devMode.SetCanRenderToCubics( false );
for( j = 0; depths[ j ].depth != 0; j++ )
{
if( modeInfo->fDepthFormats.Find( depths[ j ].fmt ) != modeInfo->fDepthFormats.kMissingIndex )
devMode.AddZStencilDepth( depths[ j ].depth );
}
for( j = 2; j <= 16; j++ )
{
if( modeInfo->fFSAATypes.Find( (D3DMULTISAMPLE_TYPE)j ) != modeInfo->fFSAATypes.kMissingIndex )
devMode.AddFSAAType( j );
}
devRec.GetModes().Append( devMode );
}
}

View File

@ -0,0 +1,200 @@
/*==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 hsGDirect3DTnLEnumerate_h
#define hsGDirect3DTnLEnumerate_h
#include "HeadSpin.h"
#include "hsTemplates.h"
//#include "plMemTrackerOff.h"
#include <d3d9.h>
//#include "plMemTrackerOn.h"
//-----------------------------------------------------------------------------
// Name: D3DEnum_ModeInfo
// Desc: Structure to hold information about a display mode. This
// info is stored as a width, height, bpp, and pixelformat within a
// DDSURFACEDESC2.
//-----------------------------------------------------------------------------
struct D3DEnum_ModeInfo
{
D3DDISPLAYMODE fDDmode;
CHAR fStrDesc[40];
BOOL fWindowed;
char fBitDepth;
DWORD fDDBehavior;
hsTArray<D3DFORMAT> fDepthFormats;
hsTArray<D3DMULTISAMPLE_TYPE> fFSAATypes;
BOOL fCanRenderToCubic;
};
//-----------------------------------------------------------------------------
// Name: D3DEnum_DeviceInfo
// Desc: Linked-list structure to hold information about a Direct3D device. The
// primary information recorded here is the D3DDEVICEDESC and a ptr to a
// list of valid display modes.
//-----------------------------------------------------------------------------
struct D3DEnum_DeviceInfo
{
D3DDEVTYPE fDDType;
CHAR fStrName[40];
D3DCAPS9 fDDCaps;
BOOL fCanWindow;
BOOL fCompatibleWithDesktop;
BOOL fIsHardware;
hsTArray<D3DEnum_ModeInfo> fModes;
};
//-----------------------------------------------------------------------------
// Name: D3DEnum_DriverInfo
// Desc: Linked-list structure to hold information about a DirectX driver. The
// info stored is the capability bits for the driver plus a list
// of valid Direct3D devices for the driver. Note: most systems will only
// have one driver. The exception are multi-monitor systems, and systems
// with non-GDI 3D video cards.
//-----------------------------------------------------------------------------
struct D3DEnum_DriverInfo
{
GUID fGuid;
CHAR fStrDesc[40];
CHAR fStrName[40];
unsigned int fMemory;
D3DADAPTER_IDENTIFIER9 fAdapterInfo;
D3DDISPLAYMODE fDesktopMode;
hsTArray<D3DEnum_ModeInfo> fModes;
D3DEnum_ModeInfo* fCurrentMode;
hsTArray<D3DEnum_DeviceInfo> fDevices;
D3DEnum_DeviceInfo* fCurrentDevice;
};
class hsG3DDeviceRecord;
class hsG3DDeviceMode;
class hsGDirect3DTnLEnumerate
{
protected:
HMODULE fDDrawDLL;
char fEnumeErrorStr[128]; // <20>h<EFBFBD><68><EFBFBD>C<EFBFBD>o<EFBFBD>A<EFBFBD>f<EFBFBD>o<EFBFBD>C<EFBFBD>X<EFBFBD>񋓃G<F18B9383><47><EFBFBD>[<5B><><EFBFBD>b<EFBFBD>Z<EFBFBD>[<5B>W<EFBFBD>i<EFBFBD>[<5B>o<EFBFBD>b<EFBFBD>t<EFBFBD>@
hsTArray<D3DEnum_DriverInfo> fDrivers;
D3DEnum_DriverInfo* fCurrentDriver; // The selected DD driver
static short IGetDXBitDepth( D3DFORMAT format );
/// DirectX Helper Functions
void IEnumAdapterDevices( IDirect3D9 *pD3D, UINT iAdapter, D3DEnum_DriverInfo *drivInfo );
bool IFindDepthFormats( IDirect3D9 *pD3D, UINT iAdapter, D3DDEVTYPE deviceType, D3DEnum_ModeInfo *modeInfo );
bool IFindFSAATypes( IDirect3D9 *pD3D, UINT iAdapter, D3DDEVTYPE deviceType, D3DEnum_ModeInfo *modeInfo );
bool ICheckCubicRenderTargets( IDirect3D9 *pD3D, UINT iAdapter, D3DDEVTYPE deviceType, D3DEnum_ModeInfo *modeInfo );
HRESULT IConfirmDevice( D3DCAPS9* pCaps, DWORD dwBehavior, D3DFORMAT format );
static const uint8_t kNumDisplayFormats;
static const D3DFORMAT kDisplayFormats[];
public:
hsGDirect3DTnLEnumerate();
virtual ~hsGDirect3DTnLEnumerate();
VOID D3DEnum_FreeResources();
char* GetErrorString() { return (fEnumeErrorStr[0] ? fEnumeErrorStr : nil); }
HRESULT SelectFromDevMode(const hsG3DDeviceRecord* devRec, const hsG3DDeviceMode* devMode);
HRESULT D3DEnum_SelectDefaultMode(int width, int height, int depth);
HRESULT D3DEnum_SelectDefaultDriver( DWORD dwFlags );
uint32_t GetNumDrivers() { return fDrivers.GetCount(); }
D3DEnum_DriverInfo* GetDriver(int i) { return &fDrivers[i]; }
D3DEnum_DriverInfo* GetCurrentDriver() { return fCurrentDriver; }
D3DEnum_DeviceInfo* GetCurrentDevice() { return GetCurrentDriver() ? GetCurrentDriver()->fCurrentDevice : nil; }
D3DEnum_ModeInfo* GetCurrentMode() { return GetCurrentDevice() ? GetCurrentDriver()->fCurrentMode : nil; }
void SetCurrentDriver(D3DEnum_DriverInfo* d) { fCurrentDriver = d; }
void SetCurrentDevice(D3DEnum_DeviceInfo* d) { hsAssert(GetCurrentDriver(), "Set Driver first"); GetCurrentDriver()->fCurrentDevice = d; }
void SetCurrentMode(D3DEnum_ModeInfo* m) { hsAssert(GetCurrentDriver(), "Set Driver first"); GetCurrentDriver()->fCurrentMode = m; }
char* GetEnumeErrorStr() { return fEnumeErrorStr; }
void SetEnumeErrorStr(const char* s);
};
//-----------------------------------------------------------------------------
// Name: D3DEnum_SelectDefaultDriver()
// Desc: Picks a driver based on a set of passed in criteria.
//-----------------------------------------------------------------------------
#define D3DENUM_SOFTWAREONLY 0x00000001
#define D3DENUM_FULLSCREENONLY 0x00000002
#define D3DENUM_RGBEMULATION 0x00000004
#define D3DENUM_REFERENCERAST 0x00000008
#define D3DENUM_PRIMARYHAL 0x00000010
#define D3DENUM_SECONDARYHAL 0x00000020
#define D3DENUM_TNLHAL 0x00000040
#define D3DENUM_CANWINDOW 0x00000080
#define D3DENUM_MASK 0x000000ff
//-----------------------------------------------------------------------------
// Error codes
//-----------------------------------------------------------------------------
#define D3DENUMERR_ENUMERATIONFAILED 0x81000001 // Enumeration failed
#define D3DENUMERR_SUGGESTREFRAST 0x81000002 // Suggest using the RefRast
#define D3DENUMERR_NOCOMPATIBLEDEVICES 0x81000003 // No devices were found that
// meet the app's desired
// capabilities
#define D3DENUMERR_NODIRECTDRAW 0x81000004 // DDraw couldn't initialize
#define D3DENUMERR_NOTFOUND 0x81000005 // Requested device not found
#endif //hsGDirect3DTnLEnumerate_h

View File

@ -0,0 +1,97 @@
/*==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==*/
///////////////////////////////////////////////////////////////////////////////
// //
// plDXLightRef.h - Hardware Light DeviceRef Definition //
// Cyan, Inc. //
// //
//// Version History //////////////////////////////////////////////////////////
// //
// 4.25.2001 mcn - Created. //
// //
///////////////////////////////////////////////////////////////////////////////
#ifndef _plDXLightRef_h
#define _plDXLightRef_h
#include "hsMatrix44.h"
#include "hsGeometry3.h"
#include "hsTemplates.h"
#include "plDXDeviceRef.h"
//// Definition ///////////////////////////////////////////////////////////////
class plLightInfo;
class plDXLightSettings;
class plDXLightRef : public plDXDeviceRef
{
public:
plLightInfo *fOwner;
D3DLIGHT9 fD3DInfo;
uint32_t fD3DIndex;
float fScale;
plDXLightSettings *fParentSettings;
IDirect3DDevice9 *fD3DDevice;
void Link( plDXLightRef **back ) { plDXDeviceRef::Link( (plDXDeviceRef **)back ); }
plDXLightRef *GetNext( void ) { return (plDXLightRef *)fNext; }
plDXLightRef()
{
fOwner = nil;
fParentSettings = nil;
fD3DDevice = nil;
fD3DIndex = -1;
fScale = 1.f;
}
virtual ~plDXLightRef();
void Release( void );
void UpdateD3DInfo( IDirect3DDevice9 *dev, plDXLightSettings *settings );
};
#endif // _plDXLightRef_h

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,842 @@
/*==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 "plPipeline/plFogEnvironment.h"
#include "plPipeline/hsG3DDeviceSelector.h"
#include "hsGeometry3.h"
#include "hsTemplates.h"
#include "hsColorRGBA.h"
#include "plPipeline/hsGDeviceRef.h"
#include "hsPoint2.h"
class plAccessSpan;
class plAuxSpan;
class plVertexSpan;
#include "plPipeline/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 bool 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_t 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,
kCapsWBuffer = 0x00000200,
kCapsTexBoundToStage = 0x00000400,
kCapsDither = 0x00000800,
kCapsLODWatch = 0x00001000,
kCapsFSAntiAlias = 0x00002000,
kCapsLuminanceTextures = 0x00004000,
kCapsDoesSmallTextures = 0x00008000,
kCapsDoesWFog = 0x00010000,
kCapsPixelFog = 0x00020000,
kCapsHasBadYonStuff = 0x00040000,
kCapsNoKindaSmallTexs = 0x00080000,
kCapsNpotTextures = 0x00100000,
kCapsCubicTextures = 0x00200000,
kCapsCubicMipmap = 0x00400000
};
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_t fVtxRefTime;
uint32_t fNextDynVtx;
uint32_t fDynVtxSize;
IDirect3DVertexBuffer9* fDynVtxBuff;
bool fManagedAlloced;
bool fAllocUnManaged;
// States
plDXGeneralSettings fSettings;
plDXTweakSettings fTweaks;
plDXStencilSettings fStencil;
bool fDeviceLost;
bool 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_t fCurrLayerIdx, fCurrNumLayers, fCurrRenderLayer;
uint32_t fCurrLightingMethod; // Based on plSpan flags
D3DCULL fCurrCullMode;
hsGMatState fMatOverOn;
hsGMatState fMatOverOff;
hsTArray<hsGMaterial*> fOverrideMat;
hsGMaterial* fHoldMat;
bool fCurrD3DLiteState;
hsMatrix44 fBumpDuMatrix;
hsMatrix44 fBumpDvMatrix;
hsMatrix44 fBumpDwMatrix;
hsTArray<plLayerInterface*> fOverLayerStack;
plLayerInterface* fOverBaseLayer;
plLayerInterface* fOverAllLayer;
hsTArray<plLayerInterface*> fPiggyBackStack;
int32_t fMatPiggyBacks;
int32_t 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 ];
bool fLayerTransform[ 8 ];
float fLayerLODBias[ 8 ];
uint32_t fLayerUVWSrcs[ 8 ];
uint32_t fLayerXformFlags[ 8 ];
uint32_t fLastEndingStage;
bool fTexturing;
bool fForceMatHandle;
uint32_t fInSceneDepth;
uint32_t fTextUseTime; // inc'd every frame - stat gather only
static uint32_t fTexManaged;
static uint32_t fTexUsed;
static uint32_t fVtxManaged;
static uint32_t fVtxUsed;
uint32_t fEvictTime;
uint32_t fManagedSeen;
uint32_t fManagedCutoff;
double fTime; // World time.
uint32_t fFrame; // inc'd every time the camera moves.
uint32_t fRenderCnt; // inc'd every begin scene.
// View stuff
plDXViewSettings fView;
hsBitVector fDebugFlags;
uint32_t 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_t fRenderTargetNext[kMaxRenderTargetNext];
plDXTextureRef* fULutTextureRef;
plRenderTarget* fBlurScratchRTs[kMaxRenderTargetNext];
plRenderTarget* fBlurDestRTs[kMaxRenderTargetNext];
IDirect3DVertexBuffer9* fBlurVBuffers[kMaxRenderTargetNext];
uint32_t fBlurVSHandle;
hsTArray<plClothingOutfit*> fClothingOutfits;
hsTArray<plClothingOutfit*> fPrevClothingOutfits;
// Debug stuff
plDrawableSpans *fBoundsSpans;
hsGMaterial *fBoundsMat;
hsTArray<uint32_t> fBSpansToDelete;
plStatusLogDrawer *fLogDrawer;
bool fVSync;
bool fForceDeviceReset;
void IBeginAllocUnManaged();
void IEndAllocUnManaged();
void ICheckTextureUsage();
void ICheckVtxUsage();
inline void ICheckVBUsage(plDXVertexBufferRef* vRef);
bool IRefreshDynVertices(plGBufferGroup* group, plDXVertexBufferRef* vRef);
bool ICheckAuxBuffers(const plAuxSpan* span);
bool ICheckDynBuffers(plDrawableSpans* drawable, plGBufferGroup* group, const plSpan* span);
void ICheckStaticVertexBuffer(plDXVertexBufferRef* vRef, plGBufferGroup* owner, uint32_t idx);
void ICheckIndexBuffer(plDXIndexBufferRef* iRef);
void IFillStaticVertexBufferRef(plDXVertexBufferRef *ref, plGBufferGroup *group, uint32_t idx);
void IFillVolatileVertexBufferRef(plDXVertexBufferRef* ref, plGBufferGroup* group, uint32_t idx);
void IFillIndexBufferRef(plDXIndexBufferRef* iRef, plGBufferGroup* owner, uint32_t idx);
void ISetupVertexBufferRef(plGBufferGroup* owner, uint32_t idx, plDXVertexBufferRef* vRef);
void ISetupIndexBufferRef(plGBufferGroup* owner, uint32_t idx, plDXIndexBufferRef* iRef);
void ICreateDynamicBuffers();
void IReleaseDynamicBuffers();
void IAddBoundsSpan( plDrawableSpans *ice, const hsBounds3Ext *bounds, uint32_t bndColor = 0xffff0000 );
void IAddNormalsSpan( plDrawableSpans *ice, plIcicle *span, plDXVertexBufferRef *vRef, uint32_t bndColor );
// Rendering
bool IFlipSurface();
long IGetBufferD3DFormat(uint8_t format) const;
uint32_t IGetBufferFormatSize(uint8_t format) const;
void IGetVisibleSpans( plDrawableSpans* drawable, hsTArray<int16_t>& visList, plVisMgr* visMgr );
void IRenderSpans( plDrawableSpans *ice, const hsTArray<int16_t>& visList );
bool ILoopOverLayers(const plRenderPrimFunc& render, hsGMaterial* material, const plSpan& span);
void IRenderBufferSpan( const plIcicle& span,
hsGDeviceRef *vb, hsGDeviceRef *ib,
hsGMaterial *material,
uint32_t vStart, uint32_t vLength, uint32_t iStart, uint32_t 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, float scale);
void ICalcLighting( const plLayerInterface *currLayer, const plSpan *currSpan );
void IDisableSpanLights();
void IRestoreSpanLights();
void ISelectLights( plSpan *span, int numLights, bool proj );
void IEnableLights( plSpan *span );
void IMakeLightLists(plVisMgr* visMgr);
void ICheckLighting(plDrawableSpans* drawable, hsTArray<int16_t>& 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);
bool ISkipBumpMap(hsGMaterial* newMat, uint32_t& layer, const plSpan* currSpan) const;
void ISetBumpMatrices(const plLayerInterface* layer, const plSpan* span);
const hsMatrix44& IGetBumpMatrix(uint32_t miscFlags) const;
// Materials
const hsGMatState& ICompositeLayerState(int which, plLayerInterface* layer);
int32_t IHandleMaterial(hsGMaterial* newMat, uint32_t which, const plSpan* currSpan);
void IHandleFirstTextureStage( plLayerInterface* layer );
void IHandleShadeMode();
void IHandleZMode();
void IHandleMiscMode();
void IHandleTextureStage(uint32_t stage, plLayerInterface* layer);
void IHandleFirstStageBlend();
void IHandleBumpEnv(int stage, uint32_t 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_t stage);
uint32_t ILayersAtOnce(hsGMaterial* mat, uint32_t which);
bool ICanEatLayer(plLayerInterface* lay);
void ISetLayer(uint32_t 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 bool StencilEnable( bool enable );
virtual void StencilSetCompareFunc( uint8_t func, uint32_t refValue );
virtual void StencilSetMask( uint32_t mask, uint32_t writeMask );
virtual void StencilSetOps( uint8_t passOp, uint8_t failOp, uint8_t passButZFailOp );
virtual bool 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_t& texSize );
void IFormatTextureData( uint32_t formatType, uint32_t numPix, hsRGBAColor32* const src, void *dst );
void *IGetPixelScratch( uint32_t size );
hsGDeviceRef *IMakeCubicTextureRef( plLayerInterface* layer, plCubicEnvironmap *cubic );
bool IProcessMipmapLevels( plMipmap *mipmap, uint32_t &numLevels,
uint32_t *&levelSizes, uint32_t &totalSize,
uint32_t &numPixels, void *&textureData, bool noMip );
IDirect3DTexture9 *IMakeD3DTexture( plDXTextureRef *ref, D3DFORMAT formatType );
IDirect3DCubeTexture9 *IMakeD3DCubeTexture( plDXTextureRef *ref, D3DFORMAT formatType );
// Visualization of active occluders
void IMakeOcclusionSnap();
bool IAvatarSort(plDrawableSpans* d, const hsTArray<int16_t>& visList);
void IBlendVertsIntoBuffer( plSpan* span,
hsMatrix44* matrixPalette, int numMatrices,
const uint8_t *src, uint8_t format, uint32_t srcStride,
uint8_t *dest, uint32_t destStride, uint32_t count, uint16_t localUVWChans )
{ blend_vert_buffer.call(span, matrixPalette, numMatrices, src, format, srcStride, dest, destStride, count, localUVWChans); };
bool ISoftwareVertexBlend( plDrawableSpans* drawable, const hsTArray<int16_t>& 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 );
bool 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_t v);
bool IFindDepthFormat(D3DPRESENT_PARAMETERS& params);
bool IFindCompressedFormats();
bool IFindLuminanceFormats();
bool ITextureFormatAllowed( D3DFORMAT format );
void ISetCurrentDriver( D3DEnum_DriverInfo *driv );
void ISetCurrentDevice( D3DEnum_DeviceInfo *dev );
void ISetCurrentMode( D3DEnum_ModeInfo *mode );
bool ICreateMaster();
bool ICreateDevice(bool windowed);
bool ICreateNormalSurfaces();
bool ICreateDeviceObjects();
void IReleaseDeviceObjects();
bool ICreateDynDeviceObjects();
void IReleaseDynDeviceObjects();
void IReleaseShaders();
bool IResetDevice();
// View and clipping
void ISetViewport();
void IUpdateViewVectors() const;
void IRefreshCullTree();
void ISetAnisotropy(bool 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(bool flip=false);
bool inline IIsViewLeftHanded();
bool IGetClearViewPort(D3DRECT& r);
plViewTransform& IGetViewTransform() { return fView.fTransform; }
void IUpdateViewFlags();
void ISetupTransforms(plDrawableSpans* drawable, const plSpan& span, hsMatrix44& lastL2W);
// Plate management
friend class plDXPlateManager;
friend class plBinkPlayer;
void IDrawPlate( plPlate *plate );
void ISetRenderTarget( plRenderTarget *target );
bool IPrepRenderTargetInfo( plRenderTarget *owner, D3DFORMAT &surfFormat,
D3DFORMAT &depthFormat, D3DRESOURCETYPE &resType );
bool 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();
bool IPrepShadowCaster(const plShadowCaster* caster);
void IRenderShadowCasterSpan(plShadowSlave* slave, plDrawableSpans* drawable, const plIcicle& span);
void ISetupShadowCastTextureStages(plShadowSlave* slave);
bool IRenderShadowCaster(plShadowSlave* slave);
void ISetupShadowLight(plShadowSlave* slave);
plDXLightRef* INextShadowLight(plShadowSlave* slave);
bool IPushShadowCastState(plShadowSlave* slave);
bool IPopShadowCastState(plShadowSlave* slave);
plDXTextureRef* IGetULutTextureRef();
bool ICreateBlurVBuffers();
void IReleaseBlurVBuffers();
void IMakeRenderTargetPools();
void IResetRenderTargetPools();
plRenderTarget* IFindRenderTarget(uint32_t& w, uint32_t& h, bool ortho);
void IReleaseRenderTargetPools();
// Selection
void IAttachSlaveToReceivers(int iSlave, plDrawableSpans* drawable, const hsTArray<int16_t>& visList);
void IAttachShadowsToReceivers(plDrawableSpans* drawable, const hsTArray<int16_t>& visList);
bool IAcceptsShadow(const plSpan* span, plShadowSlave* slave);
bool 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)
bool ISetBlurQuadToRender(plRenderTarget* smap);
void IRenderBlurBackToShadowMap(plRenderTarget* smap, plRenderTarget* scratch, plRenderTarget* dst);
void IRenderBlurFromShadowMap(plRenderTarget* scratchRT, plRenderTarget* smap, float scale);
void IBlurSetRenderTarget(plRenderTarget* rt);
int IGetScratchRenderTarget(plRenderTarget* smap);
void IBlurShadowMap(plShadowSlave* slave);
// Avatar Texture Rendering
double fAvRTShrinkValidSince;
hsTArray<plRenderTarget*> fAvRTPool;
uint16_t fAvRTWidth;
uint32_t fAvNextFreeRT;
void IFillAvRTPool();
bool IFillAvRTPool(uint16_t numRTs, uint16_t width); // Returns true if we successfully filled the pool. Otherwise cleans up.
void IReleaseAvRTPool();
plRenderTarget* IGetNextAvRT();
void IFreeAvRT(plRenderTarget* tex);
void IPreprocessAvatarTextures();
void IDrawClothingQuad(float x, float y, float w, float h, float uOff, float 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 bool PreRender(plDrawable* drawable, hsTArray<int16_t>& visList, plVisMgr* visMgr=nil);
virtual bool PrepForRender(plDrawable* drawable, hsTArray<int16_t>& visList, plVisMgr* visMgr=nil);
virtual void Render(plDrawable* d, const hsTArray<int16_t>& visList);
virtual void Draw(plDrawable* d);
virtual void PushRenderRequest(plRenderRequest* req);
virtual void PopRenderRequest(plRenderRequest* req);
void ResetDisplayDevice(int Width, int Height, int ColorDepth, bool Windowed, int NumAASamples, int MaxAnisotropicSamples, bool VSync = false );
virtual void ClearRenderTarget( plDrawable* d );
virtual void ClearRenderTarget( const hsColorRGBA* col = nil, const float* depth = nil );
virtual void SetClear(const hsColorRGBA* col=nil, const float* depth=nil);
virtual hsColorRGBA GetClearColor() const;
virtual float GetClearDepth() const;
virtual hsGDeviceRef* MakeRenderTargetRef( plRenderTarget *owner );
virtual hsGDeviceRef* SharedRenderTargetRef(plRenderTarget* sharer, plRenderTarget *owner);
virtual void PushRenderTarget( plRenderTarget *target );
virtual plRenderTarget* PopRenderTarget();
virtual bool BeginRender();
virtual bool EndRender();
virtual void RenderScreenElements();
virtual bool BeginDrawable(plDrawable* d);
virtual bool EndDrawable(plDrawable* d);
virtual void BeginVisMgr(plVisMgr* visMgr);
virtual void EndVisMgr(plVisMgr* visMgr);
virtual bool IsFullScreen() const { return fSettings.fFullscreen; }
virtual uint32_t Width() const { return fView.fTransform.GetViewPortWidth(); }
virtual uint32_t Height() const { return fView.fTransform.GetViewPortHeight(); }
virtual uint32_t ColorDepth() const { return fSettings.fColorDepth; }
virtual void Resize( uint32_t width, uint32_t height );
// Culling. Might be used in Update before bothering to do any serious computation.
virtual bool TestVisibleWorld(const hsBounds3Ext& wBnd);
virtual bool TestVisibleWorld(const plSceneObject* sObj);
virtual bool HarvestVisible(plSpaceTree* space, hsTArray<int16_t>& visList);
virtual bool SubmitOccluders(const hsTArray<const plCullPoly*>& polyList);
// Debug flags
virtual void SetDebugFlag( uint32_t flag, bool on );
virtual bool IsDebugFlagSet( uint32_t flag ) const;
// These are also only for debugging.
virtual void SetMaxCullNodes(uint16_t n) { fView.fCullMaxNodes = n; }
virtual uint16_t GetMaxCullNodes() const { return fView.fCullMaxNodes; }
virtual bool CheckResources();
virtual void LoadResources(); // Tells us where it's a good time to load in unmanaged resources.
// Properties
virtual void SetProperty( uint32_t prop, bool on ) { on ? fSettings.fProperties |= prop : fSettings.fProperties &= ~prop; }
virtual bool GetProperty( uint32_t prop ) const { return ( fSettings.fProperties & prop ) ? true : false; }
virtual uint32_t GetMaxLayersAtOnce() const { return fSettings.fMaxLayersAtOnce; }
// Drawable type mask
virtual void SetDrawableTypeMask( uint32_t mask ) { fView.fDrawableTypeMask = mask; }
virtual uint32_t GetDrawableTypeMask() const { return fView.fDrawableTypeMask; }
virtual void SetSubDrawableTypeMask( uint32_t mask ) { fView.fSubDrawableTypeMask = mask; }
virtual uint32_t GetSubDrawableTypeMask() const { return fView.fSubDrawableTypeMask; }
// Create a debug text font object
virtual plTextFont *MakeTextFont( char *face, uint16_t size );
// Create and/or Refresh geometry buffers
virtual void CheckVertexBufferRef(plGBufferGroup* owner, uint32_t idx);
virtual void CheckIndexBufferRef(plGBufferGroup* owner, uint32_t idx);
virtual bool OpenAccess(plAccessSpan& dst, plDrawableSpans* d, const plVertexSpan* span, bool readOnly);
virtual bool CloseAccess(plAccessSpan& acc);
virtual void CheckTextureRef(plLayerInterface* lay);
static void FreeManagedTexture(uint32_t sz) { hsAssert(fTexManaged >= sz, "Freeing mem we don't have"); fTexManaged -= sz; }
static void AllocManagedTexture(uint32_t sz) { fTexManaged += sz; }
static void FreeManagedVertex(uint32_t sz) { hsAssert(fVtxManaged >= sz, "Freeing mem we don't have"); fVtxManaged -= sz; }
static void AllocManagedVertex(uint32_t sz) { fVtxManaged += sz; }
#ifndef PLASMA_EXTERNAL_RELEASE
static void ProfilePoolMem(D3DPOOL poolType, uint32_t size, bool add, const 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(float& fovX, float& fovY) const;
virtual void SetFOV(float fovX, float fovY);
virtual void GetSize(float& width, float& height) const;
virtual void SetSize(float width, float height);
virtual void GetDepth(float& hither, float& yon) const;
virtual void SetDepth(float hither, float yon);
virtual float GetZBiasScale() const;
virtual void SetZBiasScale(float 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_t stride, int32_t *scrX, int32_t *scrY,
float dist, uint32_t 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, bool onAllLayers = false);
virtual plLayerInterface* RemoveLayerInterface(plLayerInterface* li, bool onAllLayers = false);
virtual plLayerInterface* PushPiggyBackLayer(plLayerInterface* li);
virtual plLayerInterface* PopPiggyBackLayer(plLayerInterface* li);
virtual uint32_t GetMaterialOverrideOn(hsGMatState::StateIdx category) const;
virtual uint32_t GetMaterialOverrideOff(hsGMatState::StateIdx category) const;
virtual hsGMatState PushMaterialOverride(const hsGMatState& state, bool on);
virtual hsGMatState PushMaterialOverride(hsGMatState::StateIdx cat, uint32_t which, bool on);
virtual void PopMaterialOverride(const hsGMatState& restore, bool on);
virtual const hsGMatState& GetMaterialOverride(bool 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 bool SetGamma(float eR, float eG, float eB);
virtual bool SetGamma(const uint16_t* const tabR, const uint16_t* const tabG, const uint16_t* const tabB);
virtual bool CaptureScreen( plMipmap *dest, bool flipVertical = false, uint16_t desiredWidth = 0, uint16_t desiredHeight = 0 );
virtual plMipmap* ExtractMipMap(plRenderTarget* targ);
/// Error handling
virtual const char *GetErrorString();
bool 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);
// CPU-optimized functions
protected:
typedef void(*blend_vert_buffer_ptr)(plSpan*, hsMatrix44*, int, const uint8_t *, uint8_t , uint32_t, uint8_t *, uint32_t, uint32_t, uint16_t);
static hsFunctionDispatcher<blend_vert_buffer_ptr> blend_vert_buffer;
};
//// 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

View File

@ -0,0 +1,163 @@
/*==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==*/
#include "HeadSpin.h"
#include "hsWindows.h"
#include <D3d9.h>
#include <D3dx9core.h>
#include "plDXPixelShader.h"
#include "plSurface/plShader.h"
#include "plDXPipeline.h"
plDXPixelShader::plDXPixelShader(plShader* owner)
: plDXShader(owner), fHandle(nil)
{
}
plDXPixelShader::~plDXPixelShader()
{
Release();
}
void plDXPixelShader::Release()
{
ReleaseObject(fHandle);
fHandle = nil;
fPipe = nil;
ISetError(nil);
}
bool plDXPixelShader::VerifyFormat(uint8_t format) const
{
return (fOwner->GetInputFormat() & format) == fOwner->GetInputFormat();
}
IDirect3DPixelShader9 *plDXPixelShader::GetShader(plDXPipeline* pipe)
{
HRESULT hr = S_OK;
if ( !fHandle )
{
if( FAILED(hr = ICreate(pipe)) )
return nil;
}
if( FAILED(hr = ISetConstants(pipe)) )
return nil;
return fHandle;
}
HRESULT plDXPixelShader::ICreate(plDXPipeline* pipe)
{
fHandle = nil; // in case something goes wrong.
fPipe = nil;
ISetError(nil);
#ifdef HS_DEBUGGING
DWORD flags = D3DXSHADER_DEBUG | D3DXSHADER_SKIPOPTIMIZATION;
#else // HS_DEBUGGING
DWORD flags = 0;
#endif // HS_DEBUGGING
DWORD* shaderCodes = nil;
HRESULT hr = S_OK;
if( plShaderTable::LoadFromFile() || !fOwner->GetDecl()->GetCodes() )
{
if( fOwner->GetDecl()->GetFileName() )
{
LPD3DXBUFFER compiledShader = nil;
LPD3DXBUFFER compilationErrors = nil;
hr = D3DXAssembleShaderFromFile(
fOwner->GetDecl()->GetFileName(),
NULL, NULL, flags,
&compiledShader,
&compilationErrors);
if( FAILED(hr) )
{
return IOnError(hr, compilationErrors ? (char*)compilationErrors->GetBufferPointer() : "File not found");
}
shaderCodes = (DWORD*)(compiledShader->GetBufferPointer());
}
}
if( !shaderCodes )
{
shaderCodes = (DWORD*)(fOwner->GetDecl()->GetCodes());
}
if( !shaderCodes )
return IOnError(-1, "No file and no compiled codes");
hr = pipe->GetD3DDevice()->CreatePixelShader(shaderCodes, &fHandle);
if( FAILED(hr) )
{
return IOnError(hr, "Error on CreatePixelShader");
}
hsAssert(fHandle, "No error, but no pixel shader handle. Grrrr.");
fPipe = pipe;
return S_OK;
}
HRESULT plDXPixelShader::ISetConstants(plDXPipeline* pipe)
{
hsAssert(fHandle, "Pixel shader called to set constants without initialization");
if( fOwner->GetNumConsts() )
{
HRESULT hr = pipe->GetD3DDevice()->SetPixelShaderConstantF(0,
(float*)fOwner->GetConstBasePtr(),
fOwner->GetNumConsts());
if( FAILED(hr) )
return IOnError(hr, "Error setting constants");
}
return S_OK;
}

View File

@ -0,0 +1,72 @@
/*==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 plDXPixelShader_inc
#define plDXPixelShader_inc
#include "plDXShader.h"
class plShader;
class plDXPipeline;
struct IDirect3DPixelShader9;
class plDXPixelShader : public plDXShader
{
virtual HRESULT ICreate(plDXPipeline* pipe); // On error, sets error string.
virtual HRESULT ISetConstants(plDXPipeline* pipe);
IDirect3DPixelShader9 *fHandle;
public:
plDXPixelShader(plShader* owner);
virtual ~plDXPixelShader();
void Release();
void Link(plDXPixelShader** back) { plDXDeviceRef::Link((plDXDeviceRef**)back); }
bool VerifyFormat(uint8_t format) const;
IDirect3DPixelShader9 *GetShader(plDXPipeline* pipe);
};
#endif // plDXPixelShader_inc

View File

@ -0,0 +1,105 @@
/*==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==*/
///////////////////////////////////////////////////////////////////////////////
// //
// plDXRenderTargetRef.h - RenderTarget DeviceRef Definitions //
// Cyan, Inc. //
// //
//// Version History //////////////////////////////////////////////////////////
// //
// 7.19.2001 mcn - Created. //
// //
///////////////////////////////////////////////////////////////////////////////
#ifndef _plDXRenderTargetRef_h
#define _plDXRenderTargetRef_h
#include "hsMatrix44.h"
#include "hsTemplates.h"
#include "plDXTextureRef.h"
//// Definition ///////////////////////////////////////////////////////////////
class plRenderTarget;
class plDXRenderTargetRef: public plDXTextureRef
{
public:
IDirect3DSurface9 *fD3DColorSurface;
IDirect3DSurface9 *fD3DDepthSurface;
bool fReleaseDepth;
void Link( plDXRenderTargetRef **back ) { plDXDeviceRef::Link( (plDXDeviceRef **)back ); }
plDXRenderTargetRef *GetNext( void ) { return (plDXRenderTargetRef *)fNext; }
plDXRenderTargetRef( D3DFORMAT tp, uint32_t ml, plRenderTarget *owner, bool releaseDepthOnDelete = true );
plDXRenderTargetRef& Set( D3DFORMAT tp, uint32_t ml, plRenderTarget *owner );
virtual void SetOwner( plRenderTarget *targ ) { fOwner = (plBitmap *)targ; }
void SetTexture( IDirect3DSurface9 *surface, IDirect3DSurface9 *depth );
void SetTexture( IDirect3DTexture9 *surface, IDirect3DSurface9 *depth );
void SetTexture( IDirect3DCubeTexture9 *surface, IDirect3DSurface9 *depth );
IDirect3DSurface9 *GetColorSurface( void ) const
{
if( fD3DTexture != nil )
{
IDirect3DSurface9* psurf;
((IDirect3DTexture9*)fD3DTexture)->GetSurfaceLevel(0, &psurf);
if( psurf )
psurf->Release();
return psurf;
}
return fD3DColorSurface;
}
virtual ~plDXRenderTargetRef();
void Release( void );
};
#endif // _plDXRenderTargetRef_h

View File

@ -0,0 +1,301 @@
/*==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==*/
///////////////////////////////////////////////////////////////////////////////
// //
// plDXSettings - Header for the various settings groups for plDXPipeline //
// Cyan, Inc. //
// //
//// Version History //////////////////////////////////////////////////////////
// //
// 4.25.2001 mcn - Created. //
// //
///////////////////////////////////////////////////////////////////////////////
#ifndef _plDXSettings_h
#define _plDXSettings_h
#include "hsMatrix44.h"
#include "plPipeline/plFogEnvironment.h"
#include "hsGeometry3.h"
#include "hsTemplates.h"
#include "hsColorRGBA.h"
#include "hsBitVector.h"
#include "plPipeline/plStencil.h"
#include "hsPoint2.h"
#include "plPipeline/plCullTree.h"
#include "plPipeline/hsWinRef.h"
#include "plPipeline/plViewTransform.h"
//// General Settings /////////////////////////////////////////////////////////
class plRenderRequest;
class plRenderTarget;
struct IDirect3DSurface9;
class plDXDeviceRef;
class plDXVertexBufferRef;
class plDXIndexBufferRef;
class plDXViewSettings
{
public:
uint32_t fRenderState;
plRenderRequest* fRenderRequest;
uint32_t fDrawableTypeMask;
uint32_t fSubDrawableTypeMask;
DWORD fClearColor;
float fClearDepth;
plFogEnvironment fDefaultFog;
plCullTree fCullTree;
bool fCullTreeDirty;
uint16_t fCullMaxNodes;
enum XformResets
{
kResetProjection = 0x01,
kResetCamera = 0x02,
kResetL2W = 0x04,
kResetAll = 0x07
};
uint8_t fXformResetFlags;
bool fLocalToWorldLeftHanded;
bool fWorldToCamLeftHanded;
mutable hsVector3 fDirection;
mutable hsVector3 fUp;
mutable hsVector3 fAcross;
hsPoint3 fWorldPos;
mutable bool fViewVectorsDirty;
hsMatrix44 fLocalToWorld;
hsMatrix44 fWorldToLocal;
const hsMatrix44& GetLocalToWorld() const { return fLocalToWorld; }
const hsMatrix44& GetWorldToLocal() const { return fWorldToLocal; }
plViewTransform fTransform;
const hsMatrix44& GetWorldToCamera() const { return fTransform.GetWorldToCamera(); }
const hsMatrix44& GetCameraToWorld() const { return fTransform.GetCameraToWorld(); }
bool IsPerspective() const { return fTransform.GetPerspective(); }
void Reset();
};
class plDXGeneralSettings
{
public:
bool fFullscreen;
hsWinRef fHWnd;
uint32_t fColorDepth;
uint8_t fNumAASamples;
uint32_t fD3DCaps, fBoardKluge, fStageEnd;
uint32_t fMaxNumLights;
uint32_t fMaxNumProjectors;
uint32_t fMaxLayersAtOnce;
uint32_t fMaxPiggyBacks;
int32_t fBoundsDrawLevel;
uint32_t fProperties;
DWORD fClearColor;
uint8_t fMaxAnisotropicSamples;
D3DPRESENT_PARAMETERS fPresentParams;
bool fVeryAnnoyingTextureInvalidFlag;
bool fNoGammaCorrect;
int fMaxUVWSrc;
bool fCantProj;
bool fLimitedProj;
bool fBadManaged;
bool fShareDepth;
bool fCurrAnisotropy;
bool fIsIntel;
IDirect3DSurface9 *fCurrD3DMainSurface;
IDirect3DSurface9 *fCurrD3DDepthSurface;
hsTArray<plDXViewSettings> fViewStack; // One for the main view, then one for each rendertarget
hsTArray<plRenderTarget *> fRenderTargets;
plRenderTarget *fCurrRenderTarget;
plRenderTarget *fCurrBaseRenderTarget;
plDXDeviceRef *fCurrRenderTargetRef;
plDXVertexBufferRef *fCurrVertexBuffRef;
plDXIndexBufferRef *fCurrIndexBuffRef;
uint32_t fOrigWidth, fOrigHeight;
IDirect3DVertexShader9 *fCurrVertexShader;
IDirect3DPixelShader9 *fCurrPixelShader;
DWORD fCurrFVFFormat;
HRESULT fDXError;
char fErrorStr[ 256 ];
void Reset( void );
};
//// Tweak Settings ///////////////////////////////////////////////////////////
class plDXTweakSettings
{
public:
float fDefaultPerspLayerScale;
float fPerspLayerScale;
float fPerspLayerTrans;
float fDefaultLODBias;
float fFogExpApproxStart;
float fFogExp2ApproxStart;
float fFogEndBias;
float fExp2FogKnee;
float fExp2FogKneeVal;
float fExpFogKnee;
float fExpFogKneeVal;
void Reset( void )
{
fDefaultPerspLayerScale = 0.00001f;
fPerspLayerScale = 0.00001f;
fPerspLayerTrans = 0.00002f;
fDefaultLODBias = -0.25f;
fFogExpApproxStart = 0.0f;
fFogExp2ApproxStart = 0.0f;
fFogEndBias = 0.0f;
fExpFogKnee = fExp2FogKnee = 0.5f;
fExpFogKneeVal = fExp2FogKneeVal = 0.15f;
}
};
//// Fog Settings /////////////////////////////////////////////////////////////
class plDXFogSettings
{
public:
plFogEnvironment* fEnvPtr; // nil means no fog
D3DFOGMODE fMode;
uint8_t fIsVertex;
uint8_t fIsShader;
uint32_t fHexColor;
float fStart;
float fEnd;
float fDensity;
hsColorRGBA fColor;
void Reset( void )
{
fEnvPtr = nil;
fMode = D3DFOG_NONE;
fIsVertex = 0;
fIsShader = 0;
fHexColor = 0;
fStart = fEnd = fDensity = 0.0f;
fColor.Set( 0, 0, 0, 0 );
}
};
//// Light Settings ///////////////////////////////////////////////////////////
class plDXLightRef;
class plDXPipeline;
class plDXLightSettings
{
public:
hsBitVector fUsedFlags;
hsBitVector fEnabledFlags;
hsBitVector fHoldFlags;
uint32_t fNextIndex, fLastIndex;
uint16_t fTime;
plLightInfo* fActiveList;
plDXLightRef* fRefList;
plDXPipeline* fPipeline;
hsTArray<plLightInfo*> fProjEach;
hsTArray<plLightInfo*> fProjAll;
hsTArray<plLightInfo*> fCharLights;
hsTArray<plLightInfo*> fVisLights;
uint32_t fNextShadowLight;
hsTArray<plDXLightRef*> fShadowLights;
plDXLightSettings();
// Sets member variables to initial states. Does NOT release anything.
void Reset( plDXPipeline *pipe );
// Releases/deletes anything associated with these settings
void Release( void );
// Reserve a D3D light index
uint32_t ReserveD3DIndex( void );
// Release a reserved D3D light index
void ReleaseD3DIndex( uint32_t idx );
};
//// Stencil Settings /////////////////////////////////////////////////////////
class plDXStencilSettings
{
public:
uint8_t fDepth;
bool fEnabled;
uint8_t fCmpFunc;
uint8_t fFailOp, fPassOp, fPassButZFailOp;
uint32_t fRefValue;
uint32_t fMask;
uint32_t fWriteMask;
void Reset( void )
{
fEnabled = false;
fCmpFunc = 0;
fFailOp = fPassOp = fPassButZFailOp = 0;
fRefValue = 0;
fMask = 0xffffffff;
fWriteMask = 0xffffffff;
}
};
#endif // _plDXSettings_h

View File

@ -0,0 +1,101 @@
/*==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==*/
#include "HeadSpin.h"
#include <D3d9.h>
#include <D3dx9core.h>
#include "HeadSpin.h"
#include "plDXShader.h"
#include "plSurface/plShader.h"
#include "plDXPipeline.h"
plDXShader::plDXShader(plShader* owner)
: fOwner(owner),
fErrorString(nil),
fPipe(nil)
{
owner->SetDeviceRef(this);
}
plDXShader::~plDXShader()
{
fPipe = nil;
ISetError(nil);
}
void plDXShader::SetOwner(plShader* owner)
{
if( owner != fOwner )
{
Release();
fOwner = owner;
owner->SetDeviceRef(this);
}
}
const char* plDXShader::ISetError(const char* errStr)
{
delete [] fErrorString;
if( errStr )
fErrorString = hsStrcpy(errStr);
else
fErrorString = nil;
return fErrorString;
}
HRESULT plDXShader::IOnError(HRESULT hr, const char* errStr)
{
ISetError(errStr);
fOwner->Invalidate();
hsStatusMessage(errStr);
return hr;
}

View File

@ -0,0 +1,72 @@
/*==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 plDXShader_inc
#define plDXShader_inc
#include "plDXDeviceRef.h"
class plShader;
class plDXPipeline;
class plDXShader : public plDXDeviceRef
{
protected:
plShader* fOwner;
char* fErrorString;
plDXPipeline* fPipe;
HRESULT IOnError(HRESULT hr, const char* errStr);
const char* ISetError(const char* errStr);
virtual HRESULT ICreate(plDXPipeline* pipe) = 0;
virtual HRESULT ISetConstants(plDXPipeline* pipe) = 0; // On error, sets error string.
public:
plDXShader(plShader* owner);
virtual ~plDXShader();
const char* GetErrorString() const { return fErrorString; }
void SetOwner(plShader* owner);
};
#endif // plDXShader_inc

View File

@ -0,0 +1,319 @@
/*==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==*/
///////////////////////////////////////////////////////////////////////////////
// //
// plDXTextFont Class Functions //
// Cyan, Inc. //
// //
//// Version History //////////////////////////////////////////////////////////
// //
// 2.19.2001 mcn - Created. //
// //
///////////////////////////////////////////////////////////////////////////////
#include "HeadSpin.h"
#include "hsWindows.h"
#include <d3d9.h>
#include <ddraw.h>
#include <d3dx9mesh.h>
#include "plPipeline/hsWinRef.h"
#include "plDXTextFont.h"
#include "plDXPipeline.h"
//// Local Stuff //////////////////////////////////////////////////////////////
static const long PLD3D_FONTFVF = D3DFVF_XYZ | D3DFVF_DIFFUSE
| D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE3(0);
static D3DXMATRIX d3dIdentityMatrix( 1.0f, 0.0f, 0.0f, 0.0f,
0.0f, 1.0f, 0.0f, 0.0f,
0.0f, 0.0f, 1.0f, 0.0f,
0.0f, 0.0f, 0.0f, 1.0f );
// Following number needs to be at least: 64 chars max in plTextFont drawn at any one time
// * 4 primitives per char max (for bold text)
// * 3 verts per primitive
//const uint32_t kNumVertsInBuffer(32768);
const uint32_t kNumVertsInBuffer(4608);
// See the declaration for plFontVertex in plTextFont.h for info
const DWORD plDXTextFont::kFVF = D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE3(0);
IDirect3DVertexBuffer9* plDXTextFont::fBuffer = nil;
uint32_t plDXTextFont::fBufferCursor = 0;
//// Constructor & Destructor /////////////////////////////////////////////////
plDXTextFont::plDXTextFont( plPipeline *pipe, IDirect3DDevice9 *device ) : plTextFont( pipe )
{
fDevice = device;
fD3DTexture = nil;
fOldStateBlock = fTextStateBlock = 0;
}
plDXTextFont::~plDXTextFont()
{
DestroyObjects();
}
//// ICreateTexture ///////////////////////////////////////////////////////////
void plDXTextFont::ICreateTexture( uint16_t *data )
{
HRESULT hr;
D3DLOCKED_RECT lockInfo;
D3DCAPS9 d3dCaps;
// Check to make sure we can support it
fDevice->GetDeviceCaps( &d3dCaps );
hsAssert( fTextureWidth <= d3dCaps.MaxTextureWidth, "Cannot initialize DX font--texture size too big" );
// Create our texture object
hr = fDevice->CreateTexture( fTextureWidth, fTextureHeight, 1, 0, D3DFMT_A4R4G4B4, D3DPOOL_MANAGED, &fD3DTexture, NULL );
hsAssert( !FAILED( hr ), "Cannot create D3D texture" );
// Lock the texture and write our values out
fD3DTexture->LockRect( 0, &lockInfo, 0, 0 );
memcpy( lockInfo.pBits, data, fTextureWidth * fTextureHeight * sizeof( uint16_t ) );
fD3DTexture->UnlockRect( 0 );
}
void plDXTextFont::CreateShared(IDirect3DDevice9* device)
{
if( FAILED( device->CreateVertexBuffer( sizeof( plFontVertex ) * kNumVertsInBuffer,
D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, 0, D3DPOOL_DEFAULT, &fBuffer, NULL ) ) )
{
hsAssert( false, "CreateVertexBuffer() call failed!" );
}
}
void plDXTextFont::ReleaseShared(IDirect3DDevice9* device)
{
ReleaseObject( fBuffer );
}
//// IInitStateBlocks /////////////////////////////////////////////////////////
void plDXTextFont::IInitStateBlocks( void )
{
for( int i = 0; i < 2; i++ )
{
fDevice->BeginStateBlock();
fDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE );
fDevice->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_SRCALPHA );
fDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA );
fDevice->SetRenderState( D3DRS_ALPHATESTENABLE, TRUE );
fDevice->SetRenderState( D3DRS_ALPHAREF, 0x08 );
fDevice->SetRenderState( D3DRS_ALPHAFUNC, D3DCMP_GREATEREQUAL );
fDevice->SetRenderState( D3DRS_FILLMODE, D3DFILL_SOLID );
fDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_CCW );
fDevice->SetRenderState( D3DRS_ZENABLE, TRUE );
fDevice->SetRenderState( D3DRS_ZFUNC, D3DCMP_ALWAYS );
fDevice->SetRenderState( D3DRS_ZWRITEENABLE, TRUE );
fDevice->SetRenderState( D3DRS_DEPTHBIAS, 0 );
fDevice->SetRenderState( D3DRS_STENCILENABLE, FALSE );
fDevice->SetRenderState( D3DRS_CLIPPING, TRUE );
fDevice->SetRenderState( D3DRS_ANTIALIASEDLINEENABLE, FALSE );
fDevice->SetRenderState( D3DRS_VERTEXBLEND, FALSE );
fDevice->SetRenderState( D3DRS_INDEXEDVERTEXBLENDENABLE, FALSE );
fDevice->SetRenderState( D3DRS_FOGENABLE, FALSE );
fDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_MODULATE );
fDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
fDevice->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE );
fDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_MODULATE );
fDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE );
fDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE );
fDevice->SetSamplerState( 0, D3DSAMP_MINFILTER, D3DTEXF_POINT );
fDevice->SetSamplerState( 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT );
fDevice->SetSamplerState( 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE );
fDevice->SetTextureStageState( 0, D3DTSS_TEXCOORDINDEX, 0 );
fDevice->SetTextureStageState( 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2 );
fDevice->SetTextureStageState( 1, D3DTSS_COLOROP, D3DTOP_DISABLE );
fDevice->SetTextureStageState( 1, D3DTSS_ALPHAOP, D3DTOP_DISABLE );
fDevice->SetRenderState( D3DRS_LIGHTING, FALSE );
if( i == 0 )
fDevice->EndStateBlock( &fOldStateBlock );
else
fDevice->EndStateBlock( &fTextStateBlock );
}
}
//// DestroyObjects ///////////////////////////////////////////////////////////
void plDXTextFont::DestroyObjects()
{
ReleaseObject(fOldStateBlock);
ReleaseObject(fTextStateBlock);
ReleaseObject(fD3DTexture);
fOldStateBlock = fTextStateBlock = 0;
fD3DTexture = nil;
fInitialized = false;
}
//// IDrawPrimitive ///////////////////////////////////////////////////////////
void plDXTextFont::IDrawPrimitive( uint32_t count, plFontVertex *array )
{
plFontVertex *v;
if( !fBuffer )
return;
/// Lock the buffer and write to it
if( fBufferCursor && (fBufferCursor + count * 3 < kNumVertsInBuffer) )
{
// We can lock part of it
if( FAILED( fBuffer->Lock( fBufferCursor * sizeof( plFontVertex ),
count * 3 * sizeof( plFontVertex ),
(void **)&v, D3DLOCK_NOOVERWRITE ) ) )
{
hsAssert( false, "Failed to lock vertex buffer for writing" );
return;
}
fBufferCursor += count * 3;
}
else
{
// Gotta start over
FlushDraws();
fBufferCursor = count * 3;
if( FAILED( fBuffer->Lock( 0, count * 3 * sizeof( plFontVertex ),
(void **)&v, D3DLOCK_DISCARD ) ) )
{
hsAssert( false, "Failed to lock vertex buffer for writing" );
return;
}
}
if( v != nil && array != nil )
{
memcpy( v, array, count * sizeof( plFontVertex ) * 3 );
}
fBuffer->Unlock();
}
//// IDrawLines ///////////////////////////////////////////////////////////////
void plDXTextFont::IDrawLines( uint32_t count, plFontVertex *array )
{
if( !fBuffer )
return;
if( count == 0 || array == nil )
return;
fDevice->SetVertexShader(NULL);
fDevice->SetFVF(kFVF);
fDevice->SetStreamSource(0, fBuffer, 0, sizeof(plFontVertex));
fDevice->DrawPrimitiveUP( D3DPT_LINELIST, count, (const void *)array, sizeof( plFontVertex ) );
}
//// FlushDraws ///////////////////////////////////////////////////////////////
// Flushes out and finishes any drawing left to be done.
void plDXTextFont::FlushDraws( void )
{
if( !fBuffer )
return;
if( fBufferCursor > 0 )
{
fDevice->SetVertexShader( NULL );
fDevice->SetFVF(kFVF);
fDevice->SetStreamSource( 0, fBuffer, 0, sizeof( plFontVertex ) );
fDevice->DrawPrimitive( D3DPT_TRIANGLELIST, 0, fBufferCursor / 3 );
fBufferCursor = 0;
}
}
//// SaveStates ///////////////////////////////////////////////////////////////
void plDXTextFont::SaveStates( void )
{
if( !fInitialized )
IInitObjects();
if (fOldStateBlock)
fOldStateBlock->Capture();
if (fTextStateBlock)
fTextStateBlock->Apply();
fDevice->SetTexture( 0, fD3DTexture );
fDevice->SetTransform( D3DTS_TEXTURE0, &d3dIdentityMatrix );
/// Set up the transform matrices so that the vertices can range (0-screenWidth,0-screenHeight)
fDevice->SetTransform( D3DTS_WORLD, &d3dIdentityMatrix );
fDevice->SetTransform( D3DTS_VIEW, &d3dIdentityMatrix );
D3DXMATRIX mat;
mat = d3dIdentityMatrix;
mat(0,0) = 2.0f / (float)fPipe->Width();
mat(1,1) = -2.0f / (float)fPipe->Height();
mat(3,0) = -1.0;
mat(3,1) = 1.0;
fDevice->SetTransform( D3DTS_PROJECTION, &mat );
}
//// RestoreStates ////////////////////////////////////////////////////////////
void plDXTextFont::RestoreStates( void )
{
if (fOldStateBlock)
fOldStateBlock->Apply();
fDevice->SetTexture( 0, nil );
fDevice->SetTransform( D3DTS_TEXTURE0, &d3dIdentityMatrix );
}

View File

@ -0,0 +1,90 @@
/*==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 _plDXTextFont_h
#define _plDXTextFont_h
#include "plPipeline/plTextFont.h"
//#include "hsGDirect3DTnLDevice.h"
//// plDXTextFont Class Definition ///////////////////////////////////////////
struct IDirect3DTexture9;
struct IDirect3DDevice9;
struct IDirect3DStateBlock9;
class plPipeline;
class plDXTextFont : public plTextFont
{
protected:
IDirect3DTexture9 *fD3DTexture;
IDirect3DDevice9 *fDevice;
static IDirect3DVertexBuffer9 *fBuffer;
static uint32_t fBufferCursor;
IDirect3DStateBlock9 *fOldStateBlock;
IDirect3DStateBlock9 *fTextStateBlock;
virtual void ICreateTexture( uint16_t *data );
virtual void IInitStateBlocks( void );
virtual void IDrawPrimitive( uint32_t count, plFontVertex *array );
virtual void IDrawLines( uint32_t count, plFontVertex *array );
public:
plDXTextFont( plPipeline *pipe, IDirect3DDevice9 *device );
~plDXTextFont();
static void CreateShared(IDirect3DDevice9* device);
static void ReleaseShared(IDirect3DDevice9* device);
virtual void FlushDraws( void );
virtual void SaveStates( void );
virtual void RestoreStates( void );
virtual void DestroyObjects( void );
static const DWORD kFVF;
};
#endif // _plDXTextFont_h

View File

@ -0,0 +1,124 @@
/*==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==*/
///////////////////////////////////////////////////////////////////////////////
// //
// plDXTextureRef.h - Hardware Texture DeviceRef Definition //
// Cyan, Inc. //
// //
//// Version History //////////////////////////////////////////////////////////
// //
// 4.25.2001 mcn - Created. //
// //
///////////////////////////////////////////////////////////////////////////////
#ifndef _plDXTextureRef_h
#define _plDXTextureRef_h
#include "hsMatrix44.h"
#include "hsGeometry3.h"
#include "hsTemplates.h"
#include "plDXDeviceRef.h"
//// Definition ///////////////////////////////////////////////////////////////
class plBitmap;
class plDXTextureRef : public plDXDeviceRef
{
public:
enum Flags
{
kExternData = 0x00000002, // fData points to user data, don't delete
kRenderTarget = 0x00000004, // Created via a render target
kCubicMap = 0x00000008, // Texture is really a cubic map texture
kPerspProjection = 0x00000010, // Perspective projection
kOrthoProjection = 0x00000020, // Orthogonal projection
kProjection = kPerspProjection | kOrthoProjection,
kOffscreenRT = 0x00000040, // Offscreen renderTarget. Never used as an actual texture,
// but handy to still have it as a textureRef
kUVWNormal = 0x00000080, // Use the normal as the UVW src
kAutoGenMipmap = 0x00000100 // DirectX should generate mip levels for us
};
IDirect3DBaseTexture9 *fD3DTexture;
D3DFORMAT fFormatType; // Format of the D3D texture object
uint32_t fMMLvs; // Number of mipmap levels
uint32_t fMaxWidth; // Width of the highest mipmap level
uint32_t fMaxHeight; // Height of the highest mipmap level (no pun intended)
uint32_t fNumPix; // total num texels in all mip levels
uint32_t fDataSize; // size of fData[0..n] in bytes
uint32_t* fLevelSizes; // fLevelSize[i] == size in bytes of level i
//uint32_t fCurrLOD; // Current LOD setting for this texture
plBitmap *fOwner;
void* fData; // for reloading
uint32_t GetFlags() const { return fFlags; }
void SetFlags( uint32_t flag ) { fFlags = flag; }
plDXTextureRef& Set( D3DFORMAT tp, uint32_t ml, uint32_t mw, uint32_t mh, uint32_t np, uint32_t sz, uint32_t manSize, uint32_t* lSz, void* pd, bool ed=false, bool renderTarget = false );
plDXTextureRef( D3DFORMAT tp, uint32_t ml, uint32_t mw, uint32_t mh, uint32_t np, uint32_t sz, uint32_t manSize, uint32_t* lSz, void* pd, bool ed=false, bool renderTarget = false );
virtual ~plDXTextureRef();
void Link( plDXTextureRef **back ) { plDXDeviceRef::Link( (plDXDeviceRef **)back ); }
plDXTextureRef *GetNext( void ) { return (plDXTextureRef *)fNext; }
void Release( void );
};
class plDXCubeTextureRef : public plDXTextureRef
{
public:
void *fFaceData[ 5 ]; // First face is in the inherited fData
plDXCubeTextureRef( D3DFORMAT tp, uint32_t ml, uint32_t mw, uint32_t mh, uint32_t np, uint32_t sz, uint32_t manSize, uint32_t* lSz, void* pd, bool ed=false, bool renderTarget = false ) :
plDXTextureRef( tp, ml, mw, mh, np, sz, manSize, lSz, pd, ed, renderTarget )
{
}
};
#endif // _plDXTextureRef_h

View File

@ -0,0 +1,166 @@
/*==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==*/
#include "HeadSpin.h"
#include "hsWindows.h"
#include <D3d9.h>
#include <D3dx9core.h>
#include "plDXVertexShader.h"
#include "plSurface/plShader.h"
#include "plPipeline/plGBufferGroup.h"
#include "plDXPipeline.h"
plDXVertexShader::plDXVertexShader(plShader* owner)
: plDXShader(owner), fHandle(nil)
{
}
plDXVertexShader::~plDXVertexShader()
{
Release();
}
void plDXVertexShader::Release()
{
ReleaseObject(fHandle);
fHandle = nil;
fPipe = nil;
ISetError(nil);
}
bool plDXVertexShader::VerifyFormat(uint8_t format) const
{
return (fOwner->GetInputFormat() & format) == fOwner->GetInputFormat();
}
IDirect3DVertexShader9 *plDXVertexShader::GetShader(plDXPipeline* pipe)
{
HRESULT hr = S_OK;
if ( !fHandle )
{
if( FAILED(hr = ICreate(pipe)) )
return nil;
}
if( FAILED(hr = ISetConstants(pipe)) )
return nil;
return fHandle;
}
HRESULT plDXVertexShader::ICreate(plDXPipeline* pipe)
{
fHandle = nil; // in case something goes wrong.
fPipe = nil;
ISetError(nil);
#ifdef HS_DEBUGGING
DWORD flags = D3DXSHADER_DEBUG | D3DXSHADER_SKIPOPTIMIZATION;
#else // HS_DEBUGGING
DWORD flags = 0;
#endif // HS_DEBUGGING
// We could store the compiled buffer and skip the assembly step
// if we need to recreate the shader (e.g. on device lost).
// But whatever.
DWORD* shaderCodes = nil;
HRESULT hr = S_OK;
if( plShaderTable::LoadFromFile() || !fOwner->GetDecl()->GetCodes() )
{
if( fOwner->GetDecl()->GetFileName() )
{
LPD3DXBUFFER compiledShader = nil;
LPD3DXBUFFER compilationErrors = nil;
hr = D3DXAssembleShaderFromFile(
fOwner->GetDecl()->GetFileName(),
NULL, NULL, flags,
&compiledShader,
&compilationErrors);
if( FAILED(hr) )
{
return IOnError(hr, compilationErrors ? (char*)compilationErrors->GetBufferPointer() : "File not found");
}
shaderCodes = (DWORD*)(compiledShader->GetBufferPointer());
}
}
if( !shaderCodes )
{
shaderCodes = (DWORD*)(fOwner->GetDecl()->GetCodes());
}
if( !shaderCodes )
return IOnError(-1, "No file and no compiled codes");
hr = pipe->GetD3DDevice()->CreateVertexShader(shaderCodes, &fHandle);
if( FAILED(hr) )
return IOnError(hr, "Error on CreateVertexShader");
hsAssert(fHandle, "No error, but no vertex shader handle. Grrrr.");
fPipe = pipe;
return S_OK;
}
HRESULT plDXVertexShader::ISetConstants(plDXPipeline* pipe)
{
hsAssert(fHandle, "Vertex shader called to set constants without initialization");
if( fOwner->GetNumConsts() )
{
HRESULT hr = pipe->GetD3DDevice()->SetVertexShaderConstantF(0,
(float*)fOwner->GetConstBasePtr(),
fOwner->GetNumConsts());
if( FAILED(hr) )
return IOnError(hr, "Failure setting vertex shader constants");
}
return S_OK;
}

View File

@ -0,0 +1,73 @@
/*==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 plDXVertexSahder_inc
#define plDXVertexSahder_inc
#include "plDXShader.h"
#include "hsTemplates.h"
struct IDirect3DDevice9;
class plShader;
class plDXPipeline;
class plDXVertexShader : public plDXShader
{
protected:
IDirect3DVertexShader9* fHandle;
hsTArray<DWORD>& IMakeDecl(hsTArray<DWORD>& decl) const;
virtual HRESULT ICreate(plDXPipeline* pipe); // On error, sets error string.
virtual HRESULT ISetConstants(plDXPipeline* pipe); // On error, sets error string.
public:
plDXVertexShader(plShader* owner);
virtual ~plDXVertexShader();
virtual void Release();
void Link(plDXVertexShader** back) { plDXDeviceRef::Link((plDXDeviceRef**)back); }
bool VerifyFormat(uint8_t format) const;
IDirect3DVertexShader9* GetShader(plDXPipeline* pipe);
};
#endif // plDXVertexSahder_inc