这个例子是描画阳光的光谱。rgba 类包含有 4 个浮点数的颜色部分(包括alpha),这个类有一个静态函数 from_wavelength ,以及相应的构造函数。rgba8 可以用 rgba 来构造(在 AGG 中这是一个常见的策略,也就是任何的颜色类型都可以用 rgba 来构造)。
#include <stdio.h>
#include <string.h>
#include “agg_pixfmt_rgb24.h”
enum
{
frame_width = 320,
frame_height = 200
};
// Writing the buffer to a .PPM file, assuming it has
// RGB-structure, one byte per color component
//————————————————–
bool write_ppm(const unsigned char buf,
unsigned width,
unsigned height,
const char file_name)
{
FILE fd = fopen(file_name, “wb”);
if(fd)
{
fprintf(fd, “P6 %d %d 255 “, width, height);
fwrite(buf, 1, width height * 3, fd);
fclose(fd);
return true;
}
return false;
}
int main()
{
//——————–
// Allocate the buffer.
// Clear the buffer, for now “manually”
// Create the rendering buffer object
// Create the Pixel Format renderer
// Create one line (span) of type rgba8.
// Fill the buffer using blend_color_span
// Write the buffer to agg_test.ppm
// Free memory
unsigned char buffer = new unsigned char[frame_width frame_height 3];
memset(buffer, 255, frame_width frame_height 3);
agg::rendering_buffer rbuf(buffer,
frame_width,
frame_height,
frame_width 3);
agg::pixfmt_rgb24 pixf(rbuf);
agg::rgba8 span[frame_width];
unsigned i;
for(i = 0; i < frame_width; ++i)
{
agg::rgba c(380.0 + 400.0 * i / frame_width, 0.8);
span[i] = agg::rgba8(c);
}
for(i = 0; i < frame_height; ++i)
{
pixf.blend_color_hspan(0, i, frame_width, span, 0); // 这里编译无法通过 需要改为 pixf.blend_color_hspan(0,i,frame_width,span,0,255);
}
write_ppm(buffer, frame_width, frame_height, “agg_test.ppm”);
delete [] buffer;
return 0;
}
看注释部分:
这里会发生两个问题
1.手册使用为2.4版本的AGG,在2.5中,增加了Cover参数,所以会发生缺少参数提示:
[BCC32 Error] Unit1.cpp(152): E2193 Too few parameters in call to ‘agg::pixfmt_rgb24::blend_color_hspan(int,int,unsigned int,const agg::rgba8 ,const unsigned char ,unsigned char)’
2.这个示例没有使用Covers,所以Covers参数设0,最后新增的Cover需要设为大于0的值,否则还是会看不到内容。设为255,就能看到示例的效果。
但将该代码调整为
pixf.blend_color_hspan(0, i, frame_width, span , 0 , 255);
仍然出现了如下错误
[BCC32 Fatal Error] agg_pixfmt_rgb.h(235): F1004 Internal compiler error at 0xaa3dd09 with base 0xa9d0000 ,
提示错误定位到了”agg_pixfmt_rgb.h”,在第235行。class pixfmt_alpha_blend_rgb中的
AGG_INLINE void copy_or_blend_pix(value_type* p, const color_type& c){
{
if (c.a)
{
if(c.a == base_mask)
{
p[order_type::R] = c.r;
p[order_type::G] = c.g;
p[order_type::B] = c.b;
}
else
{
m_blender.blend_pix(p, c.r, c.g, c.b, c.a); // 需要修改成 m_blender.blend_pix(p, c.r, c.g, c.b, c.a, 0);
}
}
}
m_blender在这个示例中原型是agg::pixfmt_rgb24,他的定义是
typedef pixfmt_alpha_blend_rgb<blender_rgb<rgba8, order_rgb>, rendering_buffer> pixfmt_rgb24; //—-pixfmt_rgb24
所以,我们查看blend_rgb这个类
static AGG_INLINE void blend_pix(value_type p,
unsigned cr, unsigned cg, unsigned cb,
unsigned alpha,
unsigned cover=0)
{
p[Order::R] += (value_type)(((cr - p[Order::R]) alpha) >> base_shift);
p[Order::G] += (value_type)(((cg - p[Order::G]) alpha) >> base_shift);
p[Order::B] += (value_type)(((cb - p[Order::B]) alpha) >> base_shift);
}
发现没有,这里cover这个参数是使用了default参数0,由于是模板调用,BCB2010的编译器在编译时发生了F1004错误,其实是编译器的一个BUG。了解了这个,只需要在头文件中把 m_blender.blend_pix(p, c.r, c.g, c.b, c.a); 修改成 m_blender.blend_pix(p, c.r, c.g, c.b, c.a, 0); 把这个默认参数补上,问题就解决了。
下面贴上我的运行结果: