[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