start of MeshLayer for 2D Meshes w/ tessellation
This commit is contained in:
parent
836f6a60e0
commit
c519a4f34b
@ -32,9 +32,13 @@ public class ElementLayers {
|
||||
PolygonLayer.Renderer.init();
|
||||
TextureLayer.Renderer.init();
|
||||
BitmapLayer.Renderer.init();
|
||||
MeshLayer.Renderer.init();
|
||||
|
||||
TextureItem.init(gl, 0);
|
||||
}
|
||||
|
||||
// FIXME use one ArrayList for these!
|
||||
|
||||
// mixed Polygon- and LineLayer
|
||||
public RenderElement baseLayers;
|
||||
// Text- and SymbolLayer
|
||||
@ -87,6 +91,14 @@ public class ElementLayers {
|
||||
return (LineLayer) getLayer(level, RenderElement.LINE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get or add the MeshLayer for a level. Levels are ordered from
|
||||
* bottom (0) to top
|
||||
*/
|
||||
public MeshLayer getMeshLayer(int level) {
|
||||
return (MeshLayer) getLayer(level, RenderElement.MESH);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get or add the PolygonLayer for a level. Levels are ordered from
|
||||
* bottom (0) to top
|
||||
@ -115,6 +127,12 @@ public class ElementLayers {
|
||||
RenderElement l = baseLayers;
|
||||
RenderElement renderElement = null;
|
||||
|
||||
if (!(type == RenderElement.LINE
|
||||
|| type == RenderElement.POLYGON
|
||||
|| type == RenderElement.TEXLINE
|
||||
|| type == RenderElement.MESH))
|
||||
throw new IllegalArgumentException("invalid layer type");
|
||||
|
||||
if (mCurLayer != null && mCurLayer.level == level) {
|
||||
renderElement = mCurLayer;
|
||||
} else {
|
||||
@ -146,9 +164,8 @@ public class ElementLayers {
|
||||
renderElement = new PolygonLayer(level);
|
||||
else if (type == RenderElement.TEXLINE)
|
||||
renderElement = new LineTexLayer(level);
|
||||
else
|
||||
// TODO throw execption
|
||||
return null;
|
||||
else if (type == RenderElement.MESH)
|
||||
renderElement = new MeshLayer(level);
|
||||
|
||||
if (l == null) {
|
||||
// insert at start
|
||||
@ -177,6 +194,7 @@ public class ElementLayers {
|
||||
private final static int[] VERTEX_SHORT_CNT = {
|
||||
4, // LINE_VERTEX_SHORTS
|
||||
2, // POLY_VERTEX_SHORTS
|
||||
2, // MESH_VERTEX_SHORTS
|
||||
6, // TEXLINE_VERTEX_SHORTS
|
||||
};
|
||||
|
||||
@ -212,6 +230,7 @@ public class ElementLayers {
|
||||
size += addLayerItems(sbuf, baseLayers, RenderElement.LINE, 0);
|
||||
|
||||
texLineOffset = size * SHORT_BYTES;
|
||||
|
||||
for (RenderElement l = baseLayers; l != null; l = l.next) {
|
||||
if (l.type == RenderElement.TEXLINE) {
|
||||
addPoolItems(l, sbuf);
|
||||
@ -221,9 +240,14 @@ public class ElementLayers {
|
||||
}
|
||||
}
|
||||
|
||||
for (RenderElement l = baseLayers; l != null; l = l.next) {
|
||||
if (l.type == RenderElement.MESH)
|
||||
l.compile(sbuf);
|
||||
}
|
||||
|
||||
for (RenderElement l = textureLayers; l != null; l = l.next) {
|
||||
TextureLayer tl = (TextureLayer) l;
|
||||
tl.compile(sbuf);
|
||||
//TextureLayer tl = (TextureLayer) l;
|
||||
l.compile(sbuf);
|
||||
}
|
||||
|
||||
// extrusion layers are compiled by extrusion overlay
|
||||
|
||||
@ -15,91 +15,165 @@
|
||||
package org.oscim.renderer.elements;
|
||||
|
||||
import java.nio.ShortBuffer;
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.oscim.backend.GL20;
|
||||
import org.oscim.backend.Log;
|
||||
import org.oscim.backend.canvas.Color;
|
||||
import org.oscim.core.GeometryBuffer;
|
||||
import org.oscim.core.Tile;
|
||||
import org.oscim.core.MapPosition;
|
||||
import org.oscim.renderer.BufferObject;
|
||||
import org.oscim.renderer.GLState;
|
||||
import org.oscim.renderer.GLUtils;
|
||||
import org.oscim.renderer.MapRenderer;
|
||||
import org.oscim.renderer.MapRenderer.Matrices;
|
||||
import org.oscim.utils.Tessellator;
|
||||
import org.oscim.utils.pool.Inlist;
|
||||
|
||||
public class MeshLayer extends RenderElement {
|
||||
GeometryBuffer mGeom = new GeometryBuffer(10, 10);
|
||||
private static final String TAG = MeshLayer.class.getName();
|
||||
|
||||
public MeshLayer() {
|
||||
GeometryBuffer e = mGeom;
|
||||
BufferObject indicesVbo;
|
||||
int numIndices;
|
||||
|
||||
int size = Tile.SIZE;
|
||||
VertexItem indiceItems;
|
||||
|
||||
float x1 = -1;
|
||||
float y1 = -1;
|
||||
float x2 = size + 1;
|
||||
float y2 = size + 1;
|
||||
|
||||
// always clear geometry before starting
|
||||
// a different type.
|
||||
e.clear();
|
||||
e.startPolygon();
|
||||
e.addPoint(x1, y1);
|
||||
e.addPoint(x2, y1);
|
||||
e.addPoint(x2, y2);
|
||||
e.addPoint(x1, y2);
|
||||
|
||||
y1 = 5;
|
||||
y2 = size - 5;
|
||||
x1 = 5;
|
||||
x2 = size - 5;
|
||||
|
||||
e.startHole();
|
||||
e.addPoint(x1, y1);
|
||||
e.addPoint(x2, y1);
|
||||
e.addPoint(x2, y2);
|
||||
e.addPoint(x1, y2);
|
||||
|
||||
addMesh(e);
|
||||
public MeshLayer(int level) {
|
||||
super(RenderElement.MESH);
|
||||
this.level = level;
|
||||
}
|
||||
|
||||
public void addMesh(GeometryBuffer geom) {
|
||||
int numRings = 2;
|
||||
|
||||
long ctx = tessellate(geom.points, 0, geom.index, 0, numRings);
|
||||
|
||||
short[] coordinates = new short[100];
|
||||
|
||||
while (tessGetCoordinates(ctx, coordinates, 2) > 0) {
|
||||
Log.d("..", Arrays.toString(coordinates));
|
||||
if (vertexItems == null) {
|
||||
vertexItems = VertexItem.pool.get();
|
||||
indiceItems = VertexItem.pool.get();
|
||||
}
|
||||
|
||||
while (tessGetIndices(ctx, coordinates) > 0) {
|
||||
Log.d("..", Arrays.toString(coordinates));
|
||||
}
|
||||
numIndices += Tessellator.tessellate(geom, MapRenderer.COORD_SCALE,
|
||||
Inlist.last(vertexItems),
|
||||
Inlist.last(indiceItems),
|
||||
verticesCnt);
|
||||
|
||||
tessFinish(ctx);
|
||||
verticesCnt = vertexItems.getSize() / 2;
|
||||
|
||||
Log.d(TAG, "-> " + verticesCnt + " " + numIndices);
|
||||
|
||||
if (numIndices <= 0) {
|
||||
vertexItems.release();
|
||||
vertexItems = null;
|
||||
|
||||
indiceItems.release();
|
||||
indiceItems = null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void compile(ShortBuffer sbuf) {
|
||||
if (indiceItems == null) {
|
||||
|
||||
return;
|
||||
}
|
||||
Log.d(TAG, "compile");
|
||||
// add vertices to shared VBO
|
||||
ElementLayers.addPoolItems(this, sbuf);
|
||||
|
||||
int cnt = indiceItems.getSize();
|
||||
|
||||
Log.d(TAG, "check " + cnt + ":" + numIndices);
|
||||
|
||||
if (cnt != numIndices) {
|
||||
numIndices = cnt;
|
||||
}
|
||||
|
||||
// add indices to indicesVbo
|
||||
sbuf = MapRenderer.getShortBuffer(numIndices);
|
||||
|
||||
for (VertexItem it = indiceItems; it != null; it = it.next)
|
||||
sbuf.put(it.vertices, 0, it.used);
|
||||
|
||||
VertexItem.pool.releaseAll(indiceItems);
|
||||
indiceItems = null;
|
||||
|
||||
sbuf.flip();
|
||||
|
||||
indicesVbo = BufferObject.get(GL20.GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||
indicesVbo.loadBufferData(sbuf, sbuf.limit() * 2);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void clear() {
|
||||
BufferObject.release(indicesVbo);
|
||||
VertexItem.pool.releaseAll(indiceItems);
|
||||
VertexItem.pool.releaseAll(vertexItems);
|
||||
|
||||
indiceItems = null;
|
||||
vertexItems = null;
|
||||
indicesVbo = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param points an array of x,y coordinates
|
||||
* @param pos position in points array
|
||||
* @param index geom indices
|
||||
* @param ipos position in index array
|
||||
* @param numRings number of rings in polygon == outer(1) + inner rings
|
||||
* @return number of triangles in io buffer
|
||||
*/
|
||||
public static native int tessellate(float[] points, int pos,
|
||||
short[] index, int ipos, int numRings);
|
||||
public static class Renderer {
|
||||
private static int shaderProgram;
|
||||
private static int hMatrix;
|
||||
private static int hColor;
|
||||
private static int hVertexPosition;
|
||||
|
||||
public static native void tessFinish(long ctx);
|
||||
static boolean init() {
|
||||
shaderProgram = GLUtils.createProgram(vertexShader, fragmentShader);
|
||||
if (shaderProgram == 0)
|
||||
return false;
|
||||
|
||||
public static native int tessGetCoordinates(long ctx, short[] coordinates, float scale);
|
||||
hMatrix = GL.glGetUniformLocation(shaderProgram, "u_mvp");
|
||||
hColor = GL.glGetUniformLocation(shaderProgram, "u_color");
|
||||
hVertexPosition = GL.glGetAttribLocation(shaderProgram, "a_pos");
|
||||
return true;
|
||||
}
|
||||
|
||||
public static native int tessGetIndices(long ctx, short[] indices);
|
||||
public static RenderElement draw(MapPosition pos, RenderElement layer,
|
||||
Matrices m) {
|
||||
|
||||
GLState.blend(true);
|
||||
|
||||
RenderElement l = layer;
|
||||
|
||||
GLState.useProgram(shaderProgram);
|
||||
|
||||
GLState.enableVertexArrays(hVertexPosition, -1);
|
||||
|
||||
//m.viewproj.setAsUniform(hMatrix);
|
||||
//m.useScreenCoordinates(true, 1f);
|
||||
m.mvp.setAsUniform(hMatrix);
|
||||
|
||||
GLUtils.setColor(hColor, Color.BLUE, 0.4f);
|
||||
|
||||
for (; l != null && l.type == RenderElement.MESH; l = l.next) {
|
||||
MeshLayer ml = (MeshLayer) l;
|
||||
|
||||
ml.indicesVbo.bind();
|
||||
|
||||
GL.glVertexAttribPointer(hVertexPosition, 2, GL20.GL_SHORT,
|
||||
false, 0, ml.offset);
|
||||
|
||||
GL.glDrawElements(GL20.GL_TRIANGLES, ml.numIndices,
|
||||
GL20.GL_UNSIGNED_SHORT, 0);
|
||||
}
|
||||
|
||||
GL.glBindBuffer(GL20.GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||
|
||||
return l;
|
||||
}
|
||||
|
||||
private final static String vertexShader = ""
|
||||
+ "precision mediump float;"
|
||||
+ "uniform mat4 u_mvp;"
|
||||
+ "attribute vec4 a_pos;"
|
||||
+ "void main() {"
|
||||
+ " gl_Position = u_mvp * a_pos;"
|
||||
+ "}";
|
||||
|
||||
private final static String fragmentShader = ""
|
||||
+ "precision mediump float;"
|
||||
+ "uniform vec4 u_color;"
|
||||
+ "void main() {"
|
||||
+ " gl_FragColor = u_color;"
|
||||
+ "}";
|
||||
}
|
||||
}
|
||||
|
||||
@ -24,10 +24,11 @@ public abstract class RenderElement extends Inlist<RenderElement> {
|
||||
|
||||
public final static byte LINE = 0;
|
||||
public final static byte POLYGON = 1;
|
||||
public final static byte TEXLINE = 2;
|
||||
public final static byte SYMBOL = 3;
|
||||
public final static byte BITMAP = 4;
|
||||
public final static byte EXTRUSION = 5;
|
||||
public static final byte MESH = 2;
|
||||
public final static byte TEXLINE = 3;
|
||||
public final static byte SYMBOL = 4;
|
||||
public final static byte BITMAP = 5;
|
||||
public final static byte EXTRUSION = 6;
|
||||
|
||||
protected RenderElement(byte type) {
|
||||
this.type = type;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user