DirectX implementation of HardwarePixelBuffer
Наследование: Axiom.Graphics.HardwarePixelBuffer
Пример #1
0
        ///<summary>
        ///    @copydoc HardwarePixelBuffer.Blit
        ///</summary>
        public override void Blit(HardwarePixelBuffer _src, BasicBox srcBox, BasicBox dstBox)
        {
            D3DHardwarePixelBuffer src = (D3DHardwarePixelBuffer)_src;

            if (surface != null && src.surface != null)
            {
                // Surface-to-surface
                Rectangle dsrcRect  = ToD3DRectangle(srcBox);
                Rectangle ddestRect = ToD3DRectangle(dstBox);
                // D3DXLoadSurfaceFromSurface
                SurfaceLoader.FromSurface(surface, ddestRect, src.surface, dsrcRect, Filter.None, 0);
            }
            else if (volume != null && src.volume != null)
            {
                // Volume-to-volume
                Box dsrcBox  = ToD3DBox(srcBox);
                Box ddestBox = ToD3DBox(dstBox);
                // D3DXLoadVolumeFromVolume
                VolumeLoader.FromVolume(volume, ddestBox, src.volume, dsrcBox, Filter.None, 0);
            }
            else
            {
                // Software fallback
                base.Blit(_src, srcBox, dstBox);
            }
        }
        //public D3DRenderTexture(string name, int width, int height, PixelFormat format)
        //    :this(name, width, height, TextureType.TwoD, format) {}

        //public D3DRenderTexture(string name, int width, int height, TextureType type, PixelFormat format)
        //    :base(name, width, height, format) {

        //    privateTex = (D3DTexture)TextureManager.Instance.CreateManual(name + "_PRIVATE##", type, width, height, 0, format, TextureUsage.RenderTarget);

        //}

        public void Rebind(D3DHardwarePixelBuffer buffer)
        {
            pixelBuffer = buffer;
            width       = pixelBuffer.Width;
            height      = pixelBuffer.Height;
            colorDepth  = PixelUtil.GetNumElemBits(buffer.Format);
        }
 //public D3DRenderTexture(string name, int width, int height, PixelFormat format)
 //    :this(name, width, height, TextureType.TwoD, format) {}
 //public D3DRenderTexture(string name, int width, int height, TextureType type, PixelFormat format)
 //    :base(name, width, height, format) {
 //    privateTex = (D3DTexture)TextureManager.Instance.CreateManual(name + "_PRIVATE##", type, width, height, 0, format, TextureUsage.RenderTarget);
 //}
 public void Rebind(D3DHardwarePixelBuffer buffer)
 {
     pixelBuffer = buffer;
     width = pixelBuffer.Width;
     height = pixelBuffer.Height;
     colorDepth = PixelUtil.GetNumElemBits(buffer.Format);
 }
Пример #4
0
		private void CreateSurfaceList()
		{
			Debug.Assert( this._texture != null, "texture must be intialized." );
			D3D.Surface surface;

			// Make sure number of mips is right
			_mipmapCount = this._texture.LevelCount - 1;

			// Need to know static / dynamic
			BufferUsage bufusage;
			if ( ( ( Usage & TextureUsage.Dynamic ) != 0 ) && this._dynamicTextures )
			{
				bufusage = BufferUsage.Dynamic;
			}
			else
			{
				bufusage = BufferUsage.Static;
			}

			if ( ( Usage & TextureUsage.RenderTarget ) != 0 )
			{
				bufusage = (BufferUsage)( (int)bufusage | (int)TextureUsage.RenderTarget );
			}

			// If we already have the right number of surfaces, just update the old list
			bool updateOldList = ( this._surfaceList.Count == ( faceCount * ( MipmapCount + 1 ) ) );
			if ( !updateOldList )
			{
				// Create new list of surfaces
				this.ClearSurfaceList();
				for ( int face = 0; face < faceCount; ++face )
				{
					for ( int mip = 0; mip <= MipmapCount; ++mip )
					{
						D3DHardwarePixelBuffer buffer = new D3DHardwarePixelBuffer( bufusage );
						this._surfaceList.Add( buffer );
					}
				}
			}

			switch ( TextureType )
			{
				case TextureType.OneD:
				case TextureType.TwoD:
					Debug.Assert( this._normTexture != null, "texture must be intialized." );

					// For all mipmaps, store surfaces as HardwarePixelBuffer
					for ( int mip = 0; mip <= MipmapCount; ++mip )
					{
						surface = this._normTexture.GetSurfaceLevel( mip );
						this.GetSurfaceAtLevel( 0, mip ).Bind( this._device, surface, updateOldList );
						this._managedObjects.Add( surface );
					}

					break;

				case TextureType.CubeMap:
					Debug.Assert( _cubeTexture != null, "texture must be initialized." );

					// For all faces and mipmaps, store surfaces as HardwarePixelBuffer
					for ( int face = 0; face < 6; ++face )
					{
						for ( int mip = 0; mip <= MipmapCount; ++mip )
						{
							surface = this._cubeTexture.GetCubeMapSurface( (D3D.CubeMapFace)face, mip );
							this.GetSurfaceAtLevel( face, mip ).Bind( this._device, surface, updateOldList );
							this._managedObjects.Add( surface );
						}
					}

					break;

				case TextureType.ThreeD:
					Debug.Assert( _volumeTexture != null, "texture must be intialized." );

					// For all mipmaps, store surfaces as HardwarePixelBuffer
					for ( int mip = 0; mip <= MipmapCount; ++mip )
					{
						D3D.Volume volume = this._volumeTexture.GetVolumeLevel( mip );
						this.GetSurfaceAtLevel( 0, mip ).Bind( this._device, volume, updateOldList );
						this._managedObjects.Add( volume );
					}

					break;
			}

			// Set autogeneration of mipmaps for each face of the texture, if it is enabled
			if ( ( RequestedMipmapCount != 0 ) && ( ( Usage & TextureUsage.AutoMipMap ) != 0 ) )
			{
				for ( int face = 0; face < faceCount; ++face )
				{
					this.GetSurfaceAtLevel( face, 0 ).SetMipmapping( true, MipmapsHardwareGenerated, this._texture );
				}
			}
		}
        /// <summary>
        ///   This is a much faster variant of the save.  We can use it if our source format
        ///   and our destination format are typical.
        /// </summary>
        /// <param name="stream"></param>
        /// <param name="requestedFormat"></param>
        protected void SimpleSave(System.IO.Stream stream, PixelFormat requestedFormat)
        {
            D3DHardwarePixelBuffer hwBuffer = pixelBuffer as D3DHardwarePixelBuffer;

            Debug.Assert(hwBuffer.Format == PixelFormat.A8R8G8B8);
            Surface sourceSurface = hwBuffer.Surface;
            int     width         = hwBuffer.Width;
            int     height        = hwBuffer.Height;
            Device  device        = sourceSurface.Device;

            // create surface in system memory to copy render target into
            Surface destSurface = device.CreateOffscreenPlainSurface(
                width, height, D3D.Format.A8R8G8B8, Pool.SystemMemory);

            // copy render target to system memory surface
            device.GetRenderTargetData(sourceSurface, destSurface);

            int            pitch;
            GraphicsStream graphStream = destSurface.LockRectangle(LockFlags.ReadOnly | LockFlags.NoSystemLock, out pitch);

            int bytesPerPixel = 3;

            if (requestedFormat == PixelFormat.BYTE_RGBA)
            {
                bytesPerPixel = 4;
            }
            byte[] buffer = new byte[width * height * bytesPerPixel];

            int offset = 0, line = 0, count = 0;

            // gotta copy that data manually since it is in another format (sheesh!)
            unsafe
            {
                byte *data = (byte *)graphStream.InternalData;

                for (int y = height - 1; y >= 0; y--)
                {
                    line = y * pitch;

                    for (int x = 0; x < width; x++)
                    {
                        offset = x * 4;

                        int pixel = line + offset;

                        // Actual format is BRGA for some reason
                        buffer[count++] = data[pixel + 2];
                        buffer[count++] = data[pixel + 1];
                        buffer[count++] = data[pixel + 0];
                        if (bytesPerPixel == 4)
                        {
                            buffer[count++] = data[pixel + 3];
                        }
                    }
                }
            }

            destSurface.UnlockRectangle();

            // dispose of the temporary surface
            destSurface.Dispose();

            // write the data to the stream provided
            stream.Write(buffer, 0, buffer.Length);
        }
        protected void CreateSurfaceList()
        {
            Surface surface;
            Volume volume;
            D3DHardwarePixelBuffer buffer;
            Debug.Assert(texture != null);
            // Make sure number of mips is right
            numMipmaps = texture.LevelCount - 1;
            // Need to know static / dynamic
            BufferUsage bufusage;
            if (((usage & TextureUsage.Dynamic) != 0) && dynamicTextures)
                bufusage = BufferUsage.Dynamic;
            else
                bufusage = BufferUsage.Static;
            if ((usage & TextureUsage.RenderTarget) != 0)
                bufusage = (BufferUsage)((int)bufusage | (int)TextureUsage.RenderTarget);

            // If we already have the right number of surfaces, just update the old list
            bool updateOldList = (surfaceList.Count == (this.NumFaces * (numMipmaps + 1)));
            if (!updateOldList) {
                // Create new list of surfaces
                ClearSurfaceList();
                for (int face = 0; face < this.NumFaces; ++face) {
                    for (int mip = 0; mip <= numMipmaps; ++mip) {
                        buffer = new D3DHardwarePixelBuffer(bufusage);
                        surfaceList.Add(buffer);
                    }
                }
            }

            switch (textureType) {
                case TextureType.OneD:
                case TextureType.TwoD:
                    Debug.Assert(normTexture != null);
                    // For all mipmaps, store surfaces as HardwarePixelBuffer
                    for (int mip = 0; mip <= numMipmaps; ++mip) {
                        surface = normTexture.GetSurfaceLevel(mip);
                        // decrement reference count, the GetSurfaceLevel call increments this
                        // this is safe because the texture keeps a reference as well
                        // surface->Release();
                        GetSurfaceAtLevel(0, mip).Bind(device, surface, updateOldList);
                        managedObjects.Add(surface);
                    }
                    break;
                case TextureType.CubeMap:
                    Debug.Assert(cubeTexture != null);
                    // For all faces and mipmaps, store surfaces as HardwarePixelBufferSharedPtr
                    for (int face = 0; face < 6; ++face) {
                        for (int mip = 0; mip <= numMipmaps; ++mip) {
                            surface = cubeTexture.GetCubeMapSurface((CubeMapFace)face, mip);
                            // decrement reference count, the GetSurfaceLevel call increments this
                            // this is safe because the texture keeps a reference as well
                            // surface->Release();
                            GetSurfaceAtLevel(face, mip).Bind(device, surface, updateOldList);
                            managedObjects.Add(surface);
                        }
                    }
                    break;
                case TextureType.ThreeD:
                    Debug.Assert(volumeTexture != null);
                    // For all mipmaps, store surfaces as HardwarePixelBuffer
                    for (int mip = 0; mip <= numMipmaps; ++mip) {
                        volume = volumeTexture.GetVolumeLevel(mip);
                        // decrement reference count, the GetSurfaceLevel call increments this
                        // this is safe because the texture keeps a reference as well
                        // volume->Release();
                        GetSurfaceAtLevel(0, mip).Bind(device, volume, updateOldList);
                        managedObjects.Add(volume);
                    }
                    break;
            }
            // Set autogeneration of mipmaps for each face of the texture, if it is enabled
            if ((numRequestedMipmaps != 0) && ((usage & TextureUsage.AutoMipMap) != 0)) {
                for (int face = 0; face < this.NumFaces; ++face)
                    GetSurfaceAtLevel(face, 0).SetMipmapping(true, mipmapsHardwareGenerated, texture);
            }
        }