beginning of texture pattern shader for tile polygons

This commit is contained in:
Hannes Janetzek 2013-06-15 16:53:45 +02:00
parent 2933ca7b57
commit dae42f0c97
2 changed files with 132 additions and 74 deletions

View File

@ -108,6 +108,8 @@ public final class LineRenderer {
public static Layer draw(Layers layers, Layer curLayer, MapPosition pos, public static Layer draw(Layers layers, Layer curLayer, MapPosition pos,
Matrices m, float div, int mode) { Matrices m, float div, int mode) {
beginLines();
if (curLayer == null) if (curLayer == null)
return null; return null;

View File

@ -31,22 +31,26 @@ import static android.opengl.GLES20.glStencilOp;
import static android.opengl.GLES20.glUniform4fv; import static android.opengl.GLES20.glUniform4fv;
import static android.opengl.GLES20.glVertexAttribPointer; import static android.opengl.GLES20.glVertexAttribPointer;
import java.io.IOException;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.nio.ByteOrder; import java.nio.ByteOrder;
import java.nio.FloatBuffer; import java.nio.FloatBuffer;
import org.oscim.core.MapPosition; import org.oscim.core.MapPosition;
import org.oscim.renderer.GLRenderer; import org.oscim.renderer.GLRenderer;
import org.oscim.renderer.GLState;
import org.oscim.renderer.GLRenderer.Matrices; import org.oscim.renderer.GLRenderer.Matrices;
import org.oscim.renderer.GLState;
import org.oscim.theme.renderinstruction.Area; import org.oscim.theme.renderinstruction.Area;
import org.oscim.theme.renderinstruction.BitmapUtils;
import org.oscim.utils.GlUtils; import org.oscim.utils.GlUtils;
import org.oscim.utils.Matrix4; import org.oscim.utils.Matrix4;
import android.graphics.Bitmap;
import android.opengl.GLES20; import android.opengl.GLES20;
import android.opengl.GLUtils;
public final class PolygonRenderer { public final class PolygonRenderer {
//private static final String TAG = PolygonRenderer.class.getName(); private static final String TAG = PolygonRenderer.class.getName();
private static final int POLYGON_VERTICES_DATA_POS_OFFSET = 0; private static final int POLYGON_VERTICES_DATA_POS_OFFSET = 0;
private static final int STENCIL_BITS = 8; private static final int STENCIL_BITS = 8;
@ -56,45 +60,97 @@ public final class PolygonRenderer {
private static PolygonLayer[] mFillPolys; private static PolygonLayer[] mFillPolys;
private static int polygonProgram; private static int numShaders = 2;
private static int hPolygonVertexPosition; private static int polyShader = 0;
private static int hPolygonMatrix; private static int texShader = 1;
private static int hPolygonColor;
private static int[] polygonProgram = new int[numShaders];
private static int[] hPolygonVertexPosition = new int[numShaders];
private static int[] hPolygonMatrix = new int[numShaders];
private static int[] hPolygonColor = new int[numShaders];
private static int mTexWater;
private static int mTexWood;
private static int mTexGrass;
static boolean init() { static boolean init() {
for (int i = 0; i < numShaders; i++) {
// Set up the program for rendering polygons // Set up the program for rendering polygons
if (GLRenderer.debugView) { if (i == 0) {
polygonProgram = GlUtils.createProgram(polygonVertexShaderZ, if (GLRenderer.debugView)
polygonProgram[i] = GlUtils.createProgram(polygonVertexShaderZ,
polygonFragmentShaderZ); polygonFragmentShaderZ);
} else { else
polygonProgram = GlUtils.createProgram(polygonVertexShader, polygonProgram[i] = GlUtils.createProgram(polygonVertexShader,
polygonFragmentShader); polygonFragmentShader);
} else if (i == 1) {
polygonProgram[i] = GlUtils.createProgram(textureVertexShader,
textureFragmentShader);
} }
if (polygonProgram == 0) {
if (polygonProgram[i] == 0) {
// Log.e(TAG, "Could not create polygon program."); // Log.e(TAG, "Could not create polygon program.");
return false; return false;
} }
hPolygonMatrix = glGetUniformLocation(polygonProgram, "u_mvp"); hPolygonMatrix[i] = glGetUniformLocation(polygonProgram[i], "u_mvp");
hPolygonColor = glGetUniformLocation(polygonProgram, "u_color"); hPolygonColor[i] = glGetUniformLocation(polygonProgram[i], "u_color");
hPolygonVertexPosition = glGetAttribLocation(polygonProgram, "a_pos"); hPolygonVertexPosition[i] = glGetAttribLocation(polygonProgram[i], "a_pos");
}
mFillPolys = new PolygonLayer[STENCIL_BITS]; mFillPolys = new PolygonLayer[STENCIL_BITS];
//mTexWood = loadSprite("jar:grass3.png");
//mTexWater = loadSprite("jar:water2.png");
//mTexGrass= loadSprite("jar:grass2.png");
return true; return true;
} }
private static void fillPolygons(int start, int end, int zoom, float scale) { private static int loadSprite(String name) {
int[] textures = new int[1];
try {
Bitmap b = BitmapUtils.createBitmap(name);
GLES20.glGenTextures(1, textures, 0);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textures[0]);
GlUtils.setTextureParameter(GLES20.GL_LINEAR, GLES20.GL_LINEAR,
GLES20.GL_REPEAT, GLES20.GL_REPEAT);
GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, b, 0);
} catch (IOException e) {
e.printStackTrace();
}
return textures[0];
}
private static void fillPolygons(Matrices m, int start, int end, int zoom, float scale) {
/* draw to framebuffer */ /* draw to framebuffer */
glColorMask(true, true, true, true); glColorMask(true, true, true, true);
/* do not modify stencil buffer */ /* do not modify stencil buffer */
glStencilMask(0x00); glStencilMask(0x00);
int shader = polyShader;
for (int c = start; c < end; c++) { for (int c = start; c < end; c++) {
Area a = mFillPolys[c].area; Area a = mFillPolys[c].area;
//if (a.color == 0xFFAFC5E3 || a.color == 0xffd1dbc7 || a.color == 0xffa3ca7b) {
// shader = texShader;
// setShader(texShader, m);
// if (a.color == 0xFFAFC5E3)
// GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTexWater);
// else if (a.color == 0xffd1dbc7)
// GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTexWood);
// else
// GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTexGrass);
//} else
if (a.fade >= zoom) { if (a.fade >= zoom) {
float f = 1.0f; float f = 1.0f;
/* fade in/out */ /* fade in/out */
@ -106,17 +162,17 @@ public final class PolygonRenderer {
} }
GLState.blend(true); GLState.blend(true);
GlUtils.setColor(hPolygonColor, a.color, f); GlUtils.setColor(hPolygonColor[shader], a.color, f);
} else if (a.blend > 0 && a.blend <= zoom) { } else if (a.blend > 0 && a.blend <= zoom) {
/* blend colors (not alpha) */ /* blend colors (not alpha) */
GLState.blend(false); GLState.blend(false);
if (a.blend == zoom) if (a.blend == zoom)
GlUtils.setColorBlend(hPolygonColor, GlUtils.setColorBlend(hPolygonColor[shader],
a.color, a.blendColor, scale - 1.0f); a.color, a.blendColor, scale - 1.0f);
else else
GlUtils.setColor(hPolygonColor, a.blendColor, 1); GlUtils.setColor(hPolygonColor[shader], a.blendColor, 1);
} else { } else {
if (a.color < 0xff000000) if (a.color < 0xff000000)
@ -124,7 +180,7 @@ public final class PolygonRenderer {
else else
GLState.blend(false); GLState.blend(false);
GlUtils.setColor(hPolygonColor, a.color, 1); GlUtils.setColor(hPolygonColor[shader], a.color, 1);
} }
// set stencil buffer mask used to draw this layer // set stencil buffer mask used to draw this layer
@ -134,12 +190,31 @@ public final class PolygonRenderer {
/* draw tile fill coordinates */ /* draw tile fill coordinates */
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
if (shader != polyShader) {
setShader(polyShader, m);
shader = polyShader;
}
} }
} }
// current layer to fill (0 - STENCIL_BITS-1) // current layer to fill (0 - STENCIL_BITS-1)
private static int mCount; private static int mCount;
private static void setShader(int shader, Matrices m) {
//if (
GLState.useProgram(polygonProgram[shader]);
// ) {
GLState.enableVertexArrays(hPolygonVertexPosition[shader], -1);
glVertexAttribPointer(hPolygonVertexPosition[shader], 2, GL_SHORT,
false, 0, POLYGON_VERTICES_DATA_POS_OFFSET);
m.mvp.setAsUniform(hPolygonMatrix[shader]);
//}
}
/** /**
* draw polygon layers (unil layer.next is not polygon layer) * draw polygon layers (unil layer.next is not polygon layer)
* using stencil buffer method * using stencil buffer method
@ -163,12 +238,7 @@ public final class PolygonRenderer {
GLState.test(false, true); GLState.test(false, true);
GLState.useProgram(polygonProgram); setShader(polyShader, m);
GLState.enableVertexArrays(hPolygonVertexPosition, -1);
glVertexAttribPointer(hPolygonVertexPosition, 2, GL_SHORT,
false, 0, POLYGON_VERTICES_DATA_POS_OFFSET);
m.mvp.setAsUniform(hPolygonMatrix);
int zoom = pos.zoomLevel; int zoom = pos.zoomLevel;
int cur = mCount; int cur = mCount;
@ -179,7 +249,7 @@ public final class PolygonRenderer {
int start = cur; int start = cur;
float scale = (float)pos.getZoomScale(); float scale = (float) pos.getZoomScale();
Layer l = layer; Layer l = layer;
for (; l != null && l.type == Layer.POLYGON; l = l.next) { for (; l != null && l.type == Layer.POLYGON; l = l.next) {
@ -206,13 +276,13 @@ public final class PolygonRenderer {
// draw up to 7 layers into stencil buffer // draw up to 7 layers into stencil buffer
if (cur == STENCIL_BITS - 1) { if (cur == STENCIL_BITS - 1) {
fillPolygons(start, cur, zoom, scale); fillPolygons(m, start, cur, zoom, scale);
start = cur = 0; start = cur = 0;
} }
} }
if (cur > 0) if (cur > 0)
fillPolygons(start, cur, zoom, scale); fillPolygons(m, start, cur, zoom, scale);
if (clip) { if (clip) {
if (first) { if (first) {
@ -297,15 +367,7 @@ public final class PolygonRenderer {
} }
public static void drawOver(Matrices m, boolean drawColor, int color) { public static void drawOver(Matrices m, boolean drawColor, int color) {
if (GLState.useProgram(polygonProgram)) { setShader(polyShader, m);
GLState.enableVertexArrays(hPolygonVertexPosition, -1);
glVertexAttribPointer(hPolygonVertexPosition, 2, GL_SHORT,
false, 0, POLYGON_VERTICES_DATA_POS_OFFSET);
m.mvp.setAsUniform(hPolygonMatrix);
}
/* /*
* clear stencilbuffer (tile region) by drawing * clear stencilbuffer (tile region) by drawing
@ -313,7 +375,7 @@ public final class PolygonRenderer {
*/ */
if (drawColor) { if (drawColor) {
GlUtils.setColor(hPolygonColor, color, 1); GlUtils.setColor(hPolygonColor[0], color, 1);
GLState.blend(true); GLState.blend(true);
} else { } else {
// disable drawing to framebuffer (will be re-enabled in fill) // disable drawing to framebuffer (will be re-enabled in fill)
@ -349,18 +411,18 @@ public final class PolygonRenderer {
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0); GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0);
mDebugFill.position(0); mDebugFill.position(0);
GLState.useProgram(polygonProgram); GLState.useProgram(polygonProgram[0]);
GLES20.glEnableVertexAttribArray(hPolygonVertexPosition); GLES20.glEnableVertexAttribArray(hPolygonVertexPosition[0]);
glVertexAttribPointer(hPolygonVertexPosition, 2, GLES20.GL_FLOAT, glVertexAttribPointer(hPolygonVertexPosition[0], 2, GLES20.GL_FLOAT,
false, 0, mDebugFill); false, 0, mDebugFill);
m.setAsUniform(hPolygonMatrix); m.setAsUniform(hPolygonMatrix[0]);
if (color == 0) if (color == 0)
glUniform4fv(hPolygonColor, 1, debugFillColor, 0); glUniform4fv(hPolygonColor[0], 1, debugFillColor, 0);
else else
glUniform4fv(hPolygonColor, 1, debugFillColor2, 0); glUniform4fv(hPolygonColor[0], 1, debugFillColor2, 0);
glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4); glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4);
@ -406,28 +468,22 @@ public final class PolygonRenderer {
+ " gl_FragColor = vec4(0.0, z - 1.0, 0.0, 1.0)*0.8;" + " gl_FragColor = vec4(0.0, z - 1.0, 0.0, 1.0)*0.8;"
+ "}"; + "}";
// private final static String polygonTexVertexShader = "" private final static String textureVertexShader = ""
// + "precision mediump float;" + "precision mediump float;"
// + "uniform mat4 u_mvp;" + "uniform mat4 u_mvp;"
// + "attribute vec4 a_pos;" + "attribute vec4 a_pos;"
// + "varying vec2 v_st;" + "varying vec2 v_st;"
// + "void main() {" + "void main() {"
// + " if(gl_VertexID == 0)" + " v_st = clamp(a_pos.xy, 0.0, 1.0) * 2.0;"
// + " v_st = vec2(0.0,0.0);" + " gl_Position = u_mvp * a_pos;"
// + " else if(gl_VertexID == 1)" + "}";
// + " v_st = vec2(1.0,0.0);"
// + " else if(gl_VertexID == 2)" private final static String textureFragmentShader = ""
// + " v_st = vec2(1.0,1.0);" + "precision mediump float;"
// + " else if(gl_VertexID == 3)" + "uniform vec4 u_color;"
// + " v_st = vec2(0.0,1.0);" + "uniform sampler2D tex;"
// + " gl_Position = u_mvp * a_pos;" + "varying vec2 v_st;"
// + "}"; + "void main() {"
// private final static String polygonTexFragmentShader = "" + " gl_FragColor = texture2D(tex, v_st);"
// + "precision mediump float;" + "}";
// + "uniform vec4 u_color;"
// + "uniform sampler2D tex;"
// + "varying vec2 v_st;"
// + "void main() {"
// + " gl_FragColor = u_color * texture2D(tex, v_st);"
// + "}";
} }