summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorphil <[email protected]>2016-11-13 13:26:58 +1300
committerphil <[email protected]>2016-11-13 13:26:58 +1300
commit81c7243503fce67c85975d572d2fa32908f6ec86 (patch)
tree971eaea5ca22488c227f7599e6d47402310320d4
parent267f8e91cd4f1ad36a528b295e006b4b629385c0 (diff)
SimpleShaderAppearance moved to java3d-utils
from java3d-examples
-rw-r--r--src/main/java/org/jogamp/java3d/utils/shader/SimpleShaderAppearance.java473
-rw-r--r--src/main/java/org/jogamp/java3d/utils/shader/fixed_function_shader.frag108
-rw-r--r--src/main/java/org/jogamp/java3d/utils/shader/fixed_function_shader.vert141
3 files changed, 722 insertions, 0 deletions
diff --git a/src/main/java/org/jogamp/java3d/utils/shader/SimpleShaderAppearance.java b/src/main/java/org/jogamp/java3d/utils/shader/SimpleShaderAppearance.java
new file mode 100644
index 0000000..9c2b129
--- /dev/null
+++ b/src/main/java/org/jogamp/java3d/utils/shader/SimpleShaderAppearance.java
@@ -0,0 +1,473 @@
+/*
+ * Copyright (c) 2016 JogAmp Community. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+package org.jogamp.java3d.utils.shader;
+
+import org.jogamp.java3d.ColoringAttributes;
+import org.jogamp.java3d.GLSLShaderProgram;
+import org.jogamp.java3d.LineAttributes;
+import org.jogamp.java3d.Material;
+import org.jogamp.java3d.PolygonAttributes;
+import org.jogamp.java3d.RenderingAttributes;
+import org.jogamp.java3d.Shader;
+import org.jogamp.java3d.ShaderAppearance;
+import org.jogamp.java3d.ShaderAttributeSet;
+import org.jogamp.java3d.ShaderAttributeValue;
+import org.jogamp.java3d.SourceCodeShader;
+import org.jogamp.vecmath.Color3f;
+
+/**
+ * @author phil
+ *
+ */
+public class SimpleShaderAppearance extends ShaderAppearance
+{
+ private static GLSLShaderProgram flatShaderProgram;
+ private static GLSLShaderProgram textureShaderProgram;
+ private static GLSLShaderProgram colorLineShaderProgram;
+ private static GLSLShaderProgram litFlatShaderProgram;
+ private static GLSLShaderProgram litTextureShaderProgram;
+
+ public static String alphaTestUniforms = "uniform int alphaTestEnabled;\n" + //
+ "uniform int alphaTestFunction;\n" + //
+ "uniform float alphaTestValue;\n";
+
+ public static String alphaTestMethod = "if(alphaTestEnabled != 0)\n" + //
+ "{ \n" + //
+ " if(alphaTestFunction==516)//>\n" + //
+ " if(baseMap.a<=alphaTestValue)discard;\n" + //
+ " else if(alphaTestFunction==518)//>=\n" + //
+ " if(baseMap.a<alphaTestValue)discard;\n" + //
+ " else if(alphaTestFunction==514)//==\n" + //
+ " if(baseMap.a!=alphaTestValue)discard;\n" + //
+ " else if(alphaTestFunction==517)//!=\n" + //
+ " if(baseMap.a==alphaTestValue)discard;\n" + //
+ " else if(alphaTestFunction==513)//<\n" + //
+ " if(baseMap.a>=alphaTestValue)discard;\n" + //
+ " else if(alphaTestFunction==515)//<=\n" + //
+ " if(baseMap.a>alphaTestValue)discard;\n" + //
+ " else if(alphaTestFunction==512)//never \n" + //
+ " discard; \n" + //
+ "}\n";
+
+ /**
+ * Polygons no texture, no single color, must have color vertex attribute
+ */
+ public SimpleShaderAppearance()
+ {
+ this(null, false, false);
+ }
+
+ /**
+ * Lines with a single color no texture, ignores vertex attribute of color
+ * @param color
+ */
+ public SimpleShaderAppearance(Color3f color)
+ {
+ this(color, false, false);
+ }
+
+ /**
+ * Polygons if hasTexture is true a texture otherwise vertex attribute colors for face color
+ */
+ public SimpleShaderAppearance(boolean hasTexture)
+ {
+ this(null, false, hasTexture);
+ }
+
+ public SimpleShaderAppearance(boolean lit, boolean hasTexture)
+ {
+ this(null, lit, hasTexture);
+ }
+
+ /** if color is not null then a line appearance
+ * otherwise simple poly appearance
+ * @param color
+ */
+ private SimpleShaderAppearance(Color3f color, boolean lit, boolean hasTexture)
+ {
+ if (lit)
+ {
+ String vertexProgram = "#version 120\n";
+ vertexProgram += "attribute vec4 glVertex;\n";
+ vertexProgram += "attribute vec4 glColor;\n";
+ vertexProgram += "attribute vec3 glNormal; \n";
+ if (hasTexture)
+ {
+ vertexProgram += "attribute vec2 glMultiTexCoord0;\n";
+ }
+ vertexProgram += "uniform mat4 glModelViewProjectionMatrix;\n";
+ vertexProgram += "uniform mat4 glModelViewMatrix;\n";
+ vertexProgram += "uniform mat3 glNormalMatrix;\n";
+ vertexProgram += "uniform int ignoreVertexColors;\n";
+ vertexProgram += "uniform vec4 glLightModelambient;\n";
+ vertexProgram += "struct material\n";
+ vertexProgram += "{\n";
+ vertexProgram += " int lightEnabled;\n";
+ vertexProgram += " vec4 ambient;\n";
+ vertexProgram += " vec4 diffuse;\n";
+ vertexProgram += " vec4 emission; \n";
+ vertexProgram += " vec3 specular;\n";
+ vertexProgram += " float shininess;\n";
+ vertexProgram += "};\n";
+ vertexProgram += "uniform material glFrontMaterial;\n";
+ vertexProgram += "struct lightSource\n";
+ vertexProgram += " {\n";
+ vertexProgram += " vec4 position;\n";
+ vertexProgram += " vec4 diffuse;\n";
+ vertexProgram += " vec4 specular;\n";
+ vertexProgram += " float constantAttenuation, linearAttenuation, quadraticAttenuation;\n";
+ vertexProgram += " float spotCutoff, spotExponent;\n";
+ vertexProgram += " vec3 spotDirection;\n";
+ vertexProgram += " };\n";
+ vertexProgram += "\n";
+ vertexProgram += " uniform int numberOfLights;\n";
+ vertexProgram += " const int maxLights = 1;\n";
+ vertexProgram += " uniform lightSource glLightSource[maxLights];\n";
+ if (hasTexture)
+ {
+ vertexProgram += "varying vec2 glTexCoord0;\n";
+ }
+ vertexProgram += "varying vec3 LightDir;\n";
+ vertexProgram += "varying vec3 ViewDir;\n";
+ vertexProgram += "varying vec3 N;\n";
+ vertexProgram += "varying vec4 A;\n";
+ vertexProgram += "varying vec4 C;\n";
+ vertexProgram += "varying vec4 D;\n";
+ vertexProgram += "varying vec3 emissive;\n";
+ vertexProgram += "varying vec3 specular;\n";
+ vertexProgram += "varying float shininess;\n";
+ vertexProgram += "void main( void ){\n";
+ vertexProgram += "gl_Position = glModelViewProjectionMatrix * glVertex;\n";
+ if (hasTexture)
+ {
+ vertexProgram += "glTexCoord0 = glMultiTexCoord0.st;\n";
+ }
+
+ vertexProgram += "N = normalize(glNormalMatrix * glNormal);\n";
+
+ vertexProgram += "vec3 v = vec3(glModelViewMatrix * glVertex);\n";
+
+ vertexProgram += "ViewDir = -v.xyz;\n";
+ vertexProgram += "LightDir = glLightSource[0].position.xyz;\n";
+
+ vertexProgram += "A = glLightModelambient * glFrontMaterial.ambient;\n";
+ vertexProgram += "if( ignoreVertexColors != 0) \n";
+ // objectColor should be used if it is no lighting, and reusing material diffuse appears wrong
+ vertexProgram += " C = vec4(1,1,1,1);//glFrontMaterial.diffuse; \n";
+ vertexProgram += "else \n";
+ vertexProgram += " C = glColor; \n";
+
+ vertexProgram += "D = glLightSource[0].diffuse * glFrontMaterial.diffuse;\n";
+
+ vertexProgram += "emissive = glFrontMaterial.emission.rgb;\n";
+ vertexProgram += "specular = glFrontMaterial.specular;\n";
+ vertexProgram += "shininess = glFrontMaterial.shininess;\n";
+ vertexProgram += "}";
+
+ String fragmentProgram = "#version 120\n";
+ fragmentProgram += "precision mediump float;\n";
+ if (hasTexture)
+ {
+ fragmentProgram += alphaTestUniforms;
+
+ fragmentProgram += "varying vec2 glTexCoord0;\n";
+ fragmentProgram += "uniform sampler2D BaseMap;\n";
+ }
+
+ fragmentProgram += "in vec3 LightDir;\n";
+ fragmentProgram += "in vec3 ViewDir;\n";
+
+ fragmentProgram += "in vec3 N;\n";
+
+ fragmentProgram += "in vec4 A;\n";
+ fragmentProgram += "in vec4 C;\n";
+ fragmentProgram += "in vec4 D;\n";
+
+ fragmentProgram += "in vec3 emissive;\n";
+ fragmentProgram += "in vec3 specular;\n";
+ fragmentProgram += "in float shininess;\n";
+ fragmentProgram += "void main( void ){\n ";
+ if (hasTexture)
+ {
+ fragmentProgram += "vec4 baseMap = texture2D( BaseMap, glTexCoord0.st );\n";
+ }
+ if (hasTexture)
+ {
+ fragmentProgram += alphaTestMethod;
+ }
+ fragmentProgram += "vec3 normal = N;\n";
+
+ fragmentProgram += "vec3 L = normalize(LightDir);\n";
+ fragmentProgram += "vec3 E = normalize(ViewDir);\n";
+ fragmentProgram += "vec3 R = reflect(-L, normal);\n";
+ fragmentProgram += "vec3 H = normalize( L + E );\n";
+
+ fragmentProgram += "float NdotL = max( dot(normal, L), 0.0 );\n";
+ fragmentProgram += "float NdotH = max( dot(normal, H), 0.0 );\n";
+ fragmentProgram += "float EdotN = max( dot(normal, E), 0.0 );\n";
+ fragmentProgram += "float NdotNegL = max( dot(normal, -L), 0.0 );\n";
+
+ fragmentProgram += "vec4 color;\n";
+ if (hasTexture)
+ {
+ fragmentProgram += "vec3 albedo = baseMap.rgb * C.rgb;\n";
+ }
+ else
+ {
+ fragmentProgram += "vec3 albedo = C.rgb;\n";
+ }
+ fragmentProgram += "vec3 diffuse = A.rgb + (D.rgb * NdotL);\n";
+
+ // 0.3 is just what the calc is
+ fragmentProgram += "vec3 spec = specular * pow(NdotH, 0.3*shininess);\n";
+ // D is not right it should be the light source spec color, probably just 1,1,1 but java3d has no spec on lights
+ //fragmentProgram += "spec *= D.rgb;\n";
+
+ fragmentProgram += "color.rgb = albedo * (diffuse + emissive) + spec;\n";
+ if (hasTexture)
+ {
+ fragmentProgram += "color.a = C.a * baseMap.a;\n";
+ }
+ else
+ {
+ fragmentProgram += "color.a = C.a;\n";
+ }
+
+ fragmentProgram += "gl_FragColor = color;\n";
+
+ fragmentProgram += "}";
+ if (hasTexture)
+ {
+ if (litTextureShaderProgram == null)
+ {
+ litTextureShaderProgram = new GLSLShaderProgram() {
+ @Override
+ public String toString()
+ {
+ return "SimpleShaderAppearance litTextureShaderProgram";
+ }
+ };
+ litTextureShaderProgram.setShaders(makeShaders(vertexProgram, fragmentProgram));
+ litTextureShaderProgram.setShaderAttrNames(new String[] { "BaseMap" });
+
+ }
+
+ setShaderProgram(litTextureShaderProgram);
+
+ ShaderAttributeSet shaderAttributeSet = new ShaderAttributeSet();
+ shaderAttributeSet.put(new ShaderAttributeValue("BaseMap", new Integer(0)));
+ setShaderAttributeSet(shaderAttributeSet);
+ }
+ else
+ {
+ if (litFlatShaderProgram == null)
+ {
+ litFlatShaderProgram = new GLSLShaderProgram() {
+ @Override
+ public String toString()
+ {
+ return "SimpleShaderAppearance litFlatShaderProgram";
+ }
+ };
+ litFlatShaderProgram.setShaders(makeShaders(vertexProgram, fragmentProgram));
+
+ //System.out.println("vertexProgram " + vertexProgram);
+ //System.out.println("fragmentProgram " + fragmentProgram);
+
+ }
+
+ setShaderProgram(litFlatShaderProgram);
+
+ }
+ }
+ else
+ {
+ if (hasTexture)
+ {
+ if (textureShaderProgram == null)
+ {
+ textureShaderProgram = new GLSLShaderProgram() {
+ @Override
+ public String toString()
+ {
+ return "SimpleShaderAppearance textureShaderProgram";
+ }
+ };
+ String vertexProgram = "#version 120\n";
+ vertexProgram += "attribute vec4 glVertex;\n";
+ vertexProgram += "attribute vec2 glMultiTexCoord0;\n";
+ vertexProgram += "uniform mat4 glModelViewProjectionMatrix;\n";
+ vertexProgram += "varying vec2 glTexCoord0;\n";
+ vertexProgram += "void main( void ){\n";
+ vertexProgram += "gl_Position = glModelViewProjectionMatrix * glVertex;\n";
+ vertexProgram += "glTexCoord0 = glMultiTexCoord0.st;\n";
+ vertexProgram += "}";
+
+ String fragmentProgram = "#version 120\n";
+ fragmentProgram += "precision mediump float;\n";
+ fragmentProgram += alphaTestUniforms;
+ fragmentProgram += "varying vec2 glTexCoord0;\n";
+ fragmentProgram += "uniform sampler2D BaseMap;\n";
+ fragmentProgram += "void main( void ){\n ";
+ fragmentProgram += "vec4 baseMap = texture2D( BaseMap, glTexCoord0.st );\n";
+ fragmentProgram += alphaTestMethod;
+ fragmentProgram += "gl_FragColor = baseMap;\n";
+ fragmentProgram += "}";
+
+ textureShaderProgram.setShaders(makeShaders(vertexProgram, fragmentProgram));
+ textureShaderProgram.setShaderAttrNames(new String[] { "BaseMap" });
+ }
+
+ setShaderProgram(textureShaderProgram);
+
+ ShaderAttributeSet shaderAttributeSet = new ShaderAttributeSet();
+ shaderAttributeSet.put(new ShaderAttributeValue("BaseMap", new Integer(0)));
+ setShaderAttributeSet(shaderAttributeSet);
+
+ }
+ else
+
+ {
+ if (color != null)
+ {
+ PolygonAttributes polyAtt = new PolygonAttributes(PolygonAttributes.POLYGON_LINE, PolygonAttributes.CULL_NONE, 0.0f);
+ polyAtt.setPolygonOffset(0.1f);
+ setPolygonAttributes(polyAtt);
+ LineAttributes lineAtt = new LineAttributes(1, LineAttributes.PATTERN_SOLID, false);
+ setLineAttributes(lineAtt);
+
+ ColoringAttributes colorAtt = new ColoringAttributes(color, ColoringAttributes.FASTEST);
+ setColoringAttributes(colorAtt);
+
+ RenderingAttributes ra = new RenderingAttributes();
+ ra.setIgnoreVertexColors(true);
+ setRenderingAttributes(ra);
+
+ Material mat = new Material();
+ setMaterial(mat);
+
+ if (colorLineShaderProgram == null)
+ {
+ colorLineShaderProgram = new GLSLShaderProgram() {
+ @Override
+ public String toString()
+ {
+ return "SimpleShaderAppearance colorLineShaderProgram";
+ }
+ };
+ String vertexProgram = "#version 120\n";
+ vertexProgram += "attribute vec4 glVertex;\n";
+ vertexProgram += "attribute vec4 glColor;\n";
+ vertexProgram += "uniform int ignoreVertexColors;\n";
+ vertexProgram += "uniform vec4 objectColor;\n";
+ vertexProgram += "uniform mat4 glModelViewProjectionMatrix;\n";
+ vertexProgram += "varying vec4 glFrontColor;\n";
+ vertexProgram += "void main( void ){\n";
+ vertexProgram += "gl_Position = glModelViewProjectionMatrix * glVertex;\n";
+ vertexProgram += "if( ignoreVertexColors != 0 )\n";
+ vertexProgram += " glFrontColor = objectColor;\n";
+ vertexProgram += "else\n";
+ vertexProgram += " glFrontColor = glColor;\n";
+ vertexProgram += "}";
+
+ String fragmentProgram = "#version 120\n";
+ fragmentProgram += "precision mediump float;\n";
+ fragmentProgram += "varying vec4 glFrontColor;\n";
+ fragmentProgram += "void main( void ){\n";
+ fragmentProgram += "gl_FragColor = glFrontColor;\n";
+ fragmentProgram += "}";
+
+ colorLineShaderProgram.setShaders(makeShaders(vertexProgram, fragmentProgram));
+ }
+
+ setShaderProgram(colorLineShaderProgram);
+
+ }
+ else
+ {
+ RenderingAttributes ra = new RenderingAttributes();
+ setRenderingAttributes(ra);
+
+ if (flatShaderProgram == null)
+ {
+ flatShaderProgram = new GLSLShaderProgram() {
+ @Override
+ public String toString()
+ {
+ return "SimpleShaderAppearance flatShaderProgram";
+ }
+ };
+ String vertexProgram = "#version 120\n";
+ vertexProgram += "attribute vec4 glVertex;\n";
+ vertexProgram += "attribute vec4 glColor;\n";
+ vertexProgram += "uniform int ignoreVertexColors;\n";
+ vertexProgram += "uniform vec4 objectColor;\n";
+ vertexProgram += "uniform mat4 glModelViewProjectionMatrix;\n";
+ vertexProgram += "varying vec4 glFrontColor;\n";
+ vertexProgram += "void main( void ){\n";
+ vertexProgram += "gl_Position = glModelViewProjectionMatrix * glVertex;\n";
+ vertexProgram += "if( ignoreVertexColors != 0 )\n";
+ vertexProgram += " glFrontColor = objectColor;\n";
+ vertexProgram += "else\n";
+ vertexProgram += " glFrontColor = glColor;\n";
+ vertexProgram += "}";
+
+ String fragmentProgram = "#version 120\n";
+ fragmentProgram += "precision mediump float;\n";
+ fragmentProgram += "varying vec4 glFrontColor;\n";
+ fragmentProgram += "void main( void ){\n";
+ fragmentProgram += "gl_FragColor = glFrontColor;\n";
+ fragmentProgram += "}";
+
+ flatShaderProgram.setShaders(makeShaders(vertexProgram, fragmentProgram));
+
+ }
+
+ setShaderProgram(flatShaderProgram);
+
+ }
+ }
+
+ }
+
+ }
+
+ private static Shader[] makeShaders(String vertexProgram, String fragmentProgram)
+ {
+ Shader[] shaders = new Shader[2];
+ shaders[0] = new SourceCodeShader(Shader.SHADING_LANGUAGE_GLSL, Shader.SHADER_TYPE_VERTEX, vertexProgram) {
+ @Override
+ public String toString()
+ {
+ return "vertexProgram";
+ }
+ };
+ shaders[1] = new SourceCodeShader(Shader.SHADING_LANGUAGE_GLSL, Shader.SHADER_TYPE_FRAGMENT, fragmentProgram) {
+ @Override
+ public String toString()
+ {
+ return "fragmentProgram";
+ }
+ };
+ return shaders;
+ }
+}
diff --git a/src/main/java/org/jogamp/java3d/utils/shader/fixed_function_shader.frag b/src/main/java/org/jogamp/java3d/utils/shader/fixed_function_shader.frag
new file mode 100644
index 0000000..3da3ef6
--- /dev/null
+++ b/src/main/java/org/jogamp/java3d/utils/shader/fixed_function_shader.frag
@@ -0,0 +1,108 @@
+#version 140
+
+precision mediump float;
+
+
+uniform int alphaTestEnabled;
+uniform int alphaTestFunction;
+uniform float alphaTestValue;
+
+struct fogData
+{
+ int fogEnabled;
+ vec4 expColor;
+ float expDensity;
+ vec4 linearColor;
+ float linearStart;
+ float linearEnd;
+};
+uniform fogData fogData;
+
+in vec2 glTexCoord0;
+
+uniform sampler2D BaseMap;
+
+in vec3 LightDir;
+in vec3 ViewDir;
+
+in vec3 N;
+
+in vec4 A;
+in vec4 C;
+in vec4 D;
+in vec3 S;
+in vec3 emissive;
+
+in float shininess;
+
+out vec4 glFragColor;
+
+void main( void )
+{
+ vec4 baseMap = texture( BaseMap, glTexCoord0.st );
+
+ //web says the keyword discard in a shader is bad
+ //I could just gl_FragColor=vec(0,0,0,0); return;
+ if(alphaTestEnabled != 0)
+ {
+ if(alphaTestFunction==516)//>
+ if(baseMap.a<=alphaTestValue)discard;
+ else if(alphaTestFunction==518)//>=
+ if(baseMap.a<alphaTestValue)discard;
+ else if(alphaTestFunction==514)//==
+ if(baseMap.a!=alphaTestValue)discard;
+ else if(alphaTestFunction==517)//!=
+ if(baseMap.a==alphaTestValue)discard;
+ else if(alphaTestFunction==513)//<
+ if(baseMap.a>=alphaTestValue)discard;
+ else if(alphaTestFunction==515)//<=
+ if(baseMap.a>alphaTestValue)discard;
+ else if(alphaTestFunction==512)//never
+ discard;
+ }
+
+ vec3 normal = N;
+
+ vec3 L = normalize(LightDir);
+ vec3 E = normalize(ViewDir);
+ vec3 R = reflect(-L, normal);
+ vec3 H = normalize( L + E );
+
+ float NdotL = max( dot(normal, L), 0.0 );
+ float NdotH = max( dot(normal, H), 0.0 );
+ float EdotN = max( dot(normal, E), 0.0 );
+ float NdotNegL = max( dot(normal, -L), 0.0 );
+
+ vec4 color;
+ vec3 albedo = baseMap.rgb * C.rgb;
+ vec3 diffuse = A.rgb + (D.rgb * NdotL);
+
+ // Specular
+ vec3 spec = S * pow(NdotH, 0.3*shininess);
+
+ color.rgb = albedo * (diffuse + emissive) + spec;
+ color.a = C.a * baseMap.a;
+
+ if(fogData.fogEnabled == 1)
+ {
+ //compute distance used in fog equations
+ float dist = length(ViewVec);
+ float fogFactor = 0.0;
+
+ if(fogData.linearEnd > 0.0)//linear fog
+ {
+ fogFactor = 1.0-((fogData.linearEnd - dist)/(fogData.linearEnd - fogData.linearStart));
+ fogFactor = clamp( fogFactor, 0.0, 1.0 );
+ color = mix(color, fogData.linearColor, fogFactor);
+ }
+ else if( fogData.expDensity > 0.0)// exponential fog
+ {
+ fogFactor = 1.0-(1.0 /exp(dist * fogData.expDensity));
+ fogFactor = clamp( fogFactor, 0.0, 1.0 );
+ color = mix(color, fogData.expColor, fogFactor);
+ }
+ color.a = color.a + fogFactor;
+ }
+
+ glFragColor = color;
+}
diff --git a/src/main/java/org/jogamp/java3d/utils/shader/fixed_function_shader.vert b/src/main/java/org/jogamp/java3d/utils/shader/fixed_function_shader.vert
new file mode 100644
index 0000000..e07965b
--- /dev/null
+++ b/src/main/java/org/jogamp/java3d/utils/shader/fixed_function_shader.vert
@@ -0,0 +1,141 @@
+#version 150
+
+in vec4 glVertex;
+in vec4 glColor;
+in vec3 glNormal;
+in vec2 glMultiTexCoord0;
+
+uniform mat4 glProjectionMatrix;
+//uniform mat4 glProjectionMatrixInverse;
+uniform mat4 glViewMatrix;
+uniform mat4 glModelMatrix;
+//uniform mat4 glModelViewMatrix;
+//uniform mat4 glModelViewMatrixInverse;
+//uniform mat4 glModelViewProjectionMatrix;
+
+//uniform mat3 glNormalMatrix;
+
+uniform int ignoreVertexColors;
+
+uniform vec4 glLightModelambient;
+
+struct material
+{
+ int lightEnabled;
+ vec4 ambient;
+ vec4 diffuse;
+ vec4 emission;
+ vec3 specular;
+ float shininess;
+};
+uniform material glFrontMaterial;
+
+struct lightSource
+{
+ vec4 position;
+ vec4 diffuse;
+ vec4 specular;
+ float constantAttenuation, linearAttenuation, quadraticAttenuation;
+ float spotCutoff, spotExponent;
+ vec3 spotDirection;
+};
+
+uniform int numberOfLights;// numberOfLights will be set to how many the pipeline can send
+const int maxLights = 1;// this is for the shader, it will process no more than this, must be a const
+uniform lightSource glLightSource[maxLights];
+
+uniform mat4 textureTransform;
+
+// alpha testing is normally done in frag versus the texture alpha
+//uniform int alphaTestEnabled;
+//uniform int alphaTestFunction;
+//uniform float alphaTestValue;
+
+
+// struct fogData
+// {
+// int fogEnabled = -1;
+// vec4 expColor;
+// float expDensity;
+// vec4 linearColor;
+// float linearStart;
+// float linearEnd;
+// };
+// uniform fogData fogData;
+
+
+// Fixed function pipeline pre-calculated values not available:
+// Note:
+// A,D,S = Ambient,Diffuse,Specular
+// cm, cli = glFrontMaterial, glLightSource
+
+
+// gl_LightSource[i].halfVector
+// http://stackoverflow.com/questions/3744038/what-is-half-vector-in-modern-glsl
+// vec3 ecPos = vec3(glModelViewMatrix * glVertex);
+// vec3 ecL;
+// if( glLightSource[i].position.w == 0.0)
+// ecL = vec3(glLightSource0position.xyz);// no -ecPos in case of dir lights?
+// else
+// ecL = vec3(glLightSource0position.xyz - ecPos);
+// vec3 L = normalize(ecL.xyz);
+// vec3 V = -ecPos.xyz;
+// vec3 halfVector = normalize(L + V);
+
+//gl_LightSource[i].ambient
+//use glLightModelambient
+
+// gl_FrontLightModelProduct.sceneColor
+// Derived. Ecm + Acm * Acs (Acs is normal glLightModelambient)
+// use vec4 sceneColor = glFrontMaterial.emission + glFrontMaterial.ambient * glLightModelambient;
+
+
+//gl_FrontLightProduct[i]
+//vec4 ambient; // Acm * Acli (Acli does not exist use glLightModelambient)
+//vec4 diffuse; // Dcm * Dcli
+//vec4 specular; // Scm * Scli
+// calculate yourself
+
+
+out vec2 glTexCoord0;
+
+out vec3 LightDir;
+out vec3 ViewVec;
+
+out vec3 N;
+
+out vec4 A;
+out vec4 C;
+out vec4 D;
+out vec3 S;
+out vec3 E;
+
+out float shininess;
+
+void main( void )
+{
+ mat4 glModelViewMatrix = glViewMatrix * glModelMatrix;
+ gl_Position = glProjectionMatrix * glModelViewMatrix * glVertex;//glModelViewProjectionMatrix * glVertex;
+
+ glTexCoord0 = (textureTransform * vec4(glMultiTexCoord0,0,1)).st;
+
+ mat3 glNormalMatrix = mat3(transpose(inverse(glModelViewMatrix)));
+ N = normalize(glNormalMatrix * glNormal);
+
+ vec3 v = vec3(glModelViewMatrix * glVertex);
+
+ ViewVec = -v.xyz;
+ LightDir = glLightSource[0].position.xyz;
+
+ A = glLightModelambient;
+ if( ignoreVertexColors != 0)
+ C = vec4(1,1,1,1);//glFrontMaterialdiffuse; // objectColor should be used if it is no lighting
+ else
+ C = glColor;
+ D = glLightSource[0].diffuse * glFrontMaterial.diffuse;
+ S = glLightSource[0].specular.rgb * glFrontMaterial.specular;
+ E = glFrontMaterial.emission.rgb;
+
+ shininess = glFrontMaterial.shininess;
+
+}