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)
}
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{}
locationX, locationY := 0, 0
for _, c := range str {
@ -54,12 +54,11 @@ func (d *debugPrintState) drawText(gr ebiten.GraphicsContext, str string, x, y i
})
locationX += assets.TextImageCharWidth
}
geo := ebiten.GeometryMatrixI()
geo.Translate(float64(x)+1, float64(y))
clr := ebiten.ColorMatrixI()
// TODO: Is this color OK?
clr.Scale(color.RGBA{0x80, 0x80, 0x80, 0xff})
gr.Texture(d.textTexture).Draw(parts, geo, clr)
geom := ebiten.GeometryMatrixI()
geom.Translate(float64(x)+1, float64(y))
clrm := ebiten.ColorMatrixI()
clrm.Scale(clr)
gr.Texture(d.textTexture).Draw(parts, geom, clrm)
}
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)
}
}
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
}
from := textures.GetRenderTarget("scene_manager_transition_from")
context.SetOffscreen(from)
context.PushOffscreen(from)
context.Clear()
s.current.Draw(context, textures)
context.PopOffscreen()
to := textures.GetRenderTarget("scene_manager_transition_to")
context.SetOffscreen(to)
context.PushOffscreen(to)
context.Clear()
s.next.Draw(context, textures)
context.PopOffscreen()
context.ResetOffscreen()
color := ebiten.ColorMatrixI()
ebiten.DrawWhole(
context.RenderTarget(from),

View File

@ -1,6 +1,7 @@
package main
import (
"fmt"
"github.com/hajimehoshi/ebiten"
"github.com/hajimehoshi/ebiten/ebitenutil"
"github.com/hajimehoshi/ebiten/runner"
@ -35,12 +36,14 @@ func (g *Game) Draw(gr ebiten.GraphicsContext) error {
if err != nil {
return err
}
gr.SetOffscreen(g.canvasRenderTarget)
gr.PushOffscreen(g.canvasRenderTarget)
gr.Fill(0xff, 0xff, 0xff)
gr.PopOffscreen()
}
gr.ResetOffscreen()
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
}

View File

@ -50,8 +50,8 @@ type GraphicsContext interface {
Fill(r, g, b uint8)
Texture(id TextureID) Drawer
RenderTarget(id RenderTargetID) Drawer
ResetOffscreen()
SetOffscreen(id RenderTargetID)
PushOffscreen(id RenderTargetID)
PopOffscreen()
}
// 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 {
window *glfw.Window
scale int
graphicsContext *opengl.GraphicsContext
input input
funcs chan func()
@ -86,7 +87,7 @@ func (c *canvas) use(f func()) {
}
func (c *canvas) update() {
c.input.update(c.window)
c.input.update(c.window, c.scale)
}
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
}
func (c *graphicsContext) ResetOffscreen() {
func (c *graphicsContext) PopOffscreen() {
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.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,
}
func (i *input) update(window *glfw.Window) {
func (i *input) update(window *glfw.Window, scale int) {
for g, u := range glfwKeyCodeToKey {
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
}
x, y := window.GetCursorPosition()
i.cursorX = int(math.Floor(x))
i.cursorY = int(math.Floor(y))
i.cursorX = int(math.Floor(x)) / scale
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{
window: window,
scale: scale,
funcs: make(chan func()),
funcsDone: make(chan struct{}),
}

View File

@ -33,27 +33,29 @@ func Initialize(screenWidth, screenHeight, screenScale int) (*GraphicsContext, e
}
// The defualt framebuffer should be 0.
c.defaultId = idsInstance.addRenderTarget(&renderTarget{
c.defaultID = idsInstance.addRenderTarget(&renderTarget{
width: screenWidth * screenScale,
height: screenHeight * screenScale,
flipY: true,
})
var err error
c.screenId, err = idsInstance.createRenderTarget(screenWidth, screenHeight, ebiten.FilterNearest)
c.screenID, err = idsInstance.createRenderTarget(screenWidth, screenHeight, ebiten.FilterNearest)
if err != nil {
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()
return c, nil
}
type GraphicsContext struct {
screenId ebiten.RenderTargetID
defaultId ebiten.RenderTargetID
currentId ebiten.RenderTargetID
screenID ebiten.RenderTargetID
defaultID ebiten.RenderTargetID
currentIDs []ebiten.RenderTargetID
screenWidth int
screenHeight int
screenScale int
@ -63,7 +65,7 @@ var _ ebiten.GraphicsContext = new(GraphicsContext)
func (c *GraphicsContext) dispose() {
// NOTE: Now this method is not used anywhere.
idsInstance.deleteRenderTarget(c.screenId)
idsInstance.deleteRenderTarget(c.screenID)
}
func (c *GraphicsContext) Clear() {
@ -71,7 +73,7 @@ func (c *GraphicsContext) Clear() {
}
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 {
@ -82,27 +84,28 @@ func (c *GraphicsContext) RenderTarget(id ebiten.RenderTargetID) ebiten.Drawer {
return &textureWithContext{idsInstance.toTexture(id), c}
}
func (c *GraphicsContext) ResetOffscreen() {
c.currentId = c.screenId
func (c *GraphicsContext) PushOffscreen(renderTargetID ebiten.RenderTargetID) {
c.currentIDs = append(c.currentIDs, renderTargetID)
}
func (c *GraphicsContext) SetOffscreen(renderTargetId ebiten.RenderTargetID) {
c.currentId = renderTargetId
func (c *GraphicsContext) PopOffscreen() {
c.currentIDs = c.currentIDs[:len(c.currentIDs)-1]
}
func (c *GraphicsContext) PreUpdate() {
c.ResetOffscreen()
c.currentIDs = []ebiten.RenderTargetID{c.defaultID}
c.PushOffscreen(c.screenID)
c.Clear()
}
func (c *GraphicsContext) PostUpdate() {
c.SetOffscreen(c.defaultId)
c.PopOffscreen()
c.Clear()
scale := float64(c.screenScale)
geo := ebiten.GeometryMatrixI()
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()
}
@ -113,5 +116,6 @@ type textureWithContext struct {
}
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)
}