[vtkusers] Frame Grabbing from a thread conflicts with OpenGL
    jean-michel.rouet at philips.com 
    jean-michel.rouet at philips.com
       
    Tue Dec  2 05:26:30 EST 2003
    
    
  
Hi all,
I recently posted a message querying how to grab asynchronously some 
renderWindow images while the renderWindowInteractor is running. 
I told that the thread technique lead to problem (crash of wglMakeCurrent 
somewhere in vtkWin32OpenGLRenderWindow.cxx)
Here is a very short program that demonstrates the problem.
Can anyone having experience with threads in Win32 and VTK try this out. 
Maybe I did silly things while instanciating the threads...
<--- cut here --->
// first include the required header files for the vtk classes we are 
using
#include "vtkConeSource.h"
#include "vtkPolyDataMapper.h"
#include "vtkRenderWindow.h"
#include "vtkRenderWindowInteractor.h"
#include "vtkCommand.h"
#include "vtkCamera.h"
#include "vtkActor.h"
#include "vtkRenderer.h"
#include "vtkMultiThreader.h"
#include "vtkMutexLock.h"
#include "vtkWindowToImageFilter.h"
#include "vtkBMPWriter.h"
// The Thread responsible for grabbing images
static void *mythread(struct ThreadInfoStruct *data)
{
    int activeFlag;
    int i = 0;
    char filename[512];
 
    vtkRenderWindowInteractor *self = 
(vtkRenderWindowInteractor*)(data->UserData);
    vtkBMPWriter *bmpwriter = vtkBMPWriter::New();
    cout << "starting thread " << data->ThreadID << endl;
 
    while (1) {
        data->ActiveFlagLock->Lock();
        activeFlag = *(data->ActiveFlag);
        data->ActiveFlagLock->Unlock();
 
        if (activeFlag == 0)
            {
                cout << "Terminating thread " << data->ThreadID << endl;
                return NULL;
            }
        sprintf (filename, "e:/tmp/image_%03d.bmp", i);
        cout << "Saving image " << filename << endl;
 
        // ******************************** ################ 
************************
        // if enabled, this part crashes into wglMakeCurrent()
        if (1) {
            vtkWindowToImageFilter *windowToimage = 
vtkWindowToImageFilter::New();
            windowToimage->SetInput(self->GetRenderWindow());
            bmpwriter->SetInput(windowToimage->GetOutput());
            bmpwriter->SetFileName(filename);
            bmpwriter->Write();
            windowToimage->Delete();
        }
        // ******************************** ################ 
************************
 
        Sleep(1000);
    }
    bmpwriter->Delete();
    return NULL;
}
// just a call back to launch or terminate the thread when a key is 
pressed.
class vtkMyCallback : public vtkCommand
{
public:
  static vtkMyCallback *New() 
    { return new vtkMyCallback; }
    vtkMultiThreader *control;
    vtkMyCallback() {
        control = vtkMultiThreader::New();
        control->SetNumberOfThreads(1);
        threadId = -1;
    }
    ~vtkMyCallback() {
        if (threadId != -1)
            control->TerminateThread(threadId);
        control->Delete();
    }
 
  virtual void Execute(vtkObject *caller, unsigned long, void*)
    {
      vtkRenderWindowInteractor *iren = 
reinterpret_cast<vtkRenderWindowInteractor*>(caller);
      // now start a thread
      if (threadId == -1)
          threadId = 
control->SpawnThread((vtkThreadFunctionType)&mythread, iren);
      // stop the thread
      else {
          control->TerminateThread(threadId);
          threadId = -1;
      } 
    }
private:
    int threadId; 
};
int main( int argc, char *argv[] )
{
  vtkConeSource *cone = vtkConeSource::New();
  cone->SetHeight( 3.0 );
  cone->SetRadius( 1.0 );
  cone->SetResolution( 10 );
  vtkPolyDataMapper *coneMapper = vtkPolyDataMapper::New();
  coneMapper->SetInput( cone->GetOutput() );
  vtkActor *coneActor = vtkActor::New();
  coneActor->SetMapper( coneMapper );
  vtkRenderer *ren1= vtkRenderer::New();
  ren1->AddActor( coneActor );
  ren1->SetBackground( 0.1, 0.2, 0.4 );
  vtkRenderWindow *renWin = vtkRenderWindow::New();
  renWin->AddRenderer( ren1 );
  renWin->SetSize( 300, 300 );
  vtkRenderWindowInteractor *iren = vtkRenderWindowInteractor::New();
  iren->SetRenderWindow(renWin);
  iren->Initialize();
  // add an observer for keypress that will launch t
  vtkMyCallback *mo1 = vtkMyCallback::New();
  iren->AddObserver(vtkCommand::KeyPressEvent,mo1);
  mo1->Delete();
  // start interaction
  iren->Start();
 
  //
  // Free up any objects we created
  //
  cone->Delete();
  coneMapper->Delete();
  coneActor->Delete();
  ren1->Delete();
  renWin->Delete();
  return 0;
}
<--- cut here --->
    
    
More information about the vtkusers
mailing list