4#include "SEnvironmentMgr.h" 
    6#include "../AssetsDef.h" 
   12#include "../Loader/STB/stb_image.h" 
   14#include "../Settings.h" 
   15#include "../GLProgramHandle.h" 
   19unsigned int SEnvironmentMgr::m_width = 0;
 
   20unsigned int SEnvironmentMgr::m_height = 0;
 
   21unsigned int SEnvironmentMgr::m_planeVAO = 0;
 
   22unsigned int SEnvironmentMgr::m_cubeVAO = 0;
 
   24SEnvironmentMgr::SEnvironmentMgr() {
 
   27SEnvironmentMgr::~SEnvironmentMgr() {
 
   28    glDeleteBuffers(1, &m_cubeVBO);
 
   29    glDeleteBuffers(1, &m_planeVBO);
 
   32void SEnvironmentMgr::RenderPBREnvironment() {
 
   34    std::string cubemap_str = CSE::AssetMgr::LoadAssetFile(CSE::AssetsPath() + 
"Shader/PBR/IBL/cubemap.vert");
 
   35    std::string etc_str = CSE::AssetMgr::LoadAssetFile(CSE::AssetsPath() + 
"Shader/PBR/IBL/equirectangular_to_cubemap.frag");
 
   36    std::string irr_str = CSE::AssetMgr::LoadAssetFile(CSE::AssetsPath() + 
"Shader/PBR/IBL/irradiance_convolution.frag");
 
   37    std::string pre_str = CSE::AssetMgr::LoadAssetFile(CSE::AssetsPath() + 
"Shader/PBR/IBL/prefilter.frag");
 
   45    glDisable(GL_CULL_FACE);
 
   47    glGenRenderbuffers(1, &m_captureRBO);
 
   48    glBindRenderbuffer(GL_RENDERBUFFER, m_captureRBO);
 
   49    glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, 512, 512);
 
   51    glGenFramebuffers(1, &m_captureFBO);
 
   52    glBindFramebuffer(GL_FRAMEBUFFER, m_captureFBO);
 
   53    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
 
   54                              GL_RENDERBUFFER, m_captureRBO);
 
   58    stbi_set_flip_vertically_on_load(
true);
 
   59    std::string hdr_path = CSE::AssetsPath() + 
"Texture/hdr/newport_loft.hdr";
 
   60    m_hdrTexture = SResource::Create<STexture>(hdr_path);
 
   61    stbi_set_flip_vertically_on_load(
false);
 
   65    m_envCubemap = 
new STexture(STexture::TEX_CUBE);
 
   66    m_envCubemap->SetName(
"envCubemap.textureCubeMap");
 
   67    m_envCubemap->SetAbsoluteID(
"envCubemap.textureCubeMap");
 
   68    std::string hash = 
"CSEENV0000000001";
 
   69    m_envCubemap->SetHash(hash);
 
   70    m_envCubemap->InitTextureMipmap(512, 512);
 
   75    mat4 captureProjection = mat4::Perspective(90.0f, 1.0f, 0.1f, 10.0f);
 
   78                    mat4::LookAt(
vec3(0.0f, 0.0f, 0.0f), 
vec3(1.0f, 0.0f, 0.0f), 
vec3(0.0f, -1.0f, 0.0f)),
 
   79                    mat4::LookAt(
vec3(0.0f, 0.0f, 0.0f), 
vec3(-1.0f, 0.0f, 0.0f), 
vec3(0.0f, -1.0f, 0.0f)),
 
   80                    mat4::LookAt(
vec3(0.0f, 0.0f, 0.0f), 
vec3(0.0f, 1.0f, 0.0f), 
vec3(0.0f, 0.0f, 1.0f)),
 
   81                    mat4::LookAt(
vec3(0.0f, 0.0f, 0.0f), 
vec3(0.0f, -1.0f, 0.0f), 
vec3(0.0f, 0.0f, -1.0f)),
 
   82                    mat4::LookAt(
vec3(0.0f, 0.0f, 0.0f), 
vec3(0.0f, 0.0f, 1.0f), 
vec3(0.0f, -1.0f, 0.0f)),
 
   83                    mat4::LookAt(
vec3(0.0f, 0.0f, 0.0f), 
vec3(0.0f, 0.0f, -1.0f), 
vec3(0.0f, -1.0f, 0.0f))
 
   88    glUseProgram(m_equirectangularToCubemapShader->Program);
 
   89    int hdrTextureLocation = m_equirectangularToCubemapShader->UniformLocation(
"EquirectangularMap")->id;
 
   90    m_equirectangularToCubemapShader->SetUniformMat4(
"PROJECTION_MATRIX", captureProjection);
 
   92    m_hdrTexture->Bind(hdrTextureLocation, 0);
 
   94    if(m_cubeVAO <= 0) LoadCubeVAO();
 
   96    glViewport(0, 0, 512, 512); 
 
   97    glBindFramebuffer(GL_FRAMEBUFFER, m_captureFBO);
 
   98    std::cout << 
"[PBR] Generating Environment Cubemap...";
 
   99    for (
unsigned int i = 0; i < 6; ++i) {
 
  100        m_equirectangularToCubemapShader->SetUniformMat4(
"VIEW_MATRIX", captureViews[i]);
 
  102        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_X + i,
 
  103                               m_envCubemap->GetTextureID(), 0);
 
  105        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
 
  110    m_envCubemap->GenerateMipmap();
 
  112    std::cout << 
" finished!\n";
 
  116    m_irradianceMap = 
new STexture(STexture::TEX_CUBE);
 
  117    m_irradianceMap->SetName(
"irradiance.textureCubeMap");
 
  118    m_irradianceMap->SetAbsoluteID(
"irradiance.textureCubeMap");
 
  119    hash = 
"CSEENV0000000002";
 
  120    m_irradianceMap->SetHash(hash);
 
  121    m_irradianceMap->InitTexture(32, 32);
 
  123    glBindFramebuffer(GL_FRAMEBUFFER, m_captureFBO);
 
  124    glBindRenderbuffer(GL_RENDERBUFFER, m_captureRBO);
 
  125    glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, 32, 32);
 
  129    glUseProgram(m_irradianceShader->Program);
 
  130        int envTextureLocation = m_irradianceShader->UniformLocation(
"EnvironmentMap")->id;
 
  131    m_irradianceShader->SetUniformMat4(
"PROJECTION_MATRIX", captureProjection);
 
  132    m_envCubemap->Bind(envTextureLocation, 0);
 
  134    glViewport(0, 0, 32, 32); 
 
  135    glBindFramebuffer(GL_FRAMEBUFFER, m_captureFBO);
 
  136    std::cout << 
"[PBR] Generating Irradiance Cubemap...";
 
  137    for (
unsigned int i = 0; i < 6; ++i) {
 
  138        m_irradianceShader->SetUniformMat4(
"VIEW_MATRIX", captureViews[i]);
 
  140        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_X + i,
 
  141                               m_irradianceMap->GetTextureID(), 0);
 
  143        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
 
  147    std::cout << 
" finished!\n";
 
  151    m_prefilterMap = 
new STexture(STexture::TEX_CUBE);
 
  152    m_prefilterMap->SetName(
"prefilter.textureCubeMap");
 
  153    m_prefilterMap->SetAbsoluteID(
"prefilter.textureCubeMap");
 
  154    hash = 
"CSEENV0000000003";
 
  155    m_prefilterMap->SetHash(hash);
 
  156    m_prefilterMap->InitTextureMipmap(128, 128);
 
  159    m_prefilterMap->GenerateMipmap();
 
  163    glUseProgram(m_prefilterShader->Program);
 
  164    envTextureLocation = m_prefilterShader->UniformLocation(
"EnvironmentMap")->id;
 
  165    m_prefilterShader->SetUniformMat4(
"PROJECTION_MATRIX", captureProjection);
 
  166    m_envCubemap->Bind(envTextureLocation, 0);
 
  169    glBindFramebuffer(GL_FRAMEBUFFER, m_captureFBO);
 
  170    unsigned int maxMipLevels = 5;
 
  172    std::cout << 
"[PBR] Backing Prefiltering Textures...";
 
  173    for (
unsigned int mip = 0; mip < maxMipLevels; ++mip) {
 
  175        unsigned int mipWidth = 128 * std::pow(0.5, mip);
 
  176        unsigned int mipHeight = 128 * std::pow(0.5, mip);
 
  177        glBindRenderbuffer(GL_RENDERBUFFER, m_captureRBO);
 
  178        glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, mipWidth, mipHeight);
 
  179        glViewport(0, 0, mipWidth, mipHeight);
 
  181        float roughness = (float) mip / (
float) (maxMipLevels - 1);
 
  182        m_prefilterShader->SetUniformFloat(
"FLOAT_ROUGHNESS", roughness);
 
  183        for (
unsigned int i = 0; i < 6; ++i) {
 
  184            m_prefilterShader->SetUniformMat4(
"VIEW_MATRIX", captureViews[i]);
 
  185            glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_X + i,
 
  186                                   m_prefilterMap->GetTextureID(), mip);
 
  189            glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
 
  194        std::cout << 
"Level " << mip << 
"..";
 
  196    std::cout << 
" finished!\n";
 
  199void SEnvironmentMgr::LoadCubeVAO() {
 
  202            -1.0f, -1.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, 
 
  203            1.0f, 1.0f, -1.0f, 0.0f, 0.0f, -1.0f, 1.0f, 1.0f, 
 
  204            1.0f, -1.0f, -1.0f, 0.0f, 0.0f, -1.0f, 1.0f, 0.0f, 
 
  205            1.0f, 1.0f, -1.0f, 0.0f, 0.0f, -1.0f, 1.0f, 1.0f, 
 
  206            -1.0f, -1.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, 
 
  207            -1.0f, 1.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 1.0f, 
 
  209            -1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 
 
  210            1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 
 
  211            1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 
 
  212            1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 
 
  213            -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 
 
  214            -1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 
 
  216            -1.0f, 1.0f, 1.0f, -1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 
 
  217            -1.0f, 1.0f, -1.0f, -1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 
 
  218            -1.0f, -1.0f, -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 
 
  219            -1.0f, -1.0f, -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 
 
  220            -1.0f, -1.0f, 1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 
 
  221            -1.0f, 1.0f, 1.0f, -1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 
 
  223            1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 
 
  224            1.0f, -1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 
 
  225            1.0f, 1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 
 
  226            1.0f, -1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 
 
  227            1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 
 
  228            1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 
 
  230            -1.0f, -1.0f, -1.0f, 0.0f, -1.0f, 0.0f, 0.0f, 1.0f, 
 
  231            1.0f, -1.0f, -1.0f, 0.0f, -1.0f, 0.0f, 1.0f, 1.0f, 
 
  232            1.0f, -1.0f, 1.0f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f, 
 
  233            1.0f, -1.0f, 1.0f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f, 
 
  234            -1.0f, -1.0f, 1.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f, 
 
  235            -1.0f, -1.0f, -1.0f, 0.0f, -1.0f, 0.0f, 0.0f, 1.0f, 
 
  237            -1.0f, 1.0f, -1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 
 
  238            1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 
 
  239            1.0f, 1.0f, -1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, 
 
  240            1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 
 
  241            -1.0f, 1.0f, -1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 
 
  242            -1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f  
 
  244    glGenVertexArrays(1, &m_cubeVAO);
 
  245    glGenBuffers(1, &m_cubeVBO);
 
  247    glBindBuffer(GL_ARRAY_BUFFER, m_cubeVBO);
 
  248    glBufferData(GL_ARRAY_BUFFER, 
sizeof(vertices), vertices, GL_STATIC_DRAW);
 
  250    glBindVertexArray(m_cubeVAO);
 
  251    glEnableVertexAttribArray(0);
 
  252    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * 
sizeof(
float), (
void*) 0);
 
  253    glEnableVertexAttribArray(1);
 
  254    glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * 
sizeof(
float), (
void*)(3 * 
sizeof(
float)));
 
  255    glEnableVertexAttribArray(2);
 
  256    glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * 
sizeof(
float), (
void*)(6 * 
sizeof(
float)));
 
  257    glBindBuffer(GL_ARRAY_BUFFER, 0);
 
  258    glBindVertexArray(0);
 
  261void SEnvironmentMgr::RenderCubeVAO() {
 
  263    glBindVertexArray(m_cubeVAO);
 
  264    glDrawArrays(GL_TRIANGLES, 0, 36);
 
  265    glBindVertexArray(0);
 
  268void SEnvironmentMgr::LoadPlaneVAO() {
 
  269    float quadVertices[] = {
 
  271            -1.0f, 1.0f, 0.0f, 0.0f, 1.0f,
 
  272            -1.0f, -1.0f, 0.0f, 0.0f, 0.0f,
 
  273            1.0f, 1.0f, 0.0f, 1.0f, 1.0f,
 
  274            1.0f, -1.0f, 0.0f, 1.0f, 0.0f,
 
  277    glGenVertexArrays(1, &m_planeVAO);
 
  278    glGenBuffers(1, &m_planeVBO);
 
  279    glBindVertexArray(m_planeVAO);
 
  280    glBindBuffer(GL_ARRAY_BUFFER, m_planeVBO);
 
  281    glBufferData(GL_ARRAY_BUFFER, 
sizeof(quadVertices), &quadVertices, GL_STATIC_DRAW);
 
  282    glEnableVertexAttribArray(0);
 
  283    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * 
sizeof(
float), (
void*) 0);
 
  284    glEnableVertexAttribArray(1);
 
  285    glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * 
sizeof(
float), (
void*) (3 * 
sizeof(
float)));
 
  288void SEnvironmentMgr::RenderPlaneVAO() {
 
  289    glBindVertexArray(m_planeVAO);
 
  290    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
 
  291    glBindVertexArray(0);
 
  294unsigned int SEnvironmentMgr::GetWidth() {
 
  298void SEnvironmentMgr::SetWidth(
unsigned int width) {
 
  302unsigned int SEnvironmentMgr::GetHeight() {
 
  306void SEnvironmentMgr::SetHeight(
unsigned int height) {
 
  310unsigned int* SEnvironmentMgr::GetPointerWidth() {
 
  314unsigned int* SEnvironmentMgr::GetPointerHeight() {
 
  318int SEnvironmentMgr::BindPBREnvironmentMap(
const GLProgramHandle* handle, 
int textureLayout)
 const {
 
  319    if(handle == 
nullptr) 
return 0;
 
  321    if(handle->Uniforms.LightIrradiance != HANDLE_NULL)
 
  322        m_irradianceMap->Bind(handle->Uniforms.LightIrradiance, textureLayout + steps++);
 
  323    if(handle->Uniforms.LightPrefilter != HANDLE_NULL)
 
  324        m_prefilterMap->Bind(handle->Uniforms.LightPrefilter, textureLayout + steps++);
 
  328int SEnvironmentMgr::BindBRDFLUT(
const GLProgramHandle* handle, 
int textureLayout)
 const {
 
  329    if(handle == 
nullptr) 
return 0;
 
  330    if(handle->Uniforms.LightBrdfLut != HANDLE_NULL) {
 
  331        m_brdfMap->Bind(handle->Uniforms.LightBrdfLut, textureLayout);
 
  337void SEnvironmentMgr::RenderBRDFLUT() {
 
  338    std::cout << 
"[PBR] Backing a 2D LUT from the BRDF equations used...";
 
  340    std::string brdf_v_str = CSE::AssetMgr::LoadAssetFile(CSE::AssetsPath() + 
"Shaders/IBL/brdf.vert");
 
  341    std::string brdf_f_str = CSE::AssetMgr::LoadAssetFile(CSE::AssetsPath() + 
"Shaders/IBL/brdf.frag");
 
  348    m_brdfMap->SetName(
"brdfLUT.texture");
 
  349    m_brdfMap->SetAbsoluteID(
"brdfLUT.texture");
 
  350    std::string hash = 
"CSEENV0000000004";
 
  351    m_brdfMap->SetHash(hash);
 
  352    m_brdfMap->InitTexture(512, 512, GL_RG, GL_RG16F, GL_FLOAT);
 
  355    glBindFramebuffer(GL_FRAMEBUFFER, m_captureFBO);
 
  356    glBindRenderbuffer(GL_RENDERBUFFER, m_captureRBO);
 
  357    glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, 512, 512);
 
  358    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_brdfMap->GetTextureID(), 0);
 
  361    glViewport(0, 0, 512, 512);
 
  362    glUseProgram(m_brdfShader->Program);
 
  363    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
 
  364    if(m_planeVAO <= 0) LoadPlaneVAO();
 
  367    std::cout << 
" finished!\n";
 
  370void SEnvironmentMgr::ReleaseRenderingResources() {
 
  372    glDeleteFramebuffers(1, &m_captureFBO);
 
  373    glDeleteRenderbuffers(1, &m_captureRBO);
 
  378    glBindFramebuffer(GL_FRAMEBUFFER, 0);
 
  379    glEnable(GL_CULL_FACE);
 
  382void SEnvironmentMgr::ReleaseVAO() {
 
  383    glDeleteVertexArrays(1, &m_cubeVAO);
 
  384    glDeleteVertexArrays(1, &m_planeVAO);
 
static GLProgramHandle * CreateProgramHandle(const GLchar *vertexSource, const GLchar *fragmentSource, GLProgramHandle *handle=nullptr)
Creates a program handle.