vtkEGLRenderWindow (0x7f32d85782d0): Unable to eglMakeCurrent: 12290
I am trying to create a volumetric render using vtkEGLRenderWindow. It appears that on certain occasions, I am able to create one successfully and on others I get this error.
Warning: In /home/jonathan/VTK-8.2.0/Rendering/OpenGL2/vtkEGLRenderWindow.cxx, line 588
vtkEGLRenderWindow (0x7f32d85782d0): Unable to eglMakeCurrent: 12290
The idea of my application is to have an EGL volumetric render on a C++ backend, and all that is required to understand my situation for now is that a user on the frontend is repeatedly sending new Camera positions (using Position, ViewUp and Focal Point). For now all I want to do change the camera in the EGL render to the position specified by the user, and save a screen shot of the resulting render. This appears to work on occasions, but on others I get the above error, and the screenshot either appears empty or corrupted. Sometimes it works exactly as intended, and I can save several screenshots until the error occurs.
The code I'm using to set up the vtk EGL render:
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;
void createEGLRenderOnServer(){
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());
// Create the standard renderer, render window
// and interactor
colors = vtkSmartPointer<vtkNamedColors>::New();
ren1 = vtkSmartPointer<vtkRenderer>::New();
renWin = vtkSmartPointer<vtkEGLRenderWindow>::New();
renWin->AddRenderer(ren1);
// iren = vtkSmartPointer<vtkRenderWindowInteractor>::New();
// iren->SetRenderWindow(renWin);
// 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->SetSize(600, 600);
renWin->Render();
return;
}
And then when I take a screenshot, this function is getting called:
float * updateCameraAndGetData(const CameraInfo *request){
const google::protobuf::RepeatedField<float> position = request->position();
const google::protobuf::RepeatedField<float> focal_point = request->focal_point();
const google::protobuf::RepeatedField<float> view_up = request->view_up();
const double distance = request->distance();
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();
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();
vtkSmartPointer<vtkPNGWriter> writer1 =
vtkSmartPointer<vtkPNGWriter>::New();
writer1->SetFileName("screenshot1.png");
writer1->SetInputConnection(windowToImageFilter->GetOutputPort());
writer1->Write();
}
Unfortunatley I'm using some custom classes and Google's protobuff as my communication protocol between the client and server, so ofcourse this is not enough to recreate the problem. If requested I shall post all the code, but I was wondering if anyone could help me without it initially.