268 lines
9.8 KiB
C#
268 lines
9.8 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using Aiwaz.Contracts;
|
|
using Aiwaz.Core;
|
|
using SlimDX.Direct3D10;
|
|
using Aiwaz.Resources.Attributes;
|
|
|
|
namespace Aiwaz.Resources
|
|
{
|
|
[CreationParameters("Create an empty texture")]
|
|
public class EmptyTextureParams : ICreationParams
|
|
{
|
|
public int Width;
|
|
public int Height;
|
|
public int Elements;
|
|
public int MipLevels;
|
|
public SlimDX.DXGI.Format Format;
|
|
public ResourceUsage AccessType;
|
|
public TextureInitialData InitialData;
|
|
public bool RenderTarget;
|
|
public int MultiSampleCount;
|
|
public int MultiSampleQuality;
|
|
|
|
public EmptyTextureParams()
|
|
{
|
|
Width = 512;
|
|
Height = 512;
|
|
Elements = 1;
|
|
MipLevels = 1;
|
|
Format = SlimDX.DXGI.Format.Unknown;
|
|
AccessType = ResourceUsage.Default;
|
|
InitialData = null;
|
|
RenderTarget = false;
|
|
MultiSampleCount = 0;
|
|
MultiSampleQuality = 0;
|
|
}
|
|
}
|
|
|
|
[CreationParameters("Load a texture from file")]
|
|
public class FileTextureParams : ICreationParams
|
|
{
|
|
[RequiredParameter]
|
|
public string FileName;
|
|
public SlimDX.Direct3D10.ResourceUsage AccessType;
|
|
|
|
public FileTextureParams()
|
|
{
|
|
AccessType = ResourceUsage.Default;
|
|
}
|
|
}
|
|
|
|
[AiwazResource("Texture", "A placeholder of multidimensional data")]
|
|
public class Texture : ShaderParameterSet, ITexture
|
|
{
|
|
#region ITexture Members
|
|
|
|
private string bindingName = "Diffuse";
|
|
private SlimDX.Direct3D10.Resource resource;
|
|
private int lockedSubResource = 0;
|
|
private bool isLocked = false;
|
|
|
|
private Texture()
|
|
: base(3)
|
|
{
|
|
}
|
|
|
|
public Texture(FileTextureParams descriptor)
|
|
: this()
|
|
{
|
|
Console.WriteLine(string.Format("Creating Texture ({0})..", descriptor.FileName));
|
|
|
|
this.LoadFromFile(descriptor.FileName, descriptor.AccessType);
|
|
this.WellKnownName = descriptor.FileName;
|
|
}
|
|
|
|
public Texture(EmptyTextureParams descriptor)
|
|
: this()
|
|
{
|
|
this.CreateTexture(descriptor.Width, descriptor.Height, descriptor.MipLevels, descriptor.Elements, descriptor.Format, descriptor.InitialData, descriptor.AccessType, descriptor.RenderTarget, descriptor.MultiSampleCount, descriptor.MultiSampleQuality);
|
|
}
|
|
|
|
public string BindingName
|
|
{
|
|
get { return bindingName; }
|
|
set
|
|
{
|
|
if (!string.IsNullOrEmpty(bindingName))
|
|
this.RemoveParameter(bindingName);
|
|
|
|
bindingName = value;;
|
|
|
|
if (!string.IsNullOrEmpty(bindingName))
|
|
this.SetParameter(bindingName, this, ParameterBindType.BindBySemantic);
|
|
}
|
|
}
|
|
|
|
public int TextureWidth { get; protected set; }
|
|
|
|
public int TextureHeight { get; protected set; }
|
|
|
|
public int TextureArraySize { get; protected set; }
|
|
|
|
public SlimDX.DXGI.Format TextureFormat { get; protected set; }
|
|
|
|
public SlimDX.Direct3D10.ShaderResourceView ResourceView { get; protected set; }
|
|
|
|
public SlimDX.Direct3D10.Texture2D Texture2D { get; protected set; }
|
|
|
|
public SlimDX.DataRectangle MapTextureBuffer(SlimDX.Direct3D10.MapMode mode)
|
|
{
|
|
return this.MapTextureBuffer(mode, 0);
|
|
}
|
|
|
|
public SlimDX.DataRectangle MapTextureBuffer(SlimDX.Direct3D10.MapMode mode, int arrayElement)
|
|
{
|
|
if (isLocked)
|
|
throw new ActionFailedException("Texture is already locked.");
|
|
isLocked = true;
|
|
lockedSubResource = arrayElement;
|
|
|
|
return this.Texture2D.Map(arrayElement, mode, SlimDX.Direct3D10.MapFlags.None);
|
|
}
|
|
|
|
public void UnmapTextureBuffer()
|
|
{
|
|
if (!isLocked)
|
|
return;
|
|
isLocked = false;
|
|
this.Texture2D.Unmap(lockedSubResource);
|
|
}
|
|
|
|
private void LoadFromFile(string fileName, SlimDX.Direct3D10.ResourceUsage accessType)
|
|
{
|
|
var loadInfo = SlimDX.Direct3D10.ImageLoadInformation.FromDefaults();
|
|
|
|
if (accessType == SlimDX.Direct3D10.ResourceUsage.Staging)
|
|
{
|
|
loadInfo.BindFlags = 0;
|
|
loadInfo.Usage = SlimDX.Direct3D10.ResourceUsage.Staging;
|
|
loadInfo.CpuAccessFlags = SlimDX.Direct3D10.CpuAccessFlags.Write | SlimDX.Direct3D10.CpuAccessFlags.Read;
|
|
}
|
|
else if (accessType == SlimDX.Direct3D10.ResourceUsage.Dynamic)
|
|
{
|
|
loadInfo.Usage = SlimDX.Direct3D10.ResourceUsage.Dynamic;
|
|
loadInfo.CpuAccessFlags = SlimDX.Direct3D10.CpuAccessFlags.Write;
|
|
}
|
|
|
|
using (var stream = Engine.FileSystem.Open(fileName))
|
|
{
|
|
this.Texture2D = SlimDX.Direct3D10.Texture2D.FromStream(Engine.Device, stream, (int)stream.Length, loadInfo);
|
|
resource = this.Texture2D;
|
|
}
|
|
|
|
if (accessType != SlimDX.Direct3D10.ResourceUsage.Staging)
|
|
{
|
|
var texViewDesc = new SlimDX.Direct3D10.ShaderResourceViewDescription();
|
|
|
|
texViewDesc.Format = this.Texture2D.Description.Format;
|
|
texViewDesc.Dimension = SlimDX.Direct3D10.ShaderResourceViewDimension.Texture2D;
|
|
texViewDesc.MostDetailedMip = 0;
|
|
texViewDesc.MipLevels = this.Texture2D.Description.MipLevels;
|
|
|
|
this.ResourceView = new SlimDX.Direct3D10.ShaderResourceView(Engine.Device, this.Texture2D, texViewDesc);
|
|
}
|
|
|
|
this.TextureWidth = this.Texture2D.Description.Width;
|
|
this.TextureHeight = this.Texture2D.Description.Height;
|
|
this.TextureFormat = this.Texture2D.Description.Format;
|
|
this.TextureArraySize = 0;
|
|
|
|
this.BindingName = this.BindingName;
|
|
}
|
|
|
|
internal void CreateRenderTargetTexture(int width, int height, SlimDX.DXGI.Format format, int multiSampleCount, int multiSampleQuality)
|
|
{
|
|
this.CreateTexture(width, height, 1, 0, format, null, SlimDX.Direct3D10.ResourceUsage.Staging, true, multiSampleCount, multiSampleQuality);
|
|
}
|
|
|
|
private void DisposeInternal()
|
|
{
|
|
if (this.ResourceView != null)
|
|
this.ResourceView.Dispose();
|
|
this.ResourceView = null;
|
|
|
|
if (this.resource != null)
|
|
this.resource.Dispose();
|
|
this.resource = null;
|
|
this.Texture2D = null;
|
|
}
|
|
|
|
private void CreateTexture(int width, int height, int mipLevels, int elements, SlimDX.DXGI.Format format, TextureInitialData initialData, SlimDX.Direct3D10.ResourceUsage accessType, bool renderTarget, int multiSampleCount, int multiSampleQuality)
|
|
{
|
|
Console.WriteLine(string.Format("Creating Texture ({0}x{1} {2})..", width, height, format.ToString()));
|
|
|
|
this.DisposeInternal();
|
|
|
|
// calculate the needed amount of mipmap levels
|
|
int mipMapLevels = 1;
|
|
for (int tmp = Math.Min(height, width); tmp > 1; tmp /= 2, ++mipMapLevels);
|
|
mipMapLevels = Math.Max(1, Math.Min(mipMapLevels, mipLevels == 0 ? mipMapLevels : mipLevels));
|
|
|
|
// create the resource
|
|
var texDesc = new SlimDX.Direct3D10.Texture2DDescription();
|
|
texDesc.Width = width;
|
|
texDesc.Height = height;
|
|
texDesc.MipLevels = mipMapLevels;
|
|
texDesc.ArraySize = Math.Max(1, elements);
|
|
texDesc.Format = format;
|
|
texDesc.SampleDescription = new SlimDX.DXGI.SampleDescription(multiSampleCount, multiSampleQuality);
|
|
|
|
if (accessType == SlimDX.Direct3D10.ResourceUsage.Dynamic)
|
|
{
|
|
texDesc.Usage = SlimDX.Direct3D10.ResourceUsage.Dynamic;
|
|
texDesc.CpuAccessFlags = SlimDX.Direct3D10.CpuAccessFlags.Write;
|
|
}
|
|
|
|
if (accessType == SlimDX.Direct3D10.ResourceUsage.Staging)
|
|
texDesc.BindFlags = ((mipMapLevels > 1 || renderTarget) ? SlimDX.Direct3D10.BindFlags.RenderTarget : SlimDX.Direct3D10.BindFlags.None) | SlimDX.Direct3D10.BindFlags.ShaderResource;
|
|
if (mipMapLevels > 1)
|
|
texDesc.OptionFlags = SlimDX.Direct3D10.ResourceOptionFlags.GenerateMipMaps;
|
|
|
|
resource = this.Texture2D = new SlimDX.Direct3D10.Texture2D(Engine.Device, texDesc);
|
|
|
|
// create the resource view when possible
|
|
if (accessType != SlimDX.Direct3D10.ResourceUsage.Staging)
|
|
{
|
|
var texViewDesc = new SlimDX.Direct3D10.ShaderResourceViewDescription();
|
|
texViewDesc.Format = texDesc.Format;
|
|
texViewDesc.ElementWidth = elements;
|
|
|
|
if (elements > 0)
|
|
texViewDesc.Dimension = multiSampleCount == 1 ? SlimDX.Direct3D10.ShaderResourceViewDimension.Texture2DArray : SlimDX.Direct3D10.ShaderResourceViewDimension.Texture2DMultisampledArray;
|
|
else
|
|
texViewDesc.Dimension = multiSampleCount == 1 ? SlimDX.Direct3D10.ShaderResourceViewDimension.Texture2D : SlimDX.Direct3D10.ShaderResourceViewDimension.Texture2DMultisampled;
|
|
|
|
texViewDesc.MostDetailedMip = 0;
|
|
texViewDesc.MipLevels = texDesc.MipLevels;
|
|
texViewDesc.ArraySize = elements;
|
|
|
|
this.ResourceView = new SlimDX.Direct3D10.ShaderResourceView(Engine.Device, resource, texViewDesc);
|
|
}
|
|
|
|
// finalize
|
|
this.TextureWidth = width;
|
|
this.TextureHeight = height;
|
|
this.TextureFormat = format;
|
|
this.TextureArraySize = 1;
|
|
|
|
this.BindingName = this.BindingName;
|
|
}
|
|
|
|
#region IDisposable Members
|
|
|
|
public override void Dispose()
|
|
{
|
|
this.DisposeInternal();
|
|
base.Dispose();
|
|
}
|
|
|
|
#endregion
|
|
|
|
|
|
#endregion
|
|
}
|
|
}
|