
.. _program_listing_file_Src_GraphicsEngineOpenGL_renderer_deferred_LightingPass.cpp:

Program Listing for File LightingPass.cpp
=========================================

|exhale_lsh| :ref:`Return to documentation for file <file_Src_GraphicsEngineOpenGL_renderer_deferred_LightingPass.cpp>` (``Src/GraphicsEngineOpenGL/renderer/deferred/LightingPass.cpp``)

.. |exhale_lsh| unicode:: U+021B0 .. UPWARDS ARROW WITH TIP LEFTWARDS

.. code-block:: cpp

   module;
   
   #include <cassert>
   #include <cstdint>
   #include <glm/ext/vector_float3.hpp>
   #include <glm/ext/matrix_float4x4.hpp>
   #include <memory>
   #include <glad/glad.h>
   #include <glm/ext/vector_float4.hpp>
   #include <sstream>
   #include <utility>
   #include <vector>
   
   #include "hostDevice/bindings.hpp"
   #include "hostDevice/host_device_shared.hpp"
   
   module kataglyphis.opengl.lighting_pass;
   
   import kataglyphis.opengl.camera;
   import kataglyphis.opengl.directional_light;
   import kataglyphis.opengl.point_light;
   import kataglyphis.opengl.directional_light.cascaded_shadow_map;
   import kataglyphis.opengl.point_light.omni_dir_shadow_map;
   import kataglyphis.opengl.scene;
   import kataglyphis.opengl.obj_material;
   import kataglyphis.opengl.clouds;
   import kataglyphis.opengl.gbuffer;
   
   LightingPass::LightingPass() : current_offset(glm::vec3(0.0F)) { create_shader_program(); }
   
   void LightingPass::execute(glm::mat4 projection_matrix,
     const std::shared_ptr<Camera> &main_camera,
     const std::shared_ptr<Scene> &scene,
     const std::shared_ptr<GBuffer> &gbuffer,
     float delta_time)
   {
       glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
   
       std::shared_ptr<DirectionalLight> const main_light = scene->get_sun();
       std::shared_ptr<Clouds> const cloud = scene->get_clouds();
       std::vector<std::shared_ptr<PointLight>> point_lights = scene->get_point_lights();
   
       shader_program->use_shader_program();
   
       set_uniforms(projection_matrix, main_camera, scene, gbuffer, delta_time);
   
       // bind textures to their units
       main_light->get_shadow_map()->read(D_LIGHT_SHADOW_TEXTURES_SLOT);
       cloud->read();
   
       for (uint32_t i = 0; i < static_cast<GLuint>(point_lights.size()); i++) {
           point_lights[i]->get_omni_shadow_map()->read(P_LIGHT_SHADOW_TEXTURES_SLOT + i);
       }
   
       // render screen filling quad
       quad.render();
   
       glBindFramebuffer(GL_FRAMEBUFFER, 0);
   }
   
   void LightingPass::create_shader_program()
   {
       shader_program = std::make_shared<LightingPassShaderProgram>(LightingPassShaderProgram{});
       shader_program->create_from_files(
         "rasterizer/g_buffer_lighting_pass.vert", "rasterizer/g_buffer_lighting_pass.frag");
   }
   
   void LightingPass::set_uniforms(glm::mat4 projection_matrix,
     const std::shared_ptr<Camera> &main_camera,
     const std::shared_ptr<Scene> &scene,
     const std::shared_ptr<GBuffer> &gbuffer,
     float delta_time)
   {
       // VP
       glm::mat4 const view_matrix = main_camera->get_viewmatrix();
       shader_program->setUniformMatrix4fv(view_matrix, "view");
       shader_program->setUniformMatrix4fv(projection_matrix, "projection");
   
       // SUN UNIFORMS
       std::shared_ptr<DirectionalLight> const main_light = scene->get_sun();
       shader_program->setUniformFloat(main_light->get_radiance(), "directional_light.base.radiance");
       shader_program->setUniformVec3(main_light->get_color(), "directional_light.base.color");
       shader_program->setUniformVec3(main_light->get_direction(), "directional_light.direction");
   
       // EVERYTHING REGARDING THE SHADOW CASCADE
       shader_program->setUniformInt(D_LIGHT_SHADOW_TEXTURES_SLOT, "directional_shadow_maps");
   
       std::vector<GLfloat> cascade_slots = main_light->get_cascaded_slots();
   
       std::stringstream ss;
       for (uint32_t i = 0; i < NUM_CASCADES; i++) {
           glm::vec4 const clip_end_slot = projection_matrix * glm::vec4(0.0F, 0.0F, -cascade_slots[i + 1], 1.0F);
           ss << "cascade_endpoints[" << i << "]";
           shader_program->setUniformFloat(clip_end_slot.z, ss.str());
           ss.clear();
           ss.str(std::string());
       }
   
       shader_program->setUniformInt(static_cast<GLint>(main_light->get_shadow_map()->get_pcf_radius()), "pcf_radius");
   
       // READ GBUFFER
       gbuffer->read(shader_program);
   
       // POINT LIGHTS
       std::vector<std::shared_ptr<PointLight>> point_lights = scene->get_point_lights();
   
       shader_program->setUniformInt(static_cast<GLint>(point_lights.size()), "point_light_count");
   
       for (uint32_t i = 0; i < static_cast<uint32_t>(point_lights.size()); i++) {
           ss << "point_lights[" << i << "].base.color";
           shader_program->setUniformVec3(point_lights[i]->get_color(), ss.str());
           ss.clear();
           ss.str(std::string());
   
           ss << "point_lights[" << i << "].base.radiance";
           shader_program->setUniformFloat(point_lights[i]->get_radiance(), ss.str());
           ss.clear();
           ss.str(std::string());
   
           ss << "point_lights[" << i << "].position";
           shader_program->setUniformVec3(point_lights[i]->get_position(), ss.str());
           ss.clear();
           ss.str(std::string());
   
           ss << "point_lights[" << i << "].base.constant";
           shader_program->setUniformFloat(point_lights[i]->get_constant_factor(), ss.str());
           ss.clear();
           ss.str(std::string());
   
           ss << "point_lights[" << i << "].linear";
           shader_program->setUniformFloat(point_lights[i]->get_linear_factor(), ss.str());
           ss.clear();
           ss.str(std::string());
   
           ss << "point_lights[" << i << "].exponent";
           shader_program->setUniformFloat(point_lights[i]->get_exponent_factor(), ss.str());
           ss.clear();
           ss.str(std::string());
   
           ss << "omni_shadow_maps[" << i << "].shadow_map";
           shader_program->setUniformInt(static_cast<GLint>(P_LIGHT_SHADOW_TEXTURES_SLOT + i), ss.str());
           ss.clear();
           ss.str(std::string());
   
           ss << "omni_shadow_maps[" << i << "]far_plane";
           shader_program->setUniformFloat(point_lights[i]->get_far_plane(), ss.str());
           ss.clear();
           ss.str(std::string());
       }
   
       // CAMERA
       glm::vec3 const camera_position = main_camera->get_camera_position();
       shader_program->setUniformVec3(camera_position, "eye_position");
   
       // MATERIALS
       std::vector<ObjMaterial> materials = scene->get_materials();
       for (uint32_t i = 0; i < static_cast<uint32_t>(materials.size()); i++) {
           ss << "materials[" << i << "].ambient";
           shader_program->setUniformVec3(materials[i].get_ambient(), ss.str());
           ss.clear();
           ss.str(std::string());
   
           ss << "materials[" << i << "].diffuse";
           shader_program->setUniformVec3(materials[i].get_diffuse(), ss.str());
           ss.clear();
           ss.str(std::string());
   
           ss << "materials[" << i << "].specular";
           shader_program->setUniformVec3(materials[i].get_specular(), ss.str());
           ss.clear();
           ss.str(std::string());
   
           ss << "materials[" << i << "].transmittance";
           shader_program->setUniformVec3(materials[i].get_transmittance(), ss.str());
           ss.clear();
           ss.str(std::string());
   
           ss << "materials[" << i << "].emission";
           shader_program->setUniformVec3(materials[i].get_emission(), ss.str());
           ss.clear();
           ss.str(std::string());
   
           ss << "materials[" << i << "].shininess";
           shader_program->setUniformFloat(materials[i].get_shininess(), ss.str());
           ss.clear();
           ss.str(std::string());
   
           ss << "materials[" << i << "].ior";
           shader_program->setUniformFloat(materials[i].get_ior(), ss.str());
           ss.clear();
           ss.str(std::string());
   
           ss << "materials[" << i << "].dissolve";
           shader_program->setUniformFloat(materials[i].get_dissolve(), ss.str());
           ss.clear();
           ss.str(std::string());
   
           ss << "materials[" << i << "].illum";
           shader_program->setUniformInt(materials[i].get_illum(), ss.str());
           ss.clear();
           ss.str(std::string());
   
           ss << "materials[" << i << "].textureID";
           shader_program->setUniformInt(materials[i].get_textureID(), ss.str());
           ss.clear();
           ss.str(std::string());
       }
   
       // CLOUDS
   
       std::shared_ptr<Clouds> const cloud = scene->get_clouds();
   
       shader_program->setUniformVec3(cloud->get_radius(), "cloud.radius");
       GLfloat const velocity = cloud->get_movement_speed() * delta_time;
       current_offset = current_offset + cloud->get_movement_direction() * velocity;
       shader_program->setUniformVec3(current_offset, "cloud.offset");
       shader_program->setUniformMatrix4fv(cloud->get_model(), "cloud.model_to_world");
       shader_program->setUniformFloat(cloud->get_scale(), "cloud.scale");
       shader_program->setUniformFloat(1.F - cloud->get_density(), "cloud.threshold");
       shader_program->setUniformFloat(cloud->get_pillowness(), "cloud.pillowness");
       shader_program->setUniformFloat(cloud->get_cirrus_effect(), "cloud.cirrus_effect");
       shader_program->setUniformInt(static_cast<GLint>(cloud->get_num_march_steps()), "cloud.num_march_steps");
       shader_program->setUniformInt(
         static_cast<GLint>(cloud->get_num_march_steps_to_light()), "cloud.num_march_steps_to_light");
   
       if (cloud->get_powder_effect()) {
           shader_program->setUniformInt(1, "cloud.powder_effect");
       } else {
           shader_program->setUniformInt(0, "cloud.powder_effect");
       }
   
       shader_program->setUniformBlockBinding(UNIFORM_LIGHT_MATRICES_BINDING, "LightSpaceMatrices");
   
       shader_program->setUniformInt(RANDOM_NUMBERS_SLOT, "random_number");
   
       shader_program->setUniformInt(NOISE_128D_TEXTURES_SLOT, "noise_texture_1");
       shader_program->setUniformInt(NOISE_32D_TEXTURES_SLOT, "noise_texture_2");
   
       shader_program->validate_program();
   }
   
   LightingPass::~LightingPass() = default;
