OSG  3.4.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
TriangleFunctor.h
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_TRIANGLEFUNCTOR
15 #define OSG_TRIANGLEFUNCTOR 1
16 
17 #include <osg/PrimitiveSet>
18 #include <osg/Notify>
19 
20 namespace osg {
21 
22 
37 template<class T>
38 class TriangleFunctor : public PrimitiveFunctor, public T
39 {
40 public:
41 
43  {
46  _modeCache=0;
48  }
49 
50  virtual ~TriangleFunctor() {}
51 
52  void setTreatVertexDataAsTemporary(bool treatVertexDataAsTemporary) { _treatVertexDataAsTemporary=treatVertexDataAsTemporary; }
54 
55  virtual void setVertexArray(unsigned int,const Vec2*)
56  {
57  notify(WARN)<<"Triangle Functor does not support Vec2* vertex arrays"<<std::endl;
58  }
59 
60  virtual void setVertexArray(unsigned int count,const Vec3* vertices)
61  {
62  _vertexArraySize = count;
63  _vertexArrayPtr = vertices;
64  }
65 
66  virtual void setVertexArray(unsigned int,const Vec4* )
67  {
68  notify(WARN)<<"Triangle Functor does not support Vec4* vertex arrays"<<std::endl;
69  }
70 
71  virtual void setVertexArray(unsigned int,const Vec2d*)
72  {
73  notify(WARN)<<"Triangle Functor does not support Vec2d* vertex arrays"<<std::endl;
74  }
75 
76  virtual void setVertexArray(unsigned int,const Vec3d*)
77  {
78  notify(WARN)<<"Triangle Functor does not support Vec3d* vertex arrays"<<std::endl;
79  }
80 
81  virtual void setVertexArray(unsigned int,const Vec4d* )
82  {
83  notify(WARN)<<"Triangle Functor does not support Vec4d* vertex arrays"<<std::endl;
84  }
85 
86  virtual void drawArrays(GLenum mode,GLint first,GLsizei count)
87  {
88  if (_vertexArrayPtr==0 || count==0) return;
89 
90  switch(mode)
91  {
92  case(GL_TRIANGLES):
93  {
94  const Vec3* vlast = &_vertexArrayPtr[first+count];
95  for(const Vec3* vptr=&_vertexArrayPtr[first];vptr<vlast;vptr+=3)
96  this->operator()(*(vptr),*(vptr+1),*(vptr+2),_treatVertexDataAsTemporary);
97  break;
98  }
99  case(GL_TRIANGLE_STRIP):
100  {
101  const Vec3* vptr = &_vertexArrayPtr[first];
102  for(GLsizei i=2;i<count;++i,++vptr)
103  {
104  if ((i%2)) this->operator()(*(vptr),*(vptr+2),*(vptr+1),_treatVertexDataAsTemporary);
105  else this->operator()(*(vptr),*(vptr+1),*(vptr+2),_treatVertexDataAsTemporary);
106  }
107  break;
108  }
109  case(GL_QUADS):
110  {
111  const Vec3* vptr = &_vertexArrayPtr[first];
112  for(GLsizei i=3;i<count;i+=4,vptr+=4)
113  {
114  this->operator()(*(vptr),*(vptr+1),*(vptr+2),_treatVertexDataAsTemporary);
115  this->operator()(*(vptr),*(vptr+2),*(vptr+3),_treatVertexDataAsTemporary);
116  }
117  break;
118  }
119  case(GL_QUAD_STRIP):
120  {
121  const Vec3* vptr = &_vertexArrayPtr[first];
122  for(GLsizei i=3;i<count;i+=2,vptr+=2)
123  {
124  this->operator()(*(vptr),*(vptr+1),*(vptr+2),_treatVertexDataAsTemporary);
125  this->operator()(*(vptr+1),*(vptr+3),*(vptr+2),_treatVertexDataAsTemporary);
126  }
127  break;
128  }
129  case(GL_POLYGON): // treat polygons as GL_TRIANGLE_FAN
130  case(GL_TRIANGLE_FAN):
131  {
132  const Vec3* vfirst = &_vertexArrayPtr[first];
133  const Vec3* vptr = vfirst+1;
134  for(GLsizei i=2;i<count;++i,++vptr)
135  {
136  this->operator()(*(vfirst),*(vptr),*(vptr+1),_treatVertexDataAsTemporary);
137  }
138  break;
139  }
140  case(GL_POINTS):
141  case(GL_LINES):
142  case(GL_LINE_STRIP):
143  case(GL_LINE_LOOP):
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 const GLubyte* IndexPointer;
155 
156  switch(mode)
157  {
158  case(GL_TRIANGLES):
159  {
160  IndexPointer ilast = &indices[count];
161  for(IndexPointer iptr=indices;iptr<ilast;iptr+=3)
162  this->operator()(_vertexArrayPtr[*iptr],_vertexArrayPtr[*(iptr+1)],_vertexArrayPtr[*(iptr+2)],_treatVertexDataAsTemporary);
163  break;
164  }
165  case(GL_TRIANGLE_STRIP):
166  {
167  IndexPointer iptr = indices;
168  for(GLsizei i=2;i<count;++i,++iptr)
169  {
170  if ((i%2)) this->operator()(_vertexArrayPtr[*(iptr)],_vertexArrayPtr[*(iptr+2)],_vertexArrayPtr[*(iptr+1)],_treatVertexDataAsTemporary);
171  else this->operator()(_vertexArrayPtr[*(iptr)],_vertexArrayPtr[*(iptr+1)],_vertexArrayPtr[*(iptr+2)],_treatVertexDataAsTemporary);
172  }
173  break;
174  }
175  case(GL_QUADS):
176  {
177  IndexPointer iptr = indices;
178  for(GLsizei i=3;i<count;i+=4,iptr+=4)
179  {
180  this->operator()(_vertexArrayPtr[*(iptr)],_vertexArrayPtr[*(iptr+1)],_vertexArrayPtr[*(iptr+2)],_treatVertexDataAsTemporary);
181  this->operator()(_vertexArrayPtr[*(iptr)],_vertexArrayPtr[*(iptr+2)],_vertexArrayPtr[*(iptr+3)],_treatVertexDataAsTemporary);
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()(_vertexArrayPtr[*(iptr)],_vertexArrayPtr[*(iptr+1)],_vertexArrayPtr[*(iptr+2)],_treatVertexDataAsTemporary);
191  this->operator()(_vertexArrayPtr[*(iptr+1)],_vertexArrayPtr[*(iptr+3)],_vertexArrayPtr[*(iptr+2)],_treatVertexDataAsTemporary);
192  }
193  break;
194  }
195  case(GL_POLYGON): // treat polygons as GL_TRIANGLE_FAN
196  case(GL_TRIANGLE_FAN):
197  {
198  IndexPointer iptr = indices;
199  const Vec3& vfirst = _vertexArrayPtr[*iptr];
200  ++iptr;
201  for(GLsizei i=2;i<count;++i,++iptr)
202  {
203  this->operator()(vfirst,_vertexArrayPtr[*(iptr)],_vertexArrayPtr[*(iptr+1)],_treatVertexDataAsTemporary);
204  }
205  break;
206  }
207  case(GL_POINTS):
208  case(GL_LINES):
209  case(GL_LINE_STRIP):
210  case(GL_LINE_LOOP):
211  default:
212  // can't be converted into to triangles.
213  break;
214  }
215  }
216 
217  virtual void drawElements(GLenum mode,GLsizei count,const GLushort* indices)
218  {
219  if (indices==0 || count==0) return;
220 
221  typedef const GLushort* IndexPointer;
222 
223  switch(mode)
224  {
225  case(GL_TRIANGLES):
226  {
227  IndexPointer ilast = &indices[count];
228  for(IndexPointer iptr=indices;iptr<ilast;iptr+=3)
229  {
230  this->operator()(_vertexArrayPtr[*iptr],_vertexArrayPtr[*(iptr+1)],_vertexArrayPtr[*(iptr+2)],_treatVertexDataAsTemporary);
231  }
232  break;
233  }
234  case(GL_TRIANGLE_STRIP):
235  {
236  IndexPointer iptr = indices;
237  for(GLsizei i=2;i<count;++i,++iptr)
238  {
239  if ((i%2)) this->operator()(_vertexArrayPtr[*(iptr)],_vertexArrayPtr[*(iptr+2)],_vertexArrayPtr[*(iptr+1)],_treatVertexDataAsTemporary);
240  else this->operator()(_vertexArrayPtr[*(iptr)],_vertexArrayPtr[*(iptr+1)],_vertexArrayPtr[*(iptr+2)],_treatVertexDataAsTemporary);
241  }
242  break;
243  }
244  case(GL_QUADS):
245  {
246  IndexPointer iptr = indices;
247  for(GLsizei i=3;i<count;i+=4,iptr+=4)
248  {
249  this->operator()(_vertexArrayPtr[*(iptr)],_vertexArrayPtr[*(iptr+1)],_vertexArrayPtr[*(iptr+2)],_treatVertexDataAsTemporary);
250  this->operator()(_vertexArrayPtr[*(iptr)],_vertexArrayPtr[*(iptr+2)],_vertexArrayPtr[*(iptr+3)],_treatVertexDataAsTemporary);
251  }
252  break;
253  }
254  case(GL_QUAD_STRIP):
255  {
256  IndexPointer iptr = indices;
257  for(GLsizei i=3;i<count;i+=2,iptr+=2)
258  {
259  this->operator()(_vertexArrayPtr[*(iptr)],_vertexArrayPtr[*(iptr+1)],_vertexArrayPtr[*(iptr+2)],_treatVertexDataAsTemporary);
260  this->operator()(_vertexArrayPtr[*(iptr+1)],_vertexArrayPtr[*(iptr+3)],_vertexArrayPtr[*(iptr+2)],_treatVertexDataAsTemporary);
261  }
262  break;
263  }
264  case(GL_POLYGON): // treat polygons as GL_TRIANGLE_FAN
265  case(GL_TRIANGLE_FAN):
266  {
267  IndexPointer iptr = indices;
268  const Vec3& vfirst = _vertexArrayPtr[*iptr];
269  ++iptr;
270  for(GLsizei i=2;i<count;++i,++iptr)
271  {
272  this->operator()(vfirst,_vertexArrayPtr[*(iptr)],_vertexArrayPtr[*(iptr+1)],_treatVertexDataAsTemporary);
273  }
274  break;
275  }
276  case(GL_POINTS):
277  case(GL_LINES):
278  case(GL_LINE_STRIP):
279  case(GL_LINE_LOOP):
280  default:
281  // can't be converted into to triangles.
282  break;
283  }
284  }
285 
286  virtual void drawElements(GLenum mode,GLsizei count,const GLuint* indices)
287  {
288  if (indices==0 || count==0) return;
289 
290  typedef const GLuint* IndexPointer;
291 
292  switch(mode)
293  {
294  case(GL_TRIANGLES):
295  {
296  IndexPointer ilast = &indices[count];
297  for(IndexPointer iptr=indices;iptr<ilast;iptr+=3)
298  this->operator()(_vertexArrayPtr[*iptr],_vertexArrayPtr[*(iptr+1)],_vertexArrayPtr[*(iptr+2)],_treatVertexDataAsTemporary);
299  break;
300  }
301  case(GL_TRIANGLE_STRIP):
302  {
303  IndexPointer iptr = indices;
304  for(GLsizei i=2;i<count;++i,++iptr)
305  {
306  if ((i%2)) this->operator()(_vertexArrayPtr[*(iptr)],_vertexArrayPtr[*(iptr+2)],_vertexArrayPtr[*(iptr+1)],_treatVertexDataAsTemporary);
307  else this->operator()(_vertexArrayPtr[*(iptr)],_vertexArrayPtr[*(iptr+1)],_vertexArrayPtr[*(iptr+2)],_treatVertexDataAsTemporary);
308  }
309  break;
310  }
311  case(GL_QUADS):
312  {
313  IndexPointer iptr = indices;
314  for(GLsizei i=3;i<count;i+=4,iptr+=4)
315  {
316  this->operator()(_vertexArrayPtr[*(iptr)],_vertexArrayPtr[*(iptr+1)],_vertexArrayPtr[*(iptr+2)],_treatVertexDataAsTemporary);
317  this->operator()(_vertexArrayPtr[*(iptr)],_vertexArrayPtr[*(iptr+2)],_vertexArrayPtr[*(iptr+3)],_treatVertexDataAsTemporary);
318  }
319  break;
320  }
321  case(GL_QUAD_STRIP):
322  {
323  IndexPointer iptr = indices;
324  for(GLsizei i=3;i<count;i+=2,iptr+=2)
325  {
326  this->operator()(_vertexArrayPtr[*(iptr)],_vertexArrayPtr[*(iptr+1)],_vertexArrayPtr[*(iptr+2)],_treatVertexDataAsTemporary);
327  this->operator()(_vertexArrayPtr[*(iptr+1)],_vertexArrayPtr[*(iptr+3)],_vertexArrayPtr[*(iptr+2)],_treatVertexDataAsTemporary);
328  }
329  break;
330  }
331  case(GL_POLYGON): // treat polygons as GL_TRIANGLE_FAN
332  case(GL_TRIANGLE_FAN):
333  {
334  IndexPointer iptr = indices;
335  const Vec3& vfirst = _vertexArrayPtr[*iptr];
336  ++iptr;
337  for(GLsizei i=2;i<count;++i,++iptr)
338  {
339  this->operator()(vfirst,_vertexArrayPtr[*(iptr)],_vertexArrayPtr[*(iptr+1)],_treatVertexDataAsTemporary);
340  }
341  break;
342  }
343  case(GL_POINTS):
344  case(GL_LINES):
345  case(GL_LINE_STRIP):
346  case(GL_LINE_LOOP):
347  default:
348  // can't be converted into to triangles.
349  break;
350  }
351  }
352 
353 
354 
361  virtual void begin(GLenum mode)
362  {
363  _modeCache = mode;
364  _vertexCache.clear();
365  }
366 
367  virtual void vertex(const Vec2& vert) { _vertexCache.push_back(osg::Vec3(vert[0],vert[1],0.0f)); }
368  virtual void vertex(const Vec3& vert) { _vertexCache.push_back(vert); }
369  virtual void vertex(const Vec4& vert) { _vertexCache.push_back(osg::Vec3(vert[0],vert[1],vert[2])/vert[3]); }
370  virtual void vertex(float x,float y) { _vertexCache.push_back(osg::Vec3(x,y,0.0f)); }
371  virtual void vertex(float x,float y,float z) { _vertexCache.push_back(osg::Vec3(x,y,z)); }
372  virtual void vertex(float x,float y,float z,float w) { _vertexCache.push_back(osg::Vec3(x,y,z)/w); }
373  virtual void end()
374  {
375  if (!_vertexCache.empty())
376  {
377  setVertexArray(_vertexCache.size(),&_vertexCache.front());
380  }
381  }
382 
383 protected:
384 
385 
386  unsigned int _vertexArraySize;
388 
389  GLenum _modeCache;
390 };
391 
392 
393 }
394 
395 #endif
virtual void drawElements(GLenum mode, GLsizei count, const GLuint *indices)
Mimics the OpenGL glDrawElements() function.
virtual void drawArrays(GLenum mode, GLint first, GLsizei count)
Mimics the OpenGL glDrawArrays() function.
std::vector< Vec3 > _vertexCache
Definition: PrimitiveSet.h:128
virtual void vertex(const Vec4 &vert)
Mimics the OpenGL glVertex() "family of functions".
const Vec3 * _vertexArrayPtr
unsigned int _vertexArraySize
virtual void vertex(float x, float y)
Mimics the OpenGL glVertex() "family of functions".
void setTreatVertexDataAsTemporary(bool treatVertexDataAsTemporary)
virtual void begin(GLenum mode)
virtual void vertex(float x, float y, float z)
Mimics the OpenGL glVertex() "family of functions".
virtual void vertex(const Vec2 &vert)
Mimics the OpenGL glVertex() "family of functions".
bool getTreatVertexDataAsTemporary() const
virtual void vertex(float x, float y, float z, float w)
Mimics the OpenGL glVertex() "family of functions".
virtual void vertex(const Vec3 &vert)
Mimics the OpenGL glVertex() "family of functions".
virtual void end()
Mimics the OpenGL glEnd() function.
virtual void setVertexArray(unsigned int, const Vec2 *)
virtual void drawElements(GLenum mode, GLsizei count, const GLubyte *indices)
Mimics the OpenGL glDrawElements() function.
virtual void setVertexArray(unsigned int, const Vec4 *)
virtual void setVertexArray(unsigned int, const Vec3d *)
virtual void setVertexArray(unsigned int count, const Vec3 *vertices)
Definition: AlphaFunc.h:19
virtual void setVertexArray(unsigned int, const Vec2d *)
virtual void setVertexArray(unsigned int, const Vec4d *)
OSG_EXPORT std::ostream & notify(const NotifySeverity severity)
virtual void drawElements(GLenum mode, GLsizei count, const GLushort *indices)
Mimics the OpenGL glDrawElements() function.