fix z-fighting on overlapping buildings:
- modify projection matrix to add offset, glPolygonOffset is not that reliable
This commit is contained in:
parent
d1388660a1
commit
007ab2e3bf
@ -161,6 +161,8 @@ public class ExtrusionOverlay extends RenderOverlay {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public synchronized void render(MapPosition pos, float[] mv, float[] proj) {
|
public synchronized void render(MapPosition pos, float[] mv, float[] proj) {
|
||||||
|
// TODO one could render in one pass to texture and then draw the texture
|
||||||
|
// with alpha... might be faster.
|
||||||
|
|
||||||
Matrix.multiplyMM(mVPMatrix, 0, proj, 0, pos.viewMatrix, 0);
|
Matrix.multiplyMM(mVPMatrix, 0, proj, 0, pos.viewMatrix, 0);
|
||||||
proj = mVPMatrix;
|
proj = mVPMatrix;
|
||||||
@ -189,7 +191,7 @@ public class ExtrusionOverlay extends RenderOverlay {
|
|||||||
for (int i = 0; i < mTileCnt; i++) {
|
for (int i = 0; i < mTileCnt; i++) {
|
||||||
ExtrusionLayer el = (ExtrusionLayer) tiles[i].layers.extrusionLayers;
|
ExtrusionLayer el = (ExtrusionLayer) tiles[i].layers.extrusionLayers;
|
||||||
|
|
||||||
setMatrix(pos, mv, proj, tiles[i], div);
|
setMatrix(pos, mv, proj, tiles[i], div, 0);
|
||||||
GLES20.glUniformMatrix4fv(uExtMatrix, 1, false, mv, 0);
|
GLES20.glUniformMatrix4fv(uExtMatrix, 1, false, mv, 0);
|
||||||
|
|
||||||
GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, el.mIndicesBufferID);
|
GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, el.mIndicesBufferID);
|
||||||
@ -226,7 +228,6 @@ public class ExtrusionOverlay extends RenderOverlay {
|
|||||||
GLState.enableVertexArrays(uExtVertexPosition, -1);
|
GLState.enableVertexArrays(uExtVertexPosition, -1);
|
||||||
GLES20.glEnable(GLES20.GL_CULL_FACE);
|
GLES20.glEnable(GLES20.GL_CULL_FACE);
|
||||||
GLES20.glCullFace(GLES20.GL_FRONT);
|
GLES20.glCullFace(GLES20.GL_FRONT);
|
||||||
GLES20.glEnable(GLES20.GL_POLYGON_OFFSET_FILL);
|
|
||||||
GLES20.glDepthFunc(GLES20.GL_LESS);
|
GLES20.glDepthFunc(GLES20.GL_LESS);
|
||||||
GLES20.glColorMask(false, false, false, false);
|
GLES20.glColorMask(false, false, false, false);
|
||||||
GLES20.glUniform1i(uExtMode, 0);
|
GLES20.glUniform1i(uExtMode, 0);
|
||||||
@ -237,11 +238,8 @@ public class ExtrusionOverlay extends RenderOverlay {
|
|||||||
for (int i = 0; i < mTileCnt; i++) {
|
for (int i = 0; i < mTileCnt; i++) {
|
||||||
MapTile t = tiles[i];
|
MapTile t = tiles[i];
|
||||||
ExtrusionLayer el = (ExtrusionLayer) t.layers.extrusionLayers;
|
ExtrusionLayer el = (ExtrusionLayer) t.layers.extrusionLayers;
|
||||||
int add = GLRenderer.depthOffset(t);
|
int d = GLRenderer.depthOffset(t) * 10;
|
||||||
GLES20.glPolygonOffset(2, add);
|
setMatrix(pos, mv, proj, t, div, d);
|
||||||
//GLES20.glPolygonOffset(1, i * 4 + 10);
|
|
||||||
|
|
||||||
setMatrix(pos, mv, proj, t, div);
|
|
||||||
GLES20.glUniformMatrix4fv(uExtMatrix, 1, false, mv, 0);
|
GLES20.glUniformMatrix4fv(uExtMatrix, 1, false, mv, 0);
|
||||||
|
|
||||||
GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, el.mIndicesBufferID);
|
GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, el.mIndicesBufferID);
|
||||||
@ -263,12 +261,10 @@ public class ExtrusionOverlay extends RenderOverlay {
|
|||||||
for (int i = 0; i < mTileCnt; i++) {
|
for (int i = 0; i < mTileCnt; i++) {
|
||||||
MapTile t = tiles[i];
|
MapTile t = tiles[i];
|
||||||
ExtrusionLayer el = (ExtrusionLayer) t.layers.extrusionLayers;
|
ExtrusionLayer el = (ExtrusionLayer) t.layers.extrusionLayers;
|
||||||
GLES20.glDepthFunc(GLES20.GL_EQUAL);
|
|
||||||
int add = GLRenderer.depthOffset(t);
|
|
||||||
GLES20.glPolygonOffset(2, add);
|
|
||||||
//GLES20.glPolygonOffset(1, i * 4 + 10);
|
|
||||||
|
|
||||||
setMatrix(pos, mv, proj, t, div);
|
GLES20.glDepthFunc(GLES20.GL_EQUAL);
|
||||||
|
int d = GLRenderer.depthOffset(t) * 10;
|
||||||
|
setMatrix(pos, mv, proj, t, div, d);
|
||||||
GLES20.glUniformMatrix4fv(uExtMatrix, 1, false, mv, 0);
|
GLES20.glUniformMatrix4fv(uExtMatrix, 1, false, mv, 0);
|
||||||
|
|
||||||
GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, el.mIndicesBufferID);
|
GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, el.mIndicesBufferID);
|
||||||
@ -295,7 +291,11 @@ public class ExtrusionOverlay extends RenderOverlay {
|
|||||||
GLES20.glDrawElements(GLES20.GL_TRIANGLES, el.mIndiceCnt[1],
|
GLES20.glDrawElements(GLES20.GL_TRIANGLES, el.mIndiceCnt[1],
|
||||||
GLES20.GL_UNSIGNED_SHORT, el.mIndiceCnt[0] * 2);
|
GLES20.GL_UNSIGNED_SHORT, el.mIndiceCnt[0] * 2);
|
||||||
|
|
||||||
|
// drawing gl_lines with the same coordinates does not result in
|
||||||
|
// same depth values as polygons, so add offset and draw gl_lequal:
|
||||||
GLES20.glDepthFunc(GLES20.GL_LEQUAL);
|
GLES20.glDepthFunc(GLES20.GL_LEQUAL);
|
||||||
|
GlUtils.addOffsetM(mv, 1000);
|
||||||
|
GLES20.glUniformMatrix4fv(uExtMatrix, 1, false, mv, 0);
|
||||||
|
|
||||||
GLES20.glUniform1i(uExtMode, 3);
|
GLES20.glUniform1i(uExtMode, 3);
|
||||||
GLES20.glDrawElements(GLES20.GL_LINES, el.mIndiceCnt[3],
|
GLES20.glDrawElements(GLES20.GL_LINES, el.mIndiceCnt[3],
|
||||||
@ -307,12 +307,11 @@ public class ExtrusionOverlay extends RenderOverlay {
|
|||||||
}
|
}
|
||||||
|
|
||||||
GLES20.glDisable(GLES20.GL_CULL_FACE);
|
GLES20.glDisable(GLES20.GL_CULL_FACE);
|
||||||
GLES20.glDisable(GLES20.GL_POLYGON_OFFSET_FILL);
|
|
||||||
GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, 0);
|
GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void setMatrix(MapPosition mapPosition, float[] matrix, float[] proj,
|
private static void setMatrix(MapPosition mapPosition, float[] matrix, float[] proj,
|
||||||
MapTile tile, float div) {
|
MapTile tile, float div, int delta) {
|
||||||
|
|
||||||
float x = (float) (tile.pixelX - mapPosition.x * div);
|
float x = (float) (tile.pixelX - mapPosition.x * div);
|
||||||
float y = (float) (tile.pixelY - mapPosition.y * div);
|
float y = (float) (tile.pixelY - mapPosition.y * div);
|
||||||
@ -323,6 +322,8 @@ public class ExtrusionOverlay extends RenderOverlay {
|
|||||||
matrix[10] = scale / (1000f * GLRenderer.COORD_MULTIPLIER);
|
matrix[10] = scale / (1000f * GLRenderer.COORD_MULTIPLIER);
|
||||||
|
|
||||||
Matrix.multiplyMM(matrix, 0, proj, 0, matrix, 0);
|
Matrix.multiplyMM(matrix, 0, proj, 0, matrix, 0);
|
||||||
|
|
||||||
|
GlUtils.addOffsetM(matrix, delta);
|
||||||
}
|
}
|
||||||
|
|
||||||
private final float _a = 0.8f;
|
private final float _a = 0.8f;
|
||||||
@ -353,6 +354,7 @@ public class ExtrusionOverlay extends RenderOverlay {
|
|||||||
(_r - _o) / 255,
|
(_r - _o) / 255,
|
||||||
(_g - _o) / 255,
|
(_g - _o) / 255,
|
||||||
(_b - _o) / 255,
|
(_b - _o) / 255,
|
||||||
|
// 1, 0, 0,
|
||||||
1.0f,
|
1.0f,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -441,9 +443,9 @@ public class ExtrusionOverlay extends RenderOverlay {
|
|||||||
// + "varying float z;"
|
// + "varying float z;"
|
||||||
// + "void main() {"
|
// + "void main() {"
|
||||||
// + "if (z < 0.0)"
|
// + "if (z < 0.0)"
|
||||||
// + " gl_FragColor = vec4(z * -1.0, 0.0, 0.0, 1.0)*0.8;"
|
// + " gl_FragColor = vec4(z * -1.0, 0.0, 0.0, 1.0);"
|
||||||
// + "else"
|
// + "else"
|
||||||
// + " gl_FragColor = vec4(0.0, 0.0, z, 1.0)*0.8;"
|
// + " gl_FragColor = vec4(0.0, 0.0, z, 1.0);"
|
||||||
// + "}";
|
// + "}";
|
||||||
|
|
||||||
public void setAlpha(float a) {
|
public void setAlpha(float a) {
|
||||||
|
@ -230,4 +230,15 @@ public class GlUtils {
|
|||||||
matrix[5] = sy;
|
matrix[5] = sy;
|
||||||
matrix[10] = sz;
|
matrix[10] = sz;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void addOffsetM(float[] matrix, int delta) {
|
||||||
|
// from http://www.mathfor3dgameprogramming.com/code/Listing9.1.cpp
|
||||||
|
// float n = MapViewPosition.VIEW_NEAR;
|
||||||
|
// float f = MapViewPosition.VIEW_FAR;
|
||||||
|
// float pz = 1;
|
||||||
|
// float epsilon = -2.0f * f * n * delta / ((f + n) * pz * (pz + delta));
|
||||||
|
float epsilon = 1.0f / (1 << 11);
|
||||||
|
|
||||||
|
matrix[10] *= 1.0f + epsilon * delta;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user