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 . + */ +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 pList = new ArrayList(); // 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();