package javax.media.opengl.util; import javax.media.opengl.*; import javax.media.opengl.util.gl2es1.VBOBufferDrawGL2ES1; import java.nio.*; public abstract class VBOBufferDraw { public static VBOBufferDraw create(int glArrayType, int glDataType, int glBufferUsage, int comps, int initialSize) throws GLException { if(GLProfile.isGL2ES1()) { return new VBOBufferDrawGL2ES1(glArrayType, glDataType, glBufferUsage, comps, initialSize); } 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 { switch(glArrayType) { case GL2ES1.GL_VERTEX_ARRAY: case GL2ES1.GL_NORMAL_ARRAY: 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 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(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()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 32767) value = 32767; return (int)(value * 65536); } 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; }