mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-12-24 02:38:53 +01:00
Add graphics.Texture
This commit is contained in:
parent
532b52d389
commit
eda572d03e
@ -8,7 +8,7 @@ import (
|
||||
|
||||
type Game interface {
|
||||
Update()
|
||||
Draw(g graphics.GraphicsContext, offscreen graphics.Texture)
|
||||
Draw(g graphics.GraphicsContext, offscreen *graphics.Texture)
|
||||
}
|
||||
|
||||
type UI interface {
|
||||
@ -22,7 +22,7 @@ func OpenGLRun(game Game, ui UI) {
|
||||
ch := make(chan bool, 1)
|
||||
device := opengl.NewDevice(
|
||||
ui.ScreenWidth(), ui.ScreenHeight(), ui.ScreenScale(),
|
||||
func(g graphics.GraphicsContext, offscreen graphics.Texture) {
|
||||
func(g graphics.GraphicsContext, offscreen *graphics.Texture) {
|
||||
ticket := <-ch
|
||||
game.Draw(g, offscreen)
|
||||
ch<- ticket
|
||||
|
@ -91,7 +91,7 @@ func (ui *GlutUI) Run(device graphics.Device) {
|
||||
}
|
||||
|
||||
type DemoGame struct {
|
||||
ebitenTexture graphics.Texture
|
||||
ebitenTexture *graphics.Texture
|
||||
x int
|
||||
}
|
||||
|
||||
@ -108,13 +108,12 @@ func (game *DemoGame) Update() {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// TODO: It looks strange to get a texture from the device.
|
||||
game.ebitenTexture = currentUI.device.NewTextureFromImage(img)
|
||||
game.ebitenTexture = graphics.NewTextureFromImage(img)
|
||||
}
|
||||
game.x++
|
||||
}
|
||||
|
||||
func (game *DemoGame) Draw(g graphics.GraphicsContext, offscreen graphics.Texture) {
|
||||
func (game *DemoGame) Draw(g graphics.GraphicsContext, offscreen *graphics.Texture) {
|
||||
g.Fill(&color.RGBA{R: 128, G: 128, B: 255, A: 255})
|
||||
if game.ebitenTexture == nil {
|
||||
return
|
||||
@ -123,7 +122,7 @@ func (game *DemoGame) Draw(g graphics.GraphicsContext, offscreen graphics.Textur
|
||||
geometryMatrix.SetTx(float64(game.x))
|
||||
geometryMatrix.SetTy(float64(game.x))
|
||||
g.DrawTexture(game.ebitenTexture,
|
||||
0, 0, game.ebitenTexture.Width(), game.ebitenTexture.Height(),
|
||||
0, 0, game.ebitenTexture.Width, game.ebitenTexture.Height,
|
||||
geometryMatrix,
|
||||
graphics.IdentityColorMatrix())
|
||||
}
|
||||
|
@ -7,23 +7,28 @@ import (
|
||||
|
||||
type Device interface {
|
||||
Update()
|
||||
// TODO: Move somewhere
|
||||
NewTexture(width, height int) Texture
|
||||
NewTextureFromImage(img image.Image) Texture
|
||||
}
|
||||
|
||||
type GraphicsContext interface {
|
||||
Clear()
|
||||
Fill(color color.Color)
|
||||
DrawTexture(texture Texture,
|
||||
DrawTexture(texture *Texture,
|
||||
srcX, srcY, srcWidth, srcHeight int,
|
||||
geometryMatrix *GeometryMatrix, colorMatrix *ColorMatrix)
|
||||
SetOffscreen(texture Texture)
|
||||
SetOffscreen(texture *Texture)
|
||||
}
|
||||
|
||||
type Texture interface {
|
||||
Width() int
|
||||
Height() int
|
||||
TextureWidth() int
|
||||
TextureHeight() int
|
||||
type Texture struct {
|
||||
Width int
|
||||
Height int
|
||||
Image image.Image
|
||||
}
|
||||
|
||||
func NewTexture(width, height int) *Texture {
|
||||
return &Texture{width, height, nil}
|
||||
}
|
||||
|
||||
func NewTextureFromImage(img image.Image) *Texture {
|
||||
size := img.Bounds().Size()
|
||||
return &Texture{size.X, size.Y, img}
|
||||
}
|
||||
|
@ -6,7 +6,6 @@ package opengl
|
||||
// #include <stdlib.h>
|
||||
import "C"
|
||||
import (
|
||||
"image"
|
||||
"github.com/hajimehoshi/go-ebiten/graphics"
|
||||
)
|
||||
|
||||
@ -15,13 +14,13 @@ type Device struct {
|
||||
screenHeight int
|
||||
screenScale int
|
||||
graphicsContext *GraphicsContext
|
||||
offscreenTexture *Texture
|
||||
drawFunc func(graphics.GraphicsContext, graphics.Texture)
|
||||
offscreenTexture *graphics.Texture
|
||||
drawFunc func(graphics.GraphicsContext, *graphics.Texture)
|
||||
funcs []func()
|
||||
}
|
||||
|
||||
func NewDevice(screenWidth, screenHeight, screenScale int,
|
||||
drawFunc func(graphics.GraphicsContext, graphics.Texture)) *Device {
|
||||
drawFunc func(graphics.GraphicsContext, *graphics.Texture)) *Device {
|
||||
device := &Device{
|
||||
screenWidth: screenWidth,
|
||||
screenHeight: screenHeight,
|
||||
@ -30,16 +29,11 @@ func NewDevice(screenWidth, screenHeight, screenScale int,
|
||||
drawFunc: drawFunc,
|
||||
funcs: []func(){},
|
||||
}
|
||||
device.offscreenTexture = device.NewTexture(screenWidth, screenHeight).(*Texture)
|
||||
device.offscreenTexture = graphics.NewTexture(screenWidth, screenHeight)
|
||||
return device
|
||||
}
|
||||
|
||||
func (device *Device) Update() {
|
||||
for _, f := range device.funcs {
|
||||
f()
|
||||
}
|
||||
device.funcs = []func(){}
|
||||
|
||||
g := device.graphicsContext
|
||||
C.glEnable(C.GL_TEXTURE_2D)
|
||||
C.glTexParameteri(C.GL_TEXTURE_2D, C.GL_TEXTURE_MIN_FILTER, C.GL_NEAREST)
|
||||
@ -61,25 +55,3 @@ func (device *Device) Update() {
|
||||
geometryMatrix, graphics.IdentityColorMatrix())
|
||||
g.flush()
|
||||
}
|
||||
|
||||
func (device *Device) NewTexture(width, height int) graphics.Texture {
|
||||
return createTexture(device, width, height, nil)
|
||||
}
|
||||
|
||||
func (device *Device) NewTextureFromImage(img image.Image) graphics.Texture {
|
||||
var pix []uint8
|
||||
switch img.(type) {
|
||||
case *image.RGBA:
|
||||
pix = img.(*image.RGBA).Pix
|
||||
case *image.NRGBA:
|
||||
pix = img.(*image.NRGBA).Pix
|
||||
default:
|
||||
panic("image should be RGBA or NRGBA")
|
||||
}
|
||||
size := img.Bounds().Size()
|
||||
return createTexture(device, size.X, size.Y, pix)
|
||||
}
|
||||
|
||||
func (device *Device) executeWhenDrawing(f func()) {
|
||||
device.funcs = append(device.funcs, f)
|
||||
}
|
||||
|
@ -41,6 +41,23 @@ func newGraphicsContext(screenWidth, screenHeight, screenScale int) *GraphicsCon
|
||||
return context
|
||||
}
|
||||
|
||||
var glTextureCache = map[*graphics.Texture]*Texture{}
|
||||
|
||||
func glTexture(tex *graphics.Texture) *Texture {
|
||||
if glTex, ok := glTextureCache[tex]; ok {
|
||||
return glTex
|
||||
}
|
||||
|
||||
var glTex *Texture = nil
|
||||
if tex.Image != nil {
|
||||
glTex = newTextureFromImage(tex.Image)
|
||||
} else {
|
||||
glTex = newTexture(tex.Width, tex.Height)
|
||||
}
|
||||
glTextureCache[tex] = glTex
|
||||
return glTex
|
||||
}
|
||||
|
||||
func (context *GraphicsContext) Clear() {
|
||||
C.glClearColor(0, 0, 0, 1)
|
||||
C.glClear(C.GL_COLOR_BUFFER_BIT)
|
||||
@ -61,13 +78,13 @@ func (context *GraphicsContext) DrawRect(x, y, width, height int, clr color.Colo
|
||||
// TODO: implement!
|
||||
}
|
||||
|
||||
func (context *GraphicsContext) DrawTexture(tex graphics.Texture,
|
||||
func (context *GraphicsContext) DrawTexture(tex *graphics.Texture,
|
||||
srcX, srcY, srcWidth, srcHeight int,
|
||||
geometryMatrix *graphics.GeometryMatrix, colorMatrix *graphics.ColorMatrix) {
|
||||
geometryMatrix = geometryMatrix.Clone()
|
||||
colorMatrix = colorMatrix.Clone()
|
||||
|
||||
texture := tex.(*Texture)
|
||||
texture := glTexture(tex)
|
||||
|
||||
context.setShaderProgram(geometryMatrix, colorMatrix)
|
||||
C.glBindTexture(C.GL_TEXTURE_2D, texture.id)
|
||||
@ -119,12 +136,12 @@ func abs(x int) int {
|
||||
return x
|
||||
}
|
||||
|
||||
func (context *GraphicsContext) SetOffscreen(tex graphics.Texture) {
|
||||
func (context *GraphicsContext) SetOffscreen(tex *graphics.Texture) {
|
||||
C.glFlush()
|
||||
|
||||
var texture *Texture = nil
|
||||
if tex != nil {
|
||||
texture = tex.(*Texture)
|
||||
texture = glTexture(tex)
|
||||
}
|
||||
framebuffer := C.GLuint(0)
|
||||
if texture != nil {
|
||||
|
@ -5,6 +5,7 @@ package opengl
|
||||
// #include <OpenGL/gl.h>
|
||||
import "C"
|
||||
import (
|
||||
"image"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
@ -27,7 +28,7 @@ type Texture struct {
|
||||
textureHeight int
|
||||
}
|
||||
|
||||
func createTexture(device *Device, width, height int, pixels []uint8) *Texture{
|
||||
func createTexture(width, height int, pixels []uint8) *Texture {
|
||||
textureWidth := int(Clp2(uint64(width)))
|
||||
textureHeight := int(Clp2(uint64(height)))
|
||||
if pixels != nil {
|
||||
@ -46,50 +47,46 @@ func createTexture(device *Device, width, height int, pixels []uint8) *Texture{
|
||||
textureHeight: textureHeight,
|
||||
}
|
||||
|
||||
device.executeWhenDrawing(func() {
|
||||
textureID := C.GLuint(0)
|
||||
C.glGenTextures(1, (*C.GLuint)(&textureID))
|
||||
if textureID == 0 {
|
||||
panic("glGenTexture failed")
|
||||
}
|
||||
C.glPixelStorei(C.GL_UNPACK_ALIGNMENT, 4)
|
||||
C.glBindTexture(C.GL_TEXTURE_2D, C.GLuint(textureID))
|
||||
|
||||
ptr := unsafe.Pointer(nil)
|
||||
if pixels != nil {
|
||||
ptr = unsafe.Pointer(&pixels[0])
|
||||
}
|
||||
C.glTexImage2D(C.GL_TEXTURE_2D, 0, C.GL_RGBA,
|
||||
C.GLsizei(textureWidth), C.GLsizei(textureHeight),
|
||||
0, C.GL_RGBA, C.GL_UNSIGNED_BYTE, ptr)
|
||||
textureID := C.GLuint(0)
|
||||
C.glGenTextures(1, (*C.GLuint)(&textureID))
|
||||
if textureID == 0 {
|
||||
panic("glGenTexture failed")
|
||||
}
|
||||
C.glPixelStorei(C.GL_UNPACK_ALIGNMENT, 4)
|
||||
C.glBindTexture(C.GL_TEXTURE_2D, C.GLuint(textureID))
|
||||
|
||||
ptr := unsafe.Pointer(nil)
|
||||
if pixels != nil {
|
||||
ptr = unsafe.Pointer(&pixels[0])
|
||||
}
|
||||
C.glTexImage2D(C.GL_TEXTURE_2D, 0, C.GL_RGBA,
|
||||
C.GLsizei(textureWidth), C.GLsizei(textureHeight),
|
||||
0, C.GL_RGBA, C.GL_UNSIGNED_BYTE, ptr)
|
||||
|
||||
C.glTexParameteri(C.GL_TEXTURE_2D, C.GL_TEXTURE_MAG_FILTER, C.GL_LINEAR)
|
||||
C.glTexParameteri(C.GL_TEXTURE_2D, C.GL_TEXTURE_MIN_FILTER, C.GL_LINEAR)
|
||||
C.glBindTexture(C.GL_TEXTURE_2D, 0)
|
||||
C.glTexParameteri(C.GL_TEXTURE_2D, C.GL_TEXTURE_MAG_FILTER, C.GL_LINEAR)
|
||||
C.glTexParameteri(C.GL_TEXTURE_2D, C.GL_TEXTURE_MIN_FILTER, C.GL_LINEAR)
|
||||
C.glBindTexture(C.GL_TEXTURE_2D, 0)
|
||||
|
||||
// TODO: lock?
|
||||
texture.id = textureID
|
||||
})
|
||||
// TODO: lock?
|
||||
texture.id = textureID
|
||||
|
||||
return texture
|
||||
}
|
||||
|
||||
func (texture *Texture) Width() int {
|
||||
return texture.width
|
||||
func newTexture(width, height int) *Texture {
|
||||
return createTexture(width, height, nil)
|
||||
}
|
||||
|
||||
func (texture *Texture) Height() int {
|
||||
return texture.height
|
||||
}
|
||||
|
||||
func (texture *Texture) TextureWidth() int {
|
||||
return texture.textureWidth
|
||||
}
|
||||
|
||||
func (texture *Texture) TextureHeight() int {
|
||||
return texture.textureHeight
|
||||
}
|
||||
|
||||
func (texture *Texture) IsAvailable() bool {
|
||||
return texture.id != 0
|
||||
func newTextureFromImage(img image.Image) *Texture {
|
||||
var pix []uint8
|
||||
switch img.(type) {
|
||||
case *image.RGBA:
|
||||
pix = img.(*image.RGBA).Pix
|
||||
case *image.NRGBA:
|
||||
pix = img.(*image.NRGBA).Pix
|
||||
default:
|
||||
panic("image should be RGBA or NRGBA")
|
||||
}
|
||||
size := img.Bounds().Size()
|
||||
return createTexture(size.X, size.Y, pix)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user