#pragma once #include #include #include #include #include #include #include "Shader.h" #include "MeshRenderer.h" #define SHADOW_WIDTH 1024 #define SHADOW_HEIGHT 1024 class PointLight { public: unsigned int depth_map, depth_map_FBO; float near_plane = 1.0f, far_plane = 100.0f, ambient_intensity = 0.5f, diffuse_intensity = 1.0f, attenuation_constant = 1.0f, attenuation_linear = 0.09f, attenuation_exponential = 0.032f; glm::vec3 Position; glm::vec3 color; Shader shader; PointLight(glm::vec3 position, glm::vec3 color, Shader shader) { this->Position = position; this->color = color; this->shader = shader; SetupLighting(); } void RenderSceneShadows(std::vector meshes) { glm::mat4 shadowProj = glm::perspective(glm::radians(90.0f), (float)SHADOW_WIDTH / (float)SHADOW_HEIGHT, near_plane, far_plane); std::vector shadowTransforms; shadowTransforms.push_back(shadowProj * glm::lookAt(Position, Position + glm::vec3(1.0f, 0.0f, 0.0f), glm::vec3(0.0f, -1.0f, 0.0f))); // Right shadowTransforms.push_back(shadowProj * glm::lookAt(Position, Position + glm::vec3(-1.0f, 0.0f, 0.0f), glm::vec3(0.0f, -1.0f, 0.0f))); // Left shadowTransforms.push_back(shadowProj * glm::lookAt(Position, Position + glm::vec3(0.0f, 1.0f, 0.0f), glm::vec3(0.0f, 0.0f, 1.0f))); // Up shadowTransforms.push_back(shadowProj * glm::lookAt(Position, Position + glm::vec3(0.0f, -1.0f, 0.0f), glm::vec3(0.0f, 0.0f, -1.0f))); // Down shadowTransforms.push_back(shadowProj * glm::lookAt(Position, Position + glm::vec3(0.0f, 0.0f, 1.0f), glm::vec3(0.0f, -1.0f, 0.0f))); // Forward shadowTransforms.push_back(shadowProj * glm::lookAt(Position, Position + glm::vec3(0.0f, 0.0f, -1.0f), glm::vec3(0.0f, -1.0f, 0.0f))); // Backward glEnable(GL_CULL_FACE); glCullFace(GL_FRONT); glEnable(GL_DEPTH_TEST); glDepthMask(GL_TRUE); glViewport(0, 0, SHADOW_WIDTH, SHADOW_HEIGHT); glBindFramebuffer(GL_FRAMEBUFFER, depth_map_FBO); glClear(GL_DEPTH_BUFFER_BIT); shader.Use(); for (unsigned int i = 0; i < 6; ++i) { std::string matrix_name = "shadowMatrices[" + std::to_string(i) + "]"; shader.SetMatrix4(matrix_name.c_str(), shadowTransforms[i]); } shader.SetFloat("farPlane", far_plane); shader.SetVector3f("lightPosition", Position); for (MeshRenderer* mesh : meshes) { mesh->Render(shader); } if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) { std::cout << "Framebuffer not complete!" << std::endl; } glBindFramebuffer(GL_FRAMEBUFFER, 0); glCullFace(GL_BACK); } private: void SetupLighting() { //std::cout << "SetupLighting" << std::endl; glGenFramebuffers(1, &depth_map_FBO); glGenTextures(1, &depth_map); glBindTexture(GL_TEXTURE_CUBE_MAP, depth_map); for (unsigned int i = 0; i < 6; i++) { glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_DEPTH_COMPONENT, SHADOW_WIDTH, SHADOW_HEIGHT, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL); } glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); glBindFramebuffer(GL_FRAMEBUFFER, depth_map_FBO); glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, depth_map, 0); glDrawBuffer(GL_NONE); glReadBuffer(GL_NONE); if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) { std::cout << "Framebuffer not complete!" << std::endl; } glBindFramebuffer(GL_FRAMEBUFFER, 0); } };