diff --git a/BaseGLProject/BaseGLProject.vcxproj b/BaseGLProject/BaseGLProject.vcxproj
index 97f3ed1..83c9bcd 100644
--- a/BaseGLProject/BaseGLProject.vcxproj
+++ b/BaseGLProject/BaseGLProject.vcxproj
@@ -186,6 +186,8 @@
+
+
Geometry
@@ -198,10 +200,11 @@
4.0
Document
-
+
+
diff --git a/BaseGLProject/BaseGLProject.vcxproj.filters b/BaseGLProject/BaseGLProject.vcxproj.filters
index 422e905..bc636a1 100644
--- a/BaseGLProject/BaseGLProject.vcxproj.filters
+++ b/BaseGLProject/BaseGLProject.vcxproj.filters
@@ -130,9 +130,6 @@
Shaders
-
- Shaders
-
Shaders
@@ -160,6 +157,18 @@
Shaders
+
+ Shaders
+
+
+ Shaders
+
+
+ Shaders
+
+
+ Shaders
+
diff --git a/BaseGLProject/Light.cpp b/BaseGLProject/Light.cpp
index ed2a510..36fa349 100644
--- a/BaseGLProject/Light.cpp
+++ b/BaseGLProject/Light.cpp
@@ -2,6 +2,15 @@
Light::Light(glm::vec3 intensity_, glm::vec4 location_) : location(location_), intensity(intensity_)
{
+ type = BASE;
+}
+
+Light::Light(glm::vec3 intensity_, glm::vec4 location_, float spot_cutoff_, float spot_inner_cutoff_, float spot_exponent_, glm::vec3 direction_):
+ location(location_), intensity(intensity_), spot_cutoff(spot_cutoff_), spot_inner_cutoff(spot_inner_cutoff_)
+ ,spot_exponent(spot_exponent_), direction(direction_)
+
+{
+ type = SPOT;
}
diff --git a/BaseGLProject/Light.h b/BaseGLProject/Light.h
index a201ac7..c0dbdd8 100644
--- a/BaseGLProject/Light.h
+++ b/BaseGLProject/Light.h
@@ -6,11 +6,23 @@
class Light
{
public:
+ enum LightType
+ {
+ BASE,
+ SPOT
+ };
+
Light(glm::vec3 intensity, glm::vec4 location);
+ Light(glm::vec3 intensity, glm::vec4 location, float spot_cutoff, float spot_inner_cutoff, float spot_exponent, glm::vec3 direction);
~Light();
bool activated = true;
+ LightType type;
glm::vec3 intensity;
glm::vec4 location;
+ float spot_cutoff;
+ float spot_inner_cutoff;
+ float spot_exponent;
+ glm::vec3 direction;
};
diff --git a/BaseGLProject/MyGLWindow.cpp b/BaseGLProject/MyGLWindow.cpp
index f12578c..46b89f1 100644
--- a/BaseGLProject/MyGLWindow.cpp
+++ b/BaseGLProject/MyGLWindow.cpp
@@ -88,6 +88,12 @@ void MyGlWindow::shaderSetup()
shaders["TexBaseLight"] = new Shader("tex_base_light.vert", "tex_base_light.frag");
shaders["TexBaseLight"]->addUniform("tex1", 0);
+ shaders["SpotLight"] = new Shader("spotlight.vert", "spotlight.frag");
+ shaders["SpotLight"]->light_type = Light::LightType::SPOT;
+ shaders["TexSpotLight"] = new Shader("tex_spotlight.vert", "tex_spotlight.frag");
+ shaders["TexSpotLight"]->light_type = Light::LightType::SPOT;
+
+
shaders["Silhouette"] = new Shader("silhouette.vert", "silhouette.frag");
shaders["Silhouette"]->uniformFlags = ShaderFlags::MVP_FLAG;
shaders["Silhouette"]->addUniform("fColor", glm::vec3(237 / 255, 229 / 255, 194 / 255));
diff --git a/BaseGLProject/Shader.cpp b/BaseGLProject/Shader.cpp
index 2c1e688..6f933a9 100644
--- a/BaseGLProject/Shader.cpp
+++ b/BaseGLProject/Shader.cpp
@@ -48,13 +48,19 @@ void Shader::setLights(SceneContext ctx)
return;
for (auto light: ctx.lights)
{
- if (light.second.activated)
+ if (light.second.activated && light.second.type == light_type)
{
std::string lightname = "Light[" + std::to_string(i) + "].";
- _program.addUniform(lightname + "Position");
- glUniform4fv(_program.uniform(lightname + "Position"), 1, glm::value_ptr(ctx.viewMatrix * light.second.location));
- _program.addUniform(lightname + "Intensity");
- glUniform3fv(_program.uniform(lightname + "Intensity"), 1, glm::value_ptr(light.second.intensity));
+
+ glUniform4fv(_program.addUniform(lightname + "Position"), 1, glm::value_ptr(ctx.viewMatrix * light.second.location));
+ glUniform3fv(_program.addUniform(lightname + "Intensity"), 1, glm::value_ptr(light.second.intensity));
+ if (light.second.type == Light::LightType::SPOT)
+ {
+ glUniform1f(_program.addUniform(lightname + "SpotCutoff"), light.second.spot_cutoff);
+ glUniform1f(_program.addUniform(lightname + "SpotInnerCutoff"), light.second.spot_inner_cutoff);
+ glUniform1f(_program.addUniform(lightname + "SpotExponent"), light.second.spot_exponent);
+ glUniform3fv(_program.addUniform(lightname + "SpotDirection"), 1, glm::value_ptr(light.second.direction));
+ }
i++;
}
}
diff --git a/BaseGLProject/Shader.h b/BaseGLProject/Shader.h
index ca072d7..c24791b 100644
--- a/BaseGLProject/Shader.h
+++ b/BaseGLProject/Shader.h
@@ -33,6 +33,7 @@ public:
int uniformFlags = KD_FLAG | KA_FLAG | KS_FLAG | SHINE_FLAG | MVP_FLAG | NORMAL_MAT_FLAG | MODELVIEW_FLAG | LIGHTS_FLAG;
Material mat;
+ Light::LightType light_type = Light::LightType::BASE;
void enable();
void disable();
diff --git a/BaseGLProject/onelight.frag b/BaseGLProject/onelight.frag
deleted file mode 100644
index ba803a6..0000000
--- a/BaseGLProject/onelight.frag
+++ /dev/null
@@ -1,62 +0,0 @@
-#version 440
-
-in vec3 f_color;
-out vec4 FragColors;
-
-uniform vec3 Kd;
-uniform vec3 Ka;
-uniform vec3 Ks;
-uniform float Shininess;
-
-uniform vec4 LightLocation;
-uniform vec3 LightIntensity;
-
-uniform vec4 LightDirection;
-uniform float Exponent;
-uniform float Cutoff;
-uniform float InnerCutoff;
-
-in vec3 fNormal;
-in vec3 pos;
-
-const float a = 1.0f;
-const float b = 0.01f;
-const float c = 0.001f;
-
-void main()
-{
-
- vec3 LightDir = LightDirection.xyz - LightLocation.xyz;
-
- vec3 L = LightLocation.xyz - pos;
- float d = length(L);
- L = normalize(L);
-
- float attenuation = 1.0f / (a + b * d + c * pow(d, 2));
- float angle = acos(dot(-L, normalize(LightDir))); // radian
- float spotAttenuation = 1.0f;
- if (angle < radians(InnerCutoff))
- spotAttenuation = 1.0f;
- else
- {
- // pos is outside the spot's inner cutoff
- float SpotDot = dot(-L, normalize(LightDir));
- float spotValue = smoothstep(cos(radians(Cutoff)), cos(radians(InnerCutoff)), SpotDot);
- spotAttenuation = pow(spotValue, Exponent);
- }
- attenuation *= spotAttenuation;
-
- vec3 N = normalize(fNormal);
- vec3 V = normalize(-pos);
- vec3 H = normalize(V + L);
-
- float dotNL = max(dot(L, N), 0.0); // for diffuse
- float dotHN = max(dot(H, N), 0.0); // for spec
- float pf = pow(dotHN, Shininess); // for spec
-
- vec3 ambient = Ka * LightIntensity * attenuation;
- vec3 diffuse = Kd * LightIntensity * dotNL * attenuation;
- vec3 specular = Ks * LightIntensity * pf * attenuation;
-
- FragColors = vec4(diffuse + specular + ambient, 1);
-}
diff --git a/BaseGLProject/spotlight.frag b/BaseGLProject/spotlight.frag
new file mode 100644
index 0000000..c12e2a5
--- /dev/null
+++ b/BaseGLProject/spotlight.frag
@@ -0,0 +1,76 @@
+#version 440
+
+in vec3 f_color;
+out vec4 FragColors;
+
+uniform vec3 Kd;
+uniform vec3 Ka;
+uniform vec3 Ks;
+uniform float Shininess;
+
+struct LightInfo {
+ vec4 Position;
+ vec3 Intensity;
+ float SpotCutoff;
+ float SpotInnerCutoff;
+ float SpotExponent;
+ vec3 SpotDirection;
+};
+
+uniform LightInfo Light[64];
+uniform int LightCount;
+
+in vec3 fNormal;
+in vec3 pos;
+
+void main()
+{
+
+ vec3 ambient_sum;
+ vec3 diffuse_sum;
+ vec3 specular_sum;
+ vec3 ambient;
+ float D;
+ float attenuation;
+
+
+ for (int i=0; i