mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2025-01-12 12:08:58 +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/example/game/sprites"
|
||||||
"github.com/hajimehoshi/go-ebiten/ui"
|
"github.com/hajimehoshi/go-ebiten/ui"
|
||||||
"github.com/hajimehoshi/go-ebiten/ui/cocoa"
|
"github.com/hajimehoshi/go-ebiten/ui/cocoa"
|
||||||
_ "github.com/hajimehoshi/go-ebiten/ui/glut"
|
"github.com/hajimehoshi/go-ebiten/ui/glut"
|
||||||
"os"
|
"os"
|
||||||
"runtime"
|
"runtime"
|
||||||
)
|
)
|
||||||
@ -22,6 +22,10 @@ func main() {
|
|||||||
if 2 <= len(os.Args) {
|
if 2 <= len(os.Args) {
|
||||||
gameName = os.Args[1]
|
gameName = os.Args[1]
|
||||||
}
|
}
|
||||||
|
uiName := "cocoa"
|
||||||
|
if 3 <= len(os.Args) {
|
||||||
|
uiName = os.Args[2]
|
||||||
|
}
|
||||||
|
|
||||||
var game ebiten.Game
|
var game ebiten.Game
|
||||||
switch gameName {
|
switch gameName {
|
||||||
@ -33,15 +37,26 @@ func main() {
|
|||||||
game = monochrome.New()
|
game = monochrome.New()
|
||||||
case "rects":
|
case "rects":
|
||||||
game = rects.New()
|
game = rects.New()
|
||||||
|
default:
|
||||||
|
fallthrough
|
||||||
case "rotating":
|
case "rotating":
|
||||||
game = rotating.New()
|
game = rotating.New()
|
||||||
case "sprites":
|
case "sprites":
|
||||||
game = sprites.New()
|
game = sprites.New()
|
||||||
default:
|
|
||||||
game = rotating.New()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const screenWidth = 256
|
||||||
|
const screenHeight = 240
|
||||||
const screenScale = 2
|
const screenScale = 2
|
||||||
cocoaUI := cocoa.New(256, 240, screenScale, "Ebiten Demo")
|
const title = "Ebiten Demo"
|
||||||
ui.Run(cocoaUI, game)
|
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)
|
||||||
}
|
}
|
||||||
|
222
ui/glut/glut.go
222
ui/glut/glut.go
@ -21,10 +21,8 @@ package glut
|
|||||||
import "C"
|
import "C"
|
||||||
import (
|
import (
|
||||||
"github.com/hajimehoshi/go-ebiten"
|
"github.com/hajimehoshi/go-ebiten"
|
||||||
"github.com/hajimehoshi/go-ebiten/graphics"
|
|
||||||
"github.com/hajimehoshi/go-ebiten/graphics/opengl"
|
"github.com/hajimehoshi/go-ebiten/graphics/opengl"
|
||||||
"os"
|
"os"
|
||||||
"time"
|
|
||||||
"unsafe"
|
"unsafe"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -34,60 +32,44 @@ type glutInputEvent struct {
|
|||||||
Y int
|
Y int
|
||||||
}
|
}
|
||||||
|
|
||||||
type GlutUI struct {
|
type UI struct {
|
||||||
|
screenWidth int
|
||||||
|
screenHeight int
|
||||||
screenScale 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
|
graphicsDevice *opengl.Device
|
||||||
updating chan func(graphics.Context)
|
glutInputting chan glutInputEvent
|
||||||
updated chan bool
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var currentUI *GlutUI
|
var currentUI *UI
|
||||||
|
|
||||||
//export display
|
func New(screenWidth, screenHeight, screenScale int, title string) *UI {
|
||||||
func display() {
|
if currentUI != nil {
|
||||||
draw := <-currentUI.updating
|
panic("UI can't be duplicated.")
|
||||||
currentUI.graphicsDevice.Update(draw)
|
|
||||||
currentUI.updated <- true
|
|
||||||
C.glutSwapBuffers()
|
|
||||||
}
|
|
||||||
|
|
||||||
//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
|
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 motion
|
func (ui *UI) MainLoop() {
|
||||||
func motion(x, y C.int) {
|
cargs := []*C.char{C.CString(os.Args[0])}
|
||||||
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))
|
|
||||||
}
|
|
||||||
defer func() {
|
defer func() {
|
||||||
for _, carg := range cargs {
|
for _, carg := range cargs {
|
||||||
C.free(unsafe.Pointer(carg))
|
C.free(unsafe.Pointer(carg))
|
||||||
@ -99,73 +81,20 @@ func new(screenWidth, screenHeight, screenScale int, title string) *GlutUI {
|
|||||||
C.glutInit(&cargc, &cargs[0])
|
C.glutInit(&cargc, &cargs[0])
|
||||||
C.glutInitDisplayMode(C.GLUT_RGBA)
|
C.glutInitDisplayMode(C.GLUT_RGBA)
|
||||||
C.glutInitWindowSize(
|
C.glutInitWindowSize(
|
||||||
C.int(screenWidth*screenScale),
|
C.int(ui.screenWidth*ui.screenScale),
|
||||||
C.int(screenHeight*screenScale))
|
C.int(ui.screenHeight*ui.screenScale))
|
||||||
|
|
||||||
cTitle := C.CString(title)
|
cTitle := C.CString(ui.title)
|
||||||
defer C.free(unsafe.Pointer(cTitle))
|
defer C.free(unsafe.Pointer(cTitle))
|
||||||
C.glutCreateWindow(cTitle)
|
C.glutCreateWindow(cTitle)
|
||||||
|
|
||||||
return ui
|
ui.graphicsDevice = opengl.NewDevice(
|
||||||
}
|
ui.screenWidth, ui.screenHeight, ui.screenScale)
|
||||||
|
ui.graphicsDevice.Init()
|
||||||
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()
|
|
||||||
|
|
||||||
|
game := <-ui.initializing
|
||||||
game.Init(ui.graphicsDevice.TextureFactory())
|
game.Init(ui.graphicsDevice.TextureFactory())
|
||||||
|
ui.initialized <- game
|
||||||
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)
|
|
||||||
}()
|
|
||||||
|
|
||||||
// Set the callbacks
|
// Set the callbacks
|
||||||
C.setGlutFuncs()
|
C.setGlutFuncs()
|
||||||
@ -173,20 +102,75 @@ func Run(game ebiten.Game, screenWidth, screenHeight, screenScale int, title str
|
|||||||
C.glutMainLoop()
|
C.glutMainLoop()
|
||||||
}
|
}
|
||||||
|
|
||||||
type GameContext struct {
|
func (ui *UI) ScreenWidth() int {
|
||||||
screenWidth int
|
return ui.screenWidth
|
||||||
screenHeight int
|
|
||||||
inputState ebiten.InputState
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (context *GameContext) ScreenWidth() int {
|
func (ui *UI) ScreenHeight() int {
|
||||||
return context.screenWidth
|
return ui.screenHeight
|
||||||
}
|
}
|
||||||
|
|
||||||
func (context *GameContext) ScreenHeight() int {
|
func (ui *UI) Initializing() chan<- ebiten.Game {
|
||||||
return context.screenHeight
|
return ui.initializing
|
||||||
}
|
}
|
||||||
|
|
||||||
func (context *GameContext) InputState() ebiten.InputState {
|
func (ui *UI) Initialized() <-chan ebiten.Game {
|
||||||
return context.inputState
|
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