assert(content_features(n).special_material);
video::SMaterial &liquid_material =
*content_features(n).special_material;
+ video::SMaterial &liquid_material_bfculled =
+ *content_features(n).special_material2;
+
assert(content_features(n).special_atlas);
AtlasPointer &pa_liquid1 =
*content_features(n).special_atlas;
continue;
content_t neighbor_content = neighbor_contents[dir];
+ ContentFeatures &n_feat = content_features(neighbor_content);
- // Don't draw face if neighbor is not air or liquid
- if(neighbor_content != CONTENT_AIR
- && content_liquid(neighbor_content) == false)
+ // Don't draw face if neighbor is blocking the view
+ if(n_feat.solidness == 2)
continue;
bool neighbor_is_same_liquid = (neighbor_content == c_source
if(neighbor_is_same_liquid == true
&& top_is_same_liquid == false)
continue;
+
+ // Use backface culled material if neighbor doesn't have a
+ // solidness of 0
+ video::SMaterial *current_material = &liquid_material;
+ if(n_feat.solidness != 0 || n_feat.visual_solidness != 0)
+ current_material = &liquid_material_bfculled;
video::S3DVertex vertices[4] =
{
u16 indices[] = {0,1,2,2,3,0};
// Add to mesh collector
- collector.append(liquid_material, vertices, 4, indices, 6);
+ collector.append(*current_material, vertices, 4, indices, 6);
}
/*
AtlasPointer *pa_water1 = new AtlasPointer(g_texturesource->getTexture(
g_texturesource->getTextureId("water.png")));
f->special_material->setTexture(0, pa_water1->atlas);
+
+ // Flowing water material, backface culled
+ f->special_material2 = new video::SMaterial;
+ *f->special_material2 = *f->special_material;
+ f->special_material2->setFlag(video::EMF_BACK_FACE_CULLING, true);
+
f->special_atlas = pa_water1;
}
#endif
f->post_effect_color = video::SColor(64, 100, 100, 200);
if(f->special_material == NULL && g_texturesource)
{
- // Flowing water material
+ // New-style water source material (mostly unused)
f->special_material = new video::SMaterial;
f->special_material->setFlag(video::EMF_LIGHTING, false);
f->special_material->setFlag(video::EMF_BACK_FACE_CULLING, false);
f->light_propagates = false;
f->light_source = LIGHT_MAX-1;
f->solidness = 0; // Drawn separately, makes no faces
- f->visual_solidness = 2;
+ f->visual_solidness = 1; // Does not completely cover block boundaries
f->walkable = false;
f->pointable = false;
f->diggable = false;
f->special_material->setFlag(video::EMF_BILINEAR_FILTER, false);
f->special_material->setFlag(video::EMF_FOG_ENABLE, true);
f->special_material->MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF;
+
AtlasPointer *pa_lava1 = new AtlasPointer(
g_texturesource->getTexture(
g_texturesource->getTextureId("lava.png")));
f->special_material->setTexture(0, pa_lava1->atlas);
+
+ // Flowing lava material, backface culled
+ f->special_material2 = new video::SMaterial;
+ *f->special_material2 = *f->special_material;
+ f->special_material2->setFlag(video::EMF_BACK_FACE_CULLING, true);
+
f->special_atlas = pa_lava1;
}
#endif
f->post_effect_color = video::SColor(192, 255, 64, 0);
if(f->special_material == NULL && g_texturesource)
{
- // Flowing lava material
+ // New-style lava source material (mostly unused)
f->special_material = new video::SMaterial;
f->special_material->setFlag(video::EMF_LIGHTING, false);
f->special_material->setFlag(video::EMF_BACK_FACE_CULLING, false);
g_texturesource->getTexture(
g_texturesource->getTextureId("lava.png")));
f->special_material->setTexture(0, pa_lava1->atlas);
+
f->special_atlas = pa_lava1;
}
#endif
// This is hackish
content_t content0 = getNodeContent(p, n0, temp_mods);
content_t content1 = getNodeContent(p + face_dir, n1, temp_mods);
- u8 mf = face_contents(content0, content1);
+ bool equivalent = false;
+ u8 mf = face_contents(content0, content1, &equivalent);
if(mf == 0)
{
face_dir_corrected = -face_dir;
}
+ // eg. water and glass
+ if(equivalent)
+ tile.material_flags |= MATERIAL_FLAG_BACKFACE_CULLING;
+
if(smooth_lighting == false)
{
lights[0] = lights[1] = lights[2] = lights[3] =
}
+/*
+ Nodes make a face if contents differ and solidness differs.
+ Return value:
+ 0: No face
+ 1: Face uses m1's content
+ 2: Face uses m2's content
+ equivalent: Whether the blocks share the same face (eg. water and glass)
+*/
+u8 face_contents(content_t m1, content_t m2, bool *equivalent)
+{
+ *equivalent = false;
+
+ if(m1 == CONTENT_IGNORE || m2 == CONTENT_IGNORE)
+ return 0;
+
+ bool contents_differ = (m1 != m2);
+
+ // Contents don't differ for different forms of same liquid
+ if(content_liquid(m1) && content_liquid(m2)
+ && make_liquid_flowing(m1) == make_liquid_flowing(m2))
+ contents_differ = false;
+
+ u8 c1 = content_solidness(m1);
+ u8 c2 = content_solidness(m2);
+
+ bool solidness_differs = (c1 != c2);
+ bool makes_face = contents_differ && solidness_differs;
+
+ if(makes_face == false)
+ return 0;
+
+ if(c1 == 0)
+ c1 = content_features(m1).visual_solidness;
+ if(c2 == 0)
+ c2 = content_features(m2).visual_solidness;
+
+ if(c1 == c2){
+ *equivalent = true;
+ // If same solidness, liquid takes precense
+ if(content_features(m1).liquid_type != LIQUID_NONE)
+ return 1;
+ if(content_features(m2).liquid_type != LIQUID_NONE)
+ return 2;
+ }
+
+ if(c1 > c2)
+ return 1;
+ else
+ return 2;
+}
+
v3s16 facedir_rotate(u8 facedir, v3s16 dir)
{
/*
video::SColor post_effect_color;
// Special irrlicht material, used sometimes
video::SMaterial *special_material;
+ video::SMaterial *special_material2;
AtlasPointer *special_atlas;
#endif
vertex_alpha = 255;
post_effect_color = video::SColor(0, 0, 0, 0);
special_material = NULL;
+ special_material2 = NULL;
special_atlas = NULL;
#endif
param_type = CPT_NONE;
0: No face
1: Face uses m1's content
2: Face uses m2's content
+ equivalent: Whether the blocks share the same face (eg. water and glass)
*/
-inline u8 face_contents(content_t m1, content_t m2)
-{
- if(m1 == CONTENT_IGNORE || m2 == CONTENT_IGNORE)
- return 0;
-
- bool contents_differ = (m1 != m2);
-
- // Contents don't differ for different forms of same liquid
- if(content_liquid(m1) && content_liquid(m2)
- && make_liquid_flowing(m1) == make_liquid_flowing(m2))
- contents_differ = false;
-
- bool solidness_differs = (content_solidness(m1) != content_solidness(m2));
- bool makes_face = contents_differ && solidness_differs;
-
- if(makes_face == false)
- return 0;
-
- u8 c1 = content_solidness(m1);
- u8 c2 = content_solidness(m2);
-
- /*
- Special case for half-transparent content.
-
- This makes eg. the water (solidness=1) surrounding an underwater
- glass block (solidness=0, visual_solidness=1) not get drawn.
- */
- if(c1 == 1 && c2 == 0 && content_features(m2).visual_solidness != 0)
- return 0;
- if(c2 == 1 && c1 == 0 && content_features(m1).visual_solidness != 0)
- return 0;
-
- if(c1 > c2)
- return 1;
- else
- return 2;
-}
+u8 face_contents(content_t m1, content_t m2, bool *equivalent);
/*
Packs directions like (1,0,0), (1,-1,0)