From d31a93e255019a5dc177a1caf91da174bd313b82 Mon Sep 17 00:00:00 2001 From: Kenneth Russel Date: Tue, 3 Apr 2007 02:51:23 +0000 Subject: Checked in code from Chris Campbell for abstracting shader support and adding it to MSG -- thanks very much. git-svn-id: file:///usr/local/projects/SUN/JOGL/git-svn/svn-server-sync/joglutils/trunk@55 83d24430-9974-4f80-8418-2cc3294053b9 --- .../joglutils/msg/elements/GLShaderElement.java | 92 ++++ .../java/joglutils/msg/elements/ShaderElement.java | 99 ++++ src/net/java/joglutils/msg/misc/Shader.java | 508 +++++++++++++++++++++ src/net/java/joglutils/msg/nodes/ShaderNode.java | 115 +++++ 4 files changed, 814 insertions(+) create mode 100644 src/net/java/joglutils/msg/elements/GLShaderElement.java create mode 100644 src/net/java/joglutils/msg/elements/ShaderElement.java create mode 100644 src/net/java/joglutils/msg/misc/Shader.java create mode 100644 src/net/java/joglutils/msg/nodes/ShaderNode.java (limited to 'src/net/java') diff --git a/src/net/java/joglutils/msg/elements/GLShaderElement.java b/src/net/java/joglutils/msg/elements/GLShaderElement.java new file mode 100644 index 0000000..a7abbc6 --- /dev/null +++ b/src/net/java/joglutils/msg/elements/GLShaderElement.java @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2007 Sun Microsystems, Inc. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, + * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN + * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR + * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR + * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR + * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR + * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE + * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, + * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF + * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed or intended for use + * in the design, construction, operation or maintenance of any nuclear + * facility. + */ + +package net.java.joglutils.msg.elements; + +import javax.media.opengl.*; +import javax.media.opengl.glu.*; + +import net.java.joglutils.msg.misc.*; +import net.java.joglutils.msg.nodes.*; + +/** Represents the current shader, which is applied to any drawn + geometry, and performs side-effects in OpenGL. */ + +public class GLShaderElement extends ShaderElement { + // Boilerplate for concrete element subclasses + public Element newInstance() { + return new GLShaderElement(); + } + public static GLShaderElement getInstance(State state) { + return (GLShaderElement) ShaderElement.getInstance(state); + } + public static void enable(State defaultState) { + Element tmp = new GLShaderElement(); + defaultState.setElement(tmp.getStateIndex(), tmp); + } + + public void pop(State state, Element previousTopElement) { + // Put things back the way they were + switchShaders(((GLShaderElement) previousTopElement).shader, shader); + } + + public void setElt(ShaderNode shader) { + ShaderNode prev = this.shader; + super.setElt(shader); + switchShaders(prev, shader); + } + + private void switchShaders(ShaderNode prev, ShaderNode shader) { + GL gl = GLU.getCurrentGL(); + Shader prevShader = null; + Shader curShader = null; + if (prev != null) { + prevShader = prev.getShader(); + } + if (shader != null) { + curShader = shader.getShader(); + } + + // FIXME: should be smarter about this; if the target is the same + // for the previous and current shaders, just bind the new one + if (prevShader != null) { + prevShader.disable(); + } + if (curShader != null) { + curShader.enable(); + } + } +} diff --git a/src/net/java/joglutils/msg/elements/ShaderElement.java b/src/net/java/joglutils/msg/elements/ShaderElement.java new file mode 100644 index 0000000..8b1a3fe --- /dev/null +++ b/src/net/java/joglutils/msg/elements/ShaderElement.java @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2007 Sun Microsystems, Inc. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, + * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN + * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR + * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR + * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR + * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR + * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE + * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, + * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF + * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed or intended for use + * in the design, construction, operation or maintenance of any nuclear + * facility. + * + */ + +package net.java.joglutils.msg.elements; + +import net.java.joglutils.msg.misc.*; +import net.java.joglutils.msg.nodes.*; + +/** Represents the current vertex/fragment shader, which is applied to + any drawn geometry. */ + +public class ShaderElement extends Element { + // Boilerplate + private static StateIndex index = State.registerElementType(); + public StateIndex getStateIndex() { return index; } + public Element newInstance() { + return new ShaderElement(); + } + /** Returns the instance of this element in the passed State. */ + public static ShaderElement getInstance(State state) { + return (ShaderElement) state.getElement(index); + } + /** Enables this element in the passed state, which should be the + default for a given action. */ + public static void enable(State defaultState) { + ShaderElement tmp = new ShaderElement(); + defaultState.setElement(tmp.getStateIndex(), tmp); + } + /** Indicates whether this element is enabled in the given default + state for a particular action. */ + public static boolean isEnabled(State state) { + return (state.getDefaults().getElement(index) != null); + } + + // This particular element refers to the ShaderNode directly. + // Having it refer to the Shader object doesn't really make sense, + // because the Shader object implicitly relies on OpenGL and the + // intent is to make the base element class not reliant on GL. + + // The ShaderNode + protected ShaderNode shader; + + /** Sets the shader in the given state. */ + public static void set(State state, ShaderNode shader) { + getInstance(state).setElt(shader); + } + + /** Returns the current shader in the state. */ + public static ShaderNode get(State state) { + return getInstance(state).shader; + } + + public void push(State state) { + ShaderElement prev = (ShaderElement) getNextInStack(); + if (prev != null) { + // Pull down the shader from the previous element + shader = prev.shader; + } + } + + /** Sets the shader in this element. */ + public void setElt(ShaderNode shader) { + this.shader = shader; + } +} diff --git a/src/net/java/joglutils/msg/misc/Shader.java b/src/net/java/joglutils/msg/misc/Shader.java new file mode 100644 index 0000000..c816629 --- /dev/null +++ b/src/net/java/joglutils/msg/misc/Shader.java @@ -0,0 +1,508 @@ +/* + * Copyright (c) 2007 Sun Microsystems, Inc. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, + * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN + * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR + * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR + * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR + * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR + * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE + * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, + * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF + * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed or intended for use + * in the design, construction, operation or maintenance of any nuclear + * facility. + */ + +package net.java.joglutils.msg.misc; + +import javax.media.opengl.GL; +import javax.media.opengl.GLException; +import javax.media.opengl.glu.GLU; +import static javax.media.opengl.GL.*; + +/** + * Represents an OpenGL shader program object, which can be constructed from + * the source code for a vertex shader, a fragment shader, or both. + * Contains convenience methods for enabling/disabling shader state. + *

+ * Usage example: + *

+ *     String source =
+ *         "uniform sampler2D myTex;" +
+ *         "void main(void)" +
+ *         "{" +
+ *         "    vec4 src = texture2D(myTex, gl_TexCoord[0].st);" +
+ *         "    gl_FragColor = src.bgra;" + // swizzle!
+ *         "}";
+ *     Shader shader = new Shader(source);
+ *     shader.setUniform("myTex", 0); // myTex will be on texture unit 0
+ *     ...
+ *     shader.enable();
+ *     texture.enable();
+ *     texture.bind();
+ *     ...
+ *     texture.disable();
+ *     shader.disable();
+ * };
+ * 
+ * + * @author Chris Campbell + */ +public class Shader { + + /** + * The handle to the OpenGL fragment program object. + */ + private int id; + + /** + * Creates a new shader program object and compiles/links the provided + * fragment shader code into that object. + * + * @param fragmentCode a {@code String} representing the fragment shader + * source code to be compiled and linked + * + * @throws GLException if no OpenGL context was current or if any + * OpenGL-related errors occurred + */ + public Shader(String fragmentCode) + throws GLException + { + GL gl = GLU.getCurrentGL(); + id = createProgram(gl, null, fragmentCode); + } + + /** + * Creates a new shader program object and compiles/links the provided + * vertex shader and fragment shader code into that object. + * + * @param vertexCode a {@code String} representing the vertex shader + * source code to be compiled and linked; this may be null if only a + * fragment shader is going to be needed + * @param fragmentCode a {@code String} representing the fragment shader + * source code to be compiled and linked; this may be null if only a + * vertex shader is going to be needed + * + * @throws GLException if no OpenGL context was current or if any + * OpenGL-related errors occurred + */ + public Shader(String vertexCode, String fragmentCode) + throws GLException + { + GL gl = GLU.getCurrentGL(); + id = createProgram(gl, vertexCode, fragmentCode); + } + + /** + * Compiles and links a new shader program using the given sources. If + * successful, this function returns a handle to the newly created shader + * program; otherwise returns 0. + * + * @throws GLException if no OpenGL context was current or if any + * OpenGL-related errors occurred + */ + private static int createProgram(GL gl, + String vertexShaderSource, + String fragmentShaderSource) + throws GLException + { + if (vertexShaderSource == null && fragmentShaderSource == null) { + throw new GLException( + "Either vertexShaderSource or fragmentShaderSource " + + "must be specified"); + } + + int shaderProgram; + int vertexShader = 0; + int fragmentShader = 0; + int[] success = new int[1]; + int[] infoLogLength = new int[1]; + + if (vertexShaderSource != null) { + vertexShader = compileShader(gl, vertexShaderSource, true); + if (vertexShader == 0) { + return 0; + } + } + + if (fragmentShaderSource != null) { + fragmentShader = compileShader(gl, fragmentShaderSource, false); + if (fragmentShader == 0) { + if (vertexShader != 0) { + gl.glDeleteObjectARB(vertexShader); + } + return 0; + } + } + + // create the program object and attach it to the shader + shaderProgram = gl.glCreateProgramObjectARB(); + if (vertexShader != 0) { + gl.glAttachObjectARB(shaderProgram, vertexShader); + // it is now safe to delete the shader object + gl.glDeleteObjectARB(vertexShader); + } + if (fragmentShader != 0) { + gl.glAttachObjectARB(shaderProgram, fragmentShader); + // it is now safe to delete the shader object + gl.glDeleteObjectARB(fragmentShader); + } + + // link the program + gl.glLinkProgramARB(shaderProgram); + gl.glGetObjectParameterivARB(shaderProgram, + GL_OBJECT_LINK_STATUS_ARB, + success, 0); + + // print the linker messages, if necessary + gl.glGetObjectParameterivARB(shaderProgram, + GL_OBJECT_INFO_LOG_LENGTH_ARB, + infoLogLength, 0); + if (infoLogLength[0] > 1) { + byte[] infoLog = new byte[1024]; + gl.glGetInfoLogARB(shaderProgram, 1024, null, 0, infoLog, 0); + System.err.println("Linker message: " + + new String(infoLog)); + } + + if (success[0] == 0) { + gl.glDeleteObjectARB(shaderProgram); + return 0; + } + + return shaderProgram; + } + + /** + * Compiles the given shader program. If successful, this function returns + * a handle to the newly created shader object; otherwise returns 0. + * + * @throws GLException if no OpenGL context was current or if any + * OpenGL-related errors occurred + */ + private static int compileShader(GL gl, String shaderSource, boolean vertex) + throws GLException + { + int kind = vertex ? GL_VERTEX_SHADER_ARB : GL_FRAGMENT_SHADER_ARB; + int shader; + int[] success = new int[1]; + int[] infoLogLength = new int[1]; + + // create the shader object and compile the shader source code + shader = gl.glCreateShaderObjectARB(kind); + gl.glShaderSourceARB(shader, 1, new String[] { shaderSource }, null, 0); + gl.glCompileShaderARB(shader); + gl.glGetObjectParameterivARB(shader, + GL_OBJECT_COMPILE_STATUS_ARB, + success, 0); + + // print the compiler messages, if necessary + gl.glGetObjectParameterivARB(shader, + GL_OBJECT_INFO_LOG_LENGTH_ARB, + infoLogLength, 0); + if (infoLogLength[0] > 1) { + byte[] infoLog = new byte[1024]; + gl.glGetInfoLogARB(shader, 1024, null, 0, infoLog, 0); + System.err.println((vertex ? "Vertex" : "Fragment") + + " compile message: " + + new String(infoLog)); + } + + if (success[0] == 0) { + gl.glDeleteObjectARB(shader); + return 0; + } + + return shader; + } + + /** + * Returns the underlying OpenGL program object handle for this fragment + * shader. Most applications will not need to access this, since it is + * handled automatically by the enable() and dispose() methods. + * + * @return the OpenGL program object handle for this fragment shader + */ + public int getProgramObject() { + return id; + } + + /** + * Enables this shader program in the current GL context's state. + * + * @throws GLException if no OpenGL context was current or if any + * OpenGL-related errors occurred + */ + public void enable() throws GLException { + GL gl = GLU.getCurrentGL(); + gl.glUseProgramObjectARB(id); + } + + /** + * Disables this shader program in the current GL context's state. + * + * @throws GLException if no OpenGL context was current or if any + * OpenGL-related errors occurred + */ + public void disable() throws GLException { + GL gl = GLU.getCurrentGL(); + gl.glUseProgramObjectARB(0); + } + + /** + * Disposes the native resources used by this program object. + * + * @throws GLException if no OpenGL context was current or if any + * OpenGL-related errors occurred + */ + public void dispose() throws GLException { + GL gl = GLU.getCurrentGL(); + gl.glDeleteObjectARB(id); + id = 0; + } + + /** + * 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 + * @throws GLException if no OpenGL context was current or if any + * OpenGL-related errors occurred + */ + public void setUniform(String name, int i0) + throws GLException + { + GL gl = GLU.getCurrentGL(); + int loc = gl.glGetUniformLocationARB(id, name); + gl.glUniform1iARB(loc, i0); + } + + /** + * Sets the uniform variable of the given name with the provided + * integer values. + * + * @param name the name of the uniform variable to be set + * @param i0 the first uniform parameter + * @param i1 the second uniform parameter + * @throws GLException if no OpenGL context was current or if any + * OpenGL-related errors occurred + */ + public void setUniform(String name, int i0, int i1) + throws GLException + { + GL gl = GLU.getCurrentGL(); + int loc = gl.glGetUniformLocationARB(id, name); + gl.glUniform2iARB(loc, i0, i1); + } + + /** + * Sets the uniform variable of the given name with the provided + * integer values. + * + * @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 + * @throws GLException if no OpenGL context was current or if any + * OpenGL-related errors occurred + */ + public void setUniform(String name, int i0, int i1, int i2) + throws GLException + { + GL gl = GLU.getCurrentGL(); + int loc = gl.glGetUniformLocationARB(id, name); + gl.glUniform3iARB(loc, i0, i1, i2); + } + + /** + * Sets the uniform variable of the given name with the provided + * integer values. + * + * @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 + * @throws GLException if no OpenGL context was current or if any + * OpenGL-related errors occurred + */ + public void setUniform(String name, int i0, int i1, int i2, int i3) + throws GLException + { + GL gl = GLU.getCurrentGL(); + int loc = gl.glGetUniformLocationARB(id, name); + gl.glUniform4iARB(loc, i0, i1, i2, i3); + } + + /** + * Sets the uniform variable of the given name with the provided + * float value. + * + * @param name the name of the uniform variable to be set + * @param f0 the first uniform parameter + * @throws GLException if no OpenGL context was current or if any + * OpenGL-related errors occurred + */ + public void setUniform(String name, float f0) + throws GLException + { + GL gl = GLU.getCurrentGL(); + int loc = gl.glGetUniformLocationARB(id, name); + gl.glUniform1fARB(loc, f0); + } + + /** + * Sets the uniform variable of the given name with the provided + * float values. + * + * @param name the name of the uniform variable to be set + * @param f0 the first uniform parameter + * @param f1 the second uniform parameter + * @throws GLException if no OpenGL context was current or if any + * OpenGL-related errors occurred + */ + public void setUniform(String name, float f0, float f1) + throws GLException + { + GL gl = GLU.getCurrentGL(); + int loc = gl.glGetUniformLocationARB(id, name); + gl.glUniform2fARB(loc, f0, f1); + } + + /** + * Sets the uniform variable of the given name with the provided + * float values. + * + * @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 + * @throws GLException if no OpenGL context was current or if any + * OpenGL-related errors occurred + */ + public void setUniform(String name, float f0, float f1, float f2) + throws GLException + { + GL gl = GLU.getCurrentGL(); + int loc = gl.glGetUniformLocationARB(id, name); + gl.glUniform3fARB(loc, f0, f1, f2); + } + + /** + * Sets the uniform variable of the given name with the provided + * float values. + * + * @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 + * @throws GLException if no OpenGL context was current or if any + * OpenGL-related errors occurred + */ + public void setUniform(String name, float f0, float f1, float f2, float f3) + throws GLException + { + GL gl = GLU.getCurrentGL(); + int loc = gl.glGetUniformLocationARB(id, name); + gl.glUniform4fARB(loc, f0, f1, f2, f3); + } + + /** + * 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 + * @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 + * @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) + throws GLException + { + GL gl = GLU.getCurrentGL(); + int loc = gl.glGetUniformLocationARB(id, name); + gl.glUniform1fvARB(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 + * @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 + * @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) + throws GLException + { + GL gl = GLU.getCurrentGL(); + int loc = gl.glGetUniformLocationARB(id, name); + gl.glUniform2fvARB(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 + * @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 + * @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) + throws GLException + { + GL gl = GLU.getCurrentGL(); + int loc = gl.glGetUniformLocationARB(id, name); + gl.glUniform3fvARB(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 + * @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) + throws GLException + { + GL gl = GLU.getCurrentGL(); + int loc = gl.glGetUniformLocationARB(id, name); + gl.glUniform4fvARB(loc, count, vals, off); + } +} diff --git a/src/net/java/joglutils/msg/nodes/ShaderNode.java b/src/net/java/joglutils/msg/nodes/ShaderNode.java new file mode 100644 index 0000000..73154ee --- /dev/null +++ b/src/net/java/joglutils/msg/nodes/ShaderNode.java @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2007 Sun Microsystems, Inc. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, + * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN + * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR + * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR + * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR + * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR + * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE + * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, + * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF + * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed or intended for use + * in the design, construction, operation or maintenance of any nuclear + * facility. + */ + +package net.java.joglutils.msg.nodes; + +import java.awt.image.*; +import java.io.*; +import java.net.*; +import java.util.*; + +import javax.media.opengl.*; + +import net.java.joglutils.msg.actions.*; +import net.java.joglutils.msg.elements.*; +import net.java.joglutils.msg.misc.*; + +/** Represents a vertex/fragment shader. */ +public class ShaderNode extends Node { + + private String vertexShaderCode; + private String fragmentShaderCode; + private Shader shader; + private List disposedShaders = new ArrayList(); + + static { + // Enable the elements this node affects for known actions + GLShaderElement.enable(GLRenderAction.getDefaultState()); + } + + /** Initializes this shader from the given String. No OpenGL work is + done during this call; it is done lazily when the Shader is + fetched. */ + public void setShader(String fragmentShaderCode) { + disposeShader(); + this.vertexShaderCode = null; + this.fragmentShaderCode = fragmentShaderCode; + } + + /** Initializes this shader from the given String. No OpenGL work is + done during this call; it is done lazily when the Shader is + fetched. */ + public void setShader(String vertexShaderCode, String fragmentShaderCode) { + disposeShader(); + this.vertexShaderCode = vertexShaderCode; + this.fragmentShaderCode = fragmentShaderCode; + } + + /** Fetches the Shader object associated with this ShaderNode. + It is required to call this each frame during rendering. + An OpenGL context must be current at the time this method is + called or a GLException will be thrown. */ + public Shader getShader() throws GLException { + lazyDispose(); + if (shader == null) { + this.shader = new Shader(vertexShaderCode, fragmentShaderCode); + } + return shader; + } + + public void doAction(Action action) { + if (ShaderElement.isEnabled(action.getState())) { + ShaderElement.set(action.getState(), this); + } + } + + private synchronized void disposeShader() { + if (shader != null) { + disposedShaders.add(shader); + shader = null; + } + } + + private void lazyDispose() { + while (!disposedShaders.isEmpty()) { + Shader s = null; + synchronized (this) { + s = disposedShaders.remove(disposedShaders.size() - 1); + } + s.dispose(); + } + } +} -- cgit v1.2.3