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; /** * Create a client side buffer 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 chosen. * * @param gl the current GL instance * @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 Whether the data shall be normalized * @param initialSize * * @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, -1, -1, -1, -1); return adc; } /** * Create a client side buffer 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 chosen. * * @param gl the current GL instance * @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 Whether the data shall be normalized * @param stride * @param buffer the user define data * * @see javax.media.opengl.GLContext#getPredefinedArrayIndexName(int) */ 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, -1, -1, -1, -1); return adc; } /** * Create a client side buffer object, using a custom GLSL array attribute name * and starting with a new created Buffer object with initialSize size * * @param gl the current GL instance * @param name The custom name for the GL attribute. * @param comps The array component number * @param dataType The array index GL data type * @param normalized Whether the data shall be normalized * @param initialSize */ 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, -1, -1, -1, -1); return adc; } /** * Create a client side buffer object, using a custom GLSL array attribute name * and starting with a given Buffer object incl it's stride * * @param gl the current GL instance * @param name The custom name for the GL attribute. * @param comps The array component number * @param dataType The array index GL data type * @param normalized Whether the data shall be normalized * @param stride * @param buffer the user define data */ 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, -1, -1, -1, -1); return adc; } // // Data read access // public final boolean isVBOWritten() { return bufferWritten; } public final boolean sealed() { return sealed; } // // Data and GL state modification .. // public final void setVBOWritten(boolean written) { bufferWritten=written; } public void destroy(GL gl) { reset(gl); buffer=null; valid=false; } 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 || bufferEnabled != enable || getVBOName() != gl.glGetBoundBuffer(getVBOTarget()) ) { 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) { 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; }