internal/shaderir/glsl: bug fix: % was not available on old GLSLs

Use a new utility function modInt instead.

Closes #1951
This commit is contained in:
Hajime Hoshi 2022-01-12 01:41:06 +09:00
parent d110716dc0
commit 08ddb4233b
2 changed files with 31 additions and 5 deletions

View File

@ -29,7 +29,15 @@ import (
"github.com/hajimehoshi/ebiten/v2/internal/shaderir/metal"
)
func glslNormalize(str string) string {
func glslVertexNormalize(str string) string {
p := glsl.VertexPrelude(glsl.GLSLVersionDefault)
if strings.HasPrefix(str, p) {
str = str[len(p):]
}
return strings.TrimSpace(str)
}
func glslFragmentNormalize(str string) string {
p := glsl.FragmentPrelude(glsl.GLSLVersionDefault)
if strings.HasPrefix(str, p) {
str = str[len(p):]
@ -158,11 +166,11 @@ func TestCompile(t *testing.T) {
// GLSL
vs, fs := glsl.Compile(s, glsl.GLSLVersionDefault)
if got, want := glslNormalize(vs), glslNormalize(string(tc.VS)); got != want {
if got, want := glslVertexNormalize(vs), glslVertexNormalize(string(tc.VS)); got != want {
compare(t, "GLSL Vertex", got, want)
}
if tc.FS != nil {
if got, want := glslNormalize(fs), glslNormalize(string(tc.FS)); got != want {
if got, want := glslFragmentNormalize(fs), glslFragmentNormalize(string(tc.FS)); got != want {
compare(t, "GLSL Fragment", got, want)
}
}

View File

@ -33,8 +33,18 @@ const (
GLSLVersionES300
)
// utilFunctions is GLSL utility functions for old GLSL versions.
const utilFunctions = `int modInt(int x, int y) {
return x - y*(x/y);
}`
func VertexPrelude(version GLSLVersion) string {
if version == GLSLVersionES300 {
switch version {
case GLSLVersionDefault:
return utilFunctions
case GLSLVersionES100:
return utilFunctions
case GLSLVersionES300:
return `#version 300 es`
}
return ""
@ -48,13 +58,17 @@ func FragmentPrelude(version GLSLVersion) string {
case GLSLVersionES300:
prefix = `#version 300 es` + "\n\n"
}
return prefix + `#if defined(GL_ES)
prelude := prefix + `#if defined(GL_ES)
precision highp float;
#else
#define lowp
#define mediump
#define highp
#endif`
if version == GLSLVersionDefault || version == GLSLVersionES100 {
prelude += "\n\n" + utilFunctions
}
return prelude
}
type compileContext struct {
@ -496,6 +510,10 @@ func (c *compileContext) glslBlock(p *shaderir.Program, topBlock, block *shaderi
}
return fmt.Sprintf("%s(%s)", op, glslExpr(&e.Exprs[0]))
case shaderir.Binary:
if e.Op == shaderir.ModOp && (c.version == GLSLVersionDefault || c.version == GLSLVersionES100) {
// '%' is not defined.
return fmt.Sprintf("modInt((%s), (%s))", glslExpr(&e.Exprs[0]), glslExpr(&e.Exprs[1]))
}
return fmt.Sprintf("(%s) %s (%s)", glslExpr(&e.Exprs[0]), e.Op, glslExpr(&e.Exprs[1]))
case shaderir.Selection:
return fmt.Sprintf("(%s) ? (%s) : (%s)", glslExpr(&e.Exprs[0]), glslExpr(&e.Exprs[1]), glslExpr(&e.Exprs[2]))