ARGH
[matches/honours.git] / research / transmission_spectroscopy / TOF / Win32++ / samples / DirectX / src / View.cpp
1 //////////////////////////////////////////////\r
2 // View.cpp\r
3 \r
4 // Includes backbuffer resizing suggested by Guillaume WerlĂ©\r
5 \r
6 // NOTE: for MS compilers you will need the DirectX SDK v9\r
7 //       for Dev-C++ you will need the DirecX v9.0c DevPak\r
8 \r
9 \r
10 #include "stdafx.h"\r
11 #include <d3dx9.h>      // see the note above\r
12 #include <mmsystem.h>\r
13 #include "View.h"\r
14 #include "MainFrm.h"\r
15 #include "resource.h"\r
16 \r
17 \r
18 CView::~CView()\r
19 {\r
20         if(m_pVB != NULL)\r
21                 m_pVB->Release();\r
22 \r
23         if( m_pd3dDevice != NULL)\r
24         m_pd3dDevice->Release();\r
25 \r
26     if( m_pD3D != NULL)\r
27         m_pD3D->Release();\r
28 }\r
29 \r
30 HWND CView::Create(CWnd* pParent)\r
31 {\r
32         // Called by CFrame::OnCreate. \r
33         // The window is created when the thread resumes.\r
34         StartThread(pParent);\r
35         return 0;\r
36 }\r
37 \r
38 void CView::OnCreate()\r
39 {\r
40         SetIconLarge(IDW_MAIN);\r
41         SetIconSmall(IDW_MAIN);\r
42 \r
43         // Initialize Direct3D\r
44         if( SUCCEEDED( InitD3D( m_hWnd ) ) )\r
45         {\r
46                 // Create the scene geometry\r
47         if( SUCCEEDED( InitGeometry() ) )\r
48         {\r
49                         // Show the window\r
50                         ShowWindow(SW_SHOWDEFAULT);\r
51                         UpdateWindow();\r
52                 }\r
53         }\r
54         else\r
55                 TRACE(_T("Failed to initialize DirectX\n"));\r
56 }\r
57 \r
58 void CView::PreCreate(CREATESTRUCT &cs)\r
59 {\r
60         cs.x = 50;\r
61         cs.y = 50;\r
62         cs.cx = 400;\r
63         cs.cy = 400;\r
64 }\r
65 \r
66 //-----------------------------------------------------------------------------\r
67 // Name: InitD3D()\r
68 // Desc: Initializes Direct3D\r
69 //-----------------------------------------------------------------------------\r
70 HRESULT CView::InitD3D( HWND hWnd )\r
71 {\r
72     // Create the D3D object.\r
73     if( NULL == ( m_pD3D = Direct3DCreate9( D3D_SDK_VERSION ) ) )\r
74         return E_FAIL;\r
75 \r
76         CRect rc = GetClientRect();\r
77 \r
78         // Set up the structure used to create the D3DDevice    \r
79     ZeroMemory( &m_d3dpp, sizeof(m_d3dpp) );\r
80     m_d3dpp.Windowed = TRUE;\r
81     m_d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;\r
82         m_d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;\r
83     m_d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;\r
84         m_d3dpp.BackBufferWidth = rc.Width();\r
85         m_d3dpp.BackBufferHeight = rc.Height();\r
86 \r
87     // Create the D3DDevice\r
88     if( FAILED( m_pD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd,\r
89                                     //  D3DCREATE_SOFTWARE_VERTEXPROCESSING,\r
90                                                                                 D3DCREATE_HARDWARE_VERTEXPROCESSING,\r
91                                       &m_d3dpp, &m_pd3dDevice ) ) )\r
92     {\r
93         return E_FAIL;\r
94     }\r
95 \r
96         SetupDefaultRenderStates();\r
97 \r
98     return S_OK;\r
99 }\r
100 \r
101 \r
102 //-----------------------------------------------------------------------------\r
103 // Name: InitGeometry()\r
104 // Desc: Creates the scene geometry\r
105 //-----------------------------------------------------------------------------\r
106 HRESULT CView::InitGeometry()\r
107 {\r
108     // Initialize three vertices for rendering a triangle\r
109     CUSTOMVERTEX g_Vertices[] =\r
110     {\r
111         { -1.0f,-1.0f, 0.0f, 0xffff0000, },\r
112         {  1.0f,-1.0f, 0.0f, 0xff0000ff, },\r
113         {  0.0f, 1.0f, 0.0f, 0xffffffff, },\r
114     };\r
115 \r
116     // Create the vertex buffer.\r
117     if( FAILED( m_pd3dDevice->CreateVertexBuffer( 3*sizeof(CUSTOMVERTEX),\r
118                                                   0, D3DFVF_XYZ | D3DFVF_DIFFUSE,\r
119                                                   D3DPOOL_MANAGED, &m_pVB, NULL ) ) )\r
120     {\r
121         return E_FAIL;\r
122     }\r
123 \r
124     // Fill the vertex buffer.\r
125     VOID* pVertices;\r
126     if( FAILED( m_pVB->Lock( 0, sizeof(g_Vertices), (void**)&pVertices, 0 ) ) )\r
127         return E_FAIL;\r
128     memcpy( pVertices, g_Vertices, sizeof(g_Vertices) );\r
129     m_pVB->Unlock();\r
130 \r
131     return S_OK;\r
132 }\r
133 \r
134 //-----------------------------------------------------------------------------\r
135 // Name: SetupMatrices()\r
136 // Desc: Sets up the world, view, and projection transform Matrices.\r
137 //-----------------------------------------------------------------------------\r
138 void CView::SetupMatrices()\r
139 {\r
140     // For our world matrix, we will just rotate the object about the y-axis.\r
141     D3DXMATRIXA16 matWorld;\r
142 \r
143     // Set up the rotation matrix to generate 1 full rotation (2*PI radians)\r
144     // every 1000 ms. To avoid the loss of precision inherent in very high\r
145     // floating point numbers, the system time is modulated by the rotation\r
146     // period before conversion to a radian angle.\r
147     UINT  iTime  = timeGetTime() % 1000;\r
148 \r
149     FLOAT fAngle = iTime * (2.0f * D3DX_PI) / 1000.0f;\r
150     D3DXMatrixRotationY( &matWorld, fAngle );\r
151     m_pd3dDevice->SetTransform( D3DTS_WORLD, &matWorld );\r
152 \r
153     // Set up our view matrix. A view matrix can be defined given an eye point,\r
154     // a point to lookat, and a direction for which way is up. Here, we set the\r
155     // eye five units back along the z-axis and up three units, look at the\r
156     // origin, and define "up" to be in the y-direction.\r
157     D3DXVECTOR3 vEyePt( 0.0f, 3.0f,-5.0f );\r
158     D3DXVECTOR3 vLookatPt( 0.0f, 0.0f, 0.0f );\r
159     D3DXVECTOR3 vUpVec( 0.0f, 1.0f, 0.0f );\r
160     D3DXMATRIXA16 matView;\r
161     D3DXMatrixLookAtLH( &matView, &vEyePt, &vLookatPt, &vUpVec );\r
162     m_pd3dDevice->SetTransform( D3DTS_VIEW, &matView );\r
163 \r
164     // For the projection matrix, we set up a perspective transform (which\r
165     // transforms geometry from 3D view space to 2D viewport space, with\r
166     // a perspective divide making objects smaller in the distance). To build\r
167     // a perpsective transform, we need the field of view (1/4 pi is common),\r
168     // the aspect ratio, and the near and far clipping planes (which define at\r
169     // what distances geometry should be no longer be rendered).\r
170     D3DXMATRIXA16 matProj;\r
171     D3DXMatrixPerspectiveFovLH( &matProj, D3DX_PI/4, 1.0f, 1.0f, 100.0f );\r
172     m_pd3dDevice->SetTransform( D3DTS_PROJECTION, &matProj );\r
173 }\r
174 \r
175 //-----------------------------------------------------------------------------\r
176 // Name: Render()\r
177 // Desc: Draws the scene\r
178 //-----------------------------------------------------------------------------\r
179 void CView::Render()\r
180 {\r
181         if (IsWindow())\r
182         {\r
183                 HRESULT hResult = m_pd3dDevice->TestCooperativeLevel();\r
184                 switch (hResult)\r
185                 {\r
186                 case D3D_OK:\r
187                         {\r
188                                 CRect rcClient = GetClientRect();\r
189                                 bool bNeedResize = m_d3dpp.BackBufferWidth != rcClient.Width() || m_d3dpp.BackBufferHeight != rcClient.Height();\r
190                                 if (bNeedResize)\r
191                                 {\r
192                                         m_d3dpp.BackBufferWidth         = rcClient.Width();\r
193                                         m_d3dpp.BackBufferHeight        = rcClient.Height();\r
194                                         if ( !SUCCEEDED( m_pd3dDevice->Reset(&m_d3dpp) ) )\r
195                                                 TRACE(_T("Failed to reset the DirectX device\n"));\r
196                                 }\r
197 \r
198                                 // Clear the backbuffer to a black color\r
199                                 if (D3D_OK !=m_pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0,0,0), 1.0f, 0 ))\r
200                                         TRACE(_T("Failed to clear back buffer\n"));\r
201 \r
202                                 // Begin the scene\r
203                                 if( SUCCEEDED( m_pd3dDevice->BeginScene() ) )\r
204                                 {\r
205                                         // Setup the world, view, and projection Matrices\r
206                                         SetupMatrices();\r
207 \r
208                                         SetupDefaultRenderStates();\r
209 \r
210                                         // Render the vertex buffer contents\r
211                                         m_pd3dDevice->SetStreamSource( 0, m_pVB, 0, sizeof(CUSTOMVERTEX) );\r
212                                         m_pd3dDevice->SetFVF( D3DFVF_XYZ | D3DFVF_DIFFUSE );\r
213                                         m_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, 0, 1 );\r
214 \r
215                                         // End the scene\r
216                                         m_pd3dDevice->EndScene();\r
217                                 }\r
218                                 else\r
219                                         TRACE(_T("Failed to render the scene\n"));\r
220 \r
221                                 // Present the backbuffer contents to the display\r
222                                 m_pd3dDevice->Present( NULL, NULL, NULL, NULL );\r
223                         }\r
224                         break;\r
225                 case D3DERR_DEVICELOST:\r
226                         TRACE(_T("Got D3DERR_DEVICELOST\n"));\r
227                         break;\r
228                 case D3DERR_DEVICENOTRESET:\r
229                         TRACE(_T("Got D3DERR_DEVICENOTRESET\n"));\r
230                         m_pd3dDevice->Reset(&m_d3dpp);  // Reset the DX device\r
231                         break;\r
232                 default:\r
233                         TRACE(_T("Direct3D device is in an invalid state\n"));\r
234                         break;\r
235                 }\r
236 \r
237                 // Slow the thread (otherwise it runs it a tight loop)\r
238                 Sleep(1);\r
239         }\r
240 }\r
241 \r
242 void CView::StartThread(CWnd* pParent)\r
243 {\r
244         m_pParent = pParent;\r
245         SetThreadPriority(THREAD_PRIORITY_BELOW_NORMAL);\r
246         ResumeThread();\r
247 }\r
248 \r
249 BOOL CView::InitInstance()\r
250 {\r
251         // This function runs when the thread starts\r
252 \r
253         // Create the view window\r
254         CWnd::Create(m_pParent);\r
255 \r
256         m_pParent->PostMessage(UWM_VIEWCREATED, 0, 0);\r
257 \r
258         return TRUE;    // return TRUE to run the message loop\r
259 }\r
260 \r
261 int CView::MessageLoop()\r
262 // Here we override CThread::MessageLoop to accommodate the special needs of DirectX\r
263 {\r
264         MSG Msg = {0};\r
265         while( Msg.message!=WM_QUIT )\r
266         {\r
267                 if( PeekMessage(&Msg, NULL, 0U, 0U, PM_REMOVE))\r
268                 {\r
269                         ::TranslateMessage(&Msg);\r
270                         ::DispatchMessage(&Msg);\r
271                 }\r
272                 else\r
273                         Render();\r
274         }\r
275         return LOWORD(Msg.wParam);\r
276\r
277 \r
278 LRESULT CView::WndProc(UINT uMsg, WPARAM wParam, LPARAM lParam)\r
279 {\r
280         switch(uMsg)\r
281         {\r
282         case WM_DESTROY:\r
283                 // End this thread\r
284                 ::PostQuitMessage( 0 );\r
285                 break;\r
286         }\r
287 \r
288         return WndProcDefault(uMsg, wParam, lParam);\r
289 }\r
290 \r
291 void CView::SetupDefaultRenderStates()\r
292 {\r
293         // Turn off culling, so we see the front and back of the triangle\r
294         m_pd3dDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE );\r
295 \r
296         // Turn off D3D lighting, since we are providing our own vertex colors\r
297         m_pd3dDevice->SetRenderState( D3DRS_LIGHTING, FALSE );\r
298 }\r
299 \r
300 \r

UCC git Repository :: git.ucc.asn.au