csplugincommon/rendermanager/rendertree.h Source File (Crystal Space 2.0 Public API Reference)

| ## Public API Reference

- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

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