Hello, everyone!
So here is a new feature. Give it a spin, we would like to get your feedback on it.
Half a year ago we introduced texture apis. Building on that API here is modifiable texture. It resembles Snapshot object, but it is quite different, even if APIs may seem similar.
New feature is TextureResourceCanvas type. It is in-memory texture, you can render stuff into it, and than assign it to other objects. Note that you can assign it to several different objects.
It is a subject to manual texture management, so beware of memory leaks. If you don’t use it anymore, you have to release it. After you release it, you’re loosing pointer Lua handle to it, but Display Objects using it would not become invalid.
I will put some code here to explain how it works.
Creating with newTexture:
[lua]
local canvasTexture = graphics.newTexture( {
type = “canvas”
, width = 128
, height = 128
, pixelWidth = 256
, pixelHeight = 256
} )
[/lua]
Here width and height here is dimensions of canvas where you would draw your objects, basically dimensions of visible world in canvas.
Pixel width/height - size of underlying texture. If omitted, this values would be selected to correspond to pixel dimensions of display object with width/height. You can set it to like 32 for cool pixely effects (with proper scaling modes), or just some other number, for example to save memory etc.
After it is created you can assign it to the fill to other objects. Use “canvasTexture.filename” and “canvasTexture.baseDir” pretty much anywhere where those parameters are expected. For example, in composite paint or creating image rect:
[lua]
local circle = display.newCircle( display.contentCenterX, display.contentHeight*3/4, w/2 )
circle.fill = {
type=“composite”,
paint1={ type=“image”, filename=“corona.png” },
paint2={ type=“image”, filename=canvasTexture.filename, baseDir=canvasTexture.baseDir } – magic here!
}
circle.fill.effect = “composite.phoenix”
local rect = display.newImageRect(
canvasTexture.filename, – “filename” property required
canvasTexture.baseDir, – “baseDir” property required
display.contentWidth,
display.contentHeight
)
[/lua]
To draw to canvas, you would use method canvasTexture:draw(). This would put your display objects off the screen and into internal queue. You have to manually update the texture with canvasTexture:invalidate().
This call would schedule to render objects in internal queue before next frame, and after rendering them it would move them to cache.
You can also set custom background colour. This colour would fill the texture when it is cleared.
[lua]
canvasTexture:draw( someCircle )
canvasTexture:draw( someRect )
canvasTexture:setBackground( 0,0,0,1 )
canvasTexture:invalidate()
[/lua]
Note that (0; 0) point is in the centre of the canvas.
Thing to keep in mind is that when app is put in background, Android will make all GPU textures invalid, so you would have to redraw your canvas resource. Read documentation on how to do it.
Reading documentation is good in any way. It describes more edge cases and methods:
newTexture documentation <-- read me before using
TextureResourceCanvas documentation <-- me too
Canvas texture resources has a lot of fun applications, but also some limitations. Like nested textures can work weirdly, or native objects would not work at all.
Also, there is no possibility to add setPixel/getPixel. Textures are stored on GPUs and do not provide direct buffer access.
Also, I rewrote snapshot paint example, to use canvas. It has fire in the middle to demonstrate manual updates. It is attached to this post. Also, some other random example with star in it and composite paint.