diff --git a/include/cameraService.h b/include/cameraService.h index ec7c79c..f371e0b 100644 --- a/include/cameraService.h +++ b/include/cameraService.h @@ -73,15 +73,14 @@ public: Position += Right * velocity; break; case CAMERA_MOVEMENT::UP: - break; Position += Up * velocity; - case CAMERA_MOVEMENT::DOWN: break; + case CAMERA_MOVEMENT::DOWN: Position -= Up * velocity; + break; default: break; } - Position.y = 0.f; } void ProcessMouseMovement(float xOffset, float yOffset, GLboolean constrainPitch = true) diff --git a/include/light.h b/include/light.h new file mode 100644 index 0000000..75839c5 --- /dev/null +++ b/include/light.h @@ -0,0 +1,14 @@ +#ifndef LIGHT_H +#define LIGHT_H + +#include "pch.h" +namespace LIGHT{ + int Light(); + + void frameBufferSizeChange(GLFWwindow *window, int width, int height); + + void processInput(GLFWwindow *window); + void mouse_callback(GLFWwindow* window, double xpos, double ypos); + void scroll_callback(GLFWwindow* window, double xOffset, double yOffset); +} +#endif // !LIGHT_H \ No newline at end of file diff --git a/include/shaderService.h b/include/shaderService.h index 95f418e..ccc3f88 100644 --- a/include/shaderService.h +++ b/include/shaderService.h @@ -10,33 +10,47 @@ #include #include -class ShaderService { +class ShaderService +{ private: unsigned int programId; + public: ShaderService(const std::filesystem::path &vertexShaderPath, const std::filesystem::path &fragShaderPath); bool CheckShader(unsigned int shaderIndex, bool isProgram = false); void Use(); - inline unsigned int GetId(){return this->programId;} - template - requires std::is_same_v || std::is_same_v || std::is_same_v || std::is_same_v + inline unsigned int GetId() { return this->programId; } + template + requires std::is_same_v || std::is_same_v || std::is_same_v || + std::is_same_v || std::is_same_v void SetUniform(std::string_view name, T value); }; -template -requires std::is_same_v || std::is_same_v || std::is_same_v || std::is_same_v -void ShaderService::SetUniform(std::string_view name, T value) { - if constexpr (std::is_same_v) { - glUniform1i(glGetUniformLocation(programId, name.data()), (int) value); - } else if constexpr (std::is_same_v) { +template + requires std::is_same_v || std::is_same_v || std::is_same_v || + std::is_same_v || std::is_same_v +void ShaderService::SetUniform(std::string_view name, T value) +{ + if constexpr (std::is_same_v) + { + glUniform1i(glGetUniformLocation(programId, name.data()), (int)value); + } + else if constexpr (std::is_same_v) + { glUniform1i(glGetUniformLocation(programId, name.data()), value); - } else if constexpr (std::is_same_v) { + } + else if constexpr (std::is_same_v) + { glUniform1f(glGetUniformLocation(programId, name.data()), value); - }else if constexpr (std::is_same_v){ + } + else if constexpr (std::is_same_v) + { const auto index = glGetUniformLocation(this->programId, name.data()); glUniformMatrix4fv(index, 1, GL_FALSE, &value[0][0]); } + else if constexpr (std::is_same_v){ + glUniform3fv(glGetUniformLocation(programId, name.data()), 1, &value[0]); + } } - -#endif //LEARNOPENGL_SHADERHELPER_H +#endif // LEARNOPENGL_SHADERHELPER_H diff --git a/main.cpp b/main.cpp index d3f908a..39a7b35 100644 --- a/main.cpp +++ b/main.cpp @@ -1,11 +1,7 @@ #include -#include "texture.h" -#include "triangle.h" -#include "matrix.h" +#include "light.h" int main(int argc, char **const argv) { -// TRIANGLE::Practice1(); -// auto res = TEXTURE::Texture(); - MATRIX::Matrix(); + LIGHT::Light(); return 0 ; } \ No newline at end of file diff --git a/shaders/light_object.frag b/shaders/light_object.frag new file mode 100644 index 0000000..d99f25c --- /dev/null +++ b/shaders/light_object.frag @@ -0,0 +1,6 @@ +#version 330 core +out vec4 FragColor; + +void main(){ + FragColor = vec4(1.0); +} \ No newline at end of file diff --git a/shaders/light_object.vert b/shaders/light_object.vert new file mode 100644 index 0000000..eb0c7fe --- /dev/null +++ b/shaders/light_object.vert @@ -0,0 +1,10 @@ +#version 330 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); +} \ No newline at end of file diff --git a/shaders/lighting.frag b/shaders/lighting.frag new file mode 100644 index 0000000..10f3a9a --- /dev/null +++ b/shaders/lighting.frag @@ -0,0 +1,25 @@ +#version 330 core +in vec3 Normal; +in vec3 FragPos; +out vec4 FragColor; + +uniform vec3 objectColor; +uniform vec3 lightColor; +uniform vec3 lightPos; +uniform vec3 viewPos; + +void main(){ + float specularStrength = 0.5; + float ambientStrength = 0.1; + vec3 ambient = ambientStrength * lightColor; + vec3 norm = normalize(Normal); + vec3 lightDir = normalize(lightPos - FragPos); + vec3 reflectDir = reflect(-lightDir, norm); + vec3 viewDir = normalize(viewPos - FragPos); + float spec = pow(max(dot(viewDir, reflectDir), 0.0), 32); + vec3 specular = specularStrength * spec * lightColor; + float diff = max(dot(norm, lightDir), 0.0); + vec3 diffuse = diff * lightColor; + vec3 result = (ambient + diffuse + specular) * objectColor; + FragColor = vec4(result, 1.0); +} \ No newline at end of file diff --git a/shaders/lighting.vert b/shaders/lighting.vert new file mode 100644 index 0000000..93f13b9 --- /dev/null +++ b/shaders/lighting.vert @@ -0,0 +1,13 @@ +#version 330 core +layout (location = 0) in vec3 aPos; +layout (location = 1) in vec3 aNormal; +uniform mat4 model; +uniform mat4 view; +uniform mat4 projection; +out vec3 Normal; +out vec3 FragPos; +void main(){ + gl_Position = projection * view * model * vec4(aPos, 1.0); + FragPos = vec3(model * vec4(aPos, 1.0)); + Normal = aNormal; +} \ No newline at end of file diff --git a/src/light.cpp b/src/light.cpp new file mode 100644 index 0000000..487b448 --- /dev/null +++ b/src/light.cpp @@ -0,0 +1,229 @@ +#include "light.h" +#include "cameraService.h" +#include "shaderService.h" +#include "glm/glm.hpp" +#include "glm/gtc/matrix_transform.hpp" +#include "glm/gtc/type_ptr.hpp" + +namespace LIGHT +{ + constexpr unsigned int width = 800; + constexpr unsigned int height = 600; + + static CameraService camera{{0.f, 0.f, 3.f}}; + static float deltaTime = 0.f; + static float lastFrame = 0.f; + static bool firstMouse = true; + float lastX = width / 2; + float lastY = height / 2; + static glm::vec3 lightPos(1.2f, 1.0f, 2.0f); + void frameBufferSizeChange(GLFWwindow *window, int width, int height) + { + glViewport(0, 0, width, height); + } + + void processInput(GLFWwindow *window) + { + float cameraSpeed = 2.5f * deltaTime; + + if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS) + { + glfwSetWindowShouldClose(window, true); + } + if (glfwGetKey(window, GLFW_KEY_W) == GLFW_PRESS) + { + camera.ProcessKeyboard(CAMERA_MOVEMENT::FORWARD, deltaTime); + } + if (glfwGetKey(window, GLFW_KEY_S) == GLFW_PRESS) + { + camera.ProcessKeyboard(CAMERA_MOVEMENT::BACKWARD, deltaTime); + } + if (glfwGetKey(window, GLFW_KEY_A) == GLFW_PRESS) + { + camera.ProcessKeyboard(CAMERA_MOVEMENT::LEFT, deltaTime); + } + if (glfwGetKey(window, GLFW_KEY_D) == GLFW_PRESS) + { + camera.ProcessKeyboard(CAMERA_MOVEMENT::RIGHT, deltaTime); + } + if (glfwGetKey(window, GLFW_KEY_SPACE) == GLFW_PRESS) + { + camera.ProcessKeyboard(CAMERA_MOVEMENT::UP, deltaTime); + } + if (glfwGetKey(window, GLFW_KEY_LEFT_CONTROL) == GLFW_PRESS) + { + camera.ProcessKeyboard(CAMERA_MOVEMENT::DOWN, deltaTime); + } + } + + void mouse_callback(GLFWwindow *window, double xposIn, double yposIn) + { + float xpos = static_cast(xposIn); + float ypos = static_cast(yposIn); + if (firstMouse) + { + lastX = xpos; + lastY = ypos; + firstMouse = false; + } + float xOffset = xpos - lastX; + float yOffset = lastY - ypos; + lastX = xpos; + lastY = ypos; + camera.ProcessMouseMovement(xOffset, yOffset); + } + + void scroll_callback(GLFWwindow *window, double xOffset, double yOffset) + { + camera.ProcessMouseScroll(static_cast(yOffset)); + } + + int Light() + { + glfwInit(); + glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); + glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); + glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); + + GLFWwindow *window = glfwCreateWindow(width, height, "Windows", nullptr, nullptr); + if (!window) + { + glfwTerminate(); + return -1; + } + glfwMakeContextCurrent(window); + glfwSetFramebufferSizeCallback(window, frameBufferSizeChange); + glfwSetCursorPosCallback(window, mouse_callback); + glfwSetScrollCallback(window, scroll_callback); + + glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED); + + if (!gladLoadGLLoader(((GLADloadproc)glfwGetProcAddress))) + { + glfwTerminate(); + return -2; + } + + glEnable(GL_DEPTH_TEST); + + ShaderService lightingShader = ShaderService("../../shaders/lighting.vert", "../../shaders/lighting.frag"); + ShaderService lightCubeShader = ShaderService("../../shaders/light_object.vert", "../../shaders/light_object.frag"); + float 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, + 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}; + + unsigned int VBO, cubeVAO; + glGenBuffers(1, &VBO); + glGenVertexArrays(1, &cubeVAO); + + glBindBuffer(GL_ARRAY_BUFFER, VBO); + glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); + + glBindVertexArray(cubeVAO); + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void *)0); + glEnableVertexAttribArray(0); + glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)(3 * sizeof(float))); + glEnableVertexAttribArray(1); + + unsigned int lightCubeVAO; + glGenVertexArrays(1, &lightCubeVAO); + glBindVertexArray(lightCubeVAO); + + glBindBuffer(GL_ARRAY_BUFFER, VBO); + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void *)0); + glEnableVertexAttribArray(0); + + while (!glfwWindowShouldClose(window)) + { + float currentFrame = static_cast(glfwGetTime()); + deltaTime = currentFrame - lastFrame; + lastFrame = currentFrame; + + // input + // ----- + processInput(window); + + // render + // ------ + glClearColor(0.1f, 0.1f, 0.1f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + // be sure to activate shader when setting uniforms/drawing objects + lightingShader.Use(); + lightingShader.SetUniform("objectColor", glm::vec3{1.0f, 0.5f, 0.31f}); + lightingShader.SetUniform("lightColor", glm::vec3{1.0f, 1.0f, 1.0f}); + lightingShader.SetUniform("lightPos", lightPos); + lightingShader.SetUniform("viewPos", camera.Position); + + glm::mat4 projection = glm::perspective(glm::radians(camera.Zoom), (float)width / (float)width, 0.1f, 100.0f); + glm::mat4 view = camera.GetViewMartix(); + lightingShader.SetUniform("projection", projection); + lightingShader.SetUniform("view", view); + + glm::mat4 model = glm::mat4(1.0f); + lightingShader.SetUniform("model", model); + + glBindVertexArray(cubeVAO); + glDrawArrays(GL_TRIANGLES, 0, 36); + + lightCubeShader.Use(); + lightCubeShader.SetUniform("projection", projection); + lightCubeShader.SetUniform("view", view); + model = glm::mat4(1.0f); + model = glm::translate(model, lightPos); + model = glm::scale(model, glm::vec3(0.2f)); // a smaller cube + lightCubeShader.SetUniform("model", model); + + glBindVertexArray(lightCubeVAO); + glDrawArrays(GL_TRIANGLES, 0, 36); + + glfwSwapBuffers(window); + glfwPollEvents(); + } + glDeleteVertexArrays(1, &lightCubeVAO); + glDeleteVertexArrays(1, &cubeVAO); + glDeleteBuffers(1, &VBO); + + glfwTerminate(); + return 0; + } +} // namespace LIGHT diff --git a/src/shaderService.cpp b/src/shaderService.cpp index 5b771d5..0426de4 100644 --- a/src/shaderService.cpp +++ b/src/shaderService.cpp @@ -9,6 +9,8 @@ ShaderService::ShaderService(const std::filesystem::path &vertexShaderPath, const std::filesystem::path &fragShaderPath) { if(!(exists(vertexShaderPath) && exists(fragShaderPath))){ + std::cout<<"file not exist"<