1//
2// AggPas 2.4 RM3 Demo application
3// Note: Press F1 key on run to see more info about this demo
4//
5// Paths: src;src\ctrl;src\svg;src\util;src\platform\win;expat-wrap
6//
7program
8 rasterizers ;
9
10{$DEFINE AGG_BGR24 }
11
12uses
13 SysUtils ,
14
15 agg_basics ,
16 agg_platform_support ,
17 agg_math ,
18
19 agg_ctrl ,
20 agg_slider_ctrl ,
21 agg_cbox_ctrl ,
22
23 agg_rasterizer_scanline_aa ,
24 agg_rasterizer_outline ,
25 agg_scanline ,
26 agg_scanline_p ,
27 agg_scanline_bin ,
28
29 agg_renderer_base ,
30 agg_renderer_scanline ,
31 agg_renderer_primitives ,
32 agg_render_scanlines ,
33
34 agg_path_storage ,
35 agg_gamma_functions
36
37{$I pixel_formats.inc }
38{$I agg_mode.inc }
39
40const
41 flip_y = true;
42
43type
44 the_application = object(platform_support )
45   m_x ,
46   m_y : array[0..2 ] of double;
47
48   m_dx ,
49   m_dy : double;
50
51   m_idx : int;
52
53   m_gamma ,
54   m_alpha : slider_ctrl;
55   m_test  : cbox_ctrl;
56
57   m_ras    : rasterizer_scanline_aa;
58   m_sl_p8  : scanline_p8;
59   m_sl_bin : scanline_bin;
60
61   constructor Construct(format_ : pix_format_e; flip_y_ : boolean );
62   destructor  Destruct;
63
64   procedure draw_anti_aliased;
65   procedure draw_aliased;
66
67   procedure on_draw; virtual;
68
69   procedure on_mouse_move(x ,y : int; flags : unsigned ); virtual;
70
71   procedure on_mouse_button_down(x ,y : int; flags : unsigned ); virtual;
72   procedure on_mouse_button_up  (x ,y : int; flags : unsigned ); virtual;
73
74   procedure on_key(x ,y : int; key ,flags : unsigned ); virtual;
75   procedure on_ctrl_change; virtual;
76
77  end;
78
79{ CONSTRUCT }
80constructor the_application.Construct;
81begin
82 inherited Construct(format_ ,flip_y_ );
83
84 m_ras.Construct;
85 m_sl_p8.Construct;
86 m_sl_bin.Construct;
87
88 m_idx:=-1;
89
90 m_x[0 ]:=100 + 120; m_y[0 ]:=60;
91 m_x[1 ]:=369 + 120; m_y[1 ]:=170;
92 m_x[2 ]:=143 + 120; m_y[2 ]:=310;
93
94 m_gamma.Construct(130 + 10 ,10 + 4 ,130 + 150 ,10 + 8 + 4 ,not flip_y );
95
96 add_ctrl(@m_gamma );
97
98 m_gamma.range_(0 ,1 );
99 m_gamma.value_(0.5 );
100 m_gamma.label_('Gamma=%1.2f' );
101 m_gamma.no_transform;
102
103 m_alpha.Construct(130 + 150 + 10 ,10 + 4 ,500 - 10 ,10 + 8 + 4 ,not flip_y );
104
105 add_ctrl(@m_alpha );
106
107 m_alpha.range_(0 ,1 );
108 m_alpha.value_(1 );
109 m_alpha.label_('Alpha=%1.2f' );
110 m_alpha.no_transform;
111
112 m_test.Construct(130 + 10.0 ,10.0 + 4.0 + 16.0 ,'Test Performance' ,not flip_y );
113
114 add_ctrl(@m_test );
115
116 m_test.no_transform;
117
118end;
119
120{ DESTRUCT }
121destructor the_application.Destruct;
122begin
123 inherited Destruct;
124
125 m_alpha.Destruct;
126 m_gamma.Destruct;
127 m_test.Destruct;
128
129 m_ras.Destruct;
130 m_sl_p8.Destruct;
131 m_sl_bin.Destruct;
132
133end;
134
135{ DRAW_ANTI_ALIASED }
136procedure the_application.draw_anti_aliased;
137var
138 pixf   : pixel_formats;
139 rb     : renderer_base;
140 ren_aa : renderer_scanline_aa_solid;
141
142 path : path_storage;
143 rgba : aggclr;
144
145 gamma : gamma_power;
146
147begin
148 pixfmt(pixf ,rbuf_window );
149
150 rb.Construct    (@pixf );
151 ren_aa.Construct(@rb );
152
153// Path & Color
154 path.Construct;
155
156 path.move_to(m_x[0 ] ,m_y[0 ] );
157 path.line_to(m_x[1 ] ,m_y[1 ] );
158 path.line_to(m_x[2 ] ,m_y[2 ] );
159 path.close_polygon;
160
161 rgba.ConstrDbl(0.7 ,0.5 ,0.1 ,m_alpha._value );
162 ren_aa.color_ (@rgba );
163
164// Draw
165 gamma.Construct(m_gamma._value * 2.0 );
166
167 m_ras.gamma   (@gamma );
168 m_ras.add_path(@path );
169
170 render_scanlines(@m_ras ,@m_sl_p8 ,@ren_aa );
171
172// Free
173 path.Destruct;
174
175end;
176
177{ DRAW_ALIASED }
178procedure the_application.draw_aliased;
179var
180 pixf    : pixel_formats;
181 rb      : renderer_base;
182 ren_bin : renderer_scanline_bin_solid;
183
184 path : path_storage;
185 rgba : aggclr;
186
187 gamma : gamma_threshold;
188
189 ren_pr   : renderer_primitives;
190 ras_line : rasterizer_outline;
191
192begin
193 pixfmt(pixf ,rbuf_window );
194
195 rb.Construct     (@pixf );
196 ren_bin.Construct(@rb );
197
198// Path & Color
199 path.Construct;
200
201 path.move_to(m_x[0 ] - 200 ,m_y[0 ] );
202 path.line_to(m_x[1 ] - 200 ,m_y[1 ] );
203 path.line_to(m_x[2 ] - 200 ,m_y[2 ] );
204 path.close_polygon;
205
206 rgba.ConstrDbl(0.1 ,0.5 ,0.7 ,m_alpha._value );
207 ren_bin.color_(@rgba );
208
209// Draw
210 gamma.Construct(m_gamma._value );
211
212 m_ras.gamma   (@gamma );
213 m_ras.add_path(@path );
214
215 render_scanlines(@m_ras ,@m_sl_bin ,@ren_bin );
216
217//-- Drawing an outline with subpixel accuracy (aliased)
218(* ren_pr.Construct  (@rb );
219 ras_line.Construct(@ren_pr );
220
221 rgba.ConstrDbl(0.0 ,0.0 ,0.0 );
222
223 ren_pr._line_color(@rgba );
224 ras_line.add_path (@path );(**)
225
226// Free
227 path.Destruct;
228
229end;
230
231{ ON_DRAW }
232procedure the_application.on_draw;
233var
234 pixf   : pixel_formats;
235 rb     : renderer_base;
236 ren_aa : renderer_scanline_aa_solid;
237
238 ras_aa : rasterizer_scanline_aa;
239
240 rgba : aggclr;
241
242begin
243// Initialize structures
244 pixfmt(pixf ,rbuf_window );
245
246 rb.Construct    (@pixf );
247 ren_aa.Construct(@rb );
248
249 ras_aa.Construct;
250
251// Setup colors & background
252 rgba.ConstrDbl(1 ,1 ,1 );
253
254 rb.clear(@rgba );
255
256// Draw
257 draw_anti_aliased;
258 draw_aliased;
259
260// Render controls
261 render_ctrl(@ras_aa ,@m_sl_p8 ,@ren_aa ,@m_gamma );
262 render_ctrl(@ras_aa ,@m_sl_p8 ,@ren_aa ,@m_alpha );
263 render_ctrl(@ras_aa ,@m_sl_p8 ,@ren_aa ,@m_test );
264
265// Free AGG resources
266 ras_aa.Destruct;
267
268end;
269
270{ ON_MOUSE_MOVE }
271procedure the_application.on_mouse_move;
272var
273 dx ,dy : double;
274
275begin
276 if flags and mouse_left <> 0 then
277  begin
278   if m_idx = 3 then
279    begin
280     dx:=x - m_dx;
281     dy:=y - m_dy;
282
283     m_x[1 ]:=m_x[1 ] - (m_x[0 ] - dx );
284     m_y[1 ]:=m_y[1 ] - (m_y[0 ] - dy );
285     m_x[2 ]:=m_x[2 ] - (m_x[0 ] - dx );
286     m_y[2 ]:=m_y[2 ] - (m_y[0 ] - dy );
287     m_x[0 ]:= dx;
288     m_y[0 ]:= dy;
289
290     force_redraw;
291     exit;
292
293    end;
294
295   if m_idx >= 0 then
296    begin
297     m_x[m_idx ]:=x - m_dx;
298     m_y[m_idx ]:=y - m_dy;
299
300     force_redraw;
301
302    end;
303
304  end;
305
306end;
307
308{ ON_MOUSE_BUTTON_DOWN }
309procedure the_application.on_mouse_button_down;
310var
311 i : unsigned;
312
313begin
314 if flags and mouse_left <> 0 then
315  begin
316   i:=0;
317
318   while i < 3 do
319    begin
320     if (Sqrt((x - m_x[i ] ) * (x - m_x[i ] ) + (y - m_y[i ] ) * (y - m_y[i ] ) ) < 20 ) or
321        (Sqrt((x - m_x[i ] + 200 ) * (x - m_x[i ] + 200 ) + (y - m_y[i ] ) * (y - m_y[i ] ) ) < 20 ) then
322      begin
323       m_dx :=x - m_x[i ];
324       m_dy :=y - m_y[i ];
325       m_idx:=i;
326
327       break;
328
329      end;
330
331     inc(i );
332
333    end;
334
335   if i = 3 then
336    if point_in_triangle(m_x[0 ] ,m_y[0 ] ,m_x[1 ] ,m_y[1 ] ,m_x[2 ] ,m_y[2 ] ,x ,y ) or
337       point_in_triangle(m_x[0 ] - 200 ,m_y[0 ] ,m_x[1 ] - 200 ,m_y[1 ] ,m_x[2 ] - 200 ,m_y[2 ] ,x ,y ) then
338     begin
339      m_dx :=x - m_x[0 ];
340      m_dy :=y - m_y[0 ];
341      m_idx:= 3;
342
343     end;
344
345  end;
346
347end;
348
349{ ON_MOUSE_BUTTON_UP }
350procedure the_application.on_mouse_button_up;
351begin
352 m_idx:=-1;
353
354end;
355
356{ ON_KEY }
357procedure the_application.on_key;
358var
359 dx ,dy : double;
360
361begin
362 dx:=0;
363 dy:=0;
364
365 case key of
366  key_left  : dx:=-0.1;
367  key_right : dx:= 0.1;
368  key_up    : dy:= 0.1;
369  key_down  : dy:=-0.1;
370
371 end;
372
373 m_x[0 ]:=m_x[0 ] + dx;
374 m_y[0 ]:=m_y[0 ] + dy;
375 m_x[1 ]:=m_x[1 ] + dx;
376 m_y[1 ]:=m_y[1 ] + dy;
377
378 force_redraw;
379
380 if key = key_f1 then
381  message_(
382   'It''s a very simple example that was written to compare the performance between '#13 +
383   'Anti-Aliased and regular polygon filling. It appears that the most expensive '#13 +
384   'operation is rendering of horizontal scanlines. So that, we can use the very '#13 +
385   'same rasterization algorithm to draw regular, aliased polygons. Of course, it''s '#13 +
386   'possible to write a special version of the rasterizer that will work faster, but '#13 +
387   'won''t calculate the pixel coverage values. But on the other hand, the existing '#13 +
388   'version of the rasterizer_scanline_aa allows you to change gamma, and to "dilate" '#13 +
389   'or "shrink" the polygons in range of � 1 pixel.'#13#13 +
390   'How to play with:'#13#13 +
391   'As usual, you can drag the triangles as well as the vertices of them. '#13 +
392   'Compare the performance with different shapes and opacity.' +
393   #13#13'Note: F2 key saves current "screenshot" file in this demo''s directory.  ' );
394
395end;
396
397{ ON_CTRL_CHANGE }
398procedure the_application.on_ctrl_change;
399var
400 i : int;
401
402 t1 ,t2 : double;
403
404 buf : array[0..99 ] of char;
405
406begin
407 if m_test._status then
408  begin
409   on_draw;
410   update_window;
411   m_test.status_(false );
412
413   start_timer;
414
415   for i:=0 to 999 do
416    draw_aliased;
417
418   t1:=elapsed_time;
419
420   start_timer;
421
422   for i:=0 to 999 do
423    draw_anti_aliased;
424
425   t2:=elapsed_time;
426
427   update_window;
428
429   sprintf (@buf[0 ] ,'Time Aliased=%.2fms '#0 ,t1 );
430   sprintf (@buf[StrLen(@buf[0 ] ) ] ,'Time Anti-Aliased=%.2fms'#0 ,t2 );
431   message_(@buf[0 ] );
432
433  end;
434
435end;
436
437VAR
438 app : the_application;
439
440BEGIN
441 app.Construct(pix_format ,flip_y );
442 app.caption_ ('AGG Example. Line Join (F1-Help)' );
443
444 if app.init(500 ,330 ,window_resize ) then
445  app.run;
446
447 app.Destruct;
448
449END.
450