ebiten: add test for matrix indices

This commit is contained in:
Hajime Hoshi 2024-11-26 12:19:27 +09:00
parent 1ea14d5076
commit 800be4f772
3 changed files with 44 additions and 1 deletions

View File

@ -199,6 +199,9 @@ func constantBufferSize(uniformTypes []shaderir.Type, uniformOffsets []int) int
}
func adjustUniforms(uniformTypes []shaderir.Type, uniformOffsets []int, uniforms []uint32) []uint32 {
// Note that HLSL's matrices are row-major, while GLSL and MSL are column-major.
// Transpose matrices so that users can access matrix indices in the same way as GLSL and MSL.
var fs []uint32
var idx int
for i, typ := range uniformTypes {

View File

@ -909,11 +909,11 @@ func adjustUniformVariablesLayout(uniformTypes []shaderir.Type, uniforms []uint3
values = append(values, 0)
case shaderir.Mat4:
values = fillZerosToFitAlignment(values, 4)
u := uniforms[idx : idx+16]
if i == graphics.ProjectionMatrixUniformVariableIndex {
// In Metal, the NDC's Y direction (upward) and the framebuffer's Y direction (downward) don't
// match. Then, the Y direction must be inverted.
// Invert the sign bits as float32 values.
u := uniforms[idx : idx+16]
values = append(values,
u[0], u[1]^uint32(1<<31), u[2], u[3],
u[4], u[5]^uint32(1<<31), u[6], u[7],

View File

@ -1097,6 +1097,46 @@ func Fragment(dstPos vec4, srcPos vec2, color vec4) vec4 {
}
}
func TestShaderUniformMatrixIndexer(t *testing.T) {
const w, h = 16, 16
dst := ebiten.NewImage(w, h)
s, err := ebiten.NewShader([]byte(`//kage:unit pixels
package main
var Mat4 mat4
func Fragment(dstPos vec4, srcPos vec2, color vec4) vec4 {
return Mat4[1][2] * vec4(1)
}
`))
if err != nil {
t.Fatal(err)
}
op := &ebiten.DrawRectShaderOptions{}
op.Uniforms = map[string]any{
"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,
},
}
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{R: 7, G: 7, B: 7, A: 7}
if !sameColors(got, want, 2) {
t.Errorf("dst.At(%d, %d): got: %v, want: %v", i, j, got, want)
}
}
}
}
func TestShaderOptionsNegativeBounds(t *testing.T) {
const w, h = 16, 16