SceneGraph3d.cpp
Upload User: hcfgz168
Upload Date: 2011-09-11
Package Size: 116k
Code Size: 11k
Category:

OpenGL program

Development Platform:

WINDOWS

  1. //********************************************
  2. // SceneGraph.cpp
  3. //********************************************
  4. // class CSceneGraph
  5. //********************************************
  6. // pierre.alliez@cnet.francetelecom.fr
  7. // Created : 15/01/98
  8. // Modified : 15/01/98
  9. //********************************************
  10. #include "stdafx.h"
  11. #include "Base3d.h"
  12. #include "SceneGraph3d.h"
  13. //////////////////////////////////////////////
  14. // CONSTRUCTORS
  15. //////////////////////////////////////////////
  16. //********************************************
  17. // Constructor
  18. //********************************************
  19. CSceneGraph3d::CSceneGraph3d()
  20. {
  21. m_pIndexTextureBinding = NULL;
  22. m_ListDone = 0;
  23. }
  24. //********************************************
  25. // Destructor
  26. //********************************************
  27. CSceneGraph3d::~CSceneGraph3d()
  28. {
  29. Free();
  30. }
  31. //********************************************
  32. // Destructor
  33. //********************************************
  34. void CSceneGraph3d::Free(void)
  35. {
  36. // Textures
  37. if(m_ArrayTexture.GetSize())
  38. {
  39. ::glDeleteTextures(m_ArrayTexture.GetSize(),m_pIndexTextureBinding);
  40. if(m_pIndexTextureBinding != NULL)
  41. {
  42. delete [] m_pIndexTextureBinding;
  43. m_pIndexTextureBinding = NULL;
  44. }
  45. }
  46. m_ArrayTexture.Free();
  47. // Objects
  48. m_ArrayObject3d.Free();
  49. }
  50. //////////////////////////////////////////////
  51. // DATAS
  52. //////////////////////////////////////////////
  53. //********************************************
  54. // Add
  55. //********************************************
  56. void CSceneGraph3d::Add(CObject3d *pObject3d)
  57. {
  58. m_ArrayObject3d.Add(pObject3d);
  59. }
  60. //********************************************
  61. // Add
  62. //********************************************
  63. void CSceneGraph3d::RemoveAt(int index)
  64. {
  65. m_ArrayObject3d.RemoveAt(index);
  66. }
  67. //********************************************
  68. // GetAt
  69. //********************************************
  70. CObject3d *CSceneGraph3d::GetAt(int index)
  71. {
  72. ASSERT(index < m_ArrayObject3d.GetSize());
  73. return m_ArrayObject3d[index];
  74. }
  75. //********************************************
  76. // Operator []
  77. //********************************************
  78. CObject3d *CSceneGraph3d::operator[](int index)
  79. {
  80. ASSERT(index < m_ArrayObject3d.GetSize());
  81. return m_ArrayObject3d[index];
  82. }
  83. //////////////////////////////////////////////
  84. // OPENGL
  85. //////////////////////////////////////////////
  86. //********************************************
  87. // BuildList
  88. //********************************************
  89. int CSceneGraph3d::glBuildList()
  90. {
  91. TRACE("Build list");
  92. // Meshes
  93. //***********************************
  94. unsigned int size = m_ArrayObject3d.GetSize();
  95. for(unsigned int i=0; i<size; i++)
  96. {
  97. CObject3d *pObject3d = m_ArrayObject3d.GetAt(i);
  98. if(pObject3d != NULL)
  99. {
  100. pObject3d->glBuildList();
  101. TRACE("."); // progressing (debug mode)
  102. }
  103. }
  104. TRACE("okn");
  105. // Textures
  106. //***********************************
  107. unsigned int NbTexture = m_ArrayTexture.GetSize();
  108. if(NbTexture)
  109. {
  110. TRACE("SceneGraph : texture binding...(%d texture(s))n",NbTexture);
  111. // Cleanup
  112. if(m_pIndexTextureBinding != NULL)
  113. {
  114. ::glDeleteTextures(NbTexture,m_pIndexTextureBinding);
  115. delete [] m_pIndexTextureBinding;
  116. }
  117. m_pIndexTextureBinding = new unsigned int[NbTexture];
  118. ::glGenTextures(NbTexture,m_pIndexTextureBinding);
  119. int error = glGetError();
  120. ASSERT(error !=  GL_INVALID_VALUE);
  121. ASSERT(error !=  GL_INVALID_OPERATION);
  122. TRACE("Bind texture...n");
  123. for(i=0;i<NbTexture;i++)
  124. {
  125. while (GL_NO_ERROR != glGetError() ) {}
  126. // Bind texture
  127. glBindTexture(GL_TEXTURE_2D,m_pIndexTextureBinding[i]);
  128.   glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
  129.   glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
  130.   glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  131.   glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  132.   glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
  133. int error = glGetError();
  134. ASSERT(error !=  GL_INVALID_ENUM);
  135. ASSERT(error !=  GL_INVALID_OPERATION);
  136. // Read datas
  137. CTexture *pTexture = m_ArrayTexture[i];
  138. ASSERT(pTexture->GetData() != NULL);
  139. ::glTexImage2D(GL_TEXTURE_2D,0,3,
  140.  pTexture->GetWidth(),pTexture->GetHeight(),0,
  141.  GL_RGB,GL_UNSIGNED_BYTE,pTexture->GetData());
  142. error = glGetError();
  143. ASSERT(error !=  GL_INVALID_ENUM);
  144. ASSERT(error !=  GL_INVALID_OPERATION);
  145. ASSERT(error !=  GL_INVALID_VALUE);
  146. }
  147. }
  148. m_ListDone = 1;
  149. return 1;
  150. }
  151. //********************************************
  152. // glDraw
  153. //********************************************
  154. void CSceneGraph3d::glDraw(void)
  155. {
  156. if(!m_ListDone)
  157. glBuildList();
  158. unsigned int size = m_ArrayObject3d.GetSize();
  159. for(unsigned int i=0; i<size; i++)
  160. {
  161. CObject3d *pObject3d = m_ArrayObject3d[i];
  162. // Texture
  163. if(pObject3d->GetType() == TYPE_MESH3D)
  164. {
  165. CMesh3d *pMesh = (CMesh3d *)pObject3d;
  166. int IndexTexture = pMesh->GetTextureIndex();
  167. if(IndexTexture >= 0)
  168. {
  169. ASSERT(glIsTexture(m_pIndexTextureBinding[IndexTexture]));
  170. glBindTexture(GL_TEXTURE_2D,m_pIndexTextureBinding[IndexTexture]);
  171. TRACE("Texture : %dn",m_pIndexTextureBinding[IndexTexture]);
  172. }
  173. // Drawing
  174. pObject3d->glDraw();
  175. }
  176. else
  177. pObject3d->glDraw();
  178. }
  179. }
  180. //********************************************
  181. // glDraw
  182. // draw only type
  183. //********************************************
  184. void CSceneGraph3d::glDraw(int type)
  185. {
  186. if(!m_ListDone)
  187. glBuildList();
  188. unsigned int size = m_ArrayObject3d.GetSize();
  189. for(unsigned int i=0; i<size; i++)
  190. {
  191. CObject3d *pObject3d = m_ArrayObject3d[i];
  192. if(pObject3d->GetType() == type)
  193. pObject3d->glDraw();
  194. }
  195. }
  196. //////////////////////////////////////////////
  197. // MISC
  198. //////////////////////////////////////////////
  199. //********************************************
  200. // BuildAdjacency
  201. // For each mesh
  202. //********************************************
  203. int CSceneGraph3d::BuildAdjacency()
  204. {
  205. int size = m_ArrayObject3d.GetSize();
  206. if(size ==0)
  207. return 0;
  208. TRACE("Scene %x : Start BuildAdjacency...n",this);
  209. TRACE("  NbObject : %dn",size);
  210. for(int i=0;i<size;i++)
  211. {
  212. CObject3d *pObject3d = m_ArrayObject3d[i];
  213. if(pObject3d->GetType() != TYPE_MESH3D)
  214. continue;
  215. CMesh3d *pMesh = (CMesh3d *)m_ArrayObject3d[i];
  216. pMesh->BuildAdjacency();
  217. }
  218. TRACE("Scene %x : End BuildAdjacency...n",this);
  219. return 1;
  220. }
  221. //********************************************
  222. // CalculateNormalPerVertex
  223. // For each mesh
  224. //********************************************
  225. int CSceneGraph3d::CalculateNormalPerVertex()
  226. {
  227. int size = m_ArrayObject3d.GetSize();
  228. if(size ==0)
  229. return 0;
  230. for(int i=0;i<size;i++)
  231. {
  232. CObject3d *pObject3d = m_ArrayObject3d[i];
  233. if(pObject3d->GetType() != TYPE_MESH3D)
  234. continue;
  235. CMesh3d *pMesh = (CMesh3d *)m_ArrayObject3d[i];
  236. pMesh->CalculateNormalPerVertex();
  237. }
  238. return 1;
  239. }
  240. //********************************************
  241. // CalculateNormalPerFace
  242. // For each mesh
  243. //********************************************
  244. int CSceneGraph3d::CalculateNormalPerFace()
  245. {
  246. int size = m_ArrayObject3d.GetSize();
  247. if(size ==0)
  248. return 0;
  249. for(int i=0;i<size;i++)
  250. {
  251. CObject3d *pObject3d = m_ArrayObject3d[i];
  252. if(pObject3d->GetType() != TYPE_MESH3D)
  253. continue;
  254. CMesh3d *pMesh = (CMesh3d *)m_ArrayObject3d[i];
  255. pMesh->CalculateNormalPerFace();
  256. }
  257. return 1;
  258. }
  259. //********************************************
  260. // SetNormalBinding
  261. //********************************************
  262. void CSceneGraph3d::SetNormalBinding(int type)
  263. {
  264. int size = m_ArrayObject3d.GetSize();
  265. for(int i=0;i<size;i++)
  266. {
  267. CObject3d *pObject3d = m_ArrayObject3d[i];
  268. if(pObject3d->GetType() != TYPE_MESH3D)
  269. continue;
  270. CMesh3d *pMesh = (CMesh3d *)m_ArrayObject3d[i];
  271. pMesh->SetNormalBinding(type);
  272. }
  273. }
  274. //********************************************
  275. // SetColorBinding
  276. //********************************************
  277. void CSceneGraph3d::SetColorBinding(int type)
  278. {
  279. int size = m_ArrayObject3d.GetSize();
  280. for(int i=0;i<size;i++)
  281. {
  282. CObject3d *pObject3d = m_ArrayObject3d[i];
  283. if(pObject3d->GetType() != TYPE_MESH3D)
  284. continue;
  285. CMesh3d *pMesh = (CMesh3d *)m_ArrayObject3d[i];
  286. pMesh->SetColorBinding(type);
  287. }
  288. }
  289. //////////////////////////////////////////////
  290. // TEXTURES
  291. //////////////////////////////////////////////
  292. //********************************************
  293. // HasTexture
  294. //********************************************
  295. int CSceneGraph3d::HasTexture(char *name,
  296. int *index)
  297. {
  298. for(int i=0;i<m_ArrayTexture.GetSize();i++)
  299. if(m_ArrayTexture[i]->GetFileName() == name)
  300. {
  301. *index = i;
  302. return 1;
  303. }
  304. return 0;
  305. }
  306. //////////////////////////////////////////////
  307. // I/O
  308. //////////////////////////////////////////////
  309. //********************************************
  310. // SaveFile
  311. //********************************************
  312. int CSceneGraph3d::SaveFile(char *name)
  313. {
  314. // Check
  315. if(NbObject() == 0)
  316. {
  317. AfxMessageBox("This scene does not contain meshes");
  318. return 0;
  319. }
  320. // Check for valid file
  321. CStdioFile file;
  322. CFileException ex;
  323. // Write header
  324. if(!WriteHeader(file,name))
  325. {
  326. AfxMessageBox("Error during writing header");
  327. return 0;
  328. }
  329. // Meshes
  330. for(int i=0;i<NbObject();i++)
  331. {
  332. CObject3d *pObject = m_ArrayObject3d[i];
  333. if(pObject->GetType() == TYPE_MESH3D)
  334. ((CMesh3d *)pObject)->WriteFile(file);
  335. }
  336. // Close file
  337.   file.Close();
  338. return 1;
  339. }
  340. //********************************************
  341. // SaveFileRaw
  342. //********************************************
  343. int CSceneGraph3d::SaveFileRaw(char *name)
  344. {
  345. // Check
  346. if(NbObject() == 0)
  347. {
  348. AfxMessageBox("This scene does not contain meshes");
  349. return 0;
  350. }
  351. // Check for valid file
  352. CFile file;
  353. CFileException ex;
  354. // Try to open file (text mode)
  355. if(!file.Open(name,CFile::modeCreate | CFile::modeWrite | CFile::typeBinary,&ex))
  356. {
  357. #ifdef _DEBUG
  358.   afxDump << "File could not be opened " << ex.m_cause << "n";
  359. #endif
  360. AfxMessageBox("Unable to open file for writing");
  361. return 0;
  362. }
  363. // Meshes
  364. unsigned int NbMesh = NbObject();
  365. file.Write(&NbMesh,sizeof(unsigned int));
  366. for(unsigned int i=0;i<NbMesh;i++)
  367. {
  368. CObject3d *pObject = m_ArrayObject3d[i];
  369. if(pObject->GetType() == TYPE_MESH3D)
  370. ((CMesh3d *)pObject)->WriteFileRaw(file);
  371. }
  372. // Close file
  373.   file.Close();
  374. return 1;
  375. }
  376. //**********************************************
  377. // WriteHeader
  378. // Do not close file
  379. //**********************************************
  380. int CSceneGraph3d::WriteHeader(CStdioFile &file,
  381.  char *name)
  382. {
  383. CFileException ex;
  384. // Try to open file (text mode)
  385. if(!file.Open(name,CFile::modeCreate | CFile::modeWrite | CFile::typeText,&ex))
  386. {
  387. #ifdef _DEBUG
  388.   afxDump << "File could not be opened " << ex.m_cause << "n";
  389. #endif
  390. AfxMessageBox("Unable to open file for writing");
  391. return 0;
  392. }
  393. // ** Header *******************************
  394. TRACE("nSave VRML 2.0 File...n");
  395. TRACE("  name : %sn",name);
  396. TRY
  397. {
  398. file.WriteString("#VRML V2.0 utf8nn");
  399. file.WriteString("# Produced by 3d Toolbox 1.0 (Pierre Alliez, CNET / DIH / HDM)nn");
  400. }
  401. CATCH(CFileException, e)
  402. {
  403. #ifdef _DEBUG
  404. afxDump << "Error during writing " << e->m_cause << "n";
  405. #endif
  406. AfxMessageBox("Error during writing file header");
  407. file.Close();
  408. return 0;
  409. }
  410. END_CATCH
  411. // do not close file
  412. return 1;
  413. }
  414. // ** EOF **