1/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
3 * This library is open source and may be redistributed and/or modified under
4 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
5 * (at your option) any later version. The full license is in LICENSE file
6 * included with this distribution, and on the openscenegraph.org website.
8 * This library is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * OpenSceneGraph Public License for more details.
14#ifndef OSG_TRIANGLEFUNCTOR
15#define OSG_TRIANGLEFUNCTOR 1
17#include <osg/PrimitiveSet>
23/** Provides access to the triangles that compose an \c osg::Drawable. If the \c
24 * Drawable is not composed of triangles, the \c TriangleFunctor will convert
25 * the primitives to triangles whenever possible.
26 * <p>Notice that \c TriangleFunctor is a class template, and that it inherits
27 * from its template parameter \c T. This template parameter must implement
28 * <tt>T::operator() (const osg::Vec3 v1, const osg::Vec3 v2, const osg::Vec3
29 * v3, bool treatVertexDataAsTemporary)</tt>, which will be called for every
30 * triangle when the functor is applied to a \c Drawable. Parameters \c v1, \c
31 * v2, and \c v3 are the triangle vertices. The fourth parameter, \c
32 * treatVertexDataAsTemporary, indicates whether these vertices are coming from
33 * a "real" vertex array, or from a temporary vertex array, created by the \c
34 * TriangleFunctor from some other geometry representation.
35 * @see \c PrimitiveFunctor for general usage hints.
38class TriangleFunctor : public PrimitiveFunctor, public T
48 virtual ~TriangleFunctor() {}
50 virtual void setVertexArray(unsigned int,const Vec2*)
52 notify(WARN)<<"Triangle Functor does not support Vec2* vertex arrays"<<std::endl;
55 virtual void setVertexArray(unsigned int count,const Vec3* vertices)
57 _vertexArraySize = count;
58 _vertexArrayPtr = vertices;
61 virtual void setVertexArray(unsigned int,const Vec4* )
63 notify(WARN)<<"Triangle Functor does not support Vec4* vertex arrays"<<std::endl;
66 virtual void setVertexArray(unsigned int,const Vec2d*)
68 notify(WARN)<<"Triangle Functor does not support Vec2d* vertex arrays"<<std::endl;
71 virtual void setVertexArray(unsigned int,const Vec3d*)
73 notify(WARN)<<"Triangle Functor does not support Vec3d* vertex arrays"<<std::endl;
76 virtual void setVertexArray(unsigned int,const Vec4d* )
78 notify(WARN)<<"Triangle Functor does not support Vec4d* vertex arrays"<<std::endl;
81 virtual void drawArrays(GLenum mode,GLint first,GLsizei count)
83 if (_vertexArrayPtr==0 || count==0) return;
89 const Vec3* vlast = &_vertexArrayPtr[first+count];
90 for(const Vec3* vptr=&_vertexArrayPtr[first];vptr<vlast;vptr+=3)
91 this->operator()(*(vptr),*(vptr+1),*(vptr+2));
94 case(GL_TRIANGLE_STRIP):
96 const Vec3* vptr = &_vertexArrayPtr[first];
97 for(GLsizei i=2;i<count;++i,++vptr)
99 if ((i%2)) this->operator()(*(vptr),*(vptr+2),*(vptr+1));
100 else this->operator()(*(vptr),*(vptr+1),*(vptr+2));
106 const Vec3* vptr = &_vertexArrayPtr[first];
107 for(GLsizei i=3;i<count;i+=4,vptr+=4)
109 this->operator()(*(vptr),*(vptr+1),*(vptr+2));
110 this->operator()(*(vptr),*(vptr+2),*(vptr+3));
116 const Vec3* vptr = &_vertexArrayPtr[first];
117 for(GLsizei i=3;i<count;i+=2,vptr+=2)
119 this->operator()(*(vptr),*(vptr+1),*(vptr+2));
120 this->operator()(*(vptr+1),*(vptr+3),*(vptr+2));
124 case(GL_POLYGON): // treat polygons as GL_TRIANGLE_FAN
125 case(GL_TRIANGLE_FAN):
127 const Vec3* vfirst = &_vertexArrayPtr[first];
128 const Vec3* vptr = vfirst+1;
129 for(GLsizei i=2;i<count;++i,++vptr)
131 this->operator()(*(vfirst),*(vptr),*(vptr+1));
140 // can't be converted into to triangles.
145 virtual void drawElements(GLenum mode,GLsizei count,const GLubyte* indices)
147 if (indices==0 || count==0) return;
149 typedef const GLubyte* IndexPointer;
155 IndexPointer ilast = &indices[count];
156 for(IndexPointer iptr=indices;iptr<ilast;iptr+=3)
157 this->operator()(_vertexArrayPtr[*iptr],_vertexArrayPtr[*(iptr+1)],_vertexArrayPtr[*(iptr+2)]);
160 case(GL_TRIANGLE_STRIP):
162 IndexPointer iptr = indices;
163 for(GLsizei i=2;i<count;++i,++iptr)
165 if ((i%2)) this->operator()(_vertexArrayPtr[*(iptr)],_vertexArrayPtr[*(iptr+2)],_vertexArrayPtr[*(iptr+1)]);
166 else this->operator()(_vertexArrayPtr[*(iptr)],_vertexArrayPtr[*(iptr+1)],_vertexArrayPtr[*(iptr+2)]);
172 IndexPointer iptr = indices;
173 for(GLsizei i=3;i<count;i+=4,iptr+=4)
175 this->operator()(_vertexArrayPtr[*(iptr)],_vertexArrayPtr[*(iptr+1)],_vertexArrayPtr[*(iptr+2)]);
176 this->operator()(_vertexArrayPtr[*(iptr)],_vertexArrayPtr[*(iptr+2)],_vertexArrayPtr[*(iptr+3)]);
182 IndexPointer iptr = indices;
183 for(GLsizei i=3;i<count;i+=2,iptr+=2)
185 this->operator()(_vertexArrayPtr[*(iptr)],_vertexArrayPtr[*(iptr+1)],_vertexArrayPtr[*(iptr+2)]);
186 this->operator()(_vertexArrayPtr[*(iptr+1)],_vertexArrayPtr[*(iptr+3)],_vertexArrayPtr[*(iptr+2)]);
190 case(GL_POLYGON): // treat polygons as GL_TRIANGLE_FAN
191 case(GL_TRIANGLE_FAN):
193 IndexPointer iptr = indices;
194 const Vec3& vfirst = _vertexArrayPtr[*iptr];
196 for(GLsizei i=2;i<count;++i,++iptr)
198 this->operator()(vfirst,_vertexArrayPtr[*(iptr)],_vertexArrayPtr[*(iptr+1)]);
207 // can't be converted into to triangles.
212 virtual void drawElements(GLenum mode,GLsizei count,const GLushort* indices)
214 if (indices==0 || count==0) return;
216 typedef const GLushort* IndexPointer;
222 IndexPointer ilast = &indices[count];
223 for(IndexPointer iptr=indices;iptr<ilast;iptr+=3)
225 this->operator()(_vertexArrayPtr[*iptr],_vertexArrayPtr[*(iptr+1)],_vertexArrayPtr[*(iptr+2)]);
229 case(GL_TRIANGLE_STRIP):
231 IndexPointer iptr = indices;
232 for(GLsizei i=2;i<count;++i,++iptr)
234 if ((i%2)) this->operator()(_vertexArrayPtr[*(iptr)],_vertexArrayPtr[*(iptr+2)],_vertexArrayPtr[*(iptr+1)]);
235 else this->operator()(_vertexArrayPtr[*(iptr)],_vertexArrayPtr[*(iptr+1)],_vertexArrayPtr[*(iptr+2)]);
241 IndexPointer iptr = indices;
242 for(GLsizei i=3;i<count;i+=4,iptr+=4)
244 this->operator()(_vertexArrayPtr[*(iptr)],_vertexArrayPtr[*(iptr+1)],_vertexArrayPtr[*(iptr+2)]);
245 this->operator()(_vertexArrayPtr[*(iptr)],_vertexArrayPtr[*(iptr+2)],_vertexArrayPtr[*(iptr+3)]);
251 IndexPointer iptr = indices;
252 for(GLsizei i=3;i<count;i+=2,iptr+=2)
254 this->operator()(_vertexArrayPtr[*(iptr)],_vertexArrayPtr[*(iptr+1)],_vertexArrayPtr[*(iptr+2)]);
255 this->operator()(_vertexArrayPtr[*(iptr+1)],_vertexArrayPtr[*(iptr+3)],_vertexArrayPtr[*(iptr+2)]);
259 case(GL_POLYGON): // treat polygons as GL_TRIANGLE_FAN
260 case(GL_TRIANGLE_FAN):
262 IndexPointer iptr = indices;
263 const Vec3& vfirst = _vertexArrayPtr[*iptr];
265 for(GLsizei i=2;i<count;++i,++iptr)
267 this->operator()(vfirst,_vertexArrayPtr[*(iptr)],_vertexArrayPtr[*(iptr+1)]);
276 // can't be converted into to triangles.
281 virtual void drawElements(GLenum mode,GLsizei count,const GLuint* indices)
283 if (indices==0 || count==0) return;
285 typedef const GLuint* IndexPointer;
291 IndexPointer ilast = &indices[count];
292 for(IndexPointer iptr=indices;iptr<ilast;iptr+=3)
293 this->operator()(_vertexArrayPtr[*iptr],_vertexArrayPtr[*(iptr+1)],_vertexArrayPtr[*(iptr+2)]);
296 case(GL_TRIANGLE_STRIP):
298 IndexPointer iptr = indices;
299 for(GLsizei i=2;i<count;++i,++iptr)
301 if ((i%2)) this->operator()(_vertexArrayPtr[*(iptr)],_vertexArrayPtr[*(iptr+2)],_vertexArrayPtr[*(iptr+1)]);
302 else this->operator()(_vertexArrayPtr[*(iptr)],_vertexArrayPtr[*(iptr+1)],_vertexArrayPtr[*(iptr+2)]);
308 IndexPointer iptr = indices;
309 for(GLsizei i=3;i<count;i+=4,iptr+=4)
311 this->operator()(_vertexArrayPtr[*(iptr)],_vertexArrayPtr[*(iptr+1)],_vertexArrayPtr[*(iptr+2)]);
312 this->operator()(_vertexArrayPtr[*(iptr)],_vertexArrayPtr[*(iptr+2)],_vertexArrayPtr[*(iptr+3)]);
318 IndexPointer iptr = indices;
319 for(GLsizei i=3;i<count;i+=2,iptr+=2)
321 this->operator()(_vertexArrayPtr[*(iptr)],_vertexArrayPtr[*(iptr+1)],_vertexArrayPtr[*(iptr+2)]);
322 this->operator()(_vertexArrayPtr[*(iptr+1)],_vertexArrayPtr[*(iptr+3)],_vertexArrayPtr[*(iptr+2)]);
326 case(GL_POLYGON): // treat polygons as GL_TRIANGLE_FAN
327 case(GL_TRIANGLE_FAN):
329 IndexPointer iptr = indices;
330 const Vec3& vfirst = _vertexArrayPtr[*iptr];
332 for(GLsizei i=2;i<count;++i,++iptr)
334 this->operator()(vfirst,_vertexArrayPtr[*(iptr)],_vertexArrayPtr[*(iptr+1)]);
343 // can't be converted into to triangles.
351 unsigned int _vertexArraySize;
352 const Vec3* _vertexArrayPtr;