AllegroVisitor.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295
  1. /***************************************************************************
  2. AllegroVisitor.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 "AllegroVisitor.h"
  10. #include "Group.h"
  11. #include "Shape3D.h"
  12. #include "Polygon.h"
  13. #include "BillBoard.h"
  14. #include "Config.h"
  15. AllegroVisitor * AllegroVisitor::p_AllegroVisitor = NULL;
  16. AllegroVisitor::AllegroVisitor(){
  17. #if EM_USE_ALLEGRO
  18. //
  19. for (int a=0; a<256; a++) {
  20. alleg_vtx_p[a] = &alleg_vtx[a];
  21. alleg_clip_p[a] = &alleg_clip[a];
  22. alleg_tmp_p[a] = &alleg_tmp[a];
  23. }
  24. m_iMode = EM_ALLEGRO_GCOL_TEX;
  25. #endif // EM_USE_ALLEGRO
  26. }
  27. AllegroVisitor::~AllegroVisitor() {
  28. p_AllegroVisitor = NULL;
  29. }
  30. AllegroVisitor * AllegroVisitor::getInstance() {
  31. if (p_AllegroVisitor == NULL) {
  32. p_AllegroVisitor = new AllegroVisitor();
  33. }
  34. return p_AllegroVisitor;
  35. }
  36. void AllegroVisitor::empty() {
  37. #if EM_USE_ALLEGRO
  38. switch (m_iMode) {
  39. case EM_ALLEGRO_GCOL_TEX: {
  40. drawing_mode(DRAW_MODE_SOLID, NULL, 0, 0);
  41. } break;
  42. case EM_ALLEGRO_GCOL_TEX_TRANS: {
  43. drawing_mode(DRAW_MODE_SOLID, NULL, 0, 0);
  44. } break;
  45. case EM_ALLEGRO_CLEAN: {
  46. } break;
  47. }
  48. #endif // EM_USE_ALLEGRO
  49. }
  50. #if EM_USE_ALLEGRO
  51. void AllegroVisitor::visit(Group * g) {
  52. int filter = Config::getInstance()->getGLFilter();
  53. switch (m_iMode) {
  54. case EM_ALLEGRO_GCOL_TEX: {
  55. // shapes
  56. vector<Shape3D*>::iterator shapeIter = g->m_vShape3D.begin();
  57. vector<Shape3D*>::iterator shapeEnd = g->m_vShape3D.end();
  58. for ( ; shapeIter != shapeEnd; ++shapeIter) {
  59. if (EM_SHAPE3D_HIDDEN & (*shapeIter)->m_iProperties) continue;
  60. vector<Polygon3D*>::iterator polyIter = (*shapeIter)->m_vPolygon.begin();
  61. vector<Polygon3D*>::iterator polyEnd = (*shapeIter)->m_vPolygon.end();
  62. for ( ; polyIter != polyEnd; polyIter++) {
  63. // if ((*polyIter)->m_iProperties & EM_POLY_HIDDEN) continue;
  64. if ((*polyIter)->m_iProperties & EM_POLY_TRANS) continue;
  65. vector<int>::iterator indexIter = (*polyIter)->m_vIndex.begin();
  66. vector<int>::iterator indexEnd = (*polyIter)->m_vIndex.end();
  67. // 3.4 %
  68. int index=0;
  69. // TODO implement a fast float to int conversion and fast clamp;
  70. // see section 2.1 i Game Prog Gems 2
  71. if ((*shapeIter)->m_Texture == NULL || filter == -1) {
  72. // color polygon
  73. for (; indexIter != indexEnd; ++indexIter, ++index) {
  74. #if 0
  75. alleg_vtx[index].x = (*shapeIter)->m_vVtxAlign[(*indexIter)].x;
  76. alleg_vtx[index].y = (*shapeIter)->m_vVtxAlign[(*indexIter)].y;
  77. alleg_vtx[index].z = (*shapeIter)->m_vVtxAlign[(*indexIter)].z;
  78. alleg_vtx[index].u = 0;
  79. alleg_vtx[index].v = 0;
  80. alleg_vtx[index].c = 0xFFFFFF;
  81. #else
  82. // TODO Fix this slow copying !!!
  83. alleg_vtx[index].x = (*shapeIter)->m_vVtxAlign[(*indexIter)].x;
  84. alleg_vtx[index].y = (*shapeIter)->m_vVtxAlign[(*indexIter)].y;
  85. alleg_vtx[index].z = (*shapeIter)->m_vVtxAlign[(*indexIter)].z;
  86. float r = (*shapeIter)->m_vLitColor[(*indexIter)].r*255.0f;
  87. float g = (*shapeIter)->m_vLitColor[(*indexIter)].g*255.0f;
  88. float b = (*shapeIter)->m_vLitColor[(*indexIter)].b*255.0f;
  89. int ir = (int)r;
  90. int ig = (int)g;
  91. int ib = (int)b;
  92. alleg_vtx[index].c = makecol(EM_MIN(ir,255), EM_MIN(ig,255), EM_MIN(ib,255));
  93. #endif
  94. }
  95. } else {
  96. // textured polygon
  97. for (; indexIter != indexEnd; ++indexIter, ++index) {
  98. // TODO Fix this slow copying !!!
  99. alleg_vtx[index].x = (*shapeIter)->m_vVtxAlign[(*indexIter)].x;
  100. alleg_vtx[index].y = (*shapeIter)->m_vVtxAlign[(*indexIter)].y;
  101. alleg_vtx[index].z = (*shapeIter)->m_vVtxAlign[(*indexIter)].z;
  102. // TODO Not all textures are 256
  103. alleg_vtx[index].u = (int)((*shapeIter)->m_vTexCoord[(*indexIter)].u*255.0f);
  104. alleg_vtx[index].v = (int)((*shapeIter)->m_vTexCoord[(*indexIter)].v*255.0f);
  105. float r = (*shapeIter)->m_vLitColor[(*indexIter)].r*255.0f;
  106. float g = (*shapeIter)->m_vLitColor[(*indexIter)].g*255.0f;
  107. float b = (*shapeIter)->m_vLitColor[(*indexIter)].b*255.0f;
  108. int ir = (int)r;
  109. int ig = (int)g;
  110. int ib = (int)b;
  111. ib = EM_MAX(ir, EM_MAX(ig, ib));
  112. alleg_vtx[index].c = EM_MIN(ib, 255);
  113. }
  114. }
  115. // 52.9 %
  116. if (index < 3) continue;
  117. EmAssert(index < 128, "AllegorVisitor::visit polygonedge amout to large");
  118. // clip
  119. int size = 0;
  120. if ((*shapeIter)->m_Texture == NULL || filter == -1) {
  121. size = clip3d_f(POLYTYPE_GCOL, 0.1, 1000, index,
  122. (AL_CONST V3D_f**)alleg_vtx_p,alleg_clip_p, alleg_tmp_p, int_tmp);
  123. } else {
  124. size = clip3d_f(POLYTYPE_ATEX, 0.1, 1000, index, (AL_CONST V3D_f**)alleg_vtx_p,
  125. alleg_clip_p, alleg_tmp_p, int_tmp);
  126. }
  127. if (size < 3) continue;
  128. // project, if clause moved outside for loop for perfomance
  129. // most likely scenario first
  130. if (!((*shapeIter)->m_iProperties & (EM_SHAPE3D_BEHIND + EM_SHAPE3D_BEHIND2))) {
  131. for (int a=0; a<size; ++a) {
  132. persp_project_f(alleg_clip[a].x, alleg_clip[a].y, alleg_clip[a].z,
  133. &alleg_clip[a].x, &alleg_clip[a].y);
  134. }
  135. } else if ((*shapeIter)->m_iProperties & EM_SHAPE3D_BEHIND) {
  136. for (int a=0; a<size; ++a) {
  137. persp_project_f(alleg_clip[a].x, alleg_clip[a].y, alleg_clip[a].z,
  138. &alleg_clip[a].x, &alleg_clip[a].y);
  139. alleg_clip[a].z += 0.1f;
  140. }
  141. } else if ((*shapeIter)->m_iProperties & EM_SHAPE3D_BEHIND2) {
  142. for (int a=0; a<size; ++a) {
  143. persp_project_f(alleg_clip[a].x, alleg_clip[a].y, alleg_clip[a].z,
  144. &alleg_clip[a].x, &alleg_clip[a].y);
  145. alleg_clip[a].z += 0.2f;
  146. }
  147. }
  148. // cull
  149. if (polygon_z_normal_f(alleg_clip_p[0], alleg_clip_p[1], alleg_clip_p[2]) < 0) continue;
  150. //53.5 %
  151. // render
  152. if ((*shapeIter)->m_Texture == NULL || filter == -1) {
  153. polygon3d_f(backbuffer, POLYTYPE_GCOL | POLYTYPE_ZBUF, NULL, size, alleg_clip_p);
  154. } else {
  155. polygon3d_f(backbuffer, POLYTYPE_ATEX_LIT | POLYTYPE_ZBUF, (*shapeIter)->m_Texture,
  156. size, alleg_clip_p);
  157. }
  158. // 72 % (79%)
  159. }
  160. }
  161. // billboard TODO
  162. BillBoard * b = g->p_BillBoard;
  163. if (b != NULL && b->m_iProperties & EM_BILLBOARD_TRANS) {
  164. EmAssert(b->m_Texture != NULL, "all billboards must have a texture");
  165. EM_COUT_D("AllegroVisitor::visit() BillBoard at " << b->m_vtxAlign.x <<" "<<
  166. b->m_vtxAlign.y <<" "<< b->m_vtxAlign.z, 0);
  167. }
  168. } break;
  169. case EM_ALLEGRO_GCOL_TEX_TRANS: {
  170. // shapes
  171. vector<Shape3D*>::iterator shapeIter = g->m_vShape3D.begin();
  172. vector<Shape3D*>::iterator shapeEnd = g->m_vShape3D.end();
  173. for ( ; shapeIter != shapeEnd; ++shapeIter) {
  174. if (EM_SHAPE3D_HIDDEN & (*shapeIter)->m_iProperties) continue;
  175. if (!(EM_SHAPE3D_USE_TRANS & (*shapeIter)->m_iProperties)) continue;
  176. vector<Polygon3D*>::iterator polyIter = (*shapeIter)->m_vPolygon.begin();
  177. vector<Polygon3D*>::iterator polyEnd = (*shapeIter)->m_vPolygon.end();
  178. for ( ; polyIter != polyEnd; ++polyIter) {
  179. // if ((*polyIter)->m_iProperties & EM_POLY_HIDDEN) continue;
  180. if (!((*polyIter)->m_iProperties & EM_POLY_TRANS)) continue;
  181. vector<int>::iterator indexIter = (*polyIter)->m_vIndex.begin();
  182. vector<int>::iterator indexEnd = (*polyIter)->m_vIndex.end();
  183. int index=0;
  184. if ((*shapeIter)->m_Texture == NULL || filter == -1) {
  185. // color polygon
  186. for (; indexIter != indexEnd; ++indexIter, ++index) {
  187. // TODO Fix this slow copying !!!
  188. alleg_vtx[index].x = (*shapeIter)->m_vVtxAlign[(*indexIter)].x;
  189. alleg_vtx[index].y = (*shapeIter)->m_vVtxAlign[(*indexIter)].y;
  190. alleg_vtx[index].z = (*shapeIter)->m_vVtxAlign[(*indexIter)].z;
  191. // TODO implement a fast float to int conversion and fast clamp;
  192. // see section 2.1 i Game Prog Gems 2
  193. float r = (*shapeIter)->m_vLitColor[(*indexIter)].r*255.0f;
  194. float g = (*shapeIter)->m_vLitColor[(*indexIter)].g*255.0f;
  195. float b = (*shapeIter)->m_vLitColor[(*indexIter)].b*255.0f;
  196. int ir = (int)r;
  197. int ig = (int)g;
  198. int ib = (int)b;
  199. alleg_vtx[index].c = makecol(EM_MIN(ir,255), EM_MIN(ig,255), EM_MIN(ib,255));
  200. }
  201. } else {
  202. // textured polygon
  203. for (; indexIter != indexEnd; ++indexIter, ++index) {
  204. // TODO Fix this slow copying !!!
  205. alleg_vtx[index].x = (*shapeIter)->m_vVtxAlign[(*indexIter)].x;
  206. alleg_vtx[index].y = (*shapeIter)->m_vVtxAlign[(*indexIter)].y;
  207. alleg_vtx[index].z = (*shapeIter)->m_vVtxAlign[(*indexIter)].z;
  208. // TODO Not all textures are 255
  209. alleg_vtx[index].u = (int)((*shapeIter)->m_vTexCoord[(*indexIter)].u*255.0f);
  210. alleg_vtx[index].v = (int)((*shapeIter)->m_vTexCoord[(*indexIter)].v*255.0f);
  211. // TODO implement a fast float to int conversion and fast clamp;
  212. // see section 2.1 i Game Prog Gems 2
  213. float r = (*shapeIter)->m_vLitColor[(*indexIter)].r*255.0f;
  214. float g = (*shapeIter)->m_vLitColor[(*indexIter)].g*255.0f;
  215. float b = (*shapeIter)->m_vLitColor[(*indexIter)].b*255.0f;
  216. int ir = (int)r;
  217. int ig = (int)g;
  218. int ib = (int)b;
  219. ib = EM_MAX(ir, EM_MAX(ig, ib));
  220. alleg_vtx[index].c = EM_MIN(ib,255) ;
  221. }
  222. }
  223. if (index < 3) continue;
  224. EmAssert(index < 128, "AllegorVisitor::visit polygonedge amout to large");
  225. // clip
  226. int size = 0;
  227. if ((*shapeIter)->m_Texture == NULL || filter == -1) {
  228. size = clip3d_f(POLYTYPE_GCOL, 0.1, 1000, index,
  229. (AL_CONST V3D_f**)alleg_vtx_p,alleg_clip_p, alleg_tmp_p, int_tmp);
  230. } else {
  231. size = clip3d_f(POLYTYPE_ATEX, 0.1, 1000, index, (AL_CONST V3D_f**)alleg_vtx_p,
  232. alleg_clip_p, alleg_tmp_p, int_tmp);
  233. }
  234. if (size < 3) continue;
  235. // project, if clause moved outside for loop for perfomance
  236. if ((*shapeIter)->m_iProperties & EM_SHAPE3D_BEHIND) {
  237. for (int a=0; a<size; ++a) {
  238. persp_project_f(alleg_clip[a].x, alleg_clip[a].y, alleg_clip[a].z,
  239. &alleg_clip[a].x, &alleg_clip[a].y);
  240. alleg_clip[a].z += 0.1f;
  241. }
  242. } else if ((*shapeIter)->m_iProperties & EM_SHAPE3D_BEHIND2) {
  243. for (int a=0; a<size; ++a) {
  244. persp_project_f(alleg_clip[a].x, alleg_clip[a].y, alleg_clip[a].z,
  245. &alleg_clip[a].x, &alleg_clip[a].y);
  246. alleg_clip[a].z += 0.2f;
  247. }
  248. } else {
  249. for (int a=0; a<size; ++a) {
  250. persp_project_f(alleg_clip[a].x, alleg_clip[a].y, alleg_clip[a].z,
  251. &alleg_clip[a].x, &alleg_clip[a].y);
  252. }
  253. }
  254. // cull
  255. if (polygon_z_normal_f(alleg_clip_p[0], alleg_clip_p[1], alleg_clip_p[2]) < 0) continue;
  256. // render
  257. if ((*shapeIter)->m_Texture == NULL || filter == -1) {
  258. polygon3d_f(backbuffer, POLYTYPE_GCOL | POLYTYPE_ZBUF, NULL, size, alleg_clip_p);
  259. } else {
  260. polygon3d_f(backbuffer, POLYTYPE_ATEX_MASK_LIT | POLYTYPE_ZBUF,
  261. (*shapeIter)->m_Texture, size, alleg_clip_p);
  262. }
  263. }
  264. }
  265. // billboard TODO
  266. BillBoard * b = g->p_BillBoard;
  267. if (b != NULL && b->m_iProperties & EM_BILLBOARD_TRANS) {
  268. EmAssert(b->m_Texture != NULL, "all billboards must have a texture");
  269. EM_COUT_D("AllegroVisitor::visit() BillBoard at " << b->m_vtxAlign.x <<" "<<
  270. b->m_vtxAlign.y <<" "<< b->m_vtxAlign.z, 0);
  271. }
  272. } break;
  273. }
  274. }
  275. #else
  276. void AllegroVisitor::visit(Group *) {
  277. }
  278. #endif // EM_USE_ALLEGRO