mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-12-25 03:08:54 +01:00
internal/graphicsdriver/directx, internal/graphicsdriver/metal: bug fix: uniform matrix-array variables were passed wrongly
Updates #2036
This commit is contained in:
parent
eaad959472
commit
6bd3c81e27
@ -1682,24 +1682,37 @@ func (s *Shader) uniformsToFloat32s(uniforms [][]float32) []float32 {
|
|||||||
fs = append(fs, u...)
|
fs = append(fs, u...)
|
||||||
case shaderir.Mat2:
|
case shaderir.Mat2:
|
||||||
for j := 0; j < t.Length; j++ {
|
for j := 0; j < t.Length; j++ {
|
||||||
for k := 0; k < 2; k++ {
|
u1 := u[4*j : 4*(j+1)]
|
||||||
fs = append(fs, u[2*(2*j+k):2*(2*j+k+1)]...)
|
fs = append(fs,
|
||||||
if j < t.Length-1 || k < 1 {
|
u1[0], u1[2], 0, 0,
|
||||||
fs = append(fs, 0, 0)
|
u1[1], u1[3], 0, 0,
|
||||||
}
|
)
|
||||||
}
|
}
|
||||||
|
if t.Length > 0 {
|
||||||
|
fs = fs[:len(fs)-2]
|
||||||
}
|
}
|
||||||
case shaderir.Mat3:
|
case shaderir.Mat3:
|
||||||
for j := 0; j < t.Length; j++ {
|
for j := 0; j < t.Length; j++ {
|
||||||
for k := 0; k < 3; k++ {
|
u1 := u[9*j : 9*(j+1)]
|
||||||
fs = append(fs, u[3*(3*j+k):3*(3*j+k+1)]...)
|
fs = append(fs,
|
||||||
if j < t.Length-1 || k < 2 {
|
u1[0], u1[3], u1[6], 0,
|
||||||
fs = append(fs, 0)
|
u1[1], u1[4], u1[7], 0,
|
||||||
}
|
u1[2], u1[5], u1[8], 0,
|
||||||
}
|
)
|
||||||
|
}
|
||||||
|
if t.Length > 0 {
|
||||||
|
fs = fs[:len(fs)-1]
|
||||||
}
|
}
|
||||||
case shaderir.Mat4:
|
case shaderir.Mat4:
|
||||||
fs = append(fs, u...)
|
for j := 0; j < t.Length; j++ {
|
||||||
|
u1 := u[16*j : 16*(j+1)]
|
||||||
|
fs = append(fs,
|
||||||
|
u1[0], u1[4], u1[8], u1[12],
|
||||||
|
u1[1], u1[5], u1[9], u1[13],
|
||||||
|
u1[2], u1[6], u1[10], u1[14],
|
||||||
|
u1[3], u1[7], u1[11], u1[15],
|
||||||
|
)
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
panic(fmt.Sprintf("directx: not implemented type for uniform variables: %s", t.String()))
|
panic(fmt.Sprintf("directx: not implemented type for uniform variables: %s", t.String()))
|
||||||
}
|
}
|
||||||
|
@ -998,14 +998,30 @@ func (g *Graphics) DrawTriangles(dstID graphicsdriver.ImageID, srcIDs [graphics.
|
|||||||
// Set the additional uniform variables.
|
// Set the additional uniform variables.
|
||||||
for i, v := range uniforms {
|
for i, v := range uniforms {
|
||||||
const offset = graphics.PreservedUniformVariablesNum
|
const offset = graphics.PreservedUniformVariablesNum
|
||||||
switch g.shaders[shaderID].ir.Uniforms[offset+i].Main {
|
t := g.shaders[shaderID].ir.Uniforms[offset+i]
|
||||||
|
switch t.Main {
|
||||||
case shaderir.Mat3:
|
case shaderir.Mat3:
|
||||||
// float3x3 requires 16-byte alignment (#2036).
|
// float3x3 requires 16-byte alignment (#2036).
|
||||||
newV := make([]float32, 12)
|
v1 := make([]float32, 12)
|
||||||
copy(newV[0:3], v[0:3])
|
copy(v1[0:3], v[0:3])
|
||||||
copy(newV[4:7], v[3:6])
|
copy(v1[4:7], v[3:6])
|
||||||
copy(newV[8:11], v[6:9])
|
copy(v1[8:11], v[6:9])
|
||||||
uniformVars[offset+i] = newV
|
uniformVars[offset+i] = v1
|
||||||
|
case shaderir.Array:
|
||||||
|
switch t.Sub[0].Main {
|
||||||
|
case shaderir.Mat3:
|
||||||
|
v1 := make([]float32, t.Length*12)
|
||||||
|
for j := 0; j < t.Length; j++ {
|
||||||
|
offset0 := j * 9
|
||||||
|
offset1 := j * 12
|
||||||
|
copy(v1[offset1:offset1+3], v[offset0:offset0+3])
|
||||||
|
copy(v1[offset1+4:offset1+7], v[offset0+3:offset0+6])
|
||||||
|
copy(v1[offset1+8:offset1+11], v[offset0+6:offset0+9])
|
||||||
|
}
|
||||||
|
uniformVars[offset+i] = v1
|
||||||
|
default:
|
||||||
|
uniformVars[offset+i] = v
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
uniformVars[offset+i] = v
|
uniformVars[offset+i] = v
|
||||||
}
|
}
|
||||||
|
120
shader_test.go
120
shader_test.go
@ -763,6 +763,44 @@ func Fragment(position vec4, texCoord vec2, color vec4) vec4 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestShaderUniformMatrix2Array(t *testing.T) {
|
||||||
|
const w, h = 16, 16
|
||||||
|
|
||||||
|
dst := ebiten.NewImage(w, h)
|
||||||
|
s, err := ebiten.NewShader([]byte(`package main
|
||||||
|
|
||||||
|
var Mat2 [2]mat2
|
||||||
|
|
||||||
|
func Fragment(position vec4, texCoord vec2, color vec4) vec4 {
|
||||||
|
return vec4(256 * Mat2[0] * Mat2[1] * vec2(1), 1, 1)
|
||||||
|
}
|
||||||
|
`))
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
op := &ebiten.DrawRectShaderOptions{}
|
||||||
|
op.Uniforms = map[string]interface{}{
|
||||||
|
"Mat2": []float32{
|
||||||
|
1.0 / 256.0, 2.0 / 256.0,
|
||||||
|
3.0 / 256.0, 4.0 / 256.0,
|
||||||
|
5.0 / 256.0, 6.0 / 256.0,
|
||||||
|
7.0 / 256.0, 8.0 / 256.0,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
dst.DrawRectShader(w, h, s, op)
|
||||||
|
|
||||||
|
for j := 0; j < h; j++ {
|
||||||
|
for i := 0; i < w; i++ {
|
||||||
|
got := dst.At(i, j).(color.RGBA)
|
||||||
|
want := color.RGBA{54, 80, 0xff, 0xff}
|
||||||
|
if !sameColors(got, want, 2) {
|
||||||
|
t.Errorf("dst.At(%d, %d): got: %v, want: %v", i, j, got, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestShaderUniformMatrix3(t *testing.T) {
|
func TestShaderUniformMatrix3(t *testing.T) {
|
||||||
const w, h = 16, 16
|
const w, h = 16, 16
|
||||||
|
|
||||||
@ -800,6 +838,46 @@ func Fragment(position vec4, texCoord vec2, color vec4) vec4 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestShaderUniformMatrix3Array(t *testing.T) {
|
||||||
|
const w, h = 16, 16
|
||||||
|
|
||||||
|
dst := ebiten.NewImage(w, h)
|
||||||
|
s, err := ebiten.NewShader([]byte(`package main
|
||||||
|
|
||||||
|
var Mat3 [2]mat3
|
||||||
|
|
||||||
|
func Fragment(position vec4, texCoord vec2, color vec4) vec4 {
|
||||||
|
return vec4(3 * Mat3[0] * Mat3[1] * vec3(1), 1)
|
||||||
|
}
|
||||||
|
`))
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
op := &ebiten.DrawRectShaderOptions{}
|
||||||
|
op.Uniforms = map[string]interface{}{
|
||||||
|
"Mat3": []float32{
|
||||||
|
1.0 / 256.0, 2.0 / 256.0, 3.0 / 256.0,
|
||||||
|
4.0 / 256.0, 5.0 / 256.0, 6.0 / 256.0,
|
||||||
|
7.0 / 256.0, 8.0 / 256.0, 9.0 / 256.0,
|
||||||
|
10.0 / 256.0, 11.0 / 256.0, 12.0 / 256.0,
|
||||||
|
13.0 / 256.0, 14.0 / 256.0, 15.0 / 256.0,
|
||||||
|
16.0 / 256.0, 17.0 / 256.0, 18.0 / 256.0,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
dst.DrawRectShader(w, h, s, op)
|
||||||
|
|
||||||
|
for j := 0; j < h; j++ {
|
||||||
|
for i := 0; i < w; i++ {
|
||||||
|
got := dst.At(i, j).(color.RGBA)
|
||||||
|
want := color.RGBA{6, 8, 9, 0xff}
|
||||||
|
if !sameColors(got, want, 2) {
|
||||||
|
t.Errorf("dst.At(%d, %d): got: %v, want: %v", i, j, got, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestShaderUniformMatrix4(t *testing.T) {
|
func TestShaderUniformMatrix4(t *testing.T) {
|
||||||
const w, h = 16, 16
|
const w, h = 16, 16
|
||||||
|
|
||||||
@ -837,3 +915,45 @@ func Fragment(position vec4, texCoord vec2, color vec4) vec4 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestShaderUniformMatrix4Array(t *testing.T) {
|
||||||
|
const w, h = 16, 16
|
||||||
|
|
||||||
|
dst := ebiten.NewImage(w, h)
|
||||||
|
s, err := ebiten.NewShader([]byte(`package main
|
||||||
|
|
||||||
|
var Mat4 [2]mat4
|
||||||
|
|
||||||
|
func Fragment(position vec4, texCoord vec2, color vec4) vec4 {
|
||||||
|
return Mat4[0] * Mat4[1] * vec4(1)
|
||||||
|
}
|
||||||
|
`))
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
op := &ebiten.DrawRectShaderOptions{}
|
||||||
|
op.Uniforms = map[string]interface{}{
|
||||||
|
"Mat4": []float32{
|
||||||
|
1.0 / 256.0, 2.0 / 256.0, 3.0 / 256.0, 4.0 / 256.0,
|
||||||
|
5.0 / 256.0, 6.0 / 256.0, 7.0 / 256.0, 8.0 / 256.0,
|
||||||
|
9.0 / 256.0, 10.0 / 256.0, 11.0 / 256.0, 12.0 / 256.0,
|
||||||
|
13.0 / 256.0, 14.0 / 256.0, 15.0 / 256.0, 16.0 / 256.0,
|
||||||
|
17.0 / 256.0, 18.0 / 256.0, 19.0 / 256.0, 20.0 / 256.0,
|
||||||
|
21.0 / 256.0, 22.0 / 256.0, 23.0 / 256.0, 24.0 / 256.0,
|
||||||
|
25.0 / 256.0, 26.0 / 256.0, 27.0 / 256.0, 28.0 / 256.0,
|
||||||
|
29.0 / 256.0, 30.0 / 256.0, 31.0 / 256.0, 32.0 / 256.0,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
dst.DrawRectShader(w, h, s, op)
|
||||||
|
|
||||||
|
for j := 0; j < h; j++ {
|
||||||
|
for i := 0; i < w; i++ {
|
||||||
|
got := dst.At(i, j).(color.RGBA)
|
||||||
|
want := color.RGBA{11, 13, 14, 16}
|
||||||
|
if !sameColors(got, want, 2) {
|
||||||
|
t.Errorf("dst.At(%d, %d): got: %v, want: %v", i, j, got, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user