csplugincommon/rendermanager/svtraverse.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/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