drawing what's not on the screen (and best practices?)

Questions about the LÖVE API, installing LÖVE and other support related questions go here.
Forum rules
Before you make a thread asking for help, read this.
Post Reply
User avatar
paritybit
Citizen
Posts: 53
Joined: Thu Sep 06, 2012 3:52 am

drawing what's not on the screen (and best practices?)

Post by paritybit »

I've been playing around with love2d for a few weeks now and, thanks to how easy it is to use and how fun Lua is to learn, I think I've got a pretty good grasp on what I'm doing. But I have a general best practices question.

I've got a scrolling (in all directions) space-themed 'playground' set up; thanks to quite a bit of help from the community (parallax scrolling, hump and so many others) I've got a 'world' with four layers:
  • a base star layer (a layer of 512x512 tiles that are black with white dots) moving at 1/16 of the primary layer
  • a 'closer' star layer (a layer of 512x512 tiles that are transparent with white dots) moving at 1/8 of the primary layer
  • a layer of semi-randomly placed colored 'stars' (chance based to have one or more positioned within each 512x512 grid moving at 1/2 of the primary layer
  • the primary layer on which foreground objects are drawn (the player, asteroids, etc)
  • a mostly static layer on top which provides some hud-type elements.
Each of these layers is larger than the current screen; my primary layer is 32,768x32,768 of which 16,384 is really redundant buffer area for wrap-around. I had a much larger area with many more tiles (which I'd eventually like to go back to) but I wanted to scale it down for a first attempt at completing something.

So I have three layers that are essentially static, but much bigger than the screen. My questions all revolve around the stuff not currently being seen.
  • Should I try to avoid drawing what is not on the screen? Currently I'm just looping through all of my tiles and drawing them. I have an if statement to check whether some part of the tile was on the screen, but does that really save me anything? I guess this boils down to 'does the draw method simply ignore things that aren't being shown'? I think there were some hints about this in another recent topic, but I'm still not sure it was answered.
  • Would I gain any benefit by drawing each static layer to a frame buffer? I read this conversation to the end, but I don't think I reached a conclusion as to whether it's beneficial in some way for my scenario. And it really made me more curious about my first question.
  • Am I going to cause severe strain by piling layers over layers with the uppermost layers having lots of transparency?
Thanks
Last edited by paritybit on Thu Sep 20, 2012 6:30 am, edited 1 time in total.
rvj
Prole
Posts: 15
Joined: Fri Feb 10, 2012 5:55 pm

Re: drawing what's not on the screen (framebuffer?)

Post by rvj »

Good questions, and I'd like to see the answers to them (as well as a love file of your set up).

I haven't had much of a chance to test your first question (checking off-screen things instead of just drawing all of them) but I have a similar issue. From what I've read, you're generally better off just drawing everything, as the 'on-screen detection' often costs more time than it saves. In my case, since I have some objects that are pretty complicated to draw, I decided that a rough detection was worthwhile. It must vary depending on the case, specifically how long you expect it to take for the tile to draw, versus how long it would take to check it first. In my experience drawing operations have been surprisingly quick, and my collision detection (including on-screen detection) have been surprisingly slow.

I have one line of code that checks each object before it draws. I just commented it out and can't see a difference in FPS. The only lesson we can learn from that is that it's sweet to write code that lets you make these decisions later.
User avatar
verilog
Citizen
Posts: 97
Joined: Thu Nov 03, 2011 3:15 am
Contact:

Re: drawing what's not on the screen (framebuffer?)

Post by verilog »

Hey man!

I came across some similar questions when I was developing my own canvas-layer system. Maybe some of my findings could be useful for you! :crazy:

Framebuffer support is hardware dependent. That means that not all the computers may be able to run your program properly, sadly that’s my case, therefore, the only option left for me was to build a custom canvas system from scratch.

My solution does, indeed, draw layers outside of the main viewport (on-screen) area. In fact, it currently draws 3 screens: the previous screen (s-1), the current screen (s), and the next screen (s+1). Why? Because I must be able to immediately provide the next (or previous) background images as the camera scrolls, otherwise it won’t create the illusion of a camera really moving inside a huge (bigger than the viewport dimensions) continuous world.

Think of it as a 3 x 1 screen buffer (actually a matrix) that is constantly rotating images inside, depending on the camera focus. Of course, the real size of the screen buffer depends on the game resolution, and this can be tailored to your needs.

The main idea here is that you usually draw stuff outside the screen to be able to present it in real-time to the user as the camera scrolls back and forth (or up and down!). Of course, you don’t want to be wasting resources drawing things that are 20 screens ahead of the actual viewport position. :|

Edit:
paritybit? nice nickname
User avatar
paritybit
Citizen
Posts: 53
Joined: Thu Sep 06, 2012 3:52 am

Re: drawing what's not on the screen (framebuffer?)

Post by paritybit »

rvj wrote:Good questions, and I'd like to see the answers to them (as well as a love file of your set up).
Since you ask, I've attached what I've got so far. It's not all that exciting. Some of it is very well documented, but most of it is not. Mostly I've been avoiding putting it up because it doesn't necessarily have all the correct attributions yet. I'm using Anim8 for the explosion which I borrowed from a free game art web site, HadronCollider [sic] for collisions (which I feel I need to rewrite just so I don't have to worry about my son seeing the name), and some code based on others work but entirely rewritten.

Start it up and you are the ship in the middle. Collision detection is not functional for the player so there's no way to die. You will never reach the end of space because it wraps around (you will notice when you wrap around if you look at the position in the lower left corner). All objects wrap around, bullets, you, gold discs, everything -- that was my big headache tonight, but it came out well in the end; unfortunately it means I have to draw things up to three extra times if they are at the wrong part of space (in the buffer). The following controls work:
  • space bar to thrust which uses fuel (capacity shown in the bar along the bottom) which regenerates slowly. Once you're in motion, you'll stay that way until you thrust the other way. if you deplete your fuel entirely, it will become unusable for a short time.
  • 'f' toggles the camera mode; it lets you do some cool stuff with the ship. It will toggle to static screen and then back to the follow mode. If you wrap around, the transition to follow mode will act bizarre.
  • mouse button 1 shoots.
  • mouse wheel up and down zoom in and out (only on the topmost layer, stars all remain the same size)
  • the pause keyboard button will pause the game
  • 1, 5, and 0 change the game speed (0.5x, 1x and 1.5x respectively)
It's not meant to be fully functional or it'd be in the demos section. Also, not fully optimized -- some things I know, many I don't. I'd certainly love for people to tell me obvious beginners mistakes if they are so inclined, but mostly I just wanted general answers to the questions rather than a grooming of my code.
rvj wrote: I have one line of code that checks each object before it draws. I just commented it out and can't see a difference in FPS. The only lesson we can learn from that is that it's sweet to write code that lets you make these decisions later.
I did roughly the same thing and didn't notice any change in behavior. But there isn't a lot happening so I'm not sure that I'd see any benefit yet. Mostly I'm just looking for best practices and I don't think that's really been answered yet. I've been trying to design with future changes in mind, though some aspects are just randomly dumped into main for now until I find the right place for them.
verilog wrote:paritybit? nice nickname
Thanks.
verilog wrote: The main idea here is that you usually draw stuff outside the screen to be able to present it in real-time to the user as the camera scrolls back and forth (or up and down!). Of course, you don’t want to be wasting resources drawing things that are 20 screens ahead of the actual viewport position. :|
So should I be using some kind of spatial data structure to limit the sections of the world tiles and actors are actually drawn? How far outside the current viewport should I draw? It seems like I don't really need to draw outside the viewport because as soon as something shows up I could just start drawing it and that would have the same effect? When I add something new to what's being drawn, there's no real hit that I can tell. I'm just slightly confused about all this.
Attachments
spacelove.love
(937.54 KiB) Downloaded 139 times
User avatar
tv_user
Citizen
Posts: 57
Joined: Sun Aug 12, 2012 4:39 pm
Location: Portugal

Re: drawing what's not on the screen (and best practices?)

Post by tv_user »

Honestly I didn't read the entire post and I don't know how love.draw() handles objects that are not visible on screen, but here's my suggestion: why don't you organize your objects into "quadrants" and draw only the objects in the 1 to 4 quadrants that are currently visible? That wouldn't require a lot of frame-by-frame testing because each object was already pre-allocated to a quadrant. And whenever an object moved, it would also update the quadrant to which it belonged.
What say you, Love experts? :awesome:
Did my comment help/offended you? Use the Karma button!!
LÖVEing each day...
Post Reply

Who is online

Users browsing this forum: Bing [Bot], pgimeno and 9 guests