[CORE][ADD] Light Test Version

- Add point light to the left object
- Add ideal distance test
This commit is contained in:
Linloir 2022-12-18 10:05:42 +08:00
parent 3158ced31b
commit 2f4f7b0df1
No known key found for this signature in database
GPG Key ID: 58EEB209A0F2C366
5 changed files with 58 additions and 373 deletions

View File

@ -1,232 +0,0 @@
#include"lightCaster.h"
ShaderProgram* lastShader = NULL;
queue<int> available = queue<int>();
Illuminant::Illuminant(){
Logger::debug("We do not recommend to construct illuminant without parameter");
}
// white color by default
Illuminant::Illuminant(glm::vec3 position, LightType lightType){
_position = position;
setType(lightType);
Logger::info("55555555555");
}
// set up with one color
Illuminant::Illuminant(glm::vec3 position, glm::vec3 color, LightType lightType){
_position = position;
_ambient = color * 0.05f;
_diffuse = color * 0.8f;
_specular = color;
setType(lightType);
Logger::info("4444444444444444444");
}
//set up by assign all colors
Illuminant::Illuminant(glm::vec3 position, glm::vec3 ambient,
glm::vec3 diffuse, glm::vec3 specular, LightType lightType){
_position = position;
_ambient = ambient;
_diffuse = diffuse;
_specular = specular;
setType(lightType);
Logger::info("333333333333333");
}
// set up with one color建议平行光源使用这个
Illuminant::Illuminant(LightType lightType, glm::vec3 direction, glm::vec3 color) {
_direction = direction;
_ambient = color * 0.05f;
_diffuse = color * 0.8f;
_specular = color;
setType(lightType);
Logger::info("22222222222222222");
}
// set up with one color建议聚光灯光源使用这个
Illuminant::Illuminant(glm::vec3 position, glm::vec3 direction, glm::vec3 color, LightType lightType) {
_direction = direction;
_position = position;
_ambient = color * 0.05f;
_diffuse = color * 0.8f;
_specular = color;
setType(lightType);
Logger::info("1111111111111111111");
}
Illuminant::~Illuminant() {
switchOff();
if (_lightType == point) {
available.push(this->pointID);
}
}
void Illuminant::setAttenuation(float constant, float linear, float quadratic){
_constant = constant;
_linear = linear;
_quadratic = quadratic;
}
glm::vec3 Illuminant::direction(){
return _direction;
}
glm::vec3 Illuminant::position(){
return _position;
}
glm::vec3 Illuminant::ambient(){
return _ambient;
}
glm::vec3 Illuminant::diffuse(){
return _diffuse;
}
glm::vec3 Illuminant::specular(){
return _specular;
}
Illuminant::LightType Illuminant::type(){
return _lightType;
}
void Illuminant::move(glm::vec3 deltaPos){
_position += deltaPos;
}
void Illuminant::setPosition(glm::vec3 Pos){
_position = Pos;
}
void Illuminant::setColor(glm::vec3 ambient, glm::vec3 diffuse, glm::vec3 specular){
_ambient = ambient;
_diffuse = diffuse;
_specular = specular;
}
// 使用默认的分配系数
void Illuminant::setColor(glm::vec3 color){
_ambient = color * 0.05f;
_diffuse = color * 0.8f;
_specular = color;
}
void Illuminant::setDirection(glm::vec3 direction) {
_direction = direction;
}
void Illuminant::setType(LightType type){
if (available.size() == 0 and type == point) {
Logger::error("Point light number exceed!\n");
return;
}
_lightType = type;
if (type == point) {
pointID = available.front();
available.pop();
}
}
void Illuminant::updateLight(ShaderProgram& shader) {
lastShader = &shader;
if (_lightType == dir) {
// directional light
shader.setUniform("dirLight.direction", _direction);
shader.setUniform("dirLight.ambient", _ambient);
shader.setUniform("dirLight.diffuse", _diffuse);
shader.setUniform("dirLight.specular",_specular);
}
else if (_lightType == point)
{ // point light 1
string prefix = "pointLights[" + std::to_string(pointID) + "].";
shader.setUniform(prefix+"position", _position);
shader.setUniform(prefix + "ambient", _ambient);
shader.setUniform(prefix + "diffuse", _diffuse);
shader.setUniform(prefix + "specular", _specular);
shader.setUniform(prefix + "constant",_constant);
shader.setUniform(prefix + "linear", _linear);
shader.setUniform(prefix + "quadratic", _quadratic);
}
else {
// spotLight
shader.setUniform("spotLight.position", _position);
shader.setUniform("spotLight.direction", _direction);
shader.setUniform("spotLight.ambient", _ambient);
shader.setUniform("spotLight.diffuse", _diffuse);
shader.setUniform("spotLight.specular", _specular);
shader.setUniform("spotLight.constant", _constant);
shader.setUniform("spotLight.linear", _linear);
shader.setUniform("spotLight.quadratic", _quadratic);
shader.setUniform("spotLight.cutOff", glm::cos(glm::radians(12.5f)));
shader.setUniform("spotLight.outerCutOff", glm::cos(glm::radians(15.0f)));
}
}
void Illuminant::switchOff() {
// 只要没有颜色就行了
setColor(glm::vec3(0.0f, 0.0f, 0.0f));
if (lastShader != NULL) {
updateLight(*lastShader);
}
}
void init_queue() {
for (int i = 0; i < Illuminant::MAXPOINTLIGHT; i++) {
available.push(i);
Logger::info("23533423q543");
}
}
// 如果uniform变量没有被设置可能会出现不可预知的后果
void setAllLigntUniform(ShaderProgram& shader) {
shader.setUniform("dirLight.direction",0,0,-1);
shader.setUniform("dirLight.ambient", 0.1f, 0.1f, 0.1f);
shader.setUniform("dirLight.diffuse", 0.0f, 0.0f, 0.0f);
shader.setUniform("dirLight.specular", 0.0f, 0.0f, 0.0f);
// point light 1
shader.setUniform("pointLights[0].position", 0, 0, 0);
shader.setUniform("pointLights[0].ambient", 0.0f, 0.0f, 0.0f);
shader.setUniform("pointLights[0].diffuse", 0.0f, 0.0f, 0.0f);
shader.setUniform("pointLights[0].specular", 0.0f, 0.0f, 0.0f);
shader.setUniform("pointLights[0].constant", 1.0f);
shader.setUniform("pointLights[0].linear", 0.09f);
shader.setUniform("pointLights[0].quadratic", 0.032f);
// point light 2
shader.setUniform("pointLights[1].position", 0.0f, 0.0f, 0.0f);
shader.setUniform("pointLights[1].ambient", 0.0f, 0.0f, 0.0f);
shader.setUniform("pointLights[1].diffuse", 0.0f, 0.0f, 0.0f);
shader.setUniform("pointLights[1].specular", 0.0f, 0.0f, 0.0f);
shader.setUniform("pointLights[1].constant", 1.0f);
shader.setUniform("pointLights[1].linear", 0.09f);
shader.setUniform("pointLights[1].quadratic", 0.032f);
// point light 3
shader.setUniform("pointLights[2].position", 0.0f, 0.0f, 0.0f);
shader.setUniform("pointLights[2].ambient", 0.0f, 0.0f, 0.0f);
shader.setUniform("pointLights[2].diffuse", 0.0f, 0.0f, 0.0f);
shader.setUniform("pointLights[2].specular", 0.0f, 0.0f, 0.0f);
shader.setUniform("pointLights[2].constant", 1.0f);
shader.setUniform("pointLights[2].linear", 0.09f);
shader.setUniform("pointLights[2].quadratic", 0.032f);
// point light 4
shader.setUniform("pointLights[3].position", 0.0f, 0.0f, 0.0f);
shader.setUniform("pointLights[3].ambient", 0.0f, 0.0f, 0.0f);
shader.setUniform("pointLights[3].diffuse", 0.0f, 0.0f, 0.0f);
shader.setUniform("pointLights[3].specular", 0.0f, 0.0f, 0.0f);
shader.setUniform("pointLights[3].constant", 1.0f);
shader.setUniform("pointLights[3].linear", 0.09f);
shader.setUniform("pointLights[3].quadratic", 0.032f);
// spotLight
shader.setUniform("spotLight.position", 0.0f, 0.0f, 3.0f);
shader.setUniform("spotLight.direction", -0.0f,-0.0f, -1.0f);
shader.setUniform("spotLight.ambient", 0.0f, 0.0f, 0.0f);
shader.setUniform("spotLight.diffuse", 0.0f, 0.0f, 0.0f);
shader.setUniform("spotLight.specular", 0.0f, 0.0f, 0.0f);
shader.setUniform("spotLight.constant", 1.0f);
shader.setUniform("spotLight.linear", 0.09f);
shader.setUniform("spotLight.quadratic", 0.032f);
shader.setUniform("spotLight.cutOff", glm::cos(glm::radians(12.5f)));
shader.setUniform("spotLight.outerCutOff", glm::cos(glm::radians(15.0f)));
}

View File

@ -1,86 +0,0 @@
#pragma once
#include"shader.h"
#include<GLM/glm.hpp>
#include<string>
#include"logger.h"
#include<queue>
using std::queue;
using std::string;
// 发光物不需要纹理所以说需要另外的shader
// 在sceneviewer中被包含
class Illuminant {
public:
enum LightType { dir, spot, point };
int pointID = -1;
private:
LightType _lightType = dir;
glm::vec3 _direction = glm::vec3(0,0,-1);
glm::vec3 _position = glm::vec3(0.0f);
glm::vec3 _ambient = glm::vec3(0.05f, 0.05f, 0.05f);
glm::vec3 _diffuse = glm::vec3(0.8f, 0.8f, 0.8f);
glm::vec3 _specular = glm::vec3(0.8f, 0.8f, 0.8f);
float _constant = 1.0f;
float _linear = 0.09f;
float _quadratic = 0.032f;
public:
// 修改此处必须同步修改fragment shader的数组定义语句目前此值最大为4
const static int MAXPOINTLIGHT = 4;
Illuminant();
// white color by default
Illuminant(glm::vec3 position, LightType lightType);
// set up with one color建议点光源使用这个
Illuminant(glm::vec3 position,glm::vec3 color, LightType lightType);
// set up with one color建议平行光源使用这个
Illuminant(LightType lightType,glm::vec3 direction, glm::vec3 color);
// set up with one color建议聚光灯光源使用这个
Illuminant(glm::vec3 position, glm::vec3 direction,glm::vec3 color, LightType lightType);
//set up by assign all colors
Illuminant(glm::vec3 position, glm::vec3 ambient, glm::vec3 diffuse, glm::vec3 specular, LightType lightType);
// 析构函数中,如果是点光源,应该增加可用点光源数目。不过暂时没有实现,在上层进行控制
// 无论如何,将此函数置为黑色
~Illuminant();
void setAttenuation(float constant, float linear, float quadratic);
glm::vec3 direction();
glm::vec3 position();
glm::vec3 ambient();
glm::vec3 diffuse();
glm::vec3 specular();
LightType type();
void move(glm::vec3 deltaPos);
void setPosition(glm::vec3 Pos);
// 平行光与手电筒必须设置此项
void setDirection(glm::vec3 direction);
void setColor(glm::vec3 ambient, glm::vec3 diffuse, glm::vec3 specular);
// 使用默认的分配系数
void setColor(glm::vec3 color);
// 将本光源的信息传递给着色器
void updateLight(ShaderProgram& shader);
private:
// 只能在最初设定光源类型,没有必要在期间修改
void setType(LightType type);
// 懒惰删除
void switchOff();
};
// 初始设置所有变量
void setAllLigntUniform(ShaderProgram& lightingShader);
void init_queue();

View File

@ -1,9 +1,7 @@
<RCC> <RCC>
<qresource prefix="/shaders"> <qresource prefix="/shaders">
<file>fragmentshader.fs</file> <file>fragmentshader.glsl</file>
<file>vertexshader.vs</file> <file>vertexshader.glsl</file>
<file>illuminant.fs</file>
<file>illuminant.vs</file>
</qresource> </qresource>
<qresource prefix="/fonts"> <qresource prefix="/fonts">
<file>font_awesome_6_regular_free.otf</file> <file>font_awesome_6_regular_free.otf</file>

View File

@ -4,9 +4,9 @@
#include <qresource.h> #include <qresource.h>
#include <qurl.h> #include <qurl.h>
#include <qdir.h> #include <qdir.h>
#include<time.h> #include <time.h>
#include "lightCaster.h" #include "illuminer.h"
SceneViewer::SceneViewer(QWidget* parent) SceneViewer::SceneViewer(QWidget* parent)
@ -30,14 +30,18 @@ SceneViewer::SceneViewer(QWidget* parent)
} }
// Copy the shaders to the temp folder // Copy the shaders to the temp folder
extractShaderResorce("vertexshader.vs"); extractShaderResorce("vertexshader.glsl");
extractShaderResorce("fragmentshader.fs"); extractShaderResorce("fragmentshader.glsl");
extractShaderResorce("illuminant.vs");
extractShaderResorce("illuminant.fs");
} }
SceneViewer::~SceneViewer() { SceneViewer::~SceneViewer() {
if (_dirLight) {
delete _dirLight;
}
for (auto obj : _objects) {
delete obj;
}
} }
void SceneViewer::extractShaderResorce(const QString& shaderName) { void SceneViewer::extractShaderResorce(const QString& shaderName) {
@ -66,20 +70,26 @@ void SceneViewer::initializeGL() {
_shaderProgram.ensureInitialized(); _shaderProgram.ensureInitialized();
Logger::info("Shader Program initialized"); Logger::info("Shader Program initialized");
VertexShader vertexShader("./temp/shaders/vertexshader.vs"); VertexShader vertexShader("./temp/shaders/vertexshader.glsl");
FragmentShader fragmentShader("./temp/shaders/fragmentshader.fs"); FragmentShader fragmentShader("./temp/shaders/fragmentshader.glsl");
_shaderProgram.attachShader(vertexShader); _shaderProgram.attachShader(vertexShader);
_shaderProgram.attachShader(fragmentShader); _shaderProgram.attachShader(fragmentShader);
vertexShader.dispose(); vertexShader.dispose();
fragmentShader.dispose(); fragmentShader.dispose();
setAllLigntUniform(_shaderProgram); // Test Code Start
init_queue(); _dirLight = new DirLight();
addDirLight(glm::vec3(0.3, 0.5, -1), glm::vec3(0.2, 0.1, 0.2)); Model* model = new Model("E:\\Repositories\\CollegeProjects\\CGAssignments\\FinalProject\\Models\\backpack\\backpack.obj");
addSpotLight(glm::vec3(0.3, 0.5, -1), glm::vec3(-0.3, -0.5, 3), glm::vec3(0.2, 1, 0.1)); Renderable* backpack = new Renderable(model);
addPointLight(glm::vec3(0.5, 0.9, 0.4), glm::vec3(1, 0.2, 0.4)); _objects.push_back(backpack);
addPointLight(glm::vec3(-0.3, -0.9, 0.4), glm::vec3(0, 0.2, 0.9));
Renderable* backpack2 = new Renderable(model);
backpack2->move(glm::vec3(-5.0f, -2.0f, -2.0f));
backpack2->makeLight();
backpack2->originalLight()->setIdealDistance(500);
_objects.push_back(backpack2);
// Test Code End
_camera.setPosition(glm::vec3(0.0f, 0.0f, 5.0f)); _camera.setPosition(glm::vec3(0.0f, 0.0f, 5.0f));
} }
@ -100,11 +110,34 @@ void SceneViewer::paintGL() {
glm::mat4 projection = glm::perspective(glm::radians(_camera.zoomVal()), (float)width() / (float)height(), 0.1f, 100.0f); glm::mat4 projection = glm::perspective(glm::radians(_camera.zoomVal()), (float)width() / (float)height(), 0.1f, 100.0f);
_shaderProgram.setUniform("view", view); _shaderProgram.setUniform("view", view);
_shaderProgram.setUniform("projection", projection); _shaderProgram.setUniform("projection", projection);
_shaderProgram.setUniform("viewPos", _camera.position());
update_light();
int pointLights = 0;
int spotLights = 0;
for (auto object : _objects) { for (auto object : _objects) {
object.render(_shaderProgram); if (object->hasLight()) {
ScopedLight light = object->transformedLight();
if (light.isPointLight()) {
light.updateShader(_shaderProgram, pointLights++);
}
else {
light.updateShader(_shaderProgram, spotLights++);
}
}
}
_shaderProgram.setUniform("pointlightnr", pointLights);
_shaderProgram.setUniform("spotlightnr", spotLights);
if (_dirLight != nullptr) {
_dirLight->updateShader(_shaderProgram, 0);
}
_shaderProgram.setUniform("dirlightnr", _dirLight != nullptr ? 1 : 0);
for (auto object : _objects) {
object->render(_shaderProgram);
} }
_shaderProgram.unbind(); _shaderProgram.unbind();
@ -210,24 +243,3 @@ void SceneViewer::resizeEvent(QResizeEvent* event) {
//mask.addRoundedRect(rect(), _cornerRadius, _cornerRadius); //mask.addRoundedRect(rect(), _cornerRadius, _cornerRadius);
//setMask(mask.toFillPolygon().toPolygon()); //setMask(mask.toFillPolygon().toPolygon());
} }
void SceneViewer::update_light() {
setAllLigntUniform(_shaderProgram);
for (int i = 0; i < _illuminants.size(); i++) {
_illuminants[i].updateLight(_shaderProgram);
}
}
void SceneViewer::addDirLight(glm::vec3 direction, glm::vec3 color) {
_illuminants.push_back(Illuminant(Illuminant::LightType::dir, direction,color));
}
void SceneViewer::addPointLight(glm::vec3 position, glm::vec3 color) {
_illuminants.push_back(Illuminant(position, color, Illuminant::LightType::point));
}
void SceneViewer::addSpotLight(glm::vec3 direction, glm::vec3 position, glm::vec3 color) {
_illuminants.push_back(Illuminant(position,direction, color, Illuminant::LightType::spot));
}
void SceneViewer::deleteLight(int index) {
_illuminants.erase(_illuminants.begin() + index);
}

View File

@ -4,17 +4,15 @@
#include <qevent.h> #include <qevent.h>
#include <qopenglfunctions.h> #include <qopenglfunctions.h>
#include <QtOpenGLWidgets/qopenglwidget.h> #include <QtOpenGLWidgets/qopenglwidget.h>
#include <vector> #include <vector>
#include "camera.h" #include "camera.h"
#include "shader.h" #include "shader.h"
#include "renderable.h" #include "renderable.h"
#include "vao.h" #include "illuminer.h"
#include "utils.h" #include "utils.h"
#include "lightCaster.h"
#include "vbo.h"
#include "logger.h" #include "logger.h"
#include "model.h"
class SceneViewer : public QOpenGLWidget, protected QOpenGLFunctions class SceneViewer : public QOpenGLWidget, protected QOpenGLFunctions
@ -24,9 +22,9 @@ class SceneViewer : public QOpenGLWidget, protected QOpenGLFunctions
private: private:
// OpenGL section------------------------------------- // OpenGL section-------------------------------------
// List of objects currently in the scene // List of objects currently in the scene
std::vector<Renderable> _objects; std::vector<Renderable*> _objects;
// List of light casters in the scene // Dir light
std::vector<Illuminant> _illuminants; DirLight* _dirLight = nullptr;
// Shader program for objects // Shader program for objects
ShaderProgram _shaderProgram = ShaderProgram::empty(); ShaderProgram _shaderProgram = ShaderProgram::empty();
// Main camera // Main camera
@ -48,11 +46,6 @@ private:
public: public:
SceneViewer(QWidget* parent = 0); SceneViewer(QWidget* parent = 0);
~SceneViewer(); ~SceneViewer();
void update_light();
void addDirLight(glm::vec3 direction, glm::vec3 color);
void addPointLight(glm::vec3 position, glm::vec3 color);
void addSpotLight(glm::vec3 direction,glm::vec3 position, glm::vec3 color);
void deleteLight(int index);
private: private:
void extractShaderResorce(const QString& shaderName); void extractShaderResorce(const QString& shaderName);