diff --git a/docs/lectures/02/index.md b/docs/lectures/02/index.md index 049721eb5d584c4029a1a1e20f2dc900fbcb1131..c257749070710f52a67dea5cd339f6c7ef58559a 100644 --- a/docs/lectures/02/index.md +++ b/docs/lectures/02/index.md @@ -71,3 +71,80 @@ static auto create_instance() -> vk::UniqueInstance ## Swapchain A `vk::SurfaceKHR`-hez hasonlóan létezik egy `vk::SwapchainKHR` is, amivel "rajzolni" tudunk a kapott ablakfelszínre. +Az ablakfelszínnel ellentétben ezt mi fogjuk most létrehozni és felkonfigurálni. + +??? example "Vegyük fel az új (még üres) `Swapchain` osztályt." + + ```cpp title="Swapchain.hpp" + class Swapchain {}; + ``` + +Ahogyan majd később látni fogjuk, a swapchain nem mindig lesz valid állapotban. +Ez egy *immutable* objektum, és ha például az ablak mérete változik, akkor újra létre kell hozni. +Éppen ezért vegyünk fel egy **opcionális** swapchain változót a `Renderer`-be. + +!!! example "" + + ```cpp title="Renderer.hpp" + class Renderer { + // ... + std::optional<Swapchain> m_swapchain; + }; + ``` + +### Extent + +A swapchain feladata a [double/triple buffering](https://gameprogrammingpatterns.com/double-buffer.html) implementálása a rajzolt képek megjelenítéséhez, amihez értelemszerűen több képet is kezelnie kell. +A swapchain létrehozásakor legyen az első lépésünk ezen képek felbontásának megadása. + +Fontos, hogy a létrehozott ablak felbontása nem feltétlenül ugyan az képernyő- és pixelkoordinátákban, ezért a *main.cpp*-ben használt `1280x720` nem fog működni. +A GLFW könyvtár a pixelkoordinátákban vett felszínt *framebuffer*-nek nevezi. +Ennek a méretét kell majd lekérni az ablaktól. + +Sok esetben a kapott ablakfelszín segítségével lekérdezhető a hozzá tartozó méret is, de néha ez többféle érték is felhasználható. +Ilyenkor *clamp*-elni kell az általunk használni kívánt értéket a felszín által definiált min és max értékek közé. + +??? example "Mindez így néz ki kódban" + + ```cpp title="Swapchain.hpp" + class Swapchain { + public: + [[nodiscard]] + static auto choose_extent( + const vk::Extent2D& framebuffer_size, + const vk::SurfaceCapabilitiesKHR& surface_capabilities + ) -> vk::Extent2D; + // ... + ``` + + ```cpp title="Swapchain.cpp" + auto Swapchain::choose_extent( + const vk::Extent2D& framebuffer_size, + const vk::SurfaceCapabilitiesKHR& surface_capabilities + ) -> vk::Extent2D + { + if (surface_capabilities.currentExtent.width != std::numeric_limits<uint32_t>::max()) + { + return surface_capabilities.currentExtent; + } + + return vk::Extent2D{ + .width = std::clamp( + static_cast<uint32_t>(framebuffer_size.width), + surface_capabilities.minImageExtent.width, + surface_capabilities.maxImageExtent.width + ), + .height = std::clamp( + static_cast<uint32_t>(framebuffer_size.height), + surface_capabilities.minImageExtent.height, + surface_capabilities.maxImageExtent.height + ), + }; + } + ``` + + !!! note "" + + A `surface_capabilities`-t majd az ablakfelszín segítségével fogjuk megkapni, a `framebuffer_size`-t pedig maga az ablak adja. + +### Surface format