2011-11-16 14:27:53 +00:00
#region Using Statements
using System ;
using System.Collections.Generic ;
using System.Linq ;
using System.Text ;
using SharpDX ;
using SharpDX.DXGI ;
using SharpDX.Direct3D ;
using ANX.Framework.NonXNA ;
using ANX.Framework.Graphics ;
using SharpDX.Direct3D11 ;
using ANX.Framework ;
using SharpDX.D3DCompiler ;
#endregion // Using Statements
#region License
//
// This file is part of the ANX.Framework created by the "ANX.Framework developer group".
//
// This file is released under the Ms-PL license.
//
//
//
// Microsoft Public License (Ms-PL)
//
// This license governs use of the accompanying software. If you use the software, you accept this license.
// If you do not accept the license, do not use the software.
//
// 1.Definitions
// The terms "reproduce," "reproduction," "derivative works," and "distribution" have the same meaning
// here as under U.S. copyright law.
// A "contribution" is the original software, or any additions or changes to the software.
// A "contributor" is any person that distributes its contribution under this license.
// "Licensed patents" are a contributor's patent claims that read directly on its contribution.
//
// 2.Grant of Rights
// (A) Copyright Grant- Subject to the terms of this license, including the license conditions and limitations
// in section 3, each contributor grants you a non-exclusive, worldwide, royalty-free copyright license to
// reproduce its contribution, prepare derivative works of its contribution, and distribute its contribution
// or any derivative works that you create.
// (B) Patent Grant- Subject to the terms of this license, including the license conditions and limitations in
// section 3, each contributor grants you a non-exclusive, worldwide, royalty-free license under its licensed
// patents to make, have made, use, sell, offer for sale, import, and/or otherwise dispose of its contribution
// in the software or derivative works of the contribution in the software.
//
// 3.Conditions and Limitations
// (A) No Trademark License- This license does not grant you rights to use any contributors' name, logo, or trademarks.
// (B) If you bring a patent claim against any contributor over patents that you claim are infringed by the software, your
// patent license from such contributor to the software ends automatically.
// (C) If you distribute any portion of the software, you must retain all copyright, patent, trademark, and attribution
// notices that are present in the software.
// (D) If you distribute any portion of the software in source code form, you may do so only under this license by including
// a complete copy of this license with your distribution. If you distribute any portion of the software in compiled or
// object code form, you may only do so under a license that complies with this license.
// (E) The software is licensed "as-is." You bear the risk of using it. The contributors give no express warranties, guarantees,
// or conditions. You may have additional consumer rights under your local laws which this license cannot change. To the
// extent permitted under your local laws, the contributors exclude the implied warranties of merchantability, fitness for a
// particular purpose and non-infringement.
#endregion // License
using Device = SharpDX . Direct3D11 . Device ;
using Buffer = SharpDX . Direct3D11 . Buffer ;
namespace ANX.RenderSystem.Windows.DX11
{
public class GraphicsDeviceWindowsDX11 : INativeGraphicsDevice
{
private Device device ;
private SwapChain swapChain ;
private RenderTargetView renderView ;
private SharpDX . Direct3D11 . Texture2D backBuffer ;
internal Effect_DX11 currentEffect ;
private VertexBuffer currentVertexBuffer ;
private IndexBuffer currentIndexBuffer ;
private SharpDX . Direct3D11 . Viewport currentViewport ;
public GraphicsDeviceWindowsDX11 ( PresentationParameters presentationParameters )
{
// SwapChain description
var desc = new SwapChainDescription ( )
{
BufferCount = 1 ,
ModeDescription = new ModeDescription ( presentationParameters . BackBufferWidth , presentationParameters . BackBufferHeight , new Rational ( 60 , 1 ) , Format . R8G8B8A8_UNorm ) ,
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
Device . CreateWithSwapChain ( SharpDX . Direct3D10 . DriverType . Hardware , DeviceCreationFlags . Debug , desc , out device , out swapChain ) ;
#else
Device . CreateWithSwapChain ( DriverType . Hardware , DeviceCreationFlags . None , desc , out device , out swapChain ) ;
#endif
// Ignore all windows events
Factory factory = swapChain . GetParent < Factory > ( ) ;
factory . MakeWindowAssociation ( presentationParameters . DeviceWindowHandle , WindowAssociationFlags . IgnoreAll ) ;
// New RenderTargetView from the backbuffer
backBuffer = SharpDX . Direct3D11 . Texture2D . FromSwapChain < SharpDX . Direct3D11 . Texture2D > ( swapChain , 0 ) ;
renderView = new RenderTargetView ( device , backBuffer ) ;
currentViewport = new SharpDX . Direct3D11 . Viewport ( 0 , 0 , presentationParameters . BackBufferWidth , presentationParameters . BackBufferHeight ) ;
}
public void Clear ( ref Color color )
{
throw new NotImplementedException ( ) ;
//device.ClearRenderTargetView(renderView, new SharpDX.Color4(color.A / 255f, color.R / 255f, color.G / 255f, color.B / 255f));
}
public void Present ( )
{
swapChain . Present ( 0 , PresentFlags . None ) ;
}
internal Device NativeDevice
{
get
{
return this . device ;
}
}
private void SetupEffectForDraw ( out SharpDX . Direct3D11 . EffectPass pass , out SharpDX . Direct3D11 . EffectTechnique technique , out ShaderBytecode passSignature )
{
// get the current effect
//TODO: check for null and throw exception
Effect_DX11 effect = this . currentEffect ;
// get the input semantic of the current effect / technique that is used
//TODO: check for null's and throw exceptions
technique = effect . NativeEffect . GetTechniqueByIndex ( 0 ) ;
pass = technique . GetPassByIndex ( 0 ) ;
passSignature = pass . Description . Signature ;
}
private void SetupInputLayout ( ShaderBytecode passSignature )
{
// get the VertexDeclaration from current VertexBuffer to create input layout for the input assembler
//TODO: check for null and throw exception
VertexDeclaration vertexDeclaration = currentVertexBuffer . VertexDeclaration ;
var layout = CreateInputLayout ( device , passSignature , vertexDeclaration ) ;
throw new NotImplementedException ( ) ;
//device.InputAssembler.InputLayout = layout;
}
private int CalculateVertexCount ( PrimitiveType type , int primitiveCount )
{
if ( type = = PrimitiveType . TriangleList )
{
return primitiveCount * 3 ;
}
else if ( type = = PrimitiveType . LineList )
{
return primitiveCount * 2 ;
}
else if ( type = = PrimitiveType . LineStrip )
{
return primitiveCount + 1 ;
}
else if ( type = = PrimitiveType . TriangleStrip )
{
return primitiveCount + 2 ;
}
else
{
throw new NotImplementedException ( "couldn't calculate vertex count for PrimitiveType '" + type . ToString ( ) + "'" ) ;
}
}
public void DrawIndexedPrimitives ( PrimitiveType primitiveType , int baseVertex , int minVertexIndex , int numVertices , int startIndex , int primitiveCount )
{
SharpDX . Direct3D11 . EffectPass pass ; SharpDX . Direct3D11 . EffectTechnique technique ; ShaderBytecode passSignature ;
SetupEffectForDraw ( out pass , out technique , out passSignature ) ;
SetupInputLayout ( passSignature ) ;
throw new NotImplementedException ( ) ;
// Prepare All the stages
//device.InputAssembler.PrimitiveTopology = Translate(primitiveType);
//device.Rasterizer.SetViewports(currentViewport);
//device.OutputMerger.SetTargets(this.renderView);
//for (int i = 0; i < technique.Description.PassCount; ++i)
//{
// pass.Apply();
// device.DrawIndexed(CalculateVertexCount(primitiveType, primitiveCount), startIndex, baseVertex);
//}
}
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 ) ;
SetupInputLayout ( passSignature ) ;
throw new NotImplementedException ( ) ;
// Prepare All the stages
//device.InputAssembler.PrimitiveTopology = Translate(primitiveType);
//device.Rasterizer.SetViewports(currentViewport);
//device.OutputMerger.SetTargets(this.renderView);
//for (int i = 0; i < technique.Description.PassCount; ++i)
//{
// pass.Apply();
// device.Draw(primitiveCount, vertexOffset);
//}
}
public void SetIndexBuffer ( IndexBuffer indexBuffer )
{
if ( indexBuffer = = null )
{
throw new ArgumentNullException ( "indexBuffer" ) ;
}
this . currentIndexBuffer = indexBuffer ;
throw new NotImplementedException ( ) ;
//IndexBuffer_DX11 nativeIndexBuffer = indexBuffer.NativeIndexBuffer as IndexBuffer_DX11;
//if (nativeIndexBuffer != null)
//{
// device.InputAssembler.SetIndexBuffer(nativeIndexBuffer.NativeBuffer, Translate(indexBuffer.IndexElementSize), 0);
//}
//else
//{
// throw new Exception("couldn't fetch native DirectX11.1 IndexBuffer");
//}
}
public void SetVertexBuffers ( ANX . Framework . Graphics . VertexBufferBinding [ ] vertexBuffers )
{
throw new NotImplementedException ( ) ;
}
public void SetViewport ( ANX . Framework . Graphics . Viewport viewport )
{
this . currentViewport = new SharpDX . Direct3D11 . Viewport ( viewport . X , viewport . Y , viewport . Width , viewport . Height , viewport . MinDepth , viewport . MaxDepth ) ;
}
public void ApplyStateObject ( ANX . Framework . Graphics . BlendState blendState )
{
throw new NotImplementedException ( ) ;
//BlendStateDescription description = new BlendStateDescription();
//description.AlphaBlendOperation = Translate(blendState.AlphaBlendFunction);
//description.BlendOperation = Translate(blendState.ColorBlendFunction);
//description.DestinationAlphaBlend = Translate(blendState.AlphaDestinationBlend);
//description.DestinationBlend = Translate(blendState.ColorDestinationBlend);
//for (int i = 0; i < 4; i++)
//{
// description.IsBlendEnabled[i] = true;
//}
//description.RenderTargetWriteMask[0] = Translate(blendState.ColorWriteChannels);
//description.RenderTargetWriteMask[1] = Translate(blendState.ColorWriteChannels1);
//description.RenderTargetWriteMask[2] = Translate(blendState.ColorWriteChannels2);
//description.RenderTargetWriteMask[3] = Translate(blendState.ColorWriteChannels3);
//description.SourceAlphaBlend = Translate(blendState.AlphaSourceBlend);
//description.SourceBlend = Translate(blendState.ColorSourceBlend);
//SharpDX.Direct3D11.BlendState nativeBlendState = new SharpDX.Direct3D11.BlendState(device, description);
//Vector4 tempVector = blendState.BlendFactor.ToVector4();
//SharpDX.Color4 blendFactor = new Color4(tempVector.X, tempVector.Y, tempVector.Z, tempVector.W);
//device.OutputMerger.SetBlendState(nativeBlendState, blendFactor, blendState.MultiSampleMask);
}
public void ApplyStateObject ( ANX . Framework . Graphics . RasterizerState rasterizerState )
{
RasterizerStateDescription description = new RasterizerStateDescription ( ) ;
description . CullMode = Translate ( rasterizerState . CullMode ) ;
description . DepthBias = ( int ) rasterizerState . DepthBias ; //TODO: this looks wrong!!!
description . IsScissorEnabled = rasterizerState . ScissorTestEnable ;
description . SlopeScaledDepthBias = rasterizerState . SlopeScaleDepthBias ;
description . IsMultisampleEnabled = rasterizerState . MultiSampleAntiAlias ;
description . FillMode = Translate ( rasterizerState . FillMode ) ;
description . IsAntialiasedLineEnabled = false ; //TODO: this should be ok
SharpDX . Direct3D11 . RasterizerState nativeRasterizerState = new SharpDX . Direct3D11 . RasterizerState ( device , description ) ;
//device.Rasterizer.State = nativeRasterizerState;
throw new NotImplementedException ( ) ;
}
public void ApplyStateObject ( ANX . Framework . Graphics . DepthStencilState depthStencilState )
{
DepthStencilStateDescription description = new DepthStencilStateDescription ( ) ;
description . IsStencilEnabled = depthStencilState . StencilEnable ;
description . IsDepthEnabled = depthStencilState . DepthBufferEnable ;
description . DepthComparison = Translate ( depthStencilState . DepthBufferFunction ) ;
//TODO: more to implement
SharpDX . Direct3D11 . DepthStencilState nativeDepthStencilState = new SharpDX . Direct3D11 . DepthStencilState ( device , description ) ;
//device.OutputMerger.SetDepthStencilState(nativeDepthStencilState, depthStencilState.ReferenceStencil);
throw new NotImplementedException ( ) ;
}
public void ApplyStateObject ( int slot , ANX . Framework . Graphics . SamplerState samplerState )
{
SamplerStateDescription description = new SamplerStateDescription ( ) ;
description . AddressU = Translate ( samplerState . AddressU ) ;
description . AddressV = Translate ( samplerState . AddressV ) ;
description . AddressW = Translate ( samplerState . AddressW ) ;
description . Filter = Translate ( samplerState . Filter ) ;
description . MaximumAnisotropy = samplerState . MaxAnisotropy ;
description . MaximumLod = samplerState . MaxMipLevel ; //TODO: is this correct?
description . MipLodBias = samplerState . MipMapLevelOfDetailBias ;
SharpDX . Direct3D11 . SamplerState nativeSamplerState = new SharpDX . Direct3D11 . SamplerState ( device , description ) ;
//device.PixelShader.SetSampler(slot, nativeSamplerState);
throw new NotImplementedException ( ) ;
}
private Filter Translate ( TextureFilter filter )
{
switch ( filter )
{
case TextureFilter . Anisotropic :
return Filter . Anisotropic ;
case TextureFilter . Linear :
return Filter . MinMagMipLinear ;
case TextureFilter . LinearMipPoint :
return Filter . MinMagMipPoint ;
case TextureFilter . MinLinearMagPointMipLinear :
return Filter . MinLinearMagPointMipLinear ;
case TextureFilter . MinLinearMagPointMipPoint :
return Filter . MinLinearMagMipPoint ;
case TextureFilter . MinPointMagLinearMipLinear :
return Filter . MinPointMagMipLinear ;
case TextureFilter . MinPointMagLinearMipPoint :
return Filter . MinPointMagLinearMipPoint ;
case TextureFilter . Point :
return Filter . MinMagMipPoint ;
case TextureFilter . PointMipLinear :
return Filter . MinMagPointMipLinear ;
}
throw new NotImplementedException ( ) ;
}
private SharpDX . Direct3D11 . TextureAddressMode Translate ( ANX . Framework . Graphics . TextureAddressMode addressMode )
{
switch ( addressMode )
{
case ANX . Framework . Graphics . TextureAddressMode . Clamp :
return SharpDX . Direct3D11 . TextureAddressMode . Clamp ;
case ANX . Framework . Graphics . TextureAddressMode . Mirror :
return SharpDX . Direct3D11 . TextureAddressMode . Mirror ;
case ANX . Framework . Graphics . TextureAddressMode . Wrap :
return SharpDX . Direct3D11 . TextureAddressMode . Wrap ;
}
return SharpDX . Direct3D11 . TextureAddressMode . Clamp ;
}
/// <summary>
/// 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. This is what this method is for.
/// </summary>
private InputLayout CreateInputLayout ( Device device , ShaderBytecode passSignature , VertexDeclaration vertexDeclaration )
{
VertexElement [ ] vertexElements = vertexDeclaration . GetVertexElements ( ) ;
int elementCount = vertexElements . Length ;
InputElement [ ] inputElements = new InputElement [ elementCount ] ;
for ( int i = 0 ; i < elementCount ; i + + )
{
inputElements [ i ] = CreateInputElementFromVertexElement ( vertexElements [ i ] ) ;
}
// Layout from VertexShader input signature
return new InputLayout ( device , passSignature , inputElements ) ;
}
private InputElement CreateInputElementFromVertexElement ( VertexElement vertexElement )
{
string elementName = Translate ( vertexElement . VertexElementUsage ) ;
Format elementFormat ;
switch ( vertexElement . VertexElementFormat )
{
case VertexElementFormat . Vector2 :
elementFormat = Format . R32G32_Float ;
break ;
case VertexElementFormat . Vector3 :
elementFormat = Format . R32G32B32_Float ;
break ;
case VertexElementFormat . Vector4 :
elementFormat = Format . R32G32B32A32_Float ;
break ;
case VertexElementFormat . Color :
elementFormat = Format . R8G8B8A8_UNorm ;
break ;
default :
throw new Exception ( "can't map '" + vertexElement . VertexElementFormat . ToString ( ) + "' to DXGI.Format in DirectX10 RenderSystem CreateInputElementFromVertexElement" ) ;
}
return new InputElement ( elementName , vertexElement . UsageIndex , elementFormat , vertexElement . Offset , 0 ) ;
}
private PrimitiveTopology Translate ( PrimitiveType primitiveType )
{
switch ( primitiveType )
{
case PrimitiveType . LineList :
return PrimitiveTopology . LineList ;
case PrimitiveType . LineStrip :
return PrimitiveTopology . LineStrip ;
case PrimitiveType . TriangleList :
return PrimitiveTopology . TriangleList ;
case PrimitiveType . TriangleStrip :
return PrimitiveTopology . TriangleStrip ;
default :
throw new InvalidOperationException ( "unknown PrimitiveType: " + primitiveType . ToString ( ) ) ;
}
}
private SharpDX . DXGI . Format Translate ( IndexElementSize indexElementSize )
{
switch ( indexElementSize )
{
case IndexElementSize . SixteenBits :
return Format . R16_UInt ;
case IndexElementSize . ThirtyTwoBits :
return Format . R32_UInt ;
default :
throw new InvalidOperationException ( "unknown IndexElementSize: " + indexElementSize . ToString ( ) ) ;
}
}
private string Translate ( VertexElementUsage usage )
{
//TODO: map the other Usages
if ( usage = = VertexElementUsage . TextureCoordinate )
{
return "TEXCOORD" ;
}
else
{
return usage . ToString ( ) . ToUpperInvariant ( ) ;
}
}
private ColorWriteMaskFlags Translate ( ColorWriteChannels colorWriteChannels )
{
switch ( colorWriteChannels )
{
case ColorWriteChannels . All :
return ColorWriteMaskFlags . All ;
case ColorWriteChannels . Alpha :
return ColorWriteMaskFlags . Alpha ;
case ColorWriteChannels . Blue :
return ColorWriteMaskFlags . Blue ;
case ColorWriteChannels . Green :
return ColorWriteMaskFlags . Green ;
case ColorWriteChannels . Red :
return ColorWriteMaskFlags . Red ;
}
return 0 ;
}
private BlendOption Translate ( Blend blend )
{
switch ( blend )
{
case Blend . BlendFactor :
return BlendOption . BlendFactor ;
case Blend . DestinationAlpha :
return BlendOption . DestinationAlpha ;
case Blend . DestinationColor :
return BlendOption . DestinationColor ;
case Blend . InverseBlendFactor :
return BlendOption . InverseBlendFactor ;
case Blend . InverseDestinationAlpha :
return BlendOption . InverseDestinationAlpha ;
case Blend . InverseDestinationColor :
return BlendOption . InverseDestinationColor ;
case Blend . InverseSourceAlpha :
return BlendOption . InverseSourceAlpha ;
case Blend . InverseSourceColor :
return BlendOption . InverseSourceColor ;
case Blend . One :
return BlendOption . One ;
case Blend . SourceAlpha :
return BlendOption . SourceAlpha ;
case Blend . SourceAlphaSaturation :
return BlendOption . SourceAlphaSaturate ;
case Blend . SourceColor :
return BlendOption . SourceColor ;
case Blend . Zero :
return BlendOption . Zero ;
}
return BlendOption . One ;
}
private BlendOperation Translate ( BlendFunction blendFunction )
{
switch ( blendFunction )
{
case BlendFunction . Add :
return BlendOperation . Add ;
case BlendFunction . Max :
return BlendOperation . Maximum ;
case BlendFunction . Min :
return BlendOperation . Minimum ;
case BlendFunction . ReverseSubtract :
return BlendOperation . ReverseSubtract ;
case BlendFunction . Subtract :
return BlendOperation . Subtract ;
}
return BlendOperation . Add ;
}
private SharpDX . Direct3D11 . FillMode Translate ( ANX . Framework . Graphics . FillMode fillMode )
{
if ( fillMode = = ANX . Framework . Graphics . FillMode . WireFrame )
{
return SharpDX . Direct3D11 . FillMode . Wireframe ;
}
else
{
return SharpDX . Direct3D11 . FillMode . Solid ;
}
}
private SharpDX . Direct3D11 . CullMode Translate ( ANX . Framework . Graphics . CullMode cullMode )
{
if ( cullMode = = ANX . Framework . Graphics . CullMode . CullClockwiseFace )
{
return SharpDX . Direct3D11 . CullMode . Front ;
}
else if ( cullMode = = ANX . Framework . Graphics . CullMode . CullCounterClockwiseFace )
{
return SharpDX . Direct3D11 . CullMode . Back ;
}
else
{
return SharpDX . Direct3D11 . CullMode . None ;
}
}
private Comparison Translate ( CompareFunction compareFunction )
{
switch ( compareFunction )
{
case CompareFunction . Always :
return Comparison . Always ;
case CompareFunction . Equal :
return Comparison . Equal ;
case CompareFunction . Greater :
return Comparison . Greater ;
case CompareFunction . GreaterEqual :
return Comparison . GreaterEqual ;
case CompareFunction . Less :
return Comparison . Less ;
case CompareFunction . LessEqual :
return Comparison . LessEqual ;
case CompareFunction . Never :
return Comparison . Never ;
case CompareFunction . NotEqual :
return Comparison . NotEqual ;
}
return Comparison . Always ;
}
public void SetRenderTargets ( params Framework . Graphics . RenderTargetBinding [ ] renderTargets )
{
throw new NotImplementedException ( ) ;
}
public void GetBackBufferData < T > ( Framework . Rectangle ? rect , T [ ] data , int startIndex , int elementCount ) where T : struct
{
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 ( ) ;
}
public void Clear ( Framework . Graphics . ClearOptions options , Framework . Vector4 color , float depth , int stencil )
{
throw new NotImplementedException ( ) ;
}
public void DrawInstancedPrimitives ( Framework . Graphics . PrimitiveType primitiveType , int baseVertex , int minVertexIndex , int numVertices , int startIndex , int primitiveCount , int instanceCount )
{
throw new NotImplementedException ( ) ;
}
public void DrawUserIndexedPrimitives < T > ( Framework . Graphics . PrimitiveType primitiveType , T [ ] vertexData , int vertexOffset , int numVertices , Array indexData , int indexOffset , int primitiveCount , Framework . Graphics . VertexDeclaration vertexDeclaration , Framework . Graphics . IndexElementSize indexFormat ) where T : struct , Framework . Graphics . IVertexType
{
throw new NotImplementedException ( ) ;
}
public void DrawUserPrimitives < T > ( Framework . Graphics . PrimitiveType primitiveType , T [ ] vertexData , int vertexOffset , int primitiveCount , Framework . Graphics . VertexDeclaration vertexDeclaration ) where T : struct , Framework . Graphics . IVertexType
{
throw new NotImplementedException ( ) ;
}
public void ResizeBuffers ( Framework . Graphics . PresentationParameters presentationParameters )
{
throw new NotImplementedException ( ) ;
}
public bool VSync
{
get
{
throw new NotImplementedException ( ) ;
}
set
{
throw new NotImplementedException ( ) ;
}
}
2011-11-22 14:51:30 +00:00
public void Dispose ( )
{
//TODO: implement
2011-11-16 14:27:53 +00:00
}
2011-11-22 14:51:30 +00:00
}
2011-11-16 14:27:53 +00:00
}