Program Listing for File SkyBox.cpp#
↰ Return to documentation for file (Src/GraphicsEngineOpenGL/scene/sky_box/SkyBox.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); }