VTK
|
00001 /*========================================================================= 00002 00003 Program: Visualization Toolkit 00004 Module: vtkOpenGLOpacityTable.h 00005 00006 Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen 00007 All rights reserved. 00008 See Copyright.txt or http://www.kitware.com/Copyright.htm for details. 00009 00010 This software is distributed WITHOUT ANY WARRANTY; without even 00011 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 00012 PURPOSE. See the above copyright notice for more information. 00013 00014 =========================================================================*/ 00015 00016 #ifndef vtkOpenGLVolumeOpacityTable_h_ 00017 #define vtkOpenGLVolumeOpacityTable_h_ 00018 00019 #include <vtkPiecewiseFunction.h> 00020 #include <vtkVolumeMapper.h> 00021 00022 #include <vtk_glew.h> 00023 00024 //---------------------------------------------------------------------------- 00025 class vtkOpenGLOpacityTable 00026 { 00027 public: 00028 //-------------------------------------------------------------------------- 00029 vtkOpenGLOpacityTable(int width = 1024) 00030 { 00031 this->TextureId = 0; 00032 this->LastBlendMode = vtkVolumeMapper::MAXIMUM_INTENSITY_BLEND; 00033 this->TextureWidth = width; 00034 this->TextureHeight = 0; 00035 this->LastSampleDistance = 1.0; 00036 this->Table = 0; 00037 this->Loaded = false; 00038 this->LastLinearInterpolation = false; 00039 this->LastRange[0] = this->LastRange[1] = 0.0; 00040 } 00041 00042 //-------------------------------------------------------------------------- 00043 ~vtkOpenGLOpacityTable() 00044 { 00045 if (this->TextureId != 0) 00046 { 00047 glDeleteTextures(1, &this->TextureId); 00048 this->TextureId=0; 00049 } 00050 00051 if (this->Table!=0) 00052 { 00053 delete[] this->Table; 00054 this->Table=0; 00055 } 00056 } 00057 00058 // Check if opacity transfer function texture is loaded. 00059 //-------------------------------------------------------------------------- 00060 bool IsLoaded() 00061 { 00062 return this->Loaded; 00063 } 00064 00065 // Bind texture. 00066 //-------------------------------------------------------------------------- 00067 void Bind() 00068 { 00069 // Activate texture 2 00070 glActiveTexture(GL_TEXTURE2); 00071 glBindTexture(GL_TEXTURE_1D, this->TextureId); 00072 } 00073 00074 // Update opacity tranfer function texture. 00075 //-------------------------------------------------------------------------- 00076 void Update(vtkPiecewiseFunction* scalarOpacity, 00077 int blendMode, 00078 double sampleDistance, 00079 double range[2], 00080 double unitDistance, 00081 bool linearInterpolation) 00082 { 00083 // Activate texture 2 00084 glActiveTexture(GL_TEXTURE2); 00085 00086 bool needUpdate=false; 00087 if(this->TextureId == 0) 00088 { 00089 glGenTextures(1,&this->TextureId); 00090 needUpdate = true; 00091 } 00092 00093 if (this->LastRange[0] != range[0] || 00094 this->LastRange[1] != range[1]) 00095 { 00096 needUpdate = true; 00097 this->LastRange[0] = range[0]; 00098 this->LastRange[1] = range[1]; 00099 } 00100 00101 glBindTexture(GL_TEXTURE_1D,this->TextureId); 00102 if(needUpdate) 00103 { 00104 glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, 00105 GL_CLAMP_TO_EDGE); 00106 } 00107 00108 if(scalarOpacity->GetMTime() > this->BuildTime || 00109 (this->LastBlendMode != blendMode) || 00110 (blendMode == vtkVolumeMapper::COMPOSITE_BLEND && 00111 this->LastSampleDistance != sampleDistance) || 00112 needUpdate || !this->Loaded) 00113 { 00114 this->Loaded = false; 00115 if(this->Table == 0) 00116 { 00117 this->Table = new float[this->TextureWidth]; 00118 } 00119 00120 scalarOpacity->GetTable(range[0], range[1], this->TextureWidth, this->Table); 00121 this->LastBlendMode = blendMode; 00122 00123 // Correct the opacity array for the spacing between the planes if we 00124 // are using a composite blending operation 00125 // TODO Fix this code for sample distance in three dimensions 00126 if(blendMode == vtkVolumeMapper::COMPOSITE_BLEND) 00127 { 00128 float* ptr = this->Table; 00129 double factor = sampleDistance/unitDistance; 00130 int i=0; 00131 while(i < this->TextureWidth) 00132 { 00133 if(*ptr > 0.0001f) 00134 { 00135 *ptr = static_cast<float>(1.0-pow(1.0-static_cast<double>(*ptr), 00136 factor)); 00137 } 00138 ++ptr; 00139 ++i; 00140 } 00141 this->LastSampleDistance = sampleDistance; 00142 } 00143 else if (blendMode==vtkVolumeMapper::ADDITIVE_BLEND) 00144 { 00145 float* ptr = this->Table; 00146 double factor = sampleDistance/unitDistance; 00147 int i = 0; 00148 while( i < this->TextureWidth) 00149 { 00150 if(*ptr > 0.0001f) 00151 { 00152 *ptr = static_cast<float>(static_cast<double>(*ptr)*factor); 00153 } 00154 ++ptr; 00155 ++i; 00156 } 00157 this->LastSampleDistance = sampleDistance; 00158 } 00159 00160 glTexImage1D(GL_TEXTURE_1D, 0, GL_ALPHA16, this->TextureWidth, 00161 this->TextureHeight, GL_ALPHA, GL_FLOAT, this->Table); 00162 this->Loaded = true; 00163 this->BuildTime.Modified(); 00164 } 00165 00166 needUpdate= needUpdate || 00167 this->LastLinearInterpolation!=linearInterpolation; 00168 if(needUpdate) 00169 { 00170 this->LastLinearInterpolation = linearInterpolation; 00171 GLint value = linearInterpolation ? GL_LINEAR : GL_NEAREST; 00172 glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, value); 00173 glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, value); 00174 } 00175 00176 glActiveTexture(GL_TEXTURE0); 00177 } 00178 00179 protected: 00180 GLuint TextureId; 00181 int LastBlendMode; 00182 int TextureWidth; 00183 int TextureHeight; 00184 00185 double LastSampleDistance; 00186 vtkTimeStamp BuildTime; 00187 float *Table; 00188 bool Loaded; 00189 bool LastLinearInterpolation; 00190 double LastRange[2]; 00191 private: 00192 vtkOpenGLOpacityTable(const vtkOpenGLOpacityTable&); 00193 vtkOpenGLOpacityTable& operator=(const vtkOpenGLOpacityTable&); 00194 }; 00195 00196 //---------------------------------------------------------------------------- 00197 class vtkOpenGLOpacityTables 00198 { 00199 public: 00200 //-------------------------------------------------------------------------- 00201 vtkOpenGLOpacityTables(unsigned int numberOfTables) 00202 { 00203 this->Tables = new vtkOpenGLOpacityTable[numberOfTables]; 00204 this->NumberOfTables = numberOfTables; 00205 } 00206 00207 //-------------------------------------------------------------------------- 00208 ~vtkOpenGLOpacityTables() 00209 { 00210 delete [] this->Tables; 00211 } 00212 00213 // brief Get opacity table at a given index. 00214 //-------------------------------------------------------------------------- 00215 vtkOpenGLOpacityTable* GetTable(unsigned int i) 00216 { 00217 return &this->Tables[i]; 00218 } 00219 00220 // Get number of opacity tables. 00221 //-------------------------------------------------------------------------- 00222 unsigned int GetNumberOfTables() 00223 { 00224 return this->NumberOfTables; 00225 } 00226 00227 private: 00228 unsigned int NumberOfTables; 00229 vtkOpenGLOpacityTable *Tables; 00230 00231 // vtkOpenGLOpacityTables (Not implemented) 00232 vtkOpenGLOpacityTables(); 00233 00234 // vtkOpenGLOpacityTables (Not implemented) 00235 vtkOpenGLOpacityTables(const vtkOpenGLOpacityTables &other); 00236 00237 // operator = (Not implemented) 00238 vtkOpenGLOpacityTables &operator=(const vtkOpenGLOpacityTables &other); 00239 }; 00240 00241 #endif // vtkOpenGLVolumeOpacityTable_h_ 00242 // VTK-HeaderTest-Exclude: vtkOpenGLOpacityTable.h