
.. _program_listing_file_Src_GraphicsEngineOpenGL_scene_sky_box_SkyBox.cpp:

Program Listing for File SkyBox.cpp
===================================

|exhale_lsh| :ref:`Return to documentation for file <file_Src_GraphicsEngineOpenGL_scene_sky_box_SkyBox.cpp>` (``Src/GraphicsEngineOpenGL/scene/sky_box/SkyBox.cpp``)

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

.. code-block:: cpp

   module;
   
   #include <array>
   #include <cassert>
   #include <cmath>
   #include <cstdint>
   #include <cstdio>
   #include <cstdlib>
   #include <ctime>
   #include <filesystem>
   #include <iostream>
   #include <memory>
   #include <sstream>
   #include <string>
   #include <vector>
   
   #include <glad/glad.h>
   #include <glm/ext/matrix_float3x3.hpp>
   #include <glm/ext/matrix_float4x4.hpp>
   #include <stb_image.h>
   
   #include "hostDevice/bindings.hpp"
   
   module kataglyphis.opengl.sky_box;
   
   import kataglyphis.opengl.vertex;
   import kataglyphis.opengl.shader_program;
   import kataglyphis.opengl.mesh;
   
   SkyBox::SkyBox()
   {
       std::stringstream skybox_base_dir;
       std::filesystem::path const cwd = std::filesystem::current_path();
       skybox_base_dir << cwd.string();
       skybox_base_dir << RELATIVE_RESOURCE_PATH;
       skybox_base_dir << "Textures/Skybox/DOOM2016/";
   
       std::stringstream texture_loading;
       std::array<std::string, 6> skybox_textures = {
           "DOOM16RT.png", "DOOM16LF.png", "DOOM16UP.png", "DOOM16DN.png", "DOOM16FT.png", "DOOM16BK.png"
       };
   
       std::vector<std::string> skybox_faces;
   
       for (const auto &skybox_texture : skybox_textures) {
           texture_loading << skybox_base_dir.str() << skybox_texture;
           skybox_faces.push_back(texture_loading.str());
           texture_loading.str(std::string());
       }
   
       // time_t timer;
       // srand(time(&timer));
       srand(0);
       shader_playback_time = 1;
   
       shader_program = std::make_shared<ShaderProgram>();
       shader_program->create_from_files("skybox/SkyBox.vert", "skybox/SkyBox.frag");
   
       // texture setup
       glGenTextures(1, &texture_id);
       glBindTexture(GL_TEXTURE_CUBE_MAP, texture_id);
   
       int width;
       int height;
       int bit_depth;
   
       for (size_t i = 0; i < 6; i++) {
           unsigned char *texture_data = stbi_load(skybox_faces[i].c_str(), &width, &height, &bit_depth, 0);
           if (texture_data == nullptr) {
               std::cerr << "Failed to find: " << skybox_faces[i] << '\n';
               return;
           }
   
           glTexImage2D(static_cast<GLenum>(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i),
             0,
             GL_RGBA,
             width,
             height,
             0,
             GL_RGBA,
             GL_UNSIGNED_BYTE,
             texture_data);
   
           stbi_image_free(texture_data);
       }
   
       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);
       glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
       glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
   
       // Mesh Setup
       std::vector<unsigned int> sky_box_indices = { // front
           0,
           1,
           2,
           2,
           1,
           3,
           // right
           2,
           3,
           5,
           5,
           3,
           7,
           // back
           5,
           7,
           4,
           4,
           7,
           6,
           // left
           4,
           6,
           0,
           0,
           6,
           1,
           // top
           4,
           0,
           5,
           5,
           0,
           2,
           // bottom
           1,
           6,
           3,
           3,
           6,
           7
       };
   
       std::vector<Vertex> sky_box_vertices = {
   
           Vertex(glm::vec3(-1.0F, 1.0F, -1.0F),
             glm::vec3(0.0F, 0.0F, 0.0F),
             glm::vec3(0.0F, 0.0F, 0.0F),
             glm::vec2(0.0F, 0.0F)),
   
           Vertex(glm::vec3(-1.0F, -1.0F, -1.0F),
             glm::vec3(0.0F, 0.0F, 0.0F),
             glm::vec3(0.0F, 0.0F, 0.0F),
             glm::vec2(0.0F, 0.0F)),
   
           Vertex(glm::vec3(1.0F, 1.0F, -1.0F),
             glm::vec3(0.0F, 0.0F, 0.0F),
             glm::vec3(0.0F, 0.0F, 0.0F),
             glm::vec2(0.0F, 0.0F)),
   
           Vertex(glm::vec3(1.0F, -1.0F, -1.0F),
             glm::vec3(0.0F, 0.0F, 0.0F),
             glm::vec3(0.0F, 0.0F, 0.0F),
             glm::vec2(0.0F, 0.0F)),
   
           Vertex(glm::vec3(-1.0F, 1.0F, 1.0F),
             glm::vec3(0.0F, 0.0F, 0.0F),
             glm::vec3(0.0F, 0.0F, 0.0F),
             glm::vec2(0.0F, 0.0F)),
   
           Vertex(
             glm::vec3(1.0F, 1.0F, 1.0F), glm::vec3(0.0F, 0.0F, 0.0F), glm::vec3(0.0F, 0.0F, 0.0F), glm::vec2(0.0F, 0.0F)),
   
           Vertex(glm::vec3(-1.0F, -1.0F, 1.0F),
             glm::vec3(0.0F, 0.0F, 0.0F),
             glm::vec3(0.0F, 0.0F, 0.0F),
             glm::vec2(0.0F, 0.0F)),
   
           Vertex(glm::vec3(1.0F, -1.0F, 1.0F),
             glm::vec3(0.0F, 0.0F, 0.0F),
             glm::vec3(0.0F, 0.0F, 0.0F),
             glm::vec2(0.0F, 0.0F)),
   
       };
   
       sky_mesh = std::make_shared<Mesh>(sky_box_vertices, sky_box_indices);
   }
   
   void SkyBox::draw_sky_box(glm::mat4 projection_matrix,
     glm::mat4 view_matrix,
     GLuint /*window_width*/,
     GLuint /*window_height*/,
     GLfloat delta_time)
   {
       // https://learnopengl.com/Advanced-OpenGL/Cubemaps
       GLfloat const velocity = movement_speed * delta_time;
       shader_playback_time = std::fmod(shader_playback_time + velocity, 10000.0F);
   
       glm::mat4 const new_view_matrix = glm::mat4(glm::mat3(view_matrix));
   
       glDepthMask(GL_FALSE);
       glDepthFunc(GL_LEQUAL);
       // std::time_t now =
       // std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
   
       shader_program->use_shader_program();
   
       shader_program->setUniformMatrix4fv(projection_matrix, "projection");
       shader_program->setUniformMatrix4fv(new_view_matrix, "view");
       shader_program->setUniformInt(SKYBOX_TEXTURES_SLOT, "skybox");
   
       glActiveTexture(GL_TEXTURE0 + SKYBOX_TEXTURES_SLOT);
       glBindTexture(GL_TEXTURE_CUBE_MAP, texture_id);
   
       shader_program->validate_program();
   
       sky_mesh->render();
   
       glDepthMask(GL_TRUE);
       glDepthFunc(GL_LESS);
   
       glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
   }
   
   void SkyBox::reload()
   {
       shader_program = std::make_shared<ShaderProgram>();
       shader_program->create_from_files("Shaders/SkyBox.vert", "Shaders/SkyBox.frag");
   }
   
   SkyBox::~SkyBox() { glDeleteTextures(1, &texture_id); }
