I am looking at making a 'retro' thing with pixel graphics - the base resolution is 160x120 pixels. Obviously some scaling will be needed - this is smaller than some icons on modern screens!
What's the best way to this?
Draw everything onto an off-screen bitmap and then stretch it to fill the window?
Or scale all the images as they are loaded and draw them 1:1
Or something else (apply a transformation to the screen?)
Render normal then scale up using a selection of pixel filters.
Pixel-perfect (can't remember exact term, just repeat the same source pixel, no blending)
Bilinear (mushy)
2xSAI / HQ2x / HQ4x
CRT shader
That's the usual stuff people offer.
If it's 4:3, add black borders or add side artwork (but definitely give option for black borders).
-> Consider picking a proper widescreen "low res" mode (or supporting it as an option). In 99% of cases, there's no need to leave dead areas in people's monitors. 4:3 isn't some magical ratio, and people will likely "feel" the retro just fine in 16:9--and worse, if you show black bars or artwork it INSTANTLY brings your eyes attention to the fact that it's 4:3, which means they're focusing on the bars and not the game experience! (Usually) the last thing you want in entertainment is to remind everyone that they're sitting in a chair and staring at a screen instead of "in the world".
I've got an (albeit rather convoluted) setup for this in my game. The main draw code writes to the backbuffer (such that we can get antialiased primitives etc.), then the backbuffer is copied to a buffer bitmap, which is the same size as your 'retro' resolution, which is itself scaled over the backbuffer.
I've got an (albeit rather convoluted) setup for this in my game. The main draw code writes to the backbuffer (such that we can get antialiased primitives etc.)
You can enable anti-aliasing and multi-sampling on other bitmaps. There's no need to draw the backbuffer onto another buffer to draw back to the backbuffer...
https://liballeg.org/a5docs/trunk/graphics.html#al_set_new_bitmap_samples
Oh, well I guess that's part of the UNSTABLE api and only works on OpenGL.
Draw everything onto an off-screen bitmap and then stretch it to fill the window?
Or scale all the images as they are loaded and draw them 1:1
Or something else (apply a transformation to the screen?)
Render everything normal size to the smaller buffer, then transform it or shader it onto the screen.
Thanks all. Nice to have asked a programming question for once!
Oh, well I guess that's part of the UNSTABLE api and only works on OpenGL.
Yeah, compatibility was my main gripe with al_set_new_bitmap_samples. Would definitely use that once it's stabilised (and D3D-capable), but the back-and-forth method seems fast enough for now
Has anyone got any code using CRT shaders (as mentioned by Chris Katko)? I've googled some shader code but not sure how to set it up in Allegro - is it as simple as al_use_shader and then blitting a bitmap?
I've got a simple shader demo lying around somewhere - let me dig it up.
It's pretty straight forward - you build and compile the shader, then you use it whenever you want to draw a bitmap using your shader.
If you hold the left mouse button, it makes the texture all wavy. Very simple demo. I still don't understand it much myself which is why I haven't done more complicated things with it.
But the basics of it is here :
The vertex shader is stupid and just passes on data.
void main(void) { gl_Position = ftransform(); gl_TexCoord[0] = gl_MultiTexCoord0; gl_FrontColor = gl_Color; }
The fragment (pixel) shader just messes with the uv coordinates of the source.