1 /*=========================================================================
2 
3   Program:   Visualization Toolkit
4   Module:    vtkSynchronizedRenderers.h
5 
6   Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
7   All rights reserved.
8   See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
9 
10      This software is distributed WITHOUT ANY WARRANTY; without even
11      the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
12      PURPOSE.  See the above copyright notice for more information.
13 
14 =========================================================================*/
15 /**
16  * @class   vtkSynchronizedRenderers
17  * @brief   synchronizes renderers across processes.
18  *
19  * vtkSynchronizedRenderers is used to synchronize renderers (vtkRenderer and
20  * subclasses) across processes for parallel rendering. It's designed to be used
21  * in conjunction with vtkSynchronizedRenderWindows to synchronize the render
22  * windows among those processes.
23  * This class handles synchronization of certain render parameters among the
24  * renderers such as viewport, camera parameters. It doesn't support compositing
25  * of rendered images across processes on its own. You typically either subclass
26  * to implement a compositing algorithm or use a renderer capable of compositing
27  * eg. IceT based renderer.
28 */
29 
30 #ifndef vtkSynchronizedRenderers_h
31 #define vtkSynchronizedRenderers_h
32 
33 #include "vtkRenderingParallelModule.h" // For export macro
34 #include "vtkObject.h"
35 #include "vtkUnsignedCharArray.h" // needed for vtkUnsignedCharArray.
36 #include "vtkSmartPointer.h" // needed for vtkSmartPointer.
37 
38 class vtkFXAAOptions;
39 class vtkRenderer;
40 class vtkMultiProcessController;
41 class vtkMultiProcessStream;
42 class vtkOpenGLFXAAFilter;
43 class vtkOpenGLRenderer;
44 
45 class VTKRENDERINGPARALLEL_EXPORT vtkSynchronizedRenderers : public vtkObject
46 {
47 public:
48   static vtkSynchronizedRenderers* New();
49   vtkTypeMacro(vtkSynchronizedRenderers, vtkObject);
50   void PrintSelf(ostream& os, vtkIndent indent) override;
51 
52   //@{
53   /**
54    * Set the renderer to be synchronized by this instance. A
55    * vtkSynchronizedRenderers instance can be used to synchronize exactly 1
56    * renderer on each processes. You can create multiple instances on
57    * vtkSynchronizedRenderers to synchronize multiple renderers.
58    */
59   virtual void SetRenderer(vtkRenderer*);
60   virtual vtkRenderer* GetRenderer();
61   //@}
62 
63   //@{
64   /**
65    * Set the parallel message communicator. This is used to communicate among
66    * processes.
67    */
68   virtual void SetParallelController(vtkMultiProcessController*);
69   vtkGetObjectMacro(ParallelController, vtkMultiProcessController);
70   //@}
71 
72   //@{
73   /**
74    * Enable/Disable parallel rendering. Unless Parallel rendering is on, the
75    * cameras won't be synchronized across processes.
76    */
77   vtkSetMacro(ParallelRendering, bool);
78   vtkGetMacro(ParallelRendering, bool);
79   vtkBooleanMacro(ParallelRendering, bool);
80   //@}
81 
82   //@{
83   /**
84    * Get/Set the image reduction factor.
85    */
86   vtkSetClampMacro(ImageReductionFactor, int, 1, 50);
87   vtkGetMacro(ImageReductionFactor, int);
88   //@}
89 
90   //@{
91   /**
92    * If on (default), the rendered images are pasted back on to the screen. You
93    * should turn this flag off on processes that are not meant to be visible to
94    * the user.
95    */
96   vtkSetMacro(WriteBackImages, bool);
97   vtkGetMacro(WriteBackImages, bool);
98   vtkBooleanMacro(WriteBackImages, bool);
99   //@}
100 
101   //@{
102   /**
103    * Get/Set the root-process id. This is required when the ParallelController
104    * is a vtkSocketController. Set to 0 by default (which will not work when
105    * using a vtkSocketController but will work for vtkMPIController).
106    */
107   vtkSetMacro(RootProcessId, int);
108   vtkGetMacro(RootProcessId, int);
109   //@}
110 
111   /**
112    * Computes visible prob bounds. This must be called on all processes at the
113    * same time. The collective result is made available on all processes once
114    * this method returns.
115    * Note that this method requires that bounds is initialized to some value.
116    * This expands the bounds to include the prop bounds.
117    */
118   void CollectiveExpandForVisiblePropBounds(double bounds[6]);
119 
120   //@{
121   /**
122    * When set, this->CaptureRenderedImage() does not capture image from the
123    * screen instead passes the call to the delegate.
124    */
125   virtual void SetCaptureDelegate(vtkSynchronizedRenderers*);
126   vtkGetObjectMacro(CaptureDelegate, vtkSynchronizedRenderers);
127   //@}
128 
129   //@{
130   /**
131    * When multiple groups of processes are synchronized together using different
132    * controllers, one needs to specify the order in which the various
133    * synchronizers execute. In such cases one starts with the outer most
134    * vtkSynchronizedRenderers, sets the dependent one as a CaptureDelegate on it
135    * and the turn off AutomaticEventHandling on the delegate.
136    */
137   vtkSetMacro(AutomaticEventHandling, bool);
138   vtkGetMacro(AutomaticEventHandling, bool);
139   vtkBooleanMacro(AutomaticEventHandling, bool);
140   //@}
141 
142   enum
143   {
144     SYNC_RENDERER_TAG = 15101,
145     RESET_CAMERA_TAG  = 15102,
146     COMPUTE_BOUNDS_TAG = 15103
147   };
148 
149   /// vtkRawImage can be used to make it easier to deal with images for
150   /// compositing/communicating over client-server etc.
151   struct VTKRENDERINGPARALLEL_EXPORT vtkRawImage
152   {
153   public:
vtkRawImagevtkRawImage154     vtkRawImage()
155     {
156       this->Valid = false;
157       this->Size[0] = this->Size[1] = 0;
158       this->Data = vtkSmartPointer<vtkUnsignedCharArray>::New();
159     }
160 
ResizevtkRawImage161     void Resize(int dx, int dy, int numcomps)
162     {
163       this->Valid = false;
164       this->Allocate(dx, dy, numcomps);
165     }
166 
167     /**
168      * Create the buffer from an image data.
169      */
170     void Initialize(int dx, int dy, vtkUnsignedCharArray* data);
171 
MarkValidvtkRawImage172     void MarkValid() { this->Valid = true; }
MarkInValidvtkRawImage173     void MarkInValid() { this->Valid = false; }
174 
IsValidvtkRawImage175     bool IsValid() { return this->Valid; }
GetWidthvtkRawImage176     int GetWidth() { return this->Size[0];}
GetHeightvtkRawImage177     int GetHeight() { return this->Size[1];}
GetRawPtrvtkRawImage178     vtkUnsignedCharArray* GetRawPtr()
179       { return this->Data; }
180 
181     // Pushes the image to the viewport.
182     bool PushToViewport(vtkRenderer*);
183 
184     // This is a raw version of PushToViewport() that assumes that the
185     // glViewport() has already been setup externally.
186     // the argument is optional for backwards compat with old OpenGL
187     bool PushToFrameBuffer(vtkRenderer *ren = nullptr);
188 
189     // Captures the image from the viewport.
190     // This doesn't trigger a render, just captures what's currently there in
191     // the active buffer.
192     bool Capture(vtkRenderer*);
193 
194     // Save the image as a png. Useful for debugging.
195     void SaveAsPNG(const char* filename);
196 
197   private:
198     bool Valid;
199     int Size[2];
200     vtkSmartPointer<vtkUnsignedCharArray> Data;
201 
202     void Allocate(int dx, int dy, int numcomps);
203   };
204 
205 protected:
206   vtkSynchronizedRenderers();
207   ~vtkSynchronizedRenderers() override;
208 
209   struct RendererInfo
210   {
211     int ImageReductionFactor;
212     int Draw;
213     int CameraParallelProjection;
214     double Viewport[4];
215     double CameraPosition[3];
216     double CameraFocalPoint[3];
217     double CameraViewUp[3];
218     double CameraWindowCenter[2];
219     double CameraClippingRange[2];
220     double CameraViewAngle;
221     double CameraParallelScale;
222     double EyeTransformMatrix[16];
223     double ModelTransformMatrix[16];
224 
225     // Save/restore the struct to/from a stream.
226     void Save(vtkMultiProcessStream& stream);
227     bool Restore(vtkMultiProcessStream& stream);
228 
229     void CopyFrom(vtkRenderer*);
230     void CopyTo(vtkRenderer*);
231   };
232 
233   // These methods are called on all processes as a consequence of corresponding
234   // events being called on the renderer.
235   virtual void HandleStartRender();
236   virtual void HandleEndRender();
HandleAbortRender()237   virtual void HandleAbortRender() {}
238 
239   virtual void MasterStartRender();
240   virtual void SlaveStartRender();
241 
242   virtual void MasterEndRender();
243   virtual void SlaveEndRender();
244 
245   vtkMultiProcessController* ParallelController;
246   vtkOpenGLRenderer* Renderer;
247 
248   /**
249    * Can be used in HandleEndRender(), MasterEndRender() or SlaveEndRender()
250    * calls to capture the rendered image. If this->ImageReductionFactor, then
251    * the image will be capture in this->ReducedImage, otherwise it will be
252    * captured in this->FullImage (this->ReducedImage will be pointing to the
253    * same image).
254    */
255   virtual vtkRawImage& CaptureRenderedImage();
256 
257   /**
258    * Can be used in HandleEndRender(), MasterEndRender() or SlaveEndRender()
259    * calls to paste back the image from either this->ReducedImage or
260    * this->FullImage info the viewport.
261    */
262   virtual void PushImageToScreen();
263 
264   vtkSynchronizedRenderers* CaptureDelegate;
265   vtkRawImage ReducedImage;
266   vtkRawImage FullImage;
267 
268   bool ParallelRendering;
269   int ImageReductionFactor;
270   bool WriteBackImages;
271   int RootProcessId;
272   bool AutomaticEventHandling;
273 
274 private:
275   vtkSynchronizedRenderers(const vtkSynchronizedRenderers&) = delete;
276   void operator=(const vtkSynchronizedRenderers&) = delete;
277 
278   class vtkObserver;
279   vtkObserver* Observer;
280   friend class vtkObserver;
281 
282   bool UseFXAA;
283   vtkOpenGLFXAAFilter* FXAAFilter;
284 
285   double LastViewport[4];
286 };
287 
288 #endif
289 
290