使用vtk8.1的QVTKOpenGLWidget在用来在Qt的QWidget中显示vtkGenericOpenGLRenderWindow加载的体绘制如果使用QSurfaceFormat开启多重采样会导致体绘制消失。vtk9.0使用QVTKOpenGLNativeWidget 修复了部分问题但是如果采样数设置为4体绘制还是会消失。
测试项目文件目录:
CMakeLists.txt
main.cpp
mainwindow.cpp
mainwindow.h
mainwindow.ui
cmake配置如下:
vtk8.1是使用的源码编译后的build配置的,vtk9.0是使用动态链接库的形式调用的
cmake_minimum_required(VERSION 3.0)
project(TESTVTK)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(CMAKE_AUTOUIC ON)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
file(GLOB Demo_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp)
file(GLOB Demo_HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/*.h)
file(GLOB Demo_FORMS ${CMAKE_CURRENT_SOURCE_DIR}/*.ui)
#file(GLOB VTK_LIBRARIES "D:/vtk9/vtk9.0.2install/lib/vtk*.lib")
find_package(VTK REQUIRED)
include(${VTK_USE_FILE})
#include_directories(${VTK_USE_FILE})
#file(GLOB VTK_DLL "D:/vtk9/vtk9.0.2install/bin/vtk*.dll")
find_package(Qt5 COMPONENTS Widgets REQUIRED)
#调用预编译器moc,需要使用 QT5_WRAP_CPP宏
QT5_WRAP_CPP(Demo_HEADERS_MOC ${Demo_HEADERS})
#使用uic处理.ui文件
QT5_WRAP_UI(Demo_FORMS_HEADERS ${Demo_FORMS})
include_directories(${CMAKE_CURRENT_BINARY_DIR})
#include_directories("D:/vtk9/vtk9.0.2install/include/vtk-9.0")
add_executable(TESTVTK
${Demo_SOURCES}
${Demo_HEADERS_MOC}
${Demo_FORMS_HEADERS}
#${Demo_RESOURCES_RCC}
)
target_link_libraries(TESTVTK
${Qt5Widgets_LIBRARIES}
${VTK_LIBRARIES}
)
main.cpp代码如下:
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
mainwindow.cpp代码如下:
#include <vtkAutoInit.h>
VTK_MODULE_INIT(vtkRenderingOpenGL2);
VTK_MODULE_INIT(vtkInteractionStyle);
VTK_MODULE_INIT(vtkRenderingFreeType);
VTK_MODULE_INIT(vtkRenderingVolumeOpenGL2);
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QVTKOpenGLWidget.h>
#include <QSurfaceFormat>
#include <vtkSphereSource.h>
#include <vtkPolyDataMapper.h>
#include <vtkActor.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkGenericOpenGLRenderWindow.h>
#include <vtkNamedColors.h>
#include <vtkProperty.h>
#include <vtkSmartPointer.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkNIFTIImageReader.h>
#include <vtkGPUVolumeRayCastMapper.h>
#include <vtkVolumeProperty.h>
#include <vtkPiecewiseFunction.h>
#include <vtkColorTransferFunction.h>
#include <vtkRayCastImageDisplayHelper.h>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
QSurfaceFormat surfaceFormat = QSurfaceFormat::defaultFormat();
surfaceFormat.setSamples(8);
ui->widget->setFormat(surfaceFormat);
vtkSmartPointer<vtkNIFTIImageReader> reader = vtkSmartPointer<vtkNIFTIImageReader>::New();
reader->SetFileName("ct.nii.gz");
reader->Update();
vtkSmartPointer<vtkGPUVolumeRayCastMapper> volumeMapper =
vtkSmartPointer<vtkGPUVolumeRayCastMapper>::New();
volumeMapper->SetInputData(reader->GetOutput());
vtkSmartPointer<vtkVolumeProperty> volumeProperty =
vtkSmartPointer<vtkVolumeProperty>::New();
volumeProperty->SetInterpolationTypeToLinear();
volumeProperty->ShadeOn(); //打开或者关闭阴影测试
volumeProperty->SetAmbient(0.4);
volumeProperty->SetDiffuse(0.6); //漫反射
volumeProperty->SetSpecular(0.2); //镜面反射
//设置不透明度
vtkSmartPointer<vtkPiecewiseFunction> compositeOpacity =
vtkSmartPointer<vtkPiecewiseFunction>::New();
compositeOpacity->AddPoint(70, 0.00);
compositeOpacity->AddPoint(90, 0.40);
compositeOpacity->AddPoint(180, 0.60);
volumeProperty->SetScalarOpacity(compositeOpacity); //设置不透明度传输函数
//设置梯度不透明属性
vtkSmartPointer<vtkPiecewiseFunction> volumeGradientOpacity =
vtkSmartPointer<vtkPiecewiseFunction>::New();
volumeGradientOpacity->AddPoint(10, 0.0);
volumeGradientOpacity->AddPoint(90, 0.5);
volumeGradientOpacity->AddPoint(100, 1.0);
volumeProperty->SetGradientOpacity(volumeGradientOpacity);//设置梯度不透明度效果对比
//设置颜色属性
vtkSmartPointer<vtkColorTransferFunction> color =
vtkSmartPointer<vtkColorTransferFunction>::New();
color->AddRGBPoint(0.000, 0.00, 0.00, 0.00);
color->AddRGBPoint(64.00, 1.00, 0.52, 0.30);
color->AddRGBPoint(190.0, 1.00, 1.00, 1.00);
color->AddRGBPoint(220.0, 0.20, 0.20, 0.20);
volumeProperty->SetColor(color);
vtkSmartPointer<vtkVolume> volume =
vtkSmartPointer<vtkVolume>::New();
volume->SetMapper(volumeMapper);
volume->SetProperty(volumeProperty);
vtkSmartPointer<vtkRenderer> ren = vtkSmartPointer<vtkRenderer>::New();
ren->SetBackground(0, 1, 0);
ren->AddVolume(volume);
vtkSmartPointer<vtkGenericOpenGLRenderWindow> rw = vtkSmartPointer<vtkGenericOpenGLRenderWindow>::New();
rw->AddRenderer(ren);
rw->SetSize(1000, 1000);
rw->SetWindowName("VolumeRendering");
setCentralWidget(ui->widget);
ui->widget->SetRenderWindow(rw);;
}
MainWindow::~MainWindow()
{
delete ui;
}
mainwindow.h代码如下:
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = nullptr);
~MainWindow();
protected:
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
mainwindow.ui
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>300</height>
</rect>
</property>
<property name="windowTitle">
<string>MainWindow</string>
</property>
<widget class="QWidget" name="centralWidget">
<widget class="QVTKOpenGLWidget" name="widget" native="true">
<property name="geometry">
<rect>
<x>30</x>
<y>30</y>
<width>341</width>
<height>241</height>
</rect>
</property>
</widget>
</widget>
</widget>
<layoutdefault spacing="6" margin="11"/>
<customwidgets>
<customwidget>
<class>QVTKOpenGLWidget</class>
<extends>QWidget</extends>
<header>QVTKOpenGLWidget.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<resources/>
<connections/>
</ui>
运行结果如下:
QSurfaceFormat::setDefaultFormat(QVTKOpenGLWidget::defaultFormat());
执行上面这行代码会导致下面的情况。
看了vtk8.1的源码并没有定位到问题的位置,vtk8.2这个问题也没有修复,vtk9.0多重采样设置为8可以显示,但是设置成4也显示不出来。记录此问题待以后解决。