diff options
Diffstat (limited to 'src')
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 Binary files differnew file mode 100755 index 000000000..454354c12 --- /dev/null +++ b/src/classes/com/sun/opengl/impl/glsl/shader/bin/nvidia/FixedFuncColor.bfp 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 Binary files differnew file mode 100755 index 000000000..279ef72c7 --- /dev/null +++ b/src/classes/com/sun/opengl/impl/glsl/shader/bin/nvidia/FixedFuncColor.bvp 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 Binary files differnew file mode 100755 index 000000000..5a9deea71 --- /dev/null +++ b/src/classes/com/sun/opengl/impl/glsl/shader/bin/nvidia/FixedFuncColorLight.bvp 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 Binary files differnew file mode 100755 index 000000000..375ea6293 --- /dev/null +++ b/src/classes/com/sun/opengl/impl/glsl/shader/bin/nvidia/FixedFuncColorTexture.bfp 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, |