mirror of
https://foundry.openuru.org/gitblit/r/CWE-ou-minkata.git
synced 2025-07-20 04:09:16 +00:00
Initial Commit of CyanWorlds.com Engine Open Source Client/Plugin
This commit is contained in:
@ -0,0 +1,135 @@
|
||||
/*==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/>.
|
||||
|
||||
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 hsFogControl_inc
|
||||
#define hsFogControl_inc
|
||||
|
||||
//#include "hsSceneObject.h"
|
||||
//#include "hsGEnviron.h"
|
||||
|
||||
class hsSceneNode;
|
||||
class hsG3DDevice;
|
||||
class hsGView3;
|
||||
class hsPortal;
|
||||
|
||||
class hsFogControl : public plCreatable {
|
||||
public:
|
||||
enum {
|
||||
kFogCtlPortal
|
||||
};
|
||||
protected:
|
||||
|
||||
plKey fNodeKey;
|
||||
hsDynamicArray<plKey> fFogNodes;
|
||||
// hsGEnvironment::FogState fAvgFog;
|
||||
|
||||
virtual hsScalar IGetStrength(hsSceneNode* node) = 0;
|
||||
|
||||
void IPopNodes();
|
||||
void IPushNodes();
|
||||
|
||||
void IZeroAvgFog();
|
||||
void IAverageNodes();
|
||||
// void IAccumFog(hsGEnvironment* env, hsScalar wgt);
|
||||
|
||||
public:
|
||||
hsFogControl() {}
|
||||
~hsFogControl() {}
|
||||
|
||||
CLASSNAME_REGISTER( hsFogControl );
|
||||
GETINTERFACE_ANY( hsFogControl, plCreatable );
|
||||
|
||||
virtual UInt32 GetType() = 0;
|
||||
|
||||
// virtual hsGEnvironment* GetHomeEnv() = 0;
|
||||
virtual void Init(hsSceneNode* node);
|
||||
|
||||
virtual void Blend() = 0;
|
||||
|
||||
virtual void Restore() = 0;
|
||||
|
||||
virtual void Read(hsStream *stream, hsResMgr* mgr) = 0;
|
||||
virtual void Write(hsStream *stream, hsResMgr* mgr) = 0;
|
||||
|
||||
};
|
||||
|
||||
#if 0 // Move up to FeatureLevel
|
||||
class hsNodeFogControl : public hsFogControl {
|
||||
public:
|
||||
hsNodeFogControl();
|
||||
~hsNodeFogControl();
|
||||
|
||||
hsSceneNode* GetFogNode(int i);
|
||||
hsSceneNode *GetHomeNode();
|
||||
virtual void Init(hsSceneNode* node);
|
||||
|
||||
virtual hsGEnvironment* GetHomeEnv();
|
||||
|
||||
virtual void Blend();
|
||||
|
||||
virtual void Restore();
|
||||
|
||||
virtual void Read(hsStream *stream);
|
||||
virtual void Write(hsStream *stream);
|
||||
};
|
||||
|
||||
class hsPortalFogControl : public hsNodeFogControl {
|
||||
protected:
|
||||
enum {
|
||||
kStatusNone = 0x0,
|
||||
kStatusNodesSet = 0x1
|
||||
};
|
||||
|
||||
hsDynamicArray<plKey> fPortals;
|
||||
hsScalar fDefRadius;
|
||||
|
||||
UInt32 fStatus;
|
||||
|
||||
void IFindFogNodes();
|
||||
virtual hsScalar IGetStrength(hsSceneNode* node);
|
||||
public:
|
||||
hsPortalFogControl();
|
||||
|
||||
void SetDefaultRadius(hsScalar r) { fDefRadius = r; }
|
||||
hsScalar GetDefaultRadius() { return fDefRadius; }
|
||||
|
||||
hsPortal* GetPortal(int i);
|
||||
|
||||
virtual UInt32 GetType() { return kFogCtlPortal; }
|
||||
|
||||
virtual void Init(hsSceneNode* node);
|
||||
virtual void Blend();
|
||||
|
||||
int GetNumPortalKeys() { return fPortals.GetCount(); }
|
||||
void AddPortalKey(plKey key) { fPortals.Append(key); }
|
||||
plKey GetPortalKey(int i) { return fPortals[i]; }
|
||||
|
||||
virtual void Read(hsStream *stream);
|
||||
virtual void Write(hsStream *stream);
|
||||
};
|
||||
#endif // Move up to FeatureLevel
|
||||
|
||||
#endif hsFogControl_inc
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,468 @@
|
||||
/*==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/>.
|
||||
|
||||
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==*/
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// hsG3DDeviceSelector Class Header //
|
||||
// Generic device enumeration (D3D, OpenGL, etc) //
|
||||
// Cyan, Inc. //
|
||||
// //
|
||||
//// Version History //////////////////////////////////////////////////////////
|
||||
// //
|
||||
// 5.21.2001 mcn - Cleaned out all the old Glide stuff, since Plasma2 will //
|
||||
// not support Glide :( //
|
||||
// //
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef hsG3DDeviceSelector_inc
|
||||
#define hsG3DDeviceSelector_inc
|
||||
|
||||
#include "hsWinRef.h"
|
||||
|
||||
#include "hsTemplates.h"
|
||||
#include "hsBitVector.h"
|
||||
|
||||
#ifdef HS_BUILD_FOR_WIN32
|
||||
#define HS_SELECT_DIRECT3D // not supported on the Mac.
|
||||
#endif // HS_BUILD_FOR_WIN32
|
||||
|
||||
#ifdef HS_BUILD_FOR_WIN32
|
||||
#define __MSC__
|
||||
#define DYNAHEADER 1
|
||||
#endif // HS_BUILD_FOR_WIN32
|
||||
|
||||
/// #define the following to allow selection of the D3D reference driver
|
||||
#define HS_ALLOW_D3D_REF_DRIVER 1
|
||||
|
||||
|
||||
class hsStream;
|
||||
struct D3DEnum_DeviceInfo;
|
||||
struct D3DEnum_DriverInfo;
|
||||
struct D3DEnum_DeviceInfo;
|
||||
struct D3DEnum_DriverInfo;
|
||||
|
||||
class hsG3DDeviceMode
|
||||
{
|
||||
enum {
|
||||
kNone = 0x0,
|
||||
kDiscarded = 0x1
|
||||
};
|
||||
protected:
|
||||
UInt32 fFlags;
|
||||
|
||||
UInt32 fWidth;
|
||||
UInt32 fHeight;
|
||||
UInt32 fDepth;
|
||||
|
||||
hsTArray<UInt16> fZStencilDepths; // Array of supported depth/stencil buffer formats.
|
||||
// Each entry is of the form: ( stencil bit count << 8 ) | ( depth bit count )
|
||||
hsTArray<UInt8> fFSAATypes; // Array of multisample types supported (each one 2-16)
|
||||
|
||||
hsBool fCanRenderToCubics;
|
||||
|
||||
public:
|
||||
hsG3DDeviceMode();
|
||||
~hsG3DDeviceMode();
|
||||
|
||||
hsBool operator< (const hsG3DDeviceMode &mode) const;
|
||||
|
||||
void Clear();
|
||||
|
||||
hsBool GetDiscarded() const { return 0 != (fFlags & kDiscarded); }
|
||||
UInt32 GetWidth() const { return fWidth; }
|
||||
UInt32 GetHeight() const { return fHeight; }
|
||||
UInt32 GetColorDepth() const { return fDepth; }
|
||||
UInt8 GetNumZStencilDepths( void ) const { return fZStencilDepths.GetCount(); }
|
||||
UInt16 GetZStencilDepth( UInt8 i ) const { return fZStencilDepths[ i ]; }
|
||||
UInt8 GetNumFSAATypes( void ) const { return fFSAATypes.GetCount(); }
|
||||
UInt8 GetFSAAType( UInt8 i ) const { return fFSAATypes[ i ]; }
|
||||
hsBool GetCanRenderToCubics( void ) const { return fCanRenderToCubics; }
|
||||
|
||||
void SetDiscarded(hsBool on=true) { if(on) fFlags |= kDiscarded; else fFlags &= ~kDiscarded; }
|
||||
void SetWidth(UInt32 w) { fWidth = w; }
|
||||
void SetHeight(UInt32 h) { fHeight = h; }
|
||||
void SetColorDepth(UInt32 d) { fDepth = d; }
|
||||
void ClearZStencilDepths( void ) { fZStencilDepths.Reset(); }
|
||||
void AddZStencilDepth( UInt16 depth ) { fZStencilDepths.Append( depth ); }
|
||||
|
||||
void ClearFSAATypes( void ) { fFSAATypes.Reset(); }
|
||||
void AddFSAAType( UInt8 type ) { fFSAATypes.Append( type ); }
|
||||
|
||||
void SetCanRenderToCubics( hsBool can ) { fCanRenderToCubics = can; }
|
||||
|
||||
void Read(hsStream* s);
|
||||
void Write(hsStream* s) const;
|
||||
};
|
||||
|
||||
class hsG3DDeviceRecord
|
||||
{
|
||||
public:
|
||||
enum {
|
||||
kNone = 0x0,
|
||||
kDiscarded = 0x1,
|
||||
kInvalid = 0x2
|
||||
};
|
||||
|
||||
enum FogTypes {
|
||||
kFogExp = 0,
|
||||
kFogExp2,
|
||||
kNumFogTypes
|
||||
};
|
||||
|
||||
protected:
|
||||
|
||||
UInt32 fRecordVersion; /// Version starts at 2 (see .cpp for explanation)
|
||||
enum {
|
||||
kCurrRecordVersion = 0x0b
|
||||
/// Version history:
|
||||
/// 1 - Initial version (had no version #)
|
||||
/// 2 - Added Z and LOD bias
|
||||
/// 3 - Changed Z and LOD bias to floats, added fog tweaks
|
||||
/// 4 - Changed values for fog tweaks; force reload through version #
|
||||
/// 5 - Same as #4, updated fog end bias to be based solely on fog quantization/bit depth
|
||||
/// 6 - Updated values for the ATI boards, Matrox, and i810
|
||||
/// 7 - Added fog knee tweaks
|
||||
/// 8 - Added support for multiple depth/stencil formats per mode
|
||||
/// 9 - Added multisample types to the mode record
|
||||
/// A - Added anisotropic sample field
|
||||
/// B - Added flag for cubic textures support
|
||||
};
|
||||
|
||||
/// Version < 2 Data
|
||||
UInt32 fFlags;
|
||||
|
||||
UInt32 fG3DDeviceType;
|
||||
UInt32 fG3DHALorHEL;
|
||||
|
||||
|
||||
char* fG3DDriverDesc;
|
||||
char* fG3DDriverName;
|
||||
char* fG3DDriverVersion;
|
||||
char* fG3DDeviceDesc;
|
||||
|
||||
hsBitVector fCaps;
|
||||
UInt32 fLayersAtOnce;
|
||||
UInt32 fMemoryBytes;
|
||||
|
||||
hsTArray<hsG3DDeviceMode> fModes;
|
||||
|
||||
/// New to Version 3
|
||||
float fZBiasRating;
|
||||
float fLODBiasRating;
|
||||
float fFogExpApproxStart;
|
||||
float fFogExp2ApproxStart;
|
||||
float fFogEndBias; // As a percentage of the max value for fog
|
||||
// (i.e. for Z fog, it's a percentage of 1 to add on,
|
||||
// for W fog, it's a percentage of the yon)
|
||||
|
||||
/// Version 7 - Fog Knee values
|
||||
float fFogKnees[ kNumFogTypes ];
|
||||
float fFogKneeVals[ kNumFogTypes ];
|
||||
|
||||
/// Version 9 - The actual AA setting we use
|
||||
UInt8 fAASetting;
|
||||
|
||||
/// Version A - the anisotropic level we use
|
||||
UInt8 fMaxAnisotropicSamples; // 1 to disable, up to max allowed in hardware
|
||||
int fPixelShaderMajorVer;
|
||||
int fPixelShaderMinorVer;
|
||||
|
||||
public:
|
||||
hsG3DDeviceRecord();
|
||||
virtual ~hsG3DDeviceRecord();
|
||||
|
||||
hsG3DDeviceRecord(const hsG3DDeviceRecord& src);
|
||||
hsG3DDeviceRecord& operator=(const hsG3DDeviceRecord& src);
|
||||
|
||||
UInt32 GetG3DDeviceType() const { return fG3DDeviceType; }
|
||||
const char* GetG3DDeviceTypeName() const;
|
||||
UInt32 GetG3DHALorHEL() const { return fG3DHALorHEL; }
|
||||
|
||||
UInt32 GetMemoryBytes() const { return fMemoryBytes; }
|
||||
|
||||
const char* GetDriverDesc() const { return fG3DDriverDesc; }
|
||||
const char* GetDriverName() const { return fG3DDriverName; }
|
||||
const char* GetDriverVersion() const { return fG3DDriverVersion; }
|
||||
const char* GetDeviceDesc() const { return fG3DDeviceDesc; }
|
||||
|
||||
void SetG3DDeviceType(UInt32 t) { fG3DDeviceType = t; }
|
||||
void SetG3DHALorHEL(UInt32 h) { fG3DHALorHEL = h; }
|
||||
void SetMemoryBytes(UInt32 b) { fMemoryBytes = b; }
|
||||
|
||||
void SetDriverDesc(const char* s);
|
||||
void SetDriverName(const char* s);
|
||||
void SetDriverVersion(const char* s);
|
||||
void SetDeviceDesc(const char* s);
|
||||
|
||||
hsBool GetCap(UInt32 cap) const { return fCaps.IsBitSet(cap); }
|
||||
void SetCap(UInt32 cap, hsBool on=true) { fCaps.SetBit(cap, on); }
|
||||
|
||||
float GetZBiasRating( void ) const { return fZBiasRating; }
|
||||
void SetZBiasRating( float rating ) { fZBiasRating = rating; }
|
||||
|
||||
float GetLODBiasRating( void ) const { return fLODBiasRating; }
|
||||
void SetLODBiasRating( float rating ) { fLODBiasRating = rating; }
|
||||
|
||||
void GetFogApproxStarts( float &expApprox, float &exp2Approx ) const { expApprox = fFogExpApproxStart;
|
||||
exp2Approx = fFogExp2ApproxStart; }
|
||||
void SetFogApproxStarts( float exp, float exp2 ) { fFogExpApproxStart = exp;
|
||||
fFogExp2ApproxStart = exp2; }
|
||||
|
||||
float GetFogEndBias( void ) const { return fFogEndBias; }
|
||||
void SetFogEndBias( float rating ) { fFogEndBias = rating; }
|
||||
|
||||
void GetFogKneeParams( UInt8 type, float &knee, float &kneeVal ) const { knee = fFogKnees[ type ]; kneeVal = fFogKneeVals[ type ]; }
|
||||
void SetFogKneeParams( UInt8 type, float knee, float kneeVal ) { fFogKnees[ type ] = knee; fFogKneeVals[ type ] = kneeVal; }
|
||||
|
||||
UInt32 GetLayersAtOnce() const { return fLayersAtOnce; }
|
||||
void SetLayersAtOnce(UInt32 n) { fLayersAtOnce = n; }
|
||||
|
||||
UInt8 GetAASetting() const { return fAASetting; }
|
||||
void SetAASetting( UInt8 s ) { fAASetting = s; }
|
||||
|
||||
UInt8 GetMaxAnisotropicSamples( void ) const { return fMaxAnisotropicSamples; }
|
||||
void SetMaxAnisotropicSamples( UInt8 num ) { fMaxAnisotropicSamples = num; }
|
||||
|
||||
void SetDiscarded(hsBool on=true) { if(on)fFlags |= kDiscarded; else fFlags &= ~kDiscarded; }
|
||||
hsBool GetDiscarded() const { return 0 != (fFlags & kDiscarded); }
|
||||
|
||||
void SetInvalid( hsBool on = true ) { if( on ) fFlags |= kInvalid; else fFlags &= ~kInvalid; }
|
||||
hsBool IsInvalid() const { return 0 != ( fFlags & kInvalid ); }
|
||||
|
||||
hsTArray<hsG3DDeviceMode>& GetModes() { return fModes; }
|
||||
|
||||
hsG3DDeviceMode* GetMode(int i) const { return &fModes[i]; }
|
||||
|
||||
void ClearModes();
|
||||
void Clear();
|
||||
void RemoveDiscarded();
|
||||
|
||||
// PlaceHolder - Whether a mode can window is restricted by the current setup
|
||||
// of the PC. E.g. if the user changes from 16 bit to TrueColor, the Modes that
|
||||
// can window are pretty much flipped. So we'll have to pass in enough info (like
|
||||
// the hWnd?) to find out what the current setup is to make sure it's compatible.
|
||||
hsBool ModeCanWindow(void* ctx, hsG3DDeviceMode* mode) { return false; }
|
||||
void SetPixelShaderVersion(int major, int minor) { fPixelShaderMajorVer = major; fPixelShaderMinorVer = minor; }
|
||||
void GetPixelShaderVersion(int &major, int &minor) { major = fPixelShaderMajorVer; minor = fPixelShaderMinorVer; }
|
||||
|
||||
void Read(hsStream* s);
|
||||
void Write(hsStream* s) const;
|
||||
};
|
||||
|
||||
class hsG3DDeviceModeRecord
|
||||
{
|
||||
protected:
|
||||
hsG3DDeviceRecord fDevice;
|
||||
hsG3DDeviceMode fMode;
|
||||
public:
|
||||
hsG3DDeviceModeRecord();
|
||||
hsG3DDeviceModeRecord(const hsG3DDeviceRecord& devRec, const hsG3DDeviceMode& devMode);
|
||||
~hsG3DDeviceModeRecord();
|
||||
|
||||
hsG3DDeviceModeRecord(const hsG3DDeviceModeRecord& src);
|
||||
hsG3DDeviceModeRecord& operator=(const hsG3DDeviceModeRecord& src);
|
||||
|
||||
const hsG3DDeviceRecord* GetDevice() const { return &fDevice; }
|
||||
const hsG3DDeviceMode* GetMode() const { return &fMode; }
|
||||
};
|
||||
|
||||
class hsG3DDeviceSelector : public hsRefCnt
|
||||
{
|
||||
public:
|
||||
enum {
|
||||
kDevTypeUnknown = 0,
|
||||
kDevTypeGlide,
|
||||
kDevTypeDirect3D,
|
||||
kDevTypeOpenGL,
|
||||
kDevTypeDirect3DTnL,
|
||||
|
||||
kNumDevTypes
|
||||
};
|
||||
enum {
|
||||
kHHTypeUnknown = 0,
|
||||
kHHD3DNullDev,
|
||||
kHHD3DRampDev,
|
||||
kHHD3DRGBDev,
|
||||
kHHD3DHALDev,
|
||||
kHHD3DMMXDev,
|
||||
kHHD3DTnLHalDev,
|
||||
kHHD3DRefDev,
|
||||
kHHD3D3dfxDev,
|
||||
kHHD3D3dfxVoodoo5Dev,
|
||||
|
||||
kNumHHTypes
|
||||
};
|
||||
enum {
|
||||
kCapsNone = 0,
|
||||
kCapsNoWindow,
|
||||
kCapsMipmap,
|
||||
kCapsPerspective,
|
||||
kCapsHardware,
|
||||
kCapsWBuffer,
|
||||
kCapsCompressTextures,
|
||||
kCapsHWTransform,
|
||||
kCapsDither,
|
||||
kCapsFogLinear,
|
||||
kCapsFogExp,
|
||||
kCapsFogExp2,
|
||||
kCapsFogRange,
|
||||
kCapsLODWatch,
|
||||
kCapsUNUSED,
|
||||
kCapsDoesSmallTextures,
|
||||
kCapsPixelFog,
|
||||
kCapsBadYonStuff,
|
||||
kCapsNoKindaSmallTexs,
|
||||
kCapsCubicTextures,
|
||||
kCapsCubicMipmap,
|
||||
kCapsZBias,
|
||||
kCapsPixelShader,
|
||||
kCapsNoAA,
|
||||
kCapsDoubleFlush,
|
||||
kCapsSingleFlush,
|
||||
kCapsCantShadow,
|
||||
kCapsMaxUVWSrc2,
|
||||
kCapsCantProj,
|
||||
kCapsLimitedProj,
|
||||
kCapsShareDepth,
|
||||
kCapsBadManaged,
|
||||
kCapsNoAniso,
|
||||
// etc.
|
||||
|
||||
kNumCaps
|
||||
};
|
||||
enum
|
||||
{
|
||||
kDefaultWidth = 800,
|
||||
kDefaultHeight = 600,
|
||||
kDefaultDepth = 32
|
||||
};
|
||||
|
||||
protected:
|
||||
hsTArray<hsG3DDeviceRecord> fRecords;
|
||||
char fTempWinClass[ 128 ];
|
||||
|
||||
char fErrorString[ 128 ];
|
||||
|
||||
void ITryDirect3DTnLDevice(D3DEnum_DeviceInfo* devInfo, hsG3DDeviceRecord& srcDevRec);
|
||||
void ITryDirect3DTnLDriver(D3DEnum_DriverInfo* drivInfo);
|
||||
void ITryDirect3DTnL(hsWinRef winRef);
|
||||
hsBool IInitDirect3D( void );
|
||||
|
||||
#ifdef HS_SELECT_DX7
|
||||
void ITryDirect3DDevice(D3DEnum_DeviceInfo* devInfo, hsG3DDeviceRecord& srcDevRec);
|
||||
void ITryDirect3DDriver(D3DEnum_DriverInfo* drivInfo);
|
||||
void ITryDirect3D(hsWinRef winRef);
|
||||
#endif // HS_SELECT_DX7
|
||||
void IFudgeDirectXDevice( hsG3DDeviceRecord &record,
|
||||
D3DEnum_DriverInfo *driverInfo, D3DEnum_DeviceInfo *deviceInfo );
|
||||
UInt32 IAdjustDirectXMemory( UInt32 cardMem );
|
||||
|
||||
hsBool IGetD3DCardInfo( hsG3DDeviceRecord &record, void *driverInfo, void *deviceInfo,
|
||||
DWORD *vendorID, DWORD *deviceID, char **driverString, char **descString );
|
||||
#ifdef HS_SELECT_DX7
|
||||
hsBool IGetD3D7CardInfo( hsG3DDeviceRecord &record, void *driverInfo, void *deviceInfo,
|
||||
DWORD *vendorID, DWORD *deviceID, char **driverString, char **descString );
|
||||
#endif // HS_SELECT_DX7
|
||||
|
||||
void ITryOpenGL( hsWinRef winRef );
|
||||
void IGetExtOpenGLInfo( hsG3DDeviceRecord &devRec );
|
||||
void IGetOpenGLModes( hsG3DDeviceRecord &devRec, char *driverName );
|
||||
hsBool ITestOpenGLRes( int width, int height, int bitDepth,
|
||||
hsG3DDeviceRecord &devRec, char *driverName );
|
||||
#ifdef HS_OPEN_GL
|
||||
#if HS_BUILD_FOR_WIN32
|
||||
UInt32 ICreateTempOpenGLContext( HDC hDC, hsBool makeItFull );
|
||||
#endif
|
||||
#endif
|
||||
|
||||
void ISetFudgeFactors( UInt8 chipsetID, hsG3DDeviceRecord &record );
|
||||
|
||||
public:
|
||||
hsG3DDeviceSelector();
|
||||
virtual ~hsG3DDeviceSelector();
|
||||
|
||||
void Clear();
|
||||
void RemoveDiscarded();
|
||||
void RemoveUnusableDevModes(hsBool bTough); // Removes modes and devices not allowed supported in release
|
||||
|
||||
hsBool Init( void ); // Returns false if couldn't init
|
||||
const char *GetErrorString( void ) { return fErrorString; }
|
||||
|
||||
void Enumerate(hsWinRef winRef);
|
||||
hsTArray<hsG3DDeviceRecord>& GetDeviceRecords() { return fRecords; }
|
||||
|
||||
hsBool GetDefault(hsG3DDeviceModeRecord *dmr);
|
||||
|
||||
hsG3DDeviceRecord* GetRecord(int i) { return &fRecords[i]; }
|
||||
|
||||
void Read(hsStream* s);
|
||||
void Write(hsStream* s);
|
||||
};
|
||||
|
||||
|
||||
#define M3DDEMOINFO 1 /// Always compiled now, but only enabled if
|
||||
/// WIN_INIT has DemoInfoOutput in it
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Demo Debug File header file stuff
|
||||
// Created 10.10.2000 by Mathew Burrack @ Cyan, Inc.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <stdio.h>
|
||||
#include "headspin.h"
|
||||
|
||||
class plDemoDebugFile
|
||||
{
|
||||
public:
|
||||
plDemoDebugFile() { fDemoDebugFP = nil; fIsOpen = false; fEnabled = false; }
|
||||
~plDemoDebugFile() { IDDFClose(); }
|
||||
|
||||
// Static function to write a string to the DDF
|
||||
static void Write( char *string );
|
||||
|
||||
// Static function to write two strings to the DDF
|
||||
static void Write( char *string1, char *string2 );
|
||||
|
||||
// Static function to write a string and a signed integer value to the DDF
|
||||
static void Write( char *string1, Int32 value );
|
||||
|
||||
// Enables or disables the DDF class
|
||||
static void Enable( hsBool yes ) { fEnabled = yes; }
|
||||
|
||||
protected:
|
||||
static hsBool fIsOpen;
|
||||
static FILE *fDemoDebugFP;
|
||||
static hsBool fEnabled;
|
||||
|
||||
// Opens the DDF for writing
|
||||
static hsBool IDDFOpen( void );
|
||||
|
||||
// Closes the DDF
|
||||
static void IDDFClose( void );
|
||||
};
|
||||
|
||||
|
||||
#endif // hsG3DDeviceSelector_inc
|
@ -0,0 +1,69 @@
|
||||
/*==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/>.
|
||||
|
||||
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 "hsTypes.h"
|
||||
#include "plPipeline.h"
|
||||
#include "hsGColorizer.h"
|
||||
|
||||
hsBool hsGColorizer::Colorizing()
|
||||
{
|
||||
return fPipeline ? 0 != (fPipeline->GetColorOverride().fFlags & hsColorOverride::kModColor) : false;
|
||||
}
|
||||
|
||||
hsBool hsGColorizer::Alpharizing()
|
||||
{
|
||||
return fPipeline ? 0 != (fPipeline->GetColorOverride().fFlags & hsColorOverride::kModAlpha) : false;
|
||||
}
|
||||
|
||||
hsColorRGBA hsGColorizer::GetCurrentColor()
|
||||
{
|
||||
return fPipeline ? fPipeline->GetColorOverride().fColor : hsColorRGBA().Set(1.f,1.f,1.f,1.f);
|
||||
}
|
||||
|
||||
void hsGColorizer::Init(plPipeline* pipe)
|
||||
{
|
||||
fPipeline = pipe;
|
||||
}
|
||||
|
||||
void hsGColorizer::PushColorize(hsColorRGBA& col, hsBool alphaOnly)
|
||||
{
|
||||
if( fPipeline )
|
||||
{
|
||||
hsColorOverride colorOver;
|
||||
colorOver.fFlags = alphaOnly ? hsColorOverride::kModAlpha : hsColorOverride::kModColor | hsColorOverride::kModAlpha;
|
||||
colorOver.fColor = col;
|
||||
fResetColor = fPipeline->PushColorOverride(colorOver);
|
||||
}
|
||||
}
|
||||
|
||||
void hsGColorizer::PopColorize()
|
||||
{
|
||||
if( fPipeline )
|
||||
{
|
||||
fPipeline->PopColorOverride(fResetColor);
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,50 @@
|
||||
/*==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/>.
|
||||
|
||||
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 hsGColorizer_inc
|
||||
#define hsGColorizer_inc
|
||||
|
||||
#include "hsTypes.h"
|
||||
#include "hsColorRGBA.h"
|
||||
|
||||
class plPipeline;
|
||||
|
||||
class hsGColorizer {
|
||||
protected:
|
||||
hsColorOverride fResetColor;
|
||||
plPipeline* fPipeline;
|
||||
|
||||
public:
|
||||
hsGColorizer() : fPipeline(nil) {}
|
||||
hsBool Colorizing();
|
||||
hsBool Alpharizing();
|
||||
hsColorRGBA GetCurrentColor();
|
||||
void Init(plPipeline* pipe);
|
||||
void PushColorize(hsColorRGBA& col, hsBool alphaOnly);
|
||||
void PopColorize();
|
||||
};
|
||||
|
||||
#endif // hsGColorizer_inc
|
@ -0,0 +1,57 @@
|
||||
/*==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/>.
|
||||
|
||||
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 "hsTypes.h"
|
||||
|
||||
#include <ddraw.h>
|
||||
|
||||
#include "hsGDDrawDllLoad.h"
|
||||
|
||||
static hsGDDrawDllLoad staticDllLoad;
|
||||
|
||||
hsGDDrawDllLoad::hsGDDrawDllLoad()
|
||||
{
|
||||
hsAssert(!staticDllLoad.fD3DDll, "Don't make instances of this class, just use GetDDrawDll func");
|
||||
|
||||
fD3DDll = LoadLibrary( "D3D9.DLL" );
|
||||
if (fD3DDll)
|
||||
hsStatusMessage( "--- D3D9.DLL loaded successfully.\n" );
|
||||
else
|
||||
hsStatusMessage( "--- Unable to load D3D9.DLL successfully.\n" );
|
||||
}
|
||||
|
||||
hsGDDrawDllLoad::~hsGDDrawDllLoad()
|
||||
{
|
||||
if (fD3DDll != nil)
|
||||
{
|
||||
hsStatusMessage( "--- Unloading D3D.DLL.\n" );
|
||||
FreeLibrary(fD3DDll);
|
||||
}
|
||||
}
|
||||
|
||||
HMODULE hsGDDrawDllLoad::GetD3DDll()
|
||||
{
|
||||
return staticDllLoad.fD3DDll;
|
||||
}
|
@ -0,0 +1,43 @@
|
||||
/*==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/>.
|
||||
|
||||
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 hsGDDrawDllLoad_inc
|
||||
#define hsGDDrawDllLoad_inc
|
||||
|
||||
|
||||
class hsGDDrawDllLoad
|
||||
{
|
||||
private:
|
||||
HMODULE fD3DDll;
|
||||
|
||||
public:
|
||||
hsGDDrawDllLoad();
|
||||
~hsGDDrawDllLoad();
|
||||
|
||||
static HMODULE GetD3DDll();
|
||||
};
|
||||
|
||||
#endif hsGDDrawDllLoad_inc
|
@ -0,0 +1,61 @@
|
||||
/*==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/>.
|
||||
|
||||
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==*/
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// hsGDeviceRef.h - Header for the generic deviceRef class //
|
||||
// Cyan, Inc. //
|
||||
// //
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef hsGDeviceRef_inc
|
||||
#define hsGDeviceRef_inc
|
||||
|
||||
#include "hsRefCnt.h"
|
||||
|
||||
|
||||
class hsGDeviceRef : public hsRefCnt
|
||||
{
|
||||
protected:
|
||||
UInt32 fFlags;
|
||||
|
||||
public:
|
||||
// Note, derived classes define more flags. Take care if adding flags here.
|
||||
// Currently have flags 0x0 - 0x8 reserved.
|
||||
enum {
|
||||
kNone = 0x0,
|
||||
kDirty = 0x1
|
||||
};
|
||||
|
||||
UInt32 fUseTime; // time stamp when last used - stat gather only
|
||||
|
||||
hsBool IsDirty() const { return (fFlags & kDirty); }
|
||||
void SetDirty(hsBool on) { if(on)fFlags |= kDirty; else fFlags &= ~kDirty; }
|
||||
|
||||
hsGDeviceRef() : fFlags(0), fUseTime(0) {}
|
||||
virtual ~hsGDeviceRef() {}
|
||||
};
|
||||
|
||||
#endif // hsGDeviceRef_inc
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,273 @@
|
||||
/*==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/>.
|
||||
|
||||
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 hsGEnviron_inc
|
||||
#define hsGEnviron_inc
|
||||
|
||||
#include "hsGeometry3.h" // hsPoint3
|
||||
#include "../plInterp/hsTimedValue.h"
|
||||
#include "../plResMgr/hsKeyedObject.h"
|
||||
#include "hsColorRGBA.h"
|
||||
#include "hsTemplates.h"
|
||||
|
||||
//
|
||||
//-----------------------------------
|
||||
// Environment
|
||||
//-----------------------------------
|
||||
//
|
||||
|
||||
class hsGMaterial;
|
||||
class hsGDevEnvCache;
|
||||
class hsFogControl;
|
||||
class hsSceneNode;
|
||||
class hsScene;
|
||||
class hsGRenderProcs;
|
||||
class hsG3DDevice;
|
||||
class plKey;
|
||||
class hsResMgr;
|
||||
|
||||
class hsGEnvironment : public hsKeyedObject {
|
||||
private:
|
||||
static const UInt16 kSaveMagicNumber;
|
||||
static const UInt16 kSaveVersion;
|
||||
|
||||
public:
|
||||
struct FogState {
|
||||
private:
|
||||
static const UInt16 kSaveMagicNumber;
|
||||
static const UInt16 kSaveVersion;
|
||||
|
||||
public:
|
||||
FogState() : fFlags(0) {};
|
||||
enum {
|
||||
kColorSet = 0x1,
|
||||
kDistanceSet = 0x2,
|
||||
kDepthSet = 0x4,
|
||||
kDensitySet = 0x8,
|
||||
kYonSet = 0x10,
|
||||
kClearSet = 0x20,
|
||||
|
||||
kLinear = 0x10000000,
|
||||
kExp = 0x20000000,
|
||||
kExp2 = 0x40000000,
|
||||
kTypeMask = kLinear | kExp | kExp2
|
||||
};
|
||||
UInt32 fFlags;
|
||||
hsTimedValue<hsColorRGBA> fColor;
|
||||
hsTimedValue<hsColorRGBA> fClear;
|
||||
hsTimedValue<hsScalar> fDistance;
|
||||
hsTimedValue<hsScalar> fDensity;
|
||||
hsTimedValue<hsScalar> fDepth;
|
||||
hsTimedValue<hsScalar> fYon;
|
||||
|
||||
void ValidateEnv(class hsGEnvironment* env);
|
||||
void SetFromEnv(class hsGEnvironment* env);
|
||||
void SetToEnv(class hsGEnvironment* env);
|
||||
void Save(hsStream *stream, hsResMgr* mgr);
|
||||
void Load(hsStream *stream, hsResMgr* mgr);
|
||||
};
|
||||
|
||||
enum {
|
||||
kMapSet = 0x1,
|
||||
kCenterSet = 0x2,
|
||||
kRadiusSet = 0x4,
|
||||
kEnvironMapSet = kMapSet | kCenterSet | kRadiusSet,
|
||||
kFogDepthSet = 0x8,
|
||||
kFogColorSet = 0x10,
|
||||
kFogDensitySet = 0x20,
|
||||
kYonSet = 0x40,
|
||||
kOverride = 0x80,
|
||||
kFarOut = 0x100,
|
||||
kFogDistanceSet = 0x200,
|
||||
kCacheInvalid = 0x400,
|
||||
kClearColorSet = 0x800,
|
||||
kCurrentDepthSet = 0x1000,
|
||||
kFogControl = 0x2000,
|
||||
kSortObjects = 0x4000,
|
||||
kHasRenderProcs = 0x8000,
|
||||
kFogLinear = 0x10000,
|
||||
kFogExp = 0x20000,
|
||||
kFogExp2 = 0x40000,
|
||||
kFogTypeMask = kFogLinear | kFogExp | kFogExp2,
|
||||
kClearColorAmbient = 0x80000,
|
||||
kFogColorAmbient = 0x100000,
|
||||
kFogColorDiffuse = 0x200000
|
||||
};
|
||||
protected:
|
||||
static hsScalar fYonScale;
|
||||
|
||||
UInt32 fFlags;
|
||||
hsGMaterial* fMap;
|
||||
char fMapName[256];
|
||||
hsPoint3 fPos;
|
||||
hsScalar fRadius;
|
||||
hsScalar fValidScale;
|
||||
hsTArray<FogState*> fFogStateStack;
|
||||
hsTimedValue<hsScalar> fFogDistance;
|
||||
hsTimedValue<hsScalar> fFogDepth; // value 0..1, as fraction of yon, 0 is no fog
|
||||
hsTimedValue<hsScalar> fFogDensity;
|
||||
hsTimedValue<hsColorRGBA> fFogColor;
|
||||
hsTimedValue<hsColorRGBA> fClearColor;
|
||||
hsTimedValue<hsScalar> fYon;
|
||||
hsScalar fCurrentDepth; // function of Depth and Distance
|
||||
|
||||
FogState fResetState;
|
||||
hsGDevEnvCache* fDevCache;
|
||||
|
||||
hsDynamicArray<hsGRenderProcs*> fRenderProcs;
|
||||
hsTArray<plKey*> fNodeKeys;
|
||||
|
||||
hsFogControl* fFogControl;
|
||||
|
||||
void IReadFogControl(hsStream* s, hsResMgr* mgr);
|
||||
void IWriteFogControl(hsStream* s, hsResMgr* mgr);
|
||||
|
||||
public:
|
||||
hsGEnvironment();
|
||||
virtual ~hsGEnvironment();
|
||||
|
||||
hsBool32 AddNode(hsSceneNode *node);
|
||||
hsBool32 AddNodeKey(plKey *key);
|
||||
Int32 GetNumNodes() { return fNodeKeys.GetCount(); }
|
||||
hsSceneNode* GetNode(Int32 i);
|
||||
plKey* GetNodeKey(Int32 i) { return fNodeKeys[i]; }
|
||||
|
||||
char* GetMapName() { return fMapName; }
|
||||
hsGMaterial* GetMap() const { return fMap; }
|
||||
hsPoint3 GetCenter() const { return fPos; }
|
||||
hsScalar GetRadius() const { return fRadius; }
|
||||
hsScalar GetFogDistance() const { return fFogDistance.GetValue(); }
|
||||
hsScalar GetFogDepth() const { return fFogDepth.GetValue(); }
|
||||
hsScalar GetCurrentDepth() const { return fCurrentDepth; }
|
||||
hsScalar GetFogDensity() const { return fFogDensity.GetValue(); }
|
||||
hsColorRGBA GetFogColor() const { return fFogColor.GetValue(); }
|
||||
hsColorRGBA GetClearColor() const { return fClearColor.GetValue(); }
|
||||
hsScalar GetYon() const { return fYonScale * fYon.GetValue(); }
|
||||
hsScalar GetUnscaledYon() const { return fYon.GetValue(); }
|
||||
hsBool32 GetOverride() const { return 0 != (fFlags & kOverride); }
|
||||
UInt32 GetFlags() const { return fFlags; }
|
||||
|
||||
hsScalar GoalFogDistance() const { return fFogDistance.GetGoal(); }
|
||||
hsScalar GoalFogDepth() const { return fFogDepth.GetGoal(); }
|
||||
hsScalar GoalFogDensity() const { return fFogDensity.GetGoal(); }
|
||||
hsColorRGBA GoalFogColor() const { return fFogColor.GetGoal(); }
|
||||
hsColorRGBA GoalClearColor() const { return fClearColor.GetGoal(); }
|
||||
hsScalar GoalYon() const { return fYon.GetGoal(); }
|
||||
|
||||
const hsTimedValue<hsScalar>& FogDistanceState() const { return fFogDistance; }
|
||||
const hsTimedValue<hsScalar>& FogDepthState() const { return fFogDepth; }
|
||||
const hsTimedValue<hsScalar>& FogDensityState() const { return fFogDensity; }
|
||||
const hsTimedValue<hsColorRGBA>& FogColorState() const { return fFogColor; }
|
||||
const hsTimedValue<hsColorRGBA>& ClearColorState() const { return fClearColor; }
|
||||
const hsTimedValue<hsScalar>& YonState() const { return fYon; }
|
||||
|
||||
void SetFogDistance(const hsTimedValue<hsScalar>& v);
|
||||
void SetFogDepth(const hsTimedValue<hsScalar>& v);
|
||||
void SetFogDensity(const hsTimedValue<hsScalar>& v);
|
||||
void SetFogColor(const hsTimedValue<hsColorRGBA>& v);
|
||||
void SetClearColor(const hsTimedValue<hsColorRGBA>& v);
|
||||
void SetYon(const hsTimedValue<hsScalar>& v);
|
||||
|
||||
void SetMapName(const char *name);
|
||||
void SetMap(hsGMaterial *m); // refs
|
||||
void SetCenter(const hsPoint3 &p);
|
||||
void SetRadius(hsScalar r);
|
||||
void SetFogDistance(hsScalar d);
|
||||
void SetFogDepth(hsScalar f);
|
||||
void SetCurrentDepth(hsScalar f);
|
||||
void SetFogDensity(hsScalar f);
|
||||
void SetFogColor(const hsColorRGBA &c);
|
||||
void SetClearColor(const hsColorRGBA &c);
|
||||
void SetYon(hsScalar f);
|
||||
void SetOverride(hsBool32 on);
|
||||
void SetIsFar(hsBool32 on=true);
|
||||
void SetHasFogControl(hsBool32 on=true);
|
||||
void SetSortObjects(hsBool32 on=true);
|
||||
void SetFogType(UInt32 t);
|
||||
void SetFogColorAmbient(hsBool32 on=true);
|
||||
void SetFogColorDiffuse(hsBool32 on=true);
|
||||
void SetClearColorAmbient(hsBool32 on=true);
|
||||
|
||||
void SetTimedFogDistance(const hsScalar g, const hsScalar s);
|
||||
void SetTimedFogDepth(const hsScalar g, const hsScalar s);
|
||||
void SetTimedFogDensity(const hsScalar g, const hsScalar s);
|
||||
void SetTimedFogColor(const hsColorRGBA& g, const hsScalar s);
|
||||
void SetTimedClearColor(const hsColorRGBA& g, const hsScalar s);
|
||||
void SetTimedYon(const hsScalar g, const hsScalar s);
|
||||
|
||||
void UnSetMapName() { *fMapName = 0; }
|
||||
void UnSetEnvironMap() { fFlags &= ~kEnvironMapSet; }
|
||||
void UnSetFogDistance() { fFlags &= ~kFogDistanceSet; }
|
||||
void UnSetFogDepth() { fFlags &= ~kFogDepthSet; }
|
||||
void UnSetFogDensity() { fFlags &= ~kFogDensitySet; }
|
||||
void UnSetFogColor() { fFlags &= ~kFogColorSet; }
|
||||
void UnSetClearColor() { fFlags &= ~kClearColorSet; }
|
||||
void UnSetYon() { fFlags &= ~kYonSet; }
|
||||
|
||||
hsGEnvironment* Copy(hsGEnvironment* env); // returns this
|
||||
|
||||
void MixEnvirons(hsGEnvironment* env, hsGEnvironment* def);
|
||||
|
||||
void Push(hsG3DDevice* d);
|
||||
void Pop(hsG3DDevice* d);
|
||||
|
||||
void Blend();
|
||||
void Restore();
|
||||
void Init(hsSceneNode* node);
|
||||
|
||||
void SetDeviceCache(hsGDevEnvCache* p);
|
||||
hsGDevEnvCache* GetDeviceCache(){ return fDevCache; }
|
||||
|
||||
void SetFogControl(hsFogControl* fc);
|
||||
hsFogControl* GetFogControl() { return fFogControl; }
|
||||
|
||||
void SaveFogState(); // push
|
||||
hsGEnvironment::FogState* PopFogState() { return fFogStateStack.GetCount() ? fFogStateStack.Pop() : nil; } // doesn't restore
|
||||
void RestoreFogState(); // pop and restore
|
||||
|
||||
void AddRenderProc(hsGRenderProcs* rp); // refs
|
||||
hsGRenderProcs* GetRenderProc(int i); // no ref
|
||||
UInt32 GetNumRenderProcs();
|
||||
|
||||
virtual void SetResetState();
|
||||
virtual void Reset();
|
||||
virtual void ValidateInResetState();
|
||||
virtual void Save(hsStream *stream, hsResMgr* mgr);
|
||||
virtual void Load(hsStream *stream, hsResMgr* mgr);
|
||||
virtual void Update(hsScalar secs, const hsPoint3& vPos);
|
||||
|
||||
virtual void Read(hsStream* s);
|
||||
virtual void Write(hsStream* s);
|
||||
|
||||
virtual void Write(hsStream *stream, hsResMgr *group);
|
||||
virtual void Read(hsStream *stream, hsResMgr *group);
|
||||
|
||||
static hsScalar GetYonScale() { return fYonScale; }
|
||||
static hsScalar SetYonScale(hsScalar s);
|
||||
|
||||
virtual hsBool MsgReceive(plMessage* msg);
|
||||
};
|
||||
|
||||
#endif // hsGEnviron_inc
|
@ -0,0 +1,46 @@
|
||||
/*==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/>.
|
||||
|
||||
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 hsWinRef_inc
|
||||
#define hsWinRef_inc
|
||||
|
||||
|
||||
#ifdef HS_BUILD_FOR_WIN32
|
||||
|
||||
#include "hsWindows.h"
|
||||
typedef HWND hsWinRef;
|
||||
|
||||
#elif HS_BUILD_FOR_MACPPC
|
||||
|
||||
typedef WindowRef hsWinRef;
|
||||
|
||||
#else // Whatever
|
||||
|
||||
typedef void* hsWinRef;
|
||||
|
||||
#endif
|
||||
|
||||
#endif // hsWinRef_inc
|
@ -0,0 +1,219 @@
|
||||
/*==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/>.
|
||||
|
||||
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 "hsTypes.h"
|
||||
#include "plCaptureRender.h"
|
||||
|
||||
#ifndef MF_FRONTBUFF_CAPTURE
|
||||
|
||||
#include "../plGImage/plMipmap.h"
|
||||
#include "../plMessage/plCaptureRenderMsg.h"
|
||||
#include "plPipeline.h"
|
||||
#include "plRenderTarget.h"
|
||||
#include "../plScene/plPageTreeMgr.h"
|
||||
#include "../plScene/plPostEffectMod.h"
|
||||
#include "hsResMgr.h"
|
||||
#include "../pnKeyedObject/plUoid.h"
|
||||
|
||||
#include "../pfGameGUIMgr/pfGameGUIMgr.h"
|
||||
|
||||
// CaptureRenderRequest
|
||||
//
|
||||
void plCaptureRenderRequest::Render(plPipeline* pipe, plPageTreeMgr* pageMgr)
|
||||
{
|
||||
// If we don't have a render target, something has gone horribly wrong.
|
||||
if( !GetRenderTarget() )
|
||||
{
|
||||
hsAssert(false, "CaptureRenderRequest with no render target");
|
||||
return;
|
||||
}
|
||||
|
||||
// Set ourselves up like the current pipeline, except with our screen size.
|
||||
plViewTransform vt = pipe->GetViewTransform();
|
||||
vt.SetViewPort(0, 0, fRenderTarget->GetWidth(), fRenderTarget->GetHeight());
|
||||
SetViewTransform(vt);
|
||||
SetClearColor(pipe->GetClearColor());
|
||||
SetClearDepth(pipe->GetClearDepth());
|
||||
|
||||
// Clear our render target
|
||||
// Render the scene
|
||||
pipe->PushRenderRequest(this);
|
||||
|
||||
pipe->ClearRenderTarget();
|
||||
|
||||
pageMgr->Render(pipe);
|
||||
|
||||
pipe->PopRenderRequest(this);
|
||||
|
||||
// set up state so we can clear the z-buffer for every gui dialog (and therefore not have it
|
||||
// be obscured by other geometry)
|
||||
SetRenderState(GetRenderState() & ~plPipeline::kRenderClearColor);
|
||||
SetRenderState(GetRenderState() | plPipeline::kRenderClearDepth);
|
||||
SetClearDepth(1);
|
||||
|
||||
// render all GUI items
|
||||
std::vector<plPostEffectMod*> guiRenderMods = pfGameGUIMgr::GetInstance()->GetDlgRenderMods();
|
||||
for (int i = (int)guiRenderMods.size() - 1; i >= 0; i--) // render in reverse, so dialogs on the bottom get rendered first
|
||||
{
|
||||
plPageTreeMgr* dlgPageMgr = guiRenderMods[i]->GetPageMgr();
|
||||
if (dlgPageMgr)
|
||||
{
|
||||
SetViewTransform(guiRenderMods[i]->GetViewTransform());
|
||||
pipe->PushRenderRequest(this);
|
||||
pipe->ClearRenderTarget();
|
||||
dlgPageMgr->Render(pipe);
|
||||
pipe->PopRenderRequest(this);
|
||||
}
|
||||
}
|
||||
|
||||
// Callback on plCaptureRender to process the render target into a mipmap
|
||||
// and send it back to the requester.
|
||||
plCaptureRender::IProcess(pipe, GetAck(), GetRenderTarget());
|
||||
|
||||
delete fRenderTarget;
|
||||
fRenderTarget = nil;
|
||||
}
|
||||
|
||||
hsTArray<plCaptureRenderMsg*> plCaptureRender::fProcessed;
|
||||
|
||||
// plCaptureRender::Capture
|
||||
hsBool plCaptureRender::Capture(const plKey& ack, UInt16 width, UInt16 height)
|
||||
{
|
||||
// Create our render target
|
||||
const UInt16 flags = plRenderTarget::kIsOffscreen;
|
||||
const UInt8 bitDepth(32);
|
||||
const UInt8 zDepth(-1);
|
||||
const UInt8 stencilDepth(-1);
|
||||
plRenderTarget* rt = TRACKED_NEW plRenderTarget(flags, width, height, bitDepth, zDepth, stencilDepth);
|
||||
|
||||
static int idx=0;
|
||||
char buff[32];
|
||||
sprintf(buff, "tRT%d", idx++);
|
||||
hsgResMgr::ResMgr()->NewKey(buff, rt, ack->GetUoid().GetLocation());
|
||||
|
||||
|
||||
// Create a render request and render request message
|
||||
plCaptureRenderRequest* req = TRACKED_NEW plCaptureRenderRequest;
|
||||
|
||||
const hsScalar pri(-100.f);
|
||||
req->SetPriority(pri);
|
||||
|
||||
req->SetRenderTarget(rt);
|
||||
|
||||
const UInt32 renderState
|
||||
= plPipeline::kRenderNormal
|
||||
| plPipeline::kRenderClearColor
|
||||
| plPipeline::kRenderClearDepth;
|
||||
req->SetRenderState(renderState);
|
||||
|
||||
// Set the Ack to be our requestor
|
||||
req->RequestAck(ack);
|
||||
|
||||
// Submit
|
||||
plRenderRequestMsg* msg = TRACKED_NEW plRenderRequestMsg(ack, req);
|
||||
hsRefCnt_SafeUnRef(req);
|
||||
msg->Send();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// plCaptureRender::IProcess
|
||||
hsBool plCaptureRender::IProcess(plPipeline* pipe, const plKey& ack, plRenderTarget* targ)
|
||||
{
|
||||
// We've just had a successful render into our render target
|
||||
|
||||
// Copy that into a plMipmap
|
||||
plMipmap* mipMap = pipe->ExtractMipMap(targ);
|
||||
if( !mipMap )
|
||||
return false;
|
||||
|
||||
static int currentCapIndex = 0;
|
||||
|
||||
// Mipmap isn't created with a key so let's give it one now
|
||||
char buff[512];
|
||||
sprintf(buff, "CaptureRender_%d", currentCapIndex++);
|
||||
|
||||
hsgResMgr::ResMgr()->NewKey(buff, mipMap, plLocation::kGlobalFixedLoc);
|
||||
mipMap->Ref();
|
||||
|
||||
// Stash it, and send it off during the update phase.
|
||||
plCaptureRenderMsg* msg = TRACKED_NEW plCaptureRenderMsg(ack, mipMap);
|
||||
fProcessed.Append(msg);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void plCaptureRender::Update()
|
||||
{
|
||||
int i;
|
||||
for( i = 0; i < fProcessed.GetCount(); i++ )
|
||||
{
|
||||
fProcessed[i]->Send();
|
||||
}
|
||||
fProcessed.SetCount(0);
|
||||
}
|
||||
|
||||
|
||||
#else // MF_FRONTBUFF_CAPTURE
|
||||
|
||||
#include "plPipeline.h"
|
||||
#include "plgDispatch.h"
|
||||
|
||||
#include "../plMessage/plCaptureRenderMsg.h"
|
||||
#include "../plGImage/plMipmap.h"
|
||||
|
||||
hsTArray<plCaptureRender::CapInfo> plCaptureRender::fCapReqs;
|
||||
|
||||
void plCaptureRender::Update(plPipeline* pipe)
|
||||
{
|
||||
int i;
|
||||
|
||||
for( i = 0; i < fCapReqs.GetCount(); i++ )
|
||||
{
|
||||
plMipmap* mipmap = TRACKED_NEW plMipmap(fCapReqs[i].fWidth, fCapReqs[i].fHeight, plMipmap::kARGB32Config, 1);
|
||||
|
||||
pipe->CaptureScreen(mipmap, false, fCapReqs[i].fWidth, fCapReqs[i].fHeight);
|
||||
|
||||
plCaptureRenderMsg* msg = TRACKED_NEW plCaptureRenderMsg(fCapReqs[i].fAck, mipmap);
|
||||
msg->Send();
|
||||
}
|
||||
|
||||
fCapReqs.Reset();
|
||||
}
|
||||
|
||||
hsBool plCaptureRender::Capture(const plKey& ack, UInt16 width, UInt16 height)
|
||||
{
|
||||
CapInfo capInfo;
|
||||
capInfo.fAck = ack;
|
||||
capInfo.fWidth = width;
|
||||
capInfo.fHeight = height;
|
||||
|
||||
fCapReqs.Append(capInfo);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif // MF_FRONTBUFF_CAPTURE
|
@ -0,0 +1,93 @@
|
||||
/*==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/>.
|
||||
|
||||
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 plCaptureRender_inc
|
||||
#define plCaptureRender_inc
|
||||
|
||||
#ifndef MF_FRONTBUFF_CAPTURE
|
||||
|
||||
#include "../plScene/plRenderRequest.h"
|
||||
|
||||
class plRenderTarget;
|
||||
class plCaptureRenderMsg;
|
||||
|
||||
class plCaptureRenderRequest : public plRenderRequest
|
||||
{
|
||||
public:
|
||||
|
||||
virtual void Render(plPipeline* pipe, plPageTreeMgr* pageMgr);
|
||||
};
|
||||
|
||||
class plCaptureRender
|
||||
{
|
||||
protected:
|
||||
static hsTArray<plCaptureRenderMsg*> fProcessed;
|
||||
|
||||
static hsBool IProcess(plPipeline* pipe, const plKey& ack, plRenderTarget* targ);
|
||||
|
||||
friend class plCaptureRenderRequest;
|
||||
|
||||
// Only the client calls this (during the update phase).
|
||||
static void Update();
|
||||
friend class plClient;
|
||||
public:
|
||||
|
||||
static hsBool Capture(const plKey& ack, UInt16 width=800, UInt16 height=600);
|
||||
|
||||
};
|
||||
|
||||
#else // MF_FRONTBUFF_CAPTURE
|
||||
|
||||
#include "hsTemplates.h"
|
||||
#include "../pnKeyedObject/plKey.h"
|
||||
|
||||
class plPipeline;
|
||||
|
||||
class plCaptureRender
|
||||
{
|
||||
protected:
|
||||
class CapInfo
|
||||
{
|
||||
public:
|
||||
plKey fAck;
|
||||
UInt16 fWidth;
|
||||
UInt16 fHeight;
|
||||
};
|
||||
|
||||
static hsTArray<CapInfo> fCapReqs;
|
||||
|
||||
// Only the client calls this (during the update phase).
|
||||
static void Update(plPipeline* pipe);
|
||||
friend class plClient;
|
||||
public:
|
||||
|
||||
static hsBool Capture(const plKey& ack, UInt16 width=800, UInt16 height=600);
|
||||
|
||||
};
|
||||
|
||||
#endif // MF_FRONTBUFF_CAPTURE
|
||||
|
||||
#endif // plCaptureRender_inc
|
@ -0,0 +1,121 @@
|
||||
/*==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/>.
|
||||
|
||||
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==*/
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// plCubicRenderTarget Class Header //
|
||||
// Derived renderTarget class representing a collection of render targets //
|
||||
// to be used for DYNAMIC cubic environment mapping. //
|
||||
// Cyan, Inc. //
|
||||
// //
|
||||
//// Version History //////////////////////////////////////////////////////////
|
||||
// //
|
||||
// 6.7.2001 mcn - Created. //
|
||||
// //
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef _plCubicRenderTarget_h
|
||||
#define _plCubicRenderTarget_h
|
||||
|
||||
#include "plRenderTarget.h"
|
||||
#include "hsMatrix44.h"
|
||||
|
||||
|
||||
//// Class Definition /////////////////////////////////////////////////////////
|
||||
|
||||
class plCubicRenderTarget : public plRenderTarget
|
||||
{
|
||||
protected:
|
||||
|
||||
//// Protected Members ////
|
||||
|
||||
plRenderTarget *fFaces[6];
|
||||
hsMatrix44 fWorldToCameras[6];
|
||||
hsMatrix44 fCameraToWorlds[6];
|
||||
|
||||
public:
|
||||
|
||||
//// Public Data ////
|
||||
|
||||
enum Faces
|
||||
{
|
||||
kLeftFace = 0,
|
||||
kRightFace,
|
||||
kFrontFace,
|
||||
kBackFace,
|
||||
kTopFace,
|
||||
kBottomFace
|
||||
};
|
||||
|
||||
//// Public Members ////
|
||||
|
||||
CLASSNAME_REGISTER( plCubicRenderTarget );
|
||||
GETINTERFACE_ANY( plCubicRenderTarget, plRenderTarget );
|
||||
|
||||
plCubicRenderTarget()
|
||||
{
|
||||
fFaces[0] = fFaces[1] = fFaces[2] = fFaces[3] = fFaces[4] = fFaces[5] = nil;
|
||||
}
|
||||
|
||||
plCubicRenderTarget( UInt16 flags, UInt16 width, UInt16 height, UInt8 bitDepth, UInt8 zDepth = -1, UInt8 sDepth = -1 )
|
||||
: plRenderTarget( flags, width, height, bitDepth, zDepth, sDepth )
|
||||
{
|
||||
int i;
|
||||
|
||||
|
||||
for( i = 0; i < 6; i++ )
|
||||
{
|
||||
fFaces[i] = TRACKED_NEW plRenderTarget( flags, width, height, bitDepth, zDepth, sDepth );
|
||||
fFaces[i]->fParent = this;
|
||||
fWorldToCameras[i].Reset();
|
||||
fCameraToWorlds[i].Reset();
|
||||
}
|
||||
}
|
||||
|
||||
virtual ~plCubicRenderTarget()
|
||||
{
|
||||
int i;
|
||||
|
||||
|
||||
for( i = 0; i < 6; i++ )
|
||||
delete fFaces[i];
|
||||
}
|
||||
|
||||
// Get the total size in bytes
|
||||
virtual UInt32 GetTotalSize( void ) const;
|
||||
|
||||
virtual void SetCameraMatrix(const hsPoint3& pos);
|
||||
virtual const hsMatrix44& GetWorldToCamera(UInt8 face) const { return fWorldToCameras[face]; }
|
||||
virtual const hsMatrix44& GetCameraToWorld(UInt8 face) const { return fCameraToWorlds[face]; }
|
||||
|
||||
plRenderTarget *GetFace(UInt8 face) const { return fFaces[face]; }
|
||||
|
||||
virtual UInt32 Read(hsStream *s);
|
||||
virtual UInt32 Write(hsStream *s);
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif // _plCubicRenderTarget_h
|
@ -0,0 +1,243 @@
|
||||
/*==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/>.
|
||||
|
||||
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==*/
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// plCubicRenderTargetModifier Class Functions //
|
||||
// Cyan, Inc. //
|
||||
// //
|
||||
//// Version History //////////////////////////////////////////////////////////
|
||||
// //
|
||||
// 7.20.2001 mcn - Created. //
|
||||
// //
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "hsTypes.h"
|
||||
#include "plCubicRenderTargetModifier.h"
|
||||
#include "plCubicRenderTarget.h"
|
||||
#include "plgDispatch.h"
|
||||
#include "plPipeline.h"
|
||||
#include "plDrawable.h"
|
||||
#include "hsBounds.h"
|
||||
|
||||
#include "../plScene/plRenderRequest.h"
|
||||
#include "../pnSceneObject/plSceneObject.h"
|
||||
#include "../pnSceneObject/plCoordinateInterface.h"
|
||||
#include "../pnSceneObject/plDrawInterface.h"
|
||||
#include "../pnMessage/plTimeMsg.h"
|
||||
#include "../plMessage/plRenderRequestMsg.h"
|
||||
#include "hsResMgr.h"
|
||||
#include "hsTimer.h"
|
||||
|
||||
|
||||
//// Constructor & Destructor /////////////////////////////////////////////////
|
||||
|
||||
plCubicRenderTargetModifier::plCubicRenderTargetModifier()
|
||||
{
|
||||
fTarget = nil;
|
||||
fCubic = nil;
|
||||
|
||||
fRequests[ 0 ] = fRequests[ 1 ] = fRequests[ 2 ] = fRequests[ 3 ] = fRequests[ 4 ] = fRequests[ 5 ] = nil;
|
||||
}
|
||||
|
||||
plCubicRenderTargetModifier::~plCubicRenderTargetModifier()
|
||||
{
|
||||
int i;
|
||||
|
||||
|
||||
for( i = 0; i < 6; i++ )
|
||||
delete fRequests[ i ];
|
||||
}
|
||||
|
||||
//// ICreateRenderRequest /////////////////////////////////////////////////////
|
||||
// Creates a blank renderRequest to use for fun stuff.
|
||||
|
||||
void plCubicRenderTargetModifier::ICreateRenderRequest( int face )
|
||||
{
|
||||
plRenderRequest *rr = fRequests[ face ];
|
||||
hsColorRGBA c;
|
||||
|
||||
|
||||
if( rr == nil )
|
||||
rr = fRequests[ face ] = TRACKED_NEW plRenderRequest;
|
||||
|
||||
UInt32 renderState
|
||||
= plPipeline::kRenderNormal
|
||||
| plPipeline::kRenderClearColor
|
||||
| plPipeline::kRenderClearDepth;
|
||||
rr->SetRenderState( renderState );
|
||||
|
||||
rr->SetDrawableMask( plDrawable::kNormal );
|
||||
rr->SetSubDrawableMask( plDrawable::kSubAllTypes );
|
||||
|
||||
rr->SetHither(0.3f); // MF_HORSE ????
|
||||
rr->SetYon(1000.f); // MF_HORSE ????
|
||||
|
||||
rr->SetFovX( 90 );
|
||||
rr->SetFovY( 90 );
|
||||
|
||||
c.Set( 0, 0, 0, 1 );
|
||||
rr->SetClearColor( c );
|
||||
rr->SetClearDepth( 1.f );
|
||||
|
||||
rr->SetClearDrawable( nil );
|
||||
rr->SetRenderTarget( fCubic->GetFace( face ) );
|
||||
}
|
||||
|
||||
//// IEval ////////////////////////////////////////////////////////////////////
|
||||
|
||||
hsBool plCubicRenderTargetModifier::IEval( double secs, hsScalar del, UInt32 dirty )
|
||||
{
|
||||
hsPoint3 center;
|
||||
hsMatrix44 mtx, invMtx;
|
||||
int i;
|
||||
|
||||
plRenderRequestMsg *msg;
|
||||
|
||||
|
||||
if( fCubic == nil || fTarget == nil )
|
||||
return true;
|
||||
|
||||
/// Get center point for RT
|
||||
plCoordinateInterface *ci = IGetTargetCoordinateInterface( 0 );
|
||||
if( ci == nil )
|
||||
{
|
||||
plDrawInterface *di = IGetTargetDrawInterface( 0 );
|
||||
center = di->GetWorldBounds().GetCenter();
|
||||
}
|
||||
else
|
||||
center = ci->GetLocalToWorld().GetTranslate();
|
||||
|
||||
/// Set camera position of RT to this center
|
||||
fCubic->SetCameraMatrix(center);
|
||||
|
||||
/// Submit render requests!
|
||||
for( i = 0; i < 6; i++ )
|
||||
{
|
||||
if( fRequests[ i ] != nil )
|
||||
{
|
||||
fRequests[ i ]->SetCameraTransform(fCubic->GetWorldToCamera(i), fCubic->GetCameraToWorld(i));
|
||||
|
||||
msg = TRACKED_NEW plRenderRequestMsg( nil, fRequests[ i ] );
|
||||
plgDispatch::MsgSend( msg );
|
||||
}
|
||||
}
|
||||
|
||||
/// Done!
|
||||
return true;
|
||||
}
|
||||
|
||||
//// MsgReceive ///////////////////////////////////////////////////////////////
|
||||
|
||||
hsBool plCubicRenderTargetModifier::MsgReceive( plMessage* msg )
|
||||
{
|
||||
plSceneObject *scene;
|
||||
plCubicRenderTarget *cubic;
|
||||
int i;
|
||||
|
||||
|
||||
plEvalMsg* eval = plEvalMsg::ConvertNoRef(msg);
|
||||
if( eval )
|
||||
{
|
||||
const double secs = eval->DSeconds();
|
||||
const hsScalar del = eval->DelSeconds();
|
||||
IEval( secs, del, 0 );
|
||||
return true;
|
||||
}
|
||||
plRefMsg *refMsg = plRefMsg::ConvertNoRef( msg );
|
||||
if( refMsg )
|
||||
{
|
||||
if( scene = plSceneObject::ConvertNoRef( refMsg->GetRef() ) )
|
||||
{
|
||||
if( refMsg->GetContext() & ( plRefMsg::kOnCreate | plRefMsg::kOnRequest | plRefMsg::kOnReplace ) )
|
||||
AddTarget( scene );
|
||||
else
|
||||
RemoveTarget( scene );
|
||||
}
|
||||
if( cubic = plCubicRenderTarget::ConvertNoRef( refMsg->GetRef() ) )
|
||||
{
|
||||
if( refMsg->GetContext() & ( plRefMsg::kOnCreate | plRefMsg::kOnRequest | plRefMsg::kOnReplace ) )
|
||||
{
|
||||
fCubic = cubic;
|
||||
for( i = 0; i < 6; i++ )
|
||||
ICreateRenderRequest( i );
|
||||
}
|
||||
else
|
||||
{
|
||||
fCubic = nil;
|
||||
for( i = 0; i < 6; i++ )
|
||||
{
|
||||
delete fRequests[ i ];
|
||||
fRequests[ i ] = nil;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
return plModifier::MsgReceive( msg );
|
||||
}
|
||||
|
||||
//// AddTarget ////////////////////////////////////////////////////////////////
|
||||
|
||||
void plCubicRenderTargetModifier::AddTarget( plSceneObject *so )
|
||||
{
|
||||
if( fTarget != nil )
|
||||
RemoveTarget( fTarget );
|
||||
|
||||
fTarget = so;
|
||||
plgDispatch::Dispatch()->RegisterForExactType( plEvalMsg::Index(), GetKey() );
|
||||
}
|
||||
|
||||
//// RemoveTarget /////////////////////////////////////////////////////////////
|
||||
|
||||
void plCubicRenderTargetModifier::RemoveTarget( plSceneObject *so )
|
||||
{
|
||||
fTarget = nil;
|
||||
}
|
||||
|
||||
//// Read /////////////////////////////////////////////////////////////////////
|
||||
|
||||
void plCubicRenderTargetModifier::Read( hsStream *s, hsResMgr *mgr )
|
||||
{
|
||||
hsKeyedObject::Read( s, mgr );
|
||||
|
||||
plGenRefMsg* msg;
|
||||
msg = TRACKED_NEW plGenRefMsg( GetKey(), plRefMsg::kOnCreate, 0, 0 ); // SceneObject
|
||||
mgr->ReadKeyNotifyMe( s, msg, plRefFlags::kActiveRef );
|
||||
|
||||
msg = TRACKED_NEW plGenRefMsg( GetKey(), plRefMsg::kOnCreate, 0, 0 ); // cubicRT
|
||||
mgr->ReadKeyNotifyMe( s, msg, plRefFlags::kActiveRef );
|
||||
}
|
||||
|
||||
//// Write ////////////////////////////////////////////////////////////////////
|
||||
|
||||
void plCubicRenderTargetModifier::Write( hsStream *s, hsResMgr *mgr )
|
||||
{
|
||||
hsKeyedObject::Write(s, mgr);
|
||||
|
||||
mgr->WriteKey( s, fTarget ); // Write the SceneNode
|
||||
mgr->WriteKey( s, fCubic ); // Write the cubicRT
|
||||
}
|
@ -0,0 +1,87 @@
|
||||
/*==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/>.
|
||||
|
||||
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==*/
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// plCubicRenderTargetModifier Class Header //
|
||||
// Modifier applied to an object to specify the source object to render a //
|
||||
// cubicRenderTarget from. Owns a key to the cubicRenderTarget in question, //
|
||||
// which it updates with positions and submits renderRequests for. //
|
||||
// //
|
||||
// Cyan, Inc. //
|
||||
// //
|
||||
//// Version History //////////////////////////////////////////////////////////
|
||||
// //
|
||||
// 7.20.2001 mcn - Created. //
|
||||
// //
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef _plCubicRenderTargetModifier_h
|
||||
#define _plCubicRenderTargetModifier_h
|
||||
|
||||
#include "../../NucleusLib/pnModifier/plModifier.h"
|
||||
#include "../pnNetCommon/plSynchedValue.h"
|
||||
|
||||
|
||||
class plCubicRenderTarget;
|
||||
class plRenderRequest;
|
||||
|
||||
//// Class Definition /////////////////////////////////////////////////////////
|
||||
|
||||
class plCubicRenderTargetModifier : public plModifier
|
||||
{
|
||||
|
||||
public:
|
||||
plCubicRenderTargetModifier();
|
||||
virtual ~plCubicRenderTargetModifier();
|
||||
|
||||
CLASSNAME_REGISTER( plCubicRenderTargetModifier );
|
||||
GETINTERFACE_ANY( plCubicRenderTargetModifier, plModifier);
|
||||
|
||||
// Functions related to/required by plModifier
|
||||
virtual int GetNumTargets( void ) const { return fTarget ? 1 : 0; }
|
||||
virtual plSceneObject *GetTarget( int w ) const { hsAssert(w < GetNumTargets(), "Bad target"); return fTarget; }
|
||||
virtual void AddTarget( plSceneObject* so );
|
||||
virtual void RemoveTarget( plSceneObject* so );
|
||||
|
||||
virtual void Read( hsStream* s, hsResMgr* mgr );
|
||||
virtual void Write( hsStream* s, hsResMgr* mgr );
|
||||
virtual hsBool MsgReceive( plMessage* msg );
|
||||
|
||||
protected:
|
||||
|
||||
plSceneObject *fTarget;
|
||||
plCubicRenderTarget *fCubic;
|
||||
|
||||
plRenderRequest *fRequests[ 6 ];
|
||||
|
||||
virtual hsBool IEval( double secs, hsScalar del, UInt32 dirty ); // required by plModifier
|
||||
|
||||
void ICreateRenderRequest( int face );
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif //_plCubicRenderTargetModifier_h
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,207 @@
|
||||
/*==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/>.
|
||||
|
||||
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 plCullTree_inc
|
||||
#define plCullTree_inc
|
||||
|
||||
#include "hsBounds.h"
|
||||
#include "hsGeometry3.h"
|
||||
#include "hsBitVector.h"
|
||||
#include "plCuller.h"
|
||||
#include "../plScene/plCullPoly.h"
|
||||
|
||||
#ifdef HS_DEBUGGING
|
||||
#define DEBUG_POINTERS
|
||||
#endif // HS_DEBUGGING
|
||||
|
||||
class plCullTree;
|
||||
class plCullNode;
|
||||
|
||||
// for vis
|
||||
struct hsPoint3;
|
||||
struct hsVector3;
|
||||
struct hsColorRGBA;
|
||||
|
||||
class plCullTree : public plCuller
|
||||
{
|
||||
protected:
|
||||
|
||||
// Visualization stuff, to be nuked from production version.
|
||||
mutable hsBool fCapturePolys;
|
||||
mutable hsTArray<hsPoint3> fVisVerts;
|
||||
mutable hsTArray<hsVector3> fVisNorms;
|
||||
mutable hsTArray<hsColorRGBA> fVisColors;
|
||||
mutable hsTArray<UInt16> fVisTris;
|
||||
mutable hsScalar fVisYon;
|
||||
|
||||
mutable hsTArray<plCullPoly> fScratchPolys;
|
||||
mutable hsLargeArray<Int16> fScratchClear;
|
||||
mutable hsLargeArray<Int16> fScratchSplit;
|
||||
mutable hsLargeArray<Int16> fScratchCulled;
|
||||
mutable hsBitVector fScratchBitVec;
|
||||
mutable hsBitVector fScratchTotVec;
|
||||
|
||||
void IVisPolyShape(const plCullPoly& poly, hsBool dark) const;
|
||||
void IVisPolyEdge(const hsPoint3& p0, const hsPoint3& p1, hsBool dark) const;
|
||||
void IVisPoly(const plCullPoly& poly, hsBool dark) const;
|
||||
|
||||
|
||||
hsPoint3 fViewPos;
|
||||
|
||||
Int16 fRoot;
|
||||
mutable hsTArray<plCullNode> fNodeList; // Scratch list we make the tree from.
|
||||
plCullNode* IGetRoot() const { return IGetNode(fRoot); }
|
||||
plCullNode* IGetNode(Int16 i) const { return i >= 0 ? &fNodeList[i] : nil; }
|
||||
|
||||
void ITestNode(const plSpaceTree* space, Int16 who, hsTArray<Int16>& outList) const; // Appends to outlist
|
||||
void ITestList(const plSpaceTree* space, const hsTArray<Int16>& inList, hsTArray<Int16>& outList) const;
|
||||
|
||||
Int16 IAddPolyRecur(const plCullPoly& poly, Int16 iNode);
|
||||
Int16 IMakeHoleSubTree(const plCullPoly& poly) const;
|
||||
Int16 IMakePolySubTree(const plCullPoly& poly) const;
|
||||
Int16 IMakePolyNode(const plCullPoly& poly, int i0, int i1) const;
|
||||
|
||||
// Some scratch areas for the nodes use when building the tree etc.
|
||||
hsTArray<plCullPoly>& ScratchPolys() const { return fScratchPolys; }
|
||||
hsLargeArray<Int16>& ScratchClear() const { return fScratchClear; }
|
||||
hsLargeArray<Int16>& ScratchSplit() const { return fScratchSplit; }
|
||||
hsLargeArray<Int16>& ScratchCulled() const { return fScratchCulled; }
|
||||
hsBitVector& ScratchBitVec() const { return fScratchBitVec; }
|
||||
hsBitVector& ScratchTotVec() const { return fScratchTotVec; }
|
||||
|
||||
void ISetupScratch(UInt16 nNodes);
|
||||
|
||||
friend class plCullNode;
|
||||
|
||||
public:
|
||||
plCullTree();
|
||||
~plCullTree();
|
||||
|
||||
void Reset(); // Called before starting to add polys for this frame.
|
||||
void InitFrustum(const hsMatrix44& world2NDC);
|
||||
void SetViewPos(const hsPoint3& pos);
|
||||
void AddPoly(const plCullPoly& poly);
|
||||
|
||||
UInt32 GetNumNodes() const { return fNodeList.GetCount(); }
|
||||
|
||||
virtual void Harvest(const plSpaceTree* space, hsTArray<Int16>& outList) const;
|
||||
virtual hsBool BoundsVisible(const hsBounds3Ext& bnd) const;
|
||||
virtual hsBool SphereVisible(const hsPoint3& center, hsScalar rad) const;
|
||||
|
||||
// Visualization stuff. Only to be called by the pipeline (or some other vis manager).
|
||||
void SetVisualizationYon(hsScalar y) const { fVisYon = y; }
|
||||
void BeginCapturePolys() const { fCapturePolys = true; }
|
||||
void EndCapturePolys() const { fCapturePolys = false; }
|
||||
hsTArray<hsPoint3>& GetCaptureVerts() const { return fVisVerts; }
|
||||
hsTArray<hsVector3>& GetCaptureNorms() const { return fVisNorms; }
|
||||
hsTArray<hsColorRGBA>& GetCaptureColors() const { return fVisColors; }
|
||||
hsTArray<UInt16>& GetCaptureTris() const { return fVisTris; }
|
||||
void ReleaseCapture() const;
|
||||
};
|
||||
|
||||
class plCullNode
|
||||
{
|
||||
public:
|
||||
enum plCullStatus
|
||||
{
|
||||
kClear,
|
||||
kCulled,
|
||||
kSplit,
|
||||
kPureSplit
|
||||
};
|
||||
protected:
|
||||
hsVector3 fNorm;
|
||||
hsScalar fDist;
|
||||
|
||||
hsBool fIsFace;
|
||||
|
||||
Int16 fInnerChild;
|
||||
Int16 fOuterChild;
|
||||
|
||||
const plCullTree* fTree;
|
||||
|
||||
plCullNode* IGetNode(Int16 i) const;
|
||||
|
||||
#ifdef DEBUG_POINTERS
|
||||
mutable plCullNode* fInnerPtr;
|
||||
mutable plCullNode* fOuterPtr;
|
||||
|
||||
void ISetPointersRecur() const;
|
||||
#else // DEBUG_POINTERS
|
||||
void ISetPointersRecur() const {}
|
||||
#endif // DEBUG_POINTERS
|
||||
|
||||
// Bounds only version
|
||||
plCullNode::plCullStatus ITestBoundsRecur(const hsBounds3Ext& bnd) const;
|
||||
plCullNode::plCullStatus ITestSphereRecur(const hsPoint3& center, hsScalar rad) const;
|
||||
|
||||
// Using the nodes
|
||||
plCullNode::plCullStatus ITestNode(const plSpaceTree* space, Int16 who, hsLargeArray<Int16>& clear, hsLargeArray<Int16>& split, hsLargeArray<Int16>& culled) const;
|
||||
void ITestNode(const plSpaceTree* space, Int16 who, hsBitVector& totList, hsBitVector& outList) const;
|
||||
void IHarvest(const plSpaceTree* space, hsTArray<Int16>& outList) const;
|
||||
|
||||
// Constructing the tree
|
||||
hsScalar IInterpVert(const hsPoint3& p0, const hsPoint3& p1, hsPoint3& out) const;
|
||||
plCullNode::plCullStatus ISplitPoly(const plCullPoly& poly, plCullPoly*& innerPoly, plCullPoly*& outerPoly) const;
|
||||
void IMarkClipped(const plCullPoly& poly, const hsBitVector& onVerts) const;
|
||||
void ITakeHalfPoly(const plCullPoly& scrPoly,
|
||||
const hsTArray<int>& vtxIdx,
|
||||
const hsBitVector& onVerts,
|
||||
plCullPoly& outPoly) const;
|
||||
void IBreakPoly(const plCullPoly& poly, const hsTArray<hsScalar>& depths,
|
||||
hsBitVector& inVerts,
|
||||
hsBitVector& outVerts,
|
||||
hsBitVector& onVerts,
|
||||
plCullPoly& srcPoly) const;
|
||||
|
||||
hsTArray<plCullPoly>& ScratchPolys() const { return fTree->ScratchPolys(); }
|
||||
hsLargeArray<Int16>& ScratchClear() const { return fTree->ScratchClear(); }
|
||||
hsLargeArray<Int16>& ScratchSplit() const { return fTree->ScratchSplit(); }
|
||||
hsLargeArray<Int16>& ScratchCulled() const { return fTree->ScratchCulled(); }
|
||||
hsBitVector& ScratchBitVec() const { return fTree->ScratchBitVec(); }
|
||||
hsBitVector& ScratchTotVec() const { return fTree->ScratchTotVec(); }
|
||||
|
||||
friend class plCullTree;
|
||||
public:
|
||||
|
||||
void Init(const plCullTree* t, const hsVector3& n, hsScalar d) { fIsFace = false; fTree = t; fInnerChild = fOuterChild = -1; SetPlane(n, d); }
|
||||
void Init(const plCullTree* t, const plCullPoly& poly) { Init(t, poly.fNorm, poly.fDist); }
|
||||
|
||||
void SetPlane(const hsVector3& n, hsScalar d) { fNorm = n; fDist = d; }
|
||||
|
||||
const hsVector3& GetNormal() const { return fNorm; }
|
||||
const hsScalar GetDist() const { return fDist; }
|
||||
|
||||
plCullStatus TestBounds(const hsBounds3Ext& bnd) const;
|
||||
plCullStatus TestSphere(const hsPoint3& center, hsScalar rad) const;
|
||||
};
|
||||
|
||||
inline plCullNode* plCullNode::IGetNode(Int16 i) const
|
||||
{
|
||||
return fTree->IGetNode(i);
|
||||
}
|
||||
|
||||
#endif // plCullTree_inc
|
@ -0,0 +1,44 @@
|
||||
/*==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/>.
|
||||
|
||||
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 plCuller_inc
|
||||
#define plCuller_inc
|
||||
|
||||
#include "hsTemplates.h"
|
||||
|
||||
class plSpaceTree;
|
||||
|
||||
class plCuller
|
||||
{
|
||||
|
||||
public:
|
||||
plCuller() {}
|
||||
~plCuller() {}
|
||||
|
||||
virtual void Harvest(const plSpaceTree* space, hsTArray<Int16>& outList) const = 0;
|
||||
};
|
||||
|
||||
#endif // plCuller_inc
|
@ -0,0 +1,238 @@
|
||||
/*==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/>.
|
||||
|
||||
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==*/
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// plDTProgressMgr Functions //
|
||||
// //
|
||||
//// History /////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// 2.28.2001 mcn - Created //
|
||||
// //
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <stdlib.h>
|
||||
#include "hsTypes.h"
|
||||
#include "plDTProgressMgr.h"
|
||||
#include "plPipeline.h"
|
||||
#include "plDebugText.h"
|
||||
#include "plPlates.h"
|
||||
|
||||
#include "../Apps/plClient/res/resource.h"
|
||||
|
||||
#include "hsTimer.h"
|
||||
|
||||
|
||||
//// Constructor & Destructor ////////////////////////////////////////////////
|
||||
|
||||
plDTProgressMgr::plDTProgressMgr() :
|
||||
fCurrentImage(0),
|
||||
fLastDraw(0.0f),
|
||||
fStaticTextPlate(nil),
|
||||
fActivePlate(nil)
|
||||
{
|
||||
}
|
||||
|
||||
plDTProgressMgr::~plDTProgressMgr()
|
||||
{
|
||||
}
|
||||
|
||||
void plDTProgressMgr::DeclareThyself( void )
|
||||
{
|
||||
static plDTProgressMgr thyself;
|
||||
}
|
||||
|
||||
void plDTProgressMgr::Activate()
|
||||
{
|
||||
if (fStaticTextPlate == nil && fCurrentStaticText != plProgressMgr::kNone)
|
||||
{
|
||||
plPlateManager::Instance().CreatePlate(&fStaticTextPlate);
|
||||
|
||||
fStaticTextPlate->CreateFromJPEGResource(MAKEINTRESOURCE(plProgressMgr::GetStaticTextID(fCurrentStaticText)), 0);
|
||||
fStaticTextPlate->SetVisible(true);
|
||||
fStaticTextPlate->SetOpacity(1.0f);
|
||||
fStaticTextPlate->SetSize(2 * 0.192f, 2 * 0.041f, true);
|
||||
fStaticTextPlate->SetPosition(0, 0.5f, 0);
|
||||
}
|
||||
|
||||
if (fActivePlate == nil)
|
||||
{
|
||||
plPlateManager::Instance().CreatePlate( &fActivePlate );
|
||||
|
||||
fActivePlate->CreateFromJPEGResource( MAKEINTRESOURCE( plProgressMgr::GetLoadingFrameID(fCurrentImage) ), 0 );
|
||||
fActivePlate->SetVisible(true);
|
||||
fActivePlate->SetOpacity(1.0f);
|
||||
fActivePlate->SetSize(0.6, 0.6, true);
|
||||
fActivePlate->SetPosition(0, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void plDTProgressMgr::Deactivate()
|
||||
{
|
||||
if (fStaticTextPlate)
|
||||
{
|
||||
fStaticTextPlate->SetVisible(false);
|
||||
plPlateManager::Instance().DestroyPlate( fStaticTextPlate );
|
||||
fStaticTextPlate = nil;
|
||||
}
|
||||
|
||||
if (fActivePlate)
|
||||
{
|
||||
fActivePlate->SetVisible(false);
|
||||
plPlateManager::Instance().DestroyPlate( fActivePlate );
|
||||
fActivePlate = nil;
|
||||
}
|
||||
}
|
||||
|
||||
//// Draw ////////////////////////////////////////////////////////////////////
|
||||
|
||||
void plDTProgressMgr::Draw( plPipeline *p )
|
||||
{
|
||||
UInt16 scrnWidth, scrnHeight, width, height, x, y;
|
||||
plDebugText &text = plDebugText::Instance();
|
||||
|
||||
plOperationProgress *prog;
|
||||
|
||||
|
||||
if( fOperations == nil )
|
||||
return;
|
||||
|
||||
scrnWidth = (UInt16)p->Width();
|
||||
scrnHeight = (UInt16)p->Height();
|
||||
|
||||
width = scrnWidth - 64;
|
||||
height = 16;
|
||||
x = ( scrnWidth - width ) >> 1;
|
||||
y = scrnHeight - 32 - height;
|
||||
if( fOperations->GetNext() == nil )
|
||||
y -= text.GetFontSize() + 8 + height + 4;
|
||||
|
||||
|
||||
text.SetDrawOnTopMode( true );
|
||||
|
||||
if (fActivePlate)
|
||||
{
|
||||
float currentMs = hsTimer::FullTicksToMs(hsTimer::GetFullTickCount());
|
||||
if ((currentMs - fLastDraw) > 30)
|
||||
{
|
||||
fCurrentImage++;
|
||||
if (fCurrentImage >= 18)
|
||||
fCurrentImage = 0;
|
||||
|
||||
fLastDraw = currentMs;
|
||||
|
||||
fActivePlate->ReloadFromJPEGResource(MAKEINTRESOURCE(plProgressMgr::GetInstance()->GetLoadingFrameID(fCurrentImage)), 0);
|
||||
fActivePlate->SetVisible(true);
|
||||
fActivePlate->SetOpacity(1.0f);
|
||||
fActivePlate->SetSize(0.6, 0.6, true);
|
||||
fActivePlate->SetPosition(0, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
for( prog = fOperations; prog != nil; prog = prog->GetNext() )
|
||||
{
|
||||
IDrawTheStupidThing( p, prog, x, y, width, height );
|
||||
y -= text.GetFontSize() + 8 + height + 4;
|
||||
}
|
||||
|
||||
text.SetDrawOnTopMode( false );
|
||||
}
|
||||
|
||||
//// IDrawTheStupidThing /////////////////////////////////////////////////////
|
||||
|
||||
void plDTProgressMgr::IDrawTheStupidThing( plPipeline *p, plOperationProgress *prog,
|
||||
UInt16 x, UInt16 y, UInt16 width, UInt16 height )
|
||||
{
|
||||
plDebugText &text = plDebugText::Instance();
|
||||
|
||||
// Lets just set the color to blue
|
||||
UInt32 color = 0xff302b3a;
|
||||
|
||||
if( prog->GetMax() > 0.f )
|
||||
{
|
||||
text.Draw3DBorder(x, y, x + width - 1, y + height - 1, color, color);
|
||||
|
||||
x += 2;
|
||||
y += 2;
|
||||
width -= 4;
|
||||
height -= 4;
|
||||
|
||||
UInt16 drawWidth = width;
|
||||
Int16 drawX = x;
|
||||
UInt16 rightX = drawX + drawWidth;
|
||||
|
||||
if (prog->GetProgress() <= prog->GetMax())
|
||||
drawWidth = (UInt16)( (hsScalar)width * prog->GetProgress() / prog->GetMax() );
|
||||
|
||||
rightX = drawX + drawWidth;
|
||||
|
||||
if( drawWidth > 0 )
|
||||
text.DrawRect( drawX, y, rightX, y + height, color );
|
||||
|
||||
int timeRemain = prog->fRemainingSecs;
|
||||
char remainStr[1024];
|
||||
strcpy(remainStr, "APPROXIMATELY ");
|
||||
if (timeRemain > 3600)
|
||||
{
|
||||
const char* term = ((timeRemain / 3600) > 1) ? "HOURS" : "HOUR";
|
||||
sprintf(remainStr, "%s%d %s ", remainStr, (timeRemain / 3600), term);
|
||||
timeRemain %= 3600;
|
||||
}
|
||||
if (timeRemain > 60)
|
||||
{
|
||||
const char* term = ((timeRemain / 60) > 1) ? "MINUTES" : "MINUTE";
|
||||
sprintf(remainStr, "%s%d %s ", remainStr, (timeRemain / 60), term);
|
||||
timeRemain %= 60;
|
||||
}
|
||||
const char* unitTerm = (timeRemain == 1) ? "SECOND" : "SECONDS";
|
||||
sprintf(remainStr, "%s%d %s REMAINING", remainStr, timeRemain, unitTerm);
|
||||
|
||||
text.DrawString(x, y + height + 2, remainStr, (UInt32)0xff635e6d );
|
||||
|
||||
x -= 2;
|
||||
y -= 2;
|
||||
}
|
||||
|
||||
y -= ( text.GetFontSize() << 1 ) + 4;
|
||||
|
||||
#ifndef PLASMA_EXTERNAL_RELEASE
|
||||
bool drawText = true;
|
||||
#else
|
||||
bool drawText = false;
|
||||
#endif
|
||||
|
||||
if (drawText)
|
||||
{
|
||||
if( prog->GetTitle()[ 0 ] != 0 )
|
||||
{
|
||||
text.DrawString( x, y, prog->GetTitle(), (UInt32)0xccb0b0b0 );
|
||||
x += (UInt16)text.CalcStringWidth( prog->GetTitle() );
|
||||
}
|
||||
|
||||
if( prog->GetStatusText()[ 0 ] != 0 )
|
||||
text.DrawString( x, y, prog->GetStatusText(), (UInt32)0xccb0b0b0 );
|
||||
}
|
||||
}
|
||||
|
@ -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/>.
|
||||
|
||||
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==*/
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// plDTProgressMgr Header //
|
||||
// //
|
||||
//// Description /////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// Derived class of plProgressMgr to draw the progress bars via debug text.//
|
||||
// //
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef _plDTProgressMgr_h
|
||||
#define _plDTProgressMgr_h
|
||||
|
||||
#include "../plProgressMgr/plProgressMgr.h"
|
||||
|
||||
class plPipeline;
|
||||
|
||||
//// Manager Class Definition ////////////////////////////////////////////////
|
||||
|
||||
class plDTProgressMgr : public plProgressMgr
|
||||
{
|
||||
protected:
|
||||
Int32 fCurrentImage;
|
||||
float fLastDraw;
|
||||
plPlate* fActivePlate;
|
||||
plPlate* fStaticTextPlate;
|
||||
StaticText fShowingStaticText;
|
||||
|
||||
void Activate();
|
||||
void Deactivate();
|
||||
|
||||
void IDrawTheStupidThing( plPipeline *p, plOperationProgress *prog,
|
||||
UInt16 x, UInt16 y, UInt16 width, UInt16 height );
|
||||
|
||||
public:
|
||||
|
||||
plDTProgressMgr();
|
||||
~plDTProgressMgr();
|
||||
|
||||
virtual void Draw( plPipeline *p );
|
||||
|
||||
static void DeclareThyself( void );
|
||||
};
|
||||
|
||||
|
||||
#endif //_plDTProgressMgr_h
|
||||
|
@ -0,0 +1,155 @@
|
||||
/*==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/>.
|
||||
|
||||
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 fCount;
|
||||
UInt32 fIndex;
|
||||
UInt32 fVertexSize;
|
||||
Int32 fOffset;
|
||||
UInt8 fFormat;
|
||||
|
||||
plGBufferGroup* fOwner;
|
||||
UInt8* fData;
|
||||
IDirect3DDevice9* fDevice; // For releasing the VertexShader
|
||||
|
||||
UInt32 fRefTime;
|
||||
|
||||
enum {
|
||||
kRebuiltSinceUsed = 0x10, // kDirty = 0x1 is in hsGDeviceRef
|
||||
kVolatile = 0x20,
|
||||
kSkinned = 0x40
|
||||
};
|
||||
|
||||
hsBool HasFlag(UInt32 f) const { return 0 != (fFlags & f); }
|
||||
void SetFlag(UInt32 f, hsBool on) { if(on) fFlags |= f; else fFlags &= ~f; }
|
||||
|
||||
hsBool RebuiltSinceUsed() const { return HasFlag(kRebuiltSinceUsed); }
|
||||
void SetRebuiltSinceUsed(hsBool b) { SetFlag(kRebuiltSinceUsed, b); }
|
||||
|
||||
hsBool Volatile() const { return HasFlag(kVolatile); }
|
||||
void SetVolatile(hsBool b) { SetFlag(kVolatile, b); }
|
||||
|
||||
hsBool Skinned() const { return HasFlag(kSkinned); }
|
||||
void SetSkinned(hsBool b) { SetFlag(kSkinned, b); }
|
||||
|
||||
hsBool Expired(UInt32 t) const { return Volatile() && (IsDirty() || (fRefTime != t)); }
|
||||
void SetRefTime(UInt32 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 fCount;
|
||||
UInt32 fIndex;
|
||||
Int32 fOffset;
|
||||
plGBufferGroup* fOwner;
|
||||
UInt32 fRefTime;
|
||||
D3DPOOL fPoolType;
|
||||
|
||||
enum {
|
||||
kRebuiltSinceUsed = 0x10, // kDirty = 0x1 is in hsGDeviceRef
|
||||
kVolatile = 0x20
|
||||
};
|
||||
|
||||
hsBool HasFlag(UInt32 f) const { return 0 != (fFlags & f); }
|
||||
void SetFlag(UInt32 f, hsBool on) { if(on) fFlags |= f; else fFlags &= ~f; }
|
||||
|
||||
hsBool RebuiltSinceUsed() const { return HasFlag(kRebuiltSinceUsed); }
|
||||
void SetRebuiltSinceUsed(hsBool b) { SetFlag(kRebuiltSinceUsed, b); }
|
||||
|
||||
hsBool Volatile() const { return HasFlag(kVolatile); }
|
||||
void SetVolatile(hsBool b) { SetFlag(kVolatile, b); }
|
||||
|
||||
hsBool Expired(UInt32 t) const { return Volatile() && (IsDirty() || (fRefTime != t)); }
|
||||
void SetRefTime(UInt32 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
|
@ -0,0 +1,66 @@
|
||||
/*==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/>.
|
||||
|
||||
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 "hsTypes.h"
|
||||
#include "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; }
|
||||
hsBool IsLinked( void ) { return fBack != nil; }
|
||||
virtual void Release( void ) { }
|
||||
|
||||
plDXDeviceRef();
|
||||
|
||||
virtual ~plDXDeviceRef();
|
||||
};
|
||||
|
||||
|
||||
#endif // _plDXDeviceRef_h
|
@ -0,0 +1,514 @@
|
||||
/*==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/>.
|
||||
|
||||
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 "hsTypes.h"
|
||||
|
||||
#include <d3d9.h>
|
||||
#include <ddraw.h>
|
||||
|
||||
#include "hsWinRef.h"
|
||||
|
||||
#include "plDXPipeline.h"
|
||||
#include "plDXDeviceRef.h"
|
||||
#include "plDXBufferRefs.h"
|
||||
#include "plDXLightRef.h"
|
||||
#include "plDXTextureRef.h"
|
||||
#include "plDXRenderTargetRef.h"
|
||||
#include "plGBufferGroup.h"
|
||||
#include "../plDrawable/plGeometrySpan.h"
|
||||
#include "../plDrawable/plDrawableSpans.h"
|
||||
#include "../plGLight/plLightInfo.h"
|
||||
#include "plRenderTarget.h"
|
||||
#include "plCubicRenderTarget.h"
|
||||
#include "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));
|
||||
PROFILE_POOL_MEM(fPoolType, fCount * sizeof(UInt16), false, "IndexBuff");
|
||||
ReleaseObject( fD3DBuffer );
|
||||
}
|
||||
|
||||
SetDirty( true );
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//// plDXTextureRef Funktions ////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//// Set //////////////////////////////////////////////////////////////////////
|
||||
|
||||
plDXTextureRef& plDXTextureRef::Set( D3DFORMAT ft, UInt32 ml, UInt32 mw, UInt32 mh, UInt32 np,
|
||||
UInt32 sz, UInt32 manSize, UInt32* lSz, void* pd, hsBool ed, hsBool 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 = TRACKED_NEW UInt32[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 ml, UInt32 mw, UInt32 mh, UInt32 np,
|
||||
UInt32 sz, UInt32 manSize, UInt32* lSz, void* pd, hsBool ed, hsBool renderTarget )
|
||||
{
|
||||
fLevelSizes = nil;
|
||||
fOwner = nil;
|
||||
fD3DTexture = nil;
|
||||
fDataSize = 0;
|
||||
fFlags = 0;
|
||||
fFormatType = D3DFMT_UNKNOWN;
|
||||
fMMLvs = 0;
|
||||
fMaxWidth = 0;
|
||||
fMaxHeight = 0;
|
||||
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() : "(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() ? hsScalarPI : 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 ml, plRenderTarget *owner, hsBool 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 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 );
|
||||
}
|
||||
|
@ -0,0 +1,893 @@
|
||||
/*==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/>.
|
||||
|
||||
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 "hsGDDrawDllLoad.h"
|
||||
#include "hsG3DDeviceSelector.h"
|
||||
#include "hsUtils.h"
|
||||
|
||||
//// Local Typedefs ///////////////////////////////////////////////////////////
|
||||
|
||||
typedef LPDIRECT3D9 (WINAPI * Direct3DCreateProc)( UINT sdkVersion );
|
||||
|
||||
const UInt8 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 !HS_BUILD_FOR_XBOX
|
||||
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
|
||||
#endif
|
||||
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 !HS_BUILD_FOR_XBOX
|
||||
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 );
|
||||
#else
|
||||
IDirect3D9 *pD3D = Direct3DCreate9( D3D_SDK_VERSION );
|
||||
#endif
|
||||
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 = TRACKED_NEW BOOL[kNumDisplayFormats + 1]; // One for each format
|
||||
DWORD *behavior = TRACKED_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 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.
|
||||
|
||||
hsBool hsGDirect3DTnLEnumerate::IFindDepthFormats( IDirect3D9 *pD3D, UINT iAdapter, D3DDEVTYPE deviceType,
|
||||
D3DEnum_ModeInfo *modeInfo )
|
||||
{
|
||||
#if HS_BUILD_FOR_XBOX
|
||||
D3DFORMAT formats[] = { D3DFMT_D16, D3DFMT_D24S8, D3DFMT_UNKNOWN };
|
||||
#else
|
||||
D3DFORMAT formats[] = { D3DFMT_D16, D3DFMT_D24X8, D3DFMT_D32,
|
||||
D3DFMT_D15S1, D3DFMT_D24X4S4, D3DFMT_D24S8, D3DFMT_UNKNOWN };
|
||||
#endif
|
||||
|
||||
/// 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.
|
||||
|
||||
hsBool 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 /////////////////////////////////////////////////
|
||||
|
||||
hsBool 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.
|
||||
|
||||
hsBool hsG3DDeviceSelector::IGetD3DCardInfo( hsG3DDeviceRecord &record, // In
|
||||
void *driverInfo,
|
||||
void *deviceInfo,
|
||||
DWORD *vendorID, DWORD *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)adapterInfo->VendorId );
|
||||
plDemoDebugFile::Write( " Device ID", (Int32)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 ////////////////////////////////////////////////////////////
|
||||
|
||||
hsBool 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)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 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 );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,184 @@
|
||||
/*==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/>.
|
||||
|
||||
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 "hsConfig.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 );
|
||||
hsBool IFindDepthFormats( IDirect3D9 *pD3D, UINT iAdapter, D3DDEVTYPE deviceType, D3DEnum_ModeInfo *modeInfo );
|
||||
hsBool IFindFSAATypes( IDirect3D9 *pD3D, UINT iAdapter, D3DDEVTYPE deviceType, D3DEnum_ModeInfo *modeInfo );
|
||||
hsBool ICheckCubicRenderTargets( IDirect3D9 *pD3D, UINT iAdapter, D3DDEVTYPE deviceType, D3DEnum_ModeInfo *modeInfo );
|
||||
HRESULT IConfirmDevice( D3DCAPS9* pCaps, DWORD dwBehavior, D3DFORMAT format );
|
||||
|
||||
static const UInt8 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 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
|
@ -0,0 +1,81 @@
|
||||
/*==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/>.
|
||||
|
||||
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 fD3DIndex;
|
||||
hsScalar 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
@ -0,0 +1,818 @@
|
||||
/*==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/>.
|
||||
|
||||
You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
||||
or by snail mail at:
|
||||
Cyan Worlds, Inc.
|
||||
14617 N Newport Hwy
|
||||
Mead, WA 99021
|
||||
|
||||
*==LICENSE==*/
|
||||
#ifndef _plDX9Pipeline_h
|
||||
#define _plDX9Pipeline_h
|
||||
|
||||
#include "plPipeline.h"
|
||||
#include "plDXSettings.h"
|
||||
|
||||
#include "../plSurface/plLayerInterface.h"
|
||||
#include "hsMatrix44.h"
|
||||
#include "plFogEnvironment.h"
|
||||
#include "hsG3DDeviceSelector.h"
|
||||
#include "hsGeometry3.h"
|
||||
#include "hsTemplates.h"
|
||||
#include "hsColorRGBA.h"
|
||||
#include "hsGDeviceRef.h"
|
||||
#include "hsPoint2.h"
|
||||
|
||||
class plAccessSpan;
|
||||
class plAuxSpan;
|
||||
class plVertexSpan;
|
||||
|
||||
#include "plPlates.h" // Used to define plDXPlateManager
|
||||
|
||||
|
||||
//// Defines and Konstants and Other Nifty Stuff //////////////////////////////
|
||||
|
||||
class plDXLightRef;
|
||||
class plDXVertexBufferRef;
|
||||
class plDXIndexBufferRef;
|
||||
class plDXTextureRef;
|
||||
class plDXCubeTextureRef;
|
||||
class plDXVertexShader;
|
||||
class plDXPixelShader;
|
||||
|
||||
class plShader;
|
||||
|
||||
class plVisMgr;
|
||||
|
||||
//#define HS_D3D_USE_SPECULAR
|
||||
|
||||
class hsGMaterial;
|
||||
class plMipmap;
|
||||
|
||||
class plLightInfo;
|
||||
class plCullTree;
|
||||
class plShadowSlave;
|
||||
class plShadowCaster;
|
||||
|
||||
struct D3DXMATRIX;
|
||||
|
||||
#ifdef HS_DEBUGGING
|
||||
#define HS_CHECK_RELEASE
|
||||
#endif
|
||||
|
||||
#ifndef PLASMA_EXTERNAL_RELEASE
|
||||
#define PROFILE_POOL_MEM(pool, size, add, id) plDXPipeline::ProfilePoolMem(pool, size, add, id);
|
||||
#else
|
||||
#define PROFILE_POOL_MEM(pool, size, add, id)
|
||||
#endif // PLASMA_EXTERNAL_RELEASE
|
||||
|
||||
extern void D3DSURF_MEMNEW(IDirect3DSurface9* surf);
|
||||
extern void D3DSURF_MEMNEW(IDirect3DTexture9* tex);
|
||||
extern void D3DSURF_MEMNEW(IDirect3DCubeTexture9* cTex);
|
||||
extern void D3DSURF_MEMDEL(IDirect3DSurface9* surf);
|
||||
extern void D3DSURF_MEMDEL(IDirect3DTexture9* tex);
|
||||
extern void D3DSURF_MEMDEL(IDirect3DCubeTexture9* cTex);
|
||||
|
||||
|
||||
extern void plReleaseObject(IUnknown* x);
|
||||
|
||||
#define ReleaseObject(x) if(x){ plReleaseObject(x); x=NULL; }
|
||||
|
||||
typedef LPDIRECT3D9 (WINAPI * Direct3DCreateProc)( UINT sdkVersion );
|
||||
|
||||
|
||||
//// Helper Classes ///////////////////////////////////////////////////////////
|
||||
|
||||
//// The RenderPrimFunc lets you have one function which does a lot of stuff
|
||||
// around the actual call to render whatever type of primitives you have, instead
|
||||
// of duplicating everything because the one line to render is different.
|
||||
class plRenderPrimFunc
|
||||
{
|
||||
public:
|
||||
virtual hsBool RenderPrims() const = 0; // return true on error
|
||||
};
|
||||
|
||||
//// DX-specific Plate Manager implementation
|
||||
class plDXPlateManager : public plPlateManager
|
||||
{
|
||||
friend class plDXPipeline;
|
||||
|
||||
public:
|
||||
|
||||
virtual ~plDXPlateManager();
|
||||
|
||||
protected:
|
||||
|
||||
const long PLD3D_PLATEFVF;
|
||||
|
||||
struct plPlateVertex
|
||||
{
|
||||
hsPoint3 fPoint;
|
||||
UInt32 fColor;
|
||||
hsPoint3 fUV;
|
||||
};
|
||||
|
||||
IDirect3DDevice9 *fD3DDevice;
|
||||
IDirect3DVertexBuffer9 *fVertBuffer;
|
||||
|
||||
plDXPlateManager( plDXPipeline *pipe, IDirect3DDevice9 *device );
|
||||
|
||||
void ICreateGeometry(plDXPipeline* pipe);
|
||||
void IReleaseGeometry();
|
||||
|
||||
virtual void IDrawToDevice( plPipeline *pipe );
|
||||
};
|
||||
|
||||
//// Class Definition /////////////////////////////////////////////////////////
|
||||
|
||||
class plDebugTextManager;
|
||||
struct D3DEnum_DriverInfo;
|
||||
struct D3DEnum_DeviceInfo;
|
||||
struct D3DEnum_ModeInfo;
|
||||
class plGeometrySpan;
|
||||
class plDrawableSpans;
|
||||
class plSpan;
|
||||
class plIcicle;
|
||||
class hsG3DDeviceModeRecord;
|
||||
class plDXDeviceRef;
|
||||
class plParticleSpan;
|
||||
class plCubicEnvironmap;
|
||||
class plDXRenderTargetRef;
|
||||
class plStatusLogDrawer;
|
||||
class plBinkPlayer;
|
||||
|
||||
class plDXPipeline : public plPipeline
|
||||
{
|
||||
protected:
|
||||
enum {
|
||||
kCapsNone = 0x0,
|
||||
kCapsCompressTextures = 0x1,
|
||||
kCapsMipmap = 0x2,
|
||||
kCapsHWTransform = 0x4,
|
||||
kCapsHWLighting = 0x8,
|
||||
kCapsZBias = 0x10,
|
||||
kCapsLinearFog = 0x20,
|
||||
kCapsExpFog = 0x40,
|
||||
kCapsExp2Fog = 0x80,
|
||||
kCapsRangeFog = 0x100,
|
||||
kCapsWBuffer = 0x200,
|
||||
kCapsTexBoundToStage = 0x400,
|
||||
kCapsDither = 0x800,
|
||||
kCapsLODWatch = 0x1000,
|
||||
kCapsFSAntiAlias = 0x2000,
|
||||
kCapsLuminanceTextures = 0x4000,
|
||||
kCapsDoesSmallTextures = 0x8000,
|
||||
kCapsDoesWFog = 0x10000,
|
||||
kCapsPixelFog = 0x20000,
|
||||
kCapsHasBadYonStuff = 0x40000,
|
||||
kCapsNoKindaSmallTexs = 0x80000,
|
||||
|
||||
kCapsCubicTextures = 0x200000,
|
||||
kCapsCubicMipmap = 0x400000
|
||||
};
|
||||
enum {
|
||||
kKNone = 0x0,
|
||||
kKTNT = 0x1
|
||||
};
|
||||
|
||||
plDebugTextManager* fDebugTextMgr;
|
||||
plDXPlateManager* fPlateMgr;
|
||||
|
||||
// The main D3D interfaces
|
||||
LPDIRECT3D9 fD3DObject; // The main D3D object
|
||||
LPDIRECT3DDEVICE9 fD3DDevice; // The D3D rendering device
|
||||
IDirect3DSurface9* fD3DMainSurface;
|
||||
IDirect3DSurface9* fD3DDepthSurface;
|
||||
IDirect3DSurface9* fD3DBackBuff;
|
||||
|
||||
IDirect3DSurface9* fSharedDepthSurface[2];
|
||||
D3DFORMAT fSharedDepthFormat[2];
|
||||
|
||||
// Dynamic buffers
|
||||
UInt32 fVtxRefTime;
|
||||
UInt32 fNextDynVtx;
|
||||
UInt32 fDynVtxSize;
|
||||
IDirect3DVertexBuffer9* fDynVtxBuff;
|
||||
hsBool fManagedAlloced;
|
||||
hsBool fAllocUnManaged;
|
||||
|
||||
|
||||
// States
|
||||
plDXGeneralSettings fSettings;
|
||||
plDXTweakSettings fTweaks;
|
||||
plDXStencilSettings fStencil;
|
||||
hsBool fDeviceLost;
|
||||
hsBool fDevWasLost;
|
||||
|
||||
hsTArray<const plCullPoly*> fCullPolys;
|
||||
hsTArray<const plCullPoly*> fCullHoles;
|
||||
plDrawableSpans* fCullProxy;
|
||||
|
||||
plDXVertexBufferRef* fVtxBuffRefList;
|
||||
plDXIndexBufferRef* fIdxBuffRefList;
|
||||
plDXTextureRef* fTextureRefList;
|
||||
plTextFont* fTextFontRefList;
|
||||
plDXRenderTargetRef* fRenderTargetRefList;
|
||||
plDXVertexShader* fVShaderRefList;
|
||||
plDXPixelShader* fPShaderRefList;
|
||||
|
||||
hsGMaterial* fCurrMaterial;
|
||||
plLayerInterface* fCurrLay;
|
||||
UInt32 fCurrLayerIdx, fCurrNumLayers, fCurrRenderLayer;
|
||||
UInt32 fCurrLightingMethod; // Based on plSpan flags
|
||||
|
||||
D3DCULL fCurrCullMode;
|
||||
hsGMatState fMatOverOn;
|
||||
hsGMatState fMatOverOff;
|
||||
hsTArray<hsGMaterial*> fOverrideMat;
|
||||
hsGMaterial* fHoldMat;
|
||||
hsBool fCurrD3DLiteState;
|
||||
|
||||
hsMatrix44 fBumpDuMatrix;
|
||||
hsMatrix44 fBumpDvMatrix;
|
||||
hsMatrix44 fBumpDwMatrix;
|
||||
|
||||
hsTArray<plLayerInterface*> fOverLayerStack;
|
||||
plLayerInterface* fOverBaseLayer;
|
||||
plLayerInterface* fOverAllLayer;
|
||||
hsTArray<plLayerInterface*> fPiggyBackStack;
|
||||
Int32 fMatPiggyBacks;
|
||||
Int32 fActivePiggyBacks;
|
||||
|
||||
UINT fCurrentAdapter;
|
||||
D3DEnum_DriverInfo* fCurrentDriver;
|
||||
D3DEnum_DeviceInfo* fCurrentDevice;
|
||||
D3DEnum_ModeInfo* fCurrentMode;
|
||||
|
||||
hsGDeviceRef* fLayerRef[ 8 ];
|
||||
hsGMatState fLayerState[ 8 ]; // base stage (0) state is held in base class
|
||||
hsGMatState fOldLayerState[ 8 ];
|
||||
hsBool fLayerTransform[ 8 ];
|
||||
float fLayerLODBias[ 8 ];
|
||||
UInt32 fLayerUVWSrcs[ 8 ];
|
||||
UInt32 fLayerXformFlags[ 8 ];
|
||||
UInt32 fLastEndingStage;
|
||||
hsBool fTexturing;
|
||||
hsBool fForceMatHandle;
|
||||
|
||||
UInt32 fInSceneDepth;
|
||||
UInt32 fTextUseTime; // inc'd every frame - stat gather only
|
||||
static UInt32 fTexManaged;
|
||||
static UInt32 fTexUsed;
|
||||
static UInt32 fVtxManaged;
|
||||
static UInt32 fVtxUsed;
|
||||
UInt32 fEvictTime;
|
||||
UInt32 fManagedSeen;
|
||||
UInt32 fManagedCutoff;
|
||||
|
||||
double fTime; // World time.
|
||||
UInt32 fFrame; // inc'd every time the camera moves.
|
||||
UInt32 fRenderCnt; // inc'd every begin scene.
|
||||
|
||||
// View stuff
|
||||
plDXViewSettings fView;
|
||||
|
||||
hsBitVector fDebugFlags;
|
||||
UInt32 fDebugSpanGraphY;
|
||||
|
||||
// Fog
|
||||
plDXFogSettings fCurrFog;
|
||||
|
||||
// Light
|
||||
plDXLightSettings fLights;
|
||||
|
||||
// Shadows
|
||||
hsTArray<plShadowSlave*> fShadows;
|
||||
hsTArray<plRenderTarget*> fRenderTargetPool512;
|
||||
hsTArray<plRenderTarget*> fRenderTargetPool256;
|
||||
hsTArray<plRenderTarget*> fRenderTargetPool128;
|
||||
hsTArray<plRenderTarget*> fRenderTargetPool64;
|
||||
hsTArray<plRenderTarget*> fRenderTargetPool32;
|
||||
enum { kMaxRenderTargetNext = 10 };
|
||||
UInt32 fRenderTargetNext[kMaxRenderTargetNext];
|
||||
plDXTextureRef* fULutTextureRef;
|
||||
plRenderTarget* fBlurScratchRTs[kMaxRenderTargetNext];
|
||||
plRenderTarget* fBlurDestRTs[kMaxRenderTargetNext];
|
||||
IDirect3DVertexBuffer9* fBlurVBuffers[kMaxRenderTargetNext];
|
||||
UInt32 fBlurVSHandle;
|
||||
|
||||
hsTArray<plClothingOutfit*> fClothingOutfits;
|
||||
hsTArray<plClothingOutfit*> fPrevClothingOutfits;
|
||||
|
||||
// Debug stuff
|
||||
plDrawableSpans *fBoundsSpans;
|
||||
hsGMaterial *fBoundsMat;
|
||||
hsTArray<UInt32> fBSpansToDelete;
|
||||
|
||||
plStatusLogDrawer *fLogDrawer;
|
||||
|
||||
hsBool fVSync;
|
||||
hsBool fForceDeviceReset;
|
||||
|
||||
void IBeginAllocUnManaged();
|
||||
void IEndAllocUnManaged();
|
||||
void ICheckTextureUsage();
|
||||
void ICheckVtxUsage();
|
||||
inline void ICheckVBUsage(plDXVertexBufferRef* vRef);
|
||||
|
||||
hsBool IRefreshDynVertices(plGBufferGroup* group, plDXVertexBufferRef* vRef);
|
||||
hsBool ICheckAuxBuffers(const plAuxSpan* span);
|
||||
hsBool ICheckDynBuffers(plDrawableSpans* drawable, plGBufferGroup* group, const plSpan* span);
|
||||
void ICheckStaticVertexBuffer(plDXVertexBufferRef* vRef, plGBufferGroup* owner, UInt32 idx);
|
||||
void ICheckIndexBuffer(plDXIndexBufferRef* iRef);
|
||||
void IFillStaticVertexBufferRef(plDXVertexBufferRef *ref, plGBufferGroup *group, UInt32 idx);
|
||||
void IFillIndexBufferRef(plDXIndexBufferRef* iRef, plGBufferGroup* owner, UInt32 idx);
|
||||
void ISetupVertexBufferRef(plGBufferGroup* owner, UInt32 idx, plDXVertexBufferRef* vRef);
|
||||
void ISetupIndexBufferRef(plGBufferGroup* owner, UInt32 idx, plDXIndexBufferRef* iRef);
|
||||
void ICreateDynamicBuffers();
|
||||
void IReleaseDynamicBuffers();
|
||||
|
||||
void IAddBoundsSpan( plDrawableSpans *ice, const hsBounds3Ext *bounds, UInt32 bndColor = 0xffff0000 );
|
||||
void IAddNormalsSpan( plDrawableSpans *ice, plIcicle *span, plDXVertexBufferRef *vRef, UInt32 bndColor );
|
||||
|
||||
// Rendering
|
||||
hsBool IFlipSurface();
|
||||
long IGetBufferD3DFormat(UInt8 format) const;
|
||||
UInt32 IGetBufferFormatSize(UInt8 format) const;
|
||||
void IGetVisibleSpans( plDrawableSpans* drawable, hsTArray<Int16>& visList, plVisMgr* visMgr );
|
||||
void IRenderSpans( plDrawableSpans *ice, const hsTArray<Int16>& visList );
|
||||
hsBool ILoopOverLayers(const plRenderPrimFunc& render, hsGMaterial* material, const plSpan& span);
|
||||
void IRenderBufferSpan( const plIcicle& span,
|
||||
hsGDeviceRef *vb, hsGDeviceRef *ib,
|
||||
hsGMaterial *material,
|
||||
UInt32 vStart, UInt32 vLength, UInt32 iStart, UInt32 iLength );
|
||||
void IRenderAuxSpan(const plSpan& span, const plAuxSpan* aux);
|
||||
void IRenderAuxSpans(const plSpan& span);
|
||||
|
||||
// Fog
|
||||
void IGetVSFogSet(float* const set) const;
|
||||
void ISetFogParameters(const plSpan* span, const plLayerInterface* baseLay);
|
||||
|
||||
// Lighting
|
||||
hsGDeviceRef *IMakeLightRef( plLightInfo *owner );
|
||||
void IScaleD3DLight( plDXLightRef *ref, hsScalar scale);
|
||||
void ICalcLighting( const plLayerInterface *currLayer, const plSpan *currSpan );
|
||||
void IDisableSpanLights();
|
||||
void IRestoreSpanLights();
|
||||
void ISelectLights( plSpan *span, int numLights, hsBool proj );
|
||||
void IEnableLights( plSpan *span );
|
||||
void IMakeLightLists(plVisMgr* visMgr);
|
||||
void ICheckLighting(plDrawableSpans* drawable, hsTArray<Int16>& visList, plVisMgr* visMgr);
|
||||
inline void inlEnsureLightingOff();
|
||||
inline void inlEnsureLightingOn();
|
||||
void IRenderProjection(const plRenderPrimFunc& render, plLightInfo* li);
|
||||
void IRenderProjections(const plRenderPrimFunc& render);
|
||||
void IRenderProjectionEach(const plRenderPrimFunc& render, hsGMaterial* material, int iPass, const plSpan& span);
|
||||
void IRenderOverWire(const plRenderPrimFunc& render, hsGMaterial* material, const plSpan& span);
|
||||
|
||||
hsBool ISkipBumpMap(hsGMaterial* newMat, UInt32& layer, const plSpan* currSpan) const;
|
||||
void ISetBumpMatrices(const plLayerInterface* layer, const plSpan* span);
|
||||
const hsMatrix44& IGetBumpMatrix(UInt32 miscFlags) const;
|
||||
|
||||
// Materials
|
||||
const hsGMatState& ICompositeLayerState(int which, plLayerInterface* layer);
|
||||
Int32 IHandleMaterial(hsGMaterial* newMat, UInt32 which, const plSpan* currSpan);
|
||||
void IHandleFirstTextureStage( plLayerInterface* layer );
|
||||
void IHandleShadeMode();
|
||||
void IHandleZMode();
|
||||
void IHandleMiscMode();
|
||||
void IHandleTextureStage(UInt32 stage, plLayerInterface* layer);
|
||||
void IHandleFirstStageBlend();
|
||||
void IHandleBumpEnv(int stage, UInt32 blendFlags);
|
||||
void IHandleStageBlend(int stage);
|
||||
void IHandleStageClamp(int stage);
|
||||
void IHandleStageTransform(int stage, plLayerInterface* layer);
|
||||
void IHandleTextureMode(plLayerInterface* layer);
|
||||
void IUseTextureRef(int stage, hsGDeviceRef* dRef, plLayerInterface* layer);
|
||||
void IStageStop(UInt32 stage);
|
||||
UInt32 ILayersAtOnce(hsGMaterial* mat, UInt32 which);
|
||||
hsBool ICanEatLayer(plLayerInterface* lay);
|
||||
void ISetLayer(UInt32 lay);
|
||||
void IBottomLayer();
|
||||
|
||||
// Push special effects
|
||||
plLayerInterface* IPushOverBaseLayer(plLayerInterface* li);
|
||||
plLayerInterface* IPopOverBaseLayer(plLayerInterface* li);
|
||||
plLayerInterface* IPushOverAllLayer(plLayerInterface* li);
|
||||
plLayerInterface* IPopOverAllLayer(plLayerInterface* li);
|
||||
|
||||
int ISetNumActivePiggyBacks();
|
||||
void IPushPiggyBacks(hsGMaterial* mat);
|
||||
void IPopPiggyBacks();
|
||||
void IPushProjPiggyBack(plLayerInterface* li);
|
||||
void IPopProjPiggyBacks();
|
||||
|
||||
void ISetPipeConsts(plShader* shader);
|
||||
HRESULT ISetShaders(plShader* vShader, plShader* pShader);
|
||||
|
||||
// Stenciling
|
||||
virtual hsBool StencilEnable( hsBool enable );
|
||||
virtual void StencilSetCompareFunc( UInt8 func, UInt32 refValue );
|
||||
virtual void StencilSetMask( UInt32 mask, UInt32 writeMask );
|
||||
virtual void StencilSetOps( UInt8 passOp, UInt8 failOp, UInt8 passButZFailOp );
|
||||
virtual hsBool StencilGetCaps( plStencilCaps *caps );
|
||||
|
||||
hsGDeviceRef *MakeTextureRef( plLayerInterface* layer, plMipmap *b );
|
||||
void IReloadTexture( plDXTextureRef *ref );
|
||||
void IFillD3DTexture( plDXTextureRef *ref );
|
||||
void IFillD3DCubeTexture( plDXCubeTextureRef *ref );
|
||||
void IGetD3DTextureFormat( plBitmap *b, D3DFORMAT &formatType, UInt32& texSize );
|
||||
void IFormatTextureData( UInt32 formatType, UInt32 numPix, hsRGBAColor32* const src, void *dst );
|
||||
void *IGetPixelScratch( UInt32 size );
|
||||
hsGDeviceRef *IMakeCubicTextureRef( plLayerInterface* layer, plCubicEnvironmap *cubic );
|
||||
hsBool IProcessMipmapLevels( plMipmap *mipmap, UInt32 &numLevels,
|
||||
UInt32 *&levelSizes, UInt32 &totalSize,
|
||||
UInt32 &numPixels, void *&textureData, hsBool noMip );
|
||||
IDirect3DTexture9 *IMakeD3DTexture( plDXTextureRef *ref, D3DFORMAT formatType );
|
||||
IDirect3DCubeTexture9 *IMakeD3DCubeTexture( plDXTextureRef *ref, D3DFORMAT formatType );
|
||||
|
||||
// Visualization of active occluders
|
||||
void IMakeOcclusionSnap();
|
||||
|
||||
hsBool IAvatarSort(plDrawableSpans* d, const hsTArray<Int16>& visList);
|
||||
void IBlendVertsIntoBuffer( plSpan* span,
|
||||
hsMatrix44* matrixPalette, int numMatrices,
|
||||
UInt8 *src, UInt8 format, UInt32 srcStride,
|
||||
UInt8 *dest, UInt32 destStride, UInt32 count, UInt16 localUVWChans );
|
||||
hsBool ISoftwareVertexBlend( plDrawableSpans* drawable, const hsTArray<Int16>& visList );
|
||||
|
||||
|
||||
void ILinkDevRef( plDXDeviceRef *ref, plDXDeviceRef **refList );
|
||||
void IUnlinkDevRef( plDXDeviceRef *ref );
|
||||
|
||||
// Properties
|
||||
inline DWORD inlGetD3DColor( const hsColorRGBA &c ) const;
|
||||
inline D3DCOLORVALUE inlPlToD3DColor(const hsColorRGBA& c, float a) const;
|
||||
|
||||
// Error handling
|
||||
void IAddErrorMessage( char *errStr );
|
||||
void ISetErrorMessage( char *errStr = nil );
|
||||
void IGetD3DError();
|
||||
void IShowErrorMessage( char *errStr = nil );
|
||||
hsBool ICreateFail( char *errStr );
|
||||
|
||||
// FPU mode check
|
||||
void IFPUCheck();
|
||||
|
||||
// Device initialization
|
||||
void IInvalidateState();
|
||||
void IInitDeviceState();
|
||||
void IClearMembers();
|
||||
void ISetCaps();
|
||||
void IRestrictCaps( const hsG3DDeviceRecord& devRec );
|
||||
void ISetGraphicsCapability(UInt32 v);
|
||||
|
||||
hsBool IFindDepthFormat(D3DPRESENT_PARAMETERS& params);
|
||||
hsBool IFindCompressedFormats();
|
||||
hsBool IFindLuminanceFormats();
|
||||
hsBool ITextureFormatAllowed( D3DFORMAT format );
|
||||
|
||||
void ISetCurrentDriver( D3DEnum_DriverInfo *driv );
|
||||
void ISetCurrentDevice( D3DEnum_DeviceInfo *dev );
|
||||
void ISetCurrentMode( D3DEnum_ModeInfo *mode );
|
||||
|
||||
hsBool ICreateMaster();
|
||||
hsBool ICreateDevice(hsBool windowed);
|
||||
hsBool ICreateNormalSurfaces();
|
||||
|
||||
hsBool ICreateDeviceObjects();
|
||||
void IReleaseDeviceObjects();
|
||||
|
||||
hsBool ICreateDynDeviceObjects();
|
||||
void IReleaseDynDeviceObjects();
|
||||
void IReleaseShaders();
|
||||
|
||||
hsBool IResetDevice();
|
||||
|
||||
// View and clipping
|
||||
void ISetViewport();
|
||||
void IUpdateViewVectors() const;
|
||||
void IRefreshCullTree();
|
||||
void ISetAnisotropy(hsBool on);
|
||||
|
||||
// Transforms
|
||||
D3DXMATRIX& IMatrix44ToD3DMatrix( D3DXMATRIX& dst, const hsMatrix44& src );
|
||||
void ITransformsToD3D();
|
||||
hsMatrix44 IGetCameraToNDC();
|
||||
void IProjectionMatrixToD3D();
|
||||
void IWorldToCameraToD3D();
|
||||
void ILocalToWorldToD3D();
|
||||
void ISavageYonHack();
|
||||
void ISetLocalToWorld( const hsMatrix44& l2w, const hsMatrix44& w2l );
|
||||
void ISetCullMode(hsBool flip=false);
|
||||
hsBool inline IIsViewLeftHanded();
|
||||
hsBool IGetClearViewPort(D3DRECT& r);
|
||||
plViewTransform& IGetViewTransform() { return fView.fTransform; }
|
||||
void IUpdateViewFlags();
|
||||
void ISetupTransforms(plDrawableSpans* drawable, const plSpan& span, hsMatrix44& lastL2W);
|
||||
|
||||
// Plate management
|
||||
friend plDXPlateManager;
|
||||
friend plBinkPlayer;
|
||||
|
||||
void IDrawPlate( plPlate *plate );
|
||||
|
||||
void ISetRenderTarget( plRenderTarget *target );
|
||||
|
||||
hsBool IPrepRenderTargetInfo( plRenderTarget *owner, D3DFORMAT &surfFormat,
|
||||
D3DFORMAT &depthFormat, D3DRESOURCETYPE &resType );
|
||||
hsBool IFindRenderTargetInfo( plRenderTarget *owner, D3DFORMAT &surfFormat, D3DRESOURCETYPE &resType );
|
||||
|
||||
// From a D3DFORMAT enumeration, return the string literal for it
|
||||
static const char *IGetDXFormatName( D3DFORMAT format );
|
||||
|
||||
/////// Shadow internals
|
||||
// Generation
|
||||
void IClearShadowSlaves();
|
||||
void IPreprocessShadows();
|
||||
hsBool IPrepShadowCaster(const plShadowCaster* caster);
|
||||
void IRenderShadowCasterSpan(plShadowSlave* slave, plDrawableSpans* drawable, const plIcicle& span);
|
||||
void ISetupShadowCastTextureStages(plShadowSlave* slave);
|
||||
hsBool IRenderShadowCaster(plShadowSlave* slave);
|
||||
void ISetupShadowLight(plShadowSlave* slave);
|
||||
plDXLightRef* INextShadowLight(plShadowSlave* slave);
|
||||
|
||||
hsBool IPushShadowCastState(plShadowSlave* slave);
|
||||
hsBool IPopShadowCastState(plShadowSlave* slave);
|
||||
|
||||
plDXTextureRef* IGetULutTextureRef();
|
||||
hsBool ICreateBlurVBuffers();
|
||||
void IReleaseBlurVBuffers();
|
||||
void IMakeRenderTargetPools();
|
||||
void IResetRenderTargetPools();
|
||||
plRenderTarget* IFindRenderTarget(UInt32& w, UInt32& h, hsBool ortho);
|
||||
void IReleaseRenderTargetPools();
|
||||
|
||||
// Selection
|
||||
void IAttachSlaveToReceivers(int iSlave, plDrawableSpans* drawable, const hsTArray<Int16>& visList);
|
||||
void IAttachShadowsToReceivers(plDrawableSpans* drawable, const hsTArray<Int16>& visList);
|
||||
hsBool IAcceptsShadow(const plSpan* span, plShadowSlave* slave);
|
||||
hsBool IReceivesShadows(const plSpan* span, hsGMaterial* mat);
|
||||
void ISetShadowFromGroup(plDrawableSpans* drawable, const plSpan* span, plLightInfo* liInfo);
|
||||
|
||||
// Application
|
||||
void IRenderShadowsOntoSpan(const plRenderPrimFunc& render, const plSpan* span, hsGMaterial* mat);
|
||||
void ISetupShadowRcvTextureStages(hsGMaterial* mat);
|
||||
void ISetShadowLightState(hsGMaterial* mat);
|
||||
void IDisableLightsForShadow();
|
||||
void IEnableShadowLight(plShadowSlave* slave);
|
||||
void ISetupShadowSlaveTextures(plShadowSlave* slave);
|
||||
|
||||
// Postprocess (blurring)
|
||||
hsBool ISetBlurQuadToRender(plRenderTarget* smap);
|
||||
void IRenderBlurBackToShadowMap(plRenderTarget* smap, plRenderTarget* scratch, plRenderTarget* dst);
|
||||
void IRenderBlurFromShadowMap(plRenderTarget* scratchRT, plRenderTarget* smap, hsScalar scale);
|
||||
void IBlurSetRenderTarget(plRenderTarget* rt);
|
||||
int IGetScratchRenderTarget(plRenderTarget* smap);
|
||||
void IBlurShadowMap(plShadowSlave* slave);
|
||||
|
||||
// Avatar Texture Rendering
|
||||
double fAvRTShrinkValidSince;
|
||||
hsTArray<plRenderTarget*> fAvRTPool;
|
||||
UInt16 fAvRTWidth;
|
||||
UInt32 fAvNextFreeRT;
|
||||
void IFillAvRTPool();
|
||||
hsBool IFillAvRTPool(UInt16 numRTs, UInt16 width); // Returns true if we successfully filled the pool. Otherwise cleans up.
|
||||
void IReleaseAvRTPool();
|
||||
plRenderTarget* IGetNextAvRT();
|
||||
void IFreeAvRT(plRenderTarget* tex);
|
||||
void IPreprocessAvatarTextures();
|
||||
void IDrawClothingQuad(hsScalar x, hsScalar y, hsScalar w, hsScalar h, hsScalar uOff, hsScalar vOff, plMipmap *tex);
|
||||
void IClearClothingOutfits(hsTArray<plClothingOutfit*>* outfits);
|
||||
|
||||
void IPrintDeviceInitError();
|
||||
|
||||
void IResetToDefaults(D3DPRESENT_PARAMETERS *params);
|
||||
|
||||
public:
|
||||
plDXPipeline( hsWinRef hWnd, const hsG3DDeviceModeRecord *devMode );
|
||||
virtual ~plDXPipeline();
|
||||
|
||||
CLASSNAME_REGISTER( plDXPipeline );
|
||||
GETINTERFACE_ANY( plDXPipeline, plPipeline );
|
||||
|
||||
virtual IDirect3DDevice9* GetD3DDevice() const { return fD3DDevice; }
|
||||
|
||||
// Typical 3D device
|
||||
virtual hsBool PreRender(plDrawable* drawable, hsTArray<Int16>& visList, plVisMgr* visMgr=nil);
|
||||
virtual hsBool PrepForRender(plDrawable* drawable, hsTArray<Int16>& visList, plVisMgr* visMgr=nil);
|
||||
virtual void Render(plDrawable* d, const hsTArray<Int16>& visList);
|
||||
virtual void Draw(plDrawable* d);
|
||||
|
||||
virtual void PushRenderRequest(plRenderRequest* req);
|
||||
virtual void PopRenderRequest(plRenderRequest* req);
|
||||
|
||||
void ResetDisplayDevice(int Width, int Height, int ColorDepth, hsBool Windowed, int NumAASamples, int MaxAnisotropicSamples, hsBool VSync = false );
|
||||
|
||||
virtual void ClearRenderTarget( plDrawable* d );
|
||||
virtual void ClearRenderTarget( const hsColorRGBA* col = nil, const hsScalar* depth = nil );
|
||||
virtual void SetClear(const hsColorRGBA* col=nil, const hsScalar* depth=nil);
|
||||
virtual hsColorRGBA GetClearColor() const;
|
||||
virtual hsScalar GetClearDepth() const;
|
||||
virtual hsGDeviceRef* MakeRenderTargetRef( plRenderTarget *owner );
|
||||
virtual hsGDeviceRef* SharedRenderTargetRef(plRenderTarget* sharer, plRenderTarget *owner);
|
||||
virtual void PushRenderTarget( plRenderTarget *target );
|
||||
virtual plRenderTarget* PopRenderTarget();
|
||||
|
||||
virtual hsBool BeginRender();
|
||||
virtual hsBool EndRender();
|
||||
virtual void RenderScreenElements();
|
||||
|
||||
virtual hsBool BeginDrawable(plDrawable* d);
|
||||
virtual hsBool EndDrawable(plDrawable* d);
|
||||
|
||||
virtual void BeginVisMgr(plVisMgr* visMgr);
|
||||
virtual void EndVisMgr(plVisMgr* visMgr);
|
||||
|
||||
virtual hsBool IsFullScreen() const { return fSettings.fFullscreen; }
|
||||
virtual UInt32 Width() const { return fView.fTransform.GetViewPortWidth(); }
|
||||
virtual UInt32 Height() const { return fView.fTransform.GetViewPortHeight(); }
|
||||
virtual UInt32 ColorDepth() const { return fSettings.fColorDepth; }
|
||||
virtual void Resize( UInt32 width, UInt32 height );
|
||||
|
||||
// Culling. Might be used in Update before bothering to do any serious computation.
|
||||
virtual hsBool TestVisibleWorld(const hsBounds3Ext& wBnd);
|
||||
virtual hsBool TestVisibleWorld(const plSceneObject* sObj);
|
||||
virtual hsBool HarvestVisible(plSpaceTree* space, hsTArray<Int16>& visList);
|
||||
virtual hsBool SubmitOccluders(const hsTArray<const plCullPoly*>& polyList);
|
||||
|
||||
// Debug flags
|
||||
virtual void SetDebugFlag( UInt32 flag, hsBool on );
|
||||
virtual hsBool IsDebugFlagSet( UInt32 flag ) const;
|
||||
|
||||
// These are also only for debugging.
|
||||
virtual void SetMaxCullNodes(UInt16 n) { fView.fCullMaxNodes = n; }
|
||||
virtual UInt16 GetMaxCullNodes() const { return fView.fCullMaxNodes; }
|
||||
|
||||
virtual hsBool CheckResources();
|
||||
virtual void LoadResources(); // Tells us where it's a good time to load in unmanaged resources.
|
||||
|
||||
// Properties
|
||||
virtual void SetProperty( UInt32 prop, hsBool on ) { on ? fSettings.fProperties |= prop : fSettings.fProperties &= ~prop; }
|
||||
virtual hsBool GetProperty( UInt32 prop ) const { return ( fSettings.fProperties & prop ) ? true : false; }
|
||||
|
||||
virtual UInt32 GetMaxLayersAtOnce() const { return fSettings.fMaxLayersAtOnce; }
|
||||
|
||||
// Drawable type mask
|
||||
virtual void SetDrawableTypeMask( UInt32 mask ) { fView.fDrawableTypeMask = mask; }
|
||||
virtual UInt32 GetDrawableTypeMask() const { return fView.fDrawableTypeMask; }
|
||||
virtual void SetSubDrawableTypeMask( UInt32 mask ) { fView.fSubDrawableTypeMask = mask; }
|
||||
virtual UInt32 GetSubDrawableTypeMask() const { return fView.fSubDrawableTypeMask; }
|
||||
|
||||
// Create a debug text font object
|
||||
virtual plTextFont *MakeTextFont( char *face, UInt16 size );
|
||||
|
||||
// Create and/or Refresh geometry buffers
|
||||
virtual void CheckVertexBufferRef(plGBufferGroup* owner, UInt32 idx);
|
||||
virtual void CheckIndexBufferRef(plGBufferGroup* owner, UInt32 idx);
|
||||
|
||||
virtual hsBool OpenAccess(plAccessSpan& dst, plDrawableSpans* d, const plVertexSpan* span, hsBool readOnly);
|
||||
virtual hsBool CloseAccess(plAccessSpan& acc);
|
||||
|
||||
virtual void CheckTextureRef(plLayerInterface* lay);
|
||||
static void FreeManagedTexture(UInt32 sz) { hsAssert(fTexManaged >= sz, "Freeing mem we don't have"); fTexManaged -= sz; }
|
||||
static void AllocManagedTexture(UInt32 sz) { fTexManaged += sz; }
|
||||
static void FreeManagedVertex(UInt32 sz) { hsAssert(fVtxManaged >= sz, "Freeing mem we don't have"); fVtxManaged -= sz; }
|
||||
static void AllocManagedVertex(UInt32 sz) { fVtxManaged += sz; }
|
||||
|
||||
#ifndef PLASMA_EXTERNAL_RELEASE
|
||||
static void ProfilePoolMem(D3DPOOL poolType, UInt32 size, hsBool add, char *id);
|
||||
#endif // PLASMA_EXTERNAL_RELEASE
|
||||
|
||||
// From a D3DFORMAT enumeration, return the bit depth associated with it.
|
||||
static short GetDXBitDepth( D3DFORMAT format );
|
||||
|
||||
// Default fog settings
|
||||
virtual void SetDefaultFogEnviron( plFogEnvironment *fog ) { fView.fDefaultFog = *fog; fCurrFog.fEnvPtr = nil; }
|
||||
virtual const plFogEnvironment &GetDefaultFogEnviron() const { return fView.fDefaultFog; }
|
||||
|
||||
// View state
|
||||
virtual hsPoint3 GetViewPositionWorld() const { return GetViewTransform().GetPosition(); }
|
||||
virtual hsVector3 GetViewAcrossWorld() const { return GetViewTransform().GetAcross(); }
|
||||
virtual hsVector3 GetViewUpWorld() const { return GetViewTransform().GetUp(); }
|
||||
virtual hsVector3 GetViewDirWorld() const { return GetViewTransform().GetDirection(); }
|
||||
virtual void GetViewAxesWorld(hsVector3 axes[3] /* ac,up,at */ ) const;
|
||||
|
||||
virtual void GetFOV(hsScalar& fovX, hsScalar& fovY) const;
|
||||
virtual void SetFOV(hsScalar fovX, hsScalar fovY);
|
||||
|
||||
virtual void GetSize(hsScalar& width, hsScalar& height) const;
|
||||
virtual void SetSize(hsScalar width, hsScalar height);
|
||||
|
||||
virtual void GetDepth(hsScalar& hither, hsScalar& yon) const;
|
||||
virtual void SetDepth(hsScalar hither, hsScalar yon);
|
||||
|
||||
virtual hsScalar GetZBiasScale() const;
|
||||
virtual void SetZBiasScale(hsScalar scale);
|
||||
|
||||
virtual const hsMatrix44& GetWorldToCamera() const;
|
||||
virtual const hsMatrix44& GetCameraToWorld() const;
|
||||
virtual void SetWorldToCamera(const hsMatrix44& w2c, const hsMatrix44& c2w);
|
||||
|
||||
virtual void SetViewTransform(const plViewTransform& trans);
|
||||
virtual const plViewTransform& GetViewTransform() const { return fView.fTransform; }
|
||||
|
||||
virtual const hsMatrix44& GetWorldToLocal() const;
|
||||
virtual const hsMatrix44& GetLocalToWorld() const;
|
||||
|
||||
virtual void ScreenToWorldPoint( int n, UInt32 stride, Int32 *scrX, Int32 *scrY,
|
||||
hsScalar dist, UInt32 strideOut, hsPoint3 *worldOut );
|
||||
|
||||
virtual void RefreshMatrices();
|
||||
virtual void RefreshScreenMatrices();
|
||||
|
||||
virtual void RegisterLight(plLightInfo* light);
|
||||
virtual void UnRegisterLight(plLightInfo* light);
|
||||
|
||||
// Overrides, always push returns whatever is necessary to restore on pop.
|
||||
virtual hsGMaterial* PushOverrideMaterial(hsGMaterial* mat);
|
||||
virtual void PopOverrideMaterial(hsGMaterial* restore);
|
||||
virtual hsGMaterial* GetOverrideMaterial() const;
|
||||
|
||||
virtual plLayerInterface* AppendLayerInterface(plLayerInterface* li, hsBool onAllLayers = false);
|
||||
virtual plLayerInterface* RemoveLayerInterface(plLayerInterface* li, hsBool onAllLayers = false);
|
||||
|
||||
virtual plLayerInterface* PushPiggyBackLayer(plLayerInterface* li);
|
||||
virtual plLayerInterface* PopPiggyBackLayer(plLayerInterface* li);
|
||||
|
||||
virtual UInt32 GetMaterialOverrideOn(hsGMatState::StateIdx category) const;
|
||||
virtual UInt32 GetMaterialOverrideOff(hsGMatState::StateIdx category) const;
|
||||
|
||||
virtual hsGMatState PushMaterialOverride(const hsGMatState& state, hsBool on);
|
||||
virtual hsGMatState PushMaterialOverride(hsGMatState::StateIdx cat, UInt32 which, hsBool on);
|
||||
virtual void PopMaterialOverride(const hsGMatState& restore, hsBool on);
|
||||
virtual const hsGMatState& GetMaterialOverride(hsBool on) const;
|
||||
|
||||
virtual hsColorOverride PushColorOverride(const hsColorOverride& over);
|
||||
virtual void PopColorOverride(const hsColorOverride& restore);
|
||||
virtual const hsColorOverride& GetColorOverride() const;
|
||||
|
||||
virtual void SubmitShadowSlave(plShadowSlave* slave);
|
||||
virtual void SubmitClothingOutfit(plClothingOutfit* co);
|
||||
|
||||
virtual hsBool SetGamma(hsScalar eR, hsScalar eG, hsScalar eB);
|
||||
virtual hsBool SetGamma(const UInt16* const tabR, const UInt16* const tabG, const UInt16* const tabB);
|
||||
|
||||
virtual hsBool CaptureScreen( plMipmap *dest, bool flipVertical = false, UInt16 desiredWidth = 0, UInt16 desiredHeight = 0 );
|
||||
virtual plMipmap* ExtractMipMap(plRenderTarget* targ);
|
||||
|
||||
/// Error handling
|
||||
virtual const char *GetErrorString();
|
||||
|
||||
hsBool ManagedAlloced() const { return fManagedAlloced; }
|
||||
|
||||
virtual void GetSupportedColorDepths(hsTArray<int> &ColorDepths);
|
||||
virtual void GetSupportedDisplayModes(std::vector<plDisplayMode> *res, int ColorDepth = 32 );
|
||||
virtual int GetMaxAnisotropicSamples();
|
||||
virtual int GetMaxAntiAlias(int Width, int Height, int ColorDepth);
|
||||
|
||||
};
|
||||
|
||||
|
||||
//// Direct3D Inlines //////////////////////////////////////////////////////
|
||||
// ??.?? - Some mild optimizations PBG
|
||||
// MMW - take advantage of the 32 bit float representation on a PC
|
||||
|
||||
#define CONVERT_FLOAT_TO_BYTE_COLOR( f, dest ) \
|
||||
{ \
|
||||
LONG const floatBitsOne = 0x3f800000; \
|
||||
LONG const floatBits = *( (LONG const *)( &f ) ); \
|
||||
if( floatBits <= 0 ) dest = 0; \
|
||||
else if( floatBits >= floatBitsOne ) dest = 255; \
|
||||
else \
|
||||
{ \
|
||||
LONG const times256 = floatBits + ( 8 << 23 ); \
|
||||
dest = (DWORD)( *( (float const *)( ×256 ) ) ); \
|
||||
} \
|
||||
}
|
||||
|
||||
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
|
@ -0,0 +1,149 @@
|
||||
/*==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/>.
|
||||
|
||||
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 "hsConfig.h"
|
||||
#include "hsWindows.h"
|
||||
|
||||
#include <D3d9.h>
|
||||
#include <D3dx9core.h>
|
||||
|
||||
#include "hsTypes.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);
|
||||
}
|
||||
|
||||
hsBool plDXPixelShader::VerifyFormat(UInt8 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;
|
||||
}
|
@ -0,0 +1,56 @@
|
||||
/*==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/>.
|
||||
|
||||
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); }
|
||||
|
||||
hsBool VerifyFormat(UInt8 format) const;
|
||||
IDirect3DPixelShader9 *GetShader(plDXPipeline* pipe);
|
||||
};
|
||||
|
||||
|
||||
#endif // plDXPixelShader_inc
|
@ -0,0 +1,89 @@
|
||||
/*==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/>.
|
||||
|
||||
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;
|
||||
|
||||
hsBool fReleaseDepth;
|
||||
|
||||
void Link( plDXRenderTargetRef **back ) { plDXDeviceRef::Link( (plDXDeviceRef **)back ); }
|
||||
plDXRenderTargetRef *GetNext( void ) { return (plDXRenderTargetRef *)fNext; }
|
||||
|
||||
|
||||
plDXRenderTargetRef( D3DFORMAT tp, UInt32 ml, plRenderTarget *owner, hsBool releaseDepthOnDelete = true );
|
||||
plDXRenderTargetRef& Set( D3DFORMAT tp, UInt32 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
|
@ -0,0 +1,285 @@
|
||||
/*==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/>.
|
||||
|
||||
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 "plFogEnvironment.h"
|
||||
#include "hsGeometry3.h"
|
||||
#include "hsTemplates.h"
|
||||
#include "hsColorRGBA.h"
|
||||
#include "hsBitVector.h"
|
||||
#include "plStencil.h"
|
||||
#include "hsPoint2.h"
|
||||
#include "plCullTree.h"
|
||||
#include "hsWinRef.h"
|
||||
#include "plViewTransform.h"
|
||||
|
||||
//// General Settings /////////////////////////////////////////////////////////
|
||||
|
||||
class plRenderRequest;
|
||||
class plRenderTarget;
|
||||
struct IDirect3DSurface9;
|
||||
class plDXDeviceRef;
|
||||
class plDXVertexBufferRef;
|
||||
class plDXIndexBufferRef;
|
||||
|
||||
class plDXViewSettings
|
||||
{
|
||||
public:
|
||||
UInt32 fRenderState;
|
||||
|
||||
plRenderRequest* fRenderRequest;
|
||||
|
||||
UInt32 fDrawableTypeMask;
|
||||
UInt32 fSubDrawableTypeMask;
|
||||
|
||||
DWORD fClearColor;
|
||||
float fClearDepth;
|
||||
|
||||
plFogEnvironment fDefaultFog;
|
||||
|
||||
plCullTree fCullTree;
|
||||
hsBool fCullTreeDirty;
|
||||
UInt16 fCullMaxNodes;
|
||||
|
||||
enum XformResets
|
||||
{
|
||||
kResetProjection = 0x01,
|
||||
kResetCamera = 0x02,
|
||||
kResetL2W = 0x04,
|
||||
|
||||
kResetAll = 0x07
|
||||
};
|
||||
|
||||
UInt8 fXformResetFlags;
|
||||
hsBool fLocalToWorldLeftHanded;
|
||||
hsBool fWorldToCamLeftHanded;
|
||||
|
||||
mutable hsVector3 fDirection;
|
||||
mutable hsVector3 fUp;
|
||||
mutable hsVector3 fAcross;
|
||||
hsPoint3 fWorldPos;
|
||||
|
||||
mutable hsBool 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(); }
|
||||
hsBool IsPerspective() const { return fTransform.GetPerspective(); }
|
||||
|
||||
void Reset();
|
||||
};
|
||||
|
||||
class plDXGeneralSettings
|
||||
{
|
||||
public:
|
||||
|
||||
hsBool fFullscreen;
|
||||
hsWinRef fHWnd;
|
||||
UInt32 fColorDepth;
|
||||
UInt8 fNumAASamples;
|
||||
UInt32 fD3DCaps, fBoardKluge, fStageEnd;
|
||||
UInt32 fMaxNumLights;
|
||||
UInt32 fMaxNumProjectors;
|
||||
UInt32 fMaxLayersAtOnce;
|
||||
UInt32 fMaxPiggyBacks;
|
||||
Int32 fBoundsDrawLevel;
|
||||
UInt32 fProperties;
|
||||
DWORD fClearColor;
|
||||
UInt8 fMaxAnisotropicSamples;
|
||||
D3DPRESENT_PARAMETERS fPresentParams;
|
||||
hsBool fVeryAnnoyingTextureInvalidFlag;
|
||||
hsBool fNoGammaCorrect;
|
||||
int fMaxUVWSrc;
|
||||
hsBool fCantProj;
|
||||
hsBool fLimitedProj;
|
||||
hsBool fBadManaged;
|
||||
hsBool fShareDepth;
|
||||
hsBool fCurrAnisotropy;
|
||||
hsBool 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 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 fIsVertex;
|
||||
UInt8 fIsShader;
|
||||
UInt32 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 fNextIndex, fLastIndex;
|
||||
UInt16 fTime;
|
||||
plLightInfo* fActiveList;
|
||||
plDXLightRef* fRefList;
|
||||
plDXPipeline* fPipeline;
|
||||
hsTArray<plLightInfo*> fProjEach;
|
||||
hsTArray<plLightInfo*> fProjAll;
|
||||
|
||||
hsTArray<plLightInfo*> fCharLights;
|
||||
hsTArray<plLightInfo*> fVisLights;
|
||||
|
||||
UInt32 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 ReserveD3DIndex( void );
|
||||
// Release a reserved D3D light index
|
||||
void ReleaseD3DIndex( UInt32 idx );
|
||||
};
|
||||
|
||||
//// Stencil Settings /////////////////////////////////////////////////////////
|
||||
|
||||
class plDXStencilSettings
|
||||
{
|
||||
public:
|
||||
UInt8 fDepth;
|
||||
hsBool fEnabled;
|
||||
UInt8 fCmpFunc;
|
||||
UInt8 fFailOp, fPassOp, fPassButZFailOp;
|
||||
UInt32 fRefValue;
|
||||
UInt32 fMask;
|
||||
UInt32 fWriteMask;
|
||||
|
||||
void Reset( void )
|
||||
{
|
||||
fEnabled = false;
|
||||
fCmpFunc = 0;
|
||||
fFailOp = fPassOp = fPassButZFailOp = 0;
|
||||
fRefValue = 0;
|
||||
fMask = 0xffffffff;
|
||||
fWriteMask = 0xffffffff;
|
||||
}
|
||||
};
|
||||
|
||||
#endif // _plDXSettings_h
|
@ -0,0 +1,86 @@
|
||||
/*==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/>.
|
||||
|
||||
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 "hsConfig.h"
|
||||
#include "hsWindows.h"
|
||||
|
||||
#include <D3d9.h>
|
||||
#include <D3dx9core.h>
|
||||
|
||||
#include "hsTypes.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;
|
||||
}
|
||||
|
@ -0,0 +1,56 @@
|
||||
/*==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/>.
|
||||
|
||||
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
|
@ -0,0 +1,308 @@
|
||||
/*==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/>.
|
||||
|
||||
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 "hsConfig.h"
|
||||
#include "hsWindows.h"
|
||||
|
||||
#include <d3d9.h>
|
||||
#include <ddraw.h>
|
||||
#include <d3dx9mesh.h>
|
||||
|
||||
#if HS_BUILD_FOR_MAC
|
||||
#include <QuickDraw.h>
|
||||
#endif
|
||||
|
||||
#include "hsWinRef.h"
|
||||
#include "hsTypes.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 kNumVertsInBuffer(32768);
|
||||
const UInt32 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 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 *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 ) );
|
||||
fD3DTexture->UnlockRect( nil );
|
||||
}
|
||||
|
||||
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 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 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 );
|
||||
}
|
||||
|
@ -0,0 +1,74 @@
|
||||
/*==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/>.
|
||||
|
||||
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 "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 fBufferCursor;
|
||||
|
||||
IDirect3DStateBlock9 *fOldStateBlock;
|
||||
IDirect3DStateBlock9 *fTextStateBlock;
|
||||
|
||||
virtual void ICreateTexture( UInt16 *data );
|
||||
virtual void IInitStateBlocks( void );
|
||||
virtual void IDrawPrimitive( UInt32 count, plFontVertex *array );
|
||||
virtual void IDrawLines( UInt32 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
|
||||
|
@ -0,0 +1,107 @@
|
||||
/*==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/>.
|
||||
|
||||
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
|
||||
};
|
||||
|
||||
IDirect3DBaseTexture9 *fD3DTexture;
|
||||
D3DFORMAT fFormatType; // Format of the D3D texture object
|
||||
|
||||
UInt32 fMMLvs; // Number of mipmap levels
|
||||
UInt32 fMaxWidth; // Width of the highest mipmap level
|
||||
UInt32 fMaxHeight; // Height of the highest mipmap level (no pun intended)
|
||||
UInt32 fNumPix; // total num texels in all mip levels
|
||||
UInt32 fDataSize; // size of fData[0..n] in bytes
|
||||
UInt32* fLevelSizes; // fLevelSize[i] == size in bytes of level i
|
||||
//UInt32 fCurrLOD; // Current LOD setting for this texture
|
||||
|
||||
plBitmap *fOwner;
|
||||
|
||||
void* fData; // for reloading
|
||||
|
||||
UInt32 GetFlags( void ) { return fFlags; }
|
||||
void SetFlags( UInt32 flag ) { fFlags = flag; }
|
||||
|
||||
plDXTextureRef& Set( D3DFORMAT tp, UInt32 ml, UInt32 mw, UInt32 mh, UInt32 np, UInt32 sz, UInt32 manSize, UInt32* lSz, void* pd, hsBool ed=false, hsBool renderTarget = false );
|
||||
|
||||
plDXTextureRef( D3DFORMAT tp, UInt32 ml, UInt32 mw, UInt32 mh, UInt32 np, UInt32 sz, UInt32 manSize, UInt32* lSz, void* pd, hsBool ed=false, hsBool 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 ml, UInt32 mw, UInt32 mh, UInt32 np, UInt32 sz, UInt32 manSize, UInt32* lSz, void* pd, hsBool ed=false, hsBool renderTarget = false ) :
|
||||
plDXTextureRef( tp, ml, mw, mh, np, sz, manSize, lSz, pd, ed, renderTarget )
|
||||
{
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
#endif // _plDXTextureRef_h
|
@ -0,0 +1,152 @@
|
||||
/*==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/>.
|
||||
|
||||
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 "hsConfig.h"
|
||||
#include "hsWindows.h"
|
||||
|
||||
#include <D3d9.h>
|
||||
#include <D3dx9core.h>
|
||||
|
||||
#include "hsTypes.h"
|
||||
|
||||
#include "plDXVertexShader.h"
|
||||
|
||||
#include "../plSurface/plShader.h"
|
||||
|
||||
#include "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);
|
||||
}
|
||||
|
||||
hsBool plDXVertexShader::VerifyFormat(UInt8 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;
|
||||
}
|
||||
|
@ -0,0 +1,57 @@
|
||||
/*==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/>.
|
||||
|
||||
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); }
|
||||
|
||||
hsBool VerifyFormat(UInt8 format) const;
|
||||
IDirect3DVertexShader9* GetShader(plDXPipeline* pipe);
|
||||
};
|
||||
|
||||
#endif // plDXVertexSahder_inc
|
@ -0,0 +1,288 @@
|
||||
/*==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/>.
|
||||
|
||||
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==*/
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// plDebugText and plDebugTextManager Functions //
|
||||
// //
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "plPipeline.h"
|
||||
#include "plDebugText.h"
|
||||
#include "plTextFont.h"
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//// plDebugText Functions ///////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
plDebugText plDebugText::fInstance;
|
||||
|
||||
//// DrawString //////////////////////////////////////////////////////////////
|
||||
|
||||
void plDebugText::DrawString( UInt16 x, UInt16 y, const char *string, UInt32 hexColor, UInt8 style )
|
||||
{
|
||||
if( IsEnabled() && fManager && string != nil && string[ 0 ] != 0 )
|
||||
fManager->AddString( x, y, string, hexColor, style, fDrawOnTopMode );
|
||||
}
|
||||
|
||||
//// CalcStringWidth /////////////////////////////////////////////////////////
|
||||
|
||||
UInt32 plDebugText::CalcStringWidth( const char *string )
|
||||
{
|
||||
if( IsEnabled() && fManager && string )
|
||||
return fManager->CalcStringWidth( string );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//// DrawRect ////////////////////////////////////////////////////////////////
|
||||
// TEMPORARY function to draw a flat-shaded 2D rectangle to the screen. Used
|
||||
// to create a background for our console; will be obliterated once we figure
|
||||
// a better way to do so.
|
||||
|
||||
void plDebugText::DrawRect( UInt16 left, UInt16 top, UInt16 right, UInt16 bottom, UInt32 hexColor )
|
||||
{
|
||||
if( IsEnabled() && fManager )
|
||||
fManager->DrawRect( left, top, right, bottom, hexColor, fDrawOnTopMode );
|
||||
}
|
||||
|
||||
//// Draw3DBorder ////////////////////////////////////////////////////////////
|
||||
|
||||
void plDebugText::Draw3DBorder( UInt16 left, UInt16 top, UInt16 right, UInt16 bottom, UInt32 hexColor1, UInt32 hexColor2 )
|
||||
{
|
||||
if( IsEnabled() && fManager )
|
||||
fManager->Draw3DBorder( left, top, right, bottom, hexColor1, hexColor2, fDrawOnTopMode );
|
||||
}
|
||||
|
||||
//// GetScreenSize ///////////////////////////////////////////////////////////
|
||||
|
||||
void plDebugText::GetScreenSize( UInt32 *width, UInt32 *height )
|
||||
{
|
||||
if( fManager )
|
||||
fManager->GetScreenSize( width, height );
|
||||
}
|
||||
|
||||
UInt16 plDebugText::GetFontHeight()
|
||||
{
|
||||
if (fManager)
|
||||
return fManager->GetFontHeight();
|
||||
return 0;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//// plDebugTextManager Functions ////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//// plDebugTextNode Constructor /////////////////////////////////////////////
|
||||
|
||||
plDebugTextManager::plDebugTextNode::plDebugTextNode( const char *s, UInt32 c, UInt16 x, UInt16 y, UInt8 style )
|
||||
{
|
||||
HSMemory::Clear( fText, sizeof( fText ) );
|
||||
strncpy( fText, s, sizeof( fText ) - 1 );
|
||||
fColor = c;
|
||||
fX = x;
|
||||
fY = y;
|
||||
fStyle = style;
|
||||
}
|
||||
|
||||
plDebugTextManager::plDebugTextNode::plDebugTextNode( UInt16 left, UInt16 top, UInt16 right, UInt16 bottom, UInt32 c )
|
||||
{
|
||||
memset( fText, 0, sizeof( fText ) );
|
||||
fColor = c;
|
||||
fX = left;
|
||||
fY = top;
|
||||
fRight = right;
|
||||
fBottom = bottom;
|
||||
fStyle = 0xff;
|
||||
}
|
||||
|
||||
plDebugTextManager::plDebugTextNode::plDebugTextNode( UInt16 left, UInt16 top, UInt16 right, UInt16 bottom, UInt32 c1, UInt32 c2 )
|
||||
{
|
||||
memset( fText, 0, sizeof( fText ) );
|
||||
fColor = c1;
|
||||
fDarkColor = c2;
|
||||
fX = left;
|
||||
fY = top;
|
||||
fRight = right;
|
||||
fBottom = bottom;
|
||||
fStyle = 0xfe;
|
||||
}
|
||||
|
||||
//// plDebugTextManager destructor ///////////////////////////////////////////
|
||||
|
||||
plDebugTextManager::~plDebugTextManager()
|
||||
{
|
||||
if( fFont != nil )
|
||||
delete fFont;
|
||||
}
|
||||
|
||||
//// AddString ///////////////////////////////////////////////////////////////
|
||||
|
||||
void plDebugTextManager::AddString( UInt16 x, UInt16 y, const char *s, UInt32 hexColor, UInt8 style, hsBool drawOnTop )
|
||||
{
|
||||
if( drawOnTop )
|
||||
fDrawOnTopList.Append( plDebugTextNode( s, hexColor, x, y, style ) );
|
||||
else
|
||||
fList.Append( plDebugTextNode( s, hexColor, x, y, style ) );
|
||||
}
|
||||
|
||||
//// DrawRect ////////////////////////////////////////////////////////////////
|
||||
// TEMPORARY function to draw a flat-shaded 2D rectangle to the screen. Used
|
||||
// to create a background for our console; will be obliterated once we figure
|
||||
// a better way to do so.
|
||||
|
||||
void plDebugTextManager::DrawRect( UInt16 left, UInt16 top, UInt16 right, UInt16 bottom, UInt32 hexColor, hsBool drawOnTop )
|
||||
{
|
||||
if( drawOnTop )
|
||||
fDrawOnTopList.Append( plDebugTextNode( left, top, right, bottom, hexColor ) );
|
||||
else
|
||||
fList.Append( plDebugTextNode( left, top, right, bottom, hexColor ) );
|
||||
}
|
||||
|
||||
//// Draw3DBorder ////////////////////////////////////////////////////////////
|
||||
|
||||
void plDebugTextManager::Draw3DBorder( UInt16 left, UInt16 top, UInt16 right, UInt16 bottom, UInt32 hexColor1, UInt32 hexColor2, hsBool drawOnTop )
|
||||
{
|
||||
if( drawOnTop )
|
||||
fDrawOnTopList.Append( plDebugTextNode( left, top, right, bottom, hexColor1, hexColor2 ) );
|
||||
else
|
||||
fList.Append( plDebugTextNode( left, top, right, bottom, hexColor1, hexColor2 ) );
|
||||
}
|
||||
|
||||
//// DrawToDevice ////////////////////////////////////////////////////////////
|
||||
|
||||
void plDebugTextManager::DrawToDevice( plPipeline *pipe )
|
||||
{
|
||||
int i, j;
|
||||
hsTArray<plDebugTextNode> *list;
|
||||
|
||||
|
||||
if( fList.GetCount() == 0 && fDrawOnTopList.GetCount() == 0 )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if( fFont == nil )
|
||||
{
|
||||
// Create font first time around
|
||||
fFont = pipe->MakeTextFont( (char *)plDebugText::Instance().GetFontFace(),
|
||||
plDebugText::Instance().GetFontSize() );
|
||||
|
||||
if( fFont == nil )
|
||||
{
|
||||
plDebugText::Instance().DisablePermanently();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Get stuff
|
||||
fSWidth = pipe->Width();
|
||||
fSHeight = pipe->Height();
|
||||
|
||||
// Start other stuff
|
||||
fFont->SaveStates();
|
||||
|
||||
for( j = 0; j < 2; j++ )
|
||||
{
|
||||
if( j == 0 )
|
||||
list = &fList;
|
||||
else
|
||||
list = &fDrawOnTopList;
|
||||
|
||||
for( i = 0; i < list->GetCount(); i++ )
|
||||
{
|
||||
plDebugTextNode& node = (*list)[i];
|
||||
|
||||
if( node.fStyle == 0xff )
|
||||
{
|
||||
fFont->DrawRect( node.fX, node.fY,
|
||||
node.fRight, node.fBottom, node.fColor );
|
||||
}
|
||||
else if( node.fStyle == 0xfe )
|
||||
{
|
||||
fFont->Draw3DBorder( node.fX, node.fY,
|
||||
node.fRight, node.fBottom, node.fColor, node.fDarkColor );
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/// Draw string only if its in bounds (clip to right edge if necessary)
|
||||
if( node.fX >= 0 && node.fY >= 0 )
|
||||
{
|
||||
if( node.fY + fFont->GetFontHeight() < fSHeight )
|
||||
{
|
||||
if( node.fX + CalcStringWidth( node.fText ) < fSWidth )
|
||||
{
|
||||
fFont->DrawString( node.fText, node.fX, node.fY,
|
||||
node.fColor, node.fStyle );
|
||||
}
|
||||
else
|
||||
{
|
||||
fFont->DrawString( node.fText, node.fX, node.fY,
|
||||
node.fColor, node.fStyle, fSWidth );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Call this to ensure the font object finishes all its drawing
|
||||
fFont->FlushDraws();
|
||||
fFont->RestoreStates();
|
||||
|
||||
fList.Reset();
|
||||
fDrawOnTopList.Reset();
|
||||
}
|
||||
|
||||
//// CalcStringWidth /////////////////////////////////////////////////////////
|
||||
|
||||
UInt32 plDebugTextManager::CalcStringWidth( const char *string )
|
||||
{
|
||||
if( !plDebugText::Instance().IsEnabled() || fFont == nil )
|
||||
return 0;
|
||||
|
||||
return fFont->CalcStringWidth( string );
|
||||
}
|
||||
|
||||
//// GetScreenSize ///////////////////////////////////////////////////////////
|
||||
|
||||
void plDebugTextManager::GetScreenSize( UInt32 *width, UInt32 *height )
|
||||
{
|
||||
if( width != nil )
|
||||
*width = fSWidth;
|
||||
if( height != nil )
|
||||
*height = fSHeight;
|
||||
}
|
||||
|
||||
UInt16 plDebugTextManager::GetFontHeight()
|
||||
{
|
||||
if (fFont)
|
||||
return fFont->GetFontHeight();
|
||||
|
||||
// Just return a quick default height until we get a real font
|
||||
return 10;
|
||||
}
|
||||
|
@ -0,0 +1,187 @@
|
||||
/*==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/>.
|
||||
|
||||
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==*/
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// plDebugText and plDebugTextManager Headers //
|
||||
// //
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef _plDebugText_h
|
||||
#define _plDebugText_h
|
||||
|
||||
#include "hsTypes.h"
|
||||
#include "hsColorRGBA.h"
|
||||
#include "hsTemplates.h"
|
||||
#include "hsUtils.h"
|
||||
|
||||
//// plDebugText Class Definition ////////////////////////////////////////////
|
||||
|
||||
class plPipeline;
|
||||
class plDebugTextManager;
|
||||
|
||||
class plDebugText
|
||||
{
|
||||
private:
|
||||
|
||||
static plDebugText fInstance;
|
||||
|
||||
plDebugText()
|
||||
{
|
||||
fManager = nil;
|
||||
#ifdef PLASMA_EXTERNAL_RELEASE
|
||||
SetFont( "Trebuchet MS Bold", 8 );
|
||||
#else
|
||||
SetFont( "Courier New", 8 );
|
||||
#endif
|
||||
SetEnable( true );
|
||||
fLockEnable = false;
|
||||
fDrawOnTopMode = false;
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
plDebugTextManager *fManager;
|
||||
|
||||
char fFontFace[ 128 ];
|
||||
UInt16 fFontSize;
|
||||
hsBool fEnabled, fLockEnable, fDrawOnTopMode;
|
||||
|
||||
public:
|
||||
|
||||
enum Styles
|
||||
{
|
||||
kStyleItalic = 0x01,
|
||||
kStyleBold = 0x02
|
||||
};
|
||||
|
||||
~plDebugText() { ; }
|
||||
|
||||
static plDebugText &Instance( void ) { return fInstance; }
|
||||
|
||||
UInt32 CalcStringWidth( const char *string );
|
||||
|
||||
void DrawString( UInt16 x, UInt16 y, const char *string, UInt32 hexColor, UInt8 style = 0 );
|
||||
|
||||
void DrawString( UInt16 x, UInt16 y, const char *string, hsColorRGBA &color, UInt8 style = 0 )
|
||||
{
|
||||
UInt32 hex;
|
||||
UInt8 r, g, b, a;
|
||||
|
||||
|
||||
r = (UInt8)( color.r * 255.0 );
|
||||
g = (UInt8)( color.g * 255.0 );
|
||||
b = (UInt8)( color.b * 255.0 );
|
||||
a = (UInt8)( color.a * 255.0 );
|
||||
hex = ( a << 24 ) | ( r << 16 ) | ( g << 8 ) | ( b );
|
||||
|
||||
DrawString( x, y, string, hex, style );
|
||||
}
|
||||
|
||||
void DrawString( UInt16 x, UInt16 y, const char *string, UInt8 r = 255, UInt8 g = 255, UInt8 b = 255, UInt8 a = 255, UInt8 style = 0 )
|
||||
{
|
||||
DrawString( x, y, string, (UInt32)( ( a << 24 ) | ( r << 16 ) | ( g << 8 ) | ( b ) ), style );
|
||||
}
|
||||
|
||||
void SetDrawOnTopMode( hsBool enable ) { fDrawOnTopMode = enable; }
|
||||
|
||||
/// TEMPORARY FUNCTION (until we can find a better way to do this, one way or the other)
|
||||
void DrawRect( UInt16 left, UInt16 top, UInt16 right, UInt16 bottom, UInt32 hexColor );
|
||||
|
||||
/// TEMPORARY FUNCTION (until we can find a better way to do this, one way or the other)
|
||||
void DrawRect( UInt16 left, UInt16 top, UInt16 right, UInt16 bottom, UInt8 r, UInt8 g, UInt8 b, UInt8 a = 255 )
|
||||
{
|
||||
DrawRect( left, top, right, bottom, (UInt32)( ( a << 24 ) | ( r << 16 ) | ( g << 8 ) | ( b ) ) );
|
||||
}
|
||||
|
||||
/// EVEN MORE TEMPORARY FUNCTION (until we can find a better way to do this, one way or the other)
|
||||
void Draw3DBorder( UInt16 left, UInt16 top, UInt16 right, UInt16 bottom, UInt32 hexColor1, UInt32 hexColor2 );
|
||||
|
||||
void SetManager( plDebugTextManager *m ) { fManager = m; }
|
||||
|
||||
void SetFont( char *face, UInt16 size ) { hsStrncpy( fFontFace, face, sizeof( fFontFace ) ); fFontSize = size; }
|
||||
const char *GetFontFace( void ) { return fFontFace; }
|
||||
const UInt16 GetFontSize( void ) { return fFontSize; }
|
||||
UInt16 GetFontHeight();
|
||||
|
||||
void SetEnable( hsBool on ) { fEnabled = on; }
|
||||
void DisablePermanently( void ) { fEnabled = false; fLockEnable = true; }
|
||||
const hsBool IsEnabled( void ) { return fEnabled; }
|
||||
|
||||
void GetScreenSize( UInt32 *width, UInt32 *height );
|
||||
};
|
||||
|
||||
//// plDebugTextManager Class Definition /////////////////////////////////////
|
||||
|
||||
class plTextFont;
|
||||
|
||||
class plDebugTextManager
|
||||
{
|
||||
protected:
|
||||
|
||||
struct plDebugTextNode
|
||||
{
|
||||
char fText[ 256 ];
|
||||
UInt32 fColor, fDarkColor;
|
||||
UInt16 fX, fY, fRight, fBottom; // Last 2 are for rects only
|
||||
UInt8 fStyle; // 0xff means rectangle, 0xfe means 3d border
|
||||
|
||||
plDebugTextNode() { fText[ 0 ] = 0; fColor = 0; fX = fY = 0; fStyle = 0; }
|
||||
plDebugTextNode( const char *s, UInt32 c, UInt16 x, UInt16 y, UInt8 style );
|
||||
plDebugTextNode( UInt16 left, UInt16 top, UInt16 right, UInt16 bottom, UInt32 c );
|
||||
plDebugTextNode( UInt16 left, UInt16 top, UInt16 right, UInt16 bottom, UInt32 c1, UInt32 c2 );
|
||||
~plDebugTextNode() {;}
|
||||
};
|
||||
|
||||
hsTArray<plDebugTextNode> fList;
|
||||
hsTArray<plDebugTextNode> fDrawOnTopList;
|
||||
|
||||
plTextFont *fFont;
|
||||
UInt32 fSWidth, fSHeight;
|
||||
|
||||
public:
|
||||
|
||||
plDebugTextManager() { plDebugText::Instance().SetManager( this ); fFont = nil; }
|
||||
~plDebugTextManager();
|
||||
|
||||
void AddString( UInt16 x, UInt16 y, const char *s, UInt32 hexColor, UInt8 style, hsBool drawOnTop = false );
|
||||
UInt32 CalcStringWidth( const char *string );
|
||||
|
||||
/// TEMPORARY FUNCTION (until we can find a better way to do this, one way or the other)
|
||||
void DrawRect( UInt16 left, UInt16 top, UInt16 right, UInt16 bottom, UInt32 hexColor, hsBool drawOnTop = false );
|
||||
|
||||
/// EVEN MORE TEMPORARY FUNCTION (until we can find a better way to do this, one way or the other)
|
||||
void Draw3DBorder( UInt16 left, UInt16 top, UInt16 right, UInt16 bottom, UInt32 hexColor1, UInt32 hexColor2, hsBool drawOnTop = false );
|
||||
|
||||
void DrawToDevice( plPipeline *pipe );
|
||||
|
||||
void GetScreenSize( UInt32 *width, UInt32 *height );
|
||||
|
||||
UInt16 GetFontHeight();
|
||||
};
|
||||
|
||||
|
||||
#endif //_plDebugText_h
|
||||
|
@ -0,0 +1,88 @@
|
||||
/*==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/>.
|
||||
|
||||
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 "hsKeyedObject.h"
|
||||
|
||||
|
||||
struct hsMatrix44;
|
||||
class hsBounds3Ext;
|
||||
class hsGMaterial;
|
||||
class hsTriangle3;
|
||||
struct hsGSplat3;
|
||||
|
||||
class plDrawPrim : public hsRefCnt
|
||||
{
|
||||
public:
|
||||
enum plDPPrimType
|
||||
{
|
||||
kTypeNone = 0x0,
|
||||
kTypeTriList = 0x1,
|
||||
kTypeSplatList = 0x2
|
||||
};
|
||||
protected:
|
||||
UInt32 fPrimType;
|
||||
|
||||
UInt32 fDrawProps;
|
||||
|
||||
hsGMaterial* fMaterial;
|
||||
|
||||
public:
|
||||
plDrawPrim() : fMaterial(nil), fDrawProps(0), fPrimType(kTypeNone) {}
|
||||
virtual ~plDrawPrim();
|
||||
|
||||
virtual const hsBounds3Ext& GetLocalBounds() const = 0;
|
||||
|
||||
hsGMaterial* GetMaterial() { return fMaterial; }
|
||||
UInt32 GetPrimType() { return fPrimType; }
|
||||
UInt32 GetDrawProps() { return fDrawProps; }
|
||||
};
|
||||
|
||||
class plTriListPrim : public plDrawPrim
|
||||
{
|
||||
public:
|
||||
plTriListPrim() { fPrimType |= kTypeTriList; }
|
||||
virtual ~plTriListPrim();
|
||||
|
||||
virtual const hsBounds3Ext& GetLocalBounds() const = 0;
|
||||
|
||||
virtual hsTriangle3* GetTriList(int& num) = 0;
|
||||
|
||||
};
|
||||
|
||||
class plSplatListPrim : public plDrawPrim
|
||||
{
|
||||
public:
|
||||
plSplatListPrim() { fPrimType |= kTypeSplatList; }
|
||||
|
||||
virtual const hsBounds3Ext& GetLocalBounds() const = 0;
|
||||
|
||||
virtual hsGSplat3* GetSplatList(int& num) = 0;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
@ -0,0 +1,952 @@
|
||||
/*==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/>.
|
||||
|
||||
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 "hsTypes.h"
|
||||
#include "plDynamicEnvMap.h"
|
||||
|
||||
#include "plPipeline.h"
|
||||
#include "plPipeDebugFlags.h"
|
||||
#include "plDrawable.h"
|
||||
#include "plgDispatch.h"
|
||||
#include "hsResMgr.h"
|
||||
|
||||
#include "hsTimer.h"
|
||||
#include "hsStream.h"
|
||||
|
||||
#include "../plMessage/plRenderRequestMsg.h"
|
||||
#include "../plMessage/plDynamicEnvMapMsg.h"
|
||||
#include "../pfCamera/plCameraModifier.h"
|
||||
#include "../pfCamera/plVirtualCamNeu.h"
|
||||
#include "../plMessage/plRenderMsg.h"
|
||||
#include "../plMessage/plAgeLoadedMsg.h"
|
||||
#include "../plMessage/plLayRefMsg.h"
|
||||
#include "../pnMessage/plPipeResMakeMsg.h"
|
||||
#include "../pnMessage/plRefMsg.h"
|
||||
|
||||
#include "../plScene/plVisRegion.h"
|
||||
#include "../plScene/plVisMgr.h"
|
||||
#include "../plResMgr/plKeyFinder.h"
|
||||
#include "../plSurface/plLayer.h"
|
||||
|
||||
plDynamicEnvMap::plDynamicEnvMap()
|
||||
: fPos(0,0,0),
|
||||
fHither(0.3f),
|
||||
fYon(1000.f),
|
||||
fFogStart(1000.f),
|
||||
fRefreshRate(0.f),
|
||||
fLastRefresh(0.0),
|
||||
fLastRender(0),
|
||||
fOutStanding(0),
|
||||
fIncCharacters(false),
|
||||
fRootNode(nil)
|
||||
{
|
||||
fColor.Set(0,0,0,1.f);
|
||||
int i;
|
||||
for( i = 0; i < 6; i++ )
|
||||
fReqMsgs[i] = TRACKED_NEW plRenderRequestMsg(nil, &fReqs[i]);;
|
||||
|
||||
SetPosition(fPos);
|
||||
}
|
||||
|
||||
plDynamicEnvMap::plDynamicEnvMap(UInt16 width, UInt16 height, UInt8 bitDepth, UInt8 zDepth, UInt8 sDepth)
|
||||
: fPos(0,0,0),
|
||||
fHither(0.3f),
|
||||
fYon(0.f), // yon < hither means ignore and use current settings
|
||||
fFogStart(-1.f), // - fog start means use current settings
|
||||
fRefreshRate(0.f),
|
||||
fLastRefresh(0.0),
|
||||
fLastRender(0),
|
||||
fOutStanding(0),
|
||||
fIncCharacters(false),
|
||||
fRootNode(nil),
|
||||
plCubicRenderTarget(plRenderTarget::kIsTexture, width, height, bitDepth, zDepth, sDepth)
|
||||
{
|
||||
fColor.Set(0,0,0,1.f);
|
||||
int i;
|
||||
for( i = 0; i < 6; i++ )
|
||||
fReqMsgs[i] = TRACKED_NEW plRenderRequestMsg(nil, &fReqs[i]);;
|
||||
|
||||
SetPosition(fPos);
|
||||
}
|
||||
|
||||
plDynamicEnvMap::~plDynamicEnvMap()
|
||||
{
|
||||
SetDeviceRef(nil);
|
||||
|
||||
int i;
|
||||
for( i = 0; i < 6; i++ )
|
||||
delete fReqMsgs[i];
|
||||
}
|
||||
|
||||
void plDynamicEnvMap::Init()
|
||||
{
|
||||
plgDispatch::Dispatch()->RegisterForExactType(plPipeRTMakeMsg::Index(), GetKey());
|
||||
plgDispatch::Dispatch()->RegisterForExactType(plInitialAgeStateLoadedMsg::Index(), GetKey());
|
||||
plgDispatch::Dispatch()->RegisterForExactType(plAgeLoadedMsg::Index(), GetKey());
|
||||
|
||||
plgDispatch::Dispatch()->RegisterForExactType(plRenderMsg::Index(), GetKey());
|
||||
|
||||
ISetupRenderRequests();
|
||||
}
|
||||
|
||||
hsPoint3 plDynamicEnvMap::GetPosition() const
|
||||
{
|
||||
if (fRootNode)
|
||||
{
|
||||
// This is to catch export issues where we've got a root node, but its iface
|
||||
// hasn't fully been set up yet.
|
||||
if (fRootNode->GetCoordinateInterface())
|
||||
return fRootNode->GetLocalToWorld().GetTranslate();
|
||||
}
|
||||
|
||||
return fPos;
|
||||
}
|
||||
|
||||
void plDynamicEnvMap::SetPosition(const hsPoint3& pos)
|
||||
{
|
||||
hsAssert(fRootNode == nil, "Trying to override a cube map's root node.");
|
||||
fPos = pos;
|
||||
SetCameraMatrix(fPos);
|
||||
}
|
||||
|
||||
void plDynamicEnvMap::IUpdatePosition()
|
||||
{
|
||||
hsPoint3 pos = GetPosition();
|
||||
if (pos != fPos)
|
||||
SetCameraMatrix(fPos);
|
||||
}
|
||||
|
||||
void plDynamicEnvMap::SetHither(hsScalar f)
|
||||
{
|
||||
fHither = f;
|
||||
}
|
||||
|
||||
void plDynamicEnvMap::SetYon(hsScalar f)
|
||||
{
|
||||
fYon = f;
|
||||
}
|
||||
|
||||
void plDynamicEnvMap::SetFogStart(hsScalar f)
|
||||
{
|
||||
fFogStart = f;
|
||||
}
|
||||
|
||||
void plDynamicEnvMap::SetColor(const hsColorRGBA& col)
|
||||
{
|
||||
fColor = col;
|
||||
}
|
||||
|
||||
void plDynamicEnvMap::SetRefreshRate(hsScalar secs)
|
||||
{
|
||||
fRefreshRate = secs / 6.f;
|
||||
plgDispatch::Dispatch()->RegisterForExactType(plRenderMsg::Index(), GetKey());
|
||||
}
|
||||
|
||||
void plDynamicEnvMap::ISetupRenderRequests()
|
||||
{
|
||||
UInt32 renderState
|
||||
= plPipeline::kRenderNormal
|
||||
| plPipeline::kRenderClearColor
|
||||
| plPipeline::kRenderClearDepth;
|
||||
|
||||
int i;
|
||||
for( i = 0; i < 6; i++ )
|
||||
{
|
||||
fReqs[i].SetRenderState(renderState);
|
||||
|
||||
fReqs[i].SetDrawableMask(plDrawable::kNormal);
|
||||
fReqs[i].SetSubDrawableMask(plDrawable::kSubAllTypes);
|
||||
|
||||
fReqs[i].SetHither(fHither);
|
||||
fReqs[i].SetYon(fYon);
|
||||
|
||||
fReqs[i].SetFogStart(fFogStart);
|
||||
|
||||
fReqs[i].SetFovX(90.f);
|
||||
fReqs[i].SetFovY(90.f);
|
||||
|
||||
fReqs[i].SetClearColor(fColor);
|
||||
fReqs[i].SetClearDepth(1.f);
|
||||
|
||||
fReqs[i].SetClearDrawable(nil);
|
||||
fReqs[i].SetRenderTarget(GetFace(i));
|
||||
|
||||
fReqs[i].SetCameraTransform(GetWorldToCamera(i), GetCameraToWorld(i));
|
||||
|
||||
fReqs[i].SetVisForce(fVisSet);
|
||||
|
||||
fReqs[i].RequestAck(GetKey());
|
||||
}
|
||||
}
|
||||
|
||||
void plDynamicEnvMap::ISubmitRenderRequest(int i)
|
||||
{
|
||||
IUpdatePosition();
|
||||
fReqMsgs[i]->SendAndKeep();
|
||||
fLastRender = i;
|
||||
fOutStanding++;
|
||||
}
|
||||
|
||||
void plDynamicEnvMap::ISubmitRenderRequests()
|
||||
{
|
||||
IUpdatePosition();
|
||||
int i;
|
||||
for( i = 0; i < 6; i++ )
|
||||
fReqMsgs[i]->SendAndKeep();
|
||||
fLastRefresh = hsTimer::GetSysSeconds();
|
||||
fOutStanding += 6;
|
||||
}
|
||||
|
||||
void plDynamicEnvMap::ICheckForRefresh(double t, plPipeline *pipe)
|
||||
{
|
||||
if( fLastRefresh <= 0 )
|
||||
{
|
||||
ISubmitRenderRequests();
|
||||
return;
|
||||
}
|
||||
|
||||
if( fRefreshRate <= 0 )
|
||||
return;
|
||||
|
||||
#ifndef PLASMA_EXTERNAL_RELEASE
|
||||
if (pipe->IsDebugFlagSet(plPipeDbg::kFlagNVPerfHUD) && hsTimer::GetDelSysSeconds() == 0)
|
||||
{
|
||||
ISubmitRenderRequests();
|
||||
return;
|
||||
}
|
||||
#endif // PLASMA_EXTERNAL_RELEASE
|
||||
|
||||
if( t > fLastRefresh + 6.f * fRefreshRate )
|
||||
{
|
||||
ISubmitRenderRequests();
|
||||
return;
|
||||
}
|
||||
while( t > fLastRefresh + fRefreshRate )
|
||||
{
|
||||
int nextRender = fLastRender+1;
|
||||
if( nextRender > 5 )
|
||||
nextRender = 0;
|
||||
ISubmitRenderRequest(nextRender);
|
||||
fLastRefresh += fRefreshRate;
|
||||
}
|
||||
}
|
||||
|
||||
void plDynamicEnvMap::ReRender()
|
||||
{
|
||||
ISetupRenderRequests();
|
||||
ISubmitRenderRequests();
|
||||
}
|
||||
|
||||
hsBool plDynamicEnvMap::INeedReRender()
|
||||
{
|
||||
fOutStanding = 0;
|
||||
fLastRefresh = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
hsBool plDynamicEnvMap::MsgReceive(plMessage* msg)
|
||||
{
|
||||
plRenderRequestAck* ack = plRenderRequestAck::ConvertNoRef(msg);
|
||||
if( ack )
|
||||
{
|
||||
fOutStanding--;
|
||||
return true;
|
||||
}
|
||||
plRenderMsg* rendMsg = plRenderMsg::ConvertNoRef(msg);
|
||||
if( rendMsg )
|
||||
{
|
||||
if( fOutStanding )
|
||||
INeedReRender();
|
||||
|
||||
ICheckForRefresh(hsTimer::GetSysSeconds(), rendMsg->Pipeline());
|
||||
return true;
|
||||
}
|
||||
if( plPipeRTMakeMsg::ConvertNoRef(msg) )
|
||||
{
|
||||
INeedReRender();
|
||||
plCubicRenderTarget::MsgReceive(msg);
|
||||
return true;
|
||||
}
|
||||
plAgeLoadedMsg* ageLoaded = plAgeLoadedMsg::ConvertNoRef(msg);
|
||||
if( ageLoaded && ageLoaded->fLoaded )
|
||||
return INeedReRender();
|
||||
|
||||
if( plInitialAgeStateLoadedMsg::ConvertNoRef(msg) )
|
||||
return INeedReRender();
|
||||
|
||||
plDynamicEnvMapMsg* cmd = plDynamicEnvMapMsg::ConvertNoRef(msg);
|
||||
if( cmd )
|
||||
{
|
||||
if( cmd->fCmd & plDynamicEnvMapMsg::kSetPosition )
|
||||
SetPosition(cmd->fPos);
|
||||
|
||||
if( cmd->fCmd & plDynamicEnvMapMsg::kSetHither )
|
||||
SetHither(cmd->fHither);
|
||||
|
||||
if( cmd->fCmd & plDynamicEnvMapMsg::kSetFogStart )
|
||||
SetFogStart(cmd->fFogStart);
|
||||
|
||||
if( cmd->fCmd & plDynamicEnvMapMsg::kSetYon )
|
||||
SetYon(cmd->fYon);
|
||||
|
||||
if( cmd->fCmd & plDynamicEnvMapMsg::kSetColor )
|
||||
SetColor(cmd->fColor);
|
||||
|
||||
if( cmd->fCmd & plDynamicEnvMapMsg::kSetRefresh )
|
||||
SetRefreshRate(cmd->fRefresh);
|
||||
|
||||
// If we're going to ReRender, make sure we've gotten any
|
||||
// parameter changes first.
|
||||
if( cmd->fCmd & plDynamicEnvMapMsg::kReRender )
|
||||
{
|
||||
ISetupRenderRequests();
|
||||
INeedReRender();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
plGenRefMsg* refMsg = plGenRefMsg::ConvertNoRef(msg);
|
||||
if( refMsg )
|
||||
{
|
||||
if( IOnRefMsg(refMsg) )
|
||||
return true;
|
||||
}
|
||||
|
||||
return plCubicRenderTarget::MsgReceive(msg);
|
||||
}
|
||||
|
||||
hsBool plDynamicEnvMap::IOnRefMsg(plGenRefMsg* refMsg)
|
||||
{
|
||||
switch( refMsg->fType)
|
||||
{
|
||||
case kRefVisSet:
|
||||
if( refMsg->GetContext() & (plRefMsg::kOnCreate|plRefMsg::kOnRequest|plRefMsg::kOnReplace) )
|
||||
{
|
||||
plVisRegion* reg = plVisRegion::ConvertNoRef(refMsg->GetRef());
|
||||
int idx = fVisRegions.Find(reg);
|
||||
if( reg && (fVisRegions.kMissingIndex == idx) )
|
||||
{
|
||||
fVisRegions.Append(reg);
|
||||
fVisSet.SetBit(reg->GetIndex());
|
||||
}
|
||||
ISetupRenderRequests();
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
plVisRegion* reg = plVisRegion::ConvertNoRef(refMsg->GetRef());
|
||||
int idx = fVisRegions.Find(reg);
|
||||
if( reg && (fVisRegions.kMissingIndex != idx) )
|
||||
{
|
||||
fVisRegions.Remove(idx);
|
||||
fVisSet.ClearBit(reg->GetIndex());
|
||||
}
|
||||
ISetupRenderRequests();
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
|
||||
case kRefRootNode:
|
||||
plSceneObject *so = plSceneObject::ConvertNoRef(refMsg->GetRef());
|
||||
if( refMsg->GetContext() & (plRefMsg::kOnCreate|plRefMsg::kOnRequest|plRefMsg::kOnReplace) )
|
||||
fRootNode = so;
|
||||
else
|
||||
fRootNode = nil;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void plDynamicEnvMap::SetIncludeCharacters(hsBool b)
|
||||
{
|
||||
fIncCharacters = b;
|
||||
if( b )
|
||||
fVisSet.SetBit(plVisMgr::kCharacter);
|
||||
else
|
||||
fVisSet.ClearBit(plVisMgr::kCharacter);
|
||||
}
|
||||
|
||||
void plDynamicEnvMap::AddVisRegion(plVisRegion* reg)
|
||||
{
|
||||
plGenRefMsg* msg = TRACKED_NEW plGenRefMsg(GetKey(), plRefMsg::kOnRequest, 0, kRefVisSet);
|
||||
hsgResMgr::ResMgr()->AddViaNotify(reg->GetKey(), msg, plRefFlags::kActiveRef);
|
||||
}
|
||||
|
||||
void plDynamicEnvMap::Read(hsStream* s, hsResMgr* mgr)
|
||||
{
|
||||
hsKeyedObject::Read(s, mgr);
|
||||
UInt32 sz = plCubicRenderTarget::Read(s);
|
||||
|
||||
fPos.Read(s);
|
||||
fHither = s->ReadSwapScalar();
|
||||
fYon = s->ReadSwapScalar();
|
||||
fFogStart = s->ReadSwapScalar();
|
||||
fColor.Read(s);
|
||||
|
||||
fRefreshRate = s->ReadSwapScalar();
|
||||
|
||||
SetPosition(fPos);
|
||||
|
||||
sz += sizeof(fPos) + sizeof(fHither) + sizeof(fYon) + sizeof(fFogStart) + sizeof(fColor) + sizeof(fRefreshRate);
|
||||
|
||||
fIncCharacters = s->ReadByte();
|
||||
SetIncludeCharacters(fIncCharacters);
|
||||
int nVis = s->ReadSwap32();
|
||||
int i;
|
||||
for( i = 0; i < nVis; i++ )
|
||||
mgr->ReadKeyNotifyMe(s, TRACKED_NEW plGenRefMsg(GetKey(), plRefMsg::kOnCreate, -1, kRefVisSet), plRefFlags::kActiveRef);
|
||||
|
||||
nVis = s->ReadSwap32();
|
||||
for( i = 0; i < nVis; i++)
|
||||
{
|
||||
char *name = s->ReadSafeString();
|
||||
plKey key = plKeyFinder::Instance().StupidSearch(nil, nil, plVisRegion::Index(), name);
|
||||
delete[] name;
|
||||
if (key)
|
||||
hsgResMgr::ResMgr()->AddViaNotify(key, TRACKED_NEW plGenRefMsg(GetKey(), plRefMsg::kOnCreate, -1, kRefVisSet), plRefFlags::kActiveRef);
|
||||
}
|
||||
|
||||
mgr->ReadKeyNotifyMe(s, TRACKED_NEW plGenRefMsg(GetKey(), plRefMsg::kOnCreate, -1, kRefRootNode), plRefFlags::kActiveRef);
|
||||
|
||||
Init();
|
||||
}
|
||||
|
||||
void plDynamicEnvMap::Write(hsStream* s, hsResMgr* mgr)
|
||||
{
|
||||
hsKeyedObject::Write(s, mgr);
|
||||
|
||||
UInt32 sz = plCubicRenderTarget::Write(s);
|
||||
|
||||
fPos.Write(s);
|
||||
s->WriteSwapScalar(fHither);
|
||||
s->WriteSwapScalar(fYon);
|
||||
s->WriteSwapScalar(fFogStart);
|
||||
fColor.Write(s);
|
||||
|
||||
s->WriteSwapScalar(fRefreshRate);
|
||||
|
||||
sz += sizeof(fPos) + sizeof(fHither) + sizeof(fYon) + sizeof(fFogStart) + sizeof(fColor) + sizeof(fRefreshRate);
|
||||
|
||||
s->WriteByte(fIncCharacters);
|
||||
s->WriteSwap32(fVisRegions.GetCount());
|
||||
int i;
|
||||
for( i = 0; i < fVisRegions.GetCount(); i++ )
|
||||
mgr->WriteKey(s, fVisRegions[i]);
|
||||
|
||||
s->WriteSwap32(fVisRegionNames.Count());
|
||||
for( i = 0; i < fVisRegionNames.Count(); i++)
|
||||
{
|
||||
s->WriteSafeString(fVisRegionNames[i]);
|
||||
}
|
||||
|
||||
mgr->WriteKey(s, fRootNode);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
UInt8 plDynamicCamMap::fFlags = kReflectionEnabled | kReflectionCapable;
|
||||
|
||||
plDynamicCamMap::plDynamicCamMap() :
|
||||
fHither(0.3f),
|
||||
fYon(500.f),
|
||||
fFogStart(1000.f),
|
||||
fRefreshRate(0.f),
|
||||
fLastRefresh(0.0),
|
||||
fOutStanding(0),
|
||||
fCamera(nil),
|
||||
fRootNode(nil),
|
||||
fIncCharacters(false),
|
||||
fDisableTexture(nil)
|
||||
{
|
||||
fColor.Set(0,0,0,1.f);
|
||||
fReqMsg = TRACKED_NEW plRenderRequestMsg(nil, &fReq);
|
||||
}
|
||||
|
||||
plDynamicCamMap::plDynamicCamMap(UInt16 width, UInt16 height, UInt8 bitDepth, UInt8 zDepth, UInt8 sDepth) :
|
||||
fHither(0.3f),
|
||||
fYon(-1.f),
|
||||
fFogStart(-1.f),
|
||||
fRefreshRate(0.f),
|
||||
fLastRefresh(0.0),
|
||||
fOutStanding(0),
|
||||
fCamera(nil),
|
||||
fRootNode(nil),
|
||||
fIncCharacters(false),
|
||||
fDisableTexture(nil),
|
||||
plRenderTarget(plRenderTarget::kIsTexture, width, height, bitDepth, zDepth, sDepth)
|
||||
{
|
||||
fColor.Set(0,0,0,1.f);
|
||||
fReqMsg = TRACKED_NEW plRenderRequestMsg(nil, &fReq);
|
||||
}
|
||||
|
||||
plDynamicCamMap::~plDynamicCamMap()
|
||||
{
|
||||
plgDispatch::Dispatch()->UnRegisterForExactType(plPipeRTMakeMsg::Index(), GetKey());
|
||||
plgDispatch::Dispatch()->UnRegisterForExactType(plInitialAgeStateLoadedMsg::Index(), GetKey());
|
||||
plgDispatch::Dispatch()->UnRegisterForExactType(plAgeLoadedMsg::Index(), GetKey());
|
||||
plgDispatch::Dispatch()->UnRegisterForExactType(plRenderMsg::Index(), GetKey());
|
||||
|
||||
SetDeviceRef(nil);
|
||||
|
||||
delete fReqMsg;
|
||||
}
|
||||
|
||||
void plDynamicCamMap::Init()
|
||||
{
|
||||
plgDispatch::Dispatch()->RegisterForExactType(plPipeRTMakeMsg::Index(), GetKey());
|
||||
plgDispatch::Dispatch()->RegisterForExactType(plInitialAgeStateLoadedMsg::Index(), GetKey());
|
||||
plgDispatch::Dispatch()->RegisterForExactType(plAgeLoadedMsg::Index(), GetKey());
|
||||
plgDispatch::Dispatch()->RegisterForExactType(plRenderMsg::Index(), GetKey());
|
||||
}
|
||||
|
||||
void plDynamicCamMap::SetRefreshRate(hsScalar secs)
|
||||
{
|
||||
fRefreshRate = secs;
|
||||
plgDispatch::Dispatch()->RegisterForExactType(plRenderMsg::Index(), GetKey());
|
||||
}
|
||||
|
||||
void plDynamicCamMap::ISetupRenderRequest(plPipeline *pipe)
|
||||
{
|
||||
fReq.SetRenderState(plPipeline::kRenderNormal | plPipeline::kRenderClearColor | plPipeline::kRenderClearDepth);
|
||||
fReq.SetDrawableMask(plDrawable::kNormal);
|
||||
fReq.SetSubDrawableMask(plDrawable::kSubAllTypes);
|
||||
fReq.SetHither(fHither);
|
||||
fReq.SetYon(fYon);
|
||||
fReq.SetFogStart(fFogStart);
|
||||
|
||||
// For a reflection map, this must match the camera FOV, or else the camera based
|
||||
// texture coordinates for the reflection texture will be off.
|
||||
//
|
||||
// For a fixed camera, you might want to use the height in both params, so that
|
||||
// you're rendering a square FOV into your square texture. In practice, the artists
|
||||
// don't mind the visual results when just scaling their UVs, so I'll leave it the
|
||||
// same for both cases.
|
||||
fReq.SetFovX(fCamera ? fCamera->GetFOVw() : plVirtualCam1::Instance()->GetFOVw());
|
||||
fReq.SetFovY(fCamera ? fCamera->GetFOVh() : plVirtualCam1::Instance()->GetFOVh());
|
||||
|
||||
fReq.SetClearColor(fColor);
|
||||
fReq.SetClearDepth(1.f);
|
||||
fReq.SetClearDrawable(nil);
|
||||
fReq.SetRenderTarget(this);
|
||||
fReq.SetVisForce(fVisSet);
|
||||
fReq.SetIgnoreOccluders(true);
|
||||
fReq.RequestAck(GetKey());
|
||||
|
||||
hsMatrix44 w2c, c2w;
|
||||
if (fCamera)
|
||||
{
|
||||
w2c.MakeCamera(&fCamera->GetTargetPos(), &fCamera->GetTargetPOA(), &hsVector3(0.f, 0.f, 1.f));
|
||||
w2c.GetInverse(&c2w);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!fRootNode)
|
||||
return;
|
||||
|
||||
// Could be optimized, but the matrix construction work here seems cheap relative to the cost
|
||||
// of rerendering all this stuff to a separate target, so I doubt we'd notice.
|
||||
hsMatrix44 invert;
|
||||
invert.MakeScaleMat(&(hsVector3(1.f, 1.f, -1.f)));
|
||||
w2c = pipe->GetWorldToCamera();
|
||||
c2w = pipe->GetCameraToWorld();
|
||||
|
||||
w2c = w2c * fRootNode->GetLocalToWorld() * invert * fRootNode->GetWorldToLocal();
|
||||
c2w = fRootNode->GetWorldToLocal() * invert * fRootNode->GetLocalToWorld() * c2w;
|
||||
}
|
||||
fReq.SetCameraTransform(w2c, c2w);
|
||||
}
|
||||
|
||||
void plDynamicCamMap::ISubmitRenderRequest(plPipeline *pipe)
|
||||
{
|
||||
ISetupRenderRequest(pipe);
|
||||
fReqMsg->SendAndKeep();
|
||||
fOutStanding++;
|
||||
fLastRefresh = hsTimer::GetSysSeconds();
|
||||
}
|
||||
|
||||
void plDynamicCamMap::ICheckForRefresh(double t, plPipeline *pipe)
|
||||
{
|
||||
int i;
|
||||
|
||||
hsBool useRefl = (fFlags & kReflectionMask) == kReflectionMask;
|
||||
if (!fCamera)
|
||||
{
|
||||
if ((useRefl && fMatLayers[0]->GetTexture() != this) || (!useRefl && fMatLayers[0]->GetTexture() != fDisableTexture))
|
||||
IPrepTextureLayers();
|
||||
}
|
||||
|
||||
// So no one's using us, eh? Hitting this condition is likely a bug,
|
||||
// but an assert every frame would be annoying. We'll notice when
|
||||
// the render target never updates.
|
||||
if (fTargetNodes.GetCount() == 0)
|
||||
return;
|
||||
|
||||
// If dynamic planar reflections are disabled and we're using our substitute
|
||||
// texture, don't update. Otherwise, this particular reflection is forced to
|
||||
// always display.
|
||||
if (!useRefl && fDisableTexture)
|
||||
return;
|
||||
|
||||
hsBool inView = false;
|
||||
for (i = 0; i < fTargetNodes.GetCount(); i++)
|
||||
{
|
||||
if (pipe->TestVisibleWorld(fTargetNodes[i]))
|
||||
{
|
||||
inView = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!inView)
|
||||
return;
|
||||
|
||||
if( fLastRefresh <= 0 )
|
||||
{
|
||||
ISubmitRenderRequest(pipe);
|
||||
return;
|
||||
}
|
||||
|
||||
if( fRefreshRate <= 0 )
|
||||
return;
|
||||
|
||||
#ifndef PLASMA_EXTERNAL_RELEASE
|
||||
if (pipe->IsDebugFlagSet(plPipeDbg::kFlagNVPerfHUD) && hsTimer::GetDelSysSeconds() == 0)
|
||||
{
|
||||
ISubmitRenderRequest(pipe);
|
||||
}
|
||||
#endif // PLASMA_EXTERNAL_RELEASE
|
||||
|
||||
if (t > fLastRefresh + fRefreshRate)
|
||||
{
|
||||
ISubmitRenderRequest(pipe);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
hsBool plDynamicCamMap::INeedReRender()
|
||||
{
|
||||
fOutStanding = 0;
|
||||
fLastRefresh = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
hsBool plDynamicCamMap::MsgReceive(plMessage* msg)
|
||||
{
|
||||
plRenderRequestAck* ack = plRenderRequestAck::ConvertNoRef(msg);
|
||||
if( ack )
|
||||
{
|
||||
fOutStanding--;
|
||||
return true;
|
||||
}
|
||||
plRenderMsg* rendMsg = plRenderMsg::ConvertNoRef(msg);
|
||||
if( rendMsg )
|
||||
{
|
||||
if( fOutStanding )
|
||||
INeedReRender();
|
||||
|
||||
ICheckForRefresh(hsTimer::GetSysSeconds(), rendMsg->Pipeline());
|
||||
return true;
|
||||
}
|
||||
if( plPipeRTMakeMsg::ConvertNoRef(msg) )
|
||||
{
|
||||
INeedReRender();
|
||||
plRenderTarget::MsgReceive(msg);
|
||||
return true;
|
||||
}
|
||||
plAgeLoadedMsg* ageLoaded = plAgeLoadedMsg::ConvertNoRef(msg);
|
||||
if( ageLoaded && ageLoaded->fLoaded )
|
||||
return INeedReRender();
|
||||
|
||||
if( plInitialAgeStateLoadedMsg::ConvertNoRef(msg) )
|
||||
return INeedReRender();
|
||||
|
||||
plDynamicEnvMapMsg* cmd = plDynamicEnvMapMsg::ConvertNoRef(msg);
|
||||
if( cmd )
|
||||
{
|
||||
if( cmd->fCmd & plDynamicEnvMapMsg::kSetFogStart )
|
||||
fFogStart = cmd->fFogStart;
|
||||
|
||||
if( cmd->fCmd & plDynamicEnvMapMsg::kSetColor )
|
||||
fColor = cmd->fColor;
|
||||
|
||||
if( cmd->fCmd & plDynamicEnvMapMsg::kSetRefresh )
|
||||
SetRefreshRate(cmd->fRefresh);
|
||||
|
||||
return true;
|
||||
}
|
||||
plRefMsg* refMsg = plRefMsg::ConvertNoRef(msg);
|
||||
if( refMsg )
|
||||
{
|
||||
if( IOnRefMsg(refMsg) )
|
||||
return true;
|
||||
}
|
||||
|
||||
return plRenderTarget::MsgReceive(msg);
|
||||
}
|
||||
|
||||
void plDynamicCamMap::IPrepTextureLayers()
|
||||
{
|
||||
if (fDisableTexture)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < fMatLayers.GetCount(); i++)
|
||||
{
|
||||
if ((fFlags & kReflectionMask) == kReflectionMask)
|
||||
{
|
||||
fMatLayers[i]->SetUVWSrc(plLayerInterface::kUVWPosition);
|
||||
fMatLayers[i]->SetMiscFlags(hsGMatState::kMiscCam2Screen | hsGMatState::kMiscPerspProjection);
|
||||
hsgResMgr::ResMgr()->SendRef(GetKey(), TRACKED_NEW plGenRefMsg(fMatLayers[i]->GetKey(), plRefMsg::kOnRequest, 0, plLayRefMsg::kTexture), plRefFlags::kActiveRef);
|
||||
}
|
||||
else
|
||||
{
|
||||
fMatLayers[i]->SetUVWSrc(0);
|
||||
fMatLayers[i]->SetMiscFlags(0);
|
||||
hsgResMgr::ResMgr()->SendRef(fDisableTexture->GetKey(), TRACKED_NEW plGenRefMsg(fMatLayers[i]->GetKey(), plRefMsg::kOnRequest, 0, plLayRefMsg::kTexture), plRefFlags::kActiveRef);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
hsBool plDynamicCamMap::IOnRefMsg(plRefMsg* refMsg)
|
||||
{
|
||||
plGenRefMsg* genRefMsg = plGenRefMsg::ConvertNoRef(refMsg);
|
||||
|
||||
if (genRefMsg)
|
||||
{
|
||||
if (genRefMsg->fType == kRefVisSet)
|
||||
{
|
||||
plVisRegion* reg = plVisRegion::ConvertNoRef(refMsg->GetRef());
|
||||
if (reg)
|
||||
{
|
||||
int idx = fVisRegions.Find(reg);
|
||||
if ((refMsg->GetContext() & (plRefMsg::kOnCreate|plRefMsg::kOnRequest|plRefMsg::kOnReplace)) && fVisRegions.kMissingIndex == idx)
|
||||
{
|
||||
fVisRegions.Append(reg);
|
||||
fVisSet.SetBit(reg->GetIndex());
|
||||
}
|
||||
else if (!(refMsg->GetContext() & (plRefMsg::kOnCreate|plRefMsg::kOnRequest|plRefMsg::kOnReplace)) && fVisRegions.kMissingIndex != idx)
|
||||
{
|
||||
fVisRegions.Remove(idx);
|
||||
fVisSet.ClearBit(reg->GetIndex());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (genRefMsg->fType == kRefCamera)
|
||||
{
|
||||
plCameraModifier1 *cam = plCameraModifier1::ConvertNoRef(refMsg->GetRef());
|
||||
if (cam)
|
||||
{
|
||||
if (refMsg->GetContext() & (plRefMsg::kOnCreate|plRefMsg::kOnRequest|plRefMsg::kOnReplace))
|
||||
fCamera = cam;
|
||||
else
|
||||
fCamera = nil;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (genRefMsg->fType == kRefRootNode)
|
||||
{
|
||||
plSceneObject *so = plSceneObject::ConvertNoRef(refMsg->GetRef());
|
||||
if (so)
|
||||
{
|
||||
if (refMsg->GetContext() & (plRefMsg::kOnCreate|plRefMsg::kOnRequest|plRefMsg::kOnReplace))
|
||||
fRootNode = so;
|
||||
else
|
||||
fRootNode = nil;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (genRefMsg->fType == kRefTargetNode)
|
||||
{
|
||||
plSceneObject *so = plSceneObject::ConvertNoRef(refMsg->GetRef());
|
||||
if (so)
|
||||
{
|
||||
if (refMsg->GetContext() & (plRefMsg::kOnCreate|plRefMsg::kOnRequest|plRefMsg::kOnReplace))
|
||||
{
|
||||
if (fTargetNodes.Find(so) == fTargetNodes.kMissingIndex)
|
||||
fTargetNodes.Append(so);
|
||||
}
|
||||
else
|
||||
{
|
||||
fTargetNodes.RemoveItem(so);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (genRefMsg->fType == kRefDisableTexture)
|
||||
{
|
||||
plBitmap *bitmap = plBitmap::ConvertNoRef(refMsg->GetRef());
|
||||
if (bitmap)
|
||||
{
|
||||
if (refMsg->GetContext() & (plRefMsg::kOnCreate|plRefMsg::kOnRequest|plRefMsg::kOnReplace))
|
||||
fDisableTexture = bitmap;
|
||||
else
|
||||
fDisableTexture = nil;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (genRefMsg->fType == kRefMatLayer)
|
||||
{
|
||||
plLayer *lay = plLayer::ConvertNoRef(refMsg->GetRef());
|
||||
if (lay)
|
||||
{
|
||||
if (refMsg->GetContext() & (plRefMsg::kOnCreate|plRefMsg::kOnRequest|plRefMsg::kOnReplace))
|
||||
{
|
||||
if (fMatLayers.Find(lay) == fMatLayers.kMissingIndex)
|
||||
fMatLayers.Append(lay);
|
||||
}
|
||||
else
|
||||
{
|
||||
fMatLayers.RemoveItem(lay);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void plDynamicCamMap::SetIncludeCharacters(hsBool b)
|
||||
{
|
||||
fIncCharacters = b;
|
||||
if( b )
|
||||
fVisSet.SetBit(plVisMgr::kCharacter);
|
||||
else
|
||||
fVisSet.ClearBit(plVisMgr::kCharacter);
|
||||
}
|
||||
|
||||
void plDynamicCamMap::AddVisRegion(plVisRegion* reg)
|
||||
{
|
||||
hsgResMgr::ResMgr()->AddViaNotify( reg->GetKey(), TRACKED_NEW plGenRefMsg( GetKey(), plGenRefMsg::kOnReplace, -1, kRefVisSet ), plRefFlags::kActiveRef );
|
||||
}
|
||||
|
||||
void plDynamicCamMap::SetEnabled(hsBool enable)
|
||||
{
|
||||
if (enable)
|
||||
fFlags |= kReflectionEnabled;
|
||||
else
|
||||
fFlags &= ~kReflectionEnabled;
|
||||
}
|
||||
|
||||
void plDynamicCamMap::SetCapable(hsBool capable)
|
||||
{
|
||||
if (capable)
|
||||
fFlags |= kReflectionCapable;
|
||||
else
|
||||
fFlags &= ~kReflectionCapable;
|
||||
}
|
||||
|
||||
void plDynamicCamMap::Read(hsStream* s, hsResMgr* mgr)
|
||||
{
|
||||
hsKeyedObject::Read(s, mgr);
|
||||
plRenderTarget::Read(s);
|
||||
|
||||
fHither = s->ReadSwapScalar();
|
||||
fYon = s->ReadSwapScalar();
|
||||
fFogStart = s->ReadSwapScalar();
|
||||
fColor.Read(s);
|
||||
|
||||
fRefreshRate = s->ReadSwapScalar();
|
||||
fIncCharacters = s->ReadBool();
|
||||
SetIncludeCharacters(fIncCharacters);
|
||||
mgr->ReadKeyNotifyMe(s, TRACKED_NEW plGenRefMsg(GetKey(), plRefMsg::kOnCreate, 0, kRefCamera), plRefFlags::kPassiveRef);
|
||||
mgr->ReadKeyNotifyMe(s, TRACKED_NEW plGenRefMsg(GetKey(), plRefMsg::kOnCreate, 0, kRefRootNode), plRefFlags::kActiveRef);
|
||||
|
||||
int numTargs = s->ReadByte();
|
||||
int i;
|
||||
for (i = 0; i < numTargs; i++)
|
||||
mgr->ReadKeyNotifyMe(s, TRACKED_NEW plGenRefMsg(GetKey(), plRefMsg::kOnCreate, i, kRefTargetNode), plRefFlags::kPassiveRef);
|
||||
|
||||
int nVis = s->ReadSwap32();
|
||||
for( i = 0; i < nVis; i++ )
|
||||
mgr->ReadKeyNotifyMe(s, TRACKED_NEW plGenRefMsg(GetKey(), plRefMsg::kOnCreate, 0, kRefVisSet), plRefFlags::kActiveRef);
|
||||
|
||||
nVis = s->ReadSwap32();
|
||||
for( i = 0; i < nVis; i++)
|
||||
{
|
||||
char *name = s->ReadSafeString();
|
||||
plKey key = plKeyFinder::Instance().StupidSearch(nil, nil, plVisRegion::Index(), name);
|
||||
delete[] name;
|
||||
if (key)
|
||||
hsgResMgr::ResMgr()->AddViaNotify(key, TRACKED_NEW plGenRefMsg(GetKey(), plRefMsg::kOnCreate, -1, kRefVisSet), plRefFlags::kActiveRef);
|
||||
}
|
||||
|
||||
mgr->ReadKeyNotifyMe(s, TRACKED_NEW plGenRefMsg(GetKey(), plRefMsg::kOnCreate, 0, kRefDisableTexture), plRefFlags::kActiveRef);
|
||||
|
||||
UInt8 numLayers = s->ReadByte();
|
||||
for (i = 0; i < numLayers; i++)
|
||||
{
|
||||
mgr->ReadKeyNotifyMe(s, TRACKED_NEW plGenRefMsg(GetKey(), plRefMsg::kOnCreate, 0, kRefMatLayer), plRefFlags::kPassiveRef);
|
||||
}
|
||||
|
||||
Init();
|
||||
}
|
||||
|
||||
void plDynamicCamMap::Write(hsStream* s, hsResMgr* mgr)
|
||||
{
|
||||
hsKeyedObject::Write(s, mgr);
|
||||
plRenderTarget::Write(s);
|
||||
|
||||
s->WriteSwapScalar(fHither);
|
||||
s->WriteSwapScalar(fYon);
|
||||
s->WriteSwapScalar(fFogStart);
|
||||
fColor.Write(s);
|
||||
|
||||
s->WriteSwapScalar(fRefreshRate);
|
||||
s->WriteByte(fIncCharacters);
|
||||
mgr->WriteKey(s, (fCamera ? fCamera->GetKey() : nil));
|
||||
mgr->WriteKey(s, (fRootNode ? fRootNode->GetKey() : nil));
|
||||
|
||||
s->WriteByte(fTargetNodes.GetCount());
|
||||
int i;
|
||||
for (i = 0; i < fTargetNodes.GetCount(); i++)
|
||||
mgr->WriteKey(s, fTargetNodes[i]);
|
||||
|
||||
s->WriteSwap32(fVisRegions.GetCount());
|
||||
for( i = 0; i < fVisRegions.GetCount(); i++ )
|
||||
mgr->WriteKey(s, fVisRegions[i]);
|
||||
|
||||
s->WriteSwap32(fVisRegionNames.Count());
|
||||
for( i = 0; i < fVisRegionNames.Count(); i++)
|
||||
{
|
||||
s->WriteSafeString(fVisRegionNames[i]);
|
||||
}
|
||||
|
||||
mgr->WriteKey(s, fDisableTexture ? fDisableTexture->GetKey() : nil);
|
||||
|
||||
s->WriteByte(fMatLayers.GetCount());
|
||||
for (i = 0; i < fMatLayers.GetCount(); i++)
|
||||
{
|
||||
mgr->WriteKey(s, fMatLayers[i]->GetKey());
|
||||
}
|
||||
}
|
@ -0,0 +1,209 @@
|
||||
/*==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/>.
|
||||
|
||||
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 plDynamicEnvMap_inc
|
||||
#define plDynamicEnvMap_inc
|
||||
|
||||
#include "plCubicRenderTarget.h"
|
||||
#include "../plScene/plRenderRequest.h"
|
||||
#include "hsBitVector.h"
|
||||
|
||||
class plRenderRequestMsg;
|
||||
class hsStream;
|
||||
class plMessage;
|
||||
class plVisRegion;
|
||||
class plGenRefMsg;
|
||||
class hsResMgr;
|
||||
class plCameraModifier1;
|
||||
class plSceneObject;
|
||||
class plBitmap;
|
||||
class plLayer;
|
||||
|
||||
class plDynamicEnvMap : public plCubicRenderTarget
|
||||
{
|
||||
public:
|
||||
enum {
|
||||
kRefVisSet,
|
||||
kRefRootNode,
|
||||
};
|
||||
protected:
|
||||
|
||||
plRenderRequest fReqs[6];
|
||||
plRenderRequestMsg* fReqMsgs[6];
|
||||
|
||||
plSceneObject* fRootNode;
|
||||
hsPoint3 fPos;
|
||||
hsScalar fHither;
|
||||
hsScalar fYon;
|
||||
hsScalar fFogStart;
|
||||
hsColorRGBA fColor;
|
||||
|
||||
hsScalar fRefreshRate;
|
||||
double fLastRefresh;
|
||||
int fLastRender;
|
||||
int fOutStanding;
|
||||
|
||||
hsBitVector fVisSet;
|
||||
hsTArray<plVisRegion*> fVisRegions;
|
||||
hsTArray<char *> fVisRegionNames;
|
||||
hsBool fIncCharacters;
|
||||
|
||||
void IUpdatePosition();
|
||||
hsBool INeedReRender();
|
||||
|
||||
void ISetupRenderRequests();
|
||||
void ISubmitRenderRequests();
|
||||
void ISubmitRenderRequest(int i);
|
||||
void ICheckForRefresh(double t, plPipeline *pipe);
|
||||
|
||||
hsBool IOnRefMsg(plGenRefMsg* refMsg);
|
||||
|
||||
public:
|
||||
plDynamicEnvMap();
|
||||
plDynamicEnvMap(UInt16 width, UInt16 height, UInt8 bitDepth, UInt8 zDepth = -1, UInt8 sDepth = -1);
|
||||
|
||||
virtual ~plDynamicEnvMap();
|
||||
|
||||
CLASSNAME_REGISTER( plDynamicEnvMap );
|
||||
GETINTERFACE_ANY( plDynamicEnvMap, plCubicRenderTarget );
|
||||
|
||||
virtual void Read(hsStream* s, hsResMgr* mgr);
|
||||
virtual void Write(hsStream* s, hsResMgr* mgr);
|
||||
|
||||
virtual hsBool MsgReceive(plMessage* msg);
|
||||
|
||||
void ReRender();
|
||||
|
||||
void Init();
|
||||
|
||||
void SetPosition(const hsPoint3& pos);
|
||||
void SetHither(hsScalar f);
|
||||
void SetYon(hsScalar f);
|
||||
void SetFogStart(hsScalar f);
|
||||
void SetColor(const hsColorRGBA& col);
|
||||
void SetRefreshRate(hsScalar secs);
|
||||
|
||||
hsPoint3 GetPosition() const;
|
||||
hsScalar GetHither() const { return fHither; }
|
||||
hsScalar GetYon() const { return fYon; }
|
||||
hsScalar GetFogStart() const { return fFogStart; }
|
||||
hsColorRGBA GetColor() const { return fColor; }
|
||||
hsScalar GetRefreshRate() const { return 6.f * fRefreshRate; }
|
||||
|
||||
void AddVisRegion(plVisRegion* reg); // Will just send a ref
|
||||
|
||||
void SetIncludeCharacters(hsBool b);
|
||||
hsBool GetIncludeCharacters() const { return fIncCharacters; }
|
||||
void SetVisRegionName(char *name){ fVisRegionNames.Push(name); }
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Yes, it's lame that a lot of this code is nearly the same as
|
||||
// plDynamicEnvMap, but this derives from plRenderTarget, not plCubicRenderTarget
|
||||
// and I don't want to touch multiple inheritance.
|
||||
class plDynamicCamMap : public plRenderTarget
|
||||
{
|
||||
public:
|
||||
enum
|
||||
{
|
||||
kRefVisSet,
|
||||
kRefCamera,
|
||||
kRefRootNode,
|
||||
kRefTargetNode,
|
||||
kRefDisableTexture,
|
||||
kRefMatLayer,
|
||||
};
|
||||
|
||||
hsScalar fHither;
|
||||
hsScalar fYon;
|
||||
hsScalar fFogStart;
|
||||
hsColorRGBA fColor;
|
||||
|
||||
protected:
|
||||
plRenderRequest fReq;
|
||||
plRenderRequestMsg* fReqMsg;
|
||||
|
||||
hsScalar fRefreshRate;
|
||||
double fLastRefresh;
|
||||
int fOutStanding;
|
||||
|
||||
hsBitVector fVisSet;
|
||||
hsTArray<plVisRegion*> fVisRegions;
|
||||
hsTArray<char *> fVisRegionNames; // this allows us to specify vis-regions in other pages.
|
||||
hsBool fIncCharacters;
|
||||
plCameraModifier1* fCamera;
|
||||
plSceneObject* fRootNode;
|
||||
hsTArray<plSceneObject*> fTargetNodes;
|
||||
|
||||
// Extra info for swapping around textures when reflections are disabled.
|
||||
plBitmap* fDisableTexture;
|
||||
hsTArray<plLayer*> fMatLayers;
|
||||
static UInt8 fFlags;
|
||||
enum
|
||||
{
|
||||
kReflectionCapable = 0x01,
|
||||
kReflectionEnabled = 0x02,
|
||||
kReflectionMask = kReflectionCapable | kReflectionEnabled,
|
||||
};
|
||||
|
||||
hsBool INeedReRender();
|
||||
|
||||
void ISetupRenderRequest(plPipeline *pipe);
|
||||
void ISubmitRenderRequest(plPipeline *pipe);
|
||||
void ICheckForRefresh(double t, plPipeline *pipe);
|
||||
void IPrepTextureLayers();
|
||||
|
||||
hsBool IOnRefMsg(plRefMsg* refMsg);
|
||||
|
||||
public:
|
||||
plDynamicCamMap();
|
||||
plDynamicCamMap(UInt16 width, UInt16 height, UInt8 bitDepth, UInt8 zDepth = -1, UInt8 sDepth = -1);
|
||||
|
||||
virtual ~plDynamicCamMap();
|
||||
|
||||
CLASSNAME_REGISTER( plDynamicCamMap );
|
||||
GETINTERFACE_ANY( plDynamicCamMap, plRenderTarget );
|
||||
|
||||
virtual void Read(hsStream* s, hsResMgr* mgr);
|
||||
virtual void Write(hsStream* s, hsResMgr* mgr);
|
||||
|
||||
virtual hsBool MsgReceive(plMessage* msg);
|
||||
|
||||
void ReRender();
|
||||
void Init();
|
||||
|
||||
void SetIncludeCharacters(hsBool b);
|
||||
void SetRefreshRate(hsScalar secs);
|
||||
void AddVisRegion(plVisRegion* reg);
|
||||
void SetVisRegionName(char *name){ fVisRegionNames.Push(name); }
|
||||
|
||||
static hsBool GetEnabled() { return (fFlags & kReflectionEnabled) != 0; }
|
||||
static void SetEnabled(hsBool enable);
|
||||
static hsBool GetCapable() { return (fFlags & kReflectionCapable) != 0; }
|
||||
static void SetCapable(hsBool capable);
|
||||
};
|
||||
|
||||
#endif // plDynamicEnvMap_inc
|
@ -0,0 +1,197 @@
|
||||
/*==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/>.
|
||||
|
||||
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==*/
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// plFogEnvironment.cpp - Functions for the fog volume class //
|
||||
// //
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "plFogEnvironment.h"
|
||||
|
||||
#include "plTweak.h"
|
||||
|
||||
//// Constructors & Destructor ///////////////////////////////////////////////
|
||||
|
||||
plFogEnvironment::plFogEnvironment()
|
||||
{
|
||||
fType = kNoFog;
|
||||
}
|
||||
|
||||
plFogEnvironment::plFogEnvironment( hsScalar start, hsScalar end, hsScalar density, hsColorRGBA &color )
|
||||
{
|
||||
Set( start, end, density, &color );
|
||||
}
|
||||
|
||||
plFogEnvironment::plFogEnvironment( FogType type, hsScalar end, hsScalar density, hsColorRGBA &color )
|
||||
{
|
||||
SetExp( type, end, density, &color );
|
||||
}
|
||||
|
||||
plFogEnvironment::~plFogEnvironment()
|
||||
{
|
||||
}
|
||||
|
||||
//// Set /////////////////////////////////////////////////////////////////////
|
||||
|
||||
void plFogEnvironment::Set( hsScalar start, hsScalar end, hsScalar density, const hsColorRGBA *color )
|
||||
{
|
||||
if( density <= 0.f )
|
||||
{
|
||||
fType = kNoFog;
|
||||
fStart = 0.f;
|
||||
fEnd = 0.f;
|
||||
fDensity = 0.f;
|
||||
}
|
||||
else
|
||||
{
|
||||
fType = kLinearFog;
|
||||
fStart = start;
|
||||
fEnd = end;
|
||||
fDensity = density;
|
||||
}
|
||||
if( color != nil )
|
||||
fColor = *color;
|
||||
}
|
||||
|
||||
void plFogEnvironment::SetExp( FogType type, hsScalar end, hsScalar density, const hsColorRGBA *color )
|
||||
{
|
||||
hsAssert( type == kExpFog || type == kExp2Fog, "Invalid fog type passed to plFogEnvironment" );
|
||||
if( density <= 0.f )
|
||||
{
|
||||
fType = kNoFog;
|
||||
fStart = 0.f;
|
||||
fEnd = 0.f;
|
||||
fDensity = 0.f;
|
||||
}
|
||||
else
|
||||
{
|
||||
fType = type;
|
||||
fStart = 0.0f;
|
||||
fEnd = end;
|
||||
fDensity = density;
|
||||
}
|
||||
if( color != nil )
|
||||
fColor = *color;
|
||||
}
|
||||
|
||||
//// GetParameters ///////////////////////////////////////////////////////////
|
||||
// Gets the parameters. Sets start to 0 if the type is not linear (can be
|
||||
// nil).
|
||||
|
||||
void plFogEnvironment::GetParameters( hsScalar *start, hsScalar *end, hsScalar *density, hsColorRGBA *color )
|
||||
{
|
||||
hsAssert( fType != kLinearFog || start != nil, "Trying to get non-linear paramters on linear fog!" );
|
||||
hsAssert( end != nil && density != nil && color != nil, "Bad pointer to plFogEnvironment::GetParameters()" );
|
||||
|
||||
if( fType == kLinearFog )
|
||||
*start = fStart;
|
||||
else if( start != nil )
|
||||
*start = 0.0f;
|
||||
|
||||
*end = fEnd;
|
||||
*density = fDensity;
|
||||
*color = fColor;
|
||||
}
|
||||
|
||||
//// GetPipelineParams ///////////////////////////////////////////////////////
|
||||
// Gets linear pipeline (DX8) specific parameters. Basically massages our
|
||||
// interface values into values that DX8 can use. In this case, we simply
|
||||
// scale our end value out by the density. The whole formula is:
|
||||
// pipelineEnd = ( end - start ) / density + start
|
||||
|
||||
void plFogEnvironment::GetPipelineParams( hsScalar *start, hsScalar *end, hsColorRGBA *color )
|
||||
{
|
||||
// hsAssert( fType == kLinearFog, "Getting linear pipeline params on non-linear fog!" );
|
||||
|
||||
*color = fColor;
|
||||
switch(fType)
|
||||
{
|
||||
case kLinearFog:
|
||||
*start = fStart;
|
||||
*end = (fEnd - fStart) / fDensity + fStart;
|
||||
break;
|
||||
case kExpFog:
|
||||
{
|
||||
plConst(float) kKnee(0.0f);
|
||||
*start = fEnd * kKnee;
|
||||
*end = (fEnd - *start) / fDensity + *start;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
case kExp2Fog:
|
||||
{
|
||||
plConst(float) kKnee(0.3f);
|
||||
*start = fEnd * kKnee;
|
||||
*end = (fEnd - *start) / fDensity + *start;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//// GetPipelineParams ///////////////////////////////////////////////////////
|
||||
// Gets exp/exp^2 pipeline (DX8) specific parameters. Basically massages our
|
||||
// interface values into values that DX8 can use. In this case, we're going
|
||||
// to modulate the density by the end value so that it actually ends at the
|
||||
// right spot.
|
||||
|
||||
void plFogEnvironment::GetPipelineParams( hsScalar *density, hsColorRGBA *color )
|
||||
{
|
||||
const float ln256 = logf( 256.f );
|
||||
const float sqrtLn256 = sqrtf( ln256 );
|
||||
|
||||
|
||||
hsAssert( fType == kExpFog || fType == kExp2Fog, "Getting non-linear pipeline params on linear fog!" );
|
||||
|
||||
*density = ( ( fType == kExpFog ) ? ln256: sqrtLn256 ) * fDensity / fEnd;
|
||||
*color = fColor;
|
||||
}
|
||||
|
||||
//// Read ////////////////////////////////////////////////////////////////////
|
||||
|
||||
void plFogEnvironment::Read( hsStream *s, hsResMgr *mgr )
|
||||
{
|
||||
hsKeyedObject::Read( s, mgr );
|
||||
|
||||
fType = s->ReadByte();
|
||||
fStart = s->ReadSwapFloat();
|
||||
fEnd = s->ReadSwapFloat();
|
||||
fDensity = s->ReadSwapFloat();
|
||||
fColor.Read( s );
|
||||
}
|
||||
|
||||
//// Write ///////////////////////////////////////////////////////////////////
|
||||
|
||||
void plFogEnvironment::Write( hsStream *s, hsResMgr *mgr )
|
||||
{
|
||||
hsKeyedObject::Write( s, mgr );
|
||||
|
||||
s->WriteByte( fType );
|
||||
s->WriteSwapFloat( fStart );
|
||||
s->WriteSwapFloat( fEnd );
|
||||
s->WriteSwapFloat( fDensity );
|
||||
fColor.Write( s );
|
||||
}
|
||||
|
@ -0,0 +1,104 @@
|
||||
/*==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/>.
|
||||
|
||||
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==*/
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// plFogEnvironment.h - Header file for the fog environment class //
|
||||
// //
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef _plFogEnvironment_h
|
||||
#define _plFogEnvironment_h
|
||||
|
||||
#include "../pnKeyedObject/hsKeyedObject.h"
|
||||
#include "hsTypes.h"
|
||||
#include "hsColorRGBA.h"
|
||||
#include "hsTemplates.h"
|
||||
#include "hsUtils.h"
|
||||
|
||||
|
||||
//// plFogEnvironment Class Definition ////////////////////////////////////////////
|
||||
// Defines a fog environment. Bite me.
|
||||
|
||||
class plFogEnvironment : public hsKeyedObject
|
||||
{
|
||||
protected:
|
||||
|
||||
UInt8 fType;
|
||||
hsScalar fStart; // Used for linear fog only
|
||||
hsScalar fEnd, fDensity; // Always used!
|
||||
hsColorRGBA fColor;
|
||||
|
||||
public:
|
||||
|
||||
CLASSNAME_REGISTER( plFogEnvironment );
|
||||
GETINTERFACE_ANY( plFogEnvironment, hsKeyedObject );
|
||||
|
||||
enum FogType
|
||||
{
|
||||
kLinearFog = 0,
|
||||
kExpFog,
|
||||
kExp2Fog,
|
||||
kNoFog
|
||||
};
|
||||
|
||||
plFogEnvironment();
|
||||
plFogEnvironment( hsScalar start, hsScalar end, hsScalar density, hsColorRGBA &color );
|
||||
plFogEnvironment( FogType type, hsScalar end, hsScalar density, hsColorRGBA &color );
|
||||
~plFogEnvironment();
|
||||
|
||||
// Sets the parameters for linear fog
|
||||
void Set( hsScalar start, hsScalar end, hsScalar density, const hsColorRGBA *color = nil );
|
||||
|
||||
// Sets the parameters for exp or exp^2 fog
|
||||
void SetExp( FogType type, hsScalar end, hsScalar density, const hsColorRGBA *color = nil );
|
||||
|
||||
// Sets the color
|
||||
void SetColor( hsColorRGBA &color ) { fColor = color; }
|
||||
|
||||
// Clear the environment to no fog
|
||||
void Clear( void ) { fType = kNoFog; }
|
||||
|
||||
// Gets the type
|
||||
UInt8 GetType( void ) { return fType; }
|
||||
|
||||
// Gets the color
|
||||
hsColorRGBA &GetColor( void ) { return fColor; }
|
||||
|
||||
// Gets the parameters. Sets start to 0 if the type is not linear (can be nil)
|
||||
void GetParameters( hsScalar *start, hsScalar *end, hsScalar *density, hsColorRGBA *color );
|
||||
|
||||
// Gets linear pipeline (DX) specific parameters.
|
||||
void GetPipelineParams( hsScalar *start, hsScalar *end, hsColorRGBA *color );
|
||||
|
||||
// Gets exp or exp^2 pipeline (DX) specific parameters.
|
||||
void GetPipelineParams( hsScalar *density, hsColorRGBA *color );
|
||||
|
||||
virtual void Read(hsStream *s, hsResMgr *mgr);
|
||||
virtual void Write(hsStream *s, hsResMgr *mgr);
|
||||
};
|
||||
|
||||
#endif //_plFogEnvironment_h
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,292 @@
|
||||
/*==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/>.
|
||||
|
||||
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==*/
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// plGBufferGroup Class Header //
|
||||
// Cyan, Inc. //
|
||||
// //
|
||||
//// Version History //////////////////////////////////////////////////////////
|
||||
// //
|
||||
// 2.21.2001 mcn - Created. //
|
||||
// //
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef _plGBufferGroup_h
|
||||
#define _plGBufferGroup_h
|
||||
|
||||
#include "hsTemplates.h"
|
||||
#include "hsGeometry3.h"
|
||||
#include "hsColorRGBA.h"
|
||||
|
||||
//// plGBufferTriangle Struct Definition //////////////////////////////////////
|
||||
//
|
||||
// Represents a single triangle inside a plGBufferGroup, which consists of
|
||||
// three indices (the indices of the three vertices) and a 3-D point
|
||||
// representing the center of the triangle.
|
||||
|
||||
class plGBufferTriangle
|
||||
{
|
||||
public:
|
||||
UInt16 fIndex1, fIndex2, fIndex3, fSpanIndex;
|
||||
hsPoint3 fCenter;
|
||||
|
||||
void Read( hsStream *s );
|
||||
void Write( hsStream *s );
|
||||
};
|
||||
|
||||
//// plGBufferCell and plGBufferColor Definitions /////////////////////////////
|
||||
|
||||
class plGBufferCell
|
||||
{
|
||||
public:
|
||||
UInt32 fVtxStart; // In bytes
|
||||
UInt32 fColorStart; // In bytes
|
||||
UInt32 fLength;
|
||||
|
||||
plGBufferCell( UInt32 vStart, UInt32 cStart, UInt32 len )
|
||||
{
|
||||
fVtxStart = vStart; fColorStart = cStart; fLength = len;
|
||||
}
|
||||
|
||||
plGBufferCell() {}
|
||||
|
||||
void Read( hsStream *s );
|
||||
void Write( hsStream *s );
|
||||
};
|
||||
|
||||
class plGBufferColor
|
||||
{
|
||||
public:
|
||||
UInt32 fDiffuse, fSpecular;
|
||||
};
|
||||
|
||||
//// plGBufferGroup Class Definition //////////////////////////////////////////
|
||||
//
|
||||
// Represents a list of vertex and index buffers in a nice package.
|
||||
|
||||
class hsStream;
|
||||
class hsResMgr;
|
||||
class plPipeline;
|
||||
class hsGDeviceRef;
|
||||
class plGeometrySpan;
|
||||
|
||||
class plGBufferGroup
|
||||
{
|
||||
protected:
|
||||
UInt8 fFormat;
|
||||
UInt8 fStride;
|
||||
UInt8 fLiteStride;
|
||||
UInt8 fNumSkinWeights;
|
||||
UInt32 fNumVerts;
|
||||
UInt32 fNumIndices;
|
||||
hsBool fVertsVolatile;
|
||||
hsBool fIdxVolatile;
|
||||
int fLOD;
|
||||
|
||||
hsTArray<hsGDeviceRef *> fVertexBufferRefs;
|
||||
hsTArray<hsGDeviceRef *> fIndexBufferRefs;
|
||||
|
||||
hsTArray<UInt32> fVertBuffSizes;
|
||||
hsTArray<UInt32> fIdxBuffCounts;
|
||||
hsTArray<UInt32> fColorBuffCounts;
|
||||
hsTArray<UInt8 *> fVertBuffStorage;
|
||||
hsTArray<UInt16 *> fIdxBuffStorage;
|
||||
|
||||
hsTArray<UInt32> fVertBuffStarts;
|
||||
hsTArray<Int32> fVertBuffEnds;
|
||||
hsTArray<UInt32> fIdxBuffStarts;
|
||||
hsTArray<Int32> fIdxBuffEnds;
|
||||
|
||||
hsTArray<plGBufferColor *> fColorBuffStorage;
|
||||
|
||||
hsTArray<hsTArray<plGBufferCell> *> fCells;
|
||||
|
||||
virtual void ISendStorageToBuffers( plPipeline *pipe, hsBool adjustForNvidiaLighting );
|
||||
|
||||
UInt8 ICalcVertexSize( UInt8 &liteStride );
|
||||
|
||||
UInt8* IVertBuffStorage(int iBuff, int iVtx) const { return fVertBuffStorage[iBuff] + iVtx*fStride; }
|
||||
|
||||
UInt32 IMakeCell( UInt32 vbIndex, UInt8 flags, UInt32 vStart, UInt32 cStart, UInt32 len, UInt32 *offset );
|
||||
void IGetStartVtxPointer( UInt32 vbIndex, UInt32 cell, UInt32 offset, UInt8 *&tempPtr, plGBufferColor *&cPtr );
|
||||
|
||||
public:
|
||||
|
||||
static const UInt32 kMaxNumVertsPerBuffer;
|
||||
static const UInt32 kMaxNumIndicesPerBuffer;
|
||||
|
||||
enum Formats
|
||||
{
|
||||
kUVCountMask = 0x0f, // Problem is, we need enough bits to store the max #, which means
|
||||
// we really want ( max # << 1 ) - 1
|
||||
|
||||
kSkinNoWeights = 0x00, // 0000000
|
||||
kSkin1Weight = 0x10, // 0010000
|
||||
kSkin2Weights = 0x20, // 0100000
|
||||
kSkin3Weights = 0x30, // 0110000
|
||||
kSkinWeightMask = 0x30, // 0110000
|
||||
|
||||
kSkinIndices = 0x40, // 1000000
|
||||
|
||||
kEncoded = 0x80
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
kReserveInterleaved = 0x01,
|
||||
kReserveVerts = 0x02,
|
||||
kReserveColors = 0x04,
|
||||
kReserveSeparated = 0x08,
|
||||
kReserveIsolate = 0x10
|
||||
};
|
||||
|
||||
plGBufferGroup(UInt8 format, hsBool vertsVolatile, hsBool idxVolatile, int LOD = 0);
|
||||
~plGBufferGroup();
|
||||
|
||||
UInt8 GetNumUVs( void ) const { return ( fFormat & kUVCountMask ); }
|
||||
UInt8 GetNumWeights() const { return (fFormat & kSkinWeightMask) >> 4; }
|
||||
|
||||
static UInt8 CalcNumUVs( UInt8 format ) { return ( format & kUVCountMask ); }
|
||||
static UInt8 UVCountToFormat( UInt8 numUVs ) { return numUVs & kUVCountMask; }
|
||||
|
||||
void DirtyVertexBuffer(int i);
|
||||
void DirtyIndexBuffer(int i);
|
||||
hsBool VertexReady(int i) const { return (i < fVertexBufferRefs.GetCount()) && fVertexBufferRefs[i]; }
|
||||
hsBool IndexReady(int i) const { return (i < fIndexBufferRefs.GetCount()) && fIndexBufferRefs[i]; }
|
||||
UInt8 GetVertexSize( void ) const { return fStride; }
|
||||
UInt8 GetVertexLiteStride( void ) const { return fLiteStride; }
|
||||
UInt8 GetVertexFormat( void ) const { return fFormat; }
|
||||
UInt32 GetMemUsage( void ) const { return ( fNumVerts * GetVertexSize() ) + ( fNumIndices * sizeof( UInt16 ) ); }
|
||||
UInt32 GetNumVerts( void ) const { return fNumVerts; }
|
||||
UInt32 GetNumIndices( void ) const { return fNumIndices; }
|
||||
UInt32 GetNumPrimaryVertsLeft( void ) const;
|
||||
UInt32 GetNumVertsLeft( UInt32 idx ) const;
|
||||
|
||||
UInt32 GetVertBufferSize(UInt32 idx) const { return fVertBuffSizes[idx]; }
|
||||
UInt32 GetVertBufferCount(UInt32 idx) const;
|
||||
UInt32 GetIndexBufferCount(UInt32 idx) const { return fIdxBuffCounts[idx]; }
|
||||
UInt32 GetVertStartFromCell(UInt32 idx, UInt32 cell, UInt32 offset) const;
|
||||
|
||||
// These should only be called by the pipeline, because only it knows when it's safe.
|
||||
// If the data is volatile, these are no-ops
|
||||
void PurgeVertBuffer(UInt32 idx);
|
||||
void PurgeIndexBuffer(UInt32 idx);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// The following group of functions is an advanced optimization, and a pretty
|
||||
// specialized one at that. It just limits the amount of data that will get
|
||||
// uploaded to video. If you don't know you are limited by bandwidth to the
|
||||
// board, or you just don't know what your are doing, don't mess with them.
|
||||
// If you never touch them, everything will work. If you set them correcly,
|
||||
// things may work faster. If you set them incorrectly, be sure to save
|
||||
// all files before running.
|
||||
// All of these are indices, not bytes. from the beginning of the buffer.
|
||||
UInt32 GetVertBufferStart(UInt32 idx) const { return fVertBuffStarts[idx]; }
|
||||
UInt32 GetVertBufferEnd(UInt32 idx) const { return fVertBuffEnds[idx] >= 0 ? UInt32(fVertBuffEnds[idx]) : GetVertBufferCount(idx); }
|
||||
UInt32 GetIndexBufferStart(UInt32 idx) const { return fIdxBuffStarts[idx]; }
|
||||
UInt32 GetIndexBufferEnd(UInt32 idx) const { return fIdxBuffEnds[idx] >= 0 ? UInt32(fIdxBuffEnds[idx]) : GetIndexBufferCount(idx); }
|
||||
|
||||
void SetVertBufferStart(UInt32 idx, UInt32 s) { fVertBuffStarts[idx] = s; }
|
||||
void SetVertBufferEnd(UInt32 idx, UInt32 e) { fVertBuffEnds[idx] = e; }
|
||||
void SetIndexBufferStart(UInt32 idx, UInt32 s) { fIdxBuffStarts[idx] = s; }
|
||||
void SetIndexBufferEnd(UInt32 idx, UInt32 e) { fIdxBuffEnds[idx] = e; }
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
UInt32 GetNumVertexBuffers( void ) const { return fVertBuffStorage.GetCount(); }
|
||||
UInt32 GetNumIndexBuffers( void ) const { return fIdxBuffStorage.GetCount(); }
|
||||
|
||||
UInt8 *GetVertBufferData( UInt32 idx ) { return fVertBuffStorage[ idx ]; }
|
||||
UInt16 *GetIndexBufferData( UInt32 idx ) { return fIdxBuffStorage[ idx ]; }
|
||||
plGBufferColor *GetColorBufferData( UInt32 idx ) { return fColorBuffStorage[ idx ]; }
|
||||
|
||||
hsGDeviceRef *GetVertexBufferRef( UInt32 i );
|
||||
hsGDeviceRef *GetIndexBufferRef( UInt32 i );
|
||||
|
||||
UInt32 GetNumCells( UInt32 idx ) const { return fCells[ idx ]->GetCount(); }
|
||||
plGBufferCell *GetCell( UInt32 idx, UInt32 cell ) { return &( (*fCells[ idx ])[ cell ] ); }
|
||||
|
||||
void SetVertexBufferRef( UInt32 index, hsGDeviceRef *vb );
|
||||
void SetIndexBufferRef( UInt32 index, hsGDeviceRef *ib );
|
||||
|
||||
virtual void Read( hsStream* s );
|
||||
virtual void Write( hsStream* s );
|
||||
|
||||
// Accessor functions
|
||||
hsPoint3 &Position( int iBuff, UInt32 cell, int iVtx );
|
||||
hsVector3 &Normal( int iBuff, UInt32 cell, int iVtx );
|
||||
UInt32 &Color( int iBuff, UInt32 cell, int iVtx );
|
||||
UInt32 &Specular( int iBuff, UInt32 cell, int iVtx );
|
||||
hsPoint3 &UV( int iBuff, UInt32 cell, int iVtx, int channel );
|
||||
UInt32 Format() const { return fFormat; }
|
||||
|
||||
// Take temp accumulators and actually build buffer data from them
|
||||
void TidyUp( void );
|
||||
|
||||
// Delete the buffer data storage
|
||||
void CleanUp( void );
|
||||
|
||||
// Take buffer data and convert it to device-specific buffers
|
||||
void PrepForRendering( plPipeline *pipe, hsBool adjustForNvidiaLighting );
|
||||
|
||||
// Reserves space in a vertex buffer
|
||||
hsBool ReserveVertStorage( UInt32 numVerts, UInt32 *vbIndex, UInt32 *cell, UInt32 *offset, UInt8 flags );
|
||||
|
||||
// Append vertex data to the first available storage buffer
|
||||
void AppendToVertStorage( plGeometrySpan *srcSpan, UInt32 *vbIndex, UInt32 *cell, UInt32 *offset );
|
||||
void AppendToVertAndColorStorage( plGeometrySpan *srcSpan, UInt32 *vbIndex, UInt32 *cell, UInt32 *offset );
|
||||
void AppendToColorStorage( plGeometrySpan *srcSpan, UInt32 *vbIndex, UInt32 *cell, UInt32 *offset, UInt32 origCell );
|
||||
|
||||
// Reserves space in an index buffer
|
||||
hsBool ReserveIndexStorage( UInt32 numIndices, UInt32 *ibIndex, UInt32 *ibStart, UInt16 **dataPtr = nil );
|
||||
|
||||
// Append index data to the first available storage buffer
|
||||
void AppendToIndexStorage( UInt32 numIndices, UInt16 *data, UInt32 addToAll, UInt32 *ibIndex, UInt32 *ibStart );
|
||||
|
||||
|
||||
/// Dynamic functions (addition/deletion of raw data)
|
||||
void DeleteVertsFromStorage( UInt32 which, UInt32 start, UInt32 length );
|
||||
void AdjustIndicesInStorage( UInt32 which, UInt16 threshhold, Int16 delta );
|
||||
void DeleteIndicesFromStorage( UInt32 which, UInt32 start, UInt32 length );
|
||||
|
||||
// Returns an array of plGBufferTriangles representing the span of indices specified
|
||||
plGBufferTriangle *ConvertToTriList( Int16 spanIndex, UInt32 whichIdx, UInt32 whichVtx, UInt32 whichCell, UInt32 start, UInt32 numTriangles );
|
||||
|
||||
// Stuffs the indices from an array of plGBufferTriangles into the index storage
|
||||
void StuffFromTriList( UInt32 which, UInt32 start, UInt32 numTriangles, UInt16 *data );
|
||||
void StuffTri( UInt32 iBuff, UInt32 iTri, UInt16 idx0, UInt16 idx1, UInt16 idx2 );
|
||||
|
||||
// Stuff the data from a geometry span into vertex storage
|
||||
void StuffToVertStorage( plGeometrySpan *srcSpan, UInt32 vbIndex, UInt32 cell, UInt32 offset, UInt8 flags );
|
||||
|
||||
// Are our verts volatile?
|
||||
hsBool AreVertsVolatile() const { return fVertsVolatile; }
|
||||
hsBool AreIdxVolatile() const { return fIdxVolatile; }
|
||||
|
||||
int GetLOD() const { return fLOD; }
|
||||
};
|
||||
|
||||
#endif // _plGBufferGroup_h
|
||||
|
@ -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/>.
|
||||
|
||||
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 plPipeDebugFlags_inc
|
||||
#define plPipeDebugFlags_inc
|
||||
|
||||
namespace plPipeDbg
|
||||
{
|
||||
// Debug flags
|
||||
enum DebugFlags
|
||||
{
|
||||
kFlagReload,
|
||||
kFlagShowAllBounds,
|
||||
kFlagNoMultitexture,
|
||||
kFlagNoLightmaps,
|
||||
kFlagNoRuntimeLights,
|
||||
kFlagOcclusionSnap,
|
||||
kFlagNoAlphaBlending,
|
||||
kFlagNoDecals,
|
||||
kFlagDontSortFaces,
|
||||
kFlagDisableSpecular,
|
||||
kFlagOverlayWire,
|
||||
kFlagShowNormals,
|
||||
kFlagColorizeMipmaps,
|
||||
kFlagSingleMat,
|
||||
kFlagSkipVisDist,
|
||||
kFlagNoPlates,
|
||||
kFlagNoShadows,
|
||||
kFlagNoUpperLayers,
|
||||
kFlagNoProjLights,
|
||||
kFlagNoSkinning,
|
||||
kFlagBumpUV,
|
||||
kFlagBumpW,
|
||||
kFlagNoBump,
|
||||
kFlagNoRender,
|
||||
kFlagNoAnisotropy,
|
||||
kFlagAllBright,
|
||||
kFlagNoApplyProjLights,
|
||||
kFlagOnlyApplyProjLights,
|
||||
kFlagShowShadowBounds,
|
||||
kFlagNoAuxSpans,
|
||||
kFlagNoShadowApply,
|
||||
kFlagNoPreShade,
|
||||
kFlagNVPerfHUD,
|
||||
kFlagNoFog,
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // plPipeDebugFlags_inc
|
@ -0,0 +1,66 @@
|
||||
/*==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/>.
|
||||
|
||||
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 plPipelineCreatable_inc
|
||||
#define plPipelineCreatable_inc
|
||||
|
||||
#include "../pnFactory/plCreator.h"
|
||||
|
||||
#include <d3d9.h>
|
||||
|
||||
#include "plDXPipeline.h"
|
||||
|
||||
REGISTER_NONCREATABLE( plDXPipeline );
|
||||
|
||||
#include "hsFogControl.h"
|
||||
|
||||
REGISTER_NONCREATABLE( hsFogControl );
|
||||
|
||||
#include "plFogEnvironment.h"
|
||||
|
||||
REGISTER_CREATABLE( plFogEnvironment );
|
||||
|
||||
#include "plRenderTarget.h"
|
||||
|
||||
REGISTER_CREATABLE( plRenderTarget );
|
||||
|
||||
#include "plCubicRenderTarget.h"
|
||||
|
||||
REGISTER_CREATABLE( plCubicRenderTarget );
|
||||
|
||||
#include "plCubicRenderTargetModifier.h"
|
||||
|
||||
REGISTER_CREATABLE( plCubicRenderTargetModifier );
|
||||
|
||||
#include "plTransitionMgr.h"
|
||||
|
||||
REGISTER_CREATABLE( plTransitionMgr );
|
||||
|
||||
#include "plDynamicEnvMap.h"
|
||||
REGISTER_CREATABLE( plDynamicEnvMap );
|
||||
REGISTER_CREATABLE( plDynamicCamMap );
|
||||
|
||||
#endif // plPipelineCreatable_inc
|
@ -0,0 +1,75 @@
|
||||
/*==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/>.
|
||||
|
||||
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==*/
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// plPipelineCreate Class Header //
|
||||
// Cyan, Inc. //
|
||||
// //
|
||||
// Here's a fun static class. All it does is contain wrapper functions for //
|
||||
// returning pointers to new pipelines of various types. This way, someone //
|
||||
// else, say, plClient, can create a new plDXPipeline without having to //
|
||||
// include every DX header in the known universe. Its messy and there's //
|
||||
// probably a better way to do it with the resource manager, but neither //
|
||||
// Chris nor Matt can tell me what it is, so there. :P //
|
||||
// //
|
||||
// Note: complile-time trick is that the actual functions for these are //
|
||||
// in the pipeline sources themselves. Makes more sense, esp. since we //
|
||||
// then avoid any possible header conflict between the pipelines, should //
|
||||
// one ever exist. //
|
||||
// //
|
||||
//// Version History //////////////////////////////////////////////////////////
|
||||
// //
|
||||
// 3.8.2001 mcn - Created. //
|
||||
// //
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef _plPipelineCreate_h
|
||||
#define _plPipelineCreate_h
|
||||
|
||||
|
||||
//// plPipelineCreate Class Definition ////////////////////////////////////////
|
||||
|
||||
class plPipeline;
|
||||
|
||||
class plPipelineCreate
|
||||
{
|
||||
protected:
|
||||
|
||||
static plPipeline *ICreateDXPipeline( hsWinRef hWnd, const hsG3DDeviceModeRecord *devMode );
|
||||
|
||||
public:
|
||||
|
||||
static plPipeline *CreatePipeline( hsWinRef hWnd, const hsG3DDeviceModeRecord *devMode )
|
||||
{
|
||||
// Just this for now. Later we'll key off of the devMode
|
||||
return ICreateDXPipeline( hWnd, devMode );
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif // _plPipelineCreate_h
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,236 @@
|
||||
/*==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/>.
|
||||
|
||||
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==*/
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// plPlates - Header file for the plates and plPlateManager //
|
||||
// //
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef _plPlates_h
|
||||
#define _plPlates_h
|
||||
|
||||
#include "hsTypes.h"
|
||||
#include "hsStlUtils.h"
|
||||
#include "hsColorRGBA.h"
|
||||
#include "hsTemplates.h"
|
||||
#include "hsUtils.h"
|
||||
#include "hsMatrix44.h"
|
||||
|
||||
|
||||
|
||||
//// plPlate Class Definition ////////////////////////////////////////////////
|
||||
// plPlate is the actual plate object that represents one plate on the
|
||||
// screen. It has a transform matrix (which includes position, scale and
|
||||
// rotation), a material, a depth value and a color that is applied to all
|
||||
// four corners. All plates are parallelograms.
|
||||
|
||||
class plPlateManager;
|
||||
class hsGMaterial;
|
||||
class plMipmap;
|
||||
class plBitmap;
|
||||
|
||||
class plPlate
|
||||
{
|
||||
friend class plPlateManager;
|
||||
|
||||
protected:
|
||||
|
||||
hsMatrix44 fXformMatrix;
|
||||
hsGMaterial *fMaterial;
|
||||
plMipmap *fMipmap;
|
||||
hsScalar fDepth, fOpacity;
|
||||
UInt32 fFlags;
|
||||
char fTitle[ 64 ];
|
||||
|
||||
plPlate *fNext;
|
||||
plPlate **fPrevPtr;
|
||||
|
||||
plPlate **fOwningHandle;
|
||||
|
||||
static UInt32 fMagicUniqueKeyInt;
|
||||
|
||||
plPlate( plPlate** owningHandle );
|
||||
virtual ~plPlate();
|
||||
|
||||
void ILink( plPlate **back );
|
||||
|
||||
void IUnlink( void )
|
||||
{
|
||||
hsAssert( fPrevPtr, "Plate not in list" );
|
||||
if( fNext )
|
||||
fNext->fPrevPtr = fPrevPtr;
|
||||
*fPrevPtr = fNext;
|
||||
|
||||
fNext = nil;
|
||||
fPrevPtr = nil;
|
||||
}
|
||||
|
||||
void ISetResourceAlphas(UInt32 colorKey);
|
||||
|
||||
public:
|
||||
|
||||
enum
|
||||
{
|
||||
kFlagVisible = 0x00000001,
|
||||
kFlagLocalMaterial = 0x00000002,
|
||||
kFlagIsAGraph = 0x00000004
|
||||
};
|
||||
|
||||
/// Basic properties
|
||||
|
||||
void SetTransform( hsMatrix44 &matrix, hsBool reSort = true );
|
||||
void SetMaterial( hsGMaterial *material );
|
||||
void SetTexture(plBitmap *texture); // Creates a new single layer material to use the texture.
|
||||
void SetTitle( const char *title ) { if( title != nil ) strncpy( fTitle, title, sizeof( fTitle ) ); else fTitle[ 0 ] = 0; }
|
||||
|
||||
hsGMaterial *GetMaterial( void ) { return fMaterial; }
|
||||
hsMatrix44 &GetTransform( void ) { return fXformMatrix; }
|
||||
const char *GetTitle( void ) { return fTitle; }
|
||||
UInt32 GetFlags( void ) { return fFlags; }
|
||||
|
||||
void SetVisible( hsBool vis ) { if( vis ) fFlags |= kFlagVisible; else fFlags &= ~kFlagVisible; }
|
||||
hsBool IsVisible( void );
|
||||
|
||||
void SetOpacity( hsScalar opacity = 1.f );
|
||||
|
||||
plPlate *GetNext( void ) { return fNext; }
|
||||
|
||||
|
||||
/// Helper functions
|
||||
|
||||
void SetDepth( hsScalar depth) { fDepth = depth; }
|
||||
void SetPosition( hsScalar x, hsScalar y, hsScalar z = -1.0f );
|
||||
void SetSize( hsScalar width, hsScalar height, bool adjustByAspectRatio = false );
|
||||
|
||||
plMipmap *CreateMaterial( UInt32 width, UInt32 height, hsBool withAlpha, plMipmap* texture = NULL );
|
||||
void CreateFromResource( const char *resName, UInt32 colorKey = 0x00ff00ff );
|
||||
void ReloadFromResource( const char *resName, UInt32 colorKey = 0x00ff00ff );
|
||||
void CreateFromJPEGResource( const char *resName, UInt32 colorKey = 0x00ff00ff );
|
||||
void ReloadFromJPEGResource( const char *resName, UInt32 colorKey = 0x00ff00ff );
|
||||
};
|
||||
|
||||
//// plGraphPlate Class Definition ///////////////////////////////////////////
|
||||
// A derivation of plPlate that maintains a procedural texture which displays
|
||||
// a scrolling graph of data.
|
||||
|
||||
class plGraphPlate : public plPlate
|
||||
{
|
||||
protected:
|
||||
UInt32 fBGHexColor, fAxesHexColor, fGraphHexColor;
|
||||
std::vector<UInt32> fDataHexColors;
|
||||
UInt32 fMin, fMax, fLabelMin, fLabelMax;
|
||||
std::vector<Int32> fLastValues;
|
||||
std::vector<std::string> fLabelText;
|
||||
|
||||
UInt32 IMakePow2( UInt32 value );
|
||||
void IDrawNumber( UInt32 number, UInt32 *dataPtr, UInt32 stride, UInt32 color );
|
||||
void IDrawDigit( char digit, UInt32 *dataPtr, UInt32 stride, UInt32 color );
|
||||
|
||||
public:
|
||||
plGraphPlate( plPlate **owningHandle );
|
||||
virtual ~plGraphPlate();
|
||||
|
||||
void SetDataRange( UInt32 min, UInt32 max, UInt32 width );
|
||||
void SetDataLabels( UInt32 min, UInt32 max );
|
||||
void SetLabelText( char *text1, char *text2 = nil, char *text3 = nil, char *text4 = nil );
|
||||
void SetLabelText( const std::vector<std::string> & text );
|
||||
void ClearData( void );
|
||||
|
||||
void AddData( Int32 value, Int32 value2 = -1, Int32 value3 = -1, Int32 value4 = -1 );
|
||||
void AddData( std::vector<Int32> values );
|
||||
|
||||
void SetColors( UInt32 bgHexColor = 0x80000000, UInt32 axesHexColor = 0xffffffff, UInt32 dataHexColor = 0xff00ff00, UInt32 graphHexColor = 0x80ff0000 );
|
||||
void SetDataColors( UInt32 hexColor1 = 0xff00ff00, UInt32 hexColor2 = 0xff0000ff, UInt32 hexColor3 = 0xffffff00, UInt32 hexColor4 = 0xffff00ff );
|
||||
void SetDataColors( const std::vector<UInt32> & hexColors );
|
||||
|
||||
const char *GetLabelText( int i ) { return fLabelText[ i ].c_str(); }
|
||||
const UInt32 GetDataColor( int i ) { return fDataHexColors[ i ]; }
|
||||
const UInt32 GetNumLabels() { return fLabelText.size(); }
|
||||
const UInt32 GetNumColors() { return fDataHexColors.size(); }
|
||||
};
|
||||
|
||||
//// plPlateManager Class Definition /////////////////////////////////////////
|
||||
// This class handles all the plates--it keeps track of all the plates,
|
||||
// creates and destroys them, and draws them when the pipeline tells it to.
|
||||
|
||||
class plPipeline;
|
||||
|
||||
class plPlateManager
|
||||
{
|
||||
friend class plPlate;
|
||||
|
||||
private:
|
||||
|
||||
static plPlateManager *fInstance;
|
||||
|
||||
protected:
|
||||
|
||||
plPlate *fPlates;
|
||||
plPipeline *fOwner;
|
||||
hsBool fCreatedSucessfully;
|
||||
|
||||
plPlateManager( plPipeline *pipe )
|
||||
{
|
||||
fInstance = this;
|
||||
fPlates = nil;
|
||||
fOwner = pipe;
|
||||
fCreatedSucessfully = true;
|
||||
}
|
||||
|
||||
virtual void IDrawToDevice( plPipeline *pipe ) = 0;
|
||||
|
||||
void IResortPlate( plPlate *plate, bool fromCurrent );
|
||||
|
||||
public:
|
||||
|
||||
virtual ~plPlateManager();
|
||||
|
||||
static plPlateManager &Instance( void ) { return *fInstance; }
|
||||
static bool InstanceValid( void ) { return fInstance != nil; }
|
||||
|
||||
void CreatePlate( plPlate **handle );
|
||||
void CreatePlate( plPlate **handle, hsScalar width, hsScalar height );
|
||||
void CreatePlate( plPlate **handle, hsScalar x, hsScalar y, hsScalar width, hsScalar height );
|
||||
|
||||
void CreateGraphPlate( plGraphPlate **handle );
|
||||
|
||||
void DestroyPlate( plPlate *plate );
|
||||
|
||||
void SetPlateScreenPos( plPlate *plate, UInt32 x, UInt32 y );
|
||||
void SetPlatePixelSize( plPlate *plate, UInt32 pWidth, UInt32 pHeight );
|
||||
|
||||
UInt32 GetPipeWidth( void );
|
||||
UInt32 GetPipeHeight( void );
|
||||
void DrawToDevice( plPipeline *pipe );
|
||||
|
||||
hsBool IsValid( void ) { return fCreatedSucessfully; }
|
||||
};
|
||||
|
||||
// Sets the hInstance that we load our resources from. A SceneViewer hack.
|
||||
void SetHInstance(void *instance);
|
||||
|
||||
#endif //_plPlates_h
|
||||
|
@ -0,0 +1,189 @@
|
||||
/*==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/>.
|
||||
|
||||
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==*/
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// plRenderTarget.cpp - RenderTarget functions //
|
||||
// Cyan, Inc. //
|
||||
// //
|
||||
//// Version History //////////////////////////////////////////////////////////
|
||||
// //
|
||||
// 7.19.2001 mcn - Created. //
|
||||
// //
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "hsTypes.h"
|
||||
#include "plRenderTarget.h"
|
||||
#include "plCubicRenderTarget.h"
|
||||
#include "hsStream.h"
|
||||
#include "hsGDeviceRef.h"
|
||||
|
||||
#include "plPipeline.h"
|
||||
#include "plgDispatch.h"
|
||||
#include "../pnMessage/plPipeResMakeMsg.h"
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//// plRenderTarget Functions /////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void plRenderTarget::SetKey(plKey k)
|
||||
{
|
||||
hsKeyedObject::SetKey(k);
|
||||
if( k )
|
||||
{
|
||||
if( !fParent )
|
||||
plgDispatch::Dispatch()->RegisterForExactType( plPipeRTMakeMsg::Index(), GetKey() );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
hsBool plRenderTarget::MsgReceive(plMessage* msg)
|
||||
{
|
||||
plPipeRTMakeMsg* make = plPipeRTMakeMsg::ConvertNoRef(msg);
|
||||
if( make )
|
||||
{
|
||||
if( !GetDeviceRef() || GetDeviceRef()->IsDirty() )
|
||||
{
|
||||
make->Pipeline()->MakeRenderTargetRef(this);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return plBitmap::MsgReceive(msg);
|
||||
}
|
||||
|
||||
UInt32 plRenderTarget::Read( hsStream *s )
|
||||
{
|
||||
UInt32 total = plBitmap::Read( s );
|
||||
|
||||
fWidth = s->ReadSwap16();
|
||||
fHeight = s->ReadSwap16();
|
||||
|
||||
fProportionalViewport = s->ReadBool();
|
||||
if( fProportionalViewport )
|
||||
{
|
||||
fViewport.fProportional.fLeft = s->ReadSwapScalar();
|
||||
fViewport.fProportional.fTop = s->ReadSwapScalar();
|
||||
fViewport.fProportional.fRight = s->ReadSwapScalar();
|
||||
fViewport.fProportional.fBottom = s->ReadSwapScalar();
|
||||
}
|
||||
else
|
||||
{
|
||||
fViewport.fAbsolute.fLeft = s->ReadSwap16();
|
||||
fViewport.fAbsolute.fTop = s->ReadSwap16();
|
||||
fViewport.fAbsolute.fRight = s->ReadSwap16();
|
||||
fViewport.fAbsolute.fBottom = s->ReadSwap16();
|
||||
}
|
||||
|
||||
fZDepth = s->ReadByte();
|
||||
fStencilDepth = s->ReadByte();
|
||||
|
||||
return total + 2 * 2 + 2 + 4 * ( fProportionalViewport ? sizeof( hsScalar ) : sizeof( UInt16 ) ) + sizeof( hsBool );
|
||||
}
|
||||
|
||||
UInt32 plRenderTarget::Write( hsStream *s )
|
||||
{
|
||||
UInt32 total = plBitmap::Write( s );
|
||||
|
||||
s->WriteSwap16( fWidth );
|
||||
s->WriteSwap16( fHeight );
|
||||
|
||||
s->WriteBool( fProportionalViewport );
|
||||
if( fProportionalViewport )
|
||||
{
|
||||
s->WriteSwapScalar( fViewport.fProportional.fLeft );
|
||||
s->WriteSwapScalar( fViewport.fProportional.fTop );
|
||||
s->WriteSwapScalar( fViewport.fProportional.fRight );
|
||||
s->WriteSwapScalar( fViewport.fProportional.fBottom );
|
||||
}
|
||||
else
|
||||
{
|
||||
s->WriteSwap16( fViewport.fAbsolute.fLeft );
|
||||
s->WriteSwap16( fViewport.fAbsolute.fTop );
|
||||
s->WriteSwap16( fViewport.fAbsolute.fRight );
|
||||
s->WriteSwap16( fViewport.fAbsolute.fBottom );
|
||||
}
|
||||
|
||||
s->WriteByte( fZDepth );
|
||||
s->WriteByte( fStencilDepth );
|
||||
|
||||
return total + 2 * 2 + 2 + 4 * ( fProportionalViewport ? sizeof( hsScalar ) : sizeof( UInt16 ) ) + sizeof( hsBool );
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//// plCubicRenderTarget Functions ////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
UInt32 plCubicRenderTarget::Read( hsStream *s )
|
||||
{
|
||||
int i;
|
||||
UInt32 total = plRenderTarget::Read( s );
|
||||
|
||||
|
||||
for( i = 0; i < 6; i++ )
|
||||
{
|
||||
if( fFaces[ i ] == nil )
|
||||
fFaces[ i ] = TRACKED_NEW plRenderTarget();
|
||||
|
||||
fFaces[ i ]->fParent = this;
|
||||
total += fFaces[ i ]->Read( s );
|
||||
}
|
||||
|
||||
return total;
|
||||
}
|
||||
|
||||
UInt32 plCubicRenderTarget::Write( hsStream *s )
|
||||
{
|
||||
int i;
|
||||
UInt32 total = plRenderTarget::Write( s );
|
||||
|
||||
|
||||
for( i = 0; i < 6; i++ )
|
||||
{
|
||||
total += fFaces[ i ]->Write( s );
|
||||
}
|
||||
|
||||
return total;
|
||||
}
|
||||
|
||||
UInt32 plCubicRenderTarget::GetTotalSize( void ) const
|
||||
{
|
||||
UInt32 size = 0, i;
|
||||
|
||||
for( i = 0; i < 6; i++ )
|
||||
{
|
||||
if( fFaces[ i ] != nil )
|
||||
size += fFaces[ i ]->GetTotalSize();
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
//// SetCameraMatrix //////////////////////////////////////////////////////////
|
||||
|
||||
void plCubicRenderTarget::SetCameraMatrix(const hsPoint3& pos)
|
||||
{
|
||||
hsMatrix44::MakeEnvMapMatrices(pos, fWorldToCameras, fCameraToWorlds);
|
||||
}
|
@ -0,0 +1,189 @@
|
||||
/*==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/>.
|
||||
|
||||
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==*/
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// plRenderTarget.h - Header file for the plRenderTarget class //
|
||||
// Cyan, Inc. //
|
||||
// //
|
||||
//// Version History //////////////////////////////////////////////////////////
|
||||
// //
|
||||
// 5.21.2001 mcn - Created. //
|
||||
// //
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef _plRenderTarget_h
|
||||
#define _plRenderTarget_h
|
||||
|
||||
#include "plPipeResReq.h"
|
||||
|
||||
#include "../plGImage/plBitmap.h"
|
||||
|
||||
#define ASSERT_ABSOLUTE hsAssert( !fProportionalViewport, "Cannot perform this on a proportional RenderTarget" );
|
||||
#define ASSERT_PROPORTIONAL hsAssert( fProportionalViewport, "Cannot perform this on an absolute RenderTarget" );
|
||||
|
||||
//// Class Definition /////////////////////////////////////////////////////////
|
||||
|
||||
class hsGDeviceRef;
|
||||
class plCubicRenderTarget;
|
||||
|
||||
class plRenderTarget : public plBitmap
|
||||
{
|
||||
friend plCubicRenderTarget;
|
||||
|
||||
protected:
|
||||
|
||||
UInt16 fWidth, fHeight;
|
||||
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
UInt16 fLeft, fTop, fRight, fBottom;
|
||||
} fAbsolute;
|
||||
struct
|
||||
{
|
||||
hsScalar fLeft, fTop, fRight, fBottom;
|
||||
} fProportional;
|
||||
} fViewport;
|
||||
|
||||
hsBool fApplyTexQuality;
|
||||
hsBool fProportionalViewport;
|
||||
UInt8 fZDepth, fStencilDepth;
|
||||
|
||||
plCubicRenderTarget *fParent;
|
||||
|
||||
virtual void SetKey(plKey k);
|
||||
|
||||
virtual UInt32 Read( hsStream *s );
|
||||
virtual UInt32 Write( hsStream *s );
|
||||
public:
|
||||
|
||||
CLASSNAME_REGISTER( plRenderTarget );
|
||||
GETINTERFACE_ANY( plRenderTarget, plBitmap );
|
||||
|
||||
plRenderTarget()
|
||||
{
|
||||
fWidth = 0;
|
||||
fHeight = 0;
|
||||
fPixelSize = 0;
|
||||
fZDepth = 0;
|
||||
fStencilDepth = 0;
|
||||
fApplyTexQuality = false;
|
||||
fProportionalViewport = true;
|
||||
SetViewport( 0, 0, 1.f, 1.f );
|
||||
fFlags = 0;
|
||||
fParent = nil;
|
||||
|
||||
plPipeResReq::Request();
|
||||
}
|
||||
|
||||
plRenderTarget( UInt16 flags, UInt16 width, UInt16 height, UInt8 bitDepth, UInt8 zDepth = 0xff, UInt8 stencilDepth = 0xff )
|
||||
{
|
||||
fWidth = width;
|
||||
fHeight = height;
|
||||
fPixelSize = bitDepth;
|
||||
fZDepth = ( zDepth != 0xff ) ? zDepth : (bitDepth > 16 ? 24 : 16);
|
||||
fStencilDepth = ( stencilDepth != 0xff ) ? stencilDepth : 0;
|
||||
|
||||
fFlags = flags;
|
||||
fParent = nil;
|
||||
|
||||
hsAssert( fFlags & (kIsTexture|kIsOffscreen), "Cannot perform this on an on-screen RenderTarget" );
|
||||
fApplyTexQuality = false;
|
||||
fProportionalViewport = false;
|
||||
SetViewport( 0, 0, width, height );
|
||||
|
||||
plPipeResReq::Request();
|
||||
}
|
||||
|
||||
// Render-to-Screen constructor
|
||||
plRenderTarget( UInt16 flags, hsScalar left, hsScalar top, hsScalar right, hsScalar bottom, UInt8 bitDepth, UInt8 zDepth = 0xff, UInt8 stencilDepth = 0xff )
|
||||
{
|
||||
fWidth = 0; // Can't really set these, at least not yet
|
||||
fHeight = 0;
|
||||
fPixelSize = bitDepth;
|
||||
fZDepth = ( zDepth != 0xff ) ? zDepth : 16;
|
||||
fStencilDepth = ( stencilDepth != 0xff ) ? stencilDepth : 0;
|
||||
|
||||
fFlags = flags;
|
||||
fParent = nil;
|
||||
|
||||
hsAssert( !( fFlags & (kIsTexture|kIsOffscreen) ), "Cannot perform this on an offscreen RenderTarget" );
|
||||
fApplyTexQuality = false;
|
||||
fProportionalViewport = true;
|
||||
SetViewport( left, top, right, bottom );
|
||||
|
||||
plPipeResReq::Request();
|
||||
}
|
||||
|
||||
virtual ~plRenderTarget() {}
|
||||
|
||||
virtual void SetViewport( UInt16 left, UInt16 top, UInt16 right, UInt16 bottom )
|
||||
{
|
||||
ASSERT_ABSOLUTE;
|
||||
fViewport.fAbsolute.fLeft = left;
|
||||
fViewport.fAbsolute.fTop = top;
|
||||
fViewport.fAbsolute.fRight = right;
|
||||
fViewport.fAbsolute.fBottom = bottom;
|
||||
}
|
||||
|
||||
virtual void SetViewport( hsScalar left, hsScalar top, hsScalar right, hsScalar bottom )
|
||||
{
|
||||
ASSERT_PROPORTIONAL;
|
||||
fViewport.fProportional.fLeft = left;
|
||||
fViewport.fProportional.fTop = top;
|
||||
fViewport.fProportional.fRight = right;
|
||||
fViewport.fProportional.fBottom = bottom;
|
||||
}
|
||||
|
||||
UInt16 GetWidth( void ) { return fWidth; }
|
||||
UInt16 GetHeight( void ) { return fHeight; }
|
||||
UInt8 GetZDepth( void ) { return fZDepth; }
|
||||
UInt8 GetStencilDepth( void ) { return fStencilDepth; }
|
||||
|
||||
UInt16 GetVPLeft( void ) { ASSERT_ABSOLUTE; return fViewport.fAbsolute.fLeft; }
|
||||
UInt16 GetVPTop( void ) { ASSERT_ABSOLUTE; return fViewport.fAbsolute.fTop; }
|
||||
UInt16 GetVPRight( void ) { ASSERT_ABSOLUTE; return fViewport.fAbsolute.fRight; }
|
||||
UInt16 GetVPBottom( void ) { ASSERT_ABSOLUTE; return fViewport.fAbsolute.fBottom; }
|
||||
|
||||
hsScalar GetVPLeftProp( void ) { ASSERT_PROPORTIONAL; return fViewport.fProportional.fLeft; }
|
||||
hsScalar GetVPTopProp( void ) { ASSERT_PROPORTIONAL; return fViewport.fProportional.fTop; }
|
||||
hsScalar GetVPRightProp( void ) { ASSERT_PROPORTIONAL; return fViewport.fProportional.fRight; }
|
||||
hsScalar GetVPBottomProp( void ) { ASSERT_PROPORTIONAL; return fViewport.fProportional.fBottom; }
|
||||
|
||||
hsBool ViewIsProportional( void ) const { return fProportionalViewport; }
|
||||
|
||||
plCubicRenderTarget *GetParent( void ) const { return fParent; }
|
||||
|
||||
virtual UInt32 GetTotalSize( void ) const { return fWidth * fHeight * ( fPixelSize >> 3 ); }
|
||||
|
||||
virtual hsBool MsgReceive(plMessage* msg);
|
||||
|
||||
virtual void SetVisRegionName(char *name){} // override to set vis region names for anyone who cares
|
||||
};
|
||||
|
||||
|
||||
#endif // _plRenderTarget_h
|
@ -0,0 +1,112 @@
|
||||
/*==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/>.
|
||||
|
||||
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==*/
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// plStatusLogDrawer class //
|
||||
// //
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "hsTypes.h"
|
||||
#include "plStatusLogDrawer.h"
|
||||
#include "plPipeline.h"
|
||||
#include "plDebugText.h"
|
||||
#include "../plStatusLog/plStatusLog.h"
|
||||
|
||||
//// Draw ////////////////////////////////////////////////////////////////////
|
||||
|
||||
void plStatusLogDrawer::IDrawLogNames(plStatusLog* curLog, plStatusLog* firstLog)
|
||||
{
|
||||
plDebugText& drawText = plDebugText::Instance();
|
||||
|
||||
UInt32 width = 0, numLogs = 0;
|
||||
|
||||
plStatusLog* iLog = firstLog;
|
||||
while (iLog)
|
||||
{
|
||||
width = hsMaximum(drawText.CalcStringWidth(iLog->GetFileName()) + 4, width);
|
||||
iLog = iLog->fNext;
|
||||
numLogs++;
|
||||
}
|
||||
|
||||
UInt32 height = drawText.GetFontHeight() + 2;
|
||||
drawText.DrawRect(0, 0, (UInt16)width, (UInt16)(height*numLogs), 0, 0, 0);
|
||||
|
||||
UInt32 yPos = 0;
|
||||
iLog = firstLog;
|
||||
while (iLog)
|
||||
{
|
||||
if (iLog == curLog)
|
||||
drawText.DrawString(2, (UInt16)yPos, iLog->GetFileName(), 0, 255, 0);
|
||||
else
|
||||
drawText.DrawString(2, (UInt16)yPos, iLog->GetFileName());
|
||||
|
||||
iLog = iLog->fNext;
|
||||
yPos += height;
|
||||
}
|
||||
}
|
||||
|
||||
void plStatusLogDrawer::Draw(plStatusLog* curLog, plStatusLog* firstLog)
|
||||
{
|
||||
int i, x, y, width, height, lineHt;
|
||||
plDebugText &drawText = plDebugText::Instance();
|
||||
|
||||
|
||||
/// Calc position on screen
|
||||
lineHt = drawText.GetFontHeight() + 2;
|
||||
height = lineHt * ( IGetMaxNumLines( curLog ) + 2 ) + 8;
|
||||
if( IGetFlags( curLog ) & plStatusLog::kAlignToTop )
|
||||
{
|
||||
width = fPipeline->Width() - 8;
|
||||
x = 4;
|
||||
y = 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
width = fPipeline->Width() >> 1;
|
||||
x = width - 10;
|
||||
y = ( fPipeline->Height() - height ) >> 1;
|
||||
}
|
||||
|
||||
/// Draw!
|
||||
if( IGetFlags( curLog ) & plStatusLog::kFilledBackground )
|
||||
drawText.DrawRect( x, y, x + width, y + height, 0, 0, 0, 127 );
|
||||
|
||||
drawText.DrawString( x + 2, y + ( lineHt >> 1 ), IGetFilename( curLog ), 127, 127, 255, 255, plDebugText::kStyleBold );
|
||||
drawText.DrawRect( x + 2, y + ( lineHt << 1 ) + 1,
|
||||
x + width - 8, y + ( lineHt << 1 ) + 2, 127, 127, 255, 255 );
|
||||
|
||||
y += lineHt * 2;
|
||||
for( i = 0; i < IGetMaxNumLines( curLog ); i++ )
|
||||
{
|
||||
if( IGetLines( curLog )[ i ] != nil )
|
||||
drawText.DrawString( x + 4, y, IGetLines( curLog )[ i ], IGetColors( curLog )[ i ] );
|
||||
y += lineHt;
|
||||
}
|
||||
|
||||
if (firstLog)
|
||||
IDrawLogNames(curLog, firstLog);
|
||||
}
|
||||
|
@ -0,0 +1,58 @@
|
||||
/*==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/>.
|
||||
|
||||
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==*/
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// plStatusLogDrawer class //
|
||||
// //
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef _plStatusLogDrawer_h
|
||||
#define _plStatusLogDrawer_h
|
||||
|
||||
#include "../plStatusLog/plStatusLog.h"
|
||||
|
||||
|
||||
//// plStatusLogDrawer Class Definition ////////////////////////////////////////////
|
||||
|
||||
class plPipeline;
|
||||
class plStatusLogDrawer : public plStatusLogDrawerStub
|
||||
{
|
||||
protected:
|
||||
plPipeline *fPipeline;
|
||||
|
||||
void IDrawLogNames(plStatusLog* curLog, plStatusLog* firstLog);
|
||||
|
||||
public:
|
||||
|
||||
plStatusLogDrawer( plPipeline *pipe ) : fPipeline( pipe ) {}
|
||||
virtual ~plStatusLogDrawer() {}
|
||||
|
||||
virtual void Draw(plStatusLog* curLog, plStatusLog* firstLog);
|
||||
};
|
||||
|
||||
|
||||
#endif //_plStatusLogDrawer_h
|
||||
|
@ -0,0 +1,87 @@
|
||||
/*==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/>.
|
||||
|
||||
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==*/
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// plStencil.h - Header for various stencil settings and enums //
|
||||
// Cyan, Inc. //
|
||||
// //
|
||||
//// Version History //////////////////////////////////////////////////////////
|
||||
// //
|
||||
// 5.17.2001 mcn - Created. //
|
||||
// //
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef _plStencil_h
|
||||
#define _plStencil_h
|
||||
|
||||
#include "hsTypes.h"
|
||||
|
||||
|
||||
//// Stencil Caps /////////////////////////////////////////////////////////////
|
||||
|
||||
class plStencilCaps
|
||||
{
|
||||
public:
|
||||
|
||||
enum Depths
|
||||
{
|
||||
kDepth1Bit = 0x01,
|
||||
kDepth4Bits = 0x02,
|
||||
kDepth8Bits = 0x04
|
||||
};
|
||||
|
||||
enum CompareFuncs
|
||||
{
|
||||
kCmpNever = 0,
|
||||
kCmpLessThan,
|
||||
kCmpEqual,
|
||||
kCmpLessThanOrEqual,
|
||||
kCmpGreaterThan,
|
||||
kCmpNotEqual,
|
||||
kCmpGreaterThanOrEqual,
|
||||
kCmpAlways
|
||||
|
||||
};
|
||||
|
||||
enum Ops
|
||||
{
|
||||
kOpKeep = 0x01,
|
||||
kOpSetToZero = 0x02,
|
||||
kOpReplace = 0x04,
|
||||
kOpIncClamp = 0x08,
|
||||
kOpDecClamp = 0x10,
|
||||
kOpInvert = 0x20,
|
||||
kOpIncWrap = 0x40,
|
||||
kOpDecWrap = 0x80
|
||||
|
||||
};
|
||||
|
||||
hsBool fIsSupported;
|
||||
UInt8 fSupportedDepths;
|
||||
UInt8 fSupportedOps;
|
||||
};
|
||||
|
||||
#endif // _plStencil_h
|
@ -0,0 +1,431 @@
|
||||
/*==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/>.
|
||||
|
||||
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==*/
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// plTextFont Class Functions //
|
||||
// Cyan, Inc. //
|
||||
// //
|
||||
//// Version History //////////////////////////////////////////////////////////
|
||||
// //
|
||||
// 2.19.2001 mcn - Created. //
|
||||
// //
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "hsWindows.h"
|
||||
#include "HeadSpin.h"
|
||||
#include "plTextFont.h"
|
||||
#include "plDebugText.h"
|
||||
|
||||
#define DisplayableChar(c) (c >= 0 && c <= 128)
|
||||
|
||||
//// Constructor & Destructor /////////////////////////////////////////////////
|
||||
|
||||
plTextFont::plTextFont( plPipeline *pipe )
|
||||
{
|
||||
fMaxNumIndices = 1024;
|
||||
fInitialized = false;
|
||||
fPipe = pipe;
|
||||
}
|
||||
|
||||
plTextFont::~plTextFont()
|
||||
{
|
||||
IUnlink();
|
||||
}
|
||||
|
||||
//// IInitFontTexture /////////////////////////////////////////////////////////
|
||||
|
||||
UInt16 *plTextFont::IInitFontTexture( void )
|
||||
{
|
||||
int nHeight, x, y, c;
|
||||
char myChar[ 2 ] = "x";
|
||||
UInt16 *tBits;
|
||||
|
||||
DWORD *bitmapBits;
|
||||
BITMAPINFO bmi;
|
||||
HDC hDC;
|
||||
HBITMAP hBitmap;
|
||||
HFONT hFont;
|
||||
SIZE size;
|
||||
BYTE bAlpha;
|
||||
|
||||
|
||||
// Figure out our texture size
|
||||
if( fSize > 40 )
|
||||
fTextureWidth = fTextureHeight = 1024;
|
||||
else if( fSize > 20 )
|
||||
fTextureWidth = fTextureHeight = 512;
|
||||
else
|
||||
fTextureWidth = fTextureHeight = 256;
|
||||
|
||||
|
||||
// Create a new DC and bitmap that we can draw characters to
|
||||
memset( &bmi.bmiHeader, 0, sizeof( BITMAPINFOHEADER ) );
|
||||
bmi.bmiHeader.biSize = sizeof( BITMAPINFOHEADER );
|
||||
bmi.bmiHeader.biWidth = fTextureWidth;
|
||||
bmi.bmiHeader.biHeight = -(int)fTextureHeight;
|
||||
bmi.bmiHeader.biPlanes = 1;
|
||||
bmi.bmiHeader.biCompression = BI_RGB;
|
||||
bmi.bmiHeader.biBitCount = 32;
|
||||
|
||||
hDC = CreateCompatibleDC( nil );
|
||||
hBitmap = CreateDIBSection( hDC, &bmi, DIB_RGB_COLORS, (void **)&bitmapBits, nil, 0 );
|
||||
SetMapMode( hDC, MM_TEXT );
|
||||
|
||||
nHeight = -MulDiv( fSize, GetDeviceCaps( hDC, LOGPIXELSY ), 72 );
|
||||
fFontHeight = -nHeight;
|
||||
|
||||
hFont = CreateFont( nHeight, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS,
|
||||
CLIP_DEFAULT_PRECIS, ANTIALIASED_QUALITY, VARIABLE_PITCH, fFace );
|
||||
hsAssert( hFont != nil, "Cannot create Windows font" );
|
||||
|
||||
SelectObject( hDC, hBitmap );
|
||||
SelectObject( hDC, hFont );
|
||||
|
||||
// Set text colors
|
||||
SetTextColor( hDC, RGB( 255, 255, 255 ) );
|
||||
SetBkColor( hDC, 0 );
|
||||
SetTextAlign( hDC, TA_TOP );
|
||||
|
||||
// Loop through characters, drawing them one at a time
|
||||
RECT r;
|
||||
r.left = r.top = 0;
|
||||
r.right = r.bottom = 10;
|
||||
FillRect( hDC, &r, (HBRUSH)GetStockObject( GRAY_BRUSH ) );
|
||||
|
||||
// (Make first character a black dot, for filling rectangles)
|
||||
SetPixel( hDC, 0, 0, RGB( 255, 255, 255 ) );
|
||||
for( c = 32, x = 1, y = 0; c < 127; c++ )
|
||||
{
|
||||
myChar[ 0 ] = c;
|
||||
GetTextExtentPoint32( hDC, myChar, 1, &size );
|
||||
|
||||
if( (UInt32)( x + size.cx + 1 ) > fTextureWidth )
|
||||
{
|
||||
x = 0;
|
||||
y += size.cy + 1;
|
||||
}
|
||||
|
||||
ExtTextOut( hDC, x, y, ETO_OPAQUE, nil, myChar, 1, nil );
|
||||
|
||||
fCharInfo[ c ].fW = (UInt16)size.cx;
|
||||
fCharInfo[ c ].fH = (UInt16)size.cy;
|
||||
fCharInfo[ c ].fUVs[ 0 ].fX = (float)x / (float)fTextureWidth;
|
||||
fCharInfo[ c ].fUVs[ 0 ].fY = (float)y / (float)fTextureHeight;
|
||||
fCharInfo[ c ].fUVs[ 1 ].fX = (float)( x + size.cx ) / (float)fTextureWidth;
|
||||
fCharInfo[ c ].fUVs[ 1 ].fY = (float)( y + size.cy ) / (float)fTextureHeight;
|
||||
fCharInfo[ c ].fUVs[ 0 ].fZ = fCharInfo[ c ].fUVs[ 1 ].fZ = 0;
|
||||
|
||||
x += size.cx + 1;
|
||||
}
|
||||
fCharInfo[ 32 ].fUVs[ 1 ].fX = fCharInfo[ 32 ].fUVs[ 0 ].fX;
|
||||
|
||||
// Special case the tab key
|
||||
fCharInfo[ '\t' ].fUVs[ 1 ].fX = fCharInfo[ '\t' ].fUVs[ 0 ].fX = fCharInfo[ 32 ].fUVs[ 0 ].fX;
|
||||
fCharInfo[ '\t' ].fUVs[ 1 ].fY = fCharInfo[ '\t' ].fUVs[ 0 ].fY = 0;
|
||||
fCharInfo[ '\t' ].fUVs[ 0 ].fZ = fCharInfo[ '\t' ].fUVs[ 1 ].fZ = 0;
|
||||
fCharInfo[ '\t' ].fW = fCharInfo[ 32 ].fW * 4;
|
||||
fCharInfo[ '\t' ].fH = fCharInfo[ 32 ].fH;
|
||||
|
||||
/// Now create the data block
|
||||
UInt16 *data = TRACKED_NEW UInt16[ fTextureWidth * fTextureHeight ];
|
||||
tBits = data;
|
||||
for( y = 0; y < fTextureHeight; y++ )
|
||||
{
|
||||
for( x = 0; x < fTextureWidth; x++ )
|
||||
{
|
||||
bAlpha = (BYTE)( ( bitmapBits[ fTextureWidth * y + x ] & 0xff ) >> 4 );
|
||||
|
||||
if( bitmapBits[ fTextureWidth * y + x ] )
|
||||
*tBits = 0xffff;
|
||||
else
|
||||
*tBits = 0;
|
||||
|
||||
tBits++;
|
||||
}
|
||||
}
|
||||
|
||||
// Cleanup and return
|
||||
DeleteObject( hBitmap );
|
||||
DeleteDC( hDC );
|
||||
DeleteObject( hFont );
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
//// Create ///////////////////////////////////////////////////////////////////
|
||||
|
||||
void plTextFont::Create( char *face, UInt16 size )
|
||||
{
|
||||
// Init normal stuff
|
||||
strncpy( fFace, face, sizeof( fFace ) );
|
||||
fSize = size;
|
||||
}
|
||||
|
||||
//// IInitObjects /////////////////////////////////////////////////////////////
|
||||
|
||||
void plTextFont::IInitObjects( void )
|
||||
{
|
||||
UInt16 *data;
|
||||
|
||||
|
||||
// Create texture
|
||||
data = IInitFontTexture();
|
||||
hsAssert( data != nil, "Cannot create font texture" );
|
||||
|
||||
ICreateTexture( data );
|
||||
delete [] data;
|
||||
|
||||
// Create state blocks
|
||||
IInitStateBlocks();
|
||||
|
||||
fInitialized = true;
|
||||
}
|
||||
|
||||
//// DrawString ///////////////////////////////////////////////////////////////
|
||||
|
||||
void plTextFont::DrawString( const char *string, int sX, int sY, UInt32 hexColor,
|
||||
UInt8 style, UInt32 rightEdge )
|
||||
{
|
||||
static hsTArray<plFontVertex> verts;
|
||||
|
||||
int i, j, width, height, count, thisCount, italOffset;
|
||||
float x = (float)sX;
|
||||
char c, *strPtr;
|
||||
|
||||
|
||||
if( !fInitialized )
|
||||
IInitObjects();
|
||||
|
||||
/// Set up to draw
|
||||
italOffset = ( style & plDebugText::kStyleItalic ) ? fSize / 2: 0;
|
||||
count = strlen( string );
|
||||
strPtr = (char *)string;
|
||||
while( count > 0 )
|
||||
{
|
||||
thisCount = ( count > 64 ) ? 64 : count;
|
||||
count -= thisCount;
|
||||
|
||||
// Create an array for our vertices
|
||||
verts.SetCountAndZero( thisCount * ( ( style & plDebugText::kStyleBold ) ? 12 : 6 ) );
|
||||
|
||||
// Fill them all up now
|
||||
for( i = 0; i < thisCount * ( ( style & plDebugText::kStyleBold ) ? 12 : 6 ); i++ )
|
||||
{
|
||||
verts[ i ].fColor = hexColor;
|
||||
verts[ i ].fPoint.fZ = 0;
|
||||
}
|
||||
|
||||
for( i = 0, j = 0; i < thisCount; i++, j += 6 )
|
||||
{
|
||||
c = strPtr[ i ];
|
||||
// make sure its a character we will display
|
||||
if ( DisplayableChar(c) )
|
||||
{
|
||||
width = fCharInfo[ c ].fW + 1;
|
||||
height = fCharInfo[ c ].fH + 1;
|
||||
|
||||
if( rightEdge > 0 && x + width + italOffset >= rightEdge )
|
||||
{
|
||||
count = 0;
|
||||
thisCount = i;
|
||||
break;
|
||||
}
|
||||
|
||||
verts[ j ].fPoint.fX = x + italOffset;
|
||||
verts[ j ].fPoint.fY = (float)sY;
|
||||
verts[ j ].fUV = fCharInfo[ c ].fUVs[ 0 ];
|
||||
|
||||
verts[ j + 1 ].fPoint.fX = x + width + italOffset;
|
||||
verts[ j + 1 ].fPoint.fY = (float)sY;
|
||||
verts[ j + 1 ].fUV = fCharInfo[ c ].fUVs[ 0 ];
|
||||
verts[ j + 1 ].fUV.fX = fCharInfo[ c ].fUVs[ 1 ].fX;
|
||||
|
||||
verts[ j + 2 ].fPoint.fX = x;
|
||||
verts[ j + 2 ].fPoint.fY = (float)sY + height;
|
||||
verts[ j + 2 ].fUV = fCharInfo[ c ].fUVs[ 0 ];
|
||||
verts[ j + 2 ].fUV.fY = fCharInfo[ c ].fUVs[ 1 ].fY;
|
||||
|
||||
verts[ j + 3 ].fPoint.fX = x;
|
||||
verts[ j + 3 ].fPoint.fY = (float)sY + height;
|
||||
verts[ j + 3 ].fUV = fCharInfo[ c ].fUVs[ 0 ];
|
||||
verts[ j + 3 ].fUV.fY = fCharInfo[ c ].fUVs[ 1 ].fY;
|
||||
|
||||
verts[ j + 4 ].fPoint.fX = x + width + italOffset;
|
||||
verts[ j + 4 ].fPoint.fY = (float)sY;
|
||||
verts[ j + 4 ].fUV = fCharInfo[ c ].fUVs[ 0 ];
|
||||
verts[ j + 4 ].fUV.fX = fCharInfo[ c ].fUVs[ 1 ].fX;
|
||||
|
||||
verts[ j + 5 ].fPoint.fX = x + width;
|
||||
verts[ j + 5 ].fPoint.fY = (float)sY + height;
|
||||
verts[ j + 5 ].fUV = fCharInfo[ c ].fUVs[ 1 ];
|
||||
|
||||
x += width + 1;
|
||||
}
|
||||
}
|
||||
|
||||
if( thisCount == 0 )
|
||||
break;
|
||||
|
||||
if( style & plDebugText::kStyleBold )
|
||||
{
|
||||
for( i = 0; i < thisCount * 6; i++, j++ )
|
||||
{
|
||||
verts[ j ] = verts[ i ];
|
||||
verts[ j ].fPoint.fX = verts[ j ].fPoint.fX + 1.0f;
|
||||
}
|
||||
}
|
||||
|
||||
/// TEMPORARY DEBUG ONLY: see if we can catch this stupid random draw bug
|
||||
#if 0
|
||||
for( i = 0; i < thisCount * ( ( style & plDebugText::kStyleBold ) ? 12 : 6 ); i += 3 )
|
||||
{
|
||||
for( j = 0; j < 3; j++ )
|
||||
{
|
||||
hsAssert( verts[ i + j ].fPoint.fX >= 0, "Text point out of range" );
|
||||
hsAssert( verts[ i + j ].fPoint.fY >= 0, "Text point out of range" );
|
||||
hsAssert( verts[ i + j ].fPoint.fX < 1024, "Text point out of range" );
|
||||
hsAssert( verts[ i + j ].fPoint.fY < 768, "Text point out of range" );
|
||||
}
|
||||
int lt = ( verts[ i ].fPoint.fX < verts[ i + 1 ].fPoint.fX ? verts[ i ].fPoint.fX : verts[ i + 1 ].fPoint.fX );
|
||||
lt = ( verts[ i + 2 ].fPoint.fX < lt ? verts[ i + 2 ].fPoint.fX : lt );
|
||||
|
||||
int tp = ( verts[ i ].fPoint.fY < verts[ i + 1 ].fPoint.fY ? verts[ i ].fPoint.fY : verts[ i + 1 ].fPoint.fY );
|
||||
tp = ( verts[ i + 2 ].fPoint.fY < tp ? verts[ i + 2 ].fPoint.fY : tp );
|
||||
|
||||
int rt = ( verts[ i ].fPoint.fX > verts[ i + 1 ].fPoint.fX ? verts[ i ].fPoint.fX : verts[ i + 1 ].fPoint.fX );
|
||||
rt = ( verts[ i + 2 ].fPoint.fX > rt ? verts[ i + 2 ].fPoint.fX : rt );
|
||||
|
||||
int bt = ( verts[ i ].fPoint.fY > verts[ i + 1 ].fPoint.fY ? verts[ i ].fPoint.fY : verts[ i + 1 ].fPoint.fY );
|
||||
bt = ( verts[ i + 2 ].fPoint.fY > bt ? verts[ i + 2 ].fPoint.fY : bt );
|
||||
|
||||
hsAssert( rt - lt < 32, "Text character too big" );
|
||||
hsAssert( bt - tp < 32, "Text character too big" );
|
||||
}
|
||||
#endif
|
||||
/// TEMPORARY DEBUG ONLY: see if we can catch this stupid random draw bug
|
||||
|
||||
|
||||
/// Draw a set of tris now
|
||||
IDrawPrimitive( thisCount * ( ( style & plDebugText::kStyleBold ) ? 4 : 2 ), verts.AcquireArray() );
|
||||
|
||||
strPtr += thisCount;
|
||||
}
|
||||
|
||||
/// All done!
|
||||
}
|
||||
|
||||
//// CalcStringWidth //////////////////////////////////////////////////////////
|
||||
|
||||
UInt32 plTextFont::CalcStringWidth( const char *string )
|
||||
{
|
||||
int i, width = 0;
|
||||
|
||||
|
||||
if( !fInitialized )
|
||||
IInitObjects();
|
||||
|
||||
for( i = 0; i < strlen( string ); i++ )
|
||||
{
|
||||
// make sure its a character we will display
|
||||
if ( DisplayableChar(string[i]) )
|
||||
width += fCharInfo[ string[ i ] ].fW + 2;
|
||||
}
|
||||
|
||||
return width;
|
||||
}
|
||||
|
||||
//// DrawRect /////////////////////////////////////////////////////////////////
|
||||
// TEMPORARY function to draw a flat-shaded 2D rectangle to the screen. Used
|
||||
// to create a background for our console; will be obliterated once we figure
|
||||
// a better way to do so.
|
||||
|
||||
void plTextFont::DrawRect( int left, int top, int right, int bottom, UInt32 hexColor )
|
||||
{
|
||||
static hsTArray<plFontVertex> verts;
|
||||
int i;
|
||||
|
||||
|
||||
if( !fInitialized )
|
||||
IInitObjects();
|
||||
|
||||
/// Draw!
|
||||
verts.SetCountAndZero( 6 );
|
||||
for( i = 0; i < 6; i++ )
|
||||
{
|
||||
verts[ i ].fColor = hexColor;
|
||||
verts[ i ].fPoint.fZ = 0;
|
||||
verts[ i ].fUV.fX = verts[ i ].fUV.fY = 0;
|
||||
}
|
||||
|
||||
verts[ 0 ].fPoint.fX = verts[ 2 ].fPoint.fX = verts[ 3 ].fPoint.fX = (float)left;
|
||||
verts[ 1 ].fPoint.fX = verts[ 4 ].fPoint.fX = verts[ 5 ].fPoint.fX = (float)right;
|
||||
verts[ 0 ].fPoint.fY = verts[ 1 ].fPoint.fY = verts[ 4 ].fPoint.fY = (float)top;
|
||||
verts[ 2 ].fPoint.fY = verts[ 3 ].fPoint.fY = verts[ 5 ].fPoint.fY = (float)bottom;
|
||||
|
||||
// omg I had this at 6...just slap the dunce cap on me...-mcn
|
||||
IDrawPrimitive( 2, verts.AcquireArray() );
|
||||
|
||||
/// All done!
|
||||
}
|
||||
|
||||
//// Draw3DBorder /////////////////////////////////////////////////////////////
|
||||
// Draws a 3d border, upper-left with the first color, lower-right with the
|
||||
// second. I just LOOOOVE temporary functions :)
|
||||
// Note: this way sucks. Live with it.
|
||||
|
||||
void plTextFont::Draw3DBorder( int left, int top, int right, int bottom, UInt32 hexColor1, UInt32 hexColor2 )
|
||||
{
|
||||
static hsTArray<plFontVertex> verts;
|
||||
int i;
|
||||
|
||||
|
||||
if( !fInitialized )
|
||||
IInitObjects();
|
||||
|
||||
/// Draw!
|
||||
verts.SetCountAndZero( 8 );
|
||||
for( i = 0; i < 8; i++ )
|
||||
{
|
||||
verts[ i ].fColor = hexColor1;
|
||||
verts[ i ].fPoint.fZ = 0;
|
||||
verts[ i ].fUV.fX = verts[ i ].fUV.fY = 0;
|
||||
}
|
||||
|
||||
verts[ 1 ].fPoint.fX = verts[ 2 ].fPoint.fX = verts[ 3 ].fPoint.fX = verts[ 4 ].fPoint.fX = (float)left;
|
||||
verts[ 0 ].fPoint.fX = verts[ 5 ].fPoint.fX = verts[ 6 ].fPoint.fX = verts[ 7 ].fPoint.fX = (float)right;
|
||||
|
||||
verts[ 0 ].fPoint.fY = verts[ 1 ].fPoint.fY = verts[ 2 ].fPoint.fY = verts[ 7 ].fPoint.fY = (float)top;
|
||||
verts[ 3 ].fPoint.fY = verts[ 4 ].fPoint.fY = verts[ 5 ].fPoint.fY = verts[ 6 ].fPoint.fY = (float)bottom;
|
||||
|
||||
for( i = 4; i < 8; i++ )
|
||||
verts[ i ].fColor = hexColor2;
|
||||
|
||||
IDrawLines( 4, verts.AcquireArray() );
|
||||
|
||||
/// All done!
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,141 @@
|
||||
/*==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/>.
|
||||
|
||||
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==*/
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// plTextFont Class Header //
|
||||
// Generic 3D text font handler //
|
||||
// Cyan, Inc. //
|
||||
// //
|
||||
//// Version History //////////////////////////////////////////////////////////
|
||||
// //
|
||||
// 2.19.2001 mcn - Created. //
|
||||
// //
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef _plTextFont_h
|
||||
#define _plTextFont_h
|
||||
|
||||
#include "hsTemplates.h"
|
||||
#include "hsGeometry3.h"
|
||||
|
||||
//// plTextFont Class Definition //////////////////////////////////////////////
|
||||
|
||||
class plPipeline;
|
||||
|
||||
class plTextFont
|
||||
{
|
||||
protected:
|
||||
|
||||
struct plDXCharInfo
|
||||
{
|
||||
UInt16 fW, fH;
|
||||
hsPoint3 fUVs[ 2 ];
|
||||
};
|
||||
|
||||
struct plFontVertex
|
||||
{
|
||||
hsPoint3 fPoint;
|
||||
UInt32 fColor;
|
||||
hsPoint3 fUV;
|
||||
|
||||
plFontVertex& operator=(const int zero)
|
||||
{
|
||||
fPoint.Set(0,0,0);
|
||||
fColor = 0;
|
||||
fUV.Set(0,0,0);
|
||||
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
UInt32 fMaxNumIndices;
|
||||
UInt32 fTextureWidth, fTextureHeight;
|
||||
|
||||
char fFace[ 128 ];
|
||||
UInt16 fSize;
|
||||
hsBool fInitialized;
|
||||
UInt16 fFontHeight;
|
||||
|
||||
plPipeline *fPipe;
|
||||
|
||||
plTextFont *fNext;
|
||||
plTextFont **fPrevPtr;
|
||||
|
||||
plDXCharInfo fCharInfo[ 128 ];
|
||||
|
||||
|
||||
virtual void IInitObjects( void );
|
||||
virtual void ICreateTexture( UInt16 *data ) = 0;
|
||||
virtual void IInitStateBlocks( void ) = 0;
|
||||
virtual void IDrawPrimitive( UInt32 count, plFontVertex *array ) = 0;
|
||||
virtual void IDrawLines( UInt32 count, plFontVertex *array ) = 0;
|
||||
|
||||
UInt16 *IInitFontTexture( void );
|
||||
|
||||
void IUnlink( void )
|
||||
{
|
||||
hsAssert( fPrevPtr, "Font not in list" );
|
||||
if( fNext )
|
||||
fNext->fPrevPtr = fPrevPtr;
|
||||
*fPrevPtr = fNext;
|
||||
|
||||
fNext = nil;
|
||||
fPrevPtr = nil;
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
plTextFont( plPipeline *pipe );
|
||||
virtual ~plTextFont();
|
||||
|
||||
void Create( char *face, UInt16 size );
|
||||
void DrawString( const char *string, int x, int y, UInt32 hexColor, UInt8 style, UInt32 rightEdge = 0 );
|
||||
void DrawRect( int left, int top, int right, int bottom, UInt32 hexColor );
|
||||
void Draw3DBorder( int left, int top, int right, int bottom, UInt32 hexColor1, UInt32 hexColor2 );
|
||||
UInt32 CalcStringWidth( const char *string );
|
||||
UInt32 GetFontSize( void ) { return fSize; }
|
||||
|
||||
UInt16 GetFontHeight() { return fFontHeight; }
|
||||
|
||||
virtual void DestroyObjects( void ) = 0;
|
||||
virtual void SaveStates( void ) = 0;
|
||||
virtual void RestoreStates( void ) = 0;
|
||||
virtual void FlushDraws( void ) = 0;
|
||||
|
||||
void Link( plTextFont **back )
|
||||
{
|
||||
fNext = *back;
|
||||
if( *back )
|
||||
(*back)->fPrevPtr = &fNext;
|
||||
fPrevPtr = back;
|
||||
*back = this;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif // _plTextFont_h
|
||||
|
@ -0,0 +1,594 @@
|
||||
/*==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/>.
|
||||
|
||||
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==*/
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// plTextGenerator Class Functions //
|
||||
// Cyan, Inc. //
|
||||
// //
|
||||
//// Version History //////////////////////////////////////////////////////////
|
||||
// //
|
||||
// 12.13.2001 mcn - Created. //
|
||||
// //
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "hsWindows.h"
|
||||
#include "hsTypes.h"
|
||||
#include "hsMatrix44.h"
|
||||
#include "../pnKeyedObject/hsKeyedObject.h"
|
||||
#include "plTextGenerator.h"
|
||||
#include "../plGImage/plMipmap.h"
|
||||
#include "../plPipeline/hsGDeviceRef.h"
|
||||
#include "../pnMessage/plRefMsg.h"
|
||||
|
||||
#include "plgDispatch.h"
|
||||
#include "hsResMgr.h"
|
||||
|
||||
// Because tempKeys haven't been fixed yet (mf says to blame Eric Ellis), reffing
|
||||
// objects when we have a tempKey (or they have a tempKey) just don't work. In
|
||||
// fact, it will do nasty things like crashing on shutdown. Until then, we simply
|
||||
// won't do the refs. Note that this is BAD, but given the only time we currently
|
||||
// use these objects are very limited, controlled cases that *should* be okay
|
||||
// for now, we should be reasonably safe. For now.
|
||||
//#define MCN_DO_REFS
|
||||
|
||||
//// Constructor & Destructor /////////////////////////////////////////////////
|
||||
|
||||
plTextGenerator::plTextGenerator()
|
||||
{
|
||||
fHost = nil;
|
||||
}
|
||||
|
||||
plTextGenerator::plTextGenerator( plMipmap *host, UInt16 width, UInt16 height )
|
||||
{
|
||||
fHost = nil;
|
||||
Attach( host, width, height );
|
||||
}
|
||||
|
||||
plTextGenerator::~plTextGenerator()
|
||||
{
|
||||
// This also won't work until tempKeys work, since the mipmap will be gone by
|
||||
// this time, in which case, calling Detach() crashes
|
||||
#ifdef MCN_DO_REFS
|
||||
Detach();
|
||||
#endif
|
||||
}
|
||||
|
||||
//// Attach ///////////////////////////////////////////////////////////////////
|
||||
// Grab onto a plMipmap, suck the texture out of it and replace it with our
|
||||
// own.
|
||||
|
||||
void plTextGenerator::Attach( plMipmap *host, UInt16 width, UInt16 height )
|
||||
{
|
||||
UInt16 textWidth, textHeight;
|
||||
|
||||
|
||||
hsAssert( fHost == nil, "Attempting to attach an already attached plTextGenerator" );
|
||||
|
||||
fHost = host;
|
||||
|
||||
/// Suck the old texture data out
|
||||
fHost->Reset();
|
||||
|
||||
/// Make some new
|
||||
|
||||
// Note that we need POW-2 textures, so we go for the next one up that will
|
||||
// fit what we need
|
||||
for( textWidth = 1; textWidth < width; textWidth <<= 1 );
|
||||
for( textHeight = 1; textHeight < height; textHeight <<= 1 );
|
||||
|
||||
fWidth = width;
|
||||
fHeight = height;
|
||||
fHost->fImage = (void *)IAllocateOSSurface( textWidth, textHeight );
|
||||
fHost->SetConfig( plMipmap::kARGB32Config );
|
||||
fHost->fWidth = textWidth;
|
||||
fHost->fHeight = textHeight;
|
||||
fHost->fPixelSize = 32;
|
||||
fHost->fRowBytes = textWidth * 4;
|
||||
fHost->fNumLevels = 1;
|
||||
fHost->fFlags |= plMipmap::kUserOwnsBitmap | plMipmap::kDontThrowAwayImage;
|
||||
fHost->fCompressionType = plMipmap::kUncompressed;
|
||||
fHost->fUncompressedInfo.fType = plMipmap::UncompressedInfo::kRGB8888;
|
||||
fHost->IBuildLevelSizes();
|
||||
fHost->fTotalSize = fHost->GetLevelSize( 0 );
|
||||
|
||||
// Destroy the old texture ref, since it's probably completely nutsoid at this point.
|
||||
// This should force the pipeline to recreate one more suitable for our use
|
||||
fHost->SetDeviceRef( nil );
|
||||
|
||||
// Some init color
|
||||
hsColorRGBA color;
|
||||
color.Set( 0.f, 0.f, 0.f, 1.f );
|
||||
ClearToColor( color );
|
||||
FlushToHost();
|
||||
|
||||
#ifdef MCN_DO_REFS
|
||||
/// Of course, brilliantly enough, if we did an attach on the constructor, we don't have a key
|
||||
/// yet, so we better give ourselves one before we can call AddViaNotify()
|
||||
if( GetKey() == nil )
|
||||
{
|
||||
char str[ 256 ];
|
||||
sprintf( str, "plTextGen:%s", fHost->GetKeyName() );
|
||||
hsgResMgr::ResMgr()->NewKey( str, this, plLocation::kGlobalFixedLoc );
|
||||
}
|
||||
|
||||
/// Send ourselves a passive ref of the mipmap, so we get notified if and when it goes away
|
||||
hsgResMgr::ResMgr()->AddViaNotify( fHost->GetKey(), TRACKED_NEW plGenRefMsg( GetKey(), plRefMsg::kOnCreate, 0, 0 ), plRefFlags::kActiveRef );
|
||||
#endif
|
||||
/// All done!
|
||||
}
|
||||
|
||||
//// IAllocateOSSurface ///////////////////////////////////////////////////////
|
||||
// OS-specific. Allocates a rectangular bitmap of the given dimensions that
|
||||
// the OS can draw text into. Returns a pointer to the pixels.
|
||||
|
||||
UInt32 *plTextGenerator::IAllocateOSSurface( UInt16 width, UInt16 height )
|
||||
{
|
||||
#if HS_BUILD_FOR_WIN32
|
||||
|
||||
BITMAPINFO bmi;
|
||||
|
||||
|
||||
// Create a new DC and bitmap that we can draw characters to
|
||||
memset( &bmi.bmiHeader, 0, sizeof( BITMAPINFOHEADER ) );
|
||||
bmi.bmiHeader.biSize = sizeof( BITMAPINFOHEADER );
|
||||
bmi.bmiHeader.biWidth = width;
|
||||
bmi.bmiHeader.biHeight = -(int)height;
|
||||
bmi.bmiHeader.biPlanes = 1;
|
||||
bmi.bmiHeader.biCompression = BI_RGB;
|
||||
bmi.bmiHeader.biBitCount = 32;
|
||||
|
||||
fWinRGBDC = CreateCompatibleDC( nil );
|
||||
fWinRGBBitmap = CreateDIBSection( fWinRGBDC, &bmi, DIB_RGB_COLORS, (void **)&fWinRGBBits, nil, 0 );
|
||||
SetMapMode( fWinRGBDC, MM_TEXT );
|
||||
SetBkMode( fWinRGBDC, TRANSPARENT );
|
||||
SetTextAlign( fWinRGBDC, TA_TOP | TA_LEFT );
|
||||
|
||||
SelectObject( fWinRGBDC, fWinRGBBitmap );
|
||||
|
||||
// Now create a second DC/bitmap combo, this one for writing alpha values to
|
||||
memset( &bmi.bmiHeader, 0, sizeof( BITMAPINFOHEADER ) );
|
||||
bmi.bmiHeader.biSize = sizeof( BITMAPINFOHEADER );
|
||||
bmi.bmiHeader.biWidth = width;
|
||||
bmi.bmiHeader.biHeight = -(int)height;
|
||||
bmi.bmiHeader.biPlanes = 1;
|
||||
bmi.bmiHeader.biCompression = BI_RGB;
|
||||
bmi.bmiHeader.biBitCount = 8;
|
||||
|
||||
fWinAlphaDC = CreateCompatibleDC( nil );
|
||||
fWinAlphaBitmap = CreateDIBSection( fWinAlphaDC, &bmi, DIB_RGB_COLORS, (void **)&fWinAlphaBits, nil, 0 );
|
||||
SetMapMode( fWinAlphaDC, MM_TEXT );
|
||||
SetBkMode( fWinAlphaDC, TRANSPARENT );
|
||||
SetTextAlign( fWinAlphaDC, TA_TOP | TA_LEFT );
|
||||
|
||||
SelectObject( fWinAlphaDC, fWinAlphaBitmap );
|
||||
|
||||
return (UInt32 *)fWinRGBBits;
|
||||
#endif
|
||||
}
|
||||
|
||||
//// Detach ///////////////////////////////////////////////////////////////////
|
||||
// Release the mipmap unto itself.
|
||||
|
||||
void plTextGenerator::Detach( void )
|
||||
{
|
||||
if( fHost == nil )
|
||||
return;
|
||||
// hsAssert( fHost != nil, "Attempting to detach unattached host" );
|
||||
|
||||
SetFont( nil, 0 );
|
||||
IDestroyOSSurface();
|
||||
|
||||
fHost->Reset();
|
||||
fHost->fFlags &= ~( plMipmap::kUserOwnsBitmap | plMipmap::kDontThrowAwayImage );
|
||||
|
||||
// Destroy the old texture ref, since we're no longer using it
|
||||
fHost->SetDeviceRef( nil );
|
||||
|
||||
plMipmap *oldHost = fHost;
|
||||
|
||||
fHost = nil;
|
||||
|
||||
#ifdef MCN_DO_REFS
|
||||
// Now send ourselves a unref msg, just in case we were called directly (if this was done by
|
||||
// message, we'll get called a few times, but that's ok, we're set up to handle that, and it
|
||||
// won't happen 'cept on destruction so the speed penalty shouldn't be a problem)
|
||||
GetKey()->Release( oldHost->GetKey() );
|
||||
#endif
|
||||
}
|
||||
|
||||
//// IDestroyOSSurface ////////////////////////////////////////////////////////
|
||||
// Opposite of allocate. DUH!
|
||||
|
||||
void plTextGenerator::IDestroyOSSurface( void )
|
||||
{
|
||||
#if HS_BUILD_FOR_WIN32
|
||||
|
||||
fHost->fImage = nil; // DeleteObject() will get rid of it for us
|
||||
DeleteObject( fWinRGBBitmap );
|
||||
DeleteDC( fWinRGBDC );
|
||||
|
||||
DeleteObject( fWinAlphaBitmap );
|
||||
DeleteDC( fWinAlphaDC );
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
//// ClearToColor /////////////////////////////////////////////////////////////
|
||||
|
||||
void plTextGenerator::ClearToColor( hsColorRGBA &color )
|
||||
{
|
||||
int i;
|
||||
UInt32 *data = (UInt32 *)fHost->fImage;
|
||||
UInt32 hexColor = color.ToARGB32();
|
||||
|
||||
#if HS_BUILD_FOR_WIN32
|
||||
GdiFlush();
|
||||
#endif
|
||||
|
||||
for( i = 0; i < fHost->fWidth * fHost->fHeight; i++ )
|
||||
data[ i ] = hexColor;
|
||||
|
||||
// Fill our alpha bitmap as well, since we use that too
|
||||
#if HS_BUILD_FOR_WIN32
|
||||
memset( fWinAlphaBits, (UInt8)( color.a * 255.f ), fHost->fWidth * fHost->fHeight );
|
||||
#endif
|
||||
}
|
||||
|
||||
//// SetFont //////////////////////////////////////////////////////////////////
|
||||
// OS-specific. Load the given font for drawing the text with.
|
||||
|
||||
void plTextGenerator::SetFont( const char *face, UInt16 size, hsBool antiAliasRGB )
|
||||
{
|
||||
#if HS_BUILD_FOR_WIN32
|
||||
if( fWinFont != nil )
|
||||
{
|
||||
DeleteObject( fWinFont );
|
||||
fWinFont = nil;
|
||||
}
|
||||
if( fWinAlphaFont != nil )
|
||||
{
|
||||
DeleteObject( fWinAlphaFont );
|
||||
fWinAlphaFont = nil;
|
||||
}
|
||||
|
||||
if( face != nil )
|
||||
{
|
||||
int nHeight = -MulDiv( size, GetDeviceCaps( fWinRGBDC, LOGPIXELSY ), 72 );
|
||||
fWinFont = CreateFont( nHeight, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS,
|
||||
CLIP_DEFAULT_PRECIS, antiAliasRGB ? ANTIALIASED_QUALITY : DEFAULT_QUALITY, VARIABLE_PITCH, face );
|
||||
hsAssert( fWinFont != nil, "Cannot create Windows font for plTextGenerator" );
|
||||
|
||||
// The font for the alpha channel is identical except that it's antialiased, whereas the RGB version isn't.
|
||||
fWinAlphaFont = CreateFont( nHeight, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS,
|
||||
CLIP_DEFAULT_PRECIS, (!antiAliasRGB) ? ANTIALIASED_QUALITY : DEFAULT_QUALITY, VARIABLE_PITCH, face );
|
||||
hsAssert( fWinAlphaFont != nil, "Cannot create Windows font for plTextGenerator" );
|
||||
|
||||
SelectObject( fWinRGBDC, fWinFont );
|
||||
SelectObject( fWinAlphaDC, fWinAlphaFont );
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
//// SetTextColor /////////////////////////////////////////////////////////////
|
||||
// blockRGB basically forces the RGB channel to write in blocks instead of
|
||||
// actual characters. This isn't useful unless you're relying on the alpha
|
||||
// channel to do the text (opaque text and transparent background), in which
|
||||
// case you want plenty of block color in your RGB channel because it'll get
|
||||
// alpha-ed out by the alpha channel.
|
||||
|
||||
void plTextGenerator::SetTextColor( hsColorRGBA &color, hsBool blockRGB )
|
||||
{
|
||||
#if HS_BUILD_FOR_WIN32
|
||||
int r = (int)(color.r * 255.f);
|
||||
int g = (int)(color.g * 255.f);
|
||||
int b = (int)(color.b * 255.f);
|
||||
int a = (int)(color.a * 255.f);
|
||||
|
||||
if( blockRGB )
|
||||
{
|
||||
::SetBkColor( fWinRGBDC, RGB( r, g, b ) );
|
||||
::SetBkMode( fWinRGBDC, OPAQUE );
|
||||
}
|
||||
else
|
||||
::SetBkMode( fWinRGBDC, TRANSPARENT );
|
||||
|
||||
::SetTextColor( fWinRGBDC, RGB( r, g, b ) );
|
||||
::SetTextColor( fWinAlphaDC, RGB( a, a, a ) );
|
||||
#endif
|
||||
}
|
||||
|
||||
//// DrawString ///////////////////////////////////////////////////////////////
|
||||
|
||||
void plTextGenerator::DrawString( UInt16 x, UInt16 y, const char *text )
|
||||
{
|
||||
wchar_t *wText = hsStringToWString(text);
|
||||
DrawString(x,y,wText);
|
||||
delete [] wText;
|
||||
}
|
||||
|
||||
void plTextGenerator::DrawString( UInt16 x, UInt16 y, const wchar_t *text )
|
||||
{
|
||||
#if HS_BUILD_FOR_WIN32
|
||||
|
||||
::TextOutW( fWinRGBDC, x, y, text, wcslen( text ) );
|
||||
::TextOutW( fWinAlphaDC, x, y, text, wcslen( text ) );
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
//// DrawClippedString ////////////////////////////////////////////////////////
|
||||
|
||||
void plTextGenerator::DrawClippedString( Int16 x, Int16 y, const char *text, UInt16 width, UInt16 height )
|
||||
{
|
||||
wchar_t *wText = hsStringToWString(text);
|
||||
DrawClippedString(x,y,wText,width,height);
|
||||
delete [] wText;
|
||||
}
|
||||
|
||||
void plTextGenerator::DrawClippedString( Int16 x, Int16 y, const wchar_t *text, UInt16 width, UInt16 height )
|
||||
{
|
||||
#if HS_BUILD_FOR_WIN32
|
||||
|
||||
RECT r;
|
||||
::SetRect( &r, x, y, x + width, y + height );
|
||||
|
||||
::ExtTextOutW( fWinRGBDC, x, y, ETO_CLIPPED, &r, text, wcslen( text ), nil );
|
||||
::ExtTextOutW( fWinAlphaDC, x, y, ETO_CLIPPED, &r, text, wcslen( text ), nil );
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
//// DrawClippedString ////////////////////////////////////////////////////////
|
||||
|
||||
void plTextGenerator::DrawClippedString( Int16 x, Int16 y, const char *text, UInt16 clipX, UInt16 clipY, UInt16 width, UInt16 height )
|
||||
{
|
||||
wchar_t *wText = hsStringToWString(text);
|
||||
DrawClippedString(x,y,wText,clipX,clipY,width,height);
|
||||
delete [] wText;
|
||||
}
|
||||
|
||||
void plTextGenerator::DrawClippedString( Int16 x, Int16 y, const wchar_t *text, UInt16 clipX, UInt16 clipY, UInt16 width, UInt16 height )
|
||||
{
|
||||
#if HS_BUILD_FOR_WIN32
|
||||
|
||||
RECT r;
|
||||
::SetRect( &r, clipX, clipY, clipX + width, clipY + height );
|
||||
|
||||
::ExtTextOutW( fWinRGBDC, x, y, ETO_CLIPPED, &r, text, wcslen( text ), nil );
|
||||
::ExtTextOutW( fWinAlphaDC, x, y, ETO_CLIPPED, &r, text, wcslen( text ), nil );
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
//// DrawWrappedString ////////////////////////////////////////////////////////
|
||||
|
||||
void plTextGenerator::DrawWrappedString( UInt16 x, UInt16 y, const char *text, UInt16 width, UInt16 height )
|
||||
{
|
||||
wchar_t *wText = hsStringToWString(text);
|
||||
DrawWrappedString(x,y,wText,width,height);
|
||||
delete [] wText;
|
||||
}
|
||||
|
||||
void plTextGenerator::DrawWrappedString( UInt16 x, UInt16 y, const wchar_t *text, UInt16 width, UInt16 height )
|
||||
{
|
||||
#if HS_BUILD_FOR_WIN32
|
||||
|
||||
RECT r;
|
||||
::SetRect( &r, x, y, x + width, y + height );
|
||||
|
||||
// HBRUSH brush = ::CreateSolidBrush( RGB( 255, 255, 255 ) );
|
||||
// ::FillRect( fWinRGBDC, &r, brush );
|
||||
// ::DeleteObject( brush );
|
||||
::DrawTextW( fWinRGBDC, text, wcslen( text ), &r,
|
||||
DT_TOP | DT_LEFT | DT_NOPREFIX | DT_WORDBREAK );
|
||||
::DrawTextW( fWinAlphaDC, text, wcslen( text ), &r,
|
||||
DT_TOP | DT_LEFT | DT_NOPREFIX | DT_WORDBREAK );
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
//// CalcStringWidth //////////////////////////////////////////////////////////
|
||||
|
||||
UInt16 plTextGenerator::CalcStringWidth( const char *text, UInt16 *height )
|
||||
{
|
||||
wchar_t *wText = hsStringToWString(text);
|
||||
UInt16 retVal = CalcStringWidth(wText,height);
|
||||
delete [] wText;
|
||||
return retVal;
|
||||
}
|
||||
|
||||
UInt16 plTextGenerator::CalcStringWidth( const wchar_t *text, UInt16 *height )
|
||||
{
|
||||
#if HS_BUILD_FOR_WIN32
|
||||
|
||||
SIZE size;
|
||||
::GetTextExtentPoint32W( fWinRGBDC, text, wcslen( text ), &size );
|
||||
|
||||
if( height != nil )
|
||||
*height = (UInt16)size.cy;
|
||||
|
||||
return (UInt16)size.cx;
|
||||
#endif
|
||||
}
|
||||
|
||||
//// CalcWrappedStringSize ////////////////////////////////////////////////////
|
||||
|
||||
void plTextGenerator::CalcWrappedStringSize( const char *text, UInt16 *width, UInt16 *height )
|
||||
{
|
||||
wchar_t *wText = hsStringToWString(text);
|
||||
CalcWrappedStringSize(wText,width,height);
|
||||
delete [] wText;
|
||||
}
|
||||
|
||||
void plTextGenerator::CalcWrappedStringSize( const wchar_t *text, UInt16 *width, UInt16 *height )
|
||||
{
|
||||
#if HS_BUILD_FOR_WIN32
|
||||
|
||||
RECT r;
|
||||
::SetRect( &r, 0, 0, *width, 0 );
|
||||
|
||||
::DrawTextW( fWinRGBDC, text, wcslen( text ), &r, DT_TOP | DT_LEFT | DT_NOPREFIX | DT_WORDBREAK | DT_CALCRECT );
|
||||
|
||||
*width = (UInt16)(r.right);
|
||||
if( height != nil )
|
||||
*height = (UInt16)r.bottom;
|
||||
#endif
|
||||
}
|
||||
|
||||
//// FillRect /////////////////////////////////////////////////////////////////
|
||||
|
||||
void plTextGenerator::FillRect( UInt16 x, UInt16 y, UInt16 width, UInt16 height, hsColorRGBA &color )
|
||||
{
|
||||
#if HS_BUILD_FOR_WIN32
|
||||
|
||||
RECT rc;
|
||||
::SetRect( &rc, x, y, x + width, y + height );
|
||||
|
||||
int r = (int)(color.r * 255.f);
|
||||
int g = (int)(color.g * 255.f);
|
||||
int b = (int)(color.b * 255.f);
|
||||
int a = (int)(color.a * 255.f);
|
||||
|
||||
HBRUSH brush = ::CreateSolidBrush( RGB( r, g, b ) );
|
||||
::FillRect( fWinRGBDC, &rc, brush );
|
||||
::DeleteObject( brush );
|
||||
|
||||
brush = ::CreateSolidBrush( RGB( a, a, a ) );
|
||||
::FillRect( fWinAlphaDC, &rc, brush );
|
||||
::DeleteObject( brush );
|
||||
#endif
|
||||
}
|
||||
|
||||
//// FrameRect ////////////////////////////////////////////////////////////////
|
||||
|
||||
void plTextGenerator::FrameRect( UInt16 x, UInt16 y, UInt16 width, UInt16 height, hsColorRGBA &color )
|
||||
{
|
||||
#if HS_BUILD_FOR_WIN32
|
||||
|
||||
RECT rc;
|
||||
::SetRect( &rc, x, y, x + width, y + height );
|
||||
|
||||
int r = (int)(color.r * 255.f);
|
||||
int g = (int)(color.g * 255.f);
|
||||
int b = (int)(color.b * 255.f);
|
||||
int a = (int)(color.a * 255.f);
|
||||
|
||||
HBRUSH brush = ::CreateSolidBrush( RGB( r, g, b ) );
|
||||
::FrameRect( fWinRGBDC, &rc, brush );
|
||||
::DeleteObject( brush );
|
||||
|
||||
brush = ::CreateSolidBrush( RGB( a, a, a ) );
|
||||
::FrameRect( fWinAlphaDC, &rc, brush );
|
||||
::DeleteObject( brush );
|
||||
#endif
|
||||
}
|
||||
|
||||
//// FlushToHost //////////////////////////////////////////////////////////////
|
||||
|
||||
void plTextGenerator::FlushToHost( void )
|
||||
{
|
||||
#if HS_BUILD_FOR_WIN32
|
||||
// Flush the GDI first, to make sure it's done
|
||||
GdiFlush();
|
||||
|
||||
// Now copy our alpha channel over. I hate the GDI
|
||||
UInt32 i = fHost->fWidth * fHost->fHeight;
|
||||
UInt32 *dest = fWinRGBBits;
|
||||
UInt8 *src = fWinAlphaBits;
|
||||
|
||||
/* while( i-- )
|
||||
{
|
||||
*dest &= 0x00ffffff;
|
||||
*dest |= ( *src ) << 24;
|
||||
// *dest |= ( *dest << 16 ) & 0xff000000;
|
||||
dest++;
|
||||
src++;
|
||||
}
|
||||
*/
|
||||
do
|
||||
{
|
||||
i--;
|
||||
dest[ i ] &= 0x00ffffff;
|
||||
dest[ i ] |= src[ i ] << 24;
|
||||
} while( i );
|
||||
#endif
|
||||
|
||||
// Dirty the mipmap's deviceRef, if there is one
|
||||
if( fHost->GetDeviceRef() != nil )
|
||||
fHost->GetDeviceRef()->SetDirty( true );
|
||||
}
|
||||
|
||||
//// GetTextWidth/Height //////////////////////////////////////////////////////
|
||||
|
||||
UInt16 plTextGenerator::GetTextWidth( void )
|
||||
{
|
||||
return ( fHost != nil ) ? (UInt16)(fHost->fWidth) : 0;
|
||||
}
|
||||
|
||||
UInt16 plTextGenerator::GetTextHeight( void )
|
||||
{
|
||||
return ( fHost != nil ) ? (UInt16)(fHost->fHeight) : 0;
|
||||
}
|
||||
|
||||
//// GetLayerTransform ////////////////////////////////////////////////////////
|
||||
// Since the textGen can actually create a texture bigger than you were expecting,
|
||||
// you want to be able to apply a layer texture transform that will compensate. This
|
||||
// function will give you that transform. Just feed it into plLayer->SetTransform().
|
||||
|
||||
hsMatrix44 plTextGenerator::GetLayerTransform( void )
|
||||
{
|
||||
hsMatrix44 xform;
|
||||
hsVector3 scale;
|
||||
|
||||
scale.Set( (float)GetWidth() / (float)GetTextWidth(),
|
||||
(float)GetHeight() / (float)GetTextHeight(), 1.f );
|
||||
|
||||
xform.MakeScaleMat( &scale );
|
||||
return xform;
|
||||
}
|
||||
|
||||
//// MsgReceive ///////////////////////////////////////////////////////////////
|
||||
|
||||
hsBool plTextGenerator::MsgReceive( plMessage *msg )
|
||||
{
|
||||
#ifdef MCN_DO_REFS
|
||||
plGenRefMsg *refMsg = plGenRefMsg::ConvertNoRef( msg );
|
||||
if( refMsg != nil )
|
||||
{
|
||||
if( refMsg->GetContext() & ( plRefMsg::kOnCreate | plRefMsg::kOnRequest ) )
|
||||
{
|
||||
// Don't do anything--already did an attach
|
||||
}
|
||||
else if( refMsg->GetContext() & ( plRefMsg::kOnDestroy | plRefMsg::kOnRemove ) )
|
||||
{
|
||||
Detach();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
return hsKeyedObject::MsgReceive( msg );
|
||||
}
|
@ -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/>.
|
||||
|
||||
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==*/
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// plTextGenerator Class Header //
|
||||
// Helper utility class that "attaches" to a mipmap and fills that mipmap //
|
||||
// with text.
|
||||
// Cyan, Inc. //
|
||||
// //
|
||||
//// Version History //////////////////////////////////////////////////////////
|
||||
// //
|
||||
// 12.13.2001 mcn - Created. //
|
||||
// //
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef _plTextGenerator_h
|
||||
#define _plTextGenerator_h
|
||||
|
||||
#include "hsTemplates.h"
|
||||
#include "hsGeometry3.h"
|
||||
#include "hsColorRGBA.h"
|
||||
|
||||
//// plTextGenerator Class Definition //////////////////////////////////////////////
|
||||
|
||||
class plMipmap;
|
||||
struct hsMatrix44;
|
||||
|
||||
class plTextGenerator : public hsKeyedObject
|
||||
{
|
||||
protected:
|
||||
|
||||
plMipmap *fHost;
|
||||
UInt16 fWidth, fHeight;
|
||||
|
||||
#if HS_BUILD_FOR_WIN32
|
||||
HDC fWinRGBDC;
|
||||
HBITMAP fWinRGBBitmap;
|
||||
HFONT fWinFont;
|
||||
UInt32 *fWinRGBBits;
|
||||
|
||||
HFONT fWinAlphaFont;
|
||||
HDC fWinAlphaDC;
|
||||
HBITMAP fWinAlphaBitmap;
|
||||
UInt8 *fWinAlphaBits;
|
||||
#endif
|
||||
|
||||
UInt32 *IAllocateOSSurface( UInt16 width, UInt16 height );
|
||||
void IDestroyOSSurface( void );
|
||||
|
||||
public:
|
||||
|
||||
plTextGenerator();
|
||||
plTextGenerator( plMipmap *host, UInt16 width, UInt16 height );
|
||||
virtual ~plTextGenerator();
|
||||
|
||||
void Attach( plMipmap *host, UInt16 width, UInt16 height );
|
||||
void Detach( void );
|
||||
|
||||
/// Operations to perform on the text block
|
||||
|
||||
void ClearToColor( hsColorRGBA &color );
|
||||
|
||||
void SetFont( const char *face, UInt16 size, hsBool antiAliasRGB = true );
|
||||
void SetTextColor( hsColorRGBA &color, hsBool blockRGB = false );
|
||||
|
||||
void DrawString( UInt16 x, UInt16 y, const char *text );
|
||||
void DrawString( UInt16 x, UInt16 y, const wchar_t *text );
|
||||
void DrawClippedString( Int16 x, Int16 y, const char *text, UInt16 width, UInt16 height );
|
||||
void DrawClippedString( Int16 x, Int16 y, const wchar_t *text, UInt16 width, UInt16 height );
|
||||
void DrawClippedString( Int16 x, Int16 y, const char *text, UInt16 clipX, UInt16 clipY, UInt16 width, UInt16 height );
|
||||
void DrawClippedString( Int16 x, Int16 y, const wchar_t *text, UInt16 clipX, UInt16 clipY, UInt16 width, UInt16 height );
|
||||
void DrawWrappedString( UInt16 x, UInt16 y, const char *text, UInt16 width, UInt16 height );
|
||||
void DrawWrappedString( UInt16 x, UInt16 y, const wchar_t *text, UInt16 width, UInt16 height );
|
||||
UInt16 CalcStringWidth( const char *text, UInt16 *height = nil );
|
||||
UInt16 CalcStringWidth( const wchar_t *text, UInt16 *height = nil );
|
||||
void CalcWrappedStringSize( const char *text, UInt16 *width, UInt16 *height );
|
||||
void CalcWrappedStringSize( const wchar_t *text, UInt16 *width, UInt16 *height );
|
||||
void FillRect( UInt16 x, UInt16 y, UInt16 width, UInt16 height, hsColorRGBA &color );
|
||||
void FrameRect( UInt16 x, UInt16 y, UInt16 width, UInt16 height, hsColorRGBA &color );
|
||||
|
||||
void FlushToHost( void );
|
||||
|
||||
UInt16 GetTextWidth( void );
|
||||
UInt16 GetTextHeight( void );
|
||||
|
||||
UInt16 GetWidth( void ) { return fWidth; }
|
||||
UInt16 GetHeight( void ) { return fHeight; }
|
||||
|
||||
// Since the textGen can actually create a texture bigger than you were expecting,
|
||||
// you want to be able to apply a layer texture transform that will compensate. This
|
||||
// function will give you that transform. Just feed it into plLayer->SetTransform().
|
||||
|
||||
hsMatrix44 GetLayerTransform( void );
|
||||
|
||||
|
||||
virtual hsBool MsgReceive( plMessage *msg );
|
||||
};
|
||||
|
||||
|
||||
#endif // _plTextGenerator_h
|
||||
|
@ -0,0 +1,358 @@
|
||||
/*==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/>.
|
||||
|
||||
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==*/
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// plTransitionMgr - Class to handle fullscreen transitions (fades, etc) //
|
||||
// //
|
||||
// Note: eventually, I would like to drive these transitions on material //
|
||||
// animations (it's just a big screen-covering plate with a material, //
|
||||
// after all). This would allow the artists to specify their own //
|
||||
// transitions and do really cool effects. However, that would require //
|
||||
// somehow loading the materials in, and I'm not sure exactly how to do //
|
||||
// that.... //
|
||||
// //
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "hsWindows.h"
|
||||
#include "hsTypes.h"
|
||||
#include "plTransitionMgr.h"
|
||||
#include "plPlates.h"
|
||||
|
||||
#include "../plGImage/plMipmap.h"
|
||||
#include "../plSurface/plLayer.h"
|
||||
#include "../plSurface/hsGMaterial.h"
|
||||
#include "../plMessage/plLayRefMsg.h"
|
||||
#include "../pnMessage/plRefMsg.h"
|
||||
#include "../plMessage/plTransitionMsg.h"
|
||||
#include "../pnMessage/plTimeMsg.h"
|
||||
#include "../pnMessage/plEventCallbackMsg.h"
|
||||
#include "../plMessage/plLinkToAgeMsg.h"
|
||||
#include "plgDispatch.h"
|
||||
#include "hsGDeviceRef.h"
|
||||
#include "hsResMgr.h"
|
||||
#include "hsTimer.h"
|
||||
|
||||
#include "../plAudio/plAudioSystem.h"
|
||||
#include "../pnNetCommon/plNetApp.h"
|
||||
#include "../plNetClient/plLinkEffectsMgr.h"
|
||||
#include "../pnNetCommon/plNetApp.h"
|
||||
|
||||
#include "../plStatusLog/plStatusLog.h"
|
||||
|
||||
//// Constructor/Destructor //////////////////////////////////////////////////
|
||||
|
||||
plTransitionMgr::plTransitionMgr()
|
||||
{
|
||||
fEffectPlate = nil;
|
||||
fCurrentEffect = kIdle;
|
||||
fPlaying = false;
|
||||
}
|
||||
|
||||
void plTransitionMgr::Init( void )
|
||||
{
|
||||
ICreatePlate();
|
||||
plgDispatch::Dispatch()->RegisterForExactType( plTransitionMsg::Index(), GetKey() );
|
||||
plgDispatch::Dispatch()->RegisterForExactType( plLinkEffectBCMsg::Index(), GetKey() );
|
||||
}
|
||||
|
||||
plTransitionMgr::~plTransitionMgr()
|
||||
{
|
||||
int i;
|
||||
|
||||
|
||||
for( i = 0; i < fCallbacks.GetCount(); i++ )
|
||||
hsRefCnt_SafeUnRef( fCallbacks[ i ] );
|
||||
|
||||
if( fEffectPlate != nil )
|
||||
plPlateManager::Instance().DestroyPlate( fEffectPlate );
|
||||
|
||||
if( fRegisteredForTime )
|
||||
plgDispatch::Dispatch()->UnRegisterForExactType( plTimeMsg::Index(), GetKey() );
|
||||
|
||||
plgDispatch::Dispatch()->UnRegisterForExactType( plTransitionMsg::Index(), GetKey() );
|
||||
plgDispatch::Dispatch()->UnRegisterForExactType( plLinkEffectBCMsg::Index(), GetKey() );
|
||||
}
|
||||
|
||||
//// ICreatePlate ////////////////////////////////////////////////////////////
|
||||
|
||||
void plTransitionMgr::ICreatePlate( void )
|
||||
{
|
||||
int x, y;
|
||||
|
||||
|
||||
fEffectPlate = nil;
|
||||
|
||||
// +0.01 to deal with the half-pixel antialiasing stuff
|
||||
plPlateManager::Instance().CreatePlate( &fEffectPlate, 0, 0, 2.01, 2.01 );
|
||||
fEffectPlate->SetDepth(2);
|
||||
|
||||
// hack for now--create a black layer that we will animate the opacity on
|
||||
plMipmap *ourMip = fEffectPlate->CreateMaterial( 16, 16, true );
|
||||
for( y = 0; y < ourMip->GetHeight(); y++ )
|
||||
{
|
||||
UInt32 *pixels = ourMip->GetAddr32( 0, y );
|
||||
for( x = 0; x < ourMip->GetWidth(); x++ )
|
||||
pixels[ x ] = 0xff000000;
|
||||
}
|
||||
|
||||
fEffectPlate->SetVisible( false );
|
||||
}
|
||||
|
||||
//// IStartFadeOut ///////////////////////////////////////////////////////////
|
||||
|
||||
void plTransitionMgr::IStartFadeOut( hsScalar lengthInSecs, UInt8 effect )
|
||||
{
|
||||
fCurrentEffect = effect; // default - kFadeOut;
|
||||
fEffectLength = lengthInSecs;
|
||||
|
||||
// Special case for length 0--just jump straight to fadeout
|
||||
if( lengthInSecs == 0.f )
|
||||
{
|
||||
fCurrOpacity = 1.f;
|
||||
fLastTime = -1.f;
|
||||
fPlaying = false;
|
||||
plgAudioSys::SetGlobalFadeVolume( 0.f );
|
||||
}
|
||||
else
|
||||
{
|
||||
fCurrOpacity = 0;
|
||||
fOpacDelta = 1.f / lengthInSecs;
|
||||
fLastTime = -1.f;
|
||||
fPlaying = true;
|
||||
|
||||
// Register for time message
|
||||
plgDispatch::Dispatch()->RegisterForExactType( plTimeMsg::Index(), GetKey() );
|
||||
fRegisteredForTime = true;
|
||||
}
|
||||
|
||||
if( fEffectPlate == nil )
|
||||
ICreatePlate();
|
||||
fEffectPlate->SetVisible( true );
|
||||
|
||||
plLayer *layer = (plLayer *)fEffectPlate->GetMaterial()->GetLayer( 0 );
|
||||
if( layer != nil )
|
||||
{
|
||||
layer->SetOpacity( fCurrOpacity );
|
||||
}
|
||||
}
|
||||
|
||||
//// IStartFadeIn ////////////////////////////////////////////////////////////
|
||||
|
||||
void plTransitionMgr::IStartFadeIn( hsScalar lengthInSecs, UInt8 effect )
|
||||
{
|
||||
fCurrentEffect = effect; // default - kFadeIn;
|
||||
fEffectLength = lengthInSecs;
|
||||
fCurrOpacity = 1.f;
|
||||
fOpacDelta = -1.f / lengthInSecs;
|
||||
fLastTime = -1.f;
|
||||
fPlaying = true;
|
||||
|
||||
// Register for time message
|
||||
plgDispatch::Dispatch()->RegisterForExactType( plTimeMsg::Index(), GetKey() );
|
||||
fRegisteredForTime = true;
|
||||
|
||||
if( fEffectPlate == nil )
|
||||
ICreatePlate();
|
||||
fEffectPlate->SetVisible( true );
|
||||
|
||||
plLayer *layer = (plLayer *)fEffectPlate->GetMaterial()->GetLayer( 0 );
|
||||
if( layer != nil )
|
||||
{
|
||||
layer->SetOpacity( fCurrOpacity );
|
||||
}
|
||||
}
|
||||
|
||||
//// IStop ///////////////////////////////////////////////////////////////////
|
||||
|
||||
void plTransitionMgr::IStop( hsBool aboutToStartAgain /*= false*/ )
|
||||
{
|
||||
int i;
|
||||
|
||||
plgDispatch::Dispatch()->UnRegisterForExactType( plTimeMsg::Index(), GetKey() );
|
||||
fRegisteredForTime = false;
|
||||
|
||||
if( fPlaying )
|
||||
{
|
||||
if( !fHoldAtEnd && fEffectPlate != nil && !aboutToStartAgain )
|
||||
fEffectPlate->SetVisible( false );
|
||||
|
||||
// finish the opacity to the end opacity
|
||||
if( fEffectPlate != nil )
|
||||
{
|
||||
plLayer *layer = (plLayer *)fEffectPlate->GetMaterial()->GetLayer( 0 );
|
||||
if( layer != nil )
|
||||
{
|
||||
layer->SetOpacity( (fCurrentEffect == kFadeIn || fCurrentEffect == kTransitionFadeIn) ? 0.f : 1.f );
|
||||
}
|
||||
}
|
||||
|
||||
if( !aboutToStartAgain )
|
||||
{
|
||||
if (!fNoSoundFade)
|
||||
plgAudioSys::SetGlobalFadeVolume( (fCurrentEffect == kFadeIn || fCurrentEffect == kTransitionFadeIn) ? 1.f : 0.f );
|
||||
}
|
||||
|
||||
for( i = 0; i < fCallbacks.GetCount(); i++ )
|
||||
{
|
||||
fCallbacks[ i ]->SetSender( GetKey() );
|
||||
plgDispatch::MsgSend( fCallbacks[ i ] );
|
||||
}
|
||||
fCallbacks.Reset();
|
||||
|
||||
fPlaying = false;
|
||||
}
|
||||
}
|
||||
|
||||
//// MsgReceive //////////////////////////////////////////////////////////////
|
||||
|
||||
hsBool plTransitionMgr::MsgReceive( plMessage* msg )
|
||||
{
|
||||
int i;
|
||||
|
||||
|
||||
plTimeMsg *time = plTimeMsg::ConvertNoRef( msg );
|
||||
if( time != nil )
|
||||
{
|
||||
if( !fPlaying )
|
||||
return false;
|
||||
|
||||
if (fLastTime < 0)
|
||||
{
|
||||
// Semi-hack. We trigger transitions after we've finished loading.
|
||||
// Problem is the loading all happens in one really long frame, so that
|
||||
// if we record the time we started, we'll instantly be done next frame,
|
||||
// even though we triggered just at the "end" of the last frame.
|
||||
//
|
||||
// So instead we don't start the clock until we get our first plTimeMsg.
|
||||
|
||||
|
||||
fLastTime = (hsScalar)(time->DSeconds());
|
||||
return false;
|
||||
}
|
||||
|
||||
fEffectLength -= (hsScalar)( time->DSeconds() - fLastTime );//*/time->DelSeconds();
|
||||
if( fEffectLength < 0 )
|
||||
IStop();
|
||||
else
|
||||
{
|
||||
// Grab the layer so we can set the opacity
|
||||
fCurrOpacity += (hsScalar)(fOpacDelta * ( time->DSeconds() - fLastTime ));//*/time->DelSeconds();
|
||||
if( fEffectPlate == nil )
|
||||
ICreatePlate();
|
||||
|
||||
plLayer *layer = (plLayer *)fEffectPlate->GetMaterial()->GetLayer( 0 );
|
||||
if( layer != nil )
|
||||
{
|
||||
layer->SetOpacity( fCurrOpacity );
|
||||
}
|
||||
|
||||
// Let the audiosystem handle fading in sounds
|
||||
if(!fNoSoundFade)
|
||||
plgAudioSys::SetGlobalFadeVolume( 1.f - fCurrOpacity );
|
||||
|
||||
|
||||
fLastTime = (hsScalar)(time->DSeconds());
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
plTransitionMsg *effect = plTransitionMsg::ConvertNoRef( msg );
|
||||
if( effect != nil )
|
||||
{
|
||||
if( fRegisteredForTime )
|
||||
IStop( true );
|
||||
|
||||
for( i = 0; i < effect->GetNumCallbacks(); i++ )
|
||||
{
|
||||
plEventCallbackMsg *pMsg = effect->GetEventCallback( i );
|
||||
hsRefCnt_SafeRef( pMsg );
|
||||
fCallbacks.Append( pMsg );
|
||||
}
|
||||
|
||||
fHoldAtEnd = effect->GetHoldState();
|
||||
|
||||
fNoSoundFade = false;
|
||||
|
||||
switch(effect->GetEffect())
|
||||
{
|
||||
case plTransitionMsg::kFadeInNoSound:
|
||||
fNoSoundFade = true;
|
||||
case plTransitionMsg::kFadeIn:
|
||||
IStartFadeIn( effect->GetLengthInSecs(), kTransitionFadeIn );
|
||||
break;
|
||||
case plTransitionMsg::kFadeOutNoSound:
|
||||
fNoSoundFade = true;
|
||||
case plTransitionMsg::kFadeOut:
|
||||
IStartFadeOut( effect->GetLengthInSecs(), kTransitionFadeOut );
|
||||
break;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
plLinkEffectBCMsg *link = plLinkEffectBCMsg::ConvertNoRef( msg );
|
||||
if( link != nil )
|
||||
{
|
||||
const float kScreenFadeTime = 3.f; // seconds
|
||||
|
||||
// Go ahead and auto-trigger based on link FX messages
|
||||
if( plNetClientApp::GetInstance() != nil && link->fLinkKey == plNetClientApp::GetInstance()->GetLocalPlayerKey() )
|
||||
{
|
||||
if( fRegisteredForTime )
|
||||
IStop( true );
|
||||
|
||||
if( link->HasLinkFlag( plLinkEffectBCMsg::kLeavingAge ) )
|
||||
{
|
||||
plNetApp::GetInstance()->DebugMsg("Local player linking out, fading screen\n");
|
||||
|
||||
fHoldAtEnd = true;
|
||||
IStartFadeOut( kScreenFadeTime );
|
||||
}
|
||||
else
|
||||
{
|
||||
plNetApp::GetInstance()->DebugMsg("Local player linking in, fading screen\n");
|
||||
|
||||
fHoldAtEnd = false;
|
||||
IStartFadeIn( kScreenFadeTime );
|
||||
}
|
||||
|
||||
if (link->HasLinkFlag(plLinkEffectBCMsg::kSendCallback))
|
||||
{
|
||||
plLinkEffectsMgr *mgr;
|
||||
if( ( mgr = plLinkEffectsMgr::ConvertNoRef( link->GetSender()->ObjectIsLoaded() ) ) != nil )
|
||||
{
|
||||
plEventCallbackMsg *cback = plEventCallbackMsg::ConvertNoRef( mgr->WaitForEffect( link->fLinkKey ) );
|
||||
// hsRefCnt_SafeRef( cback ); // mgr has given us ownership, his ref is now ours. No need for another. -mf-
|
||||
fCallbacks.Append( cback );
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return hsKeyedObject::MsgReceive( msg );
|
||||
}
|
||||
|
@ -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/>.
|
||||
|
||||
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==*/
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// plTransitionMgr - Class to handle fullscreen transitions (fades, etc) //
|
||||
// //
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef _plTransitionMgr_h
|
||||
#define _plTransitionMgr_h
|
||||
|
||||
#include "hsTypes.h"
|
||||
#include "hsTemplates.h"
|
||||
#include "../pnKeyedObject/hsKeyedObject.h"
|
||||
#include "hsUtils.h"
|
||||
|
||||
|
||||
//// Class Definition ////////////////////////////////////////////////////////
|
||||
|
||||
class plPlate;
|
||||
class plEventCallbackMsg;
|
||||
|
||||
class plTransitionMgr : public hsKeyedObject
|
||||
{
|
||||
protected:
|
||||
|
||||
plPlate *fEffectPlate;
|
||||
|
||||
enum
|
||||
{
|
||||
kIdle,
|
||||
kFadeOut,
|
||||
kFadeIn,
|
||||
kTransitionFadeIn,
|
||||
kTransitionFadeOut
|
||||
};
|
||||
|
||||
UInt8 fCurrentEffect;
|
||||
hsBool fRegisteredForTime, fHoldAtEnd, fPlaying, fNoSoundFade;
|
||||
hsScalar fEffectLength, fCurrOpacity, fOpacDelta;
|
||||
hsScalar fLastTime;
|
||||
|
||||
void IStartFadeIn( hsScalar lengthInSecs, UInt8 effect = kFadeIn );
|
||||
void IStartFadeOut( hsScalar lengthInSecs, UInt8 effect = kFadeOut );
|
||||
|
||||
void ICreatePlate( void );
|
||||
|
||||
void IStop( hsBool aboutToStartAgain = false );
|
||||
|
||||
hsTArray<plEventCallbackMsg *> fCallbacks;
|
||||
|
||||
public:
|
||||
|
||||
plTransitionMgr();
|
||||
virtual ~plTransitionMgr();
|
||||
|
||||
CLASSNAME_REGISTER( plTransitionMgr );
|
||||
GETINTERFACE_ANY( plTransitionMgr, hsKeyedObject );
|
||||
|
||||
void Init( void );
|
||||
|
||||
virtual hsBool MsgReceive( plMessage* msg );
|
||||
};
|
||||
|
||||
|
||||
#endif //_plTransitionMgr_h
|
||||
|
@ -0,0 +1,447 @@
|
||||
/*==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/>.
|
||||
|
||||
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 "hsTypes.h"
|
||||
#include "plVertCoder.h"
|
||||
|
||||
#include "hsStream.h"
|
||||
|
||||
#include "plGBufferGroup.h"
|
||||
|
||||
const hsScalar kPosQuantum = 1.f / hsScalar(1 << 10);
|
||||
const hsScalar kWeightQuantum = 1.f / hsScalar(1 << 15);
|
||||
const hsScalar kUVWQuantum = 1.f / hsScalar(1 << 16);
|
||||
|
||||
UInt32 plVertCoder::fCodedVerts = 0;
|
||||
UInt32 plVertCoder::fCodedBytes = 0;
|
||||
UInt32 plVertCoder::fRawBytes = 0;
|
||||
UInt32 plVertCoder::fSkippedBytes = 0;
|
||||
|
||||
static const hsScalar kQuanta[plVertCoder::kNumFloatFields] =
|
||||
{
|
||||
kPosQuantum,
|
||||
kWeightQuantum,
|
||||
|
||||
kUVWQuantum,
|
||||
kUVWQuantum,
|
||||
kUVWQuantum,
|
||||
kUVWQuantum,
|
||||
|
||||
kUVWQuantum,
|
||||
kUVWQuantum,
|
||||
kUVWQuantum,
|
||||
kUVWQuantum,
|
||||
};
|
||||
|
||||
|
||||
inline void plVertCoder::ICountFloats(const UInt8* src, UInt16 maxCnt, const hsScalar quant, const UInt32 stride,
|
||||
hsScalar& lo, hsBool &allSame, UInt16& count)
|
||||
{
|
||||
lo = *(hsScalar*)src;
|
||||
lo = floor(lo / quant + 0.5f) * quant;
|
||||
allSame = false;
|
||||
hsScalar hi = lo;
|
||||
|
||||
count = 1;
|
||||
|
||||
const hsScalar maxRange = hsScalar(UInt16(0xffff)) * quant;
|
||||
|
||||
src += stride;
|
||||
maxCnt--;
|
||||
|
||||
while( maxCnt-- )
|
||||
{
|
||||
hsScalar val = *(hsScalar*)src;
|
||||
val = floor(val / quant + 0.5f) * quant;
|
||||
if( val < lo )
|
||||
{
|
||||
if( hi - val > maxRange )
|
||||
return;
|
||||
lo = val;
|
||||
}
|
||||
else if( val > hi )
|
||||
{
|
||||
if( val - lo > maxRange )
|
||||
return;
|
||||
hi = val;
|
||||
}
|
||||
count++;
|
||||
src += stride;
|
||||
}
|
||||
allSame = (lo == hi);
|
||||
}
|
||||
|
||||
static inline void IWriteFloat(hsStream* s, const UInt8*& src, const hsScalar offset, const hsScalar quantum)
|
||||
{
|
||||
float fval = *(float*)src;
|
||||
fval -= offset;
|
||||
fval /= quantum;
|
||||
// hsAssert(fval < hsScalar(UInt16(0xffff)), "Bad offset?");
|
||||
|
||||
const UInt16 ival = UInt16(floor(fval + 0.5f));
|
||||
s->WriteSwap16(ival);
|
||||
|
||||
src += 4;
|
||||
}
|
||||
|
||||
static inline void IReadFloat(hsStream* s, UInt8*& dst, const hsScalar offset, const hsScalar quantum)
|
||||
{
|
||||
const UInt16 ival = s->ReadSwap16();
|
||||
float fval = float(ival) * quantum;
|
||||
fval += offset;
|
||||
|
||||
hsScalar* val = (hsScalar*)dst;
|
||||
*val = fval;
|
||||
|
||||
dst += 4;
|
||||
}
|
||||
|
||||
inline void plVertCoder::IEncodeFloat(hsStream* s, const UInt32 vertsLeft, const int field, const int chan, const UInt8*& src, const UInt32 stride)
|
||||
{
|
||||
if( !fFloats[field][chan].fCount )
|
||||
{
|
||||
ICountFloats(src, (UInt16)vertsLeft, kQuanta[field], stride, fFloats[field][chan].fOffset, fFloats[field][chan].fAllSame, fFloats[field][chan].fCount);
|
||||
|
||||
s->WriteSwapScalar(fFloats[field][chan].fOffset);
|
||||
s->WriteBool(fFloats[field][chan].fAllSame);
|
||||
s->WriteSwap16(fFloats[field][chan].fCount);
|
||||
|
||||
}
|
||||
if (!fFloats[field][chan].fAllSame)
|
||||
IWriteFloat(s, src, fFloats[field][chan].fOffset, kQuanta[field]);
|
||||
else
|
||||
src += 4;
|
||||
|
||||
fFloats[field][chan].fCount--;
|
||||
}
|
||||
|
||||
inline void plVertCoder::IDecodeFloat(hsStream* s, const int field, const int chan, UInt8*& dst, const UInt32 stride)
|
||||
{
|
||||
if( !fFloats[field][chan].fCount )
|
||||
{
|
||||
fFloats[field][chan].fOffset = s->ReadSwapScalar();
|
||||
fFloats[field][chan].fAllSame = s->ReadBool();
|
||||
fFloats[field][chan].fCount = s->ReadSwap16();
|
||||
}
|
||||
|
||||
if (!fFloats[field][chan].fAllSame)
|
||||
IReadFloat(s, dst, fFloats[field][chan].fOffset, kQuanta[field]);
|
||||
else
|
||||
{
|
||||
*((hsScalar*)dst) = fFloats[field][chan].fOffset;
|
||||
dst += 4;
|
||||
}
|
||||
|
||||
fFloats[field][chan].fCount--;
|
||||
}
|
||||
|
||||
static inline int INumWeights(const UInt8 format)
|
||||
{
|
||||
return (format & plGBufferGroup::kSkinWeightMask) >> 4;
|
||||
}
|
||||
|
||||
static const hsScalar kNormalScale(Int16(0x7fff));
|
||||
static const hsScalar kInvNormalScale(1.f / kNormalScale);
|
||||
|
||||
inline void plVertCoder::IEncodeNormal(hsStream* s, const UInt8*& src, const UInt32 stride)
|
||||
{
|
||||
|
||||
hsScalar x = *(hsScalar*)src;
|
||||
s->WriteByte((UInt8)((x / 2.f + .5f) * 255.9f));
|
||||
src += 4;
|
||||
|
||||
x = *(hsScalar*)src;
|
||||
s->WriteByte((UInt8)((x / 2.f + .5f) * 255.9f));
|
||||
src += 4;
|
||||
|
||||
x = *(hsScalar*)src;
|
||||
s->WriteByte((UInt8)((x / 2.f + .5f) * 255.9f));
|
||||
src += 4;
|
||||
}
|
||||
|
||||
inline void plVertCoder::IDecodeNormal(hsStream* s, UInt8*& dst, const UInt32 stride)
|
||||
{
|
||||
|
||||
UInt8 ix = s->ReadByte();
|
||||
hsScalar* x = (hsScalar*)dst;
|
||||
*x = (ix / 255.9f - .5f) * 2.f;
|
||||
dst += 4;
|
||||
|
||||
ix = s->ReadByte();
|
||||
x = (hsScalar*)dst;
|
||||
*x = (ix / 255.9f - .5f) * 2.f;
|
||||
dst += 4;
|
||||
|
||||
ix = s->ReadByte();
|
||||
x = (hsScalar*)dst;
|
||||
*x = (ix / 255.9f - .5f) * 2.f;
|
||||
dst += 4;
|
||||
}
|
||||
|
||||
inline void plVertCoder::ICountBytes(const UInt32 vertsLeft, const UInt8* src, const UInt32 stride, UInt16& len, UInt8& same)
|
||||
{
|
||||
// We want to run length encode this. So we're looking here for either
|
||||
// the number of consecutive bytes of the same value,
|
||||
// or the number of consective bytes of different values.
|
||||
// The latter is so we don't wind up getting larger when there aren't any
|
||||
// runs of the same value (count=1 and val=c1, count=1 and val=c2, etc.).
|
||||
// The break-even point is a run of 3, so we'll look for a minimum run of 4.
|
||||
|
||||
if( vertsLeft < 4 )
|
||||
{
|
||||
len = (UInt16)vertsLeft;
|
||||
same = false;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// First, count how many values are the same as the first one
|
||||
int i;
|
||||
for( i = 0; i < vertsLeft; i++ )
|
||||
{
|
||||
if( src[i * stride] != src[0] )
|
||||
break;
|
||||
}
|
||||
|
||||
if( i >= 4 )
|
||||
{
|
||||
// Found a good run.
|
||||
len = i;
|
||||
same = true;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Okay, we're in a section of varying values. How far to the next
|
||||
// section of sameness?
|
||||
same = false;
|
||||
for( ; i < vertsLeft-4; i++ )
|
||||
{
|
||||
if( (src[i*stride] == src[(i+1)*stride])
|
||||
&&(src[i*stride] == src[(i+2)*stride])
|
||||
&&(src[i*stride] == src[(i+3)*stride]) )
|
||||
break;
|
||||
}
|
||||
|
||||
if( i < vertsLeft-4 )
|
||||
{
|
||||
len = i;
|
||||
return;
|
||||
}
|
||||
|
||||
len = (UInt16)vertsLeft;
|
||||
return;
|
||||
}
|
||||
|
||||
static const UInt16 kSameMask(0x8000);
|
||||
|
||||
inline void plVertCoder::IEncodeByte(hsStream* s, const int chan, const UInt32 vertsLeft, const UInt8*& src, const UInt32 stride)
|
||||
{
|
||||
if( !fColors[chan].fCount )
|
||||
{
|
||||
ICountBytes(vertsLeft, src, stride, fColors[chan].fCount, fColors[chan].fSame);
|
||||
|
||||
UInt16 cnt = fColors[chan].fCount;
|
||||
if( fColors[chan].fSame )
|
||||
cnt |= kSameMask;
|
||||
s->WriteSwap16(cnt);
|
||||
|
||||
if( fColors[chan].fSame )
|
||||
s->WriteByte(*src);
|
||||
}
|
||||
|
||||
if( !fColors[chan].fSame )
|
||||
s->WriteByte(*src);
|
||||
|
||||
src++;
|
||||
fColors[chan].fCount--;
|
||||
}
|
||||
|
||||
inline void plVertCoder::IDecodeByte(hsStream* s, const int chan, UInt8*& dst, const UInt32 stride)
|
||||
{
|
||||
if( !fColors[chan].fCount )
|
||||
{
|
||||
UInt16 cnt = s->ReadSwap16();
|
||||
if( cnt & kSameMask )
|
||||
{
|
||||
fColors[chan].fSame = true;
|
||||
fColors[chan].fVal = s->ReadByte();
|
||||
|
||||
cnt &= ~kSameMask;
|
||||
}
|
||||
else
|
||||
{
|
||||
fColors[chan].fSame = false;
|
||||
}
|
||||
fColors[chan].fCount = cnt;
|
||||
}
|
||||
if( !fColors[chan].fSame )
|
||||
*dst = s->ReadByte();
|
||||
else
|
||||
*dst = fColors[chan].fVal;
|
||||
|
||||
dst++;
|
||||
fColors[chan].fCount--;
|
||||
}
|
||||
|
||||
inline void plVertCoder::IEncodeColor(hsStream* s, const UInt32 vertsLeft, const UInt8*& src, const UInt32 stride)
|
||||
{
|
||||
IEncodeByte(s, 0, vertsLeft, src, stride);
|
||||
IEncodeByte(s, 1, vertsLeft, src, stride);
|
||||
IEncodeByte(s, 2, vertsLeft, src, stride);
|
||||
IEncodeByte(s, 3, vertsLeft, src, stride);
|
||||
}
|
||||
|
||||
inline void plVertCoder::IDecodeColor(hsStream* s, UInt8*& dst, const UInt32 stride)
|
||||
{
|
||||
IDecodeByte(s, 0, dst, stride);
|
||||
IDecodeByte(s, 1, dst, stride);
|
||||
IDecodeByte(s, 2, dst, stride);
|
||||
IDecodeByte(s, 3, dst, stride);
|
||||
}
|
||||
|
||||
inline void plVertCoder::IEncode(hsStream* s, const UInt32 vertsLeft, const UInt8*& src, const UInt32 stride, const UInt8 format)
|
||||
{
|
||||
IEncodeFloat(s, vertsLeft, kPosition, 0, src, stride);
|
||||
IEncodeFloat(s, vertsLeft, kPosition, 1, src, stride);
|
||||
IEncodeFloat(s, vertsLeft, kPosition, 2, src, stride);
|
||||
|
||||
// Weights and indices?
|
||||
const int numWeights = INumWeights(format);
|
||||
if( numWeights )
|
||||
{
|
||||
int j;
|
||||
for( j = 0; j < numWeights; j++ )
|
||||
IEncodeFloat(s, vertsLeft, kWeight, j, src, stride);
|
||||
|
||||
if( format & plGBufferGroup::kSkinIndices )
|
||||
{
|
||||
const UInt32 idx = *(UInt32*)src;
|
||||
s->WriteSwap32(idx);
|
||||
src += 4;
|
||||
}
|
||||
}
|
||||
|
||||
IEncodeNormal(s, src, stride);
|
||||
|
||||
IEncodeColor(s, vertsLeft, src, stride);
|
||||
|
||||
// COLOR2
|
||||
src += 4;
|
||||
|
||||
const int numUVWs = format & plGBufferGroup::kUVCountMask;
|
||||
int i;
|
||||
for( i = 0; i < numUVWs; i++ )
|
||||
{
|
||||
IEncodeFloat(s, vertsLeft, kUVW + i, 0, src, stride);
|
||||
IEncodeFloat(s, vertsLeft, kUVW + i, 1, src, stride);
|
||||
IEncodeFloat(s, vertsLeft, kUVW + i, 2, src, stride);
|
||||
}
|
||||
}
|
||||
|
||||
inline void plVertCoder::IDecode(hsStream* s, UInt8*& dst, const UInt32 stride, const UInt8 format)
|
||||
{
|
||||
IDecodeFloat(s, kPosition, 0, dst, stride);
|
||||
IDecodeFloat(s, kPosition, 1, dst, stride);
|
||||
IDecodeFloat(s, kPosition, 2, dst, stride);
|
||||
|
||||
// Weights and indices?
|
||||
const int numWeights = INumWeights(format);
|
||||
if( numWeights )
|
||||
{
|
||||
int j;
|
||||
for( j = 0; j < numWeights; j++ )
|
||||
IDecodeFloat(s, kWeight, j, dst, stride);
|
||||
|
||||
if( format & plGBufferGroup::kSkinIndices )
|
||||
{
|
||||
UInt32* idx = (UInt32*)dst;
|
||||
*idx = s->ReadSwap32();
|
||||
dst += 4;
|
||||
}
|
||||
}
|
||||
|
||||
IDecodeNormal(s, dst, stride);
|
||||
|
||||
IDecodeColor(s, dst, stride);
|
||||
|
||||
// COLOR2
|
||||
UInt32* trash = (UInt32*)dst;
|
||||
*trash = 0;
|
||||
dst += 4;
|
||||
|
||||
const int numUVWs = format & plGBufferGroup::kUVCountMask;
|
||||
int i;
|
||||
for( i = 0; i < numUVWs; i++ )
|
||||
{
|
||||
IDecodeFloat(s, kUVW + i, 0, dst, stride);
|
||||
IDecodeFloat(s, kUVW + i, 1, dst, stride);
|
||||
IDecodeFloat(s, kUVW + i, 2, dst, stride);
|
||||
}
|
||||
}
|
||||
|
||||
void plVertCoder::Read(hsStream* s, UInt8* dst, const UInt8 format, const UInt32 stride, const UInt16 numVerts)
|
||||
{
|
||||
Clear();
|
||||
|
||||
int i = numVerts;
|
||||
for( i = 0; i < numVerts; i++ )
|
||||
IDecode(s, dst, stride, format);
|
||||
}
|
||||
|
||||
|
||||
void plVertCoder::Write(hsStream* s, const UInt8* src, const UInt8 format, const UInt32 stride, const UInt16 numVerts)
|
||||
{
|
||||
Clear();
|
||||
|
||||
UInt32 streamStart = s->GetPosition();
|
||||
|
||||
int numLeft = numVerts;
|
||||
while( numLeft )
|
||||
{
|
||||
IEncode(s, numLeft, src, stride, format);
|
||||
numLeft--;
|
||||
}
|
||||
|
||||
fCodedVerts += numVerts;
|
||||
fCodedBytes += (s->GetPosition() - streamStart);
|
||||
fRawBytes += numVerts * stride;
|
||||
}
|
||||
|
||||
plVertCoder::plVertCoder()
|
||||
{
|
||||
Clear();
|
||||
}
|
||||
|
||||
plVertCoder::~plVertCoder()
|
||||
{
|
||||
}
|
||||
|
||||
void plVertCoder::Clear()
|
||||
{
|
||||
memset(this, 0, sizeof(*this));
|
||||
}
|
||||
|
@ -0,0 +1,106 @@
|
||||
/*==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/>.
|
||||
|
||||
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 plVertCoder_inc
|
||||
#define plVertCoder_inc
|
||||
|
||||
class hsStream;
|
||||
|
||||
class plVertCoder
|
||||
{
|
||||
public:
|
||||
enum {
|
||||
kPosition,
|
||||
kWeight,
|
||||
kUVW,
|
||||
kNumFloatFields = kUVW + 8
|
||||
};
|
||||
|
||||
protected:
|
||||
|
||||
class FloatCode
|
||||
{
|
||||
public:
|
||||
hsScalar fOffset;
|
||||
hsBool fAllSame;
|
||||
UInt16 fCount;
|
||||
};
|
||||
|
||||
FloatCode fFloats[kNumFloatFields][3];
|
||||
|
||||
class ByteCode
|
||||
{
|
||||
public:
|
||||
UInt16 fCount;
|
||||
UInt8 fVal;
|
||||
UInt8 fSame;
|
||||
};
|
||||
|
||||
ByteCode fColors[4];
|
||||
|
||||
static UInt32 fCodedVerts;
|
||||
static UInt32 fCodedBytes;
|
||||
static UInt32 fRawBytes;
|
||||
static UInt32 fSkippedBytes;
|
||||
|
||||
inline void ICountFloats(const UInt8* src, UInt16 maxCnt, const hsScalar quant, const UInt32 stride, hsScalar& lo, hsBool& allSame, UInt16& count);
|
||||
inline void IEncodeFloat(hsStream* s, const UInt32 vertsLeft, const int field, const int chan, const UInt8*& src, const UInt32 stride);
|
||||
inline void IDecodeFloat(hsStream* s, const int field, const int chan, UInt8*& dst, const UInt32 stride);
|
||||
|
||||
inline void IEncodeNormal(hsStream* s, const UInt8*& src, const UInt32 stride);
|
||||
inline void IDecodeNormal(hsStream* s, UInt8*& dst, const UInt32 stride);
|
||||
|
||||
inline void ICountBytes(const UInt32 vertsLeft, const UInt8* src, const UInt32 stride, UInt16& len, UInt8& same);
|
||||
inline void IEncodeByte(hsStream* s, const int chan, const UInt32 vertsLeft, const UInt8*& src, const UInt32 stride);
|
||||
inline void IDecodeByte(hsStream* s, const int chan, UInt8*& dst, const UInt32 stride);
|
||||
inline void IEncodeColor(hsStream* s, const UInt32 vertsLeft, const UInt8*& src, const UInt32 stride);
|
||||
inline void IDecodeColor(hsStream* s, UInt8*& dst, const UInt32 stride);
|
||||
|
||||
inline void IEncode(hsStream* s, const UInt32 vertsLeft, const UInt8*& src, const UInt32 stride, const UInt8 format);
|
||||
inline void IDecode(hsStream* s, UInt8*& dst, const UInt32 stride, const UInt8 format);
|
||||
|
||||
public:
|
||||
plVertCoder();
|
||||
~plVertCoder();
|
||||
|
||||
void Clear();
|
||||
|
||||
void Read(hsStream* s, UInt8* dst, const UInt8 format, const UInt32 stride, const UInt16 numVerts);
|
||||
void Write(hsStream* s, const UInt8* src, const UInt8 format, const UInt32 stride, const UInt16 numVerts);
|
||||
|
||||
|
||||
static void ClearAverage() { fCodedVerts = 0; fCodedBytes = 0; fRawBytes = 0; fSkippedBytes = 0; }
|
||||
static UInt32 CodedBytes() { return fCodedBytes; }
|
||||
static UInt32 RawBytes() { return fRawBytes; }
|
||||
static UInt32 CodedVerts() { return fCodedVerts; }
|
||||
static float AverageCodedVertSize() { return fCodedVerts ? float(fCodedBytes) / float(fCodedVerts) : 0; }
|
||||
static float AverageRawVertSize() { return fCodedVerts ? float(fRawBytes) / float(fCodedVerts) : 0; }
|
||||
|
||||
static UInt32 SkippedBytes() { return fSkippedBytes; }
|
||||
static void AddSkippedBytes(UInt32 f) { fSkippedBytes += f; }
|
||||
};
|
||||
|
||||
#endif // plVertCoder_inc
|
Reference in New Issue
Block a user