You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
533 lines
16 KiB
C++
533 lines
16 KiB
C++
/*=========================================================================
|
|
|
|
Program: Visualization Toolkit
|
|
Module: vtkOpenGLRenderWindow.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 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.
|
|
*/
|
|
|
|
#ifndef vtkOpenGLRenderWindow_h
|
|
#define vtkOpenGLRenderWindow_h
|
|
|
|
#include "vtkRect.h" // for vtkRecti
|
|
#include "vtkRenderWindow.h"
|
|
#include "vtkRenderingOpenGL2Module.h" // For export macro
|
|
#include "vtkType.h" // for ivar
|
|
#include <map> // for ivar
|
|
#include <set> // for ivar
|
|
#include <string> // for ivar
|
|
|
|
class vtkIdList;
|
|
class vtkOpenGLBufferObject;
|
|
class vtkOpenGLFramebufferObject;
|
|
class vtkOpenGLHardwareSupport;
|
|
class vtkOpenGLShaderCache;
|
|
class vtkOpenGLVertexBufferObjectCache;
|
|
class vtkOpenGLVertexArrayObject;
|
|
class vtkShaderProgram;
|
|
class vtkStdString;
|
|
class vtkTexture;
|
|
class vtkTextureObject;
|
|
class vtkTextureUnitManager;
|
|
class vtkGenericOpenGLResourceFreeCallback;
|
|
class vtkOpenGLState;
|
|
|
|
class VTKRENDERINGOPENGL2_EXPORT vtkOpenGLRenderWindow : public vtkRenderWindow
|
|
{
|
|
public:
|
|
vtkTypeMacro(vtkOpenGLRenderWindow, vtkRenderWindow);
|
|
void PrintSelf(ostream& os, vtkIndent indent) override;
|
|
|
|
/**
|
|
* Begin the rendering process.
|
|
*/
|
|
void Start(void) override;
|
|
|
|
/**
|
|
* A termination method performed at the end of the rendering process
|
|
* to do things like swapping buffers (if necessary) or similar actions.
|
|
*/
|
|
void Frame() override;
|
|
|
|
/**
|
|
* What rendering backend has the user requested
|
|
*/
|
|
const char* GetRenderingBackend() override;
|
|
|
|
//@{
|
|
/**
|
|
* Set/Get the maximum number of multisamples
|
|
*/
|
|
static void SetGlobalMaximumNumberOfMultiSamples(int val);
|
|
static int GetGlobalMaximumNumberOfMultiSamples();
|
|
//@}
|
|
|
|
//@{
|
|
/**
|
|
* Set/Get the pixel data of an image, transmitted as RGBRGB...
|
|
*/
|
|
unsigned char* GetPixelData(int x, int y, int x2, int y2, int front, int right) override;
|
|
int GetPixelData(
|
|
int x, int y, int x2, int y2, int front, vtkUnsignedCharArray* data, int right) override;
|
|
int SetPixelData(
|
|
int x, int y, int x2, int y2, unsigned char* data, int front, int right) override;
|
|
int SetPixelData(
|
|
int x, int y, int x2, int y2, vtkUnsignedCharArray* data, int front, int right) override;
|
|
//@}
|
|
|
|
//@{
|
|
/**
|
|
* Set/Get the pixel data of an image, transmitted as RGBARGBA...
|
|
*/
|
|
float* GetRGBAPixelData(int x, int y, int x2, int y2, int front, int right = 0) override;
|
|
int GetRGBAPixelData(
|
|
int x, int y, int x2, int y2, int front, vtkFloatArray* data, int right = 0) override;
|
|
int SetRGBAPixelData(
|
|
int x, int y, int x2, int y2, float* data, int front, int blend = 0, int right = 0) override;
|
|
int SetRGBAPixelData(int x, int y, int x2, int y2, vtkFloatArray* data, int front, int blend = 0,
|
|
int right = 0) override;
|
|
void ReleaseRGBAPixelData(float* data) override;
|
|
unsigned char* GetRGBACharPixelData(
|
|
int x, int y, int x2, int y2, int front, int right = 0) override;
|
|
int GetRGBACharPixelData(
|
|
int x, int y, int x2, int y2, int front, vtkUnsignedCharArray* data, int right = 0) override;
|
|
int SetRGBACharPixelData(int x, int y, int x2, int y2, unsigned char* data, int front,
|
|
int blend = 0, int right = 0) override;
|
|
int SetRGBACharPixelData(int x, int y, int x2, int y2, vtkUnsignedCharArray* data, int front,
|
|
int blend = 0, int right = 0) override;
|
|
//@}
|
|
|
|
//@{
|
|
/**
|
|
* Set/Get the zbuffer data from an image
|
|
*/
|
|
float* GetZbufferData(int x1, int y1, int x2, int y2) override;
|
|
int GetZbufferData(int x1, int y1, int x2, int y2, float* z) override;
|
|
int GetZbufferData(int x1, int y1, int x2, int y2, vtkFloatArray* z) override;
|
|
int SetZbufferData(int x1, int y1, int x2, int y2, float* buffer) override;
|
|
int SetZbufferData(int x1, int y1, int x2, int y2, vtkFloatArray* buffer) override;
|
|
//@}
|
|
|
|
/**
|
|
* Activate a texture unit for this texture
|
|
*/
|
|
void ActivateTexture(vtkTextureObject*);
|
|
|
|
/**
|
|
* Deactivate a previously activated texture
|
|
*/
|
|
void DeactivateTexture(vtkTextureObject*);
|
|
|
|
/**
|
|
* Get the texture unit for a given texture object
|
|
*/
|
|
int GetTextureUnitForTexture(vtkTextureObject*);
|
|
|
|
/**
|
|
* Get the size of the depth buffer.
|
|
*/
|
|
int GetDepthBufferSize() override;
|
|
|
|
/**
|
|
* Is this window/fo in sRGB colorspace
|
|
*/
|
|
bool GetUsingSRGBColorSpace();
|
|
|
|
/**
|
|
* Get the size of the color buffer.
|
|
* Returns 0 if not able to determine otherwise sets R G B and A into buffer.
|
|
*/
|
|
int GetColorBufferSizes(int* rgba) override;
|
|
|
|
/**
|
|
* 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);
|
|
|
|
//@{
|
|
/**
|
|
* Set the size (width and height) of the rendering window in
|
|
* screen coordinates (in pixels). This resizes the operating
|
|
* system's view/window and redraws it.
|
|
*
|
|
* If the size has changed, this method will fire
|
|
* vtkCommand::WindowResizeEvent.
|
|
*/
|
|
void SetSize(int width, int height) override;
|
|
void SetSize(int a[2]) override { this->SetSize(a[0], a[1]); }
|
|
//@}
|
|
|
|
/**
|
|
* Initialize OpenGL for this window.
|
|
*/
|
|
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();
|
|
|
|
/**
|
|
* 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
|
|
*/
|
|
void GetOpenGLVersion(int& major, int& minor);
|
|
|
|
/**
|
|
* 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.
|
|
*/
|
|
unsigned int GetBackLeftBuffer();
|
|
|
|
/**
|
|
* 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.
|
|
*/
|
|
unsigned int GetBackRightBuffer();
|
|
|
|
/**
|
|
* 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.
|
|
*/
|
|
unsigned int GetFrontLeftBuffer();
|
|
|
|
/**
|
|
* 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.
|
|
*/
|
|
unsigned int GetFrontRightBuffer();
|
|
|
|
/**
|
|
* Return the OpenGL name of the back left buffer.
|
|
* Identical to GetBackLeftBuffer.
|
|
*/
|
|
unsigned int GetBackBuffer();
|
|
|
|
/**
|
|
* Return the OpenGL name of the front left buffer.
|
|
* Identical to GetFrontLeftBuffer.
|
|
*/
|
|
unsigned int GetFrontBuffer();
|
|
|
|
/**
|
|
* Get the time when the OpenGL context was created.
|
|
*/
|
|
virtual vtkMTimeType GetContextCreationTime();
|
|
|
|
/**
|
|
* Returns an Shader Cache object
|
|
*/
|
|
vtkOpenGLShaderCache* GetShaderCache();
|
|
|
|
/**
|
|
* Returns the VBO Cache
|
|
*/
|
|
vtkOpenGLVertexBufferObjectCache* GetVBOCache();
|
|
|
|
//@{
|
|
/**
|
|
* Returns the offscreen framebuffer object if any
|
|
*/
|
|
vtkGetObjectMacro(OffScreenFramebuffer, vtkOpenGLFramebufferObject);
|
|
//@}
|
|
|
|
/**
|
|
* Returns its texture unit manager object. A new one will be created if one
|
|
* hasn't already been set up.
|
|
*/
|
|
vtkTextureUnitManager* GetTextureUnitManager();
|
|
|
|
/**
|
|
* Block the thread until the actual rendering is finished().
|
|
* Useful for measurement only.
|
|
*/
|
|
void WaitForCompletion() override;
|
|
|
|
/**
|
|
* Replacement for the old glDrawPixels function
|
|
*/
|
|
virtual void DrawPixels(
|
|
int x1, int y1, int x2, int y2, int numComponents, int dataType, void* data);
|
|
|
|
/**
|
|
* Replacement for the old glDrawPixels function, but it allows
|
|
* for scaling the data and using only part of the texture
|
|
*/
|
|
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);
|
|
|
|
/**
|
|
* Replacement for the old glDrawPixels function. This simple version draws all
|
|
* the data to the entire current viewport scaling as needed.
|
|
*/
|
|
virtual void DrawPixels(int srcWidth, int srcHeight, int numComponents, int dataType, void* data);
|
|
|
|
/**
|
|
* Return the largest line width supported by the hardware
|
|
*/
|
|
virtual float GetMaximumHardwareLineWidth() { return this->MaximumHardwareLineWidth; }
|
|
|
|
/**
|
|
* 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)
|
|
*/
|
|
virtual bool IsPointSpriteBugPresent() { return 0; }
|
|
|
|
/**
|
|
* 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
|
|
*/
|
|
int GetDefaultTextureInternalFormat(
|
|
int vtktype, int numComponents, bool needInteger, bool needFloat, bool needSRGB);
|
|
|
|
/**
|
|
* Return a message profiding additional details about the
|
|
* results of calling SupportsOpenGL() This can be used
|
|
* to retrieve more specifics about what failed
|
|
*/
|
|
std::string GetOpenGLSupportMessage() { return this->OpenGLSupportMessage; }
|
|
|
|
/**
|
|
* Does this render window support OpenGL? 0-false, 1-true
|
|
*/
|
|
int SupportsOpenGL() override;
|
|
|
|
/**
|
|
* Get report of capabilities for the render window
|
|
*/
|
|
const char* ReportCapabilities() override;
|
|
|
|
/**
|
|
* 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.
|
|
*/
|
|
virtual void Initialize(void) {}
|
|
|
|
std::set<vtkGenericOpenGLResourceFreeCallback*> Resources;
|
|
|
|
void RegisterGraphicsResources(vtkGenericOpenGLResourceFreeCallback* cb)
|
|
{
|
|
std::set<vtkGenericOpenGLResourceFreeCallback*>::iterator it = this->Resources.find(cb);
|
|
if (it == this->Resources.end())
|
|
{
|
|
this->Resources.insert(cb);
|
|
}
|
|
}
|
|
|
|
void UnregisterGraphicsResources(vtkGenericOpenGLResourceFreeCallback* cb)
|
|
{
|
|
std::set<vtkGenericOpenGLResourceFreeCallback*>::iterator it = this->Resources.find(cb);
|
|
if (it != this->Resources.end())
|
|
{
|
|
this->Resources.erase(it);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 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.
|
|
*/
|
|
virtual void PushContext() { this->MakeCurrent(); }
|
|
virtual void PopContext() {}
|
|
|
|
/**
|
|
* Initialize the render window from the information associated
|
|
* with the currently activated OpenGL context.
|
|
*/
|
|
bool InitializeFromCurrentContext() override;
|
|
|
|
/**
|
|
* 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);
|
|
|
|
/**
|
|
* 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
|
|
* buffers in sync with the vertical refresh to eliminate tearing.
|
|
* 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; }
|
|
|
|
// Get the state object used to keep track of
|
|
// OpenGL state
|
|
virtual vtkOpenGLState* GetState() { return this->State; }
|
|
|
|
// Get a VBO that can be shared by many
|
|
// It consists of normalized display
|
|
// coordinates for a quad and tcoords
|
|
vtkOpenGLBufferObject* GetTQuad2DVBO();
|
|
|
|
// 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();
|
|
|
|
/**
|
|
* Update the system, if needed, at end of render process
|
|
*/
|
|
void End() override;
|
|
|
|
/**
|
|
* Handle opengl specific code and calls superclass
|
|
*/
|
|
void Render() override;
|
|
|
|
/**
|
|
* Intermediate method performs operations required between the rendering
|
|
* of the left and right eye.
|
|
*/
|
|
void StereoMidpoint() override;
|
|
|
|
// does VTKs framebuffer require resolving for reading pixels
|
|
bool GetBufferNeedsResolving();
|
|
|
|
/**
|
|
* Free up any graphics resources associated with this window
|
|
* a value of NULL means the context may already be destroyed
|
|
*/
|
|
void ReleaseGraphicsResources(vtkWindow*) override;
|
|
|
|
protected:
|
|
vtkOpenGLRenderWindow();
|
|
~vtkOpenGLRenderWindow() override;
|
|
|
|
// used in testing for opengl support
|
|
// in the SupportsOpenGL() method
|
|
bool OpenGLSupportTested;
|
|
int OpenGLSupportResult;
|
|
std::string OpenGLSupportMessage;
|
|
|
|
virtual int ReadPixels(
|
|
const vtkRecti& rect, int front, int glFormat, int glType, void* data, int right = 0);
|
|
|
|
/**
|
|
* Create the offScreen framebuffer
|
|
* Return if the creation was successful or not.
|
|
* \pre positive_width: width>0
|
|
* \pre positive_height: height>0
|
|
* \pre not_initialized: !OffScreenUseFrameBuffer
|
|
* \post valid_result: (result==0 || result==1)
|
|
*/
|
|
int CreateOffScreenFramebuffer(int width, int height);
|
|
vtkOpenGLFramebufferObject* OffScreenFramebuffer;
|
|
|
|
/**
|
|
* Create a not-off-screen window.
|
|
*/
|
|
virtual void CreateAWindow() = 0;
|
|
|
|
/**
|
|
* Destroy a not-off-screen window.
|
|
*/
|
|
virtual void DestroyWindow() = 0;
|
|
|
|
/**
|
|
* Query and save OpenGL state
|
|
*/
|
|
void SaveGLState();
|
|
|
|
/**
|
|
* Restore OpenGL state at end of the rendering
|
|
*/
|
|
void RestoreGLState();
|
|
|
|
std::map<std::string, int> GLStateIntegers;
|
|
|
|
unsigned int BackLeftBuffer;
|
|
unsigned int BackRightBuffer;
|
|
unsigned int FrontLeftBuffer;
|
|
unsigned int FrontRightBuffer;
|
|
unsigned int DefaultFrameBufferId;
|
|
|
|
/**
|
|
* Flag telling if the context has been created here or was inherited.
|
|
*/
|
|
int OwnContext;
|
|
|
|
vtkTimeStamp ContextCreationTime;
|
|
|
|
vtkTextureObject* DrawPixelsTextureObject;
|
|
|
|
bool Initialized; // ensure glewinit has been called
|
|
bool GlewInitValid; // Did glewInit initialize with a valid state?
|
|
|
|
float MaximumHardwareLineWidth;
|
|
|
|
char* Capabilities;
|
|
|
|
// used for fast quad rendering
|
|
vtkOpenGLBufferObject* TQuad2DVBO;
|
|
|
|
// noise texture
|
|
vtkTextureObject* NoiseTextureObject;
|
|
|
|
double FirstRenderTime;
|
|
|
|
// keep track of in case we need to recreate the framebuffer
|
|
int LastMultiSamples;
|
|
|
|
int ScreenSize[2];
|
|
|
|
private:
|
|
vtkOpenGLRenderWindow(const vtkOpenGLRenderWindow&) = delete;
|
|
void operator=(const vtkOpenGLRenderWindow&) = delete;
|
|
|
|
// Keeping `State` private so the only way to access it is through
|
|
// `this->GetState()`.
|
|
vtkOpenGLState* State;
|
|
};
|
|
|
|
#endif
|