mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-11-10 04:57:26 +01:00
shader: Reland: Add a predefined uniform variable: __viewportSize
This commit is contained in:
parent
dde7d00231
commit
ba36d5a8e9
@ -29,17 +29,20 @@ const (
|
||||
|
||||
const shaderSrc = `package main
|
||||
|
||||
// __viewportSize is a predefined uniform variable.
|
||||
// TODO: Hide this by a function.
|
||||
|
||||
func Vertex(position vec2, texCoord vec2, color vec4) vec4 {
|
||||
return mat4(
|
||||
2.0/640, 0, 0, 0,
|
||||
0, 2.0/480, 0, 0,
|
||||
2.0/__viewportSize.x, 0, 0, 0,
|
||||
0, 2.0/__viewportSize.y, 0, 0,
|
||||
0, 0, 1, 0,
|
||||
-1, -1, 0, 1,
|
||||
) * vec4(position, 0, 1)
|
||||
}
|
||||
|
||||
func Fragment(position vec4) vec4 {
|
||||
return vec4(position.x/640, position.y/480, 0, 1)
|
||||
return vec4(position.x/__viewportSize.x, position.y/__viewportSize.y, 0, 1)
|
||||
}`
|
||||
|
||||
type Game struct {
|
||||
|
4
image.go
4
image.go
@ -384,6 +384,10 @@ func (i *Image) DrawTrianglesWithShader(vertices []Vertex, indices []uint16, sha
|
||||
}
|
||||
}
|
||||
|
||||
// The first uniform variable is Internal_ViewportSize.
|
||||
// The actual value is set at graphicscommand package.
|
||||
us = append([]interface{}{[]float32{0, 0}}, us...)
|
||||
|
||||
var bx0, by0, bx1, by1 float32
|
||||
if firstImage != nil {
|
||||
b := firstImage.Bounds()
|
||||
|
@ -453,6 +453,13 @@ func (c *drawTrianglesCommand) Exec(indexOffset int) error {
|
||||
us[i] = v
|
||||
}
|
||||
}
|
||||
|
||||
// The last uniform variables are added at /shader.go and represents a viewport size.
|
||||
w, h := c.dst.InternalSize()
|
||||
viewport := us[0].([]float32)
|
||||
viewport[0] = float32(w)
|
||||
viewport[1] = float32(h)
|
||||
|
||||
return theGraphicsDriver.DrawShader(c.dst.image.ID(), c.shader.shader.ID(), c.nindices, indexOffset, c.mode, us)
|
||||
}
|
||||
return theGraphicsDriver.Draw(c.dst.image.ID(), c.src.image.ID(), c.nindices, indexOffset, c.mode, c.color, c.filter, c.address)
|
||||
|
@ -94,7 +94,7 @@ func TestShader(t *testing.T) {
|
||||
ir := etesting.ShaderProgramFill(0xff, 0, 0, 0xff)
|
||||
s := NewShader(&ir)
|
||||
us := []interface{}{
|
||||
[]float32{w, h},
|
||||
[]float32{0, 0},
|
||||
}
|
||||
dst.DrawTriangles(nil, vs, is, nil, driver.CompositeModeSourceOver, 0, 0, s, us)
|
||||
|
||||
|
@ -36,7 +36,7 @@ func TestShader(t *testing.T) {
|
||||
ir := etesting.ShaderProgramFill(0xff, 0, 0, 0xff)
|
||||
s := NewShader(&ir)
|
||||
us := []interface{}{
|
||||
0: []float32{1, 1},
|
||||
[]float32{0, 0},
|
||||
}
|
||||
img.DrawTriangles(nil, quadVertices(1, 1, 0, 0), graphics.QuadIndices(), nil, driver.CompositeModeCopy, driver.FilterNearest, driver.AddressClampToZero, s, us)
|
||||
|
||||
@ -73,7 +73,7 @@ func TestShaderChain(t *testing.T) {
|
||||
s := NewShader(&ir)
|
||||
for i := 0; i < num-1; i++ {
|
||||
us := []interface{}{
|
||||
[]float32{1, 1},
|
||||
[]float32{0, 0},
|
||||
imgs[i],
|
||||
}
|
||||
imgs[i+1].DrawTriangles(nil, quadVertices(1, 1, 0, 0), graphics.QuadIndices(), nil, driver.CompositeModeCopy, driver.FilterNearest, driver.AddressClampToZero, s, us)
|
||||
@ -113,7 +113,7 @@ func TestShaderMultipleSources(t *testing.T) {
|
||||
ir := etesting.ShaderProgramImages(3)
|
||||
s := NewShader(&ir)
|
||||
us := []interface{}{
|
||||
[]float32{1, 1},
|
||||
[]float32{0, 0},
|
||||
srcs[0],
|
||||
srcs[1],
|
||||
[]float32{0, 0, 1, 1},
|
||||
@ -150,7 +150,7 @@ func TestShaderDispose(t *testing.T) {
|
||||
ir := etesting.ShaderProgramFill(0xff, 0, 0, 0xff)
|
||||
s := NewShader(&ir)
|
||||
us := []interface{}{
|
||||
[]float32{1, 1},
|
||||
[]float32{0, 0},
|
||||
}
|
||||
img.DrawTriangles(nil, quadVertices(1, 1, 0, 0), graphics.QuadIndices(), nil, driver.CompositeModeCopy, driver.FilterNearest, driver.AddressClampToZero, s, us)
|
||||
|
||||
|
@ -136,6 +136,26 @@ func (cs *compileState) parse(f *ast.File) {
|
||||
cs.parseDecl(&cs.global, d)
|
||||
}
|
||||
}
|
||||
|
||||
// Sort the uniform variable so that special variable starting with __ should come first.
|
||||
var unames []string
|
||||
var utypes []shaderir.Type
|
||||
for i, u := range cs.uniforms {
|
||||
if strings.HasPrefix(u, "__") {
|
||||
unames = append(unames, u)
|
||||
utypes = append(utypes, cs.ir.Uniforms[i])
|
||||
}
|
||||
}
|
||||
for i, u := range cs.uniforms {
|
||||
if !strings.HasPrefix(u, "__") {
|
||||
unames = append(unames, u)
|
||||
utypes = append(utypes, cs.ir.Uniforms[i])
|
||||
}
|
||||
}
|
||||
cs.uniforms = unames
|
||||
cs.ir.Uniforms = utypes
|
||||
|
||||
// Parse functions.
|
||||
for _, d := range f.Decls {
|
||||
if _, ok := d.(*ast.FuncDecl); ok {
|
||||
cs.parseDecl(&cs.global, d)
|
||||
@ -175,10 +195,12 @@ func (cs *compileState) parseDecl(b *block, d ast.Decl) {
|
||||
vs := cs.parseVariable(b, s)
|
||||
if b == &cs.global {
|
||||
for i, v := range vs {
|
||||
if v.name[0] < 'A' || 'Z' < v.name[0] {
|
||||
cs.addError(s.Names[i].Pos(), fmt.Sprintf("global variables must be exposed: %s", v.name))
|
||||
if !strings.HasPrefix(v.name, "__") {
|
||||
if v.name[0] < 'A' || 'Z' < v.name[0] {
|
||||
cs.addError(s.Names[i].Pos(), fmt.Sprintf("global variables must be exposed: %s", v.name))
|
||||
}
|
||||
}
|
||||
// TODO: Check init
|
||||
// TODO: Check rhs
|
||||
cs.uniforms = append(cs.uniforms, v.name)
|
||||
cs.ir.Uniforms = append(cs.ir.Uniforms, v.typ.ir)
|
||||
}
|
||||
|
@ -192,7 +192,7 @@ var (
|
||||
func defaultProgram() shaderir.Program {
|
||||
return shaderir.Program{
|
||||
Uniforms: []shaderir.Type{
|
||||
{Main: shaderir.Vec2},
|
||||
{Main: shaderir.Vec2}, // Viewport size. This must be the first uniform variable, and the values are set at graphicscommand driver.
|
||||
},
|
||||
Attributes: []shaderir.Type{
|
||||
{Main: shaderir.Vec2}, // Local var (0) in the vertex shader
|
||||
|
10
shader.go
10
shader.go
@ -15,6 +15,7 @@
|
||||
package ebiten
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"go/parser"
|
||||
"go/token"
|
||||
|
||||
@ -22,13 +23,20 @@ import (
|
||||
"github.com/hajimehoshi/ebiten/internal/shader"
|
||||
)
|
||||
|
||||
const shaderSuffix = `
|
||||
var __viewportSize vec2`
|
||||
|
||||
type Shader struct {
|
||||
shader *buffered.Shader
|
||||
}
|
||||
|
||||
func NewShader(src []byte) (*Shader, error) {
|
||||
var buf bytes.Buffer
|
||||
buf.Write(src)
|
||||
buf.WriteString(shaderSuffix)
|
||||
|
||||
fs := token.NewFileSet()
|
||||
f, err := parser.ParseFile(fs, "", src, parser.AllErrors)
|
||||
f, err := parser.ParseFile(fs, "", buf.Bytes(), parser.AllErrors)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user