- use Stencil instead of Depth for clipping test
to avoid drawing everything with polygonOffset - add GLState.useProgram
This commit is contained in:
parent
5f03a33492
commit
be748138ac
@ -16,7 +16,6 @@ package org.oscim.renderer;
|
|||||||
|
|
||||||
import static android.opengl.GLES20.GL_ARRAY_BUFFER;
|
import static android.opengl.GLES20.GL_ARRAY_BUFFER;
|
||||||
import static android.opengl.GLES20.GL_BLEND;
|
import static android.opengl.GLES20.GL_BLEND;
|
||||||
import static android.opengl.GLES20.GL_POLYGON_OFFSET_FILL;
|
|
||||||
import static org.oscim.generator.JobTile.STATE_READY;
|
import static org.oscim.generator.JobTile.STATE_READY;
|
||||||
|
|
||||||
import org.oscim.core.MapPosition;
|
import org.oscim.core.MapPosition;
|
||||||
@ -31,7 +30,7 @@ import android.opengl.Matrix;
|
|||||||
* @author Hannes Janetzek
|
* @author Hannes Janetzek
|
||||||
*/
|
*/
|
||||||
public class BaseMap {
|
public class BaseMap {
|
||||||
private final static String TAG = BaseMap.class.getName();
|
//private final static String TAG = BaseMap.class.getName();
|
||||||
|
|
||||||
// used to not draw a tile twice per frame.
|
// used to not draw a tile twice per frame.
|
||||||
private static int mDrawSerial = 0;
|
private static int mDrawSerial = 0;
|
||||||
@ -52,10 +51,10 @@ public class BaseMap {
|
|||||||
static void draw(MapTile[] tiles, int tileCnt, MapPosition pos) {
|
static void draw(MapTile[] tiles, int tileCnt, MapPosition pos) {
|
||||||
//long start = SystemClock.uptimeMillis();
|
//long start = SystemClock.uptimeMillis();
|
||||||
Matrix.multiplyMM(mVPMatrix, 0, mfProjMatrix, 0, pos.viewMatrix, 0);
|
Matrix.multiplyMM(mVPMatrix, 0, mfProjMatrix, 0, pos.viewMatrix, 0);
|
||||||
|
|
||||||
mDrawCnt = 0;
|
mDrawCnt = 0;
|
||||||
|
|
||||||
GLES20.glEnable(GL_POLYGON_OFFSET_FILL);
|
GLES20.glDepthFunc(GLES20.GL_LESS);
|
||||||
|
|
||||||
LineRenderer.beginLines();
|
LineRenderer.beginLines();
|
||||||
for (int i = 0; i < tileCnt; i++) {
|
for (int i = 0; i < tileCnt; i++) {
|
||||||
MapTile t = tiles[i];
|
MapTile t = tiles[i];
|
||||||
@ -63,9 +62,8 @@ public class BaseMap {
|
|||||||
drawTile(t, pos);
|
drawTile(t, pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
// proxies are clipped to the region where nothing was drawn to depth
|
// proxies are clipped to the region where nothing was drawn to depth buffer.
|
||||||
// buffer.
|
// draw child or parent proxies.
|
||||||
// TODO draw all parent before grandparent
|
|
||||||
// TODO draw proxies for placeholder...
|
// TODO draw proxies for placeholder...
|
||||||
for (int i = 0; i < tileCnt; i++) {
|
for (int i = 0; i < tileCnt; i++) {
|
||||||
MapTile t = tiles[i];
|
MapTile t = tiles[i];
|
||||||
@ -73,6 +71,7 @@ public class BaseMap {
|
|||||||
drawProxyTile(t, pos, true);
|
drawProxyTile(t, pos, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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))
|
||||||
@ -81,8 +80,6 @@ public class BaseMap {
|
|||||||
|
|
||||||
LineRenderer.endLines();
|
LineRenderer.endLines();
|
||||||
|
|
||||||
GLES20.glDisable(GL_POLYGON_OFFSET_FILL);
|
|
||||||
//GLES20.glFinish();
|
|
||||||
//long end = SystemClock.uptimeMillis();
|
//long end = SystemClock.uptimeMillis();
|
||||||
//Log.d(TAG, "base took " + (end - start));
|
//Log.d(TAG, "base took " + (end - start));
|
||||||
mDrawSerial++;
|
mDrawSerial++;
|
||||||
@ -103,9 +100,10 @@ public class BaseMap {
|
|||||||
if (t.holder != null)
|
if (t.holder != null)
|
||||||
t = t.holder;
|
t = t.holder;
|
||||||
|
|
||||||
if (t.layers == null || t.vbo == null)
|
if (t.layers == null || t.vbo == null) {
|
||||||
|
//Log.d(TAG, "missing data " + (t.layers == null) + " " + (t.vbo == null));
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
// set Model matrix for tile
|
// set Model matrix for tile
|
||||||
float div = FastMath.pow(tile.zoomLevel - pos.zoomLevel);
|
float div = FastMath.pow(tile.zoomLevel - pos.zoomLevel);
|
||||||
float x = (float) (tile.pixelX - pos.x * div);
|
float x = (float) (tile.pixelX - pos.x * div);
|
||||||
@ -117,8 +115,7 @@ public class BaseMap {
|
|||||||
Matrix.multiplyMM(mvp, 0, mVPMatrix, 0, mvp, 0);
|
Matrix.multiplyMM(mvp, 0, mVPMatrix, 0, mvp, 0);
|
||||||
|
|
||||||
// set depth offset (used for clipping to tile boundaries)
|
// set depth offset (used for clipping to tile boundaries)
|
||||||
//GLES20.glPolygonOffset(-1, -GLRenderer.depthOffset(t));
|
GLES20.glPolygonOffset(1, mDrawCnt++);
|
||||||
GLES20.glPolygonOffset(-1, (mDrawCnt++));
|
|
||||||
|
|
||||||
GLES20.glBindBuffer(GL_ARRAY_BUFFER, t.vbo.id);
|
GLES20.glBindBuffer(GL_ARRAY_BUFFER, t.vbo.id);
|
||||||
|
|
||||||
@ -140,8 +137,6 @@ public class BaseMap {
|
|||||||
PolygonRenderer.draw(pos, null, mvp, true, true);
|
PolygonRenderer.draw(pos, null, mvp, true, true);
|
||||||
clipped = true;
|
clipped = true;
|
||||||
}
|
}
|
||||||
// clip lines to quad in depth buffer
|
|
||||||
GLState.test(true, false);
|
|
||||||
|
|
||||||
GLES20.glEnable(GL_BLEND);
|
GLES20.glEnable(GL_BLEND);
|
||||||
l = LineRenderer.draw(pos, l, mvp, div, simpleShader,
|
l = LineRenderer.draw(pos, l, mvp, div, simpleShader,
|
||||||
@ -149,6 +144,7 @@ public class BaseMap {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
PolygonRenderer.drawOver(mvp);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int drawProxyChild(MapTile tile, MapPosition pos) {
|
private static int drawProxyChild(MapTile tile, MapPosition pos) {
|
||||||
@ -179,8 +175,9 @@ public class BaseMap {
|
|||||||
// draw parent proxy
|
// draw parent proxy
|
||||||
if ((tile.proxies & MapTile.PROXY_PARENT) != 0) {
|
if ((tile.proxies & MapTile.PROXY_PARENT) != 0) {
|
||||||
MapTile t = tile.rel.parent.tile;
|
MapTile t = tile.rel.parent.tile;
|
||||||
if (t.state == STATE_READY)
|
if (t.state == STATE_READY) {
|
||||||
drawTile(t, pos);
|
drawTile(t, pos);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else if ((tile.proxies & MapTile.PROXY_GRAMPA) != 0) {
|
} else if ((tile.proxies & MapTile.PROXY_GRAMPA) != 0) {
|
||||||
// check if parent was already drawn
|
// check if parent was already drawn
|
||||||
@ -197,14 +194,14 @@ public class BaseMap {
|
|||||||
} else {
|
} else {
|
||||||
// prefer drawing parent
|
// prefer drawing parent
|
||||||
if (parent) {
|
if (parent) {
|
||||||
MapTile t = tile.rel.parent.tile;
|
if ((tile.proxies & MapTile.PROXY_PARENT) != 0) {
|
||||||
|
MapTile t = tile.rel.parent.tile;
|
||||||
if (t != null && t.state == STATE_READY) {
|
if (t != null && t.state == STATE_READY) {
|
||||||
drawTile(t, pos);
|
drawTile(t, pos);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
drawProxyChild(tile, pos);
|
drawProxyChild(tile, pos);
|
||||||
|
|
||||||
} else if ((tile.proxies & MapTile.PROXY_GRAMPA) != 0) {
|
} else if ((tile.proxies & MapTile.PROXY_GRAMPA) != 0) {
|
||||||
|
@ -27,6 +27,7 @@ public class GLState {
|
|||||||
private static boolean blend = false;
|
private static boolean blend = false;
|
||||||
private static boolean depth = false;
|
private static boolean depth = false;
|
||||||
private static boolean stencil = false;
|
private static boolean stencil = false;
|
||||||
|
private static int shader;
|
||||||
|
|
||||||
public static void init() {
|
public static void init() {
|
||||||
vertexArray[0] = false;
|
vertexArray[0] = false;
|
||||||
@ -34,11 +35,19 @@ public class GLState {
|
|||||||
blend = false;
|
blend = false;
|
||||||
depth = false;
|
depth = false;
|
||||||
stencil = false;
|
stencil = false;
|
||||||
|
shader = -1;
|
||||||
GLES20.glDisable(GLES20.GL_STENCIL_TEST);
|
GLES20.glDisable(GLES20.GL_STENCIL_TEST);
|
||||||
GLES20.glDisable(GLES20.GL_DEPTH_TEST);
|
GLES20.glDisable(GLES20.GL_DEPTH_TEST);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void useProgram(int shaderProgram) {
|
||||||
|
if (shaderProgram != shader) {
|
||||||
|
GLES20.glUseProgram(shaderProgram);
|
||||||
|
shader = shaderProgram;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO
|
||||||
public static void blend(boolean enable) {
|
public static void blend(boolean enable) {
|
||||||
if (blend == enable)
|
if (blend == enable)
|
||||||
return;
|
return;
|
||||||
|
@ -20,9 +20,7 @@ import static android.opengl.GLES20.glDrawArrays;
|
|||||||
import static android.opengl.GLES20.glGetAttribLocation;
|
import static android.opengl.GLES20.glGetAttribLocation;
|
||||||
import static android.opengl.GLES20.glGetUniformLocation;
|
import static android.opengl.GLES20.glGetUniformLocation;
|
||||||
import static android.opengl.GLES20.glUniform1f;
|
import static android.opengl.GLES20.glUniform1f;
|
||||||
import static android.opengl.GLES20.glUniform1i;
|
|
||||||
import static android.opengl.GLES20.glUniformMatrix4fv;
|
import static android.opengl.GLES20.glUniformMatrix4fv;
|
||||||
import static android.opengl.GLES20.glUseProgram;
|
|
||||||
import static android.opengl.GLES20.glVertexAttribPointer;
|
import static android.opengl.GLES20.glVertexAttribPointer;
|
||||||
|
|
||||||
import org.oscim.core.MapPosition;
|
import org.oscim.core.MapPosition;
|
||||||
@ -119,7 +117,7 @@ public final class LineRenderer {
|
|||||||
if (layer == null)
|
if (layer == null)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
glUseProgram(lineProgram[mode]);
|
GLState.useProgram(lineProgram[mode]);
|
||||||
|
|
||||||
int uLineScale = hLineScale[mode];
|
int uLineScale = hLineScale[mode];
|
||||||
int uLineMode = hLineMode[mode];
|
int uLineMode = hLineMode[mode];
|
||||||
@ -153,7 +151,7 @@ public final class LineRenderer {
|
|||||||
|
|
||||||
glUniform1f(uLineScale, pixel);
|
glUniform1f(uLineScale, pixel);
|
||||||
int lineMode = 0;
|
int lineMode = 0;
|
||||||
glUniform1i(uLineMode, lineMode);
|
glUniform1f(uLineMode, lineMode);
|
||||||
|
|
||||||
float blurScale = pixel;
|
float blurScale = pixel;
|
||||||
boolean blur = false;
|
boolean blur = false;
|
||||||
@ -209,11 +207,11 @@ public final class LineRenderer {
|
|||||||
if (o.roundCap) {
|
if (o.roundCap) {
|
||||||
if (lineMode != 1) {
|
if (lineMode != 1) {
|
||||||
lineMode = 1;
|
lineMode = 1;
|
||||||
glUniform1i(uLineMode, lineMode);
|
glUniform1f(uLineMode, lineMode);
|
||||||
}
|
}
|
||||||
} else if (lineMode != 0) {
|
} else if (lineMode != 0) {
|
||||||
lineMode = 0;
|
lineMode = 0;
|
||||||
glUniform1i(uLineMode, lineMode);
|
glUniform1f(uLineMode, lineMode);
|
||||||
}
|
}
|
||||||
glDrawArrays(GL_TRIANGLE_STRIP, o.offset, o.verticesCnt);
|
glDrawArrays(GL_TRIANGLE_STRIP, o.offset, o.verticesCnt);
|
||||||
}
|
}
|
||||||
@ -244,11 +242,11 @@ public final class LineRenderer {
|
|||||||
if (ll.roundCap) {
|
if (ll.roundCap) {
|
||||||
if (lineMode != 1) {
|
if (lineMode != 1) {
|
||||||
lineMode = 1;
|
lineMode = 1;
|
||||||
glUniform1i(uLineMode, lineMode);
|
glUniform1f(uLineMode, lineMode);
|
||||||
}
|
}
|
||||||
} else if (lineMode != 0) {
|
} else if (lineMode != 0) {
|
||||||
lineMode = 0;
|
lineMode = 0;
|
||||||
glUniform1i(uLineMode, lineMode);
|
glUniform1f(uLineMode, lineMode);
|
||||||
}
|
}
|
||||||
|
|
||||||
glDrawArrays(GL_TRIANGLE_STRIP, l.offset, l.verticesCnt);
|
glDrawArrays(GL_TRIANGLE_STRIP, l.offset, l.verticesCnt);
|
||||||
@ -263,8 +261,9 @@ public final class LineRenderer {
|
|||||||
+ "uniform mat4 u_mvp;"
|
+ "uniform mat4 u_mvp;"
|
||||||
+ "uniform float u_width;"
|
+ "uniform float u_width;"
|
||||||
+ "attribute vec4 a_pos;"
|
+ "attribute vec4 a_pos;"
|
||||||
+ "uniform int u_mode;"
|
+ "uniform float u_mode;"
|
||||||
+ "varying vec2 v_st;"
|
+ "varying vec2 v_st;"
|
||||||
|
+ "varying vec2 v_mode;"
|
||||||
+ "const float dscale = 8.0/2048.0;"
|
+ "const float dscale = 8.0/2048.0;"
|
||||||
+ "void main() {"
|
+ "void main() {"
|
||||||
// scale extrusion to u_width pixel
|
// scale extrusion to u_width pixel
|
||||||
@ -274,22 +273,27 @@ public final class LineRenderer {
|
|||||||
// last two bits of a_st hold the texture coordinates
|
// last two bits of a_st hold the texture coordinates
|
||||||
// ..maybe one could wrap texture so that `abs` is not required
|
// ..maybe one could wrap texture so that `abs` is not required
|
||||||
+ " v_st = abs(mod(dir, 4.0)) - 1.0;"
|
+ " v_st = abs(mod(dir, 4.0)) - 1.0;"
|
||||||
|
+ " v_mode = vec2(1.0 - u_mode, u_mode);"
|
||||||
+ "}";
|
+ "}";
|
||||||
|
|
||||||
private final static String lineSimpleFragmentShader = ""
|
private final static String lineSimpleFragmentShader = ""
|
||||||
+ "precision mediump float;"
|
+ "precision mediump float;"
|
||||||
+ "uniform sampler2D tex;"
|
+ "uniform sampler2D tex;"
|
||||||
+ "uniform int u_mode;"
|
|
||||||
+ "uniform float u_width;"
|
+ "uniform float u_width;"
|
||||||
+ "uniform float u_wscale;"
|
+ "uniform float u_wscale;"
|
||||||
+ "uniform vec4 u_color;"
|
+ "uniform vec4 u_color;"
|
||||||
+ "varying vec2 v_st;"
|
+ "varying vec2 v_st;"
|
||||||
|
+ "varying vec2 v_mode;"
|
||||||
+ "void main() {"
|
+ "void main() {"
|
||||||
+ " float len;"
|
//+ " float len;"
|
||||||
+ " if (u_mode == 0)"
|
// some say one should not use conditionals
|
||||||
+ " len = abs(v_st.s);"
|
// (FIXME currently required as overlay line renderers dont load the texture)
|
||||||
+ " else"
|
//+ " if (u_mode == 0)"
|
||||||
+ " len = texture2D(tex, v_st).a;"
|
//+ " len = abs(v_st.s);"
|
||||||
|
//+ " else"
|
||||||
|
//+ " len = texture2D(tex, v_st).a;"
|
||||||
|
// one trick to avoid branching, need to check performance
|
||||||
|
+ " float len = max(v_mode[0] * abs(v_st.s), v_mode[1] * texture2D(tex, v_st).a);"
|
||||||
// interpolate alpha between: 0.0 < 1.0 - len < u_wscale
|
// interpolate alpha between: 0.0 < 1.0 - len < u_wscale
|
||||||
// where wscale is 'filter width' / 'line width' and 0 <= len <= sqrt(2)
|
// where wscale is 'filter width' / 'line width' and 0 <= len <= sqrt(2)
|
||||||
+ " gl_FragColor = u_color * smoothstep(0.0, u_wscale, 1.0 - len);"
|
+ " gl_FragColor = u_color * smoothstep(0.0, u_wscale, 1.0 - len);"
|
||||||
@ -300,7 +304,7 @@ public final class LineRenderer {
|
|||||||
+ "#extension GL_OES_standard_derivatives : enable\n"
|
+ "#extension GL_OES_standard_derivatives : enable\n"
|
||||||
+ "precision mediump float;"
|
+ "precision mediump float;"
|
||||||
+ "uniform sampler2D tex;"
|
+ "uniform sampler2D tex;"
|
||||||
+ "uniform int u_mode;"
|
+ "uniform float u_mode;"
|
||||||
+ "uniform vec4 u_color;"
|
+ "uniform vec4 u_color;"
|
||||||
+ "uniform float u_width;"
|
+ "uniform float u_width;"
|
||||||
+ "uniform float u_wscale;"
|
+ "uniform float u_wscale;"
|
||||||
@ -308,7 +312,7 @@ public final class LineRenderer {
|
|||||||
+ "void main() {"
|
+ "void main() {"
|
||||||
+ " float len;"
|
+ " float len;"
|
||||||
+ " float fuzz;"
|
+ " float fuzz;"
|
||||||
+ " if (u_mode == 0){"
|
+ " if (u_mode == 0.0){"
|
||||||
+ " len = abs(v_st.s);"
|
+ " len = abs(v_st.s);"
|
||||||
+ " fuzz = fwidth(v_st.s);"
|
+ " fuzz = fwidth(v_st.s);"
|
||||||
+ " } else {"
|
+ " } else {"
|
||||||
@ -317,10 +321,12 @@ public final class LineRenderer {
|
|||||||
+ " vec2 st_width = fwidth(v_st);"
|
+ " vec2 st_width = fwidth(v_st);"
|
||||||
+ " fuzz = max(st_width.s, st_width.t);"
|
+ " fuzz = max(st_width.s, st_width.t);"
|
||||||
+ " }"
|
+ " }"
|
||||||
// smoothstep is too sharp, guess one could increase extrusion with z..
|
|
||||||
// but this looks ok too:
|
|
||||||
+ " gl_FragColor = u_color * min(1.0, (1.0 - len) / (u_wscale + fuzz));"
|
|
||||||
//+ " gl_FragColor = u_color * smoothstep(0.0, fuzz + u_wscale, 1.0 - len);"
|
//+ " gl_FragColor = u_color * smoothstep(0.0, fuzz + u_wscale, 1.0 - len);"
|
||||||
|
// smoothstep is too sharp, guess one could increase extrusion with z..
|
||||||
|
// this looks ok:
|
||||||
|
//+ " gl_FragColor = u_color * min(1.0, (1.0 - len) / (u_wscale + fuzz));"
|
||||||
|
// can be faster according to nvidia docs 'Optimize OpenGL ES 2.0 Performace'
|
||||||
|
+ " gl_FragColor = u_color * clamp((1.0 - len) / (u_wscale + fuzz), 0.0, 1.0);"
|
||||||
+ "}";
|
+ "}";
|
||||||
|
|
||||||
// private final static String lineVertexShader = ""
|
// private final static String lineVertexShader = ""
|
||||||
|
@ -18,13 +18,11 @@ import static android.opengl.GLES20.GL_ALWAYS;
|
|||||||
import static android.opengl.GLES20.GL_BLEND;
|
import static android.opengl.GLES20.GL_BLEND;
|
||||||
import static android.opengl.GLES20.GL_EQUAL;
|
import static android.opengl.GLES20.GL_EQUAL;
|
||||||
import static android.opengl.GLES20.GL_INVERT;
|
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_SHORT;
|
||||||
import static android.opengl.GLES20.GL_TRIANGLE_FAN;
|
import static android.opengl.GLES20.GL_TRIANGLE_FAN;
|
||||||
import static android.opengl.GLES20.GL_TRIANGLE_STRIP;
|
import static android.opengl.GLES20.GL_TRIANGLE_STRIP;
|
||||||
import static android.opengl.GLES20.GL_ZERO;
|
import static android.opengl.GLES20.GL_ZERO;
|
||||||
import static android.opengl.GLES20.glColorMask;
|
import static android.opengl.GLES20.glColorMask;
|
||||||
import static android.opengl.GLES20.glDepthFunc;
|
|
||||||
import static android.opengl.GLES20.glDepthMask;
|
import static android.opengl.GLES20.glDepthMask;
|
||||||
import static android.opengl.GLES20.glDisable;
|
import static android.opengl.GLES20.glDisable;
|
||||||
import static android.opengl.GLES20.glDrawArrays;
|
import static android.opengl.GLES20.glDrawArrays;
|
||||||
@ -36,7 +34,6 @@ import static android.opengl.GLES20.glStencilMask;
|
|||||||
import static android.opengl.GLES20.glStencilOp;
|
import static android.opengl.GLES20.glStencilOp;
|
||||||
import static android.opengl.GLES20.glUniform4fv;
|
import static android.opengl.GLES20.glUniform4fv;
|
||||||
import static android.opengl.GLES20.glUniformMatrix4fv;
|
import static android.opengl.GLES20.glUniformMatrix4fv;
|
||||||
import static android.opengl.GLES20.glUseProgram;
|
|
||||||
import static android.opengl.GLES20.glVertexAttribPointer;
|
import static android.opengl.GLES20.glVertexAttribPointer;
|
||||||
|
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
@ -51,7 +48,7 @@ import org.oscim.utils.GlUtils;
|
|||||||
import android.opengl.GLES20;
|
import android.opengl.GLES20;
|
||||||
|
|
||||||
public final class PolygonRenderer {
|
public final class PolygonRenderer {
|
||||||
// private static final String TAG = "PolygonRenderer";
|
//private static final String TAG = PolygonRenderer.class.getName();
|
||||||
|
|
||||||
// private static final int NUM_VERTEX_SHORTS = 2;
|
// private static final int NUM_VERTEX_SHORTS = 2;
|
||||||
private static final int POLYGON_VERTICES_DATA_POS_OFFSET = 0;
|
private static final int POLYGON_VERTICES_DATA_POS_OFFSET = 0;
|
||||||
@ -93,7 +90,7 @@ public final class PolygonRenderer {
|
|||||||
boolean blend = false;
|
boolean blend = false;
|
||||||
|
|
||||||
/* draw to framebuffer */
|
/* draw to framebuffer */
|
||||||
glColorMask(true, true, true, true);
|
glColorMask(true, true, true, false);
|
||||||
|
|
||||||
/* do not modify stencil buffer */
|
/* do not modify stencil buffer */
|
||||||
glStencilMask(0);
|
glStencilMask(0);
|
||||||
@ -144,18 +141,10 @@ public final class PolygonRenderer {
|
|||||||
glUniform4fv(hPolygonColor, 1, l.area.color, 0);
|
glUniform4fv(hPolygonColor, 1, l.area.color, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// if (alpha < 1) {
|
// set stencil buffer mask used to draw this layer
|
||||||
// if (!blend) {
|
// also check that clip bit is 0 to avoid overdraw
|
||||||
// glEnable(GL_BLEND);
|
// of other tiles
|
||||||
// blend = true;
|
glStencilFunc(GL_EQUAL, 0x7f, 0x80 | 1 << c);
|
||||||
// }
|
|
||||||
// } else if (blend) {
|
|
||||||
// glDisable(GL_BLEND);
|
|
||||||
// blend = false;
|
|
||||||
// }
|
|
||||||
|
|
||||||
/* set stencil buffer mask used to draw this layer */
|
|
||||||
glStencilFunc(GL_EQUAL, 0xff, 1 << c);
|
|
||||||
|
|
||||||
/* draw tile fill coordinates */
|
/* draw tile fill coordinates */
|
||||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||||
@ -195,7 +184,7 @@ public final class PolygonRenderer {
|
|||||||
int zoom = pos.zoomLevel;
|
int zoom = pos.zoomLevel;
|
||||||
float scale = pos.scale;
|
float scale = pos.scale;
|
||||||
|
|
||||||
glUseProgram(polygonProgram);
|
GLState.useProgram(polygonProgram);
|
||||||
|
|
||||||
GLState.enableVertexArrays(hPolygonVertexPosition, -1);
|
GLState.enableVertexArrays(hPolygonVertexPosition, -1);
|
||||||
|
|
||||||
@ -204,82 +193,33 @@ public final class PolygonRenderer {
|
|||||||
|
|
||||||
glUniformMatrix4fv(hPolygonMatrix, 1, false, matrix, 0);
|
glUniformMatrix4fv(hPolygonMatrix, 1, false, matrix, 0);
|
||||||
|
|
||||||
// reset start when only two layer left in stencil buffer
|
// reset start when only one layer left in stencil buffer
|
||||||
// if (mCount > 5) {
|
if (first || mCount > 5) {
|
||||||
// mCount = 0;
|
|
||||||
// mStart = 0;
|
|
||||||
// }
|
|
||||||
|
|
||||||
if (first) {
|
|
||||||
mCount = 0;
|
mCount = 0;
|
||||||
mStart = 0;
|
mStart = 0;
|
||||||
} else {
|
} else {
|
||||||
mStart = mCount;
|
mStart = mCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
//GLState.test(drawClipped, true);
|
GLState.test(false, true);
|
||||||
GLState.test(true, true);
|
|
||||||
|
|
||||||
Layer l = layer;
|
Layer l = layer;
|
||||||
|
|
||||||
for (; l != null && l.type == Layer.POLYGON; l = l.next) {
|
for (; l != null && l.type == Layer.POLYGON; l = l.next) {
|
||||||
PolygonLayer pl = (PolygonLayer) l;
|
PolygonLayer pl = (PolygonLayer) l;
|
||||||
// fade out polygon layers (set in RederTheme)
|
|
||||||
|
// fade out polygon layers (set in RenderTheme)
|
||||||
if (pl.area.fade > 0 && pl.area.fade > zoom)
|
if (pl.area.fade > 0 && pl.area.fade > zoom)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (mCount == mStart) {
|
if (mCount == mStart) {
|
||||||
/* clear stencilbuffer (tile region) by drawing
|
drawStencilRegion(drawClipped, first);
|
||||||
* a quad with func 'always' and op 'zero' */
|
first = false;
|
||||||
|
|
||||||
// disable drawing to framebuffer
|
|
||||||
glColorMask(false, false, false, false);
|
|
||||||
|
|
||||||
// if (!first) {
|
|
||||||
// // first run draw map bg, otherwise
|
|
||||||
// // disable drawing to framebuffer
|
|
||||||
// glColorMask(false, false, false, false);
|
|
||||||
// } else {
|
|
||||||
// glUniform4fv(hPolygonColor, 1, GLRenderer.mClearColor, 0);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// never pass the test: always apply fail op
|
|
||||||
glStencilFunc(GL_ALWAYS, 0, 0xFF);
|
|
||||||
glStencilMask(0xFF);
|
|
||||||
glStencilOp(GL_ZERO, GL_ZERO, GL_ZERO);
|
|
||||||
|
|
||||||
/* draw clip-region into depth buffer:
|
|
||||||
* this is used for lines and polygons */
|
|
||||||
if (first && drawClipped) {
|
|
||||||
// write to depth buffer
|
|
||||||
glDepthMask(true);
|
|
||||||
|
|
||||||
// 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 (first) {
|
|
||||||
// glColorMask(false, false, false, false);
|
|
||||||
// }
|
|
||||||
|
|
||||||
if (first && drawClipped) {
|
|
||||||
first = false;
|
|
||||||
// do not modify depth buffer anymore
|
|
||||||
glDepthMask(false);
|
|
||||||
// only draw to this tile
|
|
||||||
glDepthFunc(GL_EQUAL);
|
|
||||||
}
|
|
||||||
|
|
||||||
// op for stencil method polygon drawing
|
// op for stencil method polygon drawing
|
||||||
glStencilOp(GLES20.GL_KEEP, GLES20.GL_KEEP, GL_INVERT);
|
glStencilOp(GLES20.GL_KEEP, GLES20.GL_KEEP, GL_INVERT);
|
||||||
}
|
}
|
||||||
|
|
||||||
// no need for depth test while drawing stencil
|
|
||||||
//GLState.test(false, true);
|
|
||||||
|
|
||||||
mFillPolys[mCount] = pl;
|
mFillPolys[mCount] = pl;
|
||||||
|
|
||||||
// set stencil mask to draw to
|
// set stencil mask to draw to
|
||||||
@ -287,43 +227,113 @@ public final class PolygonRenderer {
|
|||||||
|
|
||||||
glDrawArrays(GL_TRIANGLE_FAN, l.offset, l.verticesCnt);
|
glDrawArrays(GL_TRIANGLE_FAN, l.offset, l.verticesCnt);
|
||||||
|
|
||||||
// draw up to 8 layers into stencil buffer
|
// draw up to 7 layers into stencil buffer
|
||||||
if (mCount == STENCIL_BITS) {
|
if (mCount == STENCIL_BITS - 1) {
|
||||||
/* only draw where nothing was drawn yet */
|
|
||||||
if (drawClipped)
|
|
||||||
GLState.test(true, true);
|
|
||||||
|
|
||||||
fillPolygons(zoom, scale);
|
fillPolygons(zoom, scale);
|
||||||
mCount = 0;
|
mCount = 0;
|
||||||
mStart = 0;
|
mStart = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mCount > 0) {
|
if (mCount > 0)
|
||||||
/* only draw where nothing was drawn yet */
|
|
||||||
if (drawClipped)
|
|
||||||
GLState.test(true, true);
|
|
||||||
|
|
||||||
fillPolygons(zoom, scale);
|
fillPolygons(zoom, scale);
|
||||||
|
|
||||||
|
if (drawClipped) {
|
||||||
|
if (first) {
|
||||||
|
drawStencilRegion(drawClipped, first);
|
||||||
|
|
||||||
|
glStencilMask(0x00);
|
||||||
|
glColorMask(true, true, true, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
// clip bit must be zero
|
||||||
|
glStencilFunc(GL_EQUAL, 0x00, 0x80);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (drawClipped && first) {
|
|
||||||
GLState.test(true, false);
|
|
||||||
GLES20.glColorMask(false, false, false, false);
|
|
||||||
//glUniform4fv(hPolygonColor, 1, GLRenderer.mClearColor, 0);
|
|
||||||
|
|
||||||
GLES20.glDepthMask(true);
|
|
||||||
GLES20.glDepthFunc(GLES20.GL_LESS);
|
|
||||||
|
|
||||||
GLES20.glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
|
||||||
|
|
||||||
GLES20.glDepthMask(false);
|
|
||||||
GLES20.glColorMask(true, true, true, true);
|
|
||||||
GLES20.glDepthFunc(GLES20.GL_EQUAL);
|
|
||||||
}
|
|
||||||
return l;
|
return l;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void drawStencilRegion(boolean clip, boolean first) {
|
||||||
|
/* clear stencilbuffer (tile region) by drawing
|
||||||
|
* a quad with func 'always' and op 'zero' */
|
||||||
|
|
||||||
|
// disable drawing to framebuffer (will be re-enabled in fill)
|
||||||
|
glColorMask(false, false, false, false);
|
||||||
|
GLES20.glUniform4f(hPolygonColor, 0.7f, 0.7f, 0.7f, 1);
|
||||||
|
|
||||||
|
// write to all bits
|
||||||
|
glStencilMask(0xFF);
|
||||||
|
// zero out area to draw to
|
||||||
|
glStencilOp(GLES20.GL_KEEP, GLES20.GL_KEEP, GL_ZERO);
|
||||||
|
|
||||||
|
if (clip) {
|
||||||
|
if (first) {
|
||||||
|
// draw clip-region into depth and stencil buffer:
|
||||||
|
// this is used for tile line and polygon layers
|
||||||
|
|
||||||
|
// always pass stencil test:
|
||||||
|
glStencilFunc(GL_ALWAYS, 0x00, 0x00);
|
||||||
|
|
||||||
|
GLES20.glEnable(GLES20.GL_POLYGON_OFFSET_FILL);
|
||||||
|
|
||||||
|
// test depth. stencil passes always, just keep it enabled
|
||||||
|
GLState.test(true, true);
|
||||||
|
// write to depth buffer
|
||||||
|
glDepthMask(true);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// use clip region from stencil buffer
|
||||||
|
glStencilFunc(GL_EQUAL, 0x00, 0x80);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// always pass stencil test:
|
||||||
|
glStencilFunc(GL_ALWAYS, 0x00, 0x00);
|
||||||
|
}
|
||||||
|
|
||||||
|
// draw a quad for the tile region
|
||||||
|
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||||
|
|
||||||
|
if (clip) {
|
||||||
|
if (first) {
|
||||||
|
// dont modify depth buffer
|
||||||
|
glDepthMask(false);
|
||||||
|
|
||||||
|
GLState.test(false, true);
|
||||||
|
|
||||||
|
GLES20.glDisable(GLES20.GL_POLYGON_OFFSET_FILL);
|
||||||
|
} else {
|
||||||
|
glStencilFunc(GL_ALWAYS, 0x00, 0x00);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void drawOver(float[] matrix) {
|
||||||
|
GLState.useProgram(polygonProgram);
|
||||||
|
|
||||||
|
GLState.enableVertexArrays(hPolygonVertexPosition, -1);
|
||||||
|
|
||||||
|
glVertexAttribPointer(hPolygonVertexPosition, 2, GL_SHORT,
|
||||||
|
false, 0, POLYGON_VERTICES_DATA_POS_OFFSET);
|
||||||
|
|
||||||
|
glUniformMatrix4fv(hPolygonMatrix, 1, false, matrix, 0);
|
||||||
|
|
||||||
|
/* clear stencilbuffer (tile region) by drawing
|
||||||
|
* a quad with func 'always' and op 'zero' */
|
||||||
|
|
||||||
|
// disable drawing to framebuffer (will be re-enabled in fill)
|
||||||
|
glColorMask(false, false, false, false);
|
||||||
|
|
||||||
|
// always pass stencil test:
|
||||||
|
glStencilFunc(GL_ALWAYS, 0xFF, 0xFF);
|
||||||
|
// write to all bits
|
||||||
|
glStencilMask(0xFF);
|
||||||
|
// zero out area to draw to
|
||||||
|
glStencilOp(GLES20.GL_KEEP, GLES20.GL_KEEP, GLES20.GL_REPLACE);
|
||||||
|
|
||||||
|
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||||
|
glColorMask(true, true, true, true);
|
||||||
|
}
|
||||||
|
|
||||||
private static float[] debugFillColor = { 0.3f, 0.0f, 0.0f, 0.3f };
|
private static float[] debugFillColor = { 0.3f, 0.0f, 0.0f, 0.3f };
|
||||||
private static float[] debugFillColor2 = { .8f, .8f, .8f, .8f };
|
private static float[] debugFillColor2 = { .8f, .8f, .8f, .8f };
|
||||||
private static FloatBuffer mDebugFill;
|
private static FloatBuffer mDebugFill;
|
||||||
@ -339,7 +349,7 @@ public final class PolygonRenderer {
|
|||||||
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0);
|
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0);
|
||||||
|
|
||||||
mDebugFill.position(0);
|
mDebugFill.position(0);
|
||||||
glUseProgram(polygonProgram);
|
GLState.useProgram(polygonProgram);
|
||||||
GLES20.glEnableVertexAttribArray(hPolygonVertexPosition);
|
GLES20.glEnableVertexAttribArray(hPolygonVertexPosition);
|
||||||
|
|
||||||
glVertexAttribPointer(hPolygonVertexPosition, 2, GLES20.GL_FLOAT,
|
glVertexAttribPointer(hPolygonVertexPosition, 2, GLES20.GL_FLOAT,
|
||||||
|
@ -93,7 +93,7 @@ public final class TextureRenderer {
|
|||||||
GLState.test(false, false);
|
GLState.test(false, false);
|
||||||
GLES20.glEnable(GLES20.GL_BLEND);
|
GLES20.glEnable(GLES20.GL_BLEND);
|
||||||
// GlUtils.checkGlError("draw texture >");
|
// GlUtils.checkGlError("draw texture >");
|
||||||
GLES20.glUseProgram(mTextureProgram);
|
GLState.useProgram(mTextureProgram);
|
||||||
|
|
||||||
GLState.enableVertexArrays(hTextureTexCoord, hTextureVertex);
|
GLState.enableVertexArrays(hTextureTexCoord, hTextureVertex);
|
||||||
|
|
||||||
|
@ -350,7 +350,7 @@ public class BuildingOverlay extends RenderOverlay {
|
|||||||
setMatrix(pos, mv);
|
setMatrix(pos, mv);
|
||||||
Matrix.multiplyMM(mv, 0, proj, 0, mv, 0);
|
Matrix.multiplyMM(mv, 0, proj, 0, mv, 0);
|
||||||
|
|
||||||
GLES20.glUseProgram(buildingProgram);
|
GLState.useProgram(buildingProgram);
|
||||||
|
|
||||||
GLES20.glUniformMatrix4fv(hBuildingMatrix, 1, false, mv, 0);
|
GLES20.glUniformMatrix4fv(hBuildingMatrix, 1, false, mv, 0);
|
||||||
GLES20.glUniform4f(hBuildingColor, 0.5f, 0.5f, 0.5f, 0.7f);
|
GLES20.glUniform4f(hBuildingColor, 0.5f, 0.5f, 0.5f, 0.7f);
|
||||||
|
@ -180,7 +180,7 @@ public class ExtrusionOverlay extends RenderOverlay {
|
|||||||
int uExtMode = hExtrusionMode[shaderMode];
|
int uExtMode = hExtrusionMode[shaderMode];
|
||||||
|
|
||||||
if (debug) {
|
if (debug) {
|
||||||
GLES20.glUseProgram(extrusionProgram[shaderMode]);
|
GLState.useProgram(extrusionProgram[shaderMode]);
|
||||||
|
|
||||||
GLState.enableVertexArrays(uExtVertexPosition, uExtLightPosition);
|
GLState.enableVertexArrays(uExtVertexPosition, uExtLightPosition);
|
||||||
GLES20.glUniform1i(uExtMode, 0);
|
GLES20.glUniform1i(uExtMode, 0);
|
||||||
@ -224,9 +224,11 @@ public class ExtrusionOverlay extends RenderOverlay {
|
|||||||
|
|
||||||
GLState.test(true, false);
|
GLState.test(true, false);
|
||||||
|
|
||||||
GLES20.glUseProgram(extrusionProgram[shaderMode]);
|
GLState.useProgram(extrusionProgram[shaderMode]);
|
||||||
GLState.enableVertexArrays(uExtVertexPosition, -1);
|
GLState.enableVertexArrays(uExtVertexPosition, -1);
|
||||||
if (pos.scale < 2) {
|
if (pos.scale < 2) {
|
||||||
|
// chances are high that one moves through a building
|
||||||
|
// with scale > 2 also draw back sides in this case.
|
||||||
GLES20.glEnable(GLES20.GL_CULL_FACE);
|
GLES20.glEnable(GLES20.GL_CULL_FACE);
|
||||||
GLES20.glCullFace(GLES20.GL_FRONT);
|
GLES20.glCullFace(GLES20.GL_FRONT);
|
||||||
}
|
}
|
||||||
|
@ -172,7 +172,7 @@ public class ModelOverlay extends RenderOverlay {
|
|||||||
setMatrix(pos, mv);
|
setMatrix(pos, mv);
|
||||||
Matrix.multiplyMM(mv, 0, proj, 0, mv, 0);
|
Matrix.multiplyMM(mv, 0, proj, 0, mv, 0);
|
||||||
|
|
||||||
GLES20.glUseProgram(polygonProgram);
|
GLState.useProgram(polygonProgram);
|
||||||
|
|
||||||
GLState.enableVertexArrays(hPolygonVertexPosition, hPolygonLightPosition);
|
GLState.enableVertexArrays(hPolygonVertexPosition, hPolygonLightPosition);
|
||||||
|
|
||||||
|
@ -66,7 +66,7 @@ public class TestLineOverlay extends RenderOverlay {
|
|||||||
//
|
//
|
||||||
// Vertex layout:
|
// Vertex layout:
|
||||||
// x/y pos[16][16], dir_x[8]|dir_y[8], start[4]|length[12]
|
// x/y pos[16][16], dir_x[8]|dir_y[8], start[4]|length[12]
|
||||||
// - 'direction' precision 1/16 maximum line width is 2*32
|
// - 'direction' precision 1/16, maximum line width is 2*16
|
||||||
// - texture 'start' prescision 1
|
// - texture 'start' prescision 1
|
||||||
// -> max tex width is 32
|
// -> max tex width is 32
|
||||||
// - segment 'length' prescision 1/4
|
// - segment 'length' prescision 1/4
|
||||||
@ -99,16 +99,18 @@ public class TestLineOverlay extends RenderOverlay {
|
|||||||
0, 0, 0, 0,
|
0, 0, 0, 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
private final short[] indices = {
|
private short[] indices = {
|
||||||
0, 1, 2,
|
0, 1, 2,
|
||||||
2, 1, 3,
|
2, 1, 3,
|
||||||
|
|
||||||
4, 5, 6,
|
4, 5, 6,
|
||||||
6, 5, 7,
|
6, 5, 7,
|
||||||
|
|
||||||
8, 9, 10,
|
8, 9, 10,
|
||||||
10, 9, 11,
|
10, 9, 11,
|
||||||
};
|
};
|
||||||
|
|
||||||
private byte[] flip = { 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1 };
|
private byte[] flip;
|
||||||
|
|
||||||
private static int testProgram;
|
private static int testProgram;
|
||||||
private static int htestVertexPosition0;
|
private static int htestVertexPosition0;
|
||||||
@ -131,13 +133,14 @@ public class TestLineOverlay extends RenderOverlay {
|
|||||||
+ "const float ffff = 65536.0;"
|
+ "const float ffff = 65536.0;"
|
||||||
+ "void main() {"
|
+ "void main() {"
|
||||||
+ " if (a_flip == 0.0){"
|
+ " if (a_flip == 0.0){"
|
||||||
+ " vec2 dir = vec2((a_pos0.z / ffff), fract(a_pos0.z/ff))*64.0;"
|
// extract 8 bit direction vector
|
||||||
|
+ " vec2 dir = a_pos0.zw/16.0;"
|
||||||
+ " gl_Position = u_mvp * vec4(a_pos0.xy + dir, 0.0, 1.0);"
|
+ " gl_Position = u_mvp * vec4(a_pos0.xy + dir, 0.0, 1.0);"
|
||||||
+ " color = vec4(0.0,1.0,a_pos0.w,1.0);"
|
+ " color = vec4(dir/255.0 + 0.5, 1.0,1.0);"
|
||||||
+ " }else {"
|
+ " }else {"
|
||||||
+ " vec2 dir = vec2((a_pos1.z / ffff), fract(a_pos1.z/ff))*64.0;"
|
+ " vec2 dir = a_pos1.zw/16.0;"
|
||||||
+ " gl_Position = u_mvp * vec4(a_pos1.xy - dir, 0.0, 1.0);"
|
+ " gl_Position = u_mvp * vec4(a_pos1.xy - dir, 0.0, 1.0);"
|
||||||
+ " color = vec4(1.0,0.5,a_pos1.w,1.0);"
|
+ " color = vec4(dir/255.0 + 0.5, 1.0,1.0);"
|
||||||
+ "}}";
|
+ "}}";
|
||||||
|
|
||||||
final static String testFragmentShader = ""
|
final static String testFragmentShader = ""
|
||||||
@ -151,6 +154,9 @@ public class TestLineOverlay extends RenderOverlay {
|
|||||||
private int mVertexBufferID;
|
private int mVertexBufferID;
|
||||||
private int mVertexFlipID;
|
private int mVertexFlipID;
|
||||||
|
|
||||||
|
private int mNumVertices;
|
||||||
|
private int mNumIndices;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public synchronized void update(MapPosition curPos, boolean positionChanged,
|
public synchronized void update(MapPosition curPos, boolean positionChanged,
|
||||||
boolean tilesChanged) {
|
boolean tilesChanged) {
|
||||||
@ -178,6 +184,93 @@ public class TestLineOverlay extends RenderOverlay {
|
|||||||
mVertexBufferID = mVboIds[1];
|
mVertexBufferID = mVboIds[1];
|
||||||
mVertexFlipID = mVboIds[2];
|
mVertexFlipID = mVboIds[2];
|
||||||
|
|
||||||
|
float points[] = {
|
||||||
|
800, 0,
|
||||||
|
0, 0,
|
||||||
|
//-400, 100,
|
||||||
|
//-600, 200,
|
||||||
|
//-800, 100,
|
||||||
|
};
|
||||||
|
|
||||||
|
// float[] points = new float[12 * 2];
|
||||||
|
// for (int i = 0; i < 24; i += 2) {
|
||||||
|
// points[i + 0] = (float) Math.sin(-i / 11f * Math.PI) * 400;
|
||||||
|
// points[i + 1] = (float) Math.cos(-i / 11f * Math.PI) * 400;
|
||||||
|
// }
|
||||||
|
|
||||||
|
mNumVertices = (points.length - 2) * 2;
|
||||||
|
|
||||||
|
short[] vertices = new short[(mNumVertices + 2) * 4];
|
||||||
|
|
||||||
|
int opos = 4;
|
||||||
|
|
||||||
|
float x = points[0];
|
||||||
|
float y = points[1];
|
||||||
|
|
||||||
|
float scale = 127;
|
||||||
|
boolean even = true;
|
||||||
|
|
||||||
|
for (int i = 2; i < points.length;) {
|
||||||
|
float nx = points[i++];
|
||||||
|
float ny = points[i++];
|
||||||
|
|
||||||
|
// Calculate triangle corners for the given width
|
||||||
|
float vx = nx - x;
|
||||||
|
float vy = ny - y;
|
||||||
|
|
||||||
|
float a = (float) Math.sqrt(vx * vx + vy * vy);
|
||||||
|
|
||||||
|
// normal vector
|
||||||
|
vx = (vx / a);
|
||||||
|
vy = (vy / a);
|
||||||
|
|
||||||
|
float ux = -vy;
|
||||||
|
float uy = vx;
|
||||||
|
|
||||||
|
short dx = (short) (ux * scale);
|
||||||
|
short dy = (short) (uy * scale);
|
||||||
|
|
||||||
|
vertices[opos + 0] = (short) x;
|
||||||
|
vertices[opos + 1] = (short) y;
|
||||||
|
vertices[opos + 2] = dx;
|
||||||
|
vertices[opos + 3] = dy;
|
||||||
|
|
||||||
|
vertices[opos + 8] = (short) nx;
|
||||||
|
vertices[opos + 9] = (short) ny;
|
||||||
|
vertices[opos + 10] = dx;
|
||||||
|
vertices[opos + 11] = dy;
|
||||||
|
|
||||||
|
x = nx;
|
||||||
|
y = ny;
|
||||||
|
|
||||||
|
if (even) {
|
||||||
|
opos += 4;
|
||||||
|
even = false;
|
||||||
|
} else {
|
||||||
|
even = true;
|
||||||
|
opos += 12;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
flip = new byte[(points.length - 2)];
|
||||||
|
for (int i = 0; i < flip.length; i++)
|
||||||
|
flip[i] = (byte) (i % 2);
|
||||||
|
|
||||||
|
short j = 0;
|
||||||
|
mNumIndices = ((points.length) >> 2) * 6;
|
||||||
|
|
||||||
|
indices = new short[mNumIndices];
|
||||||
|
for (int i = 0; i < mNumIndices; i += 6, j += 4) {
|
||||||
|
indices[i + 0] = (short) (j + 0);
|
||||||
|
indices[i + 1] = (short) (j + 1);
|
||||||
|
indices[i + 2] = (short) (j + 2);
|
||||||
|
|
||||||
|
indices[i + 3] = (short) (j + 2);
|
||||||
|
indices[i + 4] = (short) (j + 1);
|
||||||
|
indices[i + 5] = (short) (j + 3);
|
||||||
|
}
|
||||||
|
|
||||||
ByteBuffer buf = ByteBuffer.allocateDirect(128 * 4)
|
ByteBuffer buf = ByteBuffer.allocateDirect(128 * 4)
|
||||||
.order(ByteOrder.nativeOrder());
|
.order(ByteOrder.nativeOrder());
|
||||||
|
|
||||||
@ -185,20 +278,24 @@ public class TestLineOverlay extends RenderOverlay {
|
|||||||
sbuf.put(indices);
|
sbuf.put(indices);
|
||||||
sbuf.flip();
|
sbuf.flip();
|
||||||
GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, mIndicesBufferID);
|
GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, mIndicesBufferID);
|
||||||
GLES20.glBufferData(GLES20.GL_ELEMENT_ARRAY_BUFFER, 18 * 2, sbuf, GLES20.GL_STATIC_DRAW);
|
GLES20.glBufferData(GLES20.GL_ELEMENT_ARRAY_BUFFER, indices.length * 2, sbuf,
|
||||||
|
GLES20.GL_STATIC_DRAW);
|
||||||
GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, 0);
|
GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||||
|
|
||||||
sbuf.clear();
|
sbuf.clear();
|
||||||
sbuf.put(box);
|
//sbuf.put(box);
|
||||||
|
sbuf.put(vertices);
|
||||||
sbuf.flip();
|
sbuf.flip();
|
||||||
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, mVertexBufferID);
|
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, mVertexBufferID);
|
||||||
GLES20.glBufferData(GLES20.GL_ARRAY_BUFFER, 56 * 2, sbuf, GLES20.GL_STATIC_DRAW);
|
GLES20.glBufferData(GLES20.GL_ARRAY_BUFFER, vertices.length * 2, sbuf,
|
||||||
|
GLES20.GL_STATIC_DRAW);
|
||||||
|
|
||||||
buf.clear();
|
buf.clear();
|
||||||
buf.put(flip);
|
buf.put(flip);
|
||||||
buf.flip();
|
buf.flip();
|
||||||
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, mVertexFlipID);
|
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, mVertexFlipID);
|
||||||
GLES20.glBufferData(GLES20.GL_ARRAY_BUFFER, 12, buf, GLES20.GL_STATIC_DRAW);
|
GLES20.glBufferData(GLES20.GL_ARRAY_BUFFER, flip.length, buf,
|
||||||
|
GLES20.GL_STATIC_DRAW);
|
||||||
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0);
|
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0);
|
||||||
|
|
||||||
mMapView.getMapViewPosition().getMapPosition(mMapPosition, null);
|
mMapView.getMapViewPosition().getMapPosition(mMapPosition, null);
|
||||||
@ -213,12 +310,13 @@ public class TestLineOverlay extends RenderOverlay {
|
|||||||
setMatrix(pos, mv);
|
setMatrix(pos, mv);
|
||||||
Matrix.multiplyMM(mv, 0, proj, 0, mv, 0);
|
Matrix.multiplyMM(mv, 0, proj, 0, mv, 0);
|
||||||
|
|
||||||
GLES20.glUseProgram(testProgram);
|
GLState.useProgram(testProgram);
|
||||||
GLES20.glDisable(GLES20.GL_CULL_FACE);
|
GLES20.glDisable(GLES20.GL_CULL_FACE);
|
||||||
GLState.test(false, false);
|
GLState.test(false, false);
|
||||||
GLState.enableVertexArrays(-1, -1);
|
GLState.enableVertexArrays(-1, -1);
|
||||||
GLES20.glEnableVertexAttribArray(htestVertexPosition0);
|
GLES20.glEnableVertexAttribArray(htestVertexPosition0);
|
||||||
GLES20.glEnableVertexAttribArray(htestVertexPosition1);
|
GLES20.glEnableVertexAttribArray(htestVertexPosition1);
|
||||||
|
|
||||||
GLES20.glEnableVertexAttribArray(htestVertexFlip);
|
GLES20.glEnableVertexAttribArray(htestVertexFlip);
|
||||||
|
|
||||||
GLES20.glUniformMatrix4fv(htestMatrix, 1, false, mv, 0);
|
GLES20.glUniformMatrix4fv(htestMatrix, 1, false, mv, 0);
|
||||||
@ -230,15 +328,23 @@ public class TestLineOverlay extends RenderOverlay {
|
|||||||
|
|
||||||
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, mVertexBufferID);
|
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, mVertexBufferID);
|
||||||
|
|
||||||
GLES20.glVertexAttribPointer(htestVertexPosition0, 4, GLES20.GL_SHORT, false, 0, 8);
|
GLES20.glVertexAttribPointer(htestVertexPosition0,
|
||||||
GLES20.glVertexAttribPointer(htestVertexPosition1, 4, GLES20.GL_SHORT, false, 0, 0);
|
4, GLES20.GL_SHORT, false, 0, 8);
|
||||||
GLES20.glUniform4f(htestColor, 0.5f, 0.5f, 1.0f, 1.0f);
|
|
||||||
GLES20.glDrawElements(GLES20.GL_TRIANGLES, 18, GLES20.GL_UNSIGNED_SHORT, 0);
|
GLES20.glVertexAttribPointer(htestVertexPosition1,
|
||||||
|
4, GLES20.GL_SHORT, false, 0, 0);
|
||||||
|
|
||||||
|
GLES20.glUniform4f(htestColor, 0.5f, 0.5f, 1.0f, 1.0f);
|
||||||
|
GLES20.glDrawElements(GLES20.GL_TRIANGLES, mNumIndices, GLES20.GL_UNSIGNED_SHORT, 0);
|
||||||
|
|
||||||
|
GLES20.glVertexAttribPointer(htestVertexPosition0,
|
||||||
|
4, GLES20.GL_SHORT, false, 0, 16);
|
||||||
|
|
||||||
|
GLES20.glVertexAttribPointer(htestVertexPosition1,
|
||||||
|
4, GLES20.GL_SHORT, false, 0, 8);
|
||||||
|
|
||||||
GLES20.glVertexAttribPointer(htestVertexPosition0, 4, GLES20.GL_SHORT, false, 0, 16);
|
|
||||||
GLES20.glVertexAttribPointer(htestVertexPosition1, 4, GLES20.GL_SHORT, false, 0, 8);
|
|
||||||
GLES20.glUniform4f(htestColor, 0.5f, 1.0f, 0.5f, 1.0f);
|
GLES20.glUniform4f(htestColor, 0.5f, 1.0f, 0.5f, 1.0f);
|
||||||
GLES20.glDrawElements(GLES20.GL_TRIANGLES, 18, GLES20.GL_UNSIGNED_SHORT, 0);
|
GLES20.glDrawElements(GLES20.GL_TRIANGLES, mNumIndices, GLES20.GL_UNSIGNED_SHORT, 0);
|
||||||
|
|
||||||
GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, 0);
|
GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user