diff options
Diffstat (limited to 'src/classes/javax/media/opengl/GLArrayDataServer.java')
-rw-r--r-- | src/classes/javax/media/opengl/GLArrayDataServer.java | 265 |
1 files changed, 265 insertions, 0 deletions
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; + +} + |