1 /*=========================================================================
2 
3   Program:   Visualization Toolkit
4   Module:    vtkOpenGLGPUVolumeRayCastMapper.h
5 
6   Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
7   All rights reserved.
8   See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
9 
10      This software is distributed WITHOUT ANY WARRANTY; without even
11      the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
12      PURPOSE.  See the above copyright notice for more information.
13 
14 =========================================================================*/
15 /**
16  * @class vtkOpenGLGPUVolumeRayCastMapper
17  * @brief OpenGL implementation of volume rendering through ray-casting.
18  *
19  * @section multi Multiple Inputs
20 
21  * When multiple inputs are rendered simultaneously, it is possible to
22  * composite overlapping areas correctly. Inputs are connected directly to
23  * the mapper and their parameters (transfer functions, transformations, etc.)
24  * are specified through standard vtkVolume instances. These vtkVolume
25  * instances are to be registered in a special vtkProp3D, vtkMultiVolume.
26  *
27  * Structures related to a particular active input are stored in a helper
28  * class (vtkVolumeInputHelper) and helper structures are kept in a
29  * port-referenced map (VolumeInputMap). The order of the inputs in the
30  * map is important as it defines the order in which parameters are
31  * bound to uniform variables (transformation matrices, bias, scale and every
32  * other required rendering parameter).
33  *
34  * A separate code path is used when rendering multiple-inputs in order to
35  * facilitate the co-existance of these two modes (single/multiple), due to
36  * current feature incompatibilities with multiple inputs (e.g. texture-streaming,
37  * cropping, etc.).
38  *
39  * @note A limited set of the mapper features are currently supported for
40  * multiple inputs:
41  *
42  * - Blending
43  *   - Composite (front-to-back)
44  *
45  * - Transfer functions (defined separately for per input)
46  *   - 1D color
47  *   - 1D scalar opacity
48  *   - 1D gradient magnitude opacity
49  *   - 2D scalar-gradient magnitude
50  *
51  * - Point and cell data
52  *   - With the limitation that all of the inputs are assumed to share the same
53  *     name/id.
54  *
55  * @sa vtkGPUVolumeRayCastMapper vtkVolumeInputHelper vtkVolumeTexture
56  * vtkMultiVolume
57  *
58  */
59 
60 #ifndef vtkOpenGLGPUVolumeRayCastMapper_h
61 #define vtkOpenGLGPUVolumeRayCastMapper_h
62 #include <map>                               // For methods
63 
64 #include "vtkNew.h"                          // For vtkNew
65 #include "vtkRenderingVolumeOpenGL2Module.h" // For export macro
66 #include "vtkGPUVolumeRayCastMapper.h"
67 #include "vtkShader.h"                       // For methods
68 #include "vtkSmartPointer.h"                 // For smartptr
69 
70 
71 class vtkGenericOpenGLResourceFreeCallback;
72 class vtkImplicitFunction;
73 class vtkOpenGLCamera;
74 class vtkOpenGLTransferFunctions2D;
75 class vtkOpenGLVolumeGradientOpacityTables;
76 class vtkOpenGLVolumeOpacityTables;
77 class vtkOpenGLVolumeRGBTables;
78 class vtkShaderProgram;
79 class vtkTextureObject;
80 class vtkVolume;
81 class vtkVolumeInputHelper;
82 class vtkVolumeTexture;
83 class vtkOpenGLUniforms;
84 
85 class VTKRENDERINGVOLUMEOPENGL2_EXPORT vtkOpenGLGPUVolumeRayCastMapper :
86   public vtkGPUVolumeRayCastMapper
87 {
88 public:
89   static vtkOpenGLGPUVolumeRayCastMapper* New();
90 
91   enum Passes
92   {
93     RenderPass,
94     DepthPass = 1
95   };
96 
97   vtkTypeMacro(vtkOpenGLGPUVolumeRayCastMapper, vtkGPUVolumeRayCastMapper);
98   void PrintSelf( ostream& os, vtkIndent indent ) override;
99 
100   // Description:
101   // Low level API to enable access to depth texture in
102   // RenderToTexture mode. It will return either nullptr if
103   // RenderToImage was never turned on or texture captured
104   // the last time RenderToImage was on.
105   vtkTextureObject* GetDepthTexture();
106 
107   // Description:
108   // Low level API to enable access to color texture in
109   // RenderToTexture mode. It will return either nullptr if
110   // RenderToImage was never turned on or texture captured
111   // the last time RenderToImage was on.
112   vtkTextureObject* GetColorTexture();
113 
114   // Description:
115   // Low level API to export the depth texture as vtkImageData in
116   // RenderToImage mode.
117   void GetDepthImage(vtkImageData* im) override;
118 
119   // Description:
120   // Low level API to export the color texture as vtkImageData in
121   // RenderToImage mode.
122   void GetColorImage(vtkImageData* im) override;
123 
124   // Description:
125   // Mapper can have multiple passes and internally it will set
126   // the state. The state can not be set externally explicitly
127   // but can be set indirectly depending on the options set by
128   // the user.
129   vtkGetMacro(CurrentPass, int);
130 
131   // Sets a depth texture for this mapper to use
132   // This allows many mappers to use the same
133   // texture reducing GPU usage. If this is set
134   // the standard depth texture code is skipped
135   // The depth texture should be activated
136   // and deactivated outside of this class
137   void SetSharedDepthTexture(vtkTextureObject *nt);
138 
139   /**
140    * Set a fixed number of partitions in which to split the volume
141    * during rendring. This will force by-block rendering without
142    * trying to compute an optimum number of partitions.
143    */
144   void SetPartitions(unsigned short x, unsigned short y, unsigned short z);
145 
146   /**
147    *  Load the volume texture into GPU memory.  Actual loading occurs
148    *  in vtkVolumeTexture::LoadVolume.  The mapper by default loads data
149    *  lazily (at render time), so it is most commonly not necessary to call
150    *  this function.  This method is only exposed in order to support on-site
151    *  loading which is useful in cases where the user needs to know a-priori
152    *  whether loading will succeed or not.
153    */
154   bool PreLoadData(vtkRenderer* ren, vtkVolume* vol);
155 
156   //@{
157   /**
158    * This function enables you to apply your own substitutions
159    * to the shader creation process. The shader code in this class
160    * is created by applying a bunch of string replacements to a
161    * shader template. Using this function you can apply your
162    * own string replacements to add features you desire.
163    */
164   void AddShaderReplacement(
165     vtkShader::Type shaderType, // vertex, fragment, etc
166     const std::string& originalValue,
167     bool replaceFirst,  // do this replacement before the default
168     const std::string& replacementValue,
169     bool replaceAll);
170   void ClearShaderReplacement(
171     vtkShader::Type shaderType, // vertex, fragment, etc
172     const std::string& originalValue,
173     bool replaceFirst);
174   void ClearAllShaderReplacements(vtkShader::Type shaderType);
175   void ClearAllShaderReplacements();
176   //@}
177 
178   //@{
179   /**
180    * Allow the program to set the shader codes used directly
181    * instead of using the built in templates. Be aware, if
182    * set, this template will be used for all cases,
183    * primitive types, picking etc.
184    */
185   vtkSetStringMacro(VertexShaderCode);
186   vtkGetStringMacro(VertexShaderCode);
187   vtkSetStringMacro(FragmentShaderCode);
188   vtkGetStringMacro(FragmentShaderCode);
189   //@}
190 
191   //@{
192   /**
193    * The Uniforms object allows to set custom uniform variables
194    * that are used in replacement shader code.
195    */
196   vtkGetObjectMacro(FragmentCustomUniforms,vtkOpenGLUniforms);
197   vtkGetObjectMacro(VertexCustomUniforms,vtkOpenGLUniforms);
198   //@}
199 
200   // Description:
201   // Delete OpenGL objects.
202   // \post done: this->OpenGLObjectsCreated==0
203   void ReleaseGraphicsResources(vtkWindow *window) override;
204 
205 protected:
206   vtkOpenGLGPUVolumeRayCastMapper();
207   ~vtkOpenGLGPUVolumeRayCastMapper() override;
208 
209   vtkGenericOpenGLResourceFreeCallback *ResourceCallback;
210 
211   // Description:
212   // Build vertex and fragment shader for the volume rendering
213   void BuildDepthPassShader(vtkRenderer* ren, vtkVolume* vol,
214                             int noOfComponents,
215                             int independentComponents);
216 
217   // Description:
218   // Build vertex and fragment shader for the volume rendering
219   void BuildShader(vtkRenderer* ren);
220 
221   // TODO Take these out as these are no longer needed
222   // Methods called by the AMR Volume Mapper.
PreRender(vtkRenderer * vtkNotUsed (ren),vtkVolume * vtkNotUsed (vol),double vtkNotUsed (datasetBounds)[6],double vtkNotUsed (scalarRange)[2],int vtkNotUsed (noOfComponents),unsigned int vtkNotUsed (numberOfLevels))223   void PreRender(vtkRenderer * vtkNotUsed(ren),
224                          vtkVolume *vtkNotUsed(vol),
225                          double vtkNotUsed(datasetBounds)[6],
226                          double vtkNotUsed(scalarRange)[2],
227                          int vtkNotUsed(noOfComponents),
228                          unsigned int vtkNotUsed(numberOfLevels)) override {};
229 
230   // \pre input is up-to-date
RenderBlock(vtkRenderer * vtkNotUsed (ren),vtkVolume * vtkNotUsed (vol),unsigned int vtkNotUsed (level))231   void RenderBlock(vtkRenderer *vtkNotUsed(ren),
232                            vtkVolume *vtkNotUsed(vol),
233                            unsigned int vtkNotUsed(level)) override {}
234 
PostRender(vtkRenderer * vtkNotUsed (ren),int vtkNotUsed (noOfComponents))235   void PostRender(vtkRenderer *vtkNotUsed(ren),
236                           int vtkNotUsed(noOfComponents)) override {}
237 
238   // Description:
239   // Rendering volume on GPU
240   void GPURender(vtkRenderer *ren, vtkVolume *vol) override;
241 
242   // Description:
243   // Method that performs the actual rendering given a volume and a shader
244   void DoGPURender(vtkRenderer* ren,
245                    vtkOpenGLCamera* cam,
246                    vtkShaderProgram* shaderProgram);
247 
248   // Description:
249   // Update the reduction factor of the render viewport (this->ReductionFactor)
250   // according to the time spent in seconds to render the previous frame
251   // (this->TimeToDraw) and a time in seconds allocated to render the next
252   // frame (allocatedTime).
253   // \pre valid_current_reduction_range: this->ReductionFactor>0.0 && this->ReductionFactor<=1.0
254   // \pre positive_TimeToDraw: this->TimeToDraw>=0.0
255   // \pre positive_time: allocatedTime>0
256   // \post valid_new_reduction_range: this->ReductionFactor>0.0 && this->ReductionFactor<=1.0
257   void ComputeReductionFactor(double allocatedTime);
258 
259   // Description:
260   // Empty implementation.
GetReductionRatio(double * ratio)261   void GetReductionRatio(double* ratio) override
262   {
263     ratio[0] = ratio[1] = ratio[2] = 1.0;
264   }
265 
266 
267   // Description:
268   // Empty implementation.
IsRenderSupported(vtkRenderWindow * vtkNotUsed (window),vtkVolumeProperty * vtkNotUsed (property))269   int IsRenderSupported(vtkRenderWindow *vtkNotUsed(window),
270                                 vtkVolumeProperty *vtkNotUsed(property)) override
271   {
272     return 1;
273   }
274 
275   //@{
276   /**
277    *  \brief vtkOpenGLRenderPass API
278    */
279   vtkMTimeType GetRenderPassStageMTime(vtkVolume* vol);
280 
281   /**
282    * Create the basic shader template strings before substitutions
283    */
284   void GetShaderTemplate(std::map<vtkShader::Type, vtkShader*>& shaders);
285 
286   /**
287    * Perform string replacements on the shader templates
288    */
289   void ReplaceShaderValues(std::map<vtkShader::Type, vtkShader*>& shaders,
290     vtkRenderer* ren, vtkVolume* vol, int numComps);
291 
292   /**
293    *  RenderPass string replacements on shader templates called from
294    *  ReplaceShaderValues.
295    */
296   void ReplaceShaderCustomUniforms(
297     std::map<vtkShader::Type, vtkShader*>& shaders );
298   void ReplaceShaderBase(std::map<vtkShader::Type, vtkShader*>& shaders,
299     vtkRenderer* ren, vtkVolume* vol, int numComps);
300   void ReplaceShaderTermination(std::map<vtkShader::Type, vtkShader*>& shaders,
301     vtkRenderer* ren, vtkVolume* vol, int numComps);
302   void ReplaceShaderShading(std::map<vtkShader::Type, vtkShader*>& shaders,
303     vtkRenderer* ren, vtkVolume* vol, int numComps);
304   void ReplaceShaderCompute(std::map<vtkShader::Type, vtkShader*>& shaders,
305     vtkRenderer* ren, vtkVolume* vol, int numComps);
306   void ReplaceShaderCropping(std::map<vtkShader::Type, vtkShader*>& shaders,
307     vtkRenderer* ren, vtkVolume* vol, int numComps);
308   void ReplaceShaderClipping(std::map<vtkShader::Type, vtkShader*>& shaders,
309     vtkRenderer* ren, vtkVolume* vol, int numComps);
310   void ReplaceShaderMasking(std::map<vtkShader::Type, vtkShader*>& shaders,
311     vtkRenderer* ren, vtkVolume* vol, int numComps);
312   void ReplaceShaderPicking(std::map<vtkShader::Type, vtkShader*>& shaders,
313     vtkRenderer* ren, vtkVolume* vol, int numComps);
314   void ReplaceShaderRTT(std::map<vtkShader::Type, vtkShader*>& shaders,
315     vtkRenderer* ren, vtkVolume* vol, int numComps);
316   void ReplaceShaderRenderPass(std::map<vtkShader::Type, vtkShader*>& shaders,
317     vtkVolume* vol, bool prePass);
318 
319   /**
320    *  Update parameters from RenderPass
321    */
322   void SetShaderParametersRenderPass();
323 
324   /**
325    *  Caches the vtkOpenGLRenderPass::RenderPasses() information.
326    *  Note: Do not dereference the pointers held by this object. There is no
327    *  guarantee that they are still valid!
328    */
329   vtkNew<vtkInformation> LastRenderPassInfo;
330   //@}
331 
332   double ReductionFactor;
333   int    CurrentPass;
334   char *VertexShaderCode;
335   char *FragmentShaderCode;
336   std::map<const vtkShader::ReplacementSpec, vtkShader::ReplacementValue>
337     UserShaderReplacements;
338 
339   vtkNew<vtkOpenGLUniforms> FragmentCustomUniforms;
340   vtkNew<vtkOpenGLUniforms> VertexCustomUniforms;
341 
342 public:
343   using VolumeInput = vtkVolumeInputHelper;
344   using VolumeInputMap = std::map<int, vtkVolumeInputHelper>;
345   VolumeInputMap AssembledInputs;
346 
347 private:
348   class vtkInternal;
349   vtkInternal* Impl;
350 
351   friend class vtkVolumeTexture;
352 
353   vtkOpenGLGPUVolumeRayCastMapper(
354     const vtkOpenGLGPUVolumeRayCastMapper&) = delete;
355   void operator=(const vtkOpenGLGPUVolumeRayCastMapper&) = delete;
356 };
357 
358 #endif // vtkOpenGLGPUVolumeRayCastMapper_h
359