mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-11-10 04:57:26 +01:00
Unify packages to ebiten (#19)
This commit is contained in:
parent
7311369a07
commit
164b320170
@ -1,4 +1,4 @@
|
|||||||
package matrix
|
package ebiten
|
||||||
|
|
||||||
type affine interface {
|
type affine interface {
|
||||||
dim() int
|
dim() int
|
||||||
@ -6,11 +6,11 @@ type affine interface {
|
|||||||
setElement(i, j int, element float64)
|
setElement(i, j int, element float64)
|
||||||
}
|
}
|
||||||
|
|
||||||
func isIdentity(matrix affine) bool {
|
func isIdentity(ebiten affine) bool {
|
||||||
dim := matrix.dim()
|
dim := ebiten.dim()
|
||||||
for i := 0; i < dim-1; i++ {
|
for i := 0; i < dim-1; i++ {
|
||||||
for j := 0; j < dim; j++ {
|
for j := 0; j < dim; j++ {
|
||||||
element := matrix.element(i, j)
|
element := ebiten.element(i, j)
|
||||||
if i == j && element != 1 {
|
if i == j && element != 1 {
|
||||||
return false
|
return false
|
||||||
} else if i != j && element != 0 {
|
} else if i != j && element != 0 {
|
85
colormatrix.go
Normal file
85
colormatrix.go
Normal file
@ -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
|
||||||
|
}
|
@ -1,4 +1,4 @@
|
|||||||
package matrix_test
|
package ebiten_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
. "."
|
. "."
|
||||||
@ -6,8 +6,8 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func TestColorIdentity(t *testing.T) {
|
func TestColorIdentity(t *testing.T) {
|
||||||
matrix := ColorI()
|
ebiten := ColorMatrixI()
|
||||||
got := matrix.IsIdentity()
|
got := ebiten.IsIdentity()
|
||||||
want := true
|
want := true
|
||||||
if want != got {
|
if want != got {
|
||||||
t.Errorf("matrix.IsIdentity() = %t, want %t", got, want)
|
t.Errorf("matrix.IsIdentity() = %t, want %t", got, want)
|
@ -2,9 +2,9 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"flag"
|
"flag"
|
||||||
|
"github.com/hajimehoshi/ebiten"
|
||||||
"github.com/hajimehoshi/ebiten/example/blocks"
|
"github.com/hajimehoshi/ebiten/example/blocks"
|
||||||
"github.com/hajimehoshi/ebiten/ui"
|
"github.com/hajimehoshi/ebiten/glfw"
|
||||||
"github.com/hajimehoshi/ebiten/ui/glfw"
|
|
||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
"runtime"
|
"runtime"
|
||||||
@ -30,7 +30,7 @@ func main() {
|
|||||||
|
|
||||||
u := new(glfw.UI)
|
u := new(glfw.UI)
|
||||||
game := blocks.NewGame()
|
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)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,7 @@
|
|||||||
package blocks
|
package blocks
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/hajimehoshi/ebiten/graphics"
|
"github.com/hajimehoshi/ebiten"
|
||||||
"github.com/hajimehoshi/ebiten/graphics/matrix"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type Field struct {
|
type Field struct {
|
||||||
@ -97,7 +96,7 @@ func (f *Field) flushLine(j int) bool {
|
|||||||
return true
|
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))
|
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))
|
||||||
|
@ -1,8 +1,7 @@
|
|||||||
package blocks
|
package blocks
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/hajimehoshi/ebiten/graphics"
|
"github.com/hajimehoshi/ebiten"
|
||||||
"github.com/hajimehoshi/ebiten/graphics/matrix"
|
|
||||||
"image/color"
|
"image/color"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -17,9 +16,9 @@ func textWidth(str string) int {
|
|||||||
return charWidth * len(str)
|
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")
|
fontTextureId := textures.GetTexture("font")
|
||||||
parts := []graphics.TexturePart{}
|
parts := []ebiten.TexturePart{}
|
||||||
|
|
||||||
locationX := 0
|
locationX := 0
|
||||||
locationY := 0
|
locationY := 0
|
||||||
@ -32,23 +31,23 @@ func drawText(context graphics.Context, textures *Textures, str string, x, y, sc
|
|||||||
code := int(c)
|
code := int(c)
|
||||||
x := (code % 16) * charWidth
|
x := (code % 16) * charWidth
|
||||||
y := ((code - 32) / 16) * charHeight
|
y := ((code - 32) / 16) * charHeight
|
||||||
parts = append(parts, graphics.TexturePart{
|
parts = append(parts, ebiten.TexturePart{
|
||||||
LocationX: locationX,
|
LocationX: locationX,
|
||||||
LocationY: locationY,
|
LocationY: locationY,
|
||||||
Source: graphics.Rect{x, y, charWidth, charHeight},
|
Source: ebiten.Rect{x, y, charWidth, charHeight},
|
||||||
})
|
})
|
||||||
locationX += charWidth
|
locationX += charWidth
|
||||||
}
|
}
|
||||||
|
|
||||||
geoMat := matrix.GeometryI()
|
geoMat := ebiten.GeometryMatrixI()
|
||||||
geoMat.Scale(float64(scale), float64(scale))
|
geoMat.Scale(float64(scale), float64(scale))
|
||||||
geoMat.Translate(float64(x), float64(y))
|
geoMat.Translate(float64(x), float64(y))
|
||||||
clrMat := matrix.ColorI()
|
clrMat := ebiten.ColorMatrixI()
|
||||||
clrMat.Scale(clr)
|
clrMat.Scale(clr)
|
||||||
context.Texture(fontTextureId).Draw(parts, geoMat, clrMat)
|
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+1, y+1, scale, color.RGBA{0, 0, 0, 0x80})
|
||||||
drawText(context, textures, str, x, y, scale, clr)
|
drawText(context, textures, str, x, y, scale, clr)
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
package blocks
|
package blocks
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/hajimehoshi/ebiten/graphics"
|
"github.com/hajimehoshi/ebiten"
|
||||||
"sync"
|
"sync"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -24,14 +24,14 @@ type GameState struct {
|
|||||||
|
|
||||||
type Game struct {
|
type Game struct {
|
||||||
sceneManager *SceneManager
|
sceneManager *SceneManager
|
||||||
input *Input
|
ebiten *Input
|
||||||
textures *Textures
|
textures *Textures
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewGame() *Game {
|
func NewGame() *Game {
|
||||||
game := &Game{
|
game := &Game{
|
||||||
sceneManager: NewSceneManager(NewTitleScene()),
|
sceneManager: NewSceneManager(NewTitleScene()),
|
||||||
input: NewInput(),
|
ebiten: NewInput(),
|
||||||
textures: NewTextures(),
|
textures: NewTextures(),
|
||||||
}
|
}
|
||||||
return game
|
return game
|
||||||
@ -65,15 +65,15 @@ func (game *Game) Update() error {
|
|||||||
if !game.isInitialized() {
|
if !game.isInitialized() {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
game.input.Update()
|
game.ebiten.Update()
|
||||||
game.sceneManager.Update(&GameState{
|
game.sceneManager.Update(&GameState{
|
||||||
SceneManager: game.sceneManager,
|
SceneManager: game.sceneManager,
|
||||||
Input: game.input,
|
Input: game.ebiten,
|
||||||
})
|
})
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (game *Game) Draw(context graphics.Context) error {
|
func (game *Game) Draw(context ebiten.GraphicsContext) error {
|
||||||
if !game.isInitialized() {
|
if !game.isInitialized() {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,7 @@
|
|||||||
package blocks
|
package blocks
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/hajimehoshi/ebiten/graphics"
|
"github.com/hajimehoshi/ebiten"
|
||||||
"github.com/hajimehoshi/ebiten/graphics/matrix"
|
|
||||||
"github.com/hajimehoshi/ebiten/input"
|
|
||||||
"image/color"
|
"image/color"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
"time"
|
"time"
|
||||||
@ -64,26 +62,26 @@ func (s *GameScene) Update(state *GameState) {
|
|||||||
y := s.currentPieceY
|
y := s.currentPieceY
|
||||||
angle := s.currentPieceAngle
|
angle := s.currentPieceAngle
|
||||||
moved := false
|
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)
|
s.currentPieceAngle = s.field.RotatePieceRight(piece, x, y, angle)
|
||||||
moved = angle != s.currentPieceAngle
|
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)
|
s.currentPieceX = s.field.MovePieceToLeft(piece, x, y, angle)
|
||||||
moved = x != s.currentPieceX
|
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)
|
s.currentPieceX = s.field.MovePieceToRight(piece, x, y, angle)
|
||||||
moved = y != s.currentPieceX
|
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)
|
s.currentPieceY = s.field.DropPiece(piece, x, y, angle)
|
||||||
moved = y != s.currentPieceY
|
moved = y != s.currentPieceY
|
||||||
}
|
}
|
||||||
if moved {
|
if moved {
|
||||||
s.landingCount = 0
|
s.landingCount = 0
|
||||||
} else if !s.field.PieceDroppable(piece, x, y, angle) {
|
} 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
|
s.landingCount += 10
|
||||||
} else {
|
} else {
|
||||||
s.landingCount++
|
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)
|
context.Fill(0xff, 0xff, 0xff)
|
||||||
|
|
||||||
field := textures.GetTexture("empty")
|
field := textures.GetTexture("empty")
|
||||||
geoMat := matrix.GeometryI()
|
geoMat := ebiten.GeometryMatrixI()
|
||||||
geoMat.Scale(
|
geoMat.Scale(
|
||||||
float64(fieldWidth)/float64(emptyWidth),
|
float64(fieldWidth)/float64(emptyWidth),
|
||||||
float64(fieldHeight)/float64(emptyHeight))
|
float64(fieldHeight)/float64(emptyHeight))
|
||||||
geoMat.Translate(20, 20) // magic number?
|
geoMat.Translate(20, 20) // magic number?
|
||||||
colorMat := matrix.ColorI()
|
colorMat := ebiten.ColorMatrixI()
|
||||||
colorMat.Scale(color.RGBA{0, 0, 0, 0x80})
|
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)
|
geoMat.Translate(20, 20)
|
||||||
s.field.Draw(context, textures, geoMat)
|
s.field.Draw(context, textures, geoMat)
|
||||||
|
|
||||||
|
@ -1,16 +1,16 @@
|
|||||||
package blocks
|
package blocks
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/hajimehoshi/ebiten/input"
|
"github.com/hajimehoshi/ebiten"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Input struct {
|
type Input struct {
|
||||||
states map[input.Key]int
|
states map[ebiten.Key]int
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewInput() *Input {
|
func NewInput() *Input {
|
||||||
states := map[input.Key]int{}
|
states := map[ebiten.Key]int{}
|
||||||
for key := input.Key(0); key < input.KeyMax; key++ {
|
for key := ebiten.Key(0); key < ebiten.KeyMax; key++ {
|
||||||
states[key] = 0
|
states[key] = 0
|
||||||
}
|
}
|
||||||
return &Input{
|
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]
|
return i.states[key]
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *Input) Update() {
|
func (i *Input) Update() {
|
||||||
for key := range i.states {
|
for key := range i.states {
|
||||||
if !input.IsKeyPressed(key) {
|
if !ebiten.IsKeyPressed(key) {
|
||||||
i.states[key] = 0
|
i.states[key] = 0
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,7 @@
|
|||||||
package blocks
|
package blocks
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/hajimehoshi/ebiten/graphics"
|
"github.com/hajimehoshi/ebiten"
|
||||||
"github.com/hajimehoshi/ebiten/graphics/matrix"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
@ -123,8 +122,8 @@ const blockHeight = 10
|
|||||||
const fieldBlockNumX = 10
|
const fieldBlockNumX = 10
|
||||||
const fieldBlockNumY = 20
|
const fieldBlockNumY = 20
|
||||||
|
|
||||||
func drawBlocks(context graphics.Context, textures *Textures, blocks [][]BlockType, geo matrix.Geometry) {
|
func drawBlocks(context ebiten.GraphicsContext, textures *Textures, blocks [][]BlockType, geo ebiten.GeometryMatrix) {
|
||||||
parts := []graphics.TexturePart{}
|
parts := []ebiten.TexturePart{}
|
||||||
for i, blockCol := range blocks {
|
for i, blockCol := range blocks {
|
||||||
for j, block := range blockCol {
|
for j, block := range blockCol {
|
||||||
if block == BlockTypeNone {
|
if block == BlockTypeNone {
|
||||||
@ -132,11 +131,11 @@ func drawBlocks(context graphics.Context, textures *Textures, blocks [][]BlockTy
|
|||||||
}
|
}
|
||||||
locationX := i * blockWidth
|
locationX := i * blockWidth
|
||||||
locationY := j * blockHeight
|
locationY := j * blockHeight
|
||||||
source := graphics.Rect{
|
source := ebiten.Rect{
|
||||||
(int(block) - 1) * blockWidth, 0,
|
(int(block) - 1) * blockWidth, 0,
|
||||||
blockWidth, blockHeight}
|
blockWidth, blockHeight}
|
||||||
parts = append(parts,
|
parts = append(parts,
|
||||||
graphics.TexturePart{
|
ebiten.TexturePart{
|
||||||
LocationX: locationX,
|
LocationX: locationX,
|
||||||
LocationY: locationY,
|
LocationY: locationY,
|
||||||
Source: source,
|
Source: source,
|
||||||
@ -144,7 +143,7 @@ func drawBlocks(context graphics.Context, textures *Textures, blocks [][]BlockTy
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
blocksTexture := textures.GetTexture("blocks")
|
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) {
|
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)
|
size := len(p.blocks)
|
||||||
blocks := make([][]BlockType, size)
|
blocks := make([][]BlockType, size)
|
||||||
for i := range p.blocks {
|
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
|
x := fieldX + pieceX*blockWidth
|
||||||
y := fieldY + pieceY*blockHeight
|
y := fieldY + pieceY*blockHeight
|
||||||
geoMat.Translate(float64(x), float64(y))
|
geoMat.Translate(float64(x), float64(y))
|
||||||
|
@ -1,8 +1,7 @@
|
|||||||
package blocks
|
package blocks
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/hajimehoshi/ebiten/graphics"
|
"github.com/hajimehoshi/ebiten"
|
||||||
"github.com/hajimehoshi/ebiten/graphics/matrix"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
@ -14,7 +13,7 @@ func init() {
|
|||||||
|
|
||||||
type Scene interface {
|
type Scene interface {
|
||||||
Update(state *GameState)
|
Update(state *GameState)
|
||||||
Draw(context graphics.Context, textures *Textures)
|
Draw(context ebiten.GraphicsContext, textures *Textures)
|
||||||
}
|
}
|
||||||
|
|
||||||
const transitionMaxCount = 20
|
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 {
|
if s.transitionCount == -1 {
|
||||||
s.current.Draw(context, textures)
|
s.current.Draw(context, textures)
|
||||||
return
|
return
|
||||||
@ -61,21 +60,21 @@ func (s *SceneManager) Draw(context graphics.Context, textures *Textures) {
|
|||||||
s.next.Draw(context, textures)
|
s.next.Draw(context, textures)
|
||||||
|
|
||||||
context.ResetOffscreen()
|
context.ResetOffscreen()
|
||||||
color := matrix.ColorI()
|
color := ebiten.ColorMatrixI()
|
||||||
graphics.DrawWhole(
|
ebiten.DrawWhole(
|
||||||
context.RenderTarget(from),
|
context.RenderTarget(from),
|
||||||
ScreenWidth,
|
ScreenWidth,
|
||||||
ScreenHeight,
|
ScreenHeight,
|
||||||
matrix.GeometryI(),
|
ebiten.GeometryMatrixI(),
|
||||||
color)
|
color)
|
||||||
|
|
||||||
alpha := float64(s.transitionCount) / float64(transitionMaxCount)
|
alpha := float64(s.transitionCount) / float64(transitionMaxCount)
|
||||||
color.Elements[3][3] = alpha
|
color.Elements[3][3] = alpha
|
||||||
graphics.DrawWhole(
|
ebiten.DrawWhole(
|
||||||
context.RenderTarget(to),
|
context.RenderTarget(to),
|
||||||
ScreenWidth,
|
ScreenWidth,
|
||||||
ScreenHeight,
|
ScreenHeight,
|
||||||
matrix.GeometryI(),
|
ebiten.GeometryMatrixI(),
|
||||||
color)
|
color)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
package blocks
|
package blocks
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/hajimehoshi/ebiten/graphics"
|
"github.com/hajimehoshi/ebiten"
|
||||||
"image"
|
"image"
|
||||||
_ "image/png"
|
_ "image/png"
|
||||||
"os"
|
"os"
|
||||||
@ -21,8 +21,8 @@ type nameSize struct {
|
|||||||
type Textures struct {
|
type Textures struct {
|
||||||
texturePaths chan namePath
|
texturePaths chan namePath
|
||||||
renderTargetSizes chan nameSize
|
renderTargetSizes chan nameSize
|
||||||
textures map[string]graphics.TextureID
|
textures map[string]ebiten.TextureID
|
||||||
renderTargets map[string]graphics.RenderTargetID
|
renderTargets map[string]ebiten.RenderTargetID
|
||||||
sync.RWMutex
|
sync.RWMutex
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -30,8 +30,8 @@ func NewTextures() *Textures {
|
|||||||
textures := &Textures{
|
textures := &Textures{
|
||||||
texturePaths: make(chan namePath),
|
texturePaths: make(chan namePath),
|
||||||
renderTargetSizes: make(chan nameSize),
|
renderTargetSizes: make(chan nameSize),
|
||||||
textures: map[string]graphics.TextureID{},
|
textures: map[string]ebiten.TextureID{},
|
||||||
renderTargets: map[string]graphics.RenderTargetID{},
|
renderTargets: map[string]ebiten.RenderTargetID{},
|
||||||
}
|
}
|
||||||
go func() {
|
go func() {
|
||||||
for {
|
for {
|
||||||
@ -65,7 +65,7 @@ func (t *Textures) loopMain() {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
id, err := graphics.NewTextureID(img, graphics.FilterNearest)
|
id, err := ebiten.NewTextureID(img, ebiten.FilterNearest)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
@ -77,7 +77,7 @@ func (t *Textures) loopMain() {
|
|||||||
name := s.name
|
name := s.name
|
||||||
size := s.size
|
size := s.size
|
||||||
go func() {
|
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 {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
@ -107,13 +107,13 @@ func (t *Textures) Has(name string) bool {
|
|||||||
return ok
|
return ok
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *Textures) GetTexture(name string) graphics.TextureID {
|
func (t *Textures) GetTexture(name string) ebiten.TextureID {
|
||||||
t.RLock()
|
t.RLock()
|
||||||
defer t.RUnlock()
|
defer t.RUnlock()
|
||||||
return t.textures[name]
|
return t.textures[name]
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *Textures) GetRenderTarget(name string) graphics.RenderTargetID {
|
func (t *Textures) GetRenderTarget(name string) ebiten.RenderTargetID {
|
||||||
t.RLock()
|
t.RLock()
|
||||||
defer t.RUnlock()
|
defer t.RUnlock()
|
||||||
return t.renderTargets[name]
|
return t.renderTargets[name]
|
||||||
|
@ -1,9 +1,7 @@
|
|||||||
package blocks
|
package blocks
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/hajimehoshi/ebiten/graphics"
|
"github.com/hajimehoshi/ebiten"
|
||||||
"github.com/hajimehoshi/ebiten/graphics/matrix"
|
|
||||||
"github.com/hajimehoshi/ebiten/input"
|
|
||||||
"image/color"
|
"image/color"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -21,12 +19,12 @@ func NewTitleScene() *TitleScene {
|
|||||||
|
|
||||||
func (s *TitleScene) Update(state *GameState) {
|
func (s *TitleScene) Update(state *GameState) {
|
||||||
s.count++
|
s.count++
|
||||||
if state.Input.StateForKey(input.KeySpace) == 1 {
|
if state.Input.StateForKey(ebiten.KeySpace) == 1 {
|
||||||
state.SceneManager.GoTo(NewGameScene())
|
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)
|
drawTitleBackground(context, textures, s.count)
|
||||||
drawLogo(context, textures, "BLOCKS")
|
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})
|
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 textureWidth = 32
|
||||||
const textureHeight = 32
|
const textureHeight = 32
|
||||||
|
|
||||||
backgroundTextureId := textures.GetTexture("background")
|
backgroundTextureId := textures.GetTexture("background")
|
||||||
parts := []graphics.TexturePart{}
|
parts := []ebiten.TexturePart{}
|
||||||
for j := -1; j < ScreenHeight/textureHeight+1; j++ {
|
for j := -1; j < ScreenHeight/textureHeight+1; j++ {
|
||||||
for i := 0; i < ScreenWidth/textureWidth+1; i++ {
|
for i := 0; i < ScreenWidth/textureWidth+1; i++ {
|
||||||
parts = append(parts, graphics.TexturePart{
|
parts = append(parts, ebiten.TexturePart{
|
||||||
LocationX: i * textureWidth,
|
LocationX: i * textureWidth,
|
||||||
LocationY: j * textureHeight,
|
LocationY: j * textureHeight,
|
||||||
Source: graphics.Rect{0, 0, textureWidth, textureHeight},
|
Source: ebiten.Rect{0, 0, textureWidth, textureHeight},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dx := (-c / 4) % textureWidth
|
dx := (-c / 4) % textureWidth
|
||||||
dy := (c / 4) % textureHeight
|
dy := (c / 4) % textureHeight
|
||||||
geo := matrix.GeometryI()
|
geo := ebiten.GeometryMatrixI()
|
||||||
geo.Translate(float64(dx), float64(dy))
|
geo.Translate(float64(dx), float64(dy))
|
||||||
clr := matrix.ColorI()
|
clr := ebiten.ColorMatrixI()
|
||||||
context.Texture(backgroundTextureId).Draw(parts, geo, clr)
|
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
|
scale := 4
|
||||||
textWidth := textWidth(str) * scale
|
textWidth := textWidth(str) * scale
|
||||||
x := (ScreenWidth - textWidth) / 2
|
x := (ScreenWidth - textWidth) / 2
|
||||||
|
67
geometrymatrix.go
Normal file
67
geometrymatrix.go
Normal file
@ -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)
|
||||||
|
}
|
@ -1,4 +1,4 @@
|
|||||||
package matrix_test
|
package ebiten_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
. "."
|
. "."
|
||||||
@ -6,8 +6,8 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func TestGeometryIdentity(t *testing.T) {
|
func TestGeometryIdentity(t *testing.T) {
|
||||||
matrix := GeometryI()
|
ebiten := GeometryMatrixI()
|
||||||
got := matrix.IsIdentity()
|
got := ebiten.IsIdentity()
|
||||||
want := true
|
want := true
|
||||||
if want != got {
|
if want != got {
|
||||||
t.Errorf("matrix.IsIdentity() = %t, want %t", got, want)
|
t.Errorf("matrix.IsIdentity() = %t, want %t", got, want)
|
||||||
@ -15,8 +15,8 @@ func TestGeometryIdentity(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestGeometryConcat(t *testing.T) {
|
func TestGeometryConcat(t *testing.T) {
|
||||||
matrix1 := Geometry{}
|
matrix1 := GeometryMatrix{}
|
||||||
matrix2 := Geometry{}
|
matrix2 := GeometryMatrix{}
|
||||||
matrix1.Elements = [2][3]float64{
|
matrix1.Elements = [2][3]float64{
|
||||||
{2, 0, 0},
|
{2, 0, 0},
|
||||||
{0, 2, 0},
|
{0, 2, 0},
|
@ -2,23 +2,22 @@ package glfw
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
glfw "github.com/go-gl/glfw3"
|
glfw "github.com/go-gl/glfw3"
|
||||||
"github.com/hajimehoshi/ebiten/graphics"
|
"github.com/hajimehoshi/ebiten"
|
||||||
"github.com/hajimehoshi/ebiten/graphics/opengl"
|
"github.com/hajimehoshi/ebiten/opengl"
|
||||||
"github.com/hajimehoshi/ebiten/ui"
|
|
||||||
"image"
|
"image"
|
||||||
"runtime"
|
"runtime"
|
||||||
)
|
)
|
||||||
|
|
||||||
type canvas struct {
|
type canvas struct {
|
||||||
window *glfw.Window
|
window *glfw.Window
|
||||||
context *opengl.Context
|
context *opengl.GraphicsContext
|
||||||
keyboard keyboard
|
keyboard keyboard
|
||||||
mouse mouse
|
mouse mouse
|
||||||
funcs chan func()
|
funcs chan func()
|
||||||
funcsDone chan struct{}
|
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.use(func() {
|
||||||
c.context.PreUpdate()
|
c.context.PreUpdate()
|
||||||
})
|
})
|
||||||
@ -36,8 +35,8 @@ func (c *canvas) IsClosed() bool {
|
|||||||
return c.window.ShouldClose()
|
return c.window.ShouldClose()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *canvas) NewTextureID(img image.Image, filter graphics.Filter) (graphics.TextureID, error) {
|
func (c *canvas) NewTextureID(img image.Image, filter ebiten.Filter) (ebiten.TextureID, error) {
|
||||||
var id graphics.TextureID
|
var id ebiten.TextureID
|
||||||
var err error
|
var err error
|
||||||
c.use(func() {
|
c.use(func() {
|
||||||
id, err = opengl.NewTextureID(img, filter)
|
id, err = opengl.NewTextureID(img, filter)
|
||||||
@ -45,8 +44,8 @@ func (c *canvas) NewTextureID(img image.Image, filter graphics.Filter) (graphics
|
|||||||
return id, err
|
return id, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *canvas) NewRenderTargetID(width, height int, filter graphics.Filter) (graphics.RenderTargetID, error) {
|
func (c *canvas) NewRenderTargetID(width, height int, filter ebiten.Filter) (ebiten.RenderTargetID, error) {
|
||||||
var id graphics.RenderTargetID
|
var id ebiten.RenderTargetID
|
||||||
var err error
|
var err error
|
||||||
c.use(func() {
|
c.use(func() {
|
||||||
id, err = opengl.NewRenderTargetID(width, height, filter)
|
id, err = opengl.NewRenderTargetID(width, height, filter)
|
@ -1,15 +1,14 @@
|
|||||||
package glfw
|
package glfw
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/hajimehoshi/ebiten/graphics"
|
"github.com/hajimehoshi/ebiten"
|
||||||
"github.com/hajimehoshi/ebiten/graphics/matrix"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type context struct {
|
type context struct {
|
||||||
canvas *canvas
|
canvas *canvas
|
||||||
}
|
}
|
||||||
|
|
||||||
var _ graphics.Context = new(context)
|
var _ ebiten.GraphicsContext = new(context)
|
||||||
|
|
||||||
func (c *context) Clear() {
|
func (c *context) Clear() {
|
||||||
c.canvas.use(func() {
|
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() {
|
c.canvas.use(func() {
|
||||||
d = &drawer{
|
d = &drawer{
|
||||||
canvas: c.canvas,
|
canvas: c.canvas,
|
||||||
@ -33,7 +32,7 @@ func (c *context) Texture(id graphics.TextureID) (d graphics.Drawer) {
|
|||||||
return
|
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() {
|
c.canvas.use(func() {
|
||||||
d = &drawer{
|
d = &drawer{
|
||||||
canvas: c.canvas,
|
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.use(func() {
|
||||||
c.canvas.context.SetOffscreen(id)
|
c.canvas.context.SetOffscreen(id)
|
||||||
})
|
})
|
||||||
@ -57,12 +56,12 @@ func (c *context) SetOffscreen(id graphics.RenderTargetID) {
|
|||||||
|
|
||||||
type drawer struct {
|
type drawer struct {
|
||||||
canvas *canvas
|
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.canvas.use(func() {
|
||||||
d.innerDrawer.Draw(parts, geo, color)
|
d.innerDrawer.Draw(parts, geo, color)
|
||||||
})
|
})
|
28
glfw/keyboard.go
Normal file
28
glfw/keyboard.go
Normal file
@ -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
|
||||||
|
}
|
||||||
|
}
|
@ -2,21 +2,21 @@ package glfw
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
glfw "github.com/go-gl/glfw3"
|
glfw "github.com/go-gl/glfw3"
|
||||||
"github.com/hajimehoshi/ebiten/input"
|
"github.com/hajimehoshi/ebiten"
|
||||||
"math"
|
"math"
|
||||||
)
|
)
|
||||||
|
|
||||||
type mouse struct {
|
type mouse struct {
|
||||||
buttonPressed [input.MouseButtonMax]bool
|
buttonPressed [ebiten.MouseButtonMax]bool
|
||||||
x int
|
x int
|
||||||
y int
|
y int
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *mouse) CurrentPosition() (x, y int) {
|
func (m *mouse) CursorPosition() (x, y int) {
|
||||||
return m.x, m.y
|
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]
|
return m.buttonPressed[button]
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -24,7 +24,7 @@ func (m *mouse) update(window *glfw.Window) {
|
|||||||
x, y := window.GetCursorPosition()
|
x, y := window.GetCursorPosition()
|
||||||
m.x = int(math.Floor(x))
|
m.x = int(math.Floor(x))
|
||||||
m.y = int(math.Floor(y))
|
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
|
m.buttonPressed[i] = window.GetMouseButton(glfw.MouseButton(i)) == glfw.Press
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -4,10 +4,8 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
glfw "github.com/go-gl/glfw3"
|
glfw "github.com/go-gl/glfw3"
|
||||||
"github.com/hajimehoshi/ebiten/graphics"
|
"github.com/hajimehoshi/ebiten"
|
||||||
"github.com/hajimehoshi/ebiten/graphics/opengl"
|
"github.com/hajimehoshi/ebiten/opengl"
|
||||||
"github.com/hajimehoshi/ebiten/input"
|
|
||||||
"github.com/hajimehoshi/ebiten/ui"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
@ -20,7 +18,7 @@ type UI struct {
|
|||||||
canvas *canvas
|
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() {
|
if !glfw.Init() {
|
||||||
return nil, errors.New("glfw.Init() fails")
|
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()),
|
funcs: make(chan func()),
|
||||||
funcsDone: make(chan struct{}),
|
funcsDone: make(chan struct{}),
|
||||||
}
|
}
|
||||||
input.SetKeyboard(&c.keyboard)
|
ebiten.SetKeyboard(&c.keyboard)
|
||||||
input.SetMouse(&c.mouse)
|
ebiten.SetMouse(&c.mouse)
|
||||||
graphics.SetTextureFactory(c)
|
ebiten.SetTextureFactory(c)
|
||||||
|
|
||||||
c.run(width, height, scale)
|
c.run(width, height, scale)
|
||||||
|
|
@ -1 +0,0 @@
|
|||||||
package matrix_test
|
|
@ -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
|
|
||||||
}
|
|
@ -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)
|
|
||||||
}
|
|
@ -1,8 +1,4 @@
|
|||||||
package graphics
|
package ebiten
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/hajimehoshi/ebiten/graphics/matrix"
|
|
||||||
)
|
|
||||||
|
|
||||||
// A Rect represents a rectangle.
|
// A Rect represents a rectangle.
|
||||||
type Rect struct {
|
type Rect struct {
|
||||||
@ -21,11 +17,11 @@ type TexturePart struct {
|
|||||||
|
|
||||||
// A Drawer is the interface that draws itself.
|
// A Drawer is the interface that draws itself.
|
||||||
type Drawer interface {
|
type Drawer interface {
|
||||||
Draw(parts []TexturePart, geo matrix.Geometry, color matrix.Color)
|
Draw(parts []TexturePart, geo GeometryMatrix, color ColorMatrix)
|
||||||
}
|
}
|
||||||
|
|
||||||
// DrawWhole draws the whole texture.
|
// 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{
|
parts := []TexturePart{
|
||||||
{0, 0, Rect{0, 0, width, height}},
|
{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.
|
// A Context is the interface that means a context of rendering.
|
||||||
type Context interface {
|
type GraphicsContext interface {
|
||||||
Clear()
|
Clear()
|
||||||
Fill(r, g, b uint8)
|
Fill(r, g, b uint8)
|
||||||
Texture(id TextureID) Drawer
|
Texture(id TextureID) Drawer
|
@ -1,4 +1,4 @@
|
|||||||
package input
|
package ebiten
|
||||||
|
|
||||||
type Key int
|
type Key int
|
||||||
|
|
@ -1,4 +1,4 @@
|
|||||||
package input
|
package ebiten
|
||||||
|
|
||||||
type MouseButton int
|
type MouseButton int
|
||||||
|
|
||||||
@ -12,7 +12,7 @@ const (
|
|||||||
var currentMouse Mouse
|
var currentMouse Mouse
|
||||||
|
|
||||||
type Mouse interface {
|
type Mouse interface {
|
||||||
CurrentPosition() (x, y int)
|
CursorPosition() (x, y int)
|
||||||
IsMouseButtonPressed(mouseButton MouseButton) bool
|
IsMouseButtonPressed(mouseButton MouseButton) bool
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -20,11 +20,11 @@ func SetMouse(mouse Mouse) {
|
|||||||
currentMouse = mouse
|
currentMouse = mouse
|
||||||
}
|
}
|
||||||
|
|
||||||
func CurrentPosition() (x, y int) {
|
func CursorPosition() (x, y int) {
|
||||||
if currentMouse == nil {
|
if currentMouse == nil {
|
||||||
panic("input.CurrentPosition: currentMouse is not set")
|
panic("input.CurrentPosition: currentMouse is not set")
|
||||||
}
|
}
|
||||||
return currentMouse.CurrentPosition()
|
return currentMouse.CursorPosition()
|
||||||
}
|
}
|
||||||
|
|
||||||
func IsMouseButtonPressed(button MouseButton) bool {
|
func IsMouseButtonPressed(button MouseButton) bool {
|
@ -2,16 +2,15 @@ package opengl
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/go-gl/gl"
|
"github.com/go-gl/gl"
|
||||||
"github.com/hajimehoshi/ebiten/graphics"
|
"github.com/hajimehoshi/ebiten"
|
||||||
"github.com/hajimehoshi/ebiten/graphics/matrix"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func Initialize(screenWidth, screenHeight, screenScale int) (*Context, error) {
|
func Initialize(screenWidth, screenHeight, screenScale int) (*GraphicsContext, error) {
|
||||||
gl.Init()
|
gl.Init()
|
||||||
gl.Enable(gl.TEXTURE_2D)
|
gl.Enable(gl.TEXTURE_2D)
|
||||||
gl.Enable(gl.BLEND)
|
gl.Enable(gl.BLEND)
|
||||||
|
|
||||||
c := &Context{
|
c := &GraphicsContext{
|
||||||
screenWidth: screenWidth,
|
screenWidth: screenWidth,
|
||||||
screenHeight: screenHeight,
|
screenHeight: screenHeight,
|
||||||
screenScale: screenScale,
|
screenScale: screenScale,
|
||||||
@ -25,7 +24,7 @@ func Initialize(screenWidth, screenHeight, screenScale int) (*Context, error) {
|
|||||||
})
|
})
|
||||||
|
|
||||||
var err 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 {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -35,66 +34,68 @@ func Initialize(screenWidth, screenHeight, screenScale int) (*Context, error) {
|
|||||||
return c, nil
|
return c, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type Context struct {
|
type GraphicsContext struct {
|
||||||
screenId graphics.RenderTargetID
|
screenId ebiten.RenderTargetID
|
||||||
defaultId graphics.RenderTargetID
|
defaultId ebiten.RenderTargetID
|
||||||
currentId graphics.RenderTargetID
|
currentId ebiten.RenderTargetID
|
||||||
screenWidth int
|
screenWidth int
|
||||||
screenHeight int
|
screenHeight int
|
||||||
screenScale int
|
screenScale int
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Context) dispose() {
|
var _ ebiten.GraphicsContext = new(GraphicsContext)
|
||||||
|
|
||||||
|
func (c *GraphicsContext) dispose() {
|
||||||
// NOTE: Now this method is not used anywhere.
|
// NOTE: Now this method is not used anywhere.
|
||||||
idsInstance.deleteRenderTarget(c.screenId)
|
idsInstance.deleteRenderTarget(c.screenId)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Context) Clear() {
|
func (c *GraphicsContext) Clear() {
|
||||||
c.Fill(0, 0, 0)
|
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)
|
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}
|
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}
|
return &textureWithContext{idsInstance.toTexture(id), c}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Context) ResetOffscreen() {
|
func (c *GraphicsContext) ResetOffscreen() {
|
||||||
c.currentId = c.screenId
|
c.currentId = c.screenId
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Context) SetOffscreen(renderTargetId graphics.RenderTargetID) {
|
func (c *GraphicsContext) SetOffscreen(renderTargetId ebiten.RenderTargetID) {
|
||||||
c.currentId = renderTargetId
|
c.currentId = renderTargetId
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Context) PreUpdate() {
|
func (c *GraphicsContext) PreUpdate() {
|
||||||
c.ResetOffscreen()
|
c.ResetOffscreen()
|
||||||
c.Clear()
|
c.Clear()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Context) PostUpdate() {
|
func (c *GraphicsContext) PostUpdate() {
|
||||||
c.SetOffscreen(c.defaultId)
|
c.SetOffscreen(c.defaultId)
|
||||||
c.Clear()
|
c.Clear()
|
||||||
|
|
||||||
scale := float64(c.screenScale)
|
scale := float64(c.screenScale)
|
||||||
geo := matrix.GeometryI()
|
geo := ebiten.GeometryMatrixI()
|
||||||
geo.Scale(scale, scale)
|
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()
|
gl.Flush()
|
||||||
}
|
}
|
||||||
|
|
||||||
type textureWithContext struct {
|
type textureWithContext struct {
|
||||||
id graphics.TextureID
|
id ebiten.TextureID
|
||||||
context *Context
|
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)
|
idsInstance.drawTexture(t.context.currentId, t.id, parts, geo, color)
|
||||||
}
|
}
|
@ -2,57 +2,56 @@ package opengl
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/go-gl/gl"
|
"github.com/go-gl/gl"
|
||||||
"github.com/hajimehoshi/ebiten/graphics"
|
"github.com/hajimehoshi/ebiten"
|
||||||
"github.com/hajimehoshi/ebiten/graphics/matrix"
|
"github.com/hajimehoshi/ebiten/opengl/internal/shader"
|
||||||
"github.com/hajimehoshi/ebiten/graphics/opengl/internal/shader"
|
|
||||||
"image"
|
"image"
|
||||||
"math"
|
"math"
|
||||||
"sync"
|
"sync"
|
||||||
)
|
)
|
||||||
|
|
||||||
type ids struct {
|
type ids struct {
|
||||||
textures map[graphics.TextureID]*texture
|
textures map[ebiten.TextureID]*texture
|
||||||
renderTargets map[graphics.RenderTargetID]*renderTarget
|
renderTargets map[ebiten.RenderTargetID]*renderTarget
|
||||||
renderTargetToTexture map[graphics.RenderTargetID]graphics.TextureID
|
renderTargetToTexture map[ebiten.RenderTargetID]ebiten.TextureID
|
||||||
lastId int
|
lastId int
|
||||||
currentRenderTargetId graphics.RenderTargetID
|
currentRenderTargetId ebiten.RenderTargetID
|
||||||
sync.RWMutex
|
sync.RWMutex
|
||||||
}
|
}
|
||||||
|
|
||||||
var idsInstance = &ids{
|
var idsInstance = &ids{
|
||||||
textures: map[graphics.TextureID]*texture{},
|
textures: map[ebiten.TextureID]*texture{},
|
||||||
renderTargets: map[graphics.RenderTargetID]*renderTarget{},
|
renderTargets: map[ebiten.RenderTargetID]*renderTarget{},
|
||||||
renderTargetToTexture: map[graphics.RenderTargetID]graphics.TextureID{},
|
renderTargetToTexture: map[ebiten.RenderTargetID]ebiten.TextureID{},
|
||||||
currentRenderTargetId: -1,
|
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)
|
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)
|
return idsInstance.createTexture(img, filter)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *ids) textureAt(id graphics.TextureID) *texture {
|
func (i *ids) textureAt(id ebiten.TextureID) *texture {
|
||||||
i.RLock()
|
i.RLock()
|
||||||
defer i.RUnlock()
|
defer i.RUnlock()
|
||||||
return i.textures[id]
|
return i.textures[id]
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *ids) renderTargetAt(id graphics.RenderTargetID) *renderTarget {
|
func (i *ids) renderTargetAt(id ebiten.RenderTargetID) *renderTarget {
|
||||||
i.RLock()
|
i.RLock()
|
||||||
defer i.RUnlock()
|
defer i.RUnlock()
|
||||||
return i.renderTargets[id]
|
return i.renderTargets[id]
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *ids) toTexture(id graphics.RenderTargetID) graphics.TextureID {
|
func (i *ids) toTexture(id ebiten.RenderTargetID) ebiten.TextureID {
|
||||||
i.RLock()
|
i.RLock()
|
||||||
defer i.RUnlock()
|
defer i.RUnlock()
|
||||||
return i.renderTargetToTexture[id]
|
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)
|
texture, err := createTextureFromImage(img, filter)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
@ -61,12 +60,12 @@ func (i *ids) createTexture(img image.Image, filter graphics.Filter) (graphics.T
|
|||||||
i.Lock()
|
i.Lock()
|
||||||
defer i.Unlock()
|
defer i.Unlock()
|
||||||
i.lastId++
|
i.lastId++
|
||||||
textureId := graphics.TextureID(i.lastId)
|
textureId := ebiten.TextureID(i.lastId)
|
||||||
i.textures[textureId] = texture
|
i.textures[textureId] = texture
|
||||||
return textureId, nil
|
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)
|
texture, err := createTexture(width, height, filter)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
@ -83,9 +82,9 @@ func (i *ids) createRenderTarget(width, height int, filter graphics.Filter) (gra
|
|||||||
i.Lock()
|
i.Lock()
|
||||||
defer i.Unlock()
|
defer i.Unlock()
|
||||||
i.lastId++
|
i.lastId++
|
||||||
textureId := graphics.TextureID(i.lastId)
|
textureId := ebiten.TextureID(i.lastId)
|
||||||
i.lastId++
|
i.lastId++
|
||||||
renderTargetId := graphics.RenderTargetID(i.lastId)
|
renderTargetId := ebiten.RenderTargetID(i.lastId)
|
||||||
|
|
||||||
i.textures[textureId] = texture
|
i.textures[textureId] = texture
|
||||||
i.renderTargets[renderTargetId] = r
|
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.
|
// 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()
|
i.Lock()
|
||||||
defer i.Unlock()
|
defer i.Unlock()
|
||||||
i.lastId++
|
i.lastId++
|
||||||
id := graphics.RenderTargetID(i.lastId)
|
id := ebiten.RenderTargetID(i.lastId)
|
||||||
i.renderTargets[id] = renderTarget
|
i.renderTargets[id] = renderTarget
|
||||||
|
|
||||||
return id
|
return id
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *ids) deleteRenderTarget(id graphics.RenderTargetID) {
|
func (i *ids) deleteRenderTarget(id ebiten.RenderTargetID) {
|
||||||
i.Lock()
|
i.Lock()
|
||||||
defer i.Unlock()
|
defer i.Unlock()
|
||||||
|
|
||||||
@ -121,14 +120,14 @@ func (i *ids) deleteRenderTarget(id graphics.RenderTargetID) {
|
|||||||
delete(i.textures, textureId)
|
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)
|
i.setViewportIfNeeded(id)
|
||||||
const max = float64(math.MaxUint8)
|
const max = float64(math.MaxUint8)
|
||||||
gl.ClearColor(gl.GLclampf(float64(r)/max), gl.GLclampf(float64(g)/max), gl.GLclampf(float64(b)/max), 1)
|
gl.ClearColor(gl.GLclampf(float64(r)/max), gl.GLclampf(float64(g)/max), gl.GLclampf(float64(b)/max), 1)
|
||||||
gl.Clear(gl.COLOR_BUFFER_BIT)
|
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)
|
texture := i.textureAt(id)
|
||||||
i.setViewportIfNeeded(target)
|
i.setViewportIfNeeded(target)
|
||||||
r := i.renderTargetAt(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)
|
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)
|
r := i.renderTargetAt(id)
|
||||||
if i.currentRenderTargetId != id {
|
if i.currentRenderTargetId != id {
|
||||||
r.setAsViewport()
|
r.setAsViewport()
|
@ -2,16 +2,15 @@ package shader
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/go-gl/gl"
|
"github.com/go-gl/gl"
|
||||||
"github.com/hajimehoshi/ebiten/graphics"
|
"github.com/hajimehoshi/ebiten"
|
||||||
"github.com/hajimehoshi/ebiten/graphics/matrix"
|
|
||||||
"sync"
|
"sync"
|
||||||
)
|
)
|
||||||
|
|
||||||
func glMatrix(matrix [4][4]float64) [16]float32 {
|
func glMatrix(ebiten [4][4]float64) [16]float32 {
|
||||||
result := [16]float32{}
|
result := [16]float32{}
|
||||||
for j := 0; j < 4; j++ {
|
for j := 0; j < 4; j++ {
|
||||||
for i := 0; i < 4; i++ {
|
for i := 0; i < 4; i++ {
|
||||||
result[i+j*4] = float32(matrix[i][j])
|
result[i+j*4] = float32(ebiten[i][j])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result
|
return result
|
||||||
@ -19,7 +18,8 @@ func glMatrix(matrix [4][4]float64) [16]float32 {
|
|||||||
|
|
||||||
var once sync.Once
|
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() {
|
once.Do(func() {
|
||||||
initialize()
|
initialize()
|
||||||
})
|
})
|
||||||
@ -51,7 +51,7 @@ func DrawTexture(native gl.Texture, width, height int, projectionMatrix [4][4]fl
|
|||||||
vertices := []float32{}
|
vertices := []float32{}
|
||||||
texCoords := []float32{}
|
texCoords := []float32{}
|
||||||
indicies := []uint32{}
|
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 {
|
for i, quad := range quads {
|
||||||
x1 := quad.VertexX1
|
x1 := quad.VertexX1
|
||||||
x2 := quad.VertexX2
|
x2 := quad.VertexX2
|
@ -2,7 +2,7 @@ package shader
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/go-gl/gl"
|
"github.com/go-gl/gl"
|
||||||
"github.com/hajimehoshi/ebiten/graphics/matrix"
|
"github.com/hajimehoshi/ebiten"
|
||||||
)
|
)
|
||||||
|
|
||||||
type program struct {
|
type program struct {
|
||||||
@ -65,7 +65,7 @@ func getUniformLocation(program gl.Program, name string) gl.UniformLocation {
|
|||||||
return location
|
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.
|
// TODO: Check the performance.
|
||||||
program := programColorMatrix
|
program := programColorMatrix
|
||||||
|
|
@ -1,7 +1,7 @@
|
|||||||
package shader
|
package shader
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/hajimehoshi/ebiten/graphics"
|
"github.com/hajimehoshi/ebiten"
|
||||||
)
|
)
|
||||||
|
|
||||||
type textureQuad struct {
|
type textureQuad struct {
|
||||||
@ -38,7 +38,7 @@ func v(y int, height int) float32 {
|
|||||||
return float32(y) / float32(AdjustSizeForTexture(height))
|
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{}
|
quads := []textureQuad{}
|
||||||
for _, part := range parts {
|
for _, part := range parts {
|
||||||
x1 := float32(part.LocationX)
|
x1 := float32(part.LocationX)
|
@ -3,7 +3,7 @@ package opengl
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/go-gl/gl"
|
"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 {
|
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 {
|
func (r *renderTarget) projectionMatrix() [4][4]float64 {
|
||||||
width := shader.AdjustSizeForTexture(r.width)
|
width := shader.AdjustSizeForTexture(r.width)
|
||||||
height := shader.AdjustSizeForTexture(r.height)
|
height := shader.AdjustSizeForTexture(r.height)
|
||||||
matrix := orthoProjectionMatrix(0, width, 0, height)
|
ebiten := orthoProjectionMatrix(0, width, 0, height)
|
||||||
if r.flipY {
|
if r.flipY {
|
||||||
matrix[1][1] *= -1
|
ebiten[1][1] *= -1
|
||||||
matrix[1][3] += float64(r.height) / float64(shader.AdjustSizeForTexture(r.height)) * 2
|
ebiten[1][3] += float64(r.height) / float64(shader.AdjustSizeForTexture(r.height)) * 2
|
||||||
}
|
}
|
||||||
return matrix
|
return ebiten
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *renderTarget) dispose() {
|
func (r *renderTarget) dispose() {
|
@ -2,8 +2,8 @@ package opengl
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/go-gl/gl"
|
"github.com/go-gl/gl"
|
||||||
"github.com/hajimehoshi/ebiten/graphics"
|
"github.com/hajimehoshi/ebiten"
|
||||||
"github.com/hajimehoshi/ebiten/graphics/opengl/internal/shader"
|
"github.com/hajimehoshi/ebiten/opengl/internal/shader"
|
||||||
"image"
|
"image"
|
||||||
"image/draw"
|
"image/draw"
|
||||||
)
|
)
|
||||||
@ -36,7 +36,7 @@ type texture struct {
|
|||||||
height int
|
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()
|
nativeTexture := gl.GenTexture()
|
||||||
if nativeTexture < 0 {
|
if nativeTexture < 0 {
|
||||||
panic("glGenTexture failed")
|
panic("glGenTexture failed")
|
||||||
@ -47,9 +47,9 @@ func createNativeTexture(textureWidth, textureHeight int, pixels []uint8, filter
|
|||||||
|
|
||||||
glFilter := 0
|
glFilter := 0
|
||||||
switch filter {
|
switch filter {
|
||||||
case graphics.FilterLinear:
|
case ebiten.FilterLinear:
|
||||||
glFilter = gl.LINEAR
|
glFilter = gl.LINEAR
|
||||||
case graphics.FilterNearest:
|
case ebiten.FilterNearest:
|
||||||
glFilter = gl.NEAREST
|
glFilter = gl.NEAREST
|
||||||
default:
|
default:
|
||||||
panic("not reached")
|
panic("not reached")
|
||||||
@ -62,14 +62,14 @@ func createNativeTexture(textureWidth, textureHeight int, pixels []uint8, filter
|
|||||||
return nativeTexture
|
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)
|
w := shader.AdjustSizeForTexture(width)
|
||||||
h := shader.AdjustSizeForTexture(height)
|
h := shader.AdjustSizeForTexture(height)
|
||||||
native := createNativeTexture(w, h, nil, filter)
|
native := createNativeTexture(w, h, nil, filter)
|
||||||
return &texture{native, width, height}, nil
|
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)
|
adjustedImage := adjustImageForTexture(img)
|
||||||
size := adjustedImage.Bounds().Size()
|
size := adjustedImage.Bounds().Size()
|
||||||
native := createNativeTexture(size.X, size.Y, adjustedImage.Pix, filter)
|
native := createNativeTexture(size.X, size.Y, adjustedImage.Pix, filter)
|
@ -1,7 +1,6 @@
|
|||||||
package ui
|
package ebiten
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/hajimehoshi/ebiten/graphics"
|
|
||||||
"os"
|
"os"
|
||||||
"os/signal"
|
"os/signal"
|
||||||
"syscall"
|
"syscall"
|
||||||
@ -10,7 +9,7 @@ import (
|
|||||||
|
|
||||||
type Game interface {
|
type Game interface {
|
||||||
Update() error
|
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 {
|
func Run(u UI, game Game, width, height, scale int, title string, fps int) error {
|
@ -1,4 +1,4 @@
|
|||||||
package graphics
|
package ebiten
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"image"
|
"image"
|
@ -1,8 +1,4 @@
|
|||||||
package ui
|
package ebiten
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/hajimehoshi/ebiten/graphics"
|
|
||||||
)
|
|
||||||
|
|
||||||
type UI interface {
|
type UI interface {
|
||||||
Start(widht, height, scale int, title string) (Canvas, error)
|
Start(widht, height, scale int, title string) (Canvas, error)
|
||||||
@ -10,11 +6,12 @@ type UI interface {
|
|||||||
Terminate()
|
Terminate()
|
||||||
}
|
}
|
||||||
|
|
||||||
type Drawer interface {
|
// FIXME: rename this
|
||||||
Draw(c graphics.Context) error
|
type Drawer2 interface {
|
||||||
|
Draw(c GraphicsContext) error
|
||||||
}
|
}
|
||||||
|
|
||||||
type Canvas interface {
|
type Canvas interface {
|
||||||
Draw(drawer Drawer) error
|
Draw(drawer Drawer2) error
|
||||||
IsClosed() bool
|
IsClosed() bool
|
||||||
}
|
}
|
@ -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
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user