From f92253487f627aa7d69806a3174b242ee71225a2 Mon Sep 17 00:00:00 2001 From: Hajime Hoshi Date: Sat, 30 May 2020 03:21:45 +0900 Subject: [PATCH] buffered: Add Shader --- image.go | 2 +- internal/buffered/image.go | 38 ++++++++++++++++++++++++++++++--- internal/buffered/image_test.go | 2 ++ internal/mipmap/mipmap.go | 1 + 4 files changed, 39 insertions(+), 4 deletions(-) diff --git a/image.go b/image.go index 4d85878af981..c7336c729dfd 100644 --- a/image.go +++ b/image.go @@ -331,7 +331,7 @@ func (i *Image) DrawTriangles(vertices []Vertex, indices []uint16, img *Image, o is := make([]uint16, len(indices)) copy(is, indices) - i.buffered.DrawTriangles(img.buffered, vs, is, options.ColorM.impl, mode, filter, driver.Address(options.Address)) + i.buffered.DrawTriangles(img.buffered, vs, is, options.ColorM.impl, mode, filter, driver.Address(options.Address), nil, nil) } // SubImage returns an image representing the portion of the image p visible through r. The returned value shares pixels with the original image. diff --git a/internal/buffered/image.go b/internal/buffered/image.go index 4832c6e3b98d..c3a39903851d 100644 --- a/internal/buffered/image.go +++ b/internal/buffered/image.go @@ -22,6 +22,7 @@ import ( "github.com/hajimehoshi/ebiten/internal/affine" "github.com/hajimehoshi/ebiten/internal/driver" "github.com/hajimehoshi/ebiten/internal/mipmap" + "github.com/hajimehoshi/ebiten/internal/shaderir" ) type Image struct { @@ -286,7 +287,7 @@ func (i *Image) drawImage(src *Image, bounds image.Rectangle, g mipmap.GeoM, col // DrawTriangles draws the src image with the given vertices. // // Copying vertices and indices is the caller's responsibility. -func (i *Image) DrawTriangles(src *Image, vertices []float32, indices []uint16, colorm *affine.ColorM, mode driver.CompositeMode, filter driver.Filter, address driver.Address) { +func (i *Image) DrawTriangles(src *Image, vertices []float32, indices []uint16, colorm *affine.ColorM, mode driver.CompositeMode, filter driver.Filter, address driver.Address, shader *Shader, uniforms []interface{}) { if i == src { panic("buffered: Image.DrawTriangles: src must be different from the receiver") } @@ -297,7 +298,7 @@ func (i *Image) DrawTriangles(src *Image, vertices []float32, indices []uint16, if needsToDelayCommands { delayedCommands = append(delayedCommands, func() error { // Arguments are not copied. Copying is the caller's responsibility. - i.DrawTriangles(src, vertices, indices, colorm, mode, filter, address) + i.DrawTriangles(src, vertices, indices, colorm, mode, filter, address, shader, uniforms) return nil }) return @@ -305,5 +306,36 @@ func (i *Image) DrawTriangles(src *Image, vertices []float32, indices []uint16, src.resolvePendingPixels(true) i.resolvePendingPixels(false) - i.img.DrawTriangles(src.img, vertices, indices, colorm, mode, filter, address, nil, nil) + + var s *mipmap.Shader + if shader != nil { + s = shader.shader + } + us := make([]interface{}, len(uniforms)) + for k, v := range uniforms { + switch v := v.(type) { + case *Image: + i.resolvePendingPixels(true) + us[k] = v.img + default: + us[k] = v + } + } + + i.img.DrawTriangles(src.img, vertices, indices, colorm, mode, filter, address, s, us) +} + +type Shader struct { + shader *mipmap.Shader +} + +func NewShader(program *shaderir.Program) *Shader { + return &Shader{ + shader: mipmap.NewShader(program), + } +} + +func (s *Shader) MarkDisposed() { + s.shader.MarkDisposed() + s.shader = nil } diff --git a/internal/buffered/image_test.go b/internal/buffered/image_test.go index 58a921fad950..2c1d22d6c00e 100644 --- a/internal/buffered/image_test.go +++ b/internal/buffered/image_test.go @@ -306,3 +306,5 @@ func TestReplacePixelsAndModifyBeforeMain(t *testing.T) { t.Errorf("got: %v, want: %v", got, want) } } + +// TODO: Add tests for shaders and ReplacePixels to check resolvePendingPiexles works correctly. diff --git a/internal/mipmap/mipmap.go b/internal/mipmap/mipmap.go index 1ac39799e165..104cda7517f5 100644 --- a/internal/mipmap/mipmap.go +++ b/internal/mipmap/mipmap.go @@ -184,6 +184,7 @@ func (m *Mipmap) DrawTriangles(src *Mipmap, vertices []float32, indices []uint16 vertices[i*n+11] *= ca } } + var s *shareable.Shader if shader != nil { s = shader.shader