unprojection stuff, needed for scan-line visibility checker

This commit is contained in:
Hannes Janetzek 2012-09-20 19:55:06 +02:00
parent 4a5142fdf6
commit 8d57bc7531
4 changed files with 187 additions and 150 deletions

View File

@ -49,6 +49,7 @@ import android.opengl.GLES20;
import android.opengl.GLSurfaceView; import android.opengl.GLSurfaceView;
import android.opengl.Matrix; import android.opengl.Matrix;
import android.os.SystemClock; import android.os.SystemClock;
import android.util.FloatMath;
import android.util.Log; import android.util.Log;
public class GLRenderer implements GLSurfaceView.Renderer { public class GLRenderer implements GLSurfaceView.Renderer {
@ -79,8 +80,11 @@ public class GLRenderer implements GLSurfaceView.Renderer {
private static float[] mMVPMatrix = new float[16]; private static float[] mMVPMatrix = new float[16];
private static float[] mRotateMatrix = new float[16]; private static float[] mRotateMatrix = new float[16];
private static float[] mTmpMatrix = new float[16];
private static float[] mTmp2Matrix = new float[16];
private static float[] mProjMatrix = new float[16]; private static float[] mProjMatrix = new float[16];
private static float[] mRotTMatrix = new float[16]; private static float[] mProjMatrixI = new float[16];
// curTiles is set by TileLoader and swapped with // curTiles is set by TileLoader and swapped with
// drawTiles in onDrawFrame in GL thread. // drawTiles in onDrawFrame in GL thread.
@ -232,66 +236,6 @@ public class GLRenderer implements GLSurfaceView.Renderer {
mUpdateColor = true; mUpdateColor = true;
} }
// depthRange: -1 to 1, bits: 2^24 => 2/2^24 one step
// ... asus has just 16 bit?!
// private static final float depthStep = 0.00000011920928955078125f;
private static boolean mRotate = false;
private static void setMatrix(float[] matrix, MapPosition mapPosition, MapTile tile,
float div, int offset, boolean project) {
float x, y, scale;
if (mRotate) {
scale = (float) (1.0 * mapPosition.scale / (mHeight * div));
x = (float) (tile.pixelX - mapPosition.x * div);
y = (float) (tile.pixelY - mapPosition.y * div);
Matrix.setIdentityM(matrix, 0);
// scale to tile coordinates
Matrix.scaleM(matrix, 0, scale / COORD_MULTIPLIER,
scale / COORD_MULTIPLIER, 1);
// translate to center
Matrix.translateM(matrix, 0,
x * COORD_MULTIPLIER,
-(y + Tile.TILE_SIZE) * COORD_MULTIPLIER,
// -0.99f + offset * 0.01f,
-1.000f
);
// Matrix.setRotateM(mRotTMatrix, 0, -35, 1, 0, 0);
// Matrix.multiplyMM(matrix, 0, mRotTMatrix, 0, matrix, 0);
// Matrix.translateM(matrix, 0, 0, 5000.2f, 0);
Matrix.multiplyMM(matrix, 0, mRotateMatrix, 0, matrix, 0);
float angle = 25;
Matrix.setRotateM(mRotTMatrix, 0, -angle, 1, 0, 0);
Matrix.translateM(mRotTMatrix, 0, 0, (float) Math.tan(Math.toRadians(angle)),
0);
Matrix.multiplyMM(matrix, 0, mRotTMatrix, 0, matrix, 0);
if (project)
Matrix.multiplyMM(matrix, 0, mProjMatrix, 0, matrix, 0);
}
else {
scale = (float) (2.0 * mapPosition.scale / (mHeight * div));
x = (float) (tile.pixelX - mapPosition.x * div);
y = (float) (tile.pixelY - mapPosition.y * div);
matrix[12] = x * scale * mAspect;
matrix[13] = -(y + Tile.TILE_SIZE) * scale;
// increase the 'distance' with each tile drawn.
matrix[14] = -0.99f + offset * 0.01f;
matrix[0] = scale * mAspect / COORD_MULTIPLIER;
matrix[5] = scale / COORD_MULTIPLIER;
}
}
private static boolean isVisible(MapPosition mapPosition, MapTile tile, float div) { private static boolean isVisible(MapPosition mapPosition, MapTile tile, float div) {
double dx, dy, scale; double dx, dy, scale;
@ -479,6 +423,72 @@ public class GLRenderer implements GLSurfaceView.Renderer {
} }
} }
private static boolean mRotate = false;
private static void setMatrix(float[] matrix, MapPosition mapPosition, MapTile tile,
float div, boolean project) {
float x, y, scale;
// if (mRotate) {
scale = mapPosition.scale / (div * COORD_MULTIPLIER);
x = (float) (tile.pixelX - mapPosition.x * div);
y = (float) (tile.pixelY - mapPosition.y * div);
Matrix.setIdentityM(matrix, 0);
// scale to tile coordinates
Matrix.scaleM(matrix, 0, scale, scale, 1);
// translate relative to center
Matrix.translateM(matrix, 0,
x * COORD_MULTIPLIER,
-(y + Tile.TILE_SIZE) * COORD_MULTIPLIER,
-1); // put on near plane
if (mRotate)
Matrix.multiplyMM(matrix, 0, mRotateMatrix, 0, matrix, 0);
if (project)
Matrix.multiplyMM(matrix, 0, mProjMatrix, 0, matrix, 0);
// } else {
// scale = (float) (2.0 * mapPosition.scale / (mHeight * div));
// x = (float) (tile.pixelX - mapPosition.x * div);
// y = (float) (tile.pixelY - mapPosition.y * div);
//
// matrix[12] = x * scale * mAspect;
// matrix[13] = -(y + Tile.TILE_SIZE) * scale;
// // increase the 'distance' with each tile drawn.
// matrix[14] = -0.99f + offset * 0.01f;
// matrix[0] = scale * mAspect / COORD_MULTIPLIER;
// matrix[5] = scale / COORD_MULTIPLIER;
// }
}
private float[] mv = new float[4];
private float[] mu = { 1, 1, -1, 1 };
private float[] mUnprojMatrix = new float[16];
private void unproject(MapPosition pos, float x, float y) {
mu[0] = x;
mu[1] = y;
mu[2] = -1;
// add tilt
Matrix.multiplyMV(mv, 0, mTmpMatrix, 0, mu, 0);
// Log.d(TAG, ">> " + mv[0] + " " + mv[1] + " " + mv[2]);
Matrix.multiplyMV(mv, 0, mUnprojMatrix, 0, mv, 0);
float size = Tile.TILE_SIZE * pos.scale;
if (mv[3] != 0) {
float w = 1 / mv[3];
float xx = Math.round(((mv[0] * w) / size) * 100) / 100f;
float yy = Math.round(((mv[1] * w) / size) * 100) / 100f;
Log.d(TAG, " " + xx + " " + yy);
}
}
@Override @Override
public void onDrawFrame(GL10 glUnused) { public void onDrawFrame(GL10 glUnused) {
long start = 0; long start = 0;
@ -514,16 +524,51 @@ public class GLRenderer implements GLSurfaceView.Renderer {
if (drawTiles == null) if (drawTiles == null)
return; return;
if (mRotate != (mMapView.enableRotation || mMapView.enableCompass)) { // if (mRotate != (mMapView.enableRotation || mMapView.enableCompass)) {
Matrix.setIdentityM(mMVPMatrix, 0); // Matrix.setIdentityM(mMVPMatrix, 0);
mRotate = mMapView.enableRotation || mMapView.enableCompass; // mRotate = mMapView.enableRotation || mMapView.enableCompass;
} // }
if (mRotate) {
// Matrix.setRotateM(mRotTMatrix, 0, -10, 1, 0, 0);
Matrix.setRotateM(mRotateMatrix, 0, mapPosition.angle, 0, 0, 1);
// Matrix.multiplyMM(mRotateMatrix, 0, mRotateMatrix, 0, mRotTMatrix, 0);
Matrix.transposeM(mRotTMatrix, 0, mRotateMatrix, 0); mRotate = mMapView.enableRotation || mMapView.enableCompass;
if (mRotate) {
// rotate map
Matrix.setRotateM(mRotateMatrix, 0, mapPosition.angle, 0, 0, 1);
// tilt map
float angle = 15f / (mHeight / 2);
Matrix.setRotateM(mTmpMatrix, 0, -angle, 1, 0, 0);
// move camera center back to map center
Matrix.translateM(mTmpMatrix, 0,
0, (float) Math.tan(Math.toRadians(angle)), 0);
// apply first rotation, then tilt
Matrix.multiplyMM(mRotateMatrix, 0, mTmpMatrix, 0, mRotateMatrix, 0);
// // get unproject matrix
// Matrix.setIdentityM(mTmp2Matrix, 0);
// float s = mapPosition.scale;
// Matrix.translateM(mTmp2Matrix, 0,
// (float) (mapPosition.x * s),
// (float) (mapPosition.y * s), 0);
//
// Matrix.multiplyMM(mTmp2Matrix, 0, mRotateMatrix, 0, mTmp2Matrix,
// 0);
//
// // Matrix.invertM(mTmpMatrix, 0, mTmp2Matrix, 0);
// // (AB)^-1 = B^-1*A^-1
// Matrix.multiplyMM(mUnprojMatrix, 0, mTmp2Matrix, 0, mProjMatrixI,
// 0);
//
// // set tilt of screen coords
// Matrix.setRotateM(mTmpMatrix, 0, -15, 1, 0, 0);
//
// // unproject(mapPosition, 0, 0);
// unproject(mapPosition, -1, -1); // top-left
// unproject(mapPosition, 1, -1); // top-right
// unproject(mapPosition, -1, 1); // bottom-left
// unproject(mapPosition, 1, 1); // bottom-right
} }
if (mUpdateColor && mClearColor != null) { if (mUpdateColor && mClearColor != null) {
@ -578,6 +623,7 @@ public class GLRenderer implements GLSurfaceView.Renderer {
GLES20.glEnable(GLES20.GL_DEPTH_TEST); GLES20.glEnable(GLES20.GL_DEPTH_TEST);
GLES20.glEnable(GLES20.GL_POLYGON_OFFSET_FILL); GLES20.glEnable(GLES20.GL_POLYGON_OFFSET_FILL);
for (int i = 0; i < tileCnt; i++) { for (int i = 0; i < tileCnt; i++) {
if (tiles[i].isVisible && tiles[i].isReady) { if (tiles[i].isVisible && tiles[i].isReady) {
drawTile(mapPosition, tiles[i], 1); drawTile(mapPosition, tiles[i], 1);
@ -609,19 +655,19 @@ public class GLRenderer implements GLSurfaceView.Renderer {
if (scale < 1) if (scale < 1)
scale = 1; scale = 1;
// if (z >= TileGenerator.STROKE_MAX_ZOOM_LEVEL) if (z >= TileGenerator.STROKE_MAX_ZOOM_LEVEL)
// TextRenderer.beginDraw(FloatMath.sqrt(s) / scale, mRotTMatrix); TextRenderer.beginDraw(FloatMath.sqrt(s) / scale, mProjMatrix);
// else else
// TextRenderer.beginDraw(s, mRotTMatrix);
s = (float) (1.0 / mHeight) / COORD_MULTIPLIER;
TextRenderer.beginDraw(s, mProjMatrix); TextRenderer.beginDraw(s, mProjMatrix);
// s = (float) 1.0 / COORD_MULTIPLIER;
// TextRenderer.beginDraw(s, mProjMatrix);
for (int i = 0; i < tileCnt; i++) { for (int i = 0; i < tileCnt; i++) {
if (!tiles[i].isVisible || tiles[i].texture == null) if (!tiles[i].isVisible || tiles[i].texture == null)
continue; continue;
setMatrix(mMVPMatrix, mapPosition, tiles[i], 1, 0, false); setMatrix(mMVPMatrix, mapPosition, tiles[i], 1, false);
TextRenderer.drawTile(tiles[i], mMVPMatrix); TextRenderer.drawTile(tiles[i], mMVPMatrix);
} }
TextRenderer.endDraw(); TextRenderer.endDraw();
@ -646,13 +692,11 @@ public class GLRenderer implements GLSurfaceView.Renderer {
int z = mapPosition.zoomLevel; int z = mapPosition.zoomLevel;
float s = mapPosition.scale; float s = mapPosition.scale;
// mDrawCount is used to calculation z offset. float[] mvp = mMVPMatrix;
// (used for depth clipping)
setMatrix(mMVPMatrix, mapPosition, tile, div, mDrawCount++, true);
GLES20.glPolygonOffset(0, mDrawCount); setMatrix(mvp, mapPosition, tile, div, true);
float offset = 0.0f; GLES20.glPolygonOffset(0, mDrawCount++);
glBindBuffer(GL_ARRAY_BUFFER, tile.vbo.id); glBindBuffer(GL_ARRAY_BUFFER, tile.vbo.id);
@ -674,7 +718,7 @@ public class GLRenderer implements GLSurfaceView.Renderer {
if (pl != null && pnext < lnext) { if (pl != null && pnext < lnext) {
glDisable(GL_BLEND); glDisable(GL_BLEND);
pl = PolygonRenderer.drawPolygons(pl, lnext, mMVPMatrix, offset, z, s, pl = PolygonRenderer.drawPolygons(pl, lnext, mvp, z, s,
!clipped); !clipped);
clipped = true; clipped = true;
@ -682,14 +726,12 @@ public class GLRenderer implements GLSurfaceView.Renderer {
} else { } else {
// XXX nasty // XXX nasty
if (!clipped) { if (!clipped) {
PolygonRenderer.drawPolygons(null, 0, mMVPMatrix, offset, z, s, true); PolygonRenderer.drawPolygons(null, 0, mvp, z, s, true);
clipped = true; clipped = true;
} }
glEnable(GL_BLEND); glEnable(GL_BLEND);
ll = LineRenderer.drawLines(tile, ll, pnext, mvp, div, z, s);
ll = LineRenderer.drawLines(tile, ll, pnext, mMVPMatrix, offset, div, z,
s);
} }
} }
} }
@ -771,16 +813,21 @@ public class GLRenderer implements GLSurfaceView.Renderer {
mAspect = (float) height / width; mAspect = (float) height / width;
// Matrix.orthoM(mProjMatrix, 0, -0.5f / mAspect, 0.5f / mAspect, -0.5f, 0.5f, -1, 1); // Matrix.orthoM(mProjMatrix, 0, -0.5f / mAspect, 0.5f / mAspect, -0.5f,
// 0.5f, -1, 1);
Matrix.frustumM(mProjMatrix, 0, -0.5f / mAspect, 0.5f / mAspect, -0.5f, Matrix.frustumM(mProjMatrix, 0,
0.5f, -0.5f * width,
1, 4); 0.5f * width,
-0.5f * height,
0.5f * height, 1, 2);
Matrix.invertM(mProjMatrixI, 0, mProjMatrix, 0);
// set to zero: we modify the z value with polygon-offset for clipping
mProjMatrix[10] = 0;
mProjMatrix[14] = 0;
// float angle = 35;
// Matrix.setRotateM(mRotTMatrix, 0, -angle, 1, 0, 0);
// Matrix.multiplyMM(mProjMatrix, 0, mProjMatrix, 0, mRotTMatrix, 0);
// Matrix.translateM(mProjMatrix, 0, 0, (float) Math.tan(Math.toRadians(angle)), 0);
glViewport(0, 0, width, height); glViewport(0, 0, width, height);
if (!changed && !mNewSurface) { if (!changed && !mNewSurface) {

View File

@ -50,7 +50,6 @@ class LineRenderer {
hLineScale = GLES20.glGetUniformLocation(lineProgram, "u_wscale"); hLineScale = GLES20.glGetUniformLocation(lineProgram, "u_wscale");
hLineWidth = GLES20.glGetUniformLocation(lineProgram, "u_width"); hLineWidth = GLES20.glGetUniformLocation(lineProgram, "u_width");
hLineColor = GLES20.glGetUniformLocation(lineProgram, "u_color"); hLineColor = GLES20.glGetUniformLocation(lineProgram, "u_color");
hLineOffset = GLES20.glGetUniformLocation(lineProgram, "u_offset");
hLineVertexPosition = GLES20.glGetAttribLocation(lineProgram, "a_position"); hLineVertexPosition = GLES20.glGetAttribLocation(lineProgram, "a_position");
hLineTexturePosition = GLES20.glGetAttribLocation(lineProgram, "a_st"); hLineTexturePosition = GLES20.glGetAttribLocation(lineProgram, "a_st");
@ -61,7 +60,7 @@ class LineRenderer {
static final boolean mFast = false; static final boolean mFast = false;
static LineLayer drawLines(MapTile tile, LineLayer layer, int next, float[] matrix, static LineLayer drawLines(MapTile tile, LineLayer layer, int next, float[] matrix,
float offset, float div, double zoom, float scale) { float div, double zoom, float scale) {
float z = 1 / div; float z = 1 / div;
@ -80,7 +79,6 @@ class LineRenderer {
false, 8, tile.lineOffset + LINE_VERTICES_DATA_TEX_OFFSET); false, 8, tile.lineOffset + LINE_VERTICES_DATA_TEX_OFFSET);
GLES20.glUniformMatrix4fv(hLineMatrix, 1, false, matrix, 0); GLES20.glUniformMatrix4fv(hLineMatrix, 1, false, matrix, 0);
GLES20.glUniform1f(hLineOffset, offset);
// scale factor to map one pixel on tile to one pixel on screen: // scale factor to map one pixel on tile to one pixel on screen:
float pixel = 2.0f / (scale * z); float pixel = 2.0f / (scale * z);
@ -141,7 +139,8 @@ class LineRenderer {
} }
if (line.fixed || zoom > TileGenerator.STROKE_MAX_ZOOM_LEVEL) { if (line.fixed || zoom > TileGenerator.STROKE_MAX_ZOOM_LEVEL) {
// invert scaling of extrusion vectors so that line width stays the same // invert scaling of extrusion vectors so that line width
// stays the same
GLES20.glUniform1f(hLineWidth, (l.width / (scale * z))); GLES20.glUniform1f(hLineWidth, (l.width / (scale * z)));
} else { } else {
GLES20.glUniform1f(hLineWidth, (l.width / s)); GLES20.glUniform1f(hLineWidth, (l.width / s));
@ -217,7 +216,8 @@ class LineRenderer {
// } // }
// } // }
// //
// static LineLayer get(int layer, Line line, float width, boolean outline) { // static LineLayer get(int layer, Line line, float width, boolean outline)
// {
// synchronized (lock) { // synchronized (lock) {
// //
// if (count == 0 && pool == null) { // if (count == 0 && pool == null) {

View File

@ -51,7 +51,6 @@ class PolygonRenderer {
private static int polygonProgram; private static int polygonProgram;
private static int hPolygonVertexPosition; private static int hPolygonVertexPosition;
private static int hPolygonMatrix; private static int hPolygonMatrix;
private static int hPolygonOffset;
private static int hPolygonColor; private static int hPolygonColor;
static boolean init() { static boolean init() {
@ -65,7 +64,6 @@ class PolygonRenderer {
} }
hPolygonMatrix = glGetUniformLocation(polygonProgram, "u_mvp"); hPolygonMatrix = glGetUniformLocation(polygonProgram, "u_mvp");
hPolygonColor = glGetUniformLocation(polygonProgram, "u_color"); hPolygonColor = glGetUniformLocation(polygonProgram, "u_color");
hPolygonOffset = glGetUniformLocation(polygonProgram, "u_offset");
hPolygonVertexPosition = glGetAttribLocation(polygonProgram, "a_position"); hPolygonVertexPosition = glGetAttribLocation(polygonProgram, "a_position");
mFillPolys = new PolygonLayer[STENCIL_BITS]; mFillPolys = new PolygonLayer[STENCIL_BITS];
@ -76,49 +74,50 @@ class PolygonRenderer {
private static void fillPolygons(int count, double zoom, float scale) { private static void fillPolygons(int count, double zoom, float scale) {
boolean blend = false; boolean blend = false;
// draw to framebuffer /* draw to framebuffer */
glColorMask(true, true, true, true); glColorMask(true, true, true, true);
// do not modify stencil buffer /* do not modify stencil buffer */
glStencilMask(0); glStencilMask(0);
// glEnable(GLES20.GL_DEPTH_TEST); /* only draw where nothing was drawn yet */
glEnable(GLES20.GL_DEPTH_TEST);
for (int c = 0; c < count; c++) { for (int c = 0; c < count; c++) {
PolygonLayer l = mFillPolys[c]; PolygonLayer l = mFillPolys[c];
float alpha = 1.0f; float f = 1.0f;
if (l.area.fade >= zoom || l.area.color[3] != 1.0) { if (l.area.fade >= zoom || l.area.color[3] != 1.0) {
// draw alpha blending, fade in/out /* fade in/out || draw alpha color */
if (l.area.fade >= zoom) { if (l.area.fade >= zoom) {
alpha = (scale > 1.3f ? scale : 1.3f) - alpha; f = (scale > 1.3f ? scale : 1.3f) - f;
if (alpha > 1.0f) if (f > 1.0f)
alpha = 1.0f; f = 1.0f;
} }
alpha *= l.area.color[3]; f *= l.area.color[3];
if (!blend) { if (!blend) {
glEnable(GL_BLEND); glEnable(GL_BLEND);
blend = true; blend = true;
} }
GlUtils.setColor(hPolygonColor, l.area.color, alpha); GlUtils.setColor(hPolygonColor, l.area.color, f);
} else if (l.area.blend == zoom) { } else if (l.area.blend == zoom) {
// fade in/out /* blend colors */
alpha = scale - 1.0f; f = scale - 1.0f;
if (alpha > 1.0f) if (f > 1.0f)
alpha = 1.0f; f = 1.0f;
else if (alpha < 0) else if (f < 0)
alpha = 0; f = 0;
GlUtils.setBlendColors(hPolygonColor, GlUtils.setBlendColors(hPolygonColor,
l.area.color, l.area.blendColor, alpha); l.area.color, l.area.blendColor, f);
} else { } else {
// draw solid /* draw solid */
if (blend) { if (blend) {
glDisable(GL_BLEND); glDisable(GL_BLEND);
blend = false; blend = false;
@ -139,10 +138,10 @@ class PolygonRenderer {
// blend = false; // blend = false;
// } // }
// set stencil buffer mask used to draw this layer /* set stencil buffer mask used to draw this layer */
glStencilFunc(GL_EQUAL, 0xff, 1 << c); 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);
} }
@ -151,23 +150,22 @@ class PolygonRenderer {
} }
static PolygonLayer drawPolygons(PolygonLayer layer, int next, static PolygonLayer drawPolygons(PolygonLayer layer, int next,
float[] matrix, float offset, double zoom, float scale, boolean clip) { float[] matrix, double zoom, float scale, boolean clip) {
int cnt = 0;
glUseProgram(polygonProgram); glUseProgram(polygonProgram);
GLES20.glEnableVertexAttribArray(hPolygonVertexPosition); GLES20.glEnableVertexAttribArray(hPolygonVertexPosition);
glVertexAttribPointer(hPolygonVertexPosition, 2, glVertexAttribPointer(hPolygonVertexPosition, 2, GLES20.GL_SHORT,
GLES20.GL_SHORT, false, 0, false, 0, POLYGON_VERTICES_DATA_POS_OFFSET);
POLYGON_VERTICES_DATA_POS_OFFSET);
glUniformMatrix4fv(hPolygonMatrix, 1, false, matrix, 0); glUniformMatrix4fv(hPolygonMatrix, 1, false, matrix, 0);
GLES20.glUniform1f(hPolygonOffset, offset);
glEnable(GL_STENCIL_TEST); glEnable(GL_STENCIL_TEST);
PolygonLayer l = layer; PolygonLayer l = layer;
boolean first = clip; boolean first = clip;
int cnt = 0;
for (; l != null && l.layer < next; l = l.next) { for (; l != null && l.layer < next; l = l.next) {
// fade out polygon layers (set in RederTheme) // fade out polygon layers (set in RederTheme)
@ -178,10 +176,8 @@ class PolygonRenderer {
// disable drawing to framebuffer // disable drawing to framebuffer
glColorMask(false, false, false, false); glColorMask(false, false, false, false);
// never pass the test, i.e. always apply first stencil op (sfail) // never pass the test: always apply fail op
glStencilFunc(GLES20.GL_ALWAYS, 0, 0xff); glStencilFunc(GLES20.GL_ALWAYS, 0, 0xFF);
// clear stencilbuffer
glStencilMask(0xFF); glStencilMask(0xFF);
// glClear(GL_STENCIL_BUFFER_BIT); // glClear(GL_STENCIL_BUFFER_BIT);
@ -202,13 +198,15 @@ class PolygonRenderer {
if (first) { if (first) {
first = false; first = false;
GLES20.glDepthMask(false); GLES20.glDepthMask(false);
// only draw to this tile
GLES20.glDepthFunc(GLES20.GL_EQUAL); GLES20.glDepthFunc(GLES20.GL_EQUAL);
} }
// stencil op for stencil method polygon drawing // stencil op for stencil method polygon drawing
glStencilOp(GL_INVERT, GL_INVERT, GL_INVERT); glStencilOp(GL_INVERT, GL_INVERT, GL_INVERT);
// glDisable(GLES20.GL_DEPTH_TEST); // no need for depth test while drawing stencil
glDisable(GLES20.GL_DEPTH_TEST);
} }
mFillPolys[cnt] = l; mFillPolys[cnt] = l;
@ -232,8 +230,8 @@ class PolygonRenderer {
if (clip && first) if (clip && first)
drawDepthClip(); drawDepthClip();
// required on GalaxyII, Android 2.3.3 (cant just VAA enable once...)
GLES20.glDisableVertexAttribArray(hPolygonVertexPosition); GLES20.glDisableVertexAttribArray(hPolygonVertexPosition);
return l; return l;
} }

View File

@ -22,7 +22,6 @@ class Shaders {
// + "invariant gl_Position;" // + "invariant gl_Position;"
+ "uniform mat4 u_mvp;" + "uniform mat4 u_mvp;"
+ "uniform float u_width;" + "uniform float u_width;"
+ "uniform float u_offset;"
+ "attribute vec2 a_position;" + "attribute vec2 a_position;"
+ "attribute vec2 a_st;" + "attribute vec2 a_st;"
+ "varying vec2 v_st;" + "varying vec2 v_st;"
@ -31,11 +30,7 @@ class Shaders {
// scale extrusion to u_width pixel // scale extrusion to u_width pixel
// just ignore the two most insignificant bits of a_st :) // just ignore the two most insignificant bits of a_st :)
+ " vec2 dir = dscale * u_width * a_st;" + " vec2 dir = dscale * u_width * a_st;"
+ " vec4 pos = u_mvp * vec4(a_position + dir, 0.0,1.0);" + " gl_Position = u_mvp * vec4(a_position + dir, 0.0,1.0);"
+ " pos.z = 0.0;"
// + " gl_Position = vec4(pos.xy, u_offset, 1.0);"
+ " gl_Position = pos;"
// + " gl_Position = mvp * vec4(a_position + dir, 0.0,1.0);"
// last two bits of a_st hold the texture coordinates // last two bits of a_st hold the texture coordinates
+ " v_st = u_width * (abs(mod(a_st,4.0)) - 1.0);" + " v_st = u_width * (abs(mod(a_st,4.0)) - 1.0);"
// TODO use bit operations when available (gles 1.3) // TODO use bit operations when available (gles 1.3)
@ -100,15 +95,10 @@ class Shaders {
final static String polygonVertexShader = "" final static String polygonVertexShader = ""
+ "precision mediump float;" + "precision mediump float;"
// + "invariant gl_Position;"
+ "uniform mat4 u_mvp;" + "uniform mat4 u_mvp;"
+ "uniform float u_offset;"
+ "attribute vec4 a_position;" + "attribute vec4 a_position;"
+ "void main() {" + "void main() {"
+ " vec4 pos = u_mvp * a_position;" + " gl_Position = u_mvp * a_position;"
+ " pos.z = 0.0;"
+ " gl_Position = pos;"
// + " gl_Position = mvp * a_position;"
+ "}"; + "}";
final static String polygonFragmentShader = "" final static String polygonFragmentShader = ""
@ -127,15 +117,16 @@ class Shaders {
+ "uniform float scale;" + "uniform float scale;"
+ "varying vec2 tex_c;" + "varying vec2 tex_c;"
+ "const vec2 div = vec2(1.0/4096.0,1.0/2048.0);" + "const vec2 div = vec2(1.0/4096.0,1.0/2048.0);"
+ "const float coord_scale = 0.125;"
+ "void main() {" + "void main() {"
+ " vec4 pos;" + " vec4 pos;"
+ " if (mod(vertex.x, 2.0) == 0.0){" + " if (mod(vertex.x, 2.0) == 0.0){"
+ " pos = rotation * (mvp * vec4(vertex.xy + vertex.zw, 0.0, 1.0));" + " pos = rotation * (mvp * vec4(vertex.xy + vertex.zw * (1.0 / scale), 0.0, 1.0));"
+ " } else {" + " } else {"
// place as billboard
+ " vec4 dir = mvp * vec4(vertex.xy, 0.0, 1.0);" + " vec4 dir = mvp * vec4(vertex.xy, 0.0, 1.0);"
+ " pos = rotation * (dir + vec4(vertex.zw * scale, 0.0, 0.0));" + " pos = rotation * (dir + vec4(vertex.zw * coord_scale, 0.0, 0.0));"
+ " }" + " }"
+ " pos.z = 0.0;"
+ " gl_Position = pos;" + " gl_Position = pos;"
+ " tex_c = tex_coord * div;" + " tex_c = tex_coord * div;"
+ "}"; + "}";
@ -173,7 +164,8 @@ class Shaders {
// + "const vec2 div = vec2(1.0/4096.0,1.0/2048.0);" // + "const vec2 div = vec2(1.0/4096.0,1.0/2048.0);"
// + "void main() {" // + "void main() {"
// + " if (mod(vertex.x, 2.0) == 0.0){" // + " if (mod(vertex.x, 2.0) == 0.0){"
// + " gl_Position = mvp * vec4(vertex.xy + vertex.zw / scale, 0.0, 1.0);" // +
// " gl_Position = mvp * vec4(vertex.xy + vertex.zw / scale, 0.0, 1.0);"
// + " } else {" // + " } else {"
// + " vec4 dir = rotation * vec4(vertex.zw / scale, 0.0, 1.0);" // + " vec4 dir = rotation * vec4(vertex.zw / scale, 0.0, 1.0);"
// + " gl_Position = mvp * vec4(vertex.xy + dir.xy, 0.0, 1.0);" // + " gl_Position = mvp * vec4(vertex.xy + dir.xy, 0.0, 1.0);"