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