Remove graphics/texture

This commit is contained in:
Hajime Hoshi 2014-01-08 14:37:07 +09:00
parent 05dede71e7
commit 2ed01a6232
7 changed files with 89 additions and 166 deletions

View File

@ -4,23 +4,22 @@ import (
"github.com/hajimehoshi/go-ebiten/graphics" "github.com/hajimehoshi/go-ebiten/graphics"
"github.com/hajimehoshi/go-ebiten/graphics/opengl/rendertarget" "github.com/hajimehoshi/go-ebiten/graphics/opengl/rendertarget"
"github.com/hajimehoshi/go-ebiten/graphics/opengl/texture" "github.com/hajimehoshi/go-ebiten/graphics/opengl/texture"
gtexture "github.com/hajimehoshi/go-ebiten/graphics/texture"
"image" "image"
"sync" "sync"
) )
type ids struct { type ids struct {
lock sync.RWMutex lock sync.RWMutex
textures map[graphics.TextureId]*gtexture.Texture textures map[graphics.TextureId]*texture.Texture
renderTargets map[graphics.RenderTargetId]*gtexture.RenderTarget renderTargets map[graphics.RenderTargetId]*rendertarget.RenderTarget
renderTargetToTexture map[graphics.RenderTargetId]graphics.TextureId renderTargetToTexture map[graphics.RenderTargetId]graphics.TextureId
counts chan int counts chan int
} }
func newIds() *ids { func newIds() *ids {
ids := &ids{ ids := &ids{
textures: map[graphics.TextureId]*gtexture.Texture{}, textures: map[graphics.TextureId]*texture.Texture{},
renderTargets: map[graphics.RenderTargetId]*gtexture.RenderTarget{}, renderTargets: map[graphics.RenderTargetId]*rendertarget.RenderTarget{},
renderTargetToTexture: map[graphics.RenderTargetId]graphics.TextureId{}, renderTargetToTexture: map[graphics.RenderTargetId]graphics.TextureId{},
counts: make(chan int), counts: make(chan int),
} }
@ -32,13 +31,13 @@ func newIds() *ids {
return ids return ids
} }
func (i *ids) TextureAt(id graphics.TextureId) *gtexture.Texture { func (i *ids) TextureAt(id graphics.TextureId) *texture.Texture {
i.lock.RLock() i.lock.RLock()
defer i.lock.RUnlock() defer i.lock.RUnlock()
return i.textures[id] return i.textures[id]
} }
func (i *ids) RenderTargetAt(id graphics.RenderTargetId) *gtexture.RenderTarget { func (i *ids) RenderTargetAt(id graphics.RenderTargetId) *rendertarget.RenderTarget {
i.lock.RLock() i.lock.RLock()
defer i.lock.RUnlock() defer i.lock.RUnlock()
return i.renderTargets[id] return i.renderTargets[id]
@ -84,6 +83,6 @@ func (i *ids) CreateRenderTarget(width, height int, filter graphics.Filter) (
func (i *ids) DeleteRenderTarget(id graphics.RenderTargetId) { func (i *ids) DeleteRenderTarget(id graphics.RenderTargetId) {
renderTarget := i.renderTargets[id] renderTarget := i.renderTargets[id]
rendertarget.Dispose(renderTarget) renderTarget.Dispose()
delete(i.renderTargets, id) delete(i.renderTargets, id)
} }

View File

@ -12,13 +12,12 @@ import (
"github.com/hajimehoshi/go-ebiten/graphics/opengl/rendertarget" "github.com/hajimehoshi/go-ebiten/graphics/opengl/rendertarget"
"github.com/hajimehoshi/go-ebiten/graphics/opengl/shader" "github.com/hajimehoshi/go-ebiten/graphics/opengl/shader"
"github.com/hajimehoshi/go-ebiten/graphics/opengl/texture" "github.com/hajimehoshi/go-ebiten/graphics/opengl/texture"
gtexture "github.com/hajimehoshi/go-ebiten/graphics/texture"
) )
type Offscreen struct { type Offscreen struct {
screenHeight int screenHeight int
screenScale int screenScale int
mainFramebufferTexture *gtexture.RenderTarget mainFramebufferTexture *rendertarget.RenderTarget
projectionMatrix [16]float32 projectionMatrix [16]float32
} }
@ -43,34 +42,36 @@ func New(screenWidth, screenHeight, screenScale int) *Offscreen {
return offscreen return offscreen
} }
func (o *Offscreen) Set(rt *gtexture.RenderTarget) { func (o *Offscreen) Set(rt *rendertarget.RenderTarget) {
C.glFlush() C.glFlush()
rt.SetAsOffscreen(&setter{o, rt == o.mainFramebufferTexture}) // TODO: Calc x, y, width, heigth at another function
o.doSet(rt.Framebuffer, 0, 0,
graphics.AdjustSizeForTexture(rt.Width), graphics.AdjustSizeForTexture(rt.Height))
} }
func (o *Offscreen) SetMainFramebuffer() { func (o *Offscreen) SetMainFramebuffer() {
o.Set(o.mainFramebufferTexture) o.Set(o.mainFramebufferTexture)
} }
func (o *Offscreen) DrawTexture(texture *gtexture.Texture, func (o *Offscreen) DrawTexture(texture *texture.Texture,
geometryMatrix matrix.Geometry, colorMatrix matrix.Color) { geometryMatrix matrix.Geometry, colorMatrix matrix.Color) {
texture.Draw(&drawable{o, geometryMatrix, colorMatrix}) quad := graphics.TextureQuadForTexture(texture.Width, texture.Height)
shader.DrawTexture(texture.Native,
o.projectionMatrix, []graphics.TextureQuad{quad},
geometryMatrix, colorMatrix)
} }
func (o *Offscreen) DrawTextureParts(texture *gtexture.Texture, func (o *Offscreen) DrawTextureParts(texture *texture.Texture,
parts []graphics.TexturePart, parts []graphics.TexturePart,
geometryMatrix matrix.Geometry, colorMatrix matrix.Color) { geometryMatrix matrix.Geometry, colorMatrix matrix.Color) {
texture.DrawParts(parts, &drawable{o, geometryMatrix, colorMatrix}) quads := graphics.TextureQuadsForTextureParts(parts, texture.Width, texture.Height)
shader.DrawTexture(texture.Native,
o.projectionMatrix, quads,
geometryMatrix, colorMatrix)
} }
type setter struct { func (o *Offscreen) doSet(framebuffer rendertarget.Framebuffer, x, y, width, height int) {
offscreen *Offscreen C.glBindFramebuffer(C.GL_FRAMEBUFFER, C.GLuint(framebuffer))
usingMainFramebuffer bool
}
func (s *setter) Set(framebuffer interface{}, x, y, width, height int) {
f := framebuffer.(rendertarget.Framebuffer)
C.glBindFramebuffer(C.GL_FRAMEBUFFER, C.GLuint(f))
err := C.glCheckFramebufferStatus(C.GL_FRAMEBUFFER) err := C.glCheckFramebufferStatus(C.GL_FRAMEBUFFER)
if err != C.GL_FRAMEBUFFER_COMPLETE { if err != C.GL_FRAMEBUFFER_COMPLETE {
panic(fmt.Sprintf("glBindFramebuffer failed: %d", err)) panic(fmt.Sprintf("glBindFramebuffer failed: %d", err))
@ -83,8 +84,8 @@ func (s *setter) Set(framebuffer interface{}, x, y, width, height int) {
C.GLsizei(width), C.GLsizei(height)) C.GLsizei(width), C.GLsizei(height))
matrix := graphics.OrthoProjectionMatrix(x, width, y, height) matrix := graphics.OrthoProjectionMatrix(x, width, y, height)
if s.usingMainFramebuffer { if framebuffer == o.mainFramebufferTexture.Framebuffer {
actualScreenHeight := s.offscreen.screenHeight * s.offscreen.screenScale actualScreenHeight := o.screenHeight * o.screenScale
// Flip Y and move to fit with the top of the window. // Flip Y and move to fit with the top of the window.
matrix[1][1] *= -1 matrix[1][1] *= -1
matrix[1][3] += float64(actualScreenHeight) / float64(height) * 2 matrix[1][3] += float64(actualScreenHeight) / float64(height) * 2
@ -92,19 +93,7 @@ func (s *setter) Set(framebuffer interface{}, x, y, width, height int) {
for j := 0; j < 4; j++ { for j := 0; j < 4; j++ {
for i := 0; i < 4; i++ { for i := 0; i < 4; i++ {
s.offscreen.projectionMatrix[i+j*4] = float32(matrix[i][j]) o.projectionMatrix[i+j*4] = float32(matrix[i][j])
} }
} }
} }
type drawable struct {
offscreen *Offscreen
geometryMatrix matrix.Geometry
colorMatrix matrix.Color
}
func (d *drawable) Draw(native interface{}, quads []graphics.TextureQuad) {
shader.DrawTexture(native.(texture.Native),
d.offscreen.projectionMatrix, quads,
d.geometryMatrix, d.colorMatrix)
}

View File

@ -7,11 +7,16 @@ import "C"
import ( import (
"github.com/hajimehoshi/go-ebiten/graphics" "github.com/hajimehoshi/go-ebiten/graphics"
"github.com/hajimehoshi/go-ebiten/graphics/opengl/texture" "github.com/hajimehoshi/go-ebiten/graphics/opengl/texture"
gtexture "github.com/hajimehoshi/go-ebiten/graphics/texture"
) )
type Framebuffer C.GLuint type Framebuffer C.GLuint
type RenderTarget struct {
Framebuffer
Width int
Height int
}
func createFramebuffer(nativeTexture C.GLuint) Framebuffer { func createFramebuffer(nativeTexture C.GLuint) Framebuffer {
framebuffer := C.GLuint(0) framebuffer := C.GLuint(0)
C.glGenFramebuffers(1, &framebuffer) C.glGenFramebuffers(1, &framebuffer)
@ -37,35 +42,22 @@ func createFramebuffer(nativeTexture C.GLuint) Framebuffer {
return Framebuffer(framebuffer) return Framebuffer(framebuffer)
} }
type framebufferCreator struct {
}
func (f *framebufferCreator) Create(native interface{}) interface{} {
return createFramebuffer(C.GLuint(native.(texture.Native)))
}
func Create(width, height int, filter graphics.Filter) ( func Create(width, height int, filter graphics.Filter) (
*gtexture.RenderTarget, *gtexture.Texture, error) { *RenderTarget, *texture.Texture, error) {
tex, err := texture.Create(width, height, filter) tex, err := texture.Create(width, height, filter)
if err != nil { if err != nil {
return nil, nil, err return nil, nil, err
} }
return tex.CreateRenderTarget(&framebufferCreator{}), tex, nil framebuffer := createFramebuffer(C.GLuint(tex.Native))
return &RenderTarget{framebuffer, tex.Width, tex.Height}, tex, nil
} }
func CreateWithFramebuffer(width, height int, framebuffer Framebuffer) ( func CreateWithFramebuffer(width, height int, framebuffer Framebuffer) (
*gtexture.RenderTarget, error) { *RenderTarget, error) {
return gtexture.NewRenderTarget(framebuffer, width, height), nil return &RenderTarget{framebuffer, width, height}, nil
} }
type disposer struct { func (r *RenderTarget) Dispose() {
} f := C.GLuint(r.Framebuffer)
C.glDeleteFramebuffers(1, &f)
func (d *disposer) Dispose(native interface{}) {
framebuffer := C.GLuint(native.(Framebuffer))
C.glDeleteFramebuffers(1, &framebuffer)
}
func Dispose(renderTarget *gtexture.RenderTarget) {
renderTarget.Dispose(&disposer{})
} }

View File

@ -6,13 +6,18 @@ package texture
import "C" import "C"
import ( import (
"github.com/hajimehoshi/go-ebiten/graphics" "github.com/hajimehoshi/go-ebiten/graphics"
gtexture "github.com/hajimehoshi/go-ebiten/graphics/texture"
"image" "image"
"unsafe" "unsafe"
) )
type Native C.GLuint type Native C.GLuint
type Texture struct {
Native
Width int
Height int
}
func createNativeTexture(textureWidth, textureHeight int, pixels []uint8, func createNativeTexture(textureWidth, textureHeight int, pixels []uint8,
filter graphics.Filter) Native { filter graphics.Filter) Native {
nativeTexture := C.GLuint(0) nativeTexture := C.GLuint(0)
@ -48,16 +53,16 @@ func createNativeTexture(textureWidth, textureHeight int, pixels []uint8,
return Native(nativeTexture) return Native(nativeTexture)
} }
func Create(width, height int, filter graphics.Filter) (*gtexture.Texture, error) { func Create(width, height int, filter graphics.Filter) (*Texture, error) {
native := createNativeTexture( native := createNativeTexture(
graphics.AdjustSizeForTexture(width), graphics.AdjustSizeForTexture(width),
graphics.AdjustSizeForTexture(height), nil, filter) graphics.AdjustSizeForTexture(height), nil, filter)
return gtexture.New(native, width, height), nil return &Texture{native, width, height}, nil
} }
func CreateFromImage(img image.Image, filter graphics.Filter) (*gtexture.Texture, error) { func CreateFromImage(img image.Image, filter graphics.Filter) (*Texture, error) {
adjustedImage := graphics.AdjustImageForTexture(img) adjustedImage := graphics.AdjustImageForTexture(img)
size := adjustedImage.Bounds().Size() size := adjustedImage.Bounds().Size()
native := createNativeTexture(size.X, size.Y, adjustedImage.Pix, filter) native := createNativeTexture(size.X, size.Y, adjustedImage.Pix, filter)
return gtexture.New(native, size.X, size.Y), nil return &Texture{native, size.X, size.Y}, nil
} }

View File

@ -1,35 +0,0 @@
package texture
import (
"github.com/hajimehoshi/go-ebiten/graphics"
)
type RenderTarget struct {
framebuffer interface{}
offscreenWidth int
offscreenHeight int
}
func NewRenderTarget(framebuffer interface{}, width, height int) *RenderTarget {
return &RenderTarget{
framebuffer: framebuffer,
offscreenWidth: graphics.AdjustSizeForTexture(width),
offscreenHeight: graphics.AdjustSizeForTexture(height),
}
}
type OffscreenSetter interface {
Set(framebuffer interface{}, x, y, width, height int)
}
func (r *RenderTarget) SetAsOffscreen(setter OffscreenSetter) {
setter.Set(r.framebuffer, 0, 0, r.offscreenWidth, r.offscreenHeight)
}
type RenderTargetDisposer interface {
Dispose(framebuffer interface{})
}
func (r *RenderTarget) Dispose(disposer RenderTargetDisposer) {
disposer.Dispose(r.framebuffer)
}

View File

@ -1,65 +0,0 @@
package texture
import (
"github.com/hajimehoshi/go-ebiten/graphics"
)
type Texture struct {
native interface{}
width int
height int
}
func New(native interface{}, width, height int) *Texture {
return &Texture{native, width, height}
}
func (texture *Texture) u(x int) float32 {
return float32(x) / float32(graphics.AdjustSizeForTexture(texture.width))
}
func (texture *Texture) v(y int) float32 {
return float32(y) / float32(graphics.AdjustSizeForTexture(texture.height))
}
type Drawable interface {
Draw(native interface{}, quads []graphics.TextureQuad)
}
func (texture *Texture) Draw(drawable Drawable) {
x1 := float32(0)
x2 := float32(texture.width)
y1 := float32(0)
y2 := float32(texture.height)
u1 := texture.u(0)
u2 := texture.u(texture.width)
v1 := texture.v(0)
v2 := texture.v(texture.height)
quad := graphics.TextureQuad{x1, x2, y1, y2, u1, u2, v1, v2}
drawable.Draw(texture.native, []graphics.TextureQuad{quad})
}
func (texture *Texture) DrawParts(parts []graphics.TexturePart, drawable Drawable) {
quads := []graphics.TextureQuad{}
for _, part := range parts {
x1 := float32(part.LocationX)
x2 := float32(part.LocationX + part.Source.Width)
y1 := float32(part.LocationY)
y2 := float32(part.LocationY + part.Source.Height)
u1 := texture.u(part.Source.X)
u2 := texture.u(part.Source.X + part.Source.Width)
v1 := texture.v(part.Source.Y)
v2 := texture.v(part.Source.Y + part.Source.Height)
quad := graphics.TextureQuad{x1, x2, y1, y2, u1, u2, v1, v2}
quads = append(quads, quad)
}
drawable.Draw(texture.native, quads)
}
type FramebufferCreator interface {
Create(native interface{}) interface{}
}
func (texture *Texture) CreateRenderTarget(creator FramebufferCreator) *RenderTarget {
return NewRenderTarget(creator.Create(texture.native), texture.width, texture.height)
}

View File

@ -53,3 +53,41 @@ func AdjustImageForTexture(img image.Image) *image.NRGBA {
draw.Draw(adjustedImage, dstBounds, img, image.ZP, draw.Src) draw.Draw(adjustedImage, dstBounds, img, image.ZP, draw.Src)
return adjustedImage return adjustedImage
} }
func u(x int, width int) float32 {
return float32(x) / float32(AdjustSizeForTexture(width))
}
func v(y int, height int) float32 {
return float32(y) / float32(AdjustSizeForTexture(height))
}
// TODO: Remove this if possible
func TextureQuadForTexture(width, height int) TextureQuad {
x1 := float32(0)
x2 := float32(width)
y1 := float32(0)
y2 := float32(height)
u1 := u(0, width)
u2 := u(width, width)
v1 := v(0, height)
v2 := v(height, height)
return TextureQuad{x1, x2, y1, y2, u1, u2, v1, v2}
}
func TextureQuadsForTextureParts(parts []TexturePart, width, height int) []TextureQuad {
quads := []TextureQuad{}
for _, part := range parts {
x1 := float32(part.LocationX)
x2 := float32(part.LocationX + part.Source.Width)
y1 := float32(part.LocationY)
y2 := float32(part.LocationY + part.Source.Height)
u1 := u(part.Source.X, width)
u2 := u(part.Source.X + part.Source.Width, width)
v1 := v(part.Source.Y, height)
v2 := v(part.Source.Y + part.Source.Height, height)
quad := TextureQuad{x1, x2, y1, y2, u1, u2, v1, v2}
quads = append(quads, quad)
}
return quads
}