最近在搞QT上的OPENGL,有好多库都要自己写啊
哐哧哐哧写了一大顿,已经写好了,回过头来记录一下
这篇讲的时关于opengl自由摄像机的问题
写摄像机的思路是,写一个万能的摄像机基类,可以支持各种基本操作(没有添加左右晃镜头的功能)
然后如果你需要用到什么样的摄像机,继承基类,然后重写他的移动函数和改变镜头方向函数(这两个函数为虚函数)
这样的话,你不用考虑是什么类型的摄像机,把摄像机基类指针传过去然后就可以自动调用你自己写的函数
!!!!!
注意此类用的是右手坐标系
!!!!!

代码如下:

基类摄像机

// camera.h
#pragma once
#ifndef CAMERA_H
#define CAMERA_H
#include<QObject>
#include<QVector3D>
#include<QVector4D>
#include<QMatrix4x4>
#include<QtMath>
namespace LB
{/*this is the coordinate be using^ z|||/----------> y//V  x*/class Camera:public QObject{Q_OBJECTpublic:
// pre_declareenum Direction{None=0,Up=1,Down=2,Left=3,Right=4,Front=5,Rear=6};Q_ENUMS(Direction)
// functionCamera();virtual ~Camera(){}void setCameraPosition(QVector3D p);void setSpeedMove(float s);void setSpeedWaggle(float s);void setDirectionUp(QVector3D d);void setDirectionLook(QVector3D d);void setVerticalAngle(float a);void setAspectRatio(float a);void setNearPlane(float n);void setFarPlane(float f);
// operate functionvirtual void move(Direction d);virtual void waggle(Direction d);virtual void printInfo();   // Debug Method
// get status functionQVector4D getCameraPosition() const;QVector4D getDirectionLook() const;QVector4D getDirectionUp() const;float getSpeedMove() const;float getSpeedWaggle() const;float getVerticalAngle() const;float getAspetRatio() const;float getNearPlane() const;float getFarPlane() const;
//  get matrixQMatrix4x4 getViewMatrix();QMatrix4x4 getViewMatrixLeftHand();QMatrix4x4 getProjectionMatrix();protected:QVector4D position;// the position of the free_cameraQVector4D direction_look;//the look_directionQVector4D  direction_up;float speed_move;// the speed of camera movingfloat speed_waggle;// the speed of camera waggllingfloat vertical_angle;// angle of vertical fieldfloat aspect_ratio;// ration of width/heightfloat near_plane;// the projection's near planefloat far_plane;// the projection's far plane};
}
#endif // CAMERA_H

// camera.cpp
#include "camera.h"LB::Camera::Camera():position(1.0f,0.0f,0.0f,1.0f),direction_look(-1.0f,0.0f,0.0f,0.0f),direction_up(0.0f,0.0f,1.0f,0.0f),speed_move(0.02f),speed_waggle(0.05f),vertical_angle(90),aspect_ratio(1.0f),near_plane(1.0f),far_plane(100.0f)
{}void LB::Camera::setCameraPosition(QVector3D p)
{auto tem=p.toVector4D();tem.setW(1.0f);position=tem;
}void LB::Camera::setSpeedMove(float s)
{speed_move=s;
}void LB::Camera::setSpeedWaggle(float s)
{if(s<90&&s>0)speed_waggle=s;else{qDebug()<<"Error: can't set speed_waggle";qDebug()<<"Reason: speed_waggle you set  <=0 or >=90";}
}void LB::Camera::setDirectionUp(QVector3D d)
{// new direction_upd.normalize();// direction_lookauto d_look=direction_look.toVector3D();if(d==d_look||d==-d_look){qDebug()<<"Error: set direction_up failed";qDebug()<<"Reason: direction_up you set is parallel to the direction_look";return;}else{// new direction_leftauto d_left_n=QVector3D::crossProduct(d,d_look);// set direction_upauto up=QVector3D::crossProduct(d_look,d_left_n);up.normalize();direction_up=up.toVector4D();}
}void LB::Camera::setDirectionLook(QVector3D d)
{// new direction_lookd.normalize();// direction_lookauto d_up=direction_up.toVector3D();if(d==d_up||d==-d_up){qDebug()<<"Error: set Direction_look failed";qDebug()<<"Reason: Direction_look you set is Parallel to the Direction_up";return;}else{// set the direction_lookdirection_look=d.toVector4D();// set the direction_upauto d_left=QVector3D::crossProduct(d_up,d);auto up=QVector3D::crossProduct(d,d_left);up.normalize();direction_up=up.toVector4D();}
}void LB::Camera::setVerticalAngle(float a)
{if(a>0&&a<180)vertical_angle=a;else{qDebug()<<"Error: fail to set Vertical Angle";qDebug()<<"Reason: value you set <= 0 or >= 180";}
}void LB::Camera::setAspectRatio(float a)
{if(a>0||a*vertical_angle<180)aspect_ratio=a;else{qDebug()<<"Error: fail to set Aspect Angle";qDebug()<<"Reason: value you set <= 0 or (Vertical Angle * it >= 180_";}return;
}void LB::Camera::setNearPlane(float n)
{if(n>0&&n<far_plane)near_plane=n;else{qDebug()<<"Error: fail to set Near Plane";qDebug()<<"Reason: value you set <=0 or >=far_plane";}
}void LB::Camera::setFarPlane(float f)
{if(f>near_plane)far_plane=f;else{qDebug()<<"Error: fail to set Near Plane";qDebug()<<"Reason: value you set <=near_Plane";}
}void LB::Camera::printInfo()
{qDebug()<<"----- Print Camera Info : -----";qDebug()<<" Camera Position :";qDebug()<<Camera::getCameraPosition();qDebug()<<" Camera Look Direction :";qDebug()<<Camera::getDirectionLook();qDebug()<<" Camera Up Direction :";qDebug()<<Camera::getDirectionUp();qDebug()<<"================================";
}void LB::Camera::move(Camera::Direction d)
{QVector3D direction_left;switch (d) {case Camera::Up:position+=direction_up*speed_move;break;case Camera::Down:position-=direction_up*speed_move;break;case Camera::Left:direction_left=QVector3D::crossProduct(direction_up.toVector3D(),direction_look.toVector3D());direction_left.normalize();position+=direction_left*speed_move;break;case Camera::Right:direction_left=QVector3D::crossProduct(direction_up.toVector3D(),direction_look.toVector3D());direction_left.normalize();position-=direction_left*speed_move;break;case Camera::Front:position+=direction_look*speed_move;break;case Camera::Rear:position-=direction_look*speed_move;break;default:qDebug()<<"the direction you move is not set";break;}
}void LB::Camera::waggle(Camera::Direction d)
{QMatrix4x4 matrix_rotate;QVector4D d_look;QVector3D direction_left;switch (d) {case Camera::Up:direction_left=QVector3D::crossProduct(direction_up.toVector3D(),direction_look.toVector3D());direction_left.normalize();matrix_rotate.rotate(-speed_waggle,direction_left);d_look=matrix_rotate*direction_look;setDirectionLook(d_look.toVector3D());break;case Camera::Down:direction_left=QVector3D::crossProduct(direction_up.toVector3D(),direction_look.toVector3D());direction_left.normalize();matrix_rotate.rotate(speed_waggle,direction_left);d_look=matrix_rotate*direction_look;setDirectionLook(d_look.toVector3D());break;case Camera::Left:matrix_rotate.rotate(speed_waggle,direction_up.toVector3D());d_look=matrix_rotate*direction_look;setDirectionLook(d_look.toVector3D());break;case Camera::Right:matrix_rotate.rotate(-speed_waggle,direction_up.toVector3D());d_look=matrix_rotate*direction_look;setDirectionLook(d_look.toVector3D());break;default:qDebug()<<"the direction you wggle is not set";break;}
}QVector4D LB::Camera::getCameraPosition() const
{return position;
}QVector4D LB::Camera::getDirectionLook() const
{return direction_look;
}QVector4D LB::Camera::getDirectionUp() const
{return direction_up;
}float LB::Camera::getSpeedMove() const
{return speed_move;
}float LB::Camera::getSpeedWaggle() const
{return speed_waggle;
}float LB::Camera::getVerticalAngle() const
{return vertical_angle;
}float LB::Camera::getAspetRatio() const
{return aspect_ratio;
}float LB::Camera::getNearPlane() const
{return near_plane;
}float LB::Camera::getFarPlane() const
{return far_plane;
}QMatrix4x4 LB::Camera::getProjectionMatrix()
{QMatrix4x4 matrix;matrix.perspective(vertical_angle,aspect_ratio,near_plane,far_plane);return matrix;
}QMatrix4x4 LB::Camera::getViewMatrix()
{QMatrix4x4 matrix;matrix.lookAt(position.toVector3D(),(position+direction_look).toVector3D(),direction_up.toVector3D());return matrix;
}QMatrix4x4 LB::Camera::getViewMatrixLeftHand()
{QVector3D p=position.toVector3D();QVector3D look=(position+direction_look).toVector3D();QVector3D up=direction_up.toVector3D();p.setZ(-p.z());look.setZ(-look.z());up.setZ(-up.z());QMatrix4x4 matrix;matrix.lookAt(p,look,up);return matrix;
}

============================================

自定义的定点摄像机:

// fixcamera.h#pragma once
#ifndef FIXCAMERA_H
#define FIXCAMERA_H
#include <camera.h>namespace LB
{class FixCamera: public Camera{public:FixCamera();FixCamera(QVector3D fixPosition);FixCamera(QVector3D fixPosition,QVector3D cameraPosition);virtual ~FixCamera(){}void setFixPosition(QVector3D p);// operate functionvirtual void move(Direction d);// get status functionQVector4D getFixPosition() const;private:QVector4D fix_position;};
}
#endif // FIXCAMERA_H

// fixcamera.cpp#include "fixcamera.h"LB::FixCamera::FixCamera()
{Camera::Camera();fix_position=QVector4D(0.0f,0.0f,0.0f,1.0f);
}LB::FixCamera::FixCamera(QVector3D fixPosition)
{FixCamera();if(fixPosition!=position.toVector3D()){Camera::setCameraPosition(position.toVector3D());Camera::setDirectionLook(fixPosition-position.toVector3D());}else{qDebug()<<"Error: can't set fix position";qDebug()<<"Reason: fix position you set is same to camera position";}
}LB::FixCamera::FixCamera(QVector3D fixPosition, QVector3D cameraPosition)
{FixCamera();if(fixPosition!=cameraPosition){position=cameraPosition;fix_position=fixPosition;setDirectionLook(fixPosition-position.toVector3D());}else{qDebug()<<"Error: can't set fix position";qDebug()<<"Reason: fix position you set is same to camera position";}
}void LB::FixCamera::setFixPosition(QVector3D p)
{if(fix_position!=position){fix_position=p;Camera::setDirectionLook(getFixPosition().toVector3D()-p);Camera::setDirectionUp(QVector3D(0.0f,0.0f,1.0f));}else{qDebug()<<"Error: can't set fix position";qDebug()<<"Reason: fix position you set is same to camera position";}
}void LB::FixCamera::move(Camera::Direction d)
{QVector4D p;QVector4D t;QMatrix4x4 r;double distance=position.toVector3D().distanceToPoint(fix_position.toVector3D());float a;switch (d){case Camera::Up:a=qRadiansToDegrees(qAsin(-Camera::getDirectionLook().z()));if(a+speed_waggle>=90)return;else{Camera::waggle(Camera::Down);Camera::setCameraPosition((getFixPosition()-Camera::getDirectionLook()*distance).toVector3D());}break;case Camera::Down:a=qRadiansToDegrees(qAsin(-Camera::getDirectionLook().z()));if(a-speed_waggle<=-90)return;else{Camera::waggle(Camera::Up);Camera::setCameraPosition((getFixPosition()-Camera::getDirectionLook()*distance).toVector3D());}break;case Camera::Left:p=Camera::getCameraPosition()-getFixPosition();r.rotate(-speed_waggle,QVector3D(0.0f,0.0f,1.0f));t=r*p;Camera::setCameraPosition((t+getFixPosition()).toVector3D());Camera::setDirectionLook((getFixPosition()-position).toVector3D());Camera::setDirectionUp(QVector3D(0.0f,0.0f,1.0f));break;case Camera::Right:p=Camera::getCameraPosition()-getFixPosition();r.rotate(speed_waggle,QVector3D(0.0f,0.0f,1.0f));t=r*p;Camera::setCameraPosition((t+getFixPosition()).toVector3D());Camera::setDirectionLook((getFixPosition()-position).toVector3D());Camera::setDirectionUp(QVector3D(0.0f,0.0f,1.0f));break;case Camera::Front:if(distance-speed_move<=0)return;elseCamera::move(Camera::Front);break;case Camera::Rear:Camera::move(Camera::Rear);break;default:qDebug()<<"the direction you move is not set";break;}
}QVector4D LB::FixCamera::getFixPosition() const
{return fix_position;
}

用于OpenGl的Camera类(QT实现的3D摄像机类)相关推荐

  1. Qt中的自定义模型类

    文章目录 1 Qt中的通用模型类 1.1 Qt中的通用模型类 1.2 Qt中的变体类型QVariant 2 自定义模型类 2.1 自定义模型类设计分析 2.2 自定义模型类数据层.数据表示层.数据组织 ...

  2. qt ui指针和本类对象_您需要了解的有关UI设计的形状和对象的所有信息

    qt ui指针和本类对象 重点 (Top highlight) 第1部分 (Part 1) So you're thinking about becoming a UX/UI designer, bu ...

  3. Qt的对话框与窗口--Qt中主要的窗体类及其用途

    Qt中主要的窗体类及其用途     常用的窗体基类是QWidget.QDialog和QMainWindow,在创建GUI应用程序时选择窗体基类就是从这3个类中选择.QWidget直接继承于QObjec ...

  4. OpenGL(十一)——Qt OpenGL给多边形上色

    OpenGL(十一)--Qt OpenGL给多边形上色 一.前言 上篇文章介绍了绘制多边形的代码. 本篇介绍给多边形上色. 上篇的运行效果: 二.代码 上一篇中三角形和四边形的绘制方法.这一篇给三角形 ...

  5. Boost::signals2 类QT的信号槽实现机制

    signals2 基于Boost里的另一个库signals,实现了线程安全的观察者模式.它是一种函数回调机制,当一个信号关联了多个槽时,信号发出,这些槽将会被调用.google的base库里用的多的模 ...

  6. Qt的时间控件类QDateTimeEdit,QTimeEdit,QDateEdit,QCalendarWidget

    Qt的时间控件类QDateTimeEdit,QTimeEdit,QDateEdit,QCalendarWidget QDateTimeEdit 属性 datetime: date: time: max ...

  7. Qt的4个图像类QImage/QPixmap/QBitmap/QPicture 转

    Qt的4个图像类QImage/QPixmap/QBitmap/QPicture 转 (一)QPixmap和QImage的区别 http://www.thisisqt.com/forum/viewthr ...

  8. Qt 项目视图的便捷类

    Qt 项目视图的便捷类 Qt中提供了一些标准部件来提供经典的基于项的容器部件,它们的底层是通过模型.视图框架实现的. 这些部件分别是QListWidget.QTreeWidget.QTableWidg ...

  9. linux上qt配置opengl,Ubuntu下配置Qt+OpenGL+OpenCV

    我的平台:Ubuntu 10.04+Qt+OpenGL+OpenCV OpenGL是Qt自带的,Windows下的版本OpenGL库已经随同Qt的Windows发行版一同安装,Linux版本则没有安装 ...

最新文章

  1. 初识C语言---(2)
  2. Android基于IIS的APK下载(五)IIS的配置
  3. MFC中MessageBox()用法
  4. linux系统在pe下查看ip地址,pe下查看原系统ip的方法_网站服务器运行维护
  5. 移动端导出excel_连载系列【4】Excel开发移动端quot;APPquot;
  6. java向Oracle数据库中插入blob字段数据
  7. 单链表实现反转的三种方法
  8. 某班的成绩出来了,现在老师要把班级的成绩打印出来,和 显示当前时间
  9. 一个小工具帮你搞定实时监控Nginx服务器
  10. 【转载】Pandas速查手册中文版
  11. 如何修改hosts文件权限
  12. DS3231时钟模块使用,IIC协议实践。(基于STM32)
  13. 电子统计台账:垂直流水账格式数据的导入
  14. SAS的win10 64位安装过程
  15. [Python-turtle]正弦定理能擦出多漂亮的火花?【1】
  16. java虚无世界_我的世界虚无世界2.5
  17. 淘宝上卖云控系统靠谱吗?
  18. ROS日记:ROS系统的备份和还原
  19. 仿微信二维码极速扫描(MLKit及CameraX初体验),安卓消息分发机制
  20. uniapp开发微信小程序-软考刷题小程序

热门文章

  1. 明确写简历、发简历的规则,才能玩得更好!——leo简历工作室章程
  2. python爬虫获取给定新浪微博评论
  3. go切换proxy中国代理
  4. 智能分数计算机在线使用,基于智能手机的试卷分数统计系统及其使用方法与流程...
  5. 怎么选择合适的插画培训机构(靠谱的插画培训机构)
  6. 【普通人题解】LeetCode174. 地下城游戏
  7. Ubuntu20.04正确的开启方式(美化+软件安装)
  8. 《GammaFAQ》,译名:关于伽马的常见问题及解答
  9. 《调色师手册:电影和视频调色专业技法(第2版)》——挑选监视器
  10. 小米手机劫持发往谷歌商店的链接