csplugincommon/rendermanager/standardsorter.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_STANDARDSOTER_H__ 00020 #define __CS_CSPLUGINCOMMON_RENDERMANAGER_STANDARDSOTER_H__ 00021 00026 #include "csplugincommon/rendermanager/operations.h" 00027 00028 #include "ivideo/rendermesh.h" 00029 #include "csgeom/vector3.h" 00030 00031 namespace CS 00032 { 00033 namespace RenderManager 00034 { 00035 00054 template<typename Tree> 00055 class StandardMeshSorter 00056 { 00057 public: 00058 StandardMeshSorter (iEngine* engine) 00059 : engine (engine), cameraOrigin (0,0,0) 00060 { 00061 // Build table of sorting options 00062 renderPriorityCount = uint (engine->GetRenderPriorityCount ()); 00063 sortingTypeTable = new int[renderPriorityCount]; 00064 00065 for (uint i = 0; i < renderPriorityCount; ++i) 00066 { 00067 sortingTypeTable[i] = -1; 00068 } 00069 } 00070 00071 ~StandardMeshSorter () 00072 { 00073 delete[] sortingTypeTable; 00074 } 00075 00077 void SetupCameraLocation (const csVector3& vec) 00078 { 00079 cameraOrigin = vec; 00080 } 00081 00085 void operator()(typename Tree::MeshNode* meshNode) 00086 { 00087 // Get the render priority for node 00088 CS::Graphics::RenderPriority renderPrio (meshNode->priority); 00089 00090 int sorting = GetSorting (renderPrio); 00091 meshNode->sorting = sorting; 00092 switch (sorting) 00093 { 00094 case CS_RENDPRI_SORT_NONE: 00095 { 00096 NormalSorter sorter; 00097 meshNode->meshes.SortStable (sorter); // Use a stable sort to keep some b2f 00098 } 00099 break; 00100 case CS_RENDPRI_SORT_BACK2FRONT: 00101 { 00102 // B2F: we want to render meshes with the larger distance first. 00103 DistanceSorter sorter (cameraOrigin, -1); 00104 meshNode->meshes.Sort (sorter); 00105 } 00106 break; 00107 case CS_RENDPRI_SORT_FRONT2BACK: 00108 { 00109 // F2B: we want to render meshes with the smaller distance first. 00110 DistanceSorter sorter (cameraOrigin, 1); 00111 meshNode->meshes.Sort (sorter); 00112 } 00113 break; 00114 default: 00115 CS_ASSERT_MSG("Invalid sorting mode!", 0); 00116 } 00117 } 00118 00119 00120 private: 00121 00125 class NormalSorter 00126 { 00127 public: 00128 bool operator() (typename Tree::MeshNode::SingleMesh const& m1, 00129 typename Tree::MeshNode::SingleMesh const& m2) 00130 { 00131 const csRenderMesh* rm1 = m1.renderMesh; 00132 const csRenderMesh* rm2 = m2.renderMesh; 00133 00134 if(rm1->material < rm2->material) 00135 return true; 00136 00137 if((rm1->material == rm2->material) && 00138 (rm1->geometryInstance < rm2->geometryInstance)) 00139 return true; 00140 00141 return false; 00142 } 00143 00144 }; 00145 00152 class DistanceSorter : NormalSorter 00153 { 00154 public: 00155 DistanceSorter (const csVector3& cameraOrigin, const float scaleFactor) 00156 : cameraOrigin (cameraOrigin), scaleFactor (scaleFactor) 00157 {} 00158 00159 bool operator() (typename Tree::MeshNode::SingleMesh const& m1, 00160 typename Tree::MeshNode::SingleMesh const& m2) 00161 { 00162 const csRenderMesh* rm1 = m1.renderMesh; 00163 const csRenderMesh* rm2 = m2.renderMesh; 00164 00165 const float distSqRm1 = scaleFactor*(rm1->worldspace_origin - cameraOrigin).SquaredNorm (); 00166 const float distSqRm2 = scaleFactor*(rm2->worldspace_origin - cameraOrigin).SquaredNorm (); 00167 00168 if (distSqRm1 < distSqRm2) 00169 return true; 00170 00171 if (distSqRm2 < distSqRm1) 00172 return false; 00173 00174 return NormalSorter::operator () (m1, m2); 00175 } 00176 00177 00178 private: 00179 const csVector3& cameraOrigin; 00180 const float scaleFactor; 00181 }; 00182 00183 csRenderPrioritySorting GetSorting (CS::Graphics::RenderPriority renderPrio) 00184 { 00185 CS_ASSERT(renderPrio.IsValid() && renderPrio < renderPriorityCount); 00186 00187 if (sortingTypeTable[renderPrio] < 0) 00188 { 00189 sortingTypeTable[renderPrio] = engine->GetRenderPrioritySorting (renderPrio); 00190 } 00191 00192 return (csRenderPrioritySorting)sortingTypeTable[renderPrio]; 00193 } 00194 00195 uint renderPriorityCount; 00196 int* sortingTypeTable; 00197 iEngine* engine; 00198 csVector3 cameraOrigin; 00199 }; 00200 00202 template<typename RenderTree> 00203 struct OperationTraits<StandardMeshSorter<RenderTree> > 00204 { 00205 typedef OperationUnordered Ordering; 00206 }; 00207 00208 } 00209 } 00210 00211 #endif
Generated for Crystal Space 2.1 by doxygen 1.6.1
