我目前正在尝试在VTK
中使用QQuickFramebufferObject
的本要点(https://gist.github.com/nocnokneo/c3fb01bb7ecaf437f7d6)中实现构想,但是每当超类{{ 1}}函数被调用。这是围绕该错误的代码:
VtkView.h
OpenGLInitState
VtwView.cpp
#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;
};
请注意,根据要点和代码,实例化此对象的唯一方法是使用:#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
第1帧直接指向我先前指示的行(此处为第9行)。另外,我正在使用* 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
版本8.1.1和VTK
5.11。任何帮助将非常感激。我对使用Qt
很陌生,不知道为什么会这样。
编辑:我更新了上述代码,以在VTK
行之前运行SupportsOpenGL
函数,并且它返回false。为什么会这样呢?我正在使用最新的2018 Macbook Pro,它最多支持OpenGL 4.1。我还将包括文件的其余部分和标题,以获取更多信息。