Page 1 of 3

is there a way to draw a part of a image inside a function?

Posted: Thu Mar 01, 2018 3:45 am
by Shadowblitz16
is there a way to draw part of a image without quads?

quads say they take alot of resources if drawn every frame
I am looking for something that would work for this..

Code: Select all

function drawTile(texture, i, x, y, w=8, h=8, sx=1, sy=1, ox=0, oy=0)
    local quadX = math.floor(i % (texture:getWidth() / w) % texture:getWidth())
    local quadY = math.floor(i / (texture:getWidth() / w) % texture:getHeight())
    local quad = love.graphics.newQuad(quadX,quadY,w,h)
    love.graphics.draw(texture, quad, x, y, 0, sx, sy, ox, oy)
end

Re: is there a way to draw a part of a image inside a function?

Posted: Thu Mar 01, 2018 5:53 am
by raidho36
Quads take very little resources as long as you don't create them every single frame, keeping existing ones instead. In fact, when you draw the whole image, it does the same thing except it uses a pre-programmed full-sized quad.

Re: is there a way to draw a part of a image inside a function?

Posted: Thu Mar 01, 2018 10:41 am
by pgimeno
This is the kind of misunderstanding I tried to prevent. Seems like I was late.

The slow function is love.graphics.newQuad, but you don't need to do that every time you want to draw a quad; instead you typically keep all quads for a spritesheet in a table and invoke the quad that you need to draw. Using them like that is fast.

Re: is there a way to draw a part of a image inside a function?

Posted: Thu Mar 01, 2018 8:15 pm
by Shadowblitz16
well I kinda wanted to encapsulate the quad in the function.
I don't want to have to make a quad but allow the function to do that for me.

is there a way to do something like this with shaders maybe?

Re: is there a way to draw a part of a image inside a function?

Posted: Thu Mar 01, 2018 8:19 pm
by zorg
To be honest it shouldn't bother you if you have one or more pre-made quads that you use for these kinds of purposes. You could put them in one table so that they're not all over the place, but that still should be fine.

If you're that concerned, you could have a QuadPool thing, which is basically the same i said, just with a fancy name. :P

Re: is there a way to draw a part of a image inside a function?

Posted: Thu Mar 01, 2018 11:10 pm
by Shadowblitz16
it just kinda seems odd that there is no way to draw a image from a source rect
I would think it would be faster and take up less memory.

Re: is there a way to draw a part of a image inside a function?

Posted: Thu Mar 01, 2018 11:14 pm
by grump
But there is... by using a quad. What else do you need?

Re: is there a way to draw a part of a image inside a function?

Posted: Fri Mar 02, 2018 1:18 am
by pgimeno
Most of the time, one just needs to draw fixed rectangles from a texture. It's a very uncommon operation to draw a variable rectangle from a texture. If you need to draw just one such quad, you can probably use newQuad every frame (not tested - YMMV), but if you need to do that multiple times, maybe you can use a shader instead.

Edit: I get 880 FPS with this program. I'm curious as to what performance others see.

Code: Select all

local img
local lg = love.graphics
local t = {}

function love.load()
  img = love.graphics.newImage("image1.jpg")
  img:setWrap("repeat", "repeat")

  love.window.setMode(640,480, {vsync=false})
  lg.setDefaultFilter("nearest","nearest")

  for i = 1, 12 do
    local tt = {}
    tt.x = love.math.random(0, 639)
    tt.y = love.math.random(0, 479)
    tt.vx = love.math.random() * 150 - 75
    tt.vy = love.math.random() * 150 - 75
    t[i] = tt
  end
end

function love.update(dt)
  for i = 1, 12 do
    local tt = t[i]
    tt.x = (tt.x + tt.vx * dt) % 640
    tt.y = (tt.y + tt.vy * dt) % 480
  end
end

function love.draw()
  i = 1
  for y = 0, 479, 160 do
    for x = 0, 639, 160 do
      lg.draw(img, lg.newQuad(t[i].x, t[i].y, 160, 160, 640, 480), x, y)
      i = i + 1
    end
  end

  lg.print(string.format("FPS=%d mem=%d",love.timer.getFPS(), collectgarbage("count")))
end

function love.keypressed(k)
  if k == "escape" then love.event.quit() end
end

Re: is there a way to draw a part of a image inside a function?

Posted: Fri Mar 02, 2018 2:14 am
by Shadowblitz16
@grump well drawing directly from the texture would probably be faster and take up less memory, C# allows this.
@pgimeno it actually is alot faster then I thought it would be.

Re: is there a way to draw a part of a image inside a function?

Posted: Fri Mar 02, 2018 5:00 am
by raidho36
You can't just directly draw a texture. You need a mesh that a texture is applied to. Quad is such mesh that's to-go mesh to render a sprite. Whenever you draw anything without specifying mesh, a default one is used, and that's all the same.

See, that's the problem with people starting leanring programming with anything other than C or assembly. They don't understand how computers work and think you can pull off some magic tricks using special know-how. Well, big reveal: there's no magic involved, a computer only does what you tell it to do, and unless your command was perfectly valid and fully-fledged, it will screw it up or won't do it at all. The best you can hope for is that some middle-ware will fill in the blanks and that whatever it was defaulting to was good enough for your application.