Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

360 lines
8.5 KiB

  1. /**
  2. ** File : glmesh.cxx
  3. ** Description: Implementations of CGlMesh class
  4. **/
  5. #include "precomp.h"
  6. #pragma hdrstop
  7. #include "glmesh.h"
  8. #include "pmerrors.h"
  9. /**************************************************************************/
  10. /*
  11. * CGlMesh: Constructor
  12. */
  13. CGlMesh::CGlMesh()
  14. {
  15. //Dynamically allocated arrays
  16. m_matArray = NULL;
  17. m_varray = NULL;
  18. m_narray = NULL;
  19. m_tarray = NULL;
  20. m_wedgelist = NULL;
  21. m_fnei = NULL;
  22. m_facemap = NULL;
  23. m_numFaces =
  24. m_numWedges =
  25. m_numVerts =
  26. m_numMaterials =
  27. m_numTextures = 0;
  28. }
  29. /*
  30. * CGlMesh: Destructor
  31. */
  32. CGlMesh::~CGlMesh()
  33. {
  34. delete [] m_matArray;
  35. delete [] m_varray;
  36. delete [] m_narray;
  37. delete [] m_tarray;
  38. delete [] m_wedgelist;
  39. delete [] m_fnei;
  40. delete [] m_facemap;
  41. }
  42. /*
  43. * CGlMesh: Print
  44. */
  45. STDMETHODIMP CGlMesh::Print(ostream& os)
  46. {
  47. os << "\n\nMaterials:";
  48. for (int i=0; i<m_numMaterials; ++i)
  49. {
  50. LPGLmaterial lpglm = &m_matArray[i];
  51. os << "\n\nMaterial [" << i << "] :";
  52. os << "\nShininess : " << lpglm->shininess;
  53. os << "\nDiffuse : (" << lpglm->diffuse.r << ", "
  54. << lpglm->diffuse.g << ", "
  55. << lpglm->diffuse.b << ", "
  56. << lpglm->diffuse.a << ")";
  57. os << "\nSpecular : (" << lpglm->specular.r << ", "
  58. << lpglm->specular.g << ", "
  59. << lpglm->specular.b << ", "
  60. << lpglm->specular.a << ")";
  61. os << "\nEmissive : (" << lpglm->emissive.r << ", "
  62. << lpglm->emissive.g << ", "
  63. << lpglm->emissive.b << ", "
  64. << lpglm->emissive.a << ")";
  65. os << "\nNumber of faces: " << m_matcnt[i];
  66. for (int j=0; j< m_matcnt[i]; j++)
  67. {
  68. #ifdef __MATPOS_IS_A_PTR
  69. os << "\n(" << m_matpos[i][j].w[0] << ","
  70. << (m_matpos[i][j]).w[1] << ","
  71. << (m_matpos[i][j]).w[2] << ")";
  72. #else
  73. os << "\n(" << (m_farray[m_matpos[i] + j]).w[0] << ","
  74. << (m_farray[m_matpos[i] + j]).w[0] << ","
  75. << (m_farray[m_matpos[i] + j]).w[0] << ")";
  76. #endif
  77. }
  78. }
  79. os << "\n\nWedge connectivity:";
  80. for (i=0; i<m_numWedges; ++i)
  81. {
  82. os << "\n" << m_wedgelist[i];
  83. }
  84. os << "\n\nWedge data:";
  85. for (i=0; i<m_numWedges; ++i)
  86. {
  87. os << "\n(" << m_varray[i].x << ", "
  88. << m_varray[i].y << ", "
  89. << m_varray[i].z << ") "
  90. << " (" << m_narray[i].x << ", "
  91. << m_narray[i].y << ", "
  92. << m_narray[i].z << ") "
  93. << " (" << m_tarray[i].s << ", "
  94. << m_tarray[i].t << ") ";
  95. }
  96. return S_OK;
  97. }
  98. /*
  99. * CGlMesh: Render
  100. */
  101. STDMETHODIMP CGlMesh::Render(RenderType rt)
  102. {
  103. if (rt == GLPM_SOLID)
  104. {
  105. glVertexPointer(3, GL_FLOAT, 0, (void *)&(m_varray[0].x));
  106. glNormalPointer (GL_FLOAT, 0, (void *)&(m_narray[0].x));
  107. glTexCoordPointer (2, GL_FLOAT, 0, (void *)&(m_tarray[0].s));
  108. glEnableClientState (GL_VERTEX_ARRAY);
  109. glEnableClientState (GL_NORMAL_ARRAY);
  110. for (int i=0; i<m_numMaterials; i++)
  111. {
  112. LPGLmaterial lpglm = &(m_matArray[i]);
  113. if (m_matcnt[i] == (WORD) 0) continue;
  114. glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, lpglm->shininess);
  115. glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR,
  116. (GLfloat *) &(lpglm->specular));
  117. glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE,
  118. (GLfloat *) &(lpglm->diffuse));
  119. glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION,
  120. (GLfloat *) &(lpglm->emissive));
  121. glDrawElements (GL_TRIANGLES, (GLuint) m_matcnt[i]*3,
  122. GL_UNSIGNED_SHORT,
  123. #ifdef __MATPOS_IS_A_PTR
  124. (void *) m_matpos[i]);
  125. #else
  126. (void *) &(m_farray[m_matpos[i]]));
  127. #endif
  128. }
  129. return S_OK;
  130. }
  131. else
  132. {
  133. return E_NOTIMPL;
  134. }
  135. }
  136. PHASHENTRY* hashtable;
  137. PHASHENTRY hashentries;
  138. int freeptr, maxptr;
  139. void CGlMesh::HashAdd(WORD va, WORD vb, WORD f)
  140. {
  141. #ifdef _DEBUG
  142. if (va > m_numWedges || va < 0)
  143. throw CHashOvrflw();
  144. #endif
  145. for (PHASHENTRY* t = &(hashtable[va]); *t; t = &((*t)->next));
  146. PHASHENTRY p = &(hashentries[freeptr++]);
  147. p->f = f;
  148. p->v2 = vb;
  149. p->next = NULL;
  150. *t=p;
  151. }
  152. WORD CGlMesh::HashFind(WORD va, WORD vb)
  153. {
  154. #ifdef _DEBUG
  155. if (va > m_baseWedges || va < 0)
  156. throw CHashOvrflw();
  157. #endif
  158. for (PHASHENTRY* t = &(hashtable[va]); *t; t = &((*t)->next))
  159. {
  160. if ((*t)->v2 == vb)
  161. {
  162. return (*t)->f;
  163. }
  164. }
  165. return USHRT_MAX;
  166. }
  167. void CGlMesh::ComputeAdjacency(void)
  168. {
  169. freeptr = 0;
  170. maxptr = m_numFaces*3;
  171. hashtable = new PHASHENTRY[m_numWedges];
  172. // An entry for each 3 edges of each face in base mesh
  173. hashentries = new hashentry[maxptr];
  174. if (!hashtable)
  175. throw CExNewFailed();
  176. memset(hashtable, 0, sizeof(PHASHENTRY)*m_numWedges);
  177. /*
  178. * For each group of faces
  179. */
  180. for(int i=0; i<m_numMaterials; ++i)
  181. {
  182. /*
  183. * For each face in the group
  184. */
  185. #ifdef __MATPOS_IS_A_PTR
  186. for (int k=0; k<m_matcnt[i]; ++k)
  187. {
  188. int v1 = FindVertexIndex((m_matpos[i][k]).w[0]);
  189. int v2 = FindVertexIndex((m_matpos[i][k]).w[1]);
  190. int v3 = FindVertexIndex((m_matpos[i][k]).w[2]);
  191. int fi = GetFaceIndex(i,k);
  192. HashAdd(v1,v2,fi);
  193. HashAdd(v2,v3,fi);
  194. HashAdd(v3,v1,fi);
  195. }
  196. #else
  197. for (int k=m_matpos[i]; k<(m_matpos[i]+m_matcnt[i]); ++k)
  198. {
  199. int v1 = FindVertexIndex((m_farray[k]).w[0]);
  200. int v2 = FindVertexIndex((m_farray[k]).w[1]);
  201. int v3 = FindVertexIndex((m_farray[k]).w[2]);
  202. HashAdd(v1,v2,k);
  203. HashAdd(v2,v3,k);
  204. HashAdd(v3,v1,k);
  205. }
  206. #endif
  207. }
  208. #ifdef _DEBUG
  209. if (freeptr > maxptr)
  210. throw CHashOvrflw();
  211. #endif
  212. /*
  213. * For each group of faces
  214. */
  215. for(i=0; i<m_numMaterials; ++i)
  216. {
  217. /*
  218. * For each face in the group
  219. */
  220. #ifdef __MATPOS_IS_A_PTR
  221. for (int k=0; k<m_matcnt[i]; ++k)
  222. {
  223. int v1 = FindVertexIndex((m_matpos[i][k]).w[0]);
  224. int v2 = FindVertexIndex((m_matpos[i][k]).w[1]);
  225. int v3 = FindVertexIndex((m_matpos[i][k]).w[2]);
  226. int fi = GetFaceIndex(i,k);
  227. m_fnei[fi][0] = HashFind(v3,v2);
  228. m_fnei[fi][1] = HashFind(v1,v3);
  229. m_fnei[fi][2] = HashFind(v2,v1);
  230. }
  231. #else
  232. for (int k=m_matpos[i]; k<(m_matpos[i]+m_matcnt[i]); ++k)
  233. {
  234. int v1 = FindVertexIndex((m_farray[k]).w[0]);
  235. int v2 = FindVertexIndex((m_farray[k]).w[1]);
  236. int v3 = FindVertexIndex((m_farray[k]).w[2]);
  237. m_fnei[k][0] = HashFind(v3,v2);
  238. m_fnei[k][1] = HashFind(v1,v3);
  239. m_fnei[k][2] = HashFind(v2,v1);
  240. }
  241. #endif
  242. }
  243. delete [] hashtable;
  244. delete [] hashentries;
  245. }
  246. #if 0
  247. STDMETHODIMP AddWedge (WORD vertex_id, GLnormal& n,
  248. GLtexCoord& t, DWORD* const wedge_id)
  249. {
  250. WORD w;
  251. w = m_numWedges++;
  252. m_wedgelist[w] = m_wedgelist[vertex_id];
  253. m_wedgelist[vertex_id] = w;
  254. m_varray[w] = m_varray[vertex_id];
  255. m_narray[w] = n;
  256. m_tarray[w] = t;
  257. *wedge_id = w;
  258. return S_OK;
  259. }
  260. STDMETHODIMP AddWedge (Glvertex &v, GLnormal& n, GLtexCoord& t,
  261. DWORD* const wedge_id)
  262. {
  263. WORD w;
  264. w = m_numWedges++;
  265. m_wedgelist[w] = w;
  266. m_varray[w] = v;
  267. m_narray[w] = n;
  268. m_tarray[w] = t;
  269. *wedge_id = w;
  270. return S_OK;
  271. }
  272. STDMETHODIMP AddWedge (Glvertex &v)
  273. {
  274. WORD w;
  275. w = m_numWedges++;
  276. m_wedgelist[w] = w;
  277. m_varray[w] = v;
  278. //m_narray[w] = n;
  279. //m_tarray[w] = t;
  280. *wedge_id = w;
  281. return S_OK;
  282. }
  283. STDMETHODIMP AddWedge (WORD vertex_id, WORD old_wedge_id,
  284. DWORD* const wedge_id)
  285. {
  286. WORD w;
  287. w = m_numWedges++;
  288. /*
  289. * Add wnl to the list of wedges sharing vertex_id
  290. */
  291. m_wedgelist[w] = m_wedgelist[vertex_id];
  292. m_wedgelist[vertex_id] = w;
  293. /*
  294. * Copy wedge attributes
  295. */
  296. m_varray[w] = m_varray[vertex_id];
  297. m_narray[w] = m_narray[old_wedge_id];
  298. m_tarray[w] = m_tarray[old_wedge_id];
  299. *wedge_id = w;
  300. return S_OK;
  301. }
  302. STDMETHODIMP AddFace (WORD matid, GLface& f)
  303. {
  304. return S_OK;
  305. }
  306. #endif