mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-12-25 03:08:54 +01:00
gomobile bind works
This commit is contained in:
parent
296282435a
commit
6d06b01cae
@ -17,8 +17,6 @@
|
|||||||
package mobile
|
package mobile
|
||||||
|
|
||||||
import (
|
import (
|
||||||
_ "image/jpeg"
|
|
||||||
"log"
|
|
||||||
"math"
|
"math"
|
||||||
|
|
||||||
"github.com/hajimehoshi/ebiten"
|
"github.com/hajimehoshi/ebiten"
|
||||||
@ -49,11 +47,16 @@ func update(screen *ebiten.Image) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func Start() {
|
func Start() error {
|
||||||
var err error
|
var err error
|
||||||
gophersImage, _, err = common.AssetImage("gophers.jpg", ebiten.FilterNearest)
|
gophersImage, _, err = common.AssetImage("gophers.jpg", ebiten.FilterNearest)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
return err
|
||||||
}
|
}
|
||||||
mobile.Start(update, screenWidth, screenHeight, 2, "Mobile (Ebiten Demo)")
|
mobile.Start(update, screenWidth, screenHeight, 2, "Mobile (Ebiten Demo)")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func Render() error {
|
||||||
|
return mobile.Render()
|
||||||
}
|
}
|
||||||
|
@ -14,6 +14,11 @@
|
|||||||
|
|
||||||
package ebiten
|
package ebiten
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/hajimehoshi/ebiten/internal/graphics"
|
||||||
|
"github.com/hajimehoshi/ebiten/internal/ui"
|
||||||
|
)
|
||||||
|
|
||||||
func newGraphicsContext(f func(*Image) error) *graphicsContext {
|
func newGraphicsContext(f func(*Image) error) *graphicsContext {
|
||||||
return &graphicsContext{
|
return &graphicsContext{
|
||||||
f: f,
|
f: f,
|
||||||
@ -25,6 +30,7 @@ type graphicsContext struct {
|
|||||||
screen *Image
|
screen *Image
|
||||||
defaultRenderTarget *Image
|
defaultRenderTarget *Image
|
||||||
screenScale int
|
screenScale int
|
||||||
|
imageTasksDone bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *graphicsContext) SetSize(screenWidth, screenHeight, screenScale int) error {
|
func (c *graphicsContext) SetSize(screenWidth, screenHeight, screenScale int) error {
|
||||||
@ -49,6 +55,17 @@ func (c *graphicsContext) SetSize(screenWidth, screenHeight, screenScale int) er
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *graphicsContext) Update() error {
|
func (c *graphicsContext) Update() error {
|
||||||
|
if !c.imageTasksDone {
|
||||||
|
if err := graphics.Initialize(ui.GLContext()); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
// This execution is called here because we can say actual GL function calls
|
||||||
|
// should be done here (especailly on mobiles).
|
||||||
|
if err := theDelayedImageTasks.exec(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
c.imageTasksDone = true
|
||||||
|
}
|
||||||
if err := c.screen.Clear(); err != nil {
|
if err := c.screen.Clear(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
4
image.go
4
image.go
@ -561,10 +561,6 @@ func newImageWithZeroFramebuffer(width, height int) (*Image, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
// When this is called, OpenGL context should exist.
|
|
||||||
if err := theDelayedImageTasks.exec(); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return img, nil
|
return img, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,10 +41,12 @@ func (p Program) id() programID {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type context struct {
|
type context struct {
|
||||||
gl mgl.Context
|
gl mgl.Context
|
||||||
|
worker mgl.Worker
|
||||||
|
initialized chan struct{}
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewContext() *Context {
|
func NewContext() (*Context, error) {
|
||||||
c := &Context{
|
c := &Context{
|
||||||
Nearest: mgl.NEAREST,
|
Nearest: mgl.NEAREST,
|
||||||
Linear: mgl.LINEAR,
|
Linear: mgl.LINEAR,
|
||||||
@ -65,21 +67,28 @@ func NewContext() *Context {
|
|||||||
locationCache: newLocationCache(),
|
locationCache: newLocationCache(),
|
||||||
lastCompositeMode: CompositeModeUnknown,
|
lastCompositeMode: CompositeModeUnknown,
|
||||||
}
|
}
|
||||||
return c
|
c.gl, c.worker = mgl.NewContext()
|
||||||
|
c.initialized = make(chan struct{})
|
||||||
|
go func() {
|
||||||
|
// GL calls will just enqueue an task to the worker.
|
||||||
|
// Since the worker is not avaialbe, this enqueuing should be done
|
||||||
|
// in a goroutine.
|
||||||
|
|
||||||
|
// Textures' pixel formats are alpha premultiplied.
|
||||||
|
c.gl.Enable(mgl.BLEND)
|
||||||
|
c.BlendFunc(CompositeModeSourceOver)
|
||||||
|
close(c.initialized)
|
||||||
|
}()
|
||||||
|
return c, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Context) SetContext(gl mgl.Context) {
|
func (c *Context) WaitUntilInitializingDone() {
|
||||||
c.gl = gl
|
// TODO: Call this function at an approriate place
|
||||||
if gl == nil {
|
<-c.initialized
|
||||||
return
|
|
||||||
}
|
|
||||||
// Textures' pixel formats are alpha premultiplied.
|
|
||||||
gl.Enable(mgl.BLEND)
|
|
||||||
c.BlendFunc(CompositeModeSourceOver)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Context) IsGLContextNil() bool {
|
func (c *Context) Worker() mgl.Worker {
|
||||||
return c.gl == nil
|
return c.worker
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Context) BlendFunc(mode CompositeMode) {
|
func (c *Context) BlendFunc(mode CompositeMode) {
|
||||||
|
@ -150,6 +150,9 @@ func Run(g GraphicsContext, width, height, scale int, title string, fps int) err
|
|||||||
beforeForUpdate += int64(tt) * int64(time.Second) / int64(fps)
|
beforeForUpdate += int64(tt) * int64(time.Second) / int64(fps)
|
||||||
frames++
|
frames++
|
||||||
}
|
}
|
||||||
|
if err := ui.CurrentUI().FinishRendering(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
// Calc the current FPS.
|
// Calc the current FPS.
|
||||||
if time.Second <= time.Duration(n2-beforeForFPS) {
|
if time.Second <= time.Duration(n2-beforeForFPS) {
|
||||||
|
@ -18,6 +18,7 @@ type UserInterface interface {
|
|||||||
Start(width, height, scale int, title string) error
|
Start(width, height, scale int, title string) error
|
||||||
Update() (interface{}, error)
|
Update() (interface{}, error)
|
||||||
SwapBuffers() error
|
SwapBuffers() error
|
||||||
|
FinishRendering() error
|
||||||
Terminate() error
|
Terminate() error
|
||||||
ScreenScale() int
|
ScreenScale() int
|
||||||
SetScreenSize(width, height int) bool
|
SetScreenSize(width, height int) bool
|
||||||
|
@ -23,7 +23,6 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/go-gl/glfw/v3.1/glfw"
|
"github.com/go-gl/glfw/v3.1/glfw"
|
||||||
"github.com/hajimehoshi/ebiten/internal/graphics"
|
|
||||||
"github.com/hajimehoshi/ebiten/internal/graphics/opengl"
|
"github.com/hajimehoshi/ebiten/internal/graphics/opengl"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -87,9 +86,6 @@ func initialize() (*opengl.Context, error) {
|
|||||||
if err := u.context.Init(); err != nil {
|
if err := u.context.Init(); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if err := graphics.Initialize(u.context); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return u.context, nil
|
return u.context, nil
|
||||||
}
|
}
|
||||||
@ -262,6 +258,10 @@ func (u *userInterface) swapBuffers() {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (u *userInterface) FinishRendering() error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (u *userInterface) setScreenSize(width, height, scale int) bool {
|
func (u *userInterface) setScreenSize(width, height, scale int) bool {
|
||||||
if u.width == width && u.height == height && u.scale == scale {
|
if u.width == width && u.height == height && u.scale == scale {
|
||||||
return false
|
return false
|
||||||
|
@ -20,7 +20,6 @@ import (
|
|||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
"github.com/gopherjs/gopherjs/js"
|
"github.com/gopherjs/gopherjs/js"
|
||||||
"github.com/hajimehoshi/ebiten/internal/graphics"
|
|
||||||
"github.com/hajimehoshi/ebiten/internal/graphics/opengl"
|
"github.com/hajimehoshi/ebiten/internal/graphics/opengl"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -109,6 +108,10 @@ func (u *userInterface) SwapBuffers() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (u *userInterface) FinishRendering() error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func initialize() (*opengl.Context, error) {
|
func initialize() (*opengl.Context, error) {
|
||||||
// Do nothing in node.js.
|
// Do nothing in node.js.
|
||||||
if js.Global.Get("require") != js.Undefined {
|
if js.Global.Get("require") != js.Undefined {
|
||||||
@ -116,9 +119,6 @@ func initialize() (*opengl.Context, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if err := graphics.Initialize(c); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return c, nil
|
return c, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -226,9 +226,6 @@ func initialize() (*opengl.Context, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if err := graphics.Initialize(c); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return c, nil
|
return c, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,26 +17,68 @@
|
|||||||
package ui
|
package ui
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
|
|
||||||
"github.com/hajimehoshi/ebiten/internal/graphics/opengl"
|
"github.com/hajimehoshi/ebiten/internal/graphics/opengl"
|
||||||
)
|
)
|
||||||
|
|
||||||
func initialize() (*opengl.Context, error) {
|
func initialize() (*opengl.Context, error) {
|
||||||
// TODO: Implement
|
return opengl.NewContext()
|
||||||
return nil, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func Main() error {
|
func Main() error {
|
||||||
|
return errors.New("ui: don't call this: use RunWithoutMainLoop instead of Run")
|
||||||
|
}
|
||||||
|
|
||||||
|
func Render(chError <-chan error) error {
|
||||||
|
if chError == nil {
|
||||||
|
return errors.New("ui: chError must not be nil")
|
||||||
|
}
|
||||||
|
// TODO: Check this is called on the rendering thread
|
||||||
|
chRender <- struct{}{}
|
||||||
|
worker := glContext.Worker()
|
||||||
|
loop:
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case err := <-chError:
|
||||||
|
return err
|
||||||
|
case <-worker.WorkAvailable():
|
||||||
|
worker.DoWork()
|
||||||
|
case <-chRenderEnd:
|
||||||
|
break loop
|
||||||
|
}
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type userInterface struct {
|
type userInterface struct {
|
||||||
|
width int
|
||||||
|
height int
|
||||||
|
scale int
|
||||||
|
sizeChanged bool
|
||||||
|
render chan struct{}
|
||||||
|
renderEnd chan struct{}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
chRender = make(chan struct{})
|
||||||
|
chRenderEnd = make(chan struct{})
|
||||||
|
currentUI = &userInterface{
|
||||||
|
sizeChanged: true,
|
||||||
|
render: chRender,
|
||||||
|
renderEnd: chRenderEnd,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
func CurrentUI() UserInterface {
|
func CurrentUI() UserInterface {
|
||||||
return nil
|
return currentUI
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u *userInterface) Start(width, height, scale int, title string) error {
|
func (u *userInterface) Start(width, height, scale int, title string) error {
|
||||||
|
u.width = width
|
||||||
|
u.height = height
|
||||||
|
u.scale = scale
|
||||||
|
// title is ignored?
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -45,21 +87,46 @@ func (u *userInterface) Terminate() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (u *userInterface) Update() (interface{}, error) {
|
func (u *userInterface) Update() (interface{}, error) {
|
||||||
return nil, nil
|
// TODO: Need lock?
|
||||||
|
if u.sizeChanged {
|
||||||
|
u.sizeChanged = false
|
||||||
|
e := ScreenSizeEvent{
|
||||||
|
Width: u.width,
|
||||||
|
Height: u.height,
|
||||||
|
Scale: u.scale,
|
||||||
|
ActualScale: u.actualScreenScale(),
|
||||||
|
}
|
||||||
|
return e, nil
|
||||||
|
}
|
||||||
|
select {
|
||||||
|
case <-u.render:
|
||||||
|
return RenderEvent{}, nil
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u *userInterface) SwapBuffers() error {
|
func (u *userInterface) SwapBuffers() error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (u *userInterface) FinishRendering() error {
|
||||||
|
u.renderEnd <- struct{}{}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (u *userInterface) SetScreenSize(width, height int) bool {
|
func (u *userInterface) SetScreenSize(width, height int) bool {
|
||||||
|
// TODO: Implement
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u *userInterface) SetScreenScale(scale int) bool {
|
func (u *userInterface) SetScreenScale(scale int) bool {
|
||||||
|
// TODO: Implement
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u *userInterface) ScreenScale() int {
|
func (u *userInterface) ScreenScale() int {
|
||||||
return 1
|
return u.scale
|
||||||
|
}
|
||||||
|
|
||||||
|
func (u *userInterface) actualScreenScale() int {
|
||||||
|
return u.scale
|
||||||
}
|
}
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
package mobile
|
package mobile
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"runtime"
|
"runtime"
|
||||||
|
|
||||||
"github.com/hajimehoshi/ebiten"
|
"github.com/hajimehoshi/ebiten"
|
||||||
@ -28,16 +29,6 @@ var chError <-chan error
|
|||||||
// Different from ebiten.Run, this invokes only the game loop and not the main (UI) loop.
|
// Different from ebiten.Run, this invokes only the game loop and not the main (UI) loop.
|
||||||
func Start(f func(*ebiten.Image) error, width, height, scale int, title string) {
|
func Start(f func(*ebiten.Image) error, width, height, scale int, title string) {
|
||||||
chError = ebiten.RunWithoutMainLoop(f, width, height, scale, title)
|
chError = ebiten.RunWithoutMainLoop(f, width, height, scale, title)
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func LastErrorString() string {
|
|
||||||
select {
|
|
||||||
case err := <-chError:
|
|
||||||
return err.Error()
|
|
||||||
default:
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func SetScreenSize(width, height int) {
|
func SetScreenSize(width, height int) {
|
||||||
@ -48,13 +39,12 @@ func SetScreenScale(scale int) {
|
|||||||
ui.CurrentUI().SetScreenScale(scale)
|
ui.CurrentUI().SetScreenScale(scale)
|
||||||
}
|
}
|
||||||
|
|
||||||
func Render() {
|
func Render() error {
|
||||||
runtime.LockOSThread()
|
runtime.LockOSThread()
|
||||||
// TODO: Implement this
|
defer runtime.UnlockOSThread()
|
||||||
/*select {
|
|
||||||
case <-workAvailable:
|
if chError == nil {
|
||||||
DoWork()
|
return errors.New("mobile: chError must not be nil: Start is not called yet?")
|
||||||
case <-done:
|
}
|
||||||
return
|
return ui.Render(chError)
|
||||||
}*/
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user