mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2025-01-27 03:02:49 +01:00
shaderir: Implement vertex function
This commit is contained in:
parent
eb5a2efad8
commit
ddaed674dd
@ -51,6 +51,13 @@ func (p *Program) Glsl() string {
|
|||||||
lines = append(lines, p.glslFunc(&f)...)
|
lines = append(lines, p.glslFunc(&f)...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Vertex func
|
||||||
|
if len(p.VertexFunc.Block.Stmts) > 0 {
|
||||||
|
lines = append(lines, "void main(void) {")
|
||||||
|
lines = append(lines, p.glslBlock(&p.VertexFunc.Block, 0, 0)...)
|
||||||
|
lines = append(lines, "}")
|
||||||
|
}
|
||||||
|
|
||||||
var stLines []string
|
var stLines []string
|
||||||
for i, t := range p.structTypes {
|
for i, t := range p.structTypes {
|
||||||
stLines = append(stLines, fmt.Sprintf("struct S%d {", i))
|
stLines = append(stLines, fmt.Sprintf("struct S%d {", i))
|
||||||
@ -116,13 +123,13 @@ func (p *Program) glslFunc(f *Func) []string {
|
|||||||
|
|
||||||
var lines []string
|
var lines []string
|
||||||
lines = append(lines, fmt.Sprintf("%s %s(%s) {", p.glslType(&f.Return), f.Name, argsstr))
|
lines = append(lines, fmt.Sprintf("%s %s(%s) {", p.glslType(&f.Return), f.Name, argsstr))
|
||||||
lines = append(lines, p.glslBlock(&f.Block, f, 0, idx)...)
|
lines = append(lines, p.glslBlock(&f.Block, 0, idx)...)
|
||||||
lines = append(lines, "}")
|
lines = append(lines, "}")
|
||||||
|
|
||||||
return lines
|
return lines
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Program) glslBlock(b *Block, f *Func, level int, localVarIndex int) []string {
|
func (p *Program) glslBlock(b *Block, level int, localVarIndex int) []string {
|
||||||
idt := strings.Repeat("\t", level+1)
|
idt := strings.Repeat("\t", level+1)
|
||||||
|
|
||||||
var lines []string
|
var lines []string
|
||||||
@ -142,12 +149,24 @@ func (p *Program) glslBlock(b *Block, f *Func, level int, localVarIndex int) []s
|
|||||||
switch e.Variable.Type {
|
switch e.Variable.Type {
|
||||||
case Uniform:
|
case Uniform:
|
||||||
return fmt.Sprintf("U%d", e.Variable.Index)
|
return fmt.Sprintf("U%d", e.Variable.Index)
|
||||||
case Attribute:
|
|
||||||
return fmt.Sprintf("A%d", e.Variable.Index)
|
|
||||||
case Varying:
|
|
||||||
return fmt.Sprintf("V%d", e.Variable.Index)
|
|
||||||
case Local:
|
case Local:
|
||||||
return fmt.Sprintf("l%d", e.Variable.Index)
|
idx := e.Variable.Index
|
||||||
|
if b == &p.VertexFunc.Block {
|
||||||
|
na := len(p.Attributes)
|
||||||
|
nv := len(p.Varyings)
|
||||||
|
switch {
|
||||||
|
case idx < na:
|
||||||
|
return fmt.Sprintf("A%d", idx)
|
||||||
|
case idx < na+nv:
|
||||||
|
return fmt.Sprintf("V%d", idx-na)
|
||||||
|
case idx == na+nv:
|
||||||
|
return "gl_Position"
|
||||||
|
default:
|
||||||
|
return fmt.Sprintf("l%d", idx-(na+nv))
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return fmt.Sprintf("l%d", idx)
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
return fmt.Sprintf("?(unexpected variable type: %d)", e.Variable.Type)
|
return fmt.Sprintf("?(unexpected variable type: %d)", e.Variable.Type)
|
||||||
}
|
}
|
||||||
@ -187,16 +206,16 @@ func (p *Program) glslBlock(b *Block, f *Func, level int, localVarIndex int) []s
|
|||||||
lines = append(lines, fmt.Sprintf("%s%s;", idt, glslExpr(&s.Exprs[0])))
|
lines = append(lines, fmt.Sprintf("%s%s;", idt, glslExpr(&s.Exprs[0])))
|
||||||
case BlockStmt:
|
case BlockStmt:
|
||||||
lines = append(lines, idt+"{")
|
lines = append(lines, idt+"{")
|
||||||
lines = append(lines, p.glslBlock(&s.Blocks[0], f, level+1, localVarIndex)...)
|
lines = append(lines, p.glslBlock(&s.Blocks[0], level+1, localVarIndex)...)
|
||||||
lines = append(lines, idt+"}")
|
lines = append(lines, idt+"}")
|
||||||
case Assign:
|
case Assign:
|
||||||
lines = append(lines, fmt.Sprintf("%s%s = %s;", idt, glslExpr(&s.Exprs[0]), glslExpr(&s.Exprs[1])))
|
lines = append(lines, fmt.Sprintf("%s%s = %s;", idt, glslExpr(&s.Exprs[0]), glslExpr(&s.Exprs[1])))
|
||||||
case If:
|
case If:
|
||||||
lines = append(lines, fmt.Sprintf("%sif (%s) {", idt, glslExpr(&s.Exprs[0])))
|
lines = append(lines, fmt.Sprintf("%sif (%s) {", idt, glslExpr(&s.Exprs[0])))
|
||||||
lines = append(lines, p.glslBlock(&s.Blocks[0], f, level+1, localVarIndex)...)
|
lines = append(lines, p.glslBlock(&s.Blocks[0], level+1, localVarIndex)...)
|
||||||
if len(s.Blocks) > 1 {
|
if len(s.Blocks) > 1 {
|
||||||
lines = append(lines, fmt.Sprintf("%s} else {", idt))
|
lines = append(lines, fmt.Sprintf("%s} else {", idt))
|
||||||
lines = append(lines, p.glslBlock(&s.Blocks[1], f, level+1, localVarIndex)...)
|
lines = append(lines, p.glslBlock(&s.Blocks[1], level+1, localVarIndex)...)
|
||||||
}
|
}
|
||||||
lines = append(lines, fmt.Sprintf("%s}", idt))
|
lines = append(lines, fmt.Sprintf("%s}", idt))
|
||||||
case For:
|
case For:
|
||||||
@ -225,7 +244,7 @@ func (p *Program) glslBlock(b *Block, f *Func, level int, localVarIndex int) []s
|
|||||||
op = fmt.Sprintf("?(unexpected op: %s)", string(s.ForOp))
|
op = fmt.Sprintf("?(unexpected op: %s)", string(s.ForOp))
|
||||||
}
|
}
|
||||||
lines = append(lines, fmt.Sprintf("%sfor (int l%d = %d; l%d %s %d; %s) {", idt, v, s.ForInit, v, op, s.ForEnd, delta))
|
lines = append(lines, fmt.Sprintf("%sfor (int l%d = %d; l%d %s %d; %s) {", idt, v, s.ForInit, v, op, s.ForEnd, delta))
|
||||||
lines = append(lines, p.glslBlock(&s.Blocks[0], f, level+1, localVarIndex)...)
|
lines = append(lines, p.glslBlock(&s.Blocks[0], level+1, localVarIndex)...)
|
||||||
lines = append(lines, fmt.Sprintf("%s}", idt))
|
lines = append(lines, fmt.Sprintf("%s}", idt))
|
||||||
case Continue:
|
case Continue:
|
||||||
lines = append(lines, idt+"continue;")
|
lines = append(lines, idt+"continue;")
|
||||||
@ -246,5 +265,3 @@ func (p *Program) glslBlock(b *Block, f *Func, level int, localVarIndex int) []s
|
|||||||
|
|
||||||
return lines
|
return lines
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Distinguish regular functions, vertex functions and fragment functions. e.g., Treat gl_Position correctly.
|
|
||||||
|
@ -521,6 +521,51 @@ varying vec3 V0;`,
|
|||||||
for (int l3 = 0; l3 < 100; l3++) {
|
for (int l3 = 0; l3 < 100; l3++) {
|
||||||
l2 = l0;
|
l2 = l0;
|
||||||
}
|
}
|
||||||
|
}`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "VertexFunc",
|
||||||
|
Program: Program{
|
||||||
|
Uniforms: []Type{
|
||||||
|
{Main: Float},
|
||||||
|
},
|
||||||
|
Attributes: []Type{
|
||||||
|
{Main: Vec4},
|
||||||
|
{Main: Float},
|
||||||
|
{Main: Vec2},
|
||||||
|
},
|
||||||
|
Varyings: []Type{
|
||||||
|
{Main: Float},
|
||||||
|
{Main: Vec2},
|
||||||
|
},
|
||||||
|
VertexFunc: VertexFunc{
|
||||||
|
Block: block(
|
||||||
|
nil,
|
||||||
|
assignStmt(
|
||||||
|
varNameExpr(Local, 5),
|
||||||
|
varNameExpr(Local, 0),
|
||||||
|
),
|
||||||
|
assignStmt(
|
||||||
|
varNameExpr(Local, 3),
|
||||||
|
varNameExpr(Local, 1),
|
||||||
|
),
|
||||||
|
assignStmt(
|
||||||
|
varNameExpr(Local, 4),
|
||||||
|
varNameExpr(Local, 2),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Glsl: `uniform float U0;
|
||||||
|
attribute vec4 A0;
|
||||||
|
attribute float A1;
|
||||||
|
attribute vec2 A2;
|
||||||
|
varying float V0;
|
||||||
|
varying vec2 V1;
|
||||||
|
void main(void) {
|
||||||
|
gl_Position = A0;
|
||||||
|
V0 = A1;
|
||||||
|
V1 = A2;
|
||||||
}`,
|
}`,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -19,8 +19,8 @@ type Program struct {
|
|||||||
Attributes []Type
|
Attributes []Type
|
||||||
Varyings []Type
|
Varyings []Type
|
||||||
Funcs []Func
|
Funcs []Func
|
||||||
VertexEntry string
|
VertexFunc VertexFunc
|
||||||
FragmentEntry string
|
FragmentFunc FragmentFunc
|
||||||
|
|
||||||
structNames map[string]string
|
structNames map[string]string
|
||||||
structTypes []Type
|
structTypes []Type
|
||||||
@ -37,6 +37,21 @@ type Func struct {
|
|||||||
Block Block
|
Block Block
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// VertexFunc takes pseudo params, and the number if len(attributes) + len(varyings) + 1.
|
||||||
|
// If 0 <= index < len(attributes), the params are in-params and treated as attribute variables.
|
||||||
|
// If len(attributes) <= index < len(attributes) + len(varyings), the params are out-params and treated as varying
|
||||||
|
// variables.
|
||||||
|
// The last param represents the position in vec4 (gl_Position in GLSL).
|
||||||
|
type VertexFunc struct {
|
||||||
|
Block Block
|
||||||
|
}
|
||||||
|
|
||||||
|
// FragmentFunc takes pseudo in-params, and the number is len(varyings) + 1.
|
||||||
|
// The last param represents the coordinate of the fragment (gl_FragCoord in GLSL)
|
||||||
|
type FragmentFunc struct {
|
||||||
|
Block Block
|
||||||
|
}
|
||||||
|
|
||||||
type Block struct {
|
type Block struct {
|
||||||
LocalVars []Type
|
LocalVars []Type
|
||||||
Stmts []Stmt
|
Stmts []Stmt
|
||||||
@ -100,8 +115,6 @@ type VariableType int
|
|||||||
|
|
||||||
const (
|
const (
|
||||||
Uniform VariableType = iota
|
Uniform VariableType = iota
|
||||||
Attribute
|
|
||||||
Varying
|
|
||||||
Local
|
Local
|
||||||
)
|
)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user