Anti-Grain Geometry Tutorial
tutorial_gradient_1.cpp
1 /*
2  * Copyright (c) 2019 Heng Yuan
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 #include <agg_conv_transform.h>
17 #include <agg_gamma_functions.h>
18 #include <agg_gamma_lut.h>
19 #include <agg_gradient_lut.h>
20 #include <agg_pixfmt_rgba.h>
21 #include <agg_rasterizer_scanline_aa.h>
22 #include <agg_renderer_base.h>
23 #include <agg_renderer_scanline.h>
24 #include <agg_scanline_p.h>
25 #include <agg_span_allocator.h>
26 #include <agg_span_interpolator_linear.h>
27 #include <agg_span_gradient.h>
28 
29 #include "path.h"
30 #include "writepng.h"
31 
34 
35 template<class GradientFunctionType>
36 void
37 drawGradient (GradientFunctionType& gradientFunction,
38  RendererBaseType& rBase,
39  SimplePath& path,
40  agg::trans_affine& matrix)
41 {
42  typedef agg::gradient_linear_color<agg::rgba8> ColorFunctionType;
43 
44  typedef agg::span_interpolator_linear<agg::trans_affine> InterpolatorType;
45  typedef agg::span_allocator<agg::rgba8> SpanAllocatorType;
47  InterpolatorType,
48  GradientFunctionType,
49  ColorFunctionType> SpanGradientType;
50 
51  agg::trans_affine invertMatrix (matrix);
52  invertMatrix.invert();
53  InterpolatorType interpolator (invertMatrix);
54 
55  ColorFunctionType colorFunction (agg::rgba8 (0, 0, 0, 0xff),
56  agg::rgba8 (0xff, 0xff, 0xff, 0xff),
57  100);
58 
59  SpanGradientType sg (interpolator, gradientFunction, colorFunction, 0.0, 50.0);
60  SpanAllocatorType sa;
61 
63  agg::scanline_p8 scanline;
64 
65  ras.auto_close(false);
66  ras.reset ();
67  agg::conv_transform<SimplePath> tp (path, matrix);
68  ras.add_path(tp);
69  agg::render_scanlines_aa(ras, scanline, rBase, sa, sg);
70 }
71 
72 int
73 main (int argc, const char* argv[])
74 {
75  try
76  {
77  const int imageWidth = 1000;
78  const int imageHeight = 300;
79 
80  const int pixelSize = PixelFormat::pix_width;
81 
82  agg::rendering_buffer renderBuffer;
83  PixelFormat pixFmt;
84  RendererBaseType rBase;
85 
86  unsigned char *imageBuffer = new unsigned char[imageWidth * imageHeight * pixelSize];
87 
88  // Hook everything up
89  renderBuffer.attach (imageBuffer, imageWidth, imageHeight, imageWidth * pixelSize);
90  pixFmt.attach(renderBuffer);
91  rBase.attach(pixFmt);
92 
93  const agg::rgba8 transparentwhiteColor (0xff, 0xff, 0xff, 0);
94  const agg::rgba8 blueColor (0, 0, 0xff, 0xff);
95 
96  // clear the buffer with transparent white color
97  rBase.clear(transparentwhiteColor);
98 
100  agg::scanline_p8 scanline;
101 
102  ras.auto_close(false);
103 
104  double rect[] =
105  {
106  0.0, 0.0,
107  100.0, 0.0,
108  100.0, 100.0,
109  0.0, 100.0,
110  0.0, 0.0
111  };
112  SimplePath path (rect, sizeof(rect) / sizeof(double));
113 
115  // basic gradient functions
117  double x = 0;
118  double y = 0;
119 
120  // gradient_x
121  {
122  agg::gradient_x gradientFunction;
123  agg::trans_affine matrix;
124  matrix.translate(x, y);
125  drawGradient (gradientFunction,
126  rBase,
127  path,
128  matrix);
129  x += 100;
130  }
131 
132  // gradient_y
133  {
134  agg::gradient_y gradientFunction;
135  agg::trans_affine matrix;
136  matrix.translate(x, y);
137  drawGradient (gradientFunction,
138  rBase,
139  path,
140  matrix);
141  x += 100;
142  }
143 
144  // gradient_diamond
145  {
146  agg::gradient_diamond gradientFunction;
147  agg::trans_affine matrix;
148  matrix.translate(x, y);
149  drawGradient (gradientFunction,
150  rBase,
151  path,
152  matrix);
153  x += 100;
154  }
155 
156  // gradient_xy
157  {
158  agg::gradient_xy gradientFunction;
159  agg::trans_affine matrix;
160  matrix.translate(x, y);
161  drawGradient (gradientFunction,
162  rBase,
163  path,
164  matrix);
165  x += 100;
166  }
167 
168  // gradient_sqrt_xy
169  {
170  agg::gradient_sqrt_xy gradientFunction;
171  agg::trans_affine matrix;
172  matrix.translate(x, y);
173  drawGradient (gradientFunction,
174  rBase,
175  path,
176  matrix);
177  x += 100;
178  }
179 
180  // gradient_conic
181  {
182  agg::gradient_conic gradientFunction;
183  agg::trans_affine matrix;
184  matrix.translate(x, y);
185  drawGradient (gradientFunction,
186  rBase,
187  path,
188  matrix);
189  x += 100;
190  }
191 
192  // gradient_circle
193  {
194  agg::gradient_circle gradientFunction;
195  agg::trans_affine matrix;
196  matrix.translate(x, y);
197  drawGradient (gradientFunction,
198  rBase,
199  path,
200  matrix);
201  x += 100;
202  }
203 
204  // gradient_radial
205  {
206  agg::gradient_radial gradientFunction;
207  agg::trans_affine matrix;
208  matrix.translate(x, y);
209  drawGradient (gradientFunction,
210  rBase,
211  path,
212  matrix);
213  x += 100;
214  }
215 
216  // gradient_radial_d
217  {
218  agg::gradient_radial_d gradientFunction;
219  agg::trans_affine matrix;
220  matrix.translate(x, y);
221  drawGradient (gradientFunction,
222  rBase,
223  path,
224  matrix);
225  x += 100;
226  }
227 
228  // gradient_radial_focus
229  {
230  agg::gradient_radial_focus gradientFunction;
231  agg::trans_affine matrix;
232  matrix.translate(x, y);
233  drawGradient (gradientFunction,
234  rBase,
235  path,
236  matrix);
237  x += 100;
238  }
239 
241  // repeat adapter gradient functions
243  x = 0;
244  y = 100;
245 
246  // gradient_x
247  {
248  agg::gradient_x gradientFunction;
249  agg::gradient_repeat_adaptor<agg::gradient_x> gf2 (gradientFunction);
250  agg::trans_affine matrix;
251  matrix.translate(x, y);
252  drawGradient (gf2,
253  rBase,
254  path,
255  matrix);
256  x += 100;
257  }
258 
259  // gradient_y
260  {
261  agg::gradient_y gradientFunction;
262  agg::gradient_repeat_adaptor<agg::gradient_y> gf2 (gradientFunction);
263  agg::trans_affine matrix;
264  matrix.translate(x, y);
265  drawGradient (gf2,
266  rBase,
267  path,
268  matrix);
269  x += 100;
270  }
271 
272  // gradient_diamond
273  {
274  agg::gradient_diamond gradientFunction;
276  agg::trans_affine matrix;
277  matrix.translate(x, y);
278  drawGradient (gf2,
279  rBase,
280  path,
281  matrix);
282  x += 100;
283  }
284 
285  // gradient_xy
286  {
287  agg::gradient_xy gradientFunction;
288  agg::gradient_repeat_adaptor<agg::gradient_xy> gf2 (gradientFunction);
289  agg::trans_affine matrix;
290  matrix.translate(x, y);
291  drawGradient (gf2,
292  rBase,
293  path,
294  matrix);
295  x += 100;
296  }
297 
298  // gradient_sqrt_xy
299  {
300  agg::gradient_sqrt_xy gradientFunction;
302  agg::trans_affine matrix;
303  matrix.translate(x, y);
304  drawGradient (gf2,
305  rBase,
306  path,
307  matrix);
308  x += 100;
309  }
310 
311  // gradient_conic
312  {
313  agg::gradient_conic gradientFunction;
315  agg::trans_affine matrix;
316  matrix.translate(x, y);
317  drawGradient (gf2,
318  rBase,
319  path,
320  matrix);
321  x += 100;
322  }
323 
324  // gradient_circle
325  {
326  agg::gradient_circle gradientFunction;
328  agg::trans_affine matrix;
329  matrix.translate(x, y);
330  drawGradient (gf2,
331  rBase,
332  path,
333  matrix);
334  x += 100;
335  }
336 
337  // gradient_radial
338  {
339  agg::gradient_radial gradientFunction;
341  agg::trans_affine matrix;
342  matrix.translate(x, y);
343  drawGradient (gf2,
344  rBase,
345  path,
346  matrix);
347  x += 100;
348  }
349 
350  // gradient_radial_d
351  {
352  agg::gradient_radial_d gradientFunction;
354  agg::trans_affine matrix;
355  matrix.translate(x, y);
356  drawGradient (gf2,
357  rBase,
358  path,
359  matrix);
360  x += 100;
361  }
362 
363  // gradient_radial_focus
364  {
365  agg::gradient_radial_focus gradientFunction;
367  agg::trans_affine matrix;
368  matrix.translate(x, y);
369  drawGradient (gf2,
370  rBase,
371  path,
372  matrix);
373  x += 100;
374  }
375 
377  // reflective adapter gradient functions
379  x = 0;
380  y += 100;
381 
382  // gradient_x
383  {
384  agg::gradient_x gradientFunction;
385  agg::gradient_reflect_adaptor<agg::gradient_x> gf2 (gradientFunction);
386  agg::trans_affine matrix;
387  matrix.translate(x, y);
388  drawGradient (gf2,
389  rBase,
390  path,
391  matrix);
392  x += 100;
393  }
394 
395  // gradient_y
396  {
397  agg::gradient_y gradientFunction;
398  agg::gradient_reflect_adaptor<agg::gradient_y> gf2 (gradientFunction);
399  agg::trans_affine matrix;
400  matrix.translate(x, y);
401  drawGradient (gf2,
402  rBase,
403  path,
404  matrix);
405  x += 100;
406  }
407 
408  // gradient_diamond
409  {
410  agg::gradient_diamond gradientFunction;
412  agg::trans_affine matrix;
413  matrix.translate(x, y);
414  drawGradient (gf2,
415  rBase,
416  path,
417  matrix);
418  x += 100;
419  }
420 
421  // gradient_xy
422  {
423  agg::gradient_xy gradientFunction;
425  agg::trans_affine matrix;
426  matrix.translate(x, y);
427  drawGradient (gf2,
428  rBase,
429  path,
430  matrix);
431  x += 100;
432  }
433 
434  // gradient_sqrt_xy
435  {
436  agg::gradient_sqrt_xy gradientFunction;
438  agg::trans_affine matrix;
439  matrix.translate(x, y);
440  drawGradient (gf2,
441  rBase,
442  path,
443  matrix);
444  x += 100;
445  }
446 
447  // gradient_conic
448  {
449  agg::gradient_conic gradientFunction;
451  agg::trans_affine matrix;
452  matrix.translate(x, y);
453  drawGradient (gf2,
454  rBase,
455  path,
456  matrix);
457  x += 100;
458  }
459 
460  // gradient_circle
461  {
462  agg::gradient_circle gradientFunction;
464  agg::trans_affine matrix;
465  matrix.translate(x, y);
466  drawGradient (gf2,
467  rBase,
468  path,
469  matrix);
470  x += 100;
471  }
472 
473  // gradient_radial
474  {
475  agg::gradient_radial gradientFunction;
477  agg::trans_affine matrix;
478  matrix.translate(x, y);
479  drawGradient (gf2,
480  rBase,
481  path,
482  matrix);
483  x += 100;
484  }
485 
486  // gradient_radial_d
487  {
488  agg::gradient_radial_d gradientFunction;
490  agg::trans_affine matrix;
491  matrix.translate(x, y);
492  drawGradient (gf2,
493  rBase,
494  path,
495  matrix);
496  x += 100;
497  }
498 
499  // gradient_radial_focus
500  {
501  agg::gradient_radial_focus gradientFunction;
503  agg::trans_affine matrix;
504  matrix.translate(x, y);
505  drawGradient (gf2,
506  rBase,
507  path,
508  matrix);
509  x += 100;
510  }
511 
512  // now write the image out for visualization
513  char fileName[1000] = { 0 };
514  if (argc > 1)
515  {
516  sprintf (fileName, "%s/", argv[1]);
517  }
518  strcat(fileName, "tutorial_gradient_1.png");
519  writePng<RendererBaseType> (fileName, rBase);
520 
521  delete imageBuffer;
522  }
523  catch (TutorialException& ex)
524  {
525  printf ("%s\n", ex.getMessage());
526  return 1;
527  }
528  catch (...)
529  {
530  printf ("Unknown exception detected.\n");
531  return 1;
532  }
533 
534  return 0;
535 }