mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-12-24 18:58:54 +01:00
parent
2b4cf7fd17
commit
a4334c5464
@ -23,19 +23,14 @@ const (
|
|||||||
|
|
||||||
// PreservedUniformVariablesNum represents the number of preserved uniform variables.
|
// PreservedUniformVariablesNum represents the number of preserved uniform variables.
|
||||||
// Any shaders in Ebiten must have these uniform variables.
|
// Any shaders in Ebiten must have these uniform variables.
|
||||||
//
|
|
||||||
// All the preversed uniform variables are vec2 so far.
|
|
||||||
PreservedUniformVariablesNum = 1 + // the destination texture size
|
PreservedUniformVariablesNum = 1 + // the destination texture size
|
||||||
ShaderImageNum + // the texture sizes
|
1 + // the texture sizes array
|
||||||
(ShaderImageNum - 1) // the offsets of the second and the following images
|
1 // the offsets array of the second and the following images
|
||||||
)
|
|
||||||
|
|
||||||
func TextureOffsetUniformVariableIndex(i int) int {
|
DestinationTextureSizeUniformVariableIndex = 0
|
||||||
if i == 0 {
|
TextureSizesUniformVariableIndex = 1
|
||||||
panic("graphics: the texture 0 doesn't have its offset")
|
TextureOffsetsUniformVariableIndex = 2
|
||||||
}
|
)
|
||||||
return 1 + ShaderImageNum + i - 1
|
|
||||||
}
|
|
||||||
|
|
||||||
const (
|
const (
|
||||||
IndicesNum = (1 << 16) / 3 * 3 // Adjust num for triangles.
|
IndicesNum = (1 << 16) / 3 * 3 // Adjust num for triangles.
|
||||||
|
@ -311,24 +311,32 @@ func (g *Graphics) DrawShader(dst driver.ImageID, srcs [graphics.ShaderImageNum]
|
|||||||
us[0].value = []float32{float32(vw), float32(vh)}
|
us[0].value = []float32{float32(vw), float32(vh)}
|
||||||
us[0].typ = s.ir.Uniforms[0]
|
us[0].typ = s.ir.Uniforms[0]
|
||||||
|
|
||||||
|
vsizes := make([]float32, 2*len(srcs))
|
||||||
for i, src := range srcs {
|
for i, src := range srcs {
|
||||||
img := g.images[src]
|
if img := g.images[src]; img != nil {
|
||||||
var w, h int
|
w, h := img.framebufferSize()
|
||||||
if img != nil {
|
vsizes[2*i] = float32(w)
|
||||||
w, h = img.framebufferSize()
|
vsizes[2*i+1] = float32(h)
|
||||||
}
|
}
|
||||||
const offset = 1
|
|
||||||
us[i+offset].name = fmt.Sprintf("U%d", i+offset)
|
}
|
||||||
us[i+offset].value = []float32{float32(w), float32(h)}
|
{
|
||||||
us[i+offset].typ = s.ir.Uniforms[i+offset]
|
const idx = 1
|
||||||
|
us[idx].name = fmt.Sprintf("U%d", idx)
|
||||||
|
us[idx].value = vsizes
|
||||||
|
us[idx].typ = s.ir.Uniforms[idx]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
voffsets := make([]float32, 2*len(offsets))
|
||||||
for i, o := range offsets {
|
for i, o := range offsets {
|
||||||
const offset = 1 + graphics.ShaderImageNum
|
voffsets[2*i] = o[0]
|
||||||
o := o
|
voffsets[2*i+1] = o[1]
|
||||||
us[i+offset].name = fmt.Sprintf("U%d", i+offset)
|
}
|
||||||
us[i+offset].value = o[:]
|
{
|
||||||
us[i+offset].typ = s.ir.Uniforms[i+offset]
|
const idx = 1 + 1
|
||||||
|
us[idx].name = fmt.Sprintf("U%d", idx)
|
||||||
|
us[idx].value = voffsets
|
||||||
|
us[idx].typ = s.ir.Uniforms[idx]
|
||||||
}
|
}
|
||||||
|
|
||||||
for i, v := range uniforms {
|
for i, v := range uniforms {
|
||||||
|
@ -182,11 +182,6 @@ func (cs *compileState) parse(f *ast.File) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// TODO: Check len(unames) == graphics.PreservedUniformVariablesNum. Unfortunately this is not true on tests.
|
// TODO: Check len(unames) == graphics.PreservedUniformVariablesNum. Unfortunately this is not true on tests.
|
||||||
for _, t := range utypes {
|
|
||||||
if got, want := t.Main, shaderir.Vec2; got != want {
|
|
||||||
panic(fmt.Sprintf("shader: all the preserved uniform variables' types must be %v but %v", want, got))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for i, u := range cs.uniforms {
|
for i, u := range cs.uniforms {
|
||||||
if !strings.HasPrefix(u, "__") {
|
if !strings.HasPrefix(u, "__") {
|
||||||
unames = append(unames, u)
|
unames = append(unames, u)
|
||||||
|
16
internal/shader/testdata/array.expected.vs
vendored
16
internal/shader/testdata/array.expected.vs
vendored
@ -1,17 +1,17 @@
|
|||||||
uniform vec2[4] U0;
|
uniform vec2 U0[4];
|
||||||
|
|
||||||
void F0(out vec2[2] l0);
|
void F0(out vec2 l0[2]);
|
||||||
void F1(out vec2[2] l0);
|
void F1(out vec2 l0[2]);
|
||||||
|
|
||||||
void F0(out vec2[2] l0) {
|
void F0(out vec2 l0[2]) {
|
||||||
vec2[2] l1 = vec2[2](vec2(0), vec2(0));
|
vec2 l1[2] = vec2[2](vec2(0), vec2(0));
|
||||||
l0 = l1;
|
l0 = l1;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
void F1(out vec2[2] l0) {
|
void F1(out vec2 l0[2]) {
|
||||||
vec2[2] l1 = vec2[2](vec2(0), vec2(0));
|
vec2 l1[2] = vec2[2](vec2(0), vec2(0));
|
||||||
vec2[2] l2 = vec2[2](vec2(0), vec2(0));
|
vec2 l2[2] = vec2[2](vec2(0), vec2(0));
|
||||||
(l1)[0] = vec2(1.0);
|
(l1)[0] = vec2(1.0);
|
||||||
l2 = l1;
|
l2 = l1;
|
||||||
((l2)[1]).y = vec2(2.0);
|
((l2)[1]).y = vec2(2.0);
|
||||||
|
@ -168,12 +168,12 @@ func (p *Program) Glsl() (vertexShader, fragmentShader string) {
|
|||||||
return strings.Join(vslines, "\n") + "\n", strings.Join(fslines, "\n") + "\n"
|
return strings.Join(vslines, "\n") + "\n", strings.Join(fslines, "\n") + "\n"
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Program) glslType(t *Type) string {
|
func (p *Program) glslType(t *Type) (string, string) {
|
||||||
switch t.Main {
|
switch t.Main {
|
||||||
case None:
|
case None:
|
||||||
return "void"
|
return "void", ""
|
||||||
case Struct:
|
case Struct:
|
||||||
return p.structName(t)
|
return p.structName(t), ""
|
||||||
default:
|
default:
|
||||||
return t.Glsl()
|
return t.Glsl()
|
||||||
}
|
}
|
||||||
@ -186,7 +186,8 @@ func (p *Program) glslVarDecl(t *Type, varname string) string {
|
|||||||
case Struct:
|
case Struct:
|
||||||
return fmt.Sprintf("%s %s", p.structName(t), varname)
|
return fmt.Sprintf("%s %s", p.structName(t), varname)
|
||||||
default:
|
default:
|
||||||
return fmt.Sprintf("%s %s", t.Glsl(), varname)
|
t0, t1 := t.Glsl()
|
||||||
|
return fmt.Sprintf("%s %s%s", t0, varname, t1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -200,7 +201,8 @@ func (p *Program) glslVarInit(t *Type) string {
|
|||||||
for i := 0; i < t.Length; i++ {
|
for i := 0; i < t.Length; i++ {
|
||||||
es = append(es, init)
|
es = append(es, init)
|
||||||
}
|
}
|
||||||
return fmt.Sprintf("%s[%d](%s)", t.Sub[0].Glsl(), t.Length, strings.Join(es, ", "))
|
t0, t1 := t.Glsl()
|
||||||
|
return fmt.Sprintf("%s%s(%s)", t0, t1, strings.Join(es, ", "))
|
||||||
case Struct:
|
case Struct:
|
||||||
panic("not implemented")
|
panic("not implemented")
|
||||||
case Bool:
|
case Bool:
|
||||||
@ -222,7 +224,8 @@ func (p *Program) glslVarInit(t *Type) string {
|
|||||||
case Mat4:
|
case Mat4:
|
||||||
return "mat4(0)"
|
return "mat4(0)"
|
||||||
default:
|
default:
|
||||||
panic(fmt.Sprintf("?(unexpected type: %s)", p.glslType(t)))
|
t0, t1 := p.glslType(t)
|
||||||
|
panic(fmt.Sprintf("?(unexpected type: %s%s)", t0, t1))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -242,7 +245,8 @@ func (p *Program) glslFunc(f *Func, prototype bool) []string {
|
|||||||
argsstr = strings.Join(args, ", ")
|
argsstr = strings.Join(args, ", ")
|
||||||
}
|
}
|
||||||
|
|
||||||
sig := fmt.Sprintf("%s F%d(%s)", p.glslType(&f.Return), f.Index, argsstr)
|
t0, t1 := p.glslType(&f.Return)
|
||||||
|
sig := fmt.Sprintf("%s%s F%d(%s)", t0, t1, f.Index, argsstr)
|
||||||
|
|
||||||
var lines []string
|
var lines []string
|
||||||
if prototype {
|
if prototype {
|
||||||
@ -436,7 +440,8 @@ func (p *Program) glslBlock(topBlock, block *Block, level int, localVarIndex int
|
|||||||
t := s.ForVarType
|
t := s.ForVarType
|
||||||
init := constantToNumberLiteral(ct, s.ForInit)
|
init := constantToNumberLiteral(ct, s.ForInit)
|
||||||
end := constantToNumberLiteral(ct, s.ForEnd)
|
end := constantToNumberLiteral(ct, s.ForEnd)
|
||||||
lines = append(lines, fmt.Sprintf("%sfor (%s %s = %s; %s %s %s; %s) {", idt, t.Glsl(), v, init, v, op, end, delta))
|
t0, t1 := t.Glsl()
|
||||||
|
lines = append(lines, fmt.Sprintf("%sfor (%s %s%s = %s; %s %s %s; %s) {", idt, t0, v, t1, init, v, op, end, delta))
|
||||||
lines = append(lines, p.glslBlock(topBlock, &s.Blocks[0], level+1, localVarIndex)...)
|
lines = append(lines, p.glslBlock(topBlock, &s.Blocks[0], level+1, localVarIndex)...)
|
||||||
lines = append(lines, fmt.Sprintf("%s}", idt))
|
lines = append(lines, fmt.Sprintf("%s}", idt))
|
||||||
case Continue:
|
case Continue:
|
||||||
|
@ -85,14 +85,15 @@ func (t *Type) serialize() string {
|
|||||||
return t.String()
|
return t.String()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *Type) Glsl() string {
|
func (t *Type) Glsl() (string, string) {
|
||||||
switch t.Main {
|
switch t.Main {
|
||||||
case Array:
|
case Array:
|
||||||
return fmt.Sprintf("%s[%d]", t.Sub[0].Glsl(), t.Length)
|
t0, t1 := t.Sub[0].Glsl()
|
||||||
|
return t0 + t1, fmt.Sprintf("[%d]", t.Length)
|
||||||
case Struct:
|
case Struct:
|
||||||
panic("shaderir: a struct is not implemented")
|
panic("shaderir: a struct is not implemented")
|
||||||
default:
|
default:
|
||||||
return t.Main.glsl()
|
return t.Main.glsl(), ""
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -225,8 +225,19 @@ func defaultProgram() shaderir.Program {
|
|||||||
}
|
}
|
||||||
|
|
||||||
p.Uniforms = make([]shaderir.Type, graphics.PreservedUniformVariablesNum)
|
p.Uniforms = make([]shaderir.Type, graphics.PreservedUniformVariablesNum)
|
||||||
for i := range p.Uniforms {
|
// Destination texture size
|
||||||
p.Uniforms[i] = shaderir.Type{Main: shaderir.Vec2}
|
p.Uniforms[0] = shaderir.Type{Main: shaderir.Vec2}
|
||||||
|
// Source texture sizes
|
||||||
|
p.Uniforms[1] = shaderir.Type{
|
||||||
|
Main: shaderir.Array,
|
||||||
|
Length: graphics.ShaderImageNum,
|
||||||
|
Sub: []shaderir.Type{{Main: shaderir.Vec2}},
|
||||||
|
}
|
||||||
|
// Source texture offsets
|
||||||
|
p.Uniforms[2] = shaderir.Type{
|
||||||
|
Main: shaderir.Array,
|
||||||
|
Length: graphics.ShaderImageNum - 1,
|
||||||
|
Sub: []shaderir.Type{{Main: shaderir.Vec2}},
|
||||||
}
|
}
|
||||||
return p
|
return p
|
||||||
}
|
}
|
||||||
@ -350,8 +361,18 @@ func ShaderProgramImages(imageNum int) shaderir.Program {
|
|||||||
Exprs: []shaderir.Expr{
|
Exprs: []shaderir.Expr{
|
||||||
texPos,
|
texPos,
|
||||||
{
|
{
|
||||||
Type: shaderir.UniformVariable,
|
Type: shaderir.Index,
|
||||||
Index: graphics.TextureOffsetUniformVariableIndex(i),
|
Exprs: []shaderir.Expr{
|
||||||
|
{
|
||||||
|
Type: shaderir.UniformVariable,
|
||||||
|
Index: graphics.TextureOffsetsUniformVariableIndex,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Type: shaderir.NumberExpr,
|
||||||
|
Const: constant.MakeInt64(int64(i - 1)),
|
||||||
|
ConstType: shaderir.ConstTypeInt,
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
17
shader.go
17
shader.go
@ -36,23 +36,26 @@ func textureDstSize() vec2 {
|
|||||||
}
|
}
|
||||||
`
|
`
|
||||||
|
|
||||||
|
shaderSuffix += fmt.Sprintf(`
|
||||||
|
var __textureSizes [%d]vec2
|
||||||
|
`, graphics.ShaderImageNum)
|
||||||
|
|
||||||
for i := 0; i < graphics.ShaderImageNum; i++ {
|
for i := 0; i < graphics.ShaderImageNum; i++ {
|
||||||
shaderSuffix += fmt.Sprintf(`
|
shaderSuffix += fmt.Sprintf(`
|
||||||
var __textureSize%[1]d vec2
|
|
||||||
|
|
||||||
func texture%[1]dSize() vec2 {
|
func texture%[1]dSize() vec2 {
|
||||||
return __textureSize%[1]d
|
return __textureSizes[%[1]d]
|
||||||
}
|
}
|
||||||
`, i)
|
`, i)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
shaderSuffix += fmt.Sprintf(`
|
||||||
|
var __textureOffsets [%d]vec2
|
||||||
|
`, graphics.ShaderImageNum-1)
|
||||||
|
|
||||||
for i := 0; i < graphics.ShaderImageNum; i++ {
|
for i := 0; i < graphics.ShaderImageNum; i++ {
|
||||||
var offset string
|
var offset string
|
||||||
if i >= 1 {
|
if i >= 1 {
|
||||||
shaderSuffix += fmt.Sprintf(`
|
offset = fmt.Sprintf(" + __textureOffsets[%d]", i-1)
|
||||||
var __textureOffset%[1]d vec2
|
|
||||||
`, i)
|
|
||||||
offset = fmt.Sprintf(" + __textureOffset%d", i)
|
|
||||||
}
|
}
|
||||||
// __t%d is a special variable for a texture variable.
|
// __t%d is a special variable for a texture variable.
|
||||||
shaderSuffix += fmt.Sprintf(`
|
shaderSuffix += fmt.Sprintf(`
|
||||||
|
Loading…
Reference in New Issue
Block a user