csplugincommon/rendermanager/svsetup.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_SVSETUP_H__ 00020 #define __CS_CSPLUGINCOMMON_RENDERMANAGER_SVSETUP_H__ 00021 00026 #include "iengine/portal.h" 00027 #include "iengine/sector.h" 00028 #include "ivideo/material.h" 00029 00030 #include "csplugincommon/rendermanager/rendertree.h" 00031 #include "csplugincommon/rendermanager/operations.h" 00032 00033 class csShaderVariable; 00034 00035 namespace CS 00036 { 00037 namespace RenderManager 00038 { 00039 00056 template<typename RenderTree, typename LayerConfigType> 00057 class StandardSVSetup 00058 { 00059 public: 00060 00061 StandardSVSetup (SVArrayHolder& svArrays, 00062 const LayerConfigType& layerConfig) 00063 : svArrays (svArrays), layerConfig (layerConfig) 00064 { 00065 } 00066 00068 void operator() (typename RenderTree::MeshNode* node) 00069 { 00070 csShaderVariableStack localStack; 00071 00072 // @@TODO: keep the sv-name around in a better way 00073 const size_t svO2wName = node->GetOwner().owner.GetPersistentData().svObjectToWorldName; 00074 const size_t svO2wIName = node->GetOwner().owner.GetPersistentData().svObjectToWorldInvName; 00075 00076 for (size_t i = 0; i < node->meshes.GetSize (); ++i) 00077 { 00078 typename RenderTree::MeshNode::SingleMesh& mesh = node->meshes[i]; 00079 00080 csRenderMesh* rm = mesh.renderMesh; 00081 for (size_t layer = 0; layer < layerConfig.GetLayerCount (); ++layer) 00082 { 00083 svArrays.SetupSVStack (localStack, layer, mesh.contextLocalId); 00084 00085 // Push all contexts here 00086 // @@TODO: get more of them 00087 localStack[svO2wName] = mesh.svObjectToWorld; 00088 localStack[svO2wIName] = mesh.svObjectToWorldInv; 00089 iShaderVariableContext* layerContext = 00090 layerConfig.GetSVContext (layer); 00091 if (layerContext) layerContext->PushVariables (localStack); 00092 if (rm->material) 00093 rm->material->GetMaterial ()->PushVariables (localStack); 00094 if (rm->variablecontext) 00095 rm->variablecontext->PushVariables (localStack); 00096 if (mesh.meshObjSVs) 00097 mesh.meshObjSVs->PushVariables (localStack); 00098 } 00099 } 00100 00101 } 00102 00103 private: 00104 SVArrayHolder& svArrays; 00105 const LayerConfigType& layerConfig; 00106 }; 00107 00108 template<typename RenderTree, typename LayerConfigType> 00109 struct OperationTraits<StandardSVSetup<RenderTree, LayerConfigType> > 00110 { 00111 typedef OperationUnordered Ordering; 00112 }; 00113 00114 00121 template<typename RenderTree, typename LayerConfigType> 00122 class ShaderSVSetup 00123 { 00124 public: 00125 typedef csArray<iShader*> ShaderArrayType; 00126 typedef csArray<size_t> TicketArrayType; 00127 00128 ShaderSVSetup (SVArrayHolder& svArrays, const ShaderArrayType& shaderArray, 00129 const TicketArrayType& tickets, const LayerConfigType& layerConfig) 00130 : svArrays (svArrays), shaderArray (shaderArray), 00131 ticketArray (tickets), layerConfig (layerConfig) 00132 { 00133 tempStack.Setup (svArrays.GetNumSVNames ()); 00134 } 00135 00136 void operator() (typename RenderTree::MeshNode* node) 00137 { 00138 const size_t totalMeshes = node->GetOwner().totalRenderMeshes; 00139 00140 for (size_t i = 0; i < node->meshes.GetSize (); ++i) 00141 { 00142 typename RenderTree::MeshNode::SingleMesh& mesh = node->meshes[i]; 00143 00144 for (size_t layer = 0; layer < layerConfig.GetLayerCount (); ++layer) 00145 { 00146 size_t layerOffset = layer*totalMeshes; 00147 00148 tempStack.Clear (); 00149 00150 iShader* shader = shaderArray[mesh.contextLocalId+layerOffset]; 00151 if (shader) 00152 { 00153 shader->PushShaderVariables (tempStack, 00154 ticketArray[mesh.contextLocalId+layerOffset]); 00155 00156 // Back-merge it onto the real one 00157 csShaderVariableStack localStack; 00158 svArrays.SetupSVStack (localStack, layer, mesh.contextLocalId); 00159 localStack.MergeFront (tempStack); 00160 } 00161 } 00162 } 00163 } 00164 00165 private: 00166 SVArrayHolder& svArrays; 00167 const ShaderArrayType& shaderArray; 00168 const TicketArrayType& ticketArray; 00169 csShaderVariableStack tempStack; 00170 const LayerConfigType& layerConfig; 00171 }; 00172 00173 template<typename RenderTree, typename LayerConfigType> 00174 struct OperationTraits<ShaderSVSetup<RenderTree, LayerConfigType> > 00175 { 00176 typedef OperationUnordered Ordering; 00177 }; 00178 00179 00191 template<typename ContextNode, typename LayerConfigType> 00192 void SetupStandardSVs (ContextNode& context, LayerConfigType& layerConfig, 00193 iShaderManager* shaderManager, iSector* sector) 00194 { 00195 if (context.totalRenderMeshes == 0) return; 00196 00197 // Setup SV arrays 00198 context.svArrays.Setup ( 00199 layerConfig.GetLayerCount(), 00200 shaderManager->GetSVNameStringset ()->GetSize (), 00201 context.totalRenderMeshes); 00202 00203 // Push the default stuff 00204 csShaderVariableStack& svStack = shaderManager->GetShaderVariableStack (); 00205 00206 { 00207 context.svArrays.SetupSVStack (svStack, 0, 0); 00208 00209 shaderManager->PushVariables (svStack); 00210 if (context.shadervars.IsValid()) 00211 context.shadervars->PushVariables (svStack); 00212 sector->GetSVContext ()->PushVariables (svStack); 00213 00214 // @@@ Split out fog plane setup into it's own function? 00215 CS::RenderManager::RenderView* rview = context.renderView; 00216 if (sector->HasFog()) 00217 { 00218 context.svFogplane.AttachNew (new csShaderVariable ( 00219 context.owner.GetPersistentData().svFogplaneName)); 00220 00221 //construct a cameraplane 00222 csVector4 fogPlane; 00223 iPortal *lastPortal = rview->GetLastPortal(); 00224 if(lastPortal) 00225 { 00226 csPlane3 plane; 00227 lastPortal->ComputeCameraPlane(rview->GetCamera()->GetTransform(), plane); 00228 fogPlane = -plane.norm; 00229 fogPlane.w = plane.DD; 00230 } 00231 else 00232 { 00233 fogPlane = csVector4(0.0,0.0,-1.0,0.0); 00234 } 00235 context.svFogplane->SetValue (fogPlane); 00236 00237 svStack[context.owner.GetPersistentData().svFogplaneName] 00238 = context.svFogplane; 00239 } 00240 00241 // Replicate 00242 context.svArrays.ReplicateSet (0, 0, 1); 00243 context.svArrays.ReplicateLayerZero (); 00244 } 00245 } 00246 00247 } 00248 } 00249 00250 #endif
Generated for Crystal Space 2.0 by doxygen 1.6.1