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-android-example/assets/
|
||||||
/vtm-gdx-desktop/assets/
|
/vtm-gdx-desktop/assets/
|
||||||
/vtm-gdx-html/war/
|
/vtm-gdx-html/war/
|
||||||
|
/vtm-gdx-html/assets/
|
||||||
/vtm-gdx-html/gwt-unitCache
|
/vtm-gdx-html/gwt-unitCache
|
||||||
/vtm-spatialite/
|
/vtm-spatialite/
|
||||||
/vtm-spatialite-android/
|
/vtm-spatialite-android/
|
||||||
|
@ -43,6 +43,11 @@ gwt {
|
|||||||
superDev {
|
superDev {
|
||||||
noPrecompile=true
|
noPrecompile=true
|
||||||
}
|
}
|
||||||
|
compiler {
|
||||||
|
enableClosureCompiler = false; // activates -XenableClosureCompiler
|
||||||
|
disableClassMetadata = true; // activates -XdisableClassMetadata
|
||||||
|
disableCastChecking = true; // activates -XdisableCastChecking
|
||||||
|
}
|
||||||
|
|
||||||
src += files(sourceSets.main.java.srcDirs)
|
src += files(sourceSets.main.java.srcDirs)
|
||||||
src += files(project(':vtm').sourceSets.main.allJava.srcDirs)
|
src += files(project(':vtm').sourceSets.main.allJava.srcDirs)
|
||||||
@ -58,6 +63,23 @@ task jettyDraftWar(type: JettyRunWar) {
|
|||||||
webApp=draftWar.archivePath
|
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
|
// Configuring Eclipse classpath
|
||||||
eclipse.classpath {
|
eclipse.classpath {
|
||||||
|
|
||||||
|
@ -21,7 +21,7 @@
|
|||||||
|
|
||||||
<super-source path="emu" />
|
<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 -->
|
<!-- for gradle build, commend out for eclipse build/devmode -->
|
||||||
<set-configuration-property name="gdx.assetoutputpath" value="build/gwt/draftOut" />
|
<set-configuration-property name="gdx.assetoutputpath" value="build/gwt/draftOut" />
|
||||||
|
|
||||||
|
@ -16,6 +16,8 @@
|
|||||||
*/
|
*/
|
||||||
package org.oscim.gdx.client;
|
package org.oscim.gdx.client;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
|
||||||
import org.oscim.backend.CanvasAdapter;
|
import org.oscim.backend.CanvasAdapter;
|
||||||
import org.oscim.backend.GL20;
|
import org.oscim.backend.GL20;
|
||||||
import org.oscim.backend.GLAdapter;
|
import org.oscim.backend.GLAdapter;
|
||||||
@ -23,9 +25,14 @@ import org.oscim.core.MapPosition;
|
|||||||
import org.oscim.core.MercatorProjection;
|
import org.oscim.core.MercatorProjection;
|
||||||
import org.oscim.gdx.GdxMap;
|
import org.oscim.gdx.GdxMap;
|
||||||
import org.oscim.layers.tile.bitmap.BitmapTileLayer;
|
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.renderer.MapRenderer;
|
||||||
|
import org.oscim.theme.VtmThemes;
|
||||||
import org.oscim.tiling.TileSource;
|
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.oscim.tiling.source.oscimap4.OSciMap4TileSource;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
@ -66,14 +73,20 @@ class GwtGdxMap extends GdxMap {
|
|||||||
|
|
||||||
float tilt = 0;
|
float tilt = 0;
|
||||||
float rotation = 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) {
|
if (Window.Location.getHash() != null) {
|
||||||
String hash = Window.Location.getHash();
|
String hash = Window.Location.getHash();
|
||||||
|
|
||||||
hash = hash.substring(1);
|
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 {
|
try {
|
||||||
if (p.startsWith("lat="))
|
if (p.startsWith("lat="))
|
||||||
lat = Double.parseDouble(p.substring(4));
|
lat = Double.parseDouble(p.substring(4));
|
||||||
@ -85,33 +98,82 @@ class GwtGdxMap extends GdxMap {
|
|||||||
rotation = Float.parseFloat(p.substring(4));
|
rotation = Float.parseFloat(p.substring(4));
|
||||||
else if (p.startsWith("tilt="))
|
else if (p.startsWith("tilt="))
|
||||||
tilt = Float.parseFloat(p.substring(5));
|
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) {
|
} catch (NumberFormatException e) {
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final String addParam =
|
||||||
|
(themeName == null ? "" : ("theme=" + themeName + "&"))
|
||||||
|
+ (mapName == null ? "" : ("map=" + mapName + "&"))
|
||||||
|
+ addOpts;
|
||||||
|
|
||||||
MapPosition p = new MapPosition();
|
MapPosition p = new MapPosition();
|
||||||
p.setZoomLevel(zoom);
|
p.setZoomLevel(zoom);
|
||||||
p.setPosition(lat, lon);
|
p.setPosition(lat, lon);
|
||||||
log.debug("map position: " + p.x + "/" + p.y + " " + lat + "/" + lon);
|
|
||||||
|
|
||||||
p.bearing = rotation;
|
p.bearing = rotation;
|
||||||
p.tilt = tilt;
|
p.tilt = tilt;
|
||||||
|
|
||||||
mMap.setMapPosition(p);
|
mMap.setMapPosition(p);
|
||||||
|
|
||||||
//mMap.getViewport().setTilt(tilt);
|
VectorTileLayer l = null;
|
||||||
//mMap.getViewport().setRotation(rotation);
|
|
||||||
|
|
||||||
|
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 url = c.getTileUrl();
|
||||||
String sourceName = c.getTileSource();
|
|
||||||
|
|
||||||
TileSource tileSource;
|
TileSource ts = new OSciMap4TileSource(url);
|
||||||
tileSource = 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()))
|
if (l != null) {
|
||||||
mMap.setBackgroundMap(new BitmapTileLayer(mMap, new NaturalEarth()));
|
if (!params.containsKey("nolabel"))
|
||||||
|
mMap.layers().add(new LabelLayer(mMap, l));
|
||||||
|
}
|
||||||
|
|
||||||
mSearchBox = new SearchBox(mMap);
|
mSearchBox = new SearchBox(mMap);
|
||||||
|
|
||||||
@ -139,9 +201,12 @@ class GwtGdxMap extends GdxMap {
|
|||||||
|
|
||||||
String newURL = Window.Location
|
String newURL = Window.Location
|
||||||
.createUrlBuilder()
|
.createUrlBuilder()
|
||||||
.setHash("scale=" + pos.zoomLevel + ",rot=" + curRot
|
.setHash(addParam
|
||||||
+ ",tilt=" + curTilt + ",lat=" + (curLat / 1000f)
|
+ "scale=" + pos.zoomLevel
|
||||||
+ ",lon=" + (curLon / 1000f))
|
+ "&rot=" + curRot
|
||||||
|
+ "&tilt=" + curTilt
|
||||||
|
+ "&lat=" + (curLat / 1000f)
|
||||||
|
+ "&lon=" + (curLon / 1000f))
|
||||||
.buildString();
|
.buildString();
|
||||||
Window.Location.replace(newURL);
|
Window.Location.replace(newURL);
|
||||||
}
|
}
|
||||||
|
@ -73,7 +73,13 @@ public class GwtGraphics implements Graphics {
|
|||||||
context.viewport(0, 0, config.width, config.height);
|
context.viewport(0, 0, config.width, config.height);
|
||||||
|
|
||||||
// this actually *enables* the option to use std derivatives in shader..
|
// 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);
|
this.gl = config.useDebugGL ? new GwtGL20Debug(context) : new GwtGLAdapter(context);
|
||||||
canvas.setId("gdx-canvas");
|
canvas.setId("gdx-canvas");
|
||||||
|
@ -35,6 +35,7 @@ public class GdxAssetAdapter extends AssetAdapter {
|
|||||||
try {
|
try {
|
||||||
return file.read();
|
return file.read();
|
||||||
} catch (GdxRuntimeException e) {
|
} catch (GdxRuntimeException e) {
|
||||||
|
e.printStackTrace();
|
||||||
return null;
|
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;
|
package org.oscim.backend;
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The Class AssetAdapter.
|
* The Class AssetAdapter.
|
||||||
@ -33,4 +36,25 @@ public abstract class AssetAdapter {
|
|||||||
* @return the input stream
|
* @return the input stream
|
||||||
*/
|
*/
|
||||||
public abstract InputStream openFileAsStream(String name);
|
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++) {
|
for (int i = 0; i <= SHADER; i++) {
|
||||||
if (i == 0) {
|
if (i == 0) {
|
||||||
shaderProgram[i] = GLUtils.createProgram(extrusionVertexShader,
|
shaderProgram[i] = GLShader.createProgram(extrusionVertexShader,
|
||||||
extrusionFragmentShader);
|
extrusionFragmentShader);
|
||||||
} else {
|
} else {
|
||||||
shaderProgram[i] = GLUtils.createProgram(extrusionVertexShader,
|
shaderProgram[i] = GLShader.createProgram(extrusionVertexShader,
|
||||||
extrusionFragmentShaderZ);
|
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);
|
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) {
|
public static void checkGlError(String op) {
|
||||||
//GL = GLAdapter.get();
|
//GL = GLAdapter.get();
|
||||||
|
|
||||||
|
@ -324,6 +324,7 @@ public class MapRenderer {
|
|||||||
|
|
||||||
GLState.init(GL);
|
GLState.init(GL);
|
||||||
GLUtils.init(GL);
|
GLUtils.init(GL);
|
||||||
|
GLShader.GL = GL;
|
||||||
|
|
||||||
// Set up some vertex buffer objects
|
// Set up some vertex buffer objects
|
||||||
BufferObject.init(GL, 200);
|
BufferObject.init(GL, 200);
|
||||||
|
@ -20,8 +20,8 @@ import java.nio.ShortBuffer;
|
|||||||
|
|
||||||
import org.oscim.backend.GL20;
|
import org.oscim.backend.GL20;
|
||||||
import org.oscim.backend.canvas.Bitmap;
|
import org.oscim.backend.canvas.Bitmap;
|
||||||
|
import org.oscim.renderer.GLShader;
|
||||||
import org.oscim.renderer.GLState;
|
import org.oscim.renderer.GLState;
|
||||||
import org.oscim.renderer.GLUtils;
|
|
||||||
import org.oscim.renderer.GLViewport;
|
import org.oscim.renderer.GLViewport;
|
||||||
import org.oscim.renderer.MapRenderer;
|
import org.oscim.renderer.MapRenderer;
|
||||||
import org.oscim.renderer.elements.TextureItem.TexturePool;
|
import org.oscim.renderer.elements.TextureItem.TexturePool;
|
||||||
@ -164,57 +164,50 @@ public class BitmapLayer extends TextureLayer {
|
|||||||
//textures = null;
|
//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 {
|
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;
|
public final static int INDICES_PER_SPRITE = 6;
|
||||||
final static int VERTICES_PER_SPRITE = 4;
|
final static int VERTICES_PER_SPRITE = 4;
|
||||||
final static int SHORTS_PER_VERTICE = 6;
|
final static int SHORTS_PER_VERTICE = 6;
|
||||||
|
static Shader shader;
|
||||||
|
|
||||||
static void init() {
|
static void init() {
|
||||||
mTextureProgram = GLUtils.createProgram(textVertexShader,
|
shader = new Shader("texture_alpha");
|
||||||
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");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static RenderElement draw(RenderElement renderElement, GLViewport v, float scale,
|
public static RenderElement draw(RenderElement renderElement, GLViewport v,
|
||||||
float alpha) {
|
float scale, float alpha) {
|
||||||
//GLState.test(false, false);
|
|
||||||
GLState.blend(true);
|
GLState.blend(true);
|
||||||
|
Shader s = shader;
|
||||||
GLState.useProgram(mTextureProgram);
|
s.useProgram();
|
||||||
|
|
||||||
GLState.enableVertexArrays(hTextureTexCoord, hTextureVertex);
|
|
||||||
|
|
||||||
TextureLayer tl = (TextureLayer) renderElement;
|
TextureLayer tl = (TextureLayer) renderElement;
|
||||||
|
|
||||||
if (tl.fixed)
|
GL.glUniform1f(s.uAlpha, alpha);
|
||||||
GL.glUniform1f(hTextureScale, (float) Math.sqrt(scale));
|
v.mvp.setAsUniform(s.uMVP);
|
||||||
else
|
|
||||||
GL.glUniform1f(hTextureScale, 1);
|
|
||||||
|
|
||||||
GL.glUniform1f(hTextureScreenScale, 1f / v.getWidth());
|
|
||||||
GL.glUniform1f(hAlpha, alpha);
|
|
||||||
|
|
||||||
v.proj.setAsUniform(hTextureProjMatrix);
|
|
||||||
|
|
||||||
v.mvp.setAsUniform(hTextureMVMatrix);
|
|
||||||
|
|
||||||
MapRenderer.bindQuadIndicesVBO(true);
|
MapRenderer.bindQuadIndicesVBO(true);
|
||||||
|
|
||||||
@ -229,10 +222,10 @@ public class BitmapLayer extends TextureLayer {
|
|||||||
// to.offset * (24(shorts) * 2(short-bytes) / 6(indices) == 8)
|
// to.offset * (24(shorts) * 2(short-bytes) / 6(indices) == 8)
|
||||||
int off = (t.offset + i) * 8 + tl.offset;
|
int off = (t.offset + i) * 8 + tl.offset;
|
||||||
|
|
||||||
GL.glVertexAttribPointer(hTextureVertex, 4,
|
GL.glVertexAttribPointer(s.aPos, 2,
|
||||||
GL20.GL_SHORT, false, 12, off);
|
GL20.GL_SHORT, false, 12, off);
|
||||||
|
|
||||||
GL.glVertexAttribPointer(hTextureTexCoord, 2,
|
GL.glVertexAttribPointer(s.aTexCoord, 2,
|
||||||
GL20.GL_SHORT, false, 12, off + 8);
|
GL20.GL_SHORT, false, 12, off + 8);
|
||||||
|
|
||||||
int numVertices = t.vertices - i;
|
int numVertices = t.vertices - i;
|
||||||
@ -248,26 +241,5 @@ public class BitmapLayer extends TextureLayer {
|
|||||||
|
|
||||||
return renderElement.next;
|
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.GeometryBuffer;
|
||||||
import org.oscim.core.MercatorProjection;
|
import org.oscim.core.MercatorProjection;
|
||||||
import org.oscim.core.Tile;
|
import org.oscim.core.Tile;
|
||||||
|
import org.oscim.renderer.GLShader;
|
||||||
import org.oscim.renderer.GLState;
|
import org.oscim.renderer.GLState;
|
||||||
import org.oscim.renderer.GLUtils;
|
import org.oscim.renderer.GLUtils;
|
||||||
import org.oscim.renderer.GLViewport;
|
import org.oscim.renderer.GLViewport;
|
||||||
@ -614,6 +615,31 @@ public final class LineLayer extends RenderElement {
|
|||||||
return vertexItem;
|
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 {
|
public static final class Renderer {
|
||||||
/* TODO:
|
/* TODO:
|
||||||
* http://http.developer.nvidia.com/GPUGems2/gpugems2_chapter22.html */
|
* 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_FLAT = 1;
|
||||||
private final static int SHADER_PROJ = 0;
|
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;
|
public static int mTexID;
|
||||||
|
private static Shader[] shaders = { null, null };
|
||||||
|
|
||||||
static boolean init() {
|
static boolean init() {
|
||||||
|
|
||||||
lineProgram[0] = GLUtils.createProgram(lineVertexShader,
|
shaders[0] = new Shader("line_aa_proj");
|
||||||
lineFragmentShader);
|
shaders[1] = new Shader("line_aa");
|
||||||
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");
|
|
||||||
}
|
|
||||||
|
|
||||||
/* create lookup table as texture for 'length(0..1,0..1)'
|
/* create lookup table as texture for 'length(0..1,0..1)'
|
||||||
* using mirrored wrap mode for 'length(-1..1,-1..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. */
|
* account. only used when tilt is 0. */
|
||||||
int mode = v.pos.tilt < 1 ? 1 : 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);
|
GLState.blend(true);
|
||||||
|
|
||||||
/* Somehow we loose the texture after an indefinite
|
/* Somehow we loose the texture after an indefinite
|
||||||
@ -712,18 +708,16 @@ public final class LineLayer extends RenderElement {
|
|||||||
if (!GLAdapter.GDX_DESKTOP_QUIRKS)
|
if (!GLAdapter.GDX_DESKTOP_QUIRKS)
|
||||||
GLState.bindTex2D(mTexID);
|
GLState.bindTex2D(mTexID);
|
||||||
|
|
||||||
int uLineFade = hLineFade[mode];
|
int uLineFade = s.uFade;
|
||||||
int uLineMode = hLineMode[mode];
|
int uLineMode = s.uMode;
|
||||||
int uLineColor = hLineColor[mode];
|
int uLineColor = s.uColor;
|
||||||
int uLineWidth = hLineWidth[mode];
|
int uLineWidth = s.uWidth;
|
||||||
int uLineHeight = hLineHeight[mode];
|
int uLineHeight = s.uHeight;
|
||||||
|
|
||||||
GLState.enableVertexArrays(hLineVertexPosition[mode], -1);
|
GL.glVertexAttribPointer(s.aPos, 4, GL20.GL_SHORT,
|
||||||
|
|
||||||
GL.glVertexAttribPointer(hLineVertexPosition[mode], 4, GL20.GL_SHORT,
|
|
||||||
false, 0, layers.offset[LINE]);
|
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-
|
/* Line scale factor for non fixed lines: Within a zoom-
|
||||||
* level lines would be scaled by the factor 2 by view-matrix.
|
* level lines would be scaled by the factor 2 by view-matrix.
|
||||||
@ -865,130 +859,5 @@ public final class LineLayer extends RenderElement {
|
|||||||
|
|
||||||
return l;
|
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.backend.GL20;
|
||||||
import org.oscim.core.GeometryBuffer;
|
import org.oscim.core.GeometryBuffer;
|
||||||
|
import org.oscim.renderer.GLShader;
|
||||||
import org.oscim.renderer.GLState;
|
import org.oscim.renderer.GLState;
|
||||||
import org.oscim.renderer.GLUtils;
|
import org.oscim.renderer.GLUtils;
|
||||||
import org.oscim.renderer.GLViewport;
|
import org.oscim.renderer.GLViewport;
|
||||||
@ -250,49 +251,45 @@ public final class LineTexLayer extends RenderElement {
|
|||||||
sbuf.position(sbuf.position() + 6);
|
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 {
|
public final static class Renderer {
|
||||||
|
private static Shader shader;
|
||||||
|
|
||||||
/* factor to normalize extrusion vector and scale to coord scale */
|
/* factor to normalize extrusion vector and scale to coord scale */
|
||||||
private final static float COORD_SCALE_BY_DIR_SCALE =
|
private final static float COORD_SCALE_BY_DIR_SCALE =
|
||||||
MapRenderer.COORD_SCALE / LineLayer.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;
|
private static int mVertexFlipID;
|
||||||
|
|
||||||
public static void init() {
|
public static void init() {
|
||||||
|
|
||||||
shader = GLUtils.createProgram(vertexShader, fragmentShader);
|
shader = new Shader("linetex_layer");
|
||||||
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");
|
|
||||||
|
|
||||||
int[] vboIds = GLUtils.glGenBuffers(1);
|
int[] vboIds = GLUtils.glGenBuffers(1);
|
||||||
mVertexFlipID = vboIds[0];
|
mVertexFlipID = vboIds[0];
|
||||||
@ -327,28 +324,35 @@ public final class LineTexLayer extends RenderElement {
|
|||||||
public static RenderElement draw(RenderElement curLayer, GLViewport v,
|
public static RenderElement draw(RenderElement curLayer, GLViewport v,
|
||||||
float div, ElementLayers layers) {
|
float div, ElementLayers layers) {
|
||||||
|
|
||||||
if (shader == 0)
|
//if (shader == 0)
|
||||||
return curLayer.next;
|
// return curLayer.next;
|
||||||
|
|
||||||
GLState.blend(true);
|
GLState.blend(true);
|
||||||
GLState.useProgram(shader);
|
//GLState.useProgram(shader);
|
||||||
|
shader.useProgram();
|
||||||
|
|
||||||
GLState.enableVertexArrays(-1, -1);
|
GLState.enableVertexArrays(-1, -1);
|
||||||
|
|
||||||
GL.glEnableVertexAttribArray(hVertexPosition0);
|
int aLen0 = shader.aLen0;
|
||||||
GL.glEnableVertexAttribArray(hVertexPosition1);
|
int aLen1 = shader.aLen1;
|
||||||
GL.glEnableVertexAttribArray(hVertexLength0);
|
int aPos0 = shader.aPos0;
|
||||||
GL.glEnableVertexAttribArray(hVertexLength1);
|
int aPos1 = shader.aPos1;
|
||||||
GL.glEnableVertexAttribArray(hVertexFlip);
|
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;
|
int maxIndices = MapRenderer.maxQuads * 6;
|
||||||
|
|
||||||
MapRenderer.bindQuadIndicesVBO(true);
|
MapRenderer.bindQuadIndicesVBO(true);
|
||||||
|
|
||||||
GL.glBindBuffer(GL20.GL_ARRAY_BUFFER, mVertexFlipID);
|
GL.glBindBuffer(GL20.GL_ARRAY_BUFFER, mVertexFlipID);
|
||||||
GL.glVertexAttribPointer(hVertexFlip, 1,
|
GL.glVertexAttribPointer(shader.aFlip, 1,
|
||||||
GL20.GL_BYTE, false, 0, 0);
|
GL20.GL_BYTE, false, 0, 0);
|
||||||
|
|
||||||
layers.vbo.bind();
|
layers.vbo.bind();
|
||||||
@ -364,19 +368,21 @@ public final class LineTexLayer extends RenderElement {
|
|||||||
LineTexLayer ll = (LineTexLayer) l;
|
LineTexLayer ll = (LineTexLayer) l;
|
||||||
LineStyle line = ll.line.current();
|
LineStyle line = ll.line.current();
|
||||||
|
|
||||||
GLUtils.setColor(hTexColor, line.stippleColor, 1);
|
GLUtils.setColor(shader.uColor, line.stippleColor, 1);
|
||||||
GLUtils.setColor(hBgColor, line.color, 1);
|
GLUtils.setColor(shader.uBgColor, line.color, 1);
|
||||||
|
|
||||||
float pScale = (int) (s + 0.5f);
|
float pScale = (int) (s + 0.5f);
|
||||||
if (pScale < 1)
|
if (pScale < 1)
|
||||||
pScale = 1;
|
pScale = 1;
|
||||||
|
|
||||||
GL.glUniform1f(hPatternScale, (MapRenderer.COORD_SCALE * line.stipple) / pScale);
|
GL.glUniform1f(shader.uPatternScale,
|
||||||
GL.glUniform1f(hPatternWidth, line.stippleWidth);
|
(MapRenderer.COORD_SCALE * line.stipple) / pScale);
|
||||||
|
|
||||||
|
GL.glUniform1f(shader.uPatternWidth, line.stippleWidth);
|
||||||
//GL.glUniform1f(hScale, scale);
|
//GL.glUniform1f(hScale, scale);
|
||||||
|
|
||||||
/* keep line width fixed */
|
/* 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 */
|
/* add offset vertex */
|
||||||
int vOffset = -STRIDE;
|
int vOffset = -STRIDE;
|
||||||
@ -392,20 +398,16 @@ public final class LineTexLayer extends RenderElement {
|
|||||||
/* i / 6 * (24 shorts per block * 2 short bytes) */
|
/* i / 6 * (24 shorts per block * 2 short bytes) */
|
||||||
int add = (l.offset + i * 8) + vOffset;
|
int add = (l.offset + i * 8) + vOffset;
|
||||||
|
|
||||||
GL.glVertexAttribPointer(hVertexPosition0,
|
GL.glVertexAttribPointer(aPos0, 4, GL20.GL_SHORT, false, STRIDE,
|
||||||
4, GL20.GL_SHORT, false, STRIDE,
|
|
||||||
add + STRIDE);
|
add + STRIDE);
|
||||||
|
|
||||||
GL.glVertexAttribPointer(hVertexLength0,
|
GL.glVertexAttribPointer(aLen0, 2, GL20.GL_SHORT, false, STRIDE,
|
||||||
2, GL20.GL_SHORT, false, STRIDE,
|
|
||||||
add + STRIDE + LEN_OFFSET);
|
add + STRIDE + LEN_OFFSET);
|
||||||
|
|
||||||
GL.glVertexAttribPointer(hVertexPosition1,
|
GL.glVertexAttribPointer(aPos1, 4, GL20.GL_SHORT, false, STRIDE,
|
||||||
4, GL20.GL_SHORT, false, STRIDE,
|
|
||||||
add);
|
add);
|
||||||
|
|
||||||
GL.glVertexAttribPointer(hVertexLength1,
|
GL.glVertexAttribPointer(aLen1, 2, GL20.GL_SHORT, false, STRIDE,
|
||||||
2, GL20.GL_SHORT, false, STRIDE,
|
|
||||||
add + LEN_OFFSET);
|
add + LEN_OFFSET);
|
||||||
|
|
||||||
GL.glDrawElements(GL20.GL_TRIANGLES, numIndices,
|
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) */
|
/* i / 6 * (24 shorts per block * 2 short bytes) */
|
||||||
int add = (l.offset + i * 8) + vOffset;
|
int add = (l.offset + i * 8) + vOffset;
|
||||||
|
|
||||||
GL.glVertexAttribPointer(hVertexPosition0,
|
GL.glVertexAttribPointer(aPos0, 4, GL20.GL_SHORT, false, STRIDE,
|
||||||
4, GL20.GL_SHORT, false, STRIDE,
|
|
||||||
add + 2 * STRIDE);
|
add + 2 * STRIDE);
|
||||||
|
|
||||||
GL.glVertexAttribPointer(hVertexLength0,
|
GL.glVertexAttribPointer(aLen0, 2, GL20.GL_SHORT, false, STRIDE,
|
||||||
2, GL20.GL_SHORT, false, STRIDE,
|
|
||||||
add + 2 * STRIDE + LEN_OFFSET);
|
add + 2 * STRIDE + LEN_OFFSET);
|
||||||
|
|
||||||
GL.glVertexAttribPointer(hVertexPosition1,
|
GL.glVertexAttribPointer(aPos1, 4, GL20.GL_SHORT, false, STRIDE,
|
||||||
4, GL20.GL_SHORT, false, STRIDE,
|
|
||||||
add + STRIDE);
|
add + STRIDE);
|
||||||
|
|
||||||
GL.glVertexAttribPointer(hVertexLength1,
|
GL.glVertexAttribPointer(aLen1, 2, GL20.GL_SHORT, false, STRIDE,
|
||||||
2, GL20.GL_SHORT, false, STRIDE,
|
|
||||||
add + STRIDE + LEN_OFFSET);
|
add + STRIDE + LEN_OFFSET);
|
||||||
|
|
||||||
GL.glDrawElements(GL20.GL_TRIANGLES, numIndices,
|
GL.glDrawElements(GL20.GL_TRIANGLES, numIndices,
|
||||||
@ -445,107 +443,15 @@ public final class LineTexLayer extends RenderElement {
|
|||||||
|
|
||||||
MapRenderer.bindQuadIndicesVBO(false);
|
MapRenderer.bindQuadIndicesVBO(false);
|
||||||
|
|
||||||
GL.glDisableVertexAttribArray(hVertexPosition0);
|
GL.glDisableVertexAttribArray(aPos0);
|
||||||
GL.glDisableVertexAttribArray(hVertexPosition1);
|
GL.glDisableVertexAttribArray(aPos1);
|
||||||
GL.glDisableVertexAttribArray(hVertexLength0);
|
GL.glDisableVertexAttribArray(aLen0);
|
||||||
GL.glDisableVertexAttribArray(hVertexLength1);
|
GL.glDisableVertexAttribArray(aLen1);
|
||||||
GL.glDisableVertexAttribArray(hVertexFlip);
|
GL.glDisableVertexAttribArray(aFlip);
|
||||||
|
|
||||||
//GL.glBindTexture(GL20.GL_TEXTURE_2D, 0);
|
//GL.glBindTexture(GL20.GL_TEXTURE_2D, 0);
|
||||||
|
|
||||||
return l;
|
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.GeometryBuffer;
|
||||||
import org.oscim.core.MercatorProjection;
|
import org.oscim.core.MercatorProjection;
|
||||||
import org.oscim.renderer.BufferObject;
|
import org.oscim.renderer.BufferObject;
|
||||||
|
import org.oscim.renderer.GLShader;
|
||||||
import org.oscim.renderer.GLState;
|
import org.oscim.renderer.GLState;
|
||||||
import org.oscim.renderer.GLUtils;
|
import org.oscim.renderer.GLUtils;
|
||||||
import org.oscim.renderer.GLViewport;
|
import org.oscim.renderer.GLViewport;
|
||||||
@ -104,36 +105,38 @@ public class MeshLayer extends RenderElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static class Renderer {
|
public static class Renderer {
|
||||||
private static int shaderProgram;
|
static Shader shader;
|
||||||
private static int hMatrix;
|
|
||||||
private static int hColor;
|
|
||||||
private static int hHeightOffset;
|
|
||||||
private static int hVertexPosition;
|
|
||||||
|
|
||||||
static boolean init() {
|
static boolean init() {
|
||||||
shaderProgram = GLUtils.createProgram(vertexShader, fragmentShader);
|
shader = new Shader("mesh_layer_2D");
|
||||||
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");
|
|
||||||
return true;
|
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.blend(true);
|
||||||
|
|
||||||
GLState.useProgram(shaderProgram);
|
Shader s = shader;
|
||||||
|
s.useProgram();
|
||||||
|
GLState.enableVertexArrays(s.aPos, -1);
|
||||||
|
|
||||||
GLState.enableVertexArrays(hVertexPosition, -1);
|
v.mvp.setAsUniform(s.uMVP);
|
||||||
|
|
||||||
v.mvp.setAsUniform(hMatrix);
|
|
||||||
|
|
||||||
float heightOffset = 0;
|
float heightOffset = 0;
|
||||||
GL.glUniform1f(hHeightOffset, heightOffset);
|
GL.glUniform1f(s.uHeight, heightOffset);
|
||||||
|
|
||||||
for (; l != null && l.type == RenderElement.MESH; l = l.next) {
|
for (; l != null && l.type == RenderElement.MESH; l = l.next) {
|
||||||
MeshLayer ml = (MeshLayer) l;
|
MeshLayer ml = (MeshLayer) l;
|
||||||
@ -144,25 +147,25 @@ public class MeshLayer extends RenderElement {
|
|||||||
if (ml.heightOffset != heightOffset) {
|
if (ml.heightOffset != heightOffset) {
|
||||||
heightOffset = ml.heightOffset;
|
heightOffset = ml.heightOffset;
|
||||||
|
|
||||||
GL.glUniform1f(hHeightOffset, heightOffset /
|
GL.glUniform1f(s.uHeight, heightOffset /
|
||||||
MercatorProjection.groundResolution(v.pos));
|
MercatorProjection.groundResolution(v.pos));
|
||||||
}
|
}
|
||||||
|
|
||||||
ml.indicesVbo.bind();
|
ml.indicesVbo.bind();
|
||||||
|
|
||||||
if (ml.area == null)
|
if (ml.area == null)
|
||||||
GLUtils.setColor(hColor, Color.BLUE, 0.4f);
|
GLUtils.setColor(s.uColor, Color.BLUE, 0.4f);
|
||||||
else
|
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);
|
false, 0, ml.offset);
|
||||||
|
|
||||||
GL.glDrawElements(GL20.GL_TRIANGLES, ml.numIndices,
|
GL.glDrawElements(GL20.GL_TRIANGLES, ml.numIndices,
|
||||||
GL20.GL_UNSIGNED_SHORT, 0);
|
GL20.GL_UNSIGNED_SHORT, 0);
|
||||||
|
|
||||||
if (dbg) {
|
if (dbg) {
|
||||||
GLUtils.setColor(hColor, Color.GRAY, 0.4f);
|
GLUtils.setColor(s.uColor, Color.GRAY, 0.4f);
|
||||||
GL.glDrawElements(GL20.GL_LINES, ml.numIndices,
|
GL.glDrawElements(GL20.GL_LINES, ml.numIndices,
|
||||||
GL20.GL_UNSIGNED_SHORT, 0);
|
GL20.GL_UNSIGNED_SHORT, 0);
|
||||||
}
|
}
|
||||||
@ -172,21 +175,5 @@ public class MeshLayer extends RenderElement {
|
|||||||
|
|
||||||
return l;
|
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;
|
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.GL20;
|
||||||
import org.oscim.backend.GLAdapter;
|
|
||||||
import org.oscim.core.GeometryBuffer;
|
import org.oscim.core.GeometryBuffer;
|
||||||
import org.oscim.core.Tile;
|
import org.oscim.core.Tile;
|
||||||
import org.oscim.renderer.GLMatrix;
|
import org.oscim.renderer.GLShader;
|
||||||
import org.oscim.renderer.GLState;
|
import org.oscim.renderer.GLState;
|
||||||
import org.oscim.renderer.GLUtils;
|
import org.oscim.renderer.GLUtils;
|
||||||
import org.oscim.renderer.GLViewport;
|
import org.oscim.renderer.GLViewport;
|
||||||
@ -37,7 +32,7 @@ import org.slf4j.Logger;
|
|||||||
import org.slf4j.LoggerFactory;
|
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 {
|
public final class PolygonLayer extends RenderElement {
|
||||||
static final Logger log = LoggerFactory.getLogger(PolygonLayer.class);
|
static final Logger log = LoggerFactory.getLogger(PolygonLayer.class);
|
||||||
@ -118,9 +113,25 @@ public final class PolygonLayer extends RenderElement {
|
|||||||
si.used = outPos;
|
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 {
|
public static final class Renderer {
|
||||||
|
|
||||||
private static final int POLYGON_VERTICES_DATA_POS_OFFSET = 0;
|
|
||||||
private static final int STENCIL_BITS = 8;
|
private static final int STENCIL_BITS = 8;
|
||||||
private final static int CLIP_BIT = 0x80;
|
private final static int CLIP_BIT = 0x80;
|
||||||
|
|
||||||
@ -128,45 +139,12 @@ public final class PolygonLayer extends RenderElement {
|
|||||||
|
|
||||||
private static AreaStyle[] mAreaFills;
|
private static AreaStyle[] mAreaFills;
|
||||||
|
|
||||||
private static int numShaders = 2;
|
private static Shader polyShader;
|
||||||
private static int polyShader = 0;
|
private static Shader texShader;
|
||||||
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];
|
|
||||||
|
|
||||||
static boolean init() {
|
static boolean init() {
|
||||||
|
polyShader = new Shader("base_shader");
|
||||||
for (int i = 0; i < numShaders; i++) {
|
texShader = new Shader("polygon_layer_tex");
|
||||||
|
|
||||||
// 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");
|
|
||||||
}
|
|
||||||
|
|
||||||
mAreaFills = new AreaStyle[STENCIL_BITS];
|
mAreaFills = new AreaStyle[STENCIL_BITS];
|
||||||
|
|
||||||
@ -181,17 +159,18 @@ public final class PolygonLayer extends RenderElement {
|
|||||||
|
|
||||||
/* do not modify stencil buffer */
|
/* do not modify stencil buffer */
|
||||||
GL.glStencilMask(0x00);
|
GL.glStencilMask(0x00);
|
||||||
int shader = polyShader;
|
//int shader = polyShader;
|
||||||
|
|
||||||
|
Shader s = setShader(polyShader, v, false);
|
||||||
|
|
||||||
for (int c = start; c < end; c++) {
|
for (int c = start; c < end; c++) {
|
||||||
AreaStyle a = mAreaFills[c].current();
|
AreaStyle a = mAreaFills[c].current();
|
||||||
|
|
||||||
if (enableTexture && a.texture != null) {
|
if (enableTexture && a.texture != null) {
|
||||||
shader = texShader;
|
s = setShader(texShader, v, false);
|
||||||
setShader(texShader, v);
|
|
||||||
float num = FastMath.clamp((Tile.SIZE / a.texture.width) >> 1, 1, Tile.SIZE);
|
float num = FastMath.clamp((Tile.SIZE / a.texture.width) >> 1, 1, Tile.SIZE);
|
||||||
float transition = Interpolation.exp5.apply(FastMath.clamp(scale - 1, 0, 1));
|
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);
|
//if (a.texture.alpha);
|
||||||
GLState.blend(true);
|
GLState.blend(true);
|
||||||
@ -208,17 +187,17 @@ public final class PolygonLayer extends RenderElement {
|
|||||||
}
|
}
|
||||||
GLState.blend(true);
|
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) {
|
} else if (a.blendScale > 0 && a.blendScale <= zoom) {
|
||||||
/* blend colors (not alpha) */
|
/* blend colors (not alpha) */
|
||||||
GLState.blend(false);
|
GLState.blend(false);
|
||||||
|
|
||||||
if (a.blendScale == zoom)
|
if (a.blendScale == zoom)
|
||||||
GLUtils.setColorBlend(hPolygonColor[shader],
|
GLUtils.setColorBlend(s.uColor, a.color,
|
||||||
a.color, a.blendColor, scale - 1.0f);
|
a.blendColor, scale - 1.0f);
|
||||||
else
|
else
|
||||||
GLUtils.setColor(hPolygonColor[shader], a.blendColor, 1);
|
GLUtils.setColor(s.uColor, a.blendColor, 1);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
if (a.color < 0xff000000)
|
if (a.color < 0xff000000)
|
||||||
@ -226,38 +205,37 @@ public final class PolygonLayer extends RenderElement {
|
|||||||
else
|
else
|
||||||
GLState.blend(false);
|
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
|
/* set stencil buffer mask used to draw this layer
|
||||||
// also check that clip bit is set to avoid overdraw
|
* also check that clip bit is set to avoid overdraw
|
||||||
// of other tiles
|
* of other tiles */
|
||||||
GL.glStencilFunc(GL20.GL_EQUAL, 0xff, CLIP_BIT | 1 << c);
|
GL.glStencilFunc(GL20.GL_EQUAL, 0xff, CLIP_BIT | 1 << c);
|
||||||
|
|
||||||
/* draw tile fill coordinates */
|
/* draw tile fill coordinates */
|
||||||
GL.glDrawArrays(GL20.GL_TRIANGLE_STRIP, 0, 4);
|
GL.glDrawArrays(GL20.GL_TRIANGLE_STRIP, 0, 4);
|
||||||
|
|
||||||
if (shader != polyShader) {
|
/* disable texture shader */
|
||||||
// disable texture shader
|
if (s != polyShader)
|
||||||
setShader(polyShader, v);
|
s = setShader(polyShader, v, false);
|
||||||
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, GLViewport v) {
|
private static Shader setShader(Shader shader, GLViewport v, boolean first) {
|
||||||
GLState.useProgram(polygonProgram[shader]);
|
if (shader.useProgram() || first) {
|
||||||
|
|
||||||
GLState.enableVertexArrays(hPolygonVertexPosition[shader], -1);
|
GLState.enableVertexArrays(shader.aPos, -1);
|
||||||
|
|
||||||
GL.glVertexAttribPointer(hPolygonVertexPosition[shader], 2,
|
GL.glVertexAttribPointer(shader.aPos, 2,
|
||||||
GL20.GL_SHORT, false, 0,
|
GL20.GL_SHORT, false, 0, 0);
|
||||||
POLYGON_VERTICES_DATA_POS_OFFSET);
|
|
||||||
|
|
||||||
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);
|
GLState.test(false, true);
|
||||||
|
|
||||||
setShader(polyShader, v);
|
setShader(polyShader, v, first);
|
||||||
|
|
||||||
int zoom = v.pos.zoomLevel;
|
int zoom = v.pos.zoomLevel;
|
||||||
float scale = (float) v.pos.getZoomScale();
|
float scale = (float) v.pos.getZoomScale();
|
||||||
|
|
||||||
int cur = mCount;
|
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)
|
if (first || cur > 5)
|
||||||
cur = 0;
|
cur = 0;
|
||||||
|
|
||||||
@ -304,7 +282,7 @@ public final class PolygonLayer extends RenderElement {
|
|||||||
for (; l != null && l.type == RenderElement.POLYGON; l = l.next) {
|
for (; l != null && l.type == RenderElement.POLYGON; l = l.next) {
|
||||||
PolygonLayer pl = (PolygonLayer) l;
|
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)
|
if (pl.area.fadeScale > 0 && pl.area.fadeScale > zoom)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
@ -312,18 +290,18 @@ public final class PolygonLayer extends RenderElement {
|
|||||||
drawStencilRegion(first, clipMode);
|
drawStencilRegion(first, clipMode);
|
||||||
first = false;
|
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);
|
GL.glStencilOp(GL20.GL_KEEP, GL20.GL_KEEP, GL20.GL_INVERT);
|
||||||
}
|
}
|
||||||
|
|
||||||
mAreaFills[cur] = pl.area.current();
|
mAreaFills[cur] = pl.area.current();
|
||||||
|
|
||||||
// set stencil mask to draw to
|
/* set stencil mask to draw to */
|
||||||
GL.glStencilMask(1 << cur++);
|
GL.glStencilMask(1 << cur++);
|
||||||
|
|
||||||
GL.glDrawArrays(GL20.GL_TRIANGLE_FAN, l.offset, l.numVertices);
|
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) {
|
if (cur == STENCIL_BITS - 1) {
|
||||||
fillPolygons(v, start, cur, zoom, scale, div);
|
fillPolygons(v, start, cur, zoom, scale, div);
|
||||||
start = cur = 0;
|
start = cur = 0;
|
||||||
@ -336,12 +314,12 @@ public final class PolygonLayer extends RenderElement {
|
|||||||
if (clipMode > 0) {
|
if (clipMode > 0) {
|
||||||
if (first) {
|
if (first) {
|
||||||
drawStencilRegion(first, clipMode);
|
drawStencilRegion(first, clipMode);
|
||||||
// disable writes to stencil buffer
|
/* disable writes to stencil buffer */
|
||||||
GL.glStencilMask(0x00);
|
GL.glStencilMask(0x00);
|
||||||
// enable writes to color buffer
|
/* enable writes to color buffer */
|
||||||
GL.glColorMask(true, true, true, true);
|
GL.glColorMask(true, true, true, true);
|
||||||
} else {
|
} else {
|
||||||
// set test for clip to tile region
|
/* set test for clip to tile region */
|
||||||
GL.glStencilFunc(GL20.GL_EQUAL, CLIP_BIT, CLIP_BIT);
|
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) {
|
public static void clip(GLViewport v) {
|
||||||
setShader(polyShader, v);
|
setShader(polyShader, v, true);
|
||||||
|
|
||||||
drawStencilRegion(true, 1);
|
drawStencilRegion(true, 1);
|
||||||
// disable writes to stencil buffer
|
/* disable writes to stencil buffer */
|
||||||
GL.glStencilMask(0x00);
|
GL.glStencilMask(0x00);
|
||||||
// enable writes to color buffer
|
/* enable writes to color buffer */
|
||||||
GL.glColorMask(true, true, true, true);
|
GL.glColorMask(true, true, true, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -419,10 +397,11 @@ public final class PolygonLayer extends RenderElement {
|
|||||||
* and 'alpha' to fake a fade effect.
|
* and 'alpha' to fake a fade effect.
|
||||||
*/
|
*/
|
||||||
public static void drawOver(GLViewport v, int color, float alpha) {
|
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) {
|
if (color != 0) {
|
||||||
GLUtils.setColor(hPolygonColor[0], color, alpha);
|
GLUtils.setColor(polyShader.uColor, color, alpha);
|
||||||
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) */
|
||||||
@ -447,103 +426,39 @@ public final class PolygonLayer extends RenderElement {
|
|||||||
GL.glColorMask(true, true, true, true);
|
GL.glColorMask(true, true, true, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static float[] debugFillColor = { 0.3f, 0.0f, 0.0f, 0.3f };
|
//private static float[] debugFillColor = { 0.3f, 0.0f, 0.0f, 0.3f };
|
||||||
private static float[] debugFillColor2 = { .8f, .8f, .8f, .8f };
|
//private static float[] debugFillColor2 = { .8f, .8f, .8f, .8f };
|
||||||
private static FloatBuffer mDebugFill;
|
//private static FloatBuffer mDebugFill;
|
||||||
|
|
||||||
static void debugDraw(GLMatrix m, float[] coords, int color) {
|
//static void debugDraw(GLMatrix m, float[] coords, int color) {
|
||||||
GLState.test(false, false);
|
// GLState.test(false, false);
|
||||||
if (mDebugFill == null) {
|
// if (mDebugFill == null) {
|
||||||
mDebugFill = ByteBuffer
|
// mDebugFill = ByteBuffer
|
||||||
.allocateDirect(32)
|
// .allocateDirect(32)
|
||||||
.order(ByteOrder.nativeOrder())
|
// .order(ByteOrder.nativeOrder())
|
||||||
.asFloatBuffer();
|
// .asFloatBuffer();
|
||||||
mDebugFill.put(coords);
|
// 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 java.nio.ShortBuffer;
|
||||||
|
|
||||||
import org.oscim.backend.GL20;
|
import org.oscim.backend.GL20;
|
||||||
|
import org.oscim.renderer.GLShader;
|
||||||
import org.oscim.renderer.GLState;
|
import org.oscim.renderer.GLState;
|
||||||
import org.oscim.renderer.GLUtils;
|
|
||||||
import org.oscim.renderer.GLViewport;
|
import org.oscim.renderer.GLViewport;
|
||||||
import org.oscim.renderer.MapRenderer;
|
import org.oscim.renderer.MapRenderer;
|
||||||
import org.oscim.renderer.elements.TextureItem.TexturePool;
|
import org.oscim.renderer.elements.TextureItem.TexturePool;
|
||||||
@ -113,56 +113,60 @@ public abstract class TextureLayer extends RenderElement {
|
|||||||
buf[pos + 23] = v1;
|
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 static final class Renderer {
|
||||||
|
|
||||||
public final static boolean debug = false;
|
public final static boolean debug = false;
|
||||||
|
|
||||||
private static int mTextureProgram;
|
private static Shader shader;
|
||||||
private static int hTextureMVMatrix;
|
|
||||||
private static int hTextureProjMatrix;
|
|
||||||
private static int hTextureVertex;
|
|
||||||
private static int hTextureScale;
|
|
||||||
private static int hTextureTexCoord;
|
|
||||||
private static int hTextureSize;
|
|
||||||
|
|
||||||
static void init() {
|
static void init() {
|
||||||
mTextureProgram = GLUtils.createProgram(textVertexShader,
|
shader = new Shader();
|
||||||
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");
|
|
||||||
|
|
||||||
/* FIXME pool should be disposed on exit... */
|
/* FIXME pool should be disposed on exit... */
|
||||||
pool.init(0);
|
pool.init(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static RenderElement draw(RenderElement l, GLViewport v, float scale) {
|
public static RenderElement draw(RenderElement l, GLViewport v, float scale) {
|
||||||
|
shader.useProgram();
|
||||||
|
|
||||||
GLState.test(false, false);
|
GLState.test(false, false);
|
||||||
GLState.blend(true);
|
GLState.blend(true);
|
||||||
|
|
||||||
GLState.useProgram(mTextureProgram);
|
|
||||||
|
|
||||||
GLState.enableVertexArrays(hTextureTexCoord, hTextureVertex);
|
|
||||||
|
|
||||||
TextureLayer tl = (TextureLayer) l;
|
TextureLayer tl = (TextureLayer) l;
|
||||||
|
|
||||||
if (tl.fixed)
|
GL.glUniform1f(shader.uScale, tl.fixed ? 1 / scale : 1);
|
||||||
GL.glUniform1f(hTextureScale, 1 / scale);
|
|
||||||
else
|
|
||||||
GL.glUniform1f(hTextureScale, 1);
|
|
||||||
|
|
||||||
v.proj.setAsUniform(hTextureProjMatrix);
|
v.proj.setAsUniform(shader.uProj);
|
||||||
v.mvp.setAsUniform(hTextureMVMatrix);
|
v.mvp.setAsUniform(shader.uMV);
|
||||||
|
|
||||||
MapRenderer.bindQuadIndicesVBO(true);
|
MapRenderer.bindQuadIndicesVBO(true);
|
||||||
|
|
||||||
for (TextureItem t = tl.textures; t != null; t = t.next) {
|
for (TextureItem t = tl.textures; t != null; t = t.next) {
|
||||||
GL.glUniform2f(hTextureSize,
|
GL.glUniform2f(shader.uTexSize,
|
||||||
1f / (t.width * COORD_SCALE),
|
1f / (t.width * COORD_SCALE),
|
||||||
1f / (t.height * COORD_SCALE));
|
1f / (t.height * COORD_SCALE));
|
||||||
t.bind();
|
t.bind();
|
||||||
@ -175,10 +179,10 @@ public abstract class TextureLayer extends RenderElement {
|
|||||||
* / 6(indices) == 8) */
|
* / 6(indices) == 8) */
|
||||||
int off = (t.offset + i) * 8 + tl.offset;
|
int off = (t.offset + i) * 8 + tl.offset;
|
||||||
|
|
||||||
GL.glVertexAttribPointer(hTextureVertex, 4,
|
GL.glVertexAttribPointer(shader.aPos, 4,
|
||||||
GL20.GL_SHORT, false, 12, off);
|
GL20.GL_SHORT, false, 12, off);
|
||||||
|
|
||||||
GL.glVertexAttribPointer(hTextureTexCoord, 2,
|
GL.glVertexAttribPointer(shader.aTexCoord, 2,
|
||||||
GL20.GL_SHORT, false, 12, off + 8);
|
GL20.GL_SHORT, false, 12, off + 8);
|
||||||
|
|
||||||
int numVertices = t.vertices - i;
|
int numVertices = t.vertices - i;
|
||||||
@ -194,38 +198,5 @@ public abstract class TextureLayer extends RenderElement {
|
|||||||
|
|
||||||
return l.next;
|
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