OpenGLVisitor.cpp 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450
  1. /***************************************************************************
  2. OpenGLVisitor.cpp - description
  3. -------------------
  4. begin : Sat Jan 6 2001
  5. copyright : (C) 2001 by Henrik Enqvist
  6. email : henqvist@excite.com
  7. ***************************************************************************/
  8. #include "Private.h"
  9. #include "OpenGLVisitor.h"
  10. #include "Group.h"
  11. #include "Shape3D.h"
  12. #include "Polygon.h"
  13. #include "BillBoard.h"
  14. #include "Config.h"
  15. #ifndef EM_VERTEXARRAY
  16. #define EM_VERTEXARRAY 0
  17. #endif
  18. #ifndef EM_OPENGL_LIGHTS
  19. #define EM_OPENGL_LIGHTS 0
  20. #endif
  21. /* Optimization observations:
  22. * * Voodoo 3 System
  23. * glVertex3f is a bit fatser than glVertex3fv ~3%.
  24. * glVertex3f is faster then glVertexArray ~10-20%, really strange.
  25. */
  26. OpenGLVisitor * OpenGLVisitor::p_OpenGLVisitor = NULL;
  27. int OpenGLVisitor::m_iPoly = 0;
  28. OpenGLVisitor::OpenGLVisitor(){
  29. m_iMode = EM_GL_GCOL_TEX;
  30. m_bOffset = false;
  31. }
  32. OpenGLVisitor::~OpenGLVisitor(){
  33. p_OpenGLVisitor = NULL;
  34. }
  35. OpenGLVisitor * OpenGLVisitor::getInstance() {
  36. if (p_OpenGLVisitor == NULL) {
  37. p_OpenGLVisitor = new OpenGLVisitor();
  38. }
  39. return p_OpenGLVisitor;
  40. }
  41. void OpenGLVisitor::empty() {
  42. #if EM_USE_SDL
  43. #if EM_VERTEXARRAY
  44. glEnableClientState(GL_VERTEX_ARRAY);
  45. glEnableClientState(GL_COLOR_ARRAY);
  46. #endif
  47. switch (m_iMode) {
  48. case EM_GL_GCOL_TEX: {
  49. glEnable(GL_DEPTH_TEST);
  50. glDepthFunc(GL_LESS);
  51. //glDisable(GL_TEXTURE_2D);
  52. glDisable(GL_BLEND);
  53. glDisable(GL_ALPHA_TEST);
  54. glDepthMask(GL_TRUE);
  55. } break;
  56. case EM_GL_GCOL_TEX_TRANS: {
  57. glEnable(GL_DEPTH_TEST);
  58. glDepthFunc(GL_LESS);
  59. //glDisable(GL_TEXTURE_2D);
  60. glEnable(GL_BLEND);
  61. glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  62. glDepthMask(GL_FALSE);
  63. // glEnable(GL_ALPHA_TEST);
  64. // glAlphaFunc(GL_GREATER, 0.05);
  65. } break;
  66. case EM_GL_CLEAN: {
  67. #if EM_DEBUG
  68. m_iPoly = 0;
  69. #endif
  70. glDisable(GL_DEPTH_TEST);
  71. glDisable(GL_ALPHA_TEST);
  72. glDisable(GL_TEXTURE_2D);
  73. glDisable(GL_BLEND);
  74. } break;
  75. }
  76. #endif
  77. }
  78. void OpenGLVisitor::visit(Group* g) {
  79. #if EM_USE_SDL
  80. int filter = Config::getInstance()->getGLFilter();
  81. //bool lights = Config::getInstance()->useLights();
  82. switch (m_iMode) {
  83. case EM_GL_GCOL_TEX: {
  84. // shapes
  85. vector<Shape3D*>::iterator shapeIter = g->m_vShape3D.begin();
  86. vector<Shape3D*>::iterator shapeEnd = g->m_vShape3D.end();
  87. for ( ; shapeIter != shapeEnd; shapeIter++) {
  88. if (EM_SHAPE3D_HIDDEN & (*shapeIter)->m_iProperties) continue;
  89. if ((*shapeIter)->m_iProperties & EM_SHAPE3D_BEHIND) {
  90. glEnable(GL_POLYGON_OFFSET_FILL);
  91. glPolygonOffset(1.0, 1.0);
  92. } else if ((*shapeIter)->m_iProperties & EM_SHAPE3D_BEHIND2) {
  93. glEnable(GL_POLYGON_OFFSET_FILL);
  94. glPolygonOffset(1.0, 2.0);
  95. } else {
  96. glDisable(GL_POLYGON_OFFSET_FILL);
  97. }
  98. if ((*shapeIter)->m_Texture != NULL && filter != -1) { // textured polygons
  99. glEnable(GL_TEXTURE_2D);
  100. glBindTexture(GL_TEXTURE_2D, *((*shapeIter)->m_Texture));
  101. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter);
  102. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter);
  103. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
  104. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
  105. glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
  106. if ((*shapeIter)->m_iProperties & EM_SHAPE3D_ALWAYSLIT) { // EM_SHAPE3D_ALWAYSLIT
  107. vector<Polygon3D*>::iterator polyIter = (*shapeIter)->m_vPolygon.begin();
  108. vector<Polygon3D*>::iterator polyEnd = (*shapeIter)->m_vPolygon.end();
  109. for ( ; polyIter != polyEnd; ++polyIter) {
  110. if ((*polyIter)->m_iProperties & EM_POLY_TRANS) continue;
  111. #if EM_DEBUG
  112. ++m_iPoly;
  113. #endif
  114. vector<int>::iterator indexIter = (*polyIter)->m_vIndex.begin();
  115. vector<int>::iterator indexEnd = (*polyIter)->m_vIndex.end();
  116. glBegin(GL_POLYGON);
  117. for ( ; indexIter != indexEnd; ++indexIter) {
  118. glTexCoord2f((*shapeIter)->m_vTexCoord[(*indexIter)].u,
  119. (*shapeIter)->m_vTexCoord[(*indexIter)].v);
  120. glColor3f((*shapeIter)->m_vColor[(*indexIter)].r,
  121. (*shapeIter)->m_vColor[(*indexIter)].g,
  122. (*shapeIter)->m_vColor[(*indexIter)].b);
  123. glVertex3f((*shapeIter)->m_vVtxAlign[(*indexIter)].x,
  124. (*shapeIter)->m_vVtxAlign[(*indexIter)].y,
  125. (*shapeIter)->m_vVtxAlign[(*indexIter)].z);
  126. }
  127. glEnd();
  128. }
  129. } else { // ! EM_SHAPE3D_ALWAYSLIT
  130. vector<Polygon3D*>::iterator polyIter = (*shapeIter)->m_vPolygon.begin();
  131. vector<Polygon3D*>::iterator polyEnd = (*shapeIter)->m_vPolygon.end();
  132. for ( ; polyIter != polyEnd; ++polyIter) {
  133. if ((*polyIter)->m_iProperties & EM_POLY_TRANS) continue;
  134. #if EM_DEBUG
  135. ++m_iPoly;
  136. #endif
  137. vector<int>::iterator indexIter = (*polyIter)->m_vIndex.begin();
  138. vector<int>::iterator indexEnd = (*polyIter)->m_vIndex.end();
  139. glBegin(GL_POLYGON);
  140. for ( ; indexIter != indexEnd; ++indexIter) {
  141. glTexCoord2f((*shapeIter)->m_vTexCoord[(*indexIter)].u,
  142. (*shapeIter)->m_vTexCoord[(*indexIter)].v);
  143. // Question should textured polygons have specular?
  144. glColor3f((*shapeIter)->m_vLight[(*indexIter)].r,
  145. (*shapeIter)->m_vLight[(*indexIter)].g,
  146. (*shapeIter)->m_vLight[(*indexIter)].b);
  147. glVertex3f((*shapeIter)->m_vVtxAlign[(*indexIter)].x,
  148. (*shapeIter)->m_vVtxAlign[(*indexIter)].y,
  149. (*shapeIter)->m_vVtxAlign[(*indexIter)].z);
  150. }
  151. glEnd();
  152. }
  153. }
  154. } else { // if ((*shapeIter)->m_Texture... // color polygons
  155. glDisable(GL_TEXTURE_2D);
  156. // if statement moved outside for loop for performance
  157. if ((*shapeIter)->m_iProperties & EM_SHAPE3D_ALWAYSLIT) { // EM_SHAPE3D_ALWAYSLIT
  158. vector<Polygon3D*>::iterator polyIter = (*shapeIter)->m_vPolygon.begin();
  159. vector<Polygon3D*>::iterator polyEnd = (*shapeIter)->m_vPolygon.end();
  160. for ( ; polyIter != polyEnd; ++polyIter) {
  161. if ((*polyIter)->m_iProperties & EM_POLY_TRANS) continue;
  162. #if EM_DEBUG
  163. ++m_iPoly;
  164. #endif
  165. vector<int>::iterator indexIter = (*polyIter)->m_vIndex.begin();
  166. vector<int>::iterator indexEnd = (*polyIter)->m_vIndex.end();
  167. glBegin(GL_POLYGON);
  168. for (; indexIter != indexEnd; ++indexIter) {
  169. glColor3f((*shapeIter)->m_vColor[(*indexIter)].r,
  170. (*shapeIter)->m_vColor[(*indexIter)].g,
  171. (*shapeIter)->m_vColor[(*indexIter)].b);
  172. glVertex3f((*shapeIter)->m_vVtxAlign[(*indexIter)].x,
  173. (*shapeIter)->m_vVtxAlign[(*indexIter)].y,
  174. (*shapeIter)->m_vVtxAlign[(*indexIter)].z);
  175. }
  176. glEnd();
  177. }
  178. } else { // ! EM_SHAPE3D_ALWAYSLIT
  179. vector<Polygon3D*>::iterator polyIter = (*shapeIter)->m_vPolygon.begin();
  180. vector<Polygon3D*>::iterator polyEnd = (*shapeIter)->m_vPolygon.end();
  181. for ( ; polyIter != polyEnd; ++polyIter) {
  182. if ((*polyIter)->m_iProperties & EM_POLY_TRANS) continue;
  183. #if EM_DEBUG
  184. ++m_iPoly;
  185. #endif
  186. vector<int>::iterator indexIter = (*polyIter)->m_vIndex.begin();
  187. vector<int>::iterator indexEnd = (*polyIter)->m_vIndex.end();
  188. glBegin(GL_POLYGON);
  189. for (; indexIter != indexEnd; ++indexIter) {
  190. glColor3f((*shapeIter)->m_vLitColor[(*indexIter)].r,
  191. (*shapeIter)->m_vLitColor[(*indexIter)].g,
  192. (*shapeIter)->m_vLitColor[(*indexIter)].b);
  193. glVertex3f((*shapeIter)->m_vVtxAlign[(*indexIter)].x,
  194. (*shapeIter)->m_vVtxAlign[(*indexIter)].y,
  195. (*shapeIter)->m_vVtxAlign[(*indexIter)].z);
  196. }
  197. glEnd();
  198. }
  199. }
  200. }
  201. }
  202. // billboard
  203. BillBoard * b = g->p_BillBoard;
  204. if (b != NULL && !(b->m_iProperties & EM_BILLBOARD_TRANS)) {
  205. EmAssert(b->m_Texture != NULL, "all billboards must have a texture");
  206. glBindTexture(GL_TEXTURE_2D, *(b->m_Texture));
  207. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter);
  208. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter);
  209. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
  210. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
  211. glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
  212. // a textured polygon
  213. glColor3f(1, 1, 1);
  214. glBegin(GL_POLYGON);
  215. glTexCoord2f(0, 0);
  216. glVertex3f(b->m_vtxAlign.x - b->m_fSizexD2,
  217. b->m_vtxAlign.y + b->m_fSizeyD2,
  218. b->m_vtxAlign.z);
  219. glTexCoord2f(1, 0);
  220. glVertex3f(b->m_vtxAlign.x + b->m_fSizexD2,
  221. b->m_vtxAlign.y + b->m_fSizeyD2,
  222. b->m_vtxAlign.z);
  223. glTexCoord2f(1, 1);
  224. glVertex3f(b->m_vtxAlign.x + b->m_fSizexD2,
  225. b->m_vtxAlign.y - b->m_fSizeyD2,
  226. b->m_vtxAlign.z);
  227. glTexCoord2f(0, 1);
  228. glVertex3f(b->m_vtxAlign.x - b->m_fSizexD2,
  229. b->m_vtxAlign.y - b->m_fSizeyD2,
  230. b->m_vtxAlign.z);
  231. glEnd();
  232. EM_COUT_D("OpenGLVisitor::visit() BillBoard at " << b->m_vtxAlign.x <<" "<<
  233. b->m_vtxAlign.y <<" "<< b->m_vtxAlign.z, 0);
  234. }
  235. } break;
  236. case EM_GL_GCOL_TEX_TRANS: {
  237. vector<Shape3D*>::iterator shapeIter = g->m_vShape3D.begin();
  238. vector<Shape3D*>::iterator shapeEnd = g->m_vShape3D.end();
  239. for ( ; shapeIter != shapeEnd; shapeIter++) {
  240. if (EM_SHAPE3D_HIDDEN & (*shapeIter)->m_iProperties) continue;
  241. if (!(EM_SHAPE3D_USE_TRANS & (*shapeIter)->m_iProperties)) continue;
  242. #if 0 // I used wireframes when showing some demos in school
  243. {
  244. // wireframe
  245. glEnable(GL_POLYGON_OFFSET_FILL);
  246. glPolygonOffset(1.0, -1.0);
  247. vector<Polygon3D*>::iterator polyIter = (*shapeIter)->m_vPolygon.begin();
  248. vector<Polygon3D*>::iterator polyEnd = (*shapeIter)->m_vPolygon.end();
  249. for ( ; polyIter != polyEnd; ++polyIter) {
  250. ++m_iPoly;
  251. glColor3f(0.0f, 0.0f, 0.0f);
  252. vector<int>::iterator indexIter = (*polyIter)->m_vIndex.begin();
  253. vector<int>::iterator indexEnd = (*polyIter)->m_vIndex.end();
  254. glBegin(GL_LINE_LOOP);
  255. for ( ; indexIter != indexEnd; ++indexIter) {
  256. glVertex3f((*shapeIter)->m_vVtxAlign[(*indexIter)].x,
  257. (*shapeIter)->m_vVtxAlign[(*indexIter)].y,
  258. (*shapeIter)->m_vVtxAlign[(*indexIter)].z);
  259. }
  260. glEnd();
  261. }
  262. glDisable(GL_POLYGON_OFFSET_FILL);
  263. }
  264. #endif
  265. if ((*shapeIter)->m_iProperties & EM_SHAPE3D_BEHIND) {
  266. glEnable(GL_POLYGON_OFFSET_FILL);
  267. glPolygonOffset(1.0, 1.0);
  268. } else if ((*shapeIter)->m_iProperties & EM_SHAPE3D_BEHIND2) {
  269. glEnable(GL_POLYGON_OFFSET_FILL);
  270. glPolygonOffset(1.0, 2.0);
  271. } else {
  272. glDisable(GL_POLYGON_OFFSET_FILL);
  273. }
  274. if ((*shapeIter)->m_Texture != NULL && filter != -1) { // textured polygon
  275. glEnable(GL_TEXTURE_2D);
  276. glBindTexture(GL_TEXTURE_2D, *((*shapeIter)->m_Texture));
  277. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter);
  278. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter);
  279. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
  280. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
  281. glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
  282. if ((*shapeIter)->m_iProperties & EM_SHAPE3D_ALWAYSLIT) { // EM_SHAPE3D_ALWAYSLIT
  283. vector<Polygon3D*>::iterator polyIter = (*shapeIter)->m_vPolygon.begin();
  284. vector<Polygon3D*>::iterator polyEnd = (*shapeIter)->m_vPolygon.end();
  285. for ( ; polyIter != polyEnd; polyIter++) {
  286. if (!((*polyIter)->m_iProperties & EM_POLY_TRANS)) continue;
  287. #if EM_DEBUG
  288. ++m_iPoly;
  289. #endif
  290. // textured polygon
  291. vector<int>::iterator indexIter = (*polyIter)->m_vIndex.begin();
  292. vector<int>::iterator indexEnd = (*polyIter)->m_vIndex.end();
  293. glBegin(GL_POLYGON);
  294. for ( ; indexIter != indexEnd; indexIter++) {
  295. glTexCoord2f((*shapeIter)->m_vTexCoord[(*indexIter)].u,
  296. (*shapeIter)->m_vTexCoord[(*indexIter)].v);
  297. glColor4f((*shapeIter)->m_vColor[(*indexIter)].r,
  298. (*shapeIter)->m_vColor[(*indexIter)].g,
  299. (*shapeIter)->m_vColor[(*indexIter)].b,
  300. (*shapeIter)->m_vColor[(*indexIter)].a);
  301. glVertex3f((*shapeIter)->m_vVtxAlign[(*indexIter)].x,
  302. (*shapeIter)->m_vVtxAlign[(*indexIter)].y,
  303. (*shapeIter)->m_vVtxAlign[(*indexIter)].z);
  304. }
  305. glEnd();
  306. }
  307. } else { // ! EM_SHAPE3D_ALWAYSLIT
  308. vector<Polygon3D*>::iterator polyIter = (*shapeIter)->m_vPolygon.begin();
  309. vector<Polygon3D*>::iterator polyEnd = (*shapeIter)->m_vPolygon.end();
  310. for ( ; polyIter != polyEnd; polyIter++) {
  311. if (!((*polyIter)->m_iProperties & EM_POLY_TRANS)) continue;
  312. #if EM_DEBUG
  313. ++m_iPoly;
  314. #endif
  315. // textured polygon
  316. vector<int>::iterator indexIter = (*polyIter)->m_vIndex.begin();
  317. vector<int>::iterator indexEnd = (*polyIter)->m_vIndex.end();
  318. glBegin(GL_POLYGON);
  319. for ( ; indexIter != indexEnd; indexIter++) {
  320. glTexCoord2f((*shapeIter)->m_vTexCoord[(*indexIter)].u,
  321. (*shapeIter)->m_vTexCoord[(*indexIter)].v);
  322. glColor4f((*shapeIter)->m_vLight[(*indexIter)].r,
  323. (*shapeIter)->m_vLight[(*indexIter)].g,
  324. (*shapeIter)->m_vLight[(*indexIter)].b,
  325. (*shapeIter)->m_vLight[(*indexIter)].a);
  326. glVertex3f((*shapeIter)->m_vVtxAlign[(*indexIter)].x,
  327. (*shapeIter)->m_vVtxAlign[(*indexIter)].y,
  328. (*shapeIter)->m_vVtxAlign[(*indexIter)].z);
  329. }
  330. glEnd();
  331. }
  332. }
  333. } else { // color polygon
  334. glDisable(GL_TEXTURE_2D);
  335. if ((*shapeIter)->m_iProperties & EM_SHAPE3D_ALWAYSLIT) {
  336. vector<Polygon3D*>::iterator polyIter = (*shapeIter)->m_vPolygon.begin();
  337. vector<Polygon3D*>::iterator polyEnd = (*shapeIter)->m_vPolygon.end();
  338. for ( ; polyIter != polyEnd; polyIter++) {
  339. if (!((*polyIter)->m_iProperties & EM_POLY_TRANS)) continue;
  340. #if EM_DEBUG
  341. ++m_iPoly;
  342. #endif
  343. vector<int>::iterator indexIter = (*polyIter)->m_vIndex.begin();
  344. vector<int>::iterator indexEnd = (*polyIter)->m_vIndex.end();
  345. glBegin(GL_POLYGON);
  346. for ( ; indexIter != indexEnd; indexIter++) {
  347. // transparent polygons should not be lit, or ?
  348. glColor4f((*shapeIter)->m_vColor[(*indexIter)].r,
  349. (*shapeIter)->m_vColor[(*indexIter)].g,
  350. (*shapeIter)->m_vColor[(*indexIter)].b,
  351. (*shapeIter)->m_vColor[(*indexIter)].a);
  352. glVertex3f((*shapeIter)->m_vVtxAlign[(*indexIter)].x,
  353. (*shapeIter)->m_vVtxAlign[(*indexIter)].y,
  354. (*shapeIter)->m_vVtxAlign[(*indexIter)].z);
  355. }
  356. glEnd();
  357. }
  358. } else { // EM_SHAPE3D_ALWAYSLIT
  359. vector<Polygon3D*>::iterator polyIter = (*shapeIter)->m_vPolygon.begin();
  360. vector<Polygon3D*>::iterator polyEnd = (*shapeIter)->m_vPolygon.end();
  361. for ( ; polyIter != polyEnd; polyIter++) {
  362. if (!((*polyIter)->m_iProperties & EM_POLY_TRANS)) continue;
  363. #if EM_DEBUG
  364. ++m_iPoly;
  365. #endif
  366. vector<int>::iterator indexIter = (*polyIter)->m_vIndex.begin();
  367. vector<int>::iterator indexEnd = (*polyIter)->m_vIndex.end();
  368. glBegin(GL_POLYGON);
  369. for ( ; indexIter != indexEnd; indexIter++) {
  370. // transparent polygons should not be lit, or ?
  371. glColor4f((*shapeIter)->m_vLitColor[(*indexIter)].r,
  372. (*shapeIter)->m_vLitColor[(*indexIter)].g,
  373. (*shapeIter)->m_vLitColor[(*indexIter)].b,
  374. (*shapeIter)->m_vLitColor[(*indexIter)].a);
  375. glVertex3f((*shapeIter)->m_vVtxAlign[(*indexIter)].x,
  376. (*shapeIter)->m_vVtxAlign[(*indexIter)].y,
  377. (*shapeIter)->m_vVtxAlign[(*indexIter)].z);
  378. }
  379. glEnd();
  380. }
  381. }
  382. }
  383. }
  384. // billboard
  385. BillBoard * b = g->p_BillBoard;
  386. if (b != NULL && b->m_iProperties & EM_BILLBOARD_TRANS) {
  387. EmAssert(b->m_Texture != NULL, "all billboards must have a texture");
  388. glBindTexture(GL_TEXTURE_2D, *(b->m_Texture));
  389. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter);
  390. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter);
  391. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
  392. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
  393. glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
  394. // a textured polygon
  395. glColor3f(1, 1, 1);
  396. glBegin(GL_POLYGON);
  397. glTexCoord2f(0, 0);
  398. glVertex3f(b->m_vtxAlign.x - b->m_fSizexD2,
  399. b->m_vtxAlign.y + b->m_fSizeyD2,
  400. b->m_vtxAlign.z);
  401. glTexCoord2f(1, 0);
  402. glVertex3f(b->m_vtxAlign.x + b->m_fSizexD2,
  403. b->m_vtxAlign.y + b->m_fSizeyD2,
  404. b->m_vtxAlign.z);
  405. glTexCoord2f(1, 1);
  406. glVertex3f(b->m_vtxAlign.x + b->m_fSizexD2,
  407. b->m_vtxAlign.y - b->m_fSizeyD2,
  408. b->m_vtxAlign.z);
  409. glTexCoord2f(0, 1);
  410. glVertex3f(b->m_vtxAlign.x - b->m_fSizexD2,
  411. b->m_vtxAlign.y - b->m_fSizeyD2,
  412. b->m_vtxAlign.z);
  413. glEnd();
  414. EM_COUT_D("OpenGLVisitor::visit() BillBoard at " << b->m_vtxAlign.x <<" "<<
  415. b->m_vtxAlign.y <<" "<< b->m_vtxAlign.z, 0);
  416. }
  417. } break;
  418. }
  419. #endif // EM_USE_SDL
  420. }