diff --git a/internal/shader/shader_test.go b/internal/shader/shader_test.go index c7e8496fd..cc8695c5a 100644 --- a/internal/shader/shader_test.go +++ b/internal/shader/shader_test.go @@ -17,338 +17,83 @@ package shader_test import ( "go/parser" "go/token" + "io/ioutil" + "path/filepath" + "strings" "testing" . "github.com/hajimehoshi/ebiten/internal/shader" ) -func TestDump(t *testing.T) { - tests := []struct { +func TestCompile(t *testing.T) { + files, err := ioutil.ReadDir("testdata") + if err != nil { + t.Fatal(err) + } + + type testcase struct { Name string - Src string - VS string - FS string - }{ - { - Name: "uniforms", - Src: `package main - -var ( - Foo vec2 - Boo vec4 -)`, - VS: `uniform vec2 U0; -uniform vec4 U1;`, - }, - { - Name: "func", - Src: `package main - -func Foo(foo vec2) vec4 { -}`, - VS: `void F0(in vec2 l0, out vec4 l1) { -}`, - }, - { - Name: "func body", - Src: `package main - -func Foo(foo vec2) vec4 { - return vec4(foo, 0, 1) -}`, - VS: `void F0(in vec2 l0, out vec4 l1) { - l1 = vec4(l0, 0.0, 1.0); - return; -}`, - }, - { - Name: "var init", - Src: `package main - -func Foo(foo vec2) vec4 { - var ret vec4 = vec4(foo, 0, 1) - return ret -}`, - VS: `void F0(in vec2 l0, out vec4 l1) { - vec4 l2 = vec4(0.0); - l2 = vec4(l0, 0.0, 1.0); - l1 = l2; - return; -}`, - }, - { - Name: "var init 2", - Src: `package main - -func Foo(foo vec2) vec4 { - var bar1 vec4 = vec4(foo, 0, 1) - bar1.x = bar1.x - var bar2 vec4 = bar1 - return bar2 -}`, - VS: `void F0(in vec2 l0, out vec4 l1) { - vec4 l2 = vec4(0.0); - vec4 l3 = vec4(0.0); - l2 = vec4(l0, 0.0, 1.0); - (l2).x = (l2).x; - l3 = l2; - l1 = l3; - return; -}`, - }, - { - Name: "var multiple init", - Src: `package main - -func Foo(foo vec2) vec4 { - var bar1, bar2 vec2 = foo, foo - return vec4(bar1, bar2) -}`, - VS: `void F0(in vec2 l0, out vec4 l1) { - vec2 l2 = vec2(0.0); - vec2 l3 = vec2(0.0); - l2 = l0; - l3 = l0; - l1 = vec4(l2, l3); - return; -}`, - }, - { - Name: "multiple out params", - Src: `package main - -func Foo(foo vec4) (float, float, float, float) { - return foo.x, foo.y, foo.z, foo.w -}`, - VS: `void F0(in vec4 l0, out float l1, out float l2, out float l3, out float l4) { - l1 = (l0).x; - l2 = (l0).y; - l3 = (l0).z; - l4 = (l0).w; - return; -}`, - }, - { - Name: "blocks", - Src: `package main - -func Foo(foo vec2) vec4 { - var r vec4 - { - r.x = foo.x - var foo vec3 - { - r.y = foo.y - var foo vec4 - r.z = foo.z - } - { - r.y = foo.y - var foo vec4 - r.z = foo.z - } + Src []byte + VS []byte + FS []byte } - return r -}`, - VS: `void F0(in vec2 l0, out vec4 l1) { - vec4 l2 = vec4(0.0); - { - vec3 l3 = vec3(0.0); - (l2).x = (l0).x; - { - vec4 l4 = vec4(0.0); - (l2).y = (l3).y; - (l2).z = (l4).z; + + fnames := map[string]struct{}{} + for _, f := range files { + if f.IsDir() { + continue } - { - vec4 l4 = vec4(0.0); - (l2).y = (l3).y; - (l2).z = (l4).z; + fnames[f.Name()] = struct{}{} + } + + tests := []testcase{} + for n := range fnames { + if !strings.HasSuffix(n, ".go") { + continue } + + src, err := ioutil.ReadFile(filepath.Join("testdata", n)) + if err != nil { + t.Fatal(err) + } + + name := n[:len(n)-len(".go")] + tc := testcase{ + Name: name, + Src: src, + } + + vsn := name + ".expected.vs" + if _, ok := fnames[vsn]; ok { + vs, err := ioutil.ReadFile(filepath.Join("testdata", vsn)) + if err != nil { + t.Fatal(err) + } + tc.VS = vs + } + + fsn := name + ".expected.fs" + if _, ok := fnames[fsn]; ok { + fs, err := ioutil.ReadFile(filepath.Join("testdata", fsn)) + if err != nil { + t.Fatal(err) + } + tc.FS = fs + } + + if tc.VS == nil && tc.FS == nil { + t.Fatalf("no expected file for %s", name) + } + + tests = append(tests, tc) } - l1 = l2; - return; -}`, - }, - { - Name: "define", - Src: `package main -func Foo(foo vec2) vec4 { - r := vec4(foo, 0, 1) - return r -}`, - VS: `void F0(in vec2 l0, out vec4 l1) { - vec4 l2 = vec4(0.0); - l2 = vec4(l0, 0.0, 1.0); - l1 = l2; - return; -}`, - }, - { - Name: "call", - Src: `package main - -func Foo(x vec2) vec2 { - return Bar(x) -} - -func Bar(x vec2) vec2 { - return x -}`, - VS: `void F0(in vec2 l0, out vec2 l1) { - vec2 l2 = vec2(0.0); - F1(l0, l2); - l1 = l2; - return; -} - -void F1(in vec2 l0, out vec2 l1) { - l1 = l0; - return; -}`, - }, - { - Name: "call multiple out params", - Src: `package main - -func Foo(x vec2) vec2 { - var xx, yx float = Bar(x.x, x.y) - return vec2(xx, yx) -} - -func Bar(x float) (float, float) { - return x, x -}`, - VS: `void F0(in vec2 l0, out vec2 l1) { - float l2 = 0.0; - float l3 = 0.0; - float l4 = 0.0; - float l5 = 0.0; - F1((l0).x, (l0).y, l2, l3); - l4 = l2; - l5 = l3; - l1 = vec2(l4, l5); - return; -} - -void F1(in float l0, out float l1, out float l2) { - l1 = l0; - l2 = l0; - return; -}`, - }, - { - Name: "call multiple out params nested", - Src: `package main - -func Foo(x vec2) { - Bar(Bar(x.x, x.y)) -} - -func Bar(x, y float) (float, float) { - return x, y -}`, - VS: `void F0(in vec2 l0) { - float l1 = 0.0; - float l2 = 0.0; - float l3 = 0.0; - float l4 = 0.0; - F1((l0).x, (l0).y, l1, l2); - F1(l1, l2, l3, l4); -} - -void F1(in float l0, in float l1, out float l2, out float l3) { - l2 = l0; - l3 = l1; - return; -}`, - }, - { - Name: "vertex", - Src: `package main - -func Vertex(position vec2, texCoord vec2, color vec4) (position vec4, texCoord vec2, color vec4) { - projectionMatrix := mat4( - 2 / ScreenSize.x, 0, 0, 0, - 0, 2 / ScreenSize.y, 0, 0, - 0, 0, 1, 0, - -1, -1, 0, 1, - ) - return projectionMatrix * vec4(position, 0, 1), texCoord, color -} - -var ScreenSize vec2`, - VS: `uniform vec2 U0; -attribute vec2 A0; -attribute vec2 A1; -attribute vec4 A2; -varying vec2 V0; -varying vec4 V1; - -void main(void) { - mat4 l0 = mat4(0.0); - l0 = mat4((2.0) / ((U0).x), 0.0, 0.0, 0.0, 0.0, (2.0) / ((U0).y), 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, -(1.0), -(1.0), 0.0, 1.0); - gl_Position = (l0) * (vec4(A0, 0.0, 1.0)); - V0 = A1; - V1 = A2; - return; -}`, - FS: `uniform vec2 U0; -varying vec2 V0; -varying vec4 V1;`, - }, - { - Name: "vertex and fragment", - Src: `package main - -func Vertex(position vec2, texCoord vec2, color vec4) (position vec4, texCoord vec2, color vec4) { - projectionMatrix := mat4( - 2 / ScreenSize.x, 0, 0, 0, - 0, 2 / ScreenSize.y, 0, 0, - 0, 0, 1, 0, - -1, -1, 0, 1, - ) - return projectionMatrix * vec4(position, 0, 1), texCoord, color -} - -func Fragment(position vec4, texCoord vec2, color vec4) vec4 { - return vec4(1, 0, 0, 1) -} - -var ScreenSize vec2`, - VS: `uniform vec2 U0; -attribute vec2 A0; -attribute vec2 A1; -attribute vec4 A2; -varying vec2 V0; -varying vec4 V1; - -void main(void) { - mat4 l0 = mat4(0.0); - l0 = mat4((2.0) / ((U0).x), 0.0, 0.0, 0.0, 0.0, (2.0) / ((U0).y), 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, -(1.0), -(1.0), 0.0, 1.0); - gl_Position = (l0) * (vec4(A0, 0.0, 1.0)); - V0 = A1; - V1 = A2; - return; -}`, - FS: `uniform vec2 U0; -varying vec2 V0; -varying vec4 V1; - -void main(void) { - gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); - return; -}`, - }, - } for _, tc := range tests { t.Run(tc.Name, func(t *testing.T) { fset := token.NewFileSet() - f, err := parser.ParseFile(fset, "", []byte(tc.Src), parser.AllErrors) + f, err := parser.ParseFile(fset, "", tc.Src, parser.AllErrors) if err != nil { t.Fatal(err) - return } s, err := Compile(fset, f, "Vertex", "Fragment") @@ -357,11 +102,11 @@ void main(void) { return } vs, fs := s.Glsl() - if got, want := vs, tc.VS+"\n"; got != want { + if got, want := vs, string(tc.VS); got != want { t.Errorf("got: %v, want: %v", got, want) } - if tc.FS != "" { - if got, want := fs, tc.FS+"\n"; got != want { + if tc.FS != nil { + if got, want := fs, string(tc.FS); got != want { t.Errorf("got: %v, want: %v", got, want) } } diff --git a/internal/shader/testdata/blocks.expected.vs b/internal/shader/testdata/blocks.expected.vs new file mode 100644 index 000000000..92344ffe3 --- /dev/null +++ b/internal/shader/testdata/blocks.expected.vs @@ -0,0 +1,19 @@ +void F0(in vec2 l0, out vec4 l1) { + vec4 l2 = vec4(0.0); + { + vec3 l3 = vec3(0.0); + (l2).x = (l0).x; + { + vec4 l4 = vec4(0.0); + (l2).y = (l3).y; + (l2).z = (l4).z; + } + { + vec4 l4 = vec4(0.0); + (l2).y = (l3).y; + (l2).z = (l4).z; + } + } + l1 = l2; + return; +} diff --git a/internal/shader/testdata/blocks.go b/internal/shader/testdata/blocks.go new file mode 100644 index 000000000..18d12d291 --- /dev/null +++ b/internal/shader/testdata/blocks.go @@ -0,0 +1,20 @@ +package main + +func Foo(foo vec2) vec4 { + var r vec4 + { + r.x = foo.x + var foo vec3 + { + r.y = foo.y + var foo vec4 + r.z = foo.z + } + { + r.y = foo.y + var foo vec4 + r.z = foo.z + } + } + return r +} diff --git a/internal/shader/testdata/call.expected.vs b/internal/shader/testdata/call.expected.vs new file mode 100644 index 000000000..6355e652a --- /dev/null +++ b/internal/shader/testdata/call.expected.vs @@ -0,0 +1,11 @@ +void F0(in vec2 l0, out vec2 l1) { + vec2 l2 = vec2(0.0); + F1(l0, l2); + l1 = l2; + return; +} + +void F1(in vec2 l0, out vec2 l1) { + l1 = l0; + return; +} diff --git a/internal/shader/testdata/call.go b/internal/shader/testdata/call.go new file mode 100644 index 000000000..f5fc6bcf6 --- /dev/null +++ b/internal/shader/testdata/call.go @@ -0,0 +1,9 @@ +package main + +func Foo(x vec2) vec2 { + return Bar(x) +} + +func Bar(x vec2) vec2 { + return x +} diff --git a/internal/shader/testdata/call_multiple.expected.vs b/internal/shader/testdata/call_multiple.expected.vs new file mode 100644 index 000000000..8c3157e38 --- /dev/null +++ b/internal/shader/testdata/call_multiple.expected.vs @@ -0,0 +1,17 @@ +void F0(in vec2 l0, out vec2 l1) { + float l2 = 0.0; + float l3 = 0.0; + float l4 = 0.0; + float l5 = 0.0; + F1((l0).x, (l0).y, l2, l3); + l4 = l2; + l5 = l3; + l1 = vec2(l4, l5); + return; +} + +void F1(in float l0, out float l1, out float l2) { + l1 = l0; + l2 = l0; + return; +} diff --git a/internal/shader/testdata/call_multiple.go b/internal/shader/testdata/call_multiple.go new file mode 100644 index 000000000..9e33b3f20 --- /dev/null +++ b/internal/shader/testdata/call_multiple.go @@ -0,0 +1,10 @@ +package main + +func Foo(x vec2) vec2 { + var xx, yx float = Bar(x.x, x.y) + return vec2(xx, yx) +} + +func Bar(x float) (float, float) { + return x, x +} diff --git a/internal/shader/testdata/call_multiple_nested.expected.vs b/internal/shader/testdata/call_multiple_nested.expected.vs new file mode 100644 index 000000000..7cc0592b6 --- /dev/null +++ b/internal/shader/testdata/call_multiple_nested.expected.vs @@ -0,0 +1,14 @@ +void F0(in vec2 l0) { + float l1 = 0.0; + float l2 = 0.0; + float l3 = 0.0; + float l4 = 0.0; + F1((l0).x, (l0).y, l1, l2); + F1(l1, l2, l3, l4); +} + +void F1(in float l0, in float l1, out float l2, out float l3) { + l2 = l0; + l3 = l1; + return; +} diff --git a/internal/shader/testdata/call_multiple_nested.go b/internal/shader/testdata/call_multiple_nested.go new file mode 100644 index 000000000..d5a708437 --- /dev/null +++ b/internal/shader/testdata/call_multiple_nested.go @@ -0,0 +1,9 @@ +package main + +func Foo(x vec2) { + Bar(Bar(x.x, x.y)) +} + +func Bar(x, y float) (float, float) { + return x, y +} diff --git a/internal/shader/testdata/define.expected.vs b/internal/shader/testdata/define.expected.vs new file mode 100644 index 000000000..5cce79e0c --- /dev/null +++ b/internal/shader/testdata/define.expected.vs @@ -0,0 +1,6 @@ +void F0(in vec2 l0, out vec4 l1) { + vec4 l2 = vec4(0.0); + l2 = vec4(l0, 0.0, 1.0); + l1 = l2; + return; +} diff --git a/internal/shader/testdata/define.go b/internal/shader/testdata/define.go new file mode 100644 index 000000000..2157368b7 --- /dev/null +++ b/internal/shader/testdata/define.go @@ -0,0 +1,6 @@ +package main + +func Foo(foo vec2) vec4 { + r := vec4(foo, 0, 1) + return r +} diff --git a/internal/shader/testdata/func.expected.vs b/internal/shader/testdata/func.expected.vs new file mode 100644 index 000000000..1caab6b77 --- /dev/null +++ b/internal/shader/testdata/func.expected.vs @@ -0,0 +1,2 @@ +void F0(in vec2 l0, out vec4 l1) { +} diff --git a/internal/shader/testdata/func.go b/internal/shader/testdata/func.go new file mode 100644 index 000000000..d9d56263e --- /dev/null +++ b/internal/shader/testdata/func.go @@ -0,0 +1,4 @@ +package main + +func Foo(foo vec2) vec4 { +} diff --git a/internal/shader/testdata/func_body.expected.vs b/internal/shader/testdata/func_body.expected.vs new file mode 100644 index 000000000..2447550ab --- /dev/null +++ b/internal/shader/testdata/func_body.expected.vs @@ -0,0 +1,4 @@ +void F0(in vec2 l0, out vec4 l1) { + l1 = vec4(l0, 0.0, 1.0); + return; +} diff --git a/internal/shader/testdata/func_body.go b/internal/shader/testdata/func_body.go new file mode 100644 index 000000000..57d2e3e4e --- /dev/null +++ b/internal/shader/testdata/func_body.go @@ -0,0 +1,5 @@ +package main + +func Foo(foo vec2) vec4 { + return vec4(foo, 0, 1) +} diff --git a/internal/shader/testdata/func_multiple.expected.vs b/internal/shader/testdata/func_multiple.expected.vs new file mode 100644 index 000000000..81d83fd84 --- /dev/null +++ b/internal/shader/testdata/func_multiple.expected.vs @@ -0,0 +1,7 @@ +void F0(in vec4 l0, out float l1, out float l2, out float l3, out float l4) { + l1 = (l0).x; + l2 = (l0).y; + l3 = (l0).z; + l4 = (l0).w; + return; +} diff --git a/internal/shader/testdata/func_multiple.go b/internal/shader/testdata/func_multiple.go new file mode 100644 index 000000000..4126a2e9e --- /dev/null +++ b/internal/shader/testdata/func_multiple.go @@ -0,0 +1,5 @@ +package main + +func Foo(foo vec4) (float, float, float, float) { + return foo.x, foo.y, foo.z, foo.w +} diff --git a/internal/shader/testdata/uniforms.expected.vs b/internal/shader/testdata/uniforms.expected.vs new file mode 100644 index 000000000..333178024 --- /dev/null +++ b/internal/shader/testdata/uniforms.expected.vs @@ -0,0 +1,2 @@ +uniform vec2 U0; +uniform vec4 U1; diff --git a/internal/shader/testdata/uniforms.go b/internal/shader/testdata/uniforms.go new file mode 100644 index 000000000..dc6ed30bc --- /dev/null +++ b/internal/shader/testdata/uniforms.go @@ -0,0 +1,6 @@ +package main + +var ( + Foo vec2 + Boo vec4 +) diff --git a/internal/shader/testdata/var.expected.vs b/internal/shader/testdata/var.expected.vs new file mode 100644 index 000000000..5cce79e0c --- /dev/null +++ b/internal/shader/testdata/var.expected.vs @@ -0,0 +1,6 @@ +void F0(in vec2 l0, out vec4 l1) { + vec4 l2 = vec4(0.0); + l2 = vec4(l0, 0.0, 1.0); + l1 = l2; + return; +} diff --git a/internal/shader/testdata/var.go b/internal/shader/testdata/var.go new file mode 100644 index 000000000..6a02de4ca --- /dev/null +++ b/internal/shader/testdata/var.go @@ -0,0 +1,6 @@ +package main + +func Foo(foo vec2) vec4 { + var ret vec4 = vec4(foo, 0, 1) + return ret +} diff --git a/internal/shader/testdata/var2.expected.vs b/internal/shader/testdata/var2.expected.vs new file mode 100644 index 000000000..39f20c6fb --- /dev/null +++ b/internal/shader/testdata/var2.expected.vs @@ -0,0 +1,9 @@ +void F0(in vec2 l0, out vec4 l1) { + vec4 l2 = vec4(0.0); + vec4 l3 = vec4(0.0); + l2 = vec4(l0, 0.0, 1.0); + (l2).x = (l2).x; + l3 = l2; + l1 = l3; + return; +} diff --git a/internal/shader/testdata/var2.go b/internal/shader/testdata/var2.go new file mode 100644 index 000000000..054dc38ba --- /dev/null +++ b/internal/shader/testdata/var2.go @@ -0,0 +1,8 @@ +package main + +func Foo(foo vec2) vec4 { + var bar1 vec4 = vec4(foo, 0, 1) + bar1.x = bar1.x + var bar2 vec4 = bar1 + return bar2 +} diff --git a/internal/shader/testdata/var_multiple.expected.vs b/internal/shader/testdata/var_multiple.expected.vs new file mode 100644 index 000000000..c10e14e34 --- /dev/null +++ b/internal/shader/testdata/var_multiple.expected.vs @@ -0,0 +1,8 @@ +void F0(in vec2 l0, out vec4 l1) { + vec2 l2 = vec2(0.0); + vec2 l3 = vec2(0.0); + l2 = l0; + l3 = l0; + l1 = vec4(l2, l3); + return; +} diff --git a/internal/shader/testdata/var_multiple.go b/internal/shader/testdata/var_multiple.go new file mode 100644 index 000000000..8386fe836 --- /dev/null +++ b/internal/shader/testdata/var_multiple.go @@ -0,0 +1,6 @@ +package main + +func Foo(foo vec2) vec4 { + var bar1, bar2 vec2 = foo, foo + return vec4(bar1, bar2) +} diff --git a/internal/shader/testdata/vertex.expected.fs b/internal/shader/testdata/vertex.expected.fs new file mode 100644 index 000000000..40d1c664e --- /dev/null +++ b/internal/shader/testdata/vertex.expected.fs @@ -0,0 +1,3 @@ +uniform vec2 U0; +varying vec2 V0; +varying vec4 V1; diff --git a/internal/shader/testdata/vertex.expected.vs b/internal/shader/testdata/vertex.expected.vs new file mode 100644 index 000000000..59ca7a289 --- /dev/null +++ b/internal/shader/testdata/vertex.expected.vs @@ -0,0 +1,15 @@ +uniform vec2 U0; +attribute vec2 A0; +attribute vec2 A1; +attribute vec4 A2; +varying vec2 V0; +varying vec4 V1; + +void main(void) { + mat4 l0 = mat4(0.0); + l0 = mat4((2.0) / ((U0).x), 0.0, 0.0, 0.0, 0.0, (2.0) / ((U0).y), 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, -(1.0), -(1.0), 0.0, 1.0); + gl_Position = (l0) * (vec4(A0, 0.0, 1.0)); + V0 = A1; + V1 = A2; + return; +} diff --git a/internal/shader/testdata/vertex.go b/internal/shader/testdata/vertex.go new file mode 100644 index 000000000..fa2fc12a8 --- /dev/null +++ b/internal/shader/testdata/vertex.go @@ -0,0 +1,13 @@ +package main + +func Vertex(position vec2, texCoord vec2, color vec4) (position vec4, texCoord vec2, color vec4) { + projectionMatrix := mat4( + 2/ScreenSize.x, 0, 0, 0, + 0, 2/ScreenSize.y, 0, 0, + 0, 0, 1, 0, + -1, -1, 0, 1, + ) + return projectionMatrix * vec4(position, 0, 1), texCoord, color +} + +var ScreenSize vec2 diff --git a/internal/shader/testdata/vertex_fragment.expected.fs b/internal/shader/testdata/vertex_fragment.expected.fs new file mode 100644 index 000000000..b0d7975eb --- /dev/null +++ b/internal/shader/testdata/vertex_fragment.expected.fs @@ -0,0 +1,8 @@ +uniform vec2 U0; +varying vec2 V0; +varying vec4 V1; + +void main(void) { + gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); + return; +} diff --git a/internal/shader/testdata/vertex_fragment.expected.vs b/internal/shader/testdata/vertex_fragment.expected.vs new file mode 100644 index 000000000..59ca7a289 --- /dev/null +++ b/internal/shader/testdata/vertex_fragment.expected.vs @@ -0,0 +1,15 @@ +uniform vec2 U0; +attribute vec2 A0; +attribute vec2 A1; +attribute vec4 A2; +varying vec2 V0; +varying vec4 V1; + +void main(void) { + mat4 l0 = mat4(0.0); + l0 = mat4((2.0) / ((U0).x), 0.0, 0.0, 0.0, 0.0, (2.0) / ((U0).y), 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, -(1.0), -(1.0), 0.0, 1.0); + gl_Position = (l0) * (vec4(A0, 0.0, 1.0)); + V0 = A1; + V1 = A2; + return; +} diff --git a/internal/shader/testdata/vertex_fragment.go b/internal/shader/testdata/vertex_fragment.go new file mode 100644 index 000000000..0c06f832b --- /dev/null +++ b/internal/shader/testdata/vertex_fragment.go @@ -0,0 +1,17 @@ +package main + +func Vertex(position vec2, texCoord vec2, color vec4) (position vec4, texCoord vec2, color vec4) { + projectionMatrix := mat4( + 2/ScreenSize.x, 0, 0, 0, + 0, 2/ScreenSize.y, 0, 0, + 0, 0, 1, 0, + -1, -1, 0, 1, + ) + return projectionMatrix * vec4(position, 0, 1), texCoord, color +} + +func Fragment(position vec4, texCoord vec2, color vec4) vec4 { + return vec4(1, 0, 0, 1) +} + +var ScreenSize vec2