diff --git a/src/graphics/irr_driver.cpp b/src/graphics/irr_driver.cpp index 0e8ac3e53..0f9a0d940 100644 --- a/src/graphics/irr_driver.cpp +++ b/src/graphics/irr_driver.cpp @@ -126,7 +126,7 @@ IrrDriver::IrrDriver() m_mipviz = m_wireframe = m_normals = m_ssaoviz = false; m_lightviz = m_shadowviz = m_distortviz = m_rsm = m_rh = m_gi = false; m_boundingboxesviz = false; - SkyboxCubeMap = m_last_light_bucket_distance = 0; + m_last_light_bucket_distance = 0; memset(object_count, 0, sizeof(object_count)); } // IrrDriver @@ -1364,19 +1364,19 @@ scene::ISceneNode *IrrDriver::addSkyBox(const std::vector &tex const std::vector &sphericalHarmonics) { assert(texture.size() == 6); - SkyboxTextures = texture; + /*SkyboxTextures = texture; SphericalHarmonicsTextures = sphericalHarmonics; SkyboxCubeMap = 0; - SkyboxSpecularProbe = 0; - + SkyboxSpecularProbe = 0;*/ + //m_skybox_ready = false; //TODO - prepareSkybox(); - m_skybox_ready = true; - /*m_skybox = new Skybox(m_video_driver, + //prepareSkybox(); + //m_skybox_ready = true; + m_skybox = new Skybox(m_video_driver, texture, sphericalHarmonics, - m_scene_manager->getAmbientLight().toSColor());*/ + m_scene_manager->getAmbientLight().toSColor()); @@ -1389,7 +1389,8 @@ scene::ISceneNode *IrrDriver::addSkyBox(const std::vector &tex void IrrDriver::suppressSkyBox() { - SkyboxTextures.clear(); + //TODO! + /*SkyboxTextures.clear(); SphericalHarmonicsTextures.clear(); m_skybox_ready = false; if ((SkyboxCubeMap) && (!ProfileWorld::isNoGraphics())) @@ -1398,7 +1399,9 @@ void IrrDriver::suppressSkyBox() glDeleteTextures(1, &SkyboxSpecularProbe); } SkyboxCubeMap = 0; - SkyboxSpecularProbe = 0; + SkyboxSpecularProbe = 0;*/ + delete m_skybox; + m_skybox = NULL; } // ---------------------------------------------------------------------------- @@ -1778,7 +1781,11 @@ void IrrDriver::onUnloadWorld() void IrrDriver::setAmbientLight(const video::SColorf &light) { m_scene_manager->setAmbientLight(light); - m_skybox_ready = false; + //TODO! + + + + //m_skybox_ready = false; } // setAmbientLight video::SColorf IrrDriver::getAmbientLight() const diff --git a/src/graphics/irr_driver.hpp b/src/graphics/irr_driver.hpp index ac351a326..e34f12005 100644 --- a/src/graphics/irr_driver.hpp +++ b/src/graphics/irr_driver.hpp @@ -215,16 +215,16 @@ private: /** Matrixes used in several places stored here to avoid recomputation. */ core::matrix4 m_ViewMatrix, m_InvViewMatrix, m_ProjMatrix, m_InvProjMatrix, m_ProjViewMatrix, m_InvProjViewMatrix; - std::vector SkyboxTextures; - std::vector SphericalHarmonicsTextures; - bool m_skybox_ready; + //std::vector SkyboxTextures; + //std::vector SphericalHarmonicsTextures; + //bool m_skybox_ready; Skybox *m_skybox; public: - float blueSHCoeff[9]; - float greenSHCoeff[9]; - float redSHCoeff[9]; + //float blueSHCoeff[9]; + //float greenSHCoeff[9]; + //float redSHCoeff[9]; private: /** Keep a trace of the origin file name of a texture. */ @@ -241,8 +241,8 @@ private: ShadowMatrices *m_shadow_matrices; public: - GLuint SkyboxCubeMap; - GLuint SkyboxSpecularProbe; + //GLuint SkyboxCubeMap; + //GLuint SkyboxSpecularProbe; /** A simple class to store video resolutions. */ class VideoMode { @@ -535,6 +535,9 @@ public: // ------------------------------------------------------------------------ inline core::vector3df getWind() {return m_wind->getWind();} // ----------------------------------------------------------------------- + /** Returns a pointer to the skybox. */ + inline Skybox *getSkybox() {return m_skybox;} + // ----------------------------------------------------------------------- const core::vector3df& getSunDirection() const { return m_sun_direction; }; // ----------------------------------------------------------------------- void setSunDirection(const core::vector3df &SunPos) diff --git a/src/graphics/render.cpp b/src/graphics/render.cpp index 3dc457ba7..940fbb6dc 100644 --- a/src/graphics/render.cpp +++ b/src/graphics/render.cpp @@ -186,8 +186,9 @@ void IrrDriver::renderGLSL(float dt) const core::recti &viewport = camera->getViewport(); - if (World::getWorld() && World::getWorld()->getTrack()->hasShadows() && !SphericalHarmonicsTextures.empty()) - irr_driver->getSceneManager()->setAmbientLight(SColor(0, 0, 0, 0)); + //if (World::getWorld() && World::getWorld()->getTrack()->hasShadows() && !SphericalHarmonicsTextures.empty()) + //irr_driver->getSceneManager()->setAmbientLight(SColor(0, 0, 0, 0)); + //TODO! if (!CVS->isDefferedEnabled()) glEnable(GL_FRAMEBUFFER_SRGB); diff --git a/src/graphics/render_lighting.cpp b/src/graphics/render_lighting.cpp index ef2e274fa..9f32d0d3b 100644 --- a/src/graphics/render_lighting.cpp +++ b/src/graphics/render_lighting.cpp @@ -418,9 +418,11 @@ void IrrDriver::uploadLightingData() Lighting[6] = m_suncolor.getBlue(); Lighting[7] = 0.54f; - memcpy(&Lighting[8], blueSHCoeff, 9 * sizeof(float)); - memcpy(&Lighting[17], greenSHCoeff, 9 * sizeof(float)); - memcpy(&Lighting[26], redSHCoeff, 9 * sizeof(float)); + if(m_skybox) { + memcpy(&Lighting[8], m_skybox->getBlueSHCoeff(), 9 * sizeof(float)); + memcpy(&Lighting[17], m_skybox->getGreenSHCoeff(), 9 * sizeof(float)); + memcpy(&Lighting[26], m_skybox->getRedSHCoeff(), 9 * sizeof(float)); + } glBindBuffer(GL_UNIFORM_BUFFER, SharedGPUObjects::getLightingDataUBO()); glBufferSubData(GL_UNIFORM_BUFFER, 0, 36 * sizeof(float), Lighting); @@ -488,8 +490,13 @@ void IrrDriver::renderLights(unsigned pointlightcount, bool hasShadow) { ScopedGPUTimer timer(irr_driver->getGPUTimer(Q_ENVMAP)); - m_post_processing->renderEnvMap(blueSHCoeff, greenSHCoeff, - redSHCoeff, SkyboxSpecularProbe); + if(m_skybox) { + m_post_processing->renderEnvMap(m_skybox->getBlueSHCoeff(), + m_skybox->getGreenSHCoeff(), + m_skybox->getRedSHCoeff(), + m_skybox->getSpecularProbe()); + } + //TODO: move in skybox (or IBL?) class } // Render sunlight if and only if track supports shadow diff --git a/src/graphics/render_skybox.cpp b/src/graphics/render_skybox.cpp index 607431020..7e0cded26 100644 --- a/src/graphics/render_skybox.cpp +++ b/src/graphics/render_skybox.cpp @@ -25,32 +25,7 @@ #define MAX2(a, b) ((a) > (b) ? (a) : (b)) #define MIN2(a, b) ((a) > (b) ? (b) : (a)) -class SkyboxShader : public TextureShader -{ -private: - GLuint m_vao; -public: - SkyboxShader() - { - loadProgram(OBJECT, GL_VERTEX_SHADER, "sky.vert", - GL_FRAGMENT_SHADER, "sky.frag"); - assignUniforms(); - assignSamplerNames(0, "tex", ST_TRILINEAR_CUBEMAP); - - glGenVertexArrays(1, &m_vao); - glBindVertexArray(m_vao); - glBindBuffer(GL_ARRAY_BUFFER, SharedGPUObjects::getSkyTriVBO()); - glEnableVertexAttribArray(0); - glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), 0); - glBindVertexArray(0); - } // SkyboxShader - // ------------------------------------------------------------------------ - void bindVertexArray() - { - glBindVertexArray(m_vao); - } // bindVertexArray -}; // SkyboxShader // ============================================================================ static float getTexelValue(unsigned i, unsigned j, size_t width, size_t height, @@ -119,212 +94,15 @@ static void displayCoeff(float *SHCoeff) SHCoeff[4], SHCoeff[5], SHCoeff[6], SHCoeff[7], SHCoeff[8]); } // displayCoeff -// ---------------------------------------------------------------------------- -void swapPixels(char *old_img, char *new_img, unsigned stride, unsigned old_i, - unsigned old_j, unsigned new_i, unsigned new_j) -{ - new_img[4 * (stride * new_i + new_j)] = old_img[4 * (stride * old_i + old_j)]; - new_img[4 * (stride * new_i + new_j) + 1] = old_img[4 * (stride * old_i + old_j) + 1]; - new_img[4 * (stride * new_i + new_j) + 2] = old_img[4 * (stride * old_i + old_j) + 2]; - new_img[4 * (stride * new_i + new_j) + 3] = old_img[4 * (stride * old_i + old_j) + 3]; -} // swapPixels -// ---------------------------------------------------------------------------- -/** Generate an opengl cubemap texture from 6 2d textures. -Out of legacy the sequence of textures maps to : -- 1st texture maps to GL_TEXTURE_CUBE_MAP_POSITIVE_Y -- 2nd texture maps to GL_TEXTURE_CUBE_MAP_NEGATIVE_Y -- 3rd texture maps to GL_TEXTURE_CUBE_MAP_POSITIVE_X -- 4th texture maps to GL_TEXTURE_CUBE_MAP_NEGATIVE_X -- 5th texture maps to GL_TEXTURE_CUBE_MAP_NEGATIVE_Z -- 6th texture maps to GL_TEXTURE_CUBE_MAP_POSITIVE_Z -* \param textures sequence of 6 textures. -*/ -GLuint generateCubeMapFromTextures(const std::vector &textures) -{ - assert(textures.size() == 6); - GLuint result; - glGenTextures(1, &result); - unsigned size = 0; - for (unsigned i = 0; i < 6; i++) - { - size = MAX2(size, textures[i]->getSize().Width); - size = MAX2(size, textures[i]->getSize().Height); - } - - const unsigned texture_permutation[] = { 2, 3, 0, 1, 5, 4 }; - char *rgba[6]; - for (unsigned i = 0; i < 6; i++) - rgba[i] = new char[size * size * 4]; - for (unsigned i = 0; i < 6; i++) - { - unsigned idx = texture_permutation[i]; - - video::IImage* image = irr_driver->getVideoDriver() - ->createImageFromData(textures[idx]->getColorFormat(), - textures[idx]->getSize(), - textures[idx]->lock(), false ); - textures[idx]->unlock(); - - image->copyToScaling(rgba[i], size, size); - image->drop(); - - if (i == 2 || i == 3) - { - char *tmp = new char[size * size * 4]; - memcpy(tmp, rgba[i], size * size * 4); - for (unsigned x = 0; x < size; x++) - { - for (unsigned y = 0; y < size; y++) - { - swapPixels(tmp, rgba[i], size, x, y, (size - y - 1), x); - } - } - delete[] tmp; - } - - glBindTexture(GL_TEXTURE_CUBE_MAP, result); - if (CVS->isTextureCompressionEnabled()) - { - glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, - GL_COMPRESSED_SRGB_ALPHA, size, size, 0, GL_BGRA, - GL_UNSIGNED_BYTE, (GLvoid*)rgba[i]); - } - else - { - glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, - GL_SRGB_ALPHA, size, size, 0, GL_BGRA, - GL_UNSIGNED_BYTE, (GLvoid*)rgba[i]); - } - } - glGenerateMipmap(GL_TEXTURE_CUBE_MAP); - for (unsigned i = 0; i < 6; i++) - delete[] rgba[i]; - return result; -} // generateCubeMapFromTextures - -// ---------------------------------------------------------------------------- -void IrrDriver::prepareSkybox() -{ - glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS); - - generateDiffuseCoefficients(); - if (!SkyboxTextures.empty()) - { - SkyboxCubeMap = generateCubeMapFromTextures(SkyboxTextures); - SkyboxSpecularProbe = generateSpecularCubemap(SkyboxCubeMap); - } -} // prepareSkybox - -// ---------------------------------------------------------------------------- -void IrrDriver::generateDiffuseCoefficients() -{ - const unsigned texture_permutation[] = { 2, 3, 0, 1, 5, 4 }; - - unsigned sh_w = 0, sh_h = 0; - unsigned char *sh_rgba[6]; - - if (SphericalHarmonicsTextures.size() == 6) - { - - for (unsigned i = 0; i < 6; i++) - { - sh_w = MAX2(sh_w, SphericalHarmonicsTextures[i]->getSize().Width); - sh_h = MAX2(sh_h, SphericalHarmonicsTextures[i]->getSize().Height); - } - - for (unsigned i = 0; i < 6; i++) - sh_rgba[i] = new unsigned char[sh_w * sh_h * 4]; - for (unsigned i = 0; i < 6; i++) - { - unsigned idx = texture_permutation[i]; - - video::IImage* image = getVideoDriver()->createImageFromData( - SphericalHarmonicsTextures[idx]->getColorFormat(), - SphericalHarmonicsTextures[idx]->getSize(), - SphericalHarmonicsTextures[idx]->lock(), - false - ); - SphericalHarmonicsTextures[idx]->unlock(); - - image->copyToScaling(sh_rgba[i], sh_w, sh_h); - delete image; - } - - } - else - { - sh_w = 16; - sh_h = 16; - - video::SColor ambient = m_scene_manager->getAmbientLight().toSColor(); - - for (unsigned i = 0; i < 6; i++) - { - sh_rgba[i] = new unsigned char[sh_w * sh_h * 4]; - - for (unsigned j = 0; j < sh_w * sh_h * 4; j += 4) - { - sh_rgba[i][j] = ambient.getBlue(); - sh_rgba[i][j + 1] = ambient.getGreen(); - sh_rgba[i][j + 2] = ambient.getRed(); - sh_rgba[i][j + 3] = 255; - } - } - } - - // Convert to float texture - Color *FloatTexCube[6]; - for (unsigned i = 0; i < 6; i++) - { - FloatTexCube[i] = new Color[sh_w * sh_h]; - for (unsigned j = 0; j < sh_w * sh_h; j++) - { - FloatTexCube[i][j].Blue = powf(float(0xFF & sh_rgba[i][4 * j]) / 255.f, 2.2f); - FloatTexCube[i][j].Green = powf(float(0xFF & sh_rgba[i][4 * j + 1]) / 255.f, 2.2f); - FloatTexCube[i][j].Red = powf(float(0xFF & sh_rgba[i][4 * j + 2]) / 255.f, 2.2f); - } - } - - generateSphericalHarmonics(FloatTexCube, sh_w, blueSHCoeff, greenSHCoeff, redSHCoeff); - - for (unsigned i = 0; i < 6; i++) - { - delete[] sh_rgba[i]; - delete[] FloatTexCube[i]; - } - - if (SphericalHarmonicsTextures.size() != 6) - { - // Diffuse env map is x 0.25, compensate - for (unsigned i = 0; i < 9; i++) - { - blueSHCoeff[i] *= 4; - greenSHCoeff[i] *= 4; - redSHCoeff[i] *= 4; - } - } -} // generateDiffuseCoefficients // ---------------------------------------------------------------------------- void IrrDriver::renderSkybox(const scene::ICameraSceneNode *camera) { - if (SkyboxTextures.empty()) - return; - glEnable(GL_DEPTH_TEST); - glDisable(GL_CULL_FACE); - assert(SkyboxTextures.size() == 6); - - glDisable(GL_BLEND); - - SkyboxShader::getInstance()->use(); - SkyboxShader::getInstance()->bindVertexArray(); - SkyboxShader::getInstance()->setUniforms(); - - SkyboxShader::getInstance()->setTextureUnits(SkyboxCubeMap); - - glDrawArrays(GL_TRIANGLES, 0, 3); - glBindVertexArray(0); + if(m_skybox) + { + m_skybox->render(camera); + } } // renderSkybox diff --git a/src/graphics/rtts.cpp b/src/graphics/rtts.cpp index 590972bb8..2234de1bb 100644 --- a/src/graphics/rtts.cpp +++ b/src/graphics/rtts.cpp @@ -296,10 +296,15 @@ void RTT::prepareRender(scene::ICameraSceneNode* camera) irr_driver->setRTT(this); irr_driver->getSceneManager()->setActiveCamera(camera); + + //TODO! if (!m_diffuse_coefficients_calculated) { - irr_driver->generateDiffuseCoefficients(); - m_diffuse_coefficients_calculated = true; + //irr_driver->generateDiffuseCoefficients(); + if(irr_driver->getSkybox() != NULL) { + irr_driver->getSkybox()->generateDiffuseCoefficients(irr_driver->getVideoDriver(), irr_driver->getSceneManager()->getAmbientLight().toSColor()); + m_diffuse_coefficients_calculated = true; + } } } @@ -312,6 +317,9 @@ FrameBuffer* RTT::render(scene::ICameraSceneNode* camera, float dt) std::vector glows; // TODO: put this outside of the rendering loop //irr_driver->generateDiffuseCoefficients(); + if(irr_driver->getSkybox() != NULL) + irr_driver->getSkybox()->generateDiffuseCoefficients(irr_driver->getVideoDriver(), irr_driver->getSceneManager()->getAmbientLight().toSColor()); + irr_driver->computeMatrixesAndCameras(camera, m_width, m_height); unsigned plc = irr_driver->updateLightsInfo(camera, dt); irr_driver->uploadLightingData(); diff --git a/src/graphics/shader.cpp b/src/graphics/shader.cpp index 9baf07ca4..4569674a9 100644 --- a/src/graphics/shader.cpp +++ b/src/graphics/shader.cpp @@ -174,13 +174,16 @@ void ShaderBase::bypassUBO() const irr_driver->getCurrentScreenSize().Y); GLint bLmn = glGetUniformLocation(m_program, "blueLmn[0]"); - glUniform1fv(bLmn, 9, irr_driver->blueSHCoeff); + const float* blue_SH_coeff = irr_driver->getSkybox()->getBlueSHCoeff(); + glUniform1fv(bLmn, 9, blue_SH_coeff); GLint gLmn = glGetUniformLocation(m_program, "greenLmn[0]"); - glUniform1fv(gLmn, 9, irr_driver->greenSHCoeff); + const float* green_SH_coeff = irr_driver->getSkybox()->getGreenSHCoeff(); + glUniform1fv(gLmn, 9, green_SH_coeff); GLint rLmn = glGetUniformLocation(m_program, "redLmn[0]"); - glUniform1fv(rLmn, 9, irr_driver->redSHCoeff); + const float* red_SH_coeff = irr_driver->getSkybox()->getRedSHCoeff(); + glUniform1fv(rLmn, 9, red_SH_coeff); GLint sun_dir = glGetUniformLocation(m_program, "sun_direction"); const core::vector3df &sd = irr_driver->getSunDirection(); diff --git a/src/graphics/skybox.cpp b/src/graphics/skybox.cpp index 48c1d0ca9..336fc0dbc 100644 --- a/src/graphics/skybox.cpp +++ b/src/graphics/skybox.cpp @@ -17,15 +17,134 @@ #include "graphics/skybox.hpp" +#include "graphics/central_settings.hpp" #include "graphics/IBL.hpp" +#include "graphics/shaders.hpp" + #include +#include using namespace irr; +class SkyboxShader : public TextureShader +{ +private: + GLuint m_vao; + +public: + SkyboxShader() + { + loadProgram(OBJECT, GL_VERTEX_SHADER, "sky.vert", + GL_FRAGMENT_SHADER, "sky.frag"); + assignUniforms(); + assignSamplerNames(0, "tex", ST_TRILINEAR_CUBEMAP); + + glGenVertexArrays(1, &m_vao); + glBindVertexArray(m_vao); + glBindBuffer(GL_ARRAY_BUFFER, SharedGPUObjects::getSkyTriVBO()); + glEnableVertexAttribArray(0); + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), 0); + glBindVertexArray(0); + } // SkyboxShader + // ------------------------------------------------------------------------ + void bindVertexArray() + { + glBindVertexArray(m_vao); + } // bindVertexArray +}; // SkyboxShader + + +// ---------------------------------------------------------------------------- +void swapPixels(char *old_img, char *new_img, unsigned stride, unsigned old_i, + unsigned old_j, unsigned new_i, unsigned new_j) +{ + new_img[4 * (stride * new_i + new_j)] = old_img[4 * (stride * old_i + old_j)]; + new_img[4 * (stride * new_i + new_j) + 1] = old_img[4 * (stride * old_i + old_j) + 1]; + new_img[4 * (stride * new_i + new_j) + 2] = old_img[4 * (stride * old_i + old_j) + 2]; + new_img[4 * (stride * new_i + new_j) + 3] = old_img[4 * (stride * old_i + old_j) + 3]; +} // swapPixels + + +// ---------------------------------------------------------------------------- +/** Generate an opengl cubemap texture from 6 2d textures. +Out of legacy the sequence of textures maps to : +- 1st texture maps to GL_TEXTURE_CUBE_MAP_POSITIVE_Y +- 2nd texture maps to GL_TEXTURE_CUBE_MAP_NEGATIVE_Y +- 3rd texture maps to GL_TEXTURE_CUBE_MAP_POSITIVE_X +- 4th texture maps to GL_TEXTURE_CUBE_MAP_NEGATIVE_X +- 5th texture maps to GL_TEXTURE_CUBE_MAP_NEGATIVE_Z +- 6th texture maps to GL_TEXTURE_CUBE_MAP_POSITIVE_Z +* \param textures sequence of 6 textures. +*/ +GLuint Skybox::generateCubeMapFromTextures(video::IVideoDriver *video_driver) +{ + assert(m_skybox_textures.size() == 6); + + GLuint result; + glGenTextures(1, &result); + + unsigned size = 0; + for (unsigned i = 0; i < 6; i++) + { + size = std::max(size, m_skybox_textures[i]->getSize().Width); + size = std::max(size, m_skybox_textures[i]->getSize().Height); + } + + const unsigned texture_permutation[] = { 2, 3, 0, 1, 5, 4 }; + char *rgba[6]; + for (unsigned i = 0; i < 6; i++) + rgba[i] = new char[size * size * 4]; + for (unsigned i = 0; i < 6; i++) + { + unsigned idx = texture_permutation[i]; + + video::IImage* image = video_driver + ->createImageFromData(m_skybox_textures[idx]->getColorFormat(), + m_skybox_textures[idx]->getSize(), + m_skybox_textures[idx]->lock(), false ); + m_skybox_textures[idx]->unlock(); + + image->copyToScaling(rgba[i], size, size); + image->drop(); + + if (i == 2 || i == 3) + { + char *tmp = new char[size * size * 4]; + memcpy(tmp, rgba[i], size * size * 4); + for (unsigned x = 0; x < size; x++) + { + for (unsigned y = 0; y < size; y++) + { + swapPixels(tmp, rgba[i], size, x, y, (size - y - 1), x); + } + } + delete[] tmp; + } + + glBindTexture(GL_TEXTURE_CUBE_MAP, result); + if (CVS->isTextureCompressionEnabled()) + { + glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, + GL_COMPRESSED_SRGB_ALPHA, size, size, 0, GL_BGRA, + GL_UNSIGNED_BYTE, (GLvoid*)rgba[i]); + } + else + { + glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, + GL_SRGB_ALPHA, size, size, 0, GL_BGRA, + GL_UNSIGNED_BYTE, (GLvoid*)rgba[i]); + } + } + glGenerateMipmap(GL_TEXTURE_CUBE_MAP); + for (unsigned i = 0; i < 6; i++) + delete[] rgba[i]; + return result; +} // generateCubeMapFromTextures + + void Skybox::generateDiffuseCoefficients(video::IVideoDriver *video_driver, - const std::vector &spherical_harmonics_textures, const video::SColor &ambient) { const unsigned texture_permutation[] = { 2, 3, 0, 1, 5, 4 }; @@ -33,13 +152,13 @@ void Skybox::generateDiffuseCoefficients(video::IVideoDriver *video_driver, unsigned sh_w = 0, sh_h = 0; unsigned char *sh_rgba[6]; - if (spherical_harmonics_textures.size() == 6) + if (m_spherical_harmonics_textures.size() == 6) { for (unsigned i = 0; i < 6; i++) { - sh_w = std::max(sh_w, spherical_harmonics_textures[i]->getSize().Width); - sh_h = std::max(sh_h, spherical_harmonics_textures[i]->getSize().Height); + sh_w = std::max(sh_w, m_spherical_harmonics_textures[i]->getSize().Width); + sh_h = std::max(sh_h, m_spherical_harmonics_textures[i]->getSize().Height); } for (unsigned i = 0; i < 6; i++) @@ -49,12 +168,12 @@ void Skybox::generateDiffuseCoefficients(video::IVideoDriver *video_driver, unsigned idx = texture_permutation[i]; video::IImage* image = video_driver->createImageFromData( - spherical_harmonics_textures[idx]->getColorFormat(), - spherical_harmonics_textures[idx]->getSize(), - spherical_harmonics_textures[idx]->lock(), + m_spherical_harmonics_textures[idx]->getColorFormat(), + m_spherical_harmonics_textures[idx]->getSize(), + m_spherical_harmonics_textures[idx]->lock(), false ); - spherical_harmonics_textures[idx]->unlock(); + m_spherical_harmonics_textures[idx]->unlock(); image->copyToScaling(sh_rgba[i], sh_w, sh_h); delete image; @@ -94,6 +213,18 @@ void Skybox::generateDiffuseCoefficients(video::IVideoDriver *video_driver, } generateSphericalHarmonics(FloatTexCube, sh_w, m_blue_SH_coeff, m_green_SH_coeff, m_red_SH_coeff); + Log::debug("Skybox", "Blue_SH: %f, %f, %f, %f, %f, %f, %f, %f, %f", + m_blue_SH_coeff[0], m_blue_SH_coeff[1], m_blue_SH_coeff[2], + m_blue_SH_coeff[3], m_blue_SH_coeff[4], m_blue_SH_coeff[5], + m_blue_SH_coeff[6], m_blue_SH_coeff[7], m_blue_SH_coeff[8]); + Log::debug("Skybox", "Green_SH: %f, %f, %f, %f, %f, %f, %f, %f, %f", + m_green_SH_coeff[0], m_green_SH_coeff[1], m_green_SH_coeff[2], + m_green_SH_coeff[3], m_green_SH_coeff[4], m_green_SH_coeff[5], + m_green_SH_coeff[6], m_green_SH_coeff[7], m_green_SH_coeff[8]); + Log::debug("Skybox", "Red_SH: %f, %f, %f, %f, %f, %f, %f, %f, %f", + m_red_SH_coeff[0], m_red_SH_coeff[1], m_red_SH_coeff[2], + m_red_SH_coeff[3], m_red_SH_coeff[4], m_red_SH_coeff[5], + m_red_SH_coeff[6], m_red_SH_coeff[7], m_red_SH_coeff[8]); for (unsigned i = 0; i < 6; i++) { @@ -101,7 +232,7 @@ void Skybox::generateDiffuseCoefficients(video::IVideoDriver *video_driver, delete[] FloatTexCube[i]; } - if (spherical_harmonics_textures.size() != 6) + if (m_spherical_harmonics_textures.size() != 6) { // Diffuse env map is x 0.25, compensate for (unsigned i = 0; i < 9; i++) @@ -114,14 +245,6 @@ void Skybox::generateDiffuseCoefficients(video::IVideoDriver *video_driver, } // generateDiffuseCoefficients -GLuint Skybox::generateCubeMapFromTextures(const std::vector &skybox_textures) -{ - //TODO - - - - -} Skybox::Skybox(video::IVideoDriver *video_driver, @@ -129,14 +252,19 @@ Skybox::Skybox(video::IVideoDriver *video_driver, const std::vector &spherical_harmonics_textures, const video::SColor &ambient) { + m_skybox_textures = skybox_textures; + m_spherical_harmonics_textures = spherical_harmonics_textures; + glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS); - generateDiffuseCoefficients(video_driver, spherical_harmonics_textures, ambient); + generateDiffuseCoefficients(video_driver, ambient); if (!skybox_textures.empty()) { - m_cube_map = generateCubeMapFromTextures(skybox_textures); - //m_specular_probe = generateSpecularCubemap(m_cube_map); - } + m_cube_map = generateCubeMapFromTextures(video_driver); + m_specular_probe = generateSpecularCubemap(m_cube_map); + } + + } Skybox::~Skybox() @@ -144,5 +272,25 @@ Skybox::~Skybox() //TODOskybox } +// ---------------------------------------------------------------------------- +void Skybox::render(const scene::ICameraSceneNode *camera) const +{ + if (m_skybox_textures.empty()) + return; + glEnable(GL_DEPTH_TEST); + glDisable(GL_CULL_FACE); + assert(m_skybox_textures.size() == 6); + + glDisable(GL_BLEND); + + SkyboxShader::getInstance()->use(); + SkyboxShader::getInstance()->bindVertexArray(); + SkyboxShader::getInstance()->setUniforms(); + + SkyboxShader::getInstance()->setTextureUnits(m_cube_map); + + glDrawArrays(GL_TRIANGLES, 0, 3); + glBindVertexArray(0); +} // renderSkybox diff --git a/src/graphics/skybox.hpp b/src/graphics/skybox.hpp index a4b5483b6..55c7187ba 100644 --- a/src/graphics/skybox.hpp +++ b/src/graphics/skybox.hpp @@ -20,6 +20,7 @@ #define HEADER_SKYBOX_HPP #include "graphics/gl_headers.hpp" +#include #include #include #include @@ -27,8 +28,15 @@ class Skybox { private: - /** The cube map texture id */ + /** The 6 skybox textures */ + std::vector m_skybox_textures; + + /** The skybox texture id */ GLuint m_cube_map; + + /** The 6 specular probe textures */ + std::vector m_spherical_harmonics_textures; + /** The specular probe texture id */ GLuint m_specular_probe; @@ -36,16 +44,14 @@ private: float m_blue_SH_coeff[9]; float m_green_SH_coeff[9]; float m_red_SH_coeff[9]; + //TODO : move spherical harmonic in a separate class (IBL?) + GLuint generateCubeMapFromTextures (irr::video::IVideoDriver *video_driver); - void generateDiffuseCoefficients(irr::video::IVideoDriver *video_driver, - const std::vector &spherical_harmonics_textures, - const irr::video::SColor &ambient); - - GLuint generateCubeMapFromTextures(const std::vector &skybox_textures); - - +public: + void generateDiffuseCoefficients (irr::video::IVideoDriver *video_driver, + const irr::video::SColor &ambient); public: @@ -54,11 +60,15 @@ public: const std::vector &spherical_harmonics_textures, const irr::video::SColor &ambient); ~Skybox(); + + void render(const irr::scene::ICameraSceneNode *camera) const; + inline const float* getBlueSHCoeff() const {return m_blue_SH_coeff; } inline const float* getGreenSHCoeff() const {return m_green_SH_coeff; } inline const float* getRedSHCoeff() const {return m_red_SH_coeff; } + inline GLuint getSpecularProbe() const {return m_specular_probe; } };