ebiten/graphics/texture/texture.go
2013-10-27 21:29:39 +09:00

133 lines
3.1 KiB
Go

package texture
import (
"github.com/hajimehoshi/go-ebiten/graphics"
"image"
"image/draw"
)
func nextPowerOf2(x uint64) uint64 {
x -= 1
x |= (x >> 1)
x |= (x >> 2)
x |= (x >> 4)
x |= (x >> 8)
x |= (x >> 16)
x |= (x >> 32)
return x + 1
}
type Texture struct {
native interface{}
width int
height int
}
func New(width, height int, create func(textureWidth, textureHeight int) (
interface{}, error)) (*Texture, error) {
texture := &Texture{
width: width,
height: height,
}
var err error
texture.native, err = create(texture.textureWidth(),
texture.textureHeight())
if err != nil {
return nil, err
}
return texture, nil
}
func NewFromImage(img image.Image, create func(img *image.NRGBA) (
interface{}, error)) (*Texture, error) {
size := img.Bounds().Size()
width, height := size.X, size.Y
texture := &Texture{
width: width,
height: height,
}
adjustedImageBound := image.Rectangle{
image.ZP,
image.Point{texture.textureWidth(), texture.textureHeight()},
}
adjustedImage := image.NewNRGBA(adjustedImageBound)
dstBound := image.Rectangle{
image.ZP,
img.Bounds().Size(),
}
draw.Draw(adjustedImage, dstBound, img, image.ZP, draw.Src)
var err error
texture.native, err = create(adjustedImage)
if err != nil {
return nil, err
}
return texture, nil
}
func (texture *Texture) textureWidth() int {
return int(nextPowerOf2(uint64(texture.width)))
}
func (texture *Texture) textureHeight() int {
return int(nextPowerOf2(uint64(texture.height)))
}
func (texture *Texture) u(x int) float32 {
return float32(x) / float32(texture.textureWidth())
}
func (texture *Texture) v(y int) float32 {
return float32(y) / float32(texture.textureHeight())
}
func (texture *Texture) SetAsViewport(setter func(x, y, width, height int)) {
setter(0, 0, texture.textureWidth(), texture.textureHeight())
}
type Quad struct {
VertexX1 float32
VertexX2 float32
VertexY1 float32
VertexY2 float32
TextureCoordU1 float32
TextureCoordU2 float32
TextureCoordV1 float32
TextureCoordV2 float32
}
func (texture *Texture) Draw(draw func(native interface{}, quads []Quad)) {
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 := Quad{x1, x2, y1, y2, u1, u2, v1, v2}
draw(texture.native, []Quad{quad})
}
func (texture *Texture) DrawParts(parts []graphics.TexturePart,
draw func(native interface{}, quads []Quad)) {
quads := []Quad{}
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 := Quad{x1, x2, y1, y2, u1, u2, v1, v2}
quads = append(quads, quad)
}
draw(texture.native, quads)
}
func (texture *Texture) CreateFramebuffer(
create func(native interface{}) interface{}) interface{} {
return create(texture.native)
}