diff --git a/FinalProject/FinalProject.vcxproj b/FinalProject/FinalProject.vcxproj
index f3f0de1..2df4171 100644
--- a/FinalProject/FinalProject.vcxproj
+++ b/FinalProject/FinalProject.vcxproj
@@ -108,6 +108,7 @@
+
@@ -142,6 +143,8 @@
+
+
diff --git a/FinalProject/FinalProject.vcxproj.filters b/FinalProject/FinalProject.vcxproj.filters
index 7638a20..6a5c503 100644
--- a/FinalProject/FinalProject.vcxproj.filters
+++ b/FinalProject/FinalProject.vcxproj.filters
@@ -165,6 +165,9 @@
Source Files\Qt Widgets\Pages\Scene Editor\Object Selector
+
+ Source Files\OpenGL Abstractions
+
@@ -206,6 +209,12 @@
Header Files\Qt Widgets\Pages\Scene Editor\Object Setter
+
+ Header Files\OpenGL Abstractions
+
+
+ Header Files\OpenGL Abstractions
+
diff --git a/FinalProject/fragmentshader.fs b/FinalProject/fragmentshader.fs
index 556286e..5dbf34b 100644
--- a/FinalProject/fragmentshader.fs
+++ b/FinalProject/fragmentshader.fs
@@ -1,13 +1,148 @@
#version 430 core
out vec4 FragColor;
+struct Material {
+ sampler2D texture_diffuse1;
+ sampler2D texture_specular1;
+ float shininess;
+};
+
+struct DirLight {
+ vec3 direction;
+
+ vec3 ambient;
+ vec3 diffuse;
+ vec3 specular;
+};
+
+struct PointLight {
+ vec3 position;
+
+ float constant;
+ float linear;
+ float quadratic;
+
+ vec3 ambient;
+ vec3 diffuse;
+ vec3 specular;
+};
+
+struct SpotLight {
+ vec3 position;
+ vec3 direction;
+ float cutOff;
+ float outerCutOff;
+
+ float constant;
+ float linear;
+ float quadratic;
+
+ vec3 ambient;
+ vec3 diffuse;
+ vec3 specular;
+};
+
+#define NR_POINT_LIGHTS 4
+
+in vec3 FragPos;
+in vec3 Normal;
in vec2 TexCoords;
-uniform sampler2D texture_diffuse1;
-uniform sampler2D texture_specular1;
+
+uniform vec3 viewPos;
+uniform DirLight dirLight;
+uniform PointLight pointLights[NR_POINT_LIGHTS];
+uniform SpotLight spotLight;
+uniform Material material;
+
+// function prototypes
+vec3 CalcDirLight(DirLight light, vec3 normal, vec3 viewDir);
+vec3 CalcPointLight(PointLight light, vec3 normal, vec3 fragPos, vec3 viewDir);
+vec3 CalcSpotLight(SpotLight light, vec3 normal, vec3 fragPos, vec3 viewDir);
void main()
{
- FragColor = texture(texture_specular1, TexCoords);
- FragColor = texture(texture_diffuse1, TexCoords);
+ // properties
+ vec3 norm = normalize(Normal);
+ vec3 viewDir = normalize(viewPos - FragPos);
+
+ // == =====================================================
+ // Our lighting is set up in 3 phases: directional, point lights and an optional flashlight
+ // For each phase, a calculate function is defined that calculates the corresponding color
+ // per lamp. In the main() function we take all the calculated colors and sum them up for
+ // this fragment's final color.
+ // == =====================================================
+ // phase 1: directional lighting
+ vec3 result = CalcDirLight(dirLight, norm, viewDir);
+ // phase 2: point lights
+ for(int i = 0; i < NR_POINT_LIGHTS; i++)
+ result += CalcPointLight(pointLights[i], norm, FragPos, viewDir);
+ // phase 3: spot light
+ result += CalcSpotLight(spotLight, norm, FragPos, viewDir);
+
+ FragColor = vec4(result, 1.0);
+}
+
+// calculates the color when using a directional light.
+vec3 CalcDirLight(DirLight light, vec3 normal, vec3 viewDir)
+{
+ vec3 lightDir = normalize(-light.direction);
+ // diffuse shading
+ float diff = max(dot(normal, lightDir), 0.0);
+ // specular shading
+ vec3 reflectDir = reflect(-lightDir, normal);
+ float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess);
+ // combine results
+ vec3 ambient = light.ambient * vec3(texture(material.texture_diffuse1, TexCoords));
+ vec3 diffuse = light.diffuse * diff * vec3(texture(material.texture_diffuse1, TexCoords));
+ vec3 specular = light.specular * spec * vec3(texture(material.texture_specular1, TexCoords));
+ return (ambient + diffuse + specular);
+}
+
+// calculates the color when using a point light.
+vec3 CalcPointLight(PointLight light, vec3 normal, vec3 fragPos, vec3 viewDir)
+{
+ vec3 lightDir = normalize(light.position - fragPos);
+ // diffuse shading
+ float diff = max(dot(normal, lightDir), 0.0);
+ // specular shading
+ vec3 reflectDir = reflect(-lightDir, normal);
+ float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess);
+ // attenuation
+ float distance = length(light.position - fragPos);
+ float attenuation = 1.0 / (light.constant + light.linear * distance + light.quadratic * (distance * distance));
+ // combine results
+ vec3 ambient = light.ambient * vec3(texture(material.texture_diffuse1, TexCoords));
+ vec3 diffuse = light.diffuse * diff * vec3(texture(material.texture_diffuse1, TexCoords));
+ vec3 specular = light.specular * spec * vec3(texture(material.texture_specular1, TexCoords));
+ ambient *= attenuation;
+ diffuse *= attenuation;
+ specular *= attenuation;
+ return (ambient + diffuse + specular);
+}
+
+// calculates the color when using a spot light.
+vec3 CalcSpotLight(SpotLight light, vec3 normal, vec3 fragPos, vec3 viewDir)
+{
+ vec3 lightDir = normalize(light.position - fragPos);
+ // diffuse shading
+ float diff = max(dot(normal, lightDir), 0.0);
+ // specular shading
+ vec3 reflectDir = reflect(-lightDir, normal);
+ float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess);
+ // attenuation
+ float distance = length(light.position - fragPos);
+ float attenuation = 1.0 / (light.constant + light.linear * distance + light.quadratic * (distance * distance));
+ // spotlight intensity
+ float theta = dot(lightDir, normalize(-light.direction));
+ float epsilon = light.cutOff - light.outerCutOff;
+ float intensity = clamp((theta - light.outerCutOff) / epsilon, 0.0, 1.0);
+ // combine results
+ vec3 ambient = light.ambient * vec3(texture(material.texture_diffuse1, TexCoords));
+ vec3 diffuse = light.diffuse * diff * vec3(texture(material.texture_diffuse1, TexCoords));
+ vec3 specular = light.specular * spec * vec3(texture(material.texture_specular1, TexCoords));
+ ambient *= attenuation * intensity;
+ diffuse *= attenuation * intensity;
+ specular *= attenuation * intensity;
+ return (ambient + diffuse + specular);
}
\ No newline at end of file
diff --git a/FinalProject/illuminant.fs b/FinalProject/illuminant.fs
new file mode 100644
index 0000000..e69de29
diff --git a/FinalProject/illuminant.h b/FinalProject/illuminant.h
new file mode 100644
index 0000000..0eda181
--- /dev/null
+++ b/FinalProject/illuminant.h
@@ -0,0 +1,24 @@
+#pragma once
+
+#include
+#include
+#include
+
+#include "shader.h"
+#include "logger.h"
+
+class Illuminant {
+
+};
+
+class DirLight : public Illuminant {
+
+};
+
+class SpotLight : public Illuminant {
+
+};
+
+class PointLight : public Illuminant {
+
+};
\ No newline at end of file
diff --git a/FinalProject/illuminant.vs b/FinalProject/illuminant.vs
new file mode 100644
index 0000000..c875a90
--- /dev/null
+++ b/FinalProject/illuminant.vs
@@ -0,0 +1,11 @@
+#version 430 core
+layout (location = 0) in vec3 aPos;
+
+uniform mat4 model;
+uniform mat4 view;
+uniform mat4 projection;
+
+void main()
+{
+ gl_Position = projection * view * model * vec4(aPos, 1.0);
+}
\ No newline at end of file
diff --git a/FinalProject/lightCaster.cpp b/FinalProject/lightCaster.cpp
new file mode 100644
index 0000000..8fddfa1
--- /dev/null
+++ b/FinalProject/lightCaster.cpp
@@ -0,0 +1,232 @@
+#include"lightCaster.h"
+
+ShaderProgram* lastShader = NULL;
+
+queue available = queue();
+
+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)));
+}
\ No newline at end of file
diff --git a/FinalProject/lightCaster.h b/FinalProject/lightCaster.h
new file mode 100644
index 0000000..5a53e4a
--- /dev/null
+++ b/FinalProject/lightCaster.h
@@ -0,0 +1,86 @@
+#pragma once
+#include"shader.h"
+#include
+#include
+#include"logger.h"
+#include
+
+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();
\ No newline at end of file
diff --git a/FinalProject/mesh.cpp b/FinalProject/mesh.cpp
index 0f70513..bcd149e 100644
--- a/FinalProject/mesh.cpp
+++ b/FinalProject/mesh.cpp
@@ -22,11 +22,14 @@ Mesh::Mesh(const std::vector& vertices, const std::vector& text
void Mesh::render(const ShaderProgram& shader) const {
unsigned int diffuseNr = 1;
unsigned int specularNr = 1;
+ shader.setUniform("material.shininess",_shininess);
for (int i = 0; i < _textures.size(); i++) {
OPENGL_EXTRA_FUNCTIONS->glActiveTexture(GL_TEXTURE0 + i); // activate proper texture unit before binding
// retrieve texture number (the N in diffuse_textureN)
std::string number;
std::string name = _textures[i].type() == TextureType::DIFFUSE ? "texture_diffuse" : "texture_specular";
+ name = "material." + name;
+
if (_textures[i].type() == TextureType::DIFFUSE)
number = std::to_string(diffuseNr++);
else if (_textures[i].type() == TextureType::SPECULAR)
diff --git a/FinalProject/mesh.h b/FinalProject/mesh.h
index 56e07c5..86390ce 100644
--- a/FinalProject/mesh.h
+++ b/FinalProject/mesh.h
@@ -13,6 +13,9 @@ private:
std::vector _indices;
std::vector _textures;
+ // we can control shininess in mesh
+ float _shininess = 32.0f;
+
VertexArrayObject _vao = VertexArrayObject::empty();
public:
@@ -23,6 +26,9 @@ public:
inline std::vector vertices() const { return _vertices; }
inline std::vector indices() const { return _indices; }
inline std::vector textures() const { return _textures; }
+
+ inline float shininess() const { return _shininess; }
+ inline void setShininess(float shininess) { _shininess = shininess; }
inline VertexArrayObject vao() const { return _vao; }
@@ -31,4 +37,4 @@ public:
private:
void setupMesh();
-};
\ No newline at end of file
+};
diff --git a/FinalProject/renderable.cpp b/FinalProject/renderable.cpp
index e6fedfd..289a8c5 100644
--- a/FinalProject/renderable.cpp
+++ b/FinalProject/renderable.cpp
@@ -42,6 +42,7 @@ void Renderable::render(ShaderProgram shader) {
}
// Set model matrix
shader.setUniform("model", modelMatrix());
+
// Render
_model->render(shader);
}
diff --git a/FinalProject/sceneviewer.cpp b/FinalProject/sceneviewer.cpp
index ede88ab..8f39eab 100644
--- a/FinalProject/sceneviewer.cpp
+++ b/FinalProject/sceneviewer.cpp
@@ -1,18 +1,13 @@
#include "sceneviewer.h"
-#include
#include
#include
#include
#include
+#include
-#include "vbo.h"
-#include "vao.h"
-#include "shader.h"
-#include "logger.h"
-#include "model.h"
+#include "lightCaster.h"
-using std::vector;
SceneViewer::SceneViewer(QWidget* parent)
: QOpenGLWidget(parent)
@@ -22,38 +17,50 @@ SceneViewer::SceneViewer(QWidget* parent)
format.setProfile(QSurfaceFormat::CoreProfile);
format.setVersion(4, 3);
setFormat(format);
-
- // Create a folder
- QDir dir("./temp/shaders");
- if (!dir.exists()) {
- dir.mkpath(".");
+
+ // Create temp folder
+ QDir dir;
+ if (!dir.exists("./temp"))
+ {
+ dir.mkdir("./temp");
+ }
+ if (!dir.exists("./temp/shaders"))
+ {
+ dir.mkdir("./temp/shaders");
}
- // Copy the shaders to the folder
- if (QFile::exists("./temp/shaders/vertexshader.vs")) {
- QFile::remove("./temp/shaders/vertexshader.vs");
- }
- QFile::copy(":/shaders/vertexshader.vs", "./temp/shaders/vertexshader.vs");
- QFile::setPermissions("./temp/shaders/vertexshader.vs", QFileDevice::ReadOwner | QFileDevice::WriteOwner);
- if (QFile::exists("./temp/shaders/fragmentshader.fs")) {
- QFile::remove("./temp/shaders/fragmentshader.fs");
- }
- QFile::copy(":/shaders/fragmentshader.fs", "./temp/shaders/fragmentshader.fs");
- QFile::setPermissions("./temp/shaders/fragmentshader.fs", QFile::ReadOwner | QFile::WriteOwner);
+ // Copy the shaders to the temp folder
+ extractShaderResorce("vertexshader.vs");
+ extractShaderResorce("fragmentshader.fs");
+ extractShaderResorce("illuminant.vs");
+ extractShaderResorce("illuminant.fs");
}
SceneViewer::~SceneViewer() {
+
+}
+void SceneViewer::extractShaderResorce(const QString& shaderName) {
+ QString shaderResourcePath = ":/shaders/" + shaderName;
+ QString shaderTempPath = "./temp/shaders/" + shaderName;
+
+ if (QFile::exists(shaderTempPath))
+ {
+ QFile::remove(shaderTempPath);
+ }
+ QFile::copy(shaderResourcePath, shaderTempPath);
+ QFile::setPermissions(shaderTempPath, QFile::ReadOwner | QFile::WriteOwner);
}
void SceneViewer::initializeGL() {
initializeOpenGLFunctions();
-
+
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnable(GL_DEPTH_TEST);
-
+ glEnable(GL_FRAMEBUFFER_SRGB);
+
Logger::info("Currently running on OpenGL version: " + std::string((const char*)glGetString(GL_VERSION)));
_shaderProgram.ensureInitialized();
@@ -65,8 +72,16 @@ void SceneViewer::initializeGL() {
_shaderProgram.attachShader(fragmentShader);
vertexShader.dispose();
fragmentShader.dispose();
+
+ setAllLigntUniform(_shaderProgram);
+ init_queue();
+
+ addDirLight(glm::vec3(0.3, 0.5, -1), glm::vec3(0.2, 0.1, 0.2));
+ addSpotLight(glm::vec3(0.3, 0.5, -1), glm::vec3(-0.3, -0.5, 3), glm::vec3(0.2, 1, 0.1));
+ addPointLight(glm::vec3(0.5, 0.9, 0.4), glm::vec3(1, 0.2, 0.4));
+ addPointLight(glm::vec3(-0.3, -0.9, 0.4), glm::vec3(0, 0.2, 0.9));
- _camera.setPosition(glm::vec3(0.0f, 0.0f, 10.0f));
+ _camera.setPosition(glm::vec3(0.0f, 0.0f, 5.0f));
}
void SceneViewer::resizeGL(int w, int h) {
@@ -85,6 +100,8 @@ void SceneViewer::paintGL() {
glm::mat4 projection = glm::perspective(glm::radians(_camera.zoomVal()), (float)width() / (float)height(), 0.1f, 100.0f);
_shaderProgram.setUniform("view", view);
_shaderProgram.setUniform("projection", projection);
+
+ update_light();
for (auto object : _objects) {
object.render(_shaderProgram);
@@ -193,3 +210,24 @@ void SceneViewer::resizeEvent(QResizeEvent* event) {
//mask.addRoundedRect(rect(), _cornerRadius, _cornerRadius);
//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);
+}
\ No newline at end of file
diff --git a/FinalProject/sceneviewer.h b/FinalProject/sceneviewer.h
index 5d2460e..c97a399 100644
--- a/FinalProject/sceneviewer.h
+++ b/FinalProject/sceneviewer.h
@@ -4,7 +4,6 @@
#include
#include
#include
-
#include
#include "camera.h"
@@ -12,6 +11,11 @@
#include "renderable.h"
#include "vao.h"
#include "utils.h"
+#include "lightCaster.h"
+#include "vbo.h"
+#include "logger.h"
+#include "model.h"
+
class SceneViewer : public QOpenGLWidget, protected QOpenGLFunctions
{
@@ -21,6 +25,8 @@ private:
// OpenGL section-------------------------------------
// List of objects currently in the scene
std::vector _objects;
+ // List of light casters in the scene
+ std::vector _illuminants;
// Shader program for objects
ShaderProgram _shaderProgram = ShaderProgram::empty();
// Main camera
@@ -42,6 +48,14 @@ private:
public:
SceneViewer(QWidget* parent = 0);
~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:
+ void extractShaderResorce(const QString& shaderName);
protected:
// OpenGL functions
diff --git a/FinalProject/vertexshader.vs b/FinalProject/vertexshader.vs
index 73091f6..056e569 100644
--- a/FinalProject/vertexshader.vs
+++ b/FinalProject/vertexshader.vs
@@ -3,6 +3,8 @@ layout (location = 0) in vec3 aPos;
layout (location = 1) in vec3 aNormal;
layout (location = 2) in vec2 aTexCoords;
+out vec3 FragPos;
+out vec3 Normal;
out vec2 TexCoords;
uniform mat4 model;
@@ -11,6 +13,9 @@ uniform mat4 projection;
void main()
{
- TexCoords = aTexCoords;
- gl_Position = projection * view * model * vec4(aPos, 1.0);
+ FragPos = vec3(model * vec4(aPos, 1.0));
+ Normal = mat3(transpose(inverse(model))) * aNormal;
+ TexCoords = aTexCoords;
+
+ gl_Position = projection * view * vec4(FragPos, 1.0);
}
\ No newline at end of file