# 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/Tessellator.cpp

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 #include <vlGraphics/Tessellator.hpp>
    00033
    00034 using namespace vl;
    00035
    00036 //-----------------------------------------------------------------------------
    00037 Tessellator::Tessellator()
    00038 {
    00039   VL_DEBUG_SET_OBJECT_NAME()
    00040   mTessNormal = fvec3(0,0,0);
    00041   mBoundaryOnly = false;
    00042   mTolerance = 0.0;
    00043   mWindingRule = TW_TESS_WINDING_ODD;
    00044   mTessellateIntoSinglePolygon = true;
    00045 }
    00046 //-----------------------------------------------------------------------------
    00047 Tessellator::~Tessellator()
    00048 {
    00049   freeCombinedVertices();
    00050 }
    00051 //-----------------------------------------------------------------------------
    00052 bool Tessellator::tessellate(bool append_tessellated_tris)
    00053 {
    00054   if (!append_tessellated_tris)
    00055     mTessellatedTris.clear();
    00056   mFans.clear();
    00057   mTriStrips.clear();
    00058   mLineLoops.clear();
    00059   mPrimitiveType = 0;
    00060   freeCombinedVertices();
    00061   if (mContours.empty() || mContourVerts.empty())
    00062   {
    00063     vl::Log::error("Tessellator::tessellate(): no contours specified.\n");
    00064     return false;
    00065   }
    00066
    00067   GLUtesselator* tobj = gluNewTess();
    00068   // callbacks
    00069   gluTessCallback(tobj, GLU_TESS_BEGIN_DATA,   (callback_type)tessBeginData);
    00070   gluTessCallback(tobj, GLU_TESS_VERTEX_DATA,  (callback_type)tessVertexData);
    00071   gluTessCallback(tobj, GLU_TESS_COMBINE_DATA, (callback_type)tessCombineData);
    00072   gluTessCallback(tobj, GLU_TESS_END,     (callback_type)tessEnd);
    00073   gluTessCallback(tobj, GLU_TESS_ERROR,        (callback_type)tessError);
    00074   // normal
    00075    gluTessNormal( tobj, tessNormal().x(), tessNormal().y(), tessNormal().z() );
    00076   // properties
    00077    gluTessProperty(tobj, GLU_TESS_BOUNDARY_ONLY, boundaryOnly() ? GL_TRUE : GL_FALSE);
    00078    gluTessProperty(tobj, GLU_TESS_TOLERANCE, tolerance());
    00079    gluTessProperty(tobj, GLU_TESS_WINDING_RULE, windingRule());
    00080   // tessellation
    00081   if (tessellateIntoSinglePolygon())
    00082   {
    00083     gluTessBeginPolygon(tobj, this);
    00084     for(unsigned cont=0, idx=0; cont<mContours.size(); ++cont)
    00085     {
    00086       gluTessBeginContour(tobj);
    00087       for(int i=0; i<mContours[cont]; ++i, ++idx)
    00088         gluTessVertex(tobj, mContourVerts[idx].ptr(), mContourVerts[idx].ptr());
    00089       gluTessEndContour(tobj);
    00090     }
    00091     gluTessEndPolygon(tobj);
    00092   }
    00093   else
    00094   {
    00095     for(unsigned cont=0, idx=0; cont<mContours.size(); ++cont)
    00096     {
    00097       gluTessBeginPolygon(tobj, this);
    00098       gluTessBeginContour(tobj);
    00099       for(int i=0; i<mContours[cont]; ++i, ++idx)
    00100         gluTessVertex(tobj, mContourVerts[idx].ptr(), mContourVerts[idx].ptr());
    00101       gluTessEndContour(tobj);
    00102       gluTessEndPolygon(tobj);
    00103     }
    00104   }
    00105   gluDeleteTess(tobj);
    00106
    00107   // triangulate fans
    00108   for(unsigned fan=0; fan<mFans.size();    ++fan)
    00109   for(unsigned iv =1; iv<mFans[fan].size()-1; ++iv)
    00110   {
    00111     mTessellatedTris.push_back(mFans[fan][0]);
    00112     mTessellatedTris.push_back(mFans[fan][iv]);
    00113     mTessellatedTris.push_back(mFans[fan][iv+1]);
    00114   }
    00115
    00116   // triangulate strips
    00117   for(unsigned strip=0; strip<mTriStrips.size(); ++strip)
    00118   for(unsigned iv=0; iv<mTriStrips[strip].size()-2; ++iv)
    00119   {
    00120     if (iv % 2)
    00121     {
    00122       mTessellatedTris.push_back(mTriStrips[strip][iv+0]);
    00123       mTessellatedTris.push_back(mTriStrips[strip][iv+2]);
    00124       mTessellatedTris.push_back(mTriStrips[strip][iv+1]);
    00125     }
    00126     else
    00127     {
    00128       mTessellatedTris.push_back(mTriStrips[strip][iv+0]);
    00129       mTessellatedTris.push_back(mTriStrips[strip][iv+1]);
    00130       mTessellatedTris.push_back(mTriStrips[strip][iv+2]);
    00131     }
    00132   }
    00133
    00134   mContours.clear();
    00135   mContourVerts.clear();
    00136
    00137   #if 0
    00138     if (tessellatedTris().empty())
    00139     {
    00140       vl::Log::warning("Tessellator::tessellate(): no triangles generated.\n");
    00141       return false;
    00142     }
    00143   #endif
    00144
    00145   return true;
    00146 }
    00147 //-----------------------------------------------------------------------------
    00148 void Tessellator::freeCombinedVertices()
    00149 {
    00150   for(unsigned i=0; i<mCombinedVertices.size(); ++i)
    00151     delete mCombinedVertices[i];
    00152   mCombinedVertices.clear();
    00153 }
    00154 //-----------------------------------------------------------------------------
    00155 ref<Geometry> Tessellator::tessellateGeometry(bool append_tessellated_tris)
    00156 {
    00157   tessellate(append_tessellated_tris);
    00158
    00159   if (mTessellatedTris.empty())
    00160     return NULL;
    00161
    00162   ref<Geometry> geom = new Geometry;
    00163   ref<ArrayFloat3> vert_array = new ArrayFloat3;
    00164
    00165   *vert_array = mTessellatedTris;
    00166
    00167   geom->setVertexArray(vert_array.get());
    00168   geom->drawCalls()->push_back( new vl::DrawArrays(PT_TRIANGLES,0,vert_array->size()) );
    00169   geom->computeNormals();
    00170   return geom;
    00171 }
    00172 //-----------------------------------------------------------------------------
    00173 // Tessellation callbacks
    00174 //-----------------------------------------------------------------------------
    00175 void CALLBACK Tessellator::tessBeginData( GLenum type, Tessellator* tessellator )
    00176 {
    00177   tessellator->mPrimitiveType = type;
    00178   if(type == GL_TRIANGLES)
    00179   {
    00180     // do nothing
    00181   }
    00182   else
    00183   if(type == GL_TRIANGLE_FAN)
    00184     tessellator->mFans.resize( tessellator->mFans.size() + 1 );
    00185   else
    00186   if(type == GL_TRIANGLE_STRIP)
    00187     tessellator->mTriStrips.resize( tessellator->mTriStrips.size() + 1 );
    00188   else
    00189   if(type == GL_LINE_LOOP)
    00190     tessellator->mLineLoops.resize( tessellator->mLineLoops.size() + 1 );
    00191   else
    00192   {
    00193     Log::error("Tessellator::beginData() unknown primitive.\n");
    00194   }
    00195 }
    00196 //-----------------------------------------------------------------------------
    00197 void CALLBACK Tessellator::tessVertexData( dvec3* vec, Tessellator* tessellator )
    00198 {
    00199   if(tessellator->mPrimitiveType == GL_TRIANGLES)
    00200     tessellator->mTessellatedTris.push_back( (fvec3)(*vec) );
    00201   else
    00202   if(tessellator->mPrimitiveType == GL_TRIANGLE_FAN)
    00203     tessellator->mFans.back().push_back( (fvec3)(*vec) );
    00204   else
    00205   if(tessellator->mPrimitiveType == GL_TRIANGLE_STRIP)
    00206     tessellator->mTriStrips.back().push_back( (fvec3)(*vec) );
    00207   else
    00208   if(tessellator->mPrimitiveType == GL_LINE_LOOP)
    00209     tessellator->mLineLoops.back().push_back( (fvec3)(*vec) );
    00210   else
    00211   {
    00212     Log::error("Tessellator::vertexData() unknown primitive.\n");
    00213   }
    00214 }
    00215 //-----------------------------------------------------------------------------
    00216 void CALLBACK Tessellator::tessCombineData( GLdouble coords[3], dvec3* d[4], GLfloat w[4], dvec3 **dataOut, Tessellator* tessellator )
    00217 {
    00218   dvec3 *vec = new dvec3;
    00219   vec->x() = coords[0];
    00220   vec->y() = coords[1];
    00221   vec->z() = coords[2];
    00222   *dataOut = vec;
    00223   tessellator->mCombinedVertices.push_back( vec );
    00224 }
    00225 //-----------------------------------------------------------------------------
    00226 void CALLBACK Tessellator::tessEnd(void)
    00227 {
    00228 }
    00229 //-----------------------------------------------------------------------------
    00230 void CALLBACK Tessellator::tessError( GLenum errno )
    00231 {
    00232   const GLubyte* estring = gluErrorString(errno);
    00233   Log::error( Say("Tessellator error: %s.\n") << estring );
    00234 }
    00235 //-----------------------------------------------------------------------------

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