先看上一篇文章:Qt Opengl 给两个立方体设置两中不同颜色
使用环境光非常的简单,我们只需要设置一个环境光强度,用这个强度值乘上光源的颜色得到环境光颜色。最后,用环境光颜色乘上物体的颜色,得到物体在光照下的最终颜色值。先看效果:
#pragma once
#include <QOpenGLWindow>
#include <QOpenGLWindow>
#include <QOpenGLExtraFunctions>
#include <QDebug>
#include <QOpenGLTexture>
#include <QElapsedTimer>
#include <QOpenGLShader>
#include <QOpenGLShaderProgram>
//光照界面练习
class BaseLightWnd : public QOpenGLWindow{
Q_OBJECT
public:
BaseLightWnd();
~BaseLightWnd();
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:
void drawObj();
void drawLight();
private slots:
void slotTimeout();
private:
GLuint _VBO, _VAO;
class QOpenGLFunctions_3_3_Core* _openGLCore;
QOpenGLShaderProgram _shaderProgram;//着色器程序,所里系统所有的着色器
QOpenGLShaderProgram _shaderProgram1;//着色器程序,所里系统所有的着色器
QMatrix4x4 model, view, projection;
class BaseLightCamera* _baseLightCamera = nullptr;
bool _lBtnDown = false;
QPoint _lBtnDownPos;
class QTimer* _timer = nullptr;
float _ambientStrength = 0.0;//关照强度
float _stepStrength = 0.05;
};
#include "BaseLightWnd.h"
#include <QKeyEvent>
#include <QMouseEvent>
#include <QWheelEvent>
#include <QTimer>
#include <QOpenGLFunctions_3_3_Core>
#include "BaseLightCamera.h"
BaseLightWnd::BaseLightWnd() {
_baseLightCamera = new BaseLightCamera(QVector3D(0.0, 0.0, -4.0), 0.0, 90.0, QVector3D(0.0, 1.0, 0.0));
_timer = new QTimer();
connect(_timer, SIGNAL(timeout()), this, SLOT(slotTimeout()));
_timer->start(100);
}
BaseLightWnd::~BaseLightWnd() {
}
void BaseLightWnd::initializeGL() {
_openGLCore = QOpenGLContext::currentContext()->versionFunctions<QOpenGLFunctions_3_3_Core>();
//开启深度测试
_openGLCore->glEnable(GL_DEPTH_TEST);
_openGLCore->glDepthFunc(GL_LESS);
//顶点数据
GLfloat vertexData[] = {
// X Y Z
// 下
-1.0f,-1.0f,-1.0f,
1.0f,-1.0f,-1.0f,
-1.0f,-1.0f, 1.0f,
1.0f,-1.0f,-1.0f,
1.0f,-1.0f, 1.0f,
-1.0f,-1.0f, 1.0f,
// 上
-1.0f, 1.0f,-1.0f,
-1.0f, 1.0f, 1.0f,
1.0f, 1.0f,-1.0f,
1.0f, 1.0f,-1.0f,
-1.0f, 1.0f, 1.0f,
1.0f, 1.0f, 1.0f,
// 前
-1.0f,-1.0f, 1.0f,
1.0f,-1.0f, 1.0f,
-1.0f, 1.0f, 1.0f,
1.0f,-1.0f, 1.0f,
1.0f, 1.0f, 1.0f,
-1.0f, 1.0f, 1.0f,
// 后
-1.0f,-1.0f,-1.0f,
-1.0f, 1.0f,-1.0f,
1.0f,-1.0f,-1.0f,
1.0f,-1.0f,-1.0f,
-1.0f, 1.0f,-1.0f,
1.0f, 1.0f,-1.0f,
// 左
-1.0f,-1.0f, 1.0f,
-1.0f, 1.0f,-1.0f,
-1.0f,-1.0f,-1.0f,
-1.0f,-1.0f, 1.0f,
-1.0f, 1.0f, 1.0f,
-1.0f, 1.0f,-1.0f,
// 右
1.0f,-1.0f, 1.0f,
1.0f,-1.0f,-1.0f,
1.0f, 1.0f,-1.0f,
1.0f,-1.0f, 1.0f,
1.0f, 1.0f,-1.0f,
1.0f, 1.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(vertexData), vertexData, GL_STATIC_DRAW);
// 4.解析数据
_openGLCore->glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
_openGLCore->glEnableVertexAttribArray(0);
// 5.解绑
_openGLCore->glBindBuffer(GL_ARRAY_BUFFER, 0);
_openGLCore->glBindVertexArray(0);
// 6.着色器程序
_shaderProgram.addShaderFromSourceFile(QOpenGLShader::Vertex, "E:/Projects/QtGuiTest/OPenGLApp/BaseLight/BaseLight.vert");
_shaderProgram.addShaderFromSourceFile(QOpenGLShader::Fragment, "E:/Projects/QtGuiTest/OPenGLApp/BaseLight/ObjLight.frag");
_shaderProgram.link();
_shaderProgram1.addShaderFromSourceFile(QOpenGLShader::Vertex, "E:/Projects/QtGuiTest/OPenGLApp/BaseLight/BaseLight.vert");
_shaderProgram1.addShaderFromSourceFile(QOpenGLShader::Fragment, "E:/Projects/QtGuiTest/OPenGLApp/BaseLight/BaseLight.frag");
_shaderProgram1.link();
}
void BaseLightWnd::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();
drawLight();
update();
}
void BaseLightWnd::keyPressEvent(QKeyEvent *event) {
_baseLightCamera->keyPress(event->key());
}
void BaseLightWnd::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();
_baseLightCamera->mouseMove(xoffset, yoffset);
}
}
void BaseLightWnd::wheelEvent(QWheelEvent *event) {
_baseLightCamera->wheel(event->delta());
update();
}
void BaseLightWnd::mousePressEvent(QMouseEvent *event) {
if (event->button() == Qt::LeftButton) {
_lBtnDown = true;
_lBtnDownPos = event->pos();
}
}
void BaseLightWnd::mouseReleaseEvent(QMouseEvent *event) {
if (event->button() == Qt::LeftButton) {
_lBtnDown = false;
}
}
void BaseLightWnd::drawObj() {
_shaderProgram.bind();
QMatrix4x4 model;
model.rotate(45.0, QVector3D(1.0, 0.0, 0.0));
model.scale(0.5);
QMatrix4x4 view = _baseLightCamera->getViewMatrix();
QMatrix4x4 projection;
projection.perspective(_baseLightCamera->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("ambientStrength", _ambientStrength);
_openGLCore->glDrawArrays(GL_TRIANGLES, 0, 36);
}
void BaseLightWnd::drawLight() {
_shaderProgram1.bind();
QMatrix4x4 model;
model.rotate(45.0, QVector3D(0.0, 1.0, 0.0));
model.scale(0.2);
model.translate(10.0, 0.0, 0.0);
QMatrix4x4 view = _baseLightCamera->getViewMatrix();
QMatrix4x4 projection;
projection.perspective(_baseLightCamera->getZoom(), width() / height(), 0.1, 100);
_shaderProgram1.setUniformValue("model", model);
_shaderProgram1.setUniformValue("view", view);
_shaderProgram1.setUniformValue("projection", projection);
_openGLCore->glDrawArrays(GL_TRIANGLES, 0, 36);
}
void BaseLightWnd::slotTimeout() {
_ambientStrength += _stepStrength;
if (_ambientStrength>= 1.0){
_stepStrength = -0.05;
}else if (_ambientStrength <= 0.0){
_stepStrength = 0.05;
}
}
片段着色器:
#version 330 core
out vec4 FragColor;
uniform vec3 objectColor;
uniform vec3 lightColor;
uniform float ambientStrength;
void main()
{
/*
正常情况下
光照×物体的样色 = 反射光颜色
*/
// FragColor = vec4(lightColor * objectColor, 1.0);
/*
环境光
环境光强度×环境光×物体颜色 = 反射光颜色
*/
//float ambientStrength = 0.5;
vec3 ambient = ambientStrength * lightColor;
vec3 result = ambient * objectColor;
FragColor = vec4(result, 1.0f);
}
aaa