From eb1183158548b1ba2b55b085415f27290c86e4e8 Mon Sep 17 00:00:00 2001 From: Hajime Hoshi Date: Wed, 17 Dec 2014 21:49:28 +0900 Subject: [PATCH] Replace TextureID with Texture --- ebitenutil/debugprint.go | 6 ++-- ebitenutil/texture.go | 12 ++++--- example/blocks/blocks/textures.go | 8 ++--- example/image/main.go | 22 ++++++++++--- example/paint/main.go | 8 ++--- gamecontext.go | 6 ++-- graphics.go | 14 +++++++-- graphicscontext.go | 8 ++--- ids.go | 52 +++++++++++++++---------------- syncgraphicscontext.go | 4 +-- ui.go | 8 ++--- 11 files changed, 87 insertions(+), 61 deletions(-) diff --git a/ebitenutil/debugprint.go b/ebitenutil/debugprint.go index 235d8b83c..5450f6a5a 100644 --- a/ebitenutil/debugprint.go +++ b/ebitenutil/debugprint.go @@ -23,7 +23,7 @@ import ( ) type debugPrintState struct { - textTexture ebiten.TextureID + textTexture *ebiten.Texture debugPrintRenderTarget ebiten.RenderTargetID y int } @@ -62,12 +62,12 @@ func (d *debugPrintState) drawText(gr ebiten.GraphicsContext, str string, x, y i } func (d *debugPrintState) DebugPrint(gr ebiten.GraphicsContext, str string) { - if d.textTexture.IsNil() { + if d.textTexture == nil { img, err := assets.TextImage() if err != nil { panic(err) } - d.textTexture, err = ebiten.NewTextureID(img, ebiten.FilterNearest) + d.textTexture, err = ebiten.NewTexture(img, ebiten.FilterNearest) if err != nil { panic(err) } diff --git a/ebitenutil/texture.go b/ebitenutil/texture.go index e07d8c1ac..c2fdd963e 100644 --- a/ebitenutil/texture.go +++ b/ebitenutil/texture.go @@ -22,15 +22,19 @@ import ( "os" ) -func NewTextureIDFromFile(path string, filter ebiten.Filter) (ebiten.TextureID, error) { +func NewTextureFromFile(path string, filter ebiten.Filter) (*ebiten.Texture, image.Image, error) { file, err := os.Open(path) if err != nil { - return 0, err + return nil, nil, err } defer file.Close() img, _, err := image.Decode(file) if err != nil { - return 0, err + return nil, nil, err } - return ebiten.NewTextureID(img, filter) + texture, err := ebiten.NewTexture(img, filter) + if err != nil { + return nil, nil, err + } + return texture, img, err } diff --git a/example/blocks/blocks/textures.go b/example/blocks/blocks/textures.go index 1d39fb1e5..fca0599e8 100644 --- a/example/blocks/blocks/textures.go +++ b/example/blocks/blocks/textures.go @@ -37,7 +37,7 @@ type nameSize struct { type Textures struct { texturePaths chan namePath renderTargetSizes chan nameSize - textures map[string]ebiten.TextureID + textures map[string]*ebiten.Texture renderTargets map[string]ebiten.RenderTargetID sync.RWMutex } @@ -46,7 +46,7 @@ func NewTextures() *Textures { textures := &Textures{ texturePaths: make(chan namePath), renderTargetSizes: make(chan nameSize), - textures: map[string]ebiten.TextureID{}, + textures: map[string]*ebiten.Texture{}, renderTargets: map[string]ebiten.RenderTargetID{}, } go func() { @@ -81,7 +81,7 @@ func (t *Textures) loopMain() { if err != nil { panic(err) } - id, err := ebiten.NewTextureID(img, ebiten.FilterNearest) + id, err := ebiten.NewTexture(img, ebiten.FilterNearest) if err != nil { panic(err) } @@ -123,7 +123,7 @@ func (t *Textures) Has(name string) bool { return ok } -func (t *Textures) GetTexture(name string) ebiten.TextureID { +func (t *Textures) GetTexture(name string) *ebiten.Texture { t.RLock() defer t.RUnlock() return t.textures[name] diff --git a/example/image/main.go b/example/image/main.go index dad2edec7..89fafb5c3 100644 --- a/example/image/main.go +++ b/example/image/main.go @@ -19,8 +19,10 @@ package main import ( "github.com/hajimehoshi/ebiten" "github.com/hajimehoshi/ebiten/ebitenutil" + "image" _ "image/jpeg" "log" + "math" ) const ( @@ -29,21 +31,33 @@ const ( ) type Game struct { - gophersTexture ebiten.TextureID + count int + gophersTexture *ebiten.Texture + gophersTextureWidth int + gophersTextureHeight int } func (g *Game) Update(gr ebiten.GraphicsContext) error { - ebiten.DrawWhole(gr.Texture(g.gophersTexture), 500, 414, ebiten.GeometryMatrixI(), ebiten.ColorMatrixI()) + g.count++ + + geo := ebiten.TranslateGeometry(-float64(g.gophersTextureWidth)/2, -float64(g.gophersTextureHeight)/2) + geo.Concat(ebiten.ScaleGeometry(0.5, 0.5)) + geo.Concat(ebiten.TranslateGeometry(screenWidth/2, screenHeight/2)) + clr := ebiten.RotateHue(float64(g.count%180) * 2 * math.Pi / 180) + ebiten.DrawWhole(gr.Texture(g.gophersTexture), g.gophersTextureWidth, g.gophersTextureHeight, geo, clr) return nil } func main() { g := new(Game) - id, err := ebitenutil.NewTextureIDFromFile("images/gophers.jpg", ebiten.FilterLinear) + var img image.Image + var err error + g.gophersTexture, img, err = ebitenutil.NewTextureFromFile("images/gophers.jpg", ebiten.FilterLinear) if err != nil { log.Fatal(err) } - g.gophersTexture = id + g.gophersTextureWidth = img.Bounds().Size().X + g.gophersTextureHeight = img.Bounds().Size().Y if err := ebiten.Run(g.Update, screenWidth, screenHeight, 2, "Image (Ebiten Demo)"); err != nil { log.Fatal(err) } diff --git a/example/paint/main.go b/example/paint/main.go index 22b029e49..18f15b229 100644 --- a/example/paint/main.go +++ b/example/paint/main.go @@ -23,7 +23,6 @@ import ( "image/color" "log" "math" - "sync" ) const ( @@ -32,7 +31,7 @@ const ( ) type Game struct { - init sync.Once + inited bool count int brushRenderTarget ebiten.RenderTargetID canvasRenderTarget ebiten.RenderTargetID @@ -42,14 +41,15 @@ func (g *Game) Update(gr ebiten.GraphicsContext) error { if ebiten.IsMouseButtonPressed(ebiten.MouseButtonLeft) { g.count++ } - g.init.Do(func() { + if !g.inited { gr.PushRenderTarget(g.brushRenderTarget) gr.Fill(0xff, 0xff, 0xff) gr.PopRenderTarget() gr.PushRenderTarget(g.canvasRenderTarget) gr.Fill(0xff, 0xff, 0xff) gr.PopRenderTarget() - }) + g.inited = true + } mx, my := ebiten.CursorPosition() diff --git a/gamecontext.go b/gamecontext.go index e6ddab55c..72cbd16d5 100644 --- a/gamecontext.go +++ b/gamecontext.go @@ -52,7 +52,7 @@ func NewRenderTargetID(width, height int, filter Filter) (RenderTargetID, error) return currentUI.newRenderTargetID(width, height, glFilter(filter)) } -// NewTextureID returns a new TextureID. -func NewTextureID(img image.Image, filter Filter) (TextureID, error) { - return currentUI.newTextureID(img, glFilter(filter)) +// NewTexture returns a new Texture. +func NewTexture(img image.Image, filter Filter) (*Texture, error) { + return currentUI.newTexture(img, glFilter(filter)) } diff --git a/graphics.go b/graphics.go index 163681736..fa39d4b0c 100644 --- a/graphics.go +++ b/graphics.go @@ -53,7 +53,7 @@ func DrawWhole(drawer Drawer, width, height int, geo GeometryMatrix, color Color type GraphicsContext interface { Clear() error Fill(r, g, b uint8) error - Texture(id TextureID) Drawer + Texture(texture *Texture) Drawer RenderTarget(id RenderTargetID) Drawer // TODO: ScreenRenderTarget() Drawer PushRenderTarget(id RenderTargetID) @@ -70,13 +70,21 @@ const ( FilterLinear ) +type Texture struct { + id int +} + +type RenderTarget struct { + id int +} + // TextureID represents an ID of a texture. -type TextureID int +/*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 diff --git a/graphicscontext.go b/graphicscontext.go index 466c50fb5..d4d991b8a 100644 --- a/graphicscontext.go +++ b/graphicscontext.go @@ -68,8 +68,8 @@ func (c *graphicsContext) Fill(r, g, b uint8) error { return idsInstance.fillRenderTarget(c.currentIDs[len(c.currentIDs)-1], r, g, b) } -func (c *graphicsContext) Texture(id TextureID) Drawer { - return &textureWithContext{id, c} +func (c *graphicsContext) Texture(texture *Texture) Drawer { + return &textureWithContext{texture, c} } func (c *graphicsContext) RenderTarget(id RenderTargetID) Drawer { @@ -104,11 +104,11 @@ func (c *graphicsContext) postUpdate() { } type textureWithContext struct { - id TextureID + texture *Texture context *graphicsContext } func (t *textureWithContext) Draw(parts []TexturePart, geo GeometryMatrix, color ColorMatrix) error { currentID := t.context.currentIDs[len(t.context.currentIDs)-1] - return idsInstance.drawTexture(currentID, t.id, parts, geo, color) + return idsInstance.drawTexture(currentID, t.texture, parts, geo, color) } diff --git a/ids.go b/ids.go index 5f5857570..05dad6528 100644 --- a/ids.go +++ b/ids.go @@ -26,25 +26,25 @@ import ( ) type ids struct { - textures map[TextureID]*opengl.Texture + textures map[*Texture]*opengl.Texture renderTargets map[RenderTargetID]*opengl.RenderTarget - renderTargetToTexture map[RenderTargetID]TextureID + renderTargetToTexture map[RenderTargetID]*Texture lastID int currentRenderTargetID RenderTargetID sync.RWMutex } var idsInstance = &ids{ - textures: map[TextureID]*opengl.Texture{}, + textures: map[*Texture]*opengl.Texture{}, renderTargets: map[RenderTargetID]*opengl.RenderTarget{}, - renderTargetToTexture: map[RenderTargetID]TextureID{}, + renderTargetToTexture: map[RenderTargetID]*Texture{}, currentRenderTargetID: -1, } -func (i *ids) textureAt(id TextureID) *opengl.Texture { +func (i *ids) textureAt(texture *Texture) *opengl.Texture { i.RLock() defer i.RUnlock() - return i.textures[id] + return i.textures[texture] } func (i *ids) renderTargetAt(id RenderTargetID) *opengl.RenderTarget { @@ -53,35 +53,35 @@ func (i *ids) renderTargetAt(id RenderTargetID) *opengl.RenderTarget { return i.renderTargets[id] } -func (i *ids) toTexture(id RenderTargetID) TextureID { +func (i *ids) toTexture(id RenderTargetID) *Texture { i.RLock() defer i.RUnlock() return i.renderTargetToTexture[id] } -func (i *ids) createTexture(img image.Image, filter int) (TextureID, error) { - texture, err := opengl.CreateTextureFromImage(img, filter) +func (i *ids) createTexture(img image.Image, filter int) (*Texture, error) { + glTexture, err := opengl.CreateTextureFromImage(img, filter) if err != nil { - return 0, err + return nil, err } i.Lock() defer i.Unlock() i.lastID++ - textureID := TextureID(i.lastID) - i.textures[textureID] = texture - return textureID, nil + texture := &Texture{i.lastID} + i.textures[texture] = glTexture + return texture, nil } func (i *ids) createRenderTarget(width, height int, filter int) (RenderTargetID, error) { - texture, err := opengl.CreateTexture(width, height, filter) + glTexture, err := opengl.CreateTexture(width, height, filter) if err != nil { return 0, err } // The current binded framebuffer can be changed. i.currentRenderTargetID = -1 - r, err := opengl.NewRenderTargetFromTexture(texture) + r, err := opengl.NewRenderTargetFromTexture(glTexture) if err != nil { return 0, err } @@ -89,13 +89,13 @@ func (i *ids) createRenderTarget(width, height int, filter int) (RenderTargetID, i.Lock() defer i.Unlock() i.lastID++ - textureID := TextureID(i.lastID) + texture := &Texture{i.lastID} i.lastID++ renderTargetID := RenderTargetID(i.lastID) - i.textures[textureID] = texture + i.textures[texture] = glTexture i.renderTargets[renderTargetID] = r - i.renderTargetToTexture[renderTargetID] = textureID + i.renderTargetToTexture[renderTargetID] = texture return renderTargetID, nil } @@ -116,15 +116,15 @@ func (i *ids) deleteRenderTarget(id RenderTargetID) { defer i.Unlock() renderTarget := i.renderTargets[id] - textureID := i.renderTargetToTexture[id] - texture := i.textures[textureID] + texture := i.renderTargetToTexture[id] + glTexture := i.textures[texture] renderTarget.Dispose() - texture.Dispose() + glTexture.Dispose() delete(i.renderTargets, id) delete(i.renderTargetToTexture, id) - delete(i.textures, textureID) + delete(i.textures, texture) } func (i *ids) fillRenderTarget(id RenderTargetID, r, g, b uint8) error { @@ -137,15 +137,15 @@ func (i *ids) fillRenderTarget(id RenderTargetID, r, g, b uint8) error { return nil } -func (i *ids) drawTexture(target RenderTargetID, id TextureID, parts []TexturePart, geo GeometryMatrix, color ColorMatrix) error { - texture := i.textureAt(id) +func (i *ids) drawTexture(target RenderTargetID, texture *Texture, parts []TexturePart, geo GeometryMatrix, color ColorMatrix) error { + glTexture := i.textureAt(texture) if err := i.setViewportIfNeeded(target); err != nil { return err } r := i.renderTargetAt(target) projectionMatrix := r.ProjectionMatrix() - quads := textureQuads(parts, texture.Width(), texture.Height()) - shader.DrawTexture(texture.Native(), projectionMatrix, quads, &geo, &color) + quads := textureQuads(parts, glTexture.Width(), glTexture.Height()) + shader.DrawTexture(glTexture.Native(), projectionMatrix, quads, &geo, &color) return nil } diff --git a/syncgraphicscontext.go b/syncgraphicscontext.go index 106c600c1..e5bf41e28 100644 --- a/syncgraphicscontext.go +++ b/syncgraphicscontext.go @@ -41,11 +41,11 @@ func (c *syncGraphicsContext) Fill(r, g, b uint8) (err error) { return } -func (c *syncGraphicsContext) Texture(id TextureID) (d Drawer) { +func (c *syncGraphicsContext) Texture(texture *Texture) (d Drawer) { c.syncer.Sync(func() { d = &drawer{ syncer: c.syncer, - innerDrawer: c.innerGraphicsContext.Texture(id), + innerDrawer: c.innerGraphicsContext.Texture(texture), } }) return diff --git a/ui.go b/ui.go index 229453acd..5fea34b51 100644 --- a/ui.go +++ b/ui.go @@ -127,13 +127,13 @@ func (u *ui) draw(f func(GraphicsContext) error) (err error) { return } -func (u *ui) newTextureID(img image.Image, filter int) (TextureID, error) { - var id TextureID +func (u *ui) newTexture(img image.Image, filter int) (*Texture, error) { + var texture *Texture var err error u.use(func() { - id, err = idsInstance.createTexture(img, filter) + texture, err = idsInstance.createTexture(img, filter) }) - return id, err + return texture, err } func (u *ui) newRenderTargetID(width, height int, filter int) (RenderTargetID, error) {