Quick Links: Download Gideros Studio | Gideros Documentation | Gideros Development Center | Gideros community chat | DONATE
Does Gideros render off-screen objects? — Gideros Forum

Does Gideros render off-screen objects?

MikeHartMikeHart Guru
edited December 2011 in General questions
I would like to know if gideros automatically pulls objects from the render process, that are with their bounds completely off-screen. Or does the developer have to take care of this him-/herself?

Comments

  • atilimatilim Maintainer
    Currently only for tilemaps (I mean if you have a huge tilemap, only the portion that's inside the screen is drawn). For others, it'll be implemented soon.

    Likes: SinisterSoft

    +1 -1 (+1 / -0 )Share on Facebook
  • Hi atilim,

    I send you a private message on the forum.

    Michael
  • This thread is a bit older than ... anyways ;) .
    For others, it'll be implemented soon.
    What's the status? Does Gideros still render off screen images?


    Greetings
    Sebastian
  • Yep - nothing's changed on that front (yet). If you know your image is offscreen you can set it's visible status to false to make the rendering a bit more efficient.
    WhiteTree Games - Home, home on the web, where the bits and bytes they do play!
    #MakeABetterGame! "Never give up, Never NEVER give up!" - Winston Churchill
  • petecpetec Member
    I find it quite useful that images are rendered when off screen (if that means outside the logical dimensions) as it allows me to position things like a close button at top right of a 400x800 screen and then, with a bit of code, move it further up if the app is on an ipad, so the button still sits top right rather than down the screen a bit. I take it this would no longer be possible if off screen images were not rendered? If that's the case, then I'd prefer it to be a settable option and I'll manage visibility status or removal manually when necessary.
  • @petec, you would still be able to do that. The feature they're referring to is so anything that would not display on the current device's screen would not be rendered to save processing power.
  • petecpetec Member
    @zvardin - That's fine then. Thanks for the explanation. :)
  • john26john26 Maintainer
    Doesn't OpenGL cull off-screen fragments automatically? If you tell OpenGL to draw a polygon and it turns out to be off-screen, clearly OpenGL does not draw it... I guess it depends when OpenGL discovers the object is out of bounds, hopefully before it wastes too much time.
  • It does, but before OpenGL get's to it there's plenty of code run to translate, rotate, test, setup buffers, change state etc etc. If the object is invisible then none of that code has to be run and when the number of objects increases so does the total time taken.

    Likes: seppsepp

    WhiteTree Games - Home, home on the web, where the bits and bytes they do play!
    #MakeABetterGame! "Never give up, Never NEVER give up!" - Winston Churchill
    +1 -1 (+1 / -0 )Share on Facebook
  • jimlevjimlev Member
    One year later, quite the same interrogations... :(

    I have a large quantity of animated sprites on the stage (sthg like 200).
    As they move independently and the user can drag the display, I think to include a test on their onEnterframe event to check if they are offscreen. The goal is to stop the animation (or any other processes of their class) to optimize the framerate.

    As it's quite difficult for me to code a solution (I'm a self-learning-and-empiric-method-developper™), I have few questions :

    - is it necessary to manage these sprites or, as they are offscreen, they are not drawn (and so they are not a charge for the processor) ?

    - In the same way, does a sprite with alpha set to 0 is equally gourmand than a visible sprite ?

    - As I'm an animator, I immediately worry for the processor's difficulties to face to my sprites (the graphist point of vue). But do I have to worry much more about the many operations that my sprites have to manage on each frame (calculate their direction, their stats, updating their datas, etc...) ?
    My meditation plan :
    SinisterSoft: “ I don't create classes that much - classes are good for making things simpler but imho for frame rate they are also death by a thousand cuts.”
    Totebo: “ Best quote ever.”
    🤔
  • ar2rsawseenar2rsawseen Maintainer
    @jimlev unfortunately sprites outside the screen still count
    the only way to make them not count is to set setVisible(false)
  • Hi jimlev
    Don't worry about animating Sprites. Do it by Movieclip Class(OpenGL and native code =very fast)
    Don't worry about using Gideros functions(Like setX(),getX(),...) (Lau and native code = fast)
    Just worry about using a lot of Calculation in lua (lua= it's not fast in calculation. it's a scripting language not programing one)

  • So what is the most efficient way to stop the off screen rendering?
    I have all my sprites in the same layer

    I have tried this code in enter frame function but it seems inefficient
    local child
    for i = 1,layer:getNumChildren() do
     child = layer:getChildAt(i)
     if child:getX() < 0 or child:getX() > 400 then
      child:setVisible(false)
     else
     child:setVisible(true)
    end
  • ar2rsawseenar2rsawseen Maintainer
    1) it could be efficient with Luajit :)
    2) You don't have to check it on every enterframe, you can check it like once a second, it also would be enough

    Likes: SinisterSoft

    +1 -1 (+1 / -0 )Share on Facebook
  • Or one or two sprites per second - share the workload.

    Another thing you could do is use table variables for your sprites and keep a constant set of them - never create or remove them - just change their image. That's what I do and it seems to be faster. It makes the machine like a classic console.
    Coder, video game industry veteran (since the '80s, ❤'s assembler), arrested - never convicted hacker (in the '90s), dad of five, he/him (if that even matters!).
    https://deluxepixel.com
  • @ar2rsawseen It would definitely be more efficient with luajit
    The problem is that in my game I use a camera class, scrollable by the user. I think that if the user drags very fast then the one second difference between checks is a very big amount of time
    and the sprites for a few ms would be invisible even being on screen.
  • HolonistHolonist Member
    edited April 2015
    Check if your sprites are out of bounds. If they are, check if they are visible. If so, change their state to invisible. If, on the other hand, they are in bounds, check if they are visible. If not, set them visible.

    It's a lot of checks every frame, but it's very simple statements. You should be able to compute tons of them every frame.

    Likes: SinisterSoft

    +1 -1 (+1 / -0 )Share on Facebook
  • piepie Member
    @dreiko65 if the only way that sprites enter/exit your screen bounds is the user scrolling you could do the check just on mousemove/mouse up events (or any event that refresh the screen)

    Likes: Holonist

    +1 -1 (+1 / -0 )Share on Facebook
  • or set a flag on any mouse move events - check the flag on the render event.
    Coder, video game industry veteran (since the '80s, ❤'s assembler), arrested - never convicted hacker (in the '90s), dad of five, he/him (if that even matters!).
    https://deluxepixel.com
  • Well I think the solution to the off screen rendering is a mix of all the above comments
    My game has six layers on every level.Each one contains a few png images, one next to the other (ex. 2 layer contain mountains, 2 others some trees , the foreground etc). That way I wanted to make a parallaxing background. In a big level I might need lets say 20 images per leyer.
    Yes! but each image is 1280 width by its height( there are not all the same in height) whitch makes six 25.600 pixels wide layers. Its useless to render them all each frame.
    Anyway I came up with a solution which is a mix of all the comments above

    In the EnterFrame event I added a counter which counts the frames.

    On frame 1 it checks 2 layers, on frame 2 other two layers and on frame 3 the other two and it turns to 0 again
    frame = frame + 1 
    	local child
    	if frame == 1 then
    		for i = 1,self.componentsLayer:getNumChildren()do
    			child = self.componentsLayer:getChildAt(i)
    			local x,y =  self.componentsLayer:localToGlobal(child:getPosition())
    			if x + child:getWidth() < -100 or x - child:getWidth() > 1000 then
    				child:setVisible(false)
    			else
    				child:setVisible(true)
    			end
    		end
    		for i = 1,self.mountsLayer_One:getNumChildren()do
    			child = self.mountsLayer_One:getChildAt(i)
    			local x,y =  self.mountsLayer_One:localToGlobal(child:getPosition())
    			if x + child:getWidth() < -100 or x - child:getWidth() > 1000 then
    				child:setVisible(false)
    			else
    				child:setVisible(true)
    			end
    		end
    	elseif frame == 2 then
    		for i = 1,self.mountsLayer_Two:getNumChildren()do
    			child = self.mountsLayer_Two:getChildAt(i)
    			local x,y =  self.mountsLayer_Two:localToGlobal(child:getPosition())
    			if x + child:getWidth() < -100 or x - child:getWidth() > 1000 then
    				child:setVisible(false)
    			else
    				child:setVisible(true)
    			end
    		end
     
    		for i = 1,self.mountsLayer_Three:getNumChildren()do
    			child = self.mountsLayer_Three:getChildAt(i)
    			local x,y =  self.mountsLayer_Three:localToGlobal(child:getPosition())
    			if x + child:getWidth() < -100 or x - child:getWidth() > 1000 then
    				child:setVisible(false)
    			else
    				child:setVisible(true)
    			end
    		end
    	elseif frame == 3 then
    		for i = 1,self.boushesLayer:getNumChildren()do
    			child = self.boushesLayer:getChildAt(i)
    			local x,y =  self.boushesLayer:localToGlobal(child:getPosition())
    			if x + child:getWidth() < -100 or x - child:getWidth() > 1000 then
    				child:setVisible(false)
    			else
    				child:setVisible(true)
    			end
    		end
    		for i = 1,self.greensLayer:getNumChildren()do
    			child = self.greensLayer:getChildAt(i)
    			local x,y =  self.greensLayer:localToGlobal(child:getPosition())
    			if x + child:getWidth() < -100 or x - child:getWidth() > 1000 then
    				child:setVisible(false)
    			else
    				child:setVisible(true)
    			end
    		end
    		frame = 0
    	end
    Without that code I was getting 12fps with 200 png per layer (256.000 pixels!!)
    with this code in the enterframe I get 55!!
    I will never use 200 images per layer ofcourse but it was a stress test

    I might try to make some adjustments to make my code more efficient but I am quite happy with the result.
    Hope that helps..
  • SinisterSoftSinisterSoft Maintainer
    edited April 2015
    Work out the scale of the layer to the screen and find new up,down,left,right max points.

    That way you don't have to work out the local to global.

    Also when you create the objects, if you also put their pointer into a table then just interate through that rather than having to use getnumchildren and getchildat.

    You could also have all the objects on one layer, then sort them one pass per video frame based on a layer value. I do this with the dungeons game and it seems to work ok. A command to swap two sprites in the drawing list in one of the last versions of gideros.
    Coder, video game industry veteran (since the '80s, ❤'s assembler), arrested - never convicted hacker (in the '90s), dad of five, he/him (if that even matters!).
    https://deluxepixel.com
Sign In or Register to comment.