add GLShader:

- load shaders from assets
- start to move shaders to asset files
This commit is contained in:
Hannes Janetzek 2014-03-17 15:01:16 +01:00
parent 4205d42e7f
commit 18f6784e81
12 changed files with 521 additions and 70 deletions

View File

@ -35,6 +35,7 @@ public class GdxAssetAdapter extends AssetAdapter {
try {
return file.read();
} catch (GdxRuntimeException e) {
e.printStackTrace();
return null;
}
}

View 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;
}

View 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;
}

View File

@ -0,0 +1,61 @@
#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;
}
$$
#ifndef DESKTOP_QUIRKS
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);
}

View 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);
}

View 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);
}

View File

@ -0,0 +1,13 @@
precision mediump float;
uniform mat4 u_mvp;
attribute vec4 a_pos;
void main() {
gl_Position = u_mvp * a_pos;
}
§
precision mediump float;
uniform vec4 u_color;
void main() {
gl_FragColor = u_color;
}

View 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);
}

View File

@ -16,7 +16,10 @@
*/
package org.oscim.backend;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
/**
* The Class AssetAdapter.
@ -33,4 +36,25 @@ public abstract class AssetAdapter {
* @return the input stream
*/
public abstract InputStream openFileAsStream(String name);
public String openTextFile(String name) {
StringBuilder sb = new StringBuilder();
InputStream is = g.openFileAsStream(name);
if (is == null)
return null;
BufferedReader r = new BufferedReader(new InputStreamReader(is));
String line;
try {
while ((line = r.readLine()) != null) {
sb.append(line);
sb.append('\n');
}
} catch (IOException e) {
e.printStackTrace();
}
return sb.toString();
}
}

View 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 {
}
}

View File

@ -324,6 +324,7 @@ public class MapRenderer {
GLState.init(GL);
GLUtils.init(GL);
GLShader.GL = GL;
// Set up some vertex buffer objects
BufferObject.init(GL, 200);

View File

@ -21,7 +21,6 @@ import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import org.oscim.backend.GL20;
import org.oscim.backend.GLAdapter;
import org.oscim.core.GeometryBuffer;
import org.oscim.core.Tile;
import org.oscim.renderer.GLMatrix;
@ -145,16 +144,11 @@ public final class PolygonLayer extends RenderElement {
// 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);
polygonProgram[i] = ShaderProgram.loadShader("simple_shader");
//polygonProgram[i] = GLUtils.createProgram(polygonVertexShader,
// polygonFragmentShader);
} else if (i == 1) {
polygonProgram[i] = GLUtils.createProgram(textureVertexShader,
textureFragmentShader);
polygonProgram[i] = ShaderProgram.loadShader("poly_texture");
}
if (polygonProgram[i] == 0) {
@ -482,68 +476,68 @@ public final class PolygonLayer extends RenderElement {
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 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 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 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);"
+ "}";
// 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);"
// + "}";
}
}