Ok, here’s my first commit to jME. After studying jME and some questions to renanse, I’ve made this ShaderObjectsState working. It works very well, but I don’t know if the code is correct for jME (understand that some part of the code could have been made better using existing jME features)… Just tell me what’s wrong and I’ll correct it
First, here are the modifications to existing code :
Renderer.java
/**
* <code>createShaderObjectsState</code> retrieves the shader object state object for the
* proper renderer.
*
* @return the <code>ShaderObjectsState</code> object that can make use of the
* proper renderer.
*/
public ShaderObjectsState createShaderObjectsState();
LWJGLRenderer.java
/**
* <code>createShaderObjectsState</code> returns a new LWJGLShaderObjectsState
* object as a regular ShaderObjectsState.
*
* @return an ShaderObjectsState object.
*/
public ShaderObjectsState createShaderObjectsState() {
return new LWJGLShaderObjectsState();
}
RenderState.java
/** The value returned by getType() for ShaderObjectsState. */
public final static int RS_SHADER_OBJECTS = 14;
/** The total number of diffrent types of RenderState. */
public final static int RS_MAX_STATE = 15;
DisplaySystem.java
/**
* Called when the display system is created, this function sets the default render states for
* the renderer. It should not be called directly by the user.
* @param r The renderer to get the default states from.
*/
public static void updateStates(Renderer r) {
// ... //
Spatial.defaultStateList[RenderState.RS_SHADER_OBJECTS] = r.createShaderObjectsState();
Spatial.defaultStateList[RenderState.RS_SHADER_OBJECTS].setEnabled(false);
}
DummyDisplaySystem.java
public ShaderObjectsState createShaderObjectsState() {
return new ShaderObjectsState(){
public boolean isSupported() {return false;}
public void load(URL vert, URL frag) {}
public void apply() {}
};
}
public ShaderObjectsState getShaderObjectsState() {return createShaderObjectsState();}
Matrix3f.java
/**
* <code>toFloatBuffer</code> returns a FloatBuffer object that contains the
* matrix data.
*
* @return matrix data as a FloatBuffer.
*/
public FloatBuffer toFloatBuffer()
{
FloatBuffer fb = BufferUtils.createFloatBuffer(9);
fb.put(m00).put(m01).put(m02);
fb.put(m10).put(m11).put(m12);
fb.put(m20).put(m21).put(m22);
fb.rewind();
return fb;
}
Matrix4f.java
/**
* <code>toFloatBuffer</code> returns a FloatBuffer object that contains the
* matrix data.
*
* @return matrix data as a FloatBuffer.
*/
public FloatBuffer toFloatBuffer()
{
FloatBuffer fb = BufferUtils.createFloatBuffer(16);
fb.put(matrix[0]).put(matrix[1]).put(matrix[2]).put(matrix[3]);
fb.rewind();
return fb;
}
The state code now :
ShaderObjectsState.java
/*
* Copyright (c) 2003-2004, jMonkeyEngine - Mojo Monkey Coding
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* Redistributions 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 the Mojo Monkey Coding, jME, jMonkey Engine, nor the
* names of its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
package com.jme.scene.state;
import java.net.URL;
import java.util.HashMap;
import com.jme.math.Matrix3f;
import com.jme.math.Matrix4f;
import com.jme.util.ShaderUniform;
/**
* Implementation of the GL_ARB_shader_objects extension.
* @author Thomas Hourdel
*/
public abstract class ShaderObjectsState extends RenderState {
public HashMap uniforms = new HashMap();
/**
* <code>isSupported</code> determines if the ARB_shader_objects extension
* is supported by current graphics configuration.
* @return if ARB shader objects are supported
*/
public abstract boolean isSupported();
/**
* Set an uniform value for this shader object.
*
* @param var uniform variable to change
* @param value the new value
*/
public void setUniform(String var, int value) {
ShaderUniform object = new ShaderUniform(var, ShaderUniform.SU_INT);
object.vint = new int[1];
object.vint[0] = value;
uniforms.put(var, object);
}
/**
* Set an uniform value for this shader object.
*
* @param var uniform variable to change
* @param value the new value
*/
public void setUniform(String var, float value) {
ShaderUniform object = new ShaderUniform(var, ShaderUniform.SU_FLOAT);
object.vfloat = new float[1];
object.vfloat[0] = value;
uniforms.put(var, object);
}
/**
* Set an uniform value for this shader object.
*
* @param var uniform variable to change
* @param value1 the new value
* @param value2 the new value
*/
public void setUniform(String var, int value1, int value2) {
ShaderUniform object = new ShaderUniform(var, ShaderUniform.SU_INT2);
object.vint = new int[2];
object.vint[0] = value1;
object.vint[1] = value2;
uniforms.put(var, object);
}
/**
* Set an uniform value for this shader object.
*
* @param var uniform variable to change
* @param value1 the new value
* @param value2 the new value
*/
public void setUniform(String var, float value1, float value2) {
ShaderUniform object = new ShaderUniform(var, ShaderUniform.SU_FLOAT2);
object.vfloat = new float[2];
object.vfloat[0] = value1;
object.vfloat[1] = value2;
uniforms.put(var, object);
}
/**
* Set an uniform value for this shader object.
*
* @param var uniform variable to change
* @param value1 the new value
* @param value2 the new value
* @param value3 the new value
*/
public void setUniform(String var, int value1, int value2, int value3) {
ShaderUniform object = new ShaderUniform(var, ShaderUniform.SU_INT3);
object.vint = new int[3];
object.vint[0] = value1;
object.vint[1] = value2;
object.vint[2] = value3;
uniforms.put(var, object);
}
/**
* Set an uniform value for this shader object.
*
* @param var uniform variable to change
* @param value1 the new value
* @param value2 the new value
* @param value3 the new value
*/
public void setUniform(String var, float value1, float value2, float value3) {
ShaderUniform object = new ShaderUniform(var, ShaderUniform.SU_FLOAT3);
object.vfloat = new float[3];
object.vfloat[0] = value1;
object.vfloat[1] = value2;
object.vfloat[2] = value3;
uniforms.put(var, object);
}
/**
* Set an uniform value for this shader object.
*
* @param var uniform variable to change
* @param value1 the new value
* @param value2 the new value
* @param value3 the new value
* @param value4 the new value
*/
public void setUniform(String var, int value1, int value2, int value3, int value4) {
ShaderUniform object = new ShaderUniform(var, ShaderUniform.SU_INT4);
object.vint = new int[4];
object.vint[0] = value1;
object.vint[1] = value2;
object.vint[2] = value3;
object.vint[3] = value4;
uniforms.put(var, object);
}
/**
* Set an uniform value for this shader object.
*
* @param var uniform variable to change
* @param value1 the new value
* @param value2 the new value
* @param value3 the new value
* @param value4 the new value
*/
public void setUniform(String var, float value1, float value2, float value3, float value4) {
ShaderUniform object = new ShaderUniform(var, ShaderUniform.SU_FLOAT4);
object.vfloat = new float[4];
object.vfloat[0] = value1;
object.vfloat[1] = value2;
object.vfloat[2] = value3;
object.vfloat[3] = value4;
uniforms.put(var, object);
}
/**
* Set an uniform value for this shader object.
*
* @param var uniform variable to change
* @param value the new value (a float buffer of size 4)
* @param transpose transpose the matrix ?
*/
public void setUniform(String var, float value[], boolean transpose) {
if(value.length != 4)
return;
ShaderUniform object = new ShaderUniform(var, ShaderUniform.SU_MATRIX2);
object.matrix2f = new float[4];
object.matrix2f = value;
object.transpose = transpose;
uniforms.put(var, object);
}
/**
* Set an uniform value for this shader object.
*
* @param var uniform variable to change
* @param value the new value
* @param transpose transpose the matrix ?
*/
public void setUniform(String var, Matrix3f value, boolean transpose) {
ShaderUniform object = new ShaderUniform(var, ShaderUniform.SU_MATRIX3);
object.matrix3f = value;
object.transpose = transpose;
uniforms.put(var, object);
}
/**
* Set an uniform value for this shader object.
*
* @param var uniform variable to change
* @param value the new value
* @param transpose transpose the matrix ?
*/
public void setUniform(String var, Matrix4f value, boolean transpose) {
ShaderUniform object = new ShaderUniform(var, ShaderUniform.SU_MATRIX4);
object.matrix4f = value;
object.transpose = transpose;
uniforms.put(var, object);
}
/**
* Set an uniform value for the shader object.
*
* @param var uniform variable to change
* @param sampler the new value
*/
public void setUniform(String var, com.jme.image.Texture sampler) {
setUniform(var, sampler.getTextureId());
}
/**
* @return RS_SHADER_OBJECTS
* @see com.jme.scene.state.RenderState#getType()
*/
public int getType() {
return RS_SHADER_OBJECTS;
}
/**
* <code>load</code> loads the shader object from the specified file.
* The program must be in ASCII format. We delegate the loading to each
* implementation because we do not know in what format the underlying API
* wants the data.
* @param vert text file containing the vertex shader object
* @param frag text file containing the fragment shader object
*/
public abstract void load(URL vert, URL frag);
}
LWJGLShaderObjectsState.java
/*
* Copyright (c) 2003-2004, jMonkeyEngine - Mojo Monkey Coding
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* Redistributions 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 the Mojo Monkey Coding, jME, jMonkey Engine, nor the
* names of its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
package com.jme.scene.state.lwjgl;
import java.io.BufferedInputStream;
import java.io.DataInputStream;
import java.net.URL;
import java.nio.ByteBuffer;
import java.nio.IntBuffer;
import java.util.Iterator;
import java.util.logging.Level;
import org.lwjgl.BufferUtils;
import org.lwjgl.opengl.*;
import com.jme.scene.state.ShaderObjectsState;
import com.jme.util.LoggingSystem;
import com.jme.util.ShaderUniform;
/**
* Implementation of the GL_ARB_shader_objects extension.
* @author Thomas Hourdel
*/
public class LWJGLShaderObjectsState extends ShaderObjectsState {
/** OpenGL id for this program. **/
private int programID = -1;
/**
* Determines if the current OpenGL context supports the
* GL_ARB_shader_objects extension.
* @see com.jme.scene.state.ShaderObjectsState#isSupported()
*/
public boolean isSupported() {
return GLContext.GL_ARB_shader_objects;
}
/**
* Get uniform variable location according to his string name.
*
* @param name uniform variable name
*/
private int getUniLoc(String name) {
ByteBuffer nameBuf = BufferUtils.createByteBuffer(name.getBytes().length);
nameBuf.clear();
nameBuf.put(name.getBytes());
nameBuf.rewind();
return ARBShaderObjects.glGetUniformLocationARB(programID, nameBuf);
}
/**
* Load an URL and grab content into a ByteBuffer.
*
* @param url the url to load
*/
private ByteBuffer load(java.net.URL url) {
try {
byte shaderCode[] = null;
ByteBuffer shaderByteBuffer = null;
BufferedInputStream bufferedInputStream = new BufferedInputStream(url.openStream());
DataInputStream dataStream = new DataInputStream(bufferedInputStream);
dataStream.readFully(shaderCode = new byte[bufferedInputStream.available()]);
bufferedInputStream.close();
dataStream.close();
shaderByteBuffer = BufferUtils.createByteBuffer(shaderCode.length);
shaderByteBuffer.put(shaderCode);
shaderByteBuffer.rewind();
return shaderByteBuffer;
} catch (Exception e) {
LoggingSystem.getLogger().log(Level.SEVERE,
"Could not load shader object: " + e);
LoggingSystem.getLogger().throwing(getClass().getName(),
"load(URL)", e);
return null;
}
}
/**
* Loads the shader object.
* @see com.jme.scene.state.ShaderObjectsState#load(java.net.URL, java.net.URL)
*/
public void load(URL vert, URL frag) {
ByteBuffer vertexByteBuffer = load(vert);
ByteBuffer fragmentByteBuffer = load(frag);
if(vertexByteBuffer != null || fragmentByteBuffer != null) {
// Create the shader objects
int vertexShaderID = ARBShaderObjects.glCreateShaderObjectARB(ARBVertexShader.GL_VERTEX_SHADER_ARB);
int fragmentShaderID = ARBShaderObjects.glCreateShaderObjectARB(ARBFragmentShader.GL_FRAGMENT_SHADER_ARB);
// Create the sources
ARBShaderObjects.glShaderSourceARB(vertexShaderID, vertexByteBuffer);
ARBShaderObjects.glShaderSourceARB(fragmentShaderID, fragmentByteBuffer);
// Compile the vertex shader
IntBuffer compiled = BufferUtils.createIntBuffer(1);
ARBShaderObjects.glCompileShaderARB(vertexShaderID);
ARBShaderObjects.glGetObjectParameterARB(vertexShaderID, ARBShaderObjects.GL_OBJECT_COMPILE_STATUS_ARB, compiled);
checkProgramError(compiled, vertexShaderID);
// Compile the fragment shader
compiled.clear();
ARBShaderObjects.glCompileShaderARB(fragmentShaderID);
ARBShaderObjects.glGetObjectParameterARB(fragmentShaderID, ARBShaderObjects.GL_OBJECT_COMPILE_STATUS_ARB, compiled);
checkProgramError(compiled, fragmentShaderID);
// Create the program
programID = ARBShaderObjects.glCreateProgramObjectARB();
ARBShaderObjects.glAttachObjectARB(programID, vertexShaderID);
ARBShaderObjects.glAttachObjectARB(programID, fragmentShaderID);
ARBShaderObjects.glLinkProgramARB(programID);
}
}
/**
* Check for program errors. If an error is detected, program exits.
*
* @param compiled the compiler state for a given shader
* @param id shader's id
*/
private void checkProgramError(IntBuffer compiled, int id) {
if(compiled.get(0) == 0) {
IntBuffer iVal = BufferUtils.createIntBuffer(1);
ARBShaderObjects.glGetObjectParameterARB(id, ARBShaderObjects.GL_OBJECT_INFO_LOG_LENGTH_ARB, iVal);
int length = iVal.get();
String out = null;
if(length > 0) {
ByteBuffer infoLog = BufferUtils.createByteBuffer(length);
iVal.flip();
ARBShaderObjects.glGetInfoLogARB(id, iVal, infoLog);
byte[] infoBytes = new byte[length];
infoLog.get(infoBytes);
out = new String(infoBytes);
}
LoggingSystem.getLogger().log(Level.SEVERE, out);
System.exit(0);
}
}
/**
* Applies those shader objects to the current scene. Checks if the
* GL_ARB_shader_objects extension is supported before attempting to enable
* those objects.
* @see com.jme.scene.state.RenderState#apply()
*/
public void apply() {
if(isSupported()) {
if(isEnabled()) {
if(programID != -1) {
// Apply the shader...
ARBShaderObjects.glUseProgramObjectARB(programID);
// Assign uniforms...
if(!uniforms.isEmpty()) {
for(Iterator iterator = uniforms.keySet().iterator(); iterator.hasNext();) {
ShaderUniform uniformVar = (ShaderUniform)uniforms.get((String)iterator.next());
switch(uniformVar.type) {
case ShaderUniform.SU_INT:
ARBShaderObjects.glUniform1iARB(getUniLoc(uniformVar.name),
uniformVar.vint[0]);
break;
case ShaderUniform.SU_INT2:
ARBShaderObjects.glUniform2iARB(getUniLoc(uniformVar.name),
uniformVar.vint[0],
uniformVar.vint[1]);
break;
case ShaderUniform.SU_INT3:
ARBShaderObjects.glUniform3iARB(getUniLoc(uniformVar.name),
uniformVar.vint[0],
uniformVar.vint[1],
uniformVar.vint[2]);
break;
case ShaderUniform.SU_INT4:
ARBShaderObjects.glUniform4iARB(getUniLoc(uniformVar.name),
uniformVar.vint[0],
uniformVar.vint[1],
uniformVar.vint[2],
uniformVar.vint[3]);
break;
case ShaderUniform.SU_FLOAT:
ARBShaderObjects.glUniform1fARB(getUniLoc(uniformVar.name),
uniformVar.vfloat[0]);
break;
case ShaderUniform.SU_FLOAT2:
ARBShaderObjects.glUniform2fARB(getUniLoc(uniformVar.name),
uniformVar.vfloat[0],
uniformVar.vfloat[1]);
break;
case ShaderUniform.SU_FLOAT3:
ARBShaderObjects.glUniform3fARB(getUniLoc(uniformVar.name),
uniformVar.vfloat[0],
uniformVar.vfloat[1],
uniformVar.vfloat[2]);
break;
case ShaderUniform.SU_FLOAT4:
ARBShaderObjects.glUniform4fARB(getUniLoc(uniformVar.name),
uniformVar.vfloat[0],
uniformVar.vfloat[1],
uniformVar.vfloat[2],
uniformVar.vfloat[3]);
break;
case ShaderUniform.SU_MATRIX2:
final java.nio.FloatBuffer matrix2f = org.lwjgl.BufferUtils.createFloatBuffer(4);
matrix2f.clear();
matrix2f.put(uniformVar.matrix2f);
matrix2f.rewind();
ARBShaderObjects.glUniformMatrix2ARB(getUniLoc(uniformVar.name),
uniformVar.transpose,
matrix2f);
break;
case ShaderUniform.SU_MATRIX3:
ARBShaderObjects.glUniformMatrix3ARB(getUniLoc(uniformVar.name),
uniformVar.transpose,
uniformVar.matrix3f.toFloatBuffer());
break;
case ShaderUniform.SU_MATRIX4:
ARBShaderObjects.glUniformMatrix4ARB(getUniLoc(uniformVar.name),
uniformVar.transpose,
uniformVar.matrix4f.toFloatBuffer());
break;
default: // Sould never happen.
break;
}
}
}
}
} else {
ARBShaderObjects.glUseProgramObjectARB(0);
}
}
}
}
ShaderUniform.java
/*
* Copyright (c) 2003-2004, jMonkeyEngine - Mojo Monkey Coding
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* Redistributions 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 the Mojo Monkey Coding, jME, jMonkey Engine, nor the
* names of its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
package com.jme.util;
import com.jme.math.Matrix3f;
import com.jme.math.Matrix4f;
/**
* An utily class to store shader's uniform variables content. Used by the <code>ShaderObjectsState</code> class.
* @author Thomas Hourdel
* @see com.jme.scene.state.ShaderObjectsState
*/
public class ShaderUniform {
public final static int SU_INT = 0;
public final static int SU_INT2 = 1;
public final static int SU_INT3 = 2;
public final static int SU_INT4 = 3;
public final static int SU_FLOAT = 4;
public final static int SU_FLOAT2 = 5;
public final static int SU_FLOAT3 = 6;
public final static int SU_FLOAT4 = 7;
public final static int SU_MATRIX2 = 8;
public final static int SU_MATRIX3 = 9;
public final static int SU_MATRIX4 = 10;
/** Name of the uniform variable. **/
public String name;
/** Type of uniform value. **/
public int type;
/** For int content. **/
public int vint[];
/** For float content. **/
public float vfloat[];
/** Matrix2f storage. **/
public float matrix2f[];
/** Matrix3f storage. **/
public Matrix3f matrix3f;
/** Matrix4f storage. **/
public Matrix4f matrix4f;
/** Used to transpose the matrix if wanted. **/
public boolean transpose;
/**
* Create a new uniform object.
*
* @param name uniform's name
* @param type uniform's value type
*/
public ShaderUniform(String name, int type) {
this.name = name;
this.type = type;
}
}
TestShaderObjectsState.java
/*
* Copyright (c) 2003-2004, jMonkeyEngine - Mojo Monkey Coding
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* Redistributions 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 the Mojo Monkey Coding, jME, jMonkey Engine, nor the
* names of its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
package jmetest.renderer.state;
import com.jme.app.SimpleGame;
import com.jme.input.NodeHandler;
import com.jme.math.Vector3f;
import com.jme.renderer.ColorRGBA;
import com.jme.scene.shape.Quad;
import com.jme.scene.state.ShaderObjectsState;
/**
* @author Thomas Hourdel
*/
public class TestShaderObjectsState extends SimpleGame {
public static void main(String[] args) {
TestShaderObjectsState app = new TestShaderObjectsState();
app.setDialogBehaviour(ALWAYS_SHOW_PROPS_DIALOG);
app.start();
}
protected void simpleInitGame() {
display.setTitle("GLSL");
display.getRenderer().setBackgroundColor(new ColorRGBA(0.0f, 0.0f, 0.0f, 0.0f));
cam.setLocation(new Vector3f(0, 0, 2));
cam.update();
input = new NodeHandler(this, rootNode, properties.getRenderer());
input.setKeySpeed(10);
input.setMouseSpeed(2);
Quad brick = createBrickQuad();
rootNode.attachChild(brick);
rootNode.updateRenderState();
}
private Quad createBrickQuad() {
ShaderObjectsState so = display.getRenderer().createShaderObjectsState();
// Check is GLSL is supported on current hardware.
if(!so.isSupported())
{
display.close();
System.exit(0);
}
so.load(TestShaderObjectsState.class.getClassLoader().getResource(
"jmetest/data/images/shader.vert"),
TestShaderObjectsState.class.getClassLoader().getResource(
"jmetest/data/images/shader.frag"));
so.setUniform("BrickColor", 1.0f, 0.3f, 0.2f);
so.setUniform("MortarColor", 0.85f, 0.86f, 0.84f);
so.setUniform("BrickSize", 0.30f, 0.15f);
so.setUniform("BrickPct", 0.90f, 0.85f);
so.setUniform("LightPosition", 0.0f, 0.0f, 4.0f);
so.setEnabled(true);
//Generate the torus
Quad box = new Quad("glslQuad", 1f, 1f);
box.setRenderState(so);
return box;
}
}
You can find the shaders for the test here.
Tell me what you think about it, I'll make all the changes needed.
Chman