2013-12-06 18:20:48 +01:00
|
|
|
package cocoa
|
|
|
|
|
2013-12-30 19:17:39 +01:00
|
|
|
// @class NSOpenGLContext;
|
|
|
|
//
|
|
|
|
// NSOpenGLContext* CreateGLContext(NSOpenGLContext* sharedGLContext);
|
|
|
|
// void UseGLContext(NSOpenGLContext* glContext);
|
2013-12-07 17:35:24 +01:00
|
|
|
// void UnuseGLContext(void);
|
2013-12-06 18:20:48 +01:00
|
|
|
//
|
|
|
|
import "C"
|
|
|
|
import (
|
2014-01-06 16:10:46 +01:00
|
|
|
"github.com/hajimehoshi/go-ebiten/graphics"
|
|
|
|
"github.com/hajimehoshi/go-ebiten/graphics/opengl"
|
|
|
|
"image"
|
2013-12-08 14:13:48 +01:00
|
|
|
"runtime"
|
2013-12-06 18:20:48 +01:00
|
|
|
)
|
|
|
|
|
2014-01-11 02:34:38 +01:00
|
|
|
type sharedContext struct {
|
2014-01-11 10:04:15 +01:00
|
|
|
inited chan struct{}
|
|
|
|
sharedContext *opengl.SharedContext
|
|
|
|
events chan interface{}
|
|
|
|
funcs chan func()
|
|
|
|
funcsDone chan struct{}
|
|
|
|
gameWindows chan *GameWindow
|
2013-12-06 18:20:48 +01:00
|
|
|
}
|
|
|
|
|
2014-01-11 02:34:38 +01:00
|
|
|
func newSharedContext() *sharedContext {
|
|
|
|
return &sharedContext{
|
2014-01-06 18:14:53 +01:00
|
|
|
inited: make(chan struct{}),
|
|
|
|
funcs: make(chan func()),
|
|
|
|
funcsDone: make(chan struct{}),
|
|
|
|
gameWindows: make(chan *GameWindow),
|
2013-12-06 18:20:48 +01:00
|
|
|
}
|
2014-01-06 18:14:53 +01:00
|
|
|
}
|
|
|
|
|
2014-01-11 02:34:38 +01:00
|
|
|
func (t *sharedContext) run() {
|
|
|
|
var sharedGLContext *C.NSOpenGLContext
|
2013-12-06 18:20:48 +01:00
|
|
|
go func() {
|
2013-12-08 14:13:48 +01:00
|
|
|
runtime.LockOSThread()
|
2014-01-11 10:04:15 +01:00
|
|
|
t.sharedContext = opengl.Initialize()
|
2014-01-11 02:34:38 +01:00
|
|
|
sharedGLContext = C.CreateGLContext(nil)
|
2014-01-06 18:14:53 +01:00
|
|
|
close(t.inited)
|
2014-01-11 02:34:38 +01:00
|
|
|
t.loop(sharedGLContext)
|
2014-01-06 18:14:53 +01:00
|
|
|
}()
|
|
|
|
<-t.inited
|
|
|
|
go func() {
|
|
|
|
for w := range t.gameWindows {
|
2014-01-11 10:04:15 +01:00
|
|
|
w.run(t.sharedContext, sharedGLContext)
|
2014-01-06 18:14:53 +01:00
|
|
|
}
|
|
|
|
}()
|
2013-12-06 18:20:48 +01:00
|
|
|
}
|
|
|
|
|
2014-01-11 02:34:38 +01:00
|
|
|
func (t *sharedContext) loop(sharedGLContext *C.NSOpenGLContext) {
|
2013-12-06 18:20:48 +01:00
|
|
|
for {
|
|
|
|
select {
|
|
|
|
case f := <-t.funcs:
|
2014-01-11 02:34:38 +01:00
|
|
|
C.UseGLContext(sharedGLContext)
|
2013-12-06 18:20:48 +01:00
|
|
|
f()
|
2013-12-07 17:35:24 +01:00
|
|
|
C.UnuseGLContext()
|
2013-12-06 18:20:48 +01:00
|
|
|
t.funcsDone <- struct{}{}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-01-11 02:34:38 +01:00
|
|
|
func (t *sharedContext) useGLContext(f func()) {
|
2013-12-06 18:20:48 +01:00
|
|
|
t.funcs <- f
|
|
|
|
<-t.funcsDone
|
|
|
|
}
|
|
|
|
|
2014-01-11 02:34:38 +01:00
|
|
|
func (t *sharedContext) createGameWindow(width, height, scale int, title string) *GameWindow {
|
2014-01-06 18:14:53 +01:00
|
|
|
w := newGameWindow(width, height, scale, title)
|
|
|
|
go func() {
|
|
|
|
t.gameWindows <- w
|
|
|
|
}()
|
|
|
|
return w
|
2014-01-06 16:10:46 +01:00
|
|
|
}
|
|
|
|
|
2014-01-11 02:34:38 +01:00
|
|
|
func (t *sharedContext) Events() <-chan interface{} {
|
2014-01-06 16:10:46 +01:00
|
|
|
if t.events != nil {
|
|
|
|
return t.events
|
|
|
|
}
|
|
|
|
t.events = make(chan interface{})
|
|
|
|
return t.events
|
|
|
|
}
|
|
|
|
|
2014-01-11 02:34:38 +01:00
|
|
|
func (t *sharedContext) CreateTexture(tag interface{}, img image.Image, filter graphics.Filter) {
|
2014-01-06 16:10:46 +01:00
|
|
|
go func() {
|
2014-01-06 18:14:53 +01:00
|
|
|
<-t.inited
|
2014-01-06 16:10:46 +01:00
|
|
|
var id graphics.TextureId
|
|
|
|
var err error
|
|
|
|
t.useGLContext(func() {
|
2014-01-11 10:04:15 +01:00
|
|
|
id, err = t.sharedContext.CreateTexture(img, filter)
|
2014-01-06 16:10:46 +01:00
|
|
|
})
|
|
|
|
if t.events == nil {
|
|
|
|
return
|
|
|
|
}
|
2014-01-11 02:34:38 +01:00
|
|
|
t.events <- graphics.TextureCreatedEvent{
|
2014-01-06 16:10:46 +01:00
|
|
|
Tag: tag,
|
|
|
|
Id: id,
|
|
|
|
Error: err,
|
|
|
|
}
|
|
|
|
}()
|
|
|
|
}
|
|
|
|
|
2014-01-11 10:07:12 +01:00
|
|
|
func (t *sharedContext) CreateRenderTarget(tag interface{}, width, height int, filter graphics.Filter) {
|
2014-01-06 16:10:46 +01:00
|
|
|
go func() {
|
2014-01-06 18:14:53 +01:00
|
|
|
<-t.inited
|
2014-01-06 16:10:46 +01:00
|
|
|
var id graphics.RenderTargetId
|
|
|
|
var err error
|
|
|
|
t.useGLContext(func() {
|
2014-01-11 10:07:12 +01:00
|
|
|
id, err = t.sharedContext.CreateRenderTarget(width, height, filter)
|
2014-01-06 16:10:46 +01:00
|
|
|
})
|
|
|
|
if t.events == nil {
|
|
|
|
return
|
|
|
|
}
|
2014-01-11 02:34:38 +01:00
|
|
|
t.events <- graphics.RenderTargetCreatedEvent{
|
2014-01-06 16:10:46 +01:00
|
|
|
Tag: tag,
|
|
|
|
Id: id,
|
|
|
|
Error: err,
|
|
|
|
}
|
|
|
|
}()
|
2013-12-06 18:20:48 +01:00
|
|
|
}
|