3dObjectDisk.cpp NEW
上传用户:shxiangxiu
上传日期:2007-01-03
资源大小:1101k
文件大小:11k
源码类别:

OpenGL

开发平台:

Visual C++

  1. /////////////////////////////////////////////////////////////////////////////
  2. // 3dObjectDisk.cpp : implementation file
  3. //
  4. // glOOP (OpenGL Object Oriented Programming library)
  5. // Copyright (c) Craig Fahrnbach 1997, 1998
  6. //
  7. // OpenGL is a registered trademark of Silicon Graphics
  8. //
  9. //
  10. // This program is freely distributable without licensing fees and is
  11. // provided without guarantee or warrantee expressed or implied. This
  12. // program is -not- in the public domain.
  13. //
  14. /////////////////////////////////////////////////////////////////////////////
  15. #include "stdafx.h"
  16. #include "glOOP.h"
  17. #include "3dObjectDialog.h"
  18. #ifdef _DEBUG
  19. #define new DEBUG_NEW
  20. #undef THIS_FILE
  21. static char THIS_FILE[] = __FILE__;
  22. #endif
  23. //////////////////////////////////////////////////////////////////
  24. // C3dObjectDisk
  25. IMPLEMENT_DYNAMIC(C3dObjectDisk, C3dObject)
  26. /////////////////////////////////////////////////////////////////////////////
  27. // C3dShape construction
  28. C3dObjectDisk::C3dObjectDisk()
  29. {
  30. // Set the attributes to default values..
  31.   m_iType = SHAPE_OBJECT;
  32.    m_szName.Format("Disk %u", nDiskObjects++);
  33. m_fInnerRadius = 0.0f;
  34. m_fOuterRadius = 1.0f;
  35. m_fSweepAngle = 360.0f; // full circle  
  36. m_iSegments = 10;
  37. m_iRings = 1;
  38. // Create our C3dPointArray object
  39. m_pPointArray = new C3dPointArray;
  40. ASSERT(m_pPointArray);
  41. // Create an array of points for our vertices
  42. m_pPointArray->Create(m_iSegments+2);
  43. // Initialize our cubes vertices (points)
  44. InitVertices();
  45. }
  46. /////////////////////////////////////////////////////////////////////////////
  47. // C3DWorld Destructor
  48. C3dObjectDisk::~C3dObjectDisk()
  49. {
  50. // Delete our point array
  51. if(m_pPointArray)
  52. delete m_pPointArray;
  53. }
  54. /////////////////////////////////////////////////////////////////////////////
  55. // C3dObjectDisk Methods or virtual function implimentation
  56. void C3dObjectDisk::AddAttributePage(C3dWorld* pWorld, LPVOID pSht)
  57. {
  58. C3dObjectPropSheet* pSheet = (C3dObjectPropSheet*)pSht;
  59. ASSERT(pSheet);
  60. // Add the page to the property sheet
  61. pSheet->AddPage(&pSheet->m_DiskPage);
  62. // Save the address of this object in the page
  63. pSheet->m_DiskPage.m_pObject = this;
  64. }
  65. int C3dObjectDisk::LoadBitMapImage(CImageList* pList)
  66. {
  67. CBitmap bitmap;
  68. // If the image index has been stored in this object,
  69. // return the index.
  70. if(m_iBMImage > -1)
  71. return m_iBMImage;
  72. // If the image index for this object type has been
  73. // created, store the index for this object and
  74. // return the index.
  75. if( iObjectDiskBMImage > -1) {
  76. m_iBMImage = iObjectDiskBMImage;
  77. return m_iBMImage;
  78. }
  79. // The image index for this object type has not been
  80. // loaded and the object image index has not been
  81. // stored.
  82. //
  83. // Load the bitmap for the non-selected light
  84. bitmap.LoadBitmap(IDB_OBJECT_DISK);
  85. m_iBMImage = pList->Add(&bitmap, (COLORREF)0xFFFFFF);
  86. bitmap.DeleteObject();
  87. // Load the bitmap for the non-selected light
  88. bitmap.LoadBitmap(IDB_OBJECT_DISK_SELECTED);
  89. pList->Add(&bitmap, (COLORREF)0xFFFFFF);
  90. bitmap.DeleteObject();
  91. iObjectDiskBMImage = m_iBMImage;
  92. return m_iBMImage;
  93. }
  94. void C3dObjectDisk::Serialize(CArchive& ar, int iVersion)
  95. {
  96. CString szBuffer;
  97. if (ar.IsStoring())
  98. {
  99. // Save the Object Class header...
  100. szBuffer.Format("n%sC3dObjectDisk {n", szIndent);
  101. ar.WriteString(szBuffer);
  102. // Save the this objects' specific data...
  103. szBuffer.Format("%stInnerRadius   < %f >n", szIndent, m_fInnerRadius);
  104. ar.WriteString(szBuffer);
  105. szBuffer.Format("%stOuterRadius   < %f >n", szIndent, m_fOuterRadius);
  106. ar.WriteString(szBuffer);
  107. szBuffer.Format("%stSegments      < %d >n", szIndent, m_iSegments);
  108. ar.WriteString(szBuffer);
  109. szBuffer.Format("%stSweepAngle    < %f >n", szIndent, m_fSweepAngle);
  110. ar.WriteString(szBuffer);
  111. szBuffer.Format("%stSolid Color   < %d >n", szIndent, m_bSolidColor);
  112. ar.WriteString(szBuffer);
  113. szBuffer.Format("%stNum Points    < %d >n", szIndent, m_pPointArray->m_iNumPoints);
  114. ar.WriteString(szBuffer);
  115. m_pPointArray->Serialize(ar, iVersion, !m_bSolidColor);
  116. // Save the base class object data...
  117. C3dObject::Serialize(ar, iVersion);
  118. szBuffer.Format("%s}n", szIndent); // end of object def
  119. ar.WriteString(szBuffer);
  120. }
  121. else
  122. {
  123. if(iVersion < 102)
  124. // Read the base class object data...
  125. C3dObject::Serialize(ar, iVersion);
  126. // Read the derived class data..
  127. ar.ReadString(szBuffer);
  128. szBuffer.TrimLeft(); // Remove leading white spaces
  129. sscanf(szBuffer, "InnerRadius   < %f >n", &m_fInnerRadius);
  130. ar.ReadString(szBuffer);
  131. szBuffer.TrimLeft();
  132. sscanf(szBuffer, "OuterRadius   < %f >n", &m_fOuterRadius);
  133. ar.ReadString(szBuffer);
  134. szBuffer.TrimLeft();
  135. sscanf(szBuffer, "Segments      < %d >n", &m_iSegments);
  136. // Resize our point array to accomodate all points
  137. int arraySize;
  138. if(m_fInnerRadius)
  139. arraySize = (m_iSegments+2)*2;
  140. else
  141. arraySize = m_iSegments+2;
  142. if(m_pPointArray->SetArraySize(arraySize))
  143. return;
  144. if(iVersion < 110)
  145. {
  146. // Version 1.10 and higher do not support rings on disk, so just read
  147. // the buffer
  148. ar.ReadString(szBuffer);
  149. // Initialize our point array vertices
  150. InitVertices();
  151. }
  152. else
  153. {
  154. ar.ReadString(szBuffer);
  155. szBuffer.TrimLeft();
  156. sscanf(szBuffer, "SweepAngle    < %f >n", &m_fSweepAngle);
  157. if(iVersion > 130)
  158. {
  159. // Version 1.4 added point color capability
  160. ar.ReadString(szBuffer);
  161. szBuffer.TrimLeft();
  162. sscanf(szBuffer, "Solid Color   < %d >n", &m_bSolidColor);
  163. }
  164. ar.ReadString(szBuffer);
  165. szBuffer.TrimLeft();
  166. sscanf(szBuffer, "Num Points    < %d >n", &m_pPointArray->m_iNumPoints);
  167. // Read the shape vertice, or point data
  168. m_pPointArray->Serialize(ar, iVersion, !m_bSolidColor);
  169. }
  170. if(iVersion < 102)
  171. // Read all child objects...
  172. LoadChildObjects(ar, iVersion);
  173. else
  174. // Read the base class object data...
  175. C3dObject::Serialize(ar, iVersion);
  176. }
  177. }
  178. void C3dObjectDisk::Build(C3dWorld* pWorld, C3dCamera* pCamera)
  179. {
  180. VECTORF Normal;
  181. GLfloat x0, y0, x1, y1;
  182. double a0, a1;
  183. int i;
  184. // Compile and build the list
  185. glNewList(m_iDisplayLists, GL_COMPILE_AND_EXECUTE);
  186. if(!m_fInnerRadius)
  187. {
  188. C3dPoint* pInnerPoint; // Pointer to the first inner point
  189. C3dPoint* pOuterPoint; // Pointer to the first outer point
  190. pInnerPoint = &m_pPointArray->m_pPoints[0]; // first point in array
  191. pOuterPoint = &m_pPointArray->m_pPoints[1]; // second point in array
  192. // Initialize our disks vertice points
  193. for(i=0; i<m_iSegments; i++)
  194. {
  195. a0 = i * (m_fSweepAngle/m_iSegments);
  196. x0 = Cosf((GLfloat)a0);
  197. y0 = Sinf((GLfloat)a0);
  198. a1 = (i+1) * (m_fSweepAngle/m_iSegments);
  199. x1 = Cosf((GLfloat)a1);
  200. y1 = Sinf((GLfloat)a1);
  201. glBegin(GL_TRIANGLES);
  202. // Calculate the normal for the triangle
  203. CalNormalf(pInnerPoint->m_fOrigin,
  204.    pOuterPoint[i+1].m_fOrigin,
  205.    pOuterPoint[i].m_fOrigin,
  206.    Normal);
  207. glNormal3fv(Normal);
  208. glTexCoord2d(0.5, 0.5);
  209. if(!m_bSolidColor)
  210. glColor4fv(pInnerPoint->m_Color.m_fColor);
  211. glVertex3fv(pInnerPoint->m_fOrigin);
  212. glTexCoord2d((x0*0.5)+0.5, (y0*0.5)+0.5); 
  213. if(!m_bSolidColor)
  214. glColor4fv(pOuterPoint[i].m_Color.m_fColor);
  215. glVertex3fv(pOuterPoint[i].m_fOrigin);
  216. glTexCoord2d((x1*0.5)+0.5, (y1*0.5)+0.5); 
  217. if(!m_bSolidColor)
  218. glColor4fv(pOuterPoint[i+1].m_Color.m_fColor);
  219. glVertex3fv(pOuterPoint[i+1].m_fOrigin);
  220. glEnd();
  221. }
  222. }
  223. else
  224. {
  225. C3dPoint* pPoint = m_pPointArray->m_pPoints; // first point in array
  226. // Initialize our disks vertice points
  227. for(i=0; i<(m_iSegments*2); i+=2)
  228. {
  229. a0 = (i/2) * (m_fSweepAngle/m_iSegments);
  230. x0 = Cosf((GLfloat)a0);
  231. y0 = Sinf((GLfloat)a0);
  232. a1 = ((i/2)+1) * (m_fSweepAngle/m_iSegments);
  233. x1 = Cosf((GLfloat)a1);
  234. y1 = Sinf((GLfloat)a1);
  235. glBegin(GL_TRIANGLE_STRIP);
  236. // Calculate the normal for the triangle
  237. CalNormalf(pPoint[i+1].m_fOrigin,
  238.    pPoint[i].m_fOrigin,
  239.    pPoint[i+3].m_fOrigin,
  240.    Normal);
  241. glNormal3fv(Normal);
  242. glTexCoord2d((x0*0.5)+0.5, (y0*0.5)+0.5); 
  243. if(!m_bSolidColor)
  244. glColor4fv(pPoint[i+1].m_Color.m_fColor);
  245. glVertex3fv(pPoint[i+1].m_fOrigin);
  246. glTexCoord2d((x1*0.5)+0.5, (y1*0.5)+0.5); 
  247. if(!m_bSolidColor)
  248. glColor4fv(pPoint[i+3].m_Color.m_fColor);
  249. glVertex3fv(pPoint[i+3].m_fOrigin);
  250. glTexCoord2d(((x0*(m_fInnerRadius/m_fOuterRadius))/2)+0.5,
  251.  ((y0*(m_fInnerRadius/m_fOuterRadius))/2)+0.5); 
  252. if(!m_bSolidColor)
  253. glColor4fv(pPoint[i].m_Color.m_fColor);
  254. glVertex3fv(pPoint[i].m_fOrigin);
  255. // Calculate the normal for the triangle
  256. CalNormalf(pPoint[i].m_fOrigin,
  257.    pPoint[i+2].m_fOrigin,
  258.    pPoint[i+3].m_fOrigin,
  259.    Normal);
  260. glNormal3fv(Normal);
  261. glTexCoord2d(((x1*(m_fInnerRadius/m_fOuterRadius))/2)+0.5,
  262.  ((y1*(m_fInnerRadius/m_fOuterRadius))/2)+0.5); 
  263. if(!m_bSolidColor)
  264. glColor4fv(pPoint[i+2].m_Color.m_fColor);
  265. glVertex3fv(pPoint[i+2].m_fOrigin);
  266. glEnd();
  267. }
  268. }
  269. glEndList();
  270. }
  271. /////////////////////////////////////////////////////////////////////////////
  272. // C3dObjectDisk Methods or Implementation
  273. void C3dObjectDisk::InitVertices()
  274. {
  275. /*   Flat disk with Inner Flat disk with Inner
  276.   radius = 0.0 radius = x.0
  277.                                           p5 -------  p3
  278.                                            /            
  279.          p3 ------ p2                    /                      
  280.           /                           /   p4 ----- p2   
  281.         /                            |     /            |
  282.     p4 |       *p0    | p1&pN      p7 |  p6|         |p0  | p1
  283.        |              |               |            / pN  | pN+1
  284.                     /                    p8 ----- p10  /
  285.                   /                                  /
  286.          p5 ------ p6                               /
  287.                                           p9 ------- p11
  288. */
  289. C3dPoint* pPoint;
  290. int iNumPoints;
  291. // Determine the number of points in the disk
  292. if(m_fInnerRadius)
  293. iNumPoints = (m_iSegments+2)*2;
  294. else
  295. iNumPoints = m_iSegments+2;
  296. if(m_pPointArray->SetArraySize(iNumPoints))
  297. return; // function failed
  298. pPoint= m_pPointArray->m_pPoints; // address of the first point
  299. // Initialize our disks vertice points
  300. int i;
  301. for(i=0; i<=m_iSegments; i++)
  302. {
  303. double a0  = i * (m_fSweepAngle/m_iSegments);
  304. GLfloat x0 = Cosf((GLfloat)a0);
  305. GLfloat y0 = Sinf((GLfloat)a0);
  306. if(m_fInnerRadius || i==0)
  307. {
  308. pPoint->m_fOrigin[X] = m_fInnerRadius*x0;
  309. pPoint->m_fOrigin[Y] = m_fInnerRadius*y0;
  310. pPoint->m_fOrigin[Z] = 0.0f;
  311. pPoint++;
  312. }
  313. pPoint->m_fOrigin[X] = m_fOuterRadius*x0;
  314. pPoint->m_fOrigin[Y] = m_fOuterRadius*y0;
  315. pPoint->m_fOrigin[Z] = 0.0f;
  316. pPoint++;
  317. }
  318. }