shader: Implement len function

Fixes #1279
This commit is contained in:
Hajime Hoshi 2020-08-16 02:07:36 +09:00
parent a1d278b097
commit 06ed4f5444
6 changed files with 38 additions and 4 deletions

View File

@ -27,9 +27,8 @@ func Fragment(position vec4, texCoord vec2, color vec4) vec4 {
samples := [...]float{
-22, -14, -8, -4, -2, 2, 4, 8, 14, 22,
}
// TODO: Add len(samples)
sum := clr
for i := 0; i < 10; i++ {
for i := 0; i < len(samples); i++ {
pos := texCoord + dir*samples[i]/imageSrcTextureSize()
sum += image2TextureBoundsAt(pos)
}

View File

@ -2,4 +2,4 @@
package main
var radialblur_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\tdir := normalize(position.xy - Cursor)\n\tclr := image2TextureAt(texCoord)\n\n\tsamples := [...]float{\n\t\t-22, -14, -8, -4, -2, 2, 4, 8, 14, 22,\n\t}\n\t// TODO: Add len(samples)\n\tsum := clr\n\tfor i := 0; i < 10; i++ {\n\t\tpos := texCoord + dir*samples[i]/imageSrcTextureSize()\n\t\tsum += image2TextureBoundsAt(pos)\n\t}\n\tsum /= 10 + 1\n\n\tdist := distance(position.xy, Cursor)\n\tt := clamp(dist/256, 0, 1)\n\treturn mix(clr, sum, t)\n}\n")
var radialblur_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\tdir := normalize(position.xy - Cursor)\n\tclr := image2TextureAt(texCoord)\n\n\tsamples := [...]float{\n\t\t-22, -14, -8, -4, -2, 2, 4, 8, 14, 22,\n\t}\n\tsum := clr\n\tfor i := 0; i < len(samples); i++ {\n\t\tpos := texCoord + dir*samples[i]/imageSrcTextureSize()\n\t\tsum += image2TextureBoundsAt(pos)\n\t}\n\tsum /= 10 + 1\n\n\tdist := distance(position.xy, Cursor)\n\tt := clamp(dist/256, 0, 1)\n\treturn mix(clr, sum, t)\n}\n")

View File

@ -220,6 +220,24 @@ func (cs *compileState) parseExpr(block *block, expr ast.Expr) ([]shaderir.Expr,
// For built-in functions, we can call this in this position. Return an expression for the function
// call.
if callee.Type == shaderir.BuiltinFuncExpr {
if callee.BuiltinFunc == shaderir.Len {
if len(args) != 1 {
cs.addError(e.Pos(), fmt.Sprintf("number of len's arguments must be 1 but %d", len(args)))
return nil, nil, nil, false
}
if argts[0].Main != shaderir.Array {
cs.addError(e.Pos(), fmt.Sprintf("len takes an array but %s", argts[0].String()))
return nil, nil, nil, false
}
return []shaderir.Expr{
{
Type: shaderir.NumberExpr,
Const: gconstant.MakeInt64(int64(argts[0].Length)),
ConstType: shaderir.ConstTypeInt,
},
}, []shaderir.Type{{Main: shaderir.Int}}, stmts, true
}
var t shaderir.Type
switch callee.BuiltinFunc {
case shaderir.BoolF:

View File

@ -0,0 +1,9 @@
void F0(in vec2 l0, out int l1);
void F0(in vec2 l0, out int l1) {
int l2[2];
l2[0] = 0;
l2[1] = 0;
l1 = 2;
return;
}

6
internal/shader/testdata/len.go vendored Normal file
View File

@ -0,0 +1,6 @@
package main
func Foo(foo vec2) int {
var a [2]int
return len(a)
}

View File

@ -198,6 +198,7 @@ func OpFromToken(t token.Token) (Op, bool) {
type BuiltinFunc string
const (
Len BuiltinFunc = "len"
BoolF BuiltinFunc = "bool"
IntF BuiltinFunc = "int"
FloatF BuiltinFunc = "float"
@ -250,7 +251,8 @@ const (
func ParseBuiltinFunc(str string) (BuiltinFunc, bool) {
switch BuiltinFunc(str) {
case BoolF,
case Len,
BoolF,
IntF,
FloatF,
Vec2F,