splitted skybox class in Skybox and SphericalHarmonic classes

This commit is contained in:
Elderme 2015-07-27 22:56:11 +02:00
parent 3640e4a69a
commit 97ed8b2dbf
11 changed files with 254 additions and 170 deletions

View File

@ -122,6 +122,7 @@ IrrDriver::IrrDriver()
m_post_processing = NULL;
m_wind = new Wind();
m_skybox = NULL;
m_spherical_harmonic = NULL;
m_mipviz = m_wireframe = m_normals = m_ssaoviz = false;
m_lightviz = m_shadowviz = m_distortviz = m_rsm = m_rh = m_gi = false;
@ -1373,14 +1374,20 @@ scene::ISceneNode *IrrDriver::addSkyBox(const std::vector<video::ITexture*> &tex
//TODO
//prepareSkybox();
//m_skybox_ready = true;
m_skybox = new Skybox(m_video_driver,
texture,
sphericalHarmonics,
m_scene_manager->getAmbientLight().toSColor());
m_skybox = new Skybox(texture);
if(sphericalHarmonics.size() == 6)
{
if(m_spherical_harmonic != NULL)
{
delete m_spherical_harmonic;
}
m_spherical_harmonic = new SphericalHarmonic(sphericalHarmonics);
}
else
{
m_spherical_harmonic = new SphericalHarmonic(m_scene_manager->getAmbientLight().toSColor());
}
return m_scene_manager->addSkyBoxSceneNode(texture[0], texture[1],
texture[2], texture[3],
@ -1402,6 +1409,8 @@ void IrrDriver::suppressSkyBox()
SkyboxSpecularProbe = 0;*/
delete m_skybox;
m_skybox = NULL;
delete m_spherical_harmonic;
m_spherical_harmonic = NULL;
}
// ----------------------------------------------------------------------------
@ -1783,7 +1792,8 @@ void IrrDriver::setAmbientLight(const video::SColorf &light)
m_scene_manager->setAmbientLight(light);
//TODO!
if(m_spherical_harmonic == NULL)
m_spherical_harmonic = new SphericalHarmonic(light.toSColor());
//m_skybox_ready = false;
} // setAmbientLight

View File

@ -36,9 +36,10 @@
#include <SColor.h>
#include "IrrlichtDevice.h"
#include "ISkinnedMesh.h"
#include "graphics/wind.hpp"
#include "graphics/gl_headers.hpp"
#include "graphics/skybox.hpp"
#include "graphics/sphericalHarmonic.hpp"
#include "graphics/wind.hpp"
#include "io/file_manager.hpp"
#include "utils/aligned_array.hpp"
#include "utils/no_copy.hpp"
@ -220,6 +221,7 @@ private:
//bool m_skybox_ready;
Skybox *m_skybox;
SphericalHarmonic *m_spherical_harmonic;
public:
//float blueSHCoeff[9];
@ -536,7 +538,10 @@ public:
// -----------------------------------------------------------------------
/** Returns a pointer to the skybox. */
inline Skybox *getSkybox() {return m_skybox;}
// -----------------------------------------------------------------------
// -----------------------------------------------------------------------
/** Returns a pointer to spherical harmonic. */
inline SphericalHarmonic *getSphericalHarmonic() {return m_spherical_harmonic;}
// -----------------------------------------------------------------------
const core::vector3df& getSunDirection() const { return m_sun_direction; };
// -----------------------------------------------------------------------
void setSunDirection(const core::vector3df &SunPos)

View File

@ -987,8 +987,7 @@ static void renderBloom(GLuint in)
} // renderBloom
// ----------------------------------------------------------------------------
void PostProcessing::renderEnvMap(const float *bSHCoeff, const float *gSHCoeff,
const float *rSHCoeff, GLuint skybox)
void PostProcessing::renderEnvMap(GLuint skybox)
{
glDisable(GL_DEPTH_TEST);
glEnable(GL_BLEND);

View File

@ -79,8 +79,7 @@ public:
const video::SColorf &col);
void renderSSAO();
void renderEnvMap(const float *bSHCoeff, const float *gSHCoeff,
const float *rSHCoeff, unsigned skycubemap);
void renderEnvMap(unsigned skycubemap);
void renderRHDebug(unsigned SHR, unsigned SHG, unsigned SHB,
const core::matrix4 &rh_matrix,
const core::vector3df &rh_extend);

View File

@ -418,10 +418,10 @@ void IrrDriver::uploadLightingData()
Lighting[6] = m_suncolor.getBlue();
Lighting[7] = 0.54f;
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));
if(m_spherical_harmonic) {
memcpy(&Lighting[8], m_spherical_harmonic->getBlueSHCoeff(), 9 * sizeof(float));
memcpy(&Lighting[17], m_spherical_harmonic->getGreenSHCoeff(), 9 * sizeof(float));
memcpy(&Lighting[26], m_spherical_harmonic->getRedSHCoeff(), 9 * sizeof(float));
}
glBindBuffer(GL_UNIFORM_BUFFER, SharedGPUObjects::getLightingDataUBO());
@ -491,10 +491,7 @@ void IrrDriver::renderLights(unsigned pointlightcount, bool hasShadow)
{
ScopedGPUTimer timer(irr_driver->getGPUTimer(Q_ENVMAP));
if(m_skybox) {
m_post_processing->renderEnvMap(m_skybox->getBlueSHCoeff(),
m_skybox->getGreenSHCoeff(),
m_skybox->getRedSHCoeff(),
m_skybox->getSpecularProbe());
m_post_processing->renderEnvMap(m_skybox->getSpecularProbe());
}
//TODO: move in skybox (or IBL?) class
}

View File

@ -296,16 +296,16 @@ void RTT::prepareRender(scene::ICameraSceneNode* camera)
irr_driver->setRTT(this);
irr_driver->getSceneManager()->setActiveCamera(camera);
m_diffuse_coefficients_calculated = true;
//TODO!
if (!m_diffuse_coefficients_calculated)
/*if (!m_diffuse_coefficients_calculated)
{
//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;
}
}
}*/
}
FrameBuffer* RTT::render(scene::ICameraSceneNode* camera, float dt)
@ -317,8 +317,8 @@ FrameBuffer* RTT::render(scene::ICameraSceneNode* camera, float dt)
std::vector<IrrDriver::GlowData> 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());
//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);

View File

@ -174,15 +174,15 @@ void ShaderBase::bypassUBO() const
irr_driver->getCurrentScreenSize().Y);
GLint bLmn = glGetUniformLocation(m_program, "blueLmn[0]");
const float* blue_SH_coeff = irr_driver->getSkybox()->getBlueSHCoeff();
const float* blue_SH_coeff = irr_driver->getSphericalHarmonic()->getBlueSHCoeff();
glUniform1fv(bLmn, 9, blue_SH_coeff);
GLint gLmn = glGetUniformLocation(m_program, "greenLmn[0]");
const float* green_SH_coeff = irr_driver->getSkybox()->getGreenSHCoeff();
const float* green_SH_coeff = irr_driver->getSphericalHarmonic()->getGreenSHCoeff();
glUniform1fv(gLmn, 9, green_SH_coeff);
GLint rLmn = glGetUniformLocation(m_program, "redLmn[0]");
const float* red_SH_coeff = irr_driver->getSkybox()->getRedSHCoeff();
const float* red_SH_coeff = irr_driver->getSphericalHarmonic()->getRedSHCoeff();
glUniform1fv(rLmn, 9, red_SH_coeff);
GLint sun_dir = glGetUniformLocation(m_program, "sun_direction");

View File

@ -19,6 +19,7 @@
#include "graphics/skybox.hpp"
#include "graphics/central_settings.hpp"
#include "graphics/IBL.hpp"
#include "graphics/irr_driver.hpp"
#include "graphics/shaders.hpp"
@ -56,16 +57,17 @@ public:
}; // 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
namespace {
// ----------------------------------------------------------------------------
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.
@ -78,7 +80,7 @@ Out of legacy the sequence of textures maps to :
- 6th texture maps to GL_TEXTURE_CUBE_MAP_POSITIVE_Z
* \param textures sequence of 6 textures.
*/
GLuint Skybox::generateCubeMapFromTextures(video::IVideoDriver *video_driver)
GLuint Skybox::generateCubeMapFromTextures()
{
assert(m_skybox_textures.size() == 6);
@ -100,7 +102,7 @@ GLuint Skybox::generateCubeMapFromTextures(video::IVideoDriver *video_driver)
{
unsigned idx = texture_permutation[i];
video::IImage* image = video_driver
video::IImage* image = irr_driver->getVideoDriver()
->createImageFromData(m_skybox_textures[idx]->getColorFormat(),
m_skybox_textures[idx]->getSize(),
m_skybox_textures[idx]->lock(), false );
@ -144,123 +146,19 @@ GLuint Skybox::generateCubeMapFromTextures(video::IVideoDriver *video_driver)
} // generateCubeMapFromTextures
void Skybox::generateDiffuseCoefficients(video::IVideoDriver *video_driver,
const video::SColor &ambient)
{
const unsigned texture_permutation[] = { 2, 3, 0, 1, 5, 4 };
unsigned sh_w = 0, sh_h = 0;
unsigned char *sh_rgba[6];
if (m_spherical_harmonics_textures.size() == 6)
{
for (unsigned i = 0; i < 6; i++)
{
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++)
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 = video_driver->createImageFromData(
m_spherical_harmonics_textures[idx]->getColorFormat(),
m_spherical_harmonics_textures[idx]->getSize(),
m_spherical_harmonics_textures[idx]->lock(),
false
);
m_spherical_harmonics_textures[idx]->unlock();
image->copyToScaling(sh_rgba[i], sh_w, sh_h);
delete image;
}
}
else
{
sh_w = 16;
sh_h = 16;
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, 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++)
{
delete[] sh_rgba[i];
delete[] FloatTexCube[i];
}
if (m_spherical_harmonics_textures.size() != 6)
{
// Diffuse env map is x 0.25, compensate
for (unsigned i = 0; i < 9; i++)
{
m_blue_SH_coeff[i] *= 4;
m_green_SH_coeff[i] *= 4;
m_red_SH_coeff[i] *= 4;
}
}
} // generateDiffuseCoefficients
Skybox::Skybox(video::IVideoDriver *video_driver,
const std::vector<video::ITexture *> &skybox_textures,
const std::vector<video::ITexture *> &spherical_harmonics_textures,
const video::SColor &ambient)
Skybox::Skybox(const std::vector<video::ITexture *> &skybox_textures)
{
m_skybox_textures = skybox_textures;
m_spherical_harmonics_textures = spherical_harmonics_textures;
glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS);
generateDiffuseCoefficients(video_driver, ambient);
if (!skybox_textures.empty())
{
m_cube_map = generateCubeMapFromTextures(video_driver);
m_cube_map = generateCubeMapFromTextures();
m_specular_probe = generateSpecularCubemap(m_cube_map);
}

View File

@ -33,41 +33,21 @@ private:
/** The skybox texture id */
GLuint m_cube_map;
/** The 6 specular probe textures */
std::vector<irr::video::ITexture *> m_spherical_harmonics_textures;
/** The specular probe texture id */
GLuint m_specular_probe;
/** The spherical harmonic coefficients */
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);
GLuint generateCubeMapFromTextures ();
public:
void generateDiffuseCoefficients (irr::video::IVideoDriver *video_driver,
const irr::video::SColor &ambient);
public:
Skybox(irr::video::IVideoDriver *video_driver,
const std::vector<irr::video::ITexture *> &skybox_textures,
const std::vector<irr::video::ITexture *> &spherical_harmonics_textures,
const irr::video::SColor &ambient);
Skybox(const std::vector<irr::video::ITexture *> &skybox_textures);
~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; }

View File

@ -0,0 +1,147 @@
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2015 SuperTuxKart-Team
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 3
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "graphics/IBL.hpp"
#include "graphics/irr_driver.hpp"
#include "graphics/sphericalHarmonic.hpp"
#include <algorithm>
#include <cassert>
using namespace irr;
namespace
{
void convertToFloatTexture(unsigned char *sh_rgba[6], unsigned sh_w, unsigned sh_h, Color *float_tex_cube[6]) {
for (unsigned i = 0; i < 6; i++)
{
float_tex_cube[i] = new Color[sh_w * sh_h];
for (unsigned j = 0; j < sh_w * sh_h; j++)
{
float_tex_cube[i][j].Blue = powf(float(0xFF & sh_rgba[i][4 * j]) / 255.f, 2.2f);
float_tex_cube[i][j].Green = powf(float(0xFF & sh_rgba[i][4 * j + 1]) / 255.f, 2.2f);
float_tex_cube[i][j].Red = powf(float(0xFF & sh_rgba[i][4 * j + 2]) / 255.f, 2.2f);
}
}
} //convertToFloatTexture
}
void SphericalHarmonic::printCoeff() {
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]);
}
SphericalHarmonic::SphericalHarmonic(const std::vector<video::ITexture *> &spherical_harmonics_textures)
{
assert(spherical_harmonics_textures.size() == 6);
m_spherical_harmonics_textures = spherical_harmonics_textures;
const unsigned texture_permutation[] = { 2, 3, 0, 1, 5, 4 };
unsigned char *sh_rgba[6];
unsigned sh_w = 0, sh_h = 0;
for (unsigned i = 0; i < 6; i++)
{
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++)
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 = irr_driver->getVideoDriver()->createImageFromData(
m_spherical_harmonics_textures[idx]->getColorFormat(),
m_spherical_harmonics_textures[idx]->getSize(),
m_spherical_harmonics_textures[idx]->lock(),
false
);
m_spherical_harmonics_textures[idx]->unlock();
image->copyToScaling(sh_rgba[i], sh_w, sh_h);
delete image;
} //for (unsigned i = 0; i < 6; i++)
Color *float_tex_cube[6];
convertToFloatTexture(sh_rgba, sh_w, sh_h, float_tex_cube);
generateSphericalHarmonics(float_tex_cube, sh_w, m_blue_SH_coeff, m_green_SH_coeff, m_red_SH_coeff);
for (unsigned i = 0; i < 6; i++)
{
delete[] sh_rgba[i];
delete[] float_tex_cube[i];
}
// Diffuse env map is x 0.25, compensate
for (unsigned i = 0; i < 9; i++)
{
m_blue_SH_coeff[i] *= 4;
m_green_SH_coeff[i] *= 4;
m_red_SH_coeff[i] *= 4;
}
}// SphericalHarmonic(const std::vector<video::ITexture *> &spherical_harmonics_textures)
SphericalHarmonic::SphericalHarmonic(const video::SColor &ambient)
{
unsigned char *sh_rgba[6];
unsigned sh_w = 16;
unsigned sh_h = 16;
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;
}
}
Color *float_tex_cube[6];
convertToFloatTexture(sh_rgba, sh_w, sh_h, float_tex_cube);
generateSphericalHarmonics(float_tex_cube, sh_w, m_blue_SH_coeff, m_green_SH_coeff, m_red_SH_coeff);
for (unsigned i = 0; i < 6; i++)
{
delete[] sh_rgba[i];
delete[] float_tex_cube[i];
}
}// SphericalHarmonic(const video::SColor &ambient)

View File

@ -0,0 +1,49 @@
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2015 SuperTuxKart-Team
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 3
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#ifndef HEADER_SPHERICAL_HARMONIC_HPP
#define HEADER_SPHERICAL_HARMONIC_HPP
#include <ITexture.h>
#include <vector>
class SphericalHarmonic
{
private:
/** The 6 spherical harmonic textures */
std::vector<irr::video::ITexture *> m_spherical_harmonics_textures;
/** The spherical harmonic coefficients */
float m_blue_SH_coeff[9];
float m_green_SH_coeff[9];
float m_red_SH_coeff[9];
/** Print spherical harmonic coefficients (debug) */
void printCoeff();
public:
SphericalHarmonic(const std::vector<irr::video::ITexture *> &spherical_harmonics_textures);
SphericalHarmonic(const irr::video::SColor &ambient);
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; }
};
#endif //HEADER_SPHERICAL_HARMONIC_HPP