mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-12-24 02:38: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 {
|
||||
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)
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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))
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -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")
|
||||
|
@ -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]
|
||||
|
@ -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 {
|
||||
|
@ -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) {
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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++ {
|
||||
|
@ -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))
|
||||
}
|
||||
|
17
graphics.go
17
graphics.go
@ -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()
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
|
@ -24,35 +24,29 @@ import (
|
||||
"image/color"
|
||||
)
|
||||
|
||||
type innerRenderTarget struct {
|
||||
glRenderTarget *opengl.RenderTarget
|
||||
image *Image
|
||||
type innerImage struct {
|
||||
// TODO: Rename them later.
|
||||
glRenderTarget *opengl.Image
|
||||
glTexture *opengl.Texture
|
||||
}
|
||||
|
||||
func newInnerRenderTarget(width, height int, filter int) (*innerRenderTarget, error) {
|
||||
glTexture, err := opengl.NewTexture(width, height, filter)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
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
|
||||
}
|
@ -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
5
run.go
@ -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
35
ui.go
@ -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() {
|
||||
|
Loading…
Reference in New Issue
Block a user