mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-11-10 04:57:26 +01:00
internal/shaderir/glfw: Insert a dummy function to touch uniform array variables
Closes #1754
This commit is contained in:
parent
6c8a7d1079
commit
d5150a194c
@ -147,9 +147,45 @@ func Compile(p *shaderir.Program, version GLSLVersion) (vertexShader, fragmentSh
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Add a dummy function to just touch uniform array variable's elements (#1754).
|
||||||
|
// Without this, the first elements of a uniform array might not be initialized correctly on some environments.
|
||||||
|
var touchedUniforms []string
|
||||||
|
for i, t := range p.Uniforms {
|
||||||
|
if t.Main != shaderir.Array {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if t.Length <= 1 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
str := fmt.Sprintf("U%d[%d]", i, t.Length-1)
|
||||||
|
switch t.Sub[0].Main {
|
||||||
|
case shaderir.Vec2, shaderir.Vec3, shaderir.Vec4:
|
||||||
|
str += ".x"
|
||||||
|
case shaderir.Mat2, shaderir.Mat3, shaderir.Mat4:
|
||||||
|
str += "[0][0]"
|
||||||
|
}
|
||||||
|
str = "float(" + str + ")"
|
||||||
|
touchedUniforms = append(touchedUniforms, str)
|
||||||
|
}
|
||||||
|
|
||||||
|
var touchUniformsFunc []string
|
||||||
|
if len(touchedUniforms) > 0 {
|
||||||
|
touchUniformsFunc = append(touchUniformsFunc, "float touchUniforms() {")
|
||||||
|
touchUniformsFunc = append(touchUniformsFunc, fmt.Sprintf("\treturn %s;", strings.Join(touchedUniforms, " + ")))
|
||||||
|
touchUniformsFunc = append(touchUniformsFunc, "}")
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
if p.VertexFunc.Block != nil && len(p.VertexFunc.Block.Stmts) > 0 {
|
if p.VertexFunc.Block != nil && len(p.VertexFunc.Block.Stmts) > 0 {
|
||||||
|
if len(touchUniformsFunc) > 0 {
|
||||||
|
vslines = append(vslines, "")
|
||||||
|
vslines = append(vslines, touchUniformsFunc...)
|
||||||
|
}
|
||||||
vslines = append(vslines, "")
|
vslines = append(vslines, "")
|
||||||
vslines = append(vslines, "void main(void) {")
|
vslines = append(vslines, "void main(void) {")
|
||||||
|
if len(touchUniformsFunc) > 0 {
|
||||||
|
vslines = append(vslines, "\ttouchUniforms();")
|
||||||
|
}
|
||||||
vslines = append(vslines, c.glslBlock(p, p.VertexFunc.Block, p.VertexFunc.Block, 0)...)
|
vslines = append(vslines, c.glslBlock(p, p.VertexFunc.Block, p.VertexFunc.Block, 0)...)
|
||||||
vslines = append(vslines, "}")
|
vslines = append(vslines, "}")
|
||||||
}
|
}
|
||||||
|
@ -1111,3 +1111,72 @@ func Fragment(position vec4, texCoord vec2, color vec4) vec4 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Issue #1754
|
||||||
|
func TestShaderUniformFirstElement(t *testing.T) {
|
||||||
|
shaders := []struct {
|
||||||
|
Name string
|
||||||
|
Shader string
|
||||||
|
Uniforms map[string]interface{}
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
Name: "float array",
|
||||||
|
Shader: `package main
|
||||||
|
|
||||||
|
var C [2]float
|
||||||
|
|
||||||
|
func Fragment(position vec4, texCoord vec2, color vec4) vec4 {
|
||||||
|
return vec4(C[0], 1, 1, 1)
|
||||||
|
}`,
|
||||||
|
Uniforms: map[string]interface{}{
|
||||||
|
"C": []float32{1, 1},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "float one-element array",
|
||||||
|
Shader: `package main
|
||||||
|
|
||||||
|
var C [1]float
|
||||||
|
|
||||||
|
func Fragment(position vec4, texCoord vec2, color vec4) vec4 {
|
||||||
|
return vec4(C[0], 1, 1, 1)
|
||||||
|
}`,
|
||||||
|
Uniforms: map[string]interface{}{
|
||||||
|
"C": []float32{1},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "matrix array",
|
||||||
|
Shader: `package main
|
||||||
|
|
||||||
|
var C [2]mat2
|
||||||
|
|
||||||
|
func Fragment(position vec4, texCoord vec2, color vec4) vec4 {
|
||||||
|
return vec4(C[0][0][0], 1, 1, 1)
|
||||||
|
}`,
|
||||||
|
Uniforms: map[string]interface{}{
|
||||||
|
"C": []float32{1, 0, 0, 0, 0, 0, 0, 0},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, shader := range shaders {
|
||||||
|
shader := shader
|
||||||
|
t.Run(shader.Name, func(t *testing.T) {
|
||||||
|
const w, h = 1, 1
|
||||||
|
|
||||||
|
dst := NewImage(w, h)
|
||||||
|
s, err := NewShader([]byte(shader.Shader))
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
op := &DrawRectShaderOptions{}
|
||||||
|
op.Uniforms = shader.Uniforms
|
||||||
|
dst.DrawRectShader(w, h, s, op)
|
||||||
|
if got, want := dst.At(0, 0), (color.RGBA{0xff, 0xff, 0xff, 0xff}); got != want {
|
||||||
|
t.Errorf("got: %v, want: %v", got, want)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user