///<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); }
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); } }