refactor ExtrusionRenderer
+ cleanups
This commit is contained in:
parent
5af831abb5
commit
b9ebf1e57b
@ -25,9 +25,8 @@ import org.slf4j.LoggerFactory;
|
||||
|
||||
public abstract class ExtrusionRenderer extends LayerRenderer {
|
||||
static final Logger log = LoggerFactory.getLogger(ExtrusionRenderer.class);
|
||||
static final boolean debugDraw = false;
|
||||
|
||||
private final boolean drawAlpha;
|
||||
private final boolean mTranslucent;
|
||||
private final int mMode;
|
||||
private Shader mShader;
|
||||
|
||||
@ -37,7 +36,7 @@ public abstract class ExtrusionRenderer extends LayerRenderer {
|
||||
|
||||
public ExtrusionRenderer(boolean mesh, boolean alpha) {
|
||||
mMode = mesh ? 1 : 0;
|
||||
drawAlpha = alpha;
|
||||
mTranslucent = alpha;
|
||||
}
|
||||
|
||||
public static class Shader extends GLShader {
|
||||
@ -67,11 +66,6 @@ public abstract class ExtrusionRenderer extends LayerRenderer {
|
||||
}
|
||||
|
||||
private void renderCombined(int vertexPointer, ExtrusionLayers els) {
|
||||
if (els.vboIndices == null)
|
||||
return;
|
||||
|
||||
els.vboIndices.bind();
|
||||
els.vboVertices.bind();
|
||||
|
||||
for (ExtrusionLayer el = els.layers; el != null; el = el.next()) {
|
||||
|
||||
@ -93,169 +87,149 @@ public abstract class ExtrusionRenderer extends LayerRenderer {
|
||||
|
||||
@Override
|
||||
public void render(GLViewport v) {
|
||||
// TODO one could render in one pass to texture and then draw the texture
|
||||
// with alpha... might be faster and would allow postprocessing outlines.
|
||||
|
||||
ExtrusionLayers[] els = mExtrusionLayerSet;
|
||||
Shader s = mShader;
|
||||
|
||||
if (debugDraw) {
|
||||
s.useProgram();
|
||||
GLState.enableVertexArrays(s.aPos, s.aLight);
|
||||
GL.glUniform1i(s.uMode, 0);
|
||||
GLUtils.glUniform4fv(s.uColor, 4, DEBUG_COLOR);
|
||||
GL.glUniform1f(s.uAlpha, 1);
|
||||
|
||||
GLState.test(false, false);
|
||||
GLState.blend(true);
|
||||
for (int i = 0; i < mExtrusionLayerCnt; i++) {
|
||||
ExtrusionLayer el = els[i].getLayers();
|
||||
|
||||
setMatrix(v, els[i], 0);
|
||||
v.mvp.setAsUniform(s.uMVP);
|
||||
|
||||
renderCombined(s.aPos, els[i]);
|
||||
|
||||
/* just a temporary reference! */
|
||||
els[i] = null;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
GL.glDepthMask(true);
|
||||
GL.glClear(GL20.GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
GLState.test(true, false);
|
||||
|
||||
Shader s = mShader;
|
||||
s.useProgram();
|
||||
GLState.enableVertexArrays(s.aPos, -1);
|
||||
GLState.blend(false);
|
||||
|
||||
GL.glEnable(GL20.GL_CULL_FACE);
|
||||
/* only use face-culling when it's unlikely
|
||||
* that one'moves through the building' */
|
||||
if (v.pos.zoomLevel < 18)
|
||||
GL.glEnable(GL20.GL_CULL_FACE);
|
||||
|
||||
GL.glDepthFunc(GL20.GL_LESS);
|
||||
|
||||
GL.glUniform1f(s.uAlpha, mAlpha);
|
||||
|
||||
if (drawAlpha) {
|
||||
ExtrusionLayers[] els = mExtrusionLayerSet;
|
||||
|
||||
if (mTranslucent) {
|
||||
/* only draw to depth buffer */
|
||||
GLState.blend(false);
|
||||
GL.glColorMask(false, false, false, false);
|
||||
GL.glUniform1i(s.uMode, -1);
|
||||
//GLUtils.glUniform4fv(uExtColor, 4, mColor);
|
||||
|
||||
/* draw to depth buffer */
|
||||
for (int i = 0; i < mExtrusionLayerCnt; i++) {
|
||||
ExtrusionLayer el = els[i].getLayers();
|
||||
if (el == null)
|
||||
continue;
|
||||
if (els[i].vboIndices == null)
|
||||
return;
|
||||
|
||||
int d = 0; // FIXME MapTile.depthOffset(t) * 10;
|
||||
els[i].vboIndices.bind();
|
||||
els[i].vboVertices.bind();
|
||||
|
||||
setMatrix(v, els[i], d);
|
||||
setMatrix(v, els[i], true);
|
||||
v.mvp.setAsUniform(s.uMVP);
|
||||
|
||||
renderCombined(s.aPos, els[i]);
|
||||
}
|
||||
|
||||
/* only draw to color buffer */
|
||||
GL.glColorMask(true, true, true, true);
|
||||
GL.glDepthMask(false);
|
||||
GLState.blend(true);
|
||||
|
||||
GL.glDepthFunc(GL20.GL_EQUAL);
|
||||
}
|
||||
|
||||
GLState.blend(true);
|
||||
GLState.enableVertexArrays(s.aPos, s.aLight);
|
||||
|
||||
GLState.enableVertexArrays(s.aPos, s.aLight);
|
||||
float[] currentColor = null;
|
||||
|
||||
for (int i = 0; i < mExtrusionLayerCnt; i++) {
|
||||
ExtrusionLayer el = els[i].getLayers();
|
||||
|
||||
if (el == null)
|
||||
continue;
|
||||
|
||||
if (els[i].vboIndices == null)
|
||||
continue;
|
||||
|
||||
els[i].vboIndices.bind();
|
||||
els[i].vboVertices.bind();
|
||||
|
||||
int d = 0;
|
||||
if (drawAlpha) {
|
||||
GL.glDepthFunc(GL20.GL_EQUAL);
|
||||
|
||||
// FIXME d = MapTile.depthOffset(t) * 10;
|
||||
if (!mTranslucent) {
|
||||
setMatrix(v, els[i], false);
|
||||
v.mvp.setAsUniform(s.uMVP);
|
||||
}
|
||||
|
||||
setMatrix(v, els[i], d);
|
||||
v.mvp.setAsUniform(s.uMVP);
|
||||
|
||||
ExtrusionLayer el = els[i].getLayers();
|
||||
for (; el != null; el = el.next()) {
|
||||
|
||||
if (el.colors != currentColor) {
|
||||
currentColor = el.colors;
|
||||
GLUtils.glUniform4fv(s.uColor, mMode == 0 ? 4 : 1,
|
||||
GLUtils.glUniform4fv(s.uColor,
|
||||
mMode == 0 ? 4 : 1,
|
||||
el.colors);
|
||||
}
|
||||
|
||||
/* indices offset */
|
||||
int indexOffset = el.indexOffset;
|
||||
/* vertex byte offset */
|
||||
int vertexOffset = el.getOffset();
|
||||
|
||||
GL.glVertexAttribPointer(s.aPos, 3,
|
||||
GL20.GL_SHORT, false, 8, vertexOffset);
|
||||
GL.glVertexAttribPointer(s.aPos, 3, GL20.GL_SHORT,
|
||||
false, 8, el.getOffset());
|
||||
|
||||
GL.glVertexAttribPointer(s.aLight, 2,
|
||||
GL20.GL_UNSIGNED_BYTE, false, 8, vertexOffset + 6);
|
||||
GL20.GL_UNSIGNED_BYTE,
|
||||
false, 8, el.getOffset() + 6);
|
||||
|
||||
/* draw extruded outlines */
|
||||
if (el.numIndices[0] > 0) {
|
||||
if (mTranslucent) {
|
||||
GL.glDepthFunc(GL20.GL_EQUAL);
|
||||
setMatrix(v, els[i], true);
|
||||
v.mvp.setAsUniform(s.uMVP);
|
||||
}
|
||||
|
||||
/* draw roof */
|
||||
GL.glUniform1i(s.uMode, 0);
|
||||
GL.glDrawElements(GL20.GL_TRIANGLES, el.numIndices[2],
|
||||
GL.glDrawElements(GL20.GL_TRIANGLES,
|
||||
el.numIndices[2],
|
||||
GL20.GL_UNSIGNED_SHORT,
|
||||
(el.numIndices[0] + el.numIndices[1]) * 2);
|
||||
(el.numIndices[0]
|
||||
+ el.numIndices[1]) * 2);
|
||||
|
||||
/* draw sides 1 */
|
||||
GL.glUniform1i(s.uMode, 1);
|
||||
GL.glDrawElements(GL20.GL_TRIANGLES, el.numIndices[0],
|
||||
GL.glDrawElements(GL20.GL_TRIANGLES,
|
||||
el.numIndices[0],
|
||||
GL20.GL_UNSIGNED_SHORT, 0);
|
||||
|
||||
/* draw sides 2 */
|
||||
GL.glUniform1i(s.uMode, 2);
|
||||
GL.glDrawElements(GL20.GL_TRIANGLES, el.numIndices[1],
|
||||
GL20.GL_UNSIGNED_SHORT, el.numIndices[0] * 2);
|
||||
GL.glDrawElements(GL20.GL_TRIANGLES,
|
||||
el.numIndices[1],
|
||||
GL20.GL_UNSIGNED_SHORT,
|
||||
el.numIndices[0] * 2);
|
||||
|
||||
if (drawAlpha) {
|
||||
if (mTranslucent) {
|
||||
/* drawing gl_lines with the same coordinates does not
|
||||
* result in same depth values as polygons, so add
|
||||
* offset and draw gl_lequal: */
|
||||
GL.glDepthFunc(GL20.GL_LEQUAL);
|
||||
v.mvp.addDepthOffset(100);
|
||||
v.mvp.setAsUniform(s.uMVP);
|
||||
}
|
||||
|
||||
v.mvp.addDepthOffset(100);
|
||||
v.mvp.setAsUniform(s.uMVP);
|
||||
|
||||
GL.glUniform1i(s.uMode, 3);
|
||||
|
||||
int offset = 2 * (indexOffset
|
||||
int offset = 2 * (el.indexOffset
|
||||
+ el.numIndices[0]
|
||||
+ el.numIndices[1]
|
||||
+ el.numIndices[2]);
|
||||
|
||||
GL.glDrawElements(GL20.GL_LINES, el.numIndices[3],
|
||||
GL20.GL_UNSIGNED_SHORT, offset);
|
||||
GL.glDrawElements(GL20.GL_LINES,
|
||||
el.numIndices[3],
|
||||
GL20.GL_UNSIGNED_SHORT,
|
||||
offset);
|
||||
|
||||
}
|
||||
|
||||
/* draw triangle meshes */
|
||||
if (el.numIndices[4] > 0) {
|
||||
int offset = 2 * (indexOffset
|
||||
int offset = 2 * (el.indexOffset
|
||||
+ el.numIndices[0]
|
||||
+ el.numIndices[1]
|
||||
+ el.numIndices[2]
|
||||
+ el.numIndices[3]);
|
||||
|
||||
GL.glUniform1i(s.uMode, 4);
|
||||
GL.glDrawElements(GL20.GL_TRIANGLES, el.numIndices[4],
|
||||
GL20.GL_UNSIGNED_SHORT, offset);
|
||||
GL.glDrawElements(GL20.GL_TRIANGLES,
|
||||
el.numIndices[4],
|
||||
GL20.GL_UNSIGNED_SHORT,
|
||||
offset);
|
||||
}
|
||||
}
|
||||
|
||||
@ -263,56 +237,31 @@ public abstract class ExtrusionRenderer extends LayerRenderer {
|
||||
els[i] = null;
|
||||
}
|
||||
|
||||
GL.glDepthMask(false);
|
||||
GL.glDisable(GL20.GL_CULL_FACE);
|
||||
if (!mTranslucent)
|
||||
GL.glDepthMask(false);
|
||||
|
||||
if (v.pos.zoomLevel < 18)
|
||||
GL.glDisable(GL20.GL_CULL_FACE);
|
||||
|
||||
GL.glBindBuffer(GL20.GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||
}
|
||||
|
||||
private static void setMatrix(GLViewport v, ExtrusionLayers l, int delta) {
|
||||
private static void setMatrix(GLViewport v, ExtrusionLayers l, boolean offset) {
|
||||
|
||||
int z = l.zoomLevel;
|
||||
double curScale = Tile.SIZE * v.pos.scale;
|
||||
float scale = (float) (v.pos.scale / (1 << z));
|
||||
|
||||
float x = (float) ((l.x - v.pos.x) * curScale);
|
||||
float y = (float) ((l.y - v.pos.y) * curScale);
|
||||
|
||||
v.mvp.setTransScale(x, y, scale / MapRenderer.COORD_SCALE);
|
||||
|
||||
// scale height ???
|
||||
v.mvp.setValue(10, scale / 10);
|
||||
|
||||
v.mvp.multiplyLhs(v.viewproj);
|
||||
|
||||
v.mvp.addDepthOffset(delta);
|
||||
if (offset) {
|
||||
int delta = (int) (l.x * (1 << z)) % 4 + (int) (l.y * (1 << z)) % 4 * 4;
|
||||
v.mvp.addDepthOffset(delta);
|
||||
}
|
||||
}
|
||||
|
||||
private static float A = 0.88f;
|
||||
private static float R = 0xe9;
|
||||
private static float G = 0xe8;
|
||||
private static float B = 0xe6;
|
||||
private static float O = 20;
|
||||
private static float S = 4;
|
||||
private static float L = 0;
|
||||
|
||||
private static float[] DEBUG_COLOR = {
|
||||
// roof color
|
||||
A * ((R + L) / 255),
|
||||
A * ((G + L) / 255),
|
||||
A * ((B + L) / 255),
|
||||
0.8f,
|
||||
// sligthly differ adjacent side
|
||||
// faces to improve contrast
|
||||
A * ((R - S) / 255 + 0.01f),
|
||||
A * ((G - S) / 255 + 0.01f),
|
||||
A * ((B - S) / 255),
|
||||
A,
|
||||
A * ((R - S) / 255),
|
||||
A * ((G - S) / 255),
|
||||
A * ((B - S) / 255),
|
||||
A,
|
||||
// roof outline
|
||||
(R - O) / 255,
|
||||
(G - O) / 255,
|
||||
(B - O) / 255,
|
||||
0.9f,
|
||||
};
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user