use depth clipping again but only when proxy tiles are drawn

This commit is contained in:
Hannes Janetzek 2014-01-29 17:52:03 +01:00
parent 5235e8483b
commit 20ddff3d26
3 changed files with 67 additions and 25 deletions

View File

@ -94,7 +94,7 @@ public abstract class ElementRenderer extends LayerRenderer {
while (l != null) { while (l != null) {
if (l.type == POLYGON) { if (l.type == POLYGON) {
l = PolygonLayer.Renderer.draw(pos, l, m, true, 1, false); l = PolygonLayer.Renderer.draw(pos, l, m, true, 1, 0);
continue; continue;
} }
if (l.type == LINE) { if (l.type == LINE) {

View File

@ -279,7 +279,7 @@ public final class PolygonLayer extends RenderElement {
* next layer * next layer
*/ */
public static RenderElement draw(MapPosition pos, RenderElement renderElement, public static RenderElement draw(MapPosition pos, RenderElement renderElement,
Matrices m, boolean first, float div, boolean clip) { Matrices m, boolean first, float div, int clip) {
GLState.test(false, true); GLState.test(false, true);
@ -305,7 +305,7 @@ public final class PolygonLayer extends RenderElement {
continue; continue;
if (cur == start) { if (cur == start) {
drawStencilRegion(first); drawStencilRegion(first, clip);
first = false; first = false;
// op for stencil method polygon drawing // op for stencil method polygon drawing
@ -329,9 +329,9 @@ public final class PolygonLayer extends RenderElement {
if (cur > 0) if (cur > 0)
fillPolygons(m, start, cur, zoom, scale, div); fillPolygons(m, start, cur, zoom, scale, div);
if (clip) { if (clip > 0) {
if (first) { if (first) {
drawStencilRegion(first); drawStencilRegion(first, clip);
// disable writes to stencil buffer // disable writes to stencil buffer
GL.glStencilMask(0x00); GL.glStencilMask(0x00);
// enable writes to color buffer // enable writes to color buffer
@ -350,7 +350,7 @@ public final class PolygonLayer extends RenderElement {
public static void clip(Matrices m) { public static void clip(Matrices m) {
setShader(polyShader, m); setShader(polyShader, m);
drawStencilRegion(true); drawStencilRegion(true, 1);
// disable writes to stencil buffer // disable writes to stencil buffer
GL.glStencilMask(0x00); GL.glStencilMask(0x00);
// enable writes to color buffer // enable writes to color buffer
@ -364,7 +364,7 @@ public final class PolygonLayer extends RenderElement {
* @param first in the first run the clip region is set based on * @param first in the first run the clip region is set based on
* depth buffer and depth buffer is updated * depth buffer and depth buffer is updated
*/ */
static void drawStencilRegion(boolean first) { static void drawStencilRegion(boolean first, int mode) {
// disable drawing to color buffer // disable drawing to color buffer
GL.glColorMask(false, false, false, false); GL.glColorMask(false, false, false, false);
@ -373,6 +373,21 @@ public final class PolygonLayer extends RenderElement {
GL.glStencilMask(0xFF); GL.glStencilMask(0xFF);
if (first) { if (first) {
// clear previous clip-region from stencil buffer
//GL.glClear(GL20.GL_STENCIL_BUFFER_BIT);
// Draw clip-region into depth and stencil buffer
// this is used for tile line and polygon layers.
// Depth offset is increased for each tile. Together
// with depth test (GL_LESS) this ensures to only
// draw where no other tile has drawn yet.
//GL.glEnable(GL20.GL_POLYGON_OFFSET_FILL);
if (mode > 1) {
// test GL_LESS and write to depth buffer
GLState.test(true, true);
GL.glDepthMask(true);
}
// always pass stencil test and set clip bit // always pass stencil test and set clip bit
GL.glStencilFunc(GL20.GL_ALWAYS, CLIP_BIT, 0x00); GL.glStencilFunc(GL20.GL_ALWAYS, CLIP_BIT, 0x00);
} else { } else {
@ -388,6 +403,12 @@ public final class PolygonLayer extends RenderElement {
GL.glDrawArrays(GL20.GL_TRIANGLE_STRIP, 0, 4); GL.glDrawArrays(GL20.GL_TRIANGLE_STRIP, 0, 4);
if (first) { if (first) {
if (mode > 1) {
// dont modify depth buffer
GL.glDepthMask(false);
// test only stencil
GLState.test(false, true);
}
GL.glStencilFunc(GL20.GL_EQUAL, CLIP_BIT, CLIP_BIT); GL.glStencilFunc(GL20.GL_EQUAL, CLIP_BIT, CLIP_BIT);
} }
} }

View File

@ -369,6 +369,7 @@ public class TileRenderer extends LayerRenderer {
// tile twice per frame. // tile twice per frame.
private int mDrawSerial = 0; private int mDrawSerial = 0;
private Matrices mMatrices; private Matrices mMatrices;
private int mClipMode = 0;
/** /**
* Draw tiles: * Draw tiles:
@ -382,6 +383,16 @@ public class TileRenderer extends LayerRenderer {
mMatrices = m; mMatrices = m;
mClipMode = 1;
for (int i = 0; i < tileCnt; i++) {
MapTile t = tiles[i];
if (t.isVisible && t.state != STATE_READY) {
mClipMode = 2;
break;
}
}
/** draw visible tiles */ /** draw visible tiles */
for (int i = 0; i < tileCnt; i++) { for (int i = 0; i < tileCnt; i++) {
MapTile t = tiles[i]; MapTile t = tiles[i];
@ -395,11 +406,18 @@ public class TileRenderer extends LayerRenderer {
* was drawn to depth buffer. * was drawn to depth buffer.
* TODO draw proxies for placeholder * TODO draw proxies for placeholder
*/ */
double scale = pos.getZoomScale(); if (mClipMode > 1) {
mClipMode = 3;
//GL.glClear(GL20.GL_DEPTH_BUFFER_BIT);
GL.glDepthFunc(GL20.GL_LESS);
double scale = pos.getZoomScale();
for (int i = 0; i < tileCnt; i++) { for (int i = 0; i < tileCnt; i++) {
MapTile t = tiles[i]; MapTile t = tiles[i];
if (t.isVisible && (t.state != STATE_READY) && (t.holder == null)) { if (t.isVisible
&& (t.state != STATE_READY)
&& (t.holder == null)) {
boolean preferParent = (scale > 1.5) boolean preferParent = (scale > 1.5)
|| (pos.zoomLevel - t.zoomLevel < 0); || (pos.zoomLevel - t.zoomLevel < 0);
drawProxyTile(t, pos, true, preferParent); drawProxyTile(t, pos, true, preferParent);
@ -409,13 +427,15 @@ public class TileRenderer extends LayerRenderer {
/** draw grandparents */ /** draw grandparents */
for (int i = 0; i < tileCnt; i++) { for (int i = 0; i < tileCnt; i++) {
MapTile t = tiles[i]; MapTile t = tiles[i];
if (t.isVisible && (t.state != STATE_READY) && (t.holder == null)) if (t.isVisible
&& (t.state != STATE_READY)
&& (t.holder == null))
drawProxyTile(t, pos, false, false); drawProxyTile(t, pos, false, false);
} }
GL.glDepthMask(false);
}
/** make sure stencil buffer write is disabled */ /** make sure stencil buffer write is disabled */
GL.glStencilMask(0x00); GL.glStencilMask(0x00);
GL.glDepthMask(false);
mDrawSerial++; mDrawSerial++;
mMatrices = null; mMatrices = null;
@ -452,17 +472,18 @@ public class TileRenderer extends LayerRenderer {
m.mvp.multiplyLhs(m.viewproj); m.mvp.multiplyLhs(m.viewproj);
boolean clipped = false; boolean clipped = false;
int mode = mClipMode;
RenderElement l = t.layers.getBaseLayers(); RenderElement l = t.layers.getBaseLayers();
while (l != null) { while (l != null) {
if (l.type == POLYGON) { if (l.type == POLYGON) {
l = PolygonLayer.Renderer.draw(pos, l, m, !clipped, div, true); l = PolygonLayer.Renderer.draw(pos, l, m, !clipped, div, mode);
clipped = true; clipped = true;
continue; continue;
} }
if (!clipped) { if (!clipped) {
// draw stencil buffer clip region // draw stencil buffer clip region
PolygonLayer.Renderer.draw(pos, null, m, true, div, true); PolygonLayer.Renderer.draw(pos, null, m, true, div, mode);
clipped = true; clipped = true;
} }
if (l.type == LINE) { if (l.type == LINE) {
@ -484,7 +505,7 @@ public class TileRenderer extends LayerRenderer {
l = t.layers.getTextureLayers(); l = t.layers.getTextureLayers();
while (l != null) { while (l != null) {
if (!clipped) { if (!clipped) {
PolygonLayer.Renderer.draw(pos, null, m, true, div, true); PolygonLayer.Renderer.draw(pos, null, m, true, div, mode);
clipped = true; clipped = true;
} }
if (l.type == BITMAP) { if (l.type == BITMAP) {