package org.oscim.test.renderer;
import static org.oscim.backend.GLAdapter.gl;
import java.nio.FloatBuffer;
import org.oscim.backend.GL;
import org.oscim.backend.canvas.Color;
import org.oscim.gdx.GdxMap;
import org.oscim.gdx.GdxMapApp;
import org.oscim.layers.GenericLayer;
import org.oscim.renderer.BucketRenderer;
import org.oscim.renderer.BufferObject;
import org.oscim.renderer.GLShader;
import org.oscim.renderer.GLState;
import org.oscim.renderer.GLUtils;
import org.oscim.renderer.GLViewport;
import org.oscim.renderer.MapRenderer;
import org.oscim.utils.FastMath;
public class HexagonRenderTest extends GdxMap {
@Override
protected void createLayers() {
mMap.setMapPosition(0, 0, 1 << 4);
mMap.layers().add(new GenericLayer(mMap, new HexagonRenderer()));
}
public static void main(String[] args) {
GdxMapApp.init();
GdxMapApp.run(new HexagonRenderTest(), null, 400);
}
/* This is an example how to integrate custom OpenGL drawing routines as map
* overlay
*
* based on chapter 2 from:
* https://github.com/dalinaum/opengl-es-book-samples/tree/master/Android */
static class HexagonRenderer extends BucketRenderer {
private int mProgramObject;
private int hVertexPosition;
private int hMatrixPosition;
private int hColorPosition;
private int hCenterPosition;
//private FloatBuffer mVertices;
private boolean mInitialized;
private BufferObject mVBO;
int mZoom = -1;
float mCellScale = 60 * MapRenderer.COORD_SCALE;
@Override
public void update(GLViewport v) {
if (!mInitialized) {
if (!init()) {
return;
}
mInitialized = true;
compile();
mMapPosition.copy(v.pos);
}
//if (mZoom != v.pos.zoomLevel) {
// mMapPosition.copy(v.pos);
// mZoom = v.pos.zoomLevel;
//}
}
@Override
protected void compile() {
float[] vertices = new float[12];
for (int i = 0; i < 6; i++) {
vertices[i * 2 + 0] = (float) Math.cos(Math.PI * 2 * i / 6) * mCellScale;
vertices[i * 2 + 1] = (float) Math.sin(Math.PI * 2 * i / 6) * mCellScale;
}
FloatBuffer buf = MapRenderer.getFloatBuffer(12);
buf.put(vertices);
mVBO = BufferObject.get(GL.ARRAY_BUFFER, 0);
mVBO.loadBufferData(buf.flip(), 12 * 4);
setReady(true);
}
@Override
public void render(GLViewport v) {
// Use the program object
GLState.useProgram(mProgramObject);
GLState.blend(true);
GLState.test(false, false);
// bind VBO data
mVBO.bind();
// set VBO vertex layout
gl.vertexAttribPointer(hVertexPosition, 2, GL.FLOAT, false, 0, 0);
GLState.enableVertexArrays(hVertexPosition, -1);
/* apply view and projection matrices */
// set mvp (tmp) matrix relative to mMapPosition
// i.e. fixed on the map
setMatrix(v);
v.mvp.setAsUniform(hMatrixPosition);
final int offset_x = 4;
final int offset_y = 16;
float h = (float) (Math.sqrt(3) / 2);
for (int y = -offset_y; y < offset_y; y++) {
for (int x = -offset_x; x < offset_x; x++) {
float xx = x * 2 + (y % 2 == 0 ? 1 : 0);
float yy = y * h + h / 2;
gl.uniform2f(hCenterPosition, xx * (mCellScale * 1.5f), yy * mCellScale);
//float alpha = 1 + (float) Math.log10(FastMath.clamp(
// (float) Math.sqrt(xx * xx + yy * yy) / offset_y, 0.0f, 1.0f)) * 2;
float alpha = (float) Math.sqrt(xx * xx + yy * yy) / offset_y;
float fy = (float) (y + offset_y) / (offset_y * 2);
float fx = (float) (x + offset_x) / (offset_x * 2);
float fz = FastMath.clamp(
(float) (x < 0 || y < 0 ? 1 - Math.sqrt(fx * fx + fy
* fy)
: 0),
0,
1);
int c = 0xff << 24
| (int) (0xff * fy) << 16
| (int) (0xff * fx) << 8
| (int) (0xff * fz);
GLUtils.setColor(hColorPosition, c, alpha);
gl.drawArrays(GL.TRIANGLE_FAN, 0, 6);
}
}
GLUtils.setColor(hColorPosition, Color.DKGRAY, 0.3f);
for (int y = -offset_y; y < offset_y; y++) {
for (int x = -offset_x; x < offset_x; x++) {
float xx = x * 2 + (y % 2 == 0 ? 1 : 0);
float yy = y * h + h / 2;
gl.uniform2f(hCenterPosition, xx * (mCellScale * 1.5f), yy * mCellScale);
gl.drawArrays(GL.LINE_LOOP, 0, 6);
}
}
GLUtils.checkGlError("...");
}
private boolean init() {
// Load the vertex/fragment shaders
int programObject = GLShader.createProgram(vShaderStr, fShaderStr);
if (programObject == 0)
return false;
// Handle for vertex position in shader
hVertexPosition = gl.getAttribLocation(programObject, "a_pos");
hMatrixPosition = gl.getUniformLocation(programObject, "u_mvp");
hColorPosition = gl.getUniformLocation(programObject, "u_color");
hCenterPosition = gl.getUniformLocation(programObject, "u_center");
// Store the program object
mProgramObject = programObject;
return true;
}
private final static String vShaderStr = ""
+ "#ifdef GLES\n"
+ "precision mediump float;\n"
+ "#endif\n"
+ "uniform mat4 u_mvp;"
+ "uniform vec2 u_center;"
+ "attribute vec2 a_pos;"
+ "void main()"
+ "{"
+ " gl_Position = u_mvp * vec4(u_center + a_pos, 0.0, 1.0);"
+ "}";
private final static String fShaderStr = ""
+ "#ifdef GLES\n"
+ "precision mediump float;\n"
+ "#endif\n"
+ "varying float alpha;"
+ "uniform vec4 u_color;"
+ "void main()"
+ "{"
+ " gl_FragColor = u_color;"
+ "}";
}
}