Hide members of RenderTarget (again)

This commit is contained in:
Hajime Hoshi 2014-12-14 18:34:47 +09:00
parent d0c0dea2be
commit 60aad4326e
8 changed files with 112 additions and 101 deletions

View File

@ -17,7 +17,6 @@ limitations under the License.
package ebiten
import (
"github.com/go-gl/gl"
glfw "github.com/go-gl/glfw3"
"image"
"runtime"
@ -32,6 +31,29 @@ type canvas struct {
funcsDone chan struct{}
}
func newCanvas(window *glfw.Window, width, height, scale int) (*canvas, error) {
c := &canvas{
window: window,
scale: scale,
funcs: make(chan func()),
funcsDone: make(chan struct{}),
}
c.run(width, height, scale)
// For retina displays, recalculate the scale with the framebuffer size.
windowWidth, _ := window.GetFramebufferSize()
realScale := windowWidth / width
var err error
c.use(func() {
c.graphicsContext, err = newGraphicsContext(width, height, realScale)
})
if err != nil {
return nil, err
}
return c, nil
}
func (c *canvas) draw(game Game) (err error) {
c.use(func() {
c.graphicsContext.PreUpdate()
@ -50,38 +72,20 @@ func (c *canvas) isClosed() bool {
return c.window.ShouldClose()
}
func (c *canvas) NewTextureID(img image.Image, filter Filter) (TextureID, error) {
func (c *canvas) newTextureID(img image.Image, filter int) (TextureID, error) {
var id TextureID
var err error
c.use(func() {
glFilter := 0
switch filter {
case FilterNearest:
glFilter = gl.NEAREST
case FilterLinear:
glFilter = gl.LINEAR
default:
panic("not reached")
}
id, err = newTextureID(img, glFilter)
id, err = newTextureID(img, filter)
})
return id, err
}
func (c *canvas) NewRenderTargetID(width, height int, filter Filter) (RenderTargetID, error) {
func (c *canvas) newRenderTargetID(width, height int, filter int) (RenderTargetID, error) {
var id RenderTargetID
var err error
c.use(func() {
glFilter := 0
switch filter {
case FilterNearest:
glFilter = gl.NEAREST
case FilterLinear:
glFilter = gl.LINEAR
default:
panic("not reached")
}
id, err = newRenderTargetID(width, height, glFilter)
id, err = newRenderTargetID(width, height, filter)
})
return id, err
}
@ -104,17 +108,5 @@ func (c *canvas) use(f func()) {
}
func (c *canvas) update() {
c.input.Update(c.window, c.scale)
}
func (c *canvas) IsKeyPressed(key Key) bool {
return c.input.IsKeyPressed(key)
}
func (c *canvas) IsMouseButtonPressed(button MouseButton) bool {
return c.input.IsMouseButtonPressed(button)
}
func (c *canvas) CursorPosition() (x, y int) {
return c.input.CursorPosition()
c.input.update(c.window, c.scale)
}

View File

@ -17,30 +17,37 @@ limitations under the License.
package ebiten
import (
"github.com/go-gl/gl"
"image"
)
type Game interface {
Update() error
Draw(gr GraphicsContext) error
}
func IsKeyPressed(key Key) bool {
return currentUI.canvas.input.IsKeyPressed(key)
return currentUI.canvas.input.isKeyPressed(key)
}
func CursorPosition() (x, y int) {
return currentUI.canvas.input.CursorPosition()
return currentUI.canvas.input.cursorPosition()
}
func IsMouseButtonPressed(mouseButton MouseButton) bool {
return currentUI.canvas.input.IsMouseButtonPressed(mouseButton)
return currentUI.canvas.input.isMouseButtonPressed(mouseButton)
}
func glFilter(f Filter) int {
switch f {
case FilterNearest:
return gl.NEAREST
case FilterLinear:
return gl.LINEAR
default:
panic("not reached")
}
}
func NewRenderTargetID(width, height int, filter Filter) (RenderTargetID, error) {
return currentUI.canvas.NewRenderTargetID(width, height, filter)
return currentUI.canvas.newRenderTargetID(width, height, glFilter(filter))
}
func NewTextureID(img image.Image, filter Filter) (TextureID, error) {
return currentUI.canvas.NewTextureID(img, filter)
return currentUI.canvas.newTextureID(img, glFilter(filter))
}

View File

@ -21,7 +21,7 @@ import (
"github.com/hajimehoshi/ebiten/internal/opengl"
)
func initialize(screenWidth, screenHeight, screenScale int) (*graphicsContext, error) {
func newGraphicsContext(screenWidth, screenHeight, screenScale int) (*graphicsContext, error) {
gl.Init()
gl.Enable(gl.TEXTURE_2D)
gl.Enable(gl.BLEND)
@ -33,11 +33,8 @@ func initialize(screenWidth, screenHeight, screenScale int) (*graphicsContext, e
}
// The defualt framebuffer should be 0.
c.defaultID = idsInstance.addRenderTarget(&opengl.RenderTarget{
Width: screenWidth * screenScale,
Height: screenHeight * screenScale,
FlipY: true,
})
r := opengl.NewRenderTarget(screenWidth*screenScale, screenHeight*screenScale, true)
c.defaultID = idsInstance.addRenderTarget(r)
var err error
c.screenID, err = idsInstance.createRenderTarget(screenWidth, screenHeight, gl.NEAREST)

8
ids.go
View File

@ -86,14 +86,10 @@ func (i *ids) createRenderTarget(width, height int, filter int) (RenderTargetID,
if err != nil {
return 0, err
}
framebuffer := opengl.CreateFramebuffer(texture.Native())
// The current binded framebuffer can be changed.
i.currentRenderTargetId = -1
r := &opengl.RenderTarget{
Framebuffer: framebuffer,
Width: texture.Width(),
Height: texture.Height(),
}
r := opengl.NewRenderTargetFromTexture(texture)
i.Lock()
defer i.Unlock()

View File

@ -28,15 +28,15 @@ type input struct {
cursorY int
}
func (i *input) IsKeyPressed(key Key) bool {
func (i *input) isKeyPressed(key Key) bool {
return i.keyPressed[key]
}
func (i *input) IsMouseButtonPressed(button MouseButton) bool {
func (i *input) isMouseButtonPressed(button MouseButton) bool {
return i.mouseButtonPressed[button]
}
func (i *input) CursorPosition() (x, y int) {
func (i *input) cursorPosition() (x, y int) {
return i.cursorX, i.cursorY
}
@ -48,7 +48,7 @@ var glfwKeyCodeToKey = map[glfw.Key]Key{
glfw.KeyDown: KeyDown,
}
func (i *input) Update(window *glfw.Window, scale int) {
func (i *input) update(window *glfw.Window, scale int) {
for g, u := range glfwKeyCodeToKey {
i.keyPressed[u] = window.GetKey(g) == glfw.Press
}

View File

@ -36,17 +36,46 @@ func orthoProjectionMatrix(left, right, bottom, top int) [4][4]float64 {
}
type RenderTarget struct {
Framebuffer gl.Framebuffer
Width int
Height int
FlipY bool
framebuffer gl.Framebuffer
width int
height int
flipY bool
}
func NewRenderTarget(width, height int, flipY bool) *RenderTarget {
return &RenderTarget{
width: width,
height: height,
flipY: flipY,
}
}
func NewRenderTargetFromTexture(texture *Texture) *RenderTarget {
framebuffer := createFramebuffer(texture.Native())
return &RenderTarget{
framebuffer: framebuffer,
width: texture.Width(),
height: texture.Height(),
}
}
func (r *RenderTarget) Width() int {
return r.width
}
func (r *RenderTarget) Height() int {
return r.height
}
func (r *RenderTarget) FlipY() bool {
return r.flipY
}
func (r *RenderTarget) Dispose() {
r.Framebuffer.Delete()
r.framebuffer.Delete()
}
func CreateFramebuffer(nativeTexture gl.Texture) gl.Framebuffer {
func createFramebuffer(nativeTexture gl.Texture) gl.Framebuffer {
framebuffer := gl.GenFramebuffer()
framebuffer.Bind()
@ -65,7 +94,7 @@ func CreateFramebuffer(nativeTexture gl.Texture) gl.Framebuffer {
func (r *RenderTarget) SetAsViewport() {
gl.Flush()
r.Framebuffer.Bind()
r.framebuffer.Bind()
err := gl.CheckFramebufferStatus(gl.FRAMEBUFFER)
if err != gl.FRAMEBUFFER_COMPLETE {
panic(fmt.Sprintf("glBindFramebuffer failed: %d", err))
@ -73,18 +102,18 @@ func (r *RenderTarget) SetAsViewport() {
gl.BlendFuncSeparate(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA, gl.ZERO, gl.ONE)
width := AdjustSizeForTexture(r.Width)
height := AdjustSizeForTexture(r.Height)
width := AdjustSizeForTexture(r.width)
height := AdjustSizeForTexture(r.height)
gl.Viewport(0, 0, width, height)
}
func (r *RenderTarget) ProjectionMatrix() [4][4]float64 {
width := AdjustSizeForTexture(r.Width)
height := AdjustSizeForTexture(r.Height)
width := AdjustSizeForTexture(r.width)
height := AdjustSizeForTexture(r.height)
m := orthoProjectionMatrix(0, width, 0, height)
if r.FlipY {
if r.flipY {
m[1][1] *= -1
m[1][3] += float64(r.Height) / float64(AdjustSizeForTexture(r.Height)) * 2
m[1][3] += float64(r.height) / float64(AdjustSizeForTexture(r.height)) * 2
}
return m
}

15
run.go
View File

@ -23,6 +23,11 @@ import (
"time"
)
type Game interface {
Update() error
Draw(gr GraphicsContext) error
}
var currentUI *ui
// Run runs the game.
@ -34,10 +39,10 @@ func Run(game Game, width, height, scale int, title string, fps int) error {
currentUI = nil
}()
if err := ui.Start(game, width, height, scale, title); err != nil {
if err := ui.start(game, width, height, scale, title); err != nil {
return err
}
defer ui.Terminate()
defer ui.terminate()
frameTime := time.Duration(int64(time.Second) / int64(fps))
tick := time.Tick(frameTime)
@ -45,13 +50,13 @@ func Run(game Game, width, height, scale int, title string, fps int) error {
signal.Notify(sigterm, os.Interrupt, syscall.SIGTERM)
for {
ui.DoEvents()
if ui.IsClosed() {
ui.doEvents()
if ui.isClosed() {
return nil
}
select {
default:
if err := ui.DrawGame(game); err != nil {
if err := ui.drawGame(game); err != nil {
return err
}
case <-tick:

27
ui.go
View File

@ -32,7 +32,7 @@ type ui struct {
canvas *canvas
}
func (u *ui) Start(game Game, width, height, scale int, title string) error {
func (u *ui) start(game Game, width, height, scale int, title string) error {
if !glfw.Init() {
return errors.New("glfw.Init() fails")
}
@ -42,43 +42,28 @@ func (u *ui) Start(game Game, width, height, scale int, title string) error {
return err
}
c := &canvas{
window: window,
scale: scale,
funcs: make(chan func()),
funcsDone: make(chan struct{}),
}
c.run(width, height, scale)
// For retina displays, recalculate the scale with the framebuffer size.
windowWidth, _ := window.GetFramebufferSize()
realScale := windowWidth / width
c.use(func() {
c.graphicsContext, err = initialize(width, height, realScale)
})
c, err := newCanvas(window, width, height, scale)
if err != nil {
return err
}
u.canvas = c
return nil
}
func (u *ui) DoEvents() {
func (u *ui) doEvents() {
glfw.PollEvents()
u.canvas.update()
}
func (u *ui) Terminate() {
func (u *ui) terminate() {
glfw.Terminate()
}
func (u *ui) IsClosed() bool {
func (u *ui) isClosed() bool {
return u.canvas.isClosed()
}
func (u *ui) DrawGame(game Game) error {
func (u *ui) drawGame(game Game) error {
return u.canvas.draw(game)
}