mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-12-24 02:38:53 +01:00
ebiten: add BlendOperationSubtract and BlendOperationReverseSubtract
Updates #2382
This commit is contained in:
parent
06c53c1445
commit
e03825bf08
12
blend.go
12
blend.go
@ -104,12 +104,24 @@ const (
|
||||
// BlendOperationAdd represents adding the source and destination color.
|
||||
// c_out = factor_src × c_src + factor_dst × c_dst
|
||||
BlendOperationAdd BlendOperation = iota
|
||||
|
||||
// BlendOperationSubtract represents subtracting the source and destination color.
|
||||
// c_out = factor_src × c_src - factor_dst × c_dst
|
||||
BlendOperationSubtract
|
||||
|
||||
// BlendOperationReverseSubtract represents subtracting the source and destination color in a reversed order.
|
||||
// c_out = factor_dst × c_dst - factor_src × c_src
|
||||
BlendOperationReverseSubtract
|
||||
)
|
||||
|
||||
func (b BlendOperation) internalBlendOperation() graphicsdriver.BlendOperation {
|
||||
switch b {
|
||||
case BlendOperationAdd:
|
||||
return graphicsdriver.BlendOperationAdd
|
||||
case BlendOperationSubtract:
|
||||
return graphicsdriver.BlendOperationSubtract
|
||||
case BlendOperationReverseSubtract:
|
||||
return graphicsdriver.BlendOperationReverseSubtract
|
||||
default:
|
||||
panic(fmt.Sprintf("ebiten: invalid blend operation: %d", b))
|
||||
}
|
||||
|
101
image_test.go
101
image_test.go
@ -3551,3 +3551,104 @@ func TestImageColorMAndScale(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestImageBlendOperation(t *testing.T) {
|
||||
const w, h = 16, 1
|
||||
dst := ebiten.NewImage(w, h)
|
||||
src := ebiten.NewImage(w, h)
|
||||
|
||||
dstColor := func(i int) (byte, byte, byte, byte) {
|
||||
return byte(4 * i * 17), byte(4*i*17 + 1), byte(4*i*17 + 2), byte(4*i*17 + 3)
|
||||
}
|
||||
srcColor := func(i int) (byte, byte, byte, byte) {
|
||||
return byte(4 * i * 13), byte(4*i*13 + 1), byte(4*i*13 + 2), byte(4*i*13 + 3)
|
||||
}
|
||||
clamp := func(x int) byte {
|
||||
if x > 255 {
|
||||
return 255
|
||||
}
|
||||
if x < 0 {
|
||||
return 0
|
||||
}
|
||||
return byte(x)
|
||||
}
|
||||
|
||||
dstPix := make([]byte, 4*w*h)
|
||||
for i := 0; i < w; i++ {
|
||||
r, g, b, a := dstColor(i)
|
||||
dstPix[4*i] = r
|
||||
dstPix[4*i+1] = g
|
||||
dstPix[4*i+2] = b
|
||||
dstPix[4*i+3] = a
|
||||
}
|
||||
srcPix := make([]byte, 4*w*h)
|
||||
for i := 0; i < w; i++ {
|
||||
r, g, b, a := srcColor(i)
|
||||
srcPix[4*i] = r
|
||||
srcPix[4*i+1] = g
|
||||
srcPix[4*i+2] = b
|
||||
srcPix[4*i+3] = a
|
||||
}
|
||||
src.WritePixels(srcPix)
|
||||
|
||||
colorOperations := []ebiten.BlendOperation{
|
||||
ebiten.BlendOperationAdd,
|
||||
ebiten.BlendOperationSubtract,
|
||||
ebiten.BlendOperationReverseSubtract,
|
||||
}
|
||||
alphaOperations := []ebiten.BlendOperation{
|
||||
ebiten.BlendOperationAdd,
|
||||
ebiten.BlendOperationSubtract,
|
||||
ebiten.BlendOperationReverseSubtract,
|
||||
}
|
||||
for _, cop := range colorOperations {
|
||||
for _, aop := range alphaOperations {
|
||||
// Reset the destination state.
|
||||
dst.WritePixels(dstPix)
|
||||
op := &ebiten.DrawImageOptions{}
|
||||
op.Blend = ebiten.Blend{
|
||||
BlendFactorSourceColor: ebiten.BlendFactorOne,
|
||||
BlendFactorSourceAlpha: ebiten.BlendFactorOne,
|
||||
BlendFactorDestinationColor: ebiten.BlendFactorOne,
|
||||
BlendFactorDestinationAlpha: ebiten.BlendFactorOne,
|
||||
BlendOperationColor: cop,
|
||||
BlendOperationAlpha: aop,
|
||||
}
|
||||
dst.DrawImage(src, op)
|
||||
for i := 0; i < w; i++ {
|
||||
got := dst.At(i, 0).(color.RGBA)
|
||||
|
||||
sr, sg, sb, sa := srcColor(i)
|
||||
dr, dg, db, da := dstColor(i)
|
||||
|
||||
var want color.RGBA
|
||||
switch cop {
|
||||
case ebiten.BlendOperationAdd:
|
||||
want.R = clamp(int(sr) + int(dr))
|
||||
want.G = clamp(int(sg) + int(dg))
|
||||
want.B = clamp(int(sb) + int(db))
|
||||
case ebiten.BlendOperationSubtract:
|
||||
want.R = clamp(int(sr) - int(dr))
|
||||
want.G = clamp(int(sg) - int(dg))
|
||||
want.B = clamp(int(sb) - int(db))
|
||||
case ebiten.BlendOperationReverseSubtract:
|
||||
want.R = clamp(int(dr) - int(sr))
|
||||
want.G = clamp(int(dg) - int(sg))
|
||||
want.B = clamp(int(db) - int(sb))
|
||||
}
|
||||
switch aop {
|
||||
case ebiten.BlendOperationAdd:
|
||||
want.A = clamp(int(sa) + int(da))
|
||||
case ebiten.BlendOperationSubtract:
|
||||
want.A = clamp(int(sa) - int(da))
|
||||
case ebiten.BlendOperationReverseSubtract:
|
||||
want.A = clamp(int(da) - int(sa))
|
||||
}
|
||||
|
||||
if !sameColors(got, want, 1) {
|
||||
t.Errorf("dst.At(%d, 0): operations: %d, %d: got: %v, want: %v", i, cop, aop, got, want)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -39,8 +39,8 @@ type BlendOperation byte
|
||||
|
||||
const (
|
||||
BlendOperationAdd BlendOperation = iota
|
||||
|
||||
// TODO: Add more operators
|
||||
BlendOperationSubtract
|
||||
BlendOperationReverseSubtract
|
||||
)
|
||||
|
||||
var BlendSourceOver = Blend{
|
||||
|
@ -55,6 +55,10 @@ func blendOperationToBlendOp(o graphicsdriver.BlendOperation) _D3D12_BLEND_OP {
|
||||
switch o {
|
||||
case graphicsdriver.BlendOperationAdd:
|
||||
return _D3D12_BLEND_OP_ADD
|
||||
case graphicsdriver.BlendOperationSubtract:
|
||||
return _D3D12_BLEND_OP_SUBTRACT
|
||||
case graphicsdriver.BlendOperationReverseSubtract:
|
||||
return _D3D12_BLEND_OP_REV_SUBTRACT
|
||||
default:
|
||||
panic(fmt.Sprintf("directx: invalid blend operation: %d", o))
|
||||
}
|
||||
|
@ -325,6 +325,10 @@ func blendOperationToMetalBlendOperation(o graphicsdriver.BlendOperation) mtl.Bl
|
||||
switch o {
|
||||
case graphicsdriver.BlendOperationAdd:
|
||||
return mtl.BlendOperationAdd
|
||||
case graphicsdriver.BlendOperationSubtract:
|
||||
return mtl.BlendOperationSubtract
|
||||
case graphicsdriver.BlendOperationReverseSubtract:
|
||||
return mtl.BlendOperationReverseSubtract
|
||||
default:
|
||||
panic(fmt.Sprintf("metal: invalid blend operation: %d", o))
|
||||
}
|
||||
|
@ -36,7 +36,9 @@ const (
|
||||
type blendOperation int
|
||||
|
||||
const (
|
||||
glFuncAdd blendOperation = 0x8006
|
||||
glFuncAdd blendOperation = 0x8006
|
||||
glFuncReverseSubtract blendOperation = 0x800b
|
||||
glFuncSubtract blendOperation = 0x800a
|
||||
)
|
||||
|
||||
func convertBlendFactor(f graphicsdriver.BlendFactor) blendFactor {
|
||||
@ -64,6 +66,10 @@ func convertBlendOperation(o graphicsdriver.BlendOperation) blendOperation {
|
||||
switch o {
|
||||
case graphicsdriver.BlendOperationAdd:
|
||||
return glFuncAdd
|
||||
case graphicsdriver.BlendOperationSubtract:
|
||||
return glFuncSubtract
|
||||
case graphicsdriver.BlendOperationReverseSubtract:
|
||||
return glFuncReverseSubtract
|
||||
default:
|
||||
panic(fmt.Sprintf("opengl: invalid blend operation %d", o))
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user