vtkOpenGLRenderWindow.h 18.4 KB
Newer Older
Ken Martin's avatar
Ken Martin committed
1 2 3
/*=========================================================================

  Program:   Visualization Toolkit
4
  Module:    vtkOpenGLRenderWindow.h
Ken Martin's avatar
Ken Martin committed
5 6 7 8 9 10 11 12 13 14

  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.

=========================================================================*/
15 16 17 18 19 20 21 22 23
/**
 * @class   vtkOpenGLRenderWindow
 * @brief   OpenGL rendering window
 *
 * vtkOpenGLRenderWindow is a concrete implementation of the abstract class
 * vtkRenderWindow. vtkOpenGLRenderer interfaces to the OpenGL graphics
 * library. Application programmers should normally use vtkRenderWindow
 * instead of the OpenGL specific version.
*/
Ken Martin's avatar
Ken Martin committed
24

25 26
#ifndef vtkOpenGLRenderWindow_h
#define vtkOpenGLRenderWindow_h
Ken Martin's avatar
Ken Martin committed
27

28
#include "vtkRect.h" // for vtkRecti
Ken Martin's avatar
Ken Martin committed
29
#include "vtkRenderWindow.h"
30 31 32 33 34
#include "vtkRenderingOpenGL2Module.h" // For export macro
#include "vtkType.h"                   // for ivar
#include <map>                         // for ivar
#include <set>                         // for ivar
#include <string>                      // for ivar
35

Ken Martin's avatar
Ken Martin committed
36
class vtkIdList;
37
class vtkOpenGLBufferObject;
Ken Martin's avatar
Ken Martin committed
38
class vtkOpenGLHardwareSupport;
39
class vtkOpenGLShaderCache;
40
class vtkOpenGLVertexBufferObjectCache;
Ken Martin's avatar
Ken Martin committed
41 42
class vtkOpenGLVertexArrayObject;
class vtkShaderProgram;
Ken Martin's avatar
Ken Martin committed
43
class vtkStdString;
Ken Martin's avatar
Ken Martin committed
44
class vtkTexture;
45
class vtkTextureObject;
Ken Martin's avatar
Ken Martin committed
46
class vtkTextureUnitManager;
47
class vtkGenericOpenGLResourceFreeCallback;
48
class vtkOpenGLState;
Ken Martin's avatar
Ken Martin committed
49

50
class VTKRENDERINGOPENGL2_EXPORT vtkOpenGLRenderWindow : public vtkRenderWindow
Ken Martin's avatar
Ken Martin committed
51 52
{
public:
53
  vtkTypeMacro(vtkOpenGLRenderWindow, vtkRenderWindow);
54
  void PrintSelf(ostream& os, vtkIndent indent) override;
Ken Martin's avatar
Ken Martin committed
55

56 57 58
  /**
   * What rendering backend has the user requested
   */
59
  const char *GetRenderingBackend() override;
60

61 62 63 64
  //@{
  /**
   * Set/Get the maximum number of multisamples
   */
Ken Martin's avatar
Ken Martin committed
65 66
  static void SetGlobalMaximumNumberOfMultiSamples(int val);
  static int  GetGlobalMaximumNumberOfMultiSamples();
67
  //@}
Ken Martin's avatar
Ken Martin committed
68

69 70 71 72
  //@{
  /**
   * Set/Get the pixel data of an image, transmitted as RGBRGB...
   */
73
  unsigned char *GetPixelData(int x,int y,int x2,int y2,int front,int right)
74
                             override;
75
  int GetPixelData(int x,int y,int x2,int y2, int front,
76
                   vtkUnsignedCharArray *data, int right) override;
77
  int SetPixelData(int x,int y,int x2,int y2,unsigned char *data,
78
                   int front, int right) override;
79
  int SetPixelData(int x,int y,int x2,int y2,
80
                   vtkUnsignedCharArray *data, int front, int right)
81
                   override;
82
  //@}
Ken Martin's avatar
Ken Martin committed
83

84 85 86 87
  //@{
  /**
   * Set/Get the pixel data of an image, transmitted as RGBARGBA...
   */
88
  float *GetRGBAPixelData(int x,int y,int x2,int y2,int front,int right=0)
89
                         override;
90
  int GetRGBAPixelData(int x,int y,int x2,int y2, int front,
91
                       vtkFloatArray* data, int right=0) override;
92
  int SetRGBAPixelData(int x,int y,int x2,int y2, float *data,
93
                       int front, int blend=0, int right=0) override;
94
  int SetRGBAPixelData(int x,int y,int x2,int y2, vtkFloatArray *data,
95 96
                       int front, int blend=0, int right=0) override;
  void ReleaseRGBAPixelData(float *data) override;
97
  unsigned char *GetRGBACharPixelData(int x,int y,int x2,int y2,
98
                                      int front, int right=0) override;
99
  int GetRGBACharPixelData(int x,int y,int x2,int y2, int front,
100
                           vtkUnsignedCharArray *data, int right=0)
101
                          override;
102
  int SetRGBACharPixelData(int x, int y, int x2, int y2,
103
                           unsigned char *data, int front,
104
                           int blend=0, int right=0) override;
105
  int SetRGBACharPixelData(int x,int y,int x2,int y2,
106
                           vtkUnsignedCharArray *data, int front,
107
                           int blend=0,int right=0) override;
108
  //@}
Ken Martin's avatar
Ken Martin committed
109

110 111 112 113
  //@{
  /**
   * Set/Get the zbuffer data from an image
   */
114 115
  float *GetZbufferData( int x1, int y1, int x2, int y2 ) override;
  int GetZbufferData( int x1, int y1, int x2, int y2, float* z ) override;
116
  int GetZbufferData( int x1, int y1, int x2, int y2,
117 118
                              vtkFloatArray* z ) override;
  int SetZbufferData( int x1, int y1, int x2, int y2, float *buffer ) override;
119
  int SetZbufferData( int x1, int y1, int x2, int y2,
120
                              vtkFloatArray *buffer ) override;
121
  //@}
Ken Martin's avatar
Ken Martin committed
122

123

124 125 126
  /**
   * Activate a texture unit for this texture
   */
127
  void ActivateTexture(vtkTextureObject *);
Ken Martin's avatar
Ken Martin committed
128

129
  /**
luz.paz's avatar
luz.paz committed
130
   * Deactivate a previously activated texture
131
   */
132
  void DeactivateTexture(vtkTextureObject *);
Ken Martin's avatar
Ken Martin committed
133

134 135 136
  /**
   * Get the texture unit for a given texture object
   */
137
  int GetTextureUnitForTexture(vtkTextureObject *);
Ken Martin's avatar
Ken Martin committed
138

139 140 141
  /**
   * Get the size of the depth buffer.
   */
142
  int GetDepthBufferSize() override;
Ken Martin's avatar
Ken Martin committed
143

144 145 146 147 148
  /**
   * Is this window/fo in sRGB colorspace
   */
  bool GetUsingSRGBColorSpace();

149 150 151 152
  /**
   * Get the size of the color buffer.
   * Returns 0 if not able to determine otherwise sets R G B and A into buffer.
   */
153
  int GetColorBufferSizes(int *rgba) override;
Ken Martin's avatar
Ken Martin committed
154

155 156 157 158 159 160 161
  /**
   * Get the internal format of current attached texture or render buffer.
   * attachmentPoint is the index of attachment.
   * Returns 0 if not able to determine.
   */
  int GetColorBufferInternalFormat(int attachmentPoint);

162 163 164 165
  //@{
  /**
   * Set the size of the window in screen coordinates in pixels.
   */
166 167
  void SetSize(int a[2]) override;
  void SetSize(int,int) override;
168
  //@}
169

170 171 172
  /**
   * Initialize OpenGL for this window.
   */
Ken Martin's avatar
Ken Martin committed
173 174 175 176 177 178 179 180
  virtual void OpenGLInit();

  // Initialize the state of OpenGL that VTK wants for this window
  virtual void OpenGLInitState();

  // Initialize VTK for rendering in a new OpenGL context
  virtual void OpenGLInitContext();

181 182 183 184 185
  /**
   * Get the major and minor version numbers of the OpenGL context we are using
   * ala 3.2, 3.3, 4.0, etc... returns 0,0 if opengl has not been initialized
   * yet
   */
186 187
  void GetOpenGLVersion(int &major, int &minor);

188 189 190 191 192 193 194
  /**
   * Return the OpenGL name of the back left buffer.
   * It is GL_BACK_LEFT if GL is bound to the window-system-provided
   * framebuffer. It is vtkgl::COLOR_ATTACHMENT0_EXT if GL is bound to an
   * application-created framebuffer object (GPU-based offscreen rendering)
   * It is used by vtkOpenGLCamera.
   */
Ken Martin's avatar
Ken Martin committed
195 196
  unsigned int GetBackLeftBuffer();

197 198 199 200 201 202 203
  /**
   * Return the OpenGL name of the back right buffer.
   * It is GL_BACK_RIGHT if GL is bound to the window-system-provided
   * framebuffer. It is vtkgl::COLOR_ATTACHMENT0_EXT+1 if GL is bound to an
   * application-created framebuffer object (GPU-based offscreen rendering)
   * It is used by vtkOpenGLCamera.
   */
Ken Martin's avatar
Ken Martin committed
204 205
  unsigned int GetBackRightBuffer();

206 207 208 209 210 211 212
  /**
   * Return the OpenGL name of the front left buffer.
   * It is GL_FRONT_LEFT if GL is bound to the window-system-provided
   * framebuffer. It is vtkgl::COLOR_ATTACHMENT0_EXT if GL is bound to an
   * application-created framebuffer object (GPU-based offscreen rendering)
   * It is used by vtkOpenGLCamera.
   */
Ken Martin's avatar
Ken Martin committed
213 214
  unsigned int GetFrontLeftBuffer();

215 216 217 218 219 220 221
  /**
   * Return the OpenGL name of the front right buffer.
   * It is GL_FRONT_RIGHT if GL is bound to the window-system-provided
   * framebuffer. It is vtkgl::COLOR_ATTACHMENT0_EXT+1 if GL is bound to an
   * application-created framebuffer object (GPU-based offscreen rendering)
   * It is used by vtkOpenGLCamera.
   */
Ken Martin's avatar
Ken Martin committed
222 223
  unsigned int GetFrontRightBuffer();

224 225 226 227 228 229 230
  /**
   * Return the OpenGL name of the back left buffer.
   * It is GL_BACK if GL is bound to the window-system-provided
   * framebuffer. It is vtkgl::COLOR_ATTACHMENT0_EXT if GL is bound to an
   * application-created framebuffer object (GPU-based offscreen rendering)
   * It is used by vtkOpenGLCamera.
   */
Ken Martin's avatar
Ken Martin committed
231 232
  unsigned int GetBackBuffer();

233 234 235 236 237 238 239
  /**
   * Return the OpenGL name of the front left buffer.
   * It is GL_FRONT if GL is bound to the window-system-provided
   * framebuffer. It is vtkgl::COLOR_ATTACHMENT0_EXT if GL is bound to an
   * application-created framebuffer object (GPU-based offscreen rendering)
   * It is used by vtkOpenGLCamera.
   */
Ken Martin's avatar
Ken Martin committed
240 241
  unsigned int GetFrontBuffer();

242 243 244
  /**
   * Get the time when the OpenGL context was created.
   */
245
  virtual vtkMTimeType GetContextCreationTime();
Ken Martin's avatar
Ken Martin committed
246

247 248 249 250
  //@{
  /**
   * Returns an Shader Cache object
   */
251
  vtkGetObjectMacro(ShaderCache,vtkOpenGLShaderCache);
252
  //@}
253

254 255 256 257 258 259 260
  //@{
  /**
   * Returns an Shader Cache object
   */
  vtkGetObjectMacro(VBOCache,vtkOpenGLVertexBufferObjectCache);
  //@}

261 262 263 264 265 266 267
  //@{
  /**
   * Returns the current default FBO (0 when OffScreenRendering is inactive).
   */
  vtkGetMacro(FrameBufferObject, unsigned int);
  //@}

268 269 270 271
  /**
   * Returns its texture unit manager object. A new one will be created if one
   * hasn't already been set up.
   */
272
  vtkTextureUnitManager *GetTextureUnitManager();
Ken Martin's avatar
Ken Martin committed
273

274 275 276 277
  /**
   * Block the thread until the actual rendering is finished().
   * Useful for measurement only.
   */
278
  void WaitForCompletion() override;
Ken Martin's avatar
Ken Martin committed
279

280 281 282
  /**
   * Replacement for the old glDrawPixels function
   */
283 284 285
  virtual void DrawPixels(int x1, int y1, int x2, int y2,
              int numComponents, int dataType, void *data);

286 287 288 289
  /**
   * Replacement for the old glDrawPixels function, but it allows
   * for scaling the data and using only part of the texture
   */
290 291 292 293 294
  virtual void DrawPixels(
    int dstXmin, int dstYmin, int dstXmax, int dstYmax,
    int srcXmin, int srcYmin, int srcXmax, int srcYmax,
    int srcWidth, int srcHeight, int numComponents, int dataType, void *data);

295 296 297 298
  /**
   * Replacement for the old glDrawPixels function.  This simple version draws all
   * the data to the entire current viewport scaling as needed.
   */
299 300
  virtual void DrawPixels(
    int srcWidth, int srcHeight, int numComponents, int dataType, void *data);
301

302 303 304
  /**
   * Return the largest line width supported by the hardware
   */
305 306 307
  virtual float GetMaximumHardwareLineWidth() {
    return this->MaximumHardwareLineWidth; };

308 309 310 311 312 313
  /**
   * Returns true if driver has an
   * EGL/OpenGL bug that makes vtkChartsCoreCxx-TestChartDoubleColors and other tests to fail
   * because point sprites don't work correctly (gl_PointCoord is undefined) unless
   * glEnable(GL_POINT_SPRITE)
   */
314 315 316 317 318
  virtual bool IsPointSpriteBugPresent()
  {
    return 0;
  }

319 320 321 322 323
  /**
   * Get a mapping of vtk data types to native texture formats for this window
   * we put this on the RenderWindow so that every texture does not have to
   * build these structures themselves
   */
324 325
  int GetDefaultTextureInternalFormat(
    int vtktype, int numComponents,
326
    bool needInteger, bool needFloat, bool needSRGB);
327

328 329 330 331 332
  /**
   * Return a message profiding additional details about the
   * results of calling SupportsOpenGL()  This can be used
   * to retrieve more specifics about what failed
   */
333 334 335 336 337
  std::string GetOpenGLSupportMessage()
  {
    return this->OpenGLSupportMessage;
  }

338 339 340 341 342 343
  // Create and bind offscreen rendering buffers without destroying the current
  // OpenGL context. This allows to temporary switch to offscreen rendering
  // (ie. to make a screenshot even if the window is hidden).
  // Return if the creation was successful (1) or not (0).
  // Note: This function requires that the device supports OpenGL framebuffer extension.
  // The function has no effect if OffScreenRendering is ON.
344 345
  int SetUseOffScreenBuffers(bool offScreen) override;
  bool GetUseOffScreenBuffers() override;
346

347 348 349
  /**
   * Does this render window support OpenGL? 0-false, 1-true
   */
350
  int SupportsOpenGL() override;
351

352 353 354
  /**
   * Get report of capabilities for the render window
   */
355
  const char *ReportCapabilities() override;
356

357 358 359 360 361 362
  /**
   * Initialize the rendering window.  This will setup all system-specific
   * resources.  This method and Finalize() must be symmetric and it
   * should be possible to call them multiple times, even changing WindowId
   * in-between.  This is what WindowRemap does.
   */
363 364
  virtual void Initialize(void) {};

365 366 367 368 369 370
  std::set<vtkGenericOpenGLResourceFreeCallback *> Resources;

  void RegisterGraphicsResources(vtkGenericOpenGLResourceFreeCallback *cb) {
    std::set<vtkGenericOpenGLResourceFreeCallback *>::iterator it
     = this->Resources.find(cb);
    if (it == this->Resources.end())
371
    {
372
      this->Resources.insert(cb);
373
    }
374 375 376 377 378 379
  }

  void UnregisterGraphicsResources(vtkGenericOpenGLResourceFreeCallback *cb) {
    std::set<vtkGenericOpenGLResourceFreeCallback *>::iterator it
     = this->Resources.find(cb);
    if (it != this->Resources.end())
380
    {
381
      this->Resources.erase(it);
382
    }
383 384
  }

385 386 387 388 389 390 391 392 393
  /**
   * Ability to push and pop this window's context
   * as the current context. The idea being to
   * if needed make this window's context current
   * and when done releasing resources restore
   * the prior context.  The default implementation
   * here is only meant as a backup for subclasses
   * that lack a proper implementation.
   */
394 395 396
  virtual void PushContext() { this->MakeCurrent(); }
  virtual void PopContext() {}

397 398 399 400
  /**
   * Initialize the render window from the information associated
   * with the currently activated OpenGL context.
   */
401
  bool InitializeFromCurrentContext() override;
402

403 404 405 406 407 408 409 410 411
  /**
   * Returns the id for the frame buffer object, if any, used by the render window
   * in which the window does all its rendering. This may be 0, in which case
   * the render window is rendering to the default OpenGL render buffers.
   *
   * @returns the name (or id) of the frame buffer object to render to.
   */
  vtkGetMacro(DefaultFrameBufferId, unsigned int);

412 413 414 415
  /**
   * Set the number of vertical syncs required between frames.
   * A value of 0 means swap buffers as quickly as possible
   * regardless of the vertical refresh. A value of 1 means swap
luz.paz's avatar
luz.paz committed
416
   * buffers in sync with the vertical refresh to eliminate tearing.
417 418 419 420 421 422
   * A value of -1 means use a value of 1 unless we missed a frame
   * in which case swap immediately. Returns true if the call
   * succeeded.
   */
  virtual bool SetSwapControl(int ) { return false; }

423 424 425 426 427
  // Get the state object used to keep track of
  // OpenGL state
  virtual vtkOpenGLState *GetState() {
    return this->State; }

428 429 430 431 432
  // Get a VBO that can be shared by many
  // It consists of normalized display
  // coordinates for a quad and tcoords
  vtkOpenGLBufferObject *GetTQuad2DVBO();

433 434 435 436 437 438
  // Activate and return thje texture unit for a generic 2d 64x64
  // float greyscale noise texture ranging from 0 to 1. The texture is
  // generated using PerlinNoise.  This textur eunit will automatically
  // be deactivated at the end of the render process.
  int GetNoiseTextureUnit();

439 440 441 442 443 444 445 446 447 448 449 450
  /**
   * Update the system, if needed, due to stereo rendering. For some stereo
   * methods, subclasses might need to switch some hardware settings here.
   */
  void StereoUpdate() override;

  /**
   * Intermediate method performs operations required between the rendering
   * of the left and right eye.
   */
  void StereoMidpoint() override;

451 452 453 454 455
  /**
   * Handle opengl specific code and calls superclass
   */
  void Render() override;

Ken Martin's avatar
Ken Martin committed
456
protected:
457
  vtkOpenGLRenderWindow();
458
  ~vtkOpenGLRenderWindow() override;
Ken Martin's avatar
Ken Martin committed
459

460
  vtkOpenGLShaderCache *ShaderCache;
461
  vtkOpenGLVertexBufferObjectCache *VBOCache;
462

463 464
  vtkOpenGLState *State;

465 466 467 468 469 470
  // used in testing for opengl support
  // in the SupportsOpenGL() method
  bool OpenGLSupportTested;
  int OpenGLSupportResult;
  std::string OpenGLSupportMessage;

471 472 473
  int TextureInternalFormats[VTK_UNICODE_STRING][3][5];
  void InitializeTextureInternalFormats();

474
  std::map<const vtkTextureObject *, int> TextureResourceIds;
Ken Martin's avatar
Ken Martin committed
475

476
  virtual int ReadPixels(const vtkRecti& rect, int front, int glFormat, int glType, void* data, int right=0);
Ken Martin's avatar
Ken Martin committed
477

478
  /**
479
   * Create an offScreen window based on OpenGL framebuffer extension.
480 481 482
   * Return if the creation was successful or not.
   * \pre positive_width: width>0
   * \pre positive_height: height>0
483 484 485
   * \pre not_initialized: !OffScreenUseFrameBuffer
   * \post valid_result: (result==0 || result==1)
   * && (result implies OffScreenUseFrameBuffer)
486
   */
487 488 489 490 491 492 493 494 495 496 497 498 499 500
  int CreateHardwareOffScreenWindow(int width, int height);

  int CreateHardwareOffScreenBuffers(int width, int height, bool bind = false);
  void BindHardwareOffScreenBuffers();

  /**
   * Destroy an offscreen window based on OpenGL framebuffer extension.
   * \pre initialized: OffScreenUseFrameBuffer
   * \post destroyed: !OffScreenUseFrameBuffer
   */
  void DestroyHardwareOffScreenWindow();

  void UnbindHardwareOffScreenBuffers();
  void DestroyHardwareOffScreenBuffers();
501

502
  /**
503
   * Flag telling if a framebuffer-based offscreen is currently in use.
504
   */
505
  int OffScreenUseFrameBuffer;
Ken Martin's avatar
Ken Martin committed
506

507
  //@{
508
  /**
509
   * Variables used by the framebuffer-based offscreen method.
510
   */
511 512 513 514 515 516 517
  int NumberOfFrameBuffers;
  unsigned int TextureObjects[4]; // really GLuint
  unsigned int FrameBufferObject; // really GLuint
  unsigned int DepthRenderBufferObject; // really GLuint
  int HardwareBufferSize[2];
  bool HardwareOffScreenBuffersBind;
  //@}
518

519 520 521
  /**
   * Create a not-off-screen window.
   */
Ken Martin's avatar
Ken Martin committed
522 523
  virtual void CreateAWindow() = 0;

524 525 526
  /**
   * Destroy a not-off-screen window.
   */
Ken Martin's avatar
Ken Martin committed
527 528
  virtual void DestroyWindow() = 0;

529 530 531 532
  /**
   * Free up any graphics resources associated with this window
   * a value of NULL means the context may already be destroyed
   */
533
  virtual void ReleaseGraphicsResources(vtkRenderWindow *);
534

535 536 537
  /**
   * Set the texture unit manager.
   */
538
  void SetTextureUnitManager(vtkTextureUnitManager *textureUnitManager);
Ken Martin's avatar
Ken Martin committed
539

540

541 542 543
  /**
   * Query and save OpenGL state
   */
544 545
  void SaveGLState();

546 547 548
  /**
   * Restore OpenGL state at end of the rendering
   */
549 550 551 552
  void RestoreGLState();

  std::map<std::string, int> GLStateIntegers;

Ken Martin's avatar
Ken Martin committed
553 554 555 556 557 558
  unsigned int BackLeftBuffer;
  unsigned int BackRightBuffer;
  unsigned int FrontLeftBuffer;
  unsigned int FrontRightBuffer;
  unsigned int FrontBuffer;
  unsigned int BackBuffer;
559
  unsigned int DefaultFrameBufferId;
Ken Martin's avatar
Ken Martin committed
560

561 562 563
  /**
   * Flag telling if the context has been created here or was inherited.
   */
Ken Martin's avatar
Ken Martin committed
564 565 566 567
  int OwnContext;

  vtkTimeStamp ContextCreationTime;

568
  vtkTextureUnitManager *TextureUnitManager;
Ken Martin's avatar
Ken Martin committed
569

570
  vtkTextureObject *DrawPixelsTextureObject;
571

572
  bool Initialized; // ensure glewinit has been called
573
  bool GlewInitValid; // Did glewInit initialize with a valid state?
574

575 576
  float MaximumHardwareLineWidth;

577 578
  char *Capabilities;

579 580 581
  // used for fast quad rendering
  vtkOpenGLBufferObject *TQuad2DVBO;

582 583 584
  // noise texture
  vtkTextureObject *NoiseTextureObject;

Ken Martin's avatar
Ken Martin committed
585
private:
586 587
  vtkOpenGLRenderWindow(const vtkOpenGLRenderWindow&) = delete;
  void operator=(const vtkOpenGLRenderWindow&) = delete;
Ken Martin's avatar
Ken Martin committed
588 589 590
};

#endif