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

news/2024/10/17 8:26:55/

书接上文,昨天装了MinGW,主要原因之一是要用到MSYS,所以顺手把FFMPEG又编译了一遍。

回到主题,其实我是想编译矢量库,因为最近要学习一些计算几何算法,所以找个方便的2D画图库就很重要。

说白了其实是懒得用OpenGL写画几何体代码,画线,AA什么的。

不管怎么说,介绍看的是这篇文章。

C++矢量图形库系列(1)——矢量图形库乱谈(转) - 北山愚公* - 博客园

提到了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_transformclass 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);// Rendererstypedef 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 pipelineagg::trans_affine mtx;        // trans_affine不 仅仅用于源顶点的变换,在AGG库中有不少地方都能看到它mtx.scale();             // x轴缩小到原来的一半mtx.rotate(agg::deg2rad()); // 旋转30度mtx.translate(, ); // 平移100,100typedef 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;// Drawrenb.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源码肯定少不了 Download

libpng和zlib编译直接使用之前编译好的 Win7 VS2015环境编译Libpng - KILEYI - 博客园

官网有一个说明,但是我没完全照做。

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 brushcairo_save(cr);// clear backgroundcairo_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 stylecairo_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 brushcairo_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 sourcecr = 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部分就结束了,活动一下筋骨,可以开始写应用了

 


http://www.ppmy.cn/news/533402.html

相关文章

Gin 初步使用

快速入门 官方文档 引入 import "github.com/gin-gonic/gin"编写代码 package mainimport ("github.com/gin-gonic/gin""net/http" )func pong(c *gin.Context) {c.JSON(http.StatusOK, gin.H{"message": "pong",}) }fu…

Jmeter简易脚本录制回放实例解析

此时jmeter脚本已经录制下来了&#xff0c;但是这个脚本是无法回放的&#xff01;因为“HTTP代理服务器”是“非测试元件”&#xff0c;所以“运行测试计划”的时候&#xff0c;自然就不会运行“非测试元件”了。那么要如何让录制下来的脚本变得可以运行呢&#xff1f;下面就来…

【Python】实现键盘鼠标动作录制和执行的小工具

突发奇想做一个可以实现鼠标键盘操作录制&#xff0c;并可以回放操作的小工具。依托于pynput模块来实现鼠标键盘的控制&#xff0c;tkinter来实现图形界面的绘制。分为以下几个步骤&#xff1a; 一 录制&#xff08;记录过程&#xff0c;并将用户的操作保存为json文件&#xf…

如何克服录制回放模式的弊端

Web浏览器的可视化界面及交互操作屏蔽了与服务器端交互的请求响应的复杂性。例如&#xff0c;我们随便打开一个网页或者触发一次交互操作&#xff0c;就可能在后端触发了成百上千的HTTP请求响应的处理&#xff0c;这些过程对使用者来说是不可见的&#xff0c;也是不需要关心的。…

web页面录制与回放全栈小项目

web页面录制与回放全栈小项目 技术栈相关文档项目代码项目效果本地启动前端后端node 推荐阅读 你越是认真生活&#xff0c;你的生活就会越美好——弗兰克劳埃德莱特 《人生果实》经典语录 技术栈 前端 Vue 后端 Node Egg 数据库 mongo 录制与回访实现 rrweb websocket …

rosbag录制和回放

rosbag录制和回放 1. 录制2. 回放3. 参考 本博客参照一位大佬YongqiangGao的博客实现仿真环境中一个 7 轴机械臂画圆时的 joint_states 数据&#xff0c;在此记录以供自己加深印象以及回顾&#xff0c;主要总结了如何通过rosbag将ROS系统运行过程中的数据录制到 .bag 文件中&am…

15-bag的录制,回放与解析

本教程教你如何使用rosbag record工具来录制ros通信数据。之后在通过rosbag play形式回放录制的数据包 此教程不详细解读&#xff0c;仅将rosbag record对应的help文档列出&#xff0c;并给出具体录制例子 rosbag bag包是存储ROS消息数据的文件格式&#xff0c;rosbag命令可以…

C++用钩子模仿按键精灵录制键盘鼠标的功能

最近需要做个跟按键精灵类似的软件&#xff0c;模仿键盘鼠标的动作&#xff0c;然后重播一次&#xff0c;最开时候的时候用键盘钩子和鼠标钩子做的&#xff0c;虽然实现了功能&#xff0c;但是鼠标移动速度非常快&#xff0c;所以换成WH_JOURNALPLAYBACK 和WH_JOURNALRECORD 钩…