TANGLVIS.CPP
上传用户:bangxh
上传日期:2007-01-31
资源大小:42235k
文件大小:7k
源码类别:

Windows编程

开发平台:

Visual C++

  1. // AtlTangramGLVisual.cpp : Implementation of CAtlTangramGLVisual
  2. //
  3. // This is a part of the Active Template Library.
  4. // Copyright (C) 1996-1998 Microsoft Corporation
  5. // All rights reserved.
  6. //
  7. // This source code is only intended as a supplement to the
  8. // Active Template Library Reference and related
  9. // electronic documentation provided with the library.
  10. // See these sources for detailed information regarding the
  11. // Active Template Library product.
  12. #include "stdafx.h"
  13. #include "GLWorld.h"
  14. #include "TanGLVis.h"
  15. #include "event_i_i.c"
  16. #include <windows.h>
  17. #include <olectl.h>
  18. // STL Interfaces
  19. #include <new.h>
  20. #include <algorithm>
  21. #include <xmemory>
  22. #include <list>
  23. #include "util.h"
  24. #include "util.cpp"
  25. #include "CGL.h"
  26. #include "CGL.cpp"
  27. #include "CGL-Pal.cpp"
  28. // Interfaces
  29. #include "TanCanv_i.c"
  30. #include "AtlModel.h"
  31. #include "GdiWorld.h"
  32. #include "GdiWorld_i.c"
  33. // Sub-Components.
  34. #include "AtlModel_i.c"
  35. // Other
  36. #include <math.h>
  37. #include <gl/gl.h>
  38. #include <gl/glu.h>
  39. ///////////////////////////////////////////////////////////
  40. //
  41. // Destructor
  42. //
  43. CAtlTangramGLVisual::~CAtlTangramGLVisual()
  44. {
  45. // We keep a strong reference to the model.
  46. // Therefore, we need to release it here.
  47. m_pModel->Release();
  48. m_pModel = NULL;
  49. // We maintain a weak reference to GdiWorld to avoid
  50. // reference cycles. A weak reference means that we
  51. // do not need to Release m_pGdiWorld here.
  52. // Delete the vertex array.
  53. delete [] m_ptVertices;
  54. }
  55. ///////////////////////////////////////////////////////////
  56. //  ITangramVisual
  57. // ITangramVisual::SetSelected Implementation.
  58. HRESULT CAtlTangramGLVisual::SetSelected(BOOL bSelected)
  59. {
  60. m_bSelected = bSelected;
  61. // Update the display.
  62. HRESULT hr = m_pWorld->Animate();
  63. ASSERT_HRESULT(hr);
  64. return S_OK;
  65. }
  66. ///////////////////////////////////////////////////////////
  67. // ITangramGLVisual::GetModel Implementation
  68. HRESULT CAtlTangramGLVisual::GetModel(const IID& iid, IUnknown** ppI)
  69. {
  70. if (!IsValidInterfaceOutParam(ppI))
  71. {
  72. ASSERT(0);
  73. return E_POINTER;
  74. }
  75. return m_pModel->QueryInterface(iid, (void**)ppI) ;
  76. }
  77. ///////////////////////////////////////////////////////////
  78. //  ITangramGLVisual
  79. // ITangramGLVisual::Initialize Implementation
  80. HRESULT __stdcall
  81. CAtlTangramGLVisual::Initialize(IATLTangramModel* pModel,
  82. IAtlTangramGLWorld* pWorld)
  83. {
  84. if (!IsValidInterface(pModel)|| !IsValidInterface(pWorld))
  85. {
  86. ASSERT(0);
  87. return E_POINTER;
  88. }
  89. if (m_pModel != NULL || m_pWorld != NULL)
  90. {
  91. // Cannot re-initialize.
  92. ASSERT(0);
  93. return E_FAIL;
  94. }
  95. // Keep a strong reference to the model.
  96. m_pModel = pModel;
  97. m_pModel->AddRef();
  98. // To avoid a cyclical reference count, we have a
  99. // weak reference to GLWorld. Therefore, we do
  100. // not AddRef this pointer.
  101. m_pWorld = pWorld;
  102. // Get the number of vertices in the model.
  103. HRESULT hr = m_pModel->GetNumberOfVertices(&m_cVertices);
  104. ASSERT_HRESULT(hr);
  105. // Create an array to hold the vertices.
  106. m_ptVertices = new TangramPoint2d[m_cVertices];
  107. //  Set up event sync
  108. // Create a sink object.
  109. TCHAR buf[128];
  110. wsprintf(buf, _T("Visual: m_dwRef = %dn"), m_dwRef);
  111. ATLTRACE(buf);
  112. // Get the connection point container.
  113. IConnectionPointContainer* pContainer = NULL;
  114. hr = pModel->QueryInterface(IID_IConnectionPointContainer,
  115. (void**)&pContainer);
  116. ASSERT_HRESULT(hr);
  117. // Get our desired connection point. Cache the pointer so
  118. // we don't have to get it again.
  119. hr = pContainer->FindConnectionPoint(IID_IATLTangramModelEvent,
  120. &m_pIConnectionPoint);
  121. pContainer->Release();
  122. ASSERT_HRESULT(hr);
  123. IATLTangramModelEvent* pIATLTangramModelEvent;
  124. hr = GetUnknown()->QueryInterface(IID_IATLTangramModelEvent,
  125. (void**)&pIATLTangramModelEvent);
  126. wsprintf(buf, _T("Visual: m_dwRef = %dn"), m_dwRef);
  127. ATLTRACE(buf);
  128. // Ask the visual to advise us of any changes.
  129. hr = m_pIConnectionPoint->Advise(pIATLTangramModelEvent, &m_dwCookie);
  130. ASSERT_HRESULT(hr);
  131. wsprintf(buf, _T("Visual: m_dwRef = %dn"), m_dwRef);
  132. ATLTRACE(buf);
  133. // We don't need to keep a reference to the sink.
  134. pIATLTangramModelEvent->Release();
  135. wsprintf(buf, _T("Visual: m_dwRef = %dn"), m_dwRef);
  136. ATLTRACE(buf);
  137. return S_OK;
  138. }
  139. ///////////////////////////////////////////////////////////
  140. // ITangramGLVisual::DrawOn Implementation
  141. HRESULT CAtlTangramGLVisual::DrawOn(IAtlTangramCanvas* pCanvas)
  142. {
  143. // Preconditions.
  144. if (!m_bFirstEvent)
  145. {
  146. // We have not received a model change event to initialize use.
  147. return S_FALSE;
  148. }
  149. if (!IsValidInterface(pCanvas))
  150. {
  151. ASSERT(0);
  152. return E_POINTER;
  153. }
  154. double thickness = 0.01;
  155. if (m_bSelected)
  156. glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
  157. // Bottom
  158. glNormal3d(0.0, 0.0, -1.0);
  159. glBegin(GL_TRIANGLE_FAN);
  160. for (int i = 0; i < m_cVertices; i++)
  161. glVertex2d(m_ptVertices[i].x, m_ptVertices[i].y);
  162. glEnd();
  163. // Top
  164. glNormal3d(0.0, 0.0, 1.0);
  165. glBegin(GL_TRIANGLE_FAN);
  166. for (i = 0; i < m_cVertices; i++)
  167. glVertex3d(m_ptVertices[i].x, m_ptVertices[i].y, thickness);
  168. glEnd();
  169. // Sides
  170. for (i = 0; i < m_cVertices; i++)
  171. {
  172. int iNextIndex = (i+1) % m_cVertices;
  173. // Compute Normal [v1 - v2] X [v2 - v3] see page 58 of RedBook
  174. // V1 = v1 - v2
  175. double X1 = m_ptVertices[i].x - m_ptVertices[iNextIndex].x;
  176. double Y1 = m_ptVertices[i].y - m_ptVertices[iNextIndex].y;
  177. double Z1 = 0.0; // 0.0f - 0.0f;
  178. // V2 = v2 - v3
  179. double X2 = 0.0; //m_ptVertices[iNextIndex].x - m_ptVertices[iNextIndex].x;
  180. double Y2 = 0.0; //m_ptVertices[iNextIndex].y - m_ptVertices[iNextIndex].y;
  181. double Z2 = -thickness; // 0.0 - thickness;
  182. // V = V1 X V2
  183. double X = Y1 * Z2; //Y1*Z2 - Z1*Y2  = Y1*Z2 - 0.0*0.0;
  184. double Y = -X1 * Z2; //Z1*X2 - X1*Z2 = 0.0*0.0 - X1*Z2
  185. //double Z = 0.0; //X1*Y2 - Y1*X2;
  186. // Normalize
  187. double d = sqrt(X*X + Y*Y /*+ Z*Z*/);
  188. ASSERT( d != 0.0);
  189. X /= d;
  190. Y /= d;
  191. //Z /= d;
  192. glNormal3d(X, Y, 0.0/*Z*/);
  193. glBegin(GL_QUADS);
  194. glVertex3d(m_ptVertices[i].x, m_ptVertices[i].y, 0.0);
  195. glVertex3d(m_ptVertices[iNextIndex].x,
  196. m_ptVertices[iNextIndex].y, 0.0);
  197. glVertex3d(m_ptVertices[iNextIndex].x,
  198. m_ptVertices[iNextIndex].y, thickness);
  199. glVertex3d(m_ptVertices[i].x, m_ptVertices[i].y, thickness);
  200. glEnd();
  201. }
  202. if (m_bSelected)
  203. glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
  204. return S_OK;
  205. }
  206. ///////////////////////////////////////////////////////////
  207. //  ITangramModelEvent
  208. // ITangramModelEvent::OnModelChange
  209. HRESULT __stdcall CAtlTangramGLVisual::OnModelChange()
  210. {
  211. // Create an array to hold the new vertices.
  212. TangramPoint2d* pointds = new TangramPoint2d[m_cVertices];
  213. // Get the vertices from the model.
  214. HRESULT hr = m_pModel->GetVertices(m_cVertices, pointds);
  215. ASSERT_HRESULT(hr);
  216. // Convert the vertices to our coordinates.
  217. for (int i = 0; i < m_cVertices; i++)
  218. {
  219. hr = m_pWorld->ModelToDevice(pointds[i], &m_ptVertices[i]);
  220. ASSERT_HRESULT(hr);
  221. }
  222. // Cleanup;
  223. delete [] pointds;
  224. // We are in sync.
  225. m_bFirstEvent = TRUE;
  226. // Update the display.
  227. hr = m_pWorld->Animate();
  228. ASSERT_HRESULT(hr);
  229. return S_OK;
  230. }
  231. STDMETHODIMP CAtlTangramGLVisual::ReleaseConnectionPoint()
  232. {
  233. HRESULT hr = S_OK;
  234. // Release the event source component.
  235. if (m_pIConnectionPoint != NULL)
  236. {
  237. // We no longer need to be enformed of events
  238. HRESULT hr = m_pIConnectionPoint->Unadvise(m_dwCookie);
  239. ASSERT_HRESULT(hr);
  240. m_pIConnectionPoint->Release();
  241. }
  242. return hr;
  243. }