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.
288 lines
9.1 KiB
C
288 lines
9.1 KiB
C
|
3 weeks ago
|
/*=========================================================================
|
||
|
|
|
||
|
|
Program: Visualization Toolkit
|
||
|
|
Module: vtkVolumeTextureMapper3D.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 vtkVolumeTextureMapper3D
|
||
|
|
* @brief volume render with 3D texture mapping
|
||
|
|
*
|
||
|
|
*
|
||
|
|
* vtkVolumeTextureMapper3D renders a volume using 3D texture mapping.
|
||
|
|
* This class is actually an abstract superclass - with all the actual
|
||
|
|
* work done by vtkOpenGLVolumeTextureMapper3D.
|
||
|
|
*
|
||
|
|
* This mappers currently supports:
|
||
|
|
*
|
||
|
|
* - any data type as input
|
||
|
|
* - one component, or two or four non-independent components
|
||
|
|
* - composite blending
|
||
|
|
* - intermixed opaque geometry
|
||
|
|
* - multiple volumes can be rendered if they can
|
||
|
|
* be sorted into back-to-front order (use the vtkFrustumCoverageCuller)
|
||
|
|
*
|
||
|
|
* This mapper does not support:
|
||
|
|
* - more than one independent component
|
||
|
|
* - maximum intensity projection
|
||
|
|
*
|
||
|
|
* Internally, this mapper will potentially change the resolution of the
|
||
|
|
* input data. The data will be resampled to be a power of two in each
|
||
|
|
* direction, and also no greater than 128*256*256 voxels (any aspect)
|
||
|
|
* for one or two component data, or 128*128*256 voxels (any aspect)
|
||
|
|
* for four component data. The limits are currently hardcoded after
|
||
|
|
* a check using the GL_PROXY_TEXTURE3D because some graphics drivers
|
||
|
|
* were always responding "yes" to the proxy call despite not being
|
||
|
|
* able to allocate that much texture memory.
|
||
|
|
*
|
||
|
|
* Currently, calculations are computed using 8 bits per RGBA channel.
|
||
|
|
* In the future this should be expanded to handle newer boards that
|
||
|
|
* can support 15 bit float compositing.
|
||
|
|
*
|
||
|
|
* This mapper supports two main families of graphics hardware:
|
||
|
|
* nvidia and ATI. There are two different implementations of
|
||
|
|
* 3D texture mapping used - one based on nvidia's GL_NV_texture_shader2
|
||
|
|
* and GL_NV_register_combiners2 extension, and one based on
|
||
|
|
* ATI's GL_ATI_fragment_shader (supported also by some nvidia boards)
|
||
|
|
* To use this class in an application that will run on various
|
||
|
|
* hardware configurations, you should have a back-up volume rendering
|
||
|
|
* method. You should create a vtkVolumeTextureMapper3D, assign its
|
||
|
|
* input, make sure you have a current OpenGL context (you've rendered
|
||
|
|
* at least once), then call IsRenderSupported with a vtkVolumeProperty
|
||
|
|
* as an argument. This method will return 0 if the input has more than
|
||
|
|
* one independent component, or if the graphics hardware does not
|
||
|
|
* support the set of required extensions for using at least one of
|
||
|
|
* the two implemented methods (nvidia or ati)
|
||
|
|
*
|
||
|
|
* @par Thanks:
|
||
|
|
* Thanks to Alexandre Gouaillard at the Megason Lab, Department of Systems
|
||
|
|
* Biology, Harvard Medical School
|
||
|
|
* https://wiki.med.harvard.edu/SysBio/Megason/
|
||
|
|
* for the idea and initial patch to speed-up rendering with compressed
|
||
|
|
* textures.
|
||
|
|
*
|
||
|
|
* @sa
|
||
|
|
* vtkVolumeMapper
|
||
|
|
* @deprecated
|
||
|
|
*/
|
||
|
|
|
||
|
|
#ifndef vtkVolumeTextureMapper3D_h
|
||
|
|
#define vtkVolumeTextureMapper3D_h
|
||
|
|
|
||
|
|
#include "vtkRenderingVolumeModule.h" // For export macro
|
||
|
|
#include "vtkVolumeMapper.h"
|
||
|
|
|
||
|
|
class vtkImageData;
|
||
|
|
class vtkColorTransferFunction;
|
||
|
|
class vtkPiecewiseFunction;
|
||
|
|
class vtkVolumeProperty;
|
||
|
|
#if !defined(VTK_LEGACY_REMOVE)
|
||
|
|
class VTKRENDERINGVOLUME_EXPORT vtkVolumeTextureMapper3D : public vtkVolumeMapper
|
||
|
|
{
|
||
|
|
public:
|
||
|
|
vtkTypeMacro(vtkVolumeTextureMapper3D,vtkVolumeMapper);
|
||
|
|
void PrintSelf(ostream& os, vtkIndent indent);
|
||
|
|
|
||
|
|
static vtkVolumeTextureMapper3D *New();
|
||
|
|
|
||
|
|
//@{
|
||
|
|
/**
|
||
|
|
* The distance at which to space sampling planes. This
|
||
|
|
* may not be honored for interactive renders. An interactive
|
||
|
|
* render is defined as one that has less than 1 second of
|
||
|
|
* allocated render time.
|
||
|
|
*/
|
||
|
|
vtkSetMacro( SampleDistance, float );
|
||
|
|
vtkGetMacro( SampleDistance, float );
|
||
|
|
//@}
|
||
|
|
|
||
|
|
//@{
|
||
|
|
/**
|
||
|
|
* These are the dimensions of the 3D texture
|
||
|
|
*/
|
||
|
|
vtkGetVectorMacro( VolumeDimensions, int, 3 );
|
||
|
|
//@}
|
||
|
|
|
||
|
|
//@{
|
||
|
|
/**
|
||
|
|
* This is the spacing of the 3D texture
|
||
|
|
*/
|
||
|
|
vtkGetVectorMacro( VolumeSpacing, float, 3 );
|
||
|
|
//@}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 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( vtkVolumeProperty *,
|
||
|
|
vtkRenderer *vtkNotUsed(r))
|
||
|
|
{return 0;}
|
||
|
|
|
||
|
|
//@{
|
||
|
|
/**
|
||
|
|
* Allow access to the number of polygons used for the
|
||
|
|
* rendering.
|
||
|
|
*/
|
||
|
|
vtkGetMacro( NumberOfPolygons, int );
|
||
|
|
//@}
|
||
|
|
|
||
|
|
//@{
|
||
|
|
/**
|
||
|
|
* Allow access to the actual sample distance used to render
|
||
|
|
* the image.
|
||
|
|
*/
|
||
|
|
vtkGetMacro( ActualSampleDistance, float );
|
||
|
|
//@}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* WARNING: INTERNAL METHOD - NOT INTENDED FOR GENERAL USE
|
||
|
|
* DO NOT USE THIS METHOD OUTSIDE OF THE RENDERING PROCESS
|
||
|
|
* Render the volume
|
||
|
|
*/
|
||
|
|
virtual void Render(vtkRenderer *, vtkVolume *) {}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* What rendering method is supported?
|
||
|
|
*/
|
||
|
|
enum
|
||
|
|
{
|
||
|
|
FRAGMENT_PROGRAM_METHOD=0,
|
||
|
|
NVIDIA_METHOD=1,
|
||
|
|
ATI_METHOD=2,
|
||
|
|
NO_METHOD=3
|
||
|
|
};
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Returns the number of components of the point scalar field
|
||
|
|
*/
|
||
|
|
int GetNumberOfScalarComponents(vtkImageData *input);
|
||
|
|
|
||
|
|
//@{
|
||
|
|
/**
|
||
|
|
* Set the preferred render method. If it is supported, this
|
||
|
|
* one will be used. Don't allow ATI_METHOD - it is not actually
|
||
|
|
* supported.
|
||
|
|
*/
|
||
|
|
vtkSetClampMacro( PreferredRenderMethod, int,
|
||
|
|
vtkVolumeTextureMapper3D::FRAGMENT_PROGRAM_METHOD,
|
||
|
|
vtkVolumeTextureMapper3D::NVIDIA_METHOD );
|
||
|
|
void SetPreferredMethodToFragmentProgram()
|
||
|
|
{ this->SetPreferredRenderMethod( vtkVolumeTextureMapper3D::FRAGMENT_PROGRAM_METHOD ); }
|
||
|
|
void SetPreferredMethodToNVidia()
|
||
|
|
{ this->SetPreferredRenderMethod( vtkVolumeTextureMapper3D::NVIDIA_METHOD ); }
|
||
|
|
vtkGetMacro(PreferredRenderMethod, int);
|
||
|
|
//@}
|
||
|
|
|
||
|
|
|
||
|
|
//@{
|
||
|
|
/**
|
||
|
|
* Set/Get if the mapper use compressed textures (if supported by the
|
||
|
|
* hardware). Initial value is false.
|
||
|
|
* There are two reasons to use compressed textures: 1. rendering can be 4
|
||
|
|
* times faster. 2. It saves some VRAM.
|
||
|
|
* There is one reason to not use compressed textures: quality may be lower
|
||
|
|
* than with uncompressed textures.
|
||
|
|
*/
|
||
|
|
vtkSetMacro(UseCompressedTexture,bool);
|
||
|
|
vtkGetMacro(UseCompressedTexture,bool);
|
||
|
|
//@}
|
||
|
|
|
||
|
|
protected:
|
||
|
|
vtkVolumeTextureMapper3D();
|
||
|
|
~vtkVolumeTextureMapper3D();
|
||
|
|
|
||
|
|
float *PolygonBuffer;
|
||
|
|
float *IntersectionBuffer;
|
||
|
|
int NumberOfPolygons;
|
||
|
|
int BufferSize;
|
||
|
|
|
||
|
|
unsigned char *Volume1;
|
||
|
|
unsigned char *Volume2;
|
||
|
|
unsigned char *Volume3;
|
||
|
|
int VolumeSize;
|
||
|
|
int VolumeComponents;
|
||
|
|
int VolumeDimensions[3];
|
||
|
|
float VolumeSpacing[3];
|
||
|
|
|
||
|
|
float SampleDistance;
|
||
|
|
float ActualSampleDistance;
|
||
|
|
|
||
|
|
vtkImageData *SavedTextureInput;
|
||
|
|
vtkImageData *SavedParametersInput;
|
||
|
|
|
||
|
|
vtkColorTransferFunction *SavedRGBFunction;
|
||
|
|
vtkPiecewiseFunction *SavedGrayFunction;
|
||
|
|
vtkPiecewiseFunction *SavedScalarOpacityFunction;
|
||
|
|
vtkPiecewiseFunction *SavedGradientOpacityFunction;
|
||
|
|
int SavedColorChannels;
|
||
|
|
float SavedSampleDistance;
|
||
|
|
float SavedScalarOpacityDistance;
|
||
|
|
|
||
|
|
unsigned char ColorLookup[65536*4];
|
||
|
|
unsigned char AlphaLookup[65536];
|
||
|
|
float TempArray1[3*4096];
|
||
|
|
float TempArray2[4096];
|
||
|
|
int ColorTableSize;
|
||
|
|
float ColorTableScale;
|
||
|
|
float ColorTableOffset;
|
||
|
|
|
||
|
|
unsigned char DiffuseLookup[65536*4];
|
||
|
|
unsigned char SpecularLookup[65536*4];
|
||
|
|
|
||
|
|
vtkTimeStamp SavedTextureMTime;
|
||
|
|
vtkTimeStamp SavedParametersMTime;
|
||
|
|
|
||
|
|
int RenderMethod;
|
||
|
|
int PreferredRenderMethod;
|
||
|
|
bool UseCompressedTexture;
|
||
|
|
|
||
|
|
bool SupportsNonPowerOfTwoTextures;
|
||
|
|
|
||
|
|
/**
|
||
|
|
* For the given viewing direction, compute the set of polygons.
|
||
|
|
*/
|
||
|
|
void ComputePolygons( vtkRenderer *ren, vtkVolume *vol, double bounds[6] );
|
||
|
|
|
||
|
|
//@{
|
||
|
|
/**
|
||
|
|
* Update the internal RGBA representation of the volume. Return 1 if
|
||
|
|
* anything change, 0 if nothing changed.
|
||
|
|
*/
|
||
|
|
int UpdateVolumes( vtkVolume * );
|
||
|
|
int UpdateColorLookup( vtkVolume * );
|
||
|
|
//@}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Impemented in subclass - check is texture size is OK.
|
||
|
|
*/
|
||
|
|
|
||
|
|
virtual int IsTextureSizeSupported(int vtkNotUsed(size)[3],
|
||
|
|
int vtkNotUsed(components))
|
||
|
|
{
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
private:
|
||
|
|
vtkVolumeTextureMapper3D(const vtkVolumeTextureMapper3D&) VTK_DELETE_FUNCTION;
|
||
|
|
void operator=(const vtkVolumeTextureMapper3D&) VTK_DELETE_FUNCTION;
|
||
|
|
};
|
||
|
|
|
||
|
|
#endif // VTK_LEGACY_REMOVE
|
||
|
|
#endif
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|