osgEarth 2.1.1
|
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