unprojection stuff, needed for scan-line visibility checker
This commit is contained in:
parent
4a5142fdf6
commit
8d57bc7531
@ -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) {
|
||||||
|
@ -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) {
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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);"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user