Visualization Library

A lightweight C++ OpenGL middleware for 2D/3D graphics
[Home] [Tutorials] [All Classes] [Grouped Classes]

X:/dropbox/visualizationlibrary/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 2011.09.1160 Reference Documentation
Copyright 2005-2011 Michele Bosi. All rights reserved.
Updated on Thu May 2 2013 13:40:35.
Permission is granted to use this page to write and publish articles regarding Visualization Library.