Problem with drawing only the cubes on screen.

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
Bogdan705
Prole
Posts: 12
Joined: Sun Aug 05, 2018 9:04 pm

Problem with drawing only the cubes on screen.

Post by Bogdan705 » Thu Aug 09, 2018 1:06 pm

So I decided to optimize my game by only drawing cubes that are visible ( already been doing that, and by that I will explain in a bit ) and those that are on screen. Problem is, there are only so many cubes on the screen at a time, yet it tells me it draws around 900+ of them.
love 2018-08-08 21-34-01-166.jpg
love 2018-08-08 21-34-01-166.jpg (543.14 KiB) Viewed 212 times
When I'm zoomed in at 100% ( default zoom and above ) it's around 900+. At 200% or when I'm at the edge, around 700+. At some point, the number of drawn cubes caps at 1200+ when I zoom out enough.
Now by visible I mean cubes that should theoretically be visible from the isometric point of view. Cubes that have a neighbor to the top, left and right are "not visible". If any of those three conditions is not met, then it "is visible".
After that I use two functions I made, normalToIsoX and normalToIsoY to find out the x,y coordinates of the cube, based on its x,y,z coordinate on the grid. After that I use cam:cameraCoords() on isoX and isoY to find the cubes x,y on the screen ( I use hump.camera )
Now here is the code :

Code: Select all

t.cubeIsVisible = function(x,y,z)
  local xE = false
  local yE = false
  local zE = false
  if (x + 1) > #grid then xE = true end
  if (y + 1) > #grid[x] then yE = true end
  if (z + 1) > #grid[x][y] then zE = true end
  if xE or yE or zE then return true end
  local n = 0
  if grid[x + 1][y][z] ~= 0 then n = n + 1 end
  if grid[x][(y + 1)][z] ~= 0 then n = n + 1 end
  if grid[x][y][(z + 1)] ~= 0 then n = n + 1 end
  local screenX, screenY = cam:cameraCoords(gridFuncs.normalToIsoX(x,y),gridFuncs.normalToIsoY(x,y,z,3))
  if n == 3 then
    return false
  elseif not (((screenX < -100*zoom) or (screenX > wW + 100*zoom)) and ((screenY < -100*zoom) or (screenY > wH + 100*zoom))) then
    return true
  end
end
I have no idea what is causing this problem. Could anyone help me please? Thank you. :rofl:
kinda know enough lua to make a game, so i decided to do it, but im lazy, and aiming too high. good thing everything i make is open source :awesome: so anyone can continue my ( messy ) work

User avatar
Bogdan705
Prole
Posts: 12
Joined: Sun Aug 05, 2018 9:04 pm

Re: Problem with drawing only the cubes on screen.

Post by Bogdan705 » Thu Aug 09, 2018 1:13 pm

I realized that the edge xE,yE and zE might be making the game draw cubes on the border of the map so I decided to scrap and change the function. Now it still draws around 800+ at 100%, but only 400+ at 200%. One significant change though ( for the worse ), is that the game runs way slower now. Here is the new code :

Code: Select all

t.cubeIsVisible = function(x,y,z) -- checks if a cube is visible ( in this case covered up by other cubes )
  local screenX, screenY = cam:cameraCoords(gridFuncs.normalToIsoX(x,y),gridFuncs.normalToIsoY(x,y,z,3))
  if not (((screenX < -150) or (screenX > wW + 150)) and ((screenY < -150) or (screenY > wH + 150))) then
    local n = 0
    if gridFuncs.gridCheck(x+1,y,z,0,false) then n = n + 1 end
    if gridFuncs.gridCheck(x,y+1,z,0,false) then n = n + 1 end
    if gridFuncs.gridCheck(x,y,z+1,0,false) then n = n + 1 end
    if n == 3 then return false else return true end
  else return false end
end
And here is gridCheck()

Code: Select all

t.gridCheck = function(x,y,z,v,t) -- checks the grid for something, if search is outside the grid then it produces an error
  return pcall(function()
            if t then
              if grid[x][y][z] == v then else print(haha + ahah) end
            elseif not t then
              if grid[x][y][z] ~= v then else print(haha + ahah) end
            end end)
end
These two functions get called in another function that loops through the grid called gridDraw(), and gridDraw() in term gets called in love.draw. Also, in love.update I have this :

Code: Select all

  if camCycle >= 0.1 then
    -- zoom
    clientFuncs.camZoom()
    cam:zoomTo(zoom)
    -- get cam pos
    local x,y = cam:position()
    -- get the diff between the target pos and current pos
    local xDiff,yDiff = math.abs(isoX - x), math.abs(isoY - y)
    -- slow down if jumping or falling
    local m = 1
    if player.data.jumping or 
       gridFuncs.gridCheck(player.entity.pos.x,
                           player.entity.pos.y,
                           player.entity.pos.z - 1,0,true) then m = 0.3 end
    if xDiff < 5 then xDiff = 0 else xDiff = xDiff / (20 / (settings.camSpeed/10*player.entity.stats.speed*m)) end
    if yDiff < 5 then yDiff = 0 else yDiff = yDiff / (20 / (settings.camSpeed/10*player.entity.stats.speed*m)) end
    camCycle = 0
    -- move cam x pos
    if isoX > x then
      cam:lookAt(x + xDiff,y)
    else
      cam:lookAt(x - xDiff,y)
    end
    -- update cam pos
    local x,y = cam:position()
    -- move cam y pos
    if isoY > y then
      cam:lookAt(x,y + yDiff)
    else
      cam:lookAt(x,y - yDiff)
    end
  end
And this :

Code: Select all

camCycle = camCycle + 1*dt*settings.camSpeed
And I think I created some sort of feedback loop, and that in turn slows down the game.
kinda know enough lua to make a game, so i decided to do it, but im lazy, and aiming too high. good thing everything i make is open source :awesome: so anyone can continue my ( messy ) work

User avatar
Bogdan705
Prole
Posts: 12
Joined: Sun Aug 05, 2018 9:04 pm

Re: Problem with drawing only the cubes on screen.

Post by Bogdan705 » Thu Aug 09, 2018 1:18 pm

Nevermind I managed to make the camera run smooth again, but it still says it renders 800+ cubes. Here is a .love file
ooga.love
(505.07 KiB) Downloaded 2 times
kinda know enough lua to make a game, so i decided to do it, but im lazy, and aiming too high. good thing everything i make is open source :awesome: so anyone can continue my ( messy ) work

User avatar
Bogdan705
Prole
Posts: 12
Joined: Sun Aug 05, 2018 9:04 pm

Re: Problem with drawing only the cubes on screen.

Post by Bogdan705 » Thu Aug 09, 2018 1:40 pm

I looked at my memory usage and it says love uses 60mb. Is that a lot or not much in terms of Love2D standards ?
kinda know enough lua to make a game, so i decided to do it, but im lazy, and aiming too high. good thing everything i make is open source :awesome: so anyone can continue my ( messy ) work

User avatar
0x72
Citizen
Posts: 50
Joined: Thu Jun 18, 2015 9:02 am

Re: Problem with drawing only the cubes on screen.

Post by 0x72 » Thu Aug 09, 2018 2:13 pm

Code: Select all

 not (((screenX < -150) or (screenX > wW + 150)) and ((screenY < -150) or (screenY > wH + 150)))  
renders 1,3,5,7,9:

Code: Select all

region #5 is your viewport and everything else is not visible:

1|2|3
-+-+-
4|5|6
-+-+-
7|8|9
You want to render only 5 (viewport) so try changing and keyword to an or.

Code: Select all

 not ((screenX < -150) or (screenX > wW + 150)) or ((screenY < -150) or (screenY > wH + 150))  
or express differently:

Code: Select all

  ((-150 < screenX) and (screenX < wW + 150)) and ((-150 < screenY) and (screenY < wH + 150)) -- "inside" instead "not outside"  
Also: this solution you have iterates over all the cubes each frame. If it ever become a performance issue read about spatial hashing.
It depends on the size of your world, but I'm already not getting steady 60 with the map you have there - 20181 cubes. cubeIsVisible is responsible for more then 91% time in the gridDraw (after fixing the condition and actually rendering around 60 cubes).

Also: it looks like your coords are anchored to corners so 150 might not be perfect value: this one worked for me better:

Code: Select all

  ((-250 < screenX) and (screenX < wW)) and ((-250 < screenY) and (screenY < wH))

User avatar
Bogdan705
Prole
Posts: 12
Joined: Sun Aug 05, 2018 9:04 pm

Re: Problem with drawing only the cubes on screen.

Post by Bogdan705 » Thu Aug 09, 2018 5:29 pm

:awesome: :awesome: :awesome: Thank you a lot
kinda know enough lua to make a game, so i decided to do it, but im lazy, and aiming too high. good thing everything i make is open source :awesome: so anyone can continue my ( messy ) work

User avatar
Bogdan705
Prole
Posts: 12
Joined: Sun Aug 05, 2018 9:04 pm

Re: Problem with drawing only the cubes on screen.

Post by Bogdan705 » Thu Aug 09, 2018 5:44 pm

I will try your solution + spatial hashing + capping the framerate and see what the result is.
kinda know enough lua to make a game, so i decided to do it, but im lazy, and aiming too high. good thing everything i make is open source :awesome: so anyone can continue my ( messy ) work

pedrosgali
Citizen
Posts: 82
Joined: Wed Oct 15, 2014 5:00 pm
Location: Yorkshire, England

Re: Problem with drawing only the cubes on screen.

Post by pedrosgali » Sat Aug 11, 2018 7:27 am

I'd also suggest drawing your cubes to a canvas and checking each frame if you need to redraw it. So if the camera moves redraw but otherwise just draw the previous render to the screen. I posted an isometric map generation example on another thread on here, I'd leave a link here but I'm on my phone so you'll have to do a search if you want to download it for the code. But using the above method I got a consistent 60 fps regardless of how many tiles I needed on screen (Until I moved the camera at which point it could get a bit laggy if there were too many objects to render.) Since you have players moving you can just draw them after the canvas render.

Code: Select all

if not wearTheseGlasses() then
  chewing_on_trashcan = true
end

Post Reply

Who is online

Users browsing this forum: Google [Bot] and 6 guests