Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » PageFlipping and DoubleBuffering Combined Problem

This thread is locked; no one can reply to it. rss feed Print
PageFlipping and DoubleBuffering Combined Problem
armond
Member #8,282
January 2007

Hi! This is a continuation of this thread

http://www.allegro.cc/forums/thread/590316

I can't seem to post any reply so I just created another thread since this seems to focus on a slightly different problem anyway.

Now, I'm sure I'm getting page flipping right this time. My page flipping and double buffering routines are fine. It's just that when I combine them, the double buffered buffer overlaps the pageflipped one.

I have these two methods in a class called GameManager which is responsible for rendering bitmap to the screen.

1void GameManager::flipPage()
2{
3 show_video_bitmap(currentPage);
4
5 if (currentPage == page1)
6 {
7 currentPage = page2;
8 }
9 else
10 {
11 currentPage = page1;
12 }
13}
14 
15void GameManager::blitBuffer()
16{
17 acquire_screen();
18
19 blit(buffer, screen, 0, 0, 0, 0, GAME_WIDTH, GAME_HEIGHT);
20
21 release_screen();
22
23 clear_bitmap(buffer);
24}

and they are called in this manner in my main game loop.

            //page flip
            GameManager::flipPage();
        
            //blit buffer
            GameManager::blitBuffer();

If you're wondering where I use pageflipping, I'm using it to render a scrolling background. The GameBackground class looks like this...

1#include "globals.h"
2 
3 
4GameBackground::GameBackground(BITMAP* bitmap, BackgroundScrollType scrollType, int scrollSpeed, int x, int y)
5{
6 this->bitmap = bitmap;
7 this->scrollType = scrollType;
8 this->scrollSpeed = scrollSpeed;
9 this->x = x;
10 this->y = y;
11
12 //tmpBuffer = create_bitmap(SCREEN_W, SCREEN_H);
13 tmpBuffer = create_video_bitmap(SCREEN_W, SCREEN_H);
14}
15 
16GameBackground::~GameBackground()
17{
18 destroy_bitmap(tmpBuffer);
19}
20 
21void GameBackground::update()
22{
23 scrollBackground();
24}
25 
26void GameBackground::scrollBackground()
27{
28 switch(scrollType)
29 {
30 case HORIZONTAL_LEFT:
31 scrollLeft();
32 break;
33 default:
34 break;
35 }
36}
37 
38void GameBackground::draw()
39{
40 draw_sprite(GameManager::currentPage, tmpBuffer, 0, 0);
41}
42 
43void GameBackground::setScrollSpeed(int speed)
44{
45 scrollSpeed = speed;
46}
47 
48void GameBackground::scrollLeft()
49{
50 x -= scrollSpeed;
51
52 int bw = bitmap->w;
53 int bh = bitmap->h;
54
55 int xOffSet = (SCREEN_W + bw);
56
57 if ( x > bw || x < -(bw) )
58 {
59 x = 0;
60 }
61
62 int newX = 0;
63
64 for (int i = -(bw); i < (xOffSet); i += bw)
65 {
66 newX = (x + i);
67
68 for (int j = 0; j < SCREEN_H; j += bh)
69 {
70 //draw tile
71 //Optimization: draw only parts that are visible to the screen
72 if ( ( newX + bw) > 0 )
73 {
74 draw_sprite(tmpBuffer, bitmap, newX, j);
75 }
76 else
77 {
78 break;
79 }
80
81 }
82 }
83}

This way, my scrolling BG uses the video memory buffer and all the other objects are stored in the memory buffer.

When I comment the GameManager::blitBuffer() method from the game loop, I can see the scrolling background scrolling smoothly. When I uncomment GameManager::blitBuffer() and comment GameManager::flipPage() I can see all the objects on the memory buffer moving. How can I possible combine these two that the background is on the back and all the other objects on top of it? Thanks!

Ceagon Xylas
Member #5,495
February 2005
avatar

If you're the last poster on the topic you may only edit your last post.

armond
Member #8,282
January 2007

Hmmm... I think that's a pretty bad feature. Anyway, you guys have any idea what I'm doing wrong? Thanks!

Kris Asick
Member #1,424
July 2001

Combining the two routines is very pointless because you can achieve the same effect with calling vsync() before drawing a memory buffer to the screen.

Now, to answer your question, to combine the two properly you need three bitmaps and one bitmap pointer:

back_buffer = Memory Bitmap
page_1 = Video Bitmap
page_2 = Video Bitmap
bmp_pointer = Pointer to page_1 and page_2 (depending on the frame)

Then, in order, here's what you want to do:

0.) Initialize bmp_pointer to point to page_2 and call show_video_bitmap() on page_1.

1.) Reset and render everything to back_buffer.
2.) blit() back_buffer to bmp_pointer.
3.) Call: show_video_bitmap(bmp_pointer);
4.) If bmp_pointer = page_1, switch it to page_2, else switch it to page_1.

If any of that is out of order, or if you've mixed up what kind of bitmaps everything is, it won't work.

Also, using this method, you should never have to call the acquire and release commands since you only ever make one blit to video memory every frame.

But I still highly recommend you just double buffer with a vsync() call right before blitting the buffer to the screen, because it's simpler and achieves the exact same effect.

--- Kris Asick (Gemini)
--- http://www.pixelships.com

--- Kris Asick (Gemini)
--- http://www.pixelships.com

ImLeftFooted
Member #3,935
October 2003
avatar

Quote:

Hmmm... I think that's a pretty bad feature.

A perfect examples of why you should never take advice from your users.

Quote:

Hi! This is a continuation of this thread

There was plenty of very sound advice in the other thread. You seem to be starting threads and only hearing what you want to hear. Which is the wrong stuff.

You wont get very far with that perspective :P

armond
Member #8,282
January 2007

My intention was to make things clearer for for those who are interested to answer(thanks to you guys).

While the other thread focuses on how to make page flipping work, this thread focuses on how to make page flipping work with double buffering(the title says so). There's nothing wrong with that, is there?

ImLeftFooted
Member #3,935
October 2003
avatar

Unfortunately you can only do page flipping or double buffer.

armond
Member #8,282
January 2007

Thank you, it's a good thing that I have two of those techniques incorporated in my code so I could just switch between them.

ImLeftFooted
Member #3,935
October 2003
avatar

Great! I'm glad you finally see the light.

James Stanley
Member #7,275
May 2006
avatar

Why would you want to switch between them? Or does the user get a choice in the matter?

armond
Member #8,282
January 2007

Quote:

James Stanley: Why would you want to switch between them? Or does the user get a choice in the matter?

To see which would perform better. I'll take this opportunity to let you guys see my source code. It comes with a dev-cpp project file. It's still far from finish but it's playable. Please tell me your comments and possible solution to optimize my game. It really runs slow on PIII machine and lower and one possible problem I can see is in my rendering. Thanks!

BTW, it uses Double Buffering as of now...

Please see attachment.

Kris Asick
Member #1,424
July 2001

Congratulations! Your code causes an internal error in the MSVC 6.0 compiler! :P

Thus I can't compile it for an unknown reason.

In either case, I ran the included executable and can't find anything wrong.

Your speed issues likely relate to trying to process too much at too great a colour depth. If you're running a PIII CPU you almost certainly want to avoid 24-bit and 32-bit colour. (Remember, Allegro is NOT hardware accelerated.) Try scaling down to 16-bit colour and see if that helps your framerate. (Your graphics aren't very complicated. You may even want to try scaling down to 8-bit, though you'll have to tweak all your graphics into one palette if you do that, but you'll get the best framerate possible that way.)

Also, the keys you chose for controls prevented me from moving up, right, and shooting all at once. (Likely my keyboard didn't like the combination, but I have a good keyboard when it comes to holding multiple keys, so I may not be the only one who experiences that.)

Other than that, your code base is massive. It would take me forever to find any optimizations you could perform. :o

Lastly, if you're doing vsyncing or page flipping, the moment your framerate drops below the monitor refresh rate it will be chopped IN HALF, no matter what. You want to look into "frame dropping" so that if the framerate drops too low the game will at least attempt to continue running the proper speed.

--- Kris Asick (Gemini)
--- http://www.pixelships.com

--- Kris Asick (Gemini)
--- http://www.pixelships.com

armond
Member #8,282
January 2007

Thanks for your comments! I would definitely experiment on the color depth, frame dropiing and those other things you mentioned and see how it would perform. Thanks!

Go to: