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.
nmWTAI-Platform/3rd/VTK7.1/include/vtkOpenGLGPUVolumeRayCastMa...

512 lines
16 KiB
C++

/*=========================================================================
Program: Visualization Toolkit
Module: vtkOpenGLGPUVolumeRayCastMapper.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 vtkOpenGLGPUVolumeRayCastMapper
* @brief OpenGL subclass that draws the
* image to the screen
*
* This is the concrete implementation of a ray cast image display helper -
* a helper class responsible for drawing the image to the screen.
*
* @sa
* vtkGPUVolumeRayCastMapper
*
* @par Thanks:
* Thanks to Michael Granseier for helping to debug this class with respect
* to maximum memory issues (which must be specified as vtkIdType and not int).
*/
#ifndef vtkOpenGLGPUVolumeRayCastMapper_h
#define vtkOpenGLGPUVolumeRayCastMapper_h
#include "vtkRenderingVolumeOpenGLModule.h" // For export macro
#include "vtkGPUVolumeRayCastMapper.h"
class vtkVolume;
class vtkRenderer;
class vtkOpenGLExtensionManager;
class vtkMatrix4x4;
class vtkUnsupportedRequiredExtensionsStringStream; // Pimpl
class vtkMapDataArrayTextureId; // Pimpl
class vtkMapMaskTextureId; // Pimpl
class vtkPolyData;
class vtkClipConvexPolyData;
class vtkClipPolyData;
class vtkTessellatedBoxSource;
class vtkOpacityTable; // internal class.
class vtkRGBTable; // internal class.
class vtkKWScalarField; // internal class.
class vtkKWMask; // internal class.
class vtkOpacityTables; // Pimpl
class vtkDensifyPolyData;
class vtkStdString;
class vtkShaderProgram2;
class vtkShader2;
class VTKRENDERINGVOLUMEOPENGL_EXPORT vtkOpenGLGPUVolumeRayCastMapper
: public vtkGPUVolumeRayCastMapper
{
public:
static vtkOpenGLGPUVolumeRayCastMapper *New();
vtkTypeMacro(vtkOpenGLGPUVolumeRayCastMapper,vtkGPUVolumeRayCastMapper);
void PrintSelf(ostream& os, vtkIndent indent) VTK_OVERRIDE;
/**
* Based on hardware and properties, we may or may not be able to
* render using 3D texture mapping. This indicates if 3D texture
* mapping is supported by the hardware, and if the other extensions
* necessary to support the specific properties are available.
*/
virtual int IsRenderSupported(vtkRenderWindow *window,
vtkVolumeProperty *property);
/**
* Delete OpenGL objects.
* \post done: this->OpenGLObjectsCreated==0
*/
virtual void ReleaseGraphicsResources(vtkWindow *window);
/**
* Return a string matching the OpenGL errorCode.
* \post result_exists: result!=0
*/
static const char *OpenGLErrorMessage(unsigned int errorCode);
/**
* Display headerMessage on the standard output and the last OpenGL error
* message if any.
* \pre headerMessage_exists: headerMessage!=0
*/
static void PrintError(const char *headerMessage);
protected:
vtkOpenGLGPUVolumeRayCastMapper();
~vtkOpenGLGPUVolumeRayCastMapper();
// The render method called by the superclass
virtual void GPURender(vtkRenderer *ren,
vtkVolume *vol);
// Methods called by the AMR Volume Mapper.
virtual void PreRender(vtkRenderer *ren,
vtkVolume *vol,
double datasetBounds[6],
double scalarRange[2],
int numberOfScalarComponents,
unsigned int numberOfLevels);
// \pre input is up-to-date
virtual void RenderBlock(vtkRenderer *ren,
vtkVolume *vol,
unsigned int level);
virtual void PostRender(vtkRenderer *ren,
int numberOfScalarComponents);
/**
* Return if the required OpenGL extension `extensionName' is supported.
* If not, its name is added to the string of unsupported but required
* extensions.
* \pre extensions_exist: extensions!=0
* \pre extensionName_exists: extensionName!=0
*/
int TestRequiredExtension(vtkOpenGLExtensionManager *extensions,
const char *extensionName);
/**
* Attempt to load required and optional OpenGL extensions for the current
* context window. Variable LoadExtensionsSucceeded is set if all required
* extensions has been loaded. In addition, variable
* Supports_GL_ARB_texture_float is set if this extension has been loaded.
* \pre: window_exists: window!=0
*/
void LoadExtensions(vtkRenderWindow *window);
/**
* Create OpenGL objects such as textures, buffers and fragment program Ids.
* It only registers Ids, there is no actual initialization of textures or
* fragment program.
* \pre extensions_loaded: this->LoadExtensionsSucceeded
* \post done: this->OpenGLObjectsCreated==1
*/
void CreateOpenGLObjects(vtkRenderer *ren);
/**
* Allocate memory on the GPU for the framebuffers according to the size of
* the window or reallocate if the size has changed. Return true if
* allocation succeeded.
* \pre ren_exists: ren!=0
* \pre opengl_objects_created: this->OpenGLObjectsCreated
* \post right_size: LastSize[]=window size.
*/
int AllocateFrameBuffers(vtkRenderer *ren);
/**
* Load the scalar field (one or four component scalar field), cell or point
* based for a given subextent of the whole extent (can be the whole extent)
* as a 3D texture on the GPU.
* Extents are expressed in point if the cell flag is false or in cells of
* the cell flag is true.
* It returns true if it succeeded, false if there is not enough memory on
* the GPU.
* If succeeded, it updates the LoadedExtent, LoadedBounds, LoadedCellFlag
* and LoadedTime. It also succeed if the scalar field is already loaded
* (ie since last load, input has not changed and cell flag has not changed
* and requested texture extents are enclosed in the loaded extent).
* \pre input_exists: input!=0
* \pre valid_point_extent: (this->CellFlag ||
* (textureExtent[0]<textureExtent[1] &&
* textureExtent[2]<textureExtent[3] &&
* textureExtent[4]<textureExtent[5])))
* \pre valid_cell_extent: (!this->CellFlag ||
* (textureExtent[0]<=textureExtent[1] &&
* textureExtent[2]<=textureExtent[3] &&
* textureExtent[4]<=textureExtent[5])))
*/
int LoadScalarField(vtkImageData *input,
vtkImageData *maskInput,
int textureExtent[6],
vtkVolume *volume);
/**
* Allocate memory and load color table on the GPU or
* reload it if the transfer function changed.
* \pre vol_exists: vol!=0
* \pre valid_numberOfScalarComponents: numberOfScalarComponents==1 || numberOfScalarComponents==4
*/
int UpdateColorTransferFunction(vtkVolume *vol,
int numberOfScalarComponents);
/**
* Allocate memory and load opacity table on the GPU or
* reload it if the transfer functions changed.
* \pre vol_exists: vol!=0
* \pre valid_numberOfScalarComponents: numberOfScalarComponents==1 || numberOfScalarComponents==4
*/
int UpdateOpacityTransferFunction(vtkVolume *vol,
int numberOfScalarComponents,
unsigned int level);
/**
* Prepare rendering in the offscreen framebuffer.
* \pre ren_exists: ren!=0
* \pre vol_exists: vol!=0
*/
void SetupRender(vtkRenderer *ren, vtkVolume *vol);
/**
* Clip the bounding box with all clipping planes
* and the near and far plane
*/
void ClipBoundingBox(vtkRenderer *ren,
double worldBounds[6],
vtkVolume *vol);
/**
* Render the bounding box. The flag indicates whether
* or not tcoords are rendered too. Return abort status (true==abort).
* \pre valid_currentBlock: currentBlock>=0 && currentBlock<numberOfBlocks
*/
int RenderClippedBoundingBox(int tcoordFlag,
size_t currentBlock,
size_t numberOfBlocks,
vtkRenderWindow *renWin);
/**
* Method used to copy the state of the color buffer (which is in
* a frame buffer object) to a texture.
*/
void CopyFBOToTexture();
/**
* Restore OpenGL state after rendering of the dataset.
*/
void CleanupRender();
/**
* Render the offscreen buffer to the screen.
* \pre ren_exists: ren!=0
*/
void RenderTextureToScreen(vtkRenderer *ren);
/**
* Compute y=2^n such that x<=y.
* \pre positive_x: x>=0
* \post valid_result: result>=x
*/
int PowerOfTwoGreaterOrEqual(int x);
/**
* Display the status of the current framebuffer on the standard output.
*/
void CheckFrameBufferStatus();
/**
* Create a string from a buffer id. The result has to be free by the caller.
*/
vtkStdString BufferToString(int buffer);
/**
* Display the buffers assigned for drawing and reading operations.
*/
void DisplayReadAndDrawBuffers();
/**
* Display all the attachments of the current framebuffer object.
*/
void DisplayFrameBufferAttachments();
/**
* Display a given attachment for the current framebuffer object.
*/
void DisplayFrameBufferAttachment(unsigned int uattachment);
/**
* Concatenate the header string, projection type code and method to the
* final fragment code in this->FragmentCode.
* \pre valid_raycastMethod: raycastMethod>= vtkOpenGLGPUVolumeRayCastMapperMethodMaximumIntensityProjection && raycastMethod<=vtkOpenGLGPUVolumeRayCastMapperMethodMinIPFourDependent
*/
void BuildProgram(vtkRenderWindow *w,
int parallelProjection,
int raycastMethod,
int shadeMethod,
int componentMethod);
/**
* Return the current OpenGL state about lighting.
*/
void GetLightingStatus();
/**
* Update the reduction factor of the render viewport (this->ReductionFactor)
* according to the time spent in seconds to render the previous frame
* (this->TimeToDraw) and a time in seconds allocated to render the next
* frame (allocatedTime).
* \pre valid_current_reduction_range: this->ReductionFactor>0.0 && this->ReductionFactor<=1.0
* \pre positive_TimeToDraw: this->TimeToDraw>=0.0
* \pre positive_time: allocatedTime>0
* \post valid_new_reduction_range: this->ReductionFactor>0.0 && this->ReductionFactor<=1.0
*/
void ComputeReductionFactor(double allocatedTime);
/**
* Render a subvolume.
* \pre this->ProgramShader!=0 and is linked.
*/
void RenderWholeVolume(vtkRenderer *ren,
vtkVolume *vol);
/**
* Render a subvolume.
* \pre this->ProgramShader!=0 and is linked.
*/
void RenderRegions(vtkRenderer *ren,
vtkVolume *vol);
// Return abort status (true==abort)
int RenderSubVolume(vtkRenderer *ren,
double bounds[6],
vtkVolume *vol);
void LoadProjectionParameters(vtkRenderer *ren,
vtkVolume *vol);
/**
* Compute and return the number of cropping regions
*/
void ComputeNumberOfCroppingRegions();
void GetTextureFormat(vtkImageData *input,
unsigned int *internalFormat,
unsigned int *format,
unsigned int *type,
int *componentSize);
bool TestLoadingScalar(unsigned int internalFormat,
unsigned int format,
unsigned int type,
int textureSize[3],
int componentSize);
void SlabsFromDatasetToIndex(double slabsDataSet[6],
double slabsPoints[6]);
void SlabsFromIndexToDataset(double slabsPoints[6],
double slabsDataSet[6]);
const char *GetEnabledString(unsigned char value);
void GetOpenGLState();
void DebugDisplayBox(vtkPolyData *box);
void UpdateNoiseTexture();
/**
* Compute how each axis of a cell is projected on the viewport in pixel.
* This requires to have information about the camera and about the volume.
* It set the value of IgnoreSampleDistancePerPixel to true in case of
* degenerated case (axes aligned with the view).
*/
double ComputeMinimalSampleDistancePerPixel(vtkRenderer *renderer,
vtkVolume *volume);
/**
* Return how much the dataset has to be reduced in each dimension to
* fit on the GPU. If the value is 1.0, there is no need to reduce the
* dataset.
* \pre the calling thread has a current OpenGL context.
* \pre mapper_supported: IsRenderSupported(renderer->GetRenderWindow(),0)
* The computation is based on hardware limits (3D texture indexable size)
* and MaxMemoryInBytes.
* \post valid_i_ratio: ratio[0]>0 && ratio[0]<=1.0
* \post valid_j_ratio: ratio[1]>0 && ratio[1]<=1.0
* \post valid_k_ratio: ratio[2]>0 && ratio[2]<=1.0
*/
virtual void GetReductionRatio(double ratio[3]);
int NumberOfCroppingRegions;
// World coordinates of each corner of the dataset.
double BoundingBox[8][3];
// Used during the clipping process.
vtkPolyData *PolyDataBoundingBox;
vtkPlaneCollection *Planes;
vtkPlane *NearPlane;
vtkClipConvexPolyData *Clip;
vtkMatrix4x4 *InvVolumeMatrix;
vtkDensifyPolyData *Densify;
int OpenGLObjectsCreated;
int NumberOfFrameBuffers;
unsigned int FrameBufferObject;
unsigned int DepthRenderBufferObject;
// 3D scalar texture +1D color+1D opacity+2D grabbed depth buffer
// +1 2D colorbuffer.
unsigned int TextureObjects[5];
// used in MIP Mode (2 needed for ping-pong technique)
unsigned int MaxValueFrameBuffer;
unsigned int MaxValueFrameBuffer2;
int ReducedSize[2];
vtkPolyData *ClippedBoundingBox;
int LastSize[2];
double ReductionFactor;
// Supported extensions
// List of unsupported required extensions. Pimpl.
vtkUnsupportedRequiredExtensionsStringStream *UnsupportedRequiredExtensions;
int LoadExtensionsSucceeded;
int Supports_GL_ARB_texture_float;
int SupportsPixelBufferObjects;
vtkTimeStamp DataBufferTime;
// Matrices used in internal computation. As a member variable,
// only one memory allocation is performed.
vtkMatrix4x4 *TempMatrix[3];
double TableRange[2];
// Final string to send to the GPU as the fragment program source code.
// char *FragmentCode;
// int FragmentCodeCapacity;
int ErrorLine;
int ErrorColumn;
char *ErrorString;
// Store the last projection an raycast method in order to not rebuild
// the fragment code at every call.
int LastParallelProjection;
int LastRayCastMethod;
int LastCroppingMode;
int LastComponent;
int LastShade;
vtkImageData *SmallInput;
vtkTimeStamp SmallInputBuildTime;
/**
* Build the fragment shader program that scale and bias a texture
* for window/level purpose.
*/
void BuildScaleBiasProgram(vtkRenderWindow *w);
#if 0
vtkIdType LoadedExtent[6];
double LoadedBounds[6];
vtkTimeStamp LoadedScalarTime;
int LoadedCellFlag; // point data or cell data (or field data, not handled) ?
#endif
unsigned int SavedFrameBuffer; // some offscreen mode use a framebuffer too.
vtkTessellatedBoxSource *BoxSource;
float *NoiseTexture;
int NoiseTextureSize; // size of one dimension.
unsigned int NoiseTextureId; // GLuint
bool IgnoreSampleDistancePerPixel;
vtkMapDataArrayTextureId *ScalarsTextures; // need a list for AMR mode.
vtkMapMaskTextureId *MaskTextures; // need a list for AMR mode.
vtkRGBTable *RGBTable;
vtkRGBTable *Mask1RGBTable;
vtkRGBTable *Mask2RGBTable;
vtkOpacityTables *OpacityTables;
vtkKWScalarField *CurrentScalar;
vtkKWMask *CurrentMask;
float ActualSampleDistance;
double LastProgressEventTime; // initial value is 0.0. Expressed in seconds.
bool PreserveOrientation;
vtkShaderProgram2 *Program;
vtkShader2 *Main;
vtkShader2 *Projection;
vtkShader2 *Trace;
vtkShader2 *CroppingShader;
vtkShader2 *Component;
vtkShader2 *Shade;
// Internal Variable used to keep track of whether or render window's size
// changed and therefore we need re-allocation.
bool SizeChanged;
vtkShaderProgram2 *ScaleBiasProgram;
private:
vtkOpenGLGPUVolumeRayCastMapper(const vtkOpenGLGPUVolumeRayCastMapper&) VTK_DELETE_FUNCTION;
void operator=(const vtkOpenGLGPUVolumeRayCastMapper&) VTK_DELETE_FUNCTION;
};
#endif