Quick Links: Download Gideros Studio | Gideros Documentation | Gideros Development Center | Gideros community chat
draw off-screen and bake - Gideros Forum

draw off-screen and bake

gemboy100gemboy100 Member
edited February 15 in General questions
Hi guys,
I have a situation that bothers me lately. Im trying to achieve rescalable rounded box (lots of them) by replicating 4 corners from texture
So far by looking at the manuals the only way is to use TextureRegion, but this gives me 8 bitmaps to parent on another sprite. All of them still lives in memory as a separated class objects which, I assume, is memory and cpu consuming. In love2d you can create a new canvas, draw multiple textures and save it in memory so it counts as a single new texture.



2019-02-15_015757.jpg
272 x 260 - 8K

Comments

  • Somewhere on the forum I showed a nine image function for this, also @Oleg I think made a class for his version.

    Likes: oleg

    +1 -1 (+1 / -0 ) Share on Facebook
  • hgy29hgy29 Maintainer
    In addition to the nine image stuff (which is probably what you are after), the gideros equivalent to offscreen canvas is a RenderTarget.

    Likes: SinisterSoft, oleg

    +1 -1 (+2 / -0 ) Share on Facebook
  • I'm not sure if @Oleg 's version used multiple sprites or not, my version used a single mesh - but wasn't as nice to use as his.

    @gemboy100 : If you can't find it let me know and I'll dig it up and repost here.
  • I think I found it. Its called slice9 class:
    http://forum.giderosmobile.com/discussion/7380/slice9-class#latest
    You also posted there, a method using setTextureCoordinateArray
    Im looking at it right now, trying to understand it

    Likes: oleg

    +1 -1 (+1 / -0 ) Share on Facebook
  • Just a note: if you use bitmaps you might get hairlines between the images. I used a TileMap to avoid this.

    Likes: antix, oleg

    My Gideros games: www.totebo.com
    +1 -1 (+2 / -0 ) Share on Facebook
  • gemboy100gemboy100 Member
    edited February 15
    Not really what i needed but I came up with my patch9 function
    function patch9(img,cut,wR,hR)
    	local tx = Texture.new(img, true)
    	local w,h = tx:getWidth(), tx:getHeight()
    	local rt = RenderTarget.new(wR, hR)
     
    	--top part
    	local r1 = TextureRegion.new(tx, 0,   0,   cut, cut)
    	local r2 = TextureRegion.new(tx, cut,   0,   w-cut*2, cut)
    	local r3 = TextureRegion.new(tx, w-cut, 0,   cut, cut)
     
    	--left
    	local r4 = TextureRegion.new(tx, 0,   cut,   cut, h-cut*2)
    	local r5 = TextureRegion.new(tx, 0,   h-cut,   cut, cut)
     
    	--mid
    	local r6 = TextureRegion.new(tx, cut,   cut,   w-cut*2, h-cut*2)
     
    	--right
    	local r7 = TextureRegion.new(tx, w-cut, cut, cut, h-cut*2)
     
    	--bot
    	local r8 = TextureRegion.new(tx, cut, h-cut, w-cut*2, cut)
    	local r9 = TextureRegion.new(tx, w-cut, h-cut, cut, cut)
     
    	--
    	--draw to render target
    	--
    	--top
    	local bm1 = Bitmap.new(r1)
    	local bm2 = Bitmap.new(r2)
    	bm2:setScaleX((wR-cut*2)/(w-cut*2)) --rescale top mid part
    	local bm3 = Bitmap.new(r3)
    	rt:draw(bm1,0,0)
    	rt:draw(bm2,cut,0)
    	rt:draw(bm3,wR-cut,0)
     
    	--left
    	bm1 = Bitmap.new(r4)
    	bm1:setScaleY((hR-cut*2)/(h-cut*2)) --rescale left mid part
    	bm2 = Bitmap.new(r5)
     
    	--mid
    	bm3 = Bitmap.new(r6)
    	bm3:setScale((wR-cut*2)/(w-cut*2), (hR-cut*2)/(h-cut*2), 1)
     
    	rt:draw(bm1,0,cut)
    	rt:draw(bm2,0,hR-cut)
    	rt:draw(bm3,cut,cut)
     
    	--right
    	bm1 = Bitmap.new(r7)
    	bm1:setScaleY((hR-cut*2)/(h-cut*2))
    	rt:draw(bm1,wR-cut, cut)
     
     
    	--bot
    	bm1 = Bitmap.new(r8)
    	bm1:setScaleX((wR-cut*2)/(w-cut*2))
    	bm2 = Bitmap.new(r9)
    	rt:draw(bm1,cut, hR-cut)
    	rt:draw(bm2,wR-cut, hR-cut)
     
    	return rt
     
    end
     
    --patch9(image, cut,  w, h)
    --cut is cutting square size
    local bm = Bitmap.new(patch9("img/btnrew.png",20, 300,50))


    @hgy29
    thanks,

    I think this would be much easier if there were additional parameters to RenderTarget:draw(x,y, w,h) so we can actually target what to draw

    Likes: pie, antix

    2019-02-15_213818.jpg
    307 x 412 - 22K
    +1 -1 (+2 / -0 ) Share on Facebook
  • SinisterSoftSinisterSoft Maintainer
    edited February 16
    You can effectively do that - the draw command takes an optional x,y and you can set a clip on the sprite you draw.

    Likes: gemboy100

    +1 -1 (+1 / -0 ) Share on Facebook
  • wow thats awesome, and I missed that too :sweat:
    so this saved me couple of lines and its much easier to write
    function patch_9(img,cut,wR,hR)
    	local t = Texture.new(img, true)
    	local tx = Bitmap.new(t)
    	local w,h = tx:getWidth(), tx:getHeight()
    	local rt = RenderTarget.new(wR, hR)
     
    	tx:setClip(0,0,cut,cut)
    	rt:draw(tx, 0,0)
     
    	local r1 = TextureRegion.new(t, cut,   0,   w-cut*2, cut)
    	local bm1 = Bitmap.new(r1)
    	bm1:setScaleX((wR-cut*2)/(w-cut*2)) 
    	tx:setClip(cut,0,w-cut*2,cut)
    	rt:draw(bm1, cut,0)
     
    	tx:setClip(w-cut,0,cut,cut)
    	rt:draw(tx, wR-w,0)
     
    	r1 = TextureRegion.new(t, 0, cut, cut,h-cut*2)
    	bm1 = Bitmap.new(r1)
    	bm1:setScaleY((hR-cut*2)/(h-cut*2))
    	rt:draw(bm1, 0,cut)
     
    	tx:setClip(0,h-cut,cut,cut)
    	rt:draw(tx, 0,hR-h)
     
    	r1 = TextureRegion.new(t, cut, cut, w-cut*2,h-cut*2)
    	bm1 = Bitmap.new(r1)
    	bm1:setScale((wR-cut*2)/(w-cut*2), (hR-cut*2)/(h-cut*2)) 
    	rt:draw(bm1, cut, cut)
     
    	r1 = TextureRegion.new(t, w-cut, cut, cut,h-cut*2)
    	bm1 = Bitmap.new(r1)
    	bm1:setScaleY((hR-cut*2)/(h-cut*2))
    	rt:draw(bm1, wR-cut, cut)
     
    	r1 = TextureRegion.new(t, cut, h-cut, w-cut*2,cut)
    	bm1 = Bitmap.new(r1)
    	bm1:setScaleX((wR-cut*2)/(w-cut*2)) 
    	rt:draw(bm1, cut,hR-cut)
     
    	tx:setClip(w-cut,h-cut,cut,cut)
    	rt:draw(tx, wR-w,hR-h)
     
    	return rt
    end

    Likes: SinisterSoft

    +1 -1 (+1 / -0 ) Share on Facebook
  • SinisterSoftSinisterSoft Maintainer
    edited February 16
    I think you can keep the same bitmap and region, just change the texture region by using use setRegion to change the coordinates.

    http://wiki.giderosmobile.com/index.php/Special:MyLanguage/TextureRegion:setRegion

    Likes: Apollo14

    +1 -1 (+1 / -0 ) Share on Facebook
  • The mesh way could be combined with this for resizing btw...

    Likes: Apollo14, keszegh

    +1 -1 (+2 / -0 ) Share on Facebook
  • @SinisterSoft is correct, you can just reuse one bitmap and use set its region and other stuff like scaling and orientation. It is easiest to store your 9 patch bits inside a TexturePack for more ease too :)
  • a class based on a mesh with 9x2 triangles and an appropriate texture array would be the most elegant and probably the fastest solution. you could also easily add functions to it which modify its shape afterwards being created.
  • Great! Thanks!
    It actually has all the tools but very little guides on this matter (or Im missing something again(or it is hard to find it)). :blush:
    keszegh said:

    a class based on a mesh with 9x2 triangles and an appropriate texture array would be the most elegant and probably the fastest solution. you could also easily add functions to it which modify its shape afterwards being created.

    Currently I don't care speed as I only use it to create new level, but if I would, what do you think, what is approximate performance I could achieve
    I assume, thats the lowest level Gideros can touch considering drawing on screen.
  • I've started using pixels a lot for stuff like this, just recombining then to make simple window shapes - they are fast as there is no read from texture - or I use path2D to create things that need smooth edges with possibly an outline - they can be changed dynamically and so could 'grow' or morph from one shape to another with the correct manipulation.

    Likes: antix

    +1 -1 (+1 / -0 ) Share on Facebook
Sign In or Register to comment.