- LineClipper added start(x0,y0), clipNext(x1,y1) 'state' clipping mode
- use vec4 array for extrusion colors -> set color only once for all tiles - use full range for direction vector in extrusion vertex
This commit is contained in:
parent
e9d2c88022
commit
d0ad2f3bd4
@ -78,10 +78,11 @@ public class ExtrusionLayer extends Layer {
|
|||||||
boolean simple = true;
|
boolean simple = true;
|
||||||
int startVertex = mNumVertices;
|
int startVertex = mNumVertices;
|
||||||
|
|
||||||
|
// just a guess to make it look ok
|
||||||
if (height == 0)
|
if (height == 0)
|
||||||
height = 400;
|
height = 320;
|
||||||
else
|
else
|
||||||
height *= 40;
|
height *= 30;
|
||||||
|
|
||||||
int length = 0;
|
int length = 0;
|
||||||
for (int ipos = 0, ppos = 0, n = index.length; ipos < n; ipos++, ppos += length) {
|
for (int ipos = 0, ppos = 0, n = index.length; ipos < n; ipos++, ppos += length) {
|
||||||
@ -212,7 +213,8 @@ public class ExtrusionLayer extends Layer {
|
|||||||
float ux, uy;
|
float ux, uy;
|
||||||
|
|
||||||
float a = (float) Math.sqrt(vx * vx + vy * vy);
|
float a = (float) Math.sqrt(vx * vx + vy * vy);
|
||||||
short color1 = getColor(vx, a);
|
//float vlight = vx > 0 ? (vx / a) : -(vx / a);
|
||||||
|
short color1 = (short) ((1 + vx / a) * 127);
|
||||||
short fcolor = color1;
|
short fcolor = color1;
|
||||||
short color2 = 0;
|
short color2 = 0;
|
||||||
|
|
||||||
@ -226,6 +228,8 @@ public class ExtrusionLayer extends Layer {
|
|||||||
short[] vertices = mCurVertices.vertices;
|
short[] vertices = mCurVertices.vertices;
|
||||||
int v = mCurVertices.used;
|
int v = mCurVertices.used;
|
||||||
|
|
||||||
|
mClipper.clipStart((int) nx, (int) ny);
|
||||||
|
|
||||||
for (int i = 2, n = vertexCnt + 2; i < n; i += 2, v += 8) {
|
for (int i = 2, n = vertexCnt + 2; i < n; i += 2, v += 8) {
|
||||||
cx = nx;
|
cx = nx;
|
||||||
cy = ny;
|
cy = ny;
|
||||||
@ -269,7 +273,7 @@ public class ExtrusionLayer extends Layer {
|
|||||||
|
|
||||||
// set lighting (by direction)
|
// set lighting (by direction)
|
||||||
a = (float) Math.sqrt(vx * vx + vy * vy);
|
a = (float) Math.sqrt(vx * vx + vy * vy);
|
||||||
color2 = getColor(vx, a);
|
color2 = (short) ((1 + vx / a) * 127); //getColor(vx, a);
|
||||||
|
|
||||||
short c;
|
short c;
|
||||||
if (even == 0)
|
if (even == 0)
|
||||||
@ -294,7 +298,7 @@ public class ExtrusionLayer extends Layer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* check if face is within tile */
|
/* check if face is within tile */
|
||||||
if (!mClipper.clip((int) cx, (int) cy, (int) nx, (int) ny)) {
|
if (!mClipper.clipNext((int) nx, (int) ny)) {
|
||||||
even = (even + 1) % 2;
|
even = (even + 1) % 2;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -146,11 +146,15 @@ public class ExtrusionOverlay extends RenderOverlay {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean debug = false;
|
private boolean debug = false;
|
||||||
|
private final float[] mVPMatrix = new float[16];
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public synchronized void render(MapPosition pos, float[] mv, float[] proj) {
|
public synchronized void render(MapPosition pos, float[] mv, float[] proj) {
|
||||||
|
|
||||||
|
Matrix.multiplyMM(mVPMatrix, 0, proj, 0, pos.viewMatrix, 0);
|
||||||
|
proj = mVPMatrix;
|
||||||
|
|
||||||
MapTile[] tiles = mTiles;
|
MapTile[] tiles = mTiles;
|
||||||
|
|
||||||
float div = FastMath.pow(tiles[0].zoomLevel - pos.zoomLevel);
|
float div = FastMath.pow(tiles[0].zoomLevel - pos.zoomLevel);
|
||||||
@ -162,7 +166,7 @@ public class ExtrusionOverlay extends RenderOverlay {
|
|||||||
|
|
||||||
GLState.enableVertexArrays(hExtrusionVertexPosition, hExtrusionLightPosition);
|
GLState.enableVertexArrays(hExtrusionVertexPosition, hExtrusionLightPosition);
|
||||||
GLES20.glUniform1i(hExtrusionMode, 0);
|
GLES20.glUniform1i(hExtrusionMode, 0);
|
||||||
GLES20.glUniform4f(hExtrusionColor, 0.6f, 0.6f, 0.6f, 0.8f);
|
GLES20.glUniform4fv(hExtrusionColor, 4, mColor, 0);
|
||||||
|
|
||||||
GLState.test(false, false);
|
GLState.test(false, false);
|
||||||
|
|
||||||
@ -209,6 +213,7 @@ public class ExtrusionOverlay extends RenderOverlay {
|
|||||||
GLES20.glDepthMask(true);
|
GLES20.glDepthMask(true);
|
||||||
GLES20.glColorMask(false, false, false, false);
|
GLES20.glColorMask(false, false, false, false);
|
||||||
GLES20.glUniform1i(hExtrusionMode, 0);
|
GLES20.glUniform1i(hExtrusionMode, 0);
|
||||||
|
GLES20.glUniform4fv(hExtrusionColor, 4, mColor, 0);
|
||||||
|
|
||||||
// draw to depth buffer
|
// draw to depth buffer
|
||||||
for (int i = 0; i < mTileCnt; i++) {
|
for (int i = 0; i < mTileCnt; i++) {
|
||||||
@ -255,30 +260,23 @@ public class ExtrusionOverlay extends RenderOverlay {
|
|||||||
|
|
||||||
// draw roof
|
// draw roof
|
||||||
GLES20.glUniform1i(hExtrusionMode, 0);
|
GLES20.glUniform1i(hExtrusionMode, 0);
|
||||||
GLES20.glUniform4fv(hExtrusionColor, 1, mRoofColor, 0);
|
|
||||||
GLES20.glDrawElements(GLES20.GL_TRIANGLES, el.mIndiceCnt[2],
|
GLES20.glDrawElements(GLES20.GL_TRIANGLES, el.mIndiceCnt[2],
|
||||||
GLES20.GL_UNSIGNED_SHORT, (el.mIndiceCnt[0] + el.mIndiceCnt[1]) * 2);
|
GLES20.GL_UNSIGNED_SHORT, (el.mIndiceCnt[0] + el.mIndiceCnt[1]) * 2);
|
||||||
|
|
||||||
// draw sides 1
|
// draw sides 1
|
||||||
GLES20.glUniform4fv(hExtrusionColor, 1, mColor, 0);
|
|
||||||
GLES20.glUniform1i(hExtrusionMode, 1);
|
GLES20.glUniform1i(hExtrusionMode, 1);
|
||||||
GLES20.glDrawElements(GLES20.GL_TRIANGLES, el.mIndiceCnt[0],
|
GLES20.glDrawElements(GLES20.GL_TRIANGLES, el.mIndiceCnt[0],
|
||||||
GLES20.GL_UNSIGNED_SHORT, 0);
|
GLES20.GL_UNSIGNED_SHORT, 0);
|
||||||
|
|
||||||
// draw sides 2
|
// draw sides 2
|
||||||
GLES20.glUniform4fv(hExtrusionColor, 1, mColor2, 0);
|
|
||||||
GLES20.glUniform1i(hExtrusionMode, 2);
|
GLES20.glUniform1i(hExtrusionMode, 2);
|
||||||
|
|
||||||
GLES20.glDrawElements(GLES20.GL_TRIANGLES, el.mIndiceCnt[1],
|
GLES20.glDrawElements(GLES20.GL_TRIANGLES, el.mIndiceCnt[1],
|
||||||
GLES20.GL_UNSIGNED_SHORT, el.mIndiceCnt[0] * 2);
|
GLES20.GL_UNSIGNED_SHORT, el.mIndiceCnt[0] * 2);
|
||||||
|
|
||||||
//GLES20.glDepthFunc(GLES20.GL_LEQUAL);
|
|
||||||
GLES20.glUniform1i(hExtrusionMode, 3);
|
GLES20.glUniform1i(hExtrusionMode, 3);
|
||||||
GLES20.glUniform4f(hExtrusionColor, 0.7f, 0.7f, 0.7f, 1.0f);
|
|
||||||
GLES20.glDrawElements(GLES20.GL_LINES, el.mIndiceCnt[3],
|
GLES20.glDrawElements(GLES20.GL_LINES, el.mIndiceCnt[3],
|
||||||
GLES20.GL_UNSIGNED_SHORT,
|
GLES20.GL_UNSIGNED_SHORT,
|
||||||
(el.mIndiceCnt[0] + el.mIndiceCnt[1] + el.mIndiceCnt[2]) * 2);
|
(el.mIndiceCnt[0] + el.mIndiceCnt[1] + el.mIndiceCnt[2]) * 2);
|
||||||
//GLES20.glDepthFunc(GLES20.GL_EQUAL);
|
|
||||||
|
|
||||||
// just a temporary reference!
|
// just a temporary reference!
|
||||||
tiles[i] = null;
|
tiles[i] = null;
|
||||||
@ -309,48 +307,46 @@ public class ExtrusionOverlay extends RenderOverlay {
|
|||||||
matrix[5] = scale;
|
matrix[5] = scale;
|
||||||
matrix[10] = scale / 1000f;
|
matrix[10] = scale / 1000f;
|
||||||
|
|
||||||
Matrix.multiplyMM(matrix, 0, mapPosition.viewMatrix, 0, matrix, 0);
|
|
||||||
Matrix.multiplyMM(matrix, 0, proj, 0, matrix, 0);
|
Matrix.multiplyMM(matrix, 0, proj, 0, matrix, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// sligthly differ adjacent faces to improve contrast
|
private final float _a = 0.8f;
|
||||||
//float mColor[] = { 0.76872549f, 0.751960784f, 0.740196078f, 0.8f };
|
|
||||||
//float mColor2[] = { 0.76372549f, 0.751960784f, 0.745196078f, 0.8f };
|
|
||||||
|
|
||||||
float mColor[] = { 201 / 255f, 200 / 255f, 198 / 255f, 0.8f };
|
private final float[] mColor = {
|
||||||
float mColor2[] = { 201 / 255f, 200 / 255f, 199 / 255f, 0.8f };
|
// roof color
|
||||||
|
236 / 255f * _a, 235 / 255f * _a, 234 / 255f * _a, _a,
|
||||||
//float mRoofColor[] = { 0.895f, 0.89f, 0.88f, 0.9f };
|
// sligthly differ adjacent side faces to improve contrast
|
||||||
float _a = 0.8f;
|
201 / 255f, 200 / 255f, 198 / 255f, _a,
|
||||||
float mRoofColor[] = { 236 / 255f * _a, 235 / 255f * _a, 234 / 255f * _a, _a };
|
200 / 255f, 200 / 255f, 196 / 255f, _a,
|
||||||
|
// roof outline
|
||||||
|
0.75f, 0.75f, 0.75f, 1.0f
|
||||||
|
};
|
||||||
|
|
||||||
final static String extrusionVertexShader = ""
|
final static String extrusionVertexShader = ""
|
||||||
+ "precision mediump float;"
|
+ "precision mediump float;"
|
||||||
+ "uniform mat4 u_mvp;"
|
+ "uniform mat4 u_mvp;"
|
||||||
+ "uniform vec4 u_color;"
|
+ "uniform vec4 u_color[4];"
|
||||||
+ "uniform int u_mode;"
|
+ "uniform int u_mode;"
|
||||||
+ "attribute vec4 a_position;"
|
+ "attribute vec4 a_position;"
|
||||||
+ "attribute vec2 a_light;"
|
+ "attribute vec2 a_light;"
|
||||||
+ "varying vec4 color;"
|
+ "varying vec4 color;"
|
||||||
+ "const float ff = 255.0;"
|
+ "const float ff = 255.0;"
|
||||||
|
+ "const float a = 0.8;"
|
||||||
+ "void main() {"
|
+ "void main() {"
|
||||||
+ " gl_Position = u_mvp * a_position;"
|
+ " gl_Position = u_mvp * a_position;"
|
||||||
+ " if (u_mode == 0)"
|
+ " if (u_mode == 0)"
|
||||||
// roof / depth pass
|
// roof / depth pass
|
||||||
+ " color = u_color;"
|
+ " color = u_color[0];"
|
||||||
+ " else {"
|
+ " else if (u_mode == 1)"
|
||||||
// decrease contrast with distance
|
|
||||||
+ " float alpha = 0.95 + gl_Position.z * 0.05;"
|
|
||||||
+ " if (u_mode == 1)"
|
|
||||||
// sides 1 - use 0xff00
|
// sides 1 - use 0xff00
|
||||||
+ " color = vec4(u_color.rgb * (a_light.y / ff * alpha), 1.0) * (0.8 * alpha);"
|
+ " color = vec4(u_color[1].rgb * ((0.90 + (0.5 - (a_light.y / ff)) * 0.2) * a), a);"
|
||||||
+ " else if (u_mode == 2)"
|
+ " else if (u_mode == 2)"
|
||||||
// sides 2 - use 0x00ff
|
// sides 2 - use 0x00ff
|
||||||
+ " color = vec4(u_color.rgb * (a_light.x / ff * alpha), 1.0) * (0.8 * alpha);"
|
+ " color = vec4(u_color[2].rgb * ((0.90 + (0.5 - (a_light.x / ff)) * 0.2) * a), a);"
|
||||||
+ " else"
|
+ " else"
|
||||||
// sides 2 - use 0x00ff
|
// outline - decrease contrast with distance
|
||||||
+ " color = u_color * alpha;"
|
+ " color = u_color[3] * (0.98 + gl_Position.z * 0.02);"
|
||||||
+ "}}";
|
+ "}";
|
||||||
|
|
||||||
// final static String extrusionVertexAnimShader = ""
|
// final static String extrusionVertexAnimShader = ""
|
||||||
// + "precision mediump float;"
|
// + "precision mediump float;"
|
||||||
|
@ -14,8 +14,6 @@
|
|||||||
*/
|
*/
|
||||||
package org.oscim.utils;
|
package org.oscim.utils;
|
||||||
|
|
||||||
import android.graphics.Point;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Hannes Janetzek
|
* @author Hannes Janetzek
|
||||||
* taken from http://en.wikipedia.org/wiki/Cohen%E2%80%93
|
* taken from http://en.wikipedia.org/wiki/Cohen%E2%80%93
|
||||||
@ -24,14 +22,11 @@ import android.graphics.Point;
|
|||||||
|
|
||||||
public class LineClipper {
|
public class LineClipper {
|
||||||
|
|
||||||
public static final int INSIDE = 0; // 0000
|
private static final int INSIDE = 0; // 0000
|
||||||
public static final int LEFT = 1; // 0001
|
private static final int LEFT = 1; // 0001
|
||||||
public static final int RIGHT = 2; // 0010
|
private static final int RIGHT = 2; // 0010
|
||||||
public static final int BOTTOM = 4; // 0100
|
private static final int BOTTOM = 4; // 0100
|
||||||
public static final int TOP = 8; // 1000
|
private static final int TOP = 8; // 1000
|
||||||
|
|
||||||
// Compute the bit code for a point (x, y) using the clip rectangle
|
|
||||||
// bounded diagonally by (xmin, ymin), and (xmax, ymax)
|
|
||||||
|
|
||||||
private int xmin, xmax, ymin, ymax;
|
private int xmin, xmax, ymin, ymax;
|
||||||
|
|
||||||
@ -42,41 +37,71 @@ public class LineClipper {
|
|||||||
this.ymax = maxy;
|
this.ymax = maxy;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean clip(Point p1, Point p2) {
|
private int mPrevOutcode;
|
||||||
return clip(p1.x, p1.y, p2.x, p2.y);
|
private int mPrevX;
|
||||||
|
private int mPrevY;
|
||||||
|
|
||||||
|
public void clipStart(int x0, int y0) {
|
||||||
|
mPrevX = x0;
|
||||||
|
mPrevY = y0;
|
||||||
|
|
||||||
|
int outcode = INSIDE;
|
||||||
|
if (x0 < xmin)
|
||||||
|
outcode |= LEFT;
|
||||||
|
else if (x0 > xmax)
|
||||||
|
outcode |= RIGHT;
|
||||||
|
if (y0 < ymin)
|
||||||
|
outcode |= BOTTOM;
|
||||||
|
else if (y0 > ymax)
|
||||||
|
outcode |= TOP;
|
||||||
|
|
||||||
|
mPrevOutcode = outcode;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int outCode(int x, int y) {
|
public boolean clipNext(int x1, int y1) {
|
||||||
int code;
|
boolean accept;
|
||||||
|
|
||||||
code = INSIDE; // initialised as being inside of clip window
|
int outcode = INSIDE;
|
||||||
|
if (x1 < xmin)
|
||||||
|
outcode |= LEFT;
|
||||||
|
else if (x1 > xmax)
|
||||||
|
outcode |= RIGHT;
|
||||||
|
if (y1 < ymin)
|
||||||
|
outcode |= BOTTOM;
|
||||||
|
else if (y1 > ymax)
|
||||||
|
outcode |= TOP;
|
||||||
|
|
||||||
if (x < xmin) // to the left of clip window
|
if ((mPrevOutcode | outcode) == 0) {
|
||||||
code |= LEFT;
|
// Bitwise OR is 0. Trivially accept
|
||||||
else if (x > xmax) // to the right of clip window
|
accept = true;
|
||||||
code |= RIGHT;
|
} else if ((mPrevOutcode & outcode) != 0) {
|
||||||
if (y < ymin) // below the clip window
|
// Bitwise AND is not 0. Trivially reject
|
||||||
code |= BOTTOM;
|
accept = false;
|
||||||
else if (y > ymax) // above the clip window
|
} else {
|
||||||
code |= TOP;
|
accept = clip(mPrevX, mPrevY, x1, y1, xmin, ymin, xmax, ymax, mPrevOutcode, outcode);
|
||||||
|
}
|
||||||
|
mPrevOutcode = outcode;
|
||||||
|
mPrevX = x1;
|
||||||
|
mPrevY = y1;
|
||||||
|
|
||||||
return code;
|
return accept;
|
||||||
}
|
}
|
||||||
|
|
||||||
// CohenSutherland clipping algorithm clips a line from
|
// CohenSutherland clipping algorithm clips a line from
|
||||||
// P0 = (x0, y0) to P1 = (x1, y1) against a rectangle with
|
// P0 = (x0, y0) to P1 = (x1, y1) against a rectangle with
|
||||||
// diagonal from (xmin, ymin) to (xmax, ymax).
|
// diagonal from (xmin, ymin) to (xmax, ymax).
|
||||||
public boolean clip(int x0, int y0, int x1, int y1) {
|
private static boolean clip(int x0, int y0, int x1, int y1,
|
||||||
// compute outcodes for P0, P1, and whatever point lies outside the clip rectangle
|
int xmin, int ymin, int xmax, int ymax, int outcode0, int outcode1) {
|
||||||
int outcode0 = outCode(x0, y0);
|
|
||||||
int outcode1 = outCode(x1, y1);
|
|
||||||
boolean accept = false;
|
boolean accept = false;
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
if ((outcode0 | outcode1) == 0) { // Bitwise OR is 0. Trivially accept and get out of loop
|
if ((outcode0 | outcode1) == 0) {
|
||||||
|
// Bitwise OR is 0. Trivially accept and get out of loop
|
||||||
accept = true;
|
accept = true;
|
||||||
break;
|
break;
|
||||||
} else if ((outcode0 & outcode1) != 0) { // Bitwise AND is not 0. Trivially reject and get out of loop
|
} else if ((outcode0 & outcode1) != 0) {
|
||||||
|
// Bitwise AND is not 0. Trivially reject and get out of loop
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
// failed both tests, so calculate the line segment to clip
|
// failed both tests, so calculate the line segment to clip
|
||||||
@ -92,32 +117,45 @@ public class LineClipper {
|
|||||||
if ((outcodeOut & TOP) != 0) { // point is above the clip rectangle
|
if ((outcodeOut & TOP) != 0) { // point is above the clip rectangle
|
||||||
x = x0 + (x1 - x0) * (ymax - y0) / (y1 - y0);
|
x = x0 + (x1 - x0) * (ymax - y0) / (y1 - y0);
|
||||||
y = ymax;
|
y = ymax;
|
||||||
} else if ((outcodeOut & BOTTOM) != 0) { // point is below the clip rectangle
|
} else if ((outcodeOut & BOTTOM) != 0) {
|
||||||
|
// point is below the clip rectangle
|
||||||
x = x0 + (x1 - x0) * (ymin - y0) / (y1 - y0);
|
x = x0 + (x1 - x0) * (ymin - y0) / (y1 - y0);
|
||||||
y = ymin;
|
y = ymin;
|
||||||
} else if ((outcodeOut & RIGHT) != 0) { // point is to the right of clip rectangle
|
} else if ((outcodeOut & RIGHT) != 0) {
|
||||||
|
// point is to the right of clip rectangle
|
||||||
y = y0 + (y1 - y0) * (xmax - x0) / (x1 - x0);
|
y = y0 + (y1 - y0) * (xmax - x0) / (x1 - x0);
|
||||||
x = xmax;
|
x = xmax;
|
||||||
} else if ((outcodeOut & LEFT) != 0) { // point is to the left of clip rectangle
|
} else if ((outcodeOut & LEFT) != 0) {
|
||||||
|
// point is to the left of clip rectangle
|
||||||
y = y0 + (y1 - y0) * (xmin - x0) / (x1 - x0);
|
y = y0 + (y1 - y0) * (xmin - x0) / (x1 - x0);
|
||||||
x = xmin;
|
x = xmin;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int outcode = INSIDE;
|
||||||
|
if (x < xmin)
|
||||||
|
outcode |= LEFT;
|
||||||
|
else if (x > xmax)
|
||||||
|
outcode |= RIGHT;
|
||||||
|
if (y < ymin)
|
||||||
|
outcode |= BOTTOM;
|
||||||
|
else if (y > ymax)
|
||||||
|
outcode |= TOP;
|
||||||
|
|
||||||
// Now we move outside point to intersection point to clip
|
// Now we move outside point to intersection point to clip
|
||||||
// and get ready for next pass.
|
// and get ready for next pass.
|
||||||
if (outcodeOut == outcode0) {
|
if (outcodeOut == outcode0) {
|
||||||
x0 = x;
|
x0 = x;
|
||||||
y0 = y;
|
y0 = y;
|
||||||
outcode0 = outCode(x0, y0);
|
outcode0 = outcode;
|
||||||
} else {
|
} else {
|
||||||
x1 = x;
|
x1 = x;
|
||||||
y1 = y;
|
y1 = y;
|
||||||
outcode1 = outCode(x1, y1);
|
outcode1 = outcode;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO do sth with the result x0...
|
// TODO could do sth with the result x0...
|
||||||
return accept;
|
return accept;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user