Change RenderTexture to interface

This commit is contained in:
Hajime Hoshi 2014-12-21 00:36:27 +09:00
parent 01e0d42451
commit 991adb7449
20 changed files with 56 additions and 60 deletions

View File

@ -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(r ebiten.RenderTarget, str string) { func DebugPrint(r *ebiten.RenderTarget, str string) {
defaultDebugPrintState.DebugPrint(r, str) defaultDebugPrintState.DebugPrint(r, str)
} }
func (d *debugPrintState) drawText(r ebiten.RenderTarget, 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 {
@ -60,7 +60,7 @@ func (d *debugPrintState) drawText(r ebiten.RenderTarget, str string, x, y int,
r.DrawTexture(d.textTexture, parts, geom, clrm) r.DrawTexture(d.textTexture, parts, geom, clrm)
} }
func (d *debugPrintState) DebugPrint(r ebiten.RenderTarget, 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 {

View File

@ -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(r ebiten.RenderTarget) 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

View File

@ -112,7 +112,7 @@ func (f *Field) flushLine(j int) bool {
return true return true
} }
func (f *Field) Draw(r ebiten.RenderTarget, 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))

View File

@ -32,7 +32,7 @@ func textWidth(str string) int {
return charWidth * len(str) return charWidth * len(str)
} }
func drawText(r ebiten.RenderTarget, 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{}
@ -59,7 +59,7 @@ func drawText(r ebiten.RenderTarget, textures *Textures, str string, ox, oy, sca
r.DrawTexture(fontTextureId, parts, geoMat, clrMat) r.DrawTexture(fontTextureId, parts, geoMat, clrMat)
} }
func drawTextWithShadow(r ebiten.RenderTarget, 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(r, 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(r, textures, str, x, y, scale, clr) drawText(r, textures, str, x, y, scale, clr)
} }

View File

@ -70,7 +70,7 @@ func (game *Game) isInitialized() bool {
return true return true
} }
func (game *Game) Update(r ebiten.RenderTarget) 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 {

View File

@ -109,7 +109,7 @@ func (s *GameScene) Update(state *GameState) {
} }
} }
func (s *GameScene) Draw(r ebiten.RenderTarget, textures *Textures) { func (s *GameScene) Draw(r *ebiten.RenderTarget, textures *Textures) {
r.Fill(color.White) r.Fill(color.White)
field := textures.GetTexture("empty") field := textures.GetTexture("empty")

View File

@ -138,7 +138,7 @@ const blockHeight = 10
const fieldBlockNumX = 10 const fieldBlockNumX = 10
const fieldBlockNumY = 20 const fieldBlockNumY = 20
func drawBlocks(r ebiten.RenderTarget, 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 {
@ -213,7 +213,7 @@ func (p *Piece) AbsorbInto(field *Field, x, y int, angle Angle) {
} }
} }
func (p *Piece) Draw(r ebiten.RenderTarget, 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 {

View File

@ -29,7 +29,7 @@ func init() {
type Scene interface { type Scene interface {
Update(state *GameState) Update(state *GameState)
Draw(r ebiten.RenderTarget, textures *Textures) Draw(r *ebiten.RenderTarget, textures *Textures)
} }
const transitionMaxCount = 20 const transitionMaxCount = 20
@ -60,7 +60,7 @@ func (s *SceneManager) Update(state *GameState) {
} }
} }
func (s *SceneManager) Draw(r ebiten.RenderTarget, textures *Textures) { func (s *SceneManager) Draw(r *ebiten.RenderTarget, textures *Textures) {
if s.transitionCount == -1 { if s.transitionCount == -1 {
s.current.Draw(r, textures) s.current.Draw(r, textures)
return return

View File

@ -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]

View File

@ -40,7 +40,7 @@ func (s *TitleScene) Update(state *GameState) {
} }
} }
func (s *TitleScene) Draw(r ebiten.RenderTarget, textures *Textures) { func (s *TitleScene) Draw(r *ebiten.RenderTarget, textures *Textures) {
drawTitleBackground(r, textures, s.count) drawTitleBackground(r, textures, s.count)
drawLogo(r, textures, "BLOCKS") drawLogo(r, textures, "BLOCKS")
@ -50,7 +50,7 @@ func (s *TitleScene) Draw(r ebiten.RenderTarget, textures *Textures) {
drawTextWithShadow(r, 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(r ebiten.RenderTarget, 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
@ -73,7 +73,7 @@ func drawTitleBackground(r ebiten.RenderTarget, textures *Textures, c int) {
r.DrawTexture(backgroundTexture, parts, geo, clr) r.DrawTexture(backgroundTexture, parts, geo, clr)
} }
func drawLogo(r ebiten.RenderTarget, 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

View File

@ -36,7 +36,7 @@ type Game struct {
gophersTexture *ebiten.Texture gophersTexture *ebiten.Texture
} }
func (g *Game) Update(r ebiten.RenderTarget) 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--

View File

@ -32,10 +32,10 @@ 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(r ebiten.RenderTarget) error { func (g *Game) Update(r *ebiten.RenderTarget) error {
geo := ebiten.ScaleGeometry(1.0/mosaicRatio, 1.0/mosaicRatio) geo := ebiten.ScaleGeometry(1.0/mosaicRatio, 1.0/mosaicRatio)
ebiten.DrawWholeTexture(g.gophersRenderTarget, g.gophersTexture, geo, ebiten.ColorMatrixI()) ebiten.DrawWholeTexture(g.gophersRenderTarget, g.gophersTexture, geo, ebiten.ColorMatrixI())

View File

@ -33,11 +33,11 @@ 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(r ebiten.RenderTarget) error { func (g *Game) Update(r *ebiten.RenderTarget) error {
if ebiten.IsMouseButtonPressed(ebiten.MouseButtonLeft) { if ebiten.IsMouseButtonPressed(ebiten.MouseButtonLeft) {
g.count++ g.count++
} }

View File

@ -32,7 +32,7 @@ type Game struct {
gophersTexture *ebiten.Texture gophersTexture *ebiten.Texture
} }
func (g *Game) Update(r ebiten.RenderTarget) 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++ {

View File

@ -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))
} }

View File

@ -34,8 +34,12 @@ type TexturePart struct {
Src Rect Src Rect
} }
type TextureDrawer interface {
DrawTexture(texture *Texture, parts []TexturePart, geo GeometryMatrix, color ColorMatrix) error
}
// DrawWholeTexture draws the whole texture. // DrawWholeTexture draws the whole texture.
func DrawWholeTexture(r RenderTarget, texture *Texture, geo GeometryMatrix, color ColorMatrix) error { func DrawWholeTexture(r TextureDrawer, 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)}},

View File

@ -86,6 +86,7 @@ void main(void) {
vec4 color1 = texture2D(texture1, vertex_out_tex_coord1); vec4 color1 = texture2D(texture1, vertex_out_tex_coord1);
color0 = (color_matrix * color0) + color_matrix_translation; color0 = (color_matrix * color0) + color_matrix_translation;
// Photoshop-like RGBA blending
gl_FragColor.a = color0.a + color1.a - color0.a * color1.a; gl_FragColor.a = color0.a + color1.a - color0.a * color1.a;
gl_FragColor.rgb = (color0.a * color0.rgb + (1.0 - color0.a) * color1.a * color1.rgb) / gl_FragColor.a; gl_FragColor.rgb = (color0.a * color0.rgb + (1.0 - color0.a) * color1.a * color1.rgb) / gl_FragColor.a;
} }

View File

@ -25,15 +25,6 @@ import (
"math" "math"
) )
// TODO: Rename
type RenderTarget interface {
Texture() *Texture
Size() (width, height int)
Clear() error
Fill(clr color.Color) error
DrawTexture(texture *Texture, parts []TexturePart, geo GeometryMatrix, color ColorMatrix) error
}
type renderTarget struct { type renderTarget struct {
glRenderTarget *opengl.RenderTarget glRenderTarget *opengl.RenderTarget
texture *Texture texture *Texture
@ -127,36 +118,36 @@ type syncer interface {
Sync(func()) Sync(func())
} }
type syncRenderTarget struct { type RenderTarget struct {
syncer syncer syncer syncer
inner RenderTarget inner *renderTarget
} }
func (c *syncRenderTarget) Texture() *Texture { func (r *RenderTarget) Texture() *Texture {
return c.inner.Texture() return r.inner.Texture()
} }
func (c *syncRenderTarget) Size() (width, height int) { func (r *RenderTarget) Size() (width, height int) {
return c.inner.Size() return r.inner.Size()
} }
func (c *syncRenderTarget) Clear() (err error) { func (r *RenderTarget) Clear() (err error) {
c.syncer.Sync(func() { r.syncer.Sync(func() {
err = c.inner.Clear() err = r.inner.Clear()
}) })
return return
} }
func (c *syncRenderTarget) Fill(clr color.Color) (err error) { func (r *RenderTarget) Fill(clr color.Color) (err error) {
c.syncer.Sync(func() { r.syncer.Sync(func() {
err = c.inner.Fill(clr) err = r.inner.Fill(clr)
}) })
return return
} }
func (c *syncRenderTarget) DrawTexture(texture *Texture, parts []TexturePart, geo GeometryMatrix, color ColorMatrix) (err error) { func (r *RenderTarget) DrawTexture(texture *Texture, parts []TexturePart, geo GeometryMatrix, color ColorMatrix) (err error) {
c.syncer.Sync(func() { r.syncer.Sync(func() {
err = c.inner.DrawTexture(texture, parts, geo, color) err = r.inner.DrawTexture(texture, parts, geo, color)
}) })
return return
} }

2
run.go
View File

@ -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(RenderTarget) 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

10
ui.go
View File

@ -110,14 +110,14 @@ func (u *ui) Sync(f func()) {
u.use(f) u.use(f)
} }
func (u *ui) draw(f func(RenderTarget) error) (err error) { func (u *ui) draw(f func(*RenderTarget) error) (err error) {
u.use(func() { u.use(func() {
err = u.graphicsContext.preUpdate() err = u.graphicsContext.preUpdate()
}) })
if err != nil { if err != nil {
return return
} }
err = f(&syncRenderTarget{syncer: u, inner: u.graphicsContext.screen}) err = f(&RenderTarget{syncer: u, inner: u.graphicsContext.screen})
if err != nil { if err != nil {
return return
} }
@ -144,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 = newRenderTarget(width, height, filter) renderTarget, err = newRenderTarget(width, height, filter)
}) })
return &syncRenderTarget{u, renderTarget}, err return &RenderTarget{u, renderTarget}, err
} }
func (u *ui) run() { func (u *ui) run() {