mirror of
https://github.com/aharabada/glitchy-engine-beef.git
synced 2026-09-05 21:01:52 +00:00
Render basic geometry
Added GraphicsContext, SwapChain, Buffer, VertexBuffer, IndexBuffer and a basic DX11 implementation.
This commit is contained in:
@@ -2,6 +2,12 @@ using System;
|
|||||||
using GlitchyEngine.Events;
|
using GlitchyEngine.Events;
|
||||||
using GlitchyEngine.Platform.DX11;
|
using GlitchyEngine.Platform.DX11;
|
||||||
using GlitchyEngine.ImGui;
|
using GlitchyEngine.ImGui;
|
||||||
|
using GlitchyEngine.Math;
|
||||||
|
using DirectX.D3D11;
|
||||||
|
using DirectX.Common;
|
||||||
|
using DirectX.D3DCompiler;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using GlitchyEngine.Renderer;
|
||||||
|
|
||||||
namespace GlitchyEngine
|
namespace GlitchyEngine
|
||||||
{
|
{
|
||||||
@@ -34,6 +40,156 @@ namespace GlitchyEngine
|
|||||||
|
|
||||||
_imGuiLayer = new ImGuiLayer();
|
_imGuiLayer = new ImGuiLayer();
|
||||||
PushOverlay(_imGuiLayer);
|
PushOverlay(_imGuiLayer);
|
||||||
|
|
||||||
|
MakeTestTriangle();
|
||||||
|
}
|
||||||
|
|
||||||
|
struct VertexColor : IVertexData
|
||||||
|
{
|
||||||
|
public Vector3 Position;
|
||||||
|
public Color Color;
|
||||||
|
|
||||||
|
public this() => this = default;
|
||||||
|
|
||||||
|
public this(Vector3 pos, Color color)
|
||||||
|
{
|
||||||
|
Position = pos;
|
||||||
|
Color = color;
|
||||||
|
}
|
||||||
|
|
||||||
|
//public static readonly InputElementDescription[] InputLayout ~ delete _;
|
||||||
|
|
||||||
|
public static readonly VertexLayout VertexLayout ~ delete _;
|
||||||
|
|
||||||
|
public static VertexLayout IVertexData.VertexLayout => VertexLayout;
|
||||||
|
|
||||||
|
static this()
|
||||||
|
{
|
||||||
|
//VertexLayout = new VertexLayout();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
VertexBuffer<VertexColor> _vertexBuffer ~ delete _;
|
||||||
|
IndexBuffer _indexBuffer ~ delete _;
|
||||||
|
|
||||||
|
ID3D11VertexShader* _vertexShader ~ _?.Release();
|
||||||
|
ID3D11PixelShader* _pixelShader ~ _?.Release();
|
||||||
|
ID3D11InputLayout* _inputLayout ~ _?.Release();
|
||||||
|
|
||||||
|
ID3D11RasterizerState* _rasterizerState ~ _?.Release();
|
||||||
|
|
||||||
|
private Vector3 CircleCoord(float angle)
|
||||||
|
{
|
||||||
|
return .(Math.Cos(angle), Math.Sin(angle), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void MakeTestTriangle()
|
||||||
|
{
|
||||||
|
// Compile vertex shader
|
||||||
|
ID3DBlob* vsCode = null;
|
||||||
|
ID3DBlob* errorBlob = null;
|
||||||
|
var result = D3DCompiler.D3DCompileFromFile("content\\basicShader.hlsl".ToScopedNativeWChar!(), null, .StandardInclude, "VS", "vs_5_0", .Debug, .None, &vsCode, &errorBlob);
|
||||||
|
|
||||||
|
if(result.Failed || errorBlob != null)
|
||||||
|
{
|
||||||
|
Debug.Write("ERROR: Failed to compile Vertex Shader: {}", result);
|
||||||
|
//ErrorPrinter.PrintErrorBlob(errorBlob);
|
||||||
|
Runtime.FatalError("Failed to compile Vertex Shader");
|
||||||
|
}
|
||||||
|
|
||||||
|
result = Dx11Cheater.Device.CreateVertexShader(vsCode.GetBufferPointer(), vsCode.GetBufferSize(), null, &_vertexShader);
|
||||||
|
|
||||||
|
if(result.Failed)
|
||||||
|
{
|
||||||
|
Debug.Write("ERROR: Failed to create Vertex Shader: {}", result);
|
||||||
|
Runtime.FatalError("Failed to create Vertex Shader");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create Input Layout
|
||||||
|
|
||||||
|
InputElementDescription[2] elementDescs = .(
|
||||||
|
InputElementDescription("POSITION", 0, .R32G32B32_Float, 0),
|
||||||
|
InputElementDescription("COLOR", 0, .R8G8B8A8_UNorm, 0)
|
||||||
|
);
|
||||||
|
|
||||||
|
result = Dx11Cheater.Device.CreateInputLayout(&elementDescs, (.)elementDescs.Count, vsCode.GetBufferPointer(), vsCode.GetBufferSize(), &_inputLayout);
|
||||||
|
|
||||||
|
vsCode.Release();
|
||||||
|
|
||||||
|
if(result.Failed)
|
||||||
|
{
|
||||||
|
Debug.Write("ERROR: Failed to create input layout: {}", result);
|
||||||
|
Runtime.FatalError("Failed to create input layout");
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Load pixel shader
|
||||||
|
//
|
||||||
|
|
||||||
|
ID3DBlob* psCode = null;
|
||||||
|
|
||||||
|
result = D3DCompiler.D3DCompileFromFile("content\\basicShader.hlsl".ToScopedNativeWChar!(), null, .StandardInclude, "PS", "ps_5_0", .Debug, .None, &psCode, &errorBlob);
|
||||||
|
|
||||||
|
if(result.Failed || errorBlob != null)
|
||||||
|
{
|
||||||
|
Debug.Write("ERROR: Failed to compile Pixel Shader: {}", result);
|
||||||
|
//ErrorPrinter.PrintErrorBlob(errorBlob);
|
||||||
|
Runtime.FatalError("Failed to compile Pixel Shader");
|
||||||
|
}
|
||||||
|
|
||||||
|
result = Dx11Cheater.Device.CreatePixelShader(psCode.GetBufferPointer(), psCode.GetBufferSize(), null, &_pixelShader);
|
||||||
|
|
||||||
|
psCode.Release();
|
||||||
|
|
||||||
|
if(result.Failed)
|
||||||
|
{
|
||||||
|
Debug.Write("ERROR: Failed to create Pixel Shader: {}", result);
|
||||||
|
Runtime.FatalError("Failed to create Pixel Shader");
|
||||||
|
}
|
||||||
|
|
||||||
|
float pO3 = Math.PI_f / 3.0f;
|
||||||
|
VertexColor[?] vertices = .(
|
||||||
|
VertexColor(.Zero, Color(255,255,255)),
|
||||||
|
VertexColor(CircleCoord(0), Color(255, 0, 0)),
|
||||||
|
VertexColor(CircleCoord(pO3), Color(255,255, 0)),
|
||||||
|
VertexColor(CircleCoord(pO3*2), Color( 0,255, 0)),
|
||||||
|
VertexColor(CircleCoord(Math.PI_f), Color( 0,255,255)),
|
||||||
|
VertexColor(CircleCoord(-pO3*2), Color( 0, 0,255)),
|
||||||
|
VertexColor(CircleCoord(-pO3), Color(255, 0,255)),
|
||||||
|
);
|
||||||
|
|
||||||
|
_vertexBuffer = new VertexBuffer<VertexColor>(Window.Context, (.)vertices.Count, .Immutable);
|
||||||
|
_vertexBuffer.SetData(vertices);
|
||||||
|
|
||||||
|
uint16[?] indices = .(
|
||||||
|
0, 1, 2,
|
||||||
|
0, 2, 3,
|
||||||
|
0, 3, 4,
|
||||||
|
0, 4, 5,
|
||||||
|
0, 5, 6,
|
||||||
|
0, 6, 1);
|
||||||
|
|
||||||
|
_indexBuffer = new IndexBuffer(Window.Context, (.)indices.Count, .Immutable);
|
||||||
|
_indexBuffer.SetData(indices);
|
||||||
|
|
||||||
|
if(result.Failed)
|
||||||
|
{
|
||||||
|
Debug.Write("ERROR: Failed to create Vertex Buffer: {}", result);
|
||||||
|
Runtime.FatalError();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create rasterizer state
|
||||||
|
RasterizerStateDescription rsDesc = .();
|
||||||
|
rsDesc.CullMode = .Back;
|
||||||
|
rsDesc.FillMode = .Solid;
|
||||||
|
rsDesc.FrontCounterClockwise = true;
|
||||||
|
|
||||||
|
result = Dx11Cheater.Device.CreateRasterizerState(ref rsDesc, &_rasterizerState);
|
||||||
|
if(result.Failed)
|
||||||
|
{
|
||||||
|
Debug.Write("ERROR: Failed to create Rasterizer State: {}", result);
|
||||||
|
Runtime.FatalError("Failed to create Rasterizer State");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void OnEvent(Event e)
|
public void OnEvent(Event e)
|
||||||
@@ -57,16 +213,38 @@ namespace GlitchyEngine
|
|||||||
|
|
||||||
Input.NewFrame();
|
Input.NewFrame();
|
||||||
|
|
||||||
DirectX.ImmediateContext.ClearRenderTargetView(DirectX.BackBufferTarget, .(1, 0, 1));
|
_window.Context.ClearRenderTarget(null, .(0.2f, 0.2f, 0.2f));
|
||||||
|
|
||||||
for(Layer layer in _layerStack)
|
for(Layer layer in _layerStack)
|
||||||
layer.Update(_gameTime);
|
layer.Update(_gameTime);
|
||||||
|
|
||||||
_window.Update();
|
_window.Update();
|
||||||
|
|
||||||
|
_window.Context.SetRenderTarget(null);
|
||||||
|
_window.Context.BindRenderTargets();
|
||||||
|
|
||||||
|
Window.Context.SetVertexBuffer(0, _vertexBuffer);
|
||||||
|
Window.Context.SetIndexBuffer(_indexBuffer);
|
||||||
|
|
||||||
|
var _immediateContext = Dx11Cheater.ImmediateContext;
|
||||||
|
|
||||||
|
_immediateContext.InputAssembler.SetInputLayout(_inputLayout);
|
||||||
|
_immediateContext.InputAssembler.SetPrimitiveTopology(.TriangleList);
|
||||||
|
|
||||||
|
_immediateContext.VertexShader.SetShader(_vertexShader, null, 0);
|
||||||
|
|
||||||
|
_immediateContext.Rasterizer.SetState(_rasterizerState);
|
||||||
|
|
||||||
|
|
||||||
|
_immediateContext.Rasterizer.SetViewports(1, &Dx11Cheater.BackbufferViewport);
|
||||||
|
|
||||||
|
_immediateContext.PixelShader.SetShader(_pixelShader, null, 0);
|
||||||
|
|
||||||
|
Window.Context.DrawIndexed(3 * 6);
|
||||||
|
|
||||||
_imGuiLayer.ImGuiRender();
|
_imGuiLayer.ImGuiRender();
|
||||||
|
|
||||||
DirectX.Present();
|
Window.Context.SwapChain.Present();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ using GlitchyEngine.Events;
|
|||||||
|
|
||||||
// Temporary
|
// Temporary
|
||||||
using GlitchyEngine.Platform.DX11;
|
using GlitchyEngine.Platform.DX11;
|
||||||
|
//using GlitchyEngine.Platform.DX11.Renderer;
|
||||||
|
|
||||||
namespace GlitchyEngine.ImGui
|
namespace GlitchyEngine.ImGui
|
||||||
{
|
{
|
||||||
@@ -40,8 +41,12 @@ namespace GlitchyEngine.ImGui
|
|||||||
#if GE_WINDOWS
|
#if GE_WINDOWS
|
||||||
// Todo: temporary, needs to be platform independent
|
// Todo: temporary, needs to be platform independent
|
||||||
ImGuiImplWin32.Init((Windows.HWnd)(int)Application.Get().Window.NativeWindow);
|
ImGuiImplWin32.Init((Windows.HWnd)(int)Application.Get().Window.NativeWindow);
|
||||||
ImGuiImplDX11.Init(Platform.DX11.DirectX.Device, Platform.DX11.DirectX.ImmediateContext);
|
|
||||||
|
var context = Application.Get().Window.Context;
|
||||||
|
|
||||||
|
ImGuiImplDX11.Init(context.[Friend]nativeDevice, context.[Friend]nativeContext);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void OnDetach()
|
public override void OnDetach()
|
||||||
@@ -174,8 +179,10 @@ namespace GlitchyEngine.ImGui
|
|||||||
|
|
||||||
public void Begin()
|
public void Begin()
|
||||||
{
|
{
|
||||||
var v = DirectX.ImmediateContext;
|
// Todo:
|
||||||
v.OutputMerger.SetRenderTargets(1, &DirectX.BackBufferTarget, null);
|
//var v = DirectX.ImmediateContext;
|
||||||
|
//v.OutputMerger.SetRenderTargets(1, &DirectX.BackBufferTarget, null);
|
||||||
|
Application.Get().Window.Context.SetRenderTarget(null);
|
||||||
|
|
||||||
ImGuiImplDX11.NewFrame();
|
ImGuiImplDX11.NewFrame();
|
||||||
ImGuiImplWin32.NewFrame();
|
ImGuiImplWin32.NewFrame();
|
||||||
|
|||||||
@@ -0,0 +1,14 @@
|
|||||||
|
namespace GlitchyEngine.Math
|
||||||
|
{
|
||||||
|
typealias Color = DirectX.Color;
|
||||||
|
typealias ColorRGB = DirectX.ColorRGB;
|
||||||
|
typealias ColorRGBA = DirectX.ColorRGBA;
|
||||||
|
|
||||||
|
typealias Vector2 = DirectX.Math.Vector2;
|
||||||
|
typealias Vector3 = DirectX.Math.Vector3;
|
||||||
|
typealias Vector4 = DirectX.Math.Vector4;
|
||||||
|
|
||||||
|
typealias Matrix3x3 = DirectX.Math.Matrix3x3;
|
||||||
|
typealias Matrix4x3 = DirectX.Math.Matrix4x3;
|
||||||
|
typealias Matrix = DirectX.Math.Matrix;
|
||||||
|
}
|
||||||
@@ -2,6 +2,7 @@ using System;
|
|||||||
|
|
||||||
namespace GlitchyEngine.Math
|
namespace GlitchyEngine.Math
|
||||||
{
|
{
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A 2D point represented by two 32bit integers.
|
* A 2D point represented by two 32bit integers.
|
||||||
*/
|
*/
|
||||||
@@ -126,4 +127,5 @@ namespace GlitchyEngine.Math
|
|||||||
//
|
//
|
||||||
public override void ToString(String strBuffer) => strBuffer.AppendF("X={0} Y={1}", X, Y);
|
public override void ToString(String strBuffer) => strBuffer.AppendF("X={0} Y={1}", X, Y);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,169 +0,0 @@
|
|||||||
using System;
|
|
||||||
using DirectX;
|
|
||||||
using DirectX.D3D11;
|
|
||||||
using DirectX.Common;
|
|
||||||
using System.Diagnostics;
|
|
||||||
using DirectX.DXGI;
|
|
||||||
using DirectX.DXGI.DXGI1_2;
|
|
||||||
using DirectX.D3D11.SDKLayers;
|
|
||||||
using static System.Windows;
|
|
||||||
|
|
||||||
namespace GlitchyEngine.Platform.DX11
|
|
||||||
{
|
|
||||||
public static class DirectX
|
|
||||||
{
|
|
||||||
public static ID3D11Device* Device;
|
|
||||||
public static ID3D11DeviceContext* ImmediateContext;
|
|
||||||
public static ID3D11Debug* DebugDevice;
|
|
||||||
|
|
||||||
public static IDXGIDevice* DxgiDevice;
|
|
||||||
public static IDXGISwapChain1* SwapChain;
|
|
||||||
|
|
||||||
public static ID3D11RenderTargetView* BackBufferTarget;
|
|
||||||
public static Viewport BackBufferViewport;
|
|
||||||
|
|
||||||
static HWnd _windowHandle;
|
|
||||||
|
|
||||||
static ~this()
|
|
||||||
{
|
|
||||||
Shutdown();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void Init(HWnd windowHandle, uint32 width, uint32 height)
|
|
||||||
{
|
|
||||||
_windowHandle = windowHandle;
|
|
||||||
|
|
||||||
InitDevice();
|
|
||||||
UpdateSwapchain(width, height);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initializes the Device and ImmediateContext.
|
|
||||||
*/
|
|
||||||
static void InitDevice()
|
|
||||||
{
|
|
||||||
Device?.Release();
|
|
||||||
Device = null;
|
|
||||||
|
|
||||||
ImmediateContext?.Release();
|
|
||||||
ImmediateContext = null;
|
|
||||||
|
|
||||||
Log.EngineLogger.Trace("Creating D3D11 Device and Context...");
|
|
||||||
|
|
||||||
DeviceCreationFlags deviceFlags = .None;
|
|
||||||
#if DEBUG
|
|
||||||
deviceFlags |= .Debug;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
FeatureLevel[] levels = scope .(.Level_11_0);
|
|
||||||
|
|
||||||
var deviceResult = D3D11.CreateDevice(null, .Hardware, 0, deviceFlags, levels, &Device, let deviceLevel, &ImmediateContext);
|
|
||||||
Debug.Assert(deviceResult.Succeeded, scope $"Failed to create D3D11 Device. Message(0x{(int32)deviceResult}): {deviceResult}");
|
|
||||||
|
|
||||||
#if DEBUG
|
|
||||||
if(Device.QueryInterface<ID3D11Debug>(out DebugDevice).Succeeded)
|
|
||||||
{
|
|
||||||
ID3D11InfoQueue* infoQueue;
|
|
||||||
if(Device.QueryInterface<ID3D11InfoQueue>(out infoQueue).Succeeded)
|
|
||||||
{
|
|
||||||
infoQueue.SetBreakOnSeverity(.Corruption, true);
|
|
||||||
infoQueue.SetBreakOnSeverity(.Error, true);
|
|
||||||
|
|
||||||
infoQueue.Release();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
Log.EngineLogger.Trace("D3D11 Device and Context created (Feature level: {})", deviceLevel);
|
|
||||||
}
|
|
||||||
|
|
||||||
static uint32 _width, _height;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initializes the swapchain.
|
|
||||||
*/
|
|
||||||
public static void UpdateSwapchain(uint32 width, uint32 height)
|
|
||||||
{
|
|
||||||
if(_width == width && _height == height)
|
|
||||||
return;
|
|
||||||
|
|
||||||
_width = width;
|
|
||||||
_height = height;
|
|
||||||
|
|
||||||
Log.EngineLogger.Trace("Updating swap chain ({}, {})", width, height);
|
|
||||||
|
|
||||||
uint32 backBufferCount = 2;
|
|
||||||
Format backBufferFormat = .R8G8B8A8_UNorm;
|
|
||||||
Format backBufferViewFormat = .R8G8B8A8_UNorm; // _SRGB
|
|
||||||
|
|
||||||
if(SwapChain != null)
|
|
||||||
{
|
|
||||||
BackBufferTarget.Release();
|
|
||||||
|
|
||||||
var resizeResult = SwapChain.ResizeBuffers(backBufferCount, width, height, backBufferFormat, .None);
|
|
||||||
Debug.Assert(resizeResult.Succeeded, scope $"Failed to resize swap chain. Message({(int32)resizeResult}):{resizeResult}");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Device.QueryInterface(out DxgiDevice);
|
|
||||||
|
|
||||||
DxgiDevice.GetAdapter(let adapter);
|
|
||||||
adapter.GetParent<IDXGIFactory2>(let factory);
|
|
||||||
adapter.Release();
|
|
||||||
|
|
||||||
SwapChainDescription1 swDesc = .();
|
|
||||||
swDesc.Width = width;
|
|
||||||
swDesc.Height = height;
|
|
||||||
swDesc.Format = backBufferFormat;
|
|
||||||
swDesc.SampleDescription = .(1, 0);
|
|
||||||
swDesc.BufferUsage = .RenderTargetOutput;
|
|
||||||
swDesc.BufferCount = backBufferCount;
|
|
||||||
swDesc.SwapEffect = .FlipDiscard;
|
|
||||||
|
|
||||||
SwapChainFullscreenDescription fsSwapChainDesc = .();
|
|
||||||
fsSwapChainDesc.Windowed = true;
|
|
||||||
|
|
||||||
var createResult = factory.CreateSwapChainForHwnd((.)Device, _windowHandle, ref swDesc, &fsSwapChainDesc, null, &SwapChain);
|
|
||||||
Debug.Assert(createResult.Succeeded, scope $"Failed to create swap chain. Message({(int32)createResult}):{createResult}");
|
|
||||||
|
|
||||||
factory.Release();
|
|
||||||
}
|
|
||||||
|
|
||||||
SwapChain.GetBuffer<ID3D11Texture2D>(0, let backBuffer);
|
|
||||||
|
|
||||||
RenderTargetViewDescription rtvDesc = .(backBuffer, .Texture2D, backBufferViewFormat);
|
|
||||||
Device.CreateRenderTargetView(backBuffer, &rtvDesc, &BackBufferTarget);
|
|
||||||
|
|
||||||
BackBufferViewport = Viewport(0, 0, width, height, 0.0f, 1.0f);
|
|
||||||
|
|
||||||
backBuffer.Release();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void Shutdown()
|
|
||||||
{
|
|
||||||
Device?.Release();
|
|
||||||
Device = null;
|
|
||||||
|
|
||||||
ImmediateContext?.Release();
|
|
||||||
ImmediateContext = null;
|
|
||||||
|
|
||||||
DxgiDevice?.Release();
|
|
||||||
DxgiDevice = null;
|
|
||||||
|
|
||||||
SwapChain?.Release();
|
|
||||||
SwapChain = null;
|
|
||||||
|
|
||||||
BackBufferTarget?.Release();
|
|
||||||
BackBufferTarget = null;
|
|
||||||
|
|
||||||
DebugDevice.ReportLiveDeviceObjects(.Detail);
|
|
||||||
DebugDevice?.Release();
|
|
||||||
DebugDevice = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void Present()
|
|
||||||
{
|
|
||||||
SwapChain.Present(Application.Get().Window.IsVSync ? 1 : 0, .None);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
using DirectX.D3D11;
|
||||||
|
using DirectX.DXGI;
|
||||||
|
|
||||||
|
namespace GlitchyEngine.Platform.DX11
|
||||||
|
{
|
||||||
|
public static class Dx11Cheater
|
||||||
|
{
|
||||||
|
public static ID3D11Device* Device;
|
||||||
|
public static ID3D11DeviceContext* ImmediateContext;
|
||||||
|
|
||||||
|
public static ID3D11DeviceContext* Context => ImmediateContext;
|
||||||
|
|
||||||
|
public static IDXGISwapChain* SwapChain;
|
||||||
|
public static ID3D11RenderTargetView* BackbufferTarget;
|
||||||
|
public static Viewport BackbufferViewport;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,135 @@
|
|||||||
|
using System.Diagnostics;
|
||||||
|
using System;
|
||||||
|
using DirectX.D3D11;
|
||||||
|
|
||||||
|
using internal GlitchyEngine.Renderer;
|
||||||
|
|
||||||
|
namespace GlitchyEngine.Renderer
|
||||||
|
{
|
||||||
|
extension CPUAccessFlags
|
||||||
|
{
|
||||||
|
public static explicit operator DirectX.D3D11.CpuAccessFlags(Self cpuAccessFlags)
|
||||||
|
{
|
||||||
|
DirectX.D3D11.CpuAccessFlags flags = .None;
|
||||||
|
|
||||||
|
if(cpuAccessFlags.HasFlag(.Read))
|
||||||
|
flags |= .Read;
|
||||||
|
|
||||||
|
if(cpuAccessFlags.HasFlag(.Write))
|
||||||
|
flags |= .Write;
|
||||||
|
|
||||||
|
return flags;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension BufferDescription
|
||||||
|
{
|
||||||
|
public static operator DirectX.D3D11.BufferDescription(Self desc)
|
||||||
|
{
|
||||||
|
DirectX.D3D11.BufferDescription result;
|
||||||
|
|
||||||
|
result.ByteWidth = desc.Size;
|
||||||
|
result.Usage = (.)desc.Usage;
|
||||||
|
|
||||||
|
result.CpuAccessFlags = (.)desc.CPUAccess;
|
||||||
|
|
||||||
|
result.BindFlags = .None;
|
||||||
|
if(desc.BindFlags.HasFlag(.Constant))
|
||||||
|
{
|
||||||
|
result.BindFlags |= .ConstantBuffer;
|
||||||
|
}
|
||||||
|
if(desc.BindFlags.HasFlag(.Index))
|
||||||
|
{
|
||||||
|
result.BindFlags |= .IndexBuffer;
|
||||||
|
}
|
||||||
|
if(desc.BindFlags.HasFlag(.Vertex))
|
||||||
|
{
|
||||||
|
result.BindFlags |= .VertexBuffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
result.MiscFlags = .None;
|
||||||
|
result.StructureByteStride = 0;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public extension MapType
|
||||||
|
{
|
||||||
|
public static explicit operator DirectX.D3D11.MapType(Self mapType)
|
||||||
|
{
|
||||||
|
return (.)(uint32)mapType;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public extension Buffer
|
||||||
|
{
|
||||||
|
// Todo: nativeBuffer contains exactly that!
|
||||||
|
internal DirectX.D3D11.BufferDescription nativeDescription;
|
||||||
|
|
||||||
|
internal ID3D11Buffer* nativeBuffer ~ _?.Release();
|
||||||
|
|
||||||
|
private Result<void> InternalCreateBuffer(void* data, uint32 byteLength, uint32 dstByteOffset)
|
||||||
|
{
|
||||||
|
nativeDescription = (.)_description;
|
||||||
|
|
||||||
|
uint8* byteData = (.)data;
|
||||||
|
|
||||||
|
if(dstByteOffset == 0)
|
||||||
|
{
|
||||||
|
byteData = new uint8[nativeDescription.ByteWidth]*;
|
||||||
|
defer:: delete byteData;
|
||||||
|
Internal.MemCpy(byteData + dstByteOffset, data, byteLength);
|
||||||
|
}
|
||||||
|
|
||||||
|
SubresourceData srData = .(byteData, byteLength, 0);
|
||||||
|
var result = _context.nativeDevice.CreateBuffer(ref nativeDescription, &srData, &nativeBuffer);
|
||||||
|
if(result.Failed)
|
||||||
|
{
|
||||||
|
Log.EngineLogger.Error("Failed to create buffer. Message({}):{}", (int)result, result);
|
||||||
|
return .Err;
|
||||||
|
}
|
||||||
|
|
||||||
|
return .Ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override Result<void> PlatformSetData(void* data, uint32 byteLength, uint32 dstByteOffset, GlitchyEngine.Renderer.MapType mapType)
|
||||||
|
{
|
||||||
|
if(nativeBuffer == null)
|
||||||
|
{
|
||||||
|
// We can pass the data while creating the buffer, so we can return here.
|
||||||
|
return InternalCreateBuffer(data, byteLength, dstByteOffset);
|
||||||
|
}
|
||||||
|
|
||||||
|
Debug.Assert(dstByteOffset + byteLength <= _description.Size, "The destination offset and byte length are too long for the target buffer.");
|
||||||
|
|
||||||
|
switch(nativeDescription.Usage)
|
||||||
|
{
|
||||||
|
case .Default:
|
||||||
|
Box dataBox = .(dstByteOffset, 0, 0, dstByteOffset + byteLength, 1, 1);
|
||||||
|
_context.nativeContext.UpdateSubresource(nativeBuffer, 0, &dataBox, data, byteLength, byteLength);
|
||||||
|
case .Dynamic:
|
||||||
|
Debug.Assert(mapType.CanWrite, "The map type has to have write access.");
|
||||||
|
// Todo: DoNotWaitFlag
|
||||||
|
MappedSubresource map = ?;
|
||||||
|
_context.nativeContext.Map(nativeBuffer, 0, (.)mapType, .None, &map);
|
||||||
|
Internal.MemCpy(((uint8*)map.Data) + dstByteOffset, data, byteLength);
|
||||||
|
_context.nativeContext.Unmap(nativeBuffer, 0);
|
||||||
|
Runtime.NotImplemented();
|
||||||
|
case .Immutable:
|
||||||
|
Log.EngineLogger.Error("Can't set the data of an immutable resource.");
|
||||||
|
return .Err;
|
||||||
|
default:
|
||||||
|
Log.EngineLogger.Error("Unknown resource usage: engine={}, native={}", _description.Usage, nativeDescription.Usage);
|
||||||
|
return .Err;
|
||||||
|
}
|
||||||
|
|
||||||
|
return .Ok;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public extension VertexBuffer<T>
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,159 @@
|
|||||||
|
using System;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using DirectX.Common;
|
||||||
|
using DirectX.D3D11;
|
||||||
|
using DirectX.D3D11.SDKLayers;
|
||||||
|
using DirectX.DXGI.DXGI1_2;
|
||||||
|
using GlitchyEngine.Renderer;
|
||||||
|
using GlitchyEngine.Math;
|
||||||
|
|
||||||
|
using GlitchyEngine.Platform.DX11;
|
||||||
|
|
||||||
|
using internal GlitchyEngine.Renderer;
|
||||||
|
//using internal GlitchyEngine.Platform.DX11.Renderer;
|
||||||
|
|
||||||
|
namespace GlitchyEngine.Renderer
|
||||||
|
//namespace GlitchyEngine.Platform.DX11.Renderer
|
||||||
|
{
|
||||||
|
/// DirectX 11 specific implementation of the GraphicsContext
|
||||||
|
extension GraphicsContext
|
||||||
|
//public class Dx11Context : GraphicsContext
|
||||||
|
{
|
||||||
|
//private Dx11SwapChain _swapChain;
|
||||||
|
private SwapChain _swapChain;
|
||||||
|
|
||||||
|
internal Windows.HWnd nativeWindowHandle;
|
||||||
|
|
||||||
|
internal ID3D11Device* nativeDevice;
|
||||||
|
internal ID3D11DeviceContext* nativeContext;
|
||||||
|
|
||||||
|
private ID3D11Debug* _debugDevice;
|
||||||
|
|
||||||
|
public override SwapChain SwapChain => _swapChain;
|
||||||
|
|
||||||
|
private const uint32 MaxRTVCount = DirectX.D3D11.D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT;
|
||||||
|
|
||||||
|
//public static override uint32 MaxRenderTargetCount() => MaxRTVCount;
|
||||||
|
|
||||||
|
public this(Windows.HWnd windowHandle)
|
||||||
|
{
|
||||||
|
nativeWindowHandle = windowHandle;
|
||||||
|
|
||||||
|
_swapChain = new SwapChain(this);
|
||||||
|
//_swapChain = new Dx11SwapChain(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ~this()
|
||||||
|
{
|
||||||
|
delete _swapChain;
|
||||||
|
|
||||||
|
nativeDevice?.Release();
|
||||||
|
nativeContext?.Release();
|
||||||
|
_debugDevice.ReportLiveDeviceObjects(.Detail);
|
||||||
|
_debugDevice?.Release();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Init()
|
||||||
|
{
|
||||||
|
InitDevice();
|
||||||
|
|
||||||
|
SwapChain.Init();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes the Device and ImmediateContext.
|
||||||
|
*/
|
||||||
|
void InitDevice()
|
||||||
|
{
|
||||||
|
nativeDevice?.Release();
|
||||||
|
nativeContext?.Release();
|
||||||
|
|
||||||
|
Log.EngineLogger.Trace("Creating D3D11 Device and Context...");
|
||||||
|
|
||||||
|
DeviceCreationFlags deviceFlags = .None;
|
||||||
|
#if DEBUG
|
||||||
|
deviceFlags |= .Debug;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
FeatureLevel[] levels = scope .(.Level_11_0);
|
||||||
|
|
||||||
|
var deviceResult = D3D11.CreateDevice(null, .Hardware, 0, deviceFlags, levels, &nativeDevice, let deviceLevel, &nativeContext);
|
||||||
|
Debug.Assert(deviceResult.Succeeded, scope $"Failed to create D3D11 Device. Message(0x{(int32)deviceResult}): {deviceResult}");
|
||||||
|
|
||||||
|
#if DEBUG
|
||||||
|
if(nativeDevice.QueryInterface<ID3D11Debug>(out _debugDevice).Succeeded)
|
||||||
|
{
|
||||||
|
ID3D11InfoQueue* infoQueue;
|
||||||
|
if(nativeDevice.QueryInterface<ID3D11InfoQueue>(out infoQueue).Succeeded)
|
||||||
|
{
|
||||||
|
infoQueue.SetBreakOnSeverity(.Corruption, true);
|
||||||
|
infoQueue.SetBreakOnSeverity(.Error, true);
|
||||||
|
|
||||||
|
infoQueue.Release();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
Dx11Cheater.Device = nativeDevice;
|
||||||
|
Dx11Cheater.ImmediateContext = nativeContext;
|
||||||
|
|
||||||
|
Log.EngineLogger.Trace("D3D11 Device and Context created (Feature level: {})", deviceLevel);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private ID3D11RenderTargetView*[MaxRTVCount] _renderTargets;
|
||||||
|
|
||||||
|
public override void SetRenderTarget(RenderTarget renderTarget, int slot = 0)
|
||||||
|
{
|
||||||
|
if(renderTarget == null)
|
||||||
|
{
|
||||||
|
_renderTargets[slot] = _swapChain.nativeBackBufferTarget;
|
||||||
|
//_immediateContext.OutputMerger.SetRenderTargets(1, &_swapChain._backBufferTarget, null);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Runtime.NotImplemented();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void BindRenderTargets()
|
||||||
|
{
|
||||||
|
nativeContext.OutputMerger.SetRenderTargets(MaxRTVCount, &_renderTargets, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void ClearRenderTarget(RenderTarget renderTarget, ColorRGBA color)
|
||||||
|
{
|
||||||
|
if(renderTarget == null)
|
||||||
|
{
|
||||||
|
nativeContext.ClearRenderTargetView(_swapChain.nativeBackBufferTarget, color);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Runtime.NotImplemented();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void SetVertexBuffer(uint32 slot, Buffer buffer, uint32 stride, uint32 offset = 0)
|
||||||
|
{
|
||||||
|
// make stride and offset mutable so that we can take their pointers.
|
||||||
|
var stride, offset;
|
||||||
|
nativeContext.InputAssembler.SetVertexBuffers(slot, 1, &buffer.nativeBuffer, &stride, &offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Draw(uint32 vertexCount, uint32 startVertexIndex = 0)
|
||||||
|
{
|
||||||
|
nativeContext.Draw(vertexCount, startVertexIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void DrawIndexed(uint32 indexCount, uint32 startIndexLocation = 0, int32 vertexOffset = 0)
|
||||||
|
{
|
||||||
|
nativeContext.DrawIndexed(indexCount, startIndexLocation, vertexOffset);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void SetIndexBuffer(Buffer buffer, IndexFormat indexFormat = .Index16Bit, uint32 byteOffset = 0)
|
||||||
|
{
|
||||||
|
nativeContext.InputAssembler.SetIndexBuffer(buffer.nativeBuffer, indexFormat == .Index32Bit ? .R32_UInt : .R16_UInt, byteOffset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,155 @@
|
|||||||
|
using DirectX.D3D11;
|
||||||
|
using DirectX.DXGI.DXGI1_2;
|
||||||
|
using GlitchyEngine.Platform.DX11;
|
||||||
|
using System.Diagnostics;
|
||||||
|
|
||||||
|
using internal GlitchyEngine.Renderer;
|
||||||
|
|
||||||
|
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;
|
||||||
|
private DirectX.D3D11.Viewport _backBufferViewport;
|
||||||
|
|
||||||
|
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(Dx11Context context)
|
||||||
|
public this(GraphicsContext context)
|
||||||
|
{
|
||||||
|
_context = context;
|
||||||
|
|
||||||
|
SetResolutionFromWindow();
|
||||||
|
}
|
||||||
|
|
||||||
|
public ~this()
|
||||||
|
{
|
||||||
|
nativeDxgiDevice?.Release();
|
||||||
|
nativeSwapChain?.Release();
|
||||||
|
nativeBackBufferTarget?.Release();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetResolutionFromWindow()
|
||||||
|
{
|
||||||
|
DirectX.Windows.Winuser.GetClientRect(_context.nativeWindowHandle, let rect);
|
||||||
|
|
||||||
|
Width = (.)(rect.Right - rect.Left);
|
||||||
|
Height = (.)(rect.Bottom - rect.Top);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Init()
|
||||||
|
{
|
||||||
|
ApplyChanges();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void ApplyChanges()
|
||||||
|
{
|
||||||
|
if(!_changed)
|
||||||
|
return;
|
||||||
|
|
||||||
|
UpdateSwapchain();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes the swapchain.
|
||||||
|
*/
|
||||||
|
public void UpdateSwapchain()
|
||||||
|
{
|
||||||
|
Log.EngineLogger.Trace("Updating swap chain ({}, {})", _width, _height);
|
||||||
|
|
||||||
|
uint32 backBufferCount = 2;
|
||||||
|
Format backBufferFormat = .R8G8B8A8_UNorm;
|
||||||
|
Format backBufferViewFormat = .R8G8B8A8_UNorm; // _SRGB
|
||||||
|
|
||||||
|
if(nativeSwapChain != null)
|
||||||
|
{
|
||||||
|
nativeBackBufferTarget.Release();
|
||||||
|
|
||||||
|
var resizeResult = nativeSwapChain.ResizeBuffers(backBufferCount, _width, _height, backBufferFormat, .None);
|
||||||
|
Debug.Assert(resizeResult.Succeeded, scope $"Failed to resize swap chain. Message({(int32)resizeResult}):{resizeResult}");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_context.nativeDevice.QueryInterface(out nativeDxgiDevice);
|
||||||
|
|
||||||
|
nativeDxgiDevice.GetAdapter(let adapter);
|
||||||
|
adapter.GetParent<DirectX.DXGI.IDXGIFactory2>(let factory);
|
||||||
|
adapter.Release();
|
||||||
|
|
||||||
|
SwapChainDescription1 swDesc = .();
|
||||||
|
swDesc.Width = _width;
|
||||||
|
swDesc.Height = _height;
|
||||||
|
swDesc.Format = backBufferFormat;
|
||||||
|
swDesc.SampleDescription = .(1, 0);
|
||||||
|
swDesc.BufferUsage = .RenderTargetOutput;
|
||||||
|
swDesc.BufferCount = backBufferCount;
|
||||||
|
swDesc.SwapEffect = .FlipDiscard;
|
||||||
|
|
||||||
|
SwapChainFullscreenDescription fsSwapChainDesc = .();
|
||||||
|
fsSwapChainDesc.Windowed = true;
|
||||||
|
|
||||||
|
var createResult = factory.CreateSwapChainForHwnd((.)_context.nativeDevice, _context.nativeWindowHandle, ref swDesc, &fsSwapChainDesc, null, &nativeSwapChain);
|
||||||
|
Debug.Assert(createResult.Succeeded, scope $"Failed to create swap chain. Message({(int32)createResult}):{createResult}");
|
||||||
|
|
||||||
|
factory.Release();
|
||||||
|
|
||||||
|
Dx11Cheater.SwapChain = nativeSwapChain;
|
||||||
|
}
|
||||||
|
|
||||||
|
nativeSwapChain.GetBuffer<ID3D11Texture2D>(0, let backBuffer);
|
||||||
|
|
||||||
|
RenderTargetViewDescription rtvDesc = .(backBuffer, .Texture2D, backBufferViewFormat);
|
||||||
|
_context.nativeDevice.CreateRenderTargetView(backBuffer, &rtvDesc, &nativeBackBufferTarget);
|
||||||
|
|
||||||
|
Dx11Cheater.BackbufferTarget = nativeBackBufferTarget;
|
||||||
|
|
||||||
|
_backBufferViewport = DirectX.D3D11.Viewport(0, 0, _width, _height, 0.0f, 1.0f);
|
||||||
|
|
||||||
|
Dx11Cheater.BackbufferViewport = _backBufferViewport;
|
||||||
|
|
||||||
|
backBuffer.Release();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Present()
|
||||||
|
{
|
||||||
|
nativeSwapChain.Present(Application.Get().Window.IsVSync ? 1 : 0, .None);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -9,6 +9,8 @@ using GlitchyEngine.Events;
|
|||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using GlitchyEngine.Platform.DX11;
|
using GlitchyEngine.Platform.DX11;
|
||||||
using GlitchyEngine.Math;
|
using GlitchyEngine.Math;
|
||||||
|
//using GlitchyEngine.Platform.DX11.Renderer;
|
||||||
|
using GlitchyEngine.Renderer;
|
||||||
using static System.Windows;
|
using static System.Windows;
|
||||||
|
|
||||||
namespace GlitchyEngine
|
namespace GlitchyEngine
|
||||||
@@ -31,6 +33,10 @@ namespace GlitchyEngine
|
|||||||
|
|
||||||
private bool _isVSync = true;
|
private bool _isVSync = true;
|
||||||
|
|
||||||
|
private GraphicsContext _graphicsContext ~ delete _;
|
||||||
|
|
||||||
|
public override GraphicsContext Context => _graphicsContext;
|
||||||
|
|
||||||
public override int32 MinWidth
|
public override int32 MinWidth
|
||||||
{
|
{
|
||||||
get => _minMaxInfo.MinimumTrackingSize.x;
|
get => _minMaxInfo.MinimumTrackingSize.x;
|
||||||
@@ -192,15 +198,18 @@ namespace GlitchyEngine
|
|||||||
_windowHandle = CreateWindowExW(.None, _windowClass.ClassName, desc.Title.ToScopedNativeWChar!(), .WS_OVERLAPPEDWINDOW | .WS_VISIBLE,
|
_windowHandle = CreateWindowExW(.None, _windowClass.ClassName, desc.Title.ToScopedNativeWChar!(), .WS_OVERLAPPEDWINDOW | .WS_VISIBLE,
|
||||||
CW_USEDEFAULT, CW_USEDEFAULT, desc.Width, desc.Height, 0, 0, (.)_instanceHandle, null);
|
CW_USEDEFAULT, CW_USEDEFAULT, desc.Width, desc.Height, 0, 0, (.)_instanceHandle, null);
|
||||||
|
|
||||||
void* myPtr = Internal.UnsafeCastToPtr(this);
|
//_graphicsContext = new Dx11Context(_windowHandle);
|
||||||
|
_graphicsContext = new GraphicsContext(_windowHandle);
|
||||||
|
_graphicsContext.Init();
|
||||||
|
|
||||||
|
void* myPtr = Internal.UnsafeCastToPtr(this);
|
||||||
SetWindowLongPtrW(_windowHandle, GWL_USERDATA, (int)myPtr);
|
SetWindowLongPtrW(_windowHandle, GWL_USERDATA, (int)myPtr);
|
||||||
|
|
||||||
LoadWindowRectangle();
|
LoadWindowRectangle();
|
||||||
|
|
||||||
Log.EngineLogger.Trace("Created window \"{}\" ({}, {})", Title, Width, Height);
|
Log.EngineLogger.Trace("Created window \"{}\" ({}, {})", Title, Width, Height);
|
||||||
|
|
||||||
DirectX.Init(_windowHandle, (.)Width, (.)Height);
|
//DirectX.Init(_windowHandle, (.)Width, (.)Height);
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool _isResizingOrMoving;
|
private bool _isResizingOrMoving;
|
||||||
@@ -249,7 +258,11 @@ namespace GlitchyEngine
|
|||||||
{
|
{
|
||||||
SplitHighAndLowOrder!(lParam, out window._clientRect.Width, out window._clientRect.Height);
|
SplitHighAndLowOrder!(lParam, out window._clientRect.Width, out window._clientRect.Height);
|
||||||
|
|
||||||
DirectX.UpdateSwapchain((.)window._clientRect.Width, (.)window._clientRect.Height);
|
window._graphicsContext.SwapChain.Width = (.)window._clientRect.Width;
|
||||||
|
window._graphicsContext.SwapChain.Height = (.)window._clientRect.Height;
|
||||||
|
|
||||||
|
window._graphicsContext.SwapChain.ApplyChanges();
|
||||||
|
|
||||||
WindowResizeEvent event = scope WindowResizeEvent(window._clientRect.Width, window._clientRect.Height, window._isResizingOrMoving);
|
WindowResizeEvent event = scope WindowResizeEvent(window._clientRect.Width, window._clientRect.Height, window._isResizingOrMoving);
|
||||||
window._eventCallback(event);
|
window._eventCallback(event);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,279 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace GlitchyEngine.Renderer
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Identifies expected resource use during rendering.
|
||||||
|
* The usage directly reflects whether a resource is accessible by the CPU and/or the graphics processing unit (GPU).
|
||||||
|
*/
|
||||||
|
public enum Usage
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* A resource that requires read and write access by the GPU.
|
||||||
|
* This is likely to be the most common usage choice.
|
||||||
|
*/
|
||||||
|
Default = 0,
|
||||||
|
/**
|
||||||
|
* A resource that can only be read by the GPU. It cannot be written by the GPU, and cannot be accessed at all by the CPU.
|
||||||
|
*/
|
||||||
|
Immutable = 1,
|
||||||
|
/**
|
||||||
|
* A resource that is accessible by both the GPU (read only) and the CPU (write only).
|
||||||
|
* A dynamic resource is a good choice for a resource that will be updated by the CPU at least once per frame.
|
||||||
|
* To update a dynamic resource, use a Map method.
|
||||||
|
*/
|
||||||
|
Dynamic = 2,
|
||||||
|
/**
|
||||||
|
* A resource that supports data transfer (copy) from the GPU to the CPU.
|
||||||
|
*/
|
||||||
|
Staging = 3
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Defines how the CPU can access a resource.
|
||||||
|
*/
|
||||||
|
public enum CPUAccessFlags
|
||||||
|
{
|
||||||
|
/// The CPU has no access to the resource.
|
||||||
|
None = 0,
|
||||||
|
/// The CPU has read access to the resource.
|
||||||
|
Read = 1,
|
||||||
|
/// The CPU has write access to the resource.
|
||||||
|
Write = 2
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Defines how to bind a buffer to the pipeline.
|
||||||
|
*/
|
||||||
|
public enum BufferBindFlags
|
||||||
|
{
|
||||||
|
/// No binding flags specified
|
||||||
|
None = 0,
|
||||||
|
/// The Buffer contains vertex data
|
||||||
|
Vertex = 1,
|
||||||
|
/// The Buffer contains index data
|
||||||
|
Index = 2,
|
||||||
|
// The Buffer contains constant data
|
||||||
|
Constant = 4,
|
||||||
|
// ShaderResource?
|
||||||
|
// UnorderedAccess?
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum BufferMiscFlags
|
||||||
|
{
|
||||||
|
None = 0,
|
||||||
|
//AllowRawView = 1,
|
||||||
|
//Structured = 2,
|
||||||
|
}
|
||||||
|
|
||||||
|
typealias Format = DirectX.DXGI.Format;
|
||||||
|
|
||||||
|
public struct BufferDescription
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* The size of the buffer in bytes.
|
||||||
|
*/
|
||||||
|
public uint32 Size;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Identify how the buffer is expected to be read from and written to. Frequency of update is a key factor.
|
||||||
|
* The most common value is typically Default.
|
||||||
|
*/
|
||||||
|
public Usage Usage;
|
||||||
|
|
||||||
|
public CPUAccessFlags CPUAccess;
|
||||||
|
|
||||||
|
public BufferBindFlags BindFlags;
|
||||||
|
|
||||||
|
public BufferMiscFlags MiscFlags;
|
||||||
|
|
||||||
|
// Strucutred Byte stride.
|
||||||
|
|
||||||
|
public this() => this = default;
|
||||||
|
|
||||||
|
public this(uint32 size, BufferBindFlags bindFlags, Usage usage = .Default, CPUAccessFlags cpuAccess = .None, BufferMiscFlags miscFlags = .None)
|
||||||
|
{
|
||||||
|
Size = size;
|
||||||
|
BindFlags = bindFlags;
|
||||||
|
Usage = usage;
|
||||||
|
CPUAccess = cpuAccess;
|
||||||
|
MiscFlags = miscFlags;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum MapType
|
||||||
|
{
|
||||||
|
case None;
|
||||||
|
case Read;
|
||||||
|
case Write;
|
||||||
|
case ReadWrite;
|
||||||
|
case WriteDiscard;
|
||||||
|
case WriteNoOverwrite;
|
||||||
|
|
||||||
|
public bool CanWrite => this == Write ||
|
||||||
|
this == ReadWrite ||
|
||||||
|
this == WriteDiscard ||
|
||||||
|
this == WriteNoOverwrite;
|
||||||
|
|
||||||
|
public bool CanRead => this == Read ||
|
||||||
|
this == ReadWrite;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Represents a buffer containing binary data on the GPU.
|
||||||
|
public class Buffer
|
||||||
|
{
|
||||||
|
internal GraphicsContext _context;
|
||||||
|
|
||||||
|
protected BufferDescription _description;
|
||||||
|
|
||||||
|
public GraphicsContext Context => _context;
|
||||||
|
|
||||||
|
public BufferDescription Description => _description;
|
||||||
|
|
||||||
|
protected this(GraphicsContext context)
|
||||||
|
{
|
||||||
|
_context = context;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new instance of a Buffer.
|
||||||
|
* @param description The buffer description.
|
||||||
|
*/
|
||||||
|
public this(GraphicsContext context, BufferDescription description) : this(context)
|
||||||
|
{
|
||||||
|
_description = description;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param data The span containing the data that will be copied into the buffer.
|
||||||
|
* @param destinationByteOffset The offset in bytes form the start of the destination buffer.
|
||||||
|
* @param mapType Only relevant for dynamic buffers...
|
||||||
|
*/
|
||||||
|
public Result<void> SetData<T>(Span<T> data, uint32 destinationByteOffset = 0, MapType mapType = .Write) where T : struct
|
||||||
|
{
|
||||||
|
return PlatformSetData(data.Ptr, (uint32)(data.Length * sizeof(T)), destinationByteOffset, mapType);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param data The span containing the data that will be copied into the buffer.
|
||||||
|
* @param destinationByteOffset The offset in bytes form the start of the destination buffer.
|
||||||
|
* @param mapType Only relevant for dynamic buffers...
|
||||||
|
*/
|
||||||
|
public Result<void> SetData<T>(T* data, uint32 elementCount, uint32 destinationByteOffset = 0, MapType mapType = .Write) where T : struct
|
||||||
|
{
|
||||||
|
return PlatformSetData(data, elementCount * (uint32)sizeof(T), destinationByteOffset, mapType);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Result<void> SetData<T, CLength>(T[CLength] data, uint32 destinationByteOffset = 0, MapType mapType = .Write) where T : struct where CLength : const int
|
||||||
|
{
|
||||||
|
var data;
|
||||||
|
return PlatformSetData(&data, (uint32)sizeof(T[CLength]), destinationByteOffset, mapType);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* // Todo: as soon as Beef supports generic method override, change to generic?
|
||||||
|
* Platform specific implementation of SetData.
|
||||||
|
* @param data The pointer to the source data that will be copied to the buffer.
|
||||||
|
* @param data The number of bytes that will be copied.
|
||||||
|
* @param dstByteOffset The offset from the start of the target buffer.
|
||||||
|
*/
|
||||||
|
protected extern Result<void> 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;}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,80 @@
|
|||||||
|
using GlitchyEngine.Math;
|
||||||
|
|
||||||
|
namespace GlitchyEngine.Renderer
|
||||||
|
{
|
||||||
|
public class RenderTarget;
|
||||||
|
|
||||||
|
//public abstract class GraphicsContext
|
||||||
|
public class GraphicsContext
|
||||||
|
{
|
||||||
|
//public abstract SwapChain SwapChain {get;}
|
||||||
|
public extern SwapChain SwapChain {get;}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The maximum number of simultaneous rendertargets supported.
|
||||||
|
*/
|
||||||
|
//public static extern uint32 MaxRenderTargetCount();
|
||||||
|
|
||||||
|
//public abstract void Init();
|
||||||
|
public extern void Init();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets a rendertarget.
|
||||||
|
* @param renderTarget The render target.
|
||||||
|
* @param slot The slot to which the rendertarget will be bound.
|
||||||
|
* @remarks When @RenderTarget is null the backbuffer will be bound.
|
||||||
|
* @BindRenderTargets has to be called in order to bind the rendertargets.
|
||||||
|
*/
|
||||||
|
//public abstract void SetRenderTarget(RenderTarget renderTarget, int slot = 0);
|
||||||
|
public extern void SetRenderTarget(RenderTarget renderTarget, int slot = 0);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Binds all.
|
||||||
|
* @param renderTarget The render target.
|
||||||
|
* @param slot The slot to which the rendertarget will be bound.
|
||||||
|
* @remarks When @RenderTarget is null the backbuffer will be bound.
|
||||||
|
*/
|
||||||
|
//public abstract void BindRenderTargets(); // Todo: maybe do this automatically when a drawcall is issued
|
||||||
|
public extern void BindRenderTargets(); // Todo: maybe do this automatically when a drawcall is issued
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets all elements in the given render target to one value.
|
||||||
|
* @param renderTarget The render target.
|
||||||
|
* @param color The color to clear the render target with.
|
||||||
|
* @remarks When @renderTarget is null the backbuffer will be cleared.
|
||||||
|
*/
|
||||||
|
//public abstract void ClearRenderTarget(RenderTarget renderTarget, ColorRGBA color);
|
||||||
|
public extern void ClearRenderTarget(RenderTarget renderTarget, ColorRGBA color);
|
||||||
|
|
||||||
|
//public abstract void SetViewport(Viewport viewport);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Binds a VertexBuffer to the pipeline.
|
||||||
|
* @param buffer The vertex buffer to bind.
|
||||||
|
* Note: the buffer has to have BindFlags.Vertex!
|
||||||
|
* @param slot The slot the vertex buffer will be bound to.
|
||||||
|
* @param offset The offset in bytes from the start of the buffer.
|
||||||
|
* @param stride The stride of the
|
||||||
|
*/
|
||||||
|
public extern void SetVertexBuffer(uint32 slot, Buffer buffer, uint32 stride, uint32 offset = 0);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Binds a VertexBuffer to the pipeline.
|
||||||
|
*/
|
||||||
|
public void SetVertexBuffer(uint32 slot, VertexBufferBinding binding)
|
||||||
|
{
|
||||||
|
SetVertexBuffer(slot, binding.Buffer, binding.Stride, binding.Offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
public extern void Draw(uint32 vertexCount, uint32 startVertexIndex = 0);
|
||||||
|
|
||||||
|
public extern void DrawIndexed(uint32 indexCount, uint32 startIndexLocation = 0, int32 vertexOffset = 0);
|
||||||
|
|
||||||
|
public void SetIndexBuffer(IndexBuffer indexBuffer, uint32 byteOffset = 0)
|
||||||
|
{
|
||||||
|
SetIndexBuffer(indexBuffer, indexBuffer.Format, byteOffset);
|
||||||
|
}
|
||||||
|
|
||||||
|
public extern void SetIndexBuffer(Buffer buffer, IndexFormat indexFormat = .Index16Bit, uint32 byteOffset = 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
namespace GlitchyEngine.Renderer
|
||||||
|
{
|
||||||
|
public enum IndexFormat
|
||||||
|
{
|
||||||
|
Index16Bit,
|
||||||
|
Index32Bit,
|
||||||
|
}
|
||||||
|
|
||||||
|
public class IndexBuffer : Buffer
|
||||||
|
{
|
||||||
|
private uint32 _indexCount;
|
||||||
|
private IndexFormat _format;
|
||||||
|
|
||||||
|
public uint32 IndexCount => _indexCount;
|
||||||
|
public IndexFormat Format => _format;
|
||||||
|
|
||||||
|
public this(GraphicsContext context, uint32 indexCount, Usage usage = .Default, CPUAccessFlags cpuAccess = .None, IndexFormat indexFormat = .Index16Bit) : base(context)
|
||||||
|
{
|
||||||
|
_indexCount = indexCount;
|
||||||
|
_format = indexFormat;
|
||||||
|
|
||||||
|
_description = .()
|
||||||
|
{
|
||||||
|
Size = (_format == .Index32Bit ? 4 : 2) * _indexCount,
|
||||||
|
Usage = usage,
|
||||||
|
CPUAccess = cpuAccess,
|
||||||
|
BindFlags = .Index,
|
||||||
|
MiscFlags = .None
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
namespace GlitchyEngine.Renderer
|
||||||
|
{
|
||||||
|
public class SwapChain
|
||||||
|
{
|
||||||
|
public extern GraphicsContext Context {get;}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets or Sets the backbuffers width.
|
||||||
|
* @remarks @ApplyChanges() needs to be called in order to apply the ganges.
|
||||||
|
*/
|
||||||
|
public extern uint32 Width {get; set;}
|
||||||
|
/**
|
||||||
|
* Gets or Sets the backbuffers height.
|
||||||
|
* @remarks @ApplyChanges() needs to be called in order to apply the ganges.
|
||||||
|
*/
|
||||||
|
public extern uint32 Height {get; set;}
|
||||||
|
|
||||||
|
public extern void Init();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Applies all changes to the swapchain.
|
||||||
|
*/
|
||||||
|
public extern void ApplyChanges();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Swaps the front- and backbuffer.
|
||||||
|
*/
|
||||||
|
public extern void Present();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
using System;
|
||||||
|
namespace GlitchyEngine.Renderer
|
||||||
|
{
|
||||||
|
public struct VertexBufferBinding
|
||||||
|
{
|
||||||
|
public Buffer Buffer;
|
||||||
|
public uint32 Stride;
|
||||||
|
public uint32 Offset;
|
||||||
|
|
||||||
|
public this(Buffer buffer, uint32 stride, uint32 offset = 0)
|
||||||
|
{
|
||||||
|
Buffer = buffer;
|
||||||
|
Stride = stride;
|
||||||
|
Offset = offset;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class VertexBuffer<T> : Buffer where T: struct, IVertexData
|
||||||
|
{
|
||||||
|
private VertexBufferBinding _defaultBinding;
|
||||||
|
|
||||||
|
public VertexBufferBinding Binding => _defaultBinding;
|
||||||
|
|
||||||
|
public this(GraphicsContext context, uint32 vertexCount, Usage usage = .Default, CPUAccessFlags cpuAccess = .None) : base(context)
|
||||||
|
{
|
||||||
|
_description = .(){
|
||||||
|
Size = ((uint32)sizeof(T) * vertexCount),
|
||||||
|
Usage = usage,
|
||||||
|
CPUAccess = cpuAccess,
|
||||||
|
BindFlags = .Vertex,
|
||||||
|
MiscFlags = .None
|
||||||
|
};
|
||||||
|
|
||||||
|
_defaultBinding = .(this, (.)sizeof(T), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Result<void> SetData(Span<T> data, uint32 destinationVertexOffset = 0, MapType mapType = .Write)
|
||||||
|
{
|
||||||
|
return SetData<T>(data, destinationVertexOffset * (uint32)sizeof(T));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Inline]
|
||||||
|
public static implicit operator VertexBufferBinding(Self buffer) => buffer._defaultBinding;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
namespace GlitchyEngine.Renderer
|
||||||
|
{
|
||||||
|
public struct Viewport
|
||||||
|
{
|
||||||
|
/// X position of the left hand side of the viewport.
|
||||||
|
public float Left;
|
||||||
|
/// Y position of the top of the viewport. Ranges between BoundsMin and BoundsMax.
|
||||||
|
public float Top;
|
||||||
|
/// Width of the viewport.
|
||||||
|
public float Width;
|
||||||
|
/// Height of the viewport.
|
||||||
|
public float Height;
|
||||||
|
/// Minimum depth of the viewport. Ranges between 0 and 1.
|
||||||
|
public float MinDepth;
|
||||||
|
/// Maximum depth of the viewport. Ranges between 0 and 1.
|
||||||
|
public float MaxDepth;
|
||||||
|
|
||||||
|
public this() => this = default;
|
||||||
|
|
||||||
|
public this(float left, float top, float width, float height, float minDepth = 0.0f, float maxDepth = 1.0f)
|
||||||
|
{
|
||||||
|
Left = left;
|
||||||
|
Top = top;
|
||||||
|
Width = width;
|
||||||
|
Height = height;
|
||||||
|
MinDepth = minDepth;
|
||||||
|
MaxDepth = maxDepth;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using GlitchyEngine.Events;
|
using GlitchyEngine.Events;
|
||||||
using GlitchyEngine.Math;
|
using GlitchyEngine.Math;
|
||||||
|
using GlitchyEngine.Renderer;
|
||||||
|
|
||||||
namespace GlitchyEngine
|
namespace GlitchyEngine
|
||||||
{
|
{
|
||||||
@@ -87,6 +88,11 @@ namespace GlitchyEngine
|
|||||||
*/
|
*/
|
||||||
public extern bool IsVSync {get; set;}
|
public extern bool IsVSync {get; set;}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the windows graphics context.
|
||||||
|
*/
|
||||||
|
public extern GraphicsContext Context {get;}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets a pointer to the platform specific window representation.
|
* Gets a pointer to the platform specific window representation.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -0,0 +1,25 @@
|
|||||||
|
struct VS_IN
|
||||||
|
{
|
||||||
|
float3 Position : POSITION;
|
||||||
|
float4 Color : COLOR;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct PS_IN
|
||||||
|
{
|
||||||
|
float4 Position : SV_POSITION;
|
||||||
|
float4 Color : COLOR;
|
||||||
|
};
|
||||||
|
|
||||||
|
PS_IN VS(VS_IN input)
|
||||||
|
{
|
||||||
|
PS_IN output;
|
||||||
|
output.Position = float4(input.Position, 1);
|
||||||
|
output.Color = input.Color;
|
||||||
|
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
float4 PS(PS_IN input) : SV_TARGET
|
||||||
|
{
|
||||||
|
return input.Color;
|
||||||
|
}
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 116 KiB |
@@ -4,6 +4,7 @@ using GlitchyEngine.Events;
|
|||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using GlitchLog;
|
using GlitchLog;
|
||||||
using GlitchyEngine.ImGui;
|
using GlitchyEngine.ImGui;
|
||||||
|
using ImGui;
|
||||||
|
|
||||||
namespace Sandbox
|
namespace Sandbox
|
||||||
{
|
{
|
||||||
@@ -29,9 +30,9 @@ namespace Sandbox
|
|||||||
|
|
||||||
private bool OnImGuiRender(ImGuiRenderEvent e)
|
private bool OnImGuiRender(ImGuiRenderEvent e)
|
||||||
{
|
{
|
||||||
ImGui.ImGui.Begin("Test");
|
ImGui.Begin("Test");
|
||||||
|
|
||||||
ImGui.ImGui.End();
|
ImGui.End();
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user