pangolin-task1
作者:互联网
说明
这是在yuntian_li的博客基础上,添加了一些自己的理解。
原文章 :https://blog.csdn.net/weixin_43991178/article/details/105119610
代码库 :https://github.com/yuntianli91/pangolin_tutorial
Task1
创建一个交互窗口,并在窗口中显示一个立方体和对应的坐标系,代码如下
#include <pangolin/pangolin.h>
int main( int /*argc*/, char** /*argv*/ )
{
// 创建名称为“Main”的GUI窗口,尺寸为640×640
pangolin::CreateWindowAndBind("Main",640,480);
// 启动深度测试
glEnable(GL_DEPTH_TEST);
// 创建一个观察相机视图
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::glDrawColouredCube();
// 绘制坐标系
glLineWidth(3);
glBegin ( GL_LINES );
glColor3f ( 0.8f,0.f,0.f );
glVertex3f( -1,-1,-1 );
glVertex3f( 0,-1,-1 );
glColor3f( 0.f,0.8f,0.f);
glVertex3f( -1,-1,-1 );
glVertex3f( -1,0,-1 );
glColor3f( 0.2f,0.2f,1.f);
glVertex3f( -1,-1,-1 );
glVertex3f( -1,-1,0 );
glEnd();
// 运行帧循环以推进窗口事件
pangolin::FinishFrame();
}
return 0;
}
逐行解析
#include <pangolin/pangolin.h>
pangolin几乎所有的功能都在pangolin.h
头文件中。
pangolin::CreateWindowAndBind("Main",640,480);
创建一个640x480的窗体,名字为"Main"。这只是窗体的初始形态,生成后的窗体可以缩放大小。
glEnable(GL_DEPTH_TEST);
GL_DEPTH_TEST用来开启更新深度缓冲区的功能。也就是说,如果深度值发生了变化,会更新深度缓冲区。它只会绘制朝向镜头那面的图像,避免容易混淆的透视关系。在3D可视化时,都应该开启这个功能。
// 观察相机的内参,参数依次为观察相机的图像高度、宽度、4个内参以及最近和最远视距
// ProjectionMatrix(int w, int h, GLprecision fu, GLprecision fv, GLprecision u0, GLprecision v0, GLprecision zNear, GLprecision zFar )
// 观察相机的位姿,相对于世界坐标系
// 参数依次为相机所在的位置,以及相机所看的视点位置(一般会设置在原点)
// ModelViewLookAt(GLprecision ex, GLprecision ey, GLprecision ez, GLprecision lx, GLprecision ly, GLprecision lz, AxisDirection up)
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)
);
创建观察相机s_cam。观察相机的作用是将它看到的景象渲染到窗口(窗口和窗体不同,后面解释)上。相机需要设置内参和观察位置。内参用来将场景透视变换为图像。观察位置好理解,重点解释相机位姿。
相机的位置点和视点定义相机的z轴。up指定一个世界坐标系的方向轴,与z轴叉乘确定相机的x方向。再用z和x确定y方向。源代码在 ModelViewLookAt 和 ModelViewLookAtRUB。这样产生的效果是,世界坐标系的三个轴都可以看到,并且位于图像底部,上部空间用来显示物体。指定不同的up(也就是世界坐标系的某个轴),对应世界坐标系的那个轴在窗口中是竖着显示的。
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);
handler是用户操作事件的类,没有这个就无法操作窗口了,注释掉.SetHandler(&handler)
试一下。
d_cam实际上就是一个能够适应窗体大小的图像,我们给他起个名字,叫窗口。那么就好理解SetBounds的参数了,前四个参数是比例值,能够同时定义窗口在窗体中的位置及尺寸。如果窗体的大小为 H x W ( 高 宽),那么四个参数 ( bottom x H, top x H, left x W, right x W),就可以确定窗口的位置和大小。最后一个参数这里是分辨率,如果窗体尺寸不变,那么分辨率固定没有问题。如果窗体尺寸可变就有问题了,会造成窗口质量不一样,可以用bool值代替,自动适应窗体变化。
while( !pangolin::ShouldQuit() )
{
转起来。
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
先清空上一帧的buffer(实际就是上一次循环的)。这里清空了颜色和深度信息。下面就是要重新生成新的信息。
d_cam.Activate(s_cam);
激活相机,开始录像啦,还没有按快门的状态。
下面开始布置场景
pangolin::glDrawColouredCube();
放一个彩色的立方体进来。
glLineWidth(3);
glBegin ( GL_LINES );
glColor3f ( 0.8f,0.f,0.f );
glVertex3f( -1,-1,-1 );
glVertex3f( 0,-1,-1 );
glColor3f( 0.f,0.8f,0.f);
glVertex3f( -1,-1,-1 );
glVertex3f( -1,0,-1 );
glColor3f( 0.2f,0.2f,1.f);
glVertex3f( -1,-1,-1 );
glVertex3f( -1,-1,0 );
glEnd();
放一个坐标系进来。
场景布置完成。准备咔嚓
pangolin::FinishFrame();
咔嚓一下,相机开始工作,对场景进行透视变换、渲染、事件处理等等,最后呈现到窗口上。
标签:task1,glVertex3f,pangolin,相机,GLprecision,cam,窗体 来源: https://blog.csdn.net/m0_48174347/article/details/121657181