gedeng/include/Gedeng/DirectionalLight.h
2021-05-23 20:09:21 +02:00

80 lines
2.6 KiB
C++

#pragma once
#include "Gedeng/Mesh.h"
#include "Gedeng/Shader.h"
#include <glm/glm.hpp>
namespace Gedeng {
class DirectionalLight {
public:
glm::vec3 direction;
explicit DirectionalLight(glm::vec3 direction)
// TODO: Avoid all this duplication
: direction(direction), shadow_shader(Gedeng::Shader("Shader/shadow.vs", "Shader/shadow.fs")) {
// Configure depth map
glGenFramebuffers(1, &depth_map_fbo);
// Create depth texture
glGenTextures(1, &depth_map);
glBindTexture(GL_TEXTURE_2D, depth_map);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RG32F, SHADOW_WIDTH, SHADOW_HEIGHT, 0, GL_RGB, GL_FLOAT, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
// Attach depth texture as FBO's depth buffer
glBindFramebuffer(GL_FRAMEBUFFER, depth_map_fbo);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, depth_map, 0);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
void set_in_shader(Shader &shader) {
shader.setVec3("light_direction", direction);
shader.setMat4("light_space_matrix", get_light_space_matrix());
}
void render_shadow(Mesh &mesh) {
shadow_shader.use();
shadow_shader.setMat4("lightSpaceMatrix", get_light_space_matrix());
glViewport(0, 0, SHADOW_WIDTH, SHADOW_HEIGHT);
glBindFramebuffer(GL_FRAMEBUFFER, depth_map_fbo);
mesh.render(shadow_shader);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
glm::mat4 get_light_space_matrix() {
// TODO: Make the values here configurable
float near_plane = 1.0f, far_plane = 100.0f;
glm::mat4 lightProjection = glm::ortho(-20.0f, 20.0f, -20.0f, 20.0f, near_plane, far_plane);
glm::mat4 lightView = glm::lookAt(-direction * 10.0f, direction, glm::vec3(0.0, 1.0, 0.0));
return lightProjection * lightView;
}
void clear_shadows() {
shadow_shader.use();
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
}
void bind_depth_map_to(int unit) {
glActiveTexture(GL_TEXTURE0 + unit);
glBindTexture(GL_TEXTURE_2D, depth_map);
}
private:
unsigned int depth_map;
unsigned int depth_map_fbo;
const unsigned int SHADOW_WIDTH = 2048;
const unsigned int SHADOW_HEIGHT = 2048;
Gedeng::Shader shadow_shader;
};
} // namespace Gedeng