2012-09-08 09:07:23 +00:00
|
|
|
#define DIRECTX_DEBUG_LAYER
|
2011-11-16 14:27:53 +00:00
|
|
|
using System;
|
2012-08-10 08:38:01 +00:00
|
|
|
using ANX.Framework;
|
2011-11-16 14:27:53 +00:00
|
|
|
using ANX.Framework.Graphics;
|
2012-09-06 09:58:13 +00:00
|
|
|
using ANX.Framework.NonXNA;
|
|
|
|
using ANX.RenderSystem.Windows.DX10.Helpers;
|
|
|
|
using SharpDX.D3DCompiler;
|
|
|
|
using SharpDX.DXGI;
|
|
|
|
using Dx10 = SharpDX.Direct3D10;
|
2012-09-07 09:48:45 +00:00
|
|
|
using ANX.BaseDirectX;
|
2011-11-16 14:27:53 +00:00
|
|
|
|
2012-08-09 09:45:04 +00:00
|
|
|
// This file is part of the ANX.Framework created by the
|
|
|
|
// "ANX.Framework developer group" and released under the Ms-PL license.
|
|
|
|
// For details see: http://anxframework.codeplex.com/license
|
2011-11-16 14:27:53 +00:00
|
|
|
|
2012-08-09 09:45:04 +00:00
|
|
|
namespace ANX.RenderSystem.Windows.DX10
|
2011-11-16 14:27:53 +00:00
|
|
|
{
|
|
|
|
public class GraphicsDeviceWindowsDX10 : INativeGraphicsDevice
|
|
|
|
{
|
|
|
|
#region Constants
|
|
|
|
private const float ColorMultiplier = 1f / 255f;
|
|
|
|
#endregion
|
|
|
|
|
2012-09-06 09:58:13 +00:00
|
|
|
#region Private
|
|
|
|
private Dx10.Device device;
|
|
|
|
private SwapChain swapChain;
|
|
|
|
private Dx10.RenderTargetView renderView;
|
|
|
|
private Dx10.RenderTargetView[] renderTargetView = new Dx10.RenderTargetView[1];
|
|
|
|
private Dx10.DepthStencilView depthStencilView;
|
|
|
|
private Dx10.Texture2D depthStencilBuffer;
|
|
|
|
private Dx10.Texture2D backBuffer;
|
2011-11-16 14:27:53 +00:00
|
|
|
internal Effect_DX10 currentEffect;
|
|
|
|
private VertexBuffer currentVertexBuffer;
|
|
|
|
private IndexBuffer currentIndexBuffer;
|
2012-09-06 09:58:13 +00:00
|
|
|
private Dx10.Viewport currentViewport;
|
2011-11-16 14:27:53 +00:00
|
|
|
private uint lastClearColor;
|
|
|
|
private SharpDX.Color4 clearColor;
|
2012-09-06 09:58:13 +00:00
|
|
|
#endregion
|
2012-09-05 19:50:10 +00:00
|
|
|
|
2012-09-06 09:58:13 +00:00
|
|
|
#region Public
|
|
|
|
internal Dx10.Device NativeDevice
|
2012-09-05 19:50:10 +00:00
|
|
|
{
|
|
|
|
get
|
|
|
|
{
|
|
|
|
return this.device;
|
|
|
|
}
|
|
|
|
}
|
2011-11-16 14:27:53 +00:00
|
|
|
|
2012-09-06 09:58:13 +00:00
|
|
|
public bool VSync { get; set; }
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
#region Constructor
|
|
|
|
public GraphicsDeviceWindowsDX10(PresentationParameters presentationParameters)
|
2011-11-16 14:27:53 +00:00
|
|
|
{
|
2012-09-06 09:58:13 +00:00
|
|
|
VSync = true;
|
2011-11-16 14:27:53 +00:00
|
|
|
|
|
|
|
// SwapChain description
|
|
|
|
var desc = new SwapChainDescription()
|
|
|
|
{
|
|
|
|
BufferCount = 1,
|
2012-09-06 09:58:13 +00:00
|
|
|
ModeDescription = new ModeDescription(presentationParameters.BackBufferWidth,
|
|
|
|
presentationParameters.BackBufferHeight, new Rational(60, 1),
|
2012-09-07 09:48:45 +00:00
|
|
|
BaseFormatConverter.Translate(presentationParameters.BackBufferFormat)),
|
2011-11-16 14:27:53 +00:00
|
|
|
IsWindowed = true,
|
|
|
|
OutputHandle = presentationParameters.DeviceWindowHandle,
|
|
|
|
SampleDescription = new SampleDescription(1, 0),
|
|
|
|
SwapEffect = SwapEffect.Discard,
|
|
|
|
Usage = Usage.RenderTargetOutput
|
|
|
|
};
|
|
|
|
|
|
|
|
// Create Device and SwapChain
|
|
|
|
#if DIRECTX_DEBUG_LAYER
|
|
|
|
// http://msdn.microsoft.com/en-us/library/windows/desktop/bb205068(v=vs.85).aspx
|
2012-09-06 09:58:13 +00:00
|
|
|
Dx10.Device.CreateWithSwapChain(Dx10.DriverType.Hardware, Dx10.DeviceCreationFlags.Debug, desc, out device,
|
|
|
|
out swapChain);
|
2011-11-16 14:27:53 +00:00
|
|
|
#else
|
2012-09-06 09:58:13 +00:00
|
|
|
Dx10.Device.CreateWithSwapChain(Dx10.DriverType.Hardware, Dx10.DeviceCreationFlags.None, desc, out device,
|
|
|
|
out swapChain);
|
2011-11-16 14:27:53 +00:00
|
|
|
#endif
|
|
|
|
|
|
|
|
// Ignore all windows events
|
|
|
|
Factory factory = swapChain.GetParent<Factory>();
|
|
|
|
factory.MakeWindowAssociation(presentationParameters.DeviceWindowHandle, WindowAssociationFlags.IgnoreAll);
|
|
|
|
|
2012-09-06 09:58:13 +00:00
|
|
|
WindowHelper.ResizeRenderWindow(presentationParameters);
|
2011-11-30 13:58:55 +00:00
|
|
|
|
2011-11-16 14:27:53 +00:00
|
|
|
// New RenderTargetView from the backbuffer
|
2012-09-06 09:58:13 +00:00
|
|
|
backBuffer = Dx10.Texture2D.FromSwapChain<Dx10.Texture2D>(swapChain, 0);
|
|
|
|
renderView = new Dx10.RenderTargetView(device, backBuffer);
|
2011-11-16 14:27:53 +00:00
|
|
|
|
2012-09-06 09:58:13 +00:00
|
|
|
currentViewport = new Dx10.Viewport(0, 0, presentationParameters.BackBufferWidth, presentationParameters.BackBufferHeight);
|
2011-11-29 13:05:37 +00:00
|
|
|
|
|
|
|
//
|
|
|
|
// create the depth stencil buffer
|
|
|
|
//
|
2012-09-07 09:48:45 +00:00
|
|
|
Format depthFormat = BaseFormatConverter.Translate(presentationParameters.DepthStencilFormat);
|
2011-11-29 13:05:37 +00:00
|
|
|
if (depthFormat != Format.Unknown)
|
2011-12-09 08:46:25 +00:00
|
|
|
CreateDepthStencilBuffer(depthFormat);
|
|
|
|
}
|
2012-09-06 09:58:13 +00:00
|
|
|
#endregion
|
2011-11-29 13:05:37 +00:00
|
|
|
|
2012-09-06 09:58:13 +00:00
|
|
|
#region CreateDepthStencilBuffer
|
|
|
|
private void CreateDepthStencilBuffer(Format depthFormat)
|
2011-12-09 08:46:25 +00:00
|
|
|
{
|
|
|
|
if (this.depthStencilBuffer != null &&
|
|
|
|
this.depthStencilBuffer.Description.Format == depthFormat &&
|
|
|
|
this.depthStencilBuffer.Description.Width == this.backBuffer.Description.Width &&
|
|
|
|
this.depthStencilBuffer.Description.Height == this.backBuffer.Description.Height)
|
|
|
|
{
|
|
|
|
// a DepthStencilBuffer with the right format and the right size already exists -> nothing to do
|
|
|
|
return;
|
2011-11-29 13:05:37 +00:00
|
|
|
}
|
2011-12-09 08:46:25 +00:00
|
|
|
|
|
|
|
if (this.depthStencilView != null)
|
|
|
|
{
|
|
|
|
this.depthStencilView.Dispose();
|
|
|
|
this.depthStencilView = null;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (this.depthStencilBuffer != null)
|
|
|
|
{
|
|
|
|
this.depthStencilBuffer.Dispose();
|
|
|
|
this.depthStencilBuffer = null;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (depthFormat == Format.Unknown)
|
|
|
|
{
|
|
|
|
// no DepthStencilBuffer to create... Old one was disposed already...
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2012-09-06 09:58:13 +00:00
|
|
|
var depthStencilViewDesc = new Dx10.DepthStencilViewDescription()
|
2011-12-09 08:46:25 +00:00
|
|
|
{
|
|
|
|
Format = depthFormat,
|
|
|
|
};
|
|
|
|
|
2012-09-06 09:58:13 +00:00
|
|
|
var depthStencilTextureDesc = new Dx10.Texture2DDescription()
|
2011-12-09 08:46:25 +00:00
|
|
|
{
|
|
|
|
Width = this.backBuffer.Description.Width,
|
|
|
|
Height = this.backBuffer.Description.Height,
|
|
|
|
MipLevels = 1,
|
|
|
|
ArraySize = 1,
|
|
|
|
Format = depthFormat,
|
|
|
|
SampleDescription = new SampleDescription(1, 0),
|
2012-09-06 09:58:13 +00:00
|
|
|
Usage = Dx10.ResourceUsage.Default,
|
|
|
|
BindFlags = Dx10.BindFlags.DepthStencil,
|
|
|
|
CpuAccessFlags = Dx10.CpuAccessFlags.None,
|
|
|
|
OptionFlags = Dx10.ResourceOptionFlags.None
|
2011-12-09 08:46:25 +00:00
|
|
|
};
|
2012-09-06 09:58:13 +00:00
|
|
|
this.depthStencilBuffer = new Dx10.Texture2D(device, depthStencilTextureDesc);
|
2011-12-09 08:46:25 +00:00
|
|
|
|
2012-09-06 09:58:13 +00:00
|
|
|
this.depthStencilView = new Dx10.DepthStencilView(device, this.depthStencilBuffer);
|
2011-12-09 08:46:25 +00:00
|
|
|
|
2012-09-06 09:58:13 +00:00
|
|
|
// this workaround is working but maybe not the best solution to issue #472
|
|
|
|
Clear(ClearOptions.DepthBuffer | ClearOptions.Stencil, Vector4.Zero, 1.0f, 0);
|
2011-11-16 14:27:53 +00:00
|
|
|
}
|
2012-09-06 09:58:13 +00:00
|
|
|
#endregion
|
2011-11-16 14:27:53 +00:00
|
|
|
|
|
|
|
#region Clear
|
|
|
|
public void Clear(ref Color color)
|
|
|
|
{
|
|
|
|
uint newClearColor = color.PackedValue;
|
|
|
|
if (lastClearColor != newClearColor)
|
|
|
|
{
|
|
|
|
lastClearColor = newClearColor;
|
|
|
|
clearColor.Red = color.R * ColorMultiplier;
|
|
|
|
clearColor.Green = color.G * ColorMultiplier;
|
|
|
|
clearColor.Blue = color.B * ColorMultiplier;
|
|
|
|
clearColor.Alpha = color.A * ColorMultiplier;
|
|
|
|
}
|
|
|
|
|
2012-08-10 08:38:01 +00:00
|
|
|
if (this.renderTargetView[0] == null)
|
|
|
|
{
|
|
|
|
this.device.ClearRenderTargetView(this.renderView, this.clearColor);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
for (int i = 0; i < this.renderTargetView.Length; i++)
|
|
|
|
{
|
|
|
|
if (this.renderTargetView[i] == null)
|
|
|
|
{
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
this.device.ClearRenderTargetView(this.renderTargetView[i], this.clearColor);
|
|
|
|
}
|
|
|
|
}
|
2011-11-16 14:27:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
public void Clear(ClearOptions options, Vector4 color, float depth, int stencil)
|
|
|
|
{
|
|
|
|
if ((options & ClearOptions.Target) == ClearOptions.Target)
|
|
|
|
{
|
|
|
|
// Clear a RenderTarget (or BackBuffer)
|
|
|
|
|
|
|
|
this.clearColor.Red = color.X;
|
|
|
|
this.clearColor.Green = color.Y;
|
|
|
|
this.clearColor.Blue = color.Z;
|
|
|
|
this.clearColor.Alpha = color.W;
|
2011-11-28 16:06:52 +00:00
|
|
|
this.lastClearColor = 0;
|
2011-11-16 14:27:53 +00:00
|
|
|
|
2012-08-10 08:38:01 +00:00
|
|
|
if (this.renderTargetView[0] == null)
|
|
|
|
{
|
|
|
|
this.device.ClearRenderTargetView(this.renderView, this.clearColor);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
for (int i = 0; i < this.renderTargetView.Length; i++)
|
|
|
|
{
|
|
|
|
if (this.renderTargetView[i] == null)
|
|
|
|
{
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
this.device.ClearRenderTargetView(this.renderTargetView[i], this.clearColor);
|
|
|
|
}
|
|
|
|
}
|
2011-11-16 14:27:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (this.depthStencilView != null)
|
|
|
|
{
|
|
|
|
if ((options | ClearOptions.Stencil | ClearOptions.DepthBuffer) == options)
|
|
|
|
{
|
|
|
|
// Clear the stencil buffer
|
2012-09-06 09:58:13 +00:00
|
|
|
device.ClearDepthStencilView(this.depthStencilView, Dx10.DepthStencilClearFlags.Depth |
|
|
|
|
Dx10.DepthStencilClearFlags.Stencil, depth, (byte)stencil);
|
2011-11-16 14:27:53 +00:00
|
|
|
}
|
|
|
|
else if ((options | ClearOptions.Stencil) == options)
|
|
|
|
{
|
2012-09-06 09:58:13 +00:00
|
|
|
device.ClearDepthStencilView(this.depthStencilView, Dx10.DepthStencilClearFlags.Stencil, depth,
|
|
|
|
(byte)stencil);
|
2011-11-16 14:27:53 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2012-09-06 09:58:13 +00:00
|
|
|
device.ClearDepthStencilView(this.depthStencilView, Dx10.DepthStencilClearFlags.Depth, depth, (byte)stencil);
|
2011-11-16 14:27:53 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endregion
|
|
|
|
|
2011-11-30 16:03:51 +00:00
|
|
|
#region Present
|
|
|
|
public void Present()
|
2011-11-16 14:27:53 +00:00
|
|
|
{
|
2012-09-06 09:58:13 +00:00
|
|
|
swapChain.Present(VSync ? 1 : 0, PresentFlags.None);
|
2011-11-16 14:27:53 +00:00
|
|
|
}
|
2012-09-06 09:58:13 +00:00
|
|
|
#endregion
|
2011-11-16 14:27:53 +00:00
|
|
|
|
2012-09-06 09:58:13 +00:00
|
|
|
#region DrawIndexedPrimitives
|
|
|
|
public void DrawIndexedPrimitives(PrimitiveType primitiveType, int baseVertex, int minVertexIndex, int numVertices,
|
|
|
|
int startIndex, int primitiveCount)
|
|
|
|
{
|
|
|
|
Dx10.EffectTechnique technique = SetupEffectForDraw();
|
2012-09-07 09:48:45 +00:00
|
|
|
int vertexCount = BaseFormatConverter.CalculateVertexCount(primitiveType, primitiveCount);
|
2011-11-30 16:03:51 +00:00
|
|
|
|
2012-09-07 09:48:45 +00:00
|
|
|
device.InputAssembler.PrimitiveTopology = BaseFormatConverter.Translate(primitiveType);
|
2011-11-30 16:03:51 +00:00
|
|
|
device.Rasterizer.SetViewports(currentViewport);
|
|
|
|
device.OutputMerger.SetTargets(this.depthStencilView, this.renderView);
|
|
|
|
|
|
|
|
for (int i = 0; i < technique.Description.PassCount; ++i)
|
2012-09-06 09:58:13 +00:00
|
|
|
{
|
|
|
|
technique.GetPassByIndex(i).Apply();
|
|
|
|
device.DrawIndexed(vertexCount, startIndex, baseVertex);
|
2012-09-08 09:07:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
device.InputAssembler.InputLayout.Dispose();
|
|
|
|
device.InputAssembler.InputLayout = null;
|
2012-09-06 09:58:13 +00:00
|
|
|
}
|
|
|
|
#endregion
|
2011-11-30 16:03:51 +00:00
|
|
|
|
2012-09-06 09:58:13 +00:00
|
|
|
#region DrawPrimitives
|
|
|
|
public void DrawPrimitives(PrimitiveType primitiveType, int vertexOffset, int primitiveCount)
|
|
|
|
{
|
|
|
|
Dx10.EffectTechnique technique = SetupEffectForDraw();
|
2011-11-30 16:03:51 +00:00
|
|
|
|
2012-09-07 09:48:45 +00:00
|
|
|
device.InputAssembler.PrimitiveTopology = BaseFormatConverter.Translate(primitiveType);
|
2011-11-30 16:03:51 +00:00
|
|
|
device.Rasterizer.SetViewports(currentViewport);
|
|
|
|
device.OutputMerger.SetTargets(this.depthStencilView, this.renderView);
|
|
|
|
|
|
|
|
for (int i = 0; i < technique.Description.PassCount; ++i)
|
2012-09-06 09:58:13 +00:00
|
|
|
{
|
|
|
|
technique.GetPassByIndex(i).Apply();
|
2011-11-30 16:03:51 +00:00
|
|
|
device.Draw(primitiveCount, vertexOffset);
|
|
|
|
}
|
2012-09-08 09:07:23 +00:00
|
|
|
|
|
|
|
device.InputAssembler.InputLayout.Dispose();
|
|
|
|
device.InputAssembler.InputLayout = null;
|
2011-11-30 16:03:51 +00:00
|
|
|
}
|
2012-09-06 09:58:13 +00:00
|
|
|
#endregion
|
2011-11-30 16:03:51 +00:00
|
|
|
|
|
|
|
#region DrawInstancedPrimitives
|
2012-09-06 09:58:13 +00:00
|
|
|
public void DrawInstancedPrimitives(PrimitiveType primitiveType, int baseVertex, int minVertexIndex, int numVertices,
|
|
|
|
int startIndex, int primitiveCount, int instanceCount)
|
2011-11-30 16:03:51 +00:00
|
|
|
{
|
2012-01-19 05:57:54 +00:00
|
|
|
device.DrawIndexedInstanced(numVertices, instanceCount, startIndex, baseVertex, 0);
|
2011-11-30 16:03:51 +00:00
|
|
|
}
|
2012-09-06 09:58:13 +00:00
|
|
|
#endregion
|
2011-11-30 16:03:51 +00:00
|
|
|
|
|
|
|
#region DrawUserIndexedPrimitives<T>
|
2012-09-06 09:58:13 +00:00
|
|
|
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
|
2011-11-30 16:03:51 +00:00
|
|
|
{
|
2012-01-17 05:14:18 +00:00
|
|
|
int vertexCount = vertexData.Length;
|
|
|
|
int indexCount = indexData.Length;
|
|
|
|
VertexBuffer_DX10 vb10 = new VertexBuffer_DX10(this.device, vertexDeclaration, vertexCount, BufferUsage.None);
|
|
|
|
vb10.SetData<T>(null, vertexData);
|
|
|
|
|
2012-09-06 09:58:13 +00:00
|
|
|
Dx10.VertexBufferBinding nativeVertexBufferBindings = new Dx10.VertexBufferBinding(vb10.NativeBuffer,
|
|
|
|
vertexDeclaration.VertexStride, 0);
|
2012-01-17 05:14:18 +00:00
|
|
|
|
|
|
|
device.InputAssembler.SetVertexBuffers(0, nativeVertexBufferBindings);
|
|
|
|
|
|
|
|
IndexBuffer_DX10 idx10 = new IndexBuffer_DX10(this.device, indexFormat, indexCount, BufferUsage.None);
|
2012-01-19 05:57:54 +00:00
|
|
|
if (indexData.GetType() == typeof(Int16[]))
|
|
|
|
idx10.SetData<short>(null, (short[])indexData);
|
|
|
|
else
|
|
|
|
idx10.SetData<int>(null, (int[])indexData);
|
2012-01-17 05:14:18 +00:00
|
|
|
|
|
|
|
DrawIndexedPrimitives(primitiveType, 0, vertexOffset, numVertices, indexOffset, primitiveCount);
|
2011-11-30 16:03:51 +00:00
|
|
|
}
|
2012-09-06 09:58:13 +00:00
|
|
|
#endregion
|
2011-11-30 16:03:51 +00:00
|
|
|
|
|
|
|
#region DrawUserPrimitives<T>
|
2012-09-06 09:58:13 +00:00
|
|
|
public void DrawUserPrimitives<T>(PrimitiveType primitiveType, T[] vertexData, int vertexOffset, int primitiveCount,
|
|
|
|
VertexDeclaration vertexDeclaration) where T : struct, IVertexType
|
2011-11-30 16:03:51 +00:00
|
|
|
{
|
2012-01-09 18:09:10 +00:00
|
|
|
int vertexCount = vertexData.Length;
|
|
|
|
VertexBuffer_DX10 vb10 = new VertexBuffer_DX10(this.device, vertexDeclaration, vertexCount, BufferUsage.None);
|
|
|
|
vb10.SetData<T>(null, vertexData);
|
|
|
|
|
2012-09-06 09:58:13 +00:00
|
|
|
Dx10.VertexBufferBinding nativeVertexBufferBindings = new Dx10.VertexBufferBinding(vb10.NativeBuffer,
|
|
|
|
vertexDeclaration.VertexStride, 0);
|
2012-01-09 18:09:10 +00:00
|
|
|
|
|
|
|
device.InputAssembler.SetVertexBuffers(0, nativeVertexBufferBindings);
|
|
|
|
|
2012-09-06 09:58:13 +00:00
|
|
|
//TODO: check for currentEffect null and throw exception
|
|
|
|
// TODO: check for null's and throw exceptions
|
|
|
|
// TODO: get the correct pass index!
|
|
|
|
var technique = currentEffect.GetCurrentTechnique().NativeTechnique;
|
|
|
|
var pass = technique.GetPassByIndex(0);
|
|
|
|
var layout = CreateInputLayout(device, pass.Description.Signature, vertexDeclaration);
|
2012-08-10 08:38:01 +00:00
|
|
|
|
|
|
|
device.InputAssembler.InputLayout = layout;
|
|
|
|
// Prepare All the stages
|
2012-09-07 09:48:45 +00:00
|
|
|
device.InputAssembler.PrimitiveTopology = BaseFormatConverter.Translate(primitiveType);
|
2012-08-10 08:38:01 +00:00
|
|
|
device.Rasterizer.SetViewports(currentViewport);
|
|
|
|
|
|
|
|
//device.OutputMerger.SetTargets(this.depthStencilView, this.renderView);
|
|
|
|
|
|
|
|
for (int i = 0; i < technique.Description.PassCount; ++i)
|
|
|
|
{
|
|
|
|
pass.Apply();
|
|
|
|
device.Draw(primitiveCount, vertexOffset);
|
|
|
|
}
|
2012-09-08 09:07:23 +00:00
|
|
|
|
|
|
|
device.InputAssembler.InputLayout.Dispose();
|
|
|
|
device.InputAssembler.InputLayout = null;
|
2011-11-30 16:03:51 +00:00
|
|
|
}
|
2012-09-06 09:58:13 +00:00
|
|
|
#endregion
|
2011-11-30 16:03:51 +00:00
|
|
|
|
2012-09-06 09:58:13 +00:00
|
|
|
#region SetupEffectForDraw
|
|
|
|
private Dx10.EffectTechnique SetupEffectForDraw()
|
2011-11-16 14:27:53 +00:00
|
|
|
{
|
2012-09-06 09:58:13 +00:00
|
|
|
//TODO: check for currentEffect null and throw exception
|
2012-09-05 19:50:10 +00:00
|
|
|
// TODO: check for null's and throw exceptions
|
|
|
|
// TODO: get the correct pass index!
|
2012-09-06 09:58:13 +00:00
|
|
|
var technique = currentEffect.GetCurrentTechnique().NativeTechnique;
|
|
|
|
var pass = technique.GetPassByIndex(0);
|
|
|
|
SetupInputLayout(pass.Description.Signature);
|
|
|
|
|
|
|
|
return technique;
|
2011-11-16 14:27:53 +00:00
|
|
|
}
|
2012-09-06 09:58:13 +00:00
|
|
|
#endregion
|
2011-11-16 14:27:53 +00:00
|
|
|
|
2012-09-06 09:58:13 +00:00
|
|
|
#region SetupInputLayout
|
|
|
|
private void SetupInputLayout(ShaderBytecode passSignature)
|
2011-11-16 14:27:53 +00:00
|
|
|
{
|
2012-08-10 08:38:01 +00:00
|
|
|
if (currentVertexBuffer == null)
|
|
|
|
throw new ArgumentNullException("passSignature");
|
|
|
|
|
2011-11-16 14:27:53 +00:00
|
|
|
VertexDeclaration vertexDeclaration = currentVertexBuffer.VertexDeclaration;
|
|
|
|
var layout = CreateInputLayout(device, passSignature, vertexDeclaration);
|
|
|
|
|
|
|
|
device.InputAssembler.InputLayout = layout;
|
|
|
|
}
|
2012-09-06 09:58:13 +00:00
|
|
|
#endregion
|
|
|
|
|
|
|
|
#region SetIndexBuffer
|
2011-11-16 14:27:53 +00:00
|
|
|
public void SetIndexBuffer(IndexBuffer indexBuffer)
|
|
|
|
{
|
|
|
|
if (indexBuffer == null)
|
|
|
|
{
|
|
|
|
throw new ArgumentNullException("indexBuffer");
|
|
|
|
}
|
|
|
|
|
|
|
|
this.currentIndexBuffer = indexBuffer;
|
|
|
|
|
|
|
|
IndexBuffer_DX10 nativeIndexBuffer = indexBuffer.NativeIndexBuffer as IndexBuffer_DX10;
|
|
|
|
|
|
|
|
if (nativeIndexBuffer != null)
|
|
|
|
{
|
2012-09-07 09:48:45 +00:00
|
|
|
device.InputAssembler.SetIndexBuffer(nativeIndexBuffer.NativeBuffer,
|
|
|
|
BaseFormatConverter.Translate(indexBuffer.IndexElementSize), 0);
|
2011-11-16 14:27:53 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
throw new Exception("couldn't fetch native DirectX10 IndexBuffer");
|
|
|
|
}
|
|
|
|
}
|
2012-09-06 09:58:13 +00:00
|
|
|
#endregion
|
2011-11-16 14:27:53 +00:00
|
|
|
|
2012-08-29 10:48:21 +00:00
|
|
|
#if XNAEXT
|
2012-09-06 09:58:13 +00:00
|
|
|
#region SetConstantBuffer
|
2012-08-29 10:48:21 +00:00
|
|
|
public void SetConstantBuffer(int slot, ANX.Framework.Graphics.ConstantBuffer constantBuffer)
|
|
|
|
{
|
|
|
|
if (constantBuffer == null)
|
|
|
|
throw new ArgumentNullException("constantBuffer");
|
|
|
|
|
|
|
|
throw new NotImplementedException();
|
|
|
|
}
|
2012-09-06 09:58:13 +00:00
|
|
|
#endregion
|
2012-08-29 10:48:21 +00:00
|
|
|
#endif
|
|
|
|
|
2012-09-06 09:58:13 +00:00
|
|
|
#region SetVertexBuffers
|
|
|
|
public void SetVertexBuffers(VertexBufferBinding[] vertexBuffers)
|
2011-11-16 14:27:53 +00:00
|
|
|
{
|
|
|
|
if (vertexBuffers == null)
|
|
|
|
throw new ArgumentNullException("vertexBuffers");
|
|
|
|
|
|
|
|
this.currentVertexBuffer = vertexBuffers[0].VertexBuffer; //TODO: hmmmmm, not nice :-)
|
|
|
|
|
2012-09-06 09:58:13 +00:00
|
|
|
Dx10.VertexBufferBinding[] nativeVertexBufferBindings =
|
|
|
|
new Dx10.VertexBufferBinding[vertexBuffers.Length];
|
2011-11-16 14:27:53 +00:00
|
|
|
for (int i = 0; i < vertexBuffers.Length; i++)
|
|
|
|
{
|
|
|
|
ANX.Framework.Graphics.VertexBufferBinding anxVertexBufferBinding = vertexBuffers[i];
|
2012-09-05 19:50:10 +00:00
|
|
|
var nativeVertexBuffer = anxVertexBufferBinding.VertexBuffer.NativeVertexBuffer as VertexBuffer_DX10;
|
2011-11-16 14:27:53 +00:00
|
|
|
|
|
|
|
if (nativeVertexBuffer != null)
|
|
|
|
{
|
2012-09-06 09:58:13 +00:00
|
|
|
nativeVertexBufferBindings[i] = new Dx10.VertexBufferBinding(nativeVertexBuffer.NativeBuffer,
|
2012-09-05 19:50:10 +00:00
|
|
|
anxVertexBufferBinding.VertexBuffer.VertexDeclaration.VertexStride, anxVertexBufferBinding.VertexOffset);
|
2011-11-16 14:27:53 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
throw new Exception("couldn't fetch native DirectX10 VertexBuffer");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
device.InputAssembler.SetVertexBuffers(0, nativeVertexBufferBindings);
|
2012-09-06 09:58:13 +00:00
|
|
|
}
|
|
|
|
#endregion
|
2011-11-16 14:27:53 +00:00
|
|
|
|
2012-09-06 09:58:13 +00:00
|
|
|
#region SetViewport
|
|
|
|
public void SetViewport(Viewport viewport)
|
2011-11-16 14:27:53 +00:00
|
|
|
{
|
2012-09-06 09:58:13 +00:00
|
|
|
this.currentViewport = new Dx10.Viewport(viewport.X, viewport.Y, viewport.Width, viewport.Height,
|
2012-09-05 19:50:10 +00:00
|
|
|
viewport.MinDepth, viewport.MaxDepth);
|
2011-11-16 14:27:53 +00:00
|
|
|
}
|
2012-09-06 09:58:13 +00:00
|
|
|
#endregion
|
2011-11-16 14:27:53 +00:00
|
|
|
|
2012-09-06 09:58:13 +00:00
|
|
|
#region CreateInputLayout
|
|
|
|
/// <summary>
|
2012-09-05 19:50:10 +00:00
|
|
|
/// This method creates a InputLayout which is needed by DirectX 10 for rendering primitives.
|
|
|
|
/// The VertexDeclaration of ANX/XNA needs to be mapped to the DirectX 10 types.
|
2011-11-16 14:27:53 +00:00
|
|
|
/// </summary>
|
2012-09-06 09:58:13 +00:00
|
|
|
private Dx10.InputLayout CreateInputLayout(Dx10.Device device, ShaderBytecode passSignature,
|
|
|
|
VertexDeclaration vertexDeclaration)
|
2011-11-16 14:27:53 +00:00
|
|
|
{
|
|
|
|
VertexElement[] vertexElements = vertexDeclaration.GetVertexElements();
|
|
|
|
int elementCount = vertexElements.Length;
|
2012-09-06 09:58:13 +00:00
|
|
|
var inputElements = new Dx10.InputElement[elementCount];
|
2011-11-16 14:27:53 +00:00
|
|
|
|
|
|
|
for (int i = 0; i < elementCount; i++)
|
|
|
|
inputElements[i] = CreateInputElementFromVertexElement(vertexElements[i]);
|
|
|
|
|
2012-09-06 09:58:13 +00:00
|
|
|
return new Dx10.InputLayout(device, passSignature, inputElements);
|
|
|
|
}
|
|
|
|
#endregion
|
2011-11-16 14:27:53 +00:00
|
|
|
|
2012-09-06 09:58:13 +00:00
|
|
|
#region CreateInputElementFromVertexElement
|
|
|
|
private Dx10.InputElement CreateInputElementFromVertexElement(VertexElement vertexElement)
|
2011-11-16 14:27:53 +00:00
|
|
|
{
|
2012-09-07 09:48:45 +00:00
|
|
|
string elementName = BaseFormatConverter.Translate(ref vertexElement);
|
2012-09-05 19:50:10 +00:00
|
|
|
Format elementFormat = ConvertVertexElementFormat(vertexElement.VertexElementFormat);
|
2012-09-06 09:58:13 +00:00
|
|
|
return new Dx10.InputElement(elementName, vertexElement.UsageIndex, elementFormat, vertexElement.Offset, 0);
|
|
|
|
}
|
|
|
|
#endregion
|
2011-11-16 14:27:53 +00:00
|
|
|
|
2012-09-06 09:58:13 +00:00
|
|
|
#region ConvertVertexElementFormat
|
2012-09-05 19:50:10 +00:00
|
|
|
private Format ConvertVertexElementFormat(VertexElementFormat format)
|
|
|
|
{
|
|
|
|
switch (format)
|
|
|
|
{
|
|
|
|
case VertexElementFormat.Vector2:
|
|
|
|
return Format.R32G32_Float;
|
|
|
|
case VertexElementFormat.Vector3:
|
|
|
|
return Format.R32G32B32_Float;
|
|
|
|
case VertexElementFormat.Vector4:
|
|
|
|
return Format.R32G32B32A32_Float;
|
|
|
|
case VertexElementFormat.Color:
|
|
|
|
return Format.R8G8B8A8_UNorm;
|
|
|
|
case VertexElementFormat.Single:
|
|
|
|
return Format.R32_Float;
|
|
|
|
// TODO: validate
|
|
|
|
case VertexElementFormat.Short2:
|
|
|
|
return Format.R16G16_SInt;
|
|
|
|
case VertexElementFormat.Short4:
|
|
|
|
return Format.R16G16B16A16_SInt;
|
|
|
|
}
|
|
|
|
|
|
|
|
throw new Exception("Can't map '" + format + "' to DXGI.Format in Dx10 CreateInputElementFromVertexElement.");
|
|
|
|
}
|
2012-09-06 09:58:13 +00:00
|
|
|
#endregion
|
2012-09-05 19:50:10 +00:00
|
|
|
|
|
|
|
#region SetRenderTargets
|
|
|
|
public void SetRenderTargets(params RenderTargetBinding[] renderTargets)
|
2011-11-16 14:27:53 +00:00
|
|
|
{
|
2011-11-28 16:06:52 +00:00
|
|
|
if (renderTargets == null)
|
|
|
|
{
|
|
|
|
// reset the RenderTarget to backbuffer
|
2012-08-10 08:38:01 +00:00
|
|
|
for (int i = 0; i < renderTargetView.Length; i++)
|
2011-11-28 16:06:52 +00:00
|
|
|
{
|
2012-08-10 08:38:01 +00:00
|
|
|
if (renderTargetView[i] != null)
|
|
|
|
{
|
|
|
|
renderTargetView[i].Dispose();
|
|
|
|
renderTargetView[i] = null;
|
|
|
|
}
|
2011-11-28 16:06:52 +00:00
|
|
|
}
|
2011-12-02 13:01:57 +00:00
|
|
|
|
2012-09-06 09:58:13 +00:00
|
|
|
device.OutputMerger.SetRenderTargets(1, new Dx10.RenderTargetView[] { this.renderView }, this.depthStencilView);
|
2011-12-02 13:01:57 +00:00
|
|
|
device.OutputMerger.SetTargets(this.depthStencilView, this.renderView);
|
2011-11-28 16:06:52 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2012-08-10 08:38:01 +00:00
|
|
|
int renderTargetCount = renderTargets.Length;
|
|
|
|
if (this.renderTargetView.Length != renderTargetCount)
|
2011-11-28 16:06:52 +00:00
|
|
|
{
|
2012-08-10 08:38:01 +00:00
|
|
|
for (int i = 0; i < renderTargetView.Length; i++)
|
2011-11-28 16:06:52 +00:00
|
|
|
{
|
2012-08-10 08:38:01 +00:00
|
|
|
if (renderTargetView[i] != null)
|
2011-11-28 16:06:52 +00:00
|
|
|
{
|
2012-08-10 08:38:01 +00:00
|
|
|
renderTargetView[i].Dispose();
|
|
|
|
renderTargetView[i] = null;
|
2011-11-28 16:06:52 +00:00
|
|
|
}
|
|
|
|
}
|
2012-08-10 08:38:01 +00:00
|
|
|
|
2012-09-06 09:58:13 +00:00
|
|
|
this.renderTargetView = new Dx10.RenderTargetView[renderTargetCount];
|
2011-11-28 16:06:52 +00:00
|
|
|
}
|
2012-08-10 08:38:01 +00:00
|
|
|
|
|
|
|
for (int i = 0; i < renderTargetCount; i++)
|
2011-11-28 16:06:52 +00:00
|
|
|
{
|
2012-08-10 08:38:01 +00:00
|
|
|
RenderTarget2D renderTarget = renderTargets[i].RenderTarget as RenderTarget2D;
|
|
|
|
if (renderTarget != null)
|
|
|
|
{
|
|
|
|
RenderTarget2D_DX10 nativeRenderTarget = renderTarget.NativeRenderTarget as RenderTarget2D_DX10;
|
|
|
|
|
|
|
|
if (renderTargetView[i] != null)
|
|
|
|
{
|
|
|
|
renderTargetView[i].Dispose();
|
|
|
|
}
|
|
|
|
|
2012-09-06 09:58:13 +00:00
|
|
|
renderTargetView[i] = new Dx10.RenderTargetView(device, ((Texture2D_DX10)nativeRenderTarget).NativeShaderResourceView.Resource);
|
2012-08-10 08:38:01 +00:00
|
|
|
}
|
2011-11-28 16:06:52 +00:00
|
|
|
}
|
2012-08-10 08:38:01 +00:00
|
|
|
|
|
|
|
device.OutputMerger.SetRenderTargets(renderTargetCount, renderTargetView, this.depthStencilView);
|
|
|
|
device.OutputMerger.SetTargets(this.depthStencilView, this.renderTargetView);
|
|
|
|
|
|
|
|
//if (renderTargets.Length == 1)
|
|
|
|
//{
|
|
|
|
// RenderTarget2D renderTarget = renderTargets[0].RenderTarget as RenderTarget2D;
|
|
|
|
// RenderTarget2D_DX10 nativeRenderTarget = renderTarget.NativeRenderTarget as RenderTarget2D_DX10;
|
|
|
|
// if (renderTarget != null)
|
|
|
|
// {
|
|
|
|
// if (renderTargetView != null)
|
|
|
|
// {
|
|
|
|
// renderTargetView.Dispose();
|
|
|
|
// renderTargetView = null;
|
|
|
|
// }
|
|
|
|
// this.renderTargetView = new RenderTargetView(device, ((Texture2D_DX10)nativeRenderTarget).NativeShaderResourceView.Resource);
|
|
|
|
// DepthStencilView depthStencilView = null;
|
|
|
|
// device.OutputMerger.SetRenderTargets(1, new RenderTargetView[] { this.renderTargetView }, depthStencilView);
|
|
|
|
// }
|
|
|
|
//}
|
|
|
|
//else
|
|
|
|
//{
|
|
|
|
// throw new NotImplementedException("handling of multiple RenderTargets are not yet implemented");
|
|
|
|
//}
|
2011-11-28 16:06:52 +00:00
|
|
|
}
|
2011-11-16 14:27:53 +00:00
|
|
|
}
|
2012-09-05 19:50:10 +00:00
|
|
|
#endregion
|
2011-11-16 14:27:53 +00:00
|
|
|
|
2012-09-06 09:58:13 +00:00
|
|
|
#region GetBackBufferData (TODO)
|
2012-09-05 19:50:10 +00:00
|
|
|
public void GetBackBufferData<T>(Rectangle? rect, T[] data, int startIndex, int elementCount) where T : struct
|
2011-11-16 14:27:53 +00:00
|
|
|
{
|
|
|
|
throw new NotImplementedException();
|
|
|
|
}
|
|
|
|
|
|
|
|
public void GetBackBufferData<T>(T[] data) where T : struct
|
|
|
|
{
|
|
|
|
throw new NotImplementedException();
|
|
|
|
}
|
|
|
|
|
|
|
|
public void GetBackBufferData<T>(T[] data, int startIndex, int elementCount) where T : struct
|
|
|
|
{
|
|
|
|
throw new NotImplementedException();
|
|
|
|
}
|
2012-09-05 19:50:10 +00:00
|
|
|
#endregion
|
2011-11-16 14:27:53 +00:00
|
|
|
|
2012-09-05 19:50:10 +00:00
|
|
|
#region ResizeBuffers
|
|
|
|
public void ResizeBuffers(PresentationParameters presentationParameters)
|
2011-11-16 14:27:53 +00:00
|
|
|
{
|
|
|
|
if (swapChain != null)
|
|
|
|
{
|
|
|
|
renderView.Dispose();
|
|
|
|
backBuffer.Dispose();
|
|
|
|
|
|
|
|
//TODO: handle format
|
|
|
|
|
2012-09-05 19:50:10 +00:00
|
|
|
swapChain.ResizeBuffers(swapChain.Description.BufferCount, presentationParameters.BackBufferWidth,
|
|
|
|
presentationParameters.BackBufferHeight, Format.R8G8B8A8_UNorm, swapChain.Description.Flags);
|
2011-11-16 14:27:53 +00:00
|
|
|
|
2012-09-06 09:58:13 +00:00
|
|
|
backBuffer = Dx10.Texture2D.FromSwapChain<Dx10.Texture2D>(swapChain, 0);
|
|
|
|
renderView = new Dx10.RenderTargetView(device, backBuffer);
|
2011-12-09 08:46:25 +00:00
|
|
|
|
2012-09-06 09:58:13 +00:00
|
|
|
currentViewport = new Dx10.Viewport(0, 0, presentationParameters.BackBufferWidth,
|
2012-09-05 19:50:10 +00:00
|
|
|
presentationParameters.BackBufferHeight);
|
2011-12-09 08:46:25 +00:00
|
|
|
|
|
|
|
// create the depth stencil buffer
|
2012-09-07 09:48:45 +00:00
|
|
|
Format depthFormat = BaseFormatConverter.Translate(presentationParameters.DepthStencilFormat);
|
2011-12-09 08:46:25 +00:00
|
|
|
if (depthFormat != Format.Unknown)
|
|
|
|
CreateDepthStencilBuffer(depthFormat);
|
2011-11-16 14:27:53 +00:00
|
|
|
}
|
|
|
|
|
2012-09-06 09:58:13 +00:00
|
|
|
WindowHelper.ResizeRenderWindow(presentationParameters);
|
2011-11-30 13:58:55 +00:00
|
|
|
}
|
2012-09-05 19:50:10 +00:00
|
|
|
#endregion
|
2011-11-30 13:58:55 +00:00
|
|
|
|
2012-09-05 19:50:10 +00:00
|
|
|
#region Dispose
|
|
|
|
public void Dispose()
|
2011-11-22 14:51:30 +00:00
|
|
|
{
|
2012-08-10 08:38:01 +00:00
|
|
|
for (int i = 0; i < renderTargetView.Length; i++)
|
2011-11-28 16:06:52 +00:00
|
|
|
{
|
2012-08-10 08:38:01 +00:00
|
|
|
if (renderTargetView[i] != null)
|
|
|
|
{
|
|
|
|
renderTargetView[i].Dispose();
|
|
|
|
renderTargetView[i] = null;
|
|
|
|
}
|
2011-11-28 16:06:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (swapChain != null)
|
|
|
|
{
|
|
|
|
renderView.Dispose();
|
|
|
|
renderView = null;
|
|
|
|
|
|
|
|
backBuffer.Dispose();
|
|
|
|
backBuffer = null;
|
|
|
|
|
|
|
|
swapChain.Dispose();
|
|
|
|
swapChain = null;
|
|
|
|
}
|
|
|
|
|
2011-11-29 13:05:37 +00:00
|
|
|
if (this.depthStencilView != null)
|
|
|
|
{
|
|
|
|
this.depthStencilBuffer.Dispose();
|
|
|
|
this.depthStencilBuffer = null;
|
|
|
|
|
|
|
|
this.depthStencilView.Dispose();
|
|
|
|
this.depthStencilView = null;
|
|
|
|
}
|
|
|
|
|
2011-11-28 16:06:52 +00:00
|
|
|
//TODO: dispose everything else
|
2012-09-05 19:50:10 +00:00
|
|
|
}
|
|
|
|
#endregion
|
|
|
|
}
|
2011-11-16 14:27:53 +00:00
|
|
|
}
|