AGG (Anti-Grain Geometry) の agg::renderer_primitives を使って図形描画のシンプルなサンプルを書いてみた。


#include <stdio.h>
#include <string.h>
#include <agg_color_rgba.h>
#include <agg_rendering_buffer.h>
#include <agg_pixfmt_rgba.h>
#include <agg_renderer_base.h>
#include <agg_renderer_primitives.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\n255\n", width, height);
    int num = width * height;
    for(int i=0; i<num; i++){
      // RGBAのRGBだけ書き出す
      fwrite(buf, 1, 3, fd);
      buf+=4;
    }
    fclose(fd);
    return true;
  }
  return false;
}
 
// バイト配列情報閲覧用
void print_bytes(const unsigned char* buf, int width, int height){
  for(int y=0; y<height; y++){
    for(int x=0; x<width; x++){
      int i = (width * y + x) * 4;
      printf("%03d,%03d = %3d,%3d,%3d,%3d\n", x, y, buf[i], buf[i+1], buf[i+2], buf[i+3]);
    }
  }
}

int main(){
 
  int frame_width = 400;
  int frame_height = 300;
  int bytes_per_pixel = 4;
 
  // メモリ確保
  agg::int8u* buffer = new agg::int8u[frame_width * frame_height * bytes_per_pixel];
  memset(buffer, 255, frame_width * frame_height * bytes_per_pixel);
 
  // AGGの描画クラスを準備
  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_primitives<agg::renderer_base<agg::pixfmt_rgba32> > prim(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);
 
  // 描画処理
  prim.line_color(red);
  prim.fill_color(blue);
  prim.ellipse(100, 100, 50, 50);
  prim.solid_ellipse(150, 100, 50, 50);
  prim.outlined_ellipse(200, 100, 50, 50);
  prim.line_color(green);
  prim.fill_color(purple);
  prim.rectangle(100, 100, 150, 150);
  prim.solid_rectangle(150, 100, 200, 200);
  prim.outlined_rectangle(200, 100, 250, 250);
 
  // 出力
  print_bytes(buffer, frame_width, frame_height);
  write_ppm(buffer, frame_width, frame_height, "aggprimitives.ppm");
 
  delete [] buffer;
  return 0;
}

コンパイルして実行。


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

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

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

ちなみに、環境。

- Mac OS X Snow Leopard
- GCC 4.2.1
- AGG 2.5


$ uname -mrsv
Darwin 10.8.0 Darwin Kernel Version 10.8.0: Tue Jun  7 16:33:36 PDT 2011; root:xnu-1504.15.3~1/RELEASE_I386 i386
 
$ gcc --version
i686-apple-darwin10-gcc-4.2.1 (GCC) 4.2.1 (Apple Inc. build 5666) (dot 3)
Copyright (C) 2007 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 
$ ls -la /usr/local/include/ | grep agg
lrwxr-xr-x   1 hoge    admin   33 12 27 16:50 agg2 -> ../Cellar/libagg/2.5/include/agg2

Ref.
- Anti-Grain Geometry -
- Anti-Grain Geometry - Basic Renderers
- PNM (画像フォーマット) - Wikipedia
- ToyViewer for Mac OS X

tags: agg

Posted by NI-Lab. (@nilab)