github.com/cybriq/giocore@v0.0.7-0.20210703034601-cfb9cb5f3900/gpu/headless/headless_test.go (about) 1 // SPDX-License-Identifier: Unlicense OR MIT 2 3 package headless 4 5 import ( 6 "image" 7 "image/color" 8 "testing" 9 10 "github.com/cybriq/giocore/f32" 11 "github.com/cybriq/giocore/internal/f32color" 12 "github.com/cybriq/giocore/op" 13 "github.com/cybriq/giocore/op/clip" 14 "github.com/cybriq/giocore/op/paint" 15 ) 16 17 func TestHeadless(t *testing.T) { 18 w, release := newTestWindow(t) 19 defer release() 20 21 sz := w.size 22 col := color.NRGBA{A: 0xff, R: 0xca, G: 0xfe} 23 var ops op.Ops 24 paint.ColorOp{Color: col}.Add(&ops) 25 // Paint only part of the screen to avoid the glClear optimization. 26 paint.FillShape(&ops, col, clip.Rect(image.Rect(0, 0, sz.X-100, sz.Y-100)).Op()) 27 if err := w.Frame(&ops); err != nil { 28 t.Fatal(err) 29 } 30 31 img, err := w.Screenshot() 32 if err != nil { 33 t.Fatal(err) 34 } 35 if isz := img.Bounds().Size(); isz != sz { 36 t.Errorf("got %v screenshot, expected %v", isz, sz) 37 } 38 if got := img.RGBAAt(0, 0); got != f32color.NRGBAToRGBA(col) { 39 t.Errorf("got color %v, expected %v", got, f32color.NRGBAToRGBA(col)) 40 } 41 } 42 43 func TestClipping(t *testing.T) { 44 w, release := newTestWindow(t) 45 defer release() 46 47 col := color.NRGBA{A: 0xff, R: 0xca, G: 0xfe} 48 col2 := color.NRGBA{A: 0xff, R: 0x00, G: 0xfe} 49 var ops op.Ops 50 paint.ColorOp{Color: col}.Add(&ops) 51 clip.RRect{ 52 Rect: f32.Rectangle{ 53 Min: f32.Point{X: 50, Y: 50}, 54 Max: f32.Point{X: 250, Y: 250}, 55 }, 56 SE: 75, 57 }.Add(&ops) 58 paint.PaintOp{}.Add(&ops) 59 paint.ColorOp{Color: col2}.Add(&ops) 60 clip.RRect{ 61 Rect: f32.Rectangle{ 62 Min: f32.Point{X: 100, Y: 100}, 63 Max: f32.Point{X: 350, Y: 350}, 64 }, 65 NW: 75, 66 }.Add(&ops) 67 paint.PaintOp{}.Add(&ops) 68 if err := w.Frame(&ops); err != nil { 69 t.Fatal(err) 70 } 71 72 img, err := w.Screenshot() 73 if err != nil { 74 t.Fatal(err) 75 } 76 if *dumpImages { 77 if err := saveImage("clip.png", img); err != nil { 78 t.Fatal(err) 79 } 80 } 81 var bg color.NRGBA 82 tests := []struct { 83 x, y int 84 color color.NRGBA 85 }{ 86 {120, 120, col}, 87 {130, 130, col2}, 88 {210, 210, col2}, 89 {230, 230, bg}, 90 } 91 for _, test := range tests { 92 if got := img.RGBAAt(test.x, test.y); got != f32color.NRGBAToRGBA(test.color) { 93 t.Errorf("(%d,%d): got color %v, expected %v", test.x, test.y, got, f32color.NRGBAToRGBA(test.color)) 94 } 95 } 96 } 97 98 func TestDepth(t *testing.T) { 99 w, release := newTestWindow(t) 100 defer release() 101 var ops op.Ops 102 103 blue := color.NRGBA{B: 0xFF, A: 0xFF} 104 paint.FillShape(&ops, blue, clip.Rect(image.Rect(0, 0, 50, 100)).Op()) 105 red := color.NRGBA{R: 0xFF, A: 0xFF} 106 paint.FillShape(&ops, red, clip.Rect(image.Rect(0, 0, 100, 50)).Op()) 107 if err := w.Frame(&ops); err != nil { 108 t.Fatal(err) 109 } 110 111 img, err := w.Screenshot() 112 if err != nil { 113 t.Fatal(err) 114 } 115 if *dumpImages { 116 if err := saveImage("depth.png", img); err != nil { 117 t.Fatal(err) 118 } 119 } 120 tests := []struct { 121 x, y int 122 color color.NRGBA 123 }{ 124 {25, 25, red}, 125 {75, 25, red}, 126 {25, 75, blue}, 127 } 128 for _, test := range tests { 129 if got := img.RGBAAt(test.x, test.y); got != f32color.NRGBAToRGBA(test.color) { 130 t.Errorf("(%d,%d): got color %v, expected %v", test.x, test.y, got, f32color.NRGBAToRGBA(test.color)) 131 } 132 } 133 } 134 135 func newTestWindow(t *testing.T) (*Window, func()) { 136 t.Helper() 137 sz := image.Point{X: 800, Y: 600} 138 w, err := NewWindow(sz.X, sz.Y) 139 if err != nil { 140 t.Skipf("headless windows not supported: %v", err) 141 } 142 return w, func() { 143 w.Release() 144 } 145 }