Renderer: Expose present mode and allow to query/set it
This commit is contained in:
parent
28d69ab552
commit
e8620894f7
|
|
@ -34,13 +34,17 @@ namespace Nz
|
||||||
inline GL::Context& GetContext();
|
inline GL::Context& GetContext();
|
||||||
const OpenGLFramebuffer& GetFramebuffer(std::size_t i) const override;
|
const OpenGLFramebuffer& GetFramebuffer(std::size_t i) const override;
|
||||||
std::size_t GetFramebufferCount() const override;
|
std::size_t GetFramebufferCount() const override;
|
||||||
|
PresentMode GetPresentMode() const override;
|
||||||
const OpenGLRenderPass& GetRenderPass() const override;
|
const OpenGLRenderPass& GetRenderPass() const override;
|
||||||
const Vector2ui& GetSize() const override;
|
const Vector2ui& GetSize() const override;
|
||||||
|
PresentModeFlags GetSupportedPresentModes() const override;
|
||||||
|
|
||||||
void NotifyResize(const Vector2ui& newSize) override;
|
void NotifyResize(const Vector2ui& newSize) override;
|
||||||
|
|
||||||
void Present();
|
void Present();
|
||||||
|
|
||||||
|
void SetPresentMode(PresentMode presentMode) override;
|
||||||
|
|
||||||
TransientResources& Transient() override;
|
TransientResources& Transient() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
@ -49,6 +53,8 @@ namespace Nz
|
||||||
std::vector<std::unique_ptr<OpenGLRenderImage>> m_renderImage;
|
std::vector<std::unique_ptr<OpenGLRenderImage>> m_renderImage;
|
||||||
std::shared_ptr<GL::Context> m_context;
|
std::shared_ptr<GL::Context> m_context;
|
||||||
OpenGLWindowFramebuffer m_framebuffer;
|
OpenGLWindowFramebuffer m_framebuffer;
|
||||||
|
PresentMode m_presentMode;
|
||||||
|
PresentModeFlags m_supportedPresentModes;
|
||||||
Vector2ui m_size;
|
Vector2ui m_size;
|
||||||
bool m_sizeInvalidated;
|
bool m_sizeInvalidated;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -148,8 +148,6 @@ namespace Nz::GL
|
||||||
|
|
||||||
inline bool DidLastCallSucceed() const;
|
inline bool DidLastCallSucceed() const;
|
||||||
|
|
||||||
virtual void EnableVerticalSync(bool enabled) = 0;
|
|
||||||
|
|
||||||
inline bool GetBoolean(GLenum name) const;
|
inline bool GetBoolean(GLenum name) const;
|
||||||
inline bool GetBoolean(GLenum name, GLuint index) const;
|
inline bool GetBoolean(GLenum name, GLuint index) const;
|
||||||
inline const OpenGLDevice* GetDevice() const;
|
inline const OpenGLDevice* GetDevice() const;
|
||||||
|
|
@ -159,6 +157,7 @@ namespace Nz::GL
|
||||||
template<typename T> T GetInteger(GLenum name) const;
|
template<typename T> T GetInteger(GLenum name) const;
|
||||||
template<typename T> T GetInteger(GLenum name, GLuint index) const;
|
template<typename T> T GetInteger(GLenum name, GLuint index) const;
|
||||||
inline const ContextParams& GetParams() const;
|
inline const ContextParams& GetParams() const;
|
||||||
|
virtual PresentModeFlags GetSupportedPresentModes() const = 0;
|
||||||
inline const OpenGLVaoCache& GetVaoCache() const;
|
inline const OpenGLVaoCache& GetVaoCache() const;
|
||||||
|
|
||||||
inline bool IsExtensionSupported(Extension extension) const;
|
inline bool IsExtensionSupported(Extension extension) const;
|
||||||
|
|
@ -183,6 +182,7 @@ namespace Nz::GL
|
||||||
inline void ResetStencilWriteMasks() const;
|
inline void ResetStencilWriteMasks() const;
|
||||||
|
|
||||||
void SetCurrentTextureUnit(UInt32 textureUnit) const;
|
void SetCurrentTextureUnit(UInt32 textureUnit) const;
|
||||||
|
virtual void SetPresentMode(PresentMode presentMode) = 0;
|
||||||
void SetScissorBox(GLint x, GLint y, GLsizei width, GLsizei height) const;
|
void SetScissorBox(GLint x, GLint y, GLsizei width, GLsizei height) const;
|
||||||
void SetViewport(GLint x, GLint y, GLsizei width, GLsizei height) const;
|
void SetViewport(GLint x, GLint y, GLsizei width, GLsizei height) const;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -35,10 +35,12 @@ namespace Nz::GL
|
||||||
virtual bool Create(const ContextParams& params, WindowHandle window, const EGLContextBase* shareContext = nullptr);
|
virtual bool Create(const ContextParams& params, WindowHandle window, const EGLContextBase* shareContext = nullptr);
|
||||||
virtual void Destroy();
|
virtual void Destroy();
|
||||||
|
|
||||||
void EnableVerticalSync(bool enabled) override;
|
PresentModeFlags GetSupportedPresentModes() const override;
|
||||||
|
|
||||||
inline bool HasPlatformExtension(const std::string& str) const;
|
inline bool HasPlatformExtension(const std::string& str) const;
|
||||||
|
|
||||||
|
void SetPresentMode(PresentMode presentMode) override;
|
||||||
|
|
||||||
void SwapBuffers() override;
|
void SwapBuffers() override;
|
||||||
|
|
||||||
EGLContextBase& operator=(const EGLContextBase&) = delete;
|
EGLContextBase& operator=(const EGLContextBase&) = delete;
|
||||||
|
|
@ -72,6 +74,8 @@ namespace Nz::GL
|
||||||
|
|
||||||
std::unordered_set<std::string> m_supportedPlatformExtensions;
|
std::unordered_set<std::string> m_supportedPlatformExtensions;
|
||||||
EGLContext m_handle;
|
EGLContext m_handle;
|
||||||
|
EGLint m_maxSwapInterval;
|
||||||
|
EGLint m_minSwapInterval;
|
||||||
bool m_ownsDisplay;
|
bool m_ownsDisplay;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,7 @@ NAZARA_OPENGLRENDERER_EGL_FUNC(eglCreatePbufferSurface, PFNEGLCREATEPBUFFERSURFA
|
||||||
NAZARA_OPENGLRENDERER_EGL_FUNC(eglCreateWindowSurface, PFNEGLCREATEWINDOWSURFACEPROC)
|
NAZARA_OPENGLRENDERER_EGL_FUNC(eglCreateWindowSurface, PFNEGLCREATEWINDOWSURFACEPROC)
|
||||||
NAZARA_OPENGLRENDERER_EGL_FUNC(eglDestroyContext, PFNEGLDESTROYCONTEXTPROC)
|
NAZARA_OPENGLRENDERER_EGL_FUNC(eglDestroyContext, PFNEGLDESTROYCONTEXTPROC)
|
||||||
NAZARA_OPENGLRENDERER_EGL_FUNC(eglDestroySurface, PFNEGLDESTROYSURFACEPROC)
|
NAZARA_OPENGLRENDERER_EGL_FUNC(eglDestroySurface, PFNEGLDESTROYSURFACEPROC)
|
||||||
|
NAZARA_OPENGLRENDERER_EGL_FUNC(eglGetConfigAttrib, PFNEGLGETCONFIGATTRIBPROC)
|
||||||
NAZARA_OPENGLRENDERER_EGL_FUNC(eglGetDisplay, PFNEGLGETDISPLAYPROC)
|
NAZARA_OPENGLRENDERER_EGL_FUNC(eglGetDisplay, PFNEGLGETDISPLAYPROC)
|
||||||
NAZARA_OPENGLRENDERER_EGL_FUNC(eglGetError, PFNEGLGETERRORPROC)
|
NAZARA_OPENGLRENDERER_EGL_FUNC(eglGetError, PFNEGLGETERRORPROC)
|
||||||
NAZARA_OPENGLRENDERER_EGL_FUNC(eglGetProcAddress, PFNEGLGETPROCADDRESSPROC)
|
NAZARA_OPENGLRENDERER_EGL_FUNC(eglGetProcAddress, PFNEGLGETPROCADDRESSPROC)
|
||||||
|
|
@ -24,6 +25,7 @@ NAZARA_OPENGLRENDERER_EGL_FUNC(eglInitialize, PFNEGLINITIALIZEPROC)
|
||||||
NAZARA_OPENGLRENDERER_EGL_FUNC(eglMakeCurrent, PFNEGLMAKECURRENTPROC)
|
NAZARA_OPENGLRENDERER_EGL_FUNC(eglMakeCurrent, PFNEGLMAKECURRENTPROC)
|
||||||
NAZARA_OPENGLRENDERER_EGL_FUNC(eglQueryString, PFNEGLQUERYSTRINGPROC)
|
NAZARA_OPENGLRENDERER_EGL_FUNC(eglQueryString, PFNEGLQUERYSTRINGPROC)
|
||||||
NAZARA_OPENGLRENDERER_EGL_FUNC(eglSwapBuffers, PFNEGLSWAPBUFFERSPROC)
|
NAZARA_OPENGLRENDERER_EGL_FUNC(eglSwapBuffers, PFNEGLSWAPBUFFERSPROC)
|
||||||
|
NAZARA_OPENGLRENDERER_EGL_FUNC(eglSwapInterval, PFNEGLSWAPINTERVALPROC)
|
||||||
NAZARA_OPENGLRENDERER_EGL_FUNC(eglTerminate, PFNEGLTERMINATEPROC)
|
NAZARA_OPENGLRENDERER_EGL_FUNC(eglTerminate, PFNEGLTERMINATEPROC)
|
||||||
|
|
||||||
NAZARA_OPENGLRENDERER_EGL_FUNC_OPT(eglCreatePlatformWindowSurface, PFNEGLCREATEPLATFORMWINDOWSURFACEPROC)
|
NAZARA_OPENGLRENDERER_EGL_FUNC_OPT(eglCreatePlatformWindowSurface, PFNEGLCREATEPLATFORMWINDOWSURFACEPROC)
|
||||||
|
|
|
||||||
|
|
@ -34,10 +34,12 @@ namespace Nz::GL
|
||||||
bool Create(const WGLContext* baseContext, const ContextParams& params, WindowHandle window, const WGLContext* shareContext = nullptr);
|
bool Create(const WGLContext* baseContext, const ContextParams& params, WindowHandle window, const WGLContext* shareContext = nullptr);
|
||||||
void Destroy();
|
void Destroy();
|
||||||
|
|
||||||
void EnableVerticalSync(bool enabled) override;
|
PresentModeFlags GetSupportedPresentModes() const override;
|
||||||
|
|
||||||
inline bool HasPlatformExtension(const std::string& str) const;
|
inline bool HasPlatformExtension(const std::string& str) const;
|
||||||
|
|
||||||
|
void SetPresentMode(PresentMode presentMode) override;
|
||||||
|
|
||||||
void SwapBuffers() override;
|
void SwapBuffers() override;
|
||||||
|
|
||||||
WGLContext& operator=(const WGLContext&) = delete;
|
WGLContext& operator=(const WGLContext&) = delete;
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
|
|
||||||
namespace Nz::GL
|
namespace Nz::GL
|
||||||
{
|
{
|
||||||
inline GL::WGLContext::WGLContext(const OpenGLDevice* device, const WGLLoader& loader) :
|
inline WGLContext::WGLContext(const OpenGLDevice* device, const WGLLoader& loader) :
|
||||||
Context(device),
|
Context(device),
|
||||||
m_loader(loader),
|
m_loader(loader),
|
||||||
m_handle(nullptr)
|
m_handle(nullptr)
|
||||||
|
|
|
||||||
|
|
@ -33,10 +33,12 @@ namespace Nz::GL
|
||||||
virtual bool Create(const ContextParams& params, WindowHandle window, const WebContext* shareContext = nullptr);
|
virtual bool Create(const ContextParams& params, WindowHandle window, const WebContext* shareContext = nullptr);
|
||||||
virtual void Destroy();
|
virtual void Destroy();
|
||||||
|
|
||||||
void EnableVerticalSync(bool enabled) override;
|
PresentModeFlags GetSupportedPresentModes() const override;
|
||||||
|
|
||||||
inline bool HasPlatformExtension(const std::string& str) const;
|
inline bool HasPlatformExtension(const std::string& str) const;
|
||||||
|
|
||||||
|
void SetPresentMode(PresentMode presentMode) override;
|
||||||
|
|
||||||
void SwapBuffers() override;
|
void SwapBuffers() override;
|
||||||
|
|
||||||
WebContext& operator=(const WebContext&) = delete;
|
WebContext& operator=(const WebContext&) = delete;
|
||||||
|
|
|
||||||
|
|
@ -109,6 +109,24 @@ namespace Nz
|
||||||
|
|
||||||
using PipelineStageFlags = Flags<PipelineStage>;
|
using PipelineStageFlags = Flags<PipelineStage>;
|
||||||
|
|
||||||
|
enum class PresentMode
|
||||||
|
{
|
||||||
|
Immediate,
|
||||||
|
Mailbox,
|
||||||
|
RelaxedVerticalSync,
|
||||||
|
VerticalSync,
|
||||||
|
|
||||||
|
Max = VerticalSync
|
||||||
|
};
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct EnumAsFlags<PresentMode>
|
||||||
|
{
|
||||||
|
static constexpr PresentMode max = PresentMode::Max;
|
||||||
|
};
|
||||||
|
|
||||||
|
using PresentModeFlags = Flags<PresentMode>;
|
||||||
|
|
||||||
enum class QueueType
|
enum class QueueType
|
||||||
{
|
{
|
||||||
Compute,
|
Compute,
|
||||||
|
|
|
||||||
|
|
@ -32,8 +32,13 @@ namespace Nz
|
||||||
|
|
||||||
virtual std::shared_ptr<CommandPool> CreateCommandPool(QueueType queueType) = 0;
|
virtual std::shared_ptr<CommandPool> CreateCommandPool(QueueType queueType) = 0;
|
||||||
|
|
||||||
|
virtual PresentMode GetPresentMode() const = 0;
|
||||||
|
virtual PresentModeFlags GetSupportedPresentModes() const = 0;
|
||||||
|
|
||||||
virtual void NotifyResize(const Vector2ui& newSize) = 0;
|
virtual void NotifyResize(const Vector2ui& newSize) = 0;
|
||||||
|
|
||||||
|
virtual void SetPresentMode(PresentMode presentMode) = 0;
|
||||||
|
|
||||||
virtual TransientResources& Transient() = 0;
|
virtual TransientResources& Transient() = 0;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@
|
||||||
#define NAZARA_RENDERER_SWAPCHAINPARAMETERS_HPP
|
#define NAZARA_RENDERER_SWAPCHAINPARAMETERS_HPP
|
||||||
|
|
||||||
#include <NazaraUtils/Prerequisites.hpp>
|
#include <NazaraUtils/Prerequisites.hpp>
|
||||||
|
#include <Nazara/Renderer/Enums.hpp>
|
||||||
#include <Nazara/Utility/PixelFormat.hpp>
|
#include <Nazara/Utility/PixelFormat.hpp>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
|
@ -15,8 +16,8 @@ namespace Nz
|
||||||
{
|
{
|
||||||
struct SwapchainParameters
|
struct SwapchainParameters
|
||||||
{
|
{
|
||||||
std::vector<PixelFormat> depthFormats = {Nz::PixelFormat::Depth24Stencil8, Nz::PixelFormat::Depth32FStencil8, Nz::PixelFormat::Depth16Stencil8, Nz::PixelFormat::Depth32F, Nz::PixelFormat::Depth24}; //< By order of preference
|
std::vector<PixelFormat> depthFormats = { Nz::PixelFormat::Depth24Stencil8, Nz::PixelFormat::Depth32FStencil8, Nz::PixelFormat::Depth16Stencil8, Nz::PixelFormat::Depth32F, Nz::PixelFormat::Depth24 }; //< By order of preference
|
||||||
bool verticalSync = false;
|
std::vector<PresentMode> presentMode = { PresentMode::Mailbox, PresentMode::Immediate, PresentMode::RelaxedVerticalSync, PresentMode::VerticalSync }; //< By order of preference
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,7 @@
|
||||||
namespace Nz
|
namespace Nz
|
||||||
{
|
{
|
||||||
inline std::optional<PixelFormat> FromVulkan(VkFormat format);
|
inline std::optional<PixelFormat> FromVulkan(VkFormat format);
|
||||||
|
inline std::optional<PresentMode> FromVulkan(VkPresentModeKHR presentMode);
|
||||||
|
|
||||||
inline VkAttachmentLoadOp ToVulkan(AttachmentLoadOp loadOp);
|
inline VkAttachmentLoadOp ToVulkan(AttachmentLoadOp loadOp);
|
||||||
inline VkAttachmentStoreOp ToVulkan(AttachmentStoreOp storeOp);
|
inline VkAttachmentStoreOp ToVulkan(AttachmentStoreOp storeOp);
|
||||||
|
|
@ -33,6 +34,7 @@ namespace Nz
|
||||||
inline VkPipelineStageFlags ToVulkan(PipelineStageFlags pipelineStages);
|
inline VkPipelineStageFlags ToVulkan(PipelineStageFlags pipelineStages);
|
||||||
inline VkFormat ToVulkan(PixelFormat pixelFormat);
|
inline VkFormat ToVulkan(PixelFormat pixelFormat);
|
||||||
inline VkImageAspectFlags ToVulkan(PixelFormatContent pixelFormatContent);
|
inline VkImageAspectFlags ToVulkan(PixelFormatContent pixelFormatContent);
|
||||||
|
inline VkPresentModeKHR ToVulkan(PresentMode presentMode);
|
||||||
inline VkPrimitiveTopology ToVulkan(PrimitiveMode primitiveMode);
|
inline VkPrimitiveTopology ToVulkan(PrimitiveMode primitiveMode);
|
||||||
inline VkCompareOp ToVulkan(RendererComparison comparison);
|
inline VkCompareOp ToVulkan(RendererComparison comparison);
|
||||||
inline VkFilter ToVulkan(SamplerFilter samplerFilter);
|
inline VkFilter ToVulkan(SamplerFilter samplerFilter);
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,20 @@ namespace Nz
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::optional<PresentMode> FromVulkan(VkPresentModeKHR presentMode)
|
||||||
|
{
|
||||||
|
switch (presentMode)
|
||||||
|
{
|
||||||
|
case VK_PRESENT_MODE_IMMEDIATE_KHR: return PresentMode::Immediate;
|
||||||
|
case VK_PRESENT_MODE_MAILBOX_KHR: return PresentMode::Mailbox;
|
||||||
|
case VK_PRESENT_MODE_FIFO_KHR: return PresentMode::VerticalSync;
|
||||||
|
case VK_PRESENT_MODE_FIFO_RELAXED_KHR: return PresentMode::RelaxedVerticalSync;
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
|
||||||
inline VkAttachmentLoadOp ToVulkan(AttachmentLoadOp loadOp)
|
inline VkAttachmentLoadOp ToVulkan(AttachmentLoadOp loadOp)
|
||||||
{
|
{
|
||||||
switch (loadOp)
|
switch (loadOp)
|
||||||
|
|
@ -306,6 +320,20 @@ namespace Nz
|
||||||
return VK_IMAGE_ASPECT_COLOR_BIT;
|
return VK_IMAGE_ASPECT_COLOR_BIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VkPresentModeKHR ToVulkan(PresentMode presentMode)
|
||||||
|
{
|
||||||
|
switch (presentMode)
|
||||||
|
{
|
||||||
|
case PresentMode::Immediate: return VK_PRESENT_MODE_IMMEDIATE_KHR;
|
||||||
|
case PresentMode::Mailbox: return VK_PRESENT_MODE_MAILBOX_KHR;
|
||||||
|
case PresentMode::RelaxedVerticalSync: return VK_PRESENT_MODE_FIFO_RELAXED_KHR;
|
||||||
|
case PresentMode::VerticalSync: return VK_PRESENT_MODE_FIFO_KHR;
|
||||||
|
}
|
||||||
|
|
||||||
|
NazaraError("Unhandled PresentMode 0x" + NumberToString(UnderlyingCast(presentMode), 16));
|
||||||
|
return VK_PRESENT_MODE_FIFO_KHR;
|
||||||
|
}
|
||||||
|
|
||||||
inline VkPrimitiveTopology ToVulkan(PrimitiveMode primitiveMode)
|
inline VkPrimitiveTopology ToVulkan(PrimitiveMode primitiveMode)
|
||||||
{
|
{
|
||||||
switch (primitiveMode)
|
switch (primitiveMode)
|
||||||
|
|
@ -318,7 +346,7 @@ namespace Nz
|
||||||
case PrimitiveMode::TriangleFan: return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN;
|
case PrimitiveMode::TriangleFan: return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN;
|
||||||
}
|
}
|
||||||
|
|
||||||
NazaraError("Unhandled FaceFilling 0x" + NumberToString(UnderlyingCast(primitiveMode), 16));
|
NazaraError("Unhandled PrimitiveMode 0x" + NumberToString(UnderlyingCast(primitiveMode), 16));
|
||||||
return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
|
return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -502,3 +530,4 @@ namespace Nz
|
||||||
}
|
}
|
||||||
|
|
||||||
#include <Nazara/VulkanRenderer/DebugOff.hpp>
|
#include <Nazara/VulkanRenderer/DebugOff.hpp>
|
||||||
|
#include "Utils.hpp"
|
||||||
|
|
|
||||||
|
|
@ -53,12 +53,16 @@ namespace Nz
|
||||||
inline Vk::QueueHandle& GetGraphicsQueue();
|
inline Vk::QueueHandle& GetGraphicsQueue();
|
||||||
const VulkanRenderPass& GetRenderPass() const override;
|
const VulkanRenderPass& GetRenderPass() const override;
|
||||||
const Vector2ui& GetSize() const override;
|
const Vector2ui& GetSize() const override;
|
||||||
|
PresentMode GetPresentMode() const override;
|
||||||
|
PresentModeFlags GetSupportedPresentModes() const override;
|
||||||
inline const Vk::Swapchain& GetSwapchain() const;
|
inline const Vk::Swapchain& GetSwapchain() const;
|
||||||
|
|
||||||
void NotifyResize(const Vector2ui& newSize) override;
|
void NotifyResize(const Vector2ui& newSize) override;
|
||||||
|
|
||||||
void Present(UInt32 imageIndex, VkSemaphore waitSemaphore = VK_NULL_HANDLE);
|
void Present(UInt32 imageIndex, VkSemaphore waitSemaphore = VK_NULL_HANDLE);
|
||||||
|
|
||||||
|
void SetPresentMode(PresentMode presentMode) override;
|
||||||
|
|
||||||
TransientResources& Transient() override;
|
TransientResources& Transient() override;
|
||||||
|
|
||||||
VulkanSwapchain& operator=(const VulkanSwapchain&) = delete;
|
VulkanSwapchain& operator=(const VulkanSwapchain&) = delete;
|
||||||
|
|
@ -85,6 +89,8 @@ namespace Nz
|
||||||
Vk::QueueHandle m_transferQueue;
|
Vk::QueueHandle m_transferQueue;
|
||||||
Vk::Surface m_surface;
|
Vk::Surface m_surface;
|
||||||
Vk::Swapchain m_swapchain;
|
Vk::Swapchain m_swapchain;
|
||||||
|
PresentMode m_presentMode;
|
||||||
|
PresentModeFlags m_supportedPresentModes;
|
||||||
Vector2ui m_swapchainSize;
|
Vector2ui m_swapchainSize;
|
||||||
VkFormat m_depthStencilFormat;
|
VkFormat m_depthStencilFormat;
|
||||||
VkSurfaceFormatKHR m_surfaceFormat;
|
VkSurfaceFormatKHR m_surfaceFormat;
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,6 @@
|
||||||
#include <Nazara/OpenGLRenderer/OpenGLCommandPool.hpp>
|
#include <Nazara/OpenGLRenderer/OpenGLCommandPool.hpp>
|
||||||
#include <Nazara/OpenGLRenderer/OpenGLRenderer.hpp>
|
#include <Nazara/OpenGLRenderer/OpenGLRenderer.hpp>
|
||||||
#include <Nazara/Renderer/CommandPool.hpp>
|
#include <Nazara/Renderer/CommandPool.hpp>
|
||||||
#include <Nazara/Renderer/WindowSwapchain.hpp>
|
|
||||||
#include <Nazara/OpenGLRenderer/Debug.hpp>
|
#include <Nazara/OpenGLRenderer/Debug.hpp>
|
||||||
|
|
||||||
namespace Nz
|
namespace Nz
|
||||||
|
|
@ -54,6 +53,23 @@ namespace Nz
|
||||||
else
|
else
|
||||||
depthFormat = PixelFormat::Undefined;
|
depthFormat = PixelFormat::Undefined;
|
||||||
|
|
||||||
|
m_supportedPresentModes = m_context->GetSupportedPresentModes();
|
||||||
|
|
||||||
|
#ifdef NAZARA_PLATFORM_WEB
|
||||||
|
m_presentMode = PresentMode::Immediate; //< default present mode
|
||||||
|
#else
|
||||||
|
m_presentMode = PresentMode::VerticalSync; //< default present mode
|
||||||
|
#endif
|
||||||
|
|
||||||
|
for (PresentMode presentMode : parameters.presentMode)
|
||||||
|
{
|
||||||
|
if (m_supportedPresentModes & presentMode)
|
||||||
|
{
|
||||||
|
SetPresentMode(presentMode);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<RenderPass::Attachment> attachments;
|
std::vector<RenderPass::Attachment> attachments;
|
||||||
std::vector<RenderPass::SubpassDescription> subpassDescriptions;
|
std::vector<RenderPass::SubpassDescription> subpassDescriptions;
|
||||||
std::vector<RenderPass::SubpassDependency> subpassDependencies;
|
std::vector<RenderPass::SubpassDependency> subpassDependencies;
|
||||||
|
|
@ -78,7 +94,7 @@ namespace Nz
|
||||||
|
|
||||||
std::shared_ptr<CommandPool> OpenGLSwapchain::CreateCommandPool(QueueType /*queueType*/)
|
std::shared_ptr<CommandPool> OpenGLSwapchain::CreateCommandPool(QueueType /*queueType*/)
|
||||||
{
|
{
|
||||||
return std::make_unique<OpenGLCommandPool>();
|
return std::make_shared<OpenGLCommandPool>();
|
||||||
}
|
}
|
||||||
|
|
||||||
const OpenGLFramebuffer& OpenGLSwapchain::GetFramebuffer(std::size_t i) const
|
const OpenGLFramebuffer& OpenGLSwapchain::GetFramebuffer(std::size_t i) const
|
||||||
|
|
@ -98,11 +114,21 @@ namespace Nz
|
||||||
return *m_renderPass;
|
return *m_renderPass;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PresentMode OpenGLSwapchain::GetPresentMode() const
|
||||||
|
{
|
||||||
|
return m_presentMode;
|
||||||
|
}
|
||||||
|
|
||||||
const Vector2ui& OpenGLSwapchain::GetSize() const
|
const Vector2ui& OpenGLSwapchain::GetSize() const
|
||||||
{
|
{
|
||||||
return m_size;
|
return m_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PresentModeFlags OpenGLSwapchain::GetSupportedPresentModes() const
|
||||||
|
{
|
||||||
|
return m_supportedPresentModes;
|
||||||
|
}
|
||||||
|
|
||||||
void OpenGLSwapchain::NotifyResize(const Vector2ui& newSize)
|
void OpenGLSwapchain::NotifyResize(const Vector2ui& newSize)
|
||||||
{
|
{
|
||||||
OnRenderTargetSizeChange(this, newSize);
|
OnRenderTargetSizeChange(this, newSize);
|
||||||
|
|
@ -117,6 +143,17 @@ namespace Nz
|
||||||
m_currentFrame = (m_currentFrame + 1) % m_renderImage.size();
|
m_currentFrame = (m_currentFrame + 1) % m_renderImage.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void OpenGLSwapchain::SetPresentMode(PresentMode presentMode)
|
||||||
|
{
|
||||||
|
NazaraAssert(m_supportedPresentModes & presentMode, "unsupported present mode");
|
||||||
|
|
||||||
|
if (m_presentMode != presentMode)
|
||||||
|
{
|
||||||
|
m_context->SetPresentMode(presentMode);
|
||||||
|
m_presentMode = presentMode;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
TransientResources& OpenGLSwapchain::Transient()
|
TransientResources& OpenGLSwapchain::Transient()
|
||||||
{
|
{
|
||||||
return *m_renderImage[m_currentFrame];
|
return *m_renderImage[m_currentFrame];
|
||||||
|
|
|
||||||
|
|
@ -670,8 +670,6 @@ namespace Nz::GL
|
||||||
m_state.renderStates.scissorTest = false;
|
m_state.renderStates.scissorTest = false;
|
||||||
m_state.renderStates.stencilTest = false;
|
m_state.renderStates.stencilTest = false;
|
||||||
|
|
||||||
EnableVerticalSync(false);
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -87,9 +87,33 @@ namespace Nz::GL
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void EGLContextBase::EnableVerticalSync(bool enabled)
|
PresentModeFlags EGLContextBase::GetSupportedPresentModes() const
|
||||||
{
|
{
|
||||||
// TODO
|
PresentModeFlags supportedModes;
|
||||||
|
if (m_maxSwapInterval >= 1)
|
||||||
|
supportedModes |= PresentMode::VerticalSync;
|
||||||
|
|
||||||
|
if (m_minSwapInterval <= 0)
|
||||||
|
supportedModes |= PresentMode::Immediate;
|
||||||
|
|
||||||
|
if (m_minSwapInterval <= -1)
|
||||||
|
supportedModes |= PresentMode::RelaxedVerticalSync;
|
||||||
|
|
||||||
|
return supportedModes;
|
||||||
|
}
|
||||||
|
|
||||||
|
void EGLContextBase::SetPresentMode(PresentMode presentMode)
|
||||||
|
{
|
||||||
|
int interval = 0;
|
||||||
|
switch (presentMode)
|
||||||
|
{
|
||||||
|
case PresentMode::Immediate: interval = 0; break;
|
||||||
|
case PresentMode::RelaxedVerticalSync: interval = -1; break;
|
||||||
|
case PresentMode::VerticalSync: interval = 1; break;
|
||||||
|
default: return; // TODO: Unreachable
|
||||||
|
}
|
||||||
|
|
||||||
|
m_loader.eglSwapInterval(m_display, interval);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EGLContextBase::SwapBuffers()
|
void EGLContextBase::SwapBuffers()
|
||||||
|
|
@ -247,6 +271,9 @@ namespace Nz::GL
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_loader.eglGetConfigAttrib(m_display, config, EGL_MAX_SWAP_INTERVAL, &m_maxSwapInterval);
|
||||||
|
m_loader.eglGetConfigAttrib(m_display, config, EGL_MIN_SWAP_INTERVAL, &m_minSwapInterval);
|
||||||
|
|
||||||
LoadEGLExt();
|
LoadEGLExt();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
|
||||||
|
|
@ -73,15 +73,34 @@ namespace Nz::GL
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void WGLContext::EnableVerticalSync(bool enabled)
|
PresentModeFlags WGLContext::GetSupportedPresentModes() const
|
||||||
{
|
{
|
||||||
|
PresentModeFlags supportedModes = PresentMode::Immediate;
|
||||||
if (wglSwapIntervalEXT)
|
if (wglSwapIntervalEXT)
|
||||||
{
|
{
|
||||||
if (!SetCurrentContext(this))
|
supportedModes |= PresentMode::VerticalSync;
|
||||||
return;
|
if (HasPlatformExtension("WGL_EXT_swap_control_tear"))
|
||||||
|
supportedModes |= PresentMode::RelaxedVerticalSync;
|
||||||
wglSwapIntervalEXT(enabled);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return supportedModes;
|
||||||
|
}
|
||||||
|
|
||||||
|
void WGLContext::SetPresentMode(PresentMode presentMode)
|
||||||
|
{
|
||||||
|
if (!SetCurrentContext(this))
|
||||||
|
return;
|
||||||
|
|
||||||
|
int interval = 0;
|
||||||
|
switch (presentMode)
|
||||||
|
{
|
||||||
|
case PresentMode::Immediate: interval = 0; break;
|
||||||
|
case PresentMode::RelaxedVerticalSync: interval = -1; break; //< WGL_EXT_swap_control_tear
|
||||||
|
case PresentMode::VerticalSync: interval = 1; break;
|
||||||
|
default: return; // TODO: Unreachable
|
||||||
|
}
|
||||||
|
|
||||||
|
wglSwapIntervalEXT(interval);
|
||||||
}
|
}
|
||||||
|
|
||||||
void WGLContext::SwapBuffers()
|
void WGLContext::SwapBuffers()
|
||||||
|
|
|
||||||
|
|
@ -64,9 +64,15 @@ namespace Nz::GL
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebContext::EnableVerticalSync(bool /*enabled*/)
|
PresentModeFlags WebContext::GetSupportedPresentModes() const
|
||||||
{
|
{
|
||||||
// TODO
|
// WebGL does not support disabling V-Sync
|
||||||
|
return PresentMode::VerticalSync;
|
||||||
|
}
|
||||||
|
|
||||||
|
void WebContext::SetPresentMode(PresentMode /*presentMode*/)
|
||||||
|
{
|
||||||
|
// Nothing to do
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebContext::SwapBuffers()
|
void WebContext::SwapBuffers()
|
||||||
|
|
|
||||||
|
|
@ -151,6 +151,27 @@ namespace Nz
|
||||||
throw std::runtime_error("failed to find a support depth-stencil format");
|
throw std::runtime_error("failed to find a support depth-stencil format");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<VkPresentModeKHR> presentModes;
|
||||||
|
if (!m_surface.GetPresentModes(physDeviceInfo.physDevice, &presentModes))
|
||||||
|
throw std::runtime_error("failed to query supported present modes");
|
||||||
|
|
||||||
|
m_supportedPresentModes.Clear();
|
||||||
|
for (VkPresentModeKHR vkPresentMode : presentModes)
|
||||||
|
{
|
||||||
|
if (auto presentModeOpt = FromVulkan(vkPresentMode))
|
||||||
|
m_supportedPresentModes |= *presentModeOpt;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_presentMode = PresentMode::VerticalSync; //< guaranteed to be supported
|
||||||
|
for (PresentMode presentMode : parameters.presentMode)
|
||||||
|
{
|
||||||
|
if (m_supportedPresentModes & presentMode)
|
||||||
|
{
|
||||||
|
m_presentMode = presentMode;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!SetupRenderPass())
|
if (!SetupRenderPass())
|
||||||
throw std::runtime_error("failed to create renderpass");
|
throw std::runtime_error("failed to create renderpass");
|
||||||
|
|
||||||
|
|
@ -292,6 +313,16 @@ namespace Nz
|
||||||
return m_swapchainSize;
|
return m_swapchainSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PresentMode VulkanSwapchain::GetPresentMode() const
|
||||||
|
{
|
||||||
|
return m_presentMode;
|
||||||
|
}
|
||||||
|
|
||||||
|
PresentModeFlags VulkanSwapchain::GetSupportedPresentModes() const
|
||||||
|
{
|
||||||
|
return m_supportedPresentModes;
|
||||||
|
}
|
||||||
|
|
||||||
void VulkanSwapchain::NotifyResize(const Vector2ui& newSize)
|
void VulkanSwapchain::NotifyResize(const Vector2ui& newSize)
|
||||||
{
|
{
|
||||||
OnRenderTargetSizeChange(this, newSize);
|
OnRenderTargetSizeChange(this, newSize);
|
||||||
|
|
@ -332,6 +363,17 @@ namespace Nz
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void VulkanSwapchain::SetPresentMode(PresentMode presentMode)
|
||||||
|
{
|
||||||
|
NazaraAssert(m_supportedPresentModes & presentMode, "unsupported present mode");
|
||||||
|
|
||||||
|
if (m_presentMode != presentMode)
|
||||||
|
{
|
||||||
|
m_presentMode = presentMode;
|
||||||
|
m_shouldRecreateSwapchain = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
TransientResources& VulkanSwapchain::Transient()
|
TransientResources& VulkanSwapchain::Transient()
|
||||||
{
|
{
|
||||||
return *m_concurrentImageData[m_currentFrame];
|
return *m_concurrentImageData[m_currentFrame];
|
||||||
|
|
@ -566,26 +608,6 @@ namespace Nz
|
||||||
else
|
else
|
||||||
extent = surfaceCapabilities.currentExtent;
|
extent = surfaceCapabilities.currentExtent;
|
||||||
|
|
||||||
std::vector<VkPresentModeKHR> presentModes;
|
|
||||||
if (!m_surface.GetPresentModes(deviceInfo.physDevice, &presentModes))
|
|
||||||
{
|
|
||||||
NazaraError("Failed to query supported present modes");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
VkPresentModeKHR swapchainPresentMode = VK_PRESENT_MODE_FIFO_KHR;
|
|
||||||
for (VkPresentModeKHR presentMode : presentModes)
|
|
||||||
{
|
|
||||||
if (presentMode == VK_PRESENT_MODE_MAILBOX_KHR)
|
|
||||||
{
|
|
||||||
swapchainPresentMode = VK_PRESENT_MODE_MAILBOX_KHR;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (presentMode == VK_PRESENT_MODE_IMMEDIATE_KHR)
|
|
||||||
swapchainPresentMode = VK_PRESENT_MODE_IMMEDIATE_KHR;
|
|
||||||
}
|
|
||||||
|
|
||||||
VkCompositeAlphaFlagBitsKHR compositeAlpha;
|
VkCompositeAlphaFlagBitsKHR compositeAlpha;
|
||||||
if (surfaceCapabilities.supportedCompositeAlpha & VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR)
|
if (surfaceCapabilities.supportedCompositeAlpha & VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR)
|
||||||
compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;
|
compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;
|
||||||
|
|
@ -610,7 +632,7 @@ namespace Nz
|
||||||
0, nullptr,
|
0, nullptr,
|
||||||
surfaceCapabilities.currentTransform,
|
surfaceCapabilities.currentTransform,
|
||||||
compositeAlpha,
|
compositeAlpha,
|
||||||
swapchainPresentMode,
|
ToVulkan(m_presentMode),
|
||||||
VK_TRUE,
|
VK_TRUE,
|
||||||
m_swapchain
|
m_swapchain
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,186 @@
|
||||||
|
#include <Nazara/Core.hpp>
|
||||||
|
#include <Nazara/Platform.hpp>
|
||||||
|
#include <Nazara/Graphics.hpp>
|
||||||
|
#include <Nazara/Renderer.hpp>
|
||||||
|
#include <Nazara/Utility.hpp>
|
||||||
|
#include <chrono>
|
||||||
|
#include <iostream>
|
||||||
|
#include <thread>
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
Nz::Renderer::Config rendererConfig;
|
||||||
|
#ifndef NAZARA_PLATFORM_WEB
|
||||||
|
std::cout << "Run using Vulkan? (y/n)" << std::endl;
|
||||||
|
if (std::getchar() == 'y')
|
||||||
|
rendererConfig.preferredAPI = Nz::RenderAPI::Vulkan;
|
||||||
|
else
|
||||||
|
rendererConfig.preferredAPI = Nz::RenderAPI::OpenGL;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
Nz::Application<Nz::Graphics> app(rendererConfig);
|
||||||
|
|
||||||
|
auto& windowing = app.AddComponent<Nz::AppWindowingComponent>();
|
||||||
|
|
||||||
|
auto& ecs = app.AddComponent<Nz::AppEntitySystemComponent>();
|
||||||
|
|
||||||
|
auto& world = ecs.AddWorld<Nz::EnttWorld>();
|
||||||
|
Nz::RenderSystem& renderSystem = world.AddSystem<Nz::RenderSystem>();
|
||||||
|
|
||||||
|
std::string windowTitle = "Physics 2D";
|
||||||
|
Nz::Window& window = windowing.CreateWindow(Nz::VideoMode(1920, 1080, 32), windowTitle);
|
||||||
|
Nz::WindowSwapchain& windowSwapchain = renderSystem.CreateSwapchain(window);
|
||||||
|
Nz::Swapchain& swapchain = windowSwapchain.GetSwapchain();
|
||||||
|
|
||||||
|
Nz::Vector2ui windowSize = window.GetSize();
|
||||||
|
|
||||||
|
entt::handle viewer = world.CreateEntity();
|
||||||
|
{
|
||||||
|
viewer.emplace<Nz::NodeComponent>();
|
||||||
|
viewer.emplace<Nz::CameraComponent>(&windowSwapchain, Nz::ProjectionType::Orthographic);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Turn present mode flags into vector for easier processing
|
||||||
|
Nz::FixedVector<Nz::PresentMode, Nz::EnumValueCount_v<Nz::PresentMode>> supportedPresentModes;
|
||||||
|
for (Nz::PresentMode presentMode : swapchain.GetSupportedPresentModes())
|
||||||
|
supportedPresentModes.push_back(presentMode);
|
||||||
|
|
||||||
|
auto presentFlagIt = std::find(supportedPresentModes.begin(), supportedPresentModes.end(), swapchain.GetPresentMode());
|
||||||
|
|
||||||
|
bool limitFps = false;
|
||||||
|
|
||||||
|
std::shared_ptr<Nz::TextSprite> presentModeText = std::make_shared<Nz::TextSprite>();
|
||||||
|
auto UpdatePresentModeText = [&]
|
||||||
|
{
|
||||||
|
Nz::RichTextDrawer textDrawer;
|
||||||
|
textDrawer.SetDefaultStyle(Nz::TextStyle::Bold);
|
||||||
|
textDrawer.AppendText("Supported present modes:\n");
|
||||||
|
textDrawer.SetDefaultStyle(Nz::TextStyle_Regular);
|
||||||
|
textDrawer.AppendText("Use +/- to switch present mode (and * to limit FPS to 50)\n");
|
||||||
|
|
||||||
|
for (Nz::PresentMode presentMode : supportedPresentModes)
|
||||||
|
{
|
||||||
|
textDrawer.AppendText("- ");
|
||||||
|
|
||||||
|
if (presentMode == swapchain.GetPresentMode())
|
||||||
|
textDrawer.SetDefaultColor(Nz::Color::Yellow());
|
||||||
|
else
|
||||||
|
textDrawer.SetDefaultColor(Nz::Color::White());
|
||||||
|
|
||||||
|
switch (presentMode)
|
||||||
|
{
|
||||||
|
case Nz::PresentMode::Immediate: textDrawer.AppendText("Immediate\n"); break;
|
||||||
|
case Nz::PresentMode::Mailbox: textDrawer.AppendText("Mailbox\n"); break;
|
||||||
|
case Nz::PresentMode::RelaxedVerticalSync: textDrawer.AppendText("RelaxedVerticalSync\n"); break;
|
||||||
|
case Nz::PresentMode::VerticalSync: textDrawer.AppendText("VerticalSync\n"); break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
textDrawer.SetDefaultColor(Nz::Color::White());
|
||||||
|
textDrawer.AppendText("Use * to limit FPS to 50\n");
|
||||||
|
if (limitFps)
|
||||||
|
{
|
||||||
|
textDrawer.SetDefaultColor(Nz::Color::Red());
|
||||||
|
textDrawer.AppendText("FPS limited to 50\n");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
textDrawer.AppendText("Unlimited FPS\n");
|
||||||
|
|
||||||
|
presentModeText->Update(textDrawer);
|
||||||
|
};
|
||||||
|
|
||||||
|
UpdatePresentModeText();
|
||||||
|
|
||||||
|
entt::handle textEntity = world.CreateEntity();
|
||||||
|
{
|
||||||
|
textEntity.emplace<Nz::NodeComponent>();
|
||||||
|
textEntity.emplace<Nz::GraphicsComponent>(presentModeText);
|
||||||
|
}
|
||||||
|
|
||||||
|
entt::handle spriteEntity = world.CreateEntity();
|
||||||
|
{
|
||||||
|
std::shared_ptr<Nz::Sprite> sprite = std::make_shared<Nz::Sprite>(Nz::MaterialInstance::GetDefault(Nz::MaterialType::Basic));
|
||||||
|
sprite->SetSize({ 128.f, 128.f });
|
||||||
|
|
||||||
|
spriteEntity.emplace<Nz::NodeComponent>();
|
||||||
|
spriteEntity.emplace<Nz::GraphicsComponent>(sprite);
|
||||||
|
}
|
||||||
|
|
||||||
|
Nz::WindowEventHandler& eventHandler = window.GetEventHandler();
|
||||||
|
eventHandler.OnKeyPressed.Connect([&](const Nz::WindowEventHandler*, const Nz::WindowEvent::KeyEvent& event)
|
||||||
|
{
|
||||||
|
if (event.virtualKey == Nz::Keyboard::VKey::Add)
|
||||||
|
{
|
||||||
|
++presentFlagIt;
|
||||||
|
if (presentFlagIt == supportedPresentModes.end())
|
||||||
|
presentFlagIt = supportedPresentModes.begin();
|
||||||
|
|
||||||
|
swapchain.SetPresentMode(*presentFlagIt);
|
||||||
|
UpdatePresentModeText();
|
||||||
|
}
|
||||||
|
else if (event.virtualKey == Nz::Keyboard::VKey::Subtract)
|
||||||
|
{
|
||||||
|
if (presentFlagIt == supportedPresentModes.begin())
|
||||||
|
presentFlagIt = supportedPresentModes.end();
|
||||||
|
|
||||||
|
--presentFlagIt;
|
||||||
|
|
||||||
|
swapchain.SetPresentMode(*presentFlagIt);
|
||||||
|
UpdatePresentModeText();
|
||||||
|
}
|
||||||
|
else if (event.virtualKey == Nz::Keyboard::VKey::Multiply)
|
||||||
|
{
|
||||||
|
limitFps = !limitFps;
|
||||||
|
UpdatePresentModeText();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Nz::Time accumulatorTime = Nz::Time::Zero();
|
||||||
|
constexpr Nz::Time timeToMove = Nz::Time::Second();
|
||||||
|
|
||||||
|
Nz::HighPrecisionClock fpsLimitClock;
|
||||||
|
Nz::MillisecondClock fpsClock;
|
||||||
|
unsigned int fps = 0;
|
||||||
|
bool forward = true;
|
||||||
|
app.AddUpdaterFunc([&](Nz::Time elapsedTime)
|
||||||
|
{
|
||||||
|
// Move sprite
|
||||||
|
if (forward)
|
||||||
|
{
|
||||||
|
accumulatorTime += elapsedTime;
|
||||||
|
if (accumulatorTime >= timeToMove)
|
||||||
|
forward = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
accumulatorTime -= elapsedTime;
|
||||||
|
if (accumulatorTime <= Nz::Time::Zero())
|
||||||
|
forward = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
float delta = (accumulatorTime.AsSeconds() / timeToMove.AsSeconds());
|
||||||
|
|
||||||
|
spriteEntity.get<Nz::NodeComponent>().SetPosition(Nz::Lerp(0.f, windowSize.x - 128.f, delta * delta * (3.f - 2.f * delta)), windowSize.y / 2.f - 128.f / 2.f, 0.f);
|
||||||
|
|
||||||
|
// Limit FPS
|
||||||
|
if (limitFps)
|
||||||
|
{
|
||||||
|
Nz::Time remainingTime = Nz::Time::TickDuration(50) - fpsLimitClock.GetElapsedTime();
|
||||||
|
if (remainingTime > Nz::Time::Zero())
|
||||||
|
std::this_thread::sleep_for(remainingTime.AsDuration<std::chrono::milliseconds>());
|
||||||
|
|
||||||
|
fpsLimitClock.Restart();
|
||||||
|
}
|
||||||
|
|
||||||
|
// FPS update
|
||||||
|
fps++;
|
||||||
|
|
||||||
|
if (fpsClock.RestartIfOver(Nz::Time::Second()))
|
||||||
|
{
|
||||||
|
window.SetTitle(windowTitle + " - " + Nz::NumberToString(fps) + " FPS");
|
||||||
|
fps = 0;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return app.Run();
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
target("PresentModeTest")
|
||||||
|
add_deps("NazaraGraphics")
|
||||||
|
add_packages("entt")
|
||||||
|
add_defines("NAZARA_ENTT")
|
||||||
|
add_files("main.cpp")
|
||||||
Loading…
Reference in New Issue