TriangleLinePointIndexFunctor 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260
  1. /* -*-c++-*- OpenSceneGraph - Copyright (C) Sketchfab
  2. *
  3. * This application is open source and may be redistributed and/or modified
  4. * freely and without restriction, both in commercial and non commercial
  5. * applications, as long as this copyright notice is maintained.
  6. *
  7. * This application is distributed in the hope that it will be useful,
  8. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  10. *
  11. */
  12. #ifndef TRIANGLE_LINE_POINT_INDEX_FUNCTOR
  13. #define TRIANGLE_LINE_POINT_INDEX_FUNCTOR
  14. #include <osg/PrimitiveSet>
  15. #include <osg/Array>
  16. namespace osg {
  17. template<class T>
  18. class TriangleLinePointIndexFunctor : public osg::PrimitiveIndexFunctor, public T
  19. {
  20. public:
  21. virtual void setVertexArray(unsigned int,const osg::Vec2*)
  22. {}
  23. virtual void setVertexArray(unsigned int ,const osg::Vec3* )
  24. {}
  25. virtual void setVertexArray(unsigned int,const osg::Vec4* )
  26. {}
  27. virtual void setVertexArray(unsigned int,const osg::Vec2d*)
  28. {}
  29. virtual void setVertexArray(unsigned int ,const osg::Vec3d* )
  30. {}
  31. virtual void setVertexArray(unsigned int,const osg::Vec4d* )
  32. {}
  33. virtual void begin(GLenum mode) {
  34. _modeCache = mode;
  35. _indexCache.clear();
  36. }
  37. virtual void vertex(unsigned int vert) {
  38. _indexCache.push_back(vert);
  39. }
  40. virtual void end() {
  41. if (!_indexCache.empty()) {
  42. drawElements(_modeCache,_indexCache.size(),&_indexCache.front());
  43. }
  44. }
  45. virtual void drawArrays(GLenum mode, GLint first, GLsizei count) {
  46. switch(mode)
  47. {
  48. case(GL_TRIANGLES):
  49. {
  50. unsigned int pos=first;
  51. for(GLsizei i = 2 ; i < count ; i += 3, pos += 3) {
  52. this->operator()(pos, pos + 1, pos + 2);
  53. }
  54. break;
  55. }
  56. case(GL_TRIANGLE_STRIP):
  57. {
  58. unsigned int pos = first;
  59. for(GLsizei i = 2 ; i < count ; ++ i, ++ pos) {
  60. if ((i%2)) this->operator()(pos, pos + 2, pos + 1);
  61. else this->operator()(pos, pos + 1, pos + 2);
  62. }
  63. break;
  64. }
  65. case(GL_QUADS):
  66. {
  67. unsigned int pos = first;
  68. for(GLsizei i = 3 ; i < count ; i += 4, pos += 4) {
  69. this->operator()(pos,pos + 1, pos + 2);
  70. this->operator()(pos,pos + 2, pos + 3);
  71. }
  72. break;
  73. }
  74. case(GL_QUAD_STRIP):
  75. {
  76. unsigned int pos = first;
  77. for(GLsizei i = 3 ; i < count ; i += 2, pos += 2) {
  78. this->operator()(pos, pos + 1,pos + 2);
  79. this->operator()(pos + 1,pos + 3,pos + 2);
  80. }
  81. break;
  82. }
  83. case(GL_POLYGON): // treat polygons as GL_TRIANGLE_FAN
  84. case(GL_TRIANGLE_FAN):
  85. {
  86. unsigned int pos = first + 1;
  87. for(GLsizei i = 2 ; i < count ; ++ i, ++ pos) {
  88. this->operator()(first, pos, pos + 1);
  89. }
  90. break;
  91. }
  92. case(GL_LINES):
  93. {
  94. unsigned int pos = first;
  95. for(GLsizei i = 0 ; i < count ; i += 2, pos += 2) {
  96. this->operator()(pos, pos + 1);
  97. }
  98. break;
  99. }
  100. case(GL_LINE_STRIP):
  101. {
  102. unsigned int pos = first;
  103. for(GLsizei i = 0 ; i < count - 1 ; i += 1, pos += 1) {
  104. this->operator()(pos, pos + 1);
  105. }
  106. break;
  107. }
  108. case(GL_LINE_LOOP):
  109. {
  110. unsigned int pos = first;
  111. for(GLsizei i = 0 ; i < count - 1 ; i += 1, pos += 1) {
  112. this->operator()(pos, pos + 1);
  113. }
  114. this->operator()(pos, first);
  115. break;
  116. }
  117. case(GL_POINTS):
  118. {
  119. unsigned int pos=first;
  120. for(GLsizei i = 0 ; i < count ; ++ i) {
  121. this->operator()(pos + i);
  122. }
  123. break;
  124. }
  125. default:
  126. break;
  127. }
  128. }
  129. template<typename I>
  130. void drawElements(GLenum mode, GLsizei count, const I* indices)
  131. {
  132. typedef I Index;
  133. typedef const I* IndexPointer;
  134. if (indices == 0 || count == 0) {
  135. return;
  136. }
  137. switch(mode)
  138. {
  139. case(GL_TRIANGLES):
  140. {
  141. IndexPointer ilast = &indices[count];
  142. for(IndexPointer iptr = indices ; iptr < ilast ; iptr += 3) {
  143. this->operator()(*iptr, *(iptr + 1), *(iptr + 2));
  144. }
  145. break;
  146. }
  147. case(GL_TRIANGLE_STRIP):
  148. {
  149. IndexPointer iptr = indices;
  150. for(GLsizei i = 2 ; i < count ; ++ i, ++ iptr) {
  151. if ((i%2)) this->operator()(*(iptr), *(iptr + 2), *(iptr + 1));
  152. else this->operator()(*(iptr), *(iptr + 1), *(iptr + 2));
  153. }
  154. break;
  155. }
  156. case(GL_QUADS):
  157. {
  158. IndexPointer iptr = indices;
  159. for(GLsizei i = 3 ; i < count ; i += 4, iptr += 4) {
  160. this->operator()(*(iptr), *(iptr + 1), *(iptr + 2));
  161. this->operator()(*(iptr), *(iptr + 2), *(iptr + 3));
  162. }
  163. break;
  164. }
  165. case(GL_QUAD_STRIP):
  166. {
  167. IndexPointer iptr = indices;
  168. for(GLsizei i = 3 ; i < count ; i += 2, iptr += 2) {
  169. this->operator()(*(iptr), *(iptr + 1), *(iptr + 2));
  170. this->operator()(*(iptr + 1), *(iptr + 3), *(iptr + 2));
  171. }
  172. break;
  173. }
  174. case(GL_POLYGON): // treat polygons as GL_TRIANGLE_FAN
  175. case(GL_TRIANGLE_FAN):
  176. {
  177. IndexPointer iptr = indices;
  178. Index first = *iptr;
  179. ++iptr;
  180. for(GLsizei i = 2 ; i < count ; ++ i, ++ iptr) {
  181. this->operator()(first, *(iptr), *(iptr + 1));
  182. }
  183. break;
  184. }
  185. case(GL_LINES):
  186. {
  187. const I* iptr = indices;
  188. for(GLsizei i = 0 ; i < count ; i += 2, iptr += 2) {
  189. this->operator()(*iptr, *(iptr + 1));
  190. }
  191. break;
  192. }
  193. case(GL_LINE_STRIP):
  194. {
  195. const I* iptr = indices;
  196. for(GLsizei i = 0 ; i < count - 1 ; i += 1, iptr += 1) {
  197. this->operator()(*iptr, *(iptr + 1));
  198. }
  199. break;
  200. }
  201. case(GL_LINE_LOOP):
  202. {
  203. const I* iptr = indices;
  204. I first = *iptr;
  205. for(GLsizei i = 0 ; i < count - 1 ; i += 1, iptr += 1) {
  206. this->operator()(*iptr, *(iptr + 1));
  207. }
  208. this->operator()(*iptr, first);
  209. break;
  210. }
  211. case GL_POINTS:
  212. {
  213. IndexPointer ilast = &indices[count];
  214. for(IndexPointer iptr = indices ; iptr < ilast ; iptr += 1) {
  215. this->operator()(*iptr);
  216. }
  217. break;
  218. }
  219. default:
  220. break;
  221. }
  222. }
  223. virtual void drawElements(GLenum mode, GLsizei count, const GLubyte* indices) {
  224. drawElements<GLubyte>(mode, count, indices);
  225. }
  226. virtual void drawElements(GLenum mode,GLsizei count,const GLushort* indices) {
  227. drawElements<GLushort>(mode, count, indices);
  228. }
  229. virtual void drawElements(GLenum mode,GLsizei count,const GLuint* indices) {
  230. drawElements<GLuint>(mode, count, indices);
  231. }
  232. GLenum _modeCache;
  233. std::vector<GLuint> _indexCache;
  234. std::vector<unsigned int> _remap;
  235. };
  236. }
  237. #endif