mirror of
https://github.com/Linloir/SceneEditor.git
synced 2025-12-17 07:28:12 +08:00
Merge lighting
This commit is contained in:
commit
cc9ae662a8
@ -108,6 +108,7 @@
|
|||||||
<ClCompile Include="ebo.cpp" />
|
<ClCompile Include="ebo.cpp" />
|
||||||
<ClCompile Include="editorpage.cpp" />
|
<ClCompile Include="editorpage.cpp" />
|
||||||
<ClCompile Include="framelesswindow.cpp" />
|
<ClCompile Include="framelesswindow.cpp" />
|
||||||
|
<ClCompile Include="lightCaster.cpp" />
|
||||||
<ClCompile Include="lineeditwidget.cpp" />
|
<ClCompile Include="lineeditwidget.cpp" />
|
||||||
<ClCompile Include="logger.cpp" />
|
<ClCompile Include="logger.cpp" />
|
||||||
<ClCompile Include="mesh.cpp" />
|
<ClCompile Include="mesh.cpp" />
|
||||||
@ -142,6 +143,8 @@
|
|||||||
<QtMoc Include="editorpage.h" />
|
<QtMoc Include="editorpage.h" />
|
||||||
<QtMoc Include="framelesswindow.h" />
|
<QtMoc Include="framelesswindow.h" />
|
||||||
<QtMoc Include="lineeditwidget.h" />
|
<QtMoc Include="lineeditwidget.h" />
|
||||||
|
<ClInclude Include="illuminant.h" />
|
||||||
|
<ClInclude Include="lightCaster.h" />
|
||||||
<ClInclude Include="logger.h" />
|
<ClInclude Include="logger.h" />
|
||||||
<ClInclude Include="mesh.h" />
|
<ClInclude Include="mesh.h" />
|
||||||
<ClInclude Include="model.h" />
|
<ClInclude Include="model.h" />
|
||||||
|
|||||||
@ -165,6 +165,9 @@
|
|||||||
<ClCompile Include="modelthumbnailwidget.cpp">
|
<ClCompile Include="modelthumbnailwidget.cpp">
|
||||||
<Filter>Source Files\Qt Widgets\Pages\Scene Editor\Object Selector</Filter>
|
<Filter>Source Files\Qt Widgets\Pages\Scene Editor\Object Selector</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="lightCaster.cpp">
|
||||||
|
<Filter>Source Files\OpenGL Abstractions</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="camera.h">
|
<ClInclude Include="camera.h">
|
||||||
@ -206,6 +209,12 @@
|
|||||||
<ClInclude Include="modelsetter.h">
|
<ClInclude Include="modelsetter.h">
|
||||||
<Filter>Header Files\Qt Widgets\Pages\Scene Editor\Object Setter</Filter>
|
<Filter>Header Files\Qt Widgets\Pages\Scene Editor\Object Setter</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="lightCaster.h">
|
||||||
|
<Filter>Header Files\OpenGL Abstractions</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="illuminant.h">
|
||||||
|
<Filter>Header Files\OpenGL Abstractions</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<QtMoc Include="mainwindow.h">
|
<QtMoc Include="mainwindow.h">
|
||||||
|
|||||||
@ -1,13 +1,148 @@
|
|||||||
#version 430 core
|
#version 430 core
|
||||||
out vec4 FragColor;
|
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;
|
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()
|
void main()
|
||||||
{
|
{
|
||||||
FragColor = texture(texture_specular1, TexCoords);
|
// properties
|
||||||
FragColor = texture(texture_diffuse1, TexCoords);
|
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);
|
||||||
}
|
}
|
||||||
0
FinalProject/illuminant.fs
Normal file
0
FinalProject/illuminant.fs
Normal file
24
FinalProject/illuminant.h
Normal file
24
FinalProject/illuminant.h
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <GLM/glm.hpp>
|
||||||
|
#include <string>
|
||||||
|
#include <queue>
|
||||||
|
|
||||||
|
#include "shader.h"
|
||||||
|
#include "logger.h"
|
||||||
|
|
||||||
|
class Illuminant {
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
class DirLight : public Illuminant {
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
class SpotLight : public Illuminant {
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
class PointLight : public Illuminant {
|
||||||
|
|
||||||
|
};
|
||||||
11
FinalProject/illuminant.vs
Normal file
11
FinalProject/illuminant.vs
Normal file
@ -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);
|
||||||
|
}
|
||||||
232
FinalProject/lightCaster.cpp
Normal file
232
FinalProject/lightCaster.cpp
Normal file
@ -0,0 +1,232 @@
|
|||||||
|
#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)));
|
||||||
|
}
|
||||||
86
FinalProject/lightCaster.h
Normal file
86
FinalProject/lightCaster.h
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
#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();
|
||||||
@ -22,11 +22,14 @@ Mesh::Mesh(const std::vector<Vertex>& vertices, const std::vector<Texture>& text
|
|||||||
void Mesh::render(const ShaderProgram& shader) const {
|
void Mesh::render(const ShaderProgram& shader) const {
|
||||||
unsigned int diffuseNr = 1;
|
unsigned int diffuseNr = 1;
|
||||||
unsigned int specularNr = 1;
|
unsigned int specularNr = 1;
|
||||||
|
shader.setUniform("material.shininess",_shininess);
|
||||||
for (int i = 0; i < _textures.size(); i++) {
|
for (int i = 0; i < _textures.size(); i++) {
|
||||||
OPENGL_EXTRA_FUNCTIONS->glActiveTexture(GL_TEXTURE0 + i); // activate proper texture unit before binding
|
OPENGL_EXTRA_FUNCTIONS->glActiveTexture(GL_TEXTURE0 + i); // activate proper texture unit before binding
|
||||||
// retrieve texture number (the N in diffuse_textureN)
|
// retrieve texture number (the N in diffuse_textureN)
|
||||||
std::string number;
|
std::string number;
|
||||||
std::string name = _textures[i].type() == TextureType::DIFFUSE ? "texture_diffuse" : "texture_specular";
|
std::string name = _textures[i].type() == TextureType::DIFFUSE ? "texture_diffuse" : "texture_specular";
|
||||||
|
name = "material." + name;
|
||||||
|
|
||||||
if (_textures[i].type() == TextureType::DIFFUSE)
|
if (_textures[i].type() == TextureType::DIFFUSE)
|
||||||
number = std::to_string(diffuseNr++);
|
number = std::to_string(diffuseNr++);
|
||||||
else if (_textures[i].type() == TextureType::SPECULAR)
|
else if (_textures[i].type() == TextureType::SPECULAR)
|
||||||
|
|||||||
@ -13,6 +13,9 @@ private:
|
|||||||
std::vector<unsigned int> _indices;
|
std::vector<unsigned int> _indices;
|
||||||
std::vector<Texture> _textures;
|
std::vector<Texture> _textures;
|
||||||
|
|
||||||
|
// we can control shininess in mesh
|
||||||
|
float _shininess = 32.0f;
|
||||||
|
|
||||||
VertexArrayObject _vao = VertexArrayObject::empty();
|
VertexArrayObject _vao = VertexArrayObject::empty();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@ -23,6 +26,9 @@ public:
|
|||||||
inline std::vector<Vertex> vertices() const { return _vertices; }
|
inline std::vector<Vertex> vertices() const { return _vertices; }
|
||||||
inline std::vector<unsigned int> indices() const { return _indices; }
|
inline std::vector<unsigned int> indices() const { return _indices; }
|
||||||
inline std::vector<Texture> textures() const { return _textures; }
|
inline std::vector<Texture> textures() const { return _textures; }
|
||||||
|
|
||||||
|
inline float shininess() const { return _shininess; }
|
||||||
|
inline void setShininess(float shininess) { _shininess = shininess; }
|
||||||
|
|
||||||
inline VertexArrayObject vao() const { return _vao; }
|
inline VertexArrayObject vao() const { return _vao; }
|
||||||
|
|
||||||
@ -31,4 +37,4 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
void setupMesh();
|
void setupMesh();
|
||||||
};
|
};
|
||||||
|
|||||||
@ -42,6 +42,7 @@ void Renderable::render(ShaderProgram shader) {
|
|||||||
}
|
}
|
||||||
// Set model matrix
|
// Set model matrix
|
||||||
shader.setUniform("model", modelMatrix());
|
shader.setUniform("model", modelMatrix());
|
||||||
|
|
||||||
// Render
|
// Render
|
||||||
_model->render(shader);
|
_model->render(shader);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,18 +1,13 @@
|
|||||||
#include "sceneviewer.h"
|
#include "sceneviewer.h"
|
||||||
|
|
||||||
#include <vector>
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <qresource.h>
|
#include <qresource.h>
|
||||||
#include <qurl.h>
|
#include <qurl.h>
|
||||||
#include <qdir.h>
|
#include <qdir.h>
|
||||||
|
#include<time.h>
|
||||||
|
|
||||||
#include "vbo.h"
|
#include "lightCaster.h"
|
||||||
#include "vao.h"
|
|
||||||
#include "shader.h"
|
|
||||||
#include "logger.h"
|
|
||||||
#include "model.h"
|
|
||||||
|
|
||||||
using std::vector;
|
|
||||||
|
|
||||||
SceneViewer::SceneViewer(QWidget* parent)
|
SceneViewer::SceneViewer(QWidget* parent)
|
||||||
: QOpenGLWidget(parent)
|
: QOpenGLWidget(parent)
|
||||||
@ -22,38 +17,50 @@ SceneViewer::SceneViewer(QWidget* parent)
|
|||||||
format.setProfile(QSurfaceFormat::CoreProfile);
|
format.setProfile(QSurfaceFormat::CoreProfile);
|
||||||
format.setVersion(4, 3);
|
format.setVersion(4, 3);
|
||||||
setFormat(format);
|
setFormat(format);
|
||||||
|
|
||||||
// Create a folder
|
// Create temp folder
|
||||||
QDir dir("./temp/shaders");
|
QDir dir;
|
||||||
if (!dir.exists()) {
|
if (!dir.exists("./temp"))
|
||||||
dir.mkpath(".");
|
{
|
||||||
|
dir.mkdir("./temp");
|
||||||
|
}
|
||||||
|
if (!dir.exists("./temp/shaders"))
|
||||||
|
{
|
||||||
|
dir.mkdir("./temp/shaders");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Copy the shaders to the folder
|
// Copy the shaders to the temp folder
|
||||||
if (QFile::exists("./temp/shaders/vertexshader.vs")) {
|
extractShaderResorce("vertexshader.vs");
|
||||||
QFile::remove("./temp/shaders/vertexshader.vs");
|
extractShaderResorce("fragmentshader.fs");
|
||||||
}
|
extractShaderResorce("illuminant.vs");
|
||||||
QFile::copy(":/shaders/vertexshader.vs", "./temp/shaders/vertexshader.vs");
|
extractShaderResorce("illuminant.fs");
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SceneViewer::~SceneViewer() {
|
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() {
|
void SceneViewer::initializeGL() {
|
||||||
initializeOpenGLFunctions();
|
initializeOpenGLFunctions();
|
||||||
|
|
||||||
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
|
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
|
||||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
|
|
||||||
glEnable(GL_DEPTH_TEST);
|
glEnable(GL_DEPTH_TEST);
|
||||||
|
glEnable(GL_FRAMEBUFFER_SRGB);
|
||||||
|
|
||||||
Logger::info("Currently running on OpenGL version: " + std::string((const char*)glGetString(GL_VERSION)));
|
Logger::info("Currently running on OpenGL version: " + std::string((const char*)glGetString(GL_VERSION)));
|
||||||
|
|
||||||
_shaderProgram.ensureInitialized();
|
_shaderProgram.ensureInitialized();
|
||||||
@ -65,8 +72,16 @@ void SceneViewer::initializeGL() {
|
|||||||
_shaderProgram.attachShader(fragmentShader);
|
_shaderProgram.attachShader(fragmentShader);
|
||||||
vertexShader.dispose();
|
vertexShader.dispose();
|
||||||
fragmentShader.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) {
|
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);
|
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);
|
||||||
|
|
||||||
|
update_light();
|
||||||
|
|
||||||
for (auto object : _objects) {
|
for (auto object : _objects) {
|
||||||
object.render(_shaderProgram);
|
object.render(_shaderProgram);
|
||||||
@ -193,3 +210,24 @@ 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);
|
||||||
|
}
|
||||||
@ -4,7 +4,6 @@
|
|||||||
#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"
|
||||||
@ -12,6 +11,11 @@
|
|||||||
#include "renderable.h"
|
#include "renderable.h"
|
||||||
#include "vao.h"
|
#include "vao.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
#include "lightCaster.h"
|
||||||
|
#include "vbo.h"
|
||||||
|
#include "logger.h"
|
||||||
|
#include "model.h"
|
||||||
|
|
||||||
|
|
||||||
class SceneViewer : public QOpenGLWidget, protected QOpenGLFunctions
|
class SceneViewer : public QOpenGLWidget, protected QOpenGLFunctions
|
||||||
{
|
{
|
||||||
@ -21,6 +25,8 @@ 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
|
||||||
|
std::vector<Illuminant> _illuminants;
|
||||||
// Shader program for objects
|
// Shader program for objects
|
||||||
ShaderProgram _shaderProgram = ShaderProgram::empty();
|
ShaderProgram _shaderProgram = ShaderProgram::empty();
|
||||||
// Main camera
|
// Main camera
|
||||||
@ -42,6 +48,14 @@ 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:
|
||||||
|
void extractShaderResorce(const QString& shaderName);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// OpenGL functions
|
// OpenGL functions
|
||||||
|
|||||||
@ -3,6 +3,8 @@ layout (location = 0) in vec3 aPos;
|
|||||||
layout (location = 1) in vec3 aNormal;
|
layout (location = 1) in vec3 aNormal;
|
||||||
layout (location = 2) in vec2 aTexCoords;
|
layout (location = 2) in vec2 aTexCoords;
|
||||||
|
|
||||||
|
out vec3 FragPos;
|
||||||
|
out vec3 Normal;
|
||||||
out vec2 TexCoords;
|
out vec2 TexCoords;
|
||||||
|
|
||||||
uniform mat4 model;
|
uniform mat4 model;
|
||||||
@ -11,6 +13,9 @@ uniform mat4 projection;
|
|||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
TexCoords = aTexCoords;
|
FragPos = vec3(model * vec4(aPos, 1.0));
|
||||||
gl_Position = projection * view * model * vec4(aPos, 1.0);
|
Normal = mat3(transpose(inverse(model))) * aNormal;
|
||||||
|
TexCoords = aTexCoords;
|
||||||
|
|
||||||
|
gl_Position = projection * view * vec4(FragPos, 1.0);
|
||||||
}
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user