mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-11-10 04:57:26 +01:00
internal/ui: add a length check for uniform variables
This commit is contained in:
parent
5ddf1df423
commit
d0e4023d88
4
image.go
4
image.go
@ -577,6 +577,8 @@ var _ [len(DrawTrianglesShaderOptions{}.Images) - graphics.ShaderImageCount]stru
|
|||||||
//
|
//
|
||||||
// When a specified image is non-nil and is disposed, DrawTrianglesShader panics.
|
// When a specified image is non-nil and is disposed, DrawTrianglesShader panics.
|
||||||
//
|
//
|
||||||
|
// If a specified uniform variable's length or type doesn't match with an expected one, DrawTrianglesShader panics.
|
||||||
|
//
|
||||||
// When the image i is disposed, DrawTrianglesShader does nothing.
|
// When the image i is disposed, DrawTrianglesShader does nothing.
|
||||||
func (i *Image) DrawTrianglesShader(vertices []Vertex, indices []uint16, shader *Shader, options *DrawTrianglesShaderOptions) {
|
func (i *Image) DrawTrianglesShader(vertices []Vertex, indices []uint16, shader *Shader, options *DrawTrianglesShaderOptions) {
|
||||||
i.copyCheck()
|
i.copyCheck()
|
||||||
@ -724,6 +726,8 @@ var _ [len(DrawRectShaderOptions{}.Images)]struct{} = [graphics.ShaderImageCount
|
|||||||
//
|
//
|
||||||
// When one of the specified image is non-nil and is disposed, DrawRectShader panics.
|
// When one of the specified image is non-nil and is disposed, DrawRectShader panics.
|
||||||
//
|
//
|
||||||
|
// If a specified uniform variable's length or type doesn't match with an expected one, DrawRectShader panics.
|
||||||
|
//
|
||||||
// When the image i is disposed, DrawRectShader does nothing.
|
// When the image i is disposed, DrawRectShader does nothing.
|
||||||
func (i *Image) DrawRectShader(width, height int, shader *Shader, options *DrawRectShaderOptions) {
|
func (i *Image) DrawRectShader(width, height int, shader *Shader, options *DrawRectShaderOptions) {
|
||||||
i.copyCheck()
|
i.copyCheck()
|
||||||
|
@ -69,13 +69,25 @@ func (s *Shader) AppendUniforms(dst []uint32, uniforms map[string]any) []uint32
|
|||||||
t := v.Type()
|
t := v.Type()
|
||||||
switch t.Kind() {
|
switch t.Kind() {
|
||||||
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
||||||
|
if typ.Uint32Count() != 1 {
|
||||||
|
panic(fmt.Sprintf("ui: unexpected uniform value for %s (%s)", name, typ.String()))
|
||||||
|
}
|
||||||
dst[idx] = uint32(v.Int())
|
dst[idx] = uint32(v.Int())
|
||||||
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
|
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
|
||||||
|
if typ.Uint32Count() != 1 {
|
||||||
|
panic(fmt.Sprintf("ui: unexpected uniform value for %s (%s)", name, typ.String()))
|
||||||
|
}
|
||||||
dst[idx] = uint32(v.Uint())
|
dst[idx] = uint32(v.Uint())
|
||||||
case reflect.Float32, reflect.Float64:
|
case reflect.Float32, reflect.Float64:
|
||||||
|
if typ.Uint32Count() != 1 {
|
||||||
|
panic(fmt.Sprintf("ui: unexpected uniform value for %s (%s)", name, typ.String()))
|
||||||
|
}
|
||||||
dst[idx] = math.Float32bits(float32(v.Float()))
|
dst[idx] = math.Float32bits(float32(v.Float()))
|
||||||
case reflect.Slice, reflect.Array:
|
case reflect.Slice, reflect.Array:
|
||||||
l := v.Len()
|
l := v.Len()
|
||||||
|
if typ.Uint32Count() != l {
|
||||||
|
panic(fmt.Sprintf("ui: unexpected uniform value for %s (%s)", name, typ.String()))
|
||||||
|
}
|
||||||
switch t.Elem().Kind() {
|
switch t.Elem().Kind() {
|
||||||
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
||||||
for i := 0; i < l; i++ {
|
for i := 0; i < l; i++ {
|
||||||
|
106
shader_test.go
106
shader_test.go
@ -1854,3 +1854,109 @@ func Fragment(position vec4, texCoord vec2, color vec4) vec4 {
|
|||||||
t.Errorf("got: %v, want: %v", got, want)
|
t.Errorf("got: %v, want: %v", got, want)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestShaderUniformSizes(t *testing.T) {
|
||||||
|
const w, h = 16, 16
|
||||||
|
|
||||||
|
dst := ebiten.NewImage(w, h)
|
||||||
|
s, err := ebiten.NewShader([]byte(`//kage:unit pixel
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
var U vec4
|
||||||
|
var V [3]float
|
||||||
|
|
||||||
|
func Fragment(position vec4, texCoord vec2, color vec4) vec4 {
|
||||||
|
return vec4(0)
|
||||||
|
}
|
||||||
|
`))
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
tests := []struct {
|
||||||
|
uniforms map[string]any
|
||||||
|
err bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
uniforms: nil,
|
||||||
|
err: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
uniforms: map[string]any{
|
||||||
|
"U": 1,
|
||||||
|
},
|
||||||
|
err: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
uniforms: map[string]any{
|
||||||
|
"U": "1",
|
||||||
|
},
|
||||||
|
err: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
uniforms: map[string]any{
|
||||||
|
"U": []int32{1, 2, 3},
|
||||||
|
},
|
||||||
|
err: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
uniforms: map[string]any{
|
||||||
|
"U": []int32{1, 2, 3, 4},
|
||||||
|
},
|
||||||
|
err: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
uniforms: map[string]any{
|
||||||
|
"U": []int32{1, 2, 3, 4, 5},
|
||||||
|
},
|
||||||
|
err: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
uniforms: map[string]any{
|
||||||
|
"V": 1,
|
||||||
|
},
|
||||||
|
err: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
uniforms: map[string]any{
|
||||||
|
"V": "1",
|
||||||
|
},
|
||||||
|
err: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
uniforms: map[string]any{
|
||||||
|
"V": []int32{1, 2},
|
||||||
|
},
|
||||||
|
err: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
uniforms: map[string]any{
|
||||||
|
"V": []int32{1, 2, 3},
|
||||||
|
},
|
||||||
|
err: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
uniforms: map[string]any{
|
||||||
|
"V": []int32{1, 2, 3, 4},
|
||||||
|
},
|
||||||
|
err: true,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tc := range tests {
|
||||||
|
tc := tc
|
||||||
|
t.Run(fmt.Sprintf("%v", tc.uniforms), func(t *testing.T) {
|
||||||
|
defer func() {
|
||||||
|
r := recover()
|
||||||
|
if r != nil && !tc.err {
|
||||||
|
t.Errorf("DrawRectShader must not panic but did")
|
||||||
|
} else if r == nil && tc.err {
|
||||||
|
t.Errorf("DrawRectShader must panic but does not")
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
op := &ebiten.DrawRectShaderOptions{}
|
||||||
|
op.Uniforms = tc.uniforms
|
||||||
|
dst.DrawRectShader(w, h, s, op)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user