/* * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ #include "BillboardExampleApp.hpp" #include "Scene/Scene.hpp" #include "Scene/Shader/Shader.hpp" #include "Scene/Geometry.hpp" #include "Scene/GeometryFactory.hpp" #include "Scene/Material.hpp" #include "Scene/Vertex.hpp" #include "Scene/SimpleDrawable.hpp" #include "Scene/UI/PerformanceInfo.hpp" #include "Scene/UniformBuffer.hpp" #include "Input/InputManager.hpp" #include "Host/GraphicsAppManager.hpp" #include "Host/GLFW/WindowGLFW.hpp" #include "Math/Math.hpp" #include "Base/EngineConfiguration.hpp" #include "Controller/FreeCamCameraController.hpp" #pragma clang diagnostic push #pragma ide diagnostic ignored "cert-msc50-cpp" #pragma ide diagnostic ignored "cppcoreguidelines-narrowing-conversions" namespace OpenVulkano { using namespace Scene; using namespace Input; using namespace Math; class BillboardExampleAppImpl final : public BillboardExampleApp { public: struct BillboardControlBlock { glm::vec2 quadSize; glm::vec2 windowSize; bool isFixedSize; }; void Init() override { auto engineConfig = OpenVulkano::EngineConfiguration::GetEngineConfiguration(); engineConfig->SetNumThreads(4); engineConfig->SetPreferFramebufferFormatSRGB(false); std::srand(1); // Fix seed for random numbers m_scene.Init(); m_cam.Init(70, 16, 9, 0.1f, 100); m_scene.SetCamera(&m_cam); m_quadBillboardShader.AddShaderProgram(OpenVulkano::ShaderProgramType::VERTEX, "Shader/billboardFromSinglePoint"); m_quadBillboardShader.AddShaderProgram(OpenVulkano::ShaderProgramType::GEOMETRY, "Shader/billboardFromSinglePoint"); m_quadBillboardShader.AddShaderProgram(OpenVulkano::ShaderProgramType::FRAGMENT, "Shader/billboard"); m_quadBillboardShader.AddVertexInputDescription(OpenVulkano::Vertex::GetVertexInputDescription()); m_quadBillboardShader.AddDescriptorSetLayoutBinding(UniformBuffer::DESCRIPTOR_SET_LAYOUT_BINDING); m_quadBillboardShader.topology = Topology::POINT_LIST; m_shader.AddShaderProgram(OpenVulkano::ShaderProgramType::VERTEX, "Shader/billboard"); m_shader.AddShaderProgram(OpenVulkano::ShaderProgramType::FRAGMENT, "Shader/billboard"); m_shader.AddVertexInputDescription(OpenVulkano::Vertex::GetVertexInputDescription()); m_shader.AddDescriptorSetLayoutBinding(UniformBuffer::DESCRIPTOR_SET_LAYOUT_BINDING); m_shader.cullMode = CullMode::NONE; constexpr int quadsCnt = 7; constexpr int otherCnt = 2; constexpr int cntDrawables = quadsCnt + otherCnt; m_bbContolBlock.quadSize = { 100.f, 100.f }; m_bbContolBlock.windowSize = { 0, 0 }; // will be initialized on first frame m_bbContolBlock.isFixedSize = false; m_uniBuffer.Init(sizeof(BillboardControlBlock), &m_bbContolBlock); m_drawablesPool.resize(cntDrawables); m_nodesPool.resize(cntDrawables); m_geo.reserve(cntDrawables); for (uint32_t i = 0; i < cntDrawables; i++) { Geometry* geo = nullptr; m_nodesPool[i].Init(); if (i < quadsCnt) { geo = new Geometry(); geo->Init(1, 0); geo->vertices[0].position = glm::vec3(1 + i, i, 0); geo->vertices[0].color = glm::vec4(1, 0, 0, 1); m_nodesPool[i].SetMatrix(Math::Utils::translate(glm::mat4x4(1.f), Vector3f(-5 + std::rand() % 5, -5 + std::rand() % 5, std::rand() % 5))); m_drawablesPool[i].Init(&m_quadBillboardShader, geo, &m_mat, &m_uniBuffer); } else { geo = GeometryFactory::MakePyramid(1, 1, glm::vec4(0, 1, 0, 1)); m_nodesPool[i].SetMatrix(Math::Utils::translate(glm::mat4x4(1.f), Vector3f(-5 + std::rand() % 5, -5 + std::rand() % 5, -std::rand() % 10))); m_drawablesPool[i].Init(&m_shader, geo, &m_mat, &m_uniBuffer); } m_geo.push_back(geo); m_scene.GetRoot()->AddChild(&m_nodesPool[i]); m_nodesPool[i].AddDrawable(&m_drawablesPool[i]); m_nodesPool[i].SetUpdateFrequency(UpdateFrequency::Always); } GetGraphicsAppManager()->GetRenderer()->SetScene(&m_scene); m_camController.Init(&m_cam); m_camController.SetDefaultKeybindings(); m_camController.SetPosition({ 0, 0, 5 }); m_camController.SetBoostFactor(5); std::shared_ptr m_perfInfo = std::make_shared(); m_ui.AddElement(m_perfInfo); GetGraphicsAppManager()->GetRenderer()->SetActiveUi(&m_ui); } void Tick() override { static bool firstFrame = true; if (firstFrame) { glm::vec2 sz = GetGraphicsAppManager()->GetWindow()->GetSize(); m_bbContolBlock.windowSize = sz; m_uniBuffer.updated = true; firstFrame = false; } m_camController.Tick(); } void Close() override { for (Geometry* g: m_geo) { delete g; } } private: OpenVulkano::Scene::Scene m_scene; BillboardControlBlock m_bbContolBlock; PerspectiveCamera m_cam; UniformBuffer m_uniBuffer; OpenVulkano::FreeCamCameraController m_camController; Material m_mat; Shader m_shader; Shader m_quadBillboardShader; std::vector m_drawablesPool; std::vector m_nodesPool; Vector3f_SIMD m_position = { 0, 0, -10 }; OpenVulkano::Scene::UI::SimpleUi m_ui; std::vector m_geo; std::shared_ptr m_perfInfo; }; IGraphicsApp* BillboardExampleApp::Create() { return new BillboardExampleAppImpl(); } std::unique_ptr BillboardExampleApp::CreateUnique() { return std::make_unique(); } } #pragma clang diagnostic pop #pragma clang diagnostic pop