From c35d0f85eca265e43c56ca6513cb7a2da3c7611c Mon Sep 17 00:00:00 2001 From: Hajime Hoshi Date: Wed, 18 Dec 2013 18:05:28 +0900 Subject: [PATCH] Title for blocks --- .gitignore | 2 + example/blocks/game.go | 158 +++++++++++++++ example/blocks/scene_manager.go | 43 ++++ example/blocks/title_scene.go | 81 ++++++++ example/game.go | 183 ------------------ example/images/blocks/background.png | Bin 0 -> 138 bytes example/images/blocks/blocks.png | Bin 0 -> 165 bytes example/images/blocks/ebiten.png | Bin 0 -> 2149 bytes example/images/blocks/font.png | Bin 0 -> 1261 bytes example/main.go | 54 ++---- graphics/graphics.go | 15 +- graphics/opengl/context.go | 8 +- graphics/opengl/device.go | 7 +- graphics/opengl/ids.go | 6 +- graphics/opengl/offscreen/offscreen.go | 4 - graphics/opengl/rendertarget/render_target.go | 3 +- graphics/opengl/texture/texture.go | 33 +--- graphics/texture/texture.go | 2 +- graphics/texture_factory.go | 2 +- ui/cocoa/ui.go | 8 +- ui/cocoa/window.go | 14 +- ui/ui.go | 3 +- 22 files changed, 338 insertions(+), 288 deletions(-) create mode 100644 example/blocks/game.go create mode 100644 example/blocks/scene_manager.go create mode 100644 example/blocks/title_scene.go delete mode 100644 example/game.go create mode 100644 example/images/blocks/background.png create mode 100644 example/images/blocks/blocks.png create mode 100644 example/images/blocks/ebiten.png create mode 100644 example/images/blocks/font.png diff --git a/.gitignore b/.gitignore index b25c15b81..915b33024 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,3 @@ +.DS_Store *~ + diff --git a/example/blocks/game.go b/example/blocks/game.go new file mode 100644 index 000000000..ff9fbe86e --- /dev/null +++ b/example/blocks/game.go @@ -0,0 +1,158 @@ +package blocks + +import ( + "fmt" + "github.com/hajimehoshi/go-ebiten/graphics" + "github.com/hajimehoshi/go-ebiten/ui" + "image" + _ "image/png" + "os" +) + +type Size struct { + Width int + Height int +} + +var texturePaths = map[string]string{ + "background": "images/blocks/background.png", + "font": "images/blocks/font.png", +} + +var renderTargetSizes = map[string]Size{ + "whole": Size{256, 254}, +} + +const ScreenWidth = 256 +const ScreenHeight = 240 + +var drawInfo = struct { + textures map[string]graphics.TextureId + renderTargets map[string]graphics.RenderTargetId +}{ + textures: map[string]graphics.TextureId{}, + renderTargets: map[string]graphics.RenderTargetId{}, +} + +type Game struct { + sceneManager *SceneManager +} + +func loadImage(path string) (image.Image, error) { + file, err := os.Open(path) + if err != nil { + return nil, err + } + defer file.Close() + + img, _, err := image.Decode(file) + if err != nil { + return nil, err + } + return img, nil +} + +func (game *Game) startLoadingTextures(textureFactory graphics.TextureFactory) { + for tag, path := range texturePaths { + tag := tag + path := path + go func() { + img, err := loadImage(path) + if err != nil { + panic(err) + } + textureFactory.CreateTexture(tag, img, graphics.FilterNearest) + }() + } + + for tag, size := range renderTargetSizes { + tag := tag + size := size + go func() { + textureFactory.CreateRenderTarget(tag, size.Width, size.Height) + }() + } +} + +func NewGame(textureFactory graphics.TextureFactory) *Game { + game := &Game{ + sceneManager: NewSceneManager(NewTitleScene()), + } + game.startLoadingTextures(textureFactory) + return game +} + +func (game *Game) HandleEvent(e interface{}) { + switch e := e.(type) { + case graphics.TextureCreatedEvent: + if e.Error != nil { + panic(e.Error) + } + drawInfo.textures[e.Tag.(string)] = e.Id + case graphics.RenderTargetCreatedEvent: + if e.Error != nil { + panic(e.Error) + } + drawInfo.renderTargets[e.Tag.(string)] = e.Id + case ui.KeyStateUpdatedEvent: + fmt.Printf("%v\n", e.Keys) + case ui.MouseStateUpdatedEvent: + } +} + +func (game *Game) isInitialized() bool { + if len(drawInfo.textures) < len(texturePaths) { + return false + } + if len(drawInfo.renderTargets) < len(renderTargetSizes) { + return false + } + return true +} + +func (game *Game) Update() { + if !game.isInitialized() { + return + } + game.sceneManager.Update() +} + +func (game *Game) Draw(context graphics.Context) { + if !game.isInitialized() { + return + } + game.sceneManager.Draw(context) +} + +/*func (game *Game) drawText(g graphics.Context, text string, x, y int, clr color.Color) { + const letterWidth = 6 + const letterHeight = 16 + + parts := []graphics.TexturePart{} + textX := 0 + textY := 0 + for _, c := range text { + if c == '\n' { + textX = 0 + textY += letterHeight + continue + } + code := int(c) + x := (code % 32) * letterWidth + y := (code / 32) * letterHeight + source := graphics.Rect{x, y, letterWidth, letterHeight} + parts = append(parts, graphics.TexturePart{ + LocationX: textX, + LocationY: textY, + Source: source, + }) + textX += letterWidth + } + + geometryMatrix := matrix.IdentityGeometry() + geometryMatrix.Translate(float64(x), float64(y)) + colorMatrix := matrix.IdentityColor() + colorMatrix.Scale(clr) + g.DrawTextureParts(drawInfo.textures["text"], parts, + geometryMatrix, colorMatrix) +}*/ diff --git a/example/blocks/scene_manager.go b/example/blocks/scene_manager.go new file mode 100644 index 000000000..d2f574f7d --- /dev/null +++ b/example/blocks/scene_manager.go @@ -0,0 +1,43 @@ +package blocks + +import ( + "github.com/hajimehoshi/go-ebiten/graphics" +) + +type GameState struct { + SceneManager *SceneManager +} + +type Scene interface { + Update(state GameState) + Draw(context graphics.Context) +} + +type SceneManager struct { + current Scene + next Scene +} + +func NewSceneManager(initScene Scene) *SceneManager { + return &SceneManager{ + current: initScene, + } +} + +func (s *SceneManager) Update() { + if s.next != nil { + s.current = s.next + s.next = nil + } + s.current.Update(GameState{ + SceneManager: s, + }) +} + +func (s *SceneManager) Draw(context graphics.Context) { + s.current.Draw(context) +} + +func (s *SceneManager) GoTo(scene Scene) { + s.next = scene +} diff --git a/example/blocks/title_scene.go b/example/blocks/title_scene.go new file mode 100644 index 000000000..8a6428cef --- /dev/null +++ b/example/blocks/title_scene.go @@ -0,0 +1,81 @@ +package blocks + +import ( + "github.com/hajimehoshi/go-ebiten/graphics" + "github.com/hajimehoshi/go-ebiten/graphics/matrix" + "image/color" +) + +type TitleScene struct { + count int +} + +func NewTitleScene() *TitleScene { + return &TitleScene{} +} + +func (s *TitleScene) Update(state GameState) { + s.count++ +} + +func (s *TitleScene) Draw(context graphics.Context) { + drawTitleBackground(context, s.count) + drawLogo(context, "BLOCKS") +} + +func drawTitleBackground(context graphics.Context, c int) { + const textureWidth = 32 + const textureHeight = 32 + + backgroundTextureId := drawInfo.textures["background"] + parts := []graphics.TexturePart{} + for j := -1; j < ScreenHeight/textureHeight+1; j++ { + for i := 0; i < ScreenWidth/textureWidth+1; i++ { + parts = append(parts, graphics.TexturePart{ + LocationX: i*textureWidth, + LocationY: j*textureHeight, + Source: graphics.Rect{0, 0, textureWidth, textureHeight}, + }) + } + } + + dx := -c % textureWidth / 2 + dy := c % textureHeight / 2 + geo := matrix.IdentityGeometry() + geo.Translate(float64(dx), float64(dy)) + context.DrawTextureParts(backgroundTextureId, parts, geo, matrix.IdentityColor()) +} + +func drawLogo(context graphics.Context, str string) { + const charWidth = 8 + const charHeight = 8 + + fontTextureId := drawInfo.textures["font"] + parts := []graphics.TexturePart{} + + locationX := 0 + locationY := 0 + for _, c := range str { + if c == '\n' { + locationX = 0 + locationY += charHeight + continue + } + code := int(c) + x := (code % 16) * charWidth + y := ((code - 32) / 16) * charHeight + parts = append(parts, graphics.TexturePart{ + LocationX: locationX, + LocationY: locationY, + Source: graphics.Rect{x, y, charWidth, charHeight}, + }) + locationX += charWidth + } + + geo := matrix.IdentityGeometry() + geo.Scale(4, 4) + clr := matrix.IdentityColor() + + clr.Scale(color.RGBA{0x00, 0x00, 0x60, 0xff}) + context.DrawTextureParts(fontTextureId, parts, geo, clr) +} diff --git a/example/game.go b/example/game.go deleted file mode 100644 index 88ca1f109..000000000 --- a/example/game.go +++ /dev/null @@ -1,183 +0,0 @@ -package main - -import ( - "fmt" - "github.com/hajimehoshi/go-ebiten/graphics" - "github.com/hajimehoshi/go-ebiten/graphics/matrix" - "github.com/hajimehoshi/go-ebiten/ui" - "image/color" - "math" -) - -var TexturePaths = map[string]string{ - "ebiten": "images/ebiten.png", - "text": "images/text.png", -} - -type Size struct { - Width int - Height int -} - -var RenderTargetSizes = map[string]Size{ - "whole": Size{256, 254}, -} - -type drawInfo struct { - textures map[string]graphics.TextureId - renderTargets map[string]graphics.RenderTargetId - inputStr string - textureX int - textureY int - textureAngle float64 - textureGeo matrix.Geometry -} - -type Game struct { - mouseX int - mouseY int - mousePrevX int - mousePrevY int - counter int - drawInfo -} - -func NewGame() *Game { - return &Game{ - mouseX: -1, - mouseY: -1, - mousePrevX: -1, - mousePrevY: -1, - counter: 0, - drawInfo: drawInfo{ - textures: map[string]graphics.TextureId{}, - renderTargets: map[string]graphics.RenderTargetId{}, - textureX: 0, - textureY: 0, - textureAngle: 0, - textureGeo: matrix.IdentityGeometry(), - }, - } -} - -func (game *Game) HandleEvent(e interface{}) { - switch e := e.(type) { - case graphics.TextureCreatedEvent: - if e.Error != nil { - panic(e.Error) - } - game.textures[e.Tag.(string)] = e.Id - case graphics.RenderTargetCreatedEvent: - if e.Error != nil { - panic(e.Error) - } - game.renderTargets[e.Tag.(string)] = e.Id - case ui.KeyStateUpdatedEvent: - fmt.Printf("%v\n", e.Keys) - case ui.MouseStateUpdatedEvent: - game.mouseX, game.mouseY = e.X, e.Y - } -} - -func (game *Game) isInitialized() bool { - if len(game.drawInfo.textures) < len(TexturePaths) { - return false - } - if len(game.drawInfo.renderTargets) < len(RenderTargetSizes) { - return false - } - return true -} - -func (game *Game) Update() { - if !game.isInitialized() { - return - } - - const textureWidth = 57 - const textureHeight = 26 - - game.counter++ - game.drawInfo.inputStr = fmt.Sprintf(`Input State: - X: %d - Y: %d`, game.mouseX, game.mouseY) - - if game.mousePrevX != -1 && game.mousePrevY != -1 && - game.mouseX != -1 && game.mouseY != -1 { - dx, dy := game.mouseX-game.mousePrevX, game.mouseY-game.mousePrevY - game.textureX += dx - game.textureY += dy - - } - game.drawInfo.textureAngle = 2 * math.Pi * float64(game.counter) / 600 - - geo := matrix.IdentityGeometry() - geo.Translate(-textureWidth/2, -textureHeight/2) - geo.Rotate(game.drawInfo.textureAngle) - geo.Translate(textureWidth/2, textureHeight/2) - geo.Translate(float64(game.textureX), float64(game.textureY)) - - game.drawInfo.textureGeo = geo - - // Update for the next frame. - game.mousePrevX, game.mousePrevY = game.mouseX, game.mouseY -} - -func (game *Game) Draw(g graphics.Context) { - if !game.isInitialized() { - return - } - - whole := game.drawInfo.renderTargets["whole"] - g.SetOffscreen(whole) - g.Fill(0x70, 0x90, 0xe0) - game.drawTexture(g, game.drawInfo.textureGeo, matrix.IdentityColor()) - game.drawText(g, game.drawInfo.inputStr, 6, 6, &color.RGBA{0x0, 0x0, 0x0, 0x80}) - game.drawText(g, game.drawInfo.inputStr, 5, 5, color.White) - - g.ResetOffscreen() - g.DrawRenderTarget(whole, matrix.IdentityGeometry(), matrix.IdentityColor()) - wholeGeo := matrix.IdentityGeometry() - wholeGeo.Scale(0.5, 0.5) - wholeGeo.Translate(256/2, 240/2) - wholeColor := matrix.IdentityColor() - wholeColor.Scale(&color.RGBA{0x80, 0x80, 0x80, 0x80}) - g.DrawRenderTarget(whole, wholeGeo, wholeColor) -} - -func (game *Game) drawText(g graphics.Context, text string, x, y int, clr color.Color) { - const letterWidth = 6 - const letterHeight = 16 - - parts := []graphics.TexturePart{} - textX := 0 - textY := 0 - for _, c := range text { - if c == '\n' { - textX = 0 - textY += letterHeight - continue - } - code := int(c) - x := (code % 32) * letterWidth - y := (code / 32) * letterHeight - source := graphics.Rect{x, y, letterWidth, letterHeight} - parts = append(parts, graphics.TexturePart{ - LocationX: textX, - LocationY: textY, - Source: source, - }) - textX += letterWidth - } - - geometryMatrix := matrix.IdentityGeometry() - geometryMatrix.Translate(float64(x), float64(y)) - colorMatrix := matrix.IdentityColor() - colorMatrix.Scale(clr) - g.DrawTextureParts(game.drawInfo.textures["text"], parts, - geometryMatrix, colorMatrix) -} - -func (game *Game) drawTexture(g graphics.Context, geo matrix.Geometry, color matrix.Color) { - g.DrawTexture(game.drawInfo.textures["ebiten"], geo, color) -} diff --git a/example/images/blocks/background.png b/example/images/blocks/background.png new file mode 100644 index 0000000000000000000000000000000000000000..011b898d685825f1fa28a4bfd1b567a439e44f72 GIT binary patch literal 138 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1SJ1Ryj={WI14-?iy0WWg+Z8+Vb&Z8prDPX zi(`n#@wXQ@@-i53Fgu>`db6K#-pMl!Q%o+_=a#VEyt{Gbs<7X}{mekc3_AjE#mRa+ dVh6GRGcsSd*?y}vd$@?2>>t%C;|Wg literal 0 HcmV?d00001 diff --git a/example/images/blocks/blocks.png b/example/images/blocks/blocks.png new file mode 100644 index 0000000000000000000000000000000000000000..1f2ede3b3496fc05bfeba30e44e5d359cd267d18 GIT binary patch literal 165 zcmeAS@N?(olHy`uVBq!ia0vp^Za~b%!3HEbw`fcTQaPS3jv*eMZ>MhLJz&7WVn4B( z|1cZR;Vu7W&QbF6{BbYl=_8hFrZLrPdzmI}*x<$NdBEhnjtT#*Jp$kT=1(%;*Z#@z zr14eZ?_Hl2s@~~UeqUc`Agi|Uuu92{7QV?B5{0aM4k<+5D}Au{t$HQDuzXxCTfO8j PpuG&9u6{1-oD!M3-|7Yx02e8$AWWZJju+@BIz*Yya)oiu_9#GzdaYCR7m=9{`U;kMC zPAO^5-`83>|MSYg_?!XLh@N1v$|KVHGy^7W&bybRHX zy*JZEMiDLJ*C)R0RY0OVP zk*=OS;L=8aCmdY0Uh#XC-qD|i<=&?tJ+SoRqmLw~U%E}gJ~UgQeex9Lu{!q1x8Er5 z+y8wwHWvVMjY?sgB&(mti5J8iDZ~`3TJvz8=$5e z?aZQifNdwxXdv@vNW%f#<+Ip$84nLXiLtrGxK&JVjd0gNN?-ip=loLjx%U(BA1{Gq z^~!f8y)u@^vwK{&G(z)C&1#0?fi0p2#13MU8EiI%(FAM}$sJ+}7#Ab5jBQU~$xxyw zZ7b^7NDAtK6~xOhp2E;RY$wNTzZu^c%-jXsv7=~M!>iYcMt8p$ z?znZrFIA7Or{k(KAWfTJiq5KO!2xi}H@chfN{4998pE}ec+jV&XqFB4|Rk-`B?HitEWm$~~8(1GTA>wbxY6B6AEWM062Pn3(57V^+ z;&-4qfl3Q4-;T5{Ae}|X6Yz@|zd%qZL0CanC((2f3PTX>L>y?+#O7C^cE@6|ch^I` zAN$O2K8*19Sa%8Jo#q{RvUGP6FYQv-@-%IrIBa$f6^l5426zR?&x5^;3wI;Q0xoqB zPh&{2eMb;=n6MWOx2+xVMI>8BjSrrODc*oBRFJ42)S*!uTn0fOYH}^f>5ArOJbH7oP_8@Z1vG}R2QTbJ{W@MW@KUK~{QgSZbB^(w z(rYb#eFKulV0-?}`;`crP2#k?R-&n*em};G&~O+RUxdanw77z5gm`r{TS5Kqwc;ln zL~R{S=aKjlDjBvgh>3@w;MY9iG4(Rdcg9ZHCjU<-99+=%fiXs&49!bVksLU+?I4E)-UYG?ee zzGJn~J6-@}GevI1x=#UTE$a0kHUz(bnlj=Xn&&viOB=@NFIbi)MN~uBsHibo{ZmHDB1Pc@vkW3)U+x2VJ9? zjRt=~RDH64?DpABi1oT~)$al;)6YLHF2@9=$7>_mGjJro&arI@*XoPV|12N<7}@Fo bwwk{Iw`MFuQA#B|00000NkvXXu0mjf)^#I} literal 0 HcmV?d00001 diff --git a/example/images/blocks/font.png b/example/images/blocks/font.png new file mode 100644 index 0000000000000000000000000000000000000000..7a76f04f485ca0803bccfa9d9d99f0b7ae9343fb GIT binary patch literal 1261 zcmVz(-h_5KE4$6kZ<`)MuA%(uliI698x`gpnKs9y|(LEKc(DavjO291dYd17Is#Y4tMUBwC*_ZQ_pa*-p1 zL)Z89Us?EOX5JJ7uDMe z5RMlVuUp8$DBf8JP|;H4w-~^&i*vY=1ytNrux^o6fT!J8_)^W0P+XbjUCOsiJA@GK%~r<9(nR zM}s+N2_Z(&mLzgA3wIJJkXYkv_(#~$Ebt6~D!;`5Ay}ys0%8To(y<^ABgnb2E^LMH zyT^(n7tnQ61F2FZk-TD&==ccw1VCFmAs&TrRl$en_XP4;;VYBMQ07buh6IkQ<|9FP zAr5+@fdL3*7PYbq%2iMG?`JLe+40?4!(q3?~6B^b*1y@o{^!}_Xvmd62p(+4U)KKB!T@+0{pT!MlDTBH$ zo*1cQyxSm986|R*dVnKHk3uqK1-GvXlr2Y#i;dt70o?G)S_Puru%Zu?g{W5F<=&18 zQPFHDgR&K*$e!JwJiyaz2RUw5sLA$MGL0$^?&Q%v>94K<5)&{1E`=J~#K*?~?q)?4 zNdH-1geI@qAGCp#{Ub7py9@6}`3sC0@;i7RwXB@=7$?V+F5?3m~4C<1RUJ{!tmYHz7(Cg@Du|_(I_yas5-;M*1=bg^Y6kRY@YW z_FyKw5R|7|p-)u+B$1LuzgZ+5LZS!l@1XG2^Gs4GOLPUP1j~%*$pifU7HkZl?)$q# zfusV*ay1PZk$dyJRrffJ0Tdp5H%(tfGgY2n7ShVLgA-vHLRZ-}(mw!8W%o0vQGR82 z6${}mKHInR8>#)-O-FD3*z-p8&$5UpGGv*`4oj}={K*6_t^Z!s!gil@(j2aKQMYNk zF!8u(Au9EJVK@9f&mEeY2gvxX19=2={Ek$zTFhb-NM$+tndN7OuK)j%2e`Uk@wRQh zp^$u`6|AT@!s-KV*Lr(Lh)%W^ck>3jZ_3LE61m}(s5IGe9}d}VS+Mu>e9EU*te zg0L((a>Xv-j3rdIrQ0GHAMMIQKA(4*3qZdMaF<|kmT2j=!YYhsZ$W2D0x5t>(-<1I zf(9YgI$!UZed;xU@$a1Eq3G`D6EUnNR=;nPxr?s-|BBDgp1-nl_;MD|r2tPJ;fJ=r XKz>MmRKJ%&00000NkvXXu0mjfDauXI literal 0 HcmV?d00001 diff --git a/example/main.go b/example/main.go index d58566f31..0ea6bae42 100644 --- a/example/main.go +++ b/example/main.go @@ -1,38 +1,28 @@ package main import ( + "github.com/hajimehoshi/go-ebiten/example/blocks" "github.com/hajimehoshi/go-ebiten/graphics" "github.com/hajimehoshi/go-ebiten/ui" "github.com/hajimehoshi/go-ebiten/ui/cocoa" - "image" - _ "image/png" - "os" "runtime" "time" ) +type Game interface { + HandleEvent(e interface{}) + Update() + Draw(c graphics.Context) +} + func init() { runtime.LockOSThread() } -func loadImage(path string) (image.Image, error) { - file, err := os.Open(path) - if err != nil { - return nil, err - } - defer file.Close() - - img, _, err := image.Decode(file) - if err != nil { - return nil, err - } - return img, nil -} - func main() { - const screenWidth = 256 - const screenHeight = 240 - const screenScale = 3 + const screenWidth = blocks.ScreenWidth + const screenHeight = blocks.ScreenHeight + const screenScale = 2 const fps = 60 const title = "Ebiten Demo" @@ -42,33 +32,13 @@ func main() { textureFactoryEvents := textureFactory.Events() - for tag, path := range TexturePaths { - tag := tag - path := path - go func() { - img, err := loadImage(path) - if err != nil { - panic(err) - } - textureFactory.CreateTexture(tag, img) - }() - } - - for tag, size := range RenderTargetSizes { - tag := tag - size := size - go func() { - textureFactory.CreateRenderTarget(tag, size.Width, size.Height) - }() - } - drawing := make(chan *graphics.LazyContext) quit := make(chan struct{}) go func() { defer close(quit) windowEvents := window.Events() - game := NewGame() + var game Game = blocks.NewGame(textureFactory) frameTime := time.Duration(int64(time.Second) / int64(fps)) tick := time.Tick(frameTime) for { @@ -76,10 +46,10 @@ func main() { case e := <-textureFactoryEvents: game.HandleEvent(e) case e := <-windowEvents: + game.HandleEvent(e) if _, ok := e.(ui.WindowClosedEvent); ok { return } - game.HandleEvent(e) case <-tick: game.Update() case context := <-drawing: diff --git a/graphics/graphics.go b/graphics/graphics.go index 264695288..f211fa3fd 100644 --- a/graphics/graphics.go +++ b/graphics/graphics.go @@ -1,9 +1,5 @@ package graphics -import ( - "image/color" -) - type Rect struct { X int Y int @@ -17,11 +13,12 @@ type TexturePart struct { Source Rect } -type Line struct { - X1, Y1 int - X2, Y2 int - Color color.Color -} +type Filter int + +const ( + FilterNearest Filter = iota + FilterLinear +) type TextureId int diff --git a/graphics/opengl/context.go b/graphics/opengl/context.go index 48074e218..b2bb4f6ff 100644 --- a/graphics/opengl/context.go +++ b/graphics/opengl/context.go @@ -9,7 +9,6 @@ import ( "github.com/hajimehoshi/go-ebiten/graphics" "github.com/hajimehoshi/go-ebiten/graphics/matrix" "github.com/hajimehoshi/go-ebiten/graphics/opengl/offscreen" - "github.com/hajimehoshi/go-ebiten/graphics/opengl/texture" "math" ) @@ -29,10 +28,11 @@ func newContext(ids *ids, screenWidth, screenHeight, screenScale int) *Context { var err error context.screenId, err = ids.CreateRenderTarget( - screenWidth, screenHeight, texture.FilterNearest) + screenWidth, screenHeight, graphics.FilterNearest) if err != nil { panic("initializing the offscreen failed: " + err.Error()) } + context.Clear() return context } @@ -98,10 +98,6 @@ func (context *Context) DrawRenderTargetParts( context.DrawTextureParts(context.ids.ToTexture(id), parts, geometryMatrix, colorMatrix) } -func (context *Context) DrawLines(lines []graphics.Line) { - context.offscreen.DrawLines(lines) -} - func (context *Context) ResetOffscreen() { context.SetOffscreen(context.screenId) } diff --git a/graphics/opengl/device.go b/graphics/opengl/device.go index f06f1c6a9..9692043a0 100644 --- a/graphics/opengl/device.go +++ b/graphics/opengl/device.go @@ -2,7 +2,6 @@ package opengl import ( "github.com/hajimehoshi/go-ebiten/graphics" - "github.com/hajimehoshi/go-ebiten/graphics/opengl/texture" "image" ) @@ -26,13 +25,13 @@ func (d *Device) Update(context *Context, draw func(graphics.Context)) { } func (d *Device) CreateRenderTarget(width, height int) (graphics.RenderTargetId, error) { - renderTargetId, err := d.ids.CreateRenderTarget(width, height, texture.FilterLinear) + renderTargetId, err := d.ids.CreateRenderTarget(width, height, graphics.FilterLinear) if err != nil { return 0, err } return renderTargetId, nil } -func (d *Device) CreateTexture(img image.Image) (graphics.TextureId, error) { - return d.ids.CreateTextureFromImage(img) +func (d *Device) CreateTexture(img image.Image, filter graphics.Filter) (graphics.TextureId, error) { + return d.ids.CreateTexture(img, filter) } diff --git a/graphics/opengl/ids.go b/graphics/opengl/ids.go index 1db051057..c1c1c024b 100644 --- a/graphics/opengl/ids.go +++ b/graphics/opengl/ids.go @@ -50,9 +50,9 @@ func (i *ids) ToTexture(id graphics.RenderTargetId) graphics.TextureId { return i.renderTargetToTexture[id] } -func (i *ids) CreateTextureFromImage(img image.Image) ( +func (i *ids) CreateTexture(img image.Image, filter graphics.Filter) ( graphics.TextureId, error) { - texture, err := texture.CreateFromImage(img) + texture, err := texture.CreateFromImage(img, filter) if err != nil { return 0, err } @@ -64,7 +64,7 @@ func (i *ids) CreateTextureFromImage(img image.Image) ( return textureId, nil } -func (i *ids) CreateRenderTarget(width, height int, filter texture.Filter) ( +func (i *ids) CreateRenderTarget(width, height int, filter graphics.Filter) ( graphics.RenderTargetId, error) { renderTarget, texture, err := rendertarget.Create(width, height, filter) if err != nil { diff --git a/graphics/opengl/offscreen/offscreen.go b/graphics/opengl/offscreen/offscreen.go index 344310f84..7d80e223b 100644 --- a/graphics/opengl/offscreen/offscreen.go +++ b/graphics/opengl/offscreen/offscreen.go @@ -63,10 +63,6 @@ func (o *Offscreen) DrawTextureParts(texture *gtexture.Texture, texture.DrawParts(parts, &drawable{o, geometryMatrix, colorMatrix}) } -func (o *Offscreen) DrawLines(lines []graphics.Line) { - // TODO: Implement! -} - type setter struct { offscreen *Offscreen usingMainFramebuffer bool diff --git a/graphics/opengl/rendertarget/render_target.go b/graphics/opengl/rendertarget/render_target.go index c26f879da..a5c5cfe3c 100644 --- a/graphics/opengl/rendertarget/render_target.go +++ b/graphics/opengl/rendertarget/render_target.go @@ -5,6 +5,7 @@ package rendertarget // #include import "C" import ( + "github.com/hajimehoshi/go-ebiten/graphics" "github.com/hajimehoshi/go-ebiten/graphics/opengl/texture" gtexture "github.com/hajimehoshi/go-ebiten/graphics/texture" ) @@ -43,7 +44,7 @@ func (f *framebufferCreator) Create(native interface{}) interface{} { return createFramebuffer(C.GLuint(native.(texture.Native))) } -func Create(width, height int, filter texture.Filter) ( +func Create(width, height int, filter graphics.Filter) ( *gtexture.RenderTarget, *gtexture.Texture, error) { tex, err := texture.Create(width, height, filter) if err != nil { diff --git a/graphics/opengl/texture/texture.go b/graphics/opengl/texture/texture.go index fbf3b4a55..8947bea97 100644 --- a/graphics/opengl/texture/texture.go +++ b/graphics/opengl/texture/texture.go @@ -5,6 +5,7 @@ package texture // #include import "C" import ( + "github.com/hajimehoshi/go-ebiten/graphics" gtexture "github.com/hajimehoshi/go-ebiten/graphics/texture" "image" "unsafe" @@ -12,15 +13,8 @@ import ( type Native C.GLuint -type Filter int - -const ( - FilterLinear Filter = iota - FilterNearest -) - func createNativeTexture(textureWidth, textureHeight int, pixels []uint8, - filter Filter) Native { + filter graphics.Filter) Native { nativeTexture := C.GLuint(0) C.glGenTextures(1, (*C.GLuint)(&nativeTexture)) @@ -33,9 +27,9 @@ func createNativeTexture(textureWidth, textureHeight int, pixels []uint8, glFilter := C.GLint(0) switch filter { - case FilterLinear: + case graphics.FilterLinear: glFilter = C.GL_LINEAR - case FilterNearest: + case graphics.FilterNearest: glFilter = C.GL_NEAREST default: panic("not reached") @@ -54,17 +48,12 @@ func createNativeTexture(textureWidth, textureHeight int, pixels []uint8, return Native(nativeTexture) } -func create(textureWidth, textureHeight int, filter Filter) ( +func create(textureWidth, textureHeight int, filter graphics.Filter) ( interface{}, error) { return createNativeTexture(textureWidth, textureHeight, nil, filter), nil } -func createFromImage(img *image.NRGBA) (interface{}, error) { - size := img.Bounds().Size() - return createNativeTexture(size.X, size.Y, img.Pix, FilterLinear), nil -} - -func Create(width, height int, filter Filter) (*gtexture.Texture, error) { +func Create(width, height int, filter graphics.Filter) (*gtexture.Texture, error) { native, err := create(gtexture.AdjustSize(width), gtexture.AdjustSize(height), filter) if err != nil { @@ -73,11 +62,9 @@ func Create(width, height int, filter Filter) (*gtexture.Texture, error) { return gtexture.New(native, width, height), nil } -func CreateFromImage(img image.Image) (*gtexture.Texture, error) { - native, err := createFromImage(gtexture.AdjustImage(img)) - if err != nil { - return nil, err - } - size := img.Bounds().Size() +func CreateFromImage(img image.Image, filter graphics.Filter) (*gtexture.Texture, error) { + adjustedImage := gtexture.AdjustImage(img) + size := adjustedImage.Bounds().Size() + native := createNativeTexture(size.X, size.Y, adjustedImage.Pix, filter) return gtexture.New(native, size.X, size.Y), nil } diff --git a/graphics/texture/texture.go b/graphics/texture/texture.go index 17e2e6c79..04d5aac67 100644 --- a/graphics/texture/texture.go +++ b/graphics/texture/texture.go @@ -36,7 +36,7 @@ func AdjustImage(img image.Image) *image.NRGBA { AdjustSize(height), }, } - if nrgba := img.(*image.NRGBA); nrgba != nil && + if nrgba, ok := img.(*image.NRGBA); ok && img.Bounds() == adjustedImageBounds { return nrgba } diff --git a/graphics/texture_factory.go b/graphics/texture_factory.go index 7478cc2bb..41a08c7a0 100644 --- a/graphics/texture_factory.go +++ b/graphics/texture_factory.go @@ -18,6 +18,6 @@ type RenderTargetCreatedEvent struct { type TextureFactory interface { CreateRenderTarget(tag interface{}, width, height int) - CreateTexture(tag interface{}, img image.Image) + CreateTexture(tag interface{}, img image.Image, filter Filter) Events() <-chan interface{} } diff --git a/ui/cocoa/ui.go b/ui/cocoa/ui.go index 4634f825a..26e969862 100644 --- a/ui/cocoa/ui.go +++ b/ui/cocoa/ui.go @@ -15,9 +15,9 @@ import ( ) type cocoaUI struct { - textureFactory *textureFactory + textureFactory *textureFactory textureFactoryEvents chan interface{} - graphicsDevice *opengl.Device + graphicsDevice *opengl.Device } var currentUI *cocoaUI @@ -63,12 +63,12 @@ func (u *cocoaUI) Events() <-chan interface{} { return u.textureFactoryEvents } -func (u *cocoaUI) CreateTexture(tag interface{}, img image.Image) { +func (u *cocoaUI) CreateTexture(tag interface{}, img image.Image, filter graphics.Filter) { go func() { var id graphics.TextureId var err error u.textureFactory.useGLContext(func() { - id, err = u.graphicsDevice.CreateTexture(img) + id, err = u.graphicsDevice.CreateTexture(img, filter) }) if u.textureFactoryEvents == nil { return diff --git a/ui/cocoa/window.go b/ui/cocoa/window.go index d16143a3c..d8e9b33a1 100644 --- a/ui/cocoa/window.go +++ b/ui/cocoa/window.go @@ -114,12 +114,13 @@ func (w *Window) notify(e interface{}) { }() } -/*//export ebiten_ScreenSizeUpdated -func ebiten_ScreenSizeUpdated(nativeWindow unsafe.Pointer, width, height int) { - u := currentUI - e := ui.ScreenSizeUpdatedEvent{width, height} - u.windowEvents.notifyScreenSizeUpdated(e) -}*/ +// Now this function is not used anywhere. +//export ebiten_WindowSizeUpdated +func ebiten_WindowSizeUpdated(nativeWindow unsafe.Pointer, width, height int) { + w := windows[nativeWindow] + e := ui.WindowSizeUpdatedEvent{width, height} + w.notify(e) +} func (w *Window) keyStateUpdatedEvent() ui.KeyStateUpdatedEvent { keys := []ui.Key{} @@ -132,6 +133,7 @@ func (w *Window) keyStateUpdatedEvent() ui.KeyStateUpdatedEvent { } var cocoaKeyCodeToKey = map[int]ui.Key{ + 49: ui.KeySpace, 123: ui.KeyLeft, 124: ui.KeyRight, 125: ui.KeyUp, diff --git a/ui/ui.go b/ui/ui.go index b3c7af525..489bae92d 100644 --- a/ui/ui.go +++ b/ui/ui.go @@ -11,9 +11,10 @@ const ( KeyDown KeyLeft KeyRight + KeySpace ) -type ScreenSizeUpdatedEvent struct { +type WindowSizeUpdatedEvent struct { Width int Height int }