00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #ifndef DepthSortCallback_INCLUDE_ONCE
00033 #define DepthSortCallback_INCLUDE_ONCE
00034
00035 #include <vlGraphics/Actor.hpp>
00036 #include <vlGraphics/Geometry.hpp>
00037 #include <vlGraphics/Camera.hpp>
00038
00039 namespace vl
00040 {
00074 class DepthSortCallback: public ActorEventCallback
00075 {
00076 VL_INSTRUMENT_CLASS(vl::DepthSortCallback, ActorEventCallback)
00077
00078 template<typename T>
00079 class Point
00080 {
00081 public:
00082 T A;
00083 };
00084 template<typename T>
00085 class Line
00086 {
00087 public:
00088 T A,B;
00089 };
00090 template<typename T>
00091 class Triangle
00092 {
00093 public:
00094 T A,B,C;
00095 };
00096 template<typename T>
00097 class Quad
00098 {
00099 public:
00100 T A,B,C,D;
00101 };
00102 typedef Point<unsigned int> PointUInt;
00103 typedef Line<unsigned int> LineUInt;
00104 typedef Triangle<unsigned int> TriangleUInt;
00105 typedef Quad<unsigned int> QuadUInt;
00106
00107 typedef Point<unsigned short> PointUShort;
00108 typedef Line<unsigned short> LineUShort;
00109 typedef Triangle<unsigned short> TriangleUShort;
00110 typedef Quad<unsigned short> QuadUShort;
00111
00112 typedef Point<unsigned char> PointUByte;
00113 typedef Line<unsigned char> LineUByte;
00114 typedef Triangle<unsigned char> TriangleUByte;
00115 typedef Quad<unsigned char> QuadUByte;
00116
00117 class PrimitiveZ
00118 {
00119 public:
00120 PrimitiveZ(int tri=0, float z=0.0f): mPrimitiveIndex(tri), mZ(z) {}
00121 unsigned int mPrimitiveIndex;
00122 float mZ;
00123 };
00124 class Sorter_Back_To_Front
00125 {
00126 public:
00127 bool operator()(const PrimitiveZ& t1, const PrimitiveZ& t2) const { return t1.mZ < t2.mZ; }
00128 };
00129 class Sorter_Front_To_Back
00130 {
00131 public:
00132 bool operator()(const PrimitiveZ& t1, const PrimitiveZ& t2) const { return t1.mZ > t2.mZ; }
00133 };
00134
00135 public:
00137 DepthSortCallback()
00138 {
00139 VL_DEBUG_SET_OBJECT_NAME()
00140 setSortMode(SM_SortBackToFront);
00141 }
00142
00143 void onActorDelete(Actor*) {}
00144
00146 virtual void onActorRenderStarted(Actor* actor, real , const Camera* cam, Renderable* renderable, const Shader*, int pass)
00147 {
00148
00149 if (pass > 0)
00150 return;
00151
00152 vl::mat4 matrix = cam->viewMatrix();
00153 if (actor && actor->transform())
00154 matrix *= actor->transform()->worldMatrix();
00155
00156 if (matrix == mCacheMatrix)
00157 return;
00158 else
00159 mCacheMatrix = matrix;
00160
00161
00162 Geometry* geometry = renderable->as<Geometry>();
00163
00164 if (!geometry)
00165 return;
00166
00167 const ArrayAbstract* verts = geometry->vertexArray() ? geometry->vertexArray() : geometry->vertexAttribArray(vl::VA_Position) ? geometry->vertexAttribArray(vl::VA_Position)->data() : NULL;
00168
00169 if (!verts)
00170 return;
00171
00172
00173 mat4 m;
00174 if (actor->transform())
00175 m = cam->viewMatrix() * actor->transform()->worldMatrix();
00176 else
00177 m = cam->viewMatrix();
00178 mEyeSpaceVerts.resize( verts->size() );
00179
00180 for(size_t i=0; i<verts->size(); ++i)
00181 mEyeSpaceVerts[i] = m * verts->getAsVec3(i);
00182
00183 geometry->setBufferObjectDirty(true);
00184 geometry->setDisplayListDirty(true);
00185
00186 for(int idraw=0; idraw<geometry->drawCalls()->size(); ++idraw)
00187 {
00188 DrawCall* dc = geometry->drawCalls()->at(idraw);
00189 if (dc->classType() == DrawElementsUInt::Type())
00190 sort<unsigned int, DrawElementsUInt>(dc->as<DrawElementsUInt>(), mSortedPointsUInt, mSortedLinesUInt, mSortedTrianglesUInt, mSortedQuadsUInt);
00191 else
00192 if (dc->classType() == DrawElementsUShort::Type())
00193 sort<unsigned short, DrawElementsUShort>(dc->as<DrawElementsUShort>(), mSortedPointsUShort, mSortedLinesUShort, mSortedTrianglesUShort, mSortedQuadsUShort);
00194 else
00195 if (dc->classType() == DrawElementsUByte::Type())
00196 sort<unsigned char, DrawElementsUByte>(dc->as<DrawElementsUByte>(), mSortedPointsUByte, mSortedLinesUByte, mSortedTrianglesUByte, mSortedQuadsUByte);
00197 }
00198 }
00199
00200 template<typename T, typename deT>
00201 void sort(deT* polys, std::vector<Point<T> >& sorted_points, std::vector<Line<T> >& sorted_lines, std::vector<Triangle<T> >& sorted_triangles, std::vector<Quad<T> >& sorted_quads)
00202 {
00203 if (polys->primitiveType() == PT_QUADS)
00204 {
00205
00206 mPrimitiveZ.resize( polys->indexBuffer()->size() / 4 );
00207 if (mPrimitiveZ.empty())
00208 return;
00209
00210 const typename deT::index_type* it = polys->indexBuffer()->begin();
00211 const typename deT::index_type* end = polys->indexBuffer()->end();
00212 for(unsigned iz=0; it != end; it+=4, ++iz)
00213 {
00214 mPrimitiveZ[iz].mZ = (float)(mEyeSpaceVerts[it[0]].z() + mEyeSpaceVerts[it[1]].z() + mEyeSpaceVerts[it[2]].z() + mEyeSpaceVerts[it[3]].z());
00215 mPrimitiveZ[iz].mPrimitiveIndex = iz;
00216 }
00217
00218
00219 if (sortMode() == SM_SortBackToFront)
00220 std::sort( mPrimitiveZ.begin(), mPrimitiveZ.end(), Sorter_Back_To_Front() );
00221 else
00222 std::sort( mPrimitiveZ.begin(), mPrimitiveZ.end(), Sorter_Front_To_Back() );
00223
00224
00225 sorted_quads.resize( polys->indexBuffer()->size() / 4 );
00226 Quad<T>* tris = (Quad<T>*)polys->indexBuffer()->ptr();
00227 for(unsigned int i=0; i<mPrimitiveZ.size(); ++i)
00228 sorted_quads[i] = tris[ mPrimitiveZ[i].mPrimitiveIndex ];
00229 memcpy(&tris[0], &sorted_quads[0], sizeof(sorted_quads[0])*sorted_quads.size() );
00230 }
00231 else
00232 if (polys->primitiveType() == PT_TRIANGLES)
00233 {
00234
00235 mPrimitiveZ.resize( polys->indexBuffer()->size() / 3 );
00236 if (mPrimitiveZ.empty())
00237 return;
00238
00239 const typename deT::index_type* it = polys->indexBuffer()->begin();
00240 const typename deT::index_type* end = polys->indexBuffer()->end();
00241 for(unsigned iz=0; it != end; it+=3, ++iz)
00242 {
00243 mPrimitiveZ[iz].mZ = (float)(mEyeSpaceVerts[it[0]].z() + mEyeSpaceVerts[it[1]].z() + mEyeSpaceVerts[it[2]].z());
00244 mPrimitiveZ[iz].mPrimitiveIndex = iz;
00245 }
00246
00247
00248 if (sortMode() == SM_SortBackToFront)
00249 std::sort( mPrimitiveZ.begin(), mPrimitiveZ.end(), Sorter_Back_To_Front() );
00250 else
00251 std::sort( mPrimitiveZ.begin(), mPrimitiveZ.end(), Sorter_Front_To_Back() );
00252
00253
00254 sorted_triangles.resize( polys->indexBuffer()->size() / 3 );
00255 Triangle<T>* tris = (Triangle<T>*)polys->indexBuffer()->ptr();
00256 for(unsigned int i=0; i<mPrimitiveZ.size(); ++i)
00257 sorted_triangles[i] = tris[ mPrimitiveZ[i].mPrimitiveIndex ];
00258 memcpy(&tris[0], &sorted_triangles[0], sizeof(sorted_triangles[0])*sorted_triangles.size() );
00259 }
00260 else
00261 if (polys->primitiveType() == PT_LINES)
00262 {
00263
00264 mPrimitiveZ.resize( polys->indexBuffer()->size() / 2 );
00265 if (mPrimitiveZ.empty())
00266 return;
00267
00268 const typename deT::index_type* it = polys->indexBuffer()->begin();
00269 const typename deT::index_type* end = polys->indexBuffer()->end();
00270 for(unsigned iz=0; it != end; it+=2, ++iz)
00271 {
00272 mPrimitiveZ[iz].mZ = (float)(mEyeSpaceVerts[it[0]].z() + mEyeSpaceVerts[it[1]].z());
00273 mPrimitiveZ[iz].mPrimitiveIndex = iz;
00274 }
00275
00276
00277 if (sortMode() == SM_SortBackToFront)
00278 std::sort( mPrimitiveZ.begin(), mPrimitiveZ.end(), Sorter_Back_To_Front() );
00279 else
00280 std::sort( mPrimitiveZ.begin(), mPrimitiveZ.end(), Sorter_Front_To_Back() );
00281
00282
00283 sorted_lines.resize( polys->indexBuffer()->size() / 2 );
00284 Line<T>* tris = (Line<T>*)polys->indexBuffer()->ptr();
00285 for(unsigned int i=0; i<mPrimitiveZ.size(); ++i)
00286 sorted_lines[i] = tris[ mPrimitiveZ[i].mPrimitiveIndex ];
00287 memcpy(&tris[0], &sorted_lines[0], sizeof(sorted_lines[0])*sorted_lines.size() );
00288 }
00289 else
00290 if (polys->primitiveType() == PT_POINTS)
00291 {
00292
00293 mPrimitiveZ.resize( polys->indexBuffer()->size() );
00294 if (mPrimitiveZ.empty())
00295 return;
00296
00297 const typename deT::index_type* it = polys->indexBuffer()->begin();
00298 const typename deT::index_type* end = polys->indexBuffer()->end();
00299 for(unsigned iz=0; it != end; ++it, ++iz)
00300 {
00301 mPrimitiveZ[iz].mZ = (float)mEyeSpaceVerts[it[0]].z();
00302 mPrimitiveZ[iz].mPrimitiveIndex = iz;
00303 }
00304
00305
00306 if (sortMode() == SM_SortBackToFront)
00307 std::sort( mPrimitiveZ.begin(), mPrimitiveZ.end(), Sorter_Back_To_Front() );
00308 else
00309 std::sort( mPrimitiveZ.begin(), mPrimitiveZ.end(), Sorter_Front_To_Back() );
00310
00311
00312 sorted_points.resize( polys->indexBuffer()->size() );
00313 Point<T>* tris = (Point<T>*)polys->indexBuffer()->ptr();
00314 for(unsigned int i=0; i<mPrimitiveZ.size(); ++i)
00315 sorted_points[i] = tris[ mPrimitiveZ[i].mPrimitiveIndex ];
00316 memcpy(&tris[0], &sorted_points[0], sizeof(sorted_points[0])*sorted_points.size() );
00317 }
00318
00319 if (Has_BufferObject)
00320 {
00321 if (polys->indexBuffer()->bufferObject()->handle())
00322 {
00323 if (polys->indexBuffer()->bufferObject()->usage() != vl::BU_DYNAMIC_DRAW)
00324 {
00325 polys->indexBuffer()->bufferObject()->setBufferData(vl::BU_DYNAMIC_DRAW);
00326 polys->indexBuffer()->setBufferObjectDirty(false);
00327 }
00328 else
00329 polys->indexBuffer()->setBufferObjectDirty(true);
00330 }
00331 }
00332 }
00333
00334 ESortMode sortMode() const { return mSortMode; }
00335 void setSortMode(ESortMode sort_mode) { mSortMode = sort_mode; }
00336
00340 void invalidateCache() { mCacheMatrix = vl::mat4(); }
00341
00342 protected:
00343 std::vector<vec3> mEyeSpaceVerts;
00344 std::vector<PrimitiveZ> mPrimitiveZ;
00345
00346 std::vector<PointUInt> mSortedPointsUInt;
00347 std::vector<LineUInt> mSortedLinesUInt;
00348 std::vector<TriangleUInt> mSortedTrianglesUInt;
00349 std::vector<QuadUInt> mSortedQuadsUInt;
00350
00351 std::vector<PointUShort> mSortedPointsUShort;
00352 std::vector<LineUShort> mSortedLinesUShort;
00353 std::vector<TriangleUShort> mSortedTrianglesUShort;
00354 std::vector<QuadUShort> mSortedQuadsUShort;
00355
00356 std::vector<PointUByte> mSortedPointsUByte;
00357 std::vector<LineUByte> mSortedLinesUByte;
00358 std::vector<TriangleUByte> mSortedTrianglesUByte;
00359 std::vector<QuadUByte> mSortedQuadsUByte;
00360
00361 vl::mat4 mCacheMatrix;
00362
00363 ESortMode mSortMode;
00364 };
00365 }
00366
00367 #endif