Pangolin学习
分类:pc28.am神测网

0.1. 资料

泡沫机器人

github example

opengl中录制机的职分,寓指标大势

gluLookAt函数

图片 1

刚开始上学opengl,做的首先个实验,就是显示圆柱体

图片 2

0.2. 利用验证

使用那些gluLookAt矩阵坐标观望矩阵能够很迅猛地把富有世界坐标调换为调查坐标LookAt矩阵

find_package(Pangolin REQUIRED)
include_directories(${Pangolin_INCLUDE_DIRS})

target_link_libraries(pangolin_test ${Pangolin_LIBRARIES})

Github 下有个example有点例子,简单的参照他事他说加以调查着写,复杂的评估价值需求查opengl.

其一通过opengl库中的api函数gluCylinder()就能够来得出来,可是最为蛋疼的是,完全看不出它是四个圆柱啊

timg.jpeg

0.3. HelloPangolin

#include <iostream>
#include <pangolin/pangolin.h>

int main(int argc, char **argv)
{
    //创建一个窗口
    pangolin::CreateWindowAndBind("Main",640,480);
    //启动深度测试
    glEnable(GL_DEPTH_TEST);

    // Define Projection and initial ModelView matrix
    pangolin::OpenGlRenderState s_cam(
            pangolin::ProjectionMatrix(640,480,420,420,320,240,0.2,100),
            //对应的是gluLookAt,摄像机位置,参考点位置,up vector(上向量)
            pangolin::ModelViewLookAt(0,-10,0.1,0,0,0,pangolin::AxisNegY)
    );

    // Create Interactive View in window
    pangolin::Handler3D handler(s_cam);
    //setBounds 跟opengl的viewport 有关
    //看SimpleDisplay中边界的设置就知道
    pangolin::View &d_cam = pangolin::CreateDisplay().SetBounds(0.0,1.0,0.0,1.0,-640.0f/480.0f)
                            .SetHandler(&handler);

    while(!pangolin::ShouldQuit())
    {
        // Clear screen and activate view to render into
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        d_cam.Activate(s_cam);

        // Render OpenGL Cube
//        pangolin::glDrawColouredCube();
        //坐标轴的创建
        pangolin::glDrawAxis(3);

        //点的创建
        glPointSize(10.0f);
        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();

        //把下面的点都做一次旋转变换
        glPushMatrix();
        //col major
        std::vector<GLfloat > Twc = {1,0,0,0, 0,1,0,0 , 0,0,1,0 ,0,0,5,1};
        glMultMatrixf(Twc.data());

        //直线的创建
        const float w = 2;
        const float h = w*0.75;
        const float z = w*0.6;
        glLineWidth(2);
        glColor3f(1.0,0,0);
        glBegin(GL_LINES);

        glVertex3f(0,0,0);
        glVertex3f(w,h,z);
        glVertex3f(0,0,0);
        glVertex3f(w,-h,z);
        glVertex3f(0,0,0);
        glVertex3f(-w,-h,z);
        glVertex3f(0,0,0);
        glVertex3f(-w,h,z);
        glVertex3f(w,h,z);
        glVertex3f(-w,h,z);
        glVertex3f(-w,h,z);
        glVertex3f(-w,-h,z);
        glVertex3f(-w,-h,z);
        glVertex3f(w,-h,z);
        glVertex3f(w,-h,z);
        glVertex3f(w,h,z);
        glEnd();

        glPopMatrix();

        // Swap frames and Process Events
        pangolin::FinishFrame();
    }

    return 0;

}

尽管如此能够由此reshape()来再一次定视角,不过每一遍运路程序,只可以突显多少个见识,多辛劳啊。

名词解释

pipleline:管线
opengl applocation: geometry(几何图形) texture(纹理贴图)
vertex data(极点数据):lighting(光照) transform(调换) scale(缩放)
geometry: rasterization(光栅) clipping(剪裁)
fragment(段): fog(雾) texture
framebuffer(帧缓冲区): stecil(蒙版卡塔 尔(阿拉伯语:قطر‎ z-test:深度测量试验 阿尔法:透明 blending(混合)
eyeball(眼球)

近平面
远平面
frustum:平截头体,视景体(远近平面之间的台式)
伪变换
GLSurfaceView:GL表层视图输出openGL画面包车型客车控件
render: 渲染器,绘制openGL 的类
viewPort : 视口,输出画面的区域
matrix:矩阵

投影:
透视投影:有深度,越远越小(站在铁轨,远处线相交 卡塔 尔(阿拉伯语:قطر‎
正投影:未有深度概念,相近大小
状态机

gl.glMatrixModel(int n):矩阵情势,openGL基于状态的,垄断(monopoly卡塔尔非常多矩阵,通过该函数钦定使用哪个矩阵
如:GL10.GL_PROJECTION 投影矩阵
GL10.GL_MODELVIEW 模态视图矩阵
点名哪个矩阵之后,须求先加载单位矩阵(gl.glLoadIdentity() 肖似于矩阵清零)

gl.glFrustumf(,,,,,,)
//参数
left:左边间隔
right:
bottom
top
zNear:近平面间距
zFar:远平面间隔

设置眼睛的地点
//眼球的坐标,观察的点,向上的向量
//操作的是模型视图矩阵,要求先安装gl.glMatrixMode(GL10.GL_MODELVIEW);
gluLookAt(GL10 gl, float eyeX, float eyeY, float eyeZ, float centerX, float centerY, float centerZ, float upX, float upY, float upZ)

率先组eyex, eyey,eyez 相机在世界坐标的岗位
第二组centerx,centery,centerz 相机镜头照准的实体在世界坐标的岗位
其三组upx,upy,upz 相机向上的倾向在世界坐标中的方向
您把相机想象变为你协和的脑瓜儿:
第一组数据就是尾部的任务
其次组数据正是双目看的物体的岗位
其三组正是尾部朝向的倾向(因为你能够歪着头看同贰个物体卡塔 尔(阿拉伯语:قطر‎
参考:http://www.cnblogs.com/jiangu66/archive/2013/04/06/3003122.html
1.背后的多少个参数(0.0,1.0,0.0),y轴为1,别的为0,表示脑袋朝上,就是例行的事态

图片 3

timg.jpeg


如此表示脑袋向下,即人眼倒着看

图片 4

timg.jpeg


即人的头颅像右歪90度来看,即顺时针转90度(换个角度思考就是壶逆时针转90度卡塔 尔(阿拉伯语:قطر‎

图片 5

timg.jpeg

0.4. Plot data with ros

参照SimplePlot, !pangolin::ShouldQuit()换成ros::ok(),就可以

参照SimpleDisplay, 能够做出抉择配置

率先个想做的正是解决录制机难题,让大家能够由此鼠标键盘交互作用,达成360度旋转和扩充裁减。

使用OpenGL步骤

  • 1.创建GLSurfaceView对象
  • 2.创建GLSurfaceView.render实现类
  • 3.设置activity的contentview,以致安装view的render对象
  • 4.兑现render类的进程
    a.onSurfaceCreated()方法
    1.设置清屏的水彩和启用顶点缓冲区
    b.onSurfaceChanged()方法
    1.设置viewPort(视口)
    2.操作投影矩阵,设置平截头体(比例平日和视口比例相通,不然输出画面会走样卡塔尔国
    c.onDrawFrame()方法
    1.扫除颜色缓冲区
    gl.glClearColor(0,0,0,1);
    2.操作模型视图矩阵,设置眼球的参数
    gl.glMatrixMode(GL10.GL_MODELVIEW);
    gl.glLoadIdentity();
    GLU.gluLookAt(gl,0,0,0,0,0,5,0,1,0);
    3.概念图形极点坐标值数组
    4.将极点坐标转换来缓冲区数据
    5.安装绘图颜色
    6.内定极点缓冲区指针
    //3.象征3维点,使用多少个坐标值表示叁个点
    //type:GL10.GL_FLOAT 各个点的数据类型
    //stride:0,跨度
    gl.glVertexPointer(3,GL10.GL_FLOAT,0,ibb);
    7.绘图
    //3. 点的数额
    //0. 起始点
    gl.glDrawArrays(GL10.GL_TRIANGLES,0,3);

 

opengl中的投影有三种,四个是(平行投影卡塔 尔(英语:State of Qatar),一个是(透视投影卡塔尔

(透视投影卡塔尔相符大家心思习惯,近大远小

为此以下的求证都以基于(透视投影卡塔尔的。 ps:其实作者还不懂平行投影

 

  1. 利用透视投影

先是main函数中增添

    glutReshapeFunc(reshape);

参数reshape()是函数名,接下去是reshape()函数

void reshape(int w, int h)
{
    glViewport(0, 0, (GLsizei)w, (GLsizei)h);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();

    gluPerspective(60.0, (GLfloat)w / (GLfloat)h, 1.0, 20.0);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    gluLookAt(5.0, 5.0, 5.0, 0.0, 0.0, 0.0, 0, 1, 0);
}

而gluLookAt()函数,其实您能够清楚成录像机,

前3个参数是您的肉眼,中间3个参数是你望着的地点,最终3个参数是您的相机的正上方

切实表明能够参见那位大佬的文章

 

 

个人驾驭,gluLookAt()定义了叁个视景矩阵,把(世界坐标系卡塔 尔(英语:State of Qatar)调换来(摄像机坐标系卡塔尔国,

然后由(录制机坐标系卡塔 尔(阿拉伯语:قطر‎来评释(世界坐标系卡塔 尔(阿拉伯语:قطر‎中物体的坐标。

具体转变表达,能够参见

以下网站

 或然本人写的数学根底知识03

 

2.矩阵调换

opengl中援助使用编写的uvn视景矩阵。

始建七个Point类(点卡塔尔国,创设一个Vector类(向量卡塔 尔(英语:State of Qatar),创设三个Camera类(摄像机卡塔尔

依靠gluLookAt()的9个参数,大家同样能够总计出相应的uvn坐标系

优先表明,那个摄像机是以世界坐标系(0, 0, 0)为核心来360度移动的,所以假设转换了着力,之后的函数都要做相对应的更改。

void setCamera(float eyex, float eyey, float eyez,
                   float centerx, float centery, float centerz,
                   float upx, float upy, float upz) 
    {
        eye.set(eyex, eyey, eyez);
        center.set(centerx, centery, centerz);
        up.setV(upx, upy, upz);

        n.setV(center, eye);
        n.normalize();
        u = n.cross(up);
        u.normalize();
        v = u.cross(n);
        v.normalize();

        R = eye.getDist();

        setModeViewMatrix();
    }

center那么些点必须是(0, 0, 0);

假定不是(0,0,0),前面旋转函数要做相对应的改变

参数表达:

eye是世界坐标系的点,坐标系调换涉及到了运动,所以必得保留下来。

Rubicon是视点中央到摄影机的离开,

函数表明:

normalize()是标准化函数,即令向量的模变为1

cross()是叉乘函数,即求出四个不平行向量决定的平面包车型地铁(法向量卡塔 尔(阿拉伯语:قطر‎。

说起底目标是使uvn两两笔直。

 

然后是矩阵设置

void setModeViewMatrix() {
        Vector pointV(eye.x, eye.y, eye.z);
        M[0] = u.x; M[1] = v.x; M[2] = -n.x; M[3] = 0;
        M[4] = u.y; M[5] = v.y; M[6] = -n.y; M[7] = 0;
        M[8] = u.z; M[9] = v.z; M[10] = -n.z; M[11] = 0;
        M[12] = -pointV.dot(u);
        M[13] = -pointV.dot(v);
        M[14] = pointV.dot(n);
        M[15] = 1;

        glMatrixMode(GL_MODELVIEW);
        glLoadIdentity();
//        gluLookAt(5.0, 5.0, 5.0, 0.0, 0.0, 0.0, 0, 1, 0);
//        gluLookAt(eye.x, eye.y, eye.z, 0.0, 0.0, 0.0, up.x, up.y, up.z);

        glMultMatrixf(M);  //这句话就是把矩阵M设为视景矩阵
    }

函数表达:

dot()是点乘函数

 

此间的矩阵为啥现身负号,和

数学功底知识03

不平等,因为向量是有来头的,方向有着改观,所以,必要求注意喔。

 

好了,然后大家得以看看效果,能够开掘和gluLookAt()未有明显的歧异

 

3.录像机旋转

率先要显明有稍微种旋转方式,

依靠查找的质地,能够分为roll,yaw,pitch,具体表明,能够参谋大佬的小说

 

和地方的大佬们的鼠标人机联作代码达成分裂样,自己平素不选用slide

以下是自身改良后的yaw()函数和pitch()函数

void yaw(float angle) {
        float cs = cos(angle*PI / 180);
        float sn = sin(angle*PI / 180);
        Vector t(n);
        Vector s(u);
        n.setV(cs*t.x - sn*s.x, cs*t.y - sn*s.y, cs*t.z - sn*s.z);
        u.setV(sn*t.x   cs*s.x, sn*t.y   cs*s.y, sn*t.z   cs*s.z);

        eye.set(-R*n.x, -R*n.y, -R*n.z);

        setModeViewMatrix();
    }

void pitch(float angle) {
        float cs = cos(angle*PI / 180);
        float sn = sin(angle*PI / 180);
        Vector t(v);
        Vector s(n);
        v.setV(cs*t.x - sn*s.x, cs*t.y - sn*s.y, cs*t.z - sn*s.z);
        n.setV(sn*t.x   cs*s.x, sn*t.y   cs*s.y, sn*t.z   cs*s.z);

        eye.set(-R*n.x, -R*n.y, -R*n.z);

        setModeViewMatrix();
    }

那三个函数,都增添了改进录像机的点再世界坐标系下的坐标

譬如,你把录制机往上活动,假若您的眸子不跟上的摄像机,你能见到东西吗?

 

鼠标交互作用函数

    glutMouseFunc(onMouse);
    glutMotionFunc(onMouseMove);

现实函数达成

void onMouse(int button, int state, int x, int y)
{
    if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN ) {
        LeftMouseOn = true;
        x11 = x;
        y11 = y;
    }
    else if (button == GLUT_RIGHT_BUTTON && state == GLUT_DOWN) {
        RightMouseOn = true;
        x11 = x;
        y11 = y;
    }
    else {
        LeftMouseOn = false;
        RightMouseOn = false;
    }
}

变量表达:

x11,y11是鼠标按下去的时候,从显示屏取得的点坐标

 

接下来是鼠标移动的连带函数

void onMouseMove(int x, int y)
{
    int dx = x - x11;
    int dy = y - y11;
//    int cnt = 10000;
    if (LeftMouseOn == true) {
        RotateX(dx);
        RotateY(dy);
    }
    else if (RightMouseOn == true) {
        RotateRoll(dx);
    }
    x11 = x;
    y11 = y;
    //x11 = x21;
    //y11 = y21;
}

驷比不上舌表明:

只要鼠标在移动,都要修正当前鼠标的坐标,

举例:你从起点出发,向右跑出去了,但是意气风发旦您蓦地向左,你毕竟向左吗,不会,相对于起源,你要么向右的。

 

函数表达:

RotateX()是程度方向旋转

RotateY()是竖直方向旋转

此处的品位和竖直指的是显示器的水平和竖直,不是中间物体的

RotateRoll()是摄像机自个儿的团团转,n不改变,旋转u和v,即roll

void RotateX(float x_move)
{
    float part_theta = 30;
    float theta = x_move*part_theta*3.14/180;
    cam.yaw(theta);
}

void RotateY(float y_move)
{
    float part_theta = 30;
    float theta = y_move*part_theta*3.14 / 180;
    cam.pitch(theta);
    /*
    theta = theta / cnt;
    for (; cnt != 0; cnt--) {
        cam.pitch(theta);
    }*/
}

void RotateRoll(float x_move)
{
    float part_theta = 30;
    float theta = x_move*part_theta*3.14 / 180;
    cam.roll(theta);
}

数传说明:

part_theta是(旋转角度/每1单位活动间距卡塔 尔(阿拉伯语:قطر‎

 

4.油画机放大减弱(伪卡塔尔国

扩充减弱的原理,笔者是用录制机和视点间隔的远近变化来掌握的。

故而自身实现的这么些函数,与其说录制机放大降低,还不及说是你拿着水墨画机向视点走过去。(因为近大远小嘛卡塔 尔(阿拉伯语:قطر‎

 

率先是键盘人机联作函数

glutKeyboardFunc(keyboard);

接下来是键盘操作函数

void keyboard(unsigned char key, int x, int y)
{
    if (key == 109){
        cam.bsChange(1);
    }
    else if (key == 110){
        cam.bsChange(-1);
    }
}

void bsChange(int d)
    {
        if (d > 0){
            R--;
            eye.set(-R*n.x, -R*n.y, -R*n.z);
        }
        else{
            R  ;
            eye.set(-R*n.x, -R*n.y, -R*n.z);
        }

        setModeViewMatrix();
    }

109和110正是某多个开关的码,大家能够由此printf寻觅别的2个键来使用

重新提示:每趟坐标系调换(无论是旋转依然平移卡塔 尔(英语:State of Qatar),都要再度安装视景矩阵

 

本文由pc28.am发布于pc28.am神测网,转载请注明出处:Pangolin学习

上一篇:NET在IIS的启动优化设置,程序池被回收问题 下一篇:没有了
猜你喜欢
热门排行
精彩图文