1 /*========================================================================= 2 3 Program: Visualization Toolkit 4 Module: vtkOpenGLRenderWindow.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 vtkOpenGLRenderWindow 17 * @brief OpenGL rendering window 18 * 19 * vtkOpenGLRenderWindow is a concrete implementation of the abstract class 20 * vtkRenderWindow. vtkOpenGLRenderer interfaces to the OpenGL graphics 21 * library. Application programmers should normally use vtkRenderWindow 22 * instead of the OpenGL specific version. 23 */ 24 25 #ifndef vtkOpenGLRenderWindow_h 26 #define vtkOpenGLRenderWindow_h 27 28 #include "vtkRect.h" // for vtkRecti 29 #include "vtkRenderWindow.h" 30 #include "vtkRenderingOpenGL2Module.h" // For export macro 31 #include "vtkType.h" // for ivar 32 #include <map> // for ivar 33 #include <set> // for ivar 34 #include <string> // for ivar 35 36 class vtkIdList; 37 class vtkOpenGLBufferObject; 38 class vtkOpenGLHardwareSupport; 39 class vtkOpenGLShaderCache; 40 class vtkOpenGLVertexBufferObjectCache; 41 class vtkOpenGLVertexArrayObject; 42 class vtkShaderProgram; 43 class vtkStdString; 44 class vtkTexture; 45 class vtkTextureObject; 46 class vtkTextureUnitManager; 47 class vtkGenericOpenGLResourceFreeCallback; 48 class vtkOpenGLState; 49 50 class VTKRENDERINGOPENGL2_EXPORT vtkOpenGLRenderWindow : public vtkRenderWindow 51 { 52 public: 53 vtkTypeMacro(vtkOpenGLRenderWindow, vtkRenderWindow); 54 void PrintSelf(ostream& os, vtkIndent indent) override; 55 56 /** 57 * What rendering backend has the user requested 58 */ 59 const char *GetRenderingBackend() override; 60 61 //@{ 62 /** 63 * Set/Get the maximum number of multisamples 64 */ 65 static void SetGlobalMaximumNumberOfMultiSamples(int val); 66 static int GetGlobalMaximumNumberOfMultiSamples(); 67 //@} 68 69 //@{ 70 /** 71 * Set/Get the pixel data of an image, transmitted as RGBRGB... 72 */ 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 //@} 83 84 //@{ 85 /** 86 * Set/Get the pixel data of an image, transmitted as RGBARGBA... 87 */ 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 int front, int blend=0, int right=0) override; 96 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 //@} 109 110 //@{ 111 /** 112 * Set/Get the zbuffer data from an image 113 */ 114 float *GetZbufferData( int x1, int y1, int x2, int y2 ) override; 115 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 vtkFloatArray* z ) override; 118 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 //@} 122 123 124 /** 125 * Activate a texture unit for this texture 126 */ 127 void ActivateTexture(vtkTextureObject *); 128 129 /** 130 * Deactivate a previously activated texture 131 */ 132 void DeactivateTexture(vtkTextureObject *); 133 134 /** 135 * Get the texture unit for a given texture object 136 */ 137 int GetTextureUnitForTexture(vtkTextureObject *); 138 139 /** 140 * Get the size of the depth buffer. 141 */ 142 int GetDepthBufferSize() override; 143 144 /** 145 * Is this window/fo in sRGB colorspace 146 */ 147 bool GetUsingSRGBColorSpace(); 148 149 /** 150 * Get the size of the color buffer. 151 * Returns 0 if not able to determine otherwise sets R G B and A into buffer. 152 */ 153 int GetColorBufferSizes(int *rgba) override; 154 155 /** 156 * Get the internal format of current attached texture or render buffer. 157 * attachmentPoint is the index of attachment. 158 * Returns 0 if not able to determine. 159 */ 160 int GetColorBufferInternalFormat(int attachmentPoint); 161 162 //@{ 163 /** 164 * Set the size of the window in screen coordinates in pixels. 165 */ 166 void SetSize(int a[2]) override; 167 void SetSize(int,int) override; 168 //@} 169 170 /** 171 * Initialize OpenGL for this window. 172 */ 173 virtual void OpenGLInit(); 174 175 // Initialize the state of OpenGL that VTK wants for this window 176 virtual void OpenGLInitState(); 177 178 // Initialize VTK for rendering in a new OpenGL context 179 virtual void OpenGLInitContext(); 180 181 /** 182 * Get the major and minor version numbers of the OpenGL context we are using 183 * ala 3.2, 3.3, 4.0, etc... returns 0,0 if opengl has not been initialized 184 * yet 185 */ 186 void GetOpenGLVersion(int &major, int &minor); 187 188 /** 189 * Return the OpenGL name of the back left buffer. 190 * It is GL_BACK_LEFT if GL is bound to the window-system-provided 191 * framebuffer. It is vtkgl::COLOR_ATTACHMENT0_EXT if GL is bound to an 192 * application-created framebuffer object (GPU-based offscreen rendering) 193 * It is used by vtkOpenGLCamera. 194 */ 195 unsigned int GetBackLeftBuffer(); 196 197 /** 198 * Return the OpenGL name of the back right buffer. 199 * It is GL_BACK_RIGHT if GL is bound to the window-system-provided 200 * framebuffer. It is vtkgl::COLOR_ATTACHMENT0_EXT+1 if GL is bound to an 201 * application-created framebuffer object (GPU-based offscreen rendering) 202 * It is used by vtkOpenGLCamera. 203 */ 204 unsigned int GetBackRightBuffer(); 205 206 /** 207 * Return the OpenGL name of the front left buffer. 208 * It is GL_FRONT_LEFT if GL is bound to the window-system-provided 209 * framebuffer. It is vtkgl::COLOR_ATTACHMENT0_EXT if GL is bound to an 210 * application-created framebuffer object (GPU-based offscreen rendering) 211 * It is used by vtkOpenGLCamera. 212 */ 213 unsigned int GetFrontLeftBuffer(); 214 215 /** 216 * Return the OpenGL name of the front right buffer. 217 * It is GL_FRONT_RIGHT if GL is bound to the window-system-provided 218 * framebuffer. It is vtkgl::COLOR_ATTACHMENT0_EXT+1 if GL is bound to an 219 * application-created framebuffer object (GPU-based offscreen rendering) 220 * It is used by vtkOpenGLCamera. 221 */ 222 unsigned int GetFrontRightBuffer(); 223 224 /** 225 * Return the OpenGL name of the back left buffer. 226 * It is GL_BACK if GL is bound to the window-system-provided 227 * framebuffer. It is vtkgl::COLOR_ATTACHMENT0_EXT if GL is bound to an 228 * application-created framebuffer object (GPU-based offscreen rendering) 229 * It is used by vtkOpenGLCamera. 230 */ 231 unsigned int GetBackBuffer(); 232 233 /** 234 * Return the OpenGL name of the front left buffer. 235 * It is GL_FRONT if GL is bound to the window-system-provided 236 * framebuffer. It is vtkgl::COLOR_ATTACHMENT0_EXT if GL is bound to an 237 * application-created framebuffer object (GPU-based offscreen rendering) 238 * It is used by vtkOpenGLCamera. 239 */ 240 unsigned int GetFrontBuffer(); 241 242 /** 243 * Get the time when the OpenGL context was created. 244 */ 245 virtual vtkMTimeType GetContextCreationTime(); 246 247 //@{ 248 /** 249 * Returns an Shader Cache object 250 */ 251 vtkGetObjectMacro(ShaderCache,vtkOpenGLShaderCache); 252 //@} 253 254 //@{ 255 /** 256 * Returns an Shader Cache object 257 */ 258 vtkGetObjectMacro(VBOCache,vtkOpenGLVertexBufferObjectCache); 259 //@} 260 261 //@{ 262 /** 263 * Returns the current default FBO (0 when OffScreenRendering is inactive). 264 */ 265 vtkGetMacro(FrameBufferObject, unsigned int); 266 //@} 267 268 /** 269 * Returns its texture unit manager object. A new one will be created if one 270 * hasn't already been set up. 271 */ 272 vtkTextureUnitManager *GetTextureUnitManager(); 273 274 /** 275 * Block the thread until the actual rendering is finished(). 276 * Useful for measurement only. 277 */ 278 void WaitForCompletion() override; 279 280 /** 281 * Replacement for the old glDrawPixels function 282 */ 283 virtual void DrawPixels(int x1, int y1, int x2, int y2, 284 int numComponents, int dataType, void *data); 285 286 /** 287 * Replacement for the old glDrawPixels function, but it allows 288 * for scaling the data and using only part of the texture 289 */ 290 virtual void DrawPixels( 291 int dstXmin, int dstYmin, int dstXmax, int dstYmax, 292 int srcXmin, int srcYmin, int srcXmax, int srcYmax, 293 int srcWidth, int srcHeight, int numComponents, int dataType, void *data); 294 295 /** 296 * Replacement for the old glDrawPixels function. This simple version draws all 297 * the data to the entire current viewport scaling as needed. 298 */ 299 virtual void DrawPixels( 300 int srcWidth, int srcHeight, int numComponents, int dataType, void *data); 301 302 /** 303 * Return the largest line width supported by the hardware 304 */ GetMaximumHardwareLineWidth()305 virtual float GetMaximumHardwareLineWidth() { 306 return this->MaximumHardwareLineWidth; }; 307 308 /** 309 * Returns true if driver has an 310 * EGL/OpenGL bug that makes vtkChartsCoreCxx-TestChartDoubleColors and other tests to fail 311 * because point sprites don't work correctly (gl_PointCoord is undefined) unless 312 * glEnable(GL_POINT_SPRITE) 313 */ IsPointSpriteBugPresent()314 virtual bool IsPointSpriteBugPresent() 315 { 316 return 0; 317 } 318 319 /** 320 * Get a mapping of vtk data types to native texture formats for this window 321 * we put this on the RenderWindow so that every texture does not have to 322 * build these structures themselves 323 */ 324 int GetDefaultTextureInternalFormat( 325 int vtktype, int numComponents, 326 bool needInteger, bool needFloat, bool needSRGB); 327 328 /** 329 * Return a message profiding additional details about the 330 * results of calling SupportsOpenGL() This can be used 331 * to retrieve more specifics about what failed 332 */ GetOpenGLSupportMessage()333 std::string GetOpenGLSupportMessage() 334 { 335 return this->OpenGLSupportMessage; 336 } 337 338 // Create and bind offscreen rendering buffers without destroying the current 339 // OpenGL context. This allows to temporary switch to offscreen rendering 340 // (ie. to make a screenshot even if the window is hidden). 341 // Return if the creation was successful (1) or not (0). 342 // Note: This function requires that the device supports OpenGL framebuffer extension. 343 // The function has no effect if OffScreenRendering is ON. 344 int SetUseOffScreenBuffers(bool offScreen) override; 345 bool GetUseOffScreenBuffers() override; 346 347 /** 348 * Does this render window support OpenGL? 0-false, 1-true 349 */ 350 int SupportsOpenGL() override; 351 352 /** 353 * Get report of capabilities for the render window 354 */ 355 const char *ReportCapabilities() override; 356 357 /** 358 * Initialize the rendering window. This will setup all system-specific 359 * resources. This method and Finalize() must be symmetric and it 360 * should be possible to call them multiple times, even changing WindowId 361 * in-between. This is what WindowRemap does. 362 */ Initialize(void)363 virtual void Initialize(void) {}; 364 365 std::set<vtkGenericOpenGLResourceFreeCallback *> Resources; 366 RegisterGraphicsResources(vtkGenericOpenGLResourceFreeCallback * cb)367 void RegisterGraphicsResources(vtkGenericOpenGLResourceFreeCallback *cb) { 368 std::set<vtkGenericOpenGLResourceFreeCallback *>::iterator it 369 = this->Resources.find(cb); 370 if (it == this->Resources.end()) 371 { 372 this->Resources.insert(cb); 373 } 374 } 375 UnregisterGraphicsResources(vtkGenericOpenGLResourceFreeCallback * cb)376 void UnregisterGraphicsResources(vtkGenericOpenGLResourceFreeCallback *cb) { 377 std::set<vtkGenericOpenGLResourceFreeCallback *>::iterator it 378 = this->Resources.find(cb); 379 if (it != this->Resources.end()) 380 { 381 this->Resources.erase(it); 382 } 383 } 384 385 /** 386 * Ability to push and pop this window's context 387 * as the current context. The idea being to 388 * if needed make this window's context current 389 * and when done releasing resources restore 390 * the prior context. The default implementation 391 * here is only meant as a backup for subclasses 392 * that lack a proper implementation. 393 */ PushContext()394 virtual void PushContext() { this->MakeCurrent(); } PopContext()395 virtual void PopContext() {} 396 397 /** 398 * Initialize the render window from the information associated 399 * with the currently activated OpenGL context. 400 */ 401 bool InitializeFromCurrentContext() override; 402 403 /** 404 * Returns the id for the frame buffer object, if any, used by the render window 405 * in which the window does all its rendering. This may be 0, in which case 406 * the render window is rendering to the default OpenGL render buffers. 407 * 408 * @returns the name (or id) of the frame buffer object to render to. 409 */ 410 vtkGetMacro(DefaultFrameBufferId, unsigned int); 411 412 /** 413 * Set the number of vertical syncs required between frames. 414 * A value of 0 means swap buffers as quickly as possible 415 * regardless of the vertical refresh. A value of 1 means swap 416 * buffers in sync with the vertical refresh to eliminate tearing. 417 * A value of -1 means use a value of 1 unless we missed a frame 418 * in which case swap immediately. Returns true if the call 419 * succeeded. 420 */ SetSwapControl(int)421 virtual bool SetSwapControl(int ) { return false; } 422 423 // Get the state object used to keep track of 424 // OpenGL state GetState()425 virtual vtkOpenGLState *GetState() { 426 return this->State; } 427 428 // Get a VBO that can be shared by many 429 // It consists of normalized display 430 // coordinates for a quad and tcoords 431 vtkOpenGLBufferObject *GetTQuad2DVBO(); 432 433 // Activate and return thje texture unit for a generic 2d 64x64 434 // float greyscale noise texture ranging from 0 to 1. The texture is 435 // generated using PerlinNoise. This textur eunit will automatically 436 // be deactivated at the end of the render process. 437 int GetNoiseTextureUnit(); 438 439 /** 440 * Update the system, if needed, due to stereo rendering. For some stereo 441 * methods, subclasses might need to switch some hardware settings here. 442 */ 443 void StereoUpdate() override; 444 445 /** 446 * Intermediate method performs operations required between the rendering 447 * of the left and right eye. 448 */ 449 void StereoMidpoint() override; 450 451 /** 452 * Handle opengl specific code and calls superclass 453 */ 454 void Render() override; 455 456 protected: 457 vtkOpenGLRenderWindow(); 458 ~vtkOpenGLRenderWindow() override; 459 460 vtkOpenGLShaderCache *ShaderCache; 461 vtkOpenGLVertexBufferObjectCache *VBOCache; 462 463 vtkOpenGLState *State; 464 465 // used in testing for opengl support 466 // in the SupportsOpenGL() method 467 bool OpenGLSupportTested; 468 int OpenGLSupportResult; 469 std::string OpenGLSupportMessage; 470 471 int TextureInternalFormats[VTK_UNICODE_STRING][3][5]; 472 void InitializeTextureInternalFormats(); 473 474 std::map<const vtkTextureObject *, int> TextureResourceIds; 475 476 virtual int ReadPixels(const vtkRecti& rect, int front, int glFormat, int glType, void* data, int right=0); 477 478 /** 479 * Create an offScreen window based on OpenGL framebuffer extension. 480 * Return if the creation was successful or not. 481 * \pre positive_width: width>0 482 * \pre positive_height: height>0 483 * \pre not_initialized: !OffScreenUseFrameBuffer 484 * \post valid_result: (result==0 || result==1) 485 * && (result implies OffScreenUseFrameBuffer) 486 */ 487 int CreateHardwareOffScreenWindow(int width, int height); 488 489 int CreateHardwareOffScreenBuffers(int width, int height, bool bind = false); 490 void BindHardwareOffScreenBuffers(); 491 492 /** 493 * Destroy an offscreen window based on OpenGL framebuffer extension. 494 * \pre initialized: OffScreenUseFrameBuffer 495 * \post destroyed: !OffScreenUseFrameBuffer 496 */ 497 void DestroyHardwareOffScreenWindow(); 498 499 void UnbindHardwareOffScreenBuffers(); 500 void DestroyHardwareOffScreenBuffers(); 501 502 /** 503 * Flag telling if a framebuffer-based offscreen is currently in use. 504 */ 505 int OffScreenUseFrameBuffer; 506 507 //@{ 508 /** 509 * Variables used by the framebuffer-based offscreen method. 510 */ 511 int NumberOfFrameBuffers; 512 unsigned int TextureObjects[4]; // really GLuint 513 unsigned int FrameBufferObject; // really GLuint 514 unsigned int DepthRenderBufferObject; // really GLuint 515 int HardwareBufferSize[2]; 516 bool HardwareOffScreenBuffersBind; 517 //@} 518 519 /** 520 * Create a not-off-screen window. 521 */ 522 virtual void CreateAWindow() = 0; 523 524 /** 525 * Destroy a not-off-screen window. 526 */ 527 virtual void DestroyWindow() = 0; 528 529 /** 530 * Free up any graphics resources associated with this window 531 * a value of NULL means the context may already be destroyed 532 */ 533 virtual void ReleaseGraphicsResources(vtkRenderWindow *); 534 535 /** 536 * Set the texture unit manager. 537 */ 538 void SetTextureUnitManager(vtkTextureUnitManager *textureUnitManager); 539 540 541 /** 542 * Query and save OpenGL state 543 */ 544 void SaveGLState(); 545 546 /** 547 * Restore OpenGL state at end of the rendering 548 */ 549 void RestoreGLState(); 550 551 std::map<std::string, int> GLStateIntegers; 552 553 unsigned int BackLeftBuffer; 554 unsigned int BackRightBuffer; 555 unsigned int FrontLeftBuffer; 556 unsigned int FrontRightBuffer; 557 unsigned int FrontBuffer; 558 unsigned int BackBuffer; 559 unsigned int DefaultFrameBufferId; 560 561 /** 562 * Flag telling if the context has been created here or was inherited. 563 */ 564 int OwnContext; 565 566 vtkTimeStamp ContextCreationTime; 567 568 vtkTextureUnitManager *TextureUnitManager; 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 float MaximumHardwareLineWidth; 576 577 char *Capabilities; 578 579 // used for fast quad rendering 580 vtkOpenGLBufferObject *TQuad2DVBO; 581 582 // noise texture 583 vtkTextureObject *NoiseTextureObject; 584 585 private: 586 vtkOpenGLRenderWindow(const vtkOpenGLRenderWindow&) = delete; 587 void operator=(const vtkOpenGLRenderWindow&) = delete; 588 }; 589 590 #endif 591