Merge branch 'extract_shaders'
This commit is contained in:
commit
ff56d5c67a
1
.gitignore
vendored
1
.gitignore
vendored
@ -16,6 +16,7 @@ build/
|
||||
/vtm-android-example/assets/
|
||||
/vtm-gdx-desktop/assets/
|
||||
/vtm-gdx-html/war/
|
||||
/vtm-gdx-html/assets/
|
||||
/vtm-gdx-html/gwt-unitCache
|
||||
/vtm-spatialite/
|
||||
/vtm-spatialite-android/
|
||||
|
@ -43,6 +43,11 @@ gwt {
|
||||
superDev {
|
||||
noPrecompile=true
|
||||
}
|
||||
compiler {
|
||||
enableClosureCompiler = false; // activates -XenableClosureCompiler
|
||||
disableClassMetadata = true; // activates -XdisableClassMetadata
|
||||
disableCastChecking = true; // activates -XdisableCastChecking
|
||||
}
|
||||
|
||||
src += files(sourceSets.main.java.srcDirs)
|
||||
src += files(project(':vtm').sourceSets.main.allJava.srcDirs)
|
||||
@ -58,6 +63,23 @@ task jettyDraftWar(type: JettyRunWar) {
|
||||
webApp=draftWar.archivePath
|
||||
}
|
||||
|
||||
task copyThemeAssets(type: Copy) {
|
||||
from "$rootDir/vtm-themes/resources/assets"
|
||||
into "assets"
|
||||
include '**/*'
|
||||
}
|
||||
|
||||
task copyVtmAssets(type: Copy) {
|
||||
from "$rootDir/vtm/resources/assets"
|
||||
into "assets"
|
||||
include '**/*'
|
||||
}
|
||||
|
||||
tasks.withType(JavaCompile) { compileTask ->
|
||||
compileTask.dependsOn copyThemeAssets
|
||||
compileTask.dependsOn copyVtmAssets
|
||||
}
|
||||
|
||||
// Configuring Eclipse classpath
|
||||
eclipse.classpath {
|
||||
|
||||
|
@ -21,7 +21,7 @@
|
||||
|
||||
<super-source path="emu" />
|
||||
|
||||
<set-configuration-property name="gdx.assetpath" value="../vtm-themes/resources/assets" />
|
||||
<set-configuration-property name="gdx.assetpath" value="./assets" />
|
||||
<!-- for gradle build, commend out for eclipse build/devmode -->
|
||||
<set-configuration-property name="gdx.assetoutputpath" value="build/gwt/draftOut" />
|
||||
|
||||
|
@ -16,6 +16,8 @@
|
||||
*/
|
||||
package org.oscim.gdx.client;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
import org.oscim.backend.CanvasAdapter;
|
||||
import org.oscim.backend.GL20;
|
||||
import org.oscim.backend.GLAdapter;
|
||||
@ -23,9 +25,14 @@ import org.oscim.core.MapPosition;
|
||||
import org.oscim.core.MercatorProjection;
|
||||
import org.oscim.gdx.GdxMap;
|
||||
import org.oscim.layers.tile.bitmap.BitmapTileLayer;
|
||||
import org.oscim.layers.tile.vector.VectorTileLayer;
|
||||
import org.oscim.layers.tile.vector.labeling.LabelLayer;
|
||||
import org.oscim.renderer.MapRenderer;
|
||||
import org.oscim.theme.VtmThemes;
|
||||
import org.oscim.tiling.TileSource;
|
||||
import org.oscim.tiling.source.bitmap.DefaultSources.NaturalEarth;
|
||||
import org.oscim.tiling.source.bitmap.BitmapTileSource;
|
||||
import org.oscim.tiling.source.bitmap.DefaultSources;
|
||||
import org.oscim.tiling.source.bitmap.DefaultSources.StamenToner;
|
||||
import org.oscim.tiling.source.oscimap4.OSciMap4TileSource;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
@ -66,14 +73,20 @@ class GwtGdxMap extends GdxMap {
|
||||
|
||||
float tilt = 0;
|
||||
float rotation = 0;
|
||||
String themeName = null;
|
||||
String mapName = null;
|
||||
|
||||
final HashMap<String, String> params = new HashMap<String, String>();
|
||||
String addOpts = "";
|
||||
if (Window.Location.getHash() != null) {
|
||||
String hash = Window.Location.getHash();
|
||||
|
||||
hash = hash.substring(1);
|
||||
String[] pairs = hash.split(",");
|
||||
String[] urlParams = null;
|
||||
urlParams = hash.split("&");
|
||||
if (urlParams.length == 1)
|
||||
urlParams = hash.split(",");
|
||||
|
||||
for (String p : pairs) {
|
||||
for (String p : urlParams) {
|
||||
try {
|
||||
if (p.startsWith("lat="))
|
||||
lat = Double.parseDouble(p.substring(4));
|
||||
@ -85,33 +98,82 @@ class GwtGdxMap extends GdxMap {
|
||||
rotation = Float.parseFloat(p.substring(4));
|
||||
else if (p.startsWith("tilt="))
|
||||
tilt = Float.parseFloat(p.substring(5));
|
||||
else if (p.startsWith("theme="))
|
||||
themeName = p.substring(6);
|
||||
else if (p.startsWith("map="))
|
||||
mapName = p.substring(4);
|
||||
else {
|
||||
String[] opt = p.split("=");
|
||||
if (opt.length > 1)
|
||||
params.put(opt[0], opt[1]);
|
||||
else
|
||||
params.put(opt[0], null);
|
||||
|
||||
addOpts += p + "&";
|
||||
|
||||
}
|
||||
} catch (NumberFormatException e) {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
final String addParam =
|
||||
(themeName == null ? "" : ("theme=" + themeName + "&"))
|
||||
+ (mapName == null ? "" : ("map=" + mapName + "&"))
|
||||
+ addOpts;
|
||||
|
||||
MapPosition p = new MapPosition();
|
||||
p.setZoomLevel(zoom);
|
||||
p.setPosition(lat, lon);
|
||||
log.debug("map position: " + p.x + "/" + p.y + " " + lat + "/" + lon);
|
||||
|
||||
p.bearing = rotation;
|
||||
p.tilt = tilt;
|
||||
|
||||
mMap.setMapPosition(p);
|
||||
|
||||
//mMap.getViewport().setTilt(tilt);
|
||||
//mMap.getViewport().setRotation(rotation);
|
||||
VectorTileLayer l = null;
|
||||
|
||||
if (c.getBackgroundLayer() != null || mapName != null) {
|
||||
BitmapTileSource ts;
|
||||
|
||||
if ("toner".equals(mapName))
|
||||
ts = new StamenToner();
|
||||
else if ("osm".equals(mapName))
|
||||
ts = new DefaultSources.OpenStreetMap();
|
||||
else if ("watercolor".equals(mapName))
|
||||
ts = new DefaultSources.StamenWatercolor();
|
||||
else if ("arcgis-shaded".equals(mapName))
|
||||
ts = new DefaultSources.ArcGISWorldShaded();
|
||||
else if ("imagico".equals(mapName))
|
||||
ts = new DefaultSources.ImagicoLandcover();
|
||||
else
|
||||
ts = new StamenToner();
|
||||
|
||||
mMap.setBackgroundMap(new BitmapTileLayer(mMap, ts));
|
||||
} else {
|
||||
String url = c.getTileUrl();
|
||||
String sourceName = c.getTileSource();
|
||||
|
||||
TileSource tileSource;
|
||||
tileSource = new OSciMap4TileSource(url);
|
||||
TileSource ts = new OSciMap4TileSource(url);
|
||||
l = mMap.setBaseMap(ts);
|
||||
|
||||
initDefaultLayers(tileSource, false, true, true);
|
||||
if (themeName == null) {
|
||||
mMap.setTheme(VtmThemes.DEFAULT);
|
||||
} else {
|
||||
if ("osmarender".equals(themeName))
|
||||
mMap.setTheme(VtmThemes.OSMARENDER);
|
||||
else if ("tron".equals(themeName))
|
||||
mMap.setTheme(VtmThemes.TRONRENDER);
|
||||
else if ("newtron".equals(themeName))
|
||||
mMap.setTheme(VtmThemes.NEWTRON);
|
||||
else
|
||||
mMap.setTheme(VtmThemes.DEFAULT);
|
||||
}
|
||||
}
|
||||
|
||||
if ("naturalearth".equals(c.getBackgroundLayer()))
|
||||
mMap.setBackgroundMap(new BitmapTileLayer(mMap, new NaturalEarth()));
|
||||
if (l != null) {
|
||||
if (!params.containsKey("nolabel"))
|
||||
mMap.layers().add(new LabelLayer(mMap, l));
|
||||
}
|
||||
|
||||
mSearchBox = new SearchBox(mMap);
|
||||
|
||||
@ -139,9 +201,12 @@ class GwtGdxMap extends GdxMap {
|
||||
|
||||
String newURL = Window.Location
|
||||
.createUrlBuilder()
|
||||
.setHash("scale=" + pos.zoomLevel + ",rot=" + curRot
|
||||
+ ",tilt=" + curTilt + ",lat=" + (curLat / 1000f)
|
||||
+ ",lon=" + (curLon / 1000f))
|
||||
.setHash(addParam
|
||||
+ "scale=" + pos.zoomLevel
|
||||
+ "&rot=" + curRot
|
||||
+ "&tilt=" + curTilt
|
||||
+ "&lat=" + (curLat / 1000f)
|
||||
+ "&lon=" + (curLon / 1000f))
|
||||
.buildString();
|
||||
Window.Location.replace(newURL);
|
||||
}
|
||||
|
@ -73,7 +73,13 @@ public class GwtGraphics implements Graphics {
|
||||
context.viewport(0, 0, config.width, config.height);
|
||||
|
||||
// this actually *enables* the option to use std derivatives in shader..
|
||||
context.getExtension("OES_standard_derivatives");
|
||||
if (context.getExtension("OES_standard_derivatives") == null) {
|
||||
|
||||
}
|
||||
|
||||
if (context.getExtension("WEBKIT_WEBGL_depth_texture") == null) {
|
||||
|
||||
}
|
||||
|
||||
this.gl = config.useDebugGL ? new GwtGL20Debug(context) : new GwtGLAdapter(context);
|
||||
canvas.setId("gdx-canvas");
|
||||
|
@ -35,6 +35,7 @@ public class GdxAssetAdapter extends AssetAdapter {
|
||||
try {
|
||||
return file.read();
|
||||
} catch (GdxRuntimeException e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
17
vtm/resources/assets/shaders/base_shader.glsl
Normal file
17
vtm/resources/assets/shaders/base_shader.glsl
Normal file
@ -0,0 +1,17 @@
|
||||
#ifdef GLES
|
||||
precision mediump float;
|
||||
#endif
|
||||
uniform mat4 u_mvp;
|
||||
attribute vec4 a_pos;
|
||||
void main() {
|
||||
gl_Position = u_mvp * a_pos;
|
||||
}
|
||||
$$
|
||||
#ifdef GLES
|
||||
precision mediump float;
|
||||
#endif
|
||||
uniform vec4 u_color;
|
||||
void main() {
|
||||
gl_FragColor = u_color;
|
||||
}
|
||||
|
59
vtm/resources/assets/shaders/extrusion_layer_ext.glsl
Normal file
59
vtm/resources/assets/shaders/extrusion_layer_ext.glsl
Normal file
@ -0,0 +1,59 @@
|
||||
uniform mat4 u_mvp;
|
||||
uniform vec4 u_color[4];
|
||||
uniform int u_mode;
|
||||
uniform float u_alpha;
|
||||
attribute vec4 a_pos;
|
||||
attribute vec2 a_light;
|
||||
varying vec4 color;
|
||||
varying float depth;
|
||||
const float ff = 255.0;
|
||||
void
|
||||
main(){
|
||||
// change height by u_alpha
|
||||
gl_Position = u_mvp * vec4(a_pos.xy, a_pos.z * u_alpha, 1.0);
|
||||
// depth = gl_Position.z;
|
||||
if (u_mode == -1) {
|
||||
;
|
||||
// roof / depth pass
|
||||
// color = u_color[0] * u_alpha;
|
||||
}
|
||||
else if (u_mode == 0) {
|
||||
// roof / depth pass
|
||||
color = u_color[0] * u_alpha;
|
||||
}
|
||||
else if (u_mode == 1) {
|
||||
// sides 1 - use 0xff00
|
||||
// scale direction to -0.5<>0.5
|
||||
float dir = a_light.y / ff;
|
||||
float z = (0.98 + gl_Position.z * 0.02);
|
||||
float h = 0.9 + clamp(a_pos.z / 2000.0, 0.0, 0.1);
|
||||
color = u_color[1];
|
||||
color.rgb *= (0.8 + dir * 0.2) * z * h;
|
||||
color *= u_alpha;
|
||||
}
|
||||
else if (u_mode == 2) {
|
||||
// sides 2 - use 0x00ff
|
||||
float dir = a_light.x / ff;
|
||||
float z = (0.98 + gl_Position.z * 0.02);
|
||||
float h = 0.9 + clamp(a_pos.z / 2000.0, 0.0, 0.1);
|
||||
color = u_color[2];
|
||||
color.rgb *= (0.8 + dir * 0.2) * z * h;
|
||||
color *= u_alpha;
|
||||
}
|
||||
else if (u_mode == 3) {
|
||||
// outline
|
||||
float z = (0.98 - gl_Position.z * 0.02);
|
||||
color = u_color[3] * z;
|
||||
}
|
||||
}
|
||||
|
||||
$$
|
||||
|
||||
#ifdef GLES
|
||||
precision mediump float;
|
||||
#endif
|
||||
varying vec4 color;
|
||||
void
|
||||
main(){
|
||||
gl_FragColor = color;
|
||||
}
|
50
vtm/resources/assets/shaders/extrusion_layer_mesh.glsl
Normal file
50
vtm/resources/assets/shaders/extrusion_layer_mesh.glsl
Normal file
@ -0,0 +1,50 @@
|
||||
uniform mat4 u_mvp;
|
||||
uniform vec4 u_color;
|
||||
uniform float u_alpha;
|
||||
attribute vec4 a_pos;
|
||||
attribute vec2 a_light;
|
||||
varying vec4 color;
|
||||
varying float depth;
|
||||
const float alpha = 1.0;
|
||||
void
|
||||
main(){
|
||||
// change height by u_alpha
|
||||
vec4 pos = a_pos;
|
||||
pos.z *= u_alpha;
|
||||
gl_Position = u_mvp * pos;
|
||||
// normalize face x/y direction
|
||||
vec2 enc = (a_light / 255.0);
|
||||
vec2 fenc = enc * 4.0 - 2.0;
|
||||
float f = dot(fenc, fenc);
|
||||
float g = sqrt(1.0 - f / 4.0);
|
||||
vec3 r_norm;
|
||||
r_norm.xy = fenc * g;
|
||||
r_norm.z = 1.0 - f / 2.0;
|
||||
// normal points up or down (1,-1)
|
||||
//// float dir = 1.0 - (2.0 * abs(mod(a_light.x,2.0)));
|
||||
// recreate face normal vector
|
||||
/// vec3 r_norm = vec3(n.xy, dir * (1.0 - length(n.xy)));
|
||||
vec3 light_dir = normalize(vec3(0.2, 0.2, 1.0));
|
||||
float l = dot(r_norm, light_dir) * 0.8;
|
||||
|
||||
light_dir = normalize(vec3(-0.2, -0.2, 1.0));
|
||||
l += dot(r_norm, light_dir) * 0.2;
|
||||
|
||||
// l = (l + (1.0 - r_norm.z))*0.5;
|
||||
l = 0.4 + l * 0.6;
|
||||
|
||||
// extreme fake-ssao by height
|
||||
l += (clamp(a_pos.z / 2048.0, 0.0, 0.1) - 0.05);
|
||||
color = vec4(u_color.rgb * (clamp(l, 0.0, 1.0) * alpha), u_color.a * alpha);
|
||||
}
|
||||
|
||||
$$
|
||||
|
||||
#ifdef GLES
|
||||
precision mediump float;
|
||||
#endif
|
||||
varying vec4 color;
|
||||
void
|
||||
main(){
|
||||
gl_FragColor = color;
|
||||
}
|
61
vtm/resources/assets/shaders/line_aa.glsl
Normal file
61
vtm/resources/assets/shaders/line_aa.glsl
Normal file
@ -0,0 +1,61 @@
|
||||
#ifdef GLES
|
||||
precision mediump float;
|
||||
#endif
|
||||
uniform mat4 u_mvp;
|
||||
// uniform mat4 u_vp;
|
||||
// factor to increase line width relative to scale
|
||||
uniform float u_width;
|
||||
// xy hold position, zw extrusion vector
|
||||
attribute vec4 a_pos;
|
||||
uniform float u_mode;
|
||||
uniform float u_height;
|
||||
varying vec2 v_st;
|
||||
void
|
||||
main(){
|
||||
|
||||
// scale extrusion to u_width pixel
|
||||
// just ignore the two most insignificant bits.
|
||||
vec2 dir = a_pos.zw;
|
||||
gl_Position = u_mvp * vec4(a_pos.xy + (u_width * dir), u_height, 1.0);
|
||||
|
||||
// last two bits hold the texture coordinates.
|
||||
v_st = abs(mod(dir, 4.0)) - 1.0;
|
||||
}
|
||||
$$
|
||||
#ifdef GLES
|
||||
precision mediump float;
|
||||
#endif
|
||||
uniform sampler2D tex;
|
||||
uniform float u_fade;
|
||||
uniform float u_mode;
|
||||
uniform vec4 u_color;
|
||||
varying vec2 v_st;
|
||||
void
|
||||
main(){
|
||||
float len;
|
||||
if (u_mode == 2.0) {
|
||||
// round cap line
|
||||
#ifdef DESKTOP_QUIRKS
|
||||
len = length(v_st);
|
||||
#else
|
||||
len = texture2D(tex, v_st).a;
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
// flat cap line
|
||||
len = abs(v_st.s);
|
||||
}
|
||||
// Antialias line-edges:
|
||||
// - 'len' is 0 at center of line. -> (1.0 - len) is 0 at the
|
||||
// edges
|
||||
// - 'u_fade' is 'pixel' / 'width', i.e. the inverse width of
|
||||
// the
|
||||
// line in pixel on screen.
|
||||
// - 'pixel' is 1.5 / relativeScale
|
||||
// - '(1.0 - len) / u_fade' interpolates the 'pixel' on
|
||||
// line-edge
|
||||
// between 0 and 1 (it is greater 1 for all inner pixel).
|
||||
gl_FragColor = u_color * clamp((1.0 - len) / u_fade, 0.0, 1.0);
|
||||
// -> nicer for thin lines
|
||||
// gl_FragColor = u_color * clamp((1.0 - (len * len)) / u_fade, 0.0, 1.0);
|
||||
}
|
60
vtm/resources/assets/shaders/line_aa_proj.glsl
Normal file
60
vtm/resources/assets/shaders/line_aa_proj.glsl
Normal file
@ -0,0 +1,60 @@
|
||||
#ifndef DESKTOP_QUIRKS
|
||||
precision mediump float;
|
||||
#endif
|
||||
uniform mat4 u_mvp;
|
||||
// uniform mat4 u_vp;
|
||||
// factor to increase line width relative to scale
|
||||
uniform float u_width;
|
||||
// xy hold position, zw extrusion vector
|
||||
attribute vec4 a_pos;
|
||||
uniform float u_mode;
|
||||
uniform float u_height;
|
||||
varying vec2 v_st;
|
||||
void
|
||||
main(){
|
||||
|
||||
// scale extrusion to u_width pixel
|
||||
// just ignore the two most insignificant bits.
|
||||
vec2 dir = a_pos.zw;
|
||||
gl_Position = u_mvp * vec4(a_pos.xy + (u_width * dir), u_height, 1.0);
|
||||
|
||||
// last two bits hold the texture coordinates.
|
||||
v_st = abs(mod(dir, 4.0)) - 1.0;
|
||||
}
|
||||
$$
|
||||
#extension GL_OES_standard_derivatives : enable
|
||||
#ifndef DESKTOP_QUIRKS
|
||||
precision mediump float;
|
||||
#endif
|
||||
uniform sampler2D tex;
|
||||
uniform float u_mode;
|
||||
uniform vec4 u_color;
|
||||
uniform float u_fade;
|
||||
varying vec2 v_st;
|
||||
void
|
||||
main(){
|
||||
float len;
|
||||
float fuzz;
|
||||
if (u_mode == 2.0) {
|
||||
/* round cap line */
|
||||
#ifdef DESKTOP_QUIRKS
|
||||
len = length(v_st);
|
||||
#else
|
||||
len = texture2D(tex, v_st).a;
|
||||
#endif
|
||||
vec2 st_width = fwidth(v_st);
|
||||
fuzz = max(st_width.s, st_width.t);
|
||||
}
|
||||
else {
|
||||
/* flat cap line */
|
||||
len = abs(v_st.s);
|
||||
fuzz = fwidth(v_st.s);
|
||||
}
|
||||
// u_mode == 0.0 -> thin line
|
||||
// len = len * clamp(u_mode, len, 1.0);
|
||||
if (fuzz > 2.0)
|
||||
gl_FragColor = u_color * 0.5;
|
||||
else
|
||||
gl_FragColor = u_color * clamp((1.0 - len) / max(u_fade, fuzz), 0.0, 1.0);
|
||||
// gl_FragColor = u_color * clamp((1.0 - len), 0.0, 1.0);
|
||||
}
|
53
vtm/resources/assets/shaders/linetex_layer.glsl
Normal file
53
vtm/resources/assets/shaders/linetex_layer.glsl
Normal file
@ -0,0 +1,53 @@
|
||||
#ifdef GLES
|
||||
precision mediump float;
|
||||
#endif
|
||||
uniform mat4 u_mvp;
|
||||
uniform vec4 u_color;
|
||||
uniform float u_pscale;
|
||||
uniform float u_width;
|
||||
attribute vec4 a_pos0;
|
||||
attribute vec4 a_pos1;
|
||||
attribute vec2 a_len0;
|
||||
attribute vec2 a_len1;
|
||||
attribute float a_flip;
|
||||
varying vec2 v_st;
|
||||
void
|
||||
main(){
|
||||
vec4 pos;
|
||||
if (a_flip == 0.0) {
|
||||
// vec2 dir = u_width * a_pos0.zw;
|
||||
pos = vec4(a_pos0.xy + (u_width * a_pos0.zw), 0.0, 1.0);
|
||||
v_st = vec2(a_len0.x / u_pscale, 1.0);
|
||||
}
|
||||
else {
|
||||
// vec2 dir = u_width * a_pos1.zw;
|
||||
pos = vec4(a_pos1.xy - (u_width * a_pos1.zw), 0.0, 1.0);
|
||||
v_st = vec2(a_len1.x / u_pscale, -1.0);
|
||||
}
|
||||
gl_Position = u_mvp * pos;
|
||||
}
|
||||
|
||||
$$
|
||||
|
||||
#extension GL_OES_standard_derivatives : enable
|
||||
#ifdef GLES
|
||||
precision mediump float;
|
||||
#endif
|
||||
uniform vec4 u_color;
|
||||
uniform vec4 u_bgcolor;
|
||||
uniform float u_pwidth;
|
||||
varying vec2 v_st;
|
||||
void
|
||||
main(){
|
||||
/* distance on perpendicular to the line */
|
||||
float dist = abs(v_st.t);
|
||||
float fuzz = fwidth(v_st.t);
|
||||
float fuzz_p = fwidth(v_st.s);
|
||||
float line_w = smoothstep(0.0, fuzz, 1.0 - dist);
|
||||
float stipple_w = smoothstep(0.0, fuzz, u_pwidth - dist);
|
||||
/* triangle waveform in the range 0..1 for regular pattern */
|
||||
float phase = abs(mod(v_st.s, 2.0) - 1.0);
|
||||
/* interpolate between on/off phase, 0.5 = equal phase length */
|
||||
float stipple_p = smoothstep(0.5 - fuzz_p, 0.5 + fuzz_p, phase);
|
||||
gl_FragColor = line_w * mix(u_bgcolor, u_color, min(stipple_w, stipple_p));
|
||||
}
|
21
vtm/resources/assets/shaders/mesh_layer_2D.glsl
Normal file
21
vtm/resources/assets/shaders/mesh_layer_2D.glsl
Normal file
@ -0,0 +1,21 @@
|
||||
#ifdef GLES
|
||||
precision mediump float;
|
||||
#endif
|
||||
uniform mat4 u_mvp;
|
||||
uniform float u_height;
|
||||
attribute vec2 a_pos;
|
||||
void
|
||||
main(){
|
||||
gl_Position = u_mvp * vec4(a_pos, u_height, 1.0);
|
||||
}
|
||||
|
||||
$$
|
||||
|
||||
#ifdef GLES
|
||||
precision mediump float;
|
||||
#endif
|
||||
uniform vec4 u_color;
|
||||
void
|
||||
main(){
|
||||
gl_FragColor = u_color;
|
||||
}
|
22
vtm/resources/assets/shaders/poly_texture.glsl
Normal file
22
vtm/resources/assets/shaders/poly_texture.glsl
Normal file
@ -0,0 +1,22 @@
|
||||
precision mediump float;
|
||||
uniform mat4 u_mvp;
|
||||
uniform vec2 u_scale;
|
||||
attribute vec4 a_pos;
|
||||
varying vec2 v_st;
|
||||
varying vec2 v_st2;
|
||||
void main() {
|
||||
v_st = clamp(a_pos.xy, 0.0, 1.0) * (2.0 / u_scale.y);
|
||||
v_st2 = clamp(a_pos.xy, 0.0, 1.0) * (4.0 / u_scale.y);
|
||||
gl_Position = u_mvp * a_pos;
|
||||
}
|
||||
|
||||
§
|
||||
precision mediump float;
|
||||
uniform vec4 u_color;
|
||||
uniform sampler2D tex;
|
||||
uniform vec2 u_scale;
|
||||
varying vec2 v_st;
|
||||
varying vec2 v_st2;
|
||||
void main() {
|
||||
gl_FragColor = mix(texture2D(tex, v_st), texture2D(tex, v_st2), u_scale.x);
|
||||
}
|
28
vtm/resources/assets/shaders/polygon_layer_tex.glsl
Normal file
28
vtm/resources/assets/shaders/polygon_layer_tex.glsl
Normal file
@ -0,0 +1,28 @@
|
||||
#ifdef GLES
|
||||
precision mediump float;
|
||||
#endif
|
||||
uniform mat4 u_mvp;
|
||||
uniform vec2 u_scale;
|
||||
attribute vec4 a_pos;
|
||||
varying vec2 v_st;
|
||||
varying vec2 v_st2;
|
||||
void
|
||||
main(){
|
||||
v_st = clamp(a_pos.xy, 0.0, 1.0) * (2.0 / u_scale.y);
|
||||
v_st2 = clamp(a_pos.xy, 0.0, 1.0) * (4.0 / u_scale.y);
|
||||
gl_Position = u_mvp * a_pos;
|
||||
}
|
||||
$$
|
||||
|
||||
#ifdef GLES
|
||||
precision mediump float;
|
||||
#endif
|
||||
uniform vec4 u_color;
|
||||
uniform sampler2D tex;
|
||||
uniform vec2 u_scale;
|
||||
varying vec2 v_st;
|
||||
varying vec2 v_st2;
|
||||
void
|
||||
main(){
|
||||
gl_FragColor = mix(texture2D(tex, v_st), texture2D(tex, v_st2), u_scale.x);
|
||||
}
|
25
vtm/resources/assets/shaders/texture_alpha.glsl
Normal file
25
vtm/resources/assets/shaders/texture_alpha.glsl
Normal file
@ -0,0 +1,25 @@
|
||||
#ifdef GLES
|
||||
precision mediump float;
|
||||
#endif
|
||||
attribute vec2 vertex;
|
||||
attribute vec2 tex_coord;
|
||||
uniform mat4 u_mvp;
|
||||
varying vec2 tex_c;
|
||||
void
|
||||
main(){
|
||||
gl_Position = u_mvp * vec4(vertex, 0.0, 1.0);
|
||||
tex_c = tex_coord;
|
||||
}
|
||||
|
||||
$$
|
||||
|
||||
#ifdef GLES
|
||||
precision mediump float;
|
||||
#endif
|
||||
uniform sampler2D tex;
|
||||
uniform float u_alpha;
|
||||
varying vec2 tex_c;
|
||||
void
|
||||
main(){
|
||||
gl_FragColor = texture2D(tex, tex_c) * u_alpha;
|
||||
}
|
37
vtm/resources/assets/shaders/texture_layer.glsl
Normal file
37
vtm/resources/assets/shaders/texture_layer.glsl
Normal file
@ -0,0 +1,37 @@
|
||||
#ifdef GLES
|
||||
precision highp float;
|
||||
#endif
|
||||
attribute vec4 vertex;
|
||||
attribute vec2 tex_coord;
|
||||
uniform mat4 u_mv;
|
||||
uniform mat4 u_proj;
|
||||
uniform float u_scale;
|
||||
uniform vec2 u_div;
|
||||
varying vec2 tex_c;
|
||||
const float coord_scale = 1.0/8.0;
|
||||
void
|
||||
main(){
|
||||
vec4 pos;
|
||||
vec2 dir = vertex.zw;
|
||||
if (mod(vertex.x, 2.0) == 0.0) {
|
||||
pos = u_proj * (u_mv * vec4(vertex.xy + dir * u_scale, 0.0, 1.0));
|
||||
}
|
||||
else { // place as billboard
|
||||
vec4 center = u_mv * vec4(vertex.xy, 0.0, 1.0);
|
||||
pos = u_proj * (center + vec4(dir * coord_scale, 0.0, 0.0));
|
||||
}
|
||||
gl_Position = pos;
|
||||
tex_c = tex_coord * u_div;
|
||||
}
|
||||
|
||||
$$
|
||||
|
||||
#ifdef GLES
|
||||
precision highp float;
|
||||
#endif
|
||||
uniform sampler2D tex;
|
||||
varying vec2 tex_c;
|
||||
void
|
||||
main(){
|
||||
gl_FragColor = texture2D(tex, tex_c.xy);
|
||||
}
|
@ -16,7 +16,10 @@
|
||||
*/
|
||||
package org.oscim.backend;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
|
||||
/**
|
||||
* The Class AssetAdapter.
|
||||
@ -33,4 +36,25 @@ public abstract class AssetAdapter {
|
||||
* @return the input stream
|
||||
*/
|
||||
public abstract InputStream openFileAsStream(String name);
|
||||
|
||||
public String openTextFile(String name) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
InputStream is = g.openFileAsStream(name);
|
||||
if (is == null)
|
||||
return null;
|
||||
|
||||
BufferedReader r = new BufferedReader(new InputStreamReader(is));
|
||||
String line;
|
||||
try {
|
||||
while ((line = r.readLine()) != null) {
|
||||
sb.append(line);
|
||||
sb.append('\n');
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
|
@ -66,10 +66,10 @@ public class ExtrusionRenderer extends LayerRenderer {
|
||||
|
||||
for (int i = 0; i <= SHADER; i++) {
|
||||
if (i == 0) {
|
||||
shaderProgram[i] = GLUtils.createProgram(extrusionVertexShader,
|
||||
shaderProgram[i] = GLShader.createProgram(extrusionVertexShader,
|
||||
extrusionFragmentShader);
|
||||
} else {
|
||||
shaderProgram[i] = GLUtils.createProgram(extrusionVertexShader,
|
||||
shaderProgram[i] = GLShader.createProgram(extrusionVertexShader,
|
||||
extrusionFragmentShaderZ);
|
||||
}
|
||||
|
||||
|
129
vtm/src/org/oscim/renderer/GLShader.java
Normal file
129
vtm/src/org/oscim/renderer/GLShader.java
Normal file
@ -0,0 +1,129 @@
|
||||
package org.oscim.renderer;
|
||||
|
||||
import java.nio.IntBuffer;
|
||||
|
||||
import org.oscim.backend.AssetAdapter;
|
||||
import org.oscim.backend.GL20;
|
||||
import org.oscim.backend.GLAdapter;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public abstract class GLShader {
|
||||
final static Logger log = LoggerFactory.getLogger(GLShader.class);
|
||||
|
||||
static GL20 GL;
|
||||
|
||||
public int program;
|
||||
|
||||
protected boolean create(String vertexSource, String fragmentSource) {
|
||||
program = createProgram(vertexSource, fragmentSource);
|
||||
return program != 0;
|
||||
}
|
||||
|
||||
protected boolean create(String fileName) {
|
||||
program = loadShader(fileName);
|
||||
return program != 0;
|
||||
}
|
||||
|
||||
protected int getAttrib(String name) {
|
||||
int loc = GL.glGetAttribLocation(program, name);
|
||||
if (loc < 0)
|
||||
log.debug("missing attribute: {}", name);
|
||||
return loc;
|
||||
}
|
||||
|
||||
protected int getUniform(String name) {
|
||||
int loc = GL.glGetUniformLocation(program, name);
|
||||
if (loc < 0)
|
||||
log.debug("missing uniform: {}", name);
|
||||
return loc;
|
||||
}
|
||||
|
||||
public boolean useProgram() {
|
||||
return GLState.useProgram(program);
|
||||
}
|
||||
|
||||
public static int loadShader(String file) {
|
||||
String path = "shaders/" + file + ".glsl";
|
||||
String vs = AssetAdapter.g.openTextFile(path);
|
||||
|
||||
if (vs == null)
|
||||
throw new IllegalArgumentException("shader file not found: " + path);
|
||||
|
||||
// TODO ...
|
||||
int fsStart = vs.indexOf('$');
|
||||
if (fsStart < 0 || vs.charAt(fsStart + 1) != '$')
|
||||
throw new IllegalArgumentException("not a shader file " + path);
|
||||
|
||||
String fs = vs.substring(fsStart + 2);
|
||||
vs = vs.substring(0, fsStart);
|
||||
|
||||
int shader = createProgram(vs, fs);
|
||||
if (shader == 0) {
|
||||
System.out.println(vs + " \n\n" + fs);
|
||||
}
|
||||
return shader;
|
||||
}
|
||||
|
||||
public static int loadShader(int shaderType, String source) {
|
||||
|
||||
int shader = GL.glCreateShader(shaderType);
|
||||
if (shader != 0) {
|
||||
GL.glShaderSource(shader, source);
|
||||
GL.glCompileShader(shader);
|
||||
IntBuffer compiled = MapRenderer.getIntBuffer(1);
|
||||
|
||||
GL.glGetShaderiv(shader, GL20.GL_COMPILE_STATUS, compiled);
|
||||
compiled.position(0);
|
||||
if (compiled.get() == 0) {
|
||||
log.error("Could not compile shader " + shaderType + ":");
|
||||
log.error(GL.glGetShaderInfoLog(shader));
|
||||
GL.glDeleteShader(shader);
|
||||
shader = 0;
|
||||
}
|
||||
}
|
||||
return shader;
|
||||
}
|
||||
|
||||
public static int createProgram(String vertexSource, String fragmentSource) {
|
||||
String defs = "";
|
||||
if (GLAdapter.GDX_DESKTOP_QUIRKS)
|
||||
defs += "#define DESKTOP_QUIRKS 1\n";
|
||||
else
|
||||
defs += "#define GLES 1\n";
|
||||
|
||||
int vertexShader = loadShader(GL20.GL_VERTEX_SHADER, defs + vertexSource);
|
||||
if (vertexShader == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int pixelShader = loadShader(GL20.GL_FRAGMENT_SHADER, defs + fragmentSource);
|
||||
if (pixelShader == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int program = GL.glCreateProgram();
|
||||
if (program != 0) {
|
||||
GLUtils.checkGlError("glCreateProgram");
|
||||
GL.glAttachShader(program, vertexShader);
|
||||
GLUtils.checkGlError("glAttachShader");
|
||||
GL.glAttachShader(program, pixelShader);
|
||||
GLUtils.checkGlError("glAttachShader");
|
||||
GL.glLinkProgram(program);
|
||||
IntBuffer linkStatus = MapRenderer.getIntBuffer(1);
|
||||
GL.glGetProgramiv(program, GL20.GL_LINK_STATUS, linkStatus);
|
||||
linkStatus.position(0);
|
||||
if (linkStatus.get() != GL20.GL_TRUE) {
|
||||
log.error("Could not link program: ");
|
||||
log.error(GL.glGetProgramInfoLog(program));
|
||||
GL.glDeleteProgram(program);
|
||||
program = 0;
|
||||
}
|
||||
}
|
||||
return program;
|
||||
}
|
||||
|
||||
public static class SimpleShader {
|
||||
|
||||
}
|
||||
}
|
@ -142,88 +142,6 @@ public class GLUtils {
|
||||
GL20.GL_REPEAT);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param shaderType
|
||||
* shader type
|
||||
* @param source
|
||||
* shader code
|
||||
* @return gl identifier
|
||||
*/
|
||||
public static int loadShader(int shaderType, String source) {
|
||||
|
||||
if (GLAdapter.GDX_DESKTOP_QUIRKS) {
|
||||
// Strip precision modifer
|
||||
int start = source.indexOf("precision");
|
||||
if (start >= 0) {
|
||||
int end = source.indexOf(';', start) + 1;
|
||||
if (start > 0)
|
||||
source = source.substring(0, start) + source.substring(end);
|
||||
else
|
||||
source = source.substring(end);
|
||||
}
|
||||
}
|
||||
|
||||
int shader = GL.glCreateShader(shaderType);
|
||||
if (shader != 0) {
|
||||
GL.glShaderSource(shader, source);
|
||||
GL.glCompileShader(shader);
|
||||
IntBuffer compiled = MapRenderer.getIntBuffer(1);
|
||||
|
||||
GL.glGetShaderiv(shader, GL20.GL_COMPILE_STATUS, compiled);
|
||||
compiled.position(0);
|
||||
if (compiled.get() == 0) {
|
||||
log.error("Could not compile shader " + shaderType + ":");
|
||||
log.error(GL.glGetShaderInfoLog(shader));
|
||||
GL.glDeleteShader(shader);
|
||||
shader = 0;
|
||||
}
|
||||
}
|
||||
return shader;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param vertexSource
|
||||
* ...
|
||||
* @param fragmentSource
|
||||
* ...
|
||||
* @return gl identifier
|
||||
*/
|
||||
public static int createProgram(String vertexSource, String fragmentSource) {
|
||||
int vertexShader = loadShader(GL20.GL_VERTEX_SHADER, vertexSource);
|
||||
if (vertexShader == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int pixelShader = loadShader(GL20.GL_FRAGMENT_SHADER, fragmentSource);
|
||||
if (pixelShader == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int program = GL.glCreateProgram();
|
||||
if (program != 0) {
|
||||
checkGlError("glCreateProgram");
|
||||
GL.glAttachShader(program, vertexShader);
|
||||
checkGlError("glAttachShader");
|
||||
GL.glAttachShader(program, pixelShader);
|
||||
checkGlError("glAttachShader");
|
||||
GL.glLinkProgram(program);
|
||||
IntBuffer linkStatus = MapRenderer.getIntBuffer(1);
|
||||
GL.glGetProgramiv(program, GL20.GL_LINK_STATUS, linkStatus);
|
||||
linkStatus.position(0);
|
||||
if (linkStatus.get() != GL20.GL_TRUE) {
|
||||
log.error("Could not link program: ");
|
||||
log.error(GL.glGetProgramInfoLog(program));
|
||||
GL.glDeleteProgram(program);
|
||||
program = 0;
|
||||
}
|
||||
}
|
||||
return program;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param op
|
||||
* ...
|
||||
*/
|
||||
public static void checkGlError(String op) {
|
||||
//GL = GLAdapter.get();
|
||||
|
||||
|
@ -324,6 +324,7 @@ public class MapRenderer {
|
||||
|
||||
GLState.init(GL);
|
||||
GLUtils.init(GL);
|
||||
GLShader.GL = GL;
|
||||
|
||||
// Set up some vertex buffer objects
|
||||
BufferObject.init(GL, 200);
|
||||
|
@ -20,8 +20,8 @@ import java.nio.ShortBuffer;
|
||||
|
||||
import org.oscim.backend.GL20;
|
||||
import org.oscim.backend.canvas.Bitmap;
|
||||
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.renderer.elements.TextureItem.TexturePool;
|
||||
@ -164,57 +164,50 @@ public class BitmapLayer extends TextureLayer {
|
||||
//textures = null;
|
||||
}
|
||||
|
||||
static class Shader extends GLShader {
|
||||
int uMVP, uAlpha, aPos, aTexCoord;
|
||||
|
||||
Shader(String shaderFile) {
|
||||
if (!create(shaderFile))
|
||||
return;
|
||||
uMVP = getUniform("u_mvp");
|
||||
uAlpha = getUniform("u_alpha");
|
||||
aPos = getAttrib("vertex");
|
||||
aTexCoord = getAttrib("tex_coord");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean useProgram() {
|
||||
if (super.useProgram()) {
|
||||
GLState.enableVertexArrays(aPos, aTexCoord);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static final class Renderer {
|
||||
|
||||
private static int mTextureProgram;
|
||||
private static int hTextureMVMatrix;
|
||||
private static int hTextureProjMatrix;
|
||||
private static int hTextureVertex;
|
||||
private static int hTextureScale;
|
||||
private static int hTextureScreenScale;
|
||||
private static int hTextureTexCoord;
|
||||
|
||||
private static int hAlpha;
|
||||
|
||||
public final static int INDICES_PER_SPRITE = 6;
|
||||
final static int VERTICES_PER_SPRITE = 4;
|
||||
final static int SHORTS_PER_VERTICE = 6;
|
||||
static Shader shader;
|
||||
|
||||
static void init() {
|
||||
mTextureProgram = GLUtils.createProgram(textVertexShader,
|
||||
textFragmentShader);
|
||||
|
||||
hTextureMVMatrix = GL.glGetUniformLocation(mTextureProgram, "u_mv");
|
||||
hTextureProjMatrix = GL.glGetUniformLocation(mTextureProgram, "u_proj");
|
||||
hTextureScale = GL.glGetUniformLocation(mTextureProgram, "u_scale");
|
||||
hTextureScreenScale = GL.glGetUniformLocation(mTextureProgram, "u_swidth");
|
||||
hTextureVertex = GL.glGetAttribLocation(mTextureProgram, "vertex");
|
||||
hTextureTexCoord = GL.glGetAttribLocation(mTextureProgram, "tex_coord");
|
||||
hAlpha = GL.glGetUniformLocation(mTextureProgram, "u_alpha");
|
||||
shader = new Shader("texture_alpha");
|
||||
}
|
||||
|
||||
public static RenderElement draw(RenderElement renderElement, GLViewport v, float scale,
|
||||
float alpha) {
|
||||
//GLState.test(false, false);
|
||||
public static RenderElement draw(RenderElement renderElement, GLViewport v,
|
||||
float scale, float alpha) {
|
||||
|
||||
GLState.blend(true);
|
||||
|
||||
GLState.useProgram(mTextureProgram);
|
||||
|
||||
GLState.enableVertexArrays(hTextureTexCoord, hTextureVertex);
|
||||
Shader s = shader;
|
||||
s.useProgram();
|
||||
|
||||
TextureLayer tl = (TextureLayer) renderElement;
|
||||
|
||||
if (tl.fixed)
|
||||
GL.glUniform1f(hTextureScale, (float) Math.sqrt(scale));
|
||||
else
|
||||
GL.glUniform1f(hTextureScale, 1);
|
||||
|
||||
GL.glUniform1f(hTextureScreenScale, 1f / v.getWidth());
|
||||
GL.glUniform1f(hAlpha, alpha);
|
||||
|
||||
v.proj.setAsUniform(hTextureProjMatrix);
|
||||
|
||||
v.mvp.setAsUniform(hTextureMVMatrix);
|
||||
GL.glUniform1f(s.uAlpha, alpha);
|
||||
v.mvp.setAsUniform(s.uMVP);
|
||||
|
||||
MapRenderer.bindQuadIndicesVBO(true);
|
||||
|
||||
@ -229,10 +222,10 @@ public class BitmapLayer extends TextureLayer {
|
||||
// to.offset * (24(shorts) * 2(short-bytes) / 6(indices) == 8)
|
||||
int off = (t.offset + i) * 8 + tl.offset;
|
||||
|
||||
GL.glVertexAttribPointer(hTextureVertex, 4,
|
||||
GL.glVertexAttribPointer(s.aPos, 2,
|
||||
GL20.GL_SHORT, false, 12, off);
|
||||
|
||||
GL.glVertexAttribPointer(hTextureTexCoord, 2,
|
||||
GL.glVertexAttribPointer(s.aTexCoord, 2,
|
||||
GL20.GL_SHORT, false, 12, off + 8);
|
||||
|
||||
int numVertices = t.vertices - i;
|
||||
@ -248,26 +241,5 @@ public class BitmapLayer extends TextureLayer {
|
||||
|
||||
return renderElement.next;
|
||||
}
|
||||
|
||||
private final static String textVertexShader = ""
|
||||
+ "precision mediump float; "
|
||||
+ "attribute vec4 vertex;"
|
||||
+ "attribute vec2 tex_coord;"
|
||||
+ "uniform mat4 u_mv;"
|
||||
+ "varying vec2 tex_c;"
|
||||
+ "void main() {"
|
||||
+ " gl_Position = u_mv * vec4(vertex.xy, 0.0, 1.0);"
|
||||
+ " tex_c = tex_coord;"
|
||||
+ "}";
|
||||
|
||||
private final static String textFragmentShader = ""
|
||||
+ "precision mediump float;"
|
||||
+ "uniform sampler2D tex;"
|
||||
+ "uniform float u_alpha;"
|
||||
+ "varying vec2 tex_c;"
|
||||
+ "void main() {"
|
||||
+ " gl_FragColor = texture2D(tex, tex_c.xy) * u_alpha;"
|
||||
+ "}";
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -25,6 +25,7 @@ import org.oscim.backend.canvas.Paint.Cap;
|
||||
import org.oscim.core.GeometryBuffer;
|
||||
import org.oscim.core.MercatorProjection;
|
||||
import org.oscim.core.Tile;
|
||||
import org.oscim.renderer.GLShader;
|
||||
import org.oscim.renderer.GLState;
|
||||
import org.oscim.renderer.GLUtils;
|
||||
import org.oscim.renderer.GLViewport;
|
||||
@ -614,6 +615,31 @@ public final class LineLayer extends RenderElement {
|
||||
return vertexItem;
|
||||
}
|
||||
|
||||
static class Shader extends GLShader {
|
||||
int uMVP, uFade, uWidth, uColor, uMode, uHeight, aPos;
|
||||
|
||||
Shader(String shaderFile) {
|
||||
if (!create(shaderFile))
|
||||
return;
|
||||
uMVP = getUniform("u_mvp");
|
||||
uFade = getUniform("u_fade");
|
||||
uWidth = getUniform("u_width");
|
||||
uColor = getUniform("u_color");
|
||||
uMode = getUniform("u_mode");
|
||||
uHeight = getUniform("u_height");
|
||||
aPos = getAttrib("a_pos");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean useProgram() {
|
||||
if (super.useProgram()) {
|
||||
GLState.enableVertexArrays(aPos, -1);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static final class Renderer {
|
||||
/* TODO:
|
||||
* http://http.developer.nvidia.com/GPUGems2/gpugems2_chapter22.html */
|
||||
@ -629,46 +655,13 @@ public final class LineLayer extends RenderElement {
|
||||
private final static int SHADER_FLAT = 1;
|
||||
private final static int SHADER_PROJ = 0;
|
||||
|
||||
/* shader handles */
|
||||
private static int[] lineProgram = new int[2];
|
||||
private static int[] hLineVertexPosition = new int[2];
|
||||
private static int[] hLineColor = new int[2];
|
||||
private static int[] hLineMatrix = new int[2];
|
||||
private static int[] hLineFade = new int[2];
|
||||
private static int[] hLineWidth = new int[2];
|
||||
private static int[] hLineMode = new int[2];
|
||||
private static int[] hLineHeight = new int[2];
|
||||
|
||||
public static int mTexID;
|
||||
private static Shader[] shaders = { null, null };
|
||||
|
||||
static boolean init() {
|
||||
|
||||
lineProgram[0] = GLUtils.createProgram(lineVertexShader,
|
||||
lineFragmentShader);
|
||||
if (lineProgram[0] == 0) {
|
||||
log.error("Could not create line program.");
|
||||
//return false;
|
||||
}
|
||||
|
||||
lineProgram[1] = GLUtils.createProgram(lineVertexShader,
|
||||
lineSimpleFragmentShader);
|
||||
if (lineProgram[1] == 0) {
|
||||
log.error("Could not create simple line program.");
|
||||
return false;
|
||||
}
|
||||
|
||||
for (int i = 0; i < 2; i++) {
|
||||
if (lineProgram[i] == 0)
|
||||
continue;
|
||||
|
||||
hLineMatrix[i] = GL.glGetUniformLocation(lineProgram[i], "u_mvp");
|
||||
hLineFade[i] = GL.glGetUniformLocation(lineProgram[i], "u_fade");
|
||||
hLineWidth[i] = GL.glGetUniformLocation(lineProgram[i], "u_width");
|
||||
hLineColor[i] = GL.glGetUniformLocation(lineProgram[i], "u_color");
|
||||
hLineMode[i] = GL.glGetUniformLocation(lineProgram[i], "u_mode");
|
||||
hLineHeight[i] = GL.glGetUniformLocation(lineProgram[i], "u_height");
|
||||
hLineVertexPosition[i] = GL.glGetAttribLocation(lineProgram[i], "a_pos");
|
||||
}
|
||||
shaders[0] = new Shader("line_aa_proj");
|
||||
shaders[1] = new Shader("line_aa");
|
||||
|
||||
/* create lookup table as texture for 'length(0..1,0..1)'
|
||||
* using mirrored wrap mode for 'length(-1..1,-1..1)' */
|
||||
@ -702,7 +695,10 @@ public final class LineLayer extends RenderElement {
|
||||
* account. only used when tilt is 0. */
|
||||
int mode = v.pos.tilt < 1 ? 1 : 0;
|
||||
|
||||
GLState.useProgram(lineProgram[mode]);
|
||||
Shader s = shaders[mode];
|
||||
s.useProgram();
|
||||
|
||||
//GLState.useProgram(lineProgram[mode]);
|
||||
GLState.blend(true);
|
||||
|
||||
/* Somehow we loose the texture after an indefinite
|
||||
@ -712,18 +708,16 @@ public final class LineLayer extends RenderElement {
|
||||
if (!GLAdapter.GDX_DESKTOP_QUIRKS)
|
||||
GLState.bindTex2D(mTexID);
|
||||
|
||||
int uLineFade = hLineFade[mode];
|
||||
int uLineMode = hLineMode[mode];
|
||||
int uLineColor = hLineColor[mode];
|
||||
int uLineWidth = hLineWidth[mode];
|
||||
int uLineHeight = hLineHeight[mode];
|
||||
int uLineFade = s.uFade;
|
||||
int uLineMode = s.uMode;
|
||||
int uLineColor = s.uColor;
|
||||
int uLineWidth = s.uWidth;
|
||||
int uLineHeight = s.uHeight;
|
||||
|
||||
GLState.enableVertexArrays(hLineVertexPosition[mode], -1);
|
||||
|
||||
GL.glVertexAttribPointer(hLineVertexPosition[mode], 4, GL20.GL_SHORT,
|
||||
GL.glVertexAttribPointer(s.aPos, 4, GL20.GL_SHORT,
|
||||
false, 0, layers.offset[LINE]);
|
||||
|
||||
v.mvp.setAsUniform(hLineMatrix[mode]);
|
||||
v.mvp.setAsUniform(s.uMVP);
|
||||
|
||||
/* Line scale factor for non fixed lines: Within a zoom-
|
||||
* level lines would be scaled by the factor 2 by view-matrix.
|
||||
@ -865,130 +859,5 @@ public final class LineLayer extends RenderElement {
|
||||
|
||||
return l;
|
||||
}
|
||||
|
||||
private final static String lineVertexShader = ""
|
||||
+ "precision mediump float;"
|
||||
+ "uniform mat4 u_mvp;"
|
||||
//+ "uniform mat4 u_vp;"
|
||||
/* factor to increase line width relative to scale */
|
||||
+ "uniform float u_width;"
|
||||
/* xy hold position, zw extrusion vector */
|
||||
+ "attribute vec4 a_pos;"
|
||||
+ "uniform float u_mode;"
|
||||
+ "uniform float u_height;"
|
||||
+ "varying vec2 v_st;"
|
||||
+ "void main() {"
|
||||
|
||||
/* scale extrusion to u_width pixel
|
||||
* just ignore the two most insignificant bits. */
|
||||
+ " vec2 dir = a_pos.zw;"
|
||||
+ " gl_Position = u_mvp * vec4(a_pos.xy + (u_width * dir), u_height, 1.0);"
|
||||
|
||||
/* last two bits hold the texture coordinates. */
|
||||
+ " v_st = abs(mod(dir, 4.0)) - 1.0;"
|
||||
+ "}";
|
||||
|
||||
private final static String lineVertexShader2 = ""
|
||||
+ "precision highp float;"
|
||||
+ "uniform mat4 u_mvp;"
|
||||
+ "uniform mat4 u_vp;"
|
||||
/* factor to increase line width relative to scale */
|
||||
+ "uniform float u_width;"
|
||||
/* xy hold position, zw extrusion vector */
|
||||
+ "attribute vec4 a_pos;"
|
||||
+ "uniform float u_mode;"
|
||||
+ "varying vec2 v_st;"
|
||||
+ "void main() {"
|
||||
|
||||
/* scale extrusion to u_width pixel */
|
||||
/* just ignore the two most insignificant bits. */
|
||||
+ " vec2 dir = a_pos.zw;"
|
||||
+ " vec4 pos = u_vp * vec4(a_pos.xy + (u_width * dir), 0.0, 0.0);"
|
||||
+ " vec4 orig = u_vp * vec4(a_pos.xy, 0.0, 0.0);"
|
||||
+ " float len = length(orig - pos);"
|
||||
//+ " if (len < 0.0625){"
|
||||
+ " pos = u_mvp * vec4(a_pos.xy + (u_width * dir) / (len * 4.0), 0.0, 1.0);"
|
||||
//+ " }"
|
||||
//+ " else pos = u_mvp * vec4(a_pos.xy + (u_width * dir), 0.0, 1.0);"
|
||||
+ " gl_Position = pos;"
|
||||
/* last two bits hold the texture coordinates. */
|
||||
+ " v_st = abs(mod(dir, 4.0)) - 1.0;"
|
||||
+ "}";
|
||||
|
||||
/** Antialising for orthonogonal projection */
|
||||
private final static String lineSimpleFragmentShader = ""
|
||||
+ "precision mediump float;"
|
||||
+ "uniform sampler2D tex;"
|
||||
+ "uniform float u_fade;"
|
||||
+ "uniform float u_mode;"
|
||||
+ "uniform vec4 u_color;"
|
||||
+ "varying vec2 v_st;"
|
||||
+ "void main() {"
|
||||
+ "float len;"
|
||||
+ " if (u_mode == 2.0){"
|
||||
/* round cap line */
|
||||
+ (GLAdapter.GDX_DESKTOP_QUIRKS
|
||||
? " len = length(v_st);"
|
||||
: " len = texture2D(tex, v_st).a;")
|
||||
+ " } else {"
|
||||
/* flat cap line */
|
||||
+ " len = abs(v_st.s);"
|
||||
+ " }"
|
||||
/* u_mode == 0.0 -> thin line */
|
||||
//+ " len = len * clamp(u_mode, len, 1.0);"
|
||||
|
||||
/* use 'max' to avoid branching, need to check performance */
|
||||
//+ (GLAdapter.GDX_DESKTOP_QUIRKS
|
||||
// ? " float len = max((1.0 - u_mode) * abs(v_st.s), u_mode * length(v_st));"
|
||||
// : " float len = max((1.0 - u_mode) * abs(v_st.s), u_mode * texture2D(tex, v_st).a);")
|
||||
|
||||
/* Antialias line-edges:
|
||||
* - 'len' is 0 at center of line. -> (1.0 - len) is 0 at the
|
||||
* edges
|
||||
* - 'u_fade' is 'pixel' / 'width', i.e. the inverse width of
|
||||
* the
|
||||
* line in pixel on screen.
|
||||
* - 'pixel' is 1.5 / relativeScale
|
||||
* - '(1.0 - len) / u_fade' interpolates the 'pixel' on
|
||||
* line-edge
|
||||
* between 0 and 1 (it is greater 1 for all inner pixel). */
|
||||
+ " gl_FragColor = u_color * clamp((1.0 - len) / u_fade, 0.0, 1.0);"
|
||||
/* -> nicer for thin lines */
|
||||
//+ " gl_FragColor = u_color * clamp((1.0 - (len * len)) / u_fade, 0.0, 1.0);"
|
||||
+ "}";
|
||||
|
||||
private final static String lineFragmentShader = ""
|
||||
+ "#extension GL_OES_standard_derivatives : enable\n"
|
||||
+ "precision mediump float;"
|
||||
+ "uniform sampler2D tex;"
|
||||
+ "uniform float u_mode;"
|
||||
+ "uniform vec4 u_color;"
|
||||
+ "uniform float u_fade;"
|
||||
+ "varying vec2 v_st;"
|
||||
+ "void main() {"
|
||||
+ " float len;"
|
||||
+ " float fuzz;"
|
||||
+ " if (u_mode == 2.0){"
|
||||
/* round cap line */
|
||||
+ (GLAdapter.GDX_DESKTOP_QUIRKS
|
||||
? " len = length(v_st);"
|
||||
: " len = texture2D(tex, v_st).a;")
|
||||
+ " vec2 st_width = fwidth(v_st);"
|
||||
+ " fuzz = max(st_width.s, st_width.t);"
|
||||
+ " } else {"
|
||||
/* flat cap line */
|
||||
+ " len = abs(v_st.s);"
|
||||
+ " fuzz = fwidth(v_st.s);"
|
||||
+ " }"
|
||||
/* u_mode == 0.0 -> thin line */
|
||||
//+ " len = len * clamp(u_mode, len, 1.0);"
|
||||
|
||||
+ " if (fuzz > 2.0)"
|
||||
+ " gl_FragColor = u_color * 0.5;" //vec4(1.0, 1.0, 1.0, 1.0);"
|
||||
+ " else"
|
||||
+ " gl_FragColor = u_color * clamp((1.0 - len) / max(u_fade, fuzz), 0.0, 1.0);"
|
||||
//+ " gl_FragColor = u_color * clamp((1.0 - len), 0.0, 1.0);"
|
||||
+ "}";
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -22,6 +22,7 @@ import java.nio.ShortBuffer;
|
||||
|
||||
import org.oscim.backend.GL20;
|
||||
import org.oscim.core.GeometryBuffer;
|
||||
import org.oscim.renderer.GLShader;
|
||||
import org.oscim.renderer.GLState;
|
||||
import org.oscim.renderer.GLUtils;
|
||||
import org.oscim.renderer.GLViewport;
|
||||
@ -250,49 +251,45 @@ public final class LineTexLayer extends RenderElement {
|
||||
sbuf.position(sbuf.position() + 6);
|
||||
}
|
||||
|
||||
static class Shader extends GLShader {
|
||||
int uMVP, uColor, uWidth, uBgColor, uScale;
|
||||
int uPatternWidth, uPatternScale;
|
||||
int aPos0, aPos1, aLen0, aLen1, aFlip;
|
||||
|
||||
Shader(String shaderFile) {
|
||||
if (!create(shaderFile))
|
||||
return;
|
||||
|
||||
uMVP = getUniform("u_mvp");
|
||||
|
||||
uScale = getUniform("u_scale");
|
||||
uColor = getUniform("u_color");
|
||||
uWidth = getUniform("u_width");
|
||||
uBgColor = getUniform("u_bgcolor");
|
||||
|
||||
uPatternWidth = getUniform("u_pwidth");
|
||||
uPatternScale = getUniform("u_pscale");
|
||||
|
||||
aPos0 = getAttrib("a_pos0");
|
||||
aPos1 = getAttrib("a_pos1");
|
||||
aLen0 = getAttrib("a_len0");
|
||||
aLen1 = getAttrib("a_len1");
|
||||
aFlip = getAttrib("a_flip");
|
||||
}
|
||||
}
|
||||
|
||||
public final static class Renderer {
|
||||
private static Shader shader;
|
||||
|
||||
/* factor to normalize extrusion vector and scale to coord scale */
|
||||
private final static float COORD_SCALE_BY_DIR_SCALE =
|
||||
MapRenderer.COORD_SCALE / LineLayer.DIR_SCALE;
|
||||
|
||||
private static int shader;
|
||||
private static int hVertexPosition0;
|
||||
private static int hVertexPosition1;
|
||||
private static int hVertexLength0;
|
||||
private static int hVertexLength1;
|
||||
private static int hVertexFlip;
|
||||
private static int hMatrix;
|
||||
private static int hTexColor;
|
||||
private static int hBgColor;
|
||||
//private static int hScale;
|
||||
private static int hWidth;
|
||||
private static int hPatternScale;
|
||||
private static int hPatternWidth;
|
||||
|
||||
private static int mVertexFlipID;
|
||||
|
||||
public static void init() {
|
||||
|
||||
shader = GLUtils.createProgram(vertexShader, fragmentShader);
|
||||
if (shader == 0) {
|
||||
log.error("Could not create program.");
|
||||
return;
|
||||
}
|
||||
|
||||
hMatrix = GL.glGetUniformLocation(shader, "u_mvp");
|
||||
hTexColor = GL.glGetUniformLocation(shader, "u_color");
|
||||
hBgColor = GL.glGetUniformLocation(shader, "u_bgcolor");
|
||||
//hScale = GL.glGetUniformLocation(shader, "u_scale");
|
||||
hWidth = GL.glGetUniformLocation(shader, "u_width");
|
||||
hPatternScale = GL.glGetUniformLocation(shader, "u_pscale");
|
||||
hPatternWidth = GL.glGetUniformLocation(shader, "u_pwidth");
|
||||
|
||||
hVertexPosition0 = GL.glGetAttribLocation(shader, "a_pos0");
|
||||
hVertexPosition1 = GL.glGetAttribLocation(shader, "a_pos1");
|
||||
hVertexLength0 = GL.glGetAttribLocation(shader, "a_len0");
|
||||
hVertexLength1 = GL.glGetAttribLocation(shader, "a_len1");
|
||||
hVertexFlip = GL.glGetAttribLocation(shader, "a_flip");
|
||||
shader = new Shader("linetex_layer");
|
||||
|
||||
int[] vboIds = GLUtils.glGenBuffers(1);
|
||||
mVertexFlipID = vboIds[0];
|
||||
@ -327,28 +324,35 @@ public final class LineTexLayer extends RenderElement {
|
||||
public static RenderElement draw(RenderElement curLayer, GLViewport v,
|
||||
float div, ElementLayers layers) {
|
||||
|
||||
if (shader == 0)
|
||||
return curLayer.next;
|
||||
//if (shader == 0)
|
||||
// return curLayer.next;
|
||||
|
||||
GLState.blend(true);
|
||||
GLState.useProgram(shader);
|
||||
//GLState.useProgram(shader);
|
||||
shader.useProgram();
|
||||
|
||||
GLState.enableVertexArrays(-1, -1);
|
||||
|
||||
GL.glEnableVertexAttribArray(hVertexPosition0);
|
||||
GL.glEnableVertexAttribArray(hVertexPosition1);
|
||||
GL.glEnableVertexAttribArray(hVertexLength0);
|
||||
GL.glEnableVertexAttribArray(hVertexLength1);
|
||||
GL.glEnableVertexAttribArray(hVertexFlip);
|
||||
int aLen0 = shader.aLen0;
|
||||
int aLen1 = shader.aLen1;
|
||||
int aPos0 = shader.aPos0;
|
||||
int aPos1 = shader.aPos1;
|
||||
int aFlip = shader.aFlip;
|
||||
|
||||
v.mvp.setAsUniform(hMatrix);
|
||||
GL.glEnableVertexAttribArray(aPos0);
|
||||
GL.glEnableVertexAttribArray(aPos1);
|
||||
GL.glEnableVertexAttribArray(aLen0);
|
||||
GL.glEnableVertexAttribArray(aLen1);
|
||||
GL.glEnableVertexAttribArray(aFlip);
|
||||
|
||||
v.mvp.setAsUniform(shader.uMVP);
|
||||
|
||||
int maxIndices = MapRenderer.maxQuads * 6;
|
||||
|
||||
MapRenderer.bindQuadIndicesVBO(true);
|
||||
|
||||
GL.glBindBuffer(GL20.GL_ARRAY_BUFFER, mVertexFlipID);
|
||||
GL.glVertexAttribPointer(hVertexFlip, 1,
|
||||
GL.glVertexAttribPointer(shader.aFlip, 1,
|
||||
GL20.GL_BYTE, false, 0, 0);
|
||||
|
||||
layers.vbo.bind();
|
||||
@ -364,19 +368,21 @@ public final class LineTexLayer extends RenderElement {
|
||||
LineTexLayer ll = (LineTexLayer) l;
|
||||
LineStyle line = ll.line.current();
|
||||
|
||||
GLUtils.setColor(hTexColor, line.stippleColor, 1);
|
||||
GLUtils.setColor(hBgColor, line.color, 1);
|
||||
GLUtils.setColor(shader.uColor, line.stippleColor, 1);
|
||||
GLUtils.setColor(shader.uBgColor, line.color, 1);
|
||||
|
||||
float pScale = (int) (s + 0.5f);
|
||||
if (pScale < 1)
|
||||
pScale = 1;
|
||||
|
||||
GL.glUniform1f(hPatternScale, (MapRenderer.COORD_SCALE * line.stipple) / pScale);
|
||||
GL.glUniform1f(hPatternWidth, line.stippleWidth);
|
||||
GL.glUniform1f(shader.uPatternScale,
|
||||
(MapRenderer.COORD_SCALE * line.stipple) / pScale);
|
||||
|
||||
GL.glUniform1f(shader.uPatternWidth, line.stippleWidth);
|
||||
//GL.glUniform1f(hScale, scale);
|
||||
|
||||
/* keep line width fixed */
|
||||
GL.glUniform1f(hWidth, ll.width / s * COORD_SCALE_BY_DIR_SCALE);
|
||||
GL.glUniform1f(shader.uWidth, ll.width / s * COORD_SCALE_BY_DIR_SCALE);
|
||||
|
||||
/* add offset vertex */
|
||||
int vOffset = -STRIDE;
|
||||
@ -392,20 +398,16 @@ public final class LineTexLayer extends RenderElement {
|
||||
/* i / 6 * (24 shorts per block * 2 short bytes) */
|
||||
int add = (l.offset + i * 8) + vOffset;
|
||||
|
||||
GL.glVertexAttribPointer(hVertexPosition0,
|
||||
4, GL20.GL_SHORT, false, STRIDE,
|
||||
GL.glVertexAttribPointer(aPos0, 4, GL20.GL_SHORT, false, STRIDE,
|
||||
add + STRIDE);
|
||||
|
||||
GL.glVertexAttribPointer(hVertexLength0,
|
||||
2, GL20.GL_SHORT, false, STRIDE,
|
||||
GL.glVertexAttribPointer(aLen0, 2, GL20.GL_SHORT, false, STRIDE,
|
||||
add + STRIDE + LEN_OFFSET);
|
||||
|
||||
GL.glVertexAttribPointer(hVertexPosition1,
|
||||
4, GL20.GL_SHORT, false, STRIDE,
|
||||
GL.glVertexAttribPointer(aPos1, 4, GL20.GL_SHORT, false, STRIDE,
|
||||
add);
|
||||
|
||||
GL.glVertexAttribPointer(hVertexLength1,
|
||||
2, GL20.GL_SHORT, false, STRIDE,
|
||||
GL.glVertexAttribPointer(aLen1, 2, GL20.GL_SHORT, false, STRIDE,
|
||||
add + LEN_OFFSET);
|
||||
|
||||
GL.glDrawElements(GL20.GL_TRIANGLES, numIndices,
|
||||
@ -421,20 +423,16 @@ public final class LineTexLayer extends RenderElement {
|
||||
/* i / 6 * (24 shorts per block * 2 short bytes) */
|
||||
int add = (l.offset + i * 8) + vOffset;
|
||||
|
||||
GL.glVertexAttribPointer(hVertexPosition0,
|
||||
4, GL20.GL_SHORT, false, STRIDE,
|
||||
GL.glVertexAttribPointer(aPos0, 4, GL20.GL_SHORT, false, STRIDE,
|
||||
add + 2 * STRIDE);
|
||||
|
||||
GL.glVertexAttribPointer(hVertexLength0,
|
||||
2, GL20.GL_SHORT, false, STRIDE,
|
||||
GL.glVertexAttribPointer(aLen0, 2, GL20.GL_SHORT, false, STRIDE,
|
||||
add + 2 * STRIDE + LEN_OFFSET);
|
||||
|
||||
GL.glVertexAttribPointer(hVertexPosition1,
|
||||
4, GL20.GL_SHORT, false, STRIDE,
|
||||
GL.glVertexAttribPointer(aPos1, 4, GL20.GL_SHORT, false, STRIDE,
|
||||
add + STRIDE);
|
||||
|
||||
GL.glVertexAttribPointer(hVertexLength1,
|
||||
2, GL20.GL_SHORT, false, STRIDE,
|
||||
GL.glVertexAttribPointer(aLen1, 2, GL20.GL_SHORT, false, STRIDE,
|
||||
add + STRIDE + LEN_OFFSET);
|
||||
|
||||
GL.glDrawElements(GL20.GL_TRIANGLES, numIndices,
|
||||
@ -445,107 +443,15 @@ public final class LineTexLayer extends RenderElement {
|
||||
|
||||
MapRenderer.bindQuadIndicesVBO(false);
|
||||
|
||||
GL.glDisableVertexAttribArray(hVertexPosition0);
|
||||
GL.glDisableVertexAttribArray(hVertexPosition1);
|
||||
GL.glDisableVertexAttribArray(hVertexLength0);
|
||||
GL.glDisableVertexAttribArray(hVertexLength1);
|
||||
GL.glDisableVertexAttribArray(hVertexFlip);
|
||||
GL.glDisableVertexAttribArray(aPos0);
|
||||
GL.glDisableVertexAttribArray(aPos1);
|
||||
GL.glDisableVertexAttribArray(aLen0);
|
||||
GL.glDisableVertexAttribArray(aLen1);
|
||||
GL.glDisableVertexAttribArray(aFlip);
|
||||
|
||||
//GL.glBindTexture(GL20.GL_TEXTURE_2D, 0);
|
||||
|
||||
return l;
|
||||
}
|
||||
|
||||
final static String vertexShader = ""
|
||||
+ "precision mediump float;"
|
||||
+ "uniform mat4 u_mvp;"
|
||||
+ "uniform vec4 u_color;"
|
||||
+ "uniform float u_pscale;"
|
||||
+ "uniform float u_width;"
|
||||
+ "attribute vec4 a_pos0;"
|
||||
+ "attribute vec4 a_pos1;"
|
||||
+ "attribute vec2 a_len0;"
|
||||
+ "attribute vec2 a_len1;"
|
||||
+ "attribute float a_flip;"
|
||||
+ "varying vec2 v_st;"
|
||||
+ "void main() {"
|
||||
+ " vec4 pos;"
|
||||
+ " if (a_flip == 0.0){"
|
||||
//+ " vec2 dir = u_width * a_pos0.zw;"
|
||||
+ " pos = vec4(a_pos0.xy + (u_width * a_pos0.zw), 0.0, 1.0);"
|
||||
+ " v_st = vec2(a_len0.x / u_pscale, 1.0);"
|
||||
+ " } else {"
|
||||
//+ " vec2 dir = u_width * a_pos1.zw;"
|
||||
+ " pos = vec4(a_pos1.xy - (u_width * a_pos1.zw), 0.0, 1.0);"
|
||||
+ " v_st = vec2(a_len1.x / u_pscale, -1.0);"
|
||||
+ " }"
|
||||
+ " gl_Position = u_mvp * pos;"
|
||||
+ "}";
|
||||
|
||||
//*
|
||||
final static String fragmentShader = ""
|
||||
+ "#extension GL_OES_standard_derivatives : enable\n"
|
||||
+ " precision mediump float;"
|
||||
+ " uniform vec4 u_color;"
|
||||
+ " uniform vec4 u_bgcolor;"
|
||||
+ " uniform float u_pwidth;"
|
||||
+ " varying vec2 v_st;"
|
||||
+ " void main() {"
|
||||
/* distance on perpendicular to the line */
|
||||
+ " float dist = abs(v_st.t);"
|
||||
+ " float fuzz = fwidth(v_st.t);"
|
||||
+ " float fuzz_p = fwidth(v_st.s);"
|
||||
+ " float line_w = smoothstep(0.0, fuzz, 1.0 - dist);"
|
||||
+ " float stipple_w = smoothstep(0.0, fuzz, u_pwidth - dist);"
|
||||
/* triangle waveform in the range 0..1 for regular pattern */
|
||||
+ " float phase = abs(mod(v_st.s, 2.0) - 1.0);"
|
||||
/* interpolate between on/off phase, 0.5 = equal phase length */
|
||||
+ " float stipple_p = smoothstep(0.5 - fuzz_p, 0.5 + fuzz_p, phase);"
|
||||
+ " gl_FragColor = line_w * mix(u_bgcolor, u_color, min(stipple_w, stipple_p));"
|
||||
+ " } "; //*/
|
||||
|
||||
/* final static String fragmentShader = ""
|
||||
* + "#extension GL_OES_standard_derivatives : enable\n"
|
||||
* + " precision mediump float;"
|
||||
* + " uniform sampler2D tex;"
|
||||
* + " uniform float u_scale;"
|
||||
* + " uniform vec4 u_color;"
|
||||
* + " uniform vec4 u_bgcolor;"
|
||||
* + " varying vec2 v_st;"
|
||||
* + " void main() {"
|
||||
* + " float len = texture2D(tex, v_st).a;"
|
||||
* + " float tex_w = abs(v_st.t);"
|
||||
* + " vec2 st_width = fwidth(v_st);"
|
||||
* + " float fuzz = max(st_width.s, st_width.t);"
|
||||
* //+ " float fuzz = fwidth(v_st.t);"
|
||||
* //+ " float line_w = 1.0 - smoothstep(1.0 - fuzz, 1.0, tex_w);"
|
||||
* //+ " float stipple_w = 1.0 - smoothstep(0.7 - fuzz, 0.7, tex_w);"
|
||||
* +
|
||||
* " float stipple_p = 1.0 - smoothstep(1.0 - fuzz, 1.0, length(vec2(len*u_scale, v_st.t)));"
|
||||
* + " gl_FragColor = u_bgcolor * stipple_p;"
|
||||
* // +
|
||||
* " gl_FragColor = line_w * mix(u_bgcolor, u_color, min(stipple_w, stipple_p));"
|
||||
* + "}"; // */
|
||||
/* final static String fragmentShader = ""
|
||||
* + "#extension GL_OES_standard_derivatives : enable\n"
|
||||
* + " precision mediump float;"
|
||||
* + " uniform sampler2D tex;"
|
||||
* + " uniform vec4 u_color;"
|
||||
* + " uniform vec4 u_bgcolor;"
|
||||
* + " uniform float u_pwidth;"
|
||||
* + " varying vec2 v_st;"
|
||||
* + " void main() {"
|
||||
* + " float dist = texture2D(tex, v_st).a;"
|
||||
* + " float tex_w = abs(v_st.t);"
|
||||
* + " vec2 st_width = fwidth(v_st);"
|
||||
* + " float fuzz = max(st_width.s, st_width.t);"
|
||||
* + " float line_w = (1.0 - smoothstep(1.0 - fuzz, 1.0, tex_w));"
|
||||
* +
|
||||
* " float stipple_w = (1.0 - smoothstep(u_pwidth - fuzz, u_pwidth, tex_w));"
|
||||
* + " float stipple_p = smoothstep(0.495, 0.505, dist);"
|
||||
* +
|
||||
* " gl_FragColor = line_w * mix(u_bgcolor, u_color, min(stipple_w, stipple_p));"
|
||||
* + " } "; // */
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -23,6 +23,7 @@ import org.oscim.backend.canvas.Color;
|
||||
import org.oscim.core.GeometryBuffer;
|
||||
import org.oscim.core.MercatorProjection;
|
||||
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;
|
||||
@ -104,36 +105,38 @@ public class MeshLayer extends RenderElement {
|
||||
}
|
||||
|
||||
public static class Renderer {
|
||||
private static int shaderProgram;
|
||||
private static int hMatrix;
|
||||
private static int hColor;
|
||||
private static int hHeightOffset;
|
||||
private static int hVertexPosition;
|
||||
static Shader shader;
|
||||
|
||||
static boolean init() {
|
||||
shaderProgram = GLUtils.createProgram(vertexShader, fragmentShader);
|
||||
if (shaderProgram == 0)
|
||||
return false;
|
||||
|
||||
hMatrix = GL.glGetUniformLocation(shaderProgram, "u_mvp");
|
||||
hColor = GL.glGetUniformLocation(shaderProgram, "u_color");
|
||||
hHeightOffset = GL.glGetUniformLocation(shaderProgram, "u_height");
|
||||
hVertexPosition = GL.glGetAttribLocation(shaderProgram, "a_pos");
|
||||
shader = new Shader("mesh_layer_2D");
|
||||
return true;
|
||||
}
|
||||
|
||||
public static RenderElement draw(RenderElement l, GLViewport v) {
|
||||
static class Shader extends GLShader {
|
||||
int uMVP, uColor, uHeight, aPos;
|
||||
|
||||
Shader(String shaderFile) {
|
||||
if (!create(shaderFile))
|
||||
return;
|
||||
|
||||
uMVP = getUniform("u_mvp");
|
||||
uColor = getUniform("u_color");
|
||||
uHeight = getUniform("u_height");
|
||||
aPos = getAttrib("a_pos");
|
||||
}
|
||||
}
|
||||
|
||||
public static RenderElement draw(RenderElement l, GLViewport v) {
|
||||
GLState.blend(true);
|
||||
|
||||
GLState.useProgram(shaderProgram);
|
||||
Shader s = shader;
|
||||
s.useProgram();
|
||||
GLState.enableVertexArrays(s.aPos, -1);
|
||||
|
||||
GLState.enableVertexArrays(hVertexPosition, -1);
|
||||
|
||||
v.mvp.setAsUniform(hMatrix);
|
||||
v.mvp.setAsUniform(s.uMVP);
|
||||
|
||||
float heightOffset = 0;
|
||||
GL.glUniform1f(hHeightOffset, heightOffset);
|
||||
GL.glUniform1f(s.uHeight, heightOffset);
|
||||
|
||||
for (; l != null && l.type == RenderElement.MESH; l = l.next) {
|
||||
MeshLayer ml = (MeshLayer) l;
|
||||
@ -144,25 +147,25 @@ public class MeshLayer extends RenderElement {
|
||||
if (ml.heightOffset != heightOffset) {
|
||||
heightOffset = ml.heightOffset;
|
||||
|
||||
GL.glUniform1f(hHeightOffset, heightOffset /
|
||||
GL.glUniform1f(s.uHeight, heightOffset /
|
||||
MercatorProjection.groundResolution(v.pos));
|
||||
}
|
||||
|
||||
ml.indicesVbo.bind();
|
||||
|
||||
if (ml.area == null)
|
||||
GLUtils.setColor(hColor, Color.BLUE, 0.4f);
|
||||
GLUtils.setColor(s.uColor, Color.BLUE, 0.4f);
|
||||
else
|
||||
GLUtils.setColor(hColor, ml.area.color, 1);
|
||||
GLUtils.setColor(s.uColor, ml.area.color, 1);
|
||||
|
||||
GL.glVertexAttribPointer(hVertexPosition, 2, GL20.GL_SHORT,
|
||||
GL.glVertexAttribPointer(s.aPos, 2, GL20.GL_SHORT,
|
||||
false, 0, ml.offset);
|
||||
|
||||
GL.glDrawElements(GL20.GL_TRIANGLES, ml.numIndices,
|
||||
GL20.GL_UNSIGNED_SHORT, 0);
|
||||
|
||||
if (dbg) {
|
||||
GLUtils.setColor(hColor, Color.GRAY, 0.4f);
|
||||
GLUtils.setColor(s.uColor, Color.GRAY, 0.4f);
|
||||
GL.glDrawElements(GL20.GL_LINES, ml.numIndices,
|
||||
GL20.GL_UNSIGNED_SHORT, 0);
|
||||
}
|
||||
@ -172,21 +175,5 @@ public class MeshLayer extends RenderElement {
|
||||
|
||||
return l;
|
||||
}
|
||||
|
||||
private final static String vertexShader = ""
|
||||
+ "precision mediump float;"
|
||||
+ "uniform mat4 u_mvp;"
|
||||
+ "uniform float u_height;"
|
||||
+ "attribute vec2 a_pos;"
|
||||
+ "void main() {"
|
||||
+ " gl_Position = u_mvp * vec4(a_pos, u_height, 1.0);"
|
||||
+ "}";
|
||||
|
||||
private final static String fragmentShader = ""
|
||||
+ "precision mediump float;"
|
||||
+ "uniform vec4 u_color;"
|
||||
+ "void main() {"
|
||||
+ " gl_FragColor = u_color;"
|
||||
+ "}";
|
||||
}
|
||||
}
|
||||
|
@ -16,15 +16,10 @@
|
||||
*/
|
||||
package org.oscim.renderer.elements;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
import java.nio.FloatBuffer;
|
||||
|
||||
import org.oscim.backend.GL20;
|
||||
import org.oscim.backend.GLAdapter;
|
||||
import org.oscim.core.GeometryBuffer;
|
||||
import org.oscim.core.Tile;
|
||||
import org.oscim.renderer.GLMatrix;
|
||||
import org.oscim.renderer.GLShader;
|
||||
import org.oscim.renderer.GLState;
|
||||
import org.oscim.renderer.GLUtils;
|
||||
import org.oscim.renderer.GLViewport;
|
||||
@ -37,7 +32,7 @@ import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* Special Renderer for drawing tile polygons using a stencil buffer method
|
||||
* Special Renderer for drawing tile polygons using the stencil buffer method
|
||||
*/
|
||||
public final class PolygonLayer extends RenderElement {
|
||||
static final Logger log = LoggerFactory.getLogger(PolygonLayer.class);
|
||||
@ -118,9 +113,25 @@ public final class PolygonLayer extends RenderElement {
|
||||
si.used = outPos;
|
||||
}
|
||||
|
||||
static class Shader extends GLShader {
|
||||
int uMVP, uColor, uScale, aPos;
|
||||
|
||||
Shader(String shaderFile) {
|
||||
if (!create(shaderFile))
|
||||
return;
|
||||
|
||||
uMVP = getUniform("u_mvp");
|
||||
aPos = getAttrib("a_pos");
|
||||
|
||||
if (shaderFile == "polygon_layer_tex")
|
||||
uScale = getUniform("u_scale");
|
||||
else
|
||||
uColor = getUniform("u_color");
|
||||
}
|
||||
}
|
||||
|
||||
public static final class Renderer {
|
||||
|
||||
private static final int POLYGON_VERTICES_DATA_POS_OFFSET = 0;
|
||||
private static final int STENCIL_BITS = 8;
|
||||
private final static int CLIP_BIT = 0x80;
|
||||
|
||||
@ -128,45 +139,12 @@ public final class PolygonLayer extends RenderElement {
|
||||
|
||||
private static AreaStyle[] mAreaFills;
|
||||
|
||||
private static int numShaders = 2;
|
||||
private static int polyShader = 0;
|
||||
private static int texShader = 1;
|
||||
|
||||
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[] hPolygonScale = new int[numShaders];
|
||||
private static Shader polyShader;
|
||||
private static Shader texShader;
|
||||
|
||||
static boolean init() {
|
||||
|
||||
for (int i = 0; i < numShaders; i++) {
|
||||
|
||||
// Set up the program for rendering polygons
|
||||
if (i == 0) {
|
||||
if (GLAdapter.debugView)
|
||||
polygonProgram[i] = GLUtils.createProgram(polygonVertexShaderZ,
|
||||
polygonFragmentShaderZ);
|
||||
else
|
||||
polygonProgram[i] = GLUtils.createProgram(polygonVertexShader,
|
||||
polygonFragmentShader);
|
||||
} else if (i == 1) {
|
||||
polygonProgram[i] = GLUtils.createProgram(textureVertexShader,
|
||||
textureFragmentShader);
|
||||
|
||||
}
|
||||
|
||||
if (polygonProgram[i] == 0) {
|
||||
log.error("Could not create polygon program.");
|
||||
return false;
|
||||
}
|
||||
hPolygonMatrix[i] = GL.glGetUniformLocation(polygonProgram[i], "u_mvp");
|
||||
hPolygonColor[i] = GL.glGetUniformLocation(polygonProgram[i], "u_color");
|
||||
hPolygonScale[i] = GL.glGetUniformLocation(polygonProgram[i], "u_scale");
|
||||
|
||||
hPolygonVertexPosition[i] = GL.glGetAttribLocation(polygonProgram[i], "a_pos");
|
||||
}
|
||||
polyShader = new Shader("base_shader");
|
||||
texShader = new Shader("polygon_layer_tex");
|
||||
|
||||
mAreaFills = new AreaStyle[STENCIL_BITS];
|
||||
|
||||
@ -181,17 +159,18 @@ public final class PolygonLayer extends RenderElement {
|
||||
|
||||
/* do not modify stencil buffer */
|
||||
GL.glStencilMask(0x00);
|
||||
int shader = polyShader;
|
||||
//int shader = polyShader;
|
||||
|
||||
Shader s = setShader(polyShader, v, false);
|
||||
|
||||
for (int c = start; c < end; c++) {
|
||||
AreaStyle a = mAreaFills[c].current();
|
||||
|
||||
if (enableTexture && a.texture != null) {
|
||||
shader = texShader;
|
||||
setShader(texShader, v);
|
||||
s = setShader(texShader, v, false);
|
||||
float num = FastMath.clamp((Tile.SIZE / a.texture.width) >> 1, 1, Tile.SIZE);
|
||||
float transition = Interpolation.exp5.apply(FastMath.clamp(scale - 1, 0, 1));
|
||||
GL.glUniform2f(hPolygonScale[1], transition, div / num);
|
||||
GL.glUniform2f(s.uScale, transition, div / num);
|
||||
|
||||
//if (a.texture.alpha);
|
||||
GLState.blend(true);
|
||||
@ -208,17 +187,17 @@ public final class PolygonLayer extends RenderElement {
|
||||
}
|
||||
GLState.blend(true);
|
||||
|
||||
GLUtils.setColor(hPolygonColor[shader], a.color, f);
|
||||
GLUtils.setColor(s.uColor, a.color, f);
|
||||
|
||||
} else if (a.blendScale > 0 && a.blendScale <= zoom) {
|
||||
/* blend colors (not alpha) */
|
||||
GLState.blend(false);
|
||||
|
||||
if (a.blendScale == zoom)
|
||||
GLUtils.setColorBlend(hPolygonColor[shader],
|
||||
a.color, a.blendColor, scale - 1.0f);
|
||||
GLUtils.setColorBlend(s.uColor, a.color,
|
||||
a.blendColor, scale - 1.0f);
|
||||
else
|
||||
GLUtils.setColor(hPolygonColor[shader], a.blendColor, 1);
|
||||
GLUtils.setColor(s.uColor, a.blendColor, 1);
|
||||
|
||||
} else {
|
||||
if (a.color < 0xff000000)
|
||||
@ -226,38 +205,37 @@ public final class PolygonLayer extends RenderElement {
|
||||
else
|
||||
GLState.blend(false);
|
||||
|
||||
GLUtils.setColor(hPolygonColor[shader], a.color, 1);
|
||||
GLUtils.setColor(s.uColor, a.color, 1);
|
||||
}
|
||||
|
||||
// set stencil buffer mask used to draw this layer
|
||||
// also check that clip bit is set to avoid overdraw
|
||||
// of other tiles
|
||||
/* set stencil buffer mask used to draw this layer
|
||||
* also check that clip bit is set to avoid overdraw
|
||||
* of other tiles */
|
||||
GL.glStencilFunc(GL20.GL_EQUAL, 0xff, CLIP_BIT | 1 << c);
|
||||
|
||||
/* draw tile fill coordinates */
|
||||
GL.glDrawArrays(GL20.GL_TRIANGLE_STRIP, 0, 4);
|
||||
|
||||
if (shader != polyShader) {
|
||||
// disable texture shader
|
||||
setShader(polyShader, v);
|
||||
shader = polyShader;
|
||||
}
|
||||
/* disable texture shader */
|
||||
if (s != polyShader)
|
||||
s = setShader(polyShader, v, false);
|
||||
}
|
||||
}
|
||||
|
||||
// current layer to fill (0 - STENCIL_BITS-1)
|
||||
private static int mCount;
|
||||
|
||||
private static void setShader(int shader, GLViewport v) {
|
||||
GLState.useProgram(polygonProgram[shader]);
|
||||
private static Shader setShader(Shader shader, GLViewport v, boolean first) {
|
||||
if (shader.useProgram() || first) {
|
||||
|
||||
GLState.enableVertexArrays(hPolygonVertexPosition[shader], -1);
|
||||
GLState.enableVertexArrays(shader.aPos, -1);
|
||||
|
||||
GL.glVertexAttribPointer(hPolygonVertexPosition[shader], 2,
|
||||
GL20.GL_SHORT, false, 0,
|
||||
POLYGON_VERTICES_DATA_POS_OFFSET);
|
||||
GL.glVertexAttribPointer(shader.aPos, 2,
|
||||
GL20.GL_SHORT, false, 0, 0);
|
||||
|
||||
v.mvp.setAsUniform(hPolygonMatrix[shader]);
|
||||
v.mvp.setAsUniform(shader.uMVP);
|
||||
}
|
||||
return shader;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -287,14 +265,14 @@ public final class PolygonLayer extends RenderElement {
|
||||
|
||||
GLState.test(false, true);
|
||||
|
||||
setShader(polyShader, v);
|
||||
setShader(polyShader, v, first);
|
||||
|
||||
int zoom = v.pos.zoomLevel;
|
||||
float scale = (float) v.pos.getZoomScale();
|
||||
|
||||
int cur = mCount;
|
||||
|
||||
// reset start when only one layer left in stencil buffer
|
||||
/* reset start when only one layer left in stencil buffer */
|
||||
if (first || cur > 5)
|
||||
cur = 0;
|
||||
|
||||
@ -304,7 +282,7 @@ public final class PolygonLayer extends RenderElement {
|
||||
for (; l != null && l.type == RenderElement.POLYGON; l = l.next) {
|
||||
PolygonLayer pl = (PolygonLayer) l;
|
||||
|
||||
// fade out polygon layers (set in RenderTheme)
|
||||
/* fade out polygon layers (set in RenderTheme) */
|
||||
if (pl.area.fadeScale > 0 && pl.area.fadeScale > zoom)
|
||||
continue;
|
||||
|
||||
@ -312,18 +290,18 @@ public final class PolygonLayer extends RenderElement {
|
||||
drawStencilRegion(first, clipMode);
|
||||
first = false;
|
||||
|
||||
// op for stencil method polygon drawing
|
||||
/* op for stencil method polygon drawing */
|
||||
GL.glStencilOp(GL20.GL_KEEP, GL20.GL_KEEP, GL20.GL_INVERT);
|
||||
}
|
||||
|
||||
mAreaFills[cur] = pl.area.current();
|
||||
|
||||
// set stencil mask to draw to
|
||||
/* set stencil mask to draw to */
|
||||
GL.glStencilMask(1 << cur++);
|
||||
|
||||
GL.glDrawArrays(GL20.GL_TRIANGLE_FAN, l.offset, l.numVertices);
|
||||
|
||||
// draw up to 7 layers into stencil buffer
|
||||
/* draw up to 7 layers into stencil buffer */
|
||||
if (cur == STENCIL_BITS - 1) {
|
||||
fillPolygons(v, start, cur, zoom, scale, div);
|
||||
start = cur = 0;
|
||||
@ -336,12 +314,12 @@ public final class PolygonLayer extends RenderElement {
|
||||
if (clipMode > 0) {
|
||||
if (first) {
|
||||
drawStencilRegion(first, clipMode);
|
||||
// disable writes to stencil buffer
|
||||
/* disable writes to stencil buffer */
|
||||
GL.glStencilMask(0x00);
|
||||
// enable writes to color buffer
|
||||
/* enable writes to color buffer */
|
||||
GL.glColorMask(true, true, true, true);
|
||||
} else {
|
||||
// set test for clip to tile region
|
||||
/* set test for clip to tile region */
|
||||
GL.glStencilFunc(GL20.GL_EQUAL, CLIP_BIT, CLIP_BIT);
|
||||
}
|
||||
}
|
||||
@ -352,12 +330,12 @@ public final class PolygonLayer extends RenderElement {
|
||||
}
|
||||
|
||||
public static void clip(GLViewport v) {
|
||||
setShader(polyShader, v);
|
||||
setShader(polyShader, v, true);
|
||||
|
||||
drawStencilRegion(true, 1);
|
||||
// disable writes to stencil buffer
|
||||
/* disable writes to stencil buffer */
|
||||
GL.glStencilMask(0x00);
|
||||
// enable writes to color buffer
|
||||
/* enable writes to color buffer */
|
||||
GL.glColorMask(true, true, true, true);
|
||||
}
|
||||
|
||||
@ -419,10 +397,11 @@ public final class PolygonLayer extends RenderElement {
|
||||
* and 'alpha' to fake a fade effect.
|
||||
*/
|
||||
public static void drawOver(GLViewport v, int color, float alpha) {
|
||||
setShader(polyShader, v);
|
||||
// TODO true could be avoided when same shader and vbo
|
||||
setShader(polyShader, v, true);
|
||||
|
||||
if (color != 0) {
|
||||
GLUtils.setColor(hPolygonColor[0], color, alpha);
|
||||
GLUtils.setColor(polyShader.uColor, color, alpha);
|
||||
GLState.blend(true);
|
||||
} else {
|
||||
/* disable drawing to framebuffer (will be re-enabled in fill) */
|
||||
@ -447,103 +426,39 @@ public final class PolygonLayer extends RenderElement {
|
||||
GL.glColorMask(true, true, true, true);
|
||||
}
|
||||
|
||||
private static float[] debugFillColor = { 0.3f, 0.0f, 0.0f, 0.3f };
|
||||
private static float[] debugFillColor2 = { .8f, .8f, .8f, .8f };
|
||||
private static FloatBuffer mDebugFill;
|
||||
//private static float[] debugFillColor = { 0.3f, 0.0f, 0.0f, 0.3f };
|
||||
//private static float[] debugFillColor2 = { .8f, .8f, .8f, .8f };
|
||||
//private static FloatBuffer mDebugFill;
|
||||
|
||||
static void debugDraw(GLMatrix m, float[] coords, int color) {
|
||||
GLState.test(false, false);
|
||||
if (mDebugFill == null) {
|
||||
mDebugFill = ByteBuffer
|
||||
.allocateDirect(32)
|
||||
.order(ByteOrder.nativeOrder())
|
||||
.asFloatBuffer();
|
||||
mDebugFill.put(coords);
|
||||
//static void debugDraw(GLMatrix m, float[] coords, int color) {
|
||||
// GLState.test(false, false);
|
||||
// if (mDebugFill == null) {
|
||||
// mDebugFill = ByteBuffer
|
||||
// .allocateDirect(32)
|
||||
// .order(ByteOrder.nativeOrder())
|
||||
// .asFloatBuffer();
|
||||
// mDebugFill.put(coords);
|
||||
// }
|
||||
//
|
||||
// GL.glBindBuffer(GL20.GL_ARRAY_BUFFER, 0);
|
||||
//
|
||||
// mDebugFill.position(0);
|
||||
// GLState.useProgram(polygonProgram[0]);
|
||||
// GL.glEnableVertexAttribArray(hPolygonVertexPosition[0]);
|
||||
//
|
||||
// GL.glVertexAttribPointer(hPolygonVertexPosition[0], 2, GL20.GL_FLOAT,
|
||||
// false, 0, mDebugFill);
|
||||
//
|
||||
// m.setAsUniform(hPolygonMatrix[0]);
|
||||
//
|
||||
// if (color == 0)
|
||||
// GLUtils.glUniform4fv(hPolygonColor[0], 1, debugFillColor);
|
||||
// else
|
||||
// GLUtils.glUniform4fv(hPolygonColor[0], 1, debugFillColor2);
|
||||
//
|
||||
// GL.glDrawArrays(GL20.GL_TRIANGLE_STRIP, 0, 4);
|
||||
//
|
||||
// GLUtils.checkGlError("draw debug");
|
||||
//}
|
||||
}
|
||||
|
||||
GL.glBindBuffer(GL20.GL_ARRAY_BUFFER, 0);
|
||||
|
||||
mDebugFill.position(0);
|
||||
GLState.useProgram(polygonProgram[0]);
|
||||
GL.glEnableVertexAttribArray(hPolygonVertexPosition[0]);
|
||||
|
||||
GL.glVertexAttribPointer(hPolygonVertexPosition[0], 2, GL20.GL_FLOAT,
|
||||
false, 0, mDebugFill);
|
||||
|
||||
m.setAsUniform(hPolygonMatrix[0]);
|
||||
|
||||
if (color == 0)
|
||||
GLUtils.glUniform4fv(hPolygonColor[0], 1, debugFillColor);
|
||||
else
|
||||
GLUtils.glUniform4fv(hPolygonColor[0], 1, debugFillColor2);
|
||||
|
||||
GL.glDrawArrays(GL20.GL_TRIANGLE_STRIP, 0, 4);
|
||||
|
||||
GLUtils.checkGlError("draw debug");
|
||||
}
|
||||
|
||||
private final static String polygonVertexShader = ""
|
||||
+ "precision mediump float;"
|
||||
+ "uniform mat4 u_mvp;"
|
||||
+ "attribute vec4 a_pos;"
|
||||
+ "void main() {"
|
||||
+ " gl_Position = u_mvp * a_pos;"
|
||||
+ "}";
|
||||
|
||||
private final static String polygonFragmentShader = ""
|
||||
+ "precision mediump float;"
|
||||
+ "uniform vec4 u_color;"
|
||||
+ "void main() {"
|
||||
+ " gl_FragColor = u_color;"
|
||||
+ "}";
|
||||
|
||||
private final static String polygonVertexShaderZ = ""
|
||||
+ "precision highp float;"
|
||||
+ "uniform mat4 u_mvp;"
|
||||
+ "attribute vec4 a_pos;"
|
||||
+ "varying float z;"
|
||||
+ "void main() {"
|
||||
+ " gl_Position = u_mvp * a_pos;"
|
||||
+ " z = gl_Position.z;"
|
||||
+ "}";
|
||||
private final static String polygonFragmentShaderZ = ""
|
||||
+ "precision highp float;"
|
||||
+ "uniform vec4 u_color;"
|
||||
+ "varying float z;"
|
||||
+ "void main() {"
|
||||
+ "if (z < -1.0)"
|
||||
+ " gl_FragColor = vec4(0.0, z + 2.0, 0.0, 1.0)*0.8;"
|
||||
+ "else if (z < 0.0)"
|
||||
+ " gl_FragColor = vec4(z + 1.0, 0.0, 0.0, 1.0)*0.8;"
|
||||
+ "else if (z < 1.0)"
|
||||
+ " gl_FragColor = vec4(0.0, 0.0, z, 1.0)*0.8;"
|
||||
+ "else"
|
||||
+ " gl_FragColor = vec4(0.0, z - 1.0, 0.0, 1.0)*0.8;"
|
||||
+ "}";
|
||||
|
||||
private final static String textureVertexShader = ""
|
||||
+ "precision mediump float;"
|
||||
+ "uniform mat4 u_mvp;"
|
||||
+ "uniform vec2 u_scale;"
|
||||
+ "attribute vec4 a_pos;"
|
||||
+ "varying vec2 v_st;"
|
||||
+ "varying vec2 v_st2;"
|
||||
+ "void main() {"
|
||||
+ " v_st = clamp(a_pos.xy, 0.0, 1.0) * (2.0 / u_scale.y);"
|
||||
+ " v_st2 = clamp(a_pos.xy, 0.0, 1.0) * (4.0 / u_scale.y);"
|
||||
+ " gl_Position = u_mvp * a_pos;"
|
||||
+ "}";
|
||||
|
||||
private final static String textureFragmentShader = ""
|
||||
+ "precision mediump float;"
|
||||
+ "uniform vec4 u_color;"
|
||||
+ "uniform sampler2D tex;"
|
||||
+ "uniform vec2 u_scale;"
|
||||
+ "varying vec2 v_st;"
|
||||
+ "varying vec2 v_st2;"
|
||||
+ "void main() {"
|
||||
+ " gl_FragColor = mix(texture2D(tex, v_st), texture2D(tex, v_st2), u_scale.x);"
|
||||
+ "}";
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -21,8 +21,8 @@ import static org.oscim.renderer.MapRenderer.COORD_SCALE;
|
||||
import java.nio.ShortBuffer;
|
||||
|
||||
import org.oscim.backend.GL20;
|
||||
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.renderer.elements.TextureItem.TexturePool;
|
||||
@ -113,56 +113,60 @@ public abstract class TextureLayer extends RenderElement {
|
||||
buf[pos + 23] = v1;
|
||||
}
|
||||
|
||||
static class Shader extends GLShader {
|
||||
int uMV, uProj, uScale, uTexSize, aPos, aTexCoord;
|
||||
|
||||
Shader() {
|
||||
if (!create("texture_layer"))
|
||||
return;
|
||||
uMV = getUniform("u_mv");
|
||||
uProj = getUniform("u_proj");
|
||||
uScale = getUniform("u_scale");
|
||||
uTexSize = getUniform("u_div");
|
||||
aPos = getAttrib("vertex");
|
||||
aTexCoord = getAttrib("tex_coord");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean useProgram() {
|
||||
if (super.useProgram()) {
|
||||
GLState.enableVertexArrays(aPos, aTexCoord);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static final class Renderer {
|
||||
|
||||
public final static boolean debug = false;
|
||||
|
||||
private static int mTextureProgram;
|
||||
private static int hTextureMVMatrix;
|
||||
private static int hTextureProjMatrix;
|
||||
private static int hTextureVertex;
|
||||
private static int hTextureScale;
|
||||
private static int hTextureTexCoord;
|
||||
private static int hTextureSize;
|
||||
private static Shader shader;
|
||||
|
||||
static void init() {
|
||||
mTextureProgram = GLUtils.createProgram(textVertexShader,
|
||||
textFragmentShader);
|
||||
|
||||
hTextureMVMatrix = GL.glGetUniformLocation(mTextureProgram, "u_mv");
|
||||
hTextureProjMatrix = GL.glGetUniformLocation(mTextureProgram, "u_proj");
|
||||
hTextureScale = GL.glGetUniformLocation(mTextureProgram, "u_scale");
|
||||
hTextureSize = GL.glGetUniformLocation(mTextureProgram, "u_div");
|
||||
hTextureVertex = GL.glGetAttribLocation(mTextureProgram, "vertex");
|
||||
hTextureTexCoord = GL.glGetAttribLocation(mTextureProgram, "tex_coord");
|
||||
shader = new Shader();
|
||||
|
||||
/* FIXME pool should be disposed on exit... */
|
||||
pool.init(0);
|
||||
}
|
||||
|
||||
public static RenderElement draw(RenderElement l, GLViewport v, float scale) {
|
||||
shader.useProgram();
|
||||
|
||||
GLState.test(false, false);
|
||||
GLState.blend(true);
|
||||
|
||||
GLState.useProgram(mTextureProgram);
|
||||
|
||||
GLState.enableVertexArrays(hTextureTexCoord, hTextureVertex);
|
||||
|
||||
TextureLayer tl = (TextureLayer) l;
|
||||
|
||||
if (tl.fixed)
|
||||
GL.glUniform1f(hTextureScale, 1 / scale);
|
||||
else
|
||||
GL.glUniform1f(hTextureScale, 1);
|
||||
GL.glUniform1f(shader.uScale, tl.fixed ? 1 / scale : 1);
|
||||
|
||||
v.proj.setAsUniform(hTextureProjMatrix);
|
||||
v.mvp.setAsUniform(hTextureMVMatrix);
|
||||
v.proj.setAsUniform(shader.uProj);
|
||||
v.mvp.setAsUniform(shader.uMV);
|
||||
|
||||
MapRenderer.bindQuadIndicesVBO(true);
|
||||
|
||||
for (TextureItem t = tl.textures; t != null; t = t.next) {
|
||||
GL.glUniform2f(hTextureSize,
|
||||
GL.glUniform2f(shader.uTexSize,
|
||||
1f / (t.width * COORD_SCALE),
|
||||
1f / (t.height * COORD_SCALE));
|
||||
t.bind();
|
||||
@ -175,10 +179,10 @@ public abstract class TextureLayer extends RenderElement {
|
||||
* / 6(indices) == 8) */
|
||||
int off = (t.offset + i) * 8 + tl.offset;
|
||||
|
||||
GL.glVertexAttribPointer(hTextureVertex, 4,
|
||||
GL.glVertexAttribPointer(shader.aPos, 4,
|
||||
GL20.GL_SHORT, false, 12, off);
|
||||
|
||||
GL.glVertexAttribPointer(hTextureTexCoord, 2,
|
||||
GL.glVertexAttribPointer(shader.aTexCoord, 2,
|
||||
GL20.GL_SHORT, false, 12, off + 8);
|
||||
|
||||
int numVertices = t.vertices - i;
|
||||
@ -194,38 +198,5 @@ public abstract class TextureLayer extends RenderElement {
|
||||
|
||||
return l.next;
|
||||
}
|
||||
|
||||
private final static double COORD_DIV = 1.0 / MapRenderer.COORD_SCALE;
|
||||
|
||||
private final static String textVertexShader = ""
|
||||
+ "precision highp float;"
|
||||
+ "attribute vec4 vertex;"
|
||||
+ "attribute vec2 tex_coord;"
|
||||
+ "uniform mat4 u_mv;"
|
||||
+ "uniform mat4 u_proj;"
|
||||
+ "uniform float u_scale;"
|
||||
+ "uniform vec2 u_div;"
|
||||
+ "varying vec2 tex_c;"
|
||||
+ "const float coord_scale = " + COORD_DIV + ";"
|
||||
+ "void main() {"
|
||||
+ " vec4 pos;"
|
||||
+ " vec2 dir = vertex.zw;"
|
||||
+ " if (mod(vertex.x, 2.0) == 0.0){"
|
||||
+ " pos = u_proj * (u_mv * vec4(vertex.xy + dir * u_scale, 0.0, 1.0));"
|
||||
+ " } else {" // place as billboard
|
||||
+ " vec4 center = u_mv * vec4(vertex.xy, 0.0, 1.0);"
|
||||
+ " pos = u_proj * (center + vec4(dir * coord_scale, 0.0, 0.0));"
|
||||
+ " }"
|
||||
+ " gl_Position = pos;"
|
||||
+ " tex_c = tex_coord * u_div;"
|
||||
+ "}";
|
||||
|
||||
private final static String textFragmentShader = ""
|
||||
+ "precision highp float;"
|
||||
+ "uniform sampler2D tex;"
|
||||
+ "varying vec2 tex_c;"
|
||||
+ "void main() {"
|
||||
+ " gl_FragColor = texture2D(tex, tex_c.xy);"
|
||||
+ "}";
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user