- Fixed the Texture2DReader to correctly fill the texture with the mipmaps

- Implemented Mipmap textures for Dx10, Dx11, GL3. Metro is implemented but has still some problems with mipmaps (probably cause of the vm)
- Added Sample dds texture
- Fixed compiler error in MetroGameTimer
This commit is contained in:
SND\AstrorEnales_cp 2012-09-08 09:07:23 +00:00
parent 1f036805f5
commit 0fc4409e58
21 changed files with 543 additions and 489 deletions

View File

@ -1,11 +1,7 @@
#region Using Statements using System;
using System;
using System.Collections.Generic;
using ANX.Framework.Graphics; using ANX.Framework.Graphics;
using ANX.Framework.NonXNA; using ANX.Framework.NonXNA;
#endregion // Using Statements
// This file is part of the ANX.Framework created by the // This file is part of the ANX.Framework created by the
// "ANX.Framework developer group" and released under the Ms-PL license. // "ANX.Framework developer group" and released under the Ms-PL license.
// For details see: http://anxframework.codeplex.com/license // For details see: http://anxframework.codeplex.com/license
@ -16,33 +12,26 @@ namespace ANX.Framework.Content
{ {
protected internal override Texture2D Read(ContentReader input, Texture2D existingInstance) protected internal override Texture2D Read(ContentReader input, Texture2D existingInstance)
{ {
IServiceProvider service = input.ContentManager.ServiceProvider; //IServiceProvider service = input.ContentManager.ServiceProvider;
//var renderSystem = service.GetService(typeof(IRenderSystemCreator)) as IRenderSystemCreator;
//if (renderSystem == null)
// throw new ContentLoadException("Service not found IRenderSystemCreator");
var rfc = service.GetService(typeof(IRenderSystemCreator)) as IRenderSystemCreator; //GraphicsDevice graphics = input.ResolveGraphicsDevice();
if (rfc == null)
{
throw new ContentLoadException("Service not found IRenderFrameworkCreator");
}
GraphicsDevice graphics = input.ResolveGraphicsDevice(); SurfaceFormat surfaceFormat = (SurfaceFormat)input.ReadInt32();
int surfaceFormat = input.ReadInt32();
int width = input.ReadInt32(); int width = input.ReadInt32();
int height = input.ReadInt32(); int height = input.ReadInt32();
int mipCount = input.ReadInt32(); int mipCount = input.ReadInt32();
SurfaceFormat sFormat = (SurfaceFormat)surfaceFormat;
List<byte> colorData = new List<byte>(); var texture2D = new Texture2D(input.ResolveGraphicsDevice(), width, height, mipCount, surfaceFormat);
for (int level = 0; level < mipCount; level++)
for (int i = 0; i < mipCount; i++) {
{
int size = input.ReadInt32(); int size = input.ReadInt32();
colorData.AddRange(input.ReadBytes(size)); byte[] data = input.ReadBytes(size);
} texture2D.SetData<byte>(level, null, data, 0, size);
}
Texture2D texture = new Texture2D(graphics, width, height, mipCount > 0, sFormat); return texture2D;
texture.SetData<byte>(colorData.ToArray());
return texture;
} }
} }
} }

View File

@ -73,14 +73,26 @@ namespace ANX.Framework.Graphics
CreateNativeTextureSurface(); CreateNativeTextureSurface();
} }
public Texture2D(GraphicsDevice graphicsDevice, int width, int height, public Texture2D(GraphicsDevice graphicsDevice, int width, int height, [MarshalAsAttribute(UnmanagedType.U1)] bool mipMap,
[MarshalAsAttribute(UnmanagedType.U1)] bool mipMap, SurfaceFormat format) SurfaceFormat format)
: base(graphicsDevice)
{
this.width = width;
this.height = height;
// TODO: pass the mipmap parameter to the creation of the texture to let the graphics card generate mipmaps!
base.levelCount = 1;
base.format = format;
CreateNativeTextureSurface();
}
internal Texture2D(GraphicsDevice graphicsDevice, int width, int height, int mipCount, SurfaceFormat format)
: base(graphicsDevice) : base(graphicsDevice)
{ {
this.width = width; this.width = width;
this.height = height; this.height = height;
base.levelCount = 1; //TODO: mipmap paramter?!?!? base.levelCount = mipCount;
base.format = format; base.format = format;
CreateNativeTextureSurface(); CreateNativeTextureSurface();

View File

@ -31,6 +31,8 @@ namespace ANX.Framework.NonXNA.Reflection
"System.Xml.Linq.dll", "System.Xml.Linq.dll",
"mscorlib.dll", "mscorlib.dll",
"Sce.PlayStation.Core.dll", "Sce.PlayStation.Core.dll",
"wrap_oal.dll",
"OpenAL32.dll",
}; };
#endregion #endregion
@ -70,9 +72,12 @@ namespace ANX.Framework.NonXNA.Reflection
LoadAssembliesFromFile(); LoadAssembliesFromFile();
LoadAssembliesFromNames(); LoadAssembliesFromNames();
#if !WINDOWSMETRO // TODO: find way for metro
// Also load the current assembly. This is needed when we run on android or win8 with merged assemblies. // Also load the current assembly. This is needed when we run on android or win8 with merged assemblies.
#if !WINDOWSMETRO
allAssemblies.Add(Assembly.GetEntryAssembly()); allAssemblies.Add(Assembly.GetEntryAssembly());
#else
// TODO: a lot of testing is required!
allAssemblies.Add(typeof(AssemblyLoader).GetTypeInfo().Assembly);
#endif #endif
} }
#endregion #endregion
@ -93,7 +98,7 @@ namespace ANX.Framework.NonXNA.Reflection
bool ignore = false; bool ignore = false;
foreach (string ignoreName in IgnoreAssemblies) foreach (string ignoreName in IgnoreAssemblies)
{ {
if (file.EndsWith(ignoreName)) if (file.EndsWith(ignoreName, StringComparison.InvariantCultureIgnoreCase))
{ {
ignore = true; ignore = true;
break; break;
@ -161,9 +166,7 @@ namespace ANX.Framework.NonXNA.Reflection
private static void SearchForValidAddInTypes() private static void SearchForValidAddInTypes()
{ {
foreach (Assembly assembly in allAssemblies) foreach (Assembly assembly in allAssemblies)
{
SearchForValidAddInTypesInAssembly(assembly); SearchForValidAddInTypesInAssembly(assembly);
}
} }
#endregion #endregion

View File

@ -1,6 +1,7 @@
#region Using Statements #region Using Statements
using System; using System;
using System.Diagnostics; using System.Diagnostics;
using ANX.Framework.NonXNA;
using ANX.Framework.NonXNA.PlatformSystem; using ANX.Framework.NonXNA.PlatformSystem;
#endregion #endregion

View File

@ -54,7 +54,7 @@ namespace ANX.BaseDirectX
return SharpDX.DXGI.Format.BC3_UNorm; return SharpDX.DXGI.Format.BC3_UNorm;
} }
throw new Exception("can't translate SurfaceFormat: " + surfaceFormat.ToString()); throw new Exception("Can't translate SurfaceFormat: " + surfaceFormat);
} }
#endregion #endregion

View File

@ -12,19 +12,13 @@ namespace ANX.BaseDirectX
public abstract class BaseTexture2D<S> : IDisposable where S : class, IDisposable public abstract class BaseTexture2D<S> : IDisposable where S : class, IDisposable
{ {
#region Private #region Private
protected int mipCount;
protected int tempSubresource; protected int tempSubresource;
protected int pitch; protected int pitch;
protected int formatSize; private int formatSize;
protected SurfaceFormat surfaceFormat; protected SurfaceFormat surfaceFormat;
protected bool useRenderTexture;
protected bool IsDxtTexture protected S NativeTextureStaging;
{
get
{
return surfaceFormat == SurfaceFormat.Dxt5 || surfaceFormat == SurfaceFormat.Dxt3 ||
surfaceFormat == SurfaceFormat.Dxt1;
}
}
#endregion #endregion
#region Public #region Public
@ -45,13 +39,10 @@ namespace ANX.BaseDirectX
#endregion #endregion
#region Constructor #region Constructor
protected BaseTexture2D(GraphicsDevice graphicsDevice) protected BaseTexture2D(GraphicsDevice graphicsDevice, SurfaceFormat setSurfaceFormat, int setMipCount)
{
GraphicsDevice = graphicsDevice;
}
protected BaseTexture2D(GraphicsDevice graphicsDevice, SurfaceFormat setSurfaceFormat)
{ {
mipCount = setMipCount;
useRenderTexture = mipCount > 1;
GraphicsDevice = graphicsDevice; GraphicsDevice = graphicsDevice;
surfaceFormat = setSurfaceFormat; surfaceFormat = setSurfaceFormat;
@ -78,94 +69,135 @@ namespace ANX.BaseDirectX
//TODO: handle offsetInBytes parameter //TODO: handle offsetInBytes parameter
//TODO: handle startIndex parameter //TODO: handle startIndex parameter
//TODO: handle elementCount parameter //TODO: handle elementCount parameter
if (surfaceFormat == SurfaceFormat.Color) unsafe
{ {
IntPtr dataPtr = MapWrite(); GCHandle handle = GCHandle.Alloc(data, GCHandleType.Pinned);
byte* colorData = (byte*)handle.AddrOfPinnedObject();
unsafe switch (surfaceFormat)
{ {
GCHandle handle = GCHandle.Alloc(data, GCHandleType.Pinned); case SurfaceFormat.Color:
byte* colorData = (byte*)handle.AddrOfPinnedObject(); SetDataColor(0, offsetInBytes, colorData, startIndex, elementCount);
return;
byte* pTexels = (byte*)dataPtr; case SurfaceFormat.Dxt1:
int srcIndex = 0; case SurfaceFormat.Dxt3:
case SurfaceFormat.Dxt5:
for (int row = 0; row < Height; row++) SetDataDxt(0, offsetInBytes, colorData, startIndex, elementCount, data.Length);
{ return;
int rowStart = row * pitch;
for (int col = 0; col < Width; col++)
{
int colStart = col * formatSize;
pTexels[rowStart + colStart + 0] = colorData[srcIndex++];
pTexels[rowStart + colStart + 1] = colorData[srcIndex++];
pTexels[rowStart + colStart + 2] = colorData[srcIndex++];
pTexels[rowStart + colStart + 3] = colorData[srcIndex++];
}
}
handle.Free();
} }
Unmap(); handle.Free();
} }
else if (IsDxtTexture)
throw new Exception(String.Format("creating textures of format {0} not yet implemented...", surfaceFormat));
}
#endregion
#region SetDataColor
private unsafe void SetDataColor(int level, int offsetInBytes, byte* colorData, int startIndex, int elementCount)
{
int mipmapWidth = Math.Max(Width >> level, 1);
int mipmapHeight = Math.Max(Height >> level, 1);
IntPtr dataPtr = MapWrite(level);
int srcIndex = 0;
byte* pTexels = (byte*)dataPtr;
for (int row = 0; row < mipmapHeight; row++)
{ {
unsafe int rowStart = row * pitch;
for (int col = 0; col < mipmapWidth; col++)
{ {
GCHandle handle = GCHandle.Alloc(data, GCHandleType.Pinned); int colStart = rowStart + (col * formatSize);
byte* colorData = (byte*)handle.AddrOfPinnedObject(); pTexels[colStart++] = colorData[srcIndex++];
pTexels[colStart++] = colorData[srcIndex++];
int w = (Width + 3) >> 2; pTexels[colStart++] = colorData[srcIndex++];
int h = (Height + 3) >> 2; pTexels[colStart++] = colorData[srcIndex++];
formatSize = (surfaceFormat == SurfaceFormat.Dxt1) ? 8 : 16;
IntPtr dataPtr = MapWrite();
var ds = new DataStream(dataPtr, Width * Height * 4 * 2, true, true);
int col = 0;
int index = 0; // startIndex
int count = data.Length; // elementCount
int actWidth = w * formatSize;
for (int i = 0; i < h; i++)
{
ds.Position = (i * pitch) + (col * formatSize);
if (count <= 0)
break;
else if (count < actWidth)
{
for (int idx = index; idx < index + count; idx++)
ds.WriteByte(colorData[idx]);
break;
}
for (int idx = index; idx < index + actWidth; idx++)
ds.WriteByte(colorData[idx]);
index += actWidth;
count -= actWidth;
}
handle.Free();
Unmap();
} }
} }
else
throw new Exception(String.Format("creating textures of format {0} not yet implemented...", surfaceFormat)); Unmap();
}
#endregion
#region SetDataDxt
private unsafe void SetDataDxt(int level, int offsetInBytes, byte* colorData, int startIndex, int elementCount,
int dataLength)
{
int mipmapWidth = Math.Max(Width >> level, 1);
int mipmapHeight = Math.Max(Height >> level, 1);
int w = (mipmapWidth + 3) >> 2;
int h = (mipmapHeight + 3) >> 2;
formatSize = (surfaceFormat == SurfaceFormat.Dxt1) ? 8 : 16;
IntPtr dataPtr = MapWrite(level);
var ds = new DataStream(dataPtr, mipmapWidth * mipmapHeight * 4 * 2, true, true);
int col = 0;
int index = 0; // startIndex
int count = dataLength; // elementCount
int actWidth = w * formatSize;
for (int i = 0; i < h; i++)
{
ds.Position = (i * pitch) + (col * formatSize);
if (count <= 0)
break;
else if (count < actWidth)
{
for (int idx = index; idx < index + count; idx++)
ds.WriteByte(colorData[idx]);
break;
}
for (int idx = index; idx < index + actWidth; idx++)
ds.WriteByte(colorData[idx]);
index += actWidth;
count -= actWidth;
}
Unmap();
} }
#endregion #endregion
#region SetData (TODO) #region SetData (TODO)
public void SetData<T>(int level, Framework.Rectangle? rect, T[] data, int startIndex, int elementCount) where T : struct public void SetData<T>(int level, Framework.Rectangle? rect, T[] data, int startIndex, int elementCount) where T : struct
{ {
throw new NotImplementedException(); //TODO: handle rect parameter
if (rect != null)
throw new Exception("Texture2D SetData with rectangle is not yet implemented!");
unsafe
{
GCHandle handle = GCHandle.Alloc(data, GCHandleType.Pinned);
byte* colorData = (byte*)handle.AddrOfPinnedObject();
switch (surfaceFormat)
{
case SurfaceFormat.Color:
SetDataColor(level, 0, colorData, startIndex, elementCount);
return;
case SurfaceFormat.Dxt1:
case SurfaceFormat.Dxt3:
case SurfaceFormat.Dxt5:
SetDataDxt(level, 0, colorData, startIndex, elementCount, data.Length);
return;
}
handle.Free();
}
throw new Exception(String.Format("creating textures of format {0} not yet implemented...", surfaceFormat));
} }
#endregion #endregion
protected abstract IntPtr MapWrite(); protected abstract IntPtr MapWrite(int level);
protected abstract IntPtr MapRead(); protected abstract IntPtr MapRead(int level);
protected abstract void Unmap(); protected abstract void Unmap();
#region Dispose #region Dispose

View File

@ -103,7 +103,7 @@
<Project>{6899F0C9-70B9-4EB0-9DD3-E598D4BE3E35}</Project> <Project>{6899F0C9-70B9-4EB0-9DD3-E598D4BE3E35}</Project>
<Name>ANX.Framework</Name> <Name>ANX.Framework</Name>
</ProjectReference> </ProjectReference>
<ProjectReference Include="..\ANX.BaseDirectX\ANX.BaseDirectX.csproj"> <ProjectReference Include="..\ANX.BaseDirectX\ANX.BaseDirectX_WindowsMetro.csproj">
<Project>{A4D3AD34-E49C-4142-8620-2AFF44ED6719}</Project> <Project>{A4D3AD34-E49C-4142-8620-2AFF44ED6719}</Project>
<Name>ANX.BaseDirectX</Name> <Name>ANX.BaseDirectX</Name>
</ProjectReference> </ProjectReference>

View File

@ -1,3 +1,4 @@
#define DIRECTX_DEBUG_LAYER
using System; using System;
using ANX.Framework; using ANX.Framework;
using ANX.Framework.Graphics; using ANX.Framework.Graphics;
@ -259,7 +260,10 @@ namespace ANX.RenderSystem.Windows.DX10
{ {
technique.GetPassByIndex(i).Apply(); technique.GetPassByIndex(i).Apply();
device.DrawIndexed(vertexCount, startIndex, baseVertex); device.DrawIndexed(vertexCount, startIndex, baseVertex);
} }
device.InputAssembler.InputLayout.Dispose();
device.InputAssembler.InputLayout = null;
} }
#endregion #endregion
@ -277,6 +281,9 @@ namespace ANX.RenderSystem.Windows.DX10
technique.GetPassByIndex(i).Apply(); technique.GetPassByIndex(i).Apply();
device.Draw(primitiveCount, vertexOffset); device.Draw(primitiveCount, vertexOffset);
} }
device.InputAssembler.InputLayout.Dispose();
device.InputAssembler.InputLayout = null;
} }
#endregion #endregion
@ -345,6 +352,9 @@ namespace ANX.RenderSystem.Windows.DX10
pass.Apply(); pass.Apply();
device.Draw(primitiveCount, vertexOffset); device.Draw(primitiveCount, vertexOffset);
} }
device.InputAssembler.InputLayout.Dispose();
device.InputAssembler.InputLayout = null;
} }
#endregion #endregion

View File

@ -36,17 +36,32 @@ namespace ANX.RenderSystem.Windows.DX10
#region Constructor #region Constructor
internal Texture2D_DX10(GraphicsDevice graphicsDevice, SurfaceFormat surfaceFormat) internal Texture2D_DX10(GraphicsDevice graphicsDevice, SurfaceFormat surfaceFormat)
: base(graphicsDevice, surfaceFormat) : base(graphicsDevice, surfaceFormat, 1)
{ {
} }
public Texture2D_DX10(GraphicsDevice graphicsDevice, int width, int height, SurfaceFormat surfaceFormat, int mipCount) public Texture2D_DX10(GraphicsDevice graphicsDevice, int width, int height, SurfaceFormat surfaceFormat, int mipCount)
: base(graphicsDevice, surfaceFormat) : base(graphicsDevice, surfaceFormat, mipCount)
{ {
if (mipCount > 1) Dx10.Device device = (graphicsDevice.NativeDevice as GraphicsDeviceWindowsDX10).NativeDevice;
throw new Exception("creating textures with mip map not yet implemented");
Dx10.Texture2DDescription description = new Dx10.Texture2DDescription() if (useRenderTexture)
{
var descriptionStaging = new Dx10.Texture2DDescription()
{
Width = width,
Height = height,
MipLevels = mipCount,
ArraySize = mipCount,
Format = BaseFormatConverter.Translate(surfaceFormat),
SampleDescription = new SharpDX.DXGI.SampleDescription(1, 0),
Usage = Dx10.ResourceUsage.Staging,
CpuAccessFlags = Dx10.CpuAccessFlags.Write,
};
NativeTextureStaging = new Dx10.Texture2D(device, descriptionStaging);
}
var description = new Dx10.Texture2DDescription()
{ {
Width = width, Width = width,
Height = height, Height = height,
@ -54,13 +69,12 @@ namespace ANX.RenderSystem.Windows.DX10
ArraySize = mipCount, ArraySize = mipCount,
Format = BaseFormatConverter.Translate(surfaceFormat), Format = BaseFormatConverter.Translate(surfaceFormat),
SampleDescription = new SharpDX.DXGI.SampleDescription(1, 0), SampleDescription = new SharpDX.DXGI.SampleDescription(1, 0),
Usage = Dx10.ResourceUsage.Dynamic, Usage = useRenderTexture ? Dx10.ResourceUsage.Default : Dx10.ResourceUsage.Dynamic,
BindFlags = Dx10.BindFlags.ShaderResource, BindFlags = Dx10.BindFlags.ShaderResource,
CpuAccessFlags = Dx10.CpuAccessFlags.Write, CpuAccessFlags = useRenderTexture ? Dx10.CpuAccessFlags.None : Dx10.CpuAccessFlags.Write,
OptionFlags = Dx10.ResourceOptionFlags.None, OptionFlags = Dx10.ResourceOptionFlags.None,
}; };
Dx10.Device device = (graphicsDevice.NativeDevice as GraphicsDeviceWindowsDX10).NativeDevice;
NativeTexture = new Dx10.Texture2D(device, description); NativeTexture = new Dx10.Texture2D(device, description);
NativeShaderResourceView = new Dx10.ShaderResourceView(device, NativeTexture); NativeShaderResourceView = new Dx10.ShaderResourceView(device, NativeTexture);
} }
@ -89,14 +103,16 @@ namespace ANX.RenderSystem.Windows.DX10
#region SaveAsJpeg (TODO) #region SaveAsJpeg (TODO)
public void SaveAsJpeg(Stream stream, int width, int height) public void SaveAsJpeg(Stream stream, int width, int height)
{ {
throw new NotImplementedException(); // TODO: handle width and height?
Dx10.Texture2D.ToStream(NativeTexture, Dx10.ImageFileFormat.Jpg, stream);
} }
#endregion #endregion
#region SaveAsPng (TODO) #region SaveAsPng (TODO)
public void SaveAsPng(Stream stream, int width, int height) public void SaveAsPng(Stream stream, int width, int height)
{ {
throw new NotImplementedException(); // TODO: handle width and height?
Dx10.Texture2D.ToStream(NativeTexture, Dx10.ImageFileFormat.Png, stream);
} }
#endregion #endregion
@ -118,20 +134,23 @@ namespace ANX.RenderSystem.Windows.DX10
#endregion #endregion
#region MapWrite #region MapWrite
protected override IntPtr MapWrite() protected override IntPtr MapWrite(int level)
{ {
tempSubresource = Dx10.Texture2D.CalculateSubResourceIndex(0, 0, 1); tempSubresource = Dx10.Texture2D.CalculateSubResourceIndex(level, 0, mipCount);
DataRectangle rect = NativeTexture.Map(tempSubresource, Dx10.MapMode.WriteDiscard, Dx10.MapFlags.None); var texture = useRenderTexture ? NativeTextureStaging : NativeTexture;
DataRectangle rect = texture.Map(tempSubresource, useRenderTexture ? Dx10.MapMode.Write : Dx10.MapMode.WriteDiscard,
Dx10.MapFlags.None);
pitch = rect.Pitch; pitch = rect.Pitch;
return rect.DataPointer; return rect.DataPointer;
} }
#endregion #endregion
#region MapRead #region MapRead
protected override IntPtr MapRead() protected override IntPtr MapRead(int level)
{ {
tempSubresource = Dx10.Texture2D.CalculateSubResourceIndex(0, 0, 1); tempSubresource = Dx10.Texture2D.CalculateSubResourceIndex(level, 0, mipCount);
DataRectangle rect = NativeTexture.Map(tempSubresource, Dx10.MapMode.Read, Dx10.MapFlags.None); var texture = useRenderTexture ? NativeTextureStaging : NativeTexture;
DataRectangle rect = texture.Map(tempSubresource, Dx10.MapMode.Read, Dx10.MapFlags.None);
pitch = rect.Pitch; pitch = rect.Pitch;
return rect.DataPointer; return rect.DataPointer;
} }
@ -140,7 +159,10 @@ namespace ANX.RenderSystem.Windows.DX10
#region Unmap #region Unmap
protected override void Unmap() protected override void Unmap()
{ {
NativeTexture.Unmap(tempSubresource); var texture = useRenderTexture ? NativeTextureStaging : NativeTexture;
texture.Unmap(tempSubresource);
if (useRenderTexture)
texture.Device.CopyResource(NativeTextureStaging, NativeTexture);
} }
#endregion #endregion
} }

View File

@ -1,11 +1,11 @@
using System; using System;
using System.IO; using System.IO;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using ANX.Framework;
using ANX.Framework.Graphics; using ANX.Framework.Graphics;
using ANX.Framework.NonXNA.RenderSystem; using ANX.Framework.NonXNA.RenderSystem;
using OpenTK.Graphics.OpenGL;
using ANX.Framework;
using ANX.RenderSystem.Windows.GL3.Helpers; using ANX.RenderSystem.Windows.GL3.Helpers;
using OpenTK.Graphics.OpenGL;
// This file is part of the ANX.Framework created by the // This file is part of the ANX.Framework created by the
// "ANX.Framework developer group" and released under the Ms-PL license. // "ANX.Framework developer group" and released under the Ms-PL license.
@ -13,58 +13,27 @@ using ANX.RenderSystem.Windows.GL3.Helpers;
namespace ANX.RenderSystem.Windows.GL3 namespace ANX.RenderSystem.Windows.GL3
{ {
/// <summary>
/// Native OpenGL Texture implementation.
/// </summary>
public class Texture2DGL3 : INativeTexture2D public class Texture2DGL3 : INativeTexture2D
{ {
#region Private #region Private
/// <summary>
/// The native OpenGL pixel format of the texture.
/// </summary>
private PixelInternalFormat nativeFormat; private PixelInternalFormat nativeFormat;
/// <summary> /// <summary>
/// The number of mipmaps used by this texture [1-n]. /// [1-n]
/// </summary> /// </summary>
private int numberOfMipMaps; private int numberOfMipMaps;
/// <summary>
/// Width of the texture.
/// </summary>
private int width; private int width;
/// <summary>
/// Height of the texture.
/// </summary>
private int height; private int height;
/// <summary>
/// Flag if the texture is a compressed format or not.
/// </summary>
private bool isCompressed; private bool isCompressed;
internal bool IsDisposed; internal bool IsDisposed;
private int uncompressedDataSize; private int uncompressedDataSize;
private byte[] texData; private byte[] texData;
/// <summary>
/// TODO: find better solution
/// </summary>
private int maxSetDataSize; private int maxSetDataSize;
#endregion #endregion
#region Public #region Public
/// <summary> protected internal int NativeHandle { get; protected set; }
/// The OpenGL texture handle.
/// </summary>
protected internal int NativeHandle
{
get;
protected set;
}
#endregion #endregion
#region Constructor #region Constructor
@ -73,15 +42,7 @@ namespace ANX.RenderSystem.Windows.GL3
GraphicsResourceManager.UpdateResource(this, true); GraphicsResourceManager.UpdateResource(this, true);
} }
/// <summary> internal Texture2DGL3(SurfaceFormat surfaceFormat, int setWidth, int setHeight, int mipCount)
/// Create a new native OpenGL texture.
/// </summary>
/// <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)
{ {
GraphicsResourceManager.UpdateResource(this, true); GraphicsResourceManager.UpdateResource(this, true);
@ -106,27 +67,15 @@ namespace ANX.RenderSystem.Windows.GL3
private void CreateTexture() private void CreateTexture()
{ {
NativeHandle = GL.GenTexture(); NativeHandle = GL.GenTexture();
#if DEBUG
ErrorHelper.Check("GenTexture");
#endif
GL.BindTexture(TextureTarget.Texture2D, NativeHandle); GL.BindTexture(TextureTarget.Texture2D, NativeHandle);
#if DEBUG
ErrorHelper.Check("BindTexture");
#endif
int wrapMode = (int)All.ClampToEdge; int wrapMode = (int)All.ClampToEdge;
int filter = (int)(numberOfMipMaps > 1 ? All minFilter = numberOfMipMaps > 1 ? All.LinearMipmapLinear : All.Linear;
All.LinearMipmapLinear :
All.Linear);
GL.TexParameter(TextureTarget.Texture2D, GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, wrapMode);
TextureParameterName.TextureWrapS, wrapMode); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, wrapMode);
GL.TexParameter(TextureTarget.Texture2D, GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)All.Linear);
TextureParameterName.TextureWrapT, wrapMode); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)minFilter);
GL.TexParameter(TextureTarget.Texture2D,
TextureParameterName.TextureMagFilter, filter);
GL.TexParameter(TextureTarget.Texture2D,
TextureParameterName.TextureMinFilter, filter);
#if DEBUG #if DEBUG
ErrorHelper.Check("TexParameter"); ErrorHelper.Check("TexParameter");
#endif #endif
@ -135,102 +84,87 @@ namespace ANX.RenderSystem.Windows.GL3
// TODO: offsetInBytes // TODO: offsetInBytes
// TODO: elementCount // TODO: elementCount
// TODO: get size of first mipmap!
#region SetData #region SetData
public void SetData<T>(GraphicsDevice graphicsDevice, T[] data) public void SetData<T>(GraphicsDevice graphicsDevice, T[] data) where T : struct
where T : struct
{ {
SetData<T>(graphicsDevice, 0, data, 0, data.Length); SetData<T>(graphicsDevice, 0, data, 0, data.Length);
} }
public void SetData<T>(GraphicsDevice graphicsDevice, T[] data, public void SetData<T>(GraphicsDevice graphicsDevice, T[] data, int startIndex, int elementCount) where T : struct
int startIndex, int elementCount) where T : struct
{ {
SetData<T>(graphicsDevice, 0, data, 0, data.Length); SetData<T>(graphicsDevice, 0, data, 0, data.Length);
} }
public void SetData<T>(int level, Rectangle? rect, T[] data, int startIndex, public void SetData<T>(int level, Rectangle? rect, T[] data, int startIndex, int elementCount) where T : struct
int elementCount) where T : struct
{ {
throw new NotImplementedException(); int size = Marshal.SizeOf(typeof(T)) * data.Length;
} if (size > maxSetDataSize)
maxSetDataSize = size;
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!");
}
GL.BindTexture(TextureTarget.Texture2D, NativeHandle); GL.BindTexture(TextureTarget.Texture2D, NativeHandle);
#if DEBUG
ErrorHelper.Check("BindTexture");
#endif
if (data.Length > maxSetDataSize)
{
maxSetDataSize = data.Length;
}
GCHandle handle = GCHandle.Alloc(data, GCHandleType.Pinned); GCHandle handle = GCHandle.Alloc(data, GCHandleType.Pinned);
// TODO: get size of first mipmap!
int mipmapByteSize = data.Length;
try try
{ {
IntPtr dataPointer = handle.AddrOfPinnedObject(); IntPtr dataPointer = handle.AddrOfPinnedObject();
// Go to the starting point. // Go to the starting point.
dataPointer += startIndex; dataPointer += startIndex;
int mipmapWidth = Math.Max(width >> level, 1);
int mipmapHeight = Math.Max(height >> level, 1);
if (isCompressed) if (isCompressed)
{ {
GL.CompressedTexImage2D(TextureTarget.Texture2D, 0, nativeFormat, GL.CompressedTexImage2D(TextureTarget.Texture2D, level, nativeFormat, width, height, 0, data.Length,
width, height, 0, mipmapByteSize, dataPointer); dataPointer);
#if DEBUG #if DEBUG
ErrorHelper.Check("CompressedTexImage2D Format=" + nativeFormat); ErrorHelper.Check("CompressedTexImage2D Format=" + nativeFormat);
#endif #endif
} }
else else
{ {
GL.TexImage2D(TextureTarget.Texture2D, 0, nativeFormat, GL.TexImage2D(TextureTarget.Texture2D, level, nativeFormat, mipmapWidth, mipmapHeight, 0,
width, height, 0, (PixelFormat)nativeFormat, (PixelFormat)nativeFormat, PixelType.UnsignedByte, dataPointer);
PixelType.UnsignedByte, dataPointer);
#if DEBUG #if DEBUG
ErrorHelper.Check("TexImage2D Format=" + nativeFormat); ErrorHelper.Check("TexImage2D Format=" + nativeFormat);
#endif #endif
} }
}
finally
{
handle.Free();
}
}
int mipmapWidth = width; public void SetData<T>(GraphicsDevice graphicsDevice, int offsetInBytes, T[] data, int startIndex, int elementCount)
int mipmapHeight = height; where T : struct
for (int index = 1; index < numberOfMipMaps; index++) {
int size = Marshal.SizeOf(typeof(T)) * data.Length;
if (size > maxSetDataSize)
maxSetDataSize = size;
GL.BindTexture(TextureTarget.Texture2D, NativeHandle);
GCHandle handle = GCHandle.Alloc(data, GCHandleType.Pinned);
try
{
IntPtr dataPointer = handle.AddrOfPinnedObject();
dataPointer += startIndex;
if (isCompressed)
{ {
dataPointer += mipmapByteSize; GL.CompressedTexImage2D(TextureTarget.Texture2D, 0, nativeFormat, width, height, 0, data.Length, dataPointer);
mipmapByteSize /= 4;
mipmapWidth /= 2;
mipmapHeight /= 2;
mipmapWidth = Math.Max(mipmapWidth, 1);
mipmapHeight = Math.Max(mipmapHeight, 1);
if (isCompressed)
{
GL.CompressedTexImage2D(TextureTarget.Texture2D, index,
nativeFormat, width, height, 0, mipmapByteSize, dataPointer);
#if DEBUG #if DEBUG
ErrorHelper.Check("CompressedTexImage2D Format=" + nativeFormat); ErrorHelper.Check("CompressedTexImage2D Format=" + nativeFormat);
#endif #endif
} }
else else
{ {
GL.TexImage2D(TextureTarget.Texture2D, index, nativeFormat, GL.TexImage2D(TextureTarget.Texture2D, 0, nativeFormat, width, height, 0, (PixelFormat)nativeFormat,
mipmapWidth, mipmapHeight, 0, (PixelFormat)nativeFormat, PixelType.UnsignedByte, dataPointer);
PixelType.UnsignedByte, dataPointer);
#if DEBUG #if DEBUG
ErrorHelper.Check("TexImage2D Format=" + nativeFormat); ErrorHelper.Check("TexImage2D Format=" + nativeFormat);
#endif #endif
}
} }
} }
finally finally
@ -240,81 +174,42 @@ namespace ANX.RenderSystem.Windows.GL3
} }
#endregion #endregion
// TODO: compressed texture, what about elementCount?
#region GetData (TODO) #region GetData (TODO)
public void GetData<T>(int level, Rectangle? rect, T[] data, int startIndex, public void GetData<T>(int level, Rectangle? rect, T[] data, int startIndex, int elementCount) where T : struct
int elementCount) where T : struct
{ {
throw new NotImplementedException(); throw new NotImplementedException();
} }
#endregion #endregion
// TODO: compressed texture (see: http://www.bearisgaming.com/texture2d-getdata-and-dxt-compression/)
#region GetData #region GetData
public void GetData<T>(T[] data) where T : struct public void GetData<T>(T[] data) where T : struct
{ {
if (isCompressed) GetData(data, 0, data.Length);
{
throw new NotImplementedException(
"GetData is currently not implemented for compressed texture " +
"formats! Format is " + nativeFormat + ".");
}
if (data == null)
{
throw new ArgumentNullException("data");
}
int size = Marshal.SizeOf(typeof(T)) * data.Length;
if (size != uncompressedDataSize)
{
throw new InvalidDataException(
"The size of the data passed in is too large or too small " +
"for this resource.");
}
GCHandle handle = GCHandle.Alloc(data, GCHandleType.Pinned);
GL.GetTexImage(TextureTarget.Texture2D, 0, (PixelFormat)nativeFormat,
PixelType.UnsignedByte, handle.AddrOfPinnedObject());
handle.Free();
} }
#endregion #endregion
// TODO: compressed texture, what about elementCount? // TODO: compressed texture (see: http://www.bearisgaming.com/texture2d-getdata-and-dxt-compression/)
// TODO: elementCount
#region GetData #region GetData
public void GetData<T>(T[] data, int startIndex, int elementCount) public void GetData<T>(T[] data, int startIndex, int elementCount) where T : struct
where T : struct
{ {
if (isCompressed) if (isCompressed)
{ throw new NotImplementedException("GetData is currently not implemented for compressed texture format " +
throw new NotImplementedException( nativeFormat + ".");
"GetData is currently not implemented for compressed texture " +
"formats! Format is " + nativeFormat + ".");
}
if (data == null) if (data == null)
{
throw new ArgumentNullException("data"); throw new ArgumentNullException("data");
}
int size = Marshal.SizeOf(typeof(T)) * data.Length; int size = Marshal.SizeOf(typeof(T)) * data.Length;
if (size < uncompressedDataSize) if (size < uncompressedDataSize)
{ throw new InvalidDataException("The size of the data passed in is too large or too small for this resource.");
throw new InvalidDataException(
"The size of the data passed in is too large or too small " +
"for this resource.");
}
GCHandle handle = GCHandle.Alloc(data, GCHandleType.Pinned); GCHandle handle = GCHandle.Alloc(data, GCHandleType.Pinned);
IntPtr ptr = handle.AddrOfPinnedObject(); IntPtr ptr = handle.AddrOfPinnedObject();
ptr += startIndex; ptr += startIndex;
GL.GetTexImage(TextureTarget.Texture2D, 0, (PixelFormat)nativeFormat, GL.GetTexImage(TextureTarget.Texture2D, 0, (PixelFormat)nativeFormat, PixelType.UnsignedByte, ptr);
PixelType.UnsignedByte, ptr);
handle.Free(); handle.Free();
} }
@ -330,8 +225,7 @@ namespace ANX.RenderSystem.Windows.GL3
texData = new byte[maxSetDataSize]; texData = new byte[maxSetDataSize];
GCHandle handle = GCHandle.Alloc(texData, GCHandleType.Pinned); GCHandle handle = GCHandle.Alloc(texData, GCHandleType.Pinned);
GL.GetCompressedTexImage(TextureTarget.Texture2D, 0, GL.GetCompressedTexImage(TextureTarget.Texture2D, 0, handle.AddrOfPinnedObject());
handle.AddrOfPinnedObject());
handle.Free(); handle.Free();
} }
@ -340,8 +234,8 @@ namespace ANX.RenderSystem.Windows.GL3
texData = new byte[uncompressedDataSize]; texData = new byte[uncompressedDataSize];
GCHandle handle = GCHandle.Alloc(texData, GCHandleType.Pinned); GCHandle handle = GCHandle.Alloc(texData, GCHandleType.Pinned);
GL.GetTexImage(TextureTarget.Texture2D, 0, (PixelFormat)nativeFormat, GL.GetTexImage(TextureTarget.Texture2D, 0, (PixelFormat)nativeFormat, PixelType.UnsignedByte,
PixelType.UnsignedByte, handle.AddrOfPinnedObject()); handle.AddrOfPinnedObject());
handle.Free(); handle.Free();
} }

View File

@ -64,7 +64,7 @@
<Project>{6899F0C9-70B9-4EB0-9DD3-E598D4BE3E35}</Project> <Project>{6899F0C9-70B9-4EB0-9DD3-E598D4BE3E35}</Project>
<Name>ANX.Framework</Name> <Name>ANX.Framework</Name>
</ProjectReference> </ProjectReference>
<ProjectReference Include="..\ANX.BaseDirectX\ANX.BaseDirectX.csproj"> <ProjectReference Include="..\ANX.BaseDirectX\ANX.BaseDirectX_WindowsMetro.csproj">
<Project>{A4D3AD34-E49C-4142-8620-2AFF44ED6719}</Project> <Project>{A4D3AD34-E49C-4142-8620-2AFF44ED6719}</Project>
<Name>ANX.BaseDirectX</Name> <Name>ANX.BaseDirectX</Name>
</ProjectReference> </ProjectReference>

View File

@ -1,3 +1,4 @@
#define DIRECTX_DEBUG_LAYER
using System; using System;
using ANX.Framework; using ANX.Framework;
using ANX.Framework.Graphics; using ANX.Framework.Graphics;
@ -243,48 +244,54 @@ namespace ANX.RenderSystem.Windows.DX11
#endregion #endregion
#region DrawPrimitives & DrawIndexedPrimitives #region DrawPrimitives & DrawIndexedPrimitives
public void DrawIndexedPrimitives(PrimitiveType primitiveType, int baseVertex, int minVertexIndex, public void DrawIndexedPrimitives(PrimitiveType primitiveType, int baseVertex, int minVertexIndex,
int numVertices, int startIndex, int primitiveCount) int numVertices, int startIndex, int primitiveCount)
{ {
SharpDX.Direct3D11.EffectPass pass; SharpDX.Direct3D11.EffectPass pass;
SharpDX.Direct3D11.EffectTechnique technique; SharpDX.Direct3D11.EffectTechnique technique;
ShaderBytecode passSignature; ShaderBytecode passSignature;
SetupEffectForDraw(out pass, out technique, out passSignature); SetupEffectForDraw(out pass, out technique, out passSignature);
SetupInputLayout(passSignature); var layout = SetupInputLayout(passSignature);
// Prepare All the stages // Prepare All the stages
deviceContext.InputAssembler.PrimitiveTopology = BaseFormatConverter.Translate(primitiveType); deviceContext.InputAssembler.PrimitiveTopology = BaseFormatConverter.Translate(primitiveType);
deviceContext.Rasterizer.SetViewports(currentViewport); deviceContext.Rasterizer.SetViewports(currentViewport);
deviceContext.OutputMerger.SetTargets(this.depthStencilView, this.renderView); deviceContext.OutputMerger.SetTargets(this.depthStencilView, this.renderView);
for (int i = 0; i < technique.Description.PassCount; ++i) for (int i = 0; i < technique.Description.PassCount; ++i)
{ {
pass.Apply(deviceContext); pass.Apply(deviceContext);
deviceContext.DrawIndexed(BaseFormatConverter.CalculateVertexCount(primitiveType, primitiveCount), startIndex, baseVertex); deviceContext.DrawIndexed(BaseFormatConverter.CalculateVertexCount(primitiveType, primitiveCount), startIndex, baseVertex);
} }
}
public void DrawPrimitives(PrimitiveType primitiveType, int vertexOffset, int primitiveCount) layout.Dispose();
{ layout = null;
SharpDX.Direct3D11.EffectPass pass; SharpDX.Direct3D11.EffectTechnique technique; ShaderBytecode passSignature; }
SetupEffectForDraw(out pass, out technique, out passSignature);
SetupInputLayout(passSignature); public void DrawPrimitives(PrimitiveType primitiveType, int vertexOffset, int primitiveCount)
{
SharpDX.Direct3D11.EffectPass pass; SharpDX.Direct3D11.EffectTechnique technique; ShaderBytecode passSignature;
SetupEffectForDraw(out pass, out technique, out passSignature);
// Prepare All the stages var layout = SetupInputLayout(passSignature);
// Prepare All the stages
deviceContext.InputAssembler.PrimitiveTopology = BaseFormatConverter.Translate(primitiveType); deviceContext.InputAssembler.PrimitiveTopology = BaseFormatConverter.Translate(primitiveType);
deviceContext.Rasterizer.SetViewports(currentViewport); deviceContext.Rasterizer.SetViewports(currentViewport);
deviceContext.OutputMerger.SetTargets(this.depthStencilView, this.renderView); deviceContext.OutputMerger.SetTargets(this.depthStencilView, this.renderView);
for (int i = 0; i < technique.Description.PassCount; ++i) for (int i = 0; i < technique.Description.PassCount; ++i)
{ {
pass.Apply(deviceContext); pass.Apply(deviceContext);
deviceContext.Draw(primitiveCount, vertexOffset); deviceContext.Draw(primitiveCount, vertexOffset);
} }
}
layout.Dispose();
layout = null;
}
#endregion // DrawPrimitives & DrawIndexedPrimitives #endregion // DrawPrimitives & DrawIndexedPrimitives
@ -297,26 +304,25 @@ namespace ANX.RenderSystem.Windows.DX11
#endregion // DrawInstancedPrimitives #endregion // DrawInstancedPrimitives
#region DrawUserIndexedPrimitives<T> #region DrawUserIndexedPrimitives<T>
public void DrawUserIndexedPrimitives<T>(PrimitiveType primitiveType, T[] vertexData, int vertexOffset, int numVertices, Array indexData, int indexOffset, int primitiveCount, VertexDeclaration vertexDeclaration, IndexElementSize indexFormat) where T : struct, IVertexType public void DrawUserIndexedPrimitives<T>(PrimitiveType primitiveType, T[] vertexData, int vertexOffset, int numVertices,
Array indexData, int indexOffset, int primitiveCount, VertexDeclaration vertexDeclaration,
IndexElementSize indexFormat) where T : struct, IVertexType
{ {
int vertexCount = vertexData.Length; int vertexCount = vertexData.Length;
int indexCount = indexData.Length; int indexCount = indexData.Length;
VertexBuffer_DX11 vb11 = new VertexBuffer_DX11(this.deviceContext.Device, vertexDeclaration, vertexCount, BufferUsage.None); var vb11 = new VertexBuffer_DX11(this.deviceContext.Device, vertexDeclaration, vertexCount, BufferUsage.None);
vb11.SetData<T>(null, vertexData); vb11.SetData<T>(null, vertexData);
SharpDX.Direct3D11.VertexBufferBinding nativeVertexBufferBindings = new SharpDX.Direct3D11.VertexBufferBinding(vb11.NativeBuffer, vertexDeclaration.VertexStride, 0); var nativeVertexBufferBindings = new SharpDX.Direct3D11.VertexBufferBinding(vb11.NativeBuffer,
vertexDeclaration.VertexStride, 0);
deviceContext.InputAssembler.SetVertexBuffers(0, nativeVertexBufferBindings); deviceContext.InputAssembler.SetVertexBuffers(0, nativeVertexBufferBindings);
IndexBuffer_DX11 idx10 = new IndexBuffer_DX11(this.deviceContext.Device, indexFormat, indexCount, BufferUsage.None); IndexBuffer_DX11 idx10 = new IndexBuffer_DX11(this.deviceContext.Device, indexFormat, indexCount, BufferUsage.None);
if (indexData.GetType() == typeof(Int16[])) if (indexData.GetType() == typeof(Int16[]))
{
idx10.SetData<short>(null, (short[])indexData); idx10.SetData<short>(null, (short[])indexData);
}
else else
{
idx10.SetData<int>(null, (int[])indexData); idx10.SetData<int>(null, (int[])indexData);
}
DrawIndexedPrimitives(primitiveType, 0, vertexOffset, numVertices, indexOffset, primitiveCount); DrawIndexedPrimitives(primitiveType, 0, vertexOffset, numVertices, indexOffset, primitiveCount);
} }
@ -350,7 +356,10 @@ namespace ANX.RenderSystem.Windows.DX11
{ {
pass.Apply(deviceContext); pass.Apply(deviceContext);
deviceContext.Draw(primitiveCount, vertexOffset); deviceContext.Draw(primitiveCount, vertexOffset);
} }
layout.Dispose();
layout = null;
} }
#endregion // DrawUserPrimitives<T> #endregion // DrawUserPrimitives<T>
@ -369,7 +378,7 @@ namespace ANX.RenderSystem.Windows.DX11
passSignature = pass.Description.Signature; passSignature = pass.Description.Signature;
} }
private void SetupInputLayout(ShaderBytecode passSignature) private InputLayout SetupInputLayout(ShaderBytecode passSignature)
{ {
// get the VertexDeclaration from current VertexBuffer to create input layout for the input assembler // get the VertexDeclaration from current VertexBuffer to create input layout for the input assembler
//TODO: check for null and throw exception //TODO: check for null and throw exception
@ -377,6 +386,7 @@ namespace ANX.RenderSystem.Windows.DX11
var layout = CreateInputLayout(deviceContext.Device, passSignature, vertexDeclaration); var layout = CreateInputLayout(deviceContext.Device, passSignature, vertexDeclaration);
deviceContext.InputAssembler.InputLayout = layout; deviceContext.InputAssembler.InputLayout = layout;
return layout;
} }
public void SetIndexBuffer(IndexBuffer indexBuffer) public void SetIndexBuffer(IndexBuffer indexBuffer)

View File

@ -36,16 +36,32 @@ namespace ANX.RenderSystem.Windows.DX11
#region Constructor #region Constructor
internal Texture2D_DX11(GraphicsDevice graphicsDevice, SurfaceFormat surfaceFormat) internal Texture2D_DX11(GraphicsDevice graphicsDevice, SurfaceFormat surfaceFormat)
: base(graphicsDevice, surfaceFormat) : base(graphicsDevice, surfaceFormat, 1)
{ {
} }
public Texture2D_DX11(GraphicsDevice graphicsDevice, int width, int height, SurfaceFormat surfaceFormat, int mipCount) public Texture2D_DX11(GraphicsDevice graphicsDevice, int width, int height, SurfaceFormat surfaceFormat, int mipCount)
: base(graphicsDevice, surfaceFormat) : base(graphicsDevice, surfaceFormat, mipCount)
{ {
if (mipCount > 1) Dx11.Device device = (graphicsDevice.NativeDevice as GraphicsDeviceWindowsDX11).NativeDevice.Device;
throw new Exception("creating textures with mip map not yet implemented"); var sampleDescription = new SharpDX.DXGI.SampleDescription(1, 0);
if (useRenderTexture)
{
var descriptionStaging = new Dx11.Texture2DDescription()
{
Width = width,
Height = height,
MipLevels = mipCount,
ArraySize = mipCount,
Format = BaseFormatConverter.Translate(surfaceFormat),
SampleDescription = sampleDescription,
Usage = Dx11.ResourceUsage.Staging,
CpuAccessFlags = Dx11.CpuAccessFlags.Write,
};
NativeTextureStaging = new Dx11.Texture2D(device, descriptionStaging);
}
var description = new Dx11.Texture2DDescription() var description = new Dx11.Texture2DDescription()
{ {
Width = width, Width = width,
@ -53,16 +69,14 @@ namespace ANX.RenderSystem.Windows.DX11
MipLevels = mipCount, MipLevels = mipCount,
ArraySize = mipCount, ArraySize = mipCount,
Format = BaseFormatConverter.Translate(surfaceFormat), Format = BaseFormatConverter.Translate(surfaceFormat),
SampleDescription = new SharpDX.DXGI.SampleDescription(1, 0), SampleDescription = sampleDescription,
Usage = Dx11.ResourceUsage.Dynamic, Usage = useRenderTexture ? Dx11.ResourceUsage.Default : Dx11.ResourceUsage.Dynamic,
BindFlags = Dx11.BindFlags.ShaderResource, BindFlags = Dx11.BindFlags.ShaderResource,
CpuAccessFlags = Dx11.CpuAccessFlags.Write, CpuAccessFlags = useRenderTexture ? Dx11.CpuAccessFlags.None : Dx11.CpuAccessFlags.Write,
OptionFlags = Dx11.ResourceOptionFlags.None,
}; };
Dx11.DeviceContext context = (graphicsDevice.NativeDevice as GraphicsDeviceWindowsDX11).NativeDevice; NativeTexture = new Dx11.Texture2D(device, description);
NativeTexture = new Dx11.Texture2D(context.Device, description); NativeShaderResourceView = new Dx11.ShaderResourceView(device, NativeTexture);
NativeShaderResourceView = new Dx11.ShaderResourceView(context.Device, NativeTexture);
} }
#endregion #endregion
@ -82,6 +96,12 @@ namespace ANX.RenderSystem.Windows.DX11
NativeShaderResourceView = null; NativeShaderResourceView = null;
} }
if (NativeTextureStaging != null)
{
NativeTextureStaging.Dispose();
NativeTextureStaging = null;
}
base.Dispose(); base.Dispose();
} }
#endregion #endregion
@ -89,14 +109,16 @@ namespace ANX.RenderSystem.Windows.DX11
#region SaveAsJpeg (TODO) #region SaveAsJpeg (TODO)
public void SaveAsJpeg(Stream stream, int width, int height) public void SaveAsJpeg(Stream stream, int width, int height)
{ {
throw new NotImplementedException(); // TODO: handle width and height?
Dx11.Texture2D.ToStream(NativeTexture.Device.ImmediateContext, NativeTexture, Dx11.ImageFileFormat.Jpg, stream);
} }
#endregion #endregion
#region SaveAsPng (TODO) #region SaveAsPng (TODO)
public void SaveAsPng(Stream stream, int width, int height) public void SaveAsPng(Stream stream, int width, int height)
{ {
throw new NotImplementedException(); // TODO: handle width and height?
Dx11.Texture2D.ToStream(NativeTexture.Device.ImmediateContext, NativeTexture, Dx11.ImageFileFormat.Png, stream);
} }
#endregion #endregion
@ -118,22 +140,25 @@ namespace ANX.RenderSystem.Windows.DX11
#endregion #endregion
#region MapWrite #region MapWrite
protected override IntPtr MapWrite() protected override IntPtr MapWrite(int level)
{ {
Dx11.DeviceContext context = (GraphicsDevice.NativeDevice as GraphicsDeviceWindowsDX11).NativeDevice; Dx11.DeviceContext context = (GraphicsDevice.NativeDevice as GraphicsDeviceWindowsDX11).NativeDevice;
tempSubresource = Dx11.Texture2D.CalculateSubResourceIndex(0, 0, 1); tempSubresource = Dx11.Texture2D.CalculateSubResourceIndex(level, 0, mipCount);
DataBox box = context.MapSubresource(NativeTexture, tempSubresource, Dx11.MapMode.WriteDiscard, Dx11.MapFlags.None); var texture = useRenderTexture ? NativeTextureStaging : NativeTexture;
DataBox box = context.MapSubresource(texture, tempSubresource,
useRenderTexture ? Dx11.MapMode.Write : Dx11.MapMode.WriteDiscard, Dx11.MapFlags.None);
pitch = box.RowPitch; pitch = box.RowPitch;
return box.DataPointer; return box.DataPointer;
} }
#endregion #endregion
#region MapRead #region MapRead
protected override IntPtr MapRead() protected override IntPtr MapRead(int level)
{ {
Dx11.DeviceContext context = (GraphicsDevice.NativeDevice as GraphicsDeviceWindowsDX11).NativeDevice; Dx11.DeviceContext context = (GraphicsDevice.NativeDevice as GraphicsDeviceWindowsDX11).NativeDevice;
tempSubresource = Dx11.Texture2D.CalculateSubResourceIndex(0, 0, 1); tempSubresource = Dx11.Texture2D.CalculateSubResourceIndex(level, 0, mipCount);
DataBox box = context.MapSubresource(NativeTexture, tempSubresource, Dx11.MapMode.Read, Dx11.MapFlags.None); var texture = useRenderTexture ? NativeTextureStaging : NativeTexture;
DataBox box = context.MapSubresource(texture, tempSubresource, Dx11.MapMode.Read, Dx11.MapFlags.None);
pitch = box.RowPitch; pitch = box.RowPitch;
return box.DataPointer; return box.DataPointer;
} }
@ -143,7 +168,11 @@ namespace ANX.RenderSystem.Windows.DX11
protected override void Unmap() protected override void Unmap()
{ {
Dx11.DeviceContext context = (GraphicsDevice.NativeDevice as GraphicsDeviceWindowsDX11).NativeDevice; Dx11.DeviceContext context = (GraphicsDevice.NativeDevice as GraphicsDeviceWindowsDX11).NativeDevice;
context.UnmapSubresource(NativeTexture, tempSubresource); var texture = useRenderTexture ? NativeTextureStaging : NativeTexture;
context.UnmapSubresource(texture, tempSubresource);
if(useRenderTexture)
context.CopyResource(NativeTextureStaging, NativeTexture);
} }
#endregion #endregion
} }

View File

@ -269,14 +269,11 @@ namespace ANX.RenderSystem.Windows.Metro
} }
#endregion #endregion
#region IRenderSystemCreator Member #region IsLanguageSupported
public bool IsLanguageSupported(EffectSourceLanguage sourceLanguage) public bool IsLanguageSupported(EffectSourceLanguage sourceLanguage)
{ {
throw new NotImplementedException(); return sourceLanguage == EffectSourceLanguage.HLSL_FX || sourceLanguage == EffectSourceLanguage.HLSL;
} }
#endregion #endregion
#region SetTextureSampler (TODO) #region SetTextureSampler (TODO)

View File

@ -15,11 +15,14 @@ namespace ANX.RenderSystem.Windows.Metro
public class Texture2D_Metro : INativeTexture2D public class Texture2D_Metro : INativeTexture2D
{ {
#region Private #region Private
protected bool useRenderTexture;
protected Dx11.Texture2D NativeTextureStaging;
protected internal Dx11.Texture2D NativeTexture; protected internal Dx11.Texture2D NativeTexture;
protected internal Dx11.ShaderResourceView NativeShaderResourceView; protected internal Dx11.ShaderResourceView NativeShaderResourceView;
protected int formatSize; protected int formatSize;
protected SurfaceFormat surfaceFormat; protected SurfaceFormat surfaceFormat;
protected GraphicsDevice graphicsDevice; protected GraphicsDevice graphicsDevice;
private int mipCount;
#endregion #endregion
#region Public #region Public
@ -27,9 +30,7 @@ namespace ANX.RenderSystem.Windows.Metro
{ {
get get
{ {
return NativeTexture != null ? return NativeTexture != null ? NativeTexture.Description.Width : 0;
NativeTexture.Description.Width :
0;
} }
} }
@ -37,9 +38,7 @@ namespace ANX.RenderSystem.Windows.Metro
{ {
get get
{ {
return NativeTexture != null ? return NativeTexture != null ? NativeTexture.Description.Height : 0;
NativeTexture.Description.Height :
0;
} }
} }
#endregion #endregion
@ -50,20 +49,32 @@ namespace ANX.RenderSystem.Windows.Metro
this.graphicsDevice = graphicsDevice; this.graphicsDevice = graphicsDevice;
} }
public Texture2D_Metro(GraphicsDevice graphicsDevice, int width, int height, public Texture2D_Metro(GraphicsDevice graphicsDevice, int width, int height, SurfaceFormat surfaceFormat, int mipCount)
SurfaceFormat surfaceFormat, int mipCount)
{ {
if (mipCount > 1) this.mipCount = mipCount;
{ useRenderTexture = mipCount > 1;
throw new Exception("creating textures with mip map not yet implemented");
}
this.graphicsDevice = graphicsDevice; this.graphicsDevice = graphicsDevice;
this.surfaceFormat = surfaceFormat; this.surfaceFormat = surfaceFormat;
GraphicsDeviceWindowsMetro graphicsMetro = graphicsDevice.NativeDevice as GraphicsDeviceWindowsMetro; GraphicsDeviceWindowsMetro graphicsMetro = graphicsDevice.NativeDevice as GraphicsDeviceWindowsMetro;
var device = graphicsMetro.NativeDevice.NativeDevice; var device = graphicsMetro.NativeDevice.NativeDevice;
if (useRenderTexture)
{
var descriptionStaging = new Dx11.Texture2DDescription()
{
Width = width,
Height = height,
MipLevels = mipCount,
ArraySize = mipCount,
Format = FormatConverter.Translate(surfaceFormat),
SampleDescription = new SharpDX.DXGI.SampleDescription(1, 0),
Usage = Dx11.ResourceUsage.Staging,
CpuAccessFlags = Dx11.CpuAccessFlags.Write,
};
NativeTextureStaging = new Dx11.Texture2D(device, descriptionStaging);
}
var description = new Dx11.Texture2DDescription() var description = new Dx11.Texture2DDescription()
{ {
Width = width, Width = width,
@ -72,10 +83,9 @@ namespace ANX.RenderSystem.Windows.Metro
ArraySize = mipCount, ArraySize = mipCount,
Format = FormatConverter.Translate(surfaceFormat), Format = FormatConverter.Translate(surfaceFormat),
SampleDescription = new SharpDX.DXGI.SampleDescription(1, 0), SampleDescription = new SharpDX.DXGI.SampleDescription(1, 0),
Usage = Dx11.ResourceUsage.Dynamic, Usage = useRenderTexture ? Dx11.ResourceUsage.Default : Dx11.ResourceUsage.Dynamic,
BindFlags = Dx11.BindFlags.ShaderResource, BindFlags = Dx11.BindFlags.ShaderResource,
CpuAccessFlags = Dx11.CpuAccessFlags.Write, CpuAccessFlags = useRenderTexture ? Dx11.CpuAccessFlags.None : Dx11.CpuAccessFlags.Write,
OptionFlags = Dx11.ResourceOptionFlags.None,
}; };
this.NativeTexture = new Dx11.Texture2D(device, description); this.NativeTexture = new Dx11.Texture2D(device, description);
this.NativeShaderResourceView = new Dx11.ShaderResourceView(device, this.NativeTexture); this.NativeShaderResourceView = new Dx11.ShaderResourceView(device, this.NativeTexture);
@ -95,119 +105,153 @@ namespace ANX.RenderSystem.Windows.Metro
#endregion #endregion
#region SetData #region SetData
public void SetData<T>(int level, Rectangle? rect, T[] data, public void SetData<T>(GraphicsDevice graphicsDevice, T[] data) where T : struct
int startIndex, int elementCount) where T : struct
{
throw new NotImplementedException();
}
public void SetData<T>(GraphicsDevice graphicsDevice, T[] data)
where T : struct
{ {
SetData<T>(graphicsDevice, 0, data, 0, data.Length); SetData<T>(graphicsDevice, 0, data, 0, data.Length);
} }
public void SetData<T>(GraphicsDevice graphicsDevice, T[] data, public void SetData<T>(GraphicsDevice graphicsDevice, T[] data, int startIndex, int elementCount) where T : struct
int startIndex, int elementCount) where T : struct
{ {
SetData<T>(graphicsDevice, 0, data, startIndex, elementCount); SetData<T>(graphicsDevice, 0, data, startIndex, elementCount);
} }
public void SetData<T>(GraphicsDevice graphicsDevice, int offsetInBytes, public void SetData<T>(GraphicsDevice graphicsDevice, int offsetInBytes, T[] data, int startIndex, int elementCount)
T[] data, int startIndex, int elementCount) where T : struct where T : struct
{ {
//TODO: handle offsetInBytes parameter //TODO: handle offsetInBytes parameter
//TODO: handle startIndex parameter //TODO: handle startIndex parameter
//TODO: handle elementCount parameter //TODO: handle elementCount parameter
unsafe
{
GCHandle handle = GCHandle.Alloc(data, GCHandleType.Pinned);
byte* colorData = (byte*)handle.AddrOfPinnedObject();
switch (surfaceFormat)
{
case SurfaceFormat.Color:
SetDataColor(0, offsetInBytes, colorData, startIndex, elementCount);
return;
case SurfaceFormat.Dxt1:
case SurfaceFormat.Dxt3:
case SurfaceFormat.Dxt5:
SetDataDxt(0, offsetInBytes, colorData, startIndex, elementCount, data.Length);
return;
}
handle.Free();
}
throw new Exception(String.Format("creating textures of format {0} not yet implemented...", surfaceFormat));
}
public void SetData<T>(int level, Rectangle? rect, T[] data, int startIndex, int elementCount) where T : struct
{
//TODO: handle rect parameter
if (rect != null)
throw new Exception("Texture2D SetData with rectangle is not yet implemented!");
unsafe
{
GCHandle handle = GCHandle.Alloc(data, GCHandleType.Pinned);
byte* colorData = (byte*)handle.AddrOfPinnedObject();
switch (surfaceFormat)
{
case SurfaceFormat.Color:
SetDataColor(level, 0, colorData, startIndex, elementCount);
return;
case SurfaceFormat.Dxt1:
case SurfaceFormat.Dxt3:
case SurfaceFormat.Dxt5:
SetDataDxt(level, 0, colorData, startIndex, elementCount, data.Length);
return;
}
handle.Free();
}
throw new Exception(String.Format("creating textures of format {0} not yet implemented...", surfaceFormat));
}
#endregion
#region SetDataColor
private unsafe void SetDataColor(int level, int offsetInBytes, byte* colorData, int startIndex, int elementCount)
{
int mipmapWidth = Math.Max(Width >> level, 1);
int mipmapHeight = Math.Max(Height >> level, 1);
int subresource = Dx11.Texture2D.CalculateSubResourceIndex(level, 0, mipCount);
var texture = useRenderTexture ? NativeTextureStaging : NativeTexture;
SharpDX.DataBox rectangle = NativeDxDevice.Current.MapSubresource(texture, subresource);
if (this.surfaceFormat == SurfaceFormat.Color) int srcIndex = 0;
byte* pTexels = (byte*)rectangle.DataPointer;
for (int row = 0; row < mipmapHeight; row++)
{ {
int subresource = Dx11.Texture2D.CalculateSubResourceIndex(0, 0, 1); int rowStart = row * rectangle.RowPitch;
SharpDX.DataBox rectangle = NativeDxDevice.Current.MapSubresource(NativeTexture, subresource);
int rowPitch = rectangle.RowPitch;
unsafe for (int col = 0; col < mipmapWidth; col++)
{ {
GCHandle handle = GCHandle.Alloc(data, GCHandleType.Pinned); int colStart = rowStart + (col * formatSize);
byte* colorData = (byte*)handle.AddrOfPinnedObject(); pTexels[colStart++] = colorData[srcIndex++];
pTexels[colStart++] = colorData[srcIndex++];
byte* pTexels = (byte*)rectangle.DataPointer; pTexels[colStart++] = colorData[srcIndex++];
int srcIndex = 0; pTexels[colStart++] = colorData[srcIndex++];
for (int row = 0; row < Height; row++)
{
int rowStart = row * rowPitch;
for (int col = 0; col < Width; col++)
{
int colStart = col * formatSize;
pTexels[rowStart + colStart + 0] = colorData[srcIndex++];
pTexels[rowStart + colStart + 1] = colorData[srcIndex++];
pTexels[rowStart + colStart + 2] = colorData[srcIndex++];
pTexels[rowStart + colStart + 3] = colorData[srcIndex++];
}
}
handle.Free();
}
NativeDxDevice.Current.UnmapSubresource(NativeTexture, subresource);
}
else if (surfaceFormat == SurfaceFormat.Dxt5 || surfaceFormat == SurfaceFormat.Dxt3 || surfaceFormat == SurfaceFormat.Dxt1)
{
unsafe
{
GCHandle handle = GCHandle.Alloc(data, GCHandleType.Pinned);
byte* colorData = (byte*)handle.AddrOfPinnedObject();
int w = (Width + 3) >> 2;
int h = (Height + 3) >> 2;
formatSize = (surfaceFormat == SurfaceFormat.Dxt1) ? 8 : 16;
int subresource = Dx11.Texture2D.CalculateSubResourceIndex(0, 0, 1);
SharpDX.DataBox rectangle =
NativeDxDevice.Current.MapSubresource(NativeTexture, subresource);
SharpDX.DataStream ds = new SharpDX.DataStream(rectangle.DataPointer, Width * Height * 4 * 2, true, true);
int pitch = rectangle.RowPitch;
int col = 0;
int index = 0; // startIndex
int count = data.Length; // elementCount
int actWidth = w * formatSize;
for (int i = 0; i < h; i++)
{
ds.Position = (i * pitch) + (col * formatSize);
if (count <= 0)
{
break;
}
else if (count < actWidth)
{
for (int idx = index; idx < index + count; idx++)
{
ds.WriteByte(colorData[idx]);
}
break;
}
for (int idx = index; idx < index + actWidth; idx++)
{
ds.WriteByte(colorData[idx]);
}
index += actWidth;
count -= actWidth;
}
handle.Free();
NativeDxDevice.Current.UnmapSubresource(NativeTexture, subresource);
} }
} }
else
NativeDxDevice.Current.UnmapSubresource(texture, subresource);
if (useRenderTexture)
NativeDxDevice.Current.NativeContext.CopyResource(NativeTextureStaging, NativeTexture);
}
#endregion
#region SetDataDxt
private unsafe void SetDataDxt(int level, int offsetInBytes, byte* colorData, int startIndex, int elementCount,
int dataLength)
{
int mipmapWidth = Math.Max(Width >> level, 1);
int mipmapHeight = Math.Max(Height >> level, 1);
int w = (mipmapWidth + 3) >> 2;
int h = (mipmapHeight + 3) >> 2;
formatSize = (surfaceFormat == SurfaceFormat.Dxt1) ? 8 : 16;
int subresource = Dx11.Texture2D.CalculateSubResourceIndex(level, 0, mipCount);
var texture = useRenderTexture ? NativeTextureStaging : NativeTexture;
SharpDX.DataBox rectangle = NativeDxDevice.Current.MapSubresource(texture, subresource);
var ds = new SharpDX.DataStream(rectangle.DataPointer, mipmapWidth * mipmapHeight * 4 * 2, true, true);
int col = 0;
int index = 0; // startIndex
int count = dataLength; // elementCount
int actWidth = w * formatSize;
for (int i = 0; i < h; i++)
{ {
throw new Exception(string.Format("creating textures of format {0} not yet implemented...", surfaceFormat.ToString())); ds.Position = (i * rectangle.RowPitch) + (col * formatSize);
if (count <= 0)
break;
else if (count < actWidth)
{
for (int idx = index; idx < index + count; idx++)
ds.WriteByte(colorData[idx]);
break;
}
for (int idx = index; idx < index + actWidth; idx++)
ds.WriteByte(colorData[idx]);
index += actWidth;
count -= actWidth;
} }
NativeDxDevice.Current.UnmapSubresource(texture, subresource);
if (useRenderTexture)
NativeDxDevice.Current.NativeContext.CopyResource(NativeTextureStaging, NativeTexture);
} }
#endregion #endregion
@ -225,6 +269,12 @@ namespace ANX.RenderSystem.Windows.Metro
NativeTexture.Dispose(); NativeTexture.Dispose();
NativeTexture = null; NativeTexture = null;
} }
if (NativeTextureStaging != null)
{
NativeTextureStaging.Dispose();
NativeTextureStaging = null;
}
} }
#endregion #endregion

View File

@ -141,6 +141,13 @@
<Processor>ModelProcessor</Processor> <Processor>ModelProcessor</Processor>
</Compile> </Compile>
</ItemGroup> </ItemGroup>
<ItemGroup>
<Compile Include="Textures\dds-test.dds">
<Name>dds-test</Name>
<Importer>TextureImporter</Importer>
<Processor>TextureProcessor</Processor>
</Compile>
</ItemGroup>
<Import Project="$(MSBuildExtensionsPath)\Microsoft\XNA Game Studio\$(XnaFrameworkVersion)\Microsoft.Xna.GameStudio.ContentPipeline.targets" /> <Import Project="$(MSBuildExtensionsPath)\Microsoft\XNA Game Studio\$(XnaFrameworkVersion)\Microsoft.Xna.GameStudio.ContentPipeline.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it. <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets. Other similar extension points exist, see Microsoft.Common.targets.

Binary file not shown.

View File

@ -71,6 +71,7 @@ namespace WindowsGame1
//this.alternateTexture = Content.Load<Texture2D>(@"Textures/DotColor4x4"); //this.alternateTexture = Content.Load<Texture2D>(@"Textures/DotColor4x4");
this.alternateTexture = Content.Load<Texture2D>(@"Textures/DotWhiteTopLeft5x5"); this.alternateTexture = Content.Load<Texture2D>(@"Textures/DotWhiteTopLeft5x5");
this.texture = Content.Load<Texture2D>(@"Textures/ANX.logo"); this.texture = Content.Load<Texture2D>(@"Textures/ANX.logo");
//this.texture = Content.Load<Texture2D>(@"Textures/dds-test");
//this.alternateTexture = new Texture2D(GraphicsDevice, 64, 64); //this.alternateTexture = new Texture2D(GraphicsDevice, 64, 64);
//Color[] color = new Color[this.alternateTexture.Width * this.alternateTexture.Height]; //Color[] color = new Color[this.alternateTexture.Width * this.alternateTexture.Height];

View File

@ -1,5 +1,3 @@
//#define USE_GL3
using System; using System;
using ANX.Framework.NonXNA; using ANX.Framework.NonXNA;
@ -12,11 +10,9 @@ namespace WindowsGame1
/// </summary> /// </summary>
static void Main(string[] args) static void Main(string[] args)
{ {
#if USE_GL3 //AddInSystemFactory.Instance.SetPreferredSystem(AddInType.RenderSystem, "OpenGL3");
AddInSystemFactory.Instance.SetPreferredSystem(AddInType.RenderSystem, "OpenGL3");
#else
AddInSystemFactory.Instance.SetPreferredSystem(AddInType.RenderSystem, "DirectX10"); AddInSystemFactory.Instance.SetPreferredSystem(AddInType.RenderSystem, "DirectX10");
#endif //AddInSystemFactory.Instance.SetPreferredSystem(AddInType.RenderSystem, "DirectX11");
using (Game1 game = new Game1()) using (Game1 game = new Game1())
{ {

View File

@ -69,12 +69,13 @@ namespace ANX.SoundSystem.Windows.XAudio
AudioBytes = (int)stream.Length, AudioBytes = (int)stream.Length,
Flags = BufferFlags.EndOfStream Flags = BufferFlags.EndOfStream
}; };
soundStream.Close();
float sizeMulBlockAlign = soundStream.Length / (waveFormat.Channels * 2); float sizeMulBlockAlign = soundStream.Length / (waveFormat.Channels * 2);
duration = TimeSpan.FromMilliseconds((double)(sizeMulBlockAlign * 1000f / (float)waveFormat.SampleRate)); duration = TimeSpan.FromMilliseconds((double)(sizeMulBlockAlign * 1000f / (float)waveFormat.SampleRate));
DecodedPacketsInfo = soundStream.DecodedPacketsInfo; DecodedPacketsInfo = soundStream.DecodedPacketsInfo;
soundStream.Dispose();
} }
#endregion #endregion

BIN
media/dds-test.dds Normal file

Binary file not shown.