Move skybox things from irr_driver to Skybox class.
This commit is contained in:
parent
94d6d2efd6
commit
cf80dde333
@ -126,7 +126,7 @@ IrrDriver::IrrDriver()
|
|||||||
m_mipviz = m_wireframe = m_normals = m_ssaoviz = false;
|
m_mipviz = m_wireframe = m_normals = m_ssaoviz = false;
|
||||||
m_lightviz = m_shadowviz = m_distortviz = m_rsm = m_rh = m_gi = false;
|
m_lightviz = m_shadowviz = m_distortviz = m_rsm = m_rh = m_gi = false;
|
||||||
m_boundingboxesviz = false;
|
m_boundingboxesviz = false;
|
||||||
SkyboxCubeMap = m_last_light_bucket_distance = 0;
|
m_last_light_bucket_distance = 0;
|
||||||
memset(object_count, 0, sizeof(object_count));
|
memset(object_count, 0, sizeof(object_count));
|
||||||
} // IrrDriver
|
} // IrrDriver
|
||||||
|
|
||||||
@ -1364,19 +1364,19 @@ scene::ISceneNode *IrrDriver::addSkyBox(const std::vector<video::ITexture*> &tex
|
|||||||
const std::vector<video::ITexture*> &sphericalHarmonics)
|
const std::vector<video::ITexture*> &sphericalHarmonics)
|
||||||
{
|
{
|
||||||
assert(texture.size() == 6);
|
assert(texture.size() == 6);
|
||||||
SkyboxTextures = texture;
|
/*SkyboxTextures = texture;
|
||||||
SphericalHarmonicsTextures = sphericalHarmonics;
|
SphericalHarmonicsTextures = sphericalHarmonics;
|
||||||
SkyboxCubeMap = 0;
|
SkyboxCubeMap = 0;
|
||||||
SkyboxSpecularProbe = 0;
|
SkyboxSpecularProbe = 0;*/
|
||||||
|
|
||||||
|
|
||||||
|
//m_skybox_ready = false;
|
||||||
//TODO
|
//TODO
|
||||||
prepareSkybox();
|
//prepareSkybox();
|
||||||
m_skybox_ready = true;
|
//m_skybox_ready = true;
|
||||||
/*m_skybox = new Skybox(m_video_driver,
|
m_skybox = new Skybox(m_video_driver,
|
||||||
texture,
|
texture,
|
||||||
sphericalHarmonics,
|
sphericalHarmonics,
|
||||||
m_scene_manager->getAmbientLight().toSColor());*/
|
m_scene_manager->getAmbientLight().toSColor());
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -1389,7 +1389,8 @@ scene::ISceneNode *IrrDriver::addSkyBox(const std::vector<video::ITexture*> &tex
|
|||||||
|
|
||||||
void IrrDriver::suppressSkyBox()
|
void IrrDriver::suppressSkyBox()
|
||||||
{
|
{
|
||||||
SkyboxTextures.clear();
|
//TODO!
|
||||||
|
/*SkyboxTextures.clear();
|
||||||
SphericalHarmonicsTextures.clear();
|
SphericalHarmonicsTextures.clear();
|
||||||
m_skybox_ready = false;
|
m_skybox_ready = false;
|
||||||
if ((SkyboxCubeMap) && (!ProfileWorld::isNoGraphics()))
|
if ((SkyboxCubeMap) && (!ProfileWorld::isNoGraphics()))
|
||||||
@ -1398,7 +1399,9 @@ void IrrDriver::suppressSkyBox()
|
|||||||
glDeleteTextures(1, &SkyboxSpecularProbe);
|
glDeleteTextures(1, &SkyboxSpecularProbe);
|
||||||
}
|
}
|
||||||
SkyboxCubeMap = 0;
|
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)
|
void IrrDriver::setAmbientLight(const video::SColorf &light)
|
||||||
{
|
{
|
||||||
m_scene_manager->setAmbientLight(light);
|
m_scene_manager->setAmbientLight(light);
|
||||||
m_skybox_ready = false;
|
//TODO!
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//m_skybox_ready = false;
|
||||||
} // setAmbientLight
|
} // setAmbientLight
|
||||||
|
|
||||||
video::SColorf IrrDriver::getAmbientLight() const
|
video::SColorf IrrDriver::getAmbientLight() const
|
||||||
|
@ -215,16 +215,16 @@ private:
|
|||||||
/** Matrixes used in several places stored here to avoid recomputation. */
|
/** Matrixes used in several places stored here to avoid recomputation. */
|
||||||
core::matrix4 m_ViewMatrix, m_InvViewMatrix, m_ProjMatrix, m_InvProjMatrix, m_ProjViewMatrix, m_InvProjViewMatrix;
|
core::matrix4 m_ViewMatrix, m_InvViewMatrix, m_ProjMatrix, m_InvProjMatrix, m_ProjViewMatrix, m_InvProjViewMatrix;
|
||||||
|
|
||||||
std::vector<video::ITexture *> SkyboxTextures;
|
//std::vector<video::ITexture *> SkyboxTextures;
|
||||||
std::vector<video::ITexture *> SphericalHarmonicsTextures;
|
//std::vector<video::ITexture *> SphericalHarmonicsTextures;
|
||||||
bool m_skybox_ready;
|
//bool m_skybox_ready;
|
||||||
|
|
||||||
Skybox *m_skybox;
|
Skybox *m_skybox;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
float blueSHCoeff[9];
|
//float blueSHCoeff[9];
|
||||||
float greenSHCoeff[9];
|
//float greenSHCoeff[9];
|
||||||
float redSHCoeff[9];
|
//float redSHCoeff[9];
|
||||||
private:
|
private:
|
||||||
|
|
||||||
/** Keep a trace of the origin file name of a texture. */
|
/** Keep a trace of the origin file name of a texture. */
|
||||||
@ -241,8 +241,8 @@ private:
|
|||||||
ShadowMatrices *m_shadow_matrices;
|
ShadowMatrices *m_shadow_matrices;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
GLuint SkyboxCubeMap;
|
//GLuint SkyboxCubeMap;
|
||||||
GLuint SkyboxSpecularProbe;
|
//GLuint SkyboxSpecularProbe;
|
||||||
/** A simple class to store video resolutions. */
|
/** A simple class to store video resolutions. */
|
||||||
class VideoMode
|
class VideoMode
|
||||||
{
|
{
|
||||||
@ -535,6 +535,9 @@ public:
|
|||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
inline core::vector3df getWind() {return m_wind->getWind();}
|
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; };
|
const core::vector3df& getSunDirection() const { return m_sun_direction; };
|
||||||
// -----------------------------------------------------------------------
|
// -----------------------------------------------------------------------
|
||||||
void setSunDirection(const core::vector3df &SunPos)
|
void setSunDirection(const core::vector3df &SunPos)
|
||||||
|
@ -186,8 +186,9 @@ void IrrDriver::renderGLSL(float dt)
|
|||||||
|
|
||||||
const core::recti &viewport = camera->getViewport();
|
const core::recti &viewport = camera->getViewport();
|
||||||
|
|
||||||
if (World::getWorld() && World::getWorld()->getTrack()->hasShadows() && !SphericalHarmonicsTextures.empty())
|
//if (World::getWorld() && World::getWorld()->getTrack()->hasShadows() && !SphericalHarmonicsTextures.empty())
|
||||||
irr_driver->getSceneManager()->setAmbientLight(SColor(0, 0, 0, 0));
|
//irr_driver->getSceneManager()->setAmbientLight(SColor(0, 0, 0, 0));
|
||||||
|
//TODO!
|
||||||
|
|
||||||
if (!CVS->isDefferedEnabled())
|
if (!CVS->isDefferedEnabled())
|
||||||
glEnable(GL_FRAMEBUFFER_SRGB);
|
glEnable(GL_FRAMEBUFFER_SRGB);
|
||||||
|
@ -418,9 +418,11 @@ void IrrDriver::uploadLightingData()
|
|||||||
Lighting[6] = m_suncolor.getBlue();
|
Lighting[6] = m_suncolor.getBlue();
|
||||||
Lighting[7] = 0.54f;
|
Lighting[7] = 0.54f;
|
||||||
|
|
||||||
memcpy(&Lighting[8], blueSHCoeff, 9 * sizeof(float));
|
if(m_skybox) {
|
||||||
memcpy(&Lighting[17], greenSHCoeff, 9 * sizeof(float));
|
memcpy(&Lighting[8], m_skybox->getBlueSHCoeff(), 9 * sizeof(float));
|
||||||
memcpy(&Lighting[26], redSHCoeff, 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());
|
glBindBuffer(GL_UNIFORM_BUFFER, SharedGPUObjects::getLightingDataUBO());
|
||||||
glBufferSubData(GL_UNIFORM_BUFFER, 0, 36 * sizeof(float), Lighting);
|
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));
|
ScopedGPUTimer timer(irr_driver->getGPUTimer(Q_ENVMAP));
|
||||||
m_post_processing->renderEnvMap(blueSHCoeff, greenSHCoeff,
|
if(m_skybox) {
|
||||||
redSHCoeff, SkyboxSpecularProbe);
|
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
|
// Render sunlight if and only if track supports shadow
|
||||||
|
@ -25,32 +25,7 @@
|
|||||||
#define MAX2(a, b) ((a) > (b) ? (a) : (b))
|
#define MAX2(a, b) ((a) > (b) ? (a) : (b))
|
||||||
#define MIN2(a, b) ((a) > (b) ? (b) : (a))
|
#define MIN2(a, b) ((a) > (b) ? (b) : (a))
|
||||||
|
|
||||||
class SkyboxShader : public TextureShader<SkyboxShader,1>
|
|
||||||
{
|
|
||||||
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,
|
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]);
|
SHCoeff[4], SHCoeff[5], SHCoeff[6], SHCoeff[7], SHCoeff[8]);
|
||||||
} // displayCoeff
|
} // 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<video::ITexture *> &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)
|
void IrrDriver::renderSkybox(const scene::ICameraSceneNode *camera)
|
||||||
{
|
{
|
||||||
if (SkyboxTextures.empty())
|
if(m_skybox)
|
||||||
return;
|
{
|
||||||
glEnable(GL_DEPTH_TEST);
|
m_skybox->render(camera);
|
||||||
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);
|
|
||||||
} // renderSkybox
|
} // renderSkybox
|
||||||
|
@ -296,10 +296,15 @@ void RTT::prepareRender(scene::ICameraSceneNode* camera)
|
|||||||
irr_driver->setRTT(this);
|
irr_driver->setRTT(this);
|
||||||
irr_driver->getSceneManager()->setActiveCamera(camera);
|
irr_driver->getSceneManager()->setActiveCamera(camera);
|
||||||
|
|
||||||
|
|
||||||
|
//TODO!
|
||||||
if (!m_diffuse_coefficients_calculated)
|
if (!m_diffuse_coefficients_calculated)
|
||||||
{
|
{
|
||||||
irr_driver->generateDiffuseCoefficients();
|
//irr_driver->generateDiffuseCoefficients();
|
||||||
m_diffuse_coefficients_calculated = true;
|
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<IrrDriver::GlowData> glows;
|
std::vector<IrrDriver::GlowData> glows;
|
||||||
// TODO: put this outside of the rendering loop
|
// TODO: put this outside of the rendering loop
|
||||||
//irr_driver->generateDiffuseCoefficients();
|
//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);
|
irr_driver->computeMatrixesAndCameras(camera, m_width, m_height);
|
||||||
unsigned plc = irr_driver->updateLightsInfo(camera, dt);
|
unsigned plc = irr_driver->updateLightsInfo(camera, dt);
|
||||||
irr_driver->uploadLightingData();
|
irr_driver->uploadLightingData();
|
||||||
|
@ -174,13 +174,16 @@ void ShaderBase::bypassUBO() const
|
|||||||
irr_driver->getCurrentScreenSize().Y);
|
irr_driver->getCurrentScreenSize().Y);
|
||||||
|
|
||||||
GLint bLmn = glGetUniformLocation(m_program, "blueLmn[0]");
|
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]");
|
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]");
|
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");
|
GLint sun_dir = glGetUniformLocation(m_program, "sun_direction");
|
||||||
const core::vector3df &sd = irr_driver->getSunDirection();
|
const core::vector3df &sd = irr_driver->getSunDirection();
|
||||||
|
@ -17,15 +17,134 @@
|
|||||||
|
|
||||||
|
|
||||||
#include "graphics/skybox.hpp"
|
#include "graphics/skybox.hpp"
|
||||||
|
#include "graphics/central_settings.hpp"
|
||||||
#include "graphics/IBL.hpp"
|
#include "graphics/IBL.hpp"
|
||||||
|
#include "graphics/shaders.hpp"
|
||||||
|
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <cassert>
|
||||||
|
|
||||||
using namespace irr;
|
using namespace irr;
|
||||||
|
|
||||||
|
|
||||||
|
class SkyboxShader : public TextureShader<SkyboxShader,1>
|
||||||
|
{
|
||||||
|
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,
|
void Skybox::generateDiffuseCoefficients(video::IVideoDriver *video_driver,
|
||||||
const std::vector<video::ITexture *> &spherical_harmonics_textures,
|
|
||||||
const video::SColor &ambient)
|
const video::SColor &ambient)
|
||||||
{
|
{
|
||||||
const unsigned texture_permutation[] = { 2, 3, 0, 1, 5, 4 };
|
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 sh_w = 0, sh_h = 0;
|
||||||
unsigned char *sh_rgba[6];
|
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++)
|
for (unsigned i = 0; i < 6; i++)
|
||||||
{
|
{
|
||||||
sh_w = std::max(sh_w, spherical_harmonics_textures[i]->getSize().Width);
|
sh_w = std::max(sh_w, m_spherical_harmonics_textures[i]->getSize().Width);
|
||||||
sh_h = std::max(sh_h, spherical_harmonics_textures[i]->getSize().Height);
|
sh_h = std::max(sh_h, m_spherical_harmonics_textures[i]->getSize().Height);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (unsigned i = 0; i < 6; i++)
|
for (unsigned i = 0; i < 6; i++)
|
||||||
@ -49,12 +168,12 @@ void Skybox::generateDiffuseCoefficients(video::IVideoDriver *video_driver,
|
|||||||
unsigned idx = texture_permutation[i];
|
unsigned idx = texture_permutation[i];
|
||||||
|
|
||||||
video::IImage* image = video_driver->createImageFromData(
|
video::IImage* image = video_driver->createImageFromData(
|
||||||
spherical_harmonics_textures[idx]->getColorFormat(),
|
m_spherical_harmonics_textures[idx]->getColorFormat(),
|
||||||
spherical_harmonics_textures[idx]->getSize(),
|
m_spherical_harmonics_textures[idx]->getSize(),
|
||||||
spherical_harmonics_textures[idx]->lock(),
|
m_spherical_harmonics_textures[idx]->lock(),
|
||||||
false
|
false
|
||||||
);
|
);
|
||||||
spherical_harmonics_textures[idx]->unlock();
|
m_spherical_harmonics_textures[idx]->unlock();
|
||||||
|
|
||||||
image->copyToScaling(sh_rgba[i], sh_w, sh_h);
|
image->copyToScaling(sh_rgba[i], sh_w, sh_h);
|
||||||
delete image;
|
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);
|
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++)
|
for (unsigned i = 0; i < 6; i++)
|
||||||
{
|
{
|
||||||
@ -101,7 +232,7 @@ void Skybox::generateDiffuseCoefficients(video::IVideoDriver *video_driver,
|
|||||||
delete[] FloatTexCube[i];
|
delete[] FloatTexCube[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (spherical_harmonics_textures.size() != 6)
|
if (m_spherical_harmonics_textures.size() != 6)
|
||||||
{
|
{
|
||||||
// Diffuse env map is x 0.25, compensate
|
// Diffuse env map is x 0.25, compensate
|
||||||
for (unsigned i = 0; i < 9; i++)
|
for (unsigned i = 0; i < 9; i++)
|
||||||
@ -114,14 +245,6 @@ void Skybox::generateDiffuseCoefficients(video::IVideoDriver *video_driver,
|
|||||||
} // generateDiffuseCoefficients
|
} // generateDiffuseCoefficients
|
||||||
|
|
||||||
|
|
||||||
GLuint Skybox::generateCubeMapFromTextures(const std::vector<video::ITexture *> &skybox_textures)
|
|
||||||
{
|
|
||||||
//TODO
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Skybox::Skybox(video::IVideoDriver *video_driver,
|
Skybox::Skybox(video::IVideoDriver *video_driver,
|
||||||
@ -129,14 +252,19 @@ Skybox::Skybox(video::IVideoDriver *video_driver,
|
|||||||
const std::vector<video::ITexture *> &spherical_harmonics_textures,
|
const std::vector<video::ITexture *> &spherical_harmonics_textures,
|
||||||
const video::SColor &ambient)
|
const video::SColor &ambient)
|
||||||
{
|
{
|
||||||
|
m_skybox_textures = skybox_textures;
|
||||||
|
m_spherical_harmonics_textures = spherical_harmonics_textures;
|
||||||
|
|
||||||
glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS);
|
glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS);
|
||||||
|
|
||||||
generateDiffuseCoefficients(video_driver, spherical_harmonics_textures, ambient);
|
generateDiffuseCoefficients(video_driver, ambient);
|
||||||
if (!skybox_textures.empty())
|
if (!skybox_textures.empty())
|
||||||
{
|
{
|
||||||
m_cube_map = generateCubeMapFromTextures(skybox_textures);
|
m_cube_map = generateCubeMapFromTextures(video_driver);
|
||||||
//m_specular_probe = generateSpecularCubemap(m_cube_map);
|
m_specular_probe = generateSpecularCubemap(m_cube_map);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Skybox::~Skybox()
|
Skybox::~Skybox()
|
||||||
@ -144,5 +272,25 @@ Skybox::~Skybox()
|
|||||||
//TODOskybox
|
//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
|
||||||
|
|
||||||
|
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
#define HEADER_SKYBOX_HPP
|
#define HEADER_SKYBOX_HPP
|
||||||
|
|
||||||
#include "graphics/gl_headers.hpp"
|
#include "graphics/gl_headers.hpp"
|
||||||
|
#include <ICameraSceneNode.h>
|
||||||
#include <ITexture.h>
|
#include <ITexture.h>
|
||||||
#include <IVideoDriver.h>
|
#include <IVideoDriver.h>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
@ -27,8 +28,15 @@
|
|||||||
class Skybox
|
class Skybox
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
/** The cube map texture id */
|
/** The 6 skybox textures */
|
||||||
|
std::vector<irr::video::ITexture *> m_skybox_textures;
|
||||||
|
|
||||||
|
/** The skybox texture id */
|
||||||
GLuint m_cube_map;
|
GLuint m_cube_map;
|
||||||
|
|
||||||
|
/** The 6 specular probe textures */
|
||||||
|
std::vector<irr::video::ITexture *> m_spherical_harmonics_textures;
|
||||||
|
|
||||||
/** The specular probe texture id */
|
/** The specular probe texture id */
|
||||||
GLuint m_specular_probe;
|
GLuint m_specular_probe;
|
||||||
|
|
||||||
@ -36,16 +44,14 @@ private:
|
|||||||
float m_blue_SH_coeff[9];
|
float m_blue_SH_coeff[9];
|
||||||
float m_green_SH_coeff[9];
|
float m_green_SH_coeff[9];
|
||||||
float m_red_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,
|
public:
|
||||||
const std::vector<irr::video::ITexture *> &spherical_harmonics_textures,
|
void generateDiffuseCoefficients (irr::video::IVideoDriver *video_driver,
|
||||||
const irr::video::SColor &ambient);
|
const irr::video::SColor &ambient);
|
||||||
|
|
||||||
GLuint generateCubeMapFromTextures(const std::vector<irr::video::ITexture *> &skybox_textures);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@ -54,11 +60,15 @@ public:
|
|||||||
const std::vector<irr::video::ITexture *> &spherical_harmonics_textures,
|
const std::vector<irr::video::ITexture *> &spherical_harmonics_textures,
|
||||||
const irr::video::SColor &ambient);
|
const irr::video::SColor &ambient);
|
||||||
~Skybox();
|
~Skybox();
|
||||||
|
|
||||||
|
void render(const irr::scene::ICameraSceneNode *camera) const;
|
||||||
|
|
||||||
|
|
||||||
inline const float* getBlueSHCoeff() const {return m_blue_SH_coeff; }
|
inline const float* getBlueSHCoeff() const {return m_blue_SH_coeff; }
|
||||||
inline const float* getGreenSHCoeff() const {return m_green_SH_coeff; }
|
inline const float* getGreenSHCoeff() const {return m_green_SH_coeff; }
|
||||||
inline const float* getRedSHCoeff() const {return m_red_SH_coeff; }
|
inline const float* getRedSHCoeff() const {return m_red_SH_coeff; }
|
||||||
|
|
||||||
|
inline GLuint getSpecularProbe() const {return m_specular_probe; }
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user