umvistad3d.cpp

  1 // +-------------------+
  2 // | Direct3D and Aero |
  3 // +-------------------+---------------------------------+
  4 // | Example written by Tristan Ward for codeproject.com |
  5 // +-----------------------------------------------------+
  6 
  7 // +------------+
  8 // | Directives |
  9 // +------------+
 10 // Specify Windows version
 11 #define WINVER         0x0600
 12 #define _WIN32_WINNT   0x0600
 13 
 14 // Includes
 15 #include <d3d9.h>
 16 #include <d3dx9.h>
 17 #include <dwmapi.h>
 18 
 19 // Import libraries to link with
 20 #pragma comment(lib, "d3d9.lib")
 21 #pragma comment(lib, "d3dx9.lib")
 22 #pragma comment(lib, "dwmapi.lib")
 23 
 24 // Global constants
 25 #define ARGB_RED     0xFFFF0000 // Full red full alpha
 26 #define ARGB_GREEN   0xFF00FF00 // Full green full alpha
 27 #define ARGB_BLUE    0x800000FF // Full blue 50% alpha
 28 #define ARGB_CYAN    0xFF00FFFF // Full cyan full alpha
 29 #define ARGB_TRANS   0x00000000 // 100% alpha
 30 #define ARGB_AMBIENT 0xFF0A0A0A // Ambient light colour
 31 
 32 // +---------+
 33 // | Globals |
 34 // +---------+
 35 WCHAR                   *g_wcpAppName  = L"VistaD3D";
 36 INT                     g_iWidth       = 256;
 37 INT                     g_iHeight      = 256;
 38 MARGINS                 g_mgDWMMargins = {-1, -1, -1, -1};
 39 IDirect3D9Ex            *g_pD3D        = NULL;
 40 IDirect3DDevice9Ex      *g_pD3DDevice  = NULL;
 41 IDirect3DVertexBuffer9  *g_pVB         = NULL;
 42 
 43 struct CUSTOMVERTEX
 44 {
 45   FLOAT     fX, fY, fZ; // The position for the vertex
 46   D3DVECTOR vctNormal;  // The normal of each vector (for lighting calcs)    
 47   DWORD     dwColour;   // The vertex color
 48 };
 49 
 50 // +--------------+
 51 // | D3DStartup() |
 52 // +--------------+----------------------------------+
 53 // | Initialise Direct3D and perform once only tasks |
 54 // +-------------------------------------------------+
 55 HRESULT D3DStartup(HWND hWnd)
 56 {
 57   BOOL                  bCompOk             = FALSE;   // Is composition enabled? 
 58   D3DPRESENT_PARAMETERS pp;                            // Presentation prefs
 59   DWORD                 msqAAQuality        = 0;       // Non-maskable quality
 60   D3DLIGHT9             ltDirectionalLight;            // Light description
 61   D3DVECTOR             vctLightDirection   = {-1.0f,  // X component
 62                                                -0.3f,  // Y component
 63                                                -1.0f}; // Z component
 64   D3DXMATRIX            mtxView;                       // View matrix
 65   D3DXMATRIX            mtxProjection;                 // Projection matrix
 66 
 67   // Make sure that DWM composition is enabled
 68   DwmIsCompositionEnabled(&bCompOk);
 69   if(!bCompOk) return E_FAIL;
 70 
 71   // Create a Direct3D object
 72   if(FAILED(Direct3DCreate9Ex(D3D_SDK_VERSION, &g_pD3D))) return E_FAIL;
 73 
 74   // Setup presentation parameters
 75   ZeroMemory(&pp, sizeof(pp));
 76   pp.Windowed            = TRUE;
 77   pp.SwapEffect          = D3DSWAPEFFECT_DISCARD; // Required for multi sampling
 78   pp.BackBufferFormat    = D3DFMT_A8R8G8B8;       // Back buffer format with alpha channel
 79 
 80   // Set highest quality non-maskable AA available or none if not
 81   if(SUCCEEDED(g_pD3D->CheckDeviceMultiSampleType(D3DADAPTER_DEFAULT,
 82                                                   D3DDEVTYPE_HAL,
 83                                                   D3DFMT_A8R8G8B8,
 84                                                   TRUE,
 85                                                   D3DMULTISAMPLE_NONMASKABLE,
 86                                                   &msqAAQuality
 87                                                   )))
 88   {
 89     // Set AA quality
 90     pp.MultiSampleType     = D3DMULTISAMPLE_NONMASKABLE;
 91     pp.MultiSampleQuality  = msqAAQuality - 1;
 92   }
 93   else
 94   {
 95     // No AA
 96     pp.MultiSampleType     = D3DMULTISAMPLE_NONE;
 97   }
 98 
 99   // Create a Direct3D device object
100   if(FAILED(g_pD3D->CreateDeviceEx(D3DADAPTER_DEFAULT,
101                                    D3DDEVTYPE_HAL,
102                                    hWnd,
103                                    D3DCREATE_HARDWARE_VERTEXPROCESSING,
104                                    &pp,
105                                    NULL,
106                                    &g_pD3DDevice
107                                    ))) return E_FAIL;
108 
109   // Configure the device state
110   g_pD3DDevice->SetRenderState(D3DRS_LIGHTING, TRUE);        // Enable 3D lighting
111   g_pD3DDevice->SetRenderState(D3DRS_AMBIENT, ARGB_AMBIENT); // Set ambient lighting
112   g_pD3DDevice->SetRenderState(D3DRS_SPECULARENABLE, FALSE); // Disable specular highlighting
113   
114   // Create a directional light
115   ZeroMemory(&ltDirectionalLight, sizeof(ltDirectionalLight));
116   ltDirectionalLight.Type       = D3DLIGHT_DIRECTIONAL;
117   ltDirectionalLight.Diffuse.r  = 1.0f;
118   ltDirectionalLight.Diffuse.g  = 1.0f;
119   ltDirectionalLight.Diffuse.b  = 1.0f;
120   ltDirectionalLight.Diffuse.a  = 1.0f;                
121   ltDirectionalLight.Direction  = vctLightDirection;
122 
123   // Add as light 0
124   g_pD3DDevice->SetLight(0, &ltDirectionalLight);
125   g_pD3DDevice->LightEnable(0, TRUE);
126 
127   // Configure camera
128   D3DXMatrixLookAtLH(&mtxView,
129                      &D3DXVECTOR3 (0.0f, 0.0f, 25.0f), // Camera position
130                      &D3DXVECTOR3 (0.0f, 0.0f, 0.0f),  // Look-at target
131                      &D3DXVECTOR3 (0.0f, 1.0f, 0.0f)); // Up direction
132   g_pD3DDevice->SetTransform(D3DTS_VIEW, &mtxView);
133 
134   // Configure projection
135   D3DXMatrixPerspectiveFovLH(&mtxProjection,
136                              D3DXToRadian(45),                          // Horizontal field of view
137                              (FLOAT)((FLOAT)g_iWidth/(FLOAT)g_iHeight),    // Aspect ratio
138                              0.0f,                                                          // Near view plane
139                              100.0f);                                                        // Far view plane
140   g_pD3DDevice->SetTransform(D3DTS_PROJECTION, &mtxProjection);
141 
142   return S_OK;
143 }
144 
145 // +---------------+
146 // | D3DShutdown() |
147 // +---------------+----------------------+
148 // | Release all created Direct3D objects |
149 // +--------------------------------------+
150 VOID D3DShutdown(VOID)
151 {
152   if(g_pVB != NULL ) g_pVB->Release();
153   if(g_pD3DDevice != NULL) g_pD3DDevice->Release();
154   if(g_pD3D != NULL) g_pD3D->Release();
155 }
156 
157 // +--------------+
158 // | CreateCube() |
159 // +--------------+------------------------------+
160 // | Populates a vertex buffer with a cube shape |
161 // +---------------------------------------------+
162 HRESULT CreateCube(VOID)
163 {
164   VOID* pVBVertices = NULL; // Pointer to vertex buffer data 
165 
166   // Initialize 24 vertices describing the shape of a cube
167   CUSTOMVERTEX cvtxCube[] = {
168   {-5.0f, 5.0f, -5.0f, 0, 0, -1, ARGB_RED,},
169   {5.0f, 5.0f, -5.0f, 0, 0, -1, ARGB_GREEN,},
170   {-5.0f, -5.0f, -5.0f, 0, 0, -1, ARGB_BLUE,},
171   {5.0f, -5.0f, -5.0f, 0, 0, -1, ARGB_CYAN,},
172 
173   {-5.0f, 5.0f, 5.0f, 0, 0, 1, ARGB_RED,},
174   {-5.0f, -5.0f, 5.0f, 0, 0, 1, ARGB_GREEN,},
175   {5.0f, 5.0f, 5.0f, 0, 0, 1, ARGB_BLUE,},
176   {5.0f, -5.0f, 5.0f, 0, 0, 1, ARGB_CYAN,},
177 
178   {-5.0f, 5.0f, 5.0f, 0, 1, 0, ARGB_RED,},
179   {5.0f, 5.0f, 5.0f, 0, 1, 0, ARGB_GREEN,},
180   {-5.0f, 5.0f, -5.0f, 0, 1, 0, ARGB_BLUE,},
181   {5.0f, 5.0f, -5.0f, 0, 1, 0, ARGB_CYAN,},
182 
183   {-5.0f, -5.0f, 5.0f, 0, -1, 0, ARGB_RED,},
184   {-5.0f, -5.0f, -5.0f, 0, -1, 0, ARGB_GREEN,},
185   {5.0f, -5.0f, 5.0f, 0, -1, 0, ARGB_BLUE,},
186   {5.0f, -5.0f, -5.0f, 0, -1, 0, ARGB_CYAN,},
187 
188   {5.0f, 5.0f, -5.0f, 1, 0, 0, ARGB_RED,},
189   {5.0f, 5.0f, 5.0f, 1, 0, 0, ARGB_GREEN,},
190   {5.0f, -5.0f, -5.0f, 1, 0, 0, ARGB_BLUE,},
191   {5.0f, -5.0f, 5.0f, 1, 0, 0, ARGB_CYAN,},
192 
193   {-5.0f, 5.0f, -5.0f, -1, 0, 0, ARGB_RED,},
194   {-5.0f, -5.0f, -5.0f, -1, 0, 0, ARGB_GREEN,},
195   {-5.0f, 5.0f, 5.0f, -1, 0, 0, ARGB_BLUE,},
196   {-5.0f, -5.0f, 5.0f, -1, 0, 0, ARGB_CYAN,}};
197 
198   // Create a vertex buffer to hold the cube data
199   if(FAILED(g_pD3DDevice->CreateVertexBuffer(24*sizeof(CUSTOMVERTEX),
200                                              0,
201                                              D3DFVF_XYZ|D3DFVF_NORMAL|D3DFVF_DIFFUSE,
202                                              D3DPOOL_DEFAULT,
203                                              &g_pVB,
204                                              NULL)
205                                              )) return E_FAIL;
206 
207   // Lock the vertex buffer for editing
208   if(FAILED(g_pVB->Lock(0, sizeof(cvtxCube), (VOID**)&pVBVertices, 0))) return E_FAIL;
209   
210   // Copy vertex array to vertex buffer
211   memcpy(pVBVertices, cvtxCube, sizeof(cvtxCube));
212   
213   // Unlock the vertex buffer
214   g_pVB->Unlock();
215 
216   return S_OK;
217 }
218 
219 // +----------+
220 // | Render() |
221 // +----------+-------------------------+
222 // | Renders a scene to the back buffer |
223 // +------------------------------------+
224 VOID Render(VOID)
225 {
226   static float    fRotator      = 0.0f; // Cube rotation factor
227   D3DXMATRIX    mtxRotateYPR;         // Yaw/Pitch/Roll matrix
228 
229   // Sanity check
230   if(g_pD3DDevice == NULL) return;
231 
232   // Increment static float
233   fRotator += 0.025f;
234     
235   // Rotate the cube using the static float
236   D3DXMatrixRotationYawPitchRoll(&mtxRotateYPR, fRotator, fRotator, fRotator);
237   g_pD3DDevice->SetTransform(D3DTS_WORLD, &mtxRotateYPR);
238 
239   // Clear the back buffer and z buffer to transparent
240   g_pD3DDevice->Clear(0, NULL, D3DCLEAR_TARGET, ARGB_TRANS, 1.0f, 0);
241 
242   // Render scene
243   if(SUCCEEDED(g_pD3DDevice->BeginScene()))
244   {
245     // Draw the cube
246     g_pD3DDevice->SetStreamSource(0, g_pVB, 0, sizeof(CUSTOMVERTEX));
247     g_pD3DDevice->SetFVF(D3DFVF_XYZ|D3DFVF_NORMAL|D3DFVF_DIFFUSE);
248     g_pD3DDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2);
249     g_pD3DDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, 4, 2);
250     g_pD3DDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, 8, 2);
251     g_pD3DDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, 12, 2);
252     g_pD3DDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, 16, 2);
253     g_pD3DDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, 20, 2);
254     g_pD3DDevice->EndScene();
255   }
256 
257   // Update display
258   g_pD3DDevice->PresentEx(NULL, NULL, NULL, NULL, NULL);
259 }
260 
261 // +--------------+
262 // | WindowProc() |
263 // +--------------+------------------+
264 // | The main window message handler |
265 // +---------------------------------+
266 LRESULT WINAPI WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
267 {
268   switch(uMsg)
269   {
270     case WM_DESTROY:
271       // Signal application to terminate
272       PostQuitMessage(0);
273       return 0;
274         
275     case WM_KEYDOWN:
276       // If ESC has been pressed then signal window should close
277       if (LOWORD(wParam) == VK_ESCAPE) SendMessage(hWnd, WM_CLOSE, NULL, NULL);
278     break;
279     
280     case WM_LBUTTONDOWN:
281       // Trick OS into thinking we are dragging on title bar for any clicks on the main window
282       SendMessage(hWnd, WM_NCLBUTTONDOWN, HTCAPTION, NULL);
283       return TRUE;
284 
285     case WM_ERASEBKGND:
286       // We dont want to call render twice so just force Render() in WM_PAINT to be called
287       SendMessage(hWnd, WM_PAINT, NULL, NULL);
288       return TRUE;
289 
290     case WM_PAINT:
291       // Force a render to keep the window updated
292       Render();
293       return 0;
294   }
295 
296   return DefWindowProc(hWnd, uMsg, wParam, lParam);
297 }
298 
299 // +-----------+
300 // | WinMain() |
301 // +-----------+---------+
302 // | Program entry point |
303 // +---------------------+
304 INT WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, LPSTR, INT)
305 {
306   HWND       hWnd  = NULL;
307   MSG        uMsg;     
308   WNDCLASSEX wc    = {sizeof(WNDCLASSEX),              // cbSize
309                       NULL,                            // style
310                       WindowProc,                      // lpfnWndProc
311                       NULL,                            // cbClsExtra
312                       NULL,                            // cbWndExtra
313                       hInstance,                       // hInstance
314                       LoadIcon(NULL, IDI_APPLICATION), // hIcon
315                       LoadCursor(NULL, IDC_ARROW),     // hCursor
316                       NULL,                            // hbrBackground
317                       NULL,                            // lpszMenuName
318                       g_wcpAppName,                    // lpszClassName
319                       LoadIcon(NULL, IDI_APPLICATION)};// hIconSm
320 
321   RegisterClassEx(&wc);
322   hWnd = CreateWindowEx(WS_EX_COMPOSITED,             // dwExStyle
323                         g_wcpAppName,                 // lpClassName
324                         g_wcpAppName,                 // lpWindowName
325                         WS_POPUP | WS_SIZEBOX,        // dwStyle
326                         CW_USEDEFAULT, CW_USEDEFAULT, // x, y
327                         g_iWidth, g_iHeight,          // nWidth, nHeight
328                         NULL,                         // hWndParent
329                         NULL,                         // hMenu
330                         hInstance,                    // hInstance
331                         NULL);                        // lpParam
332 
333   // Extend glass to cover whole window
334   DwmExtendFrameIntoClientArea(hWnd, &g_mgDWMMargins);
335 
336   // Initialise Direct3D
337   if(SUCCEEDED(D3DStartup(hWnd)))
338   {
339     if(SUCCEEDED(CreateCube()))
340     {
341       // Show the window
342       ShowWindow(hWnd, SW_SHOWDEFAULT);
343       UpdateWindow(hWnd);
344                 
345       // Enter main loop
346       while(TRUE)
347       {
348         // Check for a message
349         if(PeekMessage(&uMsg, NULL, 0, 0, PM_REMOVE))
350         {
351           // Check if the message is WM_QUIT
352           if(uMsg.message == WM_QUIT)
353           {
354             // Break out of main loop
355             break;
356           }
357 
358           // Pump the message
359           TranslateMessage(&uMsg);
360           DispatchMessage(&uMsg);
361         }
362 
363         // Render a frame
364         Render();
365       }
366     }
367   }
368 
369   // Shutdown Direct3D
370   D3DShutdown();
371 
372   // Exit application
373   return 0;
374 }

 

posted @ 2014-10-20 22:00  BinSys  阅读(317)  评论(0编辑  收藏  举报