[vtkusers] vtkPlotPoints marker in QVTKOpenGLWidget on Windows

Karsten Tausche karsten.tausche at student.hpi.uni-potsdam.de
Wed Nov 22 10:45:08 EST 2017


Hi all,

I'm having trouble with the MarkerStyle property of vtkPlotPoints when
using the QVTKOpenGLWidget for OpenGL context creation on Windows. See
the attached code for a minimum example. When cross or square is
selected, squares are drawn. For all other marker styles, no markers at
all are drawn. After some debugging, it seems that the correct marker
textures are generated and selected, but apparently they don't reach the
GPU buffer/texture data. Maybe some GPU buffers of the chart/context
components are not correctly (re-)initialized in the OpenGL context of
Qt widget.

The example code works fine when using the vtkRenderWindow for context
creation (undefine USE_QVTK in line 18). On Linux both implementations
work fine. On Windows (8.1) I tested the code on an Intel HD Graphics
5500 and GeForce 940M, with Qt 5.9 and VTK v8.1.0.rc1.

Note that the QSurfaceFormat hacks around line 52 don't change anything
on modern hardware. Also, changing the vtkPlotLine to vtkPlotPoints has
no effect on the markers, it's just convenient to see the line for
reference.

Did I miss anything for passing the QVTKOpenGLWidget's render window to
the vtkContextView? It's not that obvious in which order the widget,
context view and chart should be created and assigned to each other.
With some alternative initialization orders it just crashes at runtime.

Thanks a lot for your help!

Karsten

-------------- next part --------------
#include <iostream>
#include <QApplication>
#include <QVTKOpenGLWidget.h>
#include <vtkCallbackCommand.h>
#include <vtkChartXY.h>
#include <vtkContextScene.h>
#include <vtkContextView.h>
#include <vtkFloatArray.h>
#include <vtkGenericOpenGLRenderWindow.h>
#include <vtkNew.h>
#include <vtkPlotLine.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkSmartPointer.h>
#include <vtkTable.h>


#define USE_QVTK


int main(int argc, char ** argv)
{
    vtkNew<vtkFloatArray> x;
    x->SetName("x");
    x->SetNumberOfTuples(10);
    for (vtkIdType i = 0; i < x->GetNumberOfTuples(); ++i) {
        x->SetValue(i, float(i));
    }
    vtkNew<vtkFloatArray> y;
    y->DeepCopy(x);
    y->SetName("y");
    vtkNew<vtkTable> table;
    table->AddColumn(x);
    table->AddColumn(y);

    auto plot = vtkSmartPointer<vtkPlotLine>::New();
    plot->SetInputData(table, 0, 1);
    //plot->SetMarkerStyle(vtkPlotPoints::NONE);    // -> None
    //plot->SetMarkerStyle(vtkPlotPoints::CROSS);   // -> Square
    //plot->SetMarkerStyle(vtkPlotPoints::PLUS);    // -> None
    //plot->SetMarkerStyle(vtkPlotPoints::SQUARE);  // -> Square
    //plot->SetMarkerStyle(vtkPlotPoints::CIRCLE);  // -> None
      plot->SetMarkerStyle(vtkPlotPoints::DIAMOND);   // -> None
    plot->SetMarkerSize(20.f);

    vtkNew<vtkContextView> view;

#ifdef USE_QVTK
    auto format = QVTKOpenGLWidget::defaultFormat();
    format.setSamples(0);
    // This is required for Intel HD 3000 (and similar?) broken Windows drivers.
    format.setProfile(QSurfaceFormat::CompatibilityProfile);
    format.setOption(QSurfaceFormat::DeprecatedFunctions, true);
    QSurfaceFormat::setDefaultFormat(format);

    QApplication app(argc, argv);

    QVTKOpenGLWidget widget;
    vtkNew<vtkGenericOpenGLRenderWindow> renWin;
    widget.SetRenderWindow(renWin);
    view->SetRenderWindow(renWin);
#endif

    vtkNew<vtkChartXY> chart;
    view->GetScene()->AddItem(chart);
    chart->AddPlot(plot);

    class Callback : public vtkCallbackCommand
    {
    public:
        static Callback* New() { return new Callback; }
        void Execute(vtkObject * obj, unsigned long evId, void*ptr) override
        {
            auto iren = vtkRenderWindowInteractor::SafeDownCast(obj);
            if (!iren) {
                return;
            }
            const int diff = iren->GetKeyCode() == 'a' ? 1 : -1;
            const int newMarker = (plot->GetMarkerStyle() + diff + vtkPlotPoints::DIAMOND + 1) % (vtkPlotPoints::DIAMOND + 1);
            switch (newMarker)
            {
                case vtkPlotPoints::NONE: std::cout << "NONE" << std::endl; break;
                case vtkPlotPoints::CROSS: std::cout << "CROSS" << std::endl; break;
                case vtkPlotPoints::PLUS: std::cout << "PLUS" << std::endl; break;
                case vtkPlotPoints::SQUARE: std::cout << "SQUARE" << std::endl; break;
                case vtkPlotPoints::CIRCLE: std::cout << "CIRCLE" << std::endl; break;
                case vtkPlotPoints::DIAMOND: std::cout << "DIAMOND" << std::endl; break;
                default: std::cout << "(invalid)" << std::endl; break;
            }
            plot->SetMarkerStyle(newMarker);
            iren->Render();
        }
        Callback() {}
        vtkSmartPointer<vtkPlotPoints> plot;
    };
    vtkNew<Callback> callback;
    callback->plot = plot;
    view->GetInteractor()->AddObserver(vtkCommand::KeyReleaseEvent, callback);

#ifdef USE_QVTK
    widget.show();
    return app.exec();
#else
    view->GetInteractor()->Start();
    return 0;
#endif
}
-------------- next part --------------
cmake_minimum_required(VERSION 3.3.0 FATAL_ERROR)

project(QtPlotMarkerTest)


find_package(VTK REQUIRED COMPONENTS
    vtkRenderingContextOpenGL2
    vtkChartsCore
    vtkViewsContext2D
    vtkGUISupportQt
)
include(${VTK_USE_FILE})

add_executable(QtPlotMarkerTest QtPlotMarkerTest.cxx)
target_link_libraries(QtPlotMarkerTest ${VTK_LIBRARIES})


More information about the vtkusers mailing list