Page 1 of 1

Strange color behavior using rectangle() and a scaled canvas

Posted: Fri Feb 16, 2024 5:11 pm
by CrypticWombat
Hello!

I think I might have found a bug, and I was hoping I could get a sanity check before trying to post a bug report about it. I'm very new to love, and I am well aware that this could just be an issue with my code.

Anyways, here's what I'm observing:

I'm trying to draw to a canvas (84x48 pixels), which then gets scaled up to the actual screen size (which, for now is just the canvas size multiplied by 8). I'll attach a full .love file of my program, but here's my draw() function:

Code: Select all

function love.draw()
    --Draw to the canvas
    love.graphics.setCanvas(canvas)
        love.graphics.clear()
        love.graphics.setColor(colorDark[1], colorDark[2], colorDark[3])
        love.graphics.rectangle("fill", 0, 0, canvasWidth, canvasHeight)
        --love.graphics.setColor(colorLight[1], colorLight[2], colorLight[3])
        --love.graphics.rectangle("fill",44,0,44,48)
    
    --Point back to the main draw area (i.e. not at the canvas)
    love.graphics.setCanvas()

    --Draw the scaled canvas to the screen
    love.graphics.draw(canvas, 0, 0, 0, scaleFactor, scaleFactor)
end
In my load() function, I've defined two colors:

Code: Select all

    --Color definitions for 2 color palette
    colorLight = {199/255, 240/255, 216/255} --#c7f0d8
    colorDark = {67/255, 82/255, 61/255} --#43523d
Here's how these should look:
Image

And, here's how the screen is rendered, when the code in my .love file is ran as-is:
Image

The green displayed here is darker than the "colorDark" green I've defined. Yet, it does appear to be a dark green - not black. Odd.

Okay, here's what really throws me for a loop. When I un-comment the first of the commented out lines in my draw loop:

Code: Select all

function love.draw()
    --Draw to the canvas
    love.graphics.setCanvas(canvas)
        love.graphics.clear()
        love.graphics.setColor(colorDark[1], colorDark[2], colorDark[3])
        love.graphics.rectangle("fill", 0, 0, canvasWidth, canvasHeight)
        love.graphics.setColor(colorLight[1], colorLight[2], colorLight[3])  -- Now un-commented
        --love.graphics.rectangle("fill",44,0,44,48)
    
    --Point back to the main draw area (i.e. not at the canvas)
    love.graphics.setCanvas()

    --Draw the scaled canvas to the screen
    love.graphics.draw(canvas, 0, 0, 0, scaleFactor, scaleFactor)
end
This is the result:
Image

This is the dark green I was looking for - but it only renders correctly when I've set a different color after the rectangle has already been drawn. And, with the clear() and the original setColor() occuring earlier in the draw loop than the rectangle() call, I really don't see how setting the color in this (now un-commented) line should have any effect.

Un-commenting out that final line, to then draw a new rectangle on the right half of the screen (using the light green color), this is the result:
Image

Looks good - exactly as I would have expected. I could just move on at this point, as of course I do plan on drawing more than just one rectangle to the screen. But, I can't get over the fact that the original rectangle is drawn in a color darker than what I'd defined. If anyone is able to explain what's going on, here, I'd really appreciate it!

Since I pulled that reference image palette from a game jam page, I figure I mind as well give credit and link to it here:

https://itch.io/jam/nokiajam6

I have no affiliation with this site, other than the fact that I'm considering attempting an entry.

My appologies if this question has already been covered elsewhere. I did some searching within this forum, the wiki, as well as the bug report section for love on github. I wasn't able to find anything relevant, but I'll admit it's possible that something is there and I just wasn't able to find it (using the wrong search criteria, not digging far enough back, etc.). At any rate, I gave it an earnest effort before drafting this post.

Re: Strange color behavior using rectangle() and a scaled canvas

Posted: Fri Feb 16, 2024 5:38 pm
by slime
setColor persists forever - even across frames - until the next setColor call, and all draws (including when you draw a canvas) are affected by the active color. You probably want to use a white color when drawing the canvas to the screen since it's already had colors applied to it.

Re: Strange color behavior using rectangle() and a scaled canvas

Posted: Fri Feb 16, 2024 6:44 pm
by CrypticWombat
Interesting - thank you!

Yes, when I set the color (to white) immediately before drawing the canvas to the screen (at the end of the draw loop), it corrects the issue I was having.

As in:

Code: Select all

    love.graphics.setColor(1, 1, 1) --new line
    love.graphics.draw(canvas, 0, 0, 0, scaleFactor, scaleFactor)
So, is there some sort of alpha/transparency functionality going on with love.graphics.draw(), when drawing a canvas? I would have thought that it would take the contents of the canvas and draw to the screen (fully opaque) without altering them in any way. But, when I replace the set color arguments here with (0, 0, 0) for black, instead of white, the whole screen displays as black.

I'd tried to account for something like this previously by setting the colorMode to replace, but it didn't work out how I had hoped it might.

Anyways - this works, and gives me a bit of peace of mind. Thank you again. I really appreciate the help!

Edit: The result now looks like this:
Image

Different than what I was seeing previously. But, this is how it should actually look, I believe. I think previously it looked close to right, since it was getting filtered through the light green color - which, being reasonably close to white, didn't alter the output substantially enough for me to notice.

Edit2:
When I said colorMode, I think I meant blendMode

Re: Strange color behavior using rectangle() and a scaled canvas

Posted: Fri Feb 16, 2024 8:23 pm
by dusoft
Also, instead of division by 255 you can use
https://love2d.org/wiki/love.math.colorFromBytes

Re: Strange color behavior using rectangle() and a scaled canvas

Posted: Fri Feb 16, 2024 8:57 pm
by CrypticWombat
Ah - very cool! Much appreciated

Re: Strange color behavior using rectangle() and a scaled canvas

Posted: Fri Feb 16, 2024 9:33 pm
by slime
CrypticWombat wrote: Fri Feb 16, 2024 6:44 pm So, is there some sort of alpha/transparency functionality going on with love.graphics.draw(), when drawing a canvas? I would have thought that it would take the contents of the canvas and draw to the screen (fully opaque) without altering them in any way. But, when I replace the set color arguments here with (0, 0, 0) for black, instead of white, the whole screen displays as black.
When you draw anything, the active color is multiplied with it to produce a final result. So setting the active color to (0, 0, 0) will multiply the thing's colors by 0, which produces black.

Re: Strange color behavior using rectangle() and a scaled canvas

Posted: Fri Feb 16, 2024 9:59 pm
by CrypticWombat
slime wrote: Fri Feb 16, 2024 9:33 pm When you draw anything, the active color is multiplied with it to produce a final result. So setting the active color to (0, 0, 0) will multiply the thing's colors by 0, which produces black.
That is definitely consistent with the behavior I've observed!

Thank you for the info - that resolves the source of my confusion.