2
3
mirror of https://foundry.openuru.org/gitblit/r/CWE-ou-minkata.git synced 2025-07-14 02:27:40 -04:00

CWE Directory Reorganization

Rearrange directory structure of CWE to be loosely equivalent to
the H'uru Plasma repository.

Part 1: Movement of directories and files.
This commit is contained in:
rarified
2021-05-15 12:49:46 -06:00
parent c3f4a640a3
commit 96903e8dca
4002 changed files with 159 additions and 644 deletions

View File

@ -0,0 +1,151 @@
/*==LICENSE==*
CyanWorlds.com Engine - MMOG client, server and tools
Copyright (C) 2011 Cyan Worlds, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
You can contact Cyan Worlds, Inc. by email legal@cyan.com
or by snail mail at:
Cyan Worlds, Inc.
14617 N Newport Hwy
Mead, WA 99021
*==LICENSE==*/
#ifndef 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

View File

@ -0,0 +1,484 @@
/*==LICENSE==*
CyanWorlds.com Engine - MMOG client, server and tools
Copyright (C) 2011 Cyan Worlds, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
You can contact Cyan Worlds, Inc. by email legal@cyan.com
or by snail mail at:
Cyan Worlds, Inc.
14617 N Newport Hwy
Mead, WA 99021
*==LICENSE==*/
///////////////////////////////////////////////////////////////////////////////
// //
// 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

View File

@ -0,0 +1,85 @@
/*==LICENSE==*
CyanWorlds.com Engine - MMOG client, server and tools
Copyright (C) 2011 Cyan Worlds, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
You can contact Cyan Worlds, Inc. by email legal@cyan.com
or by snail mail at:
Cyan Worlds, Inc.
14617 N Newport Hwy
Mead, WA 99021
*==LICENSE==*/
#include "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);
}
}

View File

@ -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/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
You can contact Cyan Worlds, Inc. by email legal@cyan.com
or by snail mail at:
Cyan Worlds, Inc.
14617 N Newport Hwy
Mead, WA 99021
*==LICENSE==*/
#ifndef 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

View File

@ -0,0 +1,73 @@
/*==LICENSE==*
CyanWorlds.com Engine - MMOG client, server and tools
Copyright (C) 2011 Cyan Worlds, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
You can contact Cyan Worlds, Inc. by email legal@cyan.com
or by snail mail at:
Cyan Worlds, Inc.
14617 N Newport Hwy
Mead, WA 99021
*==LICENSE==*/
#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;
}

View File

@ -0,0 +1,59 @@
/*==LICENSE==*
CyanWorlds.com Engine - MMOG client, server and tools
Copyright (C) 2011 Cyan Worlds, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
You can contact Cyan Worlds, Inc. by email legal@cyan.com
or by snail mail at:
Cyan Worlds, Inc.
14617 N Newport Hwy
Mead, WA 99021
*==LICENSE==*/
#ifndef hsGDDrawDllLoad_inc
#define hsGDDrawDllLoad_inc
class hsGDDrawDllLoad
{
private:
HMODULE fD3DDll;
public:
hsGDDrawDllLoad();
~hsGDDrawDllLoad();
static HMODULE GetD3DDll();
};
#endif hsGDDrawDllLoad_inc

View File

@ -0,0 +1,77 @@
/*==LICENSE==*
CyanWorlds.com Engine - MMOG client, server and tools
Copyright (C) 2011 Cyan Worlds, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
You can contact Cyan Worlds, Inc. by email legal@cyan.com
or by snail mail at:
Cyan Worlds, Inc.
14617 N Newport Hwy
Mead, WA 99021
*==LICENSE==*/
///////////////////////////////////////////////////////////////////////////////
// //
// 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

View File

@ -0,0 +1,289 @@
/*==LICENSE==*
CyanWorlds.com Engine - MMOG client, server and tools
Copyright (C) 2011 Cyan Worlds, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
You can contact Cyan Worlds, Inc. by email legal@cyan.com
or by snail mail at:
Cyan Worlds, Inc.
14617 N Newport Hwy
Mead, WA 99021
*==LICENSE==*/
#ifndef 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

View File

@ -0,0 +1,62 @@
/*==LICENSE==*
CyanWorlds.com Engine - MMOG client, server and tools
Copyright (C) 2011 Cyan Worlds, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
You can contact Cyan Worlds, Inc. by email legal@cyan.com
or by snail mail at:
Cyan Worlds, Inc.
14617 N Newport Hwy
Mead, WA 99021
*==LICENSE==*/
#ifndef 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

View File

@ -0,0 +1,132 @@
/*==LICENSE==*
CyanWorlds.com Engine - MMOG client, server and tools
Copyright (C) 2011 Cyan Worlds, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
You can contact Cyan Worlds, Inc. by email legal@cyan.com
or by snail mail at:
Cyan Worlds, Inc.
14617 N Newport Hwy
Mead, WA 99021
*==LICENSE==*/
#ifndef plBinkPlayer_inc
#define plBinkPlayer_inc
#include "HeadSpin.h"
#include "hsPoint2.h"
#include "hsTemplates.h"
struct D3DVertex;
class plDXPipeline;
struct IDirect3DTexture9;
class plMessage;
struct IDirectSound8;
class plBinkPlayer
{
public:
plBinkPlayer() : fFileName(nil) { }
~plBinkPlayer() { delete [] fFileName; }
static bool Init( hsWindowHndl hWnd) { return true; }
static bool DeInit() { return true; }
static void SetForeGroundTrack(UInt32 t) { }
static void SetBackGroundTrack(UInt32 t) { }
static UInt32 GetForeGroundTrack() { }
static UInt32 GetBackGroundTrack() { }
void SetDefaults() { }
bool Start(plPipeline* pipe, hsWindowHndl hWnd) { return false; }
bool NextFrame() {
// we have reached the end
return Stop();
}
bool Pause(bool on) { return false; }
bool Stop() {
for (int i = 0; i < fCallbacks.GetCount(); i++)
fCallbacks[i]->Send();
fCallbacks.Reset();
delete [] fFileName;
fFileName = nil;
return false;
}
void SetFileName(const char* filename) {
delete [] fFileName;
fFileName = hsStrcpy(filename);
}
void SetColor(const hsColorRGBA& c) { }
void SetPosition(float x, float y) { }
void SetScale(float x, float y) { }
void SetVolume(float v) { }
void SetForeVolume(float v) { }
void SetBackVolume(float v) { }
void SetPosition(const hsPoint2& p) { }
void SetScale(const hsPoint2& s) { }
const char* GetFileName() const { return fFileName; }
const hsColorRGBA GetColor() const { return hsColorRGBA(); }
const hsPoint2 GetPosition() const { return hsPoint2(); }
const hsPoint2 GetScale() const { return hsPoint2(); }
float GetBackVolume() const { return 0.0f; }
float GetForeVolume() const { return 0.0f; }
void AddCallback(plMessage* msg) { hsRefCnt_SafeRef(msg); fCallbacks.Append(msg); }
UInt32 GetNumCallbacks() const { return 0; }
plMessage* GetCallback(int i) const { return nil; }
void SetFadeFromTime(float secs) { }
void SetFadeFromColor(hsColorRGBA c) { }
void SetFadeToTime(float secs) { }
void SetFadeToColor(hsColorRGBA c) { }
float GetFadeFromTime() const { return 0.0f; }
hsColorRGBA GetFadeFromColor() const { return hsColorRGBA(); }
float GetFadeToTime() const { return 0.0f; }
hsColorRGBA GetFadeToColor() const { return hsColorRGBA(); }
private:
char* fFileName;
hsTArray<plMessage*> fCallbacks;
};
#endif // plBinkPlayer_inc

View File

@ -0,0 +1,237 @@
/*==LICENSE==*
CyanWorlds.com Engine - MMOG client, server and tools
Copyright (C) 2011 Cyan Worlds, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
You can contact Cyan Worlds, Inc. by email legal@cyan.com
or by snail mail at:
Cyan Worlds, Inc.
14617 N Newport Hwy
Mead, WA 99021
*==LICENSE==*/
#include "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
pfGameGUIMgr::GetInstance()->SetAspectRatio((float)fRenderTarget->GetWidth() / (float)fRenderTarget->GetHeight());
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);
}
}
pfGameGUIMgr::GetInstance()->SetAspectRatio((float)pipe->Width() / (float)pipe->Height());
// 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

View File

@ -0,0 +1,109 @@
/*==LICENSE==*
CyanWorlds.com Engine - MMOG client, server and tools
Copyright (C) 2011 Cyan Worlds, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
You can contact Cyan Worlds, Inc. by email legal@cyan.com
or by snail mail at:
Cyan Worlds, Inc.
14617 N Newport Hwy
Mead, WA 99021
*==LICENSE==*/
#ifndef 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

View File

@ -0,0 +1,137 @@
/*==LICENSE==*
CyanWorlds.com Engine - MMOG client, server and tools
Copyright (C) 2011 Cyan Worlds, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
You can contact Cyan Worlds, Inc. by email legal@cyan.com
or by snail mail at:
Cyan Worlds, Inc.
14617 N Newport Hwy
Mead, WA 99021
*==LICENSE==*/
///////////////////////////////////////////////////////////////////////////////
// //
// 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

View File

@ -0,0 +1,259 @@
/*==LICENSE==*
CyanWorlds.com Engine - MMOG client, server and tools
Copyright (C) 2011 Cyan Worlds, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
You can contact Cyan Worlds, Inc. by email legal@cyan.com
or by snail mail at:
Cyan Worlds, Inc.
14617 N Newport Hwy
Mead, WA 99021
*==LICENSE==*/
///////////////////////////////////////////////////////////////////////////////
// //
// 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
}

View File

@ -0,0 +1,103 @@
/*==LICENSE==*
CyanWorlds.com Engine - MMOG client, server and tools
Copyright (C) 2011 Cyan Worlds, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
You can contact Cyan Worlds, Inc. by email legal@cyan.com
or by snail mail at:
Cyan Worlds, Inc.
14617 N Newport Hwy
Mead, WA 99021
*==LICENSE==*/
///////////////////////////////////////////////////////////////////////////////
// //
// 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

View File

@ -0,0 +1,223 @@
/*==LICENSE==*
CyanWorlds.com Engine - MMOG client, server and tools
Copyright (C) 2011 Cyan Worlds, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
You can contact Cyan Worlds, Inc. by email legal@cyan.com
or by snail mail at:
Cyan Worlds, Inc.
14617 N Newport Hwy
Mead, WA 99021
*==LICENSE==*/
#ifndef 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

View File

@ -0,0 +1,60 @@
/*==LICENSE==*
CyanWorlds.com Engine - MMOG client, server and tools
Copyright (C) 2011 Cyan Worlds, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
You can contact Cyan Worlds, Inc. by email legal@cyan.com
or by snail mail at:
Cyan Worlds, Inc.
14617 N Newport Hwy
Mead, WA 99021
*==LICENSE==*/
#ifndef 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

View File

@ -0,0 +1,252 @@
/*==LICENSE==*
CyanWorlds.com Engine - MMOG client, server and tools
Copyright (C) 2011 Cyan Worlds, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
You can contact Cyan Worlds, Inc. by email legal@cyan.com
or by snail mail at:
Cyan Worlds, Inc.
14617 N Newport Hwy
Mead, WA 99021
*==LICENSE==*/
//////////////////////////////////////////////////////////////////////////////
// //
// 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 "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->CreateFromResource(plProgressMgr::GetStaticTextID(fCurrentStaticText));
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->CreateFromResource(plProgressMgr::GetLoadingFrameID(fCurrentImage));
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->ReloadFromResource(plProgressMgr::GetLoadingFrameID(fCurrentImage));
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 );
}
}

View File

@ -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/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
You can contact Cyan Worlds, Inc. by email legal@cyan.com
or by snail mail at:
Cyan Worlds, Inc.
14617 N Newport Hwy
Mead, WA 99021
*==LICENSE==*/
//////////////////////////////////////////////////////////////////////////////
// //
// 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

View File

@ -0,0 +1,171 @@
/*==LICENSE==*
CyanWorlds.com Engine - MMOG client, server and tools
Copyright (C) 2011 Cyan Worlds, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
You can contact Cyan Worlds, Inc. by email legal@cyan.com
or by snail mail at:
Cyan Worlds, Inc.
14617 N Newport Hwy
Mead, WA 99021
*==LICENSE==*/
///////////////////////////////////////////////////////////////////////////////
// //
// plDXBufferRefs.h - Hardware Vertex and Index Buffer DeviceRef //
// Definitions //
// Cyan, Inc. //
// //
//// Version History //////////////////////////////////////////////////////////
// //
// 4.25.2001 mcn - Created. //
// //
///////////////////////////////////////////////////////////////////////////////
#ifndef _plDXBufferRefs_h
#define _plDXBufferRefs_h
#include "hsMatrix44.h"
#include "hsGeometry3.h"
#include "hsTemplates.h"
#include "plDXDeviceRef.h"
struct IDirect3DVertexShader9;
//// Definitions //////////////////////////////////////////////////////////////
class plDXVertexBufferRef : public plDXDeviceRef
{
public:
IDirect3DVertexBuffer9* fD3DBuffer;
UInt32 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

View File

@ -0,0 +1,82 @@
/*==LICENSE==*
CyanWorlds.com Engine - MMOG client, server and tools
Copyright (C) 2011 Cyan Worlds, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
You can contact Cyan Worlds, Inc. by email legal@cyan.com
or by snail mail at:
Cyan Worlds, Inc.
14617 N Newport Hwy
Mead, WA 99021
*==LICENSE==*/
///////////////////////////////////////////////////////////////////////////////
// //
// plDXDeviceRef.h - Header for the generic DX DeviceRef type //
// Cyan, Inc. //
// //
//// Version History //////////////////////////////////////////////////////////
// //
// 4.25.2001 mcn - Created. //
// //
///////////////////////////////////////////////////////////////////////////////
#ifndef _plDXDeviceRef_h
#define _plDXDeviceRef_h
#include "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

View File

@ -0,0 +1,530 @@
/*==LICENSE==*
CyanWorlds.com Engine - MMOG client, server and tools
Copyright (C) 2011 Cyan Worlds, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
You can contact Cyan Worlds, Inc. by email legal@cyan.com
or by snail mail at:
Cyan Worlds, Inc.
14617 N Newport Hwy
Mead, WA 99021
*==LICENSE==*/
///////////////////////////////////////////////////////////////////////////////
// //
// plDXDeviceRefs.cpp - Functions for the various DX DeviceRef classes //
// Cyan, Inc. //
// //
//// Version History //////////////////////////////////////////////////////////
// //
// 4.25.2001 mcn - Created. //
// //
///////////////////////////////////////////////////////////////////////////////
#include "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 );
}

View File

@ -0,0 +1,909 @@
/*==LICENSE==*
CyanWorlds.com Engine - MMOG client, server and tools
Copyright (C) 2011 Cyan Worlds, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
You can contact Cyan Worlds, Inc. by email legal@cyan.com
or by snail mail at:
Cyan Worlds, Inc.
14617 N Newport Hwy
Mead, WA 99021
*==LICENSE==*/
#include "plDXEnumerate.h"
#include <ddraw.h>
#include "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 );
}
}

View File

@ -0,0 +1,200 @@
/*==LICENSE==*
CyanWorlds.com Engine - MMOG client, server and tools
Copyright (C) 2011 Cyan Worlds, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
You can contact Cyan Worlds, Inc. by email legal@cyan.com
or by snail mail at:
Cyan Worlds, Inc.
14617 N Newport Hwy
Mead, WA 99021
*==LICENSE==*/
#ifndef hsGDirect3DTnLEnumerate_h
#define hsGDirect3DTnLEnumerate_h
#include "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

View File

@ -0,0 +1,97 @@
/*==LICENSE==*
CyanWorlds.com Engine - MMOG client, server and tools
Copyright (C) 2011 Cyan Worlds, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
You can contact Cyan Worlds, Inc. by email legal@cyan.com
or by snail mail at:
Cyan Worlds, Inc.
14617 N Newport Hwy
Mead, WA 99021
*==LICENSE==*/
///////////////////////////////////////////////////////////////////////////////
// //
// plDXLightRef.h - Hardware Light DeviceRef Definition //
// Cyan, Inc. //
// //
//// Version History //////////////////////////////////////////////////////////
// //
// 4.25.2001 mcn - Created. //
// //
///////////////////////////////////////////////////////////////////////////////
#ifndef _plDXLightRef_h
#define _plDXLightRef_h
#include "hsMatrix44.h"
#include "hsGeometry3.h"
#include "hsTemplates.h"
#include "plDXDeviceRef.h"
//// Definition ///////////////////////////////////////////////////////////////
class plLightInfo;
class plDXLightSettings;
class plDXLightRef : public plDXDeviceRef
{
public:
plLightInfo *fOwner;
D3DLIGHT9 fD3DInfo;
UInt32 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

View File

@ -0,0 +1,834 @@
/*==LICENSE==*
CyanWorlds.com Engine - MMOG client, server and tools
Copyright (C) 2011 Cyan Worlds, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
You can contact Cyan Worlds, Inc. by email legal@cyan.com
or by snail mail at:
Cyan Worlds, Inc.
14617 N Newport Hwy
Mead, WA 99021
*==LICENSE==*/
#ifndef _plDX9Pipeline_h
#define _plDX9Pipeline_h
#include "plPipeline.h"
#include "plDXSettings.h"
#include "../plSurface/plLayerInterface.h"
#include "hsMatrix44.h"
#include "plFogEnvironment.h"
#include "hsG3DDeviceSelector.h"
#include "hsGeometry3.h"
#include "hsTemplates.h"
#include "hsColorRGBA.h"
#include "hsGDeviceRef.h"
#include "hsPoint2.h"
class plAccessSpan;
class plAuxSpan;
class plVertexSpan;
#include "plPlates.h" // Used to define plDXPlateManager
//// Defines and Konstants and Other Nifty Stuff //////////////////////////////
class plDXLightRef;
class plDXVertexBufferRef;
class plDXIndexBufferRef;
class plDXTextureRef;
class plDXCubeTextureRef;
class plDXVertexShader;
class plDXPixelShader;
class plShader;
class plVisMgr;
//#define HS_D3D_USE_SPECULAR
class hsGMaterial;
class plMipmap;
class plLightInfo;
class plCullTree;
class plShadowSlave;
class plShadowCaster;
struct D3DXMATRIX;
#ifdef HS_DEBUGGING
#define HS_CHECK_RELEASE
#endif
#ifndef PLASMA_EXTERNAL_RELEASE
#define PROFILE_POOL_MEM(pool, size, add, id) plDXPipeline::ProfilePoolMem(pool, size, add, id);
#else
#define PROFILE_POOL_MEM(pool, size, add, id)
#endif // PLASMA_EXTERNAL_RELEASE
extern void D3DSURF_MEMNEW(IDirect3DSurface9* surf);
extern void D3DSURF_MEMNEW(IDirect3DTexture9* tex);
extern void D3DSURF_MEMNEW(IDirect3DCubeTexture9* cTex);
extern void D3DSURF_MEMDEL(IDirect3DSurface9* surf);
extern void D3DSURF_MEMDEL(IDirect3DTexture9* tex);
extern void D3DSURF_MEMDEL(IDirect3DCubeTexture9* cTex);
extern void plReleaseObject(IUnknown* x);
#define ReleaseObject(x) if(x){ plReleaseObject(x); x=NULL; }
typedef LPDIRECT3D9 (WINAPI * Direct3DCreateProc)( UINT sdkVersion );
//// Helper Classes ///////////////////////////////////////////////////////////
//// The RenderPrimFunc lets you have one function which does a lot of stuff
// around the actual call to render whatever type of primitives you have, instead
// of duplicating everything because the one line to render is different.
class plRenderPrimFunc
{
public:
virtual hsBool RenderPrims() const = 0; // return true on error
};
//// DX-specific Plate Manager implementation
class plDXPlateManager : public plPlateManager
{
friend class plDXPipeline;
public:
virtual ~plDXPlateManager();
protected:
const long PLD3D_PLATEFVF;
struct plPlateVertex
{
hsPoint3 fPoint;
UInt32 fColor;
hsPoint3 fUV;
};
IDirect3DDevice9 *fD3DDevice;
IDirect3DVertexBuffer9 *fVertBuffer;
plDXPlateManager( plDXPipeline *pipe, IDirect3DDevice9 *device );
void ICreateGeometry(plDXPipeline* pipe);
void IReleaseGeometry();
virtual void IDrawToDevice( plPipeline *pipe );
};
//// Class Definition /////////////////////////////////////////////////////////
class plDebugTextManager;
struct D3DEnum_DriverInfo;
struct D3DEnum_DeviceInfo;
struct D3DEnum_ModeInfo;
class plGeometrySpan;
class plDrawableSpans;
class plSpan;
class plIcicle;
class hsG3DDeviceModeRecord;
class plDXDeviceRef;
class plParticleSpan;
class plCubicEnvironmap;
class plDXRenderTargetRef;
class plStatusLogDrawer;
class plBinkPlayer;
class plDXPipeline : public plPipeline
{
protected:
enum {
kCapsNone = 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,
const UInt8 *src, UInt8 format, UInt32 srcStride,
UInt8 *dest, UInt32 destStride, UInt32 count, UInt16 localUVWChans );
hsBool ISoftwareVertexBlend( plDrawableSpans* drawable, const hsTArray<Int16>& visList );
void ILinkDevRef( plDXDeviceRef *ref, plDXDeviceRef **refList );
void IUnlinkDevRef( plDXDeviceRef *ref );
// Properties
inline DWORD inlGetD3DColor( const hsColorRGBA &c ) const;
inline D3DCOLORVALUE inlPlToD3DColor(const hsColorRGBA& c, float a) const;
// Error handling
void IAddErrorMessage( char *errStr );
void ISetErrorMessage( char *errStr = nil );
void IGetD3DError();
void IShowErrorMessage( char *errStr = nil );
hsBool ICreateFail( char *errStr );
// FPU mode check
void IFPUCheck();
// Device initialization
void IInvalidateState();
void IInitDeviceState();
void IClearMembers();
void ISetCaps();
void IRestrictCaps( const hsG3DDeviceRecord& devRec );
void ISetGraphicsCapability(UInt32 v);
hsBool IFindDepthFormat(D3DPRESENT_PARAMETERS& params);
hsBool IFindCompressedFormats();
hsBool IFindLuminanceFormats();
hsBool ITextureFormatAllowed( D3DFORMAT format );
void ISetCurrentDriver( D3DEnum_DriverInfo *driv );
void ISetCurrentDevice( D3DEnum_DeviceInfo *dev );
void ISetCurrentMode( D3DEnum_ModeInfo *mode );
hsBool ICreateMaster();
hsBool ICreateDevice(hsBool windowed);
hsBool ICreateNormalSurfaces();
hsBool ICreateDeviceObjects();
void IReleaseDeviceObjects();
hsBool ICreateDynDeviceObjects();
void IReleaseDynDeviceObjects();
void IReleaseShaders();
hsBool IResetDevice();
// View and clipping
void ISetViewport();
void IUpdateViewVectors() const;
void IRefreshCullTree();
void ISetAnisotropy(hsBool on);
// Transforms
D3DXMATRIX& IMatrix44ToD3DMatrix( D3DXMATRIX& dst, const hsMatrix44& src );
void ITransformsToD3D();
hsMatrix44 IGetCameraToNDC();
void IProjectionMatrixToD3D();
void IWorldToCameraToD3D();
void ILocalToWorldToD3D();
void ISavageYonHack();
void ISetLocalToWorld( const hsMatrix44& l2w, const hsMatrix44& w2l );
void ISetCullMode(hsBool flip=false);
hsBool inline IIsViewLeftHanded();
hsBool IGetClearViewPort(D3DRECT& r);
plViewTransform& IGetViewTransform() { return fView.fTransform; }
void IUpdateViewFlags();
void ISetupTransforms(plDrawableSpans* drawable, const plSpan& span, hsMatrix44& lastL2W);
// Plate management
friend plDXPlateManager;
friend plBinkPlayer;
void IDrawPlate( plPlate *plate );
void ISetRenderTarget( plRenderTarget *target );
hsBool IPrepRenderTargetInfo( plRenderTarget *owner, D3DFORMAT &surfFormat,
D3DFORMAT &depthFormat, D3DRESOURCETYPE &resType );
hsBool IFindRenderTargetInfo( plRenderTarget *owner, D3DFORMAT &surfFormat, D3DRESOURCETYPE &resType );
// From a D3DFORMAT enumeration, return the string literal for it
static const char *IGetDXFormatName( D3DFORMAT format );
/////// Shadow internals
// Generation
void IClearShadowSlaves();
void IPreprocessShadows();
hsBool IPrepShadowCaster(const plShadowCaster* caster);
void IRenderShadowCasterSpan(plShadowSlave* slave, plDrawableSpans* drawable, const plIcicle& span);
void ISetupShadowCastTextureStages(plShadowSlave* slave);
hsBool IRenderShadowCaster(plShadowSlave* slave);
void ISetupShadowLight(plShadowSlave* slave);
plDXLightRef* INextShadowLight(plShadowSlave* slave);
hsBool IPushShadowCastState(plShadowSlave* slave);
hsBool IPopShadowCastState(plShadowSlave* slave);
plDXTextureRef* IGetULutTextureRef();
hsBool ICreateBlurVBuffers();
void IReleaseBlurVBuffers();
void IMakeRenderTargetPools();
void IResetRenderTargetPools();
plRenderTarget* IFindRenderTarget(UInt32& w, UInt32& h, hsBool ortho);
void IReleaseRenderTargetPools();
// Selection
void IAttachSlaveToReceivers(int iSlave, plDrawableSpans* drawable, const hsTArray<Int16>& visList);
void IAttachShadowsToReceivers(plDrawableSpans* drawable, const hsTArray<Int16>& visList);
hsBool IAcceptsShadow(const plSpan* span, plShadowSlave* slave);
hsBool IReceivesShadows(const plSpan* span, hsGMaterial* mat);
void ISetShadowFromGroup(plDrawableSpans* drawable, const plSpan* span, plLightInfo* liInfo);
// Application
void IRenderShadowsOntoSpan(const plRenderPrimFunc& render, const plSpan* span, hsGMaterial* mat);
void ISetupShadowRcvTextureStages(hsGMaterial* mat);
void ISetShadowLightState(hsGMaterial* mat);
void IDisableLightsForShadow();
void IEnableShadowLight(plShadowSlave* slave);
void ISetupShadowSlaveTextures(plShadowSlave* slave);
// Postprocess (blurring)
hsBool ISetBlurQuadToRender(plRenderTarget* smap);
void IRenderBlurBackToShadowMap(plRenderTarget* smap, plRenderTarget* scratch, plRenderTarget* dst);
void IRenderBlurFromShadowMap(plRenderTarget* scratchRT, plRenderTarget* smap, hsScalar scale);
void IBlurSetRenderTarget(plRenderTarget* rt);
int IGetScratchRenderTarget(plRenderTarget* smap);
void IBlurShadowMap(plShadowSlave* slave);
// Avatar Texture Rendering
double fAvRTShrinkValidSince;
hsTArray<plRenderTarget*> fAvRTPool;
UInt16 fAvRTWidth;
UInt32 fAvNextFreeRT;
void IFillAvRTPool();
hsBool IFillAvRTPool(UInt16 numRTs, UInt16 width); // Returns true if we successfully filled the pool. Otherwise cleans up.
void IReleaseAvRTPool();
plRenderTarget* IGetNextAvRT();
void IFreeAvRT(plRenderTarget* tex);
void IPreprocessAvatarTextures();
void IDrawClothingQuad(hsScalar x, hsScalar y, hsScalar w, hsScalar h, hsScalar uOff, hsScalar vOff, plMipmap *tex);
void IClearClothingOutfits(hsTArray<plClothingOutfit*>* outfits);
void IPrintDeviceInitError();
void IResetToDefaults(D3DPRESENT_PARAMETERS *params);
public:
plDXPipeline( hsWinRef hWnd, const hsG3DDeviceModeRecord *devMode );
virtual ~plDXPipeline();
CLASSNAME_REGISTER( plDXPipeline );
GETINTERFACE_ANY( plDXPipeline, plPipeline );
virtual IDirect3DDevice9* GetD3DDevice() const { return fD3DDevice; }
// Typical 3D device
virtual hsBool PreRender(plDrawable* drawable, hsTArray<Int16>& visList, plVisMgr* visMgr=nil);
virtual hsBool PrepForRender(plDrawable* drawable, hsTArray<Int16>& visList, plVisMgr* visMgr=nil);
virtual void Render(plDrawable* d, const hsTArray<Int16>& visList);
virtual void Draw(plDrawable* d);
virtual void PushRenderRequest(plRenderRequest* req);
virtual void PopRenderRequest(plRenderRequest* req);
void ResetDisplayDevice(int Width, int Height, int ColorDepth, hsBool Windowed, int NumAASamples, int MaxAnisotropicSamples, hsBool VSync = false );
virtual void ClearRenderTarget( plDrawable* d );
virtual void ClearRenderTarget( const hsColorRGBA* col = nil, const hsScalar* depth = nil );
virtual void SetClear(const hsColorRGBA* col=nil, const hsScalar* depth=nil);
virtual hsColorRGBA GetClearColor() const;
virtual hsScalar GetClearDepth() const;
virtual hsGDeviceRef* MakeRenderTargetRef( plRenderTarget *owner );
virtual hsGDeviceRef* SharedRenderTargetRef(plRenderTarget* sharer, plRenderTarget *owner);
virtual void PushRenderTarget( plRenderTarget *target );
virtual plRenderTarget* PopRenderTarget();
virtual hsBool BeginRender();
virtual hsBool EndRender();
virtual void RenderScreenElements();
virtual hsBool BeginDrawable(plDrawable* d);
virtual hsBool EndDrawable(plDrawable* d);
virtual void BeginVisMgr(plVisMgr* visMgr);
virtual void EndVisMgr(plVisMgr* visMgr);
virtual hsBool IsFullScreen() const { return fSettings.fFullscreen; }
virtual UInt32 Width() const { return fView.fTransform.GetViewPortWidth(); }
virtual UInt32 Height() const { return fView.fTransform.GetViewPortHeight(); }
virtual UInt32 ColorDepth() const { return fSettings.fColorDepth; }
virtual void Resize( UInt32 width, UInt32 height );
// Culling. Might be used in Update before bothering to do any serious computation.
virtual hsBool TestVisibleWorld(const hsBounds3Ext& wBnd);
virtual hsBool TestVisibleWorld(const plSceneObject* sObj);
virtual hsBool HarvestVisible(plSpaceTree* space, hsTArray<Int16>& visList);
virtual hsBool SubmitOccluders(const hsTArray<const plCullPoly*>& polyList);
// Debug flags
virtual void SetDebugFlag( UInt32 flag, hsBool on );
virtual hsBool IsDebugFlagSet( UInt32 flag ) const;
// These are also only for debugging.
virtual void SetMaxCullNodes(UInt16 n) { fView.fCullMaxNodes = n; }
virtual UInt16 GetMaxCullNodes() const { return fView.fCullMaxNodes; }
virtual hsBool CheckResources();
virtual void LoadResources(); // Tells us where it's a good time to load in unmanaged resources.
// Properties
virtual void SetProperty( UInt32 prop, hsBool on ) { on ? fSettings.fProperties |= prop : fSettings.fProperties &= ~prop; }
virtual hsBool GetProperty( UInt32 prop ) const { return ( fSettings.fProperties & prop ) ? true : false; }
virtual UInt32 GetMaxLayersAtOnce() const { return fSettings.fMaxLayersAtOnce; }
// Drawable type mask
virtual void SetDrawableTypeMask( UInt32 mask ) { fView.fDrawableTypeMask = mask; }
virtual UInt32 GetDrawableTypeMask() const { return fView.fDrawableTypeMask; }
virtual void SetSubDrawableTypeMask( UInt32 mask ) { fView.fSubDrawableTypeMask = mask; }
virtual UInt32 GetSubDrawableTypeMask() const { return fView.fSubDrawableTypeMask; }
// Create a debug text font object
virtual plTextFont *MakeTextFont( char *face, UInt16 size );
// Create and/or Refresh geometry buffers
virtual void CheckVertexBufferRef(plGBufferGroup* owner, UInt32 idx);
virtual void CheckIndexBufferRef(plGBufferGroup* owner, UInt32 idx);
virtual hsBool OpenAccess(plAccessSpan& dst, plDrawableSpans* d, const plVertexSpan* span, hsBool readOnly);
virtual hsBool CloseAccess(plAccessSpan& acc);
virtual void CheckTextureRef(plLayerInterface* lay);
static void FreeManagedTexture(UInt32 sz) { hsAssert(fTexManaged >= sz, "Freeing mem we don't have"); fTexManaged -= sz; }
static void AllocManagedTexture(UInt32 sz) { fTexManaged += sz; }
static void FreeManagedVertex(UInt32 sz) { hsAssert(fVtxManaged >= sz, "Freeing mem we don't have"); fVtxManaged -= sz; }
static void AllocManagedVertex(UInt32 sz) { fVtxManaged += sz; }
#ifndef PLASMA_EXTERNAL_RELEASE
static void ProfilePoolMem(D3DPOOL poolType, UInt32 size, hsBool add, char *id);
#endif // PLASMA_EXTERNAL_RELEASE
// From a D3DFORMAT enumeration, return the bit depth associated with it.
static short GetDXBitDepth( D3DFORMAT format );
// Default fog settings
virtual void SetDefaultFogEnviron( plFogEnvironment *fog ) { fView.fDefaultFog = *fog; fCurrFog.fEnvPtr = nil; }
virtual const plFogEnvironment &GetDefaultFogEnviron() const { return fView.fDefaultFog; }
// View state
virtual hsPoint3 GetViewPositionWorld() const { return GetViewTransform().GetPosition(); }
virtual hsVector3 GetViewAcrossWorld() const { return GetViewTransform().GetAcross(); }
virtual hsVector3 GetViewUpWorld() const { return GetViewTransform().GetUp(); }
virtual hsVector3 GetViewDirWorld() const { return GetViewTransform().GetDirection(); }
virtual void GetViewAxesWorld(hsVector3 axes[3] /* ac,up,at */ ) const;
virtual void GetFOV(hsScalar& fovX, hsScalar& fovY) const;
virtual void SetFOV(hsScalar fovX, hsScalar fovY);
virtual void GetSize(hsScalar& width, hsScalar& height) const;
virtual void SetSize(hsScalar width, hsScalar height);
virtual void GetDepth(hsScalar& hither, hsScalar& yon) const;
virtual void SetDepth(hsScalar hither, hsScalar yon);
virtual hsScalar GetZBiasScale() const;
virtual void SetZBiasScale(hsScalar scale);
virtual const hsMatrix44& GetWorldToCamera() const;
virtual const hsMatrix44& GetCameraToWorld() const;
virtual void SetWorldToCamera(const hsMatrix44& w2c, const hsMatrix44& c2w);
virtual void SetViewTransform(const plViewTransform& trans);
virtual const plViewTransform& GetViewTransform() const { return fView.fTransform; }
virtual const hsMatrix44& GetWorldToLocal() const;
virtual const hsMatrix44& GetLocalToWorld() const;
virtual void ScreenToWorldPoint( int n, UInt32 stride, Int32 *scrX, Int32 *scrY,
hsScalar dist, UInt32 strideOut, hsPoint3 *worldOut );
virtual void RefreshMatrices();
virtual void RefreshScreenMatrices();
virtual void RegisterLight(plLightInfo* light);
virtual void UnRegisterLight(plLightInfo* light);
// Overrides, always push returns whatever is necessary to restore on pop.
virtual hsGMaterial* PushOverrideMaterial(hsGMaterial* mat);
virtual void PopOverrideMaterial(hsGMaterial* restore);
virtual hsGMaterial* GetOverrideMaterial() const;
virtual plLayerInterface* AppendLayerInterface(plLayerInterface* li, hsBool onAllLayers = false);
virtual plLayerInterface* RemoveLayerInterface(plLayerInterface* li, hsBool onAllLayers = false);
virtual plLayerInterface* PushPiggyBackLayer(plLayerInterface* li);
virtual plLayerInterface* PopPiggyBackLayer(plLayerInterface* li);
virtual UInt32 GetMaterialOverrideOn(hsGMatState::StateIdx category) const;
virtual UInt32 GetMaterialOverrideOff(hsGMatState::StateIdx category) const;
virtual hsGMatState PushMaterialOverride(const hsGMatState& state, hsBool on);
virtual hsGMatState PushMaterialOverride(hsGMatState::StateIdx cat, UInt32 which, hsBool on);
virtual void PopMaterialOverride(const hsGMatState& restore, hsBool on);
virtual const hsGMatState& GetMaterialOverride(hsBool on) const;
virtual hsColorOverride PushColorOverride(const hsColorOverride& over);
virtual void PopColorOverride(const hsColorOverride& restore);
virtual const hsColorOverride& GetColorOverride() const;
virtual void SubmitShadowSlave(plShadowSlave* slave);
virtual void SubmitClothingOutfit(plClothingOutfit* co);
virtual hsBool SetGamma(hsScalar eR, hsScalar eG, hsScalar eB);
virtual hsBool SetGamma(const UInt16* const tabR, const UInt16* const tabG, const UInt16* const tabB);
virtual hsBool CaptureScreen( plMipmap *dest, bool flipVertical = false, UInt16 desiredWidth = 0, UInt16 desiredHeight = 0 );
virtual plMipmap* ExtractMipMap(plRenderTarget* targ);
/// Error handling
virtual const char *GetErrorString();
hsBool ManagedAlloced() const { return fManagedAlloced; }
virtual void GetSupportedColorDepths(hsTArray<int> &ColorDepths);
virtual void GetSupportedDisplayModes(std::vector<plDisplayMode> *res, int ColorDepth = 32 );
virtual int GetMaxAnisotropicSamples();
virtual int GetMaxAntiAlias(int Width, int Height, int ColorDepth);
};
//// Direct3D Inlines //////////////////////////////////////////////////////
// ??.?? - Some mild optimizations PBG
// MMW - take advantage of the 32 bit float representation on a PC
#define CONVERT_FLOAT_TO_BYTE_COLOR( f, dest ) \
{ \
LONG const floatBitsOne = 0x3f800000; \
LONG const floatBits = *( (LONG const *)( &f ) ); \
if( floatBits <= 0 ) dest = 0; \
else if( floatBits >= floatBitsOne ) dest = 255; \
else \
{ \
LONG const times256 = floatBits + ( 8 << 23 ); \
dest = (DWORD)( *( (float const *)( &times256 ) ) ); \
} \
}
inline DWORD plDXPipeline::inlGetD3DColor( const hsColorRGBA &col ) const
{
DWORD dr, dg, db, da;
CONVERT_FLOAT_TO_BYTE_COLOR( col.r, dr );
CONVERT_FLOAT_TO_BYTE_COLOR( col.g, dg );
CONVERT_FLOAT_TO_BYTE_COLOR( col.b, db );
CONVERT_FLOAT_TO_BYTE_COLOR( col.a, da );
return( ( da << 24 ) | ( dr << 16 ) | ( dg << 8 ) | db );
}
#endif // _plDX9Pipeline_h

View File

@ -0,0 +1,165 @@
/*==LICENSE==*
CyanWorlds.com Engine - MMOG client, server and tools
Copyright (C) 2011 Cyan Worlds, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
You can contact Cyan Worlds, Inc. by email legal@cyan.com
or by snail mail at:
Cyan Worlds, Inc.
14617 N Newport Hwy
Mead, WA 99021
*==LICENSE==*/
#include "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;
}

View File

@ -0,0 +1,72 @@
/*==LICENSE==*
CyanWorlds.com Engine - MMOG client, server and tools
Copyright (C) 2011 Cyan Worlds, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
You can contact Cyan Worlds, Inc. by email legal@cyan.com
or by snail mail at:
Cyan Worlds, Inc.
14617 N Newport Hwy
Mead, WA 99021
*==LICENSE==*/
#ifndef plDXPixelShader_inc
#define plDXPixelShader_inc
#include "plDXShader.h"
class plShader;
class plDXPipeline;
struct IDirect3DPixelShader9;
class plDXPixelShader : public plDXShader
{
virtual HRESULT ICreate(plDXPipeline* pipe); // On error, sets error string.
virtual HRESULT ISetConstants(plDXPipeline* pipe);
IDirect3DPixelShader9 *fHandle;
public:
plDXPixelShader(plShader* owner);
virtual ~plDXPixelShader();
void Release();
void Link(plDXPixelShader** back) { plDXDeviceRef::Link((plDXDeviceRef**)back); }
hsBool VerifyFormat(UInt8 format) const;
IDirect3DPixelShader9 *GetShader(plDXPipeline* pipe);
};
#endif // plDXPixelShader_inc

View File

@ -0,0 +1,105 @@
/*==LICENSE==*
CyanWorlds.com Engine - MMOG client, server and tools
Copyright (C) 2011 Cyan Worlds, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
You can contact Cyan Worlds, Inc. by email legal@cyan.com
or by snail mail at:
Cyan Worlds, Inc.
14617 N Newport Hwy
Mead, WA 99021
*==LICENSE==*/
///////////////////////////////////////////////////////////////////////////////
// //
// plDXRenderTargetRef.h - RenderTarget DeviceRef Definitions //
// Cyan, Inc. //
// //
//// Version History //////////////////////////////////////////////////////////
// //
// 7.19.2001 mcn - Created. //
// //
///////////////////////////////////////////////////////////////////////////////
#ifndef _plDXRenderTargetRef_h
#define _plDXRenderTargetRef_h
#include "hsMatrix44.h"
#include "hsTemplates.h"
#include "plDXTextureRef.h"
//// Definition ///////////////////////////////////////////////////////////////
class plRenderTarget;
class plDXRenderTargetRef: public plDXTextureRef
{
public:
IDirect3DSurface9 *fD3DColorSurface;
IDirect3DSurface9 *fD3DDepthSurface;
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

View File

@ -0,0 +1,301 @@
/*==LICENSE==*
CyanWorlds.com Engine - MMOG client, server and tools
Copyright (C) 2011 Cyan Worlds, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
You can contact Cyan Worlds, Inc. by email legal@cyan.com
or by snail mail at:
Cyan Worlds, Inc.
14617 N Newport Hwy
Mead, WA 99021
*==LICENSE==*/
///////////////////////////////////////////////////////////////////////////////
// //
// plDXSettings - Header for the various settings groups for plDXPipeline //
// Cyan, Inc. //
// //
//// Version History //////////////////////////////////////////////////////////
// //
// 4.25.2001 mcn - Created. //
// //
///////////////////////////////////////////////////////////////////////////////
#ifndef _plDXSettings_h
#define _plDXSettings_h
#include "hsMatrix44.h"
#include "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

View File

@ -0,0 +1,102 @@
/*==LICENSE==*
CyanWorlds.com Engine - MMOG client, server and tools
Copyright (C) 2011 Cyan Worlds, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
You can contact Cyan Worlds, Inc. by email legal@cyan.com
or by snail mail at:
Cyan Worlds, Inc.
14617 N Newport Hwy
Mead, WA 99021
*==LICENSE==*/
#include "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;
}

View File

@ -0,0 +1,72 @@
/*==LICENSE==*
CyanWorlds.com Engine - MMOG client, server and tools
Copyright (C) 2011 Cyan Worlds, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
You can contact Cyan Worlds, Inc. by email legal@cyan.com
or by snail mail at:
Cyan Worlds, Inc.
14617 N Newport Hwy
Mead, WA 99021
*==LICENSE==*/
#ifndef plDXShader_inc
#define plDXShader_inc
#include "plDXDeviceRef.h"
class plShader;
class plDXPipeline;
class plDXShader : public plDXDeviceRef
{
protected:
plShader* fOwner;
char* fErrorString;
plDXPipeline* fPipe;
HRESULT IOnError(HRESULT hr, const char* errStr);
const char* ISetError(const char* errStr);
virtual HRESULT ICreate(plDXPipeline* pipe) = 0;
virtual HRESULT ISetConstants(plDXPipeline* pipe) = 0; // On error, sets error string.
public:
plDXShader(plShader* owner);
virtual ~plDXShader();
const char* GetErrorString() const { return fErrorString; }
void SetOwner(plShader* owner);
};
#endif // plDXShader_inc

View File

@ -0,0 +1,324 @@
/*==LICENSE==*
CyanWorlds.com Engine - MMOG client, server and tools
Copyright (C) 2011 Cyan Worlds, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
You can contact Cyan Worlds, Inc. by email legal@cyan.com
or by snail mail at:
Cyan Worlds, Inc.
14617 N Newport Hwy
Mead, WA 99021
*==LICENSE==*/
///////////////////////////////////////////////////////////////////////////////
// //
// plDXTextFont Class Functions //
// Cyan, Inc. //
// //
//// Version History //////////////////////////////////////////////////////////
// //
// 2.19.2001 mcn - Created. //
// //
///////////////////////////////////////////////////////////////////////////////
#include "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 );
}

View File

@ -0,0 +1,90 @@
/*==LICENSE==*
CyanWorlds.com Engine - MMOG client, server and tools
Copyright (C) 2011 Cyan Worlds, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
You can contact Cyan Worlds, Inc. by email legal@cyan.com
or by snail mail at:
Cyan Worlds, Inc.
14617 N Newport Hwy
Mead, WA 99021
*==LICENSE==*/
#ifndef _plDXTextFont_h
#define _plDXTextFont_h
#include "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

View File

@ -0,0 +1,123 @@
/*==LICENSE==*
CyanWorlds.com Engine - MMOG client, server and tools
Copyright (C) 2011 Cyan Worlds, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
You can contact Cyan Worlds, Inc. by email legal@cyan.com
or by snail mail at:
Cyan Worlds, Inc.
14617 N Newport Hwy
Mead, WA 99021
*==LICENSE==*/
///////////////////////////////////////////////////////////////////////////////
// //
// plDXTextureRef.h - Hardware Texture DeviceRef Definition //
// Cyan, Inc. //
// //
//// Version History //////////////////////////////////////////////////////////
// //
// 4.25.2001 mcn - Created. //
// //
///////////////////////////////////////////////////////////////////////////////
#ifndef _plDXTextureRef_h
#define _plDXTextureRef_h
#include "hsMatrix44.h"
#include "hsGeometry3.h"
#include "hsTemplates.h"
#include "plDXDeviceRef.h"
//// Definition ///////////////////////////////////////////////////////////////
class plBitmap;
class plDXTextureRef : public plDXDeviceRef
{
public:
enum Flags
{
kExternData = 0x00000002, // fData points to user data, don't delete
kRenderTarget = 0x00000004, // Created via a render target
kCubicMap = 0x00000008, // Texture is really a cubic map texture
kPerspProjection = 0x00000010, // Perspective projection
kOrthoProjection = 0x00000020, // Orthogonal projection
kProjection = kPerspProjection | kOrthoProjection,
kOffscreenRT = 0x00000040, // Offscreen renderTarget. Never used as an actual texture,
// but handy to still have it as a textureRef
kUVWNormal = 0x00000080 // Use the normal as the UVW src
};
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

View File

@ -0,0 +1,168 @@
/*==LICENSE==*
CyanWorlds.com Engine - MMOG client, server and tools
Copyright (C) 2011 Cyan Worlds, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
You can contact Cyan Worlds, Inc. by email legal@cyan.com
or by snail mail at:
Cyan Worlds, Inc.
14617 N Newport Hwy
Mead, WA 99021
*==LICENSE==*/
#include "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;
}

View File

@ -0,0 +1,73 @@
/*==LICENSE==*
CyanWorlds.com Engine - MMOG client, server and tools
Copyright (C) 2011 Cyan Worlds, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
You can contact Cyan Worlds, Inc. by email legal@cyan.com
or by snail mail at:
Cyan Worlds, Inc.
14617 N Newport Hwy
Mead, WA 99021
*==LICENSE==*/
#ifndef plDXVertexSahder_inc
#define plDXVertexSahder_inc
#include "plDXShader.h"
#include "hsTemplates.h"
struct IDirect3DDevice9;
class plShader;
class plDXPipeline;
class plDXVertexShader : public plDXShader
{
protected:
IDirect3DVertexShader9* fHandle;
hsTArray<DWORD>& IMakeDecl(hsTArray<DWORD>& decl) const;
virtual HRESULT ICreate(plDXPipeline* pipe); // On error, sets error string.
virtual HRESULT ISetConstants(plDXPipeline* pipe); // On error, sets error string.
public:
plDXVertexShader(plShader* owner);
virtual ~plDXVertexShader();
virtual void Release();
void Link(plDXVertexShader** back) { plDXDeviceRef::Link((plDXDeviceRef**)back); }
hsBool VerifyFormat(UInt8 format) const;
IDirect3DVertexShader9* GetShader(plDXPipeline* pipe);
};
#endif // plDXVertexSahder_inc

View File

@ -0,0 +1,304 @@
/*==LICENSE==*
CyanWorlds.com Engine - MMOG client, server and tools
Copyright (C) 2011 Cyan Worlds, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
You can contact Cyan Worlds, Inc. by email legal@cyan.com
or by snail mail at:
Cyan Worlds, Inc.
14617 N Newport Hwy
Mead, WA 99021
*==LICENSE==*/
//////////////////////////////////////////////////////////////////////////////
// //
// 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;
}

View File

@ -0,0 +1,203 @@
/*==LICENSE==*
CyanWorlds.com Engine - MMOG client, server and tools
Copyright (C) 2011 Cyan Worlds, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
You can contact Cyan Worlds, Inc. by email legal@cyan.com
or by snail mail at:
Cyan Worlds, Inc.
14617 N Newport Hwy
Mead, WA 99021
*==LICENSE==*/
//////////////////////////////////////////////////////////////////////////////
// //
// 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

View File

@ -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/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
You can contact Cyan Worlds, Inc. by email legal@cyan.com
or by snail mail at:
Cyan Worlds, Inc.
14617 N Newport Hwy
Mead, WA 99021
*==LICENSE==*/
#include "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;
};

View File

@ -0,0 +1,968 @@
/*==LICENSE==*
CyanWorlds.com Engine - MMOG client, server and tools
Copyright (C) 2011 Cyan Worlds, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
You can contact Cyan Worlds, Inc. by email legal@cyan.com
or by snail mail at:
Cyan Worlds, Inc.
14617 N Newport Hwy
Mead, WA 99021
*==LICENSE==*/
#include "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());
}
}

View File

@ -0,0 +1,225 @@
/*==LICENSE==*
CyanWorlds.com Engine - MMOG client, server and tools
Copyright (C) 2011 Cyan Worlds, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
You can contact Cyan Worlds, Inc. by email legal@cyan.com
or by snail mail at:
Cyan Worlds, Inc.
14617 N Newport Hwy
Mead, WA 99021
*==LICENSE==*/
#ifndef 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

View File

@ -0,0 +1,213 @@
/*==LICENSE==*
CyanWorlds.com Engine - MMOG client, server and tools
Copyright (C) 2011 Cyan Worlds, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
You can contact Cyan Worlds, Inc. by email legal@cyan.com
or by snail mail at:
Cyan Worlds, Inc.
14617 N Newport Hwy
Mead, WA 99021
*==LICENSE==*/
//////////////////////////////////////////////////////////////////////////////
// //
// 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 );
}

View File

@ -0,0 +1,120 @@
/*==LICENSE==*
CyanWorlds.com Engine - MMOG client, server and tools
Copyright (C) 2011 Cyan Worlds, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
You can contact Cyan Worlds, Inc. by email legal@cyan.com
or by snail mail at:
Cyan Worlds, Inc.
14617 N Newport Hwy
Mead, WA 99021
*==LICENSE==*/
//////////////////////////////////////////////////////////////////////////////
// //
// 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

View File

@ -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/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
You can contact Cyan Worlds, Inc. by email legal@cyan.com
or by snail mail at:
Cyan Worlds, Inc.
14617 N Newport Hwy
Mead, WA 99021
*==LICENSE==*/
///////////////////////////////////////////////////////////////////////////////
// //
// 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

View File

@ -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/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
You can contact Cyan Worlds, Inc. by email legal@cyan.com
or by snail mail at:
Cyan Worlds, Inc.
14617 N Newport Hwy
Mead, WA 99021
*==LICENSE==*/
#ifndef 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

View File

@ -0,0 +1,82 @@
/*==LICENSE==*
CyanWorlds.com Engine - MMOG client, server and tools
Copyright (C) 2011 Cyan Worlds, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
You can contact Cyan Worlds, Inc. by email legal@cyan.com
or by snail mail at:
Cyan Worlds, Inc.
14617 N Newport Hwy
Mead, WA 99021
*==LICENSE==*/
#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

View File

@ -0,0 +1,91 @@
/*==LICENSE==*
CyanWorlds.com Engine - MMOG client, server and tools
Copyright (C) 2011 Cyan Worlds, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
You can contact Cyan Worlds, Inc. by email legal@cyan.com
or by snail mail at:
Cyan Worlds, Inc.
14617 N Newport Hwy
Mead, WA 99021
*==LICENSE==*/
///////////////////////////////////////////////////////////////////////////////
// //
// 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

View File

@ -0,0 +1,792 @@
/*==LICENSE==*
CyanWorlds.com Engine - MMOG client, server and tools
Copyright (C) 2011 Cyan Worlds, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
You can contact Cyan Worlds, Inc. by email legal@cyan.com
or by snail mail at:
Cyan Worlds, Inc.
14617 N Newport Hwy
Mead, WA 99021
*==LICENSE==*/
//////////////////////////////////////////////////////////////////////////////
// //
// plPlates.cpp - Implementation of plates and plate manager //
// //
//////////////////////////////////////////////////////////////////////////////
#include "hsWindows.h"
#include "hsTypes.h"
#include "plPipeline.h"
#include "plPlates.h"
#include "../plJPEG/plJPEG.h"
#include "../plGImage/plPNG.h"
#include "../plGImage/plMipmap.h"
#include "../plSurface/plLayer.h"
#include "../plSurface/hsGMaterial.h"
#include "../plMessage/plLayRefMsg.h"
#include "../pnMessage/plRefMsg.h"
#include "hsGDeviceRef.h"
#include "hsResMgr.h"
#include "plPipeDebugFlags.h"
#include "../plClientResMgr/plClientResMgr.h"
// A bit of a hack so that we will have the correct instance in the SceneViewer
static HINSTANCE gHInstance = GetModuleHandle(nil);
void SetHInstance(void *instance)
{
gHInstance = (HINSTANCE)instance;
}
//////////////////////////////////////////////////////////////////////////////
//// plPlate Functions ///////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
UInt32 plPlate::fMagicUniqueKeyInt = 0;
plPlate::plPlate( plPlate **owningHandle )
{
fXformMatrix.Reset();
fDepth = 1.0f;
fMaterial = nil;
fFlags = 0;
fOpacity = 1.f;
fNext = nil;
fPrevPtr = nil;
fOwningHandle = owningHandle;
fMipmap = nil;
memset( fTitle, 0, sizeof( fTitle ) );
}
plPlate::~plPlate()
{
if( fFlags & kFlagLocalMaterial )
fMaterial->GetKey()->UnRefObject();
else
{
hsRefCnt_SafeUnRef( fMaterial );
}
fMaterial = nil;
*fOwningHandle = nil;
}
//// SetPosition /////////////////////////////////////////////////////////////
void plPlate::SetPosition( hsScalar x, hsScalar y, hsScalar z )
{
hsVector3 triple;
if( z != -1.0f )
{
/// Gotta resort--let the manager do it
plPlateManager::Instance().IResortPlate( this, ( z + 1.0f <= fDepth ) ? true : false );
fDepth = z + 1.0f;
}
x *= fDepth / 1.0f;
y *= fDepth / 1.0f;
triple.fX = x;
triple.fY = y;
triple.fZ = fDepth;
fXformMatrix.SetTranslate( &triple );
}
//// SetSize /////////////////////////////////////////////////////////////////
void plPlate::SetSize( hsScalar width, hsScalar height, bool adjustByAspectRation )
{
hsVector3 size;
width *= fDepth / 1.0f;
height *= fDepth / 1.0f;
size.fX = adjustByAspectRation ? (width * ((hsScalar)plPlateManager::Instance().GetPipeHeight() / (hsScalar)plPlateManager::Instance().GetPipeWidth())) : width;
size.fY = height;
size.fZ = 1.0f;
fXformMatrix.SetScale( &size );
}
//// SetTransform ////////////////////////////////////////////////////////////
void plPlate::SetTransform( hsMatrix44 &matrix, hsBool reSort )
{
fXformMatrix = matrix;
if( reSort )
plPlateManager::Instance().IResortPlate( this, false );
}
//// SetMaterial /////////////////////////////////////////////////////////////
void plPlate::SetMaterial( hsGMaterial *material )
{
hsRefCnt_SafeAssign( fMaterial, material );
}
void plPlate::SetTexture(plBitmap *texture)
{
plLayer *layer;
hsGMaterial *material;
char keyName[ 128 ];
material = TRACKED_NEW hsGMaterial();
sprintf( keyName, "PlateBlank#%d", fMagicUniqueKeyInt++ );
hsgResMgr::ResMgr()->NewKey( keyName, material, plLocation::kGlobalFixedLoc );
layer = material->MakeBaseLayer();
layer->SetShadeFlags( layer->GetShadeFlags() | hsGMatState::kShadeNoShade | hsGMatState::kShadeWhite | hsGMatState::kShadeReallyNoFog );
layer->SetZFlags( layer->GetZFlags() | hsGMatState::kZNoZRead );
layer->SetBlendFlags( layer->GetBlendFlags() | hsGMatState::kBlendAlpha );
layer->SetOpacity( fOpacity );
layer->SetUVWSrc(plLayerInterface::kUVWPassThru);
hsgResMgr::ResMgr()->AddViaNotify(texture->GetKey(), TRACKED_NEW plGenRefMsg(layer->GetKey(), plRefMsg::kOnCreate, -1, plLayRefMsg::kTexture), plRefFlags::kActiveRef);
SetMaterial(material);
}
//// SetOpacity //////////////////////////////////////////////////////////////
void plPlate::SetOpacity( hsScalar opacity )
{
if( fMaterial != nil && fMaterial->GetLayer( 0 ) != nil )
{
plLayer *layer = (plLayer *)fMaterial->GetLayer( 0 );
layer->SetOpacity( opacity );
}
fOpacity = opacity;
}
//// CreateMaterial /////////////////////////////////////////////////////
// Creates a new material for this plate with either a specified texture
// or an empty, white-filled bitmap.
plMipmap *plPlate::CreateMaterial( UInt32 width, UInt32 height, hsBool withAlpha, plMipmap* texture )
{
plLayer *layer;
hsGMaterial *material;
char keyName[ 128 ];
if (texture)
{
fMipmap = texture;
}
else
{
/// Create a new bitmap
fMipmap = TRACKED_NEW plMipmap( width, height, withAlpha ? plMipmap::kARGB32Config : plMipmap::kRGB32Config, 1 );
memset( fMipmap->GetImage(), 0xff, height * fMipmap->GetRowBytes() );
sprintf( keyName, "PlateBitmap#%d", fMagicUniqueKeyInt++ );
hsgResMgr::ResMgr()->NewKey( keyName, fMipmap, plLocation::kGlobalFixedLoc );
fMipmap->SetFlags( fMipmap->GetFlags() | plMipmap::kDontThrowAwayImage );
}
/// NOW create a layer wrapper and a material for that layer
material = TRACKED_NEW hsGMaterial();
sprintf( keyName, "PlateBlank#%d", fMagicUniqueKeyInt++ );
hsgResMgr::ResMgr()->NewKey( keyName, material, plLocation::kGlobalFixedLoc );
layer = material->MakeBaseLayer();
layer->SetShadeFlags( layer->GetShadeFlags() | hsGMatState::kShadeNoShade | hsGMatState::kShadeWhite | hsGMatState::kShadeReallyNoFog );
layer->SetZFlags( layer->GetZFlags() | hsGMatState::kZNoZRead );
layer->SetBlendFlags( layer->GetBlendFlags() | hsGMatState::kBlendAlpha );
layer->SetOpacity( fOpacity );
hsgResMgr::ResMgr()->AddViaNotify( fMipmap->GetKey(), TRACKED_NEW plLayRefMsg( layer->GetKey(), plRefMsg::kOnCreate, 0, plLayRefMsg::kTexture ), plRefFlags::kActiveRef );
// Set up a ref to these. Since we don't have a key, we use the
// generic RefObject() (and matching UnRefObject() when we're done).
// If we had a key, we would use myKey->AddViaNotify(otherKey) and myKey->Release(otherKey).
material->GetKey()->RefObject();
/// Set this as our new material and return the bitmap
fFlags |= kFlagLocalMaterial;
fMaterial = material;
return fMipmap;
}
//// CreateFromResource //////////////////////////////////////////////////////
// Creates a plate's material from a resource of the given name.
void plPlate::CreateFromResource(const char *resName)
{
if (resName)
{
plMipmap* resTexture = TRACKED_NEW plMipmap;
resTexture->CopyFrom(plClientResMgr::Instance().getResource(resName));
char keyName[128];
sprintf( keyName, "PlateResource#%d", fMagicUniqueKeyInt++ );
hsgResMgr::ResMgr()->NewKey(keyName, resTexture, plLocation::kGlobalFixedLoc);
CreateMaterial(resTexture->GetWidth(), resTexture->GetHeight(), true, resTexture);
}
else
{
// Null resource request - Create a blank Material instead
CreateMaterial(32, 32, true);
}
}
void plPlate::ReloadFromResource(const char *resName)
{
if (resName)
{
fMipmap->CopyFrom(plClientResMgr::Instance().getResource(resName));
}
}
//// ILink ///////////////////////////////////////////////////////////////////
// Links a plate into a plate list, but also sorts by decreasing depth,
// so the plate won't actually necessarily be added after the pointer
// given.
void plPlate::ILink( plPlate **back )
{
hsAssert( fNext == nil && fPrevPtr == nil, "Trying to link a plate that's already linked" );
/// Advance back as far as we need to go
while( *back != nil && (*back)->fDepth > fDepth )
back = &( (*back)->fNext );
/// Link!
fNext = *back;
if( *back )
(*back)->fPrevPtr = &fNext;
fPrevPtr = back;
*back = this;
}
hsBool plPlate::IsVisible()
{
// return not-visible if our material is not valid
if (fMaterial->GetNumLayers() == 0)
return false;
plLayerInterface* layer = fMaterial->GetLayer(0);
if (layer->GetTexture() == nil)
return false;
// cursory check of material indicates it's valid, return our visible flag status
return ( fFlags & kFlagVisible ) ? true : false;
}
//////////////////////////////////////////////////////////////////////////////
//// plGraphPlate Functions //////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
//// Constructor & Destructor ////////////////////////////////////////////////
plGraphPlate::plGraphPlate( plPlate **owningHandle ) : plPlate( owningHandle )
{
fFlags |= kFlagIsAGraph;
SetLabelText( nil );
}
plGraphPlate::~plGraphPlate()
{
}
//// IMakePow2 ///////////////////////////////////////////////////////////////
UInt32 plGraphPlate::IMakePow2( UInt32 value )
{
int i;
for( i = 0; value != 0; i++, value >>= 1 );
return 1 << i;
}
//// SetDataRange ////////////////////////////////////////////////////////////
void plGraphPlate::SetDataRange( UInt32 min, UInt32 max, UInt32 width )
{
UInt32 height;
width = IMakePow2( width + 4 );
height = IMakePow2( max - min + 1 + 4 );
CreateMaterial( width, height, true );
fMin = min;
fMax = max;
SetDataLabels( fMin, fMax );
SetColors();
SetDataColors();
ClearData();
}
//// SetDataLabels ///////////////////////////////////////////////////////////
void plGraphPlate::SetDataLabels( UInt32 min, UInt32 max )
{
fLabelMin = min;
fLabelMax = max;
}
//// ClearData ///////////////////////////////////////////////////////////////
void plGraphPlate::ClearData( void )
{
UInt32 *bits = (UInt32 *)fMipmap->GetImage(), *ptr;
int i;
// Background color
for( i = 0; i < fMipmap->GetWidth() * fMipmap->GetHeight(); bits[ i ] = fBGHexColor, i++ );
// Axes
ptr = bits + fMipmap->GetWidth();
*ptr = fAxesHexColor;
for( ptr++, i = 0; i < fMipmap->GetHeight() - 4; i++, ptr += fMipmap->GetWidth() )
*ptr = fAxesHexColor;
for( i = 0; i < fMipmap->GetWidth() - 4; ptr[ i ] = fAxesHexColor, i++ );
ptr += fMipmap->GetWidth() - 1;
ptr[ 0 ] = fAxesHexColor;
ptr[ fMipmap->GetWidth() - 5 + 1 ] = fAxesHexColor;
if( fMaterial->GetLayer( 0 ) != nil && fMaterial->GetLayer( 0 )->GetTexture() )
{
hsGDeviceRef *ref = fMaterial->GetLayer( 0 )->GetTexture()->GetDeviceRef();
if( ref != nil )
ref->SetDirty( true );
}
}
//// AddData /////////////////////////////////////////////////////////////////
// Scroll graph data left by one, then add the new value
void plGraphPlate::AddData( Int32 value, Int32 value2, Int32 value3, Int32 value4 )
{
std::vector<Int32> values;
if (value != -1)
values.push_back(value);
if (value2 != -1)
values.push_back(value2);
if (value3 != -1)
values.push_back(value3);
if (value4 != -1)
values.push_back(value4);
AddData(values);
}
void plGraphPlate::AddData( std::vector<Int32> values )
{
hsAssert( fMipmap != nil, "Trying to add data to an uninitialized plGraphPlate" );
fMipmap->SetCurrLevel( 0 );
UInt32 *bits = (UInt32 *)fMipmap->GetImage(), *ptr;
UInt32 *minDPos = fMipmap->GetAddr32( 3, fMipmap->GetHeight() - 3 - 10 );
UInt32 *maxDPos = fMipmap->GetAddr32( 3, 2 );
int i, j;
std::vector<int> lows, his;
float lineCtr, lineInc;
int lastLineInt, lineInt, bumpCtr;
// make sure we have enough colors
if (values.size() > fDataHexColors.size())
{
for (i=fDataHexColors.size(); i<values.size(); i++)
fDataHexColors.push_back(0xff00ff00); // make it a nice green color
}
// make sure we have enough "last values"
if (values.size() > fLastValues.size())
{
for (i=fLastValues.size(); i<values.size(); i++)
fLastValues.push_back(0);
}
// Scale values
for (i=0; i<values.size(); i++)
{
lows.push_back(0);
his.push_back(0);
if( values[ i ] > fLabelMax )
values[ i ] = fLabelMax;
else if( values[ i ] < fLabelMin )
values[ i ] = fLabelMin;
values[ i ] = (UInt32)( (float)values[ i ] * ( fMipmap->GetHeight() - 4 ) / ( fLabelMax - fLabelMin + 1 ) );
if( values[ i ] < fLastValues[ i ] )
{
lows[ i ] = values[ i ] - 1;
his[ i ] = fLastValues[ i ];
}
else
{
lows[ i ] = fLastValues[ i ] - 1;
his[ i ] = values[ i ];
}
}
lineCtr = 0;
lastLineInt = 0;
bumpCtr = 0;
lineInc = 8.0f / ( fMipmap->GetHeight() - 4 );
IDrawNumber( fLabelMin, minDPos, fMipmap->GetWidth(), fBGHexColor );
IDrawNumber( fLabelMax, maxDPos, fMipmap->GetWidth(), fBGHexColor );
for( i = 0, ptr = bits + fMipmap->GetWidth() + 2, j = fMipmap->GetHeight() - 4; i < fMipmap->GetHeight() - 4; i++, j-- )
{
lineInt = (int)lineCtr;
if( lineInt != lastLineInt )
bumpCtr = 2;
memmove( ptr, ptr + 1, ( fMipmap->GetWidth() - 5 ) * sizeof( UInt32 ) );
int dataIndex;
bool dataPlotted = false;
for (dataIndex = 0; dataIndex < values.size(); dataIndex++)
{
if( j >= lows[ dataIndex ] && j <= his[ dataIndex ] )
{
ptr[ fMipmap->GetWidth() - 5 ] = fDataHexColors[ dataIndex ];
dataPlotted = true;
break;
}
}
if (!dataPlotted)
{
if( bumpCtr > 0 )
{
if( lineInt == 4 )
ptr[ fMipmap->GetWidth() - 5 ] = fGraphHexColor | 0xff000000;
else
ptr[ fMipmap->GetWidth() - 5 ] = fGraphHexColor;
bumpCtr--;
}
else
ptr[ fMipmap->GetWidth() - 5 ] = fBGHexColor;
}
ptr += fMipmap->GetWidth();
lastLineInt = lineInt;
lineCtr += lineInc;
}
IDrawNumber( fLabelMin, minDPos, fMipmap->GetWidth(), fAxesHexColor );
IDrawNumber( fLabelMax, maxDPos, fMipmap->GetWidth(), fAxesHexColor );
fLastValues = values;
if( fMaterial->GetLayer( 0 ) != nil && fMaterial->GetLayer( 0 )->GetTexture() != nil )
{
hsGDeviceRef *ref = fMaterial->GetLayer( 0 )->GetTexture()->GetDeviceRef();
if( ref != nil )
ref->SetDirty( true );
}
}
//// SetColors ///////////////////////////////////////////////////////////////
void plGraphPlate::SetColors( UInt32 bgHexColor, UInt32 axesHexColor, UInt32 dataHexColor, UInt32 graphHexColor )
{
fBGHexColor = bgHexColor;
fAxesHexColor = axesHexColor;
if (fDataHexColors.size() == 0)
fDataHexColors.push_back(dataHexColor);
else
fDataHexColors[ 0 ] = dataHexColor;
fGraphHexColor = graphHexColor;
ClearData();
}
//// SetDataColors ///////////////////////////////////////////////////////////
void plGraphPlate::SetDataColors( UInt32 hexColor1, UInt32 hexColor2, UInt32 hexColor3, UInt32 hexColor4 )
{
std::vector<UInt32> colors;
colors.push_back(hexColor1);
colors.push_back(hexColor2);
colors.push_back(hexColor3);
colors.push_back(hexColor4);
SetDataColors(colors);
}
void plGraphPlate::SetDataColors( const std::vector<UInt32> & hexColors )
{
fDataHexColors = hexColors;
}
//// SetLabelText ////////////////////////////////////////////////////////////
void plGraphPlate::SetLabelText( char *text1, char *text2, char *text3, char *text4 )
{
std::vector<std::string> strings;
if( text1 != nil )
strings.push_back(text1);
else
strings.push_back("");
if( text2 != nil )
strings.push_back(text2);
else
strings.push_back("");
if( text3 != nil )
strings.push_back(text3);
else
strings.push_back("");
if( text4 != nil )
strings.push_back(text4);
else
strings.push_back("");
SetLabelText(strings);
}
void plGraphPlate::SetLabelText( const std::vector<std::string> & text )
{
fLabelText = text;
}
//// IDrawNumber /////////////////////////////////////////////////////////////
void plGraphPlate::IDrawNumber( UInt32 number, UInt32 *dataPtr, UInt32 stride, UInt32 color )
{
char str[ 16 ];
int i;
sprintf( str, "%d", number );
for( i = 0; str[ i ] != 0; i++ )
{
IDrawDigit( str[ i ] - '0', dataPtr, stride, color );
dataPtr += 7;
}
}
//// IDrawDigit //////////////////////////////////////////////////////////////
void plGraphPlate::IDrawDigit( char digit, UInt32 *dataPtr, UInt32 stride, UInt32 color )
{
/// Yes, I know this is ugly. Move it into another file if you like.
char digits[ 10 ][ 5 * 3 ] =
{ { 1,1,1,
1,0,1,
1,0,1,
1,0,1,
1,1,1 },
{ 0,1,0,
1,1,0,
0,1,0,
0,1,0,
1,1,1 },
{ 2,2,2,
0,0,2,
0,2,0,
2,0,0,
2,2,2 },
{ 3,3,3,
0,0,3,
3,3,3,
0,0,3,
3,3,3 },
{ 4,0,4,
4,0,4,
4,4,4,
0,0,4,
0,0,4 },
{ 5,5,5,
5,0,0,
5,5,5,
0,0,5,
5,5,5 },
{ 6,6,6,
6,0,0,
6,6,6,
6,0,6,
6,6,6 },
{ 7,7,7,
0,0,7,
0,0,7,
0,0,7,
0,0,7 },
{ 8,8,8,
8,0,8,
8,8,8,
8,0,8,
8,8,8 },
{ 9,9,9,
9,0,9,
9,9,9,
0,0,9,
0,0,9 } };
char *digData = digits[ digit ];
int i, j;
for( i = 0; i < 5; i++ )
{
for( j = 0; j < 6; j += 2 )
{
if( *digData )
{
dataPtr[ j ] = color;
dataPtr[ j + 1 ] = color;
dataPtr[ j + stride ] = color;
dataPtr[ j + stride + 1 ] = color;
}
digData++;
}
dataPtr += stride + stride;
}
}
//////////////////////////////////////////////////////////////////////////////
//// plPlateManager Functions ////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
plPlateManager *plPlateManager::fInstance = nil;
//// Destructor /////////////////////////////////////////////////////////////
plPlateManager::~plPlateManager()
{
while( fPlates != nil )
DestroyPlate( fPlates );
fInstance = nil;
}
//// CreatePlate /////////////////////////////////////////////////////////////
void plPlateManager::CreatePlate( plPlate **handle )
{
plPlate *plate = TRACKED_NEW plPlate( handle );
plate->ILink( &fPlates );
*handle = plate;
}
void plPlateManager::CreatePlate( plPlate **handle, hsScalar width, hsScalar height )
{
CreatePlate( handle );
(*handle)->SetSize( width, height );
}
void plPlateManager::CreatePlate( plPlate **handle, hsScalar x, hsScalar y, hsScalar width, hsScalar height )
{
CreatePlate( handle );
(*handle)->SetPosition( x, y );
(*handle)->SetSize( width, height );
}
void plPlateManager::CreateGraphPlate( plGraphPlate **handle )
{
plGraphPlate *plate = TRACKED_NEW plGraphPlate( (plPlate **)handle );
plate->ILink( &fPlates );
*handle = plate;
}
//// DestroyPlate ////////////////////////////////////////////////////////////
void plPlateManager::DestroyPlate( plPlate *plate )
{
if( plate != nil )
{
plate->IUnlink();
delete plate;
}
}
//// GetPipeWidth/Height /////////////////////////////////////////////////////
UInt32 plPlateManager::GetPipeWidth( void )
{
return fOwner->Width();
}
UInt32 plPlateManager::GetPipeHeight( void )
{
return fOwner->Height();
}
//// DrawToDevice ////////////////////////////////////////////////////////////
void plPlateManager::DrawToDevice( plPipeline *pipe )
{
if( !pipe->IsDebugFlagSet(plPipeDbg::kFlagNoPlates) )
IDrawToDevice( pipe );
}
//// IResortPlate ////////////////////////////////////////////////////////////
void plPlateManager::IResortPlate( plPlate *plate, bool fromCurrent )
{
plPlate **start = &fPlates;
if( fromCurrent )
start = plate->fPrevPtr;
plate->IUnlink();
plate->ILink( start );
}
//// SetPlateScreenPos ///////////////////////////////////////////////////////
void plPlateManager::SetPlateScreenPos( plPlate *plate, UInt32 x, UInt32 y )
{
float cX = ( (float)x / fOwner->Width() ) * 2.0f - 1.0f;
float cY = ( (float)y / fOwner->Height() ) * 2.0f - 1.0f;
plate->SetPosition( cX, cY );
}
void plPlateManager::SetPlatePixelSize( plPlate *plate, UInt32 pWidth, UInt32 pHeight )
{
float width = (float)pWidth / fOwner->Width() * 2.0f;
float height = (float)pHeight / fOwner->Height() * 2.0f;
plate->SetSize(width, height);
}

View File

@ -0,0 +1,251 @@
/*==LICENSE==*
CyanWorlds.com Engine - MMOG client, server and tools
Copyright (C) 2011 Cyan Worlds, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
You can contact Cyan Worlds, Inc. by email legal@cyan.com
or by snail mail at:
Cyan Worlds, Inc.
14617 N Newport Hwy
Mead, WA 99021
*==LICENSE==*/
//////////////////////////////////////////////////////////////////////////////
// //
// 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; }
const plMipmap *GetMipmap( void ) { return fMipmap; }
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 );
void ReloadFromResource( const char *resName );
};
//// 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

View File

@ -0,0 +1,205 @@
/*==LICENSE==*
CyanWorlds.com Engine - MMOG client, server and tools
Copyright (C) 2011 Cyan Worlds, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
You can contact Cyan Worlds, Inc. by email legal@cyan.com
or by snail mail at:
Cyan Worlds, Inc.
14617 N Newport Hwy
Mead, WA 99021
*==LICENSE==*/
///////////////////////////////////////////////////////////////////////////////
// //
// 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);
}

View File

@ -0,0 +1,205 @@
/*==LICENSE==*
CyanWorlds.com Engine - MMOG client, server and tools
Copyright (C) 2011 Cyan Worlds, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
You can contact Cyan Worlds, Inc. by email legal@cyan.com
or by snail mail at:
Cyan Worlds, Inc.
14617 N Newport Hwy
Mead, WA 99021
*==LICENSE==*/
///////////////////////////////////////////////////////////////////////////////
// //
// 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

View File

@ -0,0 +1,128 @@
/*==LICENSE==*
CyanWorlds.com Engine - MMOG client, server and tools
Copyright (C) 2011 Cyan Worlds, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
You can contact Cyan Worlds, Inc. by email legal@cyan.com
or by snail mail at:
Cyan Worlds, Inc.
14617 N Newport Hwy
Mead, WA 99021
*==LICENSE==*/
//////////////////////////////////////////////////////////////////////////////
// //
// 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);
}

View File

@ -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/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
You can contact Cyan Worlds, Inc. by email legal@cyan.com
or by snail mail at:
Cyan Worlds, Inc.
14617 N Newport Hwy
Mead, WA 99021
*==LICENSE==*/
//////////////////////////////////////////////////////////////////////////////
// //
// 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

View File

@ -0,0 +1,103 @@
/*==LICENSE==*
CyanWorlds.com Engine - MMOG client, server and tools
Copyright (C) 2011 Cyan Worlds, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
You can contact Cyan Worlds, Inc. by email legal@cyan.com
or by snail mail at:
Cyan Worlds, Inc.
14617 N Newport Hwy
Mead, WA 99021
*==LICENSE==*/
///////////////////////////////////////////////////////////////////////////////
// //
// 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

View File

@ -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/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
You can contact Cyan Worlds, Inc. by email legal@cyan.com
or by snail mail at:
Cyan Worlds, Inc.
14617 N Newport Hwy
Mead, WA 99021
*==LICENSE==*/
///////////////////////////////////////////////////////////////////////////////
// //
// 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!
}

View File

@ -0,0 +1,157 @@
/*==LICENSE==*
CyanWorlds.com Engine - MMOG client, server and tools
Copyright (C) 2011 Cyan Worlds, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
You can contact Cyan Worlds, Inc. by email legal@cyan.com
or by snail mail at:
Cyan Worlds, Inc.
14617 N Newport Hwy
Mead, WA 99021
*==LICENSE==*/
///////////////////////////////////////////////////////////////////////////////
// //
// 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

View File

@ -0,0 +1,610 @@
/*==LICENSE==*
CyanWorlds.com Engine - MMOG client, server and tools
Copyright (C) 2011 Cyan Worlds, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
You can contact Cyan Worlds, Inc. by email legal@cyan.com
or by snail mail at:
Cyan Worlds, Inc.
14617 N Newport Hwy
Mead, WA 99021
*==LICENSE==*/
///////////////////////////////////////////////////////////////////////////////
// //
// 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 );
}

View File

@ -0,0 +1,140 @@
/*==LICENSE==*
CyanWorlds.com Engine - MMOG client, server and tools
Copyright (C) 2011 Cyan Worlds, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
You can contact Cyan Worlds, Inc. by email legal@cyan.com
or by snail mail at:
Cyan Worlds, Inc.
14617 N Newport Hwy
Mead, WA 99021
*==LICENSE==*/
///////////////////////////////////////////////////////////////////////////////
// //
// 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

View File

@ -0,0 +1,374 @@
/*==LICENSE==*
CyanWorlds.com Engine - MMOG client, server and tools
Copyright (C) 2011 Cyan Worlds, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
You can contact Cyan Worlds, Inc. by email legal@cyan.com
or by snail mail at:
Cyan Worlds, Inc.
14617 N Newport Hwy
Mead, WA 99021
*==LICENSE==*/
//////////////////////////////////////////////////////////////////////////////
// //
// 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 );
}

View File

@ -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/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
You can contact Cyan Worlds, Inc. by email legal@cyan.com
or by snail mail at:
Cyan Worlds, Inc.
14617 N Newport Hwy
Mead, WA 99021
*==LICENSE==*/
//////////////////////////////////////////////////////////////////////////////
// //
// 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

View File

@ -0,0 +1,463 @@
/*==LICENSE==*
CyanWorlds.com Engine - MMOG client, server and tools
Copyright (C) 2011 Cyan Worlds, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
You can contact Cyan Worlds, Inc. by email legal@cyan.com
or by snail mail at:
Cyan Worlds, Inc.
14617 N Newport Hwy
Mead, WA 99021
*==LICENSE==*/
#include "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));
}

View File

@ -0,0 +1,122 @@
/*==LICENSE==*
CyanWorlds.com Engine - MMOG client, server and tools
Copyright (C) 2011 Cyan Worlds, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
You can contact Cyan Worlds, Inc. by email legal@cyan.com
or by snail mail at:
Cyan Worlds, Inc.
14617 N Newport Hwy
Mead, WA 99021
*==LICENSE==*/
#ifndef 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