mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-12-25 11:18:54 +01:00
affine: Transpose ColorM implementation for optimization
This commit is contained in:
parent
9b361086d7
commit
f1f7e5bcec
@ -89,7 +89,7 @@ func (c *ColorM) ChangeHSV(hueTheta float64, saturationScale float64, valueScale
|
|||||||
func (c *ColorM) Element(i, j int) float64 {
|
func (c *ColorM) Element(i, j int) float64 {
|
||||||
b, t := c.impl.UnsafeElements()
|
b, t := c.impl.UnsafeElements()
|
||||||
if j < ColorMDim-1 {
|
if j < ColorMDim-1 {
|
||||||
return float64(b[i*(ColorMDim-1)+j])
|
return float64(b[i+j*(ColorMDim-1)])
|
||||||
}
|
}
|
||||||
return float64(t[i])
|
return float64(t[i])
|
||||||
}
|
}
|
||||||
|
@ -45,7 +45,7 @@ var (
|
|||||||
type ColorM struct {
|
type ColorM struct {
|
||||||
// When elements is nil, this matrix is identity.
|
// When elements is nil, this matrix is identity.
|
||||||
// elements is immutable and a new array must be created when updating.
|
// elements is immutable and a new array must be created when updating.
|
||||||
body []float32 // TODO: Transpose this to pass this OpenGL easily
|
body []float32
|
||||||
translate []float32
|
translate []float32
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -79,10 +79,10 @@ func (c *ColorM) Apply(clr color.Color) color.Color {
|
|||||||
af := float32(a) / 0xffff
|
af := float32(a) / 0xffff
|
||||||
eb := c.body
|
eb := c.body
|
||||||
et := c.translate
|
et := c.translate
|
||||||
rf2 := eb[0]*rf + eb[1]*gf + eb[2]*bf + eb[3]*af + et[0]
|
rf2 := eb[0]*rf + eb[4]*gf + eb[8]*bf + eb[12]*af + et[0]
|
||||||
gf2 := eb[4]*rf + eb[5]*gf + eb[6]*bf + eb[7]*af + et[1]
|
gf2 := eb[1]*rf + eb[5]*gf + eb[9]*bf + eb[13]*af + et[1]
|
||||||
bf2 := eb[8]*rf + eb[9]*gf + eb[10]*bf + eb[11]*af + et[2]
|
bf2 := eb[2]*rf + eb[6]*gf + eb[10]*bf + eb[14]*af + et[2]
|
||||||
af2 := eb[12]*rf + eb[13]*gf + eb[14]*bf + eb[15]*af + et[3]
|
af2 := eb[3]*rf + eb[7]*gf + eb[11]*bf + eb[15]*af + et[3]
|
||||||
rf2 = clamp(rf2)
|
rf2 = clamp(rf2)
|
||||||
gf2 = clamp(gf2)
|
gf2 = clamp(gf2)
|
||||||
bf2 = clamp(bf2)
|
bf2 = clamp(bf2)
|
||||||
@ -112,7 +112,7 @@ func (c *ColorM) SetElement(i, j int, element float32) {
|
|||||||
if j < (ColorMDim - 1) {
|
if j < (ColorMDim - 1) {
|
||||||
es := make([]float32, len(c.body))
|
es := make([]float32, len(c.body))
|
||||||
copy(es, c.body)
|
copy(es, c.body)
|
||||||
es[i*(ColorMDim-1)+j] = element
|
es[i+j*(ColorMDim-1)] = element
|
||||||
c.body = es
|
c.body = es
|
||||||
} else {
|
} else {
|
||||||
es := make([]float32, len(c.translate))
|
es := make([]float32, len(c.translate))
|
||||||
@ -158,16 +158,18 @@ func (c *ColorM) Concat(other *ColorM) {
|
|||||||
other.body = colorMIdentityBody
|
other.body = colorMIdentityBody
|
||||||
other.translate = colorMIdentityTranslate
|
other.translate = colorMIdentityTranslate
|
||||||
}
|
}
|
||||||
c.body = mulSquare(other.body, c.body, ColorMDim-1)
|
// TODO: This is a temporary hack to calculate multiply of transposed matrices.
|
||||||
|
// Fix mulSquare implmentation and swap the arguments.
|
||||||
|
c.body = mulSquare(c.body, other.body, ColorMDim-1)
|
||||||
|
|
||||||
lhsb := other.body
|
lhsb := other.body
|
||||||
lhst := other.translate
|
lhst := other.translate
|
||||||
rhst := c.translate
|
rhst := c.translate
|
||||||
c.translate = []float32{
|
c.translate = []float32{
|
||||||
lhsb[0]*rhst[0] + lhsb[1]*rhst[1] + lhsb[2]*rhst[2] + lhsb[3]*rhst[3] + lhst[0],
|
lhsb[0]*rhst[0] + lhsb[4]*rhst[1] + lhsb[8]*rhst[2] + lhsb[12]*rhst[3] + lhst[0],
|
||||||
lhsb[4]*rhst[0] + lhsb[5]*rhst[1] + lhsb[6]*rhst[2] + lhsb[7]*rhst[3] + lhst[1],
|
lhsb[1]*rhst[0] + lhsb[5]*rhst[1] + lhsb[9]*rhst[2] + lhsb[13]*rhst[3] + lhst[1],
|
||||||
lhsb[8]*rhst[0] + lhsb[9]*rhst[1] + lhsb[10]*rhst[2] + lhsb[11]*rhst[3] + lhst[2],
|
lhsb[2]*rhst[0] + lhsb[6]*rhst[1] + lhsb[10]*rhst[2] + lhsb[14]*rhst[3] + lhst[2],
|
||||||
lhsb[12]*rhst[0] + lhsb[13]*rhst[1] + lhsb[14]*rhst[2] + lhsb[15]*rhst[3] + lhst[3],
|
lhsb[3]*rhst[0] + lhsb[7]*rhst[1] + lhsb[11]*rhst[2] + lhsb[15]*rhst[3] + lhst[3],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -212,10 +214,10 @@ func (c *ColorM) Scale(r, g, b, a float32) {
|
|||||||
es := make([]float32, len(c.body))
|
es := make([]float32, len(c.body))
|
||||||
copy(es, c.body)
|
copy(es, c.body)
|
||||||
for i := 0; i < ColorMDim-1; i++ {
|
for i := 0; i < ColorMDim-1; i++ {
|
||||||
es[i] *= r
|
es[i*(ColorMDim-1)] *= r
|
||||||
es[i+(ColorMDim-1)] *= g
|
es[i*(ColorMDim-1)+1] *= g
|
||||||
es[i+(ColorMDim-1)*2] *= b
|
es[i*(ColorMDim-1)+2] *= b
|
||||||
es[i+(ColorMDim-1)*3] *= a
|
es[i*(ColorMDim-1)+3] *= a
|
||||||
}
|
}
|
||||||
c.body = es
|
c.body = es
|
||||||
|
|
||||||
@ -251,18 +253,18 @@ var (
|
|||||||
|
|
||||||
rgbToYCbCr = ColorM{
|
rgbToYCbCr = ColorM{
|
||||||
body: []float32{
|
body: []float32{
|
||||||
0.2990, 0.5870, 0.1140, 0,
|
0.2990, -0.1687, 0.5000, 0,
|
||||||
-0.1687, -0.3313, 0.5000, 0,
|
0.5870, -0.3313, -0.4187, 0,
|
||||||
0.5000, -0.4187, -0.0813, 0,
|
0.1140, 0.5000, -0.0813, 0,
|
||||||
0, 0, 0, 1,
|
0, 0, 0, 1,
|
||||||
},
|
},
|
||||||
translate: []float32{0, 0, 0, 0},
|
translate: []float32{0, 0, 0, 0},
|
||||||
}
|
}
|
||||||
yCbCrToRgb = ColorM{
|
yCbCrToRgb = ColorM{
|
||||||
body: []float32{
|
body: []float32{
|
||||||
1, 0, 1.40200, 0,
|
1, 1, 1, 0,
|
||||||
1, -0.34414, -0.71414, 0,
|
0, -0.34414, 1.77200, 0,
|
||||||
1, 1.77200, 0, 0,
|
1.40200, -0.71414, 0, 0,
|
||||||
0, 0, 0, 1,
|
0, 0, 0, 1,
|
||||||
},
|
},
|
||||||
translate: []float32{0, 0, 0, 0},
|
translate: []float32{0, 0, 0, 0},
|
||||||
@ -282,8 +284,8 @@ func (c *ColorM) ChangeHSV(hueTheta float64, saturationScale float32, valueScale
|
|||||||
c.Concat(&ColorM{
|
c.Concat(&ColorM{
|
||||||
body: []float32{
|
body: []float32{
|
||||||
1, 0, 0, 0,
|
1, 0, 0, 0,
|
||||||
0, c32, -s32, 0,
|
0, c32, s32, 0,
|
||||||
0, s32, c32, 0,
|
0, -s32, c32, 0,
|
||||||
0, 0, 0, 1,
|
0, 0, 0, 1,
|
||||||
},
|
},
|
||||||
translate: []float32{0, 0, 0, 0},
|
translate: []float32{0, 0, 0, 0},
|
||||||
|
@ -266,19 +266,12 @@ func (s *openGLState) useProgram(proj []float32, texture opengl.Texture, sourceW
|
|||||||
|
|
||||||
esBody, esTranslate := colorM.UnsafeElements()
|
esBody, esTranslate := colorM.UnsafeElements()
|
||||||
|
|
||||||
// transpose
|
if !areSameFloat32Array(s.lastColorMatrix, esBody) {
|
||||||
colorMatrix := make([]float32, (affine.ColorMDim-1)*(affine.ColorMDim-1))
|
c.UniformFloats(program, "color_matrix", esBody)
|
||||||
for i := 0; i < affine.ColorMDim-1; i++ {
|
|
||||||
for j := 0; j < affine.ColorMDim-1; j++ {
|
|
||||||
colorMatrix[i+j*(affine.ColorMDim-1)] = float32(esBody[i*(affine.ColorMDim-1)+j])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if !areSameFloat32Array(s.lastColorMatrix, colorMatrix) {
|
|
||||||
c.UniformFloats(program, "color_matrix", colorMatrix)
|
|
||||||
if s.lastColorMatrix == nil {
|
if s.lastColorMatrix == nil {
|
||||||
s.lastColorMatrix = make([]float32, 16)
|
s.lastColorMatrix = make([]float32, 16)
|
||||||
}
|
}
|
||||||
copy(s.lastColorMatrix, colorMatrix)
|
copy(s.lastColorMatrix, esBody)
|
||||||
}
|
}
|
||||||
if !areSameFloat32Array(s.lastColorMatrixTranslation, esTranslate) {
|
if !areSameFloat32Array(s.lastColorMatrixTranslation, esTranslate) {
|
||||||
c.UniformFloats(program, "color_matrix_translation", esTranslate)
|
c.UniformFloats(program, "color_matrix_translation", esTranslate)
|
||||||
|
Loading…
Reference in New Issue
Block a user