NinePatch

Monkey Forums/Monkey Code/NinePatch

Nobuyuki(Posted 2013) [#1]
You should all know what this does. If you don't, then this picture might help explain:


NinePatch is a class I wrote sometime last year to deal with buttons for a game I was working on at the time. It takes a base image and stretches it selectively to make scaling artifacts less apparent. (This version of NinePatch doesn't have tiling capabilities.) Border thicknesses can be specified independently, in case you wish the center graphic to have higher resolution than the edges.

Source code is as follows:




Gerry Quinn(Posted 2013) [#2]
Heh, I did something similar just last week. Yours is neater, though. I just tiled everything as I didn't think of selective stretching.


Gerry Quinn(Posted 2013) [#3]
Just a suggestion about the 'seams' issue you mention: why not stretch the non-corner pieces an extra pixel or so - won't that eliminate any possibility of seams? Of course this won't work if the images are part transparent.


Nobuyuki(Posted 2013) [#4]
> Of course this won't work if the images are part transparent.

Exactly. Even stranger, though, is the fact that Firefox applies some sort of filtering when applying hue to the image before it's even blitted to screen, so even without changing the global scale, you could run into this!

I'm sure both of these problems could be resolved a better way; In the latest Monkey, importing Gles11 and using LoadImageData() to grab rgba pixels directly could in theory let a tiling (instead of a stretching) 9-patch generate a static image with no seams, even if the global scale isn't 1.0 and the component image contains alpha. But who knows how inefficient that would be at runtime when you're constantly having to redraw it on resize and keep the texture in standard RAM instead of VRAM..


Gerry Quinn(Posted 2013) [#5]
I used the tiling technique to generate fresh images in the render buffer which I then grabbed using ReadPixels and WritePixels. So I only have to generate fresh graphics when screen elements are resized (which can happen at the start or when game parameters such as board size are changed). Thus the inefficiency shouldn't be an issue in practice.

Should work well for things like buttons.


Nobuyuki(Posted 2013) [#6]
Well, true, I guess my mind is always thinking of the edge cases, like animating a dialog window, but I guess there's no point in doing that if most animations would look almost-as-good just scaling the final texture :)


Gerry Quinn(Posted 2013) [#7]
Yours is actually much simpler than mine and would be much faster if you want to do it on the fly. The only problem is the risk of overlaps if your images are not full opaque.

I think there are uses for both techniques.