aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/classes/com/sun/opengl/impl/glsl/GLSLArrayDataServer.java2
-rw-r--r--src/classes/com/sun/opengl/impl/glsl/fixed/FixedFuncPipeline.java (renamed from src/classes/com/sun/opengl/impl/glsl/FixedFuncPipeline.java)114
-rw-r--r--src/classes/com/sun/opengl/impl/glsl/shader/FixedFuncColor.fp9
-rw-r--r--src/classes/com/sun/opengl/impl/glsl/shader/FixedFuncColor.vp22
-rw-r--r--src/classes/com/sun/opengl/impl/glsl/shader/FixedFuncColorLight.vp70
-rw-r--r--src/classes/com/sun/opengl/impl/glsl/shader/FixedFuncColorTexture.fp39
-rwxr-xr-xsrc/classes/com/sun/opengl/impl/glsl/shader/bin/nvidia/FixedFuncColor.bfpbin0 -> 524 bytes
-rwxr-xr-xsrc/classes/com/sun/opengl/impl/glsl/shader/bin/nvidia/FixedFuncColor.bvpbin0 -> 2344 bytes
-rwxr-xr-xsrc/classes/com/sun/opengl/impl/glsl/shader/bin/nvidia/FixedFuncColorLight.bvpbin0 -> 8787 bytes
-rwxr-xr-xsrc/classes/com/sun/opengl/impl/glsl/shader/bin/nvidia/FixedFuncColorTexture.bfpbin0 -> 1804 bytes
-rw-r--r--src/classes/com/sun/opengl/impl/glsl/shader/es_precision.glsl14
-rw-r--r--src/classes/com/sun/opengl/impl/glsl/shader/mgl_attribute.glsl19
-rw-r--r--src/classes/com/sun/opengl/impl/glsl/shader/mgl_const.glsl10
-rw-r--r--src/classes/com/sun/opengl/impl/glsl/shader/mgl_lightdef.glsl26
-rw-r--r--src/classes/com/sun/opengl/impl/glsl/shader/mgl_settexcoord.vp35
-rw-r--r--src/classes/com/sun/opengl/impl/glsl/shader/mgl_uniform.glsl17
-rw-r--r--src/classes/com/sun/opengl/impl/glsl/shader/mgl_uniform_light.glsl15
-rw-r--r--src/classes/com/sun/opengl/impl/glsl/shader/mgl_varying.glsl12
-rwxr-xr-xsrc/classes/com/sun/opengl/impl/glsl/shader/scripts/nvidia-apx/glslc-ff.bat9
-rwxr-xr-xsrc/classes/com/sun/opengl/impl/glsl/shader/scripts/nvidia-apx/glslc.bat9
-rw-r--r--src/classes/javax/media/opengl/GLArrayData.java2
-rw-r--r--src/classes/javax/media/opengl/GLUniformData.java2
-rw-r--r--src/classes/javax/media/opengl/glsl/ShaderCode.java388
-rw-r--r--src/classes/javax/media/opengl/glsl/ShaderProgram.java197
-rw-r--r--src/classes/javax/media/opengl/glsl/ShaderState.java582
-rwxr-xr-xsrc/classes/javax/media/opengl/sdk/glsl/CompileShader.java183
-rwxr-xr-xsrc/classes/javax/media/opengl/sdk/glsl/CompileShaderNVidia.java54
-rwxr-xr-xsrc/classes/javax/media/opengl/util/BufferUtil.java.javame_cdc_fp28
-rwxr-xr-xsrc/classes/javax/media/opengl/util/BufferUtil.java.javase28
-rw-r--r--src/classes/javax/media/opengl/util/ImmModeSink.java4
30 files changed, 1806 insertions, 84 deletions
diff --git a/src/classes/com/sun/opengl/impl/glsl/GLSLArrayDataServer.java b/src/classes/com/sun/opengl/impl/glsl/GLSLArrayDataServer.java
index 551eb525f..b56c2dc92 100644
--- a/src/classes/com/sun/opengl/impl/glsl/GLSLArrayDataServer.java
+++ b/src/classes/com/sun/opengl/impl/glsl/GLSLArrayDataServer.java
@@ -2,7 +2,7 @@
package com.sun.opengl.impl.glsl;
import javax.media.opengl.*;
-import javax.media.opengl.util.glsl.ShaderState;
+import javax.media.opengl.glsl.ShaderState;
import java.nio.*;
public class GLSLArrayDataServer extends GLArrayDataServer {
diff --git a/src/classes/com/sun/opengl/impl/glsl/FixedFuncPipeline.java b/src/classes/com/sun/opengl/impl/glsl/fixed/FixedFuncPipeline.java
index dc7ebaae6..f9798f48a 100644
--- a/src/classes/com/sun/opengl/impl/glsl/FixedFuncPipeline.java
+++ b/src/classes/com/sun/opengl/impl/glsl/fixed/FixedFuncPipeline.java
@@ -1,9 +1,9 @@
-package com.sun.opengl.impl.glsl;
+package com.sun.opengl.impl.glsl.fixed;
import javax.media.opengl.*;
import javax.media.opengl.util.*;
-import javax.media.opengl.util.glsl.*;
+import javax.media.opengl.glsl.*;
import java.nio.*;
public class FixedFuncPipeline {
@@ -63,14 +63,22 @@ public class FixedFuncPipeline {
shaderState.glUseProgram(gl, true);
shaderState.glEnableVertexAttribArray(gl, getArrayIndexName(glArrayIndex));
- textureCoordsEnabled |= (1 << activeTextureUnit);
+ // textureCoordsEnabled |= (1 << activeTextureUnit);
+ if ( textureCoordsEnabled.get(activeTextureUnit) != 1 ) {
+ textureCoordsEnabled.put(activeTextureUnit, 1);
+ textureCoordsEnabledDirty = true;
+ }
}
public void glDisableClientState(GL2ES2 gl, int glArrayIndex) {
shaderState.glUseProgram(gl, true);
shaderState.glDisableVertexAttribArray(gl, getArrayIndexName(glArrayIndex));
- textureCoordsEnabled &= ~(1 << activeTextureUnit);
+ // textureCoordsEnabled &= ~(1 << activeTextureUnit);
+ if ( textureCoordsEnabled.get(activeTextureUnit) != 0 ) {
+ textureCoordsEnabled.put(activeTextureUnit, 0);
+ textureCoordsEnabledDirty = true;
+ }
}
public void glVertexPointer(GL2ES2 gl, GLArrayData data) {
@@ -245,10 +253,9 @@ public class FixedFuncPipeline {
int light = cap - GL.GL_LIGHT0;
if(0 <= light && light < MAX_LIGHTS) {
- if(enable) {
- lightsEnabled |= (1 << light);
- } else {
- lightsEnabled &= ~(1 << light);
+ if ( (lightsEnabled.get(light)==1) != enable ) {
+ lightsEnabled.put(light, enable?1:0);
+ lightsEnabledDirty = true;
}
return;
}
@@ -281,20 +288,22 @@ public class FixedFuncPipeline {
}
}
- ud = shaderState.getUniform(mgl_TexCoordEnabled);
- if(null!=ud) {
- if(textureCoordsEnabled!=ud.intValue()) {
- ud.setData(textureCoordsEnabled);
+ if(textureCoordsEnabledDirty) {
+ ud = shaderState.getUniform(mgl_TexCoordEnabled);
+ if(null!=ud) {
+ // same data object
shaderState.glUniform(gl, ud);
}
+ textureCoordsEnabledDirty=false;
}
- ud = shaderState.getUniform(mgl_LightsEnabled);
- if(null!=ud) {
- if(lightsEnabled!=ud.intValue()) {
- ud.setData(lightsEnabled);
+ if(lightsEnabledDirty) {
+ ud = shaderState.getUniform(mgl_LightsEnabled);
+ if(null!=ud) {
+ // same data object
shaderState.glUniform(gl, ud);
}
+ lightsEnabledDirty=false;
}
if(textureEnabled) {
@@ -334,69 +343,44 @@ public class FixedFuncPipeline {
this.shaderState.setVerbose(verbose);
ShaderCode vertexColor, vertexColorLight, fragmentColor, fragmentColorTexture;
- // FIXME: Proper evaluation for binary format types ..
- int binaryFormat = GLProfile.isGLES2()?GLES2.GL_NVIDIA_PLATFORM_BINARY_NV:-1;
-
- switch(binaryFormat) {
- case GLES2.GL_NVIDIA_PLATFORM_BINARY_NV:
- vertexColor = ShaderCode.create( gl.GL_VERTEX_SHADER, 1, this.getClass(),
- binaryFormat, "binary_nvidia/FixedFuncShaderVertexColor.nvbv",
- vertexColorSrcFile);
+ vertexColor = ShaderCode.create( gl, gl.GL_VERTEX_SHADER, 1, FixedFuncPipeline.class,
+ shaderSrcRoot, shaderBinRoot, vertexColorFile);
- vertexColorLight = ShaderCode.create( gl.GL_VERTEX_SHADER, 1, this.getClass(),
- binaryFormat, "binary_nvidia/FixedFuncShaderVertexColorLight.nvbv",
- vertexColorLightSrcFile);
+ vertexColorLight = ShaderCode.create( gl, gl.GL_VERTEX_SHADER, 1, FixedFuncPipeline.class,
+ shaderSrcRoot, shaderBinRoot, vertexColorLightFile);
- fragmentColor = ShaderCode.create( gl.GL_FRAGMENT_SHADER, 1, this.getClass(),
- binaryFormat, "binary_nvidia/FixedFuncShaderFragmentColor.nvbv",
- fragmentColorSrcFile);
+ fragmentColor = ShaderCode.create( gl, gl.GL_FRAGMENT_SHADER, 1, FixedFuncPipeline.class,
+ shaderSrcRoot, shaderBinRoot, fragmentColorFile);
- fragmentColorTexture = ShaderCode.create( gl.GL_FRAGMENT_SHADER, 1, this.getClass(),
- binaryFormat, "binary_nvidia/FixedFuncShaderFragmentColorTexture.nvbv",
- fragmentColorTextureSrcFile);
-
- break;
- default:
- vertexColor = ShaderCode.create( gl.GL_VERTEX_SHADER, 1, this.getClass(), -1, null,
- vertexColorSrcFile);
-
- vertexColorLight = ShaderCode.create( gl.GL_VERTEX_SHADER, 1, this.getClass(), -1, null,
- vertexColorLightSrcFile);
-
- fragmentColor = ShaderCode.create( gl.GL_FRAGMENT_SHADER, 1, this.getClass(), -1, null,
- fragmentColorSrcFile);
-
- fragmentColorTexture = ShaderCode.create( gl.GL_FRAGMENT_SHADER, 1, this.getClass(), -1, null,
- fragmentColorTextureSrcFile);
- }
+ fragmentColorTexture = ShaderCode.create( gl, gl.GL_FRAGMENT_SHADER, 1, FixedFuncPipeline.class,
+ shaderSrcRoot, shaderBinRoot, fragmentColorTextureFile);
-
shaderProgramColor = new ShaderProgram();
shaderProgramColor.add(vertexColor);
shaderProgramColor.add(fragmentColor);
if(!shaderProgramColor.link(gl, System.err)) {
- throw new GLException("Couldn't link VertexColor program");
+ throw new GLException("Couldn't link VertexColor program: "+shaderProgramColor);
}
shaderProgramColorTexture = new ShaderProgram();
shaderProgramColorTexture.add(vertexColor);
shaderProgramColorTexture.add(fragmentColorTexture);
if(!shaderProgramColorTexture.link(gl, System.err)) {
- throw new GLException("Couldn't link VertexColorTexture program");
+ throw new GLException("Couldn't link VertexColorTexture program: "+shaderProgramColorTexture);
}
shaderProgramColorLight = new ShaderProgram();
shaderProgramColorLight.add(vertexColorLight);
shaderProgramColorLight.add(fragmentColor);
if(!shaderProgramColorLight.link(gl, System.err)) {
- throw new GLException("Couldn't link VertexColorLight program");
+ throw new GLException("Couldn't link VertexColorLight program: "+shaderProgramColorLight);
}
shaderProgramColorTextureLight = new ShaderProgram();
shaderProgramColorTextureLight.add(vertexColorLight);
shaderProgramColorTextureLight.add(fragmentColorTexture);
if(!shaderProgramColorTextureLight.link(gl, System.err)) {
- throw new GLException("Couldn't link VertexColorLight program");
+ throw new GLException("Couldn't link VertexColorLight program: "+shaderProgramColorTextureLight);
}
shaderState.attachShaderProgram(gl, shaderProgramColor);
@@ -412,7 +396,7 @@ public class FixedFuncPipeline {
shaderState.glUniform(gl, new GLUniformData(mgl_ColorEnabled, 0));
shaderState.glUniform(gl, new GLUniformData(mgl_ColorStatic, 4, zero4f));
- shaderState.glUniform(gl, new GLUniformData(mgl_TexCoordEnabled, textureCoordsEnabled));
+ shaderState.glUniform(gl, new GLUniformData(mgl_TexCoordEnabled, 1, textureCoordsEnabled));
shaderState.glUniform(gl, new GLUniformData(mgl_ActiveTexture, activeTextureUnit));
shaderState.glUniform(gl, new GLUniformData(mgl_ActiveTextureIdx, activeTextureUnit));
shaderState.glUniform(gl, new GLUniformData(mgl_ShadeModel, 0));
@@ -428,7 +412,7 @@ public class FixedFuncPipeline {
shaderState.glUniform(gl, new GLUniformData(mgl_LightSource+"["+i+"].linearAttenuation", defLinearAtten));
shaderState.glUniform(gl, new GLUniformData(mgl_LightSource+"["+i+"].quadraticAttenuation", defQuadraticAtten));
}
- shaderState.glUniform(gl, new GLUniformData(mgl_LightsEnabled, lightsEnabled));
+ shaderState.glUniform(gl, new GLUniformData(mgl_LightsEnabled, 1, lightsEnabled));
shaderState.glUniform(gl, new GLUniformData(mgl_FrontMaterial+".ambient", 4, defMatAmbient));
shaderState.glUniform(gl, new GLUniformData(mgl_FrontMaterial+".diffuse", 4, defMatDiffuse));
shaderState.glUniform(gl, new GLUniformData(mgl_FrontMaterial+".specular", 4, defMatSpecular));
@@ -443,11 +427,13 @@ public class FixedFuncPipeline {
protected boolean verbose=false;
protected boolean textureEnabled=false;
- protected int textureCoordsEnabled=0;
+ protected IntBuffer textureCoordsEnabled = BufferUtil.newIntBuffer(new int[] { 0, 0, 0, 0, 0, 0, 0, 0 });
+ protected boolean textureCoordsEnabledDirty = false;
protected int activeTextureUnit=0;
protected boolean lightingEnabled=false;
- protected int lightsEnabled=0;
+ protected IntBuffer lightsEnabled = BufferUtil.newIntBuffer(new int[] { 0, 0, 0, 0, 0, 0, 0, 0 });
+ protected boolean lightsEnabledDirty = false;
protected PMVMatrix pmvMatrix;
protected ShaderState shaderState;
@@ -464,11 +450,11 @@ public class FixedFuncPipeline {
protected static final String mgl_LightSource = "mgl_LightSource"; // struct mgl_LightSourceParameters[MAX_LIGHTS]
protected static final String mgl_FrontMaterial = "mgl_FrontMaterial"; // struct mgl_MaterialParameters
- protected static final String mgl_LightsEnabled = "mgl_LightsEnabled"; // 1i bitfield
+ protected static final String mgl_LightsEnabled = "mgl_LightsEnabled"; // int mgl_LightsEnabled[MAX_LIGHTS];
protected static final String mgl_ShadeModel = "mgl_ShadeModel"; // 1i
- protected static final String mgl_TexCoordEnabled = "mgl_TexCoordEnabled"; // 1i bitfield
+ protected static final String mgl_TexCoordEnabled = "mgl_TexCoordEnabled"; // int mgl_TexCoordEnabled[MAX_TEXTURE_UNITS];
protected static final String mgl_ActiveTexture = "mgl_ActiveTexture"; // 1i
protected static final String mgl_ActiveTextureIdx = "mgl_ActiveTextureIdx";// 1i
@@ -491,9 +477,11 @@ public class FixedFuncPipeline {
public static final FloatBuffer defMatEmission= BufferUtil.newFloatBuffer(new float[] { 0f, 0f, 0f, 1f});
public static final float defMatShininess = 0f;
- protected static final String[] vertexColorSrcFile = new String[] { "source/FixedFuncShaderVertexColor.vp" };
- protected static final String[] vertexColorLightSrcFile = new String[] { "source/FixedFuncShaderVertexColorLight.vp" };
- protected static final String[] fragmentColorSrcFile = new String[] { "source/FixedFuncShaderFragmentColor.fp" } ;
- protected static final String[] fragmentColorTextureSrcFile = new String[] { "source/FixedFuncShaderFragmentColorTexture.fp" } ;
+ protected static final String vertexColorFile = "FixedFuncColor";
+ protected static final String vertexColorLightFile = "FixedFuncColorLight";
+ protected static final String fragmentColorFile = "FixedFuncColor";
+ protected static final String fragmentColorTextureFile = "FixedFuncColorTexture";
+ protected static final String shaderSrcRoot = "shader" ;
+ protected static final String shaderBinRoot = "shader/bin" ;
}
diff --git a/src/classes/com/sun/opengl/impl/glsl/shader/FixedFuncColor.fp b/src/classes/com/sun/opengl/impl/glsl/shader/FixedFuncColor.fp
new file mode 100644
index 000000000..71b39f45c
--- /dev/null
+++ b/src/classes/com/sun/opengl/impl/glsl/shader/FixedFuncColor.fp
@@ -0,0 +1,9 @@
+#include es_precision.glsl
+
+#include mgl_varying.glsl
+
+void main (void)
+{
+ gl_FragColor = frontColor;
+}
+
diff --git a/src/classes/com/sun/opengl/impl/glsl/shader/FixedFuncColor.vp b/src/classes/com/sun/opengl/impl/glsl/shader/FixedFuncColor.vp
new file mode 100644
index 000000000..346e40196
--- /dev/null
+++ b/src/classes/com/sun/opengl/impl/glsl/shader/FixedFuncColor.vp
@@ -0,0 +1,22 @@
+#include es_precision.glsl
+
+#include mgl_const.glsl
+#include mgl_uniform.glsl
+#include mgl_attribute.glsl
+#include mgl_varying.glsl
+
+#include mgl_settexcoord.vp
+
+void main(void)
+{
+ if(mgl_ColorEnabled>0) {
+ frontColor=mgl_Color;
+ } else {
+ frontColor=mgl_ColorStatic;
+ }
+
+ gl_Position = mgl_PMVMatrix[0] * mgl_PMVMatrix[1] * mgl_Vertex;
+
+ setTexCoord(gl_Position);
+}
+
diff --git a/src/classes/com/sun/opengl/impl/glsl/shader/FixedFuncColorLight.vp b/src/classes/com/sun/opengl/impl/glsl/shader/FixedFuncColorLight.vp
new file mode 100644
index 000000000..ce203cfb9
--- /dev/null
+++ b/src/classes/com/sun/opengl/impl/glsl/shader/FixedFuncColorLight.vp
@@ -0,0 +1,70 @@
+#include es_precision.glsl
+#include mgl_lightdef.glsl
+
+#include mgl_const.glsl
+#include mgl_uniform.glsl
+#include mgl_uniform_light.glsl
+#include mgl_attribute.glsl
+#include mgl_varying.glsl
+
+#include mgl_settexcoord.vp
+
+void main(void)
+{
+ vec4 position;
+ vec3 normal, lightDir, cameraDir, halfDir;
+ vec4 ambient, diffuse, specular;
+ float NdotL, NdotHV, dist, attenuation;
+ int i;
+
+ position = mgl_PMVMatrix[1] * mgl_Vertex; // vertex eye position
+
+ normal = normalize(mgl_NormalMatrix * mgl_Normal);
+ // cameraPosition: (mgl_PMVMatrix[2] * vec4(0,0,0,1.0)).xyz
+ cameraDir = normalize( (mgl_PMVMatrix[2] * vec4(0,0,0,1.0)).xyz - mgl_Vertex.xyz );
+
+ ambient = vec4(0,0,0,0);
+ diffuse = vec4(0,0,0,0);
+ specular = vec4(0,0,0,0);
+
+ bool lightEnabled = false;
+
+ for(i=0; i<MAX_LIGHTS; i++) {
+ if( 0!= mgl_LightsEnabled[i] ) {
+ lightEnabled = true;
+ ambient += mgl_LightSource[i].ambient;
+ lightDir = mgl_LightSource[i].position.xyz - position.xyz;
+ dist = length(lightDir);
+ lightDir = normalize(lightDir);
+ attenuation = 1.0 / (
+ mgl_LightSource[i].constantAttenuation+
+ mgl_LightSource[i].linearAttenuation * dist +
+ mgl_LightSource[i].quadraticAttenuation * dist * dist );
+ NdotL = max(0.0, dot(normal, lightDir));
+ diffuse += mgl_LightSource[i].diffuse * NdotL * attenuation;
+ if (NdotL != 0.0) {
+ halfDir = normalize (lightDir + cameraDir);
+ NdotHV = max(0.0, dot(normal, halfDir));
+ specular += mgl_LightSource[i].specular *
+ pow(NdotHV,mgl_FrontMaterial.shininess) * attenuation;
+ }
+ }
+ }
+ ambient += mgl_FrontMaterial.ambient;
+ diffuse *= mgl_FrontMaterial.diffuse;
+ specular *= mgl_FrontMaterial.specular;
+
+ if(mgl_ColorEnabled>0) {
+ frontColor=mgl_Color;
+ } else {
+ frontColor=mgl_ColorStatic;
+ }
+ if( lightEnabled ) {
+ frontColor *= ambient + diffuse + specular;
+ }
+
+ gl_Position = mgl_PMVMatrix[0] * position;
+
+ setTexCoord(gl_Position);
+}
+
diff --git a/src/classes/com/sun/opengl/impl/glsl/shader/FixedFuncColorTexture.fp b/src/classes/com/sun/opengl/impl/glsl/shader/FixedFuncColorTexture.fp
new file mode 100644
index 000000000..cc4bd0c64
--- /dev/null
+++ b/src/classes/com/sun/opengl/impl/glsl/shader/FixedFuncColorTexture.fp
@@ -0,0 +1,39 @@
+
+#include es_precision.glsl
+#include mgl_lightdef.glsl
+
+#include mgl_const.glsl
+#include mgl_uniform.glsl
+#include mgl_varying.glsl
+
+vec4 getTexColor(in sampler2D tex, in int idx) {
+ vec4 coord;
+ if(idx==0) {
+ coord= mgl_TexCoords[0];
+ } else if(idx==1) {
+ coord= mgl_TexCoords[1];
+ } else if(idx==2) {
+ coord= mgl_TexCoords[2];
+ } else if(idx==3) {
+ coord= mgl_TexCoords[3];
+ } else if(idx==4) {
+ coord= mgl_TexCoords[4];
+ } else if(idx==5) {
+ coord= mgl_TexCoords[5];
+ } else if(idx==6) {
+ coord= mgl_TexCoords[6];
+ } else {
+ coord= mgl_TexCoords[7];
+ }
+ return texture2D(tex, coord.st);
+}
+
+void main (void)
+{
+ vec4 texColor = getTexColor(mgl_ActiveTexture,mgl_ActiveTextureIdx);
+ if(length(texColor)>0.0) {
+ gl_FragColor = vec4(frontColor.rgb*texColor.rgb, frontColor.a * texColor.a) ;
+ } else {
+ gl_FragColor = frontColor;
+ }
+}
diff --git a/src/classes/com/sun/opengl/impl/glsl/shader/bin/nvidia/FixedFuncColor.bfp b/src/classes/com/sun/opengl/impl/glsl/shader/bin/nvidia/FixedFuncColor.bfp
new file mode 100755
index 000000000..454354c12
--- /dev/null
+++ b/src/classes/com/sun/opengl/impl/glsl/shader/bin/nvidia/FixedFuncColor.bfp
Binary files differ
diff --git a/src/classes/com/sun/opengl/impl/glsl/shader/bin/nvidia/FixedFuncColor.bvp b/src/classes/com/sun/opengl/impl/glsl/shader/bin/nvidia/FixedFuncColor.bvp
new file mode 100755
index 000000000..279ef72c7
--- /dev/null
+++ b/src/classes/com/sun/opengl/impl/glsl/shader/bin/nvidia/FixedFuncColor.bvp
Binary files differ
diff --git a/src/classes/com/sun/opengl/impl/glsl/shader/bin/nvidia/FixedFuncColorLight.bvp b/src/classes/com/sun/opengl/impl/glsl/shader/bin/nvidia/FixedFuncColorLight.bvp
new file mode 100755
index 000000000..5a9deea71
--- /dev/null
+++ b/src/classes/com/sun/opengl/impl/glsl/shader/bin/nvidia/FixedFuncColorLight.bvp
Binary files differ
diff --git a/src/classes/com/sun/opengl/impl/glsl/shader/bin/nvidia/FixedFuncColorTexture.bfp b/src/classes/com/sun/opengl/impl/glsl/shader/bin/nvidia/FixedFuncColorTexture.bfp
new file mode 100755
index 000000000..375ea6293
--- /dev/null
+++ b/src/classes/com/sun/opengl/impl/glsl/shader/bin/nvidia/FixedFuncColorTexture.bfp
Binary files differ
diff --git a/src/classes/com/sun/opengl/impl/glsl/shader/es_precision.glsl b/src/classes/com/sun/opengl/impl/glsl/shader/es_precision.glsl
new file mode 100644
index 000000000..fd6abe54e
--- /dev/null
+++ b/src/classes/com/sun/opengl/impl/glsl/shader/es_precision.glsl
@@ -0,0 +1,14 @@
+#ifndef es_precision_glsl
+#define es_precision_glsl
+
+#ifdef GL_ES
+ #define MEDIUMP mediump
+ #define HIGHP highp
+ #define LOWP lowp
+#else
+ #define MEDIUMP
+ #define HIGHP
+ #define LOWP
+#endif
+
+#endif // es_precision_glsl
diff --git a/src/classes/com/sun/opengl/impl/glsl/shader/mgl_attribute.glsl b/src/classes/com/sun/opengl/impl/glsl/shader/mgl_attribute.glsl
new file mode 100644
index 000000000..b09bdb05a
--- /dev/null
+++ b/src/classes/com/sun/opengl/impl/glsl/shader/mgl_attribute.glsl
@@ -0,0 +1,19 @@
+
+#ifndef mgl_attribute_glsl
+#define mgl_attribute_glsl
+
+#include es_precision.glsl
+
+attribute HIGHP vec4 mgl_Vertex;
+attribute HIGHP vec3 mgl_Normal;
+attribute HIGHP vec4 mgl_Color;
+attribute HIGHP vec4 mgl_MultiTexCoord0;
+attribute HIGHP vec4 mgl_MultiTexCoord1;
+attribute HIGHP vec4 mgl_MultiTexCoord2;
+attribute HIGHP vec4 mgl_MultiTexCoord3;
+attribute HIGHP vec4 mgl_MultiTexCoord4;
+attribute HIGHP vec4 mgl_MultiTexCoord5;
+attribute HIGHP vec4 mgl_MultiTexCoord6;
+attribute HIGHP vec4 mgl_MultiTexCoord7;
+
+#endif // mgl_attribute_glsl
diff --git a/src/classes/com/sun/opengl/impl/glsl/shader/mgl_const.glsl b/src/classes/com/sun/opengl/impl/glsl/shader/mgl_const.glsl
new file mode 100644
index 000000000..1a464a1cb
--- /dev/null
+++ b/src/classes/com/sun/opengl/impl/glsl/shader/mgl_const.glsl
@@ -0,0 +1,10 @@
+
+#ifndef mgl_const_glsl
+#define mgl_const_glsl
+
+#include es_precision.glsl
+
+const LOWP int MAX_TEXTURE_UNITS = 8; // <=gl_MaxTextureImageUnits
+const LOWP int MAX_LIGHTS = 8;
+
+#endif // mgl_const_glsl
diff --git a/src/classes/com/sun/opengl/impl/glsl/shader/mgl_lightdef.glsl b/src/classes/com/sun/opengl/impl/glsl/shader/mgl_lightdef.glsl
new file mode 100644
index 000000000..98e214139
--- /dev/null
+++ b/src/classes/com/sun/opengl/impl/glsl/shader/mgl_lightdef.glsl
@@ -0,0 +1,26 @@
+#ifndef mgl_lightdef_glsl
+#define mgl_lightdef_glsl
+
+struct mgl_LightSourceParameters {
+ vec4 ambient;
+ vec4 diffuse;
+ vec4 specular;
+ vec4 position;
+ // vec4 halfVector; // is computed here
+ vec3 spotDirection;
+ float spotExponent;
+ float spotCutoff; // (range: [0.0,90.0], 180.0)
+ //float spotCosCutoff; // (range: [1.0,0.0],-1.0)
+ float constantAttenuation;
+ float linearAttenuation;
+ float quadraticAttenuation;
+};
+struct mgl_MaterialParameters {
+ vec4 ambient;
+ vec4 diffuse;
+ vec4 specular;
+ vec4 emission;
+ float shininess;
+};
+
+#endif // mgl_lightdef_glsl
diff --git a/src/classes/com/sun/opengl/impl/glsl/shader/mgl_settexcoord.vp b/src/classes/com/sun/opengl/impl/glsl/shader/mgl_settexcoord.vp
new file mode 100644
index 000000000..1efe328d0
--- /dev/null
+++ b/src/classes/com/sun/opengl/impl/glsl/shader/mgl_settexcoord.vp
@@ -0,0 +1,35 @@
+#ifndef mgl_settexcoord_vp
+#define mgl_settexcoord_vp
+
+#include es_precision.glsl
+
+#include mgl_const.glsl
+#include mgl_uniform.glsl
+#include mgl_attribute.glsl
+#include mgl_varying.glsl
+
+void setTexCoord(in vec4 defpos) {
+ /**
+ * bitwise operator not supported on APX 2500 ES 2.0
+ *
+ mgl_TexCoords[0] = ( 0 != (mgl_TexCoordEnabled & 1) ) ? mgl_MultiTexCoord0 : defpos;
+ mgl_TexCoords[1] = ( 0 != (mgl_TexCoordEnabled & 2) ) ? mgl_MultiTexCoord1 : defpos;
+ mgl_TexCoords[2] = ( 0 != (mgl_TexCoordEnabled & 4) ) ? mgl_MultiTexCoord2 : defpos;
+ mgl_TexCoords[3] = ( 0 != (mgl_TexCoordEnabled & 8) ) ? mgl_MultiTexCoord3 : defpos;
+ mgl_TexCoords[4] = ( 0 != (mgl_TexCoordEnabled & 16) ) ? mgl_MultiTexCoord4 : defpos;
+ mgl_TexCoords[5] = ( 0 != (mgl_TexCoordEnabled & 32) ) ? mgl_MultiTexCoord5 : defpos;
+ mgl_TexCoords[6] = ( 0 != (mgl_TexCoordEnabled & 64) ) ? mgl_MultiTexCoord6 : defpos;
+ mgl_TexCoords[7] = ( 0 != (mgl_TexCoordEnabled & 128) ) ? mgl_MultiTexCoord7 : defpos;
+ */
+
+ mgl_TexCoords[0] = ( 0 != mgl_TexCoordEnabled[0] ) ? mgl_MultiTexCoord0 : defpos;
+ mgl_TexCoords[1] = ( 0 != mgl_TexCoordEnabled[1] ) ? mgl_MultiTexCoord1 : defpos;
+ mgl_TexCoords[2] = ( 0 != mgl_TexCoordEnabled[2] ) ? mgl_MultiTexCoord2 : defpos;
+ mgl_TexCoords[3] = ( 0 != mgl_TexCoordEnabled[3] ) ? mgl_MultiTexCoord3 : defpos;
+ mgl_TexCoords[4] = ( 0 != mgl_TexCoordEnabled[4] ) ? mgl_MultiTexCoord4 : defpos;
+ mgl_TexCoords[5] = ( 0 != mgl_TexCoordEnabled[5] ) ? mgl_MultiTexCoord5 : defpos;
+ mgl_TexCoords[6] = ( 0 != mgl_TexCoordEnabled[6] ) ? mgl_MultiTexCoord6 : defpos;
+ mgl_TexCoords[7] = ( 0 != mgl_TexCoordEnabled[7] ) ? mgl_MultiTexCoord7 : defpos;
+}
+
+#endif // mgl_settexcoord_vp
diff --git a/src/classes/com/sun/opengl/impl/glsl/shader/mgl_uniform.glsl b/src/classes/com/sun/opengl/impl/glsl/shader/mgl_uniform.glsl
new file mode 100644
index 000000000..2333e26e2
--- /dev/null
+++ b/src/classes/com/sun/opengl/impl/glsl/shader/mgl_uniform.glsl
@@ -0,0 +1,17 @@
+
+#ifndef mgl_uniform_glsl
+#define mgl_uniform_glsl
+
+#include es_precision.glsl
+
+#include mgl_const.glsl
+
+uniform HIGHP mat4 mgl_PMVMatrix[3]; // P, Mv, and Mvi
+uniform HIGHP mat3 mgl_NormalMatrix; // transpose(inverse(ModelView)).3x3
+uniform LOWP int mgl_ColorEnabled;
+uniform HIGHP vec4 mgl_ColorStatic;
+uniform LOWP int mgl_TexCoordEnabled[MAX_TEXTURE_UNITS];
+uniform sampler2D mgl_ActiveTexture;
+uniform LOWP int mgl_ActiveTextureIdx;
+
+#endif // mgl_uniform_glsl
diff --git a/src/classes/com/sun/opengl/impl/glsl/shader/mgl_uniform_light.glsl b/src/classes/com/sun/opengl/impl/glsl/shader/mgl_uniform_light.glsl
new file mode 100644
index 000000000..0dedb5d5d
--- /dev/null
+++ b/src/classes/com/sun/opengl/impl/glsl/shader/mgl_uniform_light.glsl
@@ -0,0 +1,15 @@
+
+#ifndef mgl_uniform_light_glsl
+#define mgl_uniform_light_glsl
+
+#include es_precision.glsl
+
+#include mgl_const.glsl
+#include mgl_lightdef.glsl
+
+uniform LOWP int mgl_LightsEnabled[MAX_LIGHTS];
+
+uniform mgl_LightSourceParameters mgl_LightSource[MAX_LIGHTS];
+uniform mgl_MaterialParameters mgl_FrontMaterial;
+
+#endif // mgl_uniform_light_glsl
diff --git a/src/classes/com/sun/opengl/impl/glsl/shader/mgl_varying.glsl b/src/classes/com/sun/opengl/impl/glsl/shader/mgl_varying.glsl
new file mode 100644
index 000000000..fc9f735d1
--- /dev/null
+++ b/src/classes/com/sun/opengl/impl/glsl/shader/mgl_varying.glsl
@@ -0,0 +1,12 @@
+
+#ifndef mgl_varying_glsl
+#define mgl_varying_glsl
+
+#include es_precision.glsl
+
+#include mgl_const.glsl
+
+varying vec4 frontColor;
+varying vec4 mgl_TexCoords[MAX_TEXTURE_UNITS];
+
+#endif // mgl_varying_glsl
diff --git a/src/classes/com/sun/opengl/impl/glsl/shader/scripts/nvidia-apx/glslc-ff.bat b/src/classes/com/sun/opengl/impl/glsl/shader/scripts/nvidia-apx/glslc-ff.bat
new file mode 100755
index 000000000..b8acba036
--- /dev/null
+++ b/src/classes/com/sun/opengl/impl/glsl/shader/scripts/nvidia-apx/glslc-ff.bat
@@ -0,0 +1,9 @@
+REM
+REM You have to call it from the 'shader' directory, e.g.:
+REM scripts\nvidia-apx\glslc-ff.bat
+REM
+IF !"%JOGLDIR%"==""! GOTO YESPATH
+set JOGLDIR=..
+:YESPATH
+
+java -cp %JOGLDIR%\jogl.core.jar;%JOGLDIR%\jogl.gles2.jar;%JOGLDIR%\jogl.fixed.jar;%JOGLDIR%\jogl.sdk.jar javax.media.opengl.sdk.glsl.CompileShaderNVidia FixedFuncColor.fp FixedFuncColorTexture.fp FixedFuncColorLight.vp FixedFuncColor.vp
diff --git a/src/classes/com/sun/opengl/impl/glsl/shader/scripts/nvidia-apx/glslc.bat b/src/classes/com/sun/opengl/impl/glsl/shader/scripts/nvidia-apx/glslc.bat
new file mode 100755
index 000000000..9cbea806f
--- /dev/null
+++ b/src/classes/com/sun/opengl/impl/glsl/shader/scripts/nvidia-apx/glslc.bat
@@ -0,0 +1,9 @@
+REM
+REM You have to call it from the 'shader' directory, e.g.:
+REM scripts\nvidia-apx\glslc.bat <FileName>
+REM
+IF !"%JOGLDIR%"==""! GOTO YESPATH
+set JOGLDIR=..
+:YESPATH
+
+java -cp %JOGLDIR%\jogl.core.jar;%JOGLDIR%\jogl.gles2.jar;%JOGLDIR%\jogl.fixed.jar;%JOGLDIR%\jogl.sdk.jar javax.media.opengl.sdk.glsl.CompileShaderNVidia %1
diff --git a/src/classes/javax/media/opengl/GLArrayData.java b/src/classes/javax/media/opengl/GLArrayData.java
index db017b00a..b13b0752b 100644
--- a/src/classes/javax/media/opengl/GLArrayData.java
+++ b/src/classes/javax/media/opengl/GLArrayData.java
@@ -43,7 +43,7 @@ public interface GLArrayData {
* Sets the determined location of the shader attribute
* This is usually done within ShaderState.
*
- * @see javax.media.opengl.util.glsl.ShaderState#glVertexAttribPointer(GL2ES2, GLArrayData)
+ * @see javax.media.opengl.glsl.ShaderState#glVertexAttribPointer(GL2ES2, GLArrayData)
*/
public void setLocation(int v);
diff --git a/src/classes/javax/media/opengl/GLUniformData.java b/src/classes/javax/media/opengl/GLUniformData.java
index 929a59a2a..40368e4e7 100644
--- a/src/classes/javax/media/opengl/GLUniformData.java
+++ b/src/classes/javax/media/opengl/GLUniformData.java
@@ -130,7 +130,7 @@ public class GLUniformData {
* Sets the determined location of the shader uniform
* This is usually done within ShaderState.
*
- * @see javax.media.opengl.util.glsl.ShaderState#glUniform(GL2ES2, GLUniformData)
+ * @see javax.media.opengl.glsl.ShaderState#glUniform(GL2ES2, GLUniformData)
*/
public void setLocation(int location) { this.location=location; }
diff --git a/src/classes/javax/media/opengl/glsl/ShaderCode.java b/src/classes/javax/media/opengl/glsl/ShaderCode.java
new file mode 100644
index 000000000..e8b5555b6
--- /dev/null
+++ b/src/classes/javax/media/opengl/glsl/ShaderCode.java
@@ -0,0 +1,388 @@
+
+package javax.media.opengl.glsl;
+
+import javax.media.opengl.*;
+import javax.media.opengl.util.*;
+
+import java.util.*;
+import java.nio.*;
+import java.io.*;
+import java.net.*;
+
+public class ShaderCode {
+ public static final String SUFFIX_VERTEX_SOURCE = "vp" ;
+ public static final String SUFFIX_VERTEX_BINARY = "bvp" ;
+ public static final String SUFFIX_FRAGMENT_SOURCE = "fp" ;
+ public static final String SUFFIX_FRAGMENT_BINARY = "bfp" ;
+
+ public static final String SUB_PATH_NVIDIA = "nvidia" ;
+
+ public ShaderCode(int type, int number, String[][] source) {
+ switch (type) {
+ case GL2ES2.GL_VERTEX_SHADER:
+ case GL2ES2.GL_FRAGMENT_SHADER:
+ break;
+ default:
+ throw new GLException("Unknown shader type: "+type);
+ }
+ shaderSource = source;
+ shaderBinaryFormat = -1;
+ shaderBinary = null;
+ shaderType = type;
+ shader = BufferUtil.newIntBuffer(number);
+ id = getNextID();
+ }
+
+ public ShaderCode(int type, int number, int binFormat, Buffer binary) {
+ switch (type) {
+ case GL2ES2.GL_VERTEX_SHADER:
+ case GL2ES2.GL_FRAGMENT_SHADER:
+ break;
+ default:
+ throw new GLException("Unknown shader type: "+type);
+ }
+ shaderSource = null;
+ shaderBinaryFormat = binFormat;
+ shaderBinary = binary;
+ shaderType = type;
+ shader = BufferUtil.newIntBuffer(number);
+ id = getNextID();
+ }
+
+ public static ShaderCode create(int type, int number, Class context, String[] sourceFiles) {
+ String[][] shaderSources = null;
+ if(null!=sourceFiles) {
+ shaderSources = new String[sourceFiles.length][1];
+ for(int i=0; null!=shaderSources && i<sourceFiles.length; i++) {
+ shaderSources[i][0] = readShaderSource(context, sourceFiles[i]);
+ if(null == shaderSources[i][0]) {
+ shaderSources = null;
+ }
+ }
+ }
+ if(null==shaderSources) {
+ return null;
+ }
+ return new ShaderCode(type, number, shaderSources);
+ }
+
+ public static ShaderCode create(int type, int number, Class context, int binFormat, String binaryFile) {
+ ByteBuffer shaderBinary = null;
+ if(null!=binaryFile && 0<=binFormat) {
+ shaderBinary = readShaderBinary(context, binaryFile);
+ if(null == shaderBinary) {
+ binFormat = -1;
+ }
+ }
+ if(null==shaderBinary) {
+ return null;
+ }
+ return new ShaderCode(type, number, binFormat, shaderBinary);
+ }
+
+ public static String getFileSuffix(boolean binary, int type) {
+ switch (type) {
+ case GL2ES2.GL_VERTEX_SHADER:
+ return binary?SUFFIX_VERTEX_BINARY:SUFFIX_VERTEX_SOURCE;
+ case GL2ES2.GL_FRAGMENT_SHADER:
+ return binary?SUFFIX_FRAGMENT_BINARY:SUFFIX_FRAGMENT_SOURCE;
+ default:
+ throw new GLException("illegal shader type: "+type);
+ }
+ }
+
+ public static String getBinarySubPath(int binFormat) {
+ switch (binFormat) {
+ case GLES2.GL_NVIDIA_PLATFORM_BINARY_NV:
+ return SUB_PATH_NVIDIA;
+ default:
+ throw new GLException("unsupported binary format: "+binFormat);
+ }
+ }
+
+ public static ShaderCode create(GL2ES2 gl, int type, int number, Class context,
+ String srcRoot, String binRoot, String basename) {
+ ShaderCode res = null;
+ String srcFileName = null;
+ String binFileName = null;
+
+ if(gl.glShaderCompilerAvailable()) {
+ String srcPath[] = new String[1];
+ srcFileName = srcRoot + '/' + basename + "." + getFileSuffix(false, type);
+ srcPath[0] = srcFileName;
+ res = create(type, number, context, srcPath);
+ if(null!=res) {
+ return res;
+ }
+ }
+ Set binFmts = gl.glGetShaderBinaryFormats();
+ for(Iterator iter=binFmts.iterator(); null==res && iter.hasNext(); ) {
+ int bFmt = ((Integer)(iter.next())).intValue();
+ String bFmtPath = getBinarySubPath(bFmt);
+ if(null==bFmtPath) continue;
+ binFileName = binRoot + '/' + bFmtPath + '/' + basename + "." + getFileSuffix(true, type);
+ res = create(type, number, context, bFmt, binFileName);
+ }
+
+ if(null==res) {
+ throw new GLException("No shader code found (source nor binary) for src: "+srcFileName+
+ ", bin: "+binFileName);
+ }
+
+ return res;
+ }
+
+ /**
+ * returns the uniq shader id as an integer
+ * @see #key()
+ */
+ public int id() { return id.intValue(); }
+
+ /**
+ * returns the uniq shader id as an Integer
+ *
+ * @see #id()
+ */
+ public Integer key() { return id; }
+
+ public int shaderType() { return shaderType; }
+ public String shaderTypeStr() { return shaderTypeStr(shaderType); }
+
+ public static String shaderTypeStr(int type) {
+ switch (type) {
+ case GL2ES2.GL_VERTEX_SHADER:
+ return "VERTEX_SHADER";
+ case GL2ES2.GL_FRAGMENT_SHADER:
+ return "FRAGMENT_SHADER";
+ }
+ return "UNKNOWN_SHADER";
+ }
+
+ public int shaderBinaryFormat() { return shaderBinaryFormat; }
+ public Buffer shaderBinary() { return shaderBinary; }
+ public String[][] shaderSource() { return shaderSource; }
+
+ public boolean isValid() { return valid; }
+
+ public IntBuffer shader() { return shader; }
+
+ public boolean compile(GL2ES2 gl) {
+ return compile(gl, null);
+ }
+ public boolean compile(GL2ES2 gl, PrintStream verboseOut) {
+ if(isValid()) return true;
+
+ // Create & Compile the vertex/fragment shader objects
+ if(null!=shaderSource) {
+ valid=gl.glCreateCompileShader(shader, shaderType,
+ shaderSource, verboseOut);
+ } else if(null!=shaderBinary) {
+ valid=gl.glCreateLoadShader(shader, shaderType,
+ shaderBinaryFormat, shaderBinary, verboseOut);
+ } else {
+ throw new GLException("no code (source or binary)");
+ }
+ return valid;
+ }
+
+ public void release(GL2ES2 gl) {
+ if(isValid()) {
+ gl.glDeleteShader(shader());
+ valid=false;
+ }
+ }
+
+ public boolean equals(Object obj) {
+ if(this==obj) return true;
+ if(obj instanceof ShaderCode) {
+ return id()==((ShaderCode)obj).id();
+ }
+ return false;
+ }
+ public int hashCode() {
+ return id.intValue();
+ }
+ public String toString() {
+ StringBuffer buf = new StringBuffer("ShaderCode [id="+id+", type="+shaderTypeStr()+", valid="+valid+", shader: ");
+ for(int i=0; i<shader.remaining(); i++) {
+ buf.append(" "+shader.get(i));
+ }
+ if(null!=shaderSource) {
+ buf.append(", source]");
+ } else if(null!=shaderBinary) {
+ buf.append(", binary "+shaderBinary+"]");
+ }
+ return buf.toString();
+ }
+
+ public static void readShaderSource(ClassLoader context, String path, URL url, StringBuffer result) {
+ try {
+ BufferedReader reader = new BufferedReader(new InputStreamReader(url.openStream()));
+ String line = null;
+ while ((line = reader.readLine()) != null) {
+ if (line.startsWith("#include ")) {
+ String includeFile = line.substring(9).trim();
+ // Try relative path first
+ String next = makeRelative(path, includeFile);
+ URL nextURL = getResource(next, context);
+ if (nextURL == null) {
+ // Try absolute path
+ next = includeFile;
+ nextURL = getResource(next, context);
+ }
+ if (nextURL == null) {
+ // Fail
+ throw new FileNotFoundException("Can't find include file " + includeFile);
+ }
+ readShaderSource(context, next, nextURL, result);
+ } else {
+ result.append(line + "\n");
+ }
+ }
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ public static String readShaderSource(Class context, String path) {
+ ClassLoader contextCL = (null!=context)?context.getClassLoader():null;
+ URL url = getResource(path, contextCL);
+ if (url == null && null!=context) {
+ // Try again by scoping the path within the class's package
+ String className = context.getName().replace('.', '/');
+ int lastSlash = className.lastIndexOf('/');
+ if (lastSlash >= 0) {
+ String tmpPath = className.substring(0, lastSlash + 1) + path;
+ url = getResource(tmpPath, contextCL);
+ if (url != null) {
+ path = tmpPath;
+ }
+ }
+ }
+ if (url == null) {
+ return null;
+ }
+ StringBuffer result = new StringBuffer();
+ readShaderSource(contextCL, path, url, result);
+ return result.toString();
+ }
+
+ public static ByteBuffer readShaderBinary(Class context, String path) {
+ try {
+ URL url = getResource(context, path);
+ if (url == null) {
+ return null;
+ }
+ return readAll(new BufferedInputStream(url.openStream()));
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ //----------------------------------------------------------------------
+ // Internals only below this point
+ //
+
+ public static URL getResource(Class context, String path) {
+ ClassLoader contextCL = (null!=context)?context.getClassLoader():null;
+ URL url = getResource(path, contextCL);
+ if (url == null && null!=context) {
+ // Try again by scoping the path within the class's package
+ String className = context.getName().replace('.', '/');
+ int lastSlash = className.lastIndexOf('/');
+ if (lastSlash >= 0) {
+ String tmpPath = className.substring(0, lastSlash + 1) + path;
+ url = getResource(tmpPath, contextCL);
+ }
+ }
+ return url;
+ }
+
+ public static URL getResource(String path, ClassLoader context) {
+ URL url = null;
+ if (context != null) {
+ url = context.getResource(path);
+ } else {
+ url = ClassLoader.getSystemResource(path);
+ }
+ if(!urlExists(url)) {
+ url = null;
+ try {
+ url = new URL(path);
+ } catch (MalformedURLException e) { }
+ }
+ if(!urlExists(url)) {
+ url = null;
+ try {
+ File file = new File(path);
+ if(file.exists()) {
+ url = file.toURL();
+ }
+ } catch (MalformedURLException e) {}
+ }
+ return url;
+ }
+
+ private static boolean urlExists(URL url) {
+ boolean v = false;
+ if(null!=url) {
+ try {
+ URLConnection uc = url.openConnection();
+ v = true;
+ } catch (IOException ioe) { }
+ }
+ return v;
+ }
+
+ private static String makeRelative(String context, String includeFile) {
+ File file = new File(context);
+ file = file.getParentFile();
+ while (file != null && includeFile.startsWith("../")) {
+ file = file.getParentFile();
+ includeFile = includeFile.substring(3);
+ }
+ if (file != null) {
+ String res = new File(file, includeFile).getPath();
+ // Handle things on Windows
+ return res.replace('\\', '/');
+ } else {
+ return includeFile;
+ }
+ }
+
+ private static ByteBuffer readAll(InputStream stream) throws IOException {
+ byte[] data = new byte[1024];
+ int numRead = 0;
+ int pos = 0;
+ do {
+ int avail = data.length - pos;
+ if (avail == 0) {
+ int newSize = 2 * data.length;
+ byte[] newData = new byte[newSize];
+ System.arraycopy(data, 0, newData, 0, data.length);
+ data = newData;
+ avail = data.length - pos;
+ }
+ numRead = stream.read(data, pos, avail);
+ if (numRead > 0) {
+ pos += numRead;
+ }
+ } while (numRead >= 0);
+ ByteBuffer res = BufferUtil.newByteBuffer(data, 0, pos);
+ return res;
+ }
+ protected String[][] shaderSource = null;
+ protected Buffer shaderBinary = null;
+ protected int shaderBinaryFormat = -1;
+ protected IntBuffer shader = null;
+ protected int shaderType = -1;
+ protected Integer id = null;
+
+ protected boolean valid=false;
+
+ private static synchronized Integer getNextID() {
+ return new Integer(nextID++);
+ }
+ protected static int nextID = 1;
+}
+
diff --git a/src/classes/javax/media/opengl/glsl/ShaderProgram.java b/src/classes/javax/media/opengl/glsl/ShaderProgram.java
new file mode 100644
index 000000000..13ad44b05
--- /dev/null
+++ b/src/classes/javax/media/opengl/glsl/ShaderProgram.java
@@ -0,0 +1,197 @@
+
+package javax.media.opengl.glsl;
+
+import javax.media.opengl.*;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.nio.*;
+import java.io.PrintStream;
+
+public class ShaderProgram {
+ public ShaderProgram() {
+ id = getNextID();
+ }
+
+ public boolean linked() {
+ return programLinked;
+ }
+
+ public boolean inUse() {
+ return programInUse;
+ }
+
+ public int program() { return shaderProgram; }
+
+ /**
+ * returns the uniq shader id as an integer
+ * @see #key()
+ */
+ public int id() { return id.intValue(); }
+
+ /**
+ * returns the uniq shader id as an Integer
+ *
+ * @see #id()
+ */
+ public Integer key() { return id; }
+
+ /**
+ * @see #glReleaseAllVertexAttributes
+ */
+ public synchronized void release(GL2ES2 gl) {
+ release(gl, false);
+ }
+
+ /**
+ * @see #glReleaseAllVertexAttributes
+ */
+ public synchronized void release(GL2ES2 gl, boolean releaseShaderToo) {
+ glUseProgram(gl, false);
+ for(Iterator iter=shaderMap.values().iterator(); iter.hasNext(); ) {
+ ShaderCode shaderCode = (ShaderCode) iter.next();
+ gl.glDetachShader(shaderProgram, shaderCode.shader());
+ if(releaseShaderToo) {
+ shaderCode.release(gl);
+ }
+ }
+ shaderMap.clear();
+ gl.glDeleteProgram(shaderProgram);
+ shaderProgram=-1;
+ }
+
+ //
+ // ShaderCode handling
+ //
+
+ /**
+ * Adds a new shader to a this non running program.
+ *
+ * @return false if the program is in use, or the shader already exist,
+ * otherwise true.
+ */
+ public synchronized boolean add(ShaderCode shaderCode) {
+ if(shaderMap.containsKey(shaderCode.key())) return false;
+ shaderMap.put(shaderCode.key(), shaderCode);
+ return true;
+ }
+
+ public synchronized ShaderCode getShader(int id) {
+ return (ShaderCode) shaderMap.get(new Integer(id));
+ }
+
+ //
+ // Program handling
+ //
+
+ /**
+ * Replace a shader in a 'running' program.
+ * Refetches all previously bin/get attribute names
+ * and resets all attribute data as well
+ *
+ * @see getAttribLocation
+ * @param gl
+ * @param oldShaderID the to be replace Shader
+ * @param newShader the new ShaderCode
+ * @param verboseOut the optional verbose outputstream
+ * @throws GLException is the program is not linked
+ *
+ * @see #glRefetchAttribLocations
+ * @see #glResetAllVertexAttributes
+ * @see #glReplaceShader
+ */
+ public synchronized boolean glReplaceShader(GL2ES2 gl, int oldShaderID, ShaderCode newShader, PrintStream verboseOut) {
+ if(!programLinked) throw new GLException("Program is not linked");
+ boolean shaderWasInUse = programInUse;
+ glUseProgram(gl, false);
+ if(!newShader.compile(gl, verboseOut)) {
+ return false;
+ }
+ if(oldShaderID>=0) {
+ ShaderCode oldShader = (ShaderCode) shaderMap.remove(new Integer(oldShaderID));
+ if(null!=oldShader) {
+ gl.glDetachShader(shaderProgram, oldShader.shader());
+ }
+ }
+ add(newShader);
+
+ gl.glAttachShader(shaderProgram, newShader.shader());
+ gl.glLinkProgram(shaderProgram);
+ if ( ! gl.glIsProgramValid(shaderProgram, System.err) ) {
+ return false;
+ }
+
+ if(shaderWasInUse) {
+ glUseProgram(gl, true);
+ }
+ return true;
+ }
+
+ public synchronized boolean link(GL2ES2 gl, PrintStream verboseOut) {
+ if(programLinked) throw new GLException("Program is already linked");
+
+ if(0>shaderProgram) {
+ shaderProgram = gl.glCreateProgram();
+ }
+
+ for(Iterator iter=shaderMap.values().iterator(); iter.hasNext(); ) {
+ ShaderCode shaderCode = (ShaderCode) iter.next();
+ if(!shaderCode.compile(gl, verboseOut)) {
+ return false;
+ }
+ gl.glAttachShader(shaderProgram, shaderCode.shader());
+ }
+
+ // Link the program
+ gl.glLinkProgram(shaderProgram);
+
+ programLinked = gl.glIsProgramValid(shaderProgram, System.err);
+
+ return programLinked;
+ }
+
+ public boolean equals(Object obj) {
+ if(this==obj) return true;
+ if(obj instanceof ShaderCode) {
+ return id()==((ShaderCode)obj).id();
+ }
+ return false;
+ }
+ public int hashCode() {
+ return id.intValue();
+ }
+ public String toString() {
+ StringBuffer buf = new StringBuffer();
+ buf.append("ShaderProgram[id="+id);
+ buf.append(", linked="+programLinked+", inUse="+programInUse+", program: "+shaderProgram+", [");
+ for(Iterator iter=shaderMap.values().iterator(); iter.hasNext(); ) {
+ buf.append((ShaderCode) iter.next());
+ buf.append(" ");
+ }
+ buf.append("]");
+ return buf.toString();
+ }
+
+ protected synchronized void glUseProgram(GL2ES2 gl, boolean on) {
+ if(!programLinked) throw new GLException("Program is not linked");
+ if(programInUse==on) return;
+ gl.glUseProgram(on?shaderProgram:0);
+ programInUse = on;
+
+ //Throwable tX = new Throwable("Info: ShaderProgram.glUseProgram: "+on);
+ //tX.printStackTrace();
+
+ }
+
+ protected boolean programLinked = false;
+ protected boolean programInUse = false;
+ protected int shaderProgram=-1;
+ protected HashMap shaderMap = new HashMap();
+ protected Integer id = null;
+
+ private static synchronized Integer getNextID() {
+ return new Integer(nextID++);
+ }
+ protected static int nextID = 1;
+}
+
diff --git a/src/classes/javax/media/opengl/glsl/ShaderState.java b/src/classes/javax/media/opengl/glsl/ShaderState.java
new file mode 100644
index 000000000..f17e844e8
--- /dev/null
+++ b/src/classes/javax/media/opengl/glsl/ShaderState.java
@@ -0,0 +1,582 @@
+
+package javax.media.opengl.glsl;
+
+import javax.media.opengl.*;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.nio.*;
+import java.io.PrintStream;
+
+public class ShaderState {
+
+ public ShaderState() {
+ }
+
+ public boolean verbose() { return verbose; }
+
+ public void setVerbose(boolean v) { verbose=v; }
+
+ /**
+ * Fetches the current shader state
+ *
+ * @see javax.media.opengl.glsl.ShaderState#glUseProgram(GL2ES2, boolean)
+ * @see javax.media.opengl.glsl.ShaderState#getCurrent()
+ */
+ public static synchronized ShaderState getCurrent() { return currentShaderState; }
+
+ /**
+ * Turns the shader program on
+ * and set this ShaderState to current if on equals true
+ *
+ * @see javax.media.opengl.glsl.ShaderState#glUseProgram(GL2ES2, boolean)
+ * @see javax.media.opengl.glsl.ShaderState#getCurrent()
+ */
+ public synchronized void glUseProgram(GL2ES2 gl, boolean on) {
+ if(on) {
+ if(null!=shaderProgram) {
+ shaderProgram.glUseProgram(gl, true);
+ } else {
+ throw new GLException("No program is attached");
+ }
+ if(currentShaderState!=this) {
+ currentShaderState = this;
+ }
+ } else if(null!=shaderProgram) {
+ shaderProgram.glUseProgram(gl, false);
+ }
+ }
+
+ public boolean linked() {
+ return (null!=shaderProgram)?shaderProgram.linked():false;
+ }
+
+ public boolean inUse() {
+ return (null!=shaderProgram)?shaderProgram.inUse():false;
+ }
+
+ /**
+ * Attach or switch a shader program
+ *
+ * Attaching a shader program the first time,
+ * as well as switching to another program on the fly,
+ * while managing all attribute and uniform data.
+ */
+ public synchronized void attachShaderProgram(GL2ES2 gl, ShaderProgram prog) {
+ boolean prgInUse = false; // earmarked state
+
+ if(null!=shaderProgram) {
+ if(shaderProgram.equals(prog)) {
+ // nothing to do ..
+ if(DEBUG) {
+ System.err.println("Info: attachShaderProgram: NOP: equal id: "+shaderProgram.id());
+ }
+ return;
+ }
+ prgInUse = shaderProgram.inUse();
+ }
+ if(DEBUG) {
+ Throwable tX = new Throwable("Info: attachShaderProgram: BEGIN "+shaderProgram+" -> "+prog);
+ tX.printStackTrace();
+ }
+
+ // register new one
+ shaderProgram = prog;
+
+ if(null!=shaderProgram) {
+ // reinstall all data ..
+ shaderProgram.glUseProgram(gl, true);
+ glResetAllVertexAttributes(gl);
+ glResetAllUniforms(gl);
+ if(!prgInUse) {
+ shaderProgram.glUseProgram(gl, false);
+ }
+ }
+ if(DEBUG) {
+ System.err.println("Info: attachShaderProgram: END");
+ }
+ }
+
+ public ShaderProgram shaderProgram() { return shaderProgram; }
+
+ /**
+ * @see #glReleaseAllVertexAttributes
+ * @see #glReleaseAllUniforms
+ */
+ public synchronized void release(GL2ES2 gl) {
+ release(gl, false, false);
+ }
+
+ public synchronized void release(GL2ES2 gl, boolean releaseProgramToo, boolean releaseShaderToo) {
+ boolean prgInUse = false;
+ if(null!=shaderProgram) {
+ prgInUse = shaderProgram.inUse();
+ if(!prgInUse) {
+ shaderProgram.glUseProgram(gl, true);
+ }
+ }
+ glReleaseAllVertexAttributes(gl);
+ glReleaseAllUniforms(gl);
+ if(null!=shaderProgram) {
+ if(releaseProgramToo) {
+ shaderProgram.release(gl, releaseShaderToo);
+ } else if(!prgInUse) {
+ shaderProgram.glUseProgram(gl, false);
+ }
+ }
+ }
+
+ //
+ // Shader attribute handling
+ //
+
+ /**
+ * Binds an attribute to the shader.
+ * This must be done before the program is linked !
+ * n name - 1 idx, where name is a uniq key
+ *
+ * @throws GLException is the program is already linked
+ *
+ * @see #glBindAttribLocation
+ * @see javax.media.opengl.GL2ES2#glBindAttribLocation
+ * @see #glGetAttribLocation
+ * @see javax.media.opengl.GL2ES2#glGetAttribLocation
+ * @see #getAttribLocation
+ * @see #glReplaceShader
+ */
+ public void glBindAttribLocation(GL2ES2 gl, int index, String name) {
+ if(null==shaderProgram) throw new GLException("No program is attached");
+ if(shaderProgram.linked()) throw new GLException("Program is already linked");
+ Integer idx = new Integer(index);
+ if(!attribMap2Idx.containsKey(name)) {
+ attribMap2Idx.put(name, idx);
+ gl.glBindAttribLocation(shaderProgram.program(), index, name);
+ }
+ }
+
+ /**
+ * Gets the index of a shader attribute.
+ * This must be done after the program is linked !
+ *
+ * @return -1 if there is no such attribute available,
+ * otherwise >= 0
+ * @throws GLException is the program is not linked
+ *
+ * @see #glBindAttribLocation
+ * @see javax.media.opengl.GL2ES2#glBindAttribLocation
+ * @see #glGetAttribLocation
+ * @see javax.media.opengl.GL2ES2#glGetAttribLocation
+ * @see #getAttribLocation
+ * @see #glReplaceShader
+ */
+ public int glGetAttribLocation(GL2ES2 gl, String name) {
+ if(!shaderProgram.linked()) throw new GLException("Program is not linked");
+ int index = getAttribLocation(name);
+ if(0>index) {
+ index = gl.glGetAttribLocation(shaderProgram.program(), name);
+ if(0<=index) {
+ Integer idx = new Integer(index);
+ attribMap2Idx.put(name, idx);
+ } else if(verbose) {
+ Throwable tX = new Throwable("Info: glGetAttribLocation failed, no location for: "+name+", index: "+index);
+ tX.printStackTrace();
+ }
+ }
+ return index;
+ }
+
+ protected int getAttribLocation(String name) {
+ Integer idx = (Integer) attribMap2Idx.get(name);
+ return (null!=idx)?idx.intValue():-1;
+ }
+
+
+ //
+ // Enabled Vertex Arrays and its data
+ //
+
+ /**
+ * Enable a vertex attribute array
+ *
+ * Even if the attribute is not found in the current shader,
+ * it is stored in this state.
+ *
+ * @returns false, if the name is not found, otherwise true
+ *
+ * @throws GLException if the program is not in use
+ *
+ * @see #glEnableVertexAttribArray
+ * @see #glDisableVertexAttribArray
+ * @see #glVertexAttribPointer
+ * @see #getVertexAttributePointer
+ * @see #glReleaseAllVertexAttributes
+ * @see #glResetAllVertexAttributes
+ * @see #glReplaceShader
+ */
+ public boolean glEnableVertexAttribArray(GL2ES2 gl, String name) {
+ if(!shaderProgram.inUse()) throw new GLException("Program is not in use");
+ enabledVertexAttribArraySet.add(name);
+ int index = glGetAttribLocation(gl, name);
+ if(0>index) {
+ if(verbose) {
+ Throwable tX = new Throwable("Info: glEnableVertexAttribArray failed, no index for: "+name);
+ tX.printStackTrace();
+ }
+ return false;
+ }
+ if(DEBUG) {
+ System.err.println("Info: glEnableVertexAttribArray: "+name);
+ }
+ gl.glEnableVertexAttribArray(index);
+ return true;
+ }
+
+ public boolean isVertexAttribArrayEnabled(String name) {
+ if(!shaderProgram.inUse()) throw new GLException("Program is not in use");
+ return enabledVertexAttribArraySet.contains(name);
+ }
+
+ /**
+ * Disables a vertex attribute array
+ *
+ * Even if the attribute is not found in the current shader,
+ * it is removed from this state.
+ *
+ * @returns false, if the name is not found, otherwise true
+ *
+ * @throws GLException if the program is not in use
+ *
+ * @see #glEnableVertexAttribArray
+ * @see #glDisableVertexAttribArray
+ * @see #glVertexAttribPointer
+ * @see #getVertexAttributePointer
+ * @see #glReleaseAllVertexAttributes
+ * @see #glResetAllVertexAttributes
+ * @see #glReplaceShader
+ */
+ public boolean glDisableVertexAttribArray(GL2ES2 gl, String name) {
+ if(!shaderProgram.inUse()) throw new GLException("Program is not in use");
+ enabledVertexAttribArraySet.remove(name);
+ int index = glGetAttribLocation(gl, name);
+ if(0>index) {
+ if(verbose) {
+ Throwable tX = new Throwable("Info: glDisableVertexAttribArray failed, no index for: "+name);
+ tX.printStackTrace();
+ }
+ return false;
+ }
+ if(DEBUG) {
+ System.err.println("Info: glDisableVertexAttribArray: "+name);
+ }
+ gl.glDisableVertexAttribArray(index);
+ return true;
+ }
+
+ /**
+ * Set the vertex attribute data.
+ * Enable the attribute, if it is not enabled yet.
+ *
+ * Even if the attribute is not found in the current shader,
+ * it is stored in this state.
+ *
+ * @arg data the GLArrayData's name must match the attributes one,
+ * it's index will be set with the attribute's location,
+ * if found.
+ *
+ * @returns false, if the name is not found, otherwise true
+ *
+ * @throws GLException if the program is not in use
+ *
+ * @see #glEnableVertexAttribArray
+ * @see #glDisableVertexAttribArray
+ * @see #glVertexAttribPointer
+ * @see #getVertexAttributePointer
+ * @see #glReleaseAllVertexAttributes
+ * @see #glResetAllVertexAttributes
+ * @see #glReplaceShader
+ */
+ public boolean glVertexAttribPointer(GL2ES2 gl, GLArrayData data) {
+ if(!shaderProgram.inUse()) throw new GLException("Program is not in use");
+ if(!enabledVertexAttribArraySet.contains(data.getName())) {
+ if(!glEnableVertexAttribArray(gl, data.getName())) {
+ if(verbose) {
+ Throwable tX = new Throwable("Info: glVertexAttribPointer: couldn't enable: "+data);
+ tX.printStackTrace();
+ }
+ }
+ }
+ int index = getAttribLocation(data.getName());
+ if(0>index) {
+ if(verbose) {
+ Throwable tX = new Throwable("Info: glVertexAttribPointer failed, no index for: "+data);
+ tX.printStackTrace();
+ }
+ }
+ data.setLocation(index);
+ vertexAttribMap2Data.put(data.getName(), data);
+ if(0<=index) {
+ // only pass the data, if the attribute exists in the current shader
+ if(DEBUG) {
+ System.err.println("Info: glVertexAttribPointer: "+data);
+ }
+ gl.glVertexAttribPointer(data);
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Get the vertex attribute data, previously set.
+ *
+ * @returns the GLArrayData object, null if not previously set.
+ *
+ * @see #glEnableVertexAttribArray
+ * @see #glDisableVertexAttribArray
+ * @see #glVertexAttribPointer
+ * @see #getVertexAttributePointer
+ * @see #glReleaseAllVertexAttributes
+ * @see #glResetAllVertexAttributes
+ * @see #glReplaceShader
+ */
+ public GLArrayData getVertexAttribPointer(String name) {
+ return (GLArrayData) vertexAttribMap2Data.get(name);
+ }
+
+ /**
+ * Releases all mapped vertex attribute data,
+ * disables all enabled attributes and loses all indices
+ *
+ * @throws GLException is the program is not in use but the shaderProgram is set
+ *
+ * @see #glEnableVertexAttribArray
+ * @see #glDisableVertexAttribArray
+ * @see #glVertexAttribPointer
+ * @see #getVertexAttributePointer
+ * @see #glReleaseAllVertexAttributes
+ * @see #glResetAllVertexAttributes
+ * @see #glResetAllVertexAttributes
+ * @see #glReplaceShader
+ */
+ public void glReleaseAllVertexAttributes(GL2ES2 gl) {
+ if(null!=shaderProgram) {
+ if(!shaderProgram.inUse()) throw new GLException("Program is not in use");
+ for(Iterator iter = vertexAttribMap2Data.keySet().iterator(); iter.hasNext(); ) {
+ if(!glDisableVertexAttribArray(gl, (String) iter.next())) {
+ throw new GLException("Internal Error: mapped vertex attribute couldn't be disabled");
+ }
+ }
+ for(Iterator iter = enabledVertexAttribArraySet.iterator(); iter.hasNext(); ) {
+ if(!glDisableVertexAttribArray(gl, (String) iter.next())) {
+ throw new GLException("Internal Error: prev enabled vertex attribute couldn't be disabled");
+ }
+ }
+ }
+ vertexAttribMap2Data.clear();
+ enabledVertexAttribArraySet.clear();
+ attribMap2Idx.clear();
+ }
+
+ /**
+ * Disables all vertex attribute arrays.
+ *
+ * Their enabled stated will be removed from this state only
+ * if 'removeFromState' is true.
+ *
+ * This method purpose is more for debugging.
+ *
+ * @throws GLException is the program is not in use but the shaderProgram is set
+ *
+ * @see #glEnableVertexAttribArray
+ * @see #glDisableVertexAttribArray
+ * @see #glVertexAttribPointer
+ * @see #getVertexAttributePointer
+ * @see #glReleaseAllVertexAttributes
+ * @see #glResetAllVertexAttributes
+ * @see #glResetAllVertexAttributes
+ * @see #glReplaceShader
+ */
+ public void glDisableAllVertexAttributeArrays(GL2ES2 gl, boolean removeFromState) {
+ if(!shaderProgram.inUse()) throw new GLException("Program is not in use");
+
+ for(Iterator iter = enabledVertexAttribArraySet.iterator(); iter.hasNext(); ) {
+ String name = (String) iter.next();
+ if(removeFromState) {
+ enabledVertexAttribArraySet.remove(name);
+ }
+ int index = glGetAttribLocation(gl, name);
+ if(0<=index) {
+ gl.glDisableVertexAttribArray(index);
+ }
+ }
+ }
+
+ /**
+ * Reset all previously mapped vertex attribute data,
+ * incl enabling them
+ *
+ * @throws GLException is the program is not in use
+ *
+ * @see #glEnableVertexAttribArray
+ * @see #glDisableVertexAttribArray
+ * @see #glVertexAttribPointer
+ * @see #getVertexAttributePointer
+ * @see #glReleaseAllVertexAttributes
+ * @see #glResetAllVertexAttributes
+ * @see #glReplaceShader
+ */
+ public void glResetAllVertexAttributes(GL2ES2 gl) {
+ if(!shaderProgram.inUse()) throw new GLException("Program is not in use");
+ attribMap2Idx.clear();
+
+ for(Iterator iter = enabledVertexAttribArraySet.iterator(); iter.hasNext(); ) {
+ glEnableVertexAttribArray(gl, (String) iter.next());
+ }
+
+ for(Iterator iter = vertexAttribMap2Data.values().iterator(); iter.hasNext(); ) {
+ glVertexAttribPointer(gl, (GLArrayData) iter.next());
+ }
+ }
+
+ //
+ // Shader Uniform handling
+ //
+
+ /**
+ * Gets the index of a shader uniform.
+ * This must be done when the program is in use !
+ *
+ * @return -1 if there is no such attribute available,
+ * otherwise >= 0
+
+ * @throws GLException is the program is not linked
+ *
+ * @see #glGetUniformLocation
+ * @see javax.media.opengl.GL2ES2#glGetUniformLocation
+ * @see #getUniformLocation
+ * @see #glReplaceShader
+ */
+ protected int glGetUniformLocation(GL2ES2 gl, String name) {
+ if(!shaderProgram.inUse()) throw new GLException("Program is not in use");
+ int index = getUniformLocation(name);
+ if(0>index) {
+ index = gl.glGetUniformLocation(shaderProgram.program(), name);
+ if(0<=index) {
+ Integer idx = new Integer(index);
+ uniformMap2Idx.put(name, idx);
+ } else if(verbose) {
+ Throwable tX = new Throwable("Info: glUniform failed, no location for: "+name+", index: "+index);
+ tX.printStackTrace();
+ }
+ }
+ return index;
+ }
+
+ protected int getUniformLocation(String name) {
+ Integer idx = (Integer) uniformMap2Idx.get(name);
+ return (null!=idx)?idx.intValue():-1;
+ }
+
+ /**
+ * Set the uniform data.
+ *
+ * Even if the uniform is not found in the current shader,
+ * it is stored in this state.
+ *
+ * @arg data the GLUniforms's name must match the uniform one,
+ * it's index will be set with the uniforms's location,
+ * if found.
+ *
+ *
+ * @returns false, if the name is not found, otherwise true
+ *
+ * @throws GLException if the program is not in use
+ *
+ * @see #glGetUniformLocation
+ * @see javax.media.opengl.GL2ES2#glGetUniformLocation
+ * @see #getUniformLocation
+ * @see #glReplaceShader
+ */
+ public boolean glUniform(GL2ES2 gl, GLUniformData data) {
+ if(!shaderProgram.inUse()) throw new GLException("Program is not in use");
+ int location = glGetUniformLocation(gl, data.getName());
+ data.setLocation(location);
+ uniformMap2Data.put(data.getName(), data);
+ if(0<=location) {
+ // only pass the data, if the uniform exists in the current shader
+ if(DEBUG) {
+ System.err.println("Info: glUniform: "+data);
+ }
+ gl.glUniform(data);
+ }
+ return true;
+ }
+
+ /**
+ * Get the uniform data, previously set.
+ *
+ * @returns the GLUniformData object, null if not previously set.
+ */
+ public GLUniformData getUniform(String name) {
+ return (GLUniformData) uniformMap2Data.get(name);
+ }
+
+ /**
+ * Releases all mapped uniform data
+ * and loses all indices
+ *
+ * @throws GLException is the program is not in use
+ */
+ public void glReleaseAllUniforms(GL2ES2 gl) {
+ uniformMap2Data.clear();
+ uniformMap2Idx.clear();
+ }
+
+ /**
+ * Reset all previously mapped uniform data
+ *
+ * @throws GLException is the program is not in use
+ */
+ public void glResetAllUniforms(GL2ES2 gl) {
+ if(!shaderProgram.inUse()) throw new GLException("Program is not in use");
+ uniformMap2Idx.clear();
+ for(Iterator iter = uniformMap2Data.values().iterator(); iter.hasNext(); ) {
+ glUniform(gl, (GLUniformData) iter.next());
+ }
+ }
+
+ public String toString() {
+ StringBuffer buf = new StringBuffer();
+ buf.append("ShaderState[");
+ buf.append(shaderProgram.toString());
+ buf.append(",EnabledStates: [");
+ for(Iterator iter = enabledVertexAttribArraySet.iterator(); iter.hasNext(); ) {
+ buf.append("\n ");
+ buf.append((String)iter.next());
+ }
+ buf.append("], [");
+ for(Iterator iter = vertexAttribMap2Data.values().iterator(); iter.hasNext(); ) {
+ buf.append("\n ");
+ buf.append((GLArrayData) iter.next());
+ }
+ buf.append("], [");
+ for(Iterator iter=uniformMap2Data.values().iterator(); iter.hasNext(); ) {
+ buf.append("\n ");
+ buf.append((GLUniformData) iter.next());
+ }
+ buf.append("]");
+ return buf.toString();
+ }
+
+ protected static final boolean DEBUG = false;
+ protected boolean verbose = false;
+ protected ShaderProgram shaderProgram=null;
+ protected HashMap attribMap2Idx = new HashMap();
+ protected HashSet enabledVertexAttribArraySet = new HashSet();
+ protected HashMap vertexAttribMap2Data = new HashMap();
+ protected HashMap uniformMap2Idx = new HashMap();
+ protected HashMap uniformMap2Data = new HashMap();
+ protected static ShaderState currentShaderState = null;
+
+}
+
diff --git a/src/classes/javax/media/opengl/sdk/glsl/CompileShader.java b/src/classes/javax/media/opengl/sdk/glsl/CompileShader.java
new file mode 100755
index 000000000..398836527
--- /dev/null
+++ b/src/classes/javax/media/opengl/sdk/glsl/CompileShader.java
@@ -0,0 +1,183 @@
+package javax.media.opengl.sdk.glsl;
+
+import javax.media.opengl.glsl.*;
+import javax.media.opengl.*;
+
+import java.io.*;
+import java.net.*;
+
+/** Precompiles a shader into a vendor binary format. Input is the
+ resource name of the shader, such as
+ "com/sun/opengl/impl/glsl/fixed/shader/a.fp".
+ Output is "com/sun/opengl/impl/glsl/fixed/shader/bin/nvidia/a.bfp".
+
+ All path and suffixes are determined by the ShaderCode class,
+ which ensures runtime compatibility.
+
+ @see javax.media.opengl.glsl.ShaderCode
+ */
+
+public abstract class CompileShader {
+
+ public abstract int getBinaryFormat();
+
+ public abstract File getSDKCompilerDir();
+
+ public abstract String getVertexShaderCompiler();
+
+ public abstract String getFragmentShaderCompiler();
+
+ public void processOneShader(String resourceName)
+ throws IOException, UnsupportedEncodingException, InterruptedException
+ {
+ int type = -1;
+ String outName=null;
+ int suffixLen = -1;
+ if(resourceName.endsWith(ShaderCode.getFileSuffix(false, GL2ES2.GL_FRAGMENT_SHADER))) {
+ suffixLen = 2;
+ type = GL2ES2.GL_FRAGMENT_SHADER;
+ } else if(resourceName.endsWith(".frag")) {
+ suffixLen = 4;
+ type = GL2ES2.GL_FRAGMENT_SHADER;
+ } else if(resourceName.endsWith(ShaderCode.getFileSuffix(false, GL2ES2.GL_VERTEX_SHADER))) {
+ suffixLen = 2;
+ type = GL2ES2.GL_VERTEX_SHADER;
+ } else if(resourceName.endsWith(".vert")) {
+ suffixLen = 4;
+ type = GL2ES2.GL_VERTEX_SHADER;
+ }
+ String justName = basename(resourceName);
+ outName = justName.substring(0, justName.length() - suffixLen) +
+ ShaderCode.getFileSuffix(true, type);
+ URL resourceURL = ShaderCode.getResource(null, resourceName);
+ String dirName = dirname(resourceURL.getPath());
+
+ outName = dirName + File.separator + "bin" + File.separator +
+ ShaderCode.getBinarySubPath(getBinaryFormat()) + File.separator +
+ outName;
+ processOneShader(resourceName, outName, type);
+ }
+
+ public void processOneShader(String resourceName, String outName, int type)
+ throws IOException, UnsupportedEncodingException, InterruptedException
+ {
+ URL resourceURL = ShaderCode.getResource(null, resourceName);
+ String dirName = dirname(resourceURL.getPath());
+
+ String shader = ShaderCode.readShaderSource(null, resourceName);
+ if(null==shader) {
+ System.err.println("Can't find shader source " + resourceName + " - ignored");
+ return;
+ }
+ System.err.println("Preprocessing: "+ resourceName+", in dir: "+dirName);
+ String justName = basename(resourceName);
+ String processor;
+ switch (type) {
+ case GL2ES2.GL_VERTEX_SHADER:
+ processor = getVertexShaderCompiler();
+ break;
+ case GL2ES2.GL_FRAGMENT_SHADER:
+ processor = getFragmentShaderCompiler();
+ break;
+ default:
+ throw new GLException("Unknown shader type: "+type);
+ }
+ File outputFile = new File(outName);
+
+ // Write shader to a file in java.io.tmpdir
+ File tmpDir = new File(dirName+File.separator+"tmp");
+ tmpDir.mkdirs();
+ File tmpFile = new File(tmpDir, justName);
+ Writer writer = new BufferedWriter(new FileWriter(tmpFile));
+ writer.write(shader, 0, shader.length());
+ writer.flush();
+ writer.close();
+ System.err.println("Preprocessed: "+ tmpFile.getAbsolutePath());
+
+ File processorDir = getSDKCompilerDir();
+
+ System.err.println("SDK: "+ processorDir.getAbsolutePath() + ", compiler: "+processor);
+
+ System.err.println("Output: "+ outputFile.getAbsolutePath());
+
+ // Run the tool
+ Process process = Runtime.getRuntime().exec(new String[] {
+ processorDir.getAbsolutePath() + File.separator + processor,
+ tmpFile.getAbsolutePath(),
+ outputFile.getAbsolutePath()
+ }); // , null, processorDir);
+ new StreamMonitor(process.getInputStream());
+ new StreamMonitor(process.getErrorStream());
+ process.waitFor();
+ // Delete the temporary file
+ // tmpFile.delete();
+ }
+
+ protected static String basename(String path) {
+ int lastSlash = path.lastIndexOf("/");
+ if (lastSlash < 0) {
+ lastSlash = path.lastIndexOf("\\");
+ }
+ String basename;
+ if (lastSlash < 0) {
+ basename = path;
+ } else {
+ basename = path.substring(lastSlash + 1);
+ }
+ return basename;
+ }
+
+ protected static String dirname(String path) {
+ int lastSlash = path.lastIndexOf("/");
+ if (lastSlash < 0) {
+ lastSlash = path.lastIndexOf("\\");
+ }
+ String dirname;
+ if (lastSlash < 0) {
+ dirname = new String();
+ } else {
+ dirname = path.substring(0, lastSlash + 1);
+ }
+ return dirname;
+ }
+
+ public void run(String[] args) {
+ try {
+ for (int i = 0; i < args.length; i++) {
+ processOneShader(args[i]);
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ private static class StreamMonitor implements Runnable {
+ private InputStream istream;
+ public StreamMonitor(InputStream stream) {
+ istream = stream;
+ new Thread(this, "Output Reader Thread").start();
+ }
+
+ public void run()
+ {
+ byte[] buffer = new byte[4096];
+ try {
+ int numRead = 0;
+ do {
+ numRead = istream.read(buffer);
+ if (numRead > 0) {
+ System.out.write(buffer, 0, numRead);
+ System.out.flush();
+ }
+ } while (numRead >= 0);
+ }
+ catch (IOException e) {
+ try {
+ istream.close();
+ } catch (IOException e2) {
+ }
+ // Should allow clean exit when process shuts down
+ }
+ }
+ }
+}
diff --git a/src/classes/javax/media/opengl/sdk/glsl/CompileShaderNVidia.java b/src/classes/javax/media/opengl/sdk/glsl/CompileShaderNVidia.java
new file mode 100755
index 000000000..c0c0d1c1e
--- /dev/null
+++ b/src/classes/javax/media/opengl/sdk/glsl/CompileShaderNVidia.java
@@ -0,0 +1,54 @@
+package javax.media.opengl.sdk.glsl;
+
+import javax.media.opengl.glsl.*;
+import javax.media.opengl.*;
+
+import java.io.*;
+
+/** Precompiles a shader into NVidia binary format. Input is the
+ resource name of the shader, such as
+ "com/sun/opengl/impl/glsl/fixed/shader/a.fp".
+ Output is "com/sun/opengl/impl/glsl/fixed/shader/bin/nvidia/a.bfp". */
+
+public class CompileShaderNVidia extends CompileShader {
+ private static final String NVAPSDK;
+
+ static {
+ String nvapSDKProp = System.getProperty("NVAPSDK");
+ if (nvapSDKProp != null) {
+ NVAPSDK = nvapSDKProp;
+ } else {
+ NVAPSDK = "C:\\nvap_sdk_0_3_x";
+ }
+ }
+
+ public int getBinaryFormat() {
+ return GLES2.GL_NVIDIA_PLATFORM_BINARY_NV;
+ }
+
+ public File getSDKCompilerDir() {
+ File compilerDir = new File( NVAPSDK + File.separator + "tools" + File.separator );
+ File compilerFile = new File( compilerDir, getVertexShaderCompiler());
+ if(!compilerFile.exists()) {
+ compilerDir = new File( NVAPSDK );
+ compilerFile = new File( compilerDir, getVertexShaderCompiler());
+ }
+ if(!compilerFile.exists()) {
+ throw new GLException("Can't find compiler: "+getVertexShaderCompiler() + " in : " +
+ NVAPSDK+", "+NVAPSDK + File.separator + "tools");
+ }
+ return compilerDir;
+ }
+
+ public String getVertexShaderCompiler() {
+ return "glslv.bat";
+ }
+
+ public String getFragmentShaderCompiler() {
+ return "glslf.bat";
+ }
+
+ public static void main(String[] args) {
+ new CompileShaderNVidia().run(args);
+ }
+}
diff --git a/src/classes/javax/media/opengl/util/BufferUtil.java.javame_cdc_fp b/src/classes/javax/media/opengl/util/BufferUtil.java.javame_cdc_fp
index 363d623cb..425756c07 100755
--- a/src/classes/javax/media/opengl/util/BufferUtil.java.javame_cdc_fp
+++ b/src/classes/javax/media/opengl/util/BufferUtil.java.javame_cdc_fp
@@ -69,14 +69,17 @@ public class BufferUtil {
return bb;
}
- public static ByteBuffer newByteBuffer(byte[] values, int offset) {
- int len = values.length-offset;
+ public static ByteBuffer newByteBuffer(byte[] values, int offset, int len) {
ByteBuffer bb = newByteBuffer(len);
bb.put(values, offset, len);
bb.rewind();
return bb;
}
+ public static ByteBuffer newByteBuffer(byte[] values, int offset) {
+ return newByteBuffer(values, offset, values.length-offset);
+ }
+
public static ByteBuffer newByteBuffer(byte[] values) {
return newByteBuffer(values, 0);
}
@@ -89,14 +92,17 @@ public class BufferUtil {
return bb.asFloatBuffer();
}
- public static FloatBuffer newFloatBuffer(float[] values, int offset) {
- int len = values.length-offset;
+ public static FloatBuffer newFloatBuffer(float[] values, int offset, int len) {
FloatBuffer bb = newFloatBuffer(len);
bb.put(values, offset, len);
bb.rewind();
return bb;
}
+ public static FloatBuffer newFloatBuffer(float[] values, int offset) {
+ return newFloatBuffer(values, 0, values.length-offset);
+ }
+
public static FloatBuffer newFloatBuffer(float[] values) {
return newFloatBuffer(values, 0);
}
@@ -109,14 +115,17 @@ public class BufferUtil {
return bb.asIntBuffer();
}
- public static IntBuffer newIntBuffer(int[] values, int offset) {
- int len = values.length-offset;
+ public static IntBuffer newIntBuffer(int[] values, int offset, int len) {
IntBuffer bb = newIntBuffer(len);
bb.put(values, offset, len);
bb.rewind();
return bb;
}
+ public static IntBuffer newIntBuffer(int[] values, int offset) {
+ return newIntBuffer(values, 0, values.length-offset);
+ }
+
public static IntBuffer newIntBuffer(int[] values) {
return newIntBuffer(values, 0);
}
@@ -130,14 +139,17 @@ public class BufferUtil {
return bb.asShortBuffer();
}
- public static ShortBuffer newShortBuffer(short[] values, int offset) {
- int len = values.length-offset;
+ public static ShortBuffer newShortBuffer(short[] values, int offset, int len) {
ShortBuffer bb = newShortBuffer(len);
bb.put(values, offset, len);
bb.rewind();
return bb;
}
+ public static ShortBuffer newShortBuffer(short[] values, int offset) {
+ return newShortBuffer(values, 0, values.length-offset);
+ }
+
public static ShortBuffer newShortBuffer(short[] values) {
return newShortBuffer(values, 0);
}
diff --git a/src/classes/javax/media/opengl/util/BufferUtil.java.javase b/src/classes/javax/media/opengl/util/BufferUtil.java.javase
index 944e4d8d4..6ea6fe2c7 100755
--- a/src/classes/javax/media/opengl/util/BufferUtil.java.javase
+++ b/src/classes/javax/media/opengl/util/BufferUtil.java.javase
@@ -69,14 +69,17 @@ public class BufferUtil {
return bb;
}
- public static ByteBuffer newByteBuffer(byte[] values, int offset) {
- int len = values.length-offset;
+ public static ByteBuffer newByteBuffer(byte[] values, int offset, int len) {
ByteBuffer bb = newByteBuffer(len);
bb.put(values, offset, len);
bb.rewind();
return bb;
}
+ public static ByteBuffer newByteBuffer(byte[] values, int offset) {
+ return newByteBuffer(values, offset, values.length-offset);
+ }
+
public static ByteBuffer newByteBuffer(byte[] values) {
return newByteBuffer(values, 0);
}
@@ -111,14 +114,17 @@ public class BufferUtil {
return bb.asFloatBuffer();
}
- public static FloatBuffer newFloatBuffer(float[] values, int offset) {
- int len = values.length-offset;
+ public static FloatBuffer newFloatBuffer(float[] values, int offset, int len) {
FloatBuffer bb = newFloatBuffer(len);
bb.put(values, offset, len);
bb.rewind();
return bb;
}
+ public static FloatBuffer newFloatBuffer(float[] values, int offset) {
+ return newFloatBuffer(values, 0, values.length-offset);
+ }
+
public static FloatBuffer newFloatBuffer(float[] values) {
return newFloatBuffer(values, 0);
}
@@ -132,14 +138,17 @@ public class BufferUtil {
return bb.asIntBuffer();
}
- public static IntBuffer newIntBuffer(int[] values, int offset) {
- int len = values.length-offset;
+ public static IntBuffer newIntBuffer(int[] values, int offset, int len) {
IntBuffer bb = newIntBuffer(len);
bb.put(values, offset, len);
bb.rewind();
return bb;
}
+ public static IntBuffer newIntBuffer(int[] values, int offset) {
+ return newIntBuffer(values, 0, values.length-offset);
+ }
+
public static IntBuffer newIntBuffer(int[] values) {
return newIntBuffer(values, 0);
}
@@ -160,14 +169,17 @@ public class BufferUtil {
return bb.asShortBuffer();
}
- public static ShortBuffer newShortBuffer(short[] values, int offset) {
- int len = values.length-offset;
+ public static ShortBuffer newShortBuffer(short[] values, int offset, int len) {
ShortBuffer bb = newShortBuffer(len);
bb.put(values, offset, len);
bb.rewind();
return bb;
}
+ public static ShortBuffer newShortBuffer(short[] values, int offset) {
+ return newShortBuffer(values, 0, values.length-offset);
+ }
+
public static ShortBuffer newShortBuffer(short[] values) {
return newShortBuffer(values, 0);
}
diff --git a/src/classes/javax/media/opengl/util/ImmModeSink.java b/src/classes/javax/media/opengl/util/ImmModeSink.java
index 5de9df99a..b2c2c8f2c 100644
--- a/src/classes/javax/media/opengl/util/ImmModeSink.java
+++ b/src/classes/javax/media/opengl/util/ImmModeSink.java
@@ -34,8 +34,8 @@ public class ImmModeSink {
* a ShaderState must be current, using ShaderState.glUseProgram().
*
* @see #draw(GL, boolean)
- * @see javax.media.opengl.util.glsl.ShaderState#glUseProgram(GL2ES2, boolean)
- * @see javax.media.opengl.util.glsl.ShaderState#getCurrent()
+ * @see javax.media.opengl.glsl.ShaderState#glUseProgram(GL2ES2, boolean)
+ * @see javax.media.opengl.glsl.ShaderState#getCurrent()
*/
public static ImmModeSink createGLSL(int glBufferUsage, int initialSize,
int vComps, int vDataType,