svg (partial support) via AGG

Post those lines of code you feel like sharing or find what you require for your project here; or simply use them as tutorials.
Post Reply
_maxim_
Posts: 54
Joined: Thu May 27, 2010 11:05 am
Location: Russia
Contact:

svg (partial support) via AGG

Post by _maxim_ »

Code: Select all

#include "agg_scanline_p.h"
#include "agg_basics.h"
#include "agg_rendering_buffer.h"
#include "agg_rasterizer_scanline_aa.h"
#include "agg_renderer_scanline.h"
#include "agg_pixfmt_rgba.h"
#include "agg_svg_parser.h"

using namespace agg;
using namespace svg;

typedef row_accessor<irr::u32> rendering_buffer_u32;
typedef pixfmt_alpha_blend_rgba<blender_bgra32, rendering_buffer_u32, pixel32_type> agg_pixel_type;

IRRLICHT_C_API agg::svg::path_renderer* agg_svg_path(char* file_name = "tiger.svg")
{
	agg::svg::path_renderer* m_path = new path_renderer();
	agg::svg::parser p(*m_path);
	p.parse(file_name);
	return m_path;
}

IRRLICHT_C_API ITexture* agg_svg_ITexture(agg::svg::path_renderer* m_path, IVideoDriver* driver, fschar_t* texture_name = "", double scale_value = 1.0, double rotate_value = 0.0, double expand_value = 0.0, video::ECOLOR_FORMAT color_format = ECF_A8R8G8B8, u32 alpha_value = 0, int stride_value = 1)
{
	double m_min_x = 0.0;
	double m_min_y = 0.0;
	double m_max_x = 0.0;
	double m_max_y = 0.0;
	//m_path->arrange_orientations();
	m_path->bounding_rect(&m_min_x, &m_min_y, &m_max_x, &m_max_y);
	m_max_x *= scale_value;
	m_max_y *= scale_value;
	const dimension2d<u32>& image_size = dimension2d<u32>((irr::u32)m_max_x, (irr::u32)m_max_y);
	IImage* image = driver->createImage(color_format, image_size);
	rendering_buffer_u32 rbuf((irr::u32*)image->lock(), image_size.Width, image_size.Height, image_size.Width*stride_value);
	//row_accessor<agg::int8u> rbuf((irr::u32*)image->lock(), image_size.Width, image_size.Height, image_size.Width*stride_value);
	agg_pixel_type pixf(rbuf);
	agg::renderer_base<agg_pixel_type> renb(pixf);
	agg::renderer_scanline_aa_solid<agg::renderer_base<agg_pixel_type>> ren(renb);
	renb.clear(agg::rgba8(255, 255, 255, alpha_value));
	agg::rasterizer_scanline_aa<> ras;
	agg::scanline_p8 sl;
	agg::trans_affine mtx;
	mtx *= agg::trans_affine_scaling(scale_value);
	mtx *= agg::trans_affine_rotation(agg::deg2rad(rotate_value));
	agg::render_scanlines(ras, sl, ren);
	m_path->expand(expand_value);
	m_path->render(ras, sl, ren, mtx, renb.clip_box(), 1.0);
	image->unlock();
	ITexture* texture = driver->addTexture(texture_name, image);
	image->drop();
	if (image)
		delete image;
	return texture;
}
for usage one call agg_svg_path(file_name), after this can many calls agg_svg_ITexture(...) for scale, rotate and etc. See "svg_viewer.py" for example from http://pir.sourceforge.net
hybrid
Admin
Posts: 14143
Joined: Wed Apr 19, 2006 9:20 pm
Location: Oldenburg(Oldb), Germany
Contact:

Post by hybrid »

To reduce google load, here's the link to agg http://antigrain.com/
Sounds nice, after all. And integration seems pretty easy.
_maxim_
Posts: 54
Joined: Thu May 27, 2010 11:05 am
Location: Russia
Contact:

Post by _maxim_ »

Thanks and sorry for my "memory leak".

I must add few instructions:

AGG svg parser depends from http://libexpat.org
and AGG image optional depends from zlib and libpng respectively.

For compile project or makefile require add next cpp files: agg_curves.cpp, agg_trans_affine.cpp, agg_vcgen_contour.cpp, agg_vcgen_stroke.cpp

If project with svg parser also include: agg_svg_parser.cpp, agg_svg_path_renderer.cpp, agg_svg_path_tokenizer.cpp

Next function do direct access to vector drawing functional and not require svg parser

Code: Select all

ITexture* test_vectors(IVideoDriver* driver, video::ECOLOR_FORMAT image_format = ECF_R8G8B8, const dimension2d<u32>& image_size = dimension2d<u32>(640, 480), char* texture_name = "texture_01", u32 alpha_value = 0)
{
	IImage* image = driver->createImage(image_format, image_size);

	agg::rendering_buffer rbuf;
	rbuf.attach((unsigned char*)image->lock(), image_size.Width, image_size.Height, image_size.Width*4);

	// Pixel format and basic primitives renderer
	agg::pixfmt_bgra32 pixf(rbuf);
	agg::renderer_base<agg::pixfmt_bgra32> renb(pixf);

	renb.clear(agg::rgba8(255, 255, 255, alpha_value));

	// Scanline renderer for solid filling.
	agg::renderer_scanline_aa_solid<agg::renderer_base<agg::pixfmt_bgra32> > ren(renb);

	// Rasterizer & scanline
	agg::rasterizer_scanline_aa<> ras;
	agg::scanline_p8 sl;

	// Polygon (triangle)
	ras.move_to_d(20.7, 34.15);
	ras.line_to_d(398.23, 123.43);
	ras.line_to_d(165.45, 401.87);

	// Setting the attrribute (color) & Rendering
	ren.color(agg::rgba8(80, 90, 60));
	agg::render_scanlines(ras, sl, ren);

	image->unlock();
	return driver->addTexture(texture_name, image);
}
_maxim_
Posts: 54
Joined: Thu May 27, 2010 11:05 am
Location: Russia
Contact:

Image loader

Post by _maxim_ »

Code: Select all

class agg_svg_loader : public irr::video::IImageLoader
{
public:
	agg_svg_loader(IVideoDriver* driver)
	{
		video_driver = driver;
	}
	~agg_svg_loader()
	{
		video_driver = 0;
	}
	virtual bool isALoadableFileExtension(const io::path& filename) const
	{
		return core::hasFileExtension ( filename, "svg" );
	}
	virtual bool isALoadableFileFormat(irr::io::IReadFile* file) const
	{
		return (false);
	}
	virtual irr::video::IImage* loadImage(irr::io::IReadFile* file) const
	{
		agg::svg::path_renderer m_path;
		agg::svg::parser p(m_path);
		p.parse(file->getFileName().c_str());
		double m_min_x = 0.0;
		double m_min_y = 0.0;
		double m_max_x = 0.0;
		double m_max_y = 0.0;
		m_path.bounding_rect(&m_min_x, &m_min_y, &m_max_x, &m_max_y);
		const dimension2d<u32>& image_size = dimension2d<u32>((irr::u32)m_max_x, (irr::u32)m_max_y);
		IImage* image = video_driver->createImage(ECF_A8R8G8B8, image_size);
		typedef row_accessor<irr::u32> rendering_buffer_u32;
		rendering_buffer_u32 rbuf((irr::u32*)image->lock(), image_size.Width, image_size.Height, image_size.Width);
		agg_pixel_type pixf(rbuf);
		agg::renderer_base<agg_pixel_type> renb(pixf);
		agg::renderer_scanline_aa_solid<agg::renderer_base<agg_pixel_type>> ren(renb);
		renb.clear(agg::rgba8(255, 255, 255, 0));
		agg::rasterizer_scanline_aa<> ras;
		agg::scanline_p8 sl;
		agg::trans_affine mtx;
		agg::render_scanlines(ras, sl, ren);
		m_path.render(ras, sl, ren, mtx, renb.clip_box(), 1.0);
		image->unlock();
		return image;
	}
	protected:
		IVideoDriver* video_driver;
};

video_driver->addExternalImageLoader(new agg_svg_loader(video_driver));
ITexture* tex = video_driver->getTexture("test.svg");
_maxim_
Posts: 54
Joined: Thu May 27, 2010 11:05 am
Location: Russia
Contact:

experimental svg support based on Irrlicht XML

Post by _maxim_ »

experimental SVG parser based on Irrlicht XML

AGG backend
http://code.google.com/p/pyirrlicht/sou ... svn10&r=10

Cairo backend
http://code.google.com/p/pyirrlicht/sou ... svn10&r=10
REDDemon
Developer
Posts: 1044
Joined: Tue Aug 31, 2010 8:06 pm
Location: Genova (Italy)

Re: svg (partial support) via AGG

Post by REDDemon »

What about loading SWG directly as vertices/lines? textures use much more memory.
Junior Irrlicht Developer.
Real value in social networks is not about "increasing" number of followers, but about getting in touch with Amazing people.
- by Me
_maxim_
Posts: 54
Joined: Thu May 27, 2010 11:05 am
Location: Russia
Contact:

Re: svg (partial support) via AGG

Post by _maxim_ »

interesting, but required more skils than I have.
if I understand you, this topic was about http://irrlicht.sourceforge.net/forum/v ... hp?t=40234
if you have any ideas, I can trying
Post Reply