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.
204 lines
8.2 KiB
204 lines
8.2 KiB
/*==LICENSE==* |
|
|
|
CyanWorlds.com Engine - MMOG client, server and tools |
|
Copyright (C) 2011 Cyan Worlds, Inc. |
|
|
|
This program is free software: you can redistribute it and/or modify |
|
it under the terms of the GNU General Public License as published by |
|
the Free Software Foundation, either version 3 of the License, or |
|
(at your option) any later version. |
|
|
|
This program is distributed in the hope that it will be useful, |
|
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
GNU General Public License for more details. |
|
|
|
You should have received a copy of the GNU General Public License |
|
along with this program. If not, see <http://www.gnu.org/licenses/>. |
|
|
|
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
|
|
|