# Visualization Library

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

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

- Main Page
- Related Pages
- 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.org                                               */
    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 {
    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 /*frame_clock*/, const Camera* cam, Renderable* renderable, const Shader*, int pass)
    00147     {
    00148       // need to sort only for the first pass
    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       // this works well with LOD
    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       // computes eye-space vertex positions
    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       // would be nice to optimize this with SEE2
    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         // compute zetas
    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         // sort 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->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         // compute zetas
    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         // sort based on mPrimitiveZ
    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         // regenerate the sorted indices
    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         // compute zetas
    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         // sort based on mPrimitiveZ
    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         // regenerate the sorted indices
    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         // compute zetas
    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         // sort based on mPrimitiveZ
    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         // regenerate the sorted indices
    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

Visualization Library v2011.09.1162 Reference Documentation
Copyright 2005-2011 Michele Bosi. All rights reserved.
Updated on Thu Jan 26 2012 00:43:36.
Permission is granted to use this page to write and publish articles regarding Visualization Library.