QT开发笔记(Camera)
Posted ManGo CHEN
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了QT开发笔记(Camera)相关的知识,希望对你有一定的参考价值。
Camera
此章节例程适用于 Ubuntu 和正点原子 I.MX6U 开发板,不适用于 Windows(需要自行修改
才能适用 Windows,Windows 上的应用不在我们讨论范围)!
资源简介
正点原子 I.MX6U 开发板底板上有一路“CSI”摄像头接口。支持正点原子的 OV5640、
OV2640 和 OV7725(不带 FIFO)。同时有 USB 接口,可以接 USB 免驱摄像头。例程兼容 USB
摄像头与正点原子的 OV5640、OV2640 和 OV7725 摄像头。
出厂系统请更新到正点原子 I.MX6U 最新的出厂系统,在驱动层正点原子对 OV5640、
OV2640 和 OV7725 摄像头维护、优化或者添加支持。
环境搭建
Qt 里也有一个 QCamera 类。没错,确实可以使用这个 QCamera 类来开发摄像头。但是这
个类在正点原子的 I.MX6U 开发板 4.1.15 内核版本上不能使用 OV5640、OV2640 和 OV7725,
可以使用 USB 免驱摄像头。因为 OV5640、OV2640 和 OV7725 的驱动默认是读取 YUYV 格式
数据,而 QCamera 里读取的数据是 RGB 格式数据,它们可能数据对不上就无法使用了!但是
也不建议修改驱动的方法来使用 QCamera,防止 QCamera 在某些方法上与驱动层不对应,导致
使用报错。
实际上我们使用 V4l2 编程就可以对摄像头进行编程,效果会比在 Qt 显示流畅,因为 V4l2
的数据直接可以显示在 fb0(也就是屏上)。而经过 Qt 还需要在控件上处理,所以效率会慢一些!
在正点原子 I.MX6U 开发板上或者说是嵌入式上,比较低性能的 CPU 对于处理图像等大数据还
是比较吃力的。所以我们需要去优化,不同的编程方式,对数据的处理不同,写出来的效果也
会不同!
下面主要介绍 Qt + OpenCV 调用摄像头,效果肯定不能与使用 V4l2 直接显示在 fb0 上相比。
在这个开发板的 CPU 上显示效果还是比较好的,还能接受,流畅度一般。这个可能是 OpenCV
在对摄像头数据做了一定的处理才会变的慢了。
要想在 Ubuntu 上使用 OpenCV,那么我们的 Ubuntu 上必须有 OpenCV 的库,如果您不想
在 Ubuntu 安装 OpenCV,就可以跳过这小节,直接用出厂系统提供的交叉编译工具链,里面已
经提供有 OpenCV。在 Ubuntu 上安装 OpenCV 只是方便我们测试界面,编写的程序也可以在
Ubuntu 上运行。安装的步骤也比较简单。
正点原子 I.MX6U 出厂系统的 OpenCV 版本为 3.1.0。也不一定非要与正点原子 I.MX6U 出
厂系统里的 OpenCV 相同版本,我们只是在 Ubuntu 上运行 OpenCV。其中用到的 API 在 3.1.0
版本与 3.4.1 版本基本没有什么区别。3.1.0 版本的 OpenCV 与 3.4.1 版本的 OpenCV 绝大多数核
心 API 都相同,不必要担心找不到相同的 API。
这里笔者选择安装到 OpenCV 版本为 3.4.1 版本,因为 3.1.0 版本在配置 cmake 时下载的第
三方库因为网络的原因难下载,导致 cmake 配置不过去。(PS:如果不是因为编译不过去,笔者
会选择与开发板相同的版本的 OpenCV 的)。
进入 OpenCV 的官网 https://opencv.org/releases。下载 3.4.1 版本的 OpenCV,如下图。我们
选择 Sources(源码)进行下载。
右键选择复制下载链接,用迅雷下载会比较快。下载完成后我们拷贝下载的文件到 Ubuntu
上进行解压。或者直接在正点原子的 I.MX6U 的光盘资料路径下找到开发板光盘 A-基础资料/1、
例程源码/7、第三方库源码/opencv-3.4.1.tar.gz。然后拷贝到 Ubuntu 下。
如下图我们已经下载好文件,并拷贝下载好的文件到 Ubuntu 的家目录下。
执行下面的指令进行解压。解压将会得到一个 opencv-3.4.1 文件夹,我们使用 cd 指令进入
此文件夹。
tar xf opencv-3.4.1.tar.gz
cd opencv-3.4.1
安装 cmake,用于生成编译 OpenCV 所需要的文件。
sudo apt-get install cmake
新建一个 build 目录,并进入,用于编译生成的文件。
mkdir build
cd build
执行 cmake 配置编译。注意下面的指令“…”不要漏了!这里表示上一层目录。cmake 会从
上一层目录下找配置项,并配置到当前目录。
cmake …
在配置的过程中 cmake 会下载一些库,如 ippicv_2017u3_lnx_intel64_general_20170822.tgz,
需要一段时间,请等待,如果不能下载成功请重复尝试。
cmake 配置成功如下图。
执行 make 开始编译。输入下面的指令。
make -j 16 // 以实际分配给虚拟机的核心数为准,最佳为分配给虚拟
机核心数据的 2 倍。笔者的虚拟机最大分配了 16 个核心,笔者个人的电脑并不快,就是核心多,
所以编译就快。编译完成耗时约 5 分钟。不要只输入 make,否则将编译很久!需要加参数 -j n,
n 请根据个人虚拟机的实际情况。
执行下面的指令安装,安装到系统目录,需要加 sudo 权限。
sudo make install
安装完成如下。可以看到库被安装到/usr/local/lib 下,头文件被安装在/usr/local/include 下。
我们只需要知道安装的库路径和头文件路径即可在 Qt 里调用 Ubuntu 安装的 OpenCV。头
文件作用来编写程序,库路径用来运行程序时调用。我们只要在 Qt 的 pro 项目文件里指定这两
个路径即可。
应用实例
请根据【正点原子】I.MX6U 出厂系统 Qt 交叉编译环境搭建 V1.x.pdf(x >= 6)的文档搭建好
I.MX6U 的交叉编译环境。交叉编译工具链里已经有 OpenCV,所以我们只要在我们搭建的交叉
环境下就可以调用 OpenCV 的相关 API 进行编写 Qt 项目了。
项目简介:Qt 加 OpenCV 打开摄像头采集图像并拍照。
例 05_opencv_camera,Qt Camera 编程(难度:较难)。项目路径为 Qt/3/05_opencv_camera。
用脚本打开 Qt Creator,必须按出厂系统 Qt 交叉编译环境搭建 V1.x.pdf(x >= 6)的文档搭建
好交叉编译环境,用脚本启动时,脚本有相应的环境变量,编译时会用到。
/opt/Qt5.12.9/Tools/QtCreator/bin/qtcreator.sh &
编写程序应使用我们搭建的 ATK-I.MX6U 套件编写,否则若选择了 Desktop Qt 5.12.9 GCC
64bit,如果我们的 Ubuntu 没有安装 OpenCV 就会使用不了 OpenCV。如果您在 19.2 小节已经
安装过 OpenCV,那么下面两个套件都可一起选。本次笔者两个一起选,因为笔者有 USB 摄像
头可以在 Ubutnu 上使用 OpenCV 测试,编写的程序交叉编译后在 I.MX6U 开发板使用 USB 免
驱摄像头或者正点原子 OV5640/OV7725(不带 FIFO 款)/OV2640 测试成功!
下面开始编写程序。首先我们需要在项目 pro 文件添加 OpenCV 库的支持及头文件路径。
05_opencv_camera.pro 文件如下,添加以下内容,这里主要是判断交叉编译器的类型,然
后链接到不同的头文件路径与库。
1 QT += core gui
2
3 greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
4
5 CONFIG += c++11
6
7 # The following define makes your compiler emit warnings if you use
8 # any Qt feature that has been marked deprecated (the exact warnings
9 # depend on your compiler). Please consult the documentation of the
10 # deprecated API in order to know how to port your code away from it.
11 DEFINES += QT_DEPRECATED_WARNINGS
12
13 # You can also make your code fail to compile if it uses deprecated APIs.
14 # In order to do so, uncomment the following line.
15 # You can also select to disable deprecated APIs only up to a certain
version of Qt.
16 #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the
APIs deprecated before Qt 6.0.0
17
18 TARGET_ARCH = $$QT_ARCH
19 contains(TARGET_ARCH, arm)
20 CONFIG += link_pkgconfig 21 PKGCONFIG += opencv
22 INCLUDEPATH +=
/opt/fsl-imx-x11/4.1.15-2.1.0/sysroots/cortexa7hf-neon-poky-linux-gnuea
bi/usr/include
23 else
24 LIBS += -L/usr/local/lib \\
25 -lopencv_core \\
26 -lopencv_highgui \\
27 -lopencv_imgproc \\
28 -lopencv_videoio \\
29 -lopencv_imgcodecs
30
31 #INCLUDEPATH 可写可不写,系统会到找到此路径
32 INCLUDEPATH += /usr/local/include
33
34
35 SOURCES += \\
36 camera.cpp \\
37 main.cpp \\
38 mainwindow.cpp
39
40 HEADERS += \\
41 camera.h \\
42 mainwindow.h
43
44 # Default rules for deployment.
45 qnx: target.path = /tmp/$$TARGET/bin
46 else: unix:!android: target.path = /opt/$$TARGET/bin
47 !isEmpty(target.path): INSTALLS += target
第 18 行,获取编译器的类型。
第 19 行,判断交叉编译器的类型是否为 arm。
第 22 行,arm 对应 opencv 的头文件路径,可以不写,编译不会报错,但是我们想查看对
应的头文件,就不得不包括这个路径了,否则跳转不过去!
第 24~32 行,添加库的支持。-L 后面指的是库文件路径,-l 后面的是相关库参数(l 是大
字母“L”的小写字母“l”,不是一),如果不会写库的名称,可以参考 Ubuntu 的 OpenCV 安装
路径下的/usr/local/lib/pkgconfig/opencv.pc 文件。
camera.h 文件,此文件声明了一个 Camera 类,其内容如下,比较简单。
9 #ifndef CAMERA_H
10 #define CAMERA_H
11
12 #include <QImage>
13 #include <QTimer>
14 /* 使用命名空间 cv 下的 VideoCapture 与 Mat 类 */
15 namespace cv
16 class VideoCapture;
17 class Mat;
18
19
20 class Camera : public QObject
21
22 Q_OBJECT
23 public:
24 explicit Camera(QObject *parent = nullptr);
25 ~Camera();
26
27 signals:
28 /* 声明信号,用于传递有图片信号时显示图像 */
29 void readyImage(const QImage&);
30
31 public slots:
32 /* 用于开启定时器 */
33 bool cameraProcess(bool);
34
35 /* 选择摄像头 */
36 void selectCameraDevice(int);
37
38 private slots:
39 /* 定时器时间到处理函数,发送图像数据信号 */
40 void timerTimeOut();
41
42 private:
43 /* 声明 OpenCV 的 cv 命名空间下的 VideoCapture 对象 */
44 cv::VideoCapture * capture;
45
46 /* 定时器 */
47 QTimer * timer;
48
49 /* 图像转换处理函数 */
50 QImage matToQImage(const cv::Mat&);
51 ;
52
53 #endif // CAMERA_H
54
camera.cpp 类的定义如下。
9 #include "camera.h"
10 #include "opencv2/core/core.hpp"
11 #include "opencv2/highgui/highgui.hpp"
12 #include <QImage>
13 #include <QDebug>
14
15 Camera::Camera(QObject *parent) :
16 QObject(parent)
17
18 /* 实例化 */
19 capture = new cv::VideoCapture();
20 timer = new QTimer(this);
21
22 /* 信号槽连接 */
23 connect(timer, SIGNAL(timeout()), this, SLOT(timerTimeOut()));
24
25
26 Camera::~Camera()
27
28 delete capture;
29 capture = NULL;
30
31
32 void Camera::selectCameraDevice(int index)
33
34 /* 如果有其他摄像头打开了,先释放 */
35 if (capture->isOpened())
36 capture->release();
37
38
39 /* 打开摄像头设备 */
40 capture->open(index);
41
42
43 bool Camera::cameraProcess(bool bl)
44
45 if (bl)
46 /* 为什么是 33?1000/33 约等于 30 帧,也就是一秒最多显示 30 帧 */
47 timer->start(33);
48 else
49 timer->stop();
50
51 /* 返回摄像头的状态 */
52 return capture->isOpened();
53
54
55 void Camera::timerTimeOut()
56
57 /* 如果摄像头没有打开,停止定时器,返回 */
58 if (!capture->isOpened())
59 timer->stop();
60 return;
61
62
63 static cv::Mat frame;
64 *capture >> frame;
65 if (frame.cols)
66 /* 发送图片信号 */
67 emit readyImage(matToQImage(frame));
68
69
70 QImage Camera::matToQImage(const cv::Mat &img)
71
72 /* USB 摄像头和 OV5640 等都是 RGB 三通道,不考虑单/四通道摄像头 */
73 if(img.type() == CV_8UC3)
74 /* 得到图像的的首地址 */
75 const uchar *pimg = (const uchar*)img.data;
76
77 /* 以 img 构造图片 */
78 QImage qImage(pimg, img.cols, img.rows, img.step,
79 QImage::Format_RGB888);
80
81 /* 在不改变实际图像数据的条件下,交换红蓝通道 */
82 return qImage.rgbSwapped();
83
84
85 /* 返回 QImage */
86 return QImage();
87
mainwindow.h 头文件代码如下。
/******************************************************************
Copyright © Deng Zhimao Co., Ltd. 1990-2021. All rights reserved.
* @projectName 05_opencv_camera
* @brief mainwindow.h
* @author Deng Zhimao
* @email 1252699831@qq.com
* @net www.openedv.com
* @date 2021-03-17
*******************************************************************/
1 #ifndef MAINWINDOW_H
2 #define MAINWINDOW_H
3
4 #include <QMainWindow>
5 #include <QVBoxLayout>
6 #include <QHBoxLayout>
7 #include <QComboBox>
8 #include <QPushButton>
9 #include <QVBoxLayout>
10 #include <QLabel>
11 #include <QScrollArea>
12 #include <QDebug>
13
14 class Camera;
15
16 class MainWindow : public QMainWindow
17
18 Q_OBJECT
19
20 public:
21 MainWindow(QWidget *parent = nullptr);
22 ~MainWindow();
23
24 private:
25 /* 主容器,Widget 也可以当作一种容器 */
26 QWidget *mainWidget;
27
28 /* 滚动区域,方便开发高分辨率 */
29 QScrollArea *scrollArea;
30
31 /* 将采集到的图像使用 Widget 显示 */
32 QLabel *displayLabel;
33
34 /* 界面右侧区域布局 */
35 QHBoxLayout *hboxLayout;
36
37 /* 界面右侧区域布局 */
38 QVBoxLayout *vboxLayout;
39
40 /* 界面右侧区域容器 */
41 QWidget *rightWidget;
42
43 /* 界面右侧区域显示拍照的图片 */
44 QLabel *photoLabel;
45
46 /* 界面右侧区域摄像头设备下拉选择框 */
47 QComboBox *comboBox;
48
49 /* 两个按钮,一个为拍照按钮,另一个是开启摄像头按钮 */
50 QPushButton *pushButton[2];
51
52 /* 拍照保存的照片 */
53 QImage saveImage;
54
55 /* 摄像头设备 */
56 Camera *camera;
57
58 /* 布局初始化 */
59 void layoutInit();
60
61 /* 扫描是否存在摄像头 */
62 void scanCameraDevice();
63
64 private slots:
65 /* 显示图像 */
66 void showImage(const QImage&);
67
68 /* 设置按钮文本 */
69 void setButtonText(bool);
70
71 /* 保存照片到本地 */
72 void saveImageToLocal();
73 ;
74 #endif // MAINWINDOW_H
mainwindow.cpp 源文件代码如下。
/******************************************************************
Copyright © Deng Zhimao Co., Ltd. 1990-2021. All rights reserved.
* @projectName 05_opencv_camera
* @brief mainwindow.cpp
* @author Deng Zhimao
* @email 1252699831@qq.com
* @net www.openedv.com
* @date 2021-03-17
*******************************************************************/
1 #include "mainwindow.h"
2 #include <QGuiApplication>
3 #include <QScreen>
4 #include <QFile>
5 #include <QPixmap>
6 #include <QBuffer>
7 #include "camera.h"
8
9 MainWindow::MainWindow(QWidget *parent)
10 : QMainWindow(parent)
11
12 /* 布局初始化 */
13 layoutInit();
14
15 /* 扫描摄像头 */
16 scanCameraDevice();
17
18
19 MainWindow::~MainWindow()
20
21
22
23 void MainWindow::layoutInit()
24
25 /* 获取屏幕的分辨率,Qt 官方建议使用这
26 * 种方法获取屏幕分辨率,防上多屏设备导致对应不上
27 * 注意,这是获取整个桌面系统的分辨率
28 */
29 QList <QScreen *> list_screen = QGuiApplication::screens();
30
31 /* 如果是 ARM 平台,直接设置大小为屏幕的大小 */
32 #if __arm__
33 /* 重设大小 */
34 this->resize(list_screen.at(0)->geometry().width(),
35 list_screen.at(0)->geometry().height());
36 #else
37 /* 否则则设置主窗体大小为 800x480 */
38 this->resize(800, 480);
39 #endif
40
41 /* 实例化与布局,常规操作 */
42 mainWidget = new QWidget();
43 photoLabel = new QLabel();
44 rightWidget = new QWidget();
45 comboBox = new QComboBox();
46 pushButton[0] = new QPushButton();
47 pushButton[1] = new QPushButton();
48 scrollArea = new QScrollArea();
49 displayLabel = new QLabel(scrollArea);
50 vboxLayout = new QVBoxLayout();
51 hboxLayout = new QHBoxLayout();
52
53 vboxLayout->addWidget(photoLabel);
54 vboxLayout->addWidget(comboBox);
55 vboxLayout->addWidget(pushButton[0]);
56 vboxLayout->addWidget(pushButton[1]);
57
58 rightWidget->setLayout(vboxLayout);
59
60 hboxLayout->addWidget(scrollArea);
61 hboxLayout->addWidget(rightWidget);
62 mainWidget->setLayout(hboxLayout);
63
64 this->setCentralWidget(mainWidget);
65
66 pushButton[0]->setMaximumHeight(40);
67 pushButton[0]->setMaximumWidth(200);
68
69 pushButton[1]->setMaximumHeight(40);
70 pushButton[1]->setMaximumWidth(200);
71
72 comboBox->setMaximumHeight(40);
73 comboBox->setMaxim[游戏开发-学习笔记]菜鸟慢慢飞-Camera
游戏开发中,主相机应该是最重要的GameObject之一,毕竟游戏呈现给玩家,就是通过它。
相机的使用,在不同的游戏中,有很大的不同。这里总结一下自己学到的一些相关知识。
固定位置-游戏过程中相机的Transform属性不改变。
- 调整好位置后就不要动了,一般使用正交相机,即Camera-Projection选择Orthographic。Unity Manual-Camera
适用:2D游戏。比如飞机大战,消消乐。
- 游戏开始后,相机追踪某一物体,然后固定不动。
游戏开始后,我们才能确定追踪物体的位置,先看代码:
1 using UnityEngine;
2
3 public class CameraController : MonoBehaviour
4 {
5 public GameObject player;
6 private Vector3 offset;
7 void Start ()
8 {
9 offset = transform.position - player.transform.position;
10 }
11 void LateUpdate ()
12 {
13 transform.position = player.transform.position + offset;
14 }
15 }
View Code
适用:固定视角的3D游戏。
3D视角-围绕一个中心随意旋转
先看代码:
using UnityEngine;
public class CameraContorller : MonoBehaviour
{
/// <summary>
/// 追踪目标
/// </summary>
public Transform target;
/// <summary>
/// 旋转速度
/// </summary>
public float xSpeed = 200, ySpeed = 200;
/// <summary>
/// 缩放速度
/// </summary>
public float mSpeed = 10;
/// <summary>
/// 最小/最大限制角度
/// </summary>
public float yMinLimit = -50, yMaxLimit = 50;
/// <summary>
/// 是否使用插值运算
/// </summary>
public bool needDamping = true;
/// <summary>
/// 速度
/// </summary>
public float damping = 5.0f;
/// <summary>
/// 观察距离
/// </summary>
private float distance = 2;
/// <summary>
/// 最小/最大观察距离
/// </summary>
private float minDistance = 2, maxDistance = 30;
/// <summary>
/// 旋转角度
/// </summary>
private float x = 0.0f, y = 0.0f;
void Start()
{
Vector3 angles = transform.eulerAngles;
x = angles.y;
y = angles.x;
//根据相机的初始位置初始化距离,最大距离,最小距离;
Vector3 offset = transform.position - target.position;
distance = offset.magnitude;
minDistance = distance / 5;
maxDistance = distance * 3;
}
void LateUpdate()
{
if (target)
{
if (Input.GetMouseButton(1))//0-左键,1-右键,2-中键
{
x += Input.GetAxis("Mouse X") * xSpeed * 0.02f;
y -= Input.GetAxis("Mouse Y") * ySpeed * 0.02f;
y = ClampAngle(y, yMinLimit, yMaxLimit);
}
distance -= Input.GetAxis("Mouse ScrollWheel") * mSpeed;
distance = Mathf.Clamp(distance, minDistance, maxDistance);
Quaternion rotation = Quaternion.Euler(y, x, 0.0f);
Vector3 disVector = new Vector3(0.0f, 0.0f, -distance);
Vector3 position = rotation * disVector + target.position;
if (needDamping)
{
transform.rotation = Quaternion.Lerp(transform.rotation, rotation, Time.deltaTime * damping);
Vector3 transformTemp = Vector3.Lerp(transform.position, position, Time.deltaTime * damping);
if (transformTemp.y <= 0)//如果相机位置在“水平面”以下,强制设置到水平面。
{
transform.position = new Vector3(transformTemp.x, 0, transformTemp.z);
}
else
{
transform.position = transformTemp;
}
}
else
{
transform.rotation = rotation;
if (position.y <= 0)//如果相机位置在“水平面”以下,强制设置到水平面。
{
transform.position = new Vector3(position.x, 0, position.z);
}
else
{
transform.position = position;
}
}
}
}
static float ClampAngle(float angle, float min, float max)
{
if (angle < -360)
angle += 360;
if (angle > 360)
angle -= 360;
return Mathf.Clamp(angle, min, max);
}
}
View Code
大部分3D游戏中,我这样理解:主角看作球心,球半径玩家可以自己改变,相机的位置就在“地面”以上的半球球体上。
上面这段代码基本做到了这个要求,并在相机到“地面”的时候有抬头看的效果。
代码有点问题,开始游戏后相机会跳动两次,暂时放到自己的问题清单中。
其他用法
官方教程Tanks tutorial 中有个不常见的用法。
不管两个Tank如何移动,相机通过前后缩放,大小缩放保证两个Tank肯定在相机视野内。
主要代码:(官方代码写得好啊)
private void Move ()
{
// Find the average position of the targets.
FindAveragePosition ();
// Smoothly transition to that position.
transform.position = Vector3.SmoothDamp(transform.position, m_DesiredPosition, ref m_MoveVelocity, m_DampTime);
}
private void FindAveragePosition ()
{
Vector3 averagePos = new Vector3 ();
int numTargets = 0;
// Go through all the targets and add their positions together.
for (int i = 0; i < m_Targets.Length; i++)
{
// If the target isn\'t active, go on to the next one.
if (!m_Targets[i].gameObject.activeSelf)
continue;
// Add to the average and increment the number of targets in the average.
averagePos += m_Targets[i].position;
numTargets++;
}
// If there are targets divide the sum of the positions by the number of them to find the average.
if (numTargets > 0)
averagePos /= numTargets;
// Keep the same y value.
averagePos.y = transform.position.y;
// The desired position is the average position;
m_DesiredPosition = averagePos;
}
private void Zoom ()
{
// Find the required size based on the desired position and smoothly transition to that size.
float requiredSize = FindRequiredSize();
m_Camera.orthographicSize = Mathf.SmoothDamp (m_Camera.orthographicSize, requiredSize, ref m_ZoomSpeed, m_DampTime);
}
private float FindRequiredSize ()
{
// Find the position the camera rig is moving towards in its local space.
Vector3 desiredLocalPos = transform.InverseTransformPoint(m_DesiredPosition);
// Start the camera\'s size calculation at zero.
float size = 0f;
// Go through all the targets...
for (int i = 0; i < m_Targets.Length; i++)
{
// ... and if they aren\'t active continue on to the next target.
if (!m_Targets[i].gameObject.activeSelf)
continue;
// Otherwise, find the position of the target in the camera\'s local space.
Vector3 targetLocalPos = transform.InverseTransformPoint(m_Targets[i].position);
// Find the position of the target from the desired position of the camera\'s local space.
Vector3 desiredPosToTarget = targetLocalPos - desiredLocalPos;
// Choose the largest out of the current size and the distance of the tank \'up\' or \'down\' from the camera.
size = Mathf.Max(size, Mathf.Abs(desiredPosToTarget.y));
// Choose the largest out of the current size and the calculated size based on the tank being to the left or right of the camera.
size = Mathf.Max(size, Mathf.Abs(desiredPosToTarget.x) / m_Camera.aspect);
}
// Add the edge buffer to the size.
size += m_ScreenEdgeBuffer;
// Make sure the camera\'s size isn\'t below the minimum.
size = Mathf.Max (size, m_MinSize);
return size;
}
View Code
暂时放下的内容
Unity的相机相关:
以上是关于QT开发笔记(Camera)的主要内容,如果未能解决你的问题,请参考以下文章
统信UOS系统开发笔记:国产统信UOS系统搭建Qt开发环境安装Qt5.12
C++Widgets编程(《Qt Creator快速入门》 第3版 学习笔记 )