From f761be1999eaf949c8804a232c04c21cc825ad4a Mon Sep 17 00:00:00 2001
From: Hannes Janetzek <hannes.janetzek@gmail.com>
Date: Sun, 30 Dec 2012 22:30:51 +0100
Subject: [PATCH] refactor: rename RenderOverlay classes

---
 src/org/oscim/overlay/LabelingOverlay.java    |   6 +-
 src/org/oscim/renderer/TextureRenderer.java   |   6 +-
 .../{OverlayGrid.java => GridOverlay.java}    |   4 +-
 .../oscim/renderer/overlays/ModelOverlay.java | 212 ++++++++++++++++++
 .../{OverlayTest.java => TestOverlay.java}    |   4 +-
 .../{OverlayText.java => TextOverlay.java}    |   4 +-
 src/org/oscim/view/MapView.java               |  11 +-
 7 files changed, 231 insertions(+), 16 deletions(-)
 rename src/org/oscim/renderer/overlays/{OverlayGrid.java => GridOverlay.java} (97%)
 create mode 100644 src/org/oscim/renderer/overlays/ModelOverlay.java
 rename src/org/oscim/renderer/overlays/{OverlayTest.java => TestOverlay.java} (97%)
 rename src/org/oscim/renderer/overlays/{OverlayText.java => TextOverlay.java} (98%)

diff --git a/src/org/oscim/overlay/LabelingOverlay.java b/src/org/oscim/overlay/LabelingOverlay.java
index 095e2d7e..e0f92ed8 100644
--- a/src/org/oscim/overlay/LabelingOverlay.java
+++ b/src/org/oscim/overlay/LabelingOverlay.java
@@ -14,12 +14,12 @@
  */
 package org.oscim.overlay;
 
-import org.oscim.renderer.overlays.OverlayText;
+import org.oscim.renderer.overlays.TextOverlay;
 import org.oscim.view.MapView;
 
 public class LabelingOverlay extends Overlay {
 
-	//	private OverlayText mLayer;
+	//	private TextOverlay mLayer;
 
 	//	@Override
 	//	public org.oscim.renderer.overlays.RenderOverlay getLayer() {
@@ -28,6 +28,6 @@ public class LabelingOverlay extends Overlay {
 
 	public LabelingOverlay(MapView mapView) {
 		super();
-		mLayer = new OverlayText(mapView);
+		mLayer = new TextOverlay(mapView);
 	}
 }
diff --git a/src/org/oscim/renderer/TextureRenderer.java b/src/org/oscim/renderer/TextureRenderer.java
index a111e023..8a059ee8 100644
--- a/src/org/oscim/renderer/TextureRenderer.java
+++ b/src/org/oscim/renderer/TextureRenderer.java
@@ -24,7 +24,6 @@ import org.oscim.renderer.layer.TextureLayer;
 import org.oscim.utils.GlUtils;
 
 import android.opengl.GLES20;
-import android.util.Log;
 
 public final class TextureRenderer {
 	public final static boolean debug = false;
@@ -101,7 +100,6 @@ public final class TextureRenderer {
 		TextureLayer tl = (TextureLayer) layer;
 
 		if (tl.fixed)
-
 			GLES20.glUniform1f(hTextureScale, (float) Math.sqrt(scale));
 		else
 			GLES20.glUniform1f(hTextureScale, 1);
@@ -114,8 +112,8 @@ public final class TextureRenderer {
 		GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, mIndicesVBO);
 
 		for (TextureObject to = tl.textures; to != null; to = to.next) {
-			if (TextureRenderer.debug)
-				Log.d("...", "draw texture: " + to.id + " " + to.offset + " " + to.vertices);
+			//if (TextureRenderer.debug)
+			//	Log.d("...", "draw texture: " + to.id + " " + to.offset + " " + to.vertices);
 
 			GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, to.id);
 			int maxVertices = MAX_ITEMS * INDICES_PER_SPRITE;
diff --git a/src/org/oscim/renderer/overlays/OverlayGrid.java b/src/org/oscim/renderer/overlays/GridOverlay.java
similarity index 97%
rename from src/org/oscim/renderer/overlays/OverlayGrid.java
rename to src/org/oscim/renderer/overlays/GridOverlay.java
index fc86fa49..1f8d79dd 100644
--- a/src/org/oscim/renderer/overlays/OverlayGrid.java
+++ b/src/org/oscim/renderer/overlays/GridOverlay.java
@@ -28,13 +28,13 @@ import android.graphics.Color;
 import android.graphics.Paint.Cap;
 import android.util.Log;
 
-public class OverlayGrid extends RenderOverlay {
+public class GridOverlay extends RenderOverlay {
 
 	private float[] mPoints;
 	private short[] mIndex;
 	private Text mText;
 
-	public OverlayGrid(MapView mapView) {
+	public GridOverlay(MapView mapView) {
 		super(mapView);
 
 		int size = Tile.TILE_SIZE;
diff --git a/src/org/oscim/renderer/overlays/ModelOverlay.java b/src/org/oscim/renderer/overlays/ModelOverlay.java
new file mode 100644
index 00000000..0efd8286
--- /dev/null
+++ b/src/org/oscim/renderer/overlays/ModelOverlay.java
@@ -0,0 +1,212 @@
+/*
+ * Copyright 2012 OpenScienceMap
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+package org.oscim.renderer.overlays;
+
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.FloatBuffer;
+import java.nio.ShortBuffer;
+
+import org.oscim.core.MapPosition;
+import org.oscim.renderer.GLRenderer;
+import org.oscim.utils.GlUtils;
+import org.oscim.view.MapView;
+
+import android.opengl.GLES20;
+import android.opengl.Matrix;
+import android.util.Log;
+
+/**
+ * @author Hannes Janetzek
+ */
+public class ModelOverlay extends RenderOverlay {
+
+	public ModelOverlay(MapView mapView) {
+		super(mapView);
+	}
+
+	private final float[] box = {
+			// north
+			-200f, -200f, 0, 0.9f,
+			200f, -200f, 0, 0.9f,
+			-200f, -200f, 0.15f, 0.9f,
+			200f, -200f, 0.15f, 0.9f,
+
+			// west
+			-200f, -200f, 0, 0.8f,
+			-200f, 200f, 0, 0.8f,
+			-200f, -200f, 0.15f, 0.8f,
+			-200f, 200f, 0.15f, 0.8f,
+
+			// south
+			200f, 200f, 0, 0.7f,
+			-200f, 200f, 0, 0.7f,
+			200f, 200f, 0.15f, 0.7f,
+			-200f, 200f, 0.15f, 0.7f,
+
+			// east
+			200f, -200f, 0, 1.0f,
+			200f, 200f, 0, 1.0f,
+			200f, -200f, 0.15f, 1.0f,
+			200f, 200f, 0.15f, 1.0f,
+	};
+
+	private final short[] indices = {
+			// north
+			0, 1, 2,
+			2, 1, 3,
+			// west
+			4, 5, 6,
+			6, 5, 7,
+			// south
+			8, 9, 10,
+			10, 9, 11,
+			// east
+			12, 13, 14,
+			14, 13, 15,
+			// top
+			2, 3, 10,
+			10, 11, 2
+	};
+
+	private static int polygonProgram;
+	private static int hPolygonVertexPosition;
+	private static int hPolygonLightPosition;
+	private static int hPolygonMatrix;
+	private static int hPolygonColor;
+	//private static int hPolygonScale;
+
+	private boolean initialized = false;
+
+	final static String polygonVertexShader = ""
+			+ "precision mediump float;"
+			+ "uniform mat4 u_mvp;"
+			+ "uniform vec4 u_color;"
+			+ "attribute vec4 a_position;"
+			+ "attribute float a_light;"
+			+ "varying vec4 color;"
+			+ "void main() {"
+			+ "  gl_Position = u_mvp * a_position;"
+			+ "  if (u_color.a == 0.0)"
+			+ "  color = vec4(u_color.rgb * a_light, 0.8);"
+			+ "  else"
+			+ "  color = u_color;"
+			+ "}";
+
+	final static String polygonFragmentShader = ""
+			+ "precision mediump float;"
+			+ "varying vec4 color;"
+			+ "void main() {"
+			+ "  gl_FragColor = color;"
+			+ "}";
+
+	private int mIndicesBufferID;
+	private int mVertexBufferID;
+
+	@Override
+	public synchronized void update(MapPosition curPos, boolean positionChanged,
+			boolean tilesChanged) {
+
+		if (initialized)
+			return;
+		initialized = true;
+
+		// Set up the program for rendering polygons
+		polygonProgram = GlUtils.createProgram(polygonVertexShader,
+				polygonFragmentShader);
+		if (polygonProgram == 0) {
+			Log.e("blah", "Could not create polygon program.");
+			return;
+		}
+		hPolygonMatrix = GLES20.glGetUniformLocation(polygonProgram, "u_mvp");
+		hPolygonColor = GLES20.glGetUniformLocation(polygonProgram, "u_color");
+		hPolygonVertexPosition = GLES20.glGetAttribLocation(polygonProgram, "a_position");
+		hPolygonLightPosition = GLES20.glGetAttribLocation(polygonProgram, "a_light");
+
+		int[] mVboIds = new int[2];
+		GLES20.glGenBuffers(2, mVboIds, 0);
+		mIndicesBufferID = mVboIds[0];
+		mVertexBufferID = mVboIds[1];
+
+		ByteBuffer buf = ByteBuffer.allocateDirect(64 * 4)
+				.order(ByteOrder.nativeOrder());
+
+		ShortBuffer sbuf = buf.asShortBuffer();
+		sbuf.put(indices);
+		sbuf.flip();
+		GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, mIndicesBufferID);
+		GLES20.glBufferData(GLES20.GL_ELEMENT_ARRAY_BUFFER, 30 * 2, sbuf, GLES20.GL_STATIC_DRAW);
+		GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, 0);
+
+		FloatBuffer fbuf = buf.asFloatBuffer();
+		fbuf.put(box);
+		fbuf.flip();
+		GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, mVertexBufferID);
+		GLES20.glBufferData(GLES20.GL_ARRAY_BUFFER, 64 * 4, fbuf, GLES20.GL_STATIC_DRAW);
+		GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0);
+
+		mMapView.getMapViewPosition().getMapPosition(mMapPosition, null);
+
+		// tell GLRenderer to call 'render'
+		isReady = true;
+	}
+
+	@Override
+	public synchronized void render(MapPosition pos, float[] mv, float[] proj) {
+
+		setMatrix(pos, mv);
+		Matrix.multiplyMM(mv, 0, proj, 0, mv, 0);
+
+		GLES20.glUseProgram(polygonProgram);
+
+		GLRenderer.enableVertexArrays(hPolygonVertexPosition, hPolygonLightPosition);
+
+		GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, mIndicesBufferID);
+		GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, mVertexBufferID);
+
+		GLES20.glVertexAttribPointer(hPolygonVertexPosition, 3, GLES20.GL_FLOAT, false, 16, 0);
+		GLES20.glVertexAttribPointer(hPolygonLightPosition, 1, GLES20.GL_FLOAT, false, 16, 12);
+
+		GLES20.glUniformMatrix4fv(hPolygonMatrix, 1, false, mv, 0);
+		GLES20.glUniform4f(hPolygonColor, 0.5f, 0.5f, 0.5f, 0.7f);
+
+		// draw to depth buffer
+		GLES20.glColorMask(false, false, false, false);
+		GLES20.glClear(GLES20.GL_DEPTH_BUFFER_BIT);
+		GLES20.glEnable(GLES20.GL_DEPTH_TEST);
+		GLES20.glDepthMask(true);
+		GLES20.glDepthFunc(GLES20.GL_LESS);
+
+		GLES20.glDrawElements(GLES20.GL_TRIANGLES, 30, GLES20.GL_UNSIGNED_SHORT, 0);
+
+		GLES20.glColorMask(true, true, true, true);
+		GLES20.glDepthMask(false);
+		GLES20.glDepthFunc(GLES20.GL_EQUAL);
+
+		// draw sides
+		GLES20.glUniform4f(hPolygonColor, 0.7f, 0.7f, 0.7f, 0.0f);
+		GLES20.glDrawElements(GLES20.GL_TRIANGLES, 24, GLES20.GL_UNSIGNED_SHORT, 0);
+
+		// draw roof
+		GLES20.glUniform4f(hPolygonColor, 0.7f, 0.5f, 0.5f, 0.7f);
+		GLES20.glDrawElements(GLES20.GL_TRIANGLES, 6, GLES20.GL_UNSIGNED_SHORT, 24 * 2);
+
+		GLES20.glDisable(GLES20.GL_DEPTH_TEST);
+
+		GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, 0);
+		GlUtils.checkGlError("...");
+	}
+
+}
diff --git a/src/org/oscim/renderer/overlays/OverlayTest.java b/src/org/oscim/renderer/overlays/TestOverlay.java
similarity index 97%
rename from src/org/oscim/renderer/overlays/OverlayTest.java
rename to src/org/oscim/renderer/overlays/TestOverlay.java
index 3f096bfb..c5a2ac6b 100644
--- a/src/org/oscim/renderer/overlays/OverlayTest.java
+++ b/src/org/oscim/renderer/overlays/TestOverlay.java
@@ -23,7 +23,7 @@ import org.oscim.renderer.layer.TextItem;
 import org.oscim.theme.renderinstruction.BitmapUtils;
 import org.oscim.view.MapView;
 
-public class OverlayTest extends RenderOverlay {
+public class TestOverlay extends RenderOverlay {
 
 	TextItem labels;
 
@@ -31,7 +31,7 @@ public class OverlayTest extends RenderOverlay {
 
 	private boolean first = true;
 
-	public OverlayTest(MapView mapView) {
+	public TestOverlay(MapView mapView) {
 		super(mapView);
 
 		//		LineLayer ll = (LineLayer) layers.getLayer(1, Layer.LINE);
diff --git a/src/org/oscim/renderer/overlays/OverlayText.java b/src/org/oscim/renderer/overlays/TextOverlay.java
similarity index 98%
rename from src/org/oscim/renderer/overlays/OverlayText.java
rename to src/org/oscim/renderer/overlays/TextOverlay.java
index b8b3c4a8..8f77fd7b 100644
--- a/src/org/oscim/renderer/overlays/OverlayText.java
+++ b/src/org/oscim/renderer/overlays/TextOverlay.java
@@ -31,7 +31,7 @@ import org.oscim.view.MapView;
 import android.opengl.Matrix;
 import android.os.SystemClock;
 
-public class OverlayText extends RenderOverlay {
+public class TextOverlay extends RenderOverlay {
 
 	private TileSet tiles;
 	private LabelThread mThread;
@@ -64,7 +64,7 @@ public class OverlayText extends RenderOverlay {
 		}
 	}
 
-	public OverlayText(MapView mapView) {
+	public TextOverlay(MapView mapView) {
 		super(mapView);
 
 		mWorkPos = new MapPosition();
diff --git a/src/org/oscim/view/MapView.java b/src/org/oscim/view/MapView.java
index 4d992913..904296b3 100644
--- a/src/org/oscim/view/MapView.java
+++ b/src/org/oscim/view/MapView.java
@@ -37,6 +37,7 @@ import org.oscim.database.OpenResult;
 import org.oscim.generator.JobQueue;
 import org.oscim.generator.JobTile;
 import org.oscim.generator.MapWorker;
+import org.oscim.overlay.GenericOverlay;
 import org.oscim.overlay.LabelingOverlay;
 import org.oscim.overlay.Overlay;
 import org.oscim.overlay.OverlayManager;
@@ -44,6 +45,7 @@ import org.oscim.renderer.GLRenderer;
 import org.oscim.renderer.GLView;
 import org.oscim.renderer.TileGenerator;
 import org.oscim.renderer.TileManager;
+import org.oscim.renderer.overlays.ModelOverlay;
 import org.oscim.theme.ExternalRenderTheme;
 import org.oscim.theme.InternalRenderTheme;
 import org.oscim.theme.RenderTheme;
@@ -183,9 +185,10 @@ public class MapView extends RelativeLayout {
 		enableRotation = true;
 
 		mOverlayManager.add(new LabelingOverlay(this));
-		//mOverlayManager.add(new GenericOverlay(this, new OverlayGrid(this)));
+		//mOverlayManager.add(new GenericOverlay(this, new GridOverlay(this)));
+		mOverlayManager.add(new GenericOverlay(this, new ModelOverlay(this)));
 
-		//		mOverlayManager.add(new GenericOverlay(this, new OverlayTest(this)));
+		//		mOverlayManager.add(new GenericOverlay(this, new TestOverlay(this)));
 
 		//		ArrayList<OverlayItem> pList = new ArrayList<OverlayItem>();
 		//		pList.add(new OverlayItem("title", "description", new GeoPoint(53.067221, 8.78767)));
@@ -494,7 +497,9 @@ public class MapView extends RelativeLayout {
 			mapWorker.interrupt();
 
 			try {
-				mapWorker.join();
+				// FIXME this hangs badly sometimes,
+				// just let it crash...
+				mapWorker.join(10000);
 			} catch (InterruptedException e) {
 				// restore the interrupted status
 				Thread.currentThread().interrupt();