[vtkusers] Concurrent rendering to multiple renderwindows

A. Meijster A.Meijster at rc.rug.nl
Wed Mar 5 06:10:53 EST 2003


Hi,

  I try to render concurrently to three renderwindows concurrently in
order to achieve a panorama. In fact I would like to render to three
different displays, but that doesn't matter for the time being. I
created three windows, three cameras, and three renderers, and tried
to do the rendering in parallel using pthreads. That doesn't work.
The windows come up, but freeze. Without doubt as a result
of non-thread safety of VTK (I used 4.2.1). Can anyone else tell
me how to do this.

The following code is what I tried to do (Redhat 8.0 Linux + vtk 4.2.1).


    Any help appreciated,

        Arnold Meijster (A.Meijster at rc.rug.nl)


#include <pthread.h>

//
// This example creates a polygonal model of a cone, and then rendered it to
// the screen. It willrotate the cone 360 degrees and then exit. The basic
// setup of source -> mapper -> actor -> renderer -> renderwindow is
// typical of most VTK programs.
//

// first include the required header files for the vtk classes we are using
#include "vtkConeSource.h"
#include "vtkPolyDataMapper.h"
#include "vtkRenderWindow.h"
#include "vtkRenderer.h"
#include "vtkCamera.h"

#include <iostream>
using namespace std;

vtkRenderWindow *renWin0, *renWin1, *renWin2;

void showCamera(vtkCamera *camera) {
   double viewAngle = camera->GetViewAngle();
   double x, y, z;

   cout << "ViewAngle: " << viewAngle<<endl;
   camera->GetPosition (x, y, z);
   cout << "Position: " << x <<","<< y <<","<< z << endl;

   camera->GetFocalPoint (x, y, z);
   cout << "FocalPoint: " << x <<","<< y <<","<< z << endl;

   camera->GetViewUp (x, y, z);
   cout << "UpVector: " << x <<","<< y <<","<< z << endl;
}

void *renderThread(void *arg) {
   vtkRenderWindow *win = (vtkRenderWindow *)arg;
   win->Render();
   return NULL;
}

void doRender () {
   pthread_t th0, th1, th2;
   pthread_create(&th0, NULL, renderThread, renWin0);
   pthread_create(&th1, NULL, renderThread, renWin1);
   pthread_create(&th2, NULL, renderThread, renWin2);
   pthread_join (th0, NULL);
   pthread_join (th1, NULL);
   pthread_join (th2, NULL);
}

int main( int argc, char *argv[] )
{
   //
   // Next we create an instance of vtkConeSource and set some of its
   // properties
   //
   vtkConeSource *cone = vtkConeSource::New();
   cone->SetHeight(6.0 );
   cone->SetRadius(2.0 );
   cone->SetResolution( 100 );

   //
   // We create an instance of vtkPolyDataMapper to map the polygonal data
   // into graphics primitives. We connect the output of the cone souece
   // to the input of this mapper
   //
   vtkPolyDataMapper *coneMapper = vtkPolyDataMapper::New();
   coneMapper->SetInput( cone->GetOutput() );

   //
   // create an actor to represent the cone. The actor coordinates rendering of
   // the graphics primitives for a mapper. We set this actor's mapper to be
   // coneMapper which we created above.
   //
   vtkActor *coneActor = vtkActor::New();
   coneActor->SetMapper( coneMapper );

   //
   // Create the Renderer and assign actors to it. A renderer is like a
   // viewport. It is part or all of a window on the screen and it is
   // responsible for drawing the actors it has.  We also set the background
   // color here
   //
   vtkRenderer *ren0= vtkRenderer::New();
   ren0->AddActor( coneActor );
   ren0->SetBackground(0.0, 0.1, 0.3);

   vtkRenderer *ren1= vtkRenderer::New();
   ren1->AddActor( coneActor );
   ren1->SetBackground(0.1, 0.2, 0.4);

   vtkRenderer *ren2= vtkRenderer::New();
   ren2->AddActor( coneActor );
   ren2->SetBackground(0.2, 0.3, 0.5);

   //
   // Finally we create the render window which will show up on the screen
   // We put our renderer into the render window using AddRenderer. We also
   // set the size to be 300 pixels by 300
   //
   renWin0 = vtkRenderWindow::New();
   renWin0->AddRenderer( ren0 );
   renWin0->SetSize( 300, 300 );
   renWin0->SetPosition(0,0);
   renWin0->BordersOff();

   renWin1 = vtkRenderWindow::New();
   renWin1->AddRenderer( ren1 );
   renWin1->SetSize( 300, 300 );
   renWin1->SetPosition(300,0);
   renWin1->BordersOff();

   renWin2 = vtkRenderWindow::New();
   renWin2->AddRenderer( ren2 );
   renWin2->SetSize( 300, 300 );
   renWin2->SetPosition(600, 0);
   renWin2->BordersOff();

   // Dolly cameras
   ren0->GetActiveCamera()->Dolly(1);
   ren1->GetActiveCamera()->Dolly(1);
   ren2->GetActiveCamera()->Dolly(1);

   double viewAngle = ren1->GetActiveCamera()->GetViewAngle();
   ren0->GetActiveCamera()->Yaw(-viewAngle);
   ren2->GetActiveCamera()->Yaw(viewAngle);

   cout << "Camera 0:"<<endl;
   showCamera(ren0->GetActiveCamera());
   cout << "\nCamera 1:"<<endl;
   showCamera(ren1->GetActiveCamera());
   cout << "\nCamera 2:"<<endl;
   showCamera(ren2->GetActiveCamera());

   // now we loop over 360 degrees and render the cone each time
   //
   #define STEP 0.1
   float i;
   double x, y, z;
   ren1->GetActiveCamera()->Yaw(20);

   for (i = 0.0; i < 360; i+=STEP)
     {
       ren1->GetActiveCamera()->GetPosition(x, y, z);
       ren0->GetActiveCamera()->SetPosition(x, y, z);
       ren2->GetActiveCamera()->SetPosition(x, y, z);

       ren1->GetActiveCamera()->GetFocalPoint(x, y, z);
       ren0->GetActiveCamera()->SetFocalPoint(x, y, z);
       ren2->GetActiveCamera()->SetFocalPoint(x, y, z);

       ren0->GetActiveCamera()->Yaw(viewAngle);
       ren2->GetActiveCamera()->Yaw(-viewAngle);

       ren0->ResetCameraClippingRange  ();
       ren1->ResetCameraClippingRange  ();
       ren2->ResetCameraClippingRange  ();
       // render the image
       doRender();
       // rotate the active camera by one degree
       ren1->GetActiveCamera()->Azimuth(STEP);

     }

   //
   // Free up any objects we created
   //
   cone->Delete();
   coneMapper->Delete();
   coneActor->Delete();
   ren0->Delete();
   ren1->Delete();
   ren2->Delete();
   renWin0->Delete();
   renWin1->Delete();
   renWin2->Delete();

   return 0;
}






More information about the vtkusers mailing list