mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-12-25 03:08:54 +01:00
Remove GraphicsContext; Add rendering methods to RenderTarget (#26)
This commit is contained in:
parent
d4cd858eeb
commit
01e0d42451
@ -24,17 +24,17 @@ import (
|
|||||||
|
|
||||||
type debugPrintState struct {
|
type debugPrintState struct {
|
||||||
textTexture *ebiten.Texture
|
textTexture *ebiten.Texture
|
||||||
debugPrintRenderTarget *ebiten.RenderTarget
|
debugPrintRenderTarget ebiten.RenderTarget
|
||||||
y int
|
y int
|
||||||
}
|
}
|
||||||
|
|
||||||
var defaultDebugPrintState = new(debugPrintState)
|
var defaultDebugPrintState = new(debugPrintState)
|
||||||
|
|
||||||
func DebugPrint(gr ebiten.GraphicsContext, str string) {
|
func DebugPrint(r ebiten.RenderTarget, str string) {
|
||||||
defaultDebugPrintState.DebugPrint(gr, str)
|
defaultDebugPrintState.DebugPrint(r, str)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *debugPrintState) drawText(gr ebiten.GraphicsContext, str string, x, y int, clr color.Color) {
|
func (d *debugPrintState) drawText(r ebiten.RenderTarget, 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 {
|
||||||
@ -57,10 +57,10 @@ func (d *debugPrintState) drawText(gr ebiten.GraphicsContext, str string, x, y i
|
|||||||
geom.Concat(ebiten.TranslateGeometry(float64(x)+1, float64(y)))
|
geom.Concat(ebiten.TranslateGeometry(float64(x)+1, float64(y)))
|
||||||
clrm := ebiten.ColorMatrixI()
|
clrm := ebiten.ColorMatrixI()
|
||||||
clrm.Concat(ebiten.ScaleColor(clr))
|
clrm.Concat(ebiten.ScaleColor(clr))
|
||||||
gr.DrawTexture(d.textTexture, parts, geom, clrm)
|
r.DrawTexture(d.textTexture, parts, geom, clrm)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *debugPrintState) DebugPrint(gr ebiten.GraphicsContext, str string) {
|
func (d *debugPrintState) DebugPrint(r ebiten.RenderTarget, str string) {
|
||||||
if d.textTexture == nil {
|
if d.textTexture == nil {
|
||||||
img, err := assets.TextImage()
|
img, err := assets.TextImage()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -79,6 +79,6 @@ func (d *debugPrintState) DebugPrint(gr ebiten.GraphicsContext, str string) {
|
|||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
d.drawText(gr, str, 1, d.y+1, &color.RGBA{0x00, 0x00, 0x00, 0x80})
|
d.drawText(r, str, 1, d.y+1, &color.RGBA{0x00, 0x00, 0x00, 0x80})
|
||||||
d.drawText(gr, str, 0, d.y, &color.RGBA{0xff, 0xff, 0xff, 0xff})
|
d.drawText(r, str, 0, d.y, &color.RGBA{0xff, 0xff, 0xff, 0xff})
|
||||||
}
|
}
|
||||||
|
@ -31,11 +31,11 @@ const (
|
|||||||
|
|
||||||
type Game struct {
|
type Game struct {
|
||||||
count int
|
count int
|
||||||
tmpRenderTarget *ebiten.RenderTarget
|
tmpRenderTarget ebiten.RenderTarget
|
||||||
ebitenTexture *ebiten.Texture
|
ebitenTexture *ebiten.Texture
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *Game) Update(gr ebiten.GraphicsContext) error {
|
func (g *Game) Update(r ebiten.RenderTarget) error {
|
||||||
g.count++
|
g.count++
|
||||||
g.count %= 600
|
g.count %= 600
|
||||||
diff := float64(g.count) * 0.2
|
diff := float64(g.count) * 0.2
|
||||||
@ -45,21 +45,26 @@ func (g *Game) Update(gr ebiten.GraphicsContext) error {
|
|||||||
case 240 < g.count:
|
case 240 < g.count:
|
||||||
diff = float64(480-g.count) * 0.2
|
diff = float64(480-g.count) * 0.2
|
||||||
}
|
}
|
||||||
|
_ = diff
|
||||||
|
|
||||||
gr.PushRenderTarget(g.tmpRenderTarget)
|
if err := g.tmpRenderTarget.Clear(); err != nil {
|
||||||
gr.Clear()
|
return err
|
||||||
|
}
|
||||||
for i := 0; i < 10; i++ {
|
for i := 0; i < 10; i++ {
|
||||||
geo := ebiten.TranslateGeometry(15+float64(i)*(diff), 20)
|
geo := ebiten.TranslateGeometry(15+float64(i)*(diff), 20)
|
||||||
clr := ebiten.ScaleColor(color.RGBA{0xff, 0xff, 0xff, 0x80})
|
clr := ebiten.ScaleColor(color.RGBA{0xff, 0xff, 0xff, 0x80})
|
||||||
ebiten.DrawWholeTexture(gr, g.ebitenTexture, geo, clr)
|
if err := ebiten.DrawWholeTexture(g.tmpRenderTarget, g.ebitenTexture, geo, clr); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
gr.PopRenderTarget()
|
|
||||||
|
|
||||||
gr.Fill(color.RGBA{0x00, 0x00, 0x80, 0xff})
|
r.Fill(color.RGBA{0x00, 0x00, 0x80, 0xff})
|
||||||
for i := 0; i < 10; i++ {
|
for i := 0; i < 10; i++ {
|
||||||
geo := ebiten.TranslateGeometry(0, float64(i)*(diff))
|
geo := ebiten.TranslateGeometry(0, float64(i)*(diff))
|
||||||
clr := ebiten.ColorMatrixI()
|
clr := ebiten.ColorMatrixI()
|
||||||
ebiten.DrawWholeTexture(gr, g.tmpRenderTarget.Texture(), geo, clr)
|
if err := ebiten.DrawWholeTexture(r, g.tmpRenderTarget.Texture(), geo, clr); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -112,11 +112,11 @@ func (f *Field) flushLine(j int) bool {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *Field) Draw(context ebiten.GraphicsContext, textures *Textures, geo ebiten.GeometryMatrix) {
|
func (f *Field) Draw(r ebiten.RenderTarget, textures *Textures, geo ebiten.GeometryMatrix) {
|
||||||
blocks := make([][]BlockType, len(f.blocks))
|
blocks := make([][]BlockType, len(f.blocks))
|
||||||
for i, blockCol := range f.blocks {
|
for i, blockCol := range f.blocks {
|
||||||
blocks[i] = make([]BlockType, len(blockCol))
|
blocks[i] = make([]BlockType, len(blockCol))
|
||||||
copy(blocks[i], blockCol[:])
|
copy(blocks[i], blockCol[:])
|
||||||
}
|
}
|
||||||
drawBlocks(context, textures, blocks, geo)
|
drawBlocks(r, textures, blocks, geo)
|
||||||
}
|
}
|
||||||
|
@ -32,7 +32,7 @@ func textWidth(str string) int {
|
|||||||
return charWidth * len(str)
|
return charWidth * len(str)
|
||||||
}
|
}
|
||||||
|
|
||||||
func drawText(context ebiten.GraphicsContext, textures *Textures, str string, ox, oy, scale int, clr color.Color) {
|
func drawText(r ebiten.RenderTarget, textures *Textures, str string, ox, oy, scale int, clr color.Color) {
|
||||||
fontTextureId := textures.GetTexture("font")
|
fontTextureId := textures.GetTexture("font")
|
||||||
parts := []ebiten.TexturePart{}
|
parts := []ebiten.TexturePart{}
|
||||||
|
|
||||||
@ -56,10 +56,10 @@ func drawText(context ebiten.GraphicsContext, textures *Textures, str string, ox
|
|||||||
geoMat := ebiten.ScaleGeometry(float64(scale), float64(scale))
|
geoMat := ebiten.ScaleGeometry(float64(scale), float64(scale))
|
||||||
geoMat.Concat(ebiten.TranslateGeometry(float64(ox), float64(oy)))
|
geoMat.Concat(ebiten.TranslateGeometry(float64(ox), float64(oy)))
|
||||||
clrMat := ebiten.ScaleColor(clr)
|
clrMat := ebiten.ScaleColor(clr)
|
||||||
context.DrawTexture(fontTextureId, parts, geoMat, clrMat)
|
r.DrawTexture(fontTextureId, parts, geoMat, clrMat)
|
||||||
}
|
}
|
||||||
|
|
||||||
func drawTextWithShadow(context ebiten.GraphicsContext, textures *Textures, str string, x, y, scale int, clr color.Color) {
|
func drawTextWithShadow(r ebiten.RenderTarget, textures *Textures, str string, x, y, scale int, clr color.Color) {
|
||||||
drawText(context, textures, str, x+1, y+1, scale, color.RGBA{0, 0, 0, 0x80})
|
drawText(r, textures, str, x+1, y+1, scale, color.RGBA{0, 0, 0, 0x80})
|
||||||
drawText(context, textures, str, x, y, scale, clr)
|
drawText(r, textures, str, x, y, scale, clr)
|
||||||
}
|
}
|
||||||
|
@ -70,7 +70,7 @@ func (game *Game) isInitialized() bool {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
func (game *Game) Update(g ebiten.GraphicsContext) error {
|
func (game *Game) Update(r ebiten.RenderTarget) error {
|
||||||
game.once.Do(func() {
|
game.once.Do(func() {
|
||||||
game.textures = NewTextures()
|
game.textures = NewTextures()
|
||||||
for name, path := range texturePaths {
|
for name, path := range texturePaths {
|
||||||
@ -88,6 +88,6 @@ func (game *Game) Update(g ebiten.GraphicsContext) error {
|
|||||||
SceneManager: game.sceneManager,
|
SceneManager: game.sceneManager,
|
||||||
Input: game.input,
|
Input: game.input,
|
||||||
})
|
})
|
||||||
game.sceneManager.Draw(g, game.textures)
|
game.sceneManager.Draw(r, game.textures)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -109,21 +109,21 @@ func (s *GameScene) Update(state *GameState) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *GameScene) Draw(context ebiten.GraphicsContext, textures *Textures) {
|
func (s *GameScene) Draw(r ebiten.RenderTarget, textures *Textures) {
|
||||||
context.Fill(color.White)
|
r.Fill(color.White)
|
||||||
|
|
||||||
field := textures.GetTexture("empty")
|
field := textures.GetTexture("empty")
|
||||||
w, h := field.Size()
|
w, h := field.Size()
|
||||||
geoMat := ebiten.ScaleGeometry(float64(fieldWidth)/float64(w), float64(fieldHeight)/float64(h))
|
geoMat := ebiten.ScaleGeometry(float64(fieldWidth)/float64(w), float64(fieldHeight)/float64(h))
|
||||||
geoMat.Concat(ebiten.TranslateGeometry(20, 20)) // TODO: magic number?
|
geoMat.Concat(ebiten.TranslateGeometry(20, 20)) // TODO: magic number?
|
||||||
colorMat := ebiten.ScaleColor(color.RGBA{0, 0, 0, 0x80})
|
colorMat := ebiten.ScaleColor(color.RGBA{0, 0, 0, 0x80})
|
||||||
ebiten.DrawWholeTexture(context, field, geoMat, colorMat)
|
ebiten.DrawWholeTexture(r, field, geoMat, colorMat)
|
||||||
|
|
||||||
geoMat = ebiten.GeometryMatrixI()
|
geoMat = ebiten.GeometryMatrixI()
|
||||||
geoMat.Concat(ebiten.TranslateGeometry(20, 20))
|
geoMat.Concat(ebiten.TranslateGeometry(20, 20))
|
||||||
s.field.Draw(context, textures, geoMat)
|
s.field.Draw(r, textures, geoMat)
|
||||||
|
|
||||||
if s.currentPiece != nil {
|
if s.currentPiece != nil {
|
||||||
s.currentPiece.Draw(context, textures, 20, 20, s.currentPieceX, s.currentPieceY, s.currentPieceAngle)
|
s.currentPiece.Draw(r, textures, 20, 20, s.currentPieceX, s.currentPieceY, s.currentPieceAngle)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -138,7 +138,7 @@ const blockHeight = 10
|
|||||||
const fieldBlockNumX = 10
|
const fieldBlockNumX = 10
|
||||||
const fieldBlockNumY = 20
|
const fieldBlockNumY = 20
|
||||||
|
|
||||||
func drawBlocks(context ebiten.GraphicsContext, textures *Textures, blocks [][]BlockType, geo ebiten.GeometryMatrix) {
|
func drawBlocks(r ebiten.RenderTarget, textures *Textures, blocks [][]BlockType, geo ebiten.GeometryMatrix) {
|
||||||
parts := []ebiten.TexturePart{}
|
parts := []ebiten.TexturePart{}
|
||||||
for i, blockCol := range blocks {
|
for i, blockCol := range blocks {
|
||||||
for j, block := range blockCol {
|
for j, block := range blockCol {
|
||||||
@ -153,7 +153,7 @@ func drawBlocks(context ebiten.GraphicsContext, textures *Textures, blocks [][]B
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
blocksTexture := textures.GetTexture("blocks")
|
blocksTexture := textures.GetTexture("blocks")
|
||||||
context.DrawTexture(blocksTexture, parts, geo, ebiten.ColorMatrixI())
|
r.DrawTexture(blocksTexture, parts, geo, ebiten.ColorMatrixI())
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Piece) InitialPosition() (int, int) {
|
func (p *Piece) InitialPosition() (int, int) {
|
||||||
@ -213,7 +213,7 @@ func (p *Piece) AbsorbInto(field *Field, x, y int, angle Angle) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Piece) Draw(context ebiten.GraphicsContext, textures *Textures, fieldX, fieldY int, pieceX, pieceY int, angle Angle) {
|
func (p *Piece) Draw(r ebiten.RenderTarget, textures *Textures, fieldX, fieldY int, pieceX, pieceY int, angle Angle) {
|
||||||
size := len(p.blocks)
|
size := len(p.blocks)
|
||||||
blocks := make([][]BlockType, size)
|
blocks := make([][]BlockType, size)
|
||||||
for i := range p.blocks {
|
for i := range p.blocks {
|
||||||
@ -230,5 +230,5 @@ func (p *Piece) Draw(context ebiten.GraphicsContext, textures *Textures, fieldX,
|
|||||||
y := fieldY + pieceY*blockHeight
|
y := fieldY + pieceY*blockHeight
|
||||||
geoMat.Concat(ebiten.TranslateGeometry(float64(x), float64(y)))
|
geoMat.Concat(ebiten.TranslateGeometry(float64(x), float64(y)))
|
||||||
|
|
||||||
drawBlocks(context, textures, blocks, geoMat)
|
drawBlocks(r, textures, blocks, geoMat)
|
||||||
}
|
}
|
||||||
|
@ -29,7 +29,7 @@ func init() {
|
|||||||
|
|
||||||
type Scene interface {
|
type Scene interface {
|
||||||
Update(state *GameState)
|
Update(state *GameState)
|
||||||
Draw(context ebiten.GraphicsContext, textures *Textures)
|
Draw(r ebiten.RenderTarget, textures *Textures)
|
||||||
}
|
}
|
||||||
|
|
||||||
const transitionMaxCount = 20
|
const transitionMaxCount = 20
|
||||||
@ -60,29 +60,25 @@ func (s *SceneManager) Update(state *GameState) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *SceneManager) Draw(context ebiten.GraphicsContext, textures *Textures) {
|
func (s *SceneManager) Draw(r ebiten.RenderTarget, textures *Textures) {
|
||||||
if s.transitionCount == -1 {
|
if s.transitionCount == -1 {
|
||||||
s.current.Draw(context, textures)
|
s.current.Draw(r, textures)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
from := textures.GetRenderTarget("scene_manager_transition_from")
|
from := textures.GetRenderTarget("scene_manager_transition_from")
|
||||||
context.PushRenderTarget(from)
|
from.Clear()
|
||||||
context.Clear()
|
s.current.Draw(from, textures)
|
||||||
s.current.Draw(context, textures)
|
|
||||||
context.PopRenderTarget()
|
|
||||||
|
|
||||||
to := textures.GetRenderTarget("scene_manager_transition_to")
|
to := textures.GetRenderTarget("scene_manager_transition_to")
|
||||||
context.PushRenderTarget(to)
|
to.Clear()
|
||||||
context.Clear()
|
s.next.Draw(to, textures)
|
||||||
s.next.Draw(context, textures)
|
|
||||||
context.PopRenderTarget()
|
|
||||||
|
|
||||||
color := ebiten.ColorMatrixI()
|
color := ebiten.ColorMatrixI()
|
||||||
ebiten.DrawWholeTexture(context, from.Texture(), ebiten.GeometryMatrixI(), color)
|
ebiten.DrawWholeTexture(r, from.Texture(), ebiten.GeometryMatrixI(), color)
|
||||||
|
|
||||||
alpha := float64(s.transitionCount) / float64(transitionMaxCount)
|
alpha := float64(s.transitionCount) / float64(transitionMaxCount)
|
||||||
color.Elements[3][3] = alpha
|
color.Elements[3][3] = alpha
|
||||||
ebiten.DrawWholeTexture(context, to.Texture(), ebiten.GeometryMatrixI(), color)
|
ebiten.DrawWholeTexture(r, to.Texture(), ebiten.GeometryMatrixI(), color)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *SceneManager) GoTo(scene Scene) {
|
func (s *SceneManager) GoTo(scene Scene) {
|
||||||
|
@ -38,7 +38,7 @@ type Textures struct {
|
|||||||
texturePaths chan namePath
|
texturePaths chan namePath
|
||||||
renderTargetSizes chan nameSize
|
renderTargetSizes chan nameSize
|
||||||
textures map[string]*ebiten.Texture
|
textures map[string]*ebiten.Texture
|
||||||
renderTargets map[string]*ebiten.RenderTarget
|
renderTargets map[string]ebiten.RenderTarget
|
||||||
sync.RWMutex
|
sync.RWMutex
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -47,7 +47,7 @@ func NewTextures() *Textures {
|
|||||||
texturePaths: make(chan namePath),
|
texturePaths: make(chan namePath),
|
||||||
renderTargetSizes: make(chan nameSize),
|
renderTargetSizes: make(chan nameSize),
|
||||||
textures: map[string]*ebiten.Texture{},
|
textures: map[string]*ebiten.Texture{},
|
||||||
renderTargets: map[string]*ebiten.RenderTarget{},
|
renderTargets: map[string]ebiten.RenderTarget{},
|
||||||
}
|
}
|
||||||
go func() {
|
go func() {
|
||||||
for {
|
for {
|
||||||
@ -129,7 +129,7 @@ func (t *Textures) GetTexture(name string) *ebiten.Texture {
|
|||||||
return t.textures[name]
|
return t.textures[name]
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *Textures) GetRenderTarget(name string) *ebiten.RenderTarget {
|
func (t *Textures) GetRenderTarget(name string) ebiten.RenderTarget {
|
||||||
t.RLock()
|
t.RLock()
|
||||||
defer t.RUnlock()
|
defer t.RUnlock()
|
||||||
return t.renderTargets[name]
|
return t.renderTargets[name]
|
||||||
|
@ -40,17 +40,17 @@ func (s *TitleScene) Update(state *GameState) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *TitleScene) Draw(context ebiten.GraphicsContext, textures *Textures) {
|
func (s *TitleScene) Draw(r ebiten.RenderTarget, textures *Textures) {
|
||||||
drawTitleBackground(context, textures, s.count)
|
drawTitleBackground(r, textures, s.count)
|
||||||
drawLogo(context, textures, "BLOCKS")
|
drawLogo(r, textures, "BLOCKS")
|
||||||
|
|
||||||
message := "PRESS SPACE TO START"
|
message := "PRESS SPACE TO START"
|
||||||
x := (ScreenWidth - textWidth(message)) / 2
|
x := (ScreenWidth - textWidth(message)) / 2
|
||||||
y := ScreenHeight - 48
|
y := ScreenHeight - 48
|
||||||
drawTextWithShadow(context, textures, message, x, y, 1, color.RGBA{0x80, 0, 0, 0xff})
|
drawTextWithShadow(r, textures, message, x, y, 1, color.RGBA{0x80, 0, 0, 0xff})
|
||||||
}
|
}
|
||||||
|
|
||||||
func drawTitleBackground(context ebiten.GraphicsContext, textures *Textures, c int) {
|
func drawTitleBackground(r ebiten.RenderTarget, textures *Textures, c int) {
|
||||||
const textureWidth = 32
|
const textureWidth = 32
|
||||||
const textureHeight = 32
|
const textureHeight = 32
|
||||||
|
|
||||||
@ -70,13 +70,13 @@ func drawTitleBackground(context ebiten.GraphicsContext, textures *Textures, c i
|
|||||||
geo := ebiten.GeometryMatrixI()
|
geo := ebiten.GeometryMatrixI()
|
||||||
geo.Concat(ebiten.TranslateGeometry(float64(dx), float64(dy)))
|
geo.Concat(ebiten.TranslateGeometry(float64(dx), float64(dy)))
|
||||||
clr := ebiten.ColorMatrixI()
|
clr := ebiten.ColorMatrixI()
|
||||||
context.DrawTexture(backgroundTexture, parts, geo, clr)
|
r.DrawTexture(backgroundTexture, parts, geo, clr)
|
||||||
}
|
}
|
||||||
|
|
||||||
func drawLogo(context ebiten.GraphicsContext, textures *Textures, str string) {
|
func drawLogo(r ebiten.RenderTarget, textures *Textures, str string) {
|
||||||
scale := 4
|
scale := 4
|
||||||
textWidth := textWidth(str) * scale
|
textWidth := textWidth(str) * scale
|
||||||
x := (ScreenWidth - textWidth) / 2
|
x := (ScreenWidth - textWidth) / 2
|
||||||
y := 32
|
y := 32
|
||||||
drawTextWithShadow(context, textures, str, x, y, scale, color.RGBA{0x00, 0x00, 0x80, 0xff})
|
drawTextWithShadow(r, textures, str, x, y, scale, color.RGBA{0x00, 0x00, 0x80, 0xff})
|
||||||
}
|
}
|
||||||
|
@ -36,7 +36,7 @@ type Game struct {
|
|||||||
gophersTexture *ebiten.Texture
|
gophersTexture *ebiten.Texture
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *Game) Update(gr ebiten.GraphicsContext) error {
|
func (g *Game) Update(r ebiten.RenderTarget) error {
|
||||||
g.count++
|
g.count++
|
||||||
if ebiten.IsKeyPressed(ebiten.KeyLeft) {
|
if ebiten.IsKeyPressed(ebiten.KeyLeft) {
|
||||||
g.horizontalCount--
|
g.horizontalCount--
|
||||||
@ -60,7 +60,7 @@ func (g *Game) Update(gr ebiten.GraphicsContext) error {
|
|||||||
geo.Concat(ebiten.TranslateGeometry(screenWidth/2, screenHeight/2))
|
geo.Concat(ebiten.TranslateGeometry(screenWidth/2, screenHeight/2))
|
||||||
//clr := ebiten.RotateHue(float64(g.count%180) * 2 * math.Pi / 180)
|
//clr := ebiten.RotateHue(float64(g.count%180) * 2 * math.Pi / 180)
|
||||||
clr := ebiten.ColorMatrixI()
|
clr := ebiten.ColorMatrixI()
|
||||||
ebiten.DrawWholeTexture(gr, g.gophersTexture, geo, clr)
|
ebiten.DrawWholeTexture(r, g.gophersTexture, geo, clr)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -32,17 +32,15 @@ const mosaicRatio = 16
|
|||||||
|
|
||||||
type Game struct {
|
type Game struct {
|
||||||
gophersTexture *ebiten.Texture
|
gophersTexture *ebiten.Texture
|
||||||
gophersRenderTarget *ebiten.RenderTarget
|
gophersRenderTarget ebiten.RenderTarget
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *Game) Update(gr ebiten.GraphicsContext) error {
|
func (g *Game) Update(r ebiten.RenderTarget) error {
|
||||||
gr.PushRenderTarget(g.gophersRenderTarget)
|
|
||||||
geo := ebiten.ScaleGeometry(1.0/mosaicRatio, 1.0/mosaicRatio)
|
geo := ebiten.ScaleGeometry(1.0/mosaicRatio, 1.0/mosaicRatio)
|
||||||
ebiten.DrawWholeTexture(gr, g.gophersTexture, geo, ebiten.ColorMatrixI())
|
ebiten.DrawWholeTexture(g.gophersRenderTarget, g.gophersTexture, geo, ebiten.ColorMatrixI())
|
||||||
gr.PopRenderTarget()
|
|
||||||
|
|
||||||
geo = ebiten.ScaleGeometry(mosaicRatio/2.0, mosaicRatio/2.0)
|
geo = ebiten.ScaleGeometry(mosaicRatio/2.0, mosaicRatio/2.0)
|
||||||
ebiten.DrawWholeTexture(gr, g.gophersRenderTarget.Texture(), geo, ebiten.ColorMatrixI())
|
ebiten.DrawWholeTexture(r, g.gophersRenderTarget.Texture(), geo, ebiten.ColorMatrixI())
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -33,39 +33,33 @@ const (
|
|||||||
type Game struct {
|
type Game struct {
|
||||||
inited bool
|
inited bool
|
||||||
count int
|
count int
|
||||||
brushRenderTarget *ebiten.RenderTarget
|
brushRenderTarget ebiten.RenderTarget
|
||||||
canvasRenderTarget *ebiten.RenderTarget
|
canvasRenderTarget ebiten.RenderTarget
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *Game) Update(gr ebiten.GraphicsContext) error {
|
func (g *Game) Update(r ebiten.RenderTarget) error {
|
||||||
if ebiten.IsMouseButtonPressed(ebiten.MouseButtonLeft) {
|
if ebiten.IsMouseButtonPressed(ebiten.MouseButtonLeft) {
|
||||||
g.count++
|
g.count++
|
||||||
}
|
}
|
||||||
if !g.inited {
|
if !g.inited {
|
||||||
gr.PushRenderTarget(g.brushRenderTarget)
|
g.brushRenderTarget.Fill(color.White)
|
||||||
gr.Fill(color.White)
|
g.canvasRenderTarget.Fill(color.White)
|
||||||
gr.PopRenderTarget()
|
|
||||||
gr.PushRenderTarget(g.canvasRenderTarget)
|
|
||||||
gr.Fill(color.White)
|
|
||||||
gr.PopRenderTarget()
|
|
||||||
g.inited = true
|
g.inited = true
|
||||||
}
|
}
|
||||||
|
|
||||||
mx, my := ebiten.CursorPosition()
|
mx, my := ebiten.CursorPosition()
|
||||||
|
|
||||||
if ebiten.IsMouseButtonPressed(ebiten.MouseButtonLeft) {
|
if ebiten.IsMouseButtonPressed(ebiten.MouseButtonLeft) {
|
||||||
gr.PushRenderTarget(g.canvasRenderTarget)
|
|
||||||
geo := ebiten.TranslateGeometry(float64(mx), float64(my))
|
geo := ebiten.TranslateGeometry(float64(mx), float64(my))
|
||||||
clr := ebiten.ScaleColor(color.RGBA{0xff, 0x40, 0x40, 0xff})
|
clr := ebiten.ScaleColor(color.RGBA{0xff, 0x40, 0x40, 0xff})
|
||||||
theta := 2.0 * math.Pi * float64(g.count%60) / 60.0
|
theta := 2.0 * math.Pi * float64(g.count%60) / 60.0
|
||||||
clr.Concat(ebiten.RotateHue(theta))
|
clr.Concat(ebiten.RotateHue(theta))
|
||||||
ebiten.DrawWholeTexture(gr, g.brushRenderTarget.Texture(), geo, clr)
|
ebiten.DrawWholeTexture(g.canvasRenderTarget, g.brushRenderTarget.Texture(), geo, clr)
|
||||||
gr.PopRenderTarget()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ebiten.DrawWholeTexture(gr, g.canvasRenderTarget.Texture(), ebiten.GeometryMatrixI(), ebiten.ColorMatrixI())
|
ebiten.DrawWholeTexture(r, g.canvasRenderTarget.Texture(), ebiten.GeometryMatrixI(), ebiten.ColorMatrixI())
|
||||||
|
|
||||||
ebitenutil.DebugPrint(gr, fmt.Sprintf("(%d, %d)", mx, my))
|
ebitenutil.DebugPrint(r, fmt.Sprintf("(%d, %d)", mx, my))
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -32,7 +32,7 @@ type Game struct {
|
|||||||
gophersTexture *ebiten.Texture
|
gophersTexture *ebiten.Texture
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *Game) Update(gr ebiten.GraphicsContext) error {
|
func (g *Game) Update(r ebiten.RenderTarget) error {
|
||||||
parts := []ebiten.TexturePart{}
|
parts := []ebiten.TexturePart{}
|
||||||
w, h := g.gophersTexture.Size()
|
w, h := g.gophersTexture.Size()
|
||||||
for i := 0; i < h; i++ {
|
for i := 0; i < h; i++ {
|
||||||
@ -48,7 +48,7 @@ func (g *Game) Update(gr ebiten.GraphicsContext) error {
|
|||||||
geo := ebiten.TranslateGeometry(-maxWidth/2, -float64(h)/2)
|
geo := ebiten.TranslateGeometry(-maxWidth/2, -float64(h)/2)
|
||||||
geo.Concat(ebiten.ScaleGeometry(0.4, 0.4))
|
geo.Concat(ebiten.ScaleGeometry(0.4, 0.4))
|
||||||
geo.Concat(ebiten.TranslateGeometry(screenWidth/2, screenHeight/2))
|
geo.Concat(ebiten.TranslateGeometry(screenWidth/2, screenHeight/2))
|
||||||
gr.DrawTexture(g.gophersTexture, parts, geo, ebiten.ColorMatrixI())
|
r.DrawTexture(g.gophersTexture, parts, geo, ebiten.ColorMatrixI())
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -48,7 +48,7 @@ func glFilter(f Filter) int {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// NewRenderTarget returns a new RenderTarget.
|
// NewRenderTarget returns a new RenderTarget.
|
||||||
func NewRenderTarget(width, height int, filter Filter) (*RenderTarget, error) {
|
func NewRenderTarget(width, height int, filter Filter) (RenderTarget, error) {
|
||||||
return currentUI.newRenderTarget(width, height, glFilter(filter))
|
return currentUI.newRenderTarget(width, height, glFilter(filter))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
31
graphics.go
31
graphics.go
@ -18,7 +18,6 @@ package ebiten
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/hajimehoshi/ebiten/internal/opengl"
|
"github.com/hajimehoshi/ebiten/internal/opengl"
|
||||||
"image/color"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// A Rect represents a rectangle.
|
// A Rect represents a rectangle.
|
||||||
@ -36,22 +35,12 @@ type TexturePart struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// DrawWholeTexture draws the whole texture.
|
// DrawWholeTexture draws the whole texture.
|
||||||
func DrawWholeTexture(g GraphicsContext, texture *Texture, geo GeometryMatrix, color ColorMatrix) error {
|
func DrawWholeTexture(r RenderTarget, texture *Texture, geo GeometryMatrix, color ColorMatrix) error {
|
||||||
w, h := texture.Size()
|
w, h := texture.Size()
|
||||||
parts := []TexturePart{
|
parts := []TexturePart{
|
||||||
{Rect{0, 0, float64(w), float64(h)}, Rect{0, 0, float64(w), float64(h)}},
|
{Rect{0, 0, float64(w), float64(h)}, Rect{0, 0, float64(w), float64(h)}},
|
||||||
}
|
}
|
||||||
return g.DrawTexture(texture, parts, geo, color)
|
return r.DrawTexture(texture, parts, geo, color)
|
||||||
}
|
|
||||||
|
|
||||||
// A GraphicsContext is the interface that means a context of rendering.
|
|
||||||
type GraphicsContext interface {
|
|
||||||
Clear() error
|
|
||||||
Fill(clr color.Color) error
|
|
||||||
DrawTexture(texture *Texture, parts []TexturePart, geo GeometryMatrix, color ColorMatrix) error
|
|
||||||
// TODO: ScreenRenderTarget() Drawer
|
|
||||||
PushRenderTarget(id *RenderTarget)
|
|
||||||
PopRenderTarget()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Filter represents the type of filter to be used when a texture is maginified or minified.
|
// Filter represents the type of filter to be used when a texture is maginified or minified.
|
||||||
@ -72,19 +61,3 @@ type Texture struct {
|
|||||||
func (t *Texture) Size() (width int, height int) {
|
func (t *Texture) Size() (width int, height int) {
|
||||||
return t.glTexture.Width(), t.glTexture.Height()
|
return t.glTexture.Width(), t.glTexture.Height()
|
||||||
}
|
}
|
||||||
|
|
||||||
// RenderTarget represents a render target.
|
|
||||||
type RenderTarget struct {
|
|
||||||
glRenderTarget *opengl.RenderTarget
|
|
||||||
texture *Texture
|
|
||||||
}
|
|
||||||
|
|
||||||
// Texture returns the texture of the render target.
|
|
||||||
func (r *RenderTarget) Texture() *Texture {
|
|
||||||
return r.texture
|
|
||||||
}
|
|
||||||
|
|
||||||
// Size returns the size of the render target.
|
|
||||||
func (r *RenderTarget) Size() (width int, height int) {
|
|
||||||
return r.glRenderTarget.Width(), r.glRenderTarget.Height()
|
|
||||||
}
|
|
||||||
|
@ -19,7 +19,6 @@ package ebiten
|
|||||||
import (
|
import (
|
||||||
"github.com/go-gl/gl"
|
"github.com/go-gl/gl"
|
||||||
"github.com/hajimehoshi/ebiten/internal/opengl"
|
"github.com/hajimehoshi/ebiten/internal/opengl"
|
||||||
"image/color"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func newGraphicsContext(screenWidth, screenHeight, screenScale int) (*graphicsContext, error) {
|
func newGraphicsContext(screenWidth, screenHeight, screenScale int) (*graphicsContext, error) {
|
||||||
@ -28,32 +27,24 @@ func newGraphicsContext(screenWidth, screenHeight, screenScale int) (*graphicsCo
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
screen, err := idsInstance.createRenderTarget(screenWidth, screenHeight, gl.NEAREST)
|
screen, err := newRenderTarget(screenWidth, screenHeight, gl.NEAREST)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
c := &graphicsContext{
|
c := &graphicsContext{
|
||||||
currents: make([]*RenderTarget, 1),
|
defaultR: &renderTarget{r, nil},
|
||||||
defaultR: &RenderTarget{r, nil},
|
|
||||||
screen: screen,
|
screen: screen,
|
||||||
screenWidth: screenWidth,
|
|
||||||
screenHeight: screenHeight,
|
|
||||||
screenScale: screenScale,
|
screenScale: screenScale,
|
||||||
}
|
}
|
||||||
return c, nil
|
return c, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type graphicsContext struct {
|
type graphicsContext struct {
|
||||||
screen *RenderTarget
|
screen *renderTarget
|
||||||
defaultR *RenderTarget
|
defaultR *renderTarget
|
||||||
currents []*RenderTarget
|
|
||||||
screenWidth int
|
|
||||||
screenHeight int
|
|
||||||
screenScale int
|
screenScale int
|
||||||
}
|
}
|
||||||
|
|
||||||
var _ 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.
|
||||||
glRenderTarget := c.screen.glRenderTarget
|
glRenderTarget := c.screen.glRenderTarget
|
||||||
@ -64,44 +55,20 @@ func (c *graphicsContext) dispose() {
|
|||||||
glTexture.Dispose()
|
glTexture.Dispose()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *graphicsContext) Clear() error {
|
func (c *graphicsContext) preUpdate() error {
|
||||||
return c.Fill(color.RGBA{0, 0, 0, 0})
|
return c.screen.Clear()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *graphicsContext) Fill(clr color.Color) error {
|
func (c *graphicsContext) postUpdate() error {
|
||||||
return idsInstance.fillRenderTarget(c.currents[len(c.currents)-1], clr)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *graphicsContext) DrawTexture(texture *Texture, parts []TexturePart, geo GeometryMatrix, color ColorMatrix) error {
|
|
||||||
current := c.currents[len(c.currents)-1]
|
|
||||||
return idsInstance.drawTexture(current, texture, parts, geo, color)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *graphicsContext) PushRenderTarget(renderTarget *RenderTarget) {
|
|
||||||
c.currents = append(c.currents, renderTarget)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *graphicsContext) PopRenderTarget() {
|
|
||||||
c.currents = c.currents[:len(c.currents)-1]
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *graphicsContext) preUpdate() {
|
|
||||||
c.currents = c.currents[0:1]
|
|
||||||
c.currents[0] = c.defaultR
|
|
||||||
|
|
||||||
c.PushRenderTarget(c.screen)
|
|
||||||
c.Clear()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *graphicsContext) postUpdate() {
|
|
||||||
c.PopRenderTarget()
|
|
||||||
|
|
||||||
// We don't need to clear the default render target (framebuffer).
|
// We don't need to clear the default render target (framebuffer).
|
||||||
// For the default framebuffer, a special shader is used.
|
// For the default framebuffer, a special shader is used.
|
||||||
scale := float64(c.screenScale)
|
scale := float64(c.screenScale)
|
||||||
geo := ScaleGeometry(scale, scale)
|
geo := ScaleGeometry(scale, scale)
|
||||||
clr := ColorMatrixI()
|
clr := ColorMatrixI()
|
||||||
DrawWholeTexture(c, c.screen.texture, geo, clr)
|
if err := DrawWholeTexture(c.defaultR, c.screen.texture, geo, clr); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
gl.Flush()
|
gl.Flush()
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -73,16 +73,11 @@ func (r *RenderTarget) Height() int {
|
|||||||
return r.height
|
return r.height
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *RenderTarget) FlipY() bool {
|
|
||||||
return r.flipY
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *RenderTarget) Dispose() {
|
func (r *RenderTarget) Dispose() {
|
||||||
r.framebuffer.Delete()
|
r.framebuffer.Delete()
|
||||||
}
|
}
|
||||||
|
|
||||||
func createFramebuffer(nativeTexture gl.Texture) (gl.Framebuffer, error) {
|
func createFramebuffer(nativeTexture gl.Texture) (gl.Framebuffer, error) {
|
||||||
// TODO: Does this affect the current rendering target?
|
|
||||||
framebuffer := gl.GenFramebuffer()
|
framebuffer := gl.GenFramebuffer()
|
||||||
framebuffer.Bind()
|
framebuffer.Bind()
|
||||||
|
|
||||||
@ -102,7 +97,10 @@ func (r *RenderTarget) SetAsViewport() error {
|
|||||||
r.framebuffer.Bind()
|
r.framebuffer.Bind()
|
||||||
err := gl.CheckFramebufferStatus(gl.FRAMEBUFFER)
|
err := gl.CheckFramebufferStatus(gl.FRAMEBUFFER)
|
||||||
if err != gl.FRAMEBUFFER_COMPLETE {
|
if err != gl.FRAMEBUFFER_COMPLETE {
|
||||||
return errors.New(fmt.Sprintf("glBindFramebuffer failed: %d", err))
|
if gl.GetError() != 0 {
|
||||||
|
return errors.New(fmt.Sprintf("glBindFramebuffer failed: %d", gl.GetError()))
|
||||||
|
}
|
||||||
|
return errors.New("glBindFramebuffer failed: the context is different?")
|
||||||
}
|
}
|
||||||
|
|
||||||
width := internal.AdjustSizeForTexture(r.width)
|
width := internal.AdjustSizeForTexture(r.width)
|
||||||
|
@ -25,72 +25,79 @@ import (
|
|||||||
"math"
|
"math"
|
||||||
)
|
)
|
||||||
|
|
||||||
// ids manages the current render target to be used.
|
// TODO: Rename
|
||||||
// TODO: Change this name. `ids` is not appropriate for now.
|
type RenderTarget interface {
|
||||||
type ids struct {
|
Texture() *Texture
|
||||||
currentRenderTarget *RenderTarget
|
Size() (width, height int)
|
||||||
|
Clear() error
|
||||||
|
Fill(clr color.Color) error
|
||||||
|
DrawTexture(texture *Texture, parts []TexturePart, geo GeometryMatrix, color ColorMatrix) error
|
||||||
}
|
}
|
||||||
|
|
||||||
var idsInstance = &ids{}
|
type renderTarget struct {
|
||||||
|
glRenderTarget *opengl.RenderTarget
|
||||||
|
texture *Texture
|
||||||
|
}
|
||||||
|
|
||||||
func (i *ids) createRenderTarget(width, height int, filter int) (*RenderTarget, error) {
|
func newRenderTarget(width, height int, filter int) (*renderTarget, error) {
|
||||||
glTexture, err := opengl.NewTexture(width, height, filter)
|
glTexture, err := opengl.NewTexture(width, height, filter)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// The current binded framebuffer can be changed.
|
|
||||||
i.currentRenderTarget = nil
|
|
||||||
glRenderTarget, err := opengl.NewRenderTargetFromTexture(glTexture)
|
glRenderTarget, err := opengl.NewRenderTargetFromTexture(glTexture)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
texture := &Texture{glTexture}
|
texture := &Texture{glTexture}
|
||||||
// TODO: Is |texture| necessary?
|
renderTarget := &renderTarget{glRenderTarget, texture}
|
||||||
renderTarget := &RenderTarget{glRenderTarget, texture}
|
|
||||||
i.fillRenderTarget(renderTarget, color.RGBA{0, 0, 0, 0})
|
|
||||||
|
|
||||||
return renderTarget, nil
|
return renderTarget, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *ids) fillRenderTarget(renderTarget *RenderTarget, clr color.Color) error {
|
func (r *renderTarget) Texture() *Texture {
|
||||||
if err := i.setViewportIfNeeded(renderTarget); err != nil {
|
return r.texture
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *renderTarget) Size() (width, height int) {
|
||||||
|
return r.glRenderTarget.Width(), r.glRenderTarget.Height()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *renderTarget) Clear() error {
|
||||||
|
return r.Fill(color.RGBA{0, 0, 0, 0})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *renderTarget) Fill(clr color.Color) error {
|
||||||
|
if err := r.glRenderTarget.SetAsViewport(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
const max = math.MaxUint16
|
const max = math.MaxUint16
|
||||||
r, g, b, a := clr.RGBA()
|
cr, cg, cb, ca := clr.RGBA()
|
||||||
gl.ClearColor(gl.GLclampf(float64(r)/max), gl.GLclampf(float64(g)/max), gl.GLclampf(float64(b)/max), gl.GLclampf(float64(a)/max))
|
rf := gl.GLclampf(float64(cr) / max)
|
||||||
|
gf := gl.GLclampf(float64(cg) / max)
|
||||||
|
bf := gl.GLclampf(float64(cb) / max)
|
||||||
|
af := gl.GLclampf(float64(ca) / max)
|
||||||
|
gl.ClearColor(rf, gf, bf, af)
|
||||||
gl.Clear(gl.COLOR_BUFFER_BIT)
|
gl.Clear(gl.COLOR_BUFFER_BIT)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *ids) drawTexture(target *RenderTarget, texture *Texture, parts []TexturePart, geo GeometryMatrix, color ColorMatrix) error {
|
func (r *renderTarget) DrawTexture(texture *Texture, parts []TexturePart, geo GeometryMatrix, color ColorMatrix) error {
|
||||||
|
if err := r.glRenderTarget.SetAsViewport(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
glTexture := texture.glTexture
|
glTexture := texture.glTexture
|
||||||
if err := i.setViewportIfNeeded(target); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
projectionMatrix := target.glRenderTarget.ProjectionMatrix()
|
|
||||||
quads := textureQuads(parts, glTexture.Width(), glTexture.Height())
|
quads := textureQuads(parts, glTexture.Width(), glTexture.Height())
|
||||||
w, h := target.Size()
|
|
||||||
targetNativeTexture := gl.Texture(0)
|
targetNativeTexture := gl.Texture(0)
|
||||||
if target.texture != nil {
|
if r.texture != nil {
|
||||||
targetNativeTexture = target.texture.glTexture.Native()
|
targetNativeTexture = r.texture.glTexture.Native()
|
||||||
}
|
}
|
||||||
|
w, h := r.Size()
|
||||||
|
projectionMatrix := r.glRenderTarget.ProjectionMatrix()
|
||||||
shader.DrawTexture(glTexture.Native(), targetNativeTexture, w, h, projectionMatrix, quads, &geo, &color)
|
shader.DrawTexture(glTexture.Native(), targetNativeTexture, w, h, projectionMatrix, quads, &geo, &color)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *ids) setViewportIfNeeded(renderTarget *RenderTarget) error {
|
|
||||||
if i.currentRenderTarget != renderTarget {
|
|
||||||
if err := renderTarget.glRenderTarget.SetAsViewport(); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
i.currentRenderTarget = renderTarget
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func u(x float64, width int) float32 {
|
func u(x float64, width int) float32 {
|
||||||
return float32(x) / float32(internal.AdjustSizeForTexture(width))
|
return float32(x) / float32(internal.AdjustSizeForTexture(width))
|
||||||
}
|
}
|
||||||
@ -115,3 +122,41 @@ func textureQuads(parts []TexturePart, width, height int) []shader.TextureQuad {
|
|||||||
}
|
}
|
||||||
return quads
|
return quads
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type syncer interface {
|
||||||
|
Sync(func())
|
||||||
|
}
|
||||||
|
|
||||||
|
type syncRenderTarget struct {
|
||||||
|
syncer syncer
|
||||||
|
inner RenderTarget
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *syncRenderTarget) Texture() *Texture {
|
||||||
|
return c.inner.Texture()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *syncRenderTarget) Size() (width, height int) {
|
||||||
|
return c.inner.Size()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *syncRenderTarget) Clear() (err error) {
|
||||||
|
c.syncer.Sync(func() {
|
||||||
|
err = c.inner.Clear()
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *syncRenderTarget) Fill(clr color.Color) (err error) {
|
||||||
|
c.syncer.Sync(func() {
|
||||||
|
err = c.inner.Fill(clr)
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *syncRenderTarget) DrawTexture(texture *Texture, parts []TexturePart, geo GeometryMatrix, color ColorMatrix) (err error) {
|
||||||
|
c.syncer.Sync(func() {
|
||||||
|
err = c.inner.DrawTexture(texture, parts, geo, color)
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
2
run.go
2
run.go
@ -18,7 +18,7 @@ package ebiten
|
|||||||
|
|
||||||
// Run runs the game.
|
// Run runs the game.
|
||||||
// This function must be called from the main thread.
|
// This function must be called from the main thread.
|
||||||
func Run(f func(GraphicsContext) error, width, height, scale int, title string) error {
|
func Run(f func(RenderTarget) error, width, height, scale int, title string) error {
|
||||||
err := startUI(width, height, scale, title)
|
err := startUI(width, height, scale, title)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -1,65 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright 2014 Hajime Hoshi
|
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
you may not use this file except in compliance with the License.
|
|
||||||
You may obtain a copy of the License at
|
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
See the License for the specific language governing permissions and
|
|
||||||
limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package ebiten
|
|
||||||
|
|
||||||
import (
|
|
||||||
"image/color"
|
|
||||||
)
|
|
||||||
|
|
||||||
type syncer interface {
|
|
||||||
Sync(f func())
|
|
||||||
}
|
|
||||||
|
|
||||||
type syncGraphicsContext struct {
|
|
||||||
syncer syncer
|
|
||||||
innerGraphicsContext GraphicsContext
|
|
||||||
}
|
|
||||||
|
|
||||||
var _ GraphicsContext = new(syncGraphicsContext)
|
|
||||||
|
|
||||||
func (c *syncGraphicsContext) Clear() (err error) {
|
|
||||||
c.syncer.Sync(func() {
|
|
||||||
err = c.innerGraphicsContext.Clear()
|
|
||||||
})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *syncGraphicsContext) Fill(clr color.Color) (err error) {
|
|
||||||
c.syncer.Sync(func() {
|
|
||||||
err = c.innerGraphicsContext.Fill(clr)
|
|
||||||
})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *syncGraphicsContext) DrawTexture(texture *Texture, parts []TexturePart, geo GeometryMatrix, color ColorMatrix) (err error) {
|
|
||||||
c.syncer.Sync(func() {
|
|
||||||
err = c.innerGraphicsContext.DrawTexture(texture, parts, geo, color)
|
|
||||||
})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *syncGraphicsContext) PopRenderTarget() {
|
|
||||||
c.syncer.Sync(func() {
|
|
||||||
c.innerGraphicsContext.PopRenderTarget()
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *syncGraphicsContext) PushRenderTarget(renderTarget *RenderTarget) {
|
|
||||||
c.syncer.Sync(func() {
|
|
||||||
c.innerGraphicsContext.PushRenderTarget(renderTarget)
|
|
||||||
})
|
|
||||||
}
|
|
26
ui.go
26
ui.go
@ -110,18 +110,22 @@ func (u *ui) Sync(f func()) {
|
|||||||
u.use(f)
|
u.use(f)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u *ui) draw(f func(GraphicsContext) error) (err error) {
|
func (u *ui) draw(f func(RenderTarget) error) (err error) {
|
||||||
u.use(func() {
|
u.use(func() {
|
||||||
u.graphicsContext.preUpdate()
|
err = u.graphicsContext.preUpdate()
|
||||||
})
|
})
|
||||||
if err = f(&syncGraphicsContext{
|
if err != nil {
|
||||||
syncer: u,
|
return
|
||||||
innerGraphicsContext: u.graphicsContext,
|
}
|
||||||
}); err != nil {
|
err = f(&syncRenderTarget{syncer: u, inner: u.graphicsContext.screen})
|
||||||
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
u.use(func() {
|
u.use(func() {
|
||||||
u.graphicsContext.postUpdate()
|
err = u.graphicsContext.postUpdate()
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
u.window.SwapBuffers()
|
u.window.SwapBuffers()
|
||||||
})
|
})
|
||||||
return
|
return
|
||||||
@ -140,13 +144,13 @@ func (u *ui) newTexture(img image.Image, filter int) (*Texture, error) {
|
|||||||
return texture, err
|
return texture, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u *ui) newRenderTarget(width, height int, filter int) (*RenderTarget, error) {
|
func (u *ui) newRenderTarget(width, height int, filter int) (RenderTarget, error) {
|
||||||
var renderTarget *RenderTarget
|
var renderTarget RenderTarget
|
||||||
var err error
|
var err error
|
||||||
u.use(func() {
|
u.use(func() {
|
||||||
renderTarget, err = idsInstance.createRenderTarget(width, height, filter)
|
renderTarget, err = newRenderTarget(width, height, filter)
|
||||||
})
|
})
|
||||||
return renderTarget, err
|
return &syncRenderTarget{u, renderTarget}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u *ui) run() {
|
func (u *ui) run() {
|
||||||
|
Loading…
Reference in New Issue
Block a user