vtkGenericOpenGLRenderWindow :: OpenGLInitState seg faults - PullRequest
0 голосов
/ 27 августа 2018

В настоящее время я пытаюсь реализовать идеи в этой сущности (https://gist.github.com/nocnokneo/c3fb01bb7ecaf437f7d6) для использования VTK в QQuickFramebufferObject, но я получаю ошибку seg всякий раз, когда вызывается функция суперкласса OpenGLInitState Вот код, содержащий ошибку:

VtkView.h

#pragma once

#include <QQuickFramebufferObject>
#include "visualizations/BpD/BpD.h"

class vtkGenericOpenGLRenderWindow;
class VtkViewRenderer;

class VtkView : public QQuickFramebufferObject
{
    Q_OBJECT

   public:
    explicit VtkView(QQuickItem * parent = 0);
    VtkView(BpD *, QQuickItem * parent = 0);
    ~VtkView();
    Renderer * createRenderer() const;
    vtkGenericOpenGLRenderWindow * GetRenderWindow() const;

   protected:
    // Called once before the FBO is created for the first time. This method is
    // called from render thread while the GUI thread is blocked.
    virtual void init();

    vtkGenericOpenGLRenderWindow * m_win;

    friend class VtkViewRenderer;
};

VtwView.cpp

#include "visualizations/Vtk/VtkView.h"
// Use the OpenGL API abstraction from Qt instead of from VTK because vtkgl.h
// and other Qt OpenGL-related headers do not play nice when included in the
// same compilation unit
#include <vtkCamera.h>
#include <vtkGenericOpenGLRenderWindow.h>
#include <vtkObjectFactory.h>
#include <vtkRendererCollection.h>
#include <QOpenGLFramebufferObject>
#include <QOpenGLFunctions>
#include <QQuickFramebufferObject>
#include <iostream>

class VtkViewRenderer;

class vtkInternalOpenGLRenderWindow : public vtkGenericOpenGLRenderWindow, protected QOpenGLFunctions
{
   public:
    static vtkInternalOpenGLRenderWindow * New();
    vtkTypeMacro(vtkInternalOpenGLRenderWindow, vtkGenericOpenGLRenderWindow);

    virtual void OpenGLInitState() override
    {
        std::cout << "Supports: " << std::to_string(SupportsOpenGL()) << std::endl;
        std::cout << GetOpenGLSupportMessage() << std::endl << std::flush;
        Superclass::OpenGLInitState();

        // Before any of the gl* functions in QOpenGLFunctions are called for a
        // given OpenGL context, an initialization must be run within that context
        this->MakeCurrent();
        initializeOpenGLFunctions();

        glUseProgram(0);           // Shouldn't
                                   // Superclass::OpenGLInitState()
                                   // handle this?
        glDisable(GL_DEPTH_TEST);  // depth buffer fighting between
                                   // the cone and the backround
                                   // without this
        glDisable(GL_BLEND);       // doesn't seem crucial (?) but it is one of
                                   // the differnces that showed up in apitrace
                                   // analysis
    }

    // Override to use deferred rendering - Tell the QSG that we need
    // to be rendered which will then, at the appropriate time, call
    // InternalRender to do the actual OpenGL rendering.
    virtual void Render() override;

    // Do the actual OpenGL rendering
    void InternalRender() { Superclass::Render(); }

    // Provides a convenient way to set the protected FBO ivars from
    // an existing FBO that was created and owned by Qt's FBO
    // abstraction class QOpenGLFramebufferObject
    void SetFramebufferObject(QOpenGLFramebufferObject * fbo);

    VtkViewRenderer * QtParentRenderer;

   protected:
    vtkInternalOpenGLRenderWindow() : QtParentRenderer(0) {}

    ~vtkInternalOpenGLRenderWindow()
    {
        // Prevent superclass destructors from destroying the
        // framebuffer object.  QOpenGLFramebufferObject owns the FBO
        // and manages it's lifecyle.
        this->OffScreenRendering = 0;
    }
};
vtkStandardNewMacro(vtkInternalOpenGLRenderWindow);

class VtkViewRenderer : public QQuickFramebufferObject::Renderer
{
    friend class vtkInternalOpenGLRenderWindow;

   public:
    VtkViewRenderer(vtkInternalOpenGLRenderWindow * rw) : m_vtkRenderWindow(rw), m_framebufferObject(0)
    {
        m_vtkRenderWindow->Register(NULL);
        m_vtkRenderWindow->QtParentRenderer = this;
    }

    ~VtkViewRenderer()
    {
        m_vtkRenderWindow->QtParentRenderer = 0;
        m_vtkRenderWindow->Delete();
    }

    virtual void synchronize(QQuickFramebufferObject * item)
    {
        // the first synchronize call - right before the the framebufferObject
        // is created for the first time
        if (!m_framebufferObject) {
            VtkView * vtkItem = static_cast<VtkView *>(item);
            vtkItem->init();
        }
    }

    // Called from the render thread when the GUI thread is NOT blocked
    virtual void render()
    {
        m_vtkRenderWindow->PushState();
        m_vtkRenderWindow->OpenGLInitState();
        // m_vtkRenderWindow->OpenGLInit();
        m_vtkRenderWindow->InternalRender();  // vtkXOpenGLRenderWindow
                                              // renders the scene to
                                              // the FBO
        m_vtkRenderWindow->PopState();

        // Dolly camera back and forth - FOR DEMONSTRATION PURPOSES
        // ONLY
        static int callCount = 0;
        ++callCount;
        double dolly = 1.0 + ((callCount % 200) > 100 ? -0.001 : 0.001);
        m_vtkRenderWindow->GetRenderers()->GetFirstRenderer()->GetActiveCamera()->Dolly(dolly);
        this->update();
    }

    QOpenGLFramebufferObject * createFramebufferObject(const QSize & size)
    {
        qDebug("VtkViewRenderer::createFramebufferObject");
        QOpenGLFramebufferObjectFormat format;
        format.setAttachment(QOpenGLFramebufferObject::Depth);
        m_framebufferObject = new QOpenGLFramebufferObject(size, format);

        m_vtkRenderWindow->SetFramebufferObject(m_framebufferObject);

        return m_framebufferObject;
    }

    vtkInternalOpenGLRenderWindow * m_vtkRenderWindow;
    QOpenGLFramebufferObject * m_framebufferObject;
};

//
// vtkInternalOpenGLRenderWindow Definitions
//

void vtkInternalOpenGLRenderWindow::Render()
{
    if (this->QtParentRenderer) {
        this->QtParentRenderer->update();
    }
}

void vtkInternalOpenGLRenderWindow::SetFramebufferObject(QOpenGLFramebufferObject * fbo)
{
    // QOpenGLFramebufferObject documentation states that "The color render
    // buffer or texture will have the specified internal format, and will
    // be bound to the GL_COLOR_ATTACHMENT0 attachment in the framebuffer
    // object"
    this->BackLeftBuffer = this->FrontLeftBuffer = this->BackBuffer = this->FrontBuffer =
        static_cast<unsigned int>(GL_COLOR_ATTACHMENT0);

    // Save GL objects by static casting to standard C types. GL* types
    // are not allowed in VTK header files.
    QSize fboSize = fbo->size();
    this->Size[0] = fboSize.width();
    this->Size[1] = fboSize.height();
    this->NumberOfFrameBuffers = 1;
    this->FrameBufferObject = static_cast<unsigned int>(fbo->handle());
    this->DepthRenderBufferObject = 0;  // static_cast<unsigned int>(depthRenderBufferObject);
    this->TextureObjects[0] = static_cast<unsigned int>(fbo->texture());
    this->OffScreenRendering = 1;
    this->OffScreenUseFrameBuffer = 1;
    this->Modified();
}

//
// VtkView Definitions
//

VtkView::VtkView(QQuickItem * parent) : QQuickFramebufferObject(parent)
{
    m_win = vtkInternalOpenGLRenderWindow::New();
}

VtkView::VtkView(BpD *, QQuickItem * parent) : QQuickFramebufferObject(parent)
{
    m_win = vtkInternalOpenGLRenderWindow::New();
}

VtkView::~VtkView()
{
    m_win->Delete();
}

QQuickFramebufferObject::Renderer * VtkView::createRenderer() const
{
    return new VtkViewRenderer(static_cast<vtkInternalOpenGLRenderWindow *>(m_win));
}

vtkGenericOpenGLRenderWindow * VtkView::GetRenderWindow() const
{
    return m_win;
}

void VtkView::init()
{
    qDebug("VtkView::init");
}

Обратите внимание, что в сущности и в моем коде единственный способ создания экземпляра этого объекта - использовать: vtkInternalOpenGLRenderWindow::New();. Это обратная связь с ошибкой, которую я получаю от lldb:

* thread #20, name = 'QSGRenderThread', stop reason = EXC_BAD_ACCESS (code=1, address=0x0)
  * frame #0: 0x0000000000000000
    frame #1: 0x0000000103500dc8 libvtkRenderingOpenGL2-8.1.1.dylib`vtkOpenGLRenderWindow::OpenGLInitState() + 108
    frame #2: 0x00000001000a57af WormholeDebug`vtkInternalOpenGLRenderWindow::OpenGLInitState(this=0x000000010b07ea00) at VtkView.cpp:27
    frame #3: 0x00000001000a59b1 WormholeDebug`VtkViewRenderer::render(this=0x000000011ef42980) at VtkView.cpp:104
    frame #4: 0x0000000100f8884c QtQuick`___lldb_unnamed_symbol6829$$QtQuick + 124
    frame #5: 0x000000010047919e QtCore`QMetaObject::activate(QObject*, int, int, void**) + 2334
    frame #6: 0x0000000100e53871 QtQuick`QQuickWindowPrivate::renderSceneGraph(QSize const&) + 113
    frame #7: 0x0000000100dfe75b QtQuick`___lldb_unnamed_symbol2476$$QtQuick + 987
    frame #8: 0x0000000100dff0ec QtQuick`___lldb_unnamed_symbol2481$$QtQuick + 396
    frame #9: 0x000000010029065e QtCore`___lldb_unnamed_symbol310$$QtCore + 350
    frame #10: 0x00007fff6035c661 libsystem_pthread.dylib`_pthread_body + 340
    frame #11: 0x00007fff6035c50d libsystem_pthread.dylib`_pthread_start + 377
    frame #12: 0x00007fff6035bbf9 libsystem_pthread.dylib`thread_start + 13

Кадр № 1 указывает непосредственно на линию, которую я ранее указал (строка 9 здесь). Также я использую VTK версии 8.1.1 и Qt 5.11. Любая помощь приветствуется. Я очень новичок в использовании VTK и не могу понять, почему это происходит.

Редактировать: я обновил указанный код для запуска функции SupportsOpenGL прямо перед строкой Superclass::OpenGLInitState(), и она возвращает false. С чего бы это? Я использую последний MacBook Pro 2018 года, который поддерживает до OpenGL 4.1. Я также включу остальную часть файла и заголовок для получения дополнительной информации.

...