Results 1 to 3 of 3

Thread: Trying to create overlays with DirectX

  1. #1

    Trying to create overlays with DirectX

    Hello,

    I am trying to create a surface to draw overlays with DirectX, but it always fails on the CreateSurface function with the error $88760091, that according to my google search means Invalid Pixel Format.

    But I tested lot's of different pixel formats and I can't find one that works. Any ideas? here is my code, thanks

    Code:
    function InitOverlays(vPluginData: TPluginData; var DebugInfo: Cardinal): Cardinal;
    var
      ddsd, ddsdOverlay: DDSURFACEDESC2;
      ddrval: HRESULT;
      capsDrv: TDDCaps;
      pixelFormat: DDPIXELFORMAT;
    begin
      Result := VMG_DXFUNCTIONFAILED;
      DebugInfo := 0;
    
      { Init DirectDraw }
      
      ddrval := DirectDrawCreateEx(nil, g_lpdd, IID_IDirectDraw7, nil);
      if ddrval <> DD_OK then
      begin
        DebugInfo &#58;= $1;
        Exit;
      end;
    
      &#123; For NORMAL cooperative level we no longer need to provide an HWND &#125;
      
      ddrval &#58;= g_lpdd.SetCooperativeLevel&#40;0, DDSCL_NORMAL&#41;;
      if ddrval <> DD_OK then
      begin
        DebugInfo &#58;= $2;
        Exit;
      end;
    
      if g_lpdd = nil then
      begin
        DebugInfo &#58;= $3;
        Exit;
      end;
    
      &#123; Create the primary surface &#125;
      
      FillChar&#40;ddsd, sizeof&#40;ddsd&#41;, #0&#41;;
      ddsd.dwSize &#58;= sizeof&#40;ddsd&#41;;
      ddsd.dwFlags &#58;= DDSD_CAPS;
      ddsd.ddsCaps.dwCaps &#58;= DDSCAPS_PRIMARYSURFACE;
      ddrval &#58;= g_lpdd.CreateSurface&#40;ddsd, g_lpddsPrimary, nil&#41;;
    
      if ddrval <> DD_OK then
      begin
        DebugInfo &#58;= $4;
        Exit;
      end;
    
      &#123; Get driver capabilities to determine Overlay support &#125;
      
      FillChar&#40;capsDrv, sizeof&#40;capsDrv&#41;, #0&#41;;
      capsDrv.dwSize &#58;= sizeof&#40;capsDrv&#41;;
      ddrval &#58;= g_lpdd.GetCaps&#40;@capsDrv, nil&#41;;
    
      if ddrval <> DD_OK  then
      begin
        DebugInfo &#58;= $5;
        Exit;
      end;
      
      &#123; Does the driver support overlays in the current mode?
        &#40;Currently the DirectDraw emulation layer does not support overlays.
        Overlay related APIs will fail without hardware support&#41; &#125;
        
      Result &#58;= VMG_NOSUPPORTFOROVERLAYS;
    
      if &#40;capsDrv.dwCaps and DDCAPS_OVERLAY&#41; = 0 then
      begin
        DebugInfo &#58;= $B;
        Exit;
      end;
    
      &#123; Setup the overlay surface &#125;
    
      FillChar&#40;ddsdOverlay, sizeof&#40;ddsdOverlay&#41;, #0&#41;;
      ddsdOverlay.dwSize &#58;= sizeof&#40;ddsdOverlay&#41;;
      ddsdOverlay.dwFlags &#58;= DDSD_CAPS or DDSD_HEIGHT or DDSD_WIDTH or DDSD_PIXELFORMAT;
      ddsdOverlay.dwBackBufferCount &#58;= 0;
      ddsdOverlay.dwWidth &#58;= vPluginData.DesktopWidth;
      ddsdOverlay.dwHeight &#58;= vPluginData.DesktopHeight;
      ddsdOverlay.ddsCaps.dwCaps &#58;= DDSCAPS_OVERLAY or DDSCAPS_VIDEOMEMORY;
    
      pixelFormat.dwSize &#58;= SizeOf&#40;pixelFormat&#41;;
      pixelFormat.dwFlags &#58;= DDPF_RGB;
      pixelFormat.dwFourCC &#58;= 0;
      pixelFormat.dwRGBBitCount &#58;= 32;
      pixelFormat.dwRBitMask &#58;= $00FF0000;
      pixelFormat.dwGBitMask &#58;= $0000FF00;
      pixelFormat.dwBBitMask &#58;= $000000FF;
      pixelFormat.dwRGBAlphaBitMask &#58;= $00000000;
    
      // TODO&#58;  should match the screen output color depth
      //DDPIXELFORMAT pixelFormat =
      //    &#123;sizeof&#40;DDPIXELFORMAT&#41;, DDPF_RGB, 0, 32, 0x00FF0000, 0x0000FF00, 0x000000FF, 0&#125;;
      ddsdOverlay.ddpfPixelFormat &#58;= pixelFormat;
      ddrval &#58;= g_lpdd.CreateSurface&#40;ddsdOverlay, g_lpddsOverlay, nil&#41;;
    
      if ddrval <> DD_OK then //// Will enter this block, so here is the failure
      begin
        DebugInfo &#58;= ddrval;
        Exit;
      end;
      
      if &#40;g_lpddsOverlay = nil&#41; then
      begin
        DebugInfo &#58;= $D;
        Exit;
      end;
    
    //  mPrimaryMonitorRect &#58;= System&#58;&#58;getPrimaryMonitorRect&#40;&#41;;
    
      Result &#58;= VMG_NOERROR;
    end;

  2. #2

    Trying to create overlays with DirectX

    After lot's and lot's of hours researching and testing and debuging I found out that my Video Card doesnt support RGB modes for overlays, only YUV modes

    Here is a trvial program that works correctly with overlays:

    Code:
    program overlay;
    
    &#123;$mode objfpc&#125;&#123;$H+&#125;
    
    uses
      Classes, SysUtils,
      Windows, DirectDraw;
    
    &#123; Global Variables &#125;
    var
      &#123; DirectX variables &#125;
      g_lpdd&#58; IDirectDraw7 = nil;
      g_lpddsPrimary&#58; IDirectDrawSurface7 = nil;
      g_lpddsOverlay&#58; IDirectDrawSurface7 = nil;
      g_lpClipper&#58; IDirectDrawClipper = nil;
      
      mTimerID&#58; THandle = 0;
    
      DebugLoc, DebugInfo&#58; Cardinal;
    
      ddrval&#58; HRESULT;
    
    &#123;*******************************************************************
    *  InitOverlays &#40;&#41;
    *******************************************************************&#125;
    function InitOverlays&#58; Boolean;
    var
      ddsd, ddsdOverlay&#58; DDSURFACEDESC2;
      capsDrv&#58; TDDCaps;
      pixelFormat&#58; DDPIXELFORMAT;
    begin
      Result &#58;= False;
      DebugInfo &#58;= 0;
      DebugLoc &#58;= 0;
    
      &#123; Init DirectDraw &#125;
    
      ddrval &#58;= DirectDrawCreateEx&#40;nil, g_lpdd, IID_IDirectDraw7, nil&#41;;
      if ddrval <> DD_OK then
      begin
        DebugLoc &#58;= $1;
        Exit;
      end;
    
      &#123; For NORMAL cooperative level we no longer need to provide an HWND &#125;
    
      ddrval &#58;= g_lpdd.SetCooperativeLevel&#40;0, DDSCL_NORMAL&#41;;
      if ddrval <> DD_OK then
      begin
        DebugLoc &#58;= $2;
        Exit;
      end;
    
      if g_lpdd = nil then
      begin
        DebugLoc &#58;= $3;
        Exit;
      end;
    
      &#123; Create the primary surface &#125;
    
      FillChar&#40;ddsd, sizeof&#40;ddsd&#41;, #0&#41;;
      ddsd.dwSize &#58;= sizeof&#40;ddsd&#41;;
      ddsd.dwFlags &#58;= DDSD_CAPS;
      ddsd.ddsCaps.dwCaps &#58;= DDSCAPS_PRIMARYSURFACE;
      ddrval &#58;= g_lpdd.CreateSurface&#40;ddsd, g_lpddsPrimary, nil&#41;;
    
      if ddrval <> DD_OK then
      begin
        DebugLoc &#58;= $4;
        Exit;
      end;
    
      &#123; Get driver capabilities to determine Overlay support &#125;
    
      FillChar&#40;capsDrv, sizeof&#40;capsDrv&#41;, #0&#41;;
      capsDrv.dwSize &#58;= sizeof&#40;capsDrv&#41;;
      ddrval &#58;= g_lpdd.GetCaps&#40;@capsDrv, nil&#41;;
    
      if ddrval <> DD_OK  then
      begin
        DebugLoc &#58;= $5;
        Exit;
      end;
    
      &#123; Does the driver support overlays in the current mode?
        &#40;Currently the DirectDraw emulation layer does not support overlays.
        Overlay related APIs will fail without hardware support&#41; &#125;
    
      if &#40;capsDrv.dwCaps and DDCAPS_OVERLAY&#41; = 0 then
      begin
        DebugLoc &#58;= $B;
        Exit;
      end;
    
      &#123; Setup the overlay surface &#125;
    
      &#123; Init Direct3D &#125;
    
      FillChar&#40;ddsdOverlay, sizeof&#40;ddsdOverlay&#41;, #0&#41;;
      ddsdOverlay.dwSize &#58;= sizeof&#40;ddsdOverlay&#41;;
      ddsdOverlay.dwFlags &#58;= DDSD_CAPS or DDSD_HEIGHT or DDSD_WIDTH or DDSD_PIXELFORMAT;
      ddsdOverlay.dwBackBufferCount &#58;= 0;
      ddsdOverlay.dwWidth &#58;= 800;
      ddsdOverlay.dwHeight &#58;= 720;
      ddsdOverlay.ddsCaps.dwCaps &#58;= DDSCAPS_OVERLAY or DDSCAPS_VIDEOMEMORY;
    
      pixelFormat.dwSize &#58;= SizeOf&#40;pixelFormat&#41;;
      PixelFormat.dwFlags &#58;= DDPF_FOURCC;
      PixelFormat.dwFourCC &#58;= DWORD&#40;Byte&#40;'U'&#41; or &#40;Byte&#40;'Y'&#41; shl 8&#41; or &#40;Byte&#40;'V'&#41; shl 16&#41; or &#40;Byte&#40;'Y'&#41; shl 24&#41;&#41;;
      PixelFormat.dwYUVBitCount &#58;= 16;
    
    &#123;  pixelFormat.dwFlags &#58;= DDPF_RGBTOYUV;
      pixelFormat.dwFourCC &#58;= 0;  &#125;
    
     &#123; pixelFormat.dwRGBBitCount &#58;= 16;
      pixelFormat.dwRBitMask &#58;= $7C00;
      pixelFormat.dwGBitMask &#58;= $03E0;
      pixelFormat.dwBBitMask &#58;= $001F; &#125;
    
    &#123;  pixelFormat.dwRgbBitCount &#58;= 16;
      pixelFormat.dwRBitMask &#58;= $F800;
      pixelFormat.dwGBitMask &#58;= $07E0;
      pixelFormat.dwBBitMask &#58;= $001F; &#125;
    
    &#123;  pixelFormat.dwRGBBitCount &#58;= 32;
      pixelFormat.dwRBitMask &#58;= $000000FF;
      pixelFormat.dwGBitMask &#58;= $0000FF00;
      pixelFormat.dwBBitMask &#58;= $00FF0000; &#125;
    
      // TODO&#58;  should match the screen output color depth
      //DDPIXELFORMAT pixelFormat =
      //    &#123;sizeof&#40;DDPIXELFORMAT&#41;, DDPF_RGB, 0, 32, 0x00FF0000, 0x0000FF00, 0x000000FF, 0&#125;;
      ddsdOverlay.ddpfPixelFormat &#58;= pixelFormat;
      ddrval &#58;= g_lpdd.CreateSurface&#40;ddsdOverlay, g_lpddsOverlay, nil&#41;;
    
      if ddrval <> DD_OK then
      begin
        DebugLoc &#58;= $C;
        DebugInfo &#58;= ddrval;
        Exit;
      end;
    
      if &#40;g_lpddsOverlay = nil&#41; then
      begin
        DebugLoc &#58;= $D;
        Exit;
      end;
    
      &#123; Create a clipper for our window &#125;
      ddrval &#58;= g_lpdd.CreateClipper&#40;0, g_lpClipper, nil&#41;;
      if ddrval <> DD_OK then
      begin
        DebugLoc &#58;= $E;
        Exit;
      end;
    
    //  ddrval = IDirectDrawClipper_SetHWnd&#40;lpClipper, 0, hwnd&#41;;
    
      Result &#58;= True;
    end;
    
    function WndProc&#40;ahWnd&#58; HWND; amessage&#58; UINT; awParam&#58; WPARAM; alParam&#58; LPARAM&#41;&#58; LResult; stdcall;
    var
      wmId, wmEvent&#58; Integer;
      ps&#58; PAINTSTRUCT;
      MyDC&#58; HDC;
      ptClient&#58; POINT;
      rectBlt&#58; RECT;
      addbfx&#58; DDBltFX;
    begin
      Result &#58;= 0;
    
      case amessage of
        WM_PAINT&#58;
        begin
          &#123; Attach the clipper to the primary surface for this operation &#125;
    
    //      ddrval &#58;= g_lpddsPrimary.SetClipper&#40;g_lpClipper&#41;;
    
          MyDC &#58;= BeginPaint&#40;ahWnd, @ps&#41;;
    
          &#123; Fill the client area with colour key &#125;
    
          ptClient.x &#58;= ps.rcPaint.left;
          ptClient.y &#58;= ps.rcPaint.top;
          ClientToScreen&#40;GetDesktopWindow, @ptClient&#41;;
          rectBlt.left &#58;= ptClient.x;
          rectBlt.top &#58;= ptClient.y;
    
          ptClient.x &#58;= ps.rcPaint.right;
          ptClient.y &#58;= ps.rcPaint.bottom;
          ClientToScreen&#40;GetDesktopWindow, @ptClient&#41;;
          rectBlt.right &#58;= ptClient.x;
          rectBlt.bottom &#58;= ptClient.y;
    
          addbfx.dwSize &#58;= sizeof&#40;DDBLTFX&#41;;
          addbfx.dwFillColor &#58;= 0;
    
          g_lpddsPrimary.Blt&#40;
           @rectBlt, nil, @rectBlt, DDBLT_COLORFILL or DDBLT_WAIT, @addbfx&#41;;
    
          EndPaint&#40;ahWnd, @ps&#41;;
    
    //      ddrval &#58;= g_lpddsPrimary.SetClipper&#40;nil&#41;;
        end;
       
       WM_DESTROY&#58;
         PostQuitMessage&#40;0&#41;;
      else
        Result &#58;= DefWindowProc&#40;ahWnd, amessage, awParam, alParam&#41;;
      end;
    end;
    
    procedure CreateMainWindow;
    var
      wcex&#58; WNDCLASSEX;
      ahwnd&#58; HWND;
    begin
      FillChar&#40;wcex, sizeof&#40;wcex&#41;, #0&#41;;
      wcex.cbSize &#58;= sizeof&#40;WNDCLASSEX&#41;;
    
      wcex.style		&#58;= CS_HREDRAW or CS_VREDRAW;
      wcex.lpfnWndProc	&#58;= @WndProc;
      wcex.cbClsExtra	&#58;= 0;
      wcex.cbWndExtra	&#58;= 0;
      wcex.hInstance	&#58;= hInstance;
    //  wcex.hIcon		&#58;= LoadIcon&#40;hInstance, MAKEINTRESOURCE&#40;IDI_OVERLAY&#41;&#41;;
      wcex.hCursor		&#58;= LoadCursor&#40;0, IDC_ARROW&#41;;
      wcex.hbrBackground	&#58;= &#40;COLOR_WINDOW+1&#41;;
      wcex.lpszClassName	&#58;= 'OVERLAYS';
    //  wcex.hIconSm		&#58;= LoadIcon&#40;wcex.hInstance, MAKEINTRESOURCE&#40;IDI_SMALL&#41;&#41;;
    
      RegisterClassEx&#40;@wcex&#41;;
    
      ahWnd &#58;= CreateWindow&#40;'OVERLAYS', 'Titulo', WS_OVERLAPPEDWINDOW,
       CW_USEDEFAULT, CW_USEDEFAULT, 100, 100, 0, 0, hInstance, nil&#41;;
    
       ShowWindow&#40;ahWnd, SW_SHOWNORMAL&#41;;
       UpdateWindow&#40;ahWnd&#41;;
    end;
    
    procedure ShowError;
    begin
      Windows.MessageBox&#40;0, PChar&#40;'Loc&#58; ' + IntToHex&#40;DebugLoc, 8&#41; + ' Info&#58; ' + IntToHex&#40;DebugInfo, 8&#41;&#41;, 'Titulo', MB_ICONEXCLAMATION + MB_OK&#41;;
    end;
    
    var
      Msg&#58; TMsg;
    begin
      if not InitOverlays&#40;&#41; then ShowError;
    
      CreateMainWindow&#40;&#41;;
    
      while Windows.GetMessage&#40;@Msg, 0, 0, 0&#41; do
      begin
        Windows.TranslateMessage&#40;@msg&#41;;
        Windows.DispatchMessage&#40;@msg&#41;;
      end;
    end.

  3. #3

    Trying to create overlays with DirectX

    Well done on solving the problem. Thanks for posting a demo app
    <A HREF="http://www.myhpf.co.uk/banner.asp?friend=139328">
    <br /><IMG SRC="http://www.myhpf.co.uk/banners/60x468.gif" BORDER="0">
    <br /></A>

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •