Bug fix: can't call canvas.use recursively

This commit is contained in:
Hajime Hoshi 2014-12-09 01:08:47 +09:00
parent 0d78f9937f
commit 60e4d6f6ff
7 changed files with 111 additions and 37 deletions

View File

@ -29,7 +29,7 @@ func main() {
u := new(glfw.UI)
game := NewGame()
if err := ui.Run(u, game, ScreenWidth, ScreenHeight, 2, "Ebiten Demo", 60); err != nil {
if err := ui.Run(u, game, ScreenWidth, ScreenHeight, 2, "Blocks (Ebiten Demo)", 60); err != nil {
log.Fatal(err)
}
}

View File

@ -21,7 +21,7 @@ type TexturePart struct {
// A Drawer is the interface that draws itself.
type Drawer interface {
Draw(parts []TexturePart, geometryMatrix matrix.Geometry, colorMatrix matrix.Color)
Draw(parts []TexturePart, geo matrix.Geometry, color matrix.Color)
}
// DrawWhole draws the whole texture.

View File

@ -4,19 +4,14 @@ import (
"github.com/go-gl/gl"
"github.com/hajimehoshi/ebiten/graphics"
"github.com/hajimehoshi/ebiten/graphics/matrix"
"github.com/hajimehoshi/ebiten/ui"
)
type ContextUpdater struct {
context *context
}
func Initialize(screenWidth, screenHeight, screenScale int) (*ContextUpdater, error) {
func Initialize(screenWidth, screenHeight, screenScale int) (*Context, error) {
gl.Init()
gl.Enable(gl.TEXTURE_2D)
gl.Enable(gl.BLEND)
c := &context{
c := &Context{
screenWidth: screenWidth,
screenHeight: screenHeight,
screenScale: screenScale,
@ -37,14 +32,10 @@ func Initialize(screenWidth, screenHeight, screenScale int) (*ContextUpdater, er
c.ResetOffscreen()
c.Clear()
return &ContextUpdater{c}, nil
return c, nil
}
func (u *ContextUpdater) Update(drawer ui.Drawer) error {
return u.context.update(drawer)
}
type context struct {
type Context struct {
screenId graphics.RenderTargetID
defaultId graphics.RenderTargetID
currentId graphics.RenderTargetID
@ -53,43 +44,41 @@ type context struct {
screenScale int
}
func (c *context) dispose() {
func (c *Context) dispose() {
// NOTE: Now this method is not used anywhere.
idsInstance.deleteRenderTarget(c.screenId)
}
func (c *context) Clear() {
func (c *Context) Clear() {
c.Fill(0, 0, 0)
}
func (c *context) Fill(r, g, b uint8) {
func (c *Context) Fill(r, g, b uint8) {
idsInstance.fillRenderTarget(c.currentId, r, g, b)
}
func (c *context) Texture(id graphics.TextureID) graphics.Drawer {
func (c *Context) Texture(id graphics.TextureID) graphics.Drawer {
return &textureWithContext{id, c}
}
func (c *context) RenderTarget(id graphics.RenderTargetID) graphics.Drawer {
func (c *Context) RenderTarget(id graphics.RenderTargetID) graphics.Drawer {
return &textureWithContext{idsInstance.toTexture(id), c}
}
func (c *context) ResetOffscreen() {
func (c *Context) ResetOffscreen() {
c.currentId = c.screenId
}
func (c *context) SetOffscreen(renderTargetId graphics.RenderTargetID) {
func (c *Context) SetOffscreen(renderTargetId graphics.RenderTargetID) {
c.currentId = renderTargetId
}
func (c *context) update(drawer ui.Drawer) error {
func (c *Context) PreUpdate() {
c.ResetOffscreen()
c.Clear()
}
if err := drawer.Draw(c); err != nil {
return err
}
func (c *Context) PostUpdate() {
c.SetOffscreen(c.defaultId)
c.Clear()
@ -99,12 +88,11 @@ func (c *context) update(drawer ui.Drawer) error {
graphics.DrawWhole(c.RenderTarget(c.screenId), c.screenWidth, c.screenHeight, geo, matrix.ColorI())
gl.Flush()
return nil
}
type textureWithContext struct {
id graphics.TextureID
context *context
context *Context
}
func (t *textureWithContext) Draw(parts []graphics.TexturePart, geo matrix.Geometry, color matrix.Color) {

View File

@ -16,11 +16,21 @@ const (
// TextureID represents an ID of a texture.
type TextureID int
// IsNil returns true if the texture is nil.
func (i TextureID) IsNil() bool {
return i == 0
}
// RenderTargetID represents an ID of a render target.
// A render target is essentially same as a texture, but it is assumed that the
// all alpha of a render target is maximum.
type RenderTargetID int
// IsNil returns true if the render target is nil.
func (i RenderTargetID) IsNil() bool {
return i == 0
}
var currentTextureFactory TextureFactory
// A TextureFactory is the interface that creates a render target or a texture.

View File

@ -11,7 +11,7 @@ import (
type canvas struct {
window *glfw.Window
contextUpdater *opengl.ContextUpdater
context *opengl.Context
keyboard keyboard
mouse mouse
funcs chan func()
@ -20,7 +20,13 @@ type canvas struct {
func (c *canvas) Draw(d ui.Drawer) (err error) {
c.use(func() {
err = c.contextUpdater.Update(d)
c.context.PreUpdate()
})
if err = d.Draw(&context{c}); err != nil {
return
}
c.use(func() {
c.context.PostUpdate()
c.window.SwapBuffers()
})
return
@ -54,6 +60,7 @@ func (c *canvas) run(width, height, scale int) {
c.window.MakeContextCurrent()
glfw.SwapInterval(1)
for {
f := <-c.funcs
f()
c.funcsDone <- struct{}{}

69
ui/glfw/context.go Normal file
View File

@ -0,0 +1,69 @@
package glfw
import (
"github.com/hajimehoshi/ebiten/graphics"
"github.com/hajimehoshi/ebiten/graphics/matrix"
)
type context struct {
canvas *canvas
}
var _ graphics.Context = new(context)
func (c *context) Clear() {
c.canvas.use(func() {
c.canvas.context.Clear()
})
}
func (c *context) Fill(r, g, b uint8) {
c.canvas.use(func() {
c.canvas.context.Fill(r, g, b)
})
}
func (c *context) Texture(id graphics.TextureID) (d graphics.Drawer) {
c.canvas.use(func() {
d = &drawer{
canvas: c.canvas,
innerDrawer: c.canvas.context.Texture(id),
}
})
return
}
func (c *context) RenderTarget(id graphics.RenderTargetID) (d graphics.Drawer) {
c.canvas.use(func() {
d = &drawer{
canvas: c.canvas,
innerDrawer: c.canvas.context.RenderTarget(id),
}
})
return
}
func (c *context) ResetOffscreen() {
c.canvas.use(func() {
c.canvas.context.ResetOffscreen()
})
}
func (c *context) SetOffscreen(id graphics.RenderTargetID) {
c.canvas.use(func() {
c.canvas.context.SetOffscreen(id)
})
}
type drawer struct {
canvas *canvas
innerDrawer graphics.Drawer
}
var _ graphics.Drawer = new(drawer)
func (d *drawer) Draw(parts []graphics.TexturePart, geo matrix.Geometry, color matrix.Color) {
d.canvas.use(func() {
d.innerDrawer.Draw(parts, geo, color)
})
}

View File

@ -45,7 +45,7 @@ func (u *UI) Start(width, height, scale int, title string) (ui.Canvas, error) {
windowWidth, _ := window.GetFramebufferSize()
realScale := windowWidth / width
c.use(func() {
c.contextUpdater, err = opengl.Initialize(width, height, realScale)
c.context, err = opengl.Initialize(width, height, realScale)
})
if err != nil {
return nil, err