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