Best way to DrawRotatedObject and DrawScaledObject together?

Is it possible to both DrawRotatedObject and DrawScaledObject?

Since the source can be a region, would it be best to first DrawRotatedObject a bitmap onto a region, then DrawScaledObject the region onto the screen?

Is some other way easier or better for performance?

Are you scaling it to different sizes and rotating it differently on each pass? If you’re only scaling it once, then your best bet is to cache it to a new bitmap already scaled, then use that bitmap from that point on. I don’t think using regions will make a difference in this scenario.

Sorry, yeah, scaling new size every pass, a slowly shrinking spinning object

“Komag” wrote:
Sorry, yeah, scaling new size every pass, a slowly shrinking spinning object
Admittedly, I’ve never actually used an animated sprite , but I know you can create a bunch of frames and play them back. If you’re using the compositor and performance is a concern maybe that’s an option. You could use it just for the animation part and use a more hi-Rez version when the object is static.

I’ve actually already implemented this with sprites, and it works fine, but I have to draw my own scaled sprites for each stage of shrinking, so I thought I might try the built-in scaling instead where I could do many more steps without making a zillion images.

Yea I’d rather do it without sprites too. If you can absorb the performance hit why not? As to your original question, since you are doing both things each pass, I can’t see a reason why doing one before the other matters but there might be a small difference. Maybe make a little test and do each way 10000 times and see if there is a difference.

Ok my informal tests are in (clearly avoiding actual work) and the results are clear:
You can’t tell its not butter! No dif-france!
I got zero difference by scaling first and then using drawRotatedobject or rotating first and using drawscaledobject.
On the test below ( scale first) i get 3333 or 3334 milliseconds every time on a roku3, same results with rotate first.
I will say rotating first is more complicated and needs an extra region and more complex math, at least how i did it.
All in all I’d definitely say scale first and draw rotated.

Sub Main()
			screen=CreateObject("roScreen", true, 1280, 720)
			msgport=CreateObject("roMessagePort")
			screen.SetPort(msgport)
			fontreg = createobject("rofontregistry")
			font = fontreg.GetDefaultFont(50, false, false)
			elapsedtime = CreateObject("roTimespan")
			scale = 400
			scaledirection=true
			theta = 0
			testresult = "0"
			regLoc = 0
			bitscale = 1.0
			bitloc = 0
			bitty = CreateObject("roBitmap", {width:scale, height:scale, AlphaEnable:True})
			bitty2 = CreateObject("roBitmap", {width:scale, height:scale, AlphaEnable:True})
			bitty3 = CreateObject("roBitmap", {width:scale, height:scale, AlphaEnable:True})
			bitty2.Clear(&hFF0000FF)
			bitty3.Clear(&h0000FFFF)
			bitty2.drawScaledobject( 100, 100, .5, .5,  bitty3, &h0000FFFF)
			bitty.drawobject(  0,0, bitty2)
			reggie = CreateObject( "roRegion",bitty, regLoc, regLoc, scale, scale )
			reggie.SetPretranslation( -scale/2, -scale/2)
			
			while true
			
			screen.Clear(&hebebebFF)
			screen.SetAlphaEnable(true)
			screen.drawtext( testresult, 50 , 50 , &h0000FFFF, font)
			screen.drawRotatedobject( 640, 360, theta, reggie)
			screen.swapbuffers()
			
			theta = theta + 3.6
			if theta > 360
				theta= 0
			end if
			if scaledirection 
				scale = scale -4 : regLoc = regLoc+1: bitscale = bitscale -.01: bitloc = bitloc +1
			else
				scale = scale +4 : regLoc = regLoc-1 : bitscale = bitscale +.01 :  bitloc = bitloc -1
			end if
			if scale = 0 
				 scaledirection = false
			else if scale >= 400
				scaledirection = true
				testresult = elapsedtime.Totalmilliseconds().toStr()
				elapsedtime.Mark()
			end if
		
			bitty.Clear(&hFFFFFF00)
			bitty.drawScaledobject( bitloc, bitloc, bitscale, bitscale,  bitty2)
			reggie = CreateObject( "roRegion",bitty, regLoc, regLoc, scale, scale )
			reggie.SetPretranslation( -scale/2, -scale/2)
			
			end while
			
			
End Sub

Wow, thanks NewManLiving, that’s impressive! It works great on my 2XS, but doesn’t load (just black screen) on my N1100. Is that because only a few Roku models have the OpenGL?

SquirrelTown, I may just stick with the sprites, but if I do it this way I’ll keep in mind to scale first, rotate second, to keep it more manageable, thanks for the test.

I don’t know the reason for the 1100. Don’t have anything in that series

On legacy devices like the 1100, you can only use drawscaledobject in high quality mode if you are drawing from a region to a region, perhaps that is what is causing the black screen?

  • Joel

After 4 years I have revisited this for a different section of my game! I also reviewed Romans Romans-I-XVI game engine code for this idea.

In the end it worked best for me to rotate first, scale second, with maybe a bit more complexity (although I didn’t need a second region, just the second bitmap), mainly due to the fact that it eats up less texture memory. When scaling first, I had to make the second bitmap (for rotation) the full dimensions needed (in my case up to 2x). But when rotating first, you only have to make the second bitmap (for scaling) slightly bigger to accommodate the rotated image’s corners, but then it can be scaled up a lot without using up extra texture memory. Whether this is the best approach for anyone in general depends on whether they’re already using a lot of texture memory, whether they’ll be enlarging the image significantly, and maybe some other factors.

And again, I greatly appreciate the code examples from NewManLiving, squirreltown, and Romans-I-XVI :slightly_smiling_face: Grasping how bitmaps and regions really work is STILL difficult for me.