You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
221 lines
8.8 KiB
221 lines
8.8 KiB
4 years ago
|
/*==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 plLayerInterface_inc
|
||
|
#define plLayerInterface_inc
|
||
|
|
||
|
#include "../pnNetCommon/plSynchedValue.h"
|
||
|
#include "../pnNetCommon/plSynchedObject.h"
|
||
|
#include "hsGMatState.h"
|
||
|
|
||
|
struct hsMatrix44;
|
||
|
struct hsColorRGBA;
|
||
|
class plBitmap;
|
||
|
class plMessage;
|
||
|
class hsGMatState;
|
||
|
class plShader;
|
||
|
|
||
|
class plLayerInterface : public plSynchedObject
|
||
|
{
|
||
|
friend class plLayerSDLModifier;
|
||
|
public:
|
||
|
enum plLayerDirtyBits {
|
||
|
kTransform = 0x1,
|
||
|
kPreshadeColor = 0x2,
|
||
|
kAmbientColor = 0x4,
|
||
|
kOpacity = 0x8,
|
||
|
kTexture = 0x10,
|
||
|
kState = 0x20,
|
||
|
kUVWSrc = 0x40,
|
||
|
kLODBias = 0x80,
|
||
|
kSpecularColor = 0x100,
|
||
|
kSpecularPower = 0x200,
|
||
|
kRuntimeColor = 0x400,
|
||
|
kVertexShader = 0x800,
|
||
|
kPixelShader = 0x1000,
|
||
|
kBumpEnvXfm = 0x2000,
|
||
|
|
||
|
kAllDirty = 0xffffffff
|
||
|
};
|
||
|
enum plUVWSrcModifiers {
|
||
|
kUVWPassThru = 0x00000000,
|
||
|
kUVWIdxMask = 0x0000ffff,
|
||
|
kUVWNormal = 0x00010000,
|
||
|
kUVWPosition = 0x00020000,
|
||
|
kUVWReflect = 0x00030000
|
||
|
};
|
||
|
|
||
|
protected:
|
||
|
plLayerInterface* fUnderLay;
|
||
|
plLayerInterface* fOverLay;
|
||
|
|
||
|
// NEVER MODIFY A FIELD THAT ISN'T
|
||
|
// YOUR OWN PERSONAL COPY.
|
||
|
// These are accessible so that if you're interface doesn't touch a field,
|
||
|
// it can set it's pointer to the previous interfaces pointer to that field
|
||
|
// and never even do a copy. For any fields this interface will alter, you
|
||
|
// need to alloc your own copy, and in your eval get the previous interface's
|
||
|
// value, modify it, and write it to your copy.
|
||
|
// So, if you don't touch a field, copy the pointer from prev into your channel pointer,
|
||
|
// else alloc your own and set the value to whatever you like.
|
||
|
// Then you only need to update your value when the source value changes (you'll know
|
||
|
// from dirty bits), or when you want to (you'll know from secs/frame).
|
||
|
|
||
|
// fOwnedChannels specifies which channels you have allocated and own (and will delete)
|
||
|
UInt32 fOwnedChannels;
|
||
|
// fPassThruChannels are channels which we need to pass through our underlay's values,
|
||
|
// even if we have a differing opinion on what the value should be. This let's us arbitrate
|
||
|
// between different layers that control the same channels. A layer can claim control of
|
||
|
// a channel by telling all other layers to pass through that channel via the
|
||
|
// ClaimChannels(UInt32 chans) member function. See .cpp for arbitration rules.
|
||
|
UInt32 fPassThruChannels;
|
||
|
|
||
|
hsMatrix44* fTransform;
|
||
|
hsColorRGBA* fPreshadeColor;
|
||
|
hsColorRGBA* fRuntimeColor; // Diffuse color to be used with runtime lights vs. static preshading
|
||
|
hsColorRGBA* fAmbientColor;
|
||
|
hsColorRGBA* fSpecularColor;
|
||
|
hsScalar* fOpacity;
|
||
|
|
||
|
// Would like to abstract out the mipmap, but we'll bring it
|
||
|
// along for now.
|
||
|
plBitmap** fTexture;
|
||
|
|
||
|
// (Currently) unanimatables.
|
||
|
hsGMatState* fState;
|
||
|
UInt32* fUVWSrc;
|
||
|
hsScalar* fLODBias;
|
||
|
hsScalar* fSpecularPower;
|
||
|
|
||
|
plShader** fVertexShader;
|
||
|
plShader** fPixelShader;
|
||
|
|
||
|
hsMatrix44* fBumpEnvXfm;
|
||
|
|
||
|
void IUnthread();
|
||
|
void ISetPassThru(UInt32 chans);
|
||
|
|
||
|
public:
|
||
|
plLayerInterface();
|
||
|
virtual ~plLayerInterface();
|
||
|
|
||
|
CLASSNAME_REGISTER( plLayerInterface );
|
||
|
GETINTERFACE_ANY( plLayerInterface, plSynchedObject );
|
||
|
|
||
|
plLayerInterface* BottomOfStack() { return fUnderLay ? fUnderLay->BottomOfStack() : this; }
|
||
|
plLayerInterface* TopOfStack() { return fOverLay ? fOverLay->TopOfStack() : this; }
|
||
|
|
||
|
// Used by debug code.
|
||
|
plLayerInterface* GetUnderLay() { return fUnderLay; }
|
||
|
plLayerInterface* GetOverLay() { return fOverLay; }
|
||
|
|
||
|
const hsMatrix44& GetTransform() const { return *fTransform; }
|
||
|
const hsColorRGBA& GetPreshadeColor() const { return *fPreshadeColor; }
|
||
|
const hsColorRGBA& GetRuntimeColor() const { return *fRuntimeColor; }
|
||
|
const hsColorRGBA& GetAmbientColor() const { return *fAmbientColor; }
|
||
|
const hsColorRGBA& GetSpecularColor() const { return *fSpecularColor; }
|
||
|
hsScalar GetOpacity() const { return *fOpacity; }
|
||
|
|
||
|
plBitmap* GetTexture() const { return *fTexture; }
|
||
|
|
||
|
// (Currently) unanimatables
|
||
|
UInt32 GetUVWSrc() const { return *fUVWSrc; }
|
||
|
hsScalar GetLODBias() const { return *fLODBias; }
|
||
|
hsScalar GetSpecularPower() const { return *fSpecularPower; }
|
||
|
|
||
|
const hsGMatState& GetState() const { return *fState; }
|
||
|
UInt32 GetBlendFlags() const { return fState->fBlendFlags; }
|
||
|
UInt32 GetClampFlags() const { return fState->fClampFlags; }
|
||
|
UInt32 GetShadeFlags() const { return fState->fShadeFlags; }
|
||
|
UInt32 GetZFlags() const { return fState->fZFlags; }
|
||
|
UInt32 GetMiscFlags() const { return fState->fMiscFlags; }
|
||
|
|
||
|
plShader* GetVertexShader() const { return *fVertexShader; }
|
||
|
plShader* GetPixelShader() const { return *fPixelShader; }
|
||
|
|
||
|
const hsMatrix44& GetBumpEnvMatrix() const { return *fBumpEnvXfm; }
|
||
|
|
||
|
// ClaimChannels will tell every other layer on this stack (besides this) to
|
||
|
// pass through the value, giving this layer the final say on it's value
|
||
|
void ClaimChannels(UInt32 chans);
|
||
|
|
||
|
// Eval may be called multiple times per frame, or even multiple times per render (for multiple
|
||
|
// renders per frame). The burden of deciding whether any update is necessary falls to the
|
||
|
// derived interface, but here's some info to go on.
|
||
|
// secs - world time. Time dependent effects (like time of day) look mostly at this.
|
||
|
// frame - incremented each time the camera moves. View dependent effects look at this.
|
||
|
// ignore - fields marked ignore will be overwritten (not modified) by an downstream layer, so don't bother computing.
|
||
|
// return value of fUnderLay->Eval() - bits are true for fields that an interface earlier in the chain dirtied. A field
|
||
|
// flagged dirty that you modify (as opposed to overwrite) should be updated regardless of secs and frame.
|
||
|
//
|
||
|
virtual UInt32 Eval(double secs, UInt32 frame, UInt32 ignore);
|
||
|
|
||
|
// Attach gives you a chance to decide whether you want to pass through fields from prev (by copying
|
||
|
// the pointers which you then sooner put long pins through your own eyes than modify). Alloc
|
||
|
// your own fields before Attach, and you can play with them at will. Base class will pass through
|
||
|
// (via pointer copy) all nil fields. Detach nils out any fields that are just pass through, and
|
||
|
// unthreads the requested layer from the stack, returning new top-of-stack.
|
||
|
//
|
||
|
// Given two stacks A->B and C->D, A->Attach(C) makes A->B->C->D
|
||
|
virtual plLayerInterface* Attach(plLayerInterface* prev);
|
||
|
// Given stack A->B->C->D, A->Detach(C) gives two stacks, A->B and C->D (returned value is A)
|
||
|
// If A == C (A->B->C && A->Remove(A)), it returns nil, since the it's removed A from the stack,
|
||
|
// so the two stacks are now nil and A->B->C
|
||
|
virtual plLayerInterface* Detach(plLayerInterface* nuke);
|
||
|
// Given stack A->B->C->D, A->Remove(C) gives two stacks, A->B->D and C. It returns the stack with C removed.
|
||
|
// If A==C (A->B->C && A->Remove(A)), it returns B->C.
|
||
|
virtual plLayerInterface* Remove(plLayerInterface* nuke);
|
||
|
|
||
|
plLayerInterface* GetAttached();
|
||
|
void AttachViaNotify(plLayerInterface *prev); // Export only
|
||
|
|
||
|
hsBool OwnChannel(UInt32 which) const { return 0 != (fOwnedChannels & which); }
|
||
|
|
||
|
virtual void Read(hsStream* s, hsResMgr* mgr);
|
||
|
virtual void Write(hsStream* s, hsResMgr* mgr);
|
||
|
|
||
|
virtual hsBool MsgReceive(plMessage* msg);
|
||
|
|
||
|
};
|
||
|
|
||
|
#endif // plLayerInterface_inc
|