其他分享
首页 > 其他分享> > pangolin-task1

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