Dark Bit Factory & Gravity

PROGRAMMING => C / C++ /C# => Topic started by: ninogenio on October 15, 2007

Title: need some folks to test this out
Post by: ninogenio on October 15, 2007
hey all im messing around with a gdi blitter framework sort of thing and i need some of you guys to test it out firstly to see if it works ok on your systems and secondly to see i it runs at ok speeds there is no delta timing yet so there is a wee bit of shredding.

ive included my source up to this point also and would like to know if my cpp gdi coding is ok up to this point or if im totally missing the point in some areas.
Title: Re: need some folks to test this out
Post by: taj on October 15, 2007
It runs ok but not brilliantly here. The zoom at the start pauses part way through amd when its full screen, the boxes drifting from side to side appear to be not smooth. Nowthis said, I dont know how GDI should run so maybe this is really good for GDI.

Chris
Title: Re: need some folks to test this out
Post by: ninogenio on October 15, 2007
hmm odd it should run pretty fast i get decent speed myself with tearing coming from the fact it draws between vblanks.

i think im blitting all the gfx as quickly as possible maybe not though..
Title: Re: need some folks to test this out
Post by: Shockwave on October 15, 2007
It seems to run fast enough here (Dual core 1.8 ghz), it suffers from jerkieness because of no sync though.
Title: Re: need some folks to test this out
Post by: benny! on October 15, 2007
@ninogenio:
Runs ok here. Like Shockwave says it lacks of some smooth movement - maybe because of no
sync.

General question - do you use plain GDI for that ? If so - why not use the new GDIPlus library -
it supports stuff like :

- Alpha blending
- Gradient brushes
-Transformations and rotations
- Scalable regions
- Support for several image formats

Have a look at the following url for more information :

http://www.codeproject.com/vcpp/gdiplus/startinggdiplus.asp (http://www.codeproject.com/vcpp/gdiplus/startinggdiplus.asp)
Title: Re: need some folks to test this out
Post by: Positron on October 15, 2007
You are using the WM_TIMER event to start redrawing, right? But this event only appears if windows has nothing else to do. It's not guaranteed that you get your wished interval. So the time between the animation steps are different and I think this is the reason why the animation isn't smooth.
Title: Re: need some folks to test this out
Post by: Jim on October 15, 2007
That's part of the problem, though calling timeBeginPeriod(1) at the start of the program improves matters a bit.
With WM_TIMER you can't do much in the way of delta timing either - it's basically like an interrupt that goes off at a fixed period, but nowhere near as accurate as a vblank interrupt on a console - could be off by 10s of milliseconds.
It's relatively easy to switch it over to a draw-as-fast-as-possible approach where you can add delta timing - it just means changing the GetMessage loop into a PeekMessage one and killing off the WM_TIMER/WM_PAINT messages, but you will get more tearing that way, I suspect.
Having said all that, it looks pretty good for a GDI app - expectations are low...:)

Jim
Title: Re: need some folks to test this out
Post by: ninogenio on October 15, 2007
i decided to let it run at full speed and it improves the animation quite a bit heres what ive done to get rid of the wm_timer.

Code: [Select]
do
        {
                InvalidateRect(scene_window, NULL, FALSE);                 
                while (PeekMessage(&msg, scene_window, 0, 0, PM_NOREMOVE))
                {
                        if (GetMessage(&msg, scene_window, 0,0) < 0)
                                break;
                        TranslateMessage(&msg);
                        DispatchMessage(&msg);
                }
                GenioMain( OffScreenDC , scene_window ) ;

        } while (!quit);

it runs fine for a few seconds on my comp then the text goes funny and stops spinning and all my hdc boxes go small.

Title: Re: need some folks to test this out
Post by: Jim on October 15, 2007
Totally delete the cases for WM_PAINT and WM_TIMER.  Just get them out of there :)  And the InvalidateRect call.
Then just call
Code: [Select]
GenioMain(...)
HDC destdc = GetDC(hwnd)
BitBlt(destdc, ...)
ReleaseDC(hwnd,destdc);
in your main loop.
Then, just for now, add
Code: [Select]
Sleep(15);
after ReleaseDC.

Jim
Title: Re: need some folks to test this out
Post by: ninogenio on October 15, 2007
cool the sleep fixed the hdc messup problem!

i take it without the sleep the program goes too fast for windows to keep updating.

will it be ok to take the sleep out when i add delta timing?
Title: Re: need some folks to test this out
Post by: Jim on October 15, 2007
It was removing the InvalidateRect and WM_PAINT that fixed it.  That would mess it up totally ;)

You'll want to keep it running slower than 100Hz at least, so you'll need Sleep(10) 10=1000/100, unless your drawing is taking forever.  The trick here is to keep a track of how long you took to draw the last frame and use that to work out how much to move the next frame.  But don't even bother trying to go over 100fps.  You'll get even more tearing than normal and suck up 100% CPU.

Jim
Title: Re: need some folks to test this out
Post by: ninogenio on October 15, 2007
cheers jim ive stuck a delta timer in and i think its working ok does it run smooth on you guys systems now also.

here is the timer code dont know much about c++ timers so i dont know if this is right.
Code: [Select]
LARGE_INTEGER Frequency;
        QueryPerformanceFrequency(&Frequency);
       
        do
        {
                LARGE_INTEGER liStart;
                LARGE_INTEGER liStop;

                QueryPerformanceCounter(&liStart);
                     
                while (PeekMessage(&msg, scene_window, 0, 0, PM_NOREMOVE))
                {
                        if (GetMessage(&msg, scene_window, 0,0) < 0)
                                break;
                        TranslateMessage(&msg);
                        DispatchMessage(&msg);
                }
               
                HDC destdc = GetDC( scene_window );
                GenioMain( OffScreenDC , scene_window );
                BitBlt( destdc , 0 , 0 , SCREEN_X , SCREEN_Y , OffScreenDC , 0 , 0 , SRCCOPY );
                ReleaseDC( scene_window , destdc );
                Sleep(0);     
                QueryPerformanceCounter(&liStop);

                LONGLONG llTimeDiff = liStop.QuadPart - liStart.QuadPart;

                dftDuration = (double) llTimeDiff * 1000.0 / (double) Frequency.QuadPart;

        } while (!quit);

Title: Re: need some folks to test this out
Post by: Positron on October 16, 2007
The delta timer is right. Is running smooth for GDI.
Title: Re: need some folks to test this out
Post by: Jim on October 16, 2007
That's a lot better.  I still think you ought to put in a longer Sleep() but 0 is the absolute minimum requirement to be multitasking friendly.  Basically, while you're sleeping other apps get a chance to do some real work.  If you don't sleep, everything else runs very, very slowly.

Some of the blobs seems to get stuck on the side of the screen.

Jim
Title: Re: need some folks to test this out
Post by: ninogenio on October 16, 2007
i would have liked to put a longer sleep in there jim but anything other than 0 on my system runs slow even just a sleep 1 runs at about half the speed.

i read that sleep can be diffrent from system to system so its maybe some of my hardware thats makes sleep weird on my comp.

oh and btw the blobs will get stuck i just threw this together to see if i could animate smooth but now ill actually do something with it.

- edit on your system does the top text go big after a few seconds cause on mine im having a weird bug in my text class that two seperate constructed variables based on my text class take on each others characteristics in width and height and lfescapment after a few seconds but not of color and as much as ive tried i cant figure out why?
Title: Re: need some folks to test this out
Post by: Jim on October 16, 2007
Quote
edit on your system does the top text go big after a few seconds
Yes, I think it did.  Have you read the documentation for SelectObject()?
http://msdn2.microsoft.com/en-us/library/ms533272.aspx (http://msdn2.microsoft.com/en-us/library/ms533272.aspx)
Might be relevant.   Might also be a proper bug  :inspired:

Jim
Title: Re: need some folks to test this out
Post by: ninogenio on October 16, 2007
yeah ive read that, the only thing im not doing is saving and replacing to old font so that might be where its coming from.

the only thing i dont quite get is why its only lfescapment/orentation and width/height that goes weird not x/y and color.
Title: Re: need some folks to test this out
Post by: ninogenio on October 17, 2007
been messing around again trust me  :whack:  :)

i can get even smother almost console refresh with a sleep(13) and my refresh set to 75 using dmScreenSettings.dmDisplayFrequency but how reliable will 75 be at 800x600 as opposed to 60 on other peoples comps id like to be able to use it with confidence as it runs really nicely.
Title: Re: need some folks to test this out
Post by: Jim on October 17, 2007
People with LCDs often don't have refresh rates over 60Hz in any mode.
Perhaps your font isn't changing but the dest rectangle/location is being corrupted somehow?

Jim
Title: Re: need some folks to test this out
Post by: ninogenio on October 17, 2007
it could be the dest location that is getting corrupted but my other classes for blitting sprites to the same hdc works fine.

would using the QueryPerformanceFrequency/Counter to create a wait/loop to set the fps to 6ohz be any good at emulating a vblank for folks with an lcd monitor.

im finding delta timing not very good for large objects.
Title: Re: need some folks to test this out
Post by: Jim on October 18, 2007
I think you'll have to experiment :)

Jim
Title: Re: need some folks to test this out
Post by: ninogenio on October 18, 2007
im getting closer i think to smoothness  :)

could you test this for me ill not bother you with this from now honestly  ;D

ive got two demos one at 60 fps syncronized as close with the screen refresh as i can get and the other at 500fps as this is the smoothest i can possibly get on my system, without clamping it runs almost 900 fps.

in the 60hz one i can afford a sleep(10); so this one is by far the kindest to the system.

here is what im doing in my main loop.
Code: [Select]
LARGE_INTEGER Frequency ;
        LONGLONG llTimeDiff ;
        QueryPerformanceFrequency(&Frequency) ;
       
        do
        {
                LARGE_INTEGER liStart ;
                LARGE_INTEGER liStop ;

                QueryPerformanceCounter(&liStart) ;
                     
                while (PeekMessage(&msg, scene_window, 0, 0, PM_NOREMOVE))
                {
                        if (GetMessage(&msg, scene_window, 0,0) < 0)
                                break;
                        TranslateMessage(&msg);
                        DispatchMessage(&msg);
                }
                GenioMain( OffScreenDC , scene_window ) ;
                HDC destdc = GetDC( scene_window ) ;
                BitBlt( destdc , 0 , 0 , SCREEN_X , SCREEN_Y , OffScreenDC , 0 , 0 , SRCCOPY );
                ReleaseDC( scene_window , destdc ) ;
                Sleep(10) ;
               
                QueryPerformanceCounter(&liStop) ;
                llTimeDiff = liStop.QuadPart - liStart.QuadPart ;

                dftDuration = (double) llTimeDiff * 1000.0 / (double) Frequency.QuadPart;
               
                //little wait loop to try get the fps down to 60hz
                do{
                   QueryPerformanceCounter(&liStop);
                   llTimeDiff = liStop.QuadPart - liStart.QuadPart;

                   dftDuration = (double) llTimeDiff * 1000.0 / (double) Frequency.QuadPart;
               
                }while (  dftDuration <= 1000.0/(float)dmScreenSettings.dmDisplayFrequency );     
               
        } while (!quit);

and for my fps counter and delta timing im doing this.
Code: [Select]
float Xfactor = 8 , Yfactor = 8 ;
double FPSTimer , Timer;
int FPS;
char *FramesPerSecond ;
char fname[128];
void GenioMain( HDC hdc, HWND hwnd )
{       
       
        ClearOffScreenHDC();
       
        DeltaF = dftDuration / 14.0 ;
       
        CamX += ( Xfactor * DeltaF ) ;
        CamY += ( Yfactor * DeltaF ) ;
 
        if ( CamX < 0 ){
             CamX = 0 ;
             Xfactor =- Xfactor ;
        }
       
        if ( CamX > 8 * StarMap->width ){
             CamX = 8 * StarMap->width ;
             Xfactor =- Xfactor ;
        }
       
        if ( CamY < 0 ){
             CamY = 0 ;
             Yfactor =- Yfactor ;
        }
       
        if ( CamY > 6 * StarMap->height ){
             CamY = 6 * StarMap->height ;
             Yfactor =- Yfactor ;
        }
       
        for ( int Y = 0 ; Y < 9 ; Y++ ){
             for ( int X = 0 ; X < 12 ; X++ ){
                 SkyDC->SetX( -CamX + ( X * StarMap->width ) ) ;
                 SkyDC->SetY( -CamY + ( Y * StarMap->height ) ) ;
                 SkyDC->Blit( hdc );
            }
        }
       
        FPS += 1;

        Timer += dftDuration ;
        if ( Timer >= FPSTimer ){
            sprintf( fname , "fps: %d" , FPS);
            FPS = 0 ;
            FPSTimer = Timer + 1000.0 ;
        } 
       
        myText->SetCaption( fname );
        myText->DrawText();
       
}

do my timers look ok as im very new to this stuff.

60hz
http://www.4shared.com/file/26780283/f2ec497/test60hz.html?dirPwdVerified=5cf8302d

500hz
http://www.4shared.com/file/26780294/88516075/test500hz.html?dirPwdVerified=5cf8302d
Title: Re: need some folks to test this out
Post by: Shockwave on October 18, 2007
Tested the 60 HZ version, it runs nice and smooth, there is some tearing of the image but I think you've probably got it about as close as you can.
Title: Re: need some folks to test this out
Post by: ninogenio on October 18, 2007
cheers shockwave im still in the air a little bit as to which version to go for as at least on my system with the 60hz version there is a little tearing but its much kinder to the system where as the 500 fps version runs without tearing and lookes nice and smooth but takes 100% cpu.

ahh choices ehh  :) ill probably go for the 60hz one though.
Title: Re: need some folks to test this out
Post by: Jim on October 18, 2007
They're both pretty much perfectly smooth here.  There's no point rendering 500 times a second.  Only 1/5th of those frames are going to be visible, the rest will be dropped or cause tearing.  Use the 60Hz one, and if your extra processing gets too much so it drops below 60, reduce the amount of sleep time.

Jim
Title: Re: need some folks to test this out
Post by: ninogenio on October 18, 2007
right thats great,

im much happier with the 60hz version it feels about right for me, using gdi drawing tools like lines and polys with brushes and pens the fps hardly gets hit at all.
Title: Re: need some folks to test this out
Post by: Rbz on October 19, 2007
cheers shockwave im still in the air a little bit as to which version to go for as at least on my system with the 60hz version there is a little tearing but its much kinder to the system where as the 500 fps version runs without tearing and lookes nice and smooth but takes 100% cpu.
...
Same here, on 60fps I got little tearing and at 500fps it is Ok.