#include #include #include #include namespace cig { App::App() : m_WindowListener(std::make_shared(*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(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(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; } }