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,原文在哪忘了,只是测试下。

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

 

 

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

转载于:https://www.cnblogs.com/kileyi/p/5328872.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值