Roku Developer Program

Developers and content creators—a complete solution for growing an audience directly.
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
scorpiontahir02
Level 7

roScreen

Hi,

I am writing an application that needs to run an roVideoPlayer in the background and show a different image when the video is buffering and a different image when video is playing. But then problem is when the video is loading the screen is drawn perfectly but when the video is playing screen is not drawn right. Screen is filled with black colour (i can see a very dim video playing behind this black color). I am not sure why this is working when video is loading but not when video is playing.

Here is my function that i am using to redraw screen:


function draw_screen()
tempImg = CreateObject("roBitmap", {width:1920, height:1080, AlphaEnable: true})
tempImg.DrawObject(0, 0, m.content.frameImage)
tempImg.DrawObject(1330, 40, m.content.banner506x180)
tempImg.DrawObject(1330, 221, m.content.banner506x643)
if m.isLoadingVideo = true
tempImg.DrawObject(40, 144, m.content.nowLoadingImage)
end if
m.screen.Clear(&h00000000)
m.screen.DrawScaledObject(0, 0, m.xFactor, m.yFactor, tempImg)
m.screen.SwapBuffers()
end function
0 Kudos
11 REPLIES 11\
NewManLiving
Level 8

Re: roScreen

I have had problems with the alpha settings
On bitmaps resulting in black sections where
Transparency is desired. It does not seem to
Make a difference what the underlying bitmaps
Alphaenable is set to. To get around it
I set my roScreen's alphaenable to true
Before drawing and then set it back. That
Solved my problem
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
NewManLiving
Level 8

Re: roScreen

Also keep in mind that once swapbuffers
Is called the back buffer can have anything
Or nothing on it. So say if you initially
Drew a bitmap the size of your screen onto the screen
and called Swapbuffers the screen would display your
Bitmap correctly. However if you later create another
Bitmap smaller than the previous bitmap and drew that
Onto the screen and called swapbuffers the smaller bitmap
Would display correctly but the rest of the screen would be
Black. You would need to redraw the larger then the smaller
Bitmaps and then call swapbuffers. In fact anytime you draw
Anything new onto to the screen you have to first redraw
Everything else since after swapbuffers is called the back
Buffer has no idea what is on the front buffer because it's
state becomes dirty. It only knows what you draw after the
Last swapbuffers is called. This could become a real mess
If you have a lot of bitmaps. But the solution is to use a
Compositor/Sprites and call it's drawall interface before calling swapbuffers
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
scorpiontahir02
Level 7

Re: roScreen

Thanks for your reply!
I am using roScreen just as you suggested smaller images on top and larger images in bottom and Alpha enabled screen just not using sprites and compositor but even then i am facing this problem.
0 Kudos
RokuMarkn
Level 8

Re: roScreen

Since tempImg covers the whole screen, perhaps you need to clear tempImg to transparent before you draw the objects on it.

--Mark
0 Kudos
NewManLiving
Level 8

Re: roScreen

Some things to consider
Regardless of the size, position, or
Order in which bitmaps or objects are drawn
Once swapbuffers is called everything
Previously drawn Has to be redrawn over if you decide to
Draw something new

In order to see the rovideoplayer
You have to draw a transparent area
Over it. This would also have to be
Redrawn along with everything
Else if you add graphics later in the
Program and call swapbuffers

You are limited to 720 video res
If you use imagecanvas or rovideo
Screens

Finally you will find that using sprites
And a compositor makes it much
Easier to control as you can specify
A z order for the sprite much like you
Would layers in an imagecanvas. Plus it
Is faster because the compositor draws
Everything for you internally
Not using a compositor and sprite layers
Such as you are doing forces you to always
Be aware of what has to be drawn first to last
And you always have to redraw everything
Once you make a change . It really is quite
Easy to add these components to your existing
Single layer application
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
NewManLiving
Level 8

Re: roScreen

Sorry should be 720 for imagecanvas and
Roscreen
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
scorpiontahir02
Level 7

Re: roScreen

I have changed my code to this:


function draw_screen()
m.screen.Clear(&h00000000)
m.screen.DrawScaledObject(0 * m.xFactor, 0 * m.yFactor, m.xFactor, m.yFactor, m.content.frameImage)
m.screen.DrawScaledObject(1331 * m.xFactor, 40 * m.yFactor, m.xFactor, m.yFactor, m.content.banner506x180)
m.screen.DrawScaledObject(1331 * m.xFactor, 221 * m.yFactor, m.xFactor, m.yFactor, m.content.banner506x643)
m.screen.DrawScaledObject(100 * m.xFactor, 885 * m.yFactor, m.xFactor, m.yFactor, m.content.feedImage)
if m.isLoadingVideo = true
m.screen.DrawScaledObject(40 * m.xFactor, 144 * m.yFactor, m.xFactor, m.yFactor, m.content.nowLoadingImage)
end if
m.screen.DrawText(m.content.feed.GetEntry(m.currentFeedIndex).description, m.currentFeedPosition, 968 * m.yFactor, &h000000FF, m.font)
m.screen.SwapBuffers()
end function


and it is working fine now. Although all other objects needs to be redrawn rarely but the text, that i am drawing in 2nd last line of the function, is auto scrolling so for this purpose this function is being called after every 20 milliseconds from the event loop and the whole screen refreshes once after every 20 milliseconds. So i wanted to know about the performance issues (although it is working perfect now) that whether this approach is good or i should really use roSprite and roCompositor. Sorry i am asking about roSprite and roCompositor again after your suggestion to use them but actually i have recently shifted my code from roImageCanvas to roScreen (to get scrolling effect for text) and i have never used roSprite and roCompositor before so it will take some more time of me to use them. That is why i wanted to know whether i should really use them or this approach is sufficient too and what performance gain will i get if i use them?
0 Kudos
NewManLiving
Level 8

Re: roScreen

Did not have time to clean it up . Have to go to work but this is essentially what I am talking about. Copy and paste into a new project brs an run it
it should work . It works for me. using roku 3 hi def lastest everything if you have a problem just let me know. should work if I copy/pasted correctly
did not have time to show how only one rescreen is needed for an entire application

Function Main() As Void

ne = NewExample()
ne.Initialize()
ne.Show()

ne.Clear()
ne = Invalid

End Function

' Create an example object
Function NewExample() As Object

ne = CreateObject("roAssociativeArray")
' Takes an optional roScreen - This way you can create
' an entire application my swapping out compositors
ne.Screen = Invalid
ne.Device = Invalid
ne.VP = Invalid
ne.Timer = Invalid
ne.Port = Invalid
ne.Compositor = Invalid

' Registry and fonts declarations
ne.DefaultRegistry = Invalid
ne.FontMedium = Invalid

' Bitmaps to be used in our example
ne.VideoBitmap = Invalid

ne.BehindBitmap = Invalid
ne.BehindRegion = Invalid
ne.BehindSprite = Invalid

ne.FrontBitmap = Invalid
ne.FrontSprite = Invalid
ne.FrontRegion = Invalid

' Sprite Z order or layers
ne.LOWEST_Z = 0
ne.VIDEOPLAYER_Z = 3
ne.BEHIND_Z = 2
ne.FRONT_Z = 4

' Our colors - you may see some roInt leak messages
' upon exit in the debugger
' I believe it has to do with wrapping or boxing
' of these hex values. I was told it is not a memory leak ????

ne.Transparent = &h00000000
ne.ScrBkgClr = &hE0DFDFFF
ne.OrangeClr = &hAD4F0FFF
ne.GreenClr = &h324D1FFF
ne.TextClr = &h000000FF

ne.Initialize = example_initialize
ne.Show = example_show
ne.EventLoop = example_eventloop

ne.Draw = example_draw
ne.DrawAll = example_drawall

return ne
End Function


Function example_initialize() As Void

' Create all objects to be used
m.Device = CreateObject("roDeviceInfo")
m.VP = CreateObject("roVideoPlayer")
m.Timer = CreateObject("roTimeSpan")
m.Port = CreateObject("roMessagePort")
m.Compositor = CreateObject("roCompositor")

' Create a default registry and get our font
m.DefaultRegistry = CreateObject("roFontRegistry")
m.FontMedium = m.DefaultRegistry.GetDefaultFont(28, False, False)

' Calculate size and position of the video player
l_device_rect = m.Device.GetDisplaySize()
l_vp_width = 350
l_vp_height = 250
l_vp_x = int(l_device_rect.w / 2 - l_vp_width / 2)
l_vp_y = int(l_device_rect.h / 2 - l_vp_height / 2)
l_vp_rect = {x: l_vp_x, y: l_vp_y, w: l_vp_width, h: l_vp_height}

' set the video players destination rectangle
m.VP.SetDestinationRect(l_vp_rect)

' Create the video players transparent view.
m.VideoBitmap = CreateObject("roBitmap", {width: l_vp_width, height: l_vp_height, AlphaEnable: True})
' Clear to transparent so we can see the videoplayer
m.VideoBitmap.Clear(m.Transparent)
' Create the region into the video players bitmap that we want to see. Of course this would
' be the entire videoplayer. But you can do some intresting things with regions - slides, special effects etc
l_region = CreateObject("roRegion", m.VideoBitmap, 0, 0 , l_vp_width, l_vp_height)
' Create the videoplayer sprite at x,y coordinates. You can save the handle if you want to move it later
' Place it at the predefined z order (layer) and directly over the videoplayer itself
' this now becomes the video players layer in the sprite
m.Compositor.NewSprite(l_vp_x, l_vp_y, l_region, m.VIDEOPLAYER_Z)

' Create the behind video player text box bitmap
l_text_box_margin = 25
l_text_box_w = 500 + l_text_box_margin
l_text_box_h = 100
m.BehindBitmap = CreateObject("roBitmap", {width: l_text_box_w, height: l_text_box_h, AlphaEnable: false})

' Draw some text centered within the behind text box
l_text = "This Layer Is Behind The Video Player"
l_text_w = m.FontMedium.GetOneLineWidth(l_text, l_text_box_w)
l_text_h = m.FontMedium.GetOneLineHeight()
l_x = 0
l_y = int(l_text_box_h / 2 - l_text_h / 2 )
m.BehindBitmap.Clear(m.GreenClr)
m.BehindBitmap.DrawText(l_text, l_x, l_y, m.TextClr, m.FontMedium)

' Now put it in a layer behind the video player. Since we will be scrolling the text
' we need to save the handle to the region. We dont need the handle to the sprite
' unles we want to move the text box x, y pos. A region is a view into the bitmap
' once again we want to see the entire area of the bitmap. But we want to scroll the
' region
l_w = m.BehindBitmap.GetWidth()
l_h = m.BehindBitmap.GetHeight()
m.BehindRegion = CreateObject("roRegion", m.BehindBitmap, 0, 0 ,l_w, l_h)
m.BehindRegion.SetWrap(True) ' Wrap around scrolling
' lets put this text a little above the top left of the video player, but behind it
m.Compositor.NewSprite(l_vp_rect.x - 225, l_vp_rect.y - 25, m.BehindRegion, m.BEHIND_Z)


' Create the front video player text box bitmap
l_text_box_margin = 25
l_text_box_w = 550 + l_text_box_margin
l_text_box_h = 100
m.FrontBitmap = CreateObject("roBitmap", {width: l_text_box_w, height: l_text_box_h, AlphaEnable: false})

' Draw some text centered within the front text box
l_text = "This Layer Is In Front Of The Video Player"
l_text_w = m.FontMedium.GetOneLineWidth(l_text, l_text_box_w)
l_text_h = m.FontMedium.GetOneLineHeight()
l_x = 0
l_y = int(l_text_box_h / 2 - l_text_h / 2 )
m.FrontBitmap.Clear(m.OrangeClr)
m.FrontBitmap.DrawText(l_text, l_x, l_y, m.TextClr, m.FontMedium)

' Put this text box in front of the video player
l_w = m.FrontBitmap.GetWidth()
l_h = m.FrontBitmap.GetHeight()
m.FrontRegion = CreateObject("roRegion", m.FrontBitmap, 0, 0 ,l_w, l_h)
m.FrontRegion.SetWrap(True)
' lets put this text a little above the top left of the video player, but behind it
m.Compositor.NewSprite(l_vp_rect.x + 125, l_vp_rect.y + l_vp_rect.h - 100, m.FrontRegion, m.FRONT_Z)

return
End Function


Function example_show() As Void

' Set up video player stuff port, position notification etc

' Create the screen. You can use one roScreen . A composite is
' similar to a window once setdrawto is called. Just create
' compositors and swap them in/out of one instance of roScreen
' THis example does not do this
m.Screen = CreateObject("roScreen", True)
m.Screen.SetMessagePort(m.Port)
'm.Screen.SetAlphaEnable(True)
m.Compositor.SetDrawTo(m.Screen, m.ScrBkgClr)

m.DrawAll()
m.EventLoop()

End Function

Function example_drawall() As Void
m.Compositor.DrawAll()
m.Screen.SwapBuffers()
End Function

Function example_draw() As Void
m.Compositor.Draw()
m.Screen.SwapBuffers()
End Function

Function example_eventloop() As Void

l_msg = ""
l_running = true
l_index = 0
l_kp_BK = 0

while(l_running)

l_msg = wait(100, m.port)

if m.Timer.TotalMilliseconds() >= 100
m.FrontRegion.Offset(20, 0, 0, 0)
m.BehindRegion.Offset(20, 0, 0, 0)
m.DrawAll()
m.Timer.Mark()

end if

if type(l_msg) = "roUniversalControlEvent"

l_index = l_msg.GetInt()

if l_index = l_kp_BK then l_running = False

else if type(l_msg) = "roVideoPlayerEvent"

' To DO

end if

end while


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
RokuMarkn
Level 8

Re: roScreen

Drawing to roScreen is fine. There shouldn't be any major difference in performance. The Compositor/Sprite method can be easier to code in some cases, especially if you are animating objects or drawing them in different places at different times, but it's mainly a matter of personal preference. Usually I prefer to draw directly to my screens and bitmaps rather than using sprites.

--Mark
0 Kudos