Strange color behavior using rectangle() and a scaled canvas

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
CrypticWombat
Prole
Posts: 4
Joined: Fri Feb 16, 2024 3:05 pm

Strange color behavior using rectangle() and a scaled canvas

Post 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.
Attachments
rectangles.love
(698 Bytes) Downloaded 49 times
User avatar
slime
Solid Snayke
Posts: 3162
Joined: Mon Aug 23, 2010 6:45 am
Location: Nova Scotia, Canada
Contact:

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

Post 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.
User avatar
CrypticWombat
Prole
Posts: 4
Joined: Fri Feb 16, 2024 3:05 pm

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

Post 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
User avatar
dusoft
Party member
Posts: 635
Joined: Fri Nov 08, 2013 12:07 am
Location: Europe usually
Contact:

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

Post by dusoft »

Also, instead of division by 255 you can use
https://love2d.org/wiki/love.math.colorFromBytes
User avatar
CrypticWombat
Prole
Posts: 4
Joined: Fri Feb 16, 2024 3:05 pm

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

Post by CrypticWombat »

Ah - very cool! Much appreciated
User avatar
slime
Solid Snayke
Posts: 3162
Joined: Mon Aug 23, 2010 6:45 am
Location: Nova Scotia, Canada
Contact:

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

Post 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.
User avatar
CrypticWombat
Prole
Posts: 4
Joined: Fri Feb 16, 2024 3:05 pm

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

Post 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.
Post Reply

Who is online

Users browsing this forum: Bing [Bot], Google [Bot] and 4 guests