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