Your Digital Media Has Never Looked So Good

 
User avatar
Komag
Topic Author
Posts: 808
Joined: Fri Aug 22, 2014 3:42 am

Best way to DrawRotatedObject and DrawScaledObject together?

Thu Feb 05, 2015 2:59 pm

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?
 
User avatar
TheEndless
** Valued Community Member **
Posts: 9231
Joined: Mon Oct 04, 2004 10:15 am
Location: US
Contact:

Re: Best way to DrawRotatedObject and DrawScaledObject toget

Thu Feb 05, 2015 4:41 pm

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)
 
User avatar
Komag
Topic Author
Posts: 808
Joined: Fri Aug 22, 2014 3:42 am

Re: Best way to DrawRotatedObject and DrawScaledObject toget

Thu Feb 05, 2015 6:32 pm

Sorry, yeah, scaling new size every pass, a slowly shrinking spinning object
 
User avatar
squirreltown
Posts: 870
Joined: Sun Apr 21, 2013 2:20 pm

Re: Best way to DrawRotatedObject and DrawScaledObject toget

Thu Feb 05, 2015 8:23 pm

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
 
User avatar
Komag
Topic Author
Posts: 808
Joined: Fri Aug 22, 2014 3:42 am

Re: Best way to DrawRotatedObject and DrawScaledObject toget

Fri Feb 06, 2015 7:37 am

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.
 
User avatar
squirreltown
Posts: 870
Joined: Sun Apr 21, 2013 2:20 pm

Re: Best way to DrawRotatedObject and DrawScaledObject toget

Fri Feb 06, 2015 7:49 am

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
 
User avatar
NewManLiving
Posts: 452
Joined: Fri Aug 02, 2013 6:14 pm

Re: Best way to DrawRotatedObject and DrawScaledObject toget

Fri Feb 06, 2015 7:52 am

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 )
 
User avatar
squirreltown
Posts: 870
Joined: Sun Apr 21, 2013 2:20 pm

Re: Best way to DrawRotatedObject and DrawScaledObject toget

Fri Feb 06, 2015 12:04 pm

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
 
User avatar
Komag
Topic Author
Posts: 808
Joined: Fri Aug 22, 2014 3:42 am

Re: Best way to DrawRotatedObject and DrawScaledObject toget

Sat Feb 07, 2015 3:32 am

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.
 
User avatar
NewManLiving
Posts: 452
Joined: Fri Aug 02, 2013 6:14 pm

Re: Best way to DrawRotatedObject and DrawScaledObject toget

Sat Feb 07, 2015 4:06 am

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 )
 
User avatar
RokuJoel
Posts: 1758
Joined: Mon Nov 14, 2011 5:22 pm

Re: Best way to DrawRotatedObject and DrawScaledObject toget

Thu Feb 12, 2015 3:55 pm

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
 
User avatar
Komag
Topic Author
Posts: 808
Joined: Fri Aug 22, 2014 3:42 am

Re: Best way to DrawRotatedObject and DrawScaledObject together?

Sun Sep 01, 2019 12:09 am

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 :-) Grasping how bitmaps and regions really work is STILL difficult for me.

Who is online

Users browsing this forum: No registered users and 2 guests