2012-09-15 13:43:31 +00:00
#region Using Statements
2011-11-16 14:27:53 +00:00
using System ;
2012-09-22 11:17:36 +00:00
using System.Collections.Generic ;
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 SharpDX.D3DCompiler ;
using SharpDX.DXGI ;
2012-09-22 11:17:36 +00:00
using SharpDX.Direct3D10 ;
2012-09-15 13:43:31 +00:00
#endregion
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-09-15 13:43:31 +00:00
using Dx10 = SharpDX . Direct3D10 ;
2012-08-09 09:45:04 +00:00
namespace ANX.RenderSystem.Windows.DX10
2011-11-16 14:27:53 +00:00
{
2012-09-15 13:43:31 +00:00
public partial class GraphicsDeviceDX : INativeGraphicsDevice
2011-11-16 14:27:53 +00:00
{
2012-09-06 09:58:13 +00:00
#region Private
2012-09-15 13:43:31 +00:00
private Dx10 . Device nativeDevice ;
2012-09-06 09:58:13 +00:00
private Dx10 . RenderTargetView renderView ;
private Dx10 . RenderTargetView [ ] renderTargetView = new Dx10 . RenderTargetView [ 1 ] ;
private Dx10 . DepthStencilView depthStencilView ;
private Dx10 . Texture2D depthStencilBuffer ;
private Dx10 . Texture2D backBuffer ;
2012-09-15 13:43:31 +00:00
internal EffectDX currentEffect ;
2012-09-06 09:58:13 +00:00
#endregion
2012-09-08 10:37:41 +00:00
#region CreateDevice
2012-09-15 13:43:31 +00:00
protected void CreateDevice ( PresentationParameters presentationParameters )
2012-09-08 10:37:41 +00:00
{
var desc = new SwapChainDescription ( )
{
BufferCount = 1 ,
ModeDescription = new ModeDescription ( presentationParameters . BackBufferWidth ,
2012-09-06 09:58:13 +00:00
presentationParameters . BackBufferHeight , new Rational ( 60 , 1 ) ,
2012-09-15 13:43:31 +00:00
DxFormatConverter . Translate ( presentationParameters . BackBufferFormat ) ) ,
2012-09-08 10:37:41 +00:00
IsWindowed = true ,
OutputHandle = presentationParameters . DeviceWindowHandle ,
SampleDescription = new SampleDescription ( 1 , 0 ) ,
SwapEffect = SwapEffect . Discard ,
Usage = Usage . RenderTargetOutput
} ;
// http://msdn.microsoft.com/en-us/library/windows/desktop/bb205068(v=vs.85).aspx
var flags = IsDebugMode ? Dx10 . DeviceCreationFlags . Debug : Dx10 . DeviceCreationFlags . None ;
Dx10 . Device . CreateWithSwapChain ( Dx10 . DriverType . Hardware , flags , desc , out nativeDevice , out swapChain ) ;
}
#endregion
2011-11-16 14:27:53 +00:00
2012-09-08 10:37:41 +00:00
#region CreateRenderView
2012-09-15 13:43:31 +00:00
protected void CreateRenderView ( )
2012-09-08 10:37:41 +00:00
{
backBuffer = Dx10 . Texture2D . FromSwapChain < Dx10 . Texture2D > ( swapChain , 0 ) ;
renderView = new Dx10 . RenderTargetView ( nativeDevice , backBuffer ) ;
2012-09-28 13:05:38 +00:00
nativeDevice . OutputMerger . SetTargets ( this . depthStencilView , this . renderView ) ;
2012-09-08 10:37:41 +00:00
}
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
2012-09-29 09:42:27 +00:00
protected void CreateDepthStencilBuffer ( Format depthFormat , int width , int height , bool setAndClearTarget )
2011-12-09 08:46:25 +00:00
{
if ( this . depthStencilBuffer ! = null & &
this . depthStencilBuffer . Description . Format = = depthFormat & &
2012-09-29 09:42:27 +00:00
this . depthStencilBuffer . Description . Width = = width & &
this . depthStencilBuffer . Description . Height = = height )
2011-12-09 08:46:25 +00:00
{
// 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 ( 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
{
2012-09-29 09:42:27 +00:00
Width = width ,
Height = height ,
2011-12-09 08:46:25 +00:00
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-08 10:37:41 +00:00
this . depthStencilBuffer = new Dx10 . Texture2D ( nativeDevice , depthStencilTextureDesc ) ;
2011-12-09 08:46:25 +00:00
2012-09-08 10:37:41 +00:00
this . depthStencilView = new Dx10 . DepthStencilView ( nativeDevice , this . depthStencilBuffer ) ;
2011-12-09 08:46:25 +00:00
2012-09-29 09:42:27 +00:00
if ( setAndClearTarget )
{
nativeDevice . OutputMerger . SetTargets ( this . depthStencilView , this . renderView ) ;
// 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 )
{
2012-09-08 10:37:41 +00:00
UpdateClearColorIfNeeded ( ref color ) ;
2011-11-16 14:27:53 +00:00
2012-08-10 08:38:01 +00:00
if ( this . renderTargetView [ 0 ] = = null )
2012-09-08 10:37:41 +00:00
nativeDevice . ClearRenderTargetView ( this . renderView , this . clearColor ) ;
2012-08-10 08:38:01 +00:00
else
{
for ( int i = 0 ; i < this . renderTargetView . Length ; i + + )
{
if ( this . renderTargetView [ i ] = = null )
{
break ;
}
2012-09-08 10:37:41 +00:00
nativeDevice . ClearRenderTargetView ( this . renderTargetView [ i ] , this . clearColor ) ;
2012-08-10 08:38:01 +00:00
}
}
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 )
{
2012-09-08 10:37:41 +00:00
nativeDevice . ClearRenderTargetView ( this . renderView , this . clearColor ) ;
2012-08-10 08:38:01 +00:00
}
else
{
for ( int i = 0 ; i < this . renderTargetView . Length ; i + + )
{
if ( this . renderTargetView [ i ] = = null )
break ;
2012-09-08 10:37:41 +00:00
nativeDevice . ClearRenderTargetView ( this . renderTargetView [ i ] , this . clearColor ) ;
2012-08-10 08:38:01 +00:00
}
}
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-08 10:37:41 +00:00
nativeDevice . ClearDepthStencilView ( this . depthStencilView , Dx10 . DepthStencilClearFlags . Depth |
2012-09-06 09:58:13 +00:00
Dx10 . DepthStencilClearFlags . Stencil , depth , ( byte ) stencil ) ;
2011-11-16 14:27:53 +00:00
}
else if ( ( options | ClearOptions . Stencil ) = = options )
{
2012-09-08 10:37:41 +00:00
nativeDevice . ClearDepthStencilView ( this . depthStencilView , Dx10 . DepthStencilClearFlags . Stencil , depth ,
2012-09-06 09:58:13 +00:00
( byte ) stencil ) ;
2011-11-16 14:27:53 +00:00
}
else
{
2012-09-08 10:37:41 +00:00
nativeDevice . 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
2012-09-21 12:07:20 +00:00
public void DrawIndexedPrimitives ( PrimitiveType primitiveType , int baseVertex , int minVertexIndex , int numVertices , int startIndex , int primitiveCount , IndexBuffer indexBuffer )
2012-09-06 09:58:13 +00:00
{
2012-09-27 10:08:00 +00:00
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 . currentVertexBuffer = = null | | this . currentVertexBufferCount < = 0 ) throw new InvalidOperationException ( "you have to set a valid vertex buffer before drawing." ) ;
2012-09-06 09:58:13 +00:00
Dx10 . EffectTechnique technique = SetupEffectForDraw ( ) ;
2012-09-15 13:43:31 +00:00
int vertexCount = DxFormatConverter . CalculateVertexCount ( primitiveType , primitiveCount ) ;
2011-11-30 16:03:51 +00:00
2012-09-15 13:43:31 +00:00
nativeDevice . InputAssembler . PrimitiveTopology = DxFormatConverter . Translate ( primitiveType ) ;
2012-09-29 09:42:27 +00:00
//nativeDevice.Rasterizer.SetViewports(currentViewport);
2012-09-28 13:05:38 +00:00
//nativeDevice.OutputMerger.SetTargets(this.depthStencilView, this.renderView);
2011-11-30 16:03:51 +00:00
2012-09-21 12:07:20 +00:00
if ( indexBuffer ! = null )
{
SetIndexBuffer ( indexBuffer ) ;
}
2011-11-30 16:03:51 +00:00
for ( int i = 0 ; i < technique . Description . PassCount ; + + i )
2012-09-06 09:58:13 +00:00
{
technique . GetPassByIndex ( i ) . Apply ( ) ;
2012-09-08 10:37:41 +00:00
nativeDevice . DrawIndexed ( vertexCount , startIndex , baseVertex ) ;
2012-09-08 09:07:23 +00:00
}
2012-09-20 11:53:50 +00:00
nativeDevice . InputAssembler . InputLayout . Dispose ( ) ;
nativeDevice . 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 ( ) ;
2012-09-20 11:53:50 +00:00
int vertexCount = DxFormatConverter . CalculateVertexCount ( primitiveType , primitiveCount ) ;
2011-11-30 16:03:51 +00:00
2012-09-15 13:43:31 +00:00
nativeDevice . InputAssembler . PrimitiveTopology = DxFormatConverter . Translate ( primitiveType ) ;
2012-09-29 09:42:27 +00:00
//nativeDevice.Rasterizer.SetViewports(currentViewport);
2012-09-28 13:05:38 +00:00
//nativeDevice.OutputMerger.SetTargets(this.depthStencilView, this.renderView);
2011-11-30 16:03:51 +00:00
for ( int i = 0 ; i < technique . Description . PassCount ; + + i )
2012-09-06 09:58:13 +00:00
{
technique . GetPassByIndex ( i ) . Apply ( ) ;
2012-09-20 11:53:50 +00:00
nativeDevice . Draw ( vertexCount , vertexOffset ) ;
2011-11-30 16:03:51 +00:00
}
2012-09-08 09:07:23 +00:00
2012-09-08 10:37:41 +00:00
nativeDevice . InputAssembler . InputLayout . Dispose ( ) ;
nativeDevice . 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 ,
2012-09-22 11:17:36 +00:00
int startIndex , int primitiveCount , int instanceCount , IndexBuffer indexBuffer )
2011-11-30 16:03:51 +00:00
{
2012-09-22 11:17:36 +00:00
Dx10 . EffectTechnique technique = SetupEffectForDraw ( ) ;
int vertexCount = DxFormatConverter . CalculateVertexCount ( primitiveType , primitiveCount ) ;
nativeDevice . InputAssembler . PrimitiveTopology = DxFormatConverter . Translate ( primitiveType ) ;
2012-09-29 09:42:27 +00:00
//nativeDevice.Rasterizer.SetViewports(currentViewport);
2012-09-28 13:05:38 +00:00
//nativeDevice.OutputMerger.SetTargets(this.depthStencilView, this.renderView);
2012-09-22 11:17:36 +00:00
if ( indexBuffer ! = null )
{
SetIndexBuffer ( indexBuffer ) ;
}
for ( int i = 0 ; i < technique . Description . PassCount ; + + i )
{
technique . GetPassByIndex ( i ) . Apply ( ) ;
nativeDevice . DrawIndexedInstanced ( vertexCount , instanceCount , startIndex , baseVertex , 0 ) ;
}
nativeDevice . InputAssembler . InputLayout . Dispose ( ) ;
nativeDevice . 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 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 ;
2012-09-27 10:08:00 +00:00
VertexBuffer vertexBuffer = new VertexBuffer ( vertexDeclaration . GraphicsDevice , vertexDeclaration , vertexCount , BufferUsage . WriteOnly ) ;
vertexBuffer . SetData ( vertexData ) ;
this . SetVertexBuffers ( new [ ] { new Framework . Graphics . VertexBufferBinding ( vertexBuffer , vertexOffset ) } ) ;
2012-01-17 05:14:18 +00:00
2012-09-27 10:08:00 +00:00
IndexBuffer indexBuffer = new IndexBuffer ( vertexDeclaration . GraphicsDevice , indexFormat , indexCount , BufferUsage . WriteOnly ) ;
2012-09-20 10:23:03 +00:00
if ( indexData . GetType ( ) = = typeof ( Int16 [ ] ) )
{
2012-09-27 10:08:00 +00:00
indexBuffer . SetData < short > ( ( short [ ] ) indexData ) ;
2012-09-20 10:23:03 +00:00
}
2012-01-19 05:57:54 +00:00
else
2012-09-20 10:23:03 +00:00
{
2012-09-27 10:08:00 +00:00
indexBuffer . SetData < int > ( ( int [ ] ) indexData ) ;
2012-09-20 10:23:03 +00:00
}
2012-09-27 10:08:00 +00:00
DrawIndexedPrimitives ( primitiveType , 0 , vertexOffset , numVertices , indexOffset , primitiveCount , indexBuffer ) ;
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-20 11:53:50 +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 ;
2012-09-15 13:43:31 +00:00
DxVertexBuffer vb10 = new DxVertexBuffer ( nativeDevice , vertexDeclaration , vertexCount , BufferUsage . None ) ;
2012-01-09 18:09:10 +00:00
vb10 . SetData < T > ( null , vertexData ) ;
2012-09-20 11:53:50 +00:00
Dx10 . VertexBufferBinding nativeVertexBufferBindings = new Dx10 . VertexBufferBinding ( vb10 . NativeBuffer , vertexDeclaration . VertexStride , 0 ) ;
2012-01-09 18:09:10 +00:00
2012-09-08 10:37:41 +00:00
nativeDevice . InputAssembler . SetVertexBuffers ( 0 , nativeVertexBufferBindings ) ;
2012-01-09 18:09:10 +00:00
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 ) ;
2012-09-08 10:37:41 +00:00
var layout = CreateInputLayout ( nativeDevice , pass . Description . Signature , vertexDeclaration ) ;
2012-08-10 08:38:01 +00:00
2012-09-08 10:37:41 +00:00
nativeDevice . InputAssembler . InputLayout = layout ;
2012-08-10 08:38:01 +00:00
// Prepare All the stages
2012-09-15 13:43:31 +00:00
nativeDevice . InputAssembler . PrimitiveTopology = DxFormatConverter . Translate ( primitiveType ) ;
2012-09-29 09:42:27 +00:00
//nativeDevice.Rasterizer.SetViewports(currentViewport);
2012-08-10 08:38:01 +00:00
//device.OutputMerger.SetTargets(this.depthStencilView, this.renderView);
for ( int i = 0 ; i < technique . Description . PassCount ; + + i )
{
2012-09-20 11:53:50 +00:00
technique . GetPassByIndex ( i ) . Apply ( ) ;
nativeDevice . Draw ( vertexCount , vertexOffset ) ;
2012-08-10 08:38:01 +00:00
}
2012-09-08 09:07:23 +00:00
2012-09-08 10:37:41 +00:00
nativeDevice . InputAssembler . InputLayout . Dispose ( ) ;
nativeDevice . 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
2012-09-22 11:17:36 +00:00
private InputLayout SetupInputLayout ( ShaderBytecode passSignature )
2011-11-16 14:27:53 +00:00
{
2012-09-22 11:17:36 +00:00
// get the VertexDeclaration from current VertexBuffer to create input layout for the input assembler
var layout = CreateInputLayout ( nativeDevice , passSignature , currentVertexBuffer ) ;
2011-11-16 14:27:53 +00:00
2012-09-22 11:17:36 +00:00
nativeDevice . InputAssembler . InputLayout = layout ;
return layout ;
2011-11-16 14:27:53 +00:00
}
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 ;
2012-09-15 13:43:31 +00:00
DxIndexBuffer nativeIndexBuffer = indexBuffer . NativeIndexBuffer as DxIndexBuffer ;
2011-11-16 14:27:53 +00:00
if ( nativeIndexBuffer ! = null )
{
2012-09-21 12:07:20 +00:00
nativeDevice . InputAssembler . SetIndexBuffer ( nativeIndexBuffer . NativeBuffer , DxFormatConverter . 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-09-06 09:58:13 +00:00
#region SetVertexBuffers
2012-09-22 11:17:36 +00:00
public void SetVertexBuffers ( ANX . Framework . Graphics . VertexBufferBinding [ ] vertexBuffers )
2011-11-16 14:27:53 +00:00
{
if ( vertexBuffers = = null )
throw new ArgumentNullException ( "vertexBuffers" ) ;
2012-09-22 11:17:36 +00:00
this . currentVertexBufferCount = vertexBuffers . Length ;
2011-11-16 14:27:53 +00:00
2012-09-22 11:17:36 +00:00
if ( this . currentVertexBuffer = = null | | this . currentVertexBuffer . Length < currentVertexBufferCount )
{
this . currentVertexBuffer = new ANX . Framework . Graphics . VertexBufferBinding [ currentVertexBufferCount ] ;
}
for ( int i = 0 ; i < this . currentVertexBufferCount ; i + + )
{
this . currentVertexBuffer [ i ] = vertexBuffers [ i ] ;
}
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-15 13:43:31 +00:00
var nativeVertexBuffer = anxVertexBufferBinding . VertexBuffer . NativeVertexBuffer as DxVertexBuffer ;
2011-11-16 14:27:53 +00:00
if ( nativeVertexBuffer ! = null )
{
2012-09-20 07:17:14 +00:00
int vertexStride = anxVertexBufferBinding . VertexBuffer . VertexDeclaration . VertexStride ;
nativeVertexBufferBindings [ i ] = new Dx10 . VertexBufferBinding ( nativeVertexBuffer . NativeBuffer , vertexStride , anxVertexBufferBinding . VertexOffset * vertexStride ) ;
2011-11-16 14:27:53 +00:00
}
else
{
throw new Exception ( "couldn't fetch native DirectX10 VertexBuffer" ) ;
}
}
2012-09-08 10:37:41 +00:00
nativeDevice . 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
2012-09-15 13:43:31 +00:00
protected void SetViewport ( int x , int y , int width , int height , float minDepth , float maxDepth )
2012-09-08 10:37:41 +00:00
{
2012-09-29 09:42:27 +00:00
nativeDevice . Rasterizer . SetViewports ( new Dx10 . Viewport ( x , y , width , height , minDepth , maxDepth ) ) ;
2012-09-08 10:37:41 +00:00
}
2011-11-16 14:27:53 +00:00
2012-09-29 09:42:27 +00:00
protected void SetViewport ( params Dx10 . Viewport [ ] viewports )
{
nativeDevice . Rasterizer . SetViewports ( viewports ) ;
}
#endregion
#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.
2012-09-29 09:42:27 +00:00
/// 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-29 09:42:27 +00:00
private Dx10 . InputLayout CreateInputLayout ( Dx10 . Device device , ShaderBytecode passSignature , params VertexDeclaration [ ] vertexDeclaration )
2011-11-16 14:27:53 +00:00
{
2012-09-27 10:08:00 +00:00
if ( device = = null ) throw new ArgumentNullException ( "device" ) ;
if ( passSignature = = null ) throw new ArgumentNullException ( "passSignature" ) ;
if ( vertexDeclaration = = null ) throw new ArgumentNullException ( "vertexDeclaration" ) ;
2012-09-22 11:17:36 +00:00
//TODO: try to get rid of the list
List < InputElement > inputElements = new List < InputElement > ( ) ;
foreach ( VertexDeclaration decl in vertexDeclaration )
{
foreach ( VertexElement vertexElement in decl . GetVertexElements ( ) )
{
inputElements . Add ( CreateInputElementFromVertexElement ( vertexElement , 0 ) ) ;
}
}
2011-11-16 14:27:53 +00:00
2012-09-22 11:17:36 +00:00
return new Dx10 . InputLayout ( device , passSignature , inputElements . ToArray ( ) ) ;
2012-09-06 09:58:13 +00:00
}
2012-09-22 11:17:36 +00:00
private Dx10 . InputLayout CreateInputLayout ( Dx10 . Device device , ShaderBytecode passSignature , params ANX . Framework . Graphics . VertexBufferBinding [ ] vertexBufferBindings )
{
2012-09-27 10:08:00 +00:00
if ( device = = null ) throw new ArgumentNullException ( "device" ) ;
if ( passSignature = = null ) throw new ArgumentNullException ( "passSignature" ) ;
if ( vertexBufferBindings = = null ) throw new ArgumentNullException ( "vertexBufferBindings" ) ;
2012-09-22 11:17:36 +00:00
//TODO: try to get rid of the list
List < InputElement > inputElements = new List < InputElement > ( ) ;
int slot = 0 ;
foreach ( ANX . Framework . Graphics . VertexBufferBinding binding in vertexBufferBindings )
{
foreach ( VertexElement vertexElement in binding . VertexBuffer . VertexDeclaration . GetVertexElements ( ) )
{
inputElements . Add ( CreateInputElementFromVertexElement ( vertexElement , binding . InstanceFrequency , slot ) ) ;
}
slot + + ;
}
// Layout from VertexShader input signature
return new InputLayout ( device , passSignature , inputElements . ToArray ( ) ) ;
}
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 CreateInputElementFromVertexElement
2012-09-22 11:17:36 +00:00
private InputElement CreateInputElementFromVertexElement ( VertexElement vertexElement , int slot )
2011-11-16 14:27:53 +00:00
{
2012-09-22 11:17:36 +00:00
return CreateInputElementFromVertexElement ( vertexElement , 0 , slot ) ;
}
private InputElement CreateInputElementFromVertexElement ( VertexElement vertexElement , int instanceFrequency , int slot )
{
string elementName = DxFormatConverter . Translate ( ref vertexElement ) ;
Format elementFormat = DxFormatConverter . ConvertVertexElementFormat ( vertexElement . VertexElementFormat ) ;
return new InputElement ( elementName , vertexElement . UsageIndex , elementFormat , vertexElement . Offset , slot , instanceFrequency = = 0 ? InputClassification . PerVertexData : InputClassification . PerInstanceData , instanceFrequency ) ;
}
#endregion
2011-11-16 14:27:53 +00:00
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-09-29 09:42:27 +00:00
CreateDepthStencilBuffer ( this . depthStencilBuffer . Description . Format , this . backBuffer . Description . Width , this . backBuffer . Description . Height , false ) ;
nativeDevice . OutputMerger . SetRenderTargets ( 1 , new Dx10 . RenderTargetView [ ] { this . renderView } , this . depthStencilView ) ; //TODO: necessary?
nativeDevice . OutputMerger . SetTargets ( this . depthStencilView , this . renderView ) ;
nativeDevice . Rasterizer . SetViewports ( new Dx10 . Viewport ( 0 , 0 , this . backBuffer . Description . Width , this . backBuffer . Description . Height ) ) ;
// dispose the old views
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
}
}
else
{
2012-08-10 08:38:01 +00:00
int renderTargetCount = renderTargets . Length ;
2012-09-29 09:42:27 +00:00
RenderTargetView [ ] renderTargetsToDelete = new RenderTargetView [ renderTargetView . Length ] ;
Array . Copy ( renderTargetView , renderTargetsToDelete , renderTargetView . Length ) ;
Dx10 . Viewport [ ] rtViewports = new Dx10 . Viewport [ renderTargetCount ] ;
2012-08-10 08:38:01 +00:00
if ( this . renderTargetView . Length ! = renderTargetCount )
2011-11-28 16:06:52 +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
2012-09-29 09:42:27 +00:00
int width = this . backBuffer . Description . Width ;
int height = this . backBuffer . Description . Height ;
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 ;
2012-09-29 09:42:27 +00:00
//TODO: check if all render Targets have the same size
width = renderTarget . Width ;
height = renderTarget . Height ;
2012-08-10 08:38:01 +00:00
if ( renderTarget ! = null )
{
RenderTarget2D_DX10 nativeRenderTarget = renderTarget . NativeRenderTarget as RenderTarget2D_DX10 ;
if ( renderTargetView [ i ] ! = null )
2012-09-29 09:42:27 +00:00
{
2012-08-10 08:38:01 +00:00
renderTargetView [ i ] . Dispose ( ) ;
2012-09-29 09:42:27 +00:00
}
2012-08-10 08:38:01 +00:00
2012-09-29 09:42:27 +00:00
renderTargetView [ i ] = new Dx10 . RenderTargetView ( nativeDevice , ( ( DxTexture2D ) nativeRenderTarget ) . NativeShaderResourceView . Resource ) ;
rtViewports [ i ] = new Dx10 . Viewport ( 0 , 0 , width , height ) ;
2012-08-10 08:38:01 +00:00
}
2011-11-28 16:06:52 +00:00
}
2012-08-10 08:38:01 +00:00
2012-09-29 09:42:27 +00:00
CreateDepthStencilBuffer ( this . depthStencilBuffer . Description . Format , width , height , false ) ;
2012-09-08 10:37:41 +00:00
nativeDevice . OutputMerger . SetRenderTargets ( renderTargetCount , renderTargetView , this . depthStencilView ) ;
2012-09-29 09:42:27 +00:00
nativeDevice . Rasterizer . SetViewports ( rtViewports ) ;
// free the old render target views...
for ( int i = 0 ; i < renderTargetsToDelete . Length ; i + + )
{
if ( renderTargetsToDelete [ i ] ! = null )
{
renderTargetsToDelete [ i ] . Dispose ( ) ;
renderTargetsToDelete [ i ] = null ;
}
}
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-08 10:37:41 +00:00
#region DisposeRenderView
2012-09-15 13:43:31 +00:00
protected void DisposeRenderView ( )
2012-09-08 10:37:41 +00:00
{
renderView . Dispose ( ) ;
renderView = null ;
2011-11-16 14:27:53 +00:00
2012-09-08 10:37:41 +00:00
backBuffer . Dispose ( ) ;
backBuffer = null ;
}
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 )
{
2012-09-08 10:37:41 +00:00
DisposeRenderView ( ) ;
2011-11-28 16:06:52 +00:00
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
2012-09-15 13:43:31 +00:00
internal Dx10 . Device NativeDevice
{
get
{
return this . nativeDevice ;
}
}
2012-09-05 19:50:10 +00:00
}
2011-11-16 14:27:53 +00:00
}