public override Microsoft.DirectX.Direct3D.Surface Lock(int surface)
 {
     if (!textureLock)
     {
         D3d.Surface lockedSurface = d3dTexture.GetSurfaceLevel(0);
         textureLock = true;
         return(lockedSurface);
     }
     return(null);
 }
예제 #2
0
        public Texture TakeScreenshot()
        {
            DisplayMode dm = device.DisplayMode;

            Microsoft.DirectX.Direct3D.Texture shot = new Microsoft.DirectX.Direct3D.Texture(device, dm.Width, dm.Height, 1, 0, Format.A8R8G8B8, Pool.SystemMemory);
            device.GetFrontBufferData(0, shot.GetSurfaceLevel(0));
            System.Drawing.Rectangle rect;
            if (fullscreen)
            {
                rect = new Rectangle(0, 0, width, height);
            }
            else
            {
                rect = new Rectangle(Kernel.Form.PointToScreen(new System.Drawing.Point(0, 0)), new Size(width, height));
            }
            int[]   pixels = (int[])shot.LockRectangle(typeof(int), 0, LockFlags.None, dm.Width * dm.Height);
            Texture res    = new Texture(width, height);
            int     i      = 0;

            for (int y = rect.Top; y < rect.Bottom; y++)
            {
                for (int x = rect.Left; x < rect.Right; x++)
                {
                    res[i++] = Color.FromColorCode(pixels[x + y * dm.Width]);
                }
            }
            shot.UnlockRectangle(0);
            return(res);
        }
예제 #3
0
        /// <summary>
        /// Creates the texture as a render target.
        /// </summary>
        public Texture(Renderer renderer, int width, int height, bool alpha)
        {
            if (renderer == null)
                throw new ArgumentNullException("renderer",
                    "Unable to create texture without a valid renderer reference.");

            this.renderer = renderer;

            try
            {
                d3dTexture = new Microsoft.DirectX.Direct3D.Texture(renderer.Device,
                    width, height, 1, Usage.RenderTarget, alpha ? Format.A8R8G8B8 : Format.X8R8G8B8,
                    Pool.Default);

                d3dSurface = d3dTexture.GetSurfaceLevel(0);

                this.size = new Size(width, height);
                this.hasAlpha = alpha;

                loaded = true;

                renderer.AddGraphicsObject(this);
            }
            catch (Exception ex)
            {
                loaded = false;
                Log.Write("Failed to create texture as render target, will use empty texture!" +
                    " Error: " + ex.ToString());
            }
        }
예제 #4
0
        ///<summary>
        ///    @copydoc HardwarePixelBuffer.BlitToMemory
        ///</summary>
        public override void BlitToMemory(BasicBox srcBox, PixelBox dst)
        {
            // Decide on pixel format of temp surface
            PixelFormat tmpFormat = format;

            if (D3DHelper.ConvertEnum(dst.Format) == D3D.Format.Unknown)
            {
                tmpFormat = dst.Format;
            }
            if (surface != null)
            {
                Debug.Assert(srcBox.Depth == 1 && dst.Depth == 1);
                // Create temp texture
                D3D.Texture tmp =
                    new D3D.Texture(device, dst.Width, dst.Height,
                                    1, // 1 mip level ie topmost, generate no mipmaps
                                    0, D3DHelper.ConvertEnum(tmpFormat),
                                    Pool.Scratch);
                D3D.Surface subSurface = tmp.GetSurfaceLevel(0);
                // Copy texture to this temp surface
                Rectangle destRect, srcRect;
                srcRect  = ToD3DRectangle(srcBox);
                destRect = ToD3DRectangleExtent(dst);

                SurfaceLoader.FromSurface(subSurface, destRect, surface, srcRect, Filter.None, 0);

                // Lock temp surface and copy it to memory
                int            pitch; // Filled in by D3D
                GraphicsStream data = subSurface.LockRectangle(D3D.LockFlags.ReadOnly, out pitch);
                // Copy it
                PixelBox locked = new PixelBox(dst.Width, dst.Height, dst.Depth, tmpFormat);
                FromD3DLock(locked, pitch, data);
                PixelUtil.BulkPixelConversion(locked, dst);
                subSurface.UnlockRectangle();
                // Release temporary surface and texture
                subSurface.Dispose();
                tmp.Dispose();
            }
            else
            {
                // Create temp texture
                D3D.VolumeTexture tmp =
                    new D3D.VolumeTexture(device, dst.Width, dst.Height, dst.Depth,
                                          0, D3D.Usage.None,
                                          D3DHelper.ConvertEnum(tmpFormat),
                                          Pool.Scratch);
                D3D.Volume subVolume = tmp.GetVolumeLevel(0);
                // Volume
                D3D.Box ddestBox = ToD3DBoxExtent(dst);
                D3D.Box dsrcBox  = ToD3DBox(srcBox);

                VolumeLoader.FromVolume(subVolume, ddestBox, volume, dsrcBox, Filter.None, 0);
                // Lock temp surface and copy it to memory
                D3D.LockedBox  lbox;                // Filled in by D3D
                GraphicsStream data = subVolume.LockBox(LockFlags.ReadOnly, out lbox);
                // Copy it
                PixelBox locked = new PixelBox(dst.Width, dst.Height, dst.Depth, tmpFormat);
                FromD3DLock(locked, lbox, data);
                PixelUtil.BulkPixelConversion(locked, dst);
                subVolume.UnlockBox();
                // Release temporary surface and texture
                subVolume.Dispose();
                tmp.Dispose();
            }
        }
        public void RefreshTexture()
        {
            if (tileData != null && dirtyImage)
            {
                EnsureTextureIsDynamic(); // Unload texture & recreate if needed

                Texture texture = TextureManager.Instance.GetByName(textureName);
                if (texture == null)
                {
                    // We couldn't find the texture.  It might be that we're in
                    // the midst of swapping them at the DirectX level (this is
                    // only speculation)
                    return;
                }

                if (texture is D3DTexture)
                {
                    // Turns out that to get performance, not only did I have to go
                    // straight to DirectX, unsafe code is much faster as well.  What
                    // we're doing here is keeping a temporary surface around that we
                    // can lock and draw to at our leisure, then copying the surface
                    // over to the correct texture data when we're done.  To do this,
                    // the easiest way is to lock the desired rectangle on the temp
                    // surface, and get a graphics stream object back from it.  You
                    // might think you could then use byte arrays, or even ask for
                    // an Array of bytes back from LockRectangle, but not only was
                    // that slower, it also produced unpredictable results, possibly
                    // due to storing the array in row order vs. column order in the
                    // native vs. managed areas.
                    //
                    // The temporary surface is necessary because, well, I could
                    // never seem to acquire the lock on the real surface.  However,
                    // an offscreen plain surface (as used above) seems to lock fine.
                    //
                    // Next caveat: The pointer on the graphics stream points to the
                    // start of the row of the locked rectangle.  You'd be surprised
                    // how long it took me to figure that one out.  Further, it's
                    // important to use the pitch returned by LockRectangle to adjust
                    // your row array position, as the pitch may or may not be your
                    // surface width in bytes.  (Some drivers store extra data on the
                    // ends of the rows, it seems.)
                    Rectangle lockRect = new Rectangle();
                    lockRect.X      = dirtyArea.X;
                    lockRect.Y      = dirtyArea.Y;
                    lockRect.Width  = dirtyArea.Width;
                    lockRect.Height = dirtyArea.Height;

                    D3D.Texture       t = (texture as D3DTexture).DXTexture as D3D.Texture;
                    int               pitch;
                    int               bpp = PixelUtil.GetNumElemBytes(texture.Format);
                    D3D.Surface       dst = t.GetSurfaceLevel(0);
                    DX.GraphicsStream g   = dynamicSurface.LockRectangle(lockRect, D3D.LockFlags.NoSystemLock, out pitch);
                    unsafe
                    {
                        uint *dstArray = (uint *)g.InternalDataPointer;
                        pitch /= sizeof(uint);
                        for (int z = 0; z < lockRect.Height; z++)
                        {
                            for (int x = 0; x < lockRect.Width; x++)
                            {
                                uint data      = GetData(x + lockRect.X, z + lockRect.Y);
                                uint converted = ConvertPixel(data, INTERNAL_DATA_FORMAT, texture.Format);
                                dstArray[z * pitch + x] = converted;
                            }
                        }
                    }
                    dynamicSurface.UnlockRectangle();
                    D3D.SurfaceLoader.FromSurface(dst, dynamicSurface, D3D.Filter.None, 0);
                }
                else
                {
#if false
                    // following code is for blitting only the dirty rectangle
                    BasicBox destBox = new BasicBox(dirtyArea.X, dirtyArea.Y, dirtyArea.X + dirtyArea.Width,
                                                    dirtyArea.Y + dirtyArea.Height);
                    PixelBox srcPixel        = textureImage.GetPixelBox(0, 0);
                    BasicBox srcBox          = new BasicBox(0, 0, dirtyArea.Width, dirtyArea.Height);
                    PixelBox trimmedSrcPixel = srcPixel.GetSubVolume(srcBox);
                    buffer.BlitFromMemory(trimmedSrcPixel, destBox);
#endif
                }

                // Clean up dirty bit
                dirtyImage       = false;
                dirtyArea.X      = 0;
                dirtyArea.Y      = 0;
                dirtyArea.Width  = 0;
                dirtyArea.Height = 0;
            }
        }
        ///<summary>
        ///    @copydoc HardwarePixelBuffer.BlitToMemory
        ///</summary>
        public override void BlitToMemory(BasicBox srcBox, PixelBox dst)
        {
            // Decide on pixel format of temp surface
            PixelFormat tmpFormat = format;
            if (D3DHelper.ConvertEnum(dst.Format) == D3D.Format.Unknown)
                tmpFormat = dst.Format;
            if (surface != null) {
                Debug.Assert(srcBox.Depth == 1 && dst.Depth == 1);
                // Create temp texture
                D3D.Texture tmp =
                    new D3D.Texture(device, dst.Width, dst.Height,
                                    1, // 1 mip level ie topmost, generate no mipmaps
                                    0, D3DHelper.ConvertEnum(tmpFormat),
                                    Pool.Scratch);
                D3D.Surface subSurface = tmp.GetSurfaceLevel(0);
                // Copy texture to this temp surface
                Rectangle destRect, srcRect;
                srcRect = ToD3DRectangle(srcBox);
                destRect = ToD3DRectangleExtent(dst);

                SurfaceLoader.FromSurface(subSurface, destRect, surface, srcRect, Filter.None, 0);

                // Lock temp surface and copy it to memory
                int pitch; // Filled in by D3D
                GraphicsStream data = subSurface.LockRectangle(D3D.LockFlags.ReadOnly, out pitch);
                // Copy it
                PixelBox locked = new PixelBox(dst.Width, dst.Height, dst.Depth, tmpFormat);
                FromD3DLock(locked, pitch, data);
                PixelUtil.BulkPixelConversion(locked, dst);
                subSurface.UnlockRectangle();
                // Release temporary surface and texture
                subSurface.Dispose();
                tmp.Dispose();
            }
            else {
                // Create temp texture
                D3D.VolumeTexture tmp =
                    new D3D.VolumeTexture(device, dst.Width, dst.Height, dst.Depth,
                                          0, D3D.Usage.None,
                                          D3DHelper.ConvertEnum(tmpFormat),
                                          Pool.Scratch);
                D3D.Volume subVolume = tmp.GetVolumeLevel(0);
                // Volume
                D3D.Box ddestBox = ToD3DBoxExtent(dst);
                D3D.Box dsrcBox = ToD3DBox(srcBox);

                VolumeLoader.FromVolume(subVolume, ddestBox, volume, dsrcBox, Filter.None, 0);
                // Lock temp surface and copy it to memory
                D3D.LockedBox lbox; // Filled in by D3D
                GraphicsStream data = subVolume.LockBox(LockFlags.ReadOnly, out lbox);
                // Copy it
                PixelBox locked = new PixelBox(dst.Width, dst.Height, dst.Depth, tmpFormat);
                FromD3DLock(locked, lbox, data);
                PixelUtil.BulkPixelConversion(locked, dst);
                subVolume.UnlockBox();
                // Release temporary surface and texture
                subVolume.Dispose();
                tmp.Dispose();
            }
        }