openscenegraph
TemplatePrimitiveIndexFunctor
Go to the documentation of this file.
1/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
2 *
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.
7 *
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.
12*/
13
14#ifndef OSG_TERMPLATEPRIMITIVEINDEXFUNCTOR
15#define OSG_TERMPLATEPRIMITIVEINDEXFUNCTOR 1
16
17#include <osg/PrimitiveSet>
18#include <osg/Notify>
19
20namespace osg {
21
22
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.
39 */
40template<class T>
41class TemplatePrimitiveIndexFunctor : public PrimitiveIndexFunctor, public T
42{
43public:
44
45 TemplatePrimitiveIndexFunctor() {}
46
47 virtual ~TemplatePrimitiveIndexFunctor() {}
48
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*) {}
55
56 virtual void drawArrays(GLenum mode,GLint first,GLsizei count)
57 {
58 switch(mode)
59 {
60 case(GL_TRIANGLES):
61 {
62 unsigned int pos=first;
63 for(GLsizei i=2;i<count;i+=3,pos+=3)
64 {
65 this->operator()(pos,pos+1,pos+2);
66 }
67 break;
68 }
69 case(GL_TRIANGLE_STRIP):
70 {
71 unsigned int pos=first;
72 for(GLsizei i=2;i<count;++i,++pos)
73 {
74 if ((i%2)) this->operator()(pos,pos+2,pos+1);
75 else this->operator()(pos,pos+1,pos+2);
76 }
77 break;
78 }
79 case(GL_QUADS):
80 {
81 unsigned int pos=first;
82 for(GLsizei i=3;i<count;i+=4,pos+=4)
83 {
84 this->operator()(pos,pos+1,pos+2,pos+3);
85 }
86 break;
87 }
88 case(GL_QUAD_STRIP):
89 {
90 unsigned int pos=first;
91 for(GLsizei i=3;i<count;i+=2,pos+=2)
92 {
93 this->operator()(pos,pos+1,pos+2,pos+3);
94 }
95 break;
96 }
97 case(GL_POLYGON): // treat polygons as GL_TRIANGLE_FAN
98 case(GL_TRIANGLE_FAN):
99 {
100 unsigned int pos=first+1;
101 for(GLsizei i=2;i<count;++i,++pos)
102 {
103 this->operator()(first,pos,pos+1);
104 }
105 break;
106 }
107 case(GL_POINTS):
108 {
109 unsigned int pos=first;
110 for(GLsizei i=0;i<count;++i,++pos)
111 {
112 this->operator()(pos);
113 }
114 break;
115 }
116 case(GL_LINES):
117 {
118 unsigned int pos=first;
119 for(GLsizei i=1;i<count;i+=2,pos+=2)
120 {
121 this->operator()(pos,pos+1);
122 }
123 break;
124 }
125 case(GL_LINE_STRIP):
126 {
127 unsigned int pos=first;
128 for(GLsizei i=1;i<count;++i,++pos)
129 {
130 this->operator()(pos,pos+1);
131 }
132 break;
133 }
134 case(GL_LINE_LOOP):
135 {
136 unsigned int pos=first;
137 for(GLsizei i=1;i<count;++i,++pos)
138 {
139 this->operator()(pos,pos+1);
140 }
141 this->operator()(first+count-1,first);
142 break;
143 }
144 default:
145 // can't be converted into to triangles.
146 break;
147 }
148 }
149
150 virtual void drawElements(GLenum mode,GLsizei count,const GLubyte* indices)
151 {
152 if (indices==0 || count==0) return;
153
154 typedef GLubyte Index;
155 typedef const Index* IndexPointer;
156
157 switch(mode)
158 {
159 case(GL_TRIANGLES):
160 {
161 IndexPointer ilast = &indices[count];
162 for(IndexPointer iptr=indices;iptr<ilast;iptr+=3)
163 this->operator()(*iptr,*(iptr+1),*(iptr+2));
164 break;
165 }
166 case(GL_TRIANGLE_STRIP):
167 {
168 IndexPointer iptr = indices;
169 for(GLsizei i=2;i<count;++i,++iptr)
170 {
171 if ((i%2)) this->operator()(*(iptr),*(iptr+2),*(iptr+1));
172 else this->operator()(*(iptr),*(iptr+1),*(iptr+2));
173 }
174 break;
175 }
176 case(GL_QUADS):
177 {
178 IndexPointer iptr = indices;
179 for(GLsizei i=3;i<count;i+=4,iptr+=4)
180 {
181 this->operator()(*(iptr),*(iptr+1),*(iptr+2),*(iptr+3));
182 }
183 break;
184 }
185 case(GL_QUAD_STRIP):
186 {
187 IndexPointer iptr = indices;
188 for(GLsizei i=3;i<count;i+=2,iptr+=2)
189 {
190 this->operator()(*(iptr),*(iptr+1),*(iptr+2),*(iptr+3));
191 }
192 break;
193 }
194 case(GL_POLYGON): // treat polygons as GL_TRIANGLE_FAN
195 case(GL_TRIANGLE_FAN):
196 {
197 IndexPointer iptr = indices;
198 Index first = *iptr;
199 ++iptr;
200 for(GLsizei i=2;i<count;++i,++iptr)
201 {
202 this->operator()(first,*(iptr),*(iptr+1));
203 }
204 break;
205 }
206 case(GL_POINTS):
207 {
208 IndexPointer ilast = &indices[count];
209 for(IndexPointer iptr=indices;iptr<ilast;++iptr)
210 this->operator()(*iptr);
211 break;
212 }
213 case(GL_LINES):
214 {
215 IndexPointer ilast = &indices[count];
216 for(IndexPointer iptr=indices;iptr<ilast;iptr+=2)
217 this->operator()(*iptr,*(iptr+1));
218 break;
219 }
220 case(GL_LINE_STRIP):
221 {
222 IndexPointer iptr = indices;
223 for(GLsizei i=1;i<count;++i,++iptr)
224 {
225 this->operator()(*(iptr),*(iptr+1));
226 }
227 break;
228 }
229 case(GL_LINE_LOOP):
230 {
231 IndexPointer iptr = indices;
232 for(GLsizei i=1;i<count;++i,++iptr)
233 {
234 this->operator()(*(iptr),*(iptr+1));
235 }
236 this->operator()(*(iptr),*(indices));
237 break;
238 }
239 default:
240 // can't be converted into to triangles.
241 break;
242 }
243 }
244
245
246 virtual void drawElements(GLenum mode,GLsizei count,const GLushort* indices)
247 {
248 if (indices==0 || count==0) return;
249
250 typedef GLushort Index;
251 typedef const Index* IndexPointer;
252
253 switch(mode)
254 {
255 case(GL_TRIANGLES):
256 {
257 IndexPointer ilast = &indices[count];
258 for(IndexPointer iptr=indices;iptr<ilast;iptr+=3)
259 this->operator()(*iptr,*(iptr+1),*(iptr+2));
260 break;
261 }
262 case(GL_TRIANGLE_STRIP):
263 {
264 IndexPointer iptr = indices;
265 for(GLsizei i=2;i<count;++i,++iptr)
266 {
267 if ((i%2)) this->operator()(*(iptr),*(iptr+2),*(iptr+1));
268 else this->operator()(*(iptr),*(iptr+1),*(iptr+2));
269 }
270 break;
271 }
272 case(GL_QUADS):
273 {
274 IndexPointer iptr = indices;
275 for(GLsizei i=3;i<count;i+=4,iptr+=4)
276 {
277 this->operator()(*(iptr),*(iptr+1),*(iptr+2),*(iptr+3));
278 }
279 break;
280 }
281 case(GL_QUAD_STRIP):
282 {
283 IndexPointer iptr = indices;
284 for(GLsizei i=3;i<count;i+=2,iptr+=2)
285 {
286 this->operator()(*(iptr),*(iptr+1),*(iptr+2),*(iptr+3));
287 }
288 break;
289 }
290 case(GL_POLYGON): // treat polygons as GL_TRIANGLE_FAN
291 case(GL_TRIANGLE_FAN):
292 {
293 IndexPointer iptr = indices;
294 Index first = *iptr;
295 ++iptr;
296 for(GLsizei i=2;i<count;++i,++iptr)
297 {
298 this->operator()(first,*(iptr),*(iptr+1));
299 }
300 break;
301 }
302 case(GL_POINTS):
303 {
304 IndexPointer ilast = &indices[count];
305 for(IndexPointer iptr=indices;iptr<ilast;++iptr)
306 this->operator()(*iptr);
307 break;
308 }
309 case(GL_LINES):
310 {
311 IndexPointer ilast = &indices[count];
312 for(IndexPointer iptr=indices;iptr<ilast;iptr+=2)
313 this->operator()(*iptr,*(iptr+1));
314 break;
315 }
316 case(GL_LINE_STRIP):
317 {
318 IndexPointer iptr = indices;
319 for(GLsizei i=1;i<count;++i,++iptr)
320 {
321 this->operator()(*(iptr),*(iptr+1));
322 }
323 break;
324 }
325 case(GL_LINE_LOOP):
326 {
327 IndexPointer iptr = indices;
328 for(GLsizei i=1;i<count;++i,++iptr)
329 {
330 this->operator()(*(iptr),*(iptr+1));
331 }
332 this->operator()(*(iptr),*(indices));
333 break;
334 }
335 default:
336 // can't be converted into to triangles.
337 break;
338 }
339 }
340
341 virtual void drawElements(GLenum mode,GLsizei count,const GLuint* indices)
342 {
343 if (indices==0 || count==0) return;
344
345 typedef GLuint Index;
346 typedef const Index* IndexPointer;
347
348 switch(mode)
349 {
350 case(GL_TRIANGLES):
351 {
352 IndexPointer ilast = &indices[count];
353 for(IndexPointer iptr=indices;iptr<ilast;iptr+=3)
354 this->operator()(*iptr,*(iptr+1),*(iptr+2));
355 break;
356 }
357 case(GL_TRIANGLE_STRIP):
358 {
359 IndexPointer iptr = indices;
360 for(GLsizei i=2;i<count;++i,++iptr)
361 {
362 if ((i%2)) this->operator()(*(iptr),*(iptr+2),*(iptr+1));
363 else this->operator()(*(iptr),*(iptr+1),*(iptr+2));
364 }
365 break;
366 }
367 case(GL_QUADS):
368 {
369 IndexPointer iptr = indices;
370 for(GLsizei i=3;i<count;i+=4,iptr+=4)
371 {
372 this->operator()(*(iptr),*(iptr+1),*(iptr+2),*(iptr+3));
373 }
374 break;
375 }
376 case(GL_QUAD_STRIP):
377 {
378 IndexPointer iptr = indices;
379 for(GLsizei i=3;i<count;i+=2,iptr+=2)
380 {
381 this->operator()(*(iptr),*(iptr+1),*(iptr+2),*(iptr+3));
382 }
383 break;
384 }
385 case(GL_POLYGON): // treat polygons as GL_TRIANGLE_FAN
386 case(GL_TRIANGLE_FAN):
387 {
388 IndexPointer iptr = indices;
389 Index first = *iptr;
390 ++iptr;
391 for(GLsizei i=2;i<count;++i,++iptr)
392 {
393 this->operator()(first,*(iptr),*(iptr+1));
394 }
395 break;
396 }
397 case(GL_POINTS):
398 {
399 IndexPointer ilast = &indices[count];
400 for(IndexPointer iptr=indices;iptr<ilast;++iptr)
401 this->operator()(*iptr);
402 break;
403 }
404 case(GL_LINES):
405 {
406 IndexPointer ilast = &indices[count];
407 for(IndexPointer iptr=indices;iptr<ilast;iptr+=2)
408 this->operator()(*iptr,*(iptr+1));
409 break;
410 }
411 case(GL_LINE_STRIP):
412 {
413 IndexPointer iptr = indices;
414 for(GLsizei i=1;i<count;++i,++iptr)
415 {
416 this->operator()(*(iptr),*(iptr+1));
417 }
418 break;
419 }
420 case(GL_LINE_LOOP):
421 {
422 IndexPointer iptr = indices;
423 for(GLsizei i=1;i<count;++i,++iptr)
424 {
425 this->operator()(*(iptr),*(iptr+1));
426 }
427 this->operator()(*(iptr),*(indices));
428 break;
429 }
430 default:
431 // can't be converted into to triangles.
432 break;
433 }
434 }
435
436};
437
438
439}
440
441#endif