Weird pixel glitch

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
milon
Party member
Posts: 472
Joined: Thu Jan 18, 2018 9:14 pm

Weird pixel glitch

Post by milon »

I just ran into a weird pixel glitch that I can't figure out. Maybe someone here can shed some light on this?

Here's the code to reproduce the problem:

Code: Select all

function love.load()
    
    -- initialize canvas
    local locations = 20
    width, height = 200, 200
    canvas = love.graphics.newCanvas(width, height)
    love.graphics.setCanvas(canvas)
    for x = 1, width do
        for y = 1, height do
            love.graphics.setColor(0.7, 0.7, 0.7)
            love.graphics.points(x, y)
        end
    end
    love.graphics.setCanvas()
    
    -- randomize locations
    towns = {}
    for i = 1, locations do
        towns[i] = {x=love.math.random(2, width-1), y=love.math.random(2, height-1)}
    end
    
    -- set player to a random location
    local i = love.math.random(1, #towns)
    player = {x=towns[i].x, y=towns[i].y}
end

function love.draw()
    
    -- reset graphics
    love.graphics.setColor(1, 1, 1)
    
    -- draw canvas
    love.graphics.draw(canvas, 1, 1)
    
    -- draw player
    love.graphics.setColor(1, 1, 1)
    love.graphics.rectangle("fill", player.x - 1, player.y - 1, 3, 3)
    
    -- draw towns
    love.graphics.setColor(0, 0, 0)
    for i = 1, #towns do
        love.graphics.points(towns[i].x, towns[i].y) -- This SHOULD be correct
        --~ love.graphics.points(towns[i].x+1, towns[i].y) -- This works on my Home PC
        --~ love.graphics.points(towns[i].x, towns[i].y+1) -- This works on my Work PC
    end
end
This is already pretty simple, but you can comment out the Canvas stuff and the bug still happens. I ran into this when trying to draw a world minimap with player and towns noted on it. The world map is a canvas, the player is a rectangle (3x3 square), and the towns are single pixels.

The problem is that the town pixels are misaligned. On my home PC, they get shifted to the left 1 pixel. On my work PC, they're shifted up 1 pixel. Both computers are Linux Mint XFCE with all updates installed, and both are running Love 11.3. The hardware is different between them, which shouldn't matter.

Does anyone else get a weird pixel shift? Is there something in my code that I'm not seeing? Is this a Love bug, or is it more likely to be a driver issue? I've attached screenshots of what I'm seeing in case that's helpful.
Attachments
WorkPC.png
WorkPC.png (107.04 KiB) Viewed 3894 times
HomePC.png
HomePC.png (151.92 KiB) Viewed 3894 times
Any code samples/ideas by me should be considered Public Domain (no attribution needed) license unless otherwise stated.
grump
Party member
Posts: 947
Joined: Sat Jul 22, 2017 7:43 pm

Re: Weird pixel glitch

Post by grump »

Add .5 to coordinates of lines and points. Some primitives have to be aligned at the center of pixels to render correctly, while others have to be aligned at integer coordinates. I have no explanation for the weirdness, it just is.
User avatar
zorg
Party member
Posts: 3444
Joined: Thu Dec 13, 2012 2:55 pm
Location: Absurdistan, Hungary
Contact:

Re: Weird pixel glitch

Post by zorg »

Hardware and/or Drivers, otherwise OpenGL is jank.
Me and my stuff :3True Neutral Aspirant. Why, yes, i do indeed enjoy sarcastically correcting others when they make the most blatant of spelling mistakes. No bullying or trolling the innocent tho.
User avatar
pgimeno
Party member
Posts: 3550
Joined: Sun Oct 18, 2015 2:58 pm

Re: Weird pixel glitch

Post by pgimeno »

Apart from what grump said, I advise you to use love.graphics.clear(0.7, 0.7, 0.7) to clear the canvas, instead of filling all 40,000 pixels of it.

Also, I'd suggest to make them 1x1 rectangles instead of points. That way, they will work in Android, for example. If you do that, use integer coordinates, don't add 0.5.

As for the weirdness that grump talks about, there's an explanation, but it could be a bit long. The short version is that the borders of filled rectangles are conceptually infinitely thin, so they must go in integer coordinates, which are located between pixels; points, on the other hand, are conceptually 1x1 rectangles with the hook in the middle of them, so you need to add 0.5 to each coordinate in order to place them in the centre of the destination pixel, and if you place them at an integer coordinate, rounding could go either way. That goes for lines and line rectangles as well, except they are influenced by the current line width.
User avatar
milon
Party member
Posts: 472
Joined: Thu Jan 18, 2018 9:14 pm

Re: Weird pixel glitch

Post by milon »

Thanks all! I vaguely remember reading something about that a long time ago, and had totally forgotten it.

@pgimeno, thanks for the elaboration. That's helpful. I'm not specifically targetting Android, but I'd like to have the option open. I'll keep it in mind.
Any code samples/ideas by me should be considered Public Domain (no attribution needed) license unless otherwise stated.
Post Reply

Who is online

Users browsing this forum: Google [Bot], steVeRoll and 193 guests