CrystalSpace

Public API Reference

csplugincommon/rendermanager/rendertree.h
Go to the documentation of this file.
00001 /*
00002     Copyright (C) 2007-2008 by Marten Svanfeldt
00003 
00004     This library is free software; you can redistribute it and/or
00005     modify it under the terms of the GNU Library General Public
00006     License as published by the Free Software Foundation; either
00007     version 2 of the License, or (at your option) any later version.
00008 
00009     This library is distributed in the hope that it will be useful,
00010     but WITHOUT ANY WARRANTY; without even the implied warranty of
00011     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012     Library General Public License for more details.
00013 
00014     You should have received a copy of the GNU Library General Public
00015     License along with this library; if not, write to the Free
00016     Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00017 */
00018 
00019 #ifndef __CS_CSPLUGINCOMMON_RENDERMANAGER_RENDERTREE_H__
00020 #define __CS_CSPLUGINCOMMON_RENDERMANAGER_RENDERTREE_H__
00021 
00026 #include "iengine/camera.h"
00027 #include "csplugincommon/rendermanager/standardtreetraits.h"
00028 #include "csutil/dirtyaccessarray.h"
00029 #include "csutil/metautils.h"
00030 #include "csutil/redblacktree.h"
00031 #include "cstool/rendermeshholder.h"
00032 
00033 struct iMeshWrapper;
00034 struct iPortalContainer;
00035 
00036 namespace CS
00037 {
00038 namespace RenderManager
00039 {
00040   class PostEffectManager;
00041   
00046   class CS_CRYSTALSPACE_EXPORT RenderTreeBase
00047   {
00048   public:
00049    struct CS_CRYSTALSPACE_EXPORT DebugPersistent
00050     {
00051       DebugPersistent ();
00052       
00053       uint RegisterDebugFlag (const char* string);
00054       uint QueryDebugFlag (const char* string);
00055     
00056       bool IsDebugFlagEnabled (uint flag);
00057       void EnableDebugFlag (uint flag, bool state);
00058     protected:
00059       uint nextDebugId;
00060       csHash<uint, csString> debugIdMappings;
00061       csHash<csArray<uint>, uint> debugIdChildren;
00062       csBitArray debugFlags;
00063     };
00064   
00065   protected:
00066     struct DebugTexture
00067     {
00068       csRef<iTextureHandle> texh;
00069       float aspect;
00070     };
00071     csArray<DebugTexture> debugTextures;
00072     DebugPersistent& debugPersist;
00073     
00074     RenderTreeBase (DebugPersistent& debugPersist)
00075     : debugPersist (debugPersist) {}
00076   public:
00085     uint RegisterDebugFlag (const char* string)
00086     { return debugPersist.RegisterDebugFlag (string); }
00091     uint QueryDebugFlag (const char* string)
00092     { return debugPersist.QueryDebugFlag (string); }
00093     
00095     bool IsDebugFlagEnabled (uint flag) const
00096     { return debugPersist.IsDebugFlagEnabled (flag); }
00103     void EnableDebugFlag (uint flag, bool state)
00104     { debugPersist.EnableDebugFlag (flag, state); }
00111     void EnableDebugFlag (const char* flagStr, bool state)
00112     {
00113       uint flag = RegisterDebugFlag (flagStr);
00114       EnableDebugFlag (flag, state); 
00115     }
00124     void AddDebugTexture (iTextureHandle* tex, float aspect = 1.0f);
00129     void RenderDebugTextures (iGraphics3D* g3d);
00131   
00133 
00136 
00137     void AddDebugLine3D (const csVector3& v1, const csVector3& v2,
00138                          const csColor& color1, const csColor& color2);
00143     void AddDebugLine3DTF (const csVector3& v1, const csVector3& v2,
00144                            const csTransform& toWorldSpace,
00145                            const csColor& color1, const csColor& color2);
00150     void AddDebugBBox (const csBox3& box,
00151                        const csTransform& toWorldSpace,
00152                        const csColor& col);
00157     void AddDebugPlane (const csPlane3& _plane,
00158                         const csTransform& toWorldSpace,
00159                         const csColor& col,
00160                         const csVector3& linesOrg = csVector3 (0));
00164     void AddDebugClipPlanes (RenderView* view);
00165 
00166     struct DebugLines
00167     {
00168       csDirtyAccessArray<csVector3> verts;
00169       csDirtyAccessArray<csVector4> colors;
00170     };
00172     const DebugLines& GetDebugLines () const { return debugLines; }
00177     void SetDebugLines (const DebugLines& lines) { debugLines = lines; }
00179   
00180       
00182 
00188     void AddDebugLineScreen (const csVector2& v1, const csVector2& v2,
00189       csRGBcolor color);
00191     
00196     void DrawDebugLines (iGraphics3D* g3d, RenderView* view);
00197   protected:
00198     DebugLines debugLines;
00199     struct DebugLineScreen
00200     {
00201       csVector2 v1, v2;
00202       csRGBcolor color;
00203     };
00204     csArray<DebugLineScreen> debugLinesScreen;
00205   };
00206 
00219   template<typename TreeTraits = RenderTreeStandardTraits>
00220   class RenderTree : public RenderTreeBase
00221   {
00222   public:
00223     //---- Forward declarations
00224     struct MeshNode;
00225     struct ContextNode;
00226     struct ContextsContainer;
00227 
00228     //---- Type definitions
00229     typedef TreeTraits TreeTraitsType;
00230     typedef RenderTree<TreeTraitsType> ThisType;
00231     typedef RenderTree<TreeTraitsType> RealTreeType;
00232 
00233     //---- Internal types
00234     typedef csFixedSizeAllocator<
00235       csRedBlackTreeMap<typename TreeTraitsType::MeshNodeKeyType,
00236         MeshNode*>::allocationUnitSize> MeshNodeTreeBlockAlloc;
00237     typedef CS::Memory::AllocatorRef<MeshNodeTreeBlockAlloc>
00238       MeshNodeTreeBlockRefAlloc;
00239     typedef csRedBlackTreeMap<typename TreeTraitsType::MeshNodeKeyType, MeshNode*,
00240       MeshNodeTreeBlockRefAlloc> MeshNodeTreeType;
00241     typedef typename MeshNodeTreeType::Iterator MeshNodeTreeIteratorType;
00242     typedef csArray<ContextNode*> ContextNodeArrayType;
00243     typedef typename ContextNodeArrayType::Iterator ContextNodeArrayIteratorType;
00244     typedef typename ContextNodeArrayType::ReverseIterator ContextNodeArrayReverseIteratorType;
00245 
00246 
00252     struct PersistentData : 
00253       public CS::Meta::EBOptHelper<typename TreeTraitsType::PersistentDataExtraDataType>
00254     {
00260       void Initialize (iShaderManager* shmgr)
00261       {
00262         svObjectToWorldName = 
00263           shmgr->GetSVNameStringset()->Request ("object2world transform");
00264         svObjectToWorldInvName = 
00265           shmgr->GetSVNameStringset()->Request ("object2world transform inverse");
00266         svFogplaneName = 
00267           shmgr->GetSVNameStringset()->Request ("fogplane");
00268           
00269         dbgDebugClearScreen = debugPersist.RegisterDebugFlag ("debugclear");
00270       }
00271 
00272       void Clear ()
00273       {
00274         // Clean up the persistent data
00275         contextNodeAllocator.Empty ();
00276         meshNodeAllocator.Empty ();
00277       }
00278 
00279       csBlockAllocator<MeshNode> meshNodeAllocator;
00280       csBlockAllocator<ContextNode> contextNodeAllocator;
00281       MeshNodeTreeBlockAlloc meshNodeTreeAlloc;
00282 
00283       CS::ShaderVarStringID svObjectToWorldName;
00284       CS::ShaderVarStringID svObjectToWorldInvName;
00285       CS::ShaderVarStringID svFogplaneName;
00286     
00287       CS::RenderManager::RenderViewCache renderViews;
00288       csRenderMeshHolder rmHolder;
00289       
00290       DebugPersistent debugPersist;
00291       uint dbgDebugClearScreen;
00292     };
00293 
00298     struct MeshNode : 
00299       public CS::Meta::EBOptHelper<typename TreeTraitsType::MeshNodeExtraDataType>
00300     {
00304       struct SingleMesh : 
00305         public CS::Meta::EBOptHelper<typename TreeTraitsType::MeshExtraDataType>
00306       {
00308         iMeshWrapper* meshWrapper;
00310         csRenderMesh* renderMesh;
00312         csZBufMode zmode;
00314         iShaderVariableContext* meshObjSVs;
00316         csRef<csShaderVariable> svObjectToWorld;
00318         csRef<csShaderVariable> svObjectToWorldInv;
00320         csFlags meshFlags;
00321 
00323         size_t contextLocalId;
00324         
00329 
00330         size_t preCopyNum;
00332         csRenderTargetAttachment preCopyAttachments[rtaNumAttachments];
00334         iTextureHandle* preCopyTextures[rtaNumAttachments];
00337         SingleMesh () : preCopyNum (0) {}
00338       };
00339 
00340       //-- Types
00341       typedef RealTreeType TreeType;
00342       typedef typename TreeType::ContextNode ContextNodeType;
00343 
00344       //-- Some local types
00345       typedef csArray<SingleMesh> MeshArrayType;
00346       typedef typename MeshArrayType::Iterator MeshArrayIteratorType;
00347 
00349       ContextNode& GetOwner() const { return *owner; }
00350       
00352       typename TreeTraitsType::MeshNodeKeyType key;
00353 
00355       int sorting;
00356 
00358       MeshArrayType meshes;
00359 
00360       MeshNode (ContextNode& owner)
00361         : owner (&owner)
00362       {}
00363     protected:
00364       ContextNode* owner;
00365 
00366       friend struct ContextNode;
00367     };
00368 
00375     struct ContextNode : public CS::Meta::EBOptHelper<typename TreeTraits::ContextNodeExtraDataType>
00376     {
00380       struct PortalHolder
00381       {
00382       #ifdef CS_DEBUG
00383 
00384         const char* db_mesh_name;
00385       #endif
00386 
00387         iPortalContainer* portalContainer;
00389         iMeshWrapper* meshWrapper;
00390       };
00391 
00392       //-- Types
00393       typedef RealTreeType TreeType;
00394 
00396       TreeType& owner;
00397 
00399       csRef<RenderView> renderView;
00401       struct TargetTexture
00402       {
00404         iTextureHandle* texHandle;
00406         int subtexture;
00407 
00408         TargetTexture() : texHandle (0), subtexture (0) {}
00409       };
00411       TargetTexture renderTargets[rtaNumAttachments];
00416       CS::Math::Matrix4 perspectiveFixup;
00418       csReversibleTransform cameraTransform;
00420       int drawFlags;
00422       iSector* sector;
00424       csRef<csShaderVariable> svFogplane;
00426       csRef<iShaderVariableContext> shadervars;
00428       CS::RenderPriorityGrouping renderGrouping;
00429       
00431       csRef<PostEffectManager> postEffects;
00432 
00434       MeshNodeTreeType meshNodes;
00435 
00437       csArray<PortalHolder> allPortals;
00438 
00440       SVArrayHolder svArrays;
00441 
00443       csDirtyAccessArray<iShader*> shaderArray;
00445       csArray<size_t> ticketArray;
00446 
00448       size_t totalRenderMeshes;
00449       
00450       ContextNode(TreeType& owner, MeshNodeTreeBlockAlloc& meshNodeAlloc) 
00451         : owner (owner), drawFlags (0),
00452           renderGrouping (CS::rpgByLayer),
00453           meshNodes (MeshNodeTreeBlockRefAlloc (meshNodeAlloc)),
00454           totalRenderMeshes (0) 
00455       {}
00456       
00460       void AddRenderMesh (csRenderMesh* rm, 
00461                           CS::Graphics::RenderPriority renderPrio,
00462                           typename MeshNode::SingleMesh& singleMeshTemplate)
00463       {
00464         typename TreeTraits::MeshNodeKeyType meshKey = 
00465           TreeTraits::GetMeshNodeKey (renderPrio, *rm, owner.GetPersistentData ());
00466         
00467         // Get the mesh node
00468         MeshNode* meshNode = meshNodes.Get (meshKey, 0);
00469         if (!meshNode)
00470         {
00471           // Get a new one
00472           meshNode = owner.CreateMeshNode (*this, meshKey);
00473     
00474           RenderTree::TreeTraitsType::SetupMeshNode(*meshNode, renderPrio, *rm, 
00475             owner.GetPersistentData ());
00476           meshNodes.Put (meshKey, meshNode);
00477         }
00478     
00479         csRef<csShaderVariable> svObjectToWorld;
00480         svObjectToWorld.AttachNew (new csShaderVariable (
00481           owner.GetPersistentData ().svObjectToWorldName));
00482         svObjectToWorld->SetValue (rm->object2world);
00483         csRef<csShaderVariable> svObjectToWorldInv;
00484         svObjectToWorldInv.AttachNew (new csShaderVariable (
00485           owner.GetPersistentData ().svObjectToWorldInvName));
00486         svObjectToWorldInv->SetValue (rm->object2world.GetInverse());
00487     
00488         typename MeshNode::SingleMesh sm (singleMeshTemplate);
00489         sm.renderMesh = rm;
00490         sm.svObjectToWorld = svObjectToWorld;
00491         sm.svObjectToWorldInv = svObjectToWorldInv;
00492         if (rm->z_buf_mode != (csZBufMode)~0) 
00493           sm.zmode = rm->z_buf_mode;
00494     
00495         meshNode->meshes.Push (sm);
00496         totalRenderMeshes++;
00497       }
00498 
00499       void MoveRenderMeshes (MeshNodeTreeIteratorType& sourceMeshNode,
00500                              ContextNode* targetContext)
00501       {
00502         typename TreeTraits::MeshNodeKeyType srcKey;
00503         MeshNode* srcNode = sourceMeshNode.PeekNext (srcKey);
00504 
00505         CS_ASSERT(!targetContext->meshNodes.Get (srcKey, nullptr));
00506         size_t nodeMeshes = srcNode->meshes.GetSize ();
00507         srcNode->owner = targetContext;
00508         targetContext->meshNodes.Put (srcKey, srcNode);
00509         totalRenderMeshes -= nodeMeshes;
00510         targetContext->totalRenderMeshes += nodeMeshes;
00511 
00512         meshNodes.Delete (sourceMeshNode);
00513       }
00514 
00516       void InsertLayer (size_t after)
00517       {
00518         const size_t layerCount = shaderArray.GetSize() / totalRenderMeshes;
00519         shaderArray.SetSize (shaderArray.GetSize() + totalRenderMeshes);
00520         const size_t layerOffsetNew = (after + 1) * totalRenderMeshes;
00521         memmove (shaderArray.GetArray() + layerOffsetNew + totalRenderMeshes,
00522           shaderArray.GetArray() + layerOffsetNew,
00523           totalRenderMeshes * (layerCount - after - 1) * sizeof(csShaderVariable*));
00524         memset (shaderArray.GetArray() + layerOffsetNew, 0,
00525           totalRenderMeshes * sizeof(csShaderVariable*));
00526 
00527         svArrays.InsertLayer (after, after);
00528       }
00529 
00534       void CopyLayerShader (size_t meshId, size_t fromLayer, size_t toLayer)
00535       {
00536         const size_t fromLayerOffset = fromLayer * totalRenderMeshes;
00537         const size_t toLayerOffset = toLayer * totalRenderMeshes;
00538         shaderArray[toLayerOffset + meshId] =
00539           shaderArray[fromLayerOffset + meshId];
00540       }
00541       
00545       bool GetTargetDimensions (int& renderW, int& renderH)
00546       {
00547         for (int a = 0; a < rtaNumAttachments; a++)
00548         {
00549           if (renderTargets[a].texHandle != 0)
00550           {
00551             renderTargets[a].texHandle->GetRendererDimensions (
00552               renderW, renderH);
00553             return true;
00554           }
00555         }
00556         if (renderView.IsValid())
00557         {
00558           iGraphics3D* g3d = renderView->GetGraphics3D();
00559           if (g3d)
00560           {
00561             renderW = g3d->GetWidth();
00562             renderH = g3d->GetHeight();
00563           }
00564         }
00565         return false;
00566       }
00567     };
00568 
00569 
00570     //---- Methods
00571     RenderTree (PersistentData& dataStorage)
00572       : RenderTreeBase (dataStorage.debugPersist), persistentData (dataStorage)
00573     {
00574     }
00575 
00576     ~RenderTree ()
00577     {
00578       persistentData.Clear ();
00579     }
00580 
00588     ContextNode* CreateContext (RenderView* rw, ContextNode* insertAfter = 0)
00589     {
00590       // Create an initial context
00591       ContextNode* newCtx = persistentData.contextNodeAllocator.Alloc (*this,
00592         persistentData.meshNodeTreeAlloc);
00593       newCtx->renderView = rw;
00594       newCtx->cameraTransform = rw->GetCamera ()->GetTransform ();
00595       newCtx->sector = rw->GetThisSector();
00596 
00597       if (insertAfter)
00598       {
00599         size_t n = contexts.Find (insertAfter);
00600         CS_ASSERT(n != csArrayItemNotFound);
00601         contexts.Insert (n+1, newCtx);
00602       }
00603       else
00604       {
00605         contexts.Push (newCtx);
00606       }
00607 
00608       return newCtx;
00609     }
00610     
00614     void DestroyContext (ContextNode* context)
00615     {
00616       CS_ASSERT(contexts.Find (context) != csArrayItemNotFound);
00617       contexts.Delete (context);
00618 
00619       persistentData.contextNodeAllocator.Free (context);
00620     }
00621 
00626     ContextNode* CloneContext (ContextNode* context)
00627     {
00628       // Create an initial context
00629       ContextNode* newCtx = persistentData.contextNodeAllocator.Alloc (*this,
00630         persistentData.meshNodeTreeAlloc);
00631       newCtx->renderView = context->renderView;
00632       memcpy (newCtx->renderTargets, context->renderTargets, sizeof (newCtx->renderTargets));
00633       newCtx->perspectiveFixup = context->perspectiveFixup;
00634       newCtx->cameraTransform = context->cameraTransform;
00635       newCtx->drawFlags = context->drawFlags;
00636       newCtx->renderGrouping = context->renderGrouping;
00637       newCtx->sector = context->sector;
00638       newCtx->svFogplane = context->svFogplane; // should that be copied?
00639       newCtx->shadervars = context->shadervars; // should that be copied?
00640       newCtx->postEffects = context->postEffects; // should that be copied?
00641 
00642       size_t n = contexts.Find (context);
00643       CS_ASSERT(n != csArrayItemNotFound);
00644       contexts.Insert (n, newCtx);
00645 
00646       return newCtx;
00647     }
00648 
00652     ContextNodeArrayIteratorType GetContextIterator ()
00653     {
00654       return contexts.GetIterator ();
00655     }
00656 
00660     ContextNodeArrayReverseIteratorType GetReverseContextIterator ()
00661     {
00662       return contexts.GetReverseIterator ();
00663     }
00664 
00668     MeshNode* CreateMeshNode (ContextNode& context, 
00669       const typename TreeTraitsType::MeshNodeKeyType& key)
00670     {
00671       MeshNode* newNode = persistentData.meshNodeAllocator.Alloc (context);
00672       newNode->key = key;
00673     
00674       return newNode;
00675     }
00676 
00677 
00681     void DestroyMeshNode (MeshNode* meshNode)
00682     {
00683       meshNode->owner.meshNodes.Delete (meshNode->key);
00684       persistentData.meshNodeAllocator.Free (meshNode);
00685     }
00686 
00687     
00689     bool IsDebugClearEnabled () const
00690     {
00691       return IsDebugFlagEnabled (persistentData.dbgDebugClearScreen);
00692     }
00693     
00694     PersistentData& GetPersistentData()
00695     {
00696       return persistentData;
00697     }
00698     const PersistentData& GetPersistentData() const
00699     {
00700       return persistentData;
00701     }
00702 
00703   protected:    
00704     PersistentData&         persistentData;
00705     ContextNodeArrayType    contexts; 
00706   };
00707 
00708 }
00709 }
00710 
00711 
00712 
00713 #endif

Generated for Crystal Space 2.0 by doxygen 1.7.6.1