So I tried to throw together a little app to plot points on the screen, using 1 pixel .png images, of red green and blue. Not working. Background display is working. Any suggestions as to why nothing is showing up? The idea was to plot a point and leave it up, plot another in 3 colors, just an experiment. Nothing is happening except if I set the background, which I have commented out in case it was overlaying the points. Heres the code, based off a screensaver test TheEndless posted a while back.
sub main()
backgroundHD = {
Color: "#000000",
TargetRect: { x: 0, y: 0, w: 1280, h: 720 }
}
rx=640
ry=360
gx=640
gy=360
bx=640
by=360
gpix={url:"pkg:/green.png"
TargetRect:{x:gx,y:gy,w:10,h:10}}
bpix={url:"pkg:/blue.png"
TargetRect:{x:bx,y:by,w:10,h:10}}
rpix={url:"pkg:/red.png"
TargetRect:{x:rx,y:ry,w:10,h:10}}
port = CreateObject( "roMessagePort" )
canvas = CreateObject( "roImageCanvas" )
canvas.SetMessagePort(port)
canvas.SetRequireAllImagesToDraw( false )
'canvas.SetLayer( 1, backgroundHD)
canvas.Show()
canvas.SetRequireAllImagesToDraw(false)
While true
msg = Wait(10, port )
if Type(msg)="roImageCanvasEvent" then
?msg.GetMessage()
If msg.isRemoteKeyPressed() Then
canvas.Close()
Return
End If
end if
rx=rx+rnd(3)-2
ry=ry+rnd(3)-2
gx=gx+rnd(3)-2
gy=gy+rnd(3)-2
bx=bx+rnd(3)-2
by=by+rnd(3)-2
canvas.SetLayer( 2, gpix)
canvas.SetLayer( 3, bpix)
canvas.SetLayer( 4, rpix)
canvas.show()
?rx,ry,gx,gy,bx,by
End While
End Sub
First problem I see is that you’re never updating the TargetRects for your pixel PNGs. rx, ry, gx, gy, bx, and by are all integers, so changing them won’t automatically update the TargetRects. You’ll need to explicitly update those.
Second, 10 milliseconds is probably too fast for the screen to refresh. I’d try bumping that up to 100 or so until you get the screen drawing correctly.
Otherwise, it looks ok. Are your images actually in the root of your package, or are they in an images subfolder? If in an images subfolder, then your URLs are wrong, which could be your problem.
“TheEndless” wrote:
First problem I see is that you’re never updating the TargetRects for your pixel PNGs. rx, ry, gx, gy, bx, and by are all integers, so changing them won’t automatically update the TargetRects. You’ll need to explicitly update those.
Second, 10 milliseconds is probably too fast for the screen to refresh. I’d try bumping that up to 100 or so until you get the screen drawing correctly.
Otherwise, it looks ok. Are your images actually in the root of your package, or are they in an images subfolder? If in an images subfolder, then your URLs are wrong, which could be your problem.
I’d like to mirror what TheEndless says about the update frequency. In my testing you can TRY to update at a really high frequency like that – but nine times out of ten my roku would crash with anything “sizable” being rendered in under 100ms.
I figured out I don’t need my 1pix png, I can just set a color for the targetRect and draw a dot or a square with no .png.
Other weird things: drawing to layer 1 2 or 3 results in a moving image. Drawing to layer 0 results in a line that follows the draw position.
Drawing three colors to layer 0 results in only the last draw appearing - unless a delay is put in after each draw. So as both of you mentioned, there is definitely some timing related weirdness. a 15ms wait between each color draw seems to work, don’t know what the minimum is yet.
Here’s some general tips from other threads about using roImageCanvas, and our own experience:
Whenever changing a canvas in any way, the call to .show() will take a while. Anywhere from a little less than 100ms to well over 10 seconds, depending on complexity.
After you’ve called .show() on a canvas (and it was given enough time to display), subsequent calls to .show() are very fast, generally displaying in less than 20ms until the next change.
Creating a new roImageCanvas object anywhere causes all current canvas objects to recomposite (take a long time) on the next call to .show().
Using TargetRect for simple squares is fine, just don’t try to rotate them (unless that’s fixed now?)
Scaling an image causes automatic gradients. A two pixel image with one pixel red and the other green, when scaled will automatically fill in the pixels between the colors with a gradient.
Also, be careful with floats and integers. In many places using a float instead of an integer in components yields silent but wrong behavior (such as automatically being evaluated as zero). Most places it just blows up though.
Thanks. I’m still pretty confused about how all this works. For instance:
If I plot a bunch of squares on layer 0 they all stay on the screen.
If I plot on layer 1, 2 ,3 then each new call erases the previous and draws a new square.
Also, discovered that the transparancy byte documented for text also works for graphics even though it is not documented:
#ff00F00C0 (where C0 is the transparancy)
Rotation is completely inaccurate, but could be used creatively.
Calling SetLayer on any layer should replace all of the content on that layer, even 0. What you may be seeing is left over from the screen behind your ImageCanvas not redrawing.
#ff00F00C0 (where C0 is the transparancy)
Actually ff is the transparency in that string (though technically not transparent at FF). Either the trailing 0 or the leading f is likely being ignored, since there are only 4 bytes to a color string, and yours seems to have 4 and a half..
“jbrave” wrote:
Rotation is completely inaccurate, but could be used creatively.
I don’t know what you mean by this. Look at the screensaver in Video Poker. It uses TargetTranslation and TargetRotate for the effect you see.
“TheEndless” wrote:
Calling SetLayer on any layer should replace all of the content on that layer, even 0. What you may be seeing is left over from the screen behind your ImageCanvas not redrawing.
#ff00F00C0 (where C0 is the transparancy)
Actually ff is the transparency in that string (though technically not transparent at FF). Either the trailing 0 or the leading f is likely being ignored, since there are only 4 bytes to a color string, and yours seems to have 4 and a half..
typo, but isn’t the last byte reading left to right on the end in the 4 bytes the transparancy? If it is the first byte, that might explain some of the mixed results…
“renojim” wrote:
jbrave wrote:Rotation is completely inaccurate, but could be used creatively.
I don’t know what you mean by this. It uses TargetTranslation and TargetRotate for the effect you see.
-JT
When rotating a 10x10 square it becomes distorted in an asymmetrical way instead of a symmetrical distortion as one would expect from rotating a low resolution object…
Anyone have any comments on my other questions about why writing to layer 0 results in a trail of dots that stay on the screen and writing to other layers seems to replace the last write? Is that also a timing related effect?
“jbrave” wrote:
typo, but isn’t the last byte reading left to right on the end in the 4 bytes the transparancy? If it is the first byte, that might explain some of the mixed results…
First byte on the Roku.
“jbrave” wrote:
Anyone have any comments on my other questions about why writing to layer 0 results in a trail of dots that stay on the screen and writing to other layers seems to replace the last write? Is that also a timing related effect?
I commented on that above. It’s most likely a result of you not redrawing the screen behind your image canvas.
If you want a layer to be persistent, why not just draw on a new layer? If you don’t do that, then you’ll need to keep track of everything you’ve drawn on a layer and be sure to add it back when you draw the new stuff on that layer. You can do that by passing an array of objects to the SetLayer(), instead of just a single object.
So, I guess my question is, how do I keep persistant drawing on multiple layers, or does it only work on layer 0? Sticking a background on a layer other than 0 first doesn’t seem to have an effect.
It’s not really persistent on layer 0. It appears persistent, because there’s no data to replace it with, unless you redraw the screen underneath. As a test, let the screensaver kick in between one of your draws to layer 0, and you’ll see what I mean.
If you want consistent,reliable persistence on any layer, you’ll need to redraw everything on that layer that needs to be persisted. Unless you want to keep track of that, it will be easier to just draw a new layer, and not replace the existing layer.
“jbrave” wrote:
Rotation is completely inaccurate, but could be used creatively.
I don’t know what you mean by this. Look at the screensaver in Video Poker. It uses TargetTranslation and TargetRotate for the effect you see.
I’m fairly certain he’s referring to using background colors and TargetRect to draw “quads” onthe image canvas. it works well and is fast, as long as you don’t rotate. You get some interesting effects.
jbrave, you could always use the rdPNG function from librokudev to arbitrarily color a single pixel PNG and then scale it to the dimensions you want. Rotation works perfectly then. That’s the method we used in KidPaint after examining all the other options. The correctly color indexed PNG pixel image is included in the library.