00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #include "vtkMitkOpenGLGPUVolumeRayCastMapper.h"
00017
00018
00019 #if ((VTK_MAJOR_VERSION > 5) || ((VTK_MAJOR_VERSION==5) && (VTK_MINOR_VERSION>=6) ))
00020
00021 #include "vtkObjectFactory.h"
00022 #include "vtkVolume.h"
00023 #include "vtkRenderer.h"
00024 #include "vtkRenderWindow.h"
00025 #include "vtkCamera.h"
00026 #include "vtkMatrix4x4.h"
00027 #include "vtkImageData.h"
00028
00029 #include "vtkTimerLog.h"
00030
00031 #include "vtkVolumeProperty.h"
00032 #include "vtkColorTransferFunction.h"
00033 #include "vtkPiecewiseFunction.h"
00034
00035 #include "vtkOpenGLExtensionManager.h"
00036 #include "vtkgl.h"
00037
00038 #ifndef VTK_IMPLEMENT_MESA_CXX
00039 # include "vtkOpenGL.h"
00040 #endif
00041
00042 #include <math.h>
00043
00044 #include <vtkstd/string>
00045 #include <vtkstd/map>
00046 #include <vtkstd/vector>
00047 #include <assert.h>
00048
00049 #include "vtkClipDataSet.h"
00050 #include "vtkCellArray.h"
00051 #include "vtkDoubleArray.h"
00052 #include "vtkFloatArray.h"
00053 #include "vtkGeometryFilter.h"
00054 #include "vtkMath.h"
00055 #include "vtkPlane.h"
00056 #include "vtkPlaneCollection.h"
00057 #include "vtkPlanes.h"
00058 #include "vtkPolyData.h"
00059 #include "vtkPointData.h"
00060 #include "vtkCellData.h"
00061 #include "vtkPoints.h"
00062 #include "vtkUnsignedCharArray.h"
00063 #include "vtkUnsignedShortArray.h"
00064 #include "vtkUnsignedIntArray.h"
00065 #include "vtkUnstructuredGrid.h"
00066 #include "vtkVoxel.h"
00067
00068 #include "vtkClipConvexPolyData.h"
00069 #include "vtkClipPolyData.h"
00070 #include "vtkDensifyPolyData.h"
00071
00072 #include "vtkImageResample.h"
00073
00074 #include <sstream>
00075 #include <stdlib.h>
00076
00077 #include "vtkDataSetTriangleFilter.h"
00078
00079 #include "vtkAbstractArray.h"
00080
00081 #include "vtkTessellatedBoxSource.h"
00082 #include "vtkCleanPolyData.h"
00083
00084 #include "vtkCommand.h"
00085 #include "vtkPerlinNoise.h"
00086
00087 #include <vtksys/ios/sstream>
00088 #include "vtkStdString.h"
00089
00090
00091
00092
00093 class vtkUnsupportedRequiredExtensionsStringStream
00094 {
00095 public:
00096 vtkstd::ostringstream Stream;
00097 vtkUnsupportedRequiredExtensionsStringStream()
00098 {
00099 }
00100 private:
00101
00102 vtkUnsupportedRequiredExtensionsStringStream(const vtkUnsupportedRequiredExtensionsStringStream &other);
00103
00104 vtkUnsupportedRequiredExtensionsStringStream &operator=(const vtkUnsupportedRequiredExtensionsStringStream &other);
00105 };
00106
00107 class vtkMapDataArrayTextureId
00108 {
00109 public:
00110 vtkstd::map<vtkImageData *,vtkKWScalarField *> Map;
00111 vtkMapDataArrayTextureId()
00112 {
00113 }
00114 private:
00115
00116 vtkMapDataArrayTextureId(const vtkMapDataArrayTextureId &other);
00117
00118 vtkMapDataArrayTextureId &operator=(const vtkMapDataArrayTextureId &other);
00119 };
00120
00121 class vtkMapMaskTextureId
00122 {
00123 public:
00124 vtkstd::map<vtkImageData *,vtkKWMask *> Map;
00125 vtkMapMaskTextureId()
00126 {
00127 }
00128 private:
00129
00130 vtkMapMaskTextureId(const vtkMapMaskTextureId &other);
00131
00132 vtkMapMaskTextureId &operator=(const vtkMapMaskTextureId &other);
00133 };
00134
00135
00136 extern const char *vtkMitkGPUVolumeRayCastMapper_CompositeFS;
00137 extern const char *vtkMitkGPUVolumeRayCastMapper_CompositeCroppingFS;
00138 extern const char *vtkMitkGPUVolumeRayCastMapper_CompositeNoCroppingFS;
00139 extern const char *vtkMitkGPUVolumeRayCastMapper_HeaderFS;
00140 extern const char *vtkMitkGPUVolumeRayCastMapper_MIPFS;
00141 extern const char *vtkMitkGPUVolumeRayCastMapper_MIPFourDependentFS;
00142 extern const char *vtkMitkGPUVolumeRayCastMapper_MIPFourDependentCroppingFS;
00143 extern const char *vtkMitkGPUVolumeRayCastMapper_MIPFourDependentNoCroppingFS;
00144 extern const char *vtkMitkGPUVolumeRayCastMapper_MIPCroppingFS;
00145 extern const char *vtkMitkGPUVolumeRayCastMapper_MIPNoCroppingFS;
00146 extern const char *vtkMitkGPUVolumeRayCastMapper_ParallelProjectionFS;
00147 extern const char *vtkMitkGPUVolumeRayCastMapper_PerspectiveProjectionFS;
00148 extern const char *vtkMitkGPUVolumeRayCastMapper_ScaleBiasFS;
00149 extern const char *vtkMitkGPUVolumeRayCastMapper_MinIPFS;
00150 extern const char *vtkMitkGPUVolumeRayCastMapper_MinIPFourDependentFS;
00151 extern const char *vtkMitkGPUVolumeRayCastMapper_MinIPFourDependentCroppingFS;
00152 extern const char *vtkMitkGPUVolumeRayCastMapper_MinIPFourDependentNoCroppingFS;
00153 extern const char *vtkMitkGPUVolumeRayCastMapper_MinIPCroppingFS;
00154 extern const char *vtkMitkGPUVolumeRayCastMapper_MinIPNoCroppingFS;
00155 extern const char *vtkMitkGPUVolumeRayCastMapper_CompositeMaskFS;
00156 extern const char *vtkMitkGPUVolumeRayCastMapper_NoShadeFS;
00157 extern const char *vtkMitkGPUVolumeRayCastMapper_ShadeFS;
00158 extern const char *vtkMitkGPUVolumeRayCastMapper_OneComponentFS;
00159 extern const char *vtkMitkGPUVolumeRayCastMapper_FourComponentsFS;
00160
00161 enum
00162 {
00163 vtkMitkOpenGLGPUVolumeRayCastMapperProjectionNotInitialized=-1,
00164 vtkMitkOpenGLGPUVolumeRayCastMapperProjectionPerspective=0,
00165 vtkMitkOpenGLGPUVolumeRayCastMapperProjectionParallel=1
00166 };
00167
00168 enum
00169 {
00170 vtkMitkOpenGLGPUVolumeRayCastMapperMethodNotInitialized,
00171 vtkMitkOpenGLGPUVolumeRayCastMapperMethodMIP,
00172 vtkMitkOpenGLGPUVolumeRayCastMapperMethodMIPFourDependent,
00173 vtkMitkOpenGLGPUVolumeRayCastMapperMethodComposite,
00174 vtkMitkOpenGLGPUVolumeRayCastMapperMethodMinIP,
00175 vtkMitkOpenGLGPUVolumeRayCastMapperMethodMinIPFourDependent,
00176 vtkMitkOpenGLGPUVolumeRayCastMapperMethodCompositeMask
00177 };
00178
00179
00180 enum
00181 {
00182 vtkMitkOpenGLGPUVolumeRayCastMapperComponentNotInitialized=-1,
00183 vtkMitkOpenGLGPUVolumeRayCastMapperComponentOne=0,
00184 vtkMitkOpenGLGPUVolumeRayCastMapperComponentFour=1,
00185 vtkMitkOpenGLGPUVolumeRayCastMapperComponentNotUsed=2
00186 };
00187
00188
00189 enum
00190 {
00191 vtkMitkOpenGLGPUVolumeRayCastMapperShadeNotInitialized=-1,
00192 vtkMitkOpenGLGPUVolumeRayCastMapperShadeNo=0,
00193 vtkMitkOpenGLGPUVolumeRayCastMapperShadeYes=1,
00194 vtkMitkOpenGLGPUVolumeRayCastMapperShadeNotUsed=2
00195 };
00196
00197
00198
00199 enum
00200 {
00201 vtkMitkOpenGLGPUVolumeRayCastMapperCroppingNotInitialized,
00202 vtkMitkOpenGLGPUVolumeRayCastMapperCompositeCropping,
00203 vtkMitkOpenGLGPUVolumeRayCastMapperCompositeNoCropping,
00204 vtkMitkOpenGLGPUVolumeRayCastMapperMIPCropping,
00205 vtkMitkOpenGLGPUVolumeRayCastMapperMIPNoCropping,
00206 vtkMitkOpenGLGPUVolumeRayCastMapperMIPFourDependentCropping,
00207 vtkMitkOpenGLGPUVolumeRayCastMapperMIPFourDependentNoCropping,
00208 vtkMitkOpenGLGPUVolumeRayCastMapperMinIPCropping,
00209 vtkMitkOpenGLGPUVolumeRayCastMapperMinIPNoCropping,
00210 vtkMitkOpenGLGPUVolumeRayCastMapperMinIPFourDependentCropping,
00211 vtkMitkOpenGLGPUVolumeRayCastMapperMinIPFourDependentNoCropping
00212 };
00213
00214 enum
00215 {
00216 vtkMitkOpenGLGPUVolumeRayCastMapperTextureObjectDepthMap=0,
00217 vtkMitkOpenGLGPUVolumeRayCastMapperTextureObjectFrameBufferLeftFront
00218 };
00219
00220 const int vtkMitkOpenGLGPUVolumeRayCastMapperNumberOfTextureObjects=vtkMitkOpenGLGPUVolumeRayCastMapperTextureObjectFrameBufferLeftFront+2;
00221
00222 const int vtkMitkOpenGLGPUVolumeRayCastMapperOpacityTableSize=1024;
00223
00224 #ifndef VTK_IMPLEMENT_MESA_CXX
00225 vtkCxxRevisionMacro(vtkMitkOpenGLGPUVolumeRayCastMapper, "$Revision: 1.9 $");
00226 vtkStandardNewMacro(vtkMitkOpenGLGPUVolumeRayCastMapper);
00227 #endif
00228
00229
00230
00231
00232 class vtkOpacityTable
00233 {
00234 public:
00235 vtkOpacityTable()
00236 {
00237 this->TextureId=0;
00238 this->LastBlendMode=vtkVolumeMapper::MAXIMUM_INTENSITY_BLEND;
00239 this->LastSampleDistance=1.0;
00240 this->Table=0;
00241 this->Loaded=false;
00242 this->LastLinearInterpolation=false;
00243 }
00244
00245 ~vtkOpacityTable()
00246 {
00247 if(this->TextureId!=0)
00248 {
00249 glDeleteTextures(1,&this->TextureId);
00250 this->TextureId=0;
00251 }
00252 if(this->Table!=0)
00253 {
00254 delete[] this->Table;
00255 this->Table=0;
00256 }
00257 }
00258
00259 bool IsLoaded()
00260 {
00261 return this->Loaded;
00262 }
00263
00264 void Bind()
00265 {
00266 assert("pre: uptodate" && this->Loaded);
00267 glBindTexture(GL_TEXTURE_1D,this->TextureId);
00268 }
00269
00270
00271 void Update(vtkPiecewiseFunction *scalarOpacity,
00272 int blendMode,
00273 double sampleDistance,
00274 double range[2],
00275 double unitDistance,
00276 bool linearInterpolation)
00277 {
00278 assert("pre: scalarOpacity_exists" && scalarOpacity!=0);
00279 bool needUpdate=false;
00280 if(this->TextureId==0)
00281 {
00282 glGenTextures(1,&this->TextureId);
00283 needUpdate=true;
00284 }
00285 glBindTexture(GL_TEXTURE_1D,this->TextureId);
00286 if(needUpdate)
00287 {
00288 glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S,
00289 vtkgl::CLAMP_TO_EDGE);
00290 }
00291 if(scalarOpacity->GetMTime() > this->BuildTime ||
00292 (this->LastBlendMode!=blendMode)
00293 || (blendMode==vtkVolumeMapper::COMPOSITE_BLEND &&
00294 this->LastSampleDistance!=sampleDistance)
00295 || needUpdate || !this->Loaded)
00296 {
00297 this->Loaded=false;
00298 if(this->Table==0)
00299 {
00300 this->Table=
00301 new float[vtkMitkOpenGLGPUVolumeRayCastMapperOpacityTableSize];
00302 }
00303
00304 scalarOpacity->GetTable(range[0],range[1],
00305 vtkMitkOpenGLGPUVolumeRayCastMapperOpacityTableSize,
00306 this->Table);
00307
00308 this->LastBlendMode=blendMode;
00309
00310
00311
00312 if(blendMode==vtkVolumeMapper::COMPOSITE_BLEND)
00313 {
00314 float *ptr=this->Table;
00315 double factor=sampleDistance/unitDistance;
00316 int i=0;
00317 while(i<vtkMitkOpenGLGPUVolumeRayCastMapperOpacityTableSize)
00318 {
00319 if(*ptr>0.0001f)
00320 {
00321 *ptr=static_cast<float>(1.0-pow(1.0-static_cast<double>(*ptr),
00322 factor));
00323 }
00324 ++ptr;
00325 ++i;
00326 }
00327 this->LastSampleDistance=sampleDistance;
00328 }
00329 glTexImage1D(GL_TEXTURE_1D,0,GL_ALPHA16,
00330 vtkMitkOpenGLGPUVolumeRayCastMapperOpacityTableSize,0,
00331 GL_ALPHA,GL_FLOAT,this->Table);
00332 vtkMitkOpenGLGPUVolumeRayCastMapper::PrintError("1d opacity texture is too large");
00333 this->Loaded=true;
00334 this->BuildTime.Modified();
00335 }
00336
00337 needUpdate=needUpdate ||
00338 this->LastLinearInterpolation!=linearInterpolation;
00339 if(needUpdate)
00340 {
00341 this->LastLinearInterpolation=linearInterpolation;
00342 GLint value;
00343 if(linearInterpolation)
00344 {
00345 value=GL_LINEAR;
00346 }
00347 else
00348 {
00349 value=GL_NEAREST;
00350 }
00351 glTexParameteri(GL_TEXTURE_1D,GL_TEXTURE_MIN_FILTER,value);
00352 glTexParameteri(GL_TEXTURE_1D,GL_TEXTURE_MAG_FILTER,value);
00353 }
00354 }
00355 protected:
00356 GLuint TextureId;
00357 int LastBlendMode;
00358 double LastSampleDistance;
00359 vtkTimeStamp BuildTime;
00360 float *Table;
00361 bool Loaded;
00362 bool LastLinearInterpolation;
00363 };
00364
00365
00366
00367
00368 class vtkOpacityTables
00369 {
00370 public:
00371 vtkstd::vector<vtkOpacityTable> Vector;
00372 vtkOpacityTables(size_t numberOfLevels)
00373 : Vector(numberOfLevels)
00374 {
00375 }
00376 private:
00377
00378 vtkOpacityTables(const vtkOpacityTables &other);
00379
00380 vtkOpacityTables &operator=(const vtkOpacityTables &other);
00381 };
00382
00383
00384 class vtkRGBTable
00385 {
00386 public:
00387 vtkRGBTable()
00388 {
00389 this->TextureId=0;
00390 this->Table=0;
00391 this->Loaded=false;
00392 this->LastLinearInterpolation=false;
00393 }
00394
00395 ~vtkRGBTable()
00396 {
00397 if(this->TextureId!=0)
00398 {
00399 glDeleteTextures(1,&this->TextureId);
00400 this->TextureId=0;
00401 }
00402 if(this->Table!=0)
00403 {
00404 delete[] this->Table;
00405 this->Table=0;
00406 }
00407 }
00408
00409 bool IsLoaded()
00410 {
00411 return this->Loaded;
00412 }
00413
00414 void Bind()
00415 {
00416 assert("pre: uptodate" && this->Loaded);
00417 glBindTexture(GL_TEXTURE_1D,this->TextureId);
00418 }
00419
00420
00421
00422 void Update(vtkColorTransferFunction *scalarRGB,
00423 double range[2],
00424 bool linearInterpolation)
00425 {
00426 assert("pre: scalarRGB_exists" && scalarRGB!=0);
00427 bool needUpdate=false;
00428 if(this->TextureId==0)
00429 {
00430 glGenTextures(1,&this->TextureId);
00431 needUpdate=true;
00432 }
00433 glBindTexture(GL_TEXTURE_1D,this->TextureId);
00434 if(needUpdate)
00435 {
00436 glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S,
00437 vtkgl::CLAMP_TO_EDGE);
00438 }
00439 if(scalarRGB->GetMTime() > this->BuildTime
00440 || needUpdate || !this->Loaded)
00441 {
00442 this->Loaded=false;
00443 if(this->Table==0)
00444 {
00445 this->Table=
00446 new float[vtkMitkOpenGLGPUVolumeRayCastMapperOpacityTableSize*3];
00447 }
00448
00449 scalarRGB->GetTable(range[0],range[1],
00450 vtkMitkOpenGLGPUVolumeRayCastMapperOpacityTableSize,
00451 this->Table);
00452
00453 glTexImage1D(GL_TEXTURE_1D,0,GL_RGB16,
00454 vtkMitkOpenGLGPUVolumeRayCastMapperOpacityTableSize,0,
00455 GL_RGB,GL_FLOAT,this->Table);
00456 vtkMitkOpenGLGPUVolumeRayCastMapper::PrintError("1d RGB texture is too large");
00457 this->Loaded=true;
00458 this->BuildTime.Modified();
00459 }
00460
00461 needUpdate=needUpdate ||
00462 this->LastLinearInterpolation!=linearInterpolation;
00463 if(needUpdate)
00464 {
00465 this->LastLinearInterpolation=linearInterpolation;
00466 GLint value;
00467 if(linearInterpolation)
00468 {
00469 value=GL_LINEAR;
00470 }
00471 else
00472 {
00473 value=GL_NEAREST;
00474 }
00475 glTexParameteri(GL_TEXTURE_1D,GL_TEXTURE_MIN_FILTER,value);
00476 glTexParameteri(GL_TEXTURE_1D,GL_TEXTURE_MAG_FILTER,value);
00477 }
00478 }
00479 protected:
00480 GLuint TextureId;
00481 vtkTimeStamp BuildTime;
00482 float *Table;
00483 bool Loaded;
00484 bool LastLinearInterpolation;
00485 };
00486
00487
00488
00489
00490 class vtkKWScalarField
00491 {
00492 public:
00493 vtkKWScalarField()
00494 {
00495 this->TextureId=0;
00496 this->Loaded=false;
00497 this->Supports_GL_ARB_texture_float=false;
00498 this->LoadedTableRange[0]=0.0;
00499 this->LoadedTableRange[1]=1.0;
00500 this->LoadedExtent[0]=VTK_INT_MAX;
00501 this->LoadedExtent[1]=VTK_INT_MIN;
00502 this->LoadedExtent[2]=VTK_INT_MAX;
00503 this->LoadedExtent[3]=VTK_INT_MIN;
00504 this->LoadedExtent[4]=VTK_INT_MAX;
00505 this->LoadedExtent[5]=VTK_INT_MIN;
00506 }
00507 ~vtkKWScalarField()
00508 {
00509 if(this->TextureId!=0)
00510 {
00511 glDeleteTextures(1,&this->TextureId);
00512 this->TextureId=0;
00513 }
00514 }
00515
00516 vtkTimeStamp GetBuildTime()
00517 {
00518 return this->BuildTime;
00519 }
00520
00521 void Bind()
00522 {
00523 assert("pre: uptodate" && this->Loaded);
00524 glBindTexture(vtkgl::TEXTURE_3D,this->TextureId);
00525 }
00526
00527 void Update(vtkImageData *input,
00528 int cellFlag,
00529 int textureExtent[6],
00530 int scalarMode,
00531 int arrayAccessMode,
00532 int arrayId,
00533 const char *arrayName,
00534 bool linearInterpolation,
00535 double tableRange[2],
00536 int maxMemoryInBytes)
00537 {
00538 bool needUpdate=false;
00539 bool modified=false;
00540 if(this->TextureId==0)
00541 {
00542 glGenTextures(1,&this->TextureId);
00543 needUpdate=true;
00544 }
00545 glBindTexture(vtkgl::TEXTURE_3D,this->TextureId);
00546
00547 int obsolete=needUpdate || !this->Loaded || input->GetMTime()>this->BuildTime;
00548 if(!obsolete)
00549 {
00550 obsolete=cellFlag!=this->LoadedCellFlag;
00551 int i=0;
00552 while(!obsolete && i<6)
00553 {
00554 obsolete=obsolete || this->LoadedExtent[i]>textureExtent[i];
00555 ++i;
00556 obsolete=obsolete || this->LoadedExtent[i]<textureExtent[i];
00557 ++i;
00558 }
00559 }
00560
00561 if(!obsolete)
00562 {
00563 obsolete=this->LoadedTableRange[0]!=tableRange[0] ||
00564 this->LoadedTableRange[1]!=tableRange[1];
00565 }
00566
00567 if(obsolete)
00568 {
00569 this->Loaded=false;
00570 int dim[3];
00571 input->GetDimensions(dim);
00572
00573 GLint internalFormat=0;
00574 GLenum format=0;
00575 GLenum type=0;
00576
00577 double shift=0.0;
00578 double scale=1.0;
00579 int needTypeConversion=0;
00580 vtkDataArray *sliceArray=0;
00581
00582 vtkDataArray *scalars=
00583 vtkAbstractMapper::GetScalars(input,scalarMode,arrayAccessMode,
00584 arrayId,arrayName,
00585 this->LoadedCellFlag);
00586
00587
00588
00589
00590 int scalarType=scalars->GetDataType();
00591 if(scalars->GetNumberOfComponents()==4)
00592 {
00593
00594 internalFormat=GL_RGBA16;
00595 format=GL_RGBA;
00596 type=GL_UNSIGNED_BYTE;
00597 }
00598 else
00599 {
00600
00601 switch(scalarType)
00602 {
00603 case VTK_FLOAT:
00604 if(this->Supports_GL_ARB_texture_float)
00605 {
00606 internalFormat=vtkgl::INTENSITY16F_ARB;
00607 }
00608 else
00609 {
00610 internalFormat=GL_INTENSITY16;
00611 }
00612 format=GL_RED;
00613 type=GL_FLOAT;
00614 shift=-tableRange[0];
00615 scale=1/(tableRange[1]-tableRange[0]);
00616 break;
00617 case VTK_UNSIGNED_CHAR:
00618 internalFormat=GL_INTENSITY8;
00619 format=GL_RED;
00620 type=GL_UNSIGNED_BYTE;
00621 shift=-tableRange[0]/VTK_UNSIGNED_CHAR_MAX;
00622 scale=
00623 VTK_UNSIGNED_CHAR_MAX/(tableRange[1]-tableRange[0]);
00624 break;
00625 case VTK_SIGNED_CHAR:
00626 internalFormat=GL_INTENSITY8;
00627 format=GL_RED;
00628 type=GL_BYTE;
00629 shift=-(2*tableRange[0]+1)/VTK_UNSIGNED_CHAR_MAX;
00630 scale=VTK_SIGNED_CHAR_MAX/(tableRange[1]-tableRange[0]);
00631 break;
00632 case VTK_CHAR:
00633
00634 assert("check: impossible case" && 0);
00635 break;
00636 case VTK_BIT:
00637
00638 assert("check: impossible case" && 0);
00639 break;
00640 case VTK_ID_TYPE:
00641
00642 assert("check: impossible case" && 0);
00643 break;
00644 case VTK_INT:
00645 internalFormat=GL_INTENSITY16;
00646 format=GL_RED;
00647 type=GL_INT;
00648
00649 shift=-(2*tableRange[0]+1)/VTK_UNSIGNED_INT_MAX;
00650 scale=VTK_INT_MAX/(tableRange[1]-tableRange[0]);
00651 break;
00652 case VTK_DOUBLE:
00653 case VTK___INT64:
00654 case VTK_LONG:
00655 case VTK_LONG_LONG:
00656 case VTK_UNSIGNED___INT64:
00657 case VTK_UNSIGNED_LONG:
00658 case VTK_UNSIGNED_LONG_LONG:
00659 needTypeConversion=1;
00660 if(this->Supports_GL_ARB_texture_float)
00661 {
00662 internalFormat=vtkgl::INTENSITY16F_ARB;
00663 }
00664 else
00665 {
00666 internalFormat=GL_INTENSITY16;
00667 }
00668 format=GL_RED;
00669 type=GL_FLOAT;
00670 shift=-tableRange[0];
00671 scale=1/(tableRange[1]-tableRange[0]);
00672 sliceArray=vtkFloatArray::New();
00673 break;
00674 case VTK_SHORT:
00675 internalFormat=GL_INTENSITY16;
00676 format=GL_RED;
00677 type=GL_SHORT;
00678
00679 shift=-(2*tableRange[0]+1)/VTK_UNSIGNED_SHORT_MAX;
00680 scale=VTK_SHORT_MAX/(tableRange[1]-tableRange[0]);
00681 break;
00682 case VTK_STRING:
00683
00684 assert("check: impossible case" && 0);
00685 break;
00686 case VTK_UNSIGNED_SHORT:
00687 internalFormat=GL_INTENSITY16;
00688 format=GL_RED;
00689 type=GL_UNSIGNED_SHORT;
00690
00691 shift=-tableRange[0]/VTK_UNSIGNED_SHORT_MAX;
00692 scale=
00693 VTK_UNSIGNED_SHORT_MAX/(tableRange[1]-tableRange[0]);
00694 break;
00695 case VTK_UNSIGNED_INT:
00696 internalFormat=GL_INTENSITY16;
00697 format=GL_RED;
00698 type=GL_UNSIGNED_INT;
00699
00700 shift=-tableRange[0]/VTK_UNSIGNED_INT_MAX;
00701 scale=VTK_UNSIGNED_INT_MAX/(tableRange[1]-tableRange[0]);
00702 break;
00703 default:
00704 assert("check: impossible case" && 0);
00705 break;
00706 }
00707 }
00708
00709
00710 int textureSize[3];
00711 int i=0;
00712 while(i<3)
00713 {
00714 textureSize[i]=textureExtent[2*i+1]-textureExtent[2*i]+1;
00715 ++i;
00716 }
00717
00718 GLint width;
00719 glGetIntegerv(vtkgl::MAX_3D_TEXTURE_SIZE,&width);
00720 this->Loaded=textureSize[0]<=width && textureSize[1]<=width
00721 && textureSize[2]<=width;
00722 if(this->Loaded)
00723 {
00724
00725
00726
00727 vtkgl::TexImage3D(vtkgl::PROXY_TEXTURE_3D,0,internalFormat,
00728 textureSize[0],textureSize[1],textureSize[2],0,
00729 format,type,0);
00730 glGetTexLevelParameteriv(vtkgl::PROXY_TEXTURE_3D,0,GL_TEXTURE_WIDTH,
00731 &width);
00732
00733 this->Loaded=width!=0;
00734 if(this->Loaded)
00735 {
00736
00737
00738
00739 vtkgl::TexImage3D(vtkgl::TEXTURE_3D,0,internalFormat,textureSize[0],
00740 textureSize[1],textureSize[2],0,format,type,0);
00741 GLenum errorCode=glGetError();
00742 this->Loaded=errorCode!=GL_OUT_OF_MEMORY;
00743 if(this->Loaded)
00744 {
00745
00746 if(errorCode!=GL_NO_ERROR)
00747 {
00748 cout<<"after try to load the texture";
00749 cout<<" ERROR (x"<<hex<<errorCode<<") "<<dec;
00750 cout<<vtkMitkOpenGLGPUVolumeRayCastMapper::OpenGLErrorMessage(static_cast<unsigned int>(errorCode));
00751 cout<<endl;
00752 }
00753
00754 this->Loaded=textureSize[0]*textureSize[1]*
00755 textureSize[2]*vtkAbstractArray::GetDataTypeSize(scalarType)*
00756 scalars->GetNumberOfComponents()<=maxMemoryInBytes;
00757 if(this->Loaded)
00758 {
00759
00760
00761
00762
00763
00764
00765 double bias=shift*scale;
00766
00767
00768
00769 glTexParameterf(vtkgl::TEXTURE_3D,vtkgl::TEXTURE_WRAP_R,vtkgl::CLAMP_TO_EDGE);
00770 glTexParameterf(vtkgl::TEXTURE_3D,GL_TEXTURE_WRAP_S,vtkgl::CLAMP_TO_EDGE);
00771 glTexParameterf(vtkgl::TEXTURE_3D,GL_TEXTURE_WRAP_T,vtkgl::CLAMP_TO_EDGE);
00772
00773 GLfloat borderColor[4]={0.0,0.0,0.0,0.0};
00774
00775 glTexParameterfv(vtkgl::TEXTURE_3D,GL_TEXTURE_BORDER_COLOR, borderColor);
00776
00777 if(needTypeConversion)
00778 {
00779
00780
00781
00782
00783
00784 glPixelStorei( GL_UNPACK_ALIGNMENT, 1 );
00785
00786
00787
00788
00789
00790 sliceArray->SetNumberOfComponents(1);
00791 sliceArray->SetNumberOfTuples(textureSize[0]*textureSize[1]);
00792
00793 void *slicePtr=sliceArray->GetVoidPointer(0);
00794 int k=0;
00795 int kInc=(dim[0]-cellFlag)*(dim[1]-cellFlag);
00796 int kOffset=(textureExtent[4]*(dim[1]-cellFlag)
00797 +textureExtent[2])*(dim[0]-cellFlag)
00798 +textureExtent[0];
00799 while(k<textureSize[2])
00800 {
00801 int j=0;
00802 int jOffset=0;
00803 int jDestOffset=0;
00804 while(j<textureSize[1])
00805 {
00806 i=0;
00807 while(i<textureSize[0])
00808 {
00809 sliceArray->SetTuple1(jDestOffset+i,
00810 (scalars->GetTuple1(kOffset+jOffset
00811 +i)
00812 +shift)*scale);
00813 ++i;
00814 }
00815 ++j;
00816 jOffset+=dim[0]-cellFlag;
00817 jDestOffset+=textureSize[0];
00818 }
00819
00820
00821
00822 vtkgl::TexSubImage3D(vtkgl::TEXTURE_3D, 0,
00823 0,0,k,
00824 textureSize[0],textureSize[1],
00825 1,
00826 format,type, slicePtr);
00827 ++k;
00828 kOffset+=kInc;
00829 }
00830 sliceArray->Delete();
00831 }
00832 else
00833 {
00834
00835
00836
00837
00838
00839
00840
00841 glFinish();
00842 glPixelTransferf(GL_RED_SCALE,static_cast<GLfloat>(scale));
00843 glPixelTransferf(GL_RED_BIAS,static_cast<GLfloat>(bias));
00844 glPixelStorei( GL_UNPACK_ALIGNMENT, 1 );
00845
00846 if(!(textureExtent[1]-textureExtent[0]+cellFlag==dim[0]))
00847 {
00848 glPixelStorei(GL_UNPACK_ROW_LENGTH,dim[0]-cellFlag);
00849 }
00850 if(!(textureExtent[3]-textureExtent[2]+cellFlag==dim[1]))
00851 {
00852 glPixelStorei(vtkgl::UNPACK_IMAGE_HEIGHT_EXT,
00853 dim[1]-cellFlag);
00854 }
00855 void *dataPtr=scalars->GetVoidPointer(
00856 ((textureExtent[4]*(dim[1]-cellFlag)+textureExtent[2])
00857 *(dim[0]-cellFlag)+textureExtent[0])
00858 *scalars->GetNumberOfComponents());
00859
00860 if(1)
00861 {
00862 vtkgl::TexImage3D(vtkgl::TEXTURE_3D, 0, internalFormat,
00863 textureSize[0],textureSize[1],textureSize[2],
00864 0,format,type,dataPtr);
00865 }
00866 else
00867 {
00868 GLuint pbo=0;
00869 vtkgl::GenBuffers(1,&pbo);
00870 vtkMitkOpenGLGPUVolumeRayCastMapper::PrintError("genbuffer");
00871 vtkgl::BindBuffer(vtkgl::PIXEL_UNPACK_BUFFER,pbo);
00872 vtkMitkOpenGLGPUVolumeRayCastMapper::PrintError("binbuffer");
00873 vtkgl::GLsizeiptr texSize=
00874 textureSize[0]*textureSize[1]*textureSize[2]*
00875 vtkAbstractArray::GetDataTypeSize(scalarType)*
00876 scalars->GetNumberOfComponents();
00877 vtkgl::BufferData(vtkgl::PIXEL_UNPACK_BUFFER,texSize,dataPtr,
00878 vtkgl::STREAM_DRAW);
00879 vtkMitkOpenGLGPUVolumeRayCastMapper::PrintError("bufferdata");
00880 vtkgl::TexImage3D(vtkgl::TEXTURE_3D, 0, internalFormat,
00881 textureSize[0],textureSize[1],textureSize[2],
00882 0,format,type,0);
00883 vtkMitkOpenGLGPUVolumeRayCastMapper::PrintError("teximage3d");
00884 vtkgl::BindBuffer(vtkgl::PIXEL_UNPACK_BUFFER,0);
00885 vtkMitkOpenGLGPUVolumeRayCastMapper::PrintError("bindbuffer to 0");
00886 vtkgl::DeleteBuffers(1,&pbo);
00887 }
00888 vtkMitkOpenGLGPUVolumeRayCastMapper::PrintError("3d texture is too large2");
00889
00890 glFinish();
00891
00892 glPixelStorei(GL_UNPACK_ROW_LENGTH,0);
00893 glPixelStorei(vtkgl::UNPACK_IMAGE_HEIGHT_EXT,0);
00894 glPixelTransferf(GL_RED_SCALE,1.0);
00895 glPixelTransferf(GL_RED_BIAS,0.0);
00896 }
00897 this->LoadedCellFlag=cellFlag;
00898 i=0;
00899 while(i<6)
00900 {
00901 this->LoadedExtent[i]=textureExtent[i];
00902 ++i;
00903 }
00904
00905 double spacing[3];
00906 double origin[3];
00907 input->GetSpacing(spacing);
00908 input->GetOrigin(origin);
00909 int swapBounds[3];
00910 swapBounds[0]=(spacing[0]<0);
00911 swapBounds[1]=(spacing[1]<0);
00912 swapBounds[2]=(spacing[2]<0);
00913
00914 if(!this->LoadedCellFlag)
00915 {
00916
00917
00918
00919
00920
00921
00922
00923
00924
00925
00926
00927 this->LoadedBounds[0]=origin[0]+
00928 static_cast<double>(this->LoadedExtent[0+swapBounds[0]])*spacing[0];
00929 this->LoadedBounds[2]=origin[1]+
00930 static_cast<double>(this->LoadedExtent[2+swapBounds[1]])*spacing[1];
00931 this->LoadedBounds[4]=origin[2]+
00932 static_cast<double>(this->LoadedExtent[4+swapBounds[2]])*spacing[2];
00933 this->LoadedBounds[1]=origin[0]+
00934 static_cast<double>(this->LoadedExtent[1-swapBounds[0]])*spacing[0];
00935 this->LoadedBounds[3]=origin[1]+
00936 static_cast<double>(this->LoadedExtent[3-swapBounds[1]])*spacing[1];
00937 this->LoadedBounds[5]=origin[2]+
00938 static_cast<double>(this->LoadedExtent[5-swapBounds[2]])*spacing[2];
00939
00940 }
00941 else
00942 {
00943 int wholeTextureExtent[6];
00944 input->GetExtent(wholeTextureExtent);
00945 i=1;
00946 while(i<6)
00947 {
00948 wholeTextureExtent[i]--;
00949 i+=2;
00950 }
00951
00952 i=0;
00953 while(i<3)
00954 {
00955 if(this->LoadedExtent[2*i]==wholeTextureExtent[2*i])
00956 {
00957 this->LoadedBounds[2*i+swapBounds[i]]=origin[i];
00958 }
00959 else
00960 {
00961 this->LoadedBounds[2*i+swapBounds[i]]=origin[i]+
00962 (static_cast<double>(this->LoadedExtent[2*i])+0.5)*spacing[i];
00963 }
00964
00965 if(this->LoadedExtent[2*i+1]==wholeTextureExtent[2*i+1])
00966 {
00967 this->LoadedBounds[2*i+1-swapBounds[i]]=origin[i]+
00968 (static_cast<double>(this->LoadedExtent[2*i+1])+1.0)*spacing[i];
00969 }
00970 else
00971 {
00972 this->LoadedBounds[2*i+1-swapBounds[i]]=origin[i]+
00973 (static_cast<double>(this->LoadedExtent[2*i+1])+0.5)*spacing[i];
00974 }
00975 ++i;
00976 }
00977 }
00978 this->LoadedTableRange[0]=tableRange[0];
00979 this->LoadedTableRange[1]=tableRange[1];
00980 modified=true;
00981 }
00982 else
00983 {
00984 }
00985 }
00986 else
00987 {
00988 }
00989 }
00990 else
00991 {
00992 }
00993 }
00994 else
00995 {
00996
00997 }
00998 }
00999
01000 if(this->Loaded &&
01001 (needUpdate || modified ||
01002 linearInterpolation!=this->LinearInterpolation))
01003 {
01004 this->LinearInterpolation=linearInterpolation;
01005 if(this->LinearInterpolation)
01006 {
01007 glTexParameterf(vtkgl::TEXTURE_3D,GL_TEXTURE_MIN_FILTER,
01008 GL_LINEAR);
01009 glTexParameterf(vtkgl::TEXTURE_3D,GL_TEXTURE_MAG_FILTER,
01010 GL_LINEAR);
01011 }
01012 else
01013 {
01014 glTexParameterf(vtkgl::TEXTURE_3D,GL_TEXTURE_MIN_FILTER,
01015 GL_NEAREST );
01016 glTexParameterf(vtkgl::TEXTURE_3D,GL_TEXTURE_MAG_FILTER,
01017 GL_NEAREST );
01018 }
01019 modified=true;
01020 }
01021 if(modified)
01022 {
01023 this->BuildTime.Modified();
01024 }
01025 }
01026
01027 double *GetLoadedBounds()
01028 {
01029 assert("pre: loaded" && this->Loaded);
01030 return this->LoadedBounds;
01031 }
01032
01033 vtkIdType *GetLoadedExtent()
01034 {
01035 assert("pre: loaded" && this->Loaded);
01036 return this->LoadedExtent;
01037 }
01038
01039 int GetLoadedCellFlag()
01040 {
01041 assert("pre: loaded" && this->Loaded);
01042 return this->LoadedCellFlag;
01043 }
01044
01045 bool IsLoaded()
01046 {
01047 return this->Loaded;
01048 }
01049
01050 bool GetSupports_GL_ARB_texture_float()
01051 {
01052 return this->Supports_GL_ARB_texture_float;
01053 }
01054
01055 void SetSupports_GL_ARB_texture_float(bool value)
01056 {
01057 this->Supports_GL_ARB_texture_float=value;
01058 }
01059
01060 protected:
01061 GLuint TextureId;
01062 vtkTimeStamp BuildTime;
01063 double LoadedBounds[6];
01064 vtkIdType LoadedExtent[6];
01065 int LoadedCellFlag;
01066 bool Loaded;
01067 bool LinearInterpolation;
01068 bool Supports_GL_ARB_texture_float;
01069 double LoadedTableRange[2];
01070 };
01071
01072
01073
01074 class vtkKWMask
01075 {
01076 public:
01077 vtkKWMask()
01078 {
01079 this->TextureId=0;
01080 this->Loaded=false;
01081 this->LoadedExtent[0]=VTK_INT_MAX;
01082 this->LoadedExtent[1]=VTK_INT_MIN;
01083 this->LoadedExtent[2]=VTK_INT_MAX;
01084 this->LoadedExtent[3]=VTK_INT_MIN;
01085 this->LoadedExtent[4]=VTK_INT_MAX;
01086 this->LoadedExtent[5]=VTK_INT_MIN;
01087 }
01088 ~vtkKWMask()
01089 {
01090 if(this->TextureId!=0)
01091 {
01092 glDeleteTextures(1,&this->TextureId);
01093 this->TextureId=0;
01094 }
01095 }
01096
01097 vtkTimeStamp GetBuildTime()
01098 {
01099 return this->BuildTime;
01100 }
01101
01102
01103 void Bind()
01104 {
01105 assert("pre: uptodate" && this->Loaded);
01106 glBindTexture(vtkgl::TEXTURE_3D,this->TextureId);
01107 }
01108
01109
01110 void Update(vtkImageData *input,
01111 int cellFlag,
01112 int textureExtent[6],
01113 int scalarMode,
01114 int arrayAccessMode,
01115 int arrayId,
01116 const char *arrayName,
01117 int maxMemoryInBytes)
01118 {
01119 bool needUpdate=false;
01120 bool modified=false;
01121 if(this->TextureId==0)
01122 {
01123 glGenTextures(1,&this->TextureId);
01124 needUpdate=true;
01125 }
01126 glBindTexture(vtkgl::TEXTURE_3D,this->TextureId);
01127
01128 int obsolete=needUpdate || !this->Loaded
01129 || input->GetMTime()>this->BuildTime;
01130 if(!obsolete)
01131 {
01132 obsolete=cellFlag!=this->LoadedCellFlag;
01133 int i=0;
01134 while(!obsolete && i<6)
01135 {
01136 obsolete=obsolete || this->LoadedExtent[i]>textureExtent[i];
01137 ++i;
01138 obsolete=obsolete || this->LoadedExtent[i]<textureExtent[i];
01139 ++i;
01140 }
01141 }
01142
01143 if(obsolete)
01144 {
01145 this->Loaded=false;
01146 int dim[3];
01147 input->GetDimensions(dim);
01148
01149 vtkDataArray *scalars=
01150 vtkAbstractMapper::GetScalars(input,scalarMode,arrayAccessMode,
01151 arrayId,arrayName,
01152 this->LoadedCellFlag);
01153
01154
01155
01156
01157 int scalarType=scalars->GetDataType();
01158 if(scalarType!=VTK_UNSIGNED_CHAR)
01159 {
01160 cout <<"mask should be VTK_UNSIGNED_CHAR." << endl;
01161 }
01162 if(scalars->GetNumberOfComponents()!=1)
01163 {
01164 cout <<"mask should be a one-component scalar field." << endl;
01165 }
01166
01167 GLint internalFormat=GL_ALPHA8;
01168 GLenum format=GL_ALPHA;
01169 GLenum type=GL_UNSIGNED_BYTE;
01170
01171
01172 int textureSize[3];
01173 int i=0;
01174 while(i<3)
01175 {
01176 textureSize[i]=textureExtent[2*i+1]-textureExtent[2*i]+1;
01177 ++i;
01178 }
01179
01180 GLint width;
01181 glGetIntegerv(vtkgl::MAX_3D_TEXTURE_SIZE,&width);
01182 this->Loaded=textureSize[0]<=width && textureSize[1]<=width
01183 && textureSize[2]<=width;
01184 if(this->Loaded)
01185 {
01186
01187
01188
01189 vtkgl::TexImage3D(vtkgl::PROXY_TEXTURE_3D,0,internalFormat,
01190 textureSize[0],textureSize[1],textureSize[2],0,
01191 format,type,0);
01192 glGetTexLevelParameteriv(vtkgl::PROXY_TEXTURE_3D,0,GL_TEXTURE_WIDTH,
01193 &width);
01194
01195 this->Loaded=width!=0;
01196 if(this->Loaded)
01197 {
01198
01199
01200
01201 vtkgl::TexImage3D(vtkgl::TEXTURE_3D,0,internalFormat,textureSize[0],
01202 textureSize[1],textureSize[2],0,format,type,0);
01203 GLenum errorCode=glGetError();
01204 this->Loaded=errorCode!=GL_OUT_OF_MEMORY;
01205 if(this->Loaded)
01206 {
01207
01208 if(errorCode!=GL_NO_ERROR)
01209 {
01210 cout<<"after try to load the texture";
01211 cout<<" ERROR (x"<<hex<<errorCode<<") "<<dec;
01212 cout<<vtkMitkOpenGLGPUVolumeRayCastMapper::OpenGLErrorMessage(static_cast<unsigned int>(errorCode));
01213 cout<<endl;
01214 }
01215
01216 this->Loaded=textureSize[0]*textureSize[1]*
01217 textureSize[2]*vtkAbstractArray::GetDataTypeSize(scalarType)*
01218 scalars->GetNumberOfComponents()<=maxMemoryInBytes;
01219 if(this->Loaded)
01220 {
01221
01222
01223
01224
01225
01226
01227
01228
01229 glTexParameterf(vtkgl::TEXTURE_3D,vtkgl::TEXTURE_WRAP_R,vtkgl::CLAMP_TO_EDGE);
01230 glTexParameterf(vtkgl::TEXTURE_3D,GL_TEXTURE_WRAP_S,vtkgl::CLAMP_TO_EDGE);
01231 glTexParameterf(vtkgl::TEXTURE_3D,GL_TEXTURE_WRAP_T,vtkgl::CLAMP_TO_EDGE);
01232
01233 GLfloat borderColor[4]={0.0,0.0,0.0,0.0};
01234
01235 glTexParameterfv(vtkgl::TEXTURE_3D,GL_TEXTURE_BORDER_COLOR, borderColor);
01236
01237 glPixelTransferf(GL_ALPHA_SCALE,1.0);
01238 glPixelTransferf(GL_ALPHA_BIAS,0.0);
01239 glPixelStorei(GL_UNPACK_ALIGNMENT,1);
01240
01241 if(!(textureExtent[1]-textureExtent[0]+cellFlag==dim[0]))
01242 {
01243 glPixelStorei(GL_UNPACK_ROW_LENGTH,dim[0]-cellFlag);
01244 }
01245 if(!(textureExtent[3]-textureExtent[2]+cellFlag==dim[1]))
01246 {
01247 glPixelStorei(vtkgl::UNPACK_IMAGE_HEIGHT_EXT,
01248 dim[1]-cellFlag);
01249 }
01250 void *dataPtr=scalars->GetVoidPointer(
01251 ((textureExtent[4]*(dim[1]-cellFlag)+textureExtent[2])
01252 *(dim[0]-cellFlag)+textureExtent[0])
01253 *scalars->GetNumberOfComponents());
01254
01255 vtkgl::TexImage3D(vtkgl::TEXTURE_3D, 0, internalFormat,
01256 textureSize[0],textureSize[1],textureSize[2],
01257 0,format,type,dataPtr);
01258
01259
01260 glPixelStorei(GL_UNPACK_ROW_LENGTH,0);
01261 glPixelStorei(vtkgl::UNPACK_IMAGE_HEIGHT_EXT,0);
01262 glPixelTransferf(GL_ALPHA_SCALE,1.0);
01263 glPixelTransferf(GL_ALPHA_BIAS,0.0);
01264
01265 this->LoadedCellFlag=cellFlag;
01266 i=0;
01267 while(i<6)
01268 {
01269 this->LoadedExtent[i]=textureExtent[i];
01270 ++i;
01271 }
01272
01273 double spacing[3];
01274 double origin[3];
01275 input->GetSpacing(spacing);
01276 input->GetOrigin(origin);
01277 int swapBounds[3];
01278 swapBounds[0]=(spacing[0]<0);
01279 swapBounds[1]=(spacing[1]<0);
01280 swapBounds[2]=(spacing[2]<0);
01281
01282 if(!this->LoadedCellFlag)
01283 {
01284
01285
01286
01287
01288
01289
01290
01291
01292
01293
01294
01295 this->LoadedBounds[0]=origin[0]+
01296 static_cast<double>(this->LoadedExtent[0+swapBounds[0]])*spacing[0];
01297 this->LoadedBounds[2]=origin[1]+
01298 static_cast<double>(this->LoadedExtent[2+swapBounds[1]])*spacing[1];
01299 this->LoadedBounds[4]=origin[2]+
01300 static_cast<double>(this->LoadedExtent[4+swapBounds[2]])*spacing[2];
01301 this->LoadedBounds[1]=origin[0]+
01302 static_cast<double>(this->LoadedExtent[1-swapBounds[0]])*spacing[0];
01303 this->LoadedBounds[3]=origin[1]+
01304 static_cast<double>(this->LoadedExtent[3-swapBounds[1]])*spacing[1];
01305 this->LoadedBounds[5]=origin[2]+
01306 static_cast<double>(this->LoadedExtent[5-swapBounds[2]])*spacing[2];
01307
01308 }
01309 else
01310 {
01311 int wholeTextureExtent[6];
01312 input->GetExtent(wholeTextureExtent);
01313 i=1;
01314 while(i<6)
01315 {
01316 wholeTextureExtent[i]--;
01317 i+=2;
01318 }
01319
01320 i=0;
01321 while(i<3)
01322 {
01323 if(this->LoadedExtent[2*i]==wholeTextureExtent[2*i])
01324 {
01325 this->LoadedBounds[2*i+swapBounds[i]]=origin[i];
01326 }
01327 else
01328 {
01329 this->LoadedBounds[2*i+swapBounds[i]]=origin[i]+
01330 (static_cast<double>(this->LoadedExtent[2*i])+0.5)*spacing[i];
01331 }
01332
01333 if(this->LoadedExtent[2*i+1]==wholeTextureExtent[2*i+1])
01334 {
01335 this->LoadedBounds[2*i+1-swapBounds[i]]=origin[i]+
01336 (static_cast<double>(this->LoadedExtent[2*i+1])+1.0)*spacing[i];
01337 }
01338 else
01339 {
01340 this->LoadedBounds[2*i+1-swapBounds[i]]=origin[i]+
01341 (static_cast<double>(this->LoadedExtent[2*i+1])+0.5)*spacing[i];
01342 }
01343 ++i;
01344 }
01345 }
01346 modified=true;
01347 }
01348 else
01349 {
01350 }
01351 }
01352 else
01353 {
01354 }
01355 }
01356 else
01357 {
01358 }
01359 }
01360 else
01361 {
01362
01363 }
01364 }
01365
01366 if(this->Loaded && (needUpdate || modified))
01367 {
01368 glTexParameterf(vtkgl::TEXTURE_3D,GL_TEXTURE_MIN_FILTER,
01369 GL_NEAREST );
01370 glTexParameterf(vtkgl::TEXTURE_3D,GL_TEXTURE_MAG_FILTER,
01371 GL_NEAREST );
01372 modified=true;
01373 }
01374 if(modified)
01375 {
01376 this->BuildTime.Modified();
01377 }
01378 }
01379
01380 double *GetLoadedBounds()
01381 {
01382 assert("pre: loaded" && this->Loaded);
01383 return this->LoadedBounds;
01384 }
01385
01386 vtkIdType *GetLoadedExtent()
01387 {
01388 assert("pre: loaded" && this->Loaded);
01389 return this->LoadedExtent;
01390 }
01391
01392 int GetLoadedCellFlag()
01393 {
01394 assert("pre: loaded" && this->Loaded);
01395 return this->LoadedCellFlag;
01396 }
01397
01398 bool IsLoaded()
01399 {
01400 return this->Loaded;
01401 }
01402
01403 protected:
01404 GLuint TextureId;
01405 vtkTimeStamp BuildTime;
01406 double LoadedBounds[6];
01407 vtkIdType LoadedExtent[6];
01408 int LoadedCellFlag;
01409 bool Loaded;
01410 };
01411
01412
01413
01414
01415
01416 void vtkMitkOpenGLGPUVolumeRayCastMapper::CheckFrameBufferStatus()
01417 {
01418 GLenum status;
01419 status = vtkgl::CheckFramebufferStatusEXT(vtkgl::FRAMEBUFFER_EXT);
01420 switch(status)
01421 {
01422 case 0:
01423 cout << "call to vtkgl::CheckFramebufferStatusEXT generates an error."
01424 << endl;
01425 break;
01426 case vtkgl::FRAMEBUFFER_COMPLETE_EXT:
01427 break;
01428 case vtkgl::FRAMEBUFFER_UNSUPPORTED_EXT:
01429 cout << "framebuffer is unsupported" << endl;
01430 break;
01431 case vtkgl::FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT:
01432 cout << "framebuffer has an attachment error"<<endl;
01433 break;
01434 case vtkgl::FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT:
01435 cout << "framebuffer has a missing attachment"<<endl;
01436 break;
01437 case vtkgl::FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT:
01438 cout << "framebuffer has bad dimensions"<<endl;
01439 break;
01440 case vtkgl::FRAMEBUFFER_INCOMPLETE_FORMATS_EXT:
01441 cout << "framebuffer has bad formats"<<endl;
01442 break;
01443 case vtkgl::FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT:
01444 cout << "framebuffer has bad draw buffer"<<endl;
01445 break;
01446 case vtkgl::FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT:
01447 cout << "framebuffer has bad read buffer"<<endl;
01448 break;
01449 default:
01450 cout << "Unknown framebuffer status=0x" << hex<< status << dec << endl;
01451 }
01452
01453
01454
01455 }
01456
01457
01458 vtkStdString vtkMitkOpenGLGPUVolumeRayCastMapper::BufferToString(int buffer)
01459 {
01460 vtkStdString result;
01461 vtksys_ios::ostringstream ost;
01462
01463 GLint size;
01464
01465 GLint b=static_cast<GLint>(buffer);
01466 switch(b)
01467 {
01468 case GL_NONE:
01469 ost << "GL_NONE";
01470 break;
01471 case GL_FRONT_LEFT:
01472 ost << "GL_FRONT_LEFT";
01473 break;
01474 case GL_FRONT_RIGHT:
01475 ost << "GL_FRONT_RIGHT";
01476 break;
01477 case GL_BACK_LEFT:
01478 ost << "GL_BACK_LEFT";
01479 break;
01480 case GL_BACK_RIGHT:
01481 ost << "GL_BACK_RIGHT";
01482 break;
01483 case GL_FRONT:
01484 ost << "GL_FRONT";
01485 break;
01486 case GL_BACK:
01487 ost << "GL_BACK";
01488 break;
01489 case GL_LEFT:
01490 ost << "GL_LEFT";
01491 break;
01492 case GL_RIGHT:
01493 ost << "GL_RIGHT";
01494 break;
01495 case GL_FRONT_AND_BACK:
01496 ost << "GL_FRONT_AND_BACK";
01497 break;
01498 default:
01499 glGetIntegerv(GL_AUX_BUFFERS,&size);
01500 if(buffer>=GL_AUX0 && buffer<(GL_AUX0+size))
01501 {
01502 ost << "GL_AUX" << (buffer-GL_AUX0);
01503 }
01504 else
01505 {
01506 glGetIntegerv(vtkgl::MAX_COLOR_ATTACHMENTS_EXT,&size);
01507 if(static_cast<GLuint>(buffer)>=vtkgl::COLOR_ATTACHMENT0_EXT &&
01508 static_cast<GLuint>(buffer)<
01509 (vtkgl::COLOR_ATTACHMENT0_EXT+static_cast<GLuint>(size)))
01510 {
01511 ost << "GL_COLOR_ATTACHMENT"
01512 << (static_cast<GLuint>(buffer)-vtkgl::COLOR_ATTACHMENT0_EXT)
01513 << "_EXT";
01514 }
01515 else
01516 {
01517 ost << "unknown color buffer type=0x"<<hex<<buffer<<dec;
01518 }
01519 }
01520 break;
01521 }
01522
01523 result=ost.str();
01524 return result;
01525 }
01526
01527
01528 void vtkMitkOpenGLGPUVolumeRayCastMapper::DisplayReadAndDrawBuffers()
01529 {
01530 GLint value;
01531 glGetIntegerv(vtkgl::MAX_DRAW_BUFFERS,&value);
01532 GLenum max=static_cast<GLenum>(value);
01533
01534 vtkStdString s;
01535 GLenum i=0;
01536 while(i<max)
01537 {
01538 glGetIntegerv(vtkgl::DRAW_BUFFER0+i,&value);
01539 s=this->BufferToString(static_cast<int>(value));
01540 cout << "draw buffer " << i << "=" << s << endl;
01541 ++i;
01542 }
01543
01544 glGetIntegerv(GL_READ_BUFFER,&value);
01545 s=this->BufferToString(static_cast<int>(value));
01546 cout << "read buffer=" << s << endl;
01547 }
01548
01549
01550
01551
01552
01553
01554
01555 void vtkMitkOpenGLGPUVolumeRayCastMapper::DisplayFrameBufferAttachments()
01556 {
01557 GLint framebufferBinding;
01558 glGetIntegerv(vtkgl::FRAMEBUFFER_BINDING_EXT,&framebufferBinding);
01559 this->PrintError("after getting FRAMEBUFFER_BINDING_EXT");
01560 if(framebufferBinding==0)
01561 {
01562 cout<<"Current framebuffer is bind to the system one"<<endl;
01563 }
01564 else
01565 {
01566 cout<<"Current framebuffer is bind to framebuffer object "
01567 <<framebufferBinding<<endl;
01568
01569 GLint value;
01570 glGetIntegerv(vtkgl::MAX_COLOR_ATTACHMENTS_EXT,&value);
01571 GLenum maxColorAttachments=static_cast<GLenum>(value);
01572 this->PrintError("after getting MAX_COLOR_ATTACHMENTS_EXT");
01573 GLenum i=0;
01574 while(i<maxColorAttachments)
01575 {
01576 cout<<"color attachement "<<i<<":"<<endl;
01577 this->DisplayFrameBufferAttachment(vtkgl::COLOR_ATTACHMENT0_EXT+i);
01578 ++i;
01579 }
01580 cout<<"depth attachement :"<<endl;
01581 this->DisplayFrameBufferAttachment(vtkgl::DEPTH_ATTACHMENT_EXT);
01582 cout<<"stencil attachement :"<<endl;
01583 this->DisplayFrameBufferAttachment(vtkgl::STENCIL_ATTACHMENT_EXT);
01584 }
01585 }
01586
01587
01588
01589
01590
01591
01592
01593 void vtkMitkOpenGLGPUVolumeRayCastMapper::DisplayFrameBufferAttachment(
01594 unsigned int uattachment)
01595 {
01596 GLenum attachment=static_cast<GLenum>(uattachment);
01597
01598 GLint params;
01599 vtkgl::GetFramebufferAttachmentParameterivEXT(
01600 vtkgl::FRAMEBUFFER_EXT,attachment,
01601 vtkgl::FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT,¶ms);
01602
01603 this->PrintError("after getting FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT");
01604 switch(params)
01605 {
01606 case GL_NONE:
01607 cout<<" this attachment is empty"<<endl;
01608 break;
01609 case GL_TEXTURE:
01610 vtkgl::GetFramebufferAttachmentParameterivEXT(
01611 vtkgl::FRAMEBUFFER_EXT,attachment,
01612 vtkgl::FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT,¶ms);
01613 this->PrintError("after getting FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT");
01614 cout<<" this attachment is a texture with name: "<<params<<endl;
01615 vtkgl::GetFramebufferAttachmentParameterivEXT(
01616 vtkgl::FRAMEBUFFER_EXT,attachment,
01617 vtkgl::FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_EXT,¶ms);
01618 this->PrintError(
01619 "after getting FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_EXT");
01620 cout<<" its mipmap level is: "<<params<<endl;
01621 vtkgl::GetFramebufferAttachmentParameterivEXT(
01622 vtkgl::FRAMEBUFFER_EXT,attachment,
01623 vtkgl::FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE_EXT,¶ms);
01624 this->PrintError(
01625 "after getting FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE_EXT");
01626 if(params==0)
01627 {
01628 cout<<" this is not a cube map texture."<<endl;
01629 }
01630 else
01631 {
01632 cout<<" this is a cube map texture and the image is contained in face "
01633 <<params<<endl;
01634 }
01635 vtkgl::GetFramebufferAttachmentParameterivEXT(
01636 vtkgl::FRAMEBUFFER_EXT,attachment,
01637 vtkgl::FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET_EXT,¶ms);
01638 this->PrintError(
01639 "after getting FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET_EXT");
01640 if(params==0)
01641 {
01642 cout<<" this is not 3D texture."<<endl;
01643 }
01644 else
01645 {
01646 cout<<" this is a 3D texture and the zoffset of the attached image is "
01647 <<params<<endl;
01648 }
01649 break;
01650 case vtkgl::RENDERBUFFER_EXT:
01651 cout<<" this attachment is a renderbuffer"<<endl;
01652 vtkgl::GetFramebufferAttachmentParameterivEXT(
01653 vtkgl::FRAMEBUFFER_EXT,attachment,
01654 vtkgl::FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT,¶ms);
01655 this->PrintError("after getting FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT");
01656 cout<<" this attachment is a renderbuffer with name: "<<params<<endl;
01657
01658 vtkgl::BindRenderbufferEXT(vtkgl::RENDERBUFFER_EXT,
01659 static_cast<GLuint>(params));
01660 this->PrintError(
01661 "after getting binding the current RENDERBUFFER_EXT to params");
01662
01663 vtkgl::GetRenderbufferParameterivEXT(vtkgl::RENDERBUFFER_EXT,
01664 vtkgl::RENDERBUFFER_WIDTH_EXT,
01665 ¶ms);
01666 this->PrintError("after getting RENDERBUFFER_WIDTH_EXT");
01667 cout<<" renderbuffer width="<<params<<endl;
01668 vtkgl::GetRenderbufferParameterivEXT(vtkgl::RENDERBUFFER_EXT,
01669 vtkgl::RENDERBUFFER_HEIGHT_EXT,
01670 ¶ms);
01671 this->PrintError("after getting RENDERBUFFER_HEIGHT_EXT");
01672 cout<<" renderbuffer height="<<params<<endl;
01673 vtkgl::GetRenderbufferParameterivEXT(
01674 vtkgl::RENDERBUFFER_EXT,vtkgl::RENDERBUFFER_INTERNAL_FORMAT_EXT,
01675 ¶ms);
01676 this->PrintError("after getting RENDERBUFFER_INTERNAL_FORMAT_EXT");
01677
01678 cout<<" renderbuffer internal format=0x"<< hex<<params<<dec<<endl;
01679
01680 vtkgl::GetRenderbufferParameterivEXT(vtkgl::RENDERBUFFER_EXT,
01681 vtkgl::RENDERBUFFER_RED_SIZE_EXT,
01682 ¶ms);
01683 this->PrintError("after getting RENDERBUFFER_RED_SIZE_EXT");
01684 cout<<" renderbuffer actual resolution for the red component="<<params
01685 <<endl;
01686 vtkgl::GetRenderbufferParameterivEXT(vtkgl::RENDERBUFFER_EXT,
01687 vtkgl::RENDERBUFFER_GREEN_SIZE_EXT,
01688 ¶ms);
01689 this->PrintError("after getting RENDERBUFFER_GREEN_SIZE_EXT");
01690 cout<<" renderbuffer actual resolution for the green component="<<params
01691 <<endl;
01692 vtkgl::GetRenderbufferParameterivEXT(vtkgl::RENDERBUFFER_EXT,
01693 vtkgl::RENDERBUFFER_BLUE_SIZE_EXT,
01694 ¶ms);
01695 this->PrintError("after getting RENDERBUFFER_BLUE_SIZE_EXT");
01696 cout<<" renderbuffer actual resolution for the blue component="<<params
01697 <<endl;
01698 vtkgl::GetRenderbufferParameterivEXT(vtkgl::RENDERBUFFER_EXT,
01699 vtkgl::RENDERBUFFER_ALPHA_SIZE_EXT,
01700 ¶ms);
01701 this->PrintError("after getting RENDERBUFFER_ALPHA_SIZE_EXT");
01702 cout<<" renderbuffer actual resolution for the alpha component="<<params
01703 <<endl;
01704 vtkgl::GetRenderbufferParameterivEXT(vtkgl::RENDERBUFFER_EXT,
01705 vtkgl::RENDERBUFFER_DEPTH_SIZE_EXT,
01706 ¶ms);
01707 this->PrintError("after getting RENDERBUFFER_DEPTH_SIZE_EXT");
01708 cout<<" renderbuffer actual resolution for the depth component="<<params
01709 <<endl;
01710 vtkgl::GetRenderbufferParameterivEXT(
01711 vtkgl::RENDERBUFFER_EXT,vtkgl::RENDERBUFFER_STENCIL_SIZE_EXT,¶ms);
01712 this->PrintError("after getting RENDERBUFFER_STENCIL_SIZE_EXT");
01713 cout<<" renderbuffer actual resolution for the stencil component="
01714 <<params<<endl;
01715 break;
01716 default:
01717 cout<<" unexcepted value."<<endl;
01718 break;
01719 }
01720 }
01721
01722
01723
01724
01725
01726 const char *vtkMitkOpenGLGPUVolumeRayCastMapper::OpenGLErrorMessage(
01727 unsigned int errorCode)
01728 {
01729 const char *result;
01730 switch(static_cast<GLenum>(errorCode))
01731 {
01732 case GL_NO_ERROR:
01733 result="No error";
01734 break;
01735 case GL_INVALID_ENUM:
01736 result="Invalid enum";
01737 break;
01738 case GL_INVALID_VALUE:
01739 result="Invalid value";
01740 break;
01741 case GL_INVALID_OPERATION:
01742 result="Invalid operation";
01743 break;
01744 case GL_STACK_OVERFLOW:
01745 result="stack overflow";
01746 break;
01747 case GL_STACK_UNDERFLOW:
01748 result="stack underflow";
01749 break;
01750 case GL_OUT_OF_MEMORY:
01751 result="out of memory";
01752 break;
01753 case vtkgl::TABLE_TOO_LARGE:
01754
01755 result="Table too large";
01756 break;
01757 case vtkgl::INVALID_FRAMEBUFFER_OPERATION_EXT:
01758
01759 result="invalid framebuffer operation ext";
01760 break;
01761 case vtkgl::TEXTURE_TOO_LARGE_EXT:
01762
01763 result="Texture too large";
01764 break;
01765 default:
01766 result="unknown error";
01767 }
01768 assert("post: result_exists" && result!=0);
01769 return result;
01770 }
01771
01772
01773
01774
01775
01776 void vtkMitkOpenGLGPUVolumeRayCastMapper::PrintError(const char *headerMessage)
01777 {
01778 GLenum errorCode=glGetError();
01779 if(errorCode!=GL_NO_ERROR)
01780 {
01781 if ( headerMessage )
01782 {
01783 cout<<headerMessage;
01784 }
01785 cout<<" ERROR (x"<<hex<<errorCode<<") "<<dec;
01786 cout<<OpenGLErrorMessage(static_cast<unsigned int>(errorCode));
01787 cout<<endl;
01788 }
01789 }
01790
01791
01792
01793
01794 vtkMitkOpenGLGPUVolumeRayCastMapper::vtkMitkOpenGLGPUVolumeRayCastMapper()
01795 {
01796 this->UnsupportedRequiredExtensions=0;
01797 this->OpenGLObjectsCreated=0;
01798 this->LoadExtensionsSucceeded=0;
01799 this->NumberOfFrameBuffers=0;
01800
01801
01802
01803
01804
01805
01806 int i=0;
01807 while(i<vtkMitkOpenGLGPUVolumeRayCastMapperNumberOfTextureObjects)
01808 {
01809 this->TextureObjects[i]=0;
01810 ++i;
01811 }
01812
01813 this->DepthRenderBufferObject=0;
01814 this->FrameBufferObject=0;
01815
01816 for ( int j = 0; j < 8; j++ )
01817 {
01818 for (i = 0; i < 3; i++ )
01819 {
01820 this->BoundingBox[j][i] = 0.0;
01821 }
01822 }
01823
01824 this->LastSize[0]=0;
01825 this->LastSize[1]=0;
01826
01827 this->ReductionFactor = 1.0;
01828
01829 this->Supports_GL_ARB_texture_float=0;
01830 this->SupportsPixelBufferObjects=0;
01831
01832 i=0;
01833 while(i<3)
01834 {
01835 this->TempMatrix[i]=vtkMatrix4x4::New();
01836 ++i;
01837 }
01838
01839 this->ErrorLine=0;
01840 this->ErrorColumn=0;
01841 this->ErrorString=0;
01842
01843 this->LastParallelProjection=
01844 vtkMitkOpenGLGPUVolumeRayCastMapperProjectionNotInitialized;
01845 this->LastRayCastMethod=
01846 vtkMitkOpenGLGPUVolumeRayCastMapperMethodNotInitialized;
01847 this->LastCroppingMode=
01848 vtkMitkOpenGLGPUVolumeRayCastMapperCroppingNotInitialized;
01849 this->LastComponent=
01850 vtkMitkOpenGLGPUVolumeRayCastMapperComponentNotInitialized;
01851 this->LastShade=vtkMitkOpenGLGPUVolumeRayCastMapperShadeNotInitialized;
01852
01853 this->ClippedBoundingBox = NULL;
01854
01855 this->SmallInput = NULL;
01856
01857 this->MaxValueFrameBuffer=0;
01858 this->MaxValueFrameBuffer2=0;
01859 this->ReducedSize[0]=0;
01860 this->ReducedSize[1]=0;
01861
01862 this->NumberOfCroppingRegions=0;
01863
01864 this->PolyDataBoundingBox=0;
01865 this->Planes=0;
01866 this->NearPlane=0;
01867 this->Clip=0;
01868 this->Densify=0;
01869 this->InvVolumeMatrix=vtkMatrix4x4::New();
01870
01871 this->ScaleBiasProgramShader=0;
01872 this->UFrameBufferTexture=-1;
01873 this->UScale=-1;
01874 this->UBias=-1;
01875
01876 this->SavedFrameBuffer=0;
01877
01878 this->BoxSource=0;
01879
01880 this->NoiseTexture=0;
01881 this->NoiseTextureSize=0;
01882 this->NoiseTextureId=0;
01883
01884 this->IgnoreSampleDistancePerPixel=true;
01885
01886 this->ScalarsTextures=new vtkMapDataArrayTextureId;
01887 this->MaskTextures=new vtkMapMaskTextureId;
01888
01889 this->RGBTable=0;
01890 this->Mask1RGBTable=0;
01891 this->Mask2RGBTable=0;
01892 this->OpacityTables=0;
01893
01894 this->CurrentScalar=0;
01895 this->CurrentMask=0;
01896
01897 this->ActualSampleDistance=1.0;
01898 this->LastProgressEventTime=0.0;
01899
01900 this->PreserveOrientation=true;
01901 }
01902
01903
01904
01905
01906 vtkMitkOpenGLGPUVolumeRayCastMapper::~vtkMitkOpenGLGPUVolumeRayCastMapper()
01907 {
01908 if(this->UnsupportedRequiredExtensions!=0)
01909 {
01910 delete this->UnsupportedRequiredExtensions;
01911 this->UnsupportedRequiredExtensions=0;
01912 }
01913 int i=0;
01914 while(i<3)
01915 {
01916 this->TempMatrix[i]->Delete();
01917 this->TempMatrix[i]=0;
01918 ++i;
01919 }
01920
01921 if(this->ErrorString!=0)
01922 {
01923 delete[] this->ErrorString;
01924 this->ErrorString=0;
01925 }
01926
01927 if ( this->SmallInput )
01928 {
01929 this->SmallInput->UnRegister(this);
01930 }
01931
01932 if(this->PolyDataBoundingBox!=0)
01933 {
01934 this->PolyDataBoundingBox->UnRegister(this);
01935 this->PolyDataBoundingBox=0;
01936 }
01937 if(this->Planes!=0)
01938 {
01939 this->Planes->UnRegister(this);
01940 this->Planes=0;
01941 }
01942 if(this->NearPlane!=0)
01943 {
01944 this->NearPlane->UnRegister(this);
01945 this->NearPlane=0;
01946 }
01947 if(this->Clip!=0)
01948 {
01949 this->Clip->UnRegister(this);
01950 this->Clip=0;
01951 }
01952 if(this->Densify!=0)
01953 {
01954 this->Densify->UnRegister(this);
01955 this->Densify=0;
01956 }
01957
01958 if(this->BoxSource!=0)
01959 {
01960 this->BoxSource->UnRegister(this);
01961 this->BoxSource=0;
01962 }
01963 this->InvVolumeMatrix->UnRegister(this);
01964 this->InvVolumeMatrix=0;
01965
01966 if(this->NoiseTexture!=0)
01967 {
01968 delete[] this->NoiseTexture;
01969 this->NoiseTexture=0;
01970 this->NoiseTextureSize=0;
01971 }
01972
01973 if(this->ScalarsTextures!=0)
01974 {
01975 delete this->ScalarsTextures;
01976 this->ScalarsTextures=0;
01977 }
01978
01979 if(this->MaskTextures!=0)
01980 {
01981 delete this->MaskTextures;
01982 this->MaskTextures=0;
01983 }
01984 }
01985
01986
01987
01988
01989
01990
01991
01992
01993 int vtkMitkOpenGLGPUVolumeRayCastMapper::IsRenderSupported(
01994 vtkRenderWindow *window,
01995 vtkVolumeProperty *vtkNotUsed(property))
01996 {
01997 window->MakeCurrent();
01998 if(!this->LoadExtensionsSucceeded)
01999 {
02000 this->LoadExtensions(window);
02001 }
02002 if(!this->LoadExtensionsSucceeded)
02003 {
02004 vtkDebugMacro(
02005 "The following OpenGL extensions are required but not supported: "
02006 << (this->UnsupportedRequiredExtensions->Stream.str()).c_str());
02007 return 0;
02008 }
02009 return 1;
02010 }
02011
02012
02013
02014
02015
02016
02017
02018
02019 int vtkMitkOpenGLGPUVolumeRayCastMapper::TestRequiredExtension(
02020 vtkOpenGLExtensionManager *extensions,
02021 const char *extensionName)
02022 {
02023 assert("pre: extensions_exist" && extensions!=0);
02024 assert("pre: extensionName_exists" && extensionName!=0);
02025 int result=extensions->ExtensionSupported(extensionName);
02026
02027 if(!result)
02028 {
02029 if(this->LoadExtensionsSucceeded)
02030 {
02031 this->UnsupportedRequiredExtensions->Stream<<extensionName;
02032 this->LoadExtensionsSucceeded=0;
02033 }
02034 else
02035 {
02036 this->UnsupportedRequiredExtensions->Stream<<", "<<extensionName;
02037 }
02038 }
02039 return result;
02040 }
02041
02042
02043
02044
02045
02046
02047
02048
02049
02050
02051
02052
02053
02054
02055
02056 void vtkMitkOpenGLGPUVolumeRayCastMapper::LoadExtensions(
02057 vtkRenderWindow *window)
02058 {
02059
02060
02061 if(this->UnsupportedRequiredExtensions!=0)
02062 {
02063 delete this->UnsupportedRequiredExtensions;
02064 }
02065
02066
02067
02068 this->UnsupportedRequiredExtensions =
02069 new vtkUnsupportedRequiredExtensionsStringStream;
02070
02071
02072
02073
02074 #ifdef __APPLE__
02075 this->LoadExtensionsSucceeded=0;
02076 return;
02077 #endif
02078
02079
02080 this->LoadExtensionsSucceeded=1;
02081
02082 const char *gl_vendor=reinterpret_cast<const char *>(glGetString(GL_VENDOR));
02083
02084
02085
02086
02087
02088 const char *gl_version=reinterpret_cast<const char *>(glGetString(GL_VERSION));
02089 if(strstr(gl_version,"Mesa")!=0)
02090 {
02091
02092
02093
02094
02095
02096
02097
02098
02099
02100 this->LoadExtensionsSucceeded=0;
02101 return;
02102 }
02103
02104
02105 vtkOpenGLExtensionManager *extensions=vtkOpenGLExtensionManager::New();
02106 extensions->SetRenderWindow(window);
02107
02108
02109
02110
02111
02112
02113
02114
02115
02116 int supports_GL_1_3=extensions->ExtensionSupported("GL_VERSION_1_3");
02117 int supports_GL_2_0=0;
02118
02119
02120 if(!supports_GL_1_3)
02121 {
02122 this->LoadExtensionsSucceeded=0;
02123 this->UnsupportedRequiredExtensions->Stream<<
02124 " OpenGL 1.3 is required but not supported";
02125 extensions->Delete();
02126 return;
02127 }
02128
02129
02130 supports_GL_2_0=extensions->ExtensionSupported("GL_VERSION_2_0");
02131
02132
02133
02134 int supports_shading_language_100 = 1;
02135 int supports_shader_objects = 1;
02136 int supports_fragment_shader = 1;
02137 int supports_texture_non_power_of_two = 1;
02138 int supports_draw_buffers = 1;
02139 if(!supports_GL_2_0)
02140 {
02141 supports_shading_language_100=
02142 extensions->ExtensionSupported("GL_ARB_shading_language_100");
02143 supports_shader_objects=
02144 extensions->ExtensionSupported("GL_ARB_shader_objects");
02145 supports_fragment_shader=
02146 extensions->ExtensionSupported("GL_ARB_fragment_shader");
02147 supports_texture_non_power_of_two=
02148 extensions->ExtensionSupported("GL_ARB_texture_non_power_of_two");
02149 supports_draw_buffers=
02150 extensions->ExtensionSupported("GL_ARB_draw_buffers");
02151 }
02152
02153
02154 int supports_GL_EXT_framebuffer_object=
02155 extensions->ExtensionSupported("GL_EXT_framebuffer_object" );
02156
02157
02158 int supports_GL_1_4=extensions->ExtensionSupported("GL_VERSION_1_4");
02159
02160
02161 int supports_GL_ARB_depth_texture=
02162 extensions->ExtensionSupported("GL_ARB_depth_texture");
02163
02164
02165
02166 int supports_depth_texture =
02167 supports_GL_1_4 || supports_GL_ARB_depth_texture;
02168
02169
02170
02171 if(!supports_shading_language_100)
02172 {
02173 this->UnsupportedRequiredExtensions->Stream<<
02174 " shading_language_100 (or OpenGL 2.0) is required but not supported";
02175 this->LoadExtensionsSucceeded=0;
02176 }
02177 else
02178 {
02179
02180 const char *glsl_version=
02181 reinterpret_cast<const char *>(glGetString(vtkgl::SHADING_LANGUAGE_VERSION));
02182 int glslMajor, glslMinor;
02183 vtksys_ios::istringstream ist(glsl_version);
02184 ist >> glslMajor;
02185 char c;
02186 ist.get(c);
02187 ist >> glslMinor;
02188
02189 if(glslMajor<1 || (glslMajor==1 && glslMinor<20))
02190 {
02191 this->LoadExtensionsSucceeded=0;
02192 }
02193 }
02194
02195
02196 if(!supports_shader_objects)
02197 {
02198 this->UnsupportedRequiredExtensions->Stream<<
02199 " shader_objects (or OpenGL 2.0) is required but not supported";
02200 this->LoadExtensionsSucceeded=0;
02201 }
02202
02203
02204 if(!supports_fragment_shader)
02205 {
02206 this->UnsupportedRequiredExtensions->Stream<<
02207 " fragment_shader (or OpenGL 2.0) is required but not supported";
02208 this->LoadExtensionsSucceeded=0;
02209 }
02210
02211
02212 if(!supports_texture_non_power_of_two)
02213 {
02214 this->UnsupportedRequiredExtensions->Stream<<
02215 " texture_non_power_of_two (or OpenGL 2.0) is required but not "
02216 << "supported";
02217 this->LoadExtensionsSucceeded=0;
02218 }
02219
02220
02221 if(!supports_draw_buffers)
02222 {
02223 this->UnsupportedRequiredExtensions->Stream<<
02224 " draw_buffers (or OpenGL 2.0) is required but not supported";
02225 this->LoadExtensionsSucceeded=0;
02226 }
02227
02228
02229 if(!supports_depth_texture)
02230 {
02231 this->UnsupportedRequiredExtensions->Stream<<
02232 " depth_texture (or OpenGL 1.4) is required but not supported";
02233 this->LoadExtensionsSucceeded=0;
02234 }
02235
02236
02237 if(!supports_GL_EXT_framebuffer_object)
02238 {
02239 this->UnsupportedRequiredExtensions->Stream<<
02240 " framebuffer_object is required but not supported";
02241 this->LoadExtensionsSucceeded=0;
02242 }
02243
02244
02245 if(!this->LoadExtensionsSucceeded)
02246 {
02247 extensions->Delete();
02248 return;
02249 }
02250
02251
02252
02253
02254 extensions->LoadExtension("GL_VERSION_1_2");
02255 extensions->LoadExtension("GL_VERSION_1_3");
02256
02257
02258 if(supports_GL_2_0)
02259 {
02260 extensions->LoadExtension("GL_VERSION_2_0");
02261 }
02262
02263
02264
02265 else
02266 {
02267 extensions->LoadCorePromotedExtension("GL_ARB_shader_objects");
02268 extensions->LoadCorePromotedExtension("GL_ARB_fragment_shader");
02269 extensions->LoadCorePromotedExtension("GL_ARB_draw_buffers");
02270 }
02271
02272
02273 extensions->LoadExtension("GL_EXT_framebuffer_object");
02274
02275
02276
02277
02278 this->Supports_GL_ARB_texture_float=
02279 extensions->ExtensionSupported("GL_ARB_texture_float" );
02280 if(this->Supports_GL_ARB_texture_float)
02281 {
02282 extensions->LoadExtension( "GL_ARB_texture_float" );
02283 }
02284
02285
02286
02287
02288
02289 int supports_GL_1_5=extensions->ExtensionSupported("GL_VERSION_1_5");
02290 int supports_vertex_buffer_object=supports_GL_1_5 ||
02291 extensions->ExtensionSupported("GL_ARB_vertex_buffer_object");
02292 int supports_GL_2_1=extensions->ExtensionSupported("GL_VERSION_2_1");
02293 this->SupportsPixelBufferObjects=supports_vertex_buffer_object &&
02294 (supports_GL_2_1 ||
02295 extensions->ExtensionSupported("GL_ARB_pixel_buffer_object"));
02296
02297 if(this->SupportsPixelBufferObjects)
02298 {
02299 if(supports_GL_1_5)
02300 {
02301 extensions->LoadExtension("GL_VERSION_1_5");
02302 }
02303 else
02304 {
02305 extensions->LoadCorePromotedExtension("GL_ARB_vertex_buffer_object");
02306 }
02307 if(supports_GL_2_1)
02308 {
02309 extensions->LoadExtension("GL_VERSION_2_1");
02310 }
02311 else
02312 {
02313 extensions->LoadCorePromotedExtension("GL_ARB_pixel_buffer_object");
02314 }
02315 }
02316
02317
02318
02319
02320
02321
02322
02323 this->CreateGLSLObjects();
02324 this->NumberOfCroppingRegions=1;
02325 this->BuildProgram(1,vtkMitkOpenGLGPUVolumeRayCastMapperMethodComposite,
02326 vtkMitkOpenGLGPUVolumeRayCastMapperShadeNo,
02327 vtkMitkOpenGLGPUVolumeRayCastMapperComponentOne);
02328
02329 GLint params;
02330 vtkgl::GetProgramiv(static_cast<GLuint>(this->ProgramShader),
02331 vtkgl::LINK_STATUS,¶ms);
02332 if(params==GL_FALSE)
02333 {
02334 this->LoadExtensionsSucceeded=0;
02335 this->UnsupportedRequiredExtensions->Stream<<
02336 " this card does not support while statements in fragment shaders.";
02337 }
02338
02339
02340 this->CheckLinkage(this->ProgramShader);
02341
02342
02343 GLuint programShader=static_cast<GLuint>(this->ProgramShader);
02344 vtkgl::DeleteProgram(programShader);
02345
02346 this->LastParallelProjection=
02347 vtkMitkOpenGLGPUVolumeRayCastMapperProjectionNotInitialized;
02348 this->LastRayCastMethod=
02349 vtkMitkOpenGLGPUVolumeRayCastMapperMethodNotInitialized;
02350 this->LastCroppingMode=
02351 vtkMitkOpenGLGPUVolumeRayCastMapperCroppingNotInitialized;
02352 this->LastComponent=
02353 vtkMitkOpenGLGPUVolumeRayCastMapperComponentNotInitialized;
02354 this->LastShade=vtkMitkOpenGLGPUVolumeRayCastMapperShadeNotInitialized;
02355
02356 extensions->Delete();
02357 }
02358
02359
02360
02361
02362 void vtkMitkOpenGLGPUVolumeRayCastMapper::CreateGLSLObjects()
02363 {
02364 GLuint programShader;
02365 GLuint fragmentMainShader;
02366
02367 programShader=vtkgl::CreateProgram();
02368 fragmentMainShader=vtkgl::CreateShader(vtkgl::FRAGMENT_SHADER);
02369 vtkgl::AttachShader(programShader,fragmentMainShader);
02370 vtkgl::DeleteShader(fragmentMainShader);
02371
02372 vtkgl::ShaderSource(
02373 fragmentMainShader,1,
02374 const_cast<const char **>(&vtkMitkGPUVolumeRayCastMapper_HeaderFS),0);
02375 vtkgl::CompileShader(fragmentMainShader);
02376
02377 this->CheckCompilation(static_cast<unsigned int>(fragmentMainShader));
02378
02379 GLuint fragmentProjectionShader;
02380 GLuint fragmentTraceShader;
02381 GLuint fragmentCroppingShader;
02382 GLuint fragmentComponentShader;
02383 GLuint fragmentShadeShader;
02384
02385 fragmentProjectionShader=vtkgl::CreateShader(vtkgl::FRAGMENT_SHADER);
02386 vtkgl::AttachShader(programShader,fragmentProjectionShader);
02387 vtkgl::DeleteShader(fragmentProjectionShader);
02388
02389 fragmentTraceShader=vtkgl::CreateShader(vtkgl::FRAGMENT_SHADER);
02390 vtkgl::AttachShader(programShader,fragmentTraceShader);
02391 vtkgl::DeleteShader(fragmentTraceShader);
02392 fragmentCroppingShader=vtkgl::CreateShader(vtkgl::FRAGMENT_SHADER);
02393 vtkgl::AttachShader(programShader,fragmentCroppingShader);
02394 vtkgl::DeleteShader(fragmentCroppingShader);
02395
02396 fragmentComponentShader=vtkgl::CreateShader(vtkgl::FRAGMENT_SHADER);
02397
02398
02399 fragmentShadeShader=vtkgl::CreateShader(vtkgl::FRAGMENT_SHADER);
02400
02401
02402
02403 this->ProgramShader=static_cast<unsigned int>(programShader);
02404
02405 this->FragmentMainShader=static_cast<unsigned int>(fragmentMainShader);
02406 this->FragmentProjectionShader=
02407 static_cast<unsigned int>(fragmentProjectionShader);
02408 this->FragmentTraceShader=static_cast<unsigned int>(fragmentTraceShader);
02409 this->FragmentCroppingShader=
02410 static_cast<unsigned int>(fragmentCroppingShader);
02411 this->FragmentComponentShader=
02412 static_cast<unsigned int>(fragmentComponentShader);
02413 this->FragmentShadeShader=
02414 static_cast<unsigned int>(fragmentShadeShader);
02415
02416 }
02417
02418
02419
02420
02421
02422
02423
02424
02425
02426
02427
02428
02429
02430 void vtkMitkOpenGLGPUVolumeRayCastMapper::CreateOpenGLObjects()
02431 {
02432
02433 if ( this->OpenGLObjectsCreated )
02434 {
02435 return;
02436 }
02437
02438
02439 this->NumberOfFrameBuffers=2;
02440
02441 GLuint frameBufferObject;
02442 GLuint depthRenderBufferObject;
02443
02444
02445
02446
02447
02448 GLuint textureObjects[vtkMitkOpenGLGPUVolumeRayCastMapperNumberOfTextureObjects];
02449
02450
02451
02452
02453 vtkgl::GenFramebuffersEXT(1, &frameBufferObject);
02454 vtkgl::GenRenderbuffersEXT(1, &depthRenderBufferObject);
02455 int i=0;
02456 while(i<( vtkMitkOpenGLGPUVolumeRayCastMapperTextureObjectFrameBufferLeftFront+this->NumberOfFrameBuffers))
02457 {
02458 textureObjects[i]=0;
02459 ++i;
02460 }
02461
02462
02463 glGenTextures(vtkMitkOpenGLGPUVolumeRayCastMapperTextureObjectFrameBufferLeftFront+this->NumberOfFrameBuffers,textureObjects);
02464
02465 GLint value;
02466 glGetIntegerv(vtkgl::FRAMEBUFFER_BINDING_EXT,&value);
02467 GLuint savedFrameBuffer=static_cast<GLuint>(value);
02468 vtkgl::BindFramebufferEXT(vtkgl::FRAMEBUFFER_EXT,frameBufferObject);
02469 i=0;
02470 while(i<this->NumberOfFrameBuffers)
02471 {
02472 glBindTexture(GL_TEXTURE_2D,textureObjects[vtkMitkOpenGLGPUVolumeRayCastMapperTextureObjectFrameBufferLeftFront+i]);
02473 ++i;
02474 }
02475 vtkgl::FramebufferTexture2DEXT(vtkgl::FRAMEBUFFER_EXT,
02476 vtkgl::COLOR_ATTACHMENT0_EXT,GL_TEXTURE_2D,
02477 textureObjects[vtkMitkOpenGLGPUVolumeRayCastMapperTextureObjectFrameBufferLeftFront],
02478 0);
02479
02480
02481
02482 vtkgl::BindRenderbufferEXT(vtkgl::RENDERBUFFER_EXT,
02483 depthRenderBufferObject);
02484
02485 vtkgl::FramebufferRenderbufferEXT(vtkgl::FRAMEBUFFER_EXT,
02486 vtkgl::DEPTH_ATTACHMENT_EXT,
02487 vtkgl::RENDERBUFFER_EXT,
02488 depthRenderBufferObject);
02489
02490
02491 vtkgl::BindFramebufferEXT(vtkgl::FRAMEBUFFER_EXT,savedFrameBuffer);
02492
02493 this->CreateGLSLObjects();
02494
02495
02496
02497 this->FrameBufferObject=static_cast<unsigned int>(frameBufferObject);
02498 this->DepthRenderBufferObject=static_cast<unsigned int>(depthRenderBufferObject);
02499 i=0;
02500 while(i<(vtkMitkOpenGLGPUVolumeRayCastMapperTextureObjectFrameBufferLeftFront+this->NumberOfFrameBuffers))
02501 {
02502 this->TextureObjects[i]=static_cast<unsigned int>(textureObjects[i]);
02503 ++i;
02504 }
02505
02506 this->OpenGLObjectsCreated=1;
02507 }
02508
02509
02510
02511
02512
02513 void vtkMitkOpenGLGPUVolumeRayCastMapper::CheckCompilation(
02514 unsigned int fragmentShader)
02515 {
02516 GLuint fs=static_cast<GLuint>(fragmentShader);
02517 GLint params;
02518 vtkgl::GetShaderiv(fs,vtkgl::COMPILE_STATUS,¶ms);
02519
02520 if(params==GL_TRUE)
02521 {
02522 vtkDebugMacro(<<"shader source compiled successfully");
02523 }
02524 else
02525 {
02526 vtkErrorMacro(<<"shader source compile error");
02527
02528 vtkgl::GetShaderiv(fs,vtkgl::INFO_LOG_LENGTH,¶ms);
02529 if(params>0)
02530 {
02531 char *buffer=new char[params];
02532 vtkgl::GetShaderInfoLog(fs,params,0,buffer);
02533 vtkErrorMacro(<<"log: "<<buffer);
02534 delete[] buffer;
02535 }
02536 else
02537 {
02538 vtkErrorMacro(<<"no log");
02539 }
02540 }
02541 }
02542
02543
02544
02545
02546
02547
02548
02549 void vtkMitkOpenGLGPUVolumeRayCastMapper::PrintUniformVariables(unsigned int programShader)
02550 {
02551 GLint params;
02552 GLuint prog=static_cast<GLuint>(programShader);
02553
02554
02555 vtkgl::GetProgramiv(prog,vtkgl::ACTIVE_UNIFORMS,¶ms);
02556 cout<<"There are "<<params<<" active uniform variables"<<endl;
02557 GLuint i=0;
02558 GLuint c=static_cast<GLuint>(params);
02559 vtkgl::GetProgramiv(prog,vtkgl::OBJECT_ACTIVE_UNIFORM_MAX_LENGTH_ARB,
02560 ¶ms);
02561
02562 GLint buffSize=params;
02563 char *name=new char[buffSize+1];
02564 GLint size;
02565 GLenum type;
02566 while(i<c)
02567 {
02568 vtkgl::GetActiveUniform(prog,i,buffSize,0,&size,&type,name);
02569 cout<<i<<" ";
02570 switch(type)
02571 {
02572 case GL_FLOAT:
02573 cout<<"float";
02574 break;
02575 case vtkgl::FLOAT_VEC2_ARB:
02576 cout<<"vec2";
02577 break;
02578 case vtkgl::FLOAT_VEC3_ARB:
02579 cout<<"vec3";
02580 break;
02581 case vtkgl::FLOAT_VEC4_ARB:
02582 cout<<"vec4";
02583 break;
02584 case GL_INT:
02585 cout<<"int";
02586 break;
02587 case vtkgl::INT_VEC2_ARB:
02588 cout<<"ivec2";
02589 break;
02590 case vtkgl::INT_VEC3_ARB:
02591 cout<<"ivec3";
02592 break;
02593 case vtkgl::INT_VEC4_ARB:
02594 cout<<"ivec4";
02595 break;
02596 case vtkgl::BOOL_ARB:
02597 cout<<"bool";
02598 break;
02599 case vtkgl::BOOL_VEC2_ARB:
02600 cout<<"bvec2";
02601 break;
02602 case vtkgl::BOOL_VEC3_ARB:
02603 cout<<"bvec3";
02604 break;
02605 case vtkgl::BOOL_VEC4_ARB:
02606 cout<<"bvec4";
02607 break;
02608 case vtkgl::FLOAT_MAT2_ARB:
02609 cout<<"mat2";
02610 break;
02611 case vtkgl::FLOAT_MAT3_ARB:
02612 cout<<"mat3";
02613 break;
02614 case vtkgl::FLOAT_MAT4_ARB:
02615 cout<<"mat4";
02616 break;
02617 case vtkgl::SAMPLER_1D_ARB:
02618 cout<<"sampler1D";
02619 break;
02620 case vtkgl::SAMPLER_2D_ARB:
02621 cout<<"sampler2D";
02622 break;
02623 case vtkgl::SAMPLER_3D_ARB:
02624 cout<<"sampler3D";
02625 break;
02626 case vtkgl::SAMPLER_CUBE_ARB:
02627 cout<<"samplerCube";
02628 break;
02629 case vtkgl::SAMPLER_1D_SHADOW_ARB:
02630 cout<<"sampler1Dshadow";
02631 break;
02632 case vtkgl::SAMPLER_2D_SHADOW_ARB:
02633 cout<<"sampler2Dshadow";
02634 break;
02635 }
02636 cout<<" "<<name<<endl;
02637 ++i;
02638 }
02639 delete[] name;
02640 }
02641
02642
02643
02644
02645
02646
02647 int vtkMitkOpenGLGPUVolumeRayCastMapper::CheckLinkage(unsigned int programShader)
02648 {
02649 GLint params;
02650 GLuint prog=static_cast<GLuint>(programShader);
02651 vtkgl::GetProgramiv(prog,vtkgl::LINK_STATUS,¶ms);
02652 int status = 0;
02653 if(params==GL_TRUE)
02654 {
02655 status = 1;
02656 vtkDebugMacro(<<"program linked successfully");
02657 }
02658 else
02659 {
02660 vtkErrorMacro(<<"program link error");
02661 vtkgl::GetProgramiv(prog,vtkgl::INFO_LOG_LENGTH,¶ms);
02662 if(params>0)
02663 {
02664 char *buffer=new char[params];
02665 vtkgl::GetProgramInfoLog(prog,params,0,buffer);
02666 vtkErrorMacro(<<"log: "<<buffer);
02667 delete[] buffer;
02668 }
02669 else
02670 {
02671 vtkErrorMacro(<<"no log: ");
02672 }
02673 }
02674
02675 return status;
02676 }
02677
02678
02679
02680
02681
02682 void vtkMitkOpenGLGPUVolumeRayCastMapper::ReleaseGraphicsResources(
02683 vtkWindow *window)
02684 {
02685 if(this->OpenGLObjectsCreated)
02686 {
02687 window->MakeCurrent();
02688 this->LastSize[0]=0;
02689 this->LastSize[1]=0;
02690 GLuint frameBufferObject=static_cast<GLuint>(this->FrameBufferObject);
02691 vtkgl::DeleteFramebuffersEXT(1,&frameBufferObject);
02692 GLuint depthRenderBufferObject=
02693 static_cast<GLuint>(this->DepthRenderBufferObject);
02694 vtkgl::DeleteRenderbuffersEXT(1,&depthRenderBufferObject);
02695 GLuint textureObjects[vtkMitkOpenGLGPUVolumeRayCastMapperNumberOfTextureObjects];
02696 int i=0;
02697 while(i<(vtkMitkOpenGLGPUVolumeRayCastMapperTextureObjectFrameBufferLeftFront+this->NumberOfFrameBuffers))
02698 {
02699 textureObjects[i]=static_cast<GLuint>(this->TextureObjects[i]);
02700 ++i;
02701 }
02702 glDeleteTextures(vtkMitkOpenGLGPUVolumeRayCastMapperTextureObjectFrameBufferLeftFront+this->NumberOfFrameBuffers,textureObjects);
02703
02704 if(this->MaxValueFrameBuffer!=0)
02705 {
02706 GLuint maxValueFrameBuffer=
02707 static_cast<GLuint>(this->MaxValueFrameBuffer);
02708 glDeleteTextures(1,&maxValueFrameBuffer);
02709 this->MaxValueFrameBuffer=0;
02710 }
02711 if(this->MaxValueFrameBuffer2!=0)
02712 {
02713 GLuint maxValueFrameBuffer2=
02714 static_cast<GLuint>(this->MaxValueFrameBuffer2);
02715 glDeleteTextures(1,&maxValueFrameBuffer2);
02716 this->MaxValueFrameBuffer2=0;
02717 }
02718
02719 GLuint programShader=static_cast<GLuint>(this->ProgramShader);
02720 vtkgl::DeleteProgram(programShader);
02721 this->ProgramShader=0;
02722 GLuint fragmentComponentShader=
02723 static_cast<GLuint>(this->FragmentComponentShader);
02724 vtkgl::DeleteShader(fragmentComponentShader);
02725 GLuint fragmentShadeShader=
02726 static_cast<GLuint>(this->FragmentShadeShader);
02727 vtkgl::DeleteShader(fragmentShadeShader);
02728
02729 GLuint scaleBiasProgramShader=
02730 static_cast<GLuint>(this->ScaleBiasProgramShader);
02731 if(scaleBiasProgramShader!=0)
02732 {
02733 vtkgl::DeleteProgram(scaleBiasProgramShader);
02734 this->ScaleBiasProgramShader=0;
02735 }
02736 this->LastParallelProjection=
02737 vtkMitkOpenGLGPUVolumeRayCastMapperProjectionNotInitialized;
02738 this->LastRayCastMethod=
02739 vtkMitkOpenGLGPUVolumeRayCastMapperMethodNotInitialized;
02740 this->LastCroppingMode=
02741 vtkMitkOpenGLGPUVolumeRayCastMapperCroppingNotInitialized;
02742 this->LastComponent=
02743 vtkMitkOpenGLGPUVolumeRayCastMapperComponentNotInitialized;
02744 this->LastShade=vtkMitkOpenGLGPUVolumeRayCastMapperShadeNotInitialized;
02745 this->OpenGLObjectsCreated=0;
02746 }
02747
02748 if(this->NoiseTextureId!=0)
02749 {
02750 window->MakeCurrent();
02751 GLuint noiseTextureObjects=static_cast<GLuint>(this->NoiseTextureId);
02752 glDeleteTextures(1,&noiseTextureObjects);
02753 this->NoiseTextureId=0;
02754 }
02755
02756 if(this->ScalarsTextures!=0)
02757 {
02758 if(!this->ScalarsTextures->Map.empty())
02759 {
02760 vtkstd::map<vtkImageData *,vtkKWScalarField *>::iterator it=this->ScalarsTextures->Map.begin();
02761 while(it!=this->ScalarsTextures->Map.end())
02762 {
02763 vtkKWScalarField *texture=(*it).second;
02764 delete texture;
02765 ++it;
02766 }
02767 this->ScalarsTextures->Map.clear();
02768 }
02769 }
02770
02771 if(this->MaskTextures!=0)
02772 {
02773 if(!this->MaskTextures->Map.empty())
02774 {
02775 vtkstd::map<vtkImageData *,vtkKWMask *>::iterator it=this->MaskTextures->Map.begin();
02776 while(it!=this->MaskTextures->Map.end())
02777 {
02778 vtkKWMask *texture=(*it).second;
02779 delete texture;
02780 ++it;
02781 }
02782 this->MaskTextures->Map.clear();
02783 }
02784 }
02785
02786 if(this->RGBTable!=0)
02787 {
02788 delete this->RGBTable;
02789 this->RGBTable=0;
02790 }
02791
02792 if(this->Mask1RGBTable!=0)
02793 {
02794 delete this->Mask1RGBTable;
02795 this->Mask1RGBTable=0;
02796 }
02797
02798 if(this->Mask2RGBTable!=0)
02799 {
02800 delete this->Mask2RGBTable;
02801 this->Mask2RGBTable=0;
02802 }
02803
02804 if(this->OpacityTables!=0)
02805 {
02806 delete this->OpacityTables;
02807 this->OpacityTables=0;
02808 }
02809 }
02810
02811
02812
02813
02814
02815
02816
02817
02818
02819 int vtkMitkOpenGLGPUVolumeRayCastMapper::AllocateFrameBuffers(vtkRenderer *ren)
02820 {
02821 assert("pre: ren_exists" && ren!=0);
02822 assert("pre: opengl_objects_created" && this->OpenGLObjectsCreated);
02823
02824 int result=1;
02825 int size[2];
02826 ren->GetTiledSize(&size[0],&size[1]);
02827
02828 int sizeChanged=this->LastSize[0]!=size[0] || this->LastSize[1]!=size[1];
02829
02830
02831 if(sizeChanged)
02832 {
02833 int i=0;
02834 GLenum errorCode=glGetError();
02835 while(i <this->NumberOfFrameBuffers && errorCode==GL_NO_ERROR)
02836 {
02837 glBindTexture(GL_TEXTURE_2D,static_cast<GLuint>(this->TextureObjects[vtkMitkOpenGLGPUVolumeRayCastMapperTextureObjectFrameBufferLeftFront+i]));
02838 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, vtkgl::CLAMP_TO_EDGE);
02839 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, vtkgl::CLAMP_TO_EDGE);
02840 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
02841 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
02842
02843 if(this->Supports_GL_ARB_texture_float)
02844 {
02845 glTexImage2D(GL_TEXTURE_2D,0,vtkgl::RGBA16F_ARB,size[0],size[1],
02846 0, GL_RGBA, GL_FLOAT, NULL );
02847 }
02848 else
02849 {
02850 glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA16,size[0],size[1],
02851 0, GL_RGBA, GL_FLOAT, NULL );
02852 }
02853 errorCode=glGetError();
02854 ++i;
02855 }
02856 if(errorCode==GL_NO_ERROR)
02857 {
02858
02859 glBindTexture(GL_TEXTURE_2D,static_cast<GLuint>(this->TextureObjects[vtkMitkOpenGLGPUVolumeRayCastMapperTextureObjectDepthMap]));
02860 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, vtkgl::CLAMP_TO_EDGE);
02861 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, vtkgl::CLAMP_TO_EDGE);
02862 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
02863 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
02864 glTexParameteri(GL_TEXTURE_2D, vtkgl::DEPTH_TEXTURE_MODE, GL_LUMINANCE);
02865 glTexImage2D(GL_TEXTURE_2D, 0, vtkgl::DEPTH_COMPONENT32, size[0],size[1],
02866 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL );
02867
02868
02869
02870 GLint savedFrameBuffer;
02871 glGetIntegerv(vtkgl::FRAMEBUFFER_BINDING_EXT,&savedFrameBuffer);
02872 vtkgl::BindFramebufferEXT(vtkgl::FRAMEBUFFER_EXT,
02873 static_cast<GLuint>(this->FrameBufferObject));
02874 vtkgl::BindRenderbufferEXT(
02875 vtkgl::RENDERBUFFER_EXT,
02876 static_cast<GLuint>(this->DepthRenderBufferObject));
02877 vtkgl::RenderbufferStorageEXT(vtkgl::RENDERBUFFER_EXT,
02878 vtkgl::DEPTH_COMPONENT24,size[0],size[1]);
02879 vtkgl::BindFramebufferEXT(vtkgl::FRAMEBUFFER_EXT,
02880 static_cast<GLuint>(savedFrameBuffer));
02881 errorCode=glGetError();
02882 if(errorCode==GL_NO_ERROR)
02883 {
02884 this->LastSize[0]=size[0];
02885 this->LastSize[1]=size[1];
02886 }
02887 }
02888 result=errorCode==GL_NO_ERROR;
02889 }
02890
02891 int needNewMaxValueBuffer=this->MaxValueFrameBuffer==0 &&
02892 (this->BlendMode==vtkVolumeMapper::MAXIMUM_INTENSITY_BLEND ||
02893 this->BlendMode==vtkMitkGPUVolumeRayCastMapper::MINIMUM_INTENSITY_BLEND);
02894
02895 if(needNewMaxValueBuffer)
02896 {
02897
02898
02899
02900
02901
02902
02903
02904 GLuint maxValueFrameBuffer;
02905 glGenTextures(1,&maxValueFrameBuffer);
02906
02907 GLint savedFrameBuffer;
02908 glGetIntegerv(vtkgl::FRAMEBUFFER_BINDING_EXT,&savedFrameBuffer);
02909 vtkgl::BindFramebufferEXT(
02910 vtkgl::FRAMEBUFFER_EXT,static_cast<GLuint>(this->FrameBufferObject));
02911 glBindTexture(GL_TEXTURE_2D,maxValueFrameBuffer);
02912 vtkgl::FramebufferTexture2DEXT(vtkgl::FRAMEBUFFER_EXT,
02913 vtkgl::COLOR_ATTACHMENT0_EXT+1,
02914 GL_TEXTURE_2D,maxValueFrameBuffer,0);
02915 this->MaxValueFrameBuffer=
02916 static_cast<unsigned int>(maxValueFrameBuffer);
02917 vtkgl::BindFramebufferEXT(vtkgl::FRAMEBUFFER_EXT,
02918 static_cast<GLuint>(savedFrameBuffer));
02919
02920
02921 GLuint maxValueFrameBuffer2;
02922 glGenTextures(1,&maxValueFrameBuffer2);
02923 glBindTexture(GL_TEXTURE_2D,maxValueFrameBuffer2);
02924 this->MaxValueFrameBuffer2=
02925 static_cast<unsigned int>(maxValueFrameBuffer2);
02926 }
02927 else
02928 {
02929 if(this->MaxValueFrameBuffer!=0 &&
02930 (this->BlendMode!=vtkVolumeMapper::MAXIMUM_INTENSITY_BLEND
02931 &&
02932 this->BlendMode!=vtkMitkGPUVolumeRayCastMapper::MINIMUM_INTENSITY_BLEND))
02933 {
02934
02935
02936 GLint savedFrameBuffer;
02937 glGetIntegerv(vtkgl::FRAMEBUFFER_BINDING_EXT,&savedFrameBuffer);
02938 vtkgl::BindFramebufferEXT(vtkgl::FRAMEBUFFER_EXT,
02939 static_cast<GLuint>(this->FrameBufferObject));
02940 vtkgl::FramebufferTexture2DEXT(vtkgl::FRAMEBUFFER_EXT,
02941 vtkgl::COLOR_ATTACHMENT0_EXT+1,
02942 GL_TEXTURE_2D,0,0);
02943 vtkgl::BindFramebufferEXT(vtkgl::FRAMEBUFFER_EXT,
02944 static_cast<GLuint>(savedFrameBuffer));
02945
02946 GLuint maxValueFrameBuffer=
02947 static_cast<GLuint>(this->MaxValueFrameBuffer);
02948 glDeleteTextures(1,&maxValueFrameBuffer);
02949 this->MaxValueFrameBuffer=0;
02950
02951 GLuint maxValueFrameBuffer2=
02952 static_cast<GLuint>(this->MaxValueFrameBuffer2);
02953 glDeleteTextures(1,&maxValueFrameBuffer2);
02954 this->MaxValueFrameBuffer2=0;
02955 }
02956 }
02957
02958 if((this->BlendMode==vtkVolumeMapper::MAXIMUM_INTENSITY_BLEND
02959 || this->BlendMode==vtkMitkGPUVolumeRayCastMapper::MINIMUM_INTENSITY_BLEND) && (sizeChanged || needNewMaxValueBuffer))
02960 {
02961
02962 GLuint maxValueFrameBuffer=static_cast<GLuint>(this->MaxValueFrameBuffer);
02963 glBindTexture(GL_TEXTURE_2D,maxValueFrameBuffer);
02964 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, vtkgl::CLAMP_TO_EDGE);
02965 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, vtkgl::CLAMP_TO_EDGE);
02966 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
02967 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
02968
02969 if(this->Supports_GL_ARB_texture_float)
02970 {
02971 glTexImage2D(GL_TEXTURE_2D,0,vtkgl::RGBA16F_ARB,size[0],size[1],
02972 0, GL_RGBA, GL_FLOAT, NULL );
02973 }
02974 else
02975 {
02976 glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA16,size[0],size[1],
02977 0, GL_RGBA, GL_FLOAT, NULL );
02978 }
02979
02980
02981 GLuint maxValueFrameBuffer2=static_cast<GLuint>(this->MaxValueFrameBuffer2);
02982 glBindTexture(GL_TEXTURE_2D,maxValueFrameBuffer2);
02983 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, vtkgl::CLAMP_TO_EDGE);
02984 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, vtkgl::CLAMP_TO_EDGE);
02985 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
02986 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
02987
02988 if(this->Supports_GL_ARB_texture_float)
02989 {
02990 glTexImage2D(GL_TEXTURE_2D,0,vtkgl::RGBA16F_ARB,size[0],size[1],
02991 0, GL_RGBA, GL_FLOAT, NULL );
02992 }
02993 else
02994 {
02995 glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA16,size[0],size[1],
02996 0, GL_RGBA, GL_FLOAT, NULL );
02997 }
02998
02999 }
03000 PrintError("AllocateFrameBuffers");
03001 return result;
03002 }
03003
03004
03005
03006
03007
03008 void vtkMitkOpenGLGPUVolumeRayCastMapper::GetTextureFormat(
03009 vtkImageData *input,
03010 unsigned int *internalFormat,
03011 unsigned int *format,
03012 unsigned int *type,
03013 int *componentSize)
03014 {
03015 *internalFormat=0;
03016 *format=0;
03017 *type=0;
03018 *componentSize=0;
03019
03020 vtkDataArray *scalars=this->GetScalars(input,this->ScalarMode,
03021 this->ArrayAccessMode,
03022 this->ArrayId,
03023 this->ArrayName,
03024 this->CellFlag);
03025
03026 int scalarType=scalars->GetDataType();
03027 int components=scalars->GetNumberOfComponents();
03028 *componentSize=vtkAbstractArray::GetDataTypeSize(scalarType)*components;
03029
03030 if(components==4)
03031 {
03032
03033 *internalFormat=GL_RGBA16;
03034 *format=GL_RGBA;
03035 *type=GL_UNSIGNED_BYTE;
03036 }
03037 else
03038 {
03039
03040 switch(scalarType)
03041 {
03042 case VTK_FLOAT:
03043 if(this->Supports_GL_ARB_texture_float)
03044 {
03045 *internalFormat=vtkgl::INTENSITY16F_ARB;
03046 }
03047 else
03048 {
03049 *internalFormat=GL_INTENSITY16;
03050 }
03051 *format=GL_RED;
03052 *type=GL_FLOAT;
03053 break;
03054 case VTK_UNSIGNED_CHAR:
03055 *internalFormat=GL_INTENSITY8;
03056 *format=GL_RED;
03057 *type=GL_UNSIGNED_BYTE;
03058 break;
03059 case VTK_SIGNED_CHAR:
03060 *internalFormat=GL_INTENSITY8;
03061 *format=GL_RED;
03062 *type=GL_BYTE;
03063 break;
03064 case VTK_CHAR:
03065
03066 assert("check: impossible case" && 0);
03067 break;
03068 case VTK_BIT:
03069
03070 assert("check: impossible case" && 0);
03071 break;
03072 case VTK_ID_TYPE:
03073
03074 assert("check: impossible case" && 0);
03075 break;
03076 case VTK_INT:
03077 *internalFormat=GL_INTENSITY16;
03078 *format=GL_RED;
03079 *type=GL_INT;
03080 break;
03081 case VTK_DOUBLE:
03082 case VTK___INT64:
03083 case VTK_LONG:
03084 case VTK_LONG_LONG:
03085 case VTK_UNSIGNED___INT64:
03086 case VTK_UNSIGNED_LONG:
03087 case VTK_UNSIGNED_LONG_LONG:
03088 if(this->Supports_GL_ARB_texture_float)
03089 {
03090 *internalFormat=vtkgl::INTENSITY16F_ARB;
03091 }
03092 else
03093 {
03094 *internalFormat=GL_INTENSITY16;
03095 }
03096 *format=GL_RED;
03097 *type=GL_FLOAT;
03098 break;
03099 case VTK_SHORT:
03100 *internalFormat=GL_INTENSITY16;
03101 *format=GL_RED;
03102 *type=GL_SHORT;
03103 break;
03104 case VTK_STRING:
03105
03106 assert("check: impossible case" && 0);
03107 break;
03108 case VTK_UNSIGNED_SHORT:
03109 *internalFormat=GL_INTENSITY16;
03110 *format=GL_RED;
03111 *type=GL_UNSIGNED_SHORT;
03112 break;
03113 case VTK_UNSIGNED_INT:
03114 *internalFormat=GL_INTENSITY16;
03115 *format=GL_RED;
03116 *type=GL_UNSIGNED_INT;
03117 break;
03118 default:
03119 assert("check: impossible case" && 0);
03120 break;
03121 }
03122 }
03123 }
03124
03125
03126
03127
03128
03129 bool vtkMitkOpenGLGPUVolumeRayCastMapper::TestLoadingScalar(
03130 unsigned int internalFormat,
03131 unsigned int format,
03132 unsigned int type,
03133 int textureSize[3],
03134 int componentSize)
03135 {
03136
03137
03138 bool result;
03139
03140 vtkgl::TexImage3D(vtkgl::PROXY_TEXTURE_3D,0,
03141 static_cast<GLint>(internalFormat),
03142 textureSize[0],textureSize[1],textureSize[2],0,
03143 format,
03144 type,0);
03145 GLint width;
03146 glGetTexLevelParameteriv(vtkgl::PROXY_TEXTURE_3D,0,GL_TEXTURE_WIDTH,
03147 &width);
03148
03149 result=width!=0;
03150 if(result)
03151 {
03152
03153
03154 vtkgl::TexImage3D(vtkgl::TEXTURE_3D,0,static_cast<GLint>(internalFormat),
03155 textureSize[0],
03156 textureSize[1],textureSize[2],0,
03157 format,
03158 type,0);
03159 GLenum errorCode=glGetError();
03160 result=errorCode!=GL_OUT_OF_MEMORY;
03161 if(result)
03162 {
03163 if(errorCode!=GL_NO_ERROR)
03164 {
03165 cout<<"after try to load the texture";
03166 cout<<" ERROR (x"<<hex<<errorCode<<") "<<dec;
03167 cout<<OpenGLErrorMessage(static_cast<unsigned int>(errorCode));
03168 cout<<endl;
03169 }
03170
03171 result=textureSize[0]*textureSize[1]*textureSize[2]*componentSize
03172 <=static_cast<float>(this->MaxMemoryInBytes)*this->MaxMemoryFraction;
03173 }
03174 }
03175 return result;
03176 }
03177
03178
03179
03180
03181
03182
03183
03184
03185
03186
03187
03188
03189
03190
03191
03192
03193
03194
03195
03196
03197
03198
03199
03200 int vtkMitkOpenGLGPUVolumeRayCastMapper::LoadScalarField(vtkImageData *input,
03201 vtkImageData *maskInput,
03202 int textureExtent[6],
03203 vtkVolume *volume)
03204 {
03205 assert("pre: input_exists" && input!=0);
03206 assert("pre: valid_point_extent" && (this->CellFlag ||
03207 (textureExtent[0]<textureExtent[1] &&
03208 textureExtent[2]<textureExtent[3] &&
03209 textureExtent[4]<textureExtent[5])));
03210 assert("pre: valid_cell_extent" && (!this->CellFlag ||
03211 (textureExtent[0]<=textureExtent[1] &&
03212 textureExtent[2]<=textureExtent[3] &&
03213 textureExtent[4]<=textureExtent[5])));
03214
03215 int result=1;
03216
03217
03218
03219
03220
03221 vtkgl::ActiveTexture(vtkgl::TEXTURE0);
03222
03223
03224 vtkstd::map<vtkImageData *,vtkKWScalarField *>::iterator it=
03225 this->ScalarsTextures->Map.find(input);
03226
03227
03228 vtkKWScalarField *texture;
03229 if(it==this->ScalarsTextures->Map.end())
03230 {
03231 texture=new vtkKWScalarField;
03232 this->ScalarsTextures->Map[input]=texture;
03233 texture->SetSupports_GL_ARB_texture_float(this->Supports_GL_ARB_texture_float==1);
03234 }
03235 else
03236 {
03237 texture=(*it).second;
03238 }
03239
03240 texture->Update(input,this->CellFlag,textureExtent,this->ScalarMode,
03241 this->ArrayAccessMode,
03242 this->ArrayId,
03243 this->ArrayName,
03244 volume->GetProperty()->GetInterpolationType()
03245 ==VTK_LINEAR_INTERPOLATION,
03246 this->TableRange,
03247 static_cast<int>(static_cast<float>(this->MaxMemoryInBytes)*this->MaxMemoryFraction));
03248
03249 result=texture->IsLoaded();
03250 this->CurrentScalar=texture;
03251
03252
03253
03254 if(maskInput!=0)
03255 {
03256 vtkgl::ActiveTexture(vtkgl::TEXTURE7);
03257
03258
03259 vtkstd::map<vtkImageData *,vtkKWMask *>::iterator it2=
03260 this->MaskTextures->Map.find(maskInput);
03261
03262
03263 vtkKWMask *mask;
03264 if(it2==this->MaskTextures->Map.end())
03265 {
03266 mask=new vtkKWMask;
03267 this->MaskTextures->Map[maskInput]=mask;
03268 }
03269 else
03270 {
03271 mask=(*it2).second;
03272 }
03273
03274 mask->Update(maskInput,this->CellFlag,textureExtent,this->ScalarMode,
03275 this->ArrayAccessMode,
03276 this->ArrayId,
03277 this->ArrayName,
03278 static_cast<int>(static_cast<float>(this->MaxMemoryInBytes)*this->MaxMemoryFraction));
03279
03280 result=result && mask->IsLoaded();
03281 this->CurrentMask=mask;
03282 vtkgl::ActiveTexture(vtkgl::TEXTURE0);
03283 }
03284
03285 return result;
03286 }
03287
03288
03289
03290
03291
03292
03293
03294 int vtkMitkOpenGLGPUVolumeRayCastMapper::UpdateColorTransferFunction(
03295 vtkVolume *vol,
03296 int numberOfScalarComponents)
03297 {
03298 assert("pre: vol_exists" && vol!=0);
03299 assert("pre: valid_numberOfScalarComponents" &&
03300 (numberOfScalarComponents==1 || numberOfScalarComponents==4));
03301
03302
03303
03304
03305
03306
03307 if(numberOfScalarComponents==1)
03308 {
03309 vtkVolumeProperty *volumeProperty=vol->GetProperty();
03310 vtkColorTransferFunction *colorTransferFunction=volumeProperty->GetRGBTransferFunction(0);
03311
03312 vtkgl::ActiveTexture(vtkgl::TEXTURE1);
03313
03314 this->RGBTable->Update(
03315 colorTransferFunction,this->TableRange,
03316 volumeProperty->GetInterpolationType()==VTK_LINEAR_INTERPOLATION);
03317
03318 vtkgl::ActiveTexture( vtkgl::TEXTURE0);
03319 }
03320
03321 if(this->MaskInput!=0)
03322 {
03323 vtkVolumeProperty *volumeProperty=vol->GetProperty();
03324 vtkColorTransferFunction *c=volumeProperty->GetRGBTransferFunction(1);
03325
03326 vtkgl::ActiveTexture(vtkgl::TEXTURE8);
03327 this->Mask1RGBTable->Update(c,this->TableRange,false);
03328
03329 c=volumeProperty->GetRGBTransferFunction(2);
03330 vtkgl::ActiveTexture(vtkgl::TEXTURE9);
03331 this->Mask2RGBTable->Update(c,this->TableRange,false);
03332
03333
03334 vtkgl::ActiveTexture( vtkgl::TEXTURE0);
03335 }
03336 return 1;
03337 }
03338
03339
03340
03341
03342
03343
03344
03345 int vtkMitkOpenGLGPUVolumeRayCastMapper::UpdateOpacityTransferFunction(
03346 vtkVolume *vol,
03347 int numberOfScalarComponents,
03348 unsigned int level)
03349 {
03350 assert("pre: vol_exists" && vol!=0);
03351 assert("pre: valid_numberOfScalarComponents" &&
03352 (numberOfScalarComponents==1 || numberOfScalarComponents==4));
03353
03354 (void)numberOfScalarComponents;
03355
03356 vtkVolumeProperty *volumeProperty=vol->GetProperty();
03357 vtkPiecewiseFunction *scalarOpacity=volumeProperty->GetScalarOpacity();
03358
03359 vtkgl::ActiveTexture( vtkgl::TEXTURE2);
03360 this->OpacityTables->Vector[level].Update(
03361 scalarOpacity,this->BlendMode,
03362 this->ActualSampleDistance,
03363 this->TableRange,
03364 volumeProperty->GetScalarOpacityUnitDistance(0),
03365 volumeProperty->GetInterpolationType()==VTK_LINEAR_INTERPOLATION);
03366
03367 vtkgl::ActiveTexture( vtkgl::TEXTURE0);
03368
03369 return 1;
03370 }
03371
03372
03373
03374
03375
03376
03377 void vtkMitkOpenGLGPUVolumeRayCastMapper::SetupRender(vtkRenderer *ren,
03378 vtkVolume *vol)
03379 {
03380 assert("pre: ren_exists" && ren!=0);
03381 assert("pre: vol_exists" && vol!=0);
03382
03383 double aspect[2];
03384 int lowerLeft[2];
03385 int usize, vsize;
03386
03387 ren->GetTiledSizeAndOrigin(&usize,&vsize,lowerLeft,lowerLeft+1);
03388
03389 usize = static_cast<int>(usize*this->ReductionFactor);
03390 vsize = static_cast<int>(vsize*this->ReductionFactor);
03391
03392 this->ReducedSize[0]=usize;
03393 this->ReducedSize[1]=vsize;
03394
03395
03396
03397 glViewport(0,0, usize, vsize);
03398 glEnable( GL_SCISSOR_TEST );
03399 glScissor(0,0, usize, vsize);
03400 glClearColor(0.0, 0.0, 0.0, 0.0);
03401
03402 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
03403 ren->ComputeAspect();
03404 ren->GetAspect(aspect);
03405 double aspect2[2];
03406 ren->vtkViewport::ComputeAspect();
03407 ren->vtkViewport::GetAspect(aspect2);
03408 double aspectModification = aspect[0]*aspect2[1]/(aspect[1]*aspect2[0]);
03409
03410 vtkCamera *cam = ren->GetActiveCamera();
03411
03412 glMatrixMode( GL_PROJECTION);
03413 if(usize && vsize)
03414 {
03415 this->TempMatrix[0]->DeepCopy(cam->GetProjectionTransformMatrix(
03416 aspectModification*usize/vsize, -1,1));
03417 this->TempMatrix[0]->Transpose();
03418 glLoadMatrixd(this->TempMatrix[0]->Element[0]);
03419 }
03420 else
03421 {
03422 glLoadIdentity();
03423
03424 }
03425
03426
03427
03428 glMatrixMode(GL_MODELVIEW);
03429 glPushMatrix();
03430 this->TempMatrix[0]->DeepCopy(vol->GetMatrix());
03431 this->TempMatrix[0]->Transpose();
03432
03433
03434 glMultMatrixd(this->TempMatrix[0]->Element[0]);
03435 glShadeModel(GL_SMOOTH);
03436 glDisable( GL_LIGHTING);
03437 glEnable (GL_CULL_FACE);
03438 glDisable(GL_DEPTH_TEST);
03439 glDisable(GL_BLEND);
03440 this->PrintError("SetupRender");
03441 }
03442
03443
03444
03445
03446 void vtkMitkOpenGLGPUVolumeRayCastMapper::DebugDisplayBox(vtkPolyData *box)
03447 {
03448 vtkPoints *points=box->GetPoints();
03449 vtkCellArray *polys=box->GetPolys();
03450 cout<<"npts="<<points->GetNumberOfPoints()<<endl;
03451 int pointId=0;
03452 while(pointId<points->GetNumberOfPoints())
03453 {
03454 double coords[3];
03455 points->GetPoint(pointId,coords);
03456 cout<<"pointId="<<pointId<<endl;
03457 int i=0;
03458 while(i<3)
03459 {
03460 cout<<" "<<coords[i];
03461 ++i;
03462 }
03463 cout<<endl;
03464 ++pointId;
03465 }
03466 vtkIdType npts=0;
03467 vtkIdType *pts=0;
03468 cout<<"ncells="<<polys->GetNumberOfCells()<<endl;
03469 int cellId=0;
03470 polys->InitTraversal();
03471 while(cellId<polys->GetNumberOfCells())
03472 {
03473 polys->GetNextCell(npts,pts);
03474 cout<<"cellId="<<cellId<<" npts="<<npts<<endl;
03475 vtkIdType i=0;
03476 while(i<npts)
03477 {
03478 cout<<pts[i]<<" ";
03479 ++i;
03480 }
03481 cout<<endl;
03482 ++cellId;
03483 }
03484 }
03485
03486
03487
03488
03489
03490 void vtkMitkOpenGLGPUVolumeRayCastMapper::ClipBoundingBox(vtkRenderer *ren,
03491 double worldBounds[6],
03492 vtkVolume *vol)
03493 {
03494
03495
03496 vol->GetMatrix( this->InvVolumeMatrix );
03497 this->InvVolumeMatrix->Invert();
03498
03499 if(this->BoxSource==0)
03500 {
03501 this->BoxSource=vtkTessellatedBoxSource::New();
03502 }
03503 this->BoxSource->SetBounds(worldBounds);
03504 this->BoxSource->SetLevel(0);
03505 this->BoxSource->QuadsOn();
03506
03507 if(this->Planes==0)
03508 {
03509 this->Planes=vtkPlaneCollection::New();
03510 }
03511 this->Planes->RemoveAllItems();
03512
03513 vtkCamera *cam = ren->GetActiveCamera();
03514 double camWorldRange[2];
03515 double camWorldPos[4];
03516 double camFocalWorldPoint[4];
03517 double camWorldDirection[3];
03518 double range[2];
03519 double camPos[4];
03520 double focalPoint[4];
03521 double direction[3];
03522
03523 cam->GetPosition(camWorldPos);
03524 camWorldPos[3] = 1.0;
03525 this->InvVolumeMatrix->MultiplyPoint( camWorldPos, camPos );
03526 if ( camPos[3] )
03527 {
03528 camPos[0] /= camPos[3];
03529 camPos[1] /= camPos[3];
03530 camPos[2] /= camPos[3];
03531 }
03532
03533 cam->GetFocalPoint(camFocalWorldPoint);
03534 camFocalWorldPoint[3]=1.0;
03535 this->InvVolumeMatrix->MultiplyPoint( camFocalWorldPoint,focalPoint );
03536 if ( focalPoint[3] )
03537 {
03538 focalPoint[0] /= focalPoint[3];
03539 focalPoint[1] /= focalPoint[3];
03540 focalPoint[2] /= focalPoint[3];
03541 }
03542
03543
03544 direction[0] = focalPoint[0] - camPos[0];
03545 direction[1] = focalPoint[1] - camPos[1];
03546 direction[2] = focalPoint[2] - camPos[2];
03547
03548 vtkMath::Normalize(direction);
03549
03550
03551
03552 camWorldDirection[0] = camFocalWorldPoint[0] - camWorldPos[0];
03553 camWorldDirection[1] = camFocalWorldPoint[1] - camWorldPos[1];
03554 camWorldDirection[2] = camFocalWorldPoint[2] - camWorldPos[2];
03555 vtkMath::Normalize(camWorldDirection);
03556
03557 double camNearWorldPoint[4];
03558 double camFarWorldPoint[4];
03559 double camNearPoint[4];
03560 double camFarPoint[4];
03561 cam->GetClippingRange(camWorldRange);
03562 camNearWorldPoint[0] = camWorldPos[0] + camWorldRange[0]*camWorldDirection[0];
03563 camNearWorldPoint[1] = camWorldPos[1] + camWorldRange[0]*camWorldDirection[1];
03564 camNearWorldPoint[2] = camWorldPos[2] + camWorldRange[0]*camWorldDirection[2];
03565 camNearWorldPoint[3] = 1.;
03566
03567 camFarWorldPoint[0] = camWorldPos[0] + camWorldRange[1]*camWorldDirection[0];
03568 camFarWorldPoint[1] = camWorldPos[1] + camWorldRange[1]*camWorldDirection[1];
03569 camFarWorldPoint[2] = camWorldPos[2] + camWorldRange[1]*camWorldDirection[2];
03570 camFarWorldPoint[3] = 1.;
03571
03572 this->InvVolumeMatrix->MultiplyPoint( camNearWorldPoint, camNearPoint );
03573 if (camNearPoint[3])
03574 {
03575 camNearPoint[0] /= camNearPoint[3];
03576 camNearPoint[1] /= camNearPoint[3];
03577 camNearPoint[2] /= camNearPoint[3];
03578 }
03579 this->InvVolumeMatrix->MultiplyPoint( camFarWorldPoint, camFarPoint );
03580 if (camFarPoint[3])
03581 {
03582 camFarPoint[0] /= camFarPoint[3];
03583 camFarPoint[1] /= camFarPoint[3];
03584 camFarPoint[2] /= camFarPoint[3];
03585 }
03586 range[0] = sqrt(vtkMath::Distance2BetweenPoints(camNearPoint, camPos));
03587 range[1] = sqrt(vtkMath::Distance2BetweenPoints(camFarPoint, camPos));
03588
03589
03590
03591 double dist = range[1] - range[0];
03592 range[0] += dist / (2<<16);
03593 range[1] -= dist / (2<<16);
03594
03595 if(this->NearPlane==0)
03596 {
03597 this->NearPlane= vtkPlane::New();
03598 }
03599
03600 this->NearPlane->SetOrigin( camNearPoint );
03601 this->NearPlane->SetNormal( direction );
03602 this->Planes->AddItem(this->NearPlane);
03603
03604 if ( this->ClippingPlanes )
03605 {
03606 this->ClippingPlanes->InitTraversal();
03607 vtkPlane *plane;
03608 while ( (plane = this->ClippingPlanes->GetNextItem()) )
03609 {
03610
03611
03612 double planeOrigin[4], planeNormal[4], planeP1[4];
03613 plane->GetOrigin(planeOrigin);
03614 planeOrigin[3] = 1.;
03615 plane->GetNormal(planeNormal);
03616 planeP1[0] = planeOrigin[0] + planeNormal[0];
03617 planeP1[1] = planeOrigin[1] + planeNormal[1];
03618 planeP1[2] = planeOrigin[2] + planeNormal[2];
03619 planeP1[3] = 1.;
03620 this->InvVolumeMatrix->MultiplyPoint(planeOrigin, planeOrigin);
03621 this->InvVolumeMatrix->MultiplyPoint(planeP1, planeP1);
03622 if( planeOrigin[3])
03623 {
03624 planeOrigin[0] /= planeOrigin[3];
03625 planeOrigin[1] /= planeOrigin[3];
03626 planeOrigin[2] /= planeOrigin[3];
03627 }
03628 if( planeP1[3])
03629 {
03630 planeP1[0] /= planeP1[3];
03631 planeP1[1] /= planeP1[3];
03632 planeP1[2] /= planeP1[3];
03633 }
03634 planeNormal[0] = planeP1[0] - planeOrigin[0];
03635 planeNormal[1] = planeP1[1] - planeOrigin[1];
03636 planeNormal[2] = planeP1[2] - planeOrigin[2];
03637 vtkMath::Normalize(planeNormal);
03638 vtkPlane* localPlane = vtkPlane::New();
03639 localPlane->SetOrigin(planeOrigin);
03640 localPlane->SetNormal(planeNormal);
03641 this->Planes->AddItem(localPlane);
03642 localPlane->Delete();
03643 }
03644 }
03645
03646 if(this->Clip==0)
03647 {
03648 this->Clip=vtkClipConvexPolyData::New();
03649 this->Clip->SetInputConnection(this->BoxSource->GetOutputPort());
03650 this->Clip->SetPlanes( this->Planes );
03651 }
03652
03653 this->Clip->Update();
03654
03655 if(this->Densify==0)
03656 {
03657 this->Densify=vtkDensifyPolyData::New();
03658 this->Densify->SetInputConnection(this->Clip->GetOutputPort());
03659 this->Densify->SetNumberOfSubdivisions(2);
03660 }
03661 this->Densify->Update();
03662 this->ClippedBoundingBox = this->Densify->GetOutput();
03663 }
03664
03665
03666
03667
03668 int vtkMitkOpenGLGPUVolumeRayCastMapper::RenderClippedBoundingBox(
03669 int tcoordFlag,
03670 size_t currentBlock,
03671 size_t numberOfBlocks,
03672 vtkRenderWindow *renWin )
03673 {
03674 assert("pre: valid_currentBlock" && currentBlock<numberOfBlocks);
03675
03676 vtkPoints *points = this->ClippedBoundingBox->GetPoints();
03677 vtkCellArray *polys = this->ClippedBoundingBox->GetPolys();
03678
03679 vtkIdType npts;
03680 vtkIdType *pts;
03681
03682 vtkIdType i, j;
03683
03684 double center[3] = {0,0,0};
03685 double min[3] = {VTK_DOUBLE_MAX, VTK_DOUBLE_MAX, VTK_DOUBLE_MAX};
03686 double max[3] = {VTK_DOUBLE_MIN, VTK_DOUBLE_MIN, VTK_DOUBLE_MIN};
03687
03688
03689 npts = points->GetNumberOfPoints();
03690 for ( i = 0; i < npts; i++ )
03691 {
03692 double pt[3];
03693 points->GetPoint( i, pt );
03694 for ( j = 0; j < 3; j++ )
03695 {
03696 min[j] = (pt[j]<min[j])?(pt[j]):(min[j]);
03697 max[j] = (pt[j]>max[j])?(pt[j]):(max[j]);
03698 }
03699 }
03700
03701 center[0] = 0.5*(min[0]+max[0]);
03702 center[1] = 0.5*(min[1]+max[1]);
03703 center[2] = 0.5*(min[2]+max[2]);
03704
03705 double *loadedBounds=0;
03706 vtkIdType *loadedExtent=0;
03707
03708 if ( tcoordFlag )
03709 {
03710 loadedBounds=this->CurrentScalar->GetLoadedBounds();
03711 loadedExtent=this->CurrentScalar->GetLoadedExtent();
03712 }
03713
03714 double *spacing=this->GetInput()->GetSpacing();
03715 double spacingSign[3];
03716 i=0;
03717 while(i<3)
03718 {
03719 if(spacing[i]<0)
03720 {
03721 spacingSign[i]=-1.0;
03722 }
03723 else
03724 {
03725 spacingSign[i]=1.0;
03726 }
03727 ++i;
03728 }
03729
03730
03731 int polyId=0;
03732 double polyCount=static_cast<double>(polys->GetNumberOfCells());
03733 polys->InitTraversal();
03734 int abort=0;
03735 while ( !abort && polys->GetNextCell(npts, pts) )
03736 {
03737 vtkIdType start, end, inc;
03738
03739
03740 if ( npts > 2 )
03741 {
03742
03743
03744
03745
03746
03747 double p1[3], p2[3], p3[3];
03748 double v1[3], v2[3], v3[3], v4[3];
03749
03750 points->GetPoint(pts[0], p1 );
03751 points->GetPoint(pts[1], p2 );
03752 points->GetPoint(pts[2], p3 );
03753
03754 v1[0] = p2[0] - p1[0];
03755 v1[1] = p2[1] - p1[1];
03756 v1[2] = p2[2] - p1[2];
03757
03758 v2[0] = p2[0] - p3[0];
03759 v2[1] = p2[1] - p3[1];
03760 v2[2] = p2[2] - p3[2];
03761
03762 vtkMath::Cross( v1, v2, v3 );
03763 vtkMath::Normalize(v3);
03764
03765 v4[0] = p2[0] - center[0];
03766 v4[1] = p2[1] - center[1];
03767 v4[2] = p2[2] - center[2];
03768 vtkMath::Normalize(v4);
03769
03770 double dot = vtkMath::Dot( v3, v4 );
03771
03772 if (( dot < 0) && this->PreserveOrientation)
03773 {
03774 start = 0;
03775 end = npts;
03776 inc = 1;
03777 }
03778 else
03779 {
03780 start = npts-1;
03781 end = -1;
03782 inc = -1;
03783 }
03784
03785 glBegin( GL_TRIANGLE_FAN );
03786
03787 double vert[3];
03788 double tcoord[3];
03789 for ( i = start; i != end; i += inc )
03790 {
03791 points->GetPoint(pts[i], vert);
03792 if ( tcoordFlag )
03793 {
03794 for ( j = 0; j < 3; j++ )
03795 {
03796
03797
03798 if(this->CellFlag)
03799
03800 {
03801 tcoord[j] = spacingSign[j]*(vert[j] - loadedBounds[j*2]) /
03802 (loadedBounds[j*2+1] - loadedBounds[j*2]);
03803 }
03804 else
03805 {
03806 double tmp;
03807 tmp = spacingSign[j]*(vert[j] - loadedBounds[j*2]) /
03808 (loadedBounds[j*2+1] - loadedBounds[j*2]);
03809 double delta=static_cast<double>(
03810 loadedExtent[j*2+1]-loadedExtent[j*2]+1);
03811 tcoord[j]=(tmp*(delta-1)+0.5)/delta;
03812 }
03813 }
03814 vtkgl::MultiTexCoord3dv(vtkgl::TEXTURE0, tcoord);
03815 }
03816 glVertex3dv(vert);
03817 }
03818 glEnd();
03819
03820 }
03821 if(tcoordFlag)
03822 {
03823
03824 if (!this->GeneratingCanonicalView && this->ReportProgress)
03825 {
03826 glFinish();
03827
03828 double currentTime=vtkTimerLog::GetUniversalTime();
03829 if(currentTime - this->LastProgressEventTime > 1.0)
03830 {
03831 double progress=(static_cast<double>(currentBlock)+polyId/polyCount)/
03832 static_cast<double>(numberOfBlocks);
03833 this->InvokeEvent(vtkCommand::VolumeMapperRenderProgressEvent,
03834 &progress);
03835 renWin->MakeCurrent();
03836 this->LastProgressEventTime = currentTime;
03837 }
03838 }
03839 abort=renWin->CheckAbortStatus();
03840 }
03841 ++polyId;
03842 }
03843 return abort;
03844 }
03845
03846 void vtkMitkOpenGLGPUVolumeRayCastMapper::CopyFBOToTexture()
03847 {
03848
03849
03850
03851
03852
03853
03854 vtkgl::ActiveTexture(vtkgl::TEXTURE4);
03855 glBindTexture(
03856 GL_TEXTURE_2D,
03857 this->TextureObjects[
03858 vtkMitkOpenGLGPUVolumeRayCastMapperTextureObjectFrameBufferLeftFront+1]);
03859
03860 glReadBuffer(vtkgl::COLOR_ATTACHMENT0_EXT);
03861 glCopyTexSubImage2D(GL_TEXTURE_2D,0,0,0,0,0,this->ReducedSize[0],
03862 this->ReducedSize[1]);
03863 if(this->BlendMode==vtkVolumeMapper::MAXIMUM_INTENSITY_BLEND
03864 || this->BlendMode==vtkMitkGPUVolumeRayCastMapper::MINIMUM_INTENSITY_BLEND)
03865 {
03866 vtkgl::ActiveTexture(vtkgl::TEXTURE5);
03867 glBindTexture(GL_TEXTURE_2D,this->MaxValueFrameBuffer2);
03868 glReadBuffer(vtkgl::COLOR_ATTACHMENT0_EXT+1);
03869 glCopyTexSubImage2D(GL_TEXTURE_2D,0,0,0,0,0,this->ReducedSize[0],
03870 this->ReducedSize[1]);
03871 }
03872 vtkgl::ActiveTexture(vtkgl::TEXTURE0);
03873 }
03874
03875
03876
03877
03878 void vtkMitkOpenGLGPUVolumeRayCastMapper::CleanupRender()
03879 {
03880 glPopMatrix();
03881 glDisable(GL_CULL_FACE);
03882 }
03883
03884
03885
03886
03887
03888 void vtkMitkOpenGLGPUVolumeRayCastMapper::BuildScaleBiasProgram()
03889 {
03890 if(this->ScaleBiasProgramShader==0)
03891 {
03892 GLuint programShader;
03893 GLuint fragmentShader;
03894
03895 programShader=vtkgl::CreateProgram();
03896 fragmentShader=vtkgl::CreateShader(vtkgl::FRAGMENT_SHADER);
03897 vtkgl::AttachShader(programShader,fragmentShader);
03898 vtkgl::DeleteShader(fragmentShader);
03899
03900 vtkgl::ShaderSource(
03901 fragmentShader,1,
03902 const_cast<const char **>(&vtkMitkGPUVolumeRayCastMapper_ScaleBiasFS),0);
03903 vtkgl::CompileShader(fragmentShader);
03904
03905 this->CheckCompilation(static_cast<unsigned int>(fragmentShader));
03906 vtkgl::LinkProgram(programShader);
03907 this->CheckLinkage(static_cast<unsigned int>(programShader));
03908
03909 this->ScaleBiasProgramShader=static_cast<unsigned int>(programShader);
03910 this->UFrameBufferTexture=
03911 static_cast<int>(vtkgl::GetUniformLocation(programShader,
03912 "frameBufferTexture"));
03913 this->UScale=static_cast<int>(vtkgl::GetUniformLocation(programShader,
03914 "scale"));
03915 this->UBias=static_cast<int>(vtkgl::GetUniformLocation(programShader,
03916 "bias"));
03917 }
03918
03919 }
03920
03921
03922
03923
03924
03925 void vtkMitkOpenGLGPUVolumeRayCastMapper::RenderTextureToScreen(vtkRenderer *ren)
03926 {
03927 assert("pre: ren_exists" && ren!=0);
03928
03929 if ( this->GeneratingCanonicalView )
03930 {
03931
03932 glBindTexture(GL_TEXTURE_2D,
03933 this->TextureObjects[
03934 vtkMitkOpenGLGPUVolumeRayCastMapperTextureObjectFrameBufferLeftFront]);
03935
03936 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
03937 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
03938
03939 glPixelStorei( GL_UNPACK_ALIGNMENT, 1 );
03940 glPixelStorei( GL_PACK_ALIGNMENT, 1 );
03941
03942 unsigned char *outPtr = static_cast<unsigned char *>(this->CanonicalViewImageData->GetScalarPointer());
03943 glGetTexImage( GL_TEXTURE_2D, 0, GL_RGB, GL_UNSIGNED_BYTE, outPtr );
03944 return;
03945 }
03946
03947 int lowerLeft[2];
03948 int usize, vsize;
03949 ren->GetTiledSizeAndOrigin(&usize,&vsize,lowerLeft,lowerLeft+1);
03950 glViewport(lowerLeft[0],lowerLeft[1], usize, vsize);
03951 glEnable( GL_SCISSOR_TEST );
03952 glScissor(lowerLeft[0],lowerLeft[1], usize, vsize);
03953
03954 glMatrixMode(GL_PROJECTION);
03955 glPushMatrix();
03956 glLoadIdentity();
03957 glOrtho(0.0, usize, 0.0, vsize, -1.0, 1.0 );
03958 glMatrixMode(GL_MODELVIEW);
03959 glPushMatrix();
03960 glLoadIdentity();
03961
03962 glBindTexture(GL_TEXTURE_2D,
03963 this->TextureObjects[vtkMitkOpenGLGPUVolumeRayCastMapperTextureObjectFrameBufferLeftFront]);
03964
03965 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
03966 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
03967
03968 glEnable(GL_BLEND);
03969 glBlendFunc( GL_ONE,GL_ONE_MINUS_SRC_ALPHA);
03970
03971
03972
03973 glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_REPLACE);
03974
03975 glDisable(GL_DEPTH_TEST);
03976
03977 double xOffset = 1.0 / usize;
03978 double yOffset = 1.0 / vsize;
03979
03980 glDepthMask(GL_FALSE);
03981
03982 double scale=1.0/this->FinalColorWindow;
03983 double bias=0.5-this->FinalColorLevel/this->FinalColorWindow;
03984
03985 if(scale!=1.0 || bias!=0.0)
03986 {
03987 this->BuildScaleBiasProgram();
03988 vtkgl::UseProgram(this->ScaleBiasProgramShader);
03989 if(this->UFrameBufferTexture!=-1)
03990 {
03991 vtkgl::Uniform1i(this->UFrameBufferTexture,0);
03992 }
03993 else
03994 {
03995 vtkErrorMacro(<<"uFrameBufferTexture is not a uniform variable.");
03996 }
03997 if(this->UScale!=-1)
03998 {
03999 vtkgl::Uniform1f(this->UScale,static_cast<GLfloat>(scale));
04000 }
04001 else
04002 {
04003 vtkErrorMacro(<<"uScale is not a uniform variable.");
04004 }
04005 if(this->UBias!=-1)
04006 {
04007 vtkgl::Uniform1f(this->UBias,static_cast<GLfloat>(bias));
04008 }
04009 else
04010 {
04011 vtkErrorMacro(<<"uBias is not a uniform variable.");
04012 }
04013 }
04014 else
04015 {
04016 glEnable(GL_TEXTURE_2D);
04017 }
04018
04019 glBegin(GL_QUADS);
04020 glTexCoord2f(static_cast<GLfloat>(xOffset),static_cast<GLfloat>(yOffset));
04021 glVertex2f(0.0,0.0);
04022 glTexCoord2f(static_cast<GLfloat>(this->ReductionFactor-xOffset),
04023 static_cast<GLfloat>(yOffset));
04024 glVertex2f(static_cast<GLfloat>(usize),0.0);
04025 glTexCoord2f(static_cast<GLfloat>(this->ReductionFactor-xOffset),
04026 static_cast<GLfloat>(this->ReductionFactor-yOffset));
04027 glVertex2f(static_cast<GLfloat>(usize),static_cast<GLfloat>(vsize));
04028 glTexCoord2f(static_cast<GLfloat>(xOffset),
04029 static_cast<GLfloat>(this->ReductionFactor-yOffset));
04030 glVertex2f(0.0,static_cast<GLfloat>(vsize));
04031 glEnd();
04032
04033
04034 glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_MODULATE);
04035
04036 if(scale!=1.0 || bias!=0.0)
04037 {
04038 vtkgl::UseProgram(0);
04039 }
04040 else
04041 {
04042 glDisable(GL_TEXTURE_2D);
04043 }
04044
04045 glDepthMask(GL_TRUE);
04046
04047 glDisable(GL_BLEND);
04048
04049 glMatrixMode(GL_PROJECTION);
04050 glPopMatrix();
04051 glMatrixMode(GL_MODELVIEW);
04052 glPopMatrix();
04053 }
04054
04055
04056
04057
04058
04059
04060
04061
04062
04063
04064
04065 void vtkMitkOpenGLGPUVolumeRayCastMapper::ComputeReductionFactor(
04066 double allocatedTime)
04067 {
04068 assert("pre: valid_current_reduction_range" && this->ReductionFactor>0.0
04069 && this->ReductionFactor<=1.0);
04070 assert("pre: positive_TimeToDraw" && this->TimeToDraw>=0.0);
04071 assert("pre: positive_time" && allocatedTime>0.0);
04072
04073 if ( this->GeneratingCanonicalView )
04074 {
04075 this->ReductionFactor = 1.0;
04076 return;
04077 }
04078
04079 if ( !this->AutoAdjustSampleDistances )
04080 {
04081 this->ReductionFactor = 1.0 / this->ImageSampleDistance;
04082 return;
04083 }
04084
04085 if ( this->TimeToDraw )
04086 {
04087 double oldFactor = this->ReductionFactor;
04088
04089 double timeToDraw;
04090 if (allocatedTime < 1.0)
04091 {
04092 timeToDraw = this->SmallTimeToDraw;
04093 if ( timeToDraw == 0.0 )
04094 {
04095 timeToDraw = this->BigTimeToDraw/3.0;
04096 }
04097 }
04098 else
04099 {
04100 timeToDraw = this->BigTimeToDraw;
04101 }
04102
04103 if ( timeToDraw == 0.0 )
04104 {
04105 timeToDraw = 10.0;
04106 }
04107
04108 double fullTime = timeToDraw / this->ReductionFactor;
04109 double newFactor = allocatedTime / fullTime;
04110
04111 if ( oldFactor == 1.0 ||
04112 newFactor / oldFactor > 1.3 ||
04113 newFactor / oldFactor < .95 )
04114 {
04115
04116 this->ReductionFactor = (newFactor+oldFactor)/2.0;
04117
04118 this->ReductionFactor = (this->ReductionFactor > 5.0)?(1.00):(this->ReductionFactor);
04119 this->ReductionFactor = (this->ReductionFactor > 1.0)?(0.99):(this->ReductionFactor);
04120 this->ReductionFactor = (this->ReductionFactor < 0.1)?(0.10):(this->ReductionFactor);
04121
04122 if ( 1.0/this->ReductionFactor > this->MaximumImageSampleDistance )
04123 {
04124 this->ReductionFactor = 1.0 / this->MaximumImageSampleDistance;
04125 }
04126 if ( 1.0/this->ReductionFactor < this->MinimumImageSampleDistance )
04127 {
04128 this->ReductionFactor = 1.0 / this->MinimumImageSampleDistance;
04129 }
04130 }
04131 }
04132 else
04133 {
04134 this->ReductionFactor = 1.0;
04135 }
04136
04137 assert("post: valid_new_reduction_range" && this->ReductionFactor>0.0
04138 && this->ReductionFactor<=1.0);
04139 }
04140
04141
04142
04143
04144
04145
04146
04147
04148
04149
04150
04151
04152
04153 void vtkMitkOpenGLGPUVolumeRayCastMapper::PreRender(vtkRenderer *ren,
04154 vtkVolume *vol,
04155 double datasetBounds[6],
04156 double scalarRange[2],
04157 int numberOfScalarComponents,
04158 unsigned int numberOfLevels)
04159 {
04160
04161 ren->GetRenderWindow()->MakeCurrent();
04162
04163
04164
04165 if(!this->LoadExtensionsSucceeded)
04166 {
04167 this->LoadExtensions(ren->GetRenderWindow());
04168 }
04169
04170
04171
04172 if(!this->LoadExtensionsSucceeded)
04173 {
04174 vtkErrorMacro(
04175 "Rendering failed because the following OpenGL extensions "
04176 "are required but not supported: " <<
04177 (this->UnsupportedRequiredExtensions->Stream.str()).c_str());
04178 return;
04179 }
04180
04181
04182 this->CreateOpenGLObjects();
04183
04184
04185
04186 this->ComputeReductionFactor(vol->GetAllocatedRenderTime());
04187
04188
04189 if(!this->AllocateFrameBuffers(ren))
04190 {
04191 vtkErrorMacro("Not enough GPU memory to create a framebuffer.");
04192 return;
04193 }
04194
04195
04196
04197 this->TableRange[0]=scalarRange[0];
04198 this->TableRange[1]=scalarRange[1];
04199
04200
04201 if(this->RGBTable==0)
04202 {
04203 this->RGBTable=new vtkRGBTable;
04204 }
04205
04206 if(this->MaskInput!=0)
04207 {
04208 if(this->Mask1RGBTable==0)
04209 {
04210 this->Mask1RGBTable=new vtkRGBTable;
04211 }
04212 if(this->Mask2RGBTable==0)
04213 {
04214 this->Mask2RGBTable=new vtkRGBTable;
04215 }
04216 }
04217
04218
04219 this->UpdateColorTransferFunction(vol,numberOfScalarComponents);
04220
04221
04222
04223 this->UpdateNoiseTexture();
04224
04225
04226
04227 glPushAttrib(GL_COLOR_BUFFER_BIT);
04228
04229
04230
04231 if ( this->GeneratingCanonicalView )
04232 {
04233 glClearColor(0.0, 0.0, 0.0, 0.0);
04234 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
04235 }
04236
04237
04238 vtkMatrix4x4 *m=vol->GetMatrix();
04239 double det=vtkMath::Determinant3x3(
04240 m->GetElement(0,0),m->GetElement(0,1),m->GetElement(0,2),
04241 m->GetElement(1,0),m->GetElement(1,1),m->GetElement(1,2),
04242 m->GetElement(2,0),m->GetElement(2,1),m->GetElement(2,2));
04243
04244 this->PreserveOrientation=det>0;
04245
04246
04247
04248 if(this->ClippingPlanes && this->ClippingPlanes->GetNumberOfItems()!=0)
04249 {
04250
04251
04252 glMatrixMode(GL_MODELVIEW);
04253 glPushMatrix();
04254 this->TempMatrix[0]->DeepCopy(vol->GetMatrix());
04255 this->TempMatrix[0]->Transpose();
04256 glMultMatrixd(this->TempMatrix[0]->Element[0]);
04257 this->ClipBoundingBox(ren,datasetBounds,vol);
04258 glEnable (GL_CULL_FACE);
04259 glCullFace (GL_FRONT);
04260 glColorMask(GL_FALSE,GL_FALSE,GL_FALSE,GL_FALSE);
04261 this->RenderClippedBoundingBox(0,0,1,ren->GetRenderWindow());
04262 glDisable (GL_CULL_FACE);
04263 glColorMask(GL_TRUE,GL_TRUE,GL_TRUE,GL_TRUE);
04264
04265 glPopMatrix();
04266 }
04267
04268 this->CheckFrameBufferStatus();
04269
04270
04271
04272 int size[2];
04273 int lowerLeft[2];
04274 ren->GetTiledSizeAndOrigin(size,size+1,lowerLeft,lowerLeft+1);
04275
04276 vtkgl::ActiveTexture( vtkgl::TEXTURE3 );
04277 glBindTexture(GL_TEXTURE_2D,
04278 static_cast<GLuint>(
04279 this->TextureObjects[
04280 vtkMitkOpenGLGPUVolumeRayCastMapperTextureObjectDepthMap]));
04281 glCopyTexSubImage2D(GL_TEXTURE_2D,0,0,0,lowerLeft[0],lowerLeft[1],size[0],
04282 size[1]);
04283
04284
04285 vtkgl::ActiveTexture( vtkgl::TEXTURE0 );
04286
04287 int parallelProjection=ren->GetActiveCamera()->GetParallelProjection();
04288
04289
04290 int rayCastMethod=vtkMitkOpenGLGPUVolumeRayCastMapperMethodMIP;
04291 int shadeMethod=vtkMitkOpenGLGPUVolumeRayCastMapperShadeNotUsed;
04292 int componentMethod=vtkMitkOpenGLGPUVolumeRayCastMapperComponentNotUsed;
04293
04294 switch(this->BlendMode)
04295 {
04296 case vtkVolumeMapper::COMPOSITE_BLEND:
04297 switch(numberOfScalarComponents)
04298 {
04299 case 1:
04300 componentMethod=vtkMitkOpenGLGPUVolumeRayCastMapperComponentOne;
04301 break;
04302 case 4:
04303 componentMethod=vtkMitkOpenGLGPUVolumeRayCastMapperComponentFour;
04304 break;
04305 default:
04306 assert("check: impossible case" && false);
04307 break;
04308 }
04309 if(this->MaskInput!=0)
04310 {
04311 rayCastMethod=
04312 vtkMitkOpenGLGPUVolumeRayCastMapperMethodCompositeMask;
04313 }
04314 else
04315 {
04316
04317 rayCastMethod=vtkMitkOpenGLGPUVolumeRayCastMapperMethodComposite;
04318 }
04319 if ( vol->GetProperty()->GetShade() )
04320 {
04321 shadeMethod=vtkMitkOpenGLGPUVolumeRayCastMapperShadeYes;
04322 assert("check: only_1_component_todo" && numberOfScalarComponents==1);
04323 }
04324 else
04325 {
04326 shadeMethod=vtkMitkOpenGLGPUVolumeRayCastMapperShadeNo;
04327
04328 }
04329 break;
04330 case vtkVolumeMapper::MAXIMUM_INTENSITY_BLEND:
04331 shadeMethod=vtkMitkOpenGLGPUVolumeRayCastMapperShadeNotUsed;
04332 componentMethod=vtkMitkOpenGLGPUVolumeRayCastMapperComponentNotUsed;
04333 switch(numberOfScalarComponents)
04334 {
04335 case 1:
04336 rayCastMethod=vtkMitkOpenGLGPUVolumeRayCastMapperMethodMIP;
04337 break;
04338 case 4:
04339 rayCastMethod=
04340 vtkMitkOpenGLGPUVolumeRayCastMapperMethodMIPFourDependent;
04341 break;
04342 default:
04343 assert("check: impossible case" && false);
04344 break;
04345 }
04346 break;
04347 case vtkMitkGPUVolumeRayCastMapper::MINIMUM_INTENSITY_BLEND:
04348 shadeMethod=vtkMitkOpenGLGPUVolumeRayCastMapperShadeNotUsed;
04349 componentMethod=vtkMitkOpenGLGPUVolumeRayCastMapperComponentNotUsed;
04350 switch(numberOfScalarComponents)
04351 {
04352 case 1:
04353 rayCastMethod=vtkMitkOpenGLGPUVolumeRayCastMapperMethodMinIP;
04354 break;
04355 case 4:
04356 rayCastMethod=
04357 vtkMitkOpenGLGPUVolumeRayCastMapperMethodMinIPFourDependent;
04358 break;
04359 default:
04360 assert("check: impossible case" && false);
04361 break;
04362 }
04363 break;
04364 default:
04365 assert("check: impossible case" && 0);
04366 rayCastMethod=0;
04367 break;
04368 }
04369
04370 this->ComputeNumberOfCroppingRegions();
04371 if(this->AMRMode)
04372 {
04373 NumberOfCroppingRegions=2;
04374 }
04375 this->BuildProgram(parallelProjection,rayCastMethod,shadeMethod,
04376 componentMethod);
04377 this->CheckLinkage(this->ProgramShader);
04378
04379 vtkgl::UseProgram(this->ProgramShader);
04380
04381
04382
04383 if(numberOfScalarComponents==1)
04384 {
04385
04386 vtkgl::ActiveTexture(vtkgl::TEXTURE1);
04387 this->RGBTable->Bind();
04388
04389 if(this->MaskInput!=0)
04390 {
04391 vtkgl::ActiveTexture(vtkgl::TEXTURE8);
04392 this->Mask1RGBTable->Bind();
04393 vtkgl::ActiveTexture(vtkgl::TEXTURE9);
04394 this->Mask2RGBTable->Bind();
04395 }
04396 }
04397
04398 GLint uDataSetTexture;
04399
04400 uDataSetTexture=vtkgl::GetUniformLocation(
04401 static_cast<GLuint>(this->ProgramShader),"dataSetTexture");
04402
04403 if(uDataSetTexture!=-1)
04404 {
04405 vtkgl::Uniform1i(uDataSetTexture,0);
04406 }
04407 else
04408 {
04409 vtkErrorMacro(<<"dataSetTexture is not a uniform variable.");
04410 }
04411
04412 if ( this->MaskInput)
04413 {
04414
04415 GLint uMaskTexture;
04416
04417 uMaskTexture=vtkgl::GetUniformLocation(
04418 static_cast<GLuint>(this->ProgramShader),"maskTexture");
04419
04420 if(uMaskTexture!=-1)
04421 {
04422 vtkgl::Uniform1i(uMaskTexture,7);
04423 }
04424 else
04425 {
04426 vtkErrorMacro(<<"maskTexture is not a uniform variable.");
04427 }
04428 }
04429
04430 if(numberOfScalarComponents==1)
04431 {
04432 GLint uColorTexture;
04433 uColorTexture=vtkgl::GetUniformLocation(
04434 static_cast<GLuint>(this->ProgramShader),"colorTexture");
04435
04436 if(uColorTexture!=-1)
04437 {
04438 vtkgl::Uniform1i(uColorTexture,1);
04439 }
04440 else
04441 {
04442 vtkErrorMacro(<<"colorTexture is not a uniform variable.");
04443 }
04444
04445 if(this->MaskInput!=0)
04446 {
04447 GLint uMask1ColorTexture;
04448 uMask1ColorTexture=vtkgl::GetUniformLocation(
04449 static_cast<GLuint>(this->ProgramShader),"mask1ColorTexture");
04450
04451 if(uMask1ColorTexture!=-1)
04452 {
04453 vtkgl::Uniform1i(uMask1ColorTexture,8);
04454 }
04455 else
04456 {
04457 vtkErrorMacro(<<"mask1ColorTexture is not a uniform variable.");
04458 }
04459
04460 GLint uMask2ColorTexture;
04461 uMask2ColorTexture=vtkgl::GetUniformLocation(
04462 static_cast<GLuint>(this->ProgramShader),"mask2ColorTexture");
04463
04464 if(uMask2ColorTexture!=-1)
04465 {
04466 vtkgl::Uniform1i(uMask2ColorTexture,9);
04467 }
04468 else
04469 {
04470 vtkErrorMacro(<<"mask2ColorTexture is not a uniform variable.");
04471 }
04472
04473 GLint uMaskBlendFactor;
04474 uMaskBlendFactor=vtkgl::GetUniformLocation(
04475 static_cast<GLuint>(this->ProgramShader),"maskBlendFactor");
04476 if(uMaskBlendFactor!=-1)
04477 {
04478 vtkgl::Uniform1f(uMaskBlendFactor,this->MaskBlendFactor);
04479 }
04480 else
04481 {
04482 vtkErrorMacro(<<"maskBlendFactor is not a uniform variable.");
04483 }
04484 }
04485
04486 }
04487
04488 GLint uOpacityTexture;
04489
04490 uOpacityTexture=vtkgl::GetUniformLocation(
04491 static_cast<GLuint>(this->ProgramShader),"opacityTexture");
04492
04493 if(uOpacityTexture!=-1)
04494 {
04495 vtkgl::Uniform1i(uOpacityTexture,2);
04496 }
04497 else
04498 {
04499 vtkErrorMacro(<<"opacityTexture is not a uniform variable.");
04500 }
04501
04502
04503 vtkgl::ActiveTexture( vtkgl::TEXTURE3 );
04504 glBindTexture(GL_TEXTURE_2D,static_cast<GLuint>(this->TextureObjects[vtkMitkOpenGLGPUVolumeRayCastMapperTextureObjectDepthMap]));
04505
04506 GLint uDepthTexture;
04507
04508 uDepthTexture=vtkgl::GetUniformLocation(
04509 static_cast<GLuint>(this->ProgramShader),"depthTexture");
04510
04511 if(uDepthTexture!=-1)
04512 {
04513 vtkgl::Uniform1i(uDepthTexture,3);
04514 }
04515 else
04516 {
04517 vtkErrorMacro(<<"depthTexture is not a uniform variable.");
04518 }
04519
04520
04521 vtkgl::ActiveTexture( vtkgl::TEXTURE6 );
04522 glBindTexture(GL_TEXTURE_2D,static_cast<GLuint>(this->NoiseTextureId));
04523
04524
04525 GLint uNoiseTexture;
04526
04527 uNoiseTexture=vtkgl::GetUniformLocation(
04528 static_cast<GLuint>(this->ProgramShader),"noiseTexture");
04529
04530 if(uNoiseTexture!=-1)
04531 {
04532 vtkgl::Uniform1i(uNoiseTexture,6);
04533 }
04534 else
04535 {
04536 vtkErrorMacro(<<"noiseTexture is not a uniform variable.");
04537 }
04538
04539 this->CheckFrameBufferStatus();
04540
04541 if(this->NumberOfCroppingRegions>1)
04542 {
04543
04544 if(rayCastMethod!=vtkMitkOpenGLGPUVolumeRayCastMapperMethodMIP && rayCastMethod!=vtkMitkOpenGLGPUVolumeRayCastMapperMethodMinIP)
04545 {
04546 vtkgl::ActiveTexture( vtkgl::TEXTURE4 );
04547 glBindTexture(GL_TEXTURE_2D,static_cast<GLuint>(this->TextureObjects[vtkMitkOpenGLGPUVolumeRayCastMapperTextureObjectFrameBufferLeftFront]));
04548
04549 GLint uFrameBufferTexture;
04550
04551 uFrameBufferTexture=vtkgl::GetUniformLocation(
04552 static_cast<GLuint>(this->ProgramShader),"frameBufferTexture");
04553
04554 this->PrintError("framebuffertexture 1");
04555 if(uFrameBufferTexture!=-1)
04556 {
04557 vtkgl::Uniform1i(uFrameBufferTexture,4);
04558 }
04559 else
04560 {
04561 vtkErrorMacro(<<"frameBufferTexture is not a uniform variable.");
04562 }
04563 this->PrintError("framebuffertexture 2");
04564 }
04565
04566 this->CheckFrameBufferStatus();
04567
04568 if(this->BlendMode==vtkVolumeMapper::MAXIMUM_INTENSITY_BLEND
04569 || this->BlendMode==vtkMitkGPUVolumeRayCastMapper::MINIMUM_INTENSITY_BLEND)
04570 {
04571 vtkgl::ActiveTexture( vtkgl::TEXTURE5 );
04572 glBindTexture(GL_TEXTURE_2D,static_cast<GLuint>(this->MaxValueFrameBuffer2));
04573
04574 GLint uScalarBufferTexture;
04575
04576 uScalarBufferTexture=vtkgl::GetUniformLocation(
04577 static_cast<GLuint>(this->ProgramShader),"scalarBufferTexture");
04578
04579 this->PrintError("scalarbuffertexture 1");
04580 if(uScalarBufferTexture!=-1)
04581 {
04582 vtkgl::Uniform1i(uScalarBufferTexture,5);
04583 }
04584 else
04585 {
04586 vtkErrorMacro(<<"scalarBufferTexture is not a uniform variable.");
04587 }
04588 this->PrintError("scalarbuffertexture 2");
04589 }
04590 }
04591 this->CheckFrameBufferStatus();
04592
04593 GLint uWindowLowerLeftCorner;
04594
04595 uWindowLowerLeftCorner=vtkgl::GetUniformLocation(
04596 static_cast<GLuint>(this->ProgramShader),"windowLowerLeftCorner");
04597
04598 if(uWindowLowerLeftCorner!=-1)
04599 {
04600 vtkgl::Uniform2f(uWindowLowerLeftCorner,static_cast<GLfloat>(lowerLeft[0]),
04601 static_cast<GLfloat>(lowerLeft[1]));
04602 }
04603 else
04604 {
04605 vtkErrorMacro(<<"windowLowerLeftCorner is not a uniform variable.");
04606 }
04607 GLint uInvOriginalWindowSize;
04608
04609 uInvOriginalWindowSize=vtkgl::GetUniformLocation(
04610 static_cast<GLuint>(this->ProgramShader),"invOriginalWindowSize");
04611
04612 if(uInvOriginalWindowSize!=-1)
04613 {
04614 vtkgl::Uniform2f(uInvOriginalWindowSize,
04615 static_cast<GLfloat>(1.0/size[0]),
04616 static_cast<GLfloat>(1.0/size[1]));
04617 }
04618 else
04619 {
04620
04621
04622
04623 vtkDebugMacro(
04624 <<"invOriginalWindowSize is not an active uniform variable.");
04625 }
04626
04627 size[0] = static_cast<int>(size[0]*this->ReductionFactor);
04628 size[1] = static_cast<int>(size[1]*this->ReductionFactor);
04629
04630 GLint uInvWindowSize;
04631
04632 uInvWindowSize=vtkgl::GetUniformLocation(
04633 static_cast<GLuint>(this->ProgramShader),"invWindowSize");
04634
04635 if(uInvWindowSize!=-1)
04636 {
04637 vtkgl::Uniform2f(uInvWindowSize,static_cast<GLfloat>(1.0/size[0]),
04638 static_cast<GLfloat>(1.0/size[1]));
04639 }
04640 else
04641 {
04642 vtkErrorMacro(<<"invWindowSize is not a uniform variable.");
04643 }
04644
04645
04646 this->PrintError("after uniforms for textures");
04647
04648
04649 this->CheckFrameBufferStatus();
04650
04651 GLint savedFrameBuffer;
04652 glGetIntegerv(vtkgl::FRAMEBUFFER_BINDING_EXT,&savedFrameBuffer);
04653 this->SavedFrameBuffer=static_cast<unsigned int>(savedFrameBuffer);
04654
04655 vtkgl::BindFramebufferEXT(vtkgl::FRAMEBUFFER_EXT,
04656 static_cast<GLuint>(this->FrameBufferObject));
04657
04658 GLenum buffer[4];
04659 buffer[0] = vtkgl::COLOR_ATTACHMENT0_EXT;
04660 if(this->NumberOfCroppingRegions>1 &&
04661 this->BlendMode==vtkVolumeMapper::MAXIMUM_INTENSITY_BLEND)
04662 {
04663
04664 buffer[1] = vtkgl::COLOR_ATTACHMENT1_EXT;
04665 }
04666 else
04667 {
04668 buffer[1] = GL_NONE;
04669 }
04670
04671 vtkgl::DrawBuffers(2,buffer);
04672
04673 this->CheckFrameBufferStatus();
04674
04675
04676 double shininess=vol->GetProperty()->GetSpecularPower();
04677 if(shininess>128.0)
04678 {
04679 shininess=128.0;
04680 }
04681 glMaterialf(GL_FRONT_AND_BACK,GL_SHININESS,static_cast<GLfloat>(shininess));
04682
04683 glDisable(GL_COLOR_MATERIAL);
04684
04685 GLfloat values[4];
04686 values[3]=1.0;
04687
04688 values[0]=0.0;
04689 values[1]=values[0];
04690 values[2]=values[0];
04691 glMaterialfv(GL_FRONT_AND_BACK,GL_EMISSION,values);
04692
04693 values[0]=static_cast<float>(vol->GetProperty()->GetAmbient());
04694 values[1]=values[0];
04695 values[2]=values[0];
04696 glMaterialfv(GL_FRONT_AND_BACK,GL_AMBIENT,values);
04697
04698 values[0]=static_cast<float>(vol->GetProperty()->GetDiffuse());
04699 values[1]=values[0];
04700 values[2]=values[0];
04701 glMaterialfv(GL_FRONT_AND_BACK,GL_DIFFUSE,values);
04702 values[0]=static_cast<float>(vol->GetProperty()->GetSpecular());
04703 values[1]=values[0];
04704 values[2]=values[0];
04705 glMaterialfv(GL_FRONT_AND_BACK,GL_SPECULAR,values);
04706
04707
04708
04709
04710 vtkgl::FramebufferTexture2DEXT(vtkgl::FRAMEBUFFER_EXT,
04711 vtkgl::COLOR_ATTACHMENT0_EXT,
04712 GL_TEXTURE_2D,
04713 this->TextureObjects[vtkMitkOpenGLGPUVolumeRayCastMapperTextureObjectFrameBufferLeftFront],
04714 0);
04715
04716 vtkgl::FramebufferTexture2DEXT(vtkgl::FRAMEBUFFER_EXT,
04717 vtkgl::COLOR_ATTACHMENT0_EXT+1,
04718 GL_TEXTURE_2D,
04719 this->TextureObjects[vtkMitkOpenGLGPUVolumeRayCastMapperTextureObjectFrameBufferLeftFront+1],
04720 0);
04721 buffer[0] = vtkgl::COLOR_ATTACHMENT0_EXT;
04722 buffer[1] = vtkgl::COLOR_ATTACHMENT1_EXT;
04723 vtkgl::DrawBuffers(2,buffer);
04724
04725
04726 this->CheckFrameBufferStatus();
04727 this->SetupRender(ren,vol);
04728
04729
04730 buffer[0] = vtkgl::COLOR_ATTACHMENT0_EXT;
04731 buffer[1] = GL_NONE;
04732 vtkgl::DrawBuffers(2,buffer);
04733 vtkgl::FramebufferTexture2DEXT(vtkgl::FRAMEBUFFER_EXT,
04734 vtkgl::COLOR_ATTACHMENT0_EXT+1,
04735 GL_TEXTURE_2D,0,0);
04736
04737 this->CheckFrameBufferStatus();
04738
04739 if(this->NumberOfCroppingRegions>1 &&
04740 (this->BlendMode==vtkMitkGPUVolumeRayCastMapper::MINIMUM_INTENSITY_BLEND
04741 || this->BlendMode==vtkMitkGPUVolumeRayCastMapper::MAXIMUM_INTENSITY_BLEND))
04742 {
04743
04744
04745
04746 vtkgl::FramebufferTexture2DEXT(vtkgl::FRAMEBUFFER_EXT,
04747 vtkgl::COLOR_ATTACHMENT0_EXT,
04748 GL_TEXTURE_2D,
04749 this->MaxValueFrameBuffer,0);
04750
04751 vtkgl::FramebufferTexture2DEXT(vtkgl::FRAMEBUFFER_EXT,
04752 vtkgl::COLOR_ATTACHMENT0_EXT+1,
04753 GL_TEXTURE_2D,
04754 this->MaxValueFrameBuffer2,0);
04755
04756 buffer[0] = vtkgl::COLOR_ATTACHMENT0_EXT;
04757 buffer[1] = vtkgl::COLOR_ATTACHMENT1_EXT;
04758 vtkgl::DrawBuffers(2,buffer);
04759
04760 if(this->BlendMode==vtkMitkGPUVolumeRayCastMapper::MINIMUM_INTENSITY_BLEND)
04761 {
04762 glClearColor(1.0, 0.0, 0.0, 0.0);
04763 }
04764 else
04765 {
04766 glClearColor(0.0, 0.0, 0.0, 0.0);
04767 }
04768
04769 this->CheckFrameBufferStatus();
04770 glClear(GL_COLOR_BUFFER_BIT);
04771 }
04772
04773 if(this->NumberOfCroppingRegions>1)
04774 {
04775
04776 vtkgl::FramebufferTexture2DEXT(vtkgl::FRAMEBUFFER_EXT,
04777 vtkgl::COLOR_ATTACHMENT0_EXT,
04778 GL_TEXTURE_2D,
04779 this->TextureObjects[vtkMitkOpenGLGPUVolumeRayCastMapperTextureObjectFrameBufferLeftFront],
04780 0);
04781
04782
04783 vtkgl::ActiveTexture(vtkgl::TEXTURE4);
04784 glBindTexture(GL_TEXTURE_2D,this->TextureObjects[vtkMitkOpenGLGPUVolumeRayCastMapperTextureObjectFrameBufferLeftFront+1]);
04785
04786 if(this->BlendMode==vtkVolumeMapper::MAXIMUM_INTENSITY_BLEND
04787 || this->BlendMode==vtkMitkGPUVolumeRayCastMapper::MINIMUM_INTENSITY_BLEND)
04788 {
04789
04790 vtkgl::FramebufferTexture2DEXT(vtkgl::FRAMEBUFFER_EXT,
04791 vtkgl::COLOR_ATTACHMENT0_EXT+1,
04792 GL_TEXTURE_2D,
04793 this->MaxValueFrameBuffer,0);
04794
04795
04796 vtkgl::ActiveTexture(vtkgl::TEXTURE5);
04797 glBindTexture(GL_TEXTURE_2D,this->MaxValueFrameBuffer2);
04798 }
04799 vtkgl::ActiveTexture(vtkgl::TEXTURE0);
04800 }
04801
04802 this->CheckFrameBufferStatus();
04803
04804 if(this->OpacityTables!=0 &&
04805 this->OpacityTables->Vector.size()!=numberOfLevels)
04806 {
04807 delete this->OpacityTables;
04808 this->OpacityTables=0;
04809 }
04810 if(this->OpacityTables==0)
04811 {
04812 this->OpacityTables=new vtkOpacityTables(numberOfLevels);
04813 }
04814
04815
04816
04817
04818
04819 glCullFace (GL_BACK);
04820
04821
04822
04823 if(!this->GeneratingCanonicalView && this->ReportProgress)
04824 {
04825
04826 this->LastProgressEventTime=vtkTimerLog::GetUniversalTime();
04827 }
04828
04829 this->PrintError("PreRender end");
04830 }
04831
04832
04833
04834
04835
04836
04837
04838 double vtkMitkOpenGLGPUVolumeRayCastMapper::ComputeMinimalSampleDistancePerPixel(
04839 vtkRenderer *renderer,
04840 vtkVolume *volume)
04841 {
04842
04843
04844
04845
04846
04847
04848
04849
04850 this->IgnoreSampleDistancePerPixel=true;
04851 double result=0.0;
04852
04853 vtkMatrix4x4 *worldToDataset=volume->GetMatrix();
04854 vtkCamera *camera=renderer->GetActiveCamera();
04855 vtkMatrix4x4 *eyeToWorld=camera->GetViewTransformMatrix();
04856 vtkMatrix4x4 *eyeToDataset=vtkMatrix4x4::New();
04857 vtkMatrix4x4::Multiply4x4(eyeToWorld,worldToDataset,eyeToDataset);
04858
04859 int usize;
04860 int vsize;
04861 renderer->GetTiledSize(&usize,&vsize);
04862 vtkMatrix4x4 *viewportToEye=camera->GetProjectionTransformMatrix(
04863 usize/static_cast<double>(vsize),0.0,1.0);
04864
04865 double volBounds[6];
04866 this->GetInput()->GetBounds(volBounds);
04867 int dims[3];
04868 this->GetInput()->GetDimensions(dims);
04869
04870 double v0[4];
04871 v0[0]=volBounds[0];
04872 v0[1]=volBounds[2];
04873 v0[2]=volBounds[4];
04874 v0[3]=1.0;
04875
04876 double w0[4];
04877 eyeToDataset->MultiplyPoint(v0,w0);
04878
04879 double z0;
04880
04881 if(w0[3]!=0.0)
04882 {
04883 z0=w0[2]/w0[3];
04884 }
04885 else
04886 {
04887 z0=0.0;
04888 vtkGenericWarningMacro( "eyeToWorld transformation has some projective component." );
04889 }
04890
04891 double p0[4];
04892 viewportToEye->MultiplyPoint(w0,p0);
04893 p0[0]/=p0[3];
04894 p0[1]/=p0[3];
04895 p0[2]/=p0[3];
04896
04897 bool inFrustum=p0[0]>=-1.0 && p0[0]<=1.0 && p0[1]>=-1.0 && p0[1]<=1.0 && p0[2]>=-1.0 && p0[2]<=1.0;
04898
04899 if(inFrustum)
04900 {
04901 int dim=0;
04902 while(dim<3)
04903 {
04904 double v1[4];
04905 int coord=0;
04906 while(coord<3)
04907 {
04908 if(coord==dim)
04909 {
04910 v1[coord]=volBounds[2*coord+1];
04911 }
04912 else
04913 {
04914 v1[coord]=volBounds[2*coord];
04915 }
04916 ++coord;
04917 }
04918 v1[3]=1.0;
04919
04920 double w1[4];
04921 eyeToDataset->MultiplyPoint(v1,w1);
04922 double z1;
04923
04924 if(w1[3]!=0.0)
04925 {
04926 z1=w1[2]/w1[3];
04927 }
04928 else
04929 {
04930 z1=0.0;
04931 vtkGenericWarningMacro( "eyeToWorld transformation has some projective component." );
04932 }
04933
04934
04935 double p1[4];
04936 viewportToEye->MultiplyPoint(w1,p1);
04937 p1[0]/=p1[3];
04938 p1[1]/=p1[3];
04939 p1[2]/=p1[3];
04940
04941 inFrustum=p1[0]>=-1.0 && p1[0]<=1.0 && p1[1]>=-1.0 && p1[1]<=1.0 && p1[2]>=-1.0 && p1[2]<=1.0;
04942
04943 if(inFrustum)
04944 {
04945 double dx=fabs(p1[0]-p0[0]);
04946 double dy=fabs(p1[1]-p0[1]);
04947 double dz=fabs(z1-z0);
04948 dz=dz/(dims[dim]-1);
04949 dx=dx/(dims[dim]-1)*usize;
04950 dy=dy/(dims[dim]-1)*vsize;
04951
04952 if(dz!=0.0)
04953 {
04954 if(dx!=0.0)
04955 {
04956 double d=dz/dx;
04957 if(!this->IgnoreSampleDistancePerPixel)
04958 {
04959 if(result>d)
04960 {
04961 result=d;
04962 }
04963 }
04964 else
04965 {
04966 this->IgnoreSampleDistancePerPixel=false;
04967 result=d;
04968 }
04969 }
04970
04971 if(dy!=0.0)
04972 {
04973 double d=dz/dy;
04974 if(!this->IgnoreSampleDistancePerPixel)
04975 {
04976 if(result>d)
04977 {
04978 result=d;
04979 }
04980 }
04981 else
04982 {
04983 this->IgnoreSampleDistancePerPixel=false;
04984 result=d;
04985 }
04986 }
04987
04988 }
04989 }
04990 ++dim;
04991 }
04992 }
04993
04994 eyeToDataset->Delete();
04995
04996 if(this->IgnoreSampleDistancePerPixel)
04997 {
04998
04999 }
05000 else
05001 {
05002
05003 }
05004
05005 return result;
05006 }
05007
05008
05009
05010
05011 void vtkMitkOpenGLGPUVolumeRayCastMapper::RenderBlock(vtkRenderer *ren,
05012 vtkVolume *vol,
05013 unsigned int level)
05014 {
05015 vtkImageData *input = this->GetInput();
05016
05017 if(!this->AutoAdjustSampleDistances)
05018 {
05019 this->ActualSampleDistance=this->SampleDistance;
05020 }
05021 else
05022 {
05023 double datasetSpacing[3];
05024
05025
05026 input->GetSpacing(datasetSpacing);
05027
05028 vtkMatrix4x4 *worldToDataset=vol->GetMatrix();
05029
05030 double minWorldSpacing=VTK_DOUBLE_MAX;
05031 int i=0;
05032 while(i<3)
05033 {
05034 double tmp=worldToDataset->GetElement(0,i);
05035 double tmp2=tmp*tmp;
05036 tmp=worldToDataset->GetElement(1,i);
05037 tmp2+=tmp*tmp;
05038 tmp=worldToDataset->GetElement(2,i);
05039 double worldSpacing=datasetSpacing[i]*sqrt(tmp2+tmp*tmp);
05040 if(worldSpacing<minWorldSpacing)
05041 {
05042 minWorldSpacing=worldSpacing;
05043 }
05044 ++i;
05045 }
05046
05047
05048
05049
05050 this->ActualSampleDistance=static_cast<float>(minWorldSpacing);
05051
05052 if ( this->ReductionFactor < 1.0 )
05053 {
05054 this->ActualSampleDistance /= static_cast<GLfloat>(this->ReductionFactor*0.5);
05055 }
05056 }
05057
05058
05059
05060
05061
05062 vtkDataArray *scalars=this->GetScalars(input,this->ScalarMode,
05063 this->ArrayAccessMode,
05064 this->ArrayId,
05065 this->ArrayName,
05066 this->CellFlag);
05067
05068 this->UpdateOpacityTransferFunction(vol,
05069 scalars->GetNumberOfComponents(),
05070 level);
05071
05072
05073 vtkgl::ActiveTexture(vtkgl::TEXTURE2);
05074 this->OpacityTables->Vector[level].Bind();
05075 vtkgl::ActiveTexture(vtkgl::TEXTURE0);
05076
05077 this->PrintError("after uniforms for projection and shade");
05078
05079
05080
05081
05082
05083 this->PrintError("before render");
05084 if(!this->Cropping)
05085 {
05086 this->RenderWholeVolume(ren,vol);
05087 }
05088 else
05089 {
05090 this->ClipCroppingRegionPlanes();
05091 this->RenderRegions(ren,vol);
05092 }
05093 this->PrintError("after render");
05094 }
05095
05096
05097
05098
05099 void vtkMitkOpenGLGPUVolumeRayCastMapper::PostRender(
05100 vtkRenderer *ren,
05101 int numberOfScalarComponents)
05102 {
05103 this->PrintError("PostRender1");
05104 if(this->NumberOfCroppingRegions>1)
05105 {
05106 if(this->BlendMode==vtkVolumeMapper::MAXIMUM_INTENSITY_BLEND
05107 || this->BlendMode==vtkMitkGPUVolumeRayCastMapper::MINIMUM_INTENSITY_BLEND)
05108 {
05109 vtkgl::ActiveTexture( vtkgl::TEXTURE5 );
05110 glBindTexture(GL_TEXTURE_2D,0);
05111 }
05112
05113 if(this->LastRayCastMethod!=vtkMitkOpenGLGPUVolumeRayCastMapperMethodMIP
05114 && this->LastRayCastMethod!=vtkMitkOpenGLGPUVolumeRayCastMapperMethodMinIP)
05115 {
05116 vtkgl::ActiveTexture( vtkgl::TEXTURE4 );
05117 glBindTexture(GL_TEXTURE_2D,0);
05118 }
05119 }
05120
05121
05122 vtkgl::ActiveTexture(vtkgl::TEXTURE6);
05123 glBindTexture(GL_TEXTURE_2D,0);
05124
05125
05126 vtkgl::ActiveTexture(vtkgl::TEXTURE3);
05127 glBindTexture(GL_TEXTURE_2D,0);
05128
05129
05130 vtkgl::ActiveTexture(vtkgl::TEXTURE2);
05131 glBindTexture(GL_TEXTURE_1D,0);
05132
05133 if(numberOfScalarComponents==1)
05134 {
05135 vtkgl::ActiveTexture(vtkgl::TEXTURE1);
05136 glBindTexture(GL_TEXTURE_1D,0);
05137 }
05138
05139
05140
05141 if(this->MaskInput!=0)
05142 {
05143 vtkgl::ActiveTexture(vtkgl::TEXTURE7);
05144 glBindTexture(vtkgl::TEXTURE_3D_EXT,0);
05145 }
05146
05147
05148 vtkgl::ActiveTexture(vtkgl::TEXTURE0);
05149 glBindTexture(vtkgl::TEXTURE_3D_EXT,0);
05150
05151 vtkgl::UseProgram(0);
05152
05153 this->PrintError("after UseProgram(0)");
05154
05155 this->CleanupRender();
05156 this->PrintError("after CleanupRender");
05157
05158 vtkgl::BindFramebufferEXT(vtkgl::FRAMEBUFFER_EXT,
05159 static_cast<GLuint>(this->SavedFrameBuffer));
05160 this->SavedFrameBuffer=0;
05161
05162
05163 int size[2];
05164 int lowerLeft[2];
05165 ren->GetTiledSizeAndOrigin(size,size+1,lowerLeft,lowerLeft+1);
05166 glViewport(lowerLeft[0],lowerLeft[1], size[0], size[1]);
05167 glEnable( GL_SCISSOR_TEST );
05168 glScissor(lowerLeft[0],lowerLeft[1], size[0], size[1]);
05169
05170
05171
05172 this->RenderTextureToScreen(ren);
05173 this->PrintError("after RenderTextureToScreen");
05174
05175 glEnable(GL_DEPTH_TEST);
05176
05177 glPopAttrib();
05178
05179 glFinish();
05180
05181 this->PrintError("PostRender2");
05182 }
05183
05184
05185
05186
05187 void vtkMitkOpenGLGPUVolumeRayCastMapper::GPURender(vtkRenderer *ren,
05188 vtkVolume *vol)
05189 {
05190
05191 vtkImageData *input = this->GetTransformedInput();
05192
05193
05194 double bounds[6];
05195 this->GetBounds(bounds);
05196
05197
05198 double range[2];
05199 vtkDataArray *scalars=this->GetScalars(input,this->ScalarMode,
05200 this->ArrayAccessMode,
05201 this->ArrayId,this->ArrayName,
05202 this->CellFlag);
05203
05204
05205 int numberOfScalarComponents=scalars->GetNumberOfComponents();
05206
05207
05208 if(numberOfScalarComponents==1)
05209 {
05210
05211 scalars->GetRange(range);
05212 }
05213
05214
05215
05216 else
05217 {
05218
05219
05220 scalars->GetRange(range,3);
05221 }
05222
05223
05224
05225
05226
05227
05228
05229 this->PreRender(ren,vol,bounds,range,numberOfScalarComponents,1);
05230
05231 if(!this->OpacityTables)
05232 this->PreRender(ren,vol,bounds,range,numberOfScalarComponents,1);
05233
05234 if(this->LoadExtensionsSucceeded)
05235 {
05236 this->RenderBlock(ren,vol,0);
05237 this->PostRender(ren,numberOfScalarComponents);
05238 }
05239
05240
05241 this->PrintError("End GPU Render");
05242
05243
05244
05245 if (!this->GeneratingCanonicalView )
05246 {
05247 double progress=1.0;
05248 this->InvokeEvent(vtkCommand::VolumeMapperRenderProgressEvent,&progress);
05249 ren->GetRenderWindow()->MakeCurrent();
05250 }
05251 }
05252
05253
05254
05255
05256
05257
05258 void vtkMitkOpenGLGPUVolumeRayCastMapper::RenderWholeVolume(vtkRenderer *ren,
05259 vtkVolume *vol)
05260 {
05261 double volBounds[6];
05262 this->GetTransformedInput()->GetBounds(volBounds);
05263 this->RenderSubVolume(ren,volBounds,vol);
05264 }
05265
05266
05267
05268
05269
05270 class vtkRegionDistance2
05271 {
05272 public:
05273 size_t Id;
05274
05275 double Distance2;
05276 };
05277
05278
05279
05280
05281 extern "C" int vtkRegionComparisonFunction(const void *x,
05282 const void *y)
05283 {
05284 double dx=static_cast<const vtkRegionDistance2 *>(x)->Distance2;
05285 double dy=static_cast<const vtkRegionDistance2 *>(y)->Distance2;
05286
05287 int result;
05288 if(dx<dy)
05289 {
05290 result=-1;
05291 }
05292 else
05293 {
05294 if(dx>dy)
05295 {
05296 result=1;
05297 }
05298 else
05299 {
05300 result=0;
05301 }
05302 }
05303 return result;
05304 }
05305
05306
05307
05308
05309
05310 void vtkMitkOpenGLGPUVolumeRayCastMapper::RenderRegions(vtkRenderer *ren,
05311 vtkVolume *vol)
05312 {
05313 double bounds[27][6];
05314 double distance2[27];
05315
05316 double camPos[4];
05317 ren->GetActiveCamera()->GetPosition(camPos);
05318
05319 double volBounds[6];
05320 this->GetInput()->GetBounds(volBounds);
05321
05322
05323
05324
05325 vol->GetMatrix( this->InvVolumeMatrix );
05326 camPos[3] = 1.0;
05327 this->InvVolumeMatrix->Invert();
05328 this->InvVolumeMatrix->MultiplyPoint( camPos, camPos );
05329 if ( camPos[3] )
05330 {
05331 camPos[0] /= camPos[3];
05332 camPos[1] /= camPos[3];
05333 camPos[2] /= camPos[3];
05334 }
05335
05336
05337
05338
05339
05340 double limit[12];
05341 size_t i;
05342 for ( i = 0; i < 3; i++ )
05343 {
05344 limit[i*4 ] = volBounds[i*2];
05345 limit[i*4+1] = this->ClippedCroppingRegionPlanes[i*2];
05346 limit[i*4+2] = this->ClippedCroppingRegionPlanes[i*2+1];
05347 limit[i*4+3] = volBounds[i*2+1];
05348 }
05349
05350
05351
05352
05353 size_t numRegions = 0;
05354 size_t region;
05355 for ( region = 0; region < 27; region++ )
05356 {
05357 int regionFlag = 1<<region;
05358
05359 if ( this->CroppingRegionFlags & regionFlag )
05360 {
05361
05362 size_t loc[3];
05363 loc[0] = region%3;
05364 loc[1] = (region/3)%3;
05365 loc[2] = (region/9)%3;
05366
05367
05368
05369 if((limit[loc[0]]!=limit[loc[0]+1])
05370 && (limit[loc[1]+4]!=limit[loc[1]+5])
05371 && (limit[loc[2]+8]!=limit[loc[2]+9]))
05372 {
05373
05374 double center[3];
05375 for ( i = 0; i < 3; i++ )
05376 {
05377 bounds[numRegions][i*2 ] = limit[4*i+loc[i]];
05378 bounds[numRegions][i*2+1] = limit[4*i+loc[i]+1];
05379 center[i]=(bounds[numRegions][i*2]+bounds[numRegions][i*2+1])*0.5;
05380 }
05381
05382
05383 distance2[numRegions] =
05384 (camPos[0]-center[0])*(camPos[0]-center[0]) +
05385 (camPos[1]-center[1])*(camPos[1]-center[1]) +
05386 (camPos[2]-center[2])*(camPos[2]-center[2]);
05387
05388
05389 numRegions++;
05390 }
05391 }
05392 }
05393 vtkRegionDistance2 regions[27];
05394
05395 i=0;
05396 while(i<numRegions)
05397 {
05398 regions[i].Id=i;
05399 regions[i].Distance2=distance2[i];
05400 ++i;
05401 }
05402 qsort(regions,numRegions,sizeof(vtkRegionDistance2),
05403 vtkRegionComparisonFunction);
05404
05405
05406 int abort=0;
05407 i=0;
05408 while(!abort && i < numRegions)
05409 {
05410
05411 abort=this->RenderSubVolume(ren,bounds[regions[i].Id],vol);
05412 ++i;
05413 }
05414
05415 }
05416
05417
05418
05419
05420
05421 void vtkMitkOpenGLGPUVolumeRayCastMapper::ComputeNumberOfCroppingRegions()
05422 {
05423 this->NumberOfCroppingRegions=0;
05424 if(this->Cropping)
05425 {
05426
05427 for ( int region = 0; region < 27; region++ )
05428 {
05429 int regionFlag = 1<<region;
05430
05431 if ( this->CroppingRegionFlags & regionFlag )
05432 {
05433
05434 ++this->NumberOfCroppingRegions;
05435 }
05436 }
05437 }
05438 this->NumberOfCroppingRegions=2;
05439 assert("post: positive_NumberOfCroppingRegions" &&
05440 this->NumberOfCroppingRegions>=0);
05441 }
05442
05443
05444
05445
05446
05447
05448
05449
05450
05451
05452
05453 void vtkMitkOpenGLGPUVolumeRayCastMapper::SlabsFromDatasetToIndex(
05454 double slabsDataSet[6],
05455 double slabsPoints[6])
05456 {
05457 double *spacing=this->GetInput()->GetSpacing();
05458 double origin[3];
05459
05460
05461 double *bds = this->GetInput()->GetBounds();
05462 origin[0] = bds[0];
05463 origin[1] = bds[2];
05464 origin[2] = bds[4];
05465
05466 int i=0;
05467 while(i<6)
05468 {
05469 slabsPoints[i]=(slabsDataSet[i] - origin[i/2]) / spacing[i/2];
05470 ++i;
05471 }
05472 }
05473
05474
05475
05476
05477
05478
05479
05480
05481
05482
05483
05484 void vtkMitkOpenGLGPUVolumeRayCastMapper::SlabsFromIndexToDataset(
05485 double slabsPoints[6],
05486 double slabsDataSet[6])
05487 {
05488 double *spacing=this->GetInput()->GetSpacing();
05489 double origin[3];
05490
05491
05492 double *bds = this->GetInput()->GetBounds();
05493 origin[0] = bds[0];
05494 origin[1] = bds[2];
05495 origin[2] = bds[4];
05496
05497 int i=0;
05498 while(i<6)
05499 {
05500 slabsDataSet[i]=slabsPoints[i]*spacing[i/2]+origin[i/2];
05501 ++i;
05502 }
05503 }
05504
05505
05506
05507
05508 class vtkStreamBlock
05509 {
05510 public:
05511 double Bounds[6];
05512 double Extent[6];
05513 };
05514
05515
05516
05517
05518
05519 int vtkMitkOpenGLGPUVolumeRayCastMapper::RenderSubVolume(vtkRenderer *ren,
05520 double bounds[6],
05521 vtkVolume *volume)
05522 {
05523
05524 size_t i;
05525 int wholeTextureExtent[6];
05526 this->GetTransformedInput()->GetExtent(wholeTextureExtent);
05527 if(this->CellFlag)
05528 {
05529 i=1;
05530 while(i<6)
05531 {
05532 wholeTextureExtent[i]--;
05533 i+=2;
05534 }
05535 }
05536
05537
05538 double realExtent[6];
05539 int subvolumeTextureExtent[6];
05540
05541 this->SlabsFromDatasetToIndex(bounds,realExtent);
05542
05543 if(this->CellFlag)
05544 {
05545
05546 i=0;
05547 while(i<6)
05548 {
05549 subvolumeTextureExtent[i]=vtkMath::Floor(realExtent[i]-0.5);
05550 ++i;
05551 subvolumeTextureExtent[i]=vtkMath::Floor(realExtent[i]-0.5)+1;
05552 ++i;
05553 }
05554 }
05555 else
05556 {
05557
05558 i=0;
05559 while(i<6)
05560 {
05561 subvolumeTextureExtent[i]=vtkMath::Floor(realExtent[i]);
05562 ++i;
05563 subvolumeTextureExtent[i]=vtkMath::Floor(realExtent[i])+1;
05564 ++i;
05565 }
05566 }
05567
05568 i=0;
05569 while(i<6)
05570 {
05571 assert("check: wholeTextureExtent" && wholeTextureExtent[i]==0);
05572 if(subvolumeTextureExtent[i]<wholeTextureExtent[i])
05573 {
05574 subvolumeTextureExtent[i]=wholeTextureExtent[i];
05575 }
05576 ++i;
05577 if(subvolumeTextureExtent[i]>wholeTextureExtent[i])
05578 {
05579 subvolumeTextureExtent[i]=wholeTextureExtent[i];
05580 }
05581 ++i;
05582 }
05583
05584 assert("check: subvolume_inside_wholevolume" &&
05585 subvolumeTextureExtent[0]>=wholeTextureExtent[0]
05586 && subvolumeTextureExtent[1]<=wholeTextureExtent[1]
05587 && subvolumeTextureExtent[2]>=wholeTextureExtent[2]
05588 && subvolumeTextureExtent[3]<=wholeTextureExtent[3]
05589 && subvolumeTextureExtent[4]>=wholeTextureExtent[4]
05590 && subvolumeTextureExtent[5]<=wholeTextureExtent[5]);
05591
05592
05593
05594
05595
05596
05597 vtkstd::map<vtkImageData *,vtkKWScalarField *>::iterator it=
05598 this->ScalarsTextures->Map.find(this->GetTransformedInput());
05599 vtkKWScalarField *texture;
05600 if(it==this->ScalarsTextures->Map.end())
05601 {
05602 texture=0;
05603 }
05604 else
05605 {
05606 texture=(*it).second;
05607 }
05608
05609 vtkKWMask *mask=0;
05610 if(this->MaskInput!=0)
05611 {
05612 vtkstd::map<vtkImageData *,vtkKWMask *>::iterator it2=
05613 this->MaskTextures->Map.find(this->MaskInput);
05614 if(it2==this->MaskTextures->Map.end())
05615 {
05616 mask=0;
05617 }
05618 else
05619 {
05620 mask=(*it2).second;
05621 }
05622 }
05623
05624 int loaded =
05625 texture!=0 &&
05626 texture->IsLoaded() &&
05627 this->GetTransformedInput()->GetMTime()<=texture->GetBuildTime() &&
05628 (this->GetMaskInput() ? this->GetMaskInput()->GetMTime() <= texture->GetBuildTime() : true) &&
05629 texture->GetLoadedCellFlag()==this->CellFlag;
05630
05631
05632 vtkIdType *loadedExtent;
05633
05634 if(loaded)
05635 {
05636 loadedExtent=texture->GetLoadedExtent();
05637 i=0;
05638 while(loaded && i<6)
05639 {
05640 loaded=loaded && loadedExtent[i]<=subvolumeTextureExtent[i];
05641 ++i;
05642 loaded=loaded && loadedExtent[i]>=subvolumeTextureExtent[i];
05643 ++i;
05644 }
05645 }
05646
05647 if(loaded)
05648 {
05649 this->CurrentScalar=texture;
05650 vtkgl::ActiveTexture(vtkgl::TEXTURE0);
05651 this->CurrentScalar->Bind();
05652
05653 vtkgl::ActiveTexture(vtkgl::TEXTURE7);
05654 this->CurrentMask=mask;
05655 if(this->CurrentMask!=0)
05656 {
05657 this->CurrentMask->Bind();
05658 }
05659 }
05660
05661 if(!loaded)
05662 {
05663
05664 if(!this->LoadScalarField(this->GetTransformedInput(),this->MaskInput,wholeTextureExtent,volume))
05665 {
05666
05667 if(!this->LoadScalarField(this->GetTransformedInput(),this->MaskInput, subvolumeTextureExtent,
05668 volume))
05669 {
05670
05671
05672
05673 int streamTextureExtent[6];
05674 i=0;
05675 while(i<6)
05676 {
05677 streamTextureExtent[i]=subvolumeTextureExtent[i];
05678 ++i;
05679 }
05680
05681 unsigned int internalFormat;
05682 unsigned int format;
05683 unsigned int type;
05684 int componentSize;
05685 this->GetTextureFormat(this->GetInput(),&internalFormat,&format,&type,
05686 &componentSize);
05687
05688
05689 int originalTextureSize[3];
05690 int textureSize[3];
05691 i=0;
05692 while(i<3)
05693 {
05694 textureSize[i]=subvolumeTextureExtent[2*i+1]-subvolumeTextureExtent[2*i]+1;
05695 originalTextureSize[i]=textureSize[i];
05696 ++i;
05697 }
05698
05699
05700
05701 GLint width;
05702 glGetIntegerv(vtkgl::MAX_3D_TEXTURE_SIZE,&width);
05703
05704 int clippedXY=0;
05705 int clippedZ=0;
05706
05707 if(textureSize[0]>width)
05708 {
05709 textureSize[0]=width;
05710 clippedXY=1;
05711 }
05712 if(textureSize[1]>width)
05713 {
05714 textureSize[1]=width;
05715 clippedXY=1;
05716 }
05717 if(textureSize[2]>width)
05718 {
05719 textureSize[2]=width;
05720 clippedZ=1;
05721 }
05722
05723 int minSize;
05724 if(this->CellFlag)
05725 {
05726 minSize=1;
05727 }
05728 else
05729 {
05730 minSize=2;
05731 }
05732
05733 if(clippedXY)
05734 {
05735
05736
05737
05738 bool foundSize=false;
05739 while(!foundSize && textureSize[0]>=minSize
05740 && textureSize[1]>=minSize)
05741 {
05742 foundSize=this->TestLoadingScalar(internalFormat,format,type,
05743 textureSize,componentSize);
05744 if(!foundSize)
05745 {
05746 int maxDim=0;
05747 if(textureSize[1]>textureSize[0])
05748 {
05749 maxDim=1;
05750 }
05751 if(textureSize[2]>textureSize[maxDim])
05752 {
05753 maxDim=2;
05754 }
05755 textureSize[maxDim]>>=1;
05756 }
05757 }
05758 }
05759 else
05760 {
05761
05762
05763
05764
05765
05766
05767
05768
05769 if(!clippedZ)
05770 {
05771
05772
05773 textureSize[2]>>=1;
05774 }
05775
05776 bool foundSize=false;
05777 while(!foundSize && textureSize[2]>=minSize)
05778 {
05779 foundSize=this->TestLoadingScalar(internalFormat,format,type,
05780 textureSize,componentSize);
05781 if(!foundSize)
05782 {
05783 textureSize[2]>>=1;
05784 }
05785 }
05786 if(!foundSize)
05787 {
05788 textureSize[2]=minSize;
05789 if(textureSize[0]>textureSize[1])
05790 {
05791 textureSize[0]>>=1;
05792 }
05793 else
05794 {
05795 textureSize[1]>>=1;
05796 }
05797 while(!foundSize && textureSize[0]>=minSize
05798 && textureSize[1]>=minSize)
05799 {
05800 foundSize=this->TestLoadingScalar(internalFormat,format,type,
05801 textureSize,componentSize);
05802 if(!foundSize)
05803 {
05804 if(textureSize[0]>textureSize[1])
05805 {
05806 textureSize[0]>>=1;
05807 }
05808 else
05809 {
05810 textureSize[1]>>=1;
05811 }
05812 }
05813 }
05814 }
05815 if(!foundSize)
05816 {
05817 vtkErrorMacro(
05818 <<"No memory left on the GPU even for a minimal block.");
05819 return 1;
05820 }
05821 }
05822
05823
05824
05825
05826
05827
05828 double camPos[4];
05829 vtkCamera *cam = ren->GetActiveCamera();
05830 cam->GetPosition(camPos);
05831 volume->GetMatrix( this->InvVolumeMatrix );
05832 camPos[3] = 1.0;
05833 this->InvVolumeMatrix->Invert();
05834 this->InvVolumeMatrix->MultiplyPoint( camPos, camPos );
05835 if ( camPos[3] )
05836 {
05837 camPos[0] /= camPos[3];
05838 camPos[1] /= camPos[3];
05839 camPos[2] /= camPos[3];
05840 }
05841
05842
05843
05844
05845
05846
05847
05848
05849 size_t remainder[3];
05850 i=0;
05851 while(i<3)
05852 {
05853 remainder[i]=static_cast<size_t>(
05854 (originalTextureSize[i]-textureSize[i])%(textureSize[i]-1));
05855 if(remainder[i]>0)
05856 {
05857 remainder[i]=1;
05858 }
05859 ++i;
05860 }
05861
05862 size_t counts[3];
05863
05864 counts[0]=static_cast<size_t>((originalTextureSize[0]-textureSize[0])
05865 /(textureSize[0]-1));
05866 counts[0]+=remainder[0]+1;
05867 counts[1]=static_cast<size_t>((originalTextureSize[1]-textureSize[1])
05868 /(textureSize[1]-1));
05869 counts[1]+=remainder[1]+1;
05870 counts[2]=static_cast<size_t>((originalTextureSize[2]-textureSize[2])
05871 /(textureSize[2]-1));
05872 counts[2]+=remainder[2]+1;
05873
05874 size_t count=counts[0]*counts[1]*counts[2];
05875
05876 double blockExtent[6];
05877 vtkStreamBlock *blocks=new vtkStreamBlock[count];
05878 vtkRegionDistance2 *sortedBlocks=new vtkRegionDistance2[count];
05879
05880
05881 size_t blockId=0;
05882
05883 size_t zIndex=0;
05884 blockExtent[4]=realExtent[4];
05885 blockExtent[5]=vtkMath::Floor(blockExtent[4])+textureSize[2];
05886 if(!this->CellFlag)
05887 {
05888 blockExtent[5]--;
05889 }
05890 if(blockExtent[5]>realExtent[5])
05891 {
05892 blockExtent[5]=realExtent[5];
05893 }
05894 while(zIndex<counts[2])
05895 {
05896
05897 blockExtent[2]=realExtent[2];
05898 blockExtent[3]=vtkMath::Floor(blockExtent[2])+textureSize[1];
05899 if(!this->CellFlag)
05900 {
05901 blockExtent[3]--;
05902 }
05903 if(blockExtent[3]>realExtent[3])
05904 {
05905 blockExtent[3]=realExtent[3];
05906 }
05907 size_t yIndex=0;
05908 while(yIndex<counts[1])
05909 {
05910
05911 blockExtent[0]=realExtent[0];
05912 blockExtent[1]=vtkMath::Floor(blockExtent[0])+textureSize[0];
05913 if(!this->CellFlag)
05914 {
05915 blockExtent[1]--;
05916 }
05917 if(blockExtent[1]>realExtent[1])
05918 {
05919 blockExtent[1]=realExtent[1];
05920 }
05921 size_t xIndex=0;
05922 while(xIndex<counts[0])
05923 {
05924 assert("check: valid_blockId" && blockId<count);
05925
05926 double blockBounds[6];
05927 this->SlabsFromIndexToDataset(blockExtent,blockBounds);
05928
05929
05930 double center[3];
05931 i=0;
05932 while(i<3)
05933 {
05934 center[i]=(blockBounds[i*2]+blockBounds[i*2+1])*0.5;
05935 ++i;
05936 }
05937
05938
05939 double distance2=(camPos[0]-center[0])*(camPos[0]-center[0])+
05940 (camPos[1]-center[1])*(camPos[1]-center[1]) +
05941 (camPos[2]-center[2])*(camPos[2]-center[2]);
05942
05943 i=0;
05944 while(i<6)
05945 {
05946 blocks[blockId].Bounds[i]=blockBounds[i];
05947 blocks[blockId].Extent[i]=blockExtent[i];
05948 ++i;
05949 }
05950
05951 sortedBlocks[blockId].Id=blockId;
05952 sortedBlocks[blockId].Distance2=distance2;
05953
05954 ++blockId;
05955
05956 blockExtent[0]=blockExtent[1];
05957 blockExtent[1]=blockExtent[0]+textureSize[0];
05958 if(!this->CellFlag)
05959 {
05960 blockExtent[1]--;
05961 }
05962 if(blockExtent[1]>realExtent[1])
05963 {
05964 blockExtent[1]=realExtent[1];
05965 }
05966 ++xIndex;
05967 }
05968
05969 blockExtent[2]=blockExtent[3];
05970 blockExtent[3]=blockExtent[2]+textureSize[1];
05971 if(!this->CellFlag)
05972 {
05973 blockExtent[3]--;
05974 }
05975 if(blockExtent[3]>realExtent[3])
05976 {
05977 blockExtent[3]=realExtent[3];
05978 }
05979 ++yIndex;
05980 }
05981
05982
05983 blockExtent[4]=blockExtent[5];
05984 blockExtent[5]=blockExtent[4]+textureSize[2];
05985 if(!this->CellFlag)
05986 {
05987 blockExtent[5]--;
05988 }
05989 if(blockExtent[5]>realExtent[5])
05990 {
05991 blockExtent[5]=realExtent[5];
05992 }
05993 ++zIndex;
05994 }
05995
05996 assert("check: valid_number_of_blocks" && blockId==count);
05997
05998 qsort(sortedBlocks,static_cast<size_t>(count),
05999 sizeof(vtkRegionDistance2),
06000 vtkRegionComparisonFunction);
06001
06002
06003 i=0;
06004 int abort=0;
06005 while(!abort && i < count)
06006 {
06007 size_t k=sortedBlocks[i].Id;
06008
06009 int blockTextureExtent[6];
06010 int j;
06011 if(this->CellFlag)
06012 {
06013
06014 j=0;
06015 while(j<6)
06016 {
06017 blockTextureExtent[j]=vtkMath::Floor(blocks[k].Extent[j]);
06018 ++j;
06019 }
06020 }
06021 else
06022 {
06023
06024 j=0;
06025 while(j<6)
06026 {
06027 blockTextureExtent[j]=vtkMath::Floor(blocks[k].Extent[j]);
06028 ++j;
06029 blockTextureExtent[j]=vtkMath::Floor(blocks[k].Extent[j]);
06030 if(blockTextureExtent[j]<blocks[k].Extent[j])
06031 {
06032 ++blockTextureExtent[j];
06033 }
06034 ++j;
06035 }
06036 }
06037
06038
06039 if(!this->LoadScalarField(this->GetInput(),this->MaskInput, blockTextureExtent,
06040 volume))
06041 {
06042 cout<<"Loading the streamed block FAILED!!!!!"<<endl;
06043 }
06044
06045 loadedExtent=this->CurrentScalar->GetLoadedExtent();
06046
06047 float lowBounds[3];
06048 float highBounds[3];
06049 if(!this->CurrentScalar->GetLoadedCellFlag())
06050 {
06051 j=0;
06052 while(j<3)
06053 {
06054 double delta=
06055 static_cast<double>(loadedExtent[j*2+1]-loadedExtent[j*2]);
06056 lowBounds[j]=static_cast<float>((blocks[k].Extent[j*2]-static_cast<double>(loadedExtent[j*2]))/delta);
06057 highBounds[j]=static_cast<float>((blocks[k].Extent[j*2+1]-static_cast<double>(loadedExtent[j*2]))/delta);
06058 ++j;
06059 }
06060 }
06061 else
06062 {
06063 j=0;
06064 while(j<3)
06065 {
06066 double delta=
06067 static_cast<double>(loadedExtent[j*2+1]-loadedExtent[j*2]);
06068 lowBounds[j]=static_cast<float>((blocks[k].Extent[j*2]-0.5-static_cast<double>(loadedExtent[j*2]))/delta);
06069 highBounds[j]=static_cast<float>((blocks[k].Extent[j*2+1]-0.5-static_cast<double>(loadedExtent[j*2]))/delta);
06070 ++j;
06071 }
06072 }
06073
06074
06075
06076
06077
06078
06079
06080 assert("check: positive_low_bounds0" && lowBounds[0]>=0.0);
06081 assert("check: positive_low_bounds1" && lowBounds[1]>=0.0);
06082 assert("check: positive_low_bounds2" && lowBounds[2]>=0.0);
06083
06084 assert("check: increasing_bounds0" && lowBounds[0]<=highBounds[0]);
06085 assert("check: increasing_bounds1" && lowBounds[1]<=highBounds[1]);
06086 assert("check: increasing_bounds2" && lowBounds[2]<=highBounds[2]);
06087 assert("check: high_bounds0_less_than1" && highBounds[0]<=1.0);
06088 assert("check: high_bounds1_less_than1" && highBounds[1]<=1.0);
06089 assert("check: high_bounds2_less_than1" && highBounds[2]<=1.0);
06090
06091 GLint lb;
06092 lb=vtkgl::GetUniformLocation(static_cast<GLuint>(this->ProgramShader),
06093 "lowBounds");
06094
06095 this->PrintError("get uniform low bounds");
06096 if(lb!=-1)
06097 {
06098 vtkgl::Uniform3f(lb, lowBounds[0],lowBounds[1],lowBounds[2]);
06099 this->PrintError("set uniform low bounds");
06100 }
06101 else
06102 {
06103 vtkErrorMacro(<<" lowBounds is not a uniform variable.");
06104 }
06105 GLint hb;
06106 hb=vtkgl::GetUniformLocation(static_cast<GLuint>(this->ProgramShader),
06107 "highBounds");
06108 this->PrintError("get uniform high bounds");
06109 if(hb!=-1)
06110 {
06111 vtkgl::Uniform3f(hb, highBounds[0],highBounds[1],highBounds[2]);
06112 this->PrintError("set uniform high bounds");
06113 }
06114 else
06115 {
06116 vtkErrorMacro(<<" highBounds is not a uniform variable.");
06117 }
06118
06119 this->PrintError("uniform low/high bounds block");
06120
06121 this->LoadProjectionParameters(ren,volume);
06122 this->ClipBoundingBox(ren,blocks[k].Bounds,volume);
06123 abort=this->RenderClippedBoundingBox(1,i,count,ren->GetRenderWindow());
06124 if (!abort)
06125 {
06126 this->CopyFBOToTexture();
06127 }
06128 this->PrintError("render clipped block 1");
06129
06130
06131
06132 ++i;
06133 }
06134
06135 delete[] blocks;
06136 delete[] sortedBlocks;
06137 return abort;
06138 }
06139 }
06140 }
06141
06142 loadedExtent=this->CurrentScalar->GetLoadedExtent();
06143
06144
06145 float lowBounds[3];
06146 float highBounds[3];
06147 if(!this->CurrentScalar->GetLoadedCellFlag())
06148 {
06149 i=0;
06150 while(i<3)
06151 {
06152 double delta=
06153 static_cast<double>(loadedExtent[i*2+1]-loadedExtent[i*2]+1);
06154 lowBounds[i]=static_cast<float>((realExtent[i*2]+0.5-static_cast<double>(loadedExtent[i*2]))/delta);
06155 highBounds[i]=static_cast<float>((realExtent[i*2+1]+0.5-static_cast<double>(loadedExtent[i*2]))/delta);
06156 ++i;
06157 }
06158 }
06159 else
06160 {
06161 i=0;
06162 while(i<3)
06163 {
06164 double delta=
06165 static_cast<double>(loadedExtent[i*2+1]-loadedExtent[i*2]+1);
06166
06167
06168
06169
06170
06171
06172
06173
06174 lowBounds[i]=static_cast<float>((realExtent[i*2]-static_cast<double>(loadedExtent[i*2]))/delta);
06175 highBounds[i]=static_cast<float>((realExtent[i*2+1]-static_cast<double>(loadedExtent[i*2]))/delta);
06176 ++i;
06177 }
06178 }
06179
06180 assert("check: positive_low_bounds0" && lowBounds[0]>=0.0);
06181 assert("check: positive_low_bounds1" && lowBounds[1]>=0.0);
06182 assert("check: positive_low_bounds2" && lowBounds[2]>=0.0);
06183
06184 assert("check: increasing_bounds0" && lowBounds[0]<=highBounds[0]);
06185 assert("check: increasing_bounds1" && lowBounds[1]<=highBounds[1]);
06186 assert("check: increasing_bounds2" && lowBounds[2]<=highBounds[2]);
06187 assert("check: high_bounds0_less_than1" && highBounds[0]<=1.0);
06188 assert("check: high_bounds1_less_than1" && highBounds[1]<=1.0);
06189 assert("check: high_bounds2_less_than1" && highBounds[2]<=1.0);
06190
06191 GLint lb;
06192 lb=vtkgl::GetUniformLocation(static_cast<GLuint>(this->ProgramShader),
06193 "lowBounds");
06194
06195 this->PrintError("get uniform low bounds");
06196 if(lb!=-1)
06197 {
06198 vtkgl::Uniform3f(lb, lowBounds[0],lowBounds[1],lowBounds[2]);
06199 this->PrintError("set uniform low bounds");
06200 }
06201 else
06202 {
06203 vtkErrorMacro(<<" lowBounds is not a uniform variable.");
06204 }
06205 GLint hb;
06206 hb=vtkgl::GetUniformLocation(static_cast<GLuint>(this->ProgramShader),
06207 "highBounds");
06208 this->PrintError("get uniform high bounds");
06209 if(hb!=-1)
06210 {
06211 vtkgl::Uniform3f(hb, highBounds[0],highBounds[1],highBounds[2]);
06212 this->PrintError("set uniform high bounds");
06213 }
06214 else
06215 {
06216 vtkErrorMacro(<<" highBounds is not a uniform variable.");
06217 }
06218
06219 this->PrintError("uniform low/high bounds");
06220
06221 this->LoadProjectionParameters(ren,volume);
06222 this->ClipBoundingBox(ren,bounds,volume);
06223 int abort=this->RenderClippedBoundingBox(1,0,1,ren->GetRenderWindow());
06224 if (!abort)
06225 {
06226 this->CopyFBOToTexture();
06227 }
06228 this->PrintError("render clipped 1");
06229 return abort;
06230 }
06231
06232
06233
06234
06235 void vtkMitkOpenGLGPUVolumeRayCastMapper::LoadProjectionParameters(
06236 vtkRenderer *ren,
06237 vtkVolume *vol)
06238 {
06239 vtkMatrix4x4 *worldToDataset=vol->GetMatrix();
06240 vtkMatrix4x4 *datasetToWorld=this->TempMatrix[0];
06241 vtkMatrix4x4::Invert(worldToDataset,datasetToWorld);
06242
06243 double *bounds=this->CurrentScalar->GetLoadedBounds();
06244
06245 double dx=bounds[1]-bounds[0];
06246 double dy=bounds[3]-bounds[2];
06247 double dz=bounds[5]-bounds[4];
06248
06249
06250
06251
06252 vtkMatrix4x4 *worldToTexture=this->TempMatrix[2];
06253 vtkMatrix4x4 *datasetToTexture=this->TempMatrix[1];
06254
06255
06256 datasetToTexture->Zero();
06257 datasetToTexture->SetElement(0,0,dx);
06258 datasetToTexture->SetElement(1,1,dy);
06259 datasetToTexture->SetElement(2,2,dz);
06260 datasetToTexture->SetElement(3,3,1.0);
06261 datasetToTexture->SetElement(0,3,bounds[0]);
06262 datasetToTexture->SetElement(1,3,bounds[2]);
06263 datasetToTexture->SetElement(2,3,bounds[4]);
06264
06265
06266 vtkMatrix4x4::Multiply4x4(worldToDataset,datasetToTexture,worldToTexture);
06267
06268
06269 int parallelProjection=ren->GetActiveCamera()->GetParallelProjection();
06270
06271
06272
06273 if(parallelProjection)
06274 {
06275
06276 double dirWorld[4];
06277 double dir[4];
06278 ren->GetActiveCamera()->GetDirectionOfProjection(dirWorld);
06279 dirWorld[3]=0.0;
06280
06281
06282 datasetToWorld->MultiplyPoint(dirWorld,dir);
06283
06284
06285
06286 dir[0]=dir[0]*this->ActualSampleDistance/dx;
06287 dir[1]=dir[1]*this->ActualSampleDistance/dy;
06288 dir[2]=dir[2]*this->ActualSampleDistance/dz;
06289
06290 GLint rayDir;
06291 rayDir=vtkgl::GetUniformLocation(
06292 static_cast<GLuint>(this->ProgramShader),"parallelRayDirection");
06293 if(rayDir!=-1)
06294 {
06295 vtkgl::Uniform3f(rayDir,static_cast<GLfloat>(dir[0]),
06296 static_cast<GLfloat>(dir[1]),
06297 static_cast<GLfloat>(dir[2]));
06298 }
06299 else
06300 {
06301 vtkErrorMacro(<<"parallelRayDirection is not a uniform variable.");
06302 }
06303
06304 }
06305 else
06306 {
06307
06308
06309
06310
06311 double cameraPosWorld[4];
06312
06313
06314 double cameraPosDataset[4];
06315
06316
06317 double cameraPosTexture[4];
06318
06319 ren->GetActiveCamera()->GetPosition(cameraPosWorld);
06320 cameraPosWorld[3]=1.0;
06321
06322 datasetToWorld->MultiplyPoint(cameraPosWorld,cameraPosDataset);
06323
06324
06325 if(cameraPosDataset[3]!=1.0)
06326 {
06327 double ratio=1/cameraPosDataset[3];
06328 cameraPosDataset[0]*=ratio;
06329 cameraPosDataset[1]*=ratio;
06330 cameraPosDataset[2]*=ratio;
06331 }
06332
06333 cameraPosTexture[0] = (cameraPosDataset[0]-bounds[0])/dx;
06334 cameraPosTexture[1] = (cameraPosDataset[1]-bounds[2])/dy;
06335 cameraPosTexture[2] = (cameraPosDataset[2]-bounds[4])/dz;
06336
06337
06338
06339
06340 vtkMatrix4x4 *transposeWorldToTexture=this->TempMatrix[1];
06341
06342 vtkMatrix4x4::Transpose(worldToTexture,transposeWorldToTexture);
06343
06344 vtkMatrix4x4 *coefMatrix=this->TempMatrix[1];
06345 vtkMatrix4x4::Multiply4x4(transposeWorldToTexture,worldToTexture,
06346 coefMatrix);
06347 GLint uCameraPosition;
06348
06349 uCameraPosition=vtkgl::GetUniformLocation(
06350 static_cast<GLuint>(this->ProgramShader),"cameraPosition");
06351
06352 if(uCameraPosition!=-1)
06353 {
06354 vtkgl::Uniform3f(uCameraPosition,
06355 static_cast<GLfloat>(cameraPosTexture[0]),
06356 static_cast<GLfloat>(cameraPosTexture[1]),
06357 static_cast<GLfloat>(cameraPosTexture[2]));
06358 }
06359 else
06360 {
06361 vtkErrorMacro(<<"cameraPosition is not a uniform variable.");
06362 }
06363 GLint uSampleDistance;
06364 uSampleDistance=vtkgl::GetUniformLocation(
06365 static_cast<GLuint>(this->ProgramShader),"sampleDistance");
06366
06367 if(uSampleDistance!=-1)
06368 {
06369 vtkgl::Uniform1f(uSampleDistance,this->ActualSampleDistance);
06370 }
06371 else
06372 {
06373 vtkErrorMacro(<<"sampleDistance is not a uniform variable.");
06374 }
06375
06376 GLint uMatrix1;
06377
06378 uMatrix1=vtkgl::GetUniformLocation(
06379 static_cast<GLuint>(this->ProgramShader),"matrix1");
06380
06381 if(uMatrix1!=-1)
06382 {
06383 vtkgl::Uniform3f(uMatrix1,
06384 static_cast<GLfloat>(coefMatrix->GetElement(0,0)),
06385 static_cast<GLfloat>(coefMatrix->GetElement(1,1)),
06386 static_cast<GLfloat>(coefMatrix->GetElement(2,2)));
06387 }
06388 else
06389 {
06390 vtkErrorMacro(<<"matrix1 is not a uniform variable.");
06391 }
06392 GLint uMatrix2;
06393 uMatrix2=vtkgl::GetUniformLocation(
06394 static_cast<GLuint>(this->ProgramShader),"matrix2");
06395
06396 if(uMatrix2!=-1)
06397 {
06398 vtkgl::Uniform3f(uMatrix2,
06399 static_cast<GLfloat>(2*coefMatrix->GetElement(0,1)),
06400 static_cast<GLfloat>(2*coefMatrix->GetElement(1,2)),
06401 static_cast<GLfloat>(2*coefMatrix->GetElement(0,2)));
06402 }
06403 else
06404 {
06405 vtkErrorMacro(<<"matrix2 is not a uniform variable.");
06406 }
06407 }
06408 this->PrintError("after uniforms for projection");
06409
06410
06411 vtkMatrix4x4 *eyeToTexture=this->TempMatrix[1];
06412 vtkMatrix4x4 *eyeToWorld=ren->GetActiveCamera()->GetViewTransformMatrix();
06413
06414 vtkMatrix4x4::Multiply4x4(eyeToWorld,worldToTexture,eyeToTexture);
06415
06416 GLfloat matrix[16];
06417 double *raw=eyeToTexture->Element[0];
06418 int index;
06419 int column;
06420 int row;
06421
06422 int shadeMethod=this->LastShade;
06423
06424 if(shadeMethod==vtkMitkOpenGLGPUVolumeRayCastMapperShadeYes)
06425 {
06426 index=0;
06427 column=0;
06428 while(column<3)
06429 {
06430 row=0;
06431 while(row<3)
06432 {
06433
06434 matrix[index]=static_cast<GLfloat>(raw[row*4+column]);
06435 ++index;
06436 ++row;
06437 }
06438 ++column;
06439 }
06440 GLint uEyeToTexture3;
06441
06442 uEyeToTexture3=vtkgl::GetUniformLocation(
06443 static_cast<GLuint>(this->ProgramShader),"eyeToTexture3");
06444
06445 this->PrintError("after getUniform eyeToTexture3");
06446
06447 if(uEyeToTexture3!=-1)
06448 {
06449 vtkgl::UniformMatrix3fv(uEyeToTexture3,1,GL_FALSE,matrix);
06450 }
06451 else
06452 {
06453 vtkErrorMacro(<<"eyeToTexture3 is not a uniform variable.");
06454 }
06455 this->PrintError("after Uniform eyeToTexture3");
06456
06457 index=0;
06458 column=0;
06459 while(column<4)
06460 {
06461 row=0;
06462 while(row<4)
06463 {
06464
06465 matrix[index]=static_cast<GLfloat>(raw[row*4+column]);
06466 ++index;
06467 ++row;
06468 }
06469 ++column;
06470 }
06471 GLint uEyeToTexture4;
06472
06473 uEyeToTexture4=vtkgl::GetUniformLocation(
06474 static_cast<GLuint>(this->ProgramShader),"eyeToTexture4");
06475
06476 if(uEyeToTexture4!=-1)
06477 {
06478 vtkgl::UniformMatrix4fv(uEyeToTexture4,1,GL_FALSE,matrix);
06479 }
06480 else
06481 {
06482 vtkErrorMacro(<<"eyeToTexture4 is not a uniform variable.");
06483 }
06484 }
06485
06486 eyeToTexture->Invert();
06487
06488 index=0;
06489 column=0;
06490 while(column<4)
06491 {
06492 row=0;
06493 while(row<4)
06494 {
06495
06496 matrix[index]=static_cast<GLfloat>(raw[row*4+column]);
06497 ++index;
06498 ++row;
06499 }
06500 ++column;
06501 }
06502
06503 this->PrintError("before GetUniformLocation TextureToEye");
06504 GLint uTextureToEye;
06505
06506 uTextureToEye=vtkgl::GetUniformLocation(
06507 static_cast<GLuint>(this->ProgramShader),"textureToEye");
06508
06509 this->PrintError("after GetUniformLocation TextureToEye");
06510 if(uTextureToEye!=-1)
06511 {
06512 vtkgl::UniformMatrix4fv(uTextureToEye,1,GL_FALSE,matrix);
06513 }
06514 else
06515 {
06516 vtkErrorMacro(<<"textureToEye is not a uniform variable.");
06517 }
06518 this->PrintError("after UniformMatrxix TextureToEye");
06519
06520 if(shadeMethod==vtkMitkOpenGLGPUVolumeRayCastMapperShadeYes)
06521 {
06522 eyeToTexture->Transpose();
06523
06524 index=0;
06525 column=0;
06526 while(column<3)
06527 {
06528 row=0;
06529 while(row<3)
06530 {
06531
06532 matrix[index]=static_cast<GLfloat>(raw[row*4+column]);
06533 ++index;
06534 ++row;
06535 }
06536 ++column;
06537 }
06538 GLint uTranposeTextureToEye;
06539 uTranposeTextureToEye=vtkgl::GetUniformLocation(
06540 static_cast<GLuint>(this->ProgramShader),"transposeTextureToEye");
06541
06542 if(uTranposeTextureToEye!=-1)
06543 {
06544 vtkgl::UniformMatrix3fv(uTranposeTextureToEye,1,GL_FALSE,matrix);
06545 }
06546 else
06547 {
06548 vtkErrorMacro(<<"transposeTextureToEye is not a uniform variable.");
06549 }
06550
06551 float cellScale[3];
06552 float cellStep[3];
06553
06554 vtkIdType *loadedExtent=this->CurrentScalar->GetLoadedExtent();
06555 cellScale[0]=static_cast<float>(static_cast<double>(
06556 loadedExtent[1]-loadedExtent[0])*0.5);
06557 cellScale[1]=static_cast<float>(static_cast<double>(
06558 loadedExtent[3]-loadedExtent[2])*0.5);
06559 cellScale[2]=static_cast<float>(static_cast<double>(
06560 loadedExtent[5]-loadedExtent[4])*0.5);
06561 cellStep[0]=static_cast<float>(1.0/static_cast<double>(
06562 loadedExtent[1]-loadedExtent[0]));
06563 cellStep[1]=static_cast<float>(1.0/static_cast<double>(
06564 loadedExtent[3]-loadedExtent[2]));
06565 cellStep[2]=static_cast<float>(1.0/static_cast<double>(
06566 loadedExtent[5]-loadedExtent[4]));
06567
06568 GLint uCellScale;
06569 uCellScale=vtkgl::GetUniformLocation(
06570 static_cast<GLuint>(this->ProgramShader),"cellScale");
06571 if(uCellScale!=-1)
06572 {
06573 vtkgl::Uniform3f(uCellScale,cellScale[0],cellScale[1],cellScale[2]);
06574 }
06575 else
06576 {
06577 vtkErrorMacro(<<"error: cellScale is not a uniform variable.");
06578 }
06579 GLint uCellStep;
06580
06581 uCellStep=vtkgl::GetUniformLocation(
06582 static_cast<GLuint>(this->ProgramShader),"cellStep");
06583
06584 if(uCellStep!=-1)
06585 {
06586 vtkgl::Uniform3f(uCellStep,cellStep[0],cellStep[1],cellStep[2]);
06587 }
06588 else
06589 {
06590 vtkErrorMacro(<<"error: cellStep is not a uniform variable.");
06591 }
06592 }
06593
06594 }
06595
06596
06597
06598
06599
06600
06601
06602
06603
06604
06605 void vtkMitkOpenGLGPUVolumeRayCastMapper::BuildProgram(int parallelProjection,
06606 int raycastMethod,
06607 int shadeMethod,
06608 int componentMethod)
06609 {
06610
06611 assert("pre: valid_raycastMethod" &&
06612 raycastMethod>= vtkMitkOpenGLGPUVolumeRayCastMapperMethodMIP
06613 && raycastMethod<=vtkMitkOpenGLGPUVolumeRayCastMapperMethodCompositeMask);
06614 GLuint fs;
06615
06616
06617
06618 if(parallelProjection!=this->LastParallelProjection)
06619 {
06620
06621 const char *projectionCode;
06622 if(parallelProjection)
06623 {
06624 projectionCode=vtkMitkGPUVolumeRayCastMapper_ParallelProjectionFS;
06625 }
06626 else
06627 {
06628 projectionCode=vtkMitkGPUVolumeRayCastMapper_PerspectiveProjectionFS;
06629 }
06630
06631 fs=static_cast<GLuint>(this->FragmentProjectionShader);
06632 vtkgl::ShaderSource(fs,1,const_cast<const char **>(&projectionCode),0);
06633 vtkgl::CompileShader(fs);
06634 this->CheckCompilation(this->FragmentProjectionShader);
06635 }
06636
06637 if(raycastMethod!=this->LastRayCastMethod)
06638 {
06639
06640 const char *methodCode;
06641 switch(raycastMethod)
06642 {
06643 case vtkMitkOpenGLGPUVolumeRayCastMapperMethodMIP:
06644 methodCode=vtkMitkGPUVolumeRayCastMapper_MIPFS;
06645 break;
06646 case vtkMitkOpenGLGPUVolumeRayCastMapperMethodMIPFourDependent:
06647 methodCode=vtkMitkGPUVolumeRayCastMapper_MIPFourDependentFS;
06648 break;
06649 case vtkMitkOpenGLGPUVolumeRayCastMapperMethodComposite:
06650 methodCode=vtkMitkGPUVolumeRayCastMapper_CompositeFS;
06651 break;
06652 case vtkMitkOpenGLGPUVolumeRayCastMapperMethodCompositeMask:
06653 methodCode=vtkMitkGPUVolumeRayCastMapper_CompositeMaskFS;
06654 break;
06655 case vtkMitkOpenGLGPUVolumeRayCastMapperMethodMinIP:
06656 methodCode=vtkMitkGPUVolumeRayCastMapper_MinIPFS;
06657 break;
06658 case vtkMitkOpenGLGPUVolumeRayCastMapperMethodMinIPFourDependent:
06659 methodCode=vtkMitkGPUVolumeRayCastMapper_MinIPFourDependentFS;
06660 break;
06661 }
06662 fs=static_cast<GLuint>(this->FragmentTraceShader);
06663 vtkgl::ShaderSource(fs,1,const_cast<const char **>(&methodCode),0);
06664 vtkgl::CompileShader(fs);
06665 this->CheckCompilation(this->FragmentTraceShader);
06666 }
06667
06668
06669 int croppingMode;
06670 switch(raycastMethod)
06671 {
06672 case vtkMitkOpenGLGPUVolumeRayCastMapperMethodMIP:
06673 if(this->NumberOfCroppingRegions>1)
06674 {
06675 croppingMode=vtkMitkOpenGLGPUVolumeRayCastMapperMIPCropping;
06676 }
06677 else
06678 {
06679 croppingMode=vtkMitkOpenGLGPUVolumeRayCastMapperMIPNoCropping;
06680 }
06681 break;
06682 case vtkMitkOpenGLGPUVolumeRayCastMapperMethodMIPFourDependent:
06683 if(this->NumberOfCroppingRegions>1)
06684 {
06685 croppingMode=vtkMitkOpenGLGPUVolumeRayCastMapperMIPFourDependentCropping;
06686 }
06687 else
06688 {
06689 croppingMode=
06690 vtkMitkOpenGLGPUVolumeRayCastMapperMIPFourDependentNoCropping;
06691 }
06692 break;
06693 case vtkMitkOpenGLGPUVolumeRayCastMapperMethodMinIP:
06694 if(this->NumberOfCroppingRegions>1)
06695 {
06696 croppingMode=vtkMitkOpenGLGPUVolumeRayCastMapperMinIPCropping;
06697 }
06698 else
06699 {
06700 croppingMode=vtkMitkOpenGLGPUVolumeRayCastMapperMinIPNoCropping;
06701 }
06702 break;
06703 case vtkMitkOpenGLGPUVolumeRayCastMapperMethodMinIPFourDependent:
06704 if(this->NumberOfCroppingRegions>1)
06705 {
06706 croppingMode=vtkMitkOpenGLGPUVolumeRayCastMapperMinIPFourDependentCropping;
06707 }
06708 else
06709 {
06710 croppingMode=
06711 vtkMitkOpenGLGPUVolumeRayCastMapperMinIPFourDependentNoCropping;
06712 }
06713 break;
06714 default:
06715 if(this->NumberOfCroppingRegions>1)
06716 {
06717 croppingMode=vtkMitkOpenGLGPUVolumeRayCastMapperCompositeCropping;
06718 }
06719 else
06720 {
06721 croppingMode=vtkMitkOpenGLGPUVolumeRayCastMapperCompositeNoCropping;
06722 }
06723 break;
06724 }
06725
06726
06727 if(croppingMode!=this->LastCroppingMode)
06728 {
06729 const char *croppingCode;
06730 switch(croppingMode)
06731 {
06732 case vtkMitkOpenGLGPUVolumeRayCastMapperMIPCropping:
06733 croppingCode=vtkMitkGPUVolumeRayCastMapper_MIPCroppingFS;
06734 break;
06735 case vtkMitkOpenGLGPUVolumeRayCastMapperMIPNoCropping:
06736 croppingCode=vtkMitkGPUVolumeRayCastMapper_MIPNoCroppingFS;
06737 break;
06738 case vtkMitkOpenGLGPUVolumeRayCastMapperMIPFourDependentCropping:
06739 croppingCode=vtkMitkGPUVolumeRayCastMapper_MIPFourDependentCroppingFS;
06740 break;
06741 case vtkMitkOpenGLGPUVolumeRayCastMapperMIPFourDependentNoCropping:
06742 croppingCode=vtkMitkGPUVolumeRayCastMapper_MIPFourDependentNoCroppingFS;
06743 break;
06744 case vtkMitkOpenGLGPUVolumeRayCastMapperCompositeCropping:
06745 croppingCode=vtkMitkGPUVolumeRayCastMapper_CompositeCroppingFS;
06746 break;
06747 case vtkMitkOpenGLGPUVolumeRayCastMapperCompositeNoCropping:
06748 croppingCode=vtkMitkGPUVolumeRayCastMapper_CompositeNoCroppingFS;
06749 break;
06750 case vtkMitkOpenGLGPUVolumeRayCastMapperMinIPCropping:
06751 croppingCode=vtkMitkGPUVolumeRayCastMapper_MinIPCroppingFS;
06752 break;
06753 case vtkMitkOpenGLGPUVolumeRayCastMapperMinIPNoCropping:
06754 croppingCode=vtkMitkGPUVolumeRayCastMapper_MinIPNoCroppingFS;
06755 break;
06756 case vtkMitkOpenGLGPUVolumeRayCastMapperMinIPFourDependentCropping:
06757 croppingCode=vtkMitkGPUVolumeRayCastMapper_MinIPFourDependentCroppingFS;
06758 break;
06759 case vtkMitkOpenGLGPUVolumeRayCastMapperMinIPFourDependentNoCropping:
06760 croppingCode=vtkMitkGPUVolumeRayCastMapper_MinIPFourDependentNoCroppingFS;
06761 break;
06762 }
06763
06764 fs=static_cast<GLuint>(this->FragmentCroppingShader);
06765 vtkgl::ShaderSource(fs,1,const_cast<const char **>(&croppingCode),0);
06766 vtkgl::CompileShader(fs);
06767
06768 this->CheckCompilation(this->FragmentCroppingShader);
06769 }
06770
06771 if(componentMethod!=this->LastComponent)
06772 {
06773 fs=static_cast<GLuint>(this->FragmentComponentShader);
06774 GLuint programShader=static_cast<GLuint>(this->ProgramShader);
06775 if(shadeMethod==vtkMitkOpenGLGPUVolumeRayCastMapperComponentNotUsed)
06776 {
06777 if(this->LastComponent!=
06778 vtkMitkOpenGLGPUVolumeRayCastMapperComponentNotInitialized)
06779 {
06780 vtkgl::DetachShader(programShader,fs);
06781 }
06782 }
06783 else
06784 {
06785 if(this->LastComponent==
06786 vtkMitkOpenGLGPUVolumeRayCastMapperComponentNotInitialized ||
06787 this->LastComponent==
06788 vtkMitkOpenGLGPUVolumeRayCastMapperComponentNotUsed)
06789 {
06790 vtkgl::AttachShader(programShader,fs);
06791 }
06792 const char *componentCode;
06793 if(componentMethod==vtkMitkOpenGLGPUVolumeRayCastMapperComponentOne)
06794 {
06795 componentCode=vtkMitkGPUVolumeRayCastMapper_OneComponentFS;
06796 }
06797 else
06798 {
06799 componentCode=vtkMitkGPUVolumeRayCastMapper_FourComponentsFS;
06800 }
06801 vtkgl::ShaderSource(fs,1,const_cast<const char **>(&componentCode),0);
06802 vtkgl::CompileShader(fs);
06803 this->CheckCompilation(this->FragmentComponentShader);
06804 }
06805 }
06806
06807 if(shadeMethod!=this->LastShade)
06808 {
06809 fs=static_cast<GLuint>(this->FragmentShadeShader);
06810 GLuint programShader=static_cast<GLuint>(this->ProgramShader);
06811 if(shadeMethod==vtkMitkOpenGLGPUVolumeRayCastMapperShadeNotUsed)
06812 {
06813 if(this->LastShade!=
06814 vtkMitkOpenGLGPUVolumeRayCastMapperShadeNotInitialized)
06815 {
06816 vtkgl::DetachShader(programShader,fs);
06817 }
06818 }
06819 else
06820 {
06821 if(this->LastShade==vtkMitkOpenGLGPUVolumeRayCastMapperShadeNotInitialized
06822 || this->LastShade==vtkMitkOpenGLGPUVolumeRayCastMapperShadeNotUsed)
06823 {
06824 vtkgl::AttachShader(programShader,fs);
06825 }
06826 const char *shadeCode;
06827 if(shadeMethod==vtkMitkOpenGLGPUVolumeRayCastMapperShadeYes)
06828 {
06829 shadeCode=vtkMitkGPUVolumeRayCastMapper_ShadeFS;
06830 }
06831 else
06832 {
06833 shadeCode=vtkMitkGPUVolumeRayCastMapper_NoShadeFS;
06834 }
06835 vtkgl::ShaderSource(fs,1,const_cast<const char **>(&shadeCode),0);
06836 vtkgl::CompileShader(fs);
06837 this->CheckCompilation(this->FragmentShadeShader);
06838 }
06839 }
06840
06841 if(parallelProjection!=this->LastParallelProjection ||
06842 raycastMethod!=this->LastRayCastMethod ||
06843 croppingMode!=this->LastCroppingMode ||
06844 componentMethod!=this->LastComponent ||
06845 shadeMethod!=this->LastShade)
06846 {
06847
06848 this->LastParallelProjection=parallelProjection;
06849 this->LastRayCastMethod=raycastMethod;
06850 this->LastCroppingMode=croppingMode;
06851 this->LastComponent=componentMethod;
06852 this->LastShade=shadeMethod;
06853
06854 vtkgl::LinkProgram(static_cast<GLuint>(this->ProgramShader));
06855 }
06856 }
06857
06858
06859
06860
06861
06862
06863
06864
06865 void vtkMitkOpenGLGPUVolumeRayCastMapper::ValidateProgram()
06866 {
06867 vtkgl::ValidateProgram(this->ProgramShader);
06868
06869 GLint params;
06870 vtkgl::GetProgramiv(this->ProgramShader,
06871 vtkgl::VALIDATE_STATUS,¶ms);
06872 if(params==GL_TRUE)
06873 {
06874 cout<<"In the current state the fragment program will succeed."<<endl;
06875 }
06876 else
06877 {
06878 cout<<"In the current state the fragment program will fail."<<endl;
06879 }
06880 vtkgl::GetProgramiv(this->ProgramShader,
06881 vtkgl::INFO_LOG_LENGTH,¶ms);
06882
06883 if(params>0)
06884 {
06885 char *buffer=new char[params];
06886 vtkgl::GetProgramInfoLog(this->ProgramShader,params,0,buffer);
06887 cout<<"validation log: "<<buffer<<endl;
06888 cout<<"end of validation log"<<endl;
06889 delete[] buffer;
06890 }
06891 else
06892 {
06893 cout<<"no validation log"<<endl;
06894 }
06895
06896 }
06897
06898
06899
06900
06901 const char *vtkMitkOpenGLGPUVolumeRayCastMapper::GetEnabledString(
06902 unsigned char value)
06903 {
06904 if(value)
06905 {
06906 return "enabled";
06907 }
06908 else
06909 {
06910 return "disabled";
06911 }
06912 }
06913
06914
06915
06916
06917 void vtkMitkOpenGLGPUVolumeRayCastMapper::GetOpenGLState()
06918 {
06919 cout<<"lighting:"<<this->GetEnabledString(glIsEnabled(GL_LIGHTING))<<endl;
06920 cout<<"lighting:"<<this->GetEnabledString(glIsEnabled(GL_LIGHTING))<<endl;
06921
06922
06923 GLint value;
06924 glGetIntegerv(vtkgl::ACTIVE_TEXTURE,&value);
06925 GLenum activeTexture=static_cast<GLenum>(value);
06926 cout<<"active texture is "<<(activeTexture-vtkgl::TEXTURE0)<<endl;
06927
06928
06929
06930 GLenum texture=vtkgl::TEXTURE0;
06931 while(texture<vtkgl::TEXTURE6)
06932 {
06933 vtkgl::ActiveTexture(texture);
06934 cout<<"texture"<<texture-vtkgl::TEXTURE0<<endl;
06935 cout<<"1d:"<<GetEnabledString(glIsEnabled(GL_TEXTURE_1D))<<endl;
06936 cout<<"2d:"<<GetEnabledString(glIsEnabled(GL_TEXTURE_2D))<<endl;
06937 cout<<"3d:"<<GetEnabledString(glIsEnabled(vtkgl::TEXTURE_3D_EXT))<<endl;
06938 glGetIntegerv(GL_TEXTURE_BINDING_1D,&value);
06939 cout<<"binding 1d:"<<value<<endl;
06940 glGetIntegerv(GL_TEXTURE_BINDING_2D,&value);
06941 cout<<"binding 2d:"<<value<<endl;
06942 glGetIntegerv(vtkgl::TEXTURE_BINDING_3D,&value);
06943 cout<<"binding 3d:"<<value<<endl;
06944 ++texture;
06945 }
06946
06947
06948 vtkgl::ActiveTexture(activeTexture);
06949 }
06950
06951
06952
06953
06954 void vtkMitkOpenGLGPUVolumeRayCastMapper::GetLightingStatus()
06955 {
06956
06957 GLboolean flag=glIsEnabled(GL_LIGHTING);
06958 if(flag)
06959 {
06960 cout<<"enabled"<<endl;
06961 }
06962 else
06963 {
06964 cout<<"disabled"<<endl;
06965 }
06966 GLint value;
06967 glGetIntegerv(GL_MAX_LIGHTS,&value);
06968 cout<<"number of lights supported by this GPU:"<<value<<endl;
06969
06970 float values[4];
06971 glGetFloatv(GL_LIGHT_MODEL_AMBIENT,values);
06972
06973 cout<<"light model ambient="<<values[0]<<","<<values[1]<<","<<values[2]
06974 <<","<<values[3]<<endl;
06975
06976 unsigned int i=0;
06977 unsigned int c=static_cast<unsigned int>(value);
06978
06979 cout<<"light\t| status\t| ambient\t| diffuse\t| specular\t| position\t| spot direction\t| spot exponent\t| spot cutoff\t| k0\t| k1\t| k2"<<endl;
06980
06981 while(i<c)
06982 {
06983 cout<<i<<"\t| ";
06984 glIsEnabled(GL_LIGHT0+i);
06985 if(flag)
06986 {
06987 cout<<"enabled";
06988 }
06989 else
06990 {
06991 cout<<"disabled";
06992 }
06993
06994 glGetLightfv(GL_LIGHT0+i,GL_AMBIENT,values);
06995 cout<<"\t| ("<<values[0]<<","<<values[1]<<","<<values[2]<<","<<values[3];
06996 glGetLightfv(GL_LIGHT0+i,GL_DIFFUSE,values);
06997 cout<<")\t| ("<<values[0]<<","<<values[1]<<","<<values[2]<<","<<values[3];
06998 glGetLightfv(GL_LIGHT0+i,GL_SPECULAR,values);
06999 cout<<")\t| ("<<values[0]<<","<<values[1]<<","<<values[2]<<","<<values[3];
07000 glGetLightfv(GL_LIGHT0+i,GL_POSITION,values);
07001 cout<<")\t| ("<<values[0]<<","<<values[1]<<","<<values[2]<<","<<values[3];
07002 glGetLightfv(GL_LIGHT0+i,GL_SPOT_DIRECTION,values);
07003 cout<<")\t| ("<<values[0]<<","<<values[1]<<","<<values[2];
07004 glGetLightfv(GL_LIGHT0+i,GL_SPOT_EXPONENT,values);
07005 cout<<")\t| "<<values[0];
07006 glGetLightfv(GL_LIGHT0+i,GL_SPOT_CUTOFF,values);
07007 cout<<"\t| "<<values[0];
07008 glGetLightfv(GL_LIGHT0+i,GL_CONSTANT_ATTENUATION,values);
07009 cout<<"\t| "<<values[0];
07010 glGetLightfv(GL_LIGHT0+i,GL_LINEAR_ATTENUATION,values);
07011 cout<<"\t| "<<values[0];
07012 glGetLightfv(GL_LIGHT0+i,GL_QUADRATIC_ATTENUATION,values);
07013 cout<<"\t| "<<values[0]<<endl;
07014 ++i;
07015 }
07016
07017 cout<<"color material=";
07018 flag=glIsEnabled(GL_COLOR_MATERIAL);
07019 if(flag)
07020 {
07021 cout<<"enabled"<<endl;
07022 }
07023 else
07024 {
07025 cout<<"disabled"<<endl;
07026 }
07027
07028 cout<<"color material face=";
07029 GLint ivalue[4];
07030 glGetIntegerv(GL_COLOR_MATERIAL_FACE,ivalue);
07031 switch(ivalue[0])
07032 {
07033 case GL_FRONT_AND_BACK:
07034 cout<<"GL_FRONT_AND_BACK";
07035 break;
07036 case GL_FRONT:
07037 cout<<"GL_FRONT";
07038 break;
07039 case GL_BACK:
07040 cout<<"GL_BACK";
07041 break;
07042 default:
07043 cout<<"unknown value="<<ivalue[0]<<endl;
07044 break;
07045 }
07046
07047 cout<<"color material parameter=";
07048 glGetIntegerv(GL_COLOR_MATERIAL_PARAMETER,ivalue);
07049 switch(ivalue[0])
07050 {
07051 case GL_AMBIENT_AND_DIFFUSE:
07052 cout<<"GL_AMBIENT_AND_DIFFUSE";
07053 break;
07054 case GL_AMBIENT:
07055 cout<<"GL_AMBIENT";
07056 break;
07057 case GL_DIFFUSE:
07058 cout<<"GL_DIFFUSE";
07059 break;
07060 case GL_EMISSION:
07061 cout<<"GL_EMISSION";
07062 break;
07063 case GL_SPECULAR:
07064 cout<<"GL_SPECULAR";
07065 break;
07066 default:
07067 cout<<"unknown value="<<ivalue[0]<<endl;
07068 break;
07069 }
07070
07071 GLfloat fcolor[4];
07072 glGetMaterialfv(GL_FRONT,GL_EMISSION,fcolor);
07073 cout<<"front emission="<<fcolor[0]<<" "<<fcolor[1]<<" "<<fcolor[2]<<" "<<fcolor[3]<<endl;
07074 glGetMaterialfv(GL_FRONT,GL_AMBIENT,fcolor);
07075 cout<<"front ambient="<<fcolor[0]<<" "<<fcolor[1]<<" "<<fcolor[2]<<" "<<fcolor[3]<<endl;
07076 glGetMaterialfv(GL_FRONT,GL_DIFFUSE,fcolor);
07077 cout<<"front diffuse="<<fcolor[0]<<" "<<fcolor[1]<<" "<<fcolor[2]<<" "<<fcolor[3]<<endl;
07078 glGetMaterialfv(GL_FRONT,GL_SPECULAR,fcolor);
07079 cout<<"front specular="<<fcolor[0]<<" "<<fcolor[1]<<" "<<fcolor[2]<<" "<<fcolor[3]<<endl;
07080 }
07081
07082
07083
07084
07085
07086
07087
07088 int vtkMitkOpenGLGPUVolumeRayCastMapper::PowerOfTwoGreaterOrEqual(int x)
07089 {
07090 assert("pre: positive_x" && x>=0);
07091
07092 int result=1;
07093 while(result<x)
07094 {
07095 result<<=1;
07096 }
07097 assert("post: valid_result" && result>=x);
07098 return result;
07099 }
07100
07101
07102
07103
07104 void vtkMitkOpenGLGPUVolumeRayCastMapper::UpdateNoiseTexture()
07105 {
07106 if(this->NoiseTextureId==0)
07107 {
07108 GLuint noiseTextureObject;
07109 glGenTextures(1,&noiseTextureObject);
07110 this->NoiseTextureId=static_cast<unsigned int>(noiseTextureObject);
07111 vtkgl::ActiveTexture(vtkgl::TEXTURE6);
07112 glBindTexture(GL_TEXTURE_2D,noiseTextureObject);
07113
07114 GLsizei size=128;
07115 GLint maxSize;
07116 const float factor=0.1f;
07117
07118 const float amplitude=0.5f*factor;
07119
07120
07121 glGetIntegerv(GL_MAX_TEXTURE_SIZE,&maxSize);
07122 if(size>maxSize)
07123 {
07124 size=maxSize;
07125 }
07126 if(this->NoiseTexture!=0 && this->NoiseTextureSize!=size)
07127 {
07128 delete[] this->NoiseTexture;
07129 this->NoiseTexture=0;
07130 }
07131 if(this->NoiseTexture==0)
07132 {
07133 this->NoiseTexture=new float[size*size];
07134 this->NoiseTextureSize=size;
07135 vtkPerlinNoise *noiseGenerator=vtkPerlinNoise::New();
07136 noiseGenerator->SetFrequency(size,1.0,1.0);
07137 noiseGenerator->SetPhase(0.0,0.0,0.0);
07138 noiseGenerator->SetAmplitude(amplitude);
07139 int j=0;
07140 while(j<size)
07141 {
07142 int i=0;
07143 while(i<size)
07144 {
07145 this->NoiseTexture[j*size+i]=0.0;
07146 ++i;
07147 }
07148 ++j;
07149 }
07150 noiseGenerator->Delete();
07151 }
07152 glTexImage2D(GL_TEXTURE_2D,0,GL_LUMINANCE,size,size,0,GL_RED,GL_FLOAT,
07153 this->NoiseTexture);
07154
07155 glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT);
07156 glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT);
07157 GLfloat borderColor[4]={0.0,0.0,0.0,0.0};
07158 glTexParameterfv(GL_TEXTURE_2D,GL_TEXTURE_BORDER_COLOR,borderColor);
07159 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
07160 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
07161
07162 vtkgl::ActiveTexture(vtkgl::TEXTURE0);
07163 }
07164 }
07165
07166
07167
07168
07169
07170
07171
07172
07173
07174
07175
07176
07177
07178 void vtkMitkOpenGLGPUVolumeRayCastMapper::GetReductionRatio(double ratio[3])
07179 {
07180
07181 int i;
07182 int wholeTextureExtent[6];
07183 this->GetInput()->GetExtent(wholeTextureExtent);
07184 if(this->CellFlag)
07185 {
07186 i=1;
07187 while(i<6)
07188 {
07189 wholeTextureExtent[i]--;
07190 i+=2;
07191 }
07192 }
07193
07194
07195 GLint maxSize;
07196 glGetIntegerv(vtkgl::MAX_3D_TEXTURE_SIZE,&maxSize);
07197
07198 vtkIdType rTextureSize[3];
07199 double dMaxSize=static_cast<double>(maxSize);
07200 i=0;
07201 while(i<3)
07202 {
07203 double textureSize=wholeTextureExtent[2*i+1]-wholeTextureExtent[2*i]+1;
07204 if(textureSize>maxSize)
07205 {
07206 ratio[i]=dMaxSize/textureSize;
07207 }
07208 else
07209 {
07210 ratio[i]=1.0;
07211 }
07212 rTextureSize[i]=static_cast<vtkIdType>(floor(textureSize*ratio[i]));
07213 ++i;
07214 }
07215
07216
07217
07218 vtkDataArray *scalars=this->GetScalars(this->GetInput(),this->ScalarMode,
07219 this->ArrayAccessMode,
07220 this->ArrayId,
07221 this->ArrayName,
07222 this->CellFlag);
07223 int scalarType=scalars->GetDataType();
07224
07225 vtkIdType size=rTextureSize[0]*rTextureSize[1]*rTextureSize[2]
07226 *vtkAbstractArray::GetDataTypeSize(scalarType)
07227 *scalars->GetNumberOfComponents();
07228
07229 if(size>static_cast<double>(this->MaxMemoryInBytes)
07230 *static_cast<double>(this->MaxMemoryFraction))
07231 {
07232 double r=static_cast<double>(this->MaxMemoryInBytes)
07233 *static_cast<double>(this->MaxMemoryFraction)/static_cast<double>(size);
07234 double r3=pow(r,1.0/3.0);
07235
07236 bool reduced[3];
07237 i=0;
07238 int count=0;
07239 while(i<3)
07240 {
07241 vtkIdType newSize=static_cast<vtkIdType>(
07242 floor(static_cast<double>(rTextureSize[i])*r3));
07243 reduced[i]=newSize>=1;
07244 if(reduced[i])
07245 {
07246 ++count;
07247 }
07248 ++i;
07249 }
07250
07251 if(count<3)
07252 {
07253 double r2=sqrt(r);
07254 count=0;
07255 i=0;
07256 while(i<3)
07257 {
07258 if(reduced[i])
07259 {
07260 vtkIdType newSize=static_cast<vtkIdType>(
07261 floor(static_cast<double>(rTextureSize[i])*r2));
07262 reduced[i]=newSize>=1;
07263 if(reduced[i])
07264 {
07265 ++count;
07266 }
07267 }
07268 ++i;
07269 }
07270 if(count<2)
07271 {
07272 i=0;
07273 while(i<3)
07274 {
07275 if(reduced[i])
07276 {
07277 ratio[i]*=r;
07278 }
07279 ++i;
07280 }
07281 }
07282 else
07283 {
07284 i=0;
07285 while(i<3)
07286 {
07287 if(reduced[i])
07288 {
07289 ratio[i]*=r2;
07290 }
07291 ++i;
07292 }
07293 }
07294 }
07295 else
07296 {
07297 i=0;
07298 while(i<3)
07299 {
07300 ratio[i]*=r3;
07301 ++i;
07302 }
07303 }
07304 }
07305
07306 assert("post: valid_i_ratio" && ratio[0]>0 && ratio[0]<=1.0);
07307 assert("post: valid_j_ratio" && ratio[1]>0 && ratio[1]<=1.0);
07308 assert("post: valid_k_ratio" && ratio[2]>0 && ratio[2]<=1.0);
07309 }
07310
07311
07312
07313
07314 void vtkMitkOpenGLGPUVolumeRayCastMapper::PrintSelf(ostream& os,
07315 vtkIndent indent)
07316 {
07317 this->Superclass::PrintSelf(os,indent);
07318 }
07319
07320 #endif