Unify RenderTarget and Image into Image (#34)

This commit is contained in:
Hajime Hoshi 2014-12-22 10:36:42 +09:00
parent f6809862d6
commit 0f8ac49055
22 changed files with 131 additions and 133 deletions

View File

@ -24,18 +24,18 @@ import (
)
type debugPrintState struct {
textTexture *ebiten.Image
debugPrintRenderTarget *ebiten.RenderTarget
textImage *ebiten.Image
debugPrintRenderTarget *ebiten.Image
y int
}
var defaultDebugPrintState = new(debugPrintState)
func DebugPrint(r *ebiten.RenderTarget, str string) {
func DebugPrint(r *ebiten.Image, str string) {
defaultDebugPrintState.DebugPrint(r, str)
}
func (d *debugPrintState) drawText(rt *ebiten.RenderTarget, str string, x, y int, c color.Color) {
func (d *debugPrintState) drawText(rt *ebiten.Image, str string, x, y int, c color.Color) {
parts := []ebiten.ImagePart{}
locationX, locationY := 0, 0
for _, c := range str {
@ -57,16 +57,16 @@ func (d *debugPrintState) drawText(rt *ebiten.RenderTarget, str string, x, y int
geo := ebiten.TranslateGeometry(float64(x)+1, float64(y))
r, g, b, a := internal.RGBA(c)
clr := ebiten.ScaleColor(r, g, b, a)
rt.DrawImage(d.textTexture, parts, geo, clr)
rt.DrawImage(d.textImage, parts, geo, clr)
}
func (d *debugPrintState) DebugPrint(r *ebiten.RenderTarget, str string) {
if d.textTexture == nil {
func (d *debugPrintState) DebugPrint(r *ebiten.Image, str string) {
if d.textImage == nil {
img, err := assets.TextImage()
if err != nil {
panic(err)
}
d.textTexture, err = ebiten.NewImage(img, ebiten.FilterNearest)
d.textImage, err = ebiten.NewImageFromImage(img, ebiten.FilterNearest)
if err != nil {
panic(err)
}
@ -74,7 +74,7 @@ func (d *debugPrintState) DebugPrint(r *ebiten.RenderTarget, str string) {
if d.debugPrintRenderTarget == nil {
width, height := 256, 256
var err error
d.debugPrintRenderTarget, err = ebiten.NewRenderTarget(width, height, ebiten.FilterNearest)
d.debugPrintRenderTarget, err = ebiten.NewImage(width, height, ebiten.FilterNearest)
if err != nil {
panic(err)
}

View File

@ -32,9 +32,9 @@ func NewImageFromFile(path string, filter ebiten.Filter) (*ebiten.Image, image.I
if err != nil {
return nil, nil, err
}
texture, err := ebiten.NewImage(img, filter)
img2, err := ebiten.NewImageFromImage(img, filter)
if err != nil {
return nil, nil, err
}
return texture, img, err
return img2, img, err
}

View File

@ -31,11 +31,11 @@ const (
type Game struct {
count int
tmpRenderTarget *ebiten.RenderTarget
tmpRenderTarget *ebiten.Image
ebitenImage *ebiten.Image
}
func (g *Game) Update(r *ebiten.RenderTarget) error {
func (g *Game) Update(r *ebiten.Image) error {
g.count++
g.count %= 600
diff := float64(g.count) * 0.2
@ -62,7 +62,7 @@ func (g *Game) Update(r *ebiten.RenderTarget) error {
for i := 0; i < 10; i++ {
geo := ebiten.TranslateGeometry(0, float64(i)*(diff))
clr := ebiten.ColorMatrixI()
if err := ebiten.DrawWholeImage(r, g.tmpRenderTarget.Image(), geo, clr); err != nil {
if err := ebiten.DrawWholeImage(r, g.tmpRenderTarget, geo, clr); err != nil {
return err
}
}
@ -76,7 +76,7 @@ func main() {
if err != nil {
log.Fatal(err)
}
g.tmpRenderTarget, err = ebiten.NewRenderTarget(screenWidth, screenHeight, ebiten.FilterNearest)
g.tmpRenderTarget, err = ebiten.NewImage(screenWidth, screenHeight, ebiten.FilterNearest)
if err != nil {
log.Fatal(err)
}

View File

@ -112,7 +112,7 @@ func (f *Field) flushLine(j int) bool {
return true
}
func (f *Field) Draw(r *ebiten.RenderTarget, images *Images, geo ebiten.GeometryMatrix) {
func (f *Field) Draw(r *ebiten.Image, images *Images, geo ebiten.GeometryMatrix) {
blocks := make([][]BlockType, len(f.blocks))
for i, blockCol := range f.blocks {
blocks[i] = make([]BlockType, len(blockCol))

View File

@ -33,7 +33,7 @@ func textWidth(str string) int {
return charWidth * len(str)
}
func drawText(rt *ebiten.RenderTarget, images *Images, str string, ox, oy, scale int, c color.Color) {
func drawText(rt *ebiten.Image, images *Images, str string, ox, oy, scale int, c color.Color) {
fontImageId := images.GetImage("font")
parts := []ebiten.ImagePart{}
@ -66,7 +66,7 @@ func drawText(rt *ebiten.RenderTarget, images *Images, str string, ox, oy, scale
rt.DrawImage(fontImageId, parts, geo, clr)
}
func drawTextWithShadow(rt *ebiten.RenderTarget, images *Images, str string, x, y, scale int, clr color.Color) {
func drawTextWithShadow(rt *ebiten.Image, images *Images, str string, x, y, scale int, clr color.Color) {
drawText(rt, images, str, x+1, y+1, scale, color.NRGBA{0, 0, 0, 0x80})
drawText(rt, images, str, x, y, scale, clr)
}

View File

@ -70,7 +70,7 @@ func (game *Game) isInitialized() bool {
return true
}
func (game *Game) Update(r *ebiten.RenderTarget) error {
func (game *Game) Update(r *ebiten.Image) error {
game.once.Do(func() {
game.images = NewImages()
for name, path := range imagePaths {

View File

@ -109,7 +109,7 @@ func (s *GameScene) Update(state *GameState) {
}
}
func (s *GameScene) Draw(r *ebiten.RenderTarget, images *Images) {
func (s *GameScene) Draw(r *ebiten.Image, images *Images) {
r.Fill(color.White)
field := images.GetImage("empty")

View File

@ -38,7 +38,7 @@ type Images struct {
imagePaths chan namePath
renderTargetSizes chan nameSize
images map[string]*ebiten.Image
renderTargets map[string]*ebiten.RenderTarget
renderTargets map[string]*ebiten.Image
sync.RWMutex
}
@ -47,7 +47,7 @@ func NewImages() *Images {
imagePaths: make(chan namePath),
renderTargetSizes: make(chan nameSize),
images: map[string]*ebiten.Image{},
renderTargets: map[string]*ebiten.RenderTarget{},
renderTargets: map[string]*ebiten.Image{},
}
go func() {
for {
@ -81,7 +81,7 @@ func (i *Images) loopMain() {
if err != nil {
panic(err)
}
id, err := ebiten.NewImage(img, ebiten.FilterNearest)
id, err := ebiten.NewImageFromImage(img, ebiten.FilterNearest)
if err != nil {
panic(err)
}
@ -93,7 +93,7 @@ func (i *Images) loopMain() {
name := s.name
size := s.size
go func() {
id, err := ebiten.NewRenderTarget(size.Width, size.Height, ebiten.FilterNearest)
id, err := ebiten.NewImage(size.Width, size.Height, ebiten.FilterNearest)
if err != nil {
panic(err)
}
@ -129,7 +129,7 @@ func (i *Images) GetImage(name string) *ebiten.Image {
return i.images[name]
}
func (i *Images) GetRenderTarget(name string) *ebiten.RenderTarget {
func (i *Images) GetRenderTarget(name string) *ebiten.Image {
i.RLock()
defer i.RUnlock()
return i.renderTargets[name]

View File

@ -138,7 +138,7 @@ const blockHeight = 10
const fieldBlockNumX = 10
const fieldBlockNumY = 20
func drawBlocks(r *ebiten.RenderTarget, images *Images, blocks [][]BlockType, geo ebiten.GeometryMatrix) {
func drawBlocks(r *ebiten.Image, images *Images, blocks [][]BlockType, geo ebiten.GeometryMatrix) {
parts := []ebiten.ImagePart{}
for i, blockCol := range blocks {
for j, block := range blockCol {
@ -213,7 +213,7 @@ func (p *Piece) AbsorbInto(field *Field, x, y int, angle Angle) {
}
}
func (p *Piece) Draw(r *ebiten.RenderTarget, images *Images, fieldX, fieldY int, pieceX, pieceY int, angle Angle) {
func (p *Piece) Draw(r *ebiten.Image, images *Images, fieldX, fieldY int, pieceX, pieceY int, angle Angle) {
size := len(p.blocks)
blocks := make([][]BlockType, size)
for i := range p.blocks {

View File

@ -29,7 +29,7 @@ func init() {
type Scene interface {
Update(state *GameState)
Draw(r *ebiten.RenderTarget, images *Images)
Draw(r *ebiten.Image, images *Images)
}
const transitionMaxCount = 20
@ -60,7 +60,7 @@ func (s *SceneManager) Update(state *GameState) {
}
}
func (s *SceneManager) Draw(r *ebiten.RenderTarget, images *Images) {
func (s *SceneManager) Draw(r *ebiten.Image, images *Images) {
if s.transitionCount == -1 {
s.current.Draw(r, images)
return
@ -74,11 +74,11 @@ func (s *SceneManager) Draw(r *ebiten.RenderTarget, images *Images) {
s.next.Draw(to, images)
color := ebiten.ColorMatrixI()
ebiten.DrawWholeImage(r, from.Image(), ebiten.GeometryMatrixI(), color)
ebiten.DrawWholeImage(r, from, ebiten.GeometryMatrixI(), color)
alpha := float64(s.transitionCount) / float64(transitionMaxCount)
color.Elements[3][3] = alpha
ebiten.DrawWholeImage(r, to.Image(), ebiten.GeometryMatrixI(), color)
ebiten.DrawWholeImage(r, to, ebiten.GeometryMatrixI(), color)
}
func (s *SceneManager) GoTo(scene Scene) {

View File

@ -40,7 +40,7 @@ func (s *TitleScene) Update(state *GameState) {
}
}
func (s *TitleScene) Draw(r *ebiten.RenderTarget, images *Images) {
func (s *TitleScene) Draw(r *ebiten.Image, images *Images) {
drawTitleBackground(r, images, s.count)
drawLogo(r, images, "BLOCKS")
@ -50,7 +50,7 @@ func (s *TitleScene) Draw(r *ebiten.RenderTarget, images *Images) {
drawTextWithShadow(r, images, message, x, y, 1, color.NRGBA{0x80, 0, 0, 0xff})
}
func drawTitleBackground(r *ebiten.RenderTarget, images *Images, c int) {
func drawTitleBackground(r *ebiten.Image, images *Images, c int) {
const imageWidth = 32
const imageHeight = 32
@ -73,7 +73,7 @@ func drawTitleBackground(r *ebiten.RenderTarget, images *Images, c int) {
r.DrawImage(backgroundImage, parts, geo, clr)
}
func drawLogo(r *ebiten.RenderTarget, images *Images, str string) {
func drawLogo(r *ebiten.Image, images *Images, str string) {
scale := 4
textWidth := textWidth(str) * scale
x := (ScreenWidth - textWidth) / 2

View File

@ -36,7 +36,7 @@ type Game struct {
gophersImage *ebiten.Image
}
func (g *Game) Update(r *ebiten.RenderTarget) error {
func (g *Game) Update(r *ebiten.Image) error {
g.count++
if ebiten.IsKeyPressed(ebiten.KeyLeft) {
g.horizontalCount--
@ -60,7 +60,9 @@ func (g *Game) Update(r *ebiten.RenderTarget) error {
geo.Concat(ebiten.TranslateGeometry(screenWidth/2, screenHeight/2))
//clr := ebiten.RotateHue(float64(g.count%180) * 2 * math.Pi / 180)
clr := ebiten.ColorMatrixI()
ebiten.DrawWholeImage(r, g.gophersImage, geo, clr)
if err := ebiten.DrawWholeImage(r, g.gophersImage, geo, clr); err != nil {
return err
}
return nil
}

View File

@ -32,15 +32,15 @@ const mosaicRatio = 16
type Game struct {
gophersImage *ebiten.Image
gophersRenderTarget *ebiten.RenderTarget
gophersRenderTarget *ebiten.Image
}
func (g *Game) Update(r *ebiten.RenderTarget) error {
func (g *Game) Update(r *ebiten.Image) error {
geo := ebiten.ScaleGeometry(1.0/mosaicRatio, 1.0/mosaicRatio)
ebiten.DrawWholeImage(g.gophersRenderTarget, g.gophersImage, geo, ebiten.ColorMatrixI())
geo = ebiten.ScaleGeometry(mosaicRatio/2.0, mosaicRatio/2.0)
ebiten.DrawWholeImage(r, g.gophersRenderTarget.Image(), geo, ebiten.ColorMatrixI())
ebiten.DrawWholeImage(r, g.gophersRenderTarget, geo, ebiten.ColorMatrixI())
return nil
}
@ -52,7 +52,7 @@ func main() {
log.Fatal(err)
}
w, h := g.gophersImage.Size()
g.gophersRenderTarget, err = ebiten.NewRenderTarget(w/mosaicRatio, h/mosaicRatio, ebiten.FilterNearest)
g.gophersRenderTarget, err = ebiten.NewImage(w/mosaicRatio, h/mosaicRatio, ebiten.FilterNearest)
if err != nil {
log.Fatal(err)
}

View File

@ -33,11 +33,11 @@ const (
type Game struct {
inited bool
count int
brushRenderTarget *ebiten.RenderTarget
canvasRenderTarget *ebiten.RenderTarget
brushRenderTarget *ebiten.Image
canvasRenderTarget *ebiten.Image
}
func (g *Game) Update(r *ebiten.RenderTarget) error {
func (g *Game) Update(r *ebiten.Image) error {
if ebiten.IsMouseButtonPressed(ebiten.MouseButtonLeft) {
g.count++
}
@ -54,10 +54,10 @@ func (g *Game) Update(r *ebiten.RenderTarget) error {
clr := ebiten.ScaleColor(1.0, 0.25, 0.25, 1.0)
theta := 2.0 * math.Pi * float64(g.count%60) / 60.0
clr.Concat(ebiten.RotateHue(theta))
ebiten.DrawWholeImage(g.canvasRenderTarget, g.brushRenderTarget.Image(), geo, clr)
ebiten.DrawWholeImage(g.canvasRenderTarget, g.brushRenderTarget, geo, clr)
}
ebiten.DrawWholeImage(r, g.canvasRenderTarget.Image(), ebiten.GeometryMatrixI(), ebiten.ColorMatrixI())
ebiten.DrawWholeImage(r, g.canvasRenderTarget, ebiten.GeometryMatrixI(), ebiten.ColorMatrixI())
ebitenutil.DebugPrint(r, fmt.Sprintf("(%d, %d)", mx, my))
return nil
@ -66,11 +66,11 @@ func (g *Game) Update(r *ebiten.RenderTarget) error {
func main() {
g := new(Game)
var err error
g.brushRenderTarget, err = ebiten.NewRenderTarget(1, 1, ebiten.FilterNearest)
g.brushRenderTarget, err = ebiten.NewImage(1, 1, ebiten.FilterNearest)
if err != nil {
log.Fatal(err)
}
g.canvasRenderTarget, err = ebiten.NewRenderTarget(screenWidth, screenHeight, ebiten.FilterNearest)
g.canvasRenderTarget, err = ebiten.NewImage(screenWidth, screenHeight, ebiten.FilterNearest)
if err != nil {
log.Fatal(err)
}

View File

@ -32,7 +32,7 @@ type Game struct {
gophersImage *ebiten.Image
}
func (g *Game) Update(r *ebiten.RenderTarget) error {
func (g *Game) Update(r *ebiten.Image) error {
parts := []ebiten.ImagePart{}
w, h := g.gophersImage.Size()
for i := 0; i < h; i++ {

View File

@ -47,12 +47,12 @@ func glFilter(f Filter) int {
}
}
// NewRenderTarget returns a new RenderTarget.
func NewRenderTarget(width, height int, filter Filter) (*RenderTarget, error) {
return currentUI.newRenderTarget(width, height, glFilter(filter))
// NewImage returns an empty image.
func NewImage(width, height int, filter Filter) (*Image, error) {
return currentUI.newImage(width, height, glFilter(filter))
}
// NewImage returns a new image.
func NewImage(img image.Image, filter Filter) (*Image, error) {
return currentUI.newImage(img, glFilter(filter))
// NewImage creates a new image with the given image (img).
func NewImageFromImage(img image.Image, filter Filter) (*Image, error) {
return currentUI.newImageFromImage(img, glFilter(filter))
}

View File

@ -16,10 +16,6 @@ limitations under the License.
package ebiten
import (
"github.com/hajimehoshi/ebiten/internal/opengl"
)
// A Rect represents a rectangle.
type Rect struct {
X float64
@ -35,7 +31,7 @@ type ImagePart struct {
}
// DrawWholeImage draws the whole image.
func DrawWholeImage(r *RenderTarget, image *Image, geo GeometryMatrix, color ColorMatrix) error {
func DrawWholeImage(r *Image, image *Image, geo GeometryMatrix, color ColorMatrix) error {
w, h := image.Size()
parts := []ImagePart{
{Rect{0, 0, float64(w), float64(h)}, Rect{0, 0, float64(w), float64(h)}},
@ -51,14 +47,3 @@ const (
FilterNearest Filter = iota
FilterLinear
)
// An Image represents an image to be rendered.
// An image's pixels are stored as non alpha-premultiplied.
type Image struct {
glTexture *opengl.Texture
}
// Size returns the size of the image.
func (i *Image) Size() (width int, height int) {
return i.glTexture.Size()
}

View File

@ -27,12 +27,17 @@ func newGraphicsContext(screenWidth, screenHeight, screenScale int) (*graphicsCo
return nil, err
}
screen, err := newInnerRenderTarget(screenWidth, screenHeight, gl.NEAREST)
texture, err := opengl.NewTexture(screenWidth, screenHeight, gl.NEAREST)
if err != nil {
return nil, err
}
screen, err := newInnerImage(texture, gl.NEAREST)
if err != nil {
return nil, err
}
c := &graphicsContext{
defaultR: &innerRenderTarget{r, nil},
defaultR: &innerImage{r, nil},
screen: screen,
screenScale: screenScale,
}
@ -40,15 +45,15 @@ func newGraphicsContext(screenWidth, screenHeight, screenScale int) (*graphicsCo
}
type graphicsContext struct {
screen *innerRenderTarget
defaultR *innerRenderTarget
screen *innerImage
defaultR *innerImage
screenScale int
}
func (c *graphicsContext) dispose() {
// NOTE: Now this method is not used anywhere.
glRenderTarget := c.screen.glRenderTarget
glTexture := c.screen.image.glTexture
glTexture := c.screen.glTexture
glRenderTarget.Dispose()
glTexture.Dispose()
@ -64,11 +69,11 @@ func (c *graphicsContext) postUpdate() error {
scale := float64(c.screenScale)
geo := ScaleGeometry(scale, scale)
clr := ColorMatrixI()
w, h := c.screen.image.Size()
w, h := c.screen.size()
parts := []ImagePart{
{Rect{0, 0, float64(w), float64(h)}, Rect{0, 0, float64(w), float64(h)}},
}
if err := c.defaultR.DrawImage(c.screen.image, parts, geo, clr); err != nil {
if err := c.defaultR.drawImage(c.screen, parts, geo, clr); err != nil {
return err
}

View File

@ -24,35 +24,29 @@ import (
"image/color"
)
type innerRenderTarget struct {
glRenderTarget *opengl.RenderTarget
image *Image
}
func newInnerRenderTarget(width, height int, filter int) (*innerRenderTarget, error) {
glTexture, err := opengl.NewTexture(width, height, filter)
if err != nil {
return nil, err
type innerImage struct {
// TODO: Rename them later.
glRenderTarget *opengl.Image
glTexture *opengl.Texture
}
func newInnerImage(glTexture *opengl.Texture, filter int) (*innerImage, error) {
glRenderTarget, err := opengl.NewRenderTargetFromTexture(glTexture)
if err != nil {
return nil, err
}
image := &Image{glTexture}
return &innerRenderTarget{glRenderTarget, image}, nil
return &innerImage{glRenderTarget, glTexture}, nil
}
func (r *innerRenderTarget) size() (width, height int) {
func (r *innerImage) size() (width, height int) {
return r.glRenderTarget.Size()
}
func (r *innerRenderTarget) Clear() error {
func (r *innerImage) Clear() error {
return r.Fill(color.Transparent)
}
func (r *innerRenderTarget) Fill(clr color.Color) error {
func (r *innerImage) Fill(clr color.Color) error {
if err := r.glRenderTarget.SetAsViewport(); err != nil {
return err
}
@ -62,20 +56,19 @@ func (r *innerRenderTarget) Fill(clr color.Color) error {
return nil
}
func (r *innerRenderTarget) DrawImage(image *Image, parts []ImagePart, geo GeometryMatrix, color ColorMatrix) error {
func (r *innerImage) drawImage(image *innerImage, parts []ImagePart, geo GeometryMatrix, color ColorMatrix) error {
if err := r.glRenderTarget.SetAsViewport(); err != nil {
return err
}
glTexture := image.glTexture
w, h := glTexture.Size()
w, h := image.glTexture.Size()
quads := textureQuads(parts, w, h)
targetNativeTexture := gl.Texture(0)
if r.image != nil {
targetNativeTexture = r.image.glTexture.Native()
if r.glTexture != nil {
targetNativeTexture = r.glTexture.Native()
}
w2, h2 := r.size()
projectionMatrix := r.glRenderTarget.ProjectionMatrix()
shader.DrawTexture(glTexture.Native(), targetNativeTexture, w2, h2, projectionMatrix, quads, &geo, &color)
shader.DrawTexture(image.glTexture.Native(), targetNativeTexture, w2, h2, projectionMatrix, quads, &geo, &color)
return nil
}
@ -108,36 +101,36 @@ type syncer interface {
Sync(func())
}
type RenderTarget struct {
type Image struct {
syncer syncer
inner *innerRenderTarget
inner *innerImage
}
func (r *RenderTarget) Image() *Image {
return r.inner.image
}
func (r *RenderTarget) Size() (width, height int) {
func (r *Image) Size() (width, height int) {
return r.inner.size()
}
func (r *RenderTarget) Clear() (err error) {
func (r *Image) Clear() (err error) {
r.syncer.Sync(func() {
err = r.inner.Clear()
})
return
}
func (r *RenderTarget) Fill(clr color.Color) (err error) {
func (r *Image) Fill(clr color.Color) (err error) {
r.syncer.Sync(func() {
err = r.inner.Fill(clr)
})
return
}
func (r *RenderTarget) DrawImage(image *Image, parts []ImagePart, geo GeometryMatrix, color ColorMatrix) (err error) {
func (r *Image) DrawImage(image *Image, parts []ImagePart, geo GeometryMatrix, color ColorMatrix) (err error) {
return r.drawImage(image.inner, parts, geo, color)
}
func (r *Image) drawImage(image *innerImage, parts []ImagePart, geo GeometryMatrix, color ColorMatrix) (err error) {
r.syncer.Sync(func() {
err = r.inner.DrawImage(image, parts, geo, color)
err = r.inner.drawImage(image, parts, geo, color)
})
return
}

View File

@ -37,15 +37,15 @@ func orthoProjectionMatrix(left, right, bottom, top int) [4][4]float64 {
}
}
type RenderTarget struct {
type Image struct {
framebuffer gl.Framebuffer
width int
height int
flipY bool
}
func NewZeroRenderTarget(width, height int) (*RenderTarget, error) {
r := &RenderTarget{
func NewZeroRenderTarget(width, height int) (*Image, error) {
r := &Image{
width: width,
height: height,
flipY: true,
@ -53,24 +53,24 @@ func NewZeroRenderTarget(width, height int) (*RenderTarget, error) {
return r, nil
}
func NewRenderTargetFromTexture(texture *Texture) (*RenderTarget, error) {
func NewRenderTargetFromTexture(texture *Texture) (*Image, error) {
framebuffer, err := createFramebuffer(texture.Native())
if err != nil {
return nil, err
}
w, h := texture.Size()
return &RenderTarget{
return &Image{
framebuffer: framebuffer,
width: w,
height: h,
}, nil
}
func (r *RenderTarget) Size() (width, height int) {
func (r *Image) Size() (width, height int) {
return r.width, r.height
}
func (r *RenderTarget) Dispose() {
func (r *Image) Dispose() {
r.framebuffer.Delete()
}
@ -83,13 +83,10 @@ func createFramebuffer(nativeTexture gl.Texture) (gl.Framebuffer, error) {
return 0, errors.New("creating framebuffer failed")
}
gl.ClearColor(0, 0, 0, 0)
gl.Clear(gl.COLOR_BUFFER_BIT)
return framebuffer, nil
}
func (r *RenderTarget) SetAsViewport() error {
func (r *Image) SetAsViewport() error {
gl.Flush()
r.framebuffer.Bind()
err := gl.CheckFramebufferStatus(gl.FRAMEBUFFER)
@ -106,7 +103,7 @@ func (r *RenderTarget) SetAsViewport() error {
return nil
}
func (r *RenderTarget) ProjectionMatrix() [4][4]float64 {
func (r *Image) ProjectionMatrix() [4][4]float64 {
width := internal.NextPowerOf2Int(r.width)
height := internal.NextPowerOf2Int(r.height)
m := orthoProjectionMatrix(0, width, 0, height)

5
run.go
View File

@ -17,8 +17,11 @@ limitations under the License.
package ebiten
// Run runs the game.
// f is a function which is called at every frame.
// The argument (*Image) is the render target that represents the screen.
//
// This function must be called from the main thread.
func Run(f func(*RenderTarget) error, width, height, scale int, title string) error {
func Run(f func(*Image) error, width, height, scale int, title string) error {
err := startUI(width, height, scale, title)
if err != nil {
return err

35
ui.go
View File

@ -110,14 +110,14 @@ func (u *ui) Sync(f func()) {
u.use(f)
}
func (u *ui) draw(f func(*RenderTarget) error) (err error) {
func (u *ui) draw(f func(*Image) error) (err error) {
u.use(func() {
err = u.graphicsContext.preUpdate()
})
if err != nil {
return
}
err = f(&RenderTarget{syncer: u, inner: u.graphicsContext.screen})
err = f(&Image{syncer: u, inner: u.graphicsContext.screen})
if err != nil {
return
}
@ -131,26 +131,39 @@ func (u *ui) draw(f func(*RenderTarget) error) (err error) {
return
}
func (u *ui) newImage(img image.Image, filter int) (*Image, error) {
var i *Image
func (u *ui) newImageFromImage(img image.Image, filter int) (*Image, error) {
var innerImage *innerImage
var err error
u.use(func() {
glTexture, err := opengl.NewTextureFromImage(img, filter)
var texture *opengl.Texture
texture, err = opengl.NewTextureFromImage(img, filter)
if err != nil {
return
}
i = &Image{glTexture}
innerImage, err = newInnerImage(texture, filter)
})
return i, err
if err != nil {
return nil, err
}
return &Image{u, innerImage}, nil
}
func (u *ui) newRenderTarget(width, height int, filter int) (*RenderTarget, error) {
var innerRenderTarget *innerRenderTarget
func (u *ui) newImage(width, height int, filter int) (*Image, error) {
var innerImage *innerImage
var err error
u.use(func() {
innerRenderTarget, err = newInnerRenderTarget(width, height, filter)
var texture *opengl.Texture
texture, err = opengl.NewTexture(width, height, filter)
if err != nil {
return
}
innerImage, err = newInnerImage(texture, filter)
innerImage.Clear()
})
return &RenderTarget{u, innerRenderTarget}, err
if err != nil {
return nil, err
}
return &Image{u, innerImage}, nil
}
func (u *ui) run() {