diff --git a/Future/CMakeLists.txt b/Future/CMakeLists.txt index bed5262..caefc5e 100644 --- a/Future/CMakeLists.txt +++ b/Future/CMakeLists.txt @@ -39,6 +39,8 @@ add_library(Future SHARED src/Rendering/OpenGL/Textures/Texture.hpp src/Rendering/OpenGL/Camera.cpp src/Rendering/OpenGL/Camera.hpp + src/Rendering/OpenGL/Mesh.cpp + src/Rendering/OpenGL/Mesh.hpp ) target_include_directories(Future PUBLIC diff --git a/Future/src/Rendering/OpenGL/Buffers/EBO.cpp b/Future/src/Rendering/OpenGL/Buffers/EBO.cpp index 2d0fa93..39884a5 100644 --- a/Future/src/Rendering/OpenGL/Buffers/EBO.cpp +++ b/Future/src/Rendering/OpenGL/Buffers/EBO.cpp @@ -2,11 +2,11 @@ namespace Future { - EBO::EBO(GLuint* indices, GLsizeiptr size) + EBO::EBO(std::vector& indices) { glGenBuffers(1, &ID); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ID); - glBufferData(GL_ELEMENT_ARRAY_BUFFER, size, indices, GL_STATIC_DRAW); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(GLuint), indices.data(), GL_STATIC_DRAW); } void EBO::Bind() diff --git a/Future/src/Rendering/OpenGL/Buffers/EBO.hpp b/Future/src/Rendering/OpenGL/Buffers/EBO.hpp index 1e6eb7c..a8f107e 100644 --- a/Future/src/Rendering/OpenGL/Buffers/EBO.hpp +++ b/Future/src/Rendering/OpenGL/Buffers/EBO.hpp @@ -1,5 +1,6 @@ #ifndef EBO_HPP #define EBO_HPP +#include #include namespace Future @@ -8,7 +9,7 @@ namespace Future { public: GLuint ID; - EBO(GLuint* indices, GLsizeiptr size); + EBO(std::vector& indices); void Bind(); void Unbind(); diff --git a/Future/src/Rendering/OpenGL/Buffers/VBO.cpp b/Future/src/Rendering/OpenGL/Buffers/VBO.cpp index a92dc46..4453c82 100644 --- a/Future/src/Rendering/OpenGL/Buffers/VBO.cpp +++ b/Future/src/Rendering/OpenGL/Buffers/VBO.cpp @@ -4,11 +4,11 @@ namespace Future { - VBO::VBO(GLfloat* vertices, GLsizeiptr size) + VBO::VBO(std::vector& vertices) { glGenBuffers(1, &ID); glBindBuffer(GL_ARRAY_BUFFER, ID); - glBufferData(GL_ARRAY_BUFFER, size, vertices, GL_STATIC_DRAW); + glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(Vertex), vertices.data(), GL_STATIC_DRAW); } void VBO::Bind() diff --git a/Future/src/Rendering/OpenGL/Buffers/VBO.hpp b/Future/src/Rendering/OpenGL/Buffers/VBO.hpp index bdcc118..5132d4d 100644 --- a/Future/src/Rendering/OpenGL/Buffers/VBO.hpp +++ b/Future/src/Rendering/OpenGL/Buffers/VBO.hpp @@ -2,6 +2,17 @@ #define VBO_HPP #include +#include "vec2.hpp" +#include "vec3.hpp" + +struct Vertex +{ + glm::vec3 Position; + glm::vec3 Normal; + glm::vec3 color; + glm::vec2 TexCoords; +}; + namespace Future { class VBO @@ -10,7 +21,7 @@ namespace Future // Reference ID of the Vertex Buffer Object GLuint ID; // Constructor that generates a Vertex Buffer Object and links it to vertices - VBO(GLfloat* vertices, GLsizeiptr size); + VBO(std::vector& vertices); void Bind(); void Unbind(); diff --git a/Future/src/Rendering/OpenGL/Mesh.cpp b/Future/src/Rendering/OpenGL/Mesh.cpp new file mode 100644 index 0000000..c55e05d --- /dev/null +++ b/Future/src/Rendering/OpenGL/Mesh.cpp @@ -0,0 +1,56 @@ +#include "Mesh.hpp" + + +namespace Future +{ + Mesh::Mesh(std::vector & vertices, std::vector & indices, std::vector& textures) + { + Mesh::vertices = vertices; + Mesh::indices = indices; + Mesh::textures = textures; + + VAO.Bind(); // Bind VAO + + VBO VBO (vertices); + EBO EBO (indices); + + VAO.LinkAttrib(VBO, 0, 3, GL_FLOAT, sizeof(Vertex), (void*)0); // Position + VAO.LinkAttrib(VBO, 1, 3, GL_FLOAT, sizeof(Vertex), (void*)(3 * sizeof(float))); // Color + VAO.LinkAttrib(VBO, 2, 2, GL_FLOAT, sizeof(Vertex), (void*)(6 * sizeof(float))); // Texture Coordinate + VAO.LinkAttrib(VBO, 3, 2, GL_FLOAT, sizeof(Vertex), (void*)(9 * sizeof(float))); // Normals + + VAO.Unbind(); + VBO.Unbind(); + EBO.Unbind(); + } + + void Mesh::Draw(Shaders &shaders, Camera &camera) + { + shaders.Activate(); + VAO.Bind(); + + unsigned int numDiffuse = 0; + unsigned int numSpecular = 0; + + for (unsigned int i = 0; i < textures.size(); i++) + { + std::string num; + std::string type = textures[i].type; + if (type == "diffuse") + { + num = std::to_string(numDiffuse++); + } + else if (type == "specular") + { + num = std::to_string(numSpecular++); + } + textures[i].texUnit(shaders, (type + num).c_str(), i); + textures[i].Bind(); + } + glUniform3f(glGetUniformLocation(shaders.ID, "camPos"), camera.Position.x, camera.Position.y, camera.Position.z); + camera.Matrix(shaders, "camMatrix"); + + glDrawElements(GL_TRIANGLES, indices.size(), GL_UNSIGNED_INT, 0); + } + +} // Future \ No newline at end of file diff --git a/Future/src/Rendering/OpenGL/Mesh.hpp b/Future/src/Rendering/OpenGL/Mesh.hpp new file mode 100644 index 0000000..c862b87 --- /dev/null +++ b/Future/src/Rendering/OpenGL/Mesh.hpp @@ -0,0 +1,27 @@ +#ifndef MESH_HPP +#define MESH_HPP + +#include +#include "Buffers/VAO.hpp" +#include "Buffers/EBO.hpp"" +#include "Camera.hpp" +#include "Textures/Texture.hpp" + +namespace Future +{ + class Mesh + { + public: + std::vector vertices; + std::vector indices; + std::vector textures; + + VAO VAO; + + Mesh(std::vector & vertices, std::vector & indices, std::vector& textures); + + void Draw(Shaders& shaders, Camera& camera); + }; +} + +#endif //MESH_HPP diff --git a/Future/src/Rendering/OpenGL/OpenGL.cpp b/Future/src/Rendering/OpenGL/OpenGL.cpp index 5fe294e..509a850 100644 --- a/Future/src/Rendering/OpenGL/OpenGL.cpp +++ b/Future/src/Rendering/OpenGL/OpenGL.cpp @@ -15,6 +15,7 @@ #include "Buffers/VAO.hpp" #include "Buffers/VBO.hpp" #include "Textures/Texture.hpp" +#include "Mesh.hpp" namespace Future { @@ -33,13 +34,12 @@ namespace Future bool OpenGL::Init() { - // Vertices coordinates - GLfloat vertices[] = - { // COORDINATES / COLORS / TexCoord / NORMALS // - -1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, - -1.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, - 1.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, - 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f + Vertex vertices[] = + { // COORDINATES / COLORS / NORMALS / TEXTURE COORDINATES // + Vertex{glm::vec3(-1.0f, 0.0f, 1.0f), glm::vec3(0.0f, 1.0f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f), glm::vec2(0.0f, 0.0f)}, + Vertex{glm::vec3(-1.0f, 0.0f, -1.0f), glm::vec3(0.0f, 1.0f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f), glm::vec2(0.0f, 1.0f)}, + Vertex{glm::vec3( 1.0f, 0.0f, -1.0f), glm::vec3(0.0f, 1.0f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f), glm::vec2(1.0f, 1.0f)}, + Vertex{glm::vec3( 1.0f, 0.0f, 1.0f), glm::vec3(0.0f, 1.0f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f), glm::vec2(1.0f, 0.0f)} }; // Indices for vertices order @@ -49,16 +49,16 @@ namespace Future 0, 2, 3 }; - GLfloat lightVertices[] = + Vertex lightVertices[] = { // COORDINATES // - -0.1f, -0.1f, 0.1f, - -0.1f, -0.1f, -0.1f, - 0.1f, -0.1f, -0.1f, - 0.1f, -0.1f, 0.1f, - -0.1f, 0.1f, 0.1f, - -0.1f, 0.1f, -0.1f, - 0.1f, 0.1f, -0.1f, - 0.1f, 0.1f, 0.1f + Vertex{glm::vec3(-0.1f, -0.1f, 0.1f)}, + Vertex{glm::vec3(-0.1f, -0.1f, -0.1f)}, + Vertex{glm::vec3(0.1f, -0.1f, -0.1f)}, + Vertex{glm::vec3(0.1f, -0.1f, 0.1f)}, + Vertex{glm::vec3(-0.1f, 0.1f, 0.1f)}, + Vertex{glm::vec3(-0.1f, 0.1f, -0.1f)}, + Vertex{glm::vec3(0.1f, 0.1f, -0.1f)}, + Vertex{glm::vec3(0.1f, 0.1f, 0.1f)} }; GLuint lightIndices[] = @@ -83,111 +83,81 @@ namespace Future gladLoadGL(); glViewport(0, 0, 1920, 1080); - Shaders shaderProgram("Shaders/default.vert", "Shaders/default.frag"); + Texture textures[] + { + Texture("planks.png", "diffuse", 0, GL_RGBA, GL_UNSIGNED_BYTE), + Texture("planksSpec.png", "specular", 1, GL_RED, GL_UNSIGNED_BYTE) + }; + + // Generates Shader object using shaders default.vert and default.frag + Shaders shaderProgram("default.vert", "default.frag"); + // Store mesh data in vectors for the mesh + std::vector verts(vertices, vertices + sizeof(vertices) / sizeof(Vertex)); + std::vector ind(indices, indices + sizeof(indices) / sizeof(GLuint)); + std::vector tex(textures, textures + sizeof(textures) / sizeof(Texture)); + // Create floor mesh + Mesh floor(verts, ind, tex); - VAO gl_VAO; - gl_VAO.Bind(); - VBO gl_VBO (vertices, sizeof(vertices)); - EBO gl_EBO (indices, sizeof(indices)); + // Shader for light cube + Shaders lightShader("light.vert", "light.frag"); + // Store mesh data in vectors for the mesh + std::vector lightVerts(lightVertices, lightVertices + sizeof(lightVertices) / sizeof(Vertex)); + std::vector lightInd(lightIndices, lightIndices + sizeof(lightIndices) / sizeof(GLuint)); + // Create light mesh + Mesh light(lightVerts, lightInd, tex); + - gl_VAO.LinkAttrib(gl_VBO, 0, 3, GL_FLOAT, 11 * sizeof(float), (void*)0); // Position - gl_VAO.LinkAttrib(gl_VBO, 1, 3, GL_FLOAT, 11 * sizeof(float), (void*)(3 * sizeof(float))); // Color - gl_VAO.LinkAttrib(gl_VBO, 2, 2, GL_FLOAT, 11 * sizeof(float), (void*)(6 * sizeof(float))); // Texture Coordinate - gl_VAO.LinkAttrib(gl_VBO, 3, 3, GL_FLOAT, 11 * sizeof(float), (void*)(8 * sizeof(float))); // Normals - gl_VAO.Unbind(); - gl_VBO.Unbind(); - gl_EBO.Unbind(); - // ^ Unbind so we won't overwrite it - // Shader for light cube - Shaders lightShader("Shaders/light.vert", "Shaders/light.frag"); - // Generates Vertex Array Object and binds it - VAO lightVAO; - lightVAO.Bind(); - // Generates Vertex Buffer Object and links it to vertices - VBO lightVBO(lightVertices, sizeof(lightVertices)); - // Generates Element Buffer Object and links it to indices - EBO lightEBO(lightIndices, sizeof(lightIndices)); - // Links VBO attributes such as coordinates and colors to VAO - lightVAO.LinkAttrib(lightVBO, 0, 3, GL_FLOAT, 3 * sizeof(float), (void*)0); - // Unbind all to prevent accidentally modifying them - lightVAO.Unbind(); - lightVBO.Unbind(); - lightEBO.Unbind(); glm::vec4 lightColor = glm::vec4(1.0f, 1.0f, 1.0f, 1.0f); glm::vec3 lightPos = glm::vec3(0.5f, 0.5f, 0.5f); glm::mat4 lightModel = glm::mat4(1.0f); lightModel = glm::translate(lightModel, lightPos); - glm::vec3 pyramidPos = glm::vec3(0.0f, 0.0f, 0.0f); - glm::mat4 pyramidModel = glm::mat4(1.0f); - pyramidModel = glm::translate(pyramidModel, pyramidPos); + glm::vec3 objectPos = glm::vec3(0.0f, 0.0f, 0.0f); + glm::mat4 objectModel = glm::mat4(1.0f); + objectModel = glm::translate(objectModel, objectPos); + lightShader.Activate(); glUniformMatrix4fv(glGetUniformLocation(lightShader.ID, "model"), 1, GL_FALSE, glm::value_ptr(lightModel)); glUniform4f(glGetUniformLocation(lightShader.ID, "lightColor"), lightColor.x, lightColor.y, lightColor.z, lightColor.w); shaderProgram.Activate(); - glUniformMatrix4fv(glGetUniformLocation(shaderProgram.ID, "model"), 1, GL_FALSE, glm::value_ptr(pyramidModel)); + glUniformMatrix4fv(glGetUniformLocation(shaderProgram.ID, "model"), 1, GL_FALSE, glm::value_ptr(objectModel)); glUniform4f(glGetUniformLocation(shaderProgram.ID, "lightColor"), lightColor.x, lightColor.y, lightColor.z, lightColor.w); glUniform3f(glGetUniformLocation(shaderProgram.ID, "lightPos"), lightPos.x, lightPos.y, lightPos.z); - Texture testTex("testTexture.png", GL_TEXTURE_2D, GL_TEXTURE0, GL_RGB, GL_UNSIGNED_BYTE); - Texture testTexSpecular("testTextureSpecular.png", GL_TEXTURE_2D, 1, GL_RGB, GL_UNSIGNED_BYTE); - testTex.texUnit(shaderProgram, "tex0", 0); - testTexSpecular.texUnit(shaderProgram, "tex1", 1); - - glEnable(GL_DEPTH_TEST); // Enable depth buffer + // Enables the Depth Buffer + glEnable(GL_DEPTH_TEST); - Camera camera(1920, 1080, glm::vec3(0.0f, 0.0f, 3.0f)); + // Creates camera object + Camera camera(1920, 1080, glm::vec3(0.0f, 0.0f, 2.0f)); while (true) { - // Specify the color of the background - glClearColor(0.0f, 0.0f, 0.0f, 1.0f); - // Clean the back buffer and depth buffer - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glClearColor(0.0f, 0.0f, 0.0f, 1.0f); // Clear screen with color (black) + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear buffers // Handles camera inputs camera.Inputs(glfwWindow); // Updates and exports the camera matrix to the Vertex Shader - camera.UpdateMatrix(45.0f, 0.1f, 100.0f); - - // Tells OpenGL which Shader Program we want to use - shaderProgram.Activate(); - // Exports the camera Position to the Fragment Shader for specular lighting - glUniform3f(glGetUniformLocation(shaderProgram.ID, "camPos"), camera.Position.x, camera.Position.y, camera.Position.z); - // Export the camMatrix to the Vertex Shader of the pyramid - camera.Matrix(shaderProgram, "camMatrix"); - // Binds texture so that is appears in rendering - testTex.Bind(); - testTexSpecular.Bind(); - // Bind the VAO so OpenGL knows to use it - gl_VAO.Bind(); - // Draw primitives, number of indices, datatype of indices, index of indices - glDrawElements(GL_TRIANGLES, sizeof(indices) / sizeof(int), GL_UNSIGNED_INT, 0); - - - // Tells OpenGL which Shader Program we want to use - lightShader.Activate(); - // Export the camMatrix to the Vertex Shader of the light cube - camera.Matrix(lightShader, "camMatrix"); - // Bind the VAO so OpenGL knows to use it - lightVAO.Bind(); - // Draw primitives, number of indices, datatype of indices, index of indices - glDrawElements(GL_TRIANGLES, sizeof(lightIndices) / sizeof(int), GL_UNSIGNED_INT, 0); + camera.UpdateMatrix(45.0f, 0.01f, 1000.0f); + + // Draws different meshes + floor.Draw(shaderProgram, camera); + light.Draw(lightShader, camera); + + // Swap the back buffer with the front buffer glfwSwapBuffers(glfwWindow); // Take care of all GLFW events glfwPollEvents(); } - gl_VAO.Delete(); - gl_VBO.Delete(); - gl_EBO.Delete(); shaderProgram.Delete(); + lightShader.Delete(); glfwDestroyWindow(glfwWindow); return true; diff --git a/Future/src/Rendering/OpenGL/Textures/Texture.cpp b/Future/src/Rendering/OpenGL/Textures/Texture.cpp index 9c4b7bf..2ad787b 100644 --- a/Future/src/Rendering/OpenGL/Textures/Texture.cpp +++ b/Future/src/Rendering/OpenGL/Textures/Texture.cpp @@ -2,7 +2,7 @@ namespace Future { - Texture::Texture(const char* image, GLenum texType, GLuint slot, GLenum format, GLenum pixelType) + Texture::Texture(const char* image, const char* texType, GLuint slot, GLenum format, GLenum pixelType) { // Assigns the type of the texture ot the texture object type = texType; @@ -19,30 +19,30 @@ namespace Future // Assigns the texture to a Texture Unit glActiveTexture(GL_TEXTURE0 + slot); unit == slot; - glBindTexture(texType, ID); + glBindTexture(GL_TEXTURE_2D, ID); // Configures the type of algorithm that is used to make the image smaller or bigger - glTexParameteri(texType, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_LINEAR); - glTexParameteri(texType, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); // Configures the way the texture repeats (if it does at all) - glTexParameteri(texType, GL_TEXTURE_WRAP_S, GL_REPEAT); - glTexParameteri(texType, GL_TEXTURE_WRAP_T, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); // Extra lines in case you choose to use GL_CLAMP_TO_BORDER // float flatColor[] = {1.0f, 1.0f, 1.0f, 1.0f}; // glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, flatColor); // Assigns the image to the OpenGL Texture object - glTexImage2D(texType, 0, GL_RGB, widthImg, heightImg, 0, format, pixelType, bytes); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, widthImg, heightImg, 0, format, pixelType, bytes); // Generates MipMaps - glGenerateMipmap(texType); + glGenerateMipmap(GL_TEXTURE_2D); // Deletes the image data as it is already in the OpenGL Texture object stbi_image_free(bytes); // Unbinds the OpenGL Texture object so that it can't accidentally be modified - glBindTexture(texType, 0); + glBindTexture(GL_TEXTURE_2D, 0); } void Texture::texUnit(Shaders& shader, const char* uniform, GLuint unit) @@ -58,12 +58,12 @@ namespace Future void Texture::Bind() { glActiveTexture(GL_TEXTURE0 + unit); - glBindTexture(type, ID); + glBindTexture(GL_TEXTURE_2D, ID); } void Texture::Unbind() { - glBindTexture(type, 0); + glBindTexture(GL_TEXTURE_2D, 0); } void Texture::Delete() diff --git a/Future/src/Rendering/OpenGL/Textures/Texture.hpp b/Future/src/Rendering/OpenGL/Textures/Texture.hpp index abc82ea..76d8f54 100644 --- a/Future/src/Rendering/OpenGL/Textures/Texture.hpp +++ b/Future/src/Rendering/OpenGL/Textures/Texture.hpp @@ -11,9 +11,9 @@ namespace Future class Texture { public: GLuint ID; - GLenum type; + const char* type; GLuint unit; - Texture(const char* image, GLenum texType, GLuint slot, GLenum format, GLenum pixelType); + Texture(const char* image, const char* texType, GLuint slot, GLenum format, GLenum pixelType); void texUnit(Shaders& shader, const char* uniform, GLuint unit); void Bind(); diff --git a/Future/src/Shaders/default.frag b/Future/src/Shaders/default.frag index bacc6b8..8eeafb8 100644 --- a/Future/src/Shaders/default.frag +++ b/Future/src/Shaders/default.frag @@ -13,10 +13,9 @@ in vec3 Normal; // Imports the current position from the Vertex Shader in vec3 crntPos; -// Gets the Texture Unit from the main function -uniform sampler2D tex0; -// Gets the Specular Texture Unit from the main function -uniform sampler2D tex1; +// Gets the Texture Units from the main function +uniform sampler2D diffuse0; +uniform sampler2D specular0; // Gets the color of the light from the main function uniform vec4 lightColor; // Gets the position of the light from the main function @@ -24,8 +23,62 @@ uniform vec3 lightPos; // Gets the position of the camera from the main function uniform vec3 camPos; -void main() + +vec4 pointLight() { + // used in two variables so I calculate it here to not have to do it twice + vec3 lightVec = lightPos - crntPos; + + // intensity of light with respect to distance + float dist = length(lightVec); + float a = 3.0; + float b = 0.7; + float inten = 1.0f / (a * dist * dist + b * dist + 1.0f); + + // ambient lighting + float ambient = 0.20f; + + // diffuse lighting + vec3 normal = normalize(Normal); + vec3 lightDirection = normalize(lightVec); + float diffuse = max(dot(normal, lightDirection), 0.0f); + + // specular lighting + float specularLight = 0.50f; + vec3 viewDirection = normalize(camPos - crntPos); + vec3 reflectionDirection = reflect(-lightDirection, normal); + float specAmount = pow(max(dot(viewDirection, reflectionDirection), 0.0f), 16); + float specular = specAmount * specularLight; + + return (texture(diffuse0, texCoord) * (diffuse * inten + ambient) + texture(specular0, texCoord).r * specular * inten) * lightColor; +} + +vec4 direcLight() +{ + // ambient lighting + float ambient = 0.20f; + + // diffuse lighting + vec3 normal = normalize(Normal); + vec3 lightDirection = normalize(vec3(1.0f, 1.0f, 0.0f)); + float diffuse = max(dot(normal, lightDirection), 0.0f); + + // specular lighting + float specularLight = 0.50f; + vec3 viewDirection = normalize(camPos - crntPos); + vec3 reflectionDirection = reflect(-lightDirection, normal); + float specAmount = pow(max(dot(viewDirection, reflectionDirection), 0.0f), 16); + float specular = specAmount * specularLight; + + return (texture(diffuse0, texCoord) * (diffuse + ambient) + texture(specular0, texCoord).r * specular) * lightColor; +} + +vec4 spotLight() +{ + // controls how big the area that is lit up is + float outerCone = 0.90f; + float innerCone = 0.95f; + // ambient lighting float ambient = 0.20f; @@ -41,6 +94,15 @@ void main() float specAmount = pow(max(dot(viewDirection, reflectionDirection), 0.0f), 16); float specular = specAmount * specularLight; + // calculates the intensity of the crntPos based on its angle to the center of the light cone + float angle = dot(vec3(0.0f, -1.0f, 0.0f), -lightDirection); + float inten = clamp((angle - outerCone) / (innerCone - outerCone), 0.0f, 1.0f); + + return (texture(diffuse0, texCoord) * (diffuse * inten + ambient) + texture(specular0, texCoord).r * specular * inten) * lightColor; +} + +void main() +{ // outputs final color - FragColor = texture(tex0, texCoord) * lightColor * (diffuse + ambient) + texture(tex1, texCoord).r * specular; + FragColor = spotLight(); } \ No newline at end of file diff --git a/Future/src/Shaders/default.vert b/Future/src/Shaders/default.vert index d441ef5..28dac94 100644 --- a/Future/src/Shaders/default.vert +++ b/Future/src/Shaders/default.vert @@ -2,40 +2,39 @@ // Positions/Coordinates layout (location = 0) in vec3 aPos; +// Normals (not necessarily normalized) +layout (location = 1) in vec3 aNormal; // Colors -layout (location = 1) in vec3 aColor; +layout (location = 2) in vec3 aColor; // Texture Coordinates -layout (location = 2) in vec2 aTex; -// Normals (not necessarily normalized) -layout (location = 3) in vec3 aNormal; - +layout (location = 3) in vec2 aTex; +// Outputs the current position for the Fragment Shader +out vec3 crntPos; +// Outputs the normal for the Fragment Shader +out vec3 Normal; // Outputs the color for the Fragment Shader out vec3 color; // Outputs the texture coordinates to the Fragment Shader out vec2 texCoord; -// Outputs the normal for the Fragment Shader -out vec3 Normal; -// Outputs the current position for the Fragment Shader -out vec3 crntPos; -// Imports the camera matrix from the main function -uniform mat4 camMatrix; // Imports the model matrix from the main function uniform mat4 model; +// Imports the camera matrix from the main function +uniform mat4 camMatrix; void main() { // calculates current position crntPos = vec3(model * vec4(aPos, 1.0f)); - // Outputs the positions/coordinates of all vertices - gl_Position = camMatrix * vec4(crntPos, 1.0); - + // Assigns the normal from the Vertex Data to "Normal" + Normal = aNormal; // Assigns the colors from the Vertex Data to "color" color = aColor; // Assigns the texture coordinates from the Vertex Data to "texCoord" texCoord = aTex; - // Assigns the normal from the Vertex Data to "Normal" - Normal = aNormal; + + // Outputs the positions/coordinates of all vertices + gl_Position = camMatrix * vec4(crntPos, 1.0); } \ No newline at end of file