Roku Developer Program

Developers and content creators—a complete solution for growing an audience directly.
cancel
Showing results for 
Search instead for 
Did you mean: 
Komag
Level 9

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?
0 Kudos
11 Replies
TheEndless
Level 7

Re: Best way to DrawRotatedObject and DrawScaledObject toget

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.
My Channels: http://roku.permanence.com - Twitter: @TheEndlessDev
Instant Watch Browser (NetflixIWB), Aquarium Screensaver (AQUARIUM), Clever Clocks Screensaver (CLEVERCLOCKS), iTunes Podcasts (ITPC), My Channels (MYCHANNELS)
0 Kudos
Komag
Level 9

Re: Best way to DrawRotatedObject and DrawScaledObject toget

Sorry, yeah, scaling new size every pass, a slowly shrinking spinning object
0 Kudos
squirreltown
Level 9

Re: Best way to DrawRotatedObject and DrawScaledObject toget

"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.
Kinetics Screensavers
0 Kudos
Komag
Level 9

Re: Best way to DrawRotatedObject and DrawScaledObject toget

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.
0 Kudos
squirreltown
Level 9

Re: Best way to DrawRotatedObject and DrawScaledObject toget

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.
Kinetics Screensavers
0 Kudos
NewManLiving
Level 7

Re: Best way to DrawRotatedObject and DrawScaledObject toget

Hi Komag
Started a TextFX object a few months back but did not do much with it ( just had to get that grid done) . Your post reminded me of it. So here is what I have put together. Never really optimized it or looked at it much, but plan on addressing it sometime in the future so I probably will make changes. Anyway you can look at this and get some ideas. I believe this is something like you have in mind

I just hacked quickly at a demo so it is not my style or level of scrutiny but here it is. The left,right remote keys operate. Since it is fullsize from the start you need to start with the left key. I'm sure others can improve on it, but it's a start. ( Keep in mind 360 rotation may not be supported ). Also scale modes are set to 1.

Sub Main() 

l_ds = CreateObject( "roDeviceInfo" ).GetDisplaySize()
l_dw = l_ds.w
l_dh = l_ds.h

l_bitmap = CreateBitmap()

l_screen = CreateObject( "roScreen", True, l_dw, l_dh )
l_port = CreateObject( "roMessagePort" )
l_screen.SetMessagePort( l_port )
l_screen.SetAlphaEnable( True )
l_screen.Clear( &hFFFFFFFF )
l_x = l_dw / 2 - l_bitmap.GetWidth() / 2
l_Y = l_dh / 2 - l_bitmap.GetHeight() / 2
l_screen.DrawObject( l_x, l_y, l_bitmap)
l_screen.SwapBuffers()

l_kp_BK = 0
l_kp_LT = 4
l_kp_RT = 5
l_isFullSize = True

while( True )
l_msg = l_port.GetMessage()
if type( l_msg ) = "roUniversalControlEvent"

l_index = l_msg.GetInt()

if l_index = l_kp_LT and l_isFullSize

ScaleRotate( l_screen, l_bitmap, l_x, l_y, False )
l_isFullSize = False

else if l_index = l_kp_RT and ( not l_isFullSize )

ScaleRotate( l_screen, l_bitmap, l_x, l_y )
l_isFullSize = True

else if l_index = l_kp_BK
exit while
end if

end if
end while
End Sub

Function ScaleRotate( a_screen As Object, a_bitmap As Object, a_x As Integer, a_y As Integer, a_isUp = True )

l_w = a_bitmap.GetWidth()
l_h = a_bitmap.GetHeight()
l_x = int( l_w / 2 )
l_y = int( l_h / 2 )

l_region1 = CreateObject( "roRegion", a_bitmap, 0, 0, l_w, l_h )
l_region1.SetScaleMode( 1 )
l_region1.SetPretranslation( -l_x, -l_y )

l_bitmap2 = CreateObject( "roBitmap", { width: l_w, height: l_h, AlphaEnable: True } )
l_region2 = CreateObject( "roRegion", l_bitmap2, 0, 0, l_w, l_h )
l_region2.SetScaleMode( 1 )

l_rgb = &hFFFFFF00
l_frames = 24

for l_i = 1 to l_frames

if a_isUP
l_scale = l_i / l_frames
else
l_scale = ( l_frames - l_i ) / l_frames
end if

l_j = 360 * l_scale
l_bitmap2.Clear( &h00000000 )
l_bitmap2.DrawRotatedObject( l_x, l_y, -l_j, l_region1 )
l_bitmap2.Finish()

l_rgba = int( 255 * l_scale ) + l_rgb

l_x1 = ( l_w - int( l_w * l_scale ) ) / 2
l_y1 = ( l_h - int( l_h * l_scale ) ) / 2

a_screen.Clear( &hFFFFFFFF )
a_screen.DrawScaledObject( a_x + l_x1, a_y + l_y1, l_scale, l_scale, l_region2, l_rgba )
a_screen.SwapBuffers()

end for

End Function


Function CreateBitmap() As Object
l_bitmap = CreateObject( "roBitmap", { width: 300, height: 300, AlphaEnable: True } )
l_bitmap.Clear( &hFFFFFF00 )
l_font = CreateObject( "roFontRegistry" ).GetDefaultFont( 300, True, False )
l_w = l_font.GetOneLineWidth( "X", 300 )
l_h = l_font.GetOneLineHeight()
l_bitmap.DrawText( "X" , 150 - l_w / 2, 150 - l_h / 2, &h000000FF, l_font )
l_bitmap.Finish()
return l_bitmap
End Function
My Channels: 2D API Framework Presentation: https://owner.roku.com/add/2M9LCVC
Updated: 11-11-2015 - Completed Keyboard interface
The Joel Channel ( Final Beta )
0 Kudos
squirreltown
Level 9

Re: Best way to DrawRotatedObject and DrawScaledObject toget

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
Kinetics Screensavers
0 Kudos
Komag
Level 9

Re: Best way to DrawRotatedObject and DrawScaledObject toget

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.
0 Kudos
NewManLiving
Level 7

Re: Best way to DrawRotatedObject and DrawScaledObject toget

I don't know the reason for the 1100. Don't have anything in that series
My Channels: 2D API Framework Presentation: https://owner.roku.com/add/2M9LCVC
Updated: 11-11-2015 - Completed Keyboard interface
The Joel Channel ( Final Beta )
0 Kudos