1. Pangolin介绍

常见的3D绘图的程序库有很多,MATLAB、Python的Matplotlib、OpenGL。在Linux上常用的一个3D绘图库是Pangolin,它是基于OpenGL完成的,它不但支持OpenGL的基本操作,还提供了一些GUI的功能。对于在SLAM的学习中,它是必不可少的3D显示工具。

2.安装

(1) 安装依赖库

sudo apt install libgl1-mesa-dev
sudo apt install libglew-dev
sudo apt install cmake#建议安装的库
sudo apt install libpython2.7-dev
sudo apt install pkg-config
sudo apt install libegl1-mesa-dev libwayland-dev libxkbcommon-dev wayland-protocols

另外还有一些可选的库,包括视频输入、CUDA相关,根据自己的需求选择安装。

(2)安装源文件

git clone https://github.com/stevenlovegrove/Pangolin.git
cd Pangolin
mkdir build
cd build
cmake ..
cmake --build .

3.使用方法

以下使用的所有代码,编译时对应的CMakeLists.txt文件如下:

cmake_minimum_required(VERSION 3.16)
project(generate_test)set(CMAKE_CXX_STANDARD 11)
set(CMAKE_BUILD_TYPE "release")
find_package(Pangolin REQUIRED)
include_directories(${Pangolin_INCLUDE_DIRS})add_executable(generate_test main.cpp)
target_link_libraries(${Pangolin_LIBRARIES}
)

3.1 常见的使用形式

Pangolin常用代码形式如下,为了避免注释都写在代码中看起来很乱,我先贴出代码,然后逐行解释。

#include <pangolin/pangolin.h>
int main()
{pangolin::CreateWindowAndBind("Main",640,480);glEnable(GL_DEPTH_TEST);glEnable(GL_BLEND);glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);pangolin::OpenGlRenderState s_cam(pangolin::ProjectionMatrix(640,480,420,420,320,320,0.2,100),pangolin::ModelViewLookAt(2,0,2, 0,0,0, pangolin::AxisY));pangolin::Handler3D handler(s_cam); pangolin::View& d_cam = pangolin::CreateDisplay().SetBounds(0.0, 1.0, 0.0, 1.0, -640.0f/480.0f).SetHandler(&handler);while( !pangolin::ShouldQuit() ){glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);d_cam.Activate(s_cam);//需要绘制的东西写在这里..................//pangolin::FinishFrame();}return 0;
}

下面逐行介绍代码的意思:

(1) pangolin::CreateWindowAndBind("Main",640,480);
创建一个名叫"Main"的GUI窗口用于显示,窗口的大小是640x480像素。

(2)glEnable(GL_DEPTH_TEST);
启动深度测试,开启这个功能之后,窗口中只会绘制面朝相机的那一面像素。一般如果你使用的3D可视化,就要打开这个功能。

(3)glEnable(GL_BLEND);
打开颜色混合,把某一像素位置原来的颜色和将要画上去的颜色,通过某种方式混在一起,从而实现特殊的效果。这个有点儿类似你透过红色玻璃看绿色物体的效果。

(4)glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
使用glEnable(GL_BLEND);之后,后面紧跟着这行代码,表示两种颜色以怎么样的方式进行混合。我默认情况下就是使用这种方法,目前使用上没有碰到问题。如果你感兴趣更进一步的使用,可以参考这个博客

(5)

pangolin::OpenGlRenderState s_cam(pangolin::ProjectionMatrix(640,480,420,420,320,320,0.2,100),pangolin::ModelViewLookAt(2,0,2, 0,0,0, pangolin::AxisY)
);

该行代码表示创建一个相机的观察视图,相当于是模拟一个真实的相机去观测虚拟的三维世界。既然是模拟相机观测,那就得有相机的一些配置参数:

  • ProjectMatrix(int h, int w, int fu, int fv, int cu, int cv, int znear, int zfar)是用来配置相机的内参,参数依次为相机的图像高度、宽度、4个内参以及最近和最远视距
  • ModelViewLookAt(double x, double y, double z,double lx, double ly, double lz, AxisDirection Up)
    前三个参数依次为相机所在的位置,第四到第六个参数相机所看的视点位置(一般会设置在原点),最后是相机轴的方向,最终在GUI中呈现的图像就是通过这个设置的相机内外参得到的。你可以用自己的脑袋当做例子,前三个参数告诉你脑袋在哪里,然后再告诉你看的东西在哪里,最后告诉你的头顶朝着哪里。

(6)pangolin::Handler3D handler(s_cam);
创建相机视图句柄,需要使用它来显示前面设置的相机所“拍摄”到的内容

(7)

pangolin::View& d_cam = pangolin::CreateDisplay().SetBounds(0.0, 1.0, 0.0, 1.0, -640.0f/480.0f).SetHandler(&handler);

进行显示设置。SetBounds函数前四个参数依次表示视图在视窗中的范围(下、上、左、右),最后一个参数是显示的长宽比。(0.0, 1.0, 0.0, 1.0)第一个参数0.0表示显示的拍摄窗口的下边在整个GUI中最下面,第二个参数1.0表示上边在GUI的最上面,以此类推。如果在中间就用0.5表示。

(9)pangolin::ShouldQuit()
检测你是否关闭OpenGL窗口

(10)glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
清空颜色和深度缓存。这样每次都会刷新显示,不至于前后帧的颜信息相互干扰。

(11)d_cam.Activate(s_cam);
激活显示并设置状态矩阵。

(12)pangolin::FinishFrame();
执行后期渲染,事件处理和帧交换,相当于前面设置了那么多现在可以进行最终的显示了。

以上就是一个完整的Pangolin用法,其中你要显示的东西就可以写在代码中我标注的//需要绘制的东西写在这里

是不是很简单的

下面我要向你实际介绍一些用法,包括怎么绘制点、直线、轨迹等等,甚至还包括多线程显示、按钮操作等等。

3.2 绘制点、直线、三角形等

#include <pangolin/pangolin.h>int main() {pangolin::CreateWindowAndBind("Main",640,480);glEnable(GL_DEPTH_TEST);glEnable(GL_BLEND);glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);pangolin::OpenGlRenderState s_cam(pangolin::ProjectionMatrix(640,480,420,420,320,320,0.2,100),pangolin::ModelViewLookAt(2,0,2, 0,0,0, pangolin::AxisY));pangolin::Handler3D handler(s_cam);pangolin::View& d_cam = pangolin::CreateDisplay().SetBounds(0.0, 1.0, 0.0, 1.0, -640.0f/480.0f).SetHandler(&handler);while( !pangolin::ShouldQuit() ){glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);d_cam.Activate(s_cam);//绘制点glBegin( GL_POINTS );//点设置的开始glColor3f(1.0,1.0,1.0);glVertex3f(0.0f,0.0f,0.0f);glVertex3f(1,0,0);glVertex3f(0,2,0);glEnd();//点设置的结束//绘制直线glBegin(GL_LINES);glLineWidth(2.0);glColor3f(1.0, 1.0, 1.0);glVertex3f(0,0,0);glVertex3f(1,1,1);glVertex3f(0,0,0);glVertex3f(0,1,1);glVertex3f(0,0,0);glVertex3f(1,0,1);glEnd();//绘制三角形glBegin(GL_TRIANGLES);glVertex3f(0,1,1);glVertex3f(0,0,0);glVertex3f(1,0,1);glEnd();pangolin::FinishFrame();}return 0;
}

可设置的形状还有

  • GL_POINTS:点
  • GL_LINES:线
  • GL_LINE_STRIP:折线
  • GL_LINE_LOOP:封闭折线
  • GL_TRIANGLES:三角形
  • GL_POLYGON:多边形

总之你绘制的图形必须,以及图像的相关设置必须放在glBegin()glEnd()之间。这之间还有一些可用的配置如下:

  • glVertex(); 设置顶点坐标
  • glColor(); 设置当前颜色
  • glIndex(); 设置当前颜色表
  • glNormal(); 设置法向坐标
  • glEvalCoord(); 产生坐标
  • glCallList(),glCallLists(); 执行显示列表
  • glTexCoord(); 设置纹理坐标
  • glEdgeFlag(); 控制边界绘制
  • glMaterial(); 设置材质

3.3 GUI交互按钮

#include <pangolin/pangolin.h>void function(){std::cout << "Hello pangolin" << std::endl;
}int main() {pangolin::CreateWindowAndBind("Main",640,480);glEnable(GL_DEPTH_TEST);glEnable(GL_BLEND);glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);pangolin::OpenGlRenderState s_cam(pangolin::ProjectionMatrix(640,480,420,420,320,320,0.2,100),pangolin::ModelViewLookAt(2,0,2, 0,0,0, pangolin::AxisY));pangolin::Handler3D handler(s_cam);pangolin::View& d_cam = pangolin::CreateDisplay().SetBounds(0.0, 1.0, 0.0, 1.0, -640.0f/480.0f).SetHandler(&handler);pangolin::CreatePanel("ui").SetBounds(0.0, 1.0, 0.0, pangolin::Attach::Pix(180));//创建pangolin::Var<bool> a_button("ui.A_Button", false, false);//设置一个按钮,默认值为false,最后一个false表示按钮形式pangolin::Var<double> a_double("ui.A_Double", 3, 0, 5);//设置一个double的、可拖动变换值的玩意(不知道咋形容)!pangolin::Var<int> a_int("ui.A_Int", 2, 0, 5);//设置一个int的、可拖动变换值的玩意pangolin::Var<std::function<void(void)>> reset("ui.Reset", function);//设置一个按钮,用于调用function函数while( !pangolin::ShouldQuit() ){glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);d_cam.Activate(s_cam);if (pangolin::Pushed(a_button)){//如果a_button按钮被点,就运行if里面的语句std::cout << "You tough a_buttom" << std::endl;a_double = 0;a_int = 0;}glColor3f(1.0, 1.0, 1.0);pangolin::glDrawColouredCube();pangolin::FinishFrame();}return 0;
}

运行上面的代码,你会获得如下图所示的界面,试着点击左边的按钮,看看你的终端出现了什么。

3.4 多窗口显示

下面的代码,前面几乎都出现过了,就不在细致解释了。

#include <iostream>
#include <pangolin/pangolin.h>void setImageData(unsigned char * imageArray, int size){for(int i = 0 ; i < size;i++) {imageArray[i] = (unsigned char)(rand()/(RAND_MAX/255.0));}
}int main(/*int argc, char* argv[]*/)
{pangolin::CreateWindowAndBind("Main",640,480);glEnable(GL_DEPTH_TEST);glEnable (GL_BLEND);glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);pangolin::OpenGlMatrix proj = pangolin::ProjectionMatrix(640,480,420,420,320,240,0.1,1000);pangolin::OpenGlRenderState s_cam(proj, pangolin::ModelViewLookAt(1,0.5,-2,0,0,0, pangolin::AxisY) );pangolin::OpenGlRenderState s_cam2(proj, pangolin::ModelViewLookAt(0,0,-2,0,0,0, pangolin::AxisY) );pangolin::View& d_cam1 = pangolin::Display("cam1").SetAspect(640.0f/480.0f).SetHandler(new pangolin::Handler3D(s_cam));pangolin::View& d_cam2 = pangolin::Display("cam2").SetAspect(640.0f/480.0f).SetHandler(new pangolin::Handler3D(s_cam2));pangolin::View& d_cam3 = pangolin::Display("cam3").SetAspect(640.0f/480.0f).SetHandler(new pangolin::Handler3D(s_cam));pangolin::View& d_cam4 = pangolin::Display("cam4").SetAspect(640.0f/480.0f).SetHandler(new pangolin::Handler3D(s_cam2));pangolin::View& d_img1 = pangolin::Display("img1").SetAspect(640.0f/480.0f);pangolin::View& d_img2 = pangolin::Display("img2").SetAspect(640.0f/480.0f);pangolin::Display("multi").SetBounds(0.0, 1.0, 0.0, 1.0).SetLayout(pangolin::LayoutEqual).AddDisplay(d_cam1).AddDisplay(d_img1).AddDisplay(d_cam2).AddDisplay(d_img2).AddDisplay(d_cam3).AddDisplay(d_cam4);const int width =  64;const int height = 48;unsigned char* imageArray = new unsigned char[3*width*height];pangolin::GlTexture imageTexture(width,height,GL_RGB,false,0,GL_RGB,GL_UNSIGNED_BYTE);while( !pangolin::ShouldQuit() ){glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);setImageData(imageArray,3*width*height);imageTexture.Upload(imageArray,GL_RGB,GL_UNSIGNED_BYTE);glColor3f(1.0,1.0,1.0);d_cam1.Activate(s_cam);pangolin::glDrawColouredCube();d_cam2.Activate(s_cam2);pangolin::glDrawColouredCube();d_cam3.Activate(s_cam);pangolin::glDrawColouredCube();d_cam4.Activate(s_cam2);pangolin::glDrawColouredCube();d_img1.Activate();glColor4f(1.0f,1.0f,1.0f,1.0f);imageTexture.RenderToViewport();d_img2.Activate();glColor4f(1.0f,1.0f,1.0f,1.0f);imageTexture.RenderToViewport();pangolin::FinishFrame();}delete[] imageArray;return 0;
}

运行代码之后,可以获得如下效果。

3.5 多线程

以下代码完成的任务是,新开一个线程,然后显示一个立方体。

#include <pangolin/pangolin.h>
#include <thread>static const std::string window_name = "HelloPangolinThreads";void setup() {pangolin::CreateWindowAndBind(window_name, 640, 480);glEnable(GL_DEPTH_TEST);pangolin::GetBoundWindow()->RemoveCurrent();//setup()函数是在主线程创建的,因此在主线程调用完之后,需要使用GetBoundWindow()->RemoveCurrent()对其解绑
}void run() {pangolin::BindToContext(window_name);glEnable(GL_DEPTH_TEST);pangolin::OpenGlRenderState s_cam(pangolin::ProjectionMatrix(640,480,420,420,320,240,0.2,100),pangolin::ModelViewLookAt(-2,2,-2, 0,0,0, pangolin::AxisY));pangolin::Handler3D handler(s_cam);pangolin::View& d_cam = pangolin::CreateDisplay().SetBounds(0.0, 1.0, 0.0, 1.0, -640.0f/480.0f).SetHandler(&handler);while( !pangolin::ShouldQuit() ){glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);d_cam.Activate(s_cam);pangolin::glDrawColouredCube();pangolin::FinishFrame();}pangolin::GetBoundWindow()->RemoveCurrent();
}int main()
{setup();std::thread render_loop;//新建一个线程render_loop = std::thread(run);//然后将函数run加载到线程中render_loop.join();return 0;
}

4 总结

Pangolin确实是一个很简单好用的3D显示库,加上GUI的一些交互操作简直飞起。如果你不会使用ROS或者闲ROS运行麻烦,使用Pangolin显示一些3D效果十分方便。

我相信看完我上面的总结的一些代码和用法,你基本已经掌握了Pangolin编程的思路了。如果你还有别的要求,或者本文的内容不能满足你的要求,你可以参考Pangolin官方例程进行学习。

Pangolin官方example:
https://github.com/stevenlovegrove/Pangolin/tree/master/examples

3D绘图程序库Pangolin安装以及快速入门,使用教程介绍详细,使用Pangolin绘制点云、直线、轨迹等,设置按钮,进行多窗口、多线程操作,以及Pangolin怎么使用等等相关推荐

  1. Tushare介绍、安装及快速入门

    Tushare介绍.安装及快速入门 Tushare是一个免费.开源的python财经数据接口包.主要实现对股票等金融数据从数据采集.清洗加工 到 数据存储的过程,能够为金融分析人员提供快速.整洁.和多 ...

  2. 虚幻引擎5:快速入门学习教程

    流派:电子学习| MP4 |视频:h264,1280×720 |音频:AAC,48.0 KHz 语言:英语+中英文字幕(根据原英文字幕机译更准确)|大小解压后:5.63 GB |时长:5h 23m 从 ...

  3. Python 程序设计快速入门简易教程

    Python 程序设计快速入门简易教程 Python语言快速检索 一些需要知道的事 一个简单的Python程序 Python的基本数据类型 Python的基本运算符 Python的常用函数 impor ...

  4. 教你快速入门ElasticSearch,超详细简单~

    教你快速入门ElasticSearch,超详细简单~ 一. 初探ElasticSearch 1.1 什么是ElasticSearch? ElasticSearch,简称为ES,它是一个开源的高扩展的分 ...

  5. Py之GUI之PyQt:PyQt5的简介、入门、安装(QtCreator和QtDesigner)图文教程之详细攻略

    Py之GUI之PyQt:PyQt5的简介.入门.安装(QtCreator和QtDesigner)图文教程之详细攻略 目录 PyQt的简介 1.Qt特点 2.QT中QT Widgets Applicat ...

  6. Python 零基础 快速入门 趣味教程 (咪博士 海龟绘图 turtle) 4. 函数

    什么样的程序员才是优秀的程序员?咪博士认为"慵懒"的程序员才是真正优秀的程序员.听起来不合逻辑?真正优秀的程序员知道如何高效地工作,而不是用不止境的加班来完成工作任务.函数便是程序 ...

  7. python海龟教程_Python 零基础 快速入门 趣味教程 (咪博士 海龟绘图 turtle) 7. 条件循环...

    条件循环能够让程序在条件成立时(即为真时)重复执行循环体中的语句.如果条件一直成立(即永远不会为假),则循环会一直进行下去,不会停止.如果初始时,条件不成立,则循环 1 次也不会执行.Python 中 ...

  8. Html快速入门之基本介绍

    Html快速入门之基本介绍 1. Html快速入门之基本介绍 1.1 网页组成 1.2 浏览器内核 1.3 Web标准 1.4 Html概念 1.5 超文本的含义 1.6 Html骨架标签 1.7 H ...

  9. Python测试框架pytest(01)简介、安装、快速入门

    1.简介 pytest 是成熟的功能齐全的 Python 测试工具,可帮助你编写更好的程序. pytest 是一个使构建简单和可伸缩的测试变得容易的框架.测试具有表达性和可读性,不需要样板代码.几分钟 ...

最新文章

  1. 华为提出DyNet:动态卷积
  2. CentOS LAMP一键安装网站环境及添加域名
  3. C++二叉树的建立与遍历
  4. 好好学python · 内置函数(range(),zip(),sorted(),map(),reduce(),filter())
  5. 深度学习核心技术精讲100篇(四十二)-Seq2seq框架下的文本生成
  6. wing IDE常用快捷键
  7. Android不是内部或外部指令
  8. java数组扩容arraylist,ArrayList--扩容机制
  9. JAVA实现概率计算(数字不同范围按照不同几率产生随机数)
  10. zabbix mysql pgsql_Zabbix 5.0 监控 PostgreSQL 数据库
  11. 前端 -- jQuery
  12. java verbose gc_java –verbose:gc
  13. sql函数RIGHT的简单用法
  14. 2021年过了大半了,脑机接口取得哪些进展?
  15. Mac端口5000被ControlCe占用问题解决方法
  16. 积微——荀子《强国篇》,给每个职场人士推荐
  17. SQL语法之分组函数,分组查询(进阶5)and连接查询(sql92语法进阶6)
  18. MP4文件批量转码成MP3
  19. 人人可以是好厨子:72招做饭技巧帮你变大厨
  20. JS sort函数(按照首字母字符排序)

热门文章

  1. 微信Hook实战记录2:动手实现恶意dll内存插入器
  2. JAVA计算机毕业设计学籍管理系统Mybatis+源码+数据库+lw文档+系统+调试部署
  3. “创新实践”项目介绍3:《利用深度学习进行VR手柄光点检测》
  4. 殇一曲、谁伴我地老天荒
  5. [计算机网络]交换机VLAN的作用和原理
  6. 机器学习实践:超市商品购买关联规则分析
  7. 狭窄及隐蔽地下空洞三维探测系统的研制
  8. Apache Pulsar的Function流式计算框架使用
  9. 科思创筹建上海新工厂;宝投集团与通快签约大湾区激光应用研发中心项目 | 能动...
  10. 韭菜投资ABC:如何判断当前指数便宜还是贵(PE百分位法)