diff --git a/examples/movement/main.cpp b/examples/movement/main.cpp index d5f02a2..a592e33 100644 --- a/examples/movement/main.cpp +++ b/examples/movement/main.cpp @@ -183,6 +183,7 @@ int main(int argc, char** argv) // Make a square oglu::VertexArray cubeDefault = oglu::MakeVertexArray(vertices, sizeof(vertices), nullptr, 0, topology, sizeof(topology)); + oglu::SharedMaterial cubeMaterial(new oglu::Material); oglu::Object cubes[10] = { oglu::Object(cubeDefault), oglu::Object(cubeDefault), @@ -218,6 +219,9 @@ int main(int argc, char** argv) cubes[8].SetRotation(150.0f, 20.0f, -150.0f); cubes[9].SetRotation(-130.0f, 10.0f, -150.0f); + for (oglu::Object& cube : cubes) + cube.material = cubeMaterial; + oglu::Object lightSource(cubeDefault); lightSource.SetScale(glm::vec3(0.1f)); @@ -254,6 +258,7 @@ int main(int argc, char** argv) oglu::Color bgColor = oglu::Color::Black; lightSource.SetPosition(1.0f, 1.0f, -1.0f); + while (!glfwWindowShouldClose(window)) { processInput(window); @@ -271,6 +276,8 @@ int main(int argc, char** argv) shader->SetUniform3fv("lightPos", 1, glm::value_ptr(lightSource.GetPosition())); shader->SetUniform("lightColor", pointLight.color, true); + shader->SetUniform3fv("viewPos", 1, glm::value_ptr(camera.GetPosition())); + shader->SetUniformMatrix4fv("view", 1, GL_FALSE, glm::value_ptr(camera.GetMatrix())); shader->SetUniformMatrix4fv("projection", 1, GL_FALSE, glm::value_ptr(camera.GetProjection())); @@ -278,6 +285,11 @@ int main(int argc, char** argv) { shader->SetUniform("model", cube); shader->SetUniformMatrix3fv("normal", 1, GL_FALSE, glm::value_ptr(cube.GetNormalMatrix())); + + shader->SetUniform("material.ambient", cube.material->ambient, true); + shader->SetUniform("material.diffuse", cube.material->diffuse, true); + shader->SetUniform("material.specular", cube.material->specular, true); + shader->SetUniform("material.shininess", cube.material->shininess); cube.Render(); } @@ -320,6 +332,18 @@ int main(int argc, char** argv) ImGui::TreePop(); ImGui::Separator(); } + + ImGui::SetNextItemOpen(true); + if (ImGui::TreeNode("Cube Material")) + { + ImGui::ColorEdit3("Ambient", &(cubeMaterial->ambient.r)); + ImGui::ColorEdit3("Diffuse", &(cubeMaterial->diffuse.r)); + ImGui::ColorEdit3("Specular", &(cubeMaterial->specular.r)); + ImGui::SliderFloat("Shininess", &(cubeMaterial->shininess), 1.0f, 256.0f); + + ImGui::TreePop(); + ImGui::Separator(); + } } ImGui::End(); diff --git a/examples/movement/shaders/fragmentShader.frag b/examples/movement/shaders/fragmentShader.frag index dd22c99..7ddd62d 100644 --- a/examples/movement/shaders/fragmentShader.frag +++ b/examples/movement/shaders/fragmentShader.frag @@ -1,4 +1,10 @@ #version 330 core +struct Material +{ + vec3 ambient, diffuse, specular; + float shininess; +}; + in vec2 oUV; in vec3 oNormal; in vec3 oFragPos; @@ -14,18 +20,30 @@ uniform vec3 ambientColor; uniform vec3 lightPos; uniform vec3 lightColor; +uniform vec3 viewPos; + +uniform Material material; + void main() { - vec3 ambient = ambientColor * ambientStrength; + // Ambient light + vec3 ambient = ambientColor * ambientStrength * material.ambient; + vec3 norm = normalize(oNormal); + // Diffuse light vec3 lightDir = normalize(lightPos - oFragPos); - float diff = max(dot(norm, lightDir), 0.0) * 2.0; - diff *= min(1.0 / pow(length(lightPos - oFragPos), 2), 2.0); - - vec3 diffuse = diff * lightColor; + float diff = max(dot(norm, lightDir), 0.0); + vec3 diffuse = (diff * material.diffuse) * lightColor; + + // Specular light + vec3 viewDir = normalize(viewPos - oFragPos); + vec3 reflectDir = reflect(-lightDir, norm); + + float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess); + vec3 specular = (material.specular * spec) * lightColor; vec4 objColor = mix(texture(texture1, oUV), texture(texture2, oUV), 0.2); - FragColor = vec4(ambient + diffuse, 1.0) * objColor; + FragColor = vec4(ambient + diffuse + specular, 1.0) * objColor; } \ No newline at end of file diff --git a/include/camera.hpp b/include/camera.hpp index 9f5a61e..c76ce70 100644 --- a/include/camera.hpp +++ b/include/camera.hpp @@ -74,6 +74,13 @@ namespace oglu */ void SetPosition(const glm::vec3& position); + /** + * @brief Get the cameras position. + * + * @returns a 3D vector pointing to the position of the camera + */ + const glm::vec3 GetPosition(); + /** * @brief Offset the cameras position * diff --git a/include/lighting/point.hpp b/include/lighting/point.hpp index da1c280..743a414 100644 --- a/include/lighting/point.hpp +++ b/include/lighting/point.hpp @@ -25,6 +25,7 @@ namespace oglu public: Color color; + private: glm::vec3* position; bool isLinked; diff --git a/include/object.hpp b/include/object.hpp index 951b09d..6d3594a 100644 --- a/include/object.hpp +++ b/include/object.hpp @@ -9,11 +9,26 @@ #define OBJECT_HPP #include +#include #include #include namespace oglu { + /** + * @brief A structure representing an object's material. + */ + class OGLU_API Material + { + public: + Color ambient = Color::White; + Color diffuse = Color::White; + Color specular = Color::White; + float shininess = 32.0f; + }; + + typedef std::shared_ptr SharedMaterial; + /** * @brief An object in 3D space. * @@ -63,6 +78,10 @@ namespace oglu */ void Render(); + void CopyMaterial(const Material& other); + + SharedMaterial material; + private: VertexArray VAO; ///< The VAO used for rendering }; diff --git a/src/camera.cpp b/src/camera.cpp index fb1f3b8..7613223 100644 --- a/src/camera.cpp +++ b/src/camera.cpp @@ -52,6 +52,11 @@ namespace oglu LookAt(this->position + front); } + const glm::vec3 Camera::GetPosition() + { + return position; + } + void Camera::Move(float x, float y, float z) { this->position += glm::vec3(x, y, z); diff --git a/src/object.cpp b/src/object.cpp index cff1799..2b867d5 100644 --- a/src/object.cpp +++ b/src/object.cpp @@ -2,19 +2,19 @@ namespace oglu { - Object::Object(const GLfloat* vertices, size_t verticesSize, const GLuint* indices, size_t indicesSize, const VertexAttribute* topology, size_t topologySize) //: - // VAO(MakeVertexArray(vertices, verticesSize, indices, indicesSize, topology, topologySize)) + Object::Object(const GLfloat* vertices, size_t verticesSize, const GLuint* indices, size_t indicesSize, const VertexAttribute* topology, size_t topologySize) : + VAO(MakeVertexArray(vertices, verticesSize, indices, indicesSize, topology, topologySize)), + material(new Material) { - VAO = MakeVertexArray(vertices, verticesSize, indices, indicesSize, topology, topologySize); } Object::Object(const VertexArray& vao) : - VAO(vao) + VAO(vao), material(new Material) { } Object::Object(const Object& other) : - VAO(other.VAO) + VAO(other.VAO), material(new Material) { } @@ -26,4 +26,9 @@ namespace oglu { VAO->BindAndDraw(); } + + void Object::CopyMaterial(const Material& other) + { + memcpy(material.get(), &other, sizeof(Material)); + } }