Preload all visible spm (not including physics node) properly

Also change reset-button.spm to swatter_anim.spm, reset button
was replaced by thunderbird long time ago
This commit is contained in:
Benau 2018-01-23 13:32:30 +08:00
parent 95c12faa10
commit 40552b3fa0
17 changed files with 92 additions and 76 deletions

View File

@ -145,13 +145,6 @@ void DrawCalls::parseSceneManager(core::list<scene::ISceneNode*> &List,
if (LODNode *node = dynamic_cast<LODNode *>(*I)) if (LODNode *node = dynamic_cast<LODNode *>(*I))
{ {
node->updateVisibility(); node->updateVisibility();
if (SP::sp_first_frame)
{
for (auto* child_node : node->getAllNodes())
{
child_node->setVisible(true);
}
}
} }
(*I)->updateAbsolutePosition(); (*I)->updateAbsolutePosition();
if (!(*I)->isVisible()) if (!(*I)->isVisible())
@ -159,8 +152,7 @@ void DrawCalls::parseSceneManager(core::list<scene::ISceneNode*> &List,
if (STKParticle *node = dynamic_cast<STKParticle*>(*I)) if (STKParticle *node = dynamic_cast<STKParticle*>(*I))
{ {
if (!isCulledPrecise(cam, *I, irr_driver->getBoundingBoxesViz()) || if (!isCulledPrecise(cam, *I, irr_driver->getBoundingBoxesViz()))
SP::sp_first_frame)
CPUParticleManager::getInstance()->addParticleNode(node); CPUParticleManager::getInstance()->addParticleNode(node);
continue; continue;
} }
@ -168,7 +160,7 @@ void DrawCalls::parseSceneManager(core::list<scene::ISceneNode*> &List,
if (scene::IBillboardSceneNode *node = if (scene::IBillboardSceneNode *node =
dynamic_cast<scene::IBillboardSceneNode*>(*I)) dynamic_cast<scene::IBillboardSceneNode*>(*I))
{ {
if (!isCulledPrecise(cam, *I) || SP::sp_first_frame) if (!isCulledPrecise(cam, *I))
CPUParticleManager::getInstance()->addBillboardNode(node); CPUParticleManager::getInstance()->addBillboardNode(node);
continue; continue;
} }
@ -176,8 +168,7 @@ void DrawCalls::parseSceneManager(core::list<scene::ISceneNode*> &List,
if (STKTextBillboard *tb = if (STKTextBillboard *tb =
dynamic_cast<STKTextBillboard*>(*I)) dynamic_cast<STKTextBillboard*>(*I))
{ {
if (!isCulledPrecise(cam, *I, irr_driver->getBoundingBoxesViz()) || if (!isCulledPrecise(cam, *I, irr_driver->getBoundingBoxesViz()))
SP::sp_first_frame)
TextBillboardDrawer::addTextBillboard(tb); TextBillboardDrawer::addTextBillboard(tb);
continue; continue;
} }

View File

@ -120,8 +120,6 @@ void initSTKRenderer(ShaderBasedRenderer* sbr)
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
GLuint sp_mat_ubo[MAX_PLAYER_COUNT][3] = {}; GLuint sp_mat_ubo[MAX_PLAYER_COUNT][3] = {};
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
bool sp_first_frame = false;
// ----------------------------------------------------------------------------
GLuint sp_fog_ubo = 0; GLuint sp_fog_ubo = 0;
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
core::vector3df sp_wind_dir; core::vector3df sp_wind_dir;
@ -796,8 +794,7 @@ void addObject(SPMeshNode* node)
model_matrix.transformBoxEx(bb); model_matrix.transformBoxEx(bb);
std::vector<bool> discard; std::vector<bool> discard;
discard.resize((g_handle_shadow ? 5 : 1), false); discard.resize((g_handle_shadow ? 5 : 1), false);
for (int dc_type = 0; dc_type < for (int dc_type = 0; dc_type < (g_handle_shadow ? 5 : 1); dc_type++)
(g_handle_shadow ? 5 : sp_first_frame ? 0 : 1); dc_type++)
{ {
for (int i = 0; i < 24; i += 4) for (int i = 0; i < 24; i += 4)
{ {
@ -822,7 +819,7 @@ void addObject(SPMeshNode* node)
} }
} }
} }
if (sp_first_frame || g_handle_shadow ? if (g_handle_shadow ?
(discard[0] && discard[1] && discard[2] && discard[3] && (discard[0] && discard[1] && discard[2] && discard[3] &&
discard[4]) : discard[0]) discard[4]) : discard[0])
{ {
@ -847,8 +844,7 @@ void addObject(SPMeshNode* node)
mb->uploadGLMesh(); mb->uploadGLMesh();
// For first frame only need the vbo to be initialized // For first frame only need the vbo to be initialized
if (!added_for_skinning && node->getAnimationState() && if (!added_for_skinning && node->getAnimationState())
!sp_first_frame)
{ {
added_for_skinning = true; added_for_skinning = true;
int skinning_offset = g_skinning_offset + node->getTotalJoints(); int skinning_offset = g_skinning_offset + node->getTotalJoints();
@ -873,7 +869,7 @@ void addObject(SPMeshNode* node)
for (int dc_type = 0; dc_type < (g_handle_shadow ? 5 : 1); dc_type++) for (int dc_type = 0; dc_type < (g_handle_shadow ? 5 : 1); dc_type++)
{ {
if (!sp_first_frame && discard[dc_type]) if (discard[dc_type])
{ {
continue; continue;
} }
@ -1071,7 +1067,6 @@ void updateModelMatrix()
{ {
// Make sure all textures (with handles) are loaded // Make sure all textures (with handles) are loaded
SPTextureManager::get()->checkForGLCommand(true/*before_scene*/); SPTextureManager::get()->checkForGLCommand(true/*before_scene*/);
SP::sp_first_frame = false;
if (!sp_culling) if (!sp_culling)
{ {
return; return;
@ -1395,6 +1390,24 @@ SPMesh* convertEVTStandard(irr::scene::IMesh* mesh,
return spm; return spm;
} // convertEVTStandard } // convertEVTStandard
// ----------------------------------------------------------------------------
void uploadSPM(irr::scene::IMesh* mesh)
{
if (!CVS->isGLSL())
{
return;
}
SP::SPMesh* spm = dynamic_cast<SP::SPMesh*>(mesh);
if (spm)
{
for (u32 i = 0; i < spm->getMeshBufferCount(); i++)
{
SP::SPMeshBuffer* mb = spm->getSPMeshBuffer(i);
mb->uploadGLMesh();
}
}
} // uploadSPM
} }
#endif #endif

View File

@ -87,7 +87,6 @@ class SPMeshBuffer;
extern GLuint sp_mat_ubo[MAX_PLAYER_COUNT][3]; extern GLuint sp_mat_ubo[MAX_PLAYER_COUNT][3];
extern GLuint sp_fog_ubo; extern GLuint sp_fog_ubo;
extern bool sp_first_frame;
extern std::array<GLuint, 1> sp_prefilled_tex; extern std::array<GLuint, 1> sp_prefilled_tex;
extern unsigned sp_solid_poly_count; extern unsigned sp_solid_poly_count;
extern unsigned sp_shadow_poly_count; extern unsigned sp_shadow_poly_count;
@ -136,6 +135,8 @@ void drawBoundingBoxes();
SPMesh* convertEVTStandard(irr::scene::IMesh* mesh, SPMesh* convertEVTStandard(irr::scene::IMesh* mesh,
const irr::video::SColor* color = NULL); const irr::video::SColor* color = NULL);
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
void uploadSPM(irr::scene::IMesh* mesh);
// ----------------------------------------------------------------------------
inline uint8_t srgbToLinear(float color_srgb) inline uint8_t srgbToLinear(float color_srgb)
{ {
int ret; int ret;

View File

@ -137,8 +137,12 @@ SPShaderManager::SPShaderManager()
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
SPShaderManager::~SPShaderManager() SPShaderManager::~SPShaderManager()
{ {
m_shaders.clear();
m_official_shaders.clear(); m_official_shaders.clear();
removeUnusedShaders();
for (auto p : m_shaders)
{
Log::error("SPShaderManager", "%s > 1 ref_count", p.first.c_str());
}
} // ~SPShaderManager } // ~SPShaderManager
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------

View File

@ -88,6 +88,11 @@ SPTextureManager::~SPTextureManager()
t.join(); t.join();
} }
m_threaded_load_obj.clear(); m_threaded_load_obj.clear();
removeUnusedTextures();
for (auto p : m_textures)
{
Log::error("SPTextureManager", "%s > 1 ref_count", p.first.c_str());
}
} // ~SPTextureManager } // ~SPTextureManager
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------

View File

@ -566,7 +566,8 @@ void Attachment::update(float dt)
// Everything is done in the plugin. // Everything is done in the plugin.
break; break;
case ATTACH_NOLOKS_SWATTER: case ATTACH_NOLOKS_SWATTER:
// Should never be called, this symbols is only used as an index for case ATTACH_SWATTER_ANIM:
// Should never be called, these symbols are only used as an index for
// the model, Nolok's attachment type is ATTACH_SWATTER // the model, Nolok's attachment type is ATTACH_SWATTER
assert(false); assert(false);
break; break;
@ -597,9 +598,6 @@ void Attachment::update(float dt)
} }
} }
break; break;
case ATTACH_TINYTUX:
// Nothing to do for tinytux, this is all handled in EmergencyAnimation
break;
case ATTACH_BUBBLEGUM_SHIELD: case ATTACH_BUBBLEGUM_SHIELD:
case ATTACH_NOLOK_BUBBLEGUM_SHIELD: case ATTACH_NOLOK_BUBBLEGUM_SHIELD:
if (m_time_left < 0) if (m_time_left < 0)

View File

@ -60,10 +60,10 @@ public:
ATTACH_BOMB, ATTACH_BOMB,
ATTACH_ANVIL, ATTACH_ANVIL,
ATTACH_SWATTER, ATTACH_SWATTER,
// Note that the next symbol is only used as an index into the mesh // Note that the next 2 symbols are only used as an index into the mesh
// array; it will NEVER be actually assigned as an attachment type // array; it will NEVER be actually assigned as an attachment type
ATTACH_NOLOKS_SWATTER, ATTACH_NOLOKS_SWATTER,
ATTACH_TINYTUX, ATTACH_SWATTER_ANIM,
ATTACH_BUBBLEGUM_SHIELD, ATTACH_BUBBLEGUM_SHIELD,
ATTACH_NOLOK_BUBBLEGUM_SHIELD, ATTACH_NOLOK_BUBBLEGUM_SHIELD,
ATTACH_MAX, ATTACH_MAX,

View File

@ -21,6 +21,7 @@
#include "graphics/irr_driver.hpp" #include "graphics/irr_driver.hpp"
#include "graphics/material.hpp" #include "graphics/material.hpp"
#include "graphics/material_manager.hpp" #include "graphics/material_manager.hpp"
#include "graphics/sp/sp_base.hpp"
#include "io/file_manager.hpp" #include "io/file_manager.hpp"
AttachmentManager *attachment_manager = 0; AttachmentManager *attachment_manager = 0;
@ -53,7 +54,7 @@ static const initAttachmentType iat[]=
{Attachment::ATTACH_ANVIL, "anchor.spm", "anchor-attach-icon.png" }, {Attachment::ATTACH_ANVIL, "anchor.spm", "anchor-attach-icon.png" },
{Attachment::ATTACH_SWATTER, "swatter.spm", "swatter-icon.png" }, {Attachment::ATTACH_SWATTER, "swatter.spm", "swatter-icon.png" },
{Attachment::ATTACH_NOLOKS_SWATTER, "swatter_nolok.spm", "swatter-icon.png" }, {Attachment::ATTACH_NOLOKS_SWATTER, "swatter_nolok.spm", "swatter-icon.png" },
{Attachment::ATTACH_TINYTUX, "reset-button.spm", "reset-attach-icon.png" }, {Attachment::ATTACH_SWATTER_ANIM, "swatter_anim.spm", "swatter-icon.png" },
{Attachment::ATTACH_BUBBLEGUM_SHIELD, "bubblegum_shield.spm", "shield-icon.png" }, {Attachment::ATTACH_BUBBLEGUM_SHIELD, "bubblegum_shield.spm", "shield-icon.png" },
{Attachment::ATTACH_NOLOK_BUBBLEGUM_SHIELD, "bubblegum_shield_nolok.spm", "shield-icon.png" }, {Attachment::ATTACH_NOLOK_BUBBLEGUM_SHIELD, "bubblegum_shield_nolok.spm", "shield-icon.png" },
{Attachment::ATTACH_MAX, "", "" }, {Attachment::ATTACH_MAX, "", "" },
@ -76,23 +77,18 @@ AttachmentManager::~AttachmentManager()
} }
} // ~AttachmentManager } // ~AttachmentManager
//-----------------------------------------------------------------------------
void AttachmentManager::removeTextures()
{
for(int i=0; iat[i].attachment!=Attachment::ATTACH_MAX; i++)
{
// FIXME: free attachment textures
} // for
} // removeTextures
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void AttachmentManager::loadModels() void AttachmentManager::loadModels()
{ {
for(int i=0; iat[i].attachment!=Attachment::ATTACH_MAX; i++) for(int i=0; iat[i].attachment!=Attachment::ATTACH_MAX; i++)
{ {
std::string full_path = file_manager->getAsset(FileManager::MODEL,iat[i].file); std::string full_path = file_manager->getAsset(FileManager::MODEL,iat[i].file);
m_attachments[iat[i].attachment]=irr_driver->getAnimatedMesh(full_path); scene::IAnimatedMesh* mesh = irr_driver->getAnimatedMesh(full_path);
m_attachments[iat[i].attachment]->grab(); mesh->grab();
#ifndef SERVER_ONLY
SP::uploadSPM(mesh);
#endif
m_attachments[iat[i].attachment] = mesh;
if(iat[i].icon_file) if(iat[i].icon_file)
{ {
std::string full_icon_path = std::string full_icon_path =

View File

@ -39,7 +39,6 @@ private:
public: public:
AttachmentManager() {}; AttachmentManager() {};
~AttachmentManager(); ~AttachmentManager();
void removeTextures ();
void loadModels (); void loadModels ();
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
/** Returns the mest for a certain attachment. /** Returns the mest for a certain attachment.

View File

@ -25,8 +25,7 @@
#include "config/stk_config.hpp" #include "config/stk_config.hpp"
#include "config/user_config.hpp" #include "config/user_config.hpp"
#include "graphics/irr_driver.hpp" #include "graphics/irr_driver.hpp"
#include "graphics/material.hpp" #include "graphics/sp/sp_base.hpp"
#include "graphics/material_manager.hpp"
#include "io/file_manager.hpp" #include "io/file_manager.hpp"
#include "karts/abstract_kart.hpp" #include "karts/abstract_kart.hpp"
#include "karts/controller/spare_tire_ai.hpp" #include "karts/controller/spare_tire_ai.hpp"
@ -36,6 +35,7 @@
#include "tracks/arena_graph.hpp" #include "tracks/arena_graph.hpp"
#include "tracks/arena_node.hpp" #include "tracks/arena_node.hpp"
#include "tracks/track.hpp" #include "tracks/track.hpp"
#include "utils/random_generator.hpp"
#include "utils/string_utils.hpp" #include "utils/string_utils.hpp"
#include <IMesh.h> #include <IMesh.h>
@ -104,6 +104,9 @@ void ItemManager::loadDefaultItemMeshes()
"- aborting", name.c_str()); "- aborting", name.c_str());
exit(-1); exit(-1);
} }
#ifndef SERVER_ONLY
SP::uploadSPM(mesh);
#endif
mesh->grab(); mesh->grab();
m_item_mesh[i] = mesh; m_item_mesh[i] = mesh;
node->get("glow", &(m_glow_color[i])); node->get("glow", &(m_glow_color[i]));
@ -114,7 +117,13 @@ void ItemManager::loadDefaultItemMeshes()
? NULL ? NULL
: irr_driver->getMesh(lowres_model_filename); : irr_driver->getMesh(lowres_model_filename);
if (m_item_lowres_mesh[i]) m_item_lowres_mesh[i]->grab(); if (m_item_lowres_mesh[i])
{
#ifndef SERVER_ONLY
SP::uploadSPM(m_item_lowres_mesh[i]);
#endif
m_item_lowres_mesh[i]->grab();
}
} // for i } // for i
delete root; delete root;
} // loadDefaultItemMeshes } // loadDefaultItemMeshes

View File

@ -32,7 +32,7 @@
#include "graphics/explosion.hpp" #include "graphics/explosion.hpp"
#include "graphics/irr_driver.hpp" #include "graphics/irr_driver.hpp"
#include "io/file_manager.hpp" #include "io/file_manager.hpp"
#include "items/attachment.hpp" #include "items/attachment_manager.hpp"
#include "items/projectile_manager.hpp" #include "items/projectile_manager.hpp"
#include "karts/controller/controller.hpp" #include "karts/controller/controller.hpp"
#include "karts/explosion_animation.hpp" #include "karts/explosion_animation.hpp"
@ -74,8 +74,8 @@ Swatter::Swatter(AbstractKart *kart, bool was_bomb,
if (m_removing_bomb) if (m_removing_bomb)
{ {
m_scene_node->setMesh(irr_driver->getAnimatedMesh( m_scene_node->setMesh(attachment_manager
file_manager->getAsset(FileManager::MODEL,"swatter_anim.spm") ) ); ->getMesh(Attachment::ATTACH_SWATTER_ANIM));
m_scene_node->setRotation(core::vector3df(0.0, -180.0, 0.0)); m_scene_node->setRotation(core::vector3df(0.0, -180.0, 0.0));
m_scene_node->setAnimationSpeed(0.9f); m_scene_node->setAnimationSpeed(0.9f);
m_scene_node->setCurrentFrame(0.0f); m_scene_node->setCurrentFrame(0.0f);

View File

@ -217,8 +217,7 @@ void LocalPlayerController::update(float dt)
} }
} }
#endif #endif
if (m_kart->getKartAnimation() && m_sound_schedule == false && if (m_kart->getKartAnimation() && m_sound_schedule == false)
m_kart->getAttachment()->getType() != Attachment::ATTACH_TINYTUX)
{ {
m_sound_schedule = true; m_sound_schedule = true;
} }

View File

@ -678,16 +678,7 @@ bool KartModel::loadModels(const KartProperties &kart_properties)
std::string full_name = kart_properties.getKartDir() + obj.getFilename(); std::string full_name = kart_properties.getKartDir() + obj.getFilename();
obj.setModel(irr_driver->getMesh(full_name)); obj.setModel(irr_driver->getMesh(full_name));
#ifndef SERVER_ONLY #ifndef SERVER_ONLY
if (CVS->isGLSL()) SP::uploadSPM(obj.getModel());
{
for (u32 j = 0; j < obj.getModel()->getMeshBufferCount(); j++)
{
SP::SPMeshBuffer* mb = static_cast<SP::SPMeshBuffer*>
(obj.getModel()->getMeshBuffer(j));
// Pre-upload gl meshes and textures for kart screen
mb->uploadGLMesh();
}
}
#endif #endif
obj.getModel()->grab(); obj.getModel()->grab();
irr_driver->grabAllTextures(obj.getModel()); irr_driver->grabAllTextures(obj.getModel());
@ -725,16 +716,7 @@ bool KartModel::loadModels(const KartProperties &kart_properties)
kart_properties.getKartDir()+m_wheel_filename[i]; kart_properties.getKartDir()+m_wheel_filename[i];
m_wheel_model[i] = irr_driver->getMesh(full_wheel); m_wheel_model[i] = irr_driver->getMesh(full_wheel);
#ifndef SERVER_ONLY #ifndef SERVER_ONLY
if (CVS->isGLSL()) SP::uploadSPM(m_wheel_model[i]);
{
for (u32 j = 0; j < m_wheel_model[i]->getMeshBufferCount(); j++)
{
SP::SPMeshBuffer* mb = static_cast<SP::SPMeshBuffer*>
(m_wheel_model[i]->getMeshBuffer(j));
// Pre-upload gl meshes and textures for kart screen
mb->uploadGLMesh();
}
}
#endif #endif
// Grab all textures. This is done for the master only, so // Grab all textures. This is done for the master only, so
// the destructor will only free the textures if a master // the destructor will only free the textures if a master

View File

@ -113,6 +113,7 @@ LODNode* ModelDefinitionLoader::instanciateAsLOD(const XMLNode* node, scene::ISc
m_track->handleAnimatedTextures(scene_node, *group[m].m_xml); m_track->handleAnimatedTextures(scene_node, *group[m].m_xml);
Track::uploadNodeVertexBuffer(scene_node);
lod_node->add(group[m].m_distance, scene_node, true); lod_node->add(group[m].m_distance, scene_node, true);
} }
else else
@ -136,6 +137,7 @@ LODNode* ModelDefinitionLoader::instanciateAsLOD(const XMLNode* node, scene::ISc
m_track->handleAnimatedTextures(scene_node, *group[m].m_xml); m_track->handleAnimatedTextures(scene_node, *group[m].m_xml);
Track::uploadNodeVertexBuffer(scene_node);
lod_node->add(group[m].m_distance, scene_node, true); lod_node->add(group[m].m_distance, scene_node, true);
} }
} }

View File

@ -851,6 +851,7 @@ void Track::createPhysicsModel(unsigned int main_track_count)
for(unsigned int i=main_track_count; i<m_all_nodes.size(); i++) for(unsigned int i=main_track_count; i<m_all_nodes.size(); i++)
{ {
convertTrackToBullet(m_all_nodes[i]); convertTrackToBullet(m_all_nodes[i]);
uploadNodeVertexBuffer(m_all_nodes[i]);
} }
m_track_mesh->createPhysicalBody(m_friction); m_track_mesh->createPhysicalBody(m_friction);
m_gfx_effect_mesh->createCollisionShape(); m_gfx_effect_mesh->createCollisionShape();
@ -1423,6 +1424,7 @@ bool Track::loadMainTrack(const XMLNode &root)
for(unsigned int i=0; i<m_all_nodes.size(); i++) for(unsigned int i=0; i<m_all_nodes.size(); i++)
{ {
convertTrackToBullet(m_all_nodes[i]); convertTrackToBullet(m_all_nodes[i]);
uploadNodeVertexBuffer(m_all_nodes[i]);
} }
if (m_track_mesh == NULL) if (m_track_mesh == NULL)
@ -2090,8 +2092,6 @@ void Track::loadTrackModel(bool reverse_track, unsigned int mode_id)
} }
m_spherical_harmonics_textures.clear(); m_spherical_harmonics_textures.clear();
} }
// Draw all object visible in first frame to load all textures
SP::sp_first_frame = true;
#endif // !SERVER_ONLY #endif // !SERVER_ONLY
} // loadTrackModel } // loadTrackModel
@ -2563,3 +2563,19 @@ float Track::getAngle(int n) const
{ {
return DriveGraph::get()->getAngleToNext(n, 0); return DriveGraph::get()->getAngleToNext(n, 0);
} // getAngle } // getAngle
//-----------------------------------------------------------------------------
void Track::uploadNodeVertexBuffer(scene::ISceneNode *node)
{
#ifndef SERVER_ONLY
if (!CVS->isGLSL())
{
return;
}
SP::SPMeshNode* spmn = dynamic_cast<SP::SPMeshNode*>(node);
if (spmn)
{
SP::uploadSPM(spmn->getSPM());
}
#endif
} // uploadNodeVertexBuffer

View File

@ -409,6 +409,9 @@ public:
* minutes(!) in debug mode to be computed. */ * minutes(!) in debug mode to be computed. */
static bool m_dont_load_navmesh; static bool m_dont_load_navmesh;
/** Static helper function to pre-upload vertex buffer in spm. */
static void uploadNodeVertexBuffer(scene::ISceneNode *node);
static const float NOHIT; static const float NOHIT;
Track (const std::string &filename); Track (const std::string &filename);

View File

@ -585,17 +585,15 @@ void TrackObjectPresentationMesh::init(const XMLNode* xml_node,
Track *track = Track::getCurrentTrack(); Track *track = Track::getCurrentTrack();
if (track && track && xml_node) if (track && track && xml_node)
track->handleAnimatedTextures(m_node, *xml_node); track->handleAnimatedTextures(m_node, *xml_node);
Track::uploadNodeVertexBuffer(node);
} }
else else
{ {
bool displacing = false;
if (xml_node)
xml_node->get("displacing", &displacing);
m_node = irr_driver->addMesh(m_mesh, m_model_file, parent, m_render_info); m_node = irr_driver->addMesh(m_mesh, m_model_file, parent, m_render_info);
Track *track = Track::getCurrentTrack(); Track *track = Track::getCurrentTrack();
if (track && xml_node) if (track && xml_node)
track->handleAnimatedTextures(m_node, *xml_node); track->handleAnimatedTextures(m_node, *xml_node);
Track::uploadNodeVertexBuffer(m_node);
} }
if(!enabled) if(!enabled)