<?xml version="1.0"?>
<rss version="2.0">
	<channel>
		<title>PageFlipping and DoubleBuffering Combined Problem</title>
		<link>http://www.allegro.cc/forums/view/590417</link>
		<description>Allegro.cc Forum Thread</description>
		<webMaster>matthew@allegro.cc (Matthew Leverton)</webMaster>
		<lastBuildDate>Fri, 09 Mar 2007 16:27:41 +0000</lastBuildDate>
	</channel>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Hi! This is a continuation of this thread</p><p><a href="http://www.allegro.cc/forums/thread/590316">http://www.allegro.cc/forums/thread/590316</a></p><p>I can&#39;t seem to post any reply so I just created another thread since this seems to focus on a slightly different problem anyway.</p><p>Now, I&#39;m sure I&#39;m getting page flipping right this time. My page flipping and double buffering routines are fine. It&#39;s just that when I combine them, the double buffered buffer overlaps the pageflipped one.</p><p>I have these two methods in a class called GameManager which is responsible for rendering bitmap to the screen.</p><div class="source-code"><div class="toolbar"></div><div class="inner"><table width="100%"><tbody><tr><td class="number">1</td><td><span class="k1">void</span> GameManager::flipPage<span class="k2">(</span><span class="k2">)</span></td></tr><tr><td class="number">2</td><td><span class="k2">{</span></td></tr><tr><td class="number">3</td><td>    <a href="http://www.allegro.cc/manual/show_video_bitmap" target="_blank"><span class="a">show_video_bitmap</span></a><span class="k2">(</span>currentPage<span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">4</td><td>    </td></tr><tr><td class="number">5</td><td>    <span class="k1">if</span> <span class="k2">(</span>currentPage <span class="k3">=</span><span class="k3">=</span> page1<span class="k2">)</span></td></tr><tr><td class="number">6</td><td>    <span class="k2">{</span></td></tr><tr><td class="number">7</td><td>        currentPage <span class="k3">=</span> page2<span class="k2">;</span></td></tr><tr><td class="number">8</td><td>    <span class="k2">}</span></td></tr><tr><td class="number">9</td><td>    <span class="k1">else</span></td></tr><tr><td class="number">10</td><td>    <span class="k2">{</span></td></tr><tr><td class="number">11</td><td>        currentPage <span class="k3">=</span> page1<span class="k2">;</span></td></tr><tr><td class="number">12</td><td>    <span class="k2">}</span>        </td></tr><tr><td class="number">13</td><td><span class="k2">}</span>    </td></tr><tr><td class="number">14</td><td>&#160;</td></tr><tr><td class="number">15</td><td><span class="k1">void</span> GameManager::blitBuffer<span class="k2">(</span><span class="k2">)</span></td></tr><tr><td class="number">16</td><td><span class="k2">{</span></td></tr><tr><td class="number">17</td><td>    <a href="http://www.allegro.cc/manual/acquire_screen" target="_blank"><span class="a">acquire_screen</span></a><span class="k2">(</span><span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">18</td><td>    </td></tr><tr><td class="number">19</td><td>    <a href="http://www.allegro.cc/manual/blit" target="_blank"><span class="a">blit</span></a><span class="k2">(</span>buffer, <a href="http://www.allegro.cc/manual/screen" target="_blank"><span class="a">screen</span></a>, <span class="n">0</span>, <span class="n">0</span>, <span class="n">0</span>, <span class="n">0</span>, GAME_WIDTH, GAME_HEIGHT<span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">20</td><td>    </td></tr><tr><td class="number">21</td><td>    <a href="http://www.allegro.cc/manual/release_screen" target="_blank"><span class="a">release_screen</span></a><span class="k2">(</span><span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">22</td><td>    </td></tr><tr><td class="number">23</td><td>    <a href="http://www.allegro.cc/manual/clear_bitmap" target="_blank"><span class="a">clear_bitmap</span></a><span class="k2">(</span>buffer<span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">24</td><td><span class="k2">}</span></td></tr></tbody></table></div></div><p>


and they are called in this manner in my main game loop.</p><div class="source-code snippet"><div class="inner"><pre>            <span class="c">//page flip</span>
            GameManager::flipPage<span class="k2">(</span><span class="k2">)</span><span class="k2">;</span>
        
            <span class="c">//blit buffer</span>
            GameManager::blitBuffer<span class="k2">(</span><span class="k2">)</span><span class="k2">;</span>
</pre></div></div><p>


If you&#39;re wondering where I use pageflipping, I&#39;m  using it to render a scrolling background. The GameBackground class looks like this...</p><div class="source-code"><div class="toolbar"></div><div class="inner"><table width="100%"><tbody><tr><td class="number">1</td><td><span class="p">#include "globals.h"</span></td></tr><tr><td class="number">2</td><td>&#160;</td></tr><tr><td class="number">3</td><td>&#160;</td></tr><tr><td class="number">4</td><td>GameBackground::GameBackground<span class="k2">(</span><a href="http://www.allegro.cc/manual/BITMAP" target="_blank"><span class="a">BITMAP</span></a><span class="k3">*</span> bitmap, BackgroundScrollType scrollType, <span class="k1">int</span> scrollSpeed, <span class="k1">int</span> x, <span class="k1">int</span> y<span class="k2">)</span></td></tr><tr><td class="number">5</td><td><span class="k2">{</span></td></tr><tr><td class="number">6</td><td>    this-&gt;bitmap <span class="k3">=</span> bitmap<span class="k2">;</span></td></tr><tr><td class="number">7</td><td>    this-&gt;scrollType <span class="k3">=</span> scrollType<span class="k2">;</span></td></tr><tr><td class="number">8</td><td>    this-&gt;scrollSpeed <span class="k3">=</span> scrollSpeed<span class="k2">;</span></td></tr><tr><td class="number">9</td><td>    this-&gt;x <span class="k3">=</span> x<span class="k2">;</span></td></tr><tr><td class="number">10</td><td>    this-&gt;y <span class="k3">=</span> y<span class="k2">;</span></td></tr><tr><td class="number">11</td><td>    </td></tr><tr><td class="number">12</td><td>    <span class="c">//tmpBuffer = create_bitmap(SCREEN_W, SCREEN_H);</span></td></tr><tr><td class="number">13</td><td>    tmpBuffer <span class="k3">=</span> <a href="http://www.allegro.cc/manual/create_video_bitmap" target="_blank"><span class="a">create_video_bitmap</span></a><span class="k2">(</span><a href="http://www.allegro.cc/manual/SCREEN_W" target="_blank"><span class="a">SCREEN_W</span></a>, <a href="http://www.allegro.cc/manual/SCREEN_H" target="_blank"><span class="a">SCREEN_H</span></a><span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">14</td><td><span class="k2">}</span>    </td></tr><tr><td class="number">15</td><td>&#160;</td></tr><tr><td class="number">16</td><td>GameBackground::~GameBackground<span class="k2">(</span><span class="k2">)</span></td></tr><tr><td class="number">17</td><td><span class="k2">{</span></td></tr><tr><td class="number">18</td><td>    <a href="http://www.allegro.cc/manual/destroy_bitmap" target="_blank"><span class="a">destroy_bitmap</span></a><span class="k2">(</span>tmpBuffer<span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">19</td><td><span class="k2">}</span></td></tr><tr><td class="number">20</td><td>&#160;</td></tr><tr><td class="number">21</td><td><span class="k1">void</span> GameBackground::update<span class="k2">(</span><span class="k2">)</span></td></tr><tr><td class="number">22</td><td><span class="k2">{</span></td></tr><tr><td class="number">23</td><td>    scrollBackground<span class="k2">(</span><span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">24</td><td><span class="k2">}</span></td></tr><tr><td class="number">25</td><td>&#160;</td></tr><tr><td class="number">26</td><td><span class="k1">void</span> GameBackground::scrollBackground<span class="k2">(</span><span class="k2">)</span></td></tr><tr><td class="number">27</td><td><span class="k2">{</span></td></tr><tr><td class="number">28</td><td>    <span class="k1">switch</span><span class="k2">(</span>scrollType<span class="k2">)</span></td></tr><tr><td class="number">29</td><td>    <span class="k2">{</span></td></tr><tr><td class="number">30</td><td>        <span class="k1">case</span> HORIZONTAL_LEFT:</td></tr><tr><td class="number">31</td><td>            scrollLeft<span class="k2">(</span><span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">32</td><td>            <span class="k1">break</span><span class="k2">;</span></td></tr><tr><td class="number">33</td><td>        default:</td></tr><tr><td class="number">34</td><td>            <span class="k1">break</span><span class="k2">;</span></td></tr><tr><td class="number">35</td><td>    <span class="k2">}</span>    </td></tr><tr><td class="number">36</td><td><span class="k2">}</span></td></tr><tr><td class="number">37</td><td>&#160;</td></tr><tr><td class="number">38</td><td><span class="k1">void</span> GameBackground::draw<span class="k2">(</span><span class="k2">)</span></td></tr><tr><td class="number">39</td><td><span class="k2">{</span></td></tr><tr><td class="number">40</td><td>    <a href="http://www.allegro.cc/manual/draw_sprite" target="_blank"><span class="a">draw_sprite</span></a><span class="k2">(</span>GameManager::currentPage, tmpBuffer, <span class="n">0</span>, <span class="n">0</span><span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">41</td><td><span class="k2">}</span>    </td></tr><tr><td class="number">42</td><td>&#160;</td></tr><tr><td class="number">43</td><td><span class="k1">void</span> GameBackground::setScrollSpeed<span class="k2">(</span><span class="k1">int</span> speed<span class="k2">)</span></td></tr><tr><td class="number">44</td><td><span class="k2">{</span></td></tr><tr><td class="number">45</td><td>    scrollSpeed <span class="k3">=</span> speed<span class="k2">;</span></td></tr><tr><td class="number">46</td><td><span class="k2">}</span>    </td></tr><tr><td class="number">47</td><td>&#160;</td></tr><tr><td class="number">48</td><td><span class="k1">void</span> GameBackground::scrollLeft<span class="k2">(</span><span class="k2">)</span></td></tr><tr><td class="number">49</td><td><span class="k2">{</span></td></tr><tr><td class="number">50</td><td>    x <span class="k3">-</span><span class="k3">=</span> scrollSpeed<span class="k2">;</span></td></tr><tr><td class="number">51</td><td>    </td></tr><tr><td class="number">52</td><td>    <span class="k1">int</span> bw <span class="k3">=</span> bitmap-&gt;w<span class="k2">;</span></td></tr><tr><td class="number">53</td><td>    <span class="k1">int</span> bh <span class="k3">=</span> bitmap-&gt;h<span class="k2">;</span></td></tr><tr><td class="number">54</td><td>    </td></tr><tr><td class="number">55</td><td>    <span class="k1">int</span> xOffSet <span class="k3">=</span> <span class="k2">(</span><a href="http://www.allegro.cc/manual/SCREEN_W" target="_blank"><span class="a">SCREEN_W</span></a> <span class="k3">+</span> bw<span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">56</td><td>    </td></tr><tr><td class="number">57</td><td>    <span class="k1">if</span> <span class="k2">(</span> x <span class="k3">&gt;</span> bw <span class="k3">|</span><span class="k3">|</span> x <span class="k3">&lt;</span> <span class="k3">-</span><span class="k2">(</span>bw<span class="k2">)</span> <span class="k2">)</span></td></tr><tr><td class="number">58</td><td>    <span class="k2">{</span> </td></tr><tr><td class="number">59</td><td>        x <span class="k3">=</span> <span class="n">0</span><span class="k2">;</span></td></tr><tr><td class="number">60</td><td>    <span class="k2">}</span>    </td></tr><tr><td class="number">61</td><td>    </td></tr><tr><td class="number">62</td><td>    <span class="k1">int</span> newX <span class="k3">=</span> <span class="n">0</span><span class="k2">;</span></td></tr><tr><td class="number">63</td><td>    </td></tr><tr><td class="number">64</td><td>    <span class="k1">for</span> <span class="k2">(</span><span class="k1">int</span> i <span class="k3">=</span> <span class="k3">-</span><span class="k2">(</span>bw<span class="k2">)</span><span class="k2">;</span> i <span class="k3">&lt;</span> <span class="k2">(</span>xOffSet<span class="k2">)</span><span class="k2">;</span> i <span class="k3">+</span><span class="k3">=</span> bw<span class="k2">)</span></td></tr><tr><td class="number">65</td><td>    <span class="k2">{</span></td></tr><tr><td class="number">66</td><td>        newX <span class="k3">=</span> <span class="k2">(</span>x <span class="k3">+</span> i<span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">67</td><td>        </td></tr><tr><td class="number">68</td><td>        <span class="k1">for</span> <span class="k2">(</span><span class="k1">int</span> j <span class="k3">=</span> <span class="n">0</span><span class="k2">;</span> j <span class="k3">&lt;</span> <a href="http://www.allegro.cc/manual/SCREEN_H" target="_blank"><span class="a">SCREEN_H</span></a><span class="k2">;</span> j <span class="k3">+</span><span class="k3">=</span> bh<span class="k2">)</span></td></tr><tr><td class="number">69</td><td>        <span class="k2">{</span></td></tr><tr><td class="number">70</td><td>            <span class="c">//draw tile</span></td></tr><tr><td class="number">71</td><td>            <span class="c">//Optimization: draw only parts that are visible to the screen            </span></td></tr><tr><td class="number">72</td><td>            <span class="k1">if</span> <span class="k2">(</span> <span class="k2">(</span> newX <span class="k3">+</span> bw<span class="k2">)</span> <span class="k3">&gt;</span> <span class="n">0</span> <span class="k2">)</span></td></tr><tr><td class="number">73</td><td>            <span class="k2">{</span></td></tr><tr><td class="number">74</td><td>                <a href="http://www.allegro.cc/manual/draw_sprite" target="_blank"><span class="a">draw_sprite</span></a><span class="k2">(</span>tmpBuffer, bitmap, newX, j<span class="k2">)</span><span class="k2">;</span>    </td></tr><tr><td class="number">75</td><td>            <span class="k2">}</span></td></tr><tr><td class="number">76</td><td>            <span class="k1">else</span></td></tr><tr><td class="number">77</td><td>            <span class="k2">{</span></td></tr><tr><td class="number">78</td><td>                <span class="k1">break</span><span class="k2">;</span></td></tr><tr><td class="number">79</td><td>            <span class="k2">}</span>    </td></tr><tr><td class="number">80</td><td>                    </td></tr><tr><td class="number">81</td><td>        <span class="k2">}</span>    </td></tr><tr><td class="number">82</td><td>    <span class="k2">}</span></td></tr><tr><td class="number">83</td><td><span class="k2">}</span></td></tr></tbody></table></div></div><p>

This way, my scrolling BG uses the video memory buffer and all the other objects are stored in the memory buffer.</p><p>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!
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (armond)</author>
		<pubDate>Wed, 07 Mar 2007 02:51:26 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>If you&#39;re the last poster on the topic you may only edit your last post.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Ceagon Xylas)</author>
		<pubDate>Wed, 07 Mar 2007 03:34:08 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Hmmm... I think that&#39;s a pretty bad feature. Anyway, you guys have any idea what I&#39;m doing wrong? Thanks!
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (armond)</author>
		<pubDate>Wed, 07 Mar 2007 11:19:09 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>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.</p><p>Now, to answer your question, to combine the two properly you need three bitmaps and one bitmap pointer:</p><p>back_buffer = Memory Bitmap<br />page_1 = Video Bitmap<br />page_2 = Video Bitmap<br />bmp_pointer = Pointer to page_1 and page_2 (depending on the frame)</p><p>Then, in order, here&#39;s what you want to do:</p><p>0.) Initialize bmp_pointer to point to page_2 and call show_video_bitmap() on page_1.</p><p>1.) Reset and render everything to back_buffer.<br />2.) blit() back_buffer to bmp_pointer.<br />3.) Call: show_video_bitmap(bmp_pointer);<br />4.) If bmp_pointer = page_1, switch it to page_2, else switch it to page_1.</p><p>If any of that is out of order, or if you&#39;ve mixed up what kind of bitmaps everything is, it won&#39;t work.</p><p>Also, using this method, you should <i>never</i> have to call the acquire and release commands since you only ever make one blit to video memory every frame.</p><p>But I still highly recommend you just double buffer with a vsync() call right before blitting the buffer to the screen, because it&#39;s simpler and achieves the exact same effect.</p><p>--- Kris Asick (Gemini)<br />--- <a href="http://www.pixelships.com">http://www.pixelships.com</a>
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Kris Asick)</author>
		<pubDate>Wed, 07 Mar 2007 18:03:59 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><div class="quote_container"><div class="title">Quote:</div><div class="quote"><p>
Hmmm... I think that&#39;s a pretty bad feature.
</p></div></div><p>
A perfect examples of why you should never take advice from your users.</p><div class="quote_container"><div class="title">Quote:</div><div class="quote"><p>
Hi! This is a continuation of this thread
</p></div></div><p>
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.</p><p>You wont get very far with that perspective <img src="http://www.allegro.cc/forums/smileys/tongue.gif" alt=":P" />
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (ImLeftFooted)</author>
		<pubDate>Thu, 08 Mar 2007 06:57:48 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>My intention was to make things clearer for for those who are interested to answer(thanks to you guys).</p><p>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&#39;s  nothing wrong with that, is there?
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (armond)</author>
		<pubDate>Thu, 08 Mar 2007 12:14:39 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Unfortunately you can only do page flipping <b>or</b> double buffer.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (ImLeftFooted)</author>
		<pubDate>Thu, 08 Mar 2007 12:16:36 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Thank you, it&#39;s a good thing that I have two of those techniques incorporated in my code so I could just switch between them.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (armond)</author>
		<pubDate>Thu, 08 Mar 2007 12:18:49 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Great!  I&#39;m glad you finally see the light.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (ImLeftFooted)</author>
		<pubDate>Thu, 08 Mar 2007 13:19:54 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Why would you want to switch between them? Or does the user get a choice in the matter?
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (James Stanley)</author>
		<pubDate>Thu, 08 Mar 2007 13:49:00 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><div class="quote_container"><div class="title">Quote:</div><div class="quote"><p>
James Stanley: Why would you want to switch between them? Or does the user get a choice in the matter?
</p></div></div><p>


To see which would perform better. I&#39;ll take this opportunity to let you guys see my source code. It comes with a dev-cpp project file. It&#39;s still far from finish but it&#39;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!</p><p>BTW, it uses Double Buffering as of now...</p><p>Please see attachment.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (armond)</author>
		<pubDate>Thu, 08 Mar 2007 14:40:21 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Congratulations! Your code causes an internal error in the MSVC 6.0 compiler! <img src="http://www.allegro.cc/forums/smileys/tongue.gif" alt=":P" /></p><p>Thus I can&#39;t compile it for an unknown reason.</p><p>In either case, I ran the included executable and can&#39;t find anything wrong.</p><p>Your speed issues likely relate to trying to process too much at too great a colour depth. If you&#39;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&#39;t very complicated. You may even want to try scaling down to 8-bit, though you&#39;ll have to tweak all your graphics into one palette if you do that, but you&#39;ll get the best framerate possible that way.)</p><p>Also, the keys you chose for controls prevented me from moving up, right, and shooting all at once. (Likely my keyboard didn&#39;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.)</p><p>Other than that, your code base is massive. It would take me forever to find any optimizations you could perform. <img src="http://www.allegro.cc/forums/smileys/shocked.gif" alt=":o" /></p><p>Lastly, if you&#39;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 &quot;frame dropping&quot; so that if the framerate drops too low the game will at least attempt to continue running the proper speed.</p><p>--- Kris Asick (Gemini)<br />--- <a href="http://www.pixelships.com">http://www.pixelships.com</a>
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Kris Asick)</author>
		<pubDate>Fri, 09 Mar 2007 03:46:34 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>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!
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (armond)</author>
		<pubDate>Fri, 09 Mar 2007 16:27:41 +0000</pubDate>
	</item>
</rss>
