Refactor framebuffer

This commit is contained in:
2023-06-09 13:56:07 +02:00
parent 3351fa9cd1
commit 58c71d3ff9
27 changed files with 209 additions and 713 deletions

View File

@@ -1,14 +1,12 @@
#version 330 core
const float GAMMA = 2.2f;
const float EXPOSURE = 1.0f;
layout(location = 0) out vec4 f_color;
in vec2 v_tex_coords;
uniform float u_exposure;
uniform bool u_exposureCorrection;
uniform sampler2D u_texture;
void main() {
@@ -16,8 +14,7 @@ void main() {
vec3 fragmentColor = vec3(texture2D(u_texture, v_tex_coords));
// Exposure tone mapping
if(u_exposureCorrection)
fragmentColor = vec3(1.0) - exp(-fragmentColor * u_exposure);
fragmentColor = vec3(1.0) - exp(-fragmentColor * EXPOSURE);
// Gamma correction
fragmentColor = pow(fragmentColor, vec3(1.0/GAMMA));

View File

@@ -3,11 +3,11 @@ add_library(fever_engine
Controller.cpp
Window.cpp
scene.cpp
FrameBuffer.cpp
Helper.cpp
framebuffer.cpp
util/Log.cpp
image.cpp
mesh.cpp
glad.cpp
gltf_loader.cpp
material.cpp
camera.cpp

View File

@@ -1,6 +1,4 @@
#include "Controller.h"
#include "FrameBuffer.h"
#include "Helper.h"
#include "Window.h"
#include "gltf_loader.h"
#include "input.h"
@@ -24,9 +22,11 @@
using namespace entt::literals;
static constexpr unsigned MAX_FPS = 60;
Controller::Controller()
: m_gameWindow(std::make_shared<Window>()),
m_postProcessFrameBuffer(m_gameWindow->physical_dimensions(), post_processing_shader),
post_processing_framebuffer(m_gameWindow->physical_dimensions()),
m_gltf_loader{.image_cache = m_image_cache,
.material_cache = m_material_cache,
.mesh_cache = m_mesh_cache,
@@ -47,8 +47,6 @@ Controller::Controller()
void Controller::run()
{
updateExposure(post_processing_shader);
entt::hashed_string shader_hash(Material::SHADER_NAME.data());
auto standard_material_shader =
m_shader_cache.load(shader_hash, Material::SHADER_NAME).first->second;
@@ -77,14 +75,14 @@ void Controller::run()
// --- Render and buffer swap ---
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
m_postProcessFrameBuffer.bind();
post_processing_framebuffer.bind();
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
Light::update_lights(m_scene->registry(), standard_material_shader);
Render::render(m_scene->registry());
Framebuffer::unbind();
m_postProcessFrameBuffer.drawOnEntireScreen();
post_processing_framebuffer.draw(post_processing_shader);
glfwSwapBuffers(&m_gameWindow->glfw_window());
@@ -120,14 +118,7 @@ void Controller::update_window_dimensions()
// m_gameEventHandler->setFirstMouseInput(1);
auto dimensions = m_gameWindow->physical_dimensions();
m_postProcessFrameBuffer.updateDimensions(dimensions);
}
void Controller::updateExposure(Shader& shader) const
{
shader.bind();
shader.set_uniform("u_exposure", m_exposure);
Shader::unbind();
post_processing_framebuffer = Framebuffer(dimensions);
}
void Controller::update_delta_time(entt::registry& registry) const

View File

@@ -1,6 +1,6 @@
#pragma once
#include "FrameBuffer.h"
#include "framebuffer.h"
#include "gltf_loader.h"
#include "scene.h"
#include "shader.h"
@@ -23,26 +23,19 @@ public:
void run();
void updateExposure(Shader &shader) const;
private:
void limit_framerate();
void update_delta_time(entt::registry &registry) const;
void update_delta_time(entt::registry& registry) const;
void update_window_dimensions();
std::shared_ptr<Window> m_gameWindow;
Shader skybox_shader{"skybox", "data/shaders"};
Shader post_processing_shader{"post_processing", "data/shaders"};
Framebuffer m_postProcessFrameBuffer;
static constexpr unsigned MAX_FPS = 60;
std::shared_ptr<Scene> m_scene;
Shader skybox_shader{"skybox", "data/shaders"};
Shader post_processing_shader{"post_processing", "data/shaders"};
Framebuffer post_processing_framebuffer;
double m_deltaTime{};
float m_exposure = 1.0;
// Resource caches
entt::resource_cache<Image> m_image_cache;

View File

@@ -1,114 +0,0 @@
#include "FrameBuffer.h"
#include "shader.h"
#include "util/Log.h"
#include <cstddef>
#include <glm/fwd.hpp>
void Framebuffer::bind() const
{
glBindFramebuffer(GL_FRAMEBUFFER, m_FBO);
}
void Framebuffer::unbind()
{
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
GLuint Framebuffer::getFBO() const
{
return m_FBO;
}
Framebuffer::Framebuffer(glm::u32vec2 physical_dimensions, Shader &shader) : m_shader(shader)
{
glGenFramebuffers(1, &m_FBO);
generateTextures(physical_dimensions.x, physical_dimensions.y);
setExposureCorrection(true);
}
Framebuffer::~Framebuffer()
{
glDeleteFramebuffers(1, &m_FBO);
glDeleteTextures(1, &m_colorBuffer);
glDeleteRenderbuffers(1, &m_depthStencilBuffer);
}
GLuint Framebuffer::getTextureId() const
{
return m_colorBuffer;
}
void Framebuffer::drawOnEntireScreen() const
{
// Disable wireframe mode
GLint wireframe;
glGetIntegerv(GL_POLYGON_MODE, &wireframe);
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
m_shader.bind();
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, getTextureId());
m_shader.set_uniform("u_texture", 0);
// A VAO is necessary although no data is stored in it
GLuint temp_vao;
glGenVertexArrays(1, &temp_vao);
glBindVertexArray(temp_vao);
glDrawArrays(GL_TRIANGLES, 0, 3);
glBindVertexArray(0);
glPolygonMode(GL_FRONT_AND_BACK, static_cast<GLenum>(wireframe));
m_shader.unbind();
}
void Framebuffer::updateDimensions(glm::u32vec2 physical_dimensions)
{
// Delete old textures
glDeleteTextures(1, &m_colorBuffer);
glDeleteRenderbuffers(1, &m_depthStencilBuffer);
generateTextures(physical_dimensions.x, physical_dimensions.y);
}
void Framebuffer::generateTextures(uint32_t width, uint32_t height)
{
bind();
// Create new textures
glGenTextures(1, &m_colorBuffer);
glGenRenderbuffers(1, &m_depthStencilBuffer);
{
glBindTexture(GL_TEXTURE_2D, m_colorBuffer);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F, static_cast<GLsizei>(width), static_cast<GLsizei>(height), 0,
GL_RGBA, GL_FLOAT, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_colorBuffer, 0);
glBindTexture(GL_TEXTURE_2D, 0);
}
std::array<unsigned, 3> attachments = {GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2};
glDrawBuffers(3, attachments.data());
glBindRenderbuffer(GL_RENDERBUFFER, m_depthStencilBuffer);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, static_cast<GLsizei>(width),
static_cast<GLsizei>(height));
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, m_depthStencilBuffer);
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
Log::logger().error("Framebuffer not complete");
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
unbind();
}
void Framebuffer::setExposureCorrection(bool exposureCorrection) const
{
m_shader.bind();
m_shader.set_uniform("u_exposureCorrection", exposureCorrection);
m_shader.unbind();
}

View File

@@ -1,33 +0,0 @@
#pragma once
#include <glad/gl.h>
#include <glm/glm.hpp>
class Shader;
class Framebuffer
{
public:
Framebuffer(glm::u32vec2 physical_dimensions, Shader &shader);
~Framebuffer();
void bind() const;
static void unbind();
GLuint getFBO() const;
void drawOnEntireScreen() const;
void updateDimensions(glm::u32vec2 physical_dimensions);
void setExposureCorrection(bool exposureCorrection) const;
GLuint getTextureId() const;
private:
void generateTextures(uint32_t width, uint32_t height);
GLuint m_colorBuffer;
GLuint m_depthStencilBuffer;
GLuint m_FBO;
Shader &m_shader;
};

View File

@@ -1,31 +0,0 @@
#pragma once
#include <chrono>
#include <glad/gl.h>
#include <stdint.h>
#include <string>
namespace Helper {
void gl_debug_callback(GLenum source,
GLenum type,
GLuint id,
GLenum severity,
GLsizei length,
const GLchar *message,
const void *userParam);
class Timer
{
public:
Timer(const std::string &name);
~Timer();
private:
std::string m_name;
std::chrono::high_resolution_clock::time_point m_start;
std::chrono::high_resolution_clock::time_point m_end;
std::chrono::duration<float> m_duration;
};
} // namespace Helper

View File

@@ -1,10 +1,12 @@
#include "Window.h"
#include "Helper.h"
#include "definitions/window.h"
#include "util/Log.h"
#include "glad.h"
#include <GLFW/glfw3.h>
#include <glad/gl.h>
#include <GLFW/glfw3.h>
static constexpr unsigned INIT_WINDOW_WIDTH = 1280;
static constexpr unsigned INIT_WINDOW_HEIGHT = 720;
Window::Window()
{
@@ -31,54 +33,20 @@ Window::Window()
// Create OpenGL context
glfwMakeContextCurrent(m_glfw_window.get());
// Initialize GLAD
if (gladLoadGL(glfwGetProcAddress) == 0) {
Log::logger().critical("Failed to initialize GLAD");
std::quick_exit(-1);
}
#ifndef NDEBUG
// NOLINTBEGIN(cppcoreguidelines-pro-type-reinterpret-cast)
auto const* gl_version = reinterpret_cast<char const*>(glGetString(GL_VERSION));
// NOLINTEND(cppcoreguidelines-pro-type-reinterpret-cast)
Log::logger().debug("OpenGL version: {}", gl_version);
glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
glDebugMessageCallback(&Helper::gl_debug_callback, nullptr);
#endif
// Enable z buffer
glEnable(GL_DEPTH_TEST);
// Enable face culling
glEnable(GL_CULL_FACE);
glFrontFace(GL_CW);
glCullFace(GL_FRONT);
// Enable multisampling (a bit redundant because most graphics drivers do this automatically)
glEnable(GL_MULTISAMPLE);
#ifndef NDEBUG
// Disable mouse cursor
m_mouse_catched.catched = false;
#endif
// Disable VSync
glfwSwapInterval(0);
set_catched_cursor(m_mouse_catched.catched);
{
int width{};
int height{};
glfwGetFramebufferSize(m_glfw_window.get(), &width, &height);
glViewport(0, 0, width, height);
}
// Callbacks
glfwSetWindowUserPointer(m_glfw_window.get(), this);
glfwSetKeyCallback(m_glfw_window.get(), key_callback);
glfwSetCursorPosCallback(m_glfw_window.get(), mouse_cursor_callback);
glfwSetFramebufferSizeCallback(m_glfw_window.get(), framebuffer_size_callback);
init_glad();
}
auto Window::dimensions_changed() -> bool

View File

@@ -1,11 +0,0 @@
#pragma once
struct AttributeLocations
{
int position = 0;
int uv = 1;
int normal = 2;
int tangent = 3;
};
static constexpr AttributeLocations ATTRIBUTE_LOCATION;

View File

@@ -1,4 +0,0 @@
#pragma once
static constexpr unsigned INIT_WINDOW_WIDTH = 1280;
static constexpr unsigned INIT_WINDOW_HEIGHT = 720;

100
src/framebuffer.cpp Normal file
View File

@@ -0,0 +1,100 @@
#include "framebuffer.h"
#include "util/Log.h"
#include <array>
Framebuffer::Framebuffer(glm::u32vec2 physical_dimensions)
{
glGenFramebuffers(1, &frame_buffer);
glBindFramebuffer(GL_FRAMEBUFFER, frame_buffer);
auto width = static_cast<GLsizei>(physical_dimensions.x);
auto height = static_cast<GLsizei>(physical_dimensions.y);
// Create new textures
glGenTextures(1, &color_buffer);
glGenRenderbuffers(1, &depth_stencil_buffer);
{
glBindTexture(GL_TEXTURE_2D, color_buffer);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F, width, height, 0, GL_RGBA, GL_FLOAT, nullptr);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glFramebufferTexture2D(
GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, color_buffer, 0);
glBindTexture(GL_TEXTURE_2D, 0);
}
std::array<unsigned, 3> attachments = {
GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2};
glDrawBuffers(3, attachments.data());
glBindRenderbuffer(GL_RENDERBUFFER, depth_stencil_buffer);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, width, height);
glFramebufferRenderbuffer(
GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, depth_stencil_buffer);
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
Log::logger().error("Framebuffer not complete");
}
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
}
Framebuffer::Framebuffer(Framebuffer&& other) noexcept
: color_buffer(other.color_buffer),
depth_stencil_buffer(other.depth_stencil_buffer),
frame_buffer(other.frame_buffer)
{
other.color_buffer = 0;
other.depth_stencil_buffer = 0;
other.frame_buffer = 0;
}
auto Framebuffer::operator=(Framebuffer&& other) noexcept -> Framebuffer&
{
glDeleteFramebuffers(1, &frame_buffer);
glDeleteTextures(1, &color_buffer);
glDeleteRenderbuffers(1, &depth_stencil_buffer);
color_buffer = other.color_buffer;
depth_stencil_buffer = other.depth_stencil_buffer;
frame_buffer = other.frame_buffer;
other.color_buffer = 0;
other.depth_stencil_buffer = 0;
other.frame_buffer = 0;
return *this;
}
Framebuffer::~Framebuffer()
{
glDeleteFramebuffers(1, &frame_buffer);
glDeleteTextures(1, &color_buffer);
glDeleteRenderbuffers(1, &depth_stencil_buffer);
}
void Framebuffer::draw(Shader const& shader) const
{
GLint polygon_mode{};
glGetIntegerv(GL_POLYGON_MODE, &polygon_mode);
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
shader.bind();
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, color_buffer);
shader.set_uniform("u_texture", 0);
// A VAO is necessary although no data is stored in it
GLuint vao{};
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
glDrawArrays(GL_TRIANGLES, 0, 3);
glBindVertexArray(0);
glDeleteVertexArrays(1, &vao);
glPolygonMode(GL_FRONT_AND_BACK, static_cast<GLenum>(polygon_mode));
Shader::unbind();
}

28
src/framebuffer.h Normal file
View File

@@ -0,0 +1,28 @@
#pragma once
#include "shader.h"
#include <entt/entt.hpp>
#include <glad/gl.h>
#include <glm/glm.hpp>
struct Framebuffer
{
Framebuffer(glm::u32vec2 physical_dimensions);
~Framebuffer();
Framebuffer(Framebuffer const&) = delete;
auto operator=(Framebuffer const&) -> Framebuffer& = delete;
Framebuffer(Framebuffer&& other) noexcept;
auto operator=(Framebuffer&& other) noexcept -> Framebuffer&;
void bind() const { glBindFramebuffer(GL_FRAMEBUFFER, frame_buffer); }
static void unbind() { glBindFramebuffer(GL_FRAMEBUFFER, 0); }
void draw(Shader const& shader) const;
GLuint color_buffer{};
GLuint depth_stencil_buffer{};
GLuint frame_buffer{};
};

View File

@@ -1,22 +1,22 @@
#include "Helper.h"
#include "glad.h"
#include "util/Log.h"
#include <algorithm>
#include <GLFW/glfw3.h>
void Helper::gl_debug_callback(GLenum source,
GLenum type,
GLuint id,
GLenum severity,
GLsizei length,
const GLchar *message,
const void *userParam)
static void gl_debug_callback(GLenum source,
GLenum type,
GLuint id,
GLenum severity,
GLsizei length,
GLchar const* message,
void const* userParam)
{
(void)length;
(void)userParam;
const char *_source;
const char *_type;
const char *_severity;
char const* _source;
char const* _type;
char const* _severity;
// Remove unwanted newline characters from message string
std::string _message = message;
@@ -108,7 +108,7 @@ void Helper::gl_debug_callback(GLenum source,
break;
}
if (severity == GL_DEBUG_SEVERITY_HIGH || severity == GL_DEBUG_SEVERITY_MEDIUM)
if (severity == GL_DEBUG_SEVERITY_HIGH || severity == GL_DEBUG_SEVERITY_MEDIUM) {
Log::logger().debug("[OpenGL Debug Message]\n"
"Message: {}\n"
"Source: {}\n"
@@ -120,19 +120,37 @@ void Helper::gl_debug_callback(GLenum source,
_type,
id,
_severity);
}
}
Helper::Timer::Timer(const std::string &name) : m_name(name)
void init_glad()
{
m_start = std::chrono::high_resolution_clock::now();
}
Helper::Timer::~Timer()
{
m_end = std::chrono::high_resolution_clock::now();
m_duration = m_end - m_start;
float ms = m_duration.count() * 1000.0f;
Log::logger().info("Timer {} took {}", m_name, ms);
// Initialize GLAD
if (gladLoadGL(glfwGetProcAddress) == 0) {
Log::logger().critical("Failed to initialize GLAD");
std::quick_exit(-1);
}
#ifndef NDEBUG
// NOLINTBEGIN(cppcoreguidelines-pro-type-reinterpret-cast)
auto const* gl_version = reinterpret_cast<char const*>(glGetString(GL_VERSION));
// NOLINTEND(cppcoreguidelines-pro-type-reinterpret-cast)
Log::logger().debug("OpenGL version: {}", gl_version);
glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
glDebugMessageCallback(&gl_debug_callback, nullptr);
#endif
// Enable z buffer
glEnable(GL_DEPTH_TEST);
// Enable face culling
glEnable(GL_CULL_FACE);
glFrontFace(GL_CW);
glCullFace(GL_FRONT);
// Enable multisampling (a bit redundant because most graphics drivers do this automatically)
glEnable(GL_MULTISAMPLE);
// Disable VSync
glfwSwapInterval(0);
}

3
src/glad.h Normal file
View File

@@ -0,0 +1,3 @@
#include <glad/gl.h>
void init_glad();

View File

@@ -1,6 +1,5 @@
#include "gltf_loader.h"
#include "camera.h"
#include "definitions/attribute_locations.h"
#include "name.h"
#include "relationship.h"
#include "scene.h"
@@ -8,6 +7,16 @@
#include <iterator>
struct AttributeLocations
{
int position = 0;
int uv = 1;
int normal = 2;
int tangent = 3;
};
static constexpr AttributeLocations ATTRIBUTE_LOCATION;
template <typename T>
static auto create_vertex_attribute_data(std::span<uint8_t const> vertex_attribute_data)
-> VertexAttributeData

View File

@@ -77,6 +77,8 @@ struct GpuImage
GpuImage(GpuImage &&other) noexcept : texture(other.texture) { other.texture = 0; }
auto operator=(GpuImage &&other) noexcept -> GpuImage &
{
glDeleteTextures(1, &texture);
texture = other.texture;
other.texture = 0;
return *this;

View File

@@ -1,38 +0,0 @@
#include "EntityWindow.h"
#include "../Entity.h"
#include <imgui.h>
Imgui::EntityWindow::EntityWindow(const std::vector<ModelEntity *> entities) : Window("Entities"), m_entites(entities)
{}
void Imgui::EntityWindow::addWidgets()
{
ImGui::Text("Treelist");
for (const auto &entity : m_entites) {
addChildWidget(*entity);
}
}
void Imgui::EntityWindow::addChildWidget(const ModelEntity &entity)
{
if (entity.getChildren().empty()) {
ImGui::Indent();
ImGui::Text(entity.getUniqueName().c_str());
ImGui::SameLine();
ImGui::SmallButton("Edit");
ImGui::Unindent();
} else {
bool expanded = ImGui::TreeNode(entity.getUniqueName().c_str());
ImGui::SameLine();
ImGui::SmallButton("Edit");
if (expanded) {
for (const auto &child : entity.getChildren()) {
addChildWidget(*(const ModelEntity *)child);
}
ImGui::TreePop();
}
}
}

View File

@@ -1,24 +0,0 @@
#pragma once
#include "Window.h"
#include <vector>
class ModelEntity;
namespace Imgui {
class EntityWindow : public Window
{
public:
EntityWindow(const std::vector<ModelEntity *> entities);
private:
void addWidgets() override;
static void addChildWidget(const ModelEntity &entity);
const std::vector<ModelEntity *> m_entites;
};
} // namespace Imgui

View File

@@ -1,55 +0,0 @@
#include "GeneralInfoWindow.h"
#include "../Controller.h"
#include "../Entity.h"
#include "../Scene.h"
#include "../ShaderProgram.h"
#include <imgui.h>
#include <math.h>
Imgui::GeneralInfoWindow::GeneralInfoWindow(Controller *controller, Scene *world, ShaderProgram *postProcessingProgram,
bool *rotateEntity, bool *drawShadows, bool *rotateLightSource,
glm::vec3 *lightColor, float *exposure, float *intensity)
: Window("Debug Utils"), m_controller(controller), m_scene(world), m_postProcessingProgram(postProcessingProgram),
m_rotateEntity(rotateEntity), m_drawShadows(drawShadows), m_rotateLightSource(rotateLightSource),
m_lightColor(lightColor), m_exposure(exposure), m_intensity(intensity)
{}
void Imgui::GeneralInfoWindow::addWidgets()
{
ImGui::Text("Object");
ImGui::SliderFloat("Rotation", &m_rotation, 0, 2 * M_PI);
ImGui::SliderFloat3("Position", m_translation, -4.0, 4.0);
ImGui::SliderFloat("Scale", &m_scale, 0.02, 2.0);
ImGui::Checkbox("Rotate Object", m_rotateEntity);
ModelEntity *mainObject = m_scene->getEntityById(0);
mainObject->setPosition(glm::vec3(m_translation[0], m_translation[1], m_translation[2]));
if (!*m_rotateEntity) {
mainObject->setRotation(glm::vec3(0.f, 1.0f, 0.f), m_rotation);
}
mainObject->setScale(m_scale);
// color picker
ImGui::Text("\nLight Source");
m_controller->updateExposure(m_postProcessingProgram);
ImGui::SliderFloat("Intensity", m_intensity, 0, 250.f);
ImGui::ColorEdit3("Color", m_color);
m_lightColor->x = m_color[0];
m_lightColor->y = m_color[1];
m_lightColor->z = m_color[2];
ImGui::Text("\nMiscellaneous");
ImGui::SliderFloat("Exposure", m_exposure, 0, 5.0f);
ImGui::Checkbox("Draw Shadows", m_drawShadows);
ImGui::Checkbox("Rotate Lightsource", m_rotateLightSource);
ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0 / ImGui::GetIO().Framerate,
ImGui::GetIO().Framerate);
}

View File

@@ -1,40 +0,0 @@
#pragma once
#include "Window.h"
#include <glm/glm.hpp>
class Scene;
class ShaderProgram;
class Controller;
namespace Imgui {
class GeneralInfoWindow : public Window
{
public:
GeneralInfoWindow(Controller *controller, Scene *world, ShaderProgram *postProcessingProgram, bool *rotateEntity,
bool *drawShadows, bool *rotateLightSource, glm::vec3 *lightColor, float *exposure,
float *intensity);
private:
void addWidgets() override;
Controller *m_controller;
Scene *m_scene;
ShaderProgram *m_postProcessingProgram;
bool *m_rotateEntity;
bool *m_drawShadows;
bool *m_rotateLightSource;
float m_rotation = 0.0f;
float m_translation[3] = {0.0f, 1.0f, 0.0f};
float m_scale = 0.6f;
float m_color[4] = {1.0f, 1.0f, 1.0f, 1.0f};
glm::vec3 *m_lightColor;
float *m_exposure;
float *m_intensity;
};
}; // namespace Imgui

View File

@@ -1,50 +0,0 @@
#include "Handler.h"
#include "Window.h"
#include <GLFW/glfw3.h>
#include <imgui.h>
#include <imgui_impl_glfw.h>
#include <imgui_impl_opengl3.h>
Imgui::Handler::Handler(GLFWwindow *window) : m_GLFWwindow(window)
{
// Setup Dear ImGui context
IMGUI_CHECKVERSION();
ImGui::CreateContext();
ImGuiIO &io = ImGui::GetIO();
(void)io;
// io.IniFilename = nullptr;
// Setup Platform/Renderer bindings
ImGui_ImplGlfw_InitForOpenGL(m_GLFWwindow, true);
ImGui_ImplOpenGL3_Init("#version 150");
// Setup Dear ImGui style
ImGui::StyleColorsDark();
}
Imgui::Handler::~Handler()
{
ImGui_ImplOpenGL3_Shutdown();
ImGui_ImplGlfw_Shutdown();
ImGui::DestroyContext();
}
void Imgui::Handler::addImguiWindow(std::shared_ptr<Window> window)
{
m_windows.push_back(window);
}
void Imgui::Handler::renderWindows()
{
ImGui_ImplOpenGL3_NewFrame();
ImGui_ImplGlfw_NewFrame();
ImGui::NewFrame();
for (auto window : m_windows)
window->render();
ImGui::Render();
ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
}

View File

@@ -1,26 +0,0 @@
#pragma once
#include <memory>
#include <vector>
class GLFWwindow;
namespace Imgui {
class Window;
class Handler
{
public:
Handler(GLFWwindow *window);
~Handler();
void addImguiWindow(std::shared_ptr<Window> window);
void renderWindows();
private:
std::vector<std::shared_ptr<Window>> m_windows;
GLFWwindow *m_GLFWwindow;
};
} // namespace Imgui

View File

@@ -1,15 +0,0 @@
#include "Window.h"
#include <imgui.h>
#include <imgui_impl_glfw.h>
#include <imgui_impl_opengl3.h>
Imgui::Window::Window(const std::string &title) : m_title(title)
{}
void Imgui::Window::render()
{
ImGui::Begin(m_title.c_str());
addWidgets();
ImGui::End();
}

View File

@@ -1,19 +0,0 @@
#pragma once
#include <string>
namespace Imgui {
class Window
{
public:
Window(const std::string &title);
void render();
protected:
virtual void addWidgets() = 0;
std::string m_title;
};
} // namespace Imgui

View File

@@ -1,5 +1,4 @@
#include "Controller.h"
#include "Helper.h"
#include "util/Log.h"
#include <GLFW/glfw3.h>

View File

@@ -1,102 +0,0 @@
#include "CubeMap.h"
#include "../ShaderProgram.h"
#include "../util/Log.h"
#include <glad/gl.h>
TextureCubeMap::TextureCubeMap(const TextureCubeMapDescriptor &descriptor) : AbstractCubeMap(descriptor.path)
{
stbi_set_flip_vertically_on_load(0);
glGenTextures(1, &m_glId);
glBindTexture(GL_TEXTURE_CUBE_MAP, m_glId);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
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);
std::size_t faceCount = 0;
for (const auto &faceName : FACE_NAMES) {
std::string texturePath = descriptor.path + faceName;
int textureWidth{};
int textureHeight{};
int numComponents{};
auto *textureBuffer = stbi_load(texturePath.c_str(), &textureWidth, &textureHeight, &numComponents, 0);
m_textureWidth = static_cast<unsigned>(textureWidth);
m_textureHeight = static_cast<unsigned>(textureHeight);
if (textureBuffer == nullptr) {
Log::logger().warn("CubeMap texture {} could not be loaded", texturePath);
return;
}
GLint internalFormat{};
GLenum dataFormat{};
switch (numComponents) {
case 1:
internalFormat = GL_RED;
dataFormat = GL_RED;
break;
case 3:
internalFormat = GL_SRGB8;
dataFormat = GL_RGB;
break;
case 4:
internalFormat = GL_SRGB8_ALPHA8;
dataFormat = GL_RGBA;
break;
}
glTexImage2D(static_cast<GLenum>(GL_TEXTURE_CUBE_MAP_POSITIVE_X + faceCount), 0, internalFormat,
static_cast<GLsizei>(m_textureWidth), static_cast<GLsizei>(m_textureHeight), 0, dataFormat,
GL_UNSIGNED_BYTE, textureBuffer);
stbi_image_free(textureBuffer);
faceCount++;
}
glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
}
void AbstractCubeMap::bind(ShaderProgram *shaderProgram) const
{
std::string uniformName = "u_skybox";
shaderProgram->set_uniform(uniformName, 0);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_CUBE_MAP, m_glId);
}
void AbstractCubeMap::unbind() const
{
glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
}
InternalCubeMap::InternalCubeMap(unsigned int resolution) : AbstractCubeMap("internal")
{
m_textureWidth = resolution;
m_textureHeight = resolution;
glGenTextures(1, &m_glId);
glBindTexture(GL_TEXTURE_CUBE_MAP, m_glId);
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);
for (unsigned int i = 0; i < static_cast<int>(CubeMapFace::CUBEMAP_FACES_NUM_ITEMS); i++) {
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_DEPTH_COMPONENT24, static_cast<GLsizei>(resolution),
static_cast<GLsizei>(resolution), 0, GL_DEPTH_COMPONENT, GL_FLOAT, nullptr);
}
glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
}

View File

@@ -1,50 +0,0 @@
#pragma once
#include "AbstractTexture.h"
#include <array>
#include <stb/stb_image.h>
#include <vector>
// Order is important!
enum class CubeMapFace
{
Right,
Left,
Top,
Bottom,
Back,
Front,
CUBEMAP_FACES_NUM_ITEMS
};
const std::array<std::string, 6> FACE_NAMES{"right.png", "left.png", "top.png", "bottom.png", "back.png", "front.png"};
class ShaderProgram;
struct TextureCubeMapDescriptor
{
std::string path;
};
class AbstractCubeMap : public AbstractTexture
{
public:
AbstractCubeMap(const std::string &path) : AbstractTexture(path)
{}
void bind(ShaderProgram *shaderProgram) const;
void unbind() const override;
};
class TextureCubeMap : public AbstractCubeMap
{
public:
TextureCubeMap(const TextureCubeMapDescriptor &descriptor);
};
class InternalCubeMap : public AbstractCubeMap
{
public:
InternalCubeMap(unsigned int resolution);
};