mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-12-24 02:38:53 +01:00
parent
2b4cf7fd17
commit
a4334c5464
@ -23,19 +23,14 @@ const (
|
||||
|
||||
// PreservedUniformVariablesNum represents the number of preserved 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
|
||||
ShaderImageNum + // the texture sizes
|
||||
(ShaderImageNum - 1) // the offsets of the second and the following images
|
||||
)
|
||||
1 + // the texture sizes array
|
||||
1 // the offsets array of the second and the following images
|
||||
|
||||
func TextureOffsetUniformVariableIndex(i int) int {
|
||||
if i == 0 {
|
||||
panic("graphics: the texture 0 doesn't have its offset")
|
||||
}
|
||||
return 1 + ShaderImageNum + i - 1
|
||||
}
|
||||
DestinationTextureSizeUniformVariableIndex = 0
|
||||
TextureSizesUniformVariableIndex = 1
|
||||
TextureOffsetsUniformVariableIndex = 2
|
||||
)
|
||||
|
||||
const (
|
||||
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].typ = s.ir.Uniforms[0]
|
||||
|
||||
vsizes := make([]float32, 2*len(srcs))
|
||||
for i, src := range srcs {
|
||||
img := g.images[src]
|
||||
var w, h int
|
||||
if img != nil {
|
||||
w, h = img.framebufferSize()
|
||||
if img := g.images[src]; img != nil {
|
||||
w, h := img.framebufferSize()
|
||||
vsizes[2*i] = float32(w)
|
||||
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 {
|
||||
const offset = 1 + graphics.ShaderImageNum
|
||||
o := o
|
||||
us[i+offset].name = fmt.Sprintf("U%d", i+offset)
|
||||
us[i+offset].value = o[:]
|
||||
us[i+offset].typ = s.ir.Uniforms[i+offset]
|
||||
voffsets[2*i] = o[0]
|
||||
voffsets[2*i+1] = o[1]
|
||||
}
|
||||
{
|
||||
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 {
|
||||
|
@ -182,11 +182,6 @@ func (cs *compileState) parse(f *ast.File) {
|
||||
}
|
||||
}
|
||||
// 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 {
|
||||
if !strings.HasPrefix(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 F1(out vec2[2] l0);
|
||||
void F0(out vec2 l0[2]);
|
||||
void F1(out vec2 l0[2]);
|
||||
|
||||
void F0(out vec2[2] l0) {
|
||||
vec2[2] l1 = vec2[2](vec2(0), vec2(0));
|
||||
void F0(out vec2 l0[2]) {
|
||||
vec2 l1[2] = vec2[2](vec2(0), vec2(0));
|
||||
l0 = l1;
|
||||
return;
|
||||
}
|
||||
|
||||
void F1(out vec2[2] l0) {
|
||||
vec2[2] l1 = vec2[2](vec2(0), vec2(0));
|
||||
vec2[2] l2 = vec2[2](vec2(0), vec2(0));
|
||||
void F1(out vec2 l0[2]) {
|
||||
vec2 l1[2] = vec2[2](vec2(0), vec2(0));
|
||||
vec2 l2[2] = vec2[2](vec2(0), vec2(0));
|
||||
(l1)[0] = vec2(1.0);
|
||||
l2 = l1;
|
||||
((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"
|
||||
}
|
||||
|
||||
func (p *Program) glslType(t *Type) string {
|
||||
func (p *Program) glslType(t *Type) (string, string) {
|
||||
switch t.Main {
|
||||
case None:
|
||||
return "void"
|
||||
return "void", ""
|
||||
case Struct:
|
||||
return p.structName(t)
|
||||
return p.structName(t), ""
|
||||
default:
|
||||
return t.Glsl()
|
||||
}
|
||||
@ -186,7 +186,8 @@ func (p *Program) glslVarDecl(t *Type, varname string) string {
|
||||
case Struct:
|
||||
return fmt.Sprintf("%s %s", p.structName(t), varname)
|
||||
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++ {
|
||||
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:
|
||||
panic("not implemented")
|
||||
case Bool:
|
||||
@ -222,7 +224,8 @@ func (p *Program) glslVarInit(t *Type) string {
|
||||
case Mat4:
|
||||
return "mat4(0)"
|
||||
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, ", ")
|
||||
}
|
||||
|
||||
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
|
||||
if prototype {
|
||||
@ -436,7 +440,8 @@ func (p *Program) glslBlock(topBlock, block *Block, level int, localVarIndex int
|
||||
t := s.ForVarType
|
||||
init := constantToNumberLiteral(ct, s.ForInit)
|
||||
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, fmt.Sprintf("%s}", idt))
|
||||
case Continue:
|
||||
|
@ -85,14 +85,15 @@ func (t *Type) serialize() string {
|
||||
return t.String()
|
||||
}
|
||||
|
||||
func (t *Type) Glsl() string {
|
||||
func (t *Type) Glsl() (string, string) {
|
||||
switch t.Main {
|
||||
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:
|
||||
panic("shaderir: a struct is not implemented")
|
||||
default:
|
||||
return t.Main.glsl()
|
||||
return t.Main.glsl(), ""
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -225,8 +225,19 @@ func defaultProgram() shaderir.Program {
|
||||
}
|
||||
|
||||
p.Uniforms = make([]shaderir.Type, graphics.PreservedUniformVariablesNum)
|
||||
for i := range p.Uniforms {
|
||||
p.Uniforms[i] = shaderir.Type{Main: shaderir.Vec2}
|
||||
// Destination texture size
|
||||
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
|
||||
}
|
||||
@ -350,8 +361,18 @@ func ShaderProgramImages(imageNum int) shaderir.Program {
|
||||
Exprs: []shaderir.Expr{
|
||||
texPos,
|
||||
{
|
||||
Type: shaderir.UniformVariable,
|
||||
Index: graphics.TextureOffsetUniformVariableIndex(i),
|
||||
Type: shaderir.Index,
|
||||
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++ {
|
||||
shaderSuffix += fmt.Sprintf(`
|
||||
var __textureSize%[1]d vec2
|
||||
|
||||
func texture%[1]dSize() vec2 {
|
||||
return __textureSize%[1]d
|
||||
return __textureSizes[%[1]d]
|
||||
}
|
||||
`, i)
|
||||
}
|
||||
|
||||
shaderSuffix += fmt.Sprintf(`
|
||||
var __textureOffsets [%d]vec2
|
||||
`, graphics.ShaderImageNum-1)
|
||||
|
||||
for i := 0; i < graphics.ShaderImageNum; i++ {
|
||||
var offset string
|
||||
if i >= 1 {
|
||||
shaderSuffix += fmt.Sprintf(`
|
||||
var __textureOffset%[1]d vec2
|
||||
`, i)
|
||||
offset = fmt.Sprintf(" + __textureOffset%d", i)
|
||||
offset = fmt.Sprintf(" + __textureOffsets[%d]", i-1)
|
||||
}
|
||||
// __t%d is a special variable for a texture variable.
|
||||
shaderSuffix += fmt.Sprintf(`
|
||||
|
Loading…
Reference in New Issue
Block a user