← 返回文章

AGG手册示例像素渲染器之bland部分在BCB下的编译问题

这个例子是描画阳光的光谱。rgba 类包含有 4 个浮点数的颜色部分(包括alpha),这个类有一个静态函数 from wavelength ,以及相应的构造函数。rgba8 可以用 rgba 来构造(在 AGG 中这…

#AGG#BUG#光谱示例#C++
C++

这个例子是描画阳光的光谱。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); 把这个默认参数补上,问题就解决了。

下面贴上我的运行结果:

light