Thread: double buffering for allegro

  1. #1
    Unregistered Leeman_s's Avatar
    Join Date
    Oct 2001
    Posts
    753

    double buffering for allegro

    in the following code I made a few custom modifications to get allegro at its best. first you'll see i made a function to draw with buffering, and second i tried to implement double buffering to reduce flicker when drawing a background each cycle through the main loop. I created a BITMAP** primary_buffer which holds which buffer we should draw to. then at the end of each cycle it switches what buffer primary_buffer is pointing to.

    example: in the function buffdraw, it will draw the object to put on the screen on to primary_buffer which is pointing to buffer. then it will print onto the screen whatever is on buffer2, so this way it doesnt pring what we just put onto buffer, but what we previously had put on buffer2. then next time primary buffer will be buffer2 and it will print the object onto buffer2, and print onto the screen what we had previously put in buffer. see what i mean? here is the code, but nothing shows up on the screen when i run it. if you have allegro you can try compiling it.
    Code:
    #include <allegro.h> // You must include the Allegro Header file
    
    void buffdraw(BITMAP *buffer, BITMAP *buffer2, BITMAP **primary_buffer, BITMAP *t_Bitmap_obj, int x, int y);
    void increase_speed();
    
    volatile long speed_counter = 0;//A long integer which will store the value of the
                                              //speed counter.
    
    int main(int argc, char *argv[])
    {
    	bool validness;
    	int wBuffer=1;
    
    	allegro_init(); // Initialize Allegro
    	install_keyboard(); // Initialize keyboard routines
    	set_color_depth(16); // Set the color depth						
    	set_gfx_mode(GFX_AUTODETECT, 640,480,0,0); // Change our graphics mode to 640x480
    	install_timer();
    	LOCK_VARIABLE(speed_counter);
    	LOCK_FUNCTION(increase_speed);
    	install_int_ex(increase_speed, BPS_TO_TIMER(100));//Set our BPS
    
    	BITMAP *my_pic; //Declare a BITMAP called my_pic
    	my_pic = load_bitmap("picture.bmp", NULL); // Load our picture
    
    	BITMAP *buffer; //Declare a BITMAP called buffer.
    	BITMAP *buffer2;
    	BITMAP **primary_buffer = &buffer;
    
    	BITMAP *background;
    	background = load_bitmap("lee.bmp", NULL);
    
    	buffer = create_bitmap(640,480); //Create an empty bitmap.
    	buffer2 = create_bitmap(640, 480);
    
    	int my_pic_x = 0;// Holds our pictures X coorinate
    	int my_pic_y = 0;// Holds our picture's Y coordinate
    
    	while(!key[KEY_ESC])//If the user hits escape, quit the program
    	{
    		while(speed_counter > 0)
    		{
    		    validness = true;
    
    		    /*****************************
    		    Here is a series of tests - so we can move 
    		    our bitmap around the screen
    		    ****************************/
    		    if(key[KEY_RIGHT])// If the user hits the right key, change the picture's X coordinate
    		    {
    			    my_pic_x++;// Moving right so up the X coordinate by 1
    			    if(my_pic_x > 608)
    		    	{
    		    		validness = false;
    			    	my_pic_x--;
    			    }
    		    }
    		    else if(key[KEY_LEFT])// Ditto' - only for left key
    		    {
    			    my_pic_x--;// Moving left, so lower the X coordinate by 1
    			    if(my_pic_x < 0)
    			    {
    				    validness = false;
    				    my_pic_x++;
    			    }
    		    }
    		    else if(key[KEY_UP])// If the user hits the up key, change the picture's Y coordinate
    		    {
    			    my_pic_y--;// Moving up, so lower the Y coordinate by 1
    			    if(my_pic_y < 0)
    			    {
    				    validness = false;
    				    my_pic_y++;
    			    }
    		    }
    		    else if(key[KEY_DOWN])// Ditto' - only for down
    		    {
    			    my_pic_y++;// Moving down, so up the Y coordinate by 1
    			    if(my_pic_y > 448)
    			    {
    				    validness = false;
    				    my_pic_y--;
    			    }
    		    }
    			speed_counter--;
    		};
    		
    		if(validness == true)
    		{
    		    acquire_screen();// Get the screen
    
    			buffdraw(buffer, buffer2, primary_buffer, background, 0, 0);
    
    		    buffdraw(buffer, buffer2, primary_buffer, my_pic, my_pic_x, my_pic_y);
    
    			if(*primary_buffer == buffer)
    			{
    				primary_buffer = &buffer2;
    				wBuffer = 2;
    			}
    			if(*primary_buffer == buffer2)
    			{
    				primary_buffer = &buffer;
    				wBuffer = 1;
    			}
    
    		    release_screen();// Release it
    		}
    	};
    
    
    	destroy_bitmap(my_pic);//Release the bitmap data
    	destroy_bitmap(buffer);//Release the bitmap data
    	destroy_bitmap(background);
    
    
    	return(0);// Exit with no errors
    }
    END_OF_MAIN(); // This must be called right after the closing bracket of your MAIN function.
                   // It is Allegro specific.
    
    void buffdraw(BITMAP *buffer, BITMAP *buffer2, BITMAP **primary_buffer, BITMAP *t_Bitmap_obj, int x, int y)
    {
    	draw_sprite(*primary_buffer, t_Bitmap_obj, x, y);
    
    	if(*primary_buffer == buffer2)
    	    blit(buffer, screen, 0,0,0,0,640,480);
    	if(*primary_buffer == buffer)
    		blit(buffer2, screen, 0,0,0,0,640,480);
    }
    END_OF_FUNCTION(buffdraw);
    
    void increase_speed()
    {
    	speed_counter++;
    }
    END_OF_FUNCTION(increase_speed);

  2. #2
    Unregistered Leeman_s's Avatar
    Join Date
    Oct 2001
    Posts
    753
    well, i got it to work by doing:

    Code:
    void buffdraw(BITMAP *buffer, BITMAP *buffer2, BITMAP **primary_buffer, BITMAP *t_Bitmap_obj, int x, int y)
    {
    	blit(*primary_buffer, screen, 0,0,0,0,640,480);
    	draw_sprite(*primary_buffer, t_Bitmap_obj, x, y);
    }
    although a nice idea, it didn't reduce the flicker. anybody know what to do?

  3. #3
    Unregistered Leeman_s's Avatar
    Join Date
    Oct 2001
    Posts
    753
    this is a toughie i guess

  4. #4
    Registered User fry's Avatar
    Join Date
    Mar 2002
    Posts
    128
    I followed through the code....
    I cant seem to work out why it _would_ reduce flicker. If you didnt have the "buffer2" bitmap, then it wouldnt make a difference. I think what your trying to do is triple buffering.
    IDE: Dev C++ 5
    Lib: Allegro
    OS: Windows 2000

  5. #5
    Unregistered Leeman_s's Avatar
    Join Date
    Oct 2001
    Posts
    753
    yes, i made a mistake i mean "triple buffering" not double. why do you say it woudn't make a difference if i didnt have buffer2? every time through the loop, primary buffer changes between buffer 1 and 2.

    so whats happening is:

    1. we blit to the screen what is on buffer. (first time through will show nothing, since buffer holds nothing yet.)
    2. we blit to buffer2 whatever we wanted to draw to the screen.
    3. Next time through the loop we blit to the screen what is on buffer2.
    4. we blit to buffer whatever we are blitting.
    .....and so on.

    while writing this reply i think i figured out what im doing wrong! i dont have my new source up because im at school, but this is what will happen:

    buffdraw has two things that get done:

    1. blit to a buffer
    2. blit buffer to the screen

    i am just switching primarybuffer at the wrong time. so now heres how it will work correctly:

    1. blit to primarybuffer(points to buffer)
    2. change primarybuffer to the other buffer (now primarybuffer is buffer2)
    3. blit primarybuffer to the screen (buffer2 which is nothing now)
    4. next time through:blit to primarybuffer (buffer2)
    5. change primarybuffer to the other buffer (now primarybuffer is buffer)
    6. blit primarybuffer to the screen (buffer)

    aha so i have it! triple buffering in allegro! i hope the flicker goes away, not sure if it will.

  6. #6
    Blank
    Join Date
    Aug 2001
    Posts
    1,034
    You probably want to use page flipping. There's an
    example of that in the allegro doc. If you do not
    use page flipping then use a double buffer like this.

    blit stuft to backbuffer.
    wait for vsync
    blit backbuffer to screen
    Experiment also with keeping the backbuffer in video memory
    along with the sprites but this adds some more complication.

    I don't see any real point using tripple buffering with
    out page flipping?

  7. #7
    Blank
    Join Date
    Aug 2001
    Posts
    1,034
    I'll try to explain better.
    When you use a double buffer you have
    something like what's above. You have to wait
    for the vsync because otherwise you could be drawing
    the backbuffer onto the screen while the screen is updating
    itself. Tearing results.

    http://agdn.netfirms.com/html/pflip.htm
    This looks like an ok example on how to do hardware
    page flipping in allegro. You don't blit the backbuffer to
    the screen so this is usually faster.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Copying 2-d arrays
    By Holtzy in forum C++ Programming
    Replies: 11
    Last Post: 03-14-2008, 03:44 PM
  2. Conversion From C++ To C
    By dicon in forum C++ Programming
    Replies: 2
    Last Post: 06-10-2007, 02:54 PM
  3. need some help with last part of arrays
    By Lince in forum C Programming
    Replies: 3
    Last Post: 11-18-2006, 09:13 AM
  4. newbie needs help with code
    By compudude86 in forum C Programming
    Replies: 6
    Last Post: 07-23-2006, 08:54 PM
  5. Unknown Math Issues.
    By Sir Andus in forum C++ Programming
    Replies: 1
    Last Post: 03-06-2006, 06:54 PM