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 {
00067 class DepthSortCallback: public ActorEventCallback
00068 {
00069 template<typename T>
00070 class Point
00071 {
00072 public:
00073 T A;
00074 };
00075 template<typename T>
00076 class Line
00077 {
00078 public:
00079 T A,B;
00080 };
00081 template<typename T>
00082 class Triangle
00083 {
00084 public:
00085 T A,B,C;
00086 };
00087 template<typename T>
00088 class Quad
00089 {
00090 public:
00091 T A,B,C,D;
00092 };
00093 typedef Point<unsigned int> PointUInt;
00094 typedef Line<unsigned int> LineUInt;
00095 typedef Triangle<unsigned int> TriangleUInt;
00096 typedef Quad<unsigned int> QuadUInt;
00097
00098 typedef Point<unsigned short> PointUShort;
00099 typedef Line<unsigned short> LineUShort;
00100 typedef Triangle<unsigned short> TriangleUShort;
00101 typedef Quad<unsigned short> QuadUShort;
00102
00103 typedef Point<unsigned char> PointUByte;
00104 typedef Line<unsigned char> LineUByte;
00105 typedef Triangle<unsigned char> TriangleUByte;
00106 typedef Quad<unsigned char> QuadUByte;
00107
00108 class PrimitiveZ
00109 {
00110 public:
00111 PrimitiveZ(int tri=0, float z=0.0f): mPrimitiveIndex(tri), mZ(z) {}
00112 bool operator<(const PrimitiveZ& other) const { return mZ < other.mZ; }
00113 unsigned int mPrimitiveIndex;
00114 float mZ;
00115 };
00116 class Sorter_Back_To_Front
00117 {
00118 public:
00119 bool operator()(const PrimitiveZ& t1, const PrimitiveZ& t2) const { return t1.mZ < t2.mZ; }
00120 };
00121 class Sorter_Front_To_Back
00122 {
00123 public:
00124 bool operator()(const PrimitiveZ& t1, const PrimitiveZ& t2) const { return t1.mZ > t2.mZ; }
00125 };
00126
00127 public:
00128 virtual const char* className() { return "vl::DepthSortCallback"; }
00129
00131 DepthSortCallback()
00132 {
00133 VL_DEBUG_SET_OBJECT_NAME()
00134 mEyeSpaceVerts = new ArrayFloat3;
00135 setSortMode(SM_SortBackToFront);
00136 }
00137
00138 void onActorDelete(Actor*) {}
00139
00141 virtual void onActorRenderStarted(Actor* actor, Real , const Camera* cam, Renderable* renderable, const Shader*, int pass)
00142 {
00143
00144 if (pass > 0)
00145 return;
00146
00147 vl::mat4 matrix = cam->viewMatrix();
00148 if (actor && actor->transform())
00149 matrix *= actor->transform()->worldMatrix();
00150
00151 if (matrix == mCacheMatrix)
00152 return;
00153 else
00154 mCacheMatrix = matrix;
00155
00156
00157 ref<Geometry> geometry = dynamic_cast<Geometry*>(renderable);
00158 if (!geometry)
00159 return;
00160
00161 geometry->setDisplayListDirty(true);
00162
00163 ref<ArrayFloat3> verts = dynamic_cast<ArrayFloat3*>(geometry->vertexArray());
00164
00165 if (!verts)
00166 return;
00167
00168
00169 fmat4 m;
00170 if (actor->transform())
00171 m = (fmat4)(cam->viewMatrix() * actor->transform()->worldMatrix());
00172 else
00173 m = (fmat4)cam->viewMatrix();
00174 mEyeSpaceVerts->resize( verts->size() );
00175
00176 for(size_t i=0; i<verts->size(); ++i)
00177 (*mEyeSpaceVerts)[i] = m * (*verts)[i];
00178
00179 geometry->setVBODirty(true);
00180
00181 for(int idraw=0; idraw<geometry->drawCalls()->size(); ++idraw)
00182 {
00183 ref<DrawElementsUInt> polys_uint = dynamic_cast<DrawElementsUInt*> (geometry->drawCalls()->at(idraw));
00184 ref<DrawElementsUShort> polys_ushort = dynamic_cast<DrawElementsUShort*>(geometry->drawCalls()->at(idraw));
00185 ref<DrawElementsUByte> polys_ubyte = dynamic_cast<DrawElementsUByte*> (geometry->drawCalls()->at(idraw));
00186
00187 if (polys_uint)
00188 sort<unsigned int,DrawElementsUInt>(polys_uint.get(), mSortedPointsUInt, mSortedLinesUInt, mSortedTrianglesUInt, mSortedQuadsUInt);
00189 else
00190 if (polys_ushort)
00191 sort<unsigned short,DrawElementsUShort>(polys_ushort.get(), mSortedPointsUShort, mSortedLinesUShort, mSortedTrianglesUShort, mSortedQuadsUShort);
00192 else
00193 if (polys_ubyte)
00194 sort<unsigned char,DrawElementsUByte>(polys_ubyte.get(), mSortedPointsUByte, mSortedLinesUByte, mSortedTrianglesUByte, mSortedQuadsUByte);
00195 }
00196 }
00197
00198 template<typename T, typename deT>
00199 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)
00200 {
00201 if (polys->primitiveType() == PT_QUADS)
00202 {
00203
00204 mPrimitiveZ.resize( polys->indices()->size() / 4 );
00205 if (mPrimitiveZ.empty())
00206 return;
00207
00208 for(unsigned iz=0, i=0; i<polys->indices()->size(); i+=4, ++iz)
00209 {
00210 int a = polys->indices()->at(i+0);
00211 int b = polys->indices()->at(i+1);
00212 int c = polys->indices()->at(i+2);
00213 int d = polys->indices()->at(i+2);
00214 mPrimitiveZ[iz].mZ = (*mEyeSpaceVerts)[a].z() + (*mEyeSpaceVerts)[b].z() + (*mEyeSpaceVerts)[c].z() + (*mEyeSpaceVerts)[d].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->indices()->size() / 4 );
00226 Quad<T>* tris = (Quad<T>*)polys->indices()->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->indices()->size() / 3 );
00236 if (mPrimitiveZ.empty())
00237 return;
00238
00239 for(unsigned iz=0, i=0; i<polys->indices()->size(); i+=3, ++iz)
00240 {
00241 int a = polys->indices()->at(i+0);
00242 int b = polys->indices()->at(i+1);
00243 int c = polys->indices()->at(i+2);
00244 mPrimitiveZ[iz].mZ = (*mEyeSpaceVerts)[a].z() + (*mEyeSpaceVerts)[b].z() + (*mEyeSpaceVerts)[c].z();
00245 mPrimitiveZ[iz].mPrimitiveIndex = iz;
00246 }
00247
00248
00249 if (sortMode() == SM_SortBackToFront)
00250 std::sort( mPrimitiveZ.begin(), mPrimitiveZ.end(), Sorter_Back_To_Front() );
00251 else
00252 std::sort( mPrimitiveZ.begin(), mPrimitiveZ.end(), Sorter_Front_To_Back() );
00253
00254
00255 sorted_triangles.resize( polys->indices()->size() / 3 );
00256 Triangle<T>* tris = (Triangle<T>*)polys->indices()->ptr();
00257 for(unsigned int i=0; i<mPrimitiveZ.size(); ++i)
00258 sorted_triangles[i] = tris[ mPrimitiveZ[i].mPrimitiveIndex ];
00259 memcpy(&tris[0], &sorted_triangles[0], sizeof(sorted_triangles[0])*sorted_triangles.size() );
00260 }
00261 else
00262 if (polys->primitiveType() == PT_LINES)
00263 {
00264
00265 mPrimitiveZ.resize( polys->indices()->size() / 2 );
00266 if (mPrimitiveZ.empty())
00267 return;
00268
00269 for(unsigned iz=0, i=0; i<polys->indices()->size(); i+=2, ++iz)
00270 {
00271 int a = polys->indices()->at(i+0);
00272 int b = polys->indices()->at(i+1);
00273 mPrimitiveZ[iz].mZ = (*mEyeSpaceVerts)[a].z() + (*mEyeSpaceVerts)[b].z();
00274 mPrimitiveZ[iz].mPrimitiveIndex = iz;
00275 }
00276
00277
00278 if (sortMode() == SM_SortBackToFront)
00279 std::sort( mPrimitiveZ.begin(), mPrimitiveZ.end(), Sorter_Back_To_Front() );
00280 else
00281 std::sort( mPrimitiveZ.begin(), mPrimitiveZ.end(), Sorter_Front_To_Back() );
00282
00283
00284 sorted_lines.resize( polys->indices()->size() / 2 );
00285 Line<T>* tris = (Line<T>*)polys->indices()->ptr();
00286 for(unsigned int i=0; i<mPrimitiveZ.size(); ++i)
00287 sorted_lines[i] = tris[ mPrimitiveZ[i].mPrimitiveIndex ];
00288 memcpy(&tris[0], &sorted_lines[0], sizeof(sorted_lines[0])*sorted_lines.size() );
00289 }
00290 else
00291 if (polys->primitiveType() == PT_POINTS)
00292 {
00293
00294 mPrimitiveZ.resize( polys->indices()->size() );
00295 if (mPrimitiveZ.empty())
00296 return;
00297
00298 for(unsigned iz=0, i=0; i<polys->indices()->size(); ++i, ++iz)
00299 {
00300 mPrimitiveZ[iz].mZ = (*mEyeSpaceVerts)[polys->indices()->at(i)].z();
00301 mPrimitiveZ[iz].mPrimitiveIndex = iz;
00302 }
00303
00304
00305 if (sortMode() == SM_SortBackToFront)
00306 std::sort( mPrimitiveZ.begin(), mPrimitiveZ.end(), Sorter_Back_To_Front() );
00307 else
00308 std::sort( mPrimitiveZ.begin(), mPrimitiveZ.end(), Sorter_Front_To_Back() );
00309
00310
00311 sorted_points.resize( polys->indices()->size() );
00312 Point<T>* tris = (Point<T>*)polys->indices()->ptr();
00313 for(unsigned int i=0; i<mPrimitiveZ.size(); ++i)
00314 sorted_points[i] = tris[ mPrimitiveZ[i].mPrimitiveIndex ];
00315 memcpy(&tris[0], &sorted_points[0], sizeof(sorted_points[0])*sorted_points.size() );
00316 }
00317
00318 if (GLEW_ARB_vertex_buffer_object||GLEW_VERSION_1_5||GLEW_VERSION_3_0)
00319 if (polys->indices()->gpuBuffer()->handle())
00320 {
00321 if (polys->indices()->gpuBuffer()->usage() != vl::BU_DYNAMIC_DRAW)
00322 {
00323 polys->indices()->gpuBuffer()->setBufferData(vl::BU_DYNAMIC_DRAW);
00324 polys->indices()->setVBODirty(false);
00325 }
00326 else
00327 polys->indices()->setVBODirty(true);
00328 }
00329 }
00330
00331 ESortMode sortMode() const { return mSortMode; }
00332 void setSortMode(ESortMode sort_mode) { mSortMode = sort_mode; }
00333
00337 void invalidateCache() { mCacheMatrix = vl::mat4(); }
00338
00339 protected:
00340 ref<ArrayFloat3> mEyeSpaceVerts;
00341 std::vector<PrimitiveZ> mPrimitiveZ;
00342
00343 std::vector<PointUInt> mSortedPointsUInt;
00344 std::vector<LineUInt> mSortedLinesUInt;
00345 std::vector<TriangleUInt> mSortedTrianglesUInt;
00346 std::vector<QuadUInt> mSortedQuadsUInt;
00347
00348 std::vector<PointUShort> mSortedPointsUShort;
00349 std::vector<LineUShort> mSortedLinesUShort;
00350 std::vector<TriangleUShort> mSortedTrianglesUShort;
00351 std::vector<QuadUShort> mSortedQuadsUShort;
00352
00353 std::vector<PointUByte> mSortedPointsUByte;
00354 std::vector<LineUByte> mSortedLinesUByte;
00355 std::vector<TriangleUByte> mSortedTrianglesUByte;
00356 std::vector<QuadUByte> mSortedQuadsUByte;
00357
00358 vl::mat4 mCacheMatrix;
00359
00360 ESortMode mSortMode;
00361 };
00362 }
00363
00364 #endif