当前位置:网站首页>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
边栏推荐
猜你喜欢

PHP導出word方法(一mht)

Vulnhub's Nagini

Groovy test class and JUnit test

(数据库提权——Redis)Redis未授权访问漏洞总结

The excel table is transferred to word, and the table does not exceed the edge paper range

Unity3D学习笔记5——创建子Mesh

vulnhub之pyexp

PHP export word method (phpword)

OpenGL 索引缓存对象EBO和线宽模式

Talk about the state management mechanism in Flink framework
随机推荐
How to convert a numeric string to an integer
R language uses the aggregate function to calculate the mean value (sum) of dataframe data grouping aggregation without setting na The result of RM calculation. If the group contains the missing value
在CoreOS下部署WordPress实例教程
During FTP login, the error "530 login incorrect.login failed" is reported
Capturing and sorting out external Fiddler -- Conversation bar and filter [2]
836. Merge sets (day 63) and search sets
Go language to realize static server
The excel table is transferred to word, and the table does not exceed the edge paper range
The tutor put forward 20 pieces of advice to help graduate students successfully complete their studies: first, don't plan to take a vacation
Keepalived中Master和Backup角色选举策略
Extrapolated scatter data
Slam mapping and autonomous navigation simulation based on turnlebot3
MySQL searches and sorts out common methods according to time
外插散点数据
Duplicate numbers in the array of sword finger offer 03
OpenGL 索引缓存对象EBO和线宽模式
Capturing and sorting out external Fiddler -- Conversation bar and filter [2]
【mysql专项】读锁和写锁
Talk about the state management mechanism in Flink framework
Socket TCP for network communication (I)