Win7 VS2015及MinGW环境编译矢量库agg-2.5和cairo-1.14.6
书接上文,昨天装了MinGW,主要原因之一是要用到MSYS,所以顺手把FFMPEG又编译了一遍。
回到主题,其实我是想编译矢量库,因为最近要学习一些计算几何算法,所以找个方便的2D画图库就很重要。
说白了其实是懒得用OpenGL写画几何体代码,画线,AA什么的。
不管怎么说,介绍看的是这篇文章。
http://www.cnblogs.com/yanhuiw/p/3885144.html
提到了3个矢量库,因为墙的原因,google的Skia死活弄不下来,所以只写前两个。
首先是AGG,http://www.antigrain.com/
第三方依懒库只有freetype,而freetype自带sln工程,所以编译没有问题,我直接打开的2010工程
freetype2\builds\windows\vc2010
然后新建一个Win32 Console Static library空工程,把AGG源码手动添加进工程,注意平台相关,别把没用的也加进去
并把相关目录加到include目录中,再加上freetype2的include,library,
编译就行了
相关目录
font_freetype
font_win32_tt
gpc
src
src\ctrl
src\platform\win32
========================================
然后新建一个Win32 Project,也就是窗口程序,实际上我建的Win32 Console空工程,然后在工程设置又改成的窗口,怎么弄都行。
配置上AGG的include,library目录
然后使用下面这个测试hello world,原文在哪忘了,只是测试下。
#include "agg_basics.h"
#include "agg_rendering_buffer.h"
#include "agg_rasterizer_scanline_aa.h"
#include "agg_scanline_u.h"
#include "agg_renderer_scanline.h"
#include "agg_pixfmt_rgb.h"
#include "platform/agg_platform_support.h"
#include "agg_ellipse.h"
#include "agg_conv_contour.h"
#include "agg_conv_stroke.h"
#include "agg_conv_marker.h"
#include "agg_arrowhead.h"
#include "agg_path_storage.h"
#include "agg_vcgen_markers_term.h"
#include <agg_conv_stroke.h> // conv_stroke
#include <agg_conv_dash.h> // conv_dash
#include <agg_conv_marker.h> // conv_marker
#include <agg_conv_curve.h> // conv_curve
#include <agg_conv_contour.h> // conv_contour
#include <agg_conv_smooth_poly1.h> // conv_smooth_poly1.h
#include <agg_conv_bspline.h> // conv_bspline
#include <agg_conv_transform.h> // conv_transform
class the_application : public agg::platform_support
{
public:
the_application(agg::pix_format_e format, bool flip_y) :
agg::platform_support(format, flip_y)
{
}
virtual void on_draw()
{
//Rendering Buffer //用于存放像素点阵数据的内存块,这里是最终形成的图像数据
agg::rendering_buffer &rbuf = rbuf_window();
agg::pixfmt_bgr24 pixf(rbuf);
// Renderers
typedef agg::renderer_base<agg::pixfmt_bgr24> renderer_base_type; //底层渲染器
renderer_base_type renb(pixf);
// typedef agg::renderer_scanline_aa_solid<renderer_base_type> renderer_scanline_type; //高层渲染器
typedef agg::renderer_scanline_bin_solid<renderer_base_type> renderer_scanline_type; //高层渲染器
renderer_scanline_type rensl(renb);
/*
// Vertex Source
//agg::ellipse ell(100,100,50,50); //顶点源,里面存放了一堆2D顶点以及对应的命令,这个顶点源呈现的是一个圆形
agg::triangle ell(100,100,50);
// Coordinate conversion pipeline //坐标转换管道,它可以变换Vertex Source中的顶点,比如矩阵变换,轮廓提取,转换为虚线等。
//typedef agg::conv_contour<agg::ellipse> ell_cc_type; //扩展轮廓线
typedef agg::conv_contour<agg::triangle> ell_cc_type;
ell_cc_type ccell(ell);
typedef agg::conv_stroke<ell_cc_type> ell_cc_cs_type; //只显示轮廓线
ell_cc_cs_type csccell(ccell);
*/
// Vertex Source
agg::ellipse ell(, , , ); // 圆心在中间
// Coordinate conversion pipeline
agg::trans_affine mtx; // trans_affine不 仅仅用于源顶点的变换,在AGG库中有不少地方都能看到它
mtx.scale(); // x轴缩小到原来的一半
mtx.rotate(agg::deg2rad()); // 旋转30度
mtx.translate(, ); // 平移100,100
typedef agg::conv_transform<agg::ellipse> ell_ct_type;
ell_ct_type ctell(ell, mtx); // 矩阵变换
typedef agg::conv_contour<ell_ct_type> ell_cc_type;
ell_cc_type ccell(ctell); // 轮廓变换
typedef agg::conv_dash<ell_cc_type> ell_cd_type;
ell_cd_type cdccell(ccell);
cdccell.add_dash(, );
typedef agg::conv_stroke<ell_cd_type> ell_cc_cs_type;
// ell_cc_cs_type csccell(ccell); // 转换成多义线
ell_cc_cs_type csccell(cdccell);
// csccell.width(3);
// Scanline Rasterizer //把顶点数据(矢量数据)转换成一组水平扫描线,扫描线由一组线段(Span)组成,线段(Span)包含了起始位置、长度和覆盖率(可以理解为透明度)信息。AGG的抗锯齿(Anti-Aliasing)功能也是在这时引入的。
agg::rasterizer_scanline_aa<> ras;
agg::scanline_u8 sl;
// Draw
renb.clear(agg::rgba8(, , ));
// renb.clip_box(30,30,160,160); // 设置可写区域
; i<; i++)
{
ccell.width(i * );
ras.add_path(csccell);
rensl.color(agg::rgba8(, , i * ));
// agg::render_scanlines(ras,sl,rensl);
agg::render_scanlines_aa_solid(ras, sl, renb, agg::rgba8(, , i * ));
}
;
++i;
agg::path_storage ps;
ps.start_new_path();
ps.move_to(+ i, );
ps.line_to(, );
ps.line_to(, );
ps.end_poly();
agg::conv_stroke<agg::path_storage, agg::vcgen_markers_term> csps(ps);
ras.add_path(csps);
agg::render_scanlines_aa_solid(ras, sl, renb, agg::rgba8(, , ));
/*
agg::arrowhead ah;
ah.head(0,10,5,5);
ah.tail(10,10,5,5);
// 用path_storage生成一条直线
agg::path_storage ps;
ps.move_to(160,60);
ps.line_to(100,100);
// 转换
agg::conv_stroke<agg::path_storage, agg::vcgen_markers_term> csps(ps);
agg::conv_marker<agg::vcgen_markers_term, agg::arrowhead>
arrow(csps.markers(), ah);
// 画线
ras.add_path(csps);
agg::render_scanlines_aa_solid(ras,sl,renb,agg::rgba8(0,0,0));
// 画箭头
ras.add_path(arrow);
agg::render_scanlines_aa_solid(ras,sl,renb,agg::rgba8(255,0,0));
agg::triangle t(100,100,50);//自定义顶点源
agg::conv_smooth_poly1_curve<agg::triangle> cspct(t);
ras.add_path(cspct);
agg::render_scanlines_aa_solid(
ras,sl,renb,agg::rgba8(255,0,0));
for(int j=0; j<20; j++)
pixf.blend_vline(50+j,20,100,agg::rgba(j/20.0,0,0),128);
agg::int8u* p = rbuf.row_ptr(20);//得到第20行指针
memset(p,0,rbuf.stride_abs());//整行以0填充
*/
}
virtual void on_post_draw(void* raw_handler) override
{
}
};
int agg_main(int argc, char* argv[])
{
the_application app(agg::pix_format_bgr24, false);
app.caption("AGG Example. Anti-Aliasing Demo");
, , agg::window_resize))
{
return app.run();
}
;
}
编译运行,一切OK的话显示如图

还没完,AGG最叼的是自带演示工程水平非常高,在源码中有一个叫examples的目录,直接拖一个idea.cpp编译,如图

所有例子都有预编译好的二进制版可看,真正良心实用的例子。
http://www.antigrain.com/demo/index.html
好,到此AGG部分就结束了。
========================================
接下来看看Cairo
第三方依懒库有
libpng
zlib
pixman
当然Cairo源码肯定少不了 http://www.cairographics.org/download/
libpng和zlib编译直接使用之前编译好的 http://www.cnblogs.com/kileyi/p/5193823.html
官网有一个说明,但是我没完全照做。
http://www.cairographics.org/end_to_end_build_for_win32/
主要不同的是,我的libpng和zlib编译好了,直接从pixman开始的
首先打开VS2015命令行开发环境,在开始菜单中可以找到

然后进入到pixman源码目录
D:\CPPLibs\pixman-0.34.0\pixman
注意这个不是源码根目录,而是pixman目录,一定不能搞错了
然后新建一个setpath.bat文件,内容如下,主要就是设置一下msys的bin到当前环境目录,并且release编译
set PATH=%PATH%;D:\MinGW\msys\1.0\bin
make -f Makefile.win32 "CFG=release"
之后在命令行中运行这个bat,一切OK会在release目录生成pixman-1.lib,等会儿要用到
3个依赖库都搞定后就要编译Cairo了,我的源码目录
D:\CPPLibs\cairo-1.14.6
然后在与源码目录同级新建libpng,zlib,pixman目录,放上对应的lib文件
D:\CPPLibs\libpng\libpng.lib
D:\CPPLibs\zlib\zdll.lib
D:\CPPLibs\pixman\pixman\release\pixman-1.lib
注意有些需要改名
然后回到源码目录
D:\CPPLibs\cairo-1.14.6
新建setpath.bat文件,内容如下,主要是设置include和library路径,出于一些原因我的libpng和zlib的library放到了一起,你如果没放到一起就自己加上
set INCLUDE=%INCLUDE%;D:\CPPLibs\zlib-1.2.8
set INCLUDE=%INCLUDE%;D:\CPPLibs\lpng1621
set INCLUDE=%INCLUDE%;D:\CPPLibs\pixman-0.34.0\pixman
set INCLUDE=%INCLUDE%;D:\CPPLibs\cairo-1.14.6\boilerplate
set INCLUDE=%INCLUDE%;D:\CPPLibs\cairo-1.14.6\src
set LIB=%LIB%;D:\CPPLibs\lpng1621\projects\vstudio\Release
make -f Makefile.win32 "CFG=release"
有人可能想为什么这里都设置好了路径,上面还要建立libpng和zlib,pixman目录,这主要是因为官方那个编译文件默认是写死的,只找他默认改名后的目录和文件,
我懒得改所以就直接复制了一份,在官方的那个编译说明中好像有提到
如果编译完一切OK,你会看到下面几个需要的文件
D:\CPPLibs\cairo-1.14.6\src\release\cairo.lib
D:\CPPLibs\cairo-1.14.6\src\release\cairo-static.lib
D:\CPPLibs\cairo-1.14.6\src\release\cairo.dll
我只需要cairo.lib和cairo.dll
接下来新建Win32 Console空工程,配置好Cario和OpenGL的include和library目录
使用glut,glext,opengl1.x语法,写个简单的测试工程
#include <stdlib.h>
#include <stdio.h>
#include <malloc.h>
#define _USE_MATH_DEFINES
#include <math.h>
#include <gl/glut.h>
#include <gl/glext.h>
#include <cairo.h>
;
;
;
;
double line_width = 5;
//double line_width = 1 / win_width;
cairo_surface_t * surf = NULL;
cairo_t * cr = NULL;
unsigned char * surf_data = NULL;
GLuint texture_id;
// Interface //
void opengl_init(void)
{
printf("OpenGL version: %s\n", glGetString(GL_VERSION));
printf("OpenGL vendor: %s\n", glGetString(GL_VENDOR));
printf("OpenGL renderer: %s\n", glGetString(GL_RENDERER));
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glDisable(GL_DEPTH_TEST);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_TEXTURE_RECTANGLE_ARB);
}
void opengl_cleanup(void)
{
glDeleteTextures(, &texture_id);
}
void opengl_draw(int width, int height, unsigned char * surf_data)
{
if (!surf_data)
{
printf("draw_func() - No valid pointer to surface-data passed\n");
return;
}
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glClear(GL_COLOR_BUFFER_BIT);
glPushMatrix();
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, texture_id);
glTexImage2D(GL_TEXTURE_RECTANGLE_ARB,
,
GL_RGBA,
width,
height,
,
GL_BGRA,
GL_UNSIGNED_BYTE,
surf_data);
glColor3f(0.25f, 0.5f, 1.0f);
glBegin(GL_QUADS);
glTexCoord2f(0.0f, 0.0f);
glVertex2f(0.0f, 0.0f);
glTexCoord2f((GLfloat)width, 0.0f);
glVertex2f(1.0f, 0.0f);
glTexCoord2f((GLfloat)width, (GLfloat)height);
glVertex2f(1.0f, 1.0f);
glTexCoord2f(0.0f, (GLfloat)height);
glVertex2f(0.0f, 1.0f);
glEnd();
glPopMatrix();
}
void opengl_resize(int width, int height)
{
glViewport(, , width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0.0f, 1.0f, 0.0f, 1.0f, -1.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
glDeleteTextures(, &texture_id);
glGenTextures(, &texture_id);
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, texture_id);
glTexImage2D(GL_TEXTURE_RECTANGLE_ARB,
,
GL_RGBA,
width,
height,
,
GL_BGRA,
GL_UNSIGNED_BYTE,
NULL);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
}
void drawShape()
{
//save current brush
cairo_save(cr);
// clear background
cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
//cairo_scale(cr, (double)win_height / 1.0f, (double)win_height / 1.0f);
cairo_set_source_rgba(cr, , , , );
cairo_paint(cr);
//set line color and style
cairo_set_line_cap(cr, CAIRO_LINE_CAP_ROUND);
cairo_set_line_width(cr, line_width);
;
angle += 0.01f;
//画矩形
cairo_set_source_rgba(cr, , , , );
//cairo_rectangle(cr, 0.5f + sinf(angle) * 0.1f, 0.5f, 0.1f, 0.1f);
cairo_rectangle(cr, hw + sin(angle) * , hh, , );
cairo_fill(cr);
cairo_stroke(cr);
//画弧
cairo_set_source_rgba(cr, , , , );
cairo_arc(cr, , hh, , , * M_PI);
//cairo_fill(cr);
cairo_stroke(cr);
//画线
;
;
;
;
;
x = r * cosf(angle);
y = r * sinf(angle);
cairo_set_source_rgba(cr, , , , );
cairo_move_to(cr, x + posx, y + posy);
cairo_line_to(cr, -x + posx, -y + posy);
cairo_stroke(cr);
//restore previous brush
cairo_restore(cr);
}
void display(void)
{
drawShape();
opengl_draw(win_width, win_height, surf_data);
glutSwapBuffers();
}
cairo_t*
create_cairo_context(int width,
int height,
int channels,
cairo_surface_t** surf,
unsigned char** buffer)
{
cairo_t* cr;
// create cairo-surface/context to act as OpenGL-texture source
*buffer = (unsigned char*)calloc(channels * width * height, sizeof(unsigned char));
if (!*buffer)
{
printf("create_cairo_context() - Couldn't allocate buffer\n");
return NULL;
}
*surf = cairo_image_surface_create_for_data(*buffer,
CAIRO_FORMAT_ARGB32,
width,
height,
channels * width);
if (cairo_surface_status(*surf) != CAIRO_STATUS_SUCCESS)
{
free(*buffer);
printf("create_cairo_context() - Couldn't create surface\n");
return NULL;
}
cr = cairo_create(*surf);
if (cairo_status(cr) != CAIRO_STATUS_SUCCESS)
{
free(*buffer);
printf("create_cairo_context() - Couldn't create context\n");
return NULL;
}
return cr;
}
void cleanup(void)
{
opengl_cleanup();
free(surf_data);
cairo_destroy(cr);
exit();
}
void keyboard(unsigned char key, int x, int y)
{
switch (key)
{
//27 is ESC key
:
case 'q':
cleanup();
break;
case 'd':
cairo_surface_write_to_png(surf, "frame.png");
break;
case '+':
)
line_width += ;
break;
case '-':
)
line_width -= ;
break;
}
}
void idle(void)
{
glutPostRedisplay();
}
int main(int argc, char ** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA);
glutInitWindowSize(win_width, win_height);
)
exit(-);
// create cairo-surface/context to act as OpenGL-texture source
cr = create_cairo_context(win_width, win_height, , &surf, &surf_data);
// setup "GL-context"
opengl_init();
glutDisplayFunc(display);
glutKeyboardFunc(keyboard);
glutIdleFunc(idle);
opengl_resize(win_width, win_height);
glutMainLoop();
;
}

至此Cairo部分就结束了,活动一下筋骨,可以开始写应用了
Win7 VS2015及MinGW环境编译矢量库agg-2.5和cairo-1.14.6的更多相关文章
- Win7 64位 VS2015及MinGW环境编译矢量库agg-2.5和cairo-1.14.6
书接上文,昨天装了MinGW,主要原因之一是要用到MSYS,所以顺手把FFMPEG又编译了一遍. 回到主题,其实我是想编译矢量库,因为最近要学习一些计算几何算法,所以找个方便的2D画图库就很重要. 说 ...
- Win7 VS2015及MinGW环境编译FFMPEG-20160326
因为又要弄MinGW了,所以顺便把FFMPEG编译了,文章主要参考这篇,防抽所以复制一遍,顺便加些自己的内容 http://blog.csdn.net/finewind/article/details ...
- Win7 64位 VS2015及MinGW环境编译FFMPEG-20160326
因为又要弄MinGW了,所以顺便把FFMPEG编译了,文章主要参考这篇,防抽所以复制一遍,顺便加些自己的内容 http://blog.csdn.net/finewind/article/details ...
- Win7 64位 VS2013环境编译CGAL-4.7
看到有人在QQ空间感叹编译CGAL配置折腾了一天时间,自己也想试试,虽然并不打算用,但感觉这库也挺有名的,想必日后用得着,于是着手试着编译. 首先是看一下官网的windows下配置说明 http:// ...
- Linux环境编译动态库和静态库总结
对Linux环境动态库和静态库的一些基础知识做一些总结, 首先总结静态库的编译步骤. 1 先基于.cpp或者.c文件生成对应的.o文件 2将几个.o文件 使用ar -cr命令 生成libname.a文 ...
- Win7 + VS2015 + CMake3.6.1-GUI编译库
CMake生成Unicode版本VC工程 Just add this line in your top CMakeLists.txt file: add_definitions(-DUNICO ...
- mingw 环境编译 liburl故障一例
环境是 windows 10,已经安装 mingw,并设置好mingw 和 msys的环境变量 C:\Users\cracker>set |grep MinGW Path=C:\Program ...
- Win7 64位 VS2013环境编译Squirrel 3.0.7
Squirrel是一个类似Lua,但是更面向对象的脚本语言. 国内这个介绍很少,环境配置更是没有任何文章提到,花了点时间搞定了,备忘记录下过程. 首先是下载,写本文时Squirrel最新版本为3.0. ...
- Win7 64位 MinGW环境测试SDL2.0.3
下载MinGW版的文件 http://www.libsdl.org/release/SDL2-devel-2.0.3-mingw.tar.gz 解压放到mysys下面 运行Makefile mysys ...
随机推荐
- 【校招面试 之 网络】第2题 TCP的可靠传输、流量控制、滑动窗口
1.可靠传输 (1)三次握手 TCP/IP协议中,TCP协议提供可靠的连接服务,采用三次握手建立一个连接: (1)第一次握手:建立连接时,客户端A发送SYN包(SYN=j)到服务器B,并进入SYN_S ...
- importlib的用法
这个模块可以通过字符串导入模块 比如我们有下面的例子 需要导入的模块的代码 在test_import目录下有一个test1的py文件 name = "中国是个大傻逼" class ...
- 六.Spring与RabbitMQ集成--HelloWorld
spring对RabbitMQ做了很好的集成,我们称之为spring AMQP,其官方文档写得十分详尽,文档地址:https://docs.spring.io/spring-amqp/referenc ...
- Git下基本命令操作
提前准备好一个文件夹,并且进入该文件夹. 1.clone Github 上的Repository,如: git clone git@github.com:Git账号用户名/项目名称.git 2.仓库初 ...
- 3.Mysql支持的数据类型
3.Mysql支持的数据类型数据类型用来指定一定的存储格式.约束和有效范围.数据类型主要有:数值类型.字符串类型.日期和时间类型.3.1 数字类型类型名 字节数 有符号最小值 有符号最大值 无符号最小 ...
- Android开发之ListView设置隔行变色
public class HLCheckAdapter extends BaseAdapter { private List<HuoLiang> list; private Context ...
- PAT 1011 A+B和C (15)(C++&JAVA&Python)
1011 A+B和C (15)(15 分) 给定区间[-2^31^, 2^31^]内的3个整数A.B和C,请判断A+B是否大于C. 输入格式: 输入第1行给出正整数T(<=10),是测试用例的个 ...
- javascript的变量类型:var、let、const
不同点:可变性,与作用域的关系. 可变性:const定义的变量都不可变,而var和let可以任意更改. const 只能在声明时被初始化一次,之后不允许将全新的值赋值给const变量.但可以修改con ...
- 洛谷1993 小K的农场
原题链接 裸的差分约束. \(X_a-X_b\geqslant C\) \(X_a-X_b\leqslant C\Rightarrow X_b-X_a\geqslant -C\) \(X_a-X_b\ ...
- PHP学习笔记(二)
1.表单 PHP 的 $_GET和 $_POST用于检索表单中的值,比如用户输入. $_GET和$_POST变量分别用于收集来自 method="get" 和method=&quo ...