Merge branch 'fix_2445'

This commit is contained in:
Benau 2016-10-27 09:41:35 +08:00
commit 93197d9569
9 changed files with 92 additions and 74 deletions

View File

@ -1236,7 +1236,8 @@ scene::IMeshSceneNode *IrrDriver::addMesh(scene::IMesh *mesh,
const std::string& debug_name,
scene::ISceneNode *parent,
RenderInfo* render_info,
bool all_parts_colorized)
bool all_parts_colorized,
int frame_for_mesh)
{
if (!CVS->isGLSL())
return m_scene_manager->addMeshSceneNode(mesh, parent);
@ -1251,7 +1252,8 @@ scene::IMeshSceneNode *IrrDriver::addMesh(scene::IMesh *mesh,
core::vector3df(0, 0, 0),
core::vector3df(1.0f, 1.0f, 1.0f),
true, render_info,
all_parts_colorized);
all_parts_colorized,
frame_for_mesh);
node->drop();
return node;

View File

@ -393,7 +393,8 @@ public:
const std::string& debug_name,
scene::ISceneNode *parent = NULL,
RenderInfo* render_info = NULL,
bool all_parts_colorized = false);
bool all_parts_colorized = false,
int frame_for_mesh = -1);
PerCameraNode *addPerCameraNode(scene::ISceneNode* node,
scene::ICameraSceneNode* cam,
scene::ISceneNode *parent = NULL);

View File

@ -99,6 +99,16 @@ void STKAnimatedMesh::updateNoGL()
if (!isMaterialInitialized)
{
// Use a default render info to distinguish same mesh buffer created by
// different animated mesh node in vao manager when using instanced
// rendering
RenderInfo* default_ri = NULL;
if (CVS->isARBBaseInstanceUsable())
{
default_ri = new RenderInfo();
m_static_render_info.push_back(default_ri);
}
video::IVideoDriver* driver = SceneManager->getVideoDriver();
const u32 mb_count = m->getMeshBufferCount();
for (u32 i = 0; i < mb_count; ++i)
@ -121,7 +131,7 @@ void STKAnimatedMesh::updateNoGL()
}
else
{
cur_ri = NULL;
cur_ri = default_ri;
}
}
else
@ -137,7 +147,7 @@ void STKAnimatedMesh::updateNoGL()
assert(cur_ri ? cur_ri->isStatic() : true);
GLmeshes.push_back(allocateMeshBuffer(mb, m_debug_name,
affected || m_all_parts_colorized || (cur_ri
&& cur_ri->isTransparent()) ? cur_ri : NULL));
&& cur_ri->isTransparent()) ? cur_ri : default_ri));
}
for (u32 i = 0; i < m->getMeshBufferCount(); ++i)
@ -221,7 +231,7 @@ void STKAnimatedMesh::updateGL()
if (CVS->isARBBaseInstanceUsable())
{
std::pair<unsigned, unsigned> p = VAOManager::getInstance()->getBase(mb);
std::pair<unsigned, unsigned> p = VAOManager::getInstance()->getBase(mb, GLmeshes[i].m_render_info);
mesh.vaoBaseVertex = p.first;
mesh.vaoOffset = p.second;
}

View File

@ -32,8 +32,8 @@
#include "utils/helpers.hpp"
#include "utils/tuple.hpp"
#include <ISceneManager.h>
#include <IMaterialRenderer.h>
#include <ISceneManager.h>
// ============================================================================
class ColorizeShader : public Shader<ColorizeShader, core::matrix4,
@ -54,12 +54,14 @@ STKMeshSceneNode::STKMeshSceneNode(irr::scene::IMesh* mesh, ISceneNode* parent,
irr::s32 id, const std::string& debug_name,
const irr::core::vector3df& position,
const irr::core::vector3df& rotation,
const irr::core::vector3df& scale, bool createGLMeshes, RenderInfo* render_info, bool all_parts_colorized) :
const irr::core::vector3df& scale, bool createGLMeshes, RenderInfo* render_info, bool all_parts_colorized,
int frame_for_mesh) :
CMeshSceneNode(mesh, parent, mgr, id, position, rotation, scale)
{
isDisplacement = false;
immediate_draw = false;
update_each_frame = false;
m_frame_for_mesh = frame_for_mesh;
isGlow = false;
m_debug_name = debug_name;
@ -250,9 +252,18 @@ void STKMeshSceneNode::updateGL()
{
if (isGLInitialized)
return;
for (u32 i = 0; i < Mesh->getMeshBufferCount(); ++i)
scene::IAnimatedMesh* am = dynamic_cast<scene::IAnimatedMesh*>(Mesh);
scene::IMesh* m = Mesh;
if (am && m_frame_for_mesh > -1)
{
scene::IMeshBuffer* mb = Mesh->getMeshBuffer(i);
// Get the correct frame of animation for animated mesh
m = am->getMesh(m_frame_for_mesh);
}
for (u32 i = 0; i < m->getMeshBufferCount(); ++i)
{
scene::IMeshBuffer* mb = m->getMeshBuffer(i);
if (!mb)
continue;
GLMesh &mesh = GLmeshes[i];

View File

@ -29,6 +29,7 @@ class STKMeshSceneNode : public irr::scene::CMeshSceneNode, public STKMeshCommon
{
protected:
PtrVector<RenderInfo> m_static_render_info;
int m_frame_for_mesh;
std::vector<GLMesh> GLmeshes;
core::matrix4 ModelViewProjectionMatrix;
core::vector3df windDir;
@ -58,7 +59,8 @@ public:
const irr::core::vector3df& rotation = irr::core::vector3df(0, 0, 0),
const irr::core::vector3df& scale = irr::core::vector3df(1.0f, 1.0f, 1.0f),
bool createGLMeshes = true,
RenderInfo* render_info = NULL, bool all_parts_colorized = false);
RenderInfo* render_info = NULL, bool all_parts_colorized = false,
int frame_for_mesh = -1);
virtual void render();
virtual void setMesh(irr::scene::IMesh* mesh);
virtual void OnRegisterSceneNode();

View File

@ -41,7 +41,6 @@
#include <unordered_map>
#include <SViewFrustum.h>
#include <functional>
template<typename T>
struct InstanceFiller
@ -156,28 +155,6 @@ FillInstances_impl(std::vector<std::pair<GLMesh *, scene::ISceneNode *> > Instan
PolyCount += (InstanceBufferOffset - InitialOffset) * mesh->IndexCount / 3;
}
class MeshRenderInfoHash
{
public:
size_t operator() (const std::pair<scene::IMeshBuffer*, RenderInfo*> &p) const
{
return (std::hash<scene::IMeshBuffer*>()(p.first) ^
(std::hash<RenderInfo*>()(p.second) << 1));
}
};
struct MeshRenderInfoEquals : std::binary_function
<const std::pair<scene::IMeshBuffer*, RenderInfo*>&,
const std::pair<scene::IMeshBuffer*, RenderInfo*>&, bool>
{
result_type operator() (first_argument_type lhs,
second_argument_type rhs) const
{
return (lhs.first == rhs.first) &&
(lhs.second == rhs.second);
}
};
template<typename T>
static
void FillInstances(const std::unordered_map<std::pair<scene::IMeshBuffer*, RenderInfo*>, std::vector<std::pair<GLMesh *, scene::ISceneNode*> >, MeshRenderInfoHash, MeshRenderInfoEquals> &GatheredGLMesh, std::vector<GLMesh *> &InstancedList,

View File

@ -287,7 +287,7 @@ irr::video::E_VERTEX_TYPE VAOManager::getVertexType(enum VTXTYPE tp)
}
}
void VAOManager::append(scene::IMeshBuffer *mb, VTXTYPE tp)
void VAOManager::append(scene::IMeshBuffer *mb, VTXTYPE tp, RenderInfo* ri)
{
size_t old_vtx_cnt = last_vertex[tp];
size_t old_idx_cnt = last_index[tp];
@ -318,26 +318,28 @@ void VAOManager::append(scene::IMeshBuffer *mb, VTXTYPE tp)
glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, old_idx_cnt * sizeof(u16), mb->getIndexCount() * sizeof(u16), mb->getIndices());
}
mappedBaseVertex[tp][mb] = old_vtx_cnt;
mappedBaseIndex[tp][mb] = old_idx_cnt * sizeof(u16);
std::pair<scene::IMeshBuffer*, RenderInfo*> key(mb, ri);
mappedBaseVertex[tp][key] = old_vtx_cnt;
mappedBaseIndex[tp][key] = old_idx_cnt * sizeof(u16);
}
std::pair<unsigned, unsigned> VAOManager::getBase(scene::IMeshBuffer *mb)
std::pair<unsigned, unsigned> VAOManager::getBase(scene::IMeshBuffer *mb, RenderInfo* ri)
{
VTXTYPE tp = getVTXTYPE(mb->getVertexType());
if (mappedBaseVertex[tp].find(mb) == mappedBaseVertex[tp].end())
std::pair<scene::IMeshBuffer*, RenderInfo*> key(mb, ri);
if (mappedBaseVertex[tp].find(key) == mappedBaseVertex[tp].end())
{
assert(mappedBaseIndex[tp].find(mb) == mappedBaseIndex[tp].end());
append(mb, tp);
assert(mappedBaseIndex[tp].find(key) == mappedBaseIndex[tp].end());
append(mb, tp, ri);
regenerateVAO(tp);
regenerateInstancedVAO();
}
std::unordered_map<scene::IMeshBuffer*, unsigned>::iterator It;
It = mappedBaseVertex[tp].find(mb);
std::unordered_map<std::pair<scene::IMeshBuffer*, RenderInfo*>, unsigned, MeshRenderInfoHash, MeshRenderInfoEquals>::iterator It;
It = mappedBaseVertex[tp].find(key);
assert(It != mappedBaseVertex[tp].end());
unsigned vtx = It->second;
It = mappedBaseIndex[tp].find(mb);
It = mappedBaseIndex[tp].find(key);
assert(It != mappedBaseIndex[tp].end());
return std::pair<unsigned, unsigned>(vtx, It->second);
}

View File

@ -26,6 +26,8 @@
#include <map>
#include <unordered_map>
class RenderInfo;
enum InstanceType
{
InstanceTypeDualTex,
@ -153,6 +155,30 @@ struct GlowInstanceData
#pragma pack(pop)
#endif
#include <functional>
class MeshRenderInfoHash
{
public:
size_t operator() (const std::pair<irr::scene::IMeshBuffer*, RenderInfo*> &p) const
{
return (std::hash<irr::scene::IMeshBuffer*>()(p.first) ^
(std::hash<RenderInfo*>()(p.second) << 1));
}
};
struct MeshRenderInfoEquals : std::binary_function
<const std::pair<irr::scene::IMeshBuffer*, RenderInfo*>&,
const std::pair<irr::scene::IMeshBuffer*, RenderInfo*>&, bool>
{
result_type operator() (first_argument_type lhs,
second_argument_type rhs) const
{
return (lhs.first == rhs.first) &&
(lhs.second == rhs.second);
}
};
class VAOManager : public Singleton<VAOManager>
{
enum VTXTYPE { VTXTYPE_STANDARD, VTXTYPE_TCOORD, VTXTYPE_TANGENT, VTXTYPE_COUNT };
@ -162,7 +188,7 @@ class VAOManager : public Singleton<VAOManager>
void *VBOPtr[VTXTYPE_COUNT], *IBOPtr[VTXTYPE_COUNT];
size_t RealVBOSize[VTXTYPE_COUNT], RealIBOSize[VTXTYPE_COUNT];
size_t last_vertex[VTXTYPE_COUNT], last_index[VTXTYPE_COUNT];
std::unordered_map<irr::scene::IMeshBuffer*, unsigned> mappedBaseVertex[VTXTYPE_COUNT], mappedBaseIndex[VTXTYPE_COUNT];
std::unordered_map <std::pair<irr::scene::IMeshBuffer*, RenderInfo*>, unsigned, MeshRenderInfoHash, MeshRenderInfoEquals> mappedBaseVertex[VTXTYPE_COUNT], mappedBaseIndex[VTXTYPE_COUNT];
std::map<std::pair<irr::video::E_VERTEX_TYPE, InstanceType>, GLuint> InstanceVAO;
void cleanInstanceVAOs();
@ -172,10 +198,10 @@ class VAOManager : public Singleton<VAOManager>
size_t getVertexPitch(enum VTXTYPE) const;
VTXTYPE getVTXTYPE(irr::video::E_VERTEX_TYPE type);
irr::video::E_VERTEX_TYPE getVertexType(enum VTXTYPE tp);
void append(irr::scene::IMeshBuffer *, VTXTYPE tp);
void append(irr::scene::IMeshBuffer *, VTXTYPE tp, RenderInfo* ri = NULL);
public:
VAOManager();
std::pair<unsigned, unsigned> getBase(irr::scene::IMeshBuffer *);
std::pair<unsigned, unsigned> getBase(irr::scene::IMeshBuffer *, RenderInfo* ri = NULL);
GLuint getInstanceBuffer(InstanceType it) { return instance_vbo[it]; }
void *getInstanceBufferPtr(InstanceType it) { return Ptr[it]; }
unsigned getVBO(irr::video::E_VERTEX_TYPE type) { return vbo[getVTXTYPE(type)]; }

View File

@ -247,12 +247,6 @@ KartModel::~KartModel()
{
// Master KartModels should never have a speed weighted object attached.
assert(!m_is_master);
// Drop the cloned transparent model if created
if (m_krt == KRT_TRANSPARENT)
{
m_speed_weighted_objects[i].m_model->drop();
}
m_speed_weighted_objects[i].m_node->drop();
}
if(m_is_master && m_speed_weighted_objects[i].m_model)
@ -262,20 +256,15 @@ KartModel::~KartModel()
}
}
// In case of the master, the mesh must be dropped. A non-master KartModel
// has a copy of the master's mesh, so it needs to be dropped, too.
if (m_mesh)
if (m_is_master && m_mesh)
{
m_mesh->drop();
if (m_is_master)
// If there is only one copy left, it's the copy in irrlicht's
// mesh cache, so it can be removed.
if (m_mesh && m_mesh->getReferenceCount() == 1)
{
// If there is only one copy left, it's the copy in irrlicht's
// mesh cache, so it can be removed.
if (m_mesh && m_mesh->getReferenceCount() == 1)
{
irr_driver->dropAllTextures(m_mesh);
irr_driver->removeMeshFromCache(m_mesh);
}
irr_driver->dropAllTextures(m_mesh);
irr_driver->removeMeshFromCache(m_mesh);
}
}
@ -308,7 +297,7 @@ KartModel* KartModel::makeCopy(KartRenderType krt)
km->m_kart_height = m_kart_height;
km->m_kart_highest_point = m_kart_highest_point;
km->m_kart_lowest_point = m_kart_lowest_point;
km->m_mesh = irr_driver->copyAnimatedMesh(m_mesh);
km->m_mesh = m_mesh;
km->m_model_filename = m_model_filename;
km->m_animation_speed = m_animation_speed;
km->m_current_animation = AF_DEFAULT;
@ -343,12 +332,6 @@ KartModel* KartModel::makeCopy(KartRenderType krt)
// Master should not have any speed weighted nodes.
assert(!m_speed_weighted_objects[i].m_node);
km->m_speed_weighted_objects[i] = m_speed_weighted_objects[i];
if (krt == KRT_TRANSPARENT)
{
// Only clone the mesh if transparent type is used, see #2445
km->m_speed_weighted_objects[i].m_model = irr_driver
->copyAnimatedMesh(m_speed_weighted_objects[i].m_model);
}
}
for(unsigned int i=AF_BEGIN; i<=AF_END; i++)
@ -444,8 +427,12 @@ scene::ISceneNode* KartModel::attachModel(bool animated_models, bool always_anim
? m_animation_frame[AF_STRAIGHT]
: 0;
scene::IMesh* main_frame = m_mesh->getMesh(straight_frame);
main_frame->setHardwareMappingHint(scene::EHM_STATIC);
scene::IMesh* main_frame = m_mesh;
if (!CVS->isGLSL())
{
main_frame = m_mesh->getMesh(straight_frame);
main_frame->setHardwareMappingHint(scene::EHM_STATIC);
}
std::string debug_name;
@ -454,7 +441,7 @@ scene::ISceneNode* KartModel::attachModel(bool animated_models, bool always_anim
#endif
node = irr_driver->addMesh(main_frame, debug_name,
NULL /*parent*/, getRenderInfo());
NULL /*parent*/, getRenderInfo(), false, straight_frame);
#ifdef DEBUG
node->setName(debug_name.c_str());