mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-12-25 03:08:54 +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.
|
// BlendOperationAdd represents adding the source and destination color.
|
||||||
// c_out = factor_src × c_src + factor_dst × c_dst
|
// c_out = factor_src × c_src + factor_dst × c_dst
|
||||||
BlendOperationAdd BlendOperation = iota
|
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 {
|
func (b BlendOperation) internalBlendOperation() graphicsdriver.BlendOperation {
|
||||||
switch b {
|
switch b {
|
||||||
case BlendOperationAdd:
|
case BlendOperationAdd:
|
||||||
return graphicsdriver.BlendOperationAdd
|
return graphicsdriver.BlendOperationAdd
|
||||||
|
case BlendOperationSubtract:
|
||||||
|
return graphicsdriver.BlendOperationSubtract
|
||||||
|
case BlendOperationReverseSubtract:
|
||||||
|
return graphicsdriver.BlendOperationReverseSubtract
|
||||||
default:
|
default:
|
||||||
panic(fmt.Sprintf("ebiten: invalid blend operation: %d", b))
|
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 (
|
const (
|
||||||
BlendOperationAdd BlendOperation = iota
|
BlendOperationAdd BlendOperation = iota
|
||||||
|
BlendOperationSubtract
|
||||||
// TODO: Add more operators
|
BlendOperationReverseSubtract
|
||||||
)
|
)
|
||||||
|
|
||||||
var BlendSourceOver = Blend{
|
var BlendSourceOver = Blend{
|
||||||
|
@ -55,6 +55,10 @@ func blendOperationToBlendOp(o graphicsdriver.BlendOperation) _D3D12_BLEND_OP {
|
|||||||
switch o {
|
switch o {
|
||||||
case graphicsdriver.BlendOperationAdd:
|
case graphicsdriver.BlendOperationAdd:
|
||||||
return _D3D12_BLEND_OP_ADD
|
return _D3D12_BLEND_OP_ADD
|
||||||
|
case graphicsdriver.BlendOperationSubtract:
|
||||||
|
return _D3D12_BLEND_OP_SUBTRACT
|
||||||
|
case graphicsdriver.BlendOperationReverseSubtract:
|
||||||
|
return _D3D12_BLEND_OP_REV_SUBTRACT
|
||||||
default:
|
default:
|
||||||
panic(fmt.Sprintf("directx: invalid blend operation: %d", o))
|
panic(fmt.Sprintf("directx: invalid blend operation: %d", o))
|
||||||
}
|
}
|
||||||
|
@ -325,6 +325,10 @@ func blendOperationToMetalBlendOperation(o graphicsdriver.BlendOperation) mtl.Bl
|
|||||||
switch o {
|
switch o {
|
||||||
case graphicsdriver.BlendOperationAdd:
|
case graphicsdriver.BlendOperationAdd:
|
||||||
return mtl.BlendOperationAdd
|
return mtl.BlendOperationAdd
|
||||||
|
case graphicsdriver.BlendOperationSubtract:
|
||||||
|
return mtl.BlendOperationSubtract
|
||||||
|
case graphicsdriver.BlendOperationReverseSubtract:
|
||||||
|
return mtl.BlendOperationReverseSubtract
|
||||||
default:
|
default:
|
||||||
panic(fmt.Sprintf("metal: invalid blend operation: %d", o))
|
panic(fmt.Sprintf("metal: invalid blend operation: %d", o))
|
||||||
}
|
}
|
||||||
|
@ -37,6 +37,8 @@ type blendOperation int
|
|||||||
|
|
||||||
const (
|
const (
|
||||||
glFuncAdd blendOperation = 0x8006
|
glFuncAdd blendOperation = 0x8006
|
||||||
|
glFuncReverseSubtract blendOperation = 0x800b
|
||||||
|
glFuncSubtract blendOperation = 0x800a
|
||||||
)
|
)
|
||||||
|
|
||||||
func convertBlendFactor(f graphicsdriver.BlendFactor) blendFactor {
|
func convertBlendFactor(f graphicsdriver.BlendFactor) blendFactor {
|
||||||
@ -64,6 +66,10 @@ func convertBlendOperation(o graphicsdriver.BlendOperation) blendOperation {
|
|||||||
switch o {
|
switch o {
|
||||||
case graphicsdriver.BlendOperationAdd:
|
case graphicsdriver.BlendOperationAdd:
|
||||||
return glFuncAdd
|
return glFuncAdd
|
||||||
|
case graphicsdriver.BlendOperationSubtract:
|
||||||
|
return glFuncSubtract
|
||||||
|
case graphicsdriver.BlendOperationReverseSubtract:
|
||||||
|
return glFuncReverseSubtract
|
||||||
default:
|
default:
|
||||||
panic(fmt.Sprintf("opengl: invalid blend operation %d", o))
|
panic(fmt.Sprintf("opengl: invalid blend operation %d", o))
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user