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 {
|
public abstract class ExtrusionRenderer extends LayerRenderer {
|
||||||
static final Logger log = LoggerFactory.getLogger(ExtrusionRenderer.class);
|
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 final int mMode;
|
||||||
private Shader mShader;
|
private Shader mShader;
|
||||||
|
|
||||||
@ -37,7 +36,7 @@ public abstract class ExtrusionRenderer extends LayerRenderer {
|
|||||||
|
|
||||||
public ExtrusionRenderer(boolean mesh, boolean alpha) {
|
public ExtrusionRenderer(boolean mesh, boolean alpha) {
|
||||||
mMode = mesh ? 1 : 0;
|
mMode = mesh ? 1 : 0;
|
||||||
drawAlpha = alpha;
|
mTranslucent = alpha;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class Shader extends GLShader {
|
public static class Shader extends GLShader {
|
||||||
@ -67,11 +66,6 @@ public abstract class ExtrusionRenderer extends LayerRenderer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void renderCombined(int vertexPointer, ExtrusionLayers els) {
|
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()) {
|
for (ExtrusionLayer el = els.layers; el != null; el = el.next()) {
|
||||||
|
|
||||||
@ -93,169 +87,149 @@ public abstract class ExtrusionRenderer extends LayerRenderer {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void render(GLViewport v) {
|
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.glDepthMask(true);
|
||||||
GL.glClear(GL20.GL_DEPTH_BUFFER_BIT);
|
GL.glClear(GL20.GL_DEPTH_BUFFER_BIT);
|
||||||
|
|
||||||
GLState.test(true, false);
|
GLState.test(true, false);
|
||||||
|
|
||||||
|
Shader s = mShader;
|
||||||
s.useProgram();
|
s.useProgram();
|
||||||
GLState.enableVertexArrays(s.aPos, -1);
|
GLState.enableVertexArrays(s.aPos, -1);
|
||||||
GLState.blend(false);
|
|
||||||
|
|
||||||
|
/* 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.glEnable(GL20.GL_CULL_FACE);
|
||||||
GL.glDepthFunc(GL20.GL_LESS);
|
|
||||||
|
|
||||||
|
GL.glDepthFunc(GL20.GL_LESS);
|
||||||
GL.glUniform1f(s.uAlpha, mAlpha);
|
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.glColorMask(false, false, false, false);
|
||||||
GL.glUniform1i(s.uMode, -1);
|
GL.glUniform1i(s.uMode, -1);
|
||||||
//GLUtils.glUniform4fv(uExtColor, 4, mColor);
|
|
||||||
|
|
||||||
/* draw to depth buffer */
|
|
||||||
for (int i = 0; i < mExtrusionLayerCnt; i++) {
|
for (int i = 0; i < mExtrusionLayerCnt; i++) {
|
||||||
ExtrusionLayer el = els[i].getLayers();
|
if (els[i].vboIndices == null)
|
||||||
if (el == null)
|
return;
|
||||||
continue;
|
|
||||||
|
|
||||||
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);
|
v.mvp.setAsUniform(s.uMVP);
|
||||||
|
|
||||||
renderCombined(s.aPos, els[i]);
|
renderCombined(s.aPos, els[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* only draw to color buffer */
|
||||||
GL.glColorMask(true, true, true, true);
|
GL.glColorMask(true, true, true, true);
|
||||||
GL.glDepthMask(false);
|
GL.glDepthMask(false);
|
||||||
GLState.blend(true);
|
|
||||||
|
GL.glDepthFunc(GL20.GL_EQUAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
GLState.blend(true);
|
GLState.blend(true);
|
||||||
GLState.enableVertexArrays(s.aPos, s.aLight);
|
|
||||||
|
|
||||||
|
GLState.enableVertexArrays(s.aPos, s.aLight);
|
||||||
float[] currentColor = null;
|
float[] currentColor = null;
|
||||||
|
|
||||||
for (int i = 0; i < mExtrusionLayerCnt; i++) {
|
for (int i = 0; i < mExtrusionLayerCnt; i++) {
|
||||||
ExtrusionLayer el = els[i].getLayers();
|
|
||||||
|
|
||||||
if (el == null)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (els[i].vboIndices == null)
|
if (els[i].vboIndices == null)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
els[i].vboIndices.bind();
|
els[i].vboIndices.bind();
|
||||||
els[i].vboVertices.bind();
|
els[i].vboVertices.bind();
|
||||||
|
|
||||||
int d = 0;
|
if (!mTranslucent) {
|
||||||
if (drawAlpha) {
|
setMatrix(v, els[i], false);
|
||||||
GL.glDepthFunc(GL20.GL_EQUAL);
|
v.mvp.setAsUniform(s.uMVP);
|
||||||
|
|
||||||
// FIXME d = MapTile.depthOffset(t) * 10;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
setMatrix(v, els[i], d);
|
ExtrusionLayer el = els[i].getLayers();
|
||||||
v.mvp.setAsUniform(s.uMVP);
|
|
||||||
|
|
||||||
for (; el != null; el = el.next()) {
|
for (; el != null; el = el.next()) {
|
||||||
|
|
||||||
if (el.colors != currentColor) {
|
if (el.colors != currentColor) {
|
||||||
currentColor = el.colors;
|
currentColor = el.colors;
|
||||||
GLUtils.glUniform4fv(s.uColor, mMode == 0 ? 4 : 1,
|
GLUtils.glUniform4fv(s.uColor,
|
||||||
|
mMode == 0 ? 4 : 1,
|
||||||
el.colors);
|
el.colors);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* indices offset */
|
GL.glVertexAttribPointer(s.aPos, 3, GL20.GL_SHORT,
|
||||||
int indexOffset = el.indexOffset;
|
false, 8, el.getOffset());
|
||||||
/* vertex byte offset */
|
|
||||||
int vertexOffset = el.getOffset();
|
|
||||||
|
|
||||||
GL.glVertexAttribPointer(s.aPos, 3,
|
|
||||||
GL20.GL_SHORT, false, 8, vertexOffset);
|
|
||||||
|
|
||||||
GL.glVertexAttribPointer(s.aLight, 2,
|
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 */
|
/* draw extruded outlines */
|
||||||
if (el.numIndices[0] > 0) {
|
if (el.numIndices[0] > 0) {
|
||||||
|
if (mTranslucent) {
|
||||||
|
GL.glDepthFunc(GL20.GL_EQUAL);
|
||||||
|
setMatrix(v, els[i], true);
|
||||||
|
v.mvp.setAsUniform(s.uMVP);
|
||||||
|
}
|
||||||
|
|
||||||
/* draw roof */
|
/* draw roof */
|
||||||
GL.glUniform1i(s.uMode, 0);
|
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,
|
GL20.GL_UNSIGNED_SHORT,
|
||||||
(el.numIndices[0] + el.numIndices[1]) * 2);
|
(el.numIndices[0]
|
||||||
|
+ el.numIndices[1]) * 2);
|
||||||
|
|
||||||
/* draw sides 1 */
|
/* draw sides 1 */
|
||||||
GL.glUniform1i(s.uMode, 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);
|
GL20.GL_UNSIGNED_SHORT, 0);
|
||||||
|
|
||||||
/* draw sides 2 */
|
/* draw sides 2 */
|
||||||
GL.glUniform1i(s.uMode, 2);
|
GL.glUniform1i(s.uMode, 2);
|
||||||
GL.glDrawElements(GL20.GL_TRIANGLES, el.numIndices[1],
|
GL.glDrawElements(GL20.GL_TRIANGLES,
|
||||||
GL20.GL_UNSIGNED_SHORT, el.numIndices[0] * 2);
|
el.numIndices[1],
|
||||||
|
GL20.GL_UNSIGNED_SHORT,
|
||||||
|
el.numIndices[0] * 2);
|
||||||
|
|
||||||
if (drawAlpha) {
|
if (mTranslucent) {
|
||||||
/* drawing gl_lines with the same coordinates does not
|
/* drawing gl_lines with the same coordinates does not
|
||||||
* result in same depth values as polygons, so add
|
* result in same depth values as polygons, so add
|
||||||
* offset and draw gl_lequal: */
|
* offset and draw gl_lequal: */
|
||||||
GL.glDepthFunc(GL20.GL_LEQUAL);
|
GL.glDepthFunc(GL20.GL_LEQUAL);
|
||||||
}
|
|
||||||
|
|
||||||
v.mvp.addDepthOffset(100);
|
v.mvp.addDepthOffset(100);
|
||||||
v.mvp.setAsUniform(s.uMVP);
|
v.mvp.setAsUniform(s.uMVP);
|
||||||
|
}
|
||||||
|
|
||||||
GL.glUniform1i(s.uMode, 3);
|
GL.glUniform1i(s.uMode, 3);
|
||||||
|
int offset = 2 * (el.indexOffset
|
||||||
int offset = 2 * (indexOffset
|
|
||||||
+ el.numIndices[0]
|
+ el.numIndices[0]
|
||||||
+ el.numIndices[1]
|
+ el.numIndices[1]
|
||||||
+ el.numIndices[2]);
|
+ el.numIndices[2]);
|
||||||
|
|
||||||
GL.glDrawElements(GL20.GL_LINES, el.numIndices[3],
|
GL.glDrawElements(GL20.GL_LINES,
|
||||||
GL20.GL_UNSIGNED_SHORT, offset);
|
el.numIndices[3],
|
||||||
|
GL20.GL_UNSIGNED_SHORT,
|
||||||
|
offset);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* draw triangle meshes */
|
/* draw triangle meshes */
|
||||||
if (el.numIndices[4] > 0) {
|
if (el.numIndices[4] > 0) {
|
||||||
int offset = 2 * (indexOffset
|
int offset = 2 * (el.indexOffset
|
||||||
+ el.numIndices[0]
|
+ el.numIndices[0]
|
||||||
+ el.numIndices[1]
|
+ el.numIndices[1]
|
||||||
+ el.numIndices[2]
|
+ el.numIndices[2]
|
||||||
+ el.numIndices[3]);
|
+ el.numIndices[3]);
|
||||||
|
|
||||||
GL.glUniform1i(s.uMode, 4);
|
GL.glDrawElements(GL20.GL_TRIANGLES,
|
||||||
GL.glDrawElements(GL20.GL_TRIANGLES, el.numIndices[4],
|
el.numIndices[4],
|
||||||
GL20.GL_UNSIGNED_SHORT, offset);
|
GL20.GL_UNSIGNED_SHORT,
|
||||||
|
offset);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -263,56 +237,31 @@ public abstract class ExtrusionRenderer extends LayerRenderer {
|
|||||||
els[i] = null;
|
els[i] = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!mTranslucent)
|
||||||
GL.glDepthMask(false);
|
GL.glDepthMask(false);
|
||||||
|
|
||||||
|
if (v.pos.zoomLevel < 18)
|
||||||
GL.glDisable(GL20.GL_CULL_FACE);
|
GL.glDisable(GL20.GL_CULL_FACE);
|
||||||
|
|
||||||
GL.glBindBuffer(GL20.GL_ELEMENT_ARRAY_BUFFER, 0);
|
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;
|
int z = l.zoomLevel;
|
||||||
double curScale = Tile.SIZE * v.pos.scale;
|
double curScale = Tile.SIZE * v.pos.scale;
|
||||||
float scale = (float) (v.pos.scale / (1 << z));
|
float scale = (float) (v.pos.scale / (1 << z));
|
||||||
|
|
||||||
float x = (float) ((l.x - v.pos.x) * curScale);
|
float x = (float) ((l.x - v.pos.x) * curScale);
|
||||||
float y = (float) ((l.y - v.pos.y) * curScale);
|
float y = (float) ((l.y - v.pos.y) * curScale);
|
||||||
|
|
||||||
v.mvp.setTransScale(x, y, scale / MapRenderer.COORD_SCALE);
|
v.mvp.setTransScale(x, y, scale / MapRenderer.COORD_SCALE);
|
||||||
|
|
||||||
// scale height ???
|
|
||||||
v.mvp.setValue(10, scale / 10);
|
v.mvp.setValue(10, scale / 10);
|
||||||
|
|
||||||
v.mvp.multiplyLhs(v.viewproj);
|
v.mvp.multiplyLhs(v.viewproj);
|
||||||
|
|
||||||
|
if (offset) {
|
||||||
|
int delta = (int) (l.x * (1 << z)) % 4 + (int) (l.y * (1 << z)) % 4 * 4;
|
||||||
v.mvp.addDepthOffset(delta);
|
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