Add GraphicsContext.PushOffscreen / PopOffscreen (#21)

This commit is contained in:
Hajime Hoshi 2014-12-11 03:50:35 +09:00
parent f388a48d52
commit 54509e42cf
9 changed files with 50 additions and 40 deletions

View File

@ -34,7 +34,7 @@ func DebugPrint(ga ebiten.GameContext, gr ebiten.GraphicsContext, str string) {
defaultDebugPrintState.DebugPrint(ga, gr, str) defaultDebugPrintState.DebugPrint(ga, gr, str)
} }
func (d *debugPrintState) drawText(gr ebiten.GraphicsContext, str string, x, y int) { func (d *debugPrintState) drawText(gr ebiten.GraphicsContext, str string, x, y int, clr color.Color) {
parts := []ebiten.TexturePart{} parts := []ebiten.TexturePart{}
locationX, locationY := 0, 0 locationX, locationY := 0, 0
for _, c := range str { for _, c := range str {
@ -54,12 +54,11 @@ func (d *debugPrintState) drawText(gr ebiten.GraphicsContext, str string, x, y i
}) })
locationX += assets.TextImageCharWidth locationX += assets.TextImageCharWidth
} }
geo := ebiten.GeometryMatrixI() geom := ebiten.GeometryMatrixI()
geo.Translate(float64(x)+1, float64(y)) geom.Translate(float64(x)+1, float64(y))
clr := ebiten.ColorMatrixI() clrm := ebiten.ColorMatrixI()
// TODO: Is this color OK? clrm.Scale(clr)
clr.Scale(color.RGBA{0x80, 0x80, 0x80, 0xff}) gr.Texture(d.textTexture).Draw(parts, geom, clrm)
gr.Texture(d.textTexture).Draw(parts, geo, clr)
} }
func (d *debugPrintState) DebugPrint(ga ebiten.GameContext, gr ebiten.GraphicsContext, str string) { func (d *debugPrintState) DebugPrint(ga ebiten.GameContext, gr ebiten.GraphicsContext, str string) {
@ -81,5 +80,6 @@ func (d *debugPrintState) DebugPrint(ga ebiten.GameContext, gr ebiten.GraphicsCo
panic(err) panic(err)
} }
} }
d.drawText(gr, str, 0, d.y) d.drawText(gr, str, 1, d.y+1, &color.RGBA{0x00, 0x00, 0x00, 0x80})
d.drawText(gr, str, 0, d.y, &color.RGBA{0xff, 0xff, 0xff, 0xff})
} }

View File

@ -66,16 +66,17 @@ func (s *SceneManager) Draw(context ebiten.GraphicsContext, textures *Textures)
return return
} }
from := textures.GetRenderTarget("scene_manager_transition_from") from := textures.GetRenderTarget("scene_manager_transition_from")
context.SetOffscreen(from) context.PushOffscreen(from)
context.Clear() context.Clear()
s.current.Draw(context, textures) s.current.Draw(context, textures)
context.PopOffscreen()
to := textures.GetRenderTarget("scene_manager_transition_to") to := textures.GetRenderTarget("scene_manager_transition_to")
context.SetOffscreen(to) context.PushOffscreen(to)
context.Clear() context.Clear()
s.next.Draw(context, textures) s.next.Draw(context, textures)
context.PopOffscreen()
context.ResetOffscreen()
color := ebiten.ColorMatrixI() color := ebiten.ColorMatrixI()
ebiten.DrawWhole( ebiten.DrawWhole(
context.RenderTarget(from), context.RenderTarget(from),

View File

@ -1,6 +1,7 @@
package main package main
import ( import (
"fmt"
"github.com/hajimehoshi/ebiten" "github.com/hajimehoshi/ebiten"
"github.com/hajimehoshi/ebiten/ebitenutil" "github.com/hajimehoshi/ebiten/ebitenutil"
"github.com/hajimehoshi/ebiten/runner" "github.com/hajimehoshi/ebiten/runner"
@ -35,12 +36,14 @@ func (g *Game) Draw(gr ebiten.GraphicsContext) error {
if err != nil { if err != nil {
return err return err
} }
gr.SetOffscreen(g.canvasRenderTarget) gr.PushOffscreen(g.canvasRenderTarget)
gr.Fill(0xff, 0xff, 0xff) gr.Fill(0xff, 0xff, 0xff)
gr.PopOffscreen()
} }
gr.ResetOffscreen()
ebiten.DrawWhole(gr.RenderTarget(g.canvasRenderTarget), screenWidth, screenHeight, ebiten.GeometryMatrixI(), ebiten.ColorMatrixI()) ebiten.DrawWhole(gr.RenderTarget(g.canvasRenderTarget), screenWidth, screenHeight, ebiten.GeometryMatrixI(), ebiten.ColorMatrixI())
ebitenutil.DebugPrint(g.gameContext, gr, "Hello\nWorld!")
mx, my := g.gameContext.CursorPosition()
ebitenutil.DebugPrint(g.gameContext, gr, fmt.Sprintf("(%d, %d)", mx, my))
return nil return nil
} }

View File

@ -50,8 +50,8 @@ type GraphicsContext interface {
Fill(r, g, b uint8) Fill(r, g, b uint8)
Texture(id TextureID) Drawer Texture(id TextureID) Drawer
RenderTarget(id RenderTargetID) Drawer RenderTarget(id RenderTargetID) Drawer
ResetOffscreen() PushOffscreen(id RenderTargetID)
SetOffscreen(id RenderTargetID) PopOffscreen()
} }
// Filter represents the type of filter to be used when a texture or a render // Filter represents the type of filter to be used when a texture or a render

View File

@ -26,6 +26,7 @@ import (
type canvas struct { type canvas struct {
window *glfw.Window window *glfw.Window
scale int
graphicsContext *opengl.GraphicsContext graphicsContext *opengl.GraphicsContext
input input input input
funcs chan func() funcs chan func()
@ -86,7 +87,7 @@ func (c *canvas) use(f func()) {
} }
func (c *canvas) update() { func (c *canvas) update() {
c.input.update(c.window) c.input.update(c.window, c.scale)
} }
func (c *canvas) IsKeyPressed(key ebiten.Key) bool { func (c *canvas) IsKeyPressed(key ebiten.Key) bool {

View File

@ -58,15 +58,15 @@ func (c *graphicsContext) RenderTarget(id ebiten.RenderTargetID) (d ebiten.Drawe
return return
} }
func (c *graphicsContext) ResetOffscreen() { func (c *graphicsContext) PopOffscreen() {
c.canvas.use(func() { c.canvas.use(func() {
c.canvas.graphicsContext.ResetOffscreen() c.canvas.graphicsContext.PopOffscreen()
}) })
} }
func (c *graphicsContext) SetOffscreen(id ebiten.RenderTargetID) { func (c *graphicsContext) PushOffscreen(id ebiten.RenderTargetID) {
c.canvas.use(func() { c.canvas.use(func() {
c.canvas.graphicsContext.SetOffscreen(id) c.canvas.graphicsContext.PushOffscreen(id)
}) })
} }

View File

@ -49,7 +49,7 @@ var glfwKeyCodeToKey = map[glfw.Key]ebiten.Key{
glfw.KeyDown: ebiten.KeyDown, glfw.KeyDown: ebiten.KeyDown,
} }
func (i *input) update(window *glfw.Window) { func (i *input) update(window *glfw.Window, scale int) {
for g, u := range glfwKeyCodeToKey { for g, u := range glfwKeyCodeToKey {
i.keyPressed[u] = window.GetKey(g) == glfw.Press i.keyPressed[u] = window.GetKey(g) == glfw.Press
} }
@ -57,6 +57,6 @@ func (i *input) update(window *glfw.Window) {
i.mouseButtonPressed[b] = window.GetMouseButton(glfw.MouseButton(b)) == glfw.Press i.mouseButtonPressed[b] = window.GetMouseButton(glfw.MouseButton(b)) == glfw.Press
} }
x, y := window.GetCursorPosition() x, y := window.GetCursorPosition()
i.cursorX = int(math.Floor(x)) i.cursorX = int(math.Floor(x)) / scale
i.cursorY = int(math.Floor(y)) i.cursorY = int(math.Floor(y)) / scale
} }

View File

@ -46,6 +46,7 @@ func (u *UI) Start(game ebiten.Game, width, height, scale int, title string) err
c := &canvas{ c := &canvas{
window: window, window: window,
scale: scale,
funcs: make(chan func()), funcs: make(chan func()),
funcsDone: make(chan struct{}), funcsDone: make(chan struct{}),
} }

View File

@ -33,27 +33,29 @@ func Initialize(screenWidth, screenHeight, screenScale int) (*GraphicsContext, e
} }
// The defualt framebuffer should be 0. // The defualt framebuffer should be 0.
c.defaultId = idsInstance.addRenderTarget(&renderTarget{ c.defaultID = idsInstance.addRenderTarget(&renderTarget{
width: screenWidth * screenScale, width: screenWidth * screenScale,
height: screenHeight * screenScale, height: screenHeight * screenScale,
flipY: true, flipY: true,
}) })
var err error var err error
c.screenId, err = idsInstance.createRenderTarget(screenWidth, screenHeight, ebiten.FilterNearest) c.screenID, err = idsInstance.createRenderTarget(screenWidth, screenHeight, ebiten.FilterNearest)
if err != nil { if err != nil {
return nil, err return nil, err
} }
c.ResetOffscreen()
// TODO: This is a special stack only for clearing. Can we change this?
c.currentIDs = []ebiten.RenderTargetID{c.screenID}
c.Clear() c.Clear()
return c, nil return c, nil
} }
type GraphicsContext struct { type GraphicsContext struct {
screenId ebiten.RenderTargetID screenID ebiten.RenderTargetID
defaultId ebiten.RenderTargetID defaultID ebiten.RenderTargetID
currentId ebiten.RenderTargetID currentIDs []ebiten.RenderTargetID
screenWidth int screenWidth int
screenHeight int screenHeight int
screenScale int screenScale int
@ -63,7 +65,7 @@ var _ ebiten.GraphicsContext = new(GraphicsContext)
func (c *GraphicsContext) dispose() { func (c *GraphicsContext) dispose() {
// NOTE: Now this method is not used anywhere. // NOTE: Now this method is not used anywhere.
idsInstance.deleteRenderTarget(c.screenId) idsInstance.deleteRenderTarget(c.screenID)
} }
func (c *GraphicsContext) Clear() { func (c *GraphicsContext) Clear() {
@ -71,7 +73,7 @@ func (c *GraphicsContext) Clear() {
} }
func (c *GraphicsContext) Fill(r, g, b uint8) { func (c *GraphicsContext) Fill(r, g, b uint8) {
idsInstance.fillRenderTarget(c.currentId, r, g, b) idsInstance.fillRenderTarget(c.currentIDs[len(c.currentIDs)-1], r, g, b)
} }
func (c *GraphicsContext) Texture(id ebiten.TextureID) ebiten.Drawer { func (c *GraphicsContext) Texture(id ebiten.TextureID) ebiten.Drawer {
@ -82,27 +84,28 @@ func (c *GraphicsContext) RenderTarget(id ebiten.RenderTargetID) ebiten.Drawer {
return &textureWithContext{idsInstance.toTexture(id), c} return &textureWithContext{idsInstance.toTexture(id), c}
} }
func (c *GraphicsContext) ResetOffscreen() { func (c *GraphicsContext) PushOffscreen(renderTargetID ebiten.RenderTargetID) {
c.currentId = c.screenId c.currentIDs = append(c.currentIDs, renderTargetID)
} }
func (c *GraphicsContext) SetOffscreen(renderTargetId ebiten.RenderTargetID) { func (c *GraphicsContext) PopOffscreen() {
c.currentId = renderTargetId c.currentIDs = c.currentIDs[:len(c.currentIDs)-1]
} }
func (c *GraphicsContext) PreUpdate() { func (c *GraphicsContext) PreUpdate() {
c.ResetOffscreen() c.currentIDs = []ebiten.RenderTargetID{c.defaultID}
c.PushOffscreen(c.screenID)
c.Clear() c.Clear()
} }
func (c *GraphicsContext) PostUpdate() { func (c *GraphicsContext) PostUpdate() {
c.SetOffscreen(c.defaultId) c.PopOffscreen()
c.Clear() c.Clear()
scale := float64(c.screenScale) scale := float64(c.screenScale)
geo := ebiten.GeometryMatrixI() geo := ebiten.GeometryMatrixI()
geo.Scale(scale, scale) geo.Scale(scale, scale)
ebiten.DrawWhole(c.RenderTarget(c.screenId), c.screenWidth, c.screenHeight, geo, ebiten.ColorMatrixI()) ebiten.DrawWhole(c.RenderTarget(c.screenID), c.screenWidth, c.screenHeight, geo, ebiten.ColorMatrixI())
gl.Flush() gl.Flush()
} }
@ -113,5 +116,6 @@ type textureWithContext struct {
} }
func (t *textureWithContext) Draw(parts []ebiten.TexturePart, geo ebiten.GeometryMatrix, color ebiten.ColorMatrix) { func (t *textureWithContext) Draw(parts []ebiten.TexturePart, geo ebiten.GeometryMatrix, color ebiten.ColorMatrix) {
idsInstance.drawTexture(t.context.currentId, t.id, parts, geo, color) currentID := t.context.currentIDs[len(t.context.currentIDs)-1]
idsInstance.drawTexture(currentID, t.id, parts, geo, color)
} }