-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add initial QtQuick implementation by sharing a surface
- Loading branch information
1 parent
d5744e3
commit 1d3af3b
Showing
10 changed files
with
513 additions
and
12 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,4 @@ | ||
add_subdirectory(vsgqtmultiviewer) | ||
add_subdirectory(vsgqtviewer) | ||
add_subdirectory(vsgqtwidgets) | ||
add_subdirectory(vsgqtwindows) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
set(SOURCES | ||
main.cpp | ||
) | ||
|
||
set(HEADERS | ||
) | ||
|
||
add_executable(vsgqtwidgets ${MODE} ${SOURCES} ${HEADERS} ${FORMS}) | ||
|
||
target_link_libraries(vsgqtwidgets vsgQt6) | ||
|
||
if (vsgXchange_FOUND) | ||
target_compile_definitions(vsgqtwidgets PRIVATE vsgXchange_FOUND) | ||
target_link_libraries(vsgqtwidgets vsgXchange::vsgXchange) | ||
endif() | ||
|
||
|
||
install(TARGETS vsgqtwidgets DESTINATION bin) | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,142 @@ | ||
#include <vsg/all.h> | ||
|
||
#ifdef vsgXchange_FOUND | ||
# include <vsgXchange/all.h> | ||
#endif | ||
|
||
#include <QtWidgets/QApplication> | ||
#include <QtWidgets/QMainWindow> | ||
|
||
#include <vsgQt6/Widget.h> | ||
|
||
#include <iostream> | ||
|
||
vsgQt6::Widget* createWidget(vsg::ref_ptr<vsgQt6::Viewer> viewer, vsg::ref_ptr<vsg::WindowTraits> traits, vsg::ref_ptr<vsg::Node> vsg_scene, QWidget* parent, const QString& title = {}) | ||
{ | ||
auto widget = new vsgQt6::Widget(viewer, parent); | ||
|
||
widget->initialize(); | ||
|
||
// if this is the first window to be created, use its device for future window creation. | ||
if (!traits->device) traits->device = widget->windowAdapter->getOrCreateDevice(); | ||
|
||
// compute the bounds of the scene graph to help position camera | ||
vsg::ComputeBounds computeBounds; | ||
vsg_scene->accept(computeBounds); | ||
vsg::dvec3 centre = (computeBounds.bounds.min + computeBounds.bounds.max) * 0.5; | ||
double radius = vsg::length(computeBounds.bounds.max - computeBounds.bounds.min) * 0.6; | ||
double nearFarRatio = 0.001; | ||
|
||
uint32_t width = widget->width(); | ||
uint32_t height = widget->height(); | ||
|
||
vsg::ref_ptr<vsg::EllipsoidModel> ellipsoidModel(vsg_scene->getObject<vsg::EllipsoidModel>("EllipsoidModel")); | ||
vsg::ref_ptr<vsg::Camera> camera; | ||
{ | ||
// set up the camera | ||
auto lookAt = vsg::LookAt::create(centre + vsg::dvec3(0.0, -radius * 3.5, 0.0), centre, vsg::dvec3(0.0, 0.0, 1.0)); | ||
|
||
vsg::ref_ptr<vsg::ProjectionMatrix> perspective; | ||
if (ellipsoidModel) | ||
{ | ||
perspective = vsg::EllipsoidPerspective::create( | ||
lookAt, ellipsoidModel, 30.0, | ||
static_cast<double>(width) / | ||
static_cast<double>(height), | ||
nearFarRatio, false); | ||
} | ||
else | ||
{ | ||
perspective = vsg::Perspective::create( | ||
30.0, | ||
static_cast<double>(width) / | ||
static_cast<double>(height), | ||
nearFarRatio * radius, radius * 4.5); | ||
} | ||
|
||
camera = vsg::Camera::create(perspective, lookAt, vsg::ViewportState::create(VkExtent2D{width, height})); | ||
} | ||
|
||
auto trackball = vsg::Trackball::create(camera, ellipsoidModel); | ||
trackball->addWindow(*widget); | ||
|
||
viewer->addEventHandler(trackball); | ||
|
||
auto commandGraph = vsg::createCommandGraphForView(*widget, camera, vsg_scene); | ||
|
||
viewer->addRecordAndSubmitTaskAndPresentation({commandGraph}); | ||
|
||
return widget; | ||
} | ||
|
||
int main(int argc, char* argv[]) | ||
{ | ||
QApplication application(argc, argv); | ||
|
||
vsg::CommandLine arguments(&argc, argv); | ||
|
||
// set up vsg::Options to pass in filepaths, ReaderWriters and other IO | ||
// related options to use when reading and writing files. | ||
auto options = vsg::Options::create(); | ||
options->fileCache = vsg::getEnv("VSG_FILE_CACHE"); | ||
options->paths = vsg::getEnvPaths("VSG_FILE_PATH"); | ||
#ifdef vsgXchange_FOUND | ||
options->add(vsgXchange::all::create()); | ||
#endif | ||
|
||
arguments.read(options); | ||
|
||
auto windowTraits = vsg::WindowTraits::create(); | ||
windowTraits->windowTitle = "vsgQt6 widgets"; | ||
windowTraits->debugLayer = arguments.read({"--debug", "-d"}); | ||
windowTraits->apiDumpLayer = arguments.read({"--api", "-a"}); | ||
arguments.read("--samples", windowTraits->samples); | ||
arguments.read({"--window", "-w"}, windowTraits->width, windowTraits->height); | ||
if (arguments.read({"--fullscreen", "--fs"})) windowTraits->fullscreen = true; | ||
|
||
bool continuousUpdate = !arguments.read({"--event-driven", "--ed"}); | ||
auto interval = arguments.value<int>(8, "--interval"); | ||
|
||
if (arguments.errors()) | ||
return arguments.writeErrorMessages(std::cerr); | ||
|
||
if (argc <= 1) | ||
{ | ||
std::cout << "Please specify a 3d model or image file on the command line." | ||
<< std::endl; | ||
return 1; | ||
} | ||
|
||
vsg::Path filename = arguments[1]; | ||
|
||
auto vsg_scene = vsg::read_cast<vsg::Node>(filename, options); | ||
if (!vsg_scene) | ||
{ | ||
std::cout << "Failed to load a valid scene graph. Please specify a valid 3d " | ||
"model or image file on the command line." | ||
<< std::endl; | ||
return 1; | ||
} | ||
|
||
|
||
QMainWindow* mainWindow = new QMainWindow(); | ||
|
||
// create the viewer that will manage all the rendering of the views | ||
auto viewer = vsgQt6::Viewer::create(); | ||
|
||
auto widget = createWidget(viewer, windowTraits, vsg_scene, nullptr, "First Widget"); | ||
|
||
mainWindow->setCentralWidget(widget); | ||
|
||
mainWindow->setGeometry(windowTraits->x, windowTraits->y, windowTraits->width, windowTraits->height); | ||
|
||
mainWindow->show(); | ||
|
||
if (interval >= 0) viewer->setInterval(interval); | ||
viewer->continuousUpdate = continuousUpdate; | ||
|
||
viewer->addEventHandler(vsg::CloseHandler::create(viewer)); | ||
viewer->compile(); | ||
|
||
return application.exec(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
#pragma once | ||
|
||
/* <editor-fold desc="MIT License"> | ||
Copyright(c) 2024 Nolan Kramer | ||
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. | ||
</editor-fold> */ | ||
|
||
#include <vsg/all.h> | ||
|
||
#include <vsgQt6/Export.h> | ||
#include <vsgQt6/KeyboardMap.h> | ||
#include <vsgQt6/Viewer.h> | ||
#include <vsgQt6/Window_QQuickWindow.h> | ||
|
||
#include <QQuickWidget> | ||
|
||
namespace vsgQt6 | ||
{ | ||
|
||
// Manages VSG integration with QQuickWidget. Throws when QQuickWindow::graphicsApi() != SGRendererInterface::Vulkan. | ||
// This class works by hooking into QQuickWidget's QQuickWindow offscreen window and grabbing the surface. | ||
// VSG then renders into the surface. | ||
// QQuickWidget::quickWindow() -> QQuickWindow::beforeRendering() -> VSG render -> QQuickWindow::afterRendering() | ||
class VSGQT6_DECLSPEC Widget : public QQuickWidget | ||
{ | ||
Q_OBJECT | ||
public: | ||
Widget(vsg::ref_ptr<Viewer> in_viewer, QWidget* parent = nullptr); | ||
~Widget(); | ||
|
||
vsg::ref_ptr<Viewer> viewer; | ||
vsg::ref_ptr<Window_QQuickWindow> windowAdapter; | ||
|
||
vsg::ref_ptr<vsg::WindowTraits> traits; | ||
vsg::ref_ptr<KeyboardMap> keyboardMap; | ||
|
||
operator vsg::ref_ptr<vsg::Window>() { return windowAdapter; } | ||
|
||
/// Initialize the Vulkan integration using VulkanSceneGraph VkInstance/VkSurface support | ||
virtual void initialize(); | ||
|
||
protected: | ||
void cleanup(); | ||
|
||
bool event(QEvent* e) override; | ||
|
||
void hideEvent(QHideEvent* ev) override; | ||
|
||
void keyPressEvent(QKeyEvent*) override; | ||
void keyReleaseEvent(QKeyEvent*) override; | ||
void mouseMoveEvent(QMouseEvent*) override; | ||
void mousePressEvent(QMouseEvent*) override; | ||
void mouseReleaseEvent(QMouseEvent*) override; | ||
void resizeEvent(QResizeEvent*) override; | ||
void wheelEvent(QWheelEvent*) override; | ||
|
||
/// convert Qt's window coordinate into Vulkan/VSG ones by scaling by the devicePixelRatio() | ||
template<typename T> | ||
int32_t convert_coord(T c) const { return static_cast<int32_t>(std::round(static_cast<qreal>(c) * devicePixelRatio())); } | ||
|
||
std::pair<vsg::ButtonMask, uint32_t> convertMouseButtons(QMouseEvent* e) const; | ||
std::pair<int32_t, int32_t> convertMousePosition(QMouseEvent* e) const; | ||
|
||
private: | ||
bool _initialized = false; | ||
}; | ||
} | ||
|
||
EVSG_type_name(vsgQt6::Widget); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
#pragma once | ||
|
||
/* <editor-fold desc="MIT License"> | ||
Copyright(c) 2024 Nolan Kramer | ||
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. | ||
</editor-fold> */ | ||
|
||
#include <vsgQt6/Export.h> | ||
|
||
#include <vsg/app/Window.h> | ||
|
||
#include <QQuickWindow> | ||
|
||
namespace vsgQt6 | ||
{ | ||
|
||
// Uses QVulkanInstance::surfaceForWindow() to retrieve the surface. | ||
class VSGQT6_DECLSPEC Window_QQuickWindow : public vsg::Inherit<vsg::Window, Window_QQuickWindow> | ||
{ | ||
public: | ||
Window_QQuickWindow(QQuickWindow* quickWindow, vsg::ref_ptr<vsg::WindowTraits> in_traits); | ||
~Window_QQuickWindow(); | ||
|
||
virtual const char* instanceExtensionSurfaceName() const override { return "VK_KHR_QQuickWindow_surface"; } | ||
|
||
QQuickWindow* getQuickWindow() { return _quickWindow; } | ||
|
||
protected: | ||
virtual void _initSurface() override; | ||
|
||
private: | ||
QQuickWindow* _quickWindow; | ||
}; | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.