2014-01-07 16:45:53 +01:00
|
|
|
package graphics
|
|
|
|
|
|
|
|
import (
|
|
|
|
"image"
|
|
|
|
"image/draw"
|
|
|
|
)
|
|
|
|
|
|
|
|
type TextureQuad struct {
|
|
|
|
VertexX1 float32
|
|
|
|
VertexX2 float32
|
|
|
|
VertexY1 float32
|
|
|
|
VertexY2 float32
|
|
|
|
TextureCoordU1 float32
|
|
|
|
TextureCoordU2 float32
|
|
|
|
TextureCoordV1 float32
|
|
|
|
TextureCoordV2 float32
|
|
|
|
}
|
|
|
|
|
|
|
|
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
|
|
|
|
}
|
|
|
|
|
|
|
|
func AdjustSizeForTexture(size int) int {
|
|
|
|
return int(NextPowerOf2(uint64(size)))
|
|
|
|
}
|
|
|
|
|
|
|
|
func AdjustImageForTexture(img image.Image) *image.NRGBA {
|
|
|
|
width, height := img.Bounds().Size().X, img.Bounds().Size().Y
|
|
|
|
adjustedImageBounds := image.Rectangle{
|
|
|
|
image.ZP,
|
|
|
|
image.Point{
|
|
|
|
AdjustSizeForTexture(width),
|
|
|
|
AdjustSizeForTexture(height),
|
|
|
|
},
|
|
|
|
}
|
|
|
|
if nrgba, ok := img.(*image.NRGBA); ok &&
|
|
|
|
img.Bounds() == adjustedImageBounds {
|
|
|
|
return nrgba
|
|
|
|
}
|
|
|
|
|
|
|
|
adjustedImage := image.NewNRGBA(adjustedImageBounds)
|
|
|
|
dstBounds := image.Rectangle{
|
|
|
|
image.ZP,
|
|
|
|
img.Bounds().Size(),
|
|
|
|
}
|
|
|
|
draw.Draw(adjustedImage, dstBounds, img, image.ZP, draw.Src)
|
|
|
|
return adjustedImage
|
|
|
|
}
|
2014-01-08 06:37:07 +01:00
|
|
|
|
|
|
|
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)
|
2014-01-08 10:58:15 +01:00
|
|
|
u2 := u(part.Source.X+part.Source.Width, width)
|
2014-01-08 06:37:07 +01:00
|
|
|
v1 := v(part.Source.Y, height)
|
2014-01-08 10:58:15 +01:00
|
|
|
v2 := v(part.Source.Y+part.Source.Height, height)
|
2014-01-08 06:37:07 +01:00
|
|
|
quad := TextureQuad{x1, x2, y1, y2, u1, u2, v1, v2}
|
|
|
|
quads = append(quads, quad)
|
|
|
|
}
|
|
|
|
return quads
|
|
|
|
}
|