Hi there. I’m attempting to build a client server application where a user can request high resolution renders of a data cube from various camera positions. The request contain information about the camera such as Position and ViewUp. When I attempt to update the camera position, render and then capture the resulting frame, I get a long list of the same error repeated over again:
Warning: In /home/jonathan/VTK-8.2.0/Rendering/OpenGL2/vtkEGLRenderWindow.cxx, line 588
vtkEGLRenderWindow (0x7f81fc031500): Unable to eglMakeCurrent: 12290
If I attempt another request, it usually works. From what I’ve seen, it seems to alternate between producing an error and producing the correct output with each turn.
Here is the code I’m using to setup my vtk objects:
DataCube dataCube;
vtkSmartPointer<vtkFloatArray> floatArray;
vtkSmartPointer<vtkImageImport> imageImport;
vtkSmartPointer<vtkSmartVolumeMapper> volumeMapper;
vtkSmartPointer<vtkNamedColors> colors;
vtkSmartPointer<vtkRenderer> ren1;
vtkSmartPointer<vtkEGLRenderWindow> renWin;
vtkSmartPointer<vtkPiecewiseFunction> opacityTransferFunction;
vtkSmartPointer<vtkColorTransferFunction> colorTransferFunction;
vtkSmartPointer<vtkVolumeProperty> volumeProperty;
vtkSmartPointer<vtkVolume> volume;
vtkSmartPointer<vtkRenderWindowInteractor> iren;
vtkSmartPointer<vtkImageData> imageData;
void createEGLRenderOnServer(){
cout << "Creating EGL render on server." << endl;
floatArray = vtkSmartPointer<vtkFloatArray>::New();
floatArray->SetName("Float Array");
floatArray->SetArray(dataCube.floatArray, dataCube.num_pixels, 1);
// Create vtkImageImport object in order to use an array as input data to the volume mapper.
imageImport = vtkSmartPointer<vtkImageImport>::New();
imageImport->SetDataScalarTypeToFloat();
imageImport->SetWholeExtent(0, dataCube.dimx - 1, 0, dataCube.dimy - 1, 0, dataCube.dimz - 1);
imageImport->SetDataExtentToWholeExtent();
imageImport->SetImportVoidPointer(floatArray->GetVoidPointer(0));
imageImport->SetNumberOfScalarComponents(1);
imageImport->SetDataSpacing(1.0, (double)(dataCube.dimx) / dataCube.dimy, (double)(dataCube.dimx) / dataCube.dimz);
imageImport->Update();
// The mapper / ray cast function know how to render the data
volumeMapper = vtkSmartPointer<vtkSmartVolumeMapper>::New();
volumeMapper->SetBlendModeToComposite(); // composite first
volumeMapper->SetInputConnection(imageImport->GetOutputPort());
volumeMapper->CroppingOn();
// Create the standard renderer, render window
// and interactor
colors = vtkSmartPointer<vtkNamedColors>::New();
ren1 = vtkSmartPointer<vtkRenderer>::New();
renWin = vtkSmartPointer<vtkEGLRenderWindow>::New();
renWin->Initialize();
renWin->AddRenderer(ren1);
// Create transfer mapping scalar value to opacity
// Data values for ds9.arr 540x450x201 are in range [-0.139794;0.153026]
opacityTransferFunction = vtkSmartPointer<vtkPiecewiseFunction>::New();
opacityTransferFunction->AddPoint(-0.0, 0.0);
opacityTransferFunction->AddPoint(0.16, 1.0);
// Create transfer mapping scalar value to color
colorTransferFunction = vtkSmartPointer<vtkColorTransferFunction>::New();
colorTransferFunction->AddRGBPoint(-0.0, 0.0, 0.0, 0.0);
colorTransferFunction->AddRGBPoint(0.16, 1.0, 1.0, 1.0);
// The property describes how the data will look
volumeProperty = vtkSmartPointer<vtkVolumeProperty>::New();
volumeProperty->SetColor(colorTransferFunction);
volumeProperty->SetScalarOpacity(opacityTransferFunction);
volumeProperty->SetInterpolationTypeToNearest();
// The volume holds the mapper and the property and
// can be used to position/orient the volume
volume = vtkSmartPointer<vtkVolume>::New();
volume->SetMapper(volumeMapper);
volume->SetProperty(volumeProperty);
ren1->AddVolume(volume);
ren1->SetBackground(colors->GetColor3d("Wheat").GetData());
ren1->GetActiveCamera()->Azimuth(45);
ren1->GetActiveCamera()->Elevation(30);
ren1->ResetCameraClippingRange();
ren1->ResetCamera();
//renWin->SwapBuffersOff();
renWin->SetSize(600, 600);
renWin->Render();
renWin->Frame();
renWin->WaitForCompletion();
captureScreenShotOfCurrentEGLRender();
double * position = ren1->GetActiveCamera()->GetFocalPoint();
cout << position[0] << ' ' << position[1] << ' ' << position[2] << endl;
cout << "Finished setting up EGL render on server." << endl;
return;
}
And then changing the camera and capturing the data:
// Set variables.
ren1->ResetCamera();
ren1->GetActiveCamera()->SetPosition(position.Get(0),position.Get(1),position.Get(2));
ren1->GetActiveCamera()->SetViewUp(view_up.Get(0),view_up.Get(1),view_up.Get(2));
renWin->Render();
renWin->Frame();
renWin->WaitForCompletion();
By now the error has already shown up, but when it doesn’t I’m able to retrieve the (correct) data through the following:
vtkSmartPointer<vtkWindowToImageFilter> windowToImageFilter =
vtkSmartPointer<vtkWindowToImageFilter>::New();
windowToImageFilter->SetInput(renWin);
windowToImageFilter->SetInputBufferTypeToRGBA(); //also record the alpha (transparency) channel
windowToImageFilter->ReadFrontBufferOff(); // read from the back buffer
windowToImageFilter->Update();
imageData = windowToImageFilter->GetOutput();
I was told on the vtk gitlab issues webpage that “It looks like a misuse” but am unsure how I am misusing it. If anyone can help, it would be much appreciated.