Moved m_spherical_harmonics from IrrDriver to ShaderBasedRenderer class

This commit is contained in:
Elderme
2015-12-05 21:43:04 +01:00
parent a4ba78d1fb
commit ba7aa4bc58
10 changed files with 117 additions and 87 deletions

View File

@@ -18,6 +18,7 @@
#ifndef HEADER_ABSTRACT_RENDERER_HPP
#define HEADER_ABSTRACT_RENDERER_HPP
#include "graphics/sphericalHarmonics.hpp"
#include <irrlicht.h>
#include <vector>
@@ -50,8 +51,13 @@ public:
AbstractRenderer();
virtual ~AbstractRenderer(){}
virtual void addSkyBox(const std::vector<irr::video::ITexture*> &texture) {}
virtual void addSkyBox(const std::vector<irr::video::ITexture*> &texture,
const std::vector<irr::video::ITexture*> &spherical_harmonics_textures) {}
virtual void removeSkyBox() {}
virtual const SHCoefficients* getSHCoefficients() const { return NULL; }
virtual void setAmbientLight(const irr::video::SColorf &light,
bool force_SH_computation = true) {}
virtual void addSunLight(const irr::core::vector3df &pos){}

View File

@@ -121,10 +121,8 @@ IrrDriver::IrrDriver()
file_manager->getFileSystem());
m_request_screenshot = false;
m_rtts = NULL;
m_post_processing = NULL;
m_renderer = NULL;
m_wind = new Wind();
m_spherical_harmonics = NULL;
m_mipviz = m_wireframe = m_normals = m_ssaoviz = false;
m_lightviz = m_shadowviz = m_distortviz = m_rsm = m_rh = m_gi = false;
@@ -162,7 +160,6 @@ IrrDriver::~IrrDriver()
Shaders::destroy();
}
delete m_wind;
delete m_spherical_harmonics;
} // ~IrrDriver
// ----------------------------------------------------------------------------
@@ -510,8 +507,6 @@ void IrrDriver::initDevice()
else
m_renderer = new FixedPipelineRenderer();
m_spherical_harmonics = new SphericalHarmonics(m_scene_manager->getAmbientLight().toSColor());
if (UserConfigParams::m_shadows_resolution != 0 &&
(UserConfigParams::m_shadows_resolution < 512 ||
UserConfigParams::m_shadows_resolution > 2048))
@@ -1381,12 +1376,7 @@ scene::ISceneNode *IrrDriver::addSkyBox(const std::vector<video::ITexture*> &tex
{
assert(texture.size() == 6);
m_renderer->addSkyBox(texture);
if(spherical_harmonics_textures.size() == 6)
{
m_spherical_harmonics->setTextures(spherical_harmonics_textures);
}
m_renderer->addSkyBox(texture, spherical_harmonics_textures);
return m_scene_manager->addSkyBoxSceneNode(texture[0], texture[1],
texture[2], texture[3],
@@ -1771,11 +1761,13 @@ void IrrDriver::onUnloadWorld()
// ----------------------------------------------------------------------------
/** Sets the ambient light.
* \param light The colour of the light to set.
* \param force_SH_computation If false, do not recompute spherical harmonics
* coefficient when spherical harmonics textures have been defined
*/
void IrrDriver::setAmbientLight(const video::SColorf &light)
void IrrDriver::setAmbientLight(const video::SColorf &light, bool force_SH_computation)
{
m_scene_manager->setAmbientLight(light);
m_spherical_harmonics->setAmbientLight(light.toSColor());
m_renderer->setAmbientLight(light, force_SH_computation);
} // setAmbientLight
video::SColorf IrrDriver::getAmbientLight() const

View File

@@ -38,7 +38,6 @@
#include "ISkinnedMesh.h"
#include "graphics/abstract_renderer.hpp"
#include "graphics/gl_headers.hpp"
#include "graphics/sphericalHarmonics.hpp"
#include "graphics/wind.hpp"
#include "io/file_manager.hpp"
#include "utils/aligned_array.hpp"
@@ -222,7 +221,6 @@ 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;
SphericalHarmonics *m_spherical_harmonics;
private:
@@ -340,7 +338,8 @@ public:
const std::string& mask_path);
void displayFPS();
bool OnEvent(const irr::SEvent &event);
void setAmbientLight(const video::SColorf &light);
void setAmbientLight(const video::SColorf &light,
bool force_SH_computation = true);
std::string generateSmallerTextures(const std::string& dir);
std::string getSmallerTexture(const std::string& texture);
video::ITexture *getTexture(FileManager::AssetType type,
@@ -509,8 +508,8 @@ public:
inline core::vector3df getWind() {return m_wind->getWind();}
// -----------------------------------------------------------------------
/** Returns a pointer to spherical harmonics. */
inline SphericalHarmonics *getSphericalHarmonics() {return m_spherical_harmonics;}
/** Returns a pointer to the spherical harmonics coefficients. */
inline const SHCoefficients* getSHCoefficients() {return m_renderer->getSHCoefficients();}
// -----------------------------------------------------------------------
const core::vector3df& getSunDirection() const { return m_sun_direction; };
// -----------------------------------------------------------------------

View File

@@ -54,10 +54,12 @@ void IrrDriver::uploadLightingData()
Lighting[6] = m_suncolor.getBlue();
Lighting[7] = 0.54f;
if(m_spherical_harmonics) {
memcpy(&Lighting[8], m_spherical_harmonics->getBlueSHCoeff(), 9 * sizeof(float));
memcpy(&Lighting[17], m_spherical_harmonics->getGreenSHCoeff(), 9 * sizeof(float));
memcpy(&Lighting[26], m_spherical_harmonics->getRedSHCoeff(), 9 * sizeof(float));
const SHCoefficients* sh_coeff = irr_driver->getSHCoefficients();
if(sh_coeff) {
memcpy(&Lighting[8], sh_coeff->blue_SH_coeff, 9 * sizeof(float));
memcpy(&Lighting[17], sh_coeff->green_SH_coeff, 9 * sizeof(float));
memcpy(&Lighting[26], sh_coeff->red_SH_coeff, 9 * sizeof(float));
}
glBindBuffer(GL_UNIFORM_BUFFER, SharedGPUObjects::getLightingDataUBO());

View File

@@ -179,17 +179,16 @@ void ShaderBase::bypassUBO() const
glUniform2f(Screen, irr_driver->getCurrentScreenSize().X,
irr_driver->getCurrentScreenSize().Y);
const SHCoefficients* sh_coeff = irr_driver->getSHCoefficients();
GLint bLmn = glGetUniformLocation(m_program, "blueLmn[0]");
const float* blue_SH_coeff = irr_driver->getSphericalHarmonics()->getBlueSHCoeff();
glUniform1fv(bLmn, 9, blue_SH_coeff);
glUniform1fv(bLmn, 9, sh_coeff->blue_SH_coeff);
GLint gLmn = glGetUniformLocation(m_program, "greenLmn[0]");
const float* green_SH_coeff = irr_driver->getSphericalHarmonics()->getGreenSHCoeff();
glUniform1fv(gLmn, 9, green_SH_coeff);
glUniform1fv(gLmn, 9, sh_coeff->green_SH_coeff);
GLint rLmn = glGetUniformLocation(m_program, "redLmn[0]");
const float* red_SH_coeff = irr_driver->getSphericalHarmonics()->getRedSHCoeff();
glUniform1fv(rLmn, 9, red_SH_coeff);
glUniform1fv(rLmn, 9, sh_coeff->red_SH_coeff);
GLint sun_dir = glGetUniformLocation(m_program, "sun_direction");
const core::vector3df &sd = irr_driver->getSunDirection();

View File

@@ -528,9 +528,9 @@ void ShaderBasedRenderer::renderPostProcessing(Camera * const camera)
ShaderBasedRenderer::ShaderBasedRenderer()
{
m_skybox = NULL;
m_nb_static_glowing = 0;
m_skybox = NULL;
m_spherical_harmonics = new SphericalHarmonics(irr_driver->getAmbientLight().toSColor());
m_nb_static_glowing = 0;
if (CVS->isAZDOEnabled())
m_geometry_passes = new GeometryPasses<MultidrawPolicy>();
@@ -543,12 +543,19 @@ ShaderBasedRenderer::ShaderBasedRenderer()
ShaderBasedRenderer::~ShaderBasedRenderer()
{
delete m_geometry_passes;
delete m_spherical_harmonics;
delete m_skybox;
}
void ShaderBasedRenderer::addSkyBox(const std::vector<video::ITexture*> &texture)
void ShaderBasedRenderer::addSkyBox(const std::vector<video::ITexture*> &texture,
const std::vector<video::ITexture*> &spherical_harmonics_textures)
{
m_skybox = new Skybox(texture);
if(spherical_harmonics_textures.size() == 6)
{
m_spherical_harmonics->setTextures(spherical_harmonics_textures);
}
}
void ShaderBasedRenderer::removeSkyBox()
@@ -557,6 +564,18 @@ void ShaderBasedRenderer::removeSkyBox()
m_skybox = NULL;
}
const SHCoefficients* ShaderBasedRenderer::getSHCoefficients() const
{
return m_spherical_harmonics->getCoefficients();
}
void ShaderBasedRenderer::setAmbientLight(const video::SColorf &light,
bool force_SH_computation)
{
if(!m_spherical_harmonics->has6Textures() || force_SH_computation)
m_spherical_harmonics->setAmbientLight(light.toSColor());
}
void ShaderBasedRenderer::addSunLight(const core::vector3df &pos)
{
m_shadow_matrices.addLight(pos);

View File

@@ -25,14 +25,13 @@
#include "graphics/lighting_passes.hpp"
#include "graphics/shadow_matrices.hpp"
#include "graphics/skybox.hpp"
#include "graphics/sphericalHarmonics.hpp"
class ShaderBasedRenderer: public AbstractRenderer
{
private:
Skybox *m_skybox;
//SphericalHarmonics *m_spherical_harmonics;
SphericalHarmonics *m_spherical_harmonics;
//GLsync m_sync; //TODO
@@ -83,8 +82,12 @@ public:
ShaderBasedRenderer();
~ShaderBasedRenderer();
void addSkyBox(const std::vector<irr::video::ITexture*> &texture) override;
void addSkyBox(const std::vector<irr::video::ITexture*> &texture,
const std::vector<irr::video::ITexture*> &spherical_harmonics_textures) override;
void removeSkyBox() override;
const SHCoefficients* getSHCoefficients() const override;
void setAmbientLight(const irr::video::SColorf &light,
bool force_SH_computation = true) override;
void addSunLight(const irr::core::vector3df &pos) override;

View File

@@ -192,7 +192,8 @@ namespace
} //namespace
// ----------------------------------------------------------------------------
/** Compute m_red_SH_coeff, m_green_SH_coeff and m_blue_SH_coeff from Yml values
/** Compute m_SH_coeff->red_SH_coeff, m_SH_coeff->green_SH_coeff
* and m_SH_coeff->blue_SH_coeff from Yml values
* \param cubemap_face The 6 cubemap faces (float textures)
* \param edge_size Size of the cubemap face
* \param Yml The sphericals harmonics functions values on each texel of the cubemap
@@ -205,9 +206,9 @@ void SphericalHarmonics::projectSH(Color *cubemap_face[6], size_t edge_size,
{
for (unsigned i = 0; i < 9; i++)
{
m_blue_SH_coeff[i] = 0;
m_green_SH_coeff[i] = 0;
m_red_SH_coeff[i] = 0;
m_SH_coeff->blue_SH_coeff[i] = 0;
m_SH_coeff->green_SH_coeff[i] = 0;
m_SH_coeff->red_SH_coeff[i] = 0;
}
float wh = float(edge_size * edge_size);
@@ -272,35 +273,35 @@ void SphericalHarmonics::projectSH(Color *cubemap_face[6], size_t edge_size,
}
}
m_blue_SH_coeff[0] = b0;
m_blue_SH_coeff[1] = b1;
m_blue_SH_coeff[2] = b2;
m_blue_SH_coeff[3] = b3;
m_blue_SH_coeff[4] = b4;
m_blue_SH_coeff[5] = b5;
m_blue_SH_coeff[6] = b6;
m_blue_SH_coeff[7] = b7;
m_blue_SH_coeff[8] = b8;
m_SH_coeff->blue_SH_coeff[0] = b0;
m_SH_coeff->blue_SH_coeff[1] = b1;
m_SH_coeff->blue_SH_coeff[2] = b2;
m_SH_coeff->blue_SH_coeff[3] = b3;
m_SH_coeff->blue_SH_coeff[4] = b4;
m_SH_coeff->blue_SH_coeff[5] = b5;
m_SH_coeff->blue_SH_coeff[6] = b6;
m_SH_coeff->blue_SH_coeff[7] = b7;
m_SH_coeff->blue_SH_coeff[8] = b8;
m_red_SH_coeff[0] = r0;
m_red_SH_coeff[1] = r1;
m_red_SH_coeff[2] = r2;
m_red_SH_coeff[3] = r3;
m_red_SH_coeff[4] = r4;
m_red_SH_coeff[5] = r5;
m_red_SH_coeff[6] = r6;
m_red_SH_coeff[7] = r7;
m_red_SH_coeff[8] = r8;
m_SH_coeff->red_SH_coeff[0] = r0;
m_SH_coeff->red_SH_coeff[1] = r1;
m_SH_coeff->red_SH_coeff[2] = r2;
m_SH_coeff->red_SH_coeff[3] = r3;
m_SH_coeff->red_SH_coeff[4] = r4;
m_SH_coeff->red_SH_coeff[5] = r5;
m_SH_coeff->red_SH_coeff[6] = r6;
m_SH_coeff->red_SH_coeff[7] = r7;
m_SH_coeff->red_SH_coeff[8] = r8;
m_green_SH_coeff[0] = g0;
m_green_SH_coeff[1] = g1;
m_green_SH_coeff[2] = g2;
m_green_SH_coeff[3] = g3;
m_green_SH_coeff[4] = g4;
m_green_SH_coeff[5] = g5;
m_green_SH_coeff[6] = g6;
m_green_SH_coeff[7] = g7;
m_green_SH_coeff[8] = g8;
m_SH_coeff->green_SH_coeff[0] = g0;
m_SH_coeff->green_SH_coeff[1] = g1;
m_SH_coeff->green_SH_coeff[2] = g2;
m_SH_coeff->green_SH_coeff[3] = g3;
m_SH_coeff->green_SH_coeff[4] = g4;
m_SH_coeff->green_SH_coeff[5] = g5;
m_SH_coeff->green_SH_coeff[6] = g6;
m_SH_coeff->green_SH_coeff[7] = g7;
m_SH_coeff->green_SH_coeff[8] = g8;
} // projectSH
// ----------------------------------------------------------------------------
@@ -358,6 +359,7 @@ void SphericalHarmonics::generateSphericalHarmonics(Color *cubemap_face[6], size
// ----------------------------------------------------------------------------
SphericalHarmonics::SphericalHarmonics(const std::vector<video::ITexture *> &spherical_harmonics_textures)
{
m_SH_coeff = new SHCoefficients;
setTextures(spherical_harmonics_textures);
}
@@ -369,9 +371,16 @@ SphericalHarmonics::SphericalHarmonics(const video::SColor &ambient)
{
//make sure m_ambient and ambient are not equal
m_ambient = (ambient==0) ? 1 : 0;
m_SH_coeff = new SHCoefficients;
setAmbientLight(ambient);
}
SphericalHarmonics::~SphericalHarmonics()
{
delete m_SH_coeff;
}
/** Compute spherical harmonics coefficients from 6 textures */
void SphericalHarmonics::setTextures(const std::vector<video::ITexture *> &spherical_harmonics_textures)
{
@@ -459,9 +468,9 @@ void SphericalHarmonics::setAmbientLight(const video::SColor &ambient)
// 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;
m_SH_coeff->blue_SH_coeff[i] *= 4;
m_SH_coeff->green_SH_coeff[i] *= 4;
m_SH_coeff->red_SH_coeff[i] *= 4;
}
} //setAmbientLight
@@ -469,11 +478,11 @@ void SphericalHarmonics::setAmbientLight(const video::SColor &ambient)
/** Print spherical harmonics coefficients (debug) */
void SphericalHarmonics::printCoeff() {
Log::debug("SphericalHarmonics", "Blue_SH:");
displayCoeff(m_blue_SH_coeff);
displayCoeff(m_SH_coeff->blue_SH_coeff);
Log::debug("SphericalHarmonics", "Green_SH:");
displayCoeff(m_green_SH_coeff);
displayCoeff(m_SH_coeff->green_SH_coeff);
Log::debug("SphericalHarmonics", "Red_SH:");
displayCoeff(m_red_SH_coeff);
displayCoeff(m_SH_coeff->red_SH_coeff);
} //printCoeff
// ----------------------------------------------------------------------------
@@ -500,17 +509,17 @@ void SphericalHarmonics::unprojectSH(size_t width, size_t height,
fi = 2 * fi - 1, fj = 2 * fj - 1;
output[face][4 * height * i + 4 * j + 2] =
getTexelValue(i, j, width, height, m_red_SH_coeff, Y00[face],
getTexelValue(i, j, width, height, m_SH_coeff->red_SH_coeff, Y00[face],
Y1minus1[face], Y10[face], Y11[face],
Y2minus2[face], Y2minus1[face], Y20[face],
Y21[face], Y22[face]);
output[face][4 * height * i + 4 * j + 1] =
getTexelValue(i, j, width, height, m_green_SH_coeff, Y00[face],
getTexelValue(i, j, width, height, m_SH_coeff->green_SH_coeff, Y00[face],
Y1minus1[face], Y10[face], Y11[face],
Y2minus2[face], Y2minus1[face], Y20[face],
Y21[face], Y22[face]);
output[face][4 * height * i + 4 * j] =
getTexelValue(i, j, width, height, m_blue_SH_coeff, Y00[face],
getTexelValue(i, j, width, height, m_SH_coeff->blue_SH_coeff, Y00[face],
Y1minus1[face], Y10[face], Y11[face],
Y2minus2[face], Y2minus1[face], Y20[face],
Y21[face], Y22[face]);

View File

@@ -29,6 +29,13 @@ struct Color
float Blue;
};
struct SHCoefficients
{
float blue_SH_coeff[9];
float green_SH_coeff[9];
float red_SH_coeff[9];
};
class SphericalHarmonics
{
@@ -40,10 +47,7 @@ private:
irr::video::SColor m_ambient;
/** The spherical harmonics coefficients */
float m_blue_SH_coeff[9];
float m_green_SH_coeff[9];
float m_red_SH_coeff[9];
SHCoefficients *m_SH_coeff;
void projectSH(Color *cubemap_face[6], size_t edge_size, float *Y00[],
float *Y1minus1[], float *Y10[], float *Y11[],
@@ -55,13 +59,12 @@ private:
public:
SphericalHarmonics(const std::vector<irr::video::ITexture *> &spherical_harmonics_textures);
SphericalHarmonics(const irr::video::SColor &ambient);
~SphericalHarmonics();
void setTextures(const std::vector<irr::video::ITexture *> &spherical_harmonics_textures);
void setAmbientLight(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; }
inline const SHCoefficients* getCoefficients() const { return m_SH_coeff; }
inline bool has6Textures() const {return m_spherical_harmonics_textures.size()==6;}

View File

@@ -1760,9 +1760,7 @@ void Track::loadTrackModel(bool reverse_track, unsigned int mode_id)
// ---- Set ambient color
m_ambient_color = m_default_ambient_color;
irr_driver->getSceneManager()->setAmbientLight(m_ambient_color);
if (m_spherical_harmonics_textures.size() != 6)
irr_driver->getSphericalHarmonics()->setAmbientLight(m_ambient_color);
irr_driver->setAmbientLight(m_ambient_color, false);
// ---- Create sun (non-ambient directional light)
if (m_sun_position.getLengthSQ() < 0.03f)