PolygonLayer: separate drawing of stencil clip region
This commit is contained in:
parent
3cd2f9ea47
commit
b69923e05d
@ -1,8 +1,10 @@
|
|||||||
package org.oscim.layers.tile;
|
package org.oscim.layers.tile;
|
||||||
|
|
||||||
|
import static org.oscim.backend.GL20.GL_EQUAL;
|
||||||
import static org.oscim.layers.tile.MapTile.PROXY_GRAMPA;
|
import static org.oscim.layers.tile.MapTile.PROXY_GRAMPA;
|
||||||
import static org.oscim.layers.tile.MapTile.PROXY_PARENT;
|
import static org.oscim.layers.tile.MapTile.PROXY_PARENT;
|
||||||
import static org.oscim.layers.tile.MapTile.State.READY;
|
import static org.oscim.layers.tile.MapTile.State.READY;
|
||||||
|
import static org.oscim.renderer.MapRenderer.COORD_SCALE;
|
||||||
import static org.oscim.renderer.elements.RenderElement.BITMAP;
|
import static org.oscim.renderer.elements.RenderElement.BITMAP;
|
||||||
import static org.oscim.renderer.elements.RenderElement.HAIRLINE;
|
import static org.oscim.renderer.elements.RenderElement.HAIRLINE;
|
||||||
import static org.oscim.renderer.elements.RenderElement.LINE;
|
import static org.oscim.renderer.elements.RenderElement.LINE;
|
||||||
@ -33,7 +35,8 @@ public class VectorTileRenderer extends TileRenderer {
|
|||||||
|
|
||||||
protected int mClipMode;
|
protected int mClipMode;
|
||||||
|
|
||||||
protected GLMatrix mViewProj = new GLMatrix();
|
protected GLMatrix mClipProj = new GLMatrix();
|
||||||
|
protected GLMatrix mClipMVP = new GLMatrix();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Current number of frames drawn, used to not draw a
|
* Current number of frames drawn, used to not draw a
|
||||||
@ -47,10 +50,10 @@ public class VectorTileRenderer extends TileRenderer {
|
|||||||
|
|
||||||
/* discard depth projection from tilt, depth buffer
|
/* discard depth projection from tilt, depth buffer
|
||||||
* is used for clipping */
|
* is used for clipping */
|
||||||
mViewProj.copy(v.proj);
|
mClipProj.copy(v.proj);
|
||||||
mViewProj.setValue(10, 0);
|
mClipProj.setValue(10, 0);
|
||||||
mViewProj.setValue(14, 0);
|
mClipProj.setValue(14, 0);
|
||||||
mViewProj.multiplyRhs(v.view);
|
mClipProj.multiplyRhs(v.view);
|
||||||
|
|
||||||
mClipMode = PolygonLayer.CLIP_STENCIL;
|
mClipMode = PolygonLayer.CLIP_STENCIL;
|
||||||
|
|
||||||
@ -64,11 +67,14 @@ public class VectorTileRenderer extends TileRenderer {
|
|||||||
|
|
||||||
for (int i = 0; i < tileCnt; i++) {
|
for (int i = 0; i < tileCnt; i++) {
|
||||||
MapTile t = tiles[i];
|
MapTile t = tiles[i];
|
||||||
|
// TODO check if proxies are actually available
|
||||||
if (t.isVisible && t.state != READY) {
|
if (t.isVisible && t.state != READY) {
|
||||||
GL.glDepthMask(true);
|
GL.glDepthMask(true);
|
||||||
GL.glClear(GL20.GL_DEPTH_BUFFER_BIT);
|
GL.glClear(GL20.GL_DEPTH_BUFFER_BIT);
|
||||||
|
|
||||||
/* always write depth for non-proxy tiles */
|
/* always write depth for non-proxy tiles
|
||||||
|
* this is used in drawProxies pass to not
|
||||||
|
* draw where tiles were already drawn */
|
||||||
GL.glDepthFunc(GL20.GL_ALWAYS);
|
GL.glDepthFunc(GL20.GL_ALWAYS);
|
||||||
|
|
||||||
mClipMode = PolygonLayer.CLIP_DEPTH;
|
mClipMode = PolygonLayer.CLIP_DEPTH;
|
||||||
@ -152,6 +158,7 @@ public class VectorTileRenderer extends TileRenderer {
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
layers.vbo.bind();
|
layers.vbo.bind();
|
||||||
|
|
||||||
MapPosition pos = v.pos;
|
MapPosition pos = v.pos;
|
||||||
/* place tile relative to map position */
|
/* place tile relative to map position */
|
||||||
int z = tile.zoomLevel;
|
int z = tile.zoomLevel;
|
||||||
@ -163,25 +170,27 @@ public class VectorTileRenderer extends TileRenderer {
|
|||||||
/* scale relative to zoom-level of this tile */
|
/* scale relative to zoom-level of this tile */
|
||||||
float scale = (float) (pos.scale / (1 << z));
|
float scale = (float) (pos.scale / (1 << z));
|
||||||
|
|
||||||
v.mvp.setTransScale(x, y, scale / MapRenderer.COORD_SCALE);
|
v.mvp.setTransScale(x, y, scale / COORD_SCALE);
|
||||||
v.mvp.multiplyLhs(mViewProj);
|
v.mvp.multiplyLhs(v.viewproj);
|
||||||
|
|
||||||
boolean clipped = false;
|
mClipMVP.setTransScale(x, y, scale / COORD_SCALE);
|
||||||
int mode = mClipMode;
|
mClipMVP.multiplyLhs(mClipProj);
|
||||||
|
|
||||||
RenderElement l = layers.getBaseLayers();
|
RenderElement l = layers.getBaseLayers();
|
||||||
|
PolygonLayer.Renderer.clip(mClipMVP, mClipMode);
|
||||||
|
|
||||||
|
boolean first = true;
|
||||||
while (l != null) {
|
while (l != null) {
|
||||||
if (l.type == POLYGON) {
|
if (l.type == POLYGON) {
|
||||||
l = PolygonLayer.Renderer.draw(l, v, div, !clipped, mode);
|
l = PolygonLayer.Renderer.draw(l, v, div, first);
|
||||||
clipped = true;
|
first = false;
|
||||||
|
|
||||||
|
/* set test for clip to tile region */
|
||||||
|
GL.glStencilFunc(GL_EQUAL, 0x80, 0x80);
|
||||||
|
|
||||||
|
// clipped = true;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (!clipped) {
|
|
||||||
/* draw stencil buffer clip region */
|
|
||||||
PolygonLayer.Renderer.draw(null, v, div, true, mode);
|
|
||||||
clipped = true;
|
|
||||||
}
|
|
||||||
if (l.type == LINE) {
|
if (l.type == LINE) {
|
||||||
l = LineLayer.Renderer.draw(l, v, scale, layers);
|
l = LineLayer.Renderer.draw(l, v, scale, layers);
|
||||||
continue;
|
continue;
|
||||||
@ -206,10 +215,6 @@ public class VectorTileRenderer extends TileRenderer {
|
|||||||
|
|
||||||
l = layers.getTextureLayers();
|
l = layers.getTextureLayers();
|
||||||
while (l != null) {
|
while (l != null) {
|
||||||
if (!clipped) {
|
|
||||||
PolygonLayer.Renderer.draw(null, v, div, true, mode);
|
|
||||||
clipped = true;
|
|
||||||
}
|
|
||||||
if (l.type == BITMAP) {
|
if (l.type == BITMAP) {
|
||||||
l = BitmapLayer.Renderer.draw(l, v, 1, mLayerAlpha);
|
l = BitmapLayer.Renderer.draw(l, v, 1, mLayerAlpha);
|
||||||
continue;
|
continue;
|
||||||
@ -219,12 +224,13 @@ public class VectorTileRenderer extends TileRenderer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (debugOverdraw) {
|
if (debugOverdraw) {
|
||||||
|
|
||||||
if (tile.zoomLevel > pos.zoomLevel)
|
if (tile.zoomLevel > pos.zoomLevel)
|
||||||
PolygonLayer.Renderer.drawOver(v, Color.BLUE, 0.5f);
|
PolygonLayer.Renderer.drawOver(mClipMVP, Color.BLUE, 0.5f);
|
||||||
else if (tile.zoomLevel < pos.zoomLevel)
|
else if (tile.zoomLevel < pos.zoomLevel)
|
||||||
PolygonLayer.Renderer.drawOver(v, Color.RED, 0.5f);
|
PolygonLayer.Renderer.drawOver(mClipMVP, Color.RED, 0.5f);
|
||||||
else
|
else
|
||||||
PolygonLayer.Renderer.drawOver(v, Color.GREEN, 0.5f);
|
PolygonLayer.Renderer.drawOver(mClipMVP, Color.GREEN, 0.5f);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -238,12 +244,12 @@ public class VectorTileRenderer extends TileRenderer {
|
|||||||
long dTime = MapRenderer.frametime - tile.fadeTime;
|
long dTime = MapRenderer.frametime - tile.fadeTime;
|
||||||
|
|
||||||
if (mOverdrawColor == 0 || dTime > FADE_TIME) {
|
if (mOverdrawColor == 0 || dTime > FADE_TIME) {
|
||||||
PolygonLayer.Renderer.drawOver(v, 0, 1);
|
PolygonLayer.Renderer.drawOver(mClipMVP, 0, 1);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
float fade = 1 - dTime / FADE_TIME;
|
float fade = 1 - dTime / FADE_TIME;
|
||||||
PolygonLayer.Renderer.drawOver(v, mOverdrawColor, fade * fade);
|
PolygonLayer.Renderer.drawOver(mClipMVP, mOverdrawColor, fade * fade);
|
||||||
|
|
||||||
MapRenderer.animate();
|
MapRenderer.animate();
|
||||||
}
|
}
|
||||||
|
@ -100,7 +100,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(l, v, 1, true, 0);
|
l = PolygonLayer.Renderer.draw(l, v, 1, true);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (l.type == LINE) {
|
if (l.type == LINE) {
|
||||||
|
@ -16,16 +16,26 @@
|
|||||||
*/
|
*/
|
||||||
package org.oscim.renderer.elements;
|
package org.oscim.renderer.elements;
|
||||||
|
|
||||||
import org.oscim.backend.GL20;
|
import static org.oscim.backend.GL20.GL_ALWAYS;
|
||||||
|
import static org.oscim.backend.GL20.GL_EQUAL;
|
||||||
|
import static org.oscim.backend.GL20.GL_INVERT;
|
||||||
|
import static org.oscim.backend.GL20.GL_KEEP;
|
||||||
|
import static org.oscim.backend.GL20.GL_REPLACE;
|
||||||
|
import static org.oscim.backend.GL20.GL_SHORT;
|
||||||
|
import static org.oscim.backend.GL20.GL_TRIANGLE_FAN;
|
||||||
|
import static org.oscim.backend.GL20.GL_TRIANGLE_STRIP;
|
||||||
|
import static org.oscim.backend.GL20.GL_ZERO;
|
||||||
|
import static org.oscim.utils.FastMath.clamp;
|
||||||
|
|
||||||
import org.oscim.core.GeometryBuffer;
|
import org.oscim.core.GeometryBuffer;
|
||||||
import org.oscim.core.Tile;
|
import org.oscim.core.Tile;
|
||||||
|
import org.oscim.renderer.GLMatrix;
|
||||||
import org.oscim.renderer.GLShader;
|
import org.oscim.renderer.GLShader;
|
||||||
import org.oscim.renderer.GLState;
|
import org.oscim.renderer.GLState;
|
||||||
import org.oscim.renderer.GLUtils;
|
import org.oscim.renderer.GLUtils;
|
||||||
import org.oscim.renderer.GLViewport;
|
import org.oscim.renderer.GLViewport;
|
||||||
import org.oscim.renderer.MapRenderer;
|
import org.oscim.renderer.MapRenderer;
|
||||||
import org.oscim.theme.styles.AreaStyle;
|
import org.oscim.theme.styles.AreaStyle;
|
||||||
import org.oscim.utils.FastMath;
|
|
||||||
import org.oscim.utils.math.Interpolation;
|
import org.oscim.utils.math.Interpolation;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
@ -38,6 +48,7 @@ public final class PolygonLayer extends RenderElement {
|
|||||||
|
|
||||||
public final static int CLIP_STENCIL = 1;
|
public final static int CLIP_STENCIL = 1;
|
||||||
public final static int CLIP_DEPTH = 2;
|
public final static int CLIP_DEPTH = 2;
|
||||||
|
public final static int CLIP_TEST_DEPTH = 3;
|
||||||
|
|
||||||
private static final float S = MapRenderer.COORD_SCALE;
|
private static final float S = MapRenderer.COORD_SCALE;
|
||||||
|
|
||||||
@ -47,7 +58,6 @@ public final class PolygonLayer extends RenderElement {
|
|||||||
|
|
||||||
PolygonLayer(int layer) {
|
PolygonLayer(int layer) {
|
||||||
super(RenderElement.POLYGON);
|
super(RenderElement.POLYGON);
|
||||||
|
|
||||||
level = layer;
|
level = layer;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -105,8 +115,9 @@ public final class PolygonLayer extends RenderElement {
|
|||||||
|
|
||||||
public static final class Renderer {
|
public static final class Renderer {
|
||||||
|
|
||||||
|
private static final int OPAQUE = 0xff000000;
|
||||||
private static final int STENCIL_BITS = 8;
|
private static final int STENCIL_BITS = 8;
|
||||||
private final static int CLIP_BIT = 0x80;
|
public final static int CLIP_BIT = 0x80;
|
||||||
|
|
||||||
private static final float FADE_START = 1.3f;
|
private static final float FADE_START = 1.3f;
|
||||||
|
|
||||||
@ -134,15 +145,15 @@ public final class PolygonLayer extends RenderElement {
|
|||||||
GL.glStencilMask(0x00);
|
GL.glStencilMask(0x00);
|
||||||
//int shader = polyShader;
|
//int shader = polyShader;
|
||||||
|
|
||||||
Shader s = setShader(polyShader, v, false);
|
Shader s = setShader(polyShader, v.mvp, false);
|
||||||
|
|
||||||
for (int c = start; c < end; c++) {
|
for (int c = start; c < end; c++) {
|
||||||
AreaStyle a = mAreaFills[c].current();
|
AreaStyle a = mAreaFills[c].current();
|
||||||
|
|
||||||
if (enableTexture && a.texture != null) {
|
if (enableTexture && a.texture != null) {
|
||||||
s = setShader(texShader, v, false);
|
s = setShader(texShader, v.mvp, false);
|
||||||
float num = FastMath.clamp((Tile.SIZE / a.texture.width) >> 1, 1, Tile.SIZE);
|
float num = clamp((Tile.SIZE / a.texture.width) >> 1, 1, Tile.SIZE);
|
||||||
float transition = Interpolation.exp5.apply(FastMath.clamp(scale - 1, 0, 1));
|
float transition = Interpolation.exp5.apply(clamp(scale - 1, 0, 1));
|
||||||
GL.glUniform2f(s.uScale, transition, div / num);
|
GL.glUniform2f(s.uScale, transition, div / num);
|
||||||
|
|
||||||
//if (a.texture.alpha);
|
//if (a.texture.alpha);
|
||||||
@ -184,29 +195,28 @@ public final class PolygonLayer extends RenderElement {
|
|||||||
/* set stencil buffer mask used to draw this layer
|
/* set stencil buffer mask used to draw this layer
|
||||||
* also check that clip bit is set to avoid overdraw
|
* also check that clip bit is set to avoid overdraw
|
||||||
* of other tiles */
|
* of other tiles */
|
||||||
GL.glStencilFunc(GL20.GL_EQUAL, 0xff, CLIP_BIT | 1 << c);
|
GL.glStencilFunc(GL_EQUAL, 0xff, CLIP_BIT | 1 << c);
|
||||||
|
|
||||||
/* draw tile fill coordinates */
|
/* draw tile fill coordinates */
|
||||||
GL.glDrawArrays(GL20.GL_TRIANGLE_STRIP, 0, 4);
|
GL.glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||||
|
|
||||||
/* disable texture shader */
|
/* disable texture shader */
|
||||||
if (s != polyShader)
|
if (s != polyShader)
|
||||||
s = setShader(polyShader, v, false);
|
s = setShader(polyShader, v.mvp, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// current layer to fill (0 - STENCIL_BITS-1)
|
/** current layer to fill (0 - STENCIL_BITS-1) */
|
||||||
private static int mCount;
|
private static int mCount;
|
||||||
|
/** must clear stencil for next draw */
|
||||||
|
private static boolean mClear;
|
||||||
|
|
||||||
private static Shader setShader(Shader shader, GLViewport v, boolean first) {
|
private static Shader setShader(Shader shader, GLMatrix mvp, boolean first) {
|
||||||
if (shader.useProgram() || first) {
|
if (shader.useProgram() || first) {
|
||||||
|
|
||||||
GLState.enableVertexArrays(shader.aPos, -1);
|
GLState.enableVertexArrays(shader.aPos, -1);
|
||||||
|
|
||||||
GL.glVertexAttribPointer(shader.aPos, 2,
|
GL.glVertexAttribPointer(shader.aPos, 2,
|
||||||
GL20.GL_SHORT, false, 0, 0);
|
GL_SHORT, false, 0, 0);
|
||||||
|
mvp.setAsUniform(shader.uMVP);
|
||||||
v.mvp.setAsUniform(shader.uMVP);
|
|
||||||
}
|
}
|
||||||
return shader;
|
return shader;
|
||||||
}
|
}
|
||||||
@ -234,37 +244,40 @@ public final class PolygonLayer extends RenderElement {
|
|||||||
* next layer
|
* next layer
|
||||||
*/
|
*/
|
||||||
public static RenderElement draw(RenderElement renderElement, GLViewport v,
|
public static RenderElement draw(RenderElement renderElement, GLViewport v,
|
||||||
float div, boolean first, int clipMode) {
|
float div, boolean first) {
|
||||||
|
|
||||||
GLState.test(false, true);
|
GLState.test(false, true);
|
||||||
|
|
||||||
setShader(polyShader, v, first);
|
setShader(polyShader, v.mvp, first);
|
||||||
|
|
||||||
int zoom = v.pos.zoomLevel;
|
int zoom = v.pos.zoomLevel;
|
||||||
float scale = (float) v.pos.getZoomScale();
|
float scale = (float) v.pos.getZoomScale();
|
||||||
|
|
||||||
int cur = mCount;
|
int cur = mCount;
|
||||||
|
int start = mCount;
|
||||||
|
|
||||||
/* reset start when only one layer left in stencil buffer */
|
/* draw to stencil buffer */
|
||||||
if (first || cur > 5)
|
GL.glColorMask(false, false, false, false);
|
||||||
cur = 0;
|
|
||||||
|
|
||||||
int start = cur;
|
/* op for stencil method polygon drawing */
|
||||||
|
GL.glStencilOp(GL_KEEP, GL_KEEP, GL_INVERT);
|
||||||
|
|
||||||
|
boolean drawn = false;
|
||||||
|
|
||||||
RenderElement l = renderElement;
|
RenderElement l = renderElement;
|
||||||
for (; l != null && l.type == RenderElement.POLYGON; l = l.next) {
|
for (; l != null && l.type == POLYGON; l = l.next) {
|
||||||
PolygonLayer pl = (PolygonLayer) l;
|
PolygonLayer pl = (PolygonLayer) l;
|
||||||
|
|
||||||
/* fade out polygon layers (set in RenderTheme) */
|
/* fade out polygon layers (set in RenderTheme) */
|
||||||
if (pl.area.fadeScale > 0 && pl.area.fadeScale > zoom)
|
if (pl.area.fadeScale > 0 && pl.area.fadeScale > zoom)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (cur == start) {
|
if (mClear) {
|
||||||
drawStencilRegion(first, clipMode);
|
clearStencilRegion();
|
||||||
first = false;
|
|
||||||
|
|
||||||
/* op for stencil method polygon drawing */
|
/* op for stencil method polygon drawing */
|
||||||
GL.glStencilOp(GL20.GL_KEEP, GL20.GL_KEEP, GL20.GL_INVERT);
|
GL.glStencilOp(GL_KEEP, GL_KEEP, GL_INVERT);
|
||||||
|
|
||||||
|
start = cur = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
mAreaFills[cur] = pl.area.current();
|
mAreaFills[cur] = pl.area.current();
|
||||||
@ -272,42 +285,48 @@ public final class PolygonLayer extends RenderElement {
|
|||||||
/* set stencil mask to draw to */
|
/* set stencil mask to draw to */
|
||||||
GL.glStencilMask(1 << cur++);
|
GL.glStencilMask(1 << cur++);
|
||||||
|
|
||||||
GL.glDrawArrays(GL20.GL_TRIANGLE_FAN, l.offset, l.numVertices);
|
GL.glDrawArrays(GL_TRIANGLE_FAN, l.offset, l.numVertices);
|
||||||
|
|
||||||
/* draw up to 7 layers into stencil buffer */
|
/* draw up to 7 layers into stencil buffer */
|
||||||
if (cur == STENCIL_BITS - 1) {
|
if (cur == STENCIL_BITS - 1) {
|
||||||
|
//log.debug("fill1 {} {}", start, cur);
|
||||||
fillPolygons(v, start, cur, zoom, scale, div);
|
fillPolygons(v, start, cur, zoom, scale, div);
|
||||||
|
drawn = true;
|
||||||
|
|
||||||
|
mClear = true;
|
||||||
start = cur = 0;
|
start = cur = 0;
|
||||||
|
|
||||||
|
if (l.next != null && l.next.type == POLYGON)
|
||||||
|
setShader(polyShader, v.mvp, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cur > 0)
|
if (cur > 0) {
|
||||||
|
//log.debug("fill2 {} {}", start, cur);
|
||||||
fillPolygons(v, start, cur, zoom, scale, div);
|
fillPolygons(v, start, cur, zoom, scale, div);
|
||||||
|
drawn = true;
|
||||||
if (clipMode > 0) {
|
|
||||||
if (first) {
|
|
||||||
drawStencilRegion(first, clipMode);
|
|
||||||
/* disable writes to stencil buffer */
|
|
||||||
GL.glStencilMask(0x00);
|
|
||||||
/* enable writes to color buffer */
|
|
||||||
GL.glColorMask(true, true, true, true);
|
|
||||||
} else {
|
|
||||||
/* set test for clip to tile region */
|
|
||||||
GL.glStencilFunc(GL20.GL_EQUAL, CLIP_BIT, CLIP_BIT);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!drawn) {
|
||||||
|
/* fillPolygons would re-enable color-mask
|
||||||
|
* but it's possible that all polygon layers
|
||||||
|
* were skipped */
|
||||||
|
GL.glColorMask(true, true, true, true);
|
||||||
|
GL.glStencilMask(0x00);
|
||||||
}
|
}
|
||||||
|
|
||||||
mCount = cur;
|
mCount = cur;
|
||||||
|
|
||||||
return l;
|
return l;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void clip(GLViewport v) {
|
public static void clip(GLMatrix mvp, int clipMode) {
|
||||||
setShader(polyShader, v, true);
|
setShader(polyShader, mvp, true);
|
||||||
|
|
||||||
|
drawStencilRegion(clipMode);
|
||||||
|
|
||||||
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 */
|
||||||
GL.glColorMask(true, true, true, true);
|
GL.glColorMask(true, true, true, true);
|
||||||
}
|
}
|
||||||
@ -319,7 +338,10 @@ 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, int clipMode) {
|
static void drawStencilRegion(int clipMode) {
|
||||||
|
//log.debug("draw stencil {}", clipMode);
|
||||||
|
mCount = 0;
|
||||||
|
mClear = false;
|
||||||
|
|
||||||
/* disable drawing to color buffer */
|
/* disable drawing to color buffer */
|
||||||
GL.glColorMask(false, false, false, false);
|
GL.glColorMask(false, false, false, false);
|
||||||
@ -327,7 +349,6 @@ public final class PolygonLayer extends RenderElement {
|
|||||||
/* write to all stencil bits */
|
/* write to all stencil bits */
|
||||||
GL.glStencilMask(0xFF);
|
GL.glStencilMask(0xFF);
|
||||||
|
|
||||||
if (first) {
|
|
||||||
/* Draw clip-region into depth and stencil buffer.
|
/* Draw clip-region into depth and stencil buffer.
|
||||||
* This is used for tile line and polygon layers.
|
* This is used for tile line and polygon layers.
|
||||||
*
|
*
|
||||||
@ -335,33 +356,53 @@ public final class PolygonLayer extends RenderElement {
|
|||||||
* only draw where no other tile has drawn yet. */
|
* only draw where no other tile has drawn yet. */
|
||||||
|
|
||||||
if (clipMode == CLIP_DEPTH) {
|
if (clipMode == CLIP_DEPTH) {
|
||||||
/* test GL_LESS/GL_ALWAYS to write to depth buffer */
|
/* tests GL_LESS/GL_ALWAYS */
|
||||||
GLState.test(true, true);
|
GLState.test(true, true);
|
||||||
|
|
||||||
|
/* write tile region to depth buffer */
|
||||||
GL.glDepthMask(true);
|
GL.glDepthMask(true);
|
||||||
|
} else {
|
||||||
|
GLState.test(false, 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(GL_ALWAYS, CLIP_BIT, 0x00);
|
||||||
} else {
|
|
||||||
/* use clip bit from stencil buffer to clear stencil
|
|
||||||
* 'layer-bits' (0x7f) */
|
|
||||||
GL.glStencilFunc(GL20.GL_EQUAL, CLIP_BIT, CLIP_BIT);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* set clip bit (0x80) for draw region */
|
/* set clip bit (0x80) for draw region */
|
||||||
GL.glStencilOp(GL20.GL_KEEP, GL20.GL_KEEP, GL20.GL_REPLACE);
|
GL.glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
|
||||||
|
|
||||||
/* draw a quad for the tile region */
|
/* draw a quad for the tile region */
|
||||||
GL.glDrawArrays(GL20.GL_TRIANGLE_STRIP, 0, 4);
|
GL.glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||||
|
|
||||||
if (first) {
|
|
||||||
if (clipMode == CLIP_DEPTH) {
|
if (clipMode == CLIP_DEPTH) {
|
||||||
/* dont modify depth buffer */
|
/* dont modify depth buffer */
|
||||||
GL.glDepthMask(false);
|
GL.glDepthMask(false);
|
||||||
GLState.test(false, true);
|
GLState.test(false, true);
|
||||||
}
|
}
|
||||||
GL.glStencilFunc(GL20.GL_EQUAL, CLIP_BIT, CLIP_BIT);
|
GL.glStencilFunc(GL_EQUAL, CLIP_BIT, CLIP_BIT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void clearStencilRegion() {
|
||||||
|
//log.debug("clear stencil");
|
||||||
|
|
||||||
|
mCount = 0;
|
||||||
|
mClear = false;
|
||||||
|
|
||||||
|
/* disable drawing to color buffer */
|
||||||
|
GL.glColorMask(false, false, false, false);
|
||||||
|
|
||||||
|
/* write to all stencil bits */
|
||||||
|
GL.glStencilMask(0xFF);
|
||||||
|
|
||||||
|
/* use clip bit from stencil buffer to clear stencil
|
||||||
|
* 'layer-bits' (0x7f) */
|
||||||
|
GL.glStencilFunc(GL_EQUAL, CLIP_BIT, CLIP_BIT);
|
||||||
|
|
||||||
|
/* set clip bit (0x80) for draw region */
|
||||||
|
GL.glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
|
||||||
|
|
||||||
|
/* draw a quad for the tile region */
|
||||||
|
GL.glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -369,12 +410,11 @@ public final class PolygonLayer extends RenderElement {
|
|||||||
* a quad with func 'always' and op 'zero'. Using 'color'
|
* a quad with func 'always' and op 'zero'. Using 'color'
|
||||||
* and 'alpha' to fake a fade effect.
|
* and 'alpha' to fake a fade effect.
|
||||||
*/
|
*/
|
||||||
public static void drawOver(GLViewport v, int color, float alpha) {
|
public static void drawOver(GLMatrix mvp, int color, float alpha) {
|
||||||
// TODO true could be avoided when same shader and vbo
|
// TODO true could be avoided when same shader and vbo
|
||||||
setShader(polyShader, v, true);
|
setShader(polyShader, mvp, true);
|
||||||
|
|
||||||
if (color == 0) {
|
if (color == 0) {
|
||||||
/* disable drawing to framebuffer (will be re-enabled in fill) */
|
|
||||||
GL.glColorMask(false, false, false, false);
|
GL.glColorMask(false, false, false, false);
|
||||||
} else {
|
} else {
|
||||||
GLUtils.setColor(polyShader.uColor, color, alpha);
|
GLUtils.setColor(polyShader.uColor, color, alpha);
|
||||||
@ -384,17 +424,19 @@ public final class PolygonLayer extends RenderElement {
|
|||||||
// TODO always pass stencil test: <-- only if not proxy?
|
// TODO always pass stencil test: <-- only if not proxy?
|
||||||
//GL.glStencilFunc(GL_ALWAYS, 0x00, 0x00);
|
//GL.glStencilFunc(GL_ALWAYS, 0x00, 0x00);
|
||||||
|
|
||||||
GL.glStencilFunc(GL20.GL_EQUAL, CLIP_BIT, CLIP_BIT);
|
GL.glStencilFunc(GL_EQUAL, CLIP_BIT, CLIP_BIT);
|
||||||
|
|
||||||
/* write to all bits */
|
/* write to all bits */
|
||||||
GL.glStencilMask(0xFF);
|
GL.glStencilMask(0xFF);
|
||||||
|
|
||||||
|
// FIXME uneeded probably
|
||||||
|
GLState.test(false, true);
|
||||||
|
|
||||||
/* zero out area to draw to */
|
/* zero out area to draw to */
|
||||||
GL.glStencilOp(GL20.GL_KEEP, GL20.GL_KEEP, GL20.GL_ZERO);
|
GL.glStencilOp(GL_KEEP, GL_KEEP, GL_ZERO);
|
||||||
|
|
||||||
GL.glDrawArrays(GL20.GL_TRIANGLE_STRIP, 0, 4);
|
GL.glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||||
|
|
||||||
// FIXME needed here?
|
|
||||||
if (color == 0)
|
if (color == 0)
|
||||||
GL.glColorMask(true, true, true, true);
|
GL.glColorMask(true, true, true, true);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user