diff --git a/src/org/mapsforge/android/MapView.java b/src/org/mapsforge/android/MapView.java index 6ec03d73..03148c51 100644 --- a/src/org/mapsforge/android/MapView.java +++ b/src/org/mapsforge/android/MapView.java @@ -78,6 +78,8 @@ public class MapView extends GLSurfaceView { private static final float DEFAULT_TEXT_SCALE = 1; private static final Byte DEFAULT_START_ZOOM_LEVEL = Byte.valueOf((byte) 16); + public final static boolean debugFrameTime = false; + private final MapController mMapController; private final MapViewPosition mMapViewPosition; @@ -186,6 +188,7 @@ public class MapView extends GLSurfaceView { setEGLConfigChooser(new GlConfigChooser()); setEGLContextClientVersion(2); + // setDebugFlags(DEBUG_CHECK_GL_ERROR | DEBUG_LOG_GL_CALLS); setRenderer(mMapRenderer); @@ -193,8 +196,6 @@ public class MapView extends GLSurfaceView { setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY); } - public final static boolean debugFrameTime = false; - private void initMapStartPosition() { GeoPoint startPoint = getStartPoint(); if (startPoint != null) { diff --git a/src/org/mapsforge/android/glrenderer/LineLayer.java b/src/org/mapsforge/android/glrenderer/LineLayer.java index 4b64bee7..a8e95633 100644 --- a/src/org/mapsforge/android/glrenderer/LineLayer.java +++ b/src/org/mapsforge/android/glrenderer/LineLayer.java @@ -22,10 +22,16 @@ import android.util.FloatMath; class LineLayer { - private static final float S = MapRenderer.COORD_MULTIPLIER; - private static final float S1000 = 1000; + private static final float COORD_SCALE = MapRenderer.COORD_MULTIPLIER; + // scale factor mapping direction vector to short values + private static final float DIR_SCALE = 2048; + // mask for packing last two bits of direction vector with texture coordinates + private static final int DIR_MASK = 0xFFFFFFFC; + // next layer LineLayer next; + + // lines referenced by this outline layer LineLayer outlines; Line line; @@ -58,12 +64,12 @@ class LineLayer { } /* - * line extrusion is based on code from GLMap (https://github.com/olofsj/GLMap/) by olofsj -- need some way to know - * how the road connects to set the ending angles + * line extrusion is based on code from GLMap (https://github.com/olofsj/GLMap/) by olofsj */ void addLine(float[] points, int pos, int length) { - float x, y, nextX, nextY, prevX, prevY, ux, uy, vx, vy, wx, wy; - float a; + float x, y, nextX, nextY, prevX, prevY; + float a, ux, uy, vx, vy, wx, wy; + int ipos = pos; boolean rounded = false; boolean squared = false; @@ -94,7 +100,8 @@ class LineLayer { ux = -vy; uy = vx; - int tsize = Tile.TILE_SIZE; + int tmax = Tile.TILE_SIZE + 10; + int tmin = -10; if (pool == null) { pool = curItem = ShortPool.get(); @@ -112,27 +119,25 @@ class LineLayer { v = si.vertices; } - boolean outside = (x <= 0 || x >= tsize || y <= 0 || y >= tsize) - && (x - vx <= 0 || x - vx >= tsize || y - vy <= 0 || y - vy >= tsize); - short ox, oy, dx, dy; + int ddx, ddy; - ox = (short) (x * S); - oy = (short) (y * S); + ox = (short) (x * COORD_SCALE); + oy = (short) (y * COORD_SCALE); + + boolean outside = (x < tmin || x > tmax || y < tmin || y > tmax); if (rounded && !outside) { + // add first vertex twice + ddx = (int) ((ux - vx) * DIR_SCALE); + ddy = (int) ((uy - vy) * DIR_SCALE); + dx = (short) (0 | ddx & DIR_MASK); + dy = (short) (2 | ddy & DIR_MASK); - // For rounded line edges - dx = (short) ((ux - vx) * S1000); - dy = (short) ((uy - vy) * S1000); - - v[opos + 0] = ox; - v[opos + 1] = oy; - v[opos + 2] = dx; - v[opos + 3] = dy; - v[opos + 4] = -1; - v[opos + 5] = 1; - opos += 6; + v[opos++] = ox; + v[opos++] = oy; + v[opos++] = dx; + v[opos++] = dy; if (opos == ShortItem.SIZE) { si.used = ShortItem.SIZE; @@ -142,13 +147,10 @@ class LineLayer { v = si.vertices; } - v[opos + 0] = ox; - v[opos + 1] = oy; - v[opos + 2] = dx; - v[opos + 3] = dy; - v[opos + 4] = -1; - v[opos + 5] = 1; - opos += 6; + v[opos++] = ox; + v[opos++] = oy; + v[opos++] = dx; + v[opos++] = dy; if (opos == ShortItem.SIZE) { si.used = ShortItem.SIZE; @@ -158,16 +160,13 @@ class LineLayer { v = si.vertices; } - dx = (short) (-(ux + vx) * S1000); - dy = (short) (-(uy + vy) * S1000); + ddx = (int) (-(ux + vx) * DIR_SCALE); + ddy = (int) (-(uy + vy) * DIR_SCALE); - v[opos + 0] = ox; - v[opos + 1] = oy; - v[opos + 2] = dx; - v[opos + 3] = dy; - v[opos + 4] = 1; - v[opos + 5] = 1; - opos += 6; + v[opos++] = ox; + v[opos++] = oy; + v[opos++] = (short) (2 | ddx & DIR_MASK); + v[opos++] = (short) (2 | ddy & DIR_MASK); if (opos == ShortItem.SIZE) { si.used = ShortItem.SIZE; @@ -178,16 +177,13 @@ class LineLayer { } // Start of line - dx = (short) (ux * S1000); - dy = (short) (uy * S1000); + ddx = (int) (ux * DIR_SCALE); + ddy = (int) (uy * DIR_SCALE); - v[opos + 0] = ox; - v[opos + 1] = oy; - v[opos + 2] = dx; - v[opos + 3] = dy; - v[opos + 4] = -1; - v[opos + 5] = 0; - opos += 6; + v[opos++] = ox; + v[opos++] = oy; + v[opos++] = (short) (0 | ddx & DIR_MASK); + v[opos++] = (short) (1 | ddy & DIR_MASK); if (opos == ShortItem.SIZE) { si.used = ShortItem.SIZE; @@ -197,13 +193,10 @@ class LineLayer { v = si.vertices; } - v[opos + 0] = ox; - v[opos + 1] = oy; - v[opos + 2] = (short) (-dx); - v[opos + 3] = (short) (-dy); - v[opos + 4] = 1; - v[opos + 5] = 0; - opos += 6; + v[opos++] = ox; + v[opos++] = oy; + v[opos++] = (short) (2 | -ddx & DIR_MASK); + v[opos++] = (short) (1 | -ddy & DIR_MASK); } else { // outside means line is probably clipped @@ -221,16 +214,16 @@ class LineLayer { if (rounded) verticesCnt -= 2; - dx = (short) ((ux - vx) * S1000); - dy = (short) ((uy - vy) * S1000); + // add first vertex twice + ddx = (int) ((ux - vx) * DIR_SCALE); + ddy = (int) ((uy - vy) * DIR_SCALE); + dx = (short) (0 | ddx & DIR_MASK); + dy = (short) (1 | ddy & DIR_MASK); - v[opos + 0] = ox; - v[opos + 1] = oy; - v[opos + 2] = dx; - v[opos + 3] = dy; - v[opos + 4] = -1; - v[opos + 5] = 0; - opos += 6; + v[opos++] = ox; + v[opos++] = oy; + v[opos++] = dx; + v[opos++] = dy; if (opos == ShortItem.SIZE) { si.used = ShortItem.SIZE; @@ -240,13 +233,10 @@ class LineLayer { v = si.vertices; } - v[opos + 0] = ox; - v[opos + 1] = oy; - v[opos + 2] = dx; - v[opos + 3] = dy; - v[opos + 4] = -1; - v[opos + 5] = 0; - opos += 6; + v[opos++] = ox; + v[opos++] = oy; + v[opos++] = dx; + v[opos++] = dy; if (opos == ShortItem.SIZE) { si.used = ShortItem.SIZE; @@ -256,16 +246,14 @@ class LineLayer { v = si.vertices; } - dx = (short) (-(ux + vx) * S1000); - dy = (short) (-(uy + vy) * S1000); + ddx = (int) (-(ux + vx) * DIR_SCALE); + ddy = (int) (-(uy + vy) * DIR_SCALE); + + v[opos++] = ox; + v[opos++] = oy; + v[opos++] = (short) (2 | ddx & DIR_MASK); + v[opos++] = (short) (1 | ddy & DIR_MASK); - v[opos + 0] = ox; - v[opos + 1] = oy; - v[opos + 2] = dx; - v[opos + 3] = dy; - v[opos + 4] = 1; - v[opos + 5] = 0; - opos += 6; } prevX = x; @@ -298,14 +286,16 @@ class LineLayer { a = -wy * ux + wx * uy; // boolean split = false; - if (a < 0.1f && a > -0.1f) { - // Almost straight or miter goes to infinity, use normal vector + if (a < 0.01f && a > -0.01f) { + // Almost straight ux = -wy; uy = wx; } else { ux = (ux / a); uy = (uy / a); + // hack to avoid miter going to infinity + // note to myself: find my mathbook and do this properly! if (ux > 2.0f || ux < -2.0f || uy > 2.0f || uy < -2.0f) { ux = -wy; uy = wx; @@ -320,19 +310,16 @@ class LineLayer { v = si.vertices; } - ox = (short) (x * S); - oy = (short) (y * S); + ox = (short) (x * COORD_SCALE); + oy = (short) (y * COORD_SCALE); - dx = (short) (ux * S1000); - dy = (short) (uy * S1000); + ddx = (int) (ux * DIR_SCALE); + ddy = (int) (uy * DIR_SCALE); - v[opos + 0] = ox; - v[opos + 1] = oy; - v[opos + 2] = dx; - v[opos + 3] = dy; - v[opos + 4] = -1; - v[opos + 5] = 0; - opos += 6; + v[opos++] = ox; + v[opos++] = oy; + v[opos++] = (short) (0 | ddx & DIR_MASK); + v[opos++] = (short) (1 | ddy & DIR_MASK); if (opos == ShortItem.SIZE) { si.used = ShortItem.SIZE; @@ -342,13 +329,10 @@ class LineLayer { v = si.vertices; } - v[opos + 0] = ox; - v[opos + 1] = oy; - v[opos + 2] = (short) -dx; - v[opos + 3] = (short) -dy; - v[opos + 4] = 1; - v[opos + 5] = 0; - opos += 6; + v[opos++] = ox; + v[opos++] = oy; + v[opos++] = (short) (2 | -ddx & DIR_MASK); + v[opos++] = (short) (1 | -ddy & DIR_MASK); prevX = x; prevY = y; @@ -367,8 +351,7 @@ class LineLayer { ux = vy; uy = -vx; - outside = (x <= 0 || x >= tsize || y <= 0 || y >= tsize) - && (x - vx <= 0 || x - vx >= tsize || y - vy <= 0 || y - vy >= tsize); + outside = (x < tmin || x > tmax || y < tmin || y > tmax); if (opos == ShortItem.SIZE) { si.used = ShortItem.SIZE; @@ -378,21 +361,17 @@ class LineLayer { v = si.vertices; } - ox = (short) (x * S); - oy = (short) (y * S); + ox = (short) (x * COORD_SCALE); + oy = (short) (y * COORD_SCALE); if (rounded && !outside) { + ddx = (int) (ux * DIR_SCALE); + ddy = (int) (uy * DIR_SCALE); - dx = (short) (ux * S1000); - dy = (short) (uy * S1000); - - v[opos + 0] = ox; - v[opos + 1] = oy; - v[opos + 2] = dx; - v[opos + 3] = dy; - v[opos + 4] = -1; - v[opos + 5] = 0; - opos += 6; + v[opos++] = ox; + v[opos++] = oy; + v[opos++] = (short) (0 | ddx & DIR_MASK); + v[opos++] = (short) (1 | ddy & DIR_MASK); if (opos == ShortItem.SIZE) { si.used = ShortItem.SIZE; @@ -402,13 +381,10 @@ class LineLayer { v = si.vertices; } - v[opos + 0] = ox; - v[opos + 1] = oy; - v[opos + 2] = (short) -dx; - v[opos + 3] = (short) -dy; - v[opos + 4] = 1; - v[opos + 5] = 0; - opos += 6; + v[opos++] = ox; + v[opos++] = oy; + v[opos++] = (short) (2 | -ddx & DIR_MASK); + v[opos++] = (short) (1 | -ddy & DIR_MASK); if (opos == ShortItem.SIZE) { si.used = ShortItem.SIZE; @@ -419,16 +395,15 @@ class LineLayer { } // For rounded line edges - dx = (short) ((ux - vx) * S1000); - dy = (short) ((uy - vy) * S1000); + ddx = (int) ((ux - vx) * DIR_SCALE); + ddy = (int) ((uy - vy) * DIR_SCALE); + dx = (short) (0 | ddx & DIR_MASK); + dy = (short) (0 | ddy & DIR_MASK); - v[opos + 0] = ox; - v[opos + 1] = oy; - v[opos + 2] = dx; - v[opos + 3] = dy; - v[opos + 4] = -1; - v[opos + 5] = -1; - opos += 6; + v[opos++] = ox; + v[opos++] = oy; + v[opos++] = dx; + v[opos++] = dy; if (opos == ShortItem.SIZE) { si.used = ShortItem.SIZE; @@ -438,16 +413,16 @@ class LineLayer { v = si.vertices; } - dx = (short) (-(ux + vx) * S1000); - dy = (short) (-(uy + vy) * S1000); + // add last vertex twice + ddx = (int) (-(ux + vx) * DIR_SCALE); + ddy = (int) (-(uy + vy) * DIR_SCALE); + dx = (short) (2 | ddx & DIR_MASK); + dy = (short) (0 | ddy & DIR_MASK); - v[opos + 0] = ox; - v[opos + 1] = oy; - v[opos + 2] = dx; - v[opos + 3] = dy; - v[opos + 4] = 1; - v[opos + 5] = -1; - opos += 6; + v[opos++] = ox; + v[opos++] = oy; + v[opos++] = dx; + v[opos++] = dy; if (opos == ShortItem.SIZE) { si.used = ShortItem.SIZE; @@ -457,13 +432,10 @@ class LineLayer { v = si.vertices; } - v[opos + 0] = ox; - v[opos + 1] = oy; - v[opos + 2] = dx; - v[opos + 3] = dy; - v[opos + 4] = 1; - v[opos + 5] = -1; - opos += 6; + v[opos++] = ox; + v[opos++] = oy; + v[opos++] = dx; + v[opos++] = dy; } else { if (squared) { @@ -477,16 +449,13 @@ class LineLayer { if (rounded) verticesCnt -= 2; - dx = (short) ((ux - vx) * S1000); - dy = (short) ((uy - vy) * S1000); + ddx = (int) ((ux - vx) * DIR_SCALE); + ddy = (int) ((uy - vy) * DIR_SCALE); - v[opos + 0] = ox; - v[opos + 1] = oy; - v[opos + 2] = dx; - v[opos + 3] = dy; - v[opos + 4] = -1; - v[opos + 5] = 0; - opos += 6; + v[opos++] = ox; + v[opos++] = oy; + v[opos++] = (short) (0 | ddx & DIR_MASK); + v[opos++] = (short) (1 | ddy & DIR_MASK); if (opos == ShortItem.SIZE) { si.used = ShortItem.SIZE; @@ -496,16 +465,16 @@ class LineLayer { v = si.vertices; } - dx = (short) (-(ux + vx) * S1000); - dy = (short) (-(uy + vy) * S1000); + // add last vertex twice + ddx = (int) (-(ux + vx) * DIR_SCALE); + ddy = (int) (-(uy + vy) * DIR_SCALE); + dx = (short) (2 | ddx & DIR_MASK); + dy = (short) (1 | ddy & DIR_MASK); - v[opos + 0] = ox; - v[opos + 1] = oy; - v[opos + 2] = dx; - v[opos + 3] = dy; - v[opos + 4] = 1; - v[opos + 5] = 0; - opos += 6; + v[opos++] = ox; + v[opos++] = oy; + v[opos++] = dx; + v[opos++] = dy; if (opos == ShortItem.SIZE) { si.used = ShortItem.SIZE; @@ -515,13 +484,10 @@ class LineLayer { v = si.vertices; } - v[opos + 0] = ox; - v[opos + 1] = oy; - v[opos + 2] = dx; - v[opos + 3] = dy; - v[opos + 4] = 1; - v[opos + 5] = 0; - opos += 6; + v[opos++] = ox; + v[opos++] = oy; + v[opos++] = dx; + v[opos++] = dy; } si.used = opos; diff --git a/src/org/mapsforge/android/glrenderer/LineLayers.java b/src/org/mapsforge/android/glrenderer/LineLayers.java index ed895206..9241dea0 100644 --- a/src/org/mapsforge/android/glrenderer/LineLayers.java +++ b/src/org/mapsforge/android/glrenderer/LineLayers.java @@ -35,10 +35,10 @@ import android.opengl.GLES20; import android.util.FloatMath; class LineLayers { - private static int NUM_VERTEX_SHORTS = 6; + private static int NUM_VERTEX_SHORTS = 4; private static final int LINE_VERTICES_DATA_POS_OFFSET = 0; - private static final int LINE_VERTICES_DATA_TEX_OFFSET = 8; + private static final int LINE_VERTICES_DATA_TEX_OFFSET = 4; // shader handles private static int lineProgram; @@ -82,11 +82,11 @@ class LineLayers { glEnableVertexAttribArray(hLineVertexPosition); glEnableVertexAttribArray(hLineTexturePosition); - glVertexAttribPointer(hLineVertexPosition, 4, GLES20.GL_SHORT, - false, 12, tile.lineOffset + LINE_VERTICES_DATA_POS_OFFSET); + glVertexAttribPointer(hLineVertexPosition, 2, GLES20.GL_SHORT, + false, 8, tile.lineOffset + LINE_VERTICES_DATA_POS_OFFSET); glVertexAttribPointer(hLineTexturePosition, 2, GLES20.GL_SHORT, - false, 12, tile.lineOffset + LINE_VERTICES_DATA_TEX_OFFSET); + false, 8, tile.lineOffset + LINE_VERTICES_DATA_TEX_OFFSET); glUniformMatrix4fv(hLineMatrix, 1, false, matrix, 0); @@ -115,7 +115,10 @@ class LineLayers { if (alpha > 1.0f) alpha = 1.0f; glUniform4f(hLineColor, - line.color[0], line.color[1], line.color[2], alpha); + line.color[0] * alpha, + line.color[1] * alpha, + line.color[2] * alpha, + alpha); } else { glUniform4fv(hLineColor, 1, line.color, 0); } diff --git a/src/org/mapsforge/android/glrenderer/MapRenderer.java b/src/org/mapsforge/android/glrenderer/MapRenderer.java index 3e603867..673257e1 100644 --- a/src/org/mapsforge/android/glrenderer/MapRenderer.java +++ b/src/org/mapsforge/android/glrenderer/MapRenderer.java @@ -16,11 +16,9 @@ package org.mapsforge.android.glrenderer; import static android.opengl.GLES20.GL_ARRAY_BUFFER; import static android.opengl.GLES20.GL_BLEND; -import static android.opengl.GLES20.GL_DITHER; import static android.opengl.GLES20.GL_DYNAMIC_DRAW; import static android.opengl.GLES20.GL_ONE_MINUS_SRC_ALPHA; import static android.opengl.GLES20.GL_SCISSOR_TEST; -import static android.opengl.GLES20.GL_SRC_ALPHA; import static android.opengl.GLES20.GL_STENCIL_BUFFER_BIT; import static android.opengl.GLES20.glBindBuffer; import static android.opengl.GLES20.glBlendFunc; @@ -30,7 +28,6 @@ import static android.opengl.GLES20.glClearColor; import static android.opengl.GLES20.glClearStencil; import static android.opengl.GLES20.glDisable; import static android.opengl.GLES20.glEnable; -import static android.opengl.GLES20.glFinish; import static android.opengl.GLES20.glGenBuffers; import static android.opengl.GLES20.glScissor; import static android.opengl.GLES20.glViewport; @@ -68,7 +65,7 @@ public class MapRenderer implements org.mapsforge.android.IMapRenderer { private static final int MAX_TILES_IN_QUEUE = 40; private static final int CACHE_TILES_MAX = 250; - private static final int LIMIT_BUFFERS = 16 * MB; + private static final int LIMIT_BUFFERS = 12 * MB; private static int CACHE_TILES = CACHE_TILES_MAX; @@ -109,7 +106,7 @@ public class MapRenderer implements org.mapsforge.android.IMapRenderer { private static float[] mMVPMatrix = new float[16]; // private static float[] mRotateMatrix = new float[16]; - private static float[] mProjMatrix = new float[16]; + // private static float[] mProjMatrix = new float[16]; // newTiles is set in updateVisibleList and swapped // with curTiles on main thread. curTiles is swapped @@ -600,6 +597,12 @@ public class MapRenderer implements org.mapsforge.android.IMapRenderer { return true; } + // depthRange: -1 to 1, bits: 2^24 => 2/2^24 one step + // maybe one could avoid clearing the depth buffer for a few + // iterations when modifying glDepthRange before clipper + // gl_less test so that it does not fail + // private static final float depthStep = 0.00000011920928955078125f; + private static void setMatrix(GLMapTile tile, float div, int offset) { float x, y, scale; @@ -609,7 +612,8 @@ public class MapRenderer implements org.mapsforge.android.IMapRenderer { mMVPMatrix[12] = x * scale * mAspect; mMVPMatrix[13] = -(y + Tile.TILE_SIZE) * scale; - mMVPMatrix[14] = offset * 0.01f; + // increase the 'distance' with each tile drawn. + mMVPMatrix[14] = -1 + offset * 0.01f; // depthStep; // 0.01f; mMVPMatrix[0] = scale * mAspect / COORD_MULTIPLIER; mMVPMatrix[5] = scale / COORD_MULTIPLIER; @@ -763,6 +767,9 @@ public class MapRenderer implements org.mapsforge.android.IMapRenderer { if (mBufferMemoryUsage > LIMIT_BUFFERS) { Log.d(TAG, "buffer object usage: " + mBufferMemoryUsage / MB + "MB"); + glBindBuffer(GL_ARRAY_BUFFER, 0); + int buf[] = new int[1]; + synchronized (mVBOs) { for (VertexBufferObject vbo : mVBOs) { @@ -770,8 +777,19 @@ public class MapRenderer implements org.mapsforge.android.IMapRenderer { continue; mBufferMemoryUsage -= vbo.size; - glBindBuffer(GL_ARRAY_BUFFER, vbo.id); - glBufferData(GL_ARRAY_BUFFER, 0, null, GL_DYNAMIC_DRAW); + GlUtils.checkGlError("before"); + // this should free allocated memory but it does not. at least on HTC. + // glBindBuffer(GL_ARRAY_BUFFER, vbo.id); + // glBufferData(GL_ARRAY_BUFFER, 0, null, GLES20.GL_STATIC_DRAW); + + // recreate vbo + buf[0] = vbo.id; + GLES20.glDeleteBuffers(1, buf, 0); + GLES20.glGenBuffers(1, buf, 0); + vbo.id = buf[0]; + + GlUtils.checkGlError("after"); + vbo.size = 0; } } @@ -801,7 +819,14 @@ public class MapRenderer implements org.mapsforge.android.IMapRenderer { } GLES20.glDepthMask(true); - glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT); + + // Note: i have the impression it is faster to also clear the + // stencil buffer even when not needed. probaly otherwise it + // is masked out from the depth buffer as they share the same + // memory region afaik + glClear(GLES20.GL_COLOR_BUFFER_BIT + | GLES20.GL_DEPTH_BUFFER_BIT + | GLES20.GL_STENCIL_BUFFER_BIT); if (mInitial) return; @@ -862,7 +887,6 @@ public class MapRenderer implements org.mapsforge.android.IMapRenderer { if (updateTextures > 0) TextRenderer.compileTextures(); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); GLES20.glEnable(GLES20.GL_DEPTH_TEST); // glEnable(GLES20.GL_POLYGON_OFFSET_FILL); @@ -883,17 +907,15 @@ public class MapRenderer implements org.mapsforge.android.IMapRenderer { // glDisable(GLES20.GL_POLYGON_OFFSET_FILL); glDisable(GLES20.GL_DEPTH_TEST); + // mDrawCount = 0; glEnable(GL_BLEND); - glBlendFunc(GLES20.GL_ONE, GL_ONE_MINUS_SRC_ALPHA); - int z = mDrawPosition.zoomLevel; float s = mDrawPosition.scale; - int zoomLevelDiff = Math - .max(z - MapGenerator.STROKE_MAX_ZOOM_LEVEL, 0); + int zoomLevelDiff = Math.max(z - MapGenerator.STROKE_MAX_ZOOM_LEVEL, 0); float scale = (float) Math.pow(1.4, zoomLevelDiff); if (scale < 1) scale = 1; @@ -913,7 +935,7 @@ public class MapRenderer implements org.mapsforge.android.IMapRenderer { TextRenderer.endDraw(); if (MapView.debugFrameTime) { - glFinish(); + GLES20.glFinish(); Log.d(TAG, "draw took " + (SystemClock.uptimeMillis() - start)); } @@ -921,19 +943,20 @@ public class MapRenderer implements org.mapsforge.android.IMapRenderer { } private static void drawTile(GLMapTile tile, float div) { - + // draw parents only once if (tile.lastDraw == mRedrawCnt) return; + tile.lastDraw = mRedrawCnt; + int z = mDrawPosition.zoomLevel; float s = mDrawPosition.scale; - tile.lastDraw = mRedrawCnt; - + // mDrawCount is used to calculation z offset. + // (used for depth clipping) setMatrix(tile, div, mDrawCount++); glBindBuffer(GL_ARRAY_BUFFER, tile.vbo.id); - // GLES20.glPolygonOffset(0, mDrawCount); LineLayer ll = tile.lineLayers; PolygonLayer pl = tile.polygonLayers; @@ -955,15 +978,15 @@ public class MapRenderer implements org.mapsforge.android.IMapRenderer { pl = PolygonLayers.drawPolygons(pl, lnext, mMVPMatrix, z, s, !clipped); - if (!clipped) { - clipped = true; - } + clipped = true; + } else { - // XXX nastay + // XXX nasty if (!clipped) { PolygonLayers.drawPolygons(null, 0, mMVPMatrix, z, s, true); clipped = true; } + glEnable(GL_BLEND); ll = LineLayers.drawLines(tile, ll, pnext, mMVPMatrix, div, z, s); @@ -1081,14 +1104,7 @@ public class MapRenderer implements org.mapsforge.android.IMapRenderer { // Set up textures TextRenderer.init(numTiles); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - - // glDisable(GLES20.GL_DEPTH_TEST); - // glDepthMask(false); - // GLES20.glDepthRangef(1, 0); - // GLES20.glClearDepthf(0); - - glDisable(GL_DITHER); + // glDisable(GL_DITHER); if (mClearColor != null) { glClearColor(mClearColor[0], mClearColor[1], @@ -1096,12 +1112,17 @@ public class MapRenderer implements org.mapsforge.android.IMapRenderer { } else { glClearColor(0.98f, 0.98f, 0.97f, 1.0f); } + glClearStencil(0); glClear(GL_STENCIL_BUFFER_BIT); glEnable(GL_SCISSOR_TEST); glScissor(0, 0, mWidth, mHeight); + glBlendFunc(GLES20.GL_ONE, GL_ONE_MINUS_SRC_ALPHA); + + GlUtils.checkGlError("onSurfaceChanged"); + mMapView.redrawTiles(); } @@ -1127,10 +1148,10 @@ public class MapRenderer implements org.mapsforge.android.IMapRenderer { mFillCoords[6] = max; mFillCoords[7] = min; - int i[] = new int[1]; - + // int i[] = new int[1]; // GLES20.glGetIntegerv(GLES20.GL_, i, 0); - Log.d(TAG, " >>>> " + i[0]); + // Log.d(TAG, " >>>> " + i[0]); + LineLayers.init(); PolygonLayers.init(); } diff --git a/src/org/mapsforge/android/glrenderer/PolygonLayers.java b/src/org/mapsforge/android/glrenderer/PolygonLayers.java index 6809ffb7..049130f1 100644 --- a/src/org/mapsforge/android/glrenderer/PolygonLayers.java +++ b/src/org/mapsforge/android/glrenderer/PolygonLayers.java @@ -25,7 +25,6 @@ import static android.opengl.GLES20.glColorMask; import static android.opengl.GLES20.glDisable; import static android.opengl.GLES20.glDrawArrays; import static android.opengl.GLES20.glEnable; -import static android.opengl.GLES20.glEnableVertexAttribArray; import static android.opengl.GLES20.glGetAttribLocation; import static android.opengl.GLES20.glGetUniformLocation; import static android.opengl.GLES20.glStencilFunc; @@ -82,7 +81,7 @@ class PolygonLayers { // do not modify stencil buffer glStencilMask(0); - // GLES20.glEnable(GLES20.GL_POLYGON_OFFSET_FILL); + glEnable(GLES20.GL_DEPTH_TEST); for (int c = 0; c < count; c++) { PolygonLayer l = mFillPolys[c]; @@ -90,7 +89,7 @@ class PolygonLayers { float alpha = 1.0f; if (l.area.fade >= zoom || l.area.color[3] != 1.0) { - + // draw alpha blending, fade in/out if (l.area.fade >= zoom) { alpha = (scale > 1.3f ? scale : 1.3f) - alpha; if (alpha > 1.0f) @@ -104,9 +103,13 @@ class PolygonLayers { blend = true; } glUniform4f(hPolygonColor, - l.area.color[0], l.area.color[1], l.area.color[2], alpha); + l.area.color[0] * alpha, + l.area.color[1] * alpha, + l.area.color[2] * alpha, + alpha); } else if (l.area.blend == zoom) { + // fade in/out alpha = scale - 1.0f; if (alpha > 1.0f) alpha = 1.0f; @@ -118,6 +121,7 @@ class PolygonLayers { l.area.color[1] * (1 - alpha) + l.area.blendColor[1] * alpha, l.area.color[2] * (1 - alpha) + l.area.blendColor[2] * alpha, 1); } else { + // draw solid if (blend) { glDisable(GL_BLEND); blend = false; @@ -144,7 +148,7 @@ class PolygonLayers { int cnt = 0; glUseProgram(polygonProgram); - glEnableVertexAttribArray(hPolygonVertexPosition); + GLES20.glEnableVertexAttribArray(hPolygonVertexPosition); glVertexAttribPointer(hPolygonVertexPosition, 2, GLES20.GL_SHORT, false, 0, @@ -177,9 +181,12 @@ class PolygonLayers { // clear stencilbuffer (tile region) glStencilOp(GL_ZERO, GL_ZERO, GL_ZERO); - // draw depth clipper if (first) { + // draw clip-region into depth buffer GLES20.glDepthMask(true); + // to prevent overdraw gl_less restricts + // the clip to the area where no other + // tile was drawn GLES20.glDepthFunc(GLES20.GL_LESS); } @@ -193,6 +200,7 @@ class PolygonLayers { // stencil op for stencil method polygon drawing glStencilOp(GL_INVERT, GL_INVERT, GL_INVERT); + glDisable(GLES20.GL_DEPTH_TEST); } mFillPolys[cnt] = l; @@ -218,7 +226,6 @@ class PolygonLayers { // required on GalaxyII, Android 2.3.3 (cant just VAA enable once...) GLES20.glDisableVertexAttribArray(hPolygonVertexPosition); - return l; } diff --git a/src/org/mapsforge/android/glrenderer/Shaders.java b/src/org/mapsforge/android/glrenderer/Shaders.java index c88e62e9..c3bd5eb6 100644 --- a/src/org/mapsforge/android/glrenderer/Shaders.java +++ b/src/org/mapsforge/android/glrenderer/Shaders.java @@ -20,17 +20,35 @@ class Shaders { final static String lineVertexShader = "" + "precision mediump float;" + "uniform mat4 mvp;" - + "attribute vec4 a_position;" + + "attribute vec2 a_position;" + "attribute vec2 a_st;" + "varying vec2 v_st;" + "uniform float u_width;" - + "const float dscale = 8.0/1000.0;" + + "const float dscale = 8.0/2048.0;" + "void main() {" - + " vec2 dir = dscale * u_width * a_position.zw;" - + " gl_Position = mvp * vec4(a_position.xy + dir, 0.0,1.0);" - + " v_st = u_width * a_st;" + // scale extrusion to line u_width pixel + // just ignore the two most insignificant bits of a_st :) + + " vec2 dir = dscale * u_width * a_st;" + + " gl_Position = mvp * vec4(a_position + dir, 0.0,1.0);" + // last two bits of a_st hold the texture coordinates + // TODO use bit operations when available! + + " v_st = u_width * (abs(mod(a_st,4.0)) - 1.0);" + "}"; + // final static String lineVertexShader = "" + // + "precision mediump float;" + // + "uniform mat4 mvp;" + // + "attribute vec4 a_position;" + // + "attribute vec2 a_st;" + // + "varying vec2 v_st;" + // + "uniform float u_width;" + // + "const float dscale = 8.0/1000.0;" + // + "void main() {" + // + " vec2 dir = dscale * u_width * a_position.zw;" + // + " gl_Position = mvp * vec4(a_position.xy + dir, 0.0,1.0);" + // + " v_st = u_width * a_st;" + // + "}"; + final static String lineFragmentShader = "" + "precision mediump float;" + "uniform float u_wscale;" @@ -45,7 +63,12 @@ class Shaders { + " len = abs(v_st.s);" + " else " + " len = length(v_st);" - + " color.a *= smoothstep(zero, u_wscale, u_width - len);" + // fade to alpha. u_wscale is the width in pixel which should be faded, + // u_width - len the position of this fragment on the perpendicular to the line + + "color *= smoothstep(zero, u_wscale, u_width - len);" + + "if (color.a < 0.02)" + + " discard;" + + " else" + " gl_FragColor = color;" + "}"; diff --git a/src/org/mapsforge/android/glrenderer/VertexBufferObject.java b/src/org/mapsforge/android/glrenderer/VertexBufferObject.java index 40c5d6e2..b1a6a50f 100644 --- a/src/org/mapsforge/android/glrenderer/VertexBufferObject.java +++ b/src/org/mapsforge/android/glrenderer/VertexBufferObject.java @@ -16,11 +16,11 @@ package org.mapsforge.android.glrenderer; class VertexBufferObject { - final int id; + int id; int size; VertexBufferObject(int id) { this.id = id; size = 0; } -} \ No newline at end of file +} diff --git a/src/org/mapsforge/android/input/MapMover.java b/src/org/mapsforge/android/input/MapMover.java deleted file mode 100644 index fc2e2b5f..00000000 --- a/src/org/mapsforge/android/input/MapMover.java +++ /dev/null @@ -1,240 +0,0 @@ -/* - * Copyright 2010, 2011, 2012 mapsforge.org - * - * This program is free software: you can redistribute it and/or modify it under the - * terms of the GNU Lesser General Public License as published by the Free Software - * Foundation, either version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A - * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License along with - * this program. If not, see . - */ -package org.mapsforge.android.input; - -import org.mapsforge.android.MapView; -import org.mapsforge.android.utils.PausableThread; - -import android.os.SystemClock; -import android.view.KeyEvent; -import android.view.MotionEvent; - -/** - * A MapMover moves the map horizontally and vertically at a configurable speed. It runs in a separate thread to avoid - * blocking the UI thread. - */ -public class MapMover extends PausableThread implements KeyEvent.Callback { - - private static final int DEFAULT_MOVE_SPEED_FACTOR = 10; - private static final int FRAME_LENGTH_IN_MS = 15; - private static final float MOVE_SPEED = 0.2f; - private static final String THREAD_NAME = "MapMover"; - private static final float TRACKBALL_MOVE_SPEED_FACTOR = 40; - - private final MapView mMapView; - private float mMoveSpeedFactor; - private float mMoveX; - private float mMoveY; - private long mTimePrevious; - - /** - * @param mapView - * the MapView which should be moved by this MapMover. - */ - public MapMover(MapView mapView) { - super(); - mMapView = mapView; - mMoveSpeedFactor = DEFAULT_MOVE_SPEED_FACTOR; - } - - /** - * @return the move speed factor, used for trackball and keyboard events. - */ - public float getMoveSpeedFactor() { - return mMoveSpeedFactor; - } - - @Override - public boolean onKeyDown(int keyCode, KeyEvent keyEvent) { - if (!mMapView.isClickable()) { - return false; - } - - if (keyCode == KeyEvent.KEYCODE_DPAD_LEFT) { - moveLeft(); - return true; - } else if (keyCode == KeyEvent.KEYCODE_DPAD_RIGHT) { - moveRight(); - return true; - } else if (keyCode == KeyEvent.KEYCODE_DPAD_UP) { - moveUp(); - return true; - } else if (keyCode == KeyEvent.KEYCODE_DPAD_DOWN) { - moveDown(); - return true; - } - return false; - } - - @Override - public boolean onKeyLongPress(int keyCode, KeyEvent keyEvent) { - return false; - } - - @Override - public boolean onKeyMultiple(int keyCode, int count, KeyEvent keyEvent) { - return false; - } - - @Override - public boolean onKeyUp(int keyCode, KeyEvent keyEvent) { - if (!mMapView.isClickable()) { - return false; - } - - if (keyCode == KeyEvent.KEYCODE_DPAD_LEFT || keyCode == KeyEvent.KEYCODE_DPAD_RIGHT) { - mMoveX = 0; - return true; - } else if (keyCode == KeyEvent.KEYCODE_DPAD_UP || keyCode == KeyEvent.KEYCODE_DPAD_DOWN) { - mMoveY = 0; - return true; - } - return false; - } - - /** - * @param motionEvent - * a trackball event which should be handled. - * @return true if the event was handled, false otherwise. - */ - public boolean onTrackballEvent(MotionEvent motionEvent) { - if (!mMapView.isClickable()) { - return false; - } - - if (motionEvent.getAction() == MotionEvent.ACTION_MOVE) { - float mapMoveX = motionEvent.getX() * TRACKBALL_MOVE_SPEED_FACTOR * getMoveSpeedFactor(); - float mapMoveY = motionEvent.getY() * TRACKBALL_MOVE_SPEED_FACTOR * getMoveSpeedFactor(); - - // mapView.getFrameBuffer().matrixPostTranslate(mapMoveX, - // mapMoveY); - mMapView.getMapPosition().moveMap(mapMoveX, mapMoveY); - mMapView.redrawTiles(); - return true; - } - return false; - } - - /** - * Sets the move speed factor of the map, used for trackball and keyboard events. - * - * @param moveSpeedFactor - * the factor by which the move speed of the map will be multiplied. - * @throws IllegalArgumentException - * if the new move speed factor is negative. - */ - public void setMoveSpeedFactor(float moveSpeedFactor) { - if (moveSpeedFactor < 0) { - throw new IllegalArgumentException(); - } - mMoveSpeedFactor = moveSpeedFactor; - } - - /** - * Stops moving the map completely. - */ - public void stopMove() { - mMoveX = 0; - mMoveY = 0; - } - - private void moveDown() { - if (mMoveY > 0) { - // stop moving the map vertically - mMoveY = 0; - } else if (mMoveY == 0) { - // start moving the map - mMoveY = -MOVE_SPEED * mMoveSpeedFactor; - mTimePrevious = SystemClock.uptimeMillis(); - synchronized (this) { - notify(); - } - } - } - - private void moveLeft() { - if (mMoveX < 0) { - // stop moving the map horizontally - mMoveX = 0; - } else if (mMoveX == 0) { - // start moving the map - mMoveX = MOVE_SPEED * mMoveSpeedFactor; - mTimePrevious = SystemClock.uptimeMillis(); - synchronized (this) { - notify(); - } - } - } - - private void moveRight() { - if (mMoveX > 0) { - // stop moving the map horizontally - mMoveX = 0; - } else if (mMoveX == 0) { - // start moving the map - mMoveX = -MOVE_SPEED * mMoveSpeedFactor; - mTimePrevious = SystemClock.uptimeMillis(); - synchronized (this) { - notify(); - } - } - } - - private void moveUp() { - if (mMoveY < 0) { - // stop moving the map vertically - mMoveY = 0; - } else if (mMoveY == 0) { - // start moving the map - mMoveY = MOVE_SPEED * mMoveSpeedFactor; - mTimePrevious = SystemClock.uptimeMillis(); - synchronized (this) { - notify(); - } - } - } - - @Override - protected void afterPause() { - mTimePrevious = SystemClock.uptimeMillis(); - } - - @Override - protected void doWork() throws InterruptedException { - // calculate the time difference to previous call - long timeCurrent = SystemClock.uptimeMillis(); - long timeElapsed = timeCurrent - mTimePrevious; - mTimePrevious = timeCurrent; - - // add the movement to the transformation matrices - // mapView.getFrameBuffer().matrixPostTranslate(timeElapsed * - // moveX, timeElapsed * moveY); - - // move the map and the overlays - mMapView.getMapPosition().moveMap(timeElapsed * mMoveX, timeElapsed * mMoveY); - mMapView.redrawTiles(); - sleep(FRAME_LENGTH_IN_MS); - } - - @Override - protected String getThreadName() { - return THREAD_NAME; - } - - @Override - protected boolean hasWork() { - return mMoveX != 0 || mMoveY != 0; - } -} diff --git a/src/org/mapsforge/android/input/ZoomAnimator.java b/src/org/mapsforge/android/input/ZoomAnimator.java deleted file mode 100644 index b45860f5..00000000 --- a/src/org/mapsforge/android/input/ZoomAnimator.java +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Copyright 2010, 2011, 2012 mapsforge.org - * - * This program is free software: you can redistribute it and/or modify it under the - * terms of the GNU Lesser General Public License as published by the Free Software - * Foundation, either version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A - * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License along with - * this program. If not, see . - */ -package org.mapsforge.android.input; - -import org.mapsforge.android.MapView; -import org.mapsforge.android.utils.PausableThread; - -import android.os.SystemClock; - -/** - * A ZoomAnimator handles the zoom-in and zoom-out animations of the corresponding MapView. It runs in a separate thread - * to avoid blocking the UI thread. - */ -public class ZoomAnimator extends PausableThread { - private static final int DEFAULT_DURATION = 250; - private static final int FRAME_LENGTH_IN_MS = 15; - private static final String THREAD_NAME = "ZoomAnimator"; - - private boolean mExecuteAnimation; - private final MapView mMapView; - // private float mPivotX; - // private float mPivotY; - private float mScaleFactorApplied; - private long mTimeStart; - private float mZoomDifference; - private float mZoomEnd; - private float mZoomStart; - - /** - * @param mapView - * the MapView whose zoom level changes should be animated. - */ - public ZoomAnimator(MapView mapView) { - super(); - mMapView = mapView; - } - - /** - * @return true if the ZoomAnimator is working, false otherwise. - */ - public boolean isExecuting() { - return mExecuteAnimation; - } - - /** - * Sets the parameters for the zoom animation. - * - * @param zoomStart - * the zoom factor at the begin of the animation. - * @param zoomEnd - * the zoom factor at the end of the animation. - * @param pivotX - * the x coordinate of the animation center. - * @param pivotY - * the y coordinate of the animation center. - */ - public void setParameters(float zoomStart, float zoomEnd, float pivotX, float pivotY) { - mZoomStart = zoomStart; - mZoomEnd = zoomEnd; - // mPivotX = pivotX; - // mPivotY = pivotY; - } - - /** - * Starts a zoom animation with the current parameters. - */ - public void startAnimation() { - mZoomDifference = mZoomEnd - mZoomStart; - mScaleFactorApplied = mZoomStart; - mExecuteAnimation = true; - mTimeStart = SystemClock.uptimeMillis(); - synchronized (this) { - notify(); - } - } - - @Override - protected void doWork() throws InterruptedException { - // calculate the elapsed time - long timeElapsed = SystemClock.uptimeMillis() - mTimeStart; - float timeElapsedPercent = Math.min(1, timeElapsed / (float) DEFAULT_DURATION); - - // calculate the zoom and scale values at the current moment - float currentZoom = mZoomStart + timeElapsedPercent * mZoomDifference; - float scaleFactor = currentZoom / mScaleFactorApplied; - mScaleFactorApplied *= scaleFactor; - // mapView.getFrameBuffer().matrixPostScale(scaleFactor, scaleFactor, - // pivotX, pivotY); - - // check if the animation time is over - if (timeElapsed >= DEFAULT_DURATION) { - mExecuteAnimation = false; - mMapView.redrawTiles(); - } else { - mMapView.postInvalidate(); - sleep(FRAME_LENGTH_IN_MS); - } - } - - @Override - protected String getThreadName() { - return THREAD_NAME; - } - - @Override - protected boolean hasWork() { - return mExecuteAnimation; - } -} diff --git a/src/org/mapsforge/android/rendertheme/renderinstruction/Area.java b/src/org/mapsforge/android/rendertheme/renderinstruction/Area.java index 442ddeb4..15bfd5de 100644 --- a/src/org/mapsforge/android/rendertheme/renderinstruction/Area.java +++ b/src/org/mapsforge/android/rendertheme/renderinstruction/Area.java @@ -114,17 +114,17 @@ public final class Area extends RenderInstruction { // } color = new float[4]; - color[0] = (fill >> 16 & 0xff) / 255.0f; - color[1] = (fill >> 8 & 0xff) / 255.0f; - color[2] = (fill >> 0 & 0xff) / 255.0f; color[3] = (fill >> 24 & 0xff) / 255.0f; + color[0] = (fill >> 16 & 0xff) / 255.0f * color[3]; + color[1] = (fill >> 8 & 0xff) / 255.0f * color[3]; + color[2] = (fill >> 0 & 0xff) / 255.0f * color[3]; if (blend > 0) { blendColor = new float[4]; - blendColor[0] = (blendFill >> 16 & 0xff) / 255.0f; - blendColor[1] = (blendFill >> 8 & 0xff) / 255.0f; - blendColor[2] = (blendFill >> 0 & 0xff) / 255.0f; blendColor[3] = (blendFill >> 24 & 0xff) / 255.0f; + blendColor[0] = (blendFill >> 16 & 0xff) / 255.0f * blendColor[3]; + blendColor[1] = (blendFill >> 8 & 0xff) / 255.0f * blendColor[3]; + blendColor[2] = (blendFill >> 0 & 0xff) / 255.0f * blendColor[3]; } else { blendColor = null; } diff --git a/src/org/mapsforge/android/rendertheme/renderinstruction/Line.java b/src/org/mapsforge/android/rendertheme/renderinstruction/Line.java index 1df42522..b63d0740 100644 --- a/src/org/mapsforge/android/rendertheme/renderinstruction/Line.java +++ b/src/org/mapsforge/android/rendertheme/renderinstruction/Line.java @@ -188,10 +188,10 @@ public final class Line extends RenderInstruction { this.cap = strokeLinecap; color = new float[4]; - color[0] = (stroke >> 16 & 0xff) / 255.0f; - color[1] = (stroke >> 8 & 0xff) / 255.0f; - color[2] = (stroke >> 0 & 0xff) / 255.0f; color[3] = (stroke >> 24 & 0xff) / 255.0f; + color[0] = (stroke >> 16 & 0xff) / 255.0f * color[3]; + color[1] = (stroke >> 8 & 0xff) / 255.0f * color[3]; + color[2] = (stroke >> 0 & 0xff) / 255.0f * color[3]; this.width = strokeWidth; this.level = level; diff --git a/src/org/mapsforge/android/utils/GlConfigChooser.java b/src/org/mapsforge/android/utils/GlConfigChooser.java index c26373c3..16e015ea 100644 --- a/src/org/mapsforge/android/utils/GlConfigChooser.java +++ b/src/org/mapsforge/android/utils/GlConfigChooser.java @@ -25,9 +25,9 @@ public class GlConfigChooser implements GLSurfaceView.EGLConfigChooser { // Try to find a normal multisample configuration first. int[] configSpec = { - EGL10.EGL_RED_SIZE, 8, - EGL10.EGL_GREEN_SIZE, 8, - EGL10.EGL_BLUE_SIZE, 8, + EGL10.EGL_RED_SIZE, 5, + EGL10.EGL_GREEN_SIZE, 6, + EGL10.EGL_BLUE_SIZE, 5, EGL10.EGL_ALPHA_SIZE, 0, EGL10.EGL_DEPTH_SIZE, 24, // Requires that setEGLContextClientVersion(2) is called on the view. @@ -132,15 +132,16 @@ public class GlConfigChooser implements GLSurfaceView.EGLConfigChooser { */ return String.format("EGLConfig rgba=%d%d%d%d depth=%d stencil=%d", - new Integer(r), new Integer(g), - new Integer(b), new Integer(a), new Integer(d), new Integer(s)) + Integer.valueOf(r), Integer.valueOf(g), + Integer.valueOf(b), Integer.valueOf(a), Integer.valueOf(d), + Integer.valueOf(s)) + " native=" + findConfigAttrib(egl, display, config, EGL10.EGL_NATIVE_RENDERABLE, 0) + " buffer=" + findConfigAttrib(egl, display, config, EGL10.EGL_BUFFER_SIZE, 0) + String.format( " caveat=0x%04x", - new Integer(findConfigAttrib(egl, display, config, + Integer.valueOf(findConfigAttrib(egl, display, config, EGL10.EGL_CONFIG_CAVEAT, 0))); }