diff options
author | PilzAdam <PilzAdam@gmx.de> | 2013-02-08 23:45:41 +0100 |
---|---|---|
committer | kwolekr <kwolekr@minetest.net> | 2013-03-17 11:28:43 -0400 |
commit | c00c8832c6c8cf9a0089a486d026d829e82741a9 (patch) | |
tree | c163285e173566c1cc4c67c6e6fbf2d023ff9054 | |
parent | 5a9fd8f433e9d2a71266dd6b76174e84a5ebaa8f (diff) | |
download | minetest-c00c8832c6c8cf9a0089a486d026d829e82741a9.tar.gz minetest-c00c8832c6c8cf9a0089a486d026d829e82741a9.tar.bz2 minetest-c00c8832c6c8cf9a0089a486d026d829e82741a9.zip |
Fix new_style_water
-rw-r--r-- | client/shaders/test_shader_2/opengl_vertex.glsl | 4 | ||||
-rw-r--r-- | src/content_mapblock.cpp | 143 |
2 files changed, 136 insertions, 11 deletions
diff --git a/client/shaders/test_shader_2/opengl_vertex.glsl b/client/shaders/test_shader_2/opengl_vertex.glsl index 80fd6d427..2881bad21 100644 --- a/client/shaders/test_shader_2/opengl_vertex.glsl +++ b/client/shaders/test_shader_2/opengl_vertex.glsl @@ -8,9 +8,7 @@ varying vec3 vPosition; void main(void)
{
- vec4 pos = gl_Vertex;
- pos.y -= 2.0;
- gl_Position = mWorldViewProj * pos;
+ gl_Position = mWorldViewProj * gl_Vertex;
vPosition = (mWorldViewProj * gl_Vertex).xyz;
diff --git a/src/content_mapblock.cpp b/src/content_mapblock.cpp index ef447da6b..0fbdda303 100644 --- a/src/content_mapblock.cpp +++ b/src/content_mapblock.cpp @@ -160,18 +160,145 @@ void mapblock_mesh_generate_special(MeshMakeData *data, Add water sources to mesh if using new style */ TileSpec tile_liquid = f.special_tiles[0]; + TileSpec tile_liquid_bfculled = getNodeTile(n, p, v3s16(0,0,0), data); AtlasPointer &pa_liquid = tile_liquid.texture; - bool top_is_air = false; - MapNode n = data->m_vmanip.getNodeNoEx(blockpos_nodes + v3s16(x,y+1,z)); - if(n.getContent() == CONTENT_AIR) - top_is_air = true; - - if(top_is_air == false) - continue; + bool top_is_same_liquid = false; + MapNode ntop = data->m_vmanip.getNodeNoEx(blockpos_nodes + v3s16(x,y+1,z)); + content_t c_flowing = nodedef->getId(f.liquid_alternative_flowing); + content_t c_source = nodedef->getId(f.liquid_alternative_source); + if(ntop.getContent() == c_flowing || ntop.getContent() == c_source) + top_is_same_liquid = true; u16 l = getInteriorLight(n, 0, data); video::SColor c = MapBlock_LightColor(f.alpha, l, decode_light(f.light_source)); + + /* + Generate sides + */ + v3s16 side_dirs[4] = { + v3s16(1,0,0), + v3s16(-1,0,0), + v3s16(0,0,1), + v3s16(0,0,-1), + }; + for(u32 i=0; i<4; i++) + { + v3s16 dir = side_dirs[i]; + + MapNode neighbor = data->m_vmanip.getNodeNoEx(blockpos_nodes + p + dir); + content_t neighbor_content = neighbor.getContent(); + const ContentFeatures &n_feat = nodedef->get(neighbor_content); + MapNode n_top = data->m_vmanip.getNodeNoEx(blockpos_nodes + p + dir+ v3s16(0,1,0)); + content_t n_top_c = n_top.getContent(); + + if(neighbor_content == CONTENT_IGNORE) + continue; + + /* + If our topside is liquid and neighbor's topside + is liquid, don't draw side face + */ + if(top_is_same_liquid && (n_top_c == c_flowing || + n_top_c == c_source || n_top_c == CONTENT_IGNORE)) + continue; + + // 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 + || neighbor_content == c_flowing); + + // Don't draw any faces if neighbor same is liquid and top is + // same liquid + if(neighbor_is_same_liquid && !top_is_same_liquid) + continue; + + // Use backface culled material if neighbor doesn't have a + // solidness of 0 + const TileSpec *current_tile = &tile_liquid; + if(n_feat.solidness != 0 || n_feat.visual_solidness != 0) + current_tile = &tile_liquid_bfculled; + + video::S3DVertex vertices[4] = + { + video::S3DVertex(-BS/2,0,BS/2,0,0,0, c, + pa_liquid.x0(), pa_liquid.y1()), + video::S3DVertex(BS/2,0,BS/2,0,0,0, c, + pa_liquid.x1(), pa_liquid.y1()), + video::S3DVertex(BS/2,0,BS/2, 0,0,0, c, + pa_liquid.x1(), pa_liquid.y0()), + video::S3DVertex(-BS/2,0,BS/2, 0,0,0, c, + pa_liquid.x0(), pa_liquid.y0()), + }; + + /* + If our topside is liquid, set upper border of face + at upper border of node + */ + if(top_is_same_liquid) + { + vertices[2].Pos.Y = 0.5*BS; + vertices[3].Pos.Y = 0.5*BS; + } + /* + Otherwise upper position of face is liquid level + */ + else + { + vertices[2].Pos.Y = (node_liquid_level-0.5)*BS; + vertices[3].Pos.Y = (node_liquid_level-0.5)*BS; + } + /* + If neighbor is liquid, lower border of face is liquid level + */ + if(neighbor_is_same_liquid) + { + vertices[0].Pos.Y = (node_liquid_level-0.5)*BS; + vertices[1].Pos.Y = (node_liquid_level-0.5)*BS; + } + /* + If neighbor is not liquid, lower border of face is + lower border of node + */ + else + { + vertices[0].Pos.Y = -0.5*BS; + vertices[1].Pos.Y = -0.5*BS; + } + + for(s32 j=0; j<4; j++) + { + if(dir == v3s16(0,0,1)) + vertices[j].Pos.rotateXZBy(0); + if(dir == v3s16(0,0,-1)) + vertices[j].Pos.rotateXZBy(180); + if(dir == v3s16(-1,0,0)) + vertices[j].Pos.rotateXZBy(90); + if(dir == v3s16(1,0,-0)) + vertices[j].Pos.rotateXZBy(-90); + + // Do this to not cause glitches when two liquids are + // side-by-side + /*if(neighbor_is_same_liquid == false){ + vertices[j].Pos.X *= 0.98; + vertices[j].Pos.Z *= 0.98; + }*/ + + vertices[j].Pos += intToFloat(p, BS); + } + + u16 indices[] = {0,1,2,2,3,0}; + // Add to mesh collector + collector.append(*current_tile, vertices, 4, indices, 6); + } + + /* + Generate top + */ + if(top_is_same_liquid) + continue; video::S3DVertex vertices[4] = { @@ -185,7 +312,7 @@ void mapblock_mesh_generate_special(MeshMakeData *data, pa_liquid.x0(), pa_liquid.y0()), }; - v3f offset(p.X, p.Y + (-0.5+node_liquid_level)*BS, p.Z); + v3f offset(p.X*BS, p.Y*BS + (-0.5+node_liquid_level)*BS, p.Z*BS); for(s32 i=0; i<4; i++) { vertices[i].Pos += offset; |