123 lines
3.4 KiB
Go
123 lines
3.4 KiB
Go
package world
|
|
|
|
import (
|
|
"image"
|
|
"image/color"
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
type bgTheme struct {
|
|
img image.Image
|
|
}
|
|
|
|
func (t bgTheme) ID() string { return "bg" }
|
|
func (t bgTheme) Name() string { return "bg" }
|
|
|
|
func (t bgTheme) BackgroundColor() color.Color { return color.RGBA{A: 255} }
|
|
func (t bgTheme) BackgroundImage() image.Image { return t.img }
|
|
|
|
func (t bgTheme) BackgroundTileMode() BackgroundTileMode { return BackgroundTileRepeat }
|
|
func (t bgTheme) BackgroundScaleMode() BackgroundScaleMode { return BackgroundScaleNone }
|
|
func (t bgTheme) BackgroundAnchorMode() BackgroundAnchorMode { return BackgroundAnchorViewport }
|
|
|
|
func (t bgTheme) PointStyle() Style { return Style{FillColor: color.RGBA{A: 255}, PointRadiusPx: 2} }
|
|
func (t bgTheme) LineStyle() Style { return Style{StrokeColor: color.RGBA{A: 255}, StrokeWidthPx: 1} }
|
|
func (t bgTheme) CircleStyle() Style {
|
|
return Style{FillColor: color.RGBA{A: 255}, StrokeColor: color.RGBA{A: 255}, StrokeWidthPx: 1}
|
|
}
|
|
|
|
func (t bgTheme) PointClassOverride(PointClassID) (StyleOverride, bool) {
|
|
return StyleOverride{}, false
|
|
}
|
|
func (t bgTheme) LineClassOverride(LineClassID) (StyleOverride, bool) { return StyleOverride{}, false }
|
|
func (t bgTheme) CircleClassOverride(CircleClassID) (StyleOverride, bool) {
|
|
return StyleOverride{}, false
|
|
}
|
|
|
|
func TestRender_BackgroundImage_DrawsBeforePrimitives_FullRedraw(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
w := NewWorld(10, 10)
|
|
w.resetGrid(2 * SCALE)
|
|
|
|
// 4x4 opaque image
|
|
img := image.NewRGBA(image.Rect(0, 0, 4, 4))
|
|
w.SetTheme(bgTheme{img: img})
|
|
|
|
_, err := w.AddPoint(5, 5)
|
|
require.NoError(t, err)
|
|
for _, obj := range w.objects {
|
|
w.indexObject(obj)
|
|
}
|
|
|
|
params := RenderParams{
|
|
ViewportWidthPx: 10,
|
|
ViewportHeightPx: 10,
|
|
MarginXPx: 2,
|
|
MarginYPx: 2,
|
|
CameraXWorldFp: 5 * SCALE,
|
|
CameraYWorldFp: 5 * SCALE,
|
|
CameraZoom: 1.0,
|
|
}
|
|
|
|
d := &fakePrimitiveDrawer{}
|
|
require.NoError(t, w.Render(d, params))
|
|
|
|
cmds := d.Commands()
|
|
iClear := indexOfFirstName(cmds, "ClearAllTo")
|
|
iBg := indexOfFirstName(cmds, "DrawImage")
|
|
iPrim := indexOfFirstName(cmds, "AddPoint")
|
|
|
|
require.NotEqual(t, -1, iClear)
|
|
require.NotEqual(t, -1, iBg)
|
|
require.NotEqual(t, -1, iPrim)
|
|
require.Less(t, iClear, iBg)
|
|
require.Less(t, iBg, iPrim)
|
|
}
|
|
|
|
func TestRender_BackgroundImage_RedrawnInDirtyRects_OnIncrementalShift(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
w := NewWorld(10, 10)
|
|
w.resetGrid(2 * SCALE)
|
|
|
|
img := image.NewRGBA(image.Rect(0, 0, 4, 4))
|
|
w.SetTheme(bgTheme{img: img})
|
|
|
|
// Ensure state: first full render commits.
|
|
params := RenderParams{
|
|
ViewportWidthPx: 10,
|
|
ViewportHeightPx: 10,
|
|
MarginXPx: 2,
|
|
MarginYPx: 2,
|
|
CameraXWorldFp: 5 * SCALE,
|
|
CameraYWorldFp: 5 * SCALE,
|
|
CameraZoom: 1.0,
|
|
Options: &RenderOptions{
|
|
Incremental: &IncrementalPolicy{
|
|
AllowShiftOnly: false,
|
|
MaxCatchUpAreaPx: 0,
|
|
RenderBudgetMs: 0,
|
|
CoalesceUpdates: false,
|
|
},
|
|
},
|
|
}
|
|
|
|
d := &fakePrimitiveDrawer{}
|
|
require.NoError(t, w.Render(d, params))
|
|
|
|
// Move camera by 1px right in world (zoom=1 => 1px == 1 unit).
|
|
params2 := params
|
|
params2.CameraXWorldFp += 1 * SCALE
|
|
|
|
d2 := &fakePrimitiveDrawer{}
|
|
require.NoError(t, w.Render(d2, params2))
|
|
|
|
// In incremental shift path we must see ClearRectTo and DrawImage.
|
|
require.NotEmpty(t, d2.CommandsByName("CopyShift"))
|
|
require.NotEmpty(t, d2.CommandsByName("ClearRectTo"))
|
|
require.NotEmpty(t, d2.CommandsByName("DrawImage"))
|
|
}
|