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 
19 #include <vector>
20 
21 #include <vtkObjectFactory.h>
22 #include <vtkPiecewiseFunction.h>
23 #include <vtkTextureObject.h>
24 #include <vtkVolumeMapper.h>
25 #include <vtk_glew.h>
26 #include <vtkMath.h>
27 
28 
29 //----------------------------------------------------------------------------
31 {
32 public:
33 
35 
36  // Activate texture.
37  //--------------------------------------------------------------------------
38  void Activate()
39  {
40  if (!this->TextureObject)
41  {
42  return;
43  }
44  this->TextureObject->Activate();
45  }
46 
47  // Deactivate texture.
48  //--------------------------------------------------------------------------
49  void Deactivate()
50  {
51  if (!this->TextureObject)
52  {
53  return;
54  }
55  this->TextureObject->Deactivate();
56  }
57 
58  // Update opacity tranfer function texture.
59  //--------------------------------------------------------------------------
60  void Update(vtkPiecewiseFunction* scalarOpacity,
61  int blendMode,
62  double sampleDistance,
63  double range[2],
64  double unitDistance,
65  int filterValue,
66  vtkOpenGLRenderWindow* renWin)
67  {
68  bool needUpdate = false;
69  if (!this->TextureObject)
70  {
72  }
73 
74  this->TextureObject->SetContext(renWin);
75 
76  if (this->LastRange[0] != range[0] ||
77  this->LastRange[1] != range[1])
78  {
79  this->LastRange[0] = range[0];
80  this->LastRange[1] = range[1];
81  needUpdate = true;
82  }
83 
84  if(scalarOpacity->GetMTime() > this->BuildTime ||
85  this->TextureObject->GetMTime() > this->BuildTime ||
86  (this->LastBlendMode != blendMode) ||
87  (blendMode == vtkVolumeMapper::COMPOSITE_BLEND &&
88  this->LastSampleDistance != sampleDistance) ||
89  needUpdate || !this->TextureObject->GetHandle())
90  {
91  int const idealW = scalarOpacity->EstimateMinNumberOfSamples(this->LastRange[0],
92  this->LastRange[1]);
93  int const newWidth = this->GetMaximumSupportedTextureWidth(renWin, idealW);
94 
95  if(this->Table == NULL || this->TextureWidth != newWidth)
96  {
97  this->TextureWidth = newWidth;
98  delete [] this->Table;
99  this->Table = new float[this->TextureWidth];
100  }
101 
102  scalarOpacity->GetTable(this->LastRange[0],
103  this->LastRange[1],
104  this->TextureWidth,
105  this->Table);
106  this->LastBlendMode = blendMode;
107 
108  // Correct the opacity array for the spacing between the planes if we
109  // are using a composite blending operation
110  // TODO Fix this code for sample distance in three dimensions
111  if(blendMode == vtkVolumeMapper::COMPOSITE_BLEND)
112  {
113  float* ptr = this->Table;
114  double factor = sampleDistance/unitDistance;
115  int i=0;
116  while(i < this->TextureWidth)
117  {
118  if(*ptr > 0.0001f)
119  {
120  *ptr = static_cast<float>(1.0-pow(1.0-static_cast<double>(*ptr),
121  factor));
122  }
123  ++ptr;
124  ++i;
125  }
126  this->LastSampleDistance = sampleDistance;
127  }
128  else if (blendMode==vtkVolumeMapper::ADDITIVE_BLEND)
129  {
130  float* ptr = this->Table;
131  double factor = sampleDistance/unitDistance;
132  int i = 0;
133  while( i < this->TextureWidth)
134  {
135  if(*ptr > 0.0001f)
136  {
137  *ptr = static_cast<float>(static_cast<double>(*ptr)*factor);
138  }
139  ++ptr;
140  ++i;
141  }
142  this->LastSampleDistance = sampleDistance;
143  }
144 
146  this->TextureObject->SetMagnificationFilter(filterValue);
147  this->TextureObject->SetMinificationFilter(filterValue);
148  this->TextureObject->Create2DFromRaw(this->TextureWidth, 1, 1,
149  VTK_FLOAT,
150  this->Table);
151  this->LastInterpolation = filterValue;
152  this->BuildTime.Modified();
153  }
154 
155  if(this->LastInterpolation != filterValue)
156  {
157  this->LastInterpolation = filterValue;
158  this->TextureObject->SetMagnificationFilter(filterValue);
159  this->TextureObject->SetMinificationFilter(filterValue);
160  }
161  }
162 
163  //--------------------------------------------------------------------------
165  int idealWidth)
166  {
167  if (!this->TextureObject)
168  {
169  vtkErrorMacro("vtkTextureObject not initialized!");
170  return -1;
171  }
172 
173  // Try to match the next power of two.
174  idealWidth = vtkMath::NearestPowerOfTwo(idealWidth);
175  int const maxWidth = this->TextureObject->GetMaximumTextureSize(renWin);
176  if (maxWidth < 0)
177  {
178  vtkErrorMacro("Failed to query max texture size! using default 1024.");
179  return 1024;
180  }
181 
182  if (maxWidth >= idealWidth)
183  {
184  idealWidth = vtkMath::Max(1024, idealWidth);
185  return idealWidth;
186  }
187 
188  vtkWarningMacro("This OpenGL implementation does not support the required "
189  "texture size of " << idealWidth << ". Falling back to maximum allowed, "
190  << maxWidth << "." << "This may cause an incorrect color table mapping.");
191 
192  return maxWidth;
193  }
194 
195  // Get the texture unit
196  //--------------------------------------------------------------------------
197  int GetTextureUnit(void)
198  {
199  if (!this->TextureObject)
200  {
201  return -1;
202  }
203  return this->TextureObject->GetTextureUnit();
204  }
205 
206  //--------------------------------------------------------------------------
208  {
209  if (this->TextureObject)
210  {
212  this->TextureObject->Delete();
213  this->TextureObject = 0;
214  }
215  }
216 
217 protected:
218 
219  //--------------------------------------------------------------------------
220  vtkOpenGLVolumeOpacityTable(int width = 1024)
221  {
222  this->TextureObject = NULL;
224  this->TextureWidth = width;
225  this->LastSampleDistance = 1.0;
226  this->Table = NULL;
227  this->LastInterpolation = -1;
228  this->LastRange[0] = this->LastRange[1] = 0.0;
229  }
230 
231  //--------------------------------------------------------------------------
233  {
234  if (this->TextureObject)
235  {
236  this->TextureObject->Delete();
237  this->TextureObject = NULL;
238  }
239 
240  delete[] this->Table;
241  }
242 
243 
247 
250  float *Table;
252  double LastRange[2];
253 
254 private:
256  VTK_DELETE_FUNCTION;
258  VTK_DELETE_FUNCTION;
259 };
260 
262 
263 
266 {
267 public:
268  //--------------------------------------------------------------------------
269  vtkOpenGLVolumeOpacityTables(unsigned int numberOfTables)
270  {
271  this->Tables.reserve(static_cast<size_t>(numberOfTables));
272 
273  for (unsigned int i = 0; i < numberOfTables; i++)
274  {
275  vtkOpenGLVolumeOpacityTable* table = vtkOpenGLVolumeOpacityTable::New();
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  //--------------------------------------------------------------------------
292  vtkOpenGLVolumeOpacityTable* GetTable(unsigned int i)
293  {
294  if (i >= this->Tables.size())
295  {
296  return NULL;
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 
318 private:
319  std::vector<vtkOpenGLVolumeOpacityTable*> Tables;
320 
321  vtkOpenGLVolumeOpacityTables() VTK_DELETE_FUNCTION;
322 
323  vtkOpenGLVolumeOpacityTables(const vtkOpenGLVolumeOpacityTables &other) VTK_DELETE_FUNCTION;
324 
325  vtkOpenGLVolumeOpacityTables &operator=(const vtkOpenGLVolumeOpacityTables &other) VTK_DELETE_FUNCTION;
326 };
327 
328 #endif // vtkOpenGLVolumeOpacityTable_h
329 // VTK-HeaderTest-Exclude: vtkOpenGLVolumeOpacityTable.h
OpenGL rendering window.
vtkOpenGLVolumeOpacityTables(unsigned int numberOfTables)
abstract base class for most VTK objects
Definition: vtkObject.h:59
void ReleaseGraphicsResources(vtkWindow *window)
void SetContext(vtkRenderWindow *)
Get/Set the context.
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 Deactivate(unsigned int texUnit)
Set the active tex unit and bind (using our bind).
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].
void GetTable(double x1, double x2, int size, float *table, int stride=1)
Fills in an array of function values evaluated at regular intervals.
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:1230
vtkStandardNewMacro(vtkOpenGLVolumeOpacityTable)
virtual void SetMinificationFilter(int)
Minification filter mode.
virtual vtkMTimeType GetMTime()
Return this object'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.
void Activate(unsigned int texUnit)
Set the active tex unit and bind (using our bind).
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.
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 arugments provided.
Definition: vtkMath.h:1268
virtual void Delete()
Delete a VTK object.
virtual void SetMagnificationFilter(int)
Magnification filter mode.