Replace TextureID with Texture

This commit is contained in:
Hajime Hoshi 2014-12-17 21:49:28 +09:00
parent 33cb234ae1
commit eb11831585
11 changed files with 87 additions and 61 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

52
ids.go
View File

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

View File

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

8
ui.go
View File

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