mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-12-25 03:08:54 +01:00
internal/shader: implement a new built-in function discard
Closes #1969
This commit is contained in:
parent
2b248ef783
commit
205245b094
@ -469,6 +469,14 @@ func (cs *compileState) parseExpr(block *block, expr ast.Expr, markLocalVariable
|
|||||||
case shaderir.Texture2DF:
|
case shaderir.Texture2DF:
|
||||||
// TODO: Check arg types.
|
// TODO: Check arg types.
|
||||||
t = shaderir.Type{Main: shaderir.Vec4}
|
t = shaderir.Type{Main: shaderir.Vec4}
|
||||||
|
case shaderir.DiscardF:
|
||||||
|
if len(args) != 0 {
|
||||||
|
cs.addError(e.Pos(), fmt.Sprintf("number of %s's arguments must be 0 but %d", callee.BuiltinFunc, len(args)))
|
||||||
|
}
|
||||||
|
stmts = append(stmts, shaderir.Stmt{
|
||||||
|
Type: shaderir.Discard,
|
||||||
|
})
|
||||||
|
return nil, nil, stmts, true
|
||||||
default:
|
default:
|
||||||
// TODO: Check arg types.
|
// TODO: Check arg types.
|
||||||
// If the argument is a non-typed constant value, treat is as a float value (#1874).
|
// If the argument is a non-typed constant value, treat is as a float value (#1874).
|
||||||
|
@ -503,7 +503,7 @@ func (c *compileContext) block(p *shaderir.Program, topBlock, block *shaderir.Bl
|
|||||||
lines = append(lines, fmt.Sprintf("%sreturn %s;", idt, expr(&s.Exprs[0])))
|
lines = append(lines, fmt.Sprintf("%sreturn %s;", idt, expr(&s.Exprs[0])))
|
||||||
}
|
}
|
||||||
case shaderir.Discard:
|
case shaderir.Discard:
|
||||||
lines = append(lines, idt+"discard;")
|
lines = append(lines, idt+"discard_fragment();")
|
||||||
default:
|
default:
|
||||||
lines = append(lines, fmt.Sprintf("%s?(unexpected stmt: %d)", idt, s.Type))
|
lines = append(lines, fmt.Sprintf("%s?(unexpected stmt: %d)", idt, s.Type))
|
||||||
}
|
}
|
||||||
|
@ -265,6 +265,7 @@ const (
|
|||||||
Dfdx BuiltinFunc = "dfdx"
|
Dfdx BuiltinFunc = "dfdx"
|
||||||
Dfdy BuiltinFunc = "dfdy"
|
Dfdy BuiltinFunc = "dfdy"
|
||||||
Fwidth BuiltinFunc = "fwidth"
|
Fwidth BuiltinFunc = "fwidth"
|
||||||
|
DiscardF BuiltinFunc = "discard"
|
||||||
)
|
)
|
||||||
|
|
||||||
func ParseBuiltinFunc(str string) (BuiltinFunc, bool) {
|
func ParseBuiltinFunc(str string) (BuiltinFunc, bool) {
|
||||||
@ -317,7 +318,8 @@ func ParseBuiltinFunc(str string) (BuiltinFunc, bool) {
|
|||||||
Texture2DF,
|
Texture2DF,
|
||||||
Dfdx,
|
Dfdx,
|
||||||
Dfdy,
|
Dfdy,
|
||||||
Fwidth:
|
Fwidth,
|
||||||
|
DiscardF:
|
||||||
return BuiltinFunc(str), true
|
return BuiltinFunc(str), true
|
||||||
}
|
}
|
||||||
return "", false
|
return "", false
|
||||||
|
@ -1129,3 +1129,55 @@ func Fragment(position vec4, texCoord vec2, color vec4) vec4 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Issue #1969
|
||||||
|
func TestShaderDiscard(t *testing.T) {
|
||||||
|
const w, h = 16, 16
|
||||||
|
|
||||||
|
dst := ebiten.NewImage(w, h)
|
||||||
|
dst.Fill(color.RGBA{0xff, 0, 0, 0xff})
|
||||||
|
|
||||||
|
src := ebiten.NewImage(w, h)
|
||||||
|
pix := make([]byte, 4*w*h)
|
||||||
|
for j := 0; j < h; j++ {
|
||||||
|
for i := 0; i < w; i++ {
|
||||||
|
if i >= w/2 || j >= h/2 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
pix[4*(j*w+i)+3] = 0xff
|
||||||
|
}
|
||||||
|
}
|
||||||
|
src.WritePixels(pix)
|
||||||
|
|
||||||
|
s, err := ebiten.NewShader([]byte(`package main
|
||||||
|
|
||||||
|
func Fragment(position vec4, texCoord vec2, color vec4) vec4 {
|
||||||
|
p := imageSrc0At(texCoord)
|
||||||
|
if p.a == 0 {
|
||||||
|
discard()
|
||||||
|
} else {
|
||||||
|
return vec4(0, 1, 0, 1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`))
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
op := &ebiten.DrawRectShaderOptions{}
|
||||||
|
op.Images[0] = src
|
||||||
|
dst.DrawRectShader(w, h, s, op)
|
||||||
|
|
||||||
|
for j := 0; j < h; j++ {
|
||||||
|
for i := 0; i < w; i++ {
|
||||||
|
got := dst.At(i, j).(color.RGBA)
|
||||||
|
want := color.RGBA{0, 0xff, 0x00, 0xff}
|
||||||
|
if i >= w/2 || j >= h/2 {
|
||||||
|
want = color.RGBA{0xff, 0, 0x00, 0xff}
|
||||||
|
}
|
||||||
|
if !sameColors(got, want, 2) {
|
||||||
|
t.Errorf("dst.At(%d, %d): got: %v, want: %v", i, j, got, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user