CrystalSpace

Public API Reference

csplugincommon/rendermanager/svtraverse.h
Go to the documentation of this file.
00001 /*
00002     Copyright (C) 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_SVTRAVERSE_H__
00020 #define __CS_CSPLUGINCOMMON_RENDERMANAGER_SVTRAVERSE_H__
00021 
00026 #include "csplugincommon/rendermanager/operations.h"
00027 #include "csutil/bitarray.h"
00028 
00029 namespace CS
00030 {
00031 namespace RenderManager
00032 {
00043   template<typename RenderTree, typename Fn>
00044   class TraverseUsedSVSets
00045   {
00046   public:
00047     TraverseUsedSVSets (Fn& fn, size_t maxNumSVs, uint svUsers = iShader::svuAll)
00048       : fn (fn), svUsers (svUsers)
00049     {
00050       names.SetSize (maxNumSVs);
00051     }
00052 
00053     void operator() (typename RenderTree::MeshNode* node)
00054     {
00055       typename RenderTree::ContextNode& context = node->GetOwner();
00056       
00057 
00058       iShader* lastShader = 0;
00059       size_t lastTicket = ~0;
00060 
00061       for (size_t layer = 0; layer < context.svArrays.GetNumLayers(); ++layer)
00062       {
00063         const size_t layerOffset = context.totalRenderMeshes*layer;
00064         
00065         for (size_t m = 0; m < node->meshes.GetSize (); ++m)
00066         {
00067           typename RenderTree::MeshNode::SingleMesh& mesh = node->meshes.Get (m);
00068           iShader* shader = context.shaderArray[mesh.contextLocalId+layerOffset];
00069 
00070           // Skip meshes without shader (for current layer)
00071           if (!shader)
00072             continue;
00073           size_t ticket = context.ticketArray[mesh.contextLocalId+layerOffset];
00074 
00075           if (shader != lastShader || 
00076               ticket != lastTicket)
00077           {
00078             names.Clear();
00079             shader->GetUsedShaderVars (ticket, names, svUsers);
00080             lastShader = shader;
00081           }
00082           
00083           fn (node, layer, mesh, names);
00084         }
00085       }
00086     }
00087 
00088   private:
00089     Fn& fn;
00090     csBitArray names;
00091     uint svUsers;
00092   };
00093 
00103   template<typename RenderTree, typename Fn>
00104   class TraverseUsedSVs
00105   {
00106   public:
00107     TraverseUsedSVs (Fn& fn, size_t maxNumSVs, uint svUsers = iShader::svuAll)
00108       : proxy (fn), traverseSets (proxy, maxNumSVs, svUsers)
00109     {
00110     }
00111 
00112     void operator() (typename RenderTree::MeshNode* node)
00113     {
00114       traverseSets.operator() (node);
00115     }
00116 
00117   private:
00118     struct TraverseSVsProxy
00119     {
00120       Fn& fn;
00121       
00122       TraverseSVsProxy (Fn& fn) : fn (fn) { }
00123   
00124       void operator() (const typename RenderTree::MeshNode* node,
00125                        size_t layer,
00126                        const typename RenderTree::MeshNode::SingleMesh& mesh,
00127                        const csBitArray& names)
00128       {
00129         // No names to check anyway, so leave right away ...
00130         if (names.AllBitsFalse()) return;
00131         
00132         typename RenderTree::ContextNode& context = node->GetOwner();
00133 
00134         csShaderVariableStack varStack;
00135         context.svArrays.SetupSVStack (varStack, layer, mesh.contextLocalId);
00136   
00137         size_t lastName = csMin (names.GetSize(), varStack.GetSize());
00138   
00139         csBitArray::SetBitIterator it = names.GetSetBitIterator ();
00140         while (it.HasNext ())
00141         {
00142           size_t name = it.Next ();
00143           if (name >= lastName)
00144             break;
00145   
00146           CS::ShaderVarStringID varName ((CS::StringIDValue)name);
00147   
00148           csShaderVariable* sv = varStack[name];
00149           if (sv != 0) 
00150             fn (varName, sv);
00151         }
00152       }
00153     };
00154     TraverseSVsProxy proxy;
00155     TraverseUsedSVSets<RenderTree, TraverseSVsProxy> traverseSets;
00156   };
00157 
00158 }
00159 }
00160 
00161 #endif

Generated for Crystal Space 2.0 by doxygen 1.7.6.1