package com.jogamp.opengl.util; import com.jogamp.common.nio.Buffers; import java.security.*; import javax.media.opengl.*; import com.jogamp.opengl.util.glsl.*; import jogamp.opengl.SystemUtil; import java.nio.*; public class GLArrayDataClient extends GLArrayDataWrapper implements GLArrayDataEditable { /** * The OpenGL ES emulation on the PC probably has a buggy VBO implementation, * where we have to 'refresh' the VertexPointer or VertexAttribArray after each * BindBuffer ! * * This should not be necessary on proper native implementations. */ public static final boolean hasVBOBug = AccessController.doPrivileged(new PrivilegedAction() { public Object run() { return SystemUtil.getenv("JOGL_VBO_BUG"); } }) != null; /** * @param index The GL array index * @param 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. * @param comps The array component number * @param dataType The array index GL data type * @param normalized Wheather the data shall be normalized * * @see javax.media.opengl.GLContext#getPredefinedArrayIndexName(int) */ public static GLArrayDataClient createFixed(GL gl, int index, String name, int comps, int dataType, boolean normalized, int initialSize) throws GLException { gl.getGLProfile().isValidArrayDataType(index, comps, dataType, false, true); GLArrayDataClient adc = new GLArrayDataClient(); GLArrayHandler glArrayHandler = new GLFixedArrayHandler(adc); adc.init(name, index, comps, dataType, normalized, 0, null, initialSize, false, glArrayHandler, 0, 0); return adc; } public static GLArrayDataClient createFixed(GL gl, int index, String name, int comps, int dataType, boolean normalized, int stride, Buffer buffer) throws GLException { gl.getGLProfile().isValidArrayDataType(index, comps, dataType, false, true); GLArrayDataClient adc = new GLArrayDataClient(); GLArrayHandler glArrayHandler = new GLFixedArrayHandler(adc); adc.init(name, index, comps, dataType, normalized, stride, buffer, comps*comps, false, glArrayHandler, 0, 0); return adc; } public static GLArrayDataClient createGLSL(GL gl, String name, int comps, int dataType, boolean normalized, int initialSize) throws GLException { if(!gl.hasGLSL()) { throw new GLException("GLArrayDataClient.GLSL not supported: "+gl); } gl.getGLProfile().isValidArrayDataType(-1, comps, dataType, true, true); GLArrayDataClient adc = new GLArrayDataClient(); GLArrayHandler glArrayHandler = new GLSLArrayHandler(adc); adc.init(name, -1, comps, dataType, normalized, 0, null, initialSize, true, glArrayHandler, 0, 0); return adc; } public static GLArrayDataClient createGLSL(GL gl, String name, int comps, int dataType, boolean normalized, int stride, Buffer buffer) throws GLException { if(!gl.hasGLSL()) { throw new GLException("GLArrayDataClient.GLSL not supported: "+gl); } gl.getGLProfile().isValidArrayDataType(-1, comps, dataType, true, true); GLArrayDataClient adc = new GLArrayDataClient(); GLArrayHandler glArrayHandler = new GLSLArrayHandler(adc); adc.init(name, -1, comps, dataType, normalized, stride, buffer, comps*comps, true, glArrayHandler, 0, 0); return adc; } // // Data read access // public final boolean isBufferWritten() { return bufferWritten; } public final boolean sealed() { return sealed; } public int getBufferUsage() { return -1; } // // Data and GL state modification .. // public final void setBufferWritten(boolean written) { bufferWritten=written; } public void destroy(GL gl) { reset(gl); buffer=null; } 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(enableBufferAlways && enable) { bufferEnabled = false; } if( bufferEnabled != enable && components>0 ) { if(enable) { checkSeal(true); if(null!=buffer) { buffer.rewind(); } } glArrayHandler.enableBuffer(gl, enable); bufferEnabled = enable; } } public void setEnableAlways(boolean always) { enableBufferAlways = always; } // // 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(done0) { int osize = (buffer!=null)?buffer.capacity():0; if(clazz==ByteBuffer.class) { ByteBuffer newBBuffer = Buffers.newDirectByteBuffer( (osize+additional) * components ); if(buffer!=null) { buffer.flip(); newBBuffer.put((ByteBuffer)buffer); } buffer = newBBuffer; } else if(clazz==ShortBuffer.class) { ShortBuffer newSBuffer = Buffers.newDirectShortBuffer( (osize+additional) * components ); if(buffer!=null) { buffer.flip(); newSBuffer.put((ShortBuffer)buffer); } buffer = newSBuffer; } else if(clazz==IntBuffer.class) { IntBuffer newIBuffer = Buffers.newDirectIntBuffer( (osize+additional) * components ); if(buffer!=null) { buffer.flip(); newIBuffer.put((IntBuffer)buffer); } buffer = newIBuffer; } else if(clazz==FloatBuffer.class) { FloatBuffer newFBuffer = Buffers.newDirectFloatBuffer( (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, GLArrayHandler handler, int vboName, long bufferOffset) throws GLException { super.init(name, index, comps, dataType, normalized, stride, data, isVertexAttribute, vboName, bufferOffset); this.initialSize = initialSize; this.glArrayHandler = handler; this.sealed=false; this.sealedGL=false; this.bufferEnabled=false; this.enableBufferAlways=false; this.bufferWritten=false; if(null==buffer) { growBuffer(initialSize); } } protected void init_vbo(GL gl) {} protected GLArrayDataClient() { } protected boolean sealed, sealedGL; protected boolean bufferEnabled; protected boolean bufferWritten; protected boolean enableBufferAlways; protected int initialSize; protected GLArrayHandler glArrayHandler; }