Win7 64位 VS2015及MinGW环境编译矢量库agg-2.5和cairo-1.14.6

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Win7 64位 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,原文在哪忘了,只是测试下。

  1 #include "agg_basics.h" 
  2 #include "agg_rendering_buffer.h" 
  3 #include "agg_rasterizer_scanline_aa.h" 
  4 #include "agg_scanline_u.h" 
  5 #include "agg_renderer_scanline.h" 
  6 #include "agg_pixfmt_rgb.h" 
  7 #include "platform/agg_platform_support.h" 
  8 #include "agg_ellipse.h"  
  9 #include "agg_conv_contour.h" 
 10 #include "agg_conv_stroke.h" 
 11 
 12 #include "agg_conv_marker.h"
 13 #include "agg_arrowhead.h"
 14 #include "agg_path_storage.h"
 15 #include "agg_vcgen_markers_term.h"
 16 
 17 
 18 #include <agg_conv_stroke.h> // conv_stroke
 19 #include <agg_conv_dash.h> // conv_dash
 20 #include <agg_conv_marker.h> // conv_marker
 21 #include <agg_conv_curve.h> // conv_curve
 22 #include <agg_conv_contour.h> // conv_contour
 23 #include <agg_conv_smooth_poly1.h> // conv_smooth_poly1.h
 24 #include <agg_conv_bspline.h> // conv_bspline
 25 #include <agg_conv_transform.h> // conv_transform
 26 
 27 
 28 class the_application : public agg::platform_support
 29 {
 30 public:
 31     the_application(agg::pix_format_e format, bool flip_y) :
 32         agg::platform_support(format, flip_y)
 33     {
 34     }
 35 
 36     virtual void on_draw()
 37     {
 38         //Rendering Buffer              //用于存放像素点阵数据的内存块,这里是最终形成的图像数据
 39         agg::rendering_buffer &rbuf = rbuf_window();
 40         agg::pixfmt_bgr24 pixf(rbuf);
 41 
 42         // Renderers 
 43         typedef agg::renderer_base<agg::pixfmt_bgr24> renderer_base_type;  //底层渲染器
 44         renderer_base_type renb(pixf);
 45 
 46         // typedef agg::renderer_scanline_aa_solid<renderer_base_type> renderer_scanline_type;   //高层渲染器
 47         typedef agg::renderer_scanline_bin_solid<renderer_base_type> renderer_scanline_type;   //高层渲染器
 48 
 49         renderer_scanline_type rensl(renb);
 50         /*
 51         // Vertex Source
 52         //agg::ellipse ell(100,100,50,50); //顶点源,里面存放了一堆2D顶点以及对应的命令,这个顶点源呈现的是一个圆形
 53         agg::triangle ell(100,100,50);
 54 
 55         // Coordinate conversion pipeline //坐标转换管道,它可以变换Vertex Source中的顶点,比如矩阵变换,轮廓提取,转换为虚线等。
 56         //typedef agg::conv_contour<agg::ellipse> ell_cc_type;     //扩展轮廓线
 57         typedef agg::conv_contour<agg::triangle> ell_cc_type;
 58         ell_cc_type ccell(ell);
 59 
 60         typedef agg::conv_stroke<ell_cc_type> ell_cc_cs_type;    //只显示轮廓线
 61         ell_cc_cs_type csccell(ccell);
 62         */
 63 
 64         // Vertex Source 
 65         
 66         agg::ellipse ell(0, 0, 50, 50);  // 圆心在中间           
 67                                          // Coordinate conversion pipeline 
 68         agg::trans_affine mtx;        // trans_affine不 仅仅用于源顶点的变换,在AGG库中有不少地方都能看到它
 69         mtx.scale(0.5, 1);             // x轴缩小到原来的一半 
 70         mtx.rotate(agg::deg2rad(30)); // 旋转30度 
 71         mtx.translate(100, 100); // 平移100,100 
 72         typedef agg::conv_transform<agg::ellipse> ell_ct_type;
 73         ell_ct_type ctell(ell, mtx); // 矩阵变换 
 74 
 75         typedef agg::conv_contour<ell_ct_type> ell_cc_type;
 76         ell_cc_type ccell(ctell); // 轮廓变换 
 77 
 78         typedef agg::conv_dash<ell_cc_type> ell_cd_type;
 79         ell_cd_type cdccell(ccell);
 80         cdccell.add_dash(5, 5);
 81 
 82 
 83         typedef agg::conv_stroke<ell_cd_type> ell_cc_cs_type;
 84         // ell_cc_cs_type csccell(ccell); // 转换成多义线 
 85         ell_cc_cs_type csccell(cdccell);
 86 
 87         // csccell.width(3);
 88 
 89 
 90         // Scanline Rasterizer            //把顶点数据(矢量数据)转换成一组水平扫描线,扫描线由一组线段(Span)组成,线段(Span)包含了起始位置、长度和覆盖率(可以理解为透明度)信息。AGG的抗锯齿(Anti-Aliasing)功能也是在这时引入的。
 91         agg::rasterizer_scanline_aa<> ras;
 92         agg::scanline_u8 sl;
 93 
 94         // Draw           
 95         renb.clear(agg::rgba8(255, 255, 255));
 96         //  renb.clip_box(30,30,160,160); // 设置可写区域 
 97 
 98         for (int i = 0; i<5; i++)
 99         {
100             ccell.width(i * 20);
101             ras.add_path(csccell);
102             rensl.color(agg::rgba8(0, 0, i * 50));
103             //  agg::render_scanlines(ras,sl,rensl); 
104             agg::render_scanlines_aa_solid(ras, sl, renb, agg::rgba8(0, 0, i * 50));
105 
106         }
107 
108 
109         static double i = 0;
110         ++i;
111         agg::path_storage ps;
112 
113         ps.start_new_path();
114         ps.move_to(200+ i, 60);
115         ps.line_to(400, 100);
116         ps.line_to(300, 140);
117         ps.end_poly();
118 
119 
120 
121         agg::conv_stroke<agg::path_storage, agg::vcgen_markers_term> csps(ps);
122         ras.add_path(csps);
123         agg::render_scanlines_aa_solid(ras, sl, renb, agg::rgba8(0, 0, 0));
124 
125 
126 
127 
128 
129         /*
130         agg::arrowhead ah;
131         ah.head(0,10,5,5);
132         ah.tail(10,10,5,5);
133         // 用path_storage生成一条直线
134         agg::path_storage ps;
135         ps.move_to(160,60);
136         ps.line_to(100,100);
137         // 转换
138         agg::conv_stroke<agg::path_storage, agg::vcgen_markers_term> csps(ps);
139         agg::conv_marker<agg::vcgen_markers_term, agg::arrowhead>
140         arrow(csps.markers(), ah);
141         // 画线
142         ras.add_path(csps);
143         agg::render_scanlines_aa_solid(ras,sl,renb,agg::rgba8(0,0,0));
144         // 画箭头
145         ras.add_path(arrow);
146         agg::render_scanlines_aa_solid(ras,sl,renb,agg::rgba8(255,0,0));
147 
148 
149         agg::triangle t(100,100,50);//自定义顶点源
150         agg::conv_smooth_poly1_curve<agg::triangle> cspct(t);
151         ras.add_path(cspct);
152         agg::render_scanlines_aa_solid(
153         ras,sl,renb,agg::rgba8(255,0,0));
154 
155 
156         for(int j=0; j<20; j++)
157         pixf.blend_vline(50+j,20,100,agg::rgba(j/20.0,0,0),128);
158 
159 
160 
161         agg::int8u* p = rbuf.row_ptr(20);//得到第20行指针
162         memset(p,0,rbuf.stride_abs());//整行以0填充
163         */
164     }
165 
166     virtual void on_post_draw(void* raw_handler) override
167     {
168     }
169 
170 };
171 
172 
173 int agg_main(int argc, char* argv[])
174 {
175 
176 
177     the_application app(agg::pix_format_bgr24, false);
178 
179     app.caption("AGG Example. Anti-Aliasing Demo");
180 
181     if (app.init(600, 400, agg::window_resize))
182     {
183         return app.run();
184     }
185     return -1;
186 
187 }

编译运行,一切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语法,写个简单的测试工程

  1 #include <stdlib.h>
  2 #include <stdio.h>
  3 #include <malloc.h>
  4 
  5 #define _USE_MATH_DEFINES
  6 #include <math.h>
  7 
  8 #include <gl/glut.h>
  9 #include <gl/glext.h>
 10 
 11 #include <cairo.h>
 12 
 13 
 14 
 15 double win_width = 800;
 16 double win_height = 600;
 17 double line_width = 1/ win_width;
 18 
 19 cairo_surface_t * surf = NULL;
 20 cairo_t         * cr = NULL;
 21 unsigned char   * surf_data = NULL;
 22 
 23 GLuint texture_id;
 24 
 25 // Interface //
 26 
 27 void opengl_init(void)
 28 {
 29     printf("OpenGL version: %s\\n", glGetString(GL_VERSION));
 30     printf("OpenGL vendor: %s\\n", glGetString(GL_VENDOR));
 31     printf("OpenGL renderer: %s\\n", glGetString(GL_RENDERER));
 32 
 33     glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
 34     glDisable(GL_DEPTH_TEST);
 35     glEnable(GL_BLEND);
 36     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
 37     glEnable(GL_TEXTURE_RECTANGLE_ARB);
 38 }
 39 
 40 void opengl_cleanup(void)
 41 {
 42     glDeleteTextures(1, &texture_id);
 43 }
 44 
 45 void opengl_draw(int width, int height, unsigned char * surf_data)
 46 {
 47     if (!surf_data)
 48     {
 49         printf("draw_func() - No valid pointer to surface-data passed\\n");
 50         return;
 51     }
 52 
 53     glMatrixMode(GL_MODELVIEW);
 54     glLoadIdentity();
 55     glClear(GL_COLOR_BUFFER_BIT);
 56 
 57     glPushMatrix();
 58 
 59     glBindTexture(GL_TEXTURE_RECTANGLE_ARB, texture_id);
 60     glTexImage2D(GL_TEXTURE_RECTANGLE_ARB,
 61         0,
 62         GL_RGBA,
 63         width,
 64         height,
 65         0,
 66         GL_BGRA,
 67         GL_UNSIGNED_BYTE,
 68         surf_data);
 69 
 70     glColor3f(0.25f, 0.5f, 1.0f);
 71     glBegin(GL_QUADS);
 72     glTexCoord2f(0.0f, 0.0f);
 73     glVertex2f(0.0f, 0.0f);
 74     glTexCoord2f((GLfloat)width, 0.0f);
 75     glVertex2f(1.0f, 0.0f);
 76     glTexCoord2f((GLfloat)width, (GLfloat)height);
 77     glVertex2f(1.0f, 1.0f);
 78     glTexCoord2f(0.0f, (GLfloat)height);
 79     glVertex2f(0.0f, 1.0f);
 80     glEnd();
 81 
 82     glPopMatrix();
 83 }
 84 
 85 void opengl_resize(int width, int height)
 86 {
 87     glViewport(0, 0, width, height);
 88     glMatrixMode(GL_PROJECTION);
 89     glLoadIdentity();
 90     glOrtho(0.0f, 1.0f, 0.0f, 1.0f, -1.0f, 1.0f);
 91 
 92     glClear(GL_COLOR_BUFFER_BIT);
 93 
 94     glDeleteTextures(1, &texture_id);
 95     glGenTextures(1, &texture_id);
 96     glBindTexture(GL_TEXTURE_RECTANGLE_ARB, texture_id);
 97     glTexImage2D(GL_TEXTURE_RECTANGLE_ARB,
 98         0,
 99         GL_RGBA,
100         width,
101         height,
102         0,
103         GL_BGRA,
104         GL_UNSIGNED_BYTE,
105         NULL);
106     glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
107 }
108 
109 
110 void drawShape()
111 {
112     //save current brush
113     cairo_save(cr);
114 
115     // clear background
116     cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
117     cairo_scale(cr, (double)win_width / 1.0f, (double)win_height / 1.0f);
118     cairo_set_source_rgba(cr, 1, 1, 1, 1);
119     cairo_paint(cr);
120 
121     //set line color and style
122     cairo_set_line_cap(cr, CAIRO_LINE_CAP_ROUND);
123     cairo_set_line_width(cr, line_width);
124 
125 
126 
127     static double angle = 0;
128     angle += 0.01f;
129 
130     //画矩形
131     cairo_set_source_rgba(cr, 1, 0, 0, 1);
132     cairo_rectangle(cr, 0.5f + sinf(angle) * 0.1f, 0.5f, 0.1f, 0.1f);
133     cairo_fill(cr);
134     cairo_stroke(cr);
135 
136     //画弧
137     cairo_set_source_rgba(cr, 0, 0, 1, 1);
138     cairo_arc(cr, 0.3f, 0.5f, 0.1f, 0, 2 * M_PI);
139     //cairo_fill(cr);
140     cairo_stroke(cr);
141 
142     //画线
143     static double r = 0.05f;
144     static double posx = 0.6;
145     static double posy = 0.7;
146     static double x = 0;
147     static double y = 0;
148 
149     x = r * cosf(angle);
150     y = r * sinf(angle);
151 
152     cairo_set_source_rgba(cr, 0, 1, 0, 1);
153     cairo_move_to(cr, x + posx, y + posy);
154     cairo_line_to(cr, -x + posx, -y + posy);
155     cairo_stroke(cr);
156 
157     
158 
159     //restore previous brush
160     cairo_restore(cr);
161 }
162 
163 
164 void display(void)
165 {
166     drawShape();
167 
168     opengl_draw(win_width, win_height, surf_data);
169 
170     glutSwapBuffers();
171 }
172 
173 cairo_t*
174 create_cairo_context(int               width,
175     int               height,
176     int               channels,
177     cairo_surface_t** surf,
178     unsigned char**   buffer)
179 {
180     cairo_t* cr;
181 
182     // create cairo-surface/context to act as OpenGL-texture source
183     *buffer = (unsigned char*)calloc(channels * width * height, sizeof(unsigned char));
184     if (!*buffer)
185     {
186         printf("create_cairo_context() - Couldn‘t allocate buffer\\n");
187         return NULL;
188     }
189 
190     *surf = cairo_image_surface_create_for_data(*buffer,
191         CAIRO_FORMAT_ARGB32,
192         width,
193         height,
194         channels * width);
195     if (cairo_surface_status(*surf) != CAIRO_STATUS_SUCCESS)
196     {
197         free(*buffer);
198         printf("create_cairo_context() - Couldn‘t create surface\\n");
199         return NULL;
200     }
201 
202     cr = cairo_create(*surf);
203     if (cairo_status(cr) != CAIRO_STATUS_SUCCESS)
204     {
205         free(*buffer);
206         printf("create_cairo_context() - Couldn‘t create context\\n");
207         return NULL;
208     }
209 
210     return cr;
211 }
212 
213 void cleanup(void)
214 {
215     opengl_cleanup();
216     free(surf_data);
217     cairo_destroy(cr);
218     exit(0);
219 }
220 
221 void keyboard(unsigned char key, int x, int y)
222 {
223     switch (key)
224     {
225     //27 is ESC key
226     case 27:
227     case q:
228         cleanup();
229         break;
230 
231     case d:
232         cairo_surface_write_to_png(surf, "frame.png");
233         break;
234 
235     case +:
236         if (line_width < 0.2f)
237             line_width += 0.005f;
238         break;
239 
240     case -:
241         if (line_width > 0.01f)
242             line_width -= 0.005f;
243         break;
244 
245     }
246 }
247 
248 void idle(void)
249 {
250     glutPostRedisplay();
251 }
252 
253 int main(int argc, char ** argv)
254 {
255     glutInit(&argc, argv);
256     glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA);
257     glutInitWindowSize(win_width, win_height);
258 
259     if (glutCreateWindow("Opengl Test") == 0)
260         exit(-2);
261 
262     // create cairo-surface/context to act as OpenGL-texture source
263     cr = create_cairo_context(win_width, win_height, 4, &surf, &surf_data);
264 
265     // setup "GL-context"
266     opengl_init();
267 
268     glutDisplayFunc(display);
269     glutKeyboardFunc(keyboard);
270     glutIdleFunc(idle);
271     opengl_resize(win_width, win_height);
272 
273     glutMainLoop();
274 
275     return 0;
276 }

技术分享

 

至此Cairo部分就结束了,活动一下筋骨,可以开始写应用了

以上是关于Win7 64位 VS2015及MinGW环境编译矢量库agg-2.5和cairo-1.14.6的主要内容,如果未能解决你的问题,请参考以下文章

Win7 64位 VS2015环境编译cegui-0.8.5

mingw64位,win764位如何安装,环境变量?

win7(64位旗舰版)visual studio 2017无法安装及vs2015闪退问题解决方式

使用VS2015 编译 64位的boost库

qt4.8.7 源码在win7+vs2010环境的x64编译(qt 64位)

windows10 vs2015编译 带nginx-rtmp-module 模块的32位nginx