From b3e50da398cdd37005c1b8afb34d19a3df88dc4a Mon Sep 17 00:00:00 2001 From: "SND\\AstrorEnales_cp" Date: Mon, 14 Nov 2011 21:01:54 +0000 Subject: [PATCH] Working on Texture2DGL3. --- ANX.Framework.Windows.GL3/Creator.cs | 9 +- ANX.Framework.Windows.GL3/DatatypesMapping.cs | 75 +++++++ ANX.Framework.Windows.GL3/Texture2DGL3.cs | 206 ++++++++++-------- 3 files changed, 195 insertions(+), 95 deletions(-) diff --git a/ANX.Framework.Windows.GL3/Creator.cs b/ANX.Framework.Windows.GL3/Creator.cs index ee7e86ba..4805c98e 100644 --- a/ANX.Framework.Windows.GL3/Creator.cs +++ b/ANX.Framework.Windows.GL3/Creator.cs @@ -119,16 +119,11 @@ namespace ANX.Framework.Windows.GL3 /// The width of the texture. /// The height of the texture. /// The number of mipmaps in the texture. - /// The mipmaps as a single byte array. /// public INativeTexture2D CreateTexture(GraphicsDevice graphics, - SurfaceFormat surfaceFormat, int width, int height, int mipCount) //, - //byte[] mipMaps) + SurfaceFormat surfaceFormat, int width, int height, int mipCount) { - throw new NotImplementedException(); - - //return new Texture2DGL3(graphics, surfaceFormat, width, - // height, mipCount, mipMaps); + return new Texture2DGL3(surfaceFormat, width, height, mipCount); } #endregion diff --git a/ANX.Framework.Windows.GL3/DatatypesMapping.cs b/ANX.Framework.Windows.GL3/DatatypesMapping.cs index f4d9c7ed..6a2854fa 100644 --- a/ANX.Framework.Windows.GL3/DatatypesMapping.cs +++ b/ANX.Framework.Windows.GL3/DatatypesMapping.cs @@ -1,6 +1,7 @@ using System; using ANX.Framework.Graphics; using OpenTK.Graphics; +using OpenTK.Graphics.OpenGL; #region License @@ -159,6 +160,80 @@ namespace ANX.Framework.Windows.GL3 } #endregion + #region SurfaceToPixelInternalFormat (TODO) + /// + /// Translate the XNA surface format to an OpenGL PixelInternalFormat. + /// + /// XNA surface format. + /// Translated format for OpenGL. + public static PixelInternalFormat SurfaceToPixelInternalFormat( + SurfaceFormat format) + { + switch (format) + { + // TODO + case SurfaceFormat.HdrBlendable: + case SurfaceFormat.Bgr565: + throw new NotImplementedException("Surface Format '" + format + + "' isn't implemented yet!"); + + // TODO: CHECK! + case SurfaceFormat.NormalizedByte2: + return PixelInternalFormat.Rg8; + + default: + case SurfaceFormat.Color: + case SurfaceFormat.NormalizedByte4: + return PixelInternalFormat.Rgba; + + case SurfaceFormat.Dxt1: + return PixelInternalFormat.CompressedRgbaS3tcDxt1Ext; + + case SurfaceFormat.Dxt3: + return PixelInternalFormat.CompressedRgbaS3tcDxt3Ext; + + case SurfaceFormat.Dxt5: + return PixelInternalFormat.CompressedRgbaS3tcDxt5Ext; + + case SurfaceFormat.HalfVector2: + return PixelInternalFormat.Rg16; + + case SurfaceFormat.HalfVector4: + return PixelInternalFormat.Rgba16f; + + case SurfaceFormat.Bgra4444: + return PixelInternalFormat.Rgba4; + + case SurfaceFormat.Bgra5551: + return PixelInternalFormat.Rgb5A1; + + case SurfaceFormat.Alpha8: + return PixelInternalFormat.Alpha8; + + case SurfaceFormat.Rg32: + return PixelInternalFormat.Rg32f; + + case SurfaceFormat.Rgba1010102: + return PixelInternalFormat.Rgb10A2; + + case SurfaceFormat.Rgba64: + return PixelInternalFormat.Rgba16f; + + case SurfaceFormat.HalfSingle: + return PixelInternalFormat.R16f; + + case SurfaceFormat.Single: + return PixelInternalFormat.R32f; + + case SurfaceFormat.Vector2: + return PixelInternalFormat.Rg32f; + + case SurfaceFormat.Vector4: + return PixelInternalFormat.Rgba32f; + } + } + #endregion + #region Tests private class Tests { diff --git a/ANX.Framework.Windows.GL3/Texture2DGL3.cs b/ANX.Framework.Windows.GL3/Texture2DGL3.cs index 064ac04f..07eb9cd4 100644 --- a/ANX.Framework.Windows.GL3/Texture2DGL3.cs +++ b/ANX.Framework.Windows.GL3/Texture2DGL3.cs @@ -1,7 +1,8 @@ using System; -using ANX.Framework.Graphics; -using OpenTK.Graphics.OpenGL; using System.Runtime.InteropServices; +using ANX.Framework.Graphics; +using ANX.Framework.NonXNA.RenderSystem; +using OpenTK.Graphics.OpenGL; #region License @@ -53,10 +54,37 @@ using System.Runtime.InteropServices; namespace ANX.Framework.Windows.GL3 { /// - /// BIG TODO + /// Native OpenGL Texture implementation. /// - public class Texture2DGL3 : Texture2D + public class Texture2DGL3 : INativeTexture2D { + #region Private + /// + /// The native OpenGL pixel format of the texture. + /// + private PixelInternalFormat nativeFormat; + + /// + /// The number of mipmaps used by this texture [1-n]. + /// + private int numberOfMipMaps; + + /// + /// Width of the texture. + /// + private int width; + + /// + /// Height of the texture. + /// + private int height; + + /// + /// Flag if the texture is a compressed format or not. + /// + private bool isCompressed; + #endregion + #region Public /// /// The OpenGL texture handle. @@ -69,18 +97,26 @@ namespace ANX.Framework.Windows.GL3 #endregion #region Constructor - internal Texture2DGL3(GraphicsDevice graphics, - SurfaceFormat surfaceFormat, int width, int height, int mipCount, - byte[] mipMaps) - : base(graphics, width, height, mipCount > 0, surfaceFormat) + /// + /// Create a new native OpenGL texture. + /// + /// Surface format of the texture. + /// Width of the first mip level. + /// Height of the first mip level. + /// Number of mip levels [1-n]. + internal Texture2DGL3(SurfaceFormat surfaceFormat, int setWidth, + int setHeight, int mipCount) { - int dataLengthPerTexture = 0; + width = setWidth; + height = setHeight; + numberOfMipMaps = mipCount; + isCompressed = nativeFormat.ToString().StartsWith("Compressed"); NativeHandle = GL.GenTexture(); GL.BindTexture(TextureTarget.Texture2D, NativeHandle); int wrapMode = (int)All.ClampToEdge; - int filter = (int)(mipCount > 0 ? All.LinearMipmapLinear : All.Linear); + int filter = (int)(mipCount > 1 ? All.LinearMipmapLinear : All.Linear); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, wrapMode); @@ -91,97 +127,81 @@ namespace ANX.Framework.Windows.GL3 GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, filter); - PixelInternalFormat formatUsed = PixelInternalFormat.Rgba; + nativeFormat = + DatatypesMapping.SurfaceToPixelInternalFormat(surfaceFormat); + } + #endregion + + // TODO: offsetInBytes + // TODO: startIndex + // TODO: elementCount + // TODO: get size of first mipmap! + #region SetData + public void SetData(GraphicsDevice graphicsDevice, T[] data) + where T : struct + { + SetData(graphicsDevice, data, 0, data.Length); + } + + public void SetData(GraphicsDevice graphicsDevice, T[] data, + int startIndex, int elementCount) where T : struct + { + SetData(graphicsDevice, 0, data, 0, data.Length); + } + + public void SetData(GraphicsDevice graphicsDevice, int offsetInBytes, + T[] data, int startIndex, int elementCount) where T : struct + { + if (numberOfMipMaps > 1) + { + throw new NotImplementedException( + "Loading mipmaps is not correctly implemented yet!"); + } + + GCHandle handle = GCHandle.Alloc(data, GCHandleType.Pinned); + + // TODO: get size of first mipmap! + int mipmapByteSize = data.Length; - GCHandle handle = GCHandle.Alloc(mipMaps, GCHandleType.Pinned); try { IntPtr dataPointer = handle.AddrOfPinnedObject(); - if (surfaceFormat == SurfaceFormat.Dxt1 || - surfaceFormat == SurfaceFormat.Dxt3 || - surfaceFormat == SurfaceFormat.Dxt5) + if (isCompressed) { - // TODO: read dataLengthPerTexture from dds file. - #region Dds - formatUsed = - surfaceFormat == SurfaceFormat.Dxt1 ? - PixelInternalFormat.CompressedRgbS3tcDxt1Ext : - surfaceFormat == SurfaceFormat.Dxt3 ? - PixelInternalFormat.CompressedRgbaS3tcDxt3Ext : - PixelInternalFormat.CompressedRgbaS3tcDxt5Ext; - - GL.CompressedTexImage2D(TextureTarget.Texture2D, 0, formatUsed, - width, height, 0, dataLengthPerTexture, dataPointer); - - int mipmapByteSize = dataLengthPerTexture; - int mipmapWidth = width; - int mipmapHeight = height; - for (int i = 1; i < mipCount; i++) - { - // Move our data pointer along. - dataPointer += mipmapByteSize; - mipmapByteSize /= 4; - mipmapWidth /= 2; - mipmapHeight /= 2; - if (mipmapByteSize < 32) - { - mipmapByteSize = 32; - } - if (mipmapWidth < 1) - { - mipmapWidth = 1; - } - if (mipmapHeight < 1) - { - mipmapHeight = 1; - } - GL.CompressedTexImage2D(TextureTarget.Texture2D, i, formatUsed, - mipmapWidth, mipmapHeight, 0, mipmapByteSize, dataPointer); - } - #endregion + GL.CompressedTexImage2D(TextureTarget.Texture2D, 0, nativeFormat, + width, height, 0, mipmapByteSize, dataPointer); } else { - #region Other - PixelType pixelType = PixelType.UnsignedByte; + GL.TexImage2D(TextureTarget.Texture2D, 0, nativeFormat, + width, height, 0, (PixelFormat)nativeFormat, + PixelType.UnsignedByte, dataPointer); + } - GL.TexImage2D(TextureTarget.Texture2D, 0, - // Use the same for internal format (Rgba or Rgb) - formatUsed, width, height, 0, - // And the same for the pixel format of the incoming data - (PixelFormat)formatUsed, pixelType, dataPointer); + int mipmapWidth = width; + int mipmapHeight = height; + for (int index = 1; index < numberOfMipMaps; index++) + { + dataPointer += mipmapByteSize; + mipmapByteSize /= 4; + mipmapWidth /= 2; + mipmapHeight /= 2; + mipmapWidth = Math.Max(mipmapWidth, 1); + mipmapHeight = Math.Max(mipmapHeight, 1); - int mipmapByteSize = dataLengthPerTexture; - int mipmapWidth = width; - int mipmapHeight = height; - if (mipmapByteSize > 0 && - mipCount > 0) + if (isCompressed) { - for (int i = 1; i < mipCount; i++) - { - // Move our data pointer along. - dataPointer += mipmapByteSize; - mipmapByteSize /= 4; - mipmapWidth /= 2; - mipmapHeight /= 2; - if (mipmapWidth < 1) - { - mipmapWidth = 1; - } - if (mipmapHeight < 1) - { - mipmapHeight = 1; - } - - GL.TexImage2D(TextureTarget.Texture2D, i, - // Use the same for internal format (Rgba or Rgb) - formatUsed, mipmapWidth, mipmapHeight, 0, - // And the same for the pixel format of the incoming data - (PixelFormat)formatUsed, pixelType, dataPointer); - } + GL.CompressedTexImage2D(TextureTarget.Texture2D, index, + nativeFormat, width, height, 0, mipmapByteSize, + dataPointer); + } + else + { + GL.TexImage2D(TextureTarget.Texture2D, index, nativeFormat, + mipmapWidth, mipmapHeight, 0, (PixelFormat)nativeFormat, + PixelType.UnsignedByte, dataPointer); } - #endregion } } finally @@ -190,5 +210,15 @@ namespace ANX.Framework.Windows.GL3 } } #endregion + + #region Dispose + /// + /// Dispose the native OpenGL texture handle. + /// + public void Dispose() + { + GL.DeleteTexture(NativeHandle); + } + #endregion } }