diff --git a/src/org/oscim/renderer/layer/ExtrusionLayer.java b/src/org/oscim/renderer/layer/ExtrusionLayer.java index ee1cb623..114477a8 100644 --- a/src/org/oscim/renderer/layer/ExtrusionLayer.java +++ b/src/org/oscim/renderer/layer/ExtrusionLayer.java @@ -39,13 +39,13 @@ public class ExtrusionLayer extends Layer { private VertexPoolItem mIndices[], mCurIndices[]; private LineClipper mClipper; - public int mIndiceCnt[] = { 0, 0, 0 }; + public int mIndiceCnt[] = { 0, 0, 0, 0 }; public int mIndicesBufferID; public int mVertexBufferID; public int mNumIndices = 0; - private final static int IND_EVEN_SIDE = 0; - private final static int IND_ODD_SIDE = 1; + //private final static int IND_EVEN_SIDE = 0; + //private final static int IND_ODD_SIDE = 1; private final static int IND_ROOF = 2; private final static int IND_OUTLINE = 3; @@ -187,31 +187,38 @@ public class ExtrusionLayer extends Layer { float nx = points[pos + 0]; float ny = points[pos + 1]; + // vector to next point float vx = nx - cx; float vy = ny - cy; - float ca = (float) Math.sqrt(vx * vx + vy * vy); - float ux = vx; - float uy = vy; + // vector from previous point + float ux, uy; + float ca = (float) Math.sqrt(vx * vx + vy * vy); float vlight = vx > 0 ? (vx / ca) : -(vx / ca) - 0.1f; short color1 = (short) (200 + (50 * vlight)); short fcolor = color1; short color2 = 0; - boolean even = true; + int even = 0; int changeX = 0; int changeY = 0; + // vertex offset for all vertices in layer + int vOffset = mNumVertices; + short[] vertices = mCurVertices.vertices; int v = mCurVertices.used; - for (int i = 2; i < len + 2; i += 2, v += 8) { + for (int i = 2, n = vertexCnt + 2; i < n; i += 2, v += 8) { /* add bottom and top vertex for each point */ cx = nx; cy = ny; + ux = vx; + uy = vy; + if (v == VertexPoolItem.SIZE) { mCurVertices.used = VertexPoolItem.SIZE; mCurVertices.next = VertexPool.get(); @@ -232,28 +239,35 @@ public class ExtrusionLayer extends Layer { if (i < len) { nx = points[pos + i + 0]; ny = points[pos + i + 1]; - } else { + } else if (i == len) { nx = points[pos + 0]; ny = points[pos + 1]; - //color2 = fcolor; + } else { // if (addFace) + short c = (short) (color1 | fcolor << 8); + vertices[v + 3] = vertices[v + 7] = c; + v += 8; + break; } + // vector to next point vx = nx - cx; vy = ny - cy; - ca = (float) Math.sqrt(vx * vx + vy * vy); + ca = (float) Math.sqrt(vx * vx + vy * vy); vlight = vx > 0 ? (vx / ca) : -(vx / ca) - 0.1f; color2 = (short) (200 + (50 * vlight)); short c; - if (even) + if (even == 0) c = (short) (color1 | color2 << 8); else c = (short) (color2 | color1 << 8); // set lighting (direction) vertices[v + 3] = vertices[v + 7] = c; + color1 = color2; + // check if polygon is convex if (convex) { // TODO simple polys with only one concave arc // could be handled without special triangulation @@ -267,113 +281,59 @@ public class ExtrusionLayer extends Layer { convex = false; } - ux = vx; - uy = vy; - color1 = color2; - even = !even; - } - - if (addFace) { - if (v == VertexPoolItem.SIZE) { - mCurVertices.used = VertexPoolItem.SIZE; - mCurVertices.next = VertexPool.get(); - mCurVertices = mCurVertices.next; - vertices = mCurVertices.vertices; - v = 0; + // check if face is within tile + if (!mClipper.clip((int) cx, (int) cy, (int) nx, (int) ny)) { + even = (even + 1) % 2; + continue; } - cx = points[pos + 0]; - cy = points[pos + 1]; + // add ZigZagQuadIndices(tm) for sides + short[] indices = mCurIndices[even].vertices; + // index id relative to mCurIndices item + int ind = mCurIndices[even].used; + short vert = (short) (vOffset + (i - 2)); + short s0 = vert++; + short s1 = vert++; + short s2 = vert++; + short s3 = vert++; - vertices[v + 0] = vertices[v + 4] = (short) (cx * S); - vertices[v + 1] = vertices[v + 5] = (short) (cy * S); + if (ind == VertexPoolItem.SIZE) { + //mCurIndices[even].used = VertexPoolItem.SIZE; + mCurIndices[even].next = VertexPool.get(); + mCurIndices[even] = mCurIndices[even].next; + indices = mCurIndices[even].vertices; + ind = 0; + } - vertices[v + 2] = 0; - vertices[v + 6] = h; + // connect last to first (when number of faces is even) + if (!addFace && i == len) { + s2 -= len; + s3 -= len; + } - short c = (short) (color1 | fcolor << 8); - vertices[v + 3] = vertices[v + 7] = c; + indices[ind + 0] = s0; + indices[ind + 1] = s1; + indices[ind + 2] = s2; - v += 8; + indices[ind + 3] = s1; + indices[ind + 4] = s3; + indices[ind + 5] = s2; + + mCurIndices[even].used += 6; + even = (even + 1) % 2; + + // add outline indices + VertexPoolItem it = mCurIndices[IND_OUTLINE]; + if (it.used == VertexPoolItem.SIZE) { + it.next = VertexPool.get(); + it = mCurIndices[IND_OUTLINE] = it.next; + } + it.vertices[it.used++] = s1; + it.vertices[it.used++] = s3; } mCurVertices.used = v; - // fill ZigZagQuadIndices(tm) and outline indices - for (int j = 0; j < 2; j++) { - short[] indices = mCurIndices[j].vertices; - - // index id relative to mCurIndices - int i = mCurIndices[j].used; - - // vertex id - v = mNumVertices + (j * 2); - int ppos = pos + (j * 2); - - for (int k = j * 2; k < len; k += 4, ppos += 4) { - boolean accept; - if (k + 2 < len) { - accept = mClipper.clip( - (int) points[ppos], - (int) points[ppos + 1], - (int) points[ppos + 2], - (int) points[ppos + 3]); - } else { - accept = mClipper.clip( - (int) points[ppos], - (int) points[ppos + 1], - (int) points[pos + 0], - (int) points[pos + 1]); - } - - if (!accept) { - // Log.d(TAG, "omit line: " - // + points[ppos] + ":" + points[ppos + 1] + " " - // + points[ppos + 2] + ":" + points[ppos + 3]); - v += 4; - continue; - } - - short s0 = (short) (v++); - short s1 = (short) (v++); - short s2 = (short) (v++); - short s3 = (short) (v++); - - if (i == VertexPoolItem.SIZE) { - mCurIndices[j].used = VertexPoolItem.SIZE; - mCurIndices[j].next = VertexPool.get(); - mCurIndices[j] = mCurIndices[j].next; - indices = mCurIndices[j].vertices; - i = 0; - } - - if (k + 2 == len) { - // connect last to first (when number of faces is even) - if (!addFace) { - //Log.d(TAG, "connect last " + vertexCnt + " " + len); - s2 -= len; - s3 -= len; - } - } - - indices[i++] = s0; - indices[i++] = s1; - indices[i++] = s2; - - indices[i++] = s1; - indices[i++] = s3; - indices[i++] = s2; - //System.out.println(" i:" + (mNumIndices + (k * 6)) - // + "\t(" + s0 + "," + s1 + "," + s2 - // + ")\t(" + s1 + "," + s3 + "," + s2 + ")"); - - // outline[cOut++] = s1; - // outline[cOut++] = s3; - - } - mCurIndices[j].used = i; - } - mNumVertices += vertexCnt; return convex; } @@ -391,33 +351,24 @@ public class ExtrusionLayer extends Layer { // upload indices sbuf.clear(); - for (int i = 0; i < 3; i++) { + mNumIndices = 0; + for (int i = 0; i < 4; i++) { for (VertexPoolItem vi = mIndices[i]; vi != null; vi = vi.next) { - //System.out.println("put indices: " + vi.used + " " + mNumIndices); sbuf.put(vi.vertices, 0, vi.used); mIndiceCnt[i] += vi.used; } + mNumIndices += mIndiceCnt[i]; } - // Log.d(TAG,"put indices: " + mNumIndices + "==" - // + (mIndiceCnt[0] + mIndiceCnt[1] + mIndiceCnt[2]) - // + " " + mIndiceCnt[0] + " " + mIndiceCnt[1] + " " + mIndiceCnt[2]); - - mNumIndices = mIndiceCnt[0] + mIndiceCnt[1] + mIndiceCnt[2]; - sbuf.flip(); - GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, mIndicesBufferID); GLES20.glBufferData(GLES20.GL_ELEMENT_ARRAY_BUFFER, mNumIndices * 2, sbuf, GLES20.GL_DYNAMIC_DRAW); - sbuf.clear(); - // upload vertices - for (VertexPoolItem vi = mVertices; vi != null; vi = vi.next) { - //System.out.println("put vertices: " + vi.used + " " + mNumVertices); + sbuf.clear(); + for (VertexPoolItem vi = mVertices; vi != null; vi = vi.next) sbuf.put(vi.vertices, 0, vi.used); - } sbuf.flip(); GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, mVertexBufferID); diff --git a/src/org/oscim/renderer/overlays/BuildingOverlay2.java b/src/org/oscim/renderer/overlays/BuildingOverlay2.java index 9c2e0b89..9a50a7f3 100644 --- a/src/org/oscim/renderer/overlays/BuildingOverlay2.java +++ b/src/org/oscim/renderer/overlays/BuildingOverlay2.java @@ -150,13 +150,22 @@ public class BuildingOverlay2 extends RenderOverlay { GLES20.glVertexAttribPointer(hBuildingLightPosition, 2, GLES20.GL_UNSIGNED_BYTE, false, 8, 6); - GLES20.glDrawElements(GLES20.GL_TRIANGLES, el.mNumIndices, + GLES20.glUniform4f(hBuildingColor, 0.6f, 0.6f, 0.6f, 0.8f); + GLES20.glDrawElements(GLES20.GL_TRIANGLES, + (el.mIndiceCnt[0] + el.mIndiceCnt[1] + el.mIndiceCnt[2]), GLES20.GL_UNSIGNED_SHORT, 0); + + GLES20.glUniform1i(hBuildingMode, 0); + GLES20.glUniform4f(hBuildingColor, 1.0f, 0.5f, 0.5f, 0.9f); + + GLES20.glDrawElements(GLES20.GL_LINES, el.mIndiceCnt[3], + GLES20.GL_UNSIGNED_SHORT, + (el.mIndiceCnt[0] + el.mIndiceCnt[1] + el.mIndiceCnt[2]) * 2); } return; } - int drawCount = 0; + //int drawCount = 2; // draw to depth buffer MapTile[] tiles = mTileSet.tiles; for (int i = 0; i < mTileSet.cnt; i++) { @@ -183,13 +192,14 @@ public class BuildingOverlay2 extends RenderOverlay { GLES20.glUniform1i(hBuildingMode, 0); first = false; } + GLES20.glPolygonOffset(1, 10); - GLES20.glPolygonOffset(0, drawCount += 10); - // seems there are not infinite offset units possible - // this should suffice for at least two rows, i.e. - // having not two neighbours with the same depth - if (drawCount == 100) - drawCount = 0; + // GLES20.glPolygonOffset(0, drawCount += 10); + // // seems there are not infinite offset units possible + // // this should suffice for at least two rows, i.e. + // // having not two neighbours with the same depth + // if (drawCount == 100) + // drawCount = 0; setMatrix(pos, mv, proj, tiles[i], 1); GLES20.glUniformMatrix4fv(hBuildingMatrix, 1, false, mv, 0); @@ -200,7 +210,8 @@ public class BuildingOverlay2 extends RenderOverlay { GLES20.glVertexAttribPointer(hBuildingVertexPosition, 3, GLES20.GL_SHORT, false, 8, 0); - GLES20.glDrawElements(GLES20.GL_TRIANGLES, el.mNumIndices, + GLES20.glDrawElements(GLES20.GL_TRIANGLES, + (el.mIndiceCnt[0] + el.mIndiceCnt[1] + el.mIndiceCnt[2]), GLES20.GL_UNSIGNED_SHORT, 0); } @@ -209,12 +220,12 @@ public class BuildingOverlay2 extends RenderOverlay { // enable color buffer, use depth mask GLRenderer.enableVertexArrays(hBuildingVertexPosition, hBuildingLightPosition); GLES20.glColorMask(true, true, true, true); - //GLES20.glDepthMask(false); - GLES20.glDepthFunc(GLES20.GL_EQUAL); + GLES20.glDepthMask(false); + GLES20.glDepthFunc(GLES20.GL_LEQUAL); //GLES20.glDepthFunc(GLES20.GL_EQUAL); - drawCount = 0; - //GLES20.glEnable(GLES20.GL_POLYGON_OFFSET_FILL); + //drawCount = 0; + GLES20.glDisable(GLES20.GL_POLYGON_OFFSET_FILL); //GLES20.glPolygonOffset(0, -2); for (int i = 0; i < mTileSet.cnt; i++) { @@ -226,9 +237,9 @@ public class BuildingOverlay2 extends RenderOverlay { if (!el.compiled) continue; - GLES20.glPolygonOffset(0, drawCount += 10); - if (drawCount == 100) - drawCount = 0; + // GLES20.glPolygonOffset(0, drawCount += 10); + // if (drawCount == 100) + // drawCount = 0; setMatrix(pos, mv, proj, tiles[i], 1); GLES20.glUniformMatrix4fv(hBuildingMatrix, 1, false, mv, 0); @@ -266,17 +277,13 @@ public class BuildingOverlay2 extends RenderOverlay { GLES20.glDrawElements(GLES20.GL_TRIANGLES, el.mIndiceCnt[1], GLES20.GL_UNSIGNED_SHORT, el.mIndiceCnt[0] * 2); - GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, 0); - GlUtils.checkGlError(".1."); + GLES20.glUniform1i(hBuildingMode, 0); + GLES20.glUniform4f(hBuildingColor, 0.7f, 0.7f, 0.72f, 1.0f); + + GLES20.glDrawElements(GLES20.GL_LINES, el.mIndiceCnt[3], + GLES20.GL_UNSIGNED_SHORT, + (el.mIndiceCnt[0] + el.mIndiceCnt[1] + el.mIndiceCnt[2]) * 2); - // GLRenderer.enableVertexArrays(hBuildingVertexPosition, -1); - // GLES20.glVertexAttribPointer(hBuildingVertexPosition, 3, - // GLES20.GL_SHORT, false, 16, 8); - // - // GLES20.glUniform1i(hBuildingMode, 0); - // GLES20.glUniform4f(hBuildingColor, 1.0f, 0.5f, 0.5f, 0.9f); - // GLES20.glDrawArrays(GLES20.GL_LINE_STRIP, 0, 10); - // // GlUtils.checkGlError(".2."); }