当前位置:网站首页>Qt OpenGL相机的使用
Qt OpenGL相机的使用
2022-07-03 11:06:00 【wb175208】
先看效果:
顶点着色器:
#version 330 core
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec2 aTextureCoord;
out vec3 outColor;
out vec2 textureCoord;
//矩阵必须初始化,初始化单位矩阵,否则GLSL语言中默认矩阵是0矩阵
uniform mat4 trans = mat4(1.0);
uniform mat4 model = mat4(1.0);
uniform mat4 view = mat4(1.0);
uniform mat4 projection = mat4(1.0);
void main(){
//gl_Position = trans * vec4(aPos.x, aPos.y, aPos.z, 1.0);//在矩阵乘法中是右乘左,与显实的乘法不同
gl_Position = projection * view * model * vec4(aPos, 1.0);
textureCoord = aTextureCoord;
}
片段着色器:
#version 330 core
out vec4 fragColor;
in vec3 outColor;//从顶点着色器中传过来的颜色
in vec2 textureCoord;
uniform sampler2D textureImg;
uniform sampler2D textureCpp;
void main(){
//fragColor = texture(textureImg, textureCoord);
fragColor = mix(texture(textureImg,textureCoord), texture(textureCpp,textureCoord), 0.5);
}
相机类:
#pragma once
#include <QVector3D>
#include <qmatrix4x4.h>
// Defines several possible options for camera movement. Used as abstraction to stay away from window-system specific input methods
enum Camera_Movement {
FORWARD,
BACKWARD,
LEFT,
RIGHT,
UP,
DOWN
};
// Default camera values
const float YAW = -90.0f;
const float PITCH = 0.0f;
const float SPEED = 2.5f;
const float SENSITIVITY = 0.005f;
const float ZOOM = 45.0f;
class Camera {
public:
// camera Attributes
QVector3D Position;
QVector3D Front;
QVector3D Up;
QVector3D Right;
QVector3D WorldUp;
// euler Angles
float Yaw;
float Pitch;
// camera options
float MovementSpeed;
float MouseSensitivity;
float Zoom;
// constructor with vectors
Camera(QVector3D position = QVector3D(0.0f, 0.0f, 0.0f), QVector3D up = QVector3D(0.0f, 1.0f, 0.0f), float yaw = YAW, float pitch = PITCH) : Front(QVector3D(0.0f, 0.0f, -1.0f)), MovementSpeed(SPEED), MouseSensitivity(SENSITIVITY), Zoom(ZOOM) {
Position = position;
WorldUp = up;
Yaw = yaw;
Pitch = pitch;
updateCameraVectors();
}
// constructor with scalar values
Camera(float posX, float posY, float posZ, float upX, float upY, float upZ, float yaw, float pitch) : Front(QVector3D(0.0f, 0.0f, -1.0f)), MovementSpeed(SPEED), MouseSensitivity(SENSITIVITY), Zoom(ZOOM) {
Position = QVector3D(posX, posY, posZ);
WorldUp = QVector3D(upX, upY, upZ);
Yaw = yaw;
Pitch = pitch;
updateCameraVectors();
}
~Camera();
// returns the view matrix calculated using Euler Angles and the LookAt Matrix
QMatrix4x4 GetViewMatrix() {
QMatrix4x4 view;
view.lookAt(Position, Position + Front, Up);
return view;
}
// processes input received from any keyboard-like input system. Accepts input parameter in the form of camera defined ENUM (to abstract it from windowing systems)
void ProcessKeyboard(Camera_Movement direction, float deltaTime) {
float velocity = MovementSpeed * deltaTime;
if (direction == FORWARD)
Position += Front * velocity;
if (direction == BACKWARD)
Position -= Front * velocity;
if (direction == LEFT)
Position -= Right * velocity;
if (direction == RIGHT)
Position += Right * velocity;
if (direction == UP)
Position += WorldUp * velocity;
if (direction == DOWN)
Position -= WorldUp * velocity;
//updateCameraVectors();
}
// processes input received from a mouse input system. Expects the offset value in both the x and y direction.
void ProcessMouseMovement(float xoffset, float yoffset, bool constrainPitch = true) {
xoffset *= MouseSensitivity;
yoffset *= MouseSensitivity;
Yaw += xoffset;
Pitch += yoffset;
// make sure that when pitch is out of bounds, screen doesn't get flipped
if (constrainPitch) {
if (Pitch > 89.0f)
Pitch = 89.0f;
if (Pitch < -89.0f)
Pitch = -89.0f;
}
// update Front, Right and Up Vectors using the updated Euler angles
updateCameraVectors();
}
// processes input received from a mouse scroll-wheel event. Only requires input on the vertical wheel-axis
void ProcessMouseScroll(float yoffset) {
Zoom -= (float)yoffset;
if (Zoom < 1.0f)
Zoom = 1.0f;
if (Zoom > 45.0f)
Zoom = 45.0f;
}
private:
// calculates the front vector from the Camera's (updated) Euler Angles
void updateCameraVectors() {
// calculate the new Front vector
QVector3D front;
front.setX(cos(Yaw) * cos(Pitch));
front.setY(sin(Pitch));
front.setZ(sin(Yaw) * cos(Pitch));
Front = front.normalized();
// also re-calculate the Right and Up vector
Right = QVector3D::crossProduct(Front, WorldUp).normalized();
Up = QVector3D::crossProduct(Right, Front).normalized();
}
};
界面类:
#pragma once
#include <QOpenGLWindow>
#include <QOpenGLWidget>
#include <QOpenGLExtraFunctions>
#include <QDebug>
#include <QOpenGLTexture>
#include <QElapsedTimer>
#include <QOpenGLShader>
#include <QOpenGLShaderProgram>
#include "camera.h"
class CameraWnd : public QOpenGLWindow {
Q_OBJECT
public:
CameraWnd();
~CameraWnd();
protected:
virtual void initializeGL();
virtual void resizeGL(int w, int h);
virtual void paintGL();
void keyPressEvent(QKeyEvent *event);
void mouseMoveEvent(QMouseEvent *event);
void wheelEvent(QWheelEvent *event);
void mousePressEvent(QMouseEvent *event);
void mouseReleaseEvent(QMouseEvent *event);
private:
class QOpenGLTexture *_texture1;
class QOpenGLTexture *_texture2;
QElapsedTimer m_time;
Camera m_camera;
float m_lastX;
float m_lastY;
float m_deltaTime = 0.0f;
float m_lastFrame = 0.0f;
bool m_firstMouse = true;
bool m_isMousePress = false;
class QOpenGLFunctions_3_3_Core* _openGLCore;
QOpenGLShaderProgram _shaderProgram;//着色器程序,所里系统所有的着色器
};
#include "CameraWnd.h"
#include <QKeyEvent>
#include <QMouseEvent>
#include <QWheelEvent>
#include <QOpenGLFunctions_3_3_Core>
static GLuint VBO, VAO = 0;
// world space positions of our cubes
static QVector3D cubePositions[] = {
QVector3D(0.0f, 0.0f, 0.0f),
QVector3D(2.0f, 5.0f, -15.0f),
QVector3D(-1.5f, -2.2f, -2.5f),
QVector3D(-3.8f, -2.0f, -12.3f),
QVector3D(2.4f, -0.4f, -3.5f),
QVector3D(-1.7f, 3.0f, -7.5f),
QVector3D(1.3f, -2.0f, -2.5f),
QVector3D(1.5f, 2.0f, -2.5f),
QVector3D(1.5f, 0.2f, -1.5f),
QVector3D(-1.3f, 1.0f, -1.5f)
};
CameraWnd::CameraWnd() {
m_camera.Position = QVector3D(0.0f, 0.0f, 3.0f);
m_lastX = width() / 2;
m_lastY = height() / 2;
}
CameraWnd::~CameraWnd() {
}
void CameraWnd::initializeGL() {
_openGLCore = QOpenGLContext::currentContext()->versionFunctions<QOpenGLFunctions_3_3_Core>();
_openGLCore->glEnable(GL_DEPTH_TEST);
float vertices[] = {
-0.5f, -0.5f, -0.5f, 0.0f, 0.0f,
0.5f, -0.5f, -0.5f, 1.0f, 0.0f,
0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
-0.5f, 0.5f, -0.5f, 0.0f, 1.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 0.0f,
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f,
0.5f, -0.5f, 0.5f, 1.0f, 0.0f,
0.5f, 0.5f, 0.5f, 1.0f, 1.0f,
0.5f, 0.5f, 0.5f, 1.0f, 1.0f,
-0.5f, 0.5f, 0.5f, 0.0f, 1.0f,
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f,
-0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
-0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f,
-0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
0.5f, -0.5f, 0.5f, 0.0f, 0.0f,
0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
0.5f, -0.5f, -0.5f, 1.0f, 1.0f,
0.5f, -0.5f, 0.5f, 1.0f, 0.0f,
0.5f, -0.5f, 0.5f, 1.0f, 0.0f,
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
-0.5f, 0.5f, -0.5f, 0.0f, 1.0f,
0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
-0.5f, 0.5f, 0.5f, 0.0f, 0.0f,
-0.5f, 0.5f, -0.5f, 0.0f, 1.0f
};
_openGLCore->glGenVertexArrays(1, &VAO);
_openGLCore->glGenBuffers(1, &VBO);
_openGLCore->glBindVertexArray(VAO);
_openGLCore->glBindBuffer(GL_ARRAY_BUFFER, VBO);
_openGLCore->glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
// position attribute
_openGLCore->glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)0);
_openGLCore->glEnableVertexAttribArray(0);
// texture coord attribute
_openGLCore->glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(3 * sizeof(float)));
_openGLCore->glEnableVertexAttribArray(1);
//垂直镜像mirrored
_texture1 = new QOpenGLTexture(QImage("E:/Projects/QtGuiTest/OPenGLApp/shader/1.jpg").mirrored());
if (!_texture1->isCreated()) {
qDebug() << "Failed to load texture";
}
//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
_texture1->setWrapMode(QOpenGLTexture::DirectionS, QOpenGLTexture::Repeat);
//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
_texture1->setWrapMode(QOpenGLTexture::DirectionT, QOpenGLTexture::Repeat);
//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
_texture1->setMinificationFilter(QOpenGLTexture::Linear);
//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
_texture1->setMagnificationFilter(QOpenGLTexture::Linear);
_texture2 = new QOpenGLTexture(QImage("E:/Projects/QtGuiTest/OPenGLApp/shader/2.png").mirrored());
if (!_texture2->isCreated()) {
qDebug() << "Failed to load texture";
}
//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
_texture2->setWrapMode(QOpenGLTexture::DirectionS, QOpenGLTexture::Repeat);
//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
_texture2->setWrapMode(QOpenGLTexture::DirectionT, QOpenGLTexture::Repeat);
//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
_texture2->setMinificationFilter(QOpenGLTexture::Linear);
//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
_texture2->setMagnificationFilter(QOpenGLTexture::Linear);
//设置纹理单元编号
_shaderProgram.addShaderFromSourceFile(QOpenGLShader::Vertex, "E:/Projects/QtGuiTest/OPenGLApp/shader/Camera.vert");
_shaderProgram.addShaderFromSourceFile(QOpenGLShader::Fragment, "E:/Projects/QtGuiTest/OPenGLApp/shader/Camera.frag");
_shaderProgram.link();
//如果是一张图片就不用绑定,默认绑定。如果是多于1张就需要主动绑定,
_shaderProgram.bind();
/* ** textureImg:对应的片元着色器的 uniform sampler2D textureImg; ** textureCpp:对应的片元着色器的 uniform sampler2D textureCpp; */
_shaderProgram.setUniformValue("textureImg", 0);
_shaderProgram.setUniformValue("textureCpp", 1);
m_time.start();
}
void CameraWnd::resizeGL(int w, int h) {
_openGLCore->glViewport(0, 0, w, h);
}
void CameraWnd::paintGL() {
_openGLCore->glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
_openGLCore->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
float currentFrame = (float)m_time.elapsed() / 100;
m_deltaTime = currentFrame - m_lastFrame;
m_lastFrame = currentFrame;
//激活纹理单元0
_openGLCore->glActiveTexture(GL_TEXTURE0);
_texture1->bind();
_openGLCore->glActiveTexture(GL_TEXTURE1);
_texture2->bind();
// render container
_shaderProgram.bind();
QMatrix4x4 view = m_camera.GetViewMatrix();
QMatrix4x4 projection;
view.translate(QVector3D(0.0f, 0.0f, -3.0f));
projection.perspective(m_camera.Zoom, (float)width() / (float)height(), 0.1f, 100.0f);
for (unsigned int i = 0; i < 10; i++) {
QMatrix4x4 model;
model.translate(cubePositions[i]);
float angle;
if (i % 3 == 0) {
angle = (float)m_time.elapsed() / 10;
} else {
angle = i * 20.0f;
}
model.rotate(angle, QVector3D(1.0f, 0.3f, 0.5f));
_shaderProgram.setUniformValue("model", model);
_shaderProgram.setUniformValue("view", view);
_shaderProgram.setUniformValue("projection", projection);
_openGLCore->glDrawArrays(GL_TRIANGLES, 0, 36);
}
update();
}
void CameraWnd::keyPressEvent(QKeyEvent *event) {
if (event->key() == Qt::Key_A) {
m_camera.ProcessKeyboard(Camera_Movement::LEFT, m_deltaTime);
} else if (event->key() == Qt::Key_D) {
m_camera.ProcessKeyboard(Camera_Movement::RIGHT, m_deltaTime);
} else if (event->key() == Qt::Key_W) {
m_camera.ProcessKeyboard(Camera_Movement::FORWARD, m_deltaTime);
} else if (event->key() == Qt::Key_S) {
m_camera.ProcessKeyboard(Camera_Movement::BACKWARD, m_deltaTime);
} else if (event->key() == Qt::Key_E) {
m_camera.ProcessKeyboard(Camera_Movement::UP, m_deltaTime);
} else if (event->key() == Qt::Key_Q) {
m_camera.ProcessKeyboard(Camera_Movement::DOWN, m_deltaTime);
}
}
void CameraWnd::mouseMoveEvent(QMouseEvent *event) {
float xpos = static_cast<float>(event->pos().x());
float ypos = static_cast<float>(event->pos().y());
if (!m_isMousePress)
return;
if (m_firstMouse) {
m_lastX = xpos;
m_lastY = ypos;
m_firstMouse = false;
}
float xoffset = xpos - m_lastX;
float yoffset = m_lastY - ypos; // reversed since y-coordinates go from bottom to top
m_lastX = xpos;
m_lastY = ypos;
m_camera.ProcessMouseMovement(xoffset, yoffset);
}
void CameraWnd::wheelEvent(QWheelEvent *event) {
m_camera.ProcessMouseScroll((float)event->angleDelta().y() / 60.0f);
}
void CameraWnd::mousePressEvent(QMouseEvent *event) {
if (event->button() == Qt::LeftButton)
m_isMousePress = true;
}
void CameraWnd::mouseReleaseEvent(QMouseEvent *event) {
if (event->button() == Qt::LeftButton) {
m_isMousePress = false;
m_firstMouse = true;
}
}
aaa
边栏推荐
- 银泰百货点燃城市“夜经济”
- phpcms 提示信息頁面跳轉showmessage
- 软件测试周刊(第78期):你对未来越有信心,你对现在越有耐心。
- Key switch: press FN when pressing F1-F12
- After watching the video, AI model learned to play my world: cutting trees, making boxes, making stone picks, everything is good
- Understand go language context in one article
- 错排问题 (抽奖,发邮件)
- R语言使用gridExtra包的grid.arrange函数将ggplot2包的多个可视化图像横向组合起来,ncol参数自定义组合图列数、nrow参数自定义组合图行数
- Ripper of vulnhub
- How PHP solves the problem of high concurrency
猜你喜欢

DS90UB949

Gut | Yu Jun group of the Chinese University of Hong Kong revealed that smoking changes intestinal flora and promotes colorectal cancer (do not smoke)

Groovy test class and JUnit test

vulnhub之raven2

Momentum of vulnhub

同事写了一个责任链模式,bug无数...

牛牛的组队竞赛

Spl06-007 air pressure sensor (example of barometer)

Yintai department store ignites the city's "night economy"

Slam mapping and autonomous navigation simulation based on turnlebot3
随机推荐
Notes on 32-96 questions of sword finger offer
Gut | Yu Jun group of the Chinese University of Hong Kong revealed that smoking changes intestinal flora and promotes colorectal cancer (do not smoke)
并发编程-单例
vulnhub之GeminiInc v2
vulnhub之presidential
Vulnhub narak
Yintai department store ignites the city's "night economy"
AI模型看看视频,就学会了玩《我的世界》:砍树、造箱子、制作石镐样样不差...
The tutor put forward 20 pieces of advice to help graduate students successfully complete their studies: first, don't plan to take a vacation
mysql使用update联表更新的方法
. \vmware-vdiskmanager. exe -k “c:\\xxxxx.vmdk”
The world's most popular font editor FontCreator tool
vulnhub之momentum
Vulnhub's cereal
Web security summary
Nestjs配置服务,配置Cookie和Session
Redis things
2022年中南大学夏令营面试经验
vulnhub之pyexp
How to make others fear you