# Visualization Library

A lightweight C++ OpenGL middleware for 2D/3D graphics

[Home] [Tutorials] [All Classes] [Grouped Classes]

- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

# D:/VL/BuildSystem/VL_DISTRO/Visualization_Library_SDK/src/vlGraphics/DepthSortCallback.hpp

Go to the documentation of this file.

    00001 /**************************************************************************************/
    00002 /*                                                                                    */
    00003 /*  Visualization Library                                                             */
    00004 /*  http://www.visualizationlibrary.com                                               */
    00005 /*                                                                                    */
    00006 /*  Copyright (c) 2005-2010, Michele Bosi                                             */
    00007 /*  All rights reserved.                                                              */
    00008 /*                                                                                    */
    00009 /*  Redistribution and use in source and binary forms, with or without modification,  */
    00010 /*  are permitted provided that the following conditions are met:                     */
    00011 /*                                                                                    */
    00012 /*  - Redistributions of source code must retain the above copyright notice, this     */
    00013 /*  list of conditions and the following disclaimer.                                  */
    00014 /*                                                                                    */
    00015 /*  - Redistributions in binary form must reproduce the above copyright notice, this  */
    00016 /*  list of conditions and the following disclaimer in the documentation and/or       */
    00017 /*  other materials provided with the distribution.                                   */
    00018 /*                                                                                    */
    00019 /*  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND   */
    00020 /*  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED     */
    00021 /*  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE            */
    00022 /*  DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR  */
    00023 /*  ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES    */
    00024 /*  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;      */
    00025 /*  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON    */
    00026 /*  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT           */
    00027 /*  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS     */
    00028 /*  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.                      */
    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 /*frame_clock*/, const Camera* cam, Renderable* renderable, const Shader*, int pass)
    00142     {
    00143       // need to sort only for the first pass
    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       // this works well with LOD
    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       // computes eye-space vertex positions
    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       // would be nice to optimize this with SEE2
    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         // compute zetas
    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         // sort triangles based on mPrimitiveZ
    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         // regenerate the sorted indices
    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         // compute zetas
    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         // sort triangles based on mPrimitiveZ
    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         // regenerate the sorted indices
    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         // compute zetas
    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         // sort triangles based on mPrimitiveZ
    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         // regenerate the sorted indices
    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         // compute zetas
    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         // sort triangles based on mPrimitiveZ
    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         // regenerate the sorted indices
    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

Visualization Library v2011.05.1142 Reference Documentation
Copyright 2005-2011 Michele Bosi. All rights reserved.
Updated on Thu May 26 2011 22:51:23.
Permission is granted to use this page to write and publish articles regarding Visualization Library.