From 0c98c2988635394a8b36f5a9c46281cbaa6ad87e Mon Sep 17 00:00:00 2001 From: Glatzemann Date: Sat, 22 Sep 2012 11:17:36 +0000 Subject: [PATCH] Worked on issue #531. Primitives sample is now much more complete. The instanced primitives are looking much better in PIX now, but still not rendering. --- ANX.Framework/Graphics/GraphicsDevice.cs | 2 +- .../RenderSystem/INativeGraphicsDevice.cs | 2 +- .../GraphicsDeviceWindowsGL3.cs | 2 +- .../DxFormatConverter.cs | 33 ++++++ .../SharedGraphicsDeviceDX.cs | 3 +- .../PsVitaGraphicsDevice.cs | 4 +- .../EffectParameter_DX10.cs | 9 +- .../GraphicsDeviceDX.cs | 109 +++++++++++++----- .../GraphicsDeviceDX.cs | 83 ++++++++++--- 9 files changed, 196 insertions(+), 51 deletions(-) diff --git a/ANX.Framework/Graphics/GraphicsDevice.cs b/ANX.Framework/Graphics/GraphicsDevice.cs index b203466e..05f71e00 100644 --- a/ANX.Framework/Graphics/GraphicsDevice.cs +++ b/ANX.Framework/Graphics/GraphicsDevice.cs @@ -142,7 +142,7 @@ namespace ANX.Framework.Graphics int startIndex, int primitiveCount, int instanceCount) { NativeDevice.DrawInstancedPrimitives(primitiveType, baseVertex, minVertexIndex, numVertices, startIndex, - primitiveCount, instanceCount); + primitiveCount, instanceCount, this.indexBuffer); } #endregion diff --git a/ANX.Framework/NonXNA/RenderSystem/INativeGraphicsDevice.cs b/ANX.Framework/NonXNA/RenderSystem/INativeGraphicsDevice.cs index e7a03266..217c45de 100644 --- a/ANX.Framework/NonXNA/RenderSystem/INativeGraphicsDevice.cs +++ b/ANX.Framework/NonXNA/RenderSystem/INativeGraphicsDevice.cs @@ -17,7 +17,7 @@ namespace ANX.Framework.NonXNA void DrawIndexedPrimitives(PrimitiveType primitiveType, int baseVertex, int minVertexIndex, int numVertices, int startIndex, int primitiveCount, IndexBuffer indexBuffer); void DrawInstancedPrimitives(PrimitiveType primitiveType, int baseVertex, int minVertexIndex, int numVertices, - int startIndex, int primitiveCount, int instanceCount); + int startIndex, int primitiveCount, int instanceCount, IndexBuffer indexBuffer); void DrawUserIndexedPrimitives(PrimitiveType primitiveType, T[] vertexData, int vertexOffset, int numVertices, Array indexData, int indexOffset, int primitiveCount, VertexDeclaration vertexDeclaration, diff --git a/RenderSystems/ANX.Framework.GL3/GraphicsDeviceWindowsGL3.cs b/RenderSystems/ANX.Framework.GL3/GraphicsDeviceWindowsGL3.cs index bd8416dc..50d46f71 100644 --- a/RenderSystems/ANX.Framework.GL3/GraphicsDeviceWindowsGL3.cs +++ b/RenderSystems/ANX.Framework.GL3/GraphicsDeviceWindowsGL3.cs @@ -259,7 +259,7 @@ namespace ANX.RenderSystem.GL3 #region DrawInstancedPrimitives (TODO) public void DrawInstancedPrimitives(PrimitiveType primitiveType, int baseVertex, int minVertexIndex, int numVertices, int startIndex, - int primitiveCount, int instanceCount) + int primitiveCount, int instanceCount, IndexBuffer indexBuffer) { //GL.DrawArraysInstanced( // DatatypesMapping.PrimitiveTypeToBeginMode(primitiveType), diff --git a/RenderSystems/ANX.RenderSystem.DX.SharedSources/DxFormatConverter.cs b/RenderSystems/ANX.RenderSystem.DX.SharedSources/DxFormatConverter.cs index aa04f9a0..3a0ebf2f 100644 --- a/RenderSystems/ANX.RenderSystem.DX.SharedSources/DxFormatConverter.cs +++ b/RenderSystems/ANX.RenderSystem.DX.SharedSources/DxFormatConverter.cs @@ -49,6 +49,39 @@ namespace ANX.RenderSystem.Windows.DX11 } #endregion + public static int FormatSize(VertexElementFormat format) + { + switch (format) + { + case VertexElementFormat.Byte4: + return 4; + case VertexElementFormat.Color: + return 4; + case VertexElementFormat.HalfVector2: + return 4; + case VertexElementFormat.HalfVector4: + return 8; + case VertexElementFormat.NormalizedShort2: + return 4; + case VertexElementFormat.NormalizedShort4: + return 8; + case VertexElementFormat.Short2: + return 4; + case VertexElementFormat.Short4: + return 8; + case VertexElementFormat.Single: + return 4; + case VertexElementFormat.Vector2: + return 8; + case VertexElementFormat.Vector3: + return 12; + case VertexElementFormat.Vector4: + return 16; + } + + throw new ArgumentException("Invalid format '" + format + "'."); + } + #region Translate (SurfaceFormat) public static SharpDX.DXGI.Format Translate(SurfaceFormat surfaceFormat) { diff --git a/RenderSystems/ANX.RenderSystem.DX.SharedSources/SharedGraphicsDeviceDX.cs b/RenderSystems/ANX.RenderSystem.DX.SharedSources/SharedGraphicsDeviceDX.cs index 7a0f849d..30830b7f 100644 --- a/RenderSystems/ANX.RenderSystem.DX.SharedSources/SharedGraphicsDeviceDX.cs +++ b/RenderSystems/ANX.RenderSystem.DX.SharedSources/SharedGraphicsDeviceDX.cs @@ -36,7 +36,8 @@ namespace ANX.RenderSystem.Windows.DX11 protected uint lastClearColor; protected SharpDX.Color4 clearColor; protected SharpDX.DXGI.SwapChain swapChain; - protected VertexBuffer currentVertexBuffer; + protected VertexBufferBinding[] currentVertexBuffer; + protected int currentVertexBufferCount; protected IndexBuffer currentIndexBuffer; #endregion diff --git a/RenderSystems/ANX.RenderSystem.PsVita/PsVitaGraphicsDevice.cs b/RenderSystems/ANX.RenderSystem.PsVita/PsVitaGraphicsDevice.cs index 355291ee..52251087 100644 --- a/RenderSystems/ANX.RenderSystem.PsVita/PsVitaGraphicsDevice.cs +++ b/RenderSystems/ANX.RenderSystem.PsVita/PsVitaGraphicsDevice.cs @@ -111,14 +111,14 @@ namespace ANX.RenderSystem.PsVita #region INativeGraphicsDevice Member public void DrawIndexedPrimitives(PrimitiveType primitiveType, int baseVertex, int minVertexIndex, int numVertices, int startIndex, - int primitiveCount) + int primitiveCount, IndexBuffer indexBuffer) { throw new NotImplementedException(); } public void DrawInstancedPrimitives(PrimitiveType primitiveType, int baseVertex, int minVertexIndex, int numVertices, int startIndex, - int primitiveCount, int instanceCount) + int primitiveCount, int instanceCount, IndexBuffer indexBuffer) { throw new NotImplementedException(); } diff --git a/RenderSystems/ANX.RenderSystem.Windows.DX10/EffectParameter_DX10.cs b/RenderSystems/ANX.RenderSystem.Windows.DX10/EffectParameter_DX10.cs index b3bebcee..38a8b1bd 100644 --- a/RenderSystems/ANX.RenderSystem.Windows.DX10/EffectParameter_DX10.cs +++ b/RenderSystems/ANX.RenderSystem.Windows.DX10/EffectParameter_DX10.cs @@ -59,8 +59,13 @@ namespace ANX.RenderSystem.Windows.DX10 #region SetValue (Matrix, transpose) (TODO) public void SetValue(Matrix value, bool transpose) { - // TODO: handle transpose! - NativeParameter.AsMatrix().SetMatrix(value); + Matrix val = value; + if (transpose) + { + Matrix.Transpose(ref val, out val); + } + + NativeParameter.AsMatrix().SetMatrix(val); } #endregion diff --git a/RenderSystems/ANX.RenderSystem.Windows.DX10/GraphicsDeviceDX.cs b/RenderSystems/ANX.RenderSystem.Windows.DX10/GraphicsDeviceDX.cs index 6368bd35..9f13c7f0 100644 --- a/RenderSystems/ANX.RenderSystem.Windows.DX10/GraphicsDeviceDX.cs +++ b/RenderSystems/ANX.RenderSystem.Windows.DX10/GraphicsDeviceDX.cs @@ -1,10 +1,12 @@ #region Using Statements using System; +using System.Collections.Generic; using ANX.Framework; using ANX.Framework.Graphics; using ANX.Framework.NonXNA; using SharpDX.D3DCompiler; using SharpDX.DXGI; +using SharpDX.Direct3D10; #endregion @@ -243,9 +245,28 @@ namespace ANX.RenderSystem.Windows.DX10 #region DrawInstancedPrimitives public void DrawInstancedPrimitives(PrimitiveType primitiveType, int baseVertex, int minVertexIndex, int numVertices, - int startIndex, int primitiveCount, int instanceCount) + int startIndex, int primitiveCount, int instanceCount, IndexBuffer indexBuffer) { - nativeDevice.DrawIndexedInstanced(numVertices, instanceCount, startIndex, baseVertex, 0); + Dx10.EffectTechnique technique = SetupEffectForDraw(); + int vertexCount = DxFormatConverter.CalculateVertexCount(primitiveType, primitiveCount); + + nativeDevice.InputAssembler.PrimitiveTopology = DxFormatConverter.Translate(primitiveType); + nativeDevice.Rasterizer.SetViewports(currentViewport); + nativeDevice.OutputMerger.SetTargets(this.depthStencilView, this.renderView); + + 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; } #endregion @@ -333,15 +354,13 @@ namespace ANX.RenderSystem.Windows.DX10 #endregion #region SetupInputLayout - private void SetupInputLayout(ShaderBytecode passSignature) + private InputLayout SetupInputLayout(ShaderBytecode passSignature) { - if (currentVertexBuffer == null) - throw new ArgumentNullException("passSignature"); + // get the VertexDeclaration from current VertexBuffer to create input layout for the input assembler + var layout = CreateInputLayout(nativeDevice, passSignature, currentVertexBuffer); - VertexDeclaration vertexDeclaration = currentVertexBuffer.VertexDeclaration; - var layout = CreateInputLayout(nativeDevice, passSignature, vertexDeclaration); - - nativeDevice.InputAssembler.InputLayout = layout; + nativeDevice.InputAssembler.InputLayout = layout; + return layout; } #endregion @@ -367,15 +386,24 @@ namespace ANX.RenderSystem.Windows.DX10 #endregion #region SetVertexBuffers - public void SetVertexBuffers(VertexBufferBinding[] vertexBuffers) + public void SetVertexBuffers(ANX.Framework.Graphics.VertexBufferBinding[] vertexBuffers) { if (vertexBuffers == null) throw new ArgumentNullException("vertexBuffers"); - this.currentVertexBuffer = vertexBuffers[0].VertexBuffer; //TODO: hmmmmm, not nice :-) + this.currentVertexBufferCount = vertexBuffers.Length; - Dx10.VertexBufferBinding[] nativeVertexBufferBindings = - new Dx10.VertexBufferBinding[vertexBuffers.Length]; + 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]; for (int i = 0; i < vertexBuffers.Length; i++) { ANX.Framework.Graphics.VertexBufferBinding anxVertexBufferBinding = vertexBuffers[i]; @@ -408,28 +436,53 @@ namespace ANX.RenderSystem.Windows.DX10 /// 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. /// - private Dx10.InputLayout CreateInputLayout(Dx10.Device device, ShaderBytecode passSignature, - VertexDeclaration vertexDeclaration) + private Dx10.InputLayout CreateInputLayout(Dx10.Device device, ShaderBytecode passSignature, params VertexDeclaration[] vertexDeclaration) { - VertexElement[] vertexElements = vertexDeclaration.GetVertexElements(); - int elementCount = vertexElements.Length; - var inputElements = new Dx10.InputElement[elementCount]; + //TODO: try to get rid of the list + List inputElements = new List(); + foreach (VertexDeclaration decl in vertexDeclaration) + { + foreach (VertexElement vertexElement in decl.GetVertexElements()) + { + inputElements.Add(CreateInputElementFromVertexElement(vertexElement, 0)); + } + } - for (int i = 0; i < elementCount; i++) - inputElements[i] = CreateInputElementFromVertexElement(vertexElements[i]); - - return new Dx10.InputLayout(device, passSignature, inputElements); + return new Dx10.InputLayout(device, passSignature, inputElements.ToArray()); } + + private Dx10.InputLayout CreateInputLayout(Dx10.Device device, ShaderBytecode passSignature, params ANX.Framework.Graphics.VertexBufferBinding[] vertexBufferBindings) + { + //TODO: try to get rid of the list + List inputElements = new List(); + 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()); + } #endregion #region CreateInputElementFromVertexElement - private Dx10.InputElement CreateInputElementFromVertexElement(VertexElement vertexElement) + private InputElement CreateInputElementFromVertexElement(VertexElement vertexElement, int slot) { - string elementName = DxFormatConverter.Translate(ref vertexElement); - Format elementFormat = DxFormatConverter.ConvertVertexElementFormat(vertexElement.VertexElementFormat); - return new Dx10.InputElement(elementName, vertexElement.UsageIndex, elementFormat, vertexElement.Offset, 0); - } - #endregion + 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 #region SetRenderTargets public void SetRenderTargets(params RenderTargetBinding[] renderTargets) diff --git a/RenderSystems/ANX.RenderSystem.Windows.DX11/GraphicsDeviceDX.cs b/RenderSystems/ANX.RenderSystem.Windows.DX11/GraphicsDeviceDX.cs index 0fe7d201..2b5531e0 100644 --- a/RenderSystems/ANX.RenderSystem.Windows.DX11/GraphicsDeviceDX.cs +++ b/RenderSystems/ANX.RenderSystem.Windows.DX11/GraphicsDeviceDX.cs @@ -1,5 +1,6 @@ #region Using Statements using System; +using System.Collections.Generic; using ANX.Framework; using ANX.Framework.Graphics; using ANX.Framework.NonXNA; @@ -250,9 +251,28 @@ namespace ANX.RenderSystem.Windows.DX11 #endregion #region DrawInstancedPrimitives - public void DrawInstancedPrimitives(PrimitiveType primitiveType, int baseVertex, int minVertexIndex, int numVertices, int startIndex, int primitiveCount, int instanceCount) + public void DrawInstancedPrimitives(PrimitiveType primitiveType, int baseVertex, int minVertexIndex, int numVertices, int startIndex, int primitiveCount, int instanceCount, IndexBuffer indexBuffer) { - nativeDevice.DrawIndexedInstanced(numVertices, instanceCount, startIndex, baseVertex, 0); + SharpDX.Direct3D11.EffectTechnique technique = SetupEffectForDraw(); + int vertexCount = DxFormatConverter.CalculateVertexCount(primitiveType, primitiveCount); + + nativeDevice.InputAssembler.PrimitiveTopology = DxFormatConverter.Translate(primitiveType); + nativeDevice.Rasterizer.SetViewports(currentViewport); + nativeDevice.OutputMerger.SetTargets(this.depthStencilView, this.renderView); + + if (indexBuffer != null) + { + SetIndexBuffer(indexBuffer); + } + + for (int i = 0; i < technique.Description.PassCount; ++i) + { + technique.GetPassByIndex(i).Apply(nativeDevice); + nativeDevice.DrawIndexedInstanced(vertexCount, instanceCount, startIndex, baseVertex, 0); + } + + nativeDevice.InputAssembler.InputLayout.Dispose(); + nativeDevice.InputAssembler.InputLayout = null; } #endregion // DrawInstancedPrimitives @@ -360,9 +380,7 @@ namespace ANX.RenderSystem.Windows.DX11 private InputLayout 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(nativeDevice.Device, passSignature, vertexDeclaration); + var layout = CreateInputLayout(nativeDevice.Device, passSignature, currentVertexBuffer); nativeDevice.InputAssembler.InputLayout = layout; return layout; @@ -394,7 +412,17 @@ namespace ANX.RenderSystem.Windows.DX11 if (vertexBuffers == null) throw new ArgumentNullException("vertexBuffers"); - this.currentVertexBuffer = vertexBuffers[0].VertexBuffer; //TODO: hmmmmm, not nice :-) + this.currentVertexBufferCount = vertexBuffers.Length; + + 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].VertexBuffer; + } var nativeVertexBufferBindings = new SharpDX.Direct3D11.VertexBufferBinding[vertexBuffers.Length]; for (int i = 0; i < vertexBuffers.Length; i++) @@ -425,26 +453,51 @@ namespace ANX.RenderSystem.Windows.DX11 #endregion #region CreateInputLayout - private InputLayout CreateInputLayout(Device device, ShaderBytecode passSignature, VertexDeclaration vertexDeclaration) + private InputLayout CreateInputLayout(Device device, ShaderBytecode passSignature, params VertexDeclaration[] vertexDeclaration) { - VertexElement[] vertexElements = vertexDeclaration.GetVertexElements(); - int elementCount = vertexElements.Length; - InputElement[] inputElements = new InputElement[elementCount]; + //TODO: try to get rid of the list + List inputElements = new List(); + foreach (VertexDeclaration decl in vertexDeclaration) + { + foreach (VertexElement vertexElement in decl.GetVertexElements()) + { + inputElements.Add(CreateInputElementFromVertexElement(vertexElement, 0)); + } + } - for (int i = 0; i < elementCount; i++) - inputElements[i] = CreateInputElementFromVertexElement(vertexElements[i]); + return new InputLayout(device, passSignature, inputElements.ToArray()); + } + + private InputLayout CreateInputLayout(Device device, ShaderBytecode passSignature, params ANX.Framework.Graphics.VertexBufferBinding[] vertexBufferBindings) + { + //TODO: try to get rid of the list + List inputElements = new List(); + 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); + return new InputLayout(device, passSignature, inputElements.ToArray()); } #endregion #region CreateInputElementFromVertexElement - private InputElement CreateInputElementFromVertexElement(VertexElement vertexElement) + private InputElement CreateInputElementFromVertexElement(VertexElement vertexElement, int slot) + { + 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, 0); + return new InputElement(elementName, vertexElement.UsageIndex, elementFormat, vertexElement.Offset, slot, instanceFrequency == 0 ? InputClassification.PerVertexData : InputClassification.PerInstanceData, instanceFrequency); } #endregion