main.go 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. // Copyright 2018 The Ebiten Authors
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. // This example is an experiment to minify images with various filters.
  15. // When linear filter is used, mipmap images should be used for high-quality rendering (#578).
  16. package main
  17. import (
  18. "bytes"
  19. "fmt"
  20. "image"
  21. _ "image/jpeg"
  22. "log"
  23. "math"
  24. "github.com/hajimehoshi/ebiten/v2"
  25. "github.com/hajimehoshi/ebiten/v2/ebitenutil"
  26. "github.com/hajimehoshi/ebiten/v2/examples/resources/images"
  27. "github.com/hajimehoshi/ebiten/v2/inpututil"
  28. )
  29. const (
  30. screenWidth = 1000
  31. screenHeight = 480
  32. )
  33. var (
  34. gophersImage *ebiten.Image
  35. )
  36. type Game struct {
  37. rotate bool
  38. clip bool
  39. counter int
  40. pause bool
  41. }
  42. func (g *Game) Update() error {
  43. if inpututil.IsKeyJustPressed(ebiten.KeyR) {
  44. g.rotate = !g.rotate
  45. }
  46. if inpututil.IsKeyJustPressed(ebiten.KeyC) {
  47. g.clip = !g.clip
  48. }
  49. if inpututil.IsMouseButtonJustPressed(ebiten.MouseButtonLeft) {
  50. g.pause = !g.pause
  51. }
  52. if g.pause {
  53. return nil
  54. }
  55. g.counter++
  56. if g.counter == 480 {
  57. g.counter = 0
  58. }
  59. return nil
  60. }
  61. func (g *Game) Draw(screen *ebiten.Image) {
  62. s := 1.5 / math.Pow(1.01, float64(g.counter))
  63. clippedGophersImage := gophersImage.SubImage(image.Rect(100, 100, 200, 200)).(*ebiten.Image)
  64. for i := range 3 {
  65. //for i, f := range []ebiten.Filter{ebiten.FilterNearest, ebiten.FilterLinear} {
  66. w, h := gophersImage.Bounds().Dx(), gophersImage.Bounds().Dy()
  67. op := &ebiten.DrawImageOptions{}
  68. if g.rotate {
  69. op.GeoM.Translate(-float64(w)/2, -float64(h)/2)
  70. op.GeoM.Rotate(float64(g.counter) / 300 * 2 * math.Pi)
  71. op.GeoM.Translate(float64(w)/2, float64(h)/2)
  72. }
  73. op.GeoM.Scale(s, s)
  74. op.GeoM.Translate(32+float64(i*w)*s+float64(i*4), 100)
  75. if i == 0 {
  76. op.Filter = ebiten.FilterNearest
  77. } else {
  78. op.Filter = ebiten.FilterLinear
  79. }
  80. if i == 2 {
  81. op.DisableMipmaps = true
  82. }
  83. if g.clip {
  84. screen.DrawImage(clippedGophersImage, op)
  85. } else {
  86. screen.DrawImage(gophersImage, op)
  87. }
  88. }
  89. msg := fmt.Sprintf(`Minifying images (Nearest filter, Linear filter (w/ mipmaps), and Linear Filter (w/o mipmaps)):
  90. Press R to rotate the images.
  91. Press C to clip the images.
  92. Click to pause and resume.
  93. Scale: %0.2f`, s)
  94. ebitenutil.DebugPrint(screen, msg)
  95. }
  96. func (g *Game) Layout(outsideWidth, outsideHeight int) (int, int) {
  97. return screenWidth, screenHeight
  98. }
  99. func main() {
  100. // Decode an image from the image file's byte slice.
  101. img, _, err := image.Decode(bytes.NewReader(images.Gophers_jpg))
  102. if err != nil {
  103. log.Fatal(err)
  104. }
  105. gophersImage = ebiten.NewImageFromImage(img)
  106. ebiten.SetWindowSize(screenWidth, screenHeight)
  107. ebiten.SetWindowTitle("Minify (Ebitengine Demo)")
  108. if err := ebiten.RunGame(&Game{}); err != nil {
  109. log.Fatal(err)
  110. }
  111. }