From 7468d0beeb082817a8e4f871a4bab0fb65022f9d Mon Sep 17 00:00:00 2001
From: Hannes Janetzek <hannes.janetzek@gmail.com>
Date: Fri, 14 Feb 2014 12:03:17 +0100
Subject: [PATCH] put 'scale screen coordinates' into projection matrix

---
 vtm/src/org/oscim/map/Viewport.java           | 66 ++++++++++---------
 .../oscim/renderer/elements/TextureLayer.java |  7 +-
 2 files changed, 36 insertions(+), 37 deletions(-)

diff --git a/vtm/src/org/oscim/map/Viewport.java b/vtm/src/org/oscim/map/Viewport.java
index acd00be1..15860d2b 100644
--- a/vtm/src/org/oscim/map/Viewport.java
+++ b/vtm/src/org/oscim/map/Viewport.java
@@ -47,6 +47,7 @@ public class Viewport {
 	private final MapPosition mPos = new MapPosition();
 
 	private final GLMatrix mProjMatrix = new GLMatrix();
+	private final GLMatrix mProjMatrixUnscaled = new GLMatrix();
 	private final GLMatrix mProjMatrixI = new GLMatrix();
 	private final GLMatrix mRotMatrix = new GLMatrix();
 	private final GLMatrix mViewMatrix = new GLMatrix();
@@ -79,23 +80,37 @@ public class Viewport {
 	}
 
 	public synchronized void setScreenSize(int width, int height) {
-		float s = VIEW_SCALE;
-		float aspect = height / (float) width;
+		mHeight = height;
+		mWidth = width;
+
+		/* setup projection matrix:
+		 * 0. scale to window coordinates
+		 * 1. translate to VIEW_DISTANCE
+		 * 2. apply projection
+		 * setup inverse projection:
+		 * 0. invert projection
+		 * 1. invert translate to VIEW_DISTANCE */
+
+		float ratio = (mHeight / mWidth) * VIEW_SCALE;
 		float[] tmp = new float[16];
 
-		GLMatrix.frustumM(tmp, 0, -s, s,
-		                  aspect * s, -aspect * s, VIEW_NEAR, VIEW_FAR);
+		GLMatrix.frustumM(tmp, 0, -VIEW_SCALE, VIEW_SCALE,
+		                  ratio, -ratio, VIEW_NEAR, VIEW_FAR);
 
 		mProjMatrix.set(tmp);
 		mTmpMatrix.setTranslation(0, 0, -VIEW_DISTANCE);
 		mProjMatrix.multiplyRhs(mTmpMatrix);
-		mProjMatrix.get(tmp);
 
+		/* set inverse projection matrix (without scaling) */
+		mProjMatrix.get(tmp);
 		GLMatrix.invertM(tmp, 0, tmp, 0);
 		mProjMatrixI.set(tmp);
 
-		mHeight = height;
-		mWidth = width;
+		mProjMatrixUnscaled.copy(mProjMatrix);
+
+		/* scale to window coordinates */
+		mTmpMatrix.setScale(1 / mWidth, 1 / mWidth, 1 / mWidth);
+		mProjMatrix.multiplyRhs(mTmpMatrix);
 
 		updateMatrix();
 	}
@@ -204,7 +219,7 @@ public class Viewport {
 		mv[1] = (float) (ry / ua);
 		mv[2] = (float) (cx - cx / ua);
 
-		mProjMatrix.prj(mv);
+		mProjMatrixUnscaled.prj(mv);
 
 		return mv[2];
 	}
@@ -362,42 +377,31 @@ public class Viewport {
 	}
 
 	private void updateMatrix() {
-		// - view matrix
-		// 1. scale to window coordinates
-		// 2. apply rotate
-		// 3. apply tilt
-
-		// - projection matrix
-		// 4. translate to VIEW_DISTANCE
-		// 5. apply projection
+		/* - view matrix:
+		 * 0. apply rotate
+		 * 1. apply tilt */
 
 		mRotMatrix.setRotation(mPos.angle, 0, 0, 1);
-
-		// tilt map
 		mTmpMatrix.setRotation(mPos.tilt, 1, 0, 0);
 
-		// apply first rotation, then tilt
-		mRotMatrix.multiplyMM(mTmpMatrix, mRotMatrix);
+		/* apply first rotation, then tilt */
+		mRotMatrix.multiplyLhs(mTmpMatrix);
 
-		// scale to window coordinates
-		mTmpMatrix.setScale(1 / mWidth, 1 / mWidth, 1 / mWidth);
-
-		mViewMatrix.multiplyMM(mRotMatrix, mTmpMatrix);
+		mViewMatrix.copy(mRotMatrix);
 
 		mVPMatrix.multiplyMM(mProjMatrix, mViewMatrix);
 
-		//--- unproject matrix:
-
-		// inverse scale
+		/* inverse projection matrix: */
+		/* invert scale */
 		mUnprojMatrix.setScale(mWidth, mWidth, 1);
 
-		// inverse rotation and tilt
+		/* invert rotation and tilt */
 		mTmpMatrix.transposeM(mRotMatrix);
 
-		// (AB)^-1 = B^-1*A^-1, unapply scale, tilt and rotation
-		mTmpMatrix.multiplyMM(mUnprojMatrix, mTmpMatrix);
+		/* (AB)^-1 = B^-1*A^-1, invert scale, tilt and rotation */
+		mTmpMatrix.multiplyLhs(mUnprojMatrix);
 
-		// (AB)^-1 = B^-1*A^-1, unapply projection
+		/* (AB)^-1 = B^-1*A^-1, invert projection */
 		mUnprojMatrix.multiplyMM(mTmpMatrix, mProjMatrixI);
 	}
 
diff --git a/vtm/src/org/oscim/renderer/elements/TextureLayer.java b/vtm/src/org/oscim/renderer/elements/TextureLayer.java
index e0aef4b9..5f449c8e 100644
--- a/vtm/src/org/oscim/renderer/elements/TextureLayer.java
+++ b/vtm/src/org/oscim/renderer/elements/TextureLayer.java
@@ -122,7 +122,6 @@ public abstract class TextureLayer extends RenderElement {
 		private static int hTextureProjMatrix;
 		private static int hTextureVertex;
 		private static int hTextureScale;
-		private static int hTextureScreenScale;
 		private static int hTextureTexCoord;
 		private static int hTextureSize;
 
@@ -134,7 +133,6 @@ public abstract class TextureLayer extends RenderElement {
 			hTextureProjMatrix = GL.glGetUniformLocation(mTextureProgram, "u_proj");
 			hTextureScale = GL.glGetUniformLocation(mTextureProgram, "u_scale");
 			hTextureSize = GL.glGetUniformLocation(mTextureProgram, "u_div");
-			hTextureScreenScale = GL.glGetUniformLocation(mTextureProgram, "u_swidth");
 			hTextureVertex = GL.glGetAttribLocation(mTextureProgram, "vertex");
 			hTextureTexCoord = GL.glGetAttribLocation(mTextureProgram, "tex_coord");
 
@@ -158,8 +156,6 @@ public abstract class TextureLayer extends RenderElement {
 			else
 				GL.glUniform1f(hTextureScale, 1);
 
-			GL.glUniform1f(hTextureScreenScale, 1f / MapRenderer.screenWidth);
-
 			m.proj.setAsUniform(hTextureProjMatrix);
 			m.mvp.setAsUniform(hTextureMVMatrix);
 
@@ -208,7 +204,6 @@ public abstract class TextureLayer extends RenderElement {
 		        + "uniform mat4 u_mv;"
 		        + "uniform mat4 u_proj;"
 		        + "uniform float u_scale;"
-		        + "uniform float u_swidth;"
 		        + "uniform vec2 u_div;"
 		        + "varying vec2 tex_c;"
 		        + "const float coord_scale = " + COORD_DIV + ";"
@@ -219,7 +214,7 @@ public abstract class TextureLayer extends RenderElement {
 		        + "       pos = u_proj * (u_mv * vec4(vertex.xy + dir * u_scale, 0.0, 1.0));"
 		        + "  } else {" // place as billboard
 		        + "    vec4 center = u_mv * vec4(vertex.xy, 0.0, 1.0);"
-		        + "    pos = u_proj * (center + vec4(dir * (coord_scale * u_swidth), 0.0, 0.0));"
+		        + "    pos = u_proj * (center + vec4(dir * coord_scale, 0.0, 0.0));"
 		        + "  }"
 		        + "  gl_Position = pos;"
 		        + "  tex_c = tex_coord * u_div;"