Adding memory checks and Window Event Listener + Memory Checks (debug) + Listening to window events + Runtime Directory Structure (Vision)
197 lines
5.8 KiB
C++
197 lines
5.8 KiB
C++
#include <cigui/core/App.hpp>
|
|
|
|
#include <iostream>
|
|
#include <LLGL/Utils/VertexFormat.h>
|
|
|
|
|
|
#include <cigui/core/Memory.hpp>
|
|
namespace cig
|
|
{
|
|
App::App() : m_WindowListener(std::make_shared<WindowListener>(*this))
|
|
{
|
|
// Rectangle
|
|
m_Vertices.emplace_back(Vertex{ { 0.5f, -0.5f }, { 0, 255, 0, 255 } });
|
|
m_Vertices.emplace_back(Vertex{ { -0.5f, -0.5f }, { 255, 0, 0, 255 } });
|
|
m_Vertices.emplace_back(Vertex{ { -0.5f, 0.5f }, { 0, 0, 255, 255 } });
|
|
m_Vertices.emplace_back(Vertex{ { 0.5f, 0.5f }, { 255, 0, 0, 255 } });
|
|
m_Vertices.emplace_back(Vertex{ { -0.5f, -0.5f }, { 0, 255, 0, 255 } });
|
|
m_Vertices.emplace_back(Vertex{ { -0.5f, 0.5f }, { 0, 0, 255, 255 } });
|
|
|
|
for (const char* module : { "Direct3D12", "Direct3D11", "Vulkan", "OpenGL" }) {
|
|
LLGL::Report report;
|
|
m_RenderSystem = LLGL::RenderSystem::Load(module, &report);
|
|
if (m_RenderSystem == nullptr) {
|
|
LLGL::Log::Errorf("%s", report.GetText());
|
|
}
|
|
}
|
|
if (m_RenderSystem == nullptr) {
|
|
std::cout << "No renderer found!" << std::endl;
|
|
return;
|
|
}
|
|
|
|
LLGL::SwapChainDescriptor swapChainDesc;
|
|
swapChainDesc.resizable = true;
|
|
swapChainDesc.debugName = "SwapChain";
|
|
swapChainDesc.swapBuffers = 2;
|
|
swapChainDesc.resolution.width = 800;
|
|
swapChainDesc.resolution.height = 600; // Framebuffer resolution of 800x600 pixels
|
|
swapChainDesc.fullscreen = false; // No fullscreen, use windowed mode
|
|
swapChainDesc.samples = 8; // 8 samples for anti-aliasing
|
|
m_SwapChain = m_RenderSystem->CreateSwapChain(swapChainDesc);
|
|
|
|
LLGL::VertexFormat vertexFormat;
|
|
vertexFormat.AppendAttribute({ "position", LLGL::Format::RG32Float });
|
|
vertexFormat.AppendAttribute({ "color", LLGL::Format::RGBA8UNorm });
|
|
|
|
LLGL::BufferDescriptor VBufferDesc;
|
|
VBufferDesc.size = sizeof(Vertex) * m_Vertices.size(); // Size (in bytes) of the buffer
|
|
VBufferDesc.bindFlags = LLGL::BindFlags::VertexBuffer; // Use for vertex buffer binding
|
|
VBufferDesc.vertexAttribs = vertexFormat.attributes; // Vertex buffer attributes
|
|
m_VertexBuffer = m_RenderSystem->CreateBuffer(VBufferDesc, m_Vertices.data());
|
|
|
|
LLGL::ShaderDescriptor VSDesc, FSDesc;
|
|
if (ShaderLanguageIsSupported(LLGL::ShadingLanguage::HLSL)) {
|
|
VSDesc = { LLGL::ShaderType::Vertex, "shader/MyShader.hlsl", "VMain", "vs_4_0" };
|
|
FSDesc = { LLGL::ShaderType::Fragment, "shader/MyShader.hlsl", "PMain", "ps_4_0" };
|
|
} else if (ShaderLanguageIsSupported(LLGL::ShadingLanguage::GLSL)) {
|
|
VSDesc = { LLGL::ShaderType::Vertex, "shader/MyShader.vert" };
|
|
FSDesc = { LLGL::ShaderType::Fragment, "shader/MyShader.frag" };
|
|
} else {
|
|
std::cout << "Shading language not supported!" << std::endl;
|
|
return;
|
|
}
|
|
VSDesc.vertex.inputAttribs = vertexFormat.attributes;
|
|
|
|
m_ShaderPack.first = m_RenderSystem->CreateShader(VSDesc);
|
|
m_ShaderPack.second = m_RenderSystem->CreateShader(FSDesc);
|
|
|
|
for (LLGL::Shader* shader : { m_ShaderPack.first, m_ShaderPack.second }) {
|
|
if (const LLGL::Report* report = shader->GetReport()) {
|
|
if (report->HasErrors()) {
|
|
LLGL::Log::Errorf("Shader compile errors:\n%s", report->GetText());
|
|
} else {
|
|
LLGL::Log::Printf("Shader compile warnings:\n%s", report->GetText());
|
|
}
|
|
}
|
|
}
|
|
|
|
LLGL::GraphicsPipelineDescriptor pipelineDesc;
|
|
pipelineDesc.vertexShader = m_ShaderPack.first;
|
|
pipelineDesc.fragmentShader = m_ShaderPack.second;
|
|
pipelineDesc.primitiveTopology = LLGL::PrimitiveTopology::TriangleList;
|
|
pipelineDesc.rasterizer.multiSampleEnabled = swapChainDesc.samples > 1;
|
|
|
|
m_Pipeline = m_RenderSystem->CreatePipelineState(pipelineDesc);
|
|
|
|
m_CmdBuffer = m_RenderSystem->CreateCommandBuffer(LLGL::CommandBufferFlags::ImmediateSubmit);
|
|
}
|
|
|
|
App::~App()
|
|
{
|
|
}
|
|
|
|
|
|
App::WindowListener::WindowListener(App& app) : m_App(app) {}
|
|
|
|
void App::WindowListener::OnResize(LLGL::Window& sender, const LLGL::Extent2D& clientAreaSize)
|
|
{
|
|
EventListener::OnResize(sender, clientAreaSize);
|
|
m_App.m_SwapChain->ResizeBuffers(clientAreaSize);
|
|
m_App.resized({clientAreaSize.width, clientAreaSize.height});
|
|
m_App.update(true);
|
|
m_App.render();
|
|
}
|
|
|
|
|
|
void App::WindowListener::OnQuit(LLGL::Window& sender, bool& veto)
|
|
{
|
|
EventListener::OnQuit(sender, veto);
|
|
veto = !m_App.save() || veto;
|
|
std::cout << "App: Quit" << std::endl;
|
|
}
|
|
|
|
void App::WindowListener::OnLostFocus(LLGL::Window& sender)
|
|
{
|
|
EventListener::OnLostFocus(sender);
|
|
std::cout << "App: Lost focus" << std::endl;
|
|
}
|
|
|
|
void App::WindowListener::OnGetFocus(LLGL::Window& sender)
|
|
{
|
|
EventListener::OnGetFocus(sender);
|
|
std::cout << "App: Got focus" << std::endl;
|
|
}
|
|
|
|
|
|
bool App::ShaderLanguageIsSupported(LLGL::ShadingLanguage lang) const
|
|
{
|
|
const auto& supportedLangs = m_RenderSystem->GetRenderingCaps().shadingLanguages;
|
|
return std::find(supportedLangs.begin(), supportedLangs.end(), lang) != supportedLangs.end();
|
|
}
|
|
|
|
void App::resized(vec2u size)
|
|
{
|
|
m_WindowSize = size;
|
|
}
|
|
|
|
void App::Initialize(int argc, char** argv)
|
|
{
|
|
|
|
}
|
|
|
|
void App::update(bool force)
|
|
{
|
|
|
|
}
|
|
|
|
void App::render() const
|
|
{
|
|
static LLGL::ClearValue clear_value(.1f,.1f,.1f,1.f);
|
|
|
|
m_CmdBuffer->Begin();
|
|
{
|
|
m_CmdBuffer->SetVertexBuffer(*m_VertexBuffer);
|
|
|
|
m_CmdBuffer->BeginRenderPass(*m_SwapChain);
|
|
{
|
|
m_CmdBuffer->SetViewport(m_SwapChain->GetResolution());
|
|
|
|
m_CmdBuffer->Clear(LLGL::ClearFlags::Color, clear_value);
|
|
|
|
m_CmdBuffer->SetPipelineState(*m_Pipeline);
|
|
|
|
{
|
|
m_CmdBuffer->Draw(static_cast<uint32_t>(m_Vertices.size()), 0);
|
|
}
|
|
}
|
|
m_CmdBuffer->EndRenderPass();
|
|
}
|
|
m_CmdBuffer->End();
|
|
|
|
m_SwapChain->Present();
|
|
}
|
|
|
|
bool App::save() const
|
|
{
|
|
return true;
|
|
}
|
|
|
|
int App::Run()
|
|
{
|
|
if (!m_RenderSystem)
|
|
return -1;
|
|
|
|
m_Window = &LLGL::CastTo<LLGL::Window>(m_SwapChain->GetSurface());
|
|
|
|
m_Window->AddEventListener(m_WindowListener);
|
|
|
|
m_Window->SetTitle("Common Interface GUI");
|
|
m_Window->Show();
|
|
|
|
while (LLGL::Surface::ProcessEvents() && !m_Window->HasQuit()) {
|
|
update();
|
|
render();
|
|
}
|
|
return 0;
|
|
}
|
|
}
|