diff --git a/src/graphics/draw_calls.cpp b/src/graphics/draw_calls.cpp index a452d7519..40ad6bc94 100644 --- a/src/graphics/draw_calls.cpp +++ b/src/graphics/draw_calls.cpp @@ -145,13 +145,6 @@ void DrawCalls::parseSceneManager(core::list<scene::ISceneNode*> &List, if (LODNode *node = dynamic_cast<LODNode *>(*I)) { node->updateVisibility(); - if (SP::sp_first_frame) - { - for (auto* child_node : node->getAllNodes()) - { - child_node->setVisible(true); - } - } } (*I)->updateAbsolutePosition(); if (!(*I)->isVisible()) @@ -159,8 +152,7 @@ void DrawCalls::parseSceneManager(core::list<scene::ISceneNode*> &List, if (STKParticle *node = dynamic_cast<STKParticle*>(*I)) { - if (!isCulledPrecise(cam, *I, irr_driver->getBoundingBoxesViz()) || - SP::sp_first_frame) + if (!isCulledPrecise(cam, *I, irr_driver->getBoundingBoxesViz())) CPUParticleManager::getInstance()->addParticleNode(node); continue; } @@ -168,7 +160,7 @@ void DrawCalls::parseSceneManager(core::list<scene::ISceneNode*> &List, if (scene::IBillboardSceneNode *node = dynamic_cast<scene::IBillboardSceneNode*>(*I)) { - if (!isCulledPrecise(cam, *I) || SP::sp_first_frame) + if (!isCulledPrecise(cam, *I)) CPUParticleManager::getInstance()->addBillboardNode(node); continue; } @@ -176,8 +168,7 @@ void DrawCalls::parseSceneManager(core::list<scene::ISceneNode*> &List, if (STKTextBillboard *tb = dynamic_cast<STKTextBillboard*>(*I)) { - if (!isCulledPrecise(cam, *I, irr_driver->getBoundingBoxesViz()) || - SP::sp_first_frame) + if (!isCulledPrecise(cam, *I, irr_driver->getBoundingBoxesViz())) TextBillboardDrawer::addTextBillboard(tb); continue; } diff --git a/src/graphics/sp/sp_base.cpp b/src/graphics/sp/sp_base.cpp index c16954cb4..3f3595e2d 100644 --- a/src/graphics/sp/sp_base.cpp +++ b/src/graphics/sp/sp_base.cpp @@ -120,8 +120,6 @@ void initSTKRenderer(ShaderBasedRenderer* sbr) // ---------------------------------------------------------------------------- GLuint sp_mat_ubo[MAX_PLAYER_COUNT][3] = {}; // ---------------------------------------------------------------------------- -bool sp_first_frame = false; -// ---------------------------------------------------------------------------- GLuint sp_fog_ubo = 0; // ---------------------------------------------------------------------------- core::vector3df sp_wind_dir; @@ -796,8 +794,7 @@ void addObject(SPMeshNode* node) model_matrix.transformBoxEx(bb); std::vector<bool> discard; discard.resize((g_handle_shadow ? 5 : 1), false); - for (int dc_type = 0; dc_type < - (g_handle_shadow ? 5 : sp_first_frame ? 0 : 1); dc_type++) + for (int dc_type = 0; dc_type < (g_handle_shadow ? 5 : 1); dc_type++) { 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[4]) : discard[0]) { @@ -847,8 +844,7 @@ void addObject(SPMeshNode* node) mb->uploadGLMesh(); // For first frame only need the vbo to be initialized - if (!added_for_skinning && node->getAnimationState() && - !sp_first_frame) + if (!added_for_skinning && node->getAnimationState()) { added_for_skinning = true; 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++) { - if (!sp_first_frame && discard[dc_type]) + if (discard[dc_type]) { continue; } @@ -1071,7 +1067,6 @@ void updateModelMatrix() { // Make sure all textures (with handles) are loaded SPTextureManager::get()->checkForGLCommand(true/*before_scene*/); - SP::sp_first_frame = false; if (!sp_culling) { return; @@ -1395,6 +1390,24 @@ SPMesh* convertEVTStandard(irr::scene::IMesh* mesh, return spm; } // 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 diff --git a/src/graphics/sp/sp_base.hpp b/src/graphics/sp/sp_base.hpp index deced790d..d6284bf2b 100644 --- a/src/graphics/sp/sp_base.hpp +++ b/src/graphics/sp/sp_base.hpp @@ -87,7 +87,6 @@ class SPMeshBuffer; extern GLuint sp_mat_ubo[MAX_PLAYER_COUNT][3]; extern GLuint sp_fog_ubo; -extern bool sp_first_frame; extern std::array<GLuint, 1> sp_prefilled_tex; extern unsigned sp_solid_poly_count; extern unsigned sp_shadow_poly_count; @@ -136,6 +135,8 @@ void drawBoundingBoxes(); SPMesh* convertEVTStandard(irr::scene::IMesh* mesh, const irr::video::SColor* color = NULL); // ---------------------------------------------------------------------------- +void uploadSPM(irr::scene::IMesh* mesh); +// ---------------------------------------------------------------------------- inline uint8_t srgbToLinear(float color_srgb) { int ret; diff --git a/src/graphics/sp/sp_shader_manager.cpp b/src/graphics/sp/sp_shader_manager.cpp index bc40664af..0ff6b9e53 100644 --- a/src/graphics/sp/sp_shader_manager.cpp +++ b/src/graphics/sp/sp_shader_manager.cpp @@ -137,8 +137,12 @@ SPShaderManager::SPShaderManager() // ---------------------------------------------------------------------------- SPShaderManager::~SPShaderManager() { - m_shaders.clear(); m_official_shaders.clear(); + removeUnusedShaders(); + for (auto p : m_shaders) + { + Log::error("SPShaderManager", "%s > 1 ref_count", p.first.c_str()); + } } // ~SPShaderManager // ---------------------------------------------------------------------------- diff --git a/src/graphics/sp/sp_texture_manager.cpp b/src/graphics/sp/sp_texture_manager.cpp index 654f1f2e4..75f3b7dd1 100644 --- a/src/graphics/sp/sp_texture_manager.cpp +++ b/src/graphics/sp/sp_texture_manager.cpp @@ -88,6 +88,11 @@ SPTextureManager::~SPTextureManager() t.join(); } m_threaded_load_obj.clear(); + removeUnusedTextures(); + for (auto p : m_textures) + { + Log::error("SPTextureManager", "%s > 1 ref_count", p.first.c_str()); + } } // ~SPTextureManager // ---------------------------------------------------------------------------- diff --git a/src/items/attachment.cpp b/src/items/attachment.cpp index 3c012d58c..99be20a75 100644 --- a/src/items/attachment.cpp +++ b/src/items/attachment.cpp @@ -566,7 +566,8 @@ void Attachment::update(float dt) // Everything is done in the plugin. break; 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 assert(false); break; @@ -597,9 +598,6 @@ void Attachment::update(float dt) } } break; - case ATTACH_TINYTUX: - // Nothing to do for tinytux, this is all handled in EmergencyAnimation - break; case ATTACH_BUBBLEGUM_SHIELD: case ATTACH_NOLOK_BUBBLEGUM_SHIELD: if (m_time_left < 0) diff --git a/src/items/attachment.hpp b/src/items/attachment.hpp index a19c0c23b..154b7b984 100644 --- a/src/items/attachment.hpp +++ b/src/items/attachment.hpp @@ -60,10 +60,10 @@ public: ATTACH_BOMB, ATTACH_ANVIL, 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 ATTACH_NOLOKS_SWATTER, - ATTACH_TINYTUX, + ATTACH_SWATTER_ANIM, ATTACH_BUBBLEGUM_SHIELD, ATTACH_NOLOK_BUBBLEGUM_SHIELD, ATTACH_MAX, diff --git a/src/items/attachment_manager.cpp b/src/items/attachment_manager.cpp index b49bf4bb8..0233885f1 100644 --- a/src/items/attachment_manager.cpp +++ b/src/items/attachment_manager.cpp @@ -21,6 +21,7 @@ #include "graphics/irr_driver.hpp" #include "graphics/material.hpp" #include "graphics/material_manager.hpp" +#include "graphics/sp/sp_base.hpp" #include "io/file_manager.hpp" AttachmentManager *attachment_manager = 0; @@ -53,7 +54,7 @@ static const initAttachmentType iat[]= {Attachment::ATTACH_ANVIL, "anchor.spm", "anchor-attach-icon.png" }, {Attachment::ATTACH_SWATTER, "swatter.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_NOLOK_BUBBLEGUM_SHIELD, "bubblegum_shield_nolok.spm", "shield-icon.png" }, {Attachment::ATTACH_MAX, "", "" }, @@ -76,23 +77,18 @@ 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() { for(int i=0; iat[i].attachment!=Attachment::ATTACH_MAX; i++) { std::string full_path = file_manager->getAsset(FileManager::MODEL,iat[i].file); - m_attachments[iat[i].attachment]=irr_driver->getAnimatedMesh(full_path); - m_attachments[iat[i].attachment]->grab(); + scene::IAnimatedMesh* mesh = irr_driver->getAnimatedMesh(full_path); + mesh->grab(); +#ifndef SERVER_ONLY + SP::uploadSPM(mesh); +#endif + m_attachments[iat[i].attachment] = mesh; if(iat[i].icon_file) { std::string full_icon_path = diff --git a/src/items/attachment_manager.hpp b/src/items/attachment_manager.hpp index c5d827ed7..7bb03baab 100644 --- a/src/items/attachment_manager.hpp +++ b/src/items/attachment_manager.hpp @@ -39,7 +39,6 @@ private: public: AttachmentManager() {}; ~AttachmentManager(); - void removeTextures (); void loadModels (); // ------------------------------------------------------------------------ /** Returns the mest for a certain attachment. diff --git a/src/items/item_manager.cpp b/src/items/item_manager.cpp index 24bf8f4dc..9d2f96e47 100644 --- a/src/items/item_manager.cpp +++ b/src/items/item_manager.cpp @@ -25,8 +25,7 @@ #include "config/stk_config.hpp" #include "config/user_config.hpp" #include "graphics/irr_driver.hpp" -#include "graphics/material.hpp" -#include "graphics/material_manager.hpp" +#include "graphics/sp/sp_base.hpp" #include "io/file_manager.hpp" #include "karts/abstract_kart.hpp" #include "karts/controller/spare_tire_ai.hpp" @@ -36,6 +35,7 @@ #include "tracks/arena_graph.hpp" #include "tracks/arena_node.hpp" #include "tracks/track.hpp" +#include "utils/random_generator.hpp" #include "utils/string_utils.hpp" #include <IMesh.h> @@ -104,6 +104,9 @@ void ItemManager::loadDefaultItemMeshes() "- aborting", name.c_str()); exit(-1); } +#ifndef SERVER_ONLY + SP::uploadSPM(mesh); +#endif mesh->grab(); m_item_mesh[i] = mesh; node->get("glow", &(m_glow_color[i])); @@ -114,7 +117,13 @@ void ItemManager::loadDefaultItemMeshes() ? NULL : 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 delete root; } // loadDefaultItemMeshes diff --git a/src/items/swatter.cpp b/src/items/swatter.cpp index 4241d6654..f2b73ce6a 100644 --- a/src/items/swatter.cpp +++ b/src/items/swatter.cpp @@ -32,7 +32,7 @@ #include "graphics/explosion.hpp" #include "graphics/irr_driver.hpp" #include "io/file_manager.hpp" -#include "items/attachment.hpp" +#include "items/attachment_manager.hpp" #include "items/projectile_manager.hpp" #include "karts/controller/controller.hpp" #include "karts/explosion_animation.hpp" @@ -74,8 +74,8 @@ Swatter::Swatter(AbstractKart *kart, bool was_bomb, if (m_removing_bomb) { - m_scene_node->setMesh(irr_driver->getAnimatedMesh( - file_manager->getAsset(FileManager::MODEL,"swatter_anim.spm") ) ); + m_scene_node->setMesh(attachment_manager + ->getMesh(Attachment::ATTACH_SWATTER_ANIM)); m_scene_node->setRotation(core::vector3df(0.0, -180.0, 0.0)); m_scene_node->setAnimationSpeed(0.9f); m_scene_node->setCurrentFrame(0.0f); diff --git a/src/karts/controller/local_player_controller.cpp b/src/karts/controller/local_player_controller.cpp index b3e8bb5a2..475ff5ad0 100644 --- a/src/karts/controller/local_player_controller.cpp +++ b/src/karts/controller/local_player_controller.cpp @@ -217,8 +217,7 @@ void LocalPlayerController::update(float dt) } } #endif - if (m_kart->getKartAnimation() && m_sound_schedule == false && - m_kart->getAttachment()->getType() != Attachment::ATTACH_TINYTUX) + if (m_kart->getKartAnimation() && m_sound_schedule == false) { m_sound_schedule = true; } diff --git a/src/karts/kart_model.cpp b/src/karts/kart_model.cpp index 05f92794c..9f8271b2b 100644 --- a/src/karts/kart_model.cpp +++ b/src/karts/kart_model.cpp @@ -678,16 +678,7 @@ bool KartModel::loadModels(const KartProperties &kart_properties) std::string full_name = kart_properties.getKartDir() + obj.getFilename(); obj.setModel(irr_driver->getMesh(full_name)); #ifndef SERVER_ONLY - if (CVS->isGLSL()) - { - 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(); - } - } + SP::uploadSPM(obj.getModel()); #endif obj.getModel()->grab(); irr_driver->grabAllTextures(obj.getModel()); @@ -725,16 +716,7 @@ bool KartModel::loadModels(const KartProperties &kart_properties) kart_properties.getKartDir()+m_wheel_filename[i]; m_wheel_model[i] = irr_driver->getMesh(full_wheel); #ifndef SERVER_ONLY - if (CVS->isGLSL()) - { - 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(); - } - } + SP::uploadSPM(m_wheel_model[i]); #endif // Grab all textures. This is done for the master only, so // the destructor will only free the textures if a master diff --git a/src/tracks/model_definition_loader.cpp b/src/tracks/model_definition_loader.cpp index 0fea06376..8ffd1730c 100644 --- a/src/tracks/model_definition_loader.cpp +++ b/src/tracks/model_definition_loader.cpp @@ -113,6 +113,7 @@ LODNode* ModelDefinitionLoader::instanciateAsLOD(const XMLNode* node, scene::ISc m_track->handleAnimatedTextures(scene_node, *group[m].m_xml); + Track::uploadNodeVertexBuffer(scene_node); lod_node->add(group[m].m_distance, scene_node, true); } else @@ -136,6 +137,7 @@ LODNode* ModelDefinitionLoader::instanciateAsLOD(const XMLNode* node, scene::ISc m_track->handleAnimatedTextures(scene_node, *group[m].m_xml); + Track::uploadNodeVertexBuffer(scene_node); lod_node->add(group[m].m_distance, scene_node, true); } } diff --git a/src/tracks/track.cpp b/src/tracks/track.cpp index b39037420..93fe9322d 100644 --- a/src/tracks/track.cpp +++ b/src/tracks/track.cpp @@ -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++) { convertTrackToBullet(m_all_nodes[i]); + uploadNodeVertexBuffer(m_all_nodes[i]); } m_track_mesh->createPhysicalBody(m_friction); 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++) { convertTrackToBullet(m_all_nodes[i]); + uploadNodeVertexBuffer(m_all_nodes[i]); } if (m_track_mesh == NULL) @@ -2090,8 +2092,6 @@ void Track::loadTrackModel(bool reverse_track, unsigned int mode_id) } m_spherical_harmonics_textures.clear(); } - // Draw all object visible in first frame to load all textures - SP::sp_first_frame = true; #endif // !SERVER_ONLY } // loadTrackModel @@ -2563,3 +2563,19 @@ float Track::getAngle(int n) const { return DriveGraph::get()->getAngleToNext(n, 0); } // 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 diff --git a/src/tracks/track.hpp b/src/tracks/track.hpp index 47bd932e2..4117633ee 100644 --- a/src/tracks/track.hpp +++ b/src/tracks/track.hpp @@ -409,6 +409,9 @@ public: * minutes(!) in debug mode to be computed. */ 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; Track (const std::string &filename); diff --git a/src/tracks/track_object_presentation.cpp b/src/tracks/track_object_presentation.cpp index 8cae495f2..efe9731a8 100644 --- a/src/tracks/track_object_presentation.cpp +++ b/src/tracks/track_object_presentation.cpp @@ -585,17 +585,15 @@ void TrackObjectPresentationMesh::init(const XMLNode* xml_node, Track *track = Track::getCurrentTrack(); if (track && track && xml_node) track->handleAnimatedTextures(m_node, *xml_node); + Track::uploadNodeVertexBuffer(node); } 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); Track *track = Track::getCurrentTrack(); if (track && xml_node) track->handleAnimatedTextures(m_node, *xml_node); + Track::uploadNodeVertexBuffer(m_node); } if(!enabled)