Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Canvas PixelFormat uses rgba4 instead of rgba8 #92

Open
Yolwoocle opened this issue May 12, 2024 · 2 comments
Open

Canvas PixelFormat uses rgba4 instead of rgba8 #92

Yolwoocle opened this issue May 12, 2024 · 2 comments

Comments

@Yolwoocle
Copy link

Yolwoocle commented May 12, 2024

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. Weirdly enough, srgba8, which is gamma corrected rgba8, seems to be supported by love.js on most devices, but rgba8 isn't. Even though I didn't see any noticeable changes, but please note that srgba8 is supposed to change the colors rendered on screen.

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

image

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

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:
parrot

@ChicknTurtle
Copy link

ChicknTurtle commented May 15, 2024

So that's why my canvas was looking weird... I was drawing a background to a very small canvas

@ChicknTurtle
Copy link

Here it says no support for rgba8 for canvases, but there is for images
https://davidobot.net/lovejs/features_c/

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants