TemplatePrimitiveIndexFunctor 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441
  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_TERMPLATEPRIMITIVEINDEXFUNCTOR
  14. #define OSG_TERMPLATEPRIMITIVEINDEXFUNCTOR 1
  15. #include <osg/PrimitiveSet>
  16. #include <osg/Notify>
  17. namespace osg {
  18. /** Provides access to the primitives that compose an \c osg::Drawable.
  19. * <p>Notice that \c TemplatePrimitiveIndexFunctor is a class template, and that it inherits
  20. * from its template parameter \c T. This template parameter must implement
  21. * <tt>operator()(const osg::Vec3 v1, const osg::Vec3 v2, const osg::Vec3
  22. * v3, bool treatVertexDataAsTemporary)</tt>,
  23. * <tt>operator()(const osg::Vec3 v1, const osg::Vec3 v2, bool
  24. * treatVertexDataAsTemporary)</tt>, <tt>operator()(const osg::Vec3 v1,
  25. * const osg::Vec3 v2, const osg::Vec3 v3, bool treatVertexDataAsTemporary)</tt>,
  26. * and <tt>operator()(const osg::Vec3 v1, const osg::Vec3 v2, const osg::Vec3 v3,
  27. * const osg::Vec3 v4, bool treatVertexDataAsTemporary)</tt> which will be called
  28. * for the matching primitive when the functor is applied to a \c Drawable.
  29. * Parameters \c v1, \c v2, \c v3, and \c v4 are the vertices of the primitive.
  30. * The last parameter, \c treatVertexDataAsTemporary, indicates whether these
  31. * vertices are coming from a "real" vertex array, or from a temporary vertex array,
  32. * created by the \c TemplatePrimitiveIndexFunctor from some other geometry representation.
  33. * @see \c PrimitiveFunctor for general usage hints.
  34. */
  35. template<class T>
  36. class TemplatePrimitiveIndexFunctor : public PrimitiveIndexFunctor, public T
  37. {
  38. public:
  39. TemplatePrimitiveIndexFunctor() {}
  40. virtual ~TemplatePrimitiveIndexFunctor() {}
  41. virtual void setVertexArray(unsigned int,const Vec2*) {}
  42. virtual void setVertexArray(unsigned int ,const Vec3*) {}
  43. virtual void setVertexArray(unsigned int,const Vec4*) {}
  44. virtual void setVertexArray(unsigned int,const Vec2d*) {}
  45. virtual void setVertexArray(unsigned int ,const Vec3d*) {}
  46. virtual void setVertexArray(unsigned int,const Vec4d*) {}
  47. virtual void drawArrays(GLenum mode,GLint first,GLsizei count)
  48. {
  49. switch(mode)
  50. {
  51. case(GL_TRIANGLES):
  52. {
  53. unsigned int pos=first;
  54. for(GLsizei i=2;i<count;i+=3,pos+=3)
  55. {
  56. this->operator()(pos,pos+1,pos+2);
  57. }
  58. break;
  59. }
  60. case(GL_TRIANGLE_STRIP):
  61. {
  62. unsigned int pos=first;
  63. for(GLsizei i=2;i<count;++i,++pos)
  64. {
  65. if ((i%2)) this->operator()(pos,pos+2,pos+1);
  66. else this->operator()(pos,pos+1,pos+2);
  67. }
  68. break;
  69. }
  70. case(GL_QUADS):
  71. {
  72. unsigned int pos=first;
  73. for(GLsizei i=3;i<count;i+=4,pos+=4)
  74. {
  75. this->operator()(pos,pos+1,pos+2,pos+3);
  76. }
  77. break;
  78. }
  79. case(GL_QUAD_STRIP):
  80. {
  81. unsigned int pos=first;
  82. for(GLsizei i=3;i<count;i+=2,pos+=2)
  83. {
  84. this->operator()(pos,pos+1,pos+2,pos+3);
  85. }
  86. break;
  87. }
  88. case(GL_POLYGON): // treat polygons as GL_TRIANGLE_FAN
  89. case(GL_TRIANGLE_FAN):
  90. {
  91. unsigned int pos=first+1;
  92. for(GLsizei i=2;i<count;++i,++pos)
  93. {
  94. this->operator()(first,pos,pos+1);
  95. }
  96. break;
  97. }
  98. case(GL_POINTS):
  99. {
  100. unsigned int pos=first;
  101. for(GLsizei i=0;i<count;++i,++pos)
  102. {
  103. this->operator()(pos);
  104. }
  105. break;
  106. }
  107. case(GL_LINES):
  108. {
  109. unsigned int pos=first;
  110. for(GLsizei i=1;i<count;i+=2,pos+=2)
  111. {
  112. this->operator()(pos,pos+1);
  113. }
  114. break;
  115. }
  116. case(GL_LINE_STRIP):
  117. {
  118. unsigned int pos=first;
  119. for(GLsizei i=1;i<count;++i,++pos)
  120. {
  121. this->operator()(pos,pos+1);
  122. }
  123. break;
  124. }
  125. case(GL_LINE_LOOP):
  126. {
  127. unsigned int pos=first;
  128. for(GLsizei i=1;i<count;++i,++pos)
  129. {
  130. this->operator()(pos,pos+1);
  131. }
  132. this->operator()(first+count-1,first);
  133. break;
  134. }
  135. default:
  136. // can't be converted into to triangles.
  137. break;
  138. }
  139. }
  140. virtual void drawElements(GLenum mode,GLsizei count,const GLubyte* indices)
  141. {
  142. if (indices==0 || count==0) return;
  143. typedef GLubyte Index;
  144. typedef const Index* IndexPointer;
  145. switch(mode)
  146. {
  147. case(GL_TRIANGLES):
  148. {
  149. IndexPointer ilast = &indices[count];
  150. for(IndexPointer iptr=indices;iptr<ilast;iptr+=3)
  151. this->operator()(*iptr,*(iptr+1),*(iptr+2));
  152. break;
  153. }
  154. case(GL_TRIANGLE_STRIP):
  155. {
  156. IndexPointer iptr = indices;
  157. for(GLsizei i=2;i<count;++i,++iptr)
  158. {
  159. if ((i%2)) this->operator()(*(iptr),*(iptr+2),*(iptr+1));
  160. else this->operator()(*(iptr),*(iptr+1),*(iptr+2));
  161. }
  162. break;
  163. }
  164. case(GL_QUADS):
  165. {
  166. IndexPointer iptr = indices;
  167. for(GLsizei i=3;i<count;i+=4,iptr+=4)
  168. {
  169. this->operator()(*(iptr),*(iptr+1),*(iptr+2),*(iptr+3));
  170. }
  171. break;
  172. }
  173. case(GL_QUAD_STRIP):
  174. {
  175. IndexPointer iptr = indices;
  176. for(GLsizei i=3;i<count;i+=2,iptr+=2)
  177. {
  178. this->operator()(*(iptr),*(iptr+1),*(iptr+2),*(iptr+3));
  179. }
  180. break;
  181. }
  182. case(GL_POLYGON): // treat polygons as GL_TRIANGLE_FAN
  183. case(GL_TRIANGLE_FAN):
  184. {
  185. IndexPointer iptr = indices;
  186. Index first = *iptr;
  187. ++iptr;
  188. for(GLsizei i=2;i<count;++i,++iptr)
  189. {
  190. this->operator()(first,*(iptr),*(iptr+1));
  191. }
  192. break;
  193. }
  194. case(GL_POINTS):
  195. {
  196. IndexPointer ilast = &indices[count];
  197. for(IndexPointer iptr=indices;iptr<ilast;++iptr)
  198. this->operator()(*iptr);
  199. break;
  200. }
  201. case(GL_LINES):
  202. {
  203. IndexPointer ilast = &indices[count];
  204. for(IndexPointer iptr=indices;iptr<ilast;iptr+=2)
  205. this->operator()(*iptr,*(iptr+1));
  206. break;
  207. }
  208. case(GL_LINE_STRIP):
  209. {
  210. IndexPointer iptr = indices;
  211. for(GLsizei i=1;i<count;++i,++iptr)
  212. {
  213. this->operator()(*(iptr),*(iptr+1));
  214. }
  215. break;
  216. }
  217. case(GL_LINE_LOOP):
  218. {
  219. IndexPointer iptr = indices;
  220. for(GLsizei i=1;i<count;++i,++iptr)
  221. {
  222. this->operator()(*(iptr),*(iptr+1));
  223. }
  224. this->operator()(*(iptr),*(indices));
  225. break;
  226. }
  227. default:
  228. // can't be converted into to triangles.
  229. break;
  230. }
  231. }
  232. virtual void drawElements(GLenum mode,GLsizei count,const GLushort* indices)
  233. {
  234. if (indices==0 || count==0) return;
  235. typedef GLushort Index;
  236. typedef const Index* IndexPointer;
  237. switch(mode)
  238. {
  239. case(GL_TRIANGLES):
  240. {
  241. IndexPointer ilast = &indices[count];
  242. for(IndexPointer iptr=indices;iptr<ilast;iptr+=3)
  243. this->operator()(*iptr,*(iptr+1),*(iptr+2));
  244. break;
  245. }
  246. case(GL_TRIANGLE_STRIP):
  247. {
  248. IndexPointer iptr = indices;
  249. for(GLsizei i=2;i<count;++i,++iptr)
  250. {
  251. if ((i%2)) this->operator()(*(iptr),*(iptr+2),*(iptr+1));
  252. else this->operator()(*(iptr),*(iptr+1),*(iptr+2));
  253. }
  254. break;
  255. }
  256. case(GL_QUADS):
  257. {
  258. IndexPointer iptr = indices;
  259. for(GLsizei i=3;i<count;i+=4,iptr+=4)
  260. {
  261. this->operator()(*(iptr),*(iptr+1),*(iptr+2),*(iptr+3));
  262. }
  263. break;
  264. }
  265. case(GL_QUAD_STRIP):
  266. {
  267. IndexPointer iptr = indices;
  268. for(GLsizei i=3;i<count;i+=2,iptr+=2)
  269. {
  270. this->operator()(*(iptr),*(iptr+1),*(iptr+2),*(iptr+3));
  271. }
  272. break;
  273. }
  274. case(GL_POLYGON): // treat polygons as GL_TRIANGLE_FAN
  275. case(GL_TRIANGLE_FAN):
  276. {
  277. IndexPointer iptr = indices;
  278. Index first = *iptr;
  279. ++iptr;
  280. for(GLsizei i=2;i<count;++i,++iptr)
  281. {
  282. this->operator()(first,*(iptr),*(iptr+1));
  283. }
  284. break;
  285. }
  286. case(GL_POINTS):
  287. {
  288. IndexPointer ilast = &indices[count];
  289. for(IndexPointer iptr=indices;iptr<ilast;++iptr)
  290. this->operator()(*iptr);
  291. break;
  292. }
  293. case(GL_LINES):
  294. {
  295. IndexPointer ilast = &indices[count];
  296. for(IndexPointer iptr=indices;iptr<ilast;iptr+=2)
  297. this->operator()(*iptr,*(iptr+1));
  298. break;
  299. }
  300. case(GL_LINE_STRIP):
  301. {
  302. IndexPointer iptr = indices;
  303. for(GLsizei i=1;i<count;++i,++iptr)
  304. {
  305. this->operator()(*(iptr),*(iptr+1));
  306. }
  307. break;
  308. }
  309. case(GL_LINE_LOOP):
  310. {
  311. IndexPointer iptr = indices;
  312. for(GLsizei i=1;i<count;++i,++iptr)
  313. {
  314. this->operator()(*(iptr),*(iptr+1));
  315. }
  316. this->operator()(*(iptr),*(indices));
  317. break;
  318. }
  319. default:
  320. // can't be converted into to triangles.
  321. break;
  322. }
  323. }
  324. virtual void drawElements(GLenum mode,GLsizei count,const GLuint* indices)
  325. {
  326. if (indices==0 || count==0) return;
  327. typedef GLuint Index;
  328. typedef const Index* IndexPointer;
  329. switch(mode)
  330. {
  331. case(GL_TRIANGLES):
  332. {
  333. IndexPointer ilast = &indices[count];
  334. for(IndexPointer iptr=indices;iptr<ilast;iptr+=3)
  335. this->operator()(*iptr,*(iptr+1),*(iptr+2));
  336. break;
  337. }
  338. case(GL_TRIANGLE_STRIP):
  339. {
  340. IndexPointer iptr = indices;
  341. for(GLsizei i=2;i<count;++i,++iptr)
  342. {
  343. if ((i%2)) this->operator()(*(iptr),*(iptr+2),*(iptr+1));
  344. else this->operator()(*(iptr),*(iptr+1),*(iptr+2));
  345. }
  346. break;
  347. }
  348. case(GL_QUADS):
  349. {
  350. IndexPointer iptr = indices;
  351. for(GLsizei i=3;i<count;i+=4,iptr+=4)
  352. {
  353. this->operator()(*(iptr),*(iptr+1),*(iptr+2),*(iptr+3));
  354. }
  355. break;
  356. }
  357. case(GL_QUAD_STRIP):
  358. {
  359. IndexPointer iptr = indices;
  360. for(GLsizei i=3;i<count;i+=2,iptr+=2)
  361. {
  362. this->operator()(*(iptr),*(iptr+1),*(iptr+2),*(iptr+3));
  363. }
  364. break;
  365. }
  366. case(GL_POLYGON): // treat polygons as GL_TRIANGLE_FAN
  367. case(GL_TRIANGLE_FAN):
  368. {
  369. IndexPointer iptr = indices;
  370. Index first = *iptr;
  371. ++iptr;
  372. for(GLsizei i=2;i<count;++i,++iptr)
  373. {
  374. this->operator()(first,*(iptr),*(iptr+1));
  375. }
  376. break;
  377. }
  378. case(GL_POINTS):
  379. {
  380. IndexPointer ilast = &indices[count];
  381. for(IndexPointer iptr=indices;iptr<ilast;++iptr)
  382. this->operator()(*iptr);
  383. break;
  384. }
  385. case(GL_LINES):
  386. {
  387. IndexPointer ilast = &indices[count];
  388. for(IndexPointer iptr=indices;iptr<ilast;iptr+=2)
  389. this->operator()(*iptr,*(iptr+1));
  390. break;
  391. }
  392. case(GL_LINE_STRIP):
  393. {
  394. IndexPointer iptr = indices;
  395. for(GLsizei i=1;i<count;++i,++iptr)
  396. {
  397. this->operator()(*(iptr),*(iptr+1));
  398. }
  399. break;
  400. }
  401. case(GL_LINE_LOOP):
  402. {
  403. IndexPointer iptr = indices;
  404. for(GLsizei i=1;i<count;++i,++iptr)
  405. {
  406. this->operator()(*(iptr),*(iptr+1));
  407. }
  408. this->operator()(*(iptr),*(indices));
  409. break;
  410. }
  411. default:
  412. // can't be converted into to triangles.
  413. break;
  414. }
  415. }
  416. };
  417. }
  418. #endif