use GLState for depth and stencil test

This commit is contained in:
Hannes Janetzek 2013-01-05 07:59:55 +01:00
parent e50ea0c2ba
commit 7cc32f1572
8 changed files with 99 additions and 109 deletions

View File

@ -16,7 +16,6 @@ package org.oscim.renderer;
import static android.opengl.GLES20.GL_ARRAY_BUFFER;
import static android.opengl.GLES20.GL_BLEND;
import static android.opengl.GLES20.GL_DEPTH_TEST;
import static android.opengl.GLES20.GL_POLYGON_OFFSET_FILL;
import static org.oscim.generator.JobTile.STATE_READY;
@ -51,9 +50,7 @@ public class BaseLayer {
Matrix.multiplyMM(mVPMatrix, 0, mfProjMatrix, 0, pos.viewMatrix, 0);
/* draw base layer */
GLES20.glEnable(GL_DEPTH_TEST);
GLES20.glEnable(GL_POLYGON_OFFSET_FILL);
// mDrawCount = 0;
for (int i = 0; i < tileCnt; i++) {
MapTile t = tiles[i];
@ -72,7 +69,7 @@ public class BaseLayer {
}
GLES20.glDisable(GL_POLYGON_OFFSET_FILL);
GLES20.glDisable(GL_DEPTH_TEST);
mDrawSerial++;
}
@ -116,7 +113,8 @@ public class BaseLayer {
PolygonRenderer.draw(pos, null, mvp, true, true);
clipped = true;
}
// clip lines to quad in depth buffer
GLState.test(true, false);
GLES20.glEnable(GL_BLEND);
l = LineRenderer.draw(pos, l, mvp, div, simpleShader,
tile.layers.lineOffset);

View File

@ -34,39 +34,42 @@ public class GLState {
blend = false;
depth = false;
stencil = false;
GLES20.glDisable(GLES20.GL_STENCIL_TEST);
GLES20.glDisable(GLES20.GL_DEPTH_TEST);
}
// public static void blend(boolean enable) {
// if (blend == enable)
// return;
//
// if (blend)
// GLES20.glEnable(GLES20.GL_BLEND);
// else
// GLES20.glDisable(GLES20.GL_BLEND);
// }
//
// public static void test(boolean depthTest, boolean stencilTest) {
// if (depth != depthTest) {
//
// if (depthTest)
// GLES20.glEnable(GLES20.GL_DEPTH_TEST);
// else
// GLES20.glDisable(GLES20.GL_DEPTH_TEST);
//
// depth = depthTest;
// }
//
// if (stencil != stencilTest) {
//
// if (stencilTest)
// GLES20.glEnable(GLES20.GL_STENCIL_TEST);
// else
// GLES20.glDisable(GLES20.GL_STENCIL_TEST);
//
// stencil = stencilTest;
// }
// }
public static void blend(boolean enable) {
if (blend == enable)
return;
if (blend)
GLES20.glEnable(GLES20.GL_BLEND);
else
GLES20.glDisable(GLES20.GL_BLEND);
}
public static void test(boolean depthTest, boolean stencilTest) {
if (depth != depthTest) {
if (depthTest)
GLES20.glEnable(GLES20.GL_DEPTH_TEST);
else
GLES20.glDisable(GLES20.GL_DEPTH_TEST);
depth = depthTest;
}
if (stencil != stencilTest) {
if (stencilTest)
GLES20.glEnable(GLES20.GL_STENCIL_TEST);
else
GLES20.glDisable(GLES20.GL_STENCIL_TEST);
stencil = stencilTest;
}
}
public static void enableVertexArrays(int va1, int va2) {
if (va1 > 1 || va2 > 1)

View File

@ -16,12 +16,10 @@ package org.oscim.renderer;
import static android.opengl.GLES20.GL_ALWAYS;
import static android.opengl.GLES20.GL_BLEND;
import static android.opengl.GLES20.GL_DEPTH_TEST;
import static android.opengl.GLES20.GL_EQUAL;
import static android.opengl.GLES20.GL_INVERT;
import static android.opengl.GLES20.GL_LESS;
import static android.opengl.GLES20.GL_SHORT;
import static android.opengl.GLES20.GL_STENCIL_TEST;
import static android.opengl.GLES20.GL_TRIANGLE_FAN;
import static android.opengl.GLES20.GL_TRIANGLE_STRIP;
import static android.opengl.GLES20.GL_ZERO;
@ -167,8 +165,25 @@ public final class PolygonRenderer {
// stencil buffer index to start fill
private static int mStart;
/**
* draw polygon layers (unil layer.next is not polygon layer)
* using stencil buffer method
* @param pos
* used to fade layers accorind to 'fade'
* in layer.area.
* @param layer
* layer to draw (referencing vertices in current vbo)
* @param matrix
* mvp matrix
* @param first
* pass true to clear stencil buffer region
* @param drawClipped
* clip to first quad in current vbo
* @return
* next layer
*/
public static Layer draw(MapPosition pos, Layer layer,
float[] matrix, boolean first, boolean drawClip) {
float[] matrix, boolean first, boolean drawClipped) {
int zoom = pos.zoomLevel;
float scale = pos.scale;
@ -182,9 +197,11 @@ public final class PolygonRenderer {
glUniformMatrix4fv(hPolygonMatrix, 1, false, matrix, 0);
// use stencilbuffer method for polygon drawing
glEnable(GL_STENCIL_TEST);
//GLState.stencilTest(true);
// reset start when only two layer left in stencil buffer
// if (mCount > 5) {
// mCount = 0;
// mStart = 0;
// }
if (first) {
mCount = 0;
@ -202,7 +219,8 @@ public final class PolygonRenderer {
continue;
if (mCount == mStart) {
// clear stencilbuffer (tile region)
// clear stencilbuffer (tile region) by drawing
// a quad with func 'always' and op 'zero'
// disable drawing to framebuffer
glColorMask(false, false, false, false);
@ -210,55 +228,38 @@ public final class PolygonRenderer {
// never pass the test: always apply fail op
glStencilFunc(GL_ALWAYS, 0, 0xFF);
glStencilMask(0xFF);
glStencilOp(GL_ZERO, GL_ZERO, GL_ZERO);
if (drawClip) {
if (drawClipped) {
GLState.test(true, true);
// draw clip-region into depth buffer:
// this is used for lines and polygons
// write to depth buffer
glDepthMask(true);
// to prevent overdraw gl_less restricts
// the clip to the area where no other
// tile has drawn
// to prevent overdraw gl_less restricts the
// clip to the area where no other tile has drawn
glDepthFunc(GL_LESS);
}
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
if (drawClip) {
if (drawClipped) {
first = false;
drawClip = false;
// dont modify depth buffer
drawClipped = false;
// do not modify depth buffer anymore
glDepthMask(false);
// only draw to this tile
glDepthFunc(GL_EQUAL);
}
// stencil op for stencil method polygon drawing
// op for stencil method polygon drawing
glStencilOp(GL_INVERT, GL_INVERT, GL_INVERT);
}
// no need for depth test while drawing stencil
if (drawClip)
glDisable(GL_DEPTH_TEST);
}
// else if (mCount == mStart) {
// // disable drawing to framebuffer
// glColorMask(false, false, false, false);
//
// // never pass the test: always apply fail op
// glStencilFunc(GL_ALWAYS, 0, 0xFF);
//
// // stencil op for stencil method polygon drawing
// glStencilOp(GL_INVERT, GL_INVERT, GL_INVERT);
//
// // no need for depth test while drawing stencil
// if (clip)
// glDisable(GL_DEPTH_TEST);
// }
GLState.test(false, true);
mFillPolys[mCount] = pl;
@ -270,8 +271,8 @@ public final class PolygonRenderer {
// draw up to 8 layers into stencil buffer
if (mCount == STENCIL_BITS) {
/* only draw where nothing was drawn yet */
if (drawClip)
glEnable(GL_DEPTH_TEST);
if (drawClipped)
GLState.test(true, true);
fillPolygons(zoom, scale);
mCount = 0;
@ -281,35 +282,38 @@ public final class PolygonRenderer {
if (mCount > 0) {
/* only draw where nothing was drawn yet */
if (drawClip)
glEnable(GL_DEPTH_TEST);
if (drawClipped)
GLState.test(true, true);
fillPolygons(zoom, scale);
}
// maybe reset start when only few layers left in stencil buffer
// if (mCount > 5){
// mCount = 0;
// mStart = 0;
// }
glDisable(GL_STENCIL_TEST);
if (drawClipped && first) {
GLState.test(true, false);
GLES20.glColorMask(false, false, false, false);
GLES20.glDepthMask(true);
GLES20.glDepthFunc(GLES20.GL_LESS);
if (drawClip && first)
drawDepthClip();
GLES20.glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
GLES20.glDepthMask(false);
GLES20.glColorMask(true, true, true, true);
GLES20.glDepthFunc(GLES20.GL_EQUAL);
}
return l;
}
private static float[] debugFillColor = { 0.3f, 0.0f, 0.0f, 0.3f };
private static float[] debugFillColor2 = { 0.0f, 0.3f, 0.0f, 0.3f };
private static ByteBuffer mDebugFill;
private static FloatBuffer mDebugFill;
static void debugDraw(float[] matrix, float[] coords, int color) {
GLState.test(false, false);
if (mDebugFill == null)
mDebugFill = ByteBuffer.allocateDirect(32).order(ByteOrder.nativeOrder())
.asFloatBuffer();
mDebugFill = ByteBuffer.allocateDirect(32).order(ByteOrder.nativeOrder());
FloatBuffer buf = mDebugFill.asFloatBuffer();
buf.put(coords);
mDebugFill.put(coords);
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0);
@ -330,18 +334,5 @@ public final class PolygonRenderer {
glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4);
GlUtils.checkGlError("draw debug");
// GLES20.glDisableVertexAttribArray(hPolygonVertexPosition);
}
static void drawDepthClip() {
glColorMask(false, false, false, false);
GLES20.glDepthMask(true);
GLES20.glDepthFunc(GLES20.GL_LESS);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
GLES20.glDepthMask(false);
glColorMask(true, true, true, true);
GLES20.glDepthFunc(GLES20.GL_EQUAL);
}
}

View File

@ -90,7 +90,7 @@ public final class TextureRenderer {
}
public static Layer draw(Layer layer, float scale, float[] projection, float matrix[]) {
GLState.test(false, false);
// GlUtils.checkGlError("draw texture >");
GLES20.glUseProgram(mTextureProgram);

View File

@ -373,10 +373,8 @@ public class BuildingOverlay extends RenderOverlay {
GLES20.glUniform1i(hBuildingMode, 0);
GLES20.glColorMask(false, false, false, false);
GLES20.glClear(GLES20.GL_DEPTH_BUFFER_BIT);
GLES20.glEnable(GLES20.GL_DEPTH_TEST);
GLState.test(true, false);
GLES20.glEnable(GLES20.GL_CULL_FACE);
//GLES20.glCullFace(GLES20.GL_CW);
GLES20.glDepthMask(true);
GLES20.glDepthFunc(GLES20.GL_LESS);

View File

@ -200,13 +200,12 @@ public class ExtrusionOverlay extends RenderOverlay {
}
GLES20.glClear(GLES20.GL_DEPTH_BUFFER_BIT);
GLState.test(true, false);
GLES20.glUseProgram(extrusionProgram);
GLState.enableVertexArrays(hExtrusionVertexPosition, -1);
GLES20.glEnable(GLES20.GL_CULL_FACE);
GLES20.glCullFace(GLES20.GL_FRONT);
GLES20.glEnable(GLES20.GL_POLYGON_OFFSET_FILL);
GLES20.glEnable(GLES20.GL_DEPTH_TEST);
GLES20.glDepthFunc(GLES20.GL_LESS);
GLES20.glDepthMask(true);
GLES20.glColorMask(false, false, false, false);
@ -291,7 +290,6 @@ public class ExtrusionOverlay extends RenderOverlay {
}
GLES20.glDisable(GLES20.GL_CULL_FACE);
GLES20.glDisable(GLES20.GL_DEPTH_TEST);
GLES20.glDisable(GLES20.GL_POLYGON_OFFSET_FILL);
GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, 0);

View File

@ -188,7 +188,7 @@ public class ModelOverlay extends RenderOverlay {
// draw to depth buffer
GLES20.glColorMask(false, false, false, false);
GLES20.glClear(GLES20.GL_DEPTH_BUFFER_BIT);
GLES20.glEnable(GLES20.GL_DEPTH_TEST);
GLState.test(true, false);
GLES20.glDepthMask(true);
GLES20.glDepthFunc(GLES20.GL_LESS);

View File

@ -18,6 +18,7 @@ import org.oscim.core.MapPosition;
import org.oscim.core.Tile;
import org.oscim.renderer.BufferObject;
import org.oscim.renderer.GLRenderer;
import org.oscim.renderer.GLState;
import org.oscim.renderer.LineRenderer;
import org.oscim.renderer.PolygonRenderer;
import org.oscim.renderer.TextureRenderer;
@ -104,6 +105,7 @@ public abstract class RenderOverlay {
Matrix.multiplyMM(mvp, 0, proj, 0, mv, 0);
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, vbo.id);
GLState.test(false, false);
for (Layer l = layers.layers; l != null;) {
if (l.type == Layer.POLYGON) {