mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2025-01-26 02:42:02 +01:00
shader: Parse fragment entry point
This commit is contained in:
parent
382ba75139
commit
762b9788a0
@ -26,7 +26,8 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
vertexEntry = "Vertex"
|
vertexEntry = "Vertex"
|
||||||
|
fragmentEntry = "Fragment"
|
||||||
)
|
)
|
||||||
|
|
||||||
type variable struct {
|
type variable struct {
|
||||||
@ -56,14 +57,10 @@ type compileState struct {
|
|||||||
// uniforms is a collection of uniform variable names.
|
// uniforms is a collection of uniform variable names.
|
||||||
uniforms []string
|
uniforms []string
|
||||||
|
|
||||||
// attributes is a collection of attribute variable names.
|
|
||||||
attributes []string
|
|
||||||
|
|
||||||
// varyings is a collection of varying variable names.
|
|
||||||
varyings []string
|
|
||||||
|
|
||||||
global block
|
global block
|
||||||
|
|
||||||
|
varyingParsed bool
|
||||||
|
|
||||||
errs []string
|
errs []string
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -206,8 +203,15 @@ func (cs *compileState) parseDecl(b *block, d ast.Decl) {
|
|||||||
}
|
}
|
||||||
case *ast.FuncDecl:
|
case *ast.FuncDecl:
|
||||||
f := cs.parseFunc(b, d)
|
f := cs.parseFunc(b, d)
|
||||||
if b == &cs.global && d.Name.Name == vertexEntry {
|
if b == &cs.global {
|
||||||
cs.ir.VertexFunc.Block = f.ir.Block
|
switch d.Name.Name {
|
||||||
|
case vertexEntry:
|
||||||
|
cs.ir.VertexFunc.Block = f.ir.Block
|
||||||
|
case fragmentEntry:
|
||||||
|
cs.ir.FragmentFunc.Block = f.ir.Block
|
||||||
|
default:
|
||||||
|
b.funcs = append(b.funcs, f)
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
b.funcs = append(b.funcs, f)
|
b.funcs = append(b.funcs, f)
|
||||||
}
|
}
|
||||||
@ -310,29 +314,71 @@ func (cs *compileState) parseFunc(block *block, d *ast.FuncDecl) function {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if block == &cs.global && d.Name.Name == vertexEntry {
|
checkVaryings := func(types []shaderir.Type) {
|
||||||
for _, v := range inParams {
|
if len(cs.ir.Varyings) != len(types) {
|
||||||
cs.attributes = append(cs.attributes, v.name)
|
cs.addError(d.Pos(), fmt.Sprintf("the number of vertex entry point's returning values and the number of framgent entry point's params must be the same"))
|
||||||
|
return
|
||||||
}
|
}
|
||||||
for _, t := range inT {
|
for i, t := range cs.ir.Varyings {
|
||||||
cs.ir.Attributes = append(cs.ir.Attributes, t)
|
if t.Main != types[i].Main {
|
||||||
|
cs.addError(d.Pos(), fmt.Sprintf("vertex entry point's returning value types and framgent entry point's param types must match"))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// The first out-param is treated as gl_Position in GLSL.
|
if block == &cs.global {
|
||||||
if len(outParams) == 0 {
|
switch d.Name.Name {
|
||||||
cs.addError(d.Pos(), fmt.Sprintf("vertex entry point must have at least one return vec4 value for a positoin"))
|
case vertexEntry:
|
||||||
return function{}
|
for _, t := range inT {
|
||||||
}
|
cs.ir.Attributes = append(cs.ir.Attributes, t)
|
||||||
if outT[0].Main != shaderir.Vec4 {
|
}
|
||||||
cs.addError(d.Pos(), fmt.Sprintf("vertex entry point must have at least one return vec4 value for a positoin"))
|
|
||||||
return function{}
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, v := range outParams[1:] {
|
// The first out-param is treated as gl_Position in GLSL.
|
||||||
cs.varyings = append(cs.varyings, v.name)
|
if len(outParams) == 0 {
|
||||||
}
|
cs.addError(d.Pos(), fmt.Sprintf("vertex entry point must have at least one returning vec4 value for a position"))
|
||||||
for _, t := range outT[1:] {
|
return function{}
|
||||||
cs.ir.Varyings = append(cs.ir.Varyings, t)
|
}
|
||||||
|
if outT[0].Main != shaderir.Vec4 {
|
||||||
|
cs.addError(d.Pos(), fmt.Sprintf("vertex entry point must have at least one returning vec4 value for a position"))
|
||||||
|
return function{}
|
||||||
|
}
|
||||||
|
|
||||||
|
if cs.varyingParsed {
|
||||||
|
checkVaryings(outT[1:])
|
||||||
|
} else {
|
||||||
|
for _, t := range outT[1:] {
|
||||||
|
// TODO: Check that these params are not arrays or structs
|
||||||
|
cs.ir.Varyings = append(cs.ir.Varyings, t)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cs.varyingParsed = true
|
||||||
|
case fragmentEntry:
|
||||||
|
if len(inParams) == 0 {
|
||||||
|
cs.addError(d.Pos(), fmt.Sprintf("fragment entry point must have at least one vec4 parameter for a position"))
|
||||||
|
return function{}
|
||||||
|
}
|
||||||
|
if inT[0].Main != shaderir.Vec4 {
|
||||||
|
cs.addError(d.Pos(), fmt.Sprintf("fragment entry point must have at least one vec4 parameter for a position"))
|
||||||
|
return function{}
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(outParams) != 1 {
|
||||||
|
cs.addError(d.Pos(), fmt.Sprintf("fragment entry point must have one returning vec4 value for a color"))
|
||||||
|
return function{}
|
||||||
|
}
|
||||||
|
if outT[0].Main != shaderir.Vec4 {
|
||||||
|
cs.addError(d.Pos(), fmt.Sprintf("fragment entry point must have one returning vec4 value for a color"))
|
||||||
|
return function{}
|
||||||
|
}
|
||||||
|
|
||||||
|
if cs.varyingParsed {
|
||||||
|
checkVaryings(inT[1:])
|
||||||
|
} else {
|
||||||
|
for _, t := range inT[1:] {
|
||||||
|
cs.ir.Varyings = append(cs.ir.Varyings, t)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cs.varyingParsed = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -165,6 +165,49 @@ void main(void) {
|
|||||||
varying vec2 V0;
|
varying vec2 V0;
|
||||||
varying vec4 V1;`,
|
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 {
|
for _, tc := range tests {
|
||||||
t.Run(tc.Name, func(t *testing.T) {
|
t.Run(tc.Name, func(t *testing.T) {
|
||||||
|
Loading…
Reference in New Issue
Block a user