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
|
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 {
|
func Vertex(position vec2, texCoord vec2, color vec4) vec4 {
|
||||||
return mat4(
|
return mat4(
|
||||||
2.0/640, 0, 0, 0,
|
2.0/__viewportSize.x, 0, 0, 0,
|
||||||
0, 2.0/480, 0, 0,
|
0, 2.0/__viewportSize.y, 0, 0,
|
||||||
0, 0, 1, 0,
|
0, 0, 1, 0,
|
||||||
-1, -1, 0, 1,
|
-1, -1, 0, 1,
|
||||||
) * vec4(position, 0, 1)
|
) * vec4(position, 0, 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
func Fragment(position vec4) vec4 {
|
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 {
|
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
|
var bx0, by0, bx1, by1 float32
|
||||||
if firstImage != nil {
|
if firstImage != nil {
|
||||||
b := firstImage.Bounds()
|
b := firstImage.Bounds()
|
||||||
|
@ -453,6 +453,13 @@ func (c *drawTrianglesCommand) Exec(indexOffset int) error {
|
|||||||
us[i] = v
|
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.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)
|
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)
|
ir := etesting.ShaderProgramFill(0xff, 0, 0, 0xff)
|
||||||
s := NewShader(&ir)
|
s := NewShader(&ir)
|
||||||
us := []interface{}{
|
us := []interface{}{
|
||||||
[]float32{w, h},
|
[]float32{0, 0},
|
||||||
}
|
}
|
||||||
dst.DrawTriangles(nil, vs, is, nil, driver.CompositeModeSourceOver, 0, 0, s, us)
|
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)
|
ir := etesting.ShaderProgramFill(0xff, 0, 0, 0xff)
|
||||||
s := NewShader(&ir)
|
s := NewShader(&ir)
|
||||||
us := []interface{}{
|
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)
|
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)
|
s := NewShader(&ir)
|
||||||
for i := 0; i < num-1; i++ {
|
for i := 0; i < num-1; i++ {
|
||||||
us := []interface{}{
|
us := []interface{}{
|
||||||
[]float32{1, 1},
|
[]float32{0, 0},
|
||||||
imgs[i],
|
imgs[i],
|
||||||
}
|
}
|
||||||
imgs[i+1].DrawTriangles(nil, quadVertices(1, 1, 0, 0), graphics.QuadIndices(), nil, driver.CompositeModeCopy, driver.FilterNearest, driver.AddressClampToZero, s, us)
|
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)
|
ir := etesting.ShaderProgramImages(3)
|
||||||
s := NewShader(&ir)
|
s := NewShader(&ir)
|
||||||
us := []interface{}{
|
us := []interface{}{
|
||||||
[]float32{1, 1},
|
[]float32{0, 0},
|
||||||
srcs[0],
|
srcs[0],
|
||||||
srcs[1],
|
srcs[1],
|
||||||
[]float32{0, 0, 1, 1},
|
[]float32{0, 0, 1, 1},
|
||||||
@ -150,7 +150,7 @@ func TestShaderDispose(t *testing.T) {
|
|||||||
ir := etesting.ShaderProgramFill(0xff, 0, 0, 0xff)
|
ir := etesting.ShaderProgramFill(0xff, 0, 0, 0xff)
|
||||||
s := NewShader(&ir)
|
s := NewShader(&ir)
|
||||||
us := []interface{}{
|
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)
|
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)
|
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 {
|
for _, d := range f.Decls {
|
||||||
if _, ok := d.(*ast.FuncDecl); ok {
|
if _, ok := d.(*ast.FuncDecl); ok {
|
||||||
cs.parseDecl(&cs.global, d)
|
cs.parseDecl(&cs.global, d)
|
||||||
@ -175,10 +195,12 @@ func (cs *compileState) parseDecl(b *block, d ast.Decl) {
|
|||||||
vs := cs.parseVariable(b, s)
|
vs := cs.parseVariable(b, s)
|
||||||
if b == &cs.global {
|
if b == &cs.global {
|
||||||
for i, v := range vs {
|
for i, v := range vs {
|
||||||
|
if !strings.HasPrefix(v.name, "__") {
|
||||||
if v.name[0] < 'A' || 'Z' < v.name[0] {
|
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))
|
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.uniforms = append(cs.uniforms, v.name)
|
||||||
cs.ir.Uniforms = append(cs.ir.Uniforms, v.typ.ir)
|
cs.ir.Uniforms = append(cs.ir.Uniforms, v.typ.ir)
|
||||||
}
|
}
|
||||||
|
@ -192,7 +192,7 @@ var (
|
|||||||
func defaultProgram() shaderir.Program {
|
func defaultProgram() shaderir.Program {
|
||||||
return shaderir.Program{
|
return shaderir.Program{
|
||||||
Uniforms: []shaderir.Type{
|
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{
|
Attributes: []shaderir.Type{
|
||||||
{Main: shaderir.Vec2}, // Local var (0) in the vertex shader
|
{Main: shaderir.Vec2}, // Local var (0) in the vertex shader
|
||||||
|
10
shader.go
10
shader.go
@ -15,6 +15,7 @@
|
|||||||
package ebiten
|
package ebiten
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"go/parser"
|
"go/parser"
|
||||||
"go/token"
|
"go/token"
|
||||||
|
|
||||||
@ -22,13 +23,20 @@ import (
|
|||||||
"github.com/hajimehoshi/ebiten/internal/shader"
|
"github.com/hajimehoshi/ebiten/internal/shader"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const shaderSuffix = `
|
||||||
|
var __viewportSize vec2`
|
||||||
|
|
||||||
type Shader struct {
|
type Shader struct {
|
||||||
shader *buffered.Shader
|
shader *buffered.Shader
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewShader(src []byte) (*Shader, error) {
|
func NewShader(src []byte) (*Shader, error) {
|
||||||
|
var buf bytes.Buffer
|
||||||
|
buf.Write(src)
|
||||||
|
buf.WriteString(shaderSuffix)
|
||||||
|
|
||||||
fs := token.NewFileSet()
|
fs := token.NewFileSet()
|
||||||
f, err := parser.ParseFile(fs, "", src, parser.AllErrors)
|
f, err := parser.ParseFile(fs, "", buf.Bytes(), parser.AllErrors)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user