|
|
|
@ -299,12 +299,8 @@ void IrrDriver::renderGLSL(float dt)
|
|
|
|
|
glDisable(GL_FRAMEBUFFER_SRGB);
|
|
|
|
|
PROFILER_POP_CPU_MARKER();
|
|
|
|
|
|
|
|
|
|
GLuint perf_query_res[Q_LAST];
|
|
|
|
|
for (unsigned i = 0; i < Q_LAST; i++)
|
|
|
|
|
{
|
|
|
|
|
gl_driver->extGlGetQueryObjectuiv(m_perf_query[i], GL_QUERY_RESULT, &perf_query_res[i]);
|
|
|
|
|
Log::info("GPU Perf", "Phase %d : %d us\n", i, perf_query_res[i] / 1000);
|
|
|
|
|
}
|
|
|
|
|
Log::info("GPU Perf", "Phase %d : %d us\n", i, getGPUTimer(i).elapsedTimeus());
|
|
|
|
|
|
|
|
|
|
glBindVertexArray(0);
|
|
|
|
|
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
|
|
|
@ -444,30 +440,29 @@ void IrrDriver::renderSolidFirstPass()
|
|
|
|
|
GroupedFPSM<FPSM_DEFAULT>::reset();
|
|
|
|
|
GroupedFPSM<FPSM_ALPHA_REF_TEXTURE>::reset();
|
|
|
|
|
GroupedFPSM<FPSM_NORMAL_MAP>::reset();
|
|
|
|
|
|
|
|
|
|
irr::video::COpenGLDriver* gl_driver = (irr::video::COpenGLDriver*)m_device->getVideoDriver();
|
|
|
|
|
gl_driver->extGlBeginQuery(GL_TIME_ELAPSED, m_perf_query[Q_SOLID_PASS1]);
|
|
|
|
|
m_scene_manager->drawAll(scene::ESNRP_SOLID);
|
|
|
|
|
|
|
|
|
|
if (!UserConfigParams::m_dynamic_lights)
|
|
|
|
|
return;
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
glUseProgram(MeshShader::ObjectPass1Shader::Program);
|
|
|
|
|
for (unsigned i = 0; i < GroupedFPSM<FPSM_DEFAULT>::MeshSet.size(); ++i)
|
|
|
|
|
{
|
|
|
|
|
drawObjectPass1(*GroupedFPSM<FPSM_DEFAULT>::MeshSet[i], GroupedFPSM<FPSM_DEFAULT>::MVPSet[i], GroupedFPSM<FPSM_DEFAULT>::TIMVSet[i]);
|
|
|
|
|
ScopedGPUTimer Timer(getGPUTimer(Q_SOLID_PASS1));
|
|
|
|
|
glUseProgram(MeshShader::ObjectPass1Shader::Program);
|
|
|
|
|
for (unsigned i = 0; i < GroupedFPSM<FPSM_DEFAULT>::MeshSet.size(); ++i)
|
|
|
|
|
{
|
|
|
|
|
drawObjectPass1(*GroupedFPSM<FPSM_DEFAULT>::MeshSet[i], GroupedFPSM<FPSM_DEFAULT>::MVPSet[i], GroupedFPSM<FPSM_DEFAULT>::TIMVSet[i]);
|
|
|
|
|
}
|
|
|
|
|
glUseProgram(MeshShader::ObjectRefPass1Shader::Program);
|
|
|
|
|
for (unsigned i = 0; i < GroupedFPSM<FPSM_ALPHA_REF_TEXTURE>::MeshSet.size(); ++i)
|
|
|
|
|
{
|
|
|
|
|
drawObjectRefPass1(*GroupedFPSM<FPSM_ALPHA_REF_TEXTURE>::MeshSet[i], GroupedFPSM<FPSM_ALPHA_REF_TEXTURE>::MVPSet[i], GroupedFPSM<FPSM_ALPHA_REF_TEXTURE>::TIMVSet[i], GroupedFPSM<FPSM_ALPHA_REF_TEXTURE>::MeshSet[i]->TextureMatrix);
|
|
|
|
|
}
|
|
|
|
|
glUseProgram(MeshShader::NormalMapShader::Program);
|
|
|
|
|
for (unsigned i = 0; i < GroupedFPSM<FPSM_NORMAL_MAP>::MeshSet.size(); ++i)
|
|
|
|
|
{
|
|
|
|
|
drawNormalPass(*GroupedFPSM<FPSM_NORMAL_MAP>::MeshSet[i], GroupedFPSM<FPSM_NORMAL_MAP>::MVPSet[i], GroupedFPSM<FPSM_NORMAL_MAP>::TIMVSet[i]);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
glUseProgram(MeshShader::ObjectRefPass1Shader::Program);
|
|
|
|
|
for (unsigned i = 0; i < GroupedFPSM<FPSM_ALPHA_REF_TEXTURE>::MeshSet.size(); ++i)
|
|
|
|
|
{
|
|
|
|
|
drawObjectRefPass1(*GroupedFPSM<FPSM_ALPHA_REF_TEXTURE>::MeshSet[i], GroupedFPSM<FPSM_ALPHA_REF_TEXTURE>::MVPSet[i], GroupedFPSM<FPSM_ALPHA_REF_TEXTURE>::TIMVSet[i], GroupedFPSM<FPSM_ALPHA_REF_TEXTURE>::MeshSet[i]->TextureMatrix);
|
|
|
|
|
}
|
|
|
|
|
glUseProgram(MeshShader::NormalMapShader::Program);
|
|
|
|
|
for (unsigned i = 0; i < GroupedFPSM<FPSM_NORMAL_MAP>::MeshSet.size(); ++i)
|
|
|
|
|
{
|
|
|
|
|
drawNormalPass(*GroupedFPSM<FPSM_NORMAL_MAP>::MeshSet[i], GroupedFPSM<FPSM_NORMAL_MAP>::MVPSet[i], GroupedFPSM<FPSM_NORMAL_MAP>::TIMVSet[i]);
|
|
|
|
|
}
|
|
|
|
|
gl_driver->extGlEndQuery(GL_TIME_ELAPSED);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void IrrDriver::renderSolidSecondPass()
|
|
|
|
@ -500,42 +495,43 @@ void IrrDriver::renderSolidSecondPass()
|
|
|
|
|
setTexture(0, m_rtts->getRenderTarget(RTT_TMP1), GL_NEAREST, GL_NEAREST);
|
|
|
|
|
setTexture(1, m_rtts->getRenderTarget(RTT_TMP2), GL_NEAREST, GL_NEAREST);
|
|
|
|
|
setTexture(2, m_rtts->getRenderTarget(RTT_SSAO), GL_NEAREST, GL_NEAREST);
|
|
|
|
|
irr::video::COpenGLDriver* gl_driver = (irr::video::COpenGLDriver*)m_device->getVideoDriver();
|
|
|
|
|
gl_driver->extGlBeginQuery(GL_TIME_ELAPSED, m_perf_query[Q_SOLID_PASS2]);
|
|
|
|
|
m_scene_manager->drawAll(scene::ESNRP_SOLID);
|
|
|
|
|
|
|
|
|
|
glUseProgram(MeshShader::ObjectPass2Shader::Program);
|
|
|
|
|
for (unsigned i = 0; i < GroupedSM<SM_DEFAULT>::MeshSet.size(); i++)
|
|
|
|
|
drawObjectPass2(*GroupedSM<SM_DEFAULT>::MeshSet[i], GroupedSM<SM_DEFAULT>::MVPSet[i], GroupedSM<SM_DEFAULT>::MeshSet[i]->TextureMatrix);
|
|
|
|
|
{
|
|
|
|
|
ScopedGPUTimer Timer(getGPUTimer(Q_SOLID_PASS2));
|
|
|
|
|
m_scene_manager->drawAll(scene::ESNRP_SOLID);
|
|
|
|
|
|
|
|
|
|
glUseProgram(MeshShader::ObjectRefPass2Shader::Program);
|
|
|
|
|
for (unsigned i = 0; i < GroupedSM<SM_ALPHA_REF_TEXTURE>::MeshSet.size(); i++)
|
|
|
|
|
drawObjectRefPass2(*GroupedSM<SM_ALPHA_REF_TEXTURE>::MeshSet[i], GroupedSM<SM_ALPHA_REF_TEXTURE>::MVPSet[i], GroupedSM<SM_ALPHA_REF_TEXTURE>::MeshSet[i]->TextureMatrix);
|
|
|
|
|
glUseProgram(MeshShader::ObjectPass2Shader::Program);
|
|
|
|
|
for (unsigned i = 0; i < GroupedSM<SM_DEFAULT>::MeshSet.size(); i++)
|
|
|
|
|
drawObjectPass2(*GroupedSM<SM_DEFAULT>::MeshSet[i], GroupedSM<SM_DEFAULT>::MVPSet[i], GroupedSM<SM_DEFAULT>::MeshSet[i]->TextureMatrix);
|
|
|
|
|
|
|
|
|
|
glUseProgram(MeshShader::ObjectRimLimitShader::Program);
|
|
|
|
|
for (unsigned i = 0; i < GroupedSM<SM_RIMLIT>::MeshSet.size(); i++)
|
|
|
|
|
drawObjectRimLimit(*GroupedSM<SM_RIMLIT>::MeshSet[i], GroupedSM<SM_RIMLIT>::MVPSet[i], GroupedSM<SM_RIMLIT>::TIMVSet[i], GroupedSM<SM_RIMLIT>::MeshSet[i]->TextureMatrix);
|
|
|
|
|
glUseProgram(MeshShader::ObjectRefPass2Shader::Program);
|
|
|
|
|
for (unsigned i = 0; i < GroupedSM<SM_ALPHA_REF_TEXTURE>::MeshSet.size(); i++)
|
|
|
|
|
drawObjectRefPass2(*GroupedSM<SM_ALPHA_REF_TEXTURE>::MeshSet[i], GroupedSM<SM_ALPHA_REF_TEXTURE>::MVPSet[i], GroupedSM<SM_ALPHA_REF_TEXTURE>::MeshSet[i]->TextureMatrix);
|
|
|
|
|
|
|
|
|
|
glUseProgram(MeshShader::SphereMapShader::Program);
|
|
|
|
|
for (unsigned i = 0; i < GroupedSM<SM_SPHEREMAP>::MeshSet.size(); i++)
|
|
|
|
|
drawSphereMap(*GroupedSM<SM_SPHEREMAP>::MeshSet[i], GroupedSM<SM_SPHEREMAP>::MVPSet[i], GroupedSM<SM_SPHEREMAP>::TIMVSet[i]);
|
|
|
|
|
glUseProgram(MeshShader::ObjectRimLimitShader::Program);
|
|
|
|
|
for (unsigned i = 0; i < GroupedSM<SM_RIMLIT>::MeshSet.size(); i++)
|
|
|
|
|
drawObjectRimLimit(*GroupedSM<SM_RIMLIT>::MeshSet[i], GroupedSM<SM_RIMLIT>::MVPSet[i], GroupedSM<SM_RIMLIT>::TIMVSet[i], GroupedSM<SM_RIMLIT>::MeshSet[i]->TextureMatrix);
|
|
|
|
|
|
|
|
|
|
glUseProgram(MeshShader::SplattingShader::Program);
|
|
|
|
|
for (unsigned i = 0; i < GroupedSM<SM_SPLATTING>::MeshSet.size(); i++)
|
|
|
|
|
drawSplatting(*GroupedSM<SM_SPLATTING>::MeshSet[i], GroupedSM<SM_SPLATTING>::MVPSet[i]);
|
|
|
|
|
glUseProgram(MeshShader::SphereMapShader::Program);
|
|
|
|
|
for (unsigned i = 0; i < GroupedSM<SM_SPHEREMAP>::MeshSet.size(); i++)
|
|
|
|
|
drawSphereMap(*GroupedSM<SM_SPHEREMAP>::MeshSet[i], GroupedSM<SM_SPHEREMAP>::MVPSet[i], GroupedSM<SM_SPHEREMAP>::TIMVSet[i]);
|
|
|
|
|
|
|
|
|
|
glUseProgram(MeshShader::ObjectUnlitShader::Program);
|
|
|
|
|
for (unsigned i = 0; i < GroupedSM<SM_UNLIT>::MeshSet.size(); i++)
|
|
|
|
|
drawObjectUnlit(*GroupedSM<SM_UNLIT>::MeshSet[i], GroupedSM<SM_UNLIT>::MVPSet[i]);
|
|
|
|
|
glUseProgram(MeshShader::SplattingShader::Program);
|
|
|
|
|
for (unsigned i = 0; i < GroupedSM<SM_SPLATTING>::MeshSet.size(); i++)
|
|
|
|
|
drawSplatting(*GroupedSM<SM_SPLATTING>::MeshSet[i], GroupedSM<SM_SPLATTING>::MVPSet[i]);
|
|
|
|
|
|
|
|
|
|
glUseProgram(MeshShader::DetailledObjectPass2Shader::Program);
|
|
|
|
|
for (unsigned i = 0; i < GroupedSM<SM_DETAILS>::MeshSet.size(); i++)
|
|
|
|
|
drawDetailledObjectPass2(*GroupedSM<SM_DETAILS>::MeshSet[i], GroupedSM<SM_DETAILS>::MVPSet[i]);
|
|
|
|
|
glUseProgram(MeshShader::ObjectUnlitShader::Program);
|
|
|
|
|
for (unsigned i = 0; i < GroupedSM<SM_UNLIT>::MeshSet.size(); i++)
|
|
|
|
|
drawObjectUnlit(*GroupedSM<SM_UNLIT>::MeshSet[i], GroupedSM<SM_UNLIT>::MVPSet[i]);
|
|
|
|
|
|
|
|
|
|
glUseProgram(MeshShader::UntexturedObjectShader::Program);
|
|
|
|
|
for (unsigned i = 0; i < GroupedSM<SM_UNTEXTURED>::MeshSet.size(); i++)
|
|
|
|
|
drawUntexturedObject(*GroupedSM<SM_UNTEXTURED>::MeshSet[i], GroupedSM<SM_UNTEXTURED>::MVPSet[i]);
|
|
|
|
|
gl_driver->extGlEndQuery(GL_TIME_ELAPSED);
|
|
|
|
|
glUseProgram(MeshShader::DetailledObjectPass2Shader::Program);
|
|
|
|
|
for (unsigned i = 0; i < GroupedSM<SM_DETAILS>::MeshSet.size(); i++)
|
|
|
|
|
drawDetailledObjectPass2(*GroupedSM<SM_DETAILS>::MeshSet[i], GroupedSM<SM_DETAILS>::MVPSet[i]);
|
|
|
|
|
|
|
|
|
|
glUseProgram(MeshShader::UntexturedObjectShader::Program);
|
|
|
|
|
for (unsigned i = 0; i < GroupedSM<SM_UNTEXTURED>::MeshSet.size(); i++)
|
|
|
|
|
drawUntexturedObject(*GroupedSM<SM_UNTEXTURED>::MeshSet[i], GroupedSM<SM_UNTEXTURED>::MVPSet[i]);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void IrrDriver::renderTransparent()
|
|
|
|
@ -684,10 +680,10 @@ void IrrDriver::renderShadows(//ShadowImportanceProvider * const sicb,
|
|
|
|
|
glDrawBuffer(GL_NONE);
|
|
|
|
|
|
|
|
|
|
glBindBufferBase(GL_UNIFORM_BUFFER, 0, SharedObject::ViewProjectionMatrixesUBO);
|
|
|
|
|
irr::video::COpenGLDriver* gl_driver = (irr::video::COpenGLDriver*)m_device->getVideoDriver();
|
|
|
|
|
gl_driver->extGlBeginQuery(GL_TIME_ELAPSED, m_perf_query[Q_SHADOWS]);
|
|
|
|
|
m_scene_manager->drawAll(scene::ESNRP_SOLID);
|
|
|
|
|
gl_driver->extGlEndQuery(GL_TIME_ELAPSED);
|
|
|
|
|
{
|
|
|
|
|
ScopedGPUTimer Timer(getGPUTimer(Q_SHADOWS));
|
|
|
|
|
m_scene_manager->drawAll(scene::ESNRP_SOLID);
|
|
|
|
|
}
|
|
|
|
|
glDisable(GL_POLYGON_OFFSET_FILL);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -907,72 +903,74 @@ void IrrDriver::renderLights(const core::aabbox3df& cambox,
|
|
|
|
|
const core::vector3df &campos =
|
|
|
|
|
irr_driver->getSceneManager()->getActiveCamera()->getAbsolutePosition();
|
|
|
|
|
|
|
|
|
|
gl_driver->extGlBeginQuery(GL_TIME_ELAPSED, m_perf_query[Q_LIGHT]);
|
|
|
|
|
std::vector<LightNode *> BucketedLN[15];
|
|
|
|
|
for (unsigned int i = 0; i < lightcount; i++)
|
|
|
|
|
{
|
|
|
|
|
if (!m_lights[i]->isPointLight())
|
|
|
|
|
ScopedGPUTimer Timer(getGPUTimer(Q_LIGHT));
|
|
|
|
|
std::vector<LightNode *> BucketedLN[15];
|
|
|
|
|
for (unsigned int i = 0; i < lightcount; i++)
|
|
|
|
|
{
|
|
|
|
|
m_lights[i]->render();
|
|
|
|
|
if (UserConfigParams::m_shadows && World::getWorld()->getTrack()->hasShadows())
|
|
|
|
|
m_post_processing->renderShadowedSunlight(sun_ortho_matrix, m_rtts->getShadowDepthTex());
|
|
|
|
|
else
|
|
|
|
|
m_post_processing->renderSunlight();
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
const core::vector3df &lightpos = (m_lights[i]->getAbsolutePosition() - campos);
|
|
|
|
|
unsigned idx = (unsigned)(lightpos.getLength() / 10);
|
|
|
|
|
if (idx > 14)
|
|
|
|
|
idx = 14;
|
|
|
|
|
BucketedLN[idx].push_back(m_lights[i]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
unsigned lightnum = 0;
|
|
|
|
|
|
|
|
|
|
for (unsigned i = 0; i < 15; i++)
|
|
|
|
|
{
|
|
|
|
|
for (unsigned j = 0; j < BucketedLN[i].size(); j++)
|
|
|
|
|
{
|
|
|
|
|
if (++lightnum >= MAXLIGHT)
|
|
|
|
|
if (!m_lights[i]->isPointLight())
|
|
|
|
|
{
|
|
|
|
|
LightNode* light_node = BucketedLN[i].at(j);
|
|
|
|
|
light_node->setEnergyMultiplier(0.0f);
|
|
|
|
|
m_lights[i]->render();
|
|
|
|
|
if (UserConfigParams::m_shadows && World::getWorld()->getTrack()->hasShadows())
|
|
|
|
|
m_post_processing->renderShadowedSunlight(sun_ortho_matrix, m_rtts->getShadowDepthTex());
|
|
|
|
|
else
|
|
|
|
|
m_post_processing->renderSunlight();
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
LightNode* light_node = BucketedLN[i].at(j);
|
|
|
|
|
const core::vector3df &lightpos = (m_lights[i]->getAbsolutePosition() - campos);
|
|
|
|
|
unsigned idx = (unsigned)(lightpos.getLength() / 10);
|
|
|
|
|
if (idx > 14)
|
|
|
|
|
idx = 14;
|
|
|
|
|
BucketedLN[idx].push_back(m_lights[i]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
float em = light_node->getEnergyMultiplier();
|
|
|
|
|
if (em < 1.0f)
|
|
|
|
|
unsigned lightnum = 0;
|
|
|
|
|
|
|
|
|
|
for (unsigned i = 0; i < 15; i++)
|
|
|
|
|
{
|
|
|
|
|
for (unsigned j = 0; j < BucketedLN[i].size(); j++)
|
|
|
|
|
{
|
|
|
|
|
if (++lightnum >= MAXLIGHT)
|
|
|
|
|
{
|
|
|
|
|
light_node->setEnergyMultiplier(std::min(1.0f, em + dt));
|
|
|
|
|
LightNode* light_node = BucketedLN[i].at(j);
|
|
|
|
|
light_node->setEnergyMultiplier(0.0f);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
LightNode* light_node = BucketedLN[i].at(j);
|
|
|
|
|
|
|
|
|
|
const core::vector3df &pos = light_node->getAbsolutePosition();
|
|
|
|
|
PointLightsInfo[lightnum].posX = pos.X;
|
|
|
|
|
PointLightsInfo[lightnum].posY = pos.Y;
|
|
|
|
|
PointLightsInfo[lightnum].posZ = pos.Z;
|
|
|
|
|
float em = light_node->getEnergyMultiplier();
|
|
|
|
|
if (em < 1.0f)
|
|
|
|
|
{
|
|
|
|
|
light_node->setEnergyMultiplier(std::min(1.0f, em + dt));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
PointLightsInfo[lightnum].energy = light_node->getEffectiveEnergy();
|
|
|
|
|
const core::vector3df &pos = light_node->getAbsolutePosition();
|
|
|
|
|
PointLightsInfo[lightnum].posX = pos.X;
|
|
|
|
|
PointLightsInfo[lightnum].posY = pos.Y;
|
|
|
|
|
PointLightsInfo[lightnum].posZ = pos.Z;
|
|
|
|
|
|
|
|
|
|
const core::vector3df &col = light_node->getColor();
|
|
|
|
|
PointLightsInfo[lightnum].red = col.X;
|
|
|
|
|
PointLightsInfo[lightnum].green = col.Y;
|
|
|
|
|
PointLightsInfo[lightnum].blue = col.Z;
|
|
|
|
|
PointLightsInfo[lightnum].energy = light_node->getEffectiveEnergy();
|
|
|
|
|
|
|
|
|
|
const core::vector3df &col = light_node->getColor();
|
|
|
|
|
PointLightsInfo[lightnum].red = col.X;
|
|
|
|
|
PointLightsInfo[lightnum].green = col.Y;
|
|
|
|
|
PointLightsInfo[lightnum].blue = col.Z;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (lightnum > MAXLIGHT)
|
|
|
|
|
{
|
|
|
|
|
irr_driver->setLastLightBucketDistance(i * 10);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (lightnum > MAXLIGHT)
|
|
|
|
|
{
|
|
|
|
|
irr_driver->setLastLightBucketDistance(i * 10);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
lightnum++;
|
|
|
|
|
|
|
|
|
|
renderPointLights(MIN2(lightnum, MAXLIGHT));
|
|
|
|
|
if (SkyboxCubeMap)
|
|
|
|
|
m_post_processing->renderDiffuseEnvMap(blueSHCoeff, greenSHCoeff, redSHCoeff);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
lightnum++;
|
|
|
|
|
|
|
|
|
|
renderPointLights(MIN2(lightnum, MAXLIGHT));
|
|
|
|
|
if (SkyboxCubeMap)
|
|
|
|
|
m_post_processing->renderDiffuseEnvMap(blueSHCoeff, greenSHCoeff, redSHCoeff);
|
|
|
|
|
gl_driver->extGlDrawBuffers(1, bufs);
|
|
|
|
|
// Handle SSAO
|
|
|
|
|
if (UserConfigParams::m_ssao)
|
|
|
|
|