视框控件
在视窗的基础上,可选择添加控制组件用于完成操作。基础的控件有按钮、滑条、单选框、字符串信息等。
构建相机
首先,构建一个Pangolin相机对象:
#include <string>
#include <iostream>
#include "main.h"
int main()
{
/*-------- 构建Pangolin相机 --------*/
// 视窗
pangolin::CreateWindowAndBind("Viewer",640,480);
// 启动深度测试
glEnable(GL_DEPTH_TEST);
// 相机
pangolin::OpenGlRenderState s_cam(
pangolin::ProjectionMatrix(640,480,420,420,320,240,0.1,1000),
pangolin::ModelViewLookAt(-1,1,-1, 0,0,0, pangolin::AxisY)
);
while( !pangolin::ShouldQuit() )
{
// 清空颜色、深度缓存区
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// 背景颜色
glClearColor(0.1f, 0.2f, 0.3f, 0.3f);
// 激活相机对象
d_cam.Activate(s_cam);
// 帧循环
pangolin::FinishFrame();
}
return 0;
}
构建控制面板、交互视图
控制面板的构建使用如下语句进行:
pangolin::CreatePanel(const std::string& name)
.SetBounds(Attach bottom, Attach top, Attach left, Attach right);
name
:控制面板的Tag名称panel_tag
SetBounds
:设置控制面板的大小、位置
一般将控制面板放置在视窗的左侧,而将交互式图放置在视窗的右侧:
// 交互视图同控制面板分界
const int UI_WIDTH = 180;
// 右侧:交互视图
pangolin::View& d_cam = pangolin::CreateDisplay()
.SetBounds(0.0, 1.0, pangolin::Attach::Pix(UI_WIDTH), 1.0, -640.0f/480.0f)
.SetHandler(new pangolin::Handler3D(s_cam));
// 左侧:控制面板
pangolin::CreatePanel("ui")
.SetBounds(0.0, 1.0, 0.0, pangolin::Attach::Pix(UI_WIDTH));
此处,定义一个常量UI_WITH
作为两者的分界面,随后使用pangolin::Attach::Pix()
获得对应的像素信息。设置控制面板Tag名称为ui
,实现效果如下:
构建基础控件
Pangolin将所有“控件”视为一个对象pangolin::Var
,可用于构建按钮、滑条、控制对象、信息显示等内容:
按钮
按钮控件为Bool类型,无法反转的控件:
pangolin::Var<bool> Button(const std::string& name, const bool& value, bool toggle);
name
:按钮控件的Tag,填写格式:panel_tag.controller_tag
value
:控件默认值toggle
:控件是否可以反转,按钮控件应填写false
例如,实现一个按钮:
pangolin::Var<bool> A_Button("ui.a_button", false, false);
效果如下:
单选框
单选框控件为Bool类型,可以反转的控件:
pangolin::Var<bool> A_Checkbox(const std::string& name, const bool& value, bool toggle);
name
:按钮控件的Tag,填写格式:panel_tag.controller_tag
value
:控件默认值toggle
:控件是否可以反转,单选框控件应填写true
例如,实现一个单选框对象:
pangolin::Var<bool> A_Checkbox("ui.a_checkbox", false, true);
效果如下:
滑动条对象
滑动条对象为数值型对象::
pangolin::Var<T> Double_Slider(const std::string& name, const T& value,
double min, double max, bool logscale = false);
T
:数值类型,可选int、double、float
型name
:控件的Tag,填写格式:panel_tag.controller_tag
value
:控件的默认值min、max
:滑动条的最小、最大取值,默认0~1logscale
:是否以对数坐标形式显示
例如,实现一个Double类型滑动条对象:
pangolin::Var<double> Double_Slider("ui.a_slider", 3, 0, 5);
效果如下:
消息对象
消息显示为std::string
类型对象:
pangolin::Var<std::string> A_string(const std::string& name, const std::string& value = std::string() )
name
:控件的Tag,填写格式:panel_tag.controller_tag
value
:被显示的消息内容
例如,构建一个消息显示对象:
pangolin::Var<std::string> A_string("ui.a_string", "Hello Pangolin");
效果如下:
基础控件回调
构建控件的目的是为了进行不同的控制,由此应实现控件的回调
按钮
按钮控件应被监听,当按钮按下时进行指定操作,使用如下函数监听按钮状态
pangolin::Pushed(A_Button)
单选框
单选框控件为bool类型,只需要检测其值是否为true即可
滑动条
滑动条控件为数值型,可直接获取到当前值。
综合
由此,完成对控件的构建:
#include <string>
#include <iostream>
#include "main.h"
int main()
{
/*-------- 构建Pangolin相机 --------*/
// 视窗
pangolin::CreateWindowAndBind("Viewer",640,480);
// 启动深度测试
glEnable(GL_DEPTH_TEST);
// 相机
pangolin::OpenGlRenderState s_cam(
pangolin::ProjectionMatrix(640,480,420,420,320,240,0.1,1000),
pangolin::ModelViewLookAt(-1,1,-1, 0,0,0, pangolin::AxisY)
);
// 交互视图同控制面板分界
const int UI_WIDTH = 180;
// 右侧:交互视图
pangolin::View& d_cam = pangolin::CreateDisplay()
.SetBounds(0.0, 1.0, pangolin::Attach::Pix(UI_WIDTH), 1.0, -640.0f/480.0f)
.SetHandler(new pangolin::Handler3D(s_cam));
// 左侧:控制面板
pangolin::CreatePanel("ui")
.SetBounds(0.0, 1.0, 0.0, pangolin::Attach::Pix(UI_WIDTH));
/* -------- 构建控件 -------- */
// 按钮对象
pangolin::Var<bool> A_Button("ui.a_button", false, false);
// 单选框对象
pangolin::Var<bool> A_Checkbox("ui.a_checkbox", false, true);
// 滑条,Double型
pangolin::Var<double> Double_Slider("ui.a_slider", 3, 0, 5);
// 滑条,Int型
pangolin::Var<double> Int_Slider("ui.int_slider", 3, 0, 5);
// 字符串
pangolin::Var<std::string> A_string("ui.a_string", "Hello Pangolin");
// 按钮,保存视框
pangolin::Var<bool> SAVE_WIN("ui.save_win", false, false);
while( !pangolin::ShouldQuit() )
{
// 清空颜色、深度缓存区
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// 背景颜色
glClearColor(0.1f, 0.2f, 0.3f, 0.3f);
/*-------- 控件回调函数 --------*/
// 按钮
if (pangolin::Pushed(A_Button)) { std::cout << "Push button A." << std::endl; }
// 单选框
if (A_Checkbox) { Int_Slider = (int) Double_Slider; }
// 按钮,保存图像
if (pangolin::Pushed(SAVE_WIN)) { pangolin::SaveWindowOnRender("window"); }
// 激活相机对象
d_cam.Activate(s_cam);
/*-------- 绘制图像 --------*/
pangolin::glDrawColouredCube();
// 帧循环
pangolin::FinishFrame();
}
return 0;
}
效果如下:
其他控件
函数按钮回调
pangolin::Var<std::function<void()>> (const std::string& name, std::function<void(void)> func)
name
:控件的Tag,填写格式:panel_tag.controller_tag
func
:控件对应的函数
此类按钮控件,当按钮被按下时,将执行func
函数。
快捷键绑定
pangolin::RegisterKeyPressCallback(int key, std::function<void(void)> func);
快捷键绑定控件用于绑定键盘上的按钮,单按下固定的按钮时,将触发指定的func
。
例如使用ctrl+r
执行函数:
pangolin::RegisterKeyPressCallback(pangolin::PANGO_CTRL + 'r', SampleMethod);
键盘上的特殊键位,可在pangolin中使用对应常量调用:
const int PANGO_SPECIAL = 128;
const int PANGO_CTRL = -96;
const int PANGO_OPTN = 132;
// Ordinary keys
const int PANGO_KEY_TAB = 9;
const int PANGO_KEY_ESCAPE = 27;
// Special Keys (same as GLUT_ defines)
const int PANGO_KEY_F1 = 1;
const int PANGO_KEY_F2 = 2;
const int PANGO_KEY_F3 = 3;
const int PANGO_KEY_F4 = 4;
const int PANGO_KEY_F5 = 5;
const int PANGO_KEY_F6 = 6;
const int PANGO_KEY_F7 = 7;
const int PANGO_KEY_F8 = 8;
const int PANGO_KEY_F9 = 9;
const int PANGO_KEY_F10 = 10;
const int PANGO_KEY_F11 = 11;
const int PANGO_KEY_F12 = 12;
const int PANGO_KEY_LEFT = 100;
const int PANGO_KEY_UP = 101;
const int PANGO_KEY_RIGHT = 102;
const int PANGO_KEY_DOWN = 103;
const int PANGO_KEY_PAGE_UP = 104;
const int PANGO_KEY_PAGE_DOWN = 105;
const int PANGO_KEY_HOME = 106;
const int PANGO_KEY_END = 107;
const int PANGO_KEY_INSERT = 108;
综合
#include <string>
#include <iostream>
#include "main.h"
int main()
{
/*-------- 构建Pangolin相机 --------*/
// 视窗
pangolin::CreateWindowAndBind("Viewer",640,480);
// 启动深度测试
glEnable(GL_DEPTH_TEST);
// 相机
pangolin::OpenGlRenderState s_cam(
pangolin::ProjectionMatrix(640,480,420,420,320,240,0.1,1000),
pangolin::ModelViewLookAt(-1,1,-1, 0,0,0, pangolin::AxisY)
);
// 交互视图同控制面板分界
const int UI_WIDTH = 180;
// 右侧:交互视图
pangolin::View& d_cam = pangolin::CreateDisplay()
.SetBounds(0.0, 1.0, pangolin::Attach::Pix(UI_WIDTH), 1.0, -640.0f/480.0f)
.SetHandler(new pangolin::Handler3D(s_cam));
// 左侧:控制面板
pangolin::CreatePanel("ui")
.SetBounds(0.0, 1.0, 0.0, pangolin::Attach::Pix(UI_WIDTH));
/* -------- 构建控件 -------- */
// 按钮对象
pangolin::Var<bool> A_Button("ui.a_button", false, false);
// 单选框对象
pangolin::Var<bool> A_Checkbox("ui.a_checkbox", false, true);
// 滑条,Double型
pangolin::Var<double> Double_Slider("ui.a_slider", 3, 0, 5);
// 滑条,Int型
pangolin::Var<double> Int_Slider("ui.int_slider", 3, 0, 5);
// 字符串
pangolin::Var<std::string> A_string("ui.a_string", "Hello Pangolin");
// 按钮,保存视框
pangolin::Var<bool> SAVE_WIN("ui.save_win", false, false);
// 按钮,函数触发
pangolin::Var<std::function<void()>> reset("ui.Reset", SampleMethod);
// 绑定键盘快捷键
pangolin::RegisterKeyPressCallback(pangolin::PANGO_CTRL + 'b', pangolin::SetVarFunctor<double>("ui.a_slider", 3.5));
pangolin::RegisterKeyPressCallback(pangolin::PANGO_CTRL + 'r', SampleMethod);
while( !pangolin::ShouldQuit() )
{
// 清空颜色、深度缓存区
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// 背景颜色
glClearColor(0.1f, 0.2f, 0.3f, 0.3f);
/*-------- 控件回调函数 --------*/
//
if (pangolin::Pushed(A_Button)) { std::cout << "Push button A." << std::endl; }
if (A_Checkbox) { Int_Slider = (int) Double_Slider; }
// 按钮,保存图像回调函数实现
if (pangolin::Pushed(SAVE_WIN)) { pangolin::SaveWindowOnRender("window"); }
// 激活相机对象
d_cam.Activate(s_cam);
/*-------- 绘制图像 --------*/
pangolin::glDrawColouredCube();
// 帧循环
pangolin::FinishFrame();
}
return 0;
}
void SampleMethod()
{
std::cout << "You typed ctrl-r or pushed reset" << std::endl;
}
此时,按下Ctrl+R
触发函数SampleMethod
;按下Ctrl+B
触发函数保存图像。同时,pangolin默认定义按下按键ESC
退出程序,Tab
全屏化。