Draw retro ("big" pixels) graphics

Monkey Forums/Monkey Programming/Draw retro ("big" pixels) graphics

MonoDesire(Posted 2016) [#1]
Hello!

I'm working on a game with retro graphics, i.e. "big" pixels. What is the best way of handle the graphics for this kind of style?

Let's say I want to draw all graphics like I had a 320x200 display, but in reality, the display is probably much larger.

I've read about this, to avoid blurry pictures when scaling up:
#MOJO_IMAGE_FILTERING_ENABLED=False

But by using the above technique would require a lot of scaling.

I would like a way to "trick" Monkey-X that I am using a 320x200 "canvas", and then Monkey-X is automatically scaling my "canvas" up to the real display (whatever it is). Is there a way to set this kind of "canvas" area?

All help is appreciated! :-)


Nobuyuki(Posted 2016) [#2]
Scaling is cheap/free on modern hardware. You can use the #MOJO_IMAGE_FILTERING_ENABLED=False trick if you want, or if you're using Mojo2 you can choose to upscale a small surface.


DruggedBunny(Posted 2016) [#3]
Try AutoFit.


MonoDesire(Posted 2016) [#4]
Thank you both for your replies! :-)

I will check out your suggestions.


Leo Santos(Posted 2016) [#5]
I would definitely check Mojo2.

There are a few more steps and the code gets a little longer than Mojo1 (you always have to create a canvas, then specify which canvas you're drawing to), but it's very fast on HTML5, and the filtering setting seems to work well in all browsers that support WebGL.

The basic idea is that you do all your rendering in a small texture (let's say, 320x240) with filtering off, then you draw that texture filling the main canvas. That way, when you draw the sprites you're using a "true" 320x240 resolution, and you're just scaling the whole thing once before displaying it. It also makes it more or less easy to control how you're gonna fill up the main canvas - you can stretch it, leave black bars around it to preserve aspect ratio, opt for an integer scale that ensures all pixels are scaled equally, etc.

One thing to keep in mind, though, is that if you're going for "pixel-perfect", it's usually a good idea to create the texture width and height using the nearest power of two values (128, 256, 512, etc) and simply not use the whole texture - take a look at SetProjection2d and SetViewport functions. I had some issues with images scaling properly when the texture is not power of two, particularly noticeable when the image has dithering patterns.

Unfortunately, docs are sparse about these things, and the online docs don't even seem to include mojo2 yet. You may have to do quite a lot of googling around the forums...


Neuro(Posted 2016) [#6]
In mojo2, when you set the image using this :
Image.SetFlagsMask(Image.Managed); 
img_raider = Image.Load("Raider.png");


To sorta get that clean pixelated look. Was gonna use it for last year's NES Game Jam but eh...i'm slow :(.


MonoDesire(Posted 2016) [#7]
Thank you for this additional info! :-)

Appreciate it a lot.


MonoDesire(Posted 2016) [#8]
I went for the mojo2 track. It looks promising. But I am confused about the aspect ratio of the canvas (currently running the HTML5 target).

@Leo Santos:

You wrote this:
"It also makes it more or less easy to control how you're gonna fill up the main canvas - you can stretch it, leave black bars around it to preserve aspect ratio, opt for an integer scale that ensures all pixels are scaled equally, etc."


I'm not sure how to accomplish this - I want my canvas to have its ratio preserved (e.g. 640x480). I have found the "canvas" keyword in various places, and I am not sure how they relate to each other.

* I have a Canvas within my Monkey-X code, which I have drawn some images to, just to try out the concept. It works. I use SetProjection2d() to set a virtual area of e.g. 640x480. It works.

* Then, in the auto-generated MonkeyGame.html file, I also find the concept of "canvas". I see there CANVAS_WIDTH and CANVAS_HEIGHT. There is also an interesting variable called CANVAS_RESIZE_MODE.

* Also in the MonkeyGame.html file, there is this: <canvas id="GameCanvas" width=640 height=480 tabindex=1></canvas>

Any hints are appreciated!

Thanks!


MonoDesire(Posted 2016) [#9]
Maybe my previous post isn't very clear, so I'll add a proper question here:

How to I preserve the aspect ratio of my the canvas (i.e. the Canvas object within Monkey-X) no matter size/proportions of the physical screen? I'd like my canvas to stay centered within the screen. What is the best of doing that?

Thanks!


ImmutableOctet(SKNG)(Posted 2016) [#10]
You have a few options, but the two best examples I can think of are:
* The official "letterbox" banana found at "modules/mojo2/bananas/letterbox/letterbox.monkey", which does this using the 'SetProjection2d' route.
* My rewrite of AutoFit, which works with both Mojo 1 and Mojo 2. (Mojo 2 behavior may or may not work well)

My particular solution isn't exactly the most optimal, but it may be a useful reference. I'd say you should follow the official example. Basically, it has a method called 'CalcLetterbox', which uses the aspect ratios of the two resolutions and scales the viewport accordingly (Passes the output-array to 'SetViewport'). It uses the difference to know how big of an area will be blank. It's nothing complicated, but it gets the job done pretty well. If you want a system that can layer scaling so you can have different effective resolutions, or anything more advanced, then you might need to use matrix transformations.


MonoDesire(Posted 2016) [#11]
Thanks a lot for your reply ImmutableOctet(SKNG)! Appreciate it a lot! :-)

I will have a look at both your suggestions.

If you want a system that can layer scaling so you can have different effective resolutions, or anything more advanced, then you might need to use matrix transformations.


What do you mean by "layer scaling"? Maybe nothing I need, but curious what it is.


ImmutableOctet(SKNG)(Posted 2016) [#12]
I don't mean scaling layers, I mean having multiple viewports (Potentially inside of each other) following different resolutions. For example, a split-screen game where you have a menu at the native resolution (Or similar), and a split-screen game under it. That's not something everyone wants, but it's something I was interested in when I remade AutoFit.


MonoDesire(Posted 2016) [#13]
@ImmutableOctet(SKNG):

Okay, I get it now. Thanks for the clarification! :-)