Make skinning offset changeable by culling

This commit is contained in:
Benau 2016-12-07 16:08:57 +08:00
parent fcebb5c2e6
commit d21e5e0f76
7 changed files with 40 additions and 44 deletions

View File

@ -1458,7 +1458,7 @@ void CSkinnedMesh::convertForSkinning()
}
SkinnedLastFrame = false;
skinMesh();
m_joint_total_size = m_joint_matrixes.size() * sizeof(core::matrix4);
m_joint_total_size = m_joint_matrixes.size();
}
void CSkinnedMesh::computeWeightInfluence(SJoint *joint, size_t &index, WeightInfluence& wi)

View File

@ -178,28 +178,6 @@ void DrawCalls::handleSTKCommon(scene::ISceneNode *Node,
return;
}
uint32_t skinning_offset = 0;
STKAnimatedMesh* am = dynamic_cast<STKAnimatedMesh*>(Node);
if (am && am->useHardwareSkinning())
{
SkinningOffset::const_iterator it = m_skinning_offsets.find(am);
if (it != m_skinning_offsets.end())
{
skinning_offset = am->getSkinningOffset() / sizeof(core::matrix4);
}
else
{
const uint32_t cur_offset =
std::accumulate(m_skinning_offsets.begin(),
m_skinning_offsets.end(), 0, [] (const size_t previous,
const std::pair<STKAnimatedMesh*, uint32_t>& p)
{ return previous + p.second; });
am->setSkinningOffset(cur_offset);
m_skinning_offsets[am] = am->getTotalJointSize();
skinning_offset = cur_offset / sizeof(core::matrix4);
}
}
bool culled_for_cams[6] = { true, true, true, true, true, true };
culled_for_cams[0] = isCulledPrecise(cam, Node,
irr_driver->getBoundingBoxesViz());
@ -268,6 +246,21 @@ void DrawCalls::handleSTKCommon(scene::ISceneNode *Node,
for (GLMesh *mesh : node->TransparentMesh[TM_DISPLACEMENT])
pushVector(ListDisplacement::getInstance(), mesh, Node->getAbsoluteTransformation());
uint32_t skinning_offset = 0;
STKAnimatedMesh* am = dynamic_cast<STKAnimatedMesh*>(Node);
if (am && am->useHardwareSkinning() &&
(!culled_for_cams[0] || !culled_for_cams[1] || !culled_for_cams[2] ||
!culled_for_cams[3] || !culled_for_cams[4] || !culled_for_cams[5]))
{
skinning_offset =
std::accumulate(m_mesh_for_skinning.begin(),
m_mesh_for_skinning.end(), 0, [] (const size_t previous,
const STKAnimatedMesh* m)
{ return previous + m->getTotalJointSize(); });
m_mesh_for_skinning.insert(am);
am->setSkinningOffset(skinning_offset * sizeof(core::matrix4));
}
if (!culled_for_cams[0])
{
for (unsigned Mat = 0; Mat < Material::SHADERTYPE_COUNT; ++Mat)
@ -573,7 +566,7 @@ void DrawCalls::prepareDrawCalls( ShadowMatrices& shadow_matrices,
{
m_wind_dir = getWindDir();
clearLists();
m_mesh_for_skinning.clear();
for (unsigned Mat = 0; Mat < Material::SHADERTYPE_COUNT; ++Mat)
{
m_solid_pass_mesh[Mat].clear();

View File

@ -27,8 +27,6 @@ class ShadowMatrices;
class STKAnimatedMesh;
class STKBillboard;
typedef std::unordered_map<STKAnimatedMesh*, uint32_t> SkinningOffset;
class DrawCalls
{
private:
@ -39,7 +37,7 @@ private:
std::vector<irr::scene::ISceneNode *> m_immediate_draw_list;
std::vector<STKBillboard *> m_billboard_list;
std::vector<ParticleSystemProxy *> m_particles_list;
SkinningOffset m_skinning_offsets;
std::set<STKAnimatedMesh*> m_mesh_for_skinning;
std::vector<float> m_bounding_boxes;
@ -109,7 +107,6 @@ public:
void drawIndirectGlow() const;
void multidrawGlow() const;
void renderBoundingBoxes();
void resetSkinningOffsets() { m_skinning_offsets.clear(); }
};
#endif //HEADER_DRAW_CALLS_HPP

View File

@ -697,8 +697,7 @@ void ShaderBasedRenderer::onUnloadWorld()
{
delete m_rtts;
m_rtts = NULL;
removeSkyBox();
m_draw_calls.resetSkinningOffsets();
removeSkyBox();
}
// ----------------------------------------------------------------------------

View File

@ -35,7 +35,8 @@ irr::scene::ISceneManager* mgr, s32 id, const std::string& debug_name,
const core::vector3df& position,
const core::vector3df& rotation,
const core::vector3df& scale, RenderInfo* render_info, bool all_parts_colorized) :
CAnimatedMeshSceneNode(mesh, parent, mgr, id, position, rotation, scale), m_skinned_mesh(NULL)
CAnimatedMeshSceneNode(mesh, parent, mgr, id, position, rotation, scale),
m_skinned_mesh(NULL), m_skinning_offset(-1)
{
isGLInitialized = false;
isMaterialInitialized = false;
@ -44,10 +45,7 @@ const core::vector3df& scale, RenderInfo* render_info, bool all_parts_colorized)
#ifdef DEBUG
m_debug_name = debug_name;
#endif
m_skinning_offset = -1;
m_skinned_mesh = dynamic_cast<scene::CSkinnedMesh*>(Mesh);
if (m_skinned_mesh)
m_skinned_mesh->convertForSkinning();
resetSkinningState(mesh);
}
STKAnimatedMesh::~STKAnimatedMesh()
@ -82,6 +80,7 @@ void STKAnimatedMesh::setMesh(scene::IAnimatedMesh* mesh)
isMaterialInitialized = false;
cleanGLMeshes();
CAnimatedMeshSceneNode::setMesh(mesh);
resetSkinningState(mesh);
}
void STKAnimatedMesh::updateNoGL()
@ -274,12 +273,14 @@ void STKAnimatedMesh::updateGL()
isGLInitialized = true;
}
if (m_skinned_mesh)
if (useHardwareSkinning())
{
assert(m_skinning_offset != -1);
if (m_skinning_offset == -1) return;
glBindBuffer(GL_UNIFORM_BUFFER, SharedGPUObjects::getSkinningUBO());
glBufferSubData(GL_UNIFORM_BUFFER, m_skinning_offset,
m_skinned_mesh->getTotalJointSize(), m_skinned_mesh->getJointPointer());
m_skinned_mesh->getTotalJointSize() * sizeof(core::matrix4),
m_skinned_mesh->getJointPointer());
m_skinning_offset = -1;
return;
}
@ -330,3 +331,11 @@ int STKAnimatedMesh::getTotalJointSize() const
{
return m_skinned_mesh->getTotalJointSize();
}
void STKAnimatedMesh::resetSkinningState(scene::IAnimatedMesh* mesh)
{
m_skinning_offset = -1;
m_skinned_mesh = dynamic_cast<scene::CSkinnedMesh*>(mesh);
if (m_skinned_mesh)
m_skinned_mesh->convertForSkinning();
}

View File

@ -55,9 +55,9 @@ public:
virtual void setMesh(irr::scene::IAnimatedMesh* mesh);
virtual bool glow() const { return false; }
int getTotalJointSize() const;
int getSkinningOffset() const { return m_skinning_offset; }
void setSkinningOffset(int offset) { m_skinning_offset = offset; }
bool useHardwareSkinning() const { return m_skinned_mesh!= NULL; }
void setSkinningOffset(int offset) { m_skinning_offset = offset; }
bool useHardwareSkinning() const { return m_skinned_mesh != NULL; }
void resetSkinningState(scene::IAnimatedMesh*);
private:
RenderInfo* m_mesh_render_info;
bool m_all_parts_colorized;

View File

@ -219,8 +219,6 @@ GLMesh allocateMeshBuffer(scene::IMeshBuffer* mb, const std::string& debug_name,
}
result.VAOType = mb->getVertexType();
result.Stride = getVertexPitchFromType(result.VAOType);
result.IndexCount = mb->getIndexCount();
switch (mb->getPrimitiveType())
{
@ -250,7 +248,7 @@ GLMesh allocateMeshBuffer(scene::IMeshBuffer* mb, const std::string& debug_name,
for (unsigned i = 0; i < 8; i++)
result.textures[i] = mb->getMaterial().getTexture(i);
result.texture_trans = core::vector2df(0.0f, 0.0f);
result.VAOType = mb->getVertexType();
return result;
} // allocateMeshBuffer