github.com/cybriq/giocore@v0.0.7-0.20210703034601-cfb9cb5f3900/gpu/internal/rendertest/transform_test.go (about)

     1  package rendertest
     2  
     3  import (
     4  	"image"
     5  	"math"
     6  	"testing"
     7  
     8  	"golang.org/x/image/colornames"
     9  
    10  	"github.com/cybriq/giocore/f32"
    11  	"github.com/cybriq/giocore/op"
    12  	"github.com/cybriq/giocore/op/clip"
    13  	"github.com/cybriq/giocore/op/paint"
    14  )
    15  
    16  func TestPaintOffset(t *testing.T) {
    17  	run(t, func(o *op.Ops) {
    18  		op.Offset(f32.Pt(10, 20)).Add(o)
    19  		paint.FillShape(o, red, clip.Rect(image.Rect(0, 0, 50, 50)).Op())
    20  	}, func(r result) {
    21  		r.expect(0, 0, transparent)
    22  		r.expect(59, 30, colornames.Red)
    23  		r.expect(60, 30, transparent)
    24  		r.expect(10, 70, transparent)
    25  	})
    26  }
    27  
    28  func TestPaintRotate(t *testing.T) {
    29  	run(t, func(o *op.Ops) {
    30  		a := f32.Affine2D{}.Rotate(f32.Pt(40, 40), -math.Pi/8)
    31  		op.Affine(a).Add(o)
    32  		paint.FillShape(o, red, clip.Rect(image.Rect(20, 20, 60, 60)).Op())
    33  	}, func(r result) {
    34  		r.expect(40, 40, colornames.Red)
    35  		r.expect(50, 19, colornames.Red)
    36  		r.expect(59, 19, transparent)
    37  		r.expect(21, 21, transparent)
    38  	})
    39  }
    40  
    41  func TestPaintShear(t *testing.T) {
    42  	run(t, func(o *op.Ops) {
    43  		a := f32.Affine2D{}.Shear(f32.Point{}, math.Pi/4, 0)
    44  		op.Affine(a).Add(o)
    45  		paint.FillShape(o, red, clip.Rect(image.Rect(0, 0, 40, 40)).Op())
    46  	}, func(r result) {
    47  		r.expect(10, 30, transparent)
    48  	})
    49  }
    50  
    51  func TestClipPaintOffset(t *testing.T) {
    52  	run(t, func(o *op.Ops) {
    53  		clip.RRect{Rect: f32.Rect(10, 10, 30, 30)}.Add(o)
    54  		op.Offset(f32.Pt(20, 20)).Add(o)
    55  		paint.FillShape(o, red, clip.Rect(image.Rect(0, 0, 100, 100)).Op())
    56  	}, func(r result) {
    57  		r.expect(0, 0, transparent)
    58  		r.expect(19, 19, transparent)
    59  		r.expect(20, 20, colornames.Red)
    60  		r.expect(30, 30, transparent)
    61  	})
    62  }
    63  
    64  func TestClipOffset(t *testing.T) {
    65  	run(t, func(o *op.Ops) {
    66  		op.Offset(f32.Pt(20, 20)).Add(o)
    67  		clip.RRect{Rect: f32.Rect(10, 10, 30, 30)}.Add(o)
    68  		paint.FillShape(o, red, clip.Rect(image.Rect(0, 0, 100, 100)).Op())
    69  	}, func(r result) {
    70  		r.expect(0, 0, transparent)
    71  		r.expect(29, 29, transparent)
    72  		r.expect(30, 30, colornames.Red)
    73  		r.expect(49, 49, colornames.Red)
    74  		r.expect(50, 50, transparent)
    75  	})
    76  }
    77  
    78  func TestClipScale(t *testing.T) {
    79  	run(t, func(o *op.Ops) {
    80  		a := f32.Affine2D{}.Scale(f32.Point{}, f32.Pt(2, 2)).Offset(f32.Pt(10, 10))
    81  		op.Affine(a).Add(o)
    82  		clip.RRect{Rect: f32.Rect(10, 10, 20, 20)}.Add(o)
    83  		paint.FillShape(o, red, clip.Rect(image.Rect(0, 0, 1000, 1000)).Op())
    84  	}, func(r result) {
    85  		r.expect(19+10, 19+10, transparent)
    86  		r.expect(20+10, 20+10, colornames.Red)
    87  		r.expect(39+10, 39+10, colornames.Red)
    88  		r.expect(40+10, 40+10, transparent)
    89  	})
    90  }
    91  
    92  func TestClipRotate(t *testing.T) {
    93  	run(t, func(o *op.Ops) {
    94  		op.Affine(f32.Affine2D{}.Rotate(f32.Pt(40, 40), -math.Pi/4)).Add(o)
    95  		clip.RRect{Rect: f32.Rect(30, 30, 50, 50)}.Add(o)
    96  		paint.FillShape(o, red, clip.Rect(image.Rect(0, 40, 100, 100)).Op())
    97  	}, func(r result) {
    98  		r.expect(39, 39, transparent)
    99  		r.expect(41, 41, colornames.Red)
   100  		r.expect(50, 50, transparent)
   101  	})
   102  }
   103  
   104  func TestOffsetTexture(t *testing.T) {
   105  	run(t, func(o *op.Ops) {
   106  		op.Offset(f32.Pt(15, 15)).Add(o)
   107  		squares.Add(o)
   108  		scale(50.0/512, 50.0/512).Add(o)
   109  		paint.PaintOp{}.Add(o)
   110  	}, func(r result) {
   111  		r.expect(14, 20, transparent)
   112  		r.expect(66, 20, transparent)
   113  		r.expect(16, 64, colornames.Green)
   114  		r.expect(64, 16, colornames.Green)
   115  	})
   116  }
   117  
   118  func TestOffsetScaleTexture(t *testing.T) {
   119  	run(t, func(o *op.Ops) {
   120  		op.Offset(f32.Pt(15, 15)).Add(o)
   121  		squares.Add(o)
   122  		op.Affine(f32.Affine2D{}.Scale(f32.Point{}, f32.Pt(2, 1))).Add(o)
   123  		scale(50.0/512, 50.0/512).Add(o)
   124  		paint.PaintOp{}.Add(o)
   125  	}, func(r result) {
   126  		r.expect(114, 64, colornames.Blue)
   127  		r.expect(116, 64, transparent)
   128  	})
   129  }
   130  
   131  func TestRotateTexture(t *testing.T) {
   132  	run(t, func(o *op.Ops) {
   133  		defer op.Save(o).Load()
   134  		squares.Add(o)
   135  		a := f32.Affine2D{}.Offset(f32.Pt(30, 30)).Rotate(f32.Pt(40, 40), math.Pi/4)
   136  		op.Affine(a).Add(o)
   137  		scale(20.0/512, 20.0/512).Add(o)
   138  		paint.PaintOp{}.Add(o)
   139  	}, func(r result) {
   140  		r.expect(40, 40-12, colornames.Blue)
   141  		r.expect(40+12, 40, colornames.Green)
   142  	})
   143  }
   144  
   145  func TestRotateClipTexture(t *testing.T) {
   146  	run(t, func(o *op.Ops) {
   147  		squares.Add(o)
   148  		a := f32.Affine2D{}.Rotate(f32.Pt(40, 40), math.Pi/8)
   149  		op.Affine(a).Add(o)
   150  		clip.RRect{Rect: f32.Rect(30, 30, 50, 50)}.Add(o)
   151  		op.Affine(f32.Affine2D{}.Offset(f32.Pt(10, 10))).Add(o)
   152  		scale(60.0/512, 60.0/512).Add(o)
   153  		paint.PaintOp{}.Add(o)
   154  	}, func(r result) {
   155  		r.expect(0, 0, transparent)
   156  		r.expect(37, 39, colornames.Green)
   157  		r.expect(36, 39, colornames.Green)
   158  		r.expect(35, 39, colornames.Green)
   159  		r.expect(34, 39, colornames.Green)
   160  		r.expect(33, 39, colornames.Green)
   161  	})
   162  }
   163  
   164  func TestComplicatedTransform(t *testing.T) {
   165  	run(t, func(o *op.Ops) {
   166  		squares.Add(o)
   167  
   168  		clip.RRect{Rect: f32.Rect(0, 0, 100, 100), SE: 50, SW: 50, NW: 50, NE: 50}.Add(o)
   169  
   170  		a := f32.Affine2D{}.Shear(f32.Point{}, math.Pi/4, 0)
   171  		op.Affine(a).Add(o)
   172  		clip.RRect{Rect: f32.Rect(0, 0, 50, 40)}.Add(o)
   173  
   174  		scale(50.0/512, 50.0/512).Add(o)
   175  		paint.PaintOp{}.Add(o)
   176  	}, func(r result) {
   177  		r.expect(20, 5, transparent)
   178  	})
   179  }
   180  
   181  func TestTransformOrder(t *testing.T) {
   182  	// check the ordering of operations bot in affine and in gpu stack.
   183  	run(t, func(o *op.Ops) {
   184  		a := f32.Affine2D{}.Offset(f32.Pt(64, 64))
   185  		op.Affine(a).Add(o)
   186  
   187  		b := f32.Affine2D{}.Scale(f32.Point{}, f32.Pt(8, 8))
   188  		op.Affine(b).Add(o)
   189  
   190  		c := f32.Affine2D{}.Offset(f32.Pt(-10, -10)).Scale(f32.Point{}, f32.Pt(0.5, 0.5))
   191  		op.Affine(c).Add(o)
   192  		paint.FillShape(o, red, clip.Rect(image.Rect(0, 0, 20, 20)).Op())
   193  	}, func(r result) {
   194  		// centered and with radius 40
   195  		r.expect(64-41, 64, transparent)
   196  		r.expect(64-39, 64, colornames.Red)
   197  		r.expect(64+39, 64, colornames.Red)
   198  		r.expect(64+41, 64, transparent)
   199  	})
   200  }