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_TERMPLATEPRIMITIVEINDEXFUNCTOR
15#define OSG_TERMPLATEPRIMITIVEINDEXFUNCTOR 1
17#include <osg/PrimitiveSet>
23/** Provides access to the primitives that compose an \c osg::Drawable.
24 * <p>Notice that \c TemplatePrimitiveIndexFunctor is a class template, and that it inherits
25 * from its template parameter \c T. This template parameter must implement
26 * <tt>operator()(const osg::Vec3 v1, const osg::Vec3 v2, const osg::Vec3
27 * v3, bool treatVertexDataAsTemporary)</tt>,
28 * <tt>operator()(const osg::Vec3 v1, const osg::Vec3 v2, bool
29 * treatVertexDataAsTemporary)</tt>, <tt>operator()(const osg::Vec3 v1,
30 * const osg::Vec3 v2, const osg::Vec3 v3, bool treatVertexDataAsTemporary)</tt>,
31 * and <tt>operator()(const osg::Vec3 v1, const osg::Vec3 v2, const osg::Vec3 v3,
32 * const osg::Vec3 v4, bool treatVertexDataAsTemporary)</tt> which will be called
33 * for the matching primitive when the functor is applied to a \c Drawable.
34 * Parameters \c v1, \c v2, \c v3, and \c v4 are the vertices of the primitive.
35 * The last parameter, \c treatVertexDataAsTemporary, indicates whether these
36 * vertices are coming from a "real" vertex array, or from a temporary vertex array,
37 * created by the \c TemplatePrimitiveIndexFunctor from some other geometry representation.
38 * @see \c PrimitiveFunctor for general usage hints.
41class TemplatePrimitiveIndexFunctor : public PrimitiveIndexFunctor, public T
45 TemplatePrimitiveIndexFunctor() {}
47 virtual ~TemplatePrimitiveIndexFunctor() {}
49 virtual void setVertexArray(unsigned int,const Vec2*) {}
50 virtual void setVertexArray(unsigned int ,const Vec3*) {}
51 virtual void setVertexArray(unsigned int,const Vec4*) {}
52 virtual void setVertexArray(unsigned int,const Vec2d*) {}
53 virtual void setVertexArray(unsigned int ,const Vec3d*) {}
54 virtual void setVertexArray(unsigned int,const Vec4d*) {}
56 virtual void drawArrays(GLenum mode,GLint first,GLsizei count)
62 unsigned int pos=first;
63 for(GLsizei i=2;i<count;i+=3,pos+=3)
65 this->operator()(pos,pos+1,pos+2);
69 case(GL_TRIANGLE_STRIP):
71 unsigned int pos=first;
72 for(GLsizei i=2;i<count;++i,++pos)
74 if ((i%2)) this->operator()(pos,pos+2,pos+1);
75 else this->operator()(pos,pos+1,pos+2);
81 unsigned int pos=first;
82 for(GLsizei i=3;i<count;i+=4,pos+=4)
84 this->operator()(pos,pos+1,pos+2,pos+3);
90 unsigned int pos=first;
91 for(GLsizei i=3;i<count;i+=2,pos+=2)
93 this->operator()(pos,pos+1,pos+2,pos+3);
97 case(GL_POLYGON): // treat polygons as GL_TRIANGLE_FAN
98 case(GL_TRIANGLE_FAN):
100 unsigned int pos=first+1;
101 for(GLsizei i=2;i<count;++i,++pos)
103 this->operator()(first,pos,pos+1);
109 unsigned int pos=first;
110 for(GLsizei i=0;i<count;++i,++pos)
112 this->operator()(pos);
118 unsigned int pos=first;
119 for(GLsizei i=1;i<count;i+=2,pos+=2)
121 this->operator()(pos,pos+1);
127 unsigned int pos=first;
128 for(GLsizei i=1;i<count;++i,++pos)
130 this->operator()(pos,pos+1);
136 unsigned int pos=first;
137 for(GLsizei i=1;i<count;++i,++pos)
139 this->operator()(pos,pos+1);
141 this->operator()(first+count-1,first);
145 // can't be converted into to triangles.
150 virtual void drawElements(GLenum mode,GLsizei count,const GLubyte* indices)
152 if (indices==0 || count==0) return;
154 typedef GLubyte Index;
155 typedef const Index* IndexPointer;
161 IndexPointer ilast = &indices[count];
162 for(IndexPointer iptr=indices;iptr<ilast;iptr+=3)
163 this->operator()(*iptr,*(iptr+1),*(iptr+2));
166 case(GL_TRIANGLE_STRIP):
168 IndexPointer iptr = indices;
169 for(GLsizei i=2;i<count;++i,++iptr)
171 if ((i%2)) this->operator()(*(iptr),*(iptr+2),*(iptr+1));
172 else this->operator()(*(iptr),*(iptr+1),*(iptr+2));
178 IndexPointer iptr = indices;
179 for(GLsizei i=3;i<count;i+=4,iptr+=4)
181 this->operator()(*(iptr),*(iptr+1),*(iptr+2),*(iptr+3));
187 IndexPointer iptr = indices;
188 for(GLsizei i=3;i<count;i+=2,iptr+=2)
190 this->operator()(*(iptr),*(iptr+1),*(iptr+2),*(iptr+3));
194 case(GL_POLYGON): // treat polygons as GL_TRIANGLE_FAN
195 case(GL_TRIANGLE_FAN):
197 IndexPointer iptr = indices;
200 for(GLsizei i=2;i<count;++i,++iptr)
202 this->operator()(first,*(iptr),*(iptr+1));
208 IndexPointer ilast = &indices[count];
209 for(IndexPointer iptr=indices;iptr<ilast;++iptr)
210 this->operator()(*iptr);
215 IndexPointer ilast = &indices[count];
216 for(IndexPointer iptr=indices;iptr<ilast;iptr+=2)
217 this->operator()(*iptr,*(iptr+1));
222 IndexPointer iptr = indices;
223 for(GLsizei i=1;i<count;++i,++iptr)
225 this->operator()(*(iptr),*(iptr+1));
231 IndexPointer iptr = indices;
232 for(GLsizei i=1;i<count;++i,++iptr)
234 this->operator()(*(iptr),*(iptr+1));
236 this->operator()(*(iptr),*(indices));
240 // can't be converted into to triangles.
246 virtual void drawElements(GLenum mode,GLsizei count,const GLushort* indices)
248 if (indices==0 || count==0) return;
250 typedef GLushort Index;
251 typedef const Index* IndexPointer;
257 IndexPointer ilast = &indices[count];
258 for(IndexPointer iptr=indices;iptr<ilast;iptr+=3)
259 this->operator()(*iptr,*(iptr+1),*(iptr+2));
262 case(GL_TRIANGLE_STRIP):
264 IndexPointer iptr = indices;
265 for(GLsizei i=2;i<count;++i,++iptr)
267 if ((i%2)) this->operator()(*(iptr),*(iptr+2),*(iptr+1));
268 else this->operator()(*(iptr),*(iptr+1),*(iptr+2));
274 IndexPointer iptr = indices;
275 for(GLsizei i=3;i<count;i+=4,iptr+=4)
277 this->operator()(*(iptr),*(iptr+1),*(iptr+2),*(iptr+3));
283 IndexPointer iptr = indices;
284 for(GLsizei i=3;i<count;i+=2,iptr+=2)
286 this->operator()(*(iptr),*(iptr+1),*(iptr+2),*(iptr+3));
290 case(GL_POLYGON): // treat polygons as GL_TRIANGLE_FAN
291 case(GL_TRIANGLE_FAN):
293 IndexPointer iptr = indices;
296 for(GLsizei i=2;i<count;++i,++iptr)
298 this->operator()(first,*(iptr),*(iptr+1));
304 IndexPointer ilast = &indices[count];
305 for(IndexPointer iptr=indices;iptr<ilast;++iptr)
306 this->operator()(*iptr);
311 IndexPointer ilast = &indices[count];
312 for(IndexPointer iptr=indices;iptr<ilast;iptr+=2)
313 this->operator()(*iptr,*(iptr+1));
318 IndexPointer iptr = indices;
319 for(GLsizei i=1;i<count;++i,++iptr)
321 this->operator()(*(iptr),*(iptr+1));
327 IndexPointer iptr = indices;
328 for(GLsizei i=1;i<count;++i,++iptr)
330 this->operator()(*(iptr),*(iptr+1));
332 this->operator()(*(iptr),*(indices));
336 // can't be converted into to triangles.
341 virtual void drawElements(GLenum mode,GLsizei count,const GLuint* indices)
343 if (indices==0 || count==0) return;
345 typedef GLuint Index;
346 typedef const Index* IndexPointer;
352 IndexPointer ilast = &indices[count];
353 for(IndexPointer iptr=indices;iptr<ilast;iptr+=3)
354 this->operator()(*iptr,*(iptr+1),*(iptr+2));
357 case(GL_TRIANGLE_STRIP):
359 IndexPointer iptr = indices;
360 for(GLsizei i=2;i<count;++i,++iptr)
362 if ((i%2)) this->operator()(*(iptr),*(iptr+2),*(iptr+1));
363 else this->operator()(*(iptr),*(iptr+1),*(iptr+2));
369 IndexPointer iptr = indices;
370 for(GLsizei i=3;i<count;i+=4,iptr+=4)
372 this->operator()(*(iptr),*(iptr+1),*(iptr+2),*(iptr+3));
378 IndexPointer iptr = indices;
379 for(GLsizei i=3;i<count;i+=2,iptr+=2)
381 this->operator()(*(iptr),*(iptr+1),*(iptr+2),*(iptr+3));
385 case(GL_POLYGON): // treat polygons as GL_TRIANGLE_FAN
386 case(GL_TRIANGLE_FAN):
388 IndexPointer iptr = indices;
391 for(GLsizei i=2;i<count;++i,++iptr)
393 this->operator()(first,*(iptr),*(iptr+1));
399 IndexPointer ilast = &indices[count];
400 for(IndexPointer iptr=indices;iptr<ilast;++iptr)
401 this->operator()(*iptr);
406 IndexPointer ilast = &indices[count];
407 for(IndexPointer iptr=indices;iptr<ilast;iptr+=2)
408 this->operator()(*iptr,*(iptr+1));
413 IndexPointer iptr = indices;
414 for(GLsizei i=1;i<count;++i,++iptr)
416 this->operator()(*(iptr),*(iptr+1));
422 IndexPointer iptr = indices;
423 for(GLsizei i=1;i<count;++i,++iptr)
425 this->operator()(*(iptr),*(iptr+1));
427 this->operator()(*(iptr),*(indices));
431 // can't be converted into to triangles.