QT openGL环境光照

16 篇文章 14 订阅

先看上一篇文章: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

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

wb175208

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值