Turned ShadowMatrices into a stand-alone proper class.

This commit is contained in:
hiker 2015-05-30 11:29:08 +10:00
parent 855c59db09
commit 48235a5d77
8 changed files with 285 additions and 156 deletions

View File

@ -31,6 +31,7 @@
#include "graphics/post_processing.hpp"
#include "graphics/referee.hpp"
#include "graphics/shaders.hpp"
#include "graphics/shadow_matrixes.hpp"
#include "graphics/stkanimatedmesh.hpp"
#include "graphics/stkbillboard.hpp"
#include "graphics/stkmeshscenenode.hpp"
@ -105,6 +106,7 @@ const int MIN_SUPPORTED_WIDTH = 800;
*/
IrrDriver::IrrDriver()
{
m_shadow_matrices = NULL;
m_resolution_changing = RES_CHANGE_NONE;
m_phase = SOLID_NORMAL_AND_DEPTH_PASS;
m_device = createDevice(video::EDT_NULL,
@ -121,10 +123,6 @@ IrrDriver::IrrDriver()
m_mipviz = m_wireframe = m_normals = m_ssaoviz = \
m_lightviz = m_shadowviz = m_distortviz = m_rsm = m_rh = m_gi = m_boundingboxesviz = false;
SkyboxCubeMap = m_last_light_bucket_distance = 0;
m_shadow_camnodes[0] = NULL;
m_shadow_camnodes[1] = NULL;
m_shadow_camnodes[2] = NULL;
m_shadow_camnodes[3] = NULL;
memset(object_count, 0, sizeof(object_count));
} // IrrDriver
@ -152,6 +150,8 @@ IrrDriver::~IrrDriver()
m_device = NULL;
m_modes.clear();
delete m_shadow_matrices;
m_shadow_matrices = NULL;
Shaders::destroy();
delete m_wind;
} // ~IrrDriver
@ -194,6 +194,14 @@ GPUTimer &IrrDriver::getGPUTimer(unsigned i)
return m_perf_query[i];
}
// ----------------------------------------------------------------------------
void IrrDriver::computeMatrixesAndCameras(scene::ICameraSceneNode *const camnode,
size_t width, size_t height)
{
m_current_screen_size = core::vector2df(float(width), float(height));
m_shadow_matrices->computeMatrixesAndCameras(camnode, width, height);
} // computeMatrixesAndCameras
// ----------------------------------------------------------------------------
#if defined(__linux__) && !defined(ANDROID)
@ -519,9 +527,6 @@ void IrrDriver::initDevice()
m_mrt.clear();
m_mrt.reallocate(2);
m_suncam = m_scene_manager->addCameraSceneNode(0, vector3df(0), vector3df(0), -1, false);
m_suncam->grab();
m_suncam->setParent(NULL);
}
else
{
@ -588,6 +593,7 @@ void IrrDriver::initDevice()
// so let's decide ourselves...)
m_device->getCursorControl()->setVisible(true);
m_pointer_shown = true;
m_shadow_matrices = new ShadowMatrices();
} // initDevice
// ----------------------------------------------------------------------------
@ -1701,7 +1707,7 @@ video::ITexture* IrrDriver::applyMask(video::ITexture* texture,
// ----------------------------------------------------------------------------
void IrrDriver::setRTT(RTT* rtt)
{
memset(m_shadow_camnodes, 0, 4 * sizeof(void*));
m_shadow_matrices->resetShadowCamNodes();
m_rtts = rtt;
}
// ----------------------------------------------------------------------------
@ -1710,7 +1716,8 @@ void IrrDriver::onLoadWorld()
if (CVS->isGLSL())
{
const core::recti &viewport = Camera::getCamera(0)->getViewport();
size_t width = viewport.LowerRightCorner.X - viewport.UpperLeftCorner.X, height = viewport.LowerRightCorner.Y - viewport.UpperLeftCorner.Y;
size_t width = viewport.LowerRightCorner.X - viewport.UpperLeftCorner.X;
size_t height = viewport.LowerRightCorner.Y - viewport.UpperLeftCorner.Y;
m_rtts = new RTT(width, height);
}
}
@ -2514,11 +2521,7 @@ scene::ISceneNode *IrrDriver::addLight(const core::vector3df &pos, float energy,
{
//m_sun_interposer->setPosition(pos);
//m_sun_interposer->updateAbsolutePosition();
m_suncam->setPosition(pos);
m_suncam->updateAbsolutePosition();
m_rsm_matrix_initialized = false;
m_shadow_matrices->addLight(pos);
((WaterShaderProvider *) Shaders::getCallback(ES_WATER) )->setSunPosition(pos);
}

View File

@ -62,6 +62,7 @@ class PerCameraNode;
class PostProcessing;
class LightNode;
class ShadowImportance;
class ShadowMatrices;
enum STKRenderingPass
{
@ -200,12 +201,6 @@ private:
Wind *m_wind;
/** RTTs. */
RTT *m_rtts;
std::vector<core::matrix4> sun_ortho_matrix;
core::vector3df rh_extend;
core::matrix4 rh_matrix;
core::matrix4 rsm_matrix;
bool m_rsm_matrix_initialized;
bool m_rsm_map_available;
core::vector2df m_current_screen_size;
core::dimension2du m_actual_screen_size;
@ -240,6 +235,8 @@ private:
enum {RES_CHANGE_NONE, RES_CHANGE_YES,
RES_CHANGE_CANCEL} m_resolution_changing;
ShadowMatrices *m_shadow_matrices;
public:
GLuint SkyboxCubeMap;
GLuint SkyboxSpecularProbe;
@ -298,12 +295,8 @@ private:
unsigned poly_count[PASS_COUNT];
u32 m_renderpass;
class STKMeshSceneNode *m_sun_interposer;
scene::ICameraSceneNode *m_suncam;
core::vector3df m_sun_direction;
video::SColorf m_suncolor;
std::pair<float, float> m_shadow_scales[4];
scene::ICameraSceneNode *m_shadow_camnodes[4];
float m_shadows_cam[4][24];
std::vector<GlowData> m_glowing;
@ -361,10 +354,6 @@ public:
void renderSkybox(const scene::ICameraSceneNode *camera);
void setPhase(STKRenderingPass);
STKRenderingPass getPhase() const;
const std::vector<core::matrix4> &getShadowViewProj() const
{
return sun_ortho_matrix;
}
void IncreaseObjectCount();
void IncreasePolyCount(unsigned);
core::array<video::IRenderTarget> &getMainSetup();
@ -670,6 +659,9 @@ public:
// ------------------------------------------------------------------------
class STKMeshSceneNode *getSunInterposer() { return m_sun_interposer; }
// ------------------------------------------------------------------------
ShadowMatrices *getShadowMatrices() { return m_shadow_matrices; }
// ------------------------------------------------------------------------
void cleanSunInterposer();
void createSunInterposer();
// ------------------------------------------------------------------------

View File

@ -30,6 +30,7 @@
#include "graphics/rtts.hpp"
#include "graphics/screenquad.hpp"
#include "graphics/shaders.hpp"
#include "graphics/shadow_matrixes.hpp"
#include "graphics/stkmeshscenenode.hpp"
#include "items/item_manager.hpp"
#include "modes/world.hpp"
@ -57,36 +58,6 @@ public:
} // InstancedColorizeShader
}; // InstancedColorizeShader
// ============================================================================
class ViewFrustrumShader : public Shader<ViewFrustrumShader, video::SColor, int>
{
private:
GLuint m_frustrum_vao;
public: ViewFrustrumShader()
{
loadProgram(OBJECT, GL_VERTEX_SHADER, "frustrum.vert",
GL_FRAGMENT_SHADER, "coloredquad.frag");
assignUniforms("color", "idx");
glGenVertexArrays(1, &m_frustrum_vao);
glBindVertexArray(m_frustrum_vao);
glBindBuffer(GL_ARRAY_BUFFER, SharedGPUObjects::getFrustrumVBO());
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,
SharedGPUObjects::getFrustrumIndices());
glBindVertexArray(0);
} // ViewFrustrumShader
// ------------------------------------------------------------------------
void bindVertexArray()
{
glBindVertexArray(m_frustrum_vao);
} // bindVertexArray
}; // ViewFrustrumShader
// ============================================================================
extern std::vector<float> BoundingBoxes;
@ -313,7 +284,7 @@ void IrrDriver::renderGLSL(float dt)
}
else if (irr_driver->getShadowViz())
{
renderShadowsDebug();
getShadowMatrices()->renderShadowsDebug();
}
else
{
@ -401,7 +372,7 @@ void IrrDriver::renderScene(scene::ICameraSceneNode * const camnode, unsigned po
// Shadows
{
// To avoid wrong culling, use the largest view possible
m_scene_manager->setActiveCamera(m_suncam);
m_scene_manager->setActiveCamera(getShadowMatrices()->getSunCam());
if (CVS->isDefferedEnabled() &&
CVS->isShadowEnabled() && hasShadow)
{
@ -528,14 +499,17 @@ void IrrDriver::renderScene(scene::ICameraSceneNode * const camnode, unsigned po
m_post_processing->renderRHDebug(m_rtts->getRH().getRTT()[0],
m_rtts->getRH().getRTT()[1],
m_rtts->getRH().getRTT()[2],
rh_matrix, rh_extend);
getShadowMatrices()->getRHMatrix(),
getShadowMatrices()->getRHExtend());
}
if (getGI())
{
glDisable(GL_BLEND);
m_rtts->getFBO(FBO_COLORS).bind();
m_post_processing->renderGI(rh_matrix, rh_extend, m_rtts->getRH());
m_post_processing->renderGI(getShadowMatrices()->getRHMatrix(),
getShadowMatrices()->getRHExtend(),
m_rtts->getRH());
}
PROFILER_PUSH_CPU_MARKER("- Glow", 0xFF, 0xFF, 0x00);
@ -677,36 +651,6 @@ void IrrDriver::renderParticles()
// m_scene_manager->drawAll(scene::ESNRP_TRANSPARENT_EFFECT);
}
static void renderWireFrameFrustrum(float *tmp, unsigned i)
{
ViewFrustrumShader::getInstance()->use();
ViewFrustrumShader::getInstance()->bindVertexArray();
glBindBuffer(GL_ARRAY_BUFFER, SharedGPUObjects::getFrustrumVBO());
glBufferSubData(GL_ARRAY_BUFFER, 0, 8 * 3 * sizeof(float), (void *)tmp);
ViewFrustrumShader::getInstance()->setUniforms(video::SColor(255, 0, 255, 0), i);
glDrawElements(GL_LINES, 24, GL_UNSIGNED_INT, 0);
}
void IrrDriver::renderShadowsDebug()
{
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glViewport(0, UserConfigParams::m_height / 2, UserConfigParams::m_width / 2, UserConfigParams::m_height / 2);
m_post_processing->renderTextureLayer(m_rtts->getShadowFBO().getRTT()[0], 0);
renderWireFrameFrustrum(m_shadows_cam[0], 0);
glViewport(UserConfigParams::m_width / 2, UserConfigParams::m_height / 2, UserConfigParams::m_width / 2, UserConfigParams::m_height / 2);
m_post_processing->renderTextureLayer(m_rtts->getShadowFBO().getRTT()[0], 1);
renderWireFrameFrustrum(m_shadows_cam[1], 1);
glViewport(0, 0, UserConfigParams::m_width / 2, UserConfigParams::m_height / 2);
m_post_processing->renderTextureLayer(m_rtts->getShadowFBO().getRTT()[0], 2);
renderWireFrameFrustrum(m_shadows_cam[2], 2);
glViewport(UserConfigParams::m_width / 2, 0, UserConfigParams::m_width / 2, UserConfigParams::m_height / 2);
m_post_processing->renderTextureLayer(m_rtts->getShadowFBO().getRTT()[0], 3);
renderWireFrameFrustrum(m_shadows_cam[3], 3);
glViewport(0, 0, UserConfigParams::m_width, UserConfigParams::m_height);
}
// ----------------------------------------------------------------------------
void IrrDriver::renderGlow(std::vector<GlowData>& glows)

View File

@ -16,19 +16,20 @@
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "graphics/irr_driver.hpp"
#include "central_settings.hpp"
#include "config/user_config.hpp"
#include "graphics/callbacks.hpp"
#include "graphics/central_settings.hpp"
#include "graphics/glwrap.hpp"
#include "graphics/post_processing.hpp"
#include "graphics/rtts.hpp"
#include "graphics/shaders.hpp"
#include "graphics/shadow_matrixes.hpp"
#include "graphics/stkscenemanager.hpp"
#include "modes/world.hpp"
#include "utils/log.hpp"
#include "utils/profiler.hpp"
#include "utils/tuple.hpp"
#include "stkscenemanager.hpp"
#include "utils/profiler.hpp"
#include <S3DVertex.h>
@ -1815,11 +1816,14 @@ void IrrDriver::renderShadows()
if (CVS->isARBTextureViewUsable())
{
const std::pair<float, float>* shadow_scales
= getShadowMatrices()->getShadowScales();
for (unsigned i = 0; i < 2; i++)
{
m_post_processing->renderGaussian6BlurLayer(m_rtts->getShadowFBO(), i,
2.f * m_shadow_scales[0].first / m_shadow_scales[i].first,
2.f * m_shadow_scales[0].second / m_shadow_scales[i].second);
2.f * shadow_scales[0].first / shadow_scales[i].first,
2.f * shadow_scales[0].second / shadow_scales[i].second);
}
}
glBindTexture(GL_TEXTURE_2D_ARRAY, m_rtts->getShadowFBO().getRTT()[0]);
@ -1920,12 +1924,13 @@ void multidrawRSM(Args...args)
// ----------------------------------------------------------------------------
void IrrDriver::renderRSM()
{
if (m_rsm_map_available)
if (getShadowMatrices()->isRSMMapAvail())
return;
ScopedGPUTimer Timer(getGPUTimer(Q_RSM));
m_rtts->getRSM().bind();
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
const core::matrix4 &rsm_matrix = getShadowMatrices()->getRSMMatrix();
drawRSM<DefaultMaterial, 3, 1>(rsm_matrix);
drawRSM<AlphaRef, 3, 1>(rsm_matrix);
drawRSM<NormalMat, 3, 1>(rsm_matrix);
@ -1953,5 +1958,5 @@ void IrrDriver::renderRSM()
renderRSMShadow<NormalMat>(rsm_matrix);
renderRSMShadow<DetailMat>(rsm_matrix);
}
m_rsm_map_available = true;
getShadowMatrices()->setRSMMapAvail(true);
} // renderRSM

View File

@ -447,8 +447,9 @@ void IrrDriver::renderLights(unsigned pointlightcount, bool hasShadow)
for (unsigned i = 0; i < 32; i++)
{
NVWorkaroundRadianceHintsConstructionShader::getInstance()
->setUniforms(rsm_matrix, rh_matrix,
rh_extend, i,
->setUniforms(getShadowMatrices()->getRSMMatrix(),
getShadowMatrices()->getRHMatrix(),
getShadowMatrices()->getRHExtend(), i,
irr_driver->getSunColor());
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
}
@ -463,14 +464,14 @@ void IrrDriver::renderLights(unsigned pointlightcount, bool hasShadow)
m_rtts->getRSM().getDepthTexture()
);
RadianceHintsConstructionShader::getInstance()
->setUniforms(rsm_matrix, rh_matrix, rh_extend,
->setUniforms(getShadowMatrices()->getRSMMatrix(),
getShadowMatrices()->getRHMatrix(),
getShadowMatrices()->getRHExtend(),
irr_driver->getSunColor());
glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4, 32);
}
}
for (unsigned i = 0; i < sun_ortho_matrix.size(); i++)
sun_ortho_matrix[i] *= getInvViewMatrix();
getShadowMatrices()->updateSunOrthoMatrices();
m_rtts->getFBO(FBO_COMBINED_DIFFUSE_SPECULAR).bind();
glClear(GL_COLOR_BUFFER_BIT);
@ -478,7 +479,9 @@ void IrrDriver::renderLights(unsigned pointlightcount, bool hasShadow)
if (CVS->isGlobalIlluminationEnabled() && hasShadow)
{
ScopedGPUTimer timer(irr_driver->getGPUTimer(Q_GI));
m_post_processing->renderGI(rh_matrix, rh_extend, m_rtts->getRH());
m_post_processing->renderGI(getShadowMatrices()->getRHMatrix(),
getShadowMatrices()->getRHExtend(),
m_rtts->getRH());
}
m_rtts->getFBO(FBO_COMBINED_DIFFUSE_SPECULAR).bind();

View File

@ -18,7 +18,10 @@
#include "graphics/shadow_matrixes.hpp"
#include "graphics/central_settings.hpp"
#include "graphics/glwrap.hpp"
#include "graphics/irr_driver.hpp"
#include "graphics/post_processing.hpp"
#include "graphics/rtts.hpp"
#include "graphics/shaders.hpp"
#include "graphics/shared_gpu_objects.hpp"
#include "modes/world.hpp"
@ -35,8 +38,6 @@
#define MIN2(a, b) ((a) > (b) ? (b) : (a))
float ShadowMatrices::m_shadow_split[5] = { 1., 5., 20., 50., 150 };
// ============================================================================
class LightspaceBoundingBoxShader
: public TextureShader<LightspaceBoundingBoxShader, 1,
@ -78,6 +79,68 @@ public:
}; // ShadowMatricesGenerationShader
float ShadowMatrices:: m_shadow_split[5] = { 1., 5., 20., 50., 150 };
// ============================================================================
class ViewFrustrumShader : public Shader<ViewFrustrumShader, video::SColor, int>
{
private:
GLuint m_frustrum_vao;
public: ViewFrustrumShader()
{
loadProgram(OBJECT, GL_VERTEX_SHADER, "frustrum.vert",
GL_FRAGMENT_SHADER, "coloredquad.frag");
assignUniforms("color", "idx");
glGenVertexArrays(1, &m_frustrum_vao);
glBindVertexArray(m_frustrum_vao);
glBindBuffer(GL_ARRAY_BUFFER, SharedGPUObjects::getFrustrumVBO());
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,
SharedGPUObjects::getFrustrumIndices());
glBindVertexArray(0);
} // ViewFrustrumShader
// ------------------------------------------------------------------------
void bindVertexArray()
{
glBindVertexArray(m_frustrum_vao);
} // bindVertexArray
}; // ViewFrustrumShader
// ============================================================================
ShadowMatrices::ShadowMatrices()
{
m_sun_cam = irr_driver->getSceneManager()
->addCameraSceneNode(0, vector3df(0), vector3df(0), -1, false);
m_sun_cam->grab();
m_sun_cam->setParent(NULL);
m_shadow_cam_nodes[0] = NULL;
m_shadow_cam_nodes[1] = NULL;
m_shadow_cam_nodes[2] = NULL;
m_shadow_cam_nodes[3] = NULL;
} // ShadowMatrices
// ----------------------------------------------------------------------------
void ShadowMatrices::addLight(const core::vector3df &pos)
{
m_sun_cam->setPosition(pos);
m_sun_cam->updateAbsolutePosition();
m_rsm_matrix_initialized = false;
} // addLight
// ----------------------------------------------------------------------------
void ShadowMatrices::updateSunOrthoMatrices()
{
for (unsigned i = 0; i < m_sun_ortho_matrices.size(); i++)
m_sun_ortho_matrices[i] *= irr_driver->getInvViewMatrix();
} // updateSunOrthoMatrices
// ============================================================================
static std::vector<vector3df> getFrustrumVertex(const scene::SViewFrustum &frustrum)
{
@ -101,7 +164,7 @@ static std::vector<vector3df> getFrustrumVertex(const scene::SViewFrustum &frust
* \param pointsInside a vector of point in 3d space.
* \param size returns the size (width, height) of shadowmap coverage
*/
static core::matrix4 getTighestFitOrthoProj(const core::matrix4 &transform,
core::matrix4 ShadowMatrices::getTighestFitOrthoProj(const core::matrix4 &transform,
const std::vector<vector3df> &pointsInside,
std::pair<float, float> &size)
{
@ -154,8 +217,8 @@ static core::matrix4 getTighestFitOrthoProj(const core::matrix4 &transform,
* TODO : The depth histogram part is commented out, needs to tweak it when
* I have some motivation
*/
void IrrDriver::updateSplitAndLightcoordRangeFromComputeShaders(size_t width,
size_t height)
void ShadowMatrices::updateSplitAndLightcoordRangeFromComputeShaders(unsigned int width,
unsigned int height)
{
struct CascadeBoundingBox
{
@ -192,9 +255,9 @@ void IrrDriver::updateSplitAndLightcoordRangeFromComputeShaders(size_t width,
LightspaceBoundingBoxShader::getInstance()->use();
LightspaceBoundingBoxShader::getInstance()
->setTextureUnits(getDepthStencilTexture());
->setTextureUnits(irr_driver->getDepthStencilTexture());
LightspaceBoundingBoxShader::getInstance()
->setUniforms(m_suncam->getViewMatrix(),
->setUniforms(m_sun_cam->getViewMatrix(),
ShadowMatrices::m_shadow_split[1],
ShadowMatrices::m_shadow_split[2],
ShadowMatrices::m_shadow_split[3],
@ -210,7 +273,7 @@ void IrrDriver::updateSplitAndLightcoordRangeFromComputeShaders(size_t width,
ShadowMatricesGenerationShader::getInstance()->use();
ShadowMatricesGenerationShader::getInstance()
->setUniforms(m_suncam->getViewMatrix());
->setUniforms(m_sun_cam->getViewMatrix());
glDispatchCompute(4, 1, 1);
glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT);
@ -229,12 +292,12 @@ void IrrDriver::updateSplitAndLightcoordRangeFromComputeShaders(size_t width,
* \param width of the rendering viewport
* \param height of the rendering viewport
*/
void IrrDriver::computeMatrixesAndCameras(scene::ICameraSceneNode * const camnode,
size_t width, size_t height)
void ShadowMatrices::computeMatrixesAndCameras(scene::ICameraSceneNode *const camnode,
unsigned int width, unsigned int height)
{
if (CVS->isSDSMEnabled())
updateSplitAndLightcoordRangeFromComputeShaders(width, height);
static_cast<scene::CSceneManager *>(m_scene_manager)
static_cast<scene::CSceneManager *>(irr_driver->getSceneManager())
->OnAnimate(os::Timer::getTime());
camnode->render();
irr_driver->setProjMatrix(irr_driver->getVideoDriver()
@ -243,7 +306,6 @@ void IrrDriver::computeMatrixesAndCameras(scene::ICameraSceneNode * const camnod
->getTransform(video::ETS_VIEW));
irr_driver->genProjViewMatrix();
m_current_screen_size = core::vector2df(float(width), float(height));
const float oldfar = camnode->getFarValue();
const float oldnear = camnode->getNearValue();
@ -269,15 +331,15 @@ void IrrDriver::computeMatrixesAndCameras(scene::ICameraSceneNode * const camnod
memcpy(&tmp[48], irr_driver->getInvProjMatrix().pointer(), 16 * sizeof(float));
memcpy(&tmp[64], irr_driver->getProjViewMatrix().pointer(), 16 * sizeof(float));
m_suncam->render();
m_sun_cam->render();
for (unsigned i = 0; i < 4; i++)
{
if (m_shadow_camnodes[i])
delete m_shadow_camnodes[i];
m_shadow_camnodes[i] = (scene::ICameraSceneNode *) m_suncam->clone();
if (m_shadow_cam_nodes[i])
delete m_shadow_cam_nodes[i];
m_shadow_cam_nodes[i] = (scene::ICameraSceneNode *) m_sun_cam->clone();
}
sun_ortho_matrix.clear();
const core::matrix4 &SunCamViewMatrix = m_suncam->getViewMatrix();
m_sun_ortho_matrices.clear();
const core::matrix4 &sun_cam_view_matrix = m_sun_cam->getViewMatrix();
if (World::getWorld() && World::getWorld()->getTrack())
{
@ -330,16 +392,16 @@ void IrrDriver::computeMatrixesAndCameras(scene::ICameraSceneNode * const camnod
memcpy(m_shadows_cam[i], tmp, 24 * sizeof(float));
std::vector<vector3df> vectors = getFrustrumVertex(*frustrum);
tmp_matrix = getTighestFitOrthoProj(SunCamViewMatrix, vectors,
tmp_matrix = getTighestFitOrthoProj(sun_cam_view_matrix, vectors,
m_shadow_scales[i]);
m_shadow_camnodes[i]->setProjectionMatrix(tmp_matrix, true);
m_shadow_camnodes[i]->render();
m_shadow_cam_nodes[i]->setProjectionMatrix(tmp_matrix, true);
m_shadow_cam_nodes[i]->render();
sun_ortho_matrix.push_back(
getVideoDriver()->getTransform(video::ETS_PROJECTION)
* getVideoDriver()->getTransform(video::ETS_VIEW) );
m_sun_ortho_matrices.push_back(
irr_driver->getVideoDriver()->getTransform(video::ETS_PROJECTION)
* irr_driver->getVideoDriver()->getTransform(video::ETS_VIEW) );
}
// Rsm Matrix and camera
@ -347,42 +409,42 @@ void IrrDriver::computeMatrixesAndCameras(scene::ICameraSceneNode * const camnod
{
if (trackbox.MinEdge.X != trackbox.MaxEdge.X &&
trackbox.MinEdge.Y != trackbox.MaxEdge.Y &&
// Cover the case where SunCamViewMatrix is null
SunCamViewMatrix.getScale() != core::vector3df(0., 0., 0.))
// Cover the case where sun_cam_view_matrix is null
sun_cam_view_matrix.getScale() != core::vector3df(0., 0., 0.))
{
SunCamViewMatrix.transformBoxEx(trackbox);
sun_cam_view_matrix.transformBoxEx(trackbox);
core::matrix4 tmp_matrix;
tmp_matrix.buildProjectionMatrixOrthoLH(trackbox.MinEdge.X,
trackbox.MaxEdge.X,
trackbox.MaxEdge.Y,
trackbox.MinEdge.Y,
30, trackbox.MaxEdge.Z);
m_suncam->setProjectionMatrix(tmp_matrix, true);
m_suncam->render();
m_sun_cam->setProjectionMatrix(tmp_matrix, true);
m_sun_cam->render();
}
rsm_matrix = getVideoDriver()->getTransform(video::ETS_PROJECTION)
* getVideoDriver()->getTransform(video::ETS_VIEW);
m_rsm_matrix = irr_driver->getVideoDriver()->getTransform(video::ETS_PROJECTION)
* irr_driver->getVideoDriver()->getTransform(video::ETS_VIEW);
m_rsm_matrix_initialized = true;
m_rsm_map_available = false;
}
rh_extend = core::vector3df(128, 64, 128);
m_rh_extend = core::vector3df(128, 64, 128);
core::vector3df campos = camnode->getAbsolutePosition();
core::vector3df translation(8 * floor(campos.X / 8),
8 * floor(campos.Y / 8),
8 * floor(campos.Z / 8));
rh_matrix.setTranslation(translation);
m_rh_matrix.setTranslation(translation);
assert(sun_ortho_matrix.size() == 4);
assert(m_sun_ortho_matrices.size() == 4);
// reset normal camera
camnode->setNearValue(oldnear);
camnode->setFarValue(oldfar);
camnode->render();
size_t size = irr_driver->getShadowViewProj().size();
size_t size = m_sun_ortho_matrices.size();
for (unsigned i = 0; i < size; i++)
memcpy(&tmp[16 * i + 80],
irr_driver->getShadowViewProj()[i].pointer(),
m_sun_ortho_matrices[i].pointer(),
16 * sizeof(float));
}
@ -400,3 +462,38 @@ void IrrDriver::computeMatrixesAndCameras(scene::ICameraSceneNode * const camnod
glBufferSubData(GL_UNIFORM_BUFFER, 0, (16 * 9 + 2) * sizeof(float),
tmp);
} // computeMatrixesAndCameras
// ----------------------------------------------------------------------------
void ShadowMatrices::renderWireFrameFrustrum(float *tmp, unsigned i)
{
ViewFrustrumShader::getInstance()->use();
ViewFrustrumShader::getInstance()->bindVertexArray();
glBindBuffer(GL_ARRAY_BUFFER, SharedGPUObjects::getFrustrumVBO());
glBufferSubData(GL_ARRAY_BUFFER, 0, 8 * 3 * sizeof(float), (void *)tmp);
ViewFrustrumShader::getInstance()->setUniforms(video::SColor(255, 0, 255, 0), i);
glDrawElements(GL_LINES, 24, GL_UNSIGNED_INT, 0);
}
// ----------------------------------------------------------------------------
void ShadowMatrices::renderShadowsDebug()
{
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glViewport(0, UserConfigParams::m_height / 2,
UserConfigParams::m_width / 2, UserConfigParams::m_height / 2);
PostProcessing *post_processing = irr_driver->getPostProcessing();
RTT *rtt = irr_driver->getRTT();
post_processing->renderTextureLayer(rtt->getShadowFBO().getRTT()[0], 0);
renderWireFrameFrustrum(m_shadows_cam[0], 0);
glViewport(UserConfigParams::m_width / 2, UserConfigParams::m_height / 2,
UserConfigParams::m_width / 2, UserConfigParams::m_height / 2);
post_processing->renderTextureLayer(rtt->getShadowFBO().getRTT()[0], 1);
renderWireFrameFrustrum(m_shadows_cam[1], 1);
glViewport(0, 0, UserConfigParams::m_width / 2, UserConfigParams::m_height / 2);
post_processing->renderTextureLayer(rtt->getShadowFBO().getRTT()[0], 2);
renderWireFrameFrustrum(m_shadows_cam[2], 2);
glViewport(UserConfigParams::m_width / 2, 0, UserConfigParams::m_width / 2,
UserConfigParams::m_height / 2);
post_processing->renderTextureLayer(rtt->getShadowFBO().getRTT()[0], 3);
renderWireFrameFrustrum(m_shadows_cam[3], 3);
glViewport(0, 0, UserConfigParams::m_width, UserConfigParams::m_height);
}

View File

@ -19,10 +19,89 @@
#ifndef HEADER_SHADOW_MATRICES_HPP
#define HEADER_SHADOW_MATRICES_HPP
#include "matrix4.h"
#include "vector3d.h"
#include <tuple>
#include <vector>
namespace irr
{
namespace scene { class ICameraSceneNode; }
}
using namespace irr;
class ShadowMatrices
{
public:
static float m_shadow_split[5];
static float m_shadow_split[5];
private:
std::vector<core::matrix4> m_sun_ortho_matrices;
scene::ICameraSceneNode *m_sun_cam;
scene::ICameraSceneNode *m_shadow_cam_nodes[4];
std::pair<float, float> m_shadow_scales[4];
core::matrix4 m_rsm_matrix;
bool m_rsm_matrix_initialized;
float m_shadows_cam[4][24];
bool m_rsm_map_available;
core::vector3df m_rh_extend;
core::matrix4 m_rh_matrix;
void updateSplitAndLightcoordRangeFromComputeShaders(unsigned int width,
unsigned int height);
core::matrix4 getTighestFitOrthoProj(const core::matrix4 &transform,
const std::vector<core::vector3df> &pointsInside,
std::pair<float, float> &size);
void renderWireFrameFrustrum(float *tmp, unsigned i);
public:
ShadowMatrices();
void computeMatrixesAndCameras(scene::ICameraSceneNode *const camnode,
unsigned int width, unsigned int height);
void addLight(const core::vector3df &pos);
void updateSunOrthoMatrices();
void renderShadowsDebug();
// ------------------------------------------------------------------------
void resetShadowCamNodes()
{
memset(m_shadow_cam_nodes, 0, 4 * sizeof(void*));
} // resetShadowCamNodes
// ------------------------------------------------------------------------
scene::ICameraSceneNode** getShadowCamNodes()
{
return m_shadow_cam_nodes;
} // getShadowCamNodes
// ------------------------------------------------------------------------
scene::ICameraSceneNode* getSunCam() { return m_sun_cam; }
// ------------------------------------------------------------------------
core::matrix4& getRHMatrix() { return m_rh_matrix; }
// ------------------------------------------------------------------------
core::vector3df& getRHExtend() { return m_rh_extend; }
// ------------------------------------------------------------------------
core::matrix4& getRSMMatrix() { return m_rsm_matrix; }
// ------------------------------------------------------------------------
std::vector<core::matrix4>& getSunOrthoMatrices()
{
return m_sun_ortho_matrices;
}
// ------------------------------------------------------------------------
void setRSMMapAvail(bool b) { m_rsm_map_available = b; }
// ------------------------------------------------------------------------
bool isRSMMapAvail() const { return m_rsm_map_available; }
// ------------------------------------------------------------------------
const std::pair<float, float>* getShadowScales() const
{
return m_shadow_scales;
}
// ------------------------------------------------------------------------
// ------------------------------------------------------------------------
}; // class ShadowMatrices

View File

@ -15,26 +15,28 @@
// 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/glwrap.hpp"
#include "graphics/stkscenemanager.hpp"
#include "graphics/stkmesh.hpp"
#include "graphics/irr_driver.hpp"
#include "graphics/callbacks.hpp"
#include "graphics/central_settings.hpp"
#include "stkanimatedmesh.hpp"
#include "stkmeshscenenode.hpp"
#include "utils/ptr_vector.hpp"
#include <ICameraSceneNode.h>
#include <SViewFrustum.h>
#include "callbacks.hpp"
#include "utils/cpp2011.hpp"
#include "graphics/glwrap.hpp"
#include "graphics/irr_driver.hpp"
#include "graphics/lod_node.hpp"
#include "graphics/shadow_matrixes.hpp"
#include "graphics/stkanimatedmesh.hpp"
#include "graphics/stkmesh.hpp"
#include "graphics/stkmeshscenenode.hpp"
#include "modes/world.hpp"
#include "tracks/track.hpp"
#include "lod_node.hpp"
#include "utils/cpp2011.hpp"
#include "utils/profiler.hpp"
#include "utils/ptr_vector.hpp"
#include "utils/time.hpp"
#include <ICameraSceneNode.h>
#include <ISceneManager.h>
#include <ISceneNode.h>
#include <SViewFrustum.h>
#include <unordered_map>
#include <SViewFrustum.h>
@ -601,7 +603,11 @@ PROFILER_PUSH_CPU_MARKER("- culling", 0xFF, 0xFF, 0x0);
bool cam = false, rsmcam = false;
bool shadowcam[4] = { false, false, false, false };
parseSceneManager(List, ImmediateDrawList::getInstance(), camnode, m_shadow_camnodes, m_suncam, cam, shadowcam, rsmcam, !m_rsm_map_available);
parseSceneManager(List, ImmediateDrawList::getInstance(), camnode,
getShadowMatrices()->getShadowCamNodes(),
getShadowMatrices()->getSunCam(), cam,
shadowcam, rsmcam,
!getShadowMatrices()->isRSMMapAvail());
PROFILER_POP_CPU_MARKER();
// Add a 1 s timeout
@ -809,7 +815,7 @@ PROFILER_POP_CPU_MARKER();
}
}
#pragma omp section
if (!m_rsm_map_available)
if (!getShadowMatrices()->isRSMMapAvail())
{
size_t offset = 0, current_cmd = 0;
if (!CVS->supportsAsyncInstanceUpload())