gov.nasa.worldwind.util.VecBufferSequence Maven / Gradle / Ivy
The newest version!
/*
* Copyright (C) 2012 United States Government as represented by the Administrator of the
* National Aeronautics and Space Administration.
* All Rights Reserved.
*/
package gov.nasa.worldwind.util;
import gov.nasa.worldwind.render.DrawContext;
import com.jogamp.opengl.GL2;
/**
* VecBufferSequence provides storage and retrieval of a sequence of logical VecBuffers in a single VecBuffer that
* expands when more capacity is needed. VecBuffers added to a VecBufferSequence by calling {@link #append(VecBuffer)}.
* This copies the specified VecBuffer's data to the VecBuffer backing the VecBufferSequence, and expands the backing
* VecBuffer if necessary.
*
* @author dcollins
* @version $Id: VecBufferSequence.java 1171 2013-02-11 21:45:02Z dcollins $
*/
public class VecBufferSequence extends CompoundVecBuffer
{
protected int vecCount;
protected VecBuffer buffer;
/**
* Constructs a PackedCompoundVecBuffer with the specified backing VecBuffer and the specified initial capacity.
*
* @param buffer the backing VecBuffer.
* @param capacity the PackedCompoundVecBuffer's initial capacity, in number of sub-buffers.
*
* @throws IllegalArgumentException if the buffer is null, or if the capacity is less than 1.
*/
public VecBufferSequence(VecBuffer buffer, int capacity)
{
super(capacity);
if (buffer == null)
{
String message = Logging.getMessage("nullValue.BufferIsNull");
Logging.logger().severe(message);
throw new IllegalArgumentException(message);
}
this.buffer = buffer;
}
/**
* Constructs a PackedCompoundVecBuffer with the specified backing VecBuffer and the default initial capacity.
*
* @param buffer the backing VecBuffer.
*
* @throws IllegalArgumentException if the buffer is null.
*/
public VecBufferSequence(VecBuffer buffer)
{
this(buffer, DEFAULT_INITIAL_CAPACITY);
}
protected VecBufferSequence(VecBufferSequence that, int beginIndex, int endIndex)
{
super(that, beginIndex, endIndex);
this.vecCount = that.vecCount;
this.buffer = that.buffer;
}
protected VecBufferSequence(VecBufferSequence that, int[] indices, int offset, int length)
{
super(that, indices, offset, length);
this.vecCount = that.vecCount;
this.buffer = that.buffer;
}
/**
* Returns an empty VecBufferSequence. The returned VecBufferSequence has a size of zero and contains no
* sub-buffers.
*
* @param coordsPerVec the number of coordinates per logical vector.
*
* @return the empty VecBufferSequence.
*/
public static VecBufferSequence emptyVecBufferSequence(int coordsPerVec)
{
if (coordsPerVec < 1)
{
String message = Logging.getMessage("generic.ArgumentOutOfRange", coordsPerVec);
Logging.logger().severe(message);
throw new IllegalArgumentException(message);
}
return new VecBufferSequence(VecBuffer.emptyVecBuffer(coordsPerVec));
}
/** {@inheritDoc} */
public int subBufferSize(int index)
{
if (index < 0 || index >= this.count)
{
String message = Logging.getMessage("generic.indexOutOfRange", index);
Logging.logger().severe(message);
throw new IllegalArgumentException(message);
}
return this.lengths.get(index);
}
/** {@inheritDoc} */
public void clear()
{
super.clear();
this.vecCount = 0;
}
/** {@inheritDoc} */
public int getCoordsPerVec()
{
return this.buffer.getCoordsPerVec();
}
/**
* Returns the VecBuffer that stores this PackedCompoundVecBuffer's sub-buffers.
*
* @return this PackedCompoundVecBuffer's backing VecBuffer.
*/
public VecBuffer getVecBuffer()
{
return this.buffer;
}
/**
* Appends the contents of the specified sub-buffer to the end of this PackedCompoundVecBuffer, incrementing the
* number of sub-buffers by one. The backing buffer grows to accomodate the sub-buffer if it does not already have
* enough capacity to hold it.
*
* @param buffer the sub-buffer to append.
*
* @return the sub-buffer's index.
*
* @throws IllegalArgumentException if the subBuffer is null.
*/
public int append(VecBuffer buffer)
{
if (buffer == null)
{
String message = Logging.getMessage("nullValue.BufferIsNull");
Logging.logger().severe(message);
throw new IllegalArgumentException(message);
}
int minVecCount = buffer.getSize() + this.vecCount;
if (minVecCount > this.buffer.getSize())
this.expandBufferCapacity(minVecCount);
int newBufferPos = this.vecCount;
this.buffer.putSubBuffer(newBufferPos, buffer);
this.vecCount += buffer.getSize();
return this.addSubBuffer(newBufferPos, buffer.getSize());
}
//**************************************************************//
//******************** Protected Interface *******************//
//**************************************************************//
protected VecBuffer createSubBuffer(int offset, int length)
{
return this.buffer.getSubBuffer(offset, length);
}
protected CompoundVecBuffer createSlice(int[] indices, int offset, int length)
{
return new VecBufferSequence(this, indices, offset, length);
}
protected CompoundVecBuffer createSlice(int beginIndex, int endIndex)
{
return new VecBufferSequence(this, beginIndex, endIndex);
}
protected void expandBufferCapacity(int minCapacity)
{
int newCapacity = 2 * this.buffer.getSize();
// If the new capacity overflows the range of 32-bit integers, then use the largest 32-bit integer.
if (newCapacity < 0)
{
newCapacity = Integer.MAX_VALUE;
}
// If the new capacity is still not large enough for the minimum capacity specified, then just use the minimum
// capacity specified.
else if (newCapacity < minCapacity)
{
newCapacity = minCapacity;
}
this.buffer = this.buffer.copyOf(newCapacity);
}
//**************************************************************//
//******************** OpenGL Vertex Buffer Interface ********//
//**************************************************************//
/**
* Binds this buffer as the source of normal coordinates to use when rendering OpenGL primitives. The normal type is
* equal to buffer's underlying BufferWrapper GL type, the stride is 0, and the vertex data itself is this buffer's
* backing NIO {@link java.nio.Buffer}. This buffer's vector size must be 3.
*
* @param dc the current {@link gov.nasa.worldwind.render.DrawContext}.
*
* @throws IllegalArgumentException if the DrawContext is null, or if this buffer is not compatible as a normal
* buffer.
*/
public void bindAsNormalBuffer(DrawContext dc)
{
if (dc == null)
{
String message = Logging.getMessage("nullValue.DrawContextIsNull");
Logging.logger().severe(message);
throw new IllegalArgumentException(message);
}
this.buffer.bindAsNormalBuffer(dc);
}
/**
* Binds this buffer as the source of vertex coordinates to use when rendering OpenGL primitives. The vertex size is
* equal to coordsPerVertex, the vertex type is equal to buffer's underlying BufferWrapper GL type, the stride is 0,
* and the normal data itself is this buffer's backing NIO Buffer. This buffer's vector size must be 2, 3, or 4.
*
* @param dc the current DrawContext.
*
* @throws IllegalArgumentException if the DrawContext is null, or if this buffer is not compatible as a vertex
* buffer.
*/
public void bindAsVertexBuffer(DrawContext dc)
{
if (dc == null)
{
String message = Logging.getMessage("nullValue.DrawContextIsNull");
Logging.logger().severe(message);
throw new IllegalArgumentException(message);
}
this.buffer.bindAsVertexBuffer(dc);
}
/**
* Binds this buffer as the source of texture coordinates to use when rendering OpenGL primitives. The texture
* coordinate size is equal to coordsPerVertex, the texture coordinate type is equal to buffer's underlying
* BufferWrapper GL type, the stride is 0, and the texture coordinate data itself is this buffer's backing NIO
* Buffer. This buffer's vector size must be 1, 2, 3, or 4.
*
* @param dc the current DrawContext.
*
* @throws IllegalArgumentException if the DrawContext is null, or if this buffer is not compatible as a normal
* buffer.
*/
public void bindAsTexCoordBuffer(DrawContext dc)
{
if (dc == null)
{
String message = Logging.getMessage("nullValue.DrawContextIsNull");
Logging.logger().severe(message);
throw new IllegalArgumentException(message);
}
this.buffer.bindAsTexCoordBuffer(dc);
}
/**
* Renders getTotalBufferSize()
elements from the currently bounds OpenGL coordinate buffers, beginning
* with element 0. The specified drawMode indicates which type of OpenGL primitives to render.
*
* @param dc the current DrawContext.
* @param drawMode the type of OpenGL primtives to render.
*
* @throws IllegalArgumentException if the DrawContext is null.
*/
public void drawArrays(DrawContext dc, int drawMode)
{
if (dc == null)
{
String message = Logging.getMessage("nullValue.DrawContextIsNull");
Logging.logger().severe(message);
throw new IllegalArgumentException(message);
}
this.buffer.drawArrays(dc, drawMode);
}
/**
* Renders elements from the currently bounds OpenGL coordinate buffers. This behaves exactly like {@link
* #drawArrays(gov.nasa.worldwind.render.DrawContext, int)}, except that each sub-buffer is rendered independently.
* The specified drawMode indicates which type of OpenGL primitives to render.
*
* @param dc the current DrawContext.
* @param drawMode the type of OpenGL primtives to render.
*
* @throws IllegalArgumentException if the DrawContext is null.
*/
public void multiDrawArrays(DrawContext dc, int drawMode)
{
if (dc == null)
{
String message = Logging.getMessage("nullValue.DrawContextIsNull");
Logging.logger().severe(message);
throw new IllegalArgumentException(message);
}
GL2 gl = dc.getGL().getGL2(); // GL initialization checks for GL2 compatibility.
if (this.haveMultiDrawArrays(dc))
{
gl.glMultiDrawArrays(drawMode, this.offsets, this.lengths, this.count);
}
else
{
for (int i = 0; i < this.count; i++)
{
gl.glDrawArrays(drawMode, this.offsets.get(i), this.lengths.get(i));
}
}
}
protected boolean haveMultiDrawArrays(DrawContext dc)
{
return dc.getGL().isFunctionAvailable("glMultiDrawArrays");
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy