diff --git a/CMakeLists.txt b/CMakeLists.txt index 67897e8..dbfe32b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -15,7 +15,7 @@ set(CMAKE_CXX_STANDARD_REQUIRED ON) set(QT_PACKAGE_NAME Qt5 CACHE STRING "Set Qt package name, i.e. Qt5 or Qt6.") set(QT_PACKAGE_VERSION 5.10 CACHE STRING "Set minimum Qt package version.") -find_package(vsg 0.1.6 REQUIRED) +find_package(vsg 0.1.7 REQUIRED) find_package(vsgXchange) # only used by exanples find_package(${QT_PACKAGE_NAME} ${QT_PACKAGE_VERSION} COMPONENTS Widgets REQUIRED) diff --git a/examples/vsgqtviewer/main.cpp b/examples/vsgqtviewer/main.cpp index 21ed38f..9952684 100644 --- a/examples/vsgqtviewer/main.cpp +++ b/examples/vsgqtviewer/main.cpp @@ -68,7 +68,7 @@ int main(int argc, char* argv[]) // provide the calls to set up the vsg::Viewer that will be used to render to the QWindow subclass vsgQt::ViewerWindow viewerWindow->initializeCallback = [&](vsgQt::ViewerWindow& vw) { - auto& window = vw.proxyWindow; + auto& window = vw.windowAdapter; if (!window) return false; auto& viewer = vw.viewer; diff --git a/include/vsgQt/ProxySurface.h b/include/vsgQt/ProxySurface.h deleted file mode 100644 index 72ce70b..0000000 --- a/include/vsgQt/ProxySurface.h +++ /dev/null @@ -1,30 +0,0 @@ -#pragma once - -/* - -Copyright(c) 2021 Robert Osfield - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - - */ - -#include -#include - -namespace vsgQt -{ - - class VSGQT_DECLSPEC ProxySurface : public vsg::Inherit - { - public: - ProxySurface(VkSurfaceKHR surface, vsg::Instance* instance); - - protected: - virtual ~ProxySurface(); - }; - -} // namespace vsgQt diff --git a/include/vsgQt/ProxyWindow.h b/include/vsgQt/ProxyWindow.h deleted file mode 100644 index 2c8f3dc..0000000 --- a/include/vsgQt/ProxyWindow.h +++ /dev/null @@ -1,54 +0,0 @@ -#pragma once - -/* - -Copyright(c) 2021 Robert Osfield - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - - */ - -#include -#include - -namespace vsgQt -{ - - // forward declare - class ViewerWindow; - - class VSGQT_DECLSPEC ProxyWindow : public vsg::Inherit - { - public: - ProxyWindow(ViewerWindow* win, vsg::ref_ptr traits); - - ProxyWindow() = delete; - ProxyWindow(const Window&) = delete; - ProxyWindow operator=(const Window&) = delete; - - bool visible() const override { return _window != nullptr; } - bool valid() const override { return _window != nullptr; } - - bool pollEvents(vsg::UIEvents& events) override; - - bool resized() const override; - - void resize() override; - - virtual const char* instanceExtensionSurfaceName() const override; - - vsg::UIEvents bufferedEvents; - - protected: - virtual void _initSurface() override; - - virtual ~ProxyWindow() override; - - ViewerWindow* _window = nullptr; - }; - -} // namespace vsgQt diff --git a/include/vsgQt/ViewerWindow.h b/include/vsgQt/ViewerWindow.h index ce2ccd1..d09d77f 100644 --- a/include/vsgQt/ViewerWindow.h +++ b/include/vsgQt/ViewerWindow.h @@ -16,9 +16,10 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI #include #include +#include +#include + #include -#include -#include namespace vsgQt { @@ -33,8 +34,7 @@ namespace vsgQt vsg::ref_ptr instance; vsg::ref_ptr viewer; - vsg::ref_ptr proxySurface; - vsg::ref_ptr proxyWindow; + vsg::ref_ptr windowAdapter; vsg::ref_ptr keyboardMap; using InitialCallback = std::function; @@ -50,6 +50,8 @@ namespace vsgQt bool event(QEvent* e) override; void exposeEvent(QExposeEvent*) override; + void hideEvent(QHideEvent *ev) override; + void keyPressEvent(QKeyEvent*) override; void keyReleaseEvent(QKeyEvent*) override; void mouseMoveEvent(QMouseEvent*) override; diff --git a/src/vsgQt/CMakeLists.txt b/src/vsgQt/CMakeLists.txt index d29d1d0..1b31f09 100644 --- a/src/vsgQt/CMakeLists.txt +++ b/src/vsgQt/CMakeLists.txt @@ -34,15 +34,11 @@ endmacro() set(SOURCES KeyboardMap.cpp - ProxySurface.cpp - ProxyWindow.cpp ViewerWindow.cpp ) set(HEADERS ../../include/vsgQt/KeyboardMap.h - ../../include/vsgQt/ProxySurface.h - ../../include/vsgQt/ProxyWindow.h ../../include/vsgQt/ViewerWindow.h ) diff --git a/src/vsgQt/ProxySurface.cpp b/src/vsgQt/ProxySurface.cpp deleted file mode 100644 index d02ee43..0000000 --- a/src/vsgQt/ProxySurface.cpp +++ /dev/null @@ -1,31 +0,0 @@ -/* - -Copyright(c) 2021 Robert Osfield, Andre Normann - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - - */ - -#include - -#include - -using namespace vsgQt; - -ProxySurface::ProxySurface(VkSurfaceKHR surface, vsg::Instance* instance) : - Inherit(surface, instance) -{ - std::cout << __func__ << " vkSurface = " << surface << std::endl; -} - -ProxySurface::~ProxySurface() -{ - std::cout << __func__ << " vkSurface = " << _surface << std::endl; - // Prevent vsg::Surface destructor from calling vkDestroySurfaceKHR on this - // surface as QtWindow owns the surface. - _surface = 0; -} diff --git a/src/vsgQt/ProxyWindow.cpp b/src/vsgQt/ProxyWindow.cpp deleted file mode 100644 index 22a3145..0000000 --- a/src/vsgQt/ProxyWindow.cpp +++ /dev/null @@ -1,91 +0,0 @@ -/* - -Copyright(c) 2021 Robert Osfield, Andre Normann - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - - */ - -#include -#include -#include - -#include -#include - -using namespace vsgQt; - -ProxyWindow::ProxyWindow(ViewerWindow* win, - vsg::ref_ptr traits) : - Inherit(traits), _window(win) -{ - _instance = win->instance; - - if (traits->shareWindow) - { - share(*traits->shareWindow); - } - - _extent2D.width = win->size().width(); - _extent2D.height = win->size().height(); - - traits->nativeWindow = win; -} - -bool ProxyWindow::pollEvents(vsg::UIEvents& events) -{ - if (bufferedEvents.size() > 0) - { - events.splice(events.end(), bufferedEvents); - bufferedEvents.clear(); - return true; - } - - return false; -} - -bool ProxyWindow::resized() const -{ - const auto width = _window->width(); - const auto height = _window->height(); - return width != int(_extent2D.width) || height != int(_extent2D.height); -} - -void ProxyWindow::resize() -{ - const auto width = _window->width(); - const auto height = _window->height(); - - _extent2D.width = width; - _extent2D.height = height; - - buildSwapchain(); -} - -const char* ProxyWindow::instanceExtensionSurfaceName() const -{ -#if defined(VK_USE_PLATFORM_WIN32_KHR) - return VK_KHR_WIN32_SURFACE_EXTENSION_NAME; -#elif defined(VK_USE_PLATFORM_XLIB_KHR) - return VK_KHR_XLIB_SURFACE_EXTENSION_NAME; -#elif defined(VK_USE_PLATFORM_XCB_KHR) - return VK_KHR_XCB_SURFACE_EXTENSION_NAME; -#elif defined(VK_USE_PLATFORM_MACOS_MVK) - return VK_MVK_MACOS_SURFACE_EXTENSION_NAME; -#endif -} - -void ProxyWindow::_initSurface() -{ - _surface = ProxySurface::create(QVulkanInstance::surfaceForWindow(_window), - _instance); -} - -ProxyWindow::~ProxyWindow() -{ - clear(); -} diff --git a/src/vsgQt/ViewerWindow.cpp b/src/vsgQt/ViewerWindow.cpp index fdabaa7..ed4df79 100644 --- a/src/vsgQt/ViewerWindow.cpp +++ b/src/vsgQt/ViewerWindow.cpp @@ -50,15 +50,20 @@ ViewerWindow::ViewerWindow() : ViewerWindow::~ViewerWindow() { - std::cout << "ViewerWindow::~ViewerWindow() destructor" << std::endl; + cleanup(); + delete vulkanInstance; } void ViewerWindow::cleanup() { // remove links to all the VSG related classes. - proxySurface = {}; - proxyWindow = {}; + if (windowAdapter) + { + windowAdapter->getSurface()->release(); + } + + windowAdapter = {}; viewer = {}; } @@ -123,15 +128,13 @@ bool ViewerWindow::event(QEvent* e) return QWindow::event(e); } + void ViewerWindow::exposeEvent(QExposeEvent* e) { - std::cout << "vulkanWindow.isExposed() = " << isExposed() << std::endl; if (!_initialized && isExposed()) { _initialized = true; - std::cout << " initializaing ViewerWindow" << std::endl; - const auto rect = e->region().boundingRect(); const uint32_t width = static_cast(rect.width()); const uint32_t height = static_cast(rect.height()); @@ -140,9 +143,6 @@ void ViewerWindow::exposeEvent(QExposeEvent* e) traits->height = height; traits->fullscreen = false; - std::cout << " width = " << width << ", height = " << height - << std::endl; - // create instance vsg::Names instanceExtensions; vsg::Names requestedLayers; @@ -172,21 +172,49 @@ void ViewerWindow::exposeEvent(QExposeEvent* e) // set up the window for Vulkan usage setVulkanInstance(vulkanInstance); - proxyWindow = ProxyWindow::create(this, traits); + auto surface = vsg::Surface::create(QVulkanInstance::surfaceForWindow(this), instance); + windowAdapter = new vsg::WindowAdapter(surface, traits); vsg::clock::time_point event_time = vsg::clock::now(); - proxyWindow->bufferedEvents.emplace_back(new vsg::ExposeWindowEvent(proxyWindow, event_time, rect.x(), rect.y(), width, height)); + windowAdapter->bufferedEvents.emplace_back(new vsg::ExposeWindowEvent(windowAdapter, event_time, rect.x(), rect.y(), width, height)); if (initializeCallback) initializeCallback(*this); requestUpdate(); } } + + if (windowAdapter) + { + windowAdapter->windowValid = true; + windowAdapter->windowVisible = isExposed(); + } +} + +void ViewerWindow::hideEvent(QHideEvent* /*e*/) +{ + if (windowAdapter) + { + windowAdapter->windowVisible = false; + } +} + +void ViewerWindow::resizeEvent(QResizeEvent* e) +{ + if (!windowAdapter) return; + + // std::cout << __func__ << std::endl; + + // WindowAdapter + windowAdapter->updateExtents(e->size().width(), e->size().height()); + + vsg::clock::time_point event_time = vsg::clock::now(); + windowAdapter->bufferedEvents.emplace_back(new vsg::ConfigureWindowEvent(windowAdapter, event_time, x(), y(), static_cast(e->size().width()), static_cast(e->size().height()))); } void ViewerWindow::keyPressEvent(QKeyEvent* e) { - if (!proxyWindow) return; + if (!windowAdapter) return; std::cout << __func__ << std::endl; @@ -196,13 +224,13 @@ void ViewerWindow::keyPressEvent(QKeyEvent* e) if (keyboardMap->getKeySymbol(e, keySymbol, modifiedKeySymbol, keyModifier)) { vsg::clock::time_point event_time = vsg::clock::now(); - proxyWindow->bufferedEvents.emplace_back(new vsg::KeyPressEvent(proxyWindow, event_time, keySymbol, modifiedKeySymbol, keyModifier)); + windowAdapter->bufferedEvents.emplace_back(new vsg::KeyPressEvent(windowAdapter, event_time, keySymbol, modifiedKeySymbol, keyModifier)); } } void ViewerWindow::keyReleaseEvent(QKeyEvent* e) { - if (!proxyWindow) return; + if (!windowAdapter) return; std::cout << __func__ << std::endl; @@ -212,13 +240,13 @@ void ViewerWindow::keyReleaseEvent(QKeyEvent* e) if (keyboardMap->getKeySymbol(e, keySymbol, modifiedKeySymbol, keyModifier)) { vsg::clock::time_point event_time = vsg::clock::now(); - proxyWindow->bufferedEvents.emplace_back(new vsg::KeyReleaseEvent(proxyWindow, event_time, keySymbol, modifiedKeySymbol, keyModifier)); + windowAdapter->bufferedEvents.emplace_back(new vsg::KeyReleaseEvent(windowAdapter, event_time, keySymbol, modifiedKeySymbol, keyModifier)); } } void ViewerWindow::mouseMoveEvent(QMouseEvent* e) { - if (!proxyWindow) return; + if (!windowAdapter) return; // std::cout << __func__ << std::endl; @@ -234,12 +262,12 @@ void ViewerWindow::mouseMoveEvent(QMouseEvent* e) default: button = 0; break; } - proxyWindow->bufferedEvents.emplace_back(new vsg::MoveEvent(proxyWindow, event_time, e->x(), e->y(), (vsg::ButtonMask)button)); + windowAdapter->bufferedEvents.emplace_back(new vsg::MoveEvent(windowAdapter, event_time, e->x(), e->y(), (vsg::ButtonMask)button)); } void ViewerWindow::mousePressEvent(QMouseEvent* e) { - if (!proxyWindow) return; + if (!windowAdapter) return; // std::cout << __func__ << std::endl; @@ -255,12 +283,12 @@ void ViewerWindow::mousePressEvent(QMouseEvent* e) default: button = 0; break; } - proxyWindow->bufferedEvents.emplace_back(new vsg::ButtonPressEvent(proxyWindow, event_time, e->x(), e->y(), (vsg::ButtonMask)button, 0)); + windowAdapter->bufferedEvents.emplace_back(new vsg::ButtonPressEvent(windowAdapter, event_time, e->x(), e->y(), (vsg::ButtonMask)button, 0)); } void ViewerWindow::mouseReleaseEvent(QMouseEvent* e) { - if (!proxyWindow) return; + if (!windowAdapter) return; // std::cout << __func__ << std::endl; @@ -276,35 +304,25 @@ void ViewerWindow::mouseReleaseEvent(QMouseEvent* e) default: button = 0; break; } - proxyWindow->bufferedEvents.emplace_back(new vsg::ButtonReleaseEvent(proxyWindow, event_time, e->x(), e->y(), (vsg::ButtonMask)button, 0)); -} - -void ViewerWindow::resizeEvent(QResizeEvent* e) -{ - if (!proxyWindow) return; - - // std::cout << __func__ << std::endl; - - vsg::clock::time_point event_time = vsg::clock::now(); - proxyWindow->bufferedEvents.emplace_back(new vsg::ConfigureWindowEvent(proxyWindow, event_time, x(), y(), static_cast(e->size().width()), static_cast(e->size().height()))); + windowAdapter->bufferedEvents.emplace_back(new vsg::ButtonReleaseEvent(windowAdapter, event_time, e->x(), e->y(), (vsg::ButtonMask)button, 0)); } void ViewerWindow::moveEvent(QMoveEvent* e) { - if (!proxyWindow) return; + if (!windowAdapter) return; // std::cout << __func__ << std::endl; vsg::clock::time_point event_time = vsg::clock::now(); - proxyWindow->bufferedEvents.emplace_back(new vsg::ConfigureWindowEvent(proxyWindow, event_time, e->pos().x(), e->pos().y(), static_cast(size().width()), static_cast(size().height()))); + windowAdapter->bufferedEvents.emplace_back(new vsg::ConfigureWindowEvent(windowAdapter, event_time, e->pos().x(), e->pos().y(), static_cast(size().width()), static_cast(size().height()))); } void ViewerWindow::wheelEvent(QWheelEvent* e) { - if (!proxyWindow) return; + if (!windowAdapter) return; // std::cout << __func__ << std::endl; vsg::clock::time_point event_time = vsg::clock::now(); - proxyWindow->bufferedEvents.emplace_back(new vsg::ScrollWheelEvent(proxyWindow, event_time, e->angleDelta().y() < 0 ? vsg::vec3(0.0f, -1.0f, 0.0f) : vsg::vec3(0.0f, 1.0f, 0.0f))); + windowAdapter->bufferedEvents.emplace_back(new vsg::ScrollWheelEvent(windowAdapter, event_time, e->angleDelta().y() < 0 ? vsg::vec3(0.0f, -1.0f, 0.0f) : vsg::vec3(0.0f, 1.0f, 0.0f))); }