From 6d21cde397ff246c053274c47fd33f3b84f68c6e Mon Sep 17 00:00:00 2001
From: talha <talha@talhaamir.xyz>
Date: Wed, 27 Mar 2024 04:19:47 +0500
Subject: Added directional lighting, point lights

---
 source/main.cpp                      | 228 ++++++++++++++++-------------------
 source/shaders/light_subject.fs.glsl |  58 +++++++--
 source/shaders/light_subject.vs.glsl |   3 +
 3 files changed, 157 insertions(+), 132 deletions(-)

(limited to 'source')

diff --git a/source/main.cpp b/source/main.cpp
index b7597fe..94974e5 100644
--- a/source/main.cpp
+++ b/source/main.cpp
@@ -468,9 +468,9 @@ Mat4 perspective4m(r32 fov, r32 aspect_ratio, r32 near, r32 far)
 	res.data[1][1] = cotangent;
 
 	res.data[2][2] = -(far + near) / (far - near);
-	res.data[2][3] = -2.0 * far * near / (far - near);
+	res.data[2][3] = -2.0f * far * near / (far - near);
 
-	res.data[3][2] = -1.0;
+	res.data[3][2] = -1.0f;
 
 	return res;
 }
@@ -576,62 +576,50 @@ int main(int argc, char* argv[])
 	GLuint light_sp = gl_create_shader_program(light_vs, light_fs);
 	printf("Successfully compiled shaders.\n");
 
-	GLfloat rect_vertices[] = {
-		// Position						// Color						// Texture
-		-0.5f, -0.5f, 0.0f,		0.6f, 0.3f, 0.3f,		0.0f, 0.0f,		// bottom left
-		 0.5f, -0.5f, 0.0f,		0.6f, 0.5f, 0.5f,		1.0f, 0.0f,		// bottom right
-		-0.5f,  0.5f, 0.0f,   0.4f, 0.3f, 0.2f,		0.0f, 1.0f,		// top left
-		 0.5f,  0.5f, 0.0f,		0.4f, 0.5f, 0.6f,		1.0f, 1.0f		// top right
-	};
-
-	unsigned int rect_indices[] = {
-		0, 1, 2,
-		2, 1, 3
-	};
-
 	r32 cube_normal_vertices[] = {
-		-0.5f, -0.5f, -0.5f,  0.0f,  0.0f, -1.0f,
-		 0.5f, -0.5f, -0.5f,  0.0f,  0.0f, -1.0f,
-		 0.5f,  0.5f, -0.5f,  0.0f,  0.0f, -1.0f,
-		 0.5f,  0.5f, -0.5f,  0.0f,  0.0f, -1.0f,
-		-0.5f,  0.5f, -0.5f,  0.0f,  0.0f, -1.0f,
-		-0.5f, -0.5f, -0.5f,  0.0f,  0.0f, -1.0f,
-
-		-0.5f, -0.5f,  0.5f,  0.0f,  0.0f,  1.0f,           // this is the front side as seen from the camera starting at > 0.0f
-		 0.5f, -0.5f,  0.5f,  0.0f,  0.0f,  1.0f,
-		 0.5f,  0.5f,  0.5f,  0.0f,  0.0f,  1.0f,
-		 0.5f,  0.5f,  0.5f,  0.0f,  0.0f,  1.0f,
-		-0.5f,  0.5f,  0.5f,  0.0f,  0.0f,  1.0f,
-		-0.5f, -0.5f,  0.5f,  0.0f,  0.0f,  1.0f,
-
-		-0.5f,  0.5f,  0.5f, -1.0f,  0.0f,  0.0f,
-		-0.5f,  0.5f, -0.5f, -1.0f,  0.0f,  0.0f,
-		-0.5f, -0.5f, -0.5f, -1.0f,  0.0f,  0.0f,
-		-0.5f, -0.5f, -0.5f, -1.0f,  0.0f,  0.0f,
-		-0.5f, -0.5f,  0.5f, -1.0f,  0.0f,  0.0f,
-		-0.5f,  0.5f,  0.5f, -1.0f,  0.0f,  0.0f,
-
-		 0.5f,  0.5f,  0.5f,  1.0f,  0.0f,  0.0f,
-		 0.5f,  0.5f, -0.5f,  1.0f,  0.0f,  0.0f,
-		 0.5f, -0.5f, -0.5f,  1.0f,  0.0f,  0.0f,
-		 0.5f, -0.5f, -0.5f,  1.0f,  0.0f,  0.0f,
-		 0.5f, -0.5f,  0.5f,  1.0f,  0.0f,  0.0f,
-		 0.5f,  0.5f,  0.5f,  1.0f,  0.0f,  0.0f,
-
-		-0.5f, -0.5f, -0.5f,  0.0f, -1.0f,  0.0f,
-		 0.5f, -0.5f, -0.5f,  0.0f, -1.0f,  0.0f,
-		 0.5f, -0.5f,  0.5f,  0.0f, -1.0f,  0.0f,
-		 0.5f, -0.5f,  0.5f,  0.0f, -1.0f,  0.0f,
-		-0.5f, -0.5f,  0.5f,  0.0f, -1.0f,  0.0f,
-		-0.5f, -0.5f, -0.5f,  0.0f, -1.0f,  0.0f,
-
-		-0.5f,  0.5f, -0.5f,  0.0f,  1.0f,  0.0f,
-		 0.5f,  0.5f, -0.5f,  0.0f,  1.0f,  0.0f,
-		 0.5f,  0.5f,  0.5f,  0.0f,  1.0f,  0.0f,
-		 0.5f,  0.5f,  0.5f,  0.0f,  1.0f,  0.0f,
-		-0.5f,  0.5f,  0.5f,  0.0f,  1.0f,  0.0f,
-		-0.5f,  0.5f, -0.5f,  0.0f,  1.0f,  0.0f
-	};
+    // positions          // normals           // texture coords
+    -0.5f, -0.5f, -0.5f,  0.0f,  0.0f, -1.0f,  0.0f, 0.0f,
+     0.5f, -0.5f, -0.5f,  0.0f,  0.0f, -1.0f,  1.0f, 0.0f,
+     0.5f,  0.5f, -0.5f,  0.0f,  0.0f, -1.0f,  1.0f, 1.0f,
+     0.5f,  0.5f, -0.5f,  0.0f,  0.0f, -1.0f,  1.0f, 1.0f,
+    -0.5f,  0.5f, -0.5f,  0.0f,  0.0f, -1.0f,  0.0f, 1.0f,
+    -0.5f, -0.5f, -0.5f,  0.0f,  0.0f, -1.0f,  0.0f, 0.0f,
+
+    -0.5f, -0.5f,  0.5f,  0.0f,  0.0f, 1.0f,   0.0f, 0.0f,
+     0.5f, -0.5f,  0.5f,  0.0f,  0.0f, 1.0f,   1.0f, 0.0f,
+     0.5f,  0.5f,  0.5f,  0.0f,  0.0f, 1.0f,   1.0f, 1.0f,
+     0.5f,  0.5f,  0.5f,  0.0f,  0.0f, 1.0f,   1.0f, 1.0f,
+    -0.5f,  0.5f,  0.5f,  0.0f,  0.0f, 1.0f,   0.0f, 1.0f,
+    -0.5f, -0.5f,  0.5f,  0.0f,  0.0f, 1.0f,   0.0f, 0.0f,
+
+    -0.5f,  0.5f,  0.5f, -1.0f,  0.0f,  0.0f,  1.0f, 0.0f,
+    -0.5f,  0.5f, -0.5f, -1.0f,  0.0f,  0.0f,  1.0f, 1.0f,
+    -0.5f, -0.5f, -0.5f, -1.0f,  0.0f,  0.0f,  0.0f, 1.0f,
+    -0.5f, -0.5f, -0.5f, -1.0f,  0.0f,  0.0f,  0.0f, 1.0f,
+    -0.5f, -0.5f,  0.5f, -1.0f,  0.0f,  0.0f,  0.0f, 0.0f,
+    -0.5f,  0.5f,  0.5f, -1.0f,  0.0f,  0.0f,  1.0f, 0.0f,
+
+     0.5f,  0.5f,  0.5f,  1.0f,  0.0f,  0.0f,  1.0f, 0.0f,
+     0.5f,  0.5f, -0.5f,  1.0f,  0.0f,  0.0f,  1.0f, 1.0f,
+     0.5f, -0.5f, -0.5f,  1.0f,  0.0f,  0.0f,  0.0f, 1.0f,
+     0.5f, -0.5f, -0.5f,  1.0f,  0.0f,  0.0f,  0.0f, 1.0f,
+     0.5f, -0.5f,  0.5f,  1.0f,  0.0f,  0.0f,  0.0f, 0.0f,
+     0.5f,  0.5f,  0.5f,  1.0f,  0.0f,  0.0f,  1.0f, 0.0f,
+
+    -0.5f, -0.5f, -0.5f,  0.0f, -1.0f,  0.0f,  0.0f, 1.0f,
+     0.5f, -0.5f, -0.5f,  0.0f, -1.0f,  0.0f,  1.0f, 1.0f,
+     0.5f, -0.5f,  0.5f,  0.0f, -1.0f,  0.0f,  1.0f, 0.0f,
+     0.5f, -0.5f,  0.5f,  0.0f, -1.0f,  0.0f,  1.0f, 0.0f,
+    -0.5f, -0.5f,  0.5f,  0.0f, -1.0f,  0.0f,  0.0f, 0.0f,
+    -0.5f, -0.5f, -0.5f,  0.0f, -1.0f,  0.0f,  0.0f, 1.0f,
+
+    -0.5f,  0.5f, -0.5f,  0.0f,  1.0f,  0.0f,  0.0f, 1.0f,
+     0.5f,  0.5f, -0.5f,  0.0f,  1.0f,  0.0f,  1.0f, 1.0f,
+     0.5f,  0.5f,  0.5f,  0.0f,  1.0f,  0.0f,  1.0f, 0.0f,
+     0.5f,  0.5f,  0.5f,  0.0f,  1.0f,  0.0f,  1.0f, 0.0f,
+    -0.5f,  0.5f,  0.5f,  0.0f,  1.0f,  0.0f,  0.0f, 0.0f,
+    -0.5f,  0.5f, -0.5f,  0.0f,  1.0f,  0.0f,  0.0f, 1.0f
+  };
 
 	r32 cube_vertices[] = {
 		-0.5f, -0.5f, -0.5f,  0.0f, 0.0f,
@@ -694,47 +682,38 @@ int main(int argc, char* argv[])
 		glBindBuffer(GL_ARRAY_BUFFER, 0);
 	}
 
-	GLuint VBO, VAO, EBO, container_texture, smiling_texture;
+	GLuint VBO, VAO, EBO, steel_wood_container, steel_wood_specular;
 	{
 		glGenVertexArrays(1, &VAO);
 		glGenBuffers(1, &VBO);
-		//glGenBuffers(1, &EBO);
 
 		glBindVertexArray(VAO);
 
-
 		glBindBuffer(GL_ARRAY_BUFFER, VBO);
 		glBufferData(GL_ARRAY_BUFFER, sizeof(cube_normal_vertices), cube_normal_vertices, GL_STATIC_DRAW);
 
-		//glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
-		//glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(rect_indices), rect_indices, GL_STATIC_DRAW);
-
 		// Position Attribute
-		glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), (GLvoid*)0);
+		glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)0);
 		glEnableVertexAttribArray(0);
 
-		// Color Attribute
-		//glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)(3 * sizeof(GLfloat)));
-		//glEnableVertexAttribArray(1);
-
-		// Texture Attributes
-		//glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (GLvoid*)(3 * sizeof(GLfloat)));
-		//glEnableVertexAttribArray(1);
-
 		// normal attribute
-		glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), (GLvoid*)(3 * sizeof(GLfloat)));
+		glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)(3 * sizeof(GLfloat)));
 		glEnableVertexAttribArray(1);
 
+    // Texture Attributes
+    glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)(6 * sizeof(GLfloat)));
+    glEnableVertexAttribArray(2);
+
 		int img_width, img_height, img_nrChannels;
 
 		// ==== Texture 1 ====
-		glGenTextures(1, &smiling_texture);
+		glGenTextures(1, &steel_wood_container);
 		glActiveTexture(GL_TEXTURE0);
-		glBindTexture(GL_TEXTURE_2D, smiling_texture);
+		glBindTexture(GL_TEXTURE_2D, steel_wood_container);
 
-		const char* smiling_path = "assets/smiling.png";
+		const char* steel_wood_path = "assets/steel_wood_container.png";
 		stbi_set_flip_vertically_on_load(1);
-		unsigned char* smiling_data = stbi_load(smiling_path, &img_width, &img_height, &img_nrChannels, 0);
+		unsigned char* steel_wood_data = stbi_load(steel_wood_path, &img_width, &img_height, &img_nrChannels, 0);
 
 		// Texture Properties
 		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
@@ -743,23 +722,23 @@ int main(int argc, char* argv[])
 		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
 
 		// Texture Data
-		if (smiling_data)
+		if (steel_wood_data)
 		{
-			glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, img_width, img_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, smiling_data);
+			glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, img_width, img_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, steel_wood_data);
 			glGenerateMipmap(GL_TEXTURE_2D);
 		}
 		else
 		{
-			printf("Error! Failed to load image from `%s`\n", smiling_path);
+			printf("Error! Failed to load image from `%s`\n", steel_wood_path);
 		}
-		stbi_image_free(smiling_data);
+		stbi_image_free(steel_wood_data);
 
 		// ==== Texture 2 ====
-		glGenTextures(1, &container_texture);
+		glGenTextures(1, &steel_wood_specular);
 		glActiveTexture(GL_TEXTURE1);
-		glBindTexture(GL_TEXTURE_2D, container_texture);
-		const char* container_path = "assets/container.jpg";
-		unsigned char* container_data = stbi_load(container_path, &img_width, &img_height, &img_nrChannels, 0);
+		glBindTexture(GL_TEXTURE_2D, steel_wood_specular);
+		const char* steel_wood_specular_path = "assets/steel_wood_specular.png";
+		unsigned char* steel_wood_specular_data = stbi_load(steel_wood_specular_path, &img_width, &img_height, &img_nrChannels, 0);
 
 		// Texture Properties
 		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
@@ -768,67 +747,73 @@ int main(int argc, char* argv[])
 		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
 
 		// Texture Data
-		if (container_data)
+		if (steel_wood_specular_data)
 		{
-			glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, img_width, img_height, 0, GL_RGB, GL_UNSIGNED_BYTE, container_data);
+			glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, img_width, img_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, steel_wood_specular_data);
 			glGenerateMipmap(GL_TEXTURE_2D);
 		}
 		else
 		{
-			printf("Error! Failed to load image from `%s`\n", container_path);
+			printf("Error! Failed to load image from `%s`\n", steel_wood_specular_path);
 		}
-		stbi_image_free(container_data);
+		stbi_image_free(steel_wood_specular_data);
 
 		glBindVertexArray(0);
 		glBindBuffer(GL_ARRAY_BUFFER, 0);
-		//glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
-		glBindTexture(GL_TEXTURE_2D, 0);
+		//glBindTexture(GL_TEXTURE_2D, 0);
 	}
 
   glUseProgram(shader_program);
-  Vec3 ambient_color  = Vec3{ 0.0,        0.1,        0.6 };
-  Vec3 diffuse_color  = Vec3{ 0.0, 	      0.50980392, 0.50980392};
-  Vec3 specular_color = Vec3{ 0.50196078, 0.50196078, 0.50196078};
-  Vec3 light_color    = Vec3{ 1.0,        1.0,        1.0};
-  r32 specular_shine_factor = 128.0 * 0.25;
+  Vec3 ambient_color  = Vec3{ 0.0f,        0.1f,        0.6f };
+  Vec3 diffuse_color  = Vec3{ 0.0f, 	      0.50980392f, 0.50980392f};
+  Vec3 specular_color = Vec3{ 0.50196078f, 0.50196078f, 0.50196078f};
+  Vec3 light_color    = Vec3{ 1.0f,        1.0f,        1.0f};
+  r32 specular_shine_factor = 128.0f * 0.25f;
 
   // material uniforms
-  int mat_ambient_loc = glGetUniformLocation(shader_program, "material.ambient");
-  glUniform3fv(mat_ambient_loc, 1, ambient_color.data);
-
   int mat_diffuse_loc = glGetUniformLocation(shader_program, "material.diffuse");
-  glUniform3fv(mat_diffuse_loc, 1, diffuse_color.data);
+  glUniform1i(mat_diffuse_loc, 0);
 
   int mat_specular_loc = glGetUniformLocation(shader_program, "material.specular");
-  glUniform3fv(mat_specular_loc, 1, specular_color.data);
+  glUniform1i(mat_specular_loc, 1);
 
   int shine_factor_loc = glGetUniformLocation(shader_program, "material.shininess");
   glUniform1f(shine_factor_loc, specular_shine_factor);
 
   // light uniforms
-  Vec3 light_location = Vec3{ 0.0, 0.0, 3.0 };
-  Vec3 light_ambient  = Vec3{ 0.2, 0.2, 0.2 };
-  Vec3 light_diffuse  = Vec3{ 0.5, 0.5, 0.5 };
-  Vec3 light_specular = Vec3{ 1.0, 1.0, 1.0};
+  Vec3 light_location =   Vec3{ 0.0f, 0.0f, 3.0f };
+  Vec3 light_direction =  Vec3{ -0.0f, -0.0f, -0.3f };
+  Vec3 light_ambient  =   Vec3{ 0.2f, 0.2f, 0.2f };
+  Vec3 light_diffuse  =   Vec3{ 0.5f, 0.5f, 0.5f };
+  Vec3 light_specular =   Vec3{ 1.0f, 1.0f, 1.0f };
 
-  int light_ambient_loc = glGetUniformLocation(shader_program, "light.ambient");
+  int light_ambient_loc = glGetUniformLocation(shader_program, "pointLight.ambient");
   glUniform3fv(light_ambient_loc, 1, light_ambient.data);
 
-  int light_diffuse_loc = glGetUniformLocation(shader_program, "light.diffuse");
+  int light_diffuse_loc = glGetUniformLocation(shader_program, "pointLight.diffuse");
   glUniform3fv(light_diffuse_loc, 1, light_diffuse.data);
 
-  int light_specular_loc = glGetUniformLocation(shader_program, "light.specular");
+  int light_specular_loc = glGetUniformLocation(shader_program, "pointLight.specular");
   glUniform3fv(light_specular_loc, 1, light_diffuse.data);
 
-  int light_pos_loc = glGetUniformLocation(shader_program, "light.position");
+  int light_pos_loc = glGetUniformLocation(shader_program, "pointLight.position");
   glUniform3fv(light_pos_loc, 1, light_location.data);
 
+  // attenuation factors
+  int kc_loc = glGetUniformLocation(shader_program, "pointLight.kC");
+  glUniform1f(kc_loc, 1.0f);
+
+  int kl_loc = glGetUniformLocation(shader_program, "pointLight.kL");
+  glUniform1f(kl_loc, 0.09f);
+
+  int kq_loc = glGetUniformLocation(shader_program, "pointLight.kQ");
+  glUniform1f(kq_loc, 0.032f);
 	// texture uniforms
-	int smiling_loc = glGetUniformLocation(shader_program, "smilingTexture");
-	glUniform1i(smiling_loc, 0);
+	//int smiling_loc = glGetUniformLocation(shader_program, "smilingTexture");
+	//glUniform1i(smiling_loc, 0);
 
-	int container_loc = glGetUniformLocation(shader_program, "containerTexture");
-	glUniform1i(container_loc, 1);
+	//int container_loc = glGetUniformLocation(shader_program, "containerTexture");
+	//glUniform1i(container_loc, 1);
 
   int light_uniform_loc = glGetUniformLocation(shader_program, "lightColor");
   glUniform3fv(light_uniform_loc, 1, light_color.data);
@@ -839,8 +824,8 @@ int main(int argc, char* argv[])
 	// objects
 	Vec3 model_translations[] = {
 		Vec3{  0.0, 0.0,  0.0},
-		Vec3{ -5.0, -1.0, -4.0},
-		Vec3{  5.0,  2.0, -4.0},
+		Vec3{ -1.0, -1.0, -2.0},
+		Vec3{  2.0,  0.0, -5.0},
 		Vec3{ -3.0,  5.0, -6.0},
 		Vec3{  3.0, -7.0, -6.0},
 	};
@@ -862,7 +847,7 @@ int main(int argc, char* argv[])
   
   // @todo: remove this, I dont like this and think that this is unnecessary
   Vec3 camera_look_increment;
-	r32 camera_speed = 1.0f;
+	r32 camera_speed = 0.5f;
 
 	Mat4 view = camera_create4m(camera_pos, camera_look, preset_up_dir);
 	
@@ -875,8 +860,6 @@ int main(int argc, char* argv[])
 	
 	glUseProgram(light_sp);
 	Mat4 light_model = translation_matrix4m(light_location.x, light_location.y, light_location.z);
-	//Mat4 light_model = init_value4m(1.0);
-	//light_model = multiply4m(light_translation, light_model);
 
 	uint32_t light_model_loc = glGetUniformLocation(light_sp, "Model");
 	glUniformMatrix4fv(light_model_loc, 1, GL_TRUE, light_model.buffer);
@@ -1039,11 +1022,8 @@ int main(int argc, char* argv[])
 		glClearColor(1.0f, 0.6f, .6f, 1.0f);
 		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
 
-		glActiveTexture(GL_TEXTURE0);
-		glBindTexture(GL_TEXTURE_2D, smiling_texture);
-
-		glActiveTexture(GL_TEXTURE1);
-		glBindTexture(GL_TEXTURE_2D, container_texture);
+		//glActiveTexture(GL_TEXTURE1);
+		//glBindTexture(GL_TEXTURE_2D, container_texture);
 		
 		glUseProgram(light_sp);
 		glBindVertexArray(light_VAO);
@@ -1053,7 +1033,7 @@ int main(int argc, char* argv[])
 
 		glUseProgram(shader_program);
 		glBindVertexArray(VAO);
-		
+
 		for (int i = 0; i < 5; i++)
 		{
 			Vec3 translation_iter = model_translations[i];
diff --git a/source/shaders/light_subject.fs.glsl b/source/shaders/light_subject.fs.glsl
index 54bf700..aa3cf36 100644
--- a/source/shaders/light_subject.fs.glsl
+++ b/source/shaders/light_subject.fs.glsl
@@ -1,45 +1,87 @@
 #version 330 core
+
 struct Material {
+  sampler2D diffuse;
+  sampler2D specular;
+  float shininess;
+};
+
+struct Light {
   vec3 ambient;
   vec3 diffuse;
   vec3 specular;
-  float shininess;
+
+  vec3 position;
 };
 
-struct Light {
+struct DirectionalLight {
+  vec3 direction;
+
   vec3 ambient;
   vec3 diffuse;
   vec3 specular;
+};
 
+struct PointLight {
   vec3 position;
+
+  vec3 ambient;
+  vec3 diffuse;
+  vec3 specular;
+
+  // attentuation factors
+  float kC;
+  float kL;
+  float kQ;
 };
 
+in vec2 texCoords;
 in vec3 fragNormal;
 in vec3 worldPosition;
 
 uniform Material  material;
 uniform Light     light;
+uniform DirectionalLight dirLight;
+uniform PointLight pointLight;
 uniform vec3			cameraPosition;
 uniform vec3      lightColor;
-uniform sampler2D smilingTexture;
-uniform sampler2D containerTexture;
 
 out vec4 FragColor;
 
 void main() {
-		 vec3 ambientLight = light.ambient * material.ambient;
+     float lightDistance = length(pointLight.position - worldPosition);
+     float attenuationFactor = 1.0 / 
+     (pointLight.kC + (pointLight.kL * lightDistance) + (pointLight.kQ * lightDistance * lightDistance));
+
+		 vec3 ambientLight = attenuationFactor * pointLight.ambient * vec3(texture(material.diffuse, texCoords));
 
 //	 @note: Diffuse calculations
-     vec3 lightDir = normalize(light.position - worldPosition);
+     //vec3 lightDir = normalize(light.position - worldPosition);
+     /*
+     @note: an explanation of why the light direction vector is taken from fragment to the 
+     light source.
+     Basic LA really, we need to calculate the angle between the direction of the 2 vectors:
+      a. The direction at which light incidents with the fragment
+      b. The normal vector
+     The reason the light direction is taken from the fragment to the light source, is precisely so we can calculate
+     the angle between the normal and the direction at which light would hit. This if taken as starting from the light
+     source would actually be incorrect, since we would be calculating the angle between the light source in the direction
+     of the fragment and the normal. Consider what happens when it is directly above. The angle becomes 180, not 0. This 
+     is because the normal moves in the direction opposite to the lights direction if taken this way, which is not what
+     we expect or want.
+     Reversing this, allows us to consider the angle at the point in which light hits the fragment, and the normal vector
+     of the fragment. 
+     */
+     vec3 lightDir = normalize(pointLight.position - worldPosition);
      float diffuseStrength = max(dot(lightDir, fragNormal), 0.0);
-     vec3 diffuseLight = light.diffuse * (diffuseStrength * material.diffuse);
+     vec3 diffuseLight = attenuationFactor * pointLight.diffuse * diffuseStrength * vec3(texture(material.diffuse, texCoords));
 
 //	 @note: Specular calculations
 		 vec3  viewDir		      = normalize(cameraPosition - worldPosition);
 		 vec3  reflectDir				= reflect(-lightDir, fragNormal);
 		 float specularity			= max(dot(viewDir, reflectDir), 0.0);
 		 float shinePower				= pow(specularity, material.shininess);
-		 vec3  specularLight		= light.specular * (shinePower * material.specular);
+		 vec3  specularLight		= attenuationFactor * pointLight.specular * shinePower * vec3(texture(material.specular, texCoords));
 
      vec3 color = ambientLight + diffuseLight + specularLight;
      FragColor = vec4(color, 1.0);
diff --git a/source/shaders/light_subject.vs.glsl b/source/shaders/light_subject.vs.glsl
index 327e896..49e58d8 100644
--- a/source/shaders/light_subject.vs.glsl
+++ b/source/shaders/light_subject.vs.glsl
@@ -2,6 +2,7 @@
 
 layout(location = 0) in vec3 position;
 layout(location = 1) in vec3 normal;
+layout(location = 2) in vec2 inTexCoords;
 
 uniform mat4 Model;
 uniform mat4 View;
@@ -9,10 +10,12 @@ uniform mat4 Projection;
 
 out vec3 fragNormal;
 out vec3 worldPosition;
+out vec2 texCoords;
 
 void main() {
     gl_Position = Projection * View * Model * vec4(position, 1.0);
     worldPosition = vec3(Model * vec4(position, 1.0));
     fragNormal = mat3(transpose(inverse(Model))) * normal;
 		fragNormal = normalize(normal);
+    texCoords = inTexCoords;
 }
-- 
cgit v1.2.3