text: /*=========================================================================
  
    Program:   Visualization Toolkit
    Module:    vtkRenderWindow.h
  
    Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
    All rights reserved.
    See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
  
       This software is distributed WITHOUT ANY WARRANTY; without even
       the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
       PURPOSE.  See the above copyright notice for more information.
  
  =========================================================================*/
  /**
   * @class   vtkRenderWindow
   * @brief   create a window for renderers to draw into
   *
   * vtkRenderWindow is an abstract object to specify the behavior of a
   * rendering window. A rendering window is a window in a graphical user
   * interface where renderers draw their images. Methods are provided to
   * synchronize the rendering process, set window size, and control double
   * buffering.  The window also allows rendering in stereo.  The interlaced
   * render stereo type is for output to a VRex stereo projector.  All of the
   * odd horizontal lines are from the left eye, and the even lines are from
   * the right eye.  The user has to make the render window aligned with the
   * VRex projector, or the eye will be swapped.
   *
   * @warning
   * In VTK versions 4 and later, the vtkWindowToImageFilter class is
   * part of the canonical way to output an image of a window to a file
   * (replacing the obsolete SaveImageAsPPM method for vtkRenderWindows
   * that existed in 3.2 and earlier).  Connect one of these filters to
   * the output of the window, and filter's output to a writer such as
   * vtkPNGWriter.
   *
   * @sa
   * vtkRenderer vtkRenderWindowInteractor vtkWindowToImageFilter
   */
  
  #ifndef vtkRenderWindow_h
  #define vtkRenderWindow_h
  
  #include "vtkDeprecation.h"         // for VTK_DEPRECATED_IN_9_0_0
  #include "vtkNew.h"                 // For vtkNew
  #include "vtkRenderingCoreModule.h" // For export macro
  #include "vtkSmartPointer.h"        // For vtkSmartPointer
  #include "vtkWindow.h"
  
  class vtkFloatArray;
  class vtkProp;
  class vtkCollection;
  class vtkRenderTimerLog;
  class vtkRenderWindowInteractor;
  class vtkRenderer;
  class vtkRendererCollection;
  class vtkStereoCompositor;
  class vtkUnsignedCharArray;
  
  // lets define the different types of stereo
  #define VTK_STEREO_CRYSTAL_EYES 1
  #define VTK_STEREO_RED_BLUE 2
  #define VTK_STEREO_INTERLACED 3
  #define VTK_STEREO_LEFT 4
  #define VTK_STEREO_RIGHT 5
  #define VTK_STEREO_DRESDEN 6
  #define VTK_STEREO_ANAGLYPH 7
  #define VTK_STEREO_CHECKERBOARD 8
  #define VTK_STEREO_SPLITVIEWPORT_HORIZONTAL 9
  #define VTK_STEREO_FAKE 10
  #define VTK_STEREO_EMULATE 11
  
  #define VTK_CURSOR_DEFAULT 0
  #define VTK_CURSOR_ARROW 1
  #define VTK_CURSOR_SIZENE 2
  #define VTK_CURSOR_SIZENW 3
  #define VTK_CURSOR_SIZESW 4
  #define VTK_CURSOR_SIZESE 5
  #define VTK_CURSOR_SIZENS 6
  #define VTK_CURSOR_SIZEWE 7
  #define VTK_CURSOR_SIZEALL 8
  #define VTK_CURSOR_HAND 9
  #define VTK_CURSOR_CROSSHAIR 10
  #define VTK_CURSOR_CUSTOM 11
  
  class VTKRENDERINGCORE_EXPORT vtkRenderWindow : public vtkWindow
  {
  public:
    vtkTypeMacro(vtkRenderWindow, vtkWindow);
    void PrintSelf(ostream& os, vtkIndent indent) override;
  
    /**
     * Construct an instance of  vtkRenderWindow with its screen size
     * set to 300x300, borders turned on, positioned at (0,0), double
     * buffering turned on.
     */
    static vtkRenderWindow* New();
  
    /**
     * Add a renderer to the list of renderers.
     */
    virtual void AddRenderer(vtkRenderer*);
  
    /**
     * Remove a renderer from the list of renderers.
     */
    void RemoveRenderer(vtkRenderer*);
  
    /**
     * Query if a renderer is in the list of renderers.
     */
    int HasRenderer(vtkRenderer*);
  
    /**
     * What rendering library has the user requested
     */
    static const char* GetRenderLibrary();
  
    /**
     * What rendering backend has the user requested
     */
    virtual const char* GetRenderingBackend();
  
    /**
     * Get the render timer log for this window.
     */
    vtkGetNewMacro(RenderTimer, vtkRenderTimerLog);
  
    /**
     * Return the collection of renderers in the render window.
     */
    vtkRendererCollection* GetRenderers() { return this->Renderers; }
  
    /**
     * The GL2PS exporter must handle certain props in a special way (e.g. text).
     * This method performs a render and captures all "GL2PS-special" props in
     * the specified collection. The collection will contain a
     * vtkPropCollection for each vtkRenderer in this->GetRenderers(), each
     * containing the special props rendered by the corresponding renderer.
     */
    void CaptureGL2PSSpecialProps(vtkCollection* specialProps);
  
    ///@{
    /**
     * Returns true if the render process is capturing text actors.
     */
    vtkGetMacro(CapturingGL2PSSpecialProps, int);
    ///@}
  
    /**
     * Ask each renderer owned by this RenderWindow to render its image and
     * synchronize this process.
     */
    void Render() override;
  
    /**
     * Start the rendering process for a frame
     */
    virtual void Start() {}
  
    /**
     * Update the system, if needed, at end of render process
     */
    virtual void End(){};
  
    /**
     * Finalize the rendering process.
     */
    virtual void Finalize() {}
  
    /**
     * A termination method performed at the end of the rendering process
     * to do things like swapping buffers (if necessary) or similar actions.
     */
    virtual void Frame() {}
  
    /**
     * Block the thread until the actual rendering is finished().
     * Useful for measurement only.
     */
    virtual void WaitForCompletion() {}
  
    /**
     * Performed at the end of the rendering process to generate image.
     * This is typically done right before swapping buffers.
     */
    virtual void CopyResultFrame();
  
    /**
     * Create an interactor to control renderers in this window. We need
     * to know what type of interactor to create, because we might be in
     * X Windows or MS Windows.
     */
    virtual vtkRenderWindowInteractor* MakeRenderWindowInteractor();
  
    ///@{
    /**
     * Hide or Show the mouse cursor, it is nice to be able to hide the
     * default cursor if you want VTK to display a 3D cursor instead.
     * Set cursor position in window (note that (0,0) is the lower left
     * corner).
     */
    virtual void HideCursor() {}
    virtual void ShowCursor() {}
    virtual void SetCursorPosition(int, int) {}
    ///@}
  
    ///@{
    /**
     * Change the shape of the cursor.
     */
    vtkSetMacro(CurrentCursor, int);
    vtkGetMacro(CurrentCursor, int);
    ///@}
  
    ///@{
    /**
     * Set/Get the full path to the custom cursor.
     * This is used when the current cursor is set to VTK_CURSOR_CUSTOM.
     */
    vtkSetFilePathMacro(CursorFileName);
    vtkGetFilePathMacro(CursorFileName);
    ///@}
  
    ///@{
    /**
     * Turn on/off rendering full screen window size.
     */
    virtual void SetFullScreen(vtkTypeBool) {}
    vtkGetMacro(FullScreen, vtkTypeBool);
    vtkBooleanMacro(FullScreen, vtkTypeBool);
    ///@}
  
    ///@{
    /**
     * Turn on/off window manager borders. Typically, you shouldn't turn the
     * borders off, because that bypasses the window manager and can cause
     * undesirable behavior.
     */
    vtkSetMacro(Borders, vtkTypeBool);
    vtkGetMacro(Borders, vtkTypeBool);
    vtkBooleanMacro(Borders, vtkTypeBool);
    ///@}
  
    ///@{
    /**
     * Prescribe that the window be created in a stereo-capable mode. This
     * method must be called before the window is realized. Default is off.
     */
    vtkGetMacro(StereoCapableWindow, vtkTypeBool);
    vtkBooleanMacro(StereoCapableWindow, vtkTypeBool);
    virtual void SetStereoCapableWindow(vtkTypeBool capable);
    ///@}
  
    ///@{
    /**
     * Turn on/off stereo rendering.
     */
    vtkGetMacro(StereoRender, vtkTypeBool);
    void SetStereoRender(vtkTypeBool stereo);
    vtkBooleanMacro(StereoRender, vtkTypeBool);
    ///@}
  
    ///@{
    /**
     * Turn on/off the use of alpha bitplanes.
     */
    vtkSetMacro(AlphaBitPlanes, vtkTypeBool);
    vtkGetMacro(AlphaBitPlanes, vtkTypeBool);
    vtkBooleanMacro(AlphaBitPlanes, vtkTypeBool);
    ///@}
  
    ///@{
    /**
     * Turn on/off point smoothing. Default is off.
     * This must be applied before the first Render.
     */
    vtkSetMacro(PointSmoothing, vtkTypeBool);
    vtkGetMacro(PointSmoothing, vtkTypeBool);
    vtkBooleanMacro(PointSmoothing, vtkTypeBool);
    ///@}
  
    ///@{
    /**
     * Turn on/off line smoothing. Default is off.
     * This must be applied before the first Render.
     */
    vtkSetMacro(LineSmoothing, vtkTypeBool);
    vtkGetMacro(LineSmoothing, vtkTypeBool);
    vtkBooleanMacro(LineSmoothing, vtkTypeBool);
    ///@}
  
    ///@{
    /**
     * Turn on/off polygon smoothing. Default is off.
     * This must be applied before the first Render.
     */
    vtkSetMacro(PolygonSmoothing, vtkTypeBool);
    vtkGetMacro(PolygonSmoothing, vtkTypeBool);
    vtkBooleanMacro(PolygonSmoothing, vtkTypeBool);
    ///@}
  
    ///@{
    /**
     * Set/Get what type of stereo rendering to use.  CrystalEyes
     * mode uses frame-sequential capabilities available in OpenGL
     * to drive LCD shutter glasses and stereo projectors.  RedBlue
     * mode is a simple type of stereo for use with red-blue glasses.
     * Anaglyph mode is a superset of RedBlue mode, but the color
     * output channels can be configured using the AnaglyphColorMask
     * and the color of the original image can be (somewhat) maintained
     * using AnaglyphColorSaturation;  the default colors for Anaglyph
     * mode is red-cyan.  Interlaced stereo mode produces a composite
     * image where horizontal lines alternate between left and right
     * views.  StereoLeft and StereoRight modes choose one or the other
     * stereo view.  Dresden mode is yet another stereoscopic
     * interleaving. Fake simply causes the window to render twice without
     * actually swapping the camera from left eye to right eye. This is useful in
     * certain applications that want to emulate the rendering passes without
     * actually rendering in stereo mode. Emulate is similar to Fake, except that
     * it does render left and right eye. There is no compositing of the resulting
     * images from the two eyes at the end of each render in this mode, hence the
     * result onscreen will be the right eye.
     */
    vtkGetMacro(StereoType, int);
    void SetStereoType(int);
    void SetStereoTypeToCrystalEyes() { this->SetStereoType(VTK_STEREO_CRYSTAL_EYES); }
    void SetStereoTypeToRedBlue() { this->SetStereoType(VTK_STEREO_RED_BLUE); }
    void SetStereoTypeToInterlaced() { this->SetStereoType(VTK_STEREO_INTERLACED); }
    void SetStereoTypeToLeft() { this->SetStereoType(VTK_STEREO_LEFT); }
    void SetStereoTypeToRight() { this->SetStereoType(VTK_STEREO_RIGHT); }
    void SetStereoTypeToDresden() { this->SetStereoType(VTK_STEREO_DRESDEN); }
    void SetStereoTypeToAnaglyph() { this->SetStereoType(VTK_STEREO_ANAGLYPH); }
    void SetStereoTypeToCheckerboard() { this->SetStereoType(VTK_STEREO_CHECKERBOARD); }
    void SetStereoTypeToSplitViewportHorizontal()
    {
      this->SetStereoType(VTK_STEREO_SPLITVIEWPORT_HORIZONTAL);
    }
    void SetStereoTypeToFake() { this->SetStereoType(VTK_STEREO_FAKE); }
    void SetStereoTypeToEmulate() { this->SetStereoType(VTK_STEREO_EMULATE); }
    ///@}
  
    ///@{
    /**
     * Returns the stereo type as a string.
     */
    const char* GetStereoTypeAsString();
    static const char* GetStereoTypeAsString(int type);
    ///@}
  
    /**
     * Update the system, if needed, due to stereo rendering. For some stereo
     * methods, subclasses might need to switch some hardware settings here.
     */
    virtual void StereoUpdate();
  
    /**
     * Intermediate method performs operations required between the rendering
     * of the left and right eye.
     */
    virtual void StereoMidpoint();
  
    /**
     * Handles work required once both views have been rendered when using
     * stereo rendering.
     */
    virtual void StereoRenderComplete();
  
    ///@{
    /**
     * Set/get the anaglyph color saturation factor.  This number ranges from
     * 0.0 to 1.0:  0.0 means that no color from the original object is
     * maintained, 1.0 means all of the color is maintained.  The default
     * value is 0.65.  Too much saturation can produce uncomfortable 3D
     * viewing because anaglyphs also use color to encode 3D.
     */
    vtkSetClampMacro(AnaglyphColorSaturation, float, 0.0f, 1.0f);
    vtkGetMacro(AnaglyphColorSaturation, float);
    ///@}
  
    ///@{
    /**
     * Set/get the anaglyph color mask values.  These two numbers are bits
     * mask that control which color channels of the original stereo
     * images are used to produce the final anaglyph image.  The first
     * value is the color mask for the left view, the second the mask
     * for the right view.  If a bit in the mask is on for a particular
     * color for a view, that color is passed on to the final view; if
     * it is not set, that channel for that view is ignored.
     * The bits are arranged as r, g, and b, so r = 4, g = 2, and b = 1.
     * By default, the first value (the left view) is set to 4, and the
     * second value is set to 3.  That means that the red output channel
     * comes from the left view, and the green and blue values come from
     * the right view.
     */
    vtkSetVector2Macro(AnaglyphColorMask, int);
    vtkGetVectorMacro(AnaglyphColorMask, int, 2);
    ///@}
  
    /**
     * Remap the rendering window. This probably only works on UNIX right now.
     * It is useful for changing properties that can't normally be changed
     * once the window is up.
     */
    virtual void WindowRemap() {}
  
    ///@{
    /**
     * Turn on/off buffer swapping between images.
     */
    vtkSetMacro(SwapBuffers, vtkTypeBool);
    vtkGetMacro(SwapBuffers, vtkTypeBool);
    vtkBooleanMacro(SwapBuffers, vtkTypeBool);
    ///@}
  
    ///@{
    /**
     * Set/Get the pixel data of an image, transmitted as RGBRGBRGB. The
     * front argument indicates if the front buffer should be used or the back
     * buffer. It is the caller's responsibility to delete the resulting
     * array. It is very important to realize that the memory in this array
     * is organized from the bottom of the window to the top. The origin
     * of the screen is in the lower left corner. The y axis increases as
     * you go up the screen. So the storage of pixels is from left to right
     * and from bottom to top.
     * (x,y) is any corner of the rectangle. (x2,y2) is its opposite corner on
     * the diagonal.
     */
    virtual int SetPixelData(int /*x*/, int /*y*/, int /*x2*/, int /*y2*/, unsigned char* /*data*/,
      int /*front*/, int /*right*/ = 0)
    {
      return 0;
    }
    virtual int SetPixelData(int /*x*/, int /*y*/, int /*x2*/, int /*y2*/,
      vtkUnsignedCharArray* /*data*/, int /*front*/, int /*right*/ = 0)
    {
      return 0;
    }
    ///@}
  
    ///@{
    /**
     * Same as Get/SetPixelData except that the image also contains an alpha
     * component. The image is transmitted as RGBARGBARGBA... each of which is a
     * float value. The "blend" parameter controls whether the SetRGBAPixelData
     * method blends the data with the previous contents of the frame buffer
     * or completely replaces the frame buffer data.
     */
    virtual float* GetRGBAPixelData(
      int /*x*/, int /*y*/, int /*x2*/, int /*y2*/, int /*front*/, int /*right*/ = 0)
    {
      return nullptr;
    }
    virtual int GetRGBAPixelData(int /*x*/, int /*y*/, int /*x2*/, int /*y2*/, int /*front*/,
      vtkFloatArray* /*data*/, int /*right*/ = 0)
    {
      return 0;
    }
    virtual int SetRGBAPixelData(int /*x*/, int /*y*/, int /*x2*/, int /*y2*/, float*, int /*front*/,
      int /*blend*/ = 0, int /*right*/ = 0)
    {
      return 0;
    }
    virtual int SetRGBAPixelData(
      int, int, int, int, vtkFloatArray*, int, int /*blend*/ = 0, int /*right*/ = 0)
    {
      return 0;
    }
    virtual void ReleaseRGBAPixelData(float* /*data*/) {}
    virtual unsigned char* GetRGBACharPixelData(
      int /*x*/, int /*y*/, int /*x2*/, int /*y2*/, int /*front*/, int /*right*/ = 0)
    {
      return nullptr;
    }
    virtual int GetRGBACharPixelData(int /*x*/, int /*y*/, int /*x2*/, int /*y2*/, int /*front*/,
      vtkUnsignedCharArray* /*data*/, int /*right*/ = 0)
    {
      return 0;
    }
    virtual int SetRGBACharPixelData(int /*x*/, int /*y*/, int /*x2*/, int /*y2*/,
      unsigned char* /*data*/, int /*front*/, int /*blend*/ = 0, int /*right*/ = 0)
    {
      return 0;
    }
    virtual int SetRGBACharPixelData(int /*x*/, int /*y*/, int /*x2*/, int /*y2*/,
      vtkUnsignedCharArray* /*data*/, int /*front*/, int /*blend*/ = 0, int /*right*/ = 0)
    {
      return 0;
    }
    ///@}
  
    ///@{
    /**
     * Set/Get the zbuffer data from the frame buffer.
     * (x,y) is any corner of the rectangle. (x2,y2) is its opposite corner on
     * the diagonal.
     */
    virtual float* GetZbufferData(int /*x*/, int /*y*/, int /*x2*/, int /*y2*/) { return nullptr; }
    virtual int GetZbufferData(int /*x*/, int /*y*/, int /*x2*/, int /*y2*/, float* /*z*/)
    {
      return 0;
    }
    virtual int GetZbufferData(int /*x*/, int /*y*/, int /*x2*/, int /*y2*/, vtkFloatArray* /*z*/)
    {
      return 0;
    }
    virtual int SetZbufferData(int /*x*/, int /*y*/, int /*x2*/, int /*y2*/, float* /*z*/)
    {
      return 0;
    }
    virtual int SetZbufferData(int /*x*/, int /*y*/, int /*x2*/, int /*y2*/, vtkFloatArray* /*z*/)
    {
      return 0;
    }
    float GetZbufferDataAtPoint(int x, int y)
    {
      float value;
      this->GetZbufferData(x, y, x, y, &value);
      return value;
    }
    ///@}
  
    ///@{
    /**
     * This flag is set if the window hasn't rendered since it was created
     */
    vtkGetMacro(NeverRendered, int);
    ///@}
  
    ///@{
    /**
     * This is a flag that can be set to interrupt a rendering that is in
     * progress.
     */
    vtkGetMacro(AbortRender, int);
    vtkSetMacro(AbortRender, int);
    vtkGetMacro(InAbortCheck, int);
    vtkSetMacro(InAbortCheck, int);
    virtual int CheckAbortStatus();
    ///@}
  
    ///@{
    /**
     * @deprecated in VTK 9.0
     */
    VTK_DEPRECATED_IN_9_0_0("Removed in 9.0")
    vtkTypeBool GetIsPicking();
    VTK_DEPRECATED_IN_9_0_0("Removed in 9.0")
    void SetIsPicking(vtkTypeBool);
    VTK_DEPRECATED_IN_9_0_0("Removed in 9.0")
    void IsPickingOn();
    VTK_DEPRECATED_IN_9_0_0("Removed in 9.0")
    void IsPickingOff();
    ///@}
  
    /**
     * Check to see if a mouse button has been pressed.  All other events
     * are ignored by this method.  Ideally, you want to abort the render
     * on any event which causes the DesiredUpdateRate to switch from
     * a high-quality rate to a more interactive rate.
     */
    virtual vtkTypeBool GetEventPending() { return 0; }
  
    /**
     * Are we rendering at the moment
     */
    virtual int CheckInRenderStatus() { return this->InRender; }
  
    /**
     * Clear status (after an exception was thrown for example)
     */
    virtual void ClearInRenderStatus() { this->InRender = 0; }
  
    ///@{
    /**
     * Set/Get the desired update rate. This is used with
     * the vtkLODActor class. When using level of detail actors you
     * need to specify what update rate you require. The LODActors then
     * will pick the correct resolution to meet your desired update rate
     * in frames per second. A value of zero indicates that they can use
     * all the time they want to.
     */
    virtual void SetDesiredUpdateRate(double);
    vtkGetMacro(DesiredUpdateRate, double);
    ///@}
  
    ///@{
    /**
     * Get the number of layers for renderers.  Each renderer should have
     * its layer set individually.  Some algorithms iterate through all layers,
     * so it is not wise to set the number of layers to be exorbitantly large
     * (say bigger than 100).
     */
    vtkGetMacro(NumberOfLayers, int);
    vtkSetClampMacro(NumberOfLayers, int, 1, VTK_INT_MAX);
    ///@}
  
    ///@{
    /**
     * Get the interactor associated with this render window
     */
    vtkGetObjectMacro(Interactor, vtkRenderWindowInteractor);
    ///@}
  
    /**
     * Set the interactor to the render window
     */
    virtual void SetInteractor(vtkRenderWindowInteractor*);
  
    /**
     * This Method detects loops of RenderWindow<->Interactor,
     * so objects are freed properly.
     */
    void UnRegister(vtkObjectBase* o) override;
  
    ///@{
    /**
     * Dummy stubs for vtkWindow API.
     */
    void SetDisplayId(void*) override {}
    void SetWindowId(void*) override {}
    virtual void SetNextWindowId(void*) {}
    void SetParentId(void*) override {}
    void* GetGenericDisplayId() override { return nullptr; }
    void* GetGenericWindowId() override { return nullptr; }
    void* GetGenericParentId() override { return nullptr; }
    void* GetGenericContext() override { return nullptr; }
    void* GetGenericDrawable() override { return nullptr; }
    void SetWindowInfo(const char*) override {}
    virtual void SetNextWindowInfo(const char*) {}
    void SetParentInfo(const char*) override {}
    ///@}
  
    /**
     * Initialize the render window from the information associated
     * with the currently activated OpenGL context.
     */
    virtual bool InitializeFromCurrentContext() { return false; }
  
    ///@{
    /**
     * Set/Get an already existing window that this window should
     * share data with if possible. This must be set
     * after the shared render window has been created and initialized
     * but before this window has been initialized. Not all platforms
     * support data sharing.
     */
    virtual void SetSharedRenderWindow(vtkRenderWindow*);
    vtkGetObjectMacro(SharedRenderWindow, vtkRenderWindow);
    virtual bool GetPlatformSupportsRenderWindowSharing() { return false; }
    ///@}
  
    /**
     * Tells if this window is the current graphics context for the calling
     * thread.
     */
    virtual bool IsCurrent() { return false; }
  
    /**
     * Test if the window has a valid drawable. This is
     * currently only an issue on Mac OS X Cocoa where rendering
     * to an invalid drawable results in all OpenGL calls to fail
     * with "invalid framebuffer operation".
     */
    VTK_DEPRECATED_IN_9_1_0(
      "Deprecated in 9.1 because no one knows what it's for and nothing uses it")
    virtual bool IsDrawable();
  
    /**
     * If called, allow MakeCurrent() to skip cache-check when called.
     * MakeCurrent() reverts to original behavior of cache-checking
     * on the next render.
     */
    virtual void SetForceMakeCurrent() {}
  
    /**
     * Get report of capabilities for the render window
     */
    virtual const char* ReportCapabilities() { return "Not Implemented"; }
  
    /**
     * Does this render window support OpenGL? 0-false, 1-true
     */
    virtual int SupportsOpenGL() { return 0; }
  
    /**
     * Is this render window using hardware acceleration? 0-false, 1-true
     */
    virtual vtkTypeBool IsDirect() { return 0; }
  
    /**
     * This method should be defined by the subclass. How many bits of
     * precision are there in the zbuffer?
     */
    virtual int GetDepthBufferSize() { return 0; }
  
    /**
     * Get the size of the color buffer.
     * Returns 0 if not able to determine otherwise sets R G B and A into buffer.
     */
    virtual int GetColorBufferSizes(int* /*rgba*/) { return 0; }
  
    ///@{
    /**
     * Set / Get the number of multisamples to use for hardware antialiasing.
     * A value of 1 will be set to 0.
     */
    virtual void SetMultiSamples(int);
    vtkGetMacro(MultiSamples, int);
    ///@}
  
    ///@{
    /**
     * Set / Get the availability of the stencil buffer.
     */
    vtkSetMacro(StencilCapable, vtkTypeBool);
    vtkGetMacro(StencilCapable, vtkTypeBool);
    vtkBooleanMacro(StencilCapable, vtkTypeBool);
    ///@}
  
    ///@{
    /**
     * If there are several graphics card installed on a system,
     * this index can be used to specify which card you want to render to.
     * the default is 0. This may not work on all derived render window and
     * it may need to be set before the first render.
     */
    vtkSetMacro(DeviceIndex, int);
    vtkGetMacro(DeviceIndex, int);
    ///@}
    /**
     * Returns the number of devices (graphics cards) on a system.
     * This may not work on all derived render windows.
     */
    virtual int GetNumberOfDevices() { return 0; }
  
    ///@{
    /**
     * Set/Get if we want this window to use the sRGB color space.
     * Some hardware/drivers do not fully support this.
     */
    vtkGetMacro(UseSRGBColorSpace, bool);
    vtkSetMacro(UseSRGBColorSpace, bool);
    vtkBooleanMacro(UseSRGBColorSpace, bool);
    ///@}
  
  protected:
    vtkRenderWindow();
    ~vtkRenderWindow() override;
  
    virtual void DoStereoRender();
  
    vtkRendererCollection* Renderers;
    vtkNew<vtkRenderTimerLog> RenderTimer;
    vtkTypeBool Borders;
    vtkTypeBool FullScreen;
    int OldScreen[5];
    vtkTypeBool PointSmoothing;
    vtkTypeBool LineSmoothing;
    vtkTypeBool PolygonSmoothing;
    vtkTypeBool StereoRender;
    int StereoType;
    vtkTypeBool StereoCapableWindow;
    vtkTypeBool AlphaBitPlanes;
    vtkRenderWindowInteractor* Interactor;
    vtkSmartPointer<vtkUnsignedCharArray> StereoBuffer; // used for red blue stereo
    vtkSmartPointer<vtkUnsignedCharArray> ResultFrame;
    vtkTypeBool SwapBuffers;
    double DesiredUpdateRate;
    int AbortRender;
    int InAbortCheck;
    int InRender;
    int NeverRendered;
    int NumberOfLayers;
    int CurrentCursor;
    float AnaglyphColorSaturation;
    int AnaglyphColorMask[2];
    int MultiSamples;
    vtkTypeBool StencilCapable;
    int CapturingGL2PSSpecialProps;
    int DeviceIndex;
  
    bool UseSRGBColorSpace;
    char* CursorFileName;
  
    /**
     * The universal time since the last abort check occurred.
     */
    double AbortCheckTime;
  
    vtkRenderWindow* SharedRenderWindow;
  
  private:
    vtkRenderWindow(const vtkRenderWindow&) = delete;
    void operator=(const vtkRenderWindow&) = delete;
  
    vtkNew<vtkStereoCompositor> StereoCompositor;
  };
  
  #endif
  