251 lines
8.9 KiB
C#
Raw Normal View History

//#define DIRECTX_DEBUG_LAYER
#region Using Statements
using System;
using ANX.Framework;
using ANX.Framework.Graphics;
using SharpDX.DXGI;
#endregion
// 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
#if DX10
using SharpDX.Direct3D10;
namespace ANX.RenderSystem.Windows.DX10
#endif
#if DX11
using SharpDX.Direct3D11;
namespace ANX.RenderSystem.Windows.DX11
#endif
{
public partial class GraphicsDeviceDX
{
#region Private
protected SharpDX.DXGI.SwapChain swapChain;
protected Framework.Graphics.VertexBufferBinding[] currentVertexBuffer = new Framework.Graphics.VertexBufferBinding[0];
protected int currentVertexBufferCount;
protected IndexBuffer currentIndexBuffer;
private InputLayoutManager inputLayoutManager = new InputLayoutManager();
private InputLayout currentInputLayout = null;
#endregion
#region Public
public bool VSync { get; set; }
#endregion
#region Constructor
public GraphicsDeviceDX(PresentationParameters presentationParameters)
{
VSync = true;
CreateDevice(presentationParameters);
MakeWindowAssociationAndResize(presentationParameters);
CreateRenderView(presentationParameters);
}
#endregion
#region MakeWindowAssociationAndResize
protected void MakeWindowAssociationAndResize(PresentationParameters presentationParameters)
{
// Ignore all windows events
var factory = swapChain.GetParent<SharpDX.DXGI.Factory>();
factory.MakeWindowAssociation(presentationParameters.DeviceWindowHandle,
SharpDX.DXGI.WindowAssociationFlags.IgnoreAll);
WindowHelper.ResizeRenderWindow(presentationParameters);
SetViewport(0, 0, presentationParameters.BackBufferWidth, presentationParameters.BackBufferHeight, 0f, 1f);
}
#endregion
#region SetViewport
public void SetViewport(Viewport viewport)
{
SetViewport(viewport.X, viewport.Y, viewport.Width, viewport.Height, viewport.MinDepth, viewport.MaxDepth);
}
#endregion
#region ResizeBuffers
public void ResizeBuffers(PresentationParameters presentationParameters)
{
if (swapChain != null)
{
DisposeBackBuffer();
Format colorFormat = DxFormatConverter.Translate(presentationParameters.BackBufferFormat);
swapChain.ResizeBuffers(swapChain.Description.BufferCount, presentationParameters.BackBufferWidth,
presentationParameters.BackBufferHeight, colorFormat, swapChain.Description.Flags);
CreateRenderView(presentationParameters);
SetViewport(0, 0, presentationParameters.BackBufferWidth, presentationParameters.BackBufferHeight, 0f, 1f);
}
WindowHelper.ResizeRenderWindow(presentationParameters);
}
#endregion
public void DrawIndexedPrimitives(PrimitiveType primitiveType, int baseVertex, int minVertexIndex, int numVertices, int startIndex, int primitiveCount)
{
if (primitiveCount <= 0) throw new ArgumentOutOfRangeException("primitiveCount is less than or equal to zero. When drawing, at least one primitive must be drawn.");
if (this.currentVertexBufferCount == 0) throw new InvalidOperationException("you have to set a valid vertex buffer before drawing.");
int vertexCount = DxFormatConverter.CalculateVertexCount(primitiveType, primitiveCount);
SetupDraw(primitiveType);
nativeDevice.DrawIndexed(vertexCount, startIndex, baseVertex);
}
public void DrawPrimitives(PrimitiveType primitiveType, int vertexOffset, int primitiveCount)
{
int vertexCount = DxFormatConverter.CalculateVertexCount(primitiveType, primitiveCount);
SetupDraw(primitiveType);
nativeDevice.Draw(vertexCount, vertexOffset);
}
public void DrawInstancedPrimitives(PrimitiveType primitiveType, int baseVertex, int minVertexIndex, int numVertices,
int startIndex, int primitiveCount, int instanceCount)
{
int vertexCount = DxFormatConverter.CalculateVertexCount(primitiveType, primitiveCount);
SetupDraw(primitiveType);
nativeDevice.DrawIndexedInstanced(vertexCount, instanceCount, startIndex, baseVertex, 0);
}
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 indexCount = indexData.Length;
using (var vertexBuffer = new DynamicVertexBuffer(vertexDeclaration.GraphicsDevice, vertexDeclaration, vertexCount, BufferUsage.WriteOnly))
using (var indexBuffer = new DynamicIndexBuffer(vertexDeclaration.GraphicsDevice, indexFormat, indexCount, BufferUsage.WriteOnly))
{
vertexBuffer.SetData(vertexData);
this.SetVertexBuffers(new[] { new Framework.Graphics.VertexBufferBinding(vertexBuffer, vertexOffset) });
if (indexData.GetType() == typeof(Int16[]))
{
indexBuffer.SetData<short>((short[])indexData);
}
else
{
indexBuffer.SetData<int>((int[])indexData);
}
this.IndexBuffer = indexBuffer;
DrawIndexedPrimitives(primitiveType, 0, vertexOffset, numVertices, indexOffset, primitiveCount);
}
}
public void DrawUserPrimitives<T>(PrimitiveType primitiveType, T[] vertexData, int vertexOffset, int primitiveCount, VertexDeclaration vertexDeclaration) where T : struct, IVertexType
{
int vertexCount = vertexData.Length;
//TODO: use a shared vertexBuffer, instead of creating one on every call.
using (var vertexBuffer = new DynamicVertexBuffer(vertexDeclaration.GraphicsDevice, vertexDeclaration, vertexCount, BufferUsage.WriteOnly))
{
vertexBuffer.SetData(vertexData);
this.SetVertexBuffers(new[] { new Framework.Graphics.VertexBufferBinding(vertexBuffer, vertexOffset) });
SetupDraw(primitiveType);
nativeDevice.Draw(vertexCount, vertexOffset);
}
}
#region GetBackBufferData
public void GetBackBufferData<T>(Rectangle? rect, T[] data, int startIndex, int elementCount) where T : struct
{
this.backBuffer.GetData(0, rect, data, startIndex, elementCount);
}
public void GetBackBufferData<T>(T[] data) where T : struct
{
this.backBuffer.GetData(data);
}
public void GetBackBufferData<T>(T[] data, int startIndex, int elementCount) where T : struct
{
this.backBuffer.GetData(data, startIndex, elementCount);
}
#endregion
public IndexBuffer IndexBuffer
{
get
{
return this.currentIndexBuffer;
}
set
{
if (value == null)
throw new ArgumentNullException("indexBuffer");
if (this.currentIndexBuffer != value)
{
this.currentIndexBuffer = value;
DxIndexBuffer nativeIndexBuffer = value.NativeIndexBuffer as DxIndexBuffer;
if (nativeIndexBuffer != null)
{
nativeDevice.InputAssembler.SetIndexBuffer(nativeIndexBuffer.NativeBuffer, DxFormatConverter.Translate(value.IndexElementSize), 0);
}
else
{
throw new Exception("couldn't fetch native DirectX10 IndexBuffer");
}
}
}
}
#if XNAEXT
#region SetConstantBuffer (TODO)
public void SetConstantBuffer(int slot, ConstantBuffer constantBuffer)
{
if (constantBuffer == null)
throw new ArgumentNullException("constantBuffer");
throw new NotImplementedException();
}
#endregion
#endif
public void Dispose()
{
this.Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool diposeManaged)
{
if (swapChain != null)
{
DisposeBackBuffer();
swapChain.Dispose();
swapChain = null;
}
if (inputLayoutManager != null)
{
inputLayoutManager.Dispose();
inputLayoutManager = null;
}
//TODO: dispose everything else
}
}
}