Search code examples
c++bitmapallegroallegro5

Drawing antialiased primitives to bitmap Allegro 5


I'm working on a little project using C++ and Allegro 5, my question is

Is there a way to draw antialiased primitives to a bitmap using Allegro 5? I mean I'm using this function

void draw_to_gameBuffer(ALLEGRO_BITMAP *&gameBuffer, ALLEGRO_DISPLAY *&display)
{
    static float x = 0;

    al_set_target_bitmap(gameBuffer);
    al_draw_filled_rectangle(0,0, 350, 622, al_map_rgb(130, 80, 120));
    al_draw_filled_circle(x, 200, 100, al_map_rgb(12, 138, 129));
    al_draw_filled_triangle(0, 0, 100, 0, 50, 100, al_map_rgb(12, 138, 129));

    x += 2.7;
    if(x > 350 + 100)
        x = -250;

    al_set_target_backbuffer(display);
}

to draw a cicle and a triangle (testing purposes) over a target bitmap as shown, on the project display options I have

al_set_new_display_option(ALLEGRO_SAMPLE_BUFFERS, 4, ALLEGRO_SUGGEST);
al_set_new_display_option(ALLEGRO_SAMPLES, 8, ALLEGRO_SUGGEST);

to enable antialiasing, the problem is that all primitives rendered on the gameBuffer have jaggies but the primitives rendered outside the gameBuffer are perfectly smooth, how can I solve that? Or is there a way to do what I'm trying to do and get smooth primitives drawn on the gameBuffer?


Solution

  • It seems that Allegro 5 has some experimental features that can be enabled defining this macro (before defining any allegro header):

    #define ALLEGRO_UNSTABLE
    

    With this macro enabled we are able to create a bitmap to draw anything we want and do whatever we want with the bitmap, yes we can do this without enabling the ALLEGRO_UNSTABLE macro but there's this new procedure called:

    al_set_new_bitmap_samples(int numberOfSamplesDesired);
    

    that defines how many samples we want in a newly created bitmap, "the downside" of this implementation is that it's only going to work with OpenGl so... we need to force OpenGl (Windows only) to see this new feature working and, how do we put this together and draw antialiased primitives over bitmaps?

    first of all, we need to define the ALLEGRO_UNSTABLE macro

    #define ALLEGRO_UNSTABLE
    

    then we need to add some allegro headers (the ones we need)

    #include <allegro5/allegro.h>
    #include <allegro5/allegro_primitives.h>
    

    after this we need to define a bitmap

    ALLEGRO_BITMAP *buffer = nullptr;
    

    now we enable OpenGl and the flags we want and the display options

    al_set_new_display_flags(ALLEGRO_WINDOWED | ALLEGRO_RESIZABLE | ALLEGRO_OPENGL);
    al_set_new_display_option(ALLEGRO_SAMPLE_BUFFERS, 2, ALLEGRO_SUGGEST); //antialias stuff
    al_set_new_display_option(ALLEGRO_SAMPLES, 4, ALLEGRO_SUGGEST); //antialias stuff
    

    to create our bitmap we first call the experimental procedure then create our bitmap

    al_set_new_bitmap_samples(4);
    buffer = al_create_bitmap(bufferWidth, bufferHeight);
    

    4 samples as an example (lol), to draw to the bitmap we use a procedure like this

    void draw_to_buffer(ALLEGRO_BITMAP *&buffer, ALLEGRO_DISPLAY *&display) 
    { 
        al_set_target_bitmap(buffer); 
    
        al_clear_to_color(al_map_rgb(0, 0, 0));
    
        //anything you want to draw to the bitmap
    
        al_set_target_backbuffer(display); 
    }
    

    now we just need to draw our bitmap the way we usually draw bitmaps on screen

    al_draw_bitmap(buffer, 0, 0, 0);
    

    and that's pretty much it, if you have issues or questions with this implementation, yo can look at my post in the Allegro forums where I got the help of many lovely allegro users that taught me a lot without knowing.

    my post in the Allegro forum