当前位置:网站首页>Use of QT OpenGL camera
Use of QT OpenGL camera
2022-07-03 12:00:00 【wb175208】
Look at the effect :
Vertex shader :
#version 330 core
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec2 aTextureCoord;
out vec3 outColor;
out vec2 textureCoord;
// Matrix must be initialized , Initialize identity matrix , otherwise GLSL The default matrix in the language is 0 matrix
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);// In matrix multiplication, it is right times left , Different from the multiplication of explicit reality
gl_Position = projection * view * model * vec4(aPos, 1.0);
textureCoord = aTextureCoord;
}
Fragment Shader :
#version 330 core
out vec4 fragColor;
in vec3 outColor;// Color passed from vertex shader
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);
}
Cameras :
#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();
}
};
Interface class :
#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;// Shader program , All shaders in the system
};
#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);
// Vertical mirror 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);
// Sets the texture cell number
_shaderProgram.addShaderFromSourceFile(QOpenGLShader::Vertex, "E:/Projects/QtGuiTest/OPenGLApp/shader/Camera.vert");
_shaderProgram.addShaderFromSourceFile(QOpenGLShader::Fragment, "E:/Projects/QtGuiTest/OPenGLApp/shader/Camera.frag");
_shaderProgram.link();
// If it's an image, you don't need to bind , The default binding . If it is more than 1 Zhang needs to actively bind ,
_shaderProgram.bind();
/* ** textureImg: Of the corresponding slice shader uniform sampler2D textureImg; ** textureCpp: Of the corresponding slice shader 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;
// Activate texture unit 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
边栏推荐
- 小鹏 P7 撞护栏安全气囊未弹出,官方回应称撞击力度未达到弹出要求
- Solution à la défaillance de l'installation d'Electron
- DNS multi-point deployment IP anycast+bgp actual combat analysis
- vulnhub之GeminiInc v2
- Master and backup role election strategy in kept
- Qt OpenGL相机的使用
- 剑指offer专项32-96题做题笔记
- The R language uses the hist function in the native package (basic import package, graphics) to visualize the histogram plot
- 优化接口性能
- Slam mapping and autonomous navigation simulation based on turnlebot3
猜你喜欢

Vulnhub's presidential

win10 上PHP artisan storage:link 出现 symlink (): Protocol error的解决办法

STL教程10-容器共性和使用场景

vulnhub之Nagini

Unity3d learning notes 5 - create sub mesh

2022年湖南工学院ACM集训第二次周测题解

Kubernetes 三打探针及探针方式

牛牛的组队竞赛

Groovy test class and JUnit test

Colleagues wrote a responsibility chain model, with countless bugs
随机推荐
量化计算调研
(database authorization - redis) summary of unauthorized access vulnerabilities in redis
Go语言实现静态服务器
R language uses grid of gridextra package The array function combines multiple visual images of the ggplot2 package horizontally, and the ncol parameter defines the number of columns of the combined g
laravel 时区问题timezone
vulnhub之presidential
AOSP ~ NTP (Network Time Protocol)
PHP Basics
MCDF实验1
Vulnhub pyexp
【学习笔记】dp 状态与转移
Symlink(): solution to protocol error in PHP artisan storage:link on win10
Introduction to the implementation principle of rxjs observable filter operator
Yintai department store ignites the city's "night economy"
Sheet1$. Output [excel source output] Error in column [xxx]. The returned column status is: "the text is truncated, or one or more characters have no matches in the target code page.".
Socket TCP for network communication (I)
Differences between MySQL Union and union all
【mysql专项】读锁和写锁
MySQL searches and sorts out common methods according to time
小鹏 P7 撞护栏安全气囊未弹出,官方回应称撞击力度未达到弹出要求