Log in

View Full Version : gdi animation in microman's crazy computers


jih
06-29-2003, 07:20 AM
do you use doublebuffering for microman? the animation is very smooth considering it's gdi only, and not dx.

i've been trying to create smooth animation using only gdi, but so far no luck since i don't know how to create a double buffer. if gdi is capable of doublebuffering, i don't think dx is necessary. any thought?

patrox
06-29-2003, 07:38 AM
You can't do DoulbeBuffering in GDI, but you can use a backbuffer.

then you can synchronise the display with the dx command :
IDirectDraw->WaitForVerticalBlank

So you visually get the "double buffering" smoothness.


I don't think it's using any vertical sync in microman's though, if you are used to the vertical blank symptoms :) or look very carefuly, you'll notice that the animation leaves a little motion trail.


pat.

jih
06-29-2003, 07:46 AM
how do you create a back buffer in gdi, and how would you blit it onto the window you want?

my guess would be to create a memory compatible hdc. select a bitmap into it that has the dimensions of the window. draw onto that hdc, and blit it onto the window hdc. am i right?

Lizardsoft
06-29-2003, 08:09 AM
That's what I use with my skinned user interface controls, except your drawing strategy has to be different than in DirectDraw where you redraw the whole screen every frame. Draw only what has changed since you want to avoid blts to the screen at all cost. Fortunately the GDI has support for this. I remember reading on the GameDev forums a few times about people that have written their own blting code for the GDI and not using normal HBITMAP objects, so I guess there's performance to be found there. There's probably libraries out there that do this, and I think I saw a way to sync with the vertical refresh under Windows without DirectX as well (I don't think the old DOS while( inp( 0x3DA ) & 0x08 ); while( !inp( 0x3DA ) & 0x08 ); way works though).

patrox
06-29-2003, 08:30 AM
Originally posted by jih
how do you create a back buffer in gdi, and how would you blit it onto the window you want?

my guess would be to create a memory compatible hdc. select a bitmap into it that has the dimensions of the window. draw onto that hdc, and blit it onto the window hdc. am i right?


This is a quick example ( check in the msdn for exact syntax, i'm doing that from memory )

backBufferBitmap = CreateDibSection( size and bpp you want )
( the dib sections allows you to poke directly in the pixel map of the picture )

if ( backBufferBitmap == NULL ) return ANiceError( ) ;


HDC backBufferDC = CreateCompatibleDC( windowDC )
if ( backBufferDC == NULL ) return ANiceError( ) ;

oldBitmap =(HBITMAP)SelectObject( backBufferDC , backBufferBitmap ) ;

WaitForVerticalBlank( ) ;
BitBlt( windowDC , 0,0,640,480,backBufferDC ,0,0,SRCCOPY ) ;

Don't forget to store the oldBitmap when you select your backbuffer else it'll result in a memory leak when exiting your program.

patrice.

Scorpio
06-29-2003, 09:09 AM
The engine we're using in MicroMan was something I originally wrote for Windows 3.1 long long ago (1991 I think). It uses GDI and DIBs and dirty-rectangles for updating...and custom draw routines to draw into the DIBs (hbitmaps are not used). Back in the Windows 3.1 days, it was relatively impressive.

MicroMan technically uses DDraw, but only to switch to full-screen mode. If you run on a system that doesn't even have DirectX installed (i.e. fresh install of Win95) it will still run fine, it just won't allow switching to full-screen.

MicroMan basically has 2 pages...which are just DIBs. One is the "Work" page and the other is the "Back" page.

Dirty rectangles are used to simultaneously update the new sprite graphics and erase the old ones (from the previous frame). This is how you get the smooth, flicker-free animation (eliminating flicker is the key).

Our newer stuff is all DDraw and surfaces and page-flipping...but the older tech is kinda nice for lower-end games because it will run on virtually any system.
-Scorpio

brassfish
06-29-2003, 02:37 PM
MicroMan technically uses DDraw, but only to switch to full-screen mode

There is a way to switch to fullscreen mode in GDI. Although I don't have the code. Its somewhere on the GDNet forums (general programming).

LordKronos
06-29-2003, 03:35 PM
ChangeDisplaySettings is what I use. Its a core Win32 API function, and exists on all Win32 platforms.

Scorpio
06-29-2003, 04:32 PM
Yeah, I actually used ChangeDisplaySettings when I first added full-screen support...but I didn't get the "free" handling of alt+tab, etc. so I went the DDraw route in the end.
-Scorpio