mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-12-24 10:48:53 +01:00
Unify RenderTarget and Image into Image (#34)
This commit is contained in:
parent
f6809862d6
commit
0f8ac49055
@ -24,18 +24,18 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type debugPrintState struct {
|
type debugPrintState struct {
|
||||||
textTexture *ebiten.Image
|
textImage *ebiten.Image
|
||||||
debugPrintRenderTarget *ebiten.RenderTarget
|
debugPrintRenderTarget *ebiten.Image
|
||||||
y int
|
y int
|
||||||
}
|
}
|
||||||
|
|
||||||
var defaultDebugPrintState = new(debugPrintState)
|
var defaultDebugPrintState = new(debugPrintState)
|
||||||
|
|
||||||
func DebugPrint(r *ebiten.RenderTarget, str string) {
|
func DebugPrint(r *ebiten.Image, str string) {
|
||||||
defaultDebugPrintState.DebugPrint(r, str)
|
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{}
|
parts := []ebiten.ImagePart{}
|
||||||
locationX, locationY := 0, 0
|
locationX, locationY := 0, 0
|
||||||
for _, c := range str {
|
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))
|
geo := ebiten.TranslateGeometry(float64(x)+1, float64(y))
|
||||||
r, g, b, a := internal.RGBA(c)
|
r, g, b, a := internal.RGBA(c)
|
||||||
clr := ebiten.ScaleColor(r, g, b, a)
|
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) {
|
func (d *debugPrintState) DebugPrint(r *ebiten.Image, str string) {
|
||||||
if d.textTexture == nil {
|
if d.textImage == nil {
|
||||||
img, err := assets.TextImage()
|
img, err := assets.TextImage()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
d.textTexture, err = ebiten.NewImage(img, ebiten.FilterNearest)
|
d.textImage, err = ebiten.NewImageFromImage(img, ebiten.FilterNearest)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
@ -74,7 +74,7 @@ func (d *debugPrintState) DebugPrint(r *ebiten.RenderTarget, str string) {
|
|||||||
if d.debugPrintRenderTarget == nil {
|
if d.debugPrintRenderTarget == nil {
|
||||||
width, height := 256, 256
|
width, height := 256, 256
|
||||||
var err error
|
var err error
|
||||||
d.debugPrintRenderTarget, err = ebiten.NewRenderTarget(width, height, ebiten.FilterNearest)
|
d.debugPrintRenderTarget, err = ebiten.NewImage(width, height, ebiten.FilterNearest)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
@ -32,9 +32,9 @@ func NewImageFromFile(path string, filter ebiten.Filter) (*ebiten.Image, image.I
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
texture, err := ebiten.NewImage(img, filter)
|
img2, err := ebiten.NewImageFromImage(img, filter)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
return texture, img, err
|
return img2, img, err
|
||||||
}
|
}
|
||||||
|
@ -31,11 +31,11 @@ const (
|
|||||||
|
|
||||||
type Game struct {
|
type Game struct {
|
||||||
count int
|
count int
|
||||||
tmpRenderTarget *ebiten.RenderTarget
|
tmpRenderTarget *ebiten.Image
|
||||||
ebitenImage *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++
|
||||||
g.count %= 600
|
g.count %= 600
|
||||||
diff := float64(g.count) * 0.2
|
diff := float64(g.count) * 0.2
|
||||||
@ -62,7 +62,7 @@ func (g *Game) Update(r *ebiten.RenderTarget) error {
|
|||||||
for i := 0; i < 10; i++ {
|
for i := 0; i < 10; i++ {
|
||||||
geo := ebiten.TranslateGeometry(0, float64(i)*(diff))
|
geo := ebiten.TranslateGeometry(0, float64(i)*(diff))
|
||||||
clr := ebiten.ColorMatrixI()
|
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
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -76,7 +76,7 @@ func main() {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
g.tmpRenderTarget, err = ebiten.NewRenderTarget(screenWidth, screenHeight, ebiten.FilterNearest)
|
g.tmpRenderTarget, err = ebiten.NewImage(screenWidth, screenHeight, ebiten.FilterNearest)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
@ -112,7 +112,7 @@ func (f *Field) flushLine(j int) bool {
|
|||||||
return true
|
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))
|
blocks := make([][]BlockType, len(f.blocks))
|
||||||
for i, blockCol := range f.blocks {
|
for i, blockCol := range f.blocks {
|
||||||
blocks[i] = make([]BlockType, len(blockCol))
|
blocks[i] = make([]BlockType, len(blockCol))
|
||||||
|
@ -33,7 +33,7 @@ func textWidth(str string) int {
|
|||||||
return charWidth * len(str)
|
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")
|
fontImageId := images.GetImage("font")
|
||||||
parts := []ebiten.ImagePart{}
|
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)
|
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+1, y+1, scale, color.NRGBA{0, 0, 0, 0x80})
|
||||||
drawText(rt, images, str, x, y, scale, clr)
|
drawText(rt, images, str, x, y, scale, clr)
|
||||||
}
|
}
|
||||||
|
@ -70,7 +70,7 @@ func (game *Game) isInitialized() bool {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
func (game *Game) Update(r *ebiten.RenderTarget) error {
|
func (game *Game) Update(r *ebiten.Image) error {
|
||||||
game.once.Do(func() {
|
game.once.Do(func() {
|
||||||
game.images = NewImages()
|
game.images = NewImages()
|
||||||
for name, path := range imagePaths {
|
for name, path := range imagePaths {
|
||||||
|
@ -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)
|
r.Fill(color.White)
|
||||||
|
|
||||||
field := images.GetImage("empty")
|
field := images.GetImage("empty")
|
||||||
|
@ -38,7 +38,7 @@ type Images struct {
|
|||||||
imagePaths chan namePath
|
imagePaths chan namePath
|
||||||
renderTargetSizes chan nameSize
|
renderTargetSizes chan nameSize
|
||||||
images map[string]*ebiten.Image
|
images map[string]*ebiten.Image
|
||||||
renderTargets map[string]*ebiten.RenderTarget
|
renderTargets map[string]*ebiten.Image
|
||||||
sync.RWMutex
|
sync.RWMutex
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -47,7 +47,7 @@ func NewImages() *Images {
|
|||||||
imagePaths: make(chan namePath),
|
imagePaths: make(chan namePath),
|
||||||
renderTargetSizes: make(chan nameSize),
|
renderTargetSizes: make(chan nameSize),
|
||||||
images: map[string]*ebiten.Image{},
|
images: map[string]*ebiten.Image{},
|
||||||
renderTargets: map[string]*ebiten.RenderTarget{},
|
renderTargets: map[string]*ebiten.Image{},
|
||||||
}
|
}
|
||||||
go func() {
|
go func() {
|
||||||
for {
|
for {
|
||||||
@ -81,7 +81,7 @@ func (i *Images) loopMain() {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
id, err := ebiten.NewImage(img, ebiten.FilterNearest)
|
id, err := ebiten.NewImageFromImage(img, ebiten.FilterNearest)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
@ -93,7 +93,7 @@ func (i *Images) loopMain() {
|
|||||||
name := s.name
|
name := s.name
|
||||||
size := s.size
|
size := s.size
|
||||||
go func() {
|
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 {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
@ -129,7 +129,7 @@ func (i *Images) GetImage(name string) *ebiten.Image {
|
|||||||
return i.images[name]
|
return i.images[name]
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *Images) GetRenderTarget(name string) *ebiten.RenderTarget {
|
func (i *Images) GetRenderTarget(name string) *ebiten.Image {
|
||||||
i.RLock()
|
i.RLock()
|
||||||
defer i.RUnlock()
|
defer i.RUnlock()
|
||||||
return i.renderTargets[name]
|
return i.renderTargets[name]
|
||||||
|
@ -138,7 +138,7 @@ const blockHeight = 10
|
|||||||
const fieldBlockNumX = 10
|
const fieldBlockNumX = 10
|
||||||
const fieldBlockNumY = 20
|
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{}
|
parts := []ebiten.ImagePart{}
|
||||||
for i, blockCol := range blocks {
|
for i, blockCol := range blocks {
|
||||||
for j, block := range blockCol {
|
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)
|
size := len(p.blocks)
|
||||||
blocks := make([][]BlockType, size)
|
blocks := make([][]BlockType, size)
|
||||||
for i := range p.blocks {
|
for i := range p.blocks {
|
||||||
|
@ -29,7 +29,7 @@ func init() {
|
|||||||
|
|
||||||
type Scene interface {
|
type Scene interface {
|
||||||
Update(state *GameState)
|
Update(state *GameState)
|
||||||
Draw(r *ebiten.RenderTarget, images *Images)
|
Draw(r *ebiten.Image, images *Images)
|
||||||
}
|
}
|
||||||
|
|
||||||
const transitionMaxCount = 20
|
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 {
|
if s.transitionCount == -1 {
|
||||||
s.current.Draw(r, images)
|
s.current.Draw(r, images)
|
||||||
return
|
return
|
||||||
@ -74,11 +74,11 @@ func (s *SceneManager) Draw(r *ebiten.RenderTarget, images *Images) {
|
|||||||
s.next.Draw(to, images)
|
s.next.Draw(to, images)
|
||||||
|
|
||||||
color := ebiten.ColorMatrixI()
|
color := ebiten.ColorMatrixI()
|
||||||
ebiten.DrawWholeImage(r, from.Image(), ebiten.GeometryMatrixI(), color)
|
ebiten.DrawWholeImage(r, from, ebiten.GeometryMatrixI(), color)
|
||||||
|
|
||||||
alpha := float64(s.transitionCount) / float64(transitionMaxCount)
|
alpha := float64(s.transitionCount) / float64(transitionMaxCount)
|
||||||
color.Elements[3][3] = alpha
|
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) {
|
func (s *SceneManager) GoTo(scene Scene) {
|
||||||
|
@ -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)
|
drawTitleBackground(r, images, s.count)
|
||||||
drawLogo(r, images, "BLOCKS")
|
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})
|
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 imageWidth = 32
|
||||||
const imageHeight = 32
|
const imageHeight = 32
|
||||||
|
|
||||||
@ -73,7 +73,7 @@ func drawTitleBackground(r *ebiten.RenderTarget, images *Images, c int) {
|
|||||||
r.DrawImage(backgroundImage, parts, geo, clr)
|
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
|
scale := 4
|
||||||
textWidth := textWidth(str) * scale
|
textWidth := textWidth(str) * scale
|
||||||
x := (ScreenWidth - textWidth) / 2
|
x := (ScreenWidth - textWidth) / 2
|
||||||
|
@ -36,7 +36,7 @@ type Game struct {
|
|||||||
gophersImage *ebiten.Image
|
gophersImage *ebiten.Image
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *Game) Update(r *ebiten.RenderTarget) error {
|
func (g *Game) Update(r *ebiten.Image) error {
|
||||||
g.count++
|
g.count++
|
||||||
if ebiten.IsKeyPressed(ebiten.KeyLeft) {
|
if ebiten.IsKeyPressed(ebiten.KeyLeft) {
|
||||||
g.horizontalCount--
|
g.horizontalCount--
|
||||||
@ -60,7 +60,9 @@ func (g *Game) Update(r *ebiten.RenderTarget) error {
|
|||||||
geo.Concat(ebiten.TranslateGeometry(screenWidth/2, screenHeight/2))
|
geo.Concat(ebiten.TranslateGeometry(screenWidth/2, screenHeight/2))
|
||||||
//clr := ebiten.RotateHue(float64(g.count%180) * 2 * math.Pi / 180)
|
//clr := ebiten.RotateHue(float64(g.count%180) * 2 * math.Pi / 180)
|
||||||
clr := ebiten.ColorMatrixI()
|
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
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -32,15 +32,15 @@ const mosaicRatio = 16
|
|||||||
|
|
||||||
type Game struct {
|
type Game struct {
|
||||||
gophersImage *ebiten.Image
|
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)
|
geo := ebiten.ScaleGeometry(1.0/mosaicRatio, 1.0/mosaicRatio)
|
||||||
ebiten.DrawWholeImage(g.gophersRenderTarget, g.gophersImage, geo, ebiten.ColorMatrixI())
|
ebiten.DrawWholeImage(g.gophersRenderTarget, g.gophersImage, geo, ebiten.ColorMatrixI())
|
||||||
|
|
||||||
geo = ebiten.ScaleGeometry(mosaicRatio/2.0, mosaicRatio/2.0)
|
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
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -52,7 +52,7 @@ func main() {
|
|||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
w, h := g.gophersImage.Size()
|
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 {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
@ -33,11 +33,11 @@ const (
|
|||||||
type Game struct {
|
type Game struct {
|
||||||
inited bool
|
inited bool
|
||||||
count int
|
count int
|
||||||
brushRenderTarget *ebiten.RenderTarget
|
brushRenderTarget *ebiten.Image
|
||||||
canvasRenderTarget *ebiten.RenderTarget
|
canvasRenderTarget *ebiten.Image
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *Game) Update(r *ebiten.RenderTarget) error {
|
func (g *Game) Update(r *ebiten.Image) error {
|
||||||
if ebiten.IsMouseButtonPressed(ebiten.MouseButtonLeft) {
|
if ebiten.IsMouseButtonPressed(ebiten.MouseButtonLeft) {
|
||||||
g.count++
|
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)
|
clr := ebiten.ScaleColor(1.0, 0.25, 0.25, 1.0)
|
||||||
theta := 2.0 * math.Pi * float64(g.count%60) / 60.0
|
theta := 2.0 * math.Pi * float64(g.count%60) / 60.0
|
||||||
clr.Concat(ebiten.RotateHue(theta))
|
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))
|
ebitenutil.DebugPrint(r, fmt.Sprintf("(%d, %d)", mx, my))
|
||||||
return nil
|
return nil
|
||||||
@ -66,11 +66,11 @@ func (g *Game) Update(r *ebiten.RenderTarget) error {
|
|||||||
func main() {
|
func main() {
|
||||||
g := new(Game)
|
g := new(Game)
|
||||||
var err error
|
var err error
|
||||||
g.brushRenderTarget, err = ebiten.NewRenderTarget(1, 1, ebiten.FilterNearest)
|
g.brushRenderTarget, err = ebiten.NewImage(1, 1, ebiten.FilterNearest)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
g.canvasRenderTarget, err = ebiten.NewRenderTarget(screenWidth, screenHeight, ebiten.FilterNearest)
|
g.canvasRenderTarget, err = ebiten.NewImage(screenWidth, screenHeight, ebiten.FilterNearest)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
@ -32,7 +32,7 @@ type Game struct {
|
|||||||
gophersImage *ebiten.Image
|
gophersImage *ebiten.Image
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *Game) Update(r *ebiten.RenderTarget) error {
|
func (g *Game) Update(r *ebiten.Image) error {
|
||||||
parts := []ebiten.ImagePart{}
|
parts := []ebiten.ImagePart{}
|
||||||
w, h := g.gophersImage.Size()
|
w, h := g.gophersImage.Size()
|
||||||
for i := 0; i < h; i++ {
|
for i := 0; i < h; i++ {
|
||||||
|
@ -47,12 +47,12 @@ func glFilter(f Filter) int {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewRenderTarget returns a new RenderTarget.
|
// NewImage returns an empty image.
|
||||||
func NewRenderTarget(width, height int, filter Filter) (*RenderTarget, error) {
|
func NewImage(width, height int, filter Filter) (*Image, error) {
|
||||||
return currentUI.newRenderTarget(width, height, glFilter(filter))
|
return currentUI.newImage(width, height, glFilter(filter))
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewImage returns a new image.
|
// NewImage creates a new image with the given image (img).
|
||||||
func NewImage(img image.Image, filter Filter) (*Image, error) {
|
func NewImageFromImage(img image.Image, filter Filter) (*Image, error) {
|
||||||
return currentUI.newImage(img, glFilter(filter))
|
return currentUI.newImageFromImage(img, glFilter(filter))
|
||||||
}
|
}
|
||||||
|
17
graphics.go
17
graphics.go
@ -16,10 +16,6 @@ limitations under the License.
|
|||||||
|
|
||||||
package ebiten
|
package ebiten
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/hajimehoshi/ebiten/internal/opengl"
|
|
||||||
)
|
|
||||||
|
|
||||||
// A Rect represents a rectangle.
|
// A Rect represents a rectangle.
|
||||||
type Rect struct {
|
type Rect struct {
|
||||||
X float64
|
X float64
|
||||||
@ -35,7 +31,7 @@ type ImagePart struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// DrawWholeImage draws the whole image.
|
// 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()
|
w, h := image.Size()
|
||||||
parts := []ImagePart{
|
parts := []ImagePart{
|
||||||
{Rect{0, 0, float64(w), float64(h)}, Rect{0, 0, float64(w), float64(h)}},
|
{Rect{0, 0, float64(w), float64(h)}, Rect{0, 0, float64(w), float64(h)}},
|
||||||
@ -51,14 +47,3 @@ const (
|
|||||||
FilterNearest Filter = iota
|
FilterNearest Filter = iota
|
||||||
FilterLinear
|
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()
|
|
||||||
}
|
|
||||||
|
@ -27,12 +27,17 @@ func newGraphicsContext(screenWidth, screenHeight, screenScale int) (*graphicsCo
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
screen, err := newInnerRenderTarget(screenWidth, screenHeight, gl.NEAREST)
|
texture, err := opengl.NewTexture(screenWidth, screenHeight, gl.NEAREST)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
screen, err := newInnerImage(texture, gl.NEAREST)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
c := &graphicsContext{
|
c := &graphicsContext{
|
||||||
defaultR: &innerRenderTarget{r, nil},
|
defaultR: &innerImage{r, nil},
|
||||||
screen: screen,
|
screen: screen,
|
||||||
screenScale: screenScale,
|
screenScale: screenScale,
|
||||||
}
|
}
|
||||||
@ -40,15 +45,15 @@ func newGraphicsContext(screenWidth, screenHeight, screenScale int) (*graphicsCo
|
|||||||
}
|
}
|
||||||
|
|
||||||
type graphicsContext struct {
|
type graphicsContext struct {
|
||||||
screen *innerRenderTarget
|
screen *innerImage
|
||||||
defaultR *innerRenderTarget
|
defaultR *innerImage
|
||||||
screenScale int
|
screenScale int
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *graphicsContext) dispose() {
|
func (c *graphicsContext) dispose() {
|
||||||
// NOTE: Now this method is not used anywhere.
|
// NOTE: Now this method is not used anywhere.
|
||||||
glRenderTarget := c.screen.glRenderTarget
|
glRenderTarget := c.screen.glRenderTarget
|
||||||
glTexture := c.screen.image.glTexture
|
glTexture := c.screen.glTexture
|
||||||
|
|
||||||
glRenderTarget.Dispose()
|
glRenderTarget.Dispose()
|
||||||
glTexture.Dispose()
|
glTexture.Dispose()
|
||||||
@ -64,11 +69,11 @@ func (c *graphicsContext) postUpdate() error {
|
|||||||
scale := float64(c.screenScale)
|
scale := float64(c.screenScale)
|
||||||
geo := ScaleGeometry(scale, scale)
|
geo := ScaleGeometry(scale, scale)
|
||||||
clr := ColorMatrixI()
|
clr := ColorMatrixI()
|
||||||
w, h := c.screen.image.Size()
|
w, h := c.screen.size()
|
||||||
parts := []ImagePart{
|
parts := []ImagePart{
|
||||||
{Rect{0, 0, float64(w), float64(h)}, Rect{0, 0, float64(w), float64(h)}},
|
{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
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -24,35 +24,29 @@ import (
|
|||||||
"image/color"
|
"image/color"
|
||||||
)
|
)
|
||||||
|
|
||||||
type innerRenderTarget struct {
|
type innerImage struct {
|
||||||
glRenderTarget *opengl.RenderTarget
|
// TODO: Rename them later.
|
||||||
image *Image
|
glRenderTarget *opengl.Image
|
||||||
|
glTexture *opengl.Texture
|
||||||
}
|
}
|
||||||
|
|
||||||
func newInnerRenderTarget(width, height int, filter int) (*innerRenderTarget, error) {
|
func newInnerImage(glTexture *opengl.Texture, filter int) (*innerImage, error) {
|
||||||
glTexture, err := opengl.NewTexture(width, height, filter)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
glRenderTarget, err := opengl.NewRenderTargetFromTexture(glTexture)
|
glRenderTarget, err := opengl.NewRenderTargetFromTexture(glTexture)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
return &innerImage{glRenderTarget, glTexture}, nil
|
||||||
image := &Image{glTexture}
|
|
||||||
return &innerRenderTarget{glRenderTarget, image}, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *innerRenderTarget) size() (width, height int) {
|
func (r *innerImage) size() (width, height int) {
|
||||||
return r.glRenderTarget.Size()
|
return r.glRenderTarget.Size()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *innerRenderTarget) Clear() error {
|
func (r *innerImage) Clear() error {
|
||||||
return r.Fill(color.Transparent)
|
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 {
|
if err := r.glRenderTarget.SetAsViewport(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -62,20 +56,19 @@ func (r *innerRenderTarget) Fill(clr color.Color) error {
|
|||||||
return nil
|
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 {
|
if err := r.glRenderTarget.SetAsViewport(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
glTexture := image.glTexture
|
w, h := image.glTexture.Size()
|
||||||
w, h := glTexture.Size()
|
|
||||||
quads := textureQuads(parts, w, h)
|
quads := textureQuads(parts, w, h)
|
||||||
targetNativeTexture := gl.Texture(0)
|
targetNativeTexture := gl.Texture(0)
|
||||||
if r.image != nil {
|
if r.glTexture != nil {
|
||||||
targetNativeTexture = r.image.glTexture.Native()
|
targetNativeTexture = r.glTexture.Native()
|
||||||
}
|
}
|
||||||
w2, h2 := r.size()
|
w2, h2 := r.size()
|
||||||
projectionMatrix := r.glRenderTarget.ProjectionMatrix()
|
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
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -108,36 +101,36 @@ type syncer interface {
|
|||||||
Sync(func())
|
Sync(func())
|
||||||
}
|
}
|
||||||
|
|
||||||
type RenderTarget struct {
|
type Image struct {
|
||||||
syncer syncer
|
syncer syncer
|
||||||
inner *innerRenderTarget
|
inner *innerImage
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *RenderTarget) Image() *Image {
|
func (r *Image) Size() (width, height int) {
|
||||||
return r.inner.image
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *RenderTarget) Size() (width, height int) {
|
|
||||||
return r.inner.size()
|
return r.inner.size()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *RenderTarget) Clear() (err error) {
|
func (r *Image) Clear() (err error) {
|
||||||
r.syncer.Sync(func() {
|
r.syncer.Sync(func() {
|
||||||
err = r.inner.Clear()
|
err = r.inner.Clear()
|
||||||
})
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *RenderTarget) Fill(clr color.Color) (err error) {
|
func (r *Image) Fill(clr color.Color) (err error) {
|
||||||
r.syncer.Sync(func() {
|
r.syncer.Sync(func() {
|
||||||
err = r.inner.Fill(clr)
|
err = r.inner.Fill(clr)
|
||||||
})
|
})
|
||||||
return
|
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() {
|
r.syncer.Sync(func() {
|
||||||
err = r.inner.DrawImage(image, parts, geo, color)
|
err = r.inner.drawImage(image, parts, geo, color)
|
||||||
})
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
@ -37,15 +37,15 @@ func orthoProjectionMatrix(left, right, bottom, top int) [4][4]float64 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type RenderTarget struct {
|
type Image struct {
|
||||||
framebuffer gl.Framebuffer
|
framebuffer gl.Framebuffer
|
||||||
width int
|
width int
|
||||||
height int
|
height int
|
||||||
flipY bool
|
flipY bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewZeroRenderTarget(width, height int) (*RenderTarget, error) {
|
func NewZeroRenderTarget(width, height int) (*Image, error) {
|
||||||
r := &RenderTarget{
|
r := &Image{
|
||||||
width: width,
|
width: width,
|
||||||
height: height,
|
height: height,
|
||||||
flipY: true,
|
flipY: true,
|
||||||
@ -53,24 +53,24 @@ func NewZeroRenderTarget(width, height int) (*RenderTarget, error) {
|
|||||||
return r, nil
|
return r, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewRenderTargetFromTexture(texture *Texture) (*RenderTarget, error) {
|
func NewRenderTargetFromTexture(texture *Texture) (*Image, error) {
|
||||||
framebuffer, err := createFramebuffer(texture.Native())
|
framebuffer, err := createFramebuffer(texture.Native())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
w, h := texture.Size()
|
w, h := texture.Size()
|
||||||
return &RenderTarget{
|
return &Image{
|
||||||
framebuffer: framebuffer,
|
framebuffer: framebuffer,
|
||||||
width: w,
|
width: w,
|
||||||
height: h,
|
height: h,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *RenderTarget) Size() (width, height int) {
|
func (r *Image) Size() (width, height int) {
|
||||||
return r.width, r.height
|
return r.width, r.height
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *RenderTarget) Dispose() {
|
func (r *Image) Dispose() {
|
||||||
r.framebuffer.Delete()
|
r.framebuffer.Delete()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -83,13 +83,10 @@ func createFramebuffer(nativeTexture gl.Texture) (gl.Framebuffer, error) {
|
|||||||
return 0, errors.New("creating framebuffer failed")
|
return 0, errors.New("creating framebuffer failed")
|
||||||
}
|
}
|
||||||
|
|
||||||
gl.ClearColor(0, 0, 0, 0)
|
|
||||||
gl.Clear(gl.COLOR_BUFFER_BIT)
|
|
||||||
|
|
||||||
return framebuffer, nil
|
return framebuffer, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *RenderTarget) SetAsViewport() error {
|
func (r *Image) SetAsViewport() error {
|
||||||
gl.Flush()
|
gl.Flush()
|
||||||
r.framebuffer.Bind()
|
r.framebuffer.Bind()
|
||||||
err := gl.CheckFramebufferStatus(gl.FRAMEBUFFER)
|
err := gl.CheckFramebufferStatus(gl.FRAMEBUFFER)
|
||||||
@ -106,7 +103,7 @@ func (r *RenderTarget) SetAsViewport() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *RenderTarget) ProjectionMatrix() [4][4]float64 {
|
func (r *Image) ProjectionMatrix() [4][4]float64 {
|
||||||
width := internal.NextPowerOf2Int(r.width)
|
width := internal.NextPowerOf2Int(r.width)
|
||||||
height := internal.NextPowerOf2Int(r.height)
|
height := internal.NextPowerOf2Int(r.height)
|
||||||
m := orthoProjectionMatrix(0, width, 0, height)
|
m := orthoProjectionMatrix(0, width, 0, height)
|
||||||
|
5
run.go
5
run.go
@ -17,8 +17,11 @@ limitations under the License.
|
|||||||
package ebiten
|
package ebiten
|
||||||
|
|
||||||
// Run runs the game.
|
// 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.
|
// 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)
|
err := startUI(width, height, scale, title)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
35
ui.go
35
ui.go
@ -110,14 +110,14 @@ func (u *ui) Sync(f func()) {
|
|||||||
u.use(f)
|
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() {
|
u.use(func() {
|
||||||
err = u.graphicsContext.preUpdate()
|
err = u.graphicsContext.preUpdate()
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
err = f(&RenderTarget{syncer: u, inner: u.graphicsContext.screen})
|
err = f(&Image{syncer: u, inner: u.graphicsContext.screen})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -131,26 +131,39 @@ func (u *ui) draw(f func(*RenderTarget) error) (err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u *ui) newImage(img image.Image, filter int) (*Image, error) {
|
func (u *ui) newImageFromImage(img image.Image, filter int) (*Image, error) {
|
||||||
var i *Image
|
var innerImage *innerImage
|
||||||
var err error
|
var err error
|
||||||
u.use(func() {
|
u.use(func() {
|
||||||
glTexture, err := opengl.NewTextureFromImage(img, filter)
|
var texture *opengl.Texture
|
||||||
|
texture, err = opengl.NewTextureFromImage(img, filter)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
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) {
|
func (u *ui) newImage(width, height int, filter int) (*Image, error) {
|
||||||
var innerRenderTarget *innerRenderTarget
|
var innerImage *innerImage
|
||||||
var err error
|
var err error
|
||||||
u.use(func() {
|
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() {
|
func (u *ui) run() {
|
||||||
|
Loading…
Reference in New Issue
Block a user