mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-11-10 04:57:26 +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)
|
sy0 := float32(bounds.Min.Y)
|
||||||
sx1 := float32(bounds.Max.X)
|
sx1 := float32(bounds.Max.X)
|
||||||
sy1 := float32(bounds.Max.Y)
|
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()
|
is := graphics.QuadIndices()
|
||||||
|
|
||||||
srcs := [graphics.ShaderImageNum]*ui.Image{img.image}
|
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.
|
// 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)
|
filter := graphicsdriver.Filter(options.Filter)
|
||||||
|
|
||||||
|
colorm, cr, cg, cb, ca := colorMToScale(options.ColorM.affineColorM())
|
||||||
|
|
||||||
vs := graphics.Vertices(len(vertices))
|
vs := graphics.Vertices(len(vertices))
|
||||||
for i, v := range vertices {
|
for i, v := range vertices {
|
||||||
vs[i*graphics.VertexFloatNum] = v.DstX
|
vs[i*graphics.VertexFloatNum] = v.DstX
|
||||||
vs[i*graphics.VertexFloatNum+1] = v.DstY
|
vs[i*graphics.VertexFloatNum+1] = v.DstY
|
||||||
vs[i*graphics.VertexFloatNum+2] = v.SrcX
|
vs[i*graphics.VertexFloatNum+2] = v.SrcX
|
||||||
vs[i*graphics.VertexFloatNum+3] = v.SrcY
|
vs[i*graphics.VertexFloatNum+3] = v.SrcY
|
||||||
vs[i*graphics.VertexFloatNum+4] = v.ColorR
|
vs[i*graphics.VertexFloatNum+4] = v.ColorR * cr
|
||||||
vs[i*graphics.VertexFloatNum+5] = v.ColorG
|
vs[i*graphics.VertexFloatNum+5] = v.ColorG * cg
|
||||||
vs[i*graphics.VertexFloatNum+6] = v.ColorB
|
vs[i*graphics.VertexFloatNum+6] = v.ColorB * cb
|
||||||
vs[i*graphics.VertexFloatNum+7] = v.ColorA
|
vs[i*graphics.VertexFloatNum+7] = v.ColorA * ca
|
||||||
}
|
}
|
||||||
is := make([]uint16, len(indices))
|
is := make([]uint16, len(indices))
|
||||||
copy(is, indices)
|
copy(is, indices)
|
||||||
|
|
||||||
srcs := [graphics.ShaderImageNum]*ui.Image{img.image}
|
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.
|
// DrawTrianglesShaderOptions represents options for DrawTrianglesShader.
|
||||||
@ -828,3 +831,44 @@ func NewImageFromImage(source image.Image) *Image {
|
|||||||
i.ReplacePixels(imageToBytes(source))
|
i.ReplacePixels(imageToBytes(source))
|
||||||
return i
|
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)
|
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
|
var dx, dy float32
|
||||||
// A screen image doesn't have its padding.
|
// A screen image doesn't have its padding.
|
||||||
if !i.screen {
|
if !i.screen {
|
||||||
@ -477,10 +443,6 @@ func (i *Image) drawTriangles(srcs [graphics.ShaderImageNum]*Image, vertices []f
|
|||||||
vertices[i+1] += dy
|
vertices[i+1] += dy
|
||||||
vertices[i+2] += oxf
|
vertices[i+2] += oxf
|
||||||
vertices[i+3] += oyf
|
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
|
// srcRegion can be delibarately empty when this is not needed in order to avoid unexpected
|
||||||
// performance issue (#1293).
|
// 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 {
|
for i := 0; i < n; i += graphics.VertexFloatNum {
|
||||||
vertices[i] += dx
|
vertices[i] += dx
|
||||||
vertices[i+1] += dy
|
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