00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #ifdef _OPENMP
00019 #include <omp.h>
00020 #endif
00021
00022 #include "vtkWindows.h"
00023 #include "vtkMitkOpenGLVolumeTextureMapper3D.h"
00024 #include "mitkCommon.h"
00025
00026 #define GPU_INFO MITK_INFO("mapper.vr")
00027 #define GPU_WARN MITK_WARN("mapper.vr")
00028
00029 #include "vtkImageData.h"
00030 #include "vtkMatrix4x4.h"
00031 #include "vtkObjectFactory.h"
00032 #include "vtkPlane.h"
00033 #include "vtkPlaneCollection.h"
00034 #include "vtkPointData.h"
00035 #include "vtkRenderWindow.h"
00036 #include "vtkRenderer.h"
00037 #include "vtkTimerLog.h"
00038 #include "vtkVolumeProperty.h"
00039 #include "vtkTransform.h"
00040 #include "vtkLightCollection.h"
00041 #include "vtkLight.h"
00042 #include "vtkCamera.h"
00043 #include "vtkMath.h"
00044 #include "vtkOpenGLExtensionManager.h"
00045 #include "vtkgl.h"
00046
00047 #include "vtkOpenGLRenderWindow.h"
00048
00049
00050 #define myGL_COMPRESSED_RGB_S3TC_DXT1_EXT 0x83F0
00051 #define myGL_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT 0x8C72
00052 #define myGL_COMPRESSED_RGBA_S3TC_DXT5_EXT 0x83F3
00053
00054
00055 const char *vtkMitkVolumeTextureMapper3D_FourDependentShadeFP =
00056 "!!ARBfp1.0\n"
00057
00058
00059 "TEMP index, normal, finalColor;\n"
00060 "TEMP temp,temp1, temp2, temp3,temp4; \n"
00061 "TEMP sampleColor;\n"
00062 "TEMP ndotl, ndoth, ndotv; \n"
00063 "TEMP lightInfo, lightResult;\n"
00064
00065
00066
00067 "ATTRIB tex0 = fragment.texcoord[0];\n"
00068
00069
00070 "PARAM lightDirection = program.local[0];\n"
00071 "PARAM halfwayVector = program.local[1];\n"
00072 "PARAM coefficient = program.local[2];\n"
00073 "PARAM lightDiffColor = program.local[3]; \n"
00074 "PARAM lightSpecColor = program.local[4]; \n"
00075 "PARAM viewVector = program.local[5];\n"
00076 "PARAM constants = program.local[6];\n"
00077
00078
00079 "OUTPUT out = result.color;\n"
00080
00081
00082
00083 "TEX temp2, tex0, texture[0], 3D;\n"
00084
00085
00086
00087 "MAD normal, temp2, constants.x, constants.y;\n"
00088
00089 "DP3 temp4, normal, normal;\n"
00090 "RSQ temp, temp4.x;\n"
00091 "MUL normal, normal, temp;\n"
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101 "TEX sampleColor, tex0, texture[1], 3D;\n"
00102
00103
00104
00105 "DP3 ndotl, normal, lightDirection;\n"
00106
00107
00108
00109 "DP3 ndoth, normal, halfwayVector;\n"
00110
00111 "DP3 ndotv, normal, viewVector;\n"
00112
00113
00114 "MUL temp3, ndotl, constants.y; \n"
00115 "CMP ndotl, ndotv, ndotl, temp3;\n"
00116 "MUL temp3, ndoth, constants.y; \n"
00117 "CMP ndoth, ndotv, ndoth, temp3;\n"
00118
00119
00120 "MOV lightInfo.x, ndotl.x; \n"
00121 "MOV lightInfo.y, ndoth.x; \n"
00122 "MOV lightInfo.w, coefficient.w; \n"
00123
00124
00125 "LIT lightResult, lightInfo;\n"
00126
00127
00128 "MUL lightResult, lightResult, 4.0;\n"
00129
00130
00131 "MUL finalColor, coefficient.x, sampleColor;\n"
00132
00133
00134 "MUL temp3, lightDiffColor, sampleColor;\n"
00135 "MUL temp3, temp3, lightResult.y;\n"
00136 "ADD finalColor, finalColor, temp3;\n"
00137
00138
00139 "MUL temp3, lightSpecColor, lightResult.z; \n"
00140
00141
00142
00143 "ADD out, finalColor, temp3;\n"
00144 "MOV out.w, temp2.w;\n"
00145
00146 "END\n";
00147
00148 const char *vtkMitkVolumeTextureMapper3D_OneComponentShadeFP =
00149 "!!ARBfp1.0\n"
00150
00151
00152
00153
00154
00155 "TEMP index, normal, finalColor;\n"
00156 "TEMP temp,temp1, temp2, temp3,temp4; \n"
00157 "TEMP sampleColor;\n"
00158 "TEMP ndotl, ndoth, ndotv; \n"
00159 "TEMP lightInfo, lightResult;\n"
00160
00161
00162
00163 "ATTRIB tex0 = fragment.texcoord[0];\n"
00164
00165
00166 "PARAM lightDirection = program.local[0];\n"
00167 "PARAM halfwayVector = program.local[1];\n"
00168 "PARAM coefficient = program.local[2];\n"
00169 "PARAM lightDiffColor = program.local[3]; \n"
00170 "PARAM lightSpecColor = program.local[4]; \n"
00171 "PARAM viewVector = program.local[5];\n"
00172 "PARAM constants = program.local[6];\n"
00173
00174
00175 "OUTPUT out = result.color;\n"
00176
00177
00178
00179 "TEX temp2, tex0, texture[0], 3D;\n"
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221 "MOV index.x,temp2.a;\n"
00222
00223
00224
00225 "MAD normal, temp2, constants.x, constants.y;\n"
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235 "DP3 temp4, normal, normal;\n"
00236
00237 "RSQ temp, temp4.x;\n"
00238
00239 "RCP temp4,temp.x;\n"
00240
00241 "MUL normal, normal, temp;\n"
00242
00243 "MOV index.y, temp4.x;\n"
00244
00245 "TEX sampleColor, index, texture[1], 2D;\n"
00246
00247
00248
00249
00250
00251 "DP3 ndotl, normal, lightDirection;\n"
00252
00253
00254
00255 "DP3 ndoth, normal, halfwayVector;\n"
00256
00257 "DP3 ndotv, normal, viewVector;\n"
00258
00259
00260 "MUL temp3, ndotl, constants.y; \n"
00261 "CMP ndotl, ndotv, ndotl, temp3;\n"
00262 "MUL temp3, ndoth, constants.y; \n"
00263 "CMP ndoth, ndotv, ndoth, temp3;\n"
00264
00265
00266 "MOV lightInfo.x, ndotl.x; \n"
00267 "MOV lightInfo.y, ndoth.x; \n"
00268 "MOV lightInfo.w, coefficient.w; \n"
00269
00270
00271 "LIT lightResult, lightInfo;\n"
00272
00273
00274 "MUL lightResult, lightResult, 4.0;\n"
00275
00276
00277 "MUL finalColor, coefficient.x, sampleColor;\n"
00278
00279
00280 "MUL temp3, lightDiffColor, sampleColor;\n"
00281 "MUL temp3, temp3, lightResult.y;\n"
00282 "ADD finalColor, finalColor, temp3;\n"
00283
00284
00285 "MUL temp3, lightSpecColor, lightResult.z; \n"
00286
00287
00288
00289 "ADD out, finalColor, temp3;\n"
00290 "MOV out.w, sampleColor.w;\n"
00291
00292 "END\n";
00293
00294
00295
00296
00297 vtkCxxRevisionMacro(vtkMitkOpenGLVolumeTextureMapper3D, "$Revision: 1.21 $");
00298 vtkStandardNewMacro(vtkMitkOpenGLVolumeTextureMapper3D);
00299
00300
00301 vtkMitkOpenGLVolumeTextureMapper3D::vtkMitkOpenGLVolumeTextureMapper3D()
00302 {
00303
00304
00305 this->Initialized = 0;
00306 this->Volume1Index = 0;
00307 this->Volume2Index = 0;
00308 this->Volume3Index = 0;
00309 this->ColorLookupIndex = 0;
00310 this->AlphaLookupIndex = 0;
00311 this->RenderWindow = NULL;
00312 this->SupportsCompressedTexture = false;
00313
00314 prgOneComponentShade = 0;
00315 prgRGBAShade = 0;
00316 }
00317
00318 vtkMitkOpenGLVolumeTextureMapper3D::~vtkMitkOpenGLVolumeTextureMapper3D()
00319 {
00320
00321 if(prgOneComponentShade)
00322 vtkgl::DeleteProgramsARB( 1, &prgOneComponentShade );
00323
00324 if(prgRGBAShade)
00325 vtkgl::DeleteProgramsARB( 1, &prgRGBAShade );
00326 }
00327
00328
00329 void vtkMitkOpenGLVolumeTextureMapper3D::ReleaseGraphicsResources(vtkWindow
00330 *renWin)
00331 {
00332
00333
00334 if (( this->Volume1Index || this->Volume2Index ||
00335 this->Volume3Index || this->ColorLookupIndex) && renWin)
00336 {
00337 static_cast<vtkRenderWindow *>(renWin)->MakeCurrent();
00338 #ifdef GL_VERSION_1_1
00339
00340 this->DeleteTextureIndex( &this->Volume1Index );
00341 this->DeleteTextureIndex( &this->Volume2Index );
00342 this->DeleteTextureIndex( &this->Volume3Index );
00343 this->DeleteTextureIndex( &this->ColorLookupIndex );
00344 this->DeleteTextureIndex( &this->AlphaLookupIndex );
00345 #endif
00346 }
00347 this->Volume1Index = 0;
00348 this->Volume2Index = 0;
00349 this->Volume3Index = 0;
00350 this->ColorLookupIndex = 0;
00351 this->RenderWindow = NULL;
00352 this->SupportsCompressedTexture=false;
00353 this->SupportsNonPowerOfTwoTextures=false;
00354
00355 this->Modified();
00356 }
00357
00358 void vtkMitkOpenGLVolumeTextureMapper3D::Render(vtkRenderer *ren, vtkVolume *vol)
00359 {
00360
00361
00362 ren->GetRenderWindow()->MakeCurrent();
00363
00364 if ( !this->Initialized )
00365 {
00366
00367 this->Initialize(ren);
00368 }
00369
00370 if ( !this->RenderPossible )
00371 {
00372 vtkErrorMacro( "required extensions not supported" );
00373 return;
00374 }
00375
00376
00377 vtkMatrix4x4 *matrix = vtkMatrix4x4::New();
00378 vtkPlaneCollection *clipPlanes;
00379 vtkPlane *plane;
00380 int numClipPlanes = 0;
00381 double planeEquation[4];
00382
00383
00384
00385 vol->GetMatrix(matrix);
00386 matrix->Transpose();
00387
00388 glPushAttrib(GL_ENABLE_BIT |
00389 GL_COLOR_BUFFER_BIT |
00390 GL_STENCIL_BUFFER_BIT |
00391 GL_DEPTH_BUFFER_BIT |
00392 GL_POLYGON_BIT |
00393 GL_TEXTURE_BIT);
00394
00395 int i;
00396
00397
00398 clipPlanes = this->ClippingPlanes;
00399 if ( clipPlanes )
00400 {
00401 numClipPlanes = clipPlanes->GetNumberOfItems();
00402 if (numClipPlanes > 6)
00403 {
00404 vtkErrorMacro(<< "OpenGL guarantees only 6 additional clipping planes");
00405 }
00406
00407 for (i = 0; i < numClipPlanes; i++)
00408 {
00409 glEnable(static_cast<GLenum>(GL_CLIP_PLANE0+i));
00410
00411 plane = static_cast<vtkPlane *>(clipPlanes->GetItemAsObject(i));
00412
00413 planeEquation[0] = plane->GetNormal()[0];
00414 planeEquation[1] = plane->GetNormal()[1];
00415 planeEquation[2] = plane->GetNormal()[2];
00416 planeEquation[3] = -(planeEquation[0]*plane->GetOrigin()[0]+
00417 planeEquation[1]*plane->GetOrigin()[1]+
00418 planeEquation[2]*plane->GetOrigin()[2]);
00419 glClipPlane(static_cast<GLenum>(GL_CLIP_PLANE0+i),planeEquation);
00420 }
00421 }
00422
00423
00424
00425
00426 glMatrixMode( GL_MODELVIEW );
00427 glPushMatrix();
00428 glMultMatrixd(matrix->Element[0]);
00429
00430 glColor4f( 1.0, 1.0, 1.0, 1.0 );
00431
00432
00433 glDisable( GL_LIGHTING );
00434
00435 vtkGraphicErrorMacro(ren->GetRenderWindow(),"Before actual render method");
00436
00437 this->RenderFP(ren,vol);
00438
00439
00440 glMatrixMode( GL_MODELVIEW );
00441 glPopMatrix();
00442
00443 matrix->Delete();
00444 glPopAttrib();
00445 }
00446
00447 void vtkMitkOpenGLVolumeTextureMapper3D::RenderFP(vtkRenderer *ren,
00448 vtkVolume *vol)
00449 {
00450
00451
00452
00453
00454
00455
00456
00457 glEnable( GL_BLEND );
00458 glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
00459
00460 int components = this->GetInput()->GetNumberOfScalarComponents();
00461 switch ( components )
00462 {
00463 case 1:
00464 this->RenderOneIndependentShadeFP(ren,vol);
00465 break;
00466
00467 case 4:
00468 this->RenderRGBAShadeFP(ren,vol);
00469 break;
00470 }
00471
00472 vtkgl::ActiveTexture( vtkgl::TEXTURE2);
00473 glDisable( GL_TEXTURE_2D );
00474 glDisable( vtkgl::TEXTURE_3D );
00475
00476 vtkgl::ActiveTexture( vtkgl::TEXTURE1);
00477 glDisable( GL_TEXTURE_2D );
00478 glDisable( vtkgl::TEXTURE_3D );
00479
00480 vtkgl::ActiveTexture( vtkgl::TEXTURE0);
00481 glDisable( GL_TEXTURE_2D );
00482 glDisable( vtkgl::TEXTURE_3D );
00483
00484 glDisable( GL_BLEND );
00485 }
00486
00487 void vtkMitkOpenGLVolumeTextureMapper3D::DeleteTextureIndex( GLuint *index )
00488 {
00489
00490
00491 if (glIsTexture(*index))
00492 {
00493 GLuint tempIndex;
00494 tempIndex = *index;
00495 glDeleteTextures(1, &tempIndex);
00496 *index = 0;
00497 }
00498 }
00499
00500 void vtkMitkOpenGLVolumeTextureMapper3D::CreateTextureIndex( GLuint *index )
00501 {
00502
00503
00504 GLuint tempIndex=0;
00505 glGenTextures(1, &tempIndex);
00506 *index = static_cast<long>(tempIndex);
00507 }
00508
00509 void vtkMitkOpenGLVolumeTextureMapper3D::RenderPolygons( vtkRenderer *ren,
00510 vtkVolume *vol,
00511 int stages[4] )
00512 {
00513
00514
00515 vtkRenderWindow *renWin = ren->GetRenderWindow();
00516
00517 if ( renWin->CheckAbortStatus() )
00518 {
00519 return;
00520 }
00521
00522 double bounds[27][6];
00523 float distance2[27];
00524
00525 int numIterations;
00526 int i, j, k;
00527
00528
00529 if ( !this->Cropping )
00530 {
00531
00532
00533 this->GetInput()->GetBounds(bounds[0]);
00534 numIterations = 1;
00535 }
00536
00537 else if ( this->CroppingRegionFlags == 0x2000 )
00538 {
00539 this->GetCroppingRegionPlanes(bounds[0]);
00540 numIterations = 1;
00541 }
00542
00543 else
00544 {
00545
00546 double camPos[4];
00547 ren->GetActiveCamera()->GetPosition(camPos);
00548
00549 double volBounds[6];
00550 this->GetInput()->GetBounds(volBounds);
00551
00552
00553
00554 vtkMatrix4x4 *volMatrix = vtkMatrix4x4::New();
00555 vol->GetMatrix( volMatrix );
00556 camPos[3] = 1.0;
00557 volMatrix->Invert();
00558 volMatrix->MultiplyPoint( camPos, camPos );
00559 volMatrix->Delete();
00560 if ( camPos[3] )
00561 {
00562 camPos[0] /= camPos[3];
00563 camPos[1] /= camPos[3];
00564 camPos[2] /= camPos[3];
00565 }
00566
00567
00568
00569
00570
00571 float limit[12];
00572 for ( i = 0; i < 3; i++ )
00573 {
00574 limit[i*4 ] = volBounds[i*2];
00575 limit[i*4+1] = this->CroppingRegionPlanes[i*2];
00576 limit[i*4+2] = this->CroppingRegionPlanes[i*2+1];
00577 limit[i*4+3] = volBounds[i*2+1];
00578 }
00579
00580
00581
00582
00583 int numRegions = 0;
00584 int region;
00585 for ( region = 0; region < 27; region++ )
00586 {
00587 int regionFlag = 1<<region;
00588
00589 if ( this->CroppingRegionFlags & regionFlag )
00590 {
00591
00592 int loc[3];
00593 loc[0] = region%3;
00594 loc[1] = (region/3)%3;
00595 loc[2] = (region/9)%3;
00596
00597
00598 float center[3];
00599 for ( i = 0; i < 3; i++ )
00600 {
00601 bounds[numRegions][i*2 ] = limit[4*i+loc[i]];
00602 bounds[numRegions][i*2+1] = limit[4*i+loc[i]+1];
00603 center[i] =
00604 (bounds[numRegions][i*2 ] +
00605 bounds[numRegions][i*2+1])/2.0;
00606 }
00607
00608
00609 distance2[numRegions] =
00610 (camPos[0]-center[0])*(camPos[0]-center[0]) +
00611 (camPos[1]-center[1])*(camPos[1]-center[1]) +
00612 (camPos[2]-center[2])*(camPos[2]-center[2]);
00613
00614
00615 numRegions++;
00616 }
00617 }
00618
00619
00620 for ( i = 1; i < numRegions; i++ )
00621 {
00622 for ( j = i; j > 0 && distance2[j] > distance2[j-1]; j-- )
00623 {
00624 float tmpBounds[6];
00625 float tmpDistance2;
00626
00627 for ( k = 0; k < 6; k++ )
00628 {
00629 tmpBounds[k] = bounds[j][k];
00630 }
00631 tmpDistance2 = distance2[j];
00632
00633 for ( k = 0; k < 6; k++ )
00634 {
00635 bounds[j][k] = bounds[j-1][k];
00636 }
00637 distance2[j] = distance2[j-1];
00638
00639 for ( k = 0; k < 6; k++ )
00640 {
00641 bounds[j-1][k] = tmpBounds[k];
00642 }
00643 distance2[j-1] = tmpDistance2;
00644
00645 }
00646 }
00647
00648 numIterations = numRegions;
00649 }
00650
00651
00652 for ( int loop = 0;
00653 loop < numIterations;
00654 loop++ )
00655 {
00656
00657
00658 this->ComputePolygons( ren, vol, bounds[loop] );
00659
00660
00661 for ( i = 0; i < this->NumberOfPolygons; i++ )
00662 {
00663
00664 if ( renWin->CheckAbortStatus() )
00665 {
00666 return;
00667 }
00668
00669 float *ptr = this->PolygonBuffer + 36*i;
00670
00671 glBegin( GL_TRIANGLE_FAN );
00672
00673 for ( j = 0; j < 6; j++ )
00674 {
00675 if ( ptr[0] < 0.0 )
00676 {
00677 break;
00678 }
00679
00680 for ( k = 0; k < 4; k++ )
00681 {
00682 if ( stages[k] )
00683 {
00684 vtkgl::MultiTexCoord3fv( vtkgl::TEXTURE0 + k, ptr );
00685 }
00686 }
00687 glVertex3fv( ptr+3 );
00688
00689 ptr += 6;
00690 }
00691 glEnd();
00692 }
00693 }
00694 }
00695
00696
00697
00698
00699
00700
00701
00702
00703
00704
00705
00706
00707
00708
00709
00710
00711
00712
00713
00714
00715
00716
00717
00718
00719
00720
00721 template <class T>
00722 class ScalarGradientCompute
00723 {
00724 T *dataPtr;
00725 unsigned char *tmpPtr;
00726 unsigned char *tmpPtr2;
00727 int sizeX;
00728 int sizeY;
00729 int sizeZ;
00730 int sizeXY;
00731 int sizeXm1;
00732 int sizeYm1;
00733 int sizeZm1;
00734 int fullX;
00735 int fullY;
00736 int fullZ;
00737 int fullXY;
00738 int currentChunkStart;
00739 int currentChunkEnd;
00740
00741 int offZ;
00742
00743 float offset;
00744 float scale;
00745
00746 public:
00747
00748 ScalarGradientCompute( T *_dataPtr,unsigned char *_tmpPtr,unsigned char *_tmpPtr2,int _sizeX,int _sizeY,int _sizeZ,int _fullX,int _fullY,int _fullZ,float _offset,float _scale)
00749 {
00750 dataPtr=_dataPtr;
00751 tmpPtr=_tmpPtr;
00752 tmpPtr2=_tmpPtr2;
00753 sizeX=_sizeX;
00754 sizeY=_sizeY;
00755 sizeZ=_sizeZ;
00756 fullX=_fullX;
00757 fullY=_fullY;
00758 fullZ=_fullZ;
00759 offset=_offset;
00760 scale=_scale;
00761
00762 sizeXY=sizeX*sizeY;
00763 sizeXm1=sizeX-1;
00764 sizeYm1=sizeY-1;
00765 sizeZm1=sizeZ-1;
00766
00767 fullXY=fullX*fullY;
00768 }
00769
00770 inline float sample(int x,int y,int z)
00771 {
00772 return float(dataPtr[ x + y * sizeX + z * sizeXY ]);
00773 }
00774
00775 inline void fill(int x,int y,int z)
00776 {
00777 int doff = x + y * fullX + (z-offZ) * fullXY;
00778
00779 tmpPtr[doff*4+0]= 0;
00780 tmpPtr[doff*4+1]= 0;
00781 tmpPtr[doff*4+2]= 0;
00782 tmpPtr[doff*4+3]= 0;
00783
00784
00785
00786
00787
00788 }
00789
00790 inline int clamp(int x)
00791 {
00792 if(x<0) x=0; else if(x>255) x=255;
00793 return x;
00794 }
00795
00796 inline void write(int x,int y,int z,float grayValue,float gx,float gy,float gz)
00797 {
00798
00799
00800
00801
00802
00803
00804
00805
00806 int iGrayValue = static_cast<int>( (grayValue + offset) * scale + 0.5f );
00807
00808 gx *= scale;
00809 gy *= scale;
00810 gz *= scale;
00811
00812 float t = sqrtf( gx*gx + gy*gy + gz*gz );
00813
00814 if ( t > 0.01f )
00815 {
00816 if( t < 2.0f )
00817 {
00818 float fac = 2.0f/t;
00819 gx *= fac;
00820 gy *= fac;
00821 gz *= fac;
00822 }
00823 else if( t > 255.0f)
00824 {
00825 float fac = 255.0f/t;
00826 gx *= fac;
00827 gy *= fac;
00828 gz *= fac;
00829 }
00830 }
00831 else
00832 {
00833 gx=gy=gz=0.0f;
00834 }
00835
00836 int nx = static_cast<int>(0.5f*gx+127.5f);
00837 int ny = static_cast<int>(0.5f*gy+127.5f);
00838 int nz = static_cast<int>(0.5f*gz+127.5f);
00839
00840 int doff = x + y * fullX + (z-offZ) * fullXY;
00841
00842
00843
00844 tmpPtr[doff*4+0]= clamp(nx);
00845 tmpPtr[doff*4+1]= clamp(ny);
00846 tmpPtr[doff*4+2]= clamp(nz);
00847 tmpPtr[doff*4+3]= clamp(iGrayValue);
00848
00849
00850
00851
00852
00853
00854 }
00855
00856
00857 inline void compute(int x,int y,int z)
00858 {
00859 float grayValue = sample(x,y,z);
00860 float gx,gy,gz;
00861
00862 gx = sample(x+1,y,z) - sample(x-1,y,z);
00863 gy = sample(x,y+1,z) - sample(x,y-1,z);
00864 gz = sample(x,y,z+1) - sample(x,y,z-1);
00865
00866 write( x, y, z, grayValue, gx, gy, gz );
00867
00868 }
00869
00870 inline void computeClamp(int x,int y,int z)
00871 {
00872 float grayValue = sample(x,y,z);
00873 float gx,gy,gz;
00874
00875 if(x==0) gx = 2.0f * ( sample(x+1,y,z) - grayValue );
00876 else if(x==sizeXm1) gx = 2.0f * ( grayValue - sample(x-1,y,z) );
00877 else gx = sample(x+1,y,z) - sample(x-1,y,z);
00878
00879 if(y==0) gy = 2.0f * ( sample(x,y+1,z) - grayValue );
00880 else if(y==sizeYm1) gy = 2.0f * ( grayValue - sample(x,y-1,z) );
00881 else gy = sample(x,y+1,z) - sample(x,y-1,z);
00882
00883 if(z==0) gz = 2.0f * ( sample(x,y,z+1) - grayValue );
00884 else if(z==sizeZm1) gz = 2.0f * ( grayValue - sample(x,y,z-1) );
00885 else gz = sample(x,y,z+1) - sample(x,y,z-1);
00886
00887 write( x, y, z, grayValue, gx, gy, gz );
00888 }
00889
00890 inline void compute1D(int y,int z)
00891 {
00892 int x;
00893
00894 x=0;
00895 computeClamp(x,y,z);
00896 x++;
00897
00898 while(x<sizeX-1)
00899 {
00900 compute(x,y,z);
00901 x++;
00902 }
00903
00904 if(x<sizeX)
00905 {
00906 computeClamp(x,y,z);
00907 x++;
00908 }
00909
00910 while(x<fullX)
00911 {
00912 fill(x,y,z);
00913 x++;
00914 }
00915 }
00916
00917 inline void fill1D(int y,int z)
00918 {
00919 int x;
00920
00921 x=0;
00922 while(x<fullX)
00923 {
00924 fill(x,y,z);
00925 x++;
00926 }
00927 }
00928
00929
00930 inline void computeClamp1D(int y,int z)
00931 {
00932 int x;
00933
00934 x=0;
00935
00936 while(x<sizeX)
00937 {
00938 computeClamp(x,y,z);
00939 x++;
00940 }
00941
00942 while(x<fullX)
00943 {
00944 fill(x,y,z);
00945 x++;
00946 }
00947 }
00948
00949 inline void computeClamp2D(int z)
00950 {
00951 int y;
00952
00953 y=0;
00954
00955 while(y<sizeY)
00956 {
00957 computeClamp1D(y,z);
00958 y++;
00959 }
00960
00961 while(y<fullY)
00962 {
00963 fill1D(y,z);
00964 y++;
00965 }
00966 }
00967
00968 inline void compute2D(int z)
00969 {
00970 int y;
00971
00972 y=0;
00973 computeClamp1D(y,z);
00974 y++;
00975
00976 while(y<sizeY-1)
00977 {
00978 compute1D(y,z);
00979 y++;
00980 }
00981
00982 if(y<sizeY)
00983 {
00984 computeClamp1D(y,z);
00985 y++;
00986 }
00987
00988 while(y<fullY)
00989 {
00990 fill1D(y,z);
00991 y++;
00992 }
00993 }
00994
00995 inline void fill2D(int z)
00996 {
00997 int y;
00998
00999 y=0;
01000 while(y<fullY)
01001 {
01002 fill1D(y,z);
01003 y++;
01004 }
01005 }
01006
01007 inline void fillSlices(int currentChunkStart,int currentChunkEnd)
01008 {
01009 offZ=currentChunkStart;
01010
01011
01012
01013
01014
01015
01016 #pragma omp parallel for
01017 for(int z=currentChunkStart;z<=currentChunkEnd;z++)
01018 {
01019 if(z==0 || z==sizeZ-1)
01020 computeClamp2D(z);
01021 else if(z>=sizeZ)
01022 fill2D(z);
01023 else
01024 compute2D(z);
01025 }
01026 }
01027 };
01028
01029
01030
01031 template <class T>
01032 void vtkVolumeTextureMapper3DComputeScalars( T *dataPtr,
01033 vtkMitkVolumeTextureMapper3D *me,
01034 float offset, float scale,
01035 GLuint volume1,
01036 GLuint )
01037 {
01038 T *inPtr;
01039
01040
01041
01042
01043 int inputDimensions[3];
01044 double inputSpacing[3];
01045 vtkImageData *input = me->GetInput();
01046
01047 input->GetDimensions( inputDimensions );
01048 input->GetSpacing( inputSpacing );
01049
01050 int outputDimensions[3];
01051 float outputSpacing[3];
01052 me->GetVolumeDimensions( outputDimensions );
01053 me->GetVolumeSpacing( outputSpacing );
01054
01055
01056
01057
01058
01059
01060
01061 double sampleRate[3];
01062 sampleRate[0] = outputSpacing[0] / static_cast<double>(inputSpacing[0]);
01063 sampleRate[1] = outputSpacing[1] / static_cast<double>(inputSpacing[1]);
01064 sampleRate[2] = outputSpacing[2] / static_cast<double>(inputSpacing[2]);
01065
01066 int fullX = outputDimensions[0];
01067 int fullY = outputDimensions[1];
01068 int fullZ = outputDimensions[2];
01069
01070 int sizeX = inputDimensions[0];
01071 int sizeY = inputDimensions[1];
01072 int sizeZ = inputDimensions[2];
01073
01074 int chunkSize = 64;
01075
01076 if(fullZ < chunkSize) chunkSize=fullZ;
01077
01078 int numChunks = ( fullZ + (chunkSize-1) ) / chunkSize;
01079
01080 inPtr = dataPtr;
01081
01082 unsigned char *tmpPtr = new unsigned char[fullX*fullY*chunkSize*4];
01083 unsigned char *tmpPtr2 = 0;
01084
01085
01086 {
01087 ScalarGradientCompute<T> sgc(dataPtr,tmpPtr,tmpPtr2,sizeX,sizeY,sizeZ,fullX,fullY,fullZ,offset,scale);
01088
01089 int currentChunk = 0;
01090
01091 while(currentChunk < numChunks)
01092 {
01093
01094
01095 int currentChunkStart = currentChunk * chunkSize;
01096 int currentChunkEnd = currentChunkStart + chunkSize - 1 ;
01097
01098 if( currentChunkEnd > (fullZ-1) )
01099 currentChunkEnd = (fullZ-1);
01100
01101 int currentChunkSize = currentChunkEnd - currentChunkStart + 1;
01102
01103 sgc.fillSlices( currentChunkStart , currentChunkEnd );
01104
01105 glBindTexture(vtkgl::TEXTURE_3D, volume1);
01106 vtkgl::TexSubImage3D(vtkgl::TEXTURE_3D,0,0,0,currentChunkStart,fullX,fullY,currentChunkSize,GL_RGBA,GL_UNSIGNED_BYTE,tmpPtr);
01107
01108
01109
01110
01111 currentChunk ++;
01112 }
01113 }
01114
01115 delete tmpPtr;
01116
01117 }
01118
01119
01120 class RGBACompute
01121 {
01122 unsigned char *dataPtr;
01123 unsigned char *tmpPtr;
01124 unsigned char *tmpPtr2;
01125 int sizeX;
01126 int sizeY;
01127 int sizeZ;
01128 int sizeXY;
01129 int sizeXm1;
01130 int sizeYm1;
01131 int sizeZm1;
01132 int fullX;
01133 int fullY;
01134 int fullZ;
01135 int fullXY;
01136 int currentChunkStart;
01137 int currentChunkEnd;
01138
01139 int offZ;
01140
01141 public:
01142
01143 RGBACompute( unsigned char *_dataPtr,unsigned char *_tmpPtr,unsigned char *_tmpPtr2,int _sizeX,int _sizeY,int _sizeZ,int _fullX,int _fullY,int _fullZ)
01144 {
01145 dataPtr=_dataPtr;
01146 tmpPtr=_tmpPtr;
01147 tmpPtr2=_tmpPtr2;
01148 sizeX=_sizeX;
01149 sizeY=_sizeY;
01150 sizeZ=_sizeZ;
01151 fullX=_fullX;
01152 fullY=_fullY;
01153 fullZ=_fullZ;
01154
01155 sizeXY=sizeX*sizeY;
01156 sizeXm1=sizeX-1;
01157 sizeYm1=sizeY-1;
01158 sizeZm1=sizeZ-1;
01159
01160 fullXY=fullX*fullY;
01161 }
01162
01163 inline int sample(int x,int y,int z)
01164 {
01165 return dataPtr[ ( x + y * sizeX + z * sizeXY ) * 4 +3 ];
01166 }
01167
01168 inline void fill(int x,int y,int z)
01169 {
01170 int doff = x + y * fullX + (z-offZ) * fullXY;
01171
01172 tmpPtr[doff*4+0]= 0;
01173 tmpPtr[doff*4+1]= 0;
01174 tmpPtr[doff*4+2]= 0;
01175 tmpPtr[doff*4+3]= 0;
01176
01177 tmpPtr2[doff*3+0]= 0;
01178 tmpPtr2[doff*3+1]= 0;
01179 tmpPtr2[doff*3+2]= 0;
01180 }
01181
01182 inline int clamp(int x)
01183 {
01184 if(x<0) x=0; else if(x>255) x=255;
01185 return x;
01186 }
01187
01188 inline void write(int x,int y,int z,int iGrayValue,int gx,int gy,int gz)
01189 {
01190
01191
01192
01193
01194
01195
01196 int nx = static_cast<int>(0.5f*gx+127.5f);
01197 int ny = static_cast<int>(0.5f*gy+127.5f);
01198 int nz = static_cast<int>(0.5f*gz+127.5f);
01199
01200 int doff = x + y * fullX + (z-offZ) * fullXY;
01201
01202
01203
01204 tmpPtr[doff*4+0]= clamp(nx);
01205 tmpPtr[doff*4+1]= clamp(ny);
01206 tmpPtr[doff*4+2]= clamp(nz);
01207 tmpPtr[doff*4+3]= clamp(iGrayValue);
01208
01209 int soff = x + y * sizeX + z * sizeXY;
01210
01211 tmpPtr2[doff*3+0]= dataPtr[soff*4+0];
01212 tmpPtr2[doff*3+1]= dataPtr[soff*4+1];
01213 tmpPtr2[doff*3+2]= dataPtr[soff*4+2];
01214
01215
01216
01217
01218
01219
01220 }
01221
01222
01223 inline void compute(int x,int y,int z)
01224 {
01225 int grayValue = sample(x,y,z);
01226 int gx,gy,gz;
01227
01228 gx = sample(x+1,y,z) - sample(x-1,y,z);
01229 gy = sample(x,y+1,z) - sample(x,y-1,z);
01230 gz = sample(x,y,z+1) - sample(x,y,z-1);
01231
01232 write( x, y, z, grayValue, gx, gy, gz );
01233
01234 }
01235
01236 inline void computeClamp(int x,int y,int z)
01237 {
01238 int grayValue = sample(x,y,z);
01239 int gx,gy,gz;
01240
01241 if(x==0) gx = 2 * ( sample(x+1,y,z) - grayValue );
01242 else if(x==sizeXm1) gx = 2 * ( grayValue - sample(x-1,y,z) );
01243 else gx = sample(x+1,y,z) - sample(x-1,y,z);
01244
01245 if(y==0) gy = 2 * ( sample(x,y+1,z) - grayValue );
01246 else if(y==sizeYm1) gy = 2 * ( grayValue - sample(x,y-1,z) );
01247 else gy = sample(x,y+1,z) - sample(x,y-1,z);
01248
01249 if(z==0) gz = 2 * ( sample(x,y,z+1) - grayValue );
01250 else if(z==sizeZm1) gz = 2 * ( grayValue - sample(x,y,z-1) );
01251 else gz = sample(x,y,z+1) - sample(x,y,z-1);
01252
01253 write( x, y, z, grayValue, gx, gy, gz );
01254 }
01255
01256 inline void compute1D(int y,int z)
01257 {
01258 int x=0;
01259
01260 computeClamp(x,y,z);
01261 x++;
01262
01263 while(x<sizeX-1) {
01264 compute(x,y,z);
01265 x++;
01266 }
01267
01268 if(x<sizeX) {
01269 computeClamp(x,y,z);
01270 x++;
01271 }
01272
01273 while(x<fullX) {
01274 fill(x,y,z);
01275 x++;
01276 }
01277 }
01278
01279 inline void fill1D(int y,int z)
01280 {
01281 int x=0;
01282
01283 while(x<fullX) {
01284 fill(x,y,z);
01285 x++;
01286 }
01287 }
01288
01289
01290 inline void computeClamp1D(int y,int z)
01291 {
01292 int x=0;
01293
01294 while(x<sizeX) {
01295 computeClamp(x,y,z);
01296 x++;
01297 }
01298
01299 while(x<fullX) {
01300 fill(x,y,z);
01301 x++;
01302 }
01303 }
01304
01305 inline void computeClamp2D(int z)
01306 {
01307 int y=0;
01308
01309 while(y<sizeY) {
01310 computeClamp1D(y,z);
01311 y++;
01312 }
01313
01314 while(y<fullY) {
01315 fill1D(y,z);
01316 y++;
01317 }
01318 }
01319
01320 inline void compute2D(int z)
01321 {
01322 int y=0;
01323
01324 computeClamp1D(y,z);
01325 y++;
01326
01327 while(y<sizeY-1) {
01328 compute1D(y,z);
01329 y++;
01330 }
01331
01332 if(y<sizeY) {
01333 computeClamp1D(y,z);
01334 y++;
01335 }
01336
01337 while(y<fullY) {
01338 fill1D(y,z);
01339 y++;
01340 }
01341 }
01342
01343 inline void fill2D(int z)
01344 {
01345 int y=0;
01346
01347 while(y<fullY) {
01348 fill1D(y,z);
01349 y++;
01350 }
01351 }
01352
01353 inline void fillSlices(int currentChunkStart,int currentChunkEnd)
01354 {
01355 offZ=currentChunkStart;
01356
01357 #pragma omp parallel for
01358 for(int z=currentChunkStart;z<=currentChunkEnd;z++)
01359 {
01360 if(z==0 || z==sizeZ-1) computeClamp2D(z);
01361 else if(z>=sizeZ) fill2D(z);
01362 else compute2D(z);
01363 }
01364 }
01365 };
01366
01367
01368 void vtkVolumeTextureMapper3DComputeRGBA( unsigned char *dataPtr,
01369 vtkMitkVolumeTextureMapper3D *me,
01370 GLuint volume1,
01371 GLuint volume2)
01372 {
01373 unsigned char *inPtr;
01374
01375
01376
01377
01378 int inputDimensions[3];
01379 double inputSpacing[3];
01380 vtkImageData *input = me->GetInput();
01381
01382 input->GetDimensions( inputDimensions );
01383 input->GetSpacing( inputSpacing );
01384
01385 int outputDimensions[3];
01386 float outputSpacing[3];
01387 me->GetVolumeDimensions( outputDimensions );
01388 me->GetVolumeSpacing( outputSpacing );
01389
01390 int components = input->GetNumberOfScalarComponents();
01391
01392 MITK_INFO << "components are " << components;
01393
01394
01395
01396
01397
01398 double sampleRate[3];
01399 sampleRate[0] = outputSpacing[0] / static_cast<double>(inputSpacing[0]);
01400 sampleRate[1] = outputSpacing[1] / static_cast<double>(inputSpacing[1]);
01401 sampleRate[2] = outputSpacing[2] / static_cast<double>(inputSpacing[2]);
01402
01403 int fullX = outputDimensions[0];
01404 int fullY = outputDimensions[1];
01405 int fullZ = outputDimensions[2];
01406
01407 int sizeX = inputDimensions[0];
01408 int sizeY = inputDimensions[1];
01409 int sizeZ = inputDimensions[2];
01410
01411 int chunkSize = 64;
01412
01413 if(fullZ < chunkSize) chunkSize=fullZ;
01414
01415 int numChunks = ( fullZ + (chunkSize-1) ) / chunkSize;
01416
01417 inPtr = dataPtr;
01418
01419 unsigned char *tmpPtr = new unsigned char[fullX*fullY*chunkSize*4];
01420 unsigned char *tmpPtr2 = new unsigned char[fullX*fullY*chunkSize*3];
01421
01422
01423 {
01424 RGBACompute sgc(dataPtr,tmpPtr,tmpPtr2,sizeX,sizeY,sizeZ,fullX,fullY,fullZ);
01425
01426 int currentChunk = 0;
01427
01428 while(currentChunk < numChunks)
01429 {
01430
01431
01432 int currentChunkStart = currentChunk * chunkSize;
01433 int currentChunkEnd = currentChunkStart + chunkSize - 1 ;
01434
01435 if( currentChunkEnd > (fullZ-1) )
01436 currentChunkEnd = (fullZ-1);
01437
01438 int currentChunkSize = currentChunkEnd - currentChunkStart + 1;
01439
01440 sgc.fillSlices( currentChunkStart , currentChunkEnd );
01441
01442 glBindTexture(vtkgl::TEXTURE_3D, volume1);
01443 vtkgl::TexSubImage3D(vtkgl::TEXTURE_3D,0,0,0,currentChunkStart,fullX,fullY,currentChunkSize,GL_RGBA,GL_UNSIGNED_BYTE,tmpPtr);
01444
01445 glBindTexture(vtkgl::TEXTURE_3D, volume2);
01446 vtkgl::TexSubImage3D(vtkgl::TEXTURE_3D,0,0,0,currentChunkStart,fullX,fullY,currentChunkSize,GL_RGB,GL_UNSIGNED_BYTE,tmpPtr2);
01447
01448 currentChunk ++;
01449 }
01450 }
01451
01452 delete tmpPtr;
01453 delete tmpPtr2;
01454 }
01455
01456
01457
01458 void vtkMitkOpenGLVolumeTextureMapper3D::ComputeVolumeDimensions()
01459 {
01460
01461 vtkImageData *input = this->GetInput();
01462
01463
01464 int dim[3];
01465 input->GetDimensions(dim);
01466
01467 int powerOfTwoDim[3];
01468
01469 if(this->SupportsNonPowerOfTwoTextures)
01470 {
01471 for ( int i = 0; i < 3; i++ )
01472 powerOfTwoDim[i]=(dim[i]+1)&~1;
01473
01474
01475 }
01476 else
01477 {
01478 for ( int i = 0; i < 3; i++ )
01479 {
01480 powerOfTwoDim[i] = 4;
01481 while ( powerOfTwoDim[i] < dim[i] )
01482 powerOfTwoDim[i] *= 2;
01483 }
01484
01485 MITK_WARN << "using power-two textures (" << (1.0-double(dim[0]*dim[1]*dim[2])/double(powerOfTwoDim[0]*powerOfTwoDim[1]*powerOfTwoDim[2])) * 100.0 << "% memory wasted)";
01486 }
01487
01488
01489 this->VolumeDimensions[0] = powerOfTwoDim[0];
01490 this->VolumeDimensions[1] = powerOfTwoDim[1];
01491 this->VolumeDimensions[2] = powerOfTwoDim[2];
01492
01493
01494 double spacing[3];
01495 input->GetSpacing(spacing);
01496
01497
01498 this->VolumeSpacing[0] = ( dim[0] -1.01)*spacing[0] / static_cast<double>(this->VolumeDimensions[0]-1);
01499 this->VolumeSpacing[1] = ( dim[1] -1.01)*spacing[1] / static_cast<double>(this->VolumeDimensions[1]-1);
01500 this->VolumeSpacing[2] = ((dim[2])-1.01)*spacing[2] / static_cast<double>(this->VolumeDimensions[2]-1);
01501 }
01502
01503
01504 bool vtkMitkOpenGLVolumeTextureMapper3D::UpdateVolumes(vtkVolume *vtkNotUsed(vol))
01505 {
01506
01507 vtkImageData *input = this->GetInput();
01508 input->Update();
01509
01510 bool needUpdate = false;
01511
01512
01513 if ( this->SavedTextureInput != input || this->SavedTextureMTime.GetMTime() < input->GetMTime() )
01514 needUpdate = true;
01515
01516
01517 if(!this->Volume1Index)
01518 needUpdate = true;
01519
01520 if(!needUpdate)
01521 return true;
01522
01523 ComputeVolumeDimensions();
01524
01525 int components = input->GetNumberOfScalarComponents();
01526
01527
01528 double scalarRange[2];
01529 input->GetPointData()->GetScalars()->GetRange(scalarRange, components-1);
01530
01531
01532
01533
01534
01535
01536
01537 float offset;
01538 float scale;
01539
01540 int arraySizeNeeded;
01541
01542 int scalarType = input->GetScalarType();
01543
01544 if ( scalarType == VTK_FLOAT || scalarType == VTK_DOUBLE || scalarRange[1] - scalarRange[0] > 255 )
01545 {
01546 arraySizeNeeded = 256;
01547 offset = -scalarRange[0];
01548 scale = 255.0 / (scalarRange[1] - scalarRange[0]);
01549 }
01550 else
01551 {
01552 arraySizeNeeded = static_cast<int>(scalarRange[1] - scalarRange[0] + 1);
01553 offset = -scalarRange[0];
01554 scale = 1.0;
01555 }
01556
01557 this->ColorTableSize = arraySizeNeeded;
01558 this->ColorTableOffset = offset;
01559 this->ColorTableScale = scale;
01560
01561
01562 {
01563
01564 this->DeleteTextureIndex(&this->Volume1Index);
01565 this->DeleteTextureIndex(&this->Volume2Index);
01566 this->DeleteTextureIndex(&this->Volume3Index);
01567
01568 this->CreateTextureIndex(&this->Volume1Index);
01569
01570
01571 int dim[3]; this->GetVolumeDimensions(dim);
01572
01573 vtkgl::ActiveTexture( vtkgl::TEXTURE0 );
01574
01575 MITK_INFO << "allocating volume on gpu";
01576
01577 GLint gradientScalarTextureFormat = GL_RGBA8;
01578
01579 if(this->UseCompressedTexture && SupportsCompressedTexture)
01580 gradientScalarTextureFormat = myGL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
01581
01582 glBindTexture(vtkgl::TEXTURE_3D, this->Volume1Index);
01583 vtkgl::TexImage3D(vtkgl::TEXTURE_3D,0,gradientScalarTextureFormat,dim[0],dim[1],dim[2],0,GL_RGBA,GL_UNSIGNED_BYTE,0);
01584 this->Setup3DTextureParameters( true );
01585 }
01586
01587
01588 void *dataPtr = input->GetScalarPointer();
01589
01590 switch ( scalarType )
01591 {
01592 vtkTemplateMacro(
01593 vtkVolumeTextureMapper3DComputeScalars(
01594 static_cast<VTK_TT *>(dataPtr), this,
01595 offset, scale,
01596 this->Volume1Index,
01597 this->Volume2Index));
01598 }
01599
01600 this->SavedTextureInput = input;
01601 this->SavedTextureMTime.Modified();
01602
01603 return true;
01604 }
01605
01606
01607
01608 bool vtkMitkOpenGLVolumeTextureMapper3D::UpdateVolumesRGBA(vtkVolume *vtkNotUsed(vol))
01609 {
01610
01611 vtkImageData *input = this->GetInput();
01612 input->Update();
01613
01614 bool needUpdate = false;
01615
01616
01617 if ( this->SavedTextureInput != input || this->SavedTextureMTime.GetMTime() < input->GetMTime() )
01618 needUpdate = true;
01619
01620
01621 if(!this->Volume1Index)
01622 needUpdate = true;
01623
01624 if(!needUpdate)
01625 return true;
01626
01627 MITK_INFO << "updating rgba volume";
01628
01629 ComputeVolumeDimensions();
01630
01631
01632 {
01633
01634 this->DeleteTextureIndex(&this->Volume1Index);
01635 this->DeleteTextureIndex(&this->Volume2Index);
01636 this->DeleteTextureIndex(&this->Volume3Index);
01637
01638 this->CreateTextureIndex(&this->Volume1Index);
01639 this->CreateTextureIndex(&this->Volume2Index);
01640
01641 int dim[3]; this->GetVolumeDimensions(dim);
01642
01643 MITK_INFO << "allocating volume on gpu";
01644
01645 GLint gradientScalarTextureFormat = GL_RGBA8;
01646 GLint colorTextureFormat = GL_RGB8;
01647
01648 if(this->UseCompressedTexture && SupportsCompressedTexture)
01649 {
01650 gradientScalarTextureFormat = myGL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
01651 colorTextureFormat = myGL_COMPRESSED_RGB_S3TC_DXT1_EXT;
01652 }
01653
01654 vtkgl::ActiveTexture( vtkgl::TEXTURE0 );
01655 glBindTexture(vtkgl::TEXTURE_3D, this->Volume1Index);
01656 vtkgl::TexImage3D(vtkgl::TEXTURE_3D,0,gradientScalarTextureFormat,dim[0],dim[1],dim[2],0,GL_RGBA,GL_UNSIGNED_BYTE,0);
01657 this->Setup3DTextureParameters( true );
01658
01659 glBindTexture(vtkgl::TEXTURE_3D, this->Volume2Index);
01660 vtkgl::TexImage3D(vtkgl::TEXTURE_3D,0,colorTextureFormat,dim[0],dim[1],dim[2],0,GL_RGB,GL_UNSIGNED_BYTE,0);
01661 this->Setup3DTextureParameters( true );
01662 }
01663
01664
01665 unsigned char *dataPtr = (unsigned char*)input->GetScalarPointer();
01666 vtkVolumeTextureMapper3DComputeRGBA( dataPtr, this, this->Volume1Index, this->Volume2Index);
01667
01668 this->SavedTextureInput = input;
01669 this->SavedTextureMTime.Modified();
01670
01671 return true;
01672 }
01673
01674 void vtkMitkOpenGLVolumeTextureMapper3D::Setup3DTextureParameters( bool linear )
01675 {
01676
01677
01678 if( linear )
01679 {
01680 glTexParameterf( vtkgl::TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
01681 glTexParameterf( vtkgl::TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
01682 }
01683 else
01684 {
01685 glTexParameterf( vtkgl::TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
01686 glTexParameterf( vtkgl::TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
01687 }
01688
01689 glTexParameterf( vtkgl::TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP );
01690 glTexParameterf( vtkgl::TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP );
01691 }
01692
01693 void vtkMitkOpenGLVolumeTextureMapper3D::SetupOneIndependentTextures( vtkRenderer *vtkNotUsed(ren), vtkVolume *vol )
01694 {
01695
01696 this->UpdateVolumes( vol );
01697
01698
01699
01700 if ( this->UpdateColorLookup( vol ) || !this->ColorLookupIndex )
01701 {
01702 this->DeleteTextureIndex( &this->ColorLookupIndex );
01703 this->DeleteTextureIndex( &this->AlphaLookupIndex );
01704
01705 this->CreateTextureIndex( &this->ColorLookupIndex );
01706
01707 vtkgl::ActiveTexture( vtkgl::TEXTURE1 );
01708 glBindTexture(GL_TEXTURE_2D, this->ColorLookupIndex);
01709
01710 glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
01711 glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
01712 glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP );
01713 glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP );
01714
01715
01716
01717 GLint colorLookupTextureFormat = GL_RGBA8;
01718
01719 if(this->UseCompressedTexture && SupportsCompressedTexture)
01720 colorLookupTextureFormat = myGL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
01721
01722 glTexImage2D( GL_TEXTURE_2D, 0,colorLookupTextureFormat, 256, 256, 0, GL_RGBA, GL_UNSIGNED_BYTE, this->ColorLookup );
01723 }
01724
01725 }
01726
01727
01728
01729
01730 void vtkMitkOpenGLVolumeTextureMapper3D::SetupRGBATextures(
01731 vtkRenderer *vtkNotUsed(ren),
01732 vtkVolume *vol )
01733 {
01734 MITK_INFO << "SetupFourDependentTextures";
01735
01736 this->UpdateVolumesRGBA(vol);
01737
01738
01739
01740
01741
01742
01743
01744
01745
01746
01747
01748
01749
01750
01751
01752
01753
01754
01755
01756
01757
01758
01759
01760
01761
01762
01763
01764
01765
01766
01767
01768
01769
01770
01771
01772
01773
01774
01775
01776
01777
01778
01779
01780
01781
01782
01783
01784
01785
01786
01787
01788
01789
01790
01791
01792
01793
01794
01795
01796
01797
01798
01799
01800
01801
01802
01803
01804
01805
01806
01807
01808
01809
01810
01811
01812
01813
01814
01815
01816
01817
01818
01819
01820
01821
01822
01823
01824
01825
01826
01827
01828 }
01829
01830 void vtkMitkOpenGLVolumeTextureMapper3D::RenderOneIndependentShadeFP(
01831 vtkRenderer *ren,
01832 vtkVolume *vol )
01833 {
01834
01835
01836 this->SetupOneIndependentTextures( ren, vol );
01837
01838 glEnable( vtkgl::FRAGMENT_PROGRAM_ARB );
01839
01840 vtkgl::BindProgramARB( vtkgl::FRAGMENT_PROGRAM_ARB, prgOneComponentShade );
01841
01842 this->SetupProgramLocalsForShadingFP( ren, vol );
01843
01844
01845 {
01846 vtkgl::ActiveTexture( vtkgl::TEXTURE0 );
01847 glDisable( GL_TEXTURE_2D );
01848 glEnable( vtkgl::TEXTURE_3D );
01849 glBindTexture(vtkgl::TEXTURE_3D, this->Volume1Index);
01850
01851 vtkgl::ActiveTexture( vtkgl::TEXTURE1 );
01852 glEnable( GL_TEXTURE_2D );
01853 glDisable( vtkgl::TEXTURE_3D );
01854 glBindTexture(GL_TEXTURE_2D, this->ColorLookupIndex);
01855
01856 vtkgl::ActiveTexture( vtkgl::TEXTURE2 );
01857 glDisable( GL_TEXTURE_2D );
01858 glEnable( vtkgl::TEXTURE_3D );
01859 glBindTexture(vtkgl::TEXTURE_3D, this->Volume2Index);
01860 }
01861
01862 int stages[4] = {1,1,1,0};
01863 this->RenderPolygons( ren, vol, stages );
01864
01865 glDisable( vtkgl::FRAGMENT_PROGRAM_ARB );
01866 }
01867
01868 void vtkMitkOpenGLVolumeTextureMapper3D::RenderRGBAShadeFP(
01869 vtkRenderer *ren,
01870 vtkVolume *vol )
01871 {
01872 this->SetupRGBATextures(ren, vol);
01873
01874 glEnable( vtkgl::FRAGMENT_PROGRAM_ARB );
01875
01876 vtkgl::BindProgramARB( vtkgl::FRAGMENT_PROGRAM_ARB, prgRGBAShade );
01877
01878 this->SetupProgramLocalsForShadingFP( ren, vol );
01879
01880
01881 {
01882 vtkgl::ActiveTexture( vtkgl::TEXTURE0 );
01883 glDisable( GL_TEXTURE_2D );
01884 glEnable( vtkgl::TEXTURE_3D );
01885 glBindTexture(vtkgl::TEXTURE_3D, this->Volume1Index);
01886
01887 vtkgl::ActiveTexture( vtkgl::TEXTURE1 );
01888 glDisable( GL_TEXTURE_2D );
01889 glEnable( vtkgl::TEXTURE_3D );
01890 glBindTexture(vtkgl::TEXTURE_3D, this->Volume2Index);
01891 }
01892
01893 int stages[4] = {1,1,1,0};
01894 this->RenderPolygons( ren, vol, stages );
01895
01896 glDisable( vtkgl::FRAGMENT_PROGRAM_ARB );
01897 }
01898
01899
01900 void vtkMitkOpenGLVolumeTextureMapper3D::GetLightInformation(
01901 vtkRenderer *ren,
01902 vtkVolume *vol,
01903 GLfloat lightDirection[2][4],
01904 GLfloat lightDiffuseColor[2][4],
01905 GLfloat lightSpecularColor[2][4],
01906 GLfloat halfwayVector[2][4],
01907 GLfloat ambientColor[4] )
01908 {
01909
01910
01911
01912 float ambient = vol->GetProperty()->GetAmbient();
01913 float diffuse = vol->GetProperty()->GetDiffuse();
01914 float specular = vol->GetProperty()->GetSpecular();
01915
01916 vtkTransform *volumeTransform = vtkTransform::New();
01917
01918 volumeTransform->SetMatrix( vol->GetMatrix() );
01919 volumeTransform->Inverse();
01920
01921 vtkLightCollection *lights = ren->GetLights();
01922 lights->InitTraversal();
01923
01924 vtkLight *light[2];
01925 light[0] = lights->GetNextItem();
01926 light[1] = lights->GetNextItem();
01927
01928 int lightIndex = 0;
01929
01930 double cameraPosition[3];
01931 double cameraFocalPoint[3];
01932
01933 ren->GetActiveCamera()->GetPosition( cameraPosition );
01934 ren->GetActiveCamera()->GetFocalPoint( cameraFocalPoint );
01935
01936 double viewDirection[3];
01937
01938 volumeTransform->TransformPoint( cameraPosition, cameraPosition );
01939 volumeTransform->TransformPoint( cameraFocalPoint, cameraFocalPoint );
01940
01941 viewDirection[0] = cameraFocalPoint[0] - cameraPosition[0];
01942 viewDirection[1] = cameraFocalPoint[1] - cameraPosition[1];
01943 viewDirection[2] = cameraFocalPoint[2] - cameraPosition[2];
01944
01945 vtkMath::Normalize( viewDirection );
01946
01947
01948 ambientColor[0] = 0.0;
01949 ambientColor[1] = 0.0;
01950 ambientColor[2] = 0.0;
01951 ambientColor[3] = 0.0;
01952
01953 for ( lightIndex = 0; lightIndex < 2; lightIndex++ )
01954 {
01955 float dir[3] = {0,0,0};
01956 float half[3] = {0,0,0};
01957
01958 if ( light[lightIndex] == NULL ||
01959 light[lightIndex]->GetSwitch() == 0 )
01960 {
01961 lightDiffuseColor[lightIndex][0] = 0.0;
01962 lightDiffuseColor[lightIndex][1] = 0.0;
01963 lightDiffuseColor[lightIndex][2] = 0.0;
01964 lightDiffuseColor[lightIndex][3] = 0.0;
01965
01966 lightSpecularColor[lightIndex][0] = 0.0;
01967 lightSpecularColor[lightIndex][1] = 0.0;
01968 lightSpecularColor[lightIndex][2] = 0.0;
01969 lightSpecularColor[lightIndex][3] = 0.0;
01970 }
01971 else
01972 {
01973 float lightIntensity = light[lightIndex]->GetIntensity();
01974 double lightColor[3];
01975
01976 light[lightIndex]->GetDiffuseColor( lightColor );
01977
01978 double lightPosition[3];
01979 double lightFocalPoint[3];
01980 light[lightIndex]->GetTransformedPosition( lightPosition );
01981 light[lightIndex]->GetTransformedFocalPoint( lightFocalPoint );
01982
01983 volumeTransform->TransformPoint( lightPosition, lightPosition );
01984 volumeTransform->TransformPoint( lightFocalPoint, lightFocalPoint );
01985
01986 dir[0] = lightPosition[0] - lightFocalPoint[0];
01987 dir[1] = lightPosition[1] - lightFocalPoint[1];
01988 dir[2] = lightPosition[2] - lightFocalPoint[2];
01989
01990 vtkMath::Normalize( dir );
01991
01992 lightDiffuseColor[lightIndex][0] = lightColor[0]*diffuse*lightIntensity;
01993 lightDiffuseColor[lightIndex][1] = lightColor[1]*diffuse*lightIntensity;
01994 lightDiffuseColor[lightIndex][2] = lightColor[2]*diffuse*lightIntensity;
01995 lightDiffuseColor[lightIndex][3] = 1.0;
01996
01997 lightSpecularColor[lightIndex][0]= lightColor[0]*specular*lightIntensity;
01998 lightSpecularColor[lightIndex][1]= lightColor[1]*specular*lightIntensity;
01999 lightSpecularColor[lightIndex][2]= lightColor[2]*specular*lightIntensity;
02000 lightSpecularColor[lightIndex][3] = 0.0;
02001
02002 half[0] = dir[0] - viewDirection[0];
02003 half[1] = dir[1] - viewDirection[1];
02004 half[2] = dir[2] - viewDirection[2];
02005
02006 vtkMath::Normalize( half );
02007
02008 ambientColor[0] += ambient*lightColor[0];
02009 ambientColor[1] += ambient*lightColor[1];
02010 ambientColor[2] += ambient*lightColor[2];
02011 }
02012
02013 lightDirection[lightIndex][0] = (dir[0]+1.0)/2.0;
02014 lightDirection[lightIndex][1] = (dir[1]+1.0)/2.0;
02015 lightDirection[lightIndex][2] = (dir[2]+1.0)/2.0;
02016 lightDirection[lightIndex][3] = 0.0;
02017
02018 halfwayVector[lightIndex][0] = (half[0]+1.0)/2.0;
02019 halfwayVector[lightIndex][1] = (half[1]+1.0)/2.0;
02020 halfwayVector[lightIndex][2] = (half[2]+1.0)/2.0;
02021 halfwayVector[lightIndex][3] = 0.0;
02022 }
02023
02024 volumeTransform->Delete();
02025
02026 }
02027
02028 void vtkMitkOpenGLVolumeTextureMapper3D::SetupProgramLocalsForShadingFP(
02029 vtkRenderer *ren,
02030 vtkVolume *vol )
02031 {
02032
02033
02034 GLfloat lightDirection[2][4];
02035 GLfloat lightDiffuseColor[2][4];
02036 GLfloat lightSpecularColor[2][4];
02037 GLfloat halfwayVector[2][4];
02038 GLfloat ambientColor[4];
02039
02040 float ambient = vol->GetProperty()->GetAmbient();
02041 float diffuse = vol->GetProperty()->GetDiffuse();
02042 float specular = vol->GetProperty()->GetSpecular();
02043 float specularPower = vol->GetProperty()->GetSpecularPower();
02044
02045 vtkTransform *volumeTransform = vtkTransform::New();
02046
02047 volumeTransform->SetMatrix( vol->GetMatrix() );
02048 volumeTransform->Inverse();
02049
02050 vtkLightCollection *lights = ren->GetLights();
02051 lights->InitTraversal();
02052
02053 vtkLight *light[2];
02054 light[0] = lights->GetNextItem();
02055 light[1] = lights->GetNextItem();
02056
02057 int lightIndex = 0;
02058
02059 double cameraPosition[3];
02060 double cameraFocalPoint[3];
02061
02062 ren->GetActiveCamera()->GetPosition( cameraPosition );
02063 ren->GetActiveCamera()->GetFocalPoint( cameraFocalPoint );
02064
02065 volumeTransform->TransformPoint( cameraPosition, cameraPosition );
02066 volumeTransform->TransformPoint( cameraFocalPoint, cameraFocalPoint );
02067
02068 double viewDirection[4];
02069
02070 viewDirection[0] = cameraFocalPoint[0] - cameraPosition[0];
02071 viewDirection[1] = cameraFocalPoint[1] - cameraPosition[1];
02072 viewDirection[2] = cameraFocalPoint[2] - cameraPosition[2];
02073 viewDirection[3] = 0.0;
02074
02075 vtkMath::Normalize( viewDirection );
02076
02077 ambientColor[0] = 0.0;
02078 ambientColor[1] = 0.0;
02079 ambientColor[2] = 0.0;
02080 ambientColor[3] = 0.0;
02081
02082 for ( lightIndex = 0; lightIndex < 2; lightIndex++ )
02083 {
02084 float dir[3] = {0,0,0};
02085 float half[3] = {0,0,0};
02086
02087 if ( light[lightIndex] == NULL ||
02088 light[lightIndex]->GetSwitch() == 0 )
02089 {
02090 lightDiffuseColor[lightIndex][0] = 0.0;
02091 lightDiffuseColor[lightIndex][1] = 0.0;
02092 lightDiffuseColor[lightIndex][2] = 0.0;
02093 lightDiffuseColor[lightIndex][3] = 0.0;
02094
02095 lightSpecularColor[lightIndex][0] = 0.0;
02096 lightSpecularColor[lightIndex][1] = 0.0;
02097 lightSpecularColor[lightIndex][2] = 0.0;
02098 lightSpecularColor[lightIndex][3] = 0.0;
02099 }
02100 else
02101 {
02102 float lightIntensity = light[lightIndex]->GetIntensity();
02103 double lightColor[3];
02104
02105 light[lightIndex]->GetDiffuseColor( lightColor );
02106
02107 double lightPosition[3];
02108 double lightFocalPoint[3];
02109 light[lightIndex]->GetTransformedPosition( lightPosition );
02110 light[lightIndex]->GetTransformedFocalPoint( lightFocalPoint );
02111
02112 volumeTransform->TransformPoint( lightPosition, lightPosition );
02113 volumeTransform->TransformPoint( lightFocalPoint, lightFocalPoint );
02114
02115 dir[0] = lightPosition[0] - lightFocalPoint[0];
02116 dir[1] = lightPosition[1] - lightFocalPoint[1];
02117 dir[2] = lightPosition[2] - lightFocalPoint[2];
02118
02119 vtkMath::Normalize( dir );
02120
02121 lightDiffuseColor[lightIndex][0] = lightColor[0]*diffuse*lightIntensity;
02122 lightDiffuseColor[lightIndex][1] = lightColor[1]*diffuse*lightIntensity;
02123 lightDiffuseColor[lightIndex][2] = lightColor[2]*diffuse*lightIntensity;
02124 lightDiffuseColor[lightIndex][3] = 0.0;
02125
02126 lightSpecularColor[lightIndex][0]= lightColor[0]*specular*lightIntensity;
02127 lightSpecularColor[lightIndex][1]= lightColor[1]*specular*lightIntensity;
02128 lightSpecularColor[lightIndex][2]= lightColor[2]*specular*lightIntensity;
02129 lightSpecularColor[lightIndex][3] = 0.0;
02130
02131 half[0] = dir[0] - viewDirection[0];
02132 half[1] = dir[1] - viewDirection[1];
02133 half[2] = dir[2] - viewDirection[2];
02134
02135 vtkMath::Normalize( half );
02136
02137 ambientColor[0] += ambient*lightColor[0];
02138 ambientColor[1] += ambient*lightColor[1];
02139 ambientColor[2] += ambient*lightColor[2];
02140 }
02141
02142 lightDirection[lightIndex][0] = dir[0];
02143 lightDirection[lightIndex][1] = dir[1];
02144 lightDirection[lightIndex][2] = dir[2];
02145 lightDirection[lightIndex][3] = 0.0;
02146
02147 halfwayVector[lightIndex][0] = half[0];
02148 halfwayVector[lightIndex][1] = half[1];
02149 halfwayVector[lightIndex][2] = half[2];
02150 halfwayVector[lightIndex][3] = 0.0;
02151 }
02152
02153 volumeTransform->Delete();
02154
02155 vtkgl::ProgramLocalParameter4fARB( vtkgl::FRAGMENT_PROGRAM_ARB, 0,
02156 lightDirection[0][0],
02157 lightDirection[0][1],
02158 lightDirection[0][2],
02159 lightDirection[0][3] );
02160
02161 vtkgl::ProgramLocalParameter4fARB( vtkgl::FRAGMENT_PROGRAM_ARB, 1,
02162 halfwayVector[0][0],
02163 halfwayVector[0][1],
02164 halfwayVector[0][2],
02165 halfwayVector[0][3] );
02166
02167 vtkgl::ProgramLocalParameter4fARB( vtkgl::FRAGMENT_PROGRAM_ARB, 2,
02168 ambient, diffuse, specular, specularPower );
02169
02170 vtkgl::ProgramLocalParameter4fARB( vtkgl::FRAGMENT_PROGRAM_ARB, 3,
02171 lightDiffuseColor[0][0],
02172 lightDiffuseColor[0][1],
02173 lightDiffuseColor[0][2],
02174 lightDiffuseColor[0][3] );
02175
02176 vtkgl::ProgramLocalParameter4fARB( vtkgl::FRAGMENT_PROGRAM_ARB, 4,
02177 lightSpecularColor[0][0],
02178 lightSpecularColor[0][1],
02179 lightSpecularColor[0][2],
02180 lightSpecularColor[0][3] );
02181
02182 vtkgl::ProgramLocalParameter4fARB( vtkgl::FRAGMENT_PROGRAM_ARB, 5,
02183 viewDirection[0],
02184 viewDirection[1],
02185 viewDirection[2],
02186 viewDirection[3] );
02187
02188 vtkgl::ProgramLocalParameter4fARB( vtkgl::FRAGMENT_PROGRAM_ARB, 6,
02189 2.0, -1.0, 0.0, 0.0 );
02190 }
02191
02192 int vtkMitkOpenGLVolumeTextureMapper3D::IsRenderSupported( vtkRenderer *renderer, vtkVolumeProperty *property )
02193 {
02194
02195
02196 if ( !this->Initialized )
02197 {
02198
02199 this->Initialize(renderer);
02200 }
02201
02202 if ( !this->RenderPossible )
02203 {
02204 return 0;
02205 }
02206
02207 if ( !this->GetInput() )
02208 {
02209 return 0;
02210 }
02211
02212 if ( this->GetInput()->GetNumberOfScalarComponents() > 1 &&
02213 property->GetIndependentComponents() )
02214 {
02215 return 0;
02216 }
02217
02218 return 1;
02219 }
02220
02221 void vtkMitkOpenGLVolumeTextureMapper3D::Initialize(vtkRenderer *renderer)
02222 {
02223
02224
02225 this->Initialized = 1;
02226
02227
02228 vtkOpenGLExtensionManager *extensions=static_cast<vtkOpenGLRenderWindow *>(renderer->GetRenderWindow())->GetExtensionManager();
02229
02230 int supports_texture3D=extensions->ExtensionSupported( "GL_VERSION_1_2" );
02231 if(supports_texture3D)
02232 {
02233 extensions->LoadExtension("GL_VERSION_1_2");
02234 }
02235 else
02236 {
02237 supports_texture3D=extensions->ExtensionSupported( "GL_EXT_texture3D" );
02238 if(supports_texture3D)
02239 {
02240 extensions->LoadCorePromotedExtension("GL_EXT_texture3D");
02241 }
02242 }
02243
02244 int supports_multitexture=extensions->ExtensionSupported( "GL_VERSION_1_3" );
02245 if(supports_multitexture)
02246 {
02247 extensions->LoadExtension("GL_VERSION_1_3");
02248 }
02249 else
02250 {
02251 supports_multitexture=
02252 extensions->ExtensionSupported("GL_ARB_multitexture");
02253 if(supports_multitexture)
02254 {
02255 extensions->LoadCorePromotedExtension("GL_ARB_multitexture");
02256 }
02257 }
02258
02259 this->SupportsCompressedTexture=extensions->ExtensionSupported("GL_VERSION_1_3")==1;
02260 if(!this->SupportsCompressedTexture)
02261 {
02262 this->SupportsCompressedTexture=
02263 extensions->ExtensionSupported("GL_ARB_texture_compression")==1;
02264 if(this->SupportsCompressedTexture)
02265 {
02266 extensions->LoadCorePromotedExtension("GL_ARB_texture_compression");
02267 }
02268 }
02269
02270
02271 this->SupportsNonPowerOfTwoTextures=
02272 extensions->ExtensionSupported("GL_VERSION_2_0")
02273 || extensions->ExtensionSupported("GL_ARB_texture_non_power_of_two");
02274
02275
02276
02277 int supports_GL_ARB_fragment_program = extensions->ExtensionSupported( "GL_ARB_fragment_program" );
02278 if(supports_GL_ARB_fragment_program)
02279 {
02280 extensions->LoadExtension( "GL_ARB_fragment_program" );
02281 }
02282
02283 int supports_GL_ARB_vertex_program = extensions->ExtensionSupported( "GL_ARB_vertex_program" );
02284 if(supports_GL_ARB_vertex_program)
02285 {
02286 extensions->LoadExtension( "GL_ARB_vertex_program" );
02287 }
02288
02289 RenderPossible = 0;
02290
02291 if ( supports_texture3D &&
02292 supports_multitexture &&
02293 supports_GL_ARB_fragment_program &&
02294 supports_GL_ARB_vertex_program &&
02295 vtkgl::TexImage3D &&
02296 vtkgl::ActiveTexture &&
02297 vtkgl::MultiTexCoord3fv &&
02298 vtkgl::GenProgramsARB &&
02299 vtkgl::DeleteProgramsARB &&
02300 vtkgl::BindProgramARB &&
02301 vtkgl::ProgramStringARB &&
02302 vtkgl::ProgramLocalParameter4fARB )
02303 {
02304 RenderPossible = 1;
02305 }
02306 else
02307 {
02308 std::string errString = "no gpu-acceleration possible cause following extensions/methods are missing or unsupported:";
02309 if(!supports_texture3D) errString += " EXT_TEXTURE3D";
02310 if(!supports_multitexture) errString += " EXT_MULTITEXTURE";
02311 if(!supports_GL_ARB_fragment_program) errString += " ARB_FRAGMENT_PROGRAM";
02312 if(!supports_GL_ARB_vertex_program) errString += " ARB_VERTEX_PROGRAM";
02313 if(!vtkgl::TexImage3D) errString += " glTexImage3D";
02314 if(!vtkgl::ActiveTexture) errString += " glActiveTexture";
02315 if(!vtkgl::MultiTexCoord3fv) errString += " glMultiTexCoord3fv";
02316 if(!vtkgl::GenProgramsARB) errString += " glGenProgramsARB";
02317 if(!vtkgl::DeleteProgramsARB) errString += " glDeleteProgramsARB";
02318 if(!vtkgl::BindProgramARB) errString += " glBindProgramARB";
02319 if(!vtkgl::ProgramStringARB) errString += " glProgramStringARB";
02320 if(!vtkgl::ProgramLocalParameter4fARB) errString += " glProgramLocalParameter4fARB";
02321 GPU_WARN << errString;
02322 };
02323
02324 if(RenderPossible)
02325 {
02326 vtkgl::GenProgramsARB( 1, &prgOneComponentShade );
02327 vtkgl::BindProgramARB( vtkgl::FRAGMENT_PROGRAM_ARB, prgOneComponentShade );
02328 vtkgl::ProgramStringARB( vtkgl::FRAGMENT_PROGRAM_ARB,
02329 vtkgl::PROGRAM_FORMAT_ASCII_ARB,
02330 static_cast<GLsizei>(strlen(vtkMitkVolumeTextureMapper3D_OneComponentShadeFP)),
02331 vtkMitkVolumeTextureMapper3D_OneComponentShadeFP );
02332
02333 vtkgl::GenProgramsARB( 1, &prgRGBAShade );
02334 vtkgl::BindProgramARB( vtkgl::FRAGMENT_PROGRAM_ARB, prgRGBAShade );
02335 vtkgl::ProgramStringARB( vtkgl::FRAGMENT_PROGRAM_ARB,
02336 vtkgl::PROGRAM_FORMAT_ASCII_ARB,
02337 static_cast<GLsizei>(strlen(vtkMitkVolumeTextureMapper3D_FourDependentShadeFP)),
02338 vtkMitkVolumeTextureMapper3D_FourDependentShadeFP );
02339 }
02340 }
02341
02342
02343
02344
02345 void vtkMitkOpenGLVolumeTextureMapper3D::PrintSelf(ostream& os, vtkIndent indent)
02346 {
02347
02348
02349
02350
02351 os << indent << "Initialized " << this->Initialized << endl;
02352
02353
02354
02355
02356
02357
02358
02359
02360
02361
02362
02363
02364
02365
02366
02367
02368
02369
02370
02371
02372
02373
02374
02375
02376
02377
02378
02379
02380
02381
02382
02383
02384 if(this->RenderWindow!=0)
02385 {
02386 vtkOpenGLExtensionManager *extensions=
02387 static_cast<vtkOpenGLRenderWindow *>(this->RenderWindow)->GetExtensionManager();
02388
02389 if ( this->Initialized )
02390 {
02391 os << indent << "Supports GL_VERSION_1_2:"
02392 << extensions->ExtensionSupported( "GL_VERSION_1_2" ) << endl;
02393 os << indent << "Supports GL_EXT_texture3D:"
02394 << extensions->ExtensionSupported( "GL_EXT_texture3D" ) << endl;
02395 os << indent << "Supports GL_VERSION_1_3:"
02396 << extensions->ExtensionSupported( "GL_VERSION_1_3" ) << endl;
02397 os << indent << "Supports GL_ARB_multitexture: "
02398 << extensions->ExtensionSupported( "GL_ARB_multitexture" ) << endl;
02399 os << indent << "Supports GL_NV_texture_shader2: "
02400 << extensions->ExtensionSupported( "GL_NV_texture_shader2" ) << endl;
02401 os << indent << "Supports GL_NV_register_combiners2: "
02402 << extensions->ExtensionSupported( "GL_NV_register_combiners2" )
02403 << endl;
02404 os << indent << "Supports GL_ATI_fragment_shader: "
02405 << extensions->ExtensionSupported( "GL_ATI_fragment_shader" ) << endl;
02406 os << indent << "Supports GL_ARB_fragment_program: "
02407 << extensions->ExtensionSupported( "GL_ARB_fragment_program" )
02408 << endl;
02409 os << indent << "Supports GL_ARB_texture_compression: "
02410 << extensions->ExtensionSupported( "GL_ARB_texture_compression" )
02411 << endl;
02412 os << indent << "Supports GL_VERSION_2_0:"
02413 << extensions->ExtensionSupported( "GL_VERSION_2_0" )
02414 << endl;
02415 os << indent << "Supports GL_ARB_texture_non_power_of_two:"
02416 << extensions->ExtensionSupported( "GL_ARB_texture_non_power_of_two" )
02417 << endl;
02418 }
02419 }
02420
02421 this->Superclass::PrintSelf(os,indent);
02422 }
02423
02424
02425