osgEarth 2.1.1

/home/cube/sources/osgearth/src/osgEarthSymbology/LineFunctor

Go to the documentation of this file.
00001 /* -*-c++-*- */
00002 /* osgEarth - Dynamic map generation toolkit for OpenSceneGraph
00003  * Copyright 2008-2010 Pelican Mapping
00004  * http://osgearth.org
00005  *
00006  * osgEarth is free software; you can redistribute it and/or modify
00007  * it under the terms of the GNU Lesser General Public License as published by
00008  * the Free Software Foundation; either version 2 of the License, or
00009  * (at your option) any later version.
00010  *
00011  * This program is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  * GNU Lesser General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU Lesser General Public License
00017  * along with this program.  If not, see <http://www.gnu.org/licenses/>
00018  */
00019 #ifndef OSGEARTHSYMBOLOGY_GEOMETRY_H
00020 #define OSGEARTHSYMBOLOGY_GEOMETRY_H 1
00021 
00022 #include <osgEarthSymbology/Common>
00023 #include <osg/PrimitiveSet>
00024 #include <osg/Vec2>
00025 #include <osg/Vec3>
00026 #include <osg/Vec4>
00027 
00028 namespace osgEarth { namespace Symbology 
00029 {
00033     template<class T>
00034     class LineFunctor : public osg::PrimitiveFunctor, public T
00035     {
00036     public:
00037 
00038         LineFunctor()
00039         {
00040             _vertexArraySize=0;
00041             _vertexArrayPtr=0;
00042             _modeCache=0;
00043             _treatVertexDataAsTemporary=false;
00044         }
00045 
00046         virtual ~LineFunctor() {}
00047 
00048         void setTreatVertexDataAsTemporary(bool treatVertexDataAsTemporary) { _treatVertexDataAsTemporary=treatVertexDataAsTemporary; }
00049         bool getTreatVertexDataAsTemporary() const { return _treatVertexDataAsTemporary; }
00050 
00051 
00052         virtual void setVertexArray(unsigned int count,const osg::Vec3* vertices)
00053         {
00054             _vertexArraySize = count;
00055             _vertexArrayPtr = vertices;
00056         }
00057 
00058         virtual void setVertexArray(unsigned int,const osg::Vec2*) { }
00059         virtual void setVertexArray(unsigned int,const osg::Vec4*) { }
00060         virtual void setVertexArray(unsigned int,const osg::Vec2d*) { }
00061         virtual void setVertexArray(unsigned int,const osg::Vec3d*) { }
00062         virtual void setVertexArray(unsigned int,const osg::Vec4d*) { }
00063 
00064         virtual void drawArrays(GLenum mode,GLint first,GLsizei count)
00065         {
00066             if (_vertexArrayPtr==0 || count==0) return;
00067 
00068             switch(mode)
00069             {            
00070             case(GL_LINES):
00071                 {
00072                     const osg::Vec3* vlast = &_vertexArrayPtr[first+count];
00073                     for(const osg::Vec3* vptr = &_vertexArrayPtr[first]; vptr<vlast; vptr+=2)
00074                         this->operator()( *(vptr), *(vptr+1), _treatVertexDataAsTemporary );
00075                 }
00076                 break;
00077 
00078             case(GL_LINE_STRIP):
00079                 {
00080                     const osg::Vec3* vlast = &_vertexArrayPtr[first+count-1];
00081                     for(const osg::Vec3* vptr = &_vertexArrayPtr[first]; vptr<vlast; vptr++)
00082                         this->operator()( *(vptr), *(vptr+1), _treatVertexDataAsTemporary );
00083                 }
00084                 break;
00085 
00086             case(GL_LINE_LOOP):
00087                 {
00088                     const osg::Vec3* vlast = &_vertexArrayPtr[first+count-1];
00089                     const osg::Vec3* vptr;
00090                     for(vptr = &_vertexArrayPtr[first]; vptr<vlast; vptr++)
00091                         this->operator()( *(vptr), *(vptr+1), _treatVertexDataAsTemporary );
00092                     if ( count >= 2 )
00093                         this->operator()( *vptr, _vertexArrayPtr[first], _treatVertexDataAsTemporary );
00094                 }
00095                 break;
00096 
00097             case(GL_TRIANGLES):
00098             case(GL_TRIANGLE_STRIP):
00099             case(GL_QUADS):
00100             case(GL_QUAD_STRIP):
00101             case(GL_POLYGON):
00102             case(GL_TRIANGLE_FAN):
00103             case(GL_POINTS):
00104             default:
00105                 // can't be converted into to line segments.
00106                 break;
00107             }
00108         }
00109 
00110         virtual void drawElements(GLenum mode,GLsizei count,const GLubyte* indicies)
00111         {
00112             if (indicies==0 || count==0) return;
00113 
00114             typedef const GLubyte* IndexPointer;
00115 
00116             switch(mode)
00117             {
00118             case(GL_LINES):
00119                 {
00120                     IndexPointer ilast = &indicies[count];
00121                     for(IndexPointer iptr=indicies; iptr<ilast; iptr+=2)
00122                         this->operator()( _vertexArrayPtr[*iptr], _vertexArrayPtr[*(iptr+1)], _treatVertexDataAsTemporary );
00123                 }
00124                 break;
00125 
00126             case(GL_LINE_STRIP):
00127                 {
00128                     IndexPointer ilast = &indicies[count-1];
00129                     for(IndexPointer iptr=indicies; iptr<ilast; iptr++)
00130                         this->operator()( _vertexArrayPtr[*iptr], _vertexArrayPtr[*(iptr+1)], _treatVertexDataAsTemporary );
00131                 }
00132                 break;
00133 
00134             case(GL_LINE_LOOP):
00135                 {
00136                     IndexPointer ilast = &indicies[count-1];
00137                     IndexPointer iptr;
00138                     for(iptr=indicies; iptr<ilast; iptr++)
00139                         this->operator()( _vertexArrayPtr[*iptr], _vertexArrayPtr[*(iptr+1)], _treatVertexDataAsTemporary );
00140                     if (count >= 2)
00141                         this->operator()( _vertexArrayPtr[*iptr], _vertexArrayPtr[indicies[0]], _treatVertexDataAsTemporary );
00142                 }
00143                 break;
00144 
00145             case(GL_TRIANGLES):
00146             case(GL_TRIANGLE_STRIP):
00147             case(GL_QUADS):
00148             case(GL_QUAD_STRIP):
00149             case(GL_POLYGON):
00150             case(GL_TRIANGLE_FAN):
00151             case(GL_POINTS):
00152             default:
00153                 // can't be converted into to lines.
00154                 break;
00155             }
00156         }    
00157 
00158         virtual void drawElements(GLenum mode,GLsizei count,const GLushort* indicies)
00159         {
00160             if (indicies==0 || count==0) return;
00161 
00162             typedef const GLushort* IndexPointer;
00163 
00164             switch(mode)
00165             {
00166             case(GL_LINES):
00167                 {
00168                     IndexPointer ilast = &indicies[count];
00169                     for(IndexPointer iptr=indicies; iptr<ilast; iptr+=2)
00170                         this->operator()( _vertexArrayPtr[*iptr], _vertexArrayPtr[*(iptr+1)], _treatVertexDataAsTemporary );
00171                 }
00172                 break;
00173 
00174             case(GL_LINE_STRIP):
00175                 {
00176                     IndexPointer ilast = &indicies[count-1];
00177                     for(IndexPointer iptr=indicies; iptr<ilast; iptr++)
00178                         this->operator()( _vertexArrayPtr[*iptr], _vertexArrayPtr[*(iptr+1)], _treatVertexDataAsTemporary );
00179                 }
00180                 break;
00181 
00182             case(GL_LINE_LOOP):
00183                 {
00184                     IndexPointer ilast = &indicies[count-1];
00185                     IndexPointer iptr;
00186                     for(iptr=indicies; iptr<ilast; iptr++)
00187                         this->operator()( _vertexArrayPtr[*iptr], _vertexArrayPtr[*(iptr+1)], _treatVertexDataAsTemporary );
00188                     if (count >= 2)
00189                         this->operator()( _vertexArrayPtr[*iptr], _vertexArrayPtr[indicies[0]], _treatVertexDataAsTemporary );
00190                 }
00191                 break;
00192 
00193             case(GL_TRIANGLES):
00194             case(GL_TRIANGLE_STRIP):
00195             case(GL_QUADS):
00196             case(GL_QUAD_STRIP):
00197             case(GL_POLYGON):
00198             case(GL_TRIANGLE_FAN):
00199             case(GL_POINTS):
00200             default:
00201                 // can't be converted into to lines.
00202                 break;
00203             }
00204         }    
00205 
00206         virtual void drawElements(GLenum mode,GLsizei count,const GLuint* indicies)
00207         {
00208             if (indicies==0 || count==0) return;
00209 
00210             typedef const GLuint* IndexPointer;
00211 
00212             switch(mode)
00213             {
00214             case(GL_LINES):
00215                 {
00216                     IndexPointer ilast = &indicies[count];
00217                     for(IndexPointer iptr=indicies; iptr<ilast; iptr+=2)
00218                         this->operator()( _vertexArrayPtr[*iptr], _vertexArrayPtr[*(iptr+1)], _treatVertexDataAsTemporary );
00219                 }
00220                 break;
00221 
00222             case(GL_LINE_STRIP):
00223                 {
00224                     IndexPointer ilast = &indicies[count-1];
00225                     for(IndexPointer iptr=indicies; iptr<ilast; iptr++)
00226                         this->operator()( _vertexArrayPtr[*iptr], _vertexArrayPtr[*(iptr+1)], _treatVertexDataAsTemporary );
00227                 }
00228                 break;
00229 
00230             case(GL_LINE_LOOP):
00231                 {
00232                     IndexPointer ilast = &indicies[count-1];
00233                     IndexPointer iptr;
00234                     for(iptr=indicies; iptr<ilast; iptr++)
00235                         this->operator()( _vertexArrayPtr[*iptr], _vertexArrayPtr[*(iptr+1)], _treatVertexDataAsTemporary );
00236                     if (count >= 2)
00237                         this->operator()( _vertexArrayPtr[*iptr], _vertexArrayPtr[indicies[0]], _treatVertexDataAsTemporary );
00238                 }
00239                 break;
00240 
00241             case(GL_TRIANGLES):
00242             case(GL_TRIANGLE_STRIP):
00243             case(GL_QUADS):
00244             case(GL_QUAD_STRIP):
00245             case(GL_POLYGON):
00246             case(GL_TRIANGLE_FAN):
00247             case(GL_POINTS):
00248             default:
00249                 // can't be converted into to lines.
00250                 break;
00251             }
00252         }
00253 
00254 
00255 
00262         virtual void begin(GLenum mode)
00263         {
00264             _modeCache = mode;
00265             _vertexCache.clear();
00266         }
00267 
00268         virtual void vertex(const osg::Vec2& vert) { _vertexCache.push_back(osg::Vec3(vert[0],vert[1],0.0f)); }
00269         virtual void vertex(const osg::Vec3& vert) { _vertexCache.push_back(vert); }
00270         virtual void vertex(const osg::Vec4& vert) { _vertexCache.push_back(osg::Vec3(vert[0],vert[1],vert[2])/vert[3]); }
00271         virtual void vertex(float x,float y) { _vertexCache.push_back(osg::Vec3(x,y,0.0f)); }
00272         virtual void vertex(float x,float y,float z) { _vertexCache.push_back(osg::Vec3(x,y,z)); }
00273         virtual void vertex(float x,float y,float z,float w) { _vertexCache.push_back(osg::Vec3(x,y,z)/w); }
00274         virtual void end()
00275         {
00276             if (!_vertexCache.empty())
00277             {
00278                 setVertexArray(_vertexCache.size(),&_vertexCache.front());
00279                 _treatVertexDataAsTemporary = true;
00280                 drawArrays(_modeCache,0,_vertexCache.size());
00281             }
00282         }
00283 
00284     protected:
00285 
00286 
00287         unsigned int        _vertexArraySize;
00288         const osg::Vec3*         _vertexArrayPtr;
00289 
00290         GLenum              _modeCache;
00291         std::vector<osg::Vec3>   _vertexCache;
00292         bool                _treatVertexDataAsTemporary;
00293     };
00294 } } // namespace osgEarth::Symbology
00295 
00296 
00297 #endif // OSGEARTHSYMBOLOGY_GEOMETRY_H
00298 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines