diff options
-rw-r--r-- | src/net/java/joglutils/msg/elements/GLShaderElement.java | 11 | ||||
-rw-r--r-- | src/net/java/joglutils/msg/misc/Shader.java | 157 | ||||
-rw-r--r-- | src/net/java/joglutils/msg/nodes/ShaderNode.java | 477 |
3 files changed, 625 insertions, 20 deletions
diff --git a/src/net/java/joglutils/msg/elements/GLShaderElement.java b/src/net/java/joglutils/msg/elements/GLShaderElement.java index cf28c97..178a8f2 100644 --- a/src/net/java/joglutils/msg/elements/GLShaderElement.java +++ b/src/net/java/joglutils/msg/elements/GLShaderElement.java @@ -90,17 +90,6 @@ public class GLShaderElement extends ShaderElement { } if (curShader != null) { curShader.enable(); - - // FIXME: the following is a big hack... - Map<String, Vec4f> fMap = shader.getUniformfMap(); - if (!fMap.isEmpty()) { - for (String name : fMap.keySet()) { - Vec4f val = fMap.get(name); - //curShader.setUniform(name, val.x(), val.y(), val.z(), val.w()); - curShader.setUniform(name, val.x()); - fMap.clear(); - } - } } } } diff --git a/src/net/java/joglutils/msg/misc/Shader.java b/src/net/java/joglutils/msg/misc/Shader.java index c816629..ab25f78 100644 --- a/src/net/java/joglutils/msg/misc/Shader.java +++ b/src/net/java/joglutils/msg/misc/Shader.java @@ -432,6 +432,82 @@ public class Shader { /** * Sets the uniform array variable of the given name with the provided + * int array values. + * + * @param name the name of the uniform variable to be set + * @param count the number of int elements in the array + * @param vals the array values to be set + * @param off the offset into the vals array + * @throws GLException if no OpenGL context was current or if any + * OpenGL-related errors occurred + */ + public void setUniformArray1i(String name, int count, int[] vals, int off) + throws GLException + { + GL gl = GLU.getCurrentGL(); + int loc = gl.glGetUniformLocationARB(id, name); + gl.glUniform1ivARB(loc, count, vals, off); + } + + /** + * Sets the uniform array variable of the given name with the provided + * int array values. + * + * @param name the name of the uniform variable to be set + * @param count the number of ivec2 elements in the array + * @param vals the array values to be set + * @param off the offset into the vals array + * @throws GLException if no OpenGL context was current or if any + * OpenGL-related errors occurred + */ + public void setUniformArray2i(String name, int count, int[] vals, int off) + throws GLException + { + GL gl = GLU.getCurrentGL(); + int loc = gl.glGetUniformLocationARB(id, name); + gl.glUniform2ivARB(loc, count, vals, off); + } + + /** + * Sets the uniform array variable of the given name with the provided + * int array values. + * + * @param name the name of the uniform variable to be set + * @param count the number of ivec3 elements in the array + * @param vals the array values to be set + * @param off the offset into the vals array + * @throws GLException if no OpenGL context was current or if any + * OpenGL-related errors occurred + */ + public void setUniformArray3i(String name, int count, int[] vals, int off) + throws GLException + { + GL gl = GLU.getCurrentGL(); + int loc = gl.glGetUniformLocationARB(id, name); + gl.glUniform3ivARB(loc, count, vals, off); + } + + /** + * Sets the uniform array variable of the given name with the provided + * int array values. + * + * @param name the name of the uniform variable to be set + * @param count the number of ivec4 elements in the array + * @param vals the array values to be set + * @param off the offset into the vals array + * @throws GLException if no OpenGL context was current or if any + * OpenGL-related errors occurred + */ + public void setUniformArray4i(String name, int count, int[] vals, int off) + throws GLException + { + GL gl = GLU.getCurrentGL(); + int loc = gl.glGetUniformLocationARB(id, name); + gl.glUniform4ivARB(loc, count, vals, off); + } + + /** + * Sets the uniform array variable of the given name with the provided * float array values. * * @param name the name of the uniform variable to be set @@ -441,7 +517,8 @@ public class Shader { * @throws GLException if no OpenGL context was current or if any * OpenGL-related errors occurred */ - public void setUniformArray1f(String name, int count, float[] vals, int off) + public void setUniformArray1f(String name, + int count, float[] vals, int off) throws GLException { GL gl = GLU.getCurrentGL(); @@ -460,7 +537,8 @@ public class Shader { * @throws GLException if no OpenGL context was current or if any * OpenGL-related errors occurred */ - public void setUniformArray2f(String name, int count, float[] vals, int off) + public void setUniformArray2f(String name, + int count, float[] vals, int off) throws GLException { GL gl = GLU.getCurrentGL(); @@ -479,7 +557,8 @@ public class Shader { * @throws GLException if no OpenGL context was current or if any * OpenGL-related errors occurred */ - public void setUniformArray3f(String name, int count, float[] vals, int off) + public void setUniformArray3f(String name, + int count, float[] vals, int off) throws GLException { GL gl = GLU.getCurrentGL(); @@ -498,11 +577,81 @@ public class Shader { * @throws GLException if no OpenGL context was current or if any * OpenGL-related errors occurred */ - public void setUniformArray4f(String name, int count, float[] vals, int off) + public void setUniformArray4f(String name, + int count, float[] vals, int off) throws GLException { GL gl = GLU.getCurrentGL(); int loc = gl.glGetUniformLocationARB(id, name); gl.glUniform4fvARB(loc, count, vals, off); } + + /** + * Sets the uniform matrix (or matrix array) variable of the given name + * with the provided matrix values. + * + * @param name the name of the uniform variable to be set + * @param count the number of 2x2 matrices (mat2 elements) in the array + * @param transpose if false, each matrix is assumed to be suppplied in + * column major order; otherwise assumed to be supplied in row major order + * @param vals the matrix values to be set + * @param off the offset into the vals array + * @throws GLException if no OpenGL context was current or if any + * OpenGL-related errors occurred + */ + public void setUniformMatrices2f(String name, + int count, boolean transpose, + float[] vals, int off) + throws GLException + { + GL gl = GLU.getCurrentGL(); + int loc = gl.glGetUniformLocationARB(id, name); + gl.glUniformMatrix2fvARB(loc, count, transpose, vals, off); + } + + /** + * Sets the uniform matrix (or matrix array) variable of the given name + * with the provided matrix values. + * + * @param name the name of the uniform variable to be set + * @param count the number of 3x3 matrices (mat3 elements) in the array + * @param transpose if false, each matrix is assumed to be suppplied in + * column major order; otherwise assumed to be supplied in row major order + * @param vals the matrix values to be set + * @param off the offset into the vals array + * @throws GLException if no OpenGL context was current or if any + * OpenGL-related errors occurred + */ + public void setUniformMatrices3f(String name, + int count, boolean transpose, + float[] vals, int off) + throws GLException + { + GL gl = GLU.getCurrentGL(); + int loc = gl.glGetUniformLocationARB(id, name); + gl.glUniformMatrix3fvARB(loc, count, transpose, vals, off); + } + + /** + * Sets the uniform matrix (or matrix array) variable of the given name + * with the provided matrix values. + * + * @param name the name of the uniform variable to be set + * @param count the number of 4x4 matrices (mat4 elements) in the array + * @param transpose if false, each matrix is assumed to be suppplied in + * column major order; otherwise assumed to be supplied in row major order + * @param vals the matrix values to be set + * @param off the offset into the vals array + * @throws GLException if no OpenGL context was current or if any + * OpenGL-related errors occurred + */ + public void setUniformMatrices4f(String name, + int count, boolean transpose, + float[] vals, int off) + throws GLException + { + GL gl = GLU.getCurrentGL(); + int loc = gl.glGetUniformLocationARB(id, name); + gl.glUniformMatrix4fvARB(loc, count, transpose, vals, off); + } } diff --git a/src/net/java/joglutils/msg/nodes/ShaderNode.java b/src/net/java/joglutils/msg/nodes/ShaderNode.java index ab9ea60..676838e 100644 --- a/src/net/java/joglutils/msg/nodes/ShaderNode.java +++ b/src/net/java/joglutils/msg/nodes/ShaderNode.java @@ -55,6 +55,7 @@ public class ShaderNode extends Node { private String fragmentShaderCode; private Shader shader; private List<Shader> disposedShaders = new ArrayList<Shader>(); + private Map<String, Params> paramMap = new HashMap<String, Params>(); static { // Enable the elements this node affects for known actions @@ -79,12 +80,346 @@ public class ShaderNode extends Node { this.fragmentShaderCode = fragmentShaderCode; } - private Map<String, Vec4f> fMap = new HashMap<String, Vec4f>(); - public void setUniform(String name, float val) { - fMap.put(name, new Vec4f(val, val, val, val)); + /** + * Sets the uniform variable of the given name with the provided + * integer value. + * + * @param name the name of the uniform variable to be set + * @param i0 the first uniform parameter + */ + public void setUniform(String name, int i0) { + int[] iArr = new int[] { i0 }; + paramMap.put(name, new Params(iArr, 1)); } - public Map<String, Vec4f> getUniformfMap() { - return fMap; + + /** + * Sets the uniform variable of the given name with the provided + * integer values. + * <p> + * No OpenGL work is done during this call; it is done lazily when + * the Shader is fetched. + * + * @param name the name of the uniform variable to be set + * @param i0 the first uniform parameter + * @param i1 the second uniform parameter + */ + public void setUniform(String name, int i0, int i1) { + int[] iArr = new int[] { i0, i1 }; + paramMap.put(name, new Params(iArr, 2)); + } + + /** + * Sets the uniform variable of the given name with the provided + * integer values. + * <p> + * No OpenGL work is done during this call; it is done lazily when + * the Shader is fetched. + * + * @param name the name of the uniform variable to be set + * @param i0 the first uniform parameter + * @param i1 the second uniform parameter + * @param i2 the third uniform parameter + */ + public void setUniform(String name, int i0, int i1, int i2) { + int[] iArr = new int[] { i0, i1, i2 }; + paramMap.put(name, new Params(iArr, 3)); + } + + /** + * Sets the uniform variable of the given name with the provided + * integer values. + * <p> + * No OpenGL work is done during this call; it is done lazily when + * the Shader is fetched. + * + * @param name the name of the uniform variable to be set + * @param i0 the first uniform parameter + * @param i1 the second uniform parameter + * @param i2 the third uniform parameter + * @param i3 the fourth uniform parameter + */ + public void setUniform(String name, + int i0, int i1, int i2, int i3) + { + int[] iArr = new int[] { i0, i1, i2, i3 }; + paramMap.put(name, new Params(iArr, 4)); + } + + /** + * Sets the uniform variable of the given name with the provided + * float value. + * <p> + * No OpenGL work is done during this call; it is done lazily when + * the Shader is fetched. + * + * @param name the name of the uniform variable to be set + * @param f0 the first uniform parameter + */ + public void setUniform(String name, float f0) { + float[] fArr = new float[] { f0 }; + paramMap.put(name, new Params(fArr, 1)); + } + + /** + * Sets the uniform variable of the given name with the provided + * float values. + * <p> + * No OpenGL work is done during this call; it is done lazily when + * the Shader is fetched. + * + * @param name the name of the uniform variable to be set + * @param f0 the first uniform parameter + * @param f1 the second uniform parameter + */ + public void setUniform(String name, float f0, float f1) { + float[] fArr = new float[] { f0, f1 }; + paramMap.put(name, new Params(fArr, 2)); + } + + /** + * Sets the uniform variable of the given name with the provided + * float values. + * <p> + * No OpenGL work is done during this call; it is done lazily when + * the Shader is fetched. + * + * @param name the name of the uniform variable to be set + * @param f0 the first uniform parameter + * @param f1 the second uniform parameter + * @param f2 the third uniform parameter + */ + public void setUniform(String name, float f0, float f1, float f2) { + float[] fArr = new float[] { f0, f1, f2 }; + paramMap.put(name, new Params(fArr, 3)); + } + + /** + * Sets the uniform variable of the given name with the provided + * float values. + * <p> + * No OpenGL work is done during this call; it is done lazily when + * the Shader is fetched. + * + * @param name the name of the uniform variable to be set + * @param f0 the first uniform parameter + * @param f1 the second uniform parameter + * @param f2 the third uniform parameter + * @param f3 the fourth uniform parameter + */ + public void setUniform(String name, + float f0, float f1, float f2, float f3) + { + float[] fArr = new float[] { f0, f1, f2, f3 }; + paramMap.put(name, new Params(fArr, 4)); + } + + /** + * Sets the uniform array variable of the given name with the provided + * int array values. + * <p> + * No OpenGL work is done during this call; it is done lazily when + * the Shader is fetched. + * + * @param name the name of the uniform variable to be set + * @param count the number of int elements in the array + * @param vals the array values to be set + * @param off the offset into the vals array + */ + public void setUniformArray1i(String name, + int count, int[] vals, int off) + { + paramMap.put(name, new Params(vals, 1, count, off)); + } + + /** + * Sets the uniform array variable of the given name with the provided + * int array values. + * <p> + * No OpenGL work is done during this call; it is done lazily when + * the Shader is fetched. + * + * @param name the name of the uniform variable to be set + * @param count the number of ivec2 elements in the array + * @param vals the array values to be set + * @param off the offset into the vals array + */ + public void setUniformArray2i(String name, + int count, int[] vals, int off) + { + paramMap.put(name, new Params(vals, 2, count, off)); + } + + /** + * Sets the uniform array variable of the given name with the provided + * int array values. + * <p> + * No OpenGL work is done during this call; it is done lazily when + * the Shader is fetched. + * + * @param name the name of the uniform variable to be set + * @param count the number of ivec3 elements in the array + * @param vals the array values to be set + * @param off the offset into the vals array + */ + public void setUniformArray3i(String name, + int count, int[] vals, int off) + { + paramMap.put(name, new Params(vals, 3, count, off)); + } + + /** + * Sets the uniform array variable of the given name with the provided + * int array values. + * <p> + * No OpenGL work is done during this call; it is done lazily when + * the Shader is fetched. + * + * @param name the name of the uniform variable to be set + * @param count the number of ivec4 elements in the array + * @param vals the array values to be set + * @param off the offset into the vals array + */ + public void setUniformArray4i(String name, + int count, int[] vals, int off) + { + paramMap.put(name, new Params(vals, 4, count, off)); + } + + /** + * Sets the uniform array variable of the given name with the provided + * float array values. + * <p> + * No OpenGL work is done during this call; it is done lazily when + * the Shader is fetched. + * + * @param name the name of the uniform variable to be set + * @param count the number of float elements in the array + * @param vals the array values to be set + * @param off the offset into the vals array + */ + public void setUniformArray1f(String name, + int count, float[] vals, int off) + { + paramMap.put(name, new Params(vals, 1, count, off)); + } + + /** + * Sets the uniform array variable of the given name with the provided + * float array values. + * <p> + * No OpenGL work is done during this call; it is done lazily when + * the Shader is fetched. + * + * @param name the name of the uniform variable to be set + * @param count the number of vec2 elements in the array + * @param vals the array values to be set + * @param off the offset into the vals array + */ + public void setUniformArray2f(String name, + int count, float[] vals, int off) + { + paramMap.put(name, new Params(vals, 2, count, off)); + } + + /** + * Sets the uniform array variable of the given name with the provided + * float array values. + * <p> + * No OpenGL work is done during this call; it is done lazily when + * the Shader is fetched. + * + * @param name the name of the uniform variable to be set + * @param count the number of vec3 elements in the array + * @param vals the array values to be set + * @param off the offset into the vals array + */ + public void setUniformArray3f(String name, + int count, float[] vals, int off) + { + paramMap.put(name, new Params(vals, 3, count, off)); + } + + /** + * Sets the uniform array variable of the given name with the provided + * float array values. + * <p> + * No OpenGL work is done during this call; it is done lazily when + * the Shader is fetched. + * + * @param name the name of the uniform variable to be set + * @param count the number of vec4 elements in the array + * @param vals the array values to be set + * @param off the offset into the vals array + * @throws GLException if no OpenGL context was current or if any + * OpenGL-related errors occurred + */ + public void setUniformArray4f(String name, + int count, float[] vals, int off) + { + paramMap.put(name, new Params(vals, 4, count, off)); + } + + /** + * Sets the uniform matrix (or matrix array) variable of the given name + * with the provided matrix values. + * <p> + * No OpenGL work is done during this call; it is done lazily when + * the Shader is fetched. + * + * @param name the name of the uniform variable to be set + * @param count the number of 2x2 matrices (mat2 elements) in the array + * @param transpose if false, each matrix is assumed to be suppplied in + * column major order; otherwise assumed to be supplied in row major order + * @param vals the matrix values to be set + * @param off the offset into the vals array + */ + public void setUniformMatrices2f(String name, + int count, boolean transpose, + float[] vals, int off) + { + paramMap.put(name, new Params(vals, 2, count, off, true, transpose)); + } + + /** + * Sets the uniform matrix (or matrix array) variable of the given name + * with the provided matrix values. + * <p> + * No OpenGL work is done during this call; it is done lazily when + * the Shader is fetched. + * + * @param name the name of the uniform variable to be set + * @param count the number of 3x3 matrices (mat3 elements) in the array + * @param transpose if false, each matrix is assumed to be suppplied in + * column major order; otherwise assumed to be supplied in row major order + * @param vals the matrix values to be set + * @param off the offset into the vals array + */ + public void setUniformMatrices3f(String name, + int count, boolean transpose, + float[] vals, int off) + { + paramMap.put(name, new Params(vals, 3, count, off, true, transpose)); + } + + /** + * Sets the uniform matrix (or matrix array) variable of the given name + * with the provided matrix values. + * <p> + * No OpenGL work is done during this call; it is done lazily when + * the Shader is fetched. + * + * @param name the name of the uniform variable to be set + * @param count the number of 4x4 matrices (mat4 elements) in the array + * @param transpose if false, each matrix is assumed to be suppplied in + * column major order; otherwise assumed to be supplied in row major order + * @param vals the matrix values to be set + * @param off the offset into the vals array + */ + public void setUniformMatrices4f(String name, + int count, boolean transpose, + float[] vals, int off) + { + paramMap.put(name, new Params(vals, 4, count, off, true, transpose)); } /** Fetches the Shader object associated with this ShaderNode. @@ -96,6 +431,7 @@ public class ShaderNode extends Node { if (shader == null) { this.shader = new Shader(vertexShaderCode, fragmentShaderCode); } + sendParams(); return shader; } @@ -121,4 +457,135 @@ public class ShaderNode extends Node { s.dispose(); } } + + /** + * Sends the stored uniform parameters down to GL. + * An OpenGL context must be current at the time this method is + * called or a GLException will be thrown. + */ + private void sendParams() { + if (!paramMap.isEmpty()) { + // FIXME: the shader needs to be enabled prior to setting uniforms, + // but doing so here may lead to too many enable/disable calls + shader.enable(); + for (String name : paramMap.keySet()) { + Params params = paramMap.get(name); + if (params.isMatrix) { + switch (params.vecSize) { + case 2: + shader.setUniformMatrices2f(name, params.numElems, + params.transpose, + params.fArr, + params.offset); + break; + case 3: + shader.setUniformMatrices3f(name, params.numElems, + params.transpose, + params.fArr, + params.offset); + break; + case 4: + shader.setUniformMatrices4f(name, params.numElems, + params.transpose, + params.fArr, + params.offset); + break; + default: + continue; + } + } else if (params.fArr != null) { + switch (params.vecSize) { + case 1: + shader.setUniformArray1f(name, params.numElems, + params.fArr, params.offset); + break; + case 2: + shader.setUniformArray2f(name, params.numElems, + params.fArr, params.offset); + break; + case 3: + shader.setUniformArray3f(name, params.numElems, + params.fArr, params.offset); + break; + case 4: + shader.setUniformArray4f(name, params.numElems, + params.fArr, params.offset); + break; + default: + continue; + } + } else if (params.iArr != null) { + switch (params.vecSize) { + case 1: + shader.setUniformArray1i(name, params.numElems, + params.iArr, params.offset); + break; + case 2: + shader.setUniformArray2i(name, params.numElems, + params.iArr, params.offset); + break; + case 3: + shader.setUniformArray3i(name, params.numElems, + params.iArr, params.offset); + break; + case 4: + shader.setUniformArray4i(name, params.numElems, + params.iArr, params.offset); + break; + default: + continue; + } + } + } + // FIXME: see above... + shader.disable(); + paramMap.clear(); + } + } + + /** + * A small class to encapsulate int or float data passed in through + * the various setUniform*() methods. + */ + private static class Params { + private float[] fArr; + private int[] iArr; + private int vecSize; // 1, 2, 3, or 4 + private int numElems; + private int offset; + private boolean isMatrix; + private boolean transpose; + + Params(float[] fArr, int vecSize) { + this(fArr, vecSize, 1, 0); + } + + Params(float[] fArr, int vecSize, int numElems, int offset) { + this(fArr, vecSize, numElems, offset, false, false); + } + + Params(float[] fArr, int vecSize, int numElems, int offset, + boolean isMatrix, boolean transpose) + { + this.fArr = fArr; + this.vecSize = vecSize; + this.numElems = numElems; + this.offset = offset; + this.isMatrix = isMatrix; + this.transpose = transpose; + } + + Params(int[] iArr, int vecSize) { + this(iArr, vecSize, 1, 0); + } + + Params(int[] iArr, int vecSize, int numElems, int offset) { + this.iArr = iArr; + this.vecSize = vecSize; + this.numElems = numElems; + this.offset = offset; + this.isMatrix = false; + this.transpose = false; + } + } } |