Apparently if you are drawing more than about 2500 rectangles, then the situation gets kinda laggy. Anyone know of a way to get around this? Cause I plan on having a lot more than 2500 rectangles...
I tried stencils, couldn't get that working right.
Though I have noticed that fill rectangles are less laggy than line rectangles. Don't know what the deal is with that.
Not interested in spritebatches and canvas' because some people don't support canvas' and I'm not even working with textures yet, so don't know why I would need a spritebatch.
Any help is appreciated, especially the kind where I learn.
Faster way to draw rectangles?
Forum rules
Before you make a thread asking for help, read this.
Before you make a thread asking for help, read this.
- Zilarrezko
- Party member
- Posts: 345
- Joined: Mon Dec 10, 2012 5:50 am
- Location: Oregon
Re: Faster way to draw rectangles?
Why in hell would you need 2500 rectangles onscreen? (I emphasize onscreen, because if you're drawing anything offscreen, you're doing it wrong.)
And, I think canvases have a reasonable amount of support for you to use them. It's most likely only a small minority that would be affected, if in the name of performance.
And, I think canvases have a reasonable amount of support for you to use them. It's most likely only a small minority that would be affected, if in the name of performance.
- Zilarrezko
- Party member
- Posts: 345
- Joined: Mon Dec 10, 2012 5:50 am
- Location: Oregon
Re: Faster way to draw rectangles?
Testing, I gotta zoom out to right click to test out my laggy arse pathfinding.Kingdaro wrote:Why in hell would you need 2500 rectangles onscreen? (I emphasize onscreen, because if you're drawing anything offscreen, you're doing it wrong.)
And, I think canvases have a reasonable amount of support for you to use them. It's most likely only a small minority that would be affected, if in the name of performance.
But the thing is, is that I get the performance drop whether they're on screen, or they aren't. So if you know some magic, pass some ovah here.
Besides, I'm having trouble with canvases. I put the same draw code into the canvas after setCanvas. Then I'm having trouble that the conditions in the canvas aren't working. So I have to recreate the canvas object pretty much every frame. Now I'm back where I started performance wise.
- Jasoco
- Inner party member
- Posts: 3725
- Joined: Mon Jun 22, 2009 9:35 am
- Location: Pennsylvania, USA
- Contact:
Re: Faster way to draw rectangles?
You're gonna have to provide a .love or an example of what kind of game you're making.
- slime
- Solid Snayke
- Posts: 3132
- Joined: Mon Aug 23, 2010 6:45 am
- Location: Nova Scotia, Canada
- Contact:
Re: Faster way to draw rectangles?
When talking about filled rectangles, a white image of any size is essentially equivalent to a rectangle.Zilarrezko wrote:Not interested in spritebatches and canvas' because some people don't support canvas' and I'm not even working with textures yet, so don't know why I would need a spritebatch.
Something like this will be the most efficient (for filled rectangles):
Code: Select all
-- Create a 1x1 white image for use with a SpriteBatch.
local imagedata = love.image.newImageData(1, 1)
imagedata:setPixel(0, 0, 255, 255, 255, 255)
local rectimage = love.graphics.newImage(imagedata)
local spritebatch = love.graphics.newSpriteBatch(rectimage, 3000)
function UpdateRects(rectlist)
spritebatch:clear()
spritebatch:bind()
for i, rect in ipairs(rectlist) do
spritebatch:setColor(rect.color)
-- We can use the scale parameters for width and height, since we're scaling a 1x1 image.
spritebatch:add(rect.x, rect.y, 0, rect.width, rect.height)
end
spritebatch:unbind()
end
function DrawRects()
love.graphics.draw(spritebatch, 0, 0)
end
EDIT: kikito's advice below applies to this as well.
Last edited by slime on Wed Oct 15, 2014 7:59 am, edited 1 time in total.
- kikito
- Inner party member
- Posts: 3153
- Joined: Sat Oct 03, 2009 5:22 pm
- Location: Madrid, Spain
- Contact:
Re: Faster way to draw rectangles?
When talking about reducing the amount of tiles being drawn, a simple "if" is not enough. The trick is setting up things so that most of the rectangles are not even considered in the first place (so you don't have to do an "if" around them at all).
If the rectangles you are trying to draw are tile-based, you can do this to minimize (correctly) the amount of rectangles being drawn:
viewtopic.php?f=4&t=77081#p161482
If you are not, then your best bet is using some Spatial Database to get the rectangles efficiently. In my experience, a simple grid (where each cell has a list of rectangles touching it, and each rectangle knows what cells it touches, and these lists get updated as the rectangle moves) is enough - quadtress etc are more complex but they get similar or even worse performance when the rectangles are not sparse.
If the rectangles you are trying to draw are tile-based, you can do this to minimize (correctly) the amount of rectangles being drawn:
viewtopic.php?f=4&t=77081#p161482
If you are not, then your best bet is using some Spatial Database to get the rectangles efficiently. In my experience, a simple grid (where each cell has a list of rectangles touching it, and each rectangle knows what cells it touches, and these lists get updated as the rectangle moves) is enough - quadtress etc are more complex but they get similar or even worse performance when the rectangles are not sparse.
When I write def I mean function.
- Zilarrezko
- Party member
- Posts: 345
- Joined: Mon Dec 10, 2012 5:50 am
- Location: Oregon
Re: Faster way to draw rectangles?
Alright, so I have no experience what so ever in spritebatches... This is the first time I've looked at them...
I can't do a lot right now, because I'm at school (got chewed out once for being too into my laptop). But in a few hours I'll either edit this post, trying different things and letting you guys know the outcome. Or I'll be stuck doing homework for the rest of the day. Who knows which.
kikito, your idea has struck my mind (Since I implemented something similar to my very bad 3D thing). But I have no idea how to forsee a rectangle being out of the window. Other than if one rectangle is out of bounds of the (let's say first right part of the screen), then if another rectangles' x is greater than the one that's outside of the screen than don't draw it. But for me I think that's going to require the same amount of if then's to every rectangle. Not to mention my newbness of making things over-engineered, and in that making it even slower than it was before.
They're all just tile squares to be honest, and at this point all white/gray squares (I tried line rectangles and apparently those are slower than filled ones). So I don't think I need or will understand spatial databases for a long while.
I may end up using spritebaches though... we'll see.
And Jasoco, The game is no where near what it is going to be like haha. But It's going to be like the thing I mentioned in the what's everyone working on? Thread. Thing of a dwarf fortress adventure mode. (Chances mostly in favor of I'll never make it playable. But I'll learn a lot in the meantime). Except entities and the like won't be restricted to tiles.
But if you'd like to look at the source code so far. It's just a mashup of pretty much everything I've done... Except shaders and stuff.
I can't do a lot right now, because I'm at school (got chewed out once for being too into my laptop). But in a few hours I'll either edit this post, trying different things and letting you guys know the outcome. Or I'll be stuck doing homework for the rest of the day. Who knows which.
kikito, your idea has struck my mind (Since I implemented something similar to my very bad 3D thing). But I have no idea how to forsee a rectangle being out of the window. Other than if one rectangle is out of bounds of the (let's say first right part of the screen), then if another rectangles' x is greater than the one that's outside of the screen than don't draw it. But for me I think that's going to require the same amount of if then's to every rectangle. Not to mention my newbness of making things over-engineered, and in that making it even slower than it was before.
They're all just tile squares to be honest, and at this point all white/gray squares (I tried line rectangles and apparently those are slower than filled ones). So I don't think I need or will understand spatial databases for a long while.
I may end up using spritebaches though... we'll see.
And Jasoco, The game is no where near what it is going to be like haha. But It's going to be like the thing I mentioned in the what's everyone working on? Thread. Thing of a dwarf fortress adventure mode. (Chances mostly in favor of I'll never make it playable. But I'll learn a lot in the meantime). Except entities and the like won't be restricted to tiles.
But if you'd like to look at the source code so far. It's just a mashup of pretty much everything I've done... Except shaders and stuff.
- Attachments
-
- unnamed.love
- (9.25 KiB) Downloaded 93 times
- Zilarrezko
- Party member
- Posts: 345
- Joined: Mon Dec 10, 2012 5:50 am
- Location: Oregon
Re: Faster way to draw rectangles?
Alright, you guys thought we were done huh? HAHA nope.
So as far as I see things, in the future I need to use spritebatches.
So I'm confused as how this works...
So... I take a texture... and I assign a whole spritebatch to that texture.
I then assign rectangles that use that texture after using the :bind and before the :unbind.
Then draw it with a draw call.
I kinda get it, and I kinda don't. I use a single spritebatch for every texture, and add the position to it of every rectangle of that texture type, then draw every spritebatch? That not only sounds like it would be iffy on rendering depth for things in front of other things if I go a semi isometric view. But sounds like it still wouldn't do as much performance wise. But then again, I don't know much how this stuff works or even would begin to understand if I looked at the source code .
yet...
However I had used canvas... and it didn't really improve performance at all. I mentioned that in my reply to Kindaro.
So as far as I see things, in the future I need to use spritebatches.
So I'm confused as how this works...
So... I take a texture... and I assign a whole spritebatch to that texture.
I then assign rectangles that use that texture after using the :bind and before the :unbind.
Then draw it with a draw call.
I kinda get it, and I kinda don't. I use a single spritebatch for every texture, and add the position to it of every rectangle of that texture type, then draw every spritebatch? That not only sounds like it would be iffy on rendering depth for things in front of other things if I go a semi isometric view. But sounds like it still wouldn't do as much performance wise. But then again, I don't know much how this stuff works or even would begin to understand if I looked at the source code .
yet...
It sounds like the more optimal solution is canvas... My game is going to be like the functionality of map and entities in... prison architect. Unless I can't get path smoothing in, then it's more like dwarf fortress.slime wrote:If the rectangles overlap a lot and they don't change positions relative to each other every frame, it will improve performance to draw them to a Canvas when they do change positions, and draw the Canvas to the main screen (and be sure to use Canvas:clear before drawing to the Canvas.)
However I had used canvas... and it didn't really improve performance at all. I mentioned that in my reply to Kindaro.
- kikito
- Inner party member
- Posts: 3153
- Joined: Sat Oct 03, 2009 5:22 pm
- Location: Madrid, Spain
- Contact:
Re: Faster way to draw rectangles?
Ok, let me try to explain better.Zilarrezko wrote:But I have no idea how to forsee a rectangle being out of the window. Other than if one rectangle is out of bounds of the (let's say first right part of the screen), then if another rectangles' x is greater than the one that's outside of the screen than don't draw it. But for me I think that's going to require the same amount of if then's to every rectangle.
Let's imagine that your "world" is a 10x10 grid, and each cell is a rectangle (a tile) that you have to draw:
Code: Select all
##########
##########
##########
##########
##########
##########
##########
##########
Code: Select all
local function drawMap(map)
for x=1,map.columns do -- 10 columns
for y=1,map.rows do -- 10 rows
drawTile(map,x,y)
end
end
end
Now imagine that your screen only "sees" a 4x3 subsection:
Code: Select all
##########
##########
##....####
##....####
##....####
##########
##########
##########
Code: Select all
local function drawMap(map,screenLeft, screenTop, screenRight, screenBottom)
for x=1,map.columns
for y=1,map.rows
if x >= screenLeft and x <= screenRight
and y >= screenTop and y <= screenBottom
then
drawTile(x,y)
end
end
end
Now compare that implementation to this:
Code: Select all
local function drawMap(map,screenLeft, screenTop, screenRight, screenBottom)
for x=screenLeft,screenTop
for y=screenRight,screenBottom
drawTile(x,y)
end
end
end
I hope this clarifies things a bit.
When I write def I mean function.
- Zilarrezko
- Party member
- Posts: 345
- Joined: Mon Dec 10, 2012 5:50 am
- Location: Oregon
Re: Faster way to draw rectangles?
Alright, It does a bit. The problem was with camera, but actually now that I think about it, that's pretty easy to implement, do some pluses of some translations, some division magic here and there and then widen the tolerance to allow drawing of rectangles if they would be in the screen even if their x and/or y isn't on screen, but a part of them is.
However, I'd like, at least right now, while I'm testing somethings to zoom out pretty far, to hardcore test pathfinding, path smoothing... just path stuff ya know? So I'd like to zoom almost all the way out, and be able right click (path find to a tile) and not wait 7 millennium and 15 tiberium wars and 2 Kane lifetimes to then see the path.
something like a huge rooms map, or a map from an actual game.
Although, eventually I'd like to limit zooming out. But I have in mind some cases in the future where I'd like users to zoom out enough and not lag out, see what I'm sayin'?
Thanks for helpin' kikito, still helping me since my OOP problem post.
And in that last post I forgot to put in my project if people wanted to see what I have so far, except this is waaaayy too abstract to get an idea of what it's going to be. The "agent" (Is this what we call entities with AI capabilities?) will eventually move independently from the grid (I've said this about 12 times, and I'm sorry.). Although maybe not, depending if I can implement it or not.
So control are like f1 to make a pseudo rooms test thing (So hard to make something good with those 1 and 0 maps, I hate those.) f2 to make like a spiral thing. f3 to designate everything to be demolished. f5 to change heuristic. w a s d to move camera, scroll wheel to zoom, and uh... left click to construct/destruct a wall, and right click to move to that point.
However, I'd like, at least right now, while I'm testing somethings to zoom out pretty far, to hardcore test pathfinding, path smoothing... just path stuff ya know? So I'd like to zoom almost all the way out, and be able right click (path find to a tile) and not wait 7 millennium and 15 tiberium wars and 2 Kane lifetimes to then see the path.
something like a huge rooms map, or a map from an actual game.
Although, eventually I'd like to limit zooming out. But I have in mind some cases in the future where I'd like users to zoom out enough and not lag out, see what I'm sayin'?
Thanks for helpin' kikito, still helping me since my OOP problem post.
And in that last post I forgot to put in my project if people wanted to see what I have so far, except this is waaaayy too abstract to get an idea of what it's going to be. The "agent" (Is this what we call entities with AI capabilities?) will eventually move independently from the grid (I've said this about 12 times, and I'm sorry.). Although maybe not, depending if I can implement it or not.
So control are like f1 to make a pseudo rooms test thing (So hard to make something good with those 1 and 0 maps, I hate those.) f2 to make like a spiral thing. f3 to designate everything to be demolished. f5 to change heuristic. w a s d to move camera, scroll wheel to zoom, and uh... left click to construct/destruct a wall, and right click to move to that point.
- Attachments
-
- nameless.love
- (204.43 KiB) Downloaded 108 times
Who is online
Users browsing this forum: No registered users and 48 guests