Fast way to draw large number of quads?

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.
jeremiahs
Prole
Posts: 13
Joined: Mon May 30, 2011 10:19 pm

Fast way to draw large number of quads?

Post by jeremiahs »

The adventure continues!

Thanks to my last question, I got schooled in how to draw a more efficient map. And it worked! I implemented a "spatial hash" and all is right with the world... except for one thing.

The framerate craters when I zoom out, I assume because LOVE has to start drawing way more quads. If you load the game and hit the letter "o" to zoom "out" (clever, right?) you'll see what I mean. The reverse is also true: zoom in ("i"), showing less, and the framerate shoots up.

I'd really like to be able to zoom out to a stupid level of detail and keep framerates high. Is there some way to generate quads on the fly that consist of smaller quads joined together, perhaps? Or some other approach that will work?

There are two parts, currently, to drawing the tiles. One function creates the x,y boundaries, and the other function goes through the hash drawing every tile that's on the screen.

Boundary part:

Code: Select all

function setGrid()
	global.gridXStart = math.floor((global.camera.centerX - (global.screenW/2/global.scale)) / global.spriteSize)
	global.gridXEnd = math.floor((global.camera.centerX + (global.screenW/2)/global.scale) / global.spriteSize)
	global.gridYStart = math.floor((global.camera.centerY - (global.screenH/2)/global.scale) / global.spriteSize)
	global.gridYEnd = math.floor((global.camera.centerY + (global.screenH/2)/global.scale) / global.spriteSize)
end
(Using math.ceil seemed to lower the framerate, so I use math.floor above and add/subtract 1 below to make sure the edge tiles don't flicker instead of using math.ceil. That may have been my imagination.)

Code: Select all

function drawStuff()
	local theX
	local theY
	for theX = global.gridXStart - 1, global.gridXEnd + 1, 1 do 
		for theY = global.gridYStart - 1, global.gridYEnd + 1, 1 do
			if theX > 0 and theY > 0 and global.spriteGrid[theX][theY] ~= nil then
				global.spriteGrid[theX][theY]:draw()
			end
		end
	end
end
Edited to add: Forgot to mention that the framerate still randomly craters and then goes back up. If it happens to you too please let me know so I know I'm not crazy. Any thoughts on that still welcome.
Attachments
game.love
(7.16 MiB) Downloaded 173 times
User avatar
Kadoba
Party member
Posts: 399
Joined: Mon Jan 10, 2011 8:25 am
Location: Oklahoma

Re: Fast way to draw large number of quads?

Post by Kadoba »

You will probably get a drastic increase in speed if you utilize spritebatches to draw your map instead of drawing each tile individually. math.ceil shouldn't hit your performance although if you didn't localize the lua math table the global lookups might.

I didn't take too deep of a look but I suggest two things right off the bat. First put "local math = math" at the top of the file where your setGrid() function is. This will localize the lua math functions so calling them is faster. The second thing is to try and implement a SpriteBatch instead of having individual draw calls on every tile.

If SpriteBatches confuse you then post again and we'll help you out.

*edit*
Oh yeah and please use dt when you move anything. love.update doesn't update at a set rate so on faster computers it gets called more often. On my computer your character is moving super fast.

*edit2*
Actually you only call that setGrid() function once per draw cycle so localizing math probably won't do a whole lot. Although it's a good idea to remember to localize globals in code that gets called a lot.
Last edited by Kadoba on Sat Jun 18, 2011 9:44 pm, edited 2 times in total.
User avatar
Robin
The Omniscient
Posts: 6506
Joined: Fri Feb 20, 2009 4:29 pm
Location: The Netherlands
Contact:

Re: Fast way to draw large number of quads?

Post by Robin »

You could also use Framebuffers, perhaps one for each zoom-level. This depends on the size and variability of your game world though.
Help us help you: attach a .love.
jeremiahs
Prole
Posts: 13
Joined: Mon May 30, 2011 10:19 pm

Re: Fast way to draw large number of quads?

Post by jeremiahs »

Kadoba:

I do use dt. "A" and "S" make the character movement and animation faster/slower. The speed is displayed in the upper left-hand corner. 100 is the "base" speed, but I set it to 500 just to run around the map quicker during testing.

I'll give spritebatches a look and see if my brain can wrap around the idea.

Robin:

Will framebuffers really speed things up? My thinking is that the problem is drawing so many quads so many times, and a framebuffer is just another drawing surface, so why would it be any faster?

(I will experiment with framebuffers regardless, but I always want to know more about why things do what they do.)
User avatar
Robin
The Omniscient
Posts: 6506
Joined: Fri Feb 20, 2009 4:29 pm
Location: The Netherlands
Contact:

Re: Fast way to draw large number of quads?

Post by Robin »

jeremiahs wrote:Will framebuffers really speed things up? My thinking is that the problem is drawing so many quads so many times, and a framebuffer is just another drawing surface, so why would it be any faster?
They will not help if you keep drawing, but if you draw the map to a framebuffer once, and keep drawing that framebuffer to the screen, it will speed up massively.
Help us help you: attach a .love.
jeremiahs
Prole
Posts: 13
Joined: Mon May 30, 2011 10:19 pm

Re: Fast way to draw large number of quads?

Post by jeremiahs »

Robin, could you help me out a bit? Maybe some pseudocode or a link? I'm not getting something basic about the idea.

If the visible portion of the map changes (which it does every time the character moves), won't I have to redraw the framebuffer every time, making it just as bad as the current method? Are you saying there's a way to draw all of the map to a framebuffer at one time, and then manipulate the framebuffer to get the effect I need?
User avatar
bartbes
Sex machine
Posts: 4946
Joined: Fri Aug 29, 2008 10:35 am
Location: The Netherlands
Contact:

Re: Fast way to draw large number of quads?

Post by bartbes »

He means you only draw to the framebuffer whenever something on the map changes (when you zoom or move), that way you don't have to draw every frame. (Drawing a framebuffer is considerably cheaper.)
jeremiahs
Prole
Posts: 13
Joined: Mon May 30, 2011 10:19 pm

Re: Fast way to draw large number of quads?

Post by jeremiahs »

So when moving, the framerate would be just as bad as it is now; when standing still, the framerate would fly?
User avatar
Robin
The Omniscient
Posts: 6506
Joined: Fri Feb 20, 2009 4:29 pm
Location: The Netherlands
Contact:

Re: Fast way to draw large number of quads?

Post by Robin »

jeremiahs wrote:So when moving, the framerate would be just as bad as it is now; when standing still, the framerate would fly?
Not exactly. You can draw the whole map (even the invisible portions) once to a framebuffer, because you can draw framebuffers with an offset. So you only really need to do expensive redrawing when something in the map changes.
Help us help you: attach a .love.
jeremiahs
Prole
Posts: 13
Joined: Mon May 30, 2011 10:19 pm

Re: Fast way to draw large number of quads?

Post by jeremiahs »

Okay, so I just messed around with the framebuffer idea. LOVE crashes whenever I try to make a framebuffer larger than 16384 by 16384, which, with 50 by 50 tiles is a 327 by 327 tile map. And there are weird performance issues; it stalls and jumps for what seem like no reason. One of the things I'm trying to get straight is how to create a system that provides decent performance with arbitrary map sizes.

Smaller framebuffers do seem to be fast and don't have the performance issues of larger framebuffers, but it seems as though using them would require a semi-elaborate system, perhaps a series of spatial hashes for different zoom levels. I don't want to put in the effort and then discover a much more elegant method later on. Any thoughts?

(Still haven't had a chance to experiment with spritebatches.)
Post Reply

Who is online

Users browsing this forum: Bing [Bot] and 3 guests