Replace RenderTargetID with RenderTarget

This commit is contained in:
Hajime Hoshi 2014-12-17 22:04:33 +09:00
parent eb11831585
commit bac4317fc5
9 changed files with 82 additions and 97 deletions

View File

@ -24,7 +24,7 @@ import (
type debugPrintState struct { type debugPrintState struct {
textTexture *ebiten.Texture textTexture *ebiten.Texture
debugPrintRenderTarget ebiten.RenderTargetID debugPrintRenderTarget *ebiten.RenderTarget
y int y int
} }
@ -72,10 +72,10 @@ func (d *debugPrintState) DebugPrint(gr ebiten.GraphicsContext, str string) {
panic(err) panic(err)
} }
} }
if d.debugPrintRenderTarget.IsNil() { if d.debugPrintRenderTarget == nil {
width, height := 256, 256 width, height := 256, 256
var err error var err error
d.debugPrintRenderTarget, err = ebiten.NewRenderTargetID(width, height, ebiten.FilterNearest) d.debugPrintRenderTarget, err = ebiten.NewRenderTarget(width, height, ebiten.FilterNearest)
if err != nil { if err != nil {
panic(err) panic(err)
} }

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.RenderTargetID 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.RenderTargetID{}, renderTargets: map[string]*ebiten.RenderTarget{},
} }
go func() { go func() {
for { for {
@ -93,7 +93,7 @@ func (t *Textures) loopMain() {
name := s.name name := s.name
size := s.size size := s.size
go func() { go func() {
id, err := ebiten.NewRenderTargetID(size.Width, size.Height, ebiten.FilterNearest) id, err := ebiten.NewRenderTarget(size.Width, size.Height, ebiten.FilterNearest)
if err != nil { if err != nil {
panic(err) panic(err)
} }
@ -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.RenderTargetID { 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

@ -33,8 +33,8 @@ const (
type Game struct { type Game struct {
inited bool inited bool
count int count int
brushRenderTarget ebiten.RenderTargetID brushRenderTarget *ebiten.RenderTarget
canvasRenderTarget ebiten.RenderTargetID canvasRenderTarget *ebiten.RenderTarget
} }
func (g *Game) Update(gr ebiten.GraphicsContext) error { func (g *Game) Update(gr ebiten.GraphicsContext) error {
@ -72,11 +72,11 @@ func (g *Game) Update(gr ebiten.GraphicsContext) error {
func main() { func main() {
g := new(Game) g := new(Game)
var err error var err error
g.brushRenderTarget, err = ebiten.NewRenderTargetID(1, 1, ebiten.FilterNearest) g.brushRenderTarget, err = ebiten.NewRenderTarget(1, 1, ebiten.FilterNearest)
if err != nil { if err != nil {
log.Fatal(err) log.Fatal(err)
} }
g.canvasRenderTarget, err = ebiten.NewRenderTargetID(screenWidth, screenHeight, ebiten.FilterNearest) g.canvasRenderTarget, err = ebiten.NewRenderTarget(screenWidth, screenHeight, ebiten.FilterNearest)
if err != nil { if err != nil {
log.Fatal(err) log.Fatal(err)
} }

View File

@ -47,9 +47,9 @@ func glFilter(f Filter) int {
} }
} }
// NewRenderTargetID returns a new RenderTargetID. // NewRenderTarget returns a new RenderTarget.
func NewRenderTargetID(width, height int, filter Filter) (RenderTargetID, error) { func NewRenderTarget(width, height int, filter Filter) (*RenderTarget, error) {
return currentUI.newRenderTargetID(width, height, glFilter(filter)) return currentUI.newRenderTarget(width, height, glFilter(filter))
} }
// NewTexture returns a new Texture. // NewTexture returns a new Texture.

View File

@ -54,9 +54,9 @@ type GraphicsContext interface {
Clear() error Clear() error
Fill(r, g, b uint8) error Fill(r, g, b uint8) error
Texture(texture *Texture) Drawer Texture(texture *Texture) Drawer
RenderTarget(id RenderTargetID) Drawer RenderTarget(id *RenderTarget) Drawer
// TODO: ScreenRenderTarget() Drawer // TODO: ScreenRenderTarget() Drawer
PushRenderTarget(id RenderTargetID) PushRenderTarget(id *RenderTarget)
PopRenderTarget() PopRenderTarget()
} }
@ -70,32 +70,18 @@ const (
FilterLinear FilterLinear
) )
// Texture represents a texture.
type Texture struct { type Texture struct {
id int id int
} }
// RenderTarget represents a render target.
// A render target is essentially same as a texture, but it is assumed that the
// all alpha values of a render target is maximum.
type RenderTarget struct { type RenderTarget struct {
id int id int
} }
// TextureID represents an ID of a texture.
/*type TextureID int
// IsNil returns true if the texture is nil.
func (i TextureID) IsNil() bool {
return i == 0
}*/
// RenderTargetID represents an ID of a render target.
// A render target is essentially same as a texture, but it is assumed that the
// all alpha of a render target is maximum.
type RenderTargetID int
// IsNil returns true if the render target is nil.
func (i RenderTargetID) IsNil() bool {
return i == 0
}
func u(x int, width int) float32 { func u(x int, width int) float32 {
return float32(x) / float32(opengl.AdjustSizeForTexture(width)) return float32(x) / float32(opengl.AdjustSizeForTexture(width))
} }

View File

@ -25,29 +25,29 @@ func newGraphicsContext(screenWidth, screenHeight, screenScale int) (*graphicsCo
// The defualt framebuffer should be 0. // The defualt framebuffer should be 0.
r := opengl.NewRenderTarget(screenWidth*screenScale, screenHeight*screenScale, true) r := opengl.NewRenderTarget(screenWidth*screenScale, screenHeight*screenScale, true)
screenID, err := idsInstance.createRenderTarget(screenWidth, screenHeight, gl.NEAREST) screen, err := idsInstance.createRenderTarget(screenWidth, screenHeight, gl.NEAREST)
if err != nil { if err != nil {
return nil, err return nil, err
} }
c := &graphicsContext{ c := &graphicsContext{
currentIDs: make([]RenderTargetID, 1), currents: make([]*RenderTarget, 1),
defaultID: idsInstance.addRenderTarget(r), defaultR: idsInstance.addRenderTarget(r),
screenID: screenID, screen: screen,
screenWidth: screenWidth, screenWidth: screenWidth,
screenHeight: screenHeight, screenHeight: screenHeight,
screenScale: screenScale, screenScale: screenScale,
} }
idsInstance.fillRenderTarget(c.screenID, 0, 0, 0) idsInstance.fillRenderTarget(c.screen, 0, 0, 0)
return c, nil return c, nil
} }
type graphicsContext struct { type graphicsContext struct {
screenID RenderTargetID screen *RenderTarget
defaultID RenderTargetID defaultR *RenderTarget
currentIDs []RenderTargetID currents []*RenderTarget
screenWidth int screenWidth int
screenHeight int screenHeight int
screenScale int screenScale int
@ -57,7 +57,7 @@ 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.
idsInstance.deleteRenderTarget(c.screenID) idsInstance.deleteRenderTarget(c.screen)
} }
func (c *graphicsContext) Clear() error { func (c *graphicsContext) Clear() error {
@ -65,29 +65,29 @@ func (c *graphicsContext) Clear() error {
} }
func (c *graphicsContext) Fill(r, g, b uint8) error { func (c *graphicsContext) Fill(r, g, b uint8) error {
return idsInstance.fillRenderTarget(c.currentIDs[len(c.currentIDs)-1], r, g, b) return idsInstance.fillRenderTarget(c.currents[len(c.currents)-1], r, g, b)
} }
func (c *graphicsContext) Texture(texture *Texture) Drawer { func (c *graphicsContext) Texture(texture *Texture) Drawer {
return &textureWithContext{texture, c} return &textureWithContext{texture, c}
} }
func (c *graphicsContext) RenderTarget(id RenderTargetID) Drawer { func (c *graphicsContext) RenderTarget(id *RenderTarget) Drawer {
return &textureWithContext{idsInstance.toTexture(id), c} return &textureWithContext{idsInstance.toTexture(id), c}
} }
func (c *graphicsContext) PushRenderTarget(renderTargetID RenderTargetID) { func (c *graphicsContext) PushRenderTarget(renderTarget *RenderTarget) {
c.currentIDs = append(c.currentIDs, renderTargetID) c.currents = append(c.currents, renderTarget)
} }
func (c *graphicsContext) PopRenderTarget() { func (c *graphicsContext) PopRenderTarget() {
c.currentIDs = c.currentIDs[:len(c.currentIDs)-1] c.currents = c.currents[:len(c.currents)-1]
} }
func (c *graphicsContext) preUpdate() { func (c *graphicsContext) preUpdate() {
c.currentIDs = c.currentIDs[0:1] c.currents = c.currents[0:1]
c.currentIDs[0] = c.defaultID c.currents[0] = c.defaultR
c.PushRenderTarget(c.screenID) c.PushRenderTarget(c.screen)
c.Clear() c.Clear()
} }
@ -98,7 +98,7 @@ func (c *graphicsContext) postUpdate() {
scale := float64(c.screenScale) scale := float64(c.screenScale)
geo := GeometryMatrixI() geo := GeometryMatrixI()
geo.Concat(ScaleGeometry(scale, scale)) geo.Concat(ScaleGeometry(scale, scale))
DrawWhole(c.RenderTarget(c.screenID), c.screenWidth, c.screenHeight, geo, ColorMatrixI()) DrawWhole(c.RenderTarget(c.screen), c.screenWidth, c.screenHeight, geo, ColorMatrixI())
gl.Flush() gl.Flush()
} }
@ -109,6 +109,6 @@ type textureWithContext struct {
} }
func (t *textureWithContext) Draw(parts []TexturePart, geo GeometryMatrix, color ColorMatrix) error { func (t *textureWithContext) Draw(parts []TexturePart, geo GeometryMatrix, color ColorMatrix) error {
currentID := t.context.currentIDs[len(t.context.currentIDs)-1] current := t.context.currents[len(t.context.currents)-1]
return idsInstance.drawTexture(currentID, t.texture, parts, geo, color) return idsInstance.drawTexture(current, t.texture, parts, geo, color)
} }

69
ids.go
View File

@ -27,18 +27,17 @@ import (
type ids struct { type ids struct {
textures map[*Texture]*opengl.Texture textures map[*Texture]*opengl.Texture
renderTargets map[RenderTargetID]*opengl.RenderTarget renderTargets map[*RenderTarget]*opengl.RenderTarget
renderTargetToTexture map[RenderTargetID]*Texture renderTargetToTexture map[*RenderTarget]*Texture
lastID int lastID int
currentRenderTargetID RenderTargetID currentRenderTarget *RenderTarget
sync.RWMutex sync.RWMutex
} }
var idsInstance = &ids{ var idsInstance = &ids{
textures: map[*Texture]*opengl.Texture{}, textures: map[*Texture]*opengl.Texture{},
renderTargets: map[RenderTargetID]*opengl.RenderTarget{}, renderTargets: map[*RenderTarget]*opengl.RenderTarget{},
renderTargetToTexture: map[RenderTargetID]*Texture{}, renderTargetToTexture: map[*RenderTarget]*Texture{},
currentRenderTargetID: -1,
} }
func (i *ids) textureAt(texture *Texture) *opengl.Texture { func (i *ids) textureAt(texture *Texture) *opengl.Texture {
@ -47,16 +46,16 @@ func (i *ids) textureAt(texture *Texture) *opengl.Texture {
return i.textures[texture] return i.textures[texture]
} }
func (i *ids) renderTargetAt(id RenderTargetID) *opengl.RenderTarget { func (i *ids) renderTargetAt(renderTarget *RenderTarget) *opengl.RenderTarget {
i.RLock() i.RLock()
defer i.RUnlock() defer i.RUnlock()
return i.renderTargets[id] return i.renderTargets[renderTarget]
} }
func (i *ids) toTexture(id RenderTargetID) *Texture { func (i *ids) toTexture(renderTarget *RenderTarget) *Texture {
i.RLock() i.RLock()
defer i.RUnlock() defer i.RUnlock()
return i.renderTargetToTexture[id] return i.renderTargetToTexture[renderTarget]
} }
func (i *ids) createTexture(img image.Image, filter int) (*Texture, error) { func (i *ids) createTexture(img image.Image, filter int) (*Texture, error) {
@ -73,17 +72,17 @@ func (i *ids) createTexture(img image.Image, filter int) (*Texture, error) {
return texture, nil return texture, nil
} }
func (i *ids) createRenderTarget(width, height int, filter int) (RenderTargetID, error) { func (i *ids) createRenderTarget(width, height int, filter int) (*RenderTarget, error) {
glTexture, err := opengl.CreateTexture(width, height, filter) glTexture, err := opengl.CreateTexture(width, height, filter)
if err != nil { if err != nil {
return 0, err return nil, err
} }
// The current binded framebuffer can be changed. // The current binded framebuffer can be changed.
i.currentRenderTargetID = -1 i.currentRenderTarget = nil
r, err := opengl.NewRenderTargetFromTexture(glTexture) r, err := opengl.NewRenderTargetFromTexture(glTexture)
if err != nil { if err != nil {
return 0, err return nil, err
} }
i.Lock() i.Lock()
@ -91,44 +90,44 @@ func (i *ids) createRenderTarget(width, height int, filter int) (RenderTargetID,
i.lastID++ i.lastID++
texture := &Texture{i.lastID} texture := &Texture{i.lastID}
i.lastID++ i.lastID++
renderTargetID := RenderTargetID(i.lastID) renderTarget := &RenderTarget{i.lastID}
i.textures[texture] = glTexture i.textures[texture] = glTexture
i.renderTargets[renderTargetID] = r i.renderTargets[renderTarget] = r
i.renderTargetToTexture[renderTargetID] = texture i.renderTargetToTexture[renderTarget] = texture
return renderTargetID, nil return renderTarget, nil
} }
// NOTE: renderTarget can't be used as a texture. // NOTE: renderTarget can't be used as a texture.
func (i *ids) addRenderTarget(renderTarget *opengl.RenderTarget) RenderTargetID { func (i *ids) addRenderTarget(glRenderTarget *opengl.RenderTarget) *RenderTarget {
i.Lock() i.Lock()
defer i.Unlock() defer i.Unlock()
i.lastID++ i.lastID++
id := RenderTargetID(i.lastID) renderTarget := &RenderTarget{i.lastID}
i.renderTargets[id] = renderTarget i.renderTargets[renderTarget] = glRenderTarget
return id return renderTarget
} }
func (i *ids) deleteRenderTarget(id RenderTargetID) { func (i *ids) deleteRenderTarget(renderTarget *RenderTarget) {
i.Lock() i.Lock()
defer i.Unlock() defer i.Unlock()
renderTarget := i.renderTargets[id] glRenderTarget := i.renderTargets[renderTarget]
texture := i.renderTargetToTexture[id] texture := i.renderTargetToTexture[renderTarget]
glTexture := i.textures[texture] glTexture := i.textures[texture]
renderTarget.Dispose() glRenderTarget.Dispose()
glTexture.Dispose() glTexture.Dispose()
delete(i.renderTargets, id) delete(i.renderTargets, renderTarget)
delete(i.renderTargetToTexture, id) delete(i.renderTargetToTexture, renderTarget)
delete(i.textures, texture) delete(i.textures, texture)
} }
func (i *ids) fillRenderTarget(id RenderTargetID, r, g, b uint8) error { func (i *ids) fillRenderTarget(renderTarget *RenderTarget, r, g, b uint8) error {
if err := i.setViewportIfNeeded(id); err != nil { if err := i.setViewportIfNeeded(renderTarget); err != nil {
return err return err
} }
const max = float64(math.MaxUint8) const max = float64(math.MaxUint8)
@ -137,7 +136,7 @@ func (i *ids) fillRenderTarget(id RenderTargetID, r, g, b uint8) error {
return nil return nil
} }
func (i *ids) drawTexture(target RenderTargetID, texture *Texture, parts []TexturePart, geo GeometryMatrix, color ColorMatrix) error { func (i *ids) drawTexture(target *RenderTarget, texture *Texture, parts []TexturePart, geo GeometryMatrix, color ColorMatrix) error {
glTexture := i.textureAt(texture) glTexture := i.textureAt(texture)
if err := i.setViewportIfNeeded(target); err != nil { if err := i.setViewportIfNeeded(target); err != nil {
return err return err
@ -149,13 +148,13 @@ func (i *ids) drawTexture(target RenderTargetID, texture *Texture, parts []Textu
return nil return nil
} }
func (i *ids) setViewportIfNeeded(id RenderTargetID) error { func (i *ids) setViewportIfNeeded(renderTarget *RenderTarget) error {
r := i.renderTargetAt(id) r := i.renderTargetAt(renderTarget)
if i.currentRenderTargetID != id { if i.currentRenderTarget != renderTarget {
if err := r.SetAsViewport(); err != nil { if err := r.SetAsViewport(); err != nil {
return err return err
} }
i.currentRenderTargetID = id i.currentRenderTarget = renderTarget
} }
return nil return nil
} }

View File

@ -51,11 +51,11 @@ func (c *syncGraphicsContext) Texture(texture *Texture) (d Drawer) {
return return
} }
func (c *syncGraphicsContext) RenderTarget(id RenderTargetID) (d Drawer) { func (c *syncGraphicsContext) RenderTarget(renderTarget *RenderTarget) (d Drawer) {
c.syncer.Sync(func() { c.syncer.Sync(func() {
d = &drawer{ d = &drawer{
syncer: c.syncer, syncer: c.syncer,
innerDrawer: c.innerGraphicsContext.RenderTarget(id), innerDrawer: c.innerGraphicsContext.RenderTarget(renderTarget),
} }
}) })
return return
@ -67,9 +67,9 @@ func (c *syncGraphicsContext) PopRenderTarget() {
}) })
} }
func (c *syncGraphicsContext) PushRenderTarget(id RenderTargetID) { func (c *syncGraphicsContext) PushRenderTarget(renderTarget *RenderTarget) {
c.syncer.Sync(func() { c.syncer.Sync(func() {
c.innerGraphicsContext.PushRenderTarget(id) c.innerGraphicsContext.PushRenderTarget(renderTarget)
}) })
} }

8
ui.go
View File

@ -136,13 +136,13 @@ func (u *ui) newTexture(img image.Image, filter int) (*Texture, error) {
return texture, err return texture, err
} }
func (u *ui) newRenderTargetID(width, height int, filter int) (RenderTargetID, error) { func (u *ui) newRenderTarget(width, height int, filter int) (*RenderTarget, error) {
var id RenderTargetID var renderTarget *RenderTarget
var err error var err error
u.use(func() { u.use(func() {
id, err = idsInstance.createRenderTarget(width, height, filter) renderTarget, err = idsInstance.createRenderTarget(width, height, filter)
}) })
return id, err return renderTarget, err
} }
func (u *ui) run() { func (u *ui) run() {