Implement ui/glfw except for inputting

This commit is contained in:
Hajime Hoshi 2014-12-06 02:26:02 +09:00
parent a76102522a
commit ca97ee6961
6 changed files with 194 additions and 23 deletions

View File

@ -4,7 +4,7 @@ import (
"github.com/hajimehoshi/ebiten/example/blocks"
"github.com/hajimehoshi/ebiten/graphics"
"github.com/hajimehoshi/ebiten/ui"
"github.com/hajimehoshi/ebiten/ui/dummy"
"github.com/hajimehoshi/ebiten/ui/glfw"
"os"
"os/signal"
"runtime"
@ -29,11 +29,11 @@ func main() {
const frameTime = time.Duration(int64(time.Second) / int64(fps))
const title = "Ebiten Demo"
u := new(dummy.UI)
u := new(glfw.UI)
canvas := u.CreateCanvas(screenWidth, screenHeight, screenScale, title)
textureFactory := new(dummy.TextureFactory)
var game Game = blocks.NewGame(NewTextures(textureFactory))
textureFactory := u.TextureFactory()
game := blocks.NewGame(NewTextures(textureFactory))
tick := time.Tick(frameTime)
sigterm := make(chan os.Signal, 1)

View File

@ -67,9 +67,7 @@ func (t *Textures) loopMain() {
if err != nil {
panic(err)
}
id, err := t.textureFactory.CreateTexture(
img,
graphics.FilterNearest)
id, err := t.textureFactory.CreateTexture(img, graphics.FilterNearest)
if err != nil {
panic(err)
}
@ -81,10 +79,7 @@ func (t *Textures) loopMain() {
name := s.name
size := s.size
go func() {
id, err := t.textureFactory.CreateRenderTarget(
size.Width,
size.Height,
graphics.FilterNearest)
id, err := t.textureFactory.CreateRenderTarget(size.Width, size.Height, graphics.FilterNearest)
if err != nil {
panic(err)
}

View File

@ -42,8 +42,7 @@ func NewContext(screenWidth, screenHeight, screenScale int) *Context {
context.defaultId = idsInstance.addRenderTarget(defaultRenderTarget)
var err error
context.screenId, err = idsInstance.createRenderTarget(
screenWidth, screenHeight, graphics.FilterNearest)
context.screenId, err = idsInstance.createRenderTarget(screenWidth, screenHeight, graphics.FilterNearest)
if err != nil {
panic("initializing the offscreen failed: " + err.Error())
}
@ -60,6 +59,7 @@ func (c *Context) Dispose() {
idsInstance.deleteRenderTarget(c.screenId)
}
// TODO: This interface is confusing: Can we change this?
func (c *Context) Update(draw func(graphics.Context)) {
c.ResetOffscreen()
c.Clear()
@ -72,12 +72,7 @@ func (c *Context) Update(draw func(graphics.Context)) {
scale := float64(c.screenScale)
geo := matrix.IdentityGeometry()
geo.Scale(scale, scale)
graphics.DrawWhole(
c.RenderTarget(c.screenId),
c.screenWidth,
c.screenHeight,
geo,
matrix.IdentityColor())
graphics.DrawWhole(c.RenderTarget(c.screenId), c.screenWidth, c.screenHeight, geo, matrix.IdentityColor())
flush()
}
@ -111,9 +106,6 @@ type textureWithContext struct {
context *Context
}
func (t *textureWithContext) Draw(
parts []graphics.TexturePart,
geo matrix.Geometry,
color matrix.Color) {
func (t *textureWithContext) Draw(parts []graphics.TexturePart, geo matrix.Geometry, color matrix.Color) {
idsInstance.drawTexture(t.context.currentId, t.id, parts, geo, color)
}

91
ui/glfw/canvas.go Normal file
View File

@ -0,0 +1,91 @@
package glfw
import (
glfw "github.com/go-gl/glfw3"
"github.com/hajimehoshi/ebiten/graphics"
"github.com/hajimehoshi/ebiten/graphics/opengl"
"github.com/hajimehoshi/ebiten/ui"
"image"
"runtime"
)
type Canvas struct {
window *glfw.Window
context *opengl.Context
funcs chan func()
funcsDone chan struct{}
}
func NewCanvas(width, height, scale int, title string) *Canvas {
window, err := glfw.CreateWindow(width*scale, height*scale, title, nil, nil)
if err != nil {
panic(err)
}
canvas := &Canvas{
window: window,
funcs: make(chan func()),
funcsDone: make(chan struct{}),
}
// For retina displays, recalculate the scale with the framebuffer size.
windowWidth, windowHeight := window.GetFramebufferSize()
realScale := windowWidth / width
_ = windowHeight
canvas.run()
canvas.use(func() {
canvas.context = opengl.NewContext(width, height, realScale)
})
return canvas
}
func (c *Canvas) Draw(f func(graphics.Context)) {
c.use(func() {
c.context.Update(f)
c.window.SwapBuffers()
})
}
func (c *Canvas) IsClosed() bool {
return c.window.ShouldClose()
}
func (c *Canvas) InputState() ui.InputState {
return &InputState{newKeys(), -1, -1}
}
func (c *Canvas) CreateTexture(img image.Image, filter graphics.Filter) (graphics.TextureId, error) {
var id graphics.TextureId
var err error
c.use(func() {
id, err = opengl.CreateTexture(img, filter)
})
return id, err
}
func (c *Canvas) CreateRenderTarget(width, height int, filter graphics.Filter) (graphics.RenderTargetId, error) {
var id graphics.RenderTargetId
var err error
c.use(func() {
id, err = opengl.CreateRenderTarget(width, height, filter)
})
return id, err
}
func (c *Canvas) run() {
go func() {
runtime.LockOSThread()
c.window.MakeContextCurrent()
glfw.SwapInterval(1)
for {
f := <-c.funcs
f()
c.funcsDone <- struct{}{}
}
}()
}
func (c *Canvas) use(f func()) {
c.funcs <- f
<-c.funcsDone
}

50
ui/glfw/inputstate.go Normal file
View File

@ -0,0 +1,50 @@
package glfw
import (
"github.com/hajimehoshi/ebiten/ui"
)
type Keys map[ui.Key]struct{}
func newKeys() Keys {
return Keys(map[ui.Key]struct{}{})
}
func (k Keys) clone() Keys {
n := newKeys()
for key, value := range k {
n[key] = value
}
return n
}
func (k Keys) add(key ui.Key) {
k[key] = struct{}{}
}
func (k Keys) remove(key ui.Key) {
delete(k, key)
}
func (k Keys) Includes(key ui.Key) bool {
_, ok := k[key]
return ok
}
type InputState struct {
pressedKeys Keys
mouseX int
mouseY int
}
func (i *InputState) PressedKeys() ui.Keys {
return i.pressedKeys
}
func (i *InputState) MouseX() int {
return i.mouseX
}
func (i *InputState) MouseY() int {
return i.mouseY
}

43
ui/glfw/ui.go Normal file
View File

@ -0,0 +1,43 @@
package glfw
import (
glfw "github.com/go-gl/glfw3"
"github.com/hajimehoshi/ebiten/graphics"
"github.com/hajimehoshi/ebiten/ui"
"log"
)
func init() {
glfw.SetErrorCallback(func (err glfw.ErrorCode, desc string) {
log.Fatalf("%v: %v\n", err, desc)
})
}
type UI struct {
canvas *Canvas
}
func (u *UI) CreateCanvas(width, height, scale int, title string) ui.Canvas {
if !glfw.Init() {
panic("glfw.Init() fails")
}
glfw.WindowHint(glfw.Resizable, glfw.False)
//glfw.WindowHint(glfw.ClientAPI, glfw.OpenGLESAPI)
u.canvas = NewCanvas(width, height, scale, title)
return u.canvas
}
func (u *UI) Start() {
}
func (u *UI) DoEvents() {
glfw.PollEvents()
}
func (u *UI) Terminate() {
glfw.Terminate()
}
func (u *UI) TextureFactory() graphics.TextureFactory {
return u.canvas
}