Working on Texture2DGL3.

This commit is contained in:
SND\AstrorEnales_cp 2011-11-14 21:01:54 +00:00
parent e02485ab9e
commit b3e50da398
3 changed files with 195 additions and 95 deletions

View File

@ -119,16 +119,11 @@ namespace ANX.Framework.Windows.GL3
/// <param name="width">The width of the texture.</param> /// <param name="width">The width of the texture.</param>
/// <param name="height">The height of the texture.</param> /// <param name="height">The height of the texture.</param>
/// <param name="mipCount">The number of mipmaps in the texture.</param> /// <param name="mipCount">The number of mipmaps in the texture.</param>
/// <param name="mipMaps">The mipmaps as a single byte array.</param>
/// <returns></returns> /// <returns></returns>
public INativeTexture2D CreateTexture(GraphicsDevice graphics, public INativeTexture2D CreateTexture(GraphicsDevice graphics,
SurfaceFormat surfaceFormat, int width, int height, int mipCount) //, SurfaceFormat surfaceFormat, int width, int height, int mipCount)
//byte[] mipMaps)
{ {
throw new NotImplementedException(); return new Texture2DGL3(surfaceFormat, width, height, mipCount);
//return new Texture2DGL3(graphics, surfaceFormat, width,
// height, mipCount, mipMaps);
} }
#endregion #endregion

View File

@ -1,6 +1,7 @@
using System; using System;
using ANX.Framework.Graphics; using ANX.Framework.Graphics;
using OpenTK.Graphics; using OpenTK.Graphics;
using OpenTK.Graphics.OpenGL;
#region License #region License
@ -159,6 +160,80 @@ namespace ANX.Framework.Windows.GL3
} }
#endregion #endregion
#region SurfaceToPixelInternalFormat (TODO)
/// <summary>
/// Translate the XNA surface format to an OpenGL PixelInternalFormat.
/// </summary>
/// <param name="format">XNA surface format.</param>
/// <returns>Translated format for OpenGL.</returns>
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 #region Tests
private class Tests private class Tests
{ {

View File

@ -1,7 +1,8 @@
using System; using System;
using ANX.Framework.Graphics;
using OpenTK.Graphics.OpenGL;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using ANX.Framework.Graphics;
using ANX.Framework.NonXNA.RenderSystem;
using OpenTK.Graphics.OpenGL;
#region License #region License
@ -53,10 +54,37 @@ using System.Runtime.InteropServices;
namespace ANX.Framework.Windows.GL3 namespace ANX.Framework.Windows.GL3
{ {
/// <summary> /// <summary>
/// BIG TODO /// Native OpenGL Texture implementation.
/// </summary> /// </summary>
public class Texture2DGL3 : Texture2D public class Texture2DGL3 : INativeTexture2D
{ {
#region Private
/// <summary>
/// The native OpenGL pixel format of the texture.
/// </summary>
private PixelInternalFormat nativeFormat;
/// <summary>
/// The number of mipmaps used by this texture [1-n].
/// </summary>
private int numberOfMipMaps;
/// <summary>
/// Width of the texture.
/// </summary>
private int width;
/// <summary>
/// Height of the texture.
/// </summary>
private int height;
/// <summary>
/// Flag if the texture is a compressed format or not.
/// </summary>
private bool isCompressed;
#endregion
#region Public #region Public
/// <summary> /// <summary>
/// The OpenGL texture handle. /// The OpenGL texture handle.
@ -69,18 +97,26 @@ namespace ANX.Framework.Windows.GL3
#endregion #endregion
#region Constructor #region Constructor
internal Texture2DGL3(GraphicsDevice graphics, /// <summary>
SurfaceFormat surfaceFormat, int width, int height, int mipCount, /// Create a new native OpenGL texture.
byte[] mipMaps) /// </summary>
: base(graphics, width, height, mipCount > 0, surfaceFormat) /// <param name="surfaceFormat">Surface format of the texture.</param>
/// <param name="setWidth">Width of the first mip level.</param>
/// <param name="setHeight">Height of the first mip level.</param>
/// <param name="mipCount">Number of mip levels [1-n].</param>
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(); NativeHandle = GL.GenTexture();
GL.BindTexture(TextureTarget.Texture2D, NativeHandle); GL.BindTexture(TextureTarget.Texture2D, NativeHandle);
int wrapMode = (int)All.ClampToEdge; 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, GL.TexParameter(TextureTarget.Texture2D,
TextureParameterName.TextureWrapS, wrapMode); TextureParameterName.TextureWrapS, wrapMode);
@ -91,97 +127,81 @@ namespace ANX.Framework.Windows.GL3
GL.TexParameter(TextureTarget.Texture2D, GL.TexParameter(TextureTarget.Texture2D,
TextureParameterName.TextureMinFilter, filter); 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<T>(GraphicsDevice graphicsDevice, T[] data)
where T : struct
{
SetData<T>(graphicsDevice, data, 0, data.Length);
}
public void SetData<T>(GraphicsDevice graphicsDevice, T[] data,
int startIndex, int elementCount) where T : struct
{
SetData<T>(graphicsDevice, 0, data, 0, data.Length);
}
public void SetData<T>(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 try
{ {
IntPtr dataPointer = handle.AddrOfPinnedObject(); IntPtr dataPointer = handle.AddrOfPinnedObject();
if (surfaceFormat == SurfaceFormat.Dxt1 || if (isCompressed)
surfaceFormat == SurfaceFormat.Dxt3 ||
surfaceFormat == SurfaceFormat.Dxt5)
{ {
// TODO: read dataLengthPerTexture from dds file. GL.CompressedTexImage2D(TextureTarget.Texture2D, 0, nativeFormat,
#region Dds width, height, 0, mipmapByteSize, dataPointer);
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
} }
else else
{ {
#region Other GL.TexImage2D(TextureTarget.Texture2D, 0, nativeFormat,
PixelType pixelType = PixelType.UnsignedByte; width, height, 0, (PixelFormat)nativeFormat,
PixelType.UnsignedByte, dataPointer);
}
GL.TexImage2D(TextureTarget.Texture2D, 0, int mipmapWidth = width;
// Use the same for internal format (Rgba or Rgb) int mipmapHeight = height;
formatUsed, width, height, 0, for (int index = 1; index < numberOfMipMaps; index++)
// And the same for the pixel format of the incoming data {
(PixelFormat)formatUsed, pixelType, dataPointer); dataPointer += mipmapByteSize;
mipmapByteSize /= 4;
mipmapWidth /= 2;
mipmapHeight /= 2;
mipmapWidth = Math.Max(mipmapWidth, 1);
mipmapHeight = Math.Max(mipmapHeight, 1);
int mipmapByteSize = dataLengthPerTexture; if (isCompressed)
int mipmapWidth = width;
int mipmapHeight = height;
if (mipmapByteSize > 0 &&
mipCount > 0)
{ {
for (int i = 1; i < mipCount; i++) GL.CompressedTexImage2D(TextureTarget.Texture2D, index,
{ nativeFormat, width, height, 0, mipmapByteSize,
// Move our data pointer along. dataPointer);
dataPointer += mipmapByteSize; }
mipmapByteSize /= 4; else
mipmapWidth /= 2; {
mipmapHeight /= 2; GL.TexImage2D(TextureTarget.Texture2D, index, nativeFormat,
if (mipmapWidth < 1) mipmapWidth, mipmapHeight, 0, (PixelFormat)nativeFormat,
{ PixelType.UnsignedByte, dataPointer);
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);
}
} }
#endregion
} }
} }
finally finally
@ -190,5 +210,15 @@ namespace ANX.Framework.Windows.GL3
} }
} }
#endregion #endregion
#region Dispose
/// <summary>
/// Dispose the native OpenGL texture handle.
/// </summary>
public void Dispose()
{
GL.DeleteTexture(NativeHandle);
}
#endregion
} }
} }