aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rwxr-xr-xsrc/classes/com/sun/opengl/impl/ProjectFloat.java26
-rw-r--r--src/classes/com/sun/opengl/impl/es2/FixedFuncShader.java253
-rw-r--r--src/classes/com/sun/opengl/impl/es2/FixedFuncShaderVertexColor.java57
-rw-r--r--src/classes/com/sun/opengl/impl/es2/FixedFuncShaderVertexColorTexture.java67
-rw-r--r--src/classes/com/sun/opengl/impl/es2/ShaderData.java60
-rw-r--r--src/classes/com/sun/opengl/impl/es2/VBOBufferDrawGLES2.java70
-rw-r--r--src/classes/com/sun/opengl/impl/gl2es1/VBOBufferDrawGL2ES1.java70
-rw-r--r--src/classes/com/sun/opengl/impl/glsl/FixedFuncPipeline.java468
-rw-r--r--src/classes/com/sun/opengl/impl/glsl/FixedFuncShaderFragmentColor.java27
-rw-r--r--src/classes/com/sun/opengl/impl/glsl/FixedFuncShaderFragmentColorTexture.java39
-rw-r--r--src/classes/com/sun/opengl/impl/glsl/FixedFuncShaderVertexColor.java65
-rw-r--r--src/classes/com/sun/opengl/impl/glsl/FixedFuncShaderVertexColorLight.java136
-rw-r--r--src/classes/com/sun/opengl/impl/glsl/GLSLArrayDataServer.java58
-rw-r--r--src/classes/com/sun/opengl/impl/glu/GLUquadricImpl.java128
-rw-r--r--src/classes/javax/media/opengl/GLArrayData.java153
-rw-r--r--src/classes/javax/media/opengl/GLArrayDataClient.java498
-rw-r--r--src/classes/javax/media/opengl/GLArrayDataServer.java265
-rw-r--r--src/classes/javax/media/opengl/GLContext.java59
-rw-r--r--src/classes/javax/media/opengl/GLProfile.java302
-rw-r--r--src/classes/javax/media/opengl/GLUniformData.java159
-rw-r--r--src/classes/javax/media/opengl/util/ImmModeSink.java455
-rwxr-xr-xsrc/classes/javax/media/opengl/util/PMVMatrix.java283
-rw-r--r--src/classes/javax/media/opengl/util/VBOBufferDraw.java392
-rw-r--r--src/classes/javax/media/opengl/util/glsl/ShaderCode.java122
-rw-r--r--src/classes/javax/media/opengl/util/glsl/ShaderProgram.java201
-rw-r--r--src/classes/javax/media/opengl/util/glsl/ShaderState.java583
26 files changed, 3781 insertions, 1215 deletions
diff --git a/src/classes/com/sun/opengl/impl/ProjectFloat.java b/src/classes/com/sun/opengl/impl/ProjectFloat.java
index 637377237..309a6bdaf 100755
--- a/src/classes/com/sun/opengl/impl/ProjectFloat.java
+++ b/src/classes/com/sun/opengl/impl/ProjectFloat.java
@@ -153,8 +153,8 @@ public class ProjectFloat {
// Array-based implementation
private final float[] matrix = new float[16];
+ private final float[][] tempInvertMatrix = new float[4][4];
- private final float[][] tempMatrix = new float[4][4];
private final float[] in = new float[4];
private final float[] out = new float[4];
@@ -164,8 +164,8 @@ public class ProjectFloat {
// Buffer-based implementation
private final FloatBuffer matrixBuf;
+ private final FloatBuffer tempInvertMatrixBuf;
- private final FloatBuffer tempMatrixBuf;
private final FloatBuffer inBuf;
private final FloatBuffer outBuf;
@@ -179,12 +179,12 @@ public class ProjectFloat {
// Slice up one big buffer because some NIO implementations
// allocate a huge amount of memory to back even the smallest of
// buffers.
- FloatBuffer buf = BufferUtil.newFloatBuffer(128);
+ FloatBuffer buf = BufferUtil.newFloatBuffer(2*16+2*4+3*3);
int pos = 0;
int sz = 16;
matrixBuf = slice(buf, pos, sz);
pos += sz;
- tempMatrixBuf = slice(buf, pos, sz);
+ tempInvertMatrixBuf = slice(buf, pos, sz);
pos += sz;
sz = 4;
inBuf = slice(buf, pos, sz);
@@ -226,7 +226,7 @@ public class ProjectFloat {
/**
* Make matrix an identity matrix
*/
- private void gluMakeIdentityf(float[] m) {
+ public static void gluMakeIdentityf(float[] m) {
for (int i = 0; i < 16; i++) {
m[i] = IDENTITY_MATRIX[i];
}
@@ -275,10 +275,10 @@ public class ProjectFloat {
*
* @return
*/
- private boolean __gluInvertMatrixf(float[] src, float[] inverse) {
+ public boolean gluInvertMatrixf(float[] src, float[] inverse) {
int i, j, k, swap;
float t;
- float[][] temp = tempMatrix;
+ float[][] temp = tempInvertMatrix;
for (i = 0; i < 4; i++) {
for (j = 0; j < 4; j++) {
@@ -345,14 +345,14 @@ public class ProjectFloat {
*
* @return
*/
- private boolean __gluInvertMatrixf(FloatBuffer src, FloatBuffer inverse) {
+ public boolean gluInvertMatrixf(FloatBuffer src, FloatBuffer inverse) {
int i, j, k, swap;
float t;
int srcPos = src.position();
int invPos = inverse.position();
- FloatBuffer temp = tempMatrixBuf;
+ FloatBuffer temp = tempInvertMatrixBuf;
for (i = 0; i < 4; i++) {
for (j = 0; j < 4; j++) {
@@ -772,7 +772,7 @@ public class ProjectFloat {
gluMultMatricesf(modelMatrix, modelMatrix_offset, projMatrix, projMatrix_offset, matrix);
- if (!__gluInvertMatrixf(matrix, matrix))
+ if (!gluInvertMatrixf(matrix, matrix))
return false;
in[0] = winx;
@@ -829,7 +829,7 @@ public class ProjectFloat {
gluMultMatricesf(modelMatrix, projMatrix, matrixBuf);
- if (!__gluInvertMatrixf(matrixBuf, matrixBuf))
+ if (!gluInvertMatrixf(matrixBuf, matrixBuf))
return false;
in.put(0, winx);
@@ -898,7 +898,7 @@ public class ProjectFloat {
gluMultMatricesf(modelMatrix, modelMatrix_offset, projMatrix, projMatrix_offset, matrix);
- if (!__gluInvertMatrixf(matrix, matrix))
+ if (!gluInvertMatrixf(matrix, matrix))
return false;
in[0] = winx;
@@ -959,7 +959,7 @@ public class ProjectFloat {
gluMultMatricesf(modelMatrix, projMatrix, matrixBuf);
- if (!__gluInvertMatrixf(matrixBuf, matrixBuf))
+ if (!gluInvertMatrixf(matrixBuf, matrixBuf))
return false;
in.put(0, winx);
diff --git a/src/classes/com/sun/opengl/impl/es2/FixedFuncShader.java b/src/classes/com/sun/opengl/impl/es2/FixedFuncShader.java
deleted file mode 100644
index f6bf964a7..000000000
--- a/src/classes/com/sun/opengl/impl/es2/FixedFuncShader.java
+++ /dev/null
@@ -1,253 +0,0 @@
-
-package com.sun.opengl.impl.es2;
-
-import javax.media.opengl.util.*;
-import javax.media.opengl.*;
-import java.nio.*;
-
-public class FixedFuncShader {
- public FixedFuncShader(GL2ES2 gl, PMVMatrix pmvMatrix, ShaderData shaderData) {
- init(gl, pmvMatrix, shaderData);
- }
-
- public boolean isShaderDataValid() {
- return shaderData.isValid();
- }
- public boolean isValid() {
- return shaderData.isValid() && shaderOk;
- }
-
- public void glUseProgram(GL2ES2 gl, boolean on) {
- if(shaderInUse==on) return;
- if(!shaderOk) return;
- gl.glUseProgram(on?shaderProgram:0);
- shaderInUse = on;
- }
-
- public void release(GL2ES2 gl) {
- glUseProgram(gl, false);
- gl.glDetachShader(shaderProgram, shaderData.vertexShader());
- gl.glDetachShader(shaderProgram, shaderData.fragmentShader());
- gl.glDeleteProgram(shaderProgram);
- }
-
- public void syncUniforms(GL2ES2 gl) {
- if(!shaderOk) return;
- if(pmvMatrix.isDirty()) {
- glUseProgram(gl, true);
- gl.glUniformMatrix4fv(shaderPMVMatrix, 2, false, pmvMatrix.glGetPMVMatrixf());
- pmvMatrix.clear();
- }
- }
-
- public int glArrayName2AttribName(int glName) {
- switch(glName) {
- case GL.GL_VERTEX_ARRAY:
- return VERTEX_ARRAY;
- case GL.GL_COLOR_ARRAY:
- return COLOR_ARRAY;
- case GL.GL_NORMAL_ARRAY:
- return NORMAL_ARRAY;
- case GL.GL_TEXTURE_COORD_ARRAY:
- return TEXCOORD_ARRAY;
- }
- return -1;
- }
-
- public void glEnableClientState(GL2ES2 gl, int glArrayName) {
- if(!shaderOk) return;
- int attribName = glArrayName2AttribName(glArrayName);
- if(attribName>=0) {
- glUseProgram(gl, true);
- arrayInUse |= (1<<attribName);
- gl.glEnableVertexAttribArray(attribName);
- }
- }
-
- public void glDisableClientState(GL2ES2 gl, int glArrayName) {
- if(!shaderOk) return;
- int attribName = glArrayName2AttribName(glArrayName);
- if(attribName>=0) {
- glUseProgram(gl, true);
- gl.glDisableVertexAttribArray(attribName);
- arrayInUse &= ~(1<<attribName);
- if(0==arrayInUse) {
- glUseProgram(gl, false);
- }
- }
- }
-
- public void glVertexPointer(GL2ES2 gl, int size, int type, int stride, Buffer data ) {
- if(!shaderOk) return;
- glUseProgram(gl, true);
- gl.glVertexAttribPointer(VERTEX_ARRAY, size, type, false, stride, data);
- }
-
- public void glVertexPointer(GL2ES2 gl, int size, int type, int stride, long offset ) {
- if(!shaderOk) return;
- glUseProgram(gl, true);
- gl.glVertexAttribPointer(VERTEX_ARRAY, size, type, false, stride, offset);
- }
-
- public void glColorPointer(GL2ES2 gl, int size, int type, int stride, Buffer data ) {
- if(!shaderOk) return;
- glUseProgram(gl, true);
- gl.glVertexAttribPointer(COLOR_ARRAY, size, type, false, stride, data);
- }
-
- public void glColorPointer(GL2ES2 gl, int size, int type, int stride, long offset ) {
- if(!shaderOk) return;
- glUseProgram(gl, true);
- gl.glVertexAttribPointer(COLOR_ARRAY, size, type, false, stride, offset);
- }
-
- public void glColor4fv(GL2ES2 gl, FloatBuffer data ) {
- glColorPointer(gl, 4, gl.GL_FLOAT, 0, data);
- }
-
- public void glNormalPointer(GL2ES2 gl, int type, int stride, Buffer data ) {
- if(!shaderOk) return;
- glUseProgram(gl, true);
- gl.glVertexAttribPointer(NORMAL_ARRAY, 3, type, false, stride, data);
- }
-
- public void glNormalPointer(GL2ES2 gl, int type, int stride, long offset ) {
- if(!shaderOk) return;
- glUseProgram(gl, true);
- gl.glVertexAttribPointer(NORMAL_ARRAY, 3, type, false, stride, offset);
- }
-
- public void glTexCoordPointer(GL2ES2 gl, int size, int type, int stride, Buffer data ) {
- if(!shaderOk) return;
- glUseProgram(gl, true);
- gl.glVertexAttribPointer(TEXCOORD_ARRAY, size, type, false, stride, data);
- }
-
- public void glTexCoordPointer(GL2ES2 gl, int size, int type, int stride, long offset ) {
- if(!shaderOk) return;
- glUseProgram(gl, true);
- gl.glVertexAttribPointer(TEXCOORD_ARRAY, size, type, false, stride, offset);
- }
-
- public void setVertexAttribPointer(GL2ES2 gl, int glArrayName, int size, int type, int stride, Buffer data ) {
- int attribName = glArrayName2AttribName(glArrayName);
- if(!shaderOk || attribName<0) return;
- glUseProgram(gl, true);
- gl.glEnableVertexAttribArray(attribName);
- gl.glVertexAttribPointer(attribName, size, type, false, stride, data);
- }
-
- public void setVertexAttribPointer(GL2ES2 gl, int glArrayName, int size, int type, int stride, long offset ) {
- int attribName = glArrayName2AttribName(glArrayName);
- if(!shaderOk || attribName<0) return;
- glUseProgram(gl, true);
- gl.glEnableVertexAttribArray(attribName);
- gl.glVertexAttribPointer(attribName, size, type, false, stride, offset);
- }
-
- public void glLightfv(GL2ES2 gl, int light, int pname, java.nio.FloatBuffer params) {
- if(!shaderOk) return;
- light -=GL.GL_LIGHT0;
- if(0 <= light && light <= 7) {
- if(gl.GL_POSITION==pname && 0<=shaderLightsSource[light]) {
- glUseProgram(gl, true);
- gl.glUniform4fv(shaderLightsSource[light], 1, params);
- } else if(gl.GL_AMBIENT==pname && 0<=shaderLigthsAmbient[light]) {
- gl.glUniform4fv(shaderLigthsAmbient[light], 1, params);
- }
- }
- }
-
- public void glShadeModel(GL2ES2 gl, int mode) {
- if(!shaderOk || 0>shaderShadeModel) return;
- glUseProgram(gl, true);
- gl.glUniform1i(shaderShadeModel, mode);
- }
-
- public void glActiveTexture(GL2ES2 gl, int texture) {
- if(!shaderOk || 0>shaderShadeModel) return;
- glUseProgram(gl, true);
- texture-=gl.GL_TEXTURE0;
- gl.glUniform1i(shaderActiveTexture, 0);
- }
-
- protected void init(GL2ES2 gl, PMVMatrix pmvMatrix, ShaderData shaderData) {
- if(shaderOk) return;
-
- if(null==pmvMatrix) {
- throw new GLException("PMVMatrix is null");
- }
- this.pmvMatrix=pmvMatrix;
- this.shaderData=shaderData;
-
- if(!shaderData.createAndCompile(gl)) {
- return;
- }
-
- // Create the shader program
- shaderProgram = gl.glCreateProgram();
-
- // Attach the fragment and vertex shaders to it
- gl.glAttachShader(shaderProgram, shaderData.vertexShader());
- gl.glAttachShader(shaderProgram, shaderData.fragmentShader());
-
- gl.glBindAttribLocation(shaderProgram, VERTEX_ARRAY, "mgl_Vertex");
- gl.glBindAttribLocation(shaderProgram, COLOR_ARRAY, "mgl_Color");
- gl.glBindAttribLocation(shaderProgram, TEXCOORD_ARRAY, "mgl_MultiTexCoord0");
-
- // Link the program
- gl.glLinkProgram(shaderProgram);
-
- if ( ! gl.glIsProgramValid(shaderProgram, System.err) ) {
- return;
- }
-
- gl.glUseProgram(shaderProgram);
-
- shaderPMVMatrix = gl.glGetUniformLocation(shaderProgram, "mgl_PMVMatrix");
- if(0<=shaderPMVMatrix) {
- gl.glUniformMatrix4fv(shaderPMVMatrix, 2, false, pmvMatrix.glGetPMVMatrixf());
- pmvMatrix.clear();
- shaderOk = true;
- } else {
- System.err.println("could not get uniform mgl_PMVMatrix: "+shaderPMVMatrix);
- }
-
- // optional parameter ..
- for(int i=0; i<7; i++) {
- shaderLightsSource[i] = gl.glGetUniformLocation(shaderProgram, "mgl_LightSource"+i);
- shaderLigthsAmbient[i] = gl.glGetUniformLocation(shaderProgram, "mgl_LightAmbient"+i);
- }
- shaderShadeModel = gl.glGetUniformLocation(shaderProgram, "mgl_ShadeModel");
-
- shaderActiveTexture = gl.glGetUniformLocation(shaderProgram, "mgl_ActiveTexture");
- if(0<=shaderActiveTexture) {
- gl.glUniform1i(shaderActiveTexture, 0);
- }
-
- gl.glUseProgram(0);
- shaderInUse = false;
- }
-
- protected PMVMatrix pmvMatrix;
- protected ShaderData shaderData;
-
- protected boolean shaderOk = false;
- protected boolean shaderInUse = false;
- protected int arrayInUse = 0;
- protected int shaderProgram=-1;
-
- // attributes
- protected static final int VERTEX_ARRAY = 0; // mgl_Vertex
- protected static final int COLOR_ARRAY = 1; // mgl_Color
- protected static final int NORMAL_ARRAY = 2; // ?
- protected static final int TEXCOORD_ARRAY = 3; // mgl_MultiTexCoord0
-
- // uniforms ..
- protected int shaderPMVMatrix=-1; // mgl_PMVMatrix mat4
- protected int[] shaderLightsSource = new int[] { -1, -1, -1, -1, -1, -1, -1 }; // vec4f mgl_LightSourcei
- protected int[] shaderLigthsAmbient = new int[] { -1, -1, -1, -1, -1, -1, -1 }; // vec4f mgl_LightAmbienti
- protected int shaderShadeModel = -1; // mgl_ShadeModel int
- protected int shaderActiveTexture = -1; // mgl_ActiveTexture int
-}
-
diff --git a/src/classes/com/sun/opengl/impl/es2/FixedFuncShaderVertexColor.java b/src/classes/com/sun/opengl/impl/es2/FixedFuncShaderVertexColor.java
deleted file mode 100644
index e3900d0b4..000000000
--- a/src/classes/com/sun/opengl/impl/es2/FixedFuncShaderVertexColor.java
+++ /dev/null
@@ -1,57 +0,0 @@
-
-package com.sun.opengl.impl.es2;
-
-import javax.media.opengl.util.*;
-import javax.media.opengl.*;
-import java.nio.*;
-
-public class FixedFuncShaderVertexColor extends ShaderData {
-
- public static final String[][] vertShaderSource = new String[][] { {
- "#ifdef GL_ES\n"+
- " #define MEDIUMP mediump\n"+
- " #define HIGHP highp\n"+
- "#else\n"+
- " #define MEDIUMP\n"+
- " #define HIGHP\n"+
- "#endif\n"+
- "\n"+
- "uniform MEDIUMP mat4 mgl_PMVMatrix[2];\n"+
- "attribute HIGHP vec4 mgl_Vertex;\n"+
- "attribute HIGHP vec4 mgl_Color;\n"+
- "varying HIGHP vec4 frontColor;\n"+
- "void main(void)\n"+
- "{\n"+
- " frontColor=mgl_Color;\n"+
- " gl_Position = mgl_PMVMatrix[0] * mgl_PMVMatrix[1] * mgl_Vertex;\n"+
- "}\n" } } ;
-
- public static final String[][] fragShaderSource = new String[][] { {
- "#ifdef GL_ES\n"+
- " #define MEDIUMP mediump\n"+
- " #define HIGHP highp\n"+
- "#else\n"+
- " #define MEDIUMP\n"+
- " #define HIGHP\n"+
- "#endif\n"+
- "\n"+
- "varying HIGHP vec4 frontColor;\n"+
- "void main (void)\n"+
- "{\n"+
- " gl_FragColor = frontColor;\n"+
- "}\n" } } ;
-
-
- public FixedFuncShaderVertexColor() {
- super(1, 1);
- }
-
- public int vertexShaderBinaryFormat() { return 0; }
- public Buffer vertexShaderBinary() { return null; }
- public String[][] vertexShaderSource() { return vertShaderSource; }
-
- public int fragmentShaderBinaryFormat() { return 0; }
- public Buffer fragmentShaderBinary() { return null; }
- public String[][] fragmentShaderSource() { return fragShaderSource; }
-}
-
diff --git a/src/classes/com/sun/opengl/impl/es2/FixedFuncShaderVertexColorTexture.java b/src/classes/com/sun/opengl/impl/es2/FixedFuncShaderVertexColorTexture.java
deleted file mode 100644
index 2c33c9c07..000000000
--- a/src/classes/com/sun/opengl/impl/es2/FixedFuncShaderVertexColorTexture.java
+++ /dev/null
@@ -1,67 +0,0 @@
-
-package com.sun.opengl.impl.es2;
-
-import javax.media.opengl.util.*;
-import javax.media.opengl.*;
-import java.nio.*;
-
-public class FixedFuncShaderVertexColorTexture extends ShaderData {
-
- public static final String[][] vertShaderSource = new String[][] { {
- "#ifdef GL_ES\n"+
- " #define MEDIUMP mediump\n"+
- " #define HIGHP highp\n"+
- "#else\n"+
- " #define MEDIUMP\n"+
- " #define HIGHP\n"+
- "#endif\n"+
- "\n"+
- "uniform MEDIUMP mat4 mgl_PMVMatrix[2];\n"+
- "attribute HIGHP vec4 mgl_Vertex;\n"+
- "attribute HIGHP vec4 mgl_Color;\n"+
- "attribute HIGHP vec4 mgl_MultiTexCoord0;\n"+
- "varying HIGHP vec4 gl_TexCoord[7];\n"+
- "varying HIGHP vec4 frontColor;\n"+
- "void main(void)\n"+
- "{\n"+
- " frontColor=mgl_Color;\n"+
- " gl_TexCoord[0] = mgl_MultiTexCoord0;\n"+
- " gl_Position = mgl_PMVMatrix[0] * mgl_PMVMatrix[1] * mgl_Vertex;\n"+
- "}\n" } } ;
-
- public static final String[][] fragShaderSource = new String[][] { {
- "#ifdef GL_ES\n"+
- " #define MEDIUMP mediump\n"+
- " #define HIGHP highp\n"+
- "#else\n"+
- " #define MEDIUMP\n"+
- " #define HIGHP\n"+
- "#endif\n"+
- "\n"+
- "uniform HIGHP sampler2D mgl_ActiveTexture;\n"+
- "varying HIGHP vec4 frontColor;\n"+
- "const HIGHP vec4 one = vec4(1.0, 1.0, 1.0, 1.0);\n"+
- "const HIGHP vec4 zero = vec4(0.0, 0.0, 0.0, 0.0);\n"+
- "void main (void)\n"+
- "{\n"+
- " vec4 texColor = texture2D(mgl_ActiveTexture,gl_TexCoord[0].st);\n"+
- " if(greaterThan(texColor, zero)) {\n"+
- " gl_FragColor = vec4(frontColor.rgb*texColor.rgb, frontColor.a*texColor.a);\n"+
- " } else {\n"+
- " gl_FragColor = frontColor;\n"+
- " }\n"+
- "}\n" } } ;
-
- public FixedFuncShaderVertexColorTexture() {
- super(1, 1);
- }
-
- public int vertexShaderBinaryFormat() { return 0; }
- public Buffer vertexShaderBinary() { return null; }
- public String[][] vertexShaderSource() { return vertShaderSource; }
-
- public int fragmentShaderBinaryFormat() { return 0; }
- public Buffer fragmentShaderBinary() { return null; }
- public String[][] fragmentShaderSource() { return fragShaderSource; }
-}
-
diff --git a/src/classes/com/sun/opengl/impl/es2/ShaderData.java b/src/classes/com/sun/opengl/impl/es2/ShaderData.java
deleted file mode 100644
index 3a3c17811..000000000
--- a/src/classes/com/sun/opengl/impl/es2/ShaderData.java
+++ /dev/null
@@ -1,60 +0,0 @@
-
-package com.sun.opengl.impl.es2;
-
-import javax.media.opengl.util.*;
-import javax.media.opengl.*;
-import java.nio.*;
-
-public abstract class ShaderData {
- public abstract int vertexShaderBinaryFormat();
- public abstract Buffer vertexShaderBinary();
- public abstract String[][] vertexShaderSource();
-
- public abstract int fragmentShaderBinaryFormat();
- public abstract Buffer fragmentShaderBinary();
- public abstract String[][] fragmentShaderSource();
-
- public boolean isValid() { return valid; }
- public void setValid(boolean val) { valid=val; }
-
- public ShaderData(int numVertexShader, int numFragmentShader) {
- vertShader = BufferUtil.newIntBuffer(numVertexShader);
- fragShader = BufferUtil.newIntBuffer(numFragmentShader);
- }
-
- public IntBuffer vertexShader() { return vertShader; }
- public IntBuffer fragmentShader() { return fragShader; }
-
- public boolean createAndCompile(GL2ES2 gl) {
- if(isValid()) return true;
- boolean res;
-
- // Create & Compile the vertex/fragment shader objects
- res=gl.glCreateCompileShader(vertexShader(), gl.GL_VERTEX_SHADER,
- vertexShaderBinaryFormat(), vertexShaderBinary(),
- vertexShaderSource(), System.err);
- if(!res) return false;
-
- res=gl.glCreateCompileShader(fragmentShader(), gl.GL_FRAGMENT_SHADER,
- fragmentShaderBinaryFormat(), fragmentShaderBinary(),
- fragmentShaderSource(), System.err);
- if(!res) return false;
-
- setValid(true);
- return true;
- }
-
- public void release(GL2ES2 gl) {
- if(isValid()) {
- gl.glDeleteShader(fragmentShader());
- gl.glDeleteShader(vertexShader());
- setValid(false);
- }
- }
-
- protected IntBuffer vertShader = null;
- protected IntBuffer fragShader = null;
-
- protected boolean valid=false;
-}
-
diff --git a/src/classes/com/sun/opengl/impl/es2/VBOBufferDrawGLES2.java b/src/classes/com/sun/opengl/impl/es2/VBOBufferDrawGLES2.java
deleted file mode 100644
index 30cf7e327..000000000
--- a/src/classes/com/sun/opengl/impl/es2/VBOBufferDrawGLES2.java
+++ /dev/null
@@ -1,70 +0,0 @@
-
-package com.sun.opengl.impl.es2;
-
-import javax.media.opengl.util.VBOBufferDraw;
-import javax.media.opengl.*;
-import java.nio.*;
-
-public class VBOBufferDrawGLES2 extends VBOBufferDraw {
-
- public VBOBufferDrawGLES2(int glArrayType, int glDataType, int glBufferUsage, int comps, int initialSize) {
- init(glArrayType, glDataType, glBufferUsage, comps, initialSize);
- setVBOUsage(false);
- //System.err.println("new VBOBufferDrawGLES2: "+this);
- }
-
- protected void enableBufferGLImpl(GL gl, boolean newData) {
- if(!bufferEnabled && null!=buffer) {
- gl.glEnableClientState(glArrayType);
- if(vboUsage) {
- gl.glBindBuffer(GL.GL_ARRAY_BUFFER, vboName);
- if(newData) {
- gl.glBufferData(GL.GL_ARRAY_BUFFER, buffer.limit() * getBufferCompSize(), buffer, glBufferUsage);
- }
- switch(glArrayType) {
- case GL.GL_VERTEX_ARRAY:
- gl.glVertexPointer(components, glDataType, 0, 0);
- break;
- case GL.GL_NORMAL_ARRAY:
- gl.glNormalPointer(glDataType, 0, 0);
- break;
- case GL.GL_COLOR_ARRAY:
- gl.glColorPointer(components, glDataType, 0, 0);
- break;
- case GL.GL_TEXTURE_COORD_ARRAY:
- gl.glTexCoordPointer(components, glDataType, 0, 0);
- break;
- default:
- throw new GLException("invalid glArrayType: "+glArrayType+":\n\t"+this);
- }
- } else {
- switch(glArrayType) {
- case GL.GL_VERTEX_ARRAY:
- gl.glVertexPointer(components, glDataType, 0, buffer);
- break;
- case GL.GL_NORMAL_ARRAY:
- gl.glNormalPointer(glDataType, 0, buffer);
- break;
- case GL.GL_COLOR_ARRAY:
- gl.glColorPointer(components, glDataType, 0, buffer);
- break;
- case GL.GL_TEXTURE_COORD_ARRAY:
- gl.glTexCoordPointer(components, glDataType, 0, buffer);
- break;
- default:
- throw new GLException("invalid glArrayType: "+glArrayType+":\n\t"+this);
- }
- }
- bufferEnabled = true;
- }
- }
-
- protected void disableBufferGLImpl(GL gl) {
- if(bufferEnabled && null!=buffer) {
- gl.glDisableClientState(glArrayType);
- bufferEnabled = false;
- }
- }
-
-}
-
diff --git a/src/classes/com/sun/opengl/impl/gl2es1/VBOBufferDrawGL2ES1.java b/src/classes/com/sun/opengl/impl/gl2es1/VBOBufferDrawGL2ES1.java
deleted file mode 100644
index 5897b9a79..000000000
--- a/src/classes/com/sun/opengl/impl/gl2es1/VBOBufferDrawGL2ES1.java
+++ /dev/null
@@ -1,70 +0,0 @@
-
-package com.sun.opengl.impl.gl2es1;
-
-import javax.media.opengl.util.VBOBufferDraw;
-import javax.media.opengl.*;
-import java.nio.*;
-
-public class VBOBufferDrawGL2ES1 extends VBOBufferDraw {
-
- public VBOBufferDrawGL2ES1(int glArrayType, int glDataType, int glBufferUsage, int comps, int initialSize) {
- init(glArrayType, glDataType, glBufferUsage, comps, initialSize);
- setVBOUsage(false);
- //System.err.println("new VBOBufferDrawGL2ES1: "+this);
- }
-
- protected void enableBufferGLImpl(GL gl, boolean newData) {
- if(!bufferEnabled && null!=buffer) {
- gl.glEnableClientState(glArrayType);
- if(vboUsage) {
- gl.glBindBuffer(GL.GL_ARRAY_BUFFER, vboName);
- if(newData) {
- gl.glBufferData(GL.GL_ARRAY_BUFFER, buffer.limit() * getBufferCompSize(), buffer, glBufferUsage);
- }
- switch(glArrayType) {
- case GL.GL_VERTEX_ARRAY:
- gl.glVertexPointer(components, glDataType, 0, 0);
- break;
- case GL.GL_NORMAL_ARRAY:
- gl.glNormalPointer(glDataType, 0, 0);
- break;
- case GL.GL_COLOR_ARRAY:
- gl.glColorPointer(components, glDataType, 0, 0);
- break;
- case GL.GL_TEXTURE_COORD_ARRAY:
- gl.glTexCoordPointer(components, glDataType, 0, 0);
- break;
- default:
- throw new GLException("invalid glArrayType: "+glArrayType+":\n\t"+this);
- }
- } else {
- switch(glArrayType) {
- case GL.GL_VERTEX_ARRAY:
- gl.glVertexPointer(components, glDataType, 0, buffer);
- break;
- case GL.GL_NORMAL_ARRAY:
- gl.glNormalPointer(glDataType, 0, buffer);
- break;
- case GL.GL_COLOR_ARRAY:
- gl.glColorPointer(components, glDataType, 0, buffer);
- break;
- case GL.GL_TEXTURE_COORD_ARRAY:
- gl.glTexCoordPointer(components, glDataType, 0, buffer);
- break;
- default:
- throw new GLException("invalid glArrayType: "+glArrayType+":\n\t"+this);
- }
- }
- bufferEnabled = true;
- }
- }
-
- protected void disableBufferGLImpl(GL gl) {
- if(bufferEnabled && null!=buffer) {
- gl.glDisableClientState(glArrayType);
- bufferEnabled = false;
- }
- }
-
-}
-
diff --git a/src/classes/com/sun/opengl/impl/glsl/FixedFuncPipeline.java b/src/classes/com/sun/opengl/impl/glsl/FixedFuncPipeline.java
new file mode 100644
index 000000000..e8cf58b42
--- /dev/null
+++ b/src/classes/com/sun/opengl/impl/glsl/FixedFuncPipeline.java
@@ -0,0 +1,468 @@
+
+package com.sun.opengl.impl.es2;
+
+import javax.media.opengl.*;
+import javax.media.opengl.util.*;
+import javax.media.opengl.util.glsl.*;
+import java.nio.*;
+
+public class FixedFuncPipeline {
+ public static final int MAX_TEXTURE_UNITS = 8;
+ public static final int MAX_LIGHTS = 8;
+
+ public FixedFuncPipeline(GL2ES2 gl, PMVMatrix pmvMatrix) {
+ init(gl, pmvMatrix);
+ }
+
+ public boolean verbose() { return verbose; }
+
+ public void setVerbose(boolean v) { verbose=v; }
+
+ public boolean isValid() {
+ return shaderState.linked();
+ }
+
+ public ShaderState getShaderState() {
+ return shaderState;
+ }
+
+ public void enableLighting(boolean enable) {
+ lightingEnabled=enable;
+ }
+
+ public boolean lightingEnabled() {
+ return lightingEnabled;
+ }
+
+ public int getActiveTextureUnit() {
+ return activeTextureUnit;
+ }
+
+ public String getArrayIndexName(int glArrayIndex) {
+ String name = GLContext.getPredefinedArrayIndexName(glArrayIndex);
+ switch(glArrayIndex) {
+ case GL.GL_VERTEX_ARRAY:
+ case GL.GL_NORMAL_ARRAY:
+ case GL.GL_COLOR_ARRAY:
+ break;
+ case GL.GL_TEXTURE_COORD_ARRAY:
+ name = name + activeTextureUnit;
+ }
+ return name;
+ }
+
+ public void release(GL2ES2 gl) {
+ shaderState.release(gl);
+ shaderProgramColor.release(gl, true);
+ shaderProgramColorLight.release(gl, true);
+ shaderProgramColorTexture.release(gl, true);
+ shaderProgramColorTextureLight.release(gl, true);
+ }
+
+ public void glEnableClientState(GL2ES2 gl, int glArrayIndex) {
+ shaderState.glUseProgram(gl, true);
+
+ shaderState.glEnableVertexAttribArray(gl, getArrayIndexName(glArrayIndex));
+ textureCoordsEnabled |= (1 << activeTextureUnit);
+ }
+
+ public void glDisableClientState(GL2ES2 gl, int glArrayIndex) {
+ shaderState.glUseProgram(gl, true);
+
+ shaderState.glDisableVertexAttribArray(gl, getArrayIndexName(glArrayIndex));
+ textureCoordsEnabled &= ~(1 << activeTextureUnit);
+ }
+
+ public void glVertexPointer(GL2ES2 gl, GLArrayData data) {
+ shaderState.glUseProgram(gl, true);
+ shaderState.glVertexAttribPointer(gl, data);
+ }
+
+ public void glColorPointer(GL2ES2 gl, GLArrayData data) {
+ shaderState.glUseProgram(gl, true);
+ shaderState.glVertexAttribPointer(gl, data);
+ }
+
+ public void glColor4fv(GL2ES2 gl, FloatBuffer data ) {
+ shaderState.glUseProgram(gl, true);
+ GLUniformData ud = shaderState.getUniform(mgl_ColorStatic);
+ if(null!=ud) {
+ ud.setData(data);
+ shaderState.glUniform(gl, ud);
+ }
+ }
+
+ public void glNormalPointer(GL2ES2 gl, GLArrayData data) {
+ shaderState.glUseProgram(gl, true);
+ shaderState.glVertexAttribPointer(gl, data);
+ }
+
+ public void glTexCoordPointer(GL2ES2 gl, GLArrayData data) {
+ shaderState.glUseProgram(gl, true);
+ data.setName( getArrayIndexName(data.getIndex()) );
+ shaderState.glVertexAttribPointer(gl, data);
+ }
+
+ public void glLightfv(GL2ES2 gl, int light, int pname, java.nio.FloatBuffer params) {
+ shaderState.glUseProgram(gl, true);
+ light -=GL.GL_LIGHT0;
+ if(0 <= light && light < MAX_LIGHTS) {
+ GLUniformData ud = null;
+ switch(pname) {
+ case GL.GL_AMBIENT:
+ ud = shaderState.getUniform(mgl_LightSource+"["+light+"].ambient");
+ break;
+ case GL.GL_DIFFUSE:
+ ud = shaderState.getUniform(mgl_LightSource+"["+light+"].diffuse");
+ break;
+ case GL.GL_SPECULAR:
+ ud = shaderState.getUniform(mgl_LightSource+"["+light+"].specular");
+ break;
+ case GL.GL_POSITION:
+ ud = shaderState.getUniform(mgl_LightSource+"["+light+"].position");
+ break;
+ case GL.GL_SPOT_DIRECTION:
+ ud = shaderState.getUniform(mgl_LightSource+"["+light+"].spotDirection");
+ break;
+ case GL.GL_SPOT_EXPONENT:
+ ud = shaderState.getUniform(mgl_LightSource+"["+light+"].spotExponent");
+ break;
+ case GL.GL_SPOT_CUTOFF:
+ ud = shaderState.getUniform(mgl_LightSource+"["+light+"].spotCutoff");
+ break;
+ case GL.GL_CONSTANT_ATTENUATION:
+ ud = shaderState.getUniform(mgl_LightSource+"["+light+"].constantAttenuation");
+ break;
+ case GL.GL_LINEAR_ATTENUATION:
+ ud = shaderState.getUniform(mgl_LightSource+"["+light+"].linearAttenuation");
+ break;
+ case GL.GL_QUADRATIC_ATTENUATION:
+ ud = shaderState.getUniform(mgl_LightSource+"["+light+"].quadraticAttenuation");
+ break;
+ default:
+ if(verbose) {
+ System.err.println("glLightfv pname not within [GL_AMBIENT GL_DIFFUSE GL_SPECULAR GL_POSITION GL_SPOT_DIRECTION]: "+pname);
+ }
+ return;
+ }
+ if(null!=ud) {
+ ud.setData(params);
+ shaderState.glUniform(gl, ud);
+ }
+ } else if(verbose) {
+ System.err.println("glLightfv light not within [0.."+MAX_LIGHTS+"]: "+light);
+ }
+ }
+
+ public void glMaterialfv(GL2ES2 gl, int face, int pname, java.nio.FloatBuffer params) {
+ shaderState.glUseProgram(gl, true);
+
+ switch (face) {
+ case GL.GL_FRONT:
+ case GL.GL_FRONT_AND_BACK:
+ break;
+ case GL.GL_BACK:
+ if(verbose) {
+ System.err.println("glMaterialfv face GL_BACK currently not supported");
+ }
+ break;
+ default:
+ }
+
+ GLUniformData ud = null;
+ switch(pname) {
+ case GL.GL_AMBIENT:
+ ud = shaderState.getUniform(mgl_FrontMaterial+".ambient");
+ break;
+ case GL.GL_AMBIENT_AND_DIFFUSE:
+ glMaterialfv(gl, face, GL.GL_AMBIENT, params);
+ // fall through intended ..
+ case GL.GL_DIFFUSE:
+ ud = shaderState.getUniform(mgl_FrontMaterial+".diffuse");
+ break;
+ case GL.GL_SPECULAR:
+ ud = shaderState.getUniform(mgl_FrontMaterial+".specular");
+ break;
+ case GL.GL_EMISSION:
+ ud = shaderState.getUniform(mgl_FrontMaterial+".emission");
+ break;
+ case GL.GL_SHININESS:
+ ud = shaderState.getUniform(mgl_FrontMaterial+".shininess");
+ break;
+ default:
+ if(verbose) {
+ System.err.println("glMaterialfv pname not within [GL_AMBIENT GL_DIFFUSE GL_SPECULAR GL_EMISSION GL_SHININESS]: "+pname);
+ }
+ return;
+ }
+ if(null!=ud) {
+ ud.setData(params);
+ shaderState.glUniform(gl, ud);
+ }
+ }
+
+ public void glShadeModel(GL2ES2 gl, int mode) {
+ shaderState.glUseProgram(gl, true);
+ GLUniformData ud = shaderState.getUniform(mgl_ShadeModel);
+ if(null!=ud) {
+ ud.setData(mode);
+ shaderState.glUniform(gl, ud);
+ }
+ }
+
+ public void glActiveTexture(GL2ES2 gl, int textureUnit) {
+ textureUnit -= GL.GL_TEXTURE0;
+ if(0 <= textureUnit && textureUnit<MAX_TEXTURE_UNITS) {
+ shaderState.glUseProgram(gl, true);
+ GLUniformData ud;
+ ud = shaderState.getUniform(mgl_ActiveTexture);
+ if(null!=ud) {
+ ud.setData(textureUnit);
+ shaderState.glUniform(gl, ud);
+ }
+ ud = shaderState.getUniform(mgl_ActiveTextureIdx);
+ if(null!=ud) {
+ ud.setData(textureUnit);
+ shaderState.glUniform(gl, ud);
+ }
+ activeTextureUnit = textureUnit;
+ } else {
+ throw new GLException("glActivateTexture textureUnit not within GL_TEXTURE0 + [0.."+MAX_TEXTURE_UNITS+"]: "+textureUnit);
+ }
+ }
+
+ public void glEnable(GL2ES2 gl, int cap, boolean enable) {
+ shaderState.glUseProgram(gl, true);
+
+ switch(cap) {
+ case GL.GL_TEXTURE_2D:
+ textureEnabled=enable;
+ return;
+ case GL.GL_LIGHTING:
+ lightingEnabled=enable;
+ return;
+ }
+
+ int light = cap - GL.GL_LIGHT0;
+ if(0 <= light && light < MAX_LIGHTS) {
+ if(enable) {
+ lightsEnabled |= (1 << light);
+ } else {
+ lightsEnabled &= ~(1 << light);
+ }
+ return;
+ }
+
+ }
+
+ public void validate(GL2ES2 gl) {
+ shaderState.glUseProgram(gl, true);
+ GLUniformData ud;
+ if(pmvMatrix.update()) {
+ ud = shaderState.getUniform(mgl_PMVMatrix);
+ if(null!=ud) {
+ // same data object ..
+ shaderState.glUniform(gl, ud);
+ } else {
+ throw new GLException("Failed to update: mgl_PMVMatrix");
+ }
+ ud = shaderState.getUniform(mgl_NormalMatrix);
+ if(null!=ud) {
+ // same data object ..
+ shaderState.glUniform(gl, ud);
+ }
+ }
+ ud = shaderState.getUniform(mgl_ColorEnabled);
+ if(null!=ud) {
+ int ca = (shaderState.isVertexAttribArrayEnabled(GLContext.mgl_Color)==true)?1:0;
+ if(ca!=ud.intValue()) {
+ ud.setData(ca);
+ shaderState.glUniform(gl, ud);
+ }
+ }
+
+ ud = shaderState.getUniform(mgl_TexCoordEnabled);
+ if(null!=ud) {
+ if(textureCoordsEnabled!=ud.intValue()) {
+ ud.setData(textureCoordsEnabled);
+ shaderState.glUniform(gl, ud);
+ }
+ }
+
+ ud = shaderState.getUniform(mgl_LightsEnabled);
+ if(null!=ud) {
+ if(lightsEnabled!=ud.intValue()) {
+ ud.setData(lightsEnabled);
+ shaderState.glUniform(gl, ud);
+ }
+ }
+
+ if(textureEnabled) {
+ if(lightingEnabled) {
+ shaderState.attachShaderProgram(gl, shaderProgramColorTextureLight);
+ } else {
+ shaderState.attachShaderProgram(gl, shaderProgramColorTexture);
+ }
+ } else {
+ if(lightingEnabled) {
+ shaderState.attachShaderProgram(gl, shaderProgramColorLight);
+ } else {
+ shaderState.attachShaderProgram(gl, shaderProgramColor);
+ }
+ }
+ if(DEBUG) {
+ System.out.println("validate: "+this);
+ }
+ }
+
+ public String toString() {
+ return "FixedFuncPipeline[pmv: "+pmvMatrix+
+ ", textureEnabled: "+textureEnabled+
+ ", textureCoordsEnabled: "+textureCoordsEnabled+
+ ", lightingEnabled: "+lightingEnabled+
+ ", lightsEnabled: "+lightsEnabled+
+ ", ShaderState: "+shaderState+
+ "]";
+ }
+
+ protected void init(GL2ES2 gl, PMVMatrix pmvMatrix) {
+ if(null==pmvMatrix) {
+ throw new GLException("PMVMatrix is null");
+ }
+ this.pmvMatrix=pmvMatrix;
+ this.shaderState=new ShaderState();
+ this.shaderState.setVerbose(verbose);
+
+ ShaderCode vertexColor = new ShaderCode( gl.GL_VERTEX_SHADER, 1, -1, null,
+ FixedFuncShaderVertexColor.vertShaderSource);
+
+ ShaderCode vertexColorLight = new ShaderCode( gl.GL_VERTEX_SHADER, 1, -1, null,
+ FixedFuncShaderVertexColorLight.vertShaderSource);
+
+ ShaderCode fragmentColor = new ShaderCode( gl.GL_FRAGMENT_SHADER, 1, -1, null,
+ FixedFuncShaderFragmentColor.fragShaderSource);
+
+ ShaderCode fragmentColorTexture = new ShaderCode( gl.GL_FRAGMENT_SHADER, 1, -1, null,
+ FixedFuncShaderFragmentColorTexture.fragShaderSource);
+
+ shaderProgramColor = new ShaderProgram();
+ shaderProgramColor.add(vertexColor);
+ shaderProgramColor.add(fragmentColor);
+ if(!shaderProgramColor.link(gl, System.err)) {
+ throw new GLException("Couldn't link VertexColor program");
+ }
+
+ shaderProgramColorTexture = new ShaderProgram();
+ shaderProgramColorTexture.add(vertexColor);
+ shaderProgramColorTexture.add(fragmentColorTexture);
+ if(!shaderProgramColorTexture.link(gl, System.err)) {
+ throw new GLException("Couldn't link VertexColorTexture program");
+ }
+
+ shaderProgramColorLight = new ShaderProgram();
+ shaderProgramColorLight.add(vertexColorLight);
+ shaderProgramColorLight.add(fragmentColor);
+ if(!shaderProgramColorLight.link(gl, System.err)) {
+ throw new GLException("Couldn't link VertexColorLight program");
+ }
+
+ shaderProgramColorTextureLight = new ShaderProgram();
+ shaderProgramColorTextureLight.add(vertexColorLight);
+ shaderProgramColorTextureLight.add(fragmentColorTexture);
+ if(!shaderProgramColorTextureLight.link(gl, System.err)) {
+ throw new GLException("Couldn't link VertexColorLight program");
+ }
+
+ shaderState.attachShaderProgram(gl, shaderProgramColor);
+ shaderState.glUseProgram(gl, true);
+
+ // mandatory ..
+ if(!shaderState.glUniform(gl, new GLUniformData(mgl_PMVMatrix, 4, 4, pmvMatrix.glGetPMvMviMatrixf()))) {
+ throw new GLException("Error setting PMVMatrix in shader: "+this);
+ }
+
+ // optional parameter ..
+ shaderState.glUniform(gl, new GLUniformData(mgl_NormalMatrix, 3, 3, pmvMatrix.glGetNormalMatrixf()));
+
+ 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_ActiveTexture, activeTextureUnit));
+ shaderState.glUniform(gl, new GLUniformData(mgl_ActiveTextureIdx, activeTextureUnit));
+ shaderState.glUniform(gl, new GLUniformData(mgl_ShadeModel, 0));
+ for(int i=0; i<MAX_LIGHTS; i++) {
+ shaderState.glUniform(gl, new GLUniformData(mgl_LightSource+"["+i+"].ambient", 4, defAmbient));
+ shaderState.glUniform(gl, new GLUniformData(mgl_LightSource+"["+i+"].diffuse", 4, defDiffuse));
+ shaderState.glUniform(gl, new GLUniformData(mgl_LightSource+"["+i+"].specular", 4, defSpecular));
+ shaderState.glUniform(gl, new GLUniformData(mgl_LightSource+"["+i+"].position", 4, defPosition));
+ shaderState.glUniform(gl, new GLUniformData(mgl_LightSource+"["+i+"].spotDirection", 3, defSpotDir));
+ shaderState.glUniform(gl, new GLUniformData(mgl_LightSource+"["+i+"].spotExponent", defSpotExponent));
+ shaderState.glUniform(gl, new GLUniformData(mgl_LightSource+"["+i+"].spotCutoff", defSpotCutoff));
+ shaderState.glUniform(gl, new GLUniformData(mgl_LightSource+"["+i+"].constantAttenuation", defConstantAtten));
+ 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_FrontMaterial+".ambient", 4, defMatAmbient));
+ shaderState.glUniform(gl, new GLUniformData(mgl_FrontMaterial+".diffuse", 4, defMatDiffuse));
+ shaderState.glUniform(gl, new GLUniformData(mgl_FrontMaterial+".specular", 4, defMatSpecular));
+ shaderState.glUniform(gl, new GLUniformData(mgl_FrontMaterial+".emission", 4, defMatEmission));
+ shaderState.glUniform(gl, new GLUniformData(mgl_FrontMaterial+".shininess", defMatShininess));
+
+ shaderState.glUseProgram(gl, false);
+ }
+
+ protected static final boolean DEBUG=false;
+
+ protected boolean verbose=false;
+
+ protected boolean textureEnabled=false;
+ protected int textureCoordsEnabled=0;
+ protected int activeTextureUnit=0;
+
+ protected boolean lightingEnabled=false;
+ protected int lightsEnabled=0;
+
+ protected PMVMatrix pmvMatrix;
+ protected ShaderState shaderState;
+ protected ShaderProgram shaderProgramColor;
+ protected ShaderProgram shaderProgramColorTexture;
+ protected ShaderProgram shaderProgramColorLight;
+ protected ShaderProgram shaderProgramColorTextureLight;
+
+ // uniforms ..
+ protected static final String mgl_PMVMatrix = "mgl_PMVMatrix"; // m4fv[3]
+ protected static final String mgl_NormalMatrix = "mgl_NormalMatrix"; // m4fv
+ protected static final String mgl_ColorEnabled = "mgl_ColorEnabled"; // 1i
+ protected static final String mgl_ColorStatic = "mgl_ColorStatic"; // 4fv
+
+ 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_ShadeModel = "mgl_ShadeModel"; // 1i
+
+ protected static final String mgl_TexCoordEnabled = "mgl_TexCoordEnabled"; // 1i bitfield
+ protected static final String mgl_ActiveTexture = "mgl_ActiveTexture"; // 1i
+ protected static final String mgl_ActiveTextureIdx = "mgl_ActiveTextureIdx";// 1i
+
+ protected static final FloatBuffer zero4f = BufferUtil.newFloatBuffer(new float[] { 0.0f, 0.0f, 0.0f, 0.0f });
+
+ public static final FloatBuffer defAmbient = BufferUtil.newFloatBuffer(new float[] { 0f, 0f, 0f, 1f });
+ public static final FloatBuffer defDiffuse = zero4f;
+ public static final FloatBuffer defSpecular= zero4f;
+ public static final FloatBuffer defPosition= BufferUtil.newFloatBuffer(new float[] { 0f, 0f, 1f, 0f });
+ public static final FloatBuffer defSpotDir = BufferUtil.newFloatBuffer(new float[] { 0f, 0f, -1f });
+ public static final float defSpotExponent = 0f;
+ public static final float defSpotCutoff = 180f;
+ public static final float defConstantAtten = 1f;
+ public static final float defLinearAtten = 0f;
+ public static final float defQuadraticAtten= 0f;
+
+ public static final FloatBuffer defMatAmbient = BufferUtil.newFloatBuffer(new float[] { 0.2f, 0.2f, 0.2f, 1.0f });
+ public static final FloatBuffer defMatDiffuse = BufferUtil.newFloatBuffer(new float[] { 0.8f, 0.8f, 0.8f, 1.0f });
+ public static final FloatBuffer defMatSpecular= BufferUtil.newFloatBuffer(new float[] { 0f, 0f, 0f, 1f});
+ public static final FloatBuffer defMatEmission= BufferUtil.newFloatBuffer(new float[] { 0f, 0f, 0f, 1f});
+ public static final float defMatShininess = 0f;
+}
+
diff --git a/src/classes/com/sun/opengl/impl/glsl/FixedFuncShaderFragmentColor.java b/src/classes/com/sun/opengl/impl/glsl/FixedFuncShaderFragmentColor.java
new file mode 100644
index 000000000..170a6c1da
--- /dev/null
+++ b/src/classes/com/sun/opengl/impl/glsl/FixedFuncShaderFragmentColor.java
@@ -0,0 +1,27 @@
+
+package com.sun.opengl.impl.es2;
+
+import javax.media.opengl.util.*;
+import javax.media.opengl.*;
+import java.nio.*;
+
+public class FixedFuncShaderFragmentColor {
+
+ public static final String[][] fragShaderSource = new String[][] { {
+ "#ifdef GL_ES\n"+
+ " #define MEDIUMP mediump\n"+
+ " #define HIGHP highp\n"+
+ "#else\n"+
+ " #define MEDIUMP\n"+
+ " #define HIGHP\n"+
+ "#endif\n"+
+ "\n"+
+ "varying HIGHP vec4 frontColor;\n"+
+ "\n"+
+ "void main (void)\n"+
+ "{\n"+
+ " gl_FragColor = frontColor;\n"+
+ "}\n" } } ;
+
+}
+
diff --git a/src/classes/com/sun/opengl/impl/glsl/FixedFuncShaderFragmentColorTexture.java b/src/classes/com/sun/opengl/impl/glsl/FixedFuncShaderFragmentColorTexture.java
new file mode 100644
index 000000000..7367a7cb9
--- /dev/null
+++ b/src/classes/com/sun/opengl/impl/glsl/FixedFuncShaderFragmentColorTexture.java
@@ -0,0 +1,39 @@
+
+package com.sun.opengl.impl.es2;
+
+import javax.media.opengl.util.*;
+import javax.media.opengl.*;
+import java.nio.*;
+
+public class FixedFuncShaderFragmentColorTexture {
+
+ public static final String[][] fragShaderSource = new String[][] { {
+ "#ifdef GL_ES\n"+
+ " #define MEDIUMP mediump\n"+
+ " #define HIGHP highp\n"+
+ "#else\n"+
+ " #define MEDIUMP\n"+
+ " #define HIGHP\n"+
+ "#endif\n"+
+ "\n"+
+ "const MEDIUMP int MAX_TEXTURE_UNITS = 8; // <=gl_MaxTextureImageUnits \n"+
+ "const MEDIUMP int MAX_LIGHTS = 8; \n"+
+ "const HIGHP vec4 zero = vec4(0.0, 0.0, 0.0, 0.0);\n"+
+ "\n"+
+ "uniform HIGHP sampler2D mgl_ActiveTexture;\n"+
+ "uniform MEDIUMP int mgl_ActiveTextureIdx;\n"+
+ "\n"+
+ "varying HIGHP vec4 frontColor;\n"+
+ "varying HIGHP vec4 mgl_TexCoord[MAX_TEXTURE_UNITS];\n"+
+ "\n"+
+ "void main (void)\n"+
+ "{\n"+
+ " vec4 texColor = texture2D(mgl_ActiveTexture,mgl_TexCoord[mgl_ActiveTextureIdx].st);\n"+
+ " if(greaterThan(texColor, zero)) {\n"+
+ " gl_FragColor = vec4(frontColor.rgb*texColor.rgb, frontColor.a * texColor.a) ; \n"+
+ " } else {\n"+
+ " gl_FragColor = frontColor;\n"+
+ " }\n"+
+ "}\n" } } ;
+}
+
diff --git a/src/classes/com/sun/opengl/impl/glsl/FixedFuncShaderVertexColor.java b/src/classes/com/sun/opengl/impl/glsl/FixedFuncShaderVertexColor.java
new file mode 100644
index 000000000..2fa8d5c46
--- /dev/null
+++ b/src/classes/com/sun/opengl/impl/glsl/FixedFuncShaderVertexColor.java
@@ -0,0 +1,65 @@
+
+package com.sun.opengl.impl.es2;
+
+import javax.media.opengl.util.*;
+import javax.media.opengl.*;
+import java.nio.*;
+
+public class FixedFuncShaderVertexColor {
+
+ public static final String[][] vertShaderSource = new String[][] { {
+ "#ifdef GL_ES\n"+
+ " #define MEDIUMP mediump\n"+
+ " #define HIGHP highp\n"+
+ "#else\n"+
+ " #define MEDIUMP\n"+
+ " #define HIGHP\n"+
+ "#endif\n"+
+ "\n"+
+ "const MEDIUMP int MAX_TEXTURE_UNITS = 8; // <=gl_MaxTextureImageUnits \n"+
+ "const MEDIUMP int MAX_LIGHTS = 8; \n"+
+ "\n"+
+ "uniform HIGHP mat4 mgl_PMVMatrix[3]; // P, Mv, and Mvi\n"+
+ "uniform MEDIUMP int mgl_ColorEnabled;\n"+
+ "uniform HIGHP vec4 mgl_ColorStatic;\n"+
+ "uniform MEDIUMP int mgl_TexCoordEnabled;\n"+
+ "\n"+
+ "attribute HIGHP vec4 mgl_Vertex;\n"+
+ "attribute HIGHP vec4 mgl_Color;\n"+
+ "attribute HIGHP vec4 mgl_MultiTexCoord0;\n"+
+ "attribute HIGHP vec4 mgl_MultiTexCoord1;\n"+
+ "attribute HIGHP vec4 mgl_MultiTexCoord2;\n"+
+ "attribute HIGHP vec4 mgl_MultiTexCoord3;\n"+
+ "attribute HIGHP vec4 mgl_MultiTexCoord4;\n"+
+ "attribute HIGHP vec4 mgl_MultiTexCoord5;\n"+
+ "attribute HIGHP vec4 mgl_MultiTexCoord6;\n"+
+ "attribute HIGHP vec4 mgl_MultiTexCoord7;\n"+
+ "\n"+
+ "varying HIGHP vec4 frontColor;\n"+
+ "varying HIGHP vec4 mgl_TexCoord[MAX_TEXTURE_UNITS];\n"+
+ "\n"+
+ "void setTexCoord(in HIGHP vec4 defpos) {\n"+
+ " mgl_TexCoord[0] = ( 0 != (mgl_TexCoordEnabled & 1) ) ? mgl_MultiTexCoord0 : defpos;\n"+
+ " mgl_TexCoord[1] = ( 0 != (mgl_TexCoordEnabled & 2) ) ? mgl_MultiTexCoord0 : defpos;\n"+
+ " mgl_TexCoord[2] = ( 0 != (mgl_TexCoordEnabled & 4) ) ? mgl_MultiTexCoord0 : defpos;\n"+
+ " mgl_TexCoord[3] = ( 0 != (mgl_TexCoordEnabled & 8) ) ? mgl_MultiTexCoord0 : defpos;\n"+
+ " mgl_TexCoord[4] = ( 0 != (mgl_TexCoordEnabled & 16) ) ? mgl_MultiTexCoord0 : defpos;\n"+
+ " mgl_TexCoord[5] = ( 0 != (mgl_TexCoordEnabled & 32) ) ? mgl_MultiTexCoord0 : defpos;\n"+
+ " mgl_TexCoord[6] = ( 0 != (mgl_TexCoordEnabled & 64) ) ? mgl_MultiTexCoord0 : defpos;\n"+
+ " mgl_TexCoord[7] = ( 0 != (mgl_TexCoordEnabled & 128) ) ? mgl_MultiTexCoord0 : defpos;\n"+
+ "}\n"+
+ "\n"+
+ "void main(void)\n"+
+ "{\n"+
+ " if(mgl_ColorEnabled>0) {\n"+
+ " frontColor=mgl_Color;\n"+
+ " } else {\n"+
+ " frontColor=mgl_ColorStatic;\n"+
+ " }\n"+
+ "\n"+
+ " gl_Position = mgl_PMVMatrix[0] * mgl_PMVMatrix[1] * mgl_Vertex;\n"+
+ "\n"+
+ " setTexCoord(gl_Position);\n"+
+ "}\n" } } ;
+}
+
diff --git a/src/classes/com/sun/opengl/impl/glsl/FixedFuncShaderVertexColorLight.java b/src/classes/com/sun/opengl/impl/glsl/FixedFuncShaderVertexColorLight.java
new file mode 100644
index 000000000..f1e97a536
--- /dev/null
+++ b/src/classes/com/sun/opengl/impl/glsl/FixedFuncShaderVertexColorLight.java
@@ -0,0 +1,136 @@
+
+package com.sun.opengl.impl.es2;
+
+import javax.media.opengl.util.*;
+import javax.media.opengl.*;
+import java.nio.*;
+
+public class FixedFuncShaderVertexColorLight {
+
+ public static final String[][] vertShaderSource = new String[][] { {
+ "#ifdef GL_ES\n"+
+ " #define MEDIUMP mediump\n"+
+ " #define HIGHP highp\n"+
+ "#else\n"+
+ " #define MEDIUMP\n"+
+ " #define HIGHP\n"+
+ "#endif\n"+
+ "\n"+
+ "struct mgl_LightSourceParameters {\n"+
+ " vec4 ambient; \n"+
+ " vec4 diffuse; \n"+
+ " vec4 specular; \n"+
+ " vec4 position; \n"+
+ " // vec4 halfVector; // is computed here\n"+
+ " vec3 spotDirection; \n"+
+ " float spotExponent; \n"+
+ " float spotCutoff; // (range: [0.0,90.0], 180.0)\n"+
+ " //float spotCosCutoff; // (range: [1.0,0.0],-1.0)\n"+
+ " float constantAttenuation; \n"+
+ " float linearAttenuation; \n"+
+ " float quadraticAttenuation; \n"+
+ "};\n"+
+ "struct mgl_MaterialParameters {\n"+
+ " vec4 ambient; \n"+
+ " vec4 diffuse; \n"+
+ " vec4 specular; \n"+
+ " vec4 emission; \n"+
+ " float shininess; \n"+
+ "};\n"+
+ "\n"+
+ "\n"+
+ "const MEDIUMP int MAX_TEXTURE_UNITS = 8; // <=gl_MaxTextureImageUnits \n"+
+ "const MEDIUMP int MAX_LIGHTS = 8; \n"+
+ "\n"+
+ "uniform HIGHP mat4 mgl_PMVMatrix[3]; // P, Mv, and Mvi\n"+
+ "uniform HIGHP mat3 mgl_NormalMatrix; // transpose(inverse(ModelView)).3x3\n"+
+ "uniform MEDIUMP int mgl_ColorEnabled;\n"+
+ "uniform HIGHP vec4 mgl_ColorStatic;\n"+
+ "uniform MEDIUMP int mgl_TexCoordEnabled;\n"+
+ "uniform MEDIUMP int mgl_LightsEnabled;\n"+
+ "uniform mgl_LightSourceParameters mgl_LightSource[MAX_LIGHTS];\n"+
+ "uniform mgl_MaterialParameters mgl_FrontMaterial;\n"+
+ "\n"+
+ "attribute HIGHP vec4 mgl_Vertex;\n"+
+ "attribute HIGHP vec3 mgl_Normal;\n"+
+ "attribute HIGHP vec4 mgl_Color;\n"+
+ "attribute HIGHP vec4 mgl_MultiTexCoord0;\n"+
+ "attribute HIGHP vec4 mgl_MultiTexCoord1;\n"+
+ "attribute HIGHP vec4 mgl_MultiTexCoord2;\n"+
+ "attribute HIGHP vec4 mgl_MultiTexCoord3;\n"+
+ "attribute HIGHP vec4 mgl_MultiTexCoord4;\n"+
+ "attribute HIGHP vec4 mgl_MultiTexCoord5;\n"+
+ "attribute HIGHP vec4 mgl_MultiTexCoord6;\n"+
+ "attribute HIGHP vec4 mgl_MultiTexCoord7;\n"+
+ "\n"+
+ "varying HIGHP vec4 frontColor;\n"+
+ "varying HIGHP vec4 mgl_TexCoord[MAX_TEXTURE_UNITS];\n"+
+ "\n"+
+ "void setTexCoord(in HIGHP vec4 defpos) {\n"+
+ " mgl_TexCoord[0] = ( 0 != (mgl_TexCoordEnabled & 1) ) ? mgl_MultiTexCoord0 : defpos;\n"+
+ " mgl_TexCoord[1] = ( 0 != (mgl_TexCoordEnabled & 2) ) ? mgl_MultiTexCoord0 : defpos;\n"+
+ " mgl_TexCoord[2] = ( 0 != (mgl_TexCoordEnabled & 4) ) ? mgl_MultiTexCoord0 : defpos;\n"+
+ " mgl_TexCoord[3] = ( 0 != (mgl_TexCoordEnabled & 8) ) ? mgl_MultiTexCoord0 : defpos;\n"+
+ " mgl_TexCoord[4] = ( 0 != (mgl_TexCoordEnabled & 16) ) ? mgl_MultiTexCoord0 : defpos;\n"+
+ " mgl_TexCoord[5] = ( 0 != (mgl_TexCoordEnabled & 32) ) ? mgl_MultiTexCoord0 : defpos;\n"+
+ " mgl_TexCoord[6] = ( 0 != (mgl_TexCoordEnabled & 64) ) ? mgl_MultiTexCoord0 : defpos;\n"+
+ " mgl_TexCoord[7] = ( 0 != (mgl_TexCoordEnabled & 128) ) ? mgl_MultiTexCoord0 : defpos;\n"+
+ "}\n"+
+ "\n"+
+ "void main(void)\n"+
+ "{\n"+
+ " vec4 position;\n"+
+ " vec3 normal, lightDir, cameraDir, halfDir;\n"+
+ " vec4 ambient, diffuse, specular;\n"+
+ " float NdotL, NdotHV, dist, attenuation;\n"+
+ " int i;\n"+
+ "\n"+
+ " position = mgl_PMVMatrix[1] * mgl_Vertex; // vertex eye position \n"+
+ "\n"+
+ " normal = normalize(mgl_NormalMatrix * mgl_Normal); \n"+
+ " // cameraPosition: (mgl_PMVMatrix[2] * vec4(0,0,0,1.0)).xyz \n"+
+ " cameraDir = normalize( (mgl_PMVMatrix[2] * vec4(0,0,0,1.0)).xyz - mgl_Vertex.xyz ); \n"+
+ "\n"+
+ " ambient = vec4(0,0,0,0);\n"+
+ " diffuse = vec4(0,0,0,0);\n"+
+ " specular = vec4(0,0,0,0);\n"+
+ "\n"+
+ " for(i=0; i<MAX_LIGHTS; i++) {\n"+
+ " if( 0!= (mgl_LightsEnabled & (1<<i)) ) {\n"+
+ " ambient += mgl_LightSource[i].ambient;\n"+
+ " lightDir = mgl_LightSource[i].position.xyz - position.xyz;\n"+
+ " dist = length(lightDir);\n"+
+ " lightDir = normalize(lightDir);\n"+
+ " attenuation = 1.0 / ( \n"+
+ " mgl_LightSource[i].constantAttenuation+ \n"+
+ " mgl_LightSource[i].linearAttenuation * dist + \n"+
+ " mgl_LightSource[i].quadraticAttenuation * dist * dist );\n"+
+ " NdotL = max(0.0, dot(normal, lightDir));\n"+
+ " diffuse += mgl_LightSource[i].diffuse * NdotL * attenuation;\n"+
+ " if (NdotL != 0.0) {\n"+
+ " halfDir = normalize (lightDir + cameraDir); \n"+
+ " NdotHV = max(0.0, dot(normal, halfDir));\n"+
+ " specular += mgl_LightSource[i].specular * \n"+
+ " pow(NdotHV,gl_FrontMaterial.shininess) * attenuation;\n"+
+ " }\n"+
+ " }\n"+
+ " }\n"+
+ " ambient += mgl_FrontMaterial.ambient;\n"+
+ " diffuse *= mgl_FrontMaterial.diffuse;\n"+
+ " specular *= mgl_FrontMaterial.specular;\n"+
+ "\n"+
+ " if(mgl_ColorEnabled>0) {\n"+
+ " frontColor=mgl_Color;\n"+
+ " } else {\n"+
+ " frontColor=mgl_ColorStatic;\n"+
+ " }\n"+
+ " if( 0!= mgl_LightsEnabled ) {\n"+
+ " frontColor *= ambient + diffuse + specular;\n"+
+ " }\n"+
+ "\n"+
+ " gl_Position = mgl_PMVMatrix[0] * position;\n"+
+ "\n"+
+ " setTexCoord(gl_Position);\n"+
+ "}\n" } } ;
+}
+
diff --git a/src/classes/com/sun/opengl/impl/glsl/GLSLArrayDataServer.java b/src/classes/com/sun/opengl/impl/glsl/GLSLArrayDataServer.java
new file mode 100644
index 000000000..551eb525f
--- /dev/null
+++ b/src/classes/com/sun/opengl/impl/glsl/GLSLArrayDataServer.java
@@ -0,0 +1,58 @@
+
+package com.sun.opengl.impl.glsl;
+
+import javax.media.opengl.*;
+import javax.media.opengl.util.glsl.ShaderState;
+import java.nio.*;
+
+public class GLSLArrayDataServer extends GLArrayDataServer {
+
+ public GLSLArrayDataServer(String name, int comps, int dataType, boolean normalized,
+ int stride, Buffer buffer, int glBufferUsage) {
+ init(name, -1, comps, dataType, normalized, stride, buffer, 0, buffer.limit(), glBufferUsage, true);
+ }
+
+ public GLSLArrayDataServer(String name, int comps, int dataType, boolean normalized,
+ int stride, long bufferOffset) {
+ init(name, -1, comps, dataType, normalized, stride, null, bufferOffset, 0, -1, true);
+ }
+
+ public GLSLArrayDataServer(String name, int comps, int dataType, boolean normalized,
+ int initialSize, int glBufferUsage) {
+ init(name, -1, comps, dataType, normalized, 0, null, 0, initialSize, glBufferUsage, true);
+ }
+
+
+ protected void enableBufferGLImpl(GL gl, boolean enable) {
+ GL2ES2 glsl = gl.getGL2ES2();
+ ShaderState st = ShaderState.getCurrent();
+ if(null==st) {
+ throw new GLException("No ShaderState current");
+ }
+
+ if(enable) {
+ if(!st.glEnableVertexAttribArray(glsl, name)) {
+ throw new RuntimeException("Internal Error");
+ }
+ bufferEnabled = true;
+
+ if(vboUsage) {
+ gl.glBindBuffer(GL.GL_ARRAY_BUFFER, vboName);
+ if(!bufferWritten) {
+ gl.glBufferData(GL.GL_ARRAY_BUFFER, buffer.limit() * getBufferCompSize(), buffer, glBufferUsage);
+ }
+ }
+ if ( ! st.glVertexAttribPointer(glsl, this) ) {
+ throw new RuntimeException("Internal Error");
+ }
+ bufferWritten=true;
+ } else {
+ if(!st.glDisableVertexAttribArray(glsl, name)) {
+ throw new RuntimeException("Internal Error");
+ }
+ bufferEnabled = false;
+ }
+ }
+
+}
+
diff --git a/src/classes/com/sun/opengl/impl/glu/GLUquadricImpl.java b/src/classes/com/sun/opengl/impl/glu/GLUquadricImpl.java
index 8c2a4eef2..031d23c50 100644
--- a/src/classes/com/sun/opengl/impl/glu/GLUquadricImpl.java
+++ b/src/classes/com/sun/opengl/impl/glu/GLUquadricImpl.java
@@ -130,6 +130,7 @@ import java.nio.*;
*/
public class GLUquadricImpl implements GLUquadric {
+ private boolean useGLSL;
private int drawStyle;
private int orientation;
private boolean textureFlag;
@@ -137,19 +138,29 @@ public class GLUquadricImpl implements GLUquadric {
private boolean immModeSinkEnabled;
private boolean immModeSinkImmediate;
- public static final boolean USE_NORM_TXT = true;
+ public static final boolean USE_NORM = true;
+ public static final boolean USE_TEXT = false;
private ImmModeSink immModeSink;
- public GLUquadricImpl() {
+ public GLUquadricImpl(boolean useGLSL) {
+ this.useGLSL = useGLSL;
drawStyle = GLU.GLU_FILL;
orientation = GLU.GLU_OUTSIDE;
textureFlag = false;
normals = GLU.GLU_SMOOTH;
- if(USE_NORM_TXT) {
- immModeSink = new ImmModeSink(GL.GL_FLOAT, GL.GL_STATIC_DRAW, 3, 3, 0, 3, 32);
+ if(useGLSL) {
+ immModeSink = ImmModeSink.createGLSL (GL.GL_STATIC_DRAW, 32,
+ 3, GL.GL_FLOAT, // vertex
+ 0, GL.GL_FLOAT, // color
+ USE_NORM?3:0, GL.GL_SHORT, // normal
+ USE_TEXT?2:0, GL.GL_FLOAT); // texture
} else {
- immModeSink = new ImmModeSink(GL.GL_FLOAT, GL.GL_STATIC_DRAW, 3, 0, 0, 0, 32);
+ immModeSink = ImmModeSink.createFixed(GL.GL_STATIC_DRAW, 32,
+ 3, GL.GL_FLOAT, // vertex
+ 0, GL.GL_FLOAT, // color
+ USE_NORM?3:0, GL.GL_SHORT, // normal
+ USE_TEXT?2:0, GL.GL_FLOAT); // texture
}
immModeSinkImmediate=true;
immModeSinkEnabled=!GLProfile.isGL2();
@@ -183,10 +194,18 @@ public class GLUquadricImpl implements GLUquadric {
if(!immModeSinkEnabled) return null;
ImmModeSink res = immModeSink;
- if(USE_NORM_TXT) {
- immModeSink = new ImmModeSink(GL.GL_FLOAT, GL.GL_STATIC_DRAW, 3, 3, 0, 3, 32);
+ if(useGLSL) {
+ immModeSink = ImmModeSink.createGLSL (GL.GL_STATIC_DRAW, 32,
+ 3, GL.GL_FLOAT, // vertex
+ 0, GL.GL_FLOAT, // color
+ USE_NORM?3:0, GL.GL_SHORT, // normal
+ USE_TEXT?2:0, GL.GL_FLOAT); // texture
} else {
- immModeSink = new ImmModeSink(GL.GL_FLOAT, GL.GL_STATIC_DRAW, 3, 0, 0, 0, 32);
+ immModeSink = ImmModeSink.createFixed(GL.GL_STATIC_DRAW, 32,
+ 3, GL.GL_FLOAT, // vertex
+ 0, GL.GL_FLOAT, // color
+ USE_NORM?3:0, GL.GL_SHORT, // normal
+ USE_TEXT?2:0, GL.GL_FLOAT); // texture
}
return res;
}
@@ -349,9 +368,7 @@ public class GLUquadricImpl implements GLUquadric {
for (i = 0; i < slices; i++) {
x = cos((i * da));
y = sin((i * da));
- if(USE_NORM_TXT) {
- normal3f(gl, x * nsign, y * nsign, nz * nsign);
- }
+ normal3f(gl, x * nsign, y * nsign, nz * nsign);
z = 0.0f;
r = baseRadius;
@@ -372,9 +389,7 @@ public class GLUquadricImpl implements GLUquadric {
for (i = 0; i < slices; i++) {
x = cos((i * da));
y = sin((i * da));
- if(USE_NORM_TXT) {
- normal3f(gl, x * nsign, y * nsign, nz * nsign);
- }
+ normal3f(gl, x * nsign, y * nsign, nz * nsign);
glVertex3f(gl, (x * r), (y * r), z);
}
glEnd(gl);
@@ -388,9 +403,7 @@ public class GLUquadricImpl implements GLUquadric {
for (i = 0; i < slices; i++) {
x = cos((i * da));
y = sin((i * da));
- if(USE_NORM_TXT) {
- normal3f(gl, x * nsign, y * nsign, nz * nsign);
- }
+ normal3f(gl, x * nsign, y * nsign, nz * nsign);
glVertex3f(gl, (x * baseRadius), (y * baseRadius), 0.0f);
}
glEnd(gl);
@@ -398,9 +411,7 @@ public class GLUquadricImpl implements GLUquadric {
for (i = 0; i < slices; i++) {
x = cos((i * da));
y = sin((i * da));
- if(USE_NORM_TXT) {
- normal3f(gl, x * nsign, y * nsign, nz * nsign);
- }
+ normal3f(gl, x * nsign, y * nsign, nz * nsign);
glVertex3f(gl, (x * topRadius), (y * topRadius), height);
}
glEnd(gl);
@@ -411,9 +422,7 @@ public class GLUquadricImpl implements GLUquadric {
for (i = 0; i < slices; i++) {
x = cos((i * da));
y = sin((i * da));
- if(USE_NORM_TXT) {
- normal3f(gl, x * nsign, y * nsign, nz * nsign);
- }
+ normal3f(gl, x * nsign, y * nsign, nz * nsign);
glVertex3f(gl, (x * baseRadius), (y * baseRadius), 0.0f);
glVertex3f(gl, (x * topRadius), (y * topRadius), (height));
}
@@ -436,26 +445,18 @@ public class GLUquadricImpl implements GLUquadric {
y = cos((i * da));
}
if (nsign == 1.0f) {
- if(USE_NORM_TXT) {
- normal3f(gl, (x * nsign), (y * nsign), (nz * nsign));
- TXTR_COORD(gl, s, t);
- }
+ normal3f(gl, (x * nsign), (y * nsign), (nz * nsign));
+ TXTR_COORD(gl, s, t);
glVertex3f(gl, (x * r), (y * r), z);
- if(USE_NORM_TXT) {
- normal3f(gl, (x * nsign), (y * nsign), (nz * nsign));
- TXTR_COORD(gl, s, t + dt);
- }
+ normal3f(gl, (x * nsign), (y * nsign), (nz * nsign));
+ TXTR_COORD(gl, s, t + dt);
glVertex3f(gl, (x * (r + dr)), (y * (r + dr)), (z + dz));
} else {
- if(USE_NORM_TXT) {
- normal3f(gl, x * nsign, y * nsign, nz * nsign);
- TXTR_COORD(gl, s, t);
- }
+ normal3f(gl, x * nsign, y * nsign, nz * nsign);
+ TXTR_COORD(gl, s, t);
glVertex3f(gl, (x * r), (y * r), z);
- if(USE_NORM_TXT) {
- normal3f(gl, x * nsign, y * nsign, nz * nsign);
- TXTR_COORD(gl, s, t + dt);
- }
+ normal3f(gl, x * nsign, y * nsign, nz * nsign);
+ TXTR_COORD(gl, s, t + dt);
glVertex3f(gl, (x * (r + dr)), (y * (r + dr)), (z + dz));
}
s += ds;
@@ -959,19 +960,15 @@ public class GLUquadricImpl implements GLUquadric {
if (!textureFlag) {
// draw +Z end as a triangle fan
glBegin(gl, GL.GL_TRIANGLE_FAN);
- if(USE_NORM_TXT) {
- glNormal3f(gl, 0.0f, 0.0f, 1.0f);
- }
+ glNormal3f(gl, 0.0f, 0.0f, 1.0f);
glVertex3f(gl, 0.0f, 0.0f, nsign * radius);
for (j = 0; j <= slices; j++) {
theta = (j == slices) ? 0.0f : j * dtheta;
x = -sin(theta) * sin(drho);
y = cos(theta) * sin(drho);
z = nsign * cos(drho);
- if(USE_NORM_TXT) {
- if (normals) {
- glNormal3f(gl, x * nsign, y * nsign, z * nsign);
- }
+ if (normals) {
+ glNormal3f(gl, x * nsign, y * nsign, z * nsign);
}
glVertex3f(gl, x * radius, y * radius, z * radius);
}
@@ -999,22 +996,18 @@ public class GLUquadricImpl implements GLUquadric {
x = -sin(theta) * sin(rho);
y = cos(theta) * sin(rho);
z = nsign * cos(rho);
- if(USE_NORM_TXT) {
- if (normals) {
- glNormal3f(gl, x * nsign, y * nsign, z * nsign);
- }
- TXTR_COORD(gl, s, t);
+ if (normals) {
+ glNormal3f(gl, x * nsign, y * nsign, z * nsign);
}
+ TXTR_COORD(gl, s, t);
glVertex3f(gl, x * radius, y * radius, z * radius);
x = -sin(theta) * sin(rho + drho);
y = cos(theta) * sin(rho + drho);
z = nsign * cos(rho + drho);
- if(USE_NORM_TXT) {
- if (normals) {
- glNormal3f(gl, x * nsign, y * nsign, z * nsign);
- }
- TXTR_COORD(gl, s, t - dt);
+ if (normals) {
+ glNormal3f(gl, x * nsign, y * nsign, z * nsign);
}
+ TXTR_COORD(gl, s, t - dt);
s += ds;
glVertex3f(gl, x * radius, y * radius, z * radius);
}
@@ -1025,9 +1018,7 @@ public class GLUquadricImpl implements GLUquadric {
if (!textureFlag) {
// draw -Z end as a triangle fan
glBegin(gl, GL.GL_TRIANGLE_FAN);
- if(USE_NORM_TXT) {
- glNormal3f(gl, 0.0f, 0.0f, -1.0f);
- }
+ glNormal3f(gl, 0.0f, 0.0f, -1.0f);
glVertex3f(gl, 0.0f, 0.0f, -radius * nsign);
rho = PI - drho;
s = 1.0f;
@@ -1036,10 +1027,8 @@ public class GLUquadricImpl implements GLUquadric {
x = -sin(theta) * sin(rho);
y = cos(theta) * sin(rho);
z = nsign * cos(rho);
- if(USE_NORM_TXT) {
- if (normals)
- glNormal3f(gl, x * nsign, y * nsign, z * nsign);
- }
+ if (normals)
+ glNormal3f(gl, x * nsign, y * nsign, z * nsign);
s -= ds;
glVertex3f(gl, x * radius, y * radius, z * radius);
}
@@ -1148,10 +1137,13 @@ public class GLUquadricImpl implements GLUquadric {
}
private final void glNormal3f(GL gl, float x, float y, float z) {
+ short a=(short)(x*0xFFFF);
+ short b=(short)(y*0xFFFF);
+ short c=(short)(z*0xFFFF);
if(immModeSinkEnabled) {
- immModeSink.glNormal3f(x, y, z);
+ immModeSink.glNormal3s(a, b, c);
} else {
- ((GL2)gl).glNormal3f(x, y, z);
+ ((GL2)gl).glNormal3s(a, b, c);
}
}
@@ -1179,11 +1171,7 @@ public class GLUquadricImpl implements GLUquadric {
y /= mag;
z /= mag;
}
- if(immModeSinkEnabled) {
- immModeSink.glNormal3f(x, y, z);
- } else {
- ((GL2)gl).glNormal3f(x, y, z);
- }
+ glNormal3f(gl, x, y, z);
}
private final void TXTR_COORD(GL gl, float x, float y) {
diff --git a/src/classes/javax/media/opengl/GLArrayData.java b/src/classes/javax/media/opengl/GLArrayData.java
new file mode 100644
index 000000000..db017b00a
--- /dev/null
+++ b/src/classes/javax/media/opengl/GLArrayData.java
@@ -0,0 +1,153 @@
+
+package javax.media.opengl;
+
+import java.nio.*;
+
+public interface GLArrayData {
+
+ /**
+ * Returns true if this data set is intended for a GLSL vertex shader attribute,
+ * otherwise false, ie intended for fixed function vertex pointer
+ */
+ public boolean isVertexAttribute();
+
+ /**
+ * The index of the predefined array index, see list below,
+ * or -1 in case of a shader attribute array.
+ *
+ * @see javax.media.opengl.GL#GL_VERTEX_ARRAY
+ * @see javax.media.opengl.GL#GL_NORMAL_ARRAY
+ * @see javax.media.opengl.GL#GL_COLOR_ARRAY
+ * @see javax.media.opengl.GL#GL_TEXTURE_COORD_ARRAY
+ */
+ public int getIndex();
+
+ /**
+ * The name of the reflecting shader array attribute.
+ */
+ public String getName();
+
+ /**
+ * Set a new name for this array.
+ */
+ public void setName(String newName);
+
+
+ /**
+ * Returns the shader attribute location for this name,
+ * -1 if not yet determined
+ */
+ public int getLocation();
+
+ /**
+ * Sets the determined location of the shader attribute
+ * This is usually done within ShaderState.
+ *
+ * @see javax.media.opengl.util.glsl.ShaderState#glVertexAttribPointer(GL2ES2, GLArrayData)
+ */
+ public void setLocation(int v);
+
+
+ public boolean sealed();
+
+ /**
+ * The offset, if it's an VBO, otherwise -1
+ */
+ public long getOffset();
+
+ /**
+ * The Buffer holding the data, may be null in case of VBO
+ */
+ public Buffer getBuffer();
+
+ /**
+ * Determines wheather the data is server side (VBO),
+ * or a client side array (false).
+ */
+ public boolean isVBO();
+
+ /**
+ * The number of components per element
+ */
+ public int getComponents();
+
+ /**
+ * The GL data type of the components, ie. GL_FLOAT
+ */
+ public int getDataType();
+
+ /**
+ * True, if GL shall normalize fixed point data while converting
+ * them into float
+ */
+ public boolean getNormalized();
+
+ /**
+ * The distance to the next payload,
+ * allowing interleaved arrays.
+ */
+ public int getStride();
+
+ public int getVerticeNumber();
+
+ public int getBufferCompSize();
+
+ public String toString();
+
+ //
+ // Data and GL state modification ..
+ //
+
+ public void destroy(GL gl);
+
+ public void reset(GL gl);
+
+ /**
+ * If seal is true, it
+ * disable write operations to the buffer.
+ * Calls flip, ie limit:=position and position:=0.
+ * Also enables the buffer for OpenGL, and passes the data.
+ *
+ * If seal is false, it
+ * enable write operations continuing
+ * at the buffer position, where you left off at seal(true),
+ * ie position:=limit and limit:=capacity.
+ * Also disables the buffer for OpenGL.
+ *
+ * @see #seal(boolean)
+ */
+ public void seal(GL gl, boolean seal);
+
+ public void enableBuffer(GL gl, boolean enable);
+
+ //
+ // Data modification ..
+ //
+
+ public void reset();
+
+ /**
+ * If seal is true, it
+ * disable write operations to the buffer.
+ * Calls flip, ie limit:=position and position:=0.
+ *
+ * If seal is false, it
+ * enable write operations continuing
+ * at the buffer position, where you left off at seal(true),
+ * ie position:=limit and limit:=capacity.
+ *
+ */
+ public void seal(boolean seal);
+
+ public void rewind();
+ public void padding(int done);
+ public void put(Buffer v);
+ public void putb(byte v);
+ public void puts(short v);
+ public void puti(int v);
+ public void putx(int v);
+ public void putf(float v);
+ public void putd(double v);
+
+}
+
diff --git a/src/classes/javax/media/opengl/GLArrayDataClient.java b/src/classes/javax/media/opengl/GLArrayDataClient.java
new file mode 100644
index 000000000..5048e15c3
--- /dev/null
+++ b/src/classes/javax/media/opengl/GLArrayDataClient.java
@@ -0,0 +1,498 @@
+
+package javax.media.opengl;
+
+import javax.media.opengl.util.*;
+import com.sun.opengl.impl.GLReflection;
+
+import java.nio.*;
+
+public class GLArrayDataClient implements GLArrayData {
+
+ /**
+ * @arg index The GL array index
+ * @arg name The optional custom name for the GL array index, maybe null.
+ * If null, the default name mapping will be used, see 'getPredefinedArrayIndexName(int)'.
+ * This name might be used as the shader attribute name.
+ * @arg comps The array component number
+ * @arg dataType The array index GL data type
+ * @arg normalized Wheather the data shall be normalized
+ *
+ * @see javax.media.opengl.GLContext#getPredefinedArrayIndexName(int)
+ */
+ public static GLArrayDataClient createFixed(int index, String name, int comps, int dataType, boolean normalized,
+ int initialSize)
+ throws GLException
+ {
+ GLProfile.isValidateArrayDataType(index, comps, dataType, false, true);
+ GLArrayDataClient adc = new GLArrayDataClient();
+ adc.init(name, index, comps, dataType, normalized, 0, null, initialSize, false);
+ return adc;
+ }
+
+ public static GLArrayDataClient createFixed(int index, String name, int comps, int dataType, boolean normalized,
+ int stride, Buffer buffer)
+ throws GLException
+ {
+ GLProfile.isValidateArrayDataType(index, comps, dataType, false, true);
+ GLArrayDataClient adc = new GLArrayDataClient();
+ adc.init(name, index, comps, dataType, normalized, stride, buffer, comps*comps, false);
+ return adc;
+ }
+
+ public static GLArrayDataClient createGLSL(int index, String name, int comps, int dataType, boolean normalized,
+ int initialSize)
+ throws GLException
+ {
+ GLProfile.isValidateArrayDataType(index, comps, dataType, true, true);
+ GLArrayDataClient adc = new GLArrayDataClient();
+ adc.init(name, index, comps, dataType, normalized, 0, null, initialSize, true);
+ return adc;
+ }
+
+ public static GLArrayDataClient createGLSL(int index, String name, int comps, int dataType, boolean normalized,
+ int stride, Buffer buffer)
+ throws GLException
+ {
+ GLProfile.isValidateArrayDataType(index, comps, dataType, true, true);
+ GLArrayDataClient adc = new GLArrayDataClient();
+ adc.init(name, index, comps, dataType, normalized, stride, buffer, comps*comps, true);
+ return adc;
+ }
+
+ //
+ // Data read access
+ //
+
+ public boolean isVertexAttribute() { return isVertexAttribute; }
+
+ public int getIndex() { return index; }
+
+ public int getLocation() { return location; }
+
+ public void setLocation(int v) { location = v; }
+
+ public String getName() { return name; }
+
+ public long getOffset() { return -1; }
+
+ public Buffer getBuffer() { return buffer; }
+
+ public boolean isVBO() { return false; }
+
+ public int getComponents() { return components; }
+
+ public int getDataType() { return dataType; }
+
+ public boolean getNormalized() { return normalized; }
+
+ public int getStride() { return stride; }
+
+ public boolean sealed() { return sealed; }
+
+ public Class getBufferClass() {
+ return clazz;
+ }
+
+ public int getVerticeNumber() {
+ return ( buffer!=null ) ? ( buffer.limit() / components ) : 0 ;
+ }
+
+ //
+ // Data and GL state modification ..
+ //
+
+ public void setName(String newName) {
+ location = -1;
+ name = newName;
+ }
+
+ public void destroy(GL gl) {
+ reset(gl);
+ }
+
+ public void reset(GL gl) {
+ enableBuffer(gl, false);
+ reset();
+ }
+
+ public void seal(GL gl, boolean seal)
+ {
+ seal(seal);
+ if(sealedGL==seal) return;
+ sealedGL = seal;
+ if(seal) {
+ init_vbo(gl);
+
+ enableBuffer(gl, true);
+ } else {
+ enableBuffer(gl, false);
+ }
+ }
+
+ public void enableBuffer(GL gl, boolean enable)
+ {
+ if(enable) {
+ checkSeal(true);
+ if(!bufferEnabled && null!=buffer) {
+ buffer.rewind();
+ enableBufferGLImpl(gl, true);
+ }
+ } else if(bufferEnabled) {
+ enableBufferGLImpl(gl, false);
+ }
+ }
+
+ //
+ // Data modification ..
+ //
+
+ public void reset() {
+ if(buffer!=null) {
+ buffer.clear();
+ }
+ this.sealed=false;
+ this.bufferEnabled=false;
+ this.bufferWritten=false;
+ }
+
+ public void seal(boolean seal)
+ {
+ if(sealed==seal) return;
+ sealed = seal;
+ if(seal) {
+ bufferWritten=false;
+ if (null!=buffer) {
+ buffer.flip();
+ }
+ } else {
+ if (null!=buffer) {
+ buffer.position(buffer.limit());
+ buffer.limit(buffer.capacity());
+ }
+ }
+ }
+
+
+ public void rewind() {
+ if(buffer!=null) {
+ buffer.rewind();
+ }
+ }
+
+ public void padding(int done) {
+ if ( buffer==null || sealed ) return;
+ while(done<strideL) {
+ if(clazz==ByteBuffer.class) {
+ ((ByteBuffer)buffer).put((byte)0);
+ } else if(clazz==ShortBuffer.class) {
+ ((ShortBuffer)buffer).put((short)0);
+ } else if(clazz==IntBuffer.class) {
+ ((IntBuffer)buffer).put(0);
+ } else if(clazz==FloatBuffer.class) {
+ ((FloatBuffer)buffer).put(0f);
+ } else {
+ throw new GLException("Given Buffer Class not supported: "+clazz+" :\n\t"+this);
+ }
+ done++;
+ }
+ }
+
+ /**
+ * Generic buffer relative put method.
+ *
+ * This class buffer Class must match the arguments buffer class.
+ * The arguments remaining elements must be a multiple of this arrays element stride.
+ */
+ public void put(Buffer v) {
+ if ( buffer==null || sealed ) return;
+ if(0!=(v.remaining() % strideL)) {
+ throw new GLException("Buffer length ("+v.remaining()+") is not a multiple of component-stride:\n\t"+this);
+ }
+ Class vClazz = v.getClass();
+ if(!GLReflection.instanceOf(vClazz, clazz.getName())) {
+ throw new GLException("This array's buffer class "+clazz+" doesn't match the argument's Class: "+vClazz+" :\n\t"+this);
+ }
+ growBufferIfNecessary(v.remaining());
+ if(clazz==ByteBuffer.class) {
+ ((ByteBuffer)buffer).put((ByteBuffer)v);
+ } else if(clazz==ShortBuffer.class) {
+ ((ShortBuffer)buffer).put((ShortBuffer)v);
+ } else if(clazz==IntBuffer.class) {
+ ((IntBuffer)buffer).put((IntBuffer)v);
+ } else if(clazz==FloatBuffer.class) {
+ ((FloatBuffer)buffer).put((FloatBuffer)v);
+ }
+ }
+
+ public void putb(byte v) {
+ if ( buffer==null || sealed ) return;
+ growBufferIfNecessary(1);
+ if(clazz==ByteBuffer.class) {
+ ((ByteBuffer)buffer).put(v);
+ } else if(clazz==ShortBuffer.class) {
+ ((ShortBuffer)buffer).put((short)v);
+ } else if(clazz==IntBuffer.class) {
+ ((IntBuffer)buffer).put((int)v);
+ } else {
+ throw new GLException("Byte doesn't match Buffer Class: "+clazz+" :\n\t"+this);
+ }
+ }
+
+ public void puts(short v) {
+ if ( buffer==null || sealed ) return;
+ growBufferIfNecessary(1);
+ if(clazz==ShortBuffer.class) {
+ ((ShortBuffer)buffer).put(v);
+ } else if(clazz==IntBuffer.class) {
+ ((IntBuffer)buffer).put((int)v);
+ } else {
+ throw new GLException("Short doesn't match Buffer Class: "+clazz+" :\n\t"+this);
+ }
+ }
+
+ public void puti(int v) {
+ if ( buffer==null || sealed ) return;
+ growBufferIfNecessary(1);
+ if(clazz==IntBuffer.class) {
+ ((IntBuffer)buffer).put(v);
+ } else {
+ throw new GLException("Integer doesn't match Buffer Class: "+clazz+" :\n\t"+this);
+ }
+ }
+
+ public void putx(int v) {
+ puti(v);
+ }
+
+ public void putf(float v) {
+ if ( buffer==null || sealed ) return;
+ growBufferIfNecessary(1);
+ if(clazz==FloatBuffer.class) {
+ ((FloatBuffer)buffer).put(v);
+ } else if(clazz==IntBuffer.class) {
+ ((IntBuffer)buffer).put(FixedPoint.toFixed(v));
+ } else {
+ throw new GLException("Float doesn't match Buffer Class: "+clazz+" :\n\t"+this);
+ }
+ }
+
+ public void putd(double v) {
+ if ( buffer==null || sealed ) return;
+ growBufferIfNecessary(1);
+ if(clazz==FloatBuffer.class) {
+ ((FloatBuffer)buffer).put((float)v);
+ } else {
+ throw new GLException("Double doesn't match Buffer Class: "+clazz+" :\n\t"+this);
+ }
+ }
+
+ public String toString() {
+ return "GLArrayDataClient["+name+
+ ", index "+index+
+ ", location "+location+
+ ", isVertexAttribute "+isVertexAttribute+
+ ", dataType "+dataType+
+ ", bufferClazz "+clazz+
+ ", vertices "+getVerticeNumber()+
+ ", components "+components+
+ ", stride "+stride+"u "+strideB+"b "+strideL+"c"+
+ ", initialSize "+initialSize+
+ ", sealed "+sealed+
+ ", bufferEnabled "+bufferEnabled+
+ ", bufferWritten "+bufferWritten+
+ ", buffer "+buffer+
+ "]";
+ }
+
+ public static final Class getBufferClass(int dataType) {
+ switch(dataType) {
+ case GL.GL_BYTE:
+ case GL.GL_UNSIGNED_BYTE:
+ return ByteBuffer.class;
+ case GL.GL_SHORT:
+ case GL.GL_UNSIGNED_SHORT:
+ return ShortBuffer.class;
+ case GL2ES1.GL_FIXED:
+ return IntBuffer.class;
+ case GL.GL_FLOAT:
+ return FloatBuffer.class;
+ default:
+ throw new GLException("Given OpenGL data type not supported: "+dataType);
+ }
+ }
+
+ public final int getBufferCompSize() {
+ if(clazz==ByteBuffer.class) {
+ return BufferUtil.SIZEOF_BYTE;
+ }
+ if(clazz==ShortBuffer.class) {
+ return BufferUtil.SIZEOF_SHORT;
+ }
+ if(clazz==IntBuffer.class) {
+ return BufferUtil.SIZEOF_INT;
+ }
+ if(clazz==FloatBuffer.class) {
+ return BufferUtil.SIZEOF_FLOAT;
+ }
+ throw new GLException("Given Buffer Class not supported: "+clazz+":\n\t"+this);
+ }
+
+ // non public matters
+
+ protected final boolean growBufferIfNecessary(int spare) {
+ if(buffer==null || buffer.remaining()<spare) {
+ growBuffer(initialSize);
+ return true;
+ }
+ return false;
+ }
+
+ protected final void growBuffer(int additional) {
+ if(sealed || 0==additional || 0==components) return;
+
+ // add the stride delta
+ additional += (additional/components)*(strideL-components);
+
+ if(components>0) {
+ int osize = (buffer!=null)?buffer.capacity():0;
+ if(clazz==ByteBuffer.class) {
+ ByteBuffer newBBuffer = BufferUtil.newByteBuffer( (osize+additional) * components );
+ if(buffer!=null) {
+ buffer.flip();
+ newBBuffer.put((ByteBuffer)buffer);
+ }
+ buffer = newBBuffer;
+ } else if(clazz==ShortBuffer.class) {
+ ShortBuffer newSBuffer = BufferUtil.newShortBuffer( (osize+additional) * components );
+ if(buffer!=null) {
+ buffer.flip();
+ newSBuffer.put((ShortBuffer)buffer);
+ }
+ buffer = newSBuffer;
+ } else if(clazz==IntBuffer.class) {
+ IntBuffer newIBuffer = BufferUtil.newIntBuffer( (osize+additional) * components );
+ if(buffer!=null) {
+ buffer.flip();
+ newIBuffer.put((IntBuffer)buffer);
+ }
+ buffer = newIBuffer;
+ } else if(clazz==FloatBuffer.class) {
+ FloatBuffer newFBuffer = BufferUtil.newFloatBuffer( (osize+additional) * components );
+ if(buffer!=null) {
+ buffer.flip();
+ newFBuffer.put((FloatBuffer)buffer);
+ }
+ buffer = newFBuffer;
+ } else {
+ throw new GLException("Given Buffer Class not supported: "+clazz+":\n\t"+this);
+ }
+ }
+ }
+
+ protected final void checkSeal(boolean test) throws GLException {
+ if(sealed!=test) {
+ if(test) {
+ throw new GLException("Not Sealed yet, seal first:\n\t"+this);
+ } else {
+ throw new GLException("Already Sealed, can't modify VBO:\n\t"+this);
+ }
+ }
+ }
+
+ protected void init(String name, int index, int comps, int dataType, boolean normalized, int stride, Buffer data,
+ int initialSize, boolean isVertexAttribute)
+ throws GLException
+ {
+ this.isVertexAttribute = isVertexAttribute;
+ this.index = index;
+ this.location = -1;
+ this.name = (null==name)?GLContext.getPredefinedArrayIndexName(index):name;
+ if(null==this.name) {
+ throw new GLException("Not a valid GL array index: "+index);
+ }
+ this.dataType = dataType;
+ this.clazz = getBufferClass(dataType);
+ switch(dataType) {
+ case GL.GL_BYTE:
+ case GL.GL_UNSIGNED_BYTE:
+ case GL.GL_SHORT:
+ case GL.GL_UNSIGNED_SHORT:
+ case GL2ES1.GL_FIXED:
+ this.normalized = normalized;
+ break;
+ default:
+ this.normalized = false;
+ }
+
+ int bpc = getBufferCompSize();
+ if(0<stride && stride<comps*bpc) {
+ throw new GLException("stride ("+stride+") lower than component bytes, "+comps+" * "+bpc);
+ }
+ if(0<stride && stride%bpc!=0) {
+ throw new GLException("stride ("+stride+") not a multiple of bpc "+bpc);
+ }
+ this.buffer = data;
+ this.components = comps;
+ this.stride=stride;
+ this.strideB=(0==stride)?comps*bpc:stride;
+ this.strideL=(0==stride)?comps:strideB/bpc;
+ this.initialSize = initialSize;
+ this.sealed=false;
+ this.sealedGL=false;
+ this.bufferEnabled=false;
+ this.bufferWritten=false;
+ if(null==buffer) {
+ growBuffer(initialSize);
+ }
+ }
+
+ protected void enableBufferGLImpl(GL gl, boolean enable) {
+ if(enable) {
+ gl.glEnableClientState(index);
+ bufferEnabled = true;
+
+ switch(index) {
+ case GL.GL_VERTEX_ARRAY:
+ gl.glVertexPointer(this);
+ break;
+ case GL.GL_NORMAL_ARRAY:
+ gl.glNormalPointer(this);
+ break;
+ case GL.GL_COLOR_ARRAY:
+ gl.glColorPointer(this);
+ break;
+ case GL.GL_TEXTURE_COORD_ARRAY:
+ gl.glTexCoordPointer(this);
+ break;
+ default:
+ throw new GLException("invalid glArrayIndex: "+index+":\n\t"+this);
+ }
+ bufferWritten=true;
+ } else {
+ gl.glDisableClientState(index);
+ bufferEnabled = false;
+ }
+ }
+
+ protected void init_vbo(GL gl) {}
+
+ protected GLArrayDataClient() { }
+
+ protected int index;
+ protected int location;
+ protected String name;
+ protected int components;
+ protected int dataType;
+ protected boolean normalized;
+ protected int stride; // user given stride
+ protected int strideB; // stride in bytes
+ protected int strideL; // stride in logical components
+ protected Class clazz;
+ protected Buffer buffer;
+ protected int initialSize;
+ protected boolean isVertexAttribute;
+ protected boolean sealed, sealedGL;
+ protected boolean bufferEnabled;
+ protected boolean bufferWritten;
+}
+
diff --git a/src/classes/javax/media/opengl/GLArrayDataServer.java b/src/classes/javax/media/opengl/GLArrayDataServer.java
new file mode 100644
index 000000000..d4f2604fd
--- /dev/null
+++ b/src/classes/javax/media/opengl/GLArrayDataServer.java
@@ -0,0 +1,265 @@
+
+package javax.media.opengl;
+
+import javax.media.opengl.*;
+import java.nio.*;
+import com.sun.opengl.impl.*;
+
+public class GLArrayDataServer extends GLArrayDataClient implements GLArrayData {
+
+ //
+ // lifetime matters
+ //
+
+ /**
+ * Create a VBOBuffer object, using a predefined fixed function array index
+ * and starting with a given Buffer object incl it's stride
+ *
+ * On profiles GL2 and ES1 the fixed function pipeline behavior is as expected.
+ * On profile ES2 the fixed function emulation will transform these calls to
+ * EnableVertexAttribArray and VertexAttribPointer calls,
+ * and a predefined vertex attribute variable name will be choosen.
+ *
+ * @arg index The GL array index
+ * @arg name The optional custom name for the GL array index, maybe null.
+ * If null, the default name mapping will be used, see 'getPredefinedArrayIndexName(int)'.
+ * This name might be used as the shader attribute name.
+ * @arg comps The array component number
+ * @arg dataType The array index GL data type
+ * @arg normalized Wheather the data shall be normalized
+ *
+ * @see javax.media.opengl.GLContext#getPredefinedArrayIndexName(int)
+ */
+ public static GLArrayDataServer createFixed(int index, String name, int comps, int dataType, boolean normalized,
+ int stride, Buffer buffer, int glBufferUsage)
+ throws GLException
+ {
+ GLProfile.isValidateArrayDataType(index, comps, dataType, false, true);
+
+ GLArrayDataServer ads = new GLArrayDataServer();
+ ads.init(name, index, comps, dataType, normalized, stride, buffer, 0, buffer.limit(), glBufferUsage, false);
+ return ads;
+ }
+
+ /**
+ * Create a VBOBuffer object, using a predefined fixed function array index
+ * and starting with a new created Buffer object with initialSize size
+ *
+ * On profiles GL2 and ES1 the fixed function pipeline behavior is as expected.
+ * On profile ES2 the fixed function emulation will transform these calls to
+ * EnableVertexAttribArray and VertexAttribPointer calls,
+ * and a predefined vertex attribute variable name will be choosen.
+ *
+ * @see javax.media.opengl.GLContext#getPredefinedArrayIndexName(int)
+ */
+ public static GLArrayDataServer createFixed(int index, String name, int comps, int dataType, boolean normalized,
+ int initialSize, int glBufferUsage)
+ throws GLException
+ {
+ GLProfile.isValidateArrayDataType(index, comps, dataType, false, true);
+
+ GLArrayDataServer ads = new GLArrayDataServer();
+ ads.init(name, index, comps, dataType, normalized, 0, null, 0, initialSize, glBufferUsage, false);
+ return ads;
+ }
+
+ /**
+ * Create a VBOBuffer object, using a predefined fixed function array index
+ * and starting with a given Buffer offset incl it's stride
+ *
+ * This object can neither be enabled, nor rendered, since no knowledge of the buffer
+ * itself is available. This object is only a VBO variant of GLArrayData
+ * and cannot being drawn.
+ *
+ * @see javax.media.opengl.GLContext#getPredefinedArrayIndexName(int)
+ */
+ public static GLArrayDataServer createFixed(int index, String name, int comps, int dataType, boolean normalized,
+ int stride, long bufferOffset)
+ throws GLException
+ {
+ GLProfile.isValidateArrayDataType(index, comps, dataType, false, true);
+
+ GLArrayDataServer ads = new GLArrayDataServer();
+ ads.init(name, index, comps, dataType, normalized, stride, null, bufferOffset, 0, -1, false);
+ return ads;
+ }
+
+ /**
+ * Create a VBOBuffer object, using a custom GLSL array attribute name
+ * and starting with a new created Buffer object with initialSize size
+ *
+ * @see javax.media.opengl.GLContext#getPredefinedArrayIndexName(int)
+ */
+ public static GLArrayDataServer createGLSL(String name, int comps, int dataType, boolean normalized,
+ int initialSize, int glBufferUsage)
+ throws GLException
+ {
+ GLProfile.isValidateArrayDataType(-1, comps, dataType, true, true);
+ Class[] types = new Class[]{ String.class, int.class, int.class, boolean.class, int.class, int.class };
+ Object[] args = new Object[]{ name, new Integer(comps), new Integer(dataType),
+ new Boolean(normalized), new Integer(initialSize), new Integer(glBufferUsage) } ;
+
+ if(GLProfile.isGL2ES2()) {
+ return (GLArrayDataServer) GLReflection.createInstance("com.sun.opengl.impl.glsl.GLSLArrayDataServer", types, args);
+ }
+ throw new GLException("GLArrayDataServer not supported for profile: "+GLProfile.getProfile());
+ }
+
+ /**
+ * Create a VBOBuffer object, using a custom GLSL array attribute name
+ * and starting with a given Buffer object incl it's stride
+ *
+ * @see javax.media.opengl.GLContext#getPredefinedArrayIndexName(int)
+ */
+ public static GLArrayDataServer createGLSL(String name, int comps, int dataType, boolean normalized,
+ int stride, Buffer buffer, int glBufferUsage)
+ throws GLException
+ {
+ GLProfile.isValidateArrayDataType(-1, comps, dataType, true, true);
+ Class[] types = new Class[]{ String.class, int.class, int.class, boolean.class, int.class, Buffer.class, int.class };
+ Object[] args = new Object[]{ name, new Integer(comps), new Integer(dataType),
+ new Boolean(normalized), new Integer(stride), buffer, new Integer(glBufferUsage) } ;
+
+ if(GLProfile.isGL2ES2()) {
+ return (GLArrayDataServer) GLReflection.createInstance("com.sun.opengl.impl.glsl.GLSLArrayDataServer", types, args);
+ }
+ throw new GLException("GLArrayDataServer not supported for profile: "+GLProfile.getProfile());
+ }
+
+ //
+ // Data matters GLArrayData
+ //
+
+ public long getOffset() { return vboUsage?bufferOffset:-1; }
+
+ public boolean isVBO() { return vboUsage; }
+
+ //
+ // Data and GL state modification ..
+ //
+
+ public void destroy(GL gl) {
+ super.destroy(gl);
+ if(vboName!=0) {
+ int[] tmp = new int[1];
+ tmp[0] = vboName;
+ gl.glDeleteBuffers(1, tmp, 0);
+ vboName = 0;
+ }
+ }
+
+ //
+ // data matters
+ //
+
+ /**
+ * Convenient way do disable the VBO behavior and
+ * switch to client side data one
+ * Only possible if buffer is defined.
+ */
+ public void setVBOUsage(boolean vboUsage) {
+ checkSeal(false);
+ this.vboUsage=(null!=buffer)?vboUsage:true;
+ }
+
+ public int getBufferUsage() {
+ return glBufferUsage;
+ }
+
+ public String toString() {
+ return "GLArrayDataServer["+name+
+ ", index "+index+
+ ", location "+location+
+ ", isVertexAttribute "+isVertexAttribute+
+ ", dataType "+dataType+
+ ", bufferClazz "+clazz+
+ ", vertices "+getVerticeNumber()+
+ ", components "+components+
+ ", stride "+stride+"u "+strideB+"b "+strideL+"c"+
+ ", initialSize "+initialSize+
+ ", glBufferUsage "+glBufferUsage+
+ ", vboUsage "+vboUsage+
+ ", vboName "+vboName+
+ ", sealed "+sealed+
+ ", bufferEnabled "+bufferEnabled+
+ ", bufferWritten "+bufferWritten+
+ ", buffer "+buffer+
+ ", offset "+bufferOffset+
+ "]";
+ }
+
+ //
+ // non public matters ..
+ //
+
+ protected void init(String name, int index, int comps, int dataType, boolean normalized,
+ int stride, Buffer data, long offset, int initialSize, int glBufferUsage, boolean isVertexAttribute)
+ throws GLException
+ {
+ super.init(name, index, comps, dataType, normalized, stride, data, initialSize, isVertexAttribute);
+
+ vboUsage=true;
+
+ if( ! (GLProfile.isGL2ES2() && glBufferUsage==GL2ES2.GL_STREAM_DRAW) ) {
+ switch(glBufferUsage) {
+ case -1: // nop
+ case GL2ES1.GL_STATIC_DRAW:
+ case GL2ES1.GL_DYNAMIC_DRAW:
+ break;
+ default:
+ throw new GLException("invalid glBufferUsage: "+glBufferUsage+":\n\t"+this);
+ }
+ }
+ this.bufferOffset=offset;
+ this.glBufferUsage = glBufferUsage;
+ this.vboName = 0;
+ }
+
+ protected void enableBufferGLImpl(GL gl, boolean enable) {
+ if(enable) {
+ gl.glEnableClientState(index);
+ bufferEnabled = true;
+
+ if(vboUsage) {
+ gl.glBindBuffer(GL.GL_ARRAY_BUFFER, vboName);
+ if(!bufferWritten) {
+ gl.glBufferData(GL.GL_ARRAY_BUFFER, buffer.limit() * getBufferCompSize(), buffer, glBufferUsage);
+ }
+ }
+ switch(index) {
+ case GL.GL_VERTEX_ARRAY:
+ gl.glVertexPointer(this);
+ break;
+ case GL.GL_NORMAL_ARRAY:
+ gl.glNormalPointer(this);
+ break;
+ case GL.GL_COLOR_ARRAY:
+ gl.glColorPointer(this);
+ break;
+ case GL.GL_TEXTURE_COORD_ARRAY:
+ gl.glTexCoordPointer(this);
+ break;
+ default:
+ throw new GLException("invalid glArrayIndex: "+index+":\n\t"+this);
+ }
+ bufferWritten=true;
+ } else {
+ gl.glDisableClientState(index);
+ bufferEnabled = false;
+ }
+ }
+ protected void init_vbo(GL gl) {
+ if(vboUsage && vboName==0) {
+ int[] tmp = new int[1];
+ gl.glGenBuffers(1, tmp, 0);
+ vboName = tmp[0];
+ }
+ }
+
+ protected long bufferOffset;
+ protected int glBufferUsage;
+ protected int vboName;
+ protected boolean vboUsage;
+
+}
+
diff --git a/src/classes/javax/media/opengl/GLContext.java b/src/classes/javax/media/opengl/GLContext.java
index 02345ef04..998ede419 100644
--- a/src/classes/javax/media/opengl/GLContext.java
+++ b/src/classes/javax/media/opengl/GLContext.java
@@ -193,4 +193,63 @@ public abstract class GLContext {
"(GL: "+getGL().getClass().getName()+","+
" Factory: "+ getGLDrawable().getFactory().getClass().getName()+")";
}
+
+ /**
+ * Mapping fixed function (client) array indices to
+ * GLSL array attribute names.
+ *
+ * Useful for uniq mapping of canonical array index names as listed.
+ *
+ * @see #mgl_Vertex
+ * @see javax.media.opengl.GL#GL_VERTEX_ARRAY
+ * @see #mgl_Normal
+ * @see javax.media.opengl.GL#GL_NORMAL_ARRAY
+ * @see #mgl_Color
+ * @see javax.media.opengl.GL#GL_COLOR_ARRAY
+ * @see #mgl_MultiTexCoord
+ * @see javax.media.opengl.GL#GL_TEXTURE_COORD_ARRAY
+ * @see javax.media.opengl.GL#glEnableClientState
+ * @see javax.media.opengl.GL#glVertexPointer
+ * @see javax.media.opengl.GL#glColorPointer
+ * @see javax.media.opengl.GL#glNormalPointer
+ * @see javax.media.opengl.GL#glTexCoordPointer
+ */
+ public static String getPredefinedArrayIndexName(int glArrayIndex) {
+ switch(glArrayIndex) {
+ case GL.GL_VERTEX_ARRAY:
+ return mgl_Vertex;
+ case GL.GL_NORMAL_ARRAY:
+ return mgl_Normal;
+ case GL.GL_COLOR_ARRAY:
+ return mgl_Color;
+ case GL.GL_TEXTURE_COORD_ARRAY:
+ return mgl_MultiTexCoord;
+ }
+ return null;
+ }
+
+ /**
+ * String name for
+ * @see javax.media.opengl.GL#GL_VERTEX_ARRAY
+ */
+ public static final String mgl_Vertex = "mgl_Vertex";
+
+ /**
+ * String name for
+ * @see javax.media.opengl.GL#GL_NORMAL_ARRAY
+ */
+ public static final String mgl_Normal = "mgl_Normal";
+
+ /**
+ * String name for
+ * @see javax.media.opengl.GL#GL_COLOR_ARRAY
+ */
+ public static final String mgl_Color = "mgl_Color";
+
+ /**
+ * String name for
+ * @see javax.media.opengl.GL#GL_TEXTURE_COORD_ARRAY
+ */
+ public static final String mgl_MultiTexCoord = "mgl_MultiTexCoord" ;
+
}
diff --git a/src/classes/javax/media/opengl/GLProfile.java b/src/classes/javax/media/opengl/GLProfile.java
index ff68a6d38..67e427f5a 100644
--- a/src/classes/javax/media/opengl/GLProfile.java
+++ b/src/classes/javax/media/opengl/GLProfile.java
@@ -212,4 +212,306 @@ public class GLProfile {
throw new GLUnsupportedException("unsupported profile \"" + profile + "\"");
}
}
+
+ /**
+ * General validation if type is a valid GL data type
+ * for the current profile
+ */
+ public static boolean isValidDataType(int type, boolean throwException) {
+ switch(type) {
+ case GL.GL_UNSIGNED_BYTE:
+ case GL.GL_BYTE:
+ case GL.GL_UNSIGNED_SHORT:
+ case GL.GL_SHORT:
+ case GL.GL_FLOAT:
+ case GL.GL_FIXED:
+ return true;
+ case javax.media.opengl.GL2ES2.GL_INT:
+ case javax.media.opengl.GL2ES2.GL_UNSIGNED_INT:
+ if( isGL2ES2() ) {
+ return true;
+ }
+ case javax.media.opengl.GL2.GL_DOUBLE:
+ case javax.media.opengl.GL2.GL_2_BYTES:
+ case javax.media.opengl.GL2.GL_3_BYTES:
+ case javax.media.opengl.GL2.GL_4_BYTES:
+ if( isGL2ES12() || isGL2() ) {
+ return true;
+ }
+ }
+ if(throwException) {
+ throw new GLException("Illegal data type on profile "+GLProfile.getProfile()+": "+type);
+ }
+ return false;
+ }
+
+ public static boolean isValidateArrayDataType(int index, int comps, int type,
+ boolean isVertexAttribPointer, boolean throwException) {
+ String indexName = GLContext.getPredefinedArrayIndexName(index);
+ if(GLProfile.isGLES1()) {
+ if(isVertexAttribPointer) {
+ if(throwException) {
+ throw new GLException("Illegal array type for "+indexName+" on profile GLES1: VertexAttribPointer");
+ }
+ return false;
+ }
+ switch(index) {
+ case GL.GL_VERTEX_ARRAY:
+ case GL.GL_TEXTURE_COORD_ARRAY:
+ switch(type) {
+ case GL.GL_BYTE:
+ case GL.GL_SHORT:
+ case GL.GL_FIXED:
+ case GL.GL_FLOAT:
+ break;
+ default:
+ if(throwException) {
+ throw new GLException("Illegal data type for "+indexName+" on profile GLES1: "+type);
+ }
+ return false;
+ }
+ switch(comps) {
+ case 0:
+ case 2:
+ case 3:
+ case 4:
+ break;
+ default:
+ if(throwException) {
+ throw new GLException("Illegal component number for "+indexName+" on profile GLES1: "+comps);
+ }
+ return false;
+ }
+ break;
+ case GL.GL_NORMAL_ARRAY:
+ switch(type) {
+ case GL.GL_BYTE:
+ case GL.GL_SHORT:
+ case GL.GL_FIXED:
+ case GL.GL_FLOAT:
+ break;
+ default:
+ if(throwException) {
+ throw new GLException("Illegal data type for "+indexName+" on profile GLES1: "+type);
+ }
+ return false;
+ }
+ switch(comps) {
+ case 0:
+ case 3:
+ break;
+ default:
+ if(throwException) {
+ throw new GLException("Illegal component number for "+indexName+" on profile GLES1: "+comps);
+ }
+ return false;
+ }
+ break;
+ case GL.GL_COLOR_ARRAY:
+ switch(type) {
+ case GL.GL_UNSIGNED_BYTE:
+ case GL.GL_FIXED:
+ case GL.GL_FLOAT:
+ break;
+ default:
+ if(throwException) {
+ throw new GLException("Illegal data type for "+indexName+" on profile GLES1: "+type);
+ }
+ return false;
+ }
+ switch(comps) {
+ case 0:
+ case 4:
+ break;
+ default:
+ if(throwException) {
+ throw new GLException("Illegal component number for "+indexName+" on profile GLES1: "+comps);
+ }
+ return false;
+ }
+ break;
+ }
+ } else if(GLProfile.isGLES2()) {
+ // simply ignore !isVertexAttribPointer case, since it is simulated anyway ..
+
+ switch(type) {
+ case GL.GL_UNSIGNED_BYTE:
+ case GL.GL_BYTE:
+ case GL.GL_UNSIGNED_SHORT:
+ case GL.GL_SHORT:
+ case GL.GL_FLOAT:
+ case GL.GL_FIXED:
+ break;
+ default:
+ if(throwException) {
+ throw new GLException("Illegal data type for "+indexName+" on profile GLES2: "+type);
+ }
+ return false;
+ }
+ switch(comps) {
+ case 0:
+ case 1:
+ case 2:
+ case 3:
+ case 4:
+ break;
+ default:
+ if(throwException) {
+ throw new GLException("Illegal component number for "+indexName+" on profile GLES1: "+comps);
+ }
+ return false;
+ }
+ } else if(GLProfile.isGL2ES12() || GLProfile.isGL2()) {
+ if(isVertexAttribPointer) {
+ switch(index) {
+ case GL.GL_VERTEX_ARRAY:
+ case GL.GL_TEXTURE_COORD_ARRAY:
+ case GL.GL_NORMAL_ARRAY:
+ case GL.GL_COLOR_ARRAY:
+ switch(type) {
+ case GL.GL_UNSIGNED_BYTE:
+ case GL.GL_BYTE:
+ case GL.GL_UNSIGNED_SHORT:
+ case GL.GL_SHORT:
+ case GL.GL_FLOAT:
+ case javax.media.opengl.GL2ES2.GL_INT:
+ case javax.media.opengl.GL2ES2.GL_UNSIGNED_INT:
+ case javax.media.opengl.GL2.GL_DOUBLE:
+ break;
+ default:
+ if(throwException) {
+ throw new GLException("Illegal data type for "+indexName+" on profile GL2: "+type);
+ }
+ return false;
+ }
+ switch(comps) {
+ case 0:
+ case 1:
+ case 2:
+ case 3:
+ case 4:
+ break;
+ default:
+ if(throwException) {
+ throw new GLException("Illegal component number for "+indexName+" on profile GL2: "+comps);
+ }
+ return false;
+ }
+ break;
+ }
+ } else {
+ switch(index) {
+ case GL.GL_VERTEX_ARRAY:
+ switch(type) {
+ case GL.GL_SHORT:
+ case GL.GL_FLOAT:
+ case javax.media.opengl.GL2ES2.GL_INT:
+ case javax.media.opengl.GL2.GL_DOUBLE:
+ break;
+ default:
+ if(throwException) {
+ throw new GLException("Illegal data type for "+indexName+" on profile GL2: "+type);
+ }
+ return false;
+ }
+ switch(comps) {
+ case 0:
+ case 2:
+ case 3:
+ case 4:
+ break;
+ default:
+ if(throwException) {
+ throw new GLException("Illegal component number for "+indexName+" on profile GL2: "+comps);
+ }
+ return false;
+ }
+ break;
+ case GL.GL_NORMAL_ARRAY:
+ switch(type) {
+ case GL.GL_BYTE:
+ case GL.GL_SHORT:
+ case GL.GL_FLOAT:
+ case javax.media.opengl.GL2ES2.GL_INT:
+ case javax.media.opengl.GL2.GL_DOUBLE:
+ break;
+ default:
+ if(throwException) {
+ throw new GLException("Illegal data type for "+indexName+" on profile GL2: "+type);
+ }
+ return false;
+ }
+ switch(comps) {
+ case 0:
+ case 3:
+ break;
+ default:
+ if(throwException) {
+ throw new GLException("Illegal component number for "+indexName+" on profile GLES1: "+comps);
+ }
+ return false;
+ }
+ break;
+ case GL.GL_COLOR_ARRAY:
+ switch(type) {
+ case GL.GL_UNSIGNED_BYTE:
+ case GL.GL_BYTE:
+ case GL.GL_UNSIGNED_SHORT:
+ case GL.GL_SHORT:
+ case GL.GL_FLOAT:
+ case javax.media.opengl.GL2ES2.GL_INT:
+ case javax.media.opengl.GL2ES2.GL_UNSIGNED_INT:
+ case javax.media.opengl.GL2.GL_DOUBLE:
+ break;
+ default:
+ if(throwException) {
+ throw new GLException("Illegal data type for "+indexName+" on profile GL2: "+type);
+ }
+ return false;
+ }
+ switch(comps) {
+ case 0:
+ case 3:
+ case 4:
+ break;
+ default:
+ if(throwException) {
+ throw new GLException("Illegal component number for "+indexName+" on profile GL2: "+comps);
+ }
+ return false;
+ }
+ break;
+ case GL.GL_TEXTURE_COORD_ARRAY:
+ switch(type) {
+ case GL.GL_SHORT:
+ case GL.GL_FLOAT:
+ case javax.media.opengl.GL2ES2.GL_INT:
+ case javax.media.opengl.GL2.GL_DOUBLE:
+ break;
+ default:
+ if(throwException) {
+ throw new GLException("Illegal data type for "+indexName+" on profile GL2: "+type);
+ }
+ return false;
+ }
+ switch(comps) {
+ case 0:
+ case 1:
+ case 2:
+ case 3:
+ case 4:
+ break;
+ default:
+ if(throwException) {
+ throw new GLException("Illegal component number for "+indexName+" on profile GL2: "+comps);
+ }
+ return false;
+ }
+ break;
+ }
+ }
+ }
+ return true;
+ }
+
}
diff --git a/src/classes/javax/media/opengl/GLUniformData.java b/src/classes/javax/media/opengl/GLUniformData.java
new file mode 100644
index 000000000..929a59a2a
--- /dev/null
+++ b/src/classes/javax/media/opengl/GLUniformData.java
@@ -0,0 +1,159 @@
+
+package javax.media.opengl;
+
+import java.nio.*;
+
+public class GLUniformData {
+
+ /**
+ * int atom
+ *
+ * Number of objects is 1
+ *
+ * @arg components number of elements of one object, ie 4 for GL_FLOAT_VEC4,
+ */
+ public GLUniformData(String name, int val) {
+ init(name, 1, new Integer(val));
+ }
+
+ /**
+ * float atom
+ *
+ * Number of objects is 1
+ *
+ * @arg components number of elements of one object, ie 4 for GL_FLOAT_VEC4,
+ */
+ public GLUniformData(String name, float val) {
+ init(name, 1, new Float(val));
+ }
+
+ /**
+ * Multiple IntBuffer Vector
+ *
+ * Number of objects is calculated by data.limit()/components
+ *
+ * @arg components number of elements of one object, ie 4 for GL_FLOAT_VEC4,
+ */
+ public GLUniformData(String name, int components, IntBuffer data) {
+ init(name, components, data);
+ }
+
+ /**
+ * Multiple FloatBuffer Vector
+ *
+ * Number of objects is calculated by data.limit()/components
+ *
+ * @arg components number of elements of one object, ie 4 for GL_FLOAT_VEC4,
+ */
+ public GLUniformData(String name, int components, FloatBuffer data) {
+ init(name, components, data);
+ }
+
+ /**
+ * Multiple FloatBuffer Matrix
+ *
+ * Number of objects is calculated by data.limit()/(rows*columns)
+ *
+ * @arg rows the matrix rows
+ * @arg column the matrix column
+ */
+ public GLUniformData(String name, int rows, int columns, FloatBuffer data) {
+ init(name, rows, columns, data);
+ }
+
+ public void setData(int data) { init(new Integer(data)); }
+ public void setData(float data) { init(new Float(data)); }
+ public void setData(IntBuffer data) { init(data); }
+ public void setData(FloatBuffer data) { init(data); }
+
+ public int intValue() { return ((Integer)data).intValue(); };
+ public float floatValue() { return ((Float)data).floatValue(); };
+ public IntBuffer intBufferValue() { return (IntBuffer)data; };
+ public FloatBuffer floatBufferValue() { return (FloatBuffer)data; };
+
+ public String toString() {
+ return "GLUniformData[name "+name+
+ ", location "+location+
+ ", size "+rows+"*"+columns+
+ ", count "+count+
+ ", matrix "+isMatrix+
+ ", data "+data+
+ "]";
+ }
+
+ private void init(String name, int rows, int columns, Object data) {
+ if( 2>rows || rows>4 || 2>columns || columns>4 ) {
+ throw new GLException("rowsXcolumns must be within [2..4]X[2..4], is: "+rows+"X"+columns);
+ }
+ this.name=name;
+ this.rows=rows;
+ this.columns=columns;
+ this.isMatrix=true;
+ this.location=-1;
+ init(data);
+ }
+
+ private void init(String name, int components, Object data) {
+ if( 1>components || components>4 ) {
+ throw new GLException("components must be within [1..4], is: "+components);
+ }
+ this.name=name;
+ this.columns=components;
+ this.rows=1;
+ this.isMatrix=false;
+ this.location=-1;
+ init(data);
+ }
+
+ private void init(Object data) {
+ if(data instanceof Buffer) {
+ int sz = rows*columns;
+ Buffer buffer = (Buffer)data;
+ if(buffer.limit()<sz || 0!=buffer.limit()%sz) {
+ throw new GLException("data buffer size invalid: new buffer limit: "+buffer.limit()+"\n\t"+this);
+ }
+ this.count=buffer.limit()/(rows*columns);
+ } else {
+ if(isMatrix) {
+ throw new GLException("Atom type not allowed for matrix : "+this);
+ }
+ this.count=1;
+ }
+ this.data=data;
+ }
+
+ public String getName() { return name; }
+
+ public int getLocation() { return location; }
+
+ /**
+ * Sets the determined location of the shader uniform
+ * This is usually done within ShaderState.
+ *
+ * @see javax.media.opengl.util.glsl.ShaderState#glUniform(GL2ES2, GLUniformData)
+ */
+ public void setLocation(int location) { this.location=location; }
+
+ public Object getObject() {
+ return data;
+ }
+ public Buffer getBuffer() {
+ return (data instanceof Buffer)?(Buffer)data:null;
+ }
+ public boolean isBuffer() {
+ return (data instanceof Buffer);
+ }
+ public boolean isMatrix() { return isMatrix; }
+
+ public int count() { return count; }
+ public int components() { return rows*columns; }
+ public int rows() { return rows; }
+ public int columns() { return columns; }
+
+ private String name;
+ private int location;
+ private int rows, columns;
+ private int count;
+ private Object data;
+ private boolean isMatrix;
+}
diff --git a/src/classes/javax/media/opengl/util/ImmModeSink.java b/src/classes/javax/media/opengl/util/ImmModeSink.java
index 459372d94..5de9df99a 100644
--- a/src/classes/javax/media/opengl/util/ImmModeSink.java
+++ b/src/classes/javax/media/opengl/util/ImmModeSink.java
@@ -2,6 +2,7 @@
package javax.media.opengl.util;
import javax.media.opengl.*;
+import com.sun.opengl.impl.GLReflection;
import java.nio.*;
import java.util.Iterator;
import java.util.ArrayList;
@@ -10,24 +11,39 @@ public class ImmModeSink {
public static final boolean DEBUG_BEGIN_END = false;
public static final boolean DEBUG_DRAW = false;
- public static final boolean FLOAT2FIXED = false;
- public static final int GL_QUADS = 0x0007;
+ // public static final int GL_QUADS = 0x0007; // Needs data manipulation
public static final int GL_QUAD_STRIP = 0x0008;
public static final int GL_POLYGON = 0x0009;
- public ImmModeSink(int glDataType, int glDrawUsage,
- int vComps, int nComps, int cComps, int tComps, int initialSize) {
-
- vboSet = new VBOSet(glDataType, glDrawUsage, vComps, nComps, cComps, tComps, initialSize);
- this.vboSetList = new ArrayList();
+ /**
+ * Uses a GL2ES1, or ES2 fixed function emulation immediate mode sink
+ */
+ public static ImmModeSink createFixed(int glBufferUsage, int initialSize,
+ int vComps, int vDataType,
+ int cComps, int cDataType,
+ int nComps, int nDataType,
+ int tComps, int tDataType) {
+ return new ImmModeSink(glBufferUsage, initialSize,
+ vComps, vDataType, cComps, cDataType, nComps, nDataType, tComps, tDataType, false);
}
- private void destroyList(GL gl) {
- for(Iterator i=vboSetList.iterator(); i.hasNext() ; ) {
- ((VBOSet)i.next()).destroy(gl);
- }
- vboSetList.clear();
+ /**
+ * Uses a GL2ES2 GLSL shader immediate mode sink.
+ * To issue the draw() command,
+ * 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()
+ */
+ public static ImmModeSink createGLSL(int glBufferUsage, int initialSize,
+ int vComps, int vDataType,
+ int cComps, int cDataType,
+ int nComps, int nDataType,
+ int tComps, int tDataType) {
+ return new ImmModeSink(glBufferUsage, initialSize,
+ vComps, vDataType, cComps, cDataType, nComps, nDataType, tComps, tDataType, true);
}
public void destroy(GL gl) {
@@ -46,9 +62,20 @@ public class ImmModeSink {
}
public String toString() {
- return "ImmModeSink[listsz: "+vboSetList.size()+
- ",\n"+vboSet+
- "]";
+ StringBuffer sb = new StringBuffer("ImmModeSink[");
+ sb.append(",\n\tVBO list: "+vboSetList.size()+" [");
+ for(Iterator i=vboSetList.iterator(); i.hasNext() ; ) {
+ sb.append("\n\t");
+ sb.append( (VBOSet)i.next() );
+ }
+ if(vboSetList.size()>0) {
+ sb.append("\n\t],\nVBO current: NOP]");
+ } else {
+ sb.append("\n\t],\nVBO current: \n");
+ sb.append(vboSet);
+ sb.append("\n]");
+ }
+ return sb.toString();
}
public void draw(GL gl, boolean disableBufferAfterDraw) {
@@ -58,7 +85,18 @@ public class ImmModeSink {
}
int n=0;
for(Iterator i=vboSetList.iterator(); i.hasNext() ; n++) {
- ((VBOSet)i.next()).draw(gl, disableBufferAfterDraw, n);
+ ((VBOSet)i.next()).draw(gl, null, disableBufferAfterDraw, n);
+ }
+ }
+
+ public void draw(GL gl, Buffer indices, boolean disableBufferAfterDraw) {
+ if(DEBUG_DRAW) {
+ Exception e = new Exception("ImmModeSink.draw(disableBufferAfterDraw: "+disableBufferAfterDraw+"):\n\t"+this);
+ e.printStackTrace();
+ }
+ int n=0;
+ for(Iterator i=vboSetList.iterator(); i.hasNext() ; n++) {
+ ((VBOSet)i.next()).draw(gl, indices, disableBufferAfterDraw, n);
}
}
@@ -69,9 +107,10 @@ public class ImmModeSink {
}
vboSet.modeOrig = mode;
switch(mode) {
- case GL_QUADS:
- mode=GL.GL_TRIANGLE_STRIP;
- break;
+ // Needs data manipulation ..
+ //case GL_QUADS:
+ // mode=GL.GL_LINES;
+ // break;
case GL_QUAD_STRIP:
mode=GL.GL_TRIANGLE_STRIP;
break;
@@ -84,17 +123,25 @@ public class ImmModeSink {
}
public final void glEnd(GL gl) {
- glEnd(gl, true);
+ glEnd(gl, null, true);
}
public void glEnd(GL gl, boolean immediateDraw) {
+ glEnd(gl, null, immediateDraw);
+ }
+
+ public final void glEnd(GL gl, Buffer indices) {
+ glEnd(gl, indices, true);
+ }
+
+ private void glEnd(GL gl, Buffer indices, boolean immediateDraw) {
if(DEBUG_BEGIN_END) {
Exception e = new Exception("ImmModeSink START glEnd(immediate: "+immediateDraw+"):\n\t"+this);
e.printStackTrace();
}
if(immediateDraw) {
vboSet.seal(gl, false);
- vboSet.draw(gl, true, -1);
+ vboSet.draw(gl, indices, true, -1);
reset(gl);
} else {
vboSet.seal(gl, true);
@@ -103,6 +150,9 @@ public class ImmModeSink {
}
}
+ public void glVertexv(Buffer v) {
+ vboSet.glVertexv(v);
+ }
public final void glVertex2f(float x, float y) {
vboSet.glVertex2f(x,y);
}
@@ -111,14 +161,27 @@ public class ImmModeSink {
vboSet.glVertex3f(x,y,z);
}
+ public void glNormalv(Buffer v) {
+ vboSet.glNormalv(v);
+ }
public final void glNormal3f(float x, float y, float z) {
vboSet.glNormal3f(x,y,z);
}
+ public void glColorv(Buffer v) {
+ vboSet.glColorv(v);
+ }
public final void glColor3f(float x, float y, float z) {
vboSet.glColor3f(x,y,z);
}
+ public final void glColor4f(float x, float y, float z, float a) {
+ vboSet.glColor4f(x,y,z, a);
+ }
+
+ public void glTexCoordv(Buffer v) {
+ vboSet.glTexCoordv(v);
+ }
public final void glTexCoord2f(float x, float y) {
vboSet.glTexCoord2f(x,y);
}
@@ -127,29 +190,114 @@ public class ImmModeSink {
vboSet.glTexCoord3f(x,y,z);
}
+ public final void glVertex2s(short x, short y) {
+ vboSet.glVertex2s(x,y);
+ }
+
+ public final void glVertex3s(short x, short y, short z) {
+ vboSet.glVertex3s(x,y,z);
+ }
+
+ public final void glNormal3s(short x, short y, short z) {
+ vboSet.glNormal3s(x,y,z);
+ }
+
+ public final void glColor3s(short x, short y, short z) {
+ vboSet.glColor3s(x,y,z);
+ }
+
+ public final void glColor4s(short x, short y, short z, short a) {
+ vboSet.glColor4s(x,y,z,a);
+ }
+
+ public final void glTexCoord2s(short x, short y) {
+ vboSet.glTexCoord2s(x,y);
+ }
+
+ public final void glTexCoord3s(short x, short y, short z) {
+ vboSet.glTexCoord3s(x,y,z);
+ }
+
+ public final void glVertex2b(byte x, byte y) {
+ vboSet.glVertex2b(x,y);
+ }
+
+ public final void glVertex3b(byte x, byte y, byte z) {
+ vboSet.glVertex3b(x,y,z);
+ }
+
+ public final void glNormal3b(byte x, byte y, byte z) {
+ vboSet.glNormal3b(x,y,z);
+ }
+
+ public final void glColor3b(byte x, byte y, byte z) {
+ vboSet.glColor3b(x,y,z);
+ }
+
+ public final void glColor4b(byte x, byte y, byte z, byte a) {
+ vboSet.glColor4b(x,y,z,a);
+ }
+
+ public final void glTexCoord2b(byte x, byte y) {
+ vboSet.glTexCoord2b(x,y);
+ }
+
+ public final void glTexCoord3b(byte x, byte y, byte z) {
+ vboSet.glTexCoord3b(x,y,z);
+ }
+
+ protected ImmModeSink(int glBufferUsage, int initialSize,
+ int vComps, int vDataType,
+ int cComps, int cDataType,
+ int nComps, int nDataType,
+ int tComps, int tDataType, boolean useGLSL) {
+ if(useGLSL && !GLProfile.isGL2ES2()) {
+ throw new GLException("ImmModeSink GLSL usage not supported for profile: "+GLProfile.getProfile());
+ }
+ vboSet = new VBOSet(glBufferUsage, initialSize,
+ vComps, vDataType, cComps, cDataType, nComps, nDataType, tComps, tDataType, useGLSL);
+ this.vboSetList = new ArrayList();
+ }
+
+ private void destroyList(GL gl) {
+ for(Iterator i=vboSetList.iterator(); i.hasNext() ; ) {
+ ((VBOSet)i.next()).destroy(gl);
+ }
+ vboSetList.clear();
+ }
+
private VBOSet vboSet;
private ArrayList vboSetList;
protected static class VBOSet {
- protected VBOSet(int glDataType, int glDrawUsage,
- int vComps, int nComps, int cComps, int tComps, int initialSize) {
- nComps = 0;
- tComps = 0;
- if(FLOAT2FIXED && glDataType==GL.GL_FLOAT) {
- glDataType=GL2ES1.GL_FIXED;
- }
- this.glDataType=glDataType;
- this.glDrawUsage=glDrawUsage;
+ protected VBOSet (int glBufferUsage, int initialSize,
+ int vComps, int vDataType,
+ int cComps, int cDataType,
+ int nComps, int nDataType,
+ int tComps, int tDataType, boolean useGLSL) {
+ this.glBufferUsage=glBufferUsage;
+ this.initialSize=initialSize;
+ this.vDataType=vDataType;
this.vComps=vComps;
- this.nComps=nComps;
+ this.cDataType=cDataType;
this.cComps=cComps;
+ this.nDataType=nDataType;
+ this.nComps=nComps;
+ this.tDataType=tDataType;
this.tComps=tComps;
- this.initialSize=initialSize;
-
- this.vertexVBO = VBOBufferDraw.create(GL2ES1.GL_VERTEX_ARRAY, glDataType, glDrawUsage, vComps, initialSize);
- this.normalVBO = VBOBufferDraw.create(GL2ES1.GL_NORMAL_ARRAY, glDataType, glDrawUsage, nComps, initialSize);
- this.colorVBO = VBOBufferDraw.create(GL2ES1.GL_COLOR_ARRAY, glDataType, glDrawUsage, cComps, initialSize);
- this.texcoordVBO = VBOBufferDraw.create(GL2ES1.GL_TEXTURE_COORD_ARRAY, glDataType, glDrawUsage, tComps, initialSize);
+ this.useGLSL=useGLSL;
+
+ if(!useGLSL) {
+ this.vertexVBO = GLArrayDataServer.createFixed(GL.GL_VERTEX_ARRAY, null, vComps, vDataType, false, initialSize, glBufferUsage);
+ this.colorVBO = GLArrayDataServer.createFixed(GL.GL_COLOR_ARRAY, null, cComps, cDataType, false, initialSize, glBufferUsage);
+ this.normalVBO = GLArrayDataServer.createFixed(GL.GL_NORMAL_ARRAY, null, nComps, nDataType, false, initialSize, glBufferUsage);
+ this.texcoordVBO = GLArrayDataServer.createFixed(GL.GL_TEXTURE_COORD_ARRAY, null, tComps, tDataType, false, initialSize, glBufferUsage);
+ } else {
+ this.vertexVBO = GLArrayDataServer.createGLSL(GLContext.mgl_Vertex, vComps, vDataType, false, initialSize, glBufferUsage);
+ this.colorVBO = GLArrayDataServer.createGLSL(GLContext.mgl_Color, cComps, cDataType, false, initialSize, glBufferUsage);
+ this.normalVBO = GLArrayDataServer.createGLSL(GLContext.mgl_Normal, nComps, nDataType, false, initialSize, glBufferUsage);
+ this.texcoordVBO = GLArrayDataServer.createGLSL(GLContext.mgl_MultiTexCoord, tComps, tDataType, false, initialSize, glBufferUsage);
+ }
this.sealed=false;
this.mode = -1;
@@ -157,7 +305,8 @@ public class ImmModeSink {
}
protected final VBOSet regenerate() {
- return new VBOSet(glDataType, glDrawUsage, vComps, nComps, cComps, tComps, initialSize);
+ return new VBOSet(glBufferUsage, initialSize,
+ vComps, vDataType, cComps, cDataType, nComps, nDataType, tComps, tDataType, useGLSL);
}
protected void destroy(GL gl) {
@@ -186,10 +335,10 @@ public class ImmModeSink {
return "VBOSet[mode "+mode+
", modeOrig "+modeOrig+
", sealed "+sealed+
- ",\n\t vertexVBO "+vertexVBO+
- ",\n\t normalVBO "+normalVBO+
- ",\n\t colorVBO "+colorVBO+
- ",\n\t texcoordVBO "+texcoordVBO+
+ ",\n\t"+vertexVBO+
+ ",\n\t"+normalVBO+
+ ",\n\t"+colorVBO+
+ ",\n\t"+texcoordVBO+
"]";
}
@@ -220,35 +369,60 @@ public class ImmModeSink {
checkSeal(false);
sealed = true;
- vertexVBO.seal(gl, disableBufferAfterSeal);
- normalVBO.seal(gl, disableBufferAfterSeal);
- colorVBO.seal(gl, disableBufferAfterSeal);
- texcoordVBO.seal(gl, disableBufferAfterSeal);
+ vertexVBO.seal(gl, true);
+ normalVBO.seal(gl, true);
+ colorVBO.seal(gl, true);
+ texcoordVBO.seal(gl, true);
+
+ if(disableBufferAfterSeal) {
+ vertexVBO.enableBuffer(gl, false);
+ normalVBO.enableBuffer(gl, false);
+ colorVBO.enableBuffer(gl, false);
+ texcoordVBO.enableBuffer(gl, false);
+ }
}
- protected void draw(GL gl, boolean disableBufferAfterDraw, int i)
+ protected void draw(GL gl, Buffer indices, boolean disableBufferAfterDraw, int i)
{
if(DEBUG_DRAW) {
Exception e = new Exception("ImmModeSink.draw["+i+"](disableBufferAfterDraw: "+disableBufferAfterDraw+"):\n\t"+this);
e.printStackTrace();
}
- vertexVBO.enableBuffer(gl);
- normalVBO.enableBuffer(gl);
- colorVBO.enableBuffer(gl);
- texcoordVBO.enableBuffer(gl);
+ vertexVBO.enableBuffer(gl, true);
+ normalVBO.enableBuffer(gl, true);
+ colorVBO.enableBuffer(gl, true);
+ texcoordVBO.enableBuffer(gl, true);
if (vertexVBO.getBuffer()!=null) {
- gl.glDrawArrays(mode, 0, vertexVBO.getVerticeNumber());
+ if(null==indices) {
+ gl.glDrawArrays(mode, 0, vertexVBO.getVerticeNumber());
+ } else {
+ Class clazz = indices.getClass();
+ int type=-1;
+ if(GLReflection.instanceOf(clazz, ByteBuffer.class.getName())) {
+ type = GL.GL_UNSIGNED_BYTE;
+ } else if(GLReflection.instanceOf(clazz, ShortBuffer.class.getName())) {
+ type = GL.GL_UNSIGNED_SHORT;
+ }
+ if(0>type) {
+ throw new GLException("Given Buffer Class not supported: "+clazz+", should be ubyte or ushort:\n\t"+this);
+ }
+ gl.glDrawElements(mode, indices.remaining(), type, indices);
+ }
}
if(disableBufferAfterDraw) {
- vertexVBO.disableBuffer(gl);
- normalVBO.disableBuffer(gl);
- colorVBO.disableBuffer(gl);
- texcoordVBO.disableBuffer(gl);
+ vertexVBO.enableBuffer(gl, false);
+ normalVBO.enableBuffer(gl, false);
+ colorVBO.enableBuffer(gl, false);
+ texcoordVBO.enableBuffer(gl, false);
}
}
+ protected void glVertexv(Buffer v) {
+ checkSeal(false);
+ vertexVBO.put(v);
+ }
protected void glVertex2f(float x, float y) {
checkSeal(false);
vertexVBO.putf(x);
@@ -256,7 +430,6 @@ public class ImmModeSink {
vertexVBO.putf(y);
vertexVBO.padding(2);
}
-
protected void glVertex3f(float x, float y, float z) {
checkSeal(false);
vertexVBO.putf(x);
@@ -267,6 +440,10 @@ public class ImmModeSink {
vertexVBO.padding(3);
}
+ protected void glNormalv(Buffer v) {
+ checkSeal(false);
+ normalVBO.put(v);
+ }
protected void glNormal3f(float x, float y, float z) {
checkSeal(false);
normalVBO.putf(x);
@@ -277,6 +454,10 @@ public class ImmModeSink {
normalVBO.padding(3);
}
+ protected void glColorv(Buffer v) {
+ checkSeal(false);
+ colorVBO.put(v);
+ }
protected void glColor3f(float x, float y, float z) {
checkSeal(false);
colorVBO.putf(x);
@@ -286,7 +467,22 @@ public class ImmModeSink {
colorVBO.putf(z);
colorVBO.padding(3);
}
+ protected void glColor4f(float x, float y, float z, float a) {
+ checkSeal(false);
+ colorVBO.putf(x);
+ if(colorVBO.getComponents()>1)
+ colorVBO.putf(y);
+ if(colorVBO.getComponents()>2)
+ colorVBO.putf(z);
+ if(colorVBO.getComponents()>3)
+ colorVBO.putf(a);
+ colorVBO.padding(4);
+ }
+ protected void glTexCoordv(Buffer v) {
+ checkSeal(false);
+ texcoordVBO.put(v);
+ }
protected void glTexCoord2f(float x, float y) {
checkSeal(false);
texcoordVBO.putf(x);
@@ -294,7 +490,6 @@ public class ImmModeSink {
texcoordVBO.putf(y);
texcoordVBO.padding(2);
}
-
protected void glTexCoord3f(float x, float y, float z) {
checkSeal(false);
texcoordVBO.putf(x);
@@ -305,13 +500,145 @@ public class ImmModeSink {
texcoordVBO.padding(3);
}
- VBOBufferDraw vertexVBO;
- VBOBufferDraw normalVBO;
- VBOBufferDraw colorVBO;
- VBOBufferDraw texcoordVBO;
+ protected void glVertex2s(short x, short y) {
+ checkSeal(false);
+ vertexVBO.puts(x);
+ if(vertexVBO.getComponents()>1)
+ vertexVBO.puts(y);
+ vertexVBO.padding(2);
+ }
+ protected void glVertex3s(short x, short y, short z) {
+ checkSeal(false);
+ vertexVBO.puts(x);
+ if(vertexVBO.getComponents()>1)
+ vertexVBO.puts(y);
+ if(vertexVBO.getComponents()>2)
+ vertexVBO.puts(z);
+ vertexVBO.padding(3);
+ }
+
+ protected void glNormal3s(short x, short y, short z) {
+ checkSeal(false);
+ normalVBO.puts(x);
+ if(normalVBO.getComponents()>1)
+ normalVBO.puts(y);
+ if(normalVBO.getComponents()>2)
+ normalVBO.puts(z);
+ normalVBO.padding(3);
+ }
+
+ protected void glColor3s(short x, short y, short z) {
+ checkSeal(false);
+ colorVBO.puts(x);
+ if(colorVBO.getComponents()>1)
+ colorVBO.puts(y);
+ if(colorVBO.getComponents()>2)
+ colorVBO.puts(z);
+ colorVBO.padding(3);
+ }
+ protected void glColor4s(short x, short y, short z, short a) {
+ checkSeal(false);
+ colorVBO.puts(x);
+ if(colorVBO.getComponents()>1)
+ colorVBO.puts(y);
+ if(colorVBO.getComponents()>2)
+ colorVBO.puts(z);
+ if(colorVBO.getComponents()>3)
+ colorVBO.puts(a);
+ colorVBO.padding(4);
+ }
+
+ protected void glTexCoord2s(short x, short y) {
+ checkSeal(false);
+ texcoordVBO.puts(x);
+ if(texcoordVBO.getComponents()>1)
+ texcoordVBO.puts(y);
+ texcoordVBO.padding(2);
+ }
+ protected void glTexCoord3s(short x, short y, short z) {
+ checkSeal(false);
+ texcoordVBO.puts(x);
+ if(texcoordVBO.getComponents()>1)
+ texcoordVBO.puts(y);
+ if(texcoordVBO.getComponents()>2)
+ texcoordVBO.puts(z);
+ texcoordVBO.padding(3);
+ }
+
+ protected void glVertex2b(byte x, byte y) {
+ checkSeal(false);
+ vertexVBO.putb(x);
+ if(vertexVBO.getComponents()>1)
+ vertexVBO.putb(y);
+ vertexVBO.padding(2);
+ }
+ protected void glVertex3b(byte x, byte y, byte z) {
+ checkSeal(false);
+ vertexVBO.putb(x);
+ if(vertexVBO.getComponents()>1)
+ vertexVBO.putb(y);
+ if(vertexVBO.getComponents()>2)
+ vertexVBO.putb(z);
+ vertexVBO.padding(3);
+ }
+
+ protected void glNormal3b(byte x, byte y, byte z) {
+ checkSeal(false);
+ normalVBO.putb(x);
+ if(normalVBO.getComponents()>1)
+ normalVBO.putb(y);
+ if(normalVBO.getComponents()>2)
+ normalVBO.putb(z);
+ normalVBO.padding(3);
+ }
+
+ protected void glColor3b(byte x, byte y, byte z) {
+ checkSeal(false);
+ colorVBO.putb(x);
+ if(colorVBO.getComponents()>1)
+ colorVBO.putb(y);
+ if(colorVBO.getComponents()>2)
+ colorVBO.putb(z);
+ colorVBO.padding(3);
+ }
+ protected void glColor4b(byte x, byte y, byte z, byte a) {
+ checkSeal(false);
+ colorVBO.putb(x);
+ if(colorVBO.getComponents()>1)
+ colorVBO.putb(y);
+ if(colorVBO.getComponents()>2)
+ colorVBO.putb(z);
+ if(colorVBO.getComponents()>3)
+ colorVBO.putb(a);
+ colorVBO.padding(4);
+ }
+ protected void glTexCoord2b(byte x, byte y) {
+ checkSeal(false);
+ texcoordVBO.putb(x);
+ if(texcoordVBO.getComponents()>1)
+ texcoordVBO.putb(y);
+ texcoordVBO.padding(2);
+ }
+
+ protected void glTexCoord3b(byte x, byte y, byte z) {
+ checkSeal(false);
+ texcoordVBO.putb(x);
+ if(texcoordVBO.getComponents()>1)
+ texcoordVBO.putb(y);
+ if(texcoordVBO.getComponents()>2)
+ texcoordVBO.putb(z);
+ texcoordVBO.padding(3);
+ }
+
+ GLArrayDataServer vertexVBO;
+ GLArrayDataServer normalVBO;
+ GLArrayDataServer colorVBO;
+ GLArrayDataServer texcoordVBO;
int mode, modeOrig;
- int glDataType, glDrawUsage, vComps, nComps, cComps, tComps, initialSize;
- boolean sealed;
+ int glBufferUsage, initialSize;
+ int vComps, cComps, nComps, tComps;
+ int vDataType, cDataType, nDataType, tDataType;
+ boolean sealed, useGLSL;
}
}
diff --git a/src/classes/javax/media/opengl/util/PMVMatrix.java b/src/classes/javax/media/opengl/util/PMVMatrix.java
index 4e8693be0..37472dfe6 100755
--- a/src/classes/javax/media/opengl/util/PMVMatrix.java
+++ b/src/classes/javax/media/opengl/util/PMVMatrix.java
@@ -9,55 +9,54 @@ import java.util.List;
public class PMVMatrix {
- protected ProjectFloat pvmProjectf = null;
- protected FloatBuffer matrixPMV, matrixP, matrixMV;
- protected FloatBuffer matrixTemp, matrixTrans, matrixRot, matrixScale, matrixOrtho, matrixPersp, matrixFrustum;
- protected float[] vec3f;
- protected List/*FloatBuffer*/ matrixPStack, matrixMVStack;
- protected int matrixMode = GL.GL_MODELVIEW;
- protected boolean modifiedPMV = false;
-
public PMVMatrix() {
- pvmProjectf = new ProjectFloat();
+ projectFloat = new ProjectFloat();
+
+ matrixIdent = BufferUtil.newFloatBuffer(1*16);
+ projectFloat.gluMakeIdentityf(matrixIdent);
+ matrixIdent.rewind();
+
+ matrixPMvMviT = BufferUtil.newFloatBuffer(4*16); // grouping P + Mv + Mvi + MviT
+ matrixPMvMvi = slice(matrixPMvMviT, 0*16, 3*16); // grouping P + Mv + Mvi
+ matrixPMv = slice(matrixPMvMviT, 0*16, 2*16); // grouping P + Mv
+ matrixP = slice(matrixPMvMviT, 0*16, 1*16);
+ matrixMv = slice(matrixPMvMviT, 1*16, 1*16);
+ matrixMvi = slice(matrixPMvMviT, 2*16, 1*16);
+ matrixMvit = slice(matrixPMvMviT, 3*16, 1*16);
+ matrixPMvMviT.rewind();
- matrixPMV = BufferUtil.newFloatBuffer(2*16);
- matrixP = slice(matrixPMV, 0*16, 16);
- matrixMV = slice(matrixPMV, 1*16, 16);
- matrixPMV.rewind();
+ matrixMvit3 = BufferUtil.newFloatBuffer(3*3);
- FloatBuffer buf = BufferUtil.newFloatBuffer(7*16);
+ FloatBuffer buf = BufferUtil.newFloatBuffer(6*16);
- matrixTemp=slice(buf, 0*16, 16);
+ matrixMult=slice(buf, 0*16, 16);
matrixTrans=slice(buf, 1*16, 16);
- pvmProjectf.gluMakeIdentityf(matrixTrans);
+ projectFloat.gluMakeIdentityf(matrixTrans);
matrixRot=slice(buf, 2*16, 16);
- pvmProjectf.gluMakeIdentityf(matrixRot);
+ projectFloat.gluMakeIdentityf(matrixRot);
matrixScale=slice(buf, 3*16, 16);
- pvmProjectf.gluMakeIdentityf(matrixScale);
+ projectFloat.gluMakeIdentityf(matrixScale);
matrixOrtho=slice(buf, 4*16, 16);
- pvmProjectf.gluMakeIdentityf(matrixOrtho);
+ projectFloat.gluMakeIdentityf(matrixOrtho);
matrixFrustum=slice(buf, 5*16, 16);
- pvmProjectf.gluMakeZero(matrixFrustum);
-
- matrixPersp=slice(buf, 6*16, 16);
- pvmProjectf.gluMakeIdentityf(matrixPersp);
+ projectFloat.gluMakeZero(matrixFrustum);
vec3f=new float[3];
matrixPStack = new ArrayList();
- matrixMVStack= new ArrayList();
+ matrixMvStack= new ArrayList();
// default values and mode
glMatrixMode(GL.GL_PROJECTION);
glLoadIdentity();
glMatrixMode(GL.GL_MODELVIEW);
glLoadIdentity();
- modifiedPMV = true;
+ modified = true;
}
private static FloatBuffer slice(FloatBuffer buf, int pos, int len) {
@@ -67,11 +66,16 @@ public class PMVMatrix {
}
public boolean isDirty() {
- return modifiedPMV;
+ return modified;
}
- public void clear() {
- modifiedPMV=false;
+ public boolean update() {
+ boolean res = modified;
+ if(res) {
+ setMviMvit();
+ modified=false;
+ }
+ return res;
}
public final int glGetMatrixMode() {
@@ -89,8 +93,24 @@ public class PMVMatrix {
matrixMode = matrixName;
}
- public final FloatBuffer glGetPMVMatrixf() {
- return matrixPMV;
+ public final FloatBuffer glGetPMvMviTMatrixf() {
+ return matrixPMvMviT;
+ }
+
+ public final FloatBuffer glGetPMvMviMatrixf() {
+ return matrixPMvMvi;
+ }
+
+ public final FloatBuffer glGetPMvMatrixf() {
+ return matrixPMv;
+ }
+
+ public final FloatBuffer glGetMviMatrixf() {
+ return matrixMvi;
+ }
+
+ public final FloatBuffer glGetNormalMatrixf() {
+ return matrixMvit3;
}
public final FloatBuffer glGetMatrixf() {
@@ -99,82 +119,116 @@ public class PMVMatrix {
public final FloatBuffer glGetMatrixf(int matrixName) {
if(matrixName==GL.GL_MODELVIEW) {
- return matrixMV;
+ return matrixMv;
} else if(matrixName==GL.GL_PROJECTION) {
return matrixP;
}
return null;
}
+ public void glLoadMatrixf(float[] values, int offset) {
+ int len = values.length-offset;
+ if(matrixMode==GL.GL_MODELVIEW) {
+ matrixMv.clear();
+ matrixMv.put(values, offset, len);
+ matrixMv.rewind();
+ } else if(matrixMode==GL.GL_PROJECTION) {
+ matrixP.clear();
+ matrixP.put(values, offset, len);
+ matrixP.rewind();
+ }
+ modified = true;
+ }
+
public void glLoadMatrixf(java.nio.FloatBuffer m) {
+ int spos = m.position();
if(matrixMode==GL.GL_MODELVIEW) {
- matrixMV.clear();
- matrixMV.put(m);
- matrixMV.rewind();
+ matrixMv.clear();
+ matrixMv.put(m);
+ matrixMv.rewind();
} else if(matrixMode==GL.GL_PROJECTION) {
matrixP.clear();
matrixP.put(m);
matrixP.rewind();
}
- modifiedPMV = true;
+ m.position(spos);
+ modified = true;
}
public void glPopMatrix() {
+ float[] stackEntry=null;
if(matrixMode==GL.GL_MODELVIEW) {
- matrixMV=(FloatBuffer)matrixMVStack.remove(0);
+ stackEntry = (float[])matrixMvStack.remove(0);
} else if(matrixMode==GL.GL_PROJECTION) {
- matrixP=(FloatBuffer)matrixPStack.remove(0);
+ stackEntry = (float[])matrixPStack.remove(0);
}
- modifiedPMV = true;
+ glLoadMatrixf(stackEntry, 0);
}
public void glPushMatrix() {
+ float[] stackEntry = new float[1*16];
if(matrixMode==GL.GL_MODELVIEW) {
- matrixMVStack.add(0, matrixMV);
+ matrixMv.get(stackEntry);
+ matrixMv.rewind();
+ matrixMvStack.add(0, stackEntry);
} else if(matrixMode==GL.GL_PROJECTION) {
- matrixPStack.add(0, matrixP);
- }
+ matrixP.get(stackEntry);
+ matrixP.rewind();
+ matrixPStack.add(0, stackEntry);
+ }
}
public void glLoadIdentity() {
if(matrixMode==GL.GL_MODELVIEW) {
- matrixMV.clear();
- pvmProjectf.gluMakeIdentityf(matrixMV);
- matrixMV.rewind();
+ matrixMv.clear();
+ matrixMv.put(matrixIdent);
+ matrixMv.rewind();
+ matrixIdent.rewind();
} else if(matrixMode==GL.GL_PROJECTION) {
matrixP.clear();
- pvmProjectf.gluMakeIdentityf(matrixP);
+ matrixP.put(matrixIdent);
matrixP.rewind();
+ matrixIdent.rewind();
}
- modifiedPMV = true;
+ modified = true;
+ }
+
+ public void glMultMatrixf(FloatBuffer a, FloatBuffer b, FloatBuffer p) {
+ for (int i = 0; i < 4; i++) {
+ final float ai0=a.get(i+0*4), ai1=a.get(i+1*4), ai2=a.get(i+2*4), ai3=a.get(i+3*4);
+ p.put(i+0*4 , ai0 * b.get(0+0*4) + ai1 * b.get(1+0*4) + ai2 * b.get(2+0*4) + ai3 * b.get(3+0*4) );
+ p.put(i+1*4 , ai0 * b.get(0+1*4) + ai1 * b.get(1+1*4) + ai2 * b.get(2+1*4) + ai3 * b.get(3+1*4) );
+ p.put(i+2*4 , ai0 * b.get(0+2*4) + ai1 * b.get(1+2*4) + ai2 * b.get(2+2*4) + ai3 * b.get(3+2*4) );
+ p.put(i+3*4 , ai0 * b.get(0+3*4) + ai1 * b.get(1+3*4) + ai2 * b.get(2+3*4) + ai3 * b.get(3+3*4) );
+ }
+ // or .. projectFloat.gluMultMatricesf(b, a, p);
}
public void glMultMatrixf(FloatBuffer m) {
if(matrixMode==GL.GL_MODELVIEW) {
- pvmProjectf.gluMultMatricesf(m, matrixMV, matrixTemp);
- matrixMV.clear();
- matrixMV.put(matrixTemp);
- matrixMV.rewind();
+ glMultMatrixf(matrixMv, m, matrixMult);
+ matrixMv.clear();
+ matrixMv.put(matrixMult);
+ matrixMv.rewind();
} else if(matrixMode==GL.GL_PROJECTION) {
- pvmProjectf.gluMultMatricesf(m, matrixP, matrixTemp);
+ glMultMatrixf(matrixP, m, matrixMult);
matrixP.clear();
- matrixP.put(matrixTemp);
+ matrixP.put(matrixMult);
matrixP.rewind();
}
- matrixTemp.rewind();
- modifiedPMV = true;
+ matrixMult.rewind();
+ modified = true;
}
public void glTranslatef(float x, float y, float z) {
// Translation matrix:
- // 1 0 0 0
- // 0 1 0 0
- // 0 0 1 0
- // x y z 1
- matrixTrans.put(3*4+0, x);
- matrixTrans.put(3*4+1, y);
- matrixTrans.put(3*4+2, z);
-
+ // 1 0 0 x
+ // 0 1 0 y
+ // 0 0 1 z
+ // 0 0 0 1
+ matrixTrans.put(0+4*3, x);
+ matrixTrans.put(1+4*3, y);
+ matrixTrans.put(2+4*3, z);
glMultMatrixf(matrixTrans);
}
@@ -185,7 +239,7 @@ public class PMVMatrix {
float s = (float)Math.sin(angrad);
vec3f[0]=x; vec3f[1]=y; vec3f[2]=z;
- pvmProjectf.normalize(vec3f);
+ projectFloat.normalize(vec3f);
x = vec3f[0]; y = vec3f[1]; z = vec3f[2];
// Rotation matrix:
@@ -199,6 +253,19 @@ public class PMVMatrix {
float ys = y*s;
float yz = y*z;
float zs = z*s;
+ if(false) {
+ matrixRot.put(0+4*0, x*x*ic+c);
+ matrixRot.put(0+4*1, xy*ic+zs);
+ matrixRot.put(0+4*2, xz*ic-ys);
+
+ matrixRot.put(1+4*0, xy*ic+zs);
+ matrixRot.put(1+4*1, y*y*ic+c);
+ matrixRot.put(1+4*2, yz*ic-xs);
+
+ matrixRot.put(2+4*0, xz*ic-ys);
+ matrixRot.put(2+4*1, yz*ic+xs);
+ matrixRot.put(2+4*2, z*z*ic+c);
+ } else {
matrixRot.put(0*4+0, x*x*ic+c);
matrixRot.put(0*4+1, xy*ic+zs);
matrixRot.put(0*4+2, xz*ic-ys);
@@ -210,6 +277,7 @@ public class PMVMatrix {
matrixRot.put(2*4+0, xz*ic+ys);
matrixRot.put(2*4+1, yz*ic-xs);
matrixRot.put(2*4+2, z*z*ic+c);
+ }
glMultMatrixf(matrixRot);
}
@@ -220,19 +288,19 @@ public class PMVMatrix {
// 0 y 0 0
// 0 0 z 0
// 0 0 0 1
- matrixScale.put(0*4+0, x);
- matrixScale.put(1*4+1, y);
- matrixScale.put(2*4+2, z);
+ matrixScale.put(0+4*0, x);
+ matrixScale.put(1+4*1, y);
+ matrixScale.put(2+4*2, z);
glMultMatrixf(matrixScale);
}
public void glOrthof(float left, float right, float bottom, float top, float zNear, float zFar) {
// Ortho matrix:
- // 2/dx 0 0 0
- // 0 2/dy 0 0
- // 0 0 2/dz 0
- // tx tx tx 1
+ // 2/dx 0 0 tx
+ // 0 2/dy 0 ty
+ // 0 0 2/dz tz
+ // 0 0 0 1
float dx=right-left;
float dy=top-bottom;
float dz=zFar-zNear;
@@ -240,12 +308,12 @@ public class PMVMatrix {
float ty=-1.0f*(top+bottom)/dy;
float tz=-1.0f*(zFar+zNear)/dz;
- matrixOrtho.put(0*4+0, 2.0f/dx);
- matrixOrtho.put(1*4+1, 2.0f/dy);
- matrixOrtho.put(2*4+2, -2.0f/dz);
- matrixOrtho.put(3*4+0, tx);
- matrixOrtho.put(3*4+1, ty);
- matrixOrtho.put(3*4+2, tz);
+ matrixOrtho.put(0+4*0, 2.0f/dx);
+ matrixOrtho.put(1+4*1, 2.0f/dy);
+ matrixOrtho.put(2+4*2, -2.0f/dz);
+ matrixOrtho.put(0+4*3, tx);
+ matrixOrtho.put(1+4*3, ty);
+ matrixOrtho.put(2+4*3, tz);
glMultMatrixf(matrixOrtho);
}
@@ -271,40 +339,57 @@ public class PMVMatrix {
float C=-1.0f*(zFar+zNear)/dz;
float D=-2.0f*(zFar*zNear)/dz;
- matrixFrustum.put(0*4+0, zNear2/dx);
- matrixFrustum.put(1*4+1, zNear2/dy);
- matrixFrustum.put(2*4+2, C);
- matrixFrustum.put(0*4+2, A);
- matrixFrustum.put(1*4+2, B);
- matrixFrustum.put(2*4+3, D);
- matrixFrustum.put(3*4+2, -1.0f);
+ matrixFrustum.put(0+4*0, zNear2/dx);
+ matrixFrustum.put(1+4*1, zNear2/dy);
+ matrixFrustum.put(2+4*2, C);
+
+ matrixFrustum.put(0+4*2, A);
+ matrixFrustum.put(1+4*2, B);
+
+ matrixFrustum.put(2+4*3, D);
+ matrixFrustum.put(3+4*2, -1.0f);
glMultMatrixf(matrixFrustum);
}
public void gluPerspective(float fovy, float aspect, float zNear, float zFar) {
- float radians = fovy/2 * (float) Math.PI / 180;
-
- float sine, cotangent, deltaZ;
+ float top=(float)Math.tan(fovy*((float)Math.PI)/360.0f)*zNear;
+ float bottom=-1.0f*top;
+ float left=aspect*bottom;
+ float right=aspect*top;
+ glFrustumf(left, right, bottom, top, zNear, zFar);
+ }
- deltaZ = zFar - zNear;
- sine = (float) Math.sin(radians);
+ private void setMviMvit() {
+ if(!projectFloat.gluInvertMatrixf(matrixMv, matrixMvi)) {
+ throw new GLException("Invalid source Mv matrix, can't compute inverse");
+ }
- if ((deltaZ == 0.0f) || (sine == 0.0f) || (aspect == 0.0f)) {
- return;
+ // transpose matrix
+ for (int i = 0; i < 4; i++) {
+ for (int j = 0; j < 4; j++) {
+ matrixMvit.put(j+i*4, matrixMvi.get(i+j*4));
+ }
}
- cotangent = (float) Math.cos(radians) / sine;
+ // fetch 3x3
+ for (int i = 0; i < 3; i++) {
+ for (int j = 0; j < 3; j++) {
+ matrixMvit3.put(i+j*3, matrixMvit.get(i+j*4));
+ }
+ }
+ }
- matrixPersp.put(0 * 4 + 0, cotangent / aspect);
- matrixPersp.put(1 * 4 + 1, cotangent);
- matrixPersp.put(2 * 4 + 2, - (zFar + zNear) / deltaZ);
- matrixPersp.put(2 * 4 + 3, -1);
- matrixPersp.put(3 * 4 + 2, -2 * zNear * zFar / deltaZ);
- matrixPersp.put(3 * 4 + 3, 0);
+ protected FloatBuffer matrixIdent;
+ protected FloatBuffer matrixPMvMviT, matrixPMvMvi, matrixPMv, matrixP, matrixMv, matrixMvi, matrixMvit;
+ protected FloatBuffer matrixMvit3;
+ protected FloatBuffer matrixMult, matrixTrans, matrixRot, matrixScale, matrixOrtho, matrixFrustum;
+ protected float[] vec3f;
+ protected List/*FloatBuffer*/ matrixPStack, matrixMvStack;
+ protected int matrixMode = GL.GL_MODELVIEW;
+ protected boolean modified = false;
+ protected ProjectFloat projectFloat;
- glMultMatrixf(matrixPersp);
- }
}
diff --git a/src/classes/javax/media/opengl/util/VBOBufferDraw.java b/src/classes/javax/media/opengl/util/VBOBufferDraw.java
deleted file mode 100644
index 8ce1b3232..000000000
--- a/src/classes/javax/media/opengl/util/VBOBufferDraw.java
+++ /dev/null
@@ -1,392 +0,0 @@
-
-package javax.media.opengl.util;
-
-import javax.media.opengl.*;
-import java.nio.*;
-import com.sun.opengl.impl.*;
-
-public abstract class VBOBufferDraw {
-
- public static VBOBufferDraw create(int glArrayType, int glDataType, int glBufferUsage, int comps, int initialSize)
- throws GLException
- {
- Class[] types = new Class[]{ int.class, int.class, int.class, int.class, int.class };
- Object[] args = new Integer[]{ new Integer(glArrayType), new Integer(glDataType), new Integer(glBufferUsage),
- new Integer(comps), new Integer(initialSize) } ;
-
- if(GLProfile.isGL2ES1()) {
- return (VBOBufferDraw) GLReflection.createInstance("com.sun.opengl.impl.gl2es1.VBOBufferDrawGL2ES1", types, args);
- } else if(GLProfile.isGLES2()) {
- return (VBOBufferDraw) GLReflection.createInstance("com.sun.opengl.impl.es2.VBOBufferDrawGLES2", types, args);
- }
- throw new GLException("VBOBufferDraw not supported for profile: "+GLProfile.getProfile());
- }
-
- protected void init(int glArrayType, int glDataType, int glBufferUsage, int comps, int initialSize)
- throws GLException
- {
- vboUsage=true;
-
- switch(glArrayType) {
- case GL2ES1.GL_VERTEX_ARRAY:
- case GL2ES1.GL_NORMAL_ARRAY:
- if(3!=comps && 0!=comps) {
- throw new GLException("component size for NORMAL_ARRAY must be 3 or 0: "+comps+" \n\t"+this);
- }
- case GL2ES1.GL_COLOR_ARRAY:
- case GL2ES1.GL_TEXTURE_COORD_ARRAY:
- break;
- default:
- throw new GLException("invalid glArrayType: "+glArrayType+":\n\t"+this);
- }
- this.glArrayType = glArrayType;
- this.glDataType = glDataType;
- this.clazz = getBufferClass(glDataType);
- this.buffer = null;
- this.components = comps;
- this.initialSize = initialSize;
- if( ! (GLProfile.isGL2ES2() && glBufferUsage==GL2ES2.GL_STREAM_DRAW) ) {
- switch(glBufferUsage) {
- case GL2ES1.GL_STATIC_DRAW:
- case GL2ES1.GL_DYNAMIC_DRAW:
- break;
- default:
- throw new GLException("invalid glBufferUsage: "+glBufferUsage+":\n\t"+this);
- }
- }
- this.glBufferUsage = glBufferUsage;
- this.vboName = 0;
- this.sealed=false;
- this.bufferEnabled=false;
- growVBO(initialSize);
- }
-
- public boolean usesVBO() { return vboUsage; }
-
- public void setVBOUsage(boolean vboUsage) {
- checkSeal(false);
- this.vboUsage=vboUsage;
- }
-
- public int getGLArrayType() {
- return glArrayType;
- }
-
- public int getGlDataType() {
- return glDataType;
- }
-
- public int getComponents() {
- return components;
- }
-
- public Class getBufferClass() {
- return clazz;
- }
-
- public Buffer getBuffer() {
- return buffer;
- }
-
- public int getBufferUsage() {
- return glBufferUsage;
- }
-
- public void destroy(GL gl) {
- reset(gl);
- if(vboName!=0) {
- int[] tmp = new int[1];
- tmp[0] = vboName;
- gl.glDeleteBuffers(1, tmp, 0);
- vboName = 0;
- }
- }
-
- public void reset() {
- reset(null);
- }
-
- public void reset(GL gl) {
- if(gl!=null) {
- disableBuffer(gl);
- }
- this.sealed=false;
- if(buffer!=null) {
- buffer.clear();
- }
- }
-
- private final void init_vbo(GL gl) {
- if(vboUsage && vboName==0) {
- int[] tmp = new int[1];
- gl.glGenBuffers(1, tmp, 0);
- vboName = tmp[0];
- }
- }
-
- private final void checkSeal(boolean test) throws GLException {
- if(sealed!=test) {
- if(test) {
- throw new GLException("Not Sealed yet, seal first:\n\t"+this);
- } else {
- throw new GLException("Already Sealed, can't modify VBO:\n\t"+this);
- }
- }
- }
-
- public final boolean growVBOIfNecessary(int spare) {
- if(buffer==null) {
- throw new GLException("buffer no configured:\n\t"+this);
- }
- if(buffer!=null && buffer.remaining()<spare) {
- growVBO();
- return true;
- }
- return false;
- }
-
- public final void growVBO() {
- growVBO(initialSize);
- }
-
- public static final Class getBufferClass(int glDataType) {
- switch(glDataType) {
- case GL2ES1.GL_BYTE:
- case GL2ES1.GL_UNSIGNED_BYTE:
- return ByteBuffer.class;
- case GL2ES1.GL_SHORT:
- case GL2ES1.GL_UNSIGNED_SHORT:
- return ShortBuffer.class;
- case GL2ES1.GL_FIXED:
- return IntBuffer.class;
- case GL2ES1.GL_FLOAT:
- return FloatBuffer.class;
- default:
- throw new GLException("Given OpenGL data type not supported: "+glDataType);
- }
- }
-
- public final int getBufferCompSize() {
- if(clazz==ByteBuffer.class) {
- return BufferUtil.SIZEOF_BYTE;
- }
- if(clazz==ShortBuffer.class) {
- return BufferUtil.SIZEOF_SHORT;
- }
- if(clazz==IntBuffer.class) {
- return BufferUtil.SIZEOF_INT;
- }
- if(clazz==FloatBuffer.class) {
- return BufferUtil.SIZEOF_FLOAT;
- }
- throw new GLException("Given Buffer Class not supported: "+clazz+":\n\t"+this);
- }
-
- public final void growVBO(int additional) {
- int osize;
-
- checkSeal(false);
-
- if(components>0) {
- osize = (buffer!=null)?buffer.capacity():0;
- if(clazz==ByteBuffer.class) {
- ByteBuffer newBBuffer = BufferUtil.newByteBuffer( (osize+additional) * components );
- if(buffer!=null) {
- buffer.flip();
- newBBuffer.put((ByteBuffer)buffer);
- }
- buffer = newBBuffer;
- } else if(clazz==ShortBuffer.class) {
- ShortBuffer newSBuffer = BufferUtil.newShortBuffer( (osize+additional) * components );
- if(buffer!=null) {
- buffer.flip();
- newSBuffer.put((ShortBuffer)buffer);
- }
- buffer = newSBuffer;
- } else if(clazz==IntBuffer.class) {
- IntBuffer newIBuffer = BufferUtil.newIntBuffer( (osize+additional) * components );
- if(buffer!=null) {
- buffer.flip();
- newIBuffer.put((IntBuffer)buffer);
- }
- buffer = newIBuffer;
- } else if(clazz==FloatBuffer.class) {
- FloatBuffer newFBuffer = BufferUtil.newFloatBuffer( (osize+additional) * components );
- if(buffer!=null) {
- buffer.flip();
- newFBuffer.put((FloatBuffer)buffer);
- }
- buffer = newFBuffer;
- } else {
- throw new GLException("Given Buffer Class not supported: "+clazz+":\n\t"+this);
- }
- }
- }
-
- public void rewind() {
- checkSeal(true);
-
- if(buffer!=null) {
- buffer.rewind();
- }
- }
-
- public int getVerticeNumber() {
- return ( buffer!=null ) ? ( buffer.limit() / components ) : 0 ;
- }
-
- public void seal(GL gl, boolean disableAfterSeal)
- {
- checkSeal(false);
- sealed = true;
- init_vbo(gl);
-
- if (null!=buffer) {
- buffer.flip();
- enableBuffer(gl, true);
- }
- if(null==buffer || disableAfterSeal) {
- disableBuffer(gl);
- }
-
- }
-
- public void enableBuffer(GL gl)
- {
- enableBuffer(gl, false);
- }
-
- private void enableBuffer(GL gl, boolean newData)
- {
- checkSeal(true);
- enableBufferGLImpl(gl, newData);
- }
-
- protected abstract void enableBufferGLImpl(GL gl, boolean newData);
-
- public void disableBuffer(GL gl) {
- disableBufferGLImpl(gl);
- }
-
- protected abstract void disableBufferGLImpl(GL gl) ;
-
- public void padding(int done) {
- if(buffer==null) return; // JAU
- if(buffer==null) {
- throw new GLException("buffer no configured:\n\t"+this);
- }
- while(done<components) {
- if(clazz==ByteBuffer.class) {
- ((ByteBuffer)buffer).put((byte)0);
- } else if(clazz==ShortBuffer.class) {
- ((ShortBuffer)buffer).put((short)0);
- } else if(clazz==IntBuffer.class) {
- ((IntBuffer)buffer).put(0);
- } else if(clazz==FloatBuffer.class) {
- ((FloatBuffer)buffer).put(0f);
- } else {
- throw new GLException("Given Buffer Class not supported: "+clazz+" :\n\t"+this);
- }
- done++;
- }
- }
-
- public void putb(byte v) {
- if(buffer==null) return; // JAU
- growVBOIfNecessary(1);
- if(clazz==ByteBuffer.class) {
- ((ByteBuffer)buffer).put(v);
- } else if(clazz==ShortBuffer.class) {
- ((ShortBuffer)buffer).put((short)v);
- } else if(clazz==IntBuffer.class) {
- ((IntBuffer)buffer).put((int)v);
- } else {
- throw new GLException("Byte doesn't match Buffer Class: "+clazz+" :\n\t"+this);
- }
- }
-
- public void puts(short v) {
- if(buffer==null) return; // JAU
- growVBOIfNecessary(1);
- if(clazz==ShortBuffer.class) {
- ((ShortBuffer)buffer).put(v);
- } else if(clazz==IntBuffer.class) {
- ((IntBuffer)buffer).put((int)v);
- } else {
- throw new GLException("Short doesn't match Buffer Class: "+clazz+" :\n\t"+this);
- }
- }
-
- public void puti(int v) {
- if(buffer==null) return; // JAU
- growVBOIfNecessary(1);
- if(clazz==IntBuffer.class) {
- ((IntBuffer)buffer).put(v);
- } else {
- throw new GLException("Integer doesn't match Buffer Class: "+clazz+" :\n\t"+this);
- }
- }
-
- public void putx(int v) {
- if(buffer==null) return; // JAU
- growVBOIfNecessary(1);
- if(clazz==IntBuffer.class) {
- ((IntBuffer)buffer).put(v);
- } else {
- throw new GLException("Fixed doesn't match Buffer Class: "+clazz+" :\n\t"+this);
- }
- }
-
- public void putf(float v) {
- if(buffer==null) return; // JAU
- growVBOIfNecessary(1);
- if(clazz==FloatBuffer.class) {
- ((FloatBuffer)buffer).put(v);
- } else if(clazz==IntBuffer.class) {
- ((IntBuffer)buffer).put(FixedPoint.toFixed(v));
- } else {
- throw new GLException("Float doesn't match Buffer Class: "+clazz+" :\n\t"+this);
- }
- }
-
- public void putd(double v) {
- if(buffer==null) return; // JAU
- growVBOIfNecessary(1);
- if(clazz==FloatBuffer.class) {
- // FIXME: ok ?
- ((FloatBuffer)buffer).put((float)v);
- } else {
- throw new GLException("Double doesn't match Buffer Class: "+clazz+" :\n\t"+this);
- }
- }
-
- public String toString() {
- return "VBOBufferDraw[vertices "+getVerticeNumber()+
- ", glArrayType "+glArrayType+
- ", glDataType "+glDataType+
- ", bufferClazz "+clazz+
- ", components "+components+
- ", initialSize "+initialSize+
- ", glBufferUsage "+glBufferUsage+
- ", vboUsage "+vboUsage+
- ", vboName "+vboName+
- ", sealed "+sealed+
- ", bufferEnabled "+bufferEnabled+
- ",\n\tbuffer "+buffer+
- "]";
- }
-
- protected int glArrayType;
- protected int glDataType;
- protected Class clazz;
- protected Buffer buffer;
- protected int components;
- protected int initialSize;
- protected int glBufferUsage;
- protected int vboName;
- protected boolean sealed;
- protected boolean bufferEnabled;
- protected boolean vboUsage;
-
-}
-
diff --git a/src/classes/javax/media/opengl/util/glsl/ShaderCode.java b/src/classes/javax/media/opengl/util/glsl/ShaderCode.java
new file mode 100644
index 000000000..46ead1b30
--- /dev/null
+++ b/src/classes/javax/media/opengl/util/glsl/ShaderCode.java
@@ -0,0 +1,122 @@
+
+package javax.media.opengl.util.glsl;
+
+import javax.media.opengl.util.*;
+import javax.media.opengl.*;
+
+import java.nio.*;
+import java.io.PrintStream;
+
+public class ShaderCode {
+ public ShaderCode(int type, int number,
+ int binFormat, Buffer binary, 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 = binFormat;
+ shaderBinary = binary;
+ shaderType = type;
+ shader = BufferUtil.newIntBuffer(number);
+ id = getNextID();
+ }
+
+ /**
+ * 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
+ valid=gl.glCreateCompileShader(shader, shaderType,
+ shaderBinaryFormat, shaderBinary,
+ shaderSource, verboseOut);
+ shader.clear();
+ 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);
+ /*
+ if(shaderSource!=null) {
+ for(int i=0; i<shaderSource.length; i++) {
+ for(int j=0; j<shaderSource[i].length; j++) {
+ buf.append("\n\t, ShaderSource["+i+"]["+j+"]:\n");
+ buf.append(shaderSource[i][j]);
+ }
+ }
+ } */
+ buf.append("]");
+ return buf.toString();
+ }
+
+ 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/util/glsl/ShaderProgram.java b/src/classes/javax/media/opengl/util/glsl/ShaderProgram.java
new file mode 100644
index 000000000..5628f3332
--- /dev/null
+++ b/src/classes/javax/media/opengl/util/glsl/ShaderProgram.java
@@ -0,0 +1,201 @@
+
+package javax.media.opengl.util.glsl;
+
+import javax.media.opengl.util.*;
+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);
+
+ if ( ! gl.glIsProgramValid(shaderProgram, System.err) ) {
+ return false;
+ }
+ programLinked=true;
+
+ return true;
+ }
+
+ 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/util/glsl/ShaderState.java b/src/classes/javax/media/opengl/util/glsl/ShaderState.java
new file mode 100644
index 000000000..7f917cc07
--- /dev/null
+++ b/src/classes/javax/media/opengl/util/glsl/ShaderState.java
@@ -0,0 +1,583 @@
+
+package javax.media.opengl.util.glsl;
+
+import javax.media.opengl.util.*;
+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.util.glsl.ShaderState#glUseProgram(GL2ES2, boolean)
+ * @see javax.media.opengl.util.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.util.glsl.ShaderState#glUseProgram(GL2ES2, boolean)
+ * @see javax.media.opengl.util.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;
+
+}
+