Replace RenderWindow with swapchains
This commit is contained in:
parent
8db1c04568
commit
18851c9185
|
|
@ -13,6 +13,7 @@
|
|||
#include <Nazara/Graphics/Graphics.hpp>
|
||||
#include <Nazara/Graphics/Components/GraphicsComponent.hpp>
|
||||
#include <Nazara/Graphics/Components/LightComponent.hpp>
|
||||
#include <Nazara/Renderer/WindowSwapchain.hpp>
|
||||
#include <Nazara/Utility/Node.hpp>
|
||||
#include <Nazara/Utility/Skeleton.hpp>
|
||||
#include <Nazara/Utils/MemoryPool.hpp>
|
||||
|
|
@ -27,7 +28,6 @@ namespace Nz
|
|||
class CommandBufferBuilder;
|
||||
class FramePipeline;
|
||||
class RenderFrame;
|
||||
class RenderWindow;
|
||||
class UploadPool;
|
||||
|
||||
class NAZARA_GRAPHICS_API RenderSystem
|
||||
|
|
@ -41,7 +41,7 @@ namespace Nz
|
|||
RenderSystem(RenderSystem&&) = delete;
|
||||
~RenderSystem();
|
||||
|
||||
template<typename T = RenderWindow, typename... Args> T& CreateWindow(Args&&... args);
|
||||
WindowSwapchain& CreateSwapchain(Window& window, const SwapchainParameters& parameters = SwapchainParameters{});
|
||||
|
||||
inline FramePipeline& GetFramePipeline();
|
||||
inline const FramePipeline& GetFramePipeline() const;
|
||||
|
|
@ -133,7 +133,7 @@ namespace Nz
|
|||
std::unordered_set<GraphicsEntity*> m_newlyVisibleGfxEntities;
|
||||
std::unordered_set<LightEntity*> m_newlyHiddenLightEntities;
|
||||
std::unordered_set<LightEntity*> m_newlyVisibleLightEntities;
|
||||
std::vector<std::unique_ptr<RenderWindow>> m_renderWindows;
|
||||
std::vector<std::unique_ptr<WindowSwapchain>> m_windowSwapchains;
|
||||
ElementRendererRegistry m_elementRegistry;
|
||||
MemoryPool<CameraEntity> m_cameraEntityPool;
|
||||
MemoryPool<GraphicsEntity> m_graphicsEntityPool;
|
||||
|
|
|
|||
|
|
@ -8,19 +8,6 @@
|
|||
|
||||
namespace Nz
|
||||
{
|
||||
template<typename T, typename ...Args>
|
||||
T& RenderSystem::CreateWindow(Args&& ...args)
|
||||
{
|
||||
static_assert(std::is_base_of_v<RenderWindow, T>, "T must inherit RenderWindow");
|
||||
|
||||
auto windowPtr = std::make_unique<T>(std::forward<Args>(args)...);
|
||||
T& windowRef = *windowPtr;
|
||||
|
||||
m_renderWindows.emplace_back(std::move(windowPtr));
|
||||
|
||||
return windowRef;
|
||||
}
|
||||
|
||||
inline FramePipeline& RenderSystem::GetFramePipeline()
|
||||
{
|
||||
return *m_pipeline;
|
||||
|
|
|
|||
|
|
@ -30,7 +30,6 @@
|
|||
#define NAZARA_GLOBAL_OPENGLRENDERER_HPP
|
||||
|
||||
#include <Nazara/OpenGLRenderer/Config.hpp>
|
||||
#include <Nazara/OpenGLRenderer/DummySurface.hpp>
|
||||
#include <Nazara/OpenGLRenderer/OpenGLBuffer.hpp>
|
||||
#include <Nazara/OpenGLRenderer/OpenGLCommandBuffer.hpp>
|
||||
#include <Nazara/OpenGLRenderer/OpenGLCommandBufferBuilder.hpp>
|
||||
|
|
@ -44,9 +43,9 @@
|
|||
#include <Nazara/OpenGLRenderer/OpenGLRenderPass.hpp>
|
||||
#include <Nazara/OpenGLRenderer/OpenGLRenderPipeline.hpp>
|
||||
#include <Nazara/OpenGLRenderer/OpenGLRenderPipelineLayout.hpp>
|
||||
#include <Nazara/OpenGLRenderer/OpenGLRenderWindow.hpp>
|
||||
#include <Nazara/OpenGLRenderer/OpenGLShaderBinding.hpp>
|
||||
#include <Nazara/OpenGLRenderer/OpenGLShaderModule.hpp>
|
||||
#include <Nazara/OpenGLRenderer/OpenGLSwapchain.hpp>
|
||||
#include <Nazara/OpenGLRenderer/OpenGLTexture.hpp>
|
||||
#include <Nazara/OpenGLRenderer/OpenGLTextureSampler.hpp>
|
||||
#include <Nazara/OpenGLRenderer/OpenGLUploadPool.hpp>
|
||||
|
|
|
|||
|
|
@ -1,34 +0,0 @@
|
|||
// Copyright (C) 2022 Jérôme "Lynix" Leclercq (lynix680@gmail.com)
|
||||
// This file is part of the "Nazara Engine - OpenGL renderer"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef NAZARA_OPENGLRENDERER_DUMMYSURFACE_HPP
|
||||
#define NAZARA_OPENGLRENDERER_DUMMYSURFACE_HPP
|
||||
|
||||
#include <Nazara/Prerequisites.hpp>
|
||||
#include <Nazara/OpenGLRenderer/Config.hpp>
|
||||
#include <Nazara/Renderer/RenderSurface.hpp>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
class NAZARA_OPENGLRENDERER_API DummySurface : public RenderSurface
|
||||
{
|
||||
public:
|
||||
DummySurface() = default;
|
||||
~DummySurface() = default;
|
||||
|
||||
bool Create(WindowHandle handle) override;
|
||||
void Destroy() override;
|
||||
|
||||
inline WindowHandle GetWindowHandle() const;
|
||||
|
||||
private:
|
||||
WindowHandle m_handle;
|
||||
};
|
||||
}
|
||||
|
||||
#include <Nazara/OpenGLRenderer/DummySurface.inl>
|
||||
|
||||
#endif // NAZARA_OPENGLRENDERER_DUMMYSURFACE_HPP
|
||||
|
|
@ -1,16 +0,0 @@
|
|||
// Copyright (C) 2022 Jérôme "Lynix" Leclercq (lynix680@gmail.com)
|
||||
// This file is part of the "Nazara Engine - OpenGL renderer"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#include <Nazara/OpenGLRenderer/DummySurface.hpp>
|
||||
#include <Nazara/OpenGLRenderer/Debug.hpp>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
inline WindowHandle DummySurface::GetWindowHandle() const
|
||||
{
|
||||
return m_handle;
|
||||
}
|
||||
}
|
||||
|
||||
#include <Nazara/OpenGLRenderer/DebugOff.hpp>
|
||||
|
|
@ -45,6 +45,7 @@ namespace Nz
|
|||
std::shared_ptr<RenderPipelineLayout> InstantiateRenderPipelineLayout(RenderPipelineLayoutInfo pipelineLayoutInfo) override;
|
||||
std::shared_ptr<ShaderModule> InstantiateShaderModule(nzsl::ShaderStageTypeFlags shaderStages, const nzsl::Ast::Module& shaderModule, const nzsl::ShaderWriter::States& states) override;
|
||||
std::shared_ptr<ShaderModule> InstantiateShaderModule(nzsl::ShaderStageTypeFlags shaderStages, ShaderLanguage lang, const void* source, std::size_t sourceSize, const nzsl::ShaderWriter::States& states) override;
|
||||
std::shared_ptr<Swapchain> InstantiateSwapchain(WindowHandle windowHandle, const Vector2ui& windowSize, const SwapchainParameters& parameters) override;
|
||||
std::shared_ptr<Texture> InstantiateTexture(const TextureInfo& params) override;
|
||||
std::shared_ptr<TextureSampler> InstantiateTextureSampler(const TextureSamplerInfo& params) override;
|
||||
|
||||
|
|
|
|||
|
|
@ -15,12 +15,12 @@
|
|||
namespace Nz
|
||||
{
|
||||
class OpenGLCommandBuffer;
|
||||
class OpenGLRenderWindow;
|
||||
class OpenGLSwapchain;
|
||||
|
||||
class NAZARA_OPENGLRENDERER_API OpenGLRenderImage : public RenderImage
|
||||
{
|
||||
public:
|
||||
OpenGLRenderImage(OpenGLRenderWindow& owner);
|
||||
OpenGLRenderImage(OpenGLSwapchain& owner);
|
||||
|
||||
void Execute(const FunctionRef<void(CommandBufferBuilder& builder)>& callback, QueueTypeFlags queueTypeFlags) override;
|
||||
|
||||
|
|
@ -31,7 +31,7 @@ namespace Nz
|
|||
void SubmitCommandBuffer(CommandBuffer* commandBuffer, QueueTypeFlags queueTypeFlags) override;
|
||||
|
||||
private:
|
||||
OpenGLRenderWindow& m_owner;
|
||||
OpenGLSwapchain& m_owner;
|
||||
OpenGLUploadPool m_uploadPool;
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,9 +22,6 @@ namespace Nz
|
|||
OpenGLRenderer() = default;
|
||||
~OpenGLRenderer();
|
||||
|
||||
std::unique_ptr<RenderSurface> CreateRenderSurfaceImpl() override;
|
||||
std::unique_ptr<RenderWindowImpl> CreateRenderWindowImpl(RenderWindow& owner) override;
|
||||
|
||||
std::shared_ptr<RenderDevice> InstanciateRenderDevice(std::size_t deviceIndex, const RenderDeviceFeatures& enabledFeatures) override;
|
||||
|
||||
RenderAPI QueryAPI() const override;
|
||||
|
|
|
|||
|
|
@ -14,23 +14,21 @@
|
|||
#include <Nazara/OpenGLRenderer/OpenGLRenderPass.hpp>
|
||||
#include <Nazara/OpenGLRenderer/OpenGLWindowFramebuffer.hpp>
|
||||
#include <Nazara/OpenGLRenderer/Wrapper/Context.hpp>
|
||||
#include <Nazara/Renderer/RenderWindowImpl.hpp>
|
||||
#include <Nazara/Renderer/Swapchain.hpp>
|
||||
#include <Nazara/Renderer/SwapchainParameters.hpp>
|
||||
#include <optional>
|
||||
#include <vector>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
class RenderWindow;
|
||||
|
||||
class NAZARA_OPENGLRENDERER_API OpenGLRenderWindow final : public RenderWindowImpl
|
||||
class NAZARA_OPENGLRENDERER_API OpenGLSwapchain final : public Swapchain
|
||||
{
|
||||
public:
|
||||
OpenGLRenderWindow(RenderWindow& owner);
|
||||
~OpenGLRenderWindow() = default;
|
||||
OpenGLSwapchain(OpenGLDevice& device, WindowHandle windowHandle, const Vector2ui& windowSize, const SwapchainParameters& parameters);
|
||||
~OpenGLSwapchain() = default;
|
||||
|
||||
RenderFrame Acquire() override;
|
||||
RenderFrame AcquireFrame() override;
|
||||
|
||||
bool Create(RendererImpl* renderer, RenderSurface* surface, const RenderWindowParameters& parameters) override;
|
||||
std::shared_ptr<CommandPool> CreateCommandPool(QueueType queueType) override;
|
||||
|
||||
inline GL::Context& GetContext();
|
||||
|
|
@ -39,6 +37,8 @@ namespace Nz
|
|||
const OpenGLRenderPass& GetRenderPass() const override;
|
||||
const Vector2ui& GetSize() const override;
|
||||
|
||||
void NotifyResize(const Vector2ui& newSize) override;
|
||||
|
||||
void Present();
|
||||
|
||||
private:
|
||||
|
|
@ -47,11 +47,11 @@ namespace Nz
|
|||
std::vector<std::unique_ptr<OpenGLRenderImage>> m_renderImage;
|
||||
std::unique_ptr<GL::Context> m_context;
|
||||
OpenGLWindowFramebuffer m_framebuffer;
|
||||
RenderWindow& m_owner;
|
||||
Vector2ui m_size;
|
||||
bool m_sizeInvalidated;
|
||||
};
|
||||
}
|
||||
|
||||
#include <Nazara/OpenGLRenderer/OpenGLRenderWindow.inl>
|
||||
#include <Nazara/OpenGLRenderer/OpenGLSwapchain.inl>
|
||||
|
||||
#endif // NAZARA_OPENGLRENDERER_OPENGLRENDERWINDOW_HPP
|
||||
|
|
@ -2,13 +2,13 @@
|
|||
// This file is part of the "Nazara Engine - OpenGL renderer"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#include <Nazara/OpenGLRenderer/OpenGLRenderWindow.hpp>
|
||||
#include <Nazara/OpenGLRenderer/OpenGLSwapchain.hpp>
|
||||
#include <cassert>
|
||||
#include <Nazara/OpenGLRenderer/Debug.hpp>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
inline GL::Context& OpenGLRenderWindow::GetContext()
|
||||
inline GL::Context& OpenGLSwapchain::GetContext()
|
||||
{
|
||||
assert(m_context);
|
||||
return *m_context;
|
||||
|
|
@ -12,12 +12,12 @@
|
|||
|
||||
namespace Nz
|
||||
{
|
||||
class OpenGLRenderWindow;
|
||||
class OpenGLSwapchain;
|
||||
|
||||
class NAZARA_OPENGLRENDERER_API OpenGLWindowFramebuffer : public OpenGLFramebuffer
|
||||
{
|
||||
public:
|
||||
inline OpenGLWindowFramebuffer(OpenGLRenderWindow& renderWindow);
|
||||
inline OpenGLWindowFramebuffer(OpenGLSwapchain& renderWindow);
|
||||
OpenGLWindowFramebuffer(const OpenGLWindowFramebuffer&) = delete;
|
||||
OpenGLWindowFramebuffer(OpenGLWindowFramebuffer&&) noexcept = default;
|
||||
~OpenGLWindowFramebuffer() = default;
|
||||
|
|
@ -34,7 +34,7 @@ namespace Nz
|
|||
OpenGLWindowFramebuffer& operator=(OpenGLWindowFramebuffer&&) = delete;
|
||||
|
||||
private:
|
||||
OpenGLRenderWindow& m_renderWindow;
|
||||
OpenGLSwapchain& m_renderWindow;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
namespace Nz
|
||||
{
|
||||
inline OpenGLWindowFramebuffer::OpenGLWindowFramebuffer(OpenGLRenderWindow& renderWindow) :
|
||||
inline OpenGLWindowFramebuffer::OpenGLWindowFramebuffer(OpenGLSwapchain& renderWindow) :
|
||||
OpenGLFramebuffer(FramebufferType::Window),
|
||||
m_renderWindow(renderWindow)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -34,8 +34,8 @@
|
|||
#include <Nazara/Platform/Cursor.hpp>
|
||||
#include <Nazara/Platform/CursorController.hpp>
|
||||
#include <Nazara/Platform/Enums.hpp>
|
||||
#include <Nazara/Platform/Event.hpp>
|
||||
#include <Nazara/Platform/EventHandler.hpp>
|
||||
#include <Nazara/Platform/WindowEvent.hpp>
|
||||
#include <Nazara/Platform/WindowEventHandler.hpp>
|
||||
#include <Nazara/Platform/Icon.hpp>
|
||||
#include <Nazara/Platform/Joystick.hpp>
|
||||
#include <Nazara/Platform/Keyboard.hpp>
|
||||
|
|
|
|||
|
|
@ -48,10 +48,13 @@ namespace Nz
|
|||
|
||||
enum class WindowEventType
|
||||
{
|
||||
Created,
|
||||
Destruction,
|
||||
GainedFocus,
|
||||
LostFocus,
|
||||
KeyPressed,
|
||||
KeyReleased,
|
||||
Minimized,
|
||||
MouseButtonPressed,
|
||||
MouseButtonReleased,
|
||||
MouseEntered,
|
||||
|
|
@ -61,6 +64,7 @@ namespace Nz
|
|||
Moved,
|
||||
Quit,
|
||||
Resized,
|
||||
Restored,
|
||||
TextEdited,
|
||||
TextEntered,
|
||||
|
||||
|
|
|
|||
|
|
@ -1,57 +0,0 @@
|
|||
// Copyright (C) 2022 Jérôme "Lynix" Leclercq (lynix680@gmail.com)
|
||||
// This file is part of the "Nazara Engine - Platform module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef NAZARA_PLATFORM_EVENTHANDLER_HPP
|
||||
#define NAZARA_PLATFORM_EVENTHANDLER_HPP
|
||||
|
||||
#include <Nazara/Prerequisites.hpp>
|
||||
#include <Nazara/Core/HandledObject.hpp>
|
||||
#include <Nazara/Core/ObjectHandle.hpp>
|
||||
#include <Nazara/Platform/Config.hpp>
|
||||
#include <Nazara/Platform/Event.hpp>
|
||||
#include <Nazara/Utils/Signal.hpp>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
class EventHandler;
|
||||
|
||||
using EventHandlerHandle = ObjectHandle<EventHandler>;
|
||||
|
||||
class EventHandler : public HandledObject<EventHandler>
|
||||
{
|
||||
public:
|
||||
EventHandler() = default;
|
||||
explicit EventHandler(const EventHandler&);
|
||||
EventHandler(EventHandler&&) noexcept = default;
|
||||
~EventHandler() = default;
|
||||
|
||||
inline void Dispatch(const WindowEvent& event);
|
||||
|
||||
EventHandler& operator=(const EventHandler&) = delete;
|
||||
EventHandler& operator=(EventHandler&&) noexcept = default;
|
||||
|
||||
NazaraSignal(OnEvent, const EventHandler* /*eventHandler*/, const WindowEvent& /*event*/);
|
||||
NazaraSignal(OnGainedFocus, const EventHandler* /*eventHandler*/);
|
||||
NazaraSignal(OnLostFocus, const EventHandler* /*eventHandler*/);
|
||||
NazaraSignal(OnKeyPressed, const EventHandler* /*eventHandler*/, const WindowEvent::KeyEvent& /*event*/);
|
||||
NazaraSignal(OnKeyReleased, const EventHandler* /*eventHandler*/, const WindowEvent::KeyEvent& /*event*/);
|
||||
NazaraSignal(OnMouseButtonPressed, const EventHandler* /*eventHandler*/, const WindowEvent::MouseButtonEvent& /*event*/);
|
||||
NazaraSignal(OnMouseButtonReleased, const EventHandler* /*eventHandler*/, const WindowEvent::MouseButtonEvent& /*event*/);
|
||||
NazaraSignal(OnMouseEntered, const EventHandler* /*eventHandler*/);
|
||||
NazaraSignal(OnMouseLeft, const EventHandler* /*eventHandler*/);
|
||||
NazaraSignal(OnMouseMoved, const EventHandler* /*eventHandler*/, const WindowEvent::MouseMoveEvent& /*event*/);
|
||||
NazaraSignal(OnMouseWheelMoved, const EventHandler* /*eventHandler*/, const WindowEvent::MouseWheelEvent& /*event*/);
|
||||
NazaraSignal(OnMoved, const EventHandler* /*eventHandler*/, const WindowEvent::PositionEvent& /*event*/);
|
||||
NazaraSignal(OnQuit, const EventHandler* /*eventHandler*/);
|
||||
NazaraSignal(OnResized, const EventHandler* /*eventHandler*/, const WindowEvent::SizeEvent& /*event*/);
|
||||
NazaraSignal(OnTextEntered, const EventHandler* /*eventHandler*/, const WindowEvent::TextEvent& /*event*/);
|
||||
NazaraSignal(OnTextEdited, const EventHandler* /*eventHandler*/, const WindowEvent::EditEvent& /*event*/);
|
||||
};
|
||||
}
|
||||
|
||||
#include <Nazara/Platform/EventHandler.inl>
|
||||
|
||||
#endif // NAZARA_PLATFORM_EVENTHANDLER_HPP
|
||||
|
|
@ -15,7 +15,7 @@
|
|||
#include <Nazara/Platform/Cursor.hpp>
|
||||
#include <Nazara/Platform/CursorController.hpp>
|
||||
#include <Nazara/Platform/Enums.hpp>
|
||||
#include <Nazara/Platform/EventHandler.hpp>
|
||||
#include <Nazara/Platform/WindowEventHandler.hpp>
|
||||
#include <Nazara/Platform/Icon.hpp>
|
||||
#include <Nazara/Platform/VideoMode.hpp>
|
||||
#include <Nazara/Platform/WindowHandle.hpp>
|
||||
|
|
@ -38,35 +38,31 @@ namespace Nz
|
|||
public:
|
||||
Window();
|
||||
inline Window(VideoMode mode, const std::string& title, WindowStyleFlags style = WindowStyle_Default);
|
||||
inline explicit Window(void* handle);
|
||||
inline explicit Window(WindowHandle handle);
|
||||
Window(const Window&) = delete;
|
||||
Window(Window&& window);
|
||||
virtual ~Window();
|
||||
Window(Window&& window) noexcept;
|
||||
~Window();
|
||||
|
||||
inline void Close();
|
||||
|
||||
bool Create(VideoMode mode, const std::string& title, WindowStyleFlags style = WindowStyle_Default);
|
||||
bool Create(void* handle);
|
||||
bool Create(WindowHandle handle);
|
||||
|
||||
void Destroy();
|
||||
|
||||
inline void EnableCloseOnQuit(bool closeOnQuit);
|
||||
|
||||
NAZARA_DEPRECATED("Event pooling/waiting is deprecated, please use the EventHandler system")
|
||||
inline void EnableEventPolling(bool enable);
|
||||
|
||||
void EnableKeyRepeat(bool enable);
|
||||
void EnableSmoothScrolling(bool enable);
|
||||
|
||||
inline const std::shared_ptr<Cursor>& GetCursor() const;
|
||||
inline CursorController& GetCursorController();
|
||||
inline EventHandler& GetEventHandler();
|
||||
inline WindowEventHandler& GetEventHandler();
|
||||
WindowHandle GetHandle() const;
|
||||
Vector2i GetPosition() const;
|
||||
Vector2ui GetSize() const;
|
||||
WindowStyleFlags GetStyle() const;
|
||||
WindowHandle GetSystemHandle() const;
|
||||
std::string GetTitle() const;
|
||||
|
||||
void HandleEvent(const WindowEvent& event);
|
||||
|
||||
bool HasFocus() const;
|
||||
|
||||
bool IsMinimized() const;
|
||||
|
|
@ -75,16 +71,8 @@ namespace Nz
|
|||
inline bool IsValid() const;
|
||||
bool IsVisible() const;
|
||||
|
||||
NAZARA_DEPRECATED("Event pooling/waiting is deprecated, please use the EventHandler system")
|
||||
bool PollEvent(WindowEvent* event);
|
||||
|
||||
void PushEvent(const WindowEvent& event);
|
||||
|
||||
void ProcessEvents(bool block = false);
|
||||
|
||||
void SetCursor(std::shared_ptr<Cursor> cursor);
|
||||
inline void SetCursor(SystemCursor systemCursor);
|
||||
void SetEventListener(bool listener);
|
||||
void SetFocus();
|
||||
void SetIcon(std::shared_ptr<Icon> icon);
|
||||
void SetMaximumSize(const Vector2i& maxSize);
|
||||
|
|
@ -99,20 +87,10 @@ namespace Nz
|
|||
void SetTitle(const std::string& title);
|
||||
void SetVisible(bool visible);
|
||||
|
||||
NAZARA_DEPRECATED("Event pooling/waiting is deprecated, please use the EventHandler system")
|
||||
bool WaitEvent(WindowEvent* event);
|
||||
|
||||
Window& operator=(const Window&) = delete;
|
||||
Window& operator=(Window&& window);
|
||||
Window& operator=(Window&& window) noexcept;
|
||||
|
||||
protected:
|
||||
void* GetHandle();
|
||||
|
||||
virtual bool OnWindowCreated();
|
||||
virtual void OnWindowDestroy();
|
||||
virtual void OnWindowResized();
|
||||
|
||||
MovablePtr<WindowImpl> m_impl;
|
||||
static void ProcessEvents();
|
||||
|
||||
private:
|
||||
void ConnectSlots();
|
||||
|
|
@ -122,26 +100,21 @@ namespace Nz
|
|||
inline const WindowImpl* GetImpl() const;
|
||||
|
||||
void IgnoreNextMouseEvent(int mouseX, int mouseY) const;
|
||||
void HandleEvent(const WindowEvent& event);
|
||||
|
||||
static bool Initialize();
|
||||
static void Uninitialize();
|
||||
|
||||
NazaraSlot(CursorController, OnCursorUpdated, m_cursorUpdateSlot);
|
||||
|
||||
std::queue<WindowEvent> m_events;
|
||||
std::vector<WindowEvent> m_pendingEvents;
|
||||
std::condition_variable m_eventCondition;
|
||||
CursorController m_cursorController;
|
||||
std::shared_ptr<Cursor> m_cursor;
|
||||
EventHandler m_eventHandler;
|
||||
std::shared_ptr<Icon> m_icon;
|
||||
std::mutex m_eventMutex;
|
||||
std::mutex m_eventConditionMutex;
|
||||
bool m_asyncWindow;
|
||||
std::unique_ptr<WindowImpl> m_impl;
|
||||
CursorController m_cursorController;
|
||||
Vector2i m_position;
|
||||
Vector2ui m_size;
|
||||
WindowEventHandler m_eventHandler;
|
||||
bool m_closed;
|
||||
bool m_closeOnQuit;
|
||||
bool m_eventPolling;
|
||||
bool m_ownsWindow;
|
||||
bool m_waitForEvent;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ namespace Nz
|
|||
Create(mode, title, style);
|
||||
}
|
||||
|
||||
inline Window::Window(void* handle) :
|
||||
inline Window::Window(WindowHandle handle) :
|
||||
Window()
|
||||
{
|
||||
ErrorFlags flags(ErrorMode::ThrowException, true);
|
||||
|
|
@ -36,16 +36,6 @@ namespace Nz
|
|||
m_closeOnQuit = closeOnQuit;
|
||||
}
|
||||
|
||||
inline void Window::EnableEventPolling(bool enable)
|
||||
{
|
||||
m_eventPolling = enable;
|
||||
if (!m_eventPolling)
|
||||
{
|
||||
while (!m_events.empty())
|
||||
m_events.pop();
|
||||
}
|
||||
}
|
||||
|
||||
inline const std::shared_ptr<Cursor>& Window::GetCursor() const
|
||||
{
|
||||
return m_cursor;
|
||||
|
|
@ -56,7 +46,7 @@ namespace Nz
|
|||
return m_cursorController;
|
||||
}
|
||||
|
||||
inline EventHandler& Nz::Window::GetEventHandler()
|
||||
inline WindowEventHandler& Nz::Window::GetEventHandler()
|
||||
{
|
||||
return m_eventHandler;
|
||||
}
|
||||
|
|
@ -90,34 +80,14 @@ namespace Nz
|
|||
SetCursor(Cursor::Get(systemCursor));
|
||||
}
|
||||
|
||||
inline void Window::PushEvent(const WindowEvent& event)
|
||||
{
|
||||
if (!m_asyncWindow)
|
||||
HandleEvent(event);
|
||||
else
|
||||
{
|
||||
{
|
||||
std::lock_guard<std::mutex> eventLock(m_eventMutex);
|
||||
|
||||
m_pendingEvents.push_back(event);
|
||||
}
|
||||
|
||||
if (m_waitForEvent)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_eventConditionMutex);
|
||||
m_eventCondition.notify_all();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inline WindowImpl* Window::GetImpl()
|
||||
{
|
||||
return m_impl;
|
||||
return m_impl.get();
|
||||
}
|
||||
|
||||
inline const WindowImpl* Window::GetImpl() const
|
||||
{
|
||||
return m_impl;
|
||||
return m_impl.get();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -9,11 +9,10 @@
|
|||
#ifndef NAZARA_PLATFORM_EVENT_HPP
|
||||
#define NAZARA_PLATFORM_EVENT_HPP
|
||||
|
||||
#include <array>
|
||||
|
||||
#include <Nazara/Platform/Enums.hpp>
|
||||
#include <Nazara/Platform/Keyboard.hpp>
|
||||
#include <Nazara/Platform/Mouse.hpp>
|
||||
#include <array>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
|
|
@ -0,0 +1,61 @@
|
|||
// Copyright (C) 2022 Jérôme "Lynix" Leclercq (lynix680@gmail.com)
|
||||
// This file is part of the "Nazara Engine - Platform module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef NAZARA_PLATFORM_EVENTHANDLER_HPP
|
||||
#define NAZARA_PLATFORM_EVENTHANDLER_HPP
|
||||
|
||||
#include <Nazara/Prerequisites.hpp>
|
||||
#include <Nazara/Core/HandledObject.hpp>
|
||||
#include <Nazara/Core/ObjectHandle.hpp>
|
||||
#include <Nazara/Platform/Config.hpp>
|
||||
#include <Nazara/Platform/WindowEvent.hpp>
|
||||
#include <Nazara/Utils/Signal.hpp>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
class WindowEventHandler;
|
||||
|
||||
using EventHandlerHandle = ObjectHandle<WindowEventHandler>;
|
||||
|
||||
class WindowEventHandler : public HandledObject<WindowEventHandler>
|
||||
{
|
||||
public:
|
||||
WindowEventHandler() = default;
|
||||
explicit WindowEventHandler(const WindowEventHandler&);
|
||||
WindowEventHandler(WindowEventHandler&&) noexcept = default;
|
||||
~WindowEventHandler() = default;
|
||||
|
||||
inline void Dispatch(const WindowEvent& event);
|
||||
|
||||
WindowEventHandler& operator=(const WindowEventHandler&) = delete;
|
||||
WindowEventHandler& operator=(WindowEventHandler&&) noexcept = default;
|
||||
|
||||
NazaraSignal(OnCreated, const WindowEventHandler* /*eventHandler*/);
|
||||
NazaraSignal(OnDestruction, const WindowEventHandler* /*eventHandler*/);
|
||||
NazaraSignal(OnEvent, const WindowEventHandler* /*eventHandler*/, const WindowEvent& /*event*/);
|
||||
NazaraSignal(OnGainedFocus, const WindowEventHandler* /*eventHandler*/);
|
||||
NazaraSignal(OnLostFocus, const WindowEventHandler* /*eventHandler*/);
|
||||
NazaraSignal(OnKeyPressed, const WindowEventHandler* /*eventHandler*/, const WindowEvent::KeyEvent& /*event*/);
|
||||
NazaraSignal(OnKeyReleased, const WindowEventHandler* /*eventHandler*/, const WindowEvent::KeyEvent& /*event*/);
|
||||
NazaraSignal(OnMinimized, const WindowEventHandler* /*eventHandler*/);
|
||||
NazaraSignal(OnMouseButtonPressed, const WindowEventHandler* /*eventHandler*/, const WindowEvent::MouseButtonEvent& /*event*/);
|
||||
NazaraSignal(OnMouseButtonReleased, const WindowEventHandler* /*eventHandler*/, const WindowEvent::MouseButtonEvent& /*event*/);
|
||||
NazaraSignal(OnMouseEntered, const WindowEventHandler* /*eventHandler*/);
|
||||
NazaraSignal(OnMouseLeft, const WindowEventHandler* /*eventHandler*/);
|
||||
NazaraSignal(OnMouseMoved, const WindowEventHandler* /*eventHandler*/, const WindowEvent::MouseMoveEvent& /*event*/);
|
||||
NazaraSignal(OnMouseWheelMoved, const WindowEventHandler* /*eventHandler*/, const WindowEvent::MouseWheelEvent& /*event*/);
|
||||
NazaraSignal(OnMoved, const WindowEventHandler* /*eventHandler*/, const WindowEvent::PositionEvent& /*event*/);
|
||||
NazaraSignal(OnQuit, const WindowEventHandler* /*eventHandler*/);
|
||||
NazaraSignal(OnResized, const WindowEventHandler* /*eventHandler*/, const WindowEvent::SizeEvent& /*event*/);
|
||||
NazaraSignal(OnRestored, const WindowEventHandler* /*eventHandler*/);
|
||||
NazaraSignal(OnTextEntered, const WindowEventHandler* /*eventHandler*/, const WindowEvent::TextEvent& /*event*/);
|
||||
NazaraSignal(OnTextEdited, const WindowEventHandler* /*eventHandler*/, const WindowEvent::EditEvent& /*event*/);
|
||||
};
|
||||
}
|
||||
|
||||
#include <Nazara/Platform/WindowEventHandler.inl>
|
||||
|
||||
#endif // NAZARA_PLATFORM_EVENTHANDLER_HPP
|
||||
|
|
@ -2,23 +2,31 @@
|
|||
// This file is part of the "Nazara Engine - Platform module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#include <Nazara/Platform/EventHandler.hpp>
|
||||
#include <Nazara/Platform/WindowEventHandler.hpp>
|
||||
#include <memory>
|
||||
#include <Nazara/Platform/Debug.hpp>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
inline EventHandler::EventHandler(const EventHandler& other) :
|
||||
inline WindowEventHandler::WindowEventHandler(const WindowEventHandler& other) :
|
||||
HandledObject(other)
|
||||
{
|
||||
}
|
||||
|
||||
inline void EventHandler::Dispatch(const WindowEvent& event)
|
||||
inline void WindowEventHandler::Dispatch(const WindowEvent& event)
|
||||
{
|
||||
OnEvent(this, event);
|
||||
|
||||
switch (event.type)
|
||||
{
|
||||
case WindowEventType::Created:
|
||||
OnCreated(this);
|
||||
break;
|
||||
|
||||
case WindowEventType::Destruction:
|
||||
OnDestruction(this);
|
||||
break;
|
||||
|
||||
case WindowEventType::GainedFocus:
|
||||
OnGainedFocus(this);
|
||||
break;
|
||||
|
|
@ -35,6 +43,10 @@ namespace Nz
|
|||
OnLostFocus(this);
|
||||
break;
|
||||
|
||||
case WindowEventType::Minimized:
|
||||
OnMinimized(this);
|
||||
break;
|
||||
|
||||
case WindowEventType::MouseButtonPressed:
|
||||
OnMouseButtonPressed(this, event.mouseButton);
|
||||
break;
|
||||
|
|
@ -71,6 +83,10 @@ namespace Nz
|
|||
OnResized(this, event.size);
|
||||
break;
|
||||
|
||||
case WindowEventType::Restored:
|
||||
OnRestored(this);
|
||||
break;
|
||||
|
||||
case WindowEventType::TextEntered:
|
||||
OnTextEntered(this, event.text);
|
||||
break;
|
||||
|
|
@ -51,15 +51,14 @@
|
|||
#include <Nazara/Renderer/RenderPipeline.hpp>
|
||||
#include <Nazara/Renderer/RenderPipelineLayout.hpp>
|
||||
#include <Nazara/Renderer/RenderStates.hpp>
|
||||
#include <Nazara/Renderer/RenderSurface.hpp>
|
||||
#include <Nazara/Renderer/RenderTarget.hpp>
|
||||
#include <Nazara/Renderer/RenderWindow.hpp>
|
||||
#include <Nazara/Renderer/RenderWindowImpl.hpp>
|
||||
#include <Nazara/Renderer/RenderWindowParameters.hpp>
|
||||
#include <Nazara/Renderer/ShaderBinding.hpp>
|
||||
#include <Nazara/Renderer/ShaderModule.hpp>
|
||||
#include <Nazara/Renderer/Swapchain.hpp>
|
||||
#include <Nazara/Renderer/SwapchainParameters.hpp>
|
||||
#include <Nazara/Renderer/Texture.hpp>
|
||||
#include <Nazara/Renderer/TextureSampler.hpp>
|
||||
#include <Nazara/Renderer/UploadPool.hpp>
|
||||
#include <Nazara/Renderer/WindowSwapchain.hpp>
|
||||
|
||||
#endif // NAZARA_GLOBAL_RENDERER_HPP
|
||||
|
|
|
|||
|
|
@ -17,6 +17,8 @@
|
|||
#include <Nazara/Renderer/RenderPass.hpp>
|
||||
#include <Nazara/Renderer/RenderPipeline.hpp>
|
||||
#include <Nazara/Renderer/RenderPipelineLayout.hpp>
|
||||
#include <Nazara/Renderer/Swapchain.hpp>
|
||||
#include <Nazara/Renderer/SwapchainParameters.hpp>
|
||||
#include <Nazara/Renderer/Texture.hpp>
|
||||
#include <Nazara/Renderer/TextureSampler.hpp>
|
||||
#include <Nazara/Utility/PixelFormat.hpp>
|
||||
|
|
@ -49,6 +51,7 @@ namespace Nz
|
|||
virtual std::shared_ptr<ShaderModule> InstantiateShaderModule(nzsl::ShaderStageTypeFlags shaderStages, const nzsl::Ast::Module& shaderModule, const nzsl::ShaderWriter::States& states) = 0;
|
||||
virtual std::shared_ptr<ShaderModule> InstantiateShaderModule(nzsl::ShaderStageTypeFlags shaderStages, ShaderLanguage lang, const void* source, std::size_t sourceSize, const nzsl::ShaderWriter::States& states) = 0;
|
||||
std::shared_ptr<ShaderModule> InstantiateShaderModule(nzsl::ShaderStageTypeFlags shaderStages, ShaderLanguage lang, const std::filesystem::path& sourcePath, const nzsl::ShaderWriter::States& states);
|
||||
virtual std::shared_ptr<Swapchain> InstantiateSwapchain(WindowHandle windowHandle, const Vector2ui& windowSize, const SwapchainParameters& parameters) = 0;
|
||||
virtual std::shared_ptr<Texture> InstantiateTexture(const TextureInfo& params) = 0;
|
||||
virtual std::shared_ptr<TextureSampler> InstantiateTextureSampler(const TextureSamplerInfo& params) = 0;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,30 +0,0 @@
|
|||
// Copyright (C) 2022 Jérôme "Lynix" Leclercq (lynix680@gmail.com)
|
||||
// This file is part of the "Nazara Engine - Renderer module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef NAZARA_RENDERER_RENDERSURFACE_HPP
|
||||
#define NAZARA_RENDERER_RENDERSURFACE_HPP
|
||||
|
||||
#include <Nazara/Prerequisites.hpp>
|
||||
#include <Nazara/Platform/WindowHandle.hpp>
|
||||
#include <Nazara/Renderer/Config.hpp>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
///TODO: Rename
|
||||
class NAZARA_RENDERER_API RenderSurface
|
||||
{
|
||||
public:
|
||||
RenderSurface() = default;
|
||||
virtual ~RenderSurface();
|
||||
|
||||
virtual bool Create(WindowHandle handle) = 0;
|
||||
virtual void Destroy() = 0;
|
||||
};
|
||||
}
|
||||
|
||||
#include <Nazara/Renderer/RenderSurface.inl>
|
||||
|
||||
#endif // NAZARA_RENDERER_RENDERSURFACE_HPP
|
||||
|
|
@ -1,12 +0,0 @@
|
|||
// Copyright (C) 2022 Jérôme "Lynix" Leclercq (lynix680@gmail.com)
|
||||
// This file is part of the "Nazara Engine - Renderer module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#include <Nazara/Renderer/RenderSurface.hpp>
|
||||
#include <Nazara/Renderer/Debug.hpp>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
}
|
||||
|
||||
#include <Nazara/Renderer/DebugOff.hpp>
|
||||
|
|
@ -1,67 +0,0 @@
|
|||
// Copyright (C) 2022 Jérôme "Lynix" Leclercq (lynix680@gmail.com)
|
||||
// This file is part of the "Nazara Engine - Renderer module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef NAZARA_RENDERER_RENDERWINDOW_HPP
|
||||
#define NAZARA_RENDERER_RENDERWINDOW_HPP
|
||||
|
||||
#include <Nazara/Prerequisites.hpp>
|
||||
#include <Nazara/Core/Clock.hpp>
|
||||
#include <Nazara/Math/Rect.hpp>
|
||||
#include <Nazara/Math/Vector3.hpp>
|
||||
#include <Nazara/Platform/Window.hpp>
|
||||
#include <Nazara/Renderer/RenderSurface.hpp>
|
||||
#include <Nazara/Renderer/RenderWindowImpl.hpp>
|
||||
#include <Nazara/Renderer/RenderWindowParameters.hpp>
|
||||
#include <memory>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
class RenderDevice;
|
||||
|
||||
class NAZARA_RENDERER_API RenderWindow : public Window
|
||||
{
|
||||
public:
|
||||
inline RenderWindow();
|
||||
inline RenderWindow(std::shared_ptr<RenderDevice> renderDevice, VideoMode mode, const std::string& title, WindowStyleFlags style = WindowStyle_Default, const RenderWindowParameters& parameters = RenderWindowParameters());
|
||||
inline RenderWindow(std::shared_ptr<RenderDevice> renderDevice, void* handle, const RenderWindowParameters& parameters = RenderWindowParameters());
|
||||
inline ~RenderWindow();
|
||||
|
||||
RenderFrame AcquireFrame();
|
||||
|
||||
bool Create(std::shared_ptr<RenderDevice> renderDevice, VideoMode mode, const std::string& title, WindowStyleFlags style = WindowStyle_Default, const RenderWindowParameters& parameters = RenderWindowParameters());
|
||||
bool Create(std::shared_ptr<RenderDevice> renderDevice, void* handle, const RenderWindowParameters ¶meters = RenderWindowParameters());
|
||||
|
||||
void EnableVerticalSync(bool enabled);
|
||||
|
||||
inline const std::shared_ptr<RenderDevice>& GetRenderDevice() const;
|
||||
inline const RenderTarget* GetRenderTarget() const;
|
||||
inline RenderSurface* GetSurface();
|
||||
|
||||
inline bool IsValid() const;
|
||||
|
||||
inline void SetFramerateLimit(unsigned int limit);
|
||||
|
||||
RenderWindow &operator=(const RenderWindow &) = delete;
|
||||
RenderWindow &operator=(RenderWindow &&) = delete; ///TODO
|
||||
|
||||
protected:
|
||||
bool OnWindowCreated() override;
|
||||
void OnWindowDestroy() override;
|
||||
void OnWindowResized() override;
|
||||
|
||||
private:
|
||||
std::shared_ptr<RenderDevice> m_renderDevice;
|
||||
std::unique_ptr<RenderSurface> m_surface;
|
||||
std::unique_ptr<RenderWindowImpl> m_impl;
|
||||
MillisecondClock m_clock;
|
||||
RenderWindowParameters m_parameters;
|
||||
unsigned int m_framerateLimit;
|
||||
};
|
||||
} // namespace Nz
|
||||
|
||||
#include <Nazara/Renderer/RenderWindow.inl>
|
||||
|
||||
#endif // NAZARA_RENDERER_RENDERWINDOW_HPP
|
||||
|
|
@ -1,62 +0,0 @@
|
|||
// Copyright (C) 2022 Jérôme "Lynix" Leclercq (lynix680@gmail.com)
|
||||
// This file is part of the "Nazara Engine - Renderer module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#include <Nazara/Renderer/RenderWindow.hpp>
|
||||
#include <Nazara/Core/ErrorFlags.hpp>
|
||||
#include <Nazara/Renderer/Debug.hpp>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
inline RenderWindow::RenderWindow() :
|
||||
m_framerateLimit(0U)
|
||||
{
|
||||
}
|
||||
|
||||
inline RenderWindow::RenderWindow(std::shared_ptr<RenderDevice> renderDevice, VideoMode mode, const std::string& title, WindowStyleFlags style, const RenderWindowParameters& parameters) :
|
||||
RenderWindow()
|
||||
{
|
||||
ErrorFlags errFlags(ErrorMode::ThrowException, true);
|
||||
|
||||
Create(std::move(renderDevice), mode, title, style, parameters);
|
||||
}
|
||||
|
||||
inline RenderWindow::RenderWindow(std::shared_ptr<RenderDevice> renderDevice, void* handle, const RenderWindowParameters& parameters)
|
||||
{
|
||||
ErrorFlags errFlags(ErrorMode::ThrowException, true);
|
||||
|
||||
Create(std::move(renderDevice), handle, parameters);
|
||||
}
|
||||
|
||||
inline RenderWindow::~RenderWindow()
|
||||
{
|
||||
Destroy();
|
||||
}
|
||||
|
||||
inline const std::shared_ptr<RenderDevice>& RenderWindow::GetRenderDevice() const
|
||||
{
|
||||
return m_renderDevice;
|
||||
}
|
||||
|
||||
inline const RenderTarget* RenderWindow::GetRenderTarget() const
|
||||
{
|
||||
return m_impl.get();
|
||||
}
|
||||
|
||||
inline RenderSurface* RenderWindow::GetSurface()
|
||||
{
|
||||
return m_surface.get();
|
||||
}
|
||||
|
||||
inline bool RenderWindow::IsValid() const
|
||||
{
|
||||
return m_impl != nullptr;
|
||||
}
|
||||
|
||||
inline void RenderWindow::SetFramerateLimit(unsigned int limit)
|
||||
{
|
||||
m_framerateLimit = limit;
|
||||
}
|
||||
}
|
||||
|
||||
#include <Nazara/Renderer/DebugOff.hpp>
|
||||
|
|
@ -23,8 +23,8 @@ namespace Nz
|
|||
class RendererImpl;
|
||||
class RenderDevice;
|
||||
class RenderSurface;
|
||||
class RenderWindow;
|
||||
class RenderWindowImpl;
|
||||
class WindowSwapchain;
|
||||
class Swapchain;
|
||||
|
||||
using CreateRendererImplFunc = RendererImpl*(*)();
|
||||
|
||||
|
|
@ -34,9 +34,6 @@ namespace Nz
|
|||
RendererImpl() = default;
|
||||
virtual ~RendererImpl();
|
||||
|
||||
virtual std::unique_ptr<RenderSurface> CreateRenderSurfaceImpl() = 0;
|
||||
virtual std::unique_ptr<RenderWindowImpl> CreateRenderWindowImpl(RenderWindow& owner) = 0;
|
||||
|
||||
virtual std::shared_ptr<RenderDevice> InstanciateRenderDevice(std::size_t deviceIndex, const RenderDeviceFeatures& enabledFeatures) = 0;
|
||||
|
||||
virtual RenderAPI QueryAPI() const = 0;
|
||||
|
|
|
|||
|
|
@ -4,41 +4,38 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#ifndef NAZARA_RENDERER_RENDERWINDOWIMPL_HPP
|
||||
#define NAZARA_RENDERER_RENDERWINDOWIMPL_HPP
|
||||
#ifndef NAZARA_RENDERER_SWAPCHAIN_HPP
|
||||
#define NAZARA_RENDERER_SWAPCHAIN_HPP
|
||||
|
||||
#include <Nazara/Prerequisites.hpp>
|
||||
#include <Nazara/Math/Vector2.hpp>
|
||||
#include <Nazara/Platform/WindowHandle.hpp>
|
||||
#include <Nazara/Renderer/Config.hpp>
|
||||
#include <Nazara/Renderer/RenderDevice.hpp>
|
||||
#include <Nazara/Renderer/RenderFrame.hpp>
|
||||
#include <Nazara/Renderer/RenderPass.hpp>
|
||||
#include <Nazara/Renderer/RenderTarget.hpp>
|
||||
#include <Nazara/Renderer/RenderWindowParameters.hpp>
|
||||
#include <vector>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
class CommandPool;
|
||||
class RendererImpl;
|
||||
class RenderDevice;
|
||||
class RenderSurface;
|
||||
|
||||
class NAZARA_RENDERER_API RenderWindowImpl : public RenderTarget
|
||||
class NAZARA_RENDERER_API Swapchain : public RenderTarget
|
||||
{
|
||||
public:
|
||||
RenderWindowImpl() = default;
|
||||
virtual ~RenderWindowImpl();
|
||||
Swapchain() = default;
|
||||
virtual ~Swapchain();
|
||||
|
||||
virtual RenderFrame Acquire() = 0;
|
||||
virtual RenderFrame AcquireFrame() = 0;
|
||||
|
||||
virtual bool Create(RendererImpl* renderer, RenderSurface* surface, const RenderWindowParameters& parameters) = 0;
|
||||
virtual std::shared_ptr<CommandPool> CreateCommandPool(QueueType queueType) = 0;
|
||||
|
||||
virtual void NotifyResize(const Vector2ui& newSize) = 0;
|
||||
|
||||
protected:
|
||||
static void BuildRenderPass(PixelFormat colorFormat, PixelFormat depthFormat, std::vector<RenderPass::Attachment>& attachments, std::vector<RenderPass::SubpassDescription>& subpassDescriptions, std::vector<RenderPass::SubpassDependency>& subpassDependencies);
|
||||
};
|
||||
}
|
||||
|
||||
#endif // NAZARA_RENDERER_RENDERWINDOWIMPL_HPP
|
||||
#endif // NAZARA_RENDERER_SWAPCHAIN_HPP
|
||||
|
|
@ -13,7 +13,7 @@
|
|||
|
||||
namespace Nz
|
||||
{
|
||||
struct RenderWindowParameters
|
||||
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
|
||||
bool verticalSync = false;
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
// Copyright (C) 2022 Jérôme "Lynix" Leclercq (lynix680@gmail.com)
|
||||
// This file is part of the "Nazara Engine - Renderer module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef NAZARA_RENDERER_RENDERWINDOW_HPP
|
||||
#define NAZARA_RENDERER_RENDERWINDOW_HPP
|
||||
|
||||
#include <Nazara/Prerequisites.hpp>
|
||||
#include <Nazara/Platform/WindowEventHandler.hpp>
|
||||
#include <Nazara/Renderer/Swapchain.hpp>
|
||||
#include <Nazara/Renderer/SwapchainParameters.hpp>
|
||||
#include <memory>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
class RenderDevice;
|
||||
class Window;
|
||||
|
||||
class NAZARA_RENDERER_API WindowSwapchain
|
||||
{
|
||||
public:
|
||||
WindowSwapchain(std::shared_ptr<RenderDevice> renderDevice, Window& window, SwapchainParameters parameters = SwapchainParameters());
|
||||
WindowSwapchain(const WindowSwapchain&) = delete;
|
||||
inline WindowSwapchain(WindowSwapchain&& windowSwapchain) noexcept;
|
||||
~WindowSwapchain() = default;
|
||||
|
||||
inline RenderFrame AcquireFrame();
|
||||
|
||||
inline bool DoesRenderOnlyIfFocused() const;
|
||||
|
||||
inline void EnableRenderOnlyIfFocused(bool enable = true);
|
||||
|
||||
inline Swapchain& GetSwapchain();
|
||||
inline const Swapchain& GetSwapchain() const;
|
||||
|
||||
WindowSwapchain& operator=(const WindowSwapchain&) = default;
|
||||
inline WindowSwapchain& operator=(WindowSwapchain&& windowSwapchain) noexcept;
|
||||
|
||||
private:
|
||||
void ConnectSignals();
|
||||
inline void DisconnectSignals();
|
||||
|
||||
NazaraSlot(WindowEventHandler, OnCreated, m_onCreated);
|
||||
NazaraSlot(WindowEventHandler, OnDestruction, m_onDestruction);
|
||||
NazaraSlot(WindowEventHandler, OnGainedFocus, m_onGainedFocus);
|
||||
NazaraSlot(WindowEventHandler, OnLostFocus, m_onLostFocus);
|
||||
NazaraSlot(WindowEventHandler, OnMinimized, m_onMinimized);
|
||||
NazaraSlot(WindowEventHandler, OnResized, m_onResized);
|
||||
NazaraSlot(WindowEventHandler, OnRestored, m_onRestored);
|
||||
|
||||
std::shared_ptr<RenderDevice> m_renderDevice;
|
||||
std::shared_ptr<Swapchain> m_swapchain;
|
||||
MovablePtr<Window> m_window;
|
||||
SwapchainParameters m_parameters;
|
||||
bool m_renderOnlyIfFocused;
|
||||
bool m_hasFocus;
|
||||
bool m_isMinimized;
|
||||
};
|
||||
}
|
||||
|
||||
#include <Nazara/Renderer/WindowSwapchain.inl>
|
||||
|
||||
#endif // NAZARA_RENDERER_RENDERWINDOW_HPP
|
||||
|
|
@ -0,0 +1,76 @@
|
|||
// Copyright (C) 2022 Jérôme "Lynix" Leclercq (lynix680@gmail.com)
|
||||
// This file is part of the "Nazara Engine - Renderer module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#include <Nazara/Renderer/WindowSwapchain.hpp>
|
||||
#include <Nazara/Core/ErrorFlags.hpp>
|
||||
#include <Nazara/Renderer/Debug.hpp>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
inline WindowSwapchain::WindowSwapchain(WindowSwapchain&& windowSwapchain) noexcept :
|
||||
m_renderDevice(std::move(windowSwapchain.m_renderDevice)),
|
||||
m_swapchain(std::move(windowSwapchain.m_swapchain)),
|
||||
m_window(std::move(windowSwapchain.m_window)),
|
||||
m_renderOnlyIfFocused(windowSwapchain.m_renderOnlyIfFocused),
|
||||
m_hasFocus(windowSwapchain.m_hasFocus),
|
||||
m_isMinimized(windowSwapchain.m_isMinimized)
|
||||
{
|
||||
ConnectSignals();
|
||||
}
|
||||
|
||||
inline RenderFrame WindowSwapchain::AcquireFrame()
|
||||
{
|
||||
if (m_isMinimized || (!m_hasFocus && m_renderOnlyIfFocused))
|
||||
return RenderFrame{};
|
||||
|
||||
return m_swapchain->AcquireFrame();
|
||||
}
|
||||
|
||||
inline bool WindowSwapchain::DoesRenderOnlyIfFocused() const
|
||||
{
|
||||
return m_renderOnlyIfFocused;
|
||||
}
|
||||
|
||||
inline void WindowSwapchain::EnableRenderOnlyIfFocused(bool enable)
|
||||
{
|
||||
m_renderOnlyIfFocused = enable;
|
||||
}
|
||||
|
||||
inline Swapchain& WindowSwapchain::GetSwapchain()
|
||||
{
|
||||
return *m_swapchain;
|
||||
}
|
||||
|
||||
inline const Swapchain& WindowSwapchain::GetSwapchain() const
|
||||
{
|
||||
return *m_swapchain;
|
||||
}
|
||||
|
||||
inline WindowSwapchain& WindowSwapchain::operator=(WindowSwapchain&& windowSwapchain) noexcept
|
||||
{
|
||||
windowSwapchain.DisconnectSignals();
|
||||
|
||||
m_renderDevice = std::move(windowSwapchain.m_renderDevice);
|
||||
m_swapchain = std::move(windowSwapchain.m_swapchain);
|
||||
m_window = std::move(windowSwapchain.m_window);
|
||||
m_renderOnlyIfFocused = windowSwapchain.m_renderOnlyIfFocused;
|
||||
m_hasFocus = windowSwapchain.m_hasFocus;
|
||||
m_isMinimized = windowSwapchain.m_isMinimized;
|
||||
|
||||
ConnectSignals();
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
void WindowSwapchain::DisconnectSignals()
|
||||
{
|
||||
m_onGainedFocus.Disconnect();
|
||||
m_onLostFocus.Disconnect();
|
||||
m_onMinimized.Disconnect();
|
||||
m_onResized.Disconnect();
|
||||
m_onRestored.Disconnect();
|
||||
}
|
||||
}
|
||||
|
||||
#include <Nazara/Renderer/DebugOff.hpp>
|
||||
|
|
@ -45,10 +45,9 @@
|
|||
#include <Nazara/VulkanRenderer/VulkanRenderPass.hpp>
|
||||
#include <Nazara/VulkanRenderer/VulkanRenderPipeline.hpp>
|
||||
#include <Nazara/VulkanRenderer/VulkanRenderPipelineLayout.hpp>
|
||||
#include <Nazara/VulkanRenderer/VulkanRenderWindow.hpp>
|
||||
#include <Nazara/VulkanRenderer/VulkanShaderBinding.hpp>
|
||||
#include <Nazara/VulkanRenderer/VulkanShaderModule.hpp>
|
||||
#include <Nazara/VulkanRenderer/VulkanSurface.hpp>
|
||||
#include <Nazara/VulkanRenderer/VulkanSwapchain.hpp>
|
||||
#include <Nazara/VulkanRenderer/VulkanTexture.hpp>
|
||||
#include <Nazara/VulkanRenderer/VulkanTextureFramebuffer.hpp>
|
||||
#include <Nazara/VulkanRenderer/VulkanTextureSampler.hpp>
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@ namespace Nz
|
|||
std::shared_ptr<RenderPipelineLayout> InstantiateRenderPipelineLayout(RenderPipelineLayoutInfo pipelineLayoutInfo) override;
|
||||
std::shared_ptr<ShaderModule> InstantiateShaderModule(nzsl::ShaderStageTypeFlags stages, const nzsl::Ast::Module& shaderModule, const nzsl::ShaderWriter::States& states) override;
|
||||
std::shared_ptr<ShaderModule> InstantiateShaderModule(nzsl::ShaderStageTypeFlags stages, ShaderLanguage lang, const void* source, std::size_t sourceSize, const nzsl::ShaderWriter::States& states) override;
|
||||
std::shared_ptr<Swapchain> InstantiateSwapchain(WindowHandle windowHandle, const Vector2ui& windowSize, const SwapchainParameters& parameters) override;
|
||||
std::shared_ptr<Texture> InstantiateTexture(const TextureInfo& params) override;
|
||||
std::shared_ptr<TextureSampler> InstantiateTextureSampler(const TextureSamplerInfo& params) override;
|
||||
|
||||
|
|
|
|||
|
|
@ -18,12 +18,12 @@
|
|||
|
||||
namespace Nz
|
||||
{
|
||||
class VulkanRenderWindow;
|
||||
class VulkanSwapchain;
|
||||
|
||||
class NAZARA_VULKANRENDERER_API VulkanRenderImage : public RenderImage
|
||||
{
|
||||
public:
|
||||
VulkanRenderImage(VulkanRenderWindow& owner);
|
||||
VulkanRenderImage(VulkanSwapchain& owner);
|
||||
VulkanRenderImage(const VulkanRenderImage&) = delete;
|
||||
VulkanRenderImage(VulkanRenderImage&&) = delete;
|
||||
~VulkanRenderImage();
|
||||
|
|
@ -50,7 +50,7 @@ namespace Nz
|
|||
std::size_t m_currentCommandBuffer;
|
||||
std::vector<Vk::AutoCommandBuffer> m_inFlightCommandBuffers;
|
||||
std::vector<VkCommandBuffer> m_graphicalCommandsBuffers;
|
||||
VulkanRenderWindow& m_owner;
|
||||
VulkanSwapchain& m_owner;
|
||||
Vk::CommandPool m_commandPool;
|
||||
Vk::Fence m_inFlightFence;
|
||||
Vk::Semaphore m_imageAvailableSemaphore;
|
||||
|
|
|
|||
|
|
@ -25,9 +25,6 @@ namespace Nz
|
|||
VulkanRenderer() = default;
|
||||
~VulkanRenderer();
|
||||
|
||||
std::unique_ptr<RenderSurface> CreateRenderSurfaceImpl() override;
|
||||
std::unique_ptr<RenderWindowImpl> CreateRenderWindowImpl(RenderWindow& owner) override;
|
||||
|
||||
std::shared_ptr<RenderDevice> InstanciateRenderDevice(std::size_t deviceIndex, const RenderDeviceFeatures& enabledFeatures) override;
|
||||
|
||||
RenderAPI QueryAPI() const override;
|
||||
|
|
|
|||
|
|
@ -1,40 +0,0 @@
|
|||
// Copyright (C) 2022 Jérôme "Lynix" Leclercq (lynix680@gmail.com)
|
||||
// This file is part of the "Nazara Engine - Vulkan renderer"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef NAZARA_VULKANRENDERER_VULKANSURFACE_HPP
|
||||
#define NAZARA_VULKANRENDERER_VULKANSURFACE_HPP
|
||||
|
||||
#include <Nazara/Prerequisites.hpp>
|
||||
#include <Nazara/Renderer/RenderSurface.hpp>
|
||||
#include <Nazara/VulkanRenderer/Wrapper/Surface.hpp>
|
||||
#include <Nazara/VulkanRenderer/Wrapper/Swapchain.hpp>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
class NAZARA_VULKANRENDERER_API VulkanSurface : public RenderSurface
|
||||
{
|
||||
public:
|
||||
VulkanSurface();
|
||||
VulkanSurface(const VulkanSurface&) = delete;
|
||||
VulkanSurface(VulkanSurface&&) = delete; ///TODO
|
||||
~VulkanSurface() = default;
|
||||
|
||||
bool Create(WindowHandle handle) override;
|
||||
void Destroy() override;
|
||||
|
||||
inline Vk::Surface& GetSurface();
|
||||
|
||||
VulkanSurface& operator=(const VulkanSurface&) = delete;
|
||||
VulkanSurface& operator=(VulkanSurface&&) = delete; ///TODO
|
||||
|
||||
private:
|
||||
Vk::Surface m_surface;
|
||||
};
|
||||
}
|
||||
|
||||
#include <Nazara/VulkanRenderer/VulkanSurface.inl>
|
||||
|
||||
#endif // NAZARA_VULKANRENDERER_VULKANSURFACE_HPP
|
||||
|
|
@ -1,16 +0,0 @@
|
|||
// Copyright (C) 2022 Jérôme "Lynix" Leclercq (lynix680@gmail.com)
|
||||
// This file is part of the "Nazara Engine - Vulkan renderer"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#include <Nazara/VulkanRenderer/VulkanSurface.hpp>
|
||||
#include <Nazara/VulkanRenderer/Debug.hpp>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
inline Vk::Surface& VulkanSurface::GetSurface()
|
||||
{
|
||||
return m_surface;
|
||||
}
|
||||
}
|
||||
|
||||
#include <Nazara/VulkanRenderer/DebugOff.hpp>
|
||||
|
|
@ -12,8 +12,9 @@
|
|||
#include <Nazara/Math/Rect.hpp>
|
||||
#include <Nazara/Math/Vector3.hpp>
|
||||
#include <Nazara/Renderer/Enums.hpp>
|
||||
#include <Nazara/Renderer/RenderWindowImpl.hpp>
|
||||
#include <Nazara/Renderer/Swapchain.hpp>
|
||||
#include <Nazara/Renderer/RendererImpl.hpp>
|
||||
#include <Nazara/Renderer/SwapchainParameters.hpp>
|
||||
#include <Nazara/VulkanRenderer/Config.hpp>
|
||||
#include <Nazara/VulkanRenderer/VulkanDevice.hpp>
|
||||
#include <Nazara/VulkanRenderer/VulkanRenderImage.hpp>
|
||||
|
|
@ -33,17 +34,15 @@
|
|||
|
||||
namespace Nz
|
||||
{
|
||||
class NAZARA_VULKANRENDERER_API VulkanRenderWindow : public RenderWindowImpl
|
||||
class NAZARA_VULKANRENDERER_API VulkanSwapchain : public Swapchain
|
||||
{
|
||||
public:
|
||||
VulkanRenderWindow(RenderWindow& owner);
|
||||
VulkanRenderWindow(const VulkanRenderWindow&) = delete;
|
||||
VulkanRenderWindow(VulkanRenderWindow&&) = delete; ///TODO
|
||||
~VulkanRenderWindow();
|
||||
VulkanSwapchain(VulkanDevice& device, WindowHandle windowHandle, const Vector2ui& windowSize, const SwapchainParameters& parameters);
|
||||
VulkanSwapchain(const VulkanSwapchain&) = delete;
|
||||
VulkanSwapchain(VulkanSwapchain&&) = delete;
|
||||
~VulkanSwapchain();
|
||||
|
||||
RenderFrame Acquire() override;
|
||||
|
||||
bool Create(RendererImpl* renderer, RenderSurface* surface, const RenderWindowParameters& parameters) override;
|
||||
RenderFrame AcquireFrame() override;
|
||||
|
||||
std::shared_ptr<CommandPool> CreateCommandPool(QueueType queueType) override;
|
||||
|
||||
|
|
@ -56,20 +55,22 @@ namespace Nz
|
|||
const Vector2ui& GetSize() const override;
|
||||
inline const Vk::Swapchain& GetSwapchain() const;
|
||||
|
||||
void NotifyResize(const Vector2ui& newSize) override;
|
||||
|
||||
void Present(UInt32 imageIndex, VkSemaphore waitSemaphore = VK_NULL_HANDLE);
|
||||
|
||||
VulkanRenderWindow& operator=(const VulkanRenderWindow&) = delete;
|
||||
VulkanRenderWindow& operator=(VulkanRenderWindow&&) = delete; ///TODO
|
||||
VulkanSwapchain& operator=(const VulkanSwapchain&) = delete;
|
||||
VulkanSwapchain& operator=(VulkanSwapchain&&) = delete;
|
||||
|
||||
private:
|
||||
bool CreateSwapchain(Vk::Surface& surface, const Vector2ui& size);
|
||||
bool SetupDepthBuffer(const Vector2ui& size);
|
||||
bool SetupFrameBuffers(const Vector2ui& size);
|
||||
bool CreateSwapchain();
|
||||
bool SetupDepthBuffer();
|
||||
bool SetupFrameBuffers();
|
||||
bool SetupRenderPass();
|
||||
bool SetupSwapchain(const Vk::PhysicalDevice& deviceInfo, Vk::Surface& surface, const Vector2ui& size);
|
||||
bool SetupSurface(WindowHandle windowHandle);
|
||||
bool SetupSwapchain(const Vk::PhysicalDevice& deviceInfo);
|
||||
|
||||
std::optional<VulkanRenderPass> m_renderPass;
|
||||
std::shared_ptr<VulkanDevice> m_device;
|
||||
std::size_t m_currentFrame;
|
||||
std::vector<VulkanWindowFramebuffer> m_framebuffers;
|
||||
std::vector<Vk::Fence*> m_inflightFences;
|
||||
|
|
@ -80,15 +81,16 @@ namespace Nz
|
|||
Vk::QueueHandle m_graphicsQueue;
|
||||
Vk::QueueHandle m_presentQueue;
|
||||
Vk::QueueHandle m_transferQueue;
|
||||
Vk::Surface m_surface;
|
||||
Vk::Swapchain m_swapchain;
|
||||
RenderWindow& m_owner;
|
||||
Vector2ui m_swapchainSize;
|
||||
VkFormat m_depthStencilFormat;
|
||||
VkSurfaceFormatKHR m_surfaceFormat;
|
||||
VulkanDevice& m_device;
|
||||
bool m_shouldRecreateSwapchain;
|
||||
};
|
||||
}
|
||||
|
||||
#include <Nazara/VulkanRenderer/VulkanRenderWindow.inl>
|
||||
#include <Nazara/VulkanRenderer/VulkanSwapchain.inl>
|
||||
|
||||
#endif // NAZARA_VULKANRENDERER_VULKANRENDERWINDOW_HPP
|
||||
|
|
@ -2,27 +2,27 @@
|
|||
// This file is part of the "Nazara Engine - Vulkan renderer"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#include <Nazara/VulkanRenderer/VulkanRenderWindow.hpp>
|
||||
#include <Nazara/VulkanRenderer/VulkanSwapchain.hpp>
|
||||
#include <Nazara/VulkanRenderer/Debug.hpp>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
inline VulkanDevice& VulkanRenderWindow::GetDevice()
|
||||
inline VulkanDevice& VulkanSwapchain::GetDevice()
|
||||
{
|
||||
return *m_device;
|
||||
return m_device;
|
||||
}
|
||||
|
||||
inline const VulkanDevice& VulkanRenderWindow::GetDevice() const
|
||||
inline const VulkanDevice& VulkanSwapchain::GetDevice() const
|
||||
{
|
||||
return *m_device;
|
||||
return m_device;
|
||||
}
|
||||
|
||||
inline Vk::QueueHandle& VulkanRenderWindow::GetGraphicsQueue()
|
||||
inline Vk::QueueHandle& VulkanSwapchain::GetGraphicsQueue()
|
||||
{
|
||||
return m_graphicsQueue;
|
||||
}
|
||||
|
||||
inline const Vk::Swapchain& VulkanRenderWindow::GetSwapchain() const
|
||||
inline const Vk::Swapchain& VulkanSwapchain::GetSwapchain() const
|
||||
{
|
||||
return m_swapchain;
|
||||
}
|
||||
|
|
@ -17,78 +17,75 @@
|
|||
#include <vulkan/vulkan_metal.h>
|
||||
#endif
|
||||
|
||||
namespace Nz
|
||||
namespace Nz::Vk
|
||||
{
|
||||
namespace Vk
|
||||
class Surface
|
||||
{
|
||||
class Surface
|
||||
{
|
||||
public:
|
||||
inline Surface(Instance& instance);
|
||||
Surface(const Surface&) = delete;
|
||||
Surface(Surface&& surface);
|
||||
inline ~Surface();
|
||||
public:
|
||||
inline Surface(Instance& instance);
|
||||
Surface(const Surface&) = delete;
|
||||
Surface(Surface&& surface) noexcept;
|
||||
inline ~Surface();
|
||||
|
||||
#ifdef VK_USE_PLATFORM_ANDROID_KHR
|
||||
// VK_KHR_android_surface
|
||||
inline bool Create(const VkAndroidSurfaceCreateInfoKHR& createInfo, const VkAllocationCallbacks* allocator = nullptr);
|
||||
inline bool Create(ANativeWindow* window, VkAndroidSurfaceCreateFlagsKHR flags = 0, const VkAllocationCallbacks* allocator = nullptr);
|
||||
#endif
|
||||
#ifdef VK_USE_PLATFORM_ANDROID_KHR
|
||||
// VK_KHR_android_surface
|
||||
inline bool Create(const VkAndroidSurfaceCreateInfoKHR& createInfo, const VkAllocationCallbacks* allocator = nullptr);
|
||||
inline bool Create(ANativeWindow* window, VkAndroidSurfaceCreateFlagsKHR flags = 0, const VkAllocationCallbacks* allocator = nullptr);
|
||||
#endif
|
||||
|
||||
#ifdef VK_USE_PLATFORM_XCB_KHR
|
||||
// VK_KHR_xcb_surface
|
||||
inline bool Create(const VkXcbSurfaceCreateInfoKHR& createInfo, const VkAllocationCallbacks* allocator = nullptr);
|
||||
inline bool Create(xcb_connection_t* connection, xcb_window_t window, VkXcbSurfaceCreateFlagsKHR flags = 0, const VkAllocationCallbacks* allocator = nullptr);
|
||||
#endif
|
||||
#ifdef VK_USE_PLATFORM_XCB_KHR
|
||||
// VK_KHR_xcb_surface
|
||||
inline bool Create(const VkXcbSurfaceCreateInfoKHR& createInfo, const VkAllocationCallbacks* allocator = nullptr);
|
||||
inline bool Create(xcb_connection_t* connection, xcb_window_t window, VkXcbSurfaceCreateFlagsKHR flags = 0, const VkAllocationCallbacks* allocator = nullptr);
|
||||
#endif
|
||||
|
||||
#ifdef VK_USE_PLATFORM_XLIB_KHR
|
||||
// VK_KHR_xlib_surface
|
||||
inline bool Create(const VkXlibSurfaceCreateInfoKHR& createInfo, const VkAllocationCallbacks* allocator = nullptr);
|
||||
inline bool Create(Display* display, Window window, VkXlibSurfaceCreateFlagsKHR flags = 0, const VkAllocationCallbacks* allocator = nullptr);
|
||||
#endif
|
||||
#ifdef VK_USE_PLATFORM_XLIB_KHR
|
||||
// VK_KHR_xlib_surface
|
||||
inline bool Create(const VkXlibSurfaceCreateInfoKHR& createInfo, const VkAllocationCallbacks* allocator = nullptr);
|
||||
inline bool Create(Display* display, Window window, VkXlibSurfaceCreateFlagsKHR flags = 0, const VkAllocationCallbacks* allocator = nullptr);
|
||||
#endif
|
||||
|
||||
#ifdef VK_USE_PLATFORM_WAYLAND_KHR
|
||||
// VK_KHR_wayland_surface
|
||||
inline bool Create(const VkWaylandSurfaceCreateInfoKHR& createInfo, const VkAllocationCallbacks* allocator = nullptr);
|
||||
inline bool Create(wl_display* display, wl_surface* surface, VkWaylandSurfaceCreateFlagsKHR flags = 0, const VkAllocationCallbacks* allocator = nullptr);
|
||||
#endif
|
||||
#ifdef VK_USE_PLATFORM_WAYLAND_KHR
|
||||
// VK_KHR_wayland_surface
|
||||
inline bool Create(const VkWaylandSurfaceCreateInfoKHR& createInfo, const VkAllocationCallbacks* allocator = nullptr);
|
||||
inline bool Create(wl_display* display, wl_surface* surface, VkWaylandSurfaceCreateFlagsKHR flags = 0, const VkAllocationCallbacks* allocator = nullptr);
|
||||
#endif
|
||||
|
||||
#ifdef VK_USE_PLATFORM_WIN32_KHR
|
||||
// VK_KHR_win32_surface
|
||||
inline bool Create(const VkWin32SurfaceCreateInfoKHR& createInfo, const VkAllocationCallbacks* allocator = nullptr);
|
||||
inline bool Create(HINSTANCE instance, HWND handle, VkWin32SurfaceCreateFlagsKHR flags = 0, const VkAllocationCallbacks* allocator = nullptr);
|
||||
#endif
|
||||
#ifdef VK_USE_PLATFORM_WIN32_KHR
|
||||
// VK_KHR_win32_surface
|
||||
inline bool Create(const VkWin32SurfaceCreateInfoKHR& createInfo, const VkAllocationCallbacks* allocator = nullptr);
|
||||
inline bool Create(HINSTANCE instance, HWND handle, VkWin32SurfaceCreateFlagsKHR flags = 0, const VkAllocationCallbacks* allocator = nullptr);
|
||||
#endif
|
||||
|
||||
#ifdef VK_USE_PLATFORM_METAL_EXT
|
||||
inline bool Create(const VkMetalSurfaceCreateInfoEXT& createInfo, const VkAllocationCallbacks* allocator = nullptr);
|
||||
inline bool Create(id layer, const VkAllocationCallbacks* allocator = nullptr);
|
||||
#endif
|
||||
#ifdef VK_USE_PLATFORM_METAL_EXT
|
||||
inline bool Create(const VkMetalSurfaceCreateInfoEXT& createInfo, const VkAllocationCallbacks* allocator = nullptr);
|
||||
inline bool Create(id layer, const VkAllocationCallbacks* allocator = nullptr);
|
||||
#endif
|
||||
|
||||
inline void Destroy();
|
||||
inline void Destroy();
|
||||
|
||||
bool GetCapabilities(VkPhysicalDevice physicalDevice, VkSurfaceCapabilitiesKHR* surfaceCapabilities) const;
|
||||
bool GetFormats(VkPhysicalDevice physicalDevice, std::vector<VkSurfaceFormatKHR>* surfaceFormats) const;
|
||||
bool GetPresentModes(VkPhysicalDevice physicalDevice, std::vector<VkPresentModeKHR>* presentModes) const;
|
||||
bool GetSupportPresentation(VkPhysicalDevice physicalDevice, UInt32 queueFamilyIndex, bool* supported) const;
|
||||
bool GetCapabilities(VkPhysicalDevice physicalDevice, VkSurfaceCapabilitiesKHR* surfaceCapabilities) const;
|
||||
bool GetFormats(VkPhysicalDevice physicalDevice, std::vector<VkSurfaceFormatKHR>* surfaceFormats) const;
|
||||
bool GetPresentModes(VkPhysicalDevice physicalDevice, std::vector<VkPresentModeKHR>* presentModes) const;
|
||||
bool GetSupportPresentation(VkPhysicalDevice physicalDevice, UInt32 queueFamilyIndex, bool* supported) const;
|
||||
|
||||
inline VkResult GetLastErrorCode() const;
|
||||
inline VkResult GetLastErrorCode() const;
|
||||
|
||||
Surface& operator=(const Surface&) = delete;
|
||||
Surface& operator=(Surface&&) = delete;
|
||||
Surface& operator=(const Surface&) = delete;
|
||||
Surface& operator=(Surface&&) = delete;
|
||||
|
||||
inline operator VkSurfaceKHR() const;
|
||||
inline operator VkSurfaceKHR() const;
|
||||
|
||||
static inline bool IsSupported(const Instance& instance);
|
||||
static inline bool IsSupported(const Instance& instance);
|
||||
|
||||
private:
|
||||
inline bool Create(const VkAllocationCallbacks* allocator);
|
||||
private:
|
||||
inline bool Create(const VkAllocationCallbacks* allocator);
|
||||
|
||||
Instance& m_instance;
|
||||
VkAllocationCallbacks m_allocator;
|
||||
VkSurfaceKHR m_surface;
|
||||
mutable VkResult m_lastErrorCode;
|
||||
};
|
||||
}
|
||||
Instance& m_instance;
|
||||
VkAllocationCallbacks m_allocator;
|
||||
VkSurfaceKHR m_surface;
|
||||
mutable VkResult m_lastErrorCode;
|
||||
};
|
||||
}
|
||||
|
||||
#include <Nazara/VulkanRenderer/Wrapper/Surface.inl>
|
||||
|
|
|
|||
|
|
@ -7,305 +7,302 @@
|
|||
#include <Nazara/VulkanRenderer/Utils.hpp>
|
||||
#include <Nazara/VulkanRenderer/Debug.hpp>
|
||||
|
||||
namespace Nz
|
||||
namespace Nz::Vk
|
||||
{
|
||||
namespace Vk
|
||||
inline Surface::Surface(Instance& instance) :
|
||||
m_instance(instance),
|
||||
m_surface(VK_NULL_HANDLE)
|
||||
{
|
||||
inline Surface::Surface(Instance& instance) :
|
||||
m_instance(instance),
|
||||
m_surface(VK_NULL_HANDLE)
|
||||
}
|
||||
|
||||
inline Surface::Surface(Surface&& surface) noexcept :
|
||||
m_instance(surface.m_instance),
|
||||
m_allocator(surface.m_allocator),
|
||||
m_surface(surface.m_surface),
|
||||
m_lastErrorCode(surface.m_lastErrorCode)
|
||||
{
|
||||
surface.m_surface = VK_NULL_HANDLE;
|
||||
}
|
||||
|
||||
inline Surface::~Surface()
|
||||
{
|
||||
Destroy();
|
||||
}
|
||||
|
||||
#ifdef VK_USE_PLATFORM_ANDROID_KHR
|
||||
inline bool Surface::Create(const VkAndroidSurfaceCreateInfoKHR& createInfo, const VkAllocationCallbacks* allocator)
|
||||
{
|
||||
m_lastErrorCode = m_instance.vkCreateAndroidSurfaceKHR(m_instance, &createInfo, allocator, &m_surface);
|
||||
return Create(allocator);
|
||||
}
|
||||
|
||||
inline bool Surface::Create(ANativeWindow* window, VkAndroidSurfaceCreateFlagsKHR flags, const VkAllocationCallbacks* allocator)
|
||||
{
|
||||
VkAndroidSurfaceCreateInfoKHR createInfo =
|
||||
{
|
||||
}
|
||||
VK_STRUCTURE_TYPE_ANDROID_SURFACE_CREATE_INFO_KHR,
|
||||
nullptr,
|
||||
flags,
|
||||
window
|
||||
};
|
||||
|
||||
inline Surface::Surface(Surface&& surface) :
|
||||
m_instance(surface.m_instance),
|
||||
m_allocator(surface.m_allocator),
|
||||
m_surface(surface.m_surface),
|
||||
m_lastErrorCode(surface.m_lastErrorCode)
|
||||
return Create(createInfo, allocator);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef VK_USE_PLATFORM_XCB_KHR
|
||||
inline bool Surface::Create(const VkXcbSurfaceCreateInfoKHR& createInfo, const VkAllocationCallbacks* allocator)
|
||||
{
|
||||
m_lastErrorCode = m_instance.vkCreateXcbSurfaceKHR(m_instance, &createInfo, allocator, &m_surface);
|
||||
return Create(allocator);
|
||||
}
|
||||
|
||||
inline bool Surface::Create(xcb_connection_t* connection, xcb_window_t window, VkXcbSurfaceCreateFlagsKHR flags, const VkAllocationCallbacks* allocator)
|
||||
{
|
||||
VkXcbSurfaceCreateInfoKHR createInfo =
|
||||
{
|
||||
surface.m_surface = VK_NULL_HANDLE;
|
||||
}
|
||||
VK_STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR,
|
||||
nullptr,
|
||||
flags,
|
||||
connection,
|
||||
window
|
||||
};
|
||||
|
||||
inline Surface::~Surface()
|
||||
return Create(createInfo, allocator);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef VK_USE_PLATFORM_XLIB_KHR
|
||||
inline bool Surface::Create(const VkXlibSurfaceCreateInfoKHR& createInfo, const VkAllocationCallbacks* allocator)
|
||||
{
|
||||
m_lastErrorCode = m_instance.vkCreateXlibSurfaceKHR(m_instance, &createInfo, allocator, &m_surface);
|
||||
return Create(allocator);
|
||||
}
|
||||
|
||||
inline bool Surface::Create(Display* display, Window window, VkXlibSurfaceCreateFlagsKHR flags, const VkAllocationCallbacks* allocator)
|
||||
{
|
||||
VkXlibSurfaceCreateInfoKHR createInfo =
|
||||
{
|
||||
Destroy();
|
||||
}
|
||||
VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR,
|
||||
nullptr,
|
||||
flags,
|
||||
display,
|
||||
window
|
||||
};
|
||||
|
||||
#ifdef VK_USE_PLATFORM_ANDROID_KHR
|
||||
inline bool Surface::Create(const VkAndroidSurfaceCreateInfoKHR& createInfo, const VkAllocationCallbacks* allocator)
|
||||
return Create(createInfo, allocator);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef VK_USE_PLATFORM_WAYLAND_KHR
|
||||
inline bool Surface::Create(const VkWaylandSurfaceCreateInfoKHR& createInfo, const VkAllocationCallbacks* allocator)
|
||||
{
|
||||
m_lastErrorCode = m_instance.vkCreateWaylandSurfaceKHR(m_instance, &createInfo, allocator, &m_surface);
|
||||
return Create(allocator);
|
||||
}
|
||||
|
||||
inline bool Surface::Create(wl_display* display, wl_surface* surface, VkWaylandSurfaceCreateFlagsKHR flags, const VkAllocationCallbacks* allocator)
|
||||
{
|
||||
VkWaylandSurfaceCreateInfoKHR createInfo =
|
||||
{
|
||||
m_lastErrorCode = m_instance.vkCreateAndroidSurfaceKHR(m_instance, &createInfo, allocator, &m_surface);
|
||||
return Create(allocator);
|
||||
}
|
||||
VK_STRUCTURE_TYPE_WAYLAND_SURFACE_CREATE_INFO_KHR,
|
||||
nullptr,
|
||||
flags,
|
||||
display,
|
||||
surface
|
||||
};
|
||||
|
||||
inline bool Surface::Create(ANativeWindow* window, VkAndroidSurfaceCreateFlagsKHR flags, const VkAllocationCallbacks* allocator)
|
||||
return Create(createInfo, allocator);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef VK_USE_PLATFORM_WIN32_KHR
|
||||
inline bool Surface::Create(const VkWin32SurfaceCreateInfoKHR& createInfo, const VkAllocationCallbacks* allocator)
|
||||
{
|
||||
m_lastErrorCode = m_instance.vkCreateWin32SurfaceKHR(m_instance, &createInfo, allocator, &m_surface);
|
||||
return Create(allocator);
|
||||
}
|
||||
|
||||
inline bool Surface::Create(HINSTANCE instance, HWND handle, VkWin32SurfaceCreateFlagsKHR flags, const VkAllocationCallbacks* allocator)
|
||||
{
|
||||
VkWin32SurfaceCreateInfoKHR createInfo =
|
||||
{
|
||||
VkAndroidSurfaceCreateInfoKHR createInfo =
|
||||
{
|
||||
VK_STRUCTURE_TYPE_ANDROID_SURFACE_CREATE_INFO_KHR,
|
||||
nullptr,
|
||||
flags,
|
||||
window
|
||||
};
|
||||
VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR,
|
||||
nullptr,
|
||||
flags,
|
||||
instance,
|
||||
handle
|
||||
};
|
||||
|
||||
return Create(createInfo, allocator);
|
||||
}
|
||||
#endif
|
||||
return Create(createInfo, allocator);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef VK_USE_PLATFORM_XCB_KHR
|
||||
inline bool Surface::Create(const VkXcbSurfaceCreateInfoKHR& createInfo, const VkAllocationCallbacks* allocator)
|
||||
#ifdef VK_USE_PLATFORM_METAL_EXT
|
||||
inline bool Surface::Create(const VkMetalSurfaceCreateInfoEXT& createInfo, const VkAllocationCallbacks* allocator)
|
||||
{
|
||||
m_lastErrorCode = m_instance.vkCreateMetalSurfaceEXT(m_instance, &createInfo, allocator, &m_surface);
|
||||
return Create(allocator);
|
||||
}
|
||||
|
||||
inline bool Surface::Create(id layer, const VkAllocationCallbacks* allocator)
|
||||
{
|
||||
VkMetalSurfaceCreateInfoEXT createInfo =
|
||||
{
|
||||
m_lastErrorCode = m_instance.vkCreateXcbSurfaceKHR(m_instance, &createInfo, allocator, &m_surface);
|
||||
return Create(allocator);
|
||||
}
|
||||
VK_STRUCTURE_TYPE_METAL_SURFACE_CREATE_INFO_EXT,
|
||||
nullptr,
|
||||
0,
|
||||
layer
|
||||
};
|
||||
|
||||
inline bool Surface::Create(xcb_connection_t* connection, xcb_window_t window, VkXcbSurfaceCreateFlagsKHR flags, const VkAllocationCallbacks* allocator)
|
||||
return Create(createInfo, allocator);
|
||||
}
|
||||
#endif
|
||||
|
||||
inline void Surface::Destroy()
|
||||
{
|
||||
if (m_surface != VK_NULL_HANDLE)
|
||||
{
|
||||
VkXcbSurfaceCreateInfoKHR createInfo =
|
||||
{
|
||||
VK_STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR,
|
||||
nullptr,
|
||||
flags,
|
||||
connection,
|
||||
window
|
||||
};
|
||||
|
||||
return Create(createInfo, allocator);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef VK_USE_PLATFORM_XLIB_KHR
|
||||
inline bool Surface::Create(const VkXlibSurfaceCreateInfoKHR& createInfo, const VkAllocationCallbacks* allocator)
|
||||
{
|
||||
m_lastErrorCode = m_instance.vkCreateXlibSurfaceKHR(m_instance, &createInfo, allocator, &m_surface);
|
||||
return Create(allocator);
|
||||
}
|
||||
|
||||
inline bool Surface::Create(Display* display, Window window, VkXlibSurfaceCreateFlagsKHR flags, const VkAllocationCallbacks* allocator)
|
||||
{
|
||||
VkXlibSurfaceCreateInfoKHR createInfo =
|
||||
{
|
||||
VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR,
|
||||
nullptr,
|
||||
flags,
|
||||
display,
|
||||
window
|
||||
};
|
||||
|
||||
return Create(createInfo, allocator);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef VK_USE_PLATFORM_WAYLAND_KHR
|
||||
inline bool Surface::Create(const VkWaylandSurfaceCreateInfoKHR& createInfo, const VkAllocationCallbacks* allocator)
|
||||
{
|
||||
m_lastErrorCode = m_instance.vkCreateWaylandSurfaceKHR(m_instance, &createInfo, allocator, &m_surface);
|
||||
return Create(allocator);
|
||||
}
|
||||
|
||||
inline bool Surface::Create(wl_display* display, wl_surface* surface, VkWaylandSurfaceCreateFlagsKHR flags, const VkAllocationCallbacks* allocator)
|
||||
{
|
||||
VkWaylandSurfaceCreateInfoKHR createInfo =
|
||||
{
|
||||
VK_STRUCTURE_TYPE_WAYLAND_SURFACE_CREATE_INFO_KHR,
|
||||
nullptr,
|
||||
flags,
|
||||
display,
|
||||
surface
|
||||
};
|
||||
|
||||
return Create(createInfo, allocator);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef VK_USE_PLATFORM_WIN32_KHR
|
||||
inline bool Surface::Create(const VkWin32SurfaceCreateInfoKHR& createInfo, const VkAllocationCallbacks* allocator)
|
||||
{
|
||||
m_lastErrorCode = m_instance.vkCreateWin32SurfaceKHR(m_instance, &createInfo, allocator, &m_surface);
|
||||
return Create(allocator);
|
||||
}
|
||||
|
||||
inline bool Surface::Create(HINSTANCE instance, HWND handle, VkWin32SurfaceCreateFlagsKHR flags, const VkAllocationCallbacks* allocator)
|
||||
{
|
||||
VkWin32SurfaceCreateInfoKHR createInfo =
|
||||
{
|
||||
VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR,
|
||||
nullptr,
|
||||
flags,
|
||||
instance,
|
||||
handle
|
||||
};
|
||||
|
||||
return Create(createInfo, allocator);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef VK_USE_PLATFORM_METAL_EXT
|
||||
inline bool Surface::Create(const VkMetalSurfaceCreateInfoEXT& createInfo, const VkAllocationCallbacks* allocator)
|
||||
{
|
||||
m_lastErrorCode = m_instance.vkCreateMetalSurfaceEXT(m_instance, &createInfo, allocator, &m_surface);
|
||||
return Create(allocator);
|
||||
}
|
||||
|
||||
inline bool Surface::Create(id layer, const VkAllocationCallbacks* allocator)
|
||||
{
|
||||
VkMetalSurfaceCreateInfoEXT createInfo =
|
||||
{
|
||||
VK_STRUCTURE_TYPE_METAL_SURFACE_CREATE_INFO_EXT,
|
||||
nullptr,
|
||||
0,
|
||||
layer
|
||||
};
|
||||
|
||||
return Create(createInfo, allocator);
|
||||
}
|
||||
#endif
|
||||
|
||||
inline void Surface::Destroy()
|
||||
{
|
||||
if (m_surface != VK_NULL_HANDLE)
|
||||
{
|
||||
m_instance.vkDestroySurfaceKHR(m_instance, m_surface, (m_allocator.pfnAllocation) ? &m_allocator : nullptr);
|
||||
m_surface = VK_NULL_HANDLE;
|
||||
}
|
||||
m_instance.vkDestroySurfaceKHR(m_instance, m_surface, (m_allocator.pfnAllocation) ? &m_allocator : nullptr);
|
||||
m_surface = VK_NULL_HANDLE;
|
||||
}
|
||||
}
|
||||
|
||||
inline VkResult Surface::GetLastErrorCode() const
|
||||
inline VkResult Surface::GetLastErrorCode() const
|
||||
{
|
||||
return m_lastErrorCode;
|
||||
}
|
||||
|
||||
inline bool Surface::GetCapabilities(VkPhysicalDevice physicalDevice, VkSurfaceCapabilitiesKHR* surfaceCapabilities) const
|
||||
{
|
||||
m_lastErrorCode = m_instance.vkGetPhysicalDeviceSurfaceCapabilitiesKHR(physicalDevice, m_surface, surfaceCapabilities);
|
||||
if (m_lastErrorCode != VkResult::VK_SUCCESS)
|
||||
{
|
||||
return m_lastErrorCode;
|
||||
}
|
||||
|
||||
inline bool Surface::GetCapabilities(VkPhysicalDevice physicalDevice, VkSurfaceCapabilitiesKHR* surfaceCapabilities) const
|
||||
{
|
||||
m_lastErrorCode = m_instance.vkGetPhysicalDeviceSurfaceCapabilitiesKHR(physicalDevice, m_surface, surfaceCapabilities);
|
||||
if (m_lastErrorCode != VkResult::VK_SUCCESS)
|
||||
{
|
||||
NazaraError("Failed to query surface capabilities: " + TranslateVulkanError(m_lastErrorCode));
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool Surface::GetFormats(VkPhysicalDevice physicalDevice, std::vector<VkSurfaceFormatKHR>* surfaceFormats) const
|
||||
{
|
||||
// First, query format count
|
||||
UInt32 surfaceCount = 0; // Remember, Nz::UInt32 is a typedef on uint32_t
|
||||
m_lastErrorCode = m_instance.vkGetPhysicalDeviceSurfaceFormatsKHR(physicalDevice, m_surface, &surfaceCount, nullptr);
|
||||
if (m_lastErrorCode != VkResult::VK_SUCCESS || surfaceCount == 0)
|
||||
{
|
||||
NazaraError("Failed to query format count: " + TranslateVulkanError(m_lastErrorCode));
|
||||
return false;
|
||||
}
|
||||
|
||||
// Now we can get the list of the available physical device
|
||||
surfaceFormats->resize(surfaceCount);
|
||||
m_lastErrorCode = m_instance.vkGetPhysicalDeviceSurfaceFormatsKHR(physicalDevice, m_surface, &surfaceCount, surfaceFormats->data());
|
||||
if (m_lastErrorCode != VkResult::VK_SUCCESS)
|
||||
{
|
||||
NazaraError("Failed to query formats: " + TranslateVulkanError(m_lastErrorCode));
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool Surface::GetPresentModes(VkPhysicalDevice physicalDevice, std::vector<VkPresentModeKHR>* presentModes) const
|
||||
{
|
||||
// First, query present modes count
|
||||
UInt32 presentModeCount = 0; // Remember, Nz::UInt32 is a typedef on uint32_t
|
||||
m_lastErrorCode = m_instance.vkGetPhysicalDeviceSurfacePresentModesKHR(physicalDevice, m_surface, &presentModeCount, nullptr);
|
||||
if (m_lastErrorCode != VkResult::VK_SUCCESS || presentModeCount == 0)
|
||||
{
|
||||
NazaraError("Failed to query present mode count");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Now we can get the list of the available physical device
|
||||
presentModes->resize(presentModeCount);
|
||||
m_lastErrorCode = m_instance.vkGetPhysicalDeviceSurfacePresentModesKHR(physicalDevice, m_surface, &presentModeCount, presentModes->data());
|
||||
if (m_lastErrorCode != VkResult::VK_SUCCESS)
|
||||
{
|
||||
NazaraError("Failed to query present modes: " + TranslateVulkanError(m_lastErrorCode));
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool Surface::GetSupportPresentation(VkPhysicalDevice physicalDevice, UInt32 queueFamilyIndex, bool* supported) const
|
||||
{
|
||||
VkBool32 presentationSupported = VK_FALSE;
|
||||
m_lastErrorCode = m_instance.vkGetPhysicalDeviceSurfaceSupportKHR(physicalDevice, queueFamilyIndex, m_surface, &presentationSupported);
|
||||
if (m_lastErrorCode != VkResult::VK_SUCCESS)
|
||||
{
|
||||
NazaraError("Failed to query surface capabilities: " + TranslateVulkanError(m_lastErrorCode));
|
||||
return false;
|
||||
}
|
||||
|
||||
*supported = (presentationSupported == VK_TRUE);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
inline Surface::operator VkSurfaceKHR() const
|
||||
{
|
||||
return m_surface;
|
||||
}
|
||||
|
||||
inline bool Surface::IsSupported(const Instance& instance)
|
||||
{
|
||||
if (!instance.IsExtensionLoaded(VK_KHR_SURFACE_EXTENSION_NAME))
|
||||
return false;
|
||||
|
||||
#ifdef VK_USE_PLATFORM_ANDROID_KHR
|
||||
if (instance.IsExtensionLoaded(VK_KHR_ANDROID_SURFACE_EXTENSION_NAME))
|
||||
return true;
|
||||
#endif
|
||||
|
||||
#ifdef VK_USE_PLATFORM_XCB_KHR
|
||||
if (instance.IsExtensionLoaded(VK_KHR_XCB_SURFACE_EXTENSION_NAME))
|
||||
return true;
|
||||
#endif
|
||||
|
||||
#ifdef VK_USE_PLATFORM_XLIB_KHR
|
||||
if (instance.IsExtensionLoaded(VK_KHR_XLIB_SURFACE_EXTENSION_NAME))
|
||||
return true;
|
||||
#endif
|
||||
|
||||
#ifdef VK_USE_PLATFORM_WAYLAND_KHR
|
||||
if (instance.IsExtensionLoaded(VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME))
|
||||
return true;
|
||||
#endif
|
||||
|
||||
#ifdef VK_USE_PLATFORM_WIN32_KHR
|
||||
if (instance.IsExtensionLoaded(VK_KHR_WIN32_SURFACE_EXTENSION_NAME))
|
||||
return true;
|
||||
#endif
|
||||
|
||||
#ifdef VK_USE_PLATFORM_METAL_EXT
|
||||
if (instance.IsExtensionLoaded(VK_EXT_METAL_SURFACE_EXTENSION_NAME))
|
||||
return true;
|
||||
#endif
|
||||
NazaraError("Failed to query surface capabilities: " + TranslateVulkanError(m_lastErrorCode));
|
||||
return false;
|
||||
}
|
||||
|
||||
inline bool Surface::Create(const VkAllocationCallbacks* allocator)
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool Surface::GetFormats(VkPhysicalDevice physicalDevice, std::vector<VkSurfaceFormatKHR>* surfaceFormats) const
|
||||
{
|
||||
// First, query format count
|
||||
UInt32 surfaceCount = 0; // Remember, Nz::UInt32 is a typedef on uint32_t
|
||||
m_lastErrorCode = m_instance.vkGetPhysicalDeviceSurfaceFormatsKHR(physicalDevice, m_surface, &surfaceCount, nullptr);
|
||||
if (m_lastErrorCode != VkResult::VK_SUCCESS || surfaceCount == 0)
|
||||
{
|
||||
if (m_lastErrorCode != VkResult::VK_SUCCESS)
|
||||
{
|
||||
NazaraError("Failed to create Vulkan surface: " + TranslateVulkanError(m_lastErrorCode));
|
||||
return false;
|
||||
}
|
||||
|
||||
// Store the allocator to access them when needed
|
||||
if (allocator)
|
||||
m_allocator = *allocator;
|
||||
else
|
||||
m_allocator.pfnAllocation = nullptr;
|
||||
|
||||
return true;
|
||||
NazaraError("Failed to query format count: " + TranslateVulkanError(m_lastErrorCode));
|
||||
return false;
|
||||
}
|
||||
|
||||
// Now we can get the list of the available physical device
|
||||
surfaceFormats->resize(surfaceCount);
|
||||
m_lastErrorCode = m_instance.vkGetPhysicalDeviceSurfaceFormatsKHR(physicalDevice, m_surface, &surfaceCount, surfaceFormats->data());
|
||||
if (m_lastErrorCode != VkResult::VK_SUCCESS)
|
||||
{
|
||||
NazaraError("Failed to query formats: " + TranslateVulkanError(m_lastErrorCode));
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool Surface::GetPresentModes(VkPhysicalDevice physicalDevice, std::vector<VkPresentModeKHR>* presentModes) const
|
||||
{
|
||||
// First, query present modes count
|
||||
UInt32 presentModeCount = 0; // Remember, Nz::UInt32 is a typedef on uint32_t
|
||||
m_lastErrorCode = m_instance.vkGetPhysicalDeviceSurfacePresentModesKHR(physicalDevice, m_surface, &presentModeCount, nullptr);
|
||||
if (m_lastErrorCode != VkResult::VK_SUCCESS || presentModeCount == 0)
|
||||
{
|
||||
NazaraError("Failed to query present mode count");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Now we can get the list of the available physical device
|
||||
presentModes->resize(presentModeCount);
|
||||
m_lastErrorCode = m_instance.vkGetPhysicalDeviceSurfacePresentModesKHR(physicalDevice, m_surface, &presentModeCount, presentModes->data());
|
||||
if (m_lastErrorCode != VkResult::VK_SUCCESS)
|
||||
{
|
||||
NazaraError("Failed to query present modes: " + TranslateVulkanError(m_lastErrorCode));
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool Surface::GetSupportPresentation(VkPhysicalDevice physicalDevice, UInt32 queueFamilyIndex, bool* supported) const
|
||||
{
|
||||
VkBool32 presentationSupported = VK_FALSE;
|
||||
m_lastErrorCode = m_instance.vkGetPhysicalDeviceSurfaceSupportKHR(physicalDevice, queueFamilyIndex, m_surface, &presentationSupported);
|
||||
if (m_lastErrorCode != VkResult::VK_SUCCESS)
|
||||
{
|
||||
NazaraError("Failed to query surface capabilities: " + TranslateVulkanError(m_lastErrorCode));
|
||||
return false;
|
||||
}
|
||||
|
||||
*supported = (presentationSupported == VK_TRUE);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
inline Surface::operator VkSurfaceKHR() const
|
||||
{
|
||||
return m_surface;
|
||||
}
|
||||
|
||||
inline bool Surface::IsSupported(const Instance& instance)
|
||||
{
|
||||
if (!instance.IsExtensionLoaded(VK_KHR_SURFACE_EXTENSION_NAME))
|
||||
return false;
|
||||
|
||||
#ifdef VK_USE_PLATFORM_ANDROID_KHR
|
||||
if (instance.IsExtensionLoaded(VK_KHR_ANDROID_SURFACE_EXTENSION_NAME))
|
||||
return true;
|
||||
#endif
|
||||
|
||||
#ifdef VK_USE_PLATFORM_XCB_KHR
|
||||
if (instance.IsExtensionLoaded(VK_KHR_XCB_SURFACE_EXTENSION_NAME))
|
||||
return true;
|
||||
#endif
|
||||
|
||||
#ifdef VK_USE_PLATFORM_XLIB_KHR
|
||||
if (instance.IsExtensionLoaded(VK_KHR_XLIB_SURFACE_EXTENSION_NAME))
|
||||
return true;
|
||||
#endif
|
||||
|
||||
#ifdef VK_USE_PLATFORM_WAYLAND_KHR
|
||||
if (instance.IsExtensionLoaded(VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME))
|
||||
return true;
|
||||
#endif
|
||||
|
||||
#ifdef VK_USE_PLATFORM_WIN32_KHR
|
||||
if (instance.IsExtensionLoaded(VK_KHR_WIN32_SURFACE_EXTENSION_NAME))
|
||||
return true;
|
||||
#endif
|
||||
|
||||
#ifdef VK_USE_PLATFORM_METAL_EXT
|
||||
if (instance.IsExtensionLoaded(VK_EXT_METAL_SURFACE_EXTENSION_NAME))
|
||||
return true;
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
inline bool Surface::Create(const VkAllocationCallbacks* allocator)
|
||||
{
|
||||
if (m_lastErrorCode != VkResult::VK_SUCCESS)
|
||||
{
|
||||
NazaraError("Failed to create Vulkan surface: " + TranslateVulkanError(m_lastErrorCode));
|
||||
return false;
|
||||
}
|
||||
|
||||
// Store the allocator to access them when needed
|
||||
if (allocator)
|
||||
m_allocator = *allocator;
|
||||
else
|
||||
m_allocator.pfnAllocation = nullptr;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
#define NAZARA_WIDGETS_BASEWIDGET_HPP
|
||||
|
||||
#include <Nazara/Graphics/Sprite.hpp>
|
||||
#include <Nazara/Platform/Event.hpp>
|
||||
#include <Nazara/Platform/WindowEvent.hpp>
|
||||
#include <Nazara/Platform/Mouse.hpp>
|
||||
#include <Nazara/Utility/Node.hpp>
|
||||
#include <Nazara/Widgets/Config.hpp>
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
#define NAZARA_WIDGETS_CANVAS_HPP
|
||||
|
||||
#include <Nazara/Platform/CursorController.hpp>
|
||||
#include <Nazara/Platform/EventHandler.hpp>
|
||||
#include <Nazara/Platform/WindowEventHandler.hpp>
|
||||
#include <Nazara/Widgets/BaseWidget.hpp>
|
||||
#include <entt/entity/registry.hpp>
|
||||
#include <bitset>
|
||||
|
|
@ -20,7 +20,7 @@ namespace Nz
|
|||
friend BaseWidget;
|
||||
|
||||
public:
|
||||
Canvas(entt::registry& registry, EventHandler& eventHandler, CursorControllerHandle cursorController, UInt32 renderMask, int initialRenderLayer = 0);
|
||||
Canvas(entt::registry& registry, WindowEventHandler& eventHandler, CursorControllerHandle cursorController, UInt32 renderMask, int initialRenderLayer = 0);
|
||||
Canvas(const Canvas&) = delete;
|
||||
Canvas(Canvas&&) = delete;
|
||||
inline ~Canvas();
|
||||
|
|
@ -32,8 +32,8 @@ namespace Nz
|
|||
Canvas& operator=(const Canvas&) = delete;
|
||||
Canvas& operator=(Canvas&&) = delete;
|
||||
|
||||
NazaraSignal(OnUnhandledKeyPressed, const EventHandler* /*eventHandler*/, const WindowEvent::KeyEvent& /*event*/);
|
||||
NazaraSignal(OnUnhandledKeyReleased, const EventHandler* /*eventHandler*/, const WindowEvent::KeyEvent& /*event*/);
|
||||
NazaraSignal(OnUnhandledKeyPressed, const WindowEventHandler* /*eventHandler*/, const WindowEvent::KeyEvent& /*event*/);
|
||||
NazaraSignal(OnUnhandledKeyReleased, const WindowEventHandler* /*eventHandler*/, const WindowEvent::KeyEvent& /*event*/);
|
||||
|
||||
protected:
|
||||
inline void ClearKeyboardOwner(std::size_t canvasIndex);
|
||||
|
|
@ -57,17 +57,17 @@ namespace Nz
|
|||
private:
|
||||
template<typename F> void DispatchEvent(std::size_t widgetIndex, F&& functor);
|
||||
|
||||
void OnEventMouseButtonPressed(const EventHandler* eventHandler, const WindowEvent::MouseButtonEvent& event);
|
||||
void OnEventMouseButtonRelease(const EventHandler* eventHandler, const WindowEvent::MouseButtonEvent& event);
|
||||
void OnEventMouseEntered(const EventHandler* eventHandler);
|
||||
void OnEventMouseLeft(const EventHandler* eventHandler);
|
||||
void OnEventMouseMoved(const EventHandler* eventHandler, const WindowEvent::MouseMoveEvent& event);
|
||||
void OnEventMouseButtonPressed(const WindowEventHandler* eventHandler, const WindowEvent::MouseButtonEvent& event);
|
||||
void OnEventMouseButtonRelease(const WindowEventHandler* eventHandler, const WindowEvent::MouseButtonEvent& event);
|
||||
void OnEventMouseEntered(const WindowEventHandler* eventHandler);
|
||||
void OnEventMouseLeft(const WindowEventHandler* eventHandler);
|
||||
void OnEventMouseMoved(const WindowEventHandler* eventHandler, const WindowEvent::MouseMoveEvent& event);
|
||||
|
||||
void OnEventMouseWheelMoved(const EventHandler* eventHandler, const WindowEvent::MouseWheelEvent& event);
|
||||
void OnEventKeyPressed(const EventHandler* eventHandler, const WindowEvent::KeyEvent& event);
|
||||
void OnEventKeyReleased(const EventHandler* eventHandler, const WindowEvent::KeyEvent& event);
|
||||
void OnEventTextEntered(const EventHandler* eventHandler, const WindowEvent::TextEvent& event);
|
||||
void OnEventTextEdited(const EventHandler* eventHandler, const WindowEvent::EditEvent& event);
|
||||
void OnEventMouseWheelMoved(const WindowEventHandler* eventHandler, const WindowEvent::MouseWheelEvent& event);
|
||||
void OnEventKeyPressed(const WindowEventHandler* eventHandler, const WindowEvent::KeyEvent& event);
|
||||
void OnEventKeyReleased(const WindowEventHandler* eventHandler, const WindowEvent::KeyEvent& event);
|
||||
void OnEventTextEntered(const WindowEventHandler* eventHandler, const WindowEvent::TextEvent& event);
|
||||
void OnEventTextEdited(const WindowEventHandler* eventHandler, const WindowEvent::EditEvent& event);
|
||||
|
||||
void UpdateHoveredWidget(int x, int y);
|
||||
|
||||
|
|
@ -78,16 +78,16 @@ namespace Nz
|
|||
SystemCursor cursor;
|
||||
};
|
||||
|
||||
NazaraSlot(EventHandler, OnKeyPressed, m_keyPressedSlot);
|
||||
NazaraSlot(EventHandler, OnKeyReleased, m_keyReleasedSlot);
|
||||
NazaraSlot(EventHandler, OnMouseButtonPressed, m_mouseButtonPressedSlot);
|
||||
NazaraSlot(EventHandler, OnMouseButtonReleased, m_mouseButtonReleasedSlot);
|
||||
NazaraSlot(EventHandler, OnMouseEntered, m_mouseEnteredSlot);
|
||||
NazaraSlot(EventHandler, OnMouseLeft, m_mouseLeftSlot);
|
||||
NazaraSlot(EventHandler, OnMouseMoved, m_mouseMovedSlot);
|
||||
NazaraSlot(EventHandler, OnMouseWheelMoved, m_mouseWheelMovedSlot);
|
||||
NazaraSlot(EventHandler, OnTextEntered, m_textEnteredSlot);
|
||||
NazaraSlot(EventHandler, OnTextEdited, m_textEditedSlot);
|
||||
NazaraSlot(WindowEventHandler, OnKeyPressed, m_keyPressedSlot);
|
||||
NazaraSlot(WindowEventHandler, OnKeyReleased, m_keyReleasedSlot);
|
||||
NazaraSlot(WindowEventHandler, OnMouseButtonPressed, m_mouseButtonPressedSlot);
|
||||
NazaraSlot(WindowEventHandler, OnMouseButtonReleased, m_mouseButtonReleasedSlot);
|
||||
NazaraSlot(WindowEventHandler, OnMouseEntered, m_mouseEnteredSlot);
|
||||
NazaraSlot(WindowEventHandler, OnMouseLeft, m_mouseLeftSlot);
|
||||
NazaraSlot(WindowEventHandler, OnMouseMoved, m_mouseMovedSlot);
|
||||
NazaraSlot(WindowEventHandler, OnMouseWheelMoved, m_mouseWheelMovedSlot);
|
||||
NazaraSlot(WindowEventHandler, OnTextEntered, m_textEnteredSlot);
|
||||
NazaraSlot(WindowEventHandler, OnTextEdited, m_textEditedSlot);
|
||||
|
||||
CursorControllerHandle m_cursorController;
|
||||
UInt32 m_renderMask;
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@
|
|||
#include <Nazara/Graphics/Components/GraphicsComponent.hpp>
|
||||
#include <Nazara/Renderer/CommandBufferBuilder.hpp>
|
||||
#include <Nazara/Renderer/RenderFrame.hpp>
|
||||
#include <Nazara/Renderer/RenderWindow.hpp>
|
||||
#include <Nazara/Renderer/WindowSwapchain.hpp>
|
||||
#include <Nazara/Renderer/UploadPool.hpp>
|
||||
#include <Nazara/Utility/Components/NodeComponent.hpp>
|
||||
#include <Nazara/Utility/Components/SharedSkeletonComponent.hpp>
|
||||
|
|
@ -48,13 +48,18 @@ namespace Nz
|
|||
m_pipeline.reset();
|
||||
}
|
||||
|
||||
WindowSwapchain& RenderSystem::CreateSwapchain(Window& window, const SwapchainParameters& parameters)
|
||||
{
|
||||
return *m_windowSwapchains.emplace_back(std::make_unique<WindowSwapchain>(Graphics::Instance()->GetRenderDevice(), window, parameters));
|
||||
}
|
||||
|
||||
void RenderSystem::Update(Time /*elapsedTime*/)
|
||||
{
|
||||
UpdateObservers();
|
||||
UpdateVisibility();
|
||||
UpdateInstances();
|
||||
|
||||
for (auto& windowPtr : m_renderWindows)
|
||||
for (auto& windowPtr : m_windowSwapchains)
|
||||
{
|
||||
RenderFrame frame = windowPtr->AcquireFrame();
|
||||
if (!frame)
|
||||
|
|
|
|||
|
|
@ -1,20 +0,0 @@
|
|||
// Copyright (C) 2022 Jérôme "Lynix" Leclercq (lynix680@gmail.com)
|
||||
// This file is part of the "Nazara Engine - OpenGL renderer"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#include <Nazara/OpenGLRenderer/DummySurface.hpp>
|
||||
#include <Nazara/OpenGLRenderer/Debug.hpp>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
bool DummySurface::Create(WindowHandle handle)
|
||||
{
|
||||
m_handle = handle;
|
||||
return true;
|
||||
}
|
||||
|
||||
void DummySurface::Destroy()
|
||||
{
|
||||
m_handle = WindowHandle{};
|
||||
}
|
||||
}
|
||||
|
|
@ -11,6 +11,7 @@
|
|||
#include <Nazara/OpenGLRenderer/OpenGLRenderPipeline.hpp>
|
||||
#include <Nazara/OpenGLRenderer/OpenGLRenderPipelineLayout.hpp>
|
||||
#include <Nazara/OpenGLRenderer/OpenGLShaderModule.hpp>
|
||||
#include <Nazara/OpenGLRenderer/OpenGLSwapchain.hpp>
|
||||
#include <Nazara/OpenGLRenderer/OpenGLTexture.hpp>
|
||||
#include <Nazara/OpenGLRenderer/OpenGLTextureSampler.hpp>
|
||||
#include <Nazara/OpenGLRenderer/Wrapper/Loader.hpp>
|
||||
|
|
@ -200,6 +201,11 @@ namespace Nz
|
|||
return std::make_shared<OpenGLShaderModule>(*this, shaderStages, lang, source, sourceSize, states);
|
||||
}
|
||||
|
||||
std::shared_ptr<Swapchain> OpenGLDevice::InstantiateSwapchain(WindowHandle windowHandle, const Vector2ui& windowSize, const SwapchainParameters& parameters)
|
||||
{
|
||||
return std::make_shared<OpenGLSwapchain>(*this, windowHandle, windowSize, parameters);
|
||||
}
|
||||
|
||||
std::shared_ptr<Texture> OpenGLDevice::InstantiateTexture(const TextureInfo& params)
|
||||
{
|
||||
return std::make_shared<OpenGLTexture>(*this, params);
|
||||
|
|
|
|||
|
|
@ -5,13 +5,13 @@
|
|||
#include <Nazara/OpenGLRenderer/OpenGLRenderImage.hpp>
|
||||
#include <Nazara/OpenGLRenderer/OpenGLCommandBuffer.hpp>
|
||||
#include <Nazara/OpenGLRenderer/OpenGLCommandBufferBuilder.hpp>
|
||||
#include <Nazara/OpenGLRenderer/OpenGLRenderWindow.hpp>
|
||||
#include <Nazara/OpenGLRenderer/OpenGLSwapchain.hpp>
|
||||
#include <stdexcept>
|
||||
#include <Nazara/OpenGLRenderer/Debug.hpp>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
OpenGLRenderImage::OpenGLRenderImage(OpenGLRenderWindow& owner) :
|
||||
OpenGLRenderImage::OpenGLRenderImage(OpenGLSwapchain& owner) :
|
||||
m_owner(owner),
|
||||
m_uploadPool(2 * 1024 * 1024)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -4,11 +4,9 @@
|
|||
|
||||
#include <Nazara/OpenGLRenderer/OpenGLRenderer.hpp>
|
||||
#include <Nazara/Core/ErrorFlags.hpp>
|
||||
#include <Nazara/OpenGLRenderer/DummySurface.hpp>
|
||||
#include <Nazara/OpenGLRenderer/OpenGLRenderWindow.hpp>
|
||||
#include <Nazara/OpenGLRenderer/OpenGLSwapchain.hpp>
|
||||
#include <Nazara/Renderer/RenderDevice.hpp>
|
||||
#include <Nazara/Renderer/RenderSurface.hpp>
|
||||
#include <Nazara/Renderer/RenderWindowImpl.hpp>
|
||||
#include <Nazara/Renderer/Swapchain.hpp>
|
||||
#include <cassert>
|
||||
#include <sstream>
|
||||
|
||||
|
|
@ -30,17 +28,7 @@ namespace Nz
|
|||
m_device.reset();
|
||||
}
|
||||
|
||||
std::unique_ptr<RenderSurface> OpenGLRenderer::CreateRenderSurfaceImpl()
|
||||
{
|
||||
return std::make_unique<DummySurface>();
|
||||
}
|
||||
|
||||
std::unique_ptr<RenderWindowImpl> OpenGLRenderer::CreateRenderWindowImpl(RenderWindow& owner)
|
||||
{
|
||||
return std::make_unique<OpenGLRenderWindow>(owner);
|
||||
}
|
||||
|
||||
std::shared_ptr<RenderDevice> OpenGLRenderer::InstanciateRenderDevice(std::size_t deviceIndex, const RenderDeviceFeatures& enabledFeatures)
|
||||
std::shared_ptr<RenderDevice> OpenGLRenderer::InstanciateRenderDevice([[maybe_unused]] std::size_t deviceIndex, const RenderDeviceFeatures& enabledFeatures)
|
||||
{
|
||||
assert(deviceIndex == 0);
|
||||
|
||||
|
|
|
|||
|
|
@ -2,64 +2,36 @@
|
|||
// This file is part of the "Nazara Engine - OpenGL renderer"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#include <Nazara/OpenGLRenderer/OpenGLRenderWindow.hpp>
|
||||
#include <Nazara/OpenGLRenderer/DummySurface.hpp>
|
||||
#include <Nazara/OpenGLRenderer/OpenGLSwapchain.hpp>
|
||||
#include <Nazara/OpenGLRenderer/OpenGLCommandPool.hpp>
|
||||
#include <Nazara/OpenGLRenderer/OpenGLRenderer.hpp>
|
||||
#include <Nazara/Renderer/CommandPool.hpp>
|
||||
#include <Nazara/Renderer/RenderWindow.hpp>
|
||||
#include <Nazara/Renderer/WindowSwapchain.hpp>
|
||||
#include <Nazara/OpenGLRenderer/Debug.hpp>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
OpenGLRenderWindow::OpenGLRenderWindow(RenderWindow& owner) :
|
||||
OpenGLSwapchain::OpenGLSwapchain(OpenGLDevice& device, WindowHandle windowHandle, const Vector2ui& windowSize, const SwapchainParameters& parameters) :
|
||||
m_currentFrame(0),
|
||||
m_framebuffer(*this),
|
||||
m_owner(owner)
|
||||
m_size(windowSize),
|
||||
m_sizeInvalidated(false)
|
||||
{
|
||||
}
|
||||
|
||||
RenderFrame OpenGLRenderWindow::Acquire()
|
||||
{
|
||||
if (m_owner.IsMinimized())
|
||||
return RenderFrame();
|
||||
|
||||
bool invalidateFramebuffer = false;
|
||||
Vector2ui size = m_owner.GetSize();
|
||||
if (m_size != size)
|
||||
{
|
||||
invalidateFramebuffer = true;
|
||||
|
||||
OnRenderTargetSizeChange(this, size);
|
||||
m_size = size;
|
||||
}
|
||||
|
||||
return RenderFrame(m_renderImage[m_currentFrame].get(), invalidateFramebuffer, m_size, 0);
|
||||
}
|
||||
|
||||
bool OpenGLRenderWindow::Create(RendererImpl* /*renderer*/, RenderSurface* surface, const RenderWindowParameters& parameters)
|
||||
{
|
||||
DummySurface* dummySurface = static_cast<DummySurface*>(surface);
|
||||
|
||||
OpenGLDevice& device = static_cast<OpenGLDevice&>(*m_owner.GetRenderDevice());
|
||||
|
||||
GL::ContextParams contextParams;
|
||||
#ifdef NAZARA_OPENGLRENDERER_DEBUG
|
||||
contextParams.wrapErrorHandling = true;
|
||||
#endif
|
||||
//TODO: Pass render window parameters to context
|
||||
//TODO: Pass swapchain parameters to context
|
||||
|
||||
m_context = device.CreateContext(contextParams, dummySurface->GetWindowHandle());
|
||||
m_context = device.CreateContext(contextParams, windowHandle);
|
||||
if (!m_context)
|
||||
return false;
|
||||
|
||||
m_size = m_owner.GetSize();
|
||||
throw std::runtime_error("failed to create swapchain context");
|
||||
|
||||
// TODO: extract the exact window pixel format
|
||||
PixelFormat colorFormat;
|
||||
switch (contextParams.bitsPerPixel)
|
||||
{
|
||||
case 8: colorFormat = PixelFormat::R8; break;
|
||||
case 8: colorFormat = PixelFormat::R8; break;
|
||||
case 16: colorFormat = PixelFormat::RG8; break;
|
||||
case 24: colorFormat = PixelFormat::RGB8; break;
|
||||
|
||||
|
|
@ -94,38 +66,52 @@ namespace Nz
|
|||
m_renderImage.reserve(RenderImageCount);
|
||||
for (std::size_t i = 0; i < RenderImageCount; ++i)
|
||||
m_renderImage.emplace_back(std::make_unique<OpenGLRenderImage>(*this));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
std::shared_ptr<CommandPool> OpenGLRenderWindow::CreateCommandPool(QueueType /*queueType*/)
|
||||
RenderFrame OpenGLSwapchain::AcquireFrame()
|
||||
{
|
||||
bool sizeInvalidated = m_sizeInvalidated;
|
||||
m_sizeInvalidated = false;
|
||||
|
||||
return RenderFrame(m_renderImage[m_currentFrame].get(), sizeInvalidated, m_size, 0);
|
||||
}
|
||||
|
||||
std::shared_ptr<CommandPool> OpenGLSwapchain::CreateCommandPool(QueueType /*queueType*/)
|
||||
{
|
||||
return std::make_unique<OpenGLCommandPool>();
|
||||
}
|
||||
|
||||
const OpenGLFramebuffer& OpenGLRenderWindow::GetFramebuffer(std::size_t i) const
|
||||
const OpenGLFramebuffer& OpenGLSwapchain::GetFramebuffer(std::size_t i) const
|
||||
{
|
||||
assert(i == 0);
|
||||
NazaraUnused(i);
|
||||
return m_framebuffer;
|
||||
}
|
||||
|
||||
std::size_t OpenGLRenderWindow::GetFramebufferCount() const
|
||||
std::size_t OpenGLSwapchain::GetFramebufferCount() const
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
const OpenGLRenderPass& OpenGLRenderWindow::GetRenderPass() const
|
||||
const OpenGLRenderPass& OpenGLSwapchain::GetRenderPass() const
|
||||
{
|
||||
return *m_renderPass;
|
||||
}
|
||||
|
||||
const Vector2ui& OpenGLRenderWindow::GetSize() const
|
||||
const Vector2ui& OpenGLSwapchain::GetSize() const
|
||||
{
|
||||
return m_size;
|
||||
}
|
||||
|
||||
void OpenGLRenderWindow::Present()
|
||||
void OpenGLSwapchain::NotifyResize(const Vector2ui& newSize)
|
||||
{
|
||||
OnRenderTargetSizeChange(this, newSize);
|
||||
|
||||
m_size = newSize;
|
||||
m_sizeInvalidated = true;
|
||||
}
|
||||
|
||||
void OpenGLSwapchain::Present()
|
||||
{
|
||||
m_context->SwapBuffers();
|
||||
m_currentFrame = (m_currentFrame + 1) % m_renderImage.size();
|
||||
|
|
@ -3,7 +3,7 @@
|
|||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#include <Nazara/OpenGLRenderer/OpenGLWindowFramebuffer.hpp>
|
||||
#include <Nazara/OpenGLRenderer/OpenGLRenderWindow.hpp>
|
||||
#include <Nazara/OpenGLRenderer/OpenGLSwapchain.hpp>
|
||||
#include <stdexcept>
|
||||
#include <Nazara/OpenGLRenderer/Debug.hpp>
|
||||
|
||||
|
|
|
|||
|
|
@ -3,12 +3,25 @@
|
|||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#include <Nazara/Platform/AppWindowingComponent.hpp>
|
||||
#include <Nazara/Core/ApplicationBase.hpp>
|
||||
#include <Nazara/Platform/Debug.hpp>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
void AppWindowingComponent::Update(Time elapsedTime)
|
||||
{
|
||||
// SDL_PollEvent
|
||||
Window::ProcessEvents();
|
||||
|
||||
for (auto it = m_windows.begin(); it != m_windows.end();)
|
||||
{
|
||||
Window& window = **it;
|
||||
if (!window.IsOpen(true))
|
||||
it = m_windows.erase(it);
|
||||
else
|
||||
++it;
|
||||
}
|
||||
|
||||
if (m_quitOnLastWindowClosed && m_windows.empty())
|
||||
GetApp().Quit();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -34,16 +34,11 @@ namespace Nz
|
|||
{
|
||||
switch (sdlButton)
|
||||
{
|
||||
case SDL_BUTTON_LEFT:
|
||||
return Mouse::Left;
|
||||
case SDL_BUTTON_MIDDLE:
|
||||
return Mouse::Middle;
|
||||
case SDL_BUTTON_RIGHT:
|
||||
return Mouse::Right;
|
||||
case SDL_BUTTON_X1:
|
||||
return Mouse::XButton1;
|
||||
case SDL_BUTTON_X2:
|
||||
return Mouse::XButton2;
|
||||
case SDL_BUTTON_LEFT: return Mouse::Left;
|
||||
case SDL_BUTTON_MIDDLE: return Mouse::Middle;
|
||||
case SDL_BUTTON_RIGHT: return Mouse::Right;
|
||||
case SDL_BUTTON_X1: return Mouse::XButton1;
|
||||
case SDL_BUTTON_X2: return Mouse::XButton2;
|
||||
default:
|
||||
NazaraAssert(false, "Unkown mouse button");
|
||||
return Mouse::Left;
|
||||
|
|
@ -54,30 +49,16 @@ namespace Nz
|
|||
WindowImpl::WindowImpl(Window* parent) :
|
||||
m_cursor(nullptr),
|
||||
m_handle(nullptr),
|
||||
//m_callback(0),
|
||||
m_style(0),
|
||||
m_maxSize(-1),
|
||||
m_minSize(-1),
|
||||
m_parent(parent),
|
||||
m_keyRepeat(true),
|
||||
m_mouseInside(false),
|
||||
m_smoothScrolling(false),
|
||||
m_scrolling(0)
|
||||
m_eventListener(false),
|
||||
m_ignoreNextMouseMove(false),
|
||||
m_lastEditEventLength(0)
|
||||
{
|
||||
m_cursor = SDL_GetDefaultCursor();
|
||||
}
|
||||
|
||||
bool WindowImpl::Create(const VideoMode& mode, const std::string& title, WindowStyleFlags style)
|
||||
{
|
||||
bool async = (style & WindowStyle::Threaded) != 0;
|
||||
if (async)
|
||||
{
|
||||
NazaraError("SDL2 backend doesn't support asyn window for now");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool fullscreen = (style & WindowStyle::Fullscreen) != 0;
|
||||
|
||||
Uint32 winStyle = 0;
|
||||
|
|
@ -88,7 +69,6 @@ namespace Nz
|
|||
if (fullscreen)
|
||||
winStyle |= SDL_WINDOW_FULLSCREEN;
|
||||
|
||||
// Testé une seconde fois car sa valeur peut changer
|
||||
if (fullscreen)
|
||||
{
|
||||
x = 0;
|
||||
|
|
@ -105,72 +85,106 @@ namespace Nz
|
|||
|
||||
if (style & WindowStyle::Resizable)
|
||||
winStyle |= SDL_WINDOW_RESIZABLE;
|
||||
if (style & WindowStyle::Max)
|
||||
winStyle |= SDL_WINDOW_MAXIMIZED;
|
||||
|
||||
m_eventListener = true;
|
||||
m_ownsWindow = true;
|
||||
m_sizemove = false;
|
||||
m_style = style;
|
||||
|
||||
m_handle = SDL_CreateWindow(title.c_str(), x, y, width, height, winStyle);
|
||||
|
||||
if (!m_handle)
|
||||
{
|
||||
NazaraError("Failed to create window: " + Error::GetLastSystemError());
|
||||
return false;
|
||||
}
|
||||
|
||||
PrepareWindow(fullscreen);
|
||||
|
||||
SDL_AddEventWatch(HandleEvent, this);
|
||||
|
||||
m_windowId = SDL_GetWindowID(m_handle);
|
||||
SetEventListener(true);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool WindowImpl::Create(void* handle)
|
||||
bool WindowImpl::Create(WindowHandle handle)
|
||||
{
|
||||
m_handle = SDL_CreateWindowFrom(handle);
|
||||
void* systemHandle = nullptr;
|
||||
switch (handle.type)
|
||||
{
|
||||
case WindowBackend::Invalid:
|
||||
{
|
||||
NazaraError("unsupported creation from a Wayland handle");
|
||||
return false;
|
||||
}
|
||||
|
||||
case WindowBackend::Wayland:
|
||||
{
|
||||
NazaraError("unsupported creation from a Wayland handle");
|
||||
return false;
|
||||
}
|
||||
|
||||
case WindowBackend::Cocoa: systemHandle = handle.cocoa.window; break;
|
||||
case WindowBackend::X11: systemHandle = (void*) handle.x11.window; break;
|
||||
case WindowBackend::Windows: systemHandle = handle.windows.window; break;
|
||||
}
|
||||
|
||||
m_ownsWindow = false;
|
||||
|
||||
m_handle = SDL_CreateWindowFrom(systemHandle);
|
||||
if (!m_handle)
|
||||
{
|
||||
NazaraError("Invalid handle");
|
||||
return false;
|
||||
}
|
||||
|
||||
m_eventListener = false;
|
||||
m_ownsWindow = false;
|
||||
m_sizemove = false;
|
||||
|
||||
SDL_GetWindowPosition(m_handle, &m_position.x, &m_position.y);
|
||||
|
||||
int width;
|
||||
int height;
|
||||
SDL_GetWindowSize(m_handle, &width, &height);
|
||||
|
||||
m_size.Set(width, height);
|
||||
|
||||
m_windowId = SDL_GetWindowID(m_handle);
|
||||
SetEventListener(true);
|
||||
return true;
|
||||
}
|
||||
|
||||
void WindowImpl::Destroy()
|
||||
{
|
||||
if (m_ownsWindow && m_handle)
|
||||
SetEventListener(false);
|
||||
|
||||
if (m_handle)
|
||||
{
|
||||
SDL_DelEventWatch(HandleEvent, this);
|
||||
SDL_DestroyWindow(m_handle);
|
||||
if (m_ownsWindow)
|
||||
SDL_DestroyWindow(m_handle);
|
||||
|
||||
m_handle = nullptr;
|
||||
}
|
||||
else
|
||||
SetEventListener(false);
|
||||
}
|
||||
|
||||
void WindowImpl::EnableKeyRepeat(bool enable)
|
||||
Vector2i WindowImpl::FetchPosition() const
|
||||
{
|
||||
m_keyRepeat = enable;
|
||||
int x, y;
|
||||
SDL_GetWindowPosition(m_handle, &x, &y);
|
||||
|
||||
return { x, y };
|
||||
}
|
||||
|
||||
void WindowImpl::EnableSmoothScrolling(bool enable)
|
||||
Vector2ui WindowImpl::FetchSize() const
|
||||
{
|
||||
m_smoothScrolling = enable;
|
||||
int width, height;
|
||||
SDL_GetWindowSize(m_handle, &width, &height);
|
||||
|
||||
return { SafeCast<unsigned int>(width), SafeCast<unsigned int>(height) };
|
||||
}
|
||||
|
||||
WindowStyleFlags WindowImpl::FetchStyle() const
|
||||
{
|
||||
UInt32 windowFlags = SDL_GetWindowFlags(m_handle);
|
||||
|
||||
WindowStyleFlags styleFlags;
|
||||
if (windowFlags & SDL_WINDOW_RESIZABLE)
|
||||
styleFlags |= WindowStyle::Resizable;
|
||||
|
||||
if ((windowFlags & SDL_WINDOW_BORDERLESS) == 0)
|
||||
styleFlags |= WindowStyle::Titlebar | WindowStyle::Closable;
|
||||
|
||||
if (windowFlags & SDL_WINDOW_FULLSCREEN)
|
||||
styleFlags |= WindowStyle::Fullscreen;
|
||||
|
||||
return styleFlags;
|
||||
}
|
||||
|
||||
std::string WindowImpl::FetchTitle() const
|
||||
{
|
||||
return SDL_GetWindowTitle(m_handle);
|
||||
}
|
||||
|
||||
SDL_Window* WindowImpl::GetHandle() const
|
||||
|
|
@ -178,21 +192,6 @@ namespace Nz
|
|||
return m_handle;
|
||||
}
|
||||
|
||||
Vector2i WindowImpl::GetPosition() const
|
||||
{
|
||||
return m_position;
|
||||
}
|
||||
|
||||
Vector2ui WindowImpl::GetSize() const
|
||||
{
|
||||
return m_size;
|
||||
}
|
||||
|
||||
WindowStyleFlags WindowImpl::GetStyle() const
|
||||
{
|
||||
return m_style;
|
||||
}
|
||||
|
||||
WindowHandle WindowImpl::GetSystemHandle() const
|
||||
{
|
||||
SDL_SysWMinfo wmInfo;
|
||||
|
|
@ -253,22 +252,14 @@ namespace Nz
|
|||
return handle;
|
||||
}
|
||||
|
||||
std::string WindowImpl::GetTitle() const
|
||||
{
|
||||
return SDL_GetWindowTitle(m_handle);
|
||||
}
|
||||
|
||||
bool WindowImpl::HasFocus() const
|
||||
{
|
||||
return (SDL_GetWindowFlags(m_handle) & SDL_WINDOW_INPUT_FOCUS) != 0;
|
||||
}
|
||||
|
||||
void WindowImpl::IgnoreNextMouseEvent(int mouseX, int mouseY)
|
||||
void WindowImpl::IgnoreNextMouseEvent(int /*mouseX*/, int /*mouseY*/)
|
||||
{
|
||||
m_ignoreNextMouseMove = true;
|
||||
// Petite astuce ... probablement foireuse dans certains cas :ahde:
|
||||
m_mousePos.x = mouseX;
|
||||
m_mousePos.y = mouseY;
|
||||
}
|
||||
|
||||
bool WindowImpl::IsMinimized() const
|
||||
|
|
@ -297,27 +288,7 @@ namespace Nz
|
|||
}
|
||||
}
|
||||
|
||||
void WindowImpl::ProcessEvents(bool block)
|
||||
{
|
||||
if (m_ownsWindow)
|
||||
SDL_PumpEvents();
|
||||
|
||||
|
||||
/*if (m_ownsWindow)
|
||||
{
|
||||
if (block)
|
||||
WaitMessage();
|
||||
|
||||
MSG message;
|
||||
while (PeekMessageW(&message, nullptr, 0, 0, PM_REMOVE))
|
||||
{
|
||||
TranslateMessage(&message);
|
||||
DispatchMessageW(&message);
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
int WindowImpl::HandleEvent(void *userdata, SDL_Event* event)
|
||||
int WindowImpl::HandleEvent(void* userdata, SDL_Event* event)
|
||||
{
|
||||
try
|
||||
{
|
||||
|
|
@ -327,7 +298,7 @@ namespace Nz
|
|||
{
|
||||
case SDL_WINDOWEVENT:
|
||||
{
|
||||
if (SDL_GetWindowID(window->m_handle) != event->window.windowID)
|
||||
if (window->m_windowId != event->window.windowID)
|
||||
return 0;
|
||||
|
||||
WindowEvent windowEvent;
|
||||
|
|
@ -337,20 +308,16 @@ namespace Nz
|
|||
windowEvent.type = WindowEventType::Quit;
|
||||
break;
|
||||
|
||||
case SDL_WINDOWEVENT_RESIZED:
|
||||
case SDL_WINDOWEVENT_SIZE_CHANGED:
|
||||
windowEvent.type = WindowEventType::Resized;
|
||||
windowEvent.size.width = static_cast<unsigned int>(std::max(0, event->window.data1));
|
||||
windowEvent.size.height = static_cast<unsigned int>(std::max(0, event->window.data2));
|
||||
|
||||
window->m_size.Set(windowEvent.size.width, windowEvent.size.height);
|
||||
break;
|
||||
|
||||
case SDL_WINDOWEVENT_MOVED:
|
||||
windowEvent.type = WindowEventType::Moved;
|
||||
windowEvent.position.x = event->window.data1;
|
||||
windowEvent.position.y = event->window.data2;
|
||||
|
||||
window->m_position.Set(event->window.data1, event->window.data2);
|
||||
break;
|
||||
|
||||
case SDL_WINDOWEVENT_FOCUS_GAINED:
|
||||
|
|
@ -364,23 +331,35 @@ namespace Nz
|
|||
|
||||
case SDL_WINDOWEVENT_ENTER:
|
||||
windowEvent.type = WindowEventType::MouseEntered;
|
||||
window->RefreshCursor();
|
||||
break;
|
||||
|
||||
case SDL_WINDOWEVENT_LEAVE:
|
||||
windowEvent.type = WindowEventType::MouseLeft;
|
||||
break;
|
||||
|
||||
case SDL_WINDOWEVENT_MINIMIZED:
|
||||
windowEvent.type = WindowEventType::Minimized;
|
||||
break;
|
||||
|
||||
case SDL_WINDOWEVENT_RESTORED:
|
||||
windowEvent.type = WindowEventType::Restored;
|
||||
break;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
window->m_parent->PushEvent(windowEvent);
|
||||
window->m_parent->HandleEvent(windowEvent);
|
||||
break;
|
||||
}
|
||||
|
||||
case SDL_MOUSEMOTION:
|
||||
{
|
||||
if (SDL_GetWindowID(window->m_handle) != event->motion.windowID)
|
||||
if (window->m_windowId != event->motion.windowID)
|
||||
return 0;
|
||||
|
||||
if (window->m_ignoreNextMouseMove /*&& event->motion.x == window->m_mousePos.x && event->motion.y == window->m_mousePos.y*/)
|
||||
if (window->m_ignoreNextMouseMove)
|
||||
{
|
||||
window->m_ignoreNextMouseMove = false;
|
||||
return 0;
|
||||
|
|
@ -393,13 +372,13 @@ namespace Nz
|
|||
windowEvent.mouseMove.deltaX = event->motion.xrel;
|
||||
windowEvent.mouseMove.deltaY = event->motion.yrel;
|
||||
|
||||
window->m_parent->PushEvent(windowEvent);
|
||||
window->m_parent->HandleEvent(windowEvent);
|
||||
break;
|
||||
}
|
||||
|
||||
case SDL_MOUSEBUTTONDOWN:
|
||||
{
|
||||
if (SDL_GetWindowID(window->m_handle) != event->button.windowID)
|
||||
if (window->m_windowId != event->button.windowID)
|
||||
return 0;
|
||||
|
||||
WindowEvent windowEvent;
|
||||
|
|
@ -409,13 +388,13 @@ namespace Nz
|
|||
windowEvent.mouseButton.y = event->button.y;
|
||||
windowEvent.mouseButton.clickCount = event->button.clicks;
|
||||
|
||||
window->m_parent->PushEvent(windowEvent);
|
||||
window->m_parent->HandleEvent(windowEvent);
|
||||
break;
|
||||
}
|
||||
|
||||
case SDL_MOUSEBUTTONUP:
|
||||
{
|
||||
if (SDL_GetWindowID(window->m_handle) != event->button.windowID)
|
||||
if (window->m_windowId != event->button.windowID)
|
||||
return 0;
|
||||
|
||||
WindowEvent windowEvent;
|
||||
|
|
@ -424,25 +403,28 @@ namespace Nz
|
|||
windowEvent.mouseButton.x = event->button.x;
|
||||
windowEvent.mouseButton.y = event->button.y;
|
||||
|
||||
window->m_parent->PushEvent(windowEvent);
|
||||
window->m_parent->HandleEvent(windowEvent);
|
||||
break;
|
||||
}
|
||||
|
||||
case SDL_MOUSEWHEEL:
|
||||
{
|
||||
if (SDL_GetWindowID(window->m_handle) != event->wheel.windowID)
|
||||
if (window->m_windowId != event->wheel.windowID)
|
||||
return 0;
|
||||
|
||||
WindowEvent windowEvent;
|
||||
windowEvent.type = WindowEventType::MouseWheelMoved;
|
||||
windowEvent.mouseWheel.delta = event->wheel.y;
|
||||
windowEvent.mouseWheel.delta = event->wheel.preciseY;
|
||||
windowEvent.mouseWheel.x = event->wheel.mouseX;
|
||||
windowEvent.mouseWheel.y = event->wheel.mouseY;
|
||||
|
||||
window->m_parent->PushEvent(windowEvent);
|
||||
window->m_parent->HandleEvent(windowEvent);
|
||||
break;
|
||||
}
|
||||
|
||||
case SDL_KEYDOWN:
|
||||
if (SDL_GetWindowID(window->m_handle) != event->key.windowID)
|
||||
{
|
||||
if (window->m_windowId != event->key.windowID)
|
||||
return 0;
|
||||
|
||||
WindowEvent windowEvent;
|
||||
|
|
@ -455,7 +437,7 @@ namespace Nz
|
|||
windowEvent.key.system = (event->key.keysym.mod & KMOD_GUI) != 0;
|
||||
windowEvent.key.virtualKey = SDLHelper::FromSDL(event->key.keysym.sym);
|
||||
|
||||
window->m_parent->PushEvent(windowEvent);
|
||||
window->m_parent->HandleEvent(windowEvent);
|
||||
|
||||
// implements X11/Win32 APIs behavior for Enter and Backspace
|
||||
switch (windowEvent.key.virtualKey)
|
||||
|
|
@ -470,7 +452,7 @@ namespace Nz
|
|||
windowEvent.text.character = U'\n';
|
||||
windowEvent.text.repeated = event->key.repeat != 0;
|
||||
|
||||
window->m_parent->PushEvent(windowEvent);
|
||||
window->m_parent->HandleEvent(windowEvent);
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -479,7 +461,7 @@ namespace Nz
|
|||
windowEvent.text.character = U'\b';
|
||||
windowEvent.text.repeated = event->key.repeat != 0;
|
||||
|
||||
window->m_parent->PushEvent(windowEvent);
|
||||
window->m_parent->HandleEvent(windowEvent);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
|
@ -487,12 +469,14 @@ namespace Nz
|
|||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case SDL_KEYUP:
|
||||
{
|
||||
if (SDL_GetWindowID(window->m_handle) != event->key.windowID)
|
||||
if (window->m_windowId != event->key.windowID)
|
||||
return 0;
|
||||
|
||||
WindowEvent windowEvent;
|
||||
windowEvent.type = WindowEventType::KeyReleased;
|
||||
windowEvent.key.alt = (event->key.keysym.mod & KMOD_ALT) != 0;
|
||||
windowEvent.key.control = (event->key.keysym.mod & KMOD_CTRL) != 0;
|
||||
|
|
@ -502,15 +486,16 @@ namespace Nz
|
|||
windowEvent.key.system = (event->key.keysym.mod & KMOD_GUI) != 0;
|
||||
windowEvent.key.virtualKey = SDLHelper::FromSDL(event->key.keysym.sym);
|
||||
|
||||
window->m_parent->PushEvent(windowEvent);
|
||||
window->m_parent->HandleEvent(windowEvent);
|
||||
break;
|
||||
}
|
||||
|
||||
case SDL_TEXTINPUT:
|
||||
{
|
||||
if (SDL_GetWindowID(window->m_handle) != event->text.windowID)
|
||||
if (window->m_windowId != event->text.windowID)
|
||||
return 0;
|
||||
|
||||
WindowEvent windowEvent;
|
||||
windowEvent.type = WindowEventType::TextEntered;
|
||||
windowEvent.text.repeated = false;
|
||||
|
||||
|
|
@ -519,7 +504,7 @@ namespace Nz
|
|||
{
|
||||
windowEvent.text.character = *it;
|
||||
|
||||
window->m_parent->PushEvent(windowEvent);
|
||||
window->m_parent->HandleEvent(windowEvent);
|
||||
}
|
||||
while (*it++);
|
||||
|
||||
|
|
@ -528,9 +513,10 @@ namespace Nz
|
|||
|
||||
case SDL_TEXTEDITING:
|
||||
{
|
||||
if (SDL_GetWindowID(window->m_handle) != event->edit.windowID)
|
||||
if (window->m_windowId != event->edit.windowID)
|
||||
return 0;
|
||||
|
||||
WindowEvent windowEvent;
|
||||
windowEvent.type = WindowEventType::TextEdited;
|
||||
windowEvent.edit.length = event->edit.length;
|
||||
window->m_lastEditEventLength = windowEvent.edit.length;
|
||||
|
|
@ -540,7 +526,7 @@ namespace Nz
|
|||
windowEvent.edit.text[i] = event->edit.text[i];
|
||||
}
|
||||
|
||||
window->m_parent->PushEvent(windowEvent);
|
||||
window->m_parent->HandleEvent(windowEvent);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -557,7 +543,7 @@ namespace Nz
|
|||
return 0;
|
||||
}
|
||||
|
||||
void WindowImpl::SetCursor(const Cursor& cursor)
|
||||
void WindowImpl::UpdateCursor(const Cursor& cursor)
|
||||
{
|
||||
m_cursor = cursor.m_impl->GetCursor();
|
||||
|
||||
|
|
@ -565,73 +551,57 @@ namespace Nz
|
|||
RefreshCursor();
|
||||
}
|
||||
|
||||
void WindowImpl::SetEventListener(bool listener)
|
||||
{
|
||||
if (m_ownsWindow)
|
||||
return;
|
||||
|
||||
if (listener)
|
||||
SDL_AddEventWatch(HandleEvent, this);
|
||||
else
|
||||
SDL_DelEventWatch(HandleEvent, this);
|
||||
}
|
||||
|
||||
void WindowImpl::SetFocus()
|
||||
void WindowImpl::RaiseFocus()
|
||||
{
|
||||
SDL_RaiseWindow(m_handle);
|
||||
}
|
||||
|
||||
void WindowImpl::SetIcon(const Icon& icon)
|
||||
void WindowImpl::UpdateIcon(const Icon& icon)
|
||||
{
|
||||
SDL_SetWindowIcon(m_handle, icon.m_impl->GetIcon());
|
||||
}
|
||||
|
||||
void WindowImpl::SetMaximumSize(int width, int height)
|
||||
void WindowImpl::UpdateMaximumSize(int width, int height)
|
||||
{
|
||||
SDL_SetWindowMaximumSize(m_handle, width, height);
|
||||
}
|
||||
|
||||
void WindowImpl::SetMinimumSize(int width, int height)
|
||||
void WindowImpl::UpdateMinimumSize(int width, int height)
|
||||
{
|
||||
SDL_SetWindowMinimumSize(m_handle, width, height);
|
||||
}
|
||||
|
||||
void WindowImpl::SetPosition(int x, int y)
|
||||
void WindowImpl::UpdatePosition(int x, int y)
|
||||
{
|
||||
SDL_SetWindowPosition(m_handle, x, y);
|
||||
}
|
||||
|
||||
void WindowImpl::SetSize(unsigned int width, unsigned int height)
|
||||
void WindowImpl::UpdateSize(unsigned int width, unsigned int height)
|
||||
{
|
||||
m_size.Set(width, height);
|
||||
SDL_SetWindowSize(m_handle, width, height);
|
||||
}
|
||||
|
||||
void WindowImpl::SetStayOnTop(bool stayOnTop)
|
||||
void WindowImpl::UpdateStayOnTop(bool stayOnTop)
|
||||
{
|
||||
NazaraDebug("Stay on top isn't supported by SDL2 backend for now");
|
||||
SDL_SetWindowAlwaysOnTop(m_handle, (stayOnTop) ? SDL_TRUE : SDL_FALSE);
|
||||
}
|
||||
|
||||
void WindowImpl::SetTitle(const std::string& title)
|
||||
void WindowImpl::UpdateTitle(const std::string& title)
|
||||
{
|
||||
SDL_SetWindowTitle(m_handle, title.c_str());
|
||||
}
|
||||
|
||||
void WindowImpl::SetVisible(bool visible)
|
||||
void WindowImpl::Show(bool visible)
|
||||
{
|
||||
visible ? SDL_ShowWindow(m_handle) : SDL_HideWindow(m_handle);
|
||||
if (visible)
|
||||
SDL_ShowWindow(m_handle);
|
||||
else
|
||||
SDL_HideWindow(m_handle);
|
||||
}
|
||||
|
||||
void WindowImpl::PrepareWindow(bool fullscreen)
|
||||
void WindowImpl::ProcessEvents()
|
||||
{
|
||||
(void)fullscreen; // ignore param warning
|
||||
|
||||
SDL_GetWindowPosition(m_handle, &m_position.x, &m_position.y);
|
||||
|
||||
int width, height;
|
||||
SDL_GetWindowSize(m_handle, &width, &height);
|
||||
|
||||
m_size.Set(width, height);
|
||||
SDL_PumpEvents();
|
||||
}
|
||||
|
||||
bool WindowImpl::Initialize()
|
||||
|
|
@ -650,27 +620,18 @@ namespace Nz
|
|||
SDL_Quit();
|
||||
}
|
||||
|
||||
// not implemented for now, wait for mainloop friendly input
|
||||
//void WindowImpl::WindowThread(SDL_Window* handle, /*DWORD styleEx,*/ const String& title, /*DWORD style,*/ bool fullscreen, const Rectui& dimensions, WindowImpl* window, Mutex* mutex, ConditionVariable* condition)
|
||||
//{
|
||||
// SDL_Window& winHandle = *handle;
|
||||
/*winHandle = CreateWindowExW(styleEx, className, title.GetWideString().data(), style, dimensions.x, dimensions.y, dimensions.width, dimensions.height, nullptr, nullptr, GetModuleHandle(nullptr), window);
|
||||
void WindowImpl::SetEventListener(bool listener)
|
||||
{
|
||||
if (m_eventListener == listener)
|
||||
return;
|
||||
|
||||
if (winHandle)
|
||||
window->PrepareWindow(fullscreen);
|
||||
if (listener)
|
||||
SDL_AddEventWatch(HandleEvent, this);
|
||||
else
|
||||
SDL_DelEventWatch(HandleEvent, this);
|
||||
|
||||
mutex->Lock();
|
||||
condition->Signal();
|
||||
mutex->Unlock(); // mutex and condition may be destroyed after this line
|
||||
|
||||
if (!winHandle)
|
||||
return;
|
||||
|
||||
while (window->m_threadActive)
|
||||
window->ProcessEvents(true);
|
||||
|
||||
DestroyWindow(winHandle);*/
|
||||
//}
|
||||
m_eventListener = listener;
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(NAZARA_PLATFORM_WINDOWS)
|
||||
|
|
|
|||
|
|
@ -35,19 +35,17 @@ namespace Nz
|
|||
~WindowImpl() = default;
|
||||
|
||||
bool Create(const VideoMode& mode, const std::string& title, WindowStyleFlags style);
|
||||
bool Create(void* handle);
|
||||
bool Create(WindowHandle handle);
|
||||
|
||||
void Destroy();
|
||||
|
||||
void EnableKeyRepeat(bool enable);
|
||||
void EnableSmoothScrolling(bool enable);
|
||||
Vector2i FetchPosition() const;
|
||||
Vector2ui FetchSize() const;
|
||||
WindowStyleFlags FetchStyle() const;
|
||||
std::string FetchTitle() const;
|
||||
|
||||
SDL_Window* GetHandle() const;
|
||||
Vector2i GetPosition() const;
|
||||
Vector2ui GetSize() const;
|
||||
WindowStyleFlags GetStyle() const;
|
||||
WindowHandle GetSystemHandle() const;
|
||||
std::string GetTitle() const;
|
||||
|
||||
bool HasFocus() const;
|
||||
|
||||
|
|
@ -56,52 +54,40 @@ namespace Nz
|
|||
bool IsMinimized() const;
|
||||
bool IsVisible() const;
|
||||
|
||||
void RaiseFocus();
|
||||
void RefreshCursor();
|
||||
|
||||
void ProcessEvents(bool block);
|
||||
void UpdateCursor(const Cursor& cursor);
|
||||
void UpdateIcon(const Icon& icon);
|
||||
void UpdateMaximumSize(int width, int height);
|
||||
void UpdateMinimumSize(int width, int height);
|
||||
void UpdatePosition(int x, int y);
|
||||
void UpdateSize(unsigned int width, unsigned int height);
|
||||
void UpdateStayOnTop(bool stayOnTop);
|
||||
void UpdateTitle(const std::string& title);
|
||||
|
||||
void SetCursor(const Cursor& cursor);
|
||||
void SetEventListener(bool listener);
|
||||
void SetFocus();
|
||||
void SetIcon(const Icon& icon);
|
||||
void SetMaximumSize(int width, int height);
|
||||
void SetMinimumSize(int width, int height);
|
||||
void SetPosition(int x, int y);
|
||||
void SetSize(unsigned int width, unsigned int height);
|
||||
void SetStayOnTop(bool stayOnTop);
|
||||
void SetTitle(const std::string& title);
|
||||
void SetVisible(bool visible);
|
||||
void Show(bool visible);
|
||||
|
||||
WindowImpl& operator=(const WindowImpl&) = delete;
|
||||
WindowImpl& operator=(WindowImpl&&) = delete; ///TODO?
|
||||
|
||||
static void ProcessEvents();
|
||||
static bool Initialize();
|
||||
static void Uninitialize();
|
||||
|
||||
private:
|
||||
void SetEventListener(bool listener);
|
||||
|
||||
static int SDLCALL HandleEvent(void* userdata, SDL_Event* event);
|
||||
|
||||
void PrepareWindow(bool fullscreen);
|
||||
|
||||
int m_lastEditEventLength = 0;
|
||||
UInt32 m_windowId;
|
||||
SDL_Cursor* m_cursor;
|
||||
SDL_Window* m_handle;
|
||||
WindowStyleFlags m_style;
|
||||
Vector2i m_maxSize;
|
||||
Vector2i m_minSize;
|
||||
Vector2i m_mousePos;
|
||||
Vector2i m_position;
|
||||
Vector2ui m_size;
|
||||
Window* m_parent;
|
||||
bool m_eventListener;
|
||||
bool m_ignoreNextMouseMove = false;
|
||||
bool m_keyRepeat;
|
||||
bool m_mouseInside;
|
||||
bool m_ignoreNextMouseMove;
|
||||
bool m_ownsWindow;
|
||||
bool m_sizemove;
|
||||
bool m_smoothScrolling;
|
||||
bool m_threadActive;
|
||||
short m_scrolling;
|
||||
int m_lastEditEventLength;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -12,33 +12,22 @@
|
|||
|
||||
namespace Nz
|
||||
{
|
||||
namespace NAZARA_ANONYMOUS_NAMESPACE
|
||||
{
|
||||
Window* s_fullscreenWindow = nullptr;
|
||||
}
|
||||
|
||||
Window::Window() :
|
||||
m_impl(nullptr),
|
||||
m_asyncWindow(false),
|
||||
m_closeOnQuit(true),
|
||||
m_eventPolling(false),
|
||||
m_waitForEvent(false)
|
||||
{
|
||||
ConnectSlots();
|
||||
}
|
||||
|
||||
Window::Window(Window&& window) :
|
||||
m_events(std::move(window.m_events)),
|
||||
m_pendingEvents(std::move(window.m_pendingEvents)),
|
||||
Window::Window(Window&& window) noexcept :
|
||||
m_cursorController(std::move(window.m_cursorController)),
|
||||
m_cursor(std::move(window.m_cursor)),
|
||||
m_eventHandler(std::move(window.m_eventHandler)),
|
||||
m_icon(std::move(window.m_icon)),
|
||||
m_asyncWindow(window.m_asyncWindow),
|
||||
m_closed(window.m_asyncWindow),
|
||||
m_closed(window.m_closed),
|
||||
m_closeOnQuit(window.m_closeOnQuit),
|
||||
m_eventPolling(window.m_eventPolling),
|
||||
m_ownsWindow(window.m_asyncWindow),
|
||||
m_ownsWindow(window.m_ownsWindow),
|
||||
m_waitForEvent(window.m_waitForEvent)
|
||||
{
|
||||
window.DisconnectSlots();
|
||||
|
|
@ -52,214 +41,136 @@ namespace Nz
|
|||
|
||||
bool Window::Create(VideoMode mode, const std::string& title, WindowStyleFlags style)
|
||||
{
|
||||
NAZARA_USE_ANONYMOUS_NAMESPACE
|
||||
|
||||
// If the window is already open, we keep its position
|
||||
bool opened = IsOpen();
|
||||
Vector2i position;
|
||||
if (opened)
|
||||
position = m_impl->GetPosition();
|
||||
position = m_position;
|
||||
|
||||
Destroy();
|
||||
|
||||
// Inspired by the code of the SFML by Laurent Gomila (and its team)
|
||||
if (style & WindowStyle::Fullscreen)
|
||||
{
|
||||
if (s_fullscreenWindow)
|
||||
{
|
||||
NazaraError("Window " + PointerToString(s_fullscreenWindow) + " already in fullscreen mode");
|
||||
style &= ~WindowStyle::Fullscreen;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!mode.IsFullscreenValid())
|
||||
{
|
||||
NazaraWarning("Video mode is not fullscreen valid");
|
||||
mode = VideoMode::GetFullscreenModes()[0];
|
||||
}
|
||||
|
||||
s_fullscreenWindow = this;
|
||||
}
|
||||
}
|
||||
else if (style & WindowStyle::Closable || style & WindowStyle::Resizable)
|
||||
if (style & WindowStyle::Closable || style & WindowStyle::Resizable)
|
||||
style |= WindowStyle::Titlebar;
|
||||
|
||||
m_asyncWindow = (style & WindowStyle::Threaded) != 0;
|
||||
|
||||
std::unique_ptr<WindowImpl> impl = std::make_unique<WindowImpl>(this);
|
||||
if (!impl->Create(mode, title, style))
|
||||
m_impl = std::make_unique<WindowImpl>(this);
|
||||
if (!m_impl->Create(mode, title, style))
|
||||
{
|
||||
NazaraError("Failed to create window implementation");
|
||||
return false;
|
||||
}
|
||||
|
||||
m_impl = impl.release();
|
||||
CallOnExit destroyOnFailure([this] () { Destroy(); });
|
||||
|
||||
m_closed = false;
|
||||
m_ownsWindow = true;
|
||||
|
||||
if (!OnWindowCreated())
|
||||
{
|
||||
NazaraError("Failed to initialize window extension");
|
||||
return false;
|
||||
}
|
||||
m_position = m_impl->FetchPosition();
|
||||
m_size = m_impl->FetchSize();
|
||||
|
||||
// Default parameters
|
||||
m_impl->EnableKeyRepeat(true);
|
||||
m_impl->EnableSmoothScrolling(false);
|
||||
m_impl->SetMaximumSize(-1, -1);
|
||||
m_impl->SetMinimumSize(-1, -1);
|
||||
m_impl->SetVisible(true);
|
||||
m_impl->UpdateMaximumSize(-1, -1);
|
||||
m_impl->UpdateMinimumSize(-1, -1);
|
||||
m_impl->Show(true);
|
||||
|
||||
if (opened)
|
||||
m_impl->SetPosition(position.x, position.y);
|
||||
|
||||
OnWindowResized();
|
||||
m_impl->UpdatePosition(position.x, position.y);
|
||||
|
||||
destroyOnFailure.Reset();
|
||||
|
||||
m_eventHandler.Dispatch({ WindowEventType::Created });
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Window::Create(void* handle)
|
||||
bool Window::Create(WindowHandle handle)
|
||||
{
|
||||
Destroy();
|
||||
|
||||
m_asyncWindow = false;
|
||||
m_impl = new WindowImpl(this);
|
||||
m_impl = std::make_unique<WindowImpl>(this);
|
||||
if (!m_impl->Create(handle))
|
||||
{
|
||||
NazaraError("Unable to create window implementation");
|
||||
delete m_impl;
|
||||
m_impl = nullptr;
|
||||
|
||||
m_impl.reset();
|
||||
return false;
|
||||
}
|
||||
|
||||
m_position = m_impl->FetchPosition();
|
||||
m_size = m_impl->FetchSize();
|
||||
|
||||
m_closed = false;
|
||||
m_ownsWindow = false;
|
||||
|
||||
if (!OnWindowCreated())
|
||||
{
|
||||
NazaraError("Failed to initialize window's derivate");
|
||||
delete m_impl;
|
||||
m_impl = nullptr;
|
||||
|
||||
return false;
|
||||
}
|
||||
m_eventHandler.Dispatch({ WindowEventType::Created });
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Window::Destroy()
|
||||
{
|
||||
NAZARA_USE_ANONYMOUS_NAMESPACE
|
||||
|
||||
m_cursor.reset();
|
||||
|
||||
if (m_impl)
|
||||
{
|
||||
OnWindowDestroy();
|
||||
m_eventHandler.Dispatch({ WindowEventType::Destruction });
|
||||
|
||||
m_impl->Destroy();
|
||||
delete m_impl;
|
||||
m_impl = nullptr;
|
||||
|
||||
if (s_fullscreenWindow == this)
|
||||
s_fullscreenWindow = nullptr;
|
||||
m_impl.reset();
|
||||
}
|
||||
}
|
||||
|
||||
void Window::EnableKeyRepeat(bool enable)
|
||||
{
|
||||
#if NAZARA_PLATFORM_SAFE
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraError("Window not created");
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
m_impl->EnableKeyRepeat(enable);
|
||||
}
|
||||
|
||||
void Window::EnableSmoothScrolling(bool enable)
|
||||
{
|
||||
#if NAZARA_PLATFORM_SAFE
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraError("Window not created");
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
m_impl->EnableSmoothScrolling(enable);
|
||||
m_cursor.reset();
|
||||
}
|
||||
|
||||
Vector2i Window::GetPosition() const
|
||||
{
|
||||
#if NAZARA_PLATFORM_SAFE
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraError("Window not created");
|
||||
return Vector2i::Zero();
|
||||
}
|
||||
#endif
|
||||
|
||||
return m_impl->GetPosition();
|
||||
NazaraAssert(m_impl, "Window not created");
|
||||
return m_position;
|
||||
}
|
||||
|
||||
Vector2ui Window::GetSize() const
|
||||
{
|
||||
#if NAZARA_PLATFORM_SAFE
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraError("Window not created");
|
||||
return Vector2ui::Zero();
|
||||
}
|
||||
#endif
|
||||
|
||||
return m_impl->GetSize();
|
||||
NazaraAssert(m_impl, "Window not created");
|
||||
return m_size;
|
||||
}
|
||||
|
||||
WindowStyleFlags Window::GetStyle() const
|
||||
{
|
||||
#if NAZARA_PLATFORM_SAFE
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraError("Window not created");
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
return m_impl->GetStyle();
|
||||
}
|
||||
|
||||
WindowHandle Window::GetSystemHandle() const
|
||||
{
|
||||
#if NAZARA_PLATFORM_SAFE
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraError("Window not created");
|
||||
return {};
|
||||
}
|
||||
#endif
|
||||
|
||||
return m_impl->GetSystemHandle();
|
||||
NazaraAssert(m_impl, "Window not created");
|
||||
return m_impl->FetchStyle();
|
||||
}
|
||||
|
||||
std::string Window::GetTitle() const
|
||||
{
|
||||
#if NAZARA_PLATFORM_SAFE
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraError("Window not created");
|
||||
return {};
|
||||
}
|
||||
#endif
|
||||
NazaraAssert(m_impl, "Window not created");
|
||||
return m_impl->FetchTitle();
|
||||
}
|
||||
|
||||
return m_impl->GetTitle();
|
||||
void Window::HandleEvent(const WindowEvent& event)
|
||||
{
|
||||
m_eventHandler.Dispatch(event);
|
||||
|
||||
switch (event.type)
|
||||
{
|
||||
case WindowEventType::Moved:
|
||||
{
|
||||
m_position = { event.position.x, event.position.y };
|
||||
break;
|
||||
}
|
||||
|
||||
case WindowEventType::Quit:
|
||||
{
|
||||
if (m_closeOnQuit)
|
||||
Close();
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case WindowEventType::Resized:
|
||||
{
|
||||
m_size = { event.size.width, event.size.height };
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool Window::HasFocus() const
|
||||
|
|
@ -301,76 +212,13 @@ namespace Nz
|
|||
return m_impl->IsVisible();
|
||||
}
|
||||
|
||||
bool Window::PollEvent(WindowEvent* event)
|
||||
{
|
||||
#if NAZARA_PLATFORM_SAFE
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraError("Window not created");
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!m_asyncWindow)
|
||||
m_impl->ProcessEvents(false);
|
||||
|
||||
if (!m_events.empty())
|
||||
{
|
||||
if (event)
|
||||
*event = m_events.front();
|
||||
|
||||
m_events.pop();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void Window::ProcessEvents(bool block)
|
||||
{
|
||||
NazaraAssert(m_impl, "Window not created");
|
||||
NazaraUnused(block);
|
||||
|
||||
if (!m_asyncWindow)
|
||||
m_impl->ProcessEvents(block);
|
||||
else
|
||||
{
|
||||
std::lock_guard<std::mutex> eventLock(m_eventMutex);
|
||||
|
||||
for (const WindowEvent& event : m_pendingEvents)
|
||||
HandleEvent(event);
|
||||
|
||||
m_pendingEvents.clear();
|
||||
}
|
||||
}
|
||||
|
||||
void Window::SetCursor(std::shared_ptr<Cursor> cursor)
|
||||
{
|
||||
NazaraAssert(m_impl, "Window not created");
|
||||
NazaraAssert(cursor && cursor->IsValid(), "Invalid cursor");
|
||||
|
||||
m_cursor = std::move(cursor);
|
||||
m_impl->SetCursor(*m_cursor);
|
||||
}
|
||||
|
||||
void Window::SetEventListener(bool listener)
|
||||
{
|
||||
#if NAZARA_PLATFORM_SAFE
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraError("Window not created");
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
m_impl->SetEventListener(listener);
|
||||
if (!listener)
|
||||
{
|
||||
// Empty the event queue
|
||||
while (!m_events.empty())
|
||||
m_events.pop();
|
||||
}
|
||||
m_impl->UpdateCursor(*m_cursor);
|
||||
}
|
||||
|
||||
void Window::SetFocus()
|
||||
|
|
@ -383,7 +231,7 @@ namespace Nz
|
|||
}
|
||||
#endif
|
||||
|
||||
m_impl->SetFocus();
|
||||
m_impl->RaiseFocus();
|
||||
}
|
||||
|
||||
void Window::SetIcon(std::shared_ptr<Icon> icon)
|
||||
|
|
@ -392,7 +240,7 @@ namespace Nz
|
|||
NazaraAssert(icon, "Invalid icon");
|
||||
|
||||
m_icon = std::move(icon);
|
||||
m_impl->SetIcon(*m_icon);
|
||||
m_impl->UpdateIcon(*m_icon);
|
||||
}
|
||||
|
||||
void Window::SetMaximumSize(const Vector2i& maxSize)
|
||||
|
|
@ -405,7 +253,7 @@ namespace Nz
|
|||
}
|
||||
#endif
|
||||
|
||||
m_impl->SetMaximumSize(maxSize.x, maxSize.y);
|
||||
m_impl->UpdateMaximumSize(maxSize.x, maxSize.y);
|
||||
}
|
||||
|
||||
void Window::SetMaximumSize(int width, int height)
|
||||
|
|
@ -418,7 +266,7 @@ namespace Nz
|
|||
}
|
||||
#endif
|
||||
|
||||
m_impl->SetMaximumSize(width, height);
|
||||
m_impl->UpdateMaximumSize(width, height);
|
||||
}
|
||||
|
||||
void Window::SetMinimumSize(const Vector2i& minSize)
|
||||
|
|
@ -431,7 +279,7 @@ namespace Nz
|
|||
}
|
||||
#endif
|
||||
|
||||
m_impl->SetMinimumSize(minSize.x, minSize.y);
|
||||
m_impl->UpdateMinimumSize(minSize.x, minSize.y);
|
||||
}
|
||||
|
||||
void Window::SetMinimumSize(int width, int height)
|
||||
|
|
@ -444,7 +292,7 @@ namespace Nz
|
|||
}
|
||||
#endif
|
||||
|
||||
m_impl->SetMinimumSize(width, height);
|
||||
m_impl->UpdateMinimumSize(width, height);
|
||||
}
|
||||
|
||||
void Window::SetPosition(const Vector2i& position)
|
||||
|
|
@ -457,7 +305,7 @@ namespace Nz
|
|||
}
|
||||
#endif
|
||||
|
||||
m_impl->SetPosition(position.x, position.y);
|
||||
m_impl->UpdatePosition(position.x, position.y);
|
||||
}
|
||||
|
||||
void Window::SetPosition(int x, int y)
|
||||
|
|
@ -470,7 +318,7 @@ namespace Nz
|
|||
}
|
||||
#endif
|
||||
|
||||
m_impl->SetPosition(x, y);
|
||||
m_impl->UpdatePosition(x, y);
|
||||
}
|
||||
|
||||
void Window::SetSize(const Vector2i& size)
|
||||
|
|
@ -483,7 +331,7 @@ namespace Nz
|
|||
}
|
||||
#endif
|
||||
|
||||
m_impl->SetSize(size.x, size.y);
|
||||
m_impl->UpdateSize(size.x, size.y);
|
||||
}
|
||||
|
||||
void Window::SetSize(unsigned int width, unsigned int height)
|
||||
|
|
@ -496,7 +344,7 @@ namespace Nz
|
|||
}
|
||||
#endif
|
||||
|
||||
m_impl->SetSize(width, height);
|
||||
m_impl->UpdateSize(width, height);
|
||||
}
|
||||
|
||||
void Window::SetStayOnTop(bool stayOnTop)
|
||||
|
|
@ -509,7 +357,7 @@ namespace Nz
|
|||
}
|
||||
#endif
|
||||
|
||||
m_impl->SetStayOnTop(stayOnTop);
|
||||
m_impl->UpdateStayOnTop(stayOnTop);
|
||||
}
|
||||
|
||||
void Window::SetTitle(const std::string& title)
|
||||
|
|
@ -522,7 +370,7 @@ namespace Nz
|
|||
}
|
||||
#endif
|
||||
|
||||
m_impl->SetTitle(title);
|
||||
m_impl->UpdateTitle(title);
|
||||
}
|
||||
|
||||
void Window::SetVisible(bool visible)
|
||||
|
|
@ -535,76 +383,18 @@ namespace Nz
|
|||
}
|
||||
#endif
|
||||
|
||||
m_impl->SetVisible(visible);
|
||||
m_impl->Show(visible);
|
||||
}
|
||||
|
||||
bool Window::WaitEvent(WindowEvent* event)
|
||||
Window& Window::operator=(Window&& window) noexcept
|
||||
{
|
||||
#if NAZARA_PLATFORM_SAFE
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraError("Window not created");
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!m_asyncWindow)
|
||||
{
|
||||
while (m_events.empty())
|
||||
m_impl->ProcessEvents(true);
|
||||
|
||||
if (event)
|
||||
*event = m_events.front();
|
||||
|
||||
m_events.pop();
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_eventMutex);
|
||||
|
||||
if (m_events.empty())
|
||||
{
|
||||
m_waitForEvent = true;
|
||||
{
|
||||
m_eventMutex.unlock();
|
||||
|
||||
std::unique_lock<std::mutex> eventConditionLock(m_eventConditionMutex);
|
||||
m_eventCondition.wait(eventConditionLock);
|
||||
|
||||
m_eventMutex.lock();
|
||||
}
|
||||
m_waitForEvent = false;
|
||||
}
|
||||
|
||||
if (!m_events.empty())
|
||||
{
|
||||
if (event)
|
||||
*event = m_events.front();
|
||||
|
||||
m_events.pop();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
Window& Window::operator=(Window&& window)
|
||||
{
|
||||
m_events = std::move(window.m_events);
|
||||
m_pendingEvents = std::move(window.m_pendingEvents);
|
||||
m_cursorController = std::move(window.m_cursorController);
|
||||
m_cursor = std::move(window.m_cursor);
|
||||
m_eventHandler = std::move(window.m_eventHandler);
|
||||
m_icon = std::move(window.m_icon);
|
||||
m_asyncWindow = window.m_asyncWindow;
|
||||
m_closed = window.m_asyncWindow;
|
||||
m_closed = window.m_closed;
|
||||
m_closeOnQuit = window.m_closeOnQuit;
|
||||
m_eventPolling = window.m_eventPolling;
|
||||
m_ownsWindow = window.m_asyncWindow;
|
||||
m_ownsWindow = window.m_ownsWindow;
|
||||
m_waitForEvent = window.m_waitForEvent;
|
||||
|
||||
window.DisconnectSlots();
|
||||
|
|
@ -613,22 +403,14 @@ namespace Nz
|
|||
return *this;
|
||||
}
|
||||
|
||||
void* Window::GetHandle()
|
||||
void Window::ProcessEvents()
|
||||
{
|
||||
return (m_impl) ? m_impl->GetHandle() : nullptr;
|
||||
WindowImpl::ProcessEvents();
|
||||
}
|
||||
|
||||
bool Window::OnWindowCreated()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
void Window::OnWindowDestroy()
|
||||
{
|
||||
}
|
||||
|
||||
void Window::OnWindowResized()
|
||||
WindowHandle Window::GetHandle() const
|
||||
{
|
||||
return (m_impl) ? m_impl->GetSystemHandle() : WindowHandle{};
|
||||
}
|
||||
|
||||
void Window::ConnectSlots()
|
||||
|
|
@ -658,34 +440,6 @@ namespace Nz
|
|||
m_impl->IgnoreNextMouseEvent(mouseX, mouseY);
|
||||
}
|
||||
|
||||
void Window::HandleEvent(const WindowEvent& event)
|
||||
{
|
||||
if (m_eventPolling)
|
||||
m_events.push(event);
|
||||
|
||||
m_eventHandler.Dispatch(event);
|
||||
|
||||
switch (event.type)
|
||||
{
|
||||
case WindowEventType::MouseEntered:
|
||||
m_impl->RefreshCursor();
|
||||
break;
|
||||
|
||||
case WindowEventType::Resized:
|
||||
OnWindowResized();
|
||||
break;
|
||||
|
||||
case WindowEventType::Quit:
|
||||
if (m_closeOnQuit)
|
||||
Close();
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool Window::Initialize()
|
||||
{
|
||||
return WindowImpl::Initialize();
|
||||
|
|
|
|||
|
|
@ -1,11 +0,0 @@
|
|||
// Copyright (C) 2022 Jérôme "Lynix" Leclercq (lynix680@gmail.com)
|
||||
// This file is part of the "Nazara Engine - Renderer module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#include <Nazara/Renderer/RenderSurface.hpp>
|
||||
#include <Nazara/Renderer/Debug.hpp>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
RenderSurface::~RenderSurface() = default;
|
||||
}
|
||||
|
|
@ -1,91 +0,0 @@
|
|||
// Copyright (C) 2022 Jérôme "Lynix" Leclercq (lynix680@gmail.com)
|
||||
// This file is part of the "Nazara Engine - Renderer module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#include <Nazara/Renderer/RenderWindow.hpp>
|
||||
#include <Nazara/Core/Error.hpp>
|
||||
#include <Nazara/Renderer/Renderer.hpp>
|
||||
#include <Nazara/Renderer/RendererImpl.hpp>
|
||||
#include <chrono>
|
||||
#include <thread>
|
||||
#include <Nazara/Renderer/Debug.hpp>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
RenderFrame RenderWindow::AcquireFrame()
|
||||
{
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraError("window is not created");
|
||||
return RenderFrame{};
|
||||
}
|
||||
|
||||
if (m_framerateLimit > 0)
|
||||
{
|
||||
int remainingTime = 1000 / static_cast<int>(m_framerateLimit) - static_cast<int>(m_clock.GetElapsedTime().AsMilliseconds());
|
||||
if (remainingTime > 0)
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(remainingTime));
|
||||
|
||||
m_clock.Restart();
|
||||
}
|
||||
|
||||
return m_impl->Acquire();
|
||||
}
|
||||
|
||||
bool RenderWindow::Create(std::shared_ptr<RenderDevice> renderDevice, VideoMode mode, const std::string& title, WindowStyleFlags style, const RenderWindowParameters& parameters)
|
||||
{
|
||||
m_parameters = parameters;
|
||||
m_renderDevice = std::move(renderDevice);
|
||||
|
||||
return Window::Create(mode, title, style);
|
||||
}
|
||||
|
||||
bool RenderWindow::Create(std::shared_ptr<RenderDevice> renderDevice, void* handle, const RenderWindowParameters& parameters)
|
||||
{
|
||||
m_parameters = parameters;
|
||||
m_renderDevice = std::move(renderDevice);
|
||||
|
||||
return Window::Create(handle);
|
||||
}
|
||||
|
||||
void RenderWindow::EnableVerticalSync(bool enabled)
|
||||
{
|
||||
///TODO
|
||||
}
|
||||
|
||||
bool RenderWindow::OnWindowCreated()
|
||||
{
|
||||
RendererImpl* rendererImpl = Renderer::Instance()->GetRendererImpl();
|
||||
auto surface = rendererImpl->CreateRenderSurfaceImpl();
|
||||
if (!surface->Create(GetSystemHandle()))
|
||||
{
|
||||
NazaraError("Failed to create render surface: " + Error::GetLastError());
|
||||
return false;
|
||||
}
|
||||
|
||||
auto impl = rendererImpl->CreateRenderWindowImpl(*this);
|
||||
if (!impl->Create(rendererImpl, surface.get(), m_parameters))
|
||||
{
|
||||
NazaraError("Failed to create render window implementation: " + Error::GetLastError());
|
||||
return false;
|
||||
}
|
||||
|
||||
m_impl = std::move(impl);
|
||||
m_surface = std::move(surface);
|
||||
|
||||
m_clock.Restart();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void RenderWindow::OnWindowDestroy()
|
||||
{
|
||||
m_impl.reset();
|
||||
m_renderDevice.reset();
|
||||
m_surface.reset();
|
||||
}
|
||||
|
||||
void RenderWindow::OnWindowResized()
|
||||
{
|
||||
}
|
||||
}
|
||||
|
|
@ -2,14 +2,14 @@
|
|||
// This file is part of the "Nazara Engine - Renderer module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#include <Nazara/Renderer/RenderWindowImpl.hpp>
|
||||
#include <Nazara/Renderer/Swapchain.hpp>
|
||||
#include <Nazara/Renderer/Debug.hpp>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
RenderWindowImpl::~RenderWindowImpl() = default;
|
||||
Swapchain::~Swapchain() = default;
|
||||
|
||||
void RenderWindowImpl::BuildRenderPass(PixelFormat colorFormat, PixelFormat depthFormat, std::vector<RenderPass::Attachment>& attachments, std::vector<RenderPass::SubpassDescription>& subpassDescriptions, std::vector<RenderPass::SubpassDependency>& subpassDependencies)
|
||||
void Swapchain::BuildRenderPass(PixelFormat colorFormat, PixelFormat depthFormat, std::vector<RenderPass::Attachment>& attachments, std::vector<RenderPass::SubpassDescription>& subpassDescriptions, std::vector<RenderPass::SubpassDependency>& subpassDependencies)
|
||||
{
|
||||
assert(colorFormat != PixelFormat::Undefined);
|
||||
|
||||
|
|
@ -0,0 +1,72 @@
|
|||
// Copyright (C) 2022 Jérôme "Lynix" Leclercq (lynix680@gmail.com)
|
||||
// This file is part of the "Nazara Engine - Renderer module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#include <Nazara/Renderer/WindowSwapchain.hpp>
|
||||
#include <Nazara/Renderer/RenderDevice.hpp>
|
||||
#include <Nazara/Platform/Window.hpp>
|
||||
#include <Nazara/Renderer/Debug.hpp>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
WindowSwapchain::WindowSwapchain(std::shared_ptr<RenderDevice> renderDevice, Window& window, SwapchainParameters parameters) :
|
||||
m_renderDevice(std::move(renderDevice)),
|
||||
m_window(&window),
|
||||
m_parameters(std::move(parameters)),
|
||||
m_renderOnlyIfFocused(false)
|
||||
{
|
||||
NazaraAssert(m_renderDevice, "invalid render device");
|
||||
|
||||
if (m_window->IsValid())
|
||||
{
|
||||
m_swapchain = m_renderDevice->InstantiateSwapchain(window.GetHandle(), window.GetSize(), m_parameters);
|
||||
m_isMinimized = window.IsMinimized();
|
||||
}
|
||||
else
|
||||
m_isMinimized = true; //< consider it minimized so AcquireFrame returns no frame
|
||||
|
||||
ConnectSignals();
|
||||
}
|
||||
|
||||
void WindowSwapchain::ConnectSignals()
|
||||
{
|
||||
WindowEventHandler& windowEvents = m_window->GetEventHandler();
|
||||
m_onCreated.Connect(windowEvents.OnCreated, [this](const WindowEventHandler* /*eventHandler*/)
|
||||
{
|
||||
// Recreate swapchain
|
||||
m_swapchain = m_renderDevice->InstantiateSwapchain(m_window->GetHandle(), m_window->GetSize(), m_parameters);
|
||||
m_isMinimized = m_window->IsMinimized();
|
||||
});
|
||||
|
||||
m_onDestruction.Connect(windowEvents.OnDestruction, [this](const WindowEventHandler* /*eventHandler*/)
|
||||
{
|
||||
m_swapchain.reset();
|
||||
m_isMinimized = true;
|
||||
});
|
||||
|
||||
m_onGainedFocus.Connect(windowEvents.OnGainedFocus, [this](const WindowEventHandler* /*eventHandler*/)
|
||||
{
|
||||
m_hasFocus = true;
|
||||
});
|
||||
|
||||
m_onLostFocus.Connect(windowEvents.OnLostFocus, [this](const WindowEventHandler* /*eventHandler*/)
|
||||
{
|
||||
m_hasFocus = false;
|
||||
});
|
||||
|
||||
m_onMinimized.Connect(windowEvents.OnMinimized, [this](const WindowEventHandler* /*eventHandler*/)
|
||||
{
|
||||
m_isMinimized = true;
|
||||
});
|
||||
|
||||
m_onResized.Connect(windowEvents.OnResized, [this](const WindowEventHandler* /*eventHandler*/, const WindowEvent::SizeEvent& event)
|
||||
{
|
||||
m_swapchain->NotifyResize({ event.width, event.height });
|
||||
});
|
||||
|
||||
m_onRestored.Connect(windowEvents.OnRestored, [this](const WindowEventHandler* /*eventHandler*/)
|
||||
{
|
||||
m_isMinimized = false;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -9,6 +9,7 @@
|
|||
#include <Nazara/VulkanRenderer/VulkanRenderPipeline.hpp>
|
||||
#include <Nazara/VulkanRenderer/VulkanRenderPipelineLayout.hpp>
|
||||
#include <Nazara/VulkanRenderer/VulkanShaderModule.hpp>
|
||||
#include <Nazara/VulkanRenderer/VulkanSwapchain.hpp>
|
||||
#include <Nazara/VulkanRenderer/VulkanTexture.hpp>
|
||||
#include <Nazara/VulkanRenderer/VulkanTextureFramebuffer.hpp>
|
||||
#include <Nazara/VulkanRenderer/VulkanTextureSampler.hpp>
|
||||
|
|
@ -85,6 +86,11 @@ namespace Nz
|
|||
return stage;
|
||||
}
|
||||
|
||||
std::shared_ptr<Swapchain> VulkanDevice::InstantiateSwapchain(WindowHandle windowHandle, const Vector2ui& windowSize, const SwapchainParameters& parameters)
|
||||
{
|
||||
return std::make_shared<VulkanSwapchain>(*this, windowHandle, windowSize, parameters);
|
||||
}
|
||||
|
||||
std::shared_ptr<Texture> VulkanDevice::InstantiateTexture(const TextureInfo& params)
|
||||
{
|
||||
return std::make_shared<VulkanTexture>(*this, params);
|
||||
|
|
|
|||
|
|
@ -5,13 +5,13 @@
|
|||
#include <Nazara/VulkanRenderer/VulkanRenderImage.hpp>
|
||||
#include <Nazara/VulkanRenderer/VulkanCommandBuffer.hpp>
|
||||
#include <Nazara/VulkanRenderer/VulkanCommandBufferBuilder.hpp>
|
||||
#include <Nazara/VulkanRenderer/VulkanRenderWindow.hpp>
|
||||
#include <Nazara/VulkanRenderer/VulkanSwapchain.hpp>
|
||||
#include <stdexcept>
|
||||
#include <Nazara/VulkanRenderer/Debug.hpp>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
VulkanRenderImage::VulkanRenderImage(VulkanRenderWindow& owner) :
|
||||
VulkanRenderImage::VulkanRenderImage(VulkanSwapchain& owner) :
|
||||
m_owner(owner),
|
||||
m_uploadPool(m_owner.GetDevice(), 2 * 1024 * 1024)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -6,8 +6,7 @@
|
|||
#include <Nazara/Core/ErrorFlags.hpp>
|
||||
#include <Nazara/Renderer/RenderDevice.hpp>
|
||||
#include <Nazara/VulkanRenderer/VulkanBuffer.hpp>
|
||||
#include <Nazara/VulkanRenderer/VulkanRenderWindow.hpp>
|
||||
#include <Nazara/VulkanRenderer/VulkanSurface.hpp>
|
||||
#include <Nazara/VulkanRenderer/VulkanSwapchain.hpp>
|
||||
#include <Nazara/VulkanRenderer/Wrapper/Loader.hpp>
|
||||
#include <cassert>
|
||||
#include <sstream>
|
||||
|
|
@ -20,16 +19,6 @@ namespace Nz
|
|||
Vulkan::Uninitialize();
|
||||
}
|
||||
|
||||
std::unique_ptr<RenderSurface> VulkanRenderer::CreateRenderSurfaceImpl()
|
||||
{
|
||||
return std::make_unique<VulkanSurface>();
|
||||
}
|
||||
|
||||
std::unique_ptr<RenderWindowImpl> VulkanRenderer::CreateRenderWindowImpl(RenderWindow& owner)
|
||||
{
|
||||
return std::make_unique<VulkanRenderWindow>(owner);
|
||||
}
|
||||
|
||||
std::shared_ptr<RenderDevice> VulkanRenderer::InstanciateRenderDevice(std::size_t deviceIndex, const RenderDeviceFeatures& enabledFeatures)
|
||||
{
|
||||
const auto& physDevices = Vulkan::GetPhysicalDevices();
|
||||
|
|
|
|||
|
|
@ -1,98 +0,0 @@
|
|||
// Copyright (C) 2022 Jérôme "Lynix" Leclercq (lynix680@gmail.com)
|
||||
// This file is part of the "Nazara Engine - Vulkan renderer"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#include <Nazara/VulkanRenderer/VulkanSurface.hpp>
|
||||
#include <Nazara/VulkanRenderer/Vulkan.hpp>
|
||||
#include <vulkan/vk_sdk_platform.h>
|
||||
#include <Nazara/VulkanRenderer/Debug.hpp>
|
||||
|
||||
#ifdef VK_USE_PLATFORM_METAL_EXT
|
||||
#include <objc/runtime.h>
|
||||
#include <vulkan/vulkan_metal.h>
|
||||
#endif
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
#ifdef VK_USE_PLATFORM_METAL_EXT
|
||||
id CreateAndAttachMetalLayer(void* window);
|
||||
#endif
|
||||
|
||||
VulkanSurface::VulkanSurface() :
|
||||
m_surface(Vulkan::GetInstance())
|
||||
{
|
||||
}
|
||||
|
||||
bool VulkanSurface::Create(WindowHandle handle)
|
||||
{
|
||||
bool success = false;
|
||||
#if defined(NAZARA_PLATFORM_WINDOWS)
|
||||
{
|
||||
NazaraAssert(handle.type == WindowBackend::Windows, "expected Windows window");
|
||||
|
||||
HWND winHandle = reinterpret_cast<HWND>(handle.windows.window);
|
||||
HINSTANCE instance = reinterpret_cast<HINSTANCE>(GetWindowLongPtrW(winHandle, GWLP_HINSTANCE));
|
||||
|
||||
success = m_surface.Create(instance, winHandle);
|
||||
}
|
||||
#elif defined(NAZARA_PLATFORM_LINUX)
|
||||
{
|
||||
switch (handle.type)
|
||||
{
|
||||
#ifdef VK_USE_PLATFORM_WAYLAND_KHR
|
||||
case WindowBackend::Wayland:
|
||||
{
|
||||
wl_display* display = static_cast<wl_display*>(handle.wayland.display);
|
||||
wl_surface* surface = static_cast<wl_surface*>(handle.wayland.surface);
|
||||
|
||||
success = m_surface.Create(display, surface);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef VK_USE_PLATFORM_XLIB_KHR
|
||||
case WindowBackend::X11:
|
||||
{
|
||||
Display* display = static_cast<Display*>(handle.x11.display);
|
||||
::Window window = static_cast<::Window>(handle.x11.window);
|
||||
|
||||
success = m_surface.Create(display, window);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
default:
|
||||
{
|
||||
NazaraError("unhandled window type");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
#elif defined(NAZARA_PLATFORM_MACOS)
|
||||
{
|
||||
NazaraAssert(handle.type == WindowBackend::Cocoa, "expected cocoa window");
|
||||
id layer = CreateAndAttachMetalLayer(handle.cocoa.window);
|
||||
success = m_surface.Create(layer);
|
||||
}
|
||||
#else
|
||||
#error This OS is not supported by Vulkan
|
||||
#endif
|
||||
|
||||
if (!success)
|
||||
{
|
||||
NazaraError("Failed to create Vulkan surface: " + TranslateVulkanError(m_surface.GetLastErrorCode()));
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void VulkanSurface::Destroy()
|
||||
{
|
||||
m_surface.Destroy();
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(NAZARA_PLATFORM_WINDOWS)
|
||||
#include <Nazara/Core/AntiWindows.hpp>
|
||||
#endif
|
||||
|
|
@ -4,13 +4,17 @@
|
|||
|
||||
namespace Nz
|
||||
{
|
||||
id CreateAndAttachMetalLayer(void* window) {
|
||||
NSWindow* obj = (__bridge NSWindow*)window;
|
||||
id CreateAndAttachMetalLayer(void* window)
|
||||
{
|
||||
NSWindow* obj = (__bridge NSWindow*) window;
|
||||
|
||||
NSView* view = [[NSView alloc] initWithFrame:obj.frame];
|
||||
[view setLayer:[CAMetalLayer layer]];
|
||||
[view setWantsLayer:YES];
|
||||
view.autoresizingMask = NSViewWidthSizable | NSViewHeightSizable;
|
||||
|
||||
[obj.contentView addSubview:view];
|
||||
|
||||
return view.layer;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,34 +2,160 @@
|
|||
// This file is part of the "Nazara Engine - Vulkan renderer"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#include <Nazara/VulkanRenderer/VulkanRenderWindow.hpp>
|
||||
#include <Nazara/VulkanRenderer/VulkanSwapchain.hpp>
|
||||
#include <Nazara/Core/Error.hpp>
|
||||
#include <Nazara/Core/ErrorFlags.hpp>
|
||||
#include <Nazara/Math/Vector2.hpp>
|
||||
#include <Nazara/Renderer/RenderWindow.hpp>
|
||||
#include <Nazara/Renderer/WindowSwapchain.hpp>
|
||||
#include <Nazara/Utility/PixelFormat.hpp>
|
||||
#include <Nazara/VulkanRenderer/Vulkan.hpp>
|
||||
#include <Nazara/VulkanRenderer/VulkanCommandPool.hpp>
|
||||
#include <Nazara/VulkanRenderer/VulkanDevice.hpp>
|
||||
#include <Nazara/VulkanRenderer/VulkanSurface.hpp>
|
||||
#include <Nazara/Utils/StackArray.hpp>
|
||||
#include <array>
|
||||
#include <stdexcept>
|
||||
|
||||
#ifdef VK_USE_PLATFORM_METAL_EXT
|
||||
#include <objc/runtime.h>
|
||||
#include <vulkan/vulkan_metal.h>
|
||||
#endif
|
||||
|
||||
#include <Nazara/VulkanRenderer/Debug.hpp>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
VulkanRenderWindow::VulkanRenderWindow(RenderWindow& owner) :
|
||||
#ifdef VK_USE_PLATFORM_METAL_EXT
|
||||
id CreateAndAttachMetalLayer(void* window);
|
||||
#endif
|
||||
|
||||
VulkanSwapchain::VulkanSwapchain(VulkanDevice& device, WindowHandle windowHandle, const Vector2ui& windowSize, const SwapchainParameters& parameters) :
|
||||
m_currentFrame(0),
|
||||
m_owner(owner),
|
||||
m_surface(device.GetInstance()),
|
||||
m_swapchainSize(windowSize),
|
||||
m_device(device),
|
||||
m_shouldRecreateSwapchain(false)
|
||||
{
|
||||
if (!SetupSurface(windowHandle))
|
||||
throw std::runtime_error("failed to create surface");
|
||||
|
||||
const auto& physDeviceInfo = m_device.GetPhysicalDeviceInfo();
|
||||
|
||||
const std::vector<Vk::Device::QueueFamilyInfo>& queueFamilyInfo = m_device.GetEnabledQueues();
|
||||
UInt32 graphicsFamilyQueueIndex = UINT32_MAX;
|
||||
UInt32 presentableFamilyQueueIndex = UINT32_MAX;
|
||||
|
||||
for (const Vk::Device::QueueFamilyInfo& queueInfo : queueFamilyInfo)
|
||||
{
|
||||
bool supported = false;
|
||||
if (m_surface.GetSupportPresentation(physDeviceInfo.physDevice, queueInfo.familyIndex, &supported) && supported)
|
||||
{
|
||||
if (presentableFamilyQueueIndex == UINT32_MAX || queueInfo.flags & VK_QUEUE_GRAPHICS_BIT)
|
||||
{
|
||||
presentableFamilyQueueIndex = queueInfo.familyIndex;
|
||||
if (queueInfo.flags & VK_QUEUE_GRAPHICS_BIT)
|
||||
{
|
||||
graphicsFamilyQueueIndex = queueInfo.familyIndex;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (presentableFamilyQueueIndex == UINT32_MAX)
|
||||
throw std::runtime_error("device doesn't support presenting to this surface");
|
||||
|
||||
if (graphicsFamilyQueueIndex == UINT32_MAX)
|
||||
{
|
||||
for (const Vk::Device::QueueFamilyInfo& queueInfo : queueFamilyInfo)
|
||||
{
|
||||
if (queueInfo.flags & VK_QUEUE_GRAPHICS_BIT)
|
||||
{
|
||||
graphicsFamilyQueueIndex = queueInfo.familyIndex;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (graphicsFamilyQueueIndex == UINT32_MAX)
|
||||
throw std::runtime_error("device doesn't support graphics operation");
|
||||
|
||||
UInt32 transferFamilyQueueIndex = UINT32_MAX;
|
||||
// Search for a transfer queue (first one being different to the graphics one)
|
||||
for (const Vk::Device::QueueFamilyInfo& queueInfo : queueFamilyInfo)
|
||||
{
|
||||
// Transfer bit is not mandatory if compute and graphics bits are set (as they implicitly support transfer)
|
||||
if (queueInfo.flags & (VK_QUEUE_COMPUTE_BIT | VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_TRANSFER_BIT))
|
||||
{
|
||||
transferFamilyQueueIndex = queueInfo.familyIndex;
|
||||
if (transferFamilyQueueIndex != graphicsFamilyQueueIndex)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
assert(transferFamilyQueueIndex != UINT32_MAX);
|
||||
|
||||
m_graphicsQueue = m_device.GetQueue(graphicsFamilyQueueIndex, 0);
|
||||
m_presentQueue = m_device.GetQueue(presentableFamilyQueueIndex, 0);
|
||||
m_transferQueue = m_device.GetQueue(transferFamilyQueueIndex, 0);
|
||||
|
||||
std::vector<VkSurfaceFormatKHR> surfaceFormats;
|
||||
if (!m_surface.GetFormats(physDeviceInfo.physDevice, &surfaceFormats))
|
||||
throw std::runtime_error("failed to query supported surface formats");
|
||||
|
||||
m_surfaceFormat = [&]() -> VkSurfaceFormatKHR
|
||||
{
|
||||
if (surfaceFormats.size() == 1 && surfaceFormats.front().format == VK_FORMAT_UNDEFINED)
|
||||
{
|
||||
// If the list contains one undefined format, it means any format can be used
|
||||
return { VK_FORMAT_R8G8B8A8_UNORM, VK_COLOR_SPACE_SRGB_NONLINEAR_KHR };
|
||||
}
|
||||
else
|
||||
{
|
||||
// Search for RGBA8 and default to first format
|
||||
for (const VkSurfaceFormatKHR& surfaceFormat : surfaceFormats)
|
||||
{
|
||||
if (surfaceFormat.format == VK_FORMAT_R8G8B8A8_UNORM)
|
||||
return surfaceFormat;
|
||||
}
|
||||
|
||||
return surfaceFormats.front();
|
||||
}
|
||||
}();
|
||||
|
||||
m_depthStencilFormat = VK_FORMAT_UNDEFINED;
|
||||
if (!parameters.depthFormats.empty())
|
||||
{
|
||||
for (PixelFormat format : parameters.depthFormats)
|
||||
{
|
||||
PixelFormatContent formatContent = PixelFormatInfo::GetContent(format);
|
||||
if (formatContent != PixelFormatContent::DepthStencil && formatContent != PixelFormatContent::Stencil)
|
||||
NazaraWarning("Invalid format " + PixelFormatInfo::GetName(format) + " for depth-stencil attachment");
|
||||
|
||||
m_depthStencilFormat = ToVulkan(format);
|
||||
if (m_depthStencilFormat == VK_FORMAT_UNDEFINED)
|
||||
continue;
|
||||
|
||||
VkFormatProperties formatProperties = m_device.GetInstance().GetPhysicalDeviceFormatProperties(physDeviceInfo.physDevice, m_depthStencilFormat);
|
||||
if (formatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT)
|
||||
break; //< Found it
|
||||
|
||||
m_depthStencilFormat = VK_FORMAT_UNDEFINED;
|
||||
}
|
||||
|
||||
if (m_depthStencilFormat == VK_FORMAT_UNDEFINED)
|
||||
throw std::runtime_error("failed to find a support depth-stencil format");
|
||||
}
|
||||
|
||||
if (!SetupRenderPass())
|
||||
throw std::runtime_error("failed to create renderpass");
|
||||
|
||||
if (!CreateSwapchain())
|
||||
throw std::runtime_error("failed to create swapchain");
|
||||
}
|
||||
|
||||
VulkanRenderWindow::~VulkanRenderWindow()
|
||||
VulkanSwapchain::~VulkanSwapchain()
|
||||
{
|
||||
if (m_device)
|
||||
m_device->WaitForIdle();
|
||||
m_device.WaitForIdle();
|
||||
|
||||
m_concurrentImageData.clear();
|
||||
m_renderPass.reset();
|
||||
|
|
@ -37,22 +163,13 @@ namespace Nz
|
|||
m_swapchain.Destroy();
|
||||
}
|
||||
|
||||
RenderFrame VulkanRenderWindow::Acquire()
|
||||
RenderFrame VulkanSwapchain::AcquireFrame()
|
||||
{
|
||||
bool invalidateFramebuffer = false;
|
||||
|
||||
Vector2ui size = m_owner.GetSize();
|
||||
// Special case: window is minimized
|
||||
if (size == Nz::Vector2ui::Zero() || m_owner.IsMinimized())
|
||||
return RenderFrame();
|
||||
|
||||
if (m_shouldRecreateSwapchain || size != m_swapchainSize)
|
||||
if (m_shouldRecreateSwapchain)
|
||||
{
|
||||
Vk::Surface& vulkanSurface = static_cast<VulkanSurface*>(m_owner.GetSurface())->GetSurface();
|
||||
|
||||
OnRenderTargetSizeChange(this, size);
|
||||
|
||||
if (!CreateSwapchain(vulkanSurface, size))
|
||||
if (!CreateSwapchain())
|
||||
throw std::runtime_error("failed to recreate swapchain");
|
||||
|
||||
m_shouldRecreateSwapchain = false;
|
||||
|
|
@ -79,7 +196,7 @@ namespace Nz
|
|||
|
||||
case VK_ERROR_OUT_OF_DATE_KHR:
|
||||
m_shouldRecreateSwapchain = true;
|
||||
return Acquire();
|
||||
return AcquireFrame();
|
||||
|
||||
// Not expected (since timeout is infinite)
|
||||
case VK_TIMEOUT:
|
||||
|
|
@ -102,191 +219,16 @@ namespace Nz
|
|||
|
||||
currentFrame.Reset(imageIndex);
|
||||
|
||||
return RenderFrame(¤tFrame, invalidateFramebuffer, size, imageIndex);
|
||||
return RenderFrame(¤tFrame, invalidateFramebuffer, m_swapchainSize, imageIndex);
|
||||
}
|
||||
|
||||
bool VulkanRenderWindow::Create(RendererImpl* /*renderer*/, RenderSurface* surface, const RenderWindowParameters& parameters)
|
||||
{
|
||||
std::shared_ptr<VulkanDevice> device = std::static_pointer_cast<VulkanDevice>(m_owner.GetRenderDevice());
|
||||
|
||||
const auto& physDeviceInfo = device->GetPhysicalDeviceInfo();
|
||||
|
||||
Vk::Surface& vulkanSurface = static_cast<VulkanSurface*>(surface)->GetSurface();
|
||||
|
||||
const std::vector<Vk::Device::QueueFamilyInfo>& queueFamilyInfo = device->GetEnabledQueues();
|
||||
UInt32 graphicsFamilyQueueIndex = UINT32_MAX;
|
||||
UInt32 presentableFamilyQueueIndex = UINT32_MAX;
|
||||
|
||||
for (const Vk::Device::QueueFamilyInfo& queueInfo : queueFamilyInfo)
|
||||
{
|
||||
bool supported = false;
|
||||
if (vulkanSurface.GetSupportPresentation(physDeviceInfo.physDevice, queueInfo.familyIndex, &supported) && supported)
|
||||
{
|
||||
if (presentableFamilyQueueIndex == UINT32_MAX || queueInfo.flags & VK_QUEUE_GRAPHICS_BIT)
|
||||
{
|
||||
presentableFamilyQueueIndex = queueInfo.familyIndex;
|
||||
if (queueInfo.flags & VK_QUEUE_GRAPHICS_BIT)
|
||||
{
|
||||
graphicsFamilyQueueIndex = queueInfo.familyIndex;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (presentableFamilyQueueIndex == UINT32_MAX)
|
||||
{
|
||||
NazaraError("device doesn't support presenting to this surface");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (graphicsFamilyQueueIndex == UINT32_MAX)
|
||||
{
|
||||
for (const Vk::Device::QueueFamilyInfo& queueInfo : queueFamilyInfo)
|
||||
{
|
||||
if (queueInfo.flags & VK_QUEUE_GRAPHICS_BIT)
|
||||
{
|
||||
graphicsFamilyQueueIndex = queueInfo.familyIndex;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (graphicsFamilyQueueIndex == UINT32_MAX)
|
||||
{
|
||||
NazaraError("device doesn't support graphics operations");
|
||||
return false;
|
||||
}
|
||||
|
||||
UInt32 transferFamilyQueueIndex = UINT32_MAX;
|
||||
// Search for a transfer queue (first one being different to the graphics one)
|
||||
for (const Vk::Device::QueueFamilyInfo& queueInfo : queueFamilyInfo)
|
||||
{
|
||||
// Transfer bit is not mandatory if compute and graphics bits are set (as they implicitly support transfer)
|
||||
if (queueInfo.flags & (VK_QUEUE_COMPUTE_BIT | VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_TRANSFER_BIT))
|
||||
{
|
||||
transferFamilyQueueIndex = queueInfo.familyIndex;
|
||||
if (transferFamilyQueueIndex != graphicsFamilyQueueIndex)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
assert(transferFamilyQueueIndex != UINT32_MAX);
|
||||
|
||||
m_device = std::move(device);
|
||||
|
||||
m_graphicsQueue = m_device->GetQueue(graphicsFamilyQueueIndex, 0);
|
||||
m_presentQueue = m_device->GetQueue(presentableFamilyQueueIndex, 0);
|
||||
m_transferQueue = m_device->GetQueue(transferFamilyQueueIndex, 0);
|
||||
|
||||
std::vector<VkSurfaceFormatKHR> surfaceFormats;
|
||||
if (!vulkanSurface.GetFormats(physDeviceInfo.physDevice, &surfaceFormats))
|
||||
{
|
||||
NazaraError("Failed to query supported surface formats");
|
||||
return false;
|
||||
}
|
||||
|
||||
m_surfaceFormat = [&] () -> VkSurfaceFormatKHR
|
||||
{
|
||||
if (surfaceFormats.size() == 1 && surfaceFormats.front().format == VK_FORMAT_UNDEFINED)
|
||||
{
|
||||
// If the list contains one undefined format, it means any format can be used
|
||||
return { VK_FORMAT_R8G8B8A8_UNORM, VK_COLOR_SPACE_SRGB_NONLINEAR_KHR };
|
||||
}
|
||||
else
|
||||
{
|
||||
// Search for RGBA8 and default to first format
|
||||
for (const VkSurfaceFormatKHR& surfaceFormat : surfaceFormats)
|
||||
{
|
||||
if (surfaceFormat.format == VK_FORMAT_R8G8B8A8_UNORM)
|
||||
return surfaceFormat;
|
||||
}
|
||||
|
||||
return surfaceFormats.front();
|
||||
}
|
||||
}();
|
||||
|
||||
m_depthStencilFormat = VK_FORMAT_MAX_ENUM;
|
||||
if (!parameters.depthFormats.empty())
|
||||
{
|
||||
for (PixelFormat format : parameters.depthFormats)
|
||||
{
|
||||
switch (format)
|
||||
{
|
||||
case PixelFormat::Depth16:
|
||||
m_depthStencilFormat = VK_FORMAT_D16_UNORM;
|
||||
break;
|
||||
|
||||
case PixelFormat::Depth16Stencil8:
|
||||
m_depthStencilFormat = VK_FORMAT_D16_UNORM_S8_UINT;
|
||||
break;
|
||||
|
||||
case PixelFormat::Depth24:
|
||||
case PixelFormat::Depth24Stencil8:
|
||||
m_depthStencilFormat = VK_FORMAT_D24_UNORM_S8_UINT;
|
||||
break;
|
||||
|
||||
case PixelFormat::Depth32F:
|
||||
m_depthStencilFormat = VK_FORMAT_D32_SFLOAT;
|
||||
break;
|
||||
|
||||
case PixelFormat::Depth32FStencil8:
|
||||
m_depthStencilFormat = VK_FORMAT_D32_SFLOAT_S8_UINT;
|
||||
break;
|
||||
|
||||
case PixelFormat::Stencil1:
|
||||
case PixelFormat::Stencil4:
|
||||
case PixelFormat::Stencil8:
|
||||
m_depthStencilFormat = VK_FORMAT_S8_UINT;
|
||||
break;
|
||||
|
||||
case PixelFormat::Stencil16:
|
||||
continue;
|
||||
|
||||
default:
|
||||
{
|
||||
PixelFormatContent formatContent = PixelFormatInfo::GetContent(format);
|
||||
if (formatContent != PixelFormatContent::DepthStencil && formatContent != PixelFormatContent::Stencil)
|
||||
NazaraWarning("Invalid format " + PixelFormatInfo::GetName(format) + " for depth-stencil attachment");
|
||||
|
||||
m_depthStencilFormat = VK_FORMAT_MAX_ENUM;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (m_depthStencilFormat != VK_FORMAT_MAX_ENUM)
|
||||
{
|
||||
VkFormatProperties formatProperties = m_device->GetInstance().GetPhysicalDeviceFormatProperties(physDeviceInfo.physDevice, m_depthStencilFormat);
|
||||
if (formatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT)
|
||||
break; //< Found it
|
||||
|
||||
m_depthStencilFormat = VK_FORMAT_MAX_ENUM;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!SetupRenderPass())
|
||||
{
|
||||
NazaraError("Failed to create render pass");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!CreateSwapchain(vulkanSurface, m_owner.GetSize()))
|
||||
{
|
||||
NazaraError("failed to create swapchain");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
std::shared_ptr<CommandPool> VulkanRenderWindow::CreateCommandPool(QueueType queueType)
|
||||
std::shared_ptr<CommandPool> VulkanSwapchain::CreateCommandPool(QueueType queueType)
|
||||
{
|
||||
UInt32 queueFamilyIndex = [&] {
|
||||
switch (queueType)
|
||||
{
|
||||
case QueueType::Compute:
|
||||
return m_device->GetDefaultFamilyIndex(QueueType::Compute);
|
||||
return m_device.GetDefaultFamilyIndex(QueueType::Compute);
|
||||
|
||||
case QueueType::Graphics:
|
||||
return m_graphicsQueue.GetQueueFamilyIndex();
|
||||
|
|
@ -298,31 +240,62 @@ namespace Nz
|
|||
throw std::runtime_error("invalid queue type " + std::to_string(UnderlyingCast(queueType)));
|
||||
}();
|
||||
|
||||
return std::make_shared<VulkanCommandPool>(*m_device, queueFamilyIndex);
|
||||
return std::make_shared<VulkanCommandPool>(m_device, queueFamilyIndex);
|
||||
}
|
||||
|
||||
const VulkanWindowFramebuffer& VulkanRenderWindow::GetFramebuffer(std::size_t i) const
|
||||
bool VulkanSwapchain::CreateSwapchain()
|
||||
{
|
||||
if (!SetupSwapchain(m_device.GetPhysicalDeviceInfo()))
|
||||
{
|
||||
NazaraError("Failed to create swapchain");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (m_depthStencilFormat != VK_FORMAT_MAX_ENUM && !SetupDepthBuffer())
|
||||
{
|
||||
NazaraError("Failed to create depth buffer");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!SetupFrameBuffers())
|
||||
{
|
||||
NazaraError("failed to create framebuffers");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
const VulkanWindowFramebuffer& VulkanSwapchain::GetFramebuffer(std::size_t i) const
|
||||
{
|
||||
assert(i < m_framebuffers.size());
|
||||
return m_framebuffers[i];
|
||||
}
|
||||
|
||||
std::size_t VulkanRenderWindow::GetFramebufferCount() const
|
||||
std::size_t VulkanSwapchain::GetFramebufferCount() const
|
||||
{
|
||||
return m_framebuffers.size();
|
||||
}
|
||||
|
||||
const VulkanRenderPass& VulkanRenderWindow::GetRenderPass() const
|
||||
const VulkanRenderPass& VulkanSwapchain::GetRenderPass() const
|
||||
{
|
||||
return *m_renderPass;
|
||||
}
|
||||
|
||||
const Vector2ui& VulkanRenderWindow::GetSize() const
|
||||
const Vector2ui& VulkanSwapchain::GetSize() const
|
||||
{
|
||||
return m_swapchainSize;
|
||||
}
|
||||
|
||||
void VulkanRenderWindow::Present(UInt32 imageIndex, VkSemaphore waitSemaphore)
|
||||
void VulkanSwapchain::NotifyResize(const Vector2ui& newSize)
|
||||
{
|
||||
OnRenderTargetSizeChange(this, newSize);
|
||||
|
||||
m_swapchainSize = newSize;
|
||||
m_shouldRecreateSwapchain = true;
|
||||
}
|
||||
|
||||
void VulkanSwapchain::Present(UInt32 imageIndex, VkSemaphore waitSemaphore)
|
||||
{
|
||||
NazaraAssert(imageIndex < m_inflightFences.size(), "Invalid image index");
|
||||
|
||||
|
|
@ -354,31 +327,7 @@ namespace Nz
|
|||
}
|
||||
}
|
||||
|
||||
bool VulkanRenderWindow::CreateSwapchain(Vk::Surface& surface, const Vector2ui& size)
|
||||
{
|
||||
assert(m_device);
|
||||
if (!SetupSwapchain(m_device->GetPhysicalDeviceInfo(), surface, size))
|
||||
{
|
||||
NazaraError("Failed to create swapchain");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (m_depthStencilFormat != VK_FORMAT_MAX_ENUM && !SetupDepthBuffer(size))
|
||||
{
|
||||
NazaraError("Failed to create depth buffer");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!SetupFrameBuffers(size))
|
||||
{
|
||||
NazaraError("failed to create framebuffers");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool VulkanRenderWindow::SetupDepthBuffer(const Vector2ui& size)
|
||||
bool VulkanSwapchain::SetupDepthBuffer()
|
||||
{
|
||||
VkImageCreateInfo imageCreateInfo = {
|
||||
VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
|
||||
|
|
@ -386,7 +335,7 @@ namespace Nz
|
|||
0U, // VkImageCreateFlags flags;
|
||||
VK_IMAGE_TYPE_2D, // VkImageType imageType;
|
||||
m_depthStencilFormat, // VkFormat format;
|
||||
{size.x, size.y, 1U}, // VkExtent3D extent;
|
||||
{ m_swapchainSize.x, m_swapchainSize.y, 1U }, // VkExtent3D extent;
|
||||
1U, // uint32_t mipLevels;
|
||||
1U, // uint32_t arrayLayers;
|
||||
VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
|
||||
|
|
@ -398,14 +347,14 @@ namespace Nz
|
|||
VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
|
||||
};
|
||||
|
||||
if (!m_depthBuffer.Create(*m_device, imageCreateInfo))
|
||||
if (!m_depthBuffer.Create(m_device, imageCreateInfo))
|
||||
{
|
||||
NazaraError("Failed to create depth buffer");
|
||||
return false;
|
||||
}
|
||||
|
||||
VkMemoryRequirements memoryReq = m_depthBuffer.GetMemoryRequirements();
|
||||
if (!m_depthBufferMemory.Create(*m_device, memoryReq.size, memoryReq.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT))
|
||||
if (!m_depthBufferMemory.Create(m_device, memoryReq.size, memoryReq.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT))
|
||||
{
|
||||
NazaraError("Failed to allocate depth buffer memory");
|
||||
return false;
|
||||
|
|
@ -433,21 +382,21 @@ namespace Nz
|
|||
VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType;
|
||||
m_depthStencilFormat, // VkFormat format;
|
||||
{ // VkComponentMapping components;
|
||||
VK_COMPONENT_SWIZZLE_R, // VkComponentSwizzle .r;
|
||||
VK_COMPONENT_SWIZZLE_G, // VkComponentSwizzle .g;
|
||||
VK_COMPONENT_SWIZZLE_B, // VkComponentSwizzle .b;
|
||||
VK_COMPONENT_SWIZZLE_A // VkComponentSwizzle .a;
|
||||
VK_COMPONENT_SWIZZLE_R, // VkComponentSwizzle .r;
|
||||
VK_COMPONENT_SWIZZLE_G, // VkComponentSwizzle .g;
|
||||
VK_COMPONENT_SWIZZLE_B, // VkComponentSwizzle .b;
|
||||
VK_COMPONENT_SWIZZLE_A // VkComponentSwizzle .a;
|
||||
},
|
||||
{ // VkImageSubresourceRange subresourceRange;
|
||||
aspectMask, // VkImageAspectFlags .aspectMask;
|
||||
0, // uint32_t .baseMipLevel;
|
||||
1, // uint32_t .levelCount;
|
||||
0, // uint32_t .baseArrayLayer;
|
||||
1 // uint32_t .layerCount;
|
||||
aspectMask, // VkImageAspectFlags .aspectMask;
|
||||
0, // uint32_t .baseMipLevel;
|
||||
1, // uint32_t .levelCount;
|
||||
0, // uint32_t .baseArrayLayer;
|
||||
1 // uint32_t .layerCount;
|
||||
}
|
||||
};
|
||||
|
||||
if (!m_depthBufferView.Create(*m_device, imageViewCreateInfo))
|
||||
if (!m_depthBufferView.Create(m_device, imageViewCreateInfo))
|
||||
{
|
||||
NazaraError("Failed to create depth buffer view");
|
||||
return false;
|
||||
|
|
@ -456,7 +405,7 @@ namespace Nz
|
|||
return true;
|
||||
}
|
||||
|
||||
bool VulkanRenderWindow::SetupFrameBuffers(const Vector2ui& size)
|
||||
bool VulkanSwapchain::SetupFrameBuffers()
|
||||
{
|
||||
UInt32 imageCount = m_swapchain.GetImageCount();
|
||||
|
||||
|
|
@ -473,14 +422,14 @@ namespace Nz
|
|||
m_renderPass->GetRenderPass(),
|
||||
(attachments[1] != VK_NULL_HANDLE) ? 2U : 1U,
|
||||
attachments.data(),
|
||||
size.x,
|
||||
size.y,
|
||||
m_swapchainSize.x,
|
||||
m_swapchainSize.y,
|
||||
1U
|
||||
};
|
||||
|
||||
Vk::Framebuffer framebuffer;
|
||||
|
||||
if (!framebuffer.Create(*m_device, frameBufferCreate))
|
||||
if (!framebuffer.Create(*m_swapchain.GetDevice(), frameBufferCreate))
|
||||
{
|
||||
NazaraError("Failed to create framebuffer for image #" + NumberToString(i) + ": " + TranslateVulkanError(framebuffer.GetLastErrorCode()));
|
||||
return false;
|
||||
|
|
@ -492,7 +441,7 @@ namespace Nz
|
|||
return true;
|
||||
}
|
||||
|
||||
bool VulkanRenderWindow::SetupRenderPass()
|
||||
bool VulkanSwapchain::SetupRenderPass()
|
||||
{
|
||||
std::optional<PixelFormat> colorFormat = FromVulkan(m_surfaceFormat.format);
|
||||
if (!colorFormat)
|
||||
|
|
@ -517,34 +466,98 @@ namespace Nz
|
|||
std::vector<RenderPass::SubpassDependency> subpassDependencies;
|
||||
|
||||
BuildRenderPass(*colorFormat, depthStencilFormat.value_or(PixelFormat::Undefined), attachments, subpassDescriptions, subpassDependencies);
|
||||
m_renderPass.emplace(*m_device, std::move(attachments), std::move(subpassDescriptions), std::move(subpassDependencies));
|
||||
m_renderPass.emplace(m_device, std::move(attachments), std::move(subpassDescriptions), std::move(subpassDependencies));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool VulkanRenderWindow::SetupSwapchain(const Vk::PhysicalDevice& deviceInfo, Vk::Surface& surface, const Vector2ui& size)
|
||||
bool VulkanSwapchain::SetupSurface(WindowHandle windowHandle)
|
||||
{
|
||||
bool success = false;
|
||||
#if defined(NAZARA_PLATFORM_WINDOWS)
|
||||
{
|
||||
NazaraAssert(windowHandle.type == WindowBackend::Windows, "expected Windows window");
|
||||
|
||||
HWND winHandle = reinterpret_cast<HWND>(windowHandle.windows.window);
|
||||
HINSTANCE instance = reinterpret_cast<HINSTANCE>(GetWindowLongPtrW(winHandle, GWLP_HINSTANCE));
|
||||
|
||||
success = m_surface.Create(instance, winHandle);
|
||||
}
|
||||
#elif defined(NAZARA_PLATFORM_LINUX)
|
||||
{
|
||||
switch (windowHandle.type)
|
||||
{
|
||||
#ifdef VK_USE_PLATFORM_WAYLAND_KHR
|
||||
case WindowBackend::Wayland:
|
||||
{
|
||||
wl_display* display = static_cast<wl_display*>(windowHandle.wayland.display);
|
||||
wl_surface* surface = static_cast<wl_surface*>(windowHandle.wayland.surface);
|
||||
|
||||
success = m_surface.Create(display, surface);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef VK_USE_PLATFORM_XLIB_KHR
|
||||
case WindowBackend::X11:
|
||||
{
|
||||
Display* display = static_cast<Display*>(windowHandle.x11.display);
|
||||
::Window window = static_cast<::Window>(windowHandle.x11.window);
|
||||
|
||||
success = m_surface.Create(display, window);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
default:
|
||||
{
|
||||
NazaraError("unhandled window type");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
#elif defined(NAZARA_PLATFORM_MACOS)
|
||||
{
|
||||
NazaraAssert(windowHandle.type == WindowBackend::Cocoa, "expected cocoa window");
|
||||
id layer = CreateAndAttachMetalLayer(windowHandle.cocoa.window);
|
||||
success = m_surface.Create(layer);
|
||||
}
|
||||
#else
|
||||
#error This OS is not supported by Vulkan
|
||||
#endif
|
||||
|
||||
if (!success)
|
||||
{
|
||||
NazaraError("Failed to create Vulkan surface: " + TranslateVulkanError(m_surface.GetLastErrorCode()));
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool VulkanSwapchain::SetupSwapchain(const Vk::PhysicalDevice& deviceInfo)
|
||||
{
|
||||
VkSurfaceCapabilitiesKHR surfaceCapabilities;
|
||||
if (!surface.GetCapabilities(deviceInfo.physDevice, &surfaceCapabilities))
|
||||
if (!m_surface.GetCapabilities(deviceInfo.physDevice, &surfaceCapabilities))
|
||||
{
|
||||
NazaraError("Failed to query surface capabilities");
|
||||
return false;
|
||||
}
|
||||
|
||||
Nz::UInt32 imageCount = surfaceCapabilities.minImageCount + 1;
|
||||
UInt32 imageCount = surfaceCapabilities.minImageCount + 1;
|
||||
if (surfaceCapabilities.maxImageCount > 0 && imageCount > surfaceCapabilities.maxImageCount)
|
||||
imageCount = surfaceCapabilities.maxImageCount;
|
||||
|
||||
VkExtent2D extent;
|
||||
if (surfaceCapabilities.currentExtent.width == 0xFFFFFFFF)
|
||||
{
|
||||
extent.width = Nz::Clamp<Nz::UInt32>(size.x, surfaceCapabilities.minImageExtent.width, surfaceCapabilities.maxImageExtent.width);
|
||||
extent.height = Nz::Clamp<Nz::UInt32>(size.y, surfaceCapabilities.minImageExtent.height, surfaceCapabilities.maxImageExtent.height);
|
||||
extent.width = std::clamp<UInt32>(m_swapchainSize.x, surfaceCapabilities.minImageExtent.width, surfaceCapabilities.maxImageExtent.width);
|
||||
extent.height = std::clamp<UInt32>(m_swapchainSize.y, surfaceCapabilities.minImageExtent.height, surfaceCapabilities.maxImageExtent.height);
|
||||
}
|
||||
else
|
||||
extent = surfaceCapabilities.currentExtent;
|
||||
|
||||
std::vector<VkPresentModeKHR> presentModes;
|
||||
if (!surface.GetPresentModes(deviceInfo.physDevice, &presentModes))
|
||||
if (!m_surface.GetPresentModes(deviceInfo.physDevice, &presentModes))
|
||||
{
|
||||
NazaraError("Failed to query supported present modes");
|
||||
return false;
|
||||
|
|
@ -564,13 +577,13 @@ namespace Nz
|
|||
}
|
||||
|
||||
// Ensure all operations on the device have been finished before recreating the swapchain (this can be avoided but is more complicated)
|
||||
m_device->WaitForIdle();
|
||||
m_device.WaitForIdle();
|
||||
|
||||
VkSwapchainCreateInfoKHR swapchainInfo = {
|
||||
VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR,
|
||||
nullptr,
|
||||
0,
|
||||
surface,
|
||||
m_surface,
|
||||
imageCount,
|
||||
m_surfaceFormat.format,
|
||||
m_surfaceFormat.colorSpace,
|
||||
|
|
@ -587,14 +600,13 @@ namespace Nz
|
|||
};
|
||||
|
||||
Vk::Swapchain newSwapchain;
|
||||
if (!newSwapchain.Create(*m_device, swapchainInfo))
|
||||
if (!newSwapchain.Create(m_device, swapchainInfo))
|
||||
{
|
||||
NazaraError("failed to create swapchain: " + TranslateVulkanError(newSwapchain.GetLastErrorCode()));
|
||||
return false;
|
||||
}
|
||||
|
||||
m_swapchain = std::move(newSwapchain);
|
||||
m_swapchainSize = size;
|
||||
|
||||
// Framebuffers
|
||||
imageCount = m_swapchain.GetImageCount();
|
||||
|
|
@ -9,7 +9,7 @@
|
|||
|
||||
namespace Nz
|
||||
{
|
||||
Canvas::Canvas(entt::registry& registry, Nz::EventHandler& eventHandler, Nz::CursorControllerHandle cursorController, UInt32 renderMask, int initialRenderLayer) :
|
||||
Canvas::Canvas(entt::registry& registry, Nz::WindowEventHandler& eventHandler, Nz::CursorControllerHandle cursorController, UInt32 renderMask, int initialRenderLayer) :
|
||||
BaseWidget(std::make_shared<DefaultWidgetTheme>()),
|
||||
m_cursorController(cursorController),
|
||||
m_renderMask(renderMask),
|
||||
|
|
@ -106,7 +106,7 @@ namespace Nz
|
|||
}
|
||||
}
|
||||
|
||||
void Canvas::OnEventMouseButtonPressed(const EventHandler* /*eventHandler*/, const WindowEvent::MouseButtonEvent& event)
|
||||
void Canvas::OnEventMouseButtonPressed(const WindowEventHandler* /*eventHandler*/, const WindowEvent::MouseButtonEvent& event)
|
||||
{
|
||||
UpdateHoveredWidget(event.x, event.y);
|
||||
|
||||
|
|
@ -130,7 +130,7 @@ namespace Nz
|
|||
m_mouseOwnerButtons[event.button] = true;
|
||||
}
|
||||
|
||||
void Canvas::OnEventMouseButtonRelease(const EventHandler* /*eventHandler*/, const WindowEvent::MouseButtonEvent& event)
|
||||
void Canvas::OnEventMouseButtonRelease(const WindowEventHandler* /*eventHandler*/, const WindowEvent::MouseButtonEvent& event)
|
||||
{
|
||||
if (std::size_t targetWidgetIndex = GetMouseEventTarget(); targetWidgetIndex != InvalidCanvasIndex)
|
||||
{
|
||||
|
|
@ -150,7 +150,7 @@ namespace Nz
|
|||
UpdateHoveredWidget(event.x, event.y);
|
||||
}
|
||||
|
||||
void Canvas::OnEventMouseEntered(const EventHandler* /*eventHandler*/)
|
||||
void Canvas::OnEventMouseEntered(const WindowEventHandler* /*eventHandler*/)
|
||||
{
|
||||
// Keep previous mouse states but not new ones
|
||||
if (m_mouseOwner != InvalidCanvasIndex)
|
||||
|
|
@ -176,7 +176,7 @@ namespace Nz
|
|||
m_mouseOwnerButtons.reset();
|
||||
}
|
||||
|
||||
void Canvas::OnEventMouseLeft(const EventHandler* /*eventHandler*/)
|
||||
void Canvas::OnEventMouseLeft(const WindowEventHandler* /*eventHandler*/)
|
||||
{
|
||||
if (std::size_t targetWidgetIndex = GetMouseEventTarget(); targetWidgetIndex != InvalidCanvasIndex)
|
||||
{
|
||||
|
|
@ -185,7 +185,7 @@ namespace Nz
|
|||
}
|
||||
}
|
||||
|
||||
void Canvas::OnEventMouseMoved(const EventHandler* /*eventHandler*/, const WindowEvent::MouseMoveEvent& event)
|
||||
void Canvas::OnEventMouseMoved(const WindowEventHandler* /*eventHandler*/, const WindowEvent::MouseMoveEvent& event)
|
||||
{
|
||||
// Don't update hovered widget while the user doesn't release its mouse
|
||||
UpdateHoveredWidget(event.x, event.y);
|
||||
|
|
@ -201,7 +201,7 @@ namespace Nz
|
|||
}
|
||||
}
|
||||
|
||||
void Canvas::OnEventMouseWheelMoved(const EventHandler* /*eventHandler*/, const WindowEvent::MouseWheelEvent& event)
|
||||
void Canvas::OnEventMouseWheelMoved(const WindowEventHandler* /*eventHandler*/, const WindowEvent::MouseWheelEvent& event)
|
||||
{
|
||||
if (std::size_t targetWidgetIndex = GetMouseEventTarget(); targetWidgetIndex != InvalidCanvasIndex)
|
||||
{
|
||||
|
|
@ -215,7 +215,7 @@ namespace Nz
|
|||
}
|
||||
}
|
||||
|
||||
void Canvas::OnEventKeyPressed(const EventHandler* eventHandler, const WindowEvent::KeyEvent& event)
|
||||
void Canvas::OnEventKeyPressed(const WindowEventHandler* eventHandler, const WindowEvent::KeyEvent& event)
|
||||
{
|
||||
if (m_keyboardOwner != InvalidCanvasIndex)
|
||||
{
|
||||
|
|
@ -273,7 +273,7 @@ namespace Nz
|
|||
OnUnhandledKeyPressed(eventHandler, event);
|
||||
}
|
||||
|
||||
void Canvas::OnEventKeyReleased(const EventHandler* eventHandler, const WindowEvent::KeyEvent& event)
|
||||
void Canvas::OnEventKeyReleased(const WindowEventHandler* eventHandler, const WindowEvent::KeyEvent& event)
|
||||
{
|
||||
if (m_keyboardOwner != InvalidCanvasIndex)
|
||||
m_widgetEntries[m_keyboardOwner].widget->OnKeyReleased(event);
|
||||
|
|
@ -281,13 +281,13 @@ namespace Nz
|
|||
OnUnhandledKeyReleased(eventHandler, event);
|
||||
}
|
||||
|
||||
void Canvas::OnEventTextEntered(const EventHandler* /*eventHandler*/, const WindowEvent::TextEvent& event)
|
||||
void Canvas::OnEventTextEntered(const WindowEventHandler* /*eventHandler*/, const WindowEvent::TextEvent& event)
|
||||
{
|
||||
if (m_keyboardOwner != InvalidCanvasIndex)
|
||||
m_widgetEntries[m_keyboardOwner].widget->OnTextEntered(event.character, event.repeated);
|
||||
}
|
||||
|
||||
void Canvas::OnEventTextEdited(const EventHandler* /*eventHandler*/, const WindowEvent::EditEvent& event)
|
||||
void Canvas::OnEventTextEdited(const WindowEventHandler* /*eventHandler*/, const WindowEvent::EditEvent& event)
|
||||
{
|
||||
if (m_keyboardOwner != InvalidCanvasIndex)
|
||||
m_widgetEntries[m_keyboardOwner].widget->OnTextEdited(event.text, event.length);
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@
|
|||
#include <Nazara/Math.hpp>
|
||||
#include <Nazara/Platform.hpp>
|
||||
#include <Nazara/Renderer.hpp>
|
||||
#include <Nazara/Renderer/DebugDrawer.hpp>
|
||||
#include <NZSL/FilesystemModuleResolver.hpp>
|
||||
#include <NZSL/LangWriter.hpp>
|
||||
#include <NZSL/Parser.hpp>
|
||||
|
|
@ -12,6 +11,7 @@
|
|||
#include <chrono>
|
||||
#include <iostream>
|
||||
#include <thread>
|
||||
#include <Windows.h>
|
||||
|
||||
NAZARA_REQUEST_DEDICATED_GPU()
|
||||
|
||||
|
|
@ -101,10 +101,11 @@ int main()
|
|||
|
||||
std::shared_ptr<Nz::RenderDevice> device = Nz::Renderer::Instance()->InstanciateRenderDevice(0);
|
||||
|
||||
Nz::RenderWindow window;
|
||||
Nz::Window window;
|
||||
Nz::WindowSwapchain windowSwapchain(device, window);
|
||||
|
||||
std::string windowTitle = "Render Test";
|
||||
if (!window.Create(device, Nz::VideoMode(800, 600, 32), windowTitle))
|
||||
if (!window.Create(Nz::VideoMode(1280, 720), windowTitle))
|
||||
{
|
||||
std::cout << "Failed to create Window" << std::endl;
|
||||
return __LINE__;
|
||||
|
|
@ -153,15 +154,13 @@ int main()
|
|||
std::cout << "Vertex count: " << meshVB->GetVertexCount() << std::endl;
|
||||
|
||||
// Create renderbuffers (GPU buffers)
|
||||
const std::shared_ptr<Nz::RenderDevice>& renderDevice = window.GetRenderDevice();
|
||||
|
||||
assert(meshIB->GetBuffer()->GetStorage() == Nz::DataStorage::Software);
|
||||
assert(meshVB->GetBuffer()->GetStorage() == Nz::DataStorage::Software);
|
||||
const Nz::SoftwareBuffer* indexBufferContent = static_cast<const Nz::SoftwareBuffer*>(meshIB->GetBuffer().get());
|
||||
const Nz::SoftwareBuffer* vertexBufferContent = static_cast<const Nz::SoftwareBuffer*>(meshVB->GetBuffer().get());
|
||||
|
||||
std::shared_ptr<Nz::RenderBuffer> renderBufferIB = renderDevice->InstantiateBuffer(Nz::BufferType::Index, indexBufferContent->GetSize(), Nz::BufferUsage::DeviceLocal, indexBufferContent->GetData());
|
||||
std::shared_ptr<Nz::RenderBuffer> renderBufferVB = renderDevice->InstantiateBuffer(Nz::BufferType::Vertex, vertexBufferContent->GetSize(), Nz::BufferUsage::DeviceLocal, vertexBufferContent->GetData());
|
||||
std::shared_ptr<Nz::RenderBuffer> renderBufferIB = device->InstantiateBuffer(Nz::BufferType::Index, indexBufferContent->GetSize(), Nz::BufferUsage::DeviceLocal, indexBufferContent->GetData());
|
||||
std::shared_ptr<Nz::RenderBuffer> renderBufferVB = device->InstantiateBuffer(Nz::BufferType::Vertex, vertexBufferContent->GetSize(), Nz::BufferUsage::DeviceLocal, vertexBufferContent->GetData());
|
||||
|
||||
// Texture
|
||||
Nz::TextureParams texParams;
|
||||
|
|
@ -244,15 +243,13 @@ int main()
|
|||
|
||||
std::shared_ptr<Nz::RenderPipeline> pipeline = device->InstantiateRenderPipeline(pipelineInfo);
|
||||
|
||||
std::shared_ptr<Nz::CommandPool> commandPool = renderDevice->InstantiateCommandPool(Nz::QueueType::Graphics);
|
||||
std::shared_ptr<Nz::CommandPool> commandPool = device->InstantiateCommandPool(Nz::QueueType::Graphics);
|
||||
|
||||
Nz::Vector3f viewerPos = Nz::Vector3f::Zero();
|
||||
|
||||
Nz::EulerAnglesf camAngles(0.f, 0.f, 0.f);
|
||||
Nz::Quaternionf camQuat(camAngles);
|
||||
|
||||
window.EnableEventPolling(true);
|
||||
|
||||
Nz::MillisecondClock updateClock;
|
||||
Nz::MillisecondClock secondClock;
|
||||
unsigned int fps = 0;
|
||||
|
|
@ -260,49 +257,42 @@ int main()
|
|||
|
||||
Nz::Mouse::SetRelativeMouseMode(true);
|
||||
|
||||
Nz::DebugDrawer debugDrawer(*renderDevice);
|
||||
Nz::DebugDrawer debugDrawer(*device);
|
||||
|
||||
Nz::WindowEventHandler& windowEvents = window.GetEventHandler();
|
||||
windowEvents.OnKeyPressed.Connect([&](const Nz::WindowEventHandler*, const Nz::WindowEvent::KeyEvent& key)
|
||||
{
|
||||
if (key.virtualKey == Nz::Keyboard::VKey::F1)
|
||||
window.Create(Nz::VideoMode(1920, 1080), windowTitle);
|
||||
});
|
||||
|
||||
windowEvents.OnMouseMoved.Connect([&](const Nz::WindowEventHandler*, const Nz::WindowEvent::MouseMoveEvent& mouseMove)
|
||||
{
|
||||
// Gestion de la caméra free-fly (Rotation)
|
||||
float sensitivity = 0.3f; // Sensibilité de la souris
|
||||
|
||||
// On modifie l'angle de la caméra grâce au déplacement relatif sur X de la souris
|
||||
camAngles.yaw = camAngles.yaw - mouseMove.deltaX * sensitivity;
|
||||
camAngles.yaw.Normalize();
|
||||
|
||||
// Idem, mais pour éviter les problèmes de calcul de la matrice de vue, on restreint les angles
|
||||
camAngles.pitch = Nz::Clamp(camAngles.pitch - mouseMove.deltaY * sensitivity, -89.f, 89.f);
|
||||
|
||||
camQuat = camAngles;
|
||||
|
||||
uboUpdate = true;
|
||||
});
|
||||
|
||||
windowEvents.OnResized.Connect([&](const Nz::WindowEventHandler*, const Nz::WindowEvent::SizeEvent& sizeEvent)
|
||||
{
|
||||
windowSize = { sizeEvent.width, sizeEvent.height };
|
||||
ubo.projectionMatrix = Nz::Matrix4f::Perspective(Nz::DegreeAnglef(70.f), float(windowSize.x) / windowSize.y, 0.1f, 1000.f);
|
||||
uboUpdate = true;
|
||||
});
|
||||
|
||||
while (window.IsOpen())
|
||||
{
|
||||
Nz::WindowEvent event;
|
||||
while (window.PollEvent(&event))
|
||||
{
|
||||
switch (event.type)
|
||||
{
|
||||
case Nz::WindowEventType::Quit:
|
||||
window.Close();
|
||||
break;
|
||||
|
||||
case Nz::WindowEventType::MouseMoved: // La souris a bougé
|
||||
{
|
||||
// Gestion de la caméra free-fly (Rotation)
|
||||
float sensitivity = 0.3f; // Sensibilité de la souris
|
||||
|
||||
// On modifie l'angle de la caméra grâce au déplacement relatif sur X de la souris
|
||||
camAngles.yaw = camAngles.yaw - event.mouseMove.deltaX * sensitivity;
|
||||
camAngles.yaw.Normalize();
|
||||
|
||||
// Idem, mais pour éviter les problèmes de calcul de la matrice de vue, on restreint les angles
|
||||
camAngles.pitch = Nz::Clamp(camAngles.pitch - event.mouseMove.deltaY*sensitivity, -89.f, 89.f);
|
||||
|
||||
camQuat = camAngles;
|
||||
|
||||
uboUpdate = true;
|
||||
break;
|
||||
}
|
||||
|
||||
case Nz::WindowEventType::Resized:
|
||||
{
|
||||
windowSize = window.GetSize();
|
||||
ubo.projectionMatrix = Nz::Matrix4f::Perspective(Nz::DegreeAnglef(70.f), float(windowSize.x) / windowSize.y, 0.1f, 1000.f);
|
||||
uboUpdate = true;
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
Nz::Window::ProcessEvents();
|
||||
|
||||
if (std::optional<Nz::Time> deltaTime = updateClock.RestartIfOver(Nz::Time::TickDuration(60)))
|
||||
{
|
||||
|
|
@ -334,7 +324,7 @@ int main()
|
|||
uboUpdate = true;
|
||||
}
|
||||
|
||||
Nz::RenderFrame frame = window.AcquireFrame();
|
||||
Nz::RenderFrame frame = windowSwapchain.AcquireFrame();
|
||||
if (!frame)
|
||||
{
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(1));
|
||||
|
|
@ -373,10 +363,11 @@ int main()
|
|||
|
||||
debugDrawer.Prepare(frame);
|
||||
|
||||
const Nz::RenderTarget* windowRT = window.GetRenderTarget();
|
||||
const Nz::RenderTarget& windowRT = windowSwapchain.GetSwapchain();
|
||||
frame.Execute([&](Nz::CommandBufferBuilder& builder)
|
||||
{
|
||||
Nz::Recti renderRect(0, 0, window.GetSize().x, window.GetSize().y);
|
||||
windowSize = window.GetSize();
|
||||
Nz::Recti renderRect(0, 0, windowSize.x, windowSize.y);
|
||||
|
||||
Nz::CommandBufferBuilder::ClearValues clearValues[2];
|
||||
clearValues[0].color = Nz::Color::Black();
|
||||
|
|
@ -385,7 +376,7 @@ int main()
|
|||
|
||||
builder.BeginDebugRegion("Main window rendering", Nz::Color::Green());
|
||||
{
|
||||
builder.BeginRenderPass(windowRT->GetFramebuffer(frame.GetFramebufferIndex()), windowRT->GetRenderPass(), renderRect, { clearValues[0], clearValues[1] });
|
||||
builder.BeginRenderPass(windowRT.GetFramebuffer(frame.GetFramebufferIndex()), windowRT.GetRenderPass(), renderRect, { clearValues[0], clearValues[1] });
|
||||
{
|
||||
builder.BindIndexBuffer(*renderBufferIB, Nz::IndexType::U16);
|
||||
builder.BindRenderPipeline(*pipeline);
|
||||
|
|
|
|||
Loading…
Reference in New Issue