Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

vsgQt build fails an macOS #28

Open
rainergericke opened this issue Jun 30, 2023 · 18 comments
Open

vsgQt build fails an macOS #28

rainergericke opened this issue Jun 30, 2023 · 18 comments

Comments

@rainergericke
Copy link
Contributor

An old error is back on the Mac:
Bildschirmfoto 2023-06-30 um 08 57 09

NSView* cannot be casted to a c++ class pointer, since it is an OBJC class pointer. This problem returned with commit:c64cf39805f6011e836125979456fd0f5b02299d

Source file: ViewerWindow.cpp line 238

@robertosfield
Copy link
Collaborator

Unfortunately I don't have a macOS system or expertise to help resolve this, to get vsgQt working on macOS we'll tackle this as I have had to abandon Qt's won Vulkan support as I design choices Trollteh have adopted road-blocked proper multi-window support.

I have written up details of the new work on the VSG forum

I presume there must be a way of passing window pointers around on macOS but need those with macOS systems and expertise to step up and figure out how we can resolve the issue.

@rainergericke
Copy link
Contributor Author

Seems since Qt 6.5.2 the build under macOS is possible, after line 155 in file Window.cpp has been changed to
traits->nativeWindow = winId();
That was the good news. The bad news is the tools don't work as needed.
Starting vsgqtviewer leads to the message:
vsgqtviewer teapot.vsgt
Failed to load a valid scenene graph, Please specify a 3d model or image file on the command line.
Seems VSG_FILE_PATH is not evaluated.
Next trial:
vsgqtviewer $VSG_FILE_PATH/models/teapot.vsgt
shows this:

vsgqtviewer1

Bringing the white window to the front shows this:
vsgqtviewer2

The 3d object can be turned, scaled and moved by mouse action, but the program does not react to window close events and must be closed by ^C from the terminal.

vsgqtwindows $VSG_FILE_PATH/models/teapot.vsgt

shows this:
vsgqtwindows

Sorry, I am not able to present a complete solution, but I hope this is helpful for others.

@robertosfield
Copy link
Collaborator

That's good news that at least part of the problem is resolvable. Could you get a PR for the change you've made so far.

vsgqtviewer teapot.vsgt
Failed to load a valid scenene graph, Please specify a 3d model or image file on the command line.
Seems VSG_FILE_PATH is not evaluated.

If you have set VSG_FILE_PATH to vsgExamples/data then to load the teapot.vsgt you'll need to use:

vsgqtviewer models/teapot.vsgt

From the screenshots it looks like there are several issues outstanding, first up the viewport state doesn't look to be syncing up to the dimensions of the window. The close button should be the Qt window related so I'm surprised it's not working, perhaps the vsg::MacOS_Window.mm is affect how events are handled?

Does pressing escape work?

@rainergericke
Copy link
Contributor Author

Right!

vsgqtviewer models/teapot.vsgt

works. So reading the environment variables is not an issue, fortunately.

The escape key is not recognized.

@robertosfield
Copy link
Collaborator

Thanks for the PR, now merged.

Th escape key and close button not working, but the camera manipulator working is an odd combination of non working/working events. Unfortunately I don't have a Mac so can't provide any direct assistance on figuring out what is amiss.

@rainergericke
Copy link
Contributor Author

Is the additional empty window an intended feature?

@rainergericke
Copy link
Contributor Author

I just found out: the white window reacts on window close. Then the app terminates. The 3d window only reacts on window resize and move, not on window close.

@robertosfield
Copy link
Collaborator

Is the additional empty window an intended feature?

I didn't pick up on that there was two separate windows. I think that suggests that the MacOS_Window.mm isn't using the window passed into MacOS_Window.mm via WindowTraits::nativeWindow isn't being used as intended so it's creating it's own window rather than just adding vkSurface/Swapchain etc. to the Window.

Could you have a look at how Win32_Window.cpp, Xcb_Window.cpp and MacOS_Window.mm all respond to WindowTraits::nativeWindow? I suspect more work needs to be done in MacOS_Window.mm to support this usage case.

@rainergericke
Copy link
Contributor Author

My last activities about qt are 10 years ago, so I am not really an expert. I tried to understand the code in vsgqtviewer. In my understanding two windows are created, the mainWindow (QMainWindow) and the window (QWindow+vsg). mainWindow is the white window that hears to window close event. window contains the vsg related part. Should windows act as widget inside mainWindow?

@robertosfield
Copy link
Collaborator

I have only ever flirted with Qt during my career, working on vsgQt is the closest I've got, but even that is a need to know basis to get Vulkan/VSG integration working, rather than fully knowledge of Qt.

It looks to me like QMainWindow is a window with several features that are common to most applications main windows like menu and status bars, whereas QWindow is more bare bones that you'd need to add these features to.

It looks like QMainWindow can have widgets within that can be a QWindow, but these QWindow themselves would be wrapped. I can't claim to understand why it's done like is is.

I don't know if the separate QMainWindow and QWindow is actually an issue in your case, it may be that Qt itself is probably embedding the QWindow within the QMainWindow. The first things I'd investigate is whether MacOS_Window.mm is creating it's own window or whether it's use the one provided by QWindow.

@rainergericke
Copy link
Contributor Author

After reading the Qt6 docu, I finally understand your code, I think it is ok. 'window' is set as a widget in 'mainWindow', good so far. My next idea was to remove the manWindow and only to use 'window' from MacOS_Window.mm, not a solution, just for testing.

changed lines in main.cpp of vsgqtviewer (122 to 137):
//QMainWindow* mainWindow = new QMainWindow();

// create the viewer that will manage all the rendering of the views
auto viewer = vsgQt::Viewer::create();

auto window = createWindow(viewer, windowTraits, vsg_scene, nullptr, "First Window");

//auto widget = QWidget::createWindowContainer(window, mainWindow);

//mainWindow->setCentralWidget(widget);

window->setGeometry(windowTraits->x, windowTraits->y, windowTraits->width, windowTraits->height);

window->show();

The program output is the same as bevor, in fact we get two windows, a QWindow() and a NSWindow()!

Actually I dont have any idea how to solve this problem.

@rainergericke
Copy link
Contributor Author

I have found a possibility to use objc objects directly from c++. It is based on the metal-cpp headers. In the method
_void Window::initializeWindow()_I tried:
#if defined(VK_USE_PLATFORM_WIN32_KHR)
traits->nativeWindow = reinterpret_cast(winId());
#elif defined(VK_USE_PLATFORM_XLIB_KHR)
traits->nativeWindow = static_cast<::Window>(winId());
#elif defined(VK_USE_PLATFORM_XCB_KHR)
traits->nativeWindow = static_cast<xcb_window_t>(winId());
#elif defined(VK_USE_PLATFORM_MACOS_MVK)
traits->nativeWindow = reinterpret_castNS::Window*(winId()); // cast to Cocoa window
traits->nativeWindow = reinterpret_castNS::View*(winId()); // cast to Cocoa view
traits->nativeWindow = reinterpret_castMTK::View*(winId()); // cast to View with Metal layer
traits->nativeWindow = winId()); // no casting
#endif

The effect is always the same, not satisfactory at all.

The Qt6 examples based based on QVulkanWindow work very well on the Mac. Could that be an alternative?

@robertosfield
Copy link
Collaborator

robertosfield commented Aug 9, 2023 via email

@rainergericke
Copy link
Contributor Author

I understand.

What is the statius of VulkanSceneGraph/src/vsg/platform/MacOS_Window.mm?
Does this recieve the was nativeWindow? Does it still attempt to set up its
own Window?

MacOS_Window.mm generates an NSApplication instance, when it shall create just a window. NSApplication is equivalent to QMainWindow. Maybe the reason for this strange behavior.

@robertosfield
Copy link
Collaborator

I have just done quick code review on MacOS_Window.mm and there is no handling of WindowTraits::nativeWindow, so it's clear the the extra Window that is being created on the VSG is happening because MacOS_Window.mm doesn't yet support the usage case when a window is provided by the caller, the relevant code is in:

https://github.com/vsg-dev/VulkanSceneGraph/blob/master/src/vsg/platform/macos/MacOS_Window.mm#L711

Both the Win32_Window.cpp and Xcb_Window.cpp support using an application supplied nativeWindow.

Something similar will be needed in MacOS_Window.mm.

@rainergericke
Copy link
Contributor Author

Ok. Let's see what is possible.

@rainergericke
Copy link
Contributor Author

The Win32 code looks good to be a pattern for the Mac version, there is a line:

  bool createWindow = true;

   if (traits->nativeWindow.has_value())
   {
       auto nativeWindow = std::any_cast<HWND>(traits->nativeWindow); // similar on the Mac
       if (nativeWindow)
       {
           _window = nativeWindow;
           createWindow = false;
       }
   }

This could be on the Mac.

    bool createWindow = true;

    if (traits->nativeWindow.has_value())
    {
       // naive solution
        auto nativeWindow = std::any_cast<NSWindow*>(traits->nativeWindow); // ->runtime error
       // debugger shows an NSView* in traits->nativeWindow, so I tried next:
       //  auto nativeWindow = std::any_cast<NSView*>(traits->nativeWindow); // ->runtime error
        if (nativeWindow)
        {
            _window = nativeWindow;
            createWindow = false;
        }
    }

This is one mystery to solve. If this ever will work, the next problem is the way, how e.g. resize events are handled. On Win32 events are sent to the window, on the Mac they are sent to the NSApplication. In an external window we don't know the NSApplication!

I want to stop here and hope to find somebody with sufficient knowledge in Mac programming.

@robertosfield
Copy link
Collaborator

robertosfield commented Aug 9, 2023 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants