mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-11-10 04:57:26 +01:00
Separate Device and Canvas
This commit is contained in:
parent
7e246015ff
commit
c18b1cc9bd
@ -10,34 +10,52 @@ import (
|
|||||||
"github.com/hajimehoshi/go-ebiten/graphics/matrix"
|
"github.com/hajimehoshi/go-ebiten/graphics/matrix"
|
||||||
"github.com/hajimehoshi/go-ebiten/graphics/opengl/offscreen"
|
"github.com/hajimehoshi/go-ebiten/graphics/opengl/offscreen"
|
||||||
"github.com/hajimehoshi/go-ebiten/graphics/opengl/texture"
|
"github.com/hajimehoshi/go-ebiten/graphics/opengl/texture"
|
||||||
"image"
|
|
||||||
"math"
|
"math"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Canvas struct {
|
type Canvas struct {
|
||||||
screenId graphics.RenderTargetId
|
screenId graphics.RenderTargetId
|
||||||
ids *ids
|
ids *ids
|
||||||
offscreen *offscreen.Offscreen
|
offscreen *offscreen.Offscreen
|
||||||
|
screenScale int
|
||||||
}
|
}
|
||||||
|
|
||||||
func newCanvas(screenWidth, screenHeight, screenScale int) *Canvas {
|
func newCanvas(ids *ids, screenWidth, screenHeight, screenScale int) *Canvas {
|
||||||
canvas := &Canvas{
|
canvas := &Canvas{
|
||||||
ids: newIds(),
|
ids: ids,
|
||||||
offscreen: offscreen.New(screenWidth, screenHeight, screenScale),
|
offscreen: offscreen.New(screenWidth, screenHeight, screenScale),
|
||||||
|
screenScale: screenScale,
|
||||||
}
|
}
|
||||||
|
|
||||||
var err error
|
var err error
|
||||||
canvas.screenId, err = canvas.createRenderTarget(
|
canvas.screenId, err = ids.CreateRenderTarget(
|
||||||
screenWidth, screenHeight, texture.FilterNearest)
|
screenWidth, screenHeight, texture.FilterNearest)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic("initializing the offscreen failed: " + err.Error())
|
panic("initializing the offscreen failed: " + err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
canvas.Init()
|
|
||||||
|
|
||||||
return canvas
|
return canvas
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (canvas *Canvas) update(draw func(graphics.Canvas)) {
|
||||||
|
canvas.init()
|
||||||
|
canvas.ResetOffscreen()
|
||||||
|
canvas.Clear()
|
||||||
|
|
||||||
|
draw(canvas)
|
||||||
|
|
||||||
|
canvas.flush()
|
||||||
|
canvas.setMainFramebufferOffscreen()
|
||||||
|
canvas.Clear()
|
||||||
|
|
||||||
|
scale := float64(canvas.screenScale)
|
||||||
|
geometryMatrix := matrix.IdentityGeometry()
|
||||||
|
geometryMatrix.Scale(scale, scale)
|
||||||
|
canvas.DrawRenderTarget(canvas.screenId,
|
||||||
|
geometryMatrix, matrix.IdentityColor())
|
||||||
|
canvas.flush()
|
||||||
|
}
|
||||||
|
|
||||||
func (canvas *Canvas) Clear() {
|
func (canvas *Canvas) Clear() {
|
||||||
canvas.Fill(0, 0, 0)
|
canvas.Fill(0, 0, 0)
|
||||||
}
|
}
|
||||||
@ -78,8 +96,8 @@ func (canvas *Canvas) DrawRenderTargetParts(
|
|||||||
canvas.DrawTextureParts(canvas.ids.ToTexture(id), parts, geometryMatrix, colorMatrix)
|
canvas.DrawTextureParts(canvas.ids.ToTexture(id), parts, geometryMatrix, colorMatrix)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Init initializes the canvas. The initial state is saved for each GL canvas.
|
// init initializes the canvas. The initial state is saved for each GL canvas.
|
||||||
func (canvas *Canvas) Init() {
|
func (canvas *Canvas) init() {
|
||||||
C.glEnable(C.GL_TEXTURE_2D)
|
C.glEnable(C.GL_TEXTURE_2D)
|
||||||
C.glEnable(C.GL_BLEND)
|
C.glEnable(C.GL_BLEND)
|
||||||
}
|
}
|
||||||
@ -100,22 +118,3 @@ func (canvas *Canvas) setMainFramebufferOffscreen() {
|
|||||||
func (canvas *Canvas) flush() {
|
func (canvas *Canvas) flush() {
|
||||||
C.glFlush()
|
C.glFlush()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (canvas *Canvas) createRenderTarget(width, height int, filter texture.Filter) (
|
|
||||||
graphics.RenderTargetId, error) {
|
|
||||||
renderTargetId, err := canvas.ids.CreateRenderTarget(width, height, filter)
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
return renderTargetId, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (canvas *Canvas) CreateRenderTarget(width, height int) (
|
|
||||||
graphics.RenderTargetId, error) {
|
|
||||||
return canvas.createRenderTarget(width, height, texture.FilterLinear)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (canvas *Canvas) CreateTextureFromImage(img image.Image) (
|
|
||||||
graphics.TextureId, error) {
|
|
||||||
return canvas.ids.CreateTextureFromImage(img)
|
|
||||||
}
|
|
||||||
|
@ -2,47 +2,37 @@ package opengl
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/hajimehoshi/go-ebiten/graphics"
|
"github.com/hajimehoshi/go-ebiten/graphics"
|
||||||
"github.com/hajimehoshi/go-ebiten/graphics/matrix"
|
"github.com/hajimehoshi/go-ebiten/graphics/opengl/texture"
|
||||||
"image"
|
"image"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Device struct {
|
type Device struct {
|
||||||
canvas *Canvas
|
ids *ids
|
||||||
screenScale int
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewDevice(screenWidth, screenHeight, screenScale int) *Device {
|
func NewDevice(screenWidth, screenHeight, screenScale int) *Device {
|
||||||
canvas := newCanvas(screenWidth, screenHeight, screenScale)
|
device := &Device{
|
||||||
return &Device{
|
ids: newIds(),
|
||||||
canvas: canvas,
|
|
||||||
screenScale: screenScale,
|
|
||||||
}
|
}
|
||||||
|
return device
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Device) Update(draw func(graphics.Canvas)) {
|
func (d *Device) CreateCanvas(screenWidth, screenHeight, screenScale int) *Canvas {
|
||||||
canvas := d.canvas
|
return newCanvas(d.ids, screenWidth, screenHeight, screenScale)
|
||||||
canvas.Init()
|
}
|
||||||
canvas.ResetOffscreen()
|
|
||||||
canvas.Clear()
|
|
||||||
|
|
||||||
draw(canvas)
|
func (d *Device) Update(canvas *Canvas, draw func(graphics.Canvas)) {
|
||||||
|
canvas.update(draw)
|
||||||
canvas.flush()
|
|
||||||
canvas.setMainFramebufferOffscreen()
|
|
||||||
canvas.Clear()
|
|
||||||
|
|
||||||
scale := float64(d.screenScale)
|
|
||||||
geometryMatrix := matrix.IdentityGeometry()
|
|
||||||
geometryMatrix.Scale(scale, scale)
|
|
||||||
canvas.DrawRenderTarget(canvas.screenId,
|
|
||||||
geometryMatrix, matrix.IdentityColor())
|
|
||||||
canvas.flush()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Device) CreateRenderTarget(width, height int) (graphics.RenderTargetId, error) {
|
func (d *Device) CreateRenderTarget(width, height int) (graphics.RenderTargetId, error) {
|
||||||
return d.canvas.CreateRenderTarget(width, height)
|
renderTargetId, err := d.ids.CreateRenderTarget(width, height, texture.FilterLinear)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
return renderTargetId, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Device) CreateTexture(img image.Image) (graphics.TextureId, error) {
|
func (d *Device) CreateTexture(img image.Image) (graphics.TextureId, error) {
|
||||||
return d.canvas.CreateTextureFromImage(img)
|
return d.ids.CreateTextureFromImage(img)
|
||||||
}
|
}
|
||||||
|
@ -20,7 +20,7 @@ type UI struct {
|
|||||||
screenWidth int
|
screenWidth int
|
||||||
screenHeight int
|
screenHeight int
|
||||||
screenScale int
|
screenScale int
|
||||||
window *window
|
window *Window
|
||||||
initialEventSent bool
|
initialEventSent bool
|
||||||
textureFactory *textureFactory
|
textureFactory *textureFactory
|
||||||
graphicsDevice *opengl.Device
|
graphicsDevice *opengl.Device
|
||||||
@ -50,11 +50,10 @@ func New(screenWidth, screenHeight, screenScale int, title string) *UI {
|
|||||||
u.screenHeight,
|
u.screenHeight,
|
||||||
u.screenScale)
|
u.screenScale)
|
||||||
})
|
})
|
||||||
|
u.window = u.CreateWindow(
|
||||||
u.window = u.textureFactory.createWindow(
|
u.screenWidth,
|
||||||
u,
|
u.screenHeight,
|
||||||
u.screenWidth*u.screenScale,
|
u.screenScale,
|
||||||
u.screenHeight*u.screenScale,
|
|
||||||
title)
|
title)
|
||||||
|
|
||||||
currentUI = u
|
currentUI = u
|
||||||
@ -62,6 +61,10 @@ func New(screenWidth, screenHeight, screenScale int, title string) *UI {
|
|||||||
return u
|
return u
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (u *UI) CreateWindow(width, height, scale int, title string) *Window {
|
||||||
|
return u.textureFactory.createWindow(u, width, height, scale, title)
|
||||||
|
}
|
||||||
|
|
||||||
func (u *UI) PollEvents() {
|
func (u *UI) PollEvents() {
|
||||||
C.PollEvents()
|
C.PollEvents()
|
||||||
if !u.initialEventSent {
|
if !u.initialEventSent {
|
||||||
|
@ -50,6 +50,6 @@ func (t *textureFactory) useContext(f func()) {
|
|||||||
<-t.funcsDone
|
<-t.funcsDone
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *textureFactory) createWindow(ui *UI, width, height int, title string) *window {
|
func (t *textureFactory) createWindow(ui *UI, width, height, scale int, title string) *Window {
|
||||||
return runWindow(ui, width, height, title, t.sharedContext)
|
return runWindow(ui, width, height, scale, title, t.sharedContext)
|
||||||
}
|
}
|
||||||
|
@ -12,19 +12,21 @@ package cocoa
|
|||||||
import "C"
|
import "C"
|
||||||
import (
|
import (
|
||||||
"github.com/hajimehoshi/go-ebiten/graphics"
|
"github.com/hajimehoshi/go-ebiten/graphics"
|
||||||
|
"github.com/hajimehoshi/go-ebiten/graphics/opengl"
|
||||||
"runtime"
|
"runtime"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
)
|
)
|
||||||
|
|
||||||
type window struct {
|
type Window struct {
|
||||||
ui *UI
|
ui *UI
|
||||||
native unsafe.Pointer
|
native unsafe.Pointer
|
||||||
|
canvas *opengl.Canvas
|
||||||
funcs chan func()
|
funcs chan func()
|
||||||
funcsDone chan struct{}
|
funcsDone chan struct{}
|
||||||
}
|
}
|
||||||
|
|
||||||
func runWindow(ui *UI, width, height int, title string, sharedContext unsafe.Pointer) *window {
|
func runWindow(ui *UI, width, height, scale int, title string, sharedContext unsafe.Pointer) *Window {
|
||||||
w := &window{
|
w := &Window{
|
||||||
ui: ui,
|
ui: ui,
|
||||||
funcs: make(chan func()),
|
funcs: make(chan func()),
|
||||||
funcsDone: make(chan struct{}),
|
funcsDone: make(chan struct{}),
|
||||||
@ -37,18 +39,21 @@ func runWindow(ui *UI, width, height int, title string, sharedContext unsafe.Poi
|
|||||||
go func() {
|
go func() {
|
||||||
runtime.LockOSThread()
|
runtime.LockOSThread()
|
||||||
glContext := C.CreateGLContext(sharedContext)
|
glContext := C.CreateGLContext(sharedContext)
|
||||||
w.native = C.CreateWindow(C.size_t(width),
|
w.native = C.CreateWindow(C.size_t(width*scale),
|
||||||
C.size_t(height),
|
C.size_t(height*scale),
|
||||||
cTitle,
|
cTitle,
|
||||||
glContext)
|
glContext)
|
||||||
close(ch)
|
close(ch)
|
||||||
w.loop()
|
w.loop()
|
||||||
}()
|
}()
|
||||||
<-ch
|
<-ch
|
||||||
|
w.useContext(func() {
|
||||||
|
w.canvas = ui.graphicsDevice.CreateCanvas(width, height, scale)
|
||||||
|
})
|
||||||
return w
|
return w
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *window) loop() {
|
func (w *Window) loop() {
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case f := <-w.funcs:
|
case f := <-w.funcs:
|
||||||
@ -61,13 +66,13 @@ func (w *window) loop() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *window) Draw(f func(graphics.Canvas)) {
|
func (w *Window) Draw(f func(graphics.Canvas)) {
|
||||||
w.useContext(func() {
|
w.useContext(func() {
|
||||||
w.ui.graphicsDevice.Update(f)
|
w.ui.graphicsDevice.Update(w.canvas, f)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *window) useContext(f func()) {
|
func (w *Window) useContext(f func()) {
|
||||||
w.funcs <- f
|
w.funcs <- f
|
||||||
<-w.funcsDone
|
<-w.funcsDone
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user