VTK
vtkOpenGLVolumeOpacityTable.h
Go to the documentation of this file.
1 /*=========================================================================
2 
3  Program: Visualization Toolkit
4  Module: vtkOpenGLVolumeOpacityTable.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 #ifndef vtkOpenGLVolumeOpacityTable_h
17 #define vtkOpenGLVolumeOpacityTable_h
18 #ifndef __VTK_WRAP__
19 
20 #include <vector>
21 
22 #include <vtkObjectFactory.h>
23 #include <vtkPiecewiseFunction.h>
24 #include <vtkTextureObject.h>
25 #include <vtkVolumeMapper.h>
26 #include <vtk_glew.h>
27 #include <vtkMath.h>
28 
29 
30 //----------------------------------------------------------------------------
32 {
33 public:
34 
36 
37  // Activate texture.
38  //--------------------------------------------------------------------------
39  void Activate()
40  {
41  if (!this->TextureObject)
42  {
43  return;
44  }
45  this->TextureObject->Activate();
46  }
47 
48  // Deactivate texture.
49  //--------------------------------------------------------------------------
50  void Deactivate()
51  {
52  if (!this->TextureObject)
53  {
54  return;
55  }
56  this->TextureObject->Deactivate();
57  }
58 
59  // Update opacity transfer function texture.
60  //--------------------------------------------------------------------------
61  void Update(vtkPiecewiseFunction* scalarOpacity,
62  int blendMode,
63  double sampleDistance,
64  double range[2],
65  double unitDistance,
66  int filterValue,
67  vtkOpenGLRenderWindow* renWin)
68  {
69  bool needUpdate = false;
70  if (!this->TextureObject)
71  {
73  }
74 
75  this->TextureObject->SetContext(renWin);
76 
77  if (this->LastRange[0] != range[0] ||
78  this->LastRange[1] != range[1])
79  {
80  this->LastRange[0] = range[0];
81  this->LastRange[1] = range[1];
82  needUpdate = true;
83  }
84 
85  if(scalarOpacity->GetMTime() > this->BuildTime ||
86  this->TextureObject->GetMTime() > this->BuildTime ||
87  (this->LastBlendMode != blendMode) ||
88  (blendMode == vtkVolumeMapper::COMPOSITE_BLEND &&
89  this->LastSampleDistance != sampleDistance) ||
90  needUpdate || !this->TextureObject->GetHandle())
91  {
92  int const idealW = scalarOpacity->EstimateMinNumberOfSamples(this->LastRange[0],
93  this->LastRange[1]);
94  int const newWidth = this->GetMaximumSupportedTextureWidth(renWin, idealW);
95 
96  if(this->Table == nullptr || this->TextureWidth != newWidth)
97  {
98  this->TextureWidth = newWidth;
99  delete [] this->Table;
100  this->Table = new float[this->TextureWidth];
101  }
102 
103  scalarOpacity->GetTable(this->LastRange[0],
104  this->LastRange[1],
105  this->TextureWidth,
106  this->Table);
107  this->LastBlendMode = blendMode;
108 
109  // Correct the opacity array for the spacing between the planes if we
110  // are using a composite blending operation
111  // TODO Fix this code for sample distance in three dimensions
112  if(blendMode == vtkVolumeMapper::COMPOSITE_BLEND)
113  {
114  float* ptr = this->Table;
115  double factor = sampleDistance/unitDistance;
116  int i=0;
117  while(i < this->TextureWidth)
118  {
119  if(*ptr > 0.0001f)
120  {
121  *ptr = static_cast<float>(1.0-pow(1.0-static_cast<double>(*ptr),
122  factor));
123  }
124  ++ptr;
125  ++i;
126  }
127  this->LastSampleDistance = sampleDistance;
128  }
129  else if (blendMode==vtkVolumeMapper::ADDITIVE_BLEND)
130  {
131  float* ptr = this->Table;
132  double factor = sampleDistance/unitDistance;
133  int i = 0;
134  while( i < this->TextureWidth)
135  {
136  if(*ptr > 0.0001f)
137  {
138  *ptr = static_cast<float>(static_cast<double>(*ptr)*factor);
139  }
140  ++ptr;
141  ++i;
142  }
143  this->LastSampleDistance = sampleDistance;
144  }
145 
147  this->TextureObject->SetMagnificationFilter(filterValue);
148  this->TextureObject->SetMinificationFilter(filterValue);
149  this->TextureObject->Create2DFromRaw(this->TextureWidth, 1, 1,
150  VTK_FLOAT,
151  this->Table);
152  this->LastInterpolation = filterValue;
153  this->BuildTime.Modified();
154  }
155 
156  if(this->LastInterpolation != filterValue)
157  {
158  this->LastInterpolation = filterValue;
159  this->TextureObject->SetMagnificationFilter(filterValue);
160  this->TextureObject->SetMinificationFilter(filterValue);
161  }
162  }
163 
164  //--------------------------------------------------------------------------
166  int idealWidth)
167  {
168  if (!this->TextureObject)
169  {
170  vtkErrorMacro("vtkTextureObject not initialized!");
171  return -1;
172  }
173 
174  // Try to match the next power of two.
175  idealWidth = vtkMath::NearestPowerOfTwo(idealWidth);
176  int const maxWidth = this->TextureObject->GetMaximumTextureSize(renWin);
177  if (maxWidth < 0)
178  {
179  vtkErrorMacro("Failed to query max texture size! using default 1024.");
180  return 1024;
181  }
182 
183  if (maxWidth >= idealWidth)
184  {
185  idealWidth = vtkMath::Max(1024, idealWidth);
186  return idealWidth;
187  }
188 
189  vtkWarningMacro("This OpenGL implementation does not support the required "
190  "texture size of " << idealWidth << ". Falling back to maximum allowed, "
191  << maxWidth << "." << "This may cause an incorrect color table mapping.");
192 
193  return maxWidth;
194  }
195 
196  // Get the texture unit
197  //--------------------------------------------------------------------------
198  int GetTextureUnit(void)
199  {
200  if (!this->TextureObject)
201  {
202  return -1;
203  }
204  return this->TextureObject->GetTextureUnit();
205  }
206 
207  //--------------------------------------------------------------------------
209  {
210  if (this->TextureObject)
211  {
213  this->TextureObject->Delete();
214  this->TextureObject = nullptr;
215  }
216  }
217 
218 protected:
219 
220  //--------------------------------------------------------------------------
221  vtkOpenGLVolumeOpacityTable(int width = 1024)
222  {
223  this->TextureObject = nullptr;
225  this->TextureWidth = width;
226  this->LastSampleDistance = 1.0;
227  this->Table = nullptr;
228  this->LastInterpolation = -1;
229  this->LastRange[0] = this->LastRange[1] = 0.0;
230  }
231 
232  //--------------------------------------------------------------------------
234  {
235  if (this->TextureObject)
236  {
237  this->TextureObject->Delete();
238  this->TextureObject = nullptr;
239  }
240 
241  delete[] this->Table;
242  }
243 
244 
248 
251  float *Table;
253  double LastRange[2];
254 
255 private:
257  = delete;
259  = delete;
260 };
261 
264 {
265 public:
267 
268  //--------------------------------------------------------------------------
269  void Create(unsigned int numberOfTables)
270  {
271  this->Tables.reserve(static_cast<size_t>(numberOfTables));
272 
273  for (unsigned int i = 0; i < numberOfTables; i++)
274  {
276  this->Tables.push_back(table);
277  }
278  }
279 
280  //--------------------------------------------------------------------------
282  {
283  size_t const size = this->Tables.size();
284  for (size_t i = 0; i < size; i++)
285  {
286  this->Tables[i]->Delete();
287  }
288  }
289 
290  // brief Get opacity table at a given index.
291  //--------------------------------------------------------------------------
293  {
294  if (i >= this->Tables.size())
295  {
296  return nullptr;
297  }
298  return this->Tables[i];
299  }
300 
301  // Get number of opacity tables.
302  //--------------------------------------------------------------------------
304  {
305  return this->Tables.size();
306  }
307 
308  //--------------------------------------------------------------------------
310  {
311  size_t const size = this->Tables.size();
312  for (size_t i = 0; i < size; ++i)
313  {
314  this->Tables[i]->ReleaseGraphicsResources(window);
315  }
316  }
317 protected:
318  vtkOpenGLVolumeOpacityTables() = default;
319 
320 private:
321  std::vector<vtkOpenGLVolumeOpacityTable*> Tables;
322 
324  const vtkOpenGLVolumeOpacityTables &other) = delete;
325  vtkOpenGLVolumeOpacityTables &operator=(
326  const vtkOpenGLVolumeOpacityTables &other) = delete;
327 };
328 
329 #endif
330 #endif // vtkOpenGLVolumeOpacityTable_h
331 // VTK-HeaderTest-Exclude: vtkOpenGLVolumeOpacityTable.h
OpenGL rendering window.
abstract base class for most VTK objects
Definition: vtkObject.h:59
void ReleaseGraphicsResources(vtkWindow *window)
Defines a 1D piecewise function.
record modification and/or execution time
Definition: vtkTimeStamp.h:35
void Modified()
Set this objects time to the current time.
void GetTable(double x1, double x2, int size, float *table, int stride=1, int logIncrements=0)
Fills in an array of function values evaluated at regular intervals.
void Activate()
Activate and Bind the texture.
vtkOpenGLVolumeOpacityTable * GetTable(unsigned int i)
void ReleaseGraphicsResources(vtkWindow *window)
bool Create2DFromRaw(unsigned int width, unsigned int height, int numComps, int dataType, void *data)
Create a 2D texture from client memory numComps must be in [1-4].
window superclass for vtkRenderWindow
Definition: vtkWindow.h:37
#define VTK_FLOAT
Definition: vtkType.h:58
static int NearestPowerOfTwo(int x)
Compute the nearest power of two that is not less than x.
Definition: vtkMath.h:1330
virtual void SetMinificationFilter(int)
Minification filter mode.
void Create(unsigned int numberOfTables)
virtual vtkMTimeType GetMTime()
Return this object&#39;s modified time.
void Update(vtkPiecewiseFunction *scalarOpacity, int blendMode, double sampleDistance, double range[2], double unitDistance, int filterValue, vtkOpenGLRenderWindow *renWin)
virtual unsigned int GetHandle()
Returns the OpenGL handle.
int GetMaximumSupportedTextureWidth(vtkOpenGLRenderWindow *renWin, int idealWidth)
abstracts an OpenGL texture object.
int EstimateMinNumberOfSamples(double const &x1, double const &x2)
Estimates the minimum size of a table such that it would correctly sample this function.
static int GetMaximumTextureSize(vtkOpenGLRenderWindow *context)
Query and return maximum texture size (dimension) supported by the OpenGL driver for a particular con...
void ReleaseGraphicsResources(vtkWindow *win)
Deactivate and UnBind the texture.
void Deactivate()
Deactivate and UnBind the texture.
static vtkTextureObject * New()
virtual void SetWrapS(int)
Wrap mode for the first texture coordinate "s" Valid values are:
vtkMTimeType GetMTime() override
Data objects are composite objects and need to check each part for MTime.
int GetTextureUnit()
Return the texture unit used for this texture.
static vtkOpenGLVolumeOpacityTable * New()
static T Max(const T &a, const T &b)
Returns the maximum of the two arguments provided.
Definition: vtkMath.h:1368
virtual void Delete()
Delete a VTK object.
void SetContext(vtkOpenGLRenderWindow *)
Get/Set the context.
virtual void SetMagnificationFilter(int)
Magnification filter mode.