Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
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
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
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