mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-11-10 04:57:26 +01:00
Add AsyncGraphicsContext; Use goroutines in the main routine
This commit is contained in:
parent
6e584eb642
commit
6b1e76b669
38
ebiten.go
38
ebiten.go
@ -30,29 +30,35 @@ type InputState struct {
|
||||
Y int
|
||||
}
|
||||
|
||||
func OpenGLRun(game Game, ui UI, screenScale int, input chan InputState) {
|
||||
ch := make(chan bool, 1)
|
||||
func OpenGLRun(game Game, ui UI, screenScale int, input <-chan InputState) {
|
||||
deviceUpdate := make(chan bool)
|
||||
commandSet := make(chan chan func(graphics.GraphicsContext))
|
||||
|
||||
graphicsDevice := opengl.NewDevice(
|
||||
game.ScreenWidth(), game.ScreenHeight(), screenScale,
|
||||
func(g graphics.GraphicsContext, offscreen graphics.Texture) {
|
||||
ticket := <-ch
|
||||
game.Draw(g, offscreen)
|
||||
ch <- ticket
|
||||
})
|
||||
game.ScreenWidth(), game.ScreenHeight(), screenScale, deviceUpdate, commandSet)
|
||||
|
||||
game.Init(graphicsDevice.TextureFactory())
|
||||
|
||||
go func() {
|
||||
frameTime := time.Duration(int64(time.Second) / int64(game.Fps()))
|
||||
tick := time.Tick(frameTime)
|
||||
updateTick := time.Tick(frameTime)
|
||||
for {
|
||||
<-tick
|
||||
ticket := <-ch
|
||||
inputState := <-input
|
||||
game.Update(inputState)
|
||||
ch <- ticket
|
||||
select {
|
||||
case <-updateTick:
|
||||
inputState := <-input
|
||||
game.Update(inputState)
|
||||
case <-deviceUpdate:
|
||||
commands := make(chan func(graphics.GraphicsContext))
|
||||
commandSet <- commands
|
||||
g := graphics.NewAsyncGraphicsContext(commands)
|
||||
// TODO: graphicsDevice is shared by multiple goroutines.
|
||||
game.Draw(g, graphicsDevice.OffscreenTexture())
|
||||
close(commands)
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
game.Init(graphicsDevice.TextureFactory())
|
||||
ch <- true
|
||||
|
||||
// UI should be executed on the main thread.
|
||||
ui.Run(graphicsDevice)
|
||||
}
|
||||
|
57
graphics/async_graphics_context.go
Normal file
57
graphics/async_graphics_context.go
Normal file
@ -0,0 +1,57 @@
|
||||
package graphics
|
||||
|
||||
import (
|
||||
"github.com/hajimehoshi/go.ebiten/graphics/matrix"
|
||||
"image/color"
|
||||
)
|
||||
|
||||
type AsyncGraphicsContext struct {
|
||||
ch chan<- func(GraphicsContext)
|
||||
}
|
||||
|
||||
func NewAsyncGraphicsContext(ch chan<- func(GraphicsContext)) *AsyncGraphicsContext {
|
||||
return &AsyncGraphicsContext{
|
||||
ch: ch,
|
||||
}
|
||||
}
|
||||
|
||||
func (g *AsyncGraphicsContext) Clear() {
|
||||
g.ch <- func(g2 GraphicsContext) {
|
||||
g2.Clear()
|
||||
}
|
||||
}
|
||||
|
||||
func (g *AsyncGraphicsContext) Fill(clr color.Color) {
|
||||
g.ch <- func(g2 GraphicsContext) {
|
||||
g2.Fill(clr)
|
||||
}
|
||||
}
|
||||
|
||||
func (g *AsyncGraphicsContext) DrawRect(rect Rect, clr color.Color) {
|
||||
g.ch <- func(g2 GraphicsContext) {
|
||||
g2.DrawRect(rect, clr)
|
||||
}
|
||||
}
|
||||
|
||||
func (g *AsyncGraphicsContext) DrawTexture(textureID TextureID,
|
||||
geometryMatrix matrix.Geometry,
|
||||
colorMatrix matrix.Color) {
|
||||
g.ch <- func(g2 GraphicsContext) {
|
||||
g2.DrawTexture(textureID, geometryMatrix, colorMatrix)
|
||||
}
|
||||
}
|
||||
|
||||
func (g *AsyncGraphicsContext) DrawTextureParts(textureID TextureID,
|
||||
locations []TexturePart,
|
||||
geometryMatrix matrix.Geometry,
|
||||
colorMatrix matrix.Color) {
|
||||
g.ch <- func(g2 GraphicsContext) {
|
||||
g2.DrawTextureParts(textureID, locations, geometryMatrix, colorMatrix)
|
||||
}
|
||||
}
|
||||
|
||||
func (g *AsyncGraphicsContext) SetOffscreen(textureID TextureID) {
|
||||
g.ch <- func(g2 GraphicsContext) {
|
||||
g2.SetOffscreen(textureID)
|
||||
}
|
||||
}
|
@ -9,6 +9,7 @@ import (
|
||||
type Device interface {
|
||||
Update()
|
||||
TextureFactory() TextureFactory
|
||||
OffscreenTexture() Texture
|
||||
}
|
||||
|
||||
type Rect struct {
|
||||
@ -26,7 +27,7 @@ type TexturePart struct {
|
||||
|
||||
type GraphicsContext interface {
|
||||
Clear()
|
||||
Fill(color color.Color)
|
||||
Fill(clr color.Color)
|
||||
DrawRect(rect Rect, clr color.Color)
|
||||
DrawTexture(textureID TextureID,
|
||||
geometryMatrix matrix.Geometry,
|
||||
|
@ -16,23 +16,32 @@ type Device struct {
|
||||
screenScale int
|
||||
graphicsContext *GraphicsContext
|
||||
offscreenTexture graphics.Texture
|
||||
drawFunc func(graphics.GraphicsContext, graphics.Texture)
|
||||
deviceUpdate chan<- bool
|
||||
commandSet <-chan chan func(graphics.GraphicsContext)
|
||||
}
|
||||
|
||||
func NewDevice(screenWidth, screenHeight, screenScale int,
|
||||
drawFunc func(graphics.GraphicsContext, graphics.Texture)) *Device {
|
||||
deviceUpdate chan<- bool,
|
||||
commandSet <-chan chan func(graphics.GraphicsContext)) *Device {
|
||||
graphicsContext := newGraphicsContext(screenWidth, screenHeight, screenScale)
|
||||
|
||||
device := &Device{
|
||||
screenWidth: screenWidth,
|
||||
screenHeight: screenHeight,
|
||||
screenScale: screenScale,
|
||||
graphicsContext: newGraphicsContext(screenWidth, screenHeight, screenScale),
|
||||
drawFunc: drawFunc,
|
||||
deviceUpdate: deviceUpdate,
|
||||
commandSet: commandSet,
|
||||
graphicsContext: graphicsContext,
|
||||
}
|
||||
device.offscreenTexture =
|
||||
device.graphicsContext.NewTexture(screenWidth, screenHeight)
|
||||
return device
|
||||
}
|
||||
|
||||
func (device *Device) OffscreenTexture() graphics.Texture {
|
||||
return device.offscreenTexture
|
||||
}
|
||||
|
||||
func (device *Device) Update() {
|
||||
g := device.graphicsContext
|
||||
C.glEnable(C.GL_TEXTURE_2D)
|
||||
@ -40,7 +49,13 @@ func (device *Device) Update() {
|
||||
C.glTexParameteri(C.GL_TEXTURE_2D, C.GL_TEXTURE_MAG_FILTER, C.GL_NEAREST)
|
||||
g.SetOffscreen(device.offscreenTexture.ID)
|
||||
g.Clear()
|
||||
device.drawFunc(g, device.offscreenTexture)
|
||||
|
||||
device.deviceUpdate <- true
|
||||
commands := <-device.commandSet
|
||||
for command := range commands {
|
||||
command(g)
|
||||
}
|
||||
|
||||
g.flush()
|
||||
|
||||
C.glTexParameteri(C.GL_TEXTURE_2D, C.GL_TEXTURE_MIN_FILTER, C.GL_LINEAR)
|
||||
|
Loading…
Reference in New Issue
Block a user