ポリゴンに関しては agg::path_storage がターゲット。

今回、ポリラインに関しては線の太さも拡大したいので(図形の座標としては単純拡大だけどピクセルとしてはもうちょっと綺麗な感じになる)、 agg::conv_stroke<agg::path_storage> がターゲットになる。

[ヅ] agg::render_scanlines を使った図形描画のシンプルなサンプル をベースに、 agg::trans_affine と agg::conv_transform で2倍にスケーリングした図形を描画してみる。

ソースコード。


#include <stdio.h>
#include <string.h>
#include <agg_color_rgba.h>
#include <agg_rendering_buffer.h>
#include <agg_pixfmt_rgb.h>
#include <agg_pixfmt_rgba.h>
#include <agg_renderer_base.h>
#include <agg_renderer_scanline.h>
#include <agg_rasterizer_scanline_aa.h>
#include <agg_scanline_p.h>
#include <agg_path_storage.h>
#include <agg_conv_stroke.h>
 
bool write_ppm(const unsigned char* buf, int width, int height, const char* file_name){
  FILE* fd = fopen(file_name, "wb");
  if(fd){
    fprintf(fd, "P6 %d %d\n", width, height);
    fprintf(fd, "255\n");
    int num = width * height;
    for(int i=0; i<num; i++){
      fwrite(buf, 1, 3, fd);
      buf+=4;
    }
    fclose(fd);
    return true;
  }
  return false;
}
 
int main(){
 
  double scale_x = 2.0;	
  double scale_y = 2.0;	
  int frame_width  = 400 * scale_x;
  int frame_height = 300 * scale_y;
  int bytes_per_pixel = 4;
 
  // scaling
  agg::trans_affine mtx;
  mtx *= agg::trans_affine_scaling(scale_x, scale_y);
 
  agg::int8u* buffer = new agg::int8u[frame_width * frame_height * bytes_per_pixel];
  memset(buffer, 255, frame_width * frame_height * bytes_per_pixel);
 
  agg::rendering_buffer rbuf(buffer, frame_width, frame_height, frame_width * bytes_per_pixel);
  agg::pixfmt_rgba32 pixf(rbuf);
  agg::renderer_base<agg::pixfmt_rgba32> rbase(pixf);
  agg::renderer_scanline_aa_solid<agg::renderer_base<agg::pixfmt_rgba32> > rs(rbase);
 
  rbase.clear(agg::rgba8(255, 255, 255));
  agg::rgba8 red(255, 0, 0, 255);
  agg::rgba8 green(0, 255, 0, 255);
  agg::rgba8 blue(0, 0, 255, 100);
  agg::rgba8 purple(255, 0, 255, 100);
 
  // fill polygon
  {
    agg::path_storage path;
    path.move_to(200,  50);
    path.line_to(100, 200);
    path.line_to(100, 250);
    path.line_to(150, 200);
    path.close_polygon();
    agg::rasterizer_scanline_aa<> ras;
    agg::scanline_p8 sl;
    // affine transform
    agg::conv_transform<agg::path_storage, agg::trans_affine> trans(path, mtx);
    ras.add_path(trans);
    rs.color(agg::rgba8(0,255,0,100));
    agg::render_scanlines(ras, sl, rs);
  }
 
  // draw polygon
  {
    agg::path_storage path;
    path.move_to(150,  50);
    path.line_to(150, 200);
    path.line_to(300, 150);
    path.close_polygon();
    agg::conv_stroke<agg::path_storage> stroke(path);
    stroke.width(5.0);
    stroke.line_cap(agg::butt_cap);
    stroke.line_join(agg::miter_join);
    stroke.inner_join(agg::inner_miter);
    stroke.miter_limit(4.0);
    agg::rasterizer_scanline_aa<> ras;
    agg::scanline_p8 sl;
    // affine transform
    agg::conv_transform<agg::conv_stroke<agg::path_storage>, agg::trans_affine> trans(stroke, mtx);
    ras.add_path(trans);
    rs.color(agg::rgba8(0,0,255,100));
    agg::render_scanlines(ras, sl, rs);
  }
 
  // draw polyline
  {
    agg::path_storage path;
    path.move_to(100, 100);
    path.line_to(200, 100);
    path.line_to(200, 200);
    agg::conv_stroke<agg::path_storage> stroke(path);
    stroke.width(10.0);
    stroke.line_cap(agg::round_cap);
    stroke.line_join(agg::round_join);
    stroke.inner_join(agg::inner_round);
    agg::rasterizer_scanline_aa<> ras;
    agg::scanline_p8 sl;
    // affine transform
    agg::conv_transform<agg::conv_stroke<agg::path_storage>, agg::trans_affine> trans(stroke, mtx);
    ras.add_path(trans);
    rs.color(agg::rgba8(255,0,0,100));
    agg::render_scanlines(ras, sl, rs);
  }
 
  write_ppm(buffer, frame_width, frame_height, "agg_render_scanlines.ppm");
 
  delete [] buffer;
  return 0;
}

コンパイルと実行。


$ g++ -I/usr/local/include/agg2 -L/usr/local/lib -lagg ./aggsample.cpp 
$ ./a.out 

出力された ppm 画像を ToyViewer for Mac OS X という画像ビューアで表示したところ。

agg::trans_affine と agg::conv_transform を使って図形を拡大して描画してみるサンプル

[ヅ] agg::render_scanlines を使った図形描画のシンプルなサンプル で出力された画像を単純に2倍にしてみた画像。

Anti-Grain Geometry (libagg): agg::render_scanlines

agg::trans_affine と agg::conv_transform を使うと綺麗に拡大されることがわかる。

tags: agg

Posted by NI-Lab. (@nilab)