Structure used to define a box in a 3-D integer space. Note that the left, top, and front edges are included but the right, bottom and top ones are not.
コード例 #1
0
 public PixelBox(BasicBox extents, PixelFormat format)
 {
     CopyFromBasicBox(extents);
     this.format = format;
     this.offset = 0;
     SetConsecutive();
 }
コード例 #2
0
        /// <summary>
        ///   Return a subvolume of this PixelBox.
        /// </summary>
        /// <param name="def"> Defines the bounds of the subregion to return </param>
        /// <returns> A pixel box describing the region and the data in it </returns>
        /// <remarks>
        ///   This function does not copy any data, it just returns a PixelBox object with a data pointer pointing somewhere inside the data of object. Throws an Exception if def is not fully contained.
        /// </remarks>
        public PixelBox GetSubVolume(BasicBox def)
        {
            if (Compressed(this.format))
            {
                if (def.Left == left && def.Top == top && def.Front == front && def.Right == right && def.Bottom == bottom &&
                    def.Back == back)
                {
                    // Entire buffer is being queried
                    return(this);
                }
                throw new Exception("Cannot return subvolume of compressed PixelBuffer, in PixelBox.GetSubVolume");
            }
            if (!Contains(def))
            {
                throw new Exception("Bounds out of range, in PixelBox.GetSubVolume");
            }

            var elemSize = PixelUtil.GetNumElemBytes(this.format);
            // Calculate new data origin
            var rval = new PixelBox(def, this.format, this.data);

            rval.offset = (((def.Left - left) * elemSize) + ((def.Top - top) * this.rowPitch * elemSize) +
                           ((def.Front - front) * this.slicePitch * elemSize));
            rval.rowPitch   = this.rowPitch;
            rval.slicePitch = this.slicePitch;
            rval.format     = this.format;
            return(rval);
        }
コード例 #3
0
 ///<summary>
 ///  Constructor providing extents in the form of a Box object. This constructor assumes the pixel data is laid out consecutively in memory. (this means row after row, slice after slice, with no space in between)
 ///</summary>
 ///<param name="extents"> Extents of the region defined by data </param>
 ///<param name="format"> Format of this buffer </param>
 ///<param name="data"> Pointer to the actual data </param>
 internal PixelBox(BasicBox extents, PixelFormat format, BufferBase data)
 {
     CopyFromBasicBox(extents);
     this.format = format;
     this.data   = data;
     this.offset = 0;
     SetConsecutive();
 }
コード例 #4
0
 ///<summary>
 ///    Constructor providing extents in the form of a Box object. This constructor
 ///    assumes the pixel data is laid out consecutively in memory. (this
 ///    means row after row, slice after slice, with no space in between)
 ///</summary>
 ///<param name="extents">Extents of the region defined by data</param>
 ///<param name="ormat">Format of this buffer</param>
 ///<param name="data">Pointer to the actual data</param>
 protected PixelBox(BasicBox extents, PixelFormat format, IntPtr data)
 {
     CopyFromBasicBox(extents);
     this.format = format;
     this.data   = data;
     this.offset = 0;
     SetConsecutive();
 }
コード例 #5
0
 public void CopyFromBasicBox(BasicBox src)
 {
     this.left   = src.left;
     this.top    = src.top;
     this.front  = src.front;
     this.right  = src.right;
     this.bottom = src.bottom;
     this.back   = src.back;
 }
コード例 #6
0
 public void CopyFromBasicBox(BasicBox src)
 {
     left   = src.left;
     top    = src.top;
     front  = src.front;
     right  = src.right;
     bottom = src.bottom;
     back   = src.back;
 }
コード例 #7
0
		public override void BlitToMemory( BasicBox srcBox, PixelBox dst )
		{
			//Entering critical section
			LockDeviceAccess();

			var pair = this.mapDeviceToBufferResources.First();
			BlitToMemory( srcBox, dst, pair.Value, pair.Key );

			//Leaving critical section
			UnlockDeviceAccess();
		}
コード例 #8
0
        ///<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();
        }
コード例 #9
0
		public override void Blit( HardwarePixelBuffer rsrc, BasicBox srcBox, BasicBox dstBox )
		{
			//Entering critical section
			LockDeviceAccess();

			var _src = (D3D9HardwarePixelBuffer)rsrc;
			foreach ( var it in this.mapDeviceToBufferResources )
			{
				var srcBufferResources = ( (D3D9HardwarePixelBuffer)rsrc ).GetBufferResources( it.Key );
				var dstBufferResources = it.Value;

				if ( srcBufferResources == null )
				{
					throw new AxiomException( "There are no matching resources attached to the source pixel buffer !!" );
				}

				Blit( it.Key, rsrc, srcBox, dstBox, srcBufferResources, dstBufferResources );
			}

			//Leaving critical section
			UnlockDeviceAccess();
		}
コード例 #10
0
		public override void BlitFromMemory( PixelBox src, BasicBox dstBox )
		{
			//Entering critical section
			LockDeviceAccess();

			foreach ( var it in this.mapDeviceToBufferResources )
			{
				BlitFromMemory( src, dstBox, it.Value );
			}

			//Leaving critical section
			UnlockDeviceAccess();
		}
コード例 #11
0
		protected static System.Drawing.Rectangle ToD3DRectangle( BasicBox lockBox )
		{
			Debug.Assert( lockBox.Depth == 1 );
			var r = new System.Drawing.Rectangle();
			r.X = lockBox.Left;
			r.Width = lockBox.Width;
			r.Y = lockBox.Top;
			r.Height = lockBox.Height;
			return r;
		}
コード例 #12
0
		protected override PixelBox LockImpl( BasicBox lockBox, BufferLocking options )
		{
			//Entering critical section
			LockDeviceAccess();

			// Check for misuse
			if ( ( (int)usage & (int)TextureUsage.RenderTarget ) != 0 )
			{
				throw new AxiomException(
					"DirectX does not allow locking of or directly writing to RenderTargets. Use BlitFromMemory if you need the contents." );
			}

			// Set locking flags according to options
			var flags = D3D9Helper.ConvertEnum( options, usage );

			if ( this.mapDeviceToBufferResources.Count == 0 )
			{
				throw new AxiomException( "There are no resources attached to this pixel buffer !!" );
			}

			lockedBox = lockBox;
			this.lockFlags = flags;

			var bufferResources = this.mapDeviceToBufferResources.First().Value;

			// Lock the source buffer.
			var lockedBuf = LockBuffer( bufferResources, lockBox, flags );

			//Leaving critical section
			UnlockDeviceAccess();

			return lockedBuf;
		}
コード例 #13
0
		/// <summary>
		/// 
		/// </summary>
		/// <param name="data"></param>
		/// <param name="dest"></param>
		protected virtual void Upload( PixelBox data, BasicBox dest )
		{
			throw new AxiomException( "Upload not possible for this pixelbuffer type" );
		}
コード例 #14
0
		/// <summary>
		/// 
		/// </summary>
		/// <param name="srcBox"></param>
		/// <param name="dst"></param>
		public override void BlitToMemory( BasicBox srcBox, PixelBox dst )
		{
			if ( !_buffer.Contains( srcBox ) )
			{
				throw new ArgumentOutOfRangeException( "source boux out of range" );
			}

			if ( srcBox.Left == 0 && srcBox.Right == Width &&
				srcBox.Top == 0 && srcBox.Bottom == Height &&
				srcBox.Front == 0 && srcBox.Back == Depth &&
				dst.Width == Width &&
				dst.Height == Height &&
				dst.Depth == Depth &&
				GLESPixelUtil.GetGLOriginFormat( dst.Format ) != 0 )
			{
				// The direct case: the user wants the entire texture in a format supported by GL
				// so we don't need an intermediate buffer
				Download( dst );
			}
			else
			{
				// Use buffer for intermediate copy
				AllocateBuffer();
				//download entire buffer
				Download( _buffer );
				if ( srcBox.Width != dst.Width ||
					srcBox.Height != dst.Height ||
					srcBox.Depth != dst.Depth )
				{
					// we need scaling
					Image.Scale( _buffer.GetSubVolume( srcBox ), dst, ImageFilter.Bilinear );
				}
				else
				{
					// Just copy the bit that we need
					PixelConverter.BulkPixelConversion( _buffer.GetSubVolume( srcBox ), dst );
				}
				FreeBuffer();
			}
		}
コード例 #15
0
 ///<summary>
 ///    Constructor providing extents in the form of a Box object. This constructor
 ///    assumes the pixel data is laid out consecutively in memory. (this
 ///    means row after row, slice after slice, with no space in between)
 ///</summary>
 ///<param name="extents">Extents of the region defined by data</param>
 ///<param name="ormat">Format of this buffer</param>
 ///<param name="data">Pointer to the actual data</param>
 protected PixelBox(BasicBox extents, PixelFormat format, IntPtr data)
 {
     CopyFromBasicBox(extents);
     this.format = format;
     this.data = data;
     this.offset = 0;
     SetConsecutive();
 }
コード例 #16
0
 public void CopyFromBasicBox(BasicBox src)
 {
     left = src.left;
     top = src.top;
     front = src.front;
     right = src.right;
     bottom = src.bottom;
     back = src.back;
 }
コード例 #17
0
		public override void BlitFromMemory( PixelBox src, BasicBox dstBox )
		{
			// Fall back to normal GLHardwarePixelBuffer::blitFromMemory in case 
			// - FBO is not supported
			// - Either source or target is luminance due doesn't looks like supported by hardware
			// - the source dimensions match the destination ones, in which case no scaling is needed
			//Ogre TODO: Check that extension is NOT available
			if ( PixelUtil.IsLuminance( src.Format ) || PixelUtil.IsLuminance( this.format ) || ( src.Width == dstBox.Width && src.Height == dstBox.Height && src.Depth == dstBox.Depth ) )
			{
				base.BlitFromMemory( src, dstBox );
				return;
			}

			if ( !Buffer.Contains( dstBox ) )
			{
				throw new ArgumentOutOfRangeException( "dstBox", "Destination box out of range" );
			}

			//For scoped deletion of conversion buffer

			PixelBox srcPB;
			BufferBase buf;
			//first, convert the srcbox to a OpenGL compatible pixel format
			if ( GLES2PixelUtil.GetGLOriginFormat( src.Format ) == 0 )
			{
				//Conver to buffer intenral format
				buf = BufferBase.Wrap( new byte[ PixelUtil.GetMemorySize( src.Width, src.Height, src.Depth, this.format ) ] );

				srcPB = new PixelBox( src.Width, src.Height, src.Depth, this.format, buf );
				PixelConverter.BulkPixelConversion( src, srcPB );
			}
			else
			{
				//No conversion needed
				srcPB = src;
			}

			//Create temporary texture to store source data
			int id = 0;
			All target = All.Texture2D;
			int width = GLES2PixelUtil.OptionalPO2( src.Width );
			int height = GLES2PixelUtil.OptionalPO2( src.Height );
			All format = GLES2PixelUtil.GetClosestGLInternalFormat( src.Format );
			All datatype = GLES2PixelUtil.GetGLOriginDataType( src.Format );

			//Generate texture name
			GL.GenTextures( 1, ref id );
			GLES2Config.GlCheckError( this );

			//Set texture type
			GL.BindTexture( target, id );
			GLES2Config.GlCheckError( this );

			//Allocate texture memory
			GL.TexImage2D( target, 0, (int) format, width, height, 0, format, datatype, IntPtr.Zero );
			GLES2Config.GlCheckError( this );

			var tex = new GLES2TextureBuffer( string.Empty, target, id, width, height, format, (All) src.Format, 0, 0, BufferUsage.StaticWriteOnly, false, false, 0 );

			//Upload data to 0,0,0 in temprary texture
			var tempTarget = new BasicBox( 0, 0, 0, srcPB.Width, srcPB.Height, srcPB.Depth );
			tex.Upload( srcPB, tempTarget );

			//Blit
			this.BlitFromTexture( tex, tempTarget, dstBox );
			GLES2Config.GlCheckError( this );
		}
コード例 #18
0
		///<summary>
		///  // Very fast texture-to-texture blitter and hardware bi/trilinear scaling implementation using FBO Destination texture must be 1D, 2D, 3D, or Cube Source texture must be 1D, 2D or 3D Supports compressed formats as both source and destination format, it will use the hardware DXT compressor if available. @author W.J. van der Laan
		///</summary>
		///<param name="src"> </param>
		///<param name="srcBox"> </param>
		///<param name="dstBox"> </param>
		private void BlitFromTexture( GLES2TextureBuffer src, BasicBox srcBox, BasicBox dstBox )
		{
			/*Port notes
			 * Ogre immediately returns void, yet much code is provided below
			 * The remaining code will ported if/when Ogre makes use of it
			 */
			return; //Ogre todo add a shader attach...
		}
コード例 #19
0
 ///<summary>
 ///  Return true if the other box is a part of this one
 ///</summary>
 public bool Contains(BasicBox def)
 {
     return(def.Left >= this.left && def.top >= this.top && def.front >= this.front && def.right <= this.right &&
            def.bottom <= this.bottom &&
            def.back <= this.back);
 }
コード例 #20
0
 public PixelBox(BasicBox extents, PixelFormat format)
 {
     CopyFromBasicBox(extents);
     this.format = format;
     this.offset = 0;
     SetConsecutive();
 }
コード例 #21
0
 ///<summary>
 ///    Copies a region of this pixelbuffer to normal memory.
 ///</summary>
 ///<param name="srcBox">BasicBox describing the source region of this buffer</param>
 ///<param name="dst">PixelBox describing the destination pixels and format in memory</param>
 ///<remarks>
 ///    The source and destination regions don't have to match, in which
 ///    case scaling is done.
 ///    Only call this function when the buffer is unlocked. 
 ///</remarks>
 public override void BlitToMemory( BasicBox srcBox, PixelBox dst )
 {
 }
コード例 #22
0
        /** Return a subvolume of this PixelBox.
          		@param def	Defines the bounds of the subregion to return
          		@returns	A pixel box describing the region and the data in it
          		@remarks	This function does not copy any data, it just returns
          			a PixelBox object with a data pointer pointing somewhere inside
          			the data of object.
          		@throws	Exception(ERR_INVALIDPARAMS) if def is not fully contained
          	*/
        public PixelBox GetSubVolume(BasicBox def)
        {
            if(Compressed(format)) {
                if(def.Left == left && def.Top == top && def.Front == front &&
                   def.Right == right && def.Bottom == bottom && def.Back == back)
                    // Entire buffer is being queried
                    return this;
                throw new Exception("Cannot return subvolume of compressed PixelBuffer, in PixelBox.GetSubVolume");
            }
            if(!Contains(def))
                throw new Exception("Bounds out of range, in PixelBox.GetSubVolume");

            int elemSize = PixelUtil.GetNumElemBytes(format);
            // Calculate new data origin
            PixelBox rval = new PixelBox(def, format, data);
            rval.offset =  (((def.Left - left)*elemSize) +
                            ((def.Top - top)*rowPitch*elemSize) +
                            ((def.Front - front)*slicePitch*elemSize));
            rval.rowPitch = rowPitch;
            rval.slicePitch = slicePitch;
            rval.format = format;
            return rval;
        }
コード例 #23
0
        ///<summary>
        ///    Internal implementation of <see cref="HardwareBuffer.Lock"/>.
        ///</summary>
        protected override PixelBox LockImpl( BasicBox lockBox, BufferLocking options )
        {
            _lockedBox = lockBox;
            // Set extents and format
            var rval = new PixelBox( lockBox, Format );
            var sizeInBytes = PixelUtil.GetMemorySize( lockBox.Width, lockBox.Height, lockBox.Depth,
                                                       XnaHelper.Convert( surface.Format ) );
            if ( _bufferBytes == null || _bufferBytes.Length != sizeInBytes )
            {
                _bufferBytes = new byte[sizeInBytes];
#if !SILVERLIGHT
                if ( surface != null )
                    surface.GetData( mipLevel, XnaHelper.ToRectangle( lockBox ), _bufferBytes, 0, _bufferBytes.Length );
                else if ( cube != null )
                    cube.GetData( face, mipLevel, XnaHelper.ToRectangle( lockBox ), _bufferBytes, 0, _bufferBytes.Length );
                else
                    volume.GetData( mipLevel, lockBox.Left, lockBox.Top, lockBox.Right, lockBox.Bottom,
                                    lockBox.Front, lockBox.Back, _bufferBytes, 0, _bufferBytes.Length );
#endif
            }

            rval.Data = BufferBase.Wrap( _bufferBytes );

            return rval;
        }
コード例 #24
0
		/// <summary>
		/// 
		/// </summary>
		/// <param name="lockBox"></param>
		/// <param name="options"></param>
		/// <returns></returns>
		protected override PixelBox LockImpl( BasicBox lockBox, BufferLocking options )
		{
			AllocateBuffer();
			if ( options != BufferLocking.Discard &&
				( Usage & BufferUsage.WriteOnly ) == 0 )
			{
				// Download the old contents of the texture
				Download( _buffer );
			}
			_currentLocking = options;
			return _buffer.GetSubVolume( lockBox );
		}
コード例 #25
0
		protected abstract PixelBox LockImpl( BasicBox lockBox, BufferLocking options );
コード例 #26
0
		public void Bind( D3D9.Device dev, D3D9.Volume volume, D3D9.BaseTexture mipTex )
		{
			//Entering critical section
			LockDeviceAccess();

			var bufferResources = GetBufferResources( dev );
			var isNewBuffer = false;

			if ( bufferResources == null )
			{
				bufferResources = new BufferResources();
				this.mapDeviceToBufferResources.Add( dev, bufferResources );
				isNewBuffer = true;
			}

			bufferResources.MipTex = mipTex;
			bufferResources.Volume = volume;

			var desc = volume.Description;
			width = desc.Width;
			height = desc.Height;
			depth = desc.Depth;
			format = D3D9Helper.ConvertEnum( desc.Format );
			// Default
			rowPitch = Width;
			slicePitch = Height*Width;
			sizeInBytes = PixelUtil.GetMemorySize( Width, Height, Depth, Format );

			if ( isNewBuffer && this.ownerTexture.IsManuallyLoaded )
			{
				foreach ( var it in this.mapDeviceToBufferResources )
				{
					if ( it.Value != bufferResources && it.Value.Volume != null && it.Key.TestCooperativeLevel().Success &&
					     dev.TestCooperativeLevel().Success )
					{
						var fullBufferBox = new BasicBox( 0, 0, 0, Width, Height, Depth );
						var dstBox = new PixelBox( fullBufferBox, Format );

						var data = new byte[sizeInBytes];
						using ( var d = BufferBase.Wrap( data ) )
						{
							dstBox.Data = d;
							BlitToMemory( fullBufferBox, dstBox, it.Value, it.Key );
							BlitFromMemory( dstBox, fullBufferBox, bufferResources );
							Array.Clear( data, 0, sizeInBytes );
						}
						break;
					}
				}
			}

			//Leaving critical section
			UnlockDeviceAccess();
		}
コード例 #27
0
		public abstract void BlitFromMemory( PixelBox src, BasicBox dstBox );
コード例 #28
0
		protected static D3D9.Box ToD3DBox( BasicBox lockBox )
		{
			var pbox = new D3D9.Box();
			pbox.Left = lockBox.Left;
			pbox.Right = lockBox.Right;
			pbox.Top = lockBox.Top;
			pbox.Bottom = lockBox.Bottom;
			pbox.Front = lockBox.Front;
			pbox.Back = lockBox.Back;
			return pbox;
		}
コード例 #29
0
		public abstract void BlitToMemory( BasicBox srcBox, PixelBox dst );
コード例 #30
0
		protected PixelBox LockBuffer( BufferResources bufferResources, BasicBox lockBox, D3D9.LockFlags flags )
		{
			// Set extents and format
			// Note that we do not carry over the left/top/front here, since the returned
			// PixelBox will be re-based from the locking point onwards
			var rval = new PixelBox( lockBox.Width, lockBox.Height, lockBox.Depth, Format );

			if ( bufferResources.Surface != null )
			{
				//Surface
				DX.DataRectangle lrect; // Filled in by D3D

				if ( lockBox.Left == 0 && lockBox.Top == 0 && lockBox.Right == Width && lockBox.Bottom == Height )
				{
					// Lock whole surface
					lrect = bufferResources.Surface.LockRectangle( flags );
				}
				else
				{
					var prect = ToD3DRectangle( lockBox );
					lrect = bufferResources.Surface.LockRectangle( prect, flags );
				}

				FromD3DLock( rval, lrect );
			}
			else if ( bufferResources.Volume != null )
			{
				// Volume
				var pbox = ToD3DBox( lockBox ); // specify range to lock
				var lbox = bufferResources.Volume.LockBox( pbox, flags );
				FromD3DLock( rval, lbox );
			}

			return rval;
		}
コード例 #31
0
		protected override BufferBase LockImpl( int offset, int length, BufferLocking options )
		{
			Debug.Assert( !IsLocked, "Cannot lock this buffer, it is already locked!" );
			Debug.Assert( offset == 0 && length == sizeInBytes, "Cannot lock memory region, must lock box or entire buffer" );

			var myBox = new BasicBox( 0, 0, 0, Width, Height, Depth );
			var rv = Lock( myBox, options );
			return rv.Data;
		}
コード例 #32
0
		protected void Blit( D3D9.Device d3d9Device, HardwarePixelBuffer rsrc, BasicBox srcBox, BasicBox dstBox,
		                     BufferResources srcBufferResources, BufferResources dstBufferResources )
		{
			if ( dstBufferResources.Surface != null && srcBufferResources.Surface != null )
			{
				// Surface-to-surface
				var dsrcRect = ToD3DRectangle( srcBox );
				var ddestRect = ToD3DRectangle( dstBox );

				var srcDesc = srcBufferResources.Surface.Description;

				// If we're blitting from a RTT, try GetRenderTargetData
				// if we're going to try to use GetRenderTargetData, need to use system mem pool

				// romeoxbm: not used even in Ogre
				//var tryGetRenderTargetData = false;

				if ( ( srcDesc.Usage & D3D9.Usage.RenderTarget ) != 0 && srcDesc.MultiSampleType == D3D9.MultisampleType.None )
				{
					// Temp texture
					var tmptex = new D3D9.Texture( d3d9Device, srcDesc.Width, srcDesc.Height, 1,
					                               // 1 mip level ie topmost, generate no mipmaps
					                               0, srcDesc.Format, D3D9.Pool.SystemMemory );

					var tmpsurface = tmptex.GetSurfaceLevel( 0 );

					if ( d3d9Device.GetRenderTargetData( srcBufferResources.Surface, tmpsurface ).Success )
					{
						// Hey, it worked
						// Copy from this surface instead
						var res = D3D9.Surface.FromSurface( dstBufferResources.Surface, tmpsurface, D3D9.Filter.Default, 0, dsrcRect,
						                                    ddestRect );
						if ( res.Failure )
						{
							tmpsurface.SafeDispose();
							tmptex.SafeDispose();
							throw new AxiomException( "D3D9.Surface.FromSurface failed in D3D9HardwarePixelBuffer.Blit" );
						}
						tmpsurface.SafeDispose();
						tmptex.SafeDispose();
						return;
					}
				}

				// Otherwise, try the normal method
				var res2 = D3D9.Surface.FromSurface( dstBufferResources.Surface, srcBufferResources.Surface, D3D9.Filter.Default, 0,
				                                     dsrcRect, ddestRect );
				if ( res2.Failure )
				{
					throw new AxiomException( "D3D9.Surface.FromSurface failed in D3D9HardwarePixelBuffer.Blit" );
				}
			}
			else if ( dstBufferResources.Volume != null && srcBufferResources.Volume != null )
			{
				// Volume-to-volume
				var dsrcBox = ToD3DBox( srcBox );
				var ddestBox = ToD3DBox( dstBox );

				var res = D3D9.Volume.FromVolume( dstBufferResources.Volume, srcBufferResources.Volume, D3D9.Filter.Default, 0,
				                                  dsrcBox, ddestBox );
				if ( res.Failure )
				{
					throw new AxiomException( "D3D9.Volume.FromVolume failed in D3D9HardwarePixelBuffer.Blit" );
				}
			}
			else
			{
				// Software fallback
				base.Blit( rsrc, srcBox, dstBox );
			}
		}
コード例 #33
0
		public virtual PixelBox Lock( BasicBox lockBox, BufferLocking options )
		{
			if ( useShadowBuffer )
			{
				if ( options != BufferLocking.ReadOnly )
				{
					// we have to assume a read / write lock so we use the shadow buffer
					// and tag for sync on unlock()
					shadowUpdated = true;
				}
				this.currentLock = ( (HardwarePixelBuffer)shadowBuffer ).Lock( lockBox, options );
			}
			else
			{
				// Lock the real buffer if there is no shadow buffer 
				this.currentLock = LockImpl( lockBox, options );
				isLocked = true;
			}

			return this.currentLock;
		}
コード例 #34
0
		protected void BlitFromMemory( PixelBox src, BasicBox dstBox, BufferResources dstBufferResources )
		{
			// for scoped deletion of conversion buffer
			var converted = src;
			var bufSize = 0;

			// convert to pixelbuffer's native format if necessary
			if ( D3D9Helper.ConvertEnum( src.Format ) == D3D9.Format.Unknown )
			{
				bufSize = PixelUtil.GetMemorySize( src.Width, src.Height, src.Depth, Format );
				var newBuffer = new byte[bufSize];
				using ( var data = BufferBase.Wrap( newBuffer ) )
				{
					converted = new PixelBox( src.Width, src.Height, src.Depth, Format, data );
				}
				PixelConverter.BulkPixelConversion( src, converted );
			}

			int rowWidth = 0;
			if ( PixelUtil.IsCompressed( converted.Format ) )
			{
				rowWidth = converted.RowPitch/4;
				// D3D wants the width of one row of cells in bytes
				if ( converted.Format == PixelFormat.DXT1 )
				{
					// 64 bits (8 bytes) per 4x4 block
					rowWidth *= 8;
				}
				else
				{
					// 128 bits (16 bytes) per 4x4 block
					rowWidth *= 16;
				}
			}
			else
			{
				rowWidth = converted.RowPitch*PixelUtil.GetNumElemBytes( converted.Format );
			}

			if ( dstBufferResources.Surface != null )
			{
				var srcRect = ToD3DRectangle( converted );
				var destRect = ToD3DRectangle( dstBox );

				bufSize = PixelUtil.GetMemorySize( converted.Width, converted.Height, converted.Depth, converted.Format );
				var data = new byte[bufSize];
				using ( var dest = BufferBase.Wrap( data ) )
				{
					Memory.Copy( converted.Data, dest, bufSize );
				}

				try
				{
					D3D9.Surface.FromMemory( dstBufferResources.Surface, data, D3D9.Filter.Default, 0,
					                         D3D9Helper.ConvertEnum( converted.Format ), rowWidth, srcRect, destRect );
				}
				catch ( Exception e )
				{
					throw new AxiomException( "D3D9.Surface.FromMemory failed in D3D9HardwarePixelBuffer.BlitFromMemory", e );
				}
			}
			else if ( dstBufferResources.Volume != null )
			{
				var srcBox = ToD3DBox( converted );
				var destBox = ToD3DBox( dstBox );
				var sliceWidth = 0;
				if ( PixelUtil.IsCompressed( converted.Format ) )
				{
					sliceWidth = converted.SlicePitch/16;
					// D3D wants the width of one slice of cells in bytes
					if ( converted.Format == PixelFormat.DXT1 )
					{
						// 64 bits (8 bytes) per 4x4 block
						sliceWidth *= 8;
					}
					else
					{
						// 128 bits (16 bytes) per 4x4 block
						sliceWidth *= 16;
					}
				}
				else
				{
					sliceWidth = converted.SlicePitch*PixelUtil.GetNumElemBytes( converted.Format );
				}

				bufSize = PixelUtil.GetMemorySize( converted.Width, converted.Height, converted.Depth, converted.Format );
                var data = new byte[ bufSize ];
				using ( var dest = BufferBase.Wrap( data ) )
				{
					Memory.Copy( converted.Data, dest, bufSize );
				}

				try
				{
                    using ( var srcData = BufferBase.Wrap( data ) )
                    {
                        var srcMemoryPtr = new IntPtr( srcData.Ptr );
                        dstBufferResources.Volume.LoadFromMemory( null, destBox, srcMemoryPtr, D3D9Helper.ConvertEnum( converted.Format ),
                            rowWidth, slicePitch, null, srcBox, D3D9.Filter.Default, 0 );
                    }
				}
				catch ( Exception e )
				{
					throw new AxiomException( "D3D9.Volume.FromFileInMemory failed in D3D9HardwarePixelBuffer.BlitFromMemory", e );
				}
			}

			if ( this.doMipmapGen )
			{
				GenMipmaps( dstBufferResources.MipTex );
			}
		}
コード例 #35
0
		public virtual void Blit( HardwarePixelBuffer src, BasicBox srcBox, BasicBox dstBox )
		{
			if ( IsLocked || src.IsLocked )
			{
				throw new AxiomException( "Source and destination buffer may not be locked!" );
			}

			if ( src == this )
			{
				throw new AxiomException( "Source must not be the same object." );
			}

			var srclock = src.Lock( srcBox, BufferLocking.ReadOnly );

			var method = BufferLocking.Normal;
			if ( dstBox.Left == 0 && dstBox.Top == 0 && dstBox.Front == 0 && dstBox.Right == this.width &&
			     dstBox.Bottom == this.height &&
			     dstBox.Back == this.depth )
			{
				// Entire buffer -- we can discard the previous contents
				method = BufferLocking.Discard;
			}

			var dstlock = Lock( dstBox, method );
			if ( dstlock.Width != srclock.Width || dstlock.Height != srclock.Height || dstlock.Depth != srclock.Depth )
			{
				// Scaling desired
				Image.Scale( srclock, dstlock );
			}
			else
			{
				// No scaling needed
				PixelConverter.BulkPixelConversion( srclock, dstlock );
			}

			Unlock();
			src.Unlock();
		}
コード例 #36
0
		protected void BlitToMemory( BasicBox srcBox, PixelBox dst, BufferResources srcBufferResources, D3D9.Device d3d9Device )
		{
			// Decide on pixel format of temp surface
			PixelFormat tmpFormat = Format;
			if ( D3D9Helper.ConvertEnum( dst.Format ) != D3D9.Format.Unknown )
			{
				tmpFormat = dst.Format;
			}

			if ( srcBufferResources.Surface != null )
			{
				Debug.Assert( srcBox.Depth == 1 && dst.Depth == 1 );
				var srcDesc = srcBufferResources.Surface.Description;
				var temppool = D3D9.Pool.Scratch;

				// if we're going to try to use GetRenderTargetData, need to use system mem pool
				var tryGetRenderTargetData = false;
				if ( ( ( srcDesc.Usage & D3D9.Usage.RenderTarget ) != 0 ) && ( srcBox.Width == dst.Width ) &&
				     ( srcBox.Height == dst.Height ) && ( srcBox.Width == Width ) && ( srcBox.Height == Height ) &&
				     ( Format == tmpFormat ) )
				{
					tryGetRenderTargetData = true;
					temppool = D3D9.Pool.SystemMemory;
				}

				// Create temp texture
				var tmp = new D3D9.Texture( d3d9Device, dst.Width, dst.Height, 1, // 1 mip level ie topmost, generate no mipmaps
				                            0, D3D9Helper.ConvertEnum( tmpFormat ), temppool );

				var surface = tmp.GetSurfaceLevel( 0 );

				// Copy texture to this temp surface
				var srcRect = ToD3DRectangle( srcBox );
				var destRect = ToD3DRectangle( dst );

				// Get the real temp surface format
				var dstDesc = surface.Description;
				tmpFormat = D3D9Helper.ConvertEnum( dstDesc.Format );

				// Use fast GetRenderTargetData if we are in its usage conditions
				var fastLoadSuccess = false;
				if ( tryGetRenderTargetData )
				{
					var result = d3d9Device.GetRenderTargetData( srcBufferResources.Surface, surface );
					fastLoadSuccess = result.Success;
				}
				if ( !fastLoadSuccess )
				{
					var res = D3D9.Surface.FromSurface( surface, srcBufferResources.Surface, D3D9.Filter.Default, 0, srcRect, destRect );
					if ( res.Failure )
					{
						surface.SafeDispose();
						tmp.SafeDispose();
						throw new AxiomException( "D3D9.Surface.FromSurface failed in D3D9HardwarePixelBuffer.BlitToMemory" );
					}
				}

				// Lock temp surface and copy it to memory
				var lrect = surface.LockRectangle( D3D9.LockFlags.ReadOnly );

				// Copy it
				var locked = new PixelBox( dst.Width, dst.Height, dst.Depth, tmpFormat );
				FromD3DLock( locked, lrect );
				PixelConverter.BulkPixelConversion( locked, dst );
				surface.UnlockRectangle();
				// Release temporary surface and texture
				surface.SafeDispose();
				tmp.SafeDispose();
			}
			else if ( srcBufferResources.Volume != null )
			{
				// Create temp texture
				var tmp = new D3D9.VolumeTexture( d3d9Device, dst.Width, dst.Height, dst.Depth, 0, 0,
				                                  D3D9Helper.ConvertEnum( tmpFormat ), D3D9.Pool.Scratch );

				var surface = tmp.GetVolumeLevel( 0 );

				// Volume
				var ddestBox = ToD3DBoxExtent( dst );
				var dsrcBox = ToD3DBox( srcBox );

				var res = D3D9.Volume.FromVolume( surface, srcBufferResources.Volume, D3D9.Filter.Default, 0, dsrcBox, ddestBox );
				if ( res.Failure )
				{
					surface.SafeDispose();
					tmp.SafeDispose();
					throw new AxiomException( "D3D9.Surface.FromVolume failed in D3D9HardwarePixelBuffer.BlitToMemory" );
				}

				// Lock temp surface and copy it to memory
				var lbox = surface.LockBox( D3D9.LockFlags.ReadOnly ); // Filled in by D3D

				// Copy it
				var locked = new PixelBox( dst.Width, dst.Height, dst.Depth, tmpFormat );
				FromD3DLock( locked, lbox );
				PixelConverter.BulkPixelConversion( locked, dst );
				surface.UnlockBox();
				// Release temporary surface and texture
				surface.SafeDispose();
				tmp.SafeDispose();
			}
		}
コード例 #37
0
 ///<summary>
 ///    Return true if the other box is a part of this one
 ///</summary>
 public bool Contains(BasicBox def)
 {
     return (def.Left >= left && def.top >= top && def.front >= front &&
             def.right <= right && def.bottom <= bottom && def.back <= back);
 }