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.6.1