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
}
}