]> git.lizzy.rs Git - minetest.git/blobdiff - src/content_mapblock.cpp
fix screen flickering black when rendering to texture
[minetest.git] / src / content_mapblock.cpp
index 31f69e42c8c84db9b41cbdeff1882460d7c25729..aa3c061d6c6d7afe1df2ff0f5517c9872f312188 100644 (file)
@@ -25,6 +25,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "nodedef.h"
 #include "tile.h"
 #include "gamedef.h"
+#include "util/numeric.h"
+#include "util/directiontables.h"
 
 // Create a cuboid.
 //  collector - the MeshCollector for the resulting polygons
@@ -169,7 +171,7 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
                                continue;
 
                        u16 l = getInteriorLight(n, 0, data);
-                       video::SColor c = MapBlock_LightColor(f.alpha, l);
+                       video::SColor c = MapBlock_LightColor(f.alpha, l, decode_light(f.light_source));
                        
                        video::S3DVertex vertices[4] =
                        {
@@ -224,7 +226,7 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
                        // Otherwise use the light of this node (the liquid)
                        else
                                l = getInteriorLight(n, 0, data);
-                       video::SColor c = MapBlock_LightColor(f.alpha, l);
+                       video::SColor c = MapBlock_LightColor(f.alpha, l, decode_light(f.light_source));
                        
                        // Neighbor liquid levels (key = relative position)
                        // Includes current node
@@ -471,7 +473,9 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
                                                        pa_liquid.x0(), pa_liquid.y0()),
                                };
                                
-                               // This fixes a strange bug
+                               // To get backface culling right, the vertices need to go
+                               // clockwise around the front of the face. And we happened to
+                               // calculate corner levels in exact reverse order.
                                s32 corner_resolve[4] = {3,2,1,0};
 
                                for(s32 i=0; i<4; i++)
@@ -482,6 +486,52 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
                                        vertices[i].Pos.Y += corner_levels[j];
                                        vertices[i].Pos += intToFloat(p, BS);
                                }
+                               
+                               // Default downwards-flowing texture animation goes from 
+                               // -Z towards +Z, thus the direction is +Z.
+                               // Rotate texture to make animation go in flow direction
+                               // Positive if liquid moves towards +Z
+                               int dz = (corner_levels[side_corners[3][0]] +
+                                               corner_levels[side_corners[3][1]]) -
+                                               (corner_levels[side_corners[2][0]] +
+                                               corner_levels[side_corners[2][1]]);
+                               // Positive if liquid moves towards +X
+                               int dx = (corner_levels[side_corners[1][0]] +
+                                               corner_levels[side_corners[1][1]]) -
+                                               (corner_levels[side_corners[0][0]] +
+                                               corner_levels[side_corners[0][1]]);
+                               // -X
+                               if(-dx >= abs(dz))
+                               {
+                                       v2f t = vertices[0].TCoords;
+                                       vertices[0].TCoords = vertices[1].TCoords;
+                                       vertices[1].TCoords = vertices[2].TCoords;
+                                       vertices[2].TCoords = vertices[3].TCoords;
+                                       vertices[3].TCoords = t;
+                               }
+                               // +X
+                               if(dx >= abs(dz))
+                               {
+                                       v2f t = vertices[0].TCoords;
+                                       vertices[0].TCoords = vertices[3].TCoords;
+                                       vertices[3].TCoords = vertices[2].TCoords;
+                                       vertices[2].TCoords = vertices[1].TCoords;
+                                       vertices[1].TCoords = t;
+                               }
+                               // -Z
+                               if(-dz >= abs(dx))
+                               {
+                                       v2f t = vertices[0].TCoords;
+                                       vertices[0].TCoords = vertices[3].TCoords;
+                                       vertices[3].TCoords = vertices[2].TCoords;
+                                       vertices[2].TCoords = vertices[1].TCoords;
+                                       vertices[1].TCoords = t;
+                                       t = vertices[0].TCoords;
+                                       vertices[0].TCoords = vertices[3].TCoords;
+                                       vertices[3].TCoords = vertices[2].TCoords;
+                                       vertices[2].TCoords = vertices[1].TCoords;
+                                       vertices[1].TCoords = t;
+                               }
 
                                u16 indices[] = {0,1,2,2,3,0};
                                // Add to mesh collector
@@ -494,7 +544,7 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
                        AtlasPointer ap = tile.texture;
 
                        u16 l = getInteriorLight(n, 1, data);
-                       video::SColor c = MapBlock_LightColor(255, l);
+                       video::SColor c = MapBlock_LightColor(255, l, decode_light(f.light_source));
 
                        for(u32 j=0; j<6; j++)
                        {
@@ -554,7 +604,7 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
                        AtlasPointer pa_leaves = tile_leaves.texture;
 
                        u16 l = getInteriorLight(n, 1, data);
-                       video::SColor c = MapBlock_LightColor(255, l);
+                       video::SColor c = MapBlock_LightColor(255, l, decode_light(f.light_source));
 
                        v3f pos = intToFloat(p, BS);
                        aabb3f box(-BS/2,-BS/2,-BS/2,BS/2,BS/2,BS/2);
@@ -588,7 +638,8 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
 
                        AtlasPointer ap = tile.texture;
 
-                       video::SColor c(255,255,255,255);
+                       u16 l = getInteriorLight(n, 1, data);
+                       video::SColor c = MapBlock_LightColor(255, l, decode_light(f.light_source));
 
                        // Wall at X+ of node
                        video::S3DVertex vertices[4] =
@@ -633,7 +684,7 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
                        AtlasPointer ap = tile.texture;
 
                        u16 l = getInteriorLight(n, 0, data);
-                       video::SColor c = MapBlock_LightColor(255, l);
+                       video::SColor c = MapBlock_LightColor(255, l, decode_light(f.light_source));
                                
                        float d = (float)BS/16;
                        // Wall at X+ of node
@@ -680,7 +731,7 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
                        AtlasPointer ap = tile.texture;
                        
                        u16 l = getInteriorLight(n, 1, data);
-                       video::SColor c = MapBlock_LightColor(255, l);
+                       video::SColor c = MapBlock_LightColor(255, l, decode_light(f.light_source));
 
                        for(u32 j=0; j<4; j++)
                        {
@@ -743,7 +794,7 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
                                        tile.texture.id) + "^[transformR90");
                                        
                        u16 l = getInteriorLight(n, 1, data);
-                       video::SColor c = MapBlock_LightColor(255, l);
+                       video::SColor c = MapBlock_LightColor(255, l, decode_light(f.light_source));
 
                        const f32 post_rad=(f32)BS/8;
                        const f32 bar_rad=(f32)BS/16;
@@ -936,6 +987,7 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
                                        angle = -90;
                                break;
                        default:
+                               break;
                        }
 
                        TileSpec tile = getNodeTileN(n, p, tileindex, data);
@@ -945,7 +997,7 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
                        AtlasPointer ap = tile.texture;
                        
                        u16 l = getInteriorLight(n, 0, data);
-                       video::SColor c = MapBlock_LightColor(255, l);
+                       video::SColor c = MapBlock_LightColor(255, l, decode_light(f.light_source));
 
                        float d = (float)BS/64;
                        
@@ -975,6 +1027,63 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
                        u16 indices[] = {0,1,2,2,3,0};
                        collector.append(tile, vertices, 4, indices, 6);
                break;}
+               case NDT_NODEBOX:
+               {
+                       static const v3s16 tile_dirs[6] = {
+                               v3s16(0, 1, 0),
+                               v3s16(0, -1, 0),
+                               v3s16(1, 0, 0),
+                               v3s16(-1, 0, 0),
+                               v3s16(0, 0, 1),
+                               v3s16(0, 0, -1)
+                       };
+
+                       TileSpec tiles[6];
+                       for(int i = 0; i < 6; i++)
+                       {
+                               // Handles facedir rotation for textures
+                               tiles[i] = getNodeTile(n, p, tile_dirs[i], data);
+                       }
+
+                       u16 l = getInteriorLight(n, 0, data);
+                       video::SColor c = MapBlock_LightColor(255, l, decode_light(f.light_source));
+
+                       v3f pos = intToFloat(p, BS);
+
+                       std::vector<aabb3f> boxes = n.getNodeBoxes(nodedef);
+                       for(std::vector<aabb3f>::iterator
+                                       i = boxes.begin();
+                                       i != boxes.end(); i++)
+                       {
+                               aabb3f box = *i;
+                               box.MinEdge += pos;
+                               box.MaxEdge += pos;
+
+                               // Compute texture coords
+                               f32 tx1 = (i->MinEdge.X/BS)+0.5;
+                               f32 ty1 = (i->MinEdge.Y/BS)+0.5;
+                               f32 tz1 = (i->MinEdge.Z/BS)+0.5;
+                               f32 tx2 = (i->MaxEdge.X/BS)+0.5;
+                               f32 ty2 = (i->MaxEdge.Y/BS)+0.5;
+                               f32 tz2 = (i->MaxEdge.Z/BS)+0.5;
+                               f32 txc[24] = {
+                                       // up
+                                       tx1, 1-tz2, tx2, 1-tz1,
+                                       // down
+                                       tx1, tz1, tx2, tz2,
+                                       // right
+                                       tz1, 1-ty2, tz2, 1-ty1,
+                                       // left
+                                       1-tz2, 1-ty2, 1-tz1, 1-ty1,
+                                       // back
+                                       1-tx2, 1-ty2, 1-tx1, 1-ty1,
+                                       // front
+                                       tx1, 1-ty2, tx2, 1-ty1,
+                               };
+
+                               makeCuboid(&collector, box, tiles, 6, c, txc);
+                       }
+               break;}
                }
        }
 }