[SOLVED] love.graphics.stencil problem

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
siberian
Prole
Posts: 23
Joined: Sat Apr 06, 2019 1:42 pm

[SOLVED] love.graphics.stencil problem

Post by siberian »

Hello everyone.
I used two calls love.graphics.stencil() function in my program.

Code: Select all

local function stencil_test()
    lg.circle('fill', cx, cy, radius)
end

function love.draw()
    local w, h = lg.getDimensions()
    lg.setCanvas({canvas, stencil = true})
    lg.clear(0.2, 0.2, 0.2)
    
    cx, cy, radius = w/2, h/2, 200
    lg.stencil(stencil_test, 'increment')
    
    cx, cy, radius = w/2, h/2, 50
    lg.stencil(stencil_test, 'decrement')
    --lg.stencil(stencil_test, 'decrementwrap')
    
    lg.setColor(1, 1, 1)
    lg.setStencilTest('greater', 0)
    lg.rectangle('fill', 0, 0, lg.getDimensions())
    lg.setStencilTest()
    
    lg.setCanvas()
    
    lg.draw(canvas)
end
I expected a circle with a hole to appear on the screen. But there is nothing.
If replace 'decrement" with "decrementwrap", only a smaller circle is visible.

Does calling love.graphics.stencil reset stencil buffer? It looks like this.
Attachments
main.lua
(914 Bytes) Downloaded 93 times
Last edited by siberian on Wed Jul 27, 2022 2:40 am, edited 1 time in total.
User avatar
marclurr
Party member
Posts: 158
Joined: Fri Apr 22, 2022 9:25 am

Re: love.graphics.stencil problem

Post by marclurr »

Must admit I've not used stencils before, and I'm not really sure why yours doesn't work without messing about some more, but the below does render a circle with a "hole" in the centre using a stencil. Hope it puts you on the right track.

Code: Select all

local mx = love.graphics.getWidth() / 2
local my = love.graphics.getHeight() /2

local function drawStencil()
    love.graphics.circle("fill", mx, my, 50)
end

function love.draw()
    love.graphics.clear()
    
    love.graphics.stencil(drawStencil, "replace", 1)
    
    love.graphics.setStencilTest("less",1)
    love.graphics.circle("fill", mx, my, 100)
    love.graphics.setStencilTest()
end
Edit: It looks like there's an example on the wiki which is nearly identical to my suggestion, scroll to the second example on this page: https://love2d.org/wiki/love.graphics.setStencilTest
User avatar
siberian
Prole
Posts: 23
Joined: Sat Apr 06, 2019 1:42 pm

Re: love.graphics.stencil problem

Post by siberian »

I have seen this example.
I don't really need a circle with a hole in it. I ran into a problem when I was making shadows in 3d. And for that you need to draw the shadow volume twice in the stencil with different StencilAction.
User avatar
marclurr
Party member
Posts: 158
Joined: Fri Apr 22, 2022 9:25 am

Re: love.graphics.stencil problem

Post by marclurr »

Ah I see what you mean. It seems you were just missing a boolean parameter to love.graphics.stencil. By default it clears the current stencil buffer. This new example does the same thing but using two draws to the stencil. The only difference is the boolean true on the second call.

Code: Select all

local mx = love.graphics.getWidth() / 2
local my = love.graphics.getHeight() /2
local r = 100

local function drawStencil()
    love.graphics.circle("fill", mx, my, r)
end

function love.draw()
    love.graphics.clear()
   
    r = 100
    love.graphics.stencil(drawStencil, "increment", 1)
    
    r = 50
    love.graphics.stencil(drawStencil, "decrement", 1, true)
    love.graphics.setStencilTest("equal",1)

    love.graphics.rectangle("fill", 0, 0, 800, 600)
    
    
    love.graphics.setStencilTest()
end
Edit: https://love2d.org/wiki/love.graphics.stencil
User avatar
siberian
Prole
Posts: 23
Joined: Sat Apr 06, 2019 1:42 pm

Re: love.graphics.stencil problem

Post by siberian »

Thank you so much.
I can't believe I didn't notice that option.
Post Reply

Who is online

Users browsing this forum: Semrush [Bot] and 3 guests