mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-11-10 04:57:26 +01:00
Refactoring: glut.UI implements ui.UI
This commit is contained in:
parent
9d83ae1cfa
commit
319d1bfc74
@ -10,7 +10,7 @@ import (
|
||||
"github.com/hajimehoshi/go-ebiten/example/game/sprites"
|
||||
"github.com/hajimehoshi/go-ebiten/ui"
|
||||
"github.com/hajimehoshi/go-ebiten/ui/cocoa"
|
||||
_ "github.com/hajimehoshi/go-ebiten/ui/glut"
|
||||
"github.com/hajimehoshi/go-ebiten/ui/glut"
|
||||
"os"
|
||||
"runtime"
|
||||
)
|
||||
@ -22,6 +22,10 @@ func main() {
|
||||
if 2 <= len(os.Args) {
|
||||
gameName = os.Args[1]
|
||||
}
|
||||
uiName := "cocoa"
|
||||
if 3 <= len(os.Args) {
|
||||
uiName = os.Args[2]
|
||||
}
|
||||
|
||||
var game ebiten.Game
|
||||
switch gameName {
|
||||
@ -33,15 +37,26 @@ func main() {
|
||||
game = monochrome.New()
|
||||
case "rects":
|
||||
game = rects.New()
|
||||
default:
|
||||
fallthrough
|
||||
case "rotating":
|
||||
game = rotating.New()
|
||||
case "sprites":
|
||||
game = sprites.New()
|
||||
default:
|
||||
game = rotating.New()
|
||||
}
|
||||
|
||||
const screenWidth = 256
|
||||
const screenHeight = 240
|
||||
const screenScale = 2
|
||||
cocoaUI := cocoa.New(256, 240, screenScale, "Ebiten Demo")
|
||||
ui.Run(cocoaUI, game)
|
||||
const title = "Ebiten Demo"
|
||||
var u ui.UI
|
||||
switch uiName {
|
||||
default:
|
||||
fallthrough
|
||||
case "cocoa":
|
||||
u = cocoa.New(screenWidth, screenHeight, screenScale, title)
|
||||
case "glut":
|
||||
u = glut.New(screenWidth, screenHeight, screenScale, title)
|
||||
}
|
||||
ui.Run(u, game)
|
||||
}
|
||||
|
224
ui/glut/glut.go
224
ui/glut/glut.go
@ -21,10 +21,8 @@ package glut
|
||||
import "C"
|
||||
import (
|
||||
"github.com/hajimehoshi/go-ebiten"
|
||||
"github.com/hajimehoshi/go-ebiten/graphics"
|
||||
"github.com/hajimehoshi/go-ebiten/graphics/opengl"
|
||||
"os"
|
||||
"time"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
@ -34,60 +32,44 @@ type glutInputEvent struct {
|
||||
Y int
|
||||
}
|
||||
|
||||
type GlutUI struct {
|
||||
type UI struct {
|
||||
screenWidth int
|
||||
screenHeight int
|
||||
screenScale int
|
||||
glutInputting chan glutInputEvent
|
||||
title string
|
||||
initializing chan ebiten.Game
|
||||
initialized chan ebiten.Game
|
||||
updating chan ebiten.Game
|
||||
updated chan ebiten.Game
|
||||
input chan ebiten.InputState
|
||||
graphicsDevice *opengl.Device
|
||||
updating chan func(graphics.Context)
|
||||
updated chan bool
|
||||
glutInputting chan glutInputEvent
|
||||
}
|
||||
|
||||
var currentUI *GlutUI
|
||||
var currentUI *UI
|
||||
|
||||
//export display
|
||||
func display() {
|
||||
draw := <-currentUI.updating
|
||||
currentUI.graphicsDevice.Update(draw)
|
||||
currentUI.updated <- true
|
||||
C.glutSwapBuffers()
|
||||
func New(screenWidth, screenHeight, screenScale int, title string) *UI {
|
||||
if currentUI != nil {
|
||||
panic("UI can't be duplicated.")
|
||||
}
|
||||
ui := &UI{
|
||||
screenWidth: screenWidth,
|
||||
screenHeight: screenHeight,
|
||||
screenScale: screenScale,
|
||||
title: title,
|
||||
initializing: make(chan ebiten.Game),
|
||||
initialized: make(chan ebiten.Game),
|
||||
updating: make(chan ebiten.Game),
|
||||
updated: make(chan ebiten.Game),
|
||||
input: make(chan ebiten.InputState),
|
||||
glutInputting: make(chan glutInputEvent),
|
||||
}
|
||||
currentUI = ui
|
||||
return ui
|
||||
}
|
||||
|
||||
//export mouse
|
||||
func mouse(button, state, x, y C.int) {
|
||||
event := glutInputEvent{false, 0, 0}
|
||||
if state == C.GLUT_DOWN {
|
||||
event.IsActive = true
|
||||
event.X = int(x)
|
||||
event.Y = int(y)
|
||||
}
|
||||
currentUI.glutInputting <- event
|
||||
}
|
||||
|
||||
//export motion
|
||||
func motion(x, y C.int) {
|
||||
currentUI.glutInputting <- glutInputEvent{
|
||||
IsActive: true,
|
||||
X: int(x),
|
||||
Y: int(y),
|
||||
}
|
||||
}
|
||||
|
||||
//export idle
|
||||
func idle() {
|
||||
C.glutPostRedisplay()
|
||||
}
|
||||
|
||||
func new(screenWidth, screenHeight, screenScale int, title string) *GlutUI {
|
||||
ui := &GlutUI{
|
||||
glutInputting: make(chan glutInputEvent, 10),
|
||||
updating: make(chan func(graphics.Context)),
|
||||
updated: make(chan bool),
|
||||
}
|
||||
|
||||
cargs := []*C.char{}
|
||||
for _, arg := range os.Args {
|
||||
cargs = append(cargs, C.CString(arg))
|
||||
}
|
||||
func (ui *UI) MainLoop() {
|
||||
cargs := []*C.char{C.CString(os.Args[0])}
|
||||
defer func() {
|
||||
for _, carg := range cargs {
|
||||
C.free(unsafe.Pointer(carg))
|
||||
@ -99,73 +81,20 @@ func new(screenWidth, screenHeight, screenScale int, title string) *GlutUI {
|
||||
C.glutInit(&cargc, &cargs[0])
|
||||
C.glutInitDisplayMode(C.GLUT_RGBA)
|
||||
C.glutInitWindowSize(
|
||||
C.int(screenWidth*screenScale),
|
||||
C.int(screenHeight*screenScale))
|
||||
C.int(ui.screenWidth*ui.screenScale),
|
||||
C.int(ui.screenHeight*ui.screenScale))
|
||||
|
||||
cTitle := C.CString(title)
|
||||
cTitle := C.CString(ui.title)
|
||||
defer C.free(unsafe.Pointer(cTitle))
|
||||
C.glutCreateWindow(cTitle)
|
||||
|
||||
return ui
|
||||
}
|
||||
|
||||
func Run(game ebiten.Game, screenWidth, screenHeight, screenScale int, title string) {
|
||||
ui := new(screenWidth, screenHeight, screenScale, title)
|
||||
currentUI = ui
|
||||
|
||||
graphicsDevice := opengl.NewDevice(
|
||||
screenWidth, screenHeight, screenScale)
|
||||
ui.graphicsDevice = graphicsDevice
|
||||
graphicsDevice.Init()
|
||||
ui.graphicsDevice = opengl.NewDevice(
|
||||
ui.screenWidth, ui.screenHeight, ui.screenScale)
|
||||
ui.graphicsDevice.Init()
|
||||
|
||||
game := <-ui.initializing
|
||||
game.Init(ui.graphicsDevice.TextureFactory())
|
||||
|
||||
input := make(chan ebiten.InputState)
|
||||
go func() {
|
||||
ch := ui.glutInputting
|
||||
for {
|
||||
event := <-ch
|
||||
inputState := ebiten.InputState{-1, -1}
|
||||
if event.IsActive {
|
||||
x := event.X / screenScale
|
||||
y := event.Y / screenScale
|
||||
if x < 0 {
|
||||
x = 0
|
||||
} else if screenWidth <= x {
|
||||
x = screenWidth - 1
|
||||
}
|
||||
if y < 0 {
|
||||
y = 0
|
||||
} else if screenHeight <= y {
|
||||
y = screenHeight - 1
|
||||
}
|
||||
inputState.X = x
|
||||
inputState.Y = y
|
||||
}
|
||||
input <- inputState
|
||||
}
|
||||
}()
|
||||
|
||||
go func() {
|
||||
frameTime := time.Duration(
|
||||
int64(time.Second) / int64(ebiten.FPS))
|
||||
tick := time.Tick(frameTime)
|
||||
gameContext := &GameContext{
|
||||
screenWidth: screenWidth,
|
||||
screenHeight: screenHeight,
|
||||
inputState: ebiten.InputState{-1, -1},
|
||||
}
|
||||
for {
|
||||
select {
|
||||
case gameContext.inputState = <-input:
|
||||
case <-tick:
|
||||
game.Update(gameContext)
|
||||
case ui.updating <- game.Draw:
|
||||
<-ui.updated
|
||||
}
|
||||
}
|
||||
os.Exit(0)
|
||||
}()
|
||||
ui.initialized <- game
|
||||
|
||||
// Set the callbacks
|
||||
C.setGlutFuncs()
|
||||
@ -173,20 +102,75 @@ func Run(game ebiten.Game, screenWidth, screenHeight, screenScale int, title str
|
||||
C.glutMainLoop()
|
||||
}
|
||||
|
||||
type GameContext struct {
|
||||
screenWidth int
|
||||
screenHeight int
|
||||
inputState ebiten.InputState
|
||||
func (ui *UI) ScreenWidth() int {
|
||||
return ui.screenWidth
|
||||
}
|
||||
|
||||
func (context *GameContext) ScreenWidth() int {
|
||||
return context.screenWidth
|
||||
func (ui *UI) ScreenHeight() int {
|
||||
return ui.screenHeight
|
||||
}
|
||||
|
||||
func (context *GameContext) ScreenHeight() int {
|
||||
return context.screenHeight
|
||||
func (ui *UI) Initializing() chan<- ebiten.Game {
|
||||
return ui.initializing
|
||||
}
|
||||
|
||||
func (context *GameContext) InputState() ebiten.InputState {
|
||||
return context.inputState
|
||||
func (ui *UI) Initialized() <-chan ebiten.Game {
|
||||
return ui.initialized
|
||||
}
|
||||
|
||||
func (ui *UI) Updating() chan<- ebiten.Game {
|
||||
return ui.updating
|
||||
}
|
||||
|
||||
func (ui *UI) Updated() <-chan ebiten.Game {
|
||||
return ui.updated
|
||||
}
|
||||
|
||||
func (ui *UI) Input() <-chan ebiten.InputState {
|
||||
return ui.input
|
||||
}
|
||||
|
||||
func (ui *UI) normalizePoint(x, y int) (newX, newY int) {
|
||||
x /= ui.screenScale
|
||||
y /= ui.screenScale
|
||||
if x < 0 {
|
||||
x = 0
|
||||
} else if ui.screenWidth <= x {
|
||||
x = ui.screenWidth - 1
|
||||
}
|
||||
if y < 0 {
|
||||
y = 0
|
||||
} else if ui.screenHeight <= y {
|
||||
y = ui.screenHeight - 1
|
||||
}
|
||||
return x, y
|
||||
}
|
||||
|
||||
//export display
|
||||
func display() {
|
||||
game := <-currentUI.updating
|
||||
currentUI.graphicsDevice.Update(game.Draw)
|
||||
currentUI.updated <- game
|
||||
C.glutSwapBuffers()
|
||||
}
|
||||
|
||||
//export mouse
|
||||
func mouse(button, state, x, y C.int) {
|
||||
if state != C.GLUT_DOWN {
|
||||
currentUI.input <- ebiten.InputState{-1, -1}
|
||||
return
|
||||
}
|
||||
newX, newY := currentUI.normalizePoint(int(x), int(y))
|
||||
currentUI.input <- ebiten.InputState{newX, newY}
|
||||
}
|
||||
|
||||
//export motion
|
||||
func motion(x, y C.int) {
|
||||
newX, newY := currentUI.normalizePoint(int(x), int(y))
|
||||
currentUI.input <- ebiten.InputState{newX, newY}
|
||||
}
|
||||
|
||||
//export idle
|
||||
func idle() {
|
||||
C.glutPostRedisplay()
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user