当前位置:网站首页>Qt OPenGL 光的漫反射
Qt OPenGL 光的漫反射
2022-07-27 18:29:00 【wb175208】
先看效果:
相机:
#pragma once
#include <QVector3D>
#include <QMatrix4x4>
class DiffuseLightCamera {
public:
DiffuseLightCamera(QVector3D position, float pitch, float yaw, QVector3D wordUp);
~DiffuseLightCamera();
QMatrix4x4 getViewMatrix();
void wheel(int detal);
float&getZoom() {
return _zoom;
}
void keyPress(int key);
void mouseMove(float xoffset, float yoffset);
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 "DiffuseLightCamera.h"
DiffuseLightCamera::DiffuseLightCamera(QVector3D position, float pitch, float yaw, QVector3D wordUp) {
_position = position;
_pitch = pitch;
_yaw = yaw;
_wordUp = wordUp;
updateCameraVector();
}
DiffuseLightCamera::~DiffuseLightCamera() {
}
QMatrix4x4 DiffuseLightCamera::getViewMatrix() {
QMatrix4x4 viewMatrix;
viewMatrix.lookAt(_position, _position + _front, _up);
return viewMatrix;
}
void DiffuseLightCamera::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 DiffuseLightCamera::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 DiffuseLightCamera::mouseMove(float xoffset, float yoffset) {
xoffset *= 0.005;
yoffset *= 0.005;
_yaw -= xoffset;
_pitch += yoffset;
if (_pitch > 89.0f)
_pitch = 89.0f;
if (_pitch < -89.0f)
_pitch = -89.0f;
updateCameraVector();
}
void DiffuseLightCamera::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 DiffuseLightWnd : public QOpenGLWindow {
Q_OBJECT
public:
DiffuseLightWnd();
~DiffuseLightWnd();
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);
void resizeGL(int w, int h) Q_DECL_OVERRIDE;
private:
void drawObj();
private:
GLuint _VBO, _VAO;
class QOpenGLFunctions_3_3_Core* _openGLCore;
QOpenGLShaderProgram _shaderProgram;//着色器程序,所里系统所有的着色器
QMatrix4x4 model, view, projection;
class DiffuseLightCamera* _diffuseLightCamera = nullptr;
bool _lBtnDown = false;
QPoint _lBtnDownPos;
};
#include "DiffuseLightWnd.h"
#include <QKeyEvent>
#include <QMouseEvent>
#include <QWheelEvent>
#include <QTimer>
#include <QOpenGLFunctions_3_3_Core>
#include "DiffuseLightCamera.h"
DiffuseLightWnd::DiffuseLightWnd() {
_diffuseLightCamera = new DiffuseLightCamera(QVector3D(0.0, 0.0, -4.0), 0.0, 90.0, QVector3D(0.0, 1.0, 0.0));
}
DiffuseLightWnd::~DiffuseLightWnd() {
}
void DiffuseLightWnd::initializeGL() {
_openGLCore = QOpenGLContext::currentContext()->versionFunctions<QOpenGLFunctions_3_3_Core>();
//开启深度测试
_openGLCore->glEnable(GL_DEPTH_TEST);
_openGLCore->glDepthFunc(GL_LESS);
// 顶点数据(纹理坐标未使用)
float vertices[] = {
// positions // normal vector // texture
-0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f,
0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 1.0f, 0.0f,
0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 1.0f, 1.0f,
0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 1.0f, 1.0f,
-0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 0.0f, 1.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f,
// 2
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f,
0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f,
0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f,
-0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f,
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
// 3
-0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, 1.0f, 0.0f,
-0.5f, 0.5f, -0.5f, -1.0f, 0.0f, 0.0f, 1.0f, 1.0f,
-0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f,
-0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f,
-0.5f, -0.5f, 0.5f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f,
-0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, 1.0f, 0.0f,
// 4
0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f,
0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f,
0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f,
0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f,
0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f,
0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f,
// 5
-0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, 0.0f, 1.0f,
0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, 1.0f, 1.0f,
0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f,
0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f,
-0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f,
-0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, 0.0f, 1.0f,
// 6
-0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f,
0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f,
0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f,
0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f,
-0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f,
-0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f,
};
// 1.创建对象
_openGLCore->glGenVertexArrays(1, &_VAO);
_openGLCore->glGenBuffers(1, &_VBO);
// 2.绑定对象
_openGLCore->glBindVertexArray(_VAO);
_openGLCore->glBindBuffer(GL_ARRAY_BUFFER, _VBO);
// 3.数据存放
_openGLCore->glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
// 4.解析数据
_openGLCore->glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)0);
_openGLCore->glEnableVertexAttribArray(0);
// 5.顶点法向量
_openGLCore->glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(3 * sizeof(float)));
_openGLCore->glEnableVertexAttribArray(1);
// 6.解绑
_openGLCore->glBindBuffer(GL_ARRAY_BUFFER, 0);
_openGLCore->glBindVertexArray(0);
// 7.着色器程序
_shaderProgram.addShaderFromSourceFile(QOpenGLShader::Vertex, "E:/Projects/QtGuiTest/OPenGLApp/DiffuseLight/DiffuseLight.vert");
_shaderProgram.addShaderFromSourceFile(QOpenGLShader::Fragment, "E:/Projects/QtGuiTest/OPenGLApp/DiffuseLight/DiffuseLight.frag");
_shaderProgram.link();
}
void DiffuseLightWnd::paintGL() {
_openGLCore->glClearColor(0.4f, 0.4f, 0.4f, 1.0f);
_openGLCore->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
_openGLCore->glBindVertexArray(_VAO);
drawObj();
update();
}
void DiffuseLightWnd::keyPressEvent(QKeyEvent *event) {
_diffuseLightCamera->keyPress(event->key());
}
void DiffuseLightWnd::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();
_diffuseLightCamera->mouseMove(xoffset, yoffset);
}
}
void DiffuseLightWnd::wheelEvent(QWheelEvent *event) {
_diffuseLightCamera->wheel(event->delta());
update();
}
void DiffuseLightWnd::mousePressEvent(QMouseEvent *event) {
if (event->button() == Qt::LeftButton) {
_lBtnDown = true;
_lBtnDownPos = event->pos();
}
}
void DiffuseLightWnd::mouseReleaseEvent(QMouseEvent *event) {
if (event->button() == Qt::LeftButton) {
_lBtnDown = false;
}
}
void DiffuseLightWnd::resizeGL(int w, int h) {
glViewport(0, 0, w, h);
}
void DiffuseLightWnd::drawObj() {
_shaderProgram.bind();
QMatrix4x4 model;
model.rotate(45.0, QVector3D(1.0, 1.0, 1.0));
model.scale(0.5);
QMatrix4x4 view = _diffuseLightCamera->getViewMatrix();
QMatrix4x4 projection;
projection.perspective(_diffuseLightCamera->getZoom(), width() / height(), 0.1, 100);
_shaderProgram.setUniformValue("model", model);
_shaderProgram.setUniformValue("view", view);
_shaderProgram.setUniformValue("projection", projection);
_shaderProgram.setUniformValue("objectColor", 1.0f, 0.5f, 0.31f);
_shaderProgram.setUniformValue("lightColor", 1.0f, 1.0f, 1.0f);
_shaderProgram.setUniformValue("lightPos", 0.0f, 0.0f, -4.0f);
_openGLCore->glDrawArrays(GL_TRIANGLES, 0, 36);
}
顶点着色器:
#version 330 core
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec3 aNormal;
out vec3 Normal;
out vec3 FragPos;
//矩阵必须初始化,初始化单位矩阵,否则GLSL语言中默认矩阵是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);
FragPos = vec3(model * vec4(aPos, 1.0)); // 利用模型矩阵获取片元位置
Normal = mat3(transpose(inverse(model))) * aNormal;
}
片段着色器:
#version 330 core
out vec4 fragColor;
in vec3 Normal;
in vec3 FragPos;
uniform vec3 lightPos;
uniform vec3 lightColor;
uniform vec3 objectColor;
uniform vec3 viewPos;//镜面反射使用 - 相机的位置
void main(){
//环境光
float ambientStrength = 0.1;
vec3 ambient = ambientStrength * lightColor;
//漫反射
// 1.正则化片元位置矢量和光源方向矢量。
vec3 norm = normalize(Normal);
vec3 lightDir = normalize(lightPos - FragPos);
// 2.计算扩散光的对光源颜色的影响。
float diff = max(dot(norm, lightDir), 0.0);
vec3 diffuse = diff * lightColor;
// 3.根据环境光和扩散光计算最终片元颜色。
vec3 result = (ambient + diffuse) * objectColor;
// 下面计算镜面光照
/* ** float specularStrength = 0.5; ** vec3 viewDir = normalize(viewPos - FragPos); ** vec3 reflectDir = reflect(-lightDir, norm); ** float spec = pow(max(dot(viewDir, reflectDir), 0.0), 32); ** vec3 specular = specularStrength * spec * lightColor; ** vec3 result = (ambient + diffuse + specular) * objectColor; */
fragColor = vec4(result, 1.0);
}
aaa
边栏推荐
- JVs privatization deployment start failure handling scheme
- 程序中的地址如何转换?
- Brand list cases
- Best practices for Oracle kingbasees migration of Jincang database (2. Overview)
- IOU 目标跟踪其一:IOU Tracker
- 金仓数据库 KingbaseES异构数据库移植指南 (3. KingbaseES移植能力支撑体系)
- API Gateway介绍
- Arduino开发(二)_基于Arduino UNO开发板的RGB灯光控制方法
- How to translate the address in the program?
- Hexagon_V65_Programmers_Reference_Manual(6)
猜你喜欢

hcip第五天

LabVIEW学习笔记九:捕捉由程序修改控件值产生的“值改变”事件

How does the industrial switch enter the web management interface?

vi工作模式(3种)以及模式切换(转换)

Hcip day 5

Arduino开发(二)_基于Arduino UNO开发板的RGB灯光控制方法

未定义变量 “Lattice“ 或类 “Lattice.latticeEasy“(Matlab)
![[Numpy] 广播机制(Broadcast)](/img/1f/8d61ac7b35a82067bc0b77426590eb.png)
[Numpy] 广播机制(Broadcast)

Introduction to rk3399 platform introduction to proficient series (Introduction) 21 day learning challenge

knife4j通过js动态刷新全局参数
随机推荐
用户登录切换案例
One article to understand pychar shortcut key
认识网络模型TCPIP模型
Hcip day 5
People call this software testing engineer. You're just making a living (with HR interview Dictionary)
Where is the program?
Force deduction solution summary 592 fraction addition and subtraction
Onion group joined hands with oceanbase to realize distributed upgrading, and global data has achieved cross cloud integration for the first time
Tencent jumped out with 38K and saw the real test ceiling
Best practices for Oracle kingbasees migration of Jincang database (2. Overview)
CPDA|如何拥有数据分析思维?
Hexagon_V65_Programmers_Reference_Manual(6)
【深度学习】Pytorch Tensor 张量
R语言dplyr包summarise_at函数计算dataframe数据中多个数据列(通过向量指定)的计数个数、均值和中位数、使用list函数指定函数列表(使用.符号和~符号指定函数语法purr)
金仓数据库 Oracle至KingbaseES迁移最佳实践(2. 概述)
洋葱集团携手OceanBase实现分布式升级,全球数据首次实现跨云融合
Advanced SQL skills CTE and recursive query
推荐一款强大的搜索工具Listary
[Numpy] 数组属性
[deep learning] pytoch tensor