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();
|
PolygonLayer.Renderer.init();
|
||||||
TextureLayer.Renderer.init();
|
TextureLayer.Renderer.init();
|
||||||
BitmapLayer.Renderer.init();
|
BitmapLayer.Renderer.init();
|
||||||
|
MeshLayer.Renderer.init();
|
||||||
|
|
||||||
TextureItem.init(gl, 0);
|
TextureItem.init(gl, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FIXME use one ArrayList for these!
|
||||||
|
|
||||||
// mixed Polygon- and LineLayer
|
// mixed Polygon- and LineLayer
|
||||||
public RenderElement baseLayers;
|
public RenderElement baseLayers;
|
||||||
// Text- and SymbolLayer
|
// Text- and SymbolLayer
|
||||||
@ -87,6 +91,14 @@ public class ElementLayers {
|
|||||||
return (LineLayer) getLayer(level, RenderElement.LINE);
|
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
|
* Get or add the PolygonLayer for a level. Levels are ordered from
|
||||||
* bottom (0) to top
|
* bottom (0) to top
|
||||||
@ -115,6 +127,12 @@ public class ElementLayers {
|
|||||||
RenderElement l = baseLayers;
|
RenderElement l = baseLayers;
|
||||||
RenderElement renderElement = null;
|
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) {
|
if (mCurLayer != null && mCurLayer.level == level) {
|
||||||
renderElement = mCurLayer;
|
renderElement = mCurLayer;
|
||||||
} else {
|
} else {
|
||||||
@ -146,9 +164,8 @@ public class ElementLayers {
|
|||||||
renderElement = new PolygonLayer(level);
|
renderElement = new PolygonLayer(level);
|
||||||
else if (type == RenderElement.TEXLINE)
|
else if (type == RenderElement.TEXLINE)
|
||||||
renderElement = new LineTexLayer(level);
|
renderElement = new LineTexLayer(level);
|
||||||
else
|
else if (type == RenderElement.MESH)
|
||||||
// TODO throw execption
|
renderElement = new MeshLayer(level);
|
||||||
return null;
|
|
||||||
|
|
||||||
if (l == null) {
|
if (l == null) {
|
||||||
// insert at start
|
// insert at start
|
||||||
@ -177,6 +194,7 @@ public class ElementLayers {
|
|||||||
private final static int[] VERTEX_SHORT_CNT = {
|
private final static int[] VERTEX_SHORT_CNT = {
|
||||||
4, // LINE_VERTEX_SHORTS
|
4, // LINE_VERTEX_SHORTS
|
||||||
2, // POLY_VERTEX_SHORTS
|
2, // POLY_VERTEX_SHORTS
|
||||||
|
2, // MESH_VERTEX_SHORTS
|
||||||
6, // TEXLINE_VERTEX_SHORTS
|
6, // TEXLINE_VERTEX_SHORTS
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -212,6 +230,7 @@ public class ElementLayers {
|
|||||||
size += addLayerItems(sbuf, baseLayers, RenderElement.LINE, 0);
|
size += addLayerItems(sbuf, baseLayers, RenderElement.LINE, 0);
|
||||||
|
|
||||||
texLineOffset = size * SHORT_BYTES;
|
texLineOffset = size * SHORT_BYTES;
|
||||||
|
|
||||||
for (RenderElement l = baseLayers; l != null; l = l.next) {
|
for (RenderElement l = baseLayers; l != null; l = l.next) {
|
||||||
if (l.type == RenderElement.TEXLINE) {
|
if (l.type == RenderElement.TEXLINE) {
|
||||||
addPoolItems(l, sbuf);
|
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) {
|
for (RenderElement l = textureLayers; l != null; l = l.next) {
|
||||||
TextureLayer tl = (TextureLayer) l;
|
//TextureLayer tl = (TextureLayer) l;
|
||||||
tl.compile(sbuf);
|
l.compile(sbuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
// extrusion layers are compiled by extrusion overlay
|
// extrusion layers are compiled by extrusion overlay
|
||||||
|
|||||||
@ -15,91 +15,165 @@
|
|||||||
package org.oscim.renderer.elements;
|
package org.oscim.renderer.elements;
|
||||||
|
|
||||||
import java.nio.ShortBuffer;
|
import java.nio.ShortBuffer;
|
||||||
import java.util.Arrays;
|
|
||||||
|
|
||||||
|
import org.oscim.backend.GL20;
|
||||||
import org.oscim.backend.Log;
|
import org.oscim.backend.Log;
|
||||||
|
import org.oscim.backend.canvas.Color;
|
||||||
import org.oscim.core.GeometryBuffer;
|
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 {
|
public class MeshLayer extends RenderElement {
|
||||||
GeometryBuffer mGeom = new GeometryBuffer(10, 10);
|
private static final String TAG = MeshLayer.class.getName();
|
||||||
|
|
||||||
public MeshLayer() {
|
BufferObject indicesVbo;
|
||||||
GeometryBuffer e = mGeom;
|
int numIndices;
|
||||||
|
|
||||||
int size = Tile.SIZE;
|
VertexItem indiceItems;
|
||||||
|
|
||||||
float x1 = -1;
|
public MeshLayer(int level) {
|
||||||
float y1 = -1;
|
super(RenderElement.MESH);
|
||||||
float x2 = size + 1;
|
this.level = level;
|
||||||
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 void addMesh(GeometryBuffer geom) {
|
public void addMesh(GeometryBuffer geom) {
|
||||||
int numRings = 2;
|
if (vertexItems == null) {
|
||||||
|
vertexItems = VertexItem.pool.get();
|
||||||
long ctx = tessellate(geom.points, 0, geom.index, 0, numRings);
|
indiceItems = VertexItem.pool.get();
|
||||||
|
|
||||||
short[] coordinates = new short[100];
|
|
||||||
|
|
||||||
while (tessGetCoordinates(ctx, coordinates, 2) > 0) {
|
|
||||||
Log.d("..", Arrays.toString(coordinates));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
while (tessGetIndices(ctx, coordinates) > 0) {
|
numIndices += Tessellator.tessellate(geom, MapRenderer.COORD_SCALE,
|
||||||
Log.d("..", Arrays.toString(coordinates));
|
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
|
@Override
|
||||||
protected void compile(ShortBuffer sbuf) {
|
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
|
@Override
|
||||||
protected void clear() {
|
protected void clear() {
|
||||||
|
BufferObject.release(indicesVbo);
|
||||||
|
VertexItem.pool.releaseAll(indiceItems);
|
||||||
|
VertexItem.pool.releaseAll(vertexItems);
|
||||||
|
|
||||||
|
indiceItems = null;
|
||||||
|
vertexItems = null;
|
||||||
|
indicesVbo = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public static class Renderer {
|
||||||
* @param points an array of x,y coordinates
|
private static int shaderProgram;
|
||||||
* @param pos position in points array
|
private static int hMatrix;
|
||||||
* @param index geom indices
|
private static int hColor;
|
||||||
* @param ipos position in index array
|
private static int hVertexPosition;
|
||||||
* @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 native void tessFinish(long ctx);
|
static boolean init() {
|
||||||
|
shaderProgram = GLUtils.createProgram(vertexShader, fragmentShader);
|
||||||
public static native int tessGetCoordinates(long ctx, short[] coordinates, float scale);
|
if (shaderProgram == 0)
|
||||||
|
return false;
|
||||||
public static native int tessGetIndices(long ctx, short[] indices);
|
|
||||||
|
|
||||||
|
hMatrix = GL.glGetUniformLocation(shaderProgram, "u_mvp");
|
||||||
|
hColor = GL.glGetUniformLocation(shaderProgram, "u_color");
|
||||||
|
hVertexPosition = GL.glGetAttribLocation(shaderProgram, "a_pos");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
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 LINE = 0;
|
||||||
public final static byte POLYGON = 1;
|
public final static byte POLYGON = 1;
|
||||||
public final static byte TEXLINE = 2;
|
public static final byte MESH = 2;
|
||||||
public final static byte SYMBOL = 3;
|
public final static byte TEXLINE = 3;
|
||||||
public final static byte BITMAP = 4;
|
public final static byte SYMBOL = 4;
|
||||||
public final static byte EXTRUSION = 5;
|
public final static byte BITMAP = 5;
|
||||||
|
public final static byte EXTRUSION = 6;
|
||||||
|
|
||||||
protected RenderElement(byte type) {
|
protected RenderElement(byte type) {
|
||||||
this.type = type;
|
this.type = type;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user