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.
1 | void 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 | |
15 | void 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 | |
4 | GameBackground::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 | |
16 | GameBackground::~GameBackground() |
17 | { |
18 | destroy_bitmap(tmpBuffer); |
19 | } |
20 | |
21 | void GameBackground::update() |
22 | { |
23 | scrollBackground(); |
24 | } |
25 | |
26 | void GameBackground::scrollBackground() |
27 | { |
28 | switch(scrollType) |
29 | { |
30 | case HORIZONTAL_LEFT: |
31 | scrollLeft(); |
32 | break; |
33 | default: |
34 | break; |
35 | } |
36 | } |
37 | |
38 | void GameBackground::draw() |
39 | { |
40 | draw_sprite(GameManager::currentPage, tmpBuffer, 0, 0); |
41 | } |
42 | |
43 | void GameBackground::setScrollSpeed(int speed) |
44 | { |
45 | scrollSpeed = speed; |
46 | } |
47 | |
48 | void 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!
]]>If you're the last poster on the topic you may only edit your last post.
]]>Hmmm... I think that's a pretty bad feature. Anyway, you guys have any idea what I'm doing wrong? Thanks!
]]>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
Hmmm... I think that's a pretty bad feature.
A perfect examples of why you should never take advice from your users.
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
]]>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?
]]>Unfortunately you can only do page flipping or double buffer.
]]>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.
]]>Great! I'm glad you finally see the light.
]]>Why would you want to switch between them? Or does the user get a choice in the matter?
]]>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.
]]>Congratulations! Your code causes an internal error in the MSVC 6.0 compiler!
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.
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
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!
]]>