diff --git a/graphics/matrix/affine.go b/affine.go similarity index 86% rename from graphics/matrix/affine.go rename to affine.go index e58a511fd27d..efb995a1cea5 100644 --- a/graphics/matrix/affine.go +++ b/affine.go @@ -1,4 +1,4 @@ -package matrix +package ebiten type affine interface { dim() int @@ -6,11 +6,11 @@ type affine interface { setElement(i, j int, element float64) } -func isIdentity(matrix affine) bool { - dim := matrix.dim() +func isIdentity(ebiten affine) bool { + dim := ebiten.dim() for i := 0; i < dim-1; i++ { for j := 0; j < dim; j++ { - element := matrix.element(i, j) + element := ebiten.element(i, j) if i == j && element != 1 { return false } else if i != j && element != 0 { diff --git a/colormatrix.go b/colormatrix.go new file mode 100644 index 000000000000..9e78d8a78aca --- /dev/null +++ b/colormatrix.go @@ -0,0 +1,85 @@ +package ebiten + +import ( + "image/color" + "math" +) + +const ColorMatrixDim = 5 + +type ColorMatrix struct { + Elements [ColorMatrixDim - 1][ColorMatrixDim]float64 +} + +func ColorMatrixI() ColorMatrix { + return ColorMatrix{ + [ColorMatrixDim - 1][ColorMatrixDim]float64{ + {1, 0, 0, 0, 0}, + {0, 1, 0, 0, 0}, + {0, 0, 1, 0, 0}, + {0, 0, 0, 1, 0}, + }, + } +} + +func (c *ColorMatrix) dim() int { + return ColorMatrixDim +} + +func (c *ColorMatrix) Concat(other ColorMatrix) { + result := ColorMatrix{} + mul(&other, c, &result) + *c = result +} + +func (c *ColorMatrix) IsIdentity() bool { + return isIdentity(c) +} + +func (c *ColorMatrix) element(i, j int) float64 { + return c.Elements[i][j] +} + +func (c *ColorMatrix) setElement(i, j int, element float64) { + c.Elements[i][j] = element +} + +func Monochrome() ColorMatrix { + const r float64 = 6968.0 / 32768.0 + const g float64 = 23434.0 / 32768.0 + const b float64 = 2366.0 / 32768.0 + return ColorMatrix{ + [ColorMatrixDim - 1][ColorMatrixDim]float64{ + {r, g, b, 0, 0}, + {r, g, b, 0, 0}, + {r, g, b, 0, 0}, + {0, 0, 0, 1, 0}, + }, + } +} + +func rgba(clr color.Color) (float64, float64, float64, float64) { + r, g, b, a := clr.RGBA() + rf := float64(r) / float64(math.MaxUint16) + gf := float64(g) / float64(math.MaxUint16) + bf := float64(b) / float64(math.MaxUint16) + af := float64(a) / float64(math.MaxUint16) + return rf, gf, bf, af +} + +func (c *ColorMatrix) Scale(clr color.Color) { + rf, gf, bf, af := rgba(clr) + for i, e := range []float64{rf, gf, bf, af} { + for j := 0; j < 4; j++ { + c.Elements[i][j] *= e + } + } +} + +func (c *ColorMatrix) Translate(clr color.Color) { + rf, gf, bf, af := rgba(clr) + c.Elements[0][4] = rf + c.Elements[1][4] = gf + c.Elements[2][4] = bf + c.Elements[3][4] = af +} diff --git a/graphics/matrix/color_test.go b/colormatrix_test.go similarity index 69% rename from graphics/matrix/color_test.go rename to colormatrix_test.go index 1904aefee8fe..04e7c161716f 100644 --- a/graphics/matrix/color_test.go +++ b/colormatrix_test.go @@ -1,4 +1,4 @@ -package matrix_test +package ebiten_test import ( . "." @@ -6,8 +6,8 @@ import ( ) func TestColorIdentity(t *testing.T) { - matrix := ColorI() - got := matrix.IsIdentity() + ebiten := ColorMatrixI() + got := ebiten.IsIdentity() want := true if want != got { t.Errorf("matrix.IsIdentity() = %t, want %t", got, want) diff --git a/example/blocks.go b/example/blocks.go index 7860c2f1261b..c5489664bb0b 100644 --- a/example/blocks.go +++ b/example/blocks.go @@ -2,9 +2,9 @@ package main import ( "flag" + "github.com/hajimehoshi/ebiten" "github.com/hajimehoshi/ebiten/example/blocks" - "github.com/hajimehoshi/ebiten/ui" - "github.com/hajimehoshi/ebiten/ui/glfw" + "github.com/hajimehoshi/ebiten/glfw" "log" "os" "runtime" @@ -30,7 +30,7 @@ func main() { u := new(glfw.UI) game := blocks.NewGame() - if err := ui.Run(u, game, blocks.ScreenWidth, blocks.ScreenHeight, 2, "Blocks (Ebiten Demo)", 60); err != nil { + if err := ebiten.Run(u, game, blocks.ScreenWidth, blocks.ScreenHeight, 2, "Blocks (Ebiten Demo)", 60); err != nil { log.Fatal(err) } } diff --git a/example/blocks/field.go b/example/blocks/field.go index ae24d7843e64..746aa95e6bcc 100644 --- a/example/blocks/field.go +++ b/example/blocks/field.go @@ -1,8 +1,7 @@ package blocks import ( - "github.com/hajimehoshi/ebiten/graphics" - "github.com/hajimehoshi/ebiten/graphics/matrix" + "github.com/hajimehoshi/ebiten" ) type Field struct { @@ -97,7 +96,7 @@ func (f *Field) flushLine(j int) bool { return true } -func (f *Field) Draw(context graphics.Context, textures *Textures, geo matrix.Geometry) { +func (f *Field) Draw(context ebiten.GraphicsContext, textures *Textures, geo ebiten.GeometryMatrix) { blocks := make([][]BlockType, len(f.blocks)) for i, blockCol := range f.blocks { blocks[i] = make([]BlockType, len(blockCol)) diff --git a/example/blocks/font.go b/example/blocks/font.go index e9482719c33b..57e4896320ac 100644 --- a/example/blocks/font.go +++ b/example/blocks/font.go @@ -1,8 +1,7 @@ package blocks import ( - "github.com/hajimehoshi/ebiten/graphics" - "github.com/hajimehoshi/ebiten/graphics/matrix" + "github.com/hajimehoshi/ebiten" "image/color" ) @@ -17,9 +16,9 @@ func textWidth(str string) int { return charWidth * len(str) } -func drawText(context graphics.Context, textures *Textures, str string, x, y, scale int, clr color.Color) { +func drawText(context ebiten.GraphicsContext, textures *Textures, str string, x, y, scale int, clr color.Color) { fontTextureId := textures.GetTexture("font") - parts := []graphics.TexturePart{} + parts := []ebiten.TexturePart{} locationX := 0 locationY := 0 @@ -32,23 +31,23 @@ func drawText(context graphics.Context, textures *Textures, str string, x, y, sc code := int(c) x := (code % 16) * charWidth y := ((code - 32) / 16) * charHeight - parts = append(parts, graphics.TexturePart{ + parts = append(parts, ebiten.TexturePart{ LocationX: locationX, LocationY: locationY, - Source: graphics.Rect{x, y, charWidth, charHeight}, + Source: ebiten.Rect{x, y, charWidth, charHeight}, }) locationX += charWidth } - geoMat := matrix.GeometryI() + geoMat := ebiten.GeometryMatrixI() geoMat.Scale(float64(scale), float64(scale)) geoMat.Translate(float64(x), float64(y)) - clrMat := matrix.ColorI() + clrMat := ebiten.ColorMatrixI() clrMat.Scale(clr) context.Texture(fontTextureId).Draw(parts, geoMat, clrMat) } -func drawTextWithShadow(context graphics.Context, textures *Textures, str string, x, y, scale int, clr color.Color) { +func drawTextWithShadow(context ebiten.GraphicsContext, textures *Textures, str string, x, y, scale int, clr color.Color) { drawText(context, textures, str, x+1, y+1, scale, color.RGBA{0, 0, 0, 0x80}) drawText(context, textures, str, x, y, scale, clr) } diff --git a/example/blocks/game.go b/example/blocks/game.go index 317f110819eb..7beb99ea80fb 100644 --- a/example/blocks/game.go +++ b/example/blocks/game.go @@ -1,7 +1,7 @@ package blocks import ( - "github.com/hajimehoshi/ebiten/graphics" + "github.com/hajimehoshi/ebiten" "sync" ) @@ -24,14 +24,14 @@ type GameState struct { type Game struct { sceneManager *SceneManager - input *Input + ebiten *Input textures *Textures } func NewGame() *Game { game := &Game{ sceneManager: NewSceneManager(NewTitleScene()), - input: NewInput(), + ebiten: NewInput(), textures: NewTextures(), } return game @@ -65,15 +65,15 @@ func (game *Game) Update() error { if !game.isInitialized() { return nil } - game.input.Update() + game.ebiten.Update() game.sceneManager.Update(&GameState{ SceneManager: game.sceneManager, - Input: game.input, + Input: game.ebiten, }) return nil } -func (game *Game) Draw(context graphics.Context) error { +func (game *Game) Draw(context ebiten.GraphicsContext) error { if !game.isInitialized() { return nil } diff --git a/example/blocks/gamescene.go b/example/blocks/gamescene.go index 74ac911f4cd8..60576d9fb8c5 100644 --- a/example/blocks/gamescene.go +++ b/example/blocks/gamescene.go @@ -1,9 +1,7 @@ package blocks import ( - "github.com/hajimehoshi/ebiten/graphics" - "github.com/hajimehoshi/ebiten/graphics/matrix" - "github.com/hajimehoshi/ebiten/input" + "github.com/hajimehoshi/ebiten" "image/color" "math/rand" "time" @@ -64,26 +62,26 @@ func (s *GameScene) Update(state *GameState) { y := s.currentPieceY angle := s.currentPieceAngle moved := false - if state.Input.StateForKey(input.KeySpace) == 1 { + if state.Input.StateForKey(ebiten.KeySpace) == 1 { s.currentPieceAngle = s.field.RotatePieceRight(piece, x, y, angle) moved = angle != s.currentPieceAngle } - if l := state.Input.StateForKey(input.KeyLeft); l == 1 || (10 <= l && l%2 == 0) { + if l := state.Input.StateForKey(ebiten.KeyLeft); l == 1 || (10 <= l && l%2 == 0) { s.currentPieceX = s.field.MovePieceToLeft(piece, x, y, angle) moved = x != s.currentPieceX } - if r := state.Input.StateForKey(input.KeyRight); r == 1 || (10 <= r && r%2 == 0) { + if r := state.Input.StateForKey(ebiten.KeyRight); r == 1 || (10 <= r && r%2 == 0) { s.currentPieceX = s.field.MovePieceToRight(piece, x, y, angle) moved = y != s.currentPieceX } - if d := state.Input.StateForKey(input.KeyDown); (d-1)%2 == 0 { + if d := state.Input.StateForKey(ebiten.KeyDown); (d-1)%2 == 0 { s.currentPieceY = s.field.DropPiece(piece, x, y, angle) moved = y != s.currentPieceY } if moved { s.landingCount = 0 } else if !s.field.PieceDroppable(piece, x, y, angle) { - if 0 < state.Input.StateForKey(input.KeyDown) { + if 0 < state.Input.StateForKey(ebiten.KeyDown) { s.landingCount += 10 } else { s.landingCount++ @@ -97,20 +95,20 @@ func (s *GameScene) Update(state *GameState) { } } -func (s *GameScene) Draw(context graphics.Context, textures *Textures) { +func (s *GameScene) Draw(context ebiten.GraphicsContext, textures *Textures) { context.Fill(0xff, 0xff, 0xff) field := textures.GetTexture("empty") - geoMat := matrix.GeometryI() + geoMat := ebiten.GeometryMatrixI() geoMat.Scale( float64(fieldWidth)/float64(emptyWidth), float64(fieldHeight)/float64(emptyHeight)) geoMat.Translate(20, 20) // magic number? - colorMat := matrix.ColorI() + colorMat := ebiten.ColorMatrixI() colorMat.Scale(color.RGBA{0, 0, 0, 0x80}) - graphics.DrawWhole(context.Texture(field), emptyWidth, emptyHeight, geoMat, colorMat) + ebiten.DrawWhole(context.Texture(field), emptyWidth, emptyHeight, geoMat, colorMat) - geoMat = matrix.GeometryI() + geoMat = ebiten.GeometryMatrixI() geoMat.Translate(20, 20) s.field.Draw(context, textures, geoMat) diff --git a/example/blocks/input.go b/example/blocks/input.go index 4334a95dac12..61180cf9b1f9 100644 --- a/example/blocks/input.go +++ b/example/blocks/input.go @@ -1,16 +1,16 @@ package blocks import ( - "github.com/hajimehoshi/ebiten/input" + "github.com/hajimehoshi/ebiten" ) type Input struct { - states map[input.Key]int + states map[ebiten.Key]int } func NewInput() *Input { - states := map[input.Key]int{} - for key := input.Key(0); key < input.KeyMax; key++ { + states := map[ebiten.Key]int{} + for key := ebiten.Key(0); key < ebiten.KeyMax; key++ { states[key] = 0 } return &Input{ @@ -18,13 +18,13 @@ func NewInput() *Input { } } -func (i *Input) StateForKey(key input.Key) int { +func (i *Input) StateForKey(key ebiten.Key) int { return i.states[key] } func (i *Input) Update() { for key := range i.states { - if !input.IsKeyPressed(key) { + if !ebiten.IsKeyPressed(key) { i.states[key] = 0 continue } diff --git a/example/blocks/piece.go b/example/blocks/piece.go index 9c115b7e8532..2e99b89abf8b 100644 --- a/example/blocks/piece.go +++ b/example/blocks/piece.go @@ -1,8 +1,7 @@ package blocks import ( - "github.com/hajimehoshi/ebiten/graphics" - "github.com/hajimehoshi/ebiten/graphics/matrix" + "github.com/hajimehoshi/ebiten" ) func init() { @@ -123,8 +122,8 @@ const blockHeight = 10 const fieldBlockNumX = 10 const fieldBlockNumY = 20 -func drawBlocks(context graphics.Context, textures *Textures, blocks [][]BlockType, geo matrix.Geometry) { - parts := []graphics.TexturePart{} +func drawBlocks(context ebiten.GraphicsContext, textures *Textures, blocks [][]BlockType, geo ebiten.GeometryMatrix) { + parts := []ebiten.TexturePart{} for i, blockCol := range blocks { for j, block := range blockCol { if block == BlockTypeNone { @@ -132,11 +131,11 @@ func drawBlocks(context graphics.Context, textures *Textures, blocks [][]BlockTy } locationX := i * blockWidth locationY := j * blockHeight - source := graphics.Rect{ + source := ebiten.Rect{ (int(block) - 1) * blockWidth, 0, blockWidth, blockHeight} parts = append(parts, - graphics.TexturePart{ + ebiten.TexturePart{ LocationX: locationX, LocationY: locationY, Source: source, @@ -144,7 +143,7 @@ func drawBlocks(context graphics.Context, textures *Textures, blocks [][]BlockTy } } blocksTexture := textures.GetTexture("blocks") - context.Texture(blocksTexture).Draw(parts, geo, matrix.ColorI()) + context.Texture(blocksTexture).Draw(parts, geo, ebiten.ColorMatrixI()) } func (p *Piece) InitialPosition() (int, int) { @@ -204,7 +203,7 @@ func (p *Piece) AbsorbInto(field *Field, x, y int, angle Angle) { } } -func (p *Piece) Draw(context graphics.Context, textures *Textures, fieldX, fieldY int, pieceX, pieceY int, angle Angle) { +func (p *Piece) Draw(context ebiten.GraphicsContext, textures *Textures, fieldX, fieldY int, pieceX, pieceY int, angle Angle) { size := len(p.blocks) blocks := make([][]BlockType, size) for i := range p.blocks { @@ -216,7 +215,7 @@ func (p *Piece) Draw(context graphics.Context, textures *Textures, fieldX, field } } - geoMat := matrix.GeometryI() + geoMat := ebiten.GeometryMatrixI() x := fieldX + pieceX*blockWidth y := fieldY + pieceY*blockHeight geoMat.Translate(float64(x), float64(y)) diff --git a/example/blocks/scenemanager.go b/example/blocks/scenemanager.go index d6a11feba56f..8f43c03271be 100644 --- a/example/blocks/scenemanager.go +++ b/example/blocks/scenemanager.go @@ -1,8 +1,7 @@ package blocks import ( - "github.com/hajimehoshi/ebiten/graphics" - "github.com/hajimehoshi/ebiten/graphics/matrix" + "github.com/hajimehoshi/ebiten" ) func init() { @@ -14,7 +13,7 @@ func init() { type Scene interface { Update(state *GameState) - Draw(context graphics.Context, textures *Textures) + Draw(context ebiten.GraphicsContext, textures *Textures) } const transitionMaxCount = 20 @@ -45,7 +44,7 @@ func (s *SceneManager) Update(state *GameState) { } } -func (s *SceneManager) Draw(context graphics.Context, textures *Textures) { +func (s *SceneManager) Draw(context ebiten.GraphicsContext, textures *Textures) { if s.transitionCount == -1 { s.current.Draw(context, textures) return @@ -61,21 +60,21 @@ func (s *SceneManager) Draw(context graphics.Context, textures *Textures) { s.next.Draw(context, textures) context.ResetOffscreen() - color := matrix.ColorI() - graphics.DrawWhole( + color := ebiten.ColorMatrixI() + ebiten.DrawWhole( context.RenderTarget(from), ScreenWidth, ScreenHeight, - matrix.GeometryI(), + ebiten.GeometryMatrixI(), color) alpha := float64(s.transitionCount) / float64(transitionMaxCount) color.Elements[3][3] = alpha - graphics.DrawWhole( + ebiten.DrawWhole( context.RenderTarget(to), ScreenWidth, ScreenHeight, - matrix.GeometryI(), + ebiten.GeometryMatrixI(), color) } diff --git a/example/blocks/textures.go b/example/blocks/textures.go index a33f122e9c10..346ba6855e56 100644 --- a/example/blocks/textures.go +++ b/example/blocks/textures.go @@ -1,7 +1,7 @@ package blocks import ( - "github.com/hajimehoshi/ebiten/graphics" + "github.com/hajimehoshi/ebiten" "image" _ "image/png" "os" @@ -21,8 +21,8 @@ type nameSize struct { type Textures struct { texturePaths chan namePath renderTargetSizes chan nameSize - textures map[string]graphics.TextureID - renderTargets map[string]graphics.RenderTargetID + textures map[string]ebiten.TextureID + renderTargets map[string]ebiten.RenderTargetID sync.RWMutex } @@ -30,8 +30,8 @@ func NewTextures() *Textures { textures := &Textures{ texturePaths: make(chan namePath), renderTargetSizes: make(chan nameSize), - textures: map[string]graphics.TextureID{}, - renderTargets: map[string]graphics.RenderTargetID{}, + textures: map[string]ebiten.TextureID{}, + renderTargets: map[string]ebiten.RenderTargetID{}, } go func() { for { @@ -65,7 +65,7 @@ func (t *Textures) loopMain() { if err != nil { panic(err) } - id, err := graphics.NewTextureID(img, graphics.FilterNearest) + id, err := ebiten.NewTextureID(img, ebiten.FilterNearest) if err != nil { panic(err) } @@ -77,7 +77,7 @@ func (t *Textures) loopMain() { name := s.name size := s.size go func() { - id, err := graphics.NewRenderTargetID(size.Width, size.Height, graphics.FilterNearest) + id, err := ebiten.NewRenderTargetID(size.Width, size.Height, ebiten.FilterNearest) if err != nil { panic(err) } @@ -107,13 +107,13 @@ func (t *Textures) Has(name string) bool { return ok } -func (t *Textures) GetTexture(name string) graphics.TextureID { +func (t *Textures) GetTexture(name string) ebiten.TextureID { t.RLock() defer t.RUnlock() return t.textures[name] } -func (t *Textures) GetRenderTarget(name string) graphics.RenderTargetID { +func (t *Textures) GetRenderTarget(name string) ebiten.RenderTargetID { t.RLock() defer t.RUnlock() return t.renderTargets[name] diff --git a/example/blocks/titlescene.go b/example/blocks/titlescene.go index 9bbf54aa1518..c3dae04da497 100644 --- a/example/blocks/titlescene.go +++ b/example/blocks/titlescene.go @@ -1,9 +1,7 @@ package blocks import ( - "github.com/hajimehoshi/ebiten/graphics" - "github.com/hajimehoshi/ebiten/graphics/matrix" - "github.com/hajimehoshi/ebiten/input" + "github.com/hajimehoshi/ebiten" "image/color" ) @@ -21,12 +19,12 @@ func NewTitleScene() *TitleScene { func (s *TitleScene) Update(state *GameState) { s.count++ - if state.Input.StateForKey(input.KeySpace) == 1 { + if state.Input.StateForKey(ebiten.KeySpace) == 1 { state.SceneManager.GoTo(NewGameScene()) } } -func (s *TitleScene) Draw(context graphics.Context, textures *Textures) { +func (s *TitleScene) Draw(context ebiten.GraphicsContext, textures *Textures) { drawTitleBackground(context, textures, s.count) drawLogo(context, textures, "BLOCKS") @@ -36,31 +34,31 @@ func (s *TitleScene) Draw(context graphics.Context, textures *Textures) { drawTextWithShadow(context, textures, message, x, y, 1, color.RGBA{0x80, 0, 0, 0xff}) } -func drawTitleBackground(context graphics.Context, textures *Textures, c int) { +func drawTitleBackground(context ebiten.GraphicsContext, textures *Textures, c int) { const textureWidth = 32 const textureHeight = 32 backgroundTextureId := textures.GetTexture("background") - parts := []graphics.TexturePart{} + parts := []ebiten.TexturePart{} for j := -1; j < ScreenHeight/textureHeight+1; j++ { for i := 0; i < ScreenWidth/textureWidth+1; i++ { - parts = append(parts, graphics.TexturePart{ + parts = append(parts, ebiten.TexturePart{ LocationX: i * textureWidth, LocationY: j * textureHeight, - Source: graphics.Rect{0, 0, textureWidth, textureHeight}, + Source: ebiten.Rect{0, 0, textureWidth, textureHeight}, }) } } dx := (-c / 4) % textureWidth dy := (c / 4) % textureHeight - geo := matrix.GeometryI() + geo := ebiten.GeometryMatrixI() geo.Translate(float64(dx), float64(dy)) - clr := matrix.ColorI() + clr := ebiten.ColorMatrixI() context.Texture(backgroundTextureId).Draw(parts, geo, clr) } -func drawLogo(context graphics.Context, textures *Textures, str string) { +func drawLogo(context ebiten.GraphicsContext, textures *Textures, str string) { scale := 4 textWidth := textWidth(str) * scale x := (ScreenWidth - textWidth) / 2 diff --git a/geometrymatrix.go b/geometrymatrix.go new file mode 100644 index 000000000000..c54af154a04c --- /dev/null +++ b/geometrymatrix.go @@ -0,0 +1,67 @@ +package ebiten + +import ( + "math" +) + +const GeometryDim = 3 + +type GeometryMatrix struct { + Elements [GeometryDim - 1][GeometryDim]float64 +} + +func GeometryMatrixI() GeometryMatrix { + return GeometryMatrix{ + [GeometryDim - 1][GeometryDim]float64{ + {1, 0, 0}, + {0, 1, 0}, + }, + } +} + +func (g *GeometryMatrix) dim() int { + return GeometryDim +} + +func (g *GeometryMatrix) Concat(other GeometryMatrix) { + result := GeometryMatrix{} + mul(&other, g, &result) + *g = result +} + +func (g *GeometryMatrix) IsIdentity() bool { + return isIdentity(g) +} + +func (g *GeometryMatrix) element(i, j int) float64 { + return g.Elements[i][j] +} + +func (g *GeometryMatrix) setElement(i, j int, element float64) { + g.Elements[i][j] = element +} + +func (g *GeometryMatrix) Translate(tx, ty float64) { + g.Elements[0][2] += tx + g.Elements[1][2] += ty +} + +func (g *GeometryMatrix) Scale(x, y float64) { + g.Elements[0][0] *= x + g.Elements[0][1] *= x + g.Elements[0][2] *= x + g.Elements[1][0] *= y + g.Elements[1][1] *= y + g.Elements[1][2] *= y +} + +func (g *GeometryMatrix) Rotate(theta float64) { + sin, cos := math.Sincos(theta) + rotate := GeometryMatrix{ + [2][3]float64{ + {cos, -sin, 0}, + {sin, cos, 0}, + }, + } + g.Concat(rotate) +} diff --git a/graphics/matrix/geometry_test.go b/geometrymatrix_test.go similarity index 88% rename from graphics/matrix/geometry_test.go rename to geometrymatrix_test.go index 6fa11701097a..faf028641a23 100644 --- a/graphics/matrix/geometry_test.go +++ b/geometrymatrix_test.go @@ -1,4 +1,4 @@ -package matrix_test +package ebiten_test import ( . "." @@ -6,8 +6,8 @@ import ( ) func TestGeometryIdentity(t *testing.T) { - matrix := GeometryI() - got := matrix.IsIdentity() + ebiten := GeometryMatrixI() + got := ebiten.IsIdentity() want := true if want != got { t.Errorf("matrix.IsIdentity() = %t, want %t", got, want) @@ -15,8 +15,8 @@ func TestGeometryIdentity(t *testing.T) { } func TestGeometryConcat(t *testing.T) { - matrix1 := Geometry{} - matrix2 := Geometry{} + matrix1 := GeometryMatrix{} + matrix2 := GeometryMatrix{} matrix1.Elements = [2][3]float64{ {2, 0, 0}, {0, 2, 0}, diff --git a/ui/glfw/canvas.go b/glfw/canvas.go similarity index 68% rename from ui/glfw/canvas.go rename to glfw/canvas.go index fdc1f6c9ddc7..bd7c4b67bbe1 100644 --- a/ui/glfw/canvas.go +++ b/glfw/canvas.go @@ -2,23 +2,22 @@ package glfw import ( glfw "github.com/go-gl/glfw3" - "github.com/hajimehoshi/ebiten/graphics" - "github.com/hajimehoshi/ebiten/graphics/opengl" - "github.com/hajimehoshi/ebiten/ui" + "github.com/hajimehoshi/ebiten" + "github.com/hajimehoshi/ebiten/opengl" "image" "runtime" ) type canvas struct { window *glfw.Window - context *opengl.Context + context *opengl.GraphicsContext keyboard keyboard mouse mouse funcs chan func() funcsDone chan struct{} } -func (c *canvas) Draw(d ui.Drawer) (err error) { +func (c *canvas) Draw(d ebiten.Drawer2) (err error) { c.use(func() { c.context.PreUpdate() }) @@ -36,8 +35,8 @@ func (c *canvas) IsClosed() bool { return c.window.ShouldClose() } -func (c *canvas) NewTextureID(img image.Image, filter graphics.Filter) (graphics.TextureID, error) { - var id graphics.TextureID +func (c *canvas) NewTextureID(img image.Image, filter ebiten.Filter) (ebiten.TextureID, error) { + var id ebiten.TextureID var err error c.use(func() { id, err = opengl.NewTextureID(img, filter) @@ -45,8 +44,8 @@ func (c *canvas) NewTextureID(img image.Image, filter graphics.Filter) (graphics return id, err } -func (c *canvas) NewRenderTargetID(width, height int, filter graphics.Filter) (graphics.RenderTargetID, error) { - var id graphics.RenderTargetID +func (c *canvas) NewRenderTargetID(width, height int, filter ebiten.Filter) (ebiten.RenderTargetID, error) { + var id ebiten.RenderTargetID var err error c.use(func() { id, err = opengl.NewRenderTargetID(width, height, filter) diff --git a/ui/glfw/context.go b/glfw/context.go similarity index 61% rename from ui/glfw/context.go rename to glfw/context.go index d1a7758c6174..da5a8814fe8d 100644 --- a/ui/glfw/context.go +++ b/glfw/context.go @@ -1,15 +1,14 @@ package glfw import ( - "github.com/hajimehoshi/ebiten/graphics" - "github.com/hajimehoshi/ebiten/graphics/matrix" + "github.com/hajimehoshi/ebiten" ) type context struct { canvas *canvas } -var _ graphics.Context = new(context) +var _ ebiten.GraphicsContext = new(context) func (c *context) Clear() { c.canvas.use(func() { @@ -23,7 +22,7 @@ func (c *context) Fill(r, g, b uint8) { }) } -func (c *context) Texture(id graphics.TextureID) (d graphics.Drawer) { +func (c *context) Texture(id ebiten.TextureID) (d ebiten.Drawer) { c.canvas.use(func() { d = &drawer{ canvas: c.canvas, @@ -33,7 +32,7 @@ func (c *context) Texture(id graphics.TextureID) (d graphics.Drawer) { return } -func (c *context) RenderTarget(id graphics.RenderTargetID) (d graphics.Drawer) { +func (c *context) RenderTarget(id ebiten.RenderTargetID) (d ebiten.Drawer) { c.canvas.use(func() { d = &drawer{ canvas: c.canvas, @@ -49,7 +48,7 @@ func (c *context) ResetOffscreen() { }) } -func (c *context) SetOffscreen(id graphics.RenderTargetID) { +func (c *context) SetOffscreen(id ebiten.RenderTargetID) { c.canvas.use(func() { c.canvas.context.SetOffscreen(id) }) @@ -57,12 +56,12 @@ func (c *context) SetOffscreen(id graphics.RenderTargetID) { type drawer struct { canvas *canvas - innerDrawer graphics.Drawer + innerDrawer ebiten.Drawer } -var _ graphics.Drawer = new(drawer) +var _ ebiten.Drawer = new(drawer) -func (d *drawer) Draw(parts []graphics.TexturePart, geo matrix.Geometry, color matrix.Color) { +func (d *drawer) Draw(parts []ebiten.TexturePart, geo ebiten.GeometryMatrix, color ebiten.ColorMatrix) { d.canvas.use(func() { d.innerDrawer.Draw(parts, geo, color) }) diff --git a/glfw/keyboard.go b/glfw/keyboard.go new file mode 100644 index 000000000000..6fedf5b6792c --- /dev/null +++ b/glfw/keyboard.go @@ -0,0 +1,28 @@ +package glfw + +import ( + glfw "github.com/go-gl/glfw3" + "github.com/hajimehoshi/ebiten" +) + +type keyboard struct { + keyPressed [ebiten.KeyMax]bool +} + +func (k *keyboard) IsKeyPressed(key ebiten.Key) bool { + return k.keyPressed[key] +} + +var glfwKeyCodeToKey = map[glfw.Key]ebiten.Key{ + glfw.KeySpace: ebiten.KeySpace, + glfw.KeyLeft: ebiten.KeyLeft, + glfw.KeyRight: ebiten.KeyRight, + glfw.KeyUp: ebiten.KeyUp, + glfw.KeyDown: ebiten.KeyDown, +} + +func (k *keyboard) update(window *glfw.Window) { + for g, u := range glfwKeyCodeToKey { + k.keyPressed[u] = window.GetKey(g) == glfw.Press + } +} diff --git a/ui/glfw/mouse.go b/glfw/mouse.go similarity index 60% rename from ui/glfw/mouse.go rename to glfw/mouse.go index 968818ecab1b..96341b57653d 100644 --- a/ui/glfw/mouse.go +++ b/glfw/mouse.go @@ -2,21 +2,21 @@ package glfw import ( glfw "github.com/go-gl/glfw3" - "github.com/hajimehoshi/ebiten/input" + "github.com/hajimehoshi/ebiten" "math" ) type mouse struct { - buttonPressed [input.MouseButtonMax]bool + buttonPressed [ebiten.MouseButtonMax]bool x int y int } -func (m *mouse) CurrentPosition() (x, y int) { +func (m *mouse) CursorPosition() (x, y int) { return m.x, m.y } -func (m *mouse) IsMouseButtonPressed(button input.MouseButton) bool { +func (m *mouse) IsMouseButtonPressed(button ebiten.MouseButton) bool { return m.buttonPressed[button] } @@ -24,7 +24,7 @@ func (m *mouse) update(window *glfw.Window) { x, y := window.GetCursorPosition() m.x = int(math.Floor(x)) m.y = int(math.Floor(y)) - for i := input.MouseButtonLeft; i < input.MouseButtonMax; i++ { + for i := ebiten.MouseButtonLeft; i < ebiten.MouseButtonMax; i++ { m.buttonPressed[i] = window.GetMouseButton(glfw.MouseButton(i)) == glfw.Press } } diff --git a/ui/glfw/ui.go b/glfw/ui.go similarity index 75% rename from ui/glfw/ui.go rename to glfw/ui.go index 1c050abef789..e47839d10e64 100644 --- a/ui/glfw/ui.go +++ b/glfw/ui.go @@ -4,10 +4,8 @@ import ( "errors" "fmt" glfw "github.com/go-gl/glfw3" - "github.com/hajimehoshi/ebiten/graphics" - "github.com/hajimehoshi/ebiten/graphics/opengl" - "github.com/hajimehoshi/ebiten/input" - "github.com/hajimehoshi/ebiten/ui" + "github.com/hajimehoshi/ebiten" + "github.com/hajimehoshi/ebiten/opengl" ) func init() { @@ -20,7 +18,7 @@ type UI struct { canvas *canvas } -func (u *UI) Start(width, height, scale int, title string) (ui.Canvas, error) { +func (u *UI) Start(width, height, scale int, title string) (ebiten.Canvas, error) { if !glfw.Init() { return nil, errors.New("glfw.Init() fails") } @@ -35,9 +33,9 @@ func (u *UI) Start(width, height, scale int, title string) (ui.Canvas, error) { funcs: make(chan func()), funcsDone: make(chan struct{}), } - input.SetKeyboard(&c.keyboard) - input.SetMouse(&c.mouse) - graphics.SetTextureFactory(c) + ebiten.SetKeyboard(&c.keyboard) + ebiten.SetMouse(&c.mouse) + ebiten.SetTextureFactory(c) c.run(width, height, scale) diff --git a/graphics/matrix/affine_test.go b/graphics/matrix/affine_test.go deleted file mode 100644 index 4ad8108b94b4..000000000000 --- a/graphics/matrix/affine_test.go +++ /dev/null @@ -1 +0,0 @@ -package matrix_test diff --git a/graphics/matrix/color.go b/graphics/matrix/color.go deleted file mode 100644 index a59f2342d18b..000000000000 --- a/graphics/matrix/color.go +++ /dev/null @@ -1,85 +0,0 @@ -package matrix - -import ( - "image/color" - "math" -) - -const ColorDim = 5 - -type Color struct { - Elements [ColorDim - 1][ColorDim]float64 -} - -func ColorI() Color { - return Color{ - [ColorDim - 1][ColorDim]float64{ - {1, 0, 0, 0, 0}, - {0, 1, 0, 0, 0}, - {0, 0, 1, 0, 0}, - {0, 0, 0, 1, 0}, - }, - } -} - -func (matrix *Color) dim() int { - return ColorDim -} - -func (matrix *Color) Concat(other Color) { - result := Color{} - mul(&other, matrix, &result) - *matrix = result -} - -func (matrix *Color) IsIdentity() bool { - return isIdentity(matrix) -} - -func (matrix *Color) element(i, j int) float64 { - return matrix.Elements[i][j] -} - -func (matrix *Color) setElement(i, j int, element float64) { - matrix.Elements[i][j] = element -} - -func Monochrome() Color { - const r float64 = 6968.0 / 32768.0 - const g float64 = 23434.0 / 32768.0 - const b float64 = 2366.0 / 32768.0 - return Color{ - [ColorDim - 1][ColorDim]float64{ - {r, g, b, 0, 0}, - {r, g, b, 0, 0}, - {r, g, b, 0, 0}, - {0, 0, 0, 1, 0}, - }, - } -} - -func rgba(clr color.Color) (float64, float64, float64, float64) { - r, g, b, a := clr.RGBA() - rf := float64(r) / float64(math.MaxUint16) - gf := float64(g) / float64(math.MaxUint16) - bf := float64(b) / float64(math.MaxUint16) - af := float64(a) / float64(math.MaxUint16) - return rf, gf, bf, af -} - -func (matrix *Color) Scale(clr color.Color) { - rf, gf, bf, af := rgba(clr) - for i, e := range []float64{rf, gf, bf, af} { - for j := 0; j < 4; j++ { - matrix.Elements[i][j] *= e - } - } -} - -func (matrix *Color) Translate(clr color.Color) { - rf, gf, bf, af := rgba(clr) - matrix.Elements[0][4] = rf - matrix.Elements[1][4] = gf - matrix.Elements[2][4] = bf - matrix.Elements[3][4] = af -} diff --git a/graphics/matrix/geometry.go b/graphics/matrix/geometry.go deleted file mode 100644 index 631463a4bb1f..000000000000 --- a/graphics/matrix/geometry.go +++ /dev/null @@ -1,67 +0,0 @@ -package matrix - -import ( - "math" -) - -const GeometryDim = 3 - -type Geometry struct { - Elements [GeometryDim - 1][GeometryDim]float64 -} - -func GeometryI() Geometry { - return Geometry{ - [GeometryDim - 1][GeometryDim]float64{ - {1, 0, 0}, - {0, 1, 0}, - }, - } -} - -func (matrix *Geometry) dim() int { - return GeometryDim -} - -func (matrix *Geometry) Concat(other Geometry) { - result := Geometry{} - mul(&other, matrix, &result) - *matrix = result -} - -func (matrix *Geometry) IsIdentity() bool { - return isIdentity(matrix) -} - -func (matrix *Geometry) element(i, j int) float64 { - return matrix.Elements[i][j] -} - -func (matrix *Geometry) setElement(i, j int, element float64) { - matrix.Elements[i][j] = element -} - -func (matrix *Geometry) Translate(tx, ty float64) { - matrix.Elements[0][2] += tx - matrix.Elements[1][2] += ty -} - -func (matrix *Geometry) Scale(x, y float64) { - matrix.Elements[0][0] *= x - matrix.Elements[0][1] *= x - matrix.Elements[0][2] *= x - matrix.Elements[1][0] *= y - matrix.Elements[1][1] *= y - matrix.Elements[1][2] *= y -} - -func (matrix *Geometry) Rotate(theta float64) { - sin, cos := math.Sincos(theta) - rotate := Geometry{ - [2][3]float64{ - {cos, -sin, 0}, - {sin, cos, 0}, - }, - } - matrix.Concat(rotate) -} diff --git a/graphics/context.go b/graphicscontext.go similarity index 71% rename from graphics/context.go rename to graphicscontext.go index 1457f33c0ea5..d2b9e08e1751 100644 --- a/graphics/context.go +++ b/graphicscontext.go @@ -1,8 +1,4 @@ -package graphics - -import ( - "github.com/hajimehoshi/ebiten/graphics/matrix" -) +package ebiten // A Rect represents a rectangle. type Rect struct { @@ -21,11 +17,11 @@ type TexturePart struct { // A Drawer is the interface that draws itself. type Drawer interface { - Draw(parts []TexturePart, geo matrix.Geometry, color matrix.Color) + Draw(parts []TexturePart, geo GeometryMatrix, color ColorMatrix) } // DrawWhole draws the whole texture. -func DrawWhole(drawer Drawer, width, height int, geo matrix.Geometry, color matrix.Color) { +func DrawWhole(drawer Drawer, width, height int, geo GeometryMatrix, color ColorMatrix) { parts := []TexturePart{ {0, 0, Rect{0, 0, width, height}}, } @@ -33,7 +29,7 @@ func DrawWhole(drawer Drawer, width, height int, geo matrix.Geometry, color matr } // A Context is the interface that means a context of rendering. -type Context interface { +type GraphicsContext interface { Clear() Fill(r, g, b uint8) Texture(id TextureID) Drawer diff --git a/input/keyboard.go b/keyboard.go similarity index 96% rename from input/keyboard.go rename to keyboard.go index 45e55c33c0b2..580a0686f844 100644 --- a/input/keyboard.go +++ b/keyboard.go @@ -1,4 +1,4 @@ -package input +package ebiten type Key int diff --git a/input/mouse.go b/mouse.go similarity index 82% rename from input/mouse.go rename to mouse.go index 596670a2c5c8..0060209cd7f7 100644 --- a/input/mouse.go +++ b/mouse.go @@ -1,4 +1,4 @@ -package input +package ebiten type MouseButton int @@ -12,7 +12,7 @@ const ( var currentMouse Mouse type Mouse interface { - CurrentPosition() (x, y int) + CursorPosition() (x, y int) IsMouseButtonPressed(mouseButton MouseButton) bool } @@ -20,11 +20,11 @@ func SetMouse(mouse Mouse) { currentMouse = mouse } -func CurrentPosition() (x, y int) { +func CursorPosition() (x, y int) { if currentMouse == nil { panic("input.CurrentPosition: currentMouse is not set") } - return currentMouse.CurrentPosition() + return currentMouse.CursorPosition() } func IsMouseButtonPressed(button MouseButton) bool { diff --git a/graphics/opengl/context.go b/opengl/context.go similarity index 51% rename from graphics/opengl/context.go rename to opengl/context.go index 5f44ecae8a9b..3624b20f8e3f 100644 --- a/graphics/opengl/context.go +++ b/opengl/context.go @@ -2,16 +2,15 @@ package opengl import ( "github.com/go-gl/gl" - "github.com/hajimehoshi/ebiten/graphics" - "github.com/hajimehoshi/ebiten/graphics/matrix" + "github.com/hajimehoshi/ebiten" ) -func Initialize(screenWidth, screenHeight, screenScale int) (*Context, error) { +func Initialize(screenWidth, screenHeight, screenScale int) (*GraphicsContext, error) { gl.Init() gl.Enable(gl.TEXTURE_2D) gl.Enable(gl.BLEND) - c := &Context{ + c := &GraphicsContext{ screenWidth: screenWidth, screenHeight: screenHeight, screenScale: screenScale, @@ -25,7 +24,7 @@ func Initialize(screenWidth, screenHeight, screenScale int) (*Context, error) { }) var err error - c.screenId, err = idsInstance.createRenderTarget(screenWidth, screenHeight, graphics.FilterNearest) + c.screenId, err = idsInstance.createRenderTarget(screenWidth, screenHeight, ebiten.FilterNearest) if err != nil { return nil, err } @@ -35,66 +34,68 @@ func Initialize(screenWidth, screenHeight, screenScale int) (*Context, error) { return c, nil } -type Context struct { - screenId graphics.RenderTargetID - defaultId graphics.RenderTargetID - currentId graphics.RenderTargetID +type GraphicsContext struct { + screenId ebiten.RenderTargetID + defaultId ebiten.RenderTargetID + currentId ebiten.RenderTargetID screenWidth int screenHeight int screenScale int } -func (c *Context) dispose() { +var _ ebiten.GraphicsContext = new(GraphicsContext) + +func (c *GraphicsContext) dispose() { // NOTE: Now this method is not used anywhere. idsInstance.deleteRenderTarget(c.screenId) } -func (c *Context) Clear() { +func (c *GraphicsContext) Clear() { c.Fill(0, 0, 0) } -func (c *Context) Fill(r, g, b uint8) { +func (c *GraphicsContext) Fill(r, g, b uint8) { idsInstance.fillRenderTarget(c.currentId, r, g, b) } -func (c *Context) Texture(id graphics.TextureID) graphics.Drawer { +func (c *GraphicsContext) Texture(id ebiten.TextureID) ebiten.Drawer { return &textureWithContext{id, c} } -func (c *Context) RenderTarget(id graphics.RenderTargetID) graphics.Drawer { +func (c *GraphicsContext) RenderTarget(id ebiten.RenderTargetID) ebiten.Drawer { return &textureWithContext{idsInstance.toTexture(id), c} } -func (c *Context) ResetOffscreen() { +func (c *GraphicsContext) ResetOffscreen() { c.currentId = c.screenId } -func (c *Context) SetOffscreen(renderTargetId graphics.RenderTargetID) { +func (c *GraphicsContext) SetOffscreen(renderTargetId ebiten.RenderTargetID) { c.currentId = renderTargetId } -func (c *Context) PreUpdate() { +func (c *GraphicsContext) PreUpdate() { c.ResetOffscreen() c.Clear() } -func (c *Context) PostUpdate() { +func (c *GraphicsContext) PostUpdate() { c.SetOffscreen(c.defaultId) c.Clear() scale := float64(c.screenScale) - geo := matrix.GeometryI() + geo := ebiten.GeometryMatrixI() geo.Scale(scale, scale) - graphics.DrawWhole(c.RenderTarget(c.screenId), c.screenWidth, c.screenHeight, geo, matrix.ColorI()) + ebiten.DrawWhole(c.RenderTarget(c.screenId), c.screenWidth, c.screenHeight, geo, ebiten.ColorMatrixI()) gl.Flush() } type textureWithContext struct { - id graphics.TextureID - context *Context + id ebiten.TextureID + context *GraphicsContext } -func (t *textureWithContext) Draw(parts []graphics.TexturePart, geo matrix.Geometry, color matrix.Color) { +func (t *textureWithContext) Draw(parts []ebiten.TexturePart, geo ebiten.GeometryMatrix, color ebiten.ColorMatrix) { idsInstance.drawTexture(t.context.currentId, t.id, parts, geo, color) } diff --git a/graphics/opengl/ids.go b/opengl/ids.go similarity index 55% rename from graphics/opengl/ids.go rename to opengl/ids.go index 457039e2107e..22261e920970 100644 --- a/graphics/opengl/ids.go +++ b/opengl/ids.go @@ -2,57 +2,56 @@ package opengl import ( "github.com/go-gl/gl" - "github.com/hajimehoshi/ebiten/graphics" - "github.com/hajimehoshi/ebiten/graphics/matrix" - "github.com/hajimehoshi/ebiten/graphics/opengl/internal/shader" + "github.com/hajimehoshi/ebiten" + "github.com/hajimehoshi/ebiten/opengl/internal/shader" "image" "math" "sync" ) type ids struct { - textures map[graphics.TextureID]*texture - renderTargets map[graphics.RenderTargetID]*renderTarget - renderTargetToTexture map[graphics.RenderTargetID]graphics.TextureID + textures map[ebiten.TextureID]*texture + renderTargets map[ebiten.RenderTargetID]*renderTarget + renderTargetToTexture map[ebiten.RenderTargetID]ebiten.TextureID lastId int - currentRenderTargetId graphics.RenderTargetID + currentRenderTargetId ebiten.RenderTargetID sync.RWMutex } var idsInstance = &ids{ - textures: map[graphics.TextureID]*texture{}, - renderTargets: map[graphics.RenderTargetID]*renderTarget{}, - renderTargetToTexture: map[graphics.RenderTargetID]graphics.TextureID{}, + textures: map[ebiten.TextureID]*texture{}, + renderTargets: map[ebiten.RenderTargetID]*renderTarget{}, + renderTargetToTexture: map[ebiten.RenderTargetID]ebiten.TextureID{}, currentRenderTargetId: -1, } -func NewRenderTargetID(width, height int, filter graphics.Filter) (graphics.RenderTargetID, error) { +func NewRenderTargetID(width, height int, filter ebiten.Filter) (ebiten.RenderTargetID, error) { return idsInstance.createRenderTarget(width, height, filter) } -func NewTextureID(img image.Image, filter graphics.Filter) (graphics.TextureID, error) { +func NewTextureID(img image.Image, filter ebiten.Filter) (ebiten.TextureID, error) { return idsInstance.createTexture(img, filter) } -func (i *ids) textureAt(id graphics.TextureID) *texture { +func (i *ids) textureAt(id ebiten.TextureID) *texture { i.RLock() defer i.RUnlock() return i.textures[id] } -func (i *ids) renderTargetAt(id graphics.RenderTargetID) *renderTarget { +func (i *ids) renderTargetAt(id ebiten.RenderTargetID) *renderTarget { i.RLock() defer i.RUnlock() return i.renderTargets[id] } -func (i *ids) toTexture(id graphics.RenderTargetID) graphics.TextureID { +func (i *ids) toTexture(id ebiten.RenderTargetID) ebiten.TextureID { i.RLock() defer i.RUnlock() return i.renderTargetToTexture[id] } -func (i *ids) createTexture(img image.Image, filter graphics.Filter) (graphics.TextureID, error) { +func (i *ids) createTexture(img image.Image, filter ebiten.Filter) (ebiten.TextureID, error) { texture, err := createTextureFromImage(img, filter) if err != nil { return 0, err @@ -61,12 +60,12 @@ func (i *ids) createTexture(img image.Image, filter graphics.Filter) (graphics.T i.Lock() defer i.Unlock() i.lastId++ - textureId := graphics.TextureID(i.lastId) + textureId := ebiten.TextureID(i.lastId) i.textures[textureId] = texture return textureId, nil } -func (i *ids) createRenderTarget(width, height int, filter graphics.Filter) (graphics.RenderTargetID, error) { +func (i *ids) createRenderTarget(width, height int, filter ebiten.Filter) (ebiten.RenderTargetID, error) { texture, err := createTexture(width, height, filter) if err != nil { return 0, err @@ -83,9 +82,9 @@ func (i *ids) createRenderTarget(width, height int, filter graphics.Filter) (gra i.Lock() defer i.Unlock() i.lastId++ - textureId := graphics.TextureID(i.lastId) + textureId := ebiten.TextureID(i.lastId) i.lastId++ - renderTargetId := graphics.RenderTargetID(i.lastId) + renderTargetId := ebiten.RenderTargetID(i.lastId) i.textures[textureId] = texture i.renderTargets[renderTargetId] = r @@ -95,17 +94,17 @@ func (i *ids) createRenderTarget(width, height int, filter graphics.Filter) (gra } // NOTE: renderTarget can't be used as a texture. -func (i *ids) addRenderTarget(renderTarget *renderTarget) graphics.RenderTargetID { +func (i *ids) addRenderTarget(renderTarget *renderTarget) ebiten.RenderTargetID { i.Lock() defer i.Unlock() i.lastId++ - id := graphics.RenderTargetID(i.lastId) + id := ebiten.RenderTargetID(i.lastId) i.renderTargets[id] = renderTarget return id } -func (i *ids) deleteRenderTarget(id graphics.RenderTargetID) { +func (i *ids) deleteRenderTarget(id ebiten.RenderTargetID) { i.Lock() defer i.Unlock() @@ -121,14 +120,14 @@ func (i *ids) deleteRenderTarget(id graphics.RenderTargetID) { delete(i.textures, textureId) } -func (i *ids) fillRenderTarget(id graphics.RenderTargetID, r, g, b uint8) { +func (i *ids) fillRenderTarget(id ebiten.RenderTargetID, r, g, b uint8) { i.setViewportIfNeeded(id) const max = float64(math.MaxUint8) gl.ClearColor(gl.GLclampf(float64(r)/max), gl.GLclampf(float64(g)/max), gl.GLclampf(float64(b)/max), 1) gl.Clear(gl.COLOR_BUFFER_BIT) } -func (i *ids) drawTexture(target graphics.RenderTargetID, id graphics.TextureID, parts []graphics.TexturePart, geo matrix.Geometry, color matrix.Color) { +func (i *ids) drawTexture(target ebiten.RenderTargetID, id ebiten.TextureID, parts []ebiten.TexturePart, geo ebiten.GeometryMatrix, color ebiten.ColorMatrix) { texture := i.textureAt(id) i.setViewportIfNeeded(target) r := i.renderTargetAt(target) @@ -136,7 +135,7 @@ func (i *ids) drawTexture(target graphics.RenderTargetID, id graphics.TextureID, shader.DrawTexture(texture.native, texture.width, texture.height, projectionMatrix, parts, geo, color) } -func (i *ids) setViewportIfNeeded(id graphics.RenderTargetID) { +func (i *ids) setViewportIfNeeded(id ebiten.RenderTargetID) { r := i.renderTargetAt(id) if i.currentRenderTargetId != id { r.setAsViewport() diff --git a/graphics/opengl/internal/shader/drawtexture.go b/opengl/internal/shader/drawtexture.go similarity index 84% rename from graphics/opengl/internal/shader/drawtexture.go rename to opengl/internal/shader/drawtexture.go index 0afc7916676c..d89ed3d9a276 100644 --- a/graphics/opengl/internal/shader/drawtexture.go +++ b/opengl/internal/shader/drawtexture.go @@ -2,16 +2,15 @@ package shader import ( "github.com/go-gl/gl" - "github.com/hajimehoshi/ebiten/graphics" - "github.com/hajimehoshi/ebiten/graphics/matrix" + "github.com/hajimehoshi/ebiten" "sync" ) -func glMatrix(matrix [4][4]float64) [16]float32 { +func glMatrix(ebiten [4][4]float64) [16]float32 { result := [16]float32{} for j := 0; j < 4; j++ { for i := 0; i < 4; i++ { - result[i+j*4] = float32(matrix[i][j]) + result[i+j*4] = float32(ebiten[i][j]) } } return result @@ -19,7 +18,8 @@ func glMatrix(matrix [4][4]float64) [16]float32 { var once sync.Once -func DrawTexture(native gl.Texture, width, height int, projectionMatrix [4][4]float64, parts []graphics.TexturePart, geo matrix.Geometry, color matrix.Color) { +// TODO: Use VBO +func DrawTexture(native gl.Texture, width, height int, projectionMatrix [4][4]float64, parts []ebiten.TexturePart, geo ebiten.GeometryMatrix, color ebiten.ColorMatrix) { once.Do(func() { initialize() }) @@ -51,7 +51,7 @@ func DrawTexture(native gl.Texture, width, height int, projectionMatrix [4][4]fl vertices := []float32{} texCoords := []float32{} indicies := []uint32{} - // TODO: Check len(parts) and GL_MAX_ELEMENTS_INDICES + // TODO: Check len(parts) and gl.MAX_ELEMENTS_INDICES? for i, quad := range quads { x1 := quad.VertexX1 x2 := quad.VertexX2 diff --git a/graphics/opengl/internal/shader/program.go b/opengl/internal/shader/program.go similarity index 94% rename from graphics/opengl/internal/shader/program.go rename to opengl/internal/shader/program.go index ab181418b38f..5cbdc8920a1a 100644 --- a/graphics/opengl/internal/shader/program.go +++ b/opengl/internal/shader/program.go @@ -2,7 +2,7 @@ package shader import ( "github.com/go-gl/gl" - "github.com/hajimehoshi/ebiten/graphics/matrix" + "github.com/hajimehoshi/ebiten" ) type program struct { @@ -65,7 +65,7 @@ func getUniformLocation(program gl.Program, name string) gl.UniformLocation { return location } -func use(projectionMatrix [16]float32, geo matrix.Geometry, color matrix.Color) gl.Program { +func use(projectionMatrix [16]float32, geo ebiten.GeometryMatrix, color ebiten.ColorMatrix) gl.Program { // TODO: Check the performance. program := programColorMatrix diff --git a/graphics/opengl/internal/shader/shader.go b/opengl/internal/shader/shader.go similarity index 100% rename from graphics/opengl/internal/shader/shader.go rename to opengl/internal/shader/shader.go diff --git a/graphics/opengl/internal/shader/texturequad.go b/opengl/internal/shader/texturequad.go similarity index 90% rename from graphics/opengl/internal/shader/texturequad.go rename to opengl/internal/shader/texturequad.go index e7654037f6c4..7535c88f75bf 100644 --- a/graphics/opengl/internal/shader/texturequad.go +++ b/opengl/internal/shader/texturequad.go @@ -1,7 +1,7 @@ package shader import ( - "github.com/hajimehoshi/ebiten/graphics" + "github.com/hajimehoshi/ebiten" ) type textureQuad struct { @@ -38,7 +38,7 @@ func v(y int, height int) float32 { return float32(y) / float32(AdjustSizeForTexture(height)) } -func textureQuads(parts []graphics.TexturePart, width, height int) []textureQuad { +func textureQuads(parts []ebiten.TexturePart, width, height int) []textureQuad { quads := []textureQuad{} for _, part := range parts { x1 := float32(part.LocationX) diff --git a/graphics/opengl/internal/shader/texturequad_test.go b/opengl/internal/shader/texturequad_test.go similarity index 100% rename from graphics/opengl/internal/shader/texturequad_test.go rename to opengl/internal/shader/texturequad_test.go diff --git a/graphics/opengl/rendertarget.go b/opengl/rendertarget.go similarity index 88% rename from graphics/opengl/rendertarget.go rename to opengl/rendertarget.go index cc44eb339dc3..4d37108da3af 100644 --- a/graphics/opengl/rendertarget.go +++ b/opengl/rendertarget.go @@ -3,7 +3,7 @@ package opengl import ( "fmt" "github.com/go-gl/gl" - "github.com/hajimehoshi/ebiten/graphics/opengl/internal/shader" + "github.com/hajimehoshi/ebiten/opengl/internal/shader" ) func orthoProjectionMatrix(left, right, bottom, top int) [4][4]float64 { @@ -62,12 +62,12 @@ func (r *renderTarget) setAsViewport() { func (r *renderTarget) projectionMatrix() [4][4]float64 { width := shader.AdjustSizeForTexture(r.width) height := shader.AdjustSizeForTexture(r.height) - matrix := orthoProjectionMatrix(0, width, 0, height) + ebiten := orthoProjectionMatrix(0, width, 0, height) if r.flipY { - matrix[1][1] *= -1 - matrix[1][3] += float64(r.height) / float64(shader.AdjustSizeForTexture(r.height)) * 2 + ebiten[1][1] *= -1 + ebiten[1][3] += float64(r.height) / float64(shader.AdjustSizeForTexture(r.height)) * 2 } - return matrix + return ebiten } func (r *renderTarget) dispose() { diff --git a/graphics/opengl/texture.go b/opengl/texture.go similarity index 82% rename from graphics/opengl/texture.go rename to opengl/texture.go index 521a5495f5e0..3508870270f6 100644 --- a/graphics/opengl/texture.go +++ b/opengl/texture.go @@ -2,8 +2,8 @@ package opengl import ( "github.com/go-gl/gl" - "github.com/hajimehoshi/ebiten/graphics" - "github.com/hajimehoshi/ebiten/graphics/opengl/internal/shader" + "github.com/hajimehoshi/ebiten" + "github.com/hajimehoshi/ebiten/opengl/internal/shader" "image" "image/draw" ) @@ -36,7 +36,7 @@ type texture struct { height int } -func createNativeTexture(textureWidth, textureHeight int, pixels []uint8, filter graphics.Filter) gl.Texture { +func createNativeTexture(textureWidth, textureHeight int, pixels []uint8, filter ebiten.Filter) gl.Texture { nativeTexture := gl.GenTexture() if nativeTexture < 0 { panic("glGenTexture failed") @@ -47,9 +47,9 @@ func createNativeTexture(textureWidth, textureHeight int, pixels []uint8, filter glFilter := 0 switch filter { - case graphics.FilterLinear: + case ebiten.FilterLinear: glFilter = gl.LINEAR - case graphics.FilterNearest: + case ebiten.FilterNearest: glFilter = gl.NEAREST default: panic("not reached") @@ -62,14 +62,14 @@ func createNativeTexture(textureWidth, textureHeight int, pixels []uint8, filter return nativeTexture } -func createTexture(width, height int, filter graphics.Filter) (*texture, error) { +func createTexture(width, height int, filter ebiten.Filter) (*texture, error) { w := shader.AdjustSizeForTexture(width) h := shader.AdjustSizeForTexture(height) native := createNativeTexture(w, h, nil, filter) return &texture{native, width, height}, nil } -func createTextureFromImage(img image.Image, filter graphics.Filter) (*texture, error) { +func createTextureFromImage(img image.Image, filter ebiten.Filter) (*texture, error) { adjustedImage := adjustImageForTexture(img) size := adjustedImage.Bounds().Size() native := createNativeTexture(size.X, size.Y, adjustedImage.Pix, filter) diff --git a/ui/run.go b/run.go similarity index 89% rename from ui/run.go rename to run.go index 9a202ea74144..b4c07f02ae55 100644 --- a/ui/run.go +++ b/run.go @@ -1,7 +1,6 @@ -package ui +package ebiten import ( - "github.com/hajimehoshi/ebiten/graphics" "os" "os/signal" "syscall" @@ -10,7 +9,7 @@ import ( type Game interface { Update() error - Draw(context graphics.Context) error + Draw(context GraphicsContext) error } func Run(u UI, game Game, width, height, scale int, title string, fps int) error { diff --git a/graphics/texturefactory.go b/texturefactory.go similarity index 99% rename from graphics/texturefactory.go rename to texturefactory.go index ee3497d9d3b8..f7d17a755b44 100644 --- a/graphics/texturefactory.go +++ b/texturefactory.go @@ -1,4 +1,4 @@ -package graphics +package ebiten import ( "image" diff --git a/ui/ui.go b/ui.go similarity index 51% rename from ui/ui.go rename to ui.go index c6b0fdef0701..e4924b44d219 100644 --- a/ui/ui.go +++ b/ui.go @@ -1,8 +1,4 @@ -package ui - -import ( - "github.com/hajimehoshi/ebiten/graphics" -) +package ebiten type UI interface { Start(widht, height, scale int, title string) (Canvas, error) @@ -10,11 +6,12 @@ type UI interface { Terminate() } -type Drawer interface { - Draw(c graphics.Context) error +// FIXME: rename this +type Drawer2 interface { + Draw(c GraphicsContext) error } type Canvas interface { - Draw(drawer Drawer) error + Draw(drawer Drawer2) error IsClosed() bool } diff --git a/ui/glfw/keyboard.go b/ui/glfw/keyboard.go deleted file mode 100644 index ce779377fea8..000000000000 --- a/ui/glfw/keyboard.go +++ /dev/null @@ -1,28 +0,0 @@ -package glfw - -import ( - glfw "github.com/go-gl/glfw3" - "github.com/hajimehoshi/ebiten/input" -) - -type keyboard struct { - keyPressed [input.KeyMax]bool -} - -func (k *keyboard) IsKeyPressed(key input.Key) bool { - return k.keyPressed[key] -} - -var glfwKeyCodeToKey = map[glfw.Key]input.Key{ - glfw.KeySpace: input.KeySpace, - glfw.KeyLeft: input.KeyLeft, - glfw.KeyRight: input.KeyRight, - glfw.KeyUp: input.KeyUp, - glfw.KeyDown: input.KeyDown, -} - -func (k *keyboard) update(window *glfw.Window) { - for g, u := range glfwKeyCodeToKey { - k.keyPressed[u] = window.GetKey(g) == glfw.Press - } -}