DirectX:Direct3D:Tutorials:Video
From GPWiki
The wiki is now hosted by GameDev.NET at wiki.gamedev.net. All gpwiki.org content has been moved to the new server. However, the GPWiki forums are still active! Come say hello. DirectDraw Game Programming is easy, all you have to know are a few simple steps. You will probably find it VERY useful to have the DirectX documentation handy while reading this (unless of course you are a DirectX guru already, in which case you shouldn't be reading this anyway) :)
///////////////////////COPY AND PASTE THIS CODE///////////////////////// // Get rid of crap we don't need from the windows library #ifndef WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN #endif //------------------------------------------------------- // Include files //------------------------------------------------------- #include <windows.h> #include <ddraw.h> #include <stdio.h> #include <stdarg.h> #include "resource.h" //----------------------------------------------------------------------------- // Local definitions //----------------------------------------------------------------------------- #define NAME "DDExample1" #define TITLE "Direct Draw Example 1" //----------------------------------------------------------------------------- // Default settings //----------------------------------------------------------------------------- #define TIMER_ID 1 #define TIMER_RATE 500 //----------------------------------------------------------------------------- // Global data //----------------------------------------------------------------------------- LPDIRECTDRAW7 g_pDD = NULL; // DirectDraw object LPDIRECTDRAWSURFACE7 g_pDDSPrimary = NULL;// DirectDraw primary surface LPDIRECTDRAWSURFACE7 g_pDDSBack = NULL; // DirectDraw back surface BOOL g_bActive = FALSE; // Is application active? //----------------------------------------------------------------------------- // Local data //----------------------------------------------------------------------------- static char szMsg[] = "Page Flipping Test: Press F12 to exit"; static char szFrontMsg[] = "Front buffer (F12 to quit)"; static char szBackMsg[] = "Back buffer (F12 to quit)"; //----------------------------------------------------------------------------- // Name: ReleaseAllObjects() // Desc: Finished with all objects we use; release them //----------------------------------------------------------------------------- static void ReleaseAllObjects(void) { if (g_pDD != NULL) { if (g_pDDSPrimary != NULL) { // Release the Primary DirectDraw surface by calling a COM method g_pDDSPrimary->Release(); g_pDDSPrimary = NULL; } g_pDD->Release(); g_pDD = NULL; } } //----------------------------------------------------------------------------- // Name: InitFail() // Desc: This function is called if an initialization function fails //----------------------------------------------------------------------------- HRESULT InitFail(HWND hWnd, HRESULT hRet, LPCTSTR szError,...) { char szBuff[128]; va_list vl; va_start(vl, szError); vsprintf(szBuff, szError, vl); ReleaseAllObjects(); // Message Box telling what the error is MessageBox(hWnd, szBuff, TITLE, MB_OK); DestroyWindow(hWnd); va_end(vl); return hRet; } //----------------------------------------------------------------------------- // Name: UpdateFrame() // Desc: Displays the proper text for the page //----------------------------------------------------------------------------- static void UpdateFrame(HWND hWnd) { static BYTE phase = 0; HDC hdc; DDBLTFX ddbltfx; RECT rc; SIZE size; // Use the blter to do a color fill to clear the back buffer ZeroMemory(&ddbltfx, sizeof(ddbltfx)); ddbltfx.dwSize = sizeof(ddbltfx); ddbltfx.dwFillColor = 0; g_pDDSBack->Blt(NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx); // Output different text depending on what phase the program is in if (g_pDDSBack->GetDC(&hdc) == DD_OK) { SetBkColor(hdc, RGB(0, 0, 255)); SetTextColor(hdc, RGB(255, 255, 0)); if (phase) { GetClientRect(hWnd, &rc); GetTextExtentPoint(hdc, szMsg, lstrlen(szMsg), &size); TextOut(hdc, (rc.right - size.cx) / 2, (rc.bottom - size.cy) / 2, szMsg, sizeof(szMsg) - 1); TextOut(hdc, 0, 0, szFrontMsg, lstrlen(szFrontMsg)); phase = 0; } else { TextOut(hdc, 0, 0, szBackMsg, lstrlen(szBackMsg)); phase = 1; } // ALWAYS release objects when you are finished with them g_pDDSBack->ReleaseDC(hdc); } } //----------------------------------------------------------------------------- // Name: WindowProc() // Desc: The Main Window Procedure //----------------------------------------------------------------------------- long FAR PASCAL WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { HRESULT hRet; switch (message) { case WM_ACTIVATE: // Pause if minimized g_bActive = !((BOOL)HIWORD(wParam)); return 0L; case WM_DESTROY: // Clean up and close the app ReleaseAllObjects(); PostQuitMessage(0); return 0L; case WM_KEYDOWN: // Handle any non-accelerated key commands switch (wParam) { case VK_ESCAPE: case VK_F12: PostMessage(hWnd, WM_CLOSE, 0, 0); return 0L; } break; case WM_SETCURSOR: // Turn off the cursor since this is a full-screen app SetCursor(NULL); return TRUE; case WM_TIMER: // Update and flip surfaces if (g_bActive && TIMER_ID == wParam) { UpdateFrame(hWnd); while (TRUE) { hRet = g_pDDSPrimary->Flip(NULL, 0); if (hRet == DD_OK) break; if (hRet == DDERR_SURFACELOST) { hRet = g_pDDSPrimary->Restore(); if (hRet != DD_OK) break; } if (hRet != DDERR_WASSTILLDRAWING) break; } } break; } return DefWindowProc(hWnd, message, wParam, lParam); } //----------------------------------------------------------------------------- // Name: InitApp() // Desc: Do work required for every instance of the application: // Create the window, initialize data //----------------------------------------------------------------------------- static HRESULT InitApp(HINSTANCE hInstance, int nCmdShow) { HWND hWnd; WNDCLASS wc; DDSURFACEDESC2 ddsd; DDSCAPS2 ddscaps; HRESULT hRet; // Set up and register window class wc.style = CS_HREDRAW | CS_VREDRAW; wc.lpfnWndProc = WindowProc; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = hInstance; wc.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_MAIN_ICON)); wc.hCursor = LoadCursor(NULL, IDC_ARROW); // Set the background colour to black wc.hbrBackground = (HBRUSH )GetStockObject(BLACK_BRUSH); wc.lpszMenuName = NAME; wc.lpszClassName = NAME; RegisterClass(&wc); // Create a window hWnd = CreateWindowEx(WS_EX_TOPMOST, NAME, TITLE, WS_POPUP, 0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN), NULL, NULL, hInstance, NULL); if (!hWnd) return FALSE; ShowWindow(hWnd, nCmdShow); UpdateWindow(hWnd); SetFocus(hWnd); /////////////////////////////////////////////////////////////////////////// // Create the main DirectDraw object /////////////////////////////////////////////////////////////////////////// hRet = DirectDrawCreateEx(NULL, (VOID**)&g_pDD, IID_IDirectDraw7, NULL); if (hRet != DD_OK) return InitFail(hWnd, hRet, "DirectDrawCreateEx FAILED"); // Get exclusive, fullscreen mode hRet = g_pDD->SetCooperativeLevel(hWnd, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN); if (hRet != DD_OK) return InitFail(hWnd, hRet, "SetCooperativeLevel FAILED"); // Set the video mode to 640x480x8(the extra 0s aren't necessary) hRet = g_pDD->SetDisplayMode(640, 480, 8, 0, 0); if (hRet != DD_OK) return InitFail(hWnd, hRet, "SetDisplayMode FAILED"); // Create the primary surface with 1 back buffer ZeroMemory(&ddsd, sizeof(ddsd)); ddsd.dwSize = sizeof(ddsd); ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT; // Set the capabilities of the primary surface ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_FLIP | DDSCAPS_COMPLEX; ddsd.dwBackBufferCount = 1; // Actually create the surface hRet = g_pDD->CreateSurface(&ddsd, &g_pDDSPrimary, NULL); if (hRet != DD_OK) return InitFail(hWnd, hRet, "CreateSurface FAILED"); // Get a pointer to the back buffer ZeroMemory(&ddscaps, sizeof(ddscaps)); ddscaps.dwCaps = DDSCAPS_BACKBUFFER; hRet = g_pDDSPrimary->GetAttachedSurface(&ddscaps, &g_pDDSBack); if (hRet != DD_OK) return InitFail(hWnd, hRet, "GetAttachedSurface FAILED"); // Create a timer to flip the pages if (TIMER_ID != SetTimer(hWnd, TIMER_ID, TIMER_RATE, NULL)) return InitFail(hWnd, hRet, "SetTimer FAILED"); return DD_OK; } //----------------------------------------------------------------------------- // Name: WinMain() // Desc: Initialization, message loop //----------------------------------------------------------------------------- int PASCAL WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { MSG msg; if (InitApp(hInstance, nCmdShow) != DD_OK) return FALSE; while (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } return msg.wParam; } ///////////////////////END OF PROGRAM CODE///////////////////////////////
Categories: C | DirectX | Tutorial |


