paceholder / nodeeditor

Qt Node Editor. Dataflow programming framework
BSD 3-Clause "New" or "Revised" License
3.03k stars 813 forks source link

Problems with QOpenGLWidget as embedded widget #375

Closed xenogenesi closed 1 year ago

xenogenesi commented 1 year ago

Thanks for this great library!

I saw that there was an issue related to nodes with OpenGL and 3D but it has been closed without solutions (https://github.com/paceholder/nodeeditor/issues/261).

I'm trying to embed a QOpenGLWidget and I'm having some problems with the refresh, update() doesn't seem to work while I move the mouse (the content should rotate), it only refreshes once after a while, when I trigger other events not directly related in the "view" or leave the MainWindow with the pointer.

I inserted the QOpenGLWidget in a resizable node, sometimes it is drawn black (usually it draws an rgb triangle on a black background), today it doesn't happen but during the tests I had also seen some graphic glitches (like if it blit dirty/random vram in some parts), is OpenGL supposed to work? (see edit2)

I used QOpenGLWidget for convenience but if there are other more compatible 3D visualization solutions I'm open to suggestions (preferably hw accelerated). (QOpenGLWidget seems to work just fine)

Also, is there any way to filter the Wheel event for the embedded widget? I'm failing, I would like to zoom the content in/out with the wheel, but instead the event zooms the scene/view.

Here a gist with the standalone version of the widget I'm using (https://gist.github.com/xenogenesi/0dd16048e8b753e907abfb58b4e5ee04) for testing.

edit: I noticed just now that the mouse move event and update() behave as expected when the scene/view is zoomed in

edit2: The resize problems were due to the aspect ratio computed with integers in gluPerspective() (should also be fixed in the gist).

As for the mouse move events, it's not clear to me where the problem is, it seems to work when the widget has a certain size or the scene/view has a certain zoom factor. Probably something wrong with how I handle events and force refresh?

bool NaiveDataModel::eventFilter(QObject *object, QEvent *event)
{
    if (object == _triangle) {
        if (event->type() == QEvent::MouseButtonPress) {
            QMouseEvent *mouseEvent = static_cast<QMouseEvent*>(event);
            qDebug() << "filter mouse press:" << mouseEvent->position();
            _triangle->mousePressEvent(mouseEvent);
            return true;
        } else if (event->type() == QEvent::MouseMove) {
            QMouseEvent *mouseEvent = static_cast<QMouseEvent*>(event);
            qDebug() << "filter mouse move:" << mouseEvent->position();
            _triangle->mouseMoveEvent(mouseEvent);
            QRect r = _triangle->rect();
            qDebug() << "filter _tirangle rect:" << r;
            MyApplication *app = qobject_cast<MyApplication *>(QCoreApplication::instance());
            if (app) {
                app->view->invalidateScene();
            }
            return true;
        } else if (event->type() == QEvent::Wheel) {
            QWheelEvent *wheelEvent = static_cast<QWheelEvent*>(event);
            qDebug() << "filter mouse wheel delta angle:" << wheelEvent->angleDelta();
            return true;
xenogenesi commented 1 year ago

Clearly it's not a QOpenGLWidget problem that seems to work, instead it's my problem to trace the coordinates in the scene/view of the node and/or the instance of the node to refresh. For the wheel event I think it will be necessary to subclass the view.