opengl glm库 改变mvp矩阵 实现3D漫游

上一篇glm来实现的mvp矩阵变换实现opengl渲染模型,讲到了如何利用glm库实现mvp矩阵,这篇主要讲解下,我们如何利用glm库的平移、旋转矩阵实现一个简单的3d漫游的效果。

原理

移动

camera位置  和 视点  按照一个方向移动。这里主要是要修改视觉矩阵 viewMatrix

// 相当于人移动,那就是 视点 和  相机位置,按照 一定方向 移动
void translateCamera(glm::vec3 translateVector, float ra){
    translateVector = glm::normalize(translateVector)*ra;
    glm::mat4 translateMatrix;
    translateMatrix= glm::translate(translateMatrix,translateVector);

    glm::vec4 newCameraPos =  translateMatrix*(glm::vec4(cameraPos[0] , cameraPos[1] , cameraPos[2], 1.0f));
    glm::vec4 newVPos =  translateMatrix*(glm::vec4(vPos[0] , vPos[1] , vPos[2], 1.0f));

    cameraPos[0] = newCameraPos[0];
    cameraPos[1] = newCameraPos[1];
    cameraPos[2] = newCameraPos[2];

    vPos[0] = newVPos[0];
    vPos[1] = newVPos[1];
    vPos[2] = newVPos[2];

}

改变视角

camera位置不变, 视点位置 改变,相当于人看不同的目标。当旋转的时候,旋转矩阵乘以 视点,得到 目标视点,修改视觉矩阵 viewMatrix

// 改变视野方向,就是改变视点的方向
void changeDirection(glm::vec3 rotateVector, float ra) {
    rotateVector = glm::normalize(rotateVector)*ra;
    glm::mat4 translateMatrix;
    translateMatrix= glm::translate(translateMatrix,rotateVector);

    glm::vec4 newVPos =  translateMatrix*(glm::vec4(vPos[0] , vPos[1] , vPos[2], 1.0f));


    vPos[0] = newVPos[0];
    vPos[1] = newVPos[1];
    vPos[2] = newVPos[2];

}

移动和改变方向,都是需要修改投影矩阵的,因此,在draw的时候需要传入viewMatrix 。如下:

void Draw(){

//    translateCamera(glm::vec3(-1.0f , -1.0f ,-1.0f), 0.01f);
    changeDirection(glm::vec3(0.0f , 1.0f ,0.0f),0.010f);
    viewMatrix=glm::lookAt(cameraPos,vPos,glm::vec3(0.0f,1.0f,0.0f));

     model.rotateMode(glm::vec3(0.0f , 1.0f ,0.0f) ,0.10f );


     threeDCoordinates.Draw(viewMatrix,projectMatrix);
     model.Draw(viewMatrix,projectMatrix);

}

 

物体的移动旋转

物体的移动旋转主要是 modelMatrix来实现,主要是物体在世界坐标系的移动,旋转。只有在屏幕上渲染的时候才需要 projectMatrix和 viewMatrix,这2个矩阵就是把世界坐标系里的内容投放当屏幕坐标中。

void model::translateMode(glm::vec3 vec, float v) {
    vec =  glm::normalize(vec);
//    modelMatrix = glm::translate(modelMatrix, vec*v);
    position[0] = position[0] + vec[0]*v;
    position[1] = position[1] + vec[1]*v;
    position[2] = position[2] + vec[2]*v;
    setPosition( position[0] , position[1] ,position[2] );
}

int i = 0;
void model::rotateMode(glm::vec3 v, float angel) {
    glm::mat4 mat ={
     1.0f , 0.0f, 0.0f, 0.0f
    , 0.0f, 1.0f, 0.0f, 0.0f
    , 0.0f, 0.0f, 1.0f, 0.0f
    , 0.0f, 0.0f, 0.0f, 1.0f
    };
    LOGE("i = %d" , i);
    modelMatrix = glm::rotate(mat, angel*i ,v);
    modelMatrix = glm::translate(modelMatrix, position);
    i++;
//    setPosition(position[0] ,position[1],position[2]);
}

void model::setPosition(float x , float y , float z) {
    glm::mat4 mat;
    modelMatrix = glm::translate(mat, glm::vec3(x, y , z));
    position[0] = x;
    position[1] = y;
    position[2] = z;
}

node: 绘制模型的时候一定要启动,否则实现背面不会绘制。

 glEnable(GL_DEPTH_TEST);

这里提供demo,实现了视线的改变,相机的平移,物体的平移,旋转。

github 地址
 

物体边自转边移动

如何让物体一边自转,一边移动?上面实现的,具有累加效果,会绕y轴不挺的旋转,但也会偏离原来的轨道。

如下:视点(10,10,10), 视点(0,0,0),红线为z轴,向上的为y轴,蓝线为x轴,如何让地球沿着z轴移动,并且自转

思路:我们上面已经实现了绕y轴旋转,则是自转,我们先绕y轴自转,然后按照z轴移动。

1、我们将地球的圆心translate的位置记住,

2、然后在着色器中,先旋转计算出每个点的坐标 :rotateMatrix*points 计算出旋转后的 points坐标,然后利用 translate vector矩阵计算平移后的世界坐标。

3、 和 vp 矩阵来计算最终屏幕绘制的点。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值