public override void WriteData( int offset, int length, BufferBase src, bool discardWholeBuffer ) { Debug.Assert( ( offset + length ) <= base.sizeInBytes ); using ( var pIntData = BufferBase.Wrap( _mpData, length ).Offset( offset ) ) Memory.Copy( src, pIntData, length ); }
public override void ReadData( int offset, int length, BufferBase dest ) { Debug.Assert( ( offset + length ) <= base.sizeInBytes ); using ( var data = BufferBase.Wrap( _mpData ).Offset( offset ) ) Memory.Copy( dest, data, length ); }
/// <summary> /// </summary> /// <param name="idxType"> </param> /// <param name="numIndexes"> </param> /// <param name="usage"> </param> public GLES2DefaultHardwareIndexBuffer( IndexType idxType, int numIndexes, BufferUsage usage ) : base( null, idxType, numIndexes, usage, true, false ) // always software, never shadowed { if ( idxType == IndexType.Size32 ) { throw new AxiomException( "32 bit hardware buffers are not allowed in OpenGL ES." ); } this._data = new byte[ sizeInBytes ]; this._dataPtr = BufferBase.Wrap( this._data ); }
public void Convert(BufferBase input, BufferBase output, int offset) { #if !AXIOM_SAFE_ONLY unsafe #endif { var inputPtr = input.ToBytePointer(); var outputPtr = output.ToUIntPointer(); var inp = inputPtr[offset]; outputPtr[offset] = 0xFF000000 | (((uint)inp) << 0) | (((uint)inp) << 8) | (((uint)inp) << 16); } }
/// <summary> /// </summary> /// <param name="offset"> </param> /// <param name="length"> </param> /// <param name="dest"> </param> public override void ReadData(int offset, int length, BufferBase dest) { if (useShadowBuffer) { var srcData = shadowBuffer.Lock(offset, length, BufferLocking.ReadOnly); Memory.Copy(srcData, dest, length); shadowBuffer.Unlock(); } else { throw new AxiomException("Reading hardware buffer is not supported."); } }
public void WriteContentsToFile(string fileName) { var pf = SuggestPixelFormat(); var data = new byte[Width * Height * PixelUtil.GetNumElemBytes(pf)]; var buf = BufferBase.Wrap(data); var pb = new PixelBox(Width, Height, 1, pf, buf); CopyContentsToMemory(pb); (new Image()).FromDynamicImage(data, Width, Height, 1, pf, false, 1, 0).Save(fileName); buf.Dispose(); }
protected void SetBuffer(byte[] newBuffer) { if (this.buffer != null) { this.bufPtr = null; this.buffer = null; } if (newBuffer != null) { this.buffer = newBuffer; this.bufPtr = BufferBase.Wrap(newBuffer); } }
protected void allocateBuffer() { if (buffer.Data != null) { // Already allocated return; } // Allocate storage this._data = new byte[sizeInBytes]; buffer.Data = BufferBase.Wrap(this._data); // TODO: use PBO if we're HBU_DYNAMIC }
public void Convert(BufferBase input, BufferBase output, int offset) { #if !AXIOM_SAFE_ONLY unsafe #endif { var inputPtr = input.ToUIntPointer(); var outputPtr = output.ToUIntPointer(); var inp = inputPtr[offset]; outputPtr[offset] = ((inp & 0x0000FF00) << 16) | (inp & 0x00FF00FF) | ((inp & 0xFF000000) >> 16); } }
public void Convert(BufferBase input, BufferBase output, int offset) { #if !AXIOM_SAFE_ONLY unsafe #endif { var inputPtr = input.ToUIntPointer(); var outputPtr = output.ToBytePointer(); var inp = inputPtr[offset]; outputPtr[offset] = (byte)(inp & 0x000000FF); } }
public static byte[] GetBuffer(string _src) { byte[] strbyte = Encoding.UTF8.GetBytes(_src); byte[] lenbyte = BufferBase.GetBuffer((short)strbyte.Length); byte[] ret = new byte[strbyte.Length + lenbyte.Length]; lenbyte.CopyTo(ret, 0); if (strbyte.Length > 0) { strbyte.CopyTo(ret, lenbyte.Length); } return(ret); }
public override void WriteData(int offset, int length, BufferBase src, bool discardWholeBuffer) { // There is no functional interface in D3D, just do via manual // lock, copy & unlock // lock the buffer real quick var dest = Lock(offset, length, discardWholeBuffer ? BufferLocking.Discard : BufferLocking.Normal); // copy that data in there Memory.Copy(src, dest, length); // unlock the buffer Unlock(); }
/// <summary> /// Writes a specified number of floats. /// </summary> /// <param name="writer"></param> /// <param name="count">Number of values to write.</param> /// <param name="src">Pointer that holds the values.</param> protected void WriteFloats(BinaryWriter writer, int count, BufferBase src) { #if !AXIOM_SAFE_ONLY unsafe #endif { var pointer = src.ToFloatPointer(); for (var i = 0; i < count; i++) { writer.Write(pointer[i]); } } }
/// <summary> /// Reads a specified number of shorts and copies them into the destination pointer. /// </summary> /// <param name="reader"></param> /// <param name="count">Number of values to read.</param> /// <param name="dest">Pointer to copy the values into.</param> protected void ReadShorts(BinaryReader reader, int count, BufferBase dest) { // blast the data into the buffer #if !AXIOM_SAFE_ONLY unsafe #endif { var pointer = dest.ToShortPointer(); for (var i = 0; i < count; i++) { pointer[i] = ReadShort(reader); } } }
///<summary> ///</summary> ///<param name="offset"> </param> ///<param name="length"> </param> ///<param name="locking"> </param> ///<returns> </returns> protected override BufferBase LockImpl(int offset, int length, BufferLocking locking) { int access = 0; if (isLocked) { throw new Exception("Invalid attempt to lock an index buffer that has already been locked."); } // bind this buffer Gl.glBindBufferARB(Gl.GL_ELEMENT_ARRAY_BUFFER_ARB, this._bufferId); if (locking == BufferLocking.Discard) { // commented out to fix ATI issues /*Gl.glBufferDataARB(Gl.GL_ELEMENT_ARRAY_BUFFER_ARB, * sizeInBytes, * IntPtr.Zero, * GLHelper.ConvertEnum(usage)); */ // find out how we shall access this buffer access = (usage == BufferUsage.Dynamic) ? Gl.GL_READ_WRITE_ARB : Gl.GL_WRITE_ONLY_ARB; } else if (locking == BufferLocking.ReadOnly) { if (usage == BufferUsage.WriteOnly) { LogManager.Instance.Write("OGL : Invalid attempt to lock a write-only vertex buffer as read-only."); } access = Gl.GL_READ_ONLY_ARB; } else if (locking == BufferLocking.Normal || locking == BufferLocking.NoOverwrite) { access = (usage == BufferUsage.Dynamic) ? Gl.GL_READ_WRITE_ARB : Gl.GL_WRITE_ONLY_ARB; } IntPtr ptr = Gl.glMapBufferARB(Gl.GL_ELEMENT_ARRAY_BUFFER_ARB, access); if (ptr == IntPtr.Zero) { throw new Exception("OGL: Vertex Buffer: Out of memory"); } isLocked = true; return(BufferBase.Wrap(new IntPtr(ptr.ToInt64() + offset), length)); }
public override void ReadData(int offset, int length, BufferBase dest) { // There is no functional interface in D3D, just do via manual // lock, copy & unlock // lock the buffer for reading var src = Lock(offset, length, BufferLocking.ReadOnly); // copy that data in there Memory.Copy(src, dest, length); // unlock the buffer Unlock(); }
/// <summary> /// Writes a specified number of shorts. /// </summary> /// <param name="writer"></param> /// <param name="count">Number of values to write.</param> /// <param name="src">Pointer that holds the values.</param> protected void WriteShorts(BinaryWriter writer, int count, BufferBase src) { // blast the data into the buffer #if !AXIOM_SAFE_ONLY unsafe #endif { var pointer = src.ToShortPointer(); for (var i = 0; i < count; i++) { writer.Write(pointer[i]); } } }
///<summary> /// Copies a region from normal memory to a region of this pixelbuffer. The source /// image can be in any pixel format supported by Axiom, and in any size. ///</summary> ///<param name="src">PixelBox containing the source pixels and format in memory</param> ///<param name="dstBox">Image.BasicBox describing the destination region in this buffer</param> ///<remarks> /// The source and destination regions dimensions don't have to match, in which /// case scaling is done. This scaling is generally done using a bilinear filter in hardware, /// but it is faster to pass the source image in the right dimensions. /// Only call this function when both buffers are unlocked. ///</remarks> public override void BlitFromMemory(PixelBox src, BasicBox dstBox) { var converted = src; var bufGCHandle = new GCHandle(); var bufSize = 0; // Get src.Data as byte[] bufSize = PixelUtil.GetMemorySize(src.Width, src.Height, src.Depth, Format); var newBuffer = new byte[bufSize]; //bufGCHandle = GCHandle.Alloc( newBuffer, GCHandleType.Pinned ); //XnaHelper.Convert(XFG.SurfaceFormat) would never have returned SurfaceFormat.Unknown anyway... //if (XnaHelper.Convert(src.Format) != XFG.SurfaceFormat.Unknown) { converted = new PixelBox(src.Width, src.Height, src.Depth, Format, BufferBase.Wrap(newBuffer)); PixelConverter.BulkPixelConversion(src, converted); } //else //{ // Memory.Copy(converted.Data, BufferBase.Wrap(newBuffer), bufSize); //} if (surface != null) { surface.SetData(mipLevel, XnaHelper.ToRectangle(dstBox), newBuffer, 0, bufSize); } else if (cube != null) { cube.SetData(face, mipLevel, XnaHelper.ToRectangle(dstBox), newBuffer, 0, bufSize); } else { throw new NotSupportedException("BlitFromMemory on Volume Textures not supported."); } // If we allocated a buffer for the temporary conversion, free it here if (bufGCHandle.IsAllocated) { bufGCHandle.Free(); } if (doMipmapGen) { GenMipmaps(); } }
public override void EncodeToFile(Stream input, string outFileName, Codec.CodecData codecData) { int imageID; // create and bind a new image Il.ilGenImages(1, out imageID); Il.ilBindImage(imageID); var buffer = new byte[input.Length]; input.Read(buffer, 0, buffer.Length); var imgData = (ImageData)codecData; PixelBox src; using (var bufHandle = BufferBase.Wrap(buffer)) { src = new PixelBox(imgData.width, imgData.height, imgData.depth, imgData.format, bufHandle); } try { // Convert image from Axiom to current IL image ILUtil.ConvertToIL(src); } catch (Exception ex) { LogManager.Instance.Write("IL Failed image conversion :", ex.Message); } // flip the image Ilu.iluFlipImage(); // save the image to file Il.ilSaveImage(outFileName); var error = Il.ilGetError(); if (error != Il.IL_NO_ERROR) { LogManager.Instance.Write("IL Error, could not save file: {0} : {1}", outFileName, Ilu.iluErrorString(error)); } Il.ilDeleteImages(1, ref imageID); }
/// <summary> /// Reads a specified number of floats and copies them into the destination pointer. /// </summary> /// <remarks>This overload will also copy the values into the specified destination array.</remarks> /// <param name="reader"></param> /// <param name="count">Number of values to read.</param> /// <param name="dest">Pointer to copy the values into.</param> /// <param name="destArray">A float array that is to have the values copied into it at the same time as 'dest'.</param> protected void ReadFloats(BinaryReader reader, int count, BufferBase dest, float[] destArray) { // blast the data into the buffer #if !AXIOM_SAFE_ONLY unsafe #endif { var pointer = dest.ToFloatPointer(); for (var i = 0; i < count; i++) { var val = ReadFloat(reader); pointer[i] = val; destArray[i] = val; } } }
public override void ReadData(int offset, int length, BufferBase dest) { //Debug.Assert(!isLocked, "Cannot lock this buffer because it is already locked."); //imitating render system specific hardware buffer behaviour Debug.Assert(offset >= 0 && (offset + length) <= sizeInBytes, "Buffer overrun while trying to read a software buffer."); unsafe { // get a pointer to the destination intptr byte *pDest = (byte *)dest.Ptr; // copy the src data to the destination buffer for (int i = 0; i < length; i++) { pDest[offset + i] = data[offset + i]; } } }
public override void WriteData(int offset, int length, BufferBase src, bool discardWholeBuffer) { //Debug.Assert( !isLocked, "Cannot lock this buffer because it is already locked." ); //imitating render system specific hardware buffer behaviour Debug.Assert(offset >= 0 && (offset + length) <= sizeInBytes, "Buffer overrun while trying to write to a software buffer."); unsafe { // get a pointer to the destination intptr byte *pSrc = (byte *)src.Ptr; // copy the src data to the destination buffer for (int i = 0; i < length; i++) { data[offset + i] = pSrc[offset + i]; } } }
public void Convert(BufferBase input, BufferBase output, int offset) { #if !AXIOM_SAFE_ONLY unsafe #endif { var inputPtr = input.ToUIntPointer(); var outputPtr = output.ToCol3BPointer(); var inp = inputPtr[offset]; outputPtr[offset] = new Col3b { x = (byte)((inp >> 0) & 0xFF), y = (byte)((inp >> 8) & 0xFF), z = (byte)((inp >> 16) & 0xFF), }; } }
private void _flipEndian(BufferBase pData, int size) { #if AXIOM_BIG_ENDIAN byte swapByte; #if !AXIOM_SAFE_ONLY unsafe #endif { var ptr = pData.ToBytePointer(); for (var byteIndex = 0; byteIndex < size / 2; byteIndex++) { swapByte = ptr[byteIndex]; ptr[byteIndex] = ptr[size - byteIndex - 1]; ptr[size - byteIndex - 1] = swapByte; } } #endif }
public override string MagicNumberToFileExt(byte[] magicNumberBuf, int maxbytes) { if (maxbytes >= sizeof(int)) { var fileType = BitConverter.ToInt32(magicNumberBuf, 0); using (var data = BufferBase.Wrap(fileType, 2)) { _flipEndian(data, sizeof(int), 1); } if (this.PVR_MAGIC == fileType) { return("pvr"); } } return(string.Empty); }
public void Update() { if (this.mData != null && this.mDirty) { using (var mDataBuf = BufferBase.Wrap(this.mData, mData.Length * sizeof(float))) { var pSrcBase = mDataBuf + (this.mDirtyBox.Top * this.mBuffer.Width + this.mDirtyBox.Left); var pDstBase = this.mBuffer.Lock(this.mDirtyBox, BufferLocking.Normal).Data; pDstBase += this.mChannelOffset; var dstInc = PixelUtil.GetNumElemBytes(this.mBuffer.Format); #if !AXIOM_SAFE_ONLY unsafe #endif { for (int y = 0; y < this.mDirtyBox.Height; ++y) { var pSrc = (pSrcBase + (y * this.mBuffer.Width) * sizeof(float)).ToFloatPointer(); var pDst = pDstBase + (y * this.mBuffer.Width * dstInc); for (int x = 0; x < this.mDirtyBox.Width; ++x) { pDst.ToBytePointer()[0] = (byte)(pSrc[x] * 255); pDst += dstInc; } } } this.mBuffer.Unlock(); this.mDirty = false; } // make sure composite map is updated // mDirtyBox is in image space, convert to terrain units var compositeMapRect = new Rectangle(); var blendToTerrain = (float)this.mParent.Size / (float)this.mBuffer.Width; compositeMapRect.Left = (long)(this.mDirtyBox.Left * blendToTerrain); compositeMapRect.Right = (long)(this.mDirtyBox.Right * blendToTerrain + 1); compositeMapRect.Top = (long)((this.mBuffer.Height - this.mDirtyBox.Bottom) * blendToTerrain); compositeMapRect.Bottom = (long)((this.mBuffer.Height - this.mDirtyBox.Top) * blendToTerrain + 1); this.mParent.DirtyCompositeMapRect(compositeMapRect); this.mParent.UpdateCompositeMapWithDelay(); } }
/// <summary> /// Updates buffer resources from system memory buffer. /// </summary> private bool _updateBufferResources(BufferBase systemMemoryBuffer, ref BufferResources bufferResources) { Contract.RequiresNotNull(bufferResources, "Cannot update BufferResources in D3D9HardwareIndexBuffer!"); Contract.RequiresNotNull(bufferResources.IndexBuffer, "Cannot update BufferResources in D3D9HardwareIndexBuffer!"); Contract.Requires(bufferResources.IsOutOfDate); DX.DataStream dstBytes; // Lock the buffer try { dstBytes = bufferResources.IndexBuffer.Lock(bufferResources.LockOffset, bufferResources.LockLength, D3D9Helper.ConvertEnum(bufferResources.LockOptions, usage)); } catch (Exception ex) { throw new AxiomException("Cannot lock D3D9 index buffer!", ex); } using (var src = systemMemoryBuffer + bufferResources.LockOffset) { using (var dest = BufferBase.Wrap(dstBytes.DataPointer, (int)dstBytes.Length)) { Memory.Copy(src, dest, bufferResources.LockLength); } } // Unlock the buffer. var hr = bufferResources.IndexBuffer.Unlock(); if (hr.Failure) { throw new AxiomException("Cannot unlock D3D9 index buffer: {0}", hr.ToString()); } bufferResources.IsOutOfDate = false; bufferResources.LockOffset = sizeInBytes; bufferResources.LockLength = 0; bufferResources.LockOptions = BufferLocking.Normal; return(true); }
///<summary> ///</summary> ///<param name="offset"> </param> ///<param name="length"> </param> ///<param name="dest"> </param> public override void ReadData(int offset, int length, BufferBase dest) { if (useShadowBuffer) { // lock the buffer for reading var src = shadowBuffer.Lock(offset, length, BufferLocking.ReadOnly); // copy that data in there Memory.Copy(src, dest, length); // unlock the buffer shadowBuffer.Unlock(); } else { Gl.glBindBufferARB(Gl.GL_ELEMENT_ARRAY_BUFFER_ARB, this._bufferId); Gl.glGetBufferSubDataARB(Gl.GL_ELEMENT_ARRAY_BUFFER_ARB, new IntPtr(offset), new IntPtr(length), dest.Pin()); dest.UnPin(); } }
public void SetBuffer(byte[] _buffer, int _offset) { DataUsed = false; mCSLEObject = null; mIndex = 0; int tindex = _offset; mLen = BufferBase.SReadShort(_buffer, tindex); tindex += sizeof(short); mCmd = BufferBase.SReadShort(_buffer, tindex); tindex += sizeof(short); if (mData == null || mLen > mData.Length) { mData = new byte[mLen]; } else { mData.Initialize(); } Array.Copy(_buffer, tindex, mData, 0, mLen); }
public void Convert(BufferBase input, BufferBase output, int offset) { #if !AXIOM_SAFE_ONLY unsafe #endif { var inputPtr = input.ToCol3BPointer(); var outputPtr = output.ToUIntPointer(); var inp = inputPtr[offset]; int xshift = 8, yshift = 16, zshift = 24, ashift = 0; #if AXIOM_BIG_ENDIAN outputPtr[offset] = ((uint)(0xFF << ashift)) | (((uint)inp.x) << xshift) | (((uint)inp.y) << yshift) | (((uint)inp.z) << zshift); #else outputPtr[offset] = ((uint)(0xFF << ashift)) | (((uint)inp.x) << zshift) | (((uint)inp.y) << yshift) | (((uint)inp.z) << xshift); #endif } }
public D3D9HardwareVertexBuffer(HardwareBufferManagerBase manager, VertexDeclaration vertexDeclaration, int numVertices, BufferUsage usage, bool useSystemMemory, bool useShadowBuffer) : base(manager, vertexDeclaration, numVertices, usage, useSystemMemory, useShadowBuffer) { //Entering critical section this.LockDeviceAccess(); this._mapDeviceToBufferResources = new Dictionary <D3D9.Device, BufferResources>(); #if AXIOM_D3D_MANAGE_BUFFERS var eResourcePool = useSystemMemory ? D3D9.Pool.SystemMemory : // If not system mem, use managed pool UNLESS buffer is discardable // if discardable, keeping the software backing is expensive ((usage & BufferUsage.Discardable) != 0) ? D3D9.Pool.Default : D3D9.Pool.Managed; #else var eResourcePool = useSystemMemory ? D3D9.Pool.SystemMemory : D3D9.Pool.Default; #endif // Set the desired memory pool. this._bufferDesc.Pool = eResourcePool; // Allocate the system memory buffer. this._systemMemoryBuffer = BufferBase.Wrap(new byte[sizeInBytes]); // Case we have to create this buffer resource on loading. if (D3D9RenderSystem.ResourceManager.CreationPolicy == D3D9ResourceManager.ResourceCreationPolicy.CreateOnAllDevices) { foreach (var d3d9Device in D3D9RenderSystem.ResourceCreationDevices) { CreateBuffer(d3d9Device, this._bufferDesc.Pool); } } D3D9RenderSystem.ResourceManager.NotifyResourceCreated(this); //Leaving critical section this.UnlockDeviceAccess(); }
public override string MagicNumberToFileExt(byte[] magicBuf, int maxbytes) { FI.FIMEMORY fiMem; FI.FREE_IMAGE_FORMAT fif; using (var ptr = BufferBase.Wrap(magicBuf)) { fiMem = FI.FreeImage.OpenMemory(ptr.Pin(), (uint)maxbytes); ptr.UnPin(); fif = FI.FreeImage.GetFileTypeFromMemory(fiMem, maxbytes); FI.FreeImage.CloseMemory(fiMem); } if (fif != FI.FREE_IMAGE_FORMAT.FIF_UNKNOWN) { return(FI.FreeImage.GetFormatFromFIF(fif).ToLower()); } else { return(string.Empty); } }
/// <summary> /// </summary> /// <param name="offset"> </param> /// <param name="length"> </param> /// <param name="src"> </param> /// <param name="discardWholeBuffer"> </param> public override void WriteData(int offset, int length, BufferBase src, bool discardWholeBuffer) { OpenGL.BindBuffer(All.ElementArrayBuffer, this._bufferId); GLESConfig.GlCheckError(this); // Update the shadow buffer if (useShadowBuffer) { var destData = shadowBuffer.Lock(offset, length, discardWholeBuffer ? BufferLocking.Discard : BufferLocking.Normal); Memory.Copy(src, destData, length); shadowBuffer.Unlock(); } var srcPtr = src.Ptr; if (offset == 0 && length == sizeInBytes) { OpenGL.BufferData(All.ElementArrayBuffer, new IntPtr(sizeInBytes), ref srcPtr, GLESHardwareBufferManager.GetGLUsage(usage)); GLESConfig.GlCheckError(this); } else { if (discardWholeBuffer) { OpenGL.BufferData(All.ElementArrayBuffer, new IntPtr(sizeInBytes), IntPtr.Zero, GLESHardwareBufferManager.GetGLUsage(usage)); GLESConfig.GlCheckError(this); } // Now update the real buffer OpenGL.BufferSubData(All.ElementArrayBuffer, new IntPtr(offset), new IntPtr(length), ref srcPtr); GLESConfig.GlCheckError(this); } if (src.Ptr != srcPtr) { LogManager.Instance.Write("[GLES2] HardwareIndexBuffer.WriteData - buffer pointer modified by GL.BufferData."); } }
/// <summary> /// Constructor. /// </summary> /// <param name="owner">Reference to the hardware buffer who owns this stream.</param> /// <param name="data">Pointer to the raw data we will be writing to.</param> internal BufferStream( HardwareBuffer owner, BufferBase data ) { this.data = data; this.owner = owner; }
private void Unpack( ref ColorEx dst, int x, int y, int z, PixelFormat format, BufferBase src, PixelBox srcbox, int elemsize ) { var data = src + ( elemsize*( ( x ) + ( y )*srcbox.RowPitch + ( z )*srcbox.SlicePitch ) ); dst = PixelConverter.UnpackColor( format, data ); }
/// <summary> /// Caches a face group and calculates texture lighting coordinates. /// </summary> protected int CacheLightGeometry( TextureLight light, BufferBase pIndexesBuf, BufferBase pTexLightMapsBuf, BufferBase pVerticesBuf, BspStaticFaceGroup faceGroup ) { #if !AXIOM_SAFE_ONLY unsafe #endif { // Skip sky always if ( faceGroup.isSky ) { return 0; } int idxStart = 0; int numIdx = 0; int vertexStart = 0; if ( faceGroup.type == FaceGroup.FaceList ) { idxStart = faceGroup.elementStart; numIdx = faceGroup.numElements; vertexStart = faceGroup.vertexStart; } else if ( faceGroup.type == FaceGroup.Patch ) { idxStart = faceGroup.patchSurf.IndexOffset; numIdx = faceGroup.patchSurf.CurrentIndexCount; vertexStart = faceGroup.patchSurf.VertexOffset; } else { // Unsupported face type return 0; } var idxSize = this.level.Indexes.IndexSize; var idxSrc = this.level.Indexes.Lock( idxStart*idxSize, numIdx*idxSize, BufferLocking.ReadOnly ); #if SILVERLIGHT var src = idxSrc.ToUShortPointer(); #else var src = idxSrc.ToUIntPointer(); #endif int maxIndex = 0; for ( int i = 0; i < numIdx; i++ ) { var index = (int)src[ i ]; if ( index > maxIndex ) { maxIndex = index; } } var vertexPos = new Vector3[maxIndex + 1]; var vertexIsStored = new bool[maxIndex + 1]; for ( int i = 0; i < numIdx; i++ ) { var index = (int)src[ i ]; var pVertices = pVerticesBuf.ToBspVertexPointer(); if ( !vertexIsStored[ index ] ) { vertexPos[ index ] = pVertices[ vertexStart + index ].position; vertexIsStored[ index ] = true; } pVerticesBuf.UnPin(); } Vector2[] texCoors; ColorEx[] colors; bool res = light.CalculateTexCoordsAndColors( faceGroup.plane, vertexPos, out texCoors, out colors ); if ( res ) { var pTexLightMaps = pTexLightMapsBuf.ToTextureLightMapPointer(); for ( int i = 0; i <= maxIndex; i++ ) { pTexLightMaps[ vertexStart + i ] = new TextureLightMap { color = Root.Instance.RenderSystem.ConvertColor( colors[ i ] ), textureLightMap = texCoors[ i ] }; } pTexLightMapsBuf.UnPin(); // Offset the indexes here // we have to do this now rather than up-front because the // indexes are sometimes reused to address different vertex chunks if ( this.level.Indexes.Type == IndexType.Size16 ) { var pIndexes = pIndexesBuf.ToUShortPointer(); for ( int i = 0; i < numIdx; i++ ) { pIndexes[ i ] = (ushort)( src[ i ] + vertexStart ); } } else { var pIndexes = pIndexesBuf.ToUIntPointer(); for ( int i = 0; i < numIdx; i++ ) { pIndexes[ i ] = (uint)( src[ i ] + vertexStart ); } } this.level.Indexes.Unlock(); // return number of elements return numIdx; } else { this.level.Indexes.Unlock(); return 0; } } }
/// <summary> /// Writes a specified number of shorts. /// </summary> /// <param name="writer"></param> /// <param name="count">Number of values to write.</param> /// <param name="src">Pointer that holds the values.</param> protected void WriteShorts( BinaryWriter writer, int count, BufferBase src ) { // blast the data into the buffer #if !AXIOM_SAFE_ONLY unsafe #endif { var pointer = src.ToShortPointer(); for ( var i = 0; i < count; i++ ) { writer.Write( pointer[ i ] ); } } }
public override void WriteData( int offset, int length, BufferBase src, bool discardWholeBuffer ) { //Update the shadow buffer if ( useShadowBuffer ) { var destData = shadowBuffer.Lock( offset, length, discardWholeBuffer ? BufferLocking.Discard : BufferLocking.Normal ); src = destData; shadowBuffer.Unlock(); } if ( offset == 0 && length == sizeInBytes ) { GL.BufferData( GLenum.ArrayBuffer, new IntPtr( sizeInBytes ), src.Pin(), GLESHardwareBufferManager.GetGLUsage( usage ) ); GLESConfig.GlCheckError( this ); } else { if ( discardWholeBuffer ) { GL.BufferData( GLenum.ArrayBuffer, new IntPtr( sizeInBytes ), IntPtr.Zero, GLESHardwareBufferManager.GetGLUsage( usage ) ); GLESConfig.GlCheckError( this ); } GL.BufferSubData( GLenum.ArrayBuffer, new IntPtr( offset ), new IntPtr( length ), src.Pin() ); GLESConfig.GlCheckError( this ); } }
/// <summary> /// </summary> /// <param name="offset"> </param> /// <param name="length"> </param> /// <param name="src"> </param> /// <param name="discardWholeBuffer"> </param> public override void WriteData( int offset, int length, BufferBase src, bool discardWholeBuffer ) { OpenGL.BindBuffer( All.ElementArrayBuffer, this._bufferId ); GLESConfig.GlCheckError( this ); // Update the shadow buffer if ( useShadowBuffer ) { var destData = shadowBuffer.Lock( offset, length, discardWholeBuffer ? BufferLocking.Discard : BufferLocking.Normal ); Memory.Copy( src, destData, length ); shadowBuffer.Unlock(); } var srcPtr = src.Ptr; if ( offset == 0 && length == sizeInBytes ) { OpenGL.BufferData( All.ElementArrayBuffer, new IntPtr( sizeInBytes ), ref srcPtr, GLESHardwareBufferManager.GetGLUsage( usage ) ); GLESConfig.GlCheckError( this ); } else { if ( discardWholeBuffer ) { OpenGL.BufferData( All.ElementArrayBuffer, new IntPtr( sizeInBytes ), IntPtr.Zero, GLESHardwareBufferManager.GetGLUsage( usage ) ); GLESConfig.GlCheckError( this ); } // Now update the real buffer OpenGL.BufferSubData( All.ElementArrayBuffer, new IntPtr( offset ), new IntPtr( length ), ref srcPtr ); GLESConfig.GlCheckError( this ); } if ( src.Ptr != srcPtr ) { LogManager.Instance.Write( "[GLES2] HardwareIndexBuffer.WriteData - buffer pointer modified by GL.BufferData." ); } }
/// <summary> /// </summary> /// <param name="vertexSize"> </param> /// <param name="numVertices"> </param> /// <param name="usage"> </param> public GLDefaultHardwareVertexBuffer(VertexDeclaration declaration, int numVertices, BufferUsage usage) : base( null, declaration, numVertices, usage, true, false ) { this._data = new byte[ declaration.GetVertexSize() * numVertices ]; this._dataPtr = BufferBase.Wrap( this._data ); }
protected override BufferBase LockImpl( int offset, int length, BufferLocking locking ) { if ( IsLocked ) { throw new AxiomException( "Invalid attempt to lock an index buffer that has already been locked." ); } BufferBase retPtr; var glBufManager = ( HardwareBufferManager.Instance as GLESHardwareBufferManager ); //Try to use scratch buffers for smaller buffers if ( length < glBufManager.MapBufferThreshold ) { retPtr = glBufManager.AllocateScratch( length ); if ( retPtr != null ) { this._lockedToScratch = true; this._scratchOffset = offset; this._scratchSize = length; this._scratchPtr = retPtr; this._scratchUploadOnUnlock = ( locking != BufferLocking.ReadOnly ); if ( locking != BufferLocking.Discard ) { //have to read back the data before returning the pointer this.ReadData( offset, length, retPtr ); } } } else { throw new AxiomException( "Invalid Buffer lockSize" ); } if ( retPtr == null ) { GLenum access = GLenum.Zero; ( Root.Instance.RenderSystem as GLESRenderSystem ).BindGLBuffer( GLenum.ArrayBuffer, this._bufferID ); if ( locking == BufferLocking.Discard ) { //Discard the buffer GL.BufferData( GLenum.ArrayBuffer, new IntPtr( sizeInBytes ), IntPtr.Zero, GLESHardwareBufferManager.GetGLUsage( usage ) ); GLESConfig.GlCheckError( this ); } if ( ( usage & BufferUsage.WriteOnly ) == BufferUsage.WriteOnly ) { access = GLenum.WriteOnlyOes; } var pbuffer = GL.Oes.MapBuffer( GLenum.ArrayBuffer, access ); GLESConfig.GlCheckError( this ); if ( pbuffer == IntPtr.Zero ) { throw new AxiomException( "Vertex Buffer: Out of memory" ); } //return offsetted retPtr = BufferBase.Wrap( pbuffer, sizeInBytes ) + offset; this._lockedToScratch = false; } isLocked = true; return retPtr; }
public override void WriteData( int offset, int length, BufferBase source, bool discardWholeBuffer ) { throw new AxiomException( "Writing a byte range is not implemented. Use BlitToMemory." ); }
public override void WriteData( int offset, int length, BufferBase src, bool discardWholeBuffer ) { // There is no functional interface in D3D, just do via manual // lock, copy & unlock // lock the buffer real quick var dest = Lock( offset, length, discardWholeBuffer ? BufferLocking.Discard : BufferLocking.Normal ); // copy that data in there Memory.Copy( src, dest, length ); // unlock the buffer Unlock(); }
public override void ReadData( int offset, int length, BufferBase dest ) { throw new AxiomException( "Reading a byte range is not implemented. Use BlitToMemory." ); }
/// <summary> /// /// </summary> /// <param name="offset"></param> /// <param name="length"></param> /// <param name="dest"></param> public override void ReadData( int offset, int length, BufferBase dest ) { if ( useShadowBuffer ) { // lock the buffer for reading var src = shadowBuffer.Lock( offset, length, BufferLocking.ReadOnly ); // copy that data in there Memory.Copy( src, dest, length ); // unlock the buffer shadowBuffer.Unlock(); } else { Gl.glBindBufferARB( Gl.GL_ARRAY_BUFFER_ARB, this.bufferID ); Gl.glGetBufferSubDataARB( Gl.GL_ARRAY_BUFFER_ARB, new IntPtr( offset ), new IntPtr( length ), dest.Pin() ); // TAO 2.0 dest.UnPin(); //Gl.glGetBufferSubDataARB( // Gl.GL_ARRAY_BUFFER_ARB, // offset, // length, // dest ); } }
/// <summary> /// /// </summary> /// <param name="offset"></param> /// <param name="length"></param> /// <param name="src"></param> /// <param name="discardWholeBuffer"></param> public override void WriteData( int offset, int length, BufferBase src, bool discardWholeBuffer ) { Gl.glBindBufferARB( Gl.GL_ARRAY_BUFFER_ARB, this.bufferID ); if ( useShadowBuffer ) { // lock the buffer for reading var dest = shadowBuffer.Lock( offset, length, discardWholeBuffer ? BufferLocking.Discard : BufferLocking.Normal ); // copy that data in there Memory.Copy( src, dest, length ); // unlock the buffer shadowBuffer.Unlock(); } if ( discardWholeBuffer ) { Gl.glBufferDataARB( Gl.GL_ARRAY_BUFFER_ARB, new IntPtr( sizeInBytes ), IntPtr.Zero, GLHelper.ConvertEnum( usage ) ); // TAO 2.0 //Gl.glBufferDataARB( Gl.GL_ARRAY_BUFFER_ARB, // sizeInBytes, // IntPtr.Zero, // GLHelper.ConvertEnum( usage ) ); } Gl.glBufferSubDataARB( Gl.GL_ARRAY_BUFFER_ARB, new IntPtr( offset ), new IntPtr( length ), src.Pin() ); // TAO 2.0 src.UnPin(); //Gl.glBufferSubDataARB( // Gl.GL_ARRAY_BUFFER_ARB, // offset, // length, // src ); }
protected void WriteGeometryVertexBufferData( BinaryWriter writer, int count, BufferBase buf ) { var start_offset = writer.Seek( 0, SeekOrigin.Current ); WriteChunk( writer, MeshChunkID.GeometryVertexBufferData, 0 ); WriteBytes( writer, count, buf ); var end_offset = writer.Seek( 0, SeekOrigin.Current ); writer.Seek( (int)start_offset, SeekOrigin.Begin ); WriteChunk( writer, MeshChunkID.GeometryVertexBufferData, (int)( end_offset - start_offset ) ); writer.Seek( (int)end_offset, SeekOrigin.Begin ); }
/// <summary> /// </summary> /// <param name="offset"> </param> /// <param name="length"> </param> /// <param name="src"> </param> /// <param name="discardWholeBuffer"> </param> public override void WriteData( int offset, int length, BufferBase src, bool discardWholeBuffer ) { Contract.Requires( ( offset + length ) <= sizeInBytes ); // ignore discard, memory is not guaranteed to be zeroised Memory.Copy( src, this._dataPtr + offset, length ); }
public int StitchEdge( Neighbor neighbor, int hiLOD, int loLOD, bool omitFirstTri, bool omitLastTri, BufferBase ppIdx ) #endif { Debug.Assert( loLOD > hiLOD, "TerrainZoneRenderable.StitchEdge" ); /* Now do the stitching; we can stitch from any level to any level. The stitch pattern is like this for each pair of vertices in the lower LOD (excuse the poor ascii art): lower LOD *-----------* |\ \ 3 / /| |1\2 \ / 4/5| *--*--*--*--* higher LOD The algorithm is, for each pair of lower LOD vertices: 1. Iterate over the higher LOD vertices, generating tris connected to the first lower LOD vertex, up to and including 1/2 the span of the lower LOD over the higher LOD (tris 1-2). Skip the first tri if it is on the edge of the tile and that edge is to be stitched itself. 2. Generate a single tri for the middle using the 2 lower LOD vertices and the middle vertex of the higher LOD (tri 3). 3. Iterate over the higher LOD vertices from 1/2 the span of the lower LOD to the end, generating tris connected to the second lower LOD vertex (tris 4-5). Skip the last tri if it is on the edge of a tile and that edge is to be stitched itself. The same algorithm works for all edges of the patch; stitching is done clockwise so that the origin and steps used change, but the general approach does not. */ // Get pointer to be updated var pIdx = ppIdx.ToUShortPointer(); var idx = 0; // Work out the steps ie how to increment indexes // Step from one vertex to another in the high detail version var step = 1 << hiLOD; // Step from one vertex to another in the low detail version var superstep = 1 << loLOD; // Step half way between low detail steps var halfsuperstep = superstep >> 1; // Work out the starting points and sign of increments // We always work the strip clockwise int startx, starty, endx, rowstep; startx = starty = endx = rowstep = 0; var horizontal = false; switch ( neighbor ) { case Neighbor.NORTH: startx = starty = 0; endx = this.mOptions.tileSize - 1; rowstep = step; horizontal = true; break; case Neighbor.SOUTH: // invert x AND y direction, helps to keep same winding startx = starty = this.mOptions.tileSize - 1; endx = 0; rowstep = -step; step = -step; superstep = -superstep; halfsuperstep = -halfsuperstep; horizontal = true; break; case Neighbor.EAST: startx = 0; endx = this.mOptions.tileSize - 1; starty = this.mOptions.tileSize - 1; rowstep = -step; horizontal = false; break; case Neighbor.WEST: startx = this.mOptions.tileSize - 1; endx = 0; starty = 0; rowstep = step; step = -step; superstep = -superstep; halfsuperstep = -halfsuperstep; horizontal = false; break; } var numIndexes = 0; for ( var j = startx; j != endx; j += superstep ) { int k; for ( k = 0; k != halfsuperstep; k += step ) { var jk = j + k; //skip the first bit of the corner? if ( j != startx || k != 0 || !omitFirstTri ) { if ( horizontal ) { pIdx[ idx++ ] = Index( jk, starty + rowstep ); numIndexes++; // original order: 2 pIdx[ idx++ ] = Index( jk + step, starty + rowstep ); numIndexes++; // original order: 3 pIdx[ idx++ ] = Index( j, starty ); numIndexes++; // original order: 1 } else { pIdx[ idx++ ] = Index( starty + rowstep, jk ); numIndexes++; // original order: 2 pIdx[ idx++ ] = Index( starty + rowstep, jk + step ); numIndexes++; // original order: 3 pIdx[ idx++ ] = Index( starty, j ); numIndexes++; // original order: 1 } } } // Middle tri if ( horizontal ) { pIdx[ idx++ ] = Index( j + halfsuperstep, starty + rowstep ); numIndexes++; // original order: 2 pIdx[ idx++ ] = Index( j + superstep, starty ); numIndexes++; // original order: 3 pIdx[ idx++ ] = Index( j, starty ); numIndexes++; // original order: 1 } else { pIdx[ idx++ ] = Index( starty + rowstep, j + halfsuperstep ); numIndexes++; // original order: 2 pIdx[ idx++ ] = Index( starty, j + superstep ); numIndexes++; // original order: 3 pIdx[ idx++ ] = Index( starty, j ); numIndexes++; // original order: 1 } for ( k = halfsuperstep; k != superstep; k += step ) { var jk = j + k; if ( j != endx - superstep || k != superstep - step || !omitLastTri ) { if ( horizontal ) { pIdx[ idx++ ] = Index( jk, starty + rowstep ); numIndexes++; // original order: 2 pIdx[ idx++ ] = Index( jk + step, starty + rowstep ); numIndexes++; // original order: 3 pIdx[ idx++ ] = Index( j + superstep, starty ); numIndexes++; // original order: 1 } else { pIdx[ idx++ ] = Index( starty + rowstep, jk ); numIndexes++; // original order: 2 pIdx[ idx++ ] = Index( starty + rowstep, jk + step ); numIndexes++; // original order: 3 pIdx[ idx++ ] = Index( starty, j + superstep ); numIndexes++; // original order: 1 } } } } ppIdx.Ptr += idx*sizeof ( ushort ); return numIndexes; }
/// <summary> /// </summary> /// <param name="offset"> </param> /// <param name="length"> </param> /// <param name="dest"> </param> public override void ReadData( int offset, int length, BufferBase dest ) { Contract.Requires( ( offset + length ) <= sizeInBytes ); Memory.Copy( this._dataPtr + offset, dest, length ); }
public override void ReadData( int offset, int length, BufferBase dest ) { if ( useShadowBuffer ) { var srcData = shadowBuffer.Lock( offset, length, BufferLocking.ReadOnly ); dest = srcData; shadowBuffer.Unlock(); } else { throw new AxiomException( "Read hardware buffer is not supported" ); } }
private void _flipEndian( BufferBase pData, int size, int count ) { #if AXIOM_BIG_ENDIAN for ( var index = 0; index < count; index++ ) { using ( var data = pData + ( index * size ) ) _flipEndian( data, size ); } #endif }
unsafe public int StitchEdge( Neighbor neighbor, int hiLOD, int loLOD, bool omitFirstTri, bool omitLastTri, BufferBase ppIdx )
private void _flipEndian( BufferBase pData, int size ) { #if AXIOM_BIG_ENDIAN byte swapByte; #if !AXIOM_SAFE_ONLY unsafe #endif { var ptr = pData.ToBytePointer(); for ( var byteIndex = 0; byteIndex < size / 2; byteIndex++ ) { swapByte = ptr[ byteIndex ]; ptr[ byteIndex ] = ptr[ size - byteIndex - 1 ]; ptr[ size - byteIndex - 1 ] = swapByte; } } #endif }
/// <summary> /// Caches a face group for imminent rendering. /// </summary> protected int CacheGeometry( BufferBase indexes, BspStaticFaceGroup faceGroup ) { // Skip sky always if ( faceGroup.isSky ) { return 0; } int idxStart = 0; int numIdx = 0; int vertexStart = 0; if ( faceGroup.type == FaceGroup.FaceList ) { idxStart = faceGroup.elementStart; numIdx = faceGroup.numElements; vertexStart = faceGroup.vertexStart; } else if ( faceGroup.type == FaceGroup.Patch ) { idxStart = faceGroup.patchSurf.IndexOffset; numIdx = faceGroup.patchSurf.CurrentIndexCount; vertexStart = faceGroup.patchSurf.VertexOffset; } else { // Unsupported face type return 0; } #if !AXIOM_SAFE_ONLY unsafe #endif { // Offset the indexes here // we have to do this now rather than up-front because the // indexes are sometimes reused to address different vertex chunks var idxSize = this.level.Indexes.IndexSize; var idxSrc = this.level.Indexes.Lock( idxStart*idxSize, numIdx*idxSize, BufferLocking.ReadOnly ); if ( this.level.Indexes.Type == IndexType.Size16 ) { var src = idxSrc.ToUShortPointer(); var pIndexes = indexes.ToUShortPointer(); for ( int i = 0; i < numIdx; i++ ) { pIndexes[ i ] = (ushort)( src[ i ] + vertexStart ); } } else { var src = idxSrc.ToUIntPointer(); var pIndexes = indexes.ToUIntPointer(); for ( int i = 0; i < numIdx; i++ ) { pIndexes[ i ] = (uint)( src[ i ] + vertexStart ); } } this.level.Indexes.Unlock(); } // return number of elements return numIdx; }
public override void ReadData( int offset, int length, BufferBase dest ) { // There is no functional interface in D3D, just do via manual // lock, copy & unlock // lock the buffer for reading var src = Lock( offset, length, BufferLocking.ReadOnly ); // copy that data in there Memory.Copy( src, dest, length ); // unlock the buffer Unlock(); }
/// <summary> /// </summary> /// <param name="offset"> </param> /// <param name="length"> </param> /// <param name="locking"> </param> /// <returns> </returns> protected override BufferBase 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" ); } BufferBase retPtr = null; if ( length < MapBufferThreshold ) { retPtr = ( (GLESHardwareBufferManager) HardwareBufferManager.Instance ).AllocateScratch( length ); if ( retPtr != null ) { this._lockedToScratch = true; this._scratchOffset = offset; this._scratchSize = length; this._scratchPtr = retPtr; this._scratchUploadOnUnlock = ( locking != BufferLocking.ReadOnly ); if ( locking != BufferLocking.Discard ) { this.ReadData( offset, length, retPtr ); } } } else { throw new AxiomException( "Invalid Buffer lockSize" ); } if ( retPtr == null ) { OpenGL.BindBuffer( All.ElementArrayBuffer, this._bufferId ); GLESConfig.GlCheckError( this ); // Use glMapBuffer if ( locking == BufferLocking.Discard ) { OpenGL.BufferData( All.ElementArrayBuffer, new IntPtr( sizeInBytes ), IntPtr.Zero, GLESHardwareBufferManager.GetGLUsage( usage ) ); GLESConfig.GlCheckError( this ); } if ( ( usage & BufferUsage.WriteOnly ) != 0 ) { access = All.WriteOnlyOes; } IntPtr pBuffer = OpenGLOES.MapBuffer( All.ElementArrayBuffer, access ); GLESConfig.GlCheckError( this ); if ( pBuffer == IntPtr.Zero ) { throw new AxiomException( "Index Buffer: Out of memory" ); } unsafe { // return offset retPtr = BufferBase.Wrap( pBuffer, sizeInBytes ); } this._lockedToScratch = false; } isLocked = true; return retPtr; }
/// <summary> /// </summary> /// <param name="idxType"> </param> /// <param name="numIndexes"> </param> /// <param name="usage"> </param> public GLDefaultHardwareIndexBuffer( IndexType idxType, int numIndexes, BufferUsage usage ) : base( null, idxType, numIndexes, usage, true, false ) // always software, never shadowed { this._data = new byte[ sizeInBytes ]; this._dataPtr = BufferBase.Wrap( this._data ); }
public D3D9HardwareIndexBuffer( HardwareBufferManagerBase manager, IndexType type, int numIndices, BufferUsage usage, bool useSystemMemory, bool useShadowBuffer ) : base( manager, type, numIndices, usage, useSystemMemory, useShadowBuffer ) { //Entering critical section this.LockDeviceAccess(); this._mapDeviceToBufferResources = new Dictionary<D3D9.Device, BufferResources>(); #if AXIOM_D3D_MANAGE_BUFFERS var eResourcePool = useSystemMemory ? D3D9.Pool.SystemMemory : // If not system mem, use managed pool UNLESS buffer is discardable // if discardable, keeping the software backing is expensive ( ( usage & BufferUsage.Discardable ) != 0 ) ? D3D9.Pool.Default : D3D9.Pool.Managed; #else var eResourcePool = useSystemMemory ? D3D9.Pool.SystemMemory : D3D9.Pool.Default; #endif // Set the desired memory pool. this._bufferDesc.Pool = eResourcePool; // Allocate the system memory buffer. this._systemMemoryBuffer = BufferBase.Wrap( new byte[sizeInBytes] ); // Case we have to create this buffer resource on loading. if ( D3D9RenderSystem.ResourceManager.CreationPolicy == D3D9ResourceManager.ResourceCreationPolicy.CreateOnAllDevices ) { foreach ( var d3d9Device in D3D9RenderSystem.ResourceCreationDevices ) { CreateBuffer( d3d9Device, this._bufferDesc.Pool ); } } D3D9RenderSystem.ResourceManager.NotifyResourceCreated( this ); //Leaving critical section this.UnlockDeviceAccess(); }
/// <summary> /// Updates buffer resources from system memory buffer. /// </summary> private bool _updateBufferResources( BufferBase systemMemoryBuffer, ref BufferResources bufferResources ) { Contract.RequiresNotNull( bufferResources, "Cannot update BufferResources in D3D9HardwareIndexBuffer!" ); Contract.RequiresNotNull( bufferResources.IndexBuffer, "Cannot update BufferResources in D3D9HardwareIndexBuffer!" ); Contract.Requires( bufferResources.IsOutOfDate ); DX.DataStream dstBytes; // Lock the buffer try { dstBytes = bufferResources.IndexBuffer.Lock( bufferResources.LockOffset, bufferResources.LockLength, D3D9Helper.ConvertEnum( bufferResources.LockOptions, usage ) ); } catch ( Exception ex ) { throw new AxiomException( "Cannot lock D3D9 index buffer!", ex ); } using ( var src = systemMemoryBuffer + bufferResources.LockOffset ) { using ( var dest = BufferBase.Wrap( dstBytes.DataPointer, (int)dstBytes.Length ) ) { Memory.Copy( src, dest, bufferResources.LockLength ); } } // Unlock the buffer. var hr = bufferResources.IndexBuffer.Unlock(); if ( hr.Failure ) { throw new AxiomException( "Cannot unlock D3D9 index buffer: {0}", hr.ToString() ); } bufferResources.IsOutOfDate = false; bufferResources.LockOffset = sizeInBytes; bufferResources.LockLength = 0; bufferResources.LockOptions = BufferLocking.Normal; return true; }