protected override IntPtr LockImpl( int offset, int length, BufferLocking locking )
{
All access = 0;
if ( isLocked )
{
throw new AxiomException( "Invalid attempt to lock an index buffer that has already been locked" );
}
IntPtr retPtr = IntPtr.Zero;
if ( length < MapBufferThreshold )
{
retPtr = ( (GLESHardwareBufferManager)HardwareBufferManager.Instance ).AllocateScratch( length );
if ( retPtr != IntPtr.Zero )
{
_lockedToScratch = true;
_scratchOffset = offset;
_scratchSize = length;
_scratchPtr = retPtr;
_scratchUploadOnUnlock = ( locking != BufferLocking.ReadOnly );
if ( locking != BufferLocking.Discard )
{
ReadData( offset, length, retPtr );
}
}
}
else
{
throw new AxiomException( "Invalid Buffer lockSize" );
}
if ( retPtr == IntPtr.Zero )
{
OpenGL.BindBuffer( All.ElementArrayBuffer, _bufferId );
// Use glMapBuffer
if ( locking == BufferLocking.Discard )
{
OpenGL.BufferData( All.ElementArrayBuffer, new IntPtr( sizeInBytes ), IntPtr.Zero, GLESHardwareBufferManager.GetGLUsage( usage ) );
}
if ( ( usage & BufferUsage.WriteOnly ) != 0 )
{
access = All.WriteOnlyOes;
}
IntPtr pBuffer = OpenGLOES.MapBuffer( All.ElementArrayBuffer, access );
if ( pBuffer == IntPtr.Zero )
{
throw new AxiomException( "Index Buffer: Out of memory" );
}
unsafe
{
// return offset
retPtr = (IntPtr)( (byte*)pBuffer + offset );
}
_lockedToScratch = false;
}
isLocked = true;
return retPtr;
}