diff --git a/GlitchyEngine/src/Platform/DX11/Renderer/Dx11GraphicsContext.bf b/GlitchyEngine/src/Platform/DX11/Renderer/Dx11GraphicsContext.bf index be58d83..38c027e 100644 --- a/GlitchyEngine/src/Platform/DX11/Renderer/Dx11GraphicsContext.bf +++ b/GlitchyEngine/src/Platform/DX11/Renderer/Dx11GraphicsContext.bf @@ -155,5 +155,10 @@ namespace GlitchyEngine.Renderer { nativeContext.Rasterizer.SetViewports(viewportsCount, (.)viewports); } + + public override void SetVertexLayout(VertexLayout vertexLayout) + { + nativeContext.InputAssembler.SetInputLayout(vertexLayout.nativeLayout); + } } } diff --git a/GlitchyEngine/src/Platform/DX11/Renderer/Dx11VertexLayout.bf b/GlitchyEngine/src/Platform/DX11/Renderer/Dx11VertexLayout.bf new file mode 100644 index 0000000..e6c1723 --- /dev/null +++ b/GlitchyEngine/src/Platform/DX11/Renderer/Dx11VertexLayout.bf @@ -0,0 +1,47 @@ +using System; +using DirectX.D3D11; +using System.Diagnostics; +using DirectX.Common; + +using internal GlitchyEngine.Renderer; + +namespace GlitchyEngine.Renderer +{ + public extension VertexLayout + { + internal ID3D11InputLayout* nativeLayout ~ _?.Release(); + + public ID3DBlob* nativeShaderCode; + + public this(GraphicsContext context, VertexElement[] ownElements, ID3DBlob* nativeShaderCode) + { + this.nativeShaderCode = nativeShaderCode; + + _context = context; + _elements = ownElements; + + CreateNativeLayout(); + } + + private void ToNativeLayout(VertexElement[] input, InputElementDescription[] output) + { + Debug.Assert(input.Count == output.Count); + + for(int i < input.Count) + output[i] = .(input[i].SemanticName, input[i].SemanticIndex, input[i].Format, input[i].InputSlot, input[i].AlignedByteOffset, (.)input[i].InputSlotClass); + } + + protected override void CreateNativeLayout() + { + var nativeElements = scope InputElementDescription[_elements.Count]; + + ToNativeLayout(_elements, nativeElements); + + var result = _context.nativeDevice.CreateInputLayout(nativeElements.CArray(), (.)nativeElements.Count, nativeShaderCode.GetBufferPointer(), nativeShaderCode.GetBufferSize(), &nativeLayout); + if(result.Failed) + { + Log.EngineLogger.Error($"Failed to create D3D11 input layout: Message({(int)result}): {result}"); + } + } + } +} diff --git a/GlitchyEngine/src/Renderer/Buffer.bf b/GlitchyEngine/src/Renderer/Buffer.bf index bd9ae56..53f03fd 100644 --- a/GlitchyEngine/src/Renderer/Buffer.bf +++ b/GlitchyEngine/src/Renderer/Buffer.bf @@ -179,101 +179,4 @@ namespace GlitchyEngine.Renderer */ protected extern Result PlatformSetData(void* data, uint32 byteLength, uint32 dstByteOffset, MapType mapType); } - - /** - * Type of data contained in an input slot. - */ - public enum InputClassification - { - /** - * Input data is per-vertex data. - */ - PerVertexData = 0, - /** - * Input data is per-instance data. - */ - PerInstanceData = 1 - } - - public struct VertexElement - { - /** - * The semantic associated with this element in a shader input-signature. - */ - public String SemanticName; - /** - * The semantic index for the element. - * A semantic index modifies a semantic, with an integer index number. - * A semantic index is only needed in a case where there is more than one element with the same semantic. - * For example, a 4x4 matrix would have four components each with the semantic name "matrix", - * however each of the four component would have different semantic indices (0, 1, 2, and 3). - */ - public uint32 SemanticIndex; - /** - * The data type of the element data. - */ - public Format Format; - /** - * An integer value that identifies the input-assembler (see input slot). Valid values are between 0 and 15. - */ - public uint32 InputSlot; - /** - * Optional. Offset (in bytes) from the start of the vertex. Use AppendAligned for convenience to define the current element directly after the previous one, including any packing if necessary. - */ - public uint32 AlignedByteOffset; - /** - * Identifies the input data class for a single input slot. - */ - public InputClassification InputSlotClass; - /** - * The number of instances to draw using the same per-instance data before advancing in the buffer by one element. - * This value must be 0 for an element that contains per-vertex data (the slot class is set to PerVertexData). - */ - public uint32 InstanceDataStepRate; - - public this() => this = default; - - public this(String semanticName, uint32 semanticIndex, Format format, uint32 inputSlot, uint32 offset = (.)-1, InputClassification slotClass = .PerVertexData, uint32 instanceStepRate = 0) - { - SemanticName = semanticName; - SemanticIndex = semanticIndex; - Format = format; - InputSlot = inputSlot; - AlignedByteOffset = offset; - InputSlotClass = slotClass; - InstanceDataStepRate = instanceStepRate; - } - - /** - * Use AppendAligned for convenience to define the current element directly after the previous one, including any packing if necessary. - */ - public static readonly uint32 AppendAligned = 0xffffffff; - } - - public abstract class VertexLayout - { - private GraphicsContext _context; - - private VertexElement[] _elements ~ delete _; - - public GraphicsContext Context => _context; - - public VertexElement[] Elements => _elements; - - /// Takes ownership of ownElements! - public this(GraphicsContext context, VertexElement[] ownElements) - { - _context = context; - _elements = ownElements; - - //CreateNativeLayout(); - } - - private extern void CreateNativeLayout(); - } - - public interface IVertexData - { - static VertexLayout VertexLayout {get;} - } } diff --git a/GlitchyEngine/src/Renderer/GraphicsContext.bf b/GlitchyEngine/src/Renderer/GraphicsContext.bf index f80dca7..286b8d9 100644 --- a/GlitchyEngine/src/Renderer/GraphicsContext.bf +++ b/GlitchyEngine/src/Renderer/GraphicsContext.bf @@ -108,5 +108,7 @@ namespace GlitchyEngine.Renderer } public extern void SetViewports(uint32 viewportsLength, Viewport* viewports); + + public extern void SetVertexLayout(VertexLayout vertexLayout); } } diff --git a/GlitchyEngine/src/Renderer/VertexLayout.bf b/GlitchyEngine/src/Renderer/VertexLayout.bf new file mode 100644 index 0000000..8531f9b --- /dev/null +++ b/GlitchyEngine/src/Renderer/VertexLayout.bf @@ -0,0 +1,103 @@ +using System; + +namespace GlitchyEngine.Renderer +{ + + /** + * Type of data contained in an input slot. + */ + public enum InputClassification + { + /** + * Input data is per-vertex data. + */ + PerVertexData = 0, + /** + * Input data is per-instance data. + */ + PerInstanceData = 1 + } + + public struct VertexElement + { + /** + * The semantic associated with this element in a shader input-signature. + */ + public String SemanticName; + /** + * The semantic index for the element. + * A semantic index modifies a semantic, with an integer index number. + * A semantic index is only needed in a case where there is more than one element with the same semantic. + * For example, a 4x4 matrix would have four components each with the semantic name "matrix", + * however each of the four component would have different semantic indices (0, 1, 2, and 3). + */ + public uint32 SemanticIndex; + /** + * The data type of the element data. + */ + public Format Format; + /** + * An integer value that identifies the input-assembler (see input slot). Valid values are between 0 and 15. + */ + public uint32 InputSlot; + /** + * Optional. Offset (in bytes) from the start of the vertex. Use AppendAligned for convenience to define the current element directly after the previous one, including any packing if necessary. + */ + public uint32 AlignedByteOffset; + /** + * Identifies the input data class for a single input slot. + */ + public InputClassification InputSlotClass; + /** + * The number of instances to draw using the same per-instance data before advancing in the buffer by one element. + * This value must be 0 for an element that contains per-vertex data (the slot class is set to PerVertexData). + */ + public uint32 InstanceDataStepRate; + + public this() => this = default; + + public this(String semanticName, uint32 semanticIndex, Format format, uint32 inputSlot, uint32 offset = (.)-1, InputClassification slotClass = .PerVertexData, uint32 instanceStepRate = 0) + { + SemanticName = semanticName; + SemanticIndex = semanticIndex; + Format = format; + InputSlot = inputSlot; + AlignedByteOffset = offset; + InputSlotClass = slotClass; + InstanceDataStepRate = instanceStepRate; + } + + /** + * Use AppendAligned for convenience to define the current element directly after the previous one, including any packing if necessary. + */ + public static readonly uint32 AppendAligned = 0xffffffff; + } + + public class VertexLayout + { + private GraphicsContext _context; + + private VertexElement[] _elements ~ delete _; + + public GraphicsContext Context => _context; + + public VertexElement[] Elements => _elements; + + // Todo: DirectX needs shader! + /// Takes ownership of ownElements! + public this(GraphicsContext context, VertexElement[] ownElements) + { + _context = context; + _elements = ownElements; + + CreateNativeLayout(); + } + + protected extern void CreateNativeLayout(); + } + + public interface IVertexData + { + static VertexLayout VertexLayout {get;} + } +}