DirectX is a group of low-level application programs of application programming interface (API) for creating games and other demanding multimedia applications. It includes support for 2D and 3D graphics, sound and music, input, and network communication for applications such as multiplayer games. DirectX is over the layer of the operating system Microsoft Windows; this means that the programmer can use 32 bit memory addressing (no longer the old 16 bit one) for writing into Segment, Offset, a flat memory model, where memory is available from 0 to MAX, where 'MAX' is the maximum size of this memory. At present, there is a current release 7.0 containing also support for new technologies, like for example 3D sound, hardware transformation of objects and light (T&L), support of 3DNOW! commands.
DirectX contains the following components:
Here is an example of DirectX application for Delphi and DirectX in release 7:
| uses
uses Windows, Messages, DirectDraw, SysUtils; {$R *.res} const //--------------------------------------------------------------------------- // Local definitions //--------------------------------------------------------------------------- NAME : PChar = 'DDExample1'; TITLE : PChar = 'Direct Draw Example 1'; //--------------------------------------------------------------------------- // Default settings //--------------------------------------------------------------------------- TIMER_ID = 1; TIMER_RATE = 500; var //--------------------------------------------------------------------------- // Global data //--------------------------------------------------------------------------- g_pDD : IDirectDraw7; // DirectDraw objekt g_pDDSPrimary : IDirectDrawSurface7; // DirectDraw primary surface g_pDDSBack : IDirectDrawSurface7; // DirectDraw back surface g_bActive : Boolean = False; // Is application active? //--------------------------------------------------------------------------- // Local data //--------------------------------------------------------------------------- szMsg : PChar = 'Page Flipping Test: Press F12 to exit'; szFrontMsg : PChar = 'Front buffer (F12 to quit)'; szBackMsg : PChar = 'Back buffer (F12 to quit)'; //----------------------------------------------------------------------------- // Name: ReleaseAllObjects // Desc: Finished with all objects we use; release them //----------------------------------------------------------------------------- procedure ReleaseAllObjects; begin if Assigned(g_pDD) then begin if Assigned(g_pDDSBack) then begin g_pDDSBack := nil; end; if Assigned(g_pDDSPrimary) then begin g_pDDSPrimary := nil; end; g_pDD := nil; end; end; //----------------------------------------------------------------------------- // Name: InitFail // Desc: This function is called if an initialization function fails //----------------------------------------------------------------------------- function InitFail(h_Wnd : HWND; hRet : HRESULT; Text : string) : HRESULT; begin ReleaseAllObjects; MessageBox(h_Wnd, PChar(Text + ': ' + DDErrorString(hRet)), TITLE, MB_OK); DestroyWindow(h_Wnd); Result := hRet; end; //----------------------------------------------------------------------------- // Name: UpdateFrame // Desc: Displays the proper text for the page //----------------------------------------------------------------------------- var phase : Boolean = False; procedure UpdateFrame(h_Wnd : HWND); var h_DC : HDC; ddbltfx : TDDBltFx; rc : TRect; size : TSize; begin // Use the blter to do a color fill to clear the back buffer FillChar(ddbltfx, SizeOf(ddbltfx), 0); ddbltfx.dwSize := SizeOf(ddbltfx); ddbltfx.dwFillColor := 0; g_pDDSBack.Blt(nil, nil, nil, DDBLT_COLORFILL or DDBLT_WAIT, @ddbltfx); if g_pDDSBack.GetDC(h_DC) = DD_OK then begin SetBkColor(h_DC, RGB(0, 0, 255)); SetTextColor(h_DC, RGB(255, 255, 0)); if phase then begin GetClientRect(h_Wnd, rc); GetTextExtentPoint(h_DC, szMsg, StrLen(szMsg), size); TextOut(h_DC, (rc.right - size.cx) div 2, (rc.bottom - size.cy) div 2, szMsg, StrLen(szMsg)); TextOut(h_DC, 0, 0, szFrontMsg, StrLen(szFrontMsg)); phase := False; end else begin TextOut(h_DC, 0, 0, szBackMsg, StrLen(szBackMsg)); phase := True; end; g_pDDSBack.ReleaseDC(h_DC); end; end; //----------------------------------------------------------------------------- // Name: WindowProc // Desc: The Main Window Procedure //----------------------------------------------------------------------------- function WindowProc(h_Wnd: HWND; aMSG: Cardinal; wParam: Cardinal; lParam: Integer) : Integer; stdcall; var hRet : HRESULT; begin case aMSG of // Pause if minimized WM_ACTIVATE: begin if HIWORD(wParam) = 0 then g_bActive := True else g_bActive := False; Result := 0; Exit; end; // Clean up and close the app WM_DESTROY: begin ReleaseAllObjects; PostQuitMessage(0); Result := 0; Exit; end; // Handle any non-accelerated key commands WM_KEYDOWN: begin case wParam of VK_ESCAPE, VK_F12: begin PostMessage(h_Wnd, WM_CLOSE, 0, 0); Result := 0; Exit; end; end; end; // Turn off the cursor since this is a full-screen app WM_SETCURSOR: begin SetCursor(0); Result := 1; Exit; end; // Update and flip surfaces WM_TIMER: begin if g_bActive and (TIMER_ID = wParam) then begin UpdateFrame(h_Wnd); while True do begin hRet := g_pDDSPrimary.Flip(nil, 0); if hRet = DD_OK then Break; if hRet = DDERR_SURFACELOST then begin hRet := g_pDDSPrimary._Restore; if hRet <> DD_OK then Break; end; if hRet <> DDERR_WASSTILLDRAWING then Break; end; end; end; end; Result := DefWindowProc(h_Wnd, aMSG, wParam, lParam); end; //----------------------------------------------------------------------------- // Name: InitApp // Desc: Do work required for every instance of the application: // Create the window, initialize data //----------------------------------------------------------------------------- function InitApp(hInst : THANDLE; nCmdShow : Integer) : HRESULT; var h_Wnd : HWND; wc : WNDCLASS; ddsd : TDDSurfaceDesc2; ddscaps : TDDSCaps2; hRet : HRESULT; pDDTemp : IDirectDraw; begin // Set up and register window class wc.style := CS_HREDRAW or CS_VREDRAW; wc.lpfnWndProc := @WindowProc; wc.cbClsExtra := 0; wc.cbWndExtra := 0; wc.hInstance := hInst; wc.hIcon := LoadIcon(hInst, 'MAINICON'); wc.hCursor := LoadCursor(0, IDC_ARROW); wc.hbrBackground := GetStockObject(BLACK_BRUSH); wc.lpszMenuName := NAME; wc.lpszClassName := NAME; RegisterClass(wc); // Create a window h_Wnd := CreateWindowEx(WS_EX_TOPMOST, NAME, TITLE, WS_POPUP, 0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN), 0, 0, hInst, nil); if h_Wnd = 0 then begin Result := 0; Exit; end; ShowWindow(h_Wnd, nCmdShow); UpdateWindow(h_Wnd); SetFocus(h_Wnd); /////////////////////////////////////////////////////////////////////////// // Create the main DirectDraw object /////////////////////////////////////////////////////////////////////////// hRet := DirectDrawCreate(nil, pDDTemp, nil); if hRet <> DD_OK then begin Result := InitFail(h_Wnd, hRet, 'DirectDrawCreate FAILED'); Exit; end; hRet := pDDTemp.QueryInterface(IDirectDraw7, g_pDD); if hRet <> DD_OK then begin Result := InitFail(h_Wnd, hRet, 'QueryInterface FAILED'); Exit; end; pDDTemp := nil; // Adjust called "Exclusive mode" hRet := g_pDD.SetCooperativeLevel(h_Wnd, DDSCL_EXCLUSIVE or DDSCL_FULLSCREEN); if hRet <> DD_OK then begin Result := InitFail(h_Wnd, hRet, 'SetCooperativeLevel FAILED'); Exit; end; // Adjust 640x480x8 hRet := g_pDD.SetDisplayMode(640, 480, 8, 0, 0); if hRet <> DD_OK then begin Result := InitFail(h_Wnd, hRet, 'SetDisplayMode FAILED'); Exit; end; // Create primary surface with one back buffer FillChar(ddsd, SizeOf(ddsd), 0); ddsd.dwSize := SizeOf(ddsd); ddsd.dwFlags := DDSD_CAPS or DDSD_BACKBUFFERCOUNT; ddsd.ddsCaps.dwCaps := DDSCAPS_PRIMARYSURFACE or DDSCAPS_FLIP or DDSCAPS_COMPLEX; ddsd.dwBackBufferCount := 1; hRet := g_pDD.CreateSurface(ddsd, g_pDDSPrimary, nil); if hRet <> DD_OK then begin Result := InitFail(h_Wnd, hRet, 'CreateSurface FAILED'); Exit; end; // Find director na back buffer FillChar(ddscaps, SizeOf(ddscaps), 0); ddscaps.dwCaps := DDSCAPS_BACKBUFFER; hRet := g_pDDSPrimary.GetAttachedSurface(ddscaps, g_pDDSBack); if hRet <> DD_OK then begin Result := InitFail(h_Wnd, hRet, 'GetAttachedSurface FAILED'); Exit; end; // Create timer on changing pages if TIMER_ID <> SetTimer(h_Wnd, TIMER_ID, TIMER_RATE, nil) then begin Result := InitFail(h_Wnd, hRet, 'SetTimer FAILED'); Exit; end; Result := DD_OK; end; var aMSG : MSG; begin if InitApp(GetModuleHandle(nil), SW_SHOW) <> DD_OK then begin Exit; end; while GetMessage(aMSG, 0, 0, 0) do begin TranslateMessage(aMSG); DispatchMessage(aMSG); end; end. |
Used sources:
Microsoft SDK Help for DirectX7,
Microsoft help file, 20.September 1999