Page 2 of 3 FirstFirst 123 LastLast
Results 11 to 20 of 24

Thread: Using multiple surfaces

  1. #11

    Using multiple surfaces

    With a 2d rpg I've been working on solo for the last few years, I got a massive FPS increase after setting up multiple surfaces.

    I've setup 6 surfaces for the map (Ground layer, Middle layerx2, Simple Sprite Layerx2, Above Layer), 1 surface for the Gui, 3 for Characters and NPC sprites, and 1 extra layer for misc stuff. Middle, Simple Sprite and Character layers have mutliple surfaces for animation.

    Originally the Drawer had to loop through the map tiles, sprites, gui, etc and draw each tile graphic every frame. But with multiple surfaces the drawer only loops through everything once and draws to the surfaces, and only again if a specific layer changes, and only that layer gets redrawn.

    I also use something like:
    DxDraw.Surface.Draw(0,0,rect(offx,offy,screenW+off x,screenH+offy), < Surface >, true);
    to only draw what is on screen, with transparency.


    ..anyway, before multiple surfaces I had a FPS of 12, and now I get 70 FPS , and thats on a 333mhz cpu. The games runs so fast now, I have to have a Sleep(200) in the main loop for it run properly

  2. #12

    Using multiple surfaces

    Okay, I made a test program with DelphiX so if you got unDelphiX I'm not sure whether the source will load correctly. The results were quite surprising. I found that there was an average of 20fps difference between the two methods on my PC, this could be quite different on a low end machine. Here's the link to the exe with source. Hit enter to switch between the two drawing methods. Feel free to recompile before running, I won't get offended let me know what sort of results you get. Mine hovered around 420 for fast mode and 400 for slow mode. I was expecting a bigger gap but that's what tests are all about.

    http://zupload.com/download.php?file...&filepath=6340

    Oh and just so you know, this obviously isn't optimised in any way. For instance it is a very bad idea to use the Surface.Canvas. It is a very slow way of drawing text to screen IIRC. It's better to have a font sheet with all letters and characters on just blit them to the suface when needed. But that's a subject for another post/test program.

    One more thing - lowering the color depth also seems to boost FPS by a huge amount. Although 8-bit requires a decent palette so it depends on what kind of art you are gonna be using.
    Isometric game development blog http://isoenginedev.blogspot.com/

  3. #13

    Using multiple surfaces

    An interesting approach K4Z. I used to use surface.clientrect, which is the same as rect(0,0, width, height). I never actually thought of clipping the rect, using an offset. I'll keep that trick in mind!

    Quote Originally Posted by K4Z
    The games runs so fast now, I have to have a Sleep(200) in the main loop for it run properly
    From this it gather you're using framebased movement and not timebased movement?

    Crisp_N_Dry, what specs do you have? I tried your sample (exe only) and got ~229 fps with both methods. (my specs: 3ghz, 1gig ram, 6800 gt)

  4. #14

    Using multiple surfaces

    At the moment the RPG is using frame based movement, was in the middle of switching to time based when my pc died, so developement on the game has stopped for now .


    I tested Crisp_N_Dry's sample as well, and got around 240 fps on my 3ghz, 512 meg ram, geforce.

    I did a simple modification - made a new surface and created a 'BuildScreen' function that loops through the tiles and the other graphic and draws to the surface. Only when you switch to 'Slow' (lol) draw mode it calls the 'BuildScreen' function once.

    So the only thing the DrawSlow function does now is:

    DXDraw1.Surface.Draw(0,0,NewSurface.ClientRect,New Surface,False);
    DXDraw1.Surface.Canvas.TextOut(0,0,'Surface overlay method');
    DXDraw1.Surface.Canvas.Release;

    And now I get 2560 fps, lmao . over 3000 if I remove all textout() functions.


    Edit: Running the .exe straight out of the .rar gave me 200 fps, compiling with no modifications gave me 240 fps :?:

  5. #15

    Using multiple surfaces

    Edit: Running the .exe straight out of the .rar gave me 200 fps, compiling with no modifications gave me 240 fps Question
    Interesting: I tried the same using an older delphiX version. (ie no undelphix) I recompiled the given source with D7 and got a massive increase as well. from 229 fps to ~310 fps?! How odd. Could this be a difference in Delphi version?

  6. #16

    Using multiple surfaces

    Very unusual. I compiled using Delphi 4 Standard. My specs are
    AMD Athlon 2800 (Running at 2200 due to heat issues).
    1gb Crucial 400mhz.
    NVidia Geforce 5800 128mb.

    Strange about the massive jump between Delphi compiles. Never thought the optimization was that major. Also weird how I got a higher framerate with a lower end graphics card than you guys.
    Isometric game development blog http://isoenginedev.blogspot.com/

  7. #17

    Using multiple surfaces

    Here's the modifications I've made to Crisp_N_Dry's sample.

    http://zupload.com/download.php?file=getfile&filepath=6885

    Press SHIFT to switch to my mehod, ENTER to Toggle between both of Crisp_N_Dry's mehods.

    Under my method, I get around 2600 fps. And thats still without any optimizations, just drawing to a seperate layer.

  8. #18

    Using multiple surfaces

    Quote Originally Posted by K4Z
    The games runs so fast now, I have to have a Sleep(200) in the main loop for it run properly
    You might want to consider putting timebased movement in there as your latest modification of Crisp_N_Dry' sample gave me around 7000 fps.
    There's no way sleep(200) is going to help you with that.
    [size=9px]
    {edit: and thats 600 }[/size]

  9. #19

    Using multiple surfaces

    With your new method, I get around 6300 frames while the other two only get arround 225 FPS on my AthlonXP 2000+.

    Well, I got another question concerning surfaces. Here is some sourcecode to illustrate my problem:

    [pascal]

    // Version A
    procedure TfrmTest.DrawInterface;
    begin
    surfInterface.Fill(0);
    InterfaceImages.Items.Items[0].Draw(surInterface, 0, 0, 0);
    end;

    procedure TfrmTest.DXDrawInitialize(Sender: TObject);
    begin
    DXDrawTimer.Enabled := true;
    surInterface := TDirectDrawSurface.Create(DXDraw.DDraw);
    surInterface.SetSize(DXDraw.Width, DXDraw.Height);

    DrawInterface;
    end; // Version A

    // Version B
    procedure TfrmTest.DXDrawInitialize(Sender: TObject);
    begin
    DXDrawTimer.Enabled := true;
    surInterface := TDirectDrawSurface.Create(DXDraw.DDraw);
    surInterface.SetSize(DXDraw.Width, DXDraw.Height);

    surfInterface.LoadFromGraphic(InterfaceImages.{... }.graphic)
    end; // Version B

    // A & B
    procedure TfrmTest.DXDrawTimerTimer(Sender: TObject; LagCount: Integer);
    begin
    DXDraw.Surface.Draw(0, 0, surInterface, true);
    DXDraw.Flip;
    end; // A & B
    [/pascal]

    Version A dosent bring anything on my screen, Version B does. If I would call DrawInterface at the Timer Event it would draw it as well. Isn't it possible to draw Images of an DXImageList athe DXDrawInitialize Event?

  10. #20

    Using multiple surfaces

    Nope it isn't. The DXDrawInitialize is for initializing. Like loading images, initializing variables, setting timers to true.

    It kinda forces you a bit to keep your code structured, ie:

    start game
    init game variables
    process game
    deinit game variables (free objects etc)
    close game

Page 2 of 3 FirstFirst 123 LastLast

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •