Added Backbuffer to Swapchain + RenderCommand API changes

This commit is contained in:
Simon Lübeß
2021-10-15 22:40:42 +02:00
parent 90e654b750
commit ffafa380ea
14 changed files with 228 additions and 129 deletions
+3 -4
View File
@@ -100,15 +100,14 @@ namespace GlitchyEditor
TransformSystem.Update(_world);
RenderCommand.Clear(_renderTarget2D, .(0.2f, 0.2f, 0.2f));
RenderCommand.Clear(_renderTarget2D, 1.0f, 0, .Depth);
RenderCommand.Clear(_renderTarget2D, .Color | .Depth, .(0.2f, 0.2f, 0.2f), 1.0f, 0);
_context.SetRenderTarget(_renderTarget2D);
_context.BindRenderTargets();
RenderCommand.SetViewport(Viewport(0, 0, _renderTarget2D.Width, _renderTarget2D.Height));
_opaqueBlendState.Bind();
RenderCommand.SetBlendState(_opaqueBlendState);
Renderer.BeginScene(_cameraController.Camera);
@@ -117,7 +116,7 @@ namespace GlitchyEditor
Renderer.EndScene();
RenderCommand.Clear(null, .(0.2f, 0.2f, 0.2f));
RenderCommand.Clear(_swapchainDepthBuffer, 1.0f, 0, .Depth);
RenderCommand.Clear(_swapchainDepthBuffer, .Depth, 1.0f, 0);
_context.SetRenderTarget(null);
_context.SetDepthStencilTarget(_swapchainDepthBuffer);
@@ -15,11 +15,6 @@ namespace GlitchyEngine.Renderer
{
internal ID3D11BlendState* nativeBlendState ~ _?.Release();
public override void Bind(ColorRGBA blendFactor)
{
NativeContext.OutputMerger.SetBlendState(nativeBlendState, blendFactor);
}
protected override void PlatformCreateBlendState()
{
BlendDescription nativeDesc = .Default;
@@ -41,6 +41,8 @@ namespace GlitchyEngine.Renderer
nativeWindowHandle = windowHandle;
_swapChain = new SwapChain(this);
s_GraphicsContext = this;
}
public ~this()
@@ -112,20 +114,13 @@ namespace GlitchyEngine.Renderer
_depthStencilTarget = target?.nativeView;
}
public override void SetRenderTarget(RenderTarget2D renderTarget, int slot = 0)
public override void SetRenderTarget(RenderTarget2D renderTarget, int slot, bool setDepthTarget)
{
if(renderTarget == null || renderTarget.Description.IsSwapchainTarget)
{
_renderTargets[slot] = _swapChain.nativeBackBufferTarget;
}
else
{
_renderTargets[slot] = renderTarget._nativeRenderTargetView;
}
_renderTargets[slot] = (renderTarget ?? _swapChain.BackBuffer)._nativeRenderTargetView;
if(slot == 0)
if(slot == 0 && setDepthTarget)
{
SetDepthStencilTarget(renderTarget?.DepthStencilTarget);
SetDepthStencilTarget((renderTarget ?? _swapChain.BackBuffer).DepthStencilTarget);
}
}
@@ -136,14 +131,7 @@ namespace GlitchyEngine.Renderer
public override void ClearRenderTarget(RenderTarget2D renderTarget, ColorRGBA color)
{
if(renderTarget == null)
{
NativeContext.ClearRenderTargetView(_swapChain.nativeBackBufferTarget, color);
}
else
{
NativeContext.ClearRenderTargetView(renderTarget._nativeRenderTargetView, color);
}
NativeContext.ClearRenderTargetView((renderTarget ?? _swapChain.BackBuffer)._nativeRenderTargetView, color);
}
public override void SetVertexBuffer(uint32 slot, Buffer buffer, uint32 stride, uint32 offset = 0)
@@ -168,11 +156,6 @@ namespace GlitchyEngine.Renderer
NativeContext.InputAssembler.SetIndexBuffer(buffer.nativeBuffer, indexFormat == .Index32Bit ? .R32_UInt : .R16_UInt, byteOffset);
}
protected override void SetRasterizerStateImpl()
{
NativeContext.Rasterizer.SetState(_currentRasterizerState.nativeRasterizerState);
}
public override void SetViewports(uint32 viewportsCount, GlitchyEngine.Renderer.Viewport* viewports)
{
NativeContext.Rasterizer.SetViewports(viewportsCount, (.)viewports);
@@ -3,6 +3,7 @@
using DirectX.Common;
using DirectX.D3D11;
using GlitchyEngine.Platform.DX11;
using DirectX.DXGI.DXGI1_2;
using internal GlitchyEngine.Platform.DX11;
@@ -41,6 +42,18 @@ namespace GlitchyEngine.Renderer
PlatformCreateTexture();
if(_description.IsSwapchainTarget)
{
// TODO: if the engine supports multiple windows it has to support multiple swap chains.
// kinda dirty...
var context = GraphicsContext.Get();
context.SwapChain.GetBackbuffer(out _nativeTexture);
CreateViews();
}
if(_description.DepthStencilFormat != .None)
{
_depthStenilTarget = new DepthStencilTarget(_description.Width, _description.Height, _description.DepthStencilFormat);
@@ -27,21 +27,67 @@ namespace GlitchyEngine.Renderer
}
public override void Clear(RenderTarget2D renderTarget, ColorRGBA clearColor)
private mixin RtOrBackbuffer(RenderTarget2D renderTarget)
{
_context.ClearRenderTarget(renderTarget, clearColor);
renderTarget ?? _context.SwapChain.BackBuffer
}
public override void Clear(DepthStencilTarget target, float depthValue, uint8 stencilValue, DepthStencilClearFlag clearFlags)
public override void Clear(RenderTarget2D renderTarget, ColorRGBA color)
{
NativeContext.ClearDepthStencilView(target.nativeView, (.)clearFlags, depthValue, stencilValue);
NativeContext.ClearRenderTargetView(RtOrBackbuffer!(renderTarget)._nativeRenderTargetView, color);
}
public override void Clear(RenderTarget2D renderTarget, float depthValue, uint8 stencilValue, DepthStencilClearFlag clearFlags)
public override void Clear(DepthStencilTarget target, ClearOptions clearOptions, float depth, uint8 stencil)
{
NativeContext.ClearDepthStencilView(renderTarget._depthStenilTarget.nativeView, (.)clearFlags, depthValue, stencilValue);
if(target == null)
return;
DirectX.D3D11.ClearFlag flags = default;
if(clearOptions.HasFlag(.Depth))
{
flags |= .Depth;
}
if(clearOptions.HasFlag(.Stencil))
{
flags |= .Stencil;
}
NativeContext.ClearDepthStencilView(target.nativeView, flags, depth, stencil);
}
public override void SetRenderTarget(RenderTarget2D renderTarget, int slot, bool setDepthBuffer)
{
_context.SetRenderTarget(renderTarget, slot, setDepthBuffer);
}
public override void SetDepthStencilTarget(DepthStencilTarget target)
{
_context.SetDepthStencilTarget(target);
}
public override void BindRenderTargets()
{
_context.BindRenderTargets();
}
private RasterizerState _currentRasterizerState ~ _?.ReleaseRef();
public override void SetRasterizerState(RasterizerState rasterizerState)
{
SetReference!(_currentRasterizerState, rasterizerState);
NativeContext.Rasterizer.SetState(_currentRasterizerState.nativeRasterizerState);
}
private BlendState _currentBlendState ~ _?.ReleaseRef();
public override void SetBlendState(BlendState blendState, ColorRGBA blendFactor)
{
SetReference!(_currentBlendState, blendState);
NativeContext.OutputMerger.SetBlendState(_currentBlendState.nativeBlendState, blendFactor);
}
public override void DrawIndexed(GeometryBinding geometry)
{
if(geometry.IsIndexed)
@@ -12,47 +12,9 @@ namespace GlitchyEngine.Renderer
{
public extension SwapChain
{
private GraphicsContext _context;
private bool _changed;
private uint32 _width, _height;
internal DirectX.DXGI.IDXGIDevice* nativeDxgiDevice;
internal IDXGISwapChain1* nativeSwapChain;
internal ID3D11RenderTargetView* nativeBackBufferTarget;
public override uint32 Width
{
get => _width;
set
{
if(_width == value)
return;
_width = value;
_changed = true;
}
}
public override uint32 Height
{
get => _height;
set
{
if(_height == value)
return;
_height = value;
_changed = true;
}
}
public override GraphicsContext Context => _context;
public this(GraphicsContext context)
{
_context = context;
@@ -64,7 +26,6 @@ namespace GlitchyEngine.Renderer
{
nativeDxgiDevice?.Release();
nativeSwapChain?.Release();
nativeBackBufferTarget?.Release();
}
void SetResolutionFromWindow()
@@ -101,7 +62,8 @@ namespace GlitchyEngine.Renderer
if(nativeSwapChain != null)
{
nativeBackBufferTarget.Release();
//nativeBackBufferTarget.Release();
_backBuffer.ReleaseRef();
var resizeResult = nativeSwapChain.ResizeBuffers(backBufferCount, _width, _height, backBufferFormat, .None);
if(resizeResult.Failed)
@@ -122,7 +84,7 @@ namespace GlitchyEngine.Renderer
swDesc.Height = _height;
swDesc.Format = backBufferFormat;
swDesc.SampleDescription = .(1, 0);
swDesc.BufferUsage = .RenderTargetOutput;
swDesc.BufferUsage = .RenderTargetOutput | .ShaderInput;
swDesc.BufferCount = backBufferCount;
swDesc.SwapEffect = .FlipDiscard;
@@ -138,14 +100,20 @@ namespace GlitchyEngine.Renderer
factory.Release();
}
nativeSwapChain.GetBuffer<ID3D11Texture2D>(0, let backBuffer);
RenderTargetViewDescription rtvDesc = .(backBuffer, .Texture2D, backBufferViewFormat);
NativeDevice.CreateRenderTargetView(backBuffer, &rtvDesc, &nativeBackBufferTarget);
RenderTarget2DDescription desc = .(backBufferFormat, _width, _height);
desc.DepthStencilFormat = _depthStencilFormat;
desc.IsSwapchainTarget = true;
// Todo: perhaps just update the render target
_backBuffer = new RenderTarget2D(desc);
_backBufferViewport = GlitchyEngine.Renderer.Viewport(0, 0, _width, _height, 0.0f, 1.0f);
}
backBuffer.Release();
internal void GetBackbuffer(out ID3D11Texture2D* texture)
{
var result = nativeSwapChain.GetBuffer<ID3D11Texture2D>(0, out texture);
Log.EngineLogger.Assert(result.Succeeded, "Failed to get backbuffer.");
}
public override void Present()
-2
View File
@@ -85,8 +85,6 @@ namespace GlitchyEngine.Renderer
PlatformCreateBlendState();
}
public extern void Bind(ColorRGBA blendFactor = .White);
protected extern void PlatformCreateBlendState();
}
}
+4 -13
View File
@@ -6,7 +6,8 @@ namespace GlitchyEngine.Renderer
{
public class GraphicsContext : RefCounter
{
private RasterizerState _currentRasterizerState;
private static GraphicsContext s_GraphicsContext;
public static GraphicsContext Get() => s_GraphicsContext;
public extern SwapChain SwapChain {get;}
@@ -30,8 +31,9 @@ namespace GlitchyEngine.Renderer
* @BindRenderTargets has to be called in order to bind the rendertargets.
* @param renderTarget The render target to set. If null, the backbuffer will be set.
* @param slot The slot to which the rendertarget will be bound. If 0 the depth buffer of the current render target will be set. If it has no depthbuffer the current will be unset.
* @param setDepthTarget If set to true the depth stencil target of the given renderTarget will be bound (only applies if slot is 0).
*/
public extern void SetRenderTarget(RenderTarget2D renderTarget, int slot = 0);
public extern void SetRenderTarget(RenderTarget2D renderTarget, int slot = 0, bool setDepthTarget = true);
/**
* Binds all.
@@ -80,19 +82,8 @@ namespace GlitchyEngine.Renderer
public extern void SetIndexBuffer(Buffer buffer, IndexFormat indexFormat = .Index16Bit, uint32 byteOffset = 0);
public void SetRasterizerState(RasterizerState rasterizerState)
{
_currentRasterizerState = rasterizerState;
SetRasterizerStateImpl();
}
protected extern void SetRasterizerStateImpl();
public RasterizerState GetRasterizerState()
{
return _currentRasterizerState;
}
internal void SetViewport(Viewport viewport)
{
var viewport;
+38 -4
View File
@@ -3,12 +3,21 @@ using GlitchyEngine.Math;
namespace GlitchyEngine.Renderer
{
/*
public enum DepthStencilClearFlag
{
None = 0,
Depth = 1,
Stencil = 2
}
*/
public enum ClearOptions
{
None = 0,
Color = 1,
Depth = 2,
Stencil = 4
}
public static class RenderCommand
{
@@ -32,14 +41,39 @@ namespace GlitchyEngine.Renderer
_rendererAPI.Clear(renderTarget, color);
}
public static void Clear(DepthStencilTarget depthTarget, float depthValue, uint8 stencilValue, DepthStencilClearFlag clearFlags)
public static void Clear(DepthStencilTarget target, ClearOptions options, float depth, uint8 stencil)
{
_rendererAPI.Clear(depthTarget, depthValue, stencilValue, clearFlags);
_rendererAPI.Clear(target, options, depth, stencil);
}
public static void Clear(RenderTarget2D renderTarget, float depthValue, uint8 stencilValue, DepthStencilClearFlag clearFlags)
public static void Clear(RenderTarget2D renderTarget, ClearOptions options, ColorRGBA color, float depth, uint8 stencil)
{
_rendererAPI.Clear(renderTarget, depthValue, stencilValue, clearFlags);
_rendererAPI.Clear(renderTarget, options, color, depth, stencil);
}
public static void SetRenderTarget(RenderTarget2D renderTarget, int slot = 0, bool setDepthBuffer = false)
{
_rendererAPI.SetRenderTarget(renderTarget, slot, setDepthBuffer);
}
public static void SetDepthStencilTarget(DepthStencilTarget target)
{
_rendererAPI.SetDepthStencilTarget(target);
}
public static void BindRenderTargets()
{
_rendererAPI.BindRenderTargets();
}
public static void SetRasterizerState(RasterizerState rasterizerState)
{
_rendererAPI.SetRasterizerState(rasterizerState);
}
public static void SetBlendState(BlendState blendState, ColorRGBA blendFactor = .White)
{
_rendererAPI.SetBlendState(blendState, blendFactor);
}
[Inline]
+22 -3
View File
@@ -17,11 +17,30 @@ namespace GlitchyEngine.Renderer
public extern void Init();
public extern void Clear(RenderTarget2D renderTarget, ColorRGBA clearColor);
public extern void Clear(RenderTarget2D renderTarget, ColorRGBA color);
public extern void Clear(DepthStencilTarget target, float depthValue, uint8 stencilValue, DepthStencilClearFlag clearFlags);
public extern void Clear(DepthStencilTarget target, ClearOptions options, float depth, uint8 stencil);
public extern void Clear(RenderTarget2D renderTarget, float depthValue, uint8 stencilValue, DepthStencilClearFlag clearFlags);
public void Clear(RenderTarget2D renderTarget, ClearOptions options, ColorRGBA color, float depth, uint8 stencil)
{
var actualRt = (renderTarget ?? GraphicsContext.Get().SwapChain.BackBuffer);
if(options.HasFlag(.Color))
Clear(actualRt, color);
if((options.HasFlag(.Depth) || options.HasFlag(.Stencil)) && actualRt.DepthStencilTarget != null)
Clear(actualRt.DepthStencilTarget, options, depth, stencil);
}
public extern void SetRenderTarget(RenderTarget2D renderTarget, int slot, bool setDepthBuffer);
public extern void SetDepthStencilTarget(DepthStencilTarget target);
public extern void BindRenderTargets();
public extern void SetRasterizerState(RasterizerState rasterizerState);
public extern void SetBlendState(BlendState blendState, ColorRGBA blendFactor);
public extern void DrawIndexed(GeometryBinding geometry);
+58 -5
View File
@@ -2,22 +2,75 @@ namespace GlitchyEngine.Renderer
{
public class SwapChain
{
private GraphicsContext _context;
private bool _changed;
private uint32 _width, _height;
private Viewport _backBufferViewport;
public extern GraphicsContext Context {get;}
private DepthStencilFormat _depthStencilFormat = .None;
public RenderTarget2D _backBuffer ~ _?.ReleaseRef();
public GraphicsContext Context => _context;
/**
* Gets or Sets the backbuffers width.
* @remarks @ApplyChanges() needs to be called in order to apply the ganges.
* @remarks @ApplyChanges() needs to be called in order to apply the changes.
*/
public extern uint32 Width {get; set;}
public uint32 Width
{
get => _width;
set
{
if(_width == value)
return;
_width = value;
_changed = true;
}
}
/**
* Gets or Sets the backbuffers height.
* @remarks @ApplyChanges() needs to be called in order to apply the ganges.
* @remarks @ApplyChanges() needs to be called in order to apply the changes.
*/
public extern uint32 Height {get; set;}
public uint32 Height
{
get => _height;
set
{
if(_height == value)
return;
_height = value;
_changed = true;
}
}
public Viewport BackbufferViewport => _backBufferViewport;
/**
* Gets or Sets the format of the depth stencil buffer.
* If set to DepthStencilFormat.None DepthStencilTarget will be null.
* @remarks @ApplyChanges() needs to be called in order to apply the changes.
*/
public DepthStencilFormat DepthStencilFormat
{
get => _depthStencilFormat;
set
{
if(_depthStencilFormat == value)
return;
_depthStencilFormat = value;
_changed = true;
}
}
public RenderTarget2D BackBuffer => _backBuffer;
public extern void Init();
+7 -7
View File
@@ -83,20 +83,20 @@ namespace Sandbox
cameraController.Update(gameTime);
RenderCommand.Clear(null, .(0.2f, 0.2f, 0.2f));
RenderCommand.Clear(_depthTarget, 1.0f, 0, .Depth);
RenderCommand.Clear(_depthTarget, .Depth, 1.0f, 0);
// Draw test geometry
_context.SetRenderTarget(null);
_context.SetDepthStencilTarget(_depthTarget);
_context.BindRenderTargets();
RenderCommand.SetRenderTarget(null);
RenderCommand.SetDepthStencilTarget(_depthTarget);
RenderCommand.BindRenderTargets();
_context.SetRasterizerState(_rasterizerState);
RenderCommand.SetRasterizerState(_rasterizerState);
RenderCommand.SetViewport(_context.SwapChain.BackbufferViewport);
Renderer2D.BeginScene(cameraController.Camera, .BackToFront);
_alphaBlendState.Bind();
RenderCommand.SetBlendState(_alphaBlendState);
for(int x < 10)
for(int y < 10)
+8 -8
View File
@@ -346,22 +346,22 @@ namespace Sandbox
_cameraController.Update(gameTime);
RenderCommand.Clear(null, .(0.2f, 0.2f, 0.2f));
RenderCommand.Clear(_depthTarget, 1.0f, 0, .Depth);
RenderCommand.Clear(_depthTarget, .Depth, 1.0f, 0);
// Draw test geometry
_context.SetRenderTarget(null);
_context.SetDepthStencilTarget(_depthTarget);
_context.BindRenderTargets();
RenderCommand.SetRenderTarget(null);
RenderCommand.SetDepthStencilTarget(_depthTarget);
RenderCommand.BindRenderTargets();
RenderCommand.SetViewport(_context.SwapChain.BackbufferViewport);
Renderer.BeginScene(_cameraController.Camera);
_opaqueBlendState.Bind();
RenderCommand.SetBlendState(_opaqueBlendState);
var basicEffect = Application.Get().EffectLibrary.Get("basicShader");
_context.SetRasterizerState(_rasterizerState);
RenderCommand.SetRasterizerState(_rasterizerState);
TransformSystem.Update(_world);
@@ -471,8 +471,8 @@ namespace Sandbox
_checkerMaterial.SetVariable("BaseColor", Color.White);
Renderer.Submit(_quadGeometryBinding, _checkerMaterial, Matrix.RotationZ(f) * .Scaling(1.5f));
_alphaBlendState.Bind();
RenderCommand.SetBlendState(_alphaBlendState);
_logoMaterial.SetVariable("BaseColor", Color.Pink);
+2 -2
View File
@@ -169,8 +169,8 @@ namespace Sandbox
RenderCommand.SetViewport(vp);
// TODO: don't clear pink!
_context.ClearRenderTarget(_target, .Pink);
RenderCommand.Clear(_depth, 1.0f, 0, .Depth);
RenderCommand.Clear(_target, .Pink);
RenderCommand.Clear(_depth, .Depth, 1.0f, 0);
//_target.Bind();
_context.SetRenderTarget(_target);