Forum Discussion

prajwalshetty's avatar
11 years ago

RoCompositor

Hi,

Is there any example or sample code i can get where we used two seperate images combined into sprite using RoCompositor dynamically. I saw a sample with one big sprite image.

Or is it not possible two dynamically combine two images?

Is need to take a decision on what route to take based on the above example. Any help on this would be highly appreciated.

Thanks in advance.

Regards,
Prajwal

7 Replies

  • Not sure exactly what you mean by "combined" - do you mean right on top of one another? You can just draw them on top of each other, with alpha blending and have a "clear" color at least in the top picture so parts will be see-through as you wish. You can do it with or without the compositor.
  • Not sure what you are trying to do but combining images is usually done by creating a host or parent bitmap big enough to contain both of them, drawing each of them into host the bitmap and then creating a sprite out of the host bitmap. You can also investigate changing the sprites region roSprite.SetRegion. Rule of thumb: Don't go sprite crazy - many little sprites are for game developers who need what they offer in the way of collision etc...Learn to use the method above where you combine images into a parent bitmap for grids, slideshows, and other interface. Then create a sprite from the larger bitmap and use region offsetting to move things around instead of doing a bunch a DrawObjects to reposition everything when needed. This is a great performance boost for the low-end boxes. As a side note you do not need a sprite to use a region. Sprites are a good way to perform complex, layered drawings that are more or less dynamic ( in asynchronous environments ) much the same as a game.
  • Hi,

    I tried using the parent bitmap concept but the problem i am having is i have to create a layout similar to grid layout with scrolling but each image is of size around 600px and i have around 20 images to display. The issue i am facing the bitmap has a size restriction of 2048px. And also the other issue is even if i set setSwrap true it doesnot wrap but instead gets cut off.

    Any help on this would be appreciated, thanks in advance.
    screen=CreateObject("roScreen")
    compositor=CreateObject("roCompositor")
    compositor.SetDrawTo(screen, black)
    parentCanvas = createobject("roBitmap", {width:2000, height:720, AlphaEnable: false})
    dfDrawImage(parentCanvas, "image1.jpg",0,200)
    dfDrawImage(parentCanvas, "image2.jpg",600,200)
    dfDrawImage(parentCanvas, "image3.jpg",1200, 200)
    dfDrawImage(parentCanvas, "image4.jpg",1800, 200)
    region=CreateObject("roRegion", parentCanvas, 0, 0, screen.getwidth(), 325)
    region.SetWrap(true)

    view_sprite=compositor.NewSprite(0, 0, region)
    compositor.draw()
    screen.SwapBuffers()

    Thanks in advance.

    Prajwal
  • Hi,

    Thanks that was really helpful. Is there any documentation i can refer to understand the bitmap cache more throwly. Like when does roku device clears the bitmap cache and what is the cache limit.

    Sorry for troubling you, since i just started working on device trying to understand the capability.

    Regards,
    Prajwal
  • There are two ways to control larger amounts of bitmaps that may exceed available memory. roUrlTransfer and roTextureManager. I prefer to use roTextureManager for grids, although a channel I'm working on now uses roUrlTransfer for the grid since there is no need for asynchronous retrieval. The great thing about the TextureManager is its LRU cache which is undocumented, debated as to its actual existence, but can be readily observed by those that use it. It provides a great speed advantage over roURLTransfer for fast scrolling grids. To use it well you need to be able to build your application to handle asynchronous communication in a single-threaded environment. You generally request a number of textures (fetch ahead so to speak ) while the user is scrolling in, what the user is scrolling out is unloaded from the manager so that memory stays at a constant. Since you do not wait on asynchronous calls you have to be always listening on a dedicated port, especially in loops that may block for some time. With asynchronous calls the function does not wait but returns immediately and you are notified via it's event that a texture has arrived. One pitfall that many developers encounter when beginning to use asynchronous calls is not persisting their request object. The roTextureRequest for example cannot go out of scope until the texture is received. So you need to build a structure which contains information about what to do with the bitmap, a handle to the roTextureRequest. You keep a dictionary of these objects in an associative array. You can use the ID that is returned to you as a key. Keep this list at a global level. When you receive your texture event get, the ID and retrieve your structure from your dictionary. You then have all the information you need (if you designed it that way) to use draw it where you like. You can put parent bitmap in there, the x, y coordinates etc. Just be sure to invalidate all references when done with it.

    To get around things that insuring sprites are removed and bitmaps are invalidated I designed a simple framework that uses the roAssociativeArray as an object. With this you can assign function pointers to operate on any member of the associative array using the m pointer. Works good for me
  • Hi,

    Thanks for the reply that was really helpful. Had a small doubt i might be misunderstanding the concept but when if i unload a scrolled out images when the user comes back again to scrolled out image it will ended up downloading that remote image again right sir.

    But i see lot of advantage of using TextureManager so that we can be sure to clear the cache when the user goes out to a new page.

    Thanks again for the help.

    Regards,
    Prajwal
  • Yes, the texturemanager is a great tool when you need an undefined number of textures. Its pretty quick, well almost, the videoplayer trashes the lru but you can jump start it back by a few retrieves and a pause, only need about 200-300 ms pauses, in your pause loop (create with a timer) just poll the texture manager's queue as textures arrive, pull them out of your list with the id. Have everything in that structure in the list. The parent bitmap, the coordinates of the bitmap. When you do this your event handler can just write the bitmap to the x,y coordinates of the bitmap in the structure. Call Compositor.DrawAll, swapbuffers and you see it pop right into the parent bitmap. It is important again that you use a parent bitmap and region offsetting. Not only does this guarantee better scrolling performance but since you are offsetting the region and not the bitmaps when the user scrolls, your bitmap's x,y coordinates are fixed. The only one that changes is the one that is written into the virtual portion of the buffer. Otherwise if you use coordinate offsetting, you would have to go through all your structures and change the x,y positions before the texture was received by your texturemanager event handler. If you did not, obviously they would be popping all over the place. The best way to to this that I have found, which insures an even performance across the scope of supported models is to just display your place holder as the user is scrolling. On the button up event unload the bitmaps that are no longer in the display area ( I use an internal buffer lru that has x number on either side of the display, so im always throwing out and requesting a margin of bitmaps on each side of the display area ) So say I have a buffer of 10 bitmaps, then there will always be 10, no matter when the user stops. The 10 that are existing will fast-scroll by and the rest will be placeholders. When the button is up I compare and retrieve at the index the user has stopped at. On the faster boxes you can just unload and request each texture as the user scrolls and its performance is excellent, most arrive before the virtual area of the buffer is scrolled into view, their is a straggler every now and then but its nice to know that your system is working as it pops into the correct position even as the user is in a fast scroll. On the slower boxes unfortunately its too much for the processor and you notice a studdering. But like I said not so on the 3 the new 2 and possibly the tv. WIth those devices you don't need anything but to unload and request your single bitmap or if you use a fetch ahead cache as I do. Works out the same just a couple of textures ahead of the display on either side. But frankly, if the user is scrolling they are not interested and want to get somewhere else, a grid counter indicates the position and a button up brings in almost immediately the page scrolled to so you can leave this for all devices and get excellent scrolling performance

    Quite frankly it is probably the most difficult thing I have done so far so their is quite a learning curve. I spent some considerable time totally on the 2D, I could not even tell you what to do with a roPosterScreen, but I can tell something about the 2D API.