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)
(http://www.zapsolution.com/pictures/GLDrawDIB.jpg)
...
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:
(http://www.zapsolution.com/pictures/GLDrawDIB2.jpg)
8)
Following your guidelines, I have written a new graphic control that can be used with GDI, GDI+ and OpenGL at the same time.
The first post of this thread has been updated, to fix the ZIP file corruption caused by the "Server Collapse".
...