Mirror Test

BlitzMax Forums/BlitzMax Programming/Mirror Test

Tricky(Posted 2006) [#1]
In my next production I need a routine that can mirror a TImage with all its possible frames. Since there's (as far as I know) no more ImageBuffer available, I had to figure something out myself. I went diggin' into the sources of the modules. I really wonder if they couldn't be made any simpler, so it took a lot of digesting, and I still don't think I've found all I need to know.

In the end I came up with this source to do the trick:
Strict

Rem Mirror
	
	Worked by these persons:
	Tricrokra	June 3 2005		Basis source
	
End Rem

Function Mirror:TImage(Img:TImage,Frames=1)
Local Ret:TImage
Local Ak,XX,YY
Ret = CreateImage(ImageWidth(Img),ImageHeight(Img),Frames)
For Ak=0 To Frames-1
	Ret.PixMaps[Ak] = CreatePixmap(ImageWidth(Img),ImageHeight(Img),PF_BGRA8888)
	For XX=0 To ImageWidth(Img)-1
		For YY=0 To ImageHeight(Img)-1
			WritePixel Ret.PixMaps[Ak],(ImageWidth(Img)-1)-XX,YY,ReadPixel(Img.PixMaps[Ak],XX,YY)
			Next
		Next
	Next
Ret.mask_r = Img.mask_r
Ret.mask_g = Img.mask_g
Ret.mask_b = Img.mask_b
Return Ret
End Function


The first tests had good results, but I wonder if this routine would cover everything that needs to be covered, or if I should code it diffrently. Anyway, the routine appears to be working, perfectly, at least that's what the eyes indicate, and that's what matters for me for the time being.

If you think this routine should be altered somehow, then let me know. If you think this routine is perfect the way it is, you're free to use it if you need it.


Regular K(Posted 2006) [#2]
SetScale -1,1



Dreamora(Posted 2006) [#3]
How about: SetScale -1,1 or SetScale 1,-1 with a following drawimage ... ;-)
And if you need it within a static object you could regrab it.


Tricky(Posted 2006) [#4]
That idea did cross my mind, really.
Problem is this...
This routine was built because I needed to have an image facing left, and one facing right. A routine would auto-detect if the facing right version exists, if not then automaticly mirror it. Therefore I needed the mirrored version to be directly put into a TImage, and not having it to put on the screen first to regrab it. The user would always see that.

Of course I could leave the mirrored TImage empty, and have a routine that would do auto scale -1 if the empty one was detected. But due to the complexibitily this project has already that method did not really have my first preferrence.

Thanks for the suggestion anyway ;)


GfK(Posted 2006) [#5]
Why would you waste more resources storing what's essentially two copies of the same image, when you can use just one with SetScale?

I don't understand your reasoning for not doing so in the above post.


Grisu(Posted 2006) [#6]
I'm with Gfk, plus writepixel etc is slow (tm)!


(tu) ENAY(Posted 2006) [#7]
Setscale of -1 flips your image in realtime.
Why do you want to make extra image space in memory for no apparent reason.

Especially when you could do something simple like this:-

Const FACING_LEFT = 0
Const FACING_RIGHT = 1

If my_heroic_sprite_frame = FACING_LEFT Then
 SetScale -1,1
Else
 SetScale 1,1
Endif

DrawImage sprite, x, y



I hope you're not planning on loading a sound into memory twice, one for each speaker.


Tricky(Posted 2006) [#8]
Heheh.... I do get your reasoning, it really does seem as wasting memory, I know that. If the program wasn't so complex I would have used the setscale thing. But since not all sprites have to be mirrored things did become a little complicated. Most of the used characters as not simetric, so they have to be drawn from both sides anyway, meaning two TImages were needed anyway. Only those few who where simetric were to be mirrored this way in order to save a much work as possible (as little as it would be). Using "SetScale" would limit me to the simetric characters, or setting much complexibility in my DrawScreen routine, which is one that already contains more mathematics than my brain could take (ok, that may be an overstatement, since if it were I couldn't get this working). That's the reason why this method was chosen, and not setscale, which was my first thought as well. (Trust me, I only use up extra memory if that is the best way to go. If I didn't have to deal with as well simetric as non-simetric creatures, I wouldn't have bothered and used setscale instead).

Now the mirroring was not the most important part of my post.
It's more if that it may become possible for me to have to render more images on a semiliar way. And I was more inquiring on if all was covered in the direct in-image access. I couldn't really figure the best way out, y'see.


(tu) ENAY(Posted 2006) [#9]
Ok I kind of see what you're getting at now. You mean like if you had a pirate with a patch over his eye, you couldn't flip it because it would then swap eye on the images. Or someone with a right handed axe, yes then that would make sense.

However, for non symmetrical characters you're just gonna load in two images anyway. So instead of filling up memory space just to make your non-symmetrical have two sets of frames to make up the numbers.
Why don't you just have a flag for all your characters that ARE symmetrical and then have a slightly different drawing routine so you can use setscale just for those.

Like this:-

Const FACING_LEFT = 0
Const FACING_RIGHT = 1

Const NON_SYMMETRICAL = 0
Const SYMMETRICAL = 1

If my_heroic_sprite_type = NON_SYMMETRICAL Then


SetScale 1,1

If my_heroic_sprite_frame = FACING_LEFT Then
 DrawImage sprite, x, y, FACING_LEFT
Else
 DrawImage sprite, x, y, FACING_RIGHT
Endif


Else


If my_heroic_sprite_frame = FACING_LEFT Then
 SetScale -1,1
 DrawImage sprite, x, y
Else
 SetScale 1,1
 DrawImage sprite, x, y
Endif


Endif




As your function is just flipping the image with no difference in the image, there's no reason "whatsoever" why you need to save the other side.
I'm afraid to use that function of yours is just a waste of resources, processor time and is poor design.

Just use a derived version of that psuedo code I've just posted and you'll save yourself a whole ton of resources. :)