TriangleIndexFunctor 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304
  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. #ifndef OSG_TRIANGLEINDEXFUNCTOR
  14. #define OSG_TRIANGLEINDEXFUNCTOR 1
  15. #include <osg/PrimitiveSet>
  16. #include <osg/Notify>
  17. namespace osg {
  18. template<class T>
  19. class TriangleIndexFunctor : public PrimitiveIndexFunctor, public T
  20. {
  21. public:
  22. virtual void setVertexArray(unsigned int,const Vec2*) {}
  23. virtual void setVertexArray(unsigned int ,const Vec3*) {}
  24. virtual void setVertexArray(unsigned int,const Vec4*) {}
  25. virtual void setVertexArray(unsigned int,const Vec2d*) {}
  26. virtual void setVertexArray(unsigned int ,const Vec3d*) {}
  27. virtual void setVertexArray(unsigned int,const Vec4d*) {}
  28. virtual void drawArrays(GLenum mode,GLint first,GLsizei count)
  29. {
  30. switch(mode)
  31. {
  32. case(GL_TRIANGLES):
  33. {
  34. unsigned int pos=first;
  35. for(GLsizei i=2;i<count;i+=3,pos+=3)
  36. {
  37. this->operator()(pos,pos+1,pos+2);
  38. }
  39. break;
  40. }
  41. case(GL_TRIANGLE_STRIP):
  42. {
  43. unsigned int pos=first;
  44. for(GLsizei i=2;i<count;++i,++pos)
  45. {
  46. if ((i%2)) this->operator()(pos,pos+2,pos+1);
  47. else this->operator()(pos,pos+1,pos+2);
  48. }
  49. break;
  50. }
  51. case(GL_QUADS):
  52. {
  53. unsigned int pos=first;
  54. for(GLsizei i=3;i<count;i+=4,pos+=4)
  55. {
  56. this->operator()(pos,pos+1,pos+2);
  57. this->operator()(pos,pos+2,pos+3);
  58. }
  59. break;
  60. }
  61. case(GL_QUAD_STRIP):
  62. {
  63. unsigned int pos=first;
  64. for(GLsizei i=3;i<count;i+=2,pos+=2)
  65. {
  66. this->operator()(pos,pos+1,pos+2);
  67. this->operator()(pos+1,pos+3,pos+2);
  68. }
  69. break;
  70. }
  71. case(GL_POLYGON): // treat polygons as GL_TRIANGLE_FAN
  72. case(GL_TRIANGLE_FAN):
  73. {
  74. unsigned int pos=first+1;
  75. for(GLsizei i=2;i<count;++i,++pos)
  76. {
  77. this->operator()(first,pos,pos+1);
  78. }
  79. break;
  80. }
  81. case(GL_POINTS):
  82. case(GL_LINES):
  83. case(GL_LINE_STRIP):
  84. case(GL_LINE_LOOP):
  85. default:
  86. // can't be converted into to triangles.
  87. break;
  88. }
  89. }
  90. virtual void drawElements(GLenum mode,GLsizei count,const GLubyte* indices)
  91. {
  92. if (indices==0 || count==0) return;
  93. typedef GLubyte Index;
  94. typedef const Index* IndexPointer;
  95. switch(mode)
  96. {
  97. case(GL_TRIANGLES):
  98. {
  99. IndexPointer ilast = &indices[count];
  100. for(IndexPointer iptr=indices;iptr<ilast;iptr+=3)
  101. this->operator()(*iptr,*(iptr+1),*(iptr+2));
  102. break;
  103. }
  104. case(GL_TRIANGLE_STRIP):
  105. {
  106. IndexPointer iptr = indices;
  107. for(GLsizei i=2;i<count;++i,++iptr)
  108. {
  109. if ((i%2)) this->operator()(*(iptr),*(iptr+2),*(iptr+1));
  110. else this->operator()(*(iptr),*(iptr+1),*(iptr+2));
  111. }
  112. break;
  113. }
  114. case(GL_QUADS):
  115. {
  116. IndexPointer iptr = indices;
  117. for(GLsizei i=3;i<count;i+=4,iptr+=4)
  118. {
  119. this->operator()(*(iptr),*(iptr+1),*(iptr+2));
  120. this->operator()(*(iptr),*(iptr+2),*(iptr+3));
  121. }
  122. break;
  123. }
  124. case(GL_QUAD_STRIP):
  125. {
  126. IndexPointer iptr = indices;
  127. for(GLsizei i=3;i<count;i+=2,iptr+=2)
  128. {
  129. this->operator()(*(iptr),*(iptr+1),*(iptr+2));
  130. this->operator()(*(iptr+1),*(iptr+3),*(iptr+2));
  131. }
  132. break;
  133. }
  134. case(GL_POLYGON): // treat polygons as GL_TRIANGLE_FAN
  135. case(GL_TRIANGLE_FAN):
  136. {
  137. IndexPointer iptr = indices;
  138. Index first = *iptr;
  139. ++iptr;
  140. for(GLsizei i=2;i<count;++i,++iptr)
  141. {
  142. this->operator()(first,*(iptr),*(iptr+1));
  143. }
  144. break;
  145. }
  146. case(GL_POINTS):
  147. case(GL_LINES):
  148. case(GL_LINE_STRIP):
  149. case(GL_LINE_LOOP):
  150. default:
  151. // can't be converted into to triangles.
  152. break;
  153. }
  154. }
  155. virtual void drawElements(GLenum mode,GLsizei count,const GLushort* indices)
  156. {
  157. if (indices==0 || count==0) return;
  158. typedef GLushort Index;
  159. typedef const Index* IndexPointer;
  160. switch(mode)
  161. {
  162. case(GL_TRIANGLES):
  163. {
  164. IndexPointer ilast = &indices[count];
  165. for(IndexPointer iptr=indices;iptr<ilast;iptr+=3)
  166. this->operator()(*iptr,*(iptr+1),*(iptr+2));
  167. break;
  168. }
  169. case(GL_TRIANGLE_STRIP):
  170. {
  171. IndexPointer iptr = indices;
  172. for(GLsizei i=2;i<count;++i,++iptr)
  173. {
  174. if ((i%2)) this->operator()(*(iptr),*(iptr+2),*(iptr+1));
  175. else this->operator()(*(iptr),*(iptr+1),*(iptr+2));
  176. }
  177. break;
  178. }
  179. case(GL_QUADS):
  180. {
  181. IndexPointer iptr = indices;
  182. for(GLsizei i=3;i<count;i+=4,iptr+=4)
  183. {
  184. this->operator()(*(iptr),*(iptr+1),*(iptr+2));
  185. this->operator()(*(iptr),*(iptr+2),*(iptr+3));
  186. }
  187. break;
  188. }
  189. case(GL_QUAD_STRIP):
  190. {
  191. IndexPointer iptr = indices;
  192. for(GLsizei i=3;i<count;i+=2,iptr+=2)
  193. {
  194. this->operator()(*(iptr),*(iptr+1),*(iptr+2));
  195. this->operator()(*(iptr+1),*(iptr+3),*(iptr+2));
  196. }
  197. break;
  198. }
  199. case(GL_POLYGON): // treat polygons as GL_TRIANGLE_FAN
  200. case(GL_TRIANGLE_FAN):
  201. {
  202. IndexPointer iptr = indices;
  203. Index first = *iptr;
  204. ++iptr;
  205. for(GLsizei i=2;i<count;++i,++iptr)
  206. {
  207. this->operator()(first,*(iptr),*(iptr+1));
  208. }
  209. break;
  210. }
  211. case(GL_POINTS):
  212. case(GL_LINES):
  213. case(GL_LINE_STRIP):
  214. case(GL_LINE_LOOP):
  215. default:
  216. // can't be converted into to triangles.
  217. break;
  218. }
  219. }
  220. virtual void drawElements(GLenum mode,GLsizei count,const GLuint* indices)
  221. {
  222. if (indices==0 || count==0) return;
  223. typedef GLuint Index;
  224. typedef const Index* IndexPointer;
  225. switch(mode)
  226. {
  227. case(GL_TRIANGLES):
  228. {
  229. IndexPointer ilast = &indices[count];
  230. for(IndexPointer iptr=indices;iptr<ilast;iptr+=3)
  231. this->operator()(*iptr,*(iptr+1),*(iptr+2));
  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()(*(iptr),*(iptr+2),*(iptr+1));
  240. else this->operator()(*(iptr),*(iptr+1),*(iptr+2));
  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()(*(iptr),*(iptr+1),*(iptr+2));
  250. this->operator()(*(iptr),*(iptr+2),*(iptr+3));
  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()(*(iptr),*(iptr+1),*(iptr+2));
  260. this->operator()(*(iptr+1),*(iptr+3),*(iptr+2));
  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. Index first = *iptr;
  269. ++iptr;
  270. for(GLsizei i=2;i<count;++i,++iptr)
  271. {
  272. this->operator()(first,*(iptr),*(iptr+1));
  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. }
  287. #endif