Canvas PixelFormat uses rgba4 instead of rgba8
Creating a canvas uses rgb4 by default instead of rgb8 as specified by the wiki. If you try to force it to create a Canvas using rgba8, it returns the following error:
The rgba8 canvas format is not supported by your graphics drivers.
Weirdly enough, srgba8, the gamma-correct version of rgba8, seems to be supported. Although this is not supported by all graphics cards so it's not a workaround that will work for everything.
This is mentioned by #55.
Workaround
This workaround seems to work for me for now. srgba8 seems to be supported by love.js on most devices. Even though I didn't see any noticeable changes, please note that srgba8 is supposed to change the colors rendered on screen.
EDIT: This will not work in LÖVE 12.
local old_newCanvas = love.graphics.newCanvas
function love.graphics.newCanvas(width, height, settings)
settings = settings or {}
if not settings.format then
-- Fallback chain for supported Canvas formats
local supportedCanvasFormats = love.graphics.getCanvasFormats()
local fallbackChain = {
-- It's possible to include other formats if necessary, as long as they have 4 components:
-- https://love2d.org/wiki/PixelFormat
-- I don't know much about the specifics of these formats, please adapt to what works best for you.
-- Note that this does not take into account if `t.gammacorrect = true` is set in `love.conf`, please implement it yourself if needed.
"rgba8",
"srgba8",
"rgb10a2",
"rgb5a1",
"rgba4",
"normal"
}
local format = fallbackChain[1]
local i = 1
while i <= #fallbackChain and not supportedCanvasFormats[format] do
i = i + 1
format = fallbackChain[i]
end
if i == #fallbackChain + 1 then
error("No valid canvas format is supported by the system")
end
settings.format = format
end
return old_newCanvas(width, height, settings)
end
Examples
- This page creates a Canvas with a normal format, then reads and displays its format : https://yolwoocle.com/love2dtest/test1/index.html
Source code:
function love.conf(t)
t.window.width = 1200
t.window.height = 800
end
local image = love.graphics.newImage("parrot.jpg")
local canvas = love.graphics.newCanvas(600, 600, {
format = "normal",
})
local a = 0.0
function love.update(dt)
a = a + dt
end
function love.draw()
love.graphics.setCanvas(canvas)
love.graphics.clear(0, 0, 0, 1)
love.graphics.draw(image, math.cos(a) * 30, math.sin(a) * 30)
love.graphics.setCanvas()
love.graphics.clear(0, 0, 0, 1)
love.graphics.draw(canvas, 0, 0)
love.graphics.print(tostring(canvas:getFormat()), 40, 40)
end
- This page creates a Canvas with a normal format, and a second Canvas using rbga8, which causes the error mentioned above: https://yolwoocle.com/love2dtest/test2/index.html
Source code:
function love.conf(t)
t.window.width = 1200
t.window.height = 800
end
local image = love.graphics.newImage("parrot.jpg")
local canvas = love.graphics.newCanvas(600, 600, {
format = "normal",
})
local canvas2 = love.graphics.newCanvas(600, 600, {
format = "srgba8",
})
local a = 0.0
function love.update(dt)
a = a + dt
end
function love.draw()
love.graphics.setCanvas(canvas)
love.graphics.clear(0, 0, 0, 1)
love.graphics.draw(image, math.cos(a) * 30, math.sin(a) * 30)
love.graphics.setCanvas()
love.graphics.setCanvas(canvas2)
love.graphics.clear(0, 0, 0, 1)
love.graphics.draw(image, math.cos(a) * 30, math.sin(a) * 30)
love.graphics.setCanvas()
love.graphics.clear(0, 0, 0, 1)
love.graphics.draw(canvas, 0, 0)
love.graphics.draw(canvas2, 600, 0)
love.graphics.print(tostring(canvas:getFormat()), 40, 40)
love.graphics.print(tostring(canvas2:getFormat()), 640, 40)
end
It's possible to see what formats are supported using this snippet of code in love.draw:
local y = 0
local canvasformats = love.graphics.getCanvasFormats()
for formatname, formatsupported in pairs(canvasformats) do
local str = string.format("Supports format '%s': %s", formatname, tostring(formatsupported))
love.graphics.print(str, 10, y)
y = y + 20
end
The image I'm using:
So that's why my canvas was looking weird... I was drawing a background to a very small canvas
Here it says no support for rgba8 for canvases, but there is for images https://davidobot.net/lovejs/features_c/
It seems the default canvas is set to rgba4 too. Colors aren't showing up the same in the love.js port, they're slightly muted.