[SOLVED] push.lua and love.graphics.newQuad problem

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
Bondrusiek
Prole
Posts: 24
Joined: Sun Dec 03, 2023 2:49 pm

[SOLVED] push.lua and love.graphics.newQuad problem

Post by Bondrusiek »

Hello everyone!
I write this post because I have a problem with push.lua and love.graphics.newQuad. I know that here are many love2d experts and maybe someone can help me. Ok so I've done a app:

Code: Select all

push = require 'push'

virtualWidth = 33 * 16
virtualHeight = 28 * 16

windowWidth = 33 * 16
windowHeight = 28 * 16

mode = 1

function generateQuads(atlas, tilewidth, tileheight)
    local sheetWidth = atlas:getWidth() / tilewidth
    local sheetHeight = atlas:getHeight() / tileheight

    local sheetCounter = 1
    local quads = {}

    for y = 0, sheetHeight - 1 do
        for x = 0, sheetWidth - 1 do
            -- this quad represents a square cutout of our atlas that we can
            -- individually draw instead of the whole atlas
            quads[sheetCounter] =
                love.graphics.newQuad(x * tilewidth, y * tileheight, tilewidth,
                tileheight, atlas:getDimensions())
            sheetCounter = sheetCounter + 1
        end
    end

    return quads
end

function love.load()
    spriteSheets = love.graphics.newImage("tiles.png")
    tilesSprite = generateQuads(spriteSheets, 16, 16)
    love.window.setMode(33*16, 28*16)

    love.graphics.setDefaultFilter('nearest', 'nearest')
    love.window.setTitle("With push")
    -- sets up virtual screen resolution for an authentic retro feel
    if mode == 1 then 
        push:setupScreen(virtualWidth, virtualHeight, windowWidth, windowHeight, {
            fullscreen = false,
            resizable = false
        })
    end
end

-- called whenever window is resized
function love.resize(w, h)
    if mode == 1 then
        push:resize(w, h)
    end
end

function love.update(dt) 

end

function love.draw()
    if mode == 0 then
        love.graphics.clear(255, 255, 255)
        local index = 1
        for x = 1, 33 do
            for y = 1, 28 do 
                love.graphics.draw(spriteSheets, tilesSprite[index], (y - 1) * 16, (x - 1) * 16)
                index = index + 1
            end
        end
    end
    if mode == 1 then
        -- begin virtual resolution drawing
        push:apply('start')

        -- clear screen using Mario background blue
        love.graphics.clear(108, 140, 255, 255)
        local index = 1
        for x = 1, 33 do
            for y = 1, 28 do 
                love.graphics.draw(spriteSheets, tilesSprite[index], (y - 1) * 16, (x - 1) * 16)
                index = index + 1
            end
        end
        
        push:apply('end')
    end
end
Where you can use mode to control app. With mode equals 1 app runs with push otherwise without it. Result
example.png
example.png (848.16 KiB) Viewed 2530 times
As you can see, there is a 1-pixel border at the edge of the tile and I don't know how to get rid of it. This is actually the most important part of this thread. You know how to get rid of this border. You can see it better when you scale it up, but to compare it with the version without push, I used such a low resolution.
Addons:
push.lua : https://github.com/Ulydev/push/blob/master/push.lua
tiles.png:
tiles.png
tiles.png (35.55 KiB) Viewed 2530 times
Last edited by Bondrusiek on Mon May 20, 2024 9:22 am, edited 1 time in total.
User avatar
pgimeno
Party member
Posts: 3672
Joined: Sun Oct 18, 2015 2:58 pm

Re: push.lua and love.graphics.newQuad problem

Post by pgimeno »

[Edited to avoid confusion to possible future readers]

The images with push use a linear filter, while the images without push use a nearest filter. With the nearest linear filter the adjacent tiles can bleed into the current tile. Changing to linear nearest should solve it, if that's acceptable for your project. Otherwise, you'll need to fix your tileset by separating the tiles by at least one pixel.
Last edited by pgimeno on Mon May 20, 2024 10:42 am, edited 1 time in total.
Bondrusiek
Prole
Posts: 24
Joined: Sun Dec 03, 2023 2:49 pm

Re: push.lua and love.graphics.newQuad problem

Post by Bondrusiek »

Thanks for a reply. I used a linear filter

Code: Select all

love.graphics.setDefaultFilter('linear', 'linear')
but bug still exists. Moreover I created a test tiles with 17px x 17px(1px for a gap) then I used

Code: Select all

spriteSheets = love.graphics.newImage("upgrade_tiles.png")
tilesSprite = generateQuads(spriteSheets, 17, 17)
and I draw it using:

Code: Select all

        for x = 1, 27 do
            for y = 1, 2 do 
                love.graphics.draw(spriteSheets, tilesSprite[index], (y - 1) * 16, (x - 1) * 16)
                index = index + 1
            end
        end
unfortunately the border bug still exists. Maybe the push library is broken in this area.
Tested png:
upgrade_tiles.png
upgrade_tiles.png (2.08 KiB) Viewed 2397 times
Imnotaplayer
Prole
Posts: 2
Joined: Thu Dec 15, 2022 6:31 pm

Re: push.lua and love.graphics.newQuad problem

Post by Imnotaplayer »

Code: Select all

function love.load()
    spriteSheets = love.graphics.newImage("tiles.png")
    tilesSprite = generateQuads(spriteSheets, 16, 16)
    love.window.setMode(33*16, 28*16)

    love.graphics.setDefaultFilter('nearest', 'nearest')
    -- ...
end
You should call love.graphics.setDefaultFilter() before creating any images. It does not retroactively apply to images that have already been created. I would think "nearest" would work fine here and that "linear" is what's causing what you see. (In the images you provided, they can still be seen using a linear filter)

I think another problem here is that the quads you are creating border other tiles in the atlas. Having a 1 pixel gap would fix this but you create the quads as 17x17, so they will still border other tiles. You can use an additional set of values to indicate the actual size of the tile.

Code: Select all

function generateQuads(atlas, tilewidth, tileheight, sourcewidth, sourceheight)
    -- ...
    for y = 0, sheetHeight - 1 do
        for x = 0, sheetWidth - 1 do
            quads[sheetCounter] =
                love.graphics.newQuad(x * tilewidth, y * tileheight,
                sourcewidth, sourceheight, atlas:getDimensions())
        end
    end
    -- ...
end

-- ...

generateQuads(spriteSheets, 17, 17, 16, 16)
User avatar
pgimeno
Party member
Posts: 3672
Joined: Sun Oct 18, 2015 2:58 pm

Re: push.lua and love.graphics.newQuad problem

Post by pgimeno »

pgimeno wrote: Fri May 17, 2024 4:15 pm The images with push use a linear filter, while the images without push use a nearest filter. With the nearest filter the adjacent tiles can bleed into the current tile. Changing to linear should solve it, if that's acceptable for your project. Otherwise, you'll need to fix your tileset by separating the tiles by at least one pixel.
Bondrusiek wrote: Sat May 18, 2024 9:48 am Thanks for a reply. I used a linear filter

Code: Select all

love.graphics.setDefaultFilter('linear', 'linear')
but bug still exists. Moreover I created a test tiles with 17px x 17px(1px for a gap) then I used

Code: Select all

spriteSheets = love.graphics.newImage("upgrade_tiles.png")
tilesSprite = generateQuads(spriteSheets, 17, 17)
and I draw it using:

Code: Select all

        for x = 1, 27 do
            for y = 1, 2 do 
                love.graphics.draw(spriteSheets, tilesSprite[index], (y - 1) * 16, (x - 1) * 16)
                index = index + 1
            end
        end
unfortunately the border bug still exists. Maybe the push library is broken in this area.
Tested png: upgrade_tiles.png
What I said was completely reversed :ultrashocked:

I'm very sorry. Let me rewrite it.

The images with push use a linear filter, while the images without push use a nearest filter. With the linear filter the adjacent tiles can bleed into the current tile. Changing to nearest should solve it, if that's acceptable for your project. Otherwise, you'll need to fix your tileset by separating the tiles by at least one pixel.

In short, what Imnotaplayer said.
Bondrusiek
Prole
Posts: 24
Joined: Sun Dec 03, 2023 2:49 pm

Re: push.lua and love.graphics.newQuad problem

Post by Bondrusiek »

Imnotaplayer wrote: Sat May 18, 2024 1:33 pm You should call love.graphics.setDefaultFilter() before creating any images. It does not retroactively apply to images that have already been created. I would think "nearest" would work fine here and that "linear" is what's causing what you see. (In the images you provided, they can still be seen using a linear filter)
Now it works. I used love.graphics.setDefaultFilter('nearest', 'nearest') before creating any images. Lesson from this thread is love.graphics.setDefaultFilter does not retroactively apply to images that have already been created. Thanks Imnotaplayer and pgimeno for help.
Post Reply

Who is online

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