mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-12-24 18:58:54 +01:00
parent
7018e7dfb1
commit
567e2fa04c
18
blend.go
18
blend.go
@ -200,6 +200,20 @@ const (
|
||||
// c_out = (BlendFactorDestinationRGB) × c_dst - (BlendFactorSourceRGB) × c_src
|
||||
// α_out = (BlendFactorDestinationAlpha) × α_dst - (BlendFactorSourceAlpha) × α_src
|
||||
BlendOperationReverseSubtract
|
||||
|
||||
// BlendOperationMin represents a minimum function for the source and destination color.
|
||||
// If BlendOperationMin is specified, blend factors are not used.
|
||||
//
|
||||
// c_out = min(c_dst, c_src)
|
||||
// α_out = min(α_dst, α_src)
|
||||
BlendOperationMin
|
||||
|
||||
// BlendOperationMax represents a maximum function for the source and destination color.
|
||||
// If BlendOperationMax is specified, blend factors are not used.
|
||||
//
|
||||
// c_out = max(c_dst, c_src)
|
||||
// α_out = max(α_dst, α_src)
|
||||
BlendOperationMax
|
||||
)
|
||||
|
||||
func (b BlendOperation) internalBlendOperation() graphicsdriver.BlendOperation {
|
||||
@ -210,6 +224,10 @@ func (b BlendOperation) internalBlendOperation() graphicsdriver.BlendOperation {
|
||||
return graphicsdriver.BlendOperationSubtract
|
||||
case BlendOperationReverseSubtract:
|
||||
return graphicsdriver.BlendOperationReverseSubtract
|
||||
case BlendOperationMin:
|
||||
return graphicsdriver.BlendOperationMin
|
||||
case BlendOperationMax:
|
||||
return graphicsdriver.BlendOperationMax
|
||||
default:
|
||||
panic(fmt.Sprintf("ebiten: invalid blend operation: %d", b))
|
||||
}
|
||||
|
@ -335,13 +335,26 @@ func TestImageDispose(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func min(a, b int) int {
|
||||
type ordered interface {
|
||||
~int | ~int8 | ~int16 | ~int32 | ~int64 | ~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 | ~uintptr | ~float32 | ~float64 | ~string
|
||||
}
|
||||
|
||||
// TODO: Use the built-in function min from Go 1.21.
|
||||
func min[T ordered](a, b T) T {
|
||||
if a < b {
|
||||
return a
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
// TODO: Use the built-in function max from Go 1.21.
|
||||
func max[T ordered](a, b T) T {
|
||||
if a < b {
|
||||
return b
|
||||
}
|
||||
return a
|
||||
}
|
||||
|
||||
func TestImageBlendLighter(t *testing.T) {
|
||||
img0, _, err := openEbitenImage()
|
||||
if err != nil {
|
||||
@ -3687,6 +3700,87 @@ func TestImageBlendOperation(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestImageBlendOperationMinAndMax(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)
|
||||
}
|
||||
|
||||
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)
|
||||
|
||||
operations := []ebiten.BlendOperation{
|
||||
ebiten.BlendOperationMin,
|
||||
ebiten.BlendOperationMax,
|
||||
}
|
||||
for _, rgbOp := range operations {
|
||||
for _, alphaOp := range operations {
|
||||
// Reset the destination state.
|
||||
dst.WritePixels(dstPix)
|
||||
op := &ebiten.DrawImageOptions{}
|
||||
// Use the default blend factors, and confirm that the factors are ignored.
|
||||
op.Blend = ebiten.Blend{
|
||||
BlendFactorSourceRGB: ebiten.BlendFactorDefault,
|
||||
BlendFactorSourceAlpha: ebiten.BlendFactorDefault,
|
||||
BlendFactorDestinationRGB: ebiten.BlendFactorDefault,
|
||||
BlendFactorDestinationAlpha: ebiten.BlendFactorDefault,
|
||||
BlendOperationRGB: rgbOp,
|
||||
BlendOperationAlpha: alphaOp,
|
||||
}
|
||||
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 rgbOp {
|
||||
case ebiten.BlendOperationMin:
|
||||
want.R = min(sr, dr)
|
||||
want.G = min(sg, dg)
|
||||
want.B = min(sb, db)
|
||||
case ebiten.BlendOperationMax:
|
||||
want.R = max(sr, dr)
|
||||
want.G = max(sg, dg)
|
||||
want.B = max(sb, db)
|
||||
}
|
||||
switch alphaOp {
|
||||
case ebiten.BlendOperationMin:
|
||||
want.A = min(sa, da)
|
||||
case ebiten.BlendOperationMax:
|
||||
want.A = max(sa, da)
|
||||
}
|
||||
|
||||
if !sameColors(got, want, 1) {
|
||||
t.Errorf("dst.At(%d, 0): operations: %d, %d: got: %v, want: %v", i, rgbOp, alphaOp, got, want)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestImageBlendFactor(t *testing.T) {
|
||||
if skipTooSlowTests(t) {
|
||||
return
|
||||
|
@ -45,6 +45,8 @@ const (
|
||||
BlendOperationAdd BlendOperation = iota
|
||||
BlendOperationSubtract
|
||||
BlendOperationReverseSubtract
|
||||
BlendOperationMin
|
||||
BlendOperationMax
|
||||
)
|
||||
|
||||
var BlendSourceOver = Blend{
|
||||
|
@ -106,6 +106,10 @@ func blendOperationToBlendOp11(o graphicsdriver.BlendOperation) _D3D11_BLEND_OP
|
||||
return _D3D11_BLEND_OP_SUBTRACT
|
||||
case graphicsdriver.BlendOperationReverseSubtract:
|
||||
return _D3D11_BLEND_OP_REV_SUBTRACT
|
||||
case graphicsdriver.BlendOperationMin:
|
||||
return _D3D11_BLEND_OP_MIN
|
||||
case graphicsdriver.BlendOperationMax:
|
||||
return _D3D11_BLEND_OP_MAX
|
||||
default:
|
||||
panic(fmt.Sprintf("directx: invalid blend operation: %d", o))
|
||||
}
|
||||
|
@ -107,6 +107,10 @@ func blendOperationToBlendOp12(o graphicsdriver.BlendOperation) _D3D12_BLEND_OP
|
||||
return _D3D12_BLEND_OP_SUBTRACT
|
||||
case graphicsdriver.BlendOperationReverseSubtract:
|
||||
return _D3D12_BLEND_OP_REV_SUBTRACT
|
||||
case graphicsdriver.BlendOperationMin:
|
||||
return _D3D12_BLEND_OP_MIN
|
||||
case graphicsdriver.BlendOperationMax:
|
||||
return _D3D12_BLEND_OP_MAX
|
||||
default:
|
||||
panic(fmt.Sprintf("directx: invalid blend operation: %d", o))
|
||||
}
|
||||
|
@ -381,6 +381,10 @@ func blendOperationToMetalBlendOperation(o graphicsdriver.BlendOperation) mtl.Bl
|
||||
return mtl.BlendOperationSubtract
|
||||
case graphicsdriver.BlendOperationReverseSubtract:
|
||||
return mtl.BlendOperationReverseSubtract
|
||||
case graphicsdriver.BlendOperationMin:
|
||||
return mtl.BlendOperationMin
|
||||
case graphicsdriver.BlendOperationMax:
|
||||
return mtl.BlendOperationMax
|
||||
default:
|
||||
panic(fmt.Sprintf("metal: invalid blend operation: %d", o))
|
||||
}
|
||||
|
@ -67,6 +67,10 @@ func convertBlendOperation(o graphicsdriver.BlendOperation) blendOperation {
|
||||
return gl.FUNC_SUBTRACT
|
||||
case graphicsdriver.BlendOperationReverseSubtract:
|
||||
return gl.FUNC_REVERSE_SUBTRACT
|
||||
case graphicsdriver.BlendOperationMin:
|
||||
return gl.MIN
|
||||
case graphicsdriver.BlendOperationMax:
|
||||
return gl.MAX
|
||||
default:
|
||||
panic(fmt.Sprintf("opengl: invalid blend operation %d", o))
|
||||
}
|
||||
|
@ -40,7 +40,9 @@ const (
|
||||
INVERT = 0x150A
|
||||
KEEP = 0x1E00
|
||||
LINK_STATUS = 0x8B82
|
||||
MAX = 0x8008
|
||||
MAX_TEXTURE_SIZE = 0x0D33
|
||||
MIN = 0x8007
|
||||
NEAREST = 0x2600
|
||||
NO_ERROR = 0
|
||||
NOTEQUAL = 0x0205
|
||||
|
Loading…
Reference in New Issue
Block a user