mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-12-25 19:28:57 +01:00
Add cocoa.textureFactory
This commit is contained in:
parent
24a735dd0b
commit
e55060c239
@ -79,7 +79,6 @@ func New() *Sprites {
|
||||
|
||||
func (game *Sprites) OnScreenSizeUpdated(e ui.ScreenSizeUpdatedEvent) {
|
||||
go func() {
|
||||
e := e
|
||||
game.screenSizeUpdatedCh <- e
|
||||
}()
|
||||
}
|
||||
|
@ -57,7 +57,11 @@ func main() {
|
||||
const fps = 60
|
||||
const title = "Ebiten Demo"
|
||||
|
||||
var u ui.UI = cocoa.New(screenWidth, screenHeight, screenScale, title)
|
||||
type UI interface {
|
||||
ui.UI
|
||||
//graphics.TextureFactory
|
||||
}
|
||||
var u UI = cocoa.New(screenWidth, screenHeight, screenScale, title)
|
||||
// TODO: Get a map or something
|
||||
u.LoadResources(game.InitTextures)
|
||||
inputStateUpdated := u.InputStateUpdated()
|
||||
@ -72,10 +76,9 @@ func main() {
|
||||
case e, ok := <-inputStateUpdated:
|
||||
// TODO: Use Adaptor?
|
||||
if ok {
|
||||
type Handler interface {
|
||||
if game2, ok := game.(interface {
|
||||
OnInputStateUpdated(ui.InputStateUpdatedEvent)
|
||||
}
|
||||
if game2, ok := game.(Handler); ok {
|
||||
}); ok {
|
||||
game2.OnInputStateUpdated(e)
|
||||
}
|
||||
} else {
|
||||
@ -83,10 +86,9 @@ func main() {
|
||||
}
|
||||
case e, ok := <-screenSizeUpdated:
|
||||
if ok {
|
||||
type Handler interface {
|
||||
if game2, ok := game.(interface {
|
||||
OnScreenSizeUpdated(ui.ScreenSizeUpdatedEvent)
|
||||
}
|
||||
if game2, ok := game.(Handler); ok {
|
||||
}); ok {
|
||||
game2.OnScreenSizeUpdated(e)
|
||||
}
|
||||
} else {
|
||||
|
@ -3,6 +3,7 @@ package opengl
|
||||
import (
|
||||
"github.com/hajimehoshi/go-ebiten/graphics"
|
||||
"github.com/hajimehoshi/go-ebiten/graphics/matrix"
|
||||
"image"
|
||||
)
|
||||
|
||||
type Device struct {
|
||||
@ -18,8 +19,8 @@ func NewDevice(screenWidth, screenHeight, screenScale int) *Device {
|
||||
}
|
||||
}
|
||||
|
||||
func (device *Device) Update(draw func(graphics.Canvas)) {
|
||||
context := device.context
|
||||
func (d *Device) Update(draw func(graphics.Canvas)) {
|
||||
context := d.context
|
||||
context.Init()
|
||||
context.ResetOffscreen()
|
||||
context.Clear()
|
||||
@ -30,7 +31,7 @@ func (device *Device) Update(draw func(graphics.Canvas)) {
|
||||
context.setMainFramebufferOffscreen()
|
||||
context.Clear()
|
||||
|
||||
scale := float64(device.screenScale)
|
||||
scale := float64(d.screenScale)
|
||||
geometryMatrix := matrix.IdentityGeometry()
|
||||
geometryMatrix.Scale(scale, scale)
|
||||
context.DrawRenderTarget(context.screenId,
|
||||
@ -38,6 +39,10 @@ func (device *Device) Update(draw func(graphics.Canvas)) {
|
||||
context.flush()
|
||||
}
|
||||
|
||||
func (device *Device) TextureFactory() graphics.TextureFactory {
|
||||
return device.context
|
||||
func (d *Device) CreateRenderTarget(tag string, width, height int) (graphics.RenderTargetId, error) {
|
||||
return d.context.CreateRenderTarget(tag, width, height)
|
||||
}
|
||||
|
||||
func (d *Device) CreateTextureFromImage(tag string, img image.Image) (graphics.TextureId, error) {
|
||||
return d.context.CreateTextureFromImage(tag, img)
|
||||
}
|
||||
|
@ -21,6 +21,13 @@ type TextureFactoryEvents interface {
|
||||
RenderTargetCreated() <-chan RenderTargetCreatedEvent
|
||||
}
|
||||
|
||||
// TODO: Rename this later
|
||||
type TextureFactory2 interface {
|
||||
CreateRenderTarget(tag string, width, height int)
|
||||
CreateTexture(tag string, img image.Image)
|
||||
TextureFactoryEvents
|
||||
}
|
||||
|
||||
type TextureFactory interface {
|
||||
CreateRenderTarget(tag string, width, height int) (RenderTargetId, error)
|
||||
CreateTextureFromImage(tag string, img image.Image) (TextureId, error)
|
||||
|
@ -3,13 +3,9 @@ package cocoa
|
||||
// #cgo CFLAGS: -x objective-c
|
||||
// #cgo LDFLAGS: -framework Cocoa -framework OpenGL
|
||||
//
|
||||
// #include <stdlib.h>
|
||||
// #include "input.h"
|
||||
//
|
||||
// void StartApplication(void);
|
||||
// void* CreateGLContext(void* sharedGLContext);
|
||||
// void SetCurrentGLContext(void* glContext);
|
||||
// void* CreateWindow(size_t width, size_t height, const char* title, void* sharedGLContext);
|
||||
// void PollEvents(void);
|
||||
// void BeginDrawing(void* window);
|
||||
// void EndDrawing(void* window);
|
||||
@ -19,18 +15,19 @@ import (
|
||||
"github.com/hajimehoshi/go-ebiten/graphics"
|
||||
"github.com/hajimehoshi/go-ebiten/graphics/opengl"
|
||||
"github.com/hajimehoshi/go-ebiten/ui"
|
||||
"image"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
type UI struct {
|
||||
screenWidth int
|
||||
screenHeight int
|
||||
screenScale int
|
||||
graphicsDevice *opengl.Device
|
||||
window unsafe.Pointer
|
||||
initialEventSent bool
|
||||
screenSizeUpdated chan ui.ScreenSizeUpdatedEvent // initialized lazily
|
||||
inputStateUpdated chan ui.InputStateUpdatedEvent // initialized lazily
|
||||
screenWidth int
|
||||
screenHeight int
|
||||
screenScale int
|
||||
graphicsDevice *opengl.Device
|
||||
window unsafe.Pointer
|
||||
initialEventSent bool
|
||||
textureFactory *textureFactory
|
||||
uiEvents
|
||||
}
|
||||
|
||||
var currentUI *UI
|
||||
@ -46,22 +43,22 @@ func New(screenWidth, screenHeight, screenScale int, title string) *UI {
|
||||
initialEventSent: false,
|
||||
}
|
||||
|
||||
cTitle := C.CString(title)
|
||||
defer C.free(unsafe.Pointer(cTitle))
|
||||
|
||||
C.StartApplication()
|
||||
|
||||
context := C.CreateGLContext(unsafe.Pointer(nil))
|
||||
C.SetCurrentGLContext(context)
|
||||
u.graphicsDevice = opengl.NewDevice(
|
||||
u.screenWidth,
|
||||
u.screenHeight,
|
||||
u.screenScale)
|
||||
u.textureFactory = runTextureFactory()
|
||||
|
||||
u.textureFactory.UseContext(func() {
|
||||
u.graphicsDevice = opengl.NewDevice(
|
||||
u.screenWidth,
|
||||
u.screenHeight,
|
||||
u.screenScale)
|
||||
})
|
||||
|
||||
u.window = u.textureFactory.CreateWindow(
|
||||
u.screenWidth*u.screenScale,
|
||||
u.screenHeight*u.screenScale,
|
||||
title)
|
||||
|
||||
u.window = C.CreateWindow(C.size_t(u.screenWidth*u.screenScale),
|
||||
C.size_t(u.screenHeight*u.screenScale),
|
||||
cTitle,
|
||||
context)
|
||||
currentUI = u
|
||||
|
||||
return u
|
||||
@ -71,19 +68,20 @@ func (u *UI) PollEvents() {
|
||||
C.PollEvents()
|
||||
if !u.initialEventSent {
|
||||
e := ui.ScreenSizeUpdatedEvent{u.screenWidth, u.screenHeight}
|
||||
u.notifyScreenSizeUpdated(e)
|
||||
u.uiEvents.notifyScreenSizeUpdated(e)
|
||||
u.initialEventSent = true
|
||||
}
|
||||
}
|
||||
|
||||
func (u *UI) LoadTextures(map[int]string) {
|
||||
// TODO: Implement
|
||||
func (u *UI) CreateRenderTarget(tag string, width, height int) {
|
||||
}
|
||||
|
||||
func (u *UI) CreateTexture(tag string, img image.Image) {
|
||||
}
|
||||
|
||||
func (u *UI) LoadResources(f func(graphics.TextureFactory)) {
|
||||
C.BeginDrawing(u.window)
|
||||
// This should be executed on the shared-context context
|
||||
f(u.graphicsDevice)
|
||||
C.EndDrawing(u.window)
|
||||
}
|
||||
|
||||
func (u *UI) Draw(f func(graphics.Canvas)) {
|
||||
@ -92,45 +90,11 @@ func (u *UI) Draw(f func(graphics.Canvas)) {
|
||||
C.EndDrawing(u.window)
|
||||
}
|
||||
|
||||
func (u *UI) ScreenSizeUpdated() <-chan ui.ScreenSizeUpdatedEvent {
|
||||
if u.screenSizeUpdated != nil {
|
||||
return u.screenSizeUpdated
|
||||
}
|
||||
u.screenSizeUpdated = make(chan ui.ScreenSizeUpdatedEvent)
|
||||
return u.screenSizeUpdated
|
||||
}
|
||||
|
||||
func (u *UI) notifyScreenSizeUpdated(e ui.ScreenSizeUpdatedEvent) {
|
||||
if u.screenSizeUpdated == nil {
|
||||
return
|
||||
}
|
||||
go func() {
|
||||
u.screenSizeUpdated <- e
|
||||
}()
|
||||
}
|
||||
|
||||
func (u *UI) InputStateUpdated() <-chan ui.InputStateUpdatedEvent {
|
||||
if u.inputStateUpdated != nil {
|
||||
return u.inputStateUpdated
|
||||
}
|
||||
u.inputStateUpdated = make(chan ui.InputStateUpdatedEvent)
|
||||
return u.inputStateUpdated
|
||||
}
|
||||
|
||||
func (u *UI) notifyInputStateUpdated(e ui.InputStateUpdatedEvent) {
|
||||
if u.inputStateUpdated == nil {
|
||||
return
|
||||
}
|
||||
go func() {
|
||||
u.inputStateUpdated <- e
|
||||
}()
|
||||
}
|
||||
|
||||
//export ebiten_ScreenSizeUpdated
|
||||
func ebiten_ScreenSizeUpdated(width, height int) {
|
||||
u := currentUI
|
||||
e := ui.ScreenSizeUpdatedEvent{width, height}
|
||||
u.notifyScreenSizeUpdated(e)
|
||||
u.uiEvents.notifyScreenSizeUpdated(e)
|
||||
}
|
||||
|
||||
//export ebiten_InputUpdated
|
||||
@ -139,7 +103,7 @@ func ebiten_InputUpdated(inputType C.InputType, cx, cy C.int) {
|
||||
|
||||
if inputType == C.InputTypeMouseUp {
|
||||
e := ui.InputStateUpdatedEvent{-1, -1}
|
||||
u.notifyInputStateUpdated(e)
|
||||
u.uiEvents.notifyInputStateUpdated(e)
|
||||
return
|
||||
}
|
||||
|
||||
@ -157,5 +121,5 @@ func ebiten_InputUpdated(inputType C.InputType, cx, cy C.int) {
|
||||
y = u.screenHeight - 1
|
||||
}
|
||||
e := ui.InputStateUpdatedEvent{x, y}
|
||||
u.notifyInputStateUpdated(e)
|
||||
u.uiEvents.notifyInputStateUpdated(e)
|
||||
}
|
||||
|
@ -32,10 +32,6 @@ void* CreateGLContext(void* sharedGLContext) {
|
||||
return glContext;
|
||||
}
|
||||
|
||||
void SetCurrentGLContext(void* glContext) {
|
||||
[(NSOpenGLContext*)glContext makeCurrentContext];
|
||||
}
|
||||
|
||||
void* CreateWindow(size_t width, size_t height, const char* title, void* sharedGLContext) {
|
||||
NSOpenGLContext* glContext = CreateGLContext(sharedGLContext);
|
||||
[glContext makeCurrentContext];
|
||||
@ -66,7 +62,13 @@ void PollEvents(void) {
|
||||
}
|
||||
}
|
||||
|
||||
void UseGLContext(void* glContext) {
|
||||
// TODO: CGLLock
|
||||
[(NSOpenGLContext*)glContext makeCurrentContext];
|
||||
}
|
||||
|
||||
void BeginDrawing(void* window) {
|
||||
// TODO: CGLLock
|
||||
[[(EbitenWindow*)window glContext] makeCurrentContext];
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
}
|
||||
|
62
ui/cocoa/texture_factory.go
Normal file
62
ui/cocoa/texture_factory.go
Normal file
@ -0,0 +1,62 @@
|
||||
package cocoa
|
||||
|
||||
// #include <stdlib.h>
|
||||
//
|
||||
// void* CreateGLContext(void* sharedGLContext);
|
||||
// void* CreateWindow(size_t width, size_t height, const char* title, void* sharedGLContext);
|
||||
// void UseGLContext(void* glContext);
|
||||
//
|
||||
import "C"
|
||||
import (
|
||||
//"github.com/hajimehoshi/go-ebiten/graphics"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
type textureFactory struct {
|
||||
sharedContext unsafe.Pointer
|
||||
funcs chan func()
|
||||
funcsDone chan struct{}
|
||||
textureFactoryEvents
|
||||
}
|
||||
|
||||
func runTextureFactory() *textureFactory {
|
||||
t := &textureFactory{
|
||||
funcs: make(chan func()),
|
||||
funcsDone: make(chan struct{}),
|
||||
}
|
||||
ch := make(chan struct{})
|
||||
go func() {
|
||||
t.sharedContext = C.CreateGLContext(unsafe.Pointer(nil))
|
||||
close(ch)
|
||||
t.loop()
|
||||
}()
|
||||
<-ch
|
||||
return t
|
||||
}
|
||||
|
||||
func (t *textureFactory) loop() {
|
||||
for {
|
||||
select {
|
||||
case f := <-t.funcs:
|
||||
C.UseGLContext(t.sharedContext)
|
||||
f()
|
||||
t.funcsDone <- struct{}{}
|
||||
// TODO: Unuse
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (t *textureFactory) UseContext(f func()) {
|
||||
t.funcs <- f
|
||||
<-t.funcsDone
|
||||
}
|
||||
|
||||
func (t *textureFactory) CreateWindow(width, height int, title string) unsafe.Pointer {
|
||||
cTitle := C.CString(title)
|
||||
defer C.free(unsafe.Pointer(cTitle))
|
||||
|
||||
return C.CreateWindow(C.size_t(width),
|
||||
C.size_t(height),
|
||||
cTitle,
|
||||
t.sharedContext)
|
||||
}
|
44
ui/cocoa/texture_factory_events.go
Normal file
44
ui/cocoa/texture_factory_events.go
Normal file
@ -0,0 +1,44 @@
|
||||
package cocoa
|
||||
|
||||
import (
|
||||
"github.com/hajimehoshi/go-ebiten/graphics"
|
||||
)
|
||||
|
||||
type textureFactoryEvents struct {
|
||||
textureCreated chan graphics.TextureCreatedEvent
|
||||
renderTargetCreated chan graphics.RenderTargetCreatedEvent
|
||||
}
|
||||
|
||||
func (t *textureFactoryEvents) TextureCreated() <-chan graphics.TextureCreatedEvent {
|
||||
if t.textureCreated != nil {
|
||||
return t.textureCreated
|
||||
}
|
||||
t.textureCreated = make(chan graphics.TextureCreatedEvent)
|
||||
return t.textureCreated
|
||||
}
|
||||
|
||||
func (t *textureFactoryEvents) notifyTextureCreated(e graphics.TextureCreatedEvent) {
|
||||
if t.textureCreated == nil {
|
||||
return
|
||||
}
|
||||
go func() {
|
||||
t.textureCreated <- e
|
||||
}()
|
||||
}
|
||||
|
||||
func (t *textureFactoryEvents) RenderTargetCreated() <-chan graphics.RenderTargetCreatedEvent {
|
||||
if t.renderTargetCreated != nil {
|
||||
return t.renderTargetCreated
|
||||
}
|
||||
t.renderTargetCreated = make(chan graphics.RenderTargetCreatedEvent)
|
||||
return t.renderTargetCreated
|
||||
}
|
||||
|
||||
func (t *textureFactoryEvents) notifyRenderTargetCreated(e graphics.RenderTargetCreatedEvent) {
|
||||
if t.renderTargetCreated == nil {
|
||||
return
|
||||
}
|
||||
go func() {
|
||||
t.renderTargetCreated <- e
|
||||
}()
|
||||
}
|
44
ui/cocoa/ui_events.go
Normal file
44
ui/cocoa/ui_events.go
Normal file
@ -0,0 +1,44 @@
|
||||
package cocoa
|
||||
|
||||
import (
|
||||
"github.com/hajimehoshi/go-ebiten/ui"
|
||||
)
|
||||
|
||||
type uiEvents struct {
|
||||
screenSizeUpdated chan ui.ScreenSizeUpdatedEvent // initialized lazily
|
||||
inputStateUpdated chan ui.InputStateUpdatedEvent // initialized lazily
|
||||
}
|
||||
|
||||
func (u *uiEvents) ScreenSizeUpdated() <-chan ui.ScreenSizeUpdatedEvent {
|
||||
if u.screenSizeUpdated != nil {
|
||||
return u.screenSizeUpdated
|
||||
}
|
||||
u.screenSizeUpdated = make(chan ui.ScreenSizeUpdatedEvent)
|
||||
return u.screenSizeUpdated
|
||||
}
|
||||
|
||||
func (u *uiEvents) notifyScreenSizeUpdated(e ui.ScreenSizeUpdatedEvent) {
|
||||
if u.screenSizeUpdated == nil {
|
||||
return
|
||||
}
|
||||
go func() {
|
||||
u.screenSizeUpdated <- e
|
||||
}()
|
||||
}
|
||||
|
||||
func (u *uiEvents) InputStateUpdated() <-chan ui.InputStateUpdatedEvent {
|
||||
if u.inputStateUpdated != nil {
|
||||
return u.inputStateUpdated
|
||||
}
|
||||
u.inputStateUpdated = make(chan ui.InputStateUpdatedEvent)
|
||||
return u.inputStateUpdated
|
||||
}
|
||||
|
||||
func (u *uiEvents) notifyInputStateUpdated(e ui.InputStateUpdatedEvent) {
|
||||
if u.inputStateUpdated == nil {
|
||||
return
|
||||
}
|
||||
go func() {
|
||||
u.inputStateUpdated <- e
|
||||
}()
|
||||
}
|
Loading…
Reference in New Issue
Block a user