Good way to load resources? #2128
-
Hi 👋 I was trying to implement a good way of loading resources (images, shaders, etc.) while also drawing a loading screen. What I did is I loaded resources in goroutine and with images it seems to be working, but for some reason loading shaders not in main thread (goroutine) causes the program to panic. What is the proper solution when you are loading resources not in main thread (goroutine)? Smallest example of panicking code (ebiten v2.3.3)package main
import (
"fmt"
"github.com/hajimehoshi/ebiten/v2"
)
type Game struct {
frame int
shader *ebiten.Shader
loaded bool
}
const testShaderData = `
package main
func Fragment(position vec4, texCoord vec2, color vec4) vec4 {
return vec4(1)
}
`
func (g *Game) Update() error {
g.frame++
if g.frame == 1 {
go func() {
fmt.Println("Loading")
var err error
g.shader, err = ebiten.NewShader([]byte(testShaderData))
if err != nil {
panic(err)
}
g.loaded = true
fmt.Println("Loaded")
}()
} else {
if g.loaded {
g.shader.Dispose()
g.loaded = false
fmt.Println("Disposed")
}
}
return nil
}
func (g *Game) Draw(_ *ebiten.Image) {}
func (g *Game) Layout(_, _ int) (int, int) {
return 640, 480
}
func main() {
ebiten.SetWindowTitle("Test")
ebiten.SetWindowSize(640, 480)
if err := ebiten.RunGame(&Game{}); err != nil {
panic(err)
}
} Stdout
Same code but loading in main thread work completely finepackage main
import (
"fmt"
"github.com/hajimehoshi/ebiten/v2"
)
type Game struct {
frame int
shader *ebiten.Shader
loaded bool
}
const testShaderData = `
package main
func Fragment(position vec4, texCoord vec2, color vec4) vec4 {
return vec4(1)
}
`
func (g *Game) Update() error {
g.frame++
if g.frame == 1 {
//go func() { // <========
fmt.Println("Loading")
var err error
g.shader, err = ebiten.NewShader([]byte(testShaderData))
if err != nil {
panic(err)
}
g.loaded = true
fmt.Println("Loaded")
//}() // <========
} else {
if g.loaded {
g.shader.Dispose()
g.loaded = false
fmt.Println("Disposed")
}
}
return nil
}
func (g *Game) Draw(_ *ebiten.Image) {}
func (g *Game) Layout(_, _ int) (int, int) {
return 640, 480
}
func main() {
ebiten.SetWindowTitle("Test")
ebiten.SetWindowSize(640, 480)
if err := ebiten.RunGame(&Game{}); err != nil {
panic(err)
}
} |
Beta Was this translation helpful? Give feedback.
Answered by
hajimehoshi
Jun 7, 2022
Replies: 1 comment 5 replies
-
Hi, This seems a bug in Ebitengine. I'll take a look, thanks! |
Beta Was this translation helpful? Give feedback.
5 replies
Answer selected by
mymmrac
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Hi,
This seems a bug in Ebitengine. I'll take a look, thanks!