mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2025-02-20 15:00:08 +01:00
Compare commits
4 Commits
393437b8be
...
4e6fdc6db5
Author | SHA1 | Date | |
---|---|---|---|
|
4e6fdc6db5 | ||
|
1488e5e685 | ||
|
4fa8265c58 | ||
|
46cf09197b |
@ -46,7 +46,7 @@ func newGameForUI(game Game, transparent bool) *gameForUI {
|
|||||||
transparent: transparent,
|
transparent: transparent,
|
||||||
}
|
}
|
||||||
|
|
||||||
s, err := NewShader(builtinshader.ScreenShaderSource)
|
s, err := newShader(builtinshader.ScreenShaderSource, "screen")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(fmt.Sprintf("ebiten: compiling the screen shader failed: %v", err))
|
panic(fmt.Sprintf("ebiten: compiling the screen shader failed: %v", err))
|
||||||
}
|
}
|
||||||
|
4
go.mod
4
go.mod
@ -9,7 +9,7 @@ require (
|
|||||||
github.com/ebitengine/purego v0.8.0-alpha.5
|
github.com/ebitengine/purego v0.8.0-alpha.5
|
||||||
github.com/gen2brain/mpeg v0.3.2-0.20240412154320-a2ac4fc8a46f
|
github.com/gen2brain/mpeg v0.3.2-0.20240412154320-a2ac4fc8a46f
|
||||||
github.com/go-text/typesetting v0.1.1
|
github.com/go-text/typesetting v0.1.1
|
||||||
github.com/hajimehoshi/bitmapfont/v3 v3.2.0-alpha.4.0.20240905090502-03ded50a2328
|
github.com/hajimehoshi/bitmapfont/v3 v3.2.0-alpha.5
|
||||||
github.com/hajimehoshi/go-mp3 v0.3.4
|
github.com/hajimehoshi/go-mp3 v0.3.4
|
||||||
github.com/jakecoffman/cp v1.2.1
|
github.com/jakecoffman/cp v1.2.1
|
||||||
github.com/jezek/xgb v1.1.1
|
github.com/jezek/xgb v1.1.1
|
||||||
@ -17,7 +17,7 @@ require (
|
|||||||
github.com/kisielk/errcheck v1.7.0
|
github.com/kisielk/errcheck v1.7.0
|
||||||
golang.org/x/image v0.19.0
|
golang.org/x/image v0.19.0
|
||||||
golang.org/x/sync v0.8.0
|
golang.org/x/sync v0.8.0
|
||||||
golang.org/x/sys v0.24.0
|
golang.org/x/sys v0.25.0
|
||||||
golang.org/x/text v0.17.0
|
golang.org/x/text v0.17.0
|
||||||
golang.org/x/tools v0.24.0
|
golang.org/x/tools v0.24.0
|
||||||
)
|
)
|
||||||
|
8
go.sum
8
go.sum
@ -13,8 +13,8 @@ github.com/go-text/typesetting v0.1.1/go.mod h1:d22AnmeKq/on0HNv73UFriMKc4Ez6EqZ
|
|||||||
github.com/go-text/typesetting-utils v0.0.0-20231211103740-d9332ae51f04 h1:zBx+p/W2aQYtNuyZNcTfinWvXBQwYtDfme051PR/lAY=
|
github.com/go-text/typesetting-utils v0.0.0-20231211103740-d9332ae51f04 h1:zBx+p/W2aQYtNuyZNcTfinWvXBQwYtDfme051PR/lAY=
|
||||||
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
||||||
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||||
github.com/hajimehoshi/bitmapfont/v3 v3.2.0-alpha.4.0.20240905090502-03ded50a2328 h1:AYqx/yoXuPMmNJMXEblljVeqFDQnKFu5QOjHZMhGfMY=
|
github.com/hajimehoshi/bitmapfont/v3 v3.2.0-alpha.5 h1:gtIcN2INlD2qlfUiECuvbI0moNIoANgIY7MwgW4cFGE=
|
||||||
github.com/hajimehoshi/bitmapfont/v3 v3.2.0-alpha.4.0.20240905090502-03ded50a2328/go.mod h1:/GmYyEKgzzM7dzJBsL7aS5iR83Dr666E5bhQLVVPYsw=
|
github.com/hajimehoshi/bitmapfont/v3 v3.2.0-alpha.5/go.mod h1:/GmYyEKgzzM7dzJBsL7aS5iR83Dr666E5bhQLVVPYsw=
|
||||||
github.com/hajimehoshi/go-mp3 v0.3.4 h1:NUP7pBYH8OguP4diaTZ9wJbUbk3tC0KlfzsEpWmYj68=
|
github.com/hajimehoshi/go-mp3 v0.3.4 h1:NUP7pBYH8OguP4diaTZ9wJbUbk3tC0KlfzsEpWmYj68=
|
||||||
github.com/hajimehoshi/go-mp3 v0.3.4/go.mod h1:fRtZraRFcWb0pu7ok0LqyFhCUrPeMsGRSVop0eemFmo=
|
github.com/hajimehoshi/go-mp3 v0.3.4/go.mod h1:fRtZraRFcWb0pu7ok0LqyFhCUrPeMsGRSVop0eemFmo=
|
||||||
github.com/hajimehoshi/oto/v2 v2.3.1/go.mod h1:seWLbgHH7AyUMYKfKYT9pg7PhUu9/SisyJvNTT+ASQo=
|
github.com/hajimehoshi/oto/v2 v2.3.1/go.mod h1:seWLbgHH7AyUMYKfKYT9pg7PhUu9/SisyJvNTT+ASQo=
|
||||||
@ -74,8 +74,8 @@ golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
|||||||
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||||
golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||||
golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg=
|
golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34=
|
||||||
golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||||
golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXctD9OcfyVLyj2J3IxLnKwHJR8f4D8a3YE=
|
golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXctD9OcfyVLyj2J3IxLnKwHJR8f4D8a3YE=
|
||||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||||
|
@ -156,6 +156,7 @@ const (
|
|||||||
// A screen image is also unmanaged.
|
// A screen image is also unmanaged.
|
||||||
ImageTypeScreen
|
ImageTypeScreen
|
||||||
|
|
||||||
|
// ImageTypeVolatile is a volatile image that is cleared every frame.
|
||||||
ImageTypeVolatile
|
ImageTypeVolatile
|
||||||
|
|
||||||
// ImageTypeUnmanaged is an unmanaged image that is not on an atlas.
|
// ImageTypeUnmanaged is an unmanaged image that is not on an atlas.
|
||||||
|
@ -24,12 +24,14 @@ import (
|
|||||||
type Shader struct {
|
type Shader struct {
|
||||||
ir *shaderir.Program
|
ir *shaderir.Program
|
||||||
shader *restorable.Shader
|
shader *restorable.Shader
|
||||||
|
name string
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewShader(ir *shaderir.Program) *Shader {
|
func NewShader(ir *shaderir.Program, name string) *Shader {
|
||||||
// A shader is initialized lazily, and the lock is not needed.
|
// A shader is initialized lazily, and the lock is not needed.
|
||||||
return &Shader{
|
return &Shader{
|
||||||
ir: ir,
|
ir: ir,
|
||||||
|
name: name,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -45,7 +47,7 @@ func (s *Shader) ensureShader() *restorable.Shader {
|
|||||||
if s.shader != nil {
|
if s.shader != nil {
|
||||||
return s.shader
|
return s.shader
|
||||||
}
|
}
|
||||||
s.shader = restorable.NewShader(s.ir)
|
s.shader = restorable.NewShader(s.ir, s.name)
|
||||||
runtime.SetFinalizer(s, (*Shader).finalize)
|
runtime.SetFinalizer(s, (*Shader).finalize)
|
||||||
return s.shader
|
return s.shader
|
||||||
}
|
}
|
||||||
|
@ -36,12 +36,12 @@ func TestShaderFillTwice(t *testing.T) {
|
|||||||
is := graphics.QuadIndices()
|
is := graphics.QuadIndices()
|
||||||
dr := image.Rect(0, 0, w, h)
|
dr := image.Rect(0, 0, w, h)
|
||||||
g := ui.Get().GraphicsDriverForTesting()
|
g := ui.Get().GraphicsDriverForTesting()
|
||||||
s0 := atlas.NewShader(etesting.ShaderProgramFill(0xff, 0xff, 0xff, 0xff))
|
s0 := atlas.NewShader(etesting.ShaderProgramFill(0xff, 0xff, 0xff, 0xff), "")
|
||||||
dst.DrawTriangles([graphics.ShaderSrcImageCount]*atlas.Image{}, vs, is, graphicsdriver.BlendCopy, dr, [graphics.ShaderSrcImageCount]image.Rectangle{}, s0, nil, graphicsdriver.FillRuleFillAll)
|
dst.DrawTriangles([graphics.ShaderSrcImageCount]*atlas.Image{}, vs, is, graphicsdriver.BlendCopy, dr, [graphics.ShaderSrcImageCount]image.Rectangle{}, s0, nil, graphicsdriver.FillRuleFillAll)
|
||||||
|
|
||||||
// Vertices must be recreated (#1755)
|
// Vertices must be recreated (#1755)
|
||||||
vs = quadVertices(w, h, 0, 0, 1)
|
vs = quadVertices(w, h, 0, 0, 1)
|
||||||
s1 := atlas.NewShader(etesting.ShaderProgramFill(0x80, 0x80, 0x80, 0xff))
|
s1 := atlas.NewShader(etesting.ShaderProgramFill(0x80, 0x80, 0x80, 0xff), "")
|
||||||
dst.DrawTriangles([graphics.ShaderSrcImageCount]*atlas.Image{}, vs, is, graphicsdriver.BlendCopy, dr, [graphics.ShaderSrcImageCount]image.Rectangle{}, s1, nil, graphicsdriver.FillRuleFillAll)
|
dst.DrawTriangles([graphics.ShaderSrcImageCount]*atlas.Image{}, vs, is, graphicsdriver.BlendCopy, dr, [graphics.ShaderSrcImageCount]image.Rectangle{}, s1, nil, graphicsdriver.FillRuleFillAll)
|
||||||
|
|
||||||
pix := make([]byte, 4*w*h)
|
pix := make([]byte, 4*w*h)
|
||||||
@ -89,7 +89,7 @@ func TestImageDrawTwice(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestGCShader(t *testing.T) {
|
func TestGCShader(t *testing.T) {
|
||||||
s := atlas.NewShader(etesting.ShaderProgramFill(0xff, 0xff, 0xff, 0xff))
|
s := atlas.NewShader(etesting.ShaderProgramFill(0xff, 0xff, 0xff, 0xff), "")
|
||||||
|
|
||||||
// Use the shader to initialize it.
|
// Use the shader to initialize it.
|
||||||
const w, h = 1, 1
|
const w, h = 1, 1
|
||||||
|
@ -93,6 +93,8 @@ func (c *drawTrianglesCommand) String() string {
|
|||||||
dst := fmt.Sprintf("%d", c.dst.id)
|
dst := fmt.Sprintf("%d", c.dst.id)
|
||||||
if c.dst.screen {
|
if c.dst.screen {
|
||||||
dst += " (screen)"
|
dst += " (screen)"
|
||||||
|
} else if c.dst.attribute != "" {
|
||||||
|
dst += " (" + c.dst.attribute + ")"
|
||||||
}
|
}
|
||||||
|
|
||||||
var srcstrs [graphics.ShaderSrcImageCount]string
|
var srcstrs [graphics.ShaderSrcImageCount]string
|
||||||
@ -104,10 +106,17 @@ func (c *drawTrianglesCommand) String() string {
|
|||||||
srcstrs[i] = fmt.Sprintf("%d", src.id)
|
srcstrs[i] = fmt.Sprintf("%d", src.id)
|
||||||
if src.screen {
|
if src.screen {
|
||||||
srcstrs[i] += " (screen)"
|
srcstrs[i] += " (screen)"
|
||||||
|
} else if src.attribute != "" {
|
||||||
|
srcstrs[i] += " (" + src.attribute + ")"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return fmt.Sprintf("draw-triangles: dst: %s <- src: [%s], num of dst regions: %d, num of indices: %d, blend: %s, fill rule: %s, shader id: %d", dst, strings.Join(srcstrs[:], ", "), len(c.dstRegions), c.numIndices(), blend, c.fillRule, c.shader.id)
|
shader := fmt.Sprintf("%d", c.shader.id)
|
||||||
|
if c.shader.name != "" {
|
||||||
|
shader += " (" + c.shader.name + ")"
|
||||||
|
}
|
||||||
|
|
||||||
|
return fmt.Sprintf("draw-triangles: dst: %s <- src: [%s], num of dst regions: %d, num of indices: %d, blend: %s, fill rule: %s, shader: %s", dst, strings.Join(srcstrs[:], ", "), len(c.dstRegions), c.numIndices(), blend, c.fillRule, shader)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Exec executes the drawTrianglesCommand.
|
// Exec executes the drawTrianglesCommand.
|
||||||
@ -334,10 +343,15 @@ type newImageCommand struct {
|
|||||||
width int
|
width int
|
||||||
height int
|
height int
|
||||||
screen bool
|
screen bool
|
||||||
|
attribute string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *newImageCommand) String() string {
|
func (c *newImageCommand) String() string {
|
||||||
return fmt.Sprintf("new-image: result: %d, width: %d, height: %d, screen: %t", c.result.id, c.width, c.height, c.screen)
|
str := fmt.Sprintf("new-image: result: %d, width: %d, height: %d, screen: %t", c.result.id, c.width, c.height, c.screen)
|
||||||
|
if c.attribute != "" {
|
||||||
|
str += ", attribute: " + c.attribute
|
||||||
|
}
|
||||||
|
return str
|
||||||
}
|
}
|
||||||
|
|
||||||
// Exec executes a newImageCommand.
|
// Exec executes a newImageCommand.
|
||||||
|
@ -37,6 +37,9 @@ type Image struct {
|
|||||||
internalHeight int
|
internalHeight int
|
||||||
screen bool
|
screen bool
|
||||||
|
|
||||||
|
// attribute is used only for logs.
|
||||||
|
attribute string
|
||||||
|
|
||||||
// id is an identifier for the image. This is used only when dumping the information.
|
// id is an identifier for the image. This is used only when dumping the information.
|
||||||
//
|
//
|
||||||
// This is duplicated with graphicsdriver.Image's ID, but this id is still necessary because this image might not
|
// This is duplicated with graphicsdriver.Image's ID, but this id is still necessary because this image might not
|
||||||
@ -57,18 +60,20 @@ func genNextImageID() int {
|
|||||||
// NewImage returns a new image.
|
// NewImage returns a new image.
|
||||||
//
|
//
|
||||||
// Note that the image is not initialized yet.
|
// Note that the image is not initialized yet.
|
||||||
func NewImage(width, height int, screenFramebuffer bool) *Image {
|
func NewImage(width, height int, screenFramebuffer bool, attribute string) *Image {
|
||||||
i := &Image{
|
i := &Image{
|
||||||
width: width,
|
width: width,
|
||||||
height: height,
|
height: height,
|
||||||
screen: screenFramebuffer,
|
screen: screenFramebuffer,
|
||||||
id: genNextImageID(),
|
id: genNextImageID(),
|
||||||
|
attribute: attribute,
|
||||||
}
|
}
|
||||||
c := &newImageCommand{
|
c := &newImageCommand{
|
||||||
result: i,
|
result: i,
|
||||||
width: width,
|
width: width,
|
||||||
height: height,
|
height: height,
|
||||||
screen: screenFramebuffer,
|
screen: screenFramebuffer,
|
||||||
|
attribute: attribute,
|
||||||
}
|
}
|
||||||
theCommandQueueManager.enqueueCommand(c)
|
theCommandQueueManager.enqueueCommand(c)
|
||||||
return i
|
return i
|
||||||
|
@ -35,7 +35,7 @@ func init() {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
panic(fmt.Sprintf("graphicscommand: compiling the nearest shader failed: %v", err))
|
panic(fmt.Sprintf("graphicscommand: compiling the nearest shader failed: %v", err))
|
||||||
}
|
}
|
||||||
nearestFilterShader = graphicscommand.NewShader(ir)
|
nearestFilterShader = graphicscommand.NewShader(ir, "")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestMain(m *testing.M) {
|
func TestMain(m *testing.M) {
|
||||||
@ -50,8 +50,8 @@ func quadVertices(w, h float32) []float32 {
|
|||||||
|
|
||||||
func TestClear(t *testing.T) {
|
func TestClear(t *testing.T) {
|
||||||
const w, h = 1024, 1024
|
const w, h = 1024, 1024
|
||||||
src := graphicscommand.NewImage(w/2, h/2, false)
|
src := graphicscommand.NewImage(w/2, h/2, false, "")
|
||||||
dst := graphicscommand.NewImage(w, h, false)
|
dst := graphicscommand.NewImage(w, h, false, "")
|
||||||
|
|
||||||
vs := quadVertices(w/2, h/2)
|
vs := quadVertices(w/2, h/2)
|
||||||
is := graphics.QuadIndices()
|
is := graphics.QuadIndices()
|
||||||
@ -81,9 +81,9 @@ func TestClear(t *testing.T) {
|
|||||||
|
|
||||||
func TestWritePixelsPartAfterDrawTriangles(t *testing.T) {
|
func TestWritePixelsPartAfterDrawTriangles(t *testing.T) {
|
||||||
const w, h = 32, 32
|
const w, h = 32, 32
|
||||||
clr := graphicscommand.NewImage(w, h, false)
|
clr := graphicscommand.NewImage(w, h, false, "")
|
||||||
src := graphicscommand.NewImage(w/2, h/2, false)
|
src := graphicscommand.NewImage(w/2, h/2, false, "")
|
||||||
dst := graphicscommand.NewImage(w, h, false)
|
dst := graphicscommand.NewImage(w, h, false, "")
|
||||||
vs := quadVertices(w/2, h/2)
|
vs := quadVertices(w/2, h/2)
|
||||||
is := graphics.QuadIndices()
|
is := graphics.QuadIndices()
|
||||||
dr := image.Rect(0, 0, w, h)
|
dr := image.Rect(0, 0, w, h)
|
||||||
@ -101,15 +101,15 @@ func TestWritePixelsPartAfterDrawTriangles(t *testing.T) {
|
|||||||
|
|
||||||
func TestShader(t *testing.T) {
|
func TestShader(t *testing.T) {
|
||||||
const w, h = 16, 16
|
const w, h = 16, 16
|
||||||
clr := graphicscommand.NewImage(w, h, false)
|
clr := graphicscommand.NewImage(w, h, false, "")
|
||||||
dst := graphicscommand.NewImage(w, h, false)
|
dst := graphicscommand.NewImage(w, h, false, "")
|
||||||
vs := quadVertices(w, h)
|
vs := quadVertices(w, h)
|
||||||
is := graphics.QuadIndices()
|
is := graphics.QuadIndices()
|
||||||
dr := image.Rect(0, 0, w, h)
|
dr := image.Rect(0, 0, w, h)
|
||||||
dst.DrawTriangles([graphics.ShaderSrcImageCount]*graphicscommand.Image{clr}, vs, is, graphicsdriver.BlendClear, dr, [graphics.ShaderSrcImageCount]image.Rectangle{}, nearestFilterShader, nil, graphicsdriver.FillRuleFillAll)
|
dst.DrawTriangles([graphics.ShaderSrcImageCount]*graphicscommand.Image{clr}, vs, is, graphicsdriver.BlendClear, dr, [graphics.ShaderSrcImageCount]image.Rectangle{}, nearestFilterShader, nil, graphicsdriver.FillRuleFillAll)
|
||||||
|
|
||||||
g := ui.Get().GraphicsDriverForTesting()
|
g := ui.Get().GraphicsDriverForTesting()
|
||||||
s := graphicscommand.NewShader(etesting.ShaderProgramFill(0xff, 0, 0, 0xff))
|
s := graphicscommand.NewShader(etesting.ShaderProgramFill(0xff, 0, 0, 0xff), "")
|
||||||
dst.DrawTriangles([graphics.ShaderSrcImageCount]*graphicscommand.Image{}, vs, is, graphicsdriver.BlendSourceOver, dr, [graphics.ShaderSrcImageCount]image.Rectangle{}, s, nil, graphicsdriver.FillRuleFillAll)
|
dst.DrawTriangles([graphics.ShaderSrcImageCount]*graphicscommand.Image{}, vs, is, graphicsdriver.BlendSourceOver, dr, [graphics.ShaderSrcImageCount]image.Rectangle{}, s, nil, graphicsdriver.FillRuleFillAll)
|
||||||
|
|
||||||
pix := make([]byte, 4*w*h)
|
pix := make([]byte, 4*w*h)
|
||||||
@ -136,7 +136,7 @@ func TestShader(t *testing.T) {
|
|||||||
// Issue #3036
|
// Issue #3036
|
||||||
func TestSuccessiveWritePixels(t *testing.T) {
|
func TestSuccessiveWritePixels(t *testing.T) {
|
||||||
const w, h = 32, 32
|
const w, h = 32, 32
|
||||||
dst := graphicscommand.NewImage(w, h, false)
|
dst := graphicscommand.NewImage(w, h, false, "")
|
||||||
|
|
||||||
dst.WritePixels(graphics.NewManagedBytes(4, func(bs []byte) {
|
dst.WritePixels(graphics.NewManagedBytes(4, func(bs []byte) {
|
||||||
for i := range bs {
|
for i := range bs {
|
||||||
|
@ -31,12 +31,16 @@ type Shader struct {
|
|||||||
shader graphicsdriver.Shader
|
shader graphicsdriver.Shader
|
||||||
ir *shaderir.Program
|
ir *shaderir.Program
|
||||||
id int
|
id int
|
||||||
|
|
||||||
|
// name is used only for logging.
|
||||||
|
name string
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewShader(ir *shaderir.Program) *Shader {
|
func NewShader(ir *shaderir.Program, name string) *Shader {
|
||||||
s := &Shader{
|
s := &Shader{
|
||||||
ir: ir,
|
ir: ir,
|
||||||
id: genNextShaderID(),
|
id: genNextShaderID(),
|
||||||
|
name: name,
|
||||||
}
|
}
|
||||||
c := &newShaderCommand{
|
c := &newShaderCommand{
|
||||||
result: s,
|
result: s,
|
||||||
|
@ -156,8 +156,13 @@ func NewImage(width, height int, imageType ImageType) *Image {
|
|||||||
panic("restorable: graphics driver must be ready at NewImage but not")
|
panic("restorable: graphics driver must be ready at NewImage but not")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var attribute string
|
||||||
|
switch imageType {
|
||||||
|
case ImageTypeVolatile:
|
||||||
|
attribute = "volatile"
|
||||||
|
}
|
||||||
i := &Image{
|
i := &Image{
|
||||||
image: graphicscommand.NewImage(width, height, imageType == ImageTypeScreen),
|
image: graphicscommand.NewImage(width, height, imageType == ImageTypeScreen, attribute),
|
||||||
width: width,
|
width: width,
|
||||||
height: height,
|
height: height,
|
||||||
imageType: imageType,
|
imageType: imageType,
|
||||||
@ -566,7 +571,7 @@ func (i *Image) restore(graphicsDriver graphicsdriver.Graphics) error {
|
|||||||
case ImageTypeScreen:
|
case ImageTypeScreen:
|
||||||
// The screen image should also be recreated because framebuffer might
|
// The screen image should also be recreated because framebuffer might
|
||||||
// be changed.
|
// be changed.
|
||||||
i.image = graphicscommand.NewImage(w, h, true)
|
i.image = graphicscommand.NewImage(w, h, true, "")
|
||||||
i.basePixels.Dispose()
|
i.basePixels.Dispose()
|
||||||
i.basePixels = Pixels{}
|
i.basePixels = Pixels{}
|
||||||
i.clearDrawTrianglesHistory()
|
i.clearDrawTrianglesHistory()
|
||||||
@ -574,7 +579,7 @@ func (i *Image) restore(graphicsDriver graphicsdriver.Graphics) error {
|
|||||||
i.staleRegions = i.staleRegions[:0]
|
i.staleRegions = i.staleRegions[:0]
|
||||||
return nil
|
return nil
|
||||||
case ImageTypeVolatile:
|
case ImageTypeVolatile:
|
||||||
i.image = graphicscommand.NewImage(w, h, false)
|
i.image = graphicscommand.NewImage(w, h, false, "volatile")
|
||||||
iw, ih := i.image.InternalSize()
|
iw, ih := i.image.InternalSize()
|
||||||
clearImage(i.image, image.Rect(0, 0, iw, ih))
|
clearImage(i.image, image.Rect(0, 0, iw, ih))
|
||||||
return nil
|
return nil
|
||||||
@ -584,7 +589,7 @@ func (i *Image) restore(graphicsDriver graphicsdriver.Graphics) error {
|
|||||||
panic("restorable: pixels must not be stale when restoring")
|
panic("restorable: pixels must not be stale when restoring")
|
||||||
}
|
}
|
||||||
|
|
||||||
gimg := graphicscommand.NewImage(w, h, false)
|
gimg := graphicscommand.NewImage(w, h, false, "")
|
||||||
// Clear the image explicitly.
|
// Clear the image explicitly.
|
||||||
iw, ih := gimg.InternalSize()
|
iw, ih := gimg.InternalSize()
|
||||||
clearImage(gimg, image.Rect(0, 0, iw, ih))
|
clearImage(gimg, image.Rect(0, 0, iw, ih))
|
||||||
|
@ -28,12 +28,14 @@ import (
|
|||||||
type Shader struct {
|
type Shader struct {
|
||||||
shader *graphicscommand.Shader
|
shader *graphicscommand.Shader
|
||||||
ir *shaderir.Program
|
ir *shaderir.Program
|
||||||
|
name string
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewShader(ir *shaderir.Program) *Shader {
|
func NewShader(ir *shaderir.Program, name string) *Shader {
|
||||||
s := &Shader{
|
s := &Shader{
|
||||||
shader: graphicscommand.NewShader(ir),
|
shader: graphicscommand.NewShader(ir, name),
|
||||||
ir: ir,
|
ir: ir,
|
||||||
|
name: name,
|
||||||
}
|
}
|
||||||
theImages.addShader(s)
|
theImages.addShader(s)
|
||||||
return s
|
return s
|
||||||
@ -47,7 +49,7 @@ func (s *Shader) Dispose() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *Shader) restore() {
|
func (s *Shader) restore() {
|
||||||
s.shader = graphicscommand.NewShader(s.ir)
|
s.shader = graphicscommand.NewShader(s.ir, s.name)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Shader) Unit() shaderir.Unit {
|
func (s *Shader) Unit() shaderir.Unit {
|
||||||
@ -90,7 +92,7 @@ func init() {
|
|||||||
if err := wg.Wait(); err != nil {
|
if err := wg.Wait(); err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
NearestFilterShader = NewShader(nearestIR)
|
NearestFilterShader = NewShader(nearestIR, "nearest")
|
||||||
LinearFilterShader = NewShader(linearIR)
|
LinearFilterShader = NewShader(linearIR, "linear")
|
||||||
clearShader = NewShader(clearIR)
|
clearShader = NewShader(clearIR, "clear")
|
||||||
}
|
}
|
||||||
|
@ -53,7 +53,7 @@ func TestShader(t *testing.T) {
|
|||||||
img := restorable.NewImage(1, 1, restorable.ImageTypeRegular)
|
img := restorable.NewImage(1, 1, restorable.ImageTypeRegular)
|
||||||
defer img.Dispose()
|
defer img.Dispose()
|
||||||
|
|
||||||
s := restorable.NewShader(etesting.ShaderProgramFill(0xff, 0, 0, 0xff))
|
s := restorable.NewShader(etesting.ShaderProgramFill(0xff, 0, 0, 0xff), "")
|
||||||
dr := image.Rect(0, 0, 1, 1)
|
dr := image.Rect(0, 0, 1, 1)
|
||||||
img.DrawTriangles([graphics.ShaderSrcImageCount]*restorable.Image{}, quadVertices(1, 1, 0, 0), graphics.QuadIndices(), graphicsdriver.BlendCopy, dr, [graphics.ShaderSrcImageCount]image.Rectangle{}, s, nil, graphicsdriver.FillRuleFillAll)
|
img.DrawTriangles([graphics.ShaderSrcImageCount]*restorable.Image{}, quadVertices(1, 1, 0, 0), graphics.QuadIndices(), graphicsdriver.BlendCopy, dr, [graphics.ShaderSrcImageCount]image.Rectangle{}, s, nil, graphicsdriver.FillRuleFillAll)
|
||||||
|
|
||||||
@ -82,7 +82,7 @@ func TestShaderChain(t *testing.T) {
|
|||||||
|
|
||||||
imgs[0].WritePixels(bytesToManagedBytes([]byte{0xff, 0, 0, 0xff}), image.Rect(0, 0, 1, 1))
|
imgs[0].WritePixels(bytesToManagedBytes([]byte{0xff, 0, 0, 0xff}), image.Rect(0, 0, 1, 1))
|
||||||
|
|
||||||
s := restorable.NewShader(etesting.ShaderProgramImages(1))
|
s := restorable.NewShader(etesting.ShaderProgramImages(1), "")
|
||||||
for i := 0; i < num-1; i++ {
|
for i := 0; i < num-1; i++ {
|
||||||
dr := image.Rect(0, 0, 1, 1)
|
dr := image.Rect(0, 0, 1, 1)
|
||||||
imgs[i+1].DrawTriangles([graphics.ShaderSrcImageCount]*restorable.Image{imgs[i]}, quadVertices(1, 1, 0, 0), graphics.QuadIndices(), graphicsdriver.BlendCopy, dr, [graphics.ShaderSrcImageCount]image.Rectangle{}, s, nil, graphicsdriver.FillRuleFillAll)
|
imgs[i+1].DrawTriangles([graphics.ShaderSrcImageCount]*restorable.Image{imgs[i]}, quadVertices(1, 1, 0, 0), graphics.QuadIndices(), graphicsdriver.BlendCopy, dr, [graphics.ShaderSrcImageCount]image.Rectangle{}, s, nil, graphicsdriver.FillRuleFillAll)
|
||||||
@ -115,7 +115,7 @@ func TestShaderMultipleSources(t *testing.T) {
|
|||||||
|
|
||||||
dst := restorable.NewImage(1, 1, restorable.ImageTypeRegular)
|
dst := restorable.NewImage(1, 1, restorable.ImageTypeRegular)
|
||||||
|
|
||||||
s := restorable.NewShader(etesting.ShaderProgramImages(3))
|
s := restorable.NewShader(etesting.ShaderProgramImages(3), "")
|
||||||
dr := image.Rect(0, 0, 1, 1)
|
dr := image.Rect(0, 0, 1, 1)
|
||||||
dst.DrawTriangles(srcs, quadVertices(1, 1, 0, 0), graphics.QuadIndices(), graphicsdriver.BlendCopy, dr, [graphics.ShaderSrcImageCount]image.Rectangle{}, s, nil, graphicsdriver.FillRuleFillAll)
|
dst.DrawTriangles(srcs, quadVertices(1, 1, 0, 0), graphics.QuadIndices(), graphicsdriver.BlendCopy, dr, [graphics.ShaderSrcImageCount]image.Rectangle{}, s, nil, graphicsdriver.FillRuleFillAll)
|
||||||
|
|
||||||
@ -147,7 +147,7 @@ func TestShaderMultipleSourcesOnOneTexture(t *testing.T) {
|
|||||||
|
|
||||||
dst := restorable.NewImage(1, 1, restorable.ImageTypeRegular)
|
dst := restorable.NewImage(1, 1, restorable.ImageTypeRegular)
|
||||||
|
|
||||||
s := restorable.NewShader(etesting.ShaderProgramImages(3))
|
s := restorable.NewShader(etesting.ShaderProgramImages(3), "")
|
||||||
dr := image.Rect(0, 0, 1, 1)
|
dr := image.Rect(0, 0, 1, 1)
|
||||||
srcRegions := [graphics.ShaderSrcImageCount]image.Rectangle{
|
srcRegions := [graphics.ShaderSrcImageCount]image.Rectangle{
|
||||||
image.Rect(0, 0, 1, 1),
|
image.Rect(0, 0, 1, 1),
|
||||||
@ -177,7 +177,7 @@ func TestShaderDispose(t *testing.T) {
|
|||||||
img := restorable.NewImage(1, 1, restorable.ImageTypeRegular)
|
img := restorable.NewImage(1, 1, restorable.ImageTypeRegular)
|
||||||
defer img.Dispose()
|
defer img.Dispose()
|
||||||
|
|
||||||
s := restorable.NewShader(etesting.ShaderProgramFill(0xff, 0, 0, 0xff))
|
s := restorable.NewShader(etesting.ShaderProgramFill(0xff, 0, 0, 0xff), "")
|
||||||
dr := image.Rect(0, 0, 1, 1)
|
dr := image.Rect(0, 0, 1, 1)
|
||||||
img.DrawTriangles([graphics.ShaderSrcImageCount]*restorable.Image{}, quadVertices(1, 1, 0, 0), graphics.QuadIndices(), graphicsdriver.BlendCopy, dr, [graphics.ShaderSrcImageCount]image.Rectangle{}, s, nil, graphicsdriver.FillRuleFillAll)
|
img.DrawTriangles([graphics.ShaderSrcImageCount]*restorable.Image{}, quadVertices(1, 1, 0, 0), graphics.QuadIndices(), graphicsdriver.BlendCopy, dr, [graphics.ShaderSrcImageCount]image.Rectangle{}, s, nil, graphicsdriver.FillRuleFillAll)
|
||||||
|
|
||||||
|
@ -32,9 +32,9 @@ type Shader struct {
|
|||||||
uniformUint32Count int
|
uniformUint32Count int
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewShader(ir *shaderir.Program) *Shader {
|
func NewShader(ir *shaderir.Program, name string) *Shader {
|
||||||
return &Shader{
|
return &Shader{
|
||||||
shader: atlas.NewShader(ir),
|
shader: atlas.NewShader(ir, name),
|
||||||
uniformNames: ir.UniformNames[graphics.PreservedUniformVariablesCount:],
|
uniformNames: ir.UniformNames[graphics.PreservedUniformVariablesCount:],
|
||||||
uniformTypes: ir.Uniforms[graphics.PreservedUniformVariablesCount:],
|
uniformTypes: ir.Uniforms[graphics.PreservedUniformVariablesCount:],
|
||||||
}
|
}
|
||||||
|
24
shader.go
24
shader.go
@ -38,12 +38,16 @@ type Shader struct {
|
|||||||
//
|
//
|
||||||
// For the details about the shader, see https://ebitengine.org/en/documents/shader.html.
|
// For the details about the shader, see https://ebitengine.org/en/documents/shader.html.
|
||||||
func NewShader(src []byte) (*Shader, error) {
|
func NewShader(src []byte) (*Shader, error) {
|
||||||
|
return newShader(src, "")
|
||||||
|
}
|
||||||
|
|
||||||
|
func newShader(src []byte, name string) (*Shader, error) {
|
||||||
ir, err := graphics.CompileShader(src)
|
ir, err := graphics.CompileShader(src)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return &Shader{
|
return &Shader{
|
||||||
shader: ui.NewShader(ir),
|
shader: ui.NewShader(ir, name),
|
||||||
unit: ir.Unit,
|
unit: ir.Unit,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
@ -108,7 +112,23 @@ func builtinShader(filter builtinshader.Filter, address builtinshader.Address, u
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
src := builtinshader.ShaderSource(filter, address, useColorM)
|
src := builtinshader.ShaderSource(filter, address, useColorM)
|
||||||
s, err := NewShader(src)
|
var name string
|
||||||
|
switch filter {
|
||||||
|
case builtinshader.FilterNearest:
|
||||||
|
name = "nearest"
|
||||||
|
case builtinshader.FilterLinear:
|
||||||
|
name = "linear"
|
||||||
|
}
|
||||||
|
switch address {
|
||||||
|
case builtinshader.AddressClampToZero:
|
||||||
|
name += "-clamptozero"
|
||||||
|
case builtinshader.AddressRepeat:
|
||||||
|
name += "-repeat"
|
||||||
|
}
|
||||||
|
if useColorM {
|
||||||
|
name += "-colorm"
|
||||||
|
}
|
||||||
|
s, err := newShader(src, name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(fmt.Sprintf("ebiten: NewShader for a built-in shader failed: %v", err))
|
panic(fmt.Sprintf("ebiten: NewShader for a built-in shader failed: %v", err))
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user