设置相机:
#pragma once
#include <QVector3D>
#include <QMatrix4x4>
class CubeCamera {
public:
CubeCamera();
CubeCamera(QVector3D position,float pitch, float yaw, QVector3D wordUp);
~CubeCamera();
QMatrix4x4 getViewMatrix();
void wheel(int detal);
float&getZoom() {
return _zoom;
}
void keyPress(int key);
void mouseMove(float detalX, float detalY);
private:
void updateCameraVector();
private:
float _pitch = 0.0;
float _yaw = 0.0;
QVector3D _wordUp;
QVector3D _right;
QVector3D _position = QVector3D(0.0, 0.0, -3.0);
QVector3D _up = QVector3D(0.0, 1.0, 0.0);
QVector3D _front = QVector3D(0.0, 0.0, 0.0);
float _zoom = 45.0;
float _zoomStep = 2.0;
};
#include "CubeCamera.h"
CubeCamera::CubeCamera() {
}
CubeCamera::CubeCamera(QVector3D position, float pitch, float yaw, QVector3D wordUp) {
_position = position;
_pitch = pitch;
_yaw = yaw;
_wordUp = wordUp;
updateCameraVector();
}
CubeCamera::~CubeCamera() {
}
QMatrix4x4 CubeCamera::getViewMatrix() {
QMatrix4x4 viewMatrix;
viewMatrix.lookAt(_position, _position + _front, _up);
return viewMatrix;
}
void CubeCamera::wheel(int detal) {
if (detal < 0){
_zoom += _zoomStep;
if (_zoom >= 60.0){
_zoom = 60.0;
}
} else {
_zoom -= _zoomStep;
if (_zoom <= 1.0){
_zoom = 1.0;
}
}
}
void CubeCamera::keyPress(int key) {
if (key == Qt::Key_A) {
_position += _right * 0.1;
} else if (key == Qt::Key_D) {
_position -= _right * 0.1;
} else if (key == Qt::Key_W) {
_position -= _wordUp * 0.1;
} else if (key == Qt::Key_S) {
_position += _wordUp * 0.1;
} else if (key == Qt::Key_E) {
_position += _front *0.1;
} else if (key == Qt::Key_Q) {
_position -= _front *0.1;
}
}
void CubeCamera::mouseMove(float xoffset, float yoffset) {
xoffset *= 0.005;
yoffset *= 0.005;
qDebug() << xoffset<< yoffset;
_yaw -= xoffset;
_pitch += yoffset;
if (_pitch > 89.0f)
_pitch = 89.0f;
if (_pitch < -89.0f)
_pitch = -89.0f;
updateCameraVector();
}
void CubeCamera::updateCameraVector() {
QVector3D front;
front.setX(cos(_yaw) * cos(_pitch));
front.setY(sin(_pitch));
front.setZ(sin(_yaw) * cos(_pitch));
_front = front.normalized();
_right = QVector3D::crossProduct(_front, _wordUp).normalized();
_up = QVector3D::crossProduct(_right, _front).normalized();
}
#pragma once
#include <QOpenGLWindow>
#include <QOpenGLExtraFunctions>
#include <QDebug>
#include <QOpenGLTexture>
#include <QElapsedTimer>
#include <QOpenGLShader>
#include <QOpenGLShaderProgram>
class RotateCubeWnd : public QOpenGLWindow{
Q_OBJECT
public:
RotateCubeWnd();
~RotateCubeWnd();
protected:
void initializeGL()override;
void paintGL()override;
void keyPressEvent(QKeyEvent *event);
void mouseMoveEvent(QMouseEvent *event);
void wheelEvent(QWheelEvent *event);
void mousePressEvent(QMouseEvent *event);
void mouseReleaseEvent(QMouseEvent *event);
private slots:
void slotTimeOut();
private:
GLuint _VBO, _VAO;
class QOpenGLFunctions_3_3_Core* _openGLCore;
QOpenGLShaderProgram _shaderProgram;//着色器程序,所里系统所有的着色器
class QOpenGLTexture *_texture1;
QMatrix4x4 model,view, projection;
class QTimer* _timer = nullptr;
double _angle = 30.0;
class CubeCamera* _cubeCamera = nullptr;
bool _lBtnDown = false;
QPoint _lBtnDownPos;
};
#include "RotateCubeWnd.h"
#include <QKeyEvent>
#include <QMouseEvent>
#include <QWheelEvent>
#include <QTimer>
#include <QOpenGLFunctions_3_3_Core>
#include "CubeCamera.h"
RotateCubeWnd::RotateCubeWnd(){
_timer = new QTimer;
_timer->start(20);
connect(_timer, SIGNAL(timeout()), this, SLOT(slotTimeOut()));
_cubeCamera = new CubeCamera(QVector3D(0.0, 0.0, -4.0), 0.0, 90.0, QVector3D(0.0, 1.0, 0.0));
}
RotateCubeWnd::~RotateCubeWnd(){
}
void RotateCubeWnd::initializeGL() {
_openGLCore = QOpenGLContext::currentContext()->versionFunctions<QOpenGLFunctions_3_3_Core>();
//开启深度测试
_openGLCore->glEnable(GL_DEPTH_TEST);
_openGLCore->glDepthFunc(GL_LESS);
GLfloat vertexData[] = {
// X Y Z U V
// 下
-1.0f,-1.0f,-1.0f, 0.0f, 0.0f,
1.0f,-1.0f,-1.0f, 1.0f, 0.0f,
-1.0f,-1.0f, 1.0f, 0.0f, 1.0f,
1.0f,-1.0f,-1.0f, 1.0f, 0.0f,
1.0f,-1.0f, 1.0f, 1.0f, 1.0f,
-1.0f,-1.0f, 1.0f, 0.0f, 1.0f,
// 上
-1.0f, 1.0f,-1.0f, 0.0f, 0.0f,
-1.0f, 1.0f, 1.0f, 0.0f, 1.0f,
1.0f, 1.0f,-1.0f, 1.0f, 0.0f,
1.0f, 1.0f,-1.0f, 1.0f, 0.0f,
-1.0f, 1.0f, 1.0f, 0.0f, 1.0f,
1.0f, 1.0f, 1.0f, 1.0f, 1.0f,
// 前
-1.0f,-1.0f, 1.0f, 1.0f, 0.0f,
1.0f,-1.0f, 1.0f, 0.0f, 0.0f,
-1.0f, 1.0f, 1.0f, 1.0f, 1.0f,
1.0f,-1.0f, 1.0f, 0.0f, 0.0f,
1.0f, 1.0f, 1.0f, 0.0f, 1.0f,
-1.0f, 1.0f, 1.0f, 1.0f, 1.0f,
// 后
-1.0f,-1.0f,-1.0f, 0.0f, 0.0f,
-1.0f, 1.0f,-1.0f, 0.0f, 1.0f,
1.0f,-1.0f,-1.0f, 1.0f, 0.0f,
1.0f,-1.0f,-1.0f, 1.0f, 0.0f,
-1.0f, 1.0f,-1.0f, 0.0f, 1.0f,
1.0f, 1.0f,-1.0f, 1.0f, 1.0f,
// 左
-1.0f,-1.0f, 1.0f, 0.0f, 1.0f,
-1.0f, 1.0f,-1.0f, 1.0f, 0.0f,
-1.0f,-1.0f,-1.0f, 0.0f, 0.0f,
-1.0f,-1.0f, 1.0f, 0.0f, 1.0f,
-1.0f, 1.0f, 1.0f, 1.0f, 1.0f,
-1.0f, 1.0f,-1.0f, 1.0f, 0.0f,
// 右
1.0f,-1.0f, 1.0f, 1.0f, 1.0f,
1.0f,-1.0f,-1.0f, 1.0f, 0.0f,
1.0f, 1.0f,-1.0f, 0.0f, 0.0f,
1.0f,-1.0f, 1.0f, 1.0f, 1.0f,
1.0f, 1.0f,-1.0f, 0.0f, 0.0f,
1.0f, 1.0f, 1.0f, 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(vertexData), vertexData, GL_STATIC_DRAW);
// 位置属性
_openGLCore->glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)0);
_openGLCore->glEnableVertexAttribArray(0);
// 坐标属性
_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/RotateCube/a.jpg").mirrored());
if (!_texture1->isCreated()) {
qDebug() << "Failed to load texture";
}
_texture1->setWrapMode(QOpenGLTexture::DirectionS, QOpenGLTexture::Repeat);
_texture1->setWrapMode(QOpenGLTexture::DirectionT, QOpenGLTexture::Repeat);
_texture1->setMinificationFilter(QOpenGLTexture::Linear);
_texture1->setMagnificationFilter(QOpenGLTexture::Linear);
_shaderProgram.addShaderFromSourceFile(QOpenGLShader::Vertex, "E:/Projects/QtGuiTest/OPenGLApp/RotateCube/RotateCube.vert");
_shaderProgram.addShaderFromSourceFile(QOpenGLShader::Fragment, "E:/Projects/QtGuiTest/OPenGLApp/RotateCube/RotateCube.frag");
_shaderProgram.link();
_shaderProgram.bind();
_shaderProgram.setUniformValue("textureImg", 0);
model.rotate(45.0, QVector3D(1.0, 1.0, 1.0));
model.scale(0.5);
view = _cubeCamera->getViewMatrix();
}
void RotateCubeWnd::paintGL() {
_openGLCore->glClearColor(0.4f, 0.4f, 0.4f, 1.0f);
_openGLCore->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
_openGLCore->glActiveTexture(GL_TEXTURE0);
_texture1->bind();
_shaderProgram.bind();
#if 0
QMatrix4x4 view;
/*
第一个参数相当于改变摄像头的观察位置,有规律的改变这个值就能起到从不同角度观察物体的效果。
而改变第二个参数则相当于改变世界坐标系的原点,整个世界坐标系上的物体将随之移动。
*/
view.lookAt(QVector3D(0.0f, 0.0f, -3.0f), QVector3D(0.0, 0.0, 0.0), QVector3D(0.0, 1.0, 0.0));
view.rotate(_angle, QVector3D(0.0, 1.0, 0.0));
#else
QMatrix4x4 view = _cubeCamera->getViewMatrix();
#endif
QMatrix4x4 projection;
projection.perspective(_cubeCamera->getZoom(), width() / height(), 0.1, 100);
_shaderProgram.setUniformValue("model", model);
_shaderProgram.setUniformValue("view", view);
_shaderProgram.setUniformValue("projection", projection);
/*
立方体6个面,每个面有2个三角形,每个三角形有3个顶点,所以需要绘制的顶点数是:6 × 2 × 3 = 36
*/
_openGLCore->glDrawArrays(GL_TRIANGLES, 0, 36);
update();
}
void RotateCubeWnd::keyPressEvent(QKeyEvent *event) {
_cubeCamera->keyPress(event->key());
}
void RotateCubeWnd::mouseMoveEvent(QMouseEvent *event) {
if (_lBtnDown){
float xpos = static_cast<float>(event->pos().x());
float ypos = static_cast<float>(event->pos().y());
float xoffset = _lBtnDownPos.x() - xpos;
float yoffset = _lBtnDownPos.y() - ypos;
_lBtnDownPos = event->pos();
_cubeCamera->mouseMove(xoffset, yoffset);
}
}
void RotateCubeWnd::wheelEvent(QWheelEvent *event) {
_cubeCamera->wheel(event->delta());
update();
}
void RotateCubeWnd::mousePressEvent(QMouseEvent *event) {
if (event->button() == Qt::LeftButton){
_lBtnDown = true;
_lBtnDownPos = event->pos();
}
}
void RotateCubeWnd::mouseReleaseEvent(QMouseEvent *event) {
if (event->button() == Qt::LeftButton) {
_lBtnDown = false;
}
}
void RotateCubeWnd::slotTimeOut() {
_angle += 1.0;
//update();
}
#include "OPenGLApp.h"
#include <QtWidgets/QApplication>
#include <QtOpenGL/QtOpenGL>
#include "MyOpenGLWnd.h"
#include "EBOWnd.h"
#include "HelloShader.h"
#include "HelloShaderSelf.h"
#include "TextureWnd.h"
#include "CameraWnd.h"
#include "QOpenGLLight.h"
#include "RotateCube/RotateCubeWnd.h"
int main(int argc, char *argv[]) {
QApplication a(argc, argv);
RotateCubeWnd window;
window.setTitle(QStringLiteral("这是一个OpenGL窗口"));
window.resize(800, 800);
window.show();
return a.exec();
}
顶点着色器:
#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 = projection * view * model * vec4(aPos, 1.0);
textureCoord = aTextureCoord;
}
片段着色器:
#version 330 core
out vec4 fragColor;
in vec3 outColor;//从顶点着色器中传过来的颜色
in vec2 textureCoord;
uniform sampler2D textureImg;
void main(){
fragColor = texture(textureImg, textureCoord);
}
aaa