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.

300 lines
11 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 implementation of volume rendering through ray-casting.
*
* @section multi Multiple Inputs
* When multiple inputs are rendered simultaneously, it is possible to
* composite overlapping areas correctly. Inputs are connected directly to
* the mapper and their parameters (transfer functions, transformations, etc.)
* are specified through standard vtkVolume instances. These vtkVolume
* instances are to be registered in a special vtkProp3D, vtkMultiVolume.
*
* Structures related to a particular active input are stored in a helper
* class (vtkVolumeInputHelper) and helper structures are kept in a
* port-referenced map (VolumeInputMap). The order of the inputs in the
* map is important as it defines the order in which parameters are
* bound to uniform variables (transformation matrices, bias, scale and every
* other required rendering parameter).
*
* A separate code path is used when rendering multiple-inputs in order to
* facilitate the co-existance of these two modes (single/multiple), due to
* current feature incompatibilities with multiple inputs (e.g. texture-streaming,
* cropping, etc.).
*
* @note A limited set of the mapper features are currently supported for
* multiple inputs:
*
* - Blending
* - Composite (front-to-back)
*
* - Transfer functions (defined separately for per input)
* - 1D color
* - 1D scalar opacity
* - 1D gradient magnitude opacity
* - 2D scalar-gradient magnitude
*
* - Point and cell data
* - With the limitation that all of the inputs are assumed to share the same
* name/id.
*
* @sa vtkGPUVolumeRayCastMapper vtkVolumeInputHelper vtkVolumeTexture
* vtkMultiVolume
*
*/
#ifndef vtkOpenGLGPUVolumeRayCastMapper_h
#define vtkOpenGLGPUVolumeRayCastMapper_h
#include <map> // For methods
#include "vtkGPUVolumeRayCastMapper.h"
#include "vtkNew.h" // For vtkNew
#include "vtkRenderingVolumeOpenGL2Module.h" // For export macro
#include "vtkShader.h" // For methods
#include "vtkSmartPointer.h" // For smartptr
class vtkGenericOpenGLResourceFreeCallback;
class vtkImplicitFunction;
class vtkOpenGLCamera;
class vtkOpenGLTransferFunctions2D;
class vtkOpenGLVolumeGradientOpacityTables;
class vtkOpenGLVolumeOpacityTables;
class vtkOpenGLVolumeRGBTables;
class vtkShaderProgram;
class vtkTextureObject;
class vtkVolume;
class vtkVolumeInputHelper;
class vtkVolumeTexture;
class vtkOpenGLShaderProperty;
class VTKRENDERINGVOLUMEOPENGL2_EXPORT vtkOpenGLGPUVolumeRayCastMapper
: public vtkGPUVolumeRayCastMapper
{
public:
static vtkOpenGLGPUVolumeRayCastMapper* New();
enum Passes
{
RenderPass,
DepthPass = 1
};
vtkTypeMacro(vtkOpenGLGPUVolumeRayCastMapper, vtkGPUVolumeRayCastMapper);
void PrintSelf(ostream& os, vtkIndent indent) override;
// Description:
// Low level API to enable access to depth texture in
// RenderToTexture mode. It will return either nullptr if
// RenderToImage was never turned on or texture captured
// the last time RenderToImage was on.
vtkTextureObject* GetDepthTexture();
// Description:
// Low level API to enable access to color texture in
// RenderToTexture mode. It will return either nullptr if
// RenderToImage was never turned on or texture captured
// the last time RenderToImage was on.
vtkTextureObject* GetColorTexture();
// Description:
// Low level API to export the depth texture as vtkImageData in
// RenderToImage mode.
void GetDepthImage(vtkImageData* im) override;
// Description:
// Low level API to export the color texture as vtkImageData in
// RenderToImage mode.
void GetColorImage(vtkImageData* im) override;
// Description:
// Mapper can have multiple passes and internally it will set
// the state. The state can not be set externally explicitly
// but can be set indirectly depending on the options set by
// the user.
vtkGetMacro(CurrentPass, int);
// Sets a depth texture for this mapper to use
// This allows many mappers to use the same
// texture reducing GPU usage. If this is set
// the standard depth texture code is skipped
// The depth texture should be activated
// and deactivated outside of this class
void SetSharedDepthTexture(vtkTextureObject* nt);
/**
* Set a fixed number of partitions in which to split the volume
* during rendring. This will force by-block rendering without
* trying to compute an optimum number of partitions.
*/
void SetPartitions(unsigned short x, unsigned short y, unsigned short z);
/**
* Load the volume texture into GPU memory. Actual loading occurs
* in vtkVolumeTexture::LoadVolume. The mapper by default loads data
* lazily (at render time), so it is most commonly not necessary to call
* this function. This method is only exposed in order to support on-site
* loading which is useful in cases where the user needs to know a-priori
* whether loading will succeed or not.
*/
bool PreLoadData(vtkRenderer* ren, vtkVolume* vol);
// Description:
// Delete OpenGL objects.
// \post done: this->OpenGLObjectsCreated==0
void ReleaseGraphicsResources(vtkWindow* window) override;
protected:
vtkOpenGLGPUVolumeRayCastMapper();
~vtkOpenGLGPUVolumeRayCastMapper() override;
vtkGenericOpenGLResourceFreeCallback* ResourceCallback;
// Description:
// Build vertex and fragment shader for the volume rendering
void BuildDepthPassShader(
vtkRenderer* ren, vtkVolume* vol, int noOfComponents, int independentComponents);
// Description:
// Build vertex and fragment shader for the volume rendering
void BuildShader(vtkRenderer* ren);
// TODO Take these out as these are no longer needed
// Methods called by the AMR Volume Mapper.
void PreRender(vtkRenderer* vtkNotUsed(ren), vtkVolume* vtkNotUsed(vol),
double vtkNotUsed(datasetBounds)[6], double vtkNotUsed(scalarRange)[2],
int vtkNotUsed(noOfComponents), unsigned int vtkNotUsed(numberOfLevels)) override
{
}
// \pre input is up-to-date
void RenderBlock(vtkRenderer* vtkNotUsed(ren), vtkVolume* vtkNotUsed(vol),
unsigned int vtkNotUsed(level)) override
{
}
void PostRender(vtkRenderer* vtkNotUsed(ren), int vtkNotUsed(noOfComponents)) override {}
// Description:
// Rendering volume on GPU
void GPURender(vtkRenderer* ren, vtkVolume* vol) override;
// Description:
// Method that performs the actual rendering given a volume and a shader
void DoGPURender(vtkRenderer* ren, vtkOpenGLCamera* cam, vtkShaderProgram* shaderProgram,
vtkOpenGLShaderProperty* shaderProperty);
// Description:
// 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);
// Description:
// Empty implementation.
void GetReductionRatio(double* ratio) override { ratio[0] = ratio[1] = ratio[2] = 1.0; }
// Description:
// Empty implementation.
int IsRenderSupported(
vtkRenderWindow* vtkNotUsed(window), vtkVolumeProperty* vtkNotUsed(property)) override
{
return 1;
}
//@{
/**
* \brief vtkOpenGLRenderPass API
*/
vtkMTimeType GetRenderPassStageMTime(vtkVolume* vol);
/**
* Create the basic shader template strings before substitutions
*/
void GetShaderTemplate(
std::map<vtkShader::Type, vtkShader*>& shaders, vtkOpenGLShaderProperty* p);
/**
* Perform string replacements on the shader templates
*/
void ReplaceShaderValues(
std::map<vtkShader::Type, vtkShader*>& shaders, vtkRenderer* ren, vtkVolume* vol, int numComps);
/**
* RenderPass string replacements on shader templates called from
* ReplaceShaderValues.
*/
void ReplaceShaderCustomUniforms(
std::map<vtkShader::Type, vtkShader*>& shaders, vtkOpenGLShaderProperty* p);
void ReplaceShaderBase(
std::map<vtkShader::Type, vtkShader*>& shaders, vtkRenderer* ren, vtkVolume* vol, int numComps);
void ReplaceShaderTermination(
std::map<vtkShader::Type, vtkShader*>& shaders, vtkRenderer* ren, vtkVolume* vol, int numComps);
void ReplaceShaderShading(
std::map<vtkShader::Type, vtkShader*>& shaders, vtkRenderer* ren, vtkVolume* vol, int numComps);
void ReplaceShaderCompute(
std::map<vtkShader::Type, vtkShader*>& shaders, vtkRenderer* ren, vtkVolume* vol, int numComps);
void ReplaceShaderCropping(
std::map<vtkShader::Type, vtkShader*>& shaders, vtkRenderer* ren, vtkVolume* vol, int numComps);
void ReplaceShaderClipping(
std::map<vtkShader::Type, vtkShader*>& shaders, vtkRenderer* ren, vtkVolume* vol, int numComps);
void ReplaceShaderMasking(
std::map<vtkShader::Type, vtkShader*>& shaders, vtkRenderer* ren, vtkVolume* vol, int numComps);
void ReplaceShaderPicking(
std::map<vtkShader::Type, vtkShader*>& shaders, vtkRenderer* ren, vtkVolume* vol, int numComps);
void ReplaceShaderRTT(
std::map<vtkShader::Type, vtkShader*>& shaders, vtkRenderer* ren, vtkVolume* vol, int numComps);
void ReplaceShaderRenderPass(
std::map<vtkShader::Type, vtkShader*>& shaders, vtkVolume* vol, bool prePass);
/**
* Update parameters from RenderPass
*/
void SetShaderParametersRenderPass();
/**
* Caches the vtkOpenGLRenderPass::RenderPasses() information.
* Note: Do not dereference the pointers held by this object. There is no
* guarantee that they are still valid!
*/
vtkNew<vtkInformation> LastRenderPassInfo;
//@}
double ReductionFactor;
int CurrentPass;
public:
using VolumeInput = vtkVolumeInputHelper;
using VolumeInputMap = std::map<int, vtkVolumeInputHelper>;
VolumeInputMap AssembledInputs;
private:
class vtkInternal;
vtkInternal* Impl;
friend class vtkVolumeTexture;
vtkOpenGLGPUVolumeRayCastMapper(const vtkOpenGLGPUVolumeRayCastMapper&) = delete;
void operator=(const vtkOpenGLGPUVolumeRayCastMapper&) = delete;
};
#endif // vtkOpenGLGPUVolumeRayCastMapper_h