chore(renderer): remove legacy code-base

This commit is contained in:
light7734 2025-09-25 22:13:50 +03:30
parent 607e6864b4
commit d411c9ab2c
Signed by: light7734
GPG key ID: 8C30176798F1A6BA
76 changed files with 0 additions and 4381 deletions

View file

@ -1,14 +0,0 @@
#include <ranges>
#include <renderer/system.hpp>
#include <test/test.hpp>
using namespace lt;
#include <renderer/backend.hpp>
using lt::test::Case;
using lt::test::Suite;
Suite raii = [] {
Case { "happy path won't throw" } = [] {
};
};

View file

@ -1,35 +0,0 @@
#include <renderer/blender.hpp>
#include <renderer/gl/blender.hpp>
#ifdef LIGHT_PLATFORM_WINDOWS
#include <renderer/dx/blender.hpp>
#include <renderer/dx/sharedcontext.hpp>
#endif
#include <renderer/graphics_context.hpp>
namespace lt {
auto Blender::create(const Ref<SharedContext> & /*sharedContext*/) -> Scope<Blender>
{
switch (GraphicsContext::get_graphics_api())
{
case GraphicsAPI::OpenGL: return create_scope<glBlender>();
case GraphicsAPI::DirectX:
lt_win(
return create_scope<dxBlender>(
std::static_pointer_cast<dxSharedContext>(sharedContext)
);
)
default
: ensure(
false,
"Invalid/unsupported 'GraphicsAPI' {}",
static_cast<uint32_t>(GraphicsContext::get_graphics_api())
);
}
}
} // namespace lt

View file

@ -1,104 +0,0 @@
#include <lt_debug/assertions.hpp>
#include <renderer/buffers.hpp>
#include <renderer/gl/buffers.hpp>
#include <renderer/shared_context.hpp>
#ifdef LIGHT_PLATFORM_WINDOWS
#include <renderer/dx/buffers.hpp>
#include <renderer/dx/shared_context.hpp>
#endif
#include <renderer/graphics_context.hpp>
namespace lt {
auto ConstantBuffer::create(
ConstantBufferIndex index,
unsigned int size,
const Ref<SharedContext> & /*sharedContext*/
) -> Scope<ConstantBuffer>
{
switch (GraphicsContext::get_graphics_api())
{
case GraphicsAPI::OpenGL: return create_scope<glConstantBuffer>(index, size);
case GraphicsAPI::DirectX:
lt_win(
return create_scope<dxConstantBuffer>(
index,
size,
std::static_pointer_cast<dxSharedContext>(sharedContext)
);
)
default
: ensure(
false,
"Invalid/unsupported 'GraphicsAPI' {}",
static_cast<uint32_t>(GraphicsContext::get_graphics_api())
);
return nullptr;
}
}
auto VertexBuffer::create(
float *vertices,
unsigned int stride,
unsigned int count,
const Ref<SharedContext> & /*sharedContext*/
) -> Ref<VertexBuffer>
{
switch (GraphicsContext::get_graphics_api())
{
case GraphicsAPI::OpenGL: return create_ref<glVertexBuffer>(vertices, stride, count);
case GraphicsAPI::DirectX:
lt_win(
return create_ref<dxVertexBuffer>(
vertices,
stride,
count,
std::static_pointer_cast<dxSharedContext>(sharedContext)
);
)
default
: ensure(
false,
"Invalid/unsupported 'GraphicsAPI' {}",
static_cast<uint32_t>(GraphicsContext::get_graphics_api())
);
return nullptr;
}
}
auto IndexBuffer::create(
unsigned int *indices,
unsigned int count,
const Ref<SharedContext> & /*sharedContext*/
) -> Ref<IndexBuffer>
{
switch (GraphicsContext::get_graphics_api())
{
case GraphicsAPI::OpenGL: return create_ref<glIndexBuffer>(indices, count);
case GraphicsAPI::DirectX:
lt_win(
return create_ref<dxIndexBuffer>(
indices,
count,
std::dynamic_pointer_cast<dxSharedContext>(sharedContext)
);
)
default
: ensure(
false,
"Invalid/unsupported 'GraphicsAPI' {}",
static_cast<uint32_t>(GraphicsContext::get_graphics_api())
);
return nullptr;
}
}
} // namespace lt

View file

@ -1,81 +0,0 @@
#include <renderer/dx/blender.hpp>
#include <renderer/dx/shared_context.hpp>
namespace lt {
dxBlender::dxBlender(Ref<dxSharedContext> sharedContext)
: m_context(sharedContext), m_factor_map { // constants
{ BlendFactor::ZERO, D3D11_BLEND_ZERO },
{ BlendFactor::ONE, D3D11_BLEND_ONE },
// source
{ BlendFactor::SRC_COLOR, D3D11_BLEND_SRC_COLOR },
{ BlendFactor::INVERSE_SRC_COLOR, D3D11_BLEND_INV_SRC_COLOR },
{ BlendFactor::SRC_ALPHA, D3D11_BLEND_SRC_ALPHA },
{ BlendFactor::INVERSE_SRC_ALPHA, D3D11_BLEND_INV_SRC_ALPHA },
// destination
{ BlendFactor::DST_COLOR, D3D11_BLEND_DEST_COLOR },
{ BlendFactor::INVERSE_DST_COLOR, D3D11_BLEND_INV_DEST_COLOR },
{ BlendFactor::DST_ALPHA, D3D11_BLEND_DEST_ALPHA },
{ BlendFactor::INVERSE_DST_ALPHA, D3D11_BLEND_INV_DEST_ALPHA },
// source1
{ BlendFactor::SRC1_COLOR, D3D11_BLEND_SRC1_COLOR },
{ BlendFactor::INVERSE_SRC1_COLOR, D3D11_BLEND_INV_SRC1_COLOR },
{ BlendFactor::SRC1_ALPHA, D3D11_BLEND_SRC1_ALPHA },
{ BlendFactor::INVERSE_SRC1_ALPHA, D3D11_BLEND_INV_SRC1_ALPHA }
}
, m_blend_state(nullptr)
, m_desc {}
{
// factor map
// blender desc
m_desc = {};
m_desc.RenderTarget[0].BlendEnable = true;
m_desc.RenderTarget[0].SrcBlend = D3D11_BLEND_ZERO;
m_desc.RenderTarget[0].DestBlend = D3D11_BLEND_ZERO;
m_desc.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD;
m_desc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ZERO;
m_desc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ONE;
m_desc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD;
m_desc.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL;
// create blend state
auto hr = HRESULT {};
dxc(m_context->get_device()->CreateBlendState(&m_desc, &m_blend_state));
}
void dxBlender::enable(BlendFactor srcFactor, BlendFactor dstFactor)
{
// update desc
m_desc.RenderTarget[0].BlendEnable = true;
m_desc.RenderTarget[0].SrcBlend = m_factor_map.at(srcFactor);
m_desc.RenderTarget[0].DestBlend = m_factor_map.at(dstFactor);
// re-create blind state
auto hr = HRESULT {};
dxc(m_context->get_device()->CreateBlendState(&m_desc, &m_blend_state));
// bind blend state
m_context->get_device_context()->OMSetBlendState(m_blend_state.Get(), nullptr, 0x0000000f);
}
void dxBlender::disable()
{
// update desc
m_desc.RenderTarget[0].BlendEnable = false;
// re-create blind state
auto hr = HRESULT {};
dxc(m_context->get_device()->CreateBlendState(&m_desc, &m_blend_state));
// bind blend state
m_context->get_device_context()->OMSetBlendState(m_blend_state.Get(), nullptr, 0xffffffff);
}
} // namespace lt

View file

@ -1,30 +0,0 @@
#pragma once
#include <d3d11.h>
#include <renderer/blender.hpp>
#include <wrl.h>
namespace lt {
class dxSharedContext;
class dxBlender: public Blender
{
public:
dxBlender(Ref<dxSharedContext> sharedContext);
void enable(BlendFactor srcFactor, BlendFactor dstFactor) override;
void disable() override;
private:
Ref<dxSharedContext> m_context;
const std::unordered_map<BlendFactor, D3D11_BLEND> m_factor_map;
Microsoft::WRL::ComPtr<ID3D11BlendState> m_blend_state;
D3D11_BLEND_DESC m_desc;
};
} // namespace lt

View file

@ -1,188 +0,0 @@
#include <renderer/dx/buffers.hpp>
#include <renderer/dx/shared_context.hpp>
namespace lt {
//======================================== CONSTANT_BUFFER
//========================================//
dxConstantBuffer::dxConstantBuffer(
ConstantBufferIndex index,
unsigned int size,
Ref<dxSharedContext> sharedContext
)
: m_context(sharedContext)
, m_buffer(nullptr)
, m_map {}
, m_index(static_cast<int>(index))
{
auto bDesc = D3D11_BUFFER_DESC {};
bDesc.ByteWidth = size;
bDesc.Usage = D3D11_USAGE_DYNAMIC;
bDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
bDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
auto hr = HRESULT {};
dxc(m_context->get_device()->CreateBuffer(&bDesc, nullptr, &m_buffer));
m_context->get_device_context()->VSSetConstantBuffers(m_index, 1u, m_buffer.GetAddressOf());
}
void dxConstantBuffer::bind()
{
m_context->get_device_context()->VSSetConstantBuffers(m_index, 1u, m_buffer.GetAddressOf());
}
auto dxConstantBuffer::map() -> void *
{
m_context->get_device_context()->VSSetConstantBuffers(m_index, 1u, m_buffer.GetAddressOf());
m_context->get_device_context()
->map(m_buffer.Get(), NULL, D3D11_MAP_WRITE_DISCARD, NULL, &m_map);
return m_map.pData;
}
void dxConstantBuffer::un_map()
{
m_context->get_device_context()->Unmap(m_buffer.Get(), NULL);
}
dxVertexBuffer::dxVertexBuffer(
float *vertices,
unsigned int stride,
unsigned int count,
Ref<dxSharedContext> sharedContext
)
: m_context(sharedContext)
, m_buffer(nullptr)
, m_map {}
, m_stride(stride)
{
// buffer desc
auto bDesc = D3D11_BUFFER_DESC {};
bDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
bDesc.Usage = D3D11_USAGE_DYNAMIC;
bDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
bDesc.ByteWidth = count * stride;
bDesc.StructureByteStride = stride;
// create buffer
auto hr = HRESULT {};
dxc(m_context->get_device()->CreateBuffer(&bDesc, nullptr, &m_buffer));
}
dxVertexBuffer::~dxVertexBuffer()
{
un_bind();
}
auto dxVertexBuffer::map() -> void *
{
m_context->get_device_context()
->map(m_buffer.Get(), NULL, D3D11_MAP_WRITE_DISCARD, NULL, &m_map);
return m_map.pData;
}
void dxVertexBuffer::un_map()
{
m_context->get_device_context()->Unmap(m_buffer.Get(), NULL);
}
void dxVertexBuffer::bind()
{
static const auto offset = unsigned int { 0u };
m_context->get_device_context()
->IASetVertexBuffers(0u, 1u, m_buffer.GetAddressOf(), &m_stride, &offset);
}
void dxVertexBuffer::un_bind()
{
static const auto offset = unsigned int { 0u };
static auto *buffer = (ID3D11Buffer *)(nullptr);
m_context->get_device_context()->IASetVertexBuffers(0u, 1u, &buffer, &m_stride, &offset);
}
dxIndexBuffer::dxIndexBuffer(
unsigned int *indices,
unsigned int count,
Ref<dxSharedContext> sharedContext
)
: m_context(sharedContext)
, m_buffer(nullptr)
{
// generate indices if not provided
auto hasIndices = !!indices;
if (!hasIndices)
{
// check
if (count % 6 != 0)
{
log_wrn("'indices' can only be null if count is multiple of 6");
lt_log(
warn,
"Adding {} to 'count' -> {}",
(6 - (count % 6)),
count + (6 - (count % 6))
);
count = count + (6 - (count % 6));
}
// create indices
indices = new unsigned int[count];
auto offset = 0;
for (unsigned int i = 0; i < count; i += 6)
{
indices[i + 0] = offset + 0u;
indices[i + 1] = offset + 3u;
indices[i + 2] = offset + 2u;
indices[i + 3] = offset + 2u;
indices[i + 4] = offset + 1u;
indices[i + 5] = offset + 0u;
offset += 4u;
}
}
// buffer desc
auto bDesc = D3D11_BUFFER_DESC {};
bDesc.BindFlags = D3D11_BIND_INDEX_BUFFER;
bDesc.Usage = D3D11_USAGE_DEFAULT;
bDesc.ByteWidth = count * sizeof(unsigned int);
bDesc.StructureByteStride = sizeof(unsigned int);
// subresource data
auto sDesc = D3D11_SUBRESOURCE_DATA {};
sDesc.pSysMem = indices;
// create buffer
auto hr = HRESULT {};
dxc(m_context->get_device()->CreateBuffer(&bDesc, &sDesc, &m_buffer));
// delete indices
if (!hasIndices)
delete[] indices;
}
dxIndexBuffer::~dxIndexBuffer()
{
un_bind();
}
void dxIndexBuffer::bind()
{
m_context->get_device_context()->IASetIndexBuffer(m_buffer.Get(), DXGI_FORMAT_R32_UINT, 0u);
}
void dxIndexBuffer::un_bind()
{
static const auto offset = (unsigned int) { 0u };
static auto *buffer = (ID3D11Buffer *)(nullptr);
m_context->get_device_context()->IASetIndexBuffer(buffer, DXGI_FORMAT_R32_UINT, offset);
}
//======================================== INDEX_BUFFER ========================================//
} // namespace lt

View file

@ -1,83 +0,0 @@
#pragma once
#include <d3d11.h>
#include <renderer/buffers.hpp>
#include <wrl.h>
namespace lt {
class dxSharedContext;
class dxConstantBuffer: public ConstantBuffer
{
public:
dxConstantBuffer(
ConstantBufferIndex index,
unsigned int size,
Ref<dxSharedContext> sharedContext
);
void bind() override;
void *map() override;
void un_map() override;
private:
Ref<dxSharedContext> m_context;
Microsoft::WRL::ComPtr<ID3D11Buffer> m_buffer;
D3D11_MAPPED_SUBRESOURCE m_map;
unsigned int m_index;
};
class dxVertexBuffer: public VertexBuffer
{
public:
dxVertexBuffer(
float *vertices,
unsigned int stride,
unsigned int count,
Ref<dxSharedContext> sharedContext
);
~dxVertexBuffer();
void bind() override;
void un_bind() override;
auto map() -> void * override;
void un_map() override;
private:
Ref<dxSharedContext> m_context;
Microsoft::WRL::ComPtr<ID3D11Buffer> m_buffer;
D3D11_MAPPED_SUBRESOURCE m_map;
unsigned int m_stride;
};
class dxIndexBuffer: public IndexBuffer
{
public:
dxIndexBuffer(unsigned int *indices, unsigned int count, Ref<dxSharedContext> sharedContext);
~dxIndexBuffer();
void bind() override;
void un_bind() override;
private:
Ref<dxSharedContext> m_context;
Microsoft::WRL::ComPtr<ID3D11Buffer> m_buffer;
};
} // namespace lt

View file

@ -1,113 +0,0 @@
#include <renderer/dx/framebuffers.hpp>
#include <renderer/dx/shared_context.hpp>
namespace lt {
dxFramebuffer::dxFramebuffer(
const FramebufferSpecification &specification,
Ref<dxSharedContext> sharedContext
)
: m_context(sharedContext)
, m_specification(specification)
, m_render_target_view(nullptr)
, m_color_attachment(nullptr)
, m_depth_stencil_attachment(nullptr)
, m_shader_resource_view(nullptr)
, m_depth_stencil_view(nullptr)
{
auto hr = HRESULT {};
auto t2dDesc = D3D11_TEXTURE2D_DESC {};
t2dDesc.Width = specification.width;
t2dDesc.Height = specification.height;
t2dDesc.MipLevels = 1;
t2dDesc.ArraySize = 1;
t2dDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
t2dDesc.SampleDesc.Count = 1u;
t2dDesc.SampleDesc.Quality = 0u;
t2dDesc.Usage = D3D11_USAGE_DEFAULT;
t2dDesc.BindFlags = D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE;
t2dDesc.CPUAccessFlags = NULL;
t2dDesc.MiscFlags = NULL;
dxc(m_context->get_device()->CreateTexture2D(&t2dDesc, nullptr, &m_color_attachment));
auto srvDesc = D3D11_SHADER_RESOURCE_VIEW_DESC {};
srvDesc.Format = t2dDesc.Format;
srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
srvDesc.Texture2D.MipLevels = 1;
srvDesc.Texture2D.MostDetailedMip = 0;
dxc(m_context->get_device()->CreateShaderResourceView(
m_color_attachment.Get(),
&srvDesc,
&m_shader_resource_view
));
auto rtvDesc = D3D11_RENDER_TARGET_VIEW_DESC {};
rtvDesc.Format = t2dDesc.Format;
rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;
rtvDesc.Texture2D.MipSlice = 0u;
dxc(m_context->get_device()
->CreateRenderTargetView(m_color_attachment.Get(), &rtvDesc, &m_render_target_view));
}
void dxFramebuffer::bind_as_target(const glm::vec4 &clearColor)
{
FLOAT color[] = {
clearColor.r,
clearColor.g,
clearColor.b,
clearColor.a,
};
m_context->get_device_context()
->OMSetRenderTargets(1u, m_render_target_view.GetAddressOf(), nullptr);
m_context->get_device_context()->ClearRenderTargetView(m_render_target_view.Get(), color);
auto viewport = D3D11_VIEWPORT {};
viewport.TopLeftX = 0;
viewport.TopLeftY = 0;
viewport.Width = m_specification.width;
viewport.Height = m_specification.height;
viewport.MinDepth = 0.0f;
viewport.MaxDepth = 1.0f;
// set viewport
m_context->get_device_context()->RSSetViewports(1u, &viewport);
}
void dxFramebuffer::bind_as_resource()
{
log_err("NO_IMPLEMENT");
}
void dxFramebuffer::resize(const glm::uvec2 &size)
{
m_specification.width = std::clamp(size.x, 1u, 16384u);
m_specification.height = std::clamp(size.y, 1u, 16384u);
auto textureDesc = D3D11_TEXTURE2D_DESC {};
auto rtvDesc = D3D11_RENDER_TARGET_VIEW_DESC {};
auto srvDesc = D3D11_SHADER_RESOURCE_VIEW_DESC {};
m_color_attachment->GetDesc(&textureDesc);
m_render_target_view->GetDesc(&rtvDesc);
m_shader_resource_view->GetDesc(&srvDesc);
textureDesc.Width = m_specification.width;
textureDesc.Height = m_specification.height;
auto hr = HRESULT {};
dxc(m_context->get_device()->CreateTexture2D(&textureDesc, nullptr, &m_color_attachment));
dxc(m_context->get_device()
->CreateRenderTargetView(m_color_attachment.Get(), &rtvDesc, &m_render_target_view));
dxc(m_context->get_device()->CreateShaderResourceView(
m_color_attachment.Get(),
&srvDesc,
&m_shader_resource_view
));
}
} // namespace lt

View file

@ -1,46 +0,0 @@
#pragma once
#include <d3d11.h>
#include <renderer/framebuffer.hpp>
#include <wrl.h>
namespace lt {
class dxSharedContext;
class dxFramebuffer: public Framebuffer
{
public:
dxFramebuffer(
const FramebufferSpecification &specification,
Ref<dxSharedContext> sharedContext
);
auto get_color_attachment() -> void * override
{
return (void *)m_shader_resource_view.Get();
}
void bind_as_target(const glm::vec4 &clearColor) override;
void bind_as_resource() override;
void resize(const glm::uvec2 &size) override;
private:
Ref<dxSharedContext> m_context;
FramebufferSpecification m_specification;
Microsoft::WRL::ComPtr<ID3D11RenderTargetView> m_render_target_view;
Microsoft::WRL::ComPtr<ID3D11Texture2D> m_color_attachment;
Microsoft::WRL::ComPtr<ID3D11Texture2D> m_depth_stencil_attachment;
Microsoft::WRL::ComPtr<ID3D11ShaderResourceView> m_shader_resource_view;
Microsoft::WRL::ComPtr<ID3D11DepthStencilView> m_depth_stencil_view;
};
} // namespace lt

View file

@ -1,159 +0,0 @@
#include <input/events/window.hpp>
#include <renderer/blender.hpp" // required for forward declaratio>
#include <renderer/buffers.hpp" // required for forward declaratio>
#include <renderer/dx/graphics_context.hpp>
#include <renderer/dx/shared_context.hpp>
#include <renderer/render_command.hpp> // required for forward declaratio>
#include <renderer/renderer.hpp> // required for forward declaratio>
#include <ui/ui.hpp> // required for forward declaratio>
namespace lt {
dxGraphicsContext::dxGraphicsContext(): m_window_handle(windowHandle), m_debug_interface(nullptr)
{
// set 'GraphicsAPI';
m_graphics_api = GraphicsAPI::DirectX;
m_shared_context = std::make_shared<dxSharedContext>();
// setup stuff
setup_device_and_swap_chain(windowHandle);
setup_render_targets();
setup_debug_interface();
}
void dxGraphicsContext::setup_device_and_swap_chain()
{
auto context = std::static_pointer_cast<dxSharedContext>(m_shared_context);
// swap chain desc
auto sd = DXGI_SWAP_CHAIN_DESC { 0 };
// buffer desc
sd.BufferDesc.Width = 1u;
sd.BufferDesc.Height = 1u;
sd.BufferDesc.RefreshRate.Numerator = NULL; // :#todo
sd.BufferDesc.RefreshRate.Denominator = NULL; // :#todo
sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
sd.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
sd.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
// sample desc (for multi sampling) #todo: implement multi-samplingz
sd.SampleDesc.Count = 1u;
sd.SampleDesc.Quality = 0u;
// #todo: support swap chains with more than 1 back-buffer
sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
sd.BufferCount = 1u;
sd.OutputWindow = {}; // ...
sd.Windowed = true;
sd.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
sd.Flags = NULL;
// determine device flags
auto flags = UINT { NULL };
#ifdef LIGHT_DEBUG
flags = D3D11_CREATE_DEVICE_DEBUG;
#endif
// create device and swap chain
dxc(D3D11CreateDeviceAndSwapChain(
nullptr,
D3D_DRIVER_TYPE_HARDWARE,
NULL,
flags,
nullptr,
NULL,
D3D11_SDK_VERSION,
&sd,
&context->GetSwapChainRef(),
&context->GetDeviceRef(),
nullptr,
&context->GetDeviceContextRef()
));
}
void dxGraphicsContext::setup_render_targets()
{
auto context = std::static_pointer_cast<dxSharedContext>(m_shared_context);
// set primitive topology
context->get_device_context()->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
// create render target view
auto backBuffer = Microsoft::WRL::ComPtr<ID3D11Resource> {};
dxc(context->get_swap_chain()->GetBuffer(0u, __uuidof(ID3D11Resource), &backBuffer));
dxc(context->get_device()->CreateRenderTargetView(
backBuffer.Get(),
nullptr,
&context->GetRenderTargetViewRef()
));
// set render target view
context->get_device_context()
->OMSetRenderTargets(1u, context->get_render_target_view().GetAddressOf(), nullptr);
}
void dxGraphicsContext::setup_debug_interface()
{
#ifdef LIGHT_DEBUG
Ref<dxSharedContext> context = std::static_pointer_cast<dxSharedContext>(m_shared_context);
HRESULT hr;
Microsoft::WRL::ComPtr<ID3D11Debug> debugInterface = nullptr;
dxc(context->get_device()->QueryInterface(__uuidof(ID3D11Debug), &debugInterface));
Microsoft::WRL::ComPtr<ID3D11InfoQueue> infoQueue = nullptr;
dxc(debugInterface->QueryInterface(__uuidof(ID3D11InfoQueue), &infoQueue));
infoQueue->SetBreakOnSeverity(D3D11_MESSAGE_SEVERITY_CORRUPTION, true);
infoQueue->SetBreakOnSeverity(D3D11_MESSAGE_SEVERITY_ERROR, true);
D3D11_MESSAGE_ID hide[] = {
D3D11_MESSAGE_ID_UNKNOWN,
// #todo: add more messages here as needed
};
D3D11_INFO_QUEUE_FILTER filter = {};
filter.DenyList.NumIDs = _countof(hide);
filter.DenyList.pIDList = hide;
infoQueue->AddStorageFilterEntries(&filter);
infoQueue->release();
#endif
}
void dxGraphicsContext::log_debug_data()
{
auto context = std::static_pointer_cast<dxSharedContext>(m_shared_context);
// locals
auto *DXGIDevice = (IDXGIDevice *) {};
auto *DXGIAdapter = (IDXGIAdapter *) {};
auto *DXGIAdapterDesc = (DXGI_ADAPTER_DESC *) {};
context->get_device()->QueryInterface(__uuidof(IDXGIDevice), (void **)&DXGIDevice);
DXGIDevice->GetAdapter(&DXGIAdapter);
DXGIAdapter->GetDesc(&DXGIAdapterDesc);
// get the adapter's description
auto DefChar = ' ';
char ch[180];
WideCharToMultiByte(CP_ACP, 0, DXGIAdapterDesc.Description, -1, ch, 180, &DefChar, NULL);
auto adapterDesc = std::string { ch };
// release memory
DXGIDevice->release();
DXGIAdapter->release();
// #todo: log more information
log_inf("________________________________________");
log_inf("dxGraphicsContext:");
log_inf(" renderer: {}", adapterDesc);
log_inf("________________________________________");
}
} // namespace lt

View file

@ -1,26 +0,0 @@
#pragma once
#include <d3d11.h>
#include <renderer/graphics_context.hpp>
#include <wrl.h>
namespace lt {
class dxGraphicsContext: public GraphicsContext
{
public:
dxGraphicsContext();
virtual void log_debug_data() override;
private:
Microsoft::WRL::ComPtr<ID3D11Debug> m_debug_interface;
void setup_device_and_swap_chain();
void setup_render_targets();
void setup_debug_interface();
};
} // namespace lt

View file

@ -1,105 +0,0 @@
#include <renderer/dx/render_command.hpp>
#include <renderer/dx/shared_context.hpp>
namespace lt {
dxRenderCommand::dxRenderCommand(Ref<dxSharedContext> sharedContext): m_context(sharedContext)
{
}
void dxRenderCommand::swap_buffers()
{
#ifdef LIGHT_DEBUG
HRESULT hr;
if (FAILED(hr = m_context->get_swap_chain()->Present(1u, 0u)))
{
if (hr == DXGI_ERROR_DEVICE_REMOVED)
{
log_crt("dxRenderCommand::swap_buffers: DeviceRemoved:");
log_crt(" {}", m_context->get_device()->GetDeviceRemovedReason());
throw dxException(hr, __FILE__, __LINE__);
}
}
#else
m_context->get_swap_chain()->Present(0u, 0u);
#endif
}
void dxRenderCommand::clear_back_buffer(const glm::vec4 &clearColor)
{
m_context->get_device_context()->ClearRenderTargetView(
m_context->get_render_target_view().Get(),
&clearColor[0]
);
}
void dxRenderCommand::draw(unsigned int count)
{
m_context->get_device_context()->draw(count, 0u);
}
void dxRenderCommand::draw_indexed(unsigned int count)
{
m_context->get_device_context()->draw_indexed(count, 0u, 0u);
}
void dxRenderCommand::default_target_framebuffer()
{
m_context->get_device_context()
->OMSetRenderTargets(1, m_context->get_render_target_view().GetAddressOf(), nullptr);
}
void dxRenderCommand::set_viewport(
unsigned int x,
unsigned int y,
unsigned int width,
unsigned int height
)
{
// #todo: maybe call this somewhere else??
set_resolution(width, height);
// create viewport
auto viewport = D3D11_VIEWPORT {};
viewport.TopLeftX = x;
viewport.TopLeftY = y;
viewport.Width = width;
viewport.Height = height;
viewport.MinDepth = 0.0f;
viewport.MaxDepth = 1.0f;
// set viewport
m_context->get_device_context()->RSSetViewports(1u, &viewport);
}
void dxRenderCommand::set_resolution(unsigned int width, unsigned int height)
{
auto hr = HRESULT {};
// remove render target
auto *nullViews[] = (ID3D11RenderTargetView *) { nullptr };
m_context->get_device_context()->OMSetRenderTargets(1u, nullViews, nullptr);
m_context->GetRenderTargetViewRef().reset();
// resize buffer
dxc(m_context->get_swap_chain()
->ResizeBuffers(0u, width, height, DXGI_FORMAT_R8G8B8A8_UNORM, NULL));
// create render target
auto backBuffer = Microsoft::WRL::ComPtr<ID3D11Resource> { nullptr };
dxc(m_context->get_swap_chain()->GetBuffer(0u, __uuidof(ID3D11Resource), &backBuffer));
dxc(m_context->get_device()->CreateRenderTargetView(
backBuffer.Get(),
nullptr,
&m_context->GetRenderTargetViewRef()
));
// set render target
m_context->get_device_context()
->OMSetRenderTargets(1u, m_context->get_render_target_view().GetAddressOf(), nullptr);
}
} // namespace lt

View file

@ -1,39 +0,0 @@
#pragma once
#include <d3d11.h>
#include <renderer/render_command.hpp>
#include <wrl.h>
namespace lt {
class dxSharedContext;
class dxRenderCommand: public RenderCommand
{
public:
dxRenderCommand(Ref<dxSharedContext> sharedContext);
virtual void swap_buffers() override;
virtual void clear_back_buffer(const glm::vec4 &clearColor) override;
virtual void draw(unsigned int count) override;
virtual void draw_indexed(unsigned int count) override;
virtual void default_target_framebuffer() override;
virtual void set_viewport(
unsigned int x,
unsigned int y,
unsigned int width,
unsigned int height
) override;
private:
Ref<dxSharedContext> m_context;
void set_resolution(unsigned int width, unsigned int height);
};
} // namespace lt

View file

@ -1,85 +0,0 @@
#include <d3dcompiler.h>
#include <renderer/dx/shader.hpp>
#include <renderer/dx/shared_context.hpp>
namespace lt {
dxShader::dxShader(
BasicFileHandle vertexFile,
BasicFileHandle pixelFile,
Ref<dxSharedContext> sharedContext
)
: m_context(sharedContext)
, m_vertex_shader(nullptr)
, m_pixel_shader(nullptr)
, m_vertex_blob(nullptr)
{
auto ps = Microsoft::WRL::ComPtr<ID3DBlob> { nullptr };
auto vsErr = Microsoft::WRL::ComPtr<ID3DBlob> { nullptr };
auto psErr = Microsoft::WRL::ComPtr<ID3DBlob> { nullptr };
// compile shaders (we don't use dxc here because if d3_d_compile fails it throws a dxException
// without logging the vsErr/psErr
d3_d_compile(
vertexFile.GetData(),
vertexFile.get_size(),
NULL,
nullptr,
nullptr,
"main",
"vs_4_0",
NULL,
NULL,
&m_vertex_blob,
&vsErr
);
d3_d_compile(
pixelFile.GetData(),
pixelFile.get_size(),
NULL,
nullptr,
nullptr,
"main",
"ps_4_0",
NULL,
NULL,
&ps,
&psErr
);
// check
ensure(!vsErr.Get(), "Vertex shader compile error: {}", (char *)vsErr->GetBufferPointer());
ensure(!psErr.Get(), "Pixels shader compile error: {}", (char *)psErr->GetBufferPointer());
// create shaders
auto hr = HRESULT {};
dxc(m_context->get_device()->CreateVertexShader(
m_vertex_blob->GetBufferPointer(),
m_vertex_blob->GetBufferSize(),
NULL,
&m_vertex_shader
));
dxc(
m_context->get_device()
->CreatePixelShader(ps->GetBufferPointer(), ps->GetBufferSize(), NULL, &m_pixel_shader)
);
}
dxShader::~dxShader()
{
un_bind();
}
void dxShader::bind()
{
m_context->get_device_context()->VSSetShader(m_vertex_shader.Get(), nullptr, 0u);
m_context->get_device_context()->PSSetShader(m_pixel_shader.Get(), nullptr, 0u);
}
void dxShader::un_bind()
{
m_context->get_device_context()->VSSetShader(nullptr, nullptr, 0u);
m_context->get_device_context()->PSSetShader(nullptr, nullptr, 0u);
}
} // namespace lt

View file

@ -1,41 +0,0 @@
#pragma once
#include <d3d11.h>
#include <renderer/shader.hpp>
#include <wrl.h>
namespace lt {
class dxSharedContext;
class dxShader: public Shader
{
public:
dxShader(
BasicFileHandle vertexFile,
BasicFileHandle pixelFile,
Ref<dxSharedContext> sharedContext
);
~dxShader();
void bind() override;
void un_bind() override;
auto get_vertex_blob() -> Microsoft::WRL::ComPtr<ID3DBlob>
{
return m_vertex_blob;
}
private:
Ref<dxSharedContext> m_context;
Microsoft::WRL::ComPtr<ID3D11VertexShader> m_vertex_shader;
Microsoft::WRL::ComPtr<ID3D11PixelShader> m_pixel_shader;
Microsoft::WRL::ComPtr<ID3DBlob> m_vertex_blob;
};
} // namespace lt

View file

@ -1,62 +0,0 @@
#pragma once
#include <d3d11.h>
#include <renderer/shared_context.hpp>
#include <wrl.h>
namespace lt {
class dxSharedContext: public SharedContext
{
public:
[[nodiscard]] auto get_device() -> Microsoft::WRL::ComPtr<ID3D11Device>
{
return m_device;
}
[[nodiscard]] auto get_device_context() -> Microsoft::WRL::ComPtr<ID3D11DeviceContext>
{
return m_deviceContext;
}
[[nodiscard]] auto get_swap_chain() -> Microsoft::WRL::ComPtr<IDXGISwapChain>
{
return m_swap_chain;
}
[[nodiscard]] auto get_render_target_view() -> Microsoft::WRL::ComPtr<ID3D11RenderTargetView>
{
return m_render_target_view;
}
[[nodiscard]] auto GetDeviceRef() -> Microsoft::WRL::ComPtr<ID3D11Device>
{
return m_device;
}
[[nodiscard]] auto GetDeviceContextRef() -> Microsoft::WRL::ComPtr<ID3D11DeviceContext>
{
return m_deviceContext;
}
[[nodiscard]] auto GetSwapChainRef() -> Microsoft::WRL::ComPtr<IDXGISwapChain>
{
return m_swap_chain;
}
[[nodiscard]] auto GetRenderTargetViewRef() -> Microsoft::WRL::ComPtr<ID3D11RenderTargetView>
{
return m_render_target_view;
}
private:
Microsoft::WRL::ComPtr<ID3D11Device> m_device = nullptr;
Microsoft::WRL::ComPtr<ID3D11DeviceContext> m_deviceContext = nullptr;
Microsoft::WRL::ComPtr<IDXGISwapChain> m_swap_chain = nullptr;
Microsoft::WRL::ComPtr<ID3D11RenderTargetView> m_render_target_view = nullptr;
};
} // namespace lt

View file

@ -1,80 +0,0 @@
#include <renderer/dx/shared_context.hpp>
#include <renderer/dx/texture.hpp>
namespace lt {
dxTexture::dxTexture(
unsigned int width,
unsigned int height,
unsigned int components,
unsigned char *pixels,
Ref<dxSharedContext> sharedContext,
const std::string &filePath
)
: Texture(filePath)
, m_context(sharedContext)
, m_texture_2d(nullptr)
, m_shader_resource_view(nullptr)
, m_sampler_state(nullptr)
{
// texture2d desc
auto t2dDesc = D3D11_TEXTURE2D_DESC {};
t2dDesc.Width = width;
t2dDesc.Height = height;
t2dDesc.MipLevels = 0u;
t2dDesc.ArraySize = 1u;
t2dDesc.Format = components == 4u ? DXGI_FORMAT_R8G8B8A8_UNORM :
components == 3u ? DXGI_FORMAT_R8G8B8A8_UNORM :
// #todo: figure out what to do with this bitch ._.
components == 2u ? DXGI_FORMAT_R8G8_UNORM :
components == 1u ? DXGI_FORMAT_R8_UNORM :
DXGI_FORMAT_UNKNOWN;
t2dDesc.SampleDesc.Count = 1u;
t2dDesc.SampleDesc.Quality = 0u;
t2dDesc.Usage = D3D11_USAGE_DEFAULT;
t2dDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET;
t2dDesc.CPUAccessFlags = NULL;
t2dDesc.MiscFlags = D3D11_RESOURCE_MISC_GENERATE_MIPS;
// create texture
auto hr = HRESULT {};
dxc(m_context->get_device()->CreateTexture2D(&t2dDesc, nullptr, &m_texture_2d));
m_context->get_device_context()
->UpdateSubresource(m_texture_2d.Get(), 0u, nullptr, pixels, width * 4u, 0u);
m_texture_2d->GetDesc(&t2dDesc);
// shader resource view desc
auto srvDesc = D3D11_SHADER_RESOURCE_VIEW_DESC {};
srvDesc.Format = t2dDesc.Format;
srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
srvDesc.Texture2D.MostDetailedMip = 0u;
srvDesc.Texture2D.MipLevels = -1;
// create shader resource view
m_context->get_device()
->CreateShaderResourceView(m_texture_2d.Get(), &srvDesc, &m_shader_resource_view);
m_context->get_device_context()->GenerateMips(m_shader_resource_view.Get());
// sampler desc
auto sDesc = D3D11_SAMPLER_DESC {};
sDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
sDesc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP;
sDesc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP;
sDesc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP;
sDesc.MinLOD = 0.0f;
sDesc.MipLODBias = 0.0f;
sDesc.MaxLOD = D3D11_FLOAT32_MAX;
// create sampler
m_context->get_device()->CreateSamplerState(&sDesc, &m_sampler_state);
}
void dxTexture::bind(unsigned int slot /* = 0u */)
{
m_context->get_device_context()->PSSetSamplers(slot, 1u, m_sampler_state.GetAddressOf());
m_context->get_device_context()
->PSSetShaderResources(slot, 1u, m_shader_resource_view.GetAddressOf());
}
} // namespace lt

View file

@ -1,35 +0,0 @@
#pragma once
#include <d3d11.h>
#include <renderer/texture.hpp>
#include <wrl.h>
namespace lt {
class dxSharedContext;
class dxTexture: public Texture
{
public:
dxTexture(
unsigned int width,
unsigned int height,
unsigned int components,
unsigned char *pixels,
Ref<dxSharedContext> sharedContext,
const std::string &filePath
);
void bind(unsigned int slot = 0u) override;
private:
Ref<dxSharedContext> m_context;
Microsoft::WRL::ComPtr<ID3D11Texture2D> m_texture_2d;
Microsoft::WRL::ComPtr<ID3D11ShaderResourceView> m_shader_resource_view;
Microsoft::WRL::ComPtr<ID3D11SamplerState> m_sampler_state;
};
} // namespace lt

View file

@ -1,27 +0,0 @@
#pragma once
#include <d3d11.h>
#include <ui/ui.hpp>
#include <wrl.h>
namespace lt {
class dxSharedContext;
class dxUserInterface: public UserInterface
{
public:
dxUserInterface() = default;
~dxUserInterface();
void platform_implementation(Ref<SharedContext> sharedContext) override;
void begin() override;
void end() override;
void log_debug_data() override;
};
} // namespace lt

View file

@ -1,97 +0,0 @@
#include <renderer/dx/shader.hpp>
#include <renderer/dx/shared_context.hpp>
#include <renderer/dx/vertex_layout.hpp>
namespace lt {
dxVertexLayout::dxVertexLayout(
Ref<Shader> shader,
const std::vector<std::pair<std::string, VertexElementType>> &elements,
Ref<dxSharedContext> sharedContext
)
: m_context(sharedContext)
, m_input_layout(nullptr)
{
auto inputElementsDesc = std::vector<D3D11_INPUT_ELEMENT_DESC> {};
inputElementsDesc.reserve(elements.size());
// extract elements desc
for (const auto &element : elements)
{
inputElementsDesc.emplace_back(
D3D11_INPUT_ELEMENT_DESC { element.first.c_str(),
NULL,
get_dxgi_format(element.second),
0u,
D3D11_APPEND_ALIGNED_ELEMENT,
D3D11_INPUT_PER_VERTEX_DATA,
0u }
);
}
auto dxpShader = std::dynamic_pointer_cast<dxShader>(shader);
ensure(dxpShader, "Failed to cast 'Shader' to 'dxShader'");
// create input layout (vertex layout)
auto hr = HRESULT {};
dxc(m_context->get_device()->CreateInputLayout(
&inputElementsDesc[0],
inputElementsDesc.size(),
dxpShader->get_vertex_blob().Get()->GetBufferPointer(),
dxpShader->get_vertex_blob().Get()->GetBufferSize(),
&m_input_layout
));
}
dxVertexLayout::~dxVertexLayout()
{
un_bind();
}
void dxVertexLayout::bind()
{
m_context->get_device_context()->IASetInputLayout(m_input_layout.Get());
}
void dxVertexLayout::un_bind()
{
m_context->get_device_context()->IASetInputLayout(nullptr);
}
auto dxVertexLayout::get_dxgi_format(VertexElementType type) -> DXGI_FORMAT
{
switch (type)
{
/* byte */
case lt::VertexElementType::Byte1: return DXGI_FORMAT_R8_SINT;
case lt::VertexElementType::Byte2: return DXGI_FORMAT_R8G8_SINT;
case lt::VertexElementType::Byte4: return DXGI_FORMAT_R8_SINT;
/* ubyte */
case lt::VertexElementType::UByte1: return DXGI_FORMAT_R8_UINT;
case lt::VertexElementType::UByte2: return DXGI_FORMAT_R8G8_UINT;
case lt::VertexElementType::UByte4: return DXGI_FORMAT_R8G8B8A8_UINT;
/* int */
case lt::VertexElementType::Int1: return DXGI_FORMAT_R32_SINT;
case lt::VertexElementType::Int2: return DXGI_FORMAT_R32G32_SINT;
case lt::VertexElementType::Int3: return DXGI_FORMAT_R32G32B32_SINT;
case lt::VertexElementType::Int4: return DXGI_FORMAT_R32G32B32A32_SINT;
/* uint */
case lt::VertexElementType::UInt1: return DXGI_FORMAT_R32_UINT;
case lt::VertexElementType::UInt2: return DXGI_FORMAT_R32G32_UINT;
case lt::VertexElementType::UInt3: return DXGI_FORMAT_R32G32B32_UINT;
case lt::VertexElementType::UInt4: return DXGI_FORMAT_R32G32B32A32_UINT;
/* float */
case lt::VertexElementType::Float1: return DXGI_FORMAT_R32_FLOAT;
case lt::VertexElementType::Float2: return DXGI_FORMAT_R32G32_FLOAT;
case lt::VertexElementType::Float3: return DXGI_FORMAT_R32G32B32_FLOAT;
case lt::VertexElementType::Float4: return DXGI_FORMAT_R32G32B32A32_FLOAT;
default: ensure(false, "Invalid 'VertexElementType'"); return DXGI_FORMAT_UNKNOWN;
}
}
} // namespace lt

View file

@ -1,35 +0,0 @@
#pragma once
#include <d3d11.h>
#include <renderer/vertex_layout.hpp>
#include <wrl.h>
namespace lt {
class Shader;
class dxSharedContext;
class dxVertexLayout: public VertexLayout
{
public:
dxVertexLayout(
Ref<Shader> shader,
const std::vector<std::pair<std::string, VertexElementType>> &elements,
Ref<dxSharedContext> sharedContext
);
~dxVertexLayout();
void bind() override;
void un_bind() override;
private:
DXGI_FORMAT get_dxgi_format(VertexElementType type);
Ref<dxSharedContext> m_context;
Microsoft::WRL::ComPtr<ID3D11InputLayout> m_input_layout;
};
} // namespace lt

View file

@ -1,41 +0,0 @@
#include <renderer/framebuffer.hpp>
#include <renderer/gl/framebuffers.hpp>
#ifdef LIGHT_PLATFORM_WINDOWS
#include <renderer/dx/framebuffer.hpp>
#include <renderer/dx/sharedcontext.hpp>
#endif
#include <renderer/graphics_context.hpp>
namespace lt {
auto Framebuffer::create(
const FramebufferSpecification &specification,
const Ref<SharedContext> & /*sharedContext*/
) -> Ref<Framebuffer>
{
switch (GraphicsContext::get_graphics_api())
{
case GraphicsAPI::OpenGL: return create_ref<glFramebuffer>(specification);
case GraphicsAPI::DirectX:
lt_win(
return create_ref<dxFramebuffer>(
specification,
std::static_pointer_cast<dxSharedContext>(sharedContext)
);
);
default:
ensure(
false,
"Invalid/unsupported 'GraphicsAPI' {}",
static_cast<uint32_t>(GraphicsContext::get_graphics_api())
);
return nullptr;
}
}
} // namespace lt

View file

@ -1,45 +0,0 @@
#include <renderer/gl/blender.hpp>
namespace lt {
glBlender::glBlender()
: m_factor_map { // constants
{ BlendFactor::ZERO, GL_ZERO },
{ BlendFactor::ONE, GL_ONE },
// source ,
{ BlendFactor::SRC_COLOR, GL_SRC_COLOR },
{ BlendFactor::INVERSE_SRC_COLOR, GL_ONE_MINUS_SRC_COLOR },
{ BlendFactor::SRC_ALPHA, GL_SRC_ALPHA },
{ BlendFactor::INVERSE_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA },
// destination ,
{ BlendFactor::DST_COLOR, GL_DST_COLOR },
{ BlendFactor::INVERSE_DST_COLOR, GL_ONE_MINUS_DST_COLOR },
{ BlendFactor::DST_ALPHA, GL_DST_ALPHA },
{ BlendFactor::INVERSE_DST_ALPHA, GL_ONE_MINUS_DST_ALPHA },
// source1 ,
{ BlendFactor::SRC1_COLOR, GL_SRC1_COLOR },
{ BlendFactor::INVERSE_SRC1_COLOR, GL_ONE_MINUS_SRC1_COLOR },
{ BlendFactor::SRC1_ALPHA, GL_SRC1_ALPHA },
{ BlendFactor::INVERSE_SRC1_ALPHA, GL_ONE_MINUS_SRC_ALPHA }
}
{
}
void glBlender::enable(BlendFactor srcFactor, BlendFactor dstFactor)
{
glEnable(GL_BLEND);
glBlendFunc(m_factor_map.at(srcFactor), m_factor_map.at(dstFactor));
}
void glBlender::disable()
{
glDisable(GL_BLEND);
}
} // namespace lt

View file

@ -1,22 +0,0 @@
#pragma once
#include <renderer/blender.hpp>
namespace lt {
class glBlender: public Blender
{
public:
~glBlender() override = default;
glBlender();
void enable(BlendFactor srcFactor, BlendFactor dstFactor) override;
void disable() override;
private:
std::unordered_map<BlendFactor, unsigned int> m_factor_map;
};
} // namespace lt

View file

@ -1,138 +0,0 @@
#include <cstddef>
#include <logger/logger.hpp>
#include <renderer/gl/buffers.hpp>
namespace lt {
//==================== CONSTANT_BUFFER ====================//
glConstantBuffer::glConstantBuffer(ConstantBufferIndex index, unsigned int size)
: m_buffer_id()
, m_index(static_cast<int>(index))
{
glCreateBuffers(1, &m_buffer_id);
glNamedBufferData(m_buffer_id, size, nullptr, GL_DYNAMIC_DRAW);
bind();
}
glConstantBuffer::~glConstantBuffer()
{
glDeleteBuffers(1, &m_buffer_id);
}
void glConstantBuffer::bind()
{
glBindBufferBase(GL_UNIFORM_BUFFER, m_index, m_buffer_id);
}
auto glConstantBuffer::map() -> void *
{
auto *map = glMapNamedBuffer(m_buffer_id, GL_WRITE_ONLY);
return map;
}
void glConstantBuffer::un_map()
{
glUnmapNamedBuffer(m_buffer_id);
}
//==================== CONSTANT_BUFFER ====================//
//==================== VERTEX_BUFFER ====================//
glVertexBuffer::glVertexBuffer(float *vertices, unsigned int stride, unsigned int count)
: m_buffer_id()
{
glCreateBuffers(1, &m_buffer_id);
glNamedBufferData(
m_buffer_id,
static_cast<GLsizeiptr>(stride * count),
vertices,
GL_DYNAMIC_DRAW
);
}
glVertexBuffer::~glVertexBuffer()
{
glDeleteBuffers(1, &m_buffer_id);
}
void glVertexBuffer::bind()
{
glBindBuffer(GL_ARRAY_BUFFER, m_buffer_id);
}
void glVertexBuffer::un_bind()
{
glBindBuffer(GL_ARRAY_BUFFER, {});
}
auto glVertexBuffer::map() -> void *
{
return glMapNamedBuffer(m_buffer_id, GL_WRITE_ONLY);
}
void glVertexBuffer::un_map()
{
glUnmapNamedBuffer(m_buffer_id);
}
//==================== VERTEX_BUFFER ====================//
//==================== INDEX_BUFFER ====================//
glIndexBuffer::glIndexBuffer(unsigned int *indices, unsigned int count): m_buffer_id()
{
// generate indices if not provided
auto hasIndices = !!indices;
if (!hasIndices)
{
// check
if (count % 6 != 0)
{
log_wrn("'indices' can only be null if count is multiple of 6");
log_wrn("Adding {} to 'count' -> {}", (6 - (count % 6)), count + (6 - (count % 6)));
count = count + (6 - (count % 6));
}
// create indices
indices = new unsigned int[count];
auto offset = 0u;
for (auto i = 0u; i < count; i += 6u)
{
indices[i + 0] = offset + 0u;
indices[i + 1] = offset + 1u;
indices[i + 2] = offset + 2u;
indices[i + 3] = offset + 2u;
indices[i + 4] = offset + 3u;
indices[i + 5] = offset + 0u;
offset += 4u;
}
}
// create buffer
glCreateBuffers(1, &m_buffer_id);
glNamedBufferData(m_buffer_id, count * sizeof(unsigned int), indices, GL_STATIC_DRAW);
// delete indices
if (!hasIndices)
{
delete[] indices;
}
}
glIndexBuffer::~glIndexBuffer()
{
glDeleteBuffers(1, &m_buffer_id);
}
void glIndexBuffer::bind()
{
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_buffer_id);
}
void glIndexBuffer::un_bind()
{
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, {});
}
//==================== INDEX_BUFFER ====================//
} // namespace lt

View file

@ -1,61 +0,0 @@
#pragma once
#include <renderer/buffers.hpp>
namespace lt {
class glConstantBuffer: public ConstantBuffer
{
public:
glConstantBuffer(ConstantBufferIndex index, unsigned int size);
~glConstantBuffer() override;
void bind() override;
auto map() -> void * override;
void un_map() override;
private:
unsigned int m_buffer_id;
unsigned int m_index;
};
class glVertexBuffer: public VertexBuffer
{
public:
glVertexBuffer(float *vertices, unsigned int stride, unsigned int count);
~glVertexBuffer() override;
void bind() override;
void un_bind() override;
auto map() -> void * override;
void un_map() override;
private:
unsigned int m_buffer_id;
};
class glIndexBuffer: public IndexBuffer
{
public:
glIndexBuffer(unsigned int *indices, unsigned int count);
~glIndexBuffer() override;
void bind() override;
void un_bind() override;
private:
unsigned int m_buffer_id;
};
} // namespace lt

View file

@ -1,83 +0,0 @@
#include <renderer/gl/framebuffers.hpp>
namespace lt {
glFramebuffer::glFramebuffer(const FramebufferSpecification &specification)
: m_specification(specification)
, m_buffer_id()
, m_color_attachment_id()
, m_depth_stencil_attachment_id()
{
resize({ specification.width, specification.height });
}
glFramebuffer::~glFramebuffer()
{
glDeleteFramebuffers(1, &m_buffer_id);
glDeleteTextures(1, &m_color_attachment_id);
// glDeleteTextures(1, &m_depth_stencil_attachment_id);
}
void glFramebuffer::bind_as_target(const math::vec4 &clearColor)
{
// #todo: use viewport instead of default x=0, y=0
glBindFramebuffer(GL_FRAMEBUFFER, m_buffer_id);
glViewport(0, 0, m_specification.width, m_specification.height);
glClearColor(clearColor.r, clearColor.g, clearColor.b, clearColor.a);
glClear(GL_COLOR_BUFFER_BIT);
}
void glFramebuffer::bind_as_resource()
{
log_err("NO_IMPLEMENT!");
}
void glFramebuffer::resize(const math::uvec2 &size)
{
if (m_buffer_id)
{
glDeleteFramebuffers(1, &m_buffer_id);
glDeleteTextures(1, &m_color_attachment_id);
// glDeleteTextures(1, &m_depth_stencil_attachment_id);
}
m_specification.width = std::clamp(size.x, 1u, (unsigned int)GL_MAX_TEXTURE_SIZE);
m_specification.height = std::clamp(size.y, 1u, (unsigned int)GL_MAX_TEXTURE_SIZE);
glCreateFramebuffers(1, &m_buffer_id);
glBindFramebuffer(GL_FRAMEBUFFER, m_buffer_id);
// create color attachment
glCreateTextures(GL_TEXTURE_2D, 1, &m_color_attachment_id);
glBindTexture(GL_TEXTURE_2D, m_color_attachment_id);
glTexImage2D(
GL_TEXTURE_2D,
0,
GL_RGBA8,
m_specification.width,
m_specification.height,
{},
GL_RGBA,
GL_UNSIGNED_BYTE,
nullptr
);
glTextureParameteri(m_color_attachment_id, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTextureParameteri(m_color_attachment_id, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glFramebufferTexture2D(
GL_FRAMEBUFFER,
GL_COLOR_ATTACHMENT0,
GL_TEXTURE_2D,
m_color_attachment_id,
0
);
ensure(
(glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE),
"Framebuffer is incomplete"
);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
} // namespace lt

View file

@ -1,37 +0,0 @@
#pragma once
#include <math/vec2.hpp>
#include <math/vec4.hpp>
#include <renderer/framebuffer.hpp>
namespace lt {
class glFramebuffer: public Framebuffer
{
public:
glFramebuffer(const FramebufferSpecification &specification);
~glFramebuffer() override;
void bind_as_target(const math::vec4 &clearColor) override;
void bind_as_resource() override;
void resize(const math::uvec2 &size) override;
auto get_color_attachment() -> void * override
{
return (void *)m_color_attachment_id;
}
private:
FramebufferSpecification m_specification;
unsigned int m_buffer_id;
unsigned int m_color_attachment_id;
unsigned int m_depth_stencil_attachment_id;
};
} // namespace lt

View file

@ -1,103 +0,0 @@
#include <input/events/window.hpp>
#include <renderer/blender.hpp> // required for forward declaratio>
#include <renderer/buffers.hpp> // required for forward declaratio>
#include <renderer/gl/graphics_context.hpp>
#include <renderer/render_command.hpp> // required for forward declaratio>
#include <renderer/renderer.hpp> // required for forward declaratio>
namespace lt {
glGraphicsContext::glGraphicsContext()
{
m_graphics_api = GraphicsAPI::OpenGL;
set_debug_message_callback();
}
void glGraphicsContext::log_debug_data()
{
log_inf("________________________________________");
log_inf("GraphicsContext::");
log_inf(" API : OpenGL");
log_inf("________________________________________");
}
void glGraphicsContext::set_debug_message_callback()
{
// determine log level
// #todo: set filters from config.h
#if defined(LIGHT_DEBUG)
glEnable(GL_DEBUG_OUTPUT);
glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, nullptr, GL_TRUE);
GLuint ids[] = { 131185 };
glDebugMessageControl(
GL_DEBUG_SOURCE_API,
GL_DEBUG_TYPE_OTHER,
GL_DONT_CARE,
_countof(ids),
ids,
GL_FALSE
);
#elif defined(LIGHT_RELEASE)
glEnable(GL_DEBUG_OUTPUT);
glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, nullptr, GL_FALSE);
glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_HIGH, 0, nullptr, GL_TRUE);
glDebugMessageControl(
GL_DONT_CARE,
GL_DONT_CARE,
GL_DEBUG_SEVERITY_MEDIUM,
0,
nullptr,
GL_TRUE
);
#else // LIGHT_DIST
return;
#endif
/* setup message callback */
glDebugMessageCallback(
[](unsigned int source,
unsigned int type,
unsigned int id,
unsigned int severity,
int /*length*/,
const char *message,
const void * /*userParam*/) {
switch (severity)
{
case GL_DEBUG_SEVERITY_HIGH:
// TODO(Light): Add gl exception class
throw std::runtime_error { "gl exception" };
return;
case GL_DEBUG_SEVERITY_MEDIUM:
case GL_DEBUG_SEVERITY_LOW:
log_wrn(
"glMessageCallback: Severity: {} :: Source: {} :: Type: {} :: ID: {}",
// TODO(Light): Stringify!
severity,
source,
type,
id
);
log_wrn(" {}", message);
return;
case GL_DEBUG_SEVERITY_NOTIFICATION:
log_wrn(
"Severity: {} :: Source: {} :: Type: {} :: ID: {}",
// TODO(Light): Stringify!
severity,
source,
type,
id
);
log_trc(" {}", message);
return;
}
},
nullptr
);
}
} // namespace lt

View file

@ -1,19 +0,0 @@
#pragma once
#include <renderer/graphics_context.hpp>
namespace lt {
class glGraphicsContext: public GraphicsContext
{
public:
glGraphicsContext();
void log_debug_data() override;
private:
void set_debug_message_callback();
};
} // namespace lt

View file

@ -1,44 +0,0 @@
#include <renderer/gl/render_command.hpp>
namespace lt {
glRenderCommand::glRenderCommand(): m_window_handle(windowHandle)
{
}
void glRenderCommand::swap_buffers()
{
}
void glRenderCommand::clear_back_buffer(const math::vec4 &clearColor)
{
glClearColor(clearColor.r, clearColor.g, clearColor.b, clearColor.a);
glClear(GL_COLOR_BUFFER_BIT);
}
void glRenderCommand::draw(unsigned int count)
{
glDrawArrays(GL_TRIANGLES, 0, count);
}
void glRenderCommand::draw_indexed(unsigned int count)
{
glDrawElements(GL_TRIANGLES, count, GL_UNSIGNED_INT, nullptr);
}
void glRenderCommand::default_target_framebuffer()
{
glBindFramebuffer(GL_FRAMEBUFFER, {});
}
void glRenderCommand::set_viewport(
unsigned int x,
unsigned int y,
unsigned int width,
unsigned int height
)
{
glViewport(x, y, width, height);
}
} // namespace lt

View file

@ -1,31 +0,0 @@
#pragma once
#include <math/vec4.hpp>
#include <renderer/render_command.hpp>
namespace lt {
class glRenderCommand: public RenderCommand
{
public:
glRenderCommand();
void swap_buffers() override;
void clear_back_buffer(const math::vec4 &clearColor) override;
void draw(unsigned int count) override;
void draw_indexed(unsigned int count) override;
void default_target_framebuffer() override;
void set_viewport(
unsigned int x,
unsigned int y,
unsigned int width,
unsigned int height
) override;
};
} // namespace lt

View file

@ -1,110 +0,0 @@
#include <asset_parser/assets/text.hpp>
namespace lt {
glShader::glShader(
const Ref<Assets::TextAsset> &vertex_asset,
const Ref<Assets::TextAsset> &pixel_asset
)
: m_shader_id(glCreateProgram())
{
auto vertex_blob_metadata = vertex_asset->get_blob_metadata(Assets::BlobMetadata::Tag::text);
auto pixel_blob_metadata = pixel_asset->get_blob_metadata(Assets::BlobMetadata::Tag::text);
auto vertex_blob = Assets::Blob(vertex_blob_metadata.uncompressed_size);
auto pixel_blob = Assets::Blob(pixel_blob_metadata.uncompressed_size);
vertex_asset->unpack_blob(vertex_blob_metadata.tag, vertex_blob.data(), vertex_blob.size());
pixel_asset->unpack_blob(pixel_blob_metadata.tag, pixel_blob.data(), pixel_blob.size());
auto vertex_source = std::string {
reinterpret_cast<char *>(vertex_blob.data()),
reinterpret_cast<char *>(vertex_blob.data()) + vertex_blob.size(), // NOLINT
};
auto pixel_source = std::string {
reinterpret_cast<char *>(pixel_blob.data()),
reinterpret_cast<char *>(pixel_blob.data()) + pixel_blob.size(), // NOLINT
};
const auto vertex_shader = compile_shader(vertex_source, Shader::Stage::vertex);
const auto pixel_shader = compile_shader(pixel_source, Shader::Stage::pixel);
glAttachShader(m_shader_id, vertex_shader);
glAttachShader(m_shader_id, pixel_shader);
glLinkProgram(m_shader_id);
glDeleteShader(vertex_shader);
glDeleteShader(pixel_shader);
}
glShader::~glShader()
{
glDeleteProgram(m_shader_id);
}
void glShader::bind()
{
glUseProgram(m_shader_id);
}
void glShader::un_bind()
{
glUseProgram({});
}
auto glShader::compile_shader(const std::string &source, Shader::Stage stage) -> unsigned int
{
// &(address of) needs an lvalue
const auto *lvalue_source = source.c_str();
auto shader = glCreateShader(
stage == Shader::Stage::vertex ? GL_VERTEX_SHADER :
stage == Shader::Stage::pixel ? GL_FRAGMENT_SHADER :
stage == Shader::Stage::geometry ? GL_GEOMETRY_SHADER :
0
);
// compile
glShaderSource(shader, 1, &lvalue_source, nullptr);
glCompileShader(shader);
// check
auto isCompiled = 0;
glGetShaderiv(shader, GL_COMPILE_STATUS, &isCompiled);
if (isCompiled == GL_FALSE)
{
auto logLength = 0;
glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &logLength);
auto *errorLog = (char *)alloca(logLength);
glGetShaderInfoLog(shader, logLength, &logLength, &errorLog[0]);
log_err(
"glShader::glShader: failed to compile {} shader:\n {}",
stage == Shader::Stage::vertex ? "Vertex" : "Pixel",
errorLog
);
return {};
}
#define LIGHT_OPENGL_ENABLE_SHADER_INFO_LOG
#ifdef LIGHT_OPENGL_ENABLE_SHADER_INFO_LOG
// info log
{
auto logLength = 0;
glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &logLength);
if (logLength)
{
char *infoLog = (char *)alloca(logLength);
glGetShaderInfoLog(shader, logLength, &logLength, &infoLog[0]);
log_wrn("Shader info: {}", infoLog);
}
}
#endif
return shader;
}
} // namespace lt

View file

@ -1,24 +0,0 @@
#pragma once
#include <renderer/shader.hpp>
namespace lt {
class glShader: public Shader
{
public:
glShader(const Ref<Assets::TextAsset> &vertex_asset, const Ref<Assets::TextAsset> &pixel_asset);
~glShader() override;
void bind() override;
void un_bind() override;
private:
unsigned int compile_shader(const std::string &source, Shader::Stage stage);
unsigned int m_shader_id { 0u };
};
} // namespace lt

View file

@ -1,12 +0,0 @@
#pragma once
#include <renderer/shared_context.hpp>
namespace lt {
class glSharedContext: public SharedContext
{
};
} // namespace lt

View file

@ -1,81 +0,0 @@
#include <asset_parser/assets/texture.hpp>
#include <lt_debug/assertions.hpp>
#include <renderer/gl/texture.hpp>
namespace lt {
glTexture::glTexture(const Ref<Assets::TextureAsset> &asset)
{
const auto metadata = asset->get_metadata();
const auto blob_metadata = asset->get_blob_metadata(Assets::BlobMetadata::Tag::color);
glCreateTextures(GL_TEXTURE_2D, 1, &m_texture_id);
glTextureParameteri(m_texture_id, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTextureParameteri(m_texture_id, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTextureParameteri(m_texture_id, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTextureParameteri(m_texture_id, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
auto blob = std::vector<std::byte>(blob_metadata.uncompressed_size);
asset->unpack_blob(blob_metadata.tag, blob.data(), blob.size());
bind();
glTexImage2D(
GL_TEXTURE_2D,
0,
map_num_components_to_internal_format(metadata.num_components),
static_cast<int>(metadata.pixel_size[0]),
static_cast<int>(metadata.pixel_size[1]),
0,
map_num_components_to_format(metadata.num_components),
GL_UNSIGNED_BYTE,
std::bit_cast<unsigned char *>(blob.data())
);
glGenerateMipmap(GL_TEXTURE_2D);
}
glTexture::~glTexture()
{
glDeleteTextures(1, &m_texture_id);
}
void glTexture::bind(unsigned int slot /* = 0u */)
{
glActiveTexture(GL_TEXTURE0 + slot);
glBindTexture(GL_TEXTURE_2D, m_texture_id);
}
auto glTexture::get_texture() -> void *
{
return (void *)(intptr_t)m_texture_id;
}
[[nodiscard]] auto glTexture::map_num_components_to_format(uint32_t num_components) const -> int
{
switch (num_components)
{
case 4u: return GL_RGBA;
case 3u: return GL_RGB;
case 2u: return GL_RG;
case 1u: return GL_RED;
default: ensure(false, "Invalid number of components: {}", num_components);
}
return {};
}
[[nodiscard]] auto glTexture::map_num_components_to_internal_format(uint32_t num_components) const
-> int
{
switch (num_components)
{
case 4u: return GL_RGBA8;
case 3u: return GL_RGB8;
case 2u: return GL_RG8;
case 1u: return GL_R8;
default: ensure(false, "Invalid number of components: {}", num_components);
}
return {};
}
} // namespace lt

View file

@ -1,26 +0,0 @@
#pragma once
#include <renderer/texture.hpp>
namespace lt {
class glTexture: public Texture
{
public:
glTexture(const Ref<Assets::TextureAsset> &asset);
~glTexture() override;
void bind(unsigned int slot = 0u) override;
auto get_texture() -> void * override;
private:
[[nodiscard]] auto map_num_components_to_format(uint32_t num_components) const -> int;
[[nodiscard]] auto map_num_components_to_internal_format(uint32_t num_components) const -> int;
uint32_t m_texture_id {};
};
} // namespace lt

View file

@ -1,24 +0,0 @@
#pragma once
#include <ui/ui.hpp>
namespace lt {
class glUserInterface: public UserInterface
{
public:
glUserInterface() = default;
~glUserInterface() override;
void platform_implementation(Ref<SharedContext> sharedContext) override;
void begin() override;
void end() override;
void log_debug_data() override;
};
} // namespace lt

View file

@ -1,146 +0,0 @@
#include <lt_debug/assertions.hpp>
#include <renderer/gl/buffers.hpp>
#include <renderer/gl/vertex_layout.hpp>
namespace lt {
glVertexLayout::glVertexLayout(
const Ref<VertexBuffer> &buffer,
const std::vector<std::pair<std::string, VertexElementType>> &elements
)
: m_array_id()
{
// check
ensure(
std::dynamic_pointer_cast<glVertexBuffer>(buffer),
"Failed to cast 'VertexBuffer' to 'glVertexBuffer'"
);
ensure(!elements.empty(), "'elements' is empty");
// local
auto elementsDesc = std::vector<glVertexElementDesc> {};
elementsDesc.reserve(elements.size());
auto stride = 0u;
// extract elements desc
for (const auto &element : elements)
{
elementsDesc.push_back(get_element_desc(element.second, stride));
stride += elementsDesc.back().typeSize * elementsDesc.back().count;
}
// create vertex array
glCreateVertexArrays(1, &m_array_id);
// bind buffer and array
buffer->bind();
bind();
// enable vertex attributes
auto index = 0u;
for (const auto &elementDesc : elementsDesc)
{
glVertexAttribPointer(
index,
elementDesc.count,
elementDesc.type,
GL_FALSE,
stride,
(const void *)elementDesc.offset
);
glEnableVertexAttribArray(index++);
}
}
glVertexLayout::~glVertexLayout()
{
glDeleteVertexArrays(1, &m_array_id);
}
void glVertexLayout::bind()
{
glBindVertexArray(m_array_id);
}
void glVertexLayout::un_bind()
{
glBindVertexArray({});
}
auto glVertexLayout::get_element_desc(VertexElementType type, unsigned int offset)
-> glVertexElementDesc
{
switch (type)
{
/* byte */
case lt::VertexElementType::Byte1:
return { .type = GL_BYTE, .count = 1u, .typeSize = sizeof(GLbyte), .offset = offset };
case lt::VertexElementType::Byte2:
return { .type = GL_BYTE, .count = 1u, .typeSize = sizeof(GLbyte), .offset = offset };
case lt::VertexElementType::Byte4:
return { .type = GL_BYTE, .count = 1u, .typeSize = sizeof(GLbyte), .offset = offset };
/* ubyte */
case lt::VertexElementType::UByte1:
return { .type = GL_UNSIGNED_BYTE,
.count = 1u,
.typeSize = sizeof(GLubyte),
.offset = offset };
case lt::VertexElementType::UByte2:
return { .type = GL_UNSIGNED_BYTE,
.count = 2u,
.typeSize = sizeof(GLubyte),
.offset = offset };
case lt::VertexElementType::UByte4:
return { .type = GL_UNSIGNED_BYTE,
.count = 4u,
.typeSize = sizeof(GLubyte),
.offset = offset };
/* int */
case VertexElementType::Int1:
return { .type = GL_INT, .count = 1u, .typeSize = sizeof(GLint), .offset = offset };
case VertexElementType::Int2:
return { .type = GL_INT, .count = 2u, .typeSize = sizeof(GLint), .offset = offset };
case VertexElementType::Int3:
return { .type = GL_INT, .count = 3u, .typeSize = sizeof(GLint), .offset = offset };
case VertexElementType::Int4:
return { .type = GL_INT, .count = 4u, .typeSize = sizeof(GLint), .offset = offset };
/* uint */
case VertexElementType::UInt1:
return { .type = GL_UNSIGNED_INT,
.count = 1u,
.typeSize = sizeof(GLuint),
.offset = offset };
case VertexElementType::UInt2:
return { .type = GL_UNSIGNED_INT,
.count = 2u,
.typeSize = sizeof(GLuint),
.offset = offset };
case VertexElementType::UInt3:
return { .type = GL_UNSIGNED_INT,
.count = 3u,
.typeSize = sizeof(GLuint),
.offset = offset };
case VertexElementType::UInt4:
return { .type = GL_UNSIGNED_INT,
.count = 4u,
.typeSize = sizeof(GLuint),
.offset = offset };
/* float */
case VertexElementType::Float1:
return { .type = GL_FLOAT, .count = 1u, .typeSize = sizeof(GLfloat), .offset = offset };
case VertexElementType::Float2:
return { .type = GL_FLOAT, .count = 2u, .typeSize = sizeof(GLfloat), .offset = offset };
case VertexElementType::Float3:
return { .type = GL_FLOAT, .count = 3u, .typeSize = sizeof(GLfloat), .offset = offset };
case VertexElementType::Float4:
return { .type = GL_FLOAT, .count = 4u, .typeSize = sizeof(GLfloat), .offset = offset };
default: ensure(false, "Invalid 'VertexElementType'"); return {};
}
}
} // namespace lt

View file

@ -1,41 +0,0 @@
#pragma once
#include <renderer/vertex_layout.hpp>
namespace lt {
class VertexBuffer;
struct glVertexElementDesc
{
unsigned int type;
unsigned int count;
unsigned int typeSize;
unsigned int offset;
};
class glVertexLayout: public VertexLayout
{
public:
glVertexLayout(
const Ref<VertexBuffer> &buffer,
const std::vector<std::pair<std::string, VertexElementType>> &elements
);
~glVertexLayout() override;
void bind() override;
void un_bind() override;
private:
auto get_element_desc(VertexElementType type, unsigned int offset) -> glVertexElementDesc;
unsigned int m_array_id;
};
} // namespace lt

View file

@ -1,58 +0,0 @@
#include <renderer/gl/graphics_context.hpp>
#include <renderer/graphics_context.hpp>
#ifdef LIGHT_PLATFORM_WINDOWS
#include <renderer/dx/graphics_context.hpp>
#include <renderer/dx/shared_context.hpp>
#endif
namespace lt {
GraphicsContext *GraphicsContext::s_context = nullptr;
GraphicsContext::~GraphicsContext() = default;
auto GraphicsContext::create(GraphicsAPI api) -> Scope<GraphicsContext>
{
delete s_context;
if (api == GraphicsAPI::Default)
{
#if defined(LIGHT_PLATFORM_WINDOWS)
api = GraphicsAPI::DirectX;
#elif defined(LIGHT_PLATFORM_LINUX)
api = GraphicsAPI::OpenGL;
#elif defined(LIGHT_PLATFORM_MAC)
api = GraphicsAPI::OpenGL;
#endif
}
auto scope_gfx = Scope<GraphicsContext> {};
switch (api)
{
// opengl
case GraphicsAPI::OpenGL:
scope_gfx = create_scope<glGraphicsContext>(window_handle);
s_context = scope_gfx.get();
break;
// directx
case GraphicsAPI::DirectX:
lt_win(
scope_gfx = create_scope<dxGraphicsContext>(window_handle); s_context = scope_gfx.get();
break;
)
default
: ensure(
false,
"Invalid/unsupported 'GraphicsAPI' {}",
// TODO(Light): Stringifier::graphics_api_to_string(api),
"TODO"
);
return nullptr;
}
return std::move(scope_gfx);
}
} // namespace lt

View file

@ -1,71 +0,0 @@
#include <camera/camera.hpp>
#include <renderer/buffers.hpp>
#include <renderer/programs/quad.hpp>
#include <renderer/shader.hpp>
#include <renderer/vertex_layout.hpp>
namespace lt {
QuadRendererProgram::QuadRendererProgram(
unsigned int max_vertices,
const Ref<SharedContext> &shared_context,
Ref<Shader> shader
)
: m_index_buffer(nullptr)
, m_vertex_layout(nullptr)
, m_max_vertices(max_vertices)
, m_shader(std::move(shader))
{
m_vertex_buffer = Ref<VertexBuffer>(
VertexBuffer::create(nullptr, sizeof(QuadVertexData), max_vertices, shared_context)
);
m_index_buffer = Ref<IndexBuffer>(
IndexBuffer::create(nullptr, (max_vertices / 4) * 6, shared_context)
);
m_vertex_layout = Ref<VertexLayout>(VertexLayout::create(
m_vertex_buffer,
m_shader,
{ { "POSITION", VertexElementType::Float4 }, { "COLOR", VertexElementType::Float4 } },
shared_context
));
}
auto QuadRendererProgram::advance() -> bool
{
m_idx += 4;
if (m_idx >= m_map.size())
{
log_wrn("'VertexBuffer' map went beyond 'MaxVertices': {}", m_max_vertices);
return false;
}
m_quad_count++;
return true;
}
void QuadRendererProgram::map()
{
m_map = std::span<QuadVertexData> {
static_cast<QuadRendererProgram::QuadVertexData *>(m_vertex_buffer->map()),
m_max_vertices,
};
m_quad_count = 0u;
m_idx = {};
}
void QuadRendererProgram::un_map()
{
m_vertex_buffer->un_map();
m_idx = {};
}
void QuadRendererProgram::bind()
{
m_shader->bind();
m_vertex_layout->bind();
m_vertex_buffer->bind();
m_index_buffer->bind();
}
} // namespace lt

View file

@ -1,74 +0,0 @@
#pragma once
#include <math/vec4.hpp>
#include <renderer/programs/renderer_program.hpp>
namespace lt {
class Shader;
class VertexBuffer;
class IndexBuffer;
class VertexLayout;
class OrthographicCamera;
class SharedContext;
class Shader;
class QuadRendererProgram: RendererProgram
{
public:
~QuadRendererProgram() override = default;
struct QuadVertexData
{
math::vec4 position;
math::vec4 tint;
};
QuadRendererProgram(
unsigned int max_vertices,
const Ref<SharedContext> &shared_context,
Ref<Shader> shader
);
auto advance() -> bool;
void map() override;
void un_map() override;
void bind() override;
auto get_map_current() -> QuadVertexData *
{
return &m_map[m_idx];
}
[[nodiscard]] auto get_quad_count() const -> unsigned int
{
return m_quad_count;
}
[[nodiscard]] constexpr auto get_vertex_size() const -> unsigned int
{
return sizeof(QuadVertexData);
}
private:
Ref<Shader> m_shader;
Ref<VertexBuffer> m_vertex_buffer;
Ref<IndexBuffer> m_index_buffer;
Ref<VertexLayout> m_vertex_layout;
std::span<QuadVertexData> m_map;
size_t m_idx {};
unsigned int m_quad_count = 0u;
unsigned int m_max_vertices = 0u;
};
} // namespace lt

View file

@ -1,17 +0,0 @@
#pragma once
namespace lt {
class RendererProgram
{
virtual void map() = 0;
virtual void un_map() = 0;
virtual void bind() = 0;
public:
virtual ~RendererProgram() = default;
};
} // namespace lt

View file

@ -1,94 +0,0 @@
#include <camera/camera.hpp>
#include <renderer/buffers.hpp>
#include <renderer/programs/texture.hpp>
#include <renderer/shader.hpp>
#include <renderer/vertex_layout.hpp>
namespace lt {
TextureRendererProgram::TextureRendererProgram(
unsigned int max_vertices,
const Ref<SharedContext> &shared_context,
Ref<Shader> shader
)
: m_shader(std::move(shader))
, m_index_buffer(nullptr)
, m_vertex_layout(nullptr)
, m_max_vertices(max_vertices)
{
// #todo: don't use relative path
// AssetManager::load_shader(
// "LT_ENGINE_RESOURCES_TEXTURE_SHADER",
// "data/assets/shaders/texture/vs.asset",
// "data/assets/shaders/texture/ps.asset"
// );
//
// AssetManager::load_shader(
// "LT_ENGINE_RESOURCES_TINTED_TEXTURE_SHADER",
// "data/assets/shaders/tinted_texture/vs.asset",
// "data/assets/shaders/tinted_texture/ps.asset"
// );
//
// AssetManager::load_shader(
// "LT_ENGINE_RESOURCES_QUAD_SHADER",
// "data/assets/shaders/quads/vs.asset",
// "data/assets/shaders/quads/ps.asset"
// );
//
// m_shader = AssetManager::get_shader("LT_ENGINE_RESOURCES_TEXTURE_SHADER");
// m_shader = AssetManager::get_shader("LT_ENGINE_RESOURCES_TINTED_TEXTURE_SHADER");
// m_shader = AssetManager::get_shader("LT_ENGINE_RESOURCES_QUAD_SHADER");
m_vertex_buffer = Ref<VertexBuffer>(
VertexBuffer::create(nullptr, sizeof(TextureVertexData), max_vertices, shared_context)
);
m_index_buffer = Ref<IndexBuffer>(
IndexBuffer::create(nullptr, (max_vertices / 4) * 6, shared_context)
);
m_vertex_layout = Ref<VertexLayout>(VertexLayout::create(
m_vertex_buffer,
m_shader,
{ { "POSITION", VertexElementType::Float4 }, { "TEXCOORD", VertexElementType::Float2 } },
shared_context
));
}
auto TextureRendererProgram::advance() -> bool
{
m_idx += 4;
if (m_idx >= m_map.size())
{
log_wrn("'VertexBuffer' map went beyond 'MaxVertices': {}", m_max_vertices);
return false;
}
m_quad_count++;
return true;
}
void TextureRendererProgram::map()
{
m_map = std::span<TextureVertexData> {
static_cast<TextureVertexData *>(m_vertex_buffer->map()),
m_max_vertices,
};
m_quad_count = 0u;
m_idx = {};
}
void TextureRendererProgram::un_map()
{
m_vertex_buffer->un_map();
}
void TextureRendererProgram::bind()
{
m_shader->bind();
m_vertex_layout->bind();
m_vertex_buffer->bind();
m_index_buffer->bind();
}
} // namespace lt

View file

@ -1,75 +0,0 @@
#pragma once
#include <math/vec2.hpp>
#include <math/vec4.hpp>
#include <renderer/programs/renderer_program.hpp>
namespace lt {
class Shader;
class VertexBuffer;
class IndexBuffer;
class VertexLayout;
class OrthographicCamera;
class SharedContext;
class TextureRendererProgram: RendererProgram
{
public:
~TextureRendererProgram() override = default;
struct TextureVertexData
{
math::vec4 position;
math::vec2 texcoord;
};
TextureRendererProgram(
unsigned int max_vertices,
const Ref<SharedContext> &shared_context,
Ref<Shader> shader
);
auto advance() -> bool;
void map() override;
void un_map() override;
void bind() override;
auto get_map_current() -> TextureVertexData *
{
return &m_map[m_idx];
}
[[nodiscard]] auto get_quad_count() const -> unsigned int
{
return m_quad_count;
}
[[nodiscard]] constexpr auto get_vertex_size() const -> unsigned int
{
return sizeof(TextureVertexData);
}
private:
Ref<Shader> m_shader;
Ref<VertexBuffer> m_vertex_buffer;
Ref<IndexBuffer> m_index_buffer;
Ref<VertexLayout> m_vertex_layout;
std::span<TextureVertexData> m_map;
size_t m_idx {};
unsigned int m_quad_count { 0u };
unsigned int m_max_vertices;
};
} // namespace lt

View file

@ -1,73 +0,0 @@
#include <camera/camera.hpp>
#include <renderer/buffers.hpp>
#include <renderer/programs/tinted_texture.hpp>
#include <renderer/shader.hpp>
#include <renderer/vertex_layout.hpp>
namespace lt {
TintedTextureRendererProgram::TintedTextureRendererProgram(
unsigned int max_vertices,
const Ref<SharedContext> &shared_context,
Ref<Shader> shader
)
: m_shader(std::move(shader))
, m_index_buffer(nullptr)
, m_vertex_layout(nullptr)
, m_max_vertices(max_vertices)
{
m_vertex_buffer = Ref<VertexBuffer>(
VertexBuffer::create(nullptr, sizeof(TintedTextureVertexData), max_vertices, shared_context)
);
m_index_buffer = Ref<IndexBuffer>(
IndexBuffer::create(nullptr, (max_vertices / 4) * 6, shared_context)
);
m_vertex_layout = Ref<VertexLayout>(VertexLayout::create(
m_vertex_buffer,
m_shader,
{ { "POSITION", VertexElementType::Float4 },
{ "TINT", VertexElementType::Float4 },
{ "TEXCOORD", VertexElementType::Float2 } },
shared_context
));
}
auto TintedTextureRendererProgram::advance() -> bool
{
m_idx += 4;
if (m_idx >= m_map.size())
{
log_wrn("'VertexBuffer' map went beyond 'MaxVertices': {}", m_max_vertices);
return false;
}
m_quad_count++;
return true;
}
void TintedTextureRendererProgram::map()
{
m_map = std::span<TintedTextureVertexData> {
static_cast<TintedTextureVertexData *>(m_vertex_buffer->map()),
m_max_vertices,
};
m_quad_count = 0u;
m_idx = {};
}
void TintedTextureRendererProgram::un_map()
{
m_vertex_buffer->un_map();
}
void TintedTextureRendererProgram::bind()
{
m_shader->bind();
m_vertex_layout->bind();
m_vertex_buffer->bind();
m_index_buffer->bind();
}
} // namespace lt

View file

@ -1,77 +0,0 @@
#pragma once
#include <math/vec2.hpp>
#include <math/vec4.hpp>
#include <renderer/programs/renderer_program.hpp>
#include <span>
namespace lt {
class Shader;
class VertexBuffer;
class IndexBuffer;
class VertexLayout;
class OrthographicCamera;
class SharedContext;
class TintedTextureRendererProgram: RendererProgram
{
public:
~TintedTextureRendererProgram() override = default;
struct TintedTextureVertexData
{
math::vec4 position;
math::vec4 tint;
math::vec2 texcoord;
};
TintedTextureRendererProgram(
unsigned int max_vertices,
const Ref<SharedContext> &shared_context,
Ref<Shader> shader
);
auto advance() -> bool;
void map() override;
void un_map() override;
void bind() override;
auto get_map_current() -> TintedTextureVertexData *
{
return &m_map[m_idx];
}
[[nodiscard]] auto get_quad_count() const -> unsigned int
{
return m_quad_count;
}
[[nodiscard]] constexpr auto get_vertex_size() const -> unsigned int
{
return sizeof(TintedTextureVertexData);
}
private:
Ref<Shader> m_shader;
Ref<VertexBuffer> m_vertex_buffer;
Ref<IndexBuffer> m_index_buffer;
Ref<VertexLayout> m_vertex_layout;
std::span<TintedTextureVertexData> m_map;
size_t m_idx {};
unsigned int m_quad_count { 0u };
unsigned int m_max_vertices;
};
} // namespace lt

View file

@ -1,37 +0,0 @@
#include <lt_debug/assertions.hpp>
#include <renderer/gl/render_command.hpp>
#include <renderer/render_command.hpp>
#ifdef LIGHT_PLATFORM_WINDOWS
#include <renderer/dx/render_command.hpp>
#include <renderer/dx/shared_context.hpp>
#endif
#include <renderer/graphics_context.hpp>
namespace lt {
auto RenderCommand::create(const Ref<SharedContext> & /*sharedContext*/) -> Scope<RenderCommand>
{
switch (GraphicsContext::get_graphics_api())
{
case GraphicsAPI::OpenGL: return create_scope<glRenderCommand>();
case GraphicsAPI::DirectX:
lt_win(
return create_scope<dxRenderCommand>(
(std::static_pointer_cast<dxSharedContext>)(sharedContext)
);
)
default
: ensure(
false,
"Invalid/unsupported 'GraphicsAPI' {}",
static_cast<uint32_t>(GraphicsContext::get_graphics_api())
);
return nullptr;
}
}
} // namespace lt

View file

@ -1,330 +0,0 @@
#include <ecs/registry.hpp>
#include <input/events/window.hpp>
#include <lt_debug/assertions.hpp>
#include <renderer/blender.hpp>
#include <renderer/buffers.hpp>
#include <renderer/framebuffer.hpp>
#include <renderer/programs/quad.hpp>
#include <renderer/programs/texture.hpp>
#include <renderer/programs/tinted_texture.hpp>
#include <renderer/render_command.hpp>
#include <renderer/renderer.hpp>
#include <renderer/shader.hpp>
#include <renderer/texture.hpp>
namespace lt {
Renderer *Renderer::s_context = nullptr;
Renderer::Renderer(const Ref<SharedContext> &shared_context, CreateInfo create_info)
: m_quad_renderer(
create_scope<QuadRendererProgram>(
LT_MAX_QUAD_RENDERER_VERTICES,
shared_context,
std::move(create_info.quad_renderer_shader)
)
)
, m_texture_renderer(
create_scope<TextureRendererProgram>(
LT_MAX_TEXTURE_RENDERER_VERTICES,
shared_context,
std::move(create_info.texture_renderer_shader)
)
)
, m_tinted_texture_renderer(
create_scope<TintedTextureRendererProgram>(
LT_MAX_TINTED_TEXTURE_RENDERER_VERTICES,
shared_context,
std::move(create_info.tinted_texture_renderer_shader)
)
)
, m_view_projection_buffer(nullptr)
, m_render_command(nullptr)
, m_blender(nullptr)
, m_target_framebuffer(nullptr)
{
ensure(!s_context, "An instance of 'renderer' already exists, do not construct this class!");
s_context = this;
m_view_projection_buffer = ConstantBuffer::create(
ConstantBufferIndex::ViewProjection,
sizeof(math::mat4),
shared_context
);
m_render_command = RenderCommand::create(window_handle, shared_context);
m_blender = Blender::create(shared_context);
m_blender->enable(BlendFactor::SRC_ALPHA, BlendFactor::INVERSE_SRC_ALPHA);
}
Renderer::~Renderer() // NOLINT
{
}
auto Renderer::create(Ref<SharedContext> sharedContext, CreateInfo create_info) -> Scope<Renderer>
{
return make_scope<Renderer>(new Renderer(std::move(sharedContext), std::move(create_info)));
}
void Renderer::on_window_resize(const WindowResizedEvent &event)
{
m_render_command->set_viewport(0u, 0u, event.get_size().x, event.get_size().y);
}
//======================================== DRAW_QUAD ========================================//
/* tinted textures */
void Renderer::draw_quad_impl(
const math::vec3 &position,
const math::vec2 &size,
const math::vec4 &tint,
Ref<Texture> texture
)
{
draw_quad(
math::translate(position) * math::scale(math::vec3 { size.x, size.y, 1.0f }),
tint,
texture
);
}
/* tint */
void Renderer::draw_quad_impl(
const math::vec3 &position,
const math::vec2 &size,
const math::vec4 &tint
)
{
draw_quad(math::translate(position) * math::scale(math::vec3 { size.x, size.y, 1.0f }), tint);
}
/* texture */
void Renderer::draw_quad_impl(
const math::vec3 &position,
const math::vec2 &size,
Ref<Texture> texture
)
{
draw_quad(
math::translate(position) * math::scale(math::vec3 { size.x, size.y, 1.0f }),
texture
);
}
//======================================== DRAW_QUAD ========================================//
//==================== DRAW_QUAD_TINT ====================//
void Renderer::draw_quad_impl(const math::mat4 &transform, const math::vec4 &tint)
{
auto map = std::span<QuadRendererProgram::QuadVertexData> { m_quad_renderer->get_map_current(),
4 };
// top left
map[0].position = transform * math::vec4(-0.5f, -0.5f, 0.0f, 1.0f);
map[0].tint = tint;
// top right
map[1].position = transform * math::vec4(0.5f, -0.5f, 0.0f, 1.0f);
map[1].tint = tint;
// bottom right
map[2].position = transform * math::vec4(0.5f, 0.5f, 0.0f, 1.0f);
map[2].tint = tint;
// bottom left
map[3].position = transform * math::vec4(-0.5f, 0.5f, 0.0f, 1.0f);
map[3].tint = tint;
// advance
if (!m_quad_renderer->advance())
{
log_wrn("Exceeded LT_MAX_QUAD_RENDERER_VERTICES: {}", LT_MAX_QUAD_RENDERER_VERTICES);
flush_scene();
}
}
void Renderer::draw_quad_impl(const math::mat4 &transform, const Ref<Texture> &texture)
{
ensure(texture, "Texture passed to renderer::draw_quad_impl");
texture->bind();
auto map = std::span<TextureRendererProgram::TextureVertexData> {
m_texture_renderer->get_map_current(),
4
};
// top left
map[0].position = transform * math::vec4(-0.5f, -0.5f, 0.0f, 1.0f);
map[0].texcoord = { 0.0f, 0.0f };
// top right
map[1].position = transform * math::vec4(0.5f, -0.5f, 0.0f, 1.0f);
map[1].texcoord = { 1.0f, 0.0f };
// bottom right
map[2].position = transform * math::vec4(0.5f, 0.5f, 0.0f, 1.0f);
map[2].texcoord = { 1.0f, 1.0f };
// bottom left
map[3].position = transform * math::vec4(-0.5f, 0.5f, 0.0f, 1.0f);
map[3].texcoord = { 0.0f, 1.0f };
// advance
if (!m_texture_renderer->advance())
{
log_wrn("Exceeded LT_MAX_TEXTURE_RENDERER_VERTICES: {}", LT_MAX_TEXTURE_RENDERER_VERTICES);
flush_scene();
}
}
void Renderer::draw_quad_impl(
const math::mat4 &transform,
const math::vec4 &tint,
const Ref<Texture> &texture
)
{
ensure(texture, "Texture passed to renderer::draw_quad_impl");
texture->bind();
auto map = std::span<TintedTextureRendererProgram::TintedTextureVertexData> {
m_tinted_texture_renderer->get_map_current(),
4
};
// top left
map[0].position = transform * math::vec4(-0.5f, -0.5f, 0.0f, 1.0f);
map[0].tint = tint;
map[0].texcoord = { 0.0f, 0.0f };
// top right
map[1].position = transform * math::vec4(0.5f, -0.5f, 0.0f, 1.0f);
map[1].tint = tint;
map[1].texcoord = { 1.0f, 0.0f };
// bottom right
map[2].position = transform * math::vec4(0.5f, 0.5f, 0.0f, 1.0f);
map[2].tint = tint;
map[2].texcoord = { 1.0f, 1.0f };
// bottom left
map[3].position = transform * math::vec4(-0.5f, 0.5f, 0.0f, 1.0f);
map[3].tint = tint;
map[3].texcoord = { 0.0f, 1.0f };
if (!m_tinted_texture_renderer->advance())
{
log_wrn("Exceeded LT_MAX_TEXTURE_RENDERER_VERTICES: {}", LT_MAX_TEXTURE_RENDERER_VERTICES);
flush_scene();
}
}
void Renderer::begin_frame()
{
}
void Renderer::end_frame()
{
m_render_command->swap_buffers();
m_render_command->clear_back_buffer(
m_default_framebuffer_camera ? m_default_framebuffer_camera->get_background_color() :
math::vec4(0.0f)
);
m_default_framebuffer_camera = nullptr;
}
void Renderer::begin_scene_impl(
Camera *camera,
const math::mat4 &cameraTransform,
const Ref<Framebuffer> &targetFrameBuffer /* = nullptr */
)
{
// determine the target frame buffer
m_target_framebuffer = targetFrameBuffer;
if (targetFrameBuffer)
{
targetFrameBuffer->bind_as_target(camera->get_background_color());
}
else
{
m_default_framebuffer_camera = camera;
m_render_command->default_target_framebuffer();
}
// update view projection buffer
auto *map = (math::mat4 *)m_view_projection_buffer->map();
map[0] = camera->get_projection() * math::inverse(cameraTransform);
m_view_projection_buffer->un_map();
// map renderers
m_quad_renderer->map();
m_texture_renderer->map();
m_tinted_texture_renderer->map();
}
void Renderer::flush_scene()
{
/* tinted texture renderer */
m_tinted_texture_renderer->un_map();
if (m_tinted_texture_renderer->get_quad_count())
{
m_tinted_texture_renderer->bind();
m_render_command->draw_indexed(m_tinted_texture_renderer->get_quad_count() * 6u);
}
/* quad renderer */
m_quad_renderer->un_map();
if (m_quad_renderer->get_quad_count())
{
m_quad_renderer->bind();
m_render_command->draw_indexed(m_quad_renderer->get_quad_count() * 6u);
}
/* texture renderer */
m_texture_renderer->un_map();
if (m_texture_renderer->get_quad_count())
{
m_texture_renderer->bind();
m_render_command->draw_indexed(m_texture_renderer->get_quad_count() * 6u);
}
m_quad_renderer->map();
m_texture_renderer->map();
m_tinted_texture_renderer->map();
}
void Renderer::end_scene_impl()
{
/* tinted texture renderer */
m_tinted_texture_renderer->un_map();
if (m_tinted_texture_renderer->get_quad_count())
{
m_tinted_texture_renderer->bind();
m_render_command->draw_indexed(m_tinted_texture_renderer->get_quad_count() * 6u);
}
/* quad renderer */
m_quad_renderer->un_map();
if (m_quad_renderer->get_quad_count())
{
m_quad_renderer->bind();
m_render_command->draw_indexed(m_quad_renderer->get_quad_count() * 6u);
}
/* texture renderer */
m_texture_renderer->un_map();
if (m_texture_renderer->get_quad_count())
{
m_texture_renderer->bind();
m_render_command->draw_indexed(m_texture_renderer->get_quad_count() * 6u);
}
// reset frame buffer
if (m_target_framebuffer)
{
m_target_framebuffer = nullptr;
m_render_command->default_target_framebuffer();
}
}
} // namespace lt

View file

@ -1,47 +0,0 @@
#include <asset_parser/assets/text.hpp>
#include <renderer/gl/shader.hpp>
#include <renderer/shader.hpp>
#ifdef LIGHT_PLATFORM_WINDOWS
#include <renderer/dx/shader.hpp>
#include <renderer/dx/shared_context.hpp>
#endif
#include <renderer/graphics_context.hpp>
namespace lt {
/* static */ auto Shader::create(
const Ref<Assets::TextAsset> &vertex_asset,
const Ref<Assets::TextAsset> &pixel_asset,
const Ref<SharedContext> &shared_context
) -> Ref<Shader>
{
std::ignore = shared_context;
// load shader source
switch (GraphicsContext::get_graphics_api())
{
case GraphicsAPI::OpenGL:
return create_ref<glShader>(std::move(vertex_asset), std::move(pixel_asset));
case GraphicsAPI::DirectX:
lt_win(
return create_ref<dxShader>(
vertex_asset,
pixel_asset,
std::static_pointer_cast<dxSharedContext>(sharedContext)
);
);
default:
ensure(
false,
"Invalid/unsupported 'GraphicsAPI' {}",
static_cast<uint32_t>(GraphicsContext::get_graphics_api())
);
return nullptr;
}
}
} // namespace lt

View file

@ -1,17 +0,0 @@
#include <lt_debug/assertions.hpp>
#include <renderer/system.hpp>
namespace lt::renderer {
System::System(InitRequirements requirements): m_registry(std::move(requirements.registry))
{
ensure(m_registry, "null registry");
}
System::~System() = default;
void System::tick(TickRequirements requirements)
{
}
} // namespace lt::renderer

View file

@ -1,44 +0,0 @@
#include <ranges>
#include <renderer/system.hpp>
#include <test/test.hpp>
#include <window/window.hpp>
using namespace lt;
using lt::test::Case;
using lt::test::Suite;
Suite raii = [] {
using lt::test::expect_true;
using lt::test::expect_throw;
using renderer::System;
Case { "happy" } = [=] {
std::ignore = System { {
.registry = create_ref<ecs::Registry>(),
} };
};
Case { "unhappy" } = [=] {
expect_throw([=] {
std::ignore = System { {
.registry = {},
} };
});
expect_throw([=] {
std::ignore = System { {
.registry = create_ref<ecs::Registry>(),
} };
});
};
Case { "plenty" } = [=] {
for (auto idx : std::views::iota(0, 100'001))
{
std::ignore = System { {
.registry = create_ref<ecs::Registry>(),
} };
}
};
};

View file

@ -1,45 +0,0 @@
#include <logger/logger.hpp>
#include <renderer/gl/texture.hpp>
#include <renderer/texture.hpp>
#ifdef LIGHT_PLATFORM_WINDOWS
#include <renderer/dx/shared_context.hpp>
#include <renderer/dx/texture.hpp>
#endif
#include <renderer/graphics_context.hpp>
namespace lt {
/* static */ auto Texture::create(
const Ref<Assets::TextureAsset> &asset,
const Ref<SharedContext> & /*shared_context*/
) -> Ref<Texture>
{
switch (GraphicsContext::get_graphics_api())
{
case GraphicsAPI::OpenGL: return create_ref<glTexture>(std::move(asset));
case GraphicsAPI::DirectX:
lt_win(
return create_ref<dxTexture>(
width,
height,
components,
pixels,
std::static_pointer_cast<dxSharedContext>(sharedContext),
filePath
);
)
default
: ensure(
false,
"Invalid/unsupported 'GraphicsAPI' {}",
static_cast<uint32_t>(GraphicsContext::get_graphics_api())
);
return nullptr;
}
}
} // namespace lt

View file

@ -1,44 +0,0 @@
#include <lt_debug/assertions.hpp>
#include <renderer/gl/vertex_layout.hpp>
#include <renderer/vertex_layout.hpp>
#ifdef LIGHT_PLATFORM_WINDOWS
#include <renderer/dx/shared_context.hpp>
#include <renderer/dx/vertex_layout.hpp>
#endif
#include <renderer/graphics_context.hpp>
namespace lt {
auto VertexLayout::create(
const Ref<VertexBuffer> &vertexBuffer,
const Ref<Shader> & /*shader*/,
const std::vector<std::pair<std::string, VertexElementType>> &elements,
const Ref<SharedContext> & /*sharedContext*/
) -> Ref<VertexLayout>
{
switch (GraphicsContext::get_graphics_api())
{
case GraphicsAPI::OpenGL: return create_ref<glVertexLayout>(vertexBuffer, elements);
case GraphicsAPI::DirectX:
lt_win(
return create_ref<dxVertexLayout>(
shader,
elements,
std::static_pointer_cast<dxSharedContext>(sharedContext)
);
)
default
: ensure(
false,
"Invalid/unsupported 'GraphicsAPI' {}",
static_cast<uint32_t>(GraphicsContext::get_graphics_api())
);
return nullptr;
}
}
} // namespace lt

View file

@ -1,5 +0,0 @@
#include <renderer/vk/instance.hpp>
namespace lt::vk {
}

View file

@ -1,19 +0,0 @@
#pragma once
#include <vulkan/vulkan.h>
#include <vulkan/vulkan.hpp>
namespace lt::vk {
class Instance
{
public:
Instance()
{
}
private:
::vk::Instance m_instace;
};
} // namespace lt::vk

View file

@ -1,8 +0,0 @@
#include <renderer/vk/instance.hpp>
#include <test/test.hpp>
lt::test::Suite raii = [] {
lt::test::Case { "raii" } = [] {
auto instance = lt::vk::Instance {};
};
};

View file

@ -1,29 +0,0 @@
#pragma once
namespace lt::renderer {
class Backend
{
public:
enum class API : uint8_t
{
vulkan,
directx,
};
Backend() = default;
Backend(Backend &&) = default;
auto operator=(Backend &&) -> Backend & = default;
Backend(const Backend &) = delete;
auto operator=(const Backend &) -> Backend & = delete;
virtual ~Backend() = default;
[[nodiscard]] virtual auto get_api() const -> API = 0;
};
} // namespace lt::renderer

View file

@ -1,50 +0,0 @@
#pragma once
namespace lt {
class SharedContext;
enum class BlendFactor : uint8_t
{
// constants
ZERO,
ONE,
// source
SRC_COLOR,
INVERSE_SRC_COLOR,
SRC_ALPHA,
INVERSE_SRC_ALPHA,
// destination
DST_COLOR,
INVERSE_DST_COLOR,
DST_ALPHA,
INVERSE_DST_ALPHA,
// source1
SRC1_COLOR,
INVERSE_SRC1_COLOR,
SRC1_ALPHA,
INVERSE_SRC1_ALPHA,
};
class Blender
{
public:
virtual ~Blender() = default;
static auto create(const Ref<SharedContext> &sharedContext) -> Scope<Blender>;
virtual void enable(BlendFactor srcFactor, BlendFactor dstFactor) = 0;
virtual void disable() = 0;
protected:
Blender() = default;
};
} // namespace lt

View file

@ -1,76 +0,0 @@
#pragma once
namespace lt {
class SharedContext;
enum class ConstantBufferIndex
{
ViewProjection = 0u
};
class ConstantBuffer
{
public:
virtual ~ConstantBuffer() = default;
static auto create(
ConstantBufferIndex index,
unsigned int size,
const Ref<SharedContext> &sharedContext
) -> Scope<ConstantBuffer>;
virtual auto map() -> void * = 0;
virtual void un_map() = 0;
virtual void bind() = 0;
protected:
ConstantBuffer() = default;
};
class VertexBuffer
{
public:
static auto create(
float *vertices,
unsigned int stride,
unsigned int count,
const Ref<SharedContext> &sharedContext
) -> Ref<VertexBuffer>;
virtual ~VertexBuffer() = default;
virtual auto map() -> void * = 0;
virtual void un_map() = 0;
virtual void bind() = 0;
virtual void un_bind() = 0;
protected:
VertexBuffer() = default;
};
class IndexBuffer
{
public:
static auto create(
unsigned int *indices,
unsigned int count,
const Ref<SharedContext> &sharedContext
) -> Ref<IndexBuffer>;
virtual ~IndexBuffer() = default;
virtual void bind() = 0;
virtual void un_bind() = 0;
protected:
IndexBuffer() = default;
};
} // namespace lt

View file

@ -1,12 +0,0 @@
#pragma once
namespace lt::renderer {
/** Requires a Transform Component
* @todo(Light): Figure out how to enforce a component requirement list for a component
*/
struct RendererComponent
{
};
} // namespace lt::renderer

View file

@ -1,9 +0,0 @@
#pragma once
namespace lt::renderer {
class Context
{
};
} // namespace lt::renderer

View file

@ -1,40 +0,0 @@
#pragma once
#include <math/vec2.hpp>
#include <math/vec4.hpp>
namespace lt {
class SharedContext;
struct FramebufferSpecification
{
unsigned int width {};
unsigned int height {};
unsigned int samples = 1;
};
class Framebuffer
{
public:
virtual ~Framebuffer() = default;
static auto create(
const FramebufferSpecification &specification,
const Ref<SharedContext> &sharedContext
) -> Ref<Framebuffer>;
virtual void bind_as_target(const math::vec4 &clearColor) = 0;
virtual void bind_as_resource() = 0;
virtual void resize(const math::uvec2 &size) = 0;
virtual auto get_color_attachment() -> void * = 0;
protected:
Framebuffer() = default;
};
} // namespace lt

View file

@ -1,50 +0,0 @@
#pragma once
namespace lt {
class SharedContext;
class WindowResizedEvent;
enum class GraphicsAPI
{
Default = 0,
OpenGL,
DirectX,
Vulkan,
Metal
};
class GraphicsContext
{
public:
static auto create(GraphicsAPI api) -> Scope<GraphicsContext>;
GraphicsContext(const GraphicsContext &) = delete;
GraphicsContext &operator=(const GraphicsContext &) = delete;
virtual ~GraphicsContext();
virtual void log_debug_data() = 0;
static GraphicsAPI get_graphics_api()
{
return s_context->m_graphics_api;
}
static Ref<SharedContext> get_shared_context()
{
return s_context->m_shared_context;
}
protected:
GraphicsContext() = default;
GraphicsAPI m_graphics_api;
Ref<SharedContext> m_shared_context = nullptr;
private:
static GraphicsContext *s_context;
};
} // namespace lt

View file

@ -1,41 +0,0 @@
#pragma once
#include <math/vec4.hpp>
namespace lt {
class SharedContext;
class RenderCommand
{
public:
static auto create(const Ref<SharedContext> &sharedContext) -> Scope<RenderCommand>;
RenderCommand(const RenderCommand &) = delete;
auto operator=(const RenderCommand &) -> RenderCommand & = delete;
virtual ~RenderCommand() = default;
virtual void swap_buffers() = 0;
virtual void clear_back_buffer(const math::vec4 &clearColor) = 0;
virtual void draw(unsigned int count) = 0;
virtual void draw_indexed(unsigned int count) = 0;
virtual void default_target_framebuffer() = 0;
virtual void set_viewport(
unsigned int x,
unsigned int y,
unsigned int width,
unsigned int height
) = 0;
protected:
RenderCommand() = default;
};
} // namespace lt

View file

@ -1,165 +0,0 @@
#pragma once
#include <math/mat4.hpp>
#include <math/vec3.hpp>
#include <math/vec4.hpp>
#include <renderer/blender.hpp>
#include <renderer/buffers.hpp>
#include <renderer/render_command.hpp>
#include <renderer/renderer.hpp>
#include <utility>
#define LT_MAX_QUAD_RENDERER_VERTICES (1028u * 4u)
#define LT_MAX_TEXTURE_RENDERER_VERTICES (1028u * 4u)
#define LT_MAX_TINTED_TEXTURE_RENDERER_VERTICES (1028u * 4u)
namespace lt {
class ConstantBuffer;
class Framebuffer;
class RenderCommand;
class Texture;
class SharedContext;
class Camera;
class WindowResizedEvent;
class Shader;
class TintedTextureRendererProgram;
class QuadRendererProgram;
class TextureRendererProgram;
class Renderer
{
public:
struct CreateInfo
{
Ref<Shader> quad_renderer_shader;
Ref<Shader> texture_renderer_shader;
Ref<Shader> tinted_texture_renderer_shader;
};
static auto create(Ref<SharedContext> sharedContext, CreateInfo create_info) -> Scope<Renderer>;
static void draw_quad(
const math::vec3 &position,
const math::vec2 &size,
const math::vec4 &tint,
Ref<Texture> texture
)
{
s_context->draw_quad_impl(position, size, tint, std::move(texture));
}
static void draw_quad(
const math::vec3 &position,
const math::vec2 &size,
const math::vec4 &tint
)
{
s_context->draw_quad_impl(position, size, tint);
}
static void draw_quad(const math::vec3 &position, const math::vec2 &size, Ref<Texture> texture)
{
s_context->draw_quad_impl(position, size, std::move(texture));
}
static void draw_quad(
const math::mat4 &transform,
const math::vec4 &tint,
const Ref<Texture> &texture
)
{
s_context->draw_quad_impl(transform, tint, texture);
}
static void draw_quad(const math::mat4 &transform, const math::vec4 &tint)
{
s_context->draw_quad_impl(transform, tint);
}
static void draw_quad(const math::mat4 &transform, const Ref<Texture> &texture)
{
s_context->draw_quad_impl(transform, texture);
}
static void begin_scene(
Camera *camera,
const math::mat4 &cameraTransform,
const Ref<Framebuffer> &targetFrameBuffer = nullptr
)
{
s_context->begin_scene_impl(camera, cameraTransform, targetFrameBuffer);
}
static void end_scene()
{
s_context->end_scene_impl();
}
~Renderer();
void on_window_resize(const WindowResizedEvent &event);
void begin_frame();
void end_frame();
private:
static Renderer *s_context;
Scope<QuadRendererProgram> m_quad_renderer;
Scope<TextureRendererProgram> m_texture_renderer;
Scope<TintedTextureRendererProgram> m_tinted_texture_renderer;
Scope<ConstantBuffer> m_view_projection_buffer;
Scope<RenderCommand> m_render_command;
Scope<Blender> m_blender;
Camera *m_default_framebuffer_camera { nullptr };
Ref<Framebuffer> m_target_framebuffer;
bool m_should_clear_backbuffer { false };
Renderer(const Ref<SharedContext> &shared_context, CreateInfo create_info);
void draw_quad_impl(
const math::vec3 &position,
const math::vec2 &size,
const math::vec4 &tint,
Ref<Texture> texture
);
void draw_quad_impl(const math::vec3 &position, const math::vec2 &size, const math::vec4 &tint);
void draw_quad_impl(const math::vec3 &position, const math::vec2 &size, Ref<Texture> texture);
void draw_quad_impl(
const math::mat4 &transform,
const math::vec4 &tint,
const Ref<Texture> &texture
);
void draw_quad_impl(const math::mat4 &transform, const math::vec4 &tint);
void draw_quad_impl(const math::mat4 &transform, const Ref<Texture> &texture);
void begin_scene_impl(
Camera *camera,
const math::mat4 &cameraTransform,
const Ref<Framebuffer> &targetFrameBuffer = nullptr
);
void flush_scene();
void end_scene_impl();
};
} // namespace lt

View file

@ -1,41 +0,0 @@
#pragma once
namespace Assets {
class TextAsset;
} // namespace Assets
namespace lt {
class SharedContext;
class Shader
{
public:
enum Stage : uint8_t
{
none = 0,
vertex,
pixel,
geometry,
};
static auto create(
const Ref<Assets::TextAsset> &vertex_asset,
const Ref<Assets::TextAsset> &pixel_asset,
const Ref<SharedContext> &shared_context
) -> Ref<Shader>;
virtual ~Shader() = default;
virtual void bind() = 0;
virtual void un_bind() = 0;
protected:
Shader() = default;
};
} // namespace lt

View file

@ -1,12 +0,0 @@
#pragma once
namespace lt {
class SharedContext
{
public:
virtual ~SharedContext() = default;
};
} // namespace lt

View file

@ -1,56 +0,0 @@
#pragma once
#include <base/base.hpp>
#include <ecs/registry.hpp>
namespace lt::renderer {
/** The system for putting gore on your display
*
* Exclusively operates on components:
* - RendererComponent
* - PostEffectsComponent
* - UserInterfaceComponent
*
* Requires read acces on components:
* - TransformComponent
*/
class System
{
public:
/** The configurations of this system. */
struct Properties
{
};
/** The requirements for this system to initialize. */
struct InitRequirements
{
Ref<ecs::Registry> registry;
};
/** The requirements for this system to tick. */
struct TickRequirements
{
double delta_time;
};
[[nodiscard]] System(InitRequirements requirements);
System(System &&) = default;
System(const System &) = delete;
auto operator=(System &&) -> System & = default;
auto operator=(const System &) -> System & = delete;
~System();
void tick(TickRequirements requirements);
private:
Ref<ecs::Registry> m_registry;
};
} // namespace lt::renderer

View file

@ -1,38 +0,0 @@
#pragma once
namespace Assets {
class TextureAsset;
}
namespace lt {
class SharedContext;
class Texture
{
public:
static Ref<Texture> create(
const Ref<Assets::TextureAsset> &asset,
const Ref<SharedContext> &shared_context
);
virtual ~Texture() = default;
Texture(Texture &&) = default;
auto operator=(Texture &&) -> Texture & = default;
Texture(const Texture &) = delete;
auto operator=(const Texture &) -> Texture & = delete;
virtual void bind(unsigned int slot = 0) = 0;
virtual auto get_texture() -> void * = 0;
protected:
Texture() = default;
};
} // namespace lt

View file

@ -1,53 +0,0 @@
#pragma once
#include <lt_debug/assertions.hpp>
namespace lt {
class VertexBuffer;
class Shader;
class SharedContext;
enum class VertexElementType
{
Byte1,
Byte2,
Byte4,
UByte1,
UByte2,
UByte4,
Int1,
Int2,
Int3,
Int4,
UInt1,
UInt2,
UInt3,
UInt4,
Float1,
Float2,
Float3,
Float4,
};
class VertexLayout
{
public:
static auto create(
const Ref<VertexBuffer> &vertexBuffer,
const Ref<Shader> &shader,
const std::vector<std::pair<std::string, VertexElementType>> &elements,
const Ref<SharedContext> &sharedContext
) -> Ref<VertexLayout>;
virtual ~VertexLayout() = default;
virtual void bind() = 0;
virtual void un_bind() = 0;
protected:
VertexLayout() = default;
};
} // namespace lt