Remove the render target when closing the window

This commit is contained in:
Hajime Hoshi 2014-01-07 21:58:46 +09:00
parent 5d2e2476b6
commit 7cea6f4bc8
6 changed files with 54 additions and 25 deletions

View File

@ -37,6 +37,10 @@ func newContext(ids *ids, screenWidth, screenHeight, screenScale int) *Context {
return context return context
} }
func (context *Context) Dispose() {
context.ids.DeleteRenderTarget(context.screenId)
}
func (context *Context) update(draw func(graphics.Context)) { func (context *Context) update(draw func(graphics.Context)) {
C.glEnable(C.GL_TEXTURE_2D) C.glEnable(C.GL_TEXTURE_2D)
C.glEnable(C.GL_BLEND) C.glEnable(C.GL_BLEND)

View File

@ -81,3 +81,9 @@ func (i *ids) CreateRenderTarget(width, height int, filter graphics.Filter) (
return renderTargetId, nil return renderTargetId, nil
} }
func (i *ids) DeleteRenderTarget(id graphics.RenderTargetId) {
renderTarget := i.renderTargets[id]
rendertarget.Dispose(renderTarget)
delete(i.renderTargets, id)
}

View File

@ -57,3 +57,15 @@ func CreateWithFramebuffer(width, height int, framebuffer Framebuffer) (
*gtexture.RenderTarget, error) { *gtexture.RenderTarget, error) {
return gtexture.NewRenderTarget(framebuffer, width, height), nil return gtexture.NewRenderTarget(framebuffer, width, height), nil
} }
type disposer struct {
}
func (d *disposer) Dispose(native interface{}) {
framebuffer := C.GLuint(native.(Framebuffer))
C.glDeleteFramebuffers(1, &framebuffer)
}
func Dispose(renderTarget *gtexture.RenderTarget) {
renderTarget.Dispose(&disposer{})
}

View File

@ -21,3 +21,11 @@ type OffscreenSetter interface {
func (r *RenderTarget) SetAsOffscreen(setter OffscreenSetter) { func (r *RenderTarget) SetAsOffscreen(setter OffscreenSetter) {
setter.Set(r.framebuffer, 0, 0, r.offscreenWidth, r.offscreenHeight) setter.Set(r.framebuffer, 0, 0, r.offscreenWidth, r.offscreenHeight)
} }
type RenderTargetDisposer interface {
Dispose(framebuffer interface{})
}
func (r *RenderTarget) Dispose(disposer RenderTargetDisposer) {
disposer.Dispose(r.framebuffer)
}

View File

@ -12,7 +12,6 @@ package cocoa
// EbitenGameWindow* CreateGameWindow(size_t width, size_t height, const char* title, NSOpenGLContext* glContext); // EbitenGameWindow* CreateGameWindow(size_t width, size_t height, const char* title, NSOpenGLContext* glContext);
// NSOpenGLContext* CreateGLContext(NSOpenGLContext* sharedGLContext); // NSOpenGLContext* CreateGLContext(NSOpenGLContext* sharedGLContext);
// //
// NSOpenGLContext* GetGLContext(EbitenGameWindow* window);
// void UseGLContext(NSOpenGLContext* glContext); // void UseGLContext(NSOpenGLContext* glContext);
// void UnuseGLContext(void); // void UnuseGLContext(void);
// //
@ -31,12 +30,11 @@ type GameWindow struct {
screenHeight int screenHeight int
screenScale int screenScale int
title string title string
closed bool
native *C.EbitenGameWindow native *C.EbitenGameWindow
pressedKeys map[ui.Key]struct{} pressedKeys map[ui.Key]struct{}
context *opengl.Context funcs chan func(*opengl.Context)
funcs chan func()
funcsDone chan struct{} funcsDone chan struct{}
closed chan struct{}
events chan interface{} events chan interface{}
} }
@ -48,10 +46,10 @@ func newGameWindow(width, height, scale int, title string) *GameWindow {
screenHeight: height, screenHeight: height,
screenScale: scale, screenScale: scale,
title: title, title: title,
closed: false,
pressedKeys: map[ui.Key]struct{}{}, pressedKeys: map[ui.Key]struct{}{},
funcs: make(chan func()), funcs: make(chan func(*opengl.Context)),
funcsDone: make(chan struct{}), funcsDone: make(chan struct{}),
closed: make(chan struct{}),
} }
} }
@ -70,22 +68,30 @@ func (w *GameWindow) run(graphicsDevice *opengl.Device, sharedContext *C.NSOpenG
glContext) glContext)
windows[w.native] = w windows[w.native] = w
close(ch) close(ch)
w.loop() w.loop(glContext)
}() }()
<-ch <-ch
w.useGLContext(func() {
w.context = w.graphicsDevice.CreateContext(
w.screenWidth, w.screenHeight, w.screenScale)
})
} }
func (w *GameWindow) loop() { func (w *GameWindow) loop(glContext *C.NSOpenGLContext) {
C.UseGLContext(glContext)
context := w.graphicsDevice.CreateContext(
w.screenWidth, w.screenHeight, w.screenScale)
C.UnuseGLContext()
defer func() {
C.UseGLContext(glContext)
context.Dispose()
C.UnuseGLContext()
}()
for { for {
select { select {
case <-w.closed:
return
case f := <-w.funcs: case f := <-w.funcs:
glContext := C.GetGLContext(w.native)
C.UseGLContext(glContext) C.UseGLContext(glContext)
f() f(context)
C.UnuseGLContext() C.UnuseGLContext()
w.funcsDone <- struct{}{} w.funcsDone <- struct{}{}
} }
@ -93,15 +99,12 @@ func (w *GameWindow) loop() {
} }
func (w *GameWindow) Draw(f func(graphics.Context)) { func (w *GameWindow) Draw(f func(graphics.Context)) {
if w.closed { w.useGLContext(func(context *opengl.Context) {
return w.graphicsDevice.Update(context, f)
}
w.useGLContext(func() {
w.graphicsDevice.Update(w.context, f)
}) })
} }
func (w *GameWindow) useGLContext(f func()) { func (w *GameWindow) useGLContext(f func(*opengl.Context)) {
w.funcs <- f w.funcs <- f
<-w.funcsDone <-w.funcsDone
} }
@ -201,7 +204,7 @@ func ebiten_MouseStateUpdated(nativeWindow C.EbitenGameWindowPtr, inputType C.In
//export ebiten_WindowClosed //export ebiten_WindowClosed
func ebiten_WindowClosed(nativeWindow C.EbitenGameWindowPtr) { func ebiten_WindowClosed(nativeWindow C.EbitenGameWindowPtr) {
w := windows[nativeWindow] w := windows[nativeWindow]
w.closed = true close(w.closed)
w.notify(ui.WindowClosedEvent{}) w.notify(ui.WindowClosedEvent{})
delete(windows, nativeWindow) delete(windows, nativeWindow)
} }

View File

@ -108,7 +108,3 @@ void UnuseGLContext(void) {
CGLContextObj cglContext = [glContext CGLContextObj]; CGLContextObj cglContext = [glContext CGLContextObj];
CGLUnlockContext(cglContext); CGLUnlockContext(cglContext);
} }
NSOpenGLContext* GetGLContext(EbitenGameWindow* window) {
return [window glContext];
}