diff --git a/src/Graphics/IGLDevice.cs b/src/Graphics/IGLDevice.cs index 6f17c87..9715ca3 100644 --- a/src/Graphics/IGLDevice.cs +++ b/src/Graphics/IGLDevice.cs @@ -176,7 +176,7 @@ namespace Microsoft.Xna.Framework.Graphics int levelCount ); void AddDisposeTexture(IGLTexture texture); - void SetTextureData2D( + void SetTextureData2D( IGLTexture texture, SurfaceFormat format, int x, @@ -184,11 +184,12 @@ namespace Microsoft.Xna.Framework.Graphics int w, int h, int level, - T[] data, + IntPtr data, int startIndex, - int elementCount - ) where T : struct; - void SetTextureData3D( + int elementCount, + int elementSizeInBytes + ); + void SetTextureData3D( IGLTexture texture, SurfaceFormat format, int level, @@ -198,11 +199,12 @@ namespace Microsoft.Xna.Framework.Graphics int bottom, int front, int back, - T[] data, + IntPtr data, int startIndex, - int elementCount - ) where T : struct; - void SetTextureDataCube( + int elementCount, + int elementSizeInBytes + ); + void SetTextureDataCube( IGLTexture texture, SurfaceFormat format, int xOffset, @@ -211,10 +213,11 @@ namespace Microsoft.Xna.Framework.Graphics int height, CubeMapFace cubeMapFace, int level, - T[] data, + IntPtr data, int startIndex, - int elementCount - ) where T : struct; + int elementCount, + int elementSizeInBytes + ); void SetTextureData2DPointer(Texture2D texture, IntPtr ptr); void GetTextureData2D( IGLTexture texture, diff --git a/src/Graphics/OpenGLDevice.cs b/src/Graphics/OpenGLDevice.cs index f65a364..ea3b4bd 100644 --- a/src/Graphics/OpenGLDevice.cs +++ b/src/Graphics/OpenGLDevice.cs @@ -2586,7 +2586,7 @@ namespace Microsoft.Xna.Framework.Graphics #region glTexSubImage Methods - public void SetTextureData2D( + public void SetTextureData2D( IGLTexture texture, SurfaceFormat format, int x, @@ -2594,98 +2594,77 @@ namespace Microsoft.Xna.Framework.Graphics int w, int h, int level, - T[] data, + IntPtr data, int startIndex, - int elementCount - ) where T : struct { + int elementCount, + int elementSizeInBytes + ) { #if !DISABLE_THREADING ForceToMainThread(() => { #endif BindTexture(texture); - GCHandle dataHandle = GCHandle.Alloc(data, GCHandleType.Pinned); - int elementSizeInBytes = Marshal.SizeOf(typeof(T)); - int startByte = startIndex * elementSizeInBytes; - IntPtr dataPtr = (IntPtr) (dataHandle.AddrOfPinnedObject().ToInt64() + startByte); - GLenum glFormat = XNAToGL.TextureFormat[(int) format]; - try + if (glFormat == GLenum.GL_COMPRESSED_TEXTURE_FORMATS) { - if (glFormat == GLenum.GL_COMPRESSED_TEXTURE_FORMATS) + /* Note that we're using glInternalFormat, not glFormat. + * In this case, they should actually be the same thing, + * but we use glFormat somewhat differently for + * compressed textures. + * -flibit + */ + glCompressedTexSubImage2D( + GLenum.GL_TEXTURE_2D, + level, + x, + y, + w, + h, + XNAToGL.TextureInternalFormat[(int) format], + elementCount * elementSizeInBytes, + data + (startIndex * elementSizeInBytes) + ); + } + else + { + // Set pixel alignment to match texel size in bytes + int packSize = Texture.GetFormatSize(format); + if (packSize != 4) { - int dataLength; - if (elementCount > 0) - { - dataLength = elementCount * elementSizeInBytes; - } - else - { - dataLength = data.Length - startByte; - } - - /* Note that we're using glInternalFormat, not glFormat. - * In this case, they should actually be the same thing, - * but we use glFormat somewhat differently for - * compressed textures. - * -flibit - */ - glCompressedTexSubImage2D( - GLenum.GL_TEXTURE_2D, - level, - x, - y, - w, - h, - XNAToGL.TextureInternalFormat[(int) format], - dataLength, - dataPtr + glPixelStorei( + GLenum.GL_UNPACK_ALIGNMENT, + packSize ); } - else - { - // Set pixel alignment to match texel size in bytes - int packSize = Texture.GetFormatSize(format); - if (packSize != 4) - { - glPixelStorei( - GLenum.GL_UNPACK_ALIGNMENT, - packSize - ); - } - glTexSubImage2D( - GLenum.GL_TEXTURE_2D, - level, - x, - y, - w, - h, - glFormat, - XNAToGL.TextureDataType[(int) format], - dataPtr - ); + glTexSubImage2D( + GLenum.GL_TEXTURE_2D, + level, + x, + y, + w, + h, + glFormat, + XNAToGL.TextureDataType[(int) format], + data + (startIndex * elementSizeInBytes) + ); - // Keep this state sane -flibit - if (packSize != 4) - { - glPixelStorei( - GLenum.GL_UNPACK_ALIGNMENT, - 4 - ); - } + // Keep this state sane -flibit + if (packSize != 4) + { + glPixelStorei( + GLenum.GL_UNPACK_ALIGNMENT, + 4 + ); } } - finally - { - dataHandle.Free(); - } #if !DISABLE_THREADING }); #endif } - public void SetTextureData3D( + public void SetTextureData3D( IGLTexture texture, SurfaceFormat format, int level, @@ -2695,43 +2674,36 @@ namespace Microsoft.Xna.Framework.Graphics int bottom, int front, int back, - T[] data, + IntPtr data, int startIndex, - int elementCount - ) where T : struct { + int elementCount, + int elementSizeInBytes + ) { #if !DISABLE_THREADING ForceToMainThread(() => { #endif BindTexture(texture); - GCHandle dataHandle = GCHandle.Alloc(data, GCHandleType.Pinned); - try - { - glTexSubImage3D( - GLenum.GL_TEXTURE_3D, - level, - left, - top, - front, - right - left, - bottom - top, - back - front, - XNAToGL.TextureFormat[(int) format], - XNAToGL.TextureDataType[(int) format], - (IntPtr) (dataHandle.AddrOfPinnedObject().ToInt64() + startIndex * Marshal.SizeOf(typeof(T))) - ); - } - finally - { - dataHandle.Free(); - } + glTexSubImage3D( + GLenum.GL_TEXTURE_3D, + level, + left, + top, + front, + right - left, + bottom - top, + back - front, + XNAToGL.TextureFormat[(int) format], + XNAToGL.TextureDataType[(int) format], + data + (startIndex * elementSizeInBytes) + ); #if !DISABLE_THREADING }); #endif } - public void SetTextureDataCube( + public void SetTextureDataCube( IGLTexture texture, SurfaceFormat format, int xOffset, @@ -2740,71 +2712,50 @@ namespace Microsoft.Xna.Framework.Graphics int height, CubeMapFace cubeMapFace, int level, - T[] data, + IntPtr data, int startIndex, - int elementCount - ) where T : struct { + int elementCount, + int elementSizeInBytes + ) { #if !DISABLE_THREADING ForceToMainThread(() => { #endif BindTexture(texture); - GCHandle dataHandle = GCHandle.Alloc(data, GCHandleType.Pinned); - int elementSizeInBytes = Marshal.SizeOf(typeof(T)); - int startByte = startIndex * elementSizeInBytes; - IntPtr dataPtr = (IntPtr) (dataHandle.AddrOfPinnedObject().ToInt64() + startByte); - GLenum glFormat = XNAToGL.TextureFormat[(int) format]; - try + if (glFormat == GLenum.GL_COMPRESSED_TEXTURE_FORMATS) { - if (glFormat == GLenum.GL_COMPRESSED_TEXTURE_FORMATS) - { - int dataLength; - if (elementCount > 0) - { - dataLength = elementCount * elementSizeInBytes; - } - else - { - dataLength = data.Length - startByte; - } - - /* Note that we're using glInternalFormat, not glFormat. - * In this case, they should actually be the same thing, - * but we use glFormat somewhat differently for - * compressed textures. - * -flibit - */ - glCompressedTexSubImage2D( - GLenum.GL_TEXTURE_CUBE_MAP_POSITIVE_X + (int) cubeMapFace, - level, - xOffset, - yOffset, - width, - height, - XNAToGL.TextureInternalFormat[(int) format], - dataLength, - dataPtr - ); - } - else - { - glTexSubImage2D( - GLenum.GL_TEXTURE_CUBE_MAP_POSITIVE_X + (int) cubeMapFace, - level, - xOffset, - yOffset, - width, - height, - glFormat, - XNAToGL.TextureDataType[(int) format], - dataPtr - ); - } + /* Note that we're using glInternalFormat, not glFormat. + * In this case, they should actually be the same thing, + * but we use glFormat somewhat differently for + * compressed textures. + * -flibit + */ + glCompressedTexSubImage2D( + GLenum.GL_TEXTURE_CUBE_MAP_POSITIVE_X + (int) cubeMapFace, + level, + xOffset, + yOffset, + width, + height, + XNAToGL.TextureInternalFormat[(int) format], + elementCount * elementSizeInBytes, + data + (startIndex * elementSizeInBytes) + ); } - finally + else { - dataHandle.Free(); + glTexSubImage2D( + GLenum.GL_TEXTURE_CUBE_MAP_POSITIVE_X + (int) cubeMapFace, + level, + xOffset, + yOffset, + width, + height, + glFormat, + XNAToGL.TextureDataType[(int) format], + data + (startIndex * elementSizeInBytes) + ); } #if !DISABLE_THREADING diff --git a/src/Graphics/Texture2D.cs b/src/Graphics/Texture2D.cs index 00c6a52..51dcb12 100644 --- a/src/Graphics/Texture2D.cs +++ b/src/Graphics/Texture2D.cs @@ -10,6 +10,7 @@ #region Using Statements using System; using System.IO; +using System.Runtime.InteropServices; #endregion namespace Microsoft.Xna.Framework.Graphics @@ -138,6 +139,7 @@ namespace Microsoft.Xna.Framework.Graphics h = Math.Max(Height >> level, 1); } + GCHandle handle = GCHandle.Alloc(data, GCHandleType.Pinned); GraphicsDevice.GLDevice.SetTextureData2D( texture, Format, @@ -146,10 +148,12 @@ namespace Microsoft.Xna.Framework.Graphics w, h, level, - data, + handle.AddrOfPinnedObject(), startIndex, - elementCount + elementCount, + Marshal.SizeOf(typeof(T)) ); + handle.Free(); } #endregion diff --git a/src/Graphics/Texture3D.cs b/src/Graphics/Texture3D.cs index 8302548..1e80e8d 100644 --- a/src/Graphics/Texture3D.cs +++ b/src/Graphics/Texture3D.cs @@ -9,6 +9,7 @@ #region Using Statements using System; +using System.Runtime.InteropServices; #endregion namespace Microsoft.Xna.Framework.Graphics @@ -117,6 +118,7 @@ namespace Microsoft.Xna.Framework.Graphics throw new ArgumentNullException("data"); } + GCHandle handle = GCHandle.Alloc(data, GCHandleType.Pinned); GraphicsDevice.GLDevice.SetTextureData3D( texture, Format, @@ -127,9 +129,10 @@ namespace Microsoft.Xna.Framework.Graphics bottom, front, back, - data, + handle.AddrOfPinnedObject(), startIndex, - elementCount + elementCount, + Marshal.SizeOf(typeof(T)) ); } diff --git a/src/Graphics/TextureCube.cs b/src/Graphics/TextureCube.cs index fb21156..95b26c2 100644 --- a/src/Graphics/TextureCube.cs +++ b/src/Graphics/TextureCube.cs @@ -9,6 +9,7 @@ #region Using Statements using System; +using System.Runtime.InteropServices; #endregion namespace Microsoft.Xna.Framework.Graphics @@ -117,6 +118,7 @@ namespace Microsoft.Xna.Framework.Graphics height = Math.Max(1, Size >> level); } + GCHandle handle = GCHandle.Alloc(data, GCHandleType.Pinned); GraphicsDevice.GLDevice.SetTextureDataCube( texture, Format, @@ -126,10 +128,12 @@ namespace Microsoft.Xna.Framework.Graphics height, cubeMapFace, level, - data, + handle.AddrOfPinnedObject(), startIndex, - elementCount + elementCount, + Marshal.SizeOf(typeof(T)) ); + handle.Free(); } #endregion