irrlicht + AntiGrain vector graphics

A forum to store posts deemed exceptionally wise and useful

irrlicht + AntiGrain vector graphics

Postby chronologicaldot » Sun Dec 03, 2017 9:21 pm

I did a bit of digging to figure out how Anti-Grain Geometry (AGG) works and discovered it is very easy to integrate with Irrlicht. There is also some example code with loading system fonts, so one day I hope to use AGG to add font-loading capabilities to Irrlicht via IGUISkin.
Anyways, to show you how to use it, I wrote a tutorial. ... -irrlicht/

For those of you who want to cut to the chase (and read the example code because it gets chopped off on Wordpress), here is the example:
cpp Code: Select all
#include <agg_basics.h>
#include <agg_rendering_buffer.h>
#include <agg_rasterizer_scanline_aa.h>
#include <agg_scanline_p.h>
#include <agg_renderer_scanline.h>
// Color
//#include <agg_pxlfmt_rgba.h>
// For unclosed curve
#include <agg_conv_unclose_polygon.h>
// Specifically for the curve
#include <agg_conv_stroke.h>
#include <agg_conv_bspline.h>
// To save time picking a color
#define AGG_ARGB32
#include <examples/pixel_formats.h>
#include <irrlicht.h>
#include <math.h>
#define PI 3.1415926539
inline double
degToRad(double p) {
    return (p * PI) / 180.;
class SineWavePoly {
    agg::point_d position;
    unsigned increment;
    double amplitude;
    double phase;
    unsigned startX;
    unsigned endX;
        : position(0,0)
        , increment(0)
        , amplitude(10)
        , phase(0)
        , startX(0)
        , endX(0)
    setPosition(double nx, double ny) {
        position.x = nx;
        position.y = ny;
        return *this;
    setAmplitude(double a) {
        amplitude = a;
        return *this;
    setPhase(double p) {
        phase = degToRad(p);
        return *this;
    setStartX(unsigned x) {
        startX = x;
        return *this;
    setEndX(unsigned x) {
        endX = x;
        return *this;
    void rewind(unsigned) {
        increment = 0;
    unsigned vertex(double* x, double* y) {
        *x = double(startX + increment);
        double tx = degToRad(*x);
        *x = *x + position.x;
        *y = amplitude * sin(tx + phase) + position.y;
        if ( increment > endX )
            return agg::path_cmd_stop;
        if ( increment == endX ) {
            return agg::path_cmd_end_poly;
        if ( increment == 0 ) {
            return agg::path_cmd_move_to;
        return agg::path_cmd_line_to;
bool renderPolygon(irr::video::IImage* pImage, double resolution) {
    if (!pImage)
        return false;
    // Create AGG stuff, setting the Irrlicht image->getData() as the buffer
    SineWavePoly sinePoly;
    // Yes, it's technically u32 data, but Anti-Grain treats it as pixels composed of 1 byte/8 bit colors.
    irr::u8* imgDataPtr = (irr::u8*) pImage->getData();
    irr::core::dimension2du imgSize = pImage->getDimension();
    agg::rendering_buffer renderingBuffer;
    renderingBuffer.attach(imgDataPtr, imgSize.Width, imgSize.Height, pImage->getPitch());
    // Alternatively:
    //agg::rendering_buffer renderingBuffer( ... same args as passed to .attach() );
    agg::pixfmt_bgra32 pixelFormat(renderingBuffer);
    agg::renderer_base<agg::pixfmt_bgra32> rendererBase(pixelFormat);
    agg::scanline_p8 scanLine;
    agg::rasterizer_scanline_aa<> rasterizerAA;
    // function-scope-limited typedef
    typedef agg::conv_bspline conv_bspline_type;
    // Normal version ****
    // Unfilled, thick lines with controllable ends ****
    agg::conv_stroke convStrokeSinePoly(sinePoly);
    agg::render_scanlines_aa_solid(rasterizerAA, scanLine, rendererBase, agg::rgba(0.0, 0.7, 0.9));
    // Bezier version ****
    //conv_bspline_type sineBspline(sinePoly);
    //sineBspline.interpolation_step(1.0 / resolution);
    //agg::conv_stroke sineStroke(sineBspline);
    //agg::render_scanlines_aa_solid(rasterizerAA, scanLine, rendererBase, agg::rgba(1,1,1));
    return true;
int main() {
    irr::core::dimension2du screenSize(500,500);
    irr::video::SColor white(0xffffffff);
    irr::core::vector2di zeroVector(0);
    irr::IrrlichtDevice* device = irr::createDevice(irr::video::EDT_BURNINGSVIDEO, screenSize);
    if ( !device ) return 1;
    irr::video::IVideoDriver* videoDriver = device->getVideoDriver();
    videoDriver->setTextureCreationFlag(irr::video::ETCF_CREATE_MIP_MAPS, false);
    videoDriver->setTextureCreationFlag(irr::video::ETCF_ALLOW_NON_POWER_2, true);
    irr::core::recti srcRect(0,0,(irr::s32)screenSize.Width,(irr::s32)screenSize.Height);
    irr::video::IImage* img = videoDriver->createImage(irr::video::ECF_A8R8G8B8, screenSize);
    if (! renderPolygon(img, 20.0) )
        return 1;
    irr::video::ITexture* tex = videoDriver->addTexture(irr::io::path("image name"), img);
    while ( device->run() ) {
        videoDriver->draw2DImage(tex, zeroVector, srcRect, 0, white, true);
    return 0;
Last edited by chronologicaldot on Fri Dec 08, 2017 8:24 pm, edited 2 times in total.
User avatar
Competition winner
Posts: 559
Joined: Mon Sep 10, 2012 8:51 am

Re: irrlicht + AntiGrain vector graphics

Postby Mel » Mon Dec 04, 2017 11:53 am

Kewl! vector graphics should be a must for every graphics API! keep the good job :)
"There is nothing truly useless, it always serves as a bad example". Arthur A. Schmitt
User avatar
Competition winner
Posts: 2264
Joined: Wed May 07, 2008 11:40 am
Location: Granada, Spain

Re: irrlicht + AntiGrain vector graphics

Postby CuteAlien » Mon Dec 04, 2017 1:09 pm

Interesting, I didn't know anti-grain. You could add some links in your blog-post (like to anti-grain and Irrlicht).
IRC: #irrlicht on
Code snippets, patches&stuff:
Free racer created with Irrlicht:
User avatar
Posts: 8514
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany

Re: irrlicht + AntiGrain vector graphics

Postby tecan » Wed Dec 06, 2017 2:28 pm

why was the example source includes not present in the code example ?
Live long and phosphor!
-- Status 85%
User avatar
Posts: 346
Joined: Fri Jun 06, 2008 12:50 pm
Location: Edmonton, Alberta, Canada

Re: irrlicht + AntiGrain vector graphics

Postby chronologicaldot » Fri Dec 08, 2017 3:40 am

@tecan - Oops! It didn't copy correctly for some reason. Probably because Wordpress thought they were HTML tags. Let me add them again for ya.

@CuteAlien - Thanks for the suggestion. I usually do add those links, so that was oversight on my part. Thanks for catching that.
User avatar
Competition winner
Posts: 559
Joined: Mon Sep 10, 2012 8:51 am

Re: irrlicht + AntiGrain vector graphics

Postby chronologicaldot » Fri Dec 08, 2017 3:43 am

@tecan - I updated my first post for you. Now I just need to update the Wordpress page.
User avatar
Competition winner
Posts: 559
Joined: Mon Sep 10, 2012 8:51 am

Re: irrlicht + AntiGrain vector graphics

Postby chronologicaldot » Fri Dec 08, 2017 8:29 pm

Update: Sorry. Use agg::pixfmt_bgra32, not agg::pixfmt_argb32. I forgot the fact that Anti-Grain accesses colors by index, not by bit-shift, means that you have to pick the reverse pattern as the largest bit, which I believe has to do with the endianness of my machine. I seem to recall having little endian.
User avatar
Competition winner
Posts: 559
Joined: Mon Sep 10, 2012 8:51 am

Return to FAQs, Tutorials, Howtos, and external tool lists

Who is online

Users browsing this forum: No registered users and 1 guest