]> git.lizzy.rs Git - minetest.git/blobdiff - src/client/content_cao.cpp
Fix CAO light calculation issue
[minetest.git] / src / client / content_cao.cpp
index c7ab5a3477d9f6a5635e69686b1dc484d56b2f68..e603b5a21fd9c0b13c7fa79b53fd671eecb9976f 100644 (file)
@@ -435,7 +435,7 @@ const v3f GenericCAO::getPosition() const
        return m_position;
 }
 
-const bool GenericCAO::isImmortal()
+bool GenericCAO::isImmortal() const
 {
        return itemgroup_get(getGroups(), "immortal");
 }
@@ -745,9 +745,6 @@ void GenericCAO::addToScene(ITextureSource *tsrc, scene::ISceneManager *smgr)
                m_meshnode = m_smgr->addMeshSceneNode(mesh, m_matrixnode);
                m_meshnode->grab();
                mesh->drop();
-               // Set it to use the materials of the meshbuffers directly.
-               // This is needed for changing the texture in the future
-               m_meshnode->setReadOnlyMaterials(true);
        } else if (m_prop.visual == "cube") {
                grabMatrixNode();
                scene::IMesh *mesh = createCubeMesh(v3f(BS,BS,BS));
@@ -861,7 +858,7 @@ void GenericCAO::addToScene(ITextureSource *tsrc, scene::ISceneManager *smgr)
 
 void GenericCAO::updateLight(u32 day_night_ratio)
 {
-       if (m_glow < 0)
+       if (m_prop.glow < 0)
                return;
 
        u16 light_at_pos = 0;
@@ -875,7 +872,7 @@ void GenericCAO::updateLight(u32 day_night_ratio)
                MapNode n = m_env->getMap().getNode(pos[i], &this_ok);
                if (this_ok) {
                        u16 this_light = getInteriorLight(n, 0, m_client->ndef());
-                       u8 this_light_intensity = MYMAX(this_light & 0xFF, (this_light >> 8) && 0xFF);
+                       u8 this_light_intensity = MYMAX(this_light & 0xFF, this_light >> 8);
                        if (this_light_intensity > light_at_pos_intensity) {
                                light_at_pos = this_light;
                                light_at_pos_intensity = this_light_intensity;
@@ -886,7 +883,7 @@ void GenericCAO::updateLight(u32 day_night_ratio)
        if (!pos_ok)
                light_at_pos = LIGHT_SUN;
 
-       video::SColor light = encode_light(light_at_pos, m_glow);
+       video::SColor light = encode_light(light_at_pos, m_prop.glow);
        if (!m_enable_shaders)
                final_color_blend(&light, light_at_pos, day_night_ratio);
 
@@ -908,12 +905,8 @@ void GenericCAO::setNodeLight(const video::SColor &light_color)
                if (m_prop.visual == "upright_sprite") {
                        if (!m_meshnode)
                                return;
-
-                       scene::IMesh *mesh = m_meshnode->getMesh();
-                       for (u32 i = 0; i < mesh->getMeshBufferCount(); ++i) {
-                               scene::IMeshBuffer *buf = mesh->getMeshBuffer(i);
-                               buf->getMaterial().EmissiveColor = light_color;
-                       }
+                       for (u32 i = 0; i < m_meshnode->getMaterialCount(); ++i)
+                               m_meshnode->getMaterial(i).EmissiveColor = light_color;
                } else {
                        scene::ISceneNode *node = getSceneNode();
                        if (!node)
@@ -1326,7 +1319,6 @@ void GenericCAO::updateTextures(std::string mod)
 
        m_previous_texture_modifier = m_current_texture_modifier;
        m_current_texture_modifier = mod;
-       m_glow = m_prop.glow;
 
        video::ITexture *shadow_texture = nullptr;
        if (auto shadow = RenderingEngine::get_shadow_renderer())
@@ -1455,23 +1447,23 @@ void GenericCAO::updateTextures(std::string mod)
                                if (!m_prop.textures.empty())
                                        tname = m_prop.textures[0];
                                tname += mod;
-                               scene::IMeshBuffer *buf = mesh->getMeshBuffer(0);
-                               buf->getMaterial().setTexture(0,
+                               auto& material = m_meshnode->getMaterial(0);
+                               material.setTexture(0,
                                                tsrc->getTextureForMesh(tname));
-                               buf->getMaterial().setTexture(TEXTURE_LAYER_SHADOW, shadow_texture);
+                               material.setTexture(TEXTURE_LAYER_SHADOW, shadow_texture);
 
                                // This allows setting per-material colors. However, until a real lighting
                                // system is added, the code below will have no effect. Once MineTest
                                // has directional lighting, it should work automatically.
                                if(!m_prop.colors.empty()) {
-                                       buf->getMaterial().AmbientColor = m_prop.colors[0];
-                                       buf->getMaterial().DiffuseColor = m_prop.colors[0];
-                                       buf->getMaterial().SpecularColor = m_prop.colors[0];
+                                       material.AmbientColor = m_prop.colors[0];
+                                       material.DiffuseColor = m_prop.colors[0];
+                                       material.SpecularColor = m_prop.colors[0];
                                }
 
-                               buf->getMaterial().setFlag(video::EMF_TRILINEAR_FILTER, use_trilinear_filter);
-                               buf->getMaterial().setFlag(video::EMF_BILINEAR_FILTER, use_bilinear_filter);
-                               buf->getMaterial().setFlag(video::EMF_ANISOTROPIC_FILTER, use_anisotropic_filter);
+                               material.setFlag(video::EMF_TRILINEAR_FILTER, use_trilinear_filter);
+                               material.setFlag(video::EMF_BILINEAR_FILTER, use_bilinear_filter);
+                               material.setFlag(video::EMF_ANISOTROPIC_FILTER, use_anisotropic_filter);
                        }
                        {
                                std::string tname = "no_texture.png";
@@ -1480,30 +1472,30 @@ void GenericCAO::updateTextures(std::string mod)
                                else if (!m_prop.textures.empty())
                                        tname = m_prop.textures[0];
                                tname += mod;
-                               scene::IMeshBuffer *buf = mesh->getMeshBuffer(1);
-                               buf->getMaterial().setTexture(0,
+                               auto& material = m_meshnode->getMaterial(1);
+                               material.setTexture(0,
                                                tsrc->getTextureForMesh(tname));
-                               buf->getMaterial().setTexture(TEXTURE_LAYER_SHADOW, shadow_texture);
+                               material.setTexture(TEXTURE_LAYER_SHADOW, shadow_texture);
 
                                // This allows setting per-material colors. However, until a real lighting
                                // system is added, the code below will have no effect. Once MineTest
                                // has directional lighting, it should work automatically.
                                if (m_prop.colors.size() >= 2) {
-                                       buf->getMaterial().AmbientColor = m_prop.colors[1];
-                                       buf->getMaterial().DiffuseColor = m_prop.colors[1];
-                                       buf->getMaterial().SpecularColor = m_prop.colors[1];
+                                       material.AmbientColor = m_prop.colors[1];
+                                       material.DiffuseColor = m_prop.colors[1];
+                                       material.SpecularColor = m_prop.colors[1];
                                } else if (!m_prop.colors.empty()) {
-                                       buf->getMaterial().AmbientColor = m_prop.colors[0];
-                                       buf->getMaterial().DiffuseColor = m_prop.colors[0];
-                                       buf->getMaterial().SpecularColor = m_prop.colors[0];
+                                       material.AmbientColor = m_prop.colors[0];
+                                       material.DiffuseColor = m_prop.colors[0];
+                                       material.SpecularColor = m_prop.colors[0];
                                }
 
-                               buf->getMaterial().setFlag(video::EMF_TRILINEAR_FILTER, use_trilinear_filter);
-                               buf->getMaterial().setFlag(video::EMF_BILINEAR_FILTER, use_bilinear_filter);
-                               buf->getMaterial().setFlag(video::EMF_ANISOTROPIC_FILTER, use_anisotropic_filter);
+                               material.setFlag(video::EMF_TRILINEAR_FILTER, use_trilinear_filter);
+                               material.setFlag(video::EMF_BILINEAR_FILTER, use_bilinear_filter);
+                               material.setFlag(video::EMF_ANISOTROPIC_FILTER, use_anisotropic_filter);
                        }
                        // Set mesh color (only if lighting is disabled)
-                       if (!m_prop.colors.empty() && m_glow < 0)
+                       if (!m_prop.colors.empty() && m_prop.glow < 0)
                                setMeshColor(mesh, m_prop.colors[0]);
                }
        }
@@ -1977,20 +1969,17 @@ void GenericCAO::updateMeshCulling()
 
        const bool hidden = m_client->getCamera()->getCameraMode() == CAMERA_MODE_FIRST;
 
-       if (m_meshnode && m_prop.visual == "upright_sprite") {
-               u32 buffers = m_meshnode->getMesh()->getMeshBufferCount();
-               for (u32 i = 0; i < buffers; i++) {
-                       video::SMaterial &mat = m_meshnode->getMesh()->getMeshBuffer(i)->getMaterial();
-                       // upright sprite has no backface culling
-                       mat.setFlag(video::EMF_FRONT_FACE_CULLING, hidden);
-               }
-               return;
-       }
-
        scene::ISceneNode *node = getSceneNode();
+
        if (!node)
                return;
 
+       if (m_prop.visual == "upright_sprite") {
+               // upright sprite has no backface culling
+               node->setMaterialFlag(video::EMF_FRONT_FACE_CULLING, hidden);
+               return;
+       }
+
        if (hidden) {
                // Hide the mesh by culling both front and
                // back faces. Serious hackyness but it works for our