diff --git a/GlitchyEngine/src/Application.bf b/GlitchyEngine/src/Application.bf index 0d2b669..1f98f46 100644 --- a/GlitchyEngine/src/Application.bf +++ b/GlitchyEngine/src/Application.bf @@ -67,18 +67,20 @@ namespace GlitchyEngine //VertexLayout = new VertexLayout(); } } - + + VertexLayout _vertexLayout ~ delete _; VertexBuffer _vertexBuffer ~ delete _; IndexBuffer _indexBuffer ~ delete _; Buffer _cBuffer ~ delete _; RasterizerState _rasterizerState ~ delete _; - VertexLayout _vertexLayout ~ delete _; VertexShader _vertexShader ~ delete _; PixelShader _pixelShader ~ delete _; + GeometryBinding _geometryBinding ~ delete _; + private Vector3 CircleCoord(float angle) { return .(Math.Cos(angle), Math.Sin(angle), 0); @@ -134,6 +136,12 @@ namespace GlitchyEngine _indexBuffer = new IndexBuffer(Window.Context, (.)indices.Count, .Immutable); _indexBuffer.SetData(indices); + _geometryBinding = new GeometryBinding(); + _geometryBinding.SetVertexBufferSlot(_vertexBuffer, 0); + _geometryBinding.SetVertexLayout(_vertexLayout); + _geometryBinding.SetPrimitiveTopology(.TriangleList); + _geometryBinding.SetIndexBuffer(_indexBuffer); + // Create rasterizer state GlitchyEngine.Renderer.RasterizerStateDescription rsDesc = .(.Solid, .Back, true); _rasterizerState = new RasterizerState(Window.Context, rsDesc); @@ -167,12 +175,7 @@ namespace GlitchyEngine _window.Context.SetRenderTarget(null); _window.Context.BindRenderTargets(); - _window.Context.SetVertexBuffer(0, _vertexBuffer); - _window.Context.SetIndexBuffer(_indexBuffer); - - _window.Context.SetVertexLayout(_vertexLayout); - - _window.Context.SetPrimitiveTopology(.TriangleList); + _geometryBinding.Bind(_window.Context); _window.Context.SetVertexShader(_vertexShader); @@ -182,7 +185,7 @@ namespace GlitchyEngine _window.Context.SetPixelShader(_pixelShader); - _window.Context.DrawIndexed(3 * 6); + _window.Context.DrawIndexed(_geometryBinding.IndexCount); } for(Layer layer in _layerStack) diff --git a/GlitchyEngine/src/Platform/DX11/Renderer/Dx11GeometryBinding.bf b/GlitchyEngine/src/Platform/DX11/Renderer/Dx11GeometryBinding.bf new file mode 100644 index 0000000..429936f --- /dev/null +++ b/GlitchyEngine/src/Platform/DX11/Renderer/Dx11GeometryBinding.bf @@ -0,0 +1,98 @@ +using System; +using DirectX.D3D11; + +namespace GlitchyEngine.Renderer +{ + using internal GlitchyEngine.Renderer; + + extension GeometryBinding + { + internal ID3D11Buffer*[DirectX.D3D11.D3D11_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT] nativeBuffers; + internal uint32[DirectX.D3D11.D3D11_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT] bufferStrides; + internal uint32[DirectX.D3D11.D3D11_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT] bufferOffsets; + + internal ID3D11InputLayout* nativeVertexLayout; + internal ID3D11Buffer* nativeIndexBuffer; + + public ~this() + { + for(ID3D11Buffer* buffer in nativeBuffers) + { + buffer?.Release(); + } + + nativeVertexLayout?.Release(); + nativeIndexBuffer?.Release(); + } + + protected override void PlatformSetVertexBuffer(VertexBufferBinding binding, uint32 slot) + { + Log.EngineLogger.Assert(slot < nativeBuffers.Count, "The buffer slot has to be in the range from 0 to 31."); + + VertexBuffer vertexBuffer = binding.Buffer; + + if(vertexBuffer != null) + { + Log.EngineLogger.Assert(vertexBuffer.nativeDescription.BindFlags.HasFlag(.VertexBuffer), + scope $"Buffer ({vertexBuffer.nativeBuffer.GetDebugName(.. scope .())}) must have VertexBuffer-flag set to be bound as a vertex buffer."); + + nativeBuffers[slot]?.Release(); + + nativeBuffers[slot] = vertexBuffer.nativeBuffer..AddRef(); + + bufferStrides[slot] = vertexBuffer.Binding.Stride; + bufferOffsets[slot] = vertexBuffer.Binding.Offset; + } + else + { + nativeBuffers[slot]?.Release(); + + nativeBuffers[slot] = null; + bufferStrides[slot] = 0; + bufferOffsets[slot] = 0; + } + } + + protected override void PlatformSetVertexLayout(VertexLayout vertexLayout) + { + nativeVertexLayout?.Release(); + nativeVertexLayout = vertexLayout?.nativeLayout..AddRef(); + } + + protected override void PlatformSetIndexBuffer(IndexBuffer indexBuffer) + { + Log.EngineLogger.Assert(indexBuffer.nativeDescription.BindFlags.HasFlag(.IndexBuffer), + scope $"Buffer ({indexBuffer.nativeBuffer.GetDebugName(.. scope .())}) must have IndexBuffer-flag set to be bound as an index buffer."); + + nativeIndexBuffer?.Release(); + nativeIndexBuffer = indexBuffer.nativeBuffer..AddRef(); + } + + protected override void PlatformSetPrimitiveTopology(GlitchyEngine.Renderer.PrimitiveTopology topology) + { + + } + + public void Bind(GraphicsContext context) + { + context.nativeContext.InputAssembler.SetVertexBuffers(0, nativeBuffers.Count, &nativeBuffers, &bufferStrides, &bufferOffsets); + context.nativeContext.InputAssembler.SetInputLayout(_vertexLayout.nativeLayout); + context.nativeContext.InputAssembler.SetPrimitiveTopology((.)_primitiveTopology); + + context.nativeContext.InputAssembler.SetIndexBuffer(_indexBuffer.nativeBuffer, _indexBuffer.Format == .Index32Bit ? .R32_UInt : .R16_UInt, _indexByteOffset); + } + + public void Unbind(GraphicsContext context) + { + ID3D11Buffer*[nativeBuffers.Count] nullBuffers = .(); + uint32[nativeBuffers.Count] zeroStrides = .(); + uint32[nativeBuffers.Count] zeroOffsets = .(); + + context.nativeContext.InputAssembler.SetVertexBuffers(0, nativeBuffers.Count, &nullBuffers, &zeroStrides, &zeroOffsets); + context.nativeContext.InputAssembler.SetInputLayout(null); + context.nativeContext.InputAssembler.SetPrimitiveTopology(.Undefined); + + context.nativeContext.InputAssembler.SetIndexBuffer(null, .R16_UNorm, 0); + } + } +} diff --git a/GlitchyEngine/src/Renderer/GeometryBinding.bf b/GlitchyEngine/src/Renderer/GeometryBinding.bf new file mode 100644 index 0000000..408f026 --- /dev/null +++ b/GlitchyEngine/src/Renderer/GeometryBinding.bf @@ -0,0 +1,83 @@ +using System; +using System.Collections; + +namespace GlitchyEngine.Renderer +{ + public class GeometryBinding + { + internal List _vertexBuffers = new .() ~ delete _; + internal IndexBuffer _indexBuffer; + internal VertexLayout _vertexLayout; + internal uint32 _indexByteOffset; + internal uint32 _indexCount; + internal PrimitiveTopology _primitiveTopology; + + public VertexBufferBinding GetVertexBuffer(uint32 slot) + { + return _vertexBuffers[slot]; + } + + public IndexBuffer GetIndexBuffer() + { + return _indexBuffer; + } + + public VertexLayout GetVertexLayout() + { + return _vertexLayout; + } + + [Inline] + public uint32 IndexByteOffset => _indexByteOffset; + + [Inline] + public uint32 IndexCount => _indexCount; + + [Inline] + public PrimitiveTopology PrimitiveTopology => _primitiveTopology; + + public void SetVertexBufferSlot(VertexBufferBinding vertexBufferBinding, uint32 slot) + { + _vertexBuffers.Add(vertexBufferBinding); + + PlatformSetVertexBuffer(vertexBufferBinding, slot); + } + + protected extern void PlatformSetVertexBuffer(VertexBufferBinding vertexBuffer, uint32 slot); + + public void SetVertexLayout(VertexLayout vertexLayout) + { + _vertexLayout = vertexLayout; + PlatformSetVertexLayout(vertexLayout); + } + + protected extern void PlatformSetVertexLayout(VertexLayout layout); + + public void SetPrimitiveTopology(PrimitiveTopology topology) + { + _primitiveTopology = topology; + PlatformSetPrimitiveTopology(topology); + } + + protected extern void PlatformSetPrimitiveTopology(PrimitiveTopology topology); + + public void SetIndexBuffer(IndexBuffer indexBuffer, uint32 byteOffset = 0, uint32 indexCount = (.)-1) + { + _indexBuffer = indexBuffer; + _indexByteOffset = byteOffset; + + if(indexCount == (.)-1) + { + _indexCount = _indexBuffer.IndexCount - (uint32)(_indexByteOffset / _indexBuffer.Format.IndexSize); + } + else + { + _indexCount = indexCount; + } + + PlatformSetIndexBuffer(indexBuffer); + } + + protected extern void PlatformSetIndexBuffer(IndexBuffer indexBuffer); + } +}