• Welcome to Powerbasic Museum 2020-B.
 

News:

Forum in repository mode. No new members allowed.

Main Menu

GLDrawDIB (rendering OpenGL to DIB)

Started by Patrice Terrier, October 04, 2008, 06:17:03 PM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

Patrice Terrier

This example shows you how to render OpenGL into a memory DIB using the low level GDI/GDIPLUS flat API.

Rendering to a DIB is more CPU intensive than using OpenGL directly with a window , because we have to copy each frame from video RAM to our memory bitmap.

However it opens very nice perspective to combine GDI/GDIPLUS/OPENGL and render them altogether into the same memory bitmap target, to create amazing effects "à la WPF".

To stop the demo, click the left mouse button on the animation, then press the ESCAPE key.

Better to run GLDrawDIB on VISTA Premium+ with Dual Core 2 processor.
When running on XP and older processor, change these contant values:

VISTA  ;D
%FRAME_SizeX = 256 '// The animation frame width
%FRAME_SizeY = 256 '// The animation frame height
%TIMER_DELAY = 0  '// The timer delay (animation speed)

XP  :'(
%FRAME_SizeX = 128 '// The animation frame width
%FRAME_SizeY = 128 '// The animation frame height
%TIMER_DELAY = 30  '// The timer delay (animation speed)



...
Patrice Terrier
GDImage (advanced graphic addon)
http://www.zapsolution.com

Patrice Terrier

#1
Here i am sharing with you what i have learned so far, playing with OpenGL and DIB bitmap.

1 - Setting the PixelFormat:

FUNCTION zSetupPixelFormat(BYVAL hDC AS LONG) AS LONG
    LOCAL pfd AS PIXELFORMATDESCRIPTOR
    LOCAL pixelformat AS LONG
    LOCAL lRet AS LONG

    lRet = %TRUE

    pfd.nSize      = SIZEOF(pfd)
    pfd.nVersion   = 1
    pfd.dwFlags    =
%PFD_SUPPORT_OPENGL OR %PFD_SUPPORT_GDI
    pfd.iPixelType = %PFD_TYPE_RGBA

    pfd.cColorBits = 32
    pfd.cDepthBits = 32

    pixelformat = ChoosePixelFormat(hDC, pfd)

    IF pixelformat THEN
       IF SetPixelFormat(hDC, pixelformat, pfd) = 0 THEN lRet = %FALSE
    ELSE
       lRet = %FALSE
    END IF

    FUNCTION = lRet
END FUNCTION


2 - No need for swapbuffer, because we are not drawing directly to a window:

SUB SetImage(BYVAL hWnd AS LONG)
    LOCAL graphics, DesktopDC, hDeskTop, x, y, hIC, hWndDC AS LONG
    LOCAL rw AS RECT
    LOCAL bf AS BLENDFUNCTION
    LOCAL lp, ptSrc AS POINTAPI
    LOCAL lpSize AS SIZEL
     
    CALL GetWindowRect(hWnd, rw)
    lpSize.Cx = rw.nRight - rw.nLeft: lpSize.Cy = rw.nBottom - rw.nTop
    lp.X = rw.nLeft: lp.Y = rw.nTop
   
    '// Draw active frame to new memory DC
    IF ghBmp = 0 THEN
       hIC = zDisplayDC()
       ghMemDC = CreateCompatibleDC(hIC)'DesktopDC)
       ghBmp = zCreateDIBSection(hIC, lpSize.Cx, lpSize.CY, 32)
       CALL SelectObject(ghMemDC, ghBmp)
       CALL DeleteDC(hIC)
    END IF

'   // Draw background
    CALL zGradientPaintDC(ghMemDC, 0, 0, lpSize.Cx, lpSize.CY, RGB(0,0,8), RGB(0,64,92))
   
'   // Draw the OpenGL scene
    CALL DrawTheScene()
    CALL wglMakeCurrent(hGLDC, hGLRC)
    '// CALL SwapBuffers(hGLDC) ' //
Because we are drawing to DIB we don't need to swap buffers!
    CALL DrawAndSetupAlphaChannel()
'   // Alphablend the OpenGL animation hover the background
    CALL zAlphaBlend(ghMemDC, 0, 0, lpSize.Cx, lpSize.CY, hGLDC, 0, 0, lpSize.Cx, lpSize.CY)
'
'   // Paint the resulting bitmap to the our window
    hWndDC = GetDC(hWnd)
    CALL BitBlt(hWndDC, 0, 0, lpSize.Cx, lpSize.CY, ghMemDC, 0, 0, %SRCCOPY)       
    CALL ReleaseDC(hWnd, hWndDC)

END SUB


See the attached ZIP file for the small changes i have done:



8)
Patrice Terrier
GDImage (advanced graphic addon)
http://www.zapsolution.com

José Roca

#2
 
Following your guidelines, I have written a new graphic control that can be used with GDI, GDI+ and OpenGL at the same time.

Patrice Terrier

The first post of this thread has been updated, to fix the ZIP file corruption caused by the "Server Collapse".

...
Patrice Terrier
GDImage (advanced graphic addon)
http://www.zapsolution.com