//----------------------------------------------------------------------------- // Copyright (c) 2012 GarageGames, LLC // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to // deal in the Software without restriction, including without limitation the // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or // sell copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS // IN THE SOFTWARE. //----------------------------------------------------------------------------- #ifndef _RENDERPASSMANAGER_H_ #define _RENDERPASSMANAGER_H_ #ifndef _GFXDEVICE_H_ #include "gfx/gfxDevice.h" #endif #ifndef _SCENEOBJECT_H_ #include "scene/sceneObject.h" #endif #ifndef _SIMOBJECT_H_ #include "console/simObject.h" #endif #ifndef _DATACHUNKER_H_ #include "core/dataChunker.h" #endif #ifndef _SCENEMANAGER_H_ #include "scene/sceneManager.h" #endif #ifndef _SCENEMANAGER_H_ #include "scene/sceneManager.h" #endif #ifndef _CUBEMAPDATA_H_ #include "gfx/sim/cubemapData.h" #endif #ifndef _GFXPRIMITIVEBUFFER_H_ #include "gfx/gfxPrimitiveBuffer.h" #endif class SceneRenderState; class ISceneObject; class BaseMatInstance; struct SceneData; class ShaderData; class RenderBinManager; class LightInfo; struct RenderInst; class MatrixSet; class GFXPrimitiveBufferHandle; class CustomShaderBindingData; /// A RenderInstType hash value. typedef U32 RenderInstTypeHash; /// A a tiny wrapper around String that exposes a U32 operator so /// that we can assign the RIT to RenderInst::type field. class RenderInstType { /// For direct access to mName. friend class RenderBinManager; protected: String mName; public: RenderInstType() : mName( Invalid.mName ) { } RenderInstType( const RenderInstType &type ) : mName( type.mName ) { } RenderInstType( const String &name ) : mName( name ) { } ~RenderInstType() {} operator RenderInstTypeHash() const { return (RenderInstTypeHash)mName.getHashCaseInsensitive(); } const String& getName() const { return mName; } bool isValid() const { return (RenderInstTypeHash)*this != (RenderInstTypeHash)Invalid; } static const RenderInstType Invalid; }; /// class RenderPassManager : public SimObject { typedef SimObject Parent; public: // Default bin types. Not necessarily the only bin types in the system. // RIT = "R"ender "I"nstance "T"ype static const RenderInstType RIT_Mesh; static const RenderInstType RIT_Shadow; static const RenderInstType RIT_Sky; static const RenderInstType RIT_Terrain; static const RenderInstType RIT_Object; // objects that do their own rendering static const RenderInstType RIT_ObjectTranslucent;// self rendering; but sorted with static const RenderInstType RIT_Translucent static const RenderInstType RIT_Decal; static const RenderInstType RIT_DecalRoad; static const RenderInstType RIT_Water; static const RenderInstType RIT_Foliage; static const RenderInstType RIT_VolumetricFog; static const RenderInstType RIT_Translucent; static const RenderInstType RIT_Begin; static const RenderInstType RIT_Custom; static const RenderInstType RIT_Particle; static const RenderInstType RIT_Occluder; static const RenderInstType RIT_Editor; static const RenderInstType RIT_Probes; public: RenderPassManager(); virtual ~RenderPassManager(); /// @name Allocation interface /// @{ /// Allocate a render instance, use like so: MyRenderInstType* t = gRenderInstMgr->allocInst(); /// Valid until ::clear called. template T* allocInst() { T* inst = mChunker.alloc(); inst->clear(); return inst; } /// Allocate a matrix, valid until ::clear called. MatrixF* allocUniqueXform(const MatrixF& data) { MatrixF *r = mChunker.alloc(); *r = data; return r; } enum SharedTransformType { View, Projection, }; const MatrixF* allocSharedXform(SharedTransformType stt); void assignSharedXform(SharedTransformType stt, const MatrixF &xfm); MatrixSet &getMatrixSet() { return *mMatrixSet; } /// Allocate a GFXPrimitive object which will remain valid /// until the pass manager is cleared. GFXPrimitive* allocPrim() { return mChunker.alloc(); } /// @} /// Add a RenderInstance to the list virtual void addInst( RenderInst *inst ); /// Sorts the list of RenderInst's per bin. (Normally, one should just call renderPass) void sort(); /// Renders the list of RenderInsts (Normally, one should just call renderPass) void render( SceneRenderState *state ); /// Resets our allocated RenderInstances and Matrices. (Normally, one should just call renderPass) void clear(); // Calls sort, render, and clear void renderPass( SceneRenderState *state ); /// Returns the active depth buffer for this pass (NOTE: This value may be GFXTextureTarget::sDefaultDepthStencil) GFXTextureObject *getDepthTargetTexture(); /// Assigns the value for the above method void setDepthTargetTexture(GFXTextureObject *zTarget); /// @name RenderBinManager interface /// @{ /// Add a render bin manager to the list of render bin manager, this SceneRenderPassManager now owns the render bin manager and will free it when needed. /// @param mgr Render manager to add /// @param processAddOrder Where to add the manager in the addInst list, set to NO_PROCESSADD to skip processing /// this is in place for RenderManagers that will bypass the main ::addInst interface and doesn't want to process /// them. /// @param renderOrder Where to add the manager in the render list. void addManager(RenderBinManager* mgr); /// Removes a manager from render and process add lists /// @param mgr Render bin manager to remove, the caller is now responsible for freeing the mgr. void removeManager(RenderBinManager* mgr); /// How many render bin managers do we have? U32 getManagerCount() const { return mRenderBins.size(); } /// Get the render manager at i RenderBinManager* getManager( S32 i ) const; /// @} /// Get scene manager which this render pass belongs to. SceneManager* getSceneManager() { if ( !mSceneManager ) mSceneManager = gClientSceneGraph; return mSceneManager; } /// This signal is triggered when a render bin is about to be rendered. /// /// @param bin The render bin we're signaling. /// @param state The current scene state. /// @params preRender If true it is before the bin is rendered, else its /// after being rendered. /// typedef Signal RenderBinEventSignal; /// @see RenderBinEventSignal static RenderBinEventSignal& getRenderBinSignal(); typedef Signal AddInstSignal; AddInstSignal& getAddSignal( RenderInstTypeHash type ) { return mAddInstSignals.findOrInsert( type )->value; } // ConsoleObject interface static void initPersistFields(); DECLARE_CONOBJECT(RenderPassManager); protected: MultiTypedChunker mChunker; Vector< RenderBinManager* > mRenderBins; typedef HashTable AddInstTable; AddInstTable mAddInstSignals; SceneManager * mSceneManager; GFXTexHandle mDepthBuff; MatrixSet *mMatrixSet; /// Do a sorted insert into a vector, renderOrder bool controls which test we run for insertion. void _insertSort(Vector& list, RenderBinManager* mgr, bool renderOrder); }; //************************************************************************** // Render Instance //************************************************************************** struct RenderInst { /// The type of render instance this is. RenderInstTypeHash type; /// This should be true if the object needs to be sorted /// back to front with other translucent instances. /// @see sortDistSq bool translucentSort; /// The reference squared distance from the camera used for /// back to front sorting of the instances. /// @see translucentSort F32 sortDistSq; /// The default key used by render managers for /// internal sorting. U32 defaultKey; /// The secondary key used by render managers for /// internal sorting. U32 defaultKey2; /// Does a memset to clear the render instance. void clear(); }; struct ObjectRenderInst : public RenderInst { /// This is a delegate specific index which is usually /// used to define a mounted object. S32 objectIndex; /// Extra data to be used within the render callback. /// ObjectRenderInst does not own or cleanup this data. void *userData; /// The delegate callback function to call to render /// this object instance. /// /// @param ri The ObjectRenderInst that called the delegate. /// /// @param state The scene state we're rendering. /// /// @param overrideMat An alternative material to use during rendering... usually /// used for special renders like shadows. If the object doesn't /// support override materials it shouldn't render at all. Delegate renderDelegate; // Clear this instance. void clear(); }; struct MeshRenderInst : public RenderInst { //// GFXVertexBufferHandleBase *vertBuff; //// GFXPrimitiveBufferHandle *primBuff; /// If not NULL it is used to draw the primitive, else /// the primBuffIndex is used. /// @see primBuffIndex GFXPrimitive *prim; /// If prim is NULL then this index is used to draw the /// indexed primitive from the primitive buffer. /// @see prim U32 primBuffIndex; /// The material to setup when drawing this instance. BaseMatInstance *matInst; /// The object to world transform (world transform in most API's). const MatrixF *objectToWorld; /// The worldToCamera (view transform in most API's). const MatrixF* worldToCamera; /// The projection matrix. const MatrixF* projection; // misc render states U8 transFlags; bool reflective; F32 visibility; /// A generic hint value passed from the game /// code down to the material for use by shader /// features. void *materialHint; /// The lights we pass to the material for this /// mesh in order light importance. LightInfo* lights[8]; // textures GFXTextureObject *lightmap; GFXTextureObject *fogTex; GFXTextureObject *backBuffTex; GFXTextureObject *reflectTex; GFXTextureObject *miscTex; GFXTextureObject *accuTex; GFXCubemap *cubemap; /// @name Hardware Skinning /// { MatrixF *mNodeTransforms; U32 mNodeTransformCount; /// } #ifdef TORQUE_ENABLE_GFXDEBUGEVENTS const char *meshName; const char *objectName; #endif //Custom Shader data Vector mCustomShaderData; void clear(); }; enum ParticleSystemState { PSS_AwaitingHighResDraw = 0, // Keep this as first element so that if the offscreen manager rejects a particle system it will get drawn high-res PSS_AwaitingOffscreenDraw, PSS_AwaitingCompositeDraw, PSS_AwaitingMixedResDraw, PSS_DrawComplete, }; /// A special render instance for particles. struct ParticleRenderInst : public RenderInst { /// The vertex buffer. GFXVertexBufferHandleBase *vertBuff; /// The primitive buffer. GFXPrimitiveBufferHandle *primBuff; /// The total particle count to render. S32 count; bool glow; /// The combined model, camera, and projection transform. const MatrixF *modelViewProj; /// Blend style for the particle system enum BlendStyle { BlendUndefined = 0, BlendNormal, BlendAdditive, BlendSubtractive, BlendPremultAlpha, BlendGreyscale, BlendStyle_COUNT, }; U8 blendStyle; /// For the offscreen particle manager U8 targetIndex; /// State for the particle system ParticleSystemState systemState; /// The soft particle fade distance in meters. F32 softnessDistance; /// Bounding box render transform const MatrixF *bbModelViewProj; Point3F wsPosition; /// The particle texture. GFXTextureObject *diffuseTex; void clear(); }; class GFXOcclusionQuery; class SceneObject; /// A special render instance for occlusion tests. struct OccluderRenderInst : public RenderInst { Point3F scale; Point3F position; const MatrixF *orientation; GFXOcclusionQuery *query; // This optional query will have all pixels rendered. // Its purpose is to return to the user the full pixel count for comparison // with the other query. GFXOcclusionQuery *query2; /// Render a sphere or a box. bool isSphere; void clear(); }; #endif // _RENDERPASSMANAGER_H_