Closed hajimehoshi closed 6 years ago
I got about 30 FPS on my machine. Not too bad.
The simplest case:
package main
import (
"fmt"
"github.com/hajimehoshi/ebiten"
"github.com/hajimehoshi/ebiten/ebitenutil"
)
func update(screen *ebiten.Image) error {
ebitenutil.DebugPrint(screen, fmt.Sprintf("%0.2f", ebiten.CurrentFPS()))
return nil
}
func main() {
if err := ebiten.Run(update, 2000, 2000, 1, "test"); err != nil {
panic(err)
}
}
This is about 20-25 FPS on my MacBook Pro.
@hajimehoshi it runs at 60fps both on the mac (2560 x 1600) and the external monitor (2560x1440, 60Hz)
Thanks, Your mac is Retina display, right?
yes, but it happened also on a Dell
My MacBook Pro is in mid 2014, so I guess that's why the performance is bad :-)
Now the FPS is 30-40 with a very simple optimization (the above simplest case). I'll do further more.
Now the FPS is over 50, but this is not enough.
What I learned is:
glClear
is slow. This waits for finishing.fillCommand
calls glFlush
and glBindTexture
, which are slow.Remove glClear calls, that was blocking everything. Now the FPS is 60 on my MacBook Pro (MatrixSize=20
and BaseNumber = 64
in common.go
)!
Next challenge is to make the game 60FPS in
MatrixSize = 30
BaseNumber = 32
Found that in "terraformer", two image sources are used one after the other. In the below dump, the first column is the image address and second column is the number of count how many times it is used at DrawImage
:
0xc4200421c0 11
0xc420042380 1
0xc4200421c0 9
0xc420042380 1
0xc4200421c0 7
0xc420042380 1
0xc4200421c0 12
0xc420042380 1
0xc4200421c0 11
0xc420042380 1
0xc4200421c0 14
0xc420042380 1
0xc4200421c0 10
0xc420042380 1
0xc4200421c0 6
0xc420042380 1
0xc4200421c0 16
0xc420042380 1
0xc4200421c0 12
0xc420042380 1
0xc4200421c0 12
0xc420042380 1
0xc4200421c0 7
0xc420042380 1
0xc4200421c0 13
0xc420042380 1
0xc4200421c0 9
0xc420042380 1
0xc4200421c0 13
...
@tommyblue As the wiki says, your game would run much faster to reorder DrawImage
calls. Without such change, probably Ebiten cannot run your game faster.
I'm thinking to introduce "texture atlas utility" (#91) or "automatic texture atlas" feature, but not determined yet.
@hajimehoshi thanks for the debug. What is not clear to me, as a very inexperienced go and game-dev user, is what we were doing wrong and why moving from ebiten to go-sdl2, with quite unchanged code structure, the performances were so different. I mean, I'm not saying ebiten is bad and go-sdl2 is good, but if we did something wrong, we were doing it without knowing so maybe you could arrange a wiki page like: "How to structure your project from 0 and have good performances with Ebiten" or create a repo with a project skeleton that unskilled users can clone/fork as a start point and profit! 😃
Thank you for your feedback. I agree such skeleton project would be useful. On the other hand, Ebiten is a kind of low level lib and I didn't determine a good project "skeleton" on purpose.
At least in your case, "automatic texture atlas" "shared texture" (#514) where images created via NewImageFromImage
share a same texture would solve the problem and this should be useful in most games. In the ideal world, Ebiten should run any game codes quickly, and actually it looks like SDL2 works very well without changing the structure.
@tommyblue Out of curiosity, how do your draw images with SDL2? Software rendering or OpenGL with SDL2? If I understand correctly, SDL doesn't offer GPU rendering by default.
well, afaik, it does. See SDL_RENDERER_ACCELERATED
here: https://wiki.libsdl.org/SDL_CreateRenderer
we do it here: https://gitlab.com/i-tre-brutti/terraformer/blob/master/loop/loop.go#L112
I've implemented 'shared texture', which creates texture atlas automatically. Now Ebiten can run 'terraformer' with 60 FPS without code change :-)
wonderful!
Tommaso Visconti at Gophers Slack: