|
[A5] Fixed Aspect Ratio with Black Bars |
Jeremiah Griffin
Member #13,948
January 2012
|
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: 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
|
Jeremiah Griffin said: 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 |
Jeremiah Griffin
Member #13,948
January 2012
|
It never occurred to me to emulate pixels using vertices. Thanks!
|
|