mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-12-26 03:38:55 +01:00
internal/atlas: move the color scaling from internal/atlas to ebiten
Updates #1820
This commit is contained in:
parent
5c7917897c
commit
0c6362c93a
58
image.go
58
image.go
@ -179,12 +179,13 @@ func (i *Image) DrawImage(img *Image, options *DrawImageOptions) {
|
||||
sy0 := float32(bounds.Min.Y)
|
||||
sx1 := float32(bounds.Max.X)
|
||||
sy1 := float32(bounds.Max.Y)
|
||||
vs := graphics.QuadVertices(sx0, sy0, sx1, sy1, a, b, c, d, tx, ty, 1, 1, 1, 1)
|
||||
colorm, cr, cg, cb, ca := colorMToScale(options.ColorM.affineColorM())
|
||||
vs := graphics.QuadVertices(sx0, sy0, sx1, sy1, a, b, c, d, tx, ty, cr, cg, cb, ca)
|
||||
is := graphics.QuadIndices()
|
||||
|
||||
srcs := [graphics.ShaderImageNum]*ui.Image{img.image}
|
||||
|
||||
i.image.DrawTriangles(srcs, vs, is, options.ColorM.affineColorM(), mode, filter, graphicsdriver.AddressUnsafe, dstRegion, graphicsdriver.Region{}, [graphics.ShaderImageNum - 1][2]float32{}, nil, nil, false, canSkipMipmap(options.GeoM, filter))
|
||||
i.image.DrawTriangles(srcs, vs, is, colorm, mode, filter, graphicsdriver.AddressUnsafe, dstRegion, graphicsdriver.Region{}, [graphics.ShaderImageNum - 1][2]float32{}, nil, nil, false, canSkipMipmap(options.GeoM, filter))
|
||||
}
|
||||
|
||||
// Vertex represents a vertex passed to DrawTriangles.
|
||||
@ -332,23 +333,25 @@ func (i *Image) DrawTriangles(vertices []Vertex, indices []uint16, img *Image, o
|
||||
|
||||
filter := graphicsdriver.Filter(options.Filter)
|
||||
|
||||
colorm, cr, cg, cb, ca := colorMToScale(options.ColorM.affineColorM())
|
||||
|
||||
vs := graphics.Vertices(len(vertices))
|
||||
for i, v := range vertices {
|
||||
vs[i*graphics.VertexFloatNum] = v.DstX
|
||||
vs[i*graphics.VertexFloatNum+1] = v.DstY
|
||||
vs[i*graphics.VertexFloatNum+2] = v.SrcX
|
||||
vs[i*graphics.VertexFloatNum+3] = v.SrcY
|
||||
vs[i*graphics.VertexFloatNum+4] = v.ColorR
|
||||
vs[i*graphics.VertexFloatNum+5] = v.ColorG
|
||||
vs[i*graphics.VertexFloatNum+6] = v.ColorB
|
||||
vs[i*graphics.VertexFloatNum+7] = v.ColorA
|
||||
vs[i*graphics.VertexFloatNum+4] = v.ColorR * cr
|
||||
vs[i*graphics.VertexFloatNum+5] = v.ColorG * cg
|
||||
vs[i*graphics.VertexFloatNum+6] = v.ColorB * cb
|
||||
vs[i*graphics.VertexFloatNum+7] = v.ColorA * ca
|
||||
}
|
||||
is := make([]uint16, len(indices))
|
||||
copy(is, indices)
|
||||
|
||||
srcs := [graphics.ShaderImageNum]*ui.Image{img.image}
|
||||
|
||||
i.image.DrawTriangles(srcs, vs, is, options.ColorM.affineColorM(), mode, filter, address, dstRegion, sr, [graphics.ShaderImageNum - 1][2]float32{}, nil, nil, options.FillRule == EvenOdd, false)
|
||||
i.image.DrawTriangles(srcs, vs, is, colorm, mode, filter, address, dstRegion, sr, [graphics.ShaderImageNum - 1][2]float32{}, nil, nil, options.FillRule == EvenOdd, false)
|
||||
}
|
||||
|
||||
// DrawTrianglesShaderOptions represents options for DrawTrianglesShader.
|
||||
@ -828,3 +831,44 @@ func NewImageFromImage(source image.Image) *Image {
|
||||
i.ReplacePixels(imageToBytes(source))
|
||||
return i
|
||||
}
|
||||
|
||||
// colorMToScale returns a new color matrix and color sclaes that equal to the given matrix in terms of the effect.
|
||||
//
|
||||
// If the given matrix is merely a scaling matrix, colorMToScale returns
|
||||
// an identity matrix and its scaling factors. This is useful to optimize
|
||||
// the rendering speed by avoiding the use of the color matrix and instead
|
||||
// multiplying all vertex colors by the scale.
|
||||
//
|
||||
// NOTE: this is only safe when not using a custom Kage shader,
|
||||
// as custom shaders may be using vertex colors for different purposes
|
||||
// than colorization. However, currently there are no Ebiten APIs that
|
||||
// support both shaders and color matrices.
|
||||
func colorMToScale(colorm affine.ColorM) (newColorM affine.ColorM, r, g, b, a float32) {
|
||||
if colorm.IsIdentity() {
|
||||
return colorm, 1, 1, 1, 1
|
||||
}
|
||||
|
||||
if !colorm.ScaleOnly() {
|
||||
return colorm, 1, 1, 1, 1
|
||||
}
|
||||
r = colorm.At(0, 0)
|
||||
g = colorm.At(1, 1)
|
||||
b = colorm.At(2, 2)
|
||||
a = colorm.At(3, 3)
|
||||
|
||||
// Color matrices work on non-premultiplied colors.
|
||||
// This color matrix can only make colors darker or equal,
|
||||
// and thus can never invoke color clamping.
|
||||
// Thus the simpler vertex color scale based shader can be used.
|
||||
//
|
||||
// Negative color values can become positive and out-of-range
|
||||
// after applying to vertex colors below, which can make the min() in the shader kick in.
|
||||
//
|
||||
// Alpha values smaller than 0, combined with negative vertex colors,
|
||||
// can also make the min() kick in, so that shall be ruled out too.
|
||||
if r < 0 || g < 0 || b < 0 || a < 0 || r > 1 || g > 1 || b > 1 {
|
||||
return colorm, 1, 1, 1, 1
|
||||
}
|
||||
|
||||
return affine.ColorMIdentity{}, r, g, b, a
|
||||
}
|
||||
|
@ -420,40 +420,6 @@ func (i *Image) drawTriangles(srcs [graphics.ShaderImageNum]*Image, vertices []f
|
||||
i.processSrc(src)
|
||||
}
|
||||
|
||||
// If a color matrix is used, but the matrix is merely a scaling matrix,
|
||||
// and the scaling cannot cause out-of-range colors, do not use a color matrix
|
||||
// when rendering but instead multiply all vertex colors by the scale.
|
||||
// This speeds up rendering.
|
||||
//
|
||||
// NOTE: this is only safe when not using a custom Kage shader,
|
||||
// as custom shaders may be using vertex colors for different purposes
|
||||
// than colorization. However, currently there are no Ebiten APIs that
|
||||
// support both shaders and color matrices.
|
||||
cr := float32(1)
|
||||
cg := float32(1)
|
||||
cb := float32(1)
|
||||
ca := float32(1)
|
||||
if !colorm.IsIdentity() && colorm.ScaleOnly() {
|
||||
r := colorm.At(0, 0)
|
||||
g := colorm.At(1, 1)
|
||||
b := colorm.At(2, 2)
|
||||
a := colorm.At(3, 3)
|
||||
if r >= 0 && g >= 0 && b >= 0 && a >= 0 && r <= 1 && g <= 1 && b <= 1 {
|
||||
// Color matrices work on non-premultiplied colors.
|
||||
// This color matrix can only make colors darker or equal,
|
||||
// and thus can never invoke color clamping.
|
||||
// Thus the simpler vertex color scale based shader can be used.
|
||||
//
|
||||
// Negative color values can become positive and out-of-range
|
||||
// after applying to vertex colors below, which can make the min() in the shader kick in.
|
||||
//
|
||||
// Alpha values smaller than 0, combined with negative vertex colors,
|
||||
// can also make the min() kick in, so that shall be ruled out too.
|
||||
cr, cg, cb, ca = r, g, b, a
|
||||
colorm = affine.ColorMIdentity{}
|
||||
}
|
||||
}
|
||||
|
||||
var dx, dy float32
|
||||
// A screen image doesn't have its padding.
|
||||
if !i.screen {
|
||||
@ -477,10 +443,6 @@ func (i *Image) drawTriangles(srcs [graphics.ShaderImageNum]*Image, vertices []f
|
||||
vertices[i+1] += dy
|
||||
vertices[i+2] += oxf
|
||||
vertices[i+3] += oyf
|
||||
vertices[i+4] *= cr
|
||||
vertices[i+5] *= cg
|
||||
vertices[i+6] *= cb
|
||||
vertices[i+7] *= ca
|
||||
}
|
||||
// srcRegion can be delibarately empty when this is not needed in order to avoid unexpected
|
||||
// performance issue (#1293).
|
||||
@ -493,10 +455,6 @@ func (i *Image) drawTriangles(srcs [graphics.ShaderImageNum]*Image, vertices []f
|
||||
for i := 0; i < n; i += graphics.VertexFloatNum {
|
||||
vertices[i] += dx
|
||||
vertices[i+1] += dy
|
||||
vertices[i+4] *= cr
|
||||
vertices[i+5] *= cg
|
||||
vertices[i+6] *= cb
|
||||
vertices[i+7] *= ca
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user