ebiten: Change the type of Uniforms to map[string]interface{}

Fixes #1324
This commit is contained in:
Hajime Hoshi 2020-09-06 20:10:33 +09:00
parent 52fcab7a90
commit 850303b770
5 changed files with 49 additions and 16 deletions

View File

@ -18,7 +18,7 @@ package main
var Time float var Time float
var Cursor vec2 var Cursor vec2
var ScreenImage vec2 var ScreenSize vec2
func Fragment(position vec4, texCoord vec2, color vec4) vec4 { func Fragment(position vec4, texCoord vec2, color vec4) vec4 {
// Triangle wave to go 0-->1-->0... // Triangle wave to go 0-->1-->0...

View File

@ -2,4 +2,4 @@
package main package main
var dissolve_go = []byte("// Copyright 2020 The Ebiten Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n// +build ignore\n\npackage main\n\nvar Time float\nvar Cursor vec2\nvar ScreenImage vec2\n\nfunc Fragment(position vec4, texCoord vec2, color vec4) vec4 {\n\t// Triangle wave to go 0-->1-->0...\n\tlimit := abs(2*fract(Time/3) - 1)\n\tlevel := imageSrc3At(texCoord).x\n\n\t// Add a white border\n\tif limit-0.1 < level && level < limit {\n\t\talpha := imageSrc0At(texCoord).w\n\t\treturn vec4(alpha)\n\t}\n\n\treturn step(limit, level) * imageSrc0At(texCoord)\n}\n") var dissolve_go = []byte("// Copyright 2020 The Ebiten Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n// +build ignore\n\npackage main\n\nvar Time float\nvar Cursor vec2\nvar ScreenSize vec2\n\nfunc Fragment(position vec4, texCoord vec2, color vec4) vec4 {\n\t// Triangle wave to go 0-->1-->0...\n\tlimit := abs(2*fract(Time/3) - 1)\n\tlevel := imageSrc3At(texCoord).x\n\n\t// Add a white border\n\tif limit-0.1 < level && level < limit {\n\t\talpha := imageSrc0At(texCoord).w\n\t\treturn vec4(alpha)\n\t}\n\n\treturn step(limit, level) * imageSrc0At(texCoord)\n}\n")

View File

@ -130,10 +130,10 @@ func (g *Game) Draw(screen *ebiten.Image) {
cx, cy := ebiten.CursorPosition() cx, cy := ebiten.CursorPosition()
op := &ebiten.DrawRectShaderOptions{} op := &ebiten.DrawRectShaderOptions{}
op.Uniforms = []interface{}{ op.Uniforms = map[string]interface{}{
float32(g.time) / 60, // Time "Time": float32(g.time) / 60,
[]float32{float32(cx), float32(cy)}, // Cursor "Cursor": []float32{float32(cx), float32(cy)},
[]float32{float32(w), float32(h)}, // ScreenSize "ScreenSize": []float32{float32(w), float32(h)},
} }
op.Images[0] = gopherImage op.Images[0] = gopherImage
op.Images[1] = normalImage op.Images[1] = normalImage

View File

@ -140,7 +140,7 @@ type DrawImageOptions struct {
// Uniforms is a set of uniform variables for the shader. // Uniforms is a set of uniform variables for the shader.
// //
// Uniforms is used only when Shader is not nil. // Uniforms is used only when Shader is not nil.
Uniforms []interface{} Uniforms map[string]interface{}
// Deprecated: (as of 1.5.0) Use SubImage instead. // Deprecated: (as of 1.5.0) Use SubImage instead.
ImageParts ImageParts ImageParts ImageParts
@ -288,7 +288,8 @@ func (i *Image) DrawImage(img *Image, options *DrawImageOptions) error {
return nil return nil
} }
i.mipmap.DrawTriangles(srcs, vs, is, nil, mode, filter, driver.AddressUnsafe, sr, options.Shader.shader, options.Uniforms, canSkipMipmap(options.GeoM, filter)) us := options.Shader.convertUniforms(options.Uniforms)
i.mipmap.DrawTriangles(srcs, vs, is, nil, mode, filter, driver.AddressUnsafe, sr, options.Shader.shader, us, canSkipMipmap(options.GeoM, filter))
return nil return nil
} }
@ -358,7 +359,7 @@ type DrawTrianglesOptions struct {
// Uniforms is a set of uniform variables for the shader. // Uniforms is a set of uniform variables for the shader.
// //
// Uniforms is used only when Shader is not nil. // Uniforms is used only when Shader is not nil.
Uniforms []interface{} Uniforms map[string]interface{}
} }
// MaxIndicesNum is the maximum number of indices for DrawTriangles. // MaxIndicesNum is the maximum number of indices for DrawTriangles.
@ -454,7 +455,9 @@ func (i *Image) DrawTriangles(vertices []Vertex, indices []uint16, img *Image, o
i.mipmap.DrawTriangles(srcs, vs, is, options.ColorM.impl, mode, filter, driver.Address(options.Address), sr, nil, nil, false) i.mipmap.DrawTriangles(srcs, vs, is, options.ColorM.impl, mode, filter, driver.Address(options.Address), sr, nil, nil, false)
return return
} }
i.mipmap.DrawTriangles(srcs, vs, is, nil, mode, driver.FilterNearest, driver.AddressUnsafe, sr, options.Shader.shader, options.Uniforms, false)
us := options.Shader.convertUniforms(options.Uniforms)
i.mipmap.DrawTriangles(srcs, vs, is, nil, mode, driver.FilterNearest, driver.AddressUnsafe, sr, options.Shader.shader, us, false)
} }
// DrawRectShaderOptions represents options for DrawRectShader // DrawRectShaderOptions represents options for DrawRectShader
@ -470,7 +473,7 @@ type DrawRectShaderOptions struct {
CompositeMode CompositeMode CompositeMode CompositeMode
// Uniforms is a set of uniform variables for the shader. // Uniforms is a set of uniform variables for the shader.
Uniforms []interface{} Uniforms map[string]interface{}
// Images is a set of the source images. // Images is a set of the source images.
// All the image must be the same size with the rectangle. // All the image must be the same size with the rectangle.
@ -542,7 +545,8 @@ func (i *Image) DrawRectShader(width, height int, shader *Shader, options *DrawR
} }
} }
i.mipmap.DrawTriangles(imgs, vs, is, nil, mode, driver.FilterNearest, driver.AddressUnsafe, sr, shader.shader, options.Uniforms, canSkipMipmap(options.GeoM, driver.FilterNearest)) us := shader.convertUniforms(options.Uniforms)
i.mipmap.DrawTriangles(imgs, vs, is, nil, mode, driver.FilterNearest, driver.AddressUnsafe, sr, shader.shader, us, canSkipMipmap(options.GeoM, driver.FilterNearest))
} }
// DrawTrianglesShaderOptions represents options for DrawTrianglesShader // DrawTrianglesShaderOptions represents options for DrawTrianglesShader
@ -554,7 +558,7 @@ type DrawTrianglesShaderOptions struct {
CompositeMode CompositeMode CompositeMode CompositeMode
// Uniforms is a set of uniform variables for the shader. // Uniforms is a set of uniform variables for the shader.
Uniforms []interface{} Uniforms map[string]interface{}
// Images is a set of the source images. // Images is a set of the source images.
// All the image must be the same size. // All the image must be the same size.
@ -649,7 +653,8 @@ func (i *Image) DrawTrianglesShader(vertices []Vertex, indices []uint16, shader
} }
} }
i.mipmap.DrawTriangles(imgs, vs, is, nil, mode, driver.FilterNearest, driver.AddressUnsafe, sr, shader.shader, options.Uniforms, false) us := shader.convertUniforms(options.Uniforms)
i.mipmap.DrawTriangles(imgs, vs, is, nil, mode, driver.FilterNearest, driver.AddressUnsafe, sr, shader.shader, us, false)
} }
// SubImage returns an image representing the portion of the image p visible through r. // SubImage returns an image representing the portion of the image p visible through r.

View File

@ -19,6 +19,7 @@ import (
"fmt" "fmt"
"go/parser" "go/parser"
"go/token" "go/token"
"strings"
"github.com/hajimehoshi/ebiten/internal/graphics" "github.com/hajimehoshi/ebiten/internal/graphics"
"github.com/hajimehoshi/ebiten/internal/mipmap" "github.com/hajimehoshi/ebiten/internal/mipmap"
@ -102,7 +103,8 @@ func __vertex(position vec2, texCoord vec2, color vec4) (vec4, vec2, vec4) {
} }
type Shader struct { type Shader struct {
shader *mipmap.Shader shader *mipmap.Shader
uniformNames []string
} }
func NewShader(src []byte) (*Shader, error) { func NewShader(src []byte) (*Shader, error) {
@ -133,7 +135,8 @@ func NewShader(src []byte) (*Shader, error) {
} }
return &Shader{ return &Shader{
shader: mipmap.NewShader(s), shader: mipmap.NewShader(s),
uniformNames: s.UniformNames,
}, nil }, nil
} }
@ -141,3 +144,28 @@ func (s *Shader) Dispose() {
s.shader.MarkDisposed() s.shader.MarkDisposed()
s.shader = nil s.shader = nil
} }
func (s *Shader) convertUniforms(uniforms map[string]interface{}) []interface{} {
names := map[string]int{}
var idx int
for _, n := range s.uniformNames {
if strings.HasPrefix(n, "__") {
continue
}
names[n] = idx
idx++
}
us := make([]interface{}, len(names))
for n, u := range uniforms {
idx, ok := names[n]
if !ok {
// TODO: Panic here?
continue
}
us[idx] = u
}
// TODO: Check the uniform variable types?
return us
}