summaryrefslogtreecommitdiffstats
path: root/crawl-ref/source/tilebuf.cc
diff options
context:
space:
mode:
authorEnne Walker <ennewalker@users.sourceforge.net>2010-02-07 12:13:51 -0500
committerEnne Walker <ennewalker@users.sourceforge.net>2010-02-07 12:21:54 -0500
commit8cdc8ec710e9a4eef6c11b09684b936f46d86607 (patch)
tree5397ea085c4810388e897937f63e94ac8865463c /crawl-ref/source/tilebuf.cc
parenta4b097865af78dbcd841f264bac1b83847f91b53 (diff)
downloadcrawl-ref-8cdc8ec710e9a4eef6c11b09684b936f46d86607.tar.gz
crawl-ref-8cdc8ec710e9a4eef6c11b09684b936f46d86607.zip
[470] Fix opaque white shallow water in tiles.
Alpha testing is apparently not a dependable feature of OpenGL. Instead, provide an alternate method of drawing submerged tiles that does not depend on it. The older (better looking, in my opinion) behavior can be enabled via an option. It's off by default, so that folks don't file bug reports about shallow water.
Diffstat (limited to 'crawl-ref/source/tilebuf.cc')
-rw-r--r--crawl-ref/source/tilebuf.cc93
1 files changed, 58 insertions, 35 deletions
diff --git a/crawl-ref/source/tilebuf.cc b/crawl-ref/source/tilebuf.cc
index edaa3a4596..e39e0cd21c 100644
--- a/crawl-ref/source/tilebuf.cc
+++ b/crawl-ref/source/tilebuf.cc
@@ -464,11 +464,13 @@ void ColouredTileBuffer::add(int idx, int x, int y, int z,
SubmergedTileBuffer::SubmergedTileBuffer(const TilesTexture *tex,
int mask_idx, int above_max,
- int below_min) :
+ int below_min,
+ bool better_trans) :
m_mask_idx(mask_idx),
m_above_max(above_max),
m_below_min(below_min),
m_max_z(-1000),
+ m_better_trans(better_trans),
m_below_water(tex),
m_mask(tex),
m_above_water(tex)
@@ -496,14 +498,25 @@ void SubmergedTileBuffer::add(int idx, int x, int y, int z, bool submerged,
if (submerged)
{
- m_below_water.add(idx, x, y, z, ox, oy, m_below_min, ymax,
- alpha_top, alpha_bottom);
-
- m_mask.add(m_mask_idx, x, y, 0, 0, 0, -1, -1, 255, 255);
- int above_max = (ymax == -1) ? m_above_max
- : std::min(ymax, m_above_max);
- m_above_water.add(idx, x, y, z, ox, oy, -1, above_max,
- alpha_top, alpha_top);
+ if (m_better_trans)
+ {
+ m_below_water.add(idx, x, y, z, ox, oy, m_below_min, ymax,
+ alpha_top, alpha_bottom);
+
+ m_mask.add(m_mask_idx, x, y, 0, 0, 0, -1, -1, 255, 255);
+ int above_max = (ymax == -1) ? m_above_max
+ : std::min(ymax, m_above_max);
+ m_above_water.add(idx, x, y, z, ox, oy, -1, above_max,
+ alpha_top, alpha_top);
+ }
+ else
+ {
+ int water_level = (m_above_max + m_below_min) / 2;
+ m_below_water.add(idx, x, y, z, ox, oy, water_level, ymax,
+ alpha_top, alpha_bottom);
+ m_above_water.add(idx, x, y, z, ox, oy, -1, water_level,
+ alpha_top, alpha_top);
+ }
}
else
{
@@ -514,32 +527,42 @@ void SubmergedTileBuffer::add(int idx, int x, int y, int z, bool submerged,
void SubmergedTileBuffer::draw() const
{
- // First, draw anything below water. Alpha blending is turned on,
- // so these tiles will blend with anything previously drawn.
- m_below_water.draw();
-
- // Second, draw all of the mask tiles. The mask is white (255,255,255,255)
- // above water and transparent (0,0,0,0) below water.
- //
- // Alpha testing is turned on with a ref value of 255, so none of the
- // white pixels will be drawn because they will culled by alpha testing.
- // The transparent pixels below water will be "drawn", but because they
- // are fully transparent, they will not affect any colours on screen.
- // Instead, they will will set the z-buffer to a z-value (depth) that is
- // greater than the closest depth in either the below or above buffers.
- // Because all of the above water tiles are at lower z-values than this
- // maximum, they will not draw over these transparent pixels, effectively
- // masking them out. (My kingdom for a shader.)
-
- glPushMatrix();
- glTranslatef(0, 0, m_max_z + 1);
- m_mask.draw();
- glPopMatrix();
-
- // Now, draw all the above water tiles. Some of these may draw over top
- // of part of the below water tiles, but that's fine as the mask will
- // take care of only drawing the correct parts.
- m_above_water.draw();
+ if (m_better_trans)
+ {
+ // First, draw anything below water. Alpha blending is turned on,
+ // so these tiles will blend with anything previously drawn.
+ m_below_water.draw();
+
+ // Second, draw all of the mask tiles. The mask is white
+ // (255,255,255,255) above water and transparent (0,0,0,0) below water.
+ //
+ // Alpha testing is turned on with a ref value of 255, so none of the
+ // white pixels will be drawn because they will culled by alpha
+ // testing. The transparent pixels below water will be "drawn", but
+ // because they are fully transparent, they will not affect any colours
+ // on screen. Instead, they will will set the z-buffer to a z-value
+ // (depth) that is greater than the closest depth in either the below
+ // or above buffers. Because all of the above water tiles are at lower
+ // z-values than this maximum, they will not draw over these
+ // transparent pixels, effectively masking them out. (My kingdom for a
+ // shader.)
+ glPushMatrix();
+ glTranslatef(0, 0, m_max_z + 1);
+ m_mask.draw();
+ glPopMatrix();
+
+ // Now, draw all the above water tiles. Some of these may draw over
+ // top of part of the below water tiles, but that's fine as the mask
+ // will take care of only drawing the correct parts.
+ m_above_water.draw();
+ }
+ else
+ {
+ m_below_water.draw();
+ m_above_water.draw();
+
+ ASSERT(m_mask.size() == 0);
+ }
}
void SubmergedTileBuffer::clear()