]> git.lizzy.rs Git - dragonfireclient.git/blobdiff - src/mapblock_mesh.cpp
Make nametag removable with set_nametag_attributes (#5021)
[dragonfireclient.git] / src / mapblock_mesh.cpp
index e1ec50ab08ff9946528b2eb690d999130a97fc94..143adb410f006bee1fc10bd6c52f6b5f047ecaec 100644 (file)
@@ -23,7 +23,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "map.h"
 #include "profiler.h"
 #include "nodedef.h"
-#include "gamedef.h"
 #include "mesh.h"
 #include "minimap.h"
 #include "content_mapblock.h"
@@ -43,14 +42,14 @@ static void applyFacesShading(video::SColor &color, const float factor)
        MeshMakeData
 */
 
-MeshMakeData::MeshMakeData(IGameDef *gamedef, bool use_shaders,
+MeshMakeData::MeshMakeData(Client *client, bool use_shaders,
                bool use_tangent_vertices):
        m_vmanip(),
        m_blockpos(-1337,-1337,-1337),
        m_crack_pos_relative(-1337, -1337, -1337),
        m_smooth_lighting(false),
        m_show_hud(false),
-       m_gamedef(gamedef),
+       m_client(client),
        m_use_shaders(use_shaders),
        m_use_tangent_vertices(use_tangent_vertices)
 {}
@@ -233,7 +232,7 @@ static u16 getSmoothLightCombined(v3s16 p, MeshMakeData *data)
                v3s16(1,1,1),
        };
 
-       INodeDefManager *ndef = data->m_gamedef->ndef();
+       INodeDefManager *ndef = data->m_client->ndef();
 
        u16 ambient_occlusion = 0;
        u16 light_count = 0;
@@ -664,7 +663,7 @@ static u8 face_contents(content_t m1, content_t m2, bool *equivalent,
 */
 TileSpec getNodeTileN(MapNode mn, v3s16 p, u8 tileindex, MeshMakeData *data)
 {
-       INodeDefManager *ndef = data->m_gamedef->ndef();
+       INodeDefManager *ndef = data->m_client->ndef();
        TileSpec spec = ndef->get(mn).tiles[tileindex];
        // Apply temporary crack
        if (p == data->m_crack_pos_relative)
@@ -677,7 +676,7 @@ TileSpec getNodeTileN(MapNode mn, v3s16 p, u8 tileindex, MeshMakeData *data)
 */
 TileSpec getNodeTile(MapNode mn, v3s16 p, v3s16 dir, MeshMakeData *data)
 {
-       INodeDefManager *ndef = data->m_gamedef->ndef();
+       INodeDefManager *ndef = data->m_client->ndef();
 
        // Direction must be (1,0,0), (-1,0,0), (0,1,0), (0,-1,0),
        // (0,0,1), (0,0,-1) or (0,0,0)
@@ -734,7 +733,7 @@ TileSpec getNodeTile(MapNode mn, v3s16 p, v3s16 dir, MeshMakeData *data)
        u16 tile_index=facedir*16 + dir_i;
        TileSpec spec = getNodeTileN(mn, p, dir_to_tile[tile_index], data);
        spec.rotation=dir_to_tile[tile_index + 1];
-       spec.texture = data->m_gamedef->tsrc()->getTexture(spec.texture_id);
+       spec.texture = data->m_client->tsrc()->getTexture(spec.texture_id);
        return spec;
 }
 
@@ -753,7 +752,7 @@ static void getTileInfo(
        )
 {
        VoxelManipulator &vmanip = data->m_vmanip;
-       INodeDefManager *ndef = data->m_gamedef->ndef();
+       INodeDefManager *ndef = data->m_client->ndef();
        v3s16 blockpos_nodes = data->m_blockpos * MAP_BLOCKSIZE;
 
        MapNode &n0 = vmanip.getNodeRefUnsafe(blockpos_nodes + p);
@@ -839,7 +838,7 @@ static void updateFastFaceRow(
 {
        v3s16 p = startpos;
 
-       u16 continuous_tiles_count = 0;
+       u16 continuous_tiles_count = 1;
 
        bool makes_face = false;
        v3s16 p_corrected;
@@ -889,8 +888,8 @@ static void updateFastFaceRow(
                                        && (tile.material_flags & MATERIAL_FLAG_TILEABLE_HORIZONTAL)
                                        && (tile.material_flags & MATERIAL_FLAG_TILEABLE_VERTICAL)) {
                                next_is_different = false;
-                       }
-                       else{
+                               continuous_tiles_count++;
+                       } else {
                                /*if(makes_face){
                                        g_profiler->add("Meshgen: diff: next_makes_face != makes_face",
                                                        next_makes_face != makes_face ? 1 : 0);
@@ -915,8 +914,6 @@ static void updateFastFaceRow(
                                g_profiler->add("Meshgen: diff: last position", 1);*/
                }
 
-               continuous_tiles_count++;
-
                if(next_is_different)
                {
                        /*
@@ -928,8 +925,6 @@ static void updateFastFaceRow(
                                v3f pf(p_corrected.X, p_corrected.Y, p_corrected.Z);
                                // Center point of face (kind of)
                                v3f sp = pf - ((f32)continuous_tiles_count / 2.0 - 0.5) * translate_dir_f;
-                               if(continuous_tiles_count != 1)
-                                       sp += translate_dir_f;
                                v3f scale(1,1,1);
 
                                if(translate_dir.X != 0) {
@@ -952,19 +947,18 @@ static void updateFastFaceRow(
                                }
                        }
 
-                       continuous_tiles_count = 0;
-
-                       makes_face = next_makes_face;
-                       p_corrected = next_p_corrected;
-                       face_dir_corrected = next_face_dir_corrected;
-                       lights[0] = next_lights[0];
-                       lights[1] = next_lights[1];
-                       lights[2] = next_lights[2];
-                       lights[3] = next_lights[3];
-                       tile = next_tile;
-                       light_source = next_light_source;
+                       continuous_tiles_count = 1;
                }
 
+               makes_face = next_makes_face;
+               p_corrected = next_p_corrected;
+               face_dir_corrected = next_face_dir_corrected;
+               lights[0] = next_lights[0];
+               lights[1] = next_lights[1];
+               lights[2] = next_lights[2];
+               lights[3] = next_lights[3];
+               tile = next_tile;
+               light_source = next_light_source;
                p = p_next;
        }
 }
@@ -1025,9 +1019,10 @@ static void updateAllFastFaceRows(MeshMakeData *data,
 MapBlockMesh::MapBlockMesh(MeshMakeData *data, v3s16 camera_offset):
        m_mesh(new scene::SMesh()),
        m_minimap_mapblock(NULL),
-       m_gamedef(data->m_gamedef),
-       m_tsrc(m_gamedef->getTextureSource()),
-       m_shdrsrc(m_gamedef->getShaderSource()),
+       m_client(data->m_client),
+       m_driver(m_client->tsrc()->getDevice()->getVideoDriver()),
+       m_tsrc(m_client->getTextureSource()),
+       m_shdrsrc(m_client->getShaderSource()),
        m_animation_force_timer(0), // force initial animation
        m_last_crack(-1),
        m_crack_materials(),
@@ -1036,6 +1031,7 @@ MapBlockMesh::MapBlockMesh(MeshMakeData *data, v3s16 camera_offset):
 {
        m_enable_shaders = data->m_use_shaders;
        m_use_tangent_vertices = data->m_use_tangent_vertices;
+       m_enable_vbo = g_settings->getBool("enable_vbo");
 
        if (g_settings->getBool("enable_minimap")) {
                m_minimap_mapblock = new MinimapMapblock;
@@ -1134,8 +1130,7 @@ MapBlockMesh::MapBlockMesh(MeshMakeData *data, v3s16 camera_offset):
                                        &p.tile.texture_id);
                }
                // - Texture animation
-               if(p.tile.material_flags & MATERIAL_FLAG_ANIMATION_VERTICAL_FRAMES)
-               {
+               if (p.tile.material_flags & MATERIAL_FLAG_ANIMATION) {
                        // Add to MapBlockMesh in order to animate these tiles
                        m_animation_tiles[i] = p.tile;
                        m_animation_frames[i] = 0;
@@ -1247,7 +1242,7 @@ MapBlockMesh::MapBlockMesh(MeshMakeData *data, v3s16 camera_offset):
 
        if (m_use_tangent_vertices) {
                scene::IMeshManipulator* meshmanip =
-                       m_gamedef->getSceneManager()->getMeshManipulator();
+                       m_client->getSceneManager()->getMeshManipulator();
                meshmanip->recalculateTangents(m_mesh, true, false, false);
        }
 
@@ -1261,14 +1256,9 @@ MapBlockMesh::MapBlockMesh(MeshMakeData *data, v3s16 camera_offset):
 #endif
 
                // Use VBO for mesh (this just would set this for ever buffer)
-               // This will lead to infinite memory usage because or irrlicht.
-               //m_mesh->setHardwareMappingHint(scene::EHM_STATIC);
-
-               /*
-                       NOTE: If that is enabled, some kind of a queue to the main
-                       thread should be made which would call irrlicht to delete
-                       the hardware buffer and then delete the mesh
-               */
+               if (m_enable_vbo) {
+                       m_mesh->setHardwareMappingHint(scene::EHM_STATIC);
+               }
        }
 
        //std::cout<<"added "<<fastfaces.getSize()<<" faces."<<std::endl;
@@ -1282,6 +1272,12 @@ MapBlockMesh::MapBlockMesh(MeshMakeData *data, v3s16 camera_offset):
 
 MapBlockMesh::~MapBlockMesh()
 {
+       if (m_enable_vbo && m_mesh) {
+               for (u32 i = 0; i < m_mesh->getMeshBufferCount(); i++) {
+                       scene::IMeshBuffer *buf = m_mesh->getMeshBuffer(i);
+                       m_driver->removeHardwareBuffer(buf);
+               }
+       }
        m_mesh->drop();
        m_mesh = NULL;
        delete m_minimap_mapblock;
@@ -1300,10 +1296,8 @@ bool MapBlockMesh::animate(bool faraway, float time, int crack, u32 daynight_rat
        // Cracks
        if(crack != m_last_crack)
        {
-               for(std::map<u32, std::string>::iterator
-                               i = m_crack_materials.begin();
-                               i != m_crack_materials.end(); ++i)
-               {
+               for (UNORDERED_MAP<u32, std::string>::iterator i = m_crack_materials.begin();
+                               i != m_crack_materials.end(); ++i) {
                        scene::IMeshBuffer *buf = m_mesh->getMeshBuffer(i->first);
                        std::string basename = i->second;
 
@@ -1317,9 +1311,9 @@ bool MapBlockMesh::animate(bool faraway, float time, int crack, u32 daynight_rat
 
                        // If the current material is also animated,
                        // update animation info
-                       std::map<u32, TileSpec>::iterator anim_iter =
-                               m_animation_tiles.find(i->first);
-                       if(anim_iter != m_animation_tiles.end()){
+                       UNORDERED_MAP<u32, TileSpec>::iterator anim_iter =
+                                       m_animation_tiles.find(i->first);
+                       if (anim_iter != m_animation_tiles.end()){
                                TileSpec &tile = anim_iter->second;
                                tile.texture = new_texture;
                                tile.texture_id = new_texture_id;
@@ -1332,10 +1326,8 @@ bool MapBlockMesh::animate(bool faraway, float time, int crack, u32 daynight_rat
        }
 
        // Texture animation
-       for(std::map<u32, TileSpec>::iterator
-                       i = m_animation_tiles.begin();
-                       i != m_animation_tiles.end(); ++i)
-       {
+       for (UNORDERED_MAP<u32, TileSpec>::iterator i = m_animation_tiles.begin();
+                       i != m_animation_tiles.end(); ++i) {
                const TileSpec &tile = i->second;
                // Figure out current frame
                int frameoffset = m_animation_frame_offsets[i->first];
@@ -1362,6 +1354,10 @@ bool MapBlockMesh::animate(bool faraway, float time, int crack, u32 daynight_rat
        // Day-night transition
        if(!m_enable_shaders && (daynight_ratio != m_last_daynight_ratio))
        {
+               // Force reload mesh to VBO
+               if (m_enable_vbo) {
+                       m_mesh->setDirty();
+               }
                for(std::map<u32, std::map<u32, std::pair<u8, u8> > >::iterator
                                i = m_daynight_diffs.begin();
                                i != m_daynight_diffs.end(); ++i)
@@ -1387,6 +1383,9 @@ void MapBlockMesh::updateCameraOffset(v3s16 camera_offset)
 {
        if (camera_offset != m_camera_offset) {
                translateMesh(m_mesh, intToFloat(m_camera_offset-camera_offset, BS));
+               if (m_enable_vbo) {
+                       m_mesh->setDirty();
+               }
                m_camera_offset = camera_offset;
        }
 }
@@ -1438,7 +1437,7 @@ void MeshCollector::append(const TileSpec &tile,
                                vertices[i].Color, vertices[i].TCoords);
                        p->vertices.push_back(vert);
                }
-       } 
+       }
 
        for (u32 i = 0; i < numIndices; i++) {
                u32 j = indices[i] + vertex_count;
@@ -1494,7 +1493,7 @@ void MeshCollector::append(const TileSpec &tile,
                                vertices[i].Normal, c, vertices[i].TCoords);
                        p->vertices.push_back(vert);
                }
-       } 
+       }
 
        for (u32 i = 0; i < numIndices; i++) {
                u32 j = indices[i] + vertex_count;