ポリゴンに関しては 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::render_scanlines を使った図形描画のシンプルなサンプル で出力された画像を単純に2倍にしてみた画像。
agg::trans_affine と agg::conv_transform を使うと綺麗に拡大されることがわかる。
tags: agg
Posted by NI-Lab. (@nilab)