BBC BASIC for Windows
« DirectDraw - IDirectDraw.CreateSurface% »

Welcome Guest. Please Login or Register.
Apr 5th, 2018, 11:29pm



ATTENTION MEMBERS: Conforums will be closing it doors and discontinuing its service on April 15, 2018.
Ad-Free has been deactivated. Outstanding Ad-Free credits will be reimbursed to respective payment methods.

If you require a dump of the post on your message board, please come to the support board and request it.


Thank you Conforums members.

BBC BASIC for Windows Resources
Online BBC BASIC for Windows documentation
BBC BASIC for Windows Beginners' Tutorial
BBC BASIC Home Page
BBC BASIC on Rosetta Code
BBC BASIC discussion group
BBC BASIC for Windows Programmers' Reference

« Previous Topic | Next Topic »
Pages: 1  Notify Send Topic Print
 thread  Author  Topic: DirectDraw - IDirectDraw.CreateSurface%  (Read 1543 times)
Michael Hutton
Developer

member is offline

Avatar




PM

Gender: Male
Posts: 248
xx DirectDraw - IDirectDraw.CreateSurface%
« Thread started on: Dec 28th, 2009, 08:27am »

I know this is tedious but could some kind soul take a glance at the code below and see why I can't get IDirectDraw.CreateSurface% to work?

Code:
      
      MODE 8
      
      DDSCL_NORMAL = &8
      DDSD_CAPS = 1
      DDSCAPS_PRIMARYSURFACE = &200
      
      SYS "GetSystemMetrics", 0 TO xscreen%
      SYS "GetSystemMetrics", 1 TO yscreen%
      
      SYS "LoadLibrary", "DDRAW.DLL" TO ddraw%
      IF ddraw%=0 THEN ERROR 100, "Direct Draw not available"
      SYS "GetProcAddress", ddraw%, "DirectDrawCreateEx" TO `DirectDrawCreateEx`
      
      DIM IID_IDirectDraw7{a%, b%, c%, d%}
      IID_IDirectDraw7.a% = &15E65EC0
      IID_IDirectDraw7.b% = &11D23B9C
      IID_IDirectDraw7.c% = &60002FB9
      IID_IDirectDraw7.d% = &5BEA9797
      
      DIM IDirectDraw{QueryInterface%, AddRef%, Release%, Compact%, CreateClipper%, \
      \               CreatePalette%, CreateSurface%, DuplicateSurface%, \
      \               EnumDisplayModes%, EnumSurfaces%, FlipToGDISurface%, \
      \               GetCaps%, GetDisplayMode%, GetFourCCCodes%, GetGDISurface%, \
      \               GetMonitorFrequency%, GetScanLine%, GetVerticalBlankStatus%, \
      \               Initialize%, RestoreDisplayMode%, SetCooperativeLevel%, \
      \               SetDisplayMode%, WaitForVerticalBlank%}
      
      SYS `DirectDrawCreateEx`, 0, ^IDirectDraw%, IID_IDirectDraw7{}, 0
      !(^IDirectDraw{}+4) = !IDirectDraw%
      
      ON CLOSE PROC0 : QUIT
      ON ERROR PROC0 : SYS "MessageBox", @hwnd%, REPORT$, 0, 48 : QUIT
      
      REM Establish how DirectDraw will cooperate with GDI
      SYS IDirectDraw.SetCooperativeLevel%, IDirectDraw%, 0, DDSCL_NORMAL TO R%
      IF R% THEN ERROR 100,"Cannot set Cooperative Level "+STR$~R%
      
      DIM DDPIXELFORMAT{dwSize%,        \
      \                 dwFlags%,       \
      \                 dwFourCC%,      \
      \                 dwRGBBitCount%, \ Union!
      \                 dwRBitMask%,    \ Union!
      \                 dwGBitMask%,    \ Union!
      \                 dwBBitMask%,    \ Union!
      \                 dwRGBAlphaBitMask% } :REM Union!
      
      DIM DDCAPS{dwSize%, \
      \          dwCKeyCaps%, \
      \          dwPalCaps%, \
      \          dwBltCaps%, \
      \          dwAlphaCaps%, \
      \          dwOverlayCaps%, \
      \          dwVidMemTotal%, \
      \          dwVidMemFree%, \
      \          dwVidMemStride%, \
      \          dwMaxVisibleOverlays%, \
      \          dwCurrVisibleOverlays%, \
      \          dwNumFourCCCodes%, \
      \          dwAlignBoundarySrc%, \
      \          dwAlignSizeSrc%, \
      \          dwAlignBoundaryDest%, \
      \          dwAlignSizeDest%, \
      \          dwRops%, \ Possible error?
      \          dwMinOverlayStretch%, \
      \          dwMaxOverlayStretch%, \
      \          dwMiscCaps% }
      
      DIM ddsd{         dwSize%,      \
      \                 dwFlags%,     \
      \                 dwHeight%,    \
      \                 dwWidth%,     \
      \                 lPitch%,      \
      \                 lXPitch%,     \
      \                 dwBackBufferCount%, \
      \                 dwRefreshRate%,     \
      \                 lpSurface%,         \
      \                 ddckCKDestOverlay{l%,h%}, \
      \                 ddckCKDestBlt{l%,h%},     \
      \                 ddckCKSrcOverlay{l%,h%},  \
      \                 ddckCKSrcBlt{l%,h%},      \
      \                 pixelformat{} = DDPIXELFORMAT{},   \ possible error?
      \                 dwCaps%,                           \
      \                 dwSurfaceSize% }
      
      ddsd.dwSize% = DIM(ddsd{})
      ddsd.dwFlags% = DDSD_CAPS
      ddsd.dwCaps% = DDSCAPS_PRIMARYSURFACE
      
      SYS IDirectDraw.CreateSurface%, IDirectDraw%, ddsd{}, ^spSurface%, 0 TO R%
      IF R% THEN ERROR 100,"Cannot CreateSurface "+STR$~R%
      
      
      PROC0
      END
      
      DEF PROC0
      SYS IDirectDraw.Release%, IDirectDraw%
      SYS "FreeLibrary", ddraw%
      ENDPROC
      
 


I think the problem is related to my definition of the structures, but was wondering if anyone already has these definitions somewhere?

I am trying to translate http://www.codeproject.com/KB/mobile/CeScreenGrabber.aspx
"DirectDraw Screen Capture" - half way down the page.

Thank you,

Michael
User IP Logged

admin
Administrator
ImageImageImageImageImage


member is offline

Avatar




PM


Posts: 1145
xx Re: DirectDraw - IDirectDraw.CreateSurface%
« Reply #1 on: Dec 28th, 2009, 09:39am »

Quote:
I know this is tedious but could some kind soul take a glance at the code below and see why I can't get IDirectDraw.CreateSurface% to work?

The prototype for IDirectDraw7::CreateSurface is:

Code:
HRESULT CreateSurface(
    LPDDSURFACEDESC2 lpDDSurfaceDesc,         
    LPDIRECTDRAWSURFACE7 FAR *lplpDDSurface,  
    IUnknown FAR *pUnkOuter
); 

Note in particular that the first parameter is a pointer to a DDSURFACEDESC2 structure. As far as I can see, you're passing a DDSURFACEDESC structure (Windows Mobile and Windows CE only) instead.

I assume you realise that the IDirectDraw interface is obsolete? It isn't supported in DirectX8 or later and is available only for backwards compatibility with DirectX7. Strictly speaking you shouldn't be using it in 'new' projects.

Richard.
User IP Logged

Michael Hutton
Developer

member is offline

Avatar




PM

Gender: Male
Posts: 248
xx Re: DirectDraw - IDirectDraw.CreateSurface%
« Reply #2 on: Dec 29th, 2009, 01:24am »

Quote:
Note in particular that the first parameter is a pointer to a DDSURFACEDESC2 structure. As far as I can see, you're passing a DDSURFACEDESC structure (Windows Mobile and Windows CE only) instead.

Well, that would explain a bit..doh.
Quote:
I assume you realise that the IDirectDraw interface is obsolete? It isn't supported in DirectX8 or later and is available only for backwards compatibility with DirectX7. Strictly speaking you shouldn't be using it in 'new' projects.


Yes, I did realise but it was the only example I could find of capturing the Desktop. I was trying to get this to work and then was thinking of updating the code as and when I could. I am obviously intrested in speed... GetPixel is just way too slow..

I'll see where I get. Thanks for the reply.

Michael

User IP Logged

Michael Hutton
Developer

member is offline

Avatar




PM

Gender: Male
Posts: 248
xx Re: DirectDraw - IDirectDraw.CreateSurface%
« Reply #3 on: Dec 29th, 2009, 02:30am »

I seem to have got it working...

Code:
      
      MODE 8
      
      DDSCL_NORMAL = &8
      DDSD_CAPS = 1
      DDSCAPS_PRIMARYSURFACE = &200
      
      SYS "GetSystemMetrics", 0 TO xscreen%
      SYS "GetSystemMetrics", 1 TO yscreen%
      
      SYS "LoadLibrary", "DDRAW.DLL" TO ddraw%
      IF ddraw%=0 THEN ERROR 100, "Direct Draw not available"
      SYS "GetProcAddress", ddraw%, "DirectDrawCreateEx" TO `DirectDrawCreateEx`
      
      DIM IID_IDirectDraw7{a%, b%, c%, d%}
      IID_IDirectDraw7.a% = &15E65EC0
      IID_IDirectDraw7.b% = &11D23B9C
      IID_IDirectDraw7.c% = &60002FB9
      IID_IDirectDraw7.d% = &5BEA9797
      
      DIM IDirectDraw{QueryInterface%, AddRef%, Release%, Compact%, CreateClipper%, \
      \               CreatePalette%, CreateSurface%, DuplicateSurface%, \
      \               EnumDisplayModes%, EnumSurfaces%, FlipToGDISurface%, \
      \               GetCaps%, GetDisplayMode%, GetFourCCCodes%, GetGDISurface%, \
      \               GetMonitorFrequency%, GetScanLine%, GetVerticalBlankStatus%, \
      \               Initialize%, RestoreDisplayMode%, SetCooperativeLevel%, \
      \               SetDisplayMode%, WaitForVerticalBlank%}
      
      SYS `DirectDrawCreateEx`, 0, ^IDirectDraw%, IID_IDirectDraw7{}, 0
      !(^IDirectDraw{}+4) = !IDirectDraw%
      
      REM Apparently should give a pointer to the Primary Surface...
      REM PRINT IDirectDraw%
      REM PRINT !(IDirectDraw%+4)
      REM PRINT !(!(IDirectDraw%+4)+44)
      
      ON CLOSE PROC0 : QUIT
      ON ERROR PROC0 : SYS "MessageBox", @hwnd%, REPORT$, 0, 48 : QUIT
      
      REM Establish how DirectDraw will cooperate with GDI
      SYS IDirectDraw.SetCooperativeLevel%, IDirectDraw%, 0, DDSCL_NORMAL TO R%
      IF R% THEN ERROR 100,"Cannot set Cooperative Level "+STR$~R%
      
      DIM DDPIXELFORMAT{dwSize%,        \
      \                 dwFlags%,       \
      \                 dwFourCC%,      \
      \                 dwRGBBitCount%, \ Union!
      \                 dwRBitMask%,    \ Union!
      \                 dwGBitMask%,    \ Union!
      \                 dwBBitMask%,    \ Union!
      \                 dwRGBAlphaBitMask% } :REM Union!
      DIM DDSCAPS2{ \
      \ dwCaps%,  \
      \ dwCaps2%, \
      \ dwCaps3%, \
      \ dwCaps4% }
      
      DIM DDCAPS{dwSize%, \
      \          dwCKeyCaps%, \
      \          dwPalCaps%, \
      \          dwBltCaps%, \
      \          dwAlphaCaps%, \
      \          dwOverlayCaps%, \
      \          dwVidMemTotal%, \
      \          dwVidMemFree%, \
      \          dwVidMemStride%, \
      \          dwMaxVisibleOverlays%, \
      \          dwCurrVisibleOverlays%, \
      \          dwNumFourCCCodes%, \
      \          dwAlignBoundarySrc%, \
      \          dwAlignSizeSrc%, \
      \          dwAlignBoundaryDest%, \
      \          dwAlignSizeDest%, \
      \          dwRops%, \
      \          dwMinOverlayStretch%, \
      \          dwMaxOverlayStretch%, \
      \          dwMiscCaps% }
      
      
      DIM ddsd{                  \
      \          dwSize%,                   \
      \          dwFlags%,                  \
      \          dwHeight%,                 \
      \          dwWidth%,                  \
      \          dwPitchOrLinearSize%,      \
      \          dwBackBufferCount%,        \
      \          dwMipMapCount%,            \
      \          dwAlphaBitDepth%,          \
      \          dwReserved%,               \
      \          lpSurface%,                \
      \          ddckCKDestOverlay{l%,h%},  \
      \          ddckCKDestBlt{l%,h%},      \
      \          ddckCKSrcOverlay{l%,h%},   \
      \          ddckCKSrcBlt{l%,h%},       \
      \          ddpfPixelFormat{} = DDPIXELFORMAT{}, \
      \          ddsCaps{} = DDSCAPS2{},    \
      \          dwTextureStage%  }
      
      
      ddsd.dwSize% = DIM(ddsd{})
      ddsd.dwFlags% = DDSD_CAPS
      ddsd.ddsCaps.dwCaps% = DDSCAPS_PRIMARYSURFACE
      
      SYS IDirectDraw.CreateSurface%, IDirectDraw%, ddsd{}, ^spSurface%, 0 TO R%
      IF R% THEN ERROR 100,"Cannot CreateSurface "+STR$~R%
      
      PROC0
      END
      
      DEF PROC0
      SYS IDirectDraw.Release%, IDirectDraw%
      SYS "FreeLibrary", ddraw%
      ENDPROC
      
 


I'll keep people posted (if they are interested!)
User IP Logged

admin
Administrator
ImageImageImageImageImage


member is offline

Avatar




PM


Posts: 1145
xx Re: DirectDraw - IDirectDraw.CreateSurface%
« Reply #4 on: Dec 29th, 2009, 09:02am »

Quote:
Yes, I did realise but it was the only example I could find of capturing the Desktop.... GetPixel is just way too slow.

What exactly are you trying to do? If you want to read pixels from the desktop quickly, why not simply BitBlt the entire desktop DC into a DIBSection? No need for anything complicated like DirectDraw or DirectX!

Richard.
User IP Logged

Michael Hutton
Developer

member is offline

Avatar




PM

Gender: Male
Posts: 248
xx Re: DirectDraw - IDirectDraw.CreateSurface%
« Reply #5 on: Jan 2nd, 2010, 03:25am »

Quote:
What exactly are you trying to do? If you want to read pixels from the desktop quickly, why not simply BitBlt the entire desktop DC into a DIBSection? No need for anything complicated like DirectDraw or DirectX!


My aim was to capture the desktop, modify it, and then BitBlt it back, many frames a second. I will do some 'speed tests' on BitBlt. I have been away for the new year. I suppose I was slightly enamoured by the potential of directly accessing the primary surface (monitor) through DDRAW. I realise it is depreciated.

Michael
User IP Logged

admin
Administrator
ImageImageImageImageImage


member is offline

Avatar




PM


Posts: 1145
xx Re: DirectDraw - IDirectDraw.CreateSurface%
« Reply #6 on: Jan 2nd, 2010, 09:46am »

Quote:
My aim was to capture the desktop, modify it, and then BitBlt it back, many frames a second.

Write to the desktop DC? Can you even do that on Vista/Windows 7? I would have anticipated you would hit security restrictions in attempting that (unless running as an administrator) but I've not tried it.

Can't you achieve what you want by overlaying a transparent (layered) window on the desktop, and drawing to that? There have been several previous examples of doing that in BB4W.

Richard.
User IP Logged

Michael Hutton
Developer

member is offline

Avatar




PM

Gender: Male
Posts: 248
xx Re: DirectDraw - IDirectDraw.CreateSurface%
« Reply #7 on: Jan 4th, 2010, 02:47am »

Quote:
Write to the desktop DC? Can you even do that on Vista/Windows 7?


Code:
      MODE 8
      SYS "GetSystemMetrics", 0 TO xscreen%
      SYS "GetSystemMetrics", 1 TO yscreen%
      
      SYS "CreateDC", "DISPLAY", 0, 0, 0 TO hdcScreen%
      SYS "CreateCompatibleDC", hdcScreen% TO hdcCompatible%
      SYS "CreateCompatibleBitmap", hdcScreen%, xscreen%, yscreen% TO hbitmap%
      SYS "SelectObject", hdcCompatible%, hbitmap% TO oldbm%
      
      
      REPEAT
        SYS "BitBlt", hdcCompatible%, 0, 0, xscreen%, yscreen%, hdcScreen%, 0, 0, &CC0020 TO R%
        IF R% = 0 THEN  ERROR 100, "Failed to BitBlt"
        
        CIRCLE FILL RND(1280), RND(1024), RND(100)
        
        SYS "BitBlt", hdcScreen%, 0,0, 640, 512, @memhdc%, 0, 0,  &CC0020 TO R%
        IF R% = 0 THEN  ERROR 100, "Failed to BitBlt"
        
       
      UNTIL FALSE
 

(Obviously - no cleanup code)

Works on my Vista Ultimate x64 edition. Which did rather surprise me, and you can draw to the desktop DC with SYS "LineTo" @desktopDC%, X%, Y%. So access seems pretty free. I am interested to see if DirectX/DDRAW provides a faster way of interacting with it.

Michael
User IP Logged

Michael Hutton
Developer

member is offline

Avatar




PM

Gender: Male
Posts: 248
xx Re: DirectDraw - IDirectDraw.CreateSurface%
« Reply #8 on: Jul 28th, 2015, 7:41pm »

Oh! ...and this also works with Windows 8 (v6).

Forgot about this.

Michael

User IP Logged

Pages: 1  Notify Send Topic Print
« Previous Topic | Next Topic »

| |

This forum powered for FREE by Conforums ©
Terms of Service | Privacy Policy | Conforums Support | Parental Controls