diff options
Diffstat (limited to 'src/jogl/classes/com/jogamp/opengl/util/GLArrayDataServer.java')
-rw-r--r-- | src/jogl/classes/com/jogamp/opengl/util/GLArrayDataServer.java | 511 |
1 files changed, 398 insertions, 113 deletions
diff --git a/src/jogl/classes/com/jogamp/opengl/util/GLArrayDataServer.java b/src/jogl/classes/com/jogamp/opengl/util/GLArrayDataServer.java index c9dd98751..833f1ccda 100644 --- a/src/jogl/classes/com/jogamp/opengl/util/GLArrayDataServer.java +++ b/src/jogl/classes/com/jogamp/opengl/util/GLArrayDataServer.java @@ -1,14 +1,48 @@ +/** + * Copyright 2010 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. + */ package com.jogamp.opengl.util; import java.nio.Buffer; +import java.nio.ByteBuffer; +import java.nio.FloatBuffer; +import java.nio.IntBuffer; +import java.nio.ShortBuffer; import javax.media.opengl.GL; import javax.media.opengl.GL2ES2; import javax.media.opengl.GLArrayData; +import javax.media.opengl.GLBufferStorage; import javax.media.opengl.GLException; import javax.media.opengl.fixedfunc.GLPointerFuncUtil; +import com.jogamp.common.nio.Buffers; + import jogamp.opengl.util.GLArrayHandler; import jogamp.opengl.util.GLArrayHandlerInterleaved; import jogamp.opengl.util.GLDataArrayHandler; @@ -30,31 +64,31 @@ public class GLArrayDataServer extends GLArrayDataClient implements GLArrayDataE * 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 + * 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. - * - * The default name mapping will be used, + * + * The default name mapping will be used, * see {@link GLPointerFuncUtil#getPredefinedArrayIndexName(int)}. - * + * * @param index The GL array index - * @param comps The array component number - * @param dataType The array index GL data type + * @param compsPerElement component count per element + * @param dataType The component's OpenGL data type * @param normalized Whether the data shall be normalized - * @param stride + * @param stride in bytes from one element to the other. If zero, compsPerElement * compSizeInBytes * @param buffer the user define data * @param vboUsage {@link GL2ES2#GL_STREAM_DRAW}, {@link GL#GL_STATIC_DRAW} or {@link GL#GL_DYNAMIC_DRAW} * * @see javax.media.opengl.GLContext#getPredefinedArrayIndexName(int) */ - public static GLArrayDataServer createFixed(int index, int comps, int dataType, boolean normalized, int stride, + public static GLArrayDataServer createFixed(int index, int compsPerElement, int dataType, boolean normalized, int stride, Buffer buffer, int vboUsage) throws GLException { GLArrayDataServer ads = new GLArrayDataServer(); GLArrayHandler glArrayHandler = new GLFixedArrayHandler(ads); - ads.init(null, index, comps, dataType, normalized, stride, buffer, buffer.limit(), false, glArrayHandler, - 0, 0, vboUsage, GL.GL_ARRAY_BUFFER, false); + ads.init(null, index, compsPerElement, dataType, normalized, stride, buffer, buffer.limit(), 0 /* mappedElementCount */, false, + glArrayHandler, 0, 0, vboUsage, GL.GL_ARRAY_BUFFER, false); return ads; } @@ -63,143 +97,234 @@ public class GLArrayDataServer extends GLArrayDataClient implements GLArrayDataE * and starting with a new created Buffer object with initialElementCount 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 + * 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. - * - * The default name mapping will be used, + * + * The default name mapping will be used, * see {@link GLPointerFuncUtil#getPredefinedArrayIndexName(int)}. - * + * * @param index The GL array index - * @param comps The array component number - * @param dataType The array index GL data type + * @param compsPerElement component count per element + * @param dataType The component's OpenGL data type * @param normalized Whether the data shall be normalized * @param initialElementCount * @param vboUsage {@link GL2ES2#GL_STREAM_DRAW}, {@link GL#GL_STATIC_DRAW} or {@link GL#GL_DYNAMIC_DRAW} * * @see javax.media.opengl.GLContext#getPredefinedArrayIndexName(int) */ - public static GLArrayDataServer createFixed(int index, int comps, int dataType, boolean normalized, int initialElementCount, + public static GLArrayDataServer createFixed(int index, int compsPerElement, int dataType, boolean normalized, int initialElementCount, int vboUsage) throws GLException { GLArrayDataServer ads = new GLArrayDataServer(); GLArrayHandler glArrayHandler = new GLFixedArrayHandler(ads); - ads.init(null, index, comps, dataType, normalized, 0, null, initialElementCount, false, glArrayHandler, - 0, 0, vboUsage, GL.GL_ARRAY_BUFFER, false); + ads.init(null, index, compsPerElement, dataType, normalized, 0, null, initialElementCount, 0 /* mappedElementCount */, false, + glArrayHandler, 0, 0, vboUsage, GL.GL_ARRAY_BUFFER, false); return ads; } /** * Create a VBO, using a custom GLSL array attribute name * and starting with a new created Buffer object with initialElementCount size - * @param name The custom name for the GL attribute - * @param comps The array component number - * @param dataType The array index GL data type + * @param name The custom name for the GL attribute + * @param compsPerElement component count per element + * @param dataType The component's OpenGL data type * @param normalized Whether the data shall be normalized * @param initialElementCount * @param vboUsage {@link GL2ES2#GL_STREAM_DRAW}, {@link GL#GL_STATIC_DRAW} or {@link GL#GL_DYNAMIC_DRAW} */ - public static GLArrayDataServer createGLSL(String name, int comps, - int dataType, boolean normalized, int initialElementCount, int vboUsage) - throws GLException + public static GLArrayDataServer createGLSL(String name, int compsPerElement, + int dataType, boolean normalized, int initialElementCount, int vboUsage) + throws GLException { GLArrayDataServer ads = new GLArrayDataServer(); GLArrayHandler glArrayHandler = new GLSLArrayHandler(ads); - ads.init(name, -1, comps, dataType, normalized, 0, null, initialElementCount, - true, glArrayHandler, 0, 0, vboUsage, GL.GL_ARRAY_BUFFER, true); + ads.init(name, -1, compsPerElement, dataType, normalized, 0, null, initialElementCount, + 0 /* mappedElementCount */, true, glArrayHandler, 0, 0, vboUsage, GL.GL_ARRAY_BUFFER, true); return ads; - } - + } + + /** + * Create a VBO, using a custom GLSL array attribute name + * intended for GPU buffer storage mapping, see {@link GLBufferStorage}, via {@link #mapStorage(GL, int)} and {@link #mapStorage(GL, long, long, int)}. + * @param name The custom name for the GL attribute + * @param compsPerElement component count per element + * @param dataType The component's OpenGL data type + * @param normalized Whether the data shall be normalized + * @param mappedElementCount + * @param vboUsage {@link GL2ES2#GL_STREAM_DRAW}, {@link GL#GL_STATIC_DRAW} or {@link GL#GL_DYNAMIC_DRAW} + */ + public static GLArrayDataServer createGLSLMapped(String name, int compsPerElement, + int dataType, boolean normalized, int mappedElementCount, int vboUsage) + throws GLException + { + GLArrayDataServer ads = new GLArrayDataServer(); + GLArrayHandler glArrayHandler = new GLSLArrayHandler(ads); + ads.init(name, -1, compsPerElement, dataType, normalized, 0, null, 0 /* initialElementCount */, + mappedElementCount, true, glArrayHandler, 0, 0, vboUsage, GL.GL_ARRAY_BUFFER, true); + ads.seal(true); + return ads; + } + /** * Create a VBO, using a custom GLSL array attribute name * and starting with a given Buffer object incl it's stride - * @param name The custom name for the GL attribute - * @param comps The array component number - * @param dataType The array index GL data type + * @param name The custom name for the GL attribute + * @param compsPerElement component count per element + * @param dataType The component's OpenGL data type * @param normalized Whether the data shall be normalized - * @param stride + * @param stride in bytes from one element to the other. If zero, compsPerElement * compSizeInBytes * @param buffer the user define data * @param vboUsage {@link GL2ES2#GL_STREAM_DRAW}, {@link GL#GL_STATIC_DRAW} or {@link GL#GL_DYNAMIC_DRAW} */ - public static GLArrayDataServer createGLSL(String name, int comps, + public static GLArrayDataServer createGLSL(String name, int compsPerElement, int dataType, boolean normalized, int stride, Buffer buffer, - int vboUsage) + int vboUsage) throws GLException { GLArrayDataServer ads = new GLArrayDataServer(); GLArrayHandler glArrayHandler = new GLSLArrayHandler(ads); - ads.init(name, -1, comps, dataType, normalized, stride, buffer, buffer.limit(), true, glArrayHandler, - 0, 0, vboUsage, GL.GL_ARRAY_BUFFER, true); + ads.init(name, -1, compsPerElement, dataType, normalized, stride, buffer, buffer.limit(), 0 /* mappedElementCount */, true, + glArrayHandler, 0, 0, vboUsage, GL.GL_ARRAY_BUFFER, true); return ads; } - + /** * Create a VBO data object for any target w/o render pipeline association, ie {@link GL#GL_ELEMENT_ARRAY_BUFFER}. - * + * * Hence no index, name for a fixed function pipeline nor vertex attribute is given. - * - * @param comps The array component number - * @param dataType The array index GL data type - * @param stride + * + * @param compsPerElement component count per element + * @param dataType The component's OpenGL data type + * @param stride in bytes from one element to the other. If zero, compsPerElement * compSizeInBytes * @param buffer the user define data * @param vboUsage {@link GL2ES2#GL_STREAM_DRAW}, {@link GL#GL_STATIC_DRAW} or {@link GL#GL_DYNAMIC_DRAW} * @param vboTarget {@link GL#GL_ELEMENT_ARRAY_BUFFER}, .. * {@link GL#glGenBuffers(int, int[], int) */ - public static GLArrayDataServer createData(int comps, int dataType, int stride, + public static GLArrayDataServer createData(int compsPerElement, int dataType, int stride, Buffer buffer, int vboUsage, int vboTarget) throws GLException { GLArrayDataServer ads = new GLArrayDataServer(); GLArrayHandler glArrayHandler = new GLDataArrayHandler(ads); - ads.init(null, -1, comps, dataType, false, stride, buffer, buffer.limit(), false, glArrayHandler, - 0, 0, vboUsage, vboTarget, false); + ads.init(null, -1, compsPerElement, dataType, false, stride, buffer, buffer.limit(), 0 /* mappedElementCount */, false, + glArrayHandler, 0, 0, vboUsage, vboTarget, false); return ads; } /** * Create a VBO data object for any target w/o render pipeline association, ie {@link GL#GL_ELEMENT_ARRAY_BUFFER}. - * + * * Hence no index, name for a fixed function pipeline nor vertex attribute is given. - * - * @param comps The array component number - * @param dataType The array index GL data type + * + * @param compsPerElement component count per element + * @param dataType The component's OpenGL data type * @param initialElementCount * @param vboUsage {@link GL2ES2#GL_STREAM_DRAW}, {@link GL#GL_STATIC_DRAW} or {@link GL#GL_DYNAMIC_DRAW} * @param vboTarget {@link GL#GL_ELEMENT_ARRAY_BUFFER}, .. */ - public static GLArrayDataServer createData(int comps, int dataType, int initialElementCount, + public static GLArrayDataServer createData(int compsPerElement, int dataType, int initialElementCount, int vboUsage, int vboTarget) throws GLException { GLArrayDataServer ads = new GLArrayDataServer(); GLArrayHandler glArrayHandler = new GLDataArrayHandler(ads); - ads.init(null, -1, comps, dataType, false, 0, null, initialElementCount, false, glArrayHandler, - 0, 0, vboUsage, vboTarget, false); + ads.init(null, -1, compsPerElement, dataType, false, 0, null, initialElementCount, 0 /* mappedElementCount */, false, + glArrayHandler, 0, 0, vboUsage, vboTarget, false); + return ads; + } + + /** + * Create a VBO data object for any target w/o render pipeline association, i.e. {@link GL#GL_ELEMENT_ARRAY_BUFFER}, + * intended for GPU buffer storage mapping, see {@link GLBufferStorage}, via {@link #mapStorage(GL, int)} and {@link #mapStorage(GL, long, long, int)}. + * <p> + * No index, name for a fixed function pipeline nor vertex attribute is given. + * </p> + * + * @param compsPerElement component count per element + * @param dataType The component's OpenGL data type + * @param initialElementCount + * @param vboUsage {@link GL2ES2#GL_STREAM_DRAW}, {@link GL#GL_STATIC_DRAW} or {@link GL#GL_DYNAMIC_DRAW} + * @param vboTarget {@link GL#GL_ELEMENT_ARRAY_BUFFER}, .. + */ + public static GLArrayDataServer createDataMapped(int compsPerElement, int dataType, int mappedElementCount, + int vboUsage, int vboTarget) + throws GLException + { + GLArrayDataServer ads = new GLArrayDataServer(); + GLArrayHandler glArrayHandler = new GLDataArrayHandler(ads); + ads.init(null, -1, compsPerElement, dataType, false, 0, null, 0 /* initialElementCount */, mappedElementCount, false, + glArrayHandler, 0, 0, vboUsage, vboTarget, false); return ads; } - /** * Create a VBO for fixed function interleaved array data * starting with a new created Buffer object with initialElementCount size. * <p>User needs to <i>configure</i> the interleaved segments via {@link #addFixedSubArray(int, int, int)}.</p> - * - * @param comps The total number of all interleaved components. - * @param dataType The array index GL data type + * + * @param compsPerElement The total number of all interleaved components per element. + * @param dataType The component's OpenGL data type * @param normalized Whether the data shall be normalized - * @param initialElementCount + * @param initialElementCount The initial number of all interleaved elements * @param vboUsage {@link GL2ES2#GL_STREAM_DRAW}, {@link GL#GL_STATIC_DRAW} or {@link GL#GL_DYNAMIC_DRAW} */ - public static GLArrayDataServer createFixedInterleaved(int comps, int dataType, boolean normalized, int initialElementCount, + public static GLArrayDataServer createFixedInterleaved(int compsPerElement, int dataType, boolean normalized, int initialElementCount, int vboUsage) throws GLException { GLArrayDataServer ads = new GLArrayDataServer(); GLArrayHandler glArrayHandler = new GLArrayHandlerInterleaved(ads); - ads.init(GLPointerFuncUtil.mgl_InterleaveArray, -1, comps, dataType, false, 0, null, initialElementCount, false, glArrayHandler, - 0, 0, vboUsage, GL.GL_ARRAY_BUFFER, false); + ads.init(GLPointerFuncUtil.mgl_InterleaveArray, -1, compsPerElement, dataType, false, 0, null, initialElementCount, 0 /* mappedElementCount */, false, + glArrayHandler, 0, 0, vboUsage, GL.GL_ARRAY_BUFFER, false); + return ads; + } + + /** + * Create a VBO for fixed function interleaved array data + * intended for GPU buffer storage mapping, see {@link GLBufferStorage}, via {@link #mapStorage(GL, int)} and {@link #mapStorage(GL, long, long, int)}. + * <p>User needs to <i>configure</i> the interleaved segments via {@link #addFixedSubArray(int, int, int)}.</p> + * + * @param compsPerElement The total number of all interleaved components per element. + * @param dataType The component's OpenGL data type + * @param normalized Whether the data shall be normalized + * @param mappedElementCount The total number of all interleaved elements + * @param vboUsage {@link GL2ES2#GL_STREAM_DRAW}, {@link GL#GL_STATIC_DRAW} or {@link GL#GL_DYNAMIC_DRAW} + */ + public static GLArrayDataServer createFixedInterleavedMapped(int compsPerElement, int dataType, boolean normalized, int mappedElementCount, + int vboUsage) + throws GLException + { + GLArrayDataServer ads = new GLArrayDataServer(); + GLArrayHandler glArrayHandler = new GLArrayHandlerInterleaved(ads); + ads.init(GLPointerFuncUtil.mgl_InterleaveArray, -1, compsPerElement, dataType, false, 0, null, 0 /* initialElementCount */, mappedElementCount, false, + glArrayHandler, 0, 0, vboUsage, GL.GL_ARRAY_BUFFER, false); + ads.seal(true); + return ads; + } + + /** + * Create a VBO for fixed function interleaved array data + * starting with a given Buffer object incl it's stride + * <p>User needs to <i>configure</i> the interleaved segments via {@link #addFixedSubArray(int, int, int)}.</p> + * + * @param compsPerElement The total number of all interleaved components per element. + * @param dataType The component's OpenGL data type + * @param normalized Whether the data shall be normalized + * @param stride in bytes from one element of a sub-array to the other. If zero, compsPerElement * compSizeInBytes + * @param buffer The user define data of all interleaved elements + * @param vboUsage {@link GL2ES2#GL_STREAM_DRAW}, {@link GL#GL_STATIC_DRAW} or {@link GL#GL_DYNAMIC_DRAW} + */ + public static GLArrayDataServer createFixedInterleaved(int compsPerElement, int dataType, boolean normalized, int stride, Buffer buffer, + int vboUsage) + throws GLException + { + GLArrayDataServer ads = new GLArrayDataServer(); + GLArrayHandler glArrayHandler = new GLArrayHandlerInterleaved(ads); + ads.init(GLPointerFuncUtil.mgl_InterleaveArray, -1, compsPerElement, dataType, normalized, stride, buffer, buffer.limit(), 0 /* mappedElementCount */, false, + glArrayHandler, 0, 0, vboUsage, GL.GL_ARRAY_BUFFER, false); return ads; } @@ -207,14 +332,14 @@ public class GLArrayDataServer extends GLArrayDataClient implements GLArrayDataE * Configure a segment of this fixed function interleaved array (see {@link #createFixedInterleaved(int, int, boolean, int, int)}). * <p> * This method may be called several times as long the sum of interleaved components does not - * exceed the total number of components of the created interleaved array.</p> + * exceed the total component count of the created interleaved array.</p> * <p> * The memory of the the interleaved array is being used.</p> * <p> * Must be called before using the array, eg: {@link #seal(boolean)}, {@link #putf(float)}, .. </p> - * + * * @param index The GL array index, maybe -1 if vboTarget is {@link GL#GL_ELEMENT_ARRAY_BUFFER} - * @param comps This interleaved array segment's component number + * @param comps This interleaved array segment's component count per element * @param vboTarget {@link GL#GL_ARRAY_BUFFER} or {@link GL#GL_ELEMENT_ARRAY_BUFFER} */ public GLArrayData addFixedSubArray(int index, int comps, int vboTarget) { @@ -223,53 +348,107 @@ public class GLArrayDataServer extends GLArrayDataClient implements GLArrayDataE throw new GLException("Interleaved offset > total components ("+iOffC+" > "+getComponentCount()+")"); } if(usesGLSL) { - throw new GLException("buffer uses GLSL"); + throw new GLException("buffer uses GLSL"); + } + final int subStrideB = ( 0 == getStride() ) ? getComponentCount() * getComponentSizeInBytes() : getStride(); + final GLArrayDataWrapper ad; + if( 0 < mappedElementCount ) { + ad = GLArrayDataWrapper.createFixed( + index, comps, getComponentType(), + getNormalized(), subStrideB, mappedElementCount, + getVBOName(), interleavedOffset, getVBOUsage(), vboTarget); + } else { + ad = GLArrayDataWrapper.createFixed( + index, comps, getComponentType(), + getNormalized(), subStrideB, getBuffer(), + getVBOName(), interleavedOffset, getVBOUsage(), vboTarget); } - final GLArrayDataWrapper ad = GLArrayDataWrapper.createFixed( - index, comps, getComponentType(), - getNormalized(), getStride(), getBuffer(), - getVBOName(), interleavedOffset, getVBOUsage(), vboTarget); ad.setVBOEnabled(isVBO()); interleavedOffset += comps * getComponentSizeInBytes(); - if(GL.GL_ARRAY_BUFFER == vboTarget) { + if(GL.GL_ARRAY_BUFFER == vboTarget) { glArrayHandler.addSubHandler(new GLFixedArrayHandlerFlat(ad)); } return ad; } - + /** * Create a VBO for GLSL interleaved array data * starting with a new created Buffer object with initialElementCount size. * <p>User needs to <i>configure</i> the interleaved segments via {@link #addGLSLSubArray(int, int, int)}.</p> - * - * @param comps The total number of all interleaved components. - * @param dataType The array index GL data type + * + * @param compsPerElement The total number of all interleaved components per element. + * @param dataType The component's OpenGL data type * @param normalized Whether the data shall be normalized - * @param initialElementCount + * @param initialElementCount The initial number of all interleaved elements * @param vboUsage {@link GL2ES2#GL_STREAM_DRAW}, {@link GL#GL_STATIC_DRAW} or {@link GL#GL_DYNAMIC_DRAW} */ - public static GLArrayDataServer createGLSLInterleaved(int comps, int dataType, boolean normalized, int initialElementCount, - int vboUsage) + public static GLArrayDataServer createGLSLInterleaved(int compsPerElement, int dataType, boolean normalized, int initialElementCount, + int vboUsage) + throws GLException + { + GLArrayDataServer ads = new GLArrayDataServer(); + GLArrayHandler glArrayHandler = new GLSLArrayHandlerInterleaved(ads); + ads.init(GLPointerFuncUtil.mgl_InterleaveArray, -1, compsPerElement, dataType, normalized, 0, null, initialElementCount, 0 /* mappedElementCount */, false, + glArrayHandler, 0, 0, vboUsage, GL.GL_ARRAY_BUFFER, true); + return ads; + } + + /** + * Create a VBO for GLSL interleaved array data + * intended for GPU buffer storage mapping, see {@link GLBufferStorage}, via {@link #mapStorage(GL, int)} and {@link #mapStorage(GL, long, long, int)}. + * <p>User needs to <i>configure</i> the interleaved segments via {@link #addGLSLSubArray(int, int, int)}.</p> + * + * @param compsPerElement The total number of all interleaved components per element. + * @param dataType The component's OpenGL data type + * @param normalized Whether the data shall be normalized + * @param mappedElementCount The total number of all interleaved elements + * @param vboUsage {@link GL2ES2#GL_STREAM_DRAW}, {@link GL#GL_STATIC_DRAW} or {@link GL#GL_DYNAMIC_DRAW} + */ + public static GLArrayDataServer createGLSLInterleavedMapped(int compsPerElement, int dataType, boolean normalized, int mappedElementCount, int vboUsage) + throws GLException + { + GLArrayDataServer ads = new GLArrayDataServer(); + GLArrayHandler glArrayHandler = new GLSLArrayHandlerInterleaved(ads); + ads.init(GLPointerFuncUtil.mgl_InterleaveArray, -1, compsPerElement, dataType, normalized, 0, null, 0 /* initialElementCount */, mappedElementCount, false, + glArrayHandler, 0, 0, vboUsage, GL.GL_ARRAY_BUFFER, true); + ads.seal(true); + return ads; + } + + /** + * Create a VBO for GLSL interleaved array data + * starting with a given Buffer object incl it's stride + * <p>User needs to <i>configure</i> the interleaved segments via {@link #addGLSLSubArray(int, int, int)}.</p> + * + * @param compsPerElement The total number of all interleaved components per element. + * @param dataType The component's OpenGL data type + * @param normalized Whether the data shall be normalized + * @param stride in bytes from one element of a sub-array to the other. If zero, compsPerElement * compSizeInBytes + * @param buffer The user define data of all interleaved elements + * @param vboUsage {@link GL2ES2#GL_STREAM_DRAW}, {@link GL#GL_STATIC_DRAW} or {@link GL#GL_DYNAMIC_DRAW} + */ + public static GLArrayDataServer createGLSLInterleaved(int compsPerElement, int dataType, boolean normalized, int stride, Buffer buffer, + int vboUsage) throws GLException { GLArrayDataServer ads = new GLArrayDataServer(); GLArrayHandler glArrayHandler = new GLSLArrayHandlerInterleaved(ads); - ads.init(GLPointerFuncUtil.mgl_InterleaveArray, -1, comps, dataType, false, 0, null, initialElementCount, false, glArrayHandler, - 0, 0, vboUsage, GL.GL_ARRAY_BUFFER, true); + ads.init(GLPointerFuncUtil.mgl_InterleaveArray, -1, compsPerElement, dataType, normalized, stride, buffer, buffer.limit(), 0 /* mappedElementCount */, false, + glArrayHandler, 0, 0, vboUsage, GL.GL_ARRAY_BUFFER, true); return ads; } - + /** * Configure a segment of this GLSL interleaved array (see {@link #createGLSLInterleaved(int, int, boolean, int, int)}). * <p> * This method may be called several times as long the sum of interleaved components does not - * exceed the total number of components of the created interleaved array.</p> + * exceed the total component count of the created interleaved array.</p> * <p> * The memory of the the interleaved array is being used.</p> * <p> * Must be called before using the array, eg: {@link #seal(boolean)}, {@link #putf(float)}, .. </p> * @param name The custom name for the GL attribute, maybe null if vboTarget is {@link GL#GL_ELEMENT_ARRAY_BUFFER} - * @param comps This interleaved array segment's component number + * @param comps This interleaved array segment's component count per element * @param vboTarget {@link GL#GL_ARRAY_BUFFER} or {@link GL#GL_ELEMENT_ARRAY_BUFFER} */ public GLArrayData addGLSLSubArray(String name, int comps, int vboTarget) { @@ -278,20 +457,37 @@ public class GLArrayDataServer extends GLArrayDataClient implements GLArrayDataE throw new GLException("Interleaved offset > total components ("+iOffC+" > "+getComponentCount()+")"); } if(!usesGLSL) { - throw new GLException("buffer uses fixed function"); + throw new GLException("buffer uses fixed function"); + } + final int subStrideB = ( 0 == getStride() ) ? getComponentCount() * getComponentSizeInBytes() : getStride(); + final GLArrayDataWrapper ad; + if( 0 < mappedElementCount ) { + ad = GLArrayDataWrapper.createGLSL( + name, comps, getComponentType(), + getNormalized(), subStrideB, mappedElementCount, + getVBOName(), interleavedOffset, getVBOUsage(), vboTarget); + } else { + ad = GLArrayDataWrapper.createGLSL( + name, comps, getComponentType(), + getNormalized(), subStrideB, getBuffer(), + getVBOName(), interleavedOffset, getVBOUsage(), vboTarget); } - final GLArrayDataWrapper ad = GLArrayDataWrapper.createGLSL( - name, comps, getComponentType(), - getNormalized(), getStride(), getBuffer(), - getVBOName(), interleavedOffset, getVBOUsage(), vboTarget); ad.setVBOEnabled(isVBO()); interleavedOffset += comps * getComponentSizeInBytes(); - if(GL.GL_ARRAY_BUFFER == vboTarget) { + if(GL.GL_ARRAY_BUFFER == vboTarget) { glArrayHandler.addSubHandler(new GLSLArrayHandlerFlat(ad)); } return ad; } - + + public final void setInterleavedOffset(int interleavedOffset) { + this.interleavedOffset = interleavedOffset; + } + + public final int getInterleavedOffset() { + return interleavedOffset; + } + // // Data matters GLArrayData // @@ -300,6 +496,7 @@ public class GLArrayDataServer extends GLArrayDataClient implements GLArrayDataE // Data and GL state modification .. // + @Override public void destroy(GL gl) { // super.destroy(gl): // - GLArrayDataClient.destroy(gl): disables & clears client-side buffer @@ -314,40 +511,108 @@ public class GLArrayDataServer extends GLArrayDataClient implements GLArrayDataE } // - // data matters + // data matters // /** - * Convenient way do disable the VBO behavior and + * Convenient way do disable the VBO behavior and * switch to client side data one * Only possible if buffer is defined. */ - public void setVBOEnabled(boolean vboUsage) { + @Override + public void setVBOEnabled(boolean vboUsage) { checkSeal(false); super.setVBOEnabled(vboUsage); } + public GLBufferStorage mapStorage(GL gl, int access) { + if( null != this.getBuffer() ) { + throw new IllegalStateException("user buffer not null"); + } + if( null != mappedStorage ) { + throw new IllegalStateException("already mapped: "+mappedStorage); + } + checkSeal(true); + bindBuffer(gl, true); + gl.glBufferData(getVBOTarget(), getSizeInBytes(), null, getVBOUsage()); + final GLBufferStorage storage = gl.mapBuffer(getVBOTarget(), access); + setMappedBuffer(storage); + bindBuffer(gl, false); + seal(false); + rewind(); + return storage; + } + public GLBufferStorage mapStorage(GL gl, long offset, long length, int access) { + if( null != this.getBuffer() ) { + throw new IllegalStateException("user buffer not null"); + } + if( null != mappedStorage ) { + throw new IllegalStateException("already mapped: "+mappedStorage); + } + checkSeal(true); + bindBuffer(gl, true); + gl.glBufferData(getVBOTarget(), getSizeInBytes(), null, getVBOUsage()); + final GLBufferStorage storage = gl.mapBufferRange(getVBOTarget(), offset, length, access); + setMappedBuffer(storage); + bindBuffer(gl, false); + seal(false); + rewind(); + return storage; + } + private final void setMappedBuffer(GLBufferStorage storage) { + mappedStorage = storage; + final ByteBuffer bb = storage.getMappedBuffer(); + if(componentClazz==ByteBuffer.class) { + buffer = bb; + } else if(componentClazz==ShortBuffer.class) { + buffer = bb.asShortBuffer(); + } else if(componentClazz==IntBuffer.class) { + buffer = bb.asIntBuffer(); + } else if(componentClazz==FloatBuffer.class) { + buffer = bb.asFloatBuffer(); + } else { + throw new GLException("Given Buffer Class not supported: "+componentClazz+":\n\t"+this); + } + } + + public void unmapStorage(GL gl) { + if( null == mappedStorage ) { + throw new IllegalStateException("not mapped"); + } + mappedStorage = null; + buffer = null; + seal(true); + bindBuffer(gl, true); + gl.glUnmapBuffer(getVBOTarget()); + bindBuffer(gl, false); + } + + @Override public String toString() { return "GLArrayDataServer["+name+ ", index "+index+ ", location "+location+ ", isVertexAttribute "+isVertexAttribute+ - ", dataType 0x"+Integer.toHexString(componentType)+ - ", bufferClazz "+componentClazz+ + ", usesGLSL "+usesGLSL+ + ", usesShaderState "+(null!=shaderState)+ + ", dataType 0x"+Integer.toHexString(componentType)+ + ", bufferClazz "+componentClazz+ ", elements "+getElementCount()+ - ", components "+components+ + ", components "+componentsPerElement+ ", stride "+strideB+"b "+strideL+"c"+ ", initialElementCount "+initialElementCount+ - ", vboEnabled "+vboEnabled+ - ", vboName "+vboName+ - ", vboUsage 0x"+Integer.toHexString(vboUsage)+ - ", vboTarget 0x"+Integer.toHexString(vboTarget)+ - ", vboOffset "+vboOffset+ - ", sealed "+sealed+ - ", bufferEnabled "+bufferEnabled+ - ", bufferWritten "+bufferWritten+ - ", buffer "+buffer+ - ", alive "+alive+ + ", mappedElementCount "+mappedElementCount+ + ", mappedStorage "+mappedStorage+ + ", vboEnabled "+vboEnabled+ + ", vboName "+vboName+ + ", vboUsage 0x"+Integer.toHexString(vboUsage)+ + ", vboTarget 0x"+Integer.toHexString(vboTarget)+ + ", vboOffset "+vboOffset+ + ", sealed "+sealed+ + ", bufferEnabled "+bufferEnabled+ + ", bufferWritten "+bufferWritten+ + ", buffer "+buffer+ + ", alive "+alive+ "]"; } @@ -355,18 +620,20 @@ public class GLArrayDataServer extends GLArrayDataClient implements GLArrayDataE // non public matters .. // - protected void init(String name, int index, int comps, int dataType, boolean normalized, - int stride, Buffer data, int initialElementCount, boolean isVertexAttribute, - GLArrayHandler glArrayHandler, - int vboName, long vboOffset, int vboUsage, int vboTarget, boolean usesGLSL) + @Override + protected void init(String name, int index, int comps, int dataType, boolean normalized, + int stride, Buffer data, int initialElementCount, int mappedElementCount, + boolean isVertexAttribute, + GLArrayHandler glArrayHandler, int vboName, long vboOffset, int vboUsage, int vboTarget, boolean usesGLSL) throws GLException { - super.init(name, index, comps, dataType, normalized, stride, data, initialElementCount, isVertexAttribute, glArrayHandler, - vboName, vboOffset, vboUsage, vboTarget, usesGLSL); + super.init(name, index, comps, dataType, normalized, stride, data, initialElementCount, mappedElementCount, isVertexAttribute, + glArrayHandler, vboName, vboOffset, vboUsage, vboTarget, usesGLSL); vboEnabled=true; } + @Override protected void init_vbo(GL gl) { super.init_vbo(gl); if(vboEnabled && vboName==0) { @@ -378,7 +645,25 @@ public class GLArrayDataServer extends GLArrayDataClient implements GLArrayDataE } } } - - private int interleavedOffset = 0; + + protected GLArrayDataServer() { } + + /** + * Copy Constructor + * <p> + * Buffer is {@link Buffers#slice(Buffer) sliced}, i.e. sharing content but using own state. + * </p> + * <p> + * All other values are simply copied. + * </p> + */ + public GLArrayDataServer(GLArrayDataServer src) { + super(src); + this.interleavedOffset = src.interleavedOffset; + this.mappedStorage = src.mappedStorage; + } + + private int interleavedOffset = 0; + private GLBufferStorage mappedStorage = null; } |