diff --git a/vtm/src/org/oscim/renderer/ExtrusionRenderer.java b/vtm/src/org/oscim/renderer/ExtrusionRenderer.java index 3680229a..d0c07e62 100644 --- a/vtm/src/org/oscim/renderer/ExtrusionRenderer.java +++ b/vtm/src/org/oscim/renderer/ExtrusionRenderer.java @@ -59,14 +59,6 @@ public class ExtrusionRenderer extends LayerRenderer { drawAlpha = false; //alpha; } - private static int[] shaderProgram = new int[2]; - private static int[] hVertexPosition = new int[2]; - private static int[] hLightPosition = new int[2]; - private static int[] hMatrix = new int[2]; - private static int[] hColor = new int[2]; - private static int[] hAlpha = new int[2]; - private static int[] hMode = new int[2]; - private boolean initialized = false; private final TileSet mTileSet; @@ -75,30 +67,29 @@ public class ExtrusionRenderer extends LayerRenderer { private final int mMode; + static class Shader extends GLShader { + int uMVP, uColor, uAlpha, uMode, aPos, aLight; + + public Shader(String shader) { + if (!create(shader)) + return; + + uMVP = getUniform("u_mvp"); + uColor = getUniform("u_color"); + uAlpha = getUniform("u_alpha"); + uMode = getUniform("u_mode"); + aPos = getAttrib("a_pos"); + aLight = getAttrib("a_light"); + } + } + + private Shader mShader[] = { null, null }; + private boolean initShader() { initialized = true; - for (int i = 0; i < 2; i++) { - if (i == 0) { - shaderProgram[i] = GLShader.createProgram(extrusionVertexShader, - extrusionFragmentShader); - } else { - shaderProgram[i] = GLShader.createProgram(extrusionVertexShader2, - extrusionFragmentShader); - } - - if (shaderProgram[i] == 0) { - log.error("Could not create extrusion shader program. " + i); - return false; - } - - hMatrix[i] = GL.glGetUniformLocation(shaderProgram[i], "u_mvp"); - hColor[i] = GL.glGetUniformLocation(shaderProgram[i], "u_color"); - hAlpha[i] = GL.glGetUniformLocation(shaderProgram[i], "u_alpha"); - hMode[i] = GL.glGetUniformLocation(shaderProgram[i], "u_mode"); - hVertexPosition[i] = GL.glGetAttribLocation(shaderProgram[i], "a_pos"); - hLightPosition[i] = GL.glGetAttribLocation(shaderProgram[i], "a_light"); - } + mShader[0] = new Shader("extrusion_layer_ext"); + mShader[1] = new Shader("extrusion_layer_mesh"); return true; } @@ -109,8 +100,8 @@ public class ExtrusionRenderer extends LayerRenderer { if (!initialized && !initShader()) return; - if (shaderProgram[0] == 0) - return; + // if (shaderProgram[0] == 0) + // return; if (mAlpha == 0 || v.pos.zoomLevel < mTileZoom) { setReady(false); @@ -195,9 +186,6 @@ public class ExtrusionRenderer extends LayerRenderer { int sumIndices = 0; int sumVertices = 0; for (ExtrusionLayer l = el; l != null; l = l.next()) { - //if (l.sumIndices == 0){ - // l.clear(); - //} sumIndices += l.sumIndices; sumVertices += l.sumVertices; } @@ -220,8 +208,6 @@ public class ExtrusionRenderer extends LayerRenderer { el.vboIndices.loadBufferData(ibuf.flip(), size); el.vboIndices.unbind(); - //GL.glBindBuffer(GL20.GL_ELEMENT_ARRAY_BUFFER, 0); - size = sumVertices * 4 * 2; if (vbuf.position() != sumVertices * 4) { int pos = vbuf.position(); @@ -233,8 +219,6 @@ public class ExtrusionRenderer extends LayerRenderer { el.vboVertices.loadBufferData(vbuf.flip(), size); el.vboVertices.unbind(); - //GL.glBindBuffer(GL20.GL_ARRAY_BUFFER, 0); - GLUtils.checkGlError("compile extrusion layer"); return true; } @@ -249,10 +233,6 @@ public class ExtrusionRenderer extends LayerRenderer { private final boolean debug = false; - @Override - public void render(GLViewport v) { - } - private void renderCombined(int vertexPointer, ExtrusionLayer el) { for (; el != null; el = el.next()) { @@ -278,26 +258,23 @@ public class ExtrusionRenderer extends LayerRenderer { } } - public void render2(GLViewport v) { + @Override + public void render(GLViewport v) { // TODO one could render in one pass to texture and then draw the texture // with alpha... might be faster and would allow postprocessing outlines. MapTile[] tiles = mTiles; - - int uExtAlpha = hAlpha[mMode]; - int uExtColor = hColor[mMode]; - int uExtVertexPosition = hVertexPosition[mMode]; - int uExtLightPosition = hLightPosition[mMode]; - int uExtMatrix = hMatrix[mMode]; - int uExtMode = hMode[mMode]; + Shader s = mShader[mMode]; if (debug) { - GLState.useProgram(shaderProgram[mMode]); + s.useProgram(); - GLState.enableVertexArrays(uExtVertexPosition, uExtLightPosition); - GL.glUniform1i(uExtMode, 0); - GLUtils.glUniform4fv(uExtColor, 4, DEBUG_COLOR); - GL.glUniform1f(uExtAlpha, 1); + //GLState.useProgram(shaderProgram[mMode]); + + GLState.enableVertexArrays(s.aPos, s.aLight); + GL.glUniform1i(s.uMode, 0); + GLUtils.glUniform4fv(s.uColor, 4, DEBUG_COLOR); + GL.glUniform1f(s.uAlpha, 1); GLState.test(false, false); GLState.blend(true); @@ -305,9 +282,9 @@ public class ExtrusionRenderer extends LayerRenderer { ExtrusionLayer el = tiles[i].getLayers().getExtrusionLayers(); setMatrix(v, tiles[i], 0); - v.mvp.setAsUniform(uExtMatrix); + v.mvp.setAsUniform(s.uMVP); - renderCombined(uExtVertexPosition, el); + renderCombined(s.aPos, el); // just a temporary reference! tiles[i] = null; @@ -320,19 +297,20 @@ public class ExtrusionRenderer extends LayerRenderer { GLState.test(true, false); - GLState.useProgram(shaderProgram[mMode]); - GLState.enableVertexArrays(uExtVertexPosition, -1); + s.useProgram(); + //GLState.useProgram(shaderProgram[mMode]); + GLState.enableVertexArrays(s.aPos, -1); GLState.blend(false); GL.glEnable(GL20.GL_CULL_FACE); GL.glDepthFunc(GL20.GL_LESS); //GL.glUniform1f(uExtAlpha, mAlpha); - GL.glUniform1f(uExtAlpha, 1); + GL.glUniform1f(s.uAlpha, 1); if (drawAlpha) { GL.glColorMask(false, false, false, false); - GL.glUniform1i(uExtMode, -1); + GL.glUniform1i(s.uMode, -1); //GLUtils.glUniform4fv(uExtColor, 4, mColor); // draw to depth buffer @@ -345,9 +323,9 @@ public class ExtrusionRenderer extends LayerRenderer { int d = MapTile.depthOffset(t) * 10; setMatrix(v, t, d); - v.mvp.setAsUniform(uExtMatrix); + v.mvp.setAsUniform(s.uMVP); - renderCombined(uExtVertexPosition, el); + renderCombined(s.aPos, el); } GL.glColorMask(true, true, true, true); @@ -355,13 +333,8 @@ public class ExtrusionRenderer extends LayerRenderer { GLState.blend(true); } - //GLState.blend(false); - //GLState.blend(true); - //GL.glEnable(GL20.GL_BLEND); - GLState.blend(true); - - GLState.enableVertexArrays(uExtVertexPosition, uExtLightPosition); + GLState.enableVertexArrays(s.aPos, s.aLight); float[] currentColor = null; @@ -382,7 +355,7 @@ public class ExtrusionRenderer extends LayerRenderer { } setMatrix(v, t, d); - v.mvp.setAsUniform(uExtMatrix); + v.mvp.setAsUniform(s.uMVP); el.vboIndices.bind(); el.vboVertices.bind(); @@ -391,7 +364,7 @@ public class ExtrusionRenderer extends LayerRenderer { if (el.colors != currentColor) { currentColor = el.colors; - GLUtils.glUniform4fv(uExtColor, mMode == 0 ? 4 : 1, + GLUtils.glUniform4fv(s.uColor, mMode == 0 ? 4 : 1, el.colors); } @@ -400,27 +373,27 @@ public class ExtrusionRenderer extends LayerRenderer { /* vertex byte offset */ int vertexOffset = el.getOffset(); - GL.glVertexAttribPointer(uExtVertexPosition, 3, + GL.glVertexAttribPointer(s.aPos, 3, GL20.GL_SHORT, false, 8, vertexOffset); - GL.glVertexAttribPointer(uExtLightPosition, 2, + GL.glVertexAttribPointer(s.aLight, 2, GL20.GL_UNSIGNED_BYTE, false, 8, vertexOffset + 6); /* draw extruded outlines */ if (el.numIndices[0] > 0) { /* draw roof */ - GL.glUniform1i(uExtMode, 0); + GL.glUniform1i(s.uMode, 0); GL.glDrawElements(GL20.GL_TRIANGLES, el.numIndices[2], GL20.GL_UNSIGNED_SHORT, (el.numIndices[0] + el.numIndices[1]) * 2); /* draw sides 1 */ - GL.glUniform1i(uExtMode, 1); + GL.glUniform1i(s.uMode, 1); GL.glDrawElements(GL20.GL_TRIANGLES, el.numIndices[0], GL20.GL_UNSIGNED_SHORT, 0); /* draw sides 2 */ - GL.glUniform1i(uExtMode, 2); + GL.glUniform1i(s.uMode, 2); GL.glDrawElements(GL20.GL_TRIANGLES, el.numIndices[1], GL20.GL_UNSIGNED_SHORT, el.numIndices[0] * 2); @@ -432,9 +405,9 @@ public class ExtrusionRenderer extends LayerRenderer { } v.mvp.addDepthOffset(100); - v.mvp.setAsUniform(uExtMatrix); + v.mvp.setAsUniform(s.uMVP); - GL.glUniform1i(uExtMode, 3); + GL.glUniform1i(s.uMode, 3); int offset = 2 * (indexOffset + el.numIndices[0] @@ -453,7 +426,7 @@ public class ExtrusionRenderer extends LayerRenderer { + el.numIndices[2] + el.numIndices[3]); - GL.glUniform1i(uExtMode, 4); + GL.glUniform1i(s.uMode, 4); GL.glDrawElements(GL20.GL_TRIANGLES, el.numIndices[4], GL20.GL_UNSIGNED_SHORT, offset); } @@ -517,110 +490,4 @@ public class ExtrusionRenderer extends LayerRenderer { (B - O) / 255, 0.9f, }; - - final static String extrusionVertexShader = "" - //+ "precision mediump float;" - + "uniform mat4 u_mvp;" - + "uniform vec4 u_color[4];" - + "uniform int u_mode;" - + "uniform float u_alpha;" - + "attribute vec4 a_pos;" - + "attribute vec2 a_light;" - + "varying vec4 color;" - + "varying float depth;" - + "const float ff = 255.0;" - + "void main() {" - // change height by u_alpha - + " gl_Position = u_mvp * vec4(a_pos.xy, a_pos.z * u_alpha, 1.0);" - //+ " depth = gl_Position.z;" - + " if (u_mode == -1){;" - // roof / depth pass - //+ " color = u_color[0] * u_alpha;" - + " } else if (u_mode == 0){" - // roof / depth pass - + " color = u_color[0] * u_alpha;" - + " } else if (u_mode == 1){" - // sides 1 - use 0xff00 - // scale direction to -0.5<>0.5 - + " float dir = a_light.y / ff;" - + " float z = (0.98 + gl_Position.z * 0.02);" - + " float h = 0.9 + clamp(a_pos.z / 2000.0, 0.0, 0.1);" - + " color = u_color[1];" - + " color.rgb *= (0.8 + dir * 0.2) * z * h;" - + " color *= u_alpha;" - + " } else if (u_mode == 2){" - // sides 2 - use 0x00ff - + " float dir = a_light.x / ff;" - + " float z = (0.98 + gl_Position.z * 0.02);" - + " float h = 0.9 + clamp(a_pos.z / 2000.0, 0.0, 0.1);" - + " color = u_color[2];" - + " color.rgb *= (0.8 + dir * 0.2) * z * h;" - + " color *= u_alpha;" - + " } else if (u_mode == 3) {" - // outline - + " float z = (0.98 - gl_Position.z * 0.02);" - + " color = u_color[3] * z;" - + "}}"; - - final static String extrusionVertexShader2 = "" - + "uniform mat4 u_mvp;" - + "uniform vec4 u_color;" - + "uniform float u_alpha;" - + "attribute vec4 a_pos;" - + "attribute vec2 a_light;" - + "varying vec4 color;" - + "varying float depth;" - + "const float alpha = 1.0;" - - + "void main() {" - // change height by u_alpha - + " vec4 pos = a_pos;" - + " pos.z *= u_alpha;" - + " gl_Position = u_mvp * pos;" - - // normalize face x/y direction - + " vec2 enc = (a_light / 255.0);" - + " vec2 fenc = enc * 4.0 - 2.0;" - + " float f = dot(fenc, fenc);" - + " float g = sqrt(1.0 - f / 4.0);" - + " vec3 r_norm;" - + " r_norm.xy = fenc * g;" - + " r_norm.z = 1.0 - f / 2.0;" - - // normal points up or down (1,-1) - ////+ " float dir = 1.0 - (2.0 * abs(mod(a_light.x,2.0)));" - // recreate face normal vector - ///+ " vec3 r_norm = vec3(n.xy, dir * (1.0 - length(n.xy)));" - - + " vec3 light_dir = normalize(vec3(0.2, 0.2, 1.0));" - + " float l = dot(r_norm, light_dir) * 0.8;" - - + " light_dir = normalize(vec3(-0.2, -0.2, 1.0));" - + " l += dot(r_norm, light_dir) * 0.2;" - - //+ " l = (l + (1.0 - r_norm.z))*0.5;" - /** ambient */ - + " l = 0.4 + l * 0.6;" - - /** extreme fake-ssao by height */ - + " l += (clamp(a_pos.z / 2048.0, 0.0, 0.1) - 0.05);" - + " color = vec4(u_color.rgb * (clamp(l, 0.0, 1.0) * alpha), u_color.a * alpha);" - + "}"; - - final static String extrusionFragmentShader = "" - + "precision mediump float;" - + "varying vec4 color;" - + "void main() {" - + " gl_FragColor = color;" - + "}"; - - //final static String extrusionFragmentShaderZ = "" - // + "precision mediump float;" - // + "varying float depth;" - // + "void main() {" - // + "float d = depth * 0.2;" - // + "if (d < 0.0)" - // + " d = -d;" - // + " gl_FragColor = vec4(1.0 - d, 1.0 - d, 1.0 - d, 1.0 - d);" - // + "}"; }