Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » [A5] Fixed Aspect Ratio with Black Bars

Credits go to SiegeLord for helping out!
This thread is locked; no one can reply to it. rss feed Print
[A5] Fixed Aspect Ratio with Black Bars
Jeremiah Griffin
Member #13,948
January 2012
avatar

I am currently reworking an SDL 1.2/OpenGL codebase to use Allegro 5. My artist and I like to keep things simple and easy (for us), so we typically design our games to use a fixed resolution. However, to prevent the display from being stretched to a different aspect ratio, I implemented a fixed aspect ratio with letter/column boxes. This would fit a box of the given aspect ratio inside the display, taking up as much space as possible, and then adding black bars to the top/bottom or left/right as necessary. I used glViewport, glScissor, and glOrtho to accomplish this effect, like so:

float const aspectRatio = (float)VIEW_WIDTH / (float)VIEW_HEIGHT;
int clipWidth = width, clipHeight = width / aspectRatio;
int clipX = 0, clipY = (height - clipHeight) / 2;
if (clipY < 0)
{
    clipHeight = height;
    clipWidth = height * aspectRatio;
    clipX = (width - clipWidth) / 2;
    clipY = 0;
}
glViewport(clipX, clipY, clipWidth, clipHeight);
glScissor(clipX, clipY, clipWidth, clipHeight);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, clipWidth, clipHeight, 0, -1, 1);
glMatrixMode(GL_MODELVIEW);

And like this in Allegro 5:

#SelectExpand
1float const aspectRatio = (float)VIEW_WIDTH / (float)VIEW_HEIGHT; 2int clipWidth = width, clipHeight = width / aspectRatio; 3int clipX = 0, clipY = (height - clipHeight) / 2; 4if (clipY < 0) 5{ 6 clipHeight = height; 7 clipWidth = height * aspectRatio; 8 clipX = (width - clipWidth) / 2; 9 clipY = 0; 10} 11al_set_clipping_rectangle(clipX, clipY, clipWidth, clipHeight); 12 13float scaleX = (float)clipWidth / (float)VIEW_WIDTH, 14 scaleY = (float)clipHeight / (float)VIEW_HEIGHT; 15ALLEGRO_TRANSFORM projection; 16al_build_transform(&projection, clipX, clipY, scaleX, scaleY, 0.0f); 17al_use_transform(&projection);

Now, this works fine, until the size is drastically different from the "view" size (in this case, 736x768). Then my test function starts to fall apart. Literally.

for (float x = 0; x < 32; ++x)
    for (float y = 0; y < 32; ++y)
        al_draw_pixel(x, y, al_map_rgb(rand() % 255, rand() % 255, rand() % 255));

When the scale gets too big, the pixels start to move away from each other. I've attached 2 pictures demonstrating this problem (beware: one of them is rather large). I'm assuming this is due to the way Allegro transforms each individual pixel, and that the issue would go away when using bitmaps--however, I'd like to find a way to do this that works as expected with pixel-level drawing.

P.S. I am new to Allegro as a whole, this being my first time using it, so if anyone knows an all around better way of accomplishing this, I'd love to hear it.

SiegeLord
Member #7,827
October 2006
avatar

that the issue would go away when using bitmaps

It does.

Quote:

I'd like to find a way to do this that works as expected with pixel-level drawing.

It depends on what you want to happen when you zoom in. If you want to get big blocky pixels, you should draw pixels with al_draw_rectangle:

void draw_scalable_pixel(float x, float y, ALLEGRO_COLOR col)
{
    al_draw_filled_rectangle(x, y, x + 1, y + 1, col);
}

If not, you'll want to transform the vector representation of your pixel primitve. In this case you'd multiply the 32 in your loops by scaleX and scaleY for x and y respectively and then scale the coordinates you pass to al_draw_pixel:

for (float x = 0; x < 32 * scaleX; ++x)
    for (float y = 0; y < 32 * scaleY; ++y)
        al_draw_pixel(x / scaleX, y / scaleY, al_map_rgb(rand() % 255, rand() % 255, rand() % 255));

"For in much wisdom is much grief: and he that increases knowledge increases sorrow."-Ecclesiastes 1:18
[SiegeLord's Abode][Codes]:[DAllegro5]:[RustAllegro]

Jeremiah Griffin
Member #13,948
January 2012
avatar

It never occurred to me to emulate pixels using vertices. Thanks!

Go to: