From f33428a5315f0ec862c81c7f0e7369e5fd1edb39 Mon Sep 17 00:00:00 2001 From: UnknownShadow200 Date: Wed, 2 Sep 2015 18:33:13 +1000 Subject: [PATCH] Implement ability to perform partial update of textures on both graphics api backends. Partially addresses #44. --- ClassicalSharp/GraphicsAPI/Direct3D9Api.cs | 7 +++++- ClassicalSharp/GraphicsAPI/IGraphicsApi.cs | 2 ++ ClassicalSharp/GraphicsAPI/OpenGLApi.cs | 16 ++++++-------- OpenTK/SharpDX.Direct3D/Resources.cs | 25 +++++++++++++++++++++- OpenTK/SharpDX/Raw.cs | 8 ++++++- 5 files changed, 46 insertions(+), 12 deletions(-) diff --git a/ClassicalSharp/GraphicsAPI/Direct3D9Api.cs b/ClassicalSharp/GraphicsAPI/Direct3D9Api.cs index acceb24ce..5cbf2ef00 100644 --- a/ClassicalSharp/GraphicsAPI/Direct3D9Api.cs +++ b/ClassicalSharp/GraphicsAPI/Direct3D9Api.cs @@ -162,9 +162,14 @@ namespace ClassicalSharp.GraphicsAPI { public override int CreateTexture( int width, int height, IntPtr scan0 ) { D3D.Texture texture = device.CreateTexture( width, height, 0, Usage.None, Format.A8R8G8B8, Pool.Managed ); - texture.SetData( scan0, width * height * 4, 0, LockFlags.None ); + texture.SetData( 0, LockFlags.None, scan0, width * height * 4 ); return GetOrExpand( ref textures, texture, texBufferSize ); } + + public override void UpdateTexturePart( int texId, int texX, int texY, FastBitmap part ) { + D3D.Texture texture = textures[texId]; + texture.SetPartData( 0, LockFlags.None, part.Scan0, texX, texY, part.Width, part.Height ); + } public override void BindTexture( int texId ) { device.SetTexture( 0, textures[texId] ); diff --git a/ClassicalSharp/GraphicsAPI/IGraphicsApi.cs b/ClassicalSharp/GraphicsAPI/IGraphicsApi.cs index 7b8c8a4e2..960578e02 100644 --- a/ClassicalSharp/GraphicsAPI/IGraphicsApi.cs +++ b/ClassicalSharp/GraphicsAPI/IGraphicsApi.cs @@ -44,6 +44,8 @@ namespace ClassicalSharp.GraphicsAPI { public abstract int CreateTexture( int width, int height, IntPtr scan0 ); + public abstract void UpdateTexturePart( int texId, int texX, int texY, FastBitmap part ); + public abstract void BindTexture( int texId ); public abstract void DeleteTexture( ref int texId ); diff --git a/ClassicalSharp/GraphicsAPI/OpenGLApi.cs b/ClassicalSharp/GraphicsAPI/OpenGLApi.cs index 9e3f483ca..d3efafe15 100644 --- a/ClassicalSharp/GraphicsAPI/OpenGLApi.cs +++ b/ClassicalSharp/GraphicsAPI/OpenGLApi.cs @@ -159,9 +159,15 @@ namespace ClassicalSharp.GraphicsAPI { GlPixelFormat.Bgra, PixelType.UnsignedByte, scan0 ); return texId; } - + public override void BindTexture( int texture ) { GL.BindTexture( TextureTarget.Texture2D, texture ); + } + + public override void UpdateTexturePart( int texId, int texX, int texY, FastBitmap part ) { + GL.BindTexture( TextureTarget.Texture2D, texId ); + GL.TexSubImage2D( TextureTarget.Texture2D, 0, texX, texY, part.Width, part.Height, + GlPixelFormat.Bgra, PixelType.UnsignedByte, part.Scan0 ); } public unsafe override void DeleteTexture( ref int texId ) { @@ -403,14 +409,6 @@ namespace ClassicalSharp.GraphicsAPI { if( value ) GL.Enable( cap ); else GL.Disable( cap ); } - - public void UpdateTexturePart( int texId, int x, int y, FastBitmap part ) { - GL.Enable( EnableCap.Texture2D ); - GL.BindTexture( TextureTarget.Texture2D, texId ); - GL.TexSubImage2D( TextureTarget.Texture2D, 0, x, y, part.Width, part.Height, - GlPixelFormat.Bgra, PixelType.UnsignedByte, part.Scan0 ); - GL.Disable( EnableCap.Texture2D ); - } } } #endif \ No newline at end of file diff --git a/OpenTK/SharpDX.Direct3D/Resources.cs b/OpenTK/SharpDX.Direct3D/Resources.cs index 63fb0dadf..830b61003 100644 --- a/OpenTK/SharpDX.Direct3D/Resources.cs +++ b/OpenTK/SharpDX.Direct3D/Resources.cs @@ -106,12 +106,35 @@ namespace SharpDX.Direct3D9 { return lockedRect; } - public void SetData( IntPtr data, int bytes, int level, LockFlags flags ) { + public LockedRectangle LockRectangle(int level, D3DRect rect, LockFlags flags) { + LockedRectangle lockedRect = new LockedRectangle(); + int res = Interop.Calli(comPointer, level, (IntPtr)(void*)&lockedRect, (IntPtr)(void*)&rect, (int)flags,(*(IntPtr**)comPointer)[19]); + if( res < 0 ) { throw new SharpDXException( res ); } + return lockedRect; + } + + public void SetData( int level, LockFlags flags, IntPtr data,int bytes ) { LockedRectangle rect = LockRectangle( level, flags ); MemUtils.memcpy( data, rect.DataPointer, bytes ); UnlockRectangle( level ); } + public void SetPartData( int level, LockFlags flags, IntPtr data, int x, int y, int width, int height ) { + D3DRect partRect; + partRect.Left = x; partRect.Top = y; + partRect.Right = x + width; partRect.Bottom = y + height; + LockedRectangle rect = LockRectangle( level, partRect, flags ); + + // We need to copy scanline by scanline, as generally rect.stride != data.stride + byte* src = (byte*)data, dst = (byte*)rect.DataPointer; + for( int yy = 0; yy < height; yy++ ) { + MemUtils.memcpy( (IntPtr)src, (IntPtr)dst, width * 4 ); + src += width * 4; + dst += rect.Pitch; + } + UnlockRectangle( level ); + } + public void UnlockRectangle(int level) { int res = Interop.Calli(comPointer, level,(*(IntPtr**)comPointer)[20]); if( res < 0 ) { throw new SharpDXException( res ); } diff --git a/OpenTK/SharpDX/Raw.cs b/OpenTK/SharpDX/Raw.cs index fcf4e1382..6bc29cf6a 100644 --- a/OpenTK/SharpDX/Raw.cs +++ b/OpenTK/SharpDX/Raw.cs @@ -50,5 +50,11 @@ namespace SharpDX { public IntPtr DataPointer; } - + [StructLayout( LayoutKind.Sequential )] + public struct D3DRect { + public int Left; + public int Top; + public int Right; + public int Bottom; + } }