mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-12-24 02:38:53 +01:00
parent
bd0d43f98f
commit
b79495761e
254
blend.go
Normal file
254
blend.go
Normal file
@ -0,0 +1,254 @@
|
||||
// Copyright 2022 The Ebitengine Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package ebiten
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/hajimehoshi/ebiten/v2/internal/graphicsdriver"
|
||||
)
|
||||
|
||||
// Blend is a blending way of the source color and the destination color.
|
||||
//
|
||||
// The default (zero) value is source-over (regular alpha blending).
|
||||
type Blend struct {
|
||||
// BlendFactorSourceColor is a factor for source RGB values.
|
||||
BlendFactorSourceColor BlendFactor
|
||||
|
||||
// BlendFactorSourceAlpha is a factor for source alpha values.
|
||||
BlendFactorSourceAlpha BlendFactor
|
||||
|
||||
// BlendFactorDestinationColor is a factor for destination RGB values.
|
||||
BlendFactorDestinationColor BlendFactor
|
||||
|
||||
// BlendFactorDestinationAlpha is a factor for destination apha values.
|
||||
BlendFactorDestinationAlpha BlendFactor
|
||||
|
||||
// BlendOperationColor is an operation for source and destination RGB values.
|
||||
BlendOperationColor BlendOperation
|
||||
|
||||
// BlendOperationAlpha is an operation for source and destination alpha values.
|
||||
BlendOperationAlpha BlendOperation
|
||||
}
|
||||
|
||||
func (b Blend) internalBlend() graphicsdriver.Blend {
|
||||
return graphicsdriver.Blend{
|
||||
BlendFactorSourceColor: b.BlendFactorSourceColor.internalBlendFactor(true),
|
||||
BlendFactorSourceAlpha: b.BlendFactorSourceAlpha.internalBlendFactor(true),
|
||||
BlendFactorDestinationColor: b.BlendFactorDestinationColor.internalBlendFactor(false),
|
||||
BlendFactorDestinationAlpha: b.BlendFactorDestinationAlpha.internalBlendFactor(false),
|
||||
BlendOperationColor: b.BlendOperationColor.internalBlendOperation(),
|
||||
BlendOperationAlpha: b.BlendOperationAlpha.internalBlendOperation(),
|
||||
}
|
||||
}
|
||||
|
||||
// BlendFactor is a factor for source and destination color values.
|
||||
type BlendFactor byte
|
||||
|
||||
const (
|
||||
// BlendFactorDefault is the default factor value.
|
||||
// The actual value depends on which source or destination this value is used.
|
||||
BlendFactorDefault BlendFactor = iota
|
||||
BlendFactorZero
|
||||
BlendFactorOne
|
||||
BlendFactorSourceAlpha
|
||||
BlendFactorDestinationAlpha
|
||||
BlendFactorOneMinusSourceAlpha
|
||||
BlendFactorOneMinusDestinationAlpha
|
||||
BlendFactorDestinationColor
|
||||
)
|
||||
|
||||
func (b BlendFactor) internalBlendFactor(source bool) graphicsdriver.BlendFactor {
|
||||
switch b {
|
||||
case BlendFactorDefault:
|
||||
// The default is the source-over composition (regular alpha blending).
|
||||
if source {
|
||||
return graphicsdriver.BlendFactorOne
|
||||
}
|
||||
return graphicsdriver.BlendFactorOneMinusSourceAlpha
|
||||
case BlendFactorZero:
|
||||
return graphicsdriver.BlendFactorZero
|
||||
case BlendFactorOne:
|
||||
return graphicsdriver.BlendFactorOne
|
||||
case BlendFactorSourceAlpha:
|
||||
return graphicsdriver.BlendFactorSourceAlpha
|
||||
case BlendFactorDestinationAlpha:
|
||||
return graphicsdriver.BlendFactorDestinationAlpha
|
||||
case BlendFactorOneMinusSourceAlpha:
|
||||
return graphicsdriver.BlendFactorOneMinusSourceAlpha
|
||||
case BlendFactorOneMinusDestinationAlpha:
|
||||
return graphicsdriver.BlendFactorOneMinusDestinationAlpha
|
||||
case BlendFactorDestinationColor:
|
||||
return graphicsdriver.BlendFactorDestinationColor
|
||||
default:
|
||||
panic(fmt.Sprintf("ebiten: invalid blend factor: %d", b))
|
||||
}
|
||||
}
|
||||
|
||||
// BlendFactor is an operation for source and destination color values.
|
||||
type BlendOperation byte
|
||||
|
||||
const (
|
||||
// BlendOperationAdd represents adding the source and destination color.
|
||||
// c_out = factor_src × c_src + factor_dst × c_dst
|
||||
BlendOperationAdd BlendOperation = iota
|
||||
)
|
||||
|
||||
func (b BlendOperation) internalBlendOperation() graphicsdriver.BlendOperation {
|
||||
switch b {
|
||||
case BlendOperationAdd:
|
||||
return graphicsdriver.BlendOperationAdd
|
||||
default:
|
||||
panic(fmt.Sprintf("ebiten: invalid blend operation: %d", b))
|
||||
}
|
||||
}
|
||||
|
||||
// This name convention follows CSS compositing: https://drafts.fxtf.org/compositing-2/.
|
||||
//
|
||||
// In the comments,
|
||||
// c_src, c_dst and c_out represent alpha-premultiplied RGB values of source, destination and output respectively. α_src and α_dst represent alpha values of source and destination respectively.
|
||||
var (
|
||||
// BlendSourceOver represents the regular alpha blending.
|
||||
// c_out = c_src + c_dst × (1 - α_src)
|
||||
BlendSourceOver = Blend{
|
||||
BlendFactorSourceColor: BlendFactorOne,
|
||||
BlendFactorSourceAlpha: BlendFactorOne,
|
||||
BlendFactorDestinationColor: BlendFactorOneMinusSourceAlpha,
|
||||
BlendFactorDestinationAlpha: BlendFactorOneMinusSourceAlpha,
|
||||
BlendOperationColor: BlendOperationAdd,
|
||||
BlendOperationAlpha: BlendOperationAdd,
|
||||
}
|
||||
|
||||
// c_out = 0
|
||||
BlendClear = Blend{
|
||||
BlendFactorSourceColor: BlendFactorZero,
|
||||
BlendFactorSourceAlpha: BlendFactorZero,
|
||||
BlendFactorDestinationColor: BlendFactorZero,
|
||||
BlendFactorDestinationAlpha: BlendFactorZero,
|
||||
BlendOperationColor: BlendOperationAdd,
|
||||
BlendOperationAlpha: BlendOperationAdd,
|
||||
}
|
||||
|
||||
// c_out = c_src
|
||||
BlendCopy = Blend{
|
||||
BlendFactorSourceColor: BlendFactorOne,
|
||||
BlendFactorSourceAlpha: BlendFactorOne,
|
||||
BlendFactorDestinationColor: BlendFactorZero,
|
||||
BlendFactorDestinationAlpha: BlendFactorZero,
|
||||
BlendOperationColor: BlendOperationAdd,
|
||||
BlendOperationAlpha: BlendOperationAdd,
|
||||
}
|
||||
|
||||
// c_out = c_dst
|
||||
BlendDestination = Blend{
|
||||
BlendFactorSourceColor: BlendFactorZero,
|
||||
BlendFactorSourceAlpha: BlendFactorZero,
|
||||
BlendFactorDestinationColor: BlendFactorOne,
|
||||
BlendFactorDestinationAlpha: BlendFactorOne,
|
||||
BlendOperationColor: BlendOperationAdd,
|
||||
BlendOperationAlpha: BlendOperationAdd,
|
||||
}
|
||||
|
||||
// c_out = c_src × (1 - α_dst) + c_dst
|
||||
BlendDestinationOver = Blend{
|
||||
BlendFactorSourceColor: BlendFactorOneMinusDestinationAlpha,
|
||||
BlendFactorSourceAlpha: BlendFactorOneMinusDestinationAlpha,
|
||||
BlendFactorDestinationColor: BlendFactorOne,
|
||||
BlendFactorDestinationAlpha: BlendFactorOne,
|
||||
BlendOperationColor: BlendOperationAdd,
|
||||
BlendOperationAlpha: BlendOperationAdd,
|
||||
}
|
||||
|
||||
// c_out = c_src × α_dst
|
||||
BlendSourceIn = Blend{
|
||||
BlendFactorSourceColor: BlendFactorDestinationAlpha,
|
||||
BlendFactorSourceAlpha: BlendFactorDestinationAlpha,
|
||||
BlendFactorDestinationColor: BlendFactorZero,
|
||||
BlendFactorDestinationAlpha: BlendFactorZero,
|
||||
BlendOperationColor: BlendOperationAdd,
|
||||
BlendOperationAlpha: BlendOperationAdd,
|
||||
}
|
||||
|
||||
// c_out = c_dst × α_src
|
||||
BlendDestinationIn = Blend{
|
||||
BlendFactorSourceColor: BlendFactorZero,
|
||||
BlendFactorSourceAlpha: BlendFactorZero,
|
||||
BlendFactorDestinationColor: BlendFactorSourceAlpha,
|
||||
BlendFactorDestinationAlpha: BlendFactorSourceAlpha,
|
||||
BlendOperationColor: BlendOperationAdd,
|
||||
BlendOperationAlpha: BlendOperationAdd,
|
||||
}
|
||||
|
||||
// c_out = c_src × (1 - α_dst)
|
||||
BlendSourceOut = Blend{
|
||||
BlendFactorSourceColor: BlendFactorOneMinusDestinationAlpha,
|
||||
BlendFactorSourceAlpha: BlendFactorOneMinusDestinationAlpha,
|
||||
BlendFactorDestinationColor: BlendFactorZero,
|
||||
BlendFactorDestinationAlpha: BlendFactorZero,
|
||||
BlendOperationColor: BlendOperationAdd,
|
||||
BlendOperationAlpha: BlendOperationAdd,
|
||||
}
|
||||
|
||||
// c_out = c_dst × (1 - α_src)
|
||||
BlendDestinationOut = Blend{
|
||||
BlendFactorSourceColor: BlendFactorOneMinusDestinationAlpha,
|
||||
BlendFactorSourceAlpha: BlendFactorOneMinusDestinationAlpha,
|
||||
BlendFactorDestinationColor: BlendFactorZero,
|
||||
BlendFactorDestinationAlpha: BlendFactorZero,
|
||||
BlendOperationColor: BlendOperationAdd,
|
||||
BlendOperationAlpha: BlendOperationAdd,
|
||||
}
|
||||
|
||||
// c_out = c_src × α_dst + c_dst × (1 - α_src)
|
||||
BlendSourceAtop = Blend{
|
||||
BlendFactorSourceColor: BlendFactorDestinationAlpha,
|
||||
BlendFactorSourceAlpha: BlendFactorDestinationAlpha,
|
||||
BlendFactorDestinationColor: BlendFactorOneMinusSourceAlpha,
|
||||
BlendFactorDestinationAlpha: BlendFactorOneMinusSourceAlpha,
|
||||
BlendOperationColor: BlendOperationAdd,
|
||||
BlendOperationAlpha: BlendOperationAdd,
|
||||
}
|
||||
|
||||
// c_out = c_src × (1 - α_dst) + c_dst × α_src
|
||||
BlendDestinationAtop = Blend{
|
||||
BlendFactorSourceColor: BlendFactorOneMinusDestinationAlpha,
|
||||
BlendFactorSourceAlpha: BlendFactorOneMinusDestinationAlpha,
|
||||
BlendFactorDestinationColor: BlendFactorSourceAlpha,
|
||||
BlendFactorDestinationAlpha: BlendFactorSourceAlpha,
|
||||
BlendOperationColor: BlendOperationAdd,
|
||||
BlendOperationAlpha: BlendOperationAdd,
|
||||
}
|
||||
|
||||
// c_out = c_src × (1 - α_dst) + c_dst × (1 - α_src)
|
||||
BlendXor = Blend{
|
||||
BlendFactorSourceColor: BlendFactorOneMinusDestinationAlpha,
|
||||
BlendFactorSourceAlpha: BlendFactorOneMinusDestinationAlpha,
|
||||
BlendFactorDestinationColor: BlendFactorOneMinusSourceAlpha,
|
||||
BlendFactorDestinationAlpha: BlendFactorOneMinusSourceAlpha,
|
||||
BlendOperationColor: BlendOperationAdd,
|
||||
BlendOperationAlpha: BlendOperationAdd,
|
||||
}
|
||||
|
||||
// Sum of source and destination (a.k.a. 'plus' or 'additive')
|
||||
// c_out = c_src + c_dst
|
||||
BlendLighter = Blend{
|
||||
BlendFactorSourceColor: BlendFactorOne,
|
||||
BlendFactorSourceAlpha: BlendFactorOne,
|
||||
BlendFactorDestinationColor: BlendFactorOne,
|
||||
BlendFactorDestinationAlpha: BlendFactorOne,
|
||||
BlendOperationColor: BlendOperationAdd,
|
||||
BlendOperationAlpha: BlendOperationAdd,
|
||||
}
|
||||
)
|
@ -52,16 +52,16 @@ func (g *Game) Draw(screen *ebiten.Image) {
|
||||
|
||||
screen.Fill(color.NRGBA{0x00, 0x40, 0x80, 0xff})
|
||||
|
||||
// Draw the image with 'Source Alpha' composite mode (default).
|
||||
// Draw the image with 'Source Over' blend mode (default).
|
||||
op := &ebiten.DrawImageOptions{}
|
||||
op.GeoM.Translate(ox, oy)
|
||||
screen.DrawImage(ebitenImage, op)
|
||||
|
||||
// Draw the image with 'Lighter (a.k.a Additive)' composite mode.
|
||||
// Draw the image with 'Lighter (a.k.a Additive)' blend mode.
|
||||
op = &ebiten.DrawImageOptions{}
|
||||
w, _ := ebitenImage.Size()
|
||||
op.GeoM.Translate(ox+float64(w), oy)
|
||||
op.CompositeMode = ebiten.CompositeModeLighter
|
||||
op.Blend = ebiten.BlendLighter
|
||||
screen.DrawImage(ebitenImage, op)
|
||||
}
|
||||
|
||||
|
@ -62,15 +62,15 @@ func (g *Game) Draw(screen *ebiten.Image) {
|
||||
for i := -3; i <= 3; i++ {
|
||||
op := &ebiten.DrawImageOptions{}
|
||||
op.GeoM.Translate(float64(i), 244+float64(j))
|
||||
// This is a blur based on the CompositerModeSourceOver composition mode,
|
||||
// This is a blur based on the source-over blend mode,
|
||||
// which is basically (GL_ONE, GL_ONE_MINUS_SRC_ALPHA). ColorM acts
|
||||
// on unpremultiplied colors, but all Ebitengine internal colors are
|
||||
// premultiplied, meaning this mode is regular alpha blending,
|
||||
// computing each destination pixel as srcPix * alpha + dstPix * (1 - alpha).
|
||||
//
|
||||
// This means that the final color is affected by the destination color when CompositeModeSourceOver is used.
|
||||
// This composite mode is the default mode. See how this is calculated at the doc:
|
||||
// https://pkg.go.dev/github.com/hajimehoshi/ebiten/v2#CompositeMode
|
||||
// This means that the final color is affected by the destination color when BlendSourceOver is used.
|
||||
// This blend mode is the default mode. See how this is calculated at the doc:
|
||||
// https://pkg.go.dev/github.com/hajimehoshi/ebiten/v2#Blend
|
||||
//
|
||||
// So if using the same alpha every time, the end result will sure be biased towards the last layer.
|
||||
//
|
||||
|
@ -122,11 +122,11 @@ func (g *Game) Draw(screen *ebiten.Image) {
|
||||
// Reset the maskedFgImage.
|
||||
maskedFgImage.Fill(color.White)
|
||||
op := &ebiten.DrawImageOptions{}
|
||||
op.CompositeMode = ebiten.CompositeModeCopy
|
||||
op.Blend = ebiten.BlendCopy
|
||||
op.GeoM.Translate(float64(g.spotLightX), float64(g.spotLightY))
|
||||
maskedFgImage.DrawImage(spotLightImage, op)
|
||||
|
||||
// Use 'source-in' composite mode so that the source image (fgImage) is used but the alpha
|
||||
// Use 'source-in' blend mode so that the source image (fgImage) is used but the alpha
|
||||
// is determined by the destination image (maskedFgImage).
|
||||
//
|
||||
// The result image is the source image with the destination alpha. In maskedFgImage, alpha
|
||||
@ -136,7 +136,7 @@ func (g *Game) Draw(screen *ebiten.Image) {
|
||||
//
|
||||
// See also https://www.w3.org/TR/compositing-1/#porterduffcompositingoperators_srcin.
|
||||
op = &ebiten.DrawImageOptions{}
|
||||
op.CompositeMode = ebiten.CompositeModeSourceIn
|
||||
op.Blend = ebiten.BlendSourceIn
|
||||
maskedFgImage.DrawImage(fgImage, op)
|
||||
|
||||
screen.Fill(color.RGBA{0x00, 0x00, 0x80, 0xff})
|
||||
|
@ -234,7 +234,7 @@ func (g *Game) Draw(screen *ebiten.Image) {
|
||||
// Subtract ray triangles from shadow
|
||||
opt := &ebiten.DrawTrianglesOptions{}
|
||||
opt.Address = ebiten.AddressRepeat
|
||||
opt.CompositeMode = ebiten.CompositeModeSourceOut
|
||||
opt.Blend = ebiten.BlendSourceOut
|
||||
for i, line := range rays {
|
||||
nextLine := rays[(i+1)%len(rays)]
|
||||
|
||||
|
92
graphics.go
92
graphics.go
@ -18,7 +18,6 @@ import (
|
||||
"fmt"
|
||||
|
||||
"github.com/hajimehoshi/ebiten/v2/internal/builtinshader"
|
||||
"github.com/hajimehoshi/ebiten/v2/internal/graphicsdriver"
|
||||
"github.com/hajimehoshi/ebiten/v2/internal/ui"
|
||||
)
|
||||
|
||||
@ -34,101 +33,94 @@ const (
|
||||
)
|
||||
|
||||
// CompositeMode represents Porter-Duff composition mode.
|
||||
//
|
||||
// Deprecated: as of v2.5. Use Blend instead.
|
||||
type CompositeMode int
|
||||
|
||||
// This name convention follows CSS compositing: https://drafts.fxtf.org/compositing-2/.
|
||||
//
|
||||
// In the comments,
|
||||
// c_src, c_dst and c_out represent alpha-premultiplied RGB values of source, destination and output respectively. α_src and α_dst represent alpha values of source and destination respectively.
|
||||
const (
|
||||
// Regular alpha blending
|
||||
// c_out = c_src + c_dst × (1 - α_src)
|
||||
CompositeModeSourceOver CompositeMode = iota
|
||||
// CompositeModeCustom indicates to refer Blend.
|
||||
CompositeModeCustom CompositeMode = iota
|
||||
|
||||
// c_out = 0
|
||||
// Deprecated: as of v2.5. Use BlendSourceOver instead.
|
||||
CompositeModeSourceOver
|
||||
|
||||
// Deprecated: as of v2.5. Use BlendClear instead.
|
||||
CompositeModeClear
|
||||
|
||||
// c_out = c_src
|
||||
// Deprecated: as of v2.5. Use BlendCopy instead.
|
||||
CompositeModeCopy
|
||||
|
||||
// c_out = c_dst
|
||||
// Deprecated: as of v2.5. Use BlendDestination instead.
|
||||
CompositeModeDestination
|
||||
|
||||
// c_out = c_src × (1 - α_dst) + c_dst
|
||||
// Deprecated: as of v2.5. Use BlendDestinationOver instead.
|
||||
CompositeModeDestinationOver
|
||||
|
||||
// c_out = c_src × α_dst
|
||||
// Deprecated: as of v2.5. Use BlendSourceIn instead.
|
||||
CompositeModeSourceIn
|
||||
|
||||
// c_out = c_dst × α_src
|
||||
// Deprecated: as of v2.5. Use BlendDestinationIn instead.
|
||||
CompositeModeDestinationIn
|
||||
|
||||
// c_out = c_src × (1 - α_dst)
|
||||
// Deprecated: as of v2.5. Use BlendSourceOut instead.
|
||||
CompositeModeSourceOut
|
||||
|
||||
// c_out = c_dst × (1 - α_src)
|
||||
// Deprecated: as of v2.5. Use BlendDestinationOut instead.
|
||||
CompositeModeDestinationOut
|
||||
|
||||
// c_out = c_src × α_dst + c_dst × (1 - α_src)
|
||||
// Deprecated: as of v2.5. Use BlendSourceAtop instead.
|
||||
CompositeModeSourceAtop
|
||||
|
||||
// c_out = c_src × (1 - α_dst) + c_dst × α_src
|
||||
// Deprecated: as of v2.5. Use BlendDestinationAtop instead.
|
||||
CompositeModeDestinationAtop
|
||||
|
||||
// c_out = c_src × (1 - α_dst) + c_dst × (1 - α_src)
|
||||
// Deprecated: as of v2.5. Use BlendXor instead.
|
||||
CompositeModeXor
|
||||
|
||||
// Sum of source and destination (a.k.a. 'plus' or 'additive')
|
||||
// c_out = c_src + c_dst
|
||||
// Deprecated: as of v2.5. Use BlendLighter instead.
|
||||
CompositeModeLighter
|
||||
|
||||
// The product of source and destination (a.k.a 'multiply blend mode')
|
||||
// c_out = c_src * c_dst
|
||||
// Deprecated: as of v2.5. Use Blend with BlendFactorDestinationColor and BlendFactorZero instead.
|
||||
CompositeModeMultiply
|
||||
)
|
||||
|
||||
func (c CompositeMode) blend() graphicsdriver.Blend {
|
||||
src, dst := c.blendFactors()
|
||||
return graphicsdriver.Blend{
|
||||
BlendFactorSourceColor: src,
|
||||
BlendFactorSourceAlpha: src,
|
||||
BlendFactorDestinationColor: dst,
|
||||
BlendFactorDestinationAlpha: dst,
|
||||
BlendOperationColor: graphicsdriver.BlendOperationAdd,
|
||||
BlendOperationAlpha: graphicsdriver.BlendOperationAdd,
|
||||
}
|
||||
}
|
||||
|
||||
func (c CompositeMode) blendFactors() (src graphicsdriver.BlendFactor, dst graphicsdriver.BlendFactor) {
|
||||
func (c CompositeMode) blend() Blend {
|
||||
switch c {
|
||||
case CompositeModeSourceOver:
|
||||
return graphicsdriver.BlendFactorOne, graphicsdriver.BlendFactorOneMinusSourceAlpha
|
||||
return BlendSourceOver
|
||||
case CompositeModeClear:
|
||||
return graphicsdriver.BlendFactorZero, graphicsdriver.BlendFactorZero
|
||||
return BlendClear
|
||||
case CompositeModeCopy:
|
||||
return graphicsdriver.BlendFactorOne, graphicsdriver.BlendFactorZero
|
||||
return BlendCopy
|
||||
case CompositeModeDestination:
|
||||
return graphicsdriver.BlendFactorZero, graphicsdriver.BlendFactorOne
|
||||
return BlendDestination
|
||||
case CompositeModeDestinationOver:
|
||||
return graphicsdriver.BlendFactorOneMinusDestinationAlpha, graphicsdriver.BlendFactorOne
|
||||
return BlendDestinationOver
|
||||
case CompositeModeSourceIn:
|
||||
return graphicsdriver.BlendFactorDestinationAlpha, graphicsdriver.BlendFactorZero
|
||||
return BlendSourceIn
|
||||
case CompositeModeDestinationIn:
|
||||
return graphicsdriver.BlendFactorZero, graphicsdriver.BlendFactorSourceAlpha
|
||||
return BlendDestinationIn
|
||||
case CompositeModeSourceOut:
|
||||
return graphicsdriver.BlendFactorOneMinusDestinationAlpha, graphicsdriver.BlendFactorZero
|
||||
return BlendSourceOut
|
||||
case CompositeModeDestinationOut:
|
||||
return graphicsdriver.BlendFactorZero, graphicsdriver.BlendFactorOneMinusSourceAlpha
|
||||
return BlendDestinationOut
|
||||
case CompositeModeSourceAtop:
|
||||
return graphicsdriver.BlendFactorDestinationAlpha, graphicsdriver.BlendFactorOneMinusSourceAlpha
|
||||
return BlendSourceAtop
|
||||
case CompositeModeDestinationAtop:
|
||||
return graphicsdriver.BlendFactorOneMinusDestinationAlpha, graphicsdriver.BlendFactorSourceAlpha
|
||||
return BlendDestinationAtop
|
||||
case CompositeModeXor:
|
||||
return graphicsdriver.BlendFactorOneMinusDestinationAlpha, graphicsdriver.BlendFactorOneMinusSourceAlpha
|
||||
return BlendXor
|
||||
case CompositeModeLighter:
|
||||
return graphicsdriver.BlendFactorOne, graphicsdriver.BlendFactorOne
|
||||
return BlendLighter
|
||||
case CompositeModeMultiply:
|
||||
return graphicsdriver.BlendFactorDestinationColor, graphicsdriver.BlendFactorZero
|
||||
return Blend{
|
||||
BlendFactorSourceColor: BlendFactorDestinationColor,
|
||||
BlendFactorSourceAlpha: BlendFactorDestinationColor,
|
||||
BlendFactorDestinationColor: BlendFactorZero,
|
||||
BlendFactorDestinationAlpha: BlendFactorZero,
|
||||
BlendOperationColor: BlendOperationAdd,
|
||||
BlendOperationAlpha: BlendOperationAdd,
|
||||
}
|
||||
default:
|
||||
panic(fmt.Sprintf("ebiten: invalid composite mode: %d", c))
|
||||
}
|
||||
|
66
image.go
66
image.go
@ -115,9 +115,16 @@ type DrawImageOptions struct {
|
||||
ColorM ColorM
|
||||
|
||||
// CompositeMode is a composite mode to draw.
|
||||
// The default (zero) value is regular alpha blending.
|
||||
// The default (zero) value is CompositeModeCustom (Blend is used).
|
||||
//
|
||||
// Deprecated: as of v2.5. Use Blend instead.
|
||||
CompositeMode CompositeMode
|
||||
|
||||
// Blend is a blending way of the source color and the destination color.
|
||||
// Blend is used only when CompositeMode is CompositeModeCustom.
|
||||
// The default (zero) value is the regular alpha blending.
|
||||
Blend Blend
|
||||
|
||||
// Filter is a type of texture filter.
|
||||
// The default (zero) value is FilterNearest.
|
||||
Filter Filter
|
||||
@ -187,7 +194,7 @@ func (i *Image) adjustedRegion() graphicsdriver.Region {
|
||||
// - If only (*ColorM).Scale is applied to a ColorM, the ColorM has only
|
||||
// diagonal elements. The other ColorM functions might modify the other
|
||||
// elements.
|
||||
// - All CompositeMode values are same
|
||||
// - All CompositeMode/Blend values are same
|
||||
// - All Filter values are same
|
||||
//
|
||||
// Even when all the above conditions are satisfied, multiple draw commands can
|
||||
@ -215,7 +222,12 @@ func (i *Image) DrawImage(img *Image, options *DrawImageOptions) {
|
||||
options = &DrawImageOptions{}
|
||||
}
|
||||
|
||||
blend := options.CompositeMode.blend()
|
||||
var blend graphicsdriver.Blend
|
||||
if options.CompositeMode == CompositeModeCustom {
|
||||
blend = options.Blend.internalBlend()
|
||||
} else {
|
||||
blend = options.CompositeMode.blend().internalBlend()
|
||||
}
|
||||
filter := builtinshader.Filter(options.Filter)
|
||||
|
||||
if offsetX, offsetY := i.adjustPosition(0, 0); offsetX != 0 || offsetY != 0 {
|
||||
@ -327,9 +339,16 @@ type DrawTrianglesOptions struct {
|
||||
ColorScaleFormat ColorScaleFormat
|
||||
|
||||
// CompositeMode is a composite mode to draw.
|
||||
// The default (zero) value is regular alpha blending.
|
||||
// The default (zero) value is CompositeModeCustom (Blend is used).
|
||||
//
|
||||
// Deprecated: as of v2.5. Use Blend instead.
|
||||
CompositeMode CompositeMode
|
||||
|
||||
// Blend is a blending way of the source color and the destination color.
|
||||
// Blend is used only when CompositeMode is CompositeModeCustom.
|
||||
// The default (zero) value is the regular alpha blending.
|
||||
Blend Blend
|
||||
|
||||
// Filter is a type of texture filter.
|
||||
// The default (zero) value is FilterNearest.
|
||||
Filter Filter
|
||||
@ -396,7 +415,12 @@ func (i *Image) DrawTriangles(vertices []Vertex, indices []uint16, img *Image, o
|
||||
options = &DrawTrianglesOptions{}
|
||||
}
|
||||
|
||||
blend := options.CompositeMode.blend()
|
||||
var blend graphicsdriver.Blend
|
||||
if options.CompositeMode == CompositeModeCustom {
|
||||
blend = options.Blend.internalBlend()
|
||||
} else {
|
||||
blend = options.CompositeMode.blend().internalBlend()
|
||||
}
|
||||
|
||||
address := builtinshader.Address(options.Address)
|
||||
var sr graphicsdriver.Region
|
||||
@ -461,9 +485,16 @@ func (i *Image) DrawTriangles(vertices []Vertex, indices []uint16, img *Image, o
|
||||
// DrawTrianglesShaderOptions represents options for DrawTrianglesShader.
|
||||
type DrawTrianglesShaderOptions struct {
|
||||
// CompositeMode is a composite mode to draw.
|
||||
// The default (zero) value is regular alpha blending.
|
||||
// The default (zero) value is CompositeModeCustom (Blend is used).
|
||||
//
|
||||
// Deprecated: as of v2.5. Use Blend instead.
|
||||
CompositeMode CompositeMode
|
||||
|
||||
// Blend is a blending way of the source color and the destination color.
|
||||
// Blend is used only when CompositeMode is CompositeModeCustom.
|
||||
// The default (zero) value is the regular alpha blending.
|
||||
Blend Blend
|
||||
|
||||
// Uniforms is a set of uniform variables for the shader.
|
||||
// The keys are the names of the uniform variables.
|
||||
// The values must be float or []float.
|
||||
@ -525,7 +556,12 @@ func (i *Image) DrawTrianglesShader(vertices []Vertex, indices []uint16, shader
|
||||
options = &DrawTrianglesShaderOptions{}
|
||||
}
|
||||
|
||||
blend := options.CompositeMode.blend()
|
||||
var blend graphicsdriver.Blend
|
||||
if options.CompositeMode == CompositeModeCustom {
|
||||
blend = options.Blend.internalBlend()
|
||||
} else {
|
||||
blend = options.CompositeMode.blend().internalBlend()
|
||||
}
|
||||
|
||||
vs := graphics.Vertices(len(vertices))
|
||||
dst := i
|
||||
@ -604,9 +640,16 @@ type DrawRectShaderOptions struct {
|
||||
ColorScale ColorScale
|
||||
|
||||
// CompositeMode is a composite mode to draw.
|
||||
// The default (zero) value is regular alpha blending.
|
||||
// The default (zero) value is CompositeModeCustom (Blend is used).
|
||||
//
|
||||
// Deprecated: as of v2.5. Use Blend instead.
|
||||
CompositeMode CompositeMode
|
||||
|
||||
// Blend is a blending way of the source color and the destination color.
|
||||
// Blend is used only when CompositeMode is CompositeModeCustom.
|
||||
// The default (zero) value is the regular alpha blending.
|
||||
Blend Blend
|
||||
|
||||
// Uniforms is a set of uniform variables for the shader.
|
||||
// The keys are the names of the uniform variables.
|
||||
// The values must be float or []float.
|
||||
@ -645,7 +688,12 @@ func (i *Image) DrawRectShader(width, height int, shader *Shader, options *DrawR
|
||||
options = &DrawRectShaderOptions{}
|
||||
}
|
||||
|
||||
blend := options.CompositeMode.blend()
|
||||
var blend graphicsdriver.Blend
|
||||
if options.CompositeMode == CompositeModeCustom {
|
||||
blend = options.Blend.internalBlend()
|
||||
} else {
|
||||
blend = options.CompositeMode.blend().internalBlend()
|
||||
}
|
||||
|
||||
var imgs [graphics.ShaderImageCount]*ui.Image
|
||||
for i, img := range options.Images {
|
||||
|
@ -342,7 +342,7 @@ func min(a, b int) int {
|
||||
return b
|
||||
}
|
||||
|
||||
func TestImageCompositeModeLighter(t *testing.T) {
|
||||
func TestImageBlendLighter(t *testing.T) {
|
||||
img0, _, err := openEbitenImage()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
@ -353,7 +353,7 @@ func TestImageCompositeModeLighter(t *testing.T) {
|
||||
img1 := ebiten.NewImage(w, h)
|
||||
img1.Fill(color.RGBA{0x01, 0x02, 0x03, 0x04})
|
||||
op := &ebiten.DrawImageOptions{}
|
||||
op.CompositeMode = ebiten.CompositeModeLighter
|
||||
op.Blend = ebiten.BlendLighter
|
||||
img1.DrawImage(img0, op)
|
||||
for j := 0; j < img1.Bounds().Size().Y; j++ {
|
||||
for i := 0; i < img1.Bounds().Size().X; i++ {
|
||||
@ -2343,7 +2343,7 @@ func TestImageColorMCopy(t *testing.T) {
|
||||
for k := 0; k < 256; k++ {
|
||||
op := &ebiten.DrawImageOptions{}
|
||||
op.ColorM.Translate(1, 1, 1, float64(k)/0xff)
|
||||
op.CompositeMode = ebiten.CompositeModeCopy
|
||||
op.Blend = ebiten.BlendCopy
|
||||
dst.DrawImage(src, op)
|
||||
|
||||
for j := 0; j < h; j++ {
|
||||
|
4
internal/processtest/testdata/issue1753.go
vendored
4
internal/processtest/testdata/issue1753.go
vendored
@ -48,7 +48,7 @@ func Fragment(position vec4, texCoord vec2, color vec4) vec4 {
|
||||
g.dst = ebiten.NewImage(w, h)
|
||||
|
||||
op := &ebiten.DrawRectShaderOptions{}
|
||||
op.CompositeMode = ebiten.CompositeModeCopy
|
||||
op.Blend = ebiten.BlendCopy
|
||||
op.Uniforms = map[string]interface{}{
|
||||
"Color": []float32{1, 1, 1, 1},
|
||||
}
|
||||
@ -78,7 +78,7 @@ func Fragment(position vec4, texCoord vec2, color vec4) vec4 {
|
||||
}
|
||||
|
||||
op := &ebiten.DrawRectShaderOptions{}
|
||||
op.CompositeMode = ebiten.CompositeModeCopy
|
||||
op.Blend = ebiten.BlendCopy
|
||||
op.Uniforms = map[string]interface{}{
|
||||
"Dummy": float32(0),
|
||||
"R": float32(0.5),
|
||||
|
Loading…
Reference in New Issue
Block a user