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.
211 lines
7.9 KiB
C
211 lines
7.9 KiB
C
|
3 weeks ago
|
/*=========================================================================
|
||
|
|
|
||
|
|
Program: Visualization Toolkit
|
||
|
|
Module: vtkOpenGLHAVSVolumeMapper.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.
|
||
|
|
|
||
|
|
=========================================================================*/
|
||
|
|
|
||
|
|
/* Copyright 2005, 2006 by University of Utah. */
|
||
|
|
|
||
|
|
/**
|
||
|
|
* @class vtkOpenGLHAVSVolumeMapper
|
||
|
|
* @brief Hardware-Assisted
|
||
|
|
* Visibility Sorting unstructured grid mapper, OpenGL implementation
|
||
|
|
*
|
||
|
|
*
|
||
|
|
*
|
||
|
|
* vtkHAVSVolumeMapper is a class that renders polygonal data
|
||
|
|
* (represented as an unstructured grid) using the Hardware-Assisted
|
||
|
|
* Visibility Sorting (HAVS) algorithm. First the unique triangles are sorted
|
||
|
|
* in object space, then they are sorted in image space using a fixed size
|
||
|
|
* A-buffer implemented on the GPU called the k-buffer. The HAVS algorithm
|
||
|
|
* excels at rendering large datasets quickly. The trade-off is that the
|
||
|
|
* algorithm may produce some rendering artifacts due to an insufficient k
|
||
|
|
* size (currently 2 or 6 is supported) or read/write race conditions.
|
||
|
|
*
|
||
|
|
* A built in level-of-detail (LOD) approach samples the geometry using one of
|
||
|
|
* two heuristics (field or area). If LOD is enabled, the amount of geometry
|
||
|
|
* that is sampled and rendered changes dynamically to stay within the target
|
||
|
|
* frame rate. The field sampling method generally works best for datasets
|
||
|
|
* with cell sizes that don't vary much in size. On the contrary, the area
|
||
|
|
* sampling approach gives better approximations when the volume has a lot of
|
||
|
|
* variation in cell size.
|
||
|
|
*
|
||
|
|
* The HAVS algorithm uses several advanced features on graphics hardware.
|
||
|
|
* The k-buffer sorting network is implemented using framebuffer objects
|
||
|
|
* (FBOs) with multiple render targets (MRTs). Therefore, only cards that
|
||
|
|
* support these features can run the algorithm (at least an ATI 9500 or an
|
||
|
|
* NVidia NV40 (6600)).
|
||
|
|
*
|
||
|
|
*
|
||
|
|
* @attention
|
||
|
|
* Several issues had to be addressed to get the HAVS algorithm working within
|
||
|
|
* the vtk framework. These additions forced the code to forsake speed for
|
||
|
|
* the sake of compliance and robustness.
|
||
|
|
*
|
||
|
|
* @attention
|
||
|
|
* The HAVS algorithm operates on the triangles that compose the mesh.
|
||
|
|
* Therefore, before rendering, the cells are decomposed into unique triangles
|
||
|
|
* and stored on the GPU for efficient rendering. The use of GPU data
|
||
|
|
* structures is only recommended if the entire geometry can fit in graphics
|
||
|
|
* memory. Otherwise this feature should be disabled.
|
||
|
|
*
|
||
|
|
* @attention
|
||
|
|
* Another new feature is the handling of mixed data types (eg., polygonal
|
||
|
|
* data with volume data). This is handled by reading the z-buffer from the
|
||
|
|
* current window and copying it into the framebuffer object for off-screen
|
||
|
|
* rendering. The depth test is then enabled so that the volume only appears
|
||
|
|
* over the opaque geometry. Finally, the results of the off-screen rendering
|
||
|
|
* are blended into the framebuffer as a transparent, view-aligned texture.
|
||
|
|
*
|
||
|
|
* @attention
|
||
|
|
* Instead of using a preintegrated 3D lookup table for storing the ray
|
||
|
|
* integral, this implementation uses partial pre-integration. This improves
|
||
|
|
* the performance of dynamic transfer function updates by avoiding a costly
|
||
|
|
* preprocess of the table.
|
||
|
|
*
|
||
|
|
* @attention
|
||
|
|
* A final change to the original algorithm is the handling of non-convexities
|
||
|
|
* in the mesh. Due to read/write hazards that may create undesired artifacts
|
||
|
|
* with non-convexities when using a inside/outside toggle in the fragment
|
||
|
|
* program, another approach was employed. To handle non-convexities, the
|
||
|
|
* fragment shader determines if a ray-gap is larger than the max cell size
|
||
|
|
* and kill the fragment if so. This approximation performs rather well in
|
||
|
|
* practice but may miss small non-convexities.
|
||
|
|
*
|
||
|
|
* @attention
|
||
|
|
* For more information on the HAVS algorithm see:
|
||
|
|
*
|
||
|
|
* @attention
|
||
|
|
* "Hardware-Assisted Visibility Sorting for Unstructured Volume
|
||
|
|
* Rendering" by S. P. Callahan, M. Ikits, J. L. D. Comba, and C. T. Silva,
|
||
|
|
* IEEE Transactions of Visualization and Computer Graphics; May/June 2005.
|
||
|
|
*
|
||
|
|
* @attention
|
||
|
|
* For more information on the Level-of-Detail algorithm, see:
|
||
|
|
*
|
||
|
|
* @attention
|
||
|
|
* "Interactive Rendering of Large Unstructured Grids Using Dynamic
|
||
|
|
* Level-of-Detail" by S. P. Callahan, J. L. D. Comba, P. Shirley, and
|
||
|
|
* C. T. Silva, Proceedings of IEEE Visualization '05, Oct. 2005.
|
||
|
|
*
|
||
|
|
*
|
||
|
|
* @par Acknowledgments:
|
||
|
|
* This code was developed by Steven P. Callahan under the supervision
|
||
|
|
* of Prof. Claudio T. Silva. The code also contains contributions
|
||
|
|
* from Milan Ikits, Linh Ha, Huy T. Vo, Carlos E. Scheidegger, and
|
||
|
|
* Joao L. D. Comba.
|
||
|
|
*
|
||
|
|
* @par Acknowledgments:
|
||
|
|
* The work was supported by grants, contracts, and gifts from the
|
||
|
|
* National Science Foundation, the Department of Energy, the Army
|
||
|
|
* Research Office, and IBM.
|
||
|
|
*
|
||
|
|
* @par Acknowledgments:
|
||
|
|
* The port of HAVS to VTK and ParaView has been primarily supported
|
||
|
|
* by Sandia National Labs.
|
||
|
|
*
|
||
|
|
*/
|
||
|
|
|
||
|
|
#ifndef vtkOpenGLHAVSVolumeMapper_h
|
||
|
|
#define vtkOpenGLHAVSVolumeMapper_h
|
||
|
|
|
||
|
|
#include "vtkRenderingVolumeOpenGLModule.h" // For export macro
|
||
|
|
#include "vtkHAVSVolumeMapper.h"
|
||
|
|
|
||
|
|
#include "vtkWeakPointer.h" // to cache the vtkRenderWindow
|
||
|
|
class vtkRenderer;
|
||
|
|
class vtkRenderWindow;
|
||
|
|
|
||
|
|
|
||
|
|
class VTKRENDERINGVOLUMEOPENGL_EXPORT vtkOpenGLHAVSVolumeMapper
|
||
|
|
: public vtkHAVSVolumeMapper
|
||
|
|
{
|
||
|
|
public:
|
||
|
|
static vtkOpenGLHAVSVolumeMapper *New();
|
||
|
|
vtkTypeMacro(vtkOpenGLHAVSVolumeMapper,
|
||
|
|
vtkHAVSVolumeMapper);
|
||
|
|
void PrintSelf(ostream& os, vtkIndent indent) VTK_OVERRIDE;
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Render the volume
|
||
|
|
*/
|
||
|
|
virtual void Render(vtkRenderer *ren, vtkVolume *vol);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Release any graphics resources that are being consumed by this volume
|
||
|
|
* renderer.
|
||
|
|
*/
|
||
|
|
virtual void ReleaseGraphicsResources(vtkWindow *);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Set/get whether or not the data structures should be stored on the GPU
|
||
|
|
* for better peformance.
|
||
|
|
*/
|
||
|
|
virtual void SetGPUDataStructures(bool);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Check hardware support for the HAVS algorithm. Necessary
|
||
|
|
* features include off-screen rendering, 32-bit fp textures, multiple
|
||
|
|
* render targets, and framebuffer objects.
|
||
|
|
* Subclasses must override this method to indicate if supported by Hardware.
|
||
|
|
*/
|
||
|
|
virtual bool SupportedByHardware(vtkRenderer *r);
|
||
|
|
protected:
|
||
|
|
|
||
|
|
vtkOpenGLHAVSVolumeMapper();
|
||
|
|
~vtkOpenGLHAVSVolumeMapper();
|
||
|
|
virtual int FillInputPortInformation(int port, vtkInformation* info);
|
||
|
|
|
||
|
|
virtual void Initialize(vtkRenderer *ren, vtkVolume *vol);
|
||
|
|
virtual void InitializeLookupTables(vtkVolume *vol);
|
||
|
|
void InitializeGPUDataStructures();
|
||
|
|
void InitializeShaders();
|
||
|
|
void DeleteShaders();
|
||
|
|
void InitializeFramebufferObject();
|
||
|
|
|
||
|
|
void RenderHAVS(vtkRenderer *ren);
|
||
|
|
void SetupFBOZBuffer(int screenWidth, int screenHeight, float depthNear, float depthFar,
|
||
|
|
float *zbuffer);
|
||
|
|
void SetupFBOMRT();
|
||
|
|
void DrawFBOInit(int screenWidth, int screenHeight, float depthNear, float depthFar);
|
||
|
|
void DrawFBOGeometry();
|
||
|
|
void DrawFBOFlush(int screenWidth, int screenHeight, float depthNear, float depthFar);
|
||
|
|
void DrawBlend(int screenWidth, int screenHeight, float depthNear, float depthFar);
|
||
|
|
|
||
|
|
void CheckOpenGLError(const char *str);
|
||
|
|
|
||
|
|
// GPU
|
||
|
|
unsigned int VBOVertexName;
|
||
|
|
unsigned int VBOTexCoordName;
|
||
|
|
unsigned int VBOVertexIndexName;
|
||
|
|
unsigned int VertexProgram;
|
||
|
|
unsigned int FragmentProgramBegin;
|
||
|
|
unsigned int FragmentProgram;
|
||
|
|
unsigned int FragmentProgramEnd;
|
||
|
|
unsigned int FramebufferObject;
|
||
|
|
int FramebufferObjectSize;
|
||
|
|
unsigned int FramebufferTextures[4];
|
||
|
|
unsigned int DepthTexture;
|
||
|
|
|
||
|
|
// Lookup Tables
|
||
|
|
unsigned int PsiTableTexture;
|
||
|
|
unsigned int TransferFunctionTexture;
|
||
|
|
|
||
|
|
vtkWeakPointer<vtkRenderWindow> RenderWindow;
|
||
|
|
|
||
|
|
private:
|
||
|
|
vtkOpenGLHAVSVolumeMapper(const vtkOpenGLHAVSVolumeMapper&) VTK_DELETE_FUNCTION;
|
||
|
|
void operator=(const vtkOpenGLHAVSVolumeMapper&) VTK_DELETE_FUNCTION;
|
||
|
|
};
|
||
|
|
|
||
|
|
#endif
|