VTK
/Users/kitware/Dashboards/MyTests/VTK_BLD_Release_docs/Utilities/Doxygen/dox/Rendering/VolumeOpenGL2/vtkVolumeShaderComposer.h
Go to the documentation of this file.
00001 /*=========================================================================
00002 
00003   Program:   Visualization Toolkit
00004   Module:    vtkVolumeShaderComposer.h
00005 
00006   Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
00007   All rights reserved.
00008   See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
00009 
00010      This software is distributed WITHOUT ANY WARRANTY; without even
00011      the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
00012      PURPOSE.  See the above copyright notice for more information.
00013 
00014 =========================================================================*/
00015 
00016 #ifndef _vtkVolumeShaderComposer_h
00017 #define _vtkVolumeShaderComposer_h
00018 
00019 #include "vtkVolumeMask.h"
00020 
00021 #include <vtkCamera.h>
00022 #include <vtkRenderer.h>
00023 #include <vtkVolume.h>
00024 #include <vtkVolumeMapper.h>
00025 #include <vtkVolumeProperty.h>
00026 
00027 #include <map>
00028 #include <string>
00029 
00030 namespace vtkvolume
00031 {
00032   //--------------------------------------------------------------------------
00033   std::string replace(std::string source, const std::string &search,
00034                       const std::string replace, bool all)
00035     {
00036     std::string::size_type pos = 0;
00037     bool first = true;
00038     while ((pos = source.find(search, 0)) != std::string::npos)
00039       {
00040       source.replace(pos, search.length(), replace);
00041       pos += search.length();
00042       if (first)
00043         {
00044         first = false;
00045         if (!all)
00046           {
00047           return source;
00048           }
00049         }
00050       }
00051     return source;
00052     }
00053 
00054   //--------------------------------------------------------------------------
00055   std::string ComputeClip(vtkRenderer* vtkNotUsed(ren),
00056                           vtkVolumeMapper* vtkNotUsed(mapper),
00057                           vtkVolume* vtkNotUsed(vol))
00058     {
00059     return std::string("\
00060       \n  vec4 pos = in_projectionMatrix * in_modelViewMatrix *\
00061       \n             in_volumeMatrix * vec4(in_vertexPos.xyz, 1.0);\
00062       \n  gl_Position = pos;"
00063     );
00064     }
00065 
00066   //--------------------------------------------------------------------------
00067   std::string ComputeTextureCoords(vtkRenderer* vtkNotUsed(ren),
00068                                    vtkVolumeMapper* vtkNotUsed(mapper),
00069                                    vtkVolume* vtkNotUsed(vol))
00070     {
00071     return std::string(
00072       "\n  // Assuming point data only. Also, we offset the texture coordinate\
00073        \n  // to account for OpenGL treating voxel at the center of the cell.\
00074        \n  vec3 uvx = (in_vertexPos - in_volumeExtentsMin) /\
00075        \n             (in_volumeExtentsMax - in_volumeExtentsMin);\
00076        \n  vec3 delta = in_textureExtentsMax - in_textureExtentsMin;\
00077        \n  ip_textureCoords = (uvx * (delta - vec3(1.0)) + vec3(0.5)) / delta;"
00078     );
00079     }
00080 
00081   //--------------------------------------------------------------------------
00082   std::string BaseGlobalsVert(vtkRenderer* vtkNotUsed(ren),
00083                               vtkVolumeMapper* vtkNotUsed(mapper),
00084                               vtkVolume* vtkNotUsed(vol))
00085     {
00086     return std::string("\
00087       \n  uniform mat4 in_modelViewMatrix;\
00088       \n  uniform mat4 in_projectionMatrix;\
00089       \n  uniform mat4 in_volumeMatrix;\
00090       \n\
00091       \n  uniform vec3 in_volumeExtentsMin;\
00092       \n  uniform vec3 in_volumeExtentsMax;\
00093       \n\
00094       \n  uniform vec3 in_textureExtentsMax;\
00095       \n  uniform vec3 in_textureExtentsMin;"
00096     );
00097     }
00098 
00099   //--------------------------------------------------------------------------
00100   std::string BaseGlobalsFrag(vtkRenderer* vtkNotUsed(ren),
00101                               vtkVolumeMapper* vtkNotUsed(mapper),
00102                               vtkVolume* vtkNotUsed(vol),
00103                               int vtkNotUsed(numberOfLights),
00104                               int lightingComplexity,
00105                               int noOfComponents,
00106                               int independentComponents)
00107     {
00108     std::string shaderStr = std::string("\
00109       \n// Volume dataset\
00110       \nuniform sampler3D in_volume;\
00111       \nuniform int in_noOfComponents;\
00112       \nuniform int in_independentComponents;\
00113       \n\
00114       \nuniform sampler2D in_noiseSampler;\
00115       \nuniform sampler2D in_depthSampler;\
00116       \n\
00117       \n// Camera position\
00118       \nuniform vec3 in_cameraPos;\
00119       \n\
00120       \n// view and model matrices\
00121       \nuniform mat4 in_volumeMatrix;\
00122       \nuniform mat4 in_inverseVolumeMatrix;\
00123       \nuniform mat4 in_projectionMatrix;\
00124       \nuniform mat4 in_inverseProjectionMatrix;\
00125       \nuniform mat4 in_modelViewMatrix;\
00126       \nuniform mat4 in_inverseModelViewMatrix;\
00127       \nuniform mat4 in_textureDatasetMatrix;\
00128       \nuniform mat4 in_inverseTextureDatasetMatrix;\
00129       \nuniform mat3 in_texureToEyeIt;\
00130       \n\
00131       \n// Ray step size\
00132       \nuniform vec3 in_cellStep;\
00133       \nuniform vec2 in_scalarsRange;\
00134       \nuniform vec3 in_cellSpacing;\
00135       \n\
00136       \n// Sample distance\
00137       \nuniform float in_sampleDistance;\
00138       \n\
00139       \n// Scales\
00140       \nuniform vec3 in_cellScale;\
00141       \nuniform vec2 in_windowLowerLeftCorner;\
00142       \nuniform vec2 in_inverseOriginalWindowSize;\
00143       \nuniform vec2 in_inverseWindowSize;\
00144       \nuniform vec3 in_textureExtentsMax;\
00145       \nuniform vec3 in_textureExtentsMin;\
00146       \nuniform float in_volumeScale;\
00147       \nuniform float in_volumeBias;\
00148       \n\
00149       \n// Material and lighting\
00150       \nuniform vec3 in_diffuse;\
00151       \nuniform vec3 in_ambient;\
00152       \nuniform vec3 in_specular;\
00153       \nuniform float in_shininess;\
00154       ");
00155 
00156     if (lightingComplexity > 0)
00157       {
00158       shaderStr += std::string("\
00159         \nuniform bool in_twoSidedLighting;"
00160       );
00161       }
00162 
00163     if (lightingComplexity == 3)
00164       {
00165       shaderStr += std::string("\
00166         \nuniform int in_numberOfLights;\
00167         \nuniform vec3 in_lightAmbientColor[6];\
00168         \nuniform vec3 in_lightDiffuseColor[6];\
00169         \nuniform vec3 in_lightSpecularColor[6];\
00170         \nuniform vec3 in_lightDirection[6];\
00171         \nuniform vec3 in_lightPosition[6];\
00172         \nuniform vec3 in_lightAttenuation[6];\
00173         \nuniform float in_lightConeAngle[6];\
00174         \nuniform float in_lightExponent[6];\
00175         \nuniform int in_lightPositional[6];\
00176       ");
00177       }
00178     else if (lightingComplexity == 2)
00179       {
00180       shaderStr += std::string("\
00181         \nuniform int in_numberOfLights;\
00182         \nuniform vec3 in_lightAmbientColor[6];\
00183         \nuniform vec3 in_lightDiffuseColor[6];\
00184         \nuniform vec3 in_lightSpecularColor[6];\
00185         \nuniform vec3 in_lightDirection[6];\
00186       ");
00187       }
00188     else
00189       {
00190       shaderStr += std::string("\
00191         \nuniform vec3 in_lightAmbientColor[1];\
00192         \nuniform vec3 in_lightDiffuseColor[1];\
00193         \nuniform vec3 in_lightSpecularColor[1];\
00194       ");
00195       }
00196 
00197     if (noOfComponents > 1 && independentComponents)
00198       {
00199       shaderStr += std::string("\
00200         \nuniform vec4 in_componentWeight;");
00201       }
00202 
00203     return shaderStr;
00204     }
00205 
00206   //--------------------------------------------------------------------------
00207   std::string BaseInit(vtkRenderer* vtkNotUsed(ren),
00208                        vtkVolumeMapper* vtkNotUsed(mapper),
00209                        vtkVolume* vtkNotUsed(vol))
00210     {
00211     return std::string("\
00212       \n  // Get the 3D texture coordinates for lookup into the in_volume dataset\
00213       \n  g_dataPos = ip_textureCoords.xyz;\
00214       \n\
00215       \n  // Eye position in object space\
00216       \n  g_eyePosObj = (in_inverseVolumeMatrix * vec4(in_cameraPos, 1.0));\
00217       \n  if (g_eyePosObj.w != 0.0)\
00218       \n    {\
00219       \n    g_eyePosObj.x /= g_eyePosObj.w;\
00220       \n    g_eyePosObj.y /= g_eyePosObj.w;\
00221       \n    g_eyePosObj.z /= g_eyePosObj.w;\
00222       \n    g_eyePosObj.w = 1.0;\
00223       \n    }\
00224       \n\
00225       \n  // Getting the ray marching direction (in object space);\
00226       \n  vec3 rayDir = computeRayDirection();\
00227       \n\
00228       \n  // Multiply the raymarching direction with the step size to get the\
00229       \n  // sub-step size we need to take at each raymarching step\
00230       \n  g_dirStep = (in_inverseTextureDatasetMatrix *\
00231       \n              vec4(rayDir, 0.0)).xyz * in_sampleDistance;\
00232       \n\
00233       \n  g_dataPos += g_dirStep * (texture2D(in_noiseSampler, g_dataPos.xy).x);\
00234       \n\
00235       \n  // Flag to deternmine if voxel should be considered for the rendering\
00236       \n  bool l_skip = false;");
00237     }
00238 
00239   //--------------------------------------------------------------------------
00240   std::string BaseIncrement(vtkRenderer* vtkNotUsed(ren),
00241                             vtkVolumeMapper* vtkNotUsed(mapper),
00242                             vtkVolume* vtkNotUsed(vol))
00243     {
00244     return std::string("\
00245       \n    l_skip = false;"
00246     );
00247     }
00248 
00249   //--------------------------------------------------------------------------
00250   std::string BaseExit(vtkRenderer* vtkNotUsed(ren),
00251                        vtkVolumeMapper* vtkNotUsed(mapper),
00252                        vtkVolume* vtkNotUsed(vol))
00253     {
00254     return std::string();
00255     }
00256 
00257   //--------------------------------------------------------------------------
00258   std::string GradientsComputeFunc(vtkRenderer* vtkNotUsed(ren),
00259                                    vtkVolumeMapper* vtkNotUsed(mapper),
00260                                    vtkVolume* vol,
00261                                    int noOfComponents,
00262                                    int independentComponents,
00263                                    std::map<int, std::string> gradientTableMap)
00264   {
00265     std::string shaderStr;
00266     if (noOfComponents == 1 && vol->GetProperty()->HasGradientOpacity())
00267       {
00268       shaderStr += std::string("\
00269         \nuniform sampler1D in_gradientTransferFunc;\
00270         \nfloat computeGradientOpacity(vec4 grad)\
00271         \n  {\
00272         \n  return texture1D(in_gradientTransferFunc, grad.w).w;\
00273         \n  }"
00274       );
00275       }
00276     else if (noOfComponents > 1 && independentComponents &&
00277              vol->GetProperty()->HasGradientOpacity())
00278       {
00279       for (int i = 0; i < noOfComponents; ++i)
00280         {
00281         shaderStr += std::string("\n uniform sampler1D ") +
00282                      gradientTableMap[i] + std::string(";");
00283         }
00284 
00285       shaderStr += std::string("\
00286         \nfloat computeGradientOpacity(vec4 grad, int component)\
00287         \n  {\
00288         \n  if (component == 0)\
00289         \n    {\
00290         \n    return texture1D(in_gradientTransferFunc, grad.w).w;\
00291         \n    }\
00292         \n  if (component == 1)\
00293         \n    {\
00294         \n    return texture1D(in_gradientTransferFunc1, grad.w).w;\
00295         \n    }\
00296         \n  if (component == 2)\
00297         \n    {\
00298         \n    return texture1D(in_gradientTransferFunc2, grad.w).w;\
00299         \n    }\
00300         \n  if (component == 3)\
00301         \n    {\
00302         \n    return texture1D(in_gradientTransferFunc3, grad.w).w;\
00303         \n    }\
00304         \n  }"
00305       );
00306       }
00307 
00308     if (vol->GetProperty()->GetShade() &&
00309         !vol->GetProperty()->HasGradientOpacity())
00310       {
00311       shaderStr += std::string("\
00312         \nvec4 computeGradient()\
00313         \n  {\
00314         \n  vec3 g1;\
00315         \n  vec3 g2;\
00316         \n  vec3 xvec = vec3(in_cellStep[0], 0.0, 0.0);\
00317         \n  vec3 yvec = vec3(0.0, in_cellStep[1], 0.0);\
00318         \n  vec3 zvec = vec3(0.0, 0.0, in_cellStep[2]);\
00319         \n  g1.x = texture3D(in_volume, vec3(g_dataPos + xvec)).x;\
00320         \n  g1.y = texture3D(in_volume, vec3(g_dataPos + yvec)).x;\
00321         \n  g1.z = texture3D(in_volume, vec3(g_dataPos + zvec)).x;\
00322         \n  g2.x = texture3D(in_volume, vec3(g_dataPos - xvec)).x;\
00323         \n  g2.y = texture3D(in_volume, vec3(g_dataPos - yvec)).x;\
00324         \n  g2.z = texture3D(in_volume, vec3(g_dataPos - zvec)).x;\
00325         \n  return vec4((g1 - g2), -1.0);\
00326         \n  }"
00327       );
00328     }
00329     else if (vol->GetProperty()->GetShade() &&
00330              vol->GetProperty()->HasGradientOpacity())
00331       {
00332       shaderStr += std::string("\
00333         \nvec4 computeGradient()\
00334         \n  {\
00335         \n  vec3 g1;\
00336         \n  vec4 g2;\
00337         \n  vec3 xvec = vec3(in_cellStep[0], 0.0, 0.0);\
00338         \n  vec3 yvec = vec3(0.0, in_cellStep[1], 0.0);\
00339         \n  vec3 zvec = vec3(0.0, 0.0, in_cellStep[2]);\
00340         \n  g1.x = texture3D(in_volume, vec3(g_dataPos + xvec)).x;\
00341         \n  g1.y = texture3D(in_volume, vec3(g_dataPos + yvec)).x;\
00342         \n  g1.z = texture3D(in_volume, vec3(g_dataPos + zvec)).x;\
00343         \n  g2.x = texture3D(in_volume, vec3(g_dataPos - xvec)).x;\
00344         \n  g2.y = texture3D(in_volume, vec3(g_dataPos - yvec)).x;\
00345         \n  g2.z = texture3D(in_volume, vec3(g_dataPos - zvec)).x;\
00346         \n  g1.x = in_scalarsRange[0] + (\
00347         \n         in_scalarsRange[1] - in_scalarsRange[0]) * g1.x;\
00348         \n  g1.y = in_scalarsRange[0] + (\
00349         \n         in_scalarsRange[1] - in_scalarsRange[0]) * g1.y;\
00350         \n  g1.z = in_scalarsRange[0] + (\
00351         \n         in_scalarsRange[1] - in_scalarsRange[0]) * g1.z;\
00352         \n  g2.x = in_scalarsRange[0] + (\
00353         \n         in_scalarsRange[1] - in_scalarsRange[0]) * g2.x;\
00354         \n  g2.y = in_scalarsRange[0] + (\
00355         \n         in_scalarsRange[1] - in_scalarsRange[0]) * g2.y;\
00356         \n  g2.z = in_scalarsRange[0] + (\
00357         \n         in_scalarsRange[1] - in_scalarsRange[0]) * g2.z;\
00358         \n  g2.xyz = g1 - g2.xyz;\
00359         \n  vec3 cellSpacing = vec3(in_cellSpacing[0],\
00360         \n                          in_cellSpacing[1],\
00361         \n                          in_cellSpacing[2]);\
00362         \n  vec3 aspect;\
00363         \n  float avgSpacing = (cellSpacing[0] +\
00364         \n                      cellSpacing[1] +\
00365         \n                      cellSpacing[2])/3.0;\
00366         \n  // Adjust the aspect\
00367         \n  aspect.x = cellSpacing[0] * 2.0 / avgSpacing;\
00368         \n  aspect.y = cellSpacing[1] * 2.0 / avgSpacing;\
00369         \n  aspect.z = cellSpacing[2] * 2.0 / avgSpacing;\
00370         \n  g2.x /= aspect.x;\
00371         \n  g2.y /= aspect.y;\
00372         \n  g2.z /= aspect.z;\
00373         \n  float grad_mag = sqrt(g2.x * g2.x  +\
00374         \n                        g2.y * g2.y +\
00375         \n                        g2.z * g2.z);\
00376         \n  if (grad_mag > 0.0)\
00377         \n    {\
00378         \n    g2.x /= grad_mag;\
00379         \n    g2.y /= grad_mag;\
00380         \n    g2.z /= grad_mag;\
00381         \n    }\
00382         \n  else\
00383         \n    {\
00384         \n    g2.xyz = vec3(0.0, 0.0, 0.0);\
00385         \n    }\
00386         \n  grad_mag = grad_mag * 1.0 / (0.25 * (in_scalarsRange[1] -\
00387         \n                                      (in_scalarsRange[0])));\
00388         \n  grad_mag = clamp(grad_mag, 0.0, 1.0);\
00389         \n  g2.w = grad_mag;\
00390         \n  return g2;\
00391         \n  }"
00392       );
00393       }
00394     else
00395       {
00396       shaderStr += std::string("\
00397         \nvec4 computeGradient()\
00398         \n  {\
00399         \n  return vec4(0.0);\
00400         \n  }");
00401       }
00402 
00403     return shaderStr;
00404   }
00405 
00406   //--------------------------------------------------------------------------
00407   std::string LightComputeFunc(vtkRenderer* vtkNotUsed(ren),
00408                                vtkVolumeMapper* vtkNotUsed(mapper),
00409                                vtkVolume* vol,
00410                                int noOfComponents,
00411                                int independentComponents,
00412                                int vtkNotUsed(numberOfLights),
00413                                int lightingComplexity)
00414     {
00415     vtkVolumeProperty* volProperty = vol->GetProperty();
00416     std::string shaderStr = std::string("\
00417       \nvec4 computeLighting(vec4 color)\
00418       \n  {"
00419     );
00420 
00421     if (volProperty->GetShade() || volProperty->HasGradientOpacity())
00422       {
00423       shaderStr += std::string("\
00424         \n  // Compute gradient function only once\
00425         \n  vec4 gradient = computeGradient();"
00426       );
00427       }
00428 
00429     if (volProperty->GetShade())
00430       {
00431       if (lightingComplexity == 1)
00432         {
00433         shaderStr += std::string("\
00434           \n  // Light position in object space\
00435           \n  vec4 lightPosObj = (in_inverseVolumeMatrix *\
00436           \n                      vec4(in_cameraPos, 1.0));\
00437           \n  if (lightPosObj.w != 0.0)\
00438           \n    {\
00439           \n    lightPosObj.x /= lightPosObj.w;\
00440           \n    lightPosObj.y /= lightPosObj.w;\
00441           \n    lightPosObj.z /= lightPosObj.w;\
00442           \n    lightPosObj.w = 1.0;\
00443           \n    }\
00444           \n  vec3 diffuse = vec3(0.0);\
00445           \n  vec3 specular = vec3(0.0);\
00446           \n  vec3 ldir = normalize(lightPosObj.xyz - ip_vertexPos);\
00447           \n  vec3 vdir = normalize(g_eyePosObj.xyz - ip_vertexPos);\
00448           \n  vec3 h = normalize(ldir + vdir);\
00449           \n  vec3 g2 = gradient.xyz;\
00450           \n  g2 = (1.0/in_cellSpacing) * g2;\
00451           \n  float normalLength = length(g2);\
00452           \n  if (normalLength > 0.0)\
00453           \n    {\
00454           \n    g2 = normalize(g2);\
00455           \n    }\
00456           \n  else\
00457           \n    {\
00458           \n   g2 = vec3(0.0, 0.0, 0.0);\
00459           \n    }\
00460           \n   float nDotL = dot(g2, ldir);\
00461           \n   float nDotH = dot(g2, h);\
00462           \n   if (nDotL < 0.0 && in_twoSidedLighting)\
00463           \n     {\
00464           \n     nDotL = -nDotL;\
00465           \n     }\
00466           \n   if (nDotH < 0.0 && in_twoSidedLighting)\
00467           \n     {\
00468           \n     nDotH = -nDotH;\
00469           \n     }\
00470           \n   if (nDotL > 0)\
00471           \n     {\
00472           \n     diffuse = nDotL * in_diffuse * in_lightDiffuseColor[0]\
00473           \n                 * color.rgb;\
00474           \n     }\
00475           \n  if (nDotH > 0)\
00476           \n    {\
00477           \n    specular = pow(nDotH, in_shininess) * in_specular *\
00478           \n                 in_lightSpecularColor[0];\
00479           \n    }\
00480           \n  // For the headlight, ignore the light's ambient color\
00481           \n  // for now as it is causing the old mapper tests to fail\
00482           \n  vec3 finalColor = (in_ambient * color.rgb +\
00483           \n                    diffuse + specular);"
00484           );
00485         }
00486       else if (lightingComplexity == 2)
00487         {
00488         shaderStr += std::string("\
00489           \n  vec4 fragWorldPos = in_modelViewMatrix * in_volumeMatrix *\
00490           \n                      in_textureDatasetMatrix * vec4(-g_dataPos, 1.0);\
00491           \n  if (fragWorldPos.w != 0.0)\
00492           \n   {\
00493           \n   fragWorldPos /= fragWorldPos.w;\
00494           \n   }\
00495           \n  vec3 vdir = normalize(fragWorldPos.xyz);\
00496           \n  vec3 normal = gradient.xyz;\
00497           \n  vec3 ambient = vec3(0.0);\
00498           \n  vec3 diffuse = vec3(0.0);\
00499           \n  vec3 specular = vec3(0.0);\
00500           \n  float normalLength = length(normal);\
00501           \n  if (normalLength > 0.0)\
00502           \n    {\
00503           \n    normal = normalize(in_texureToEyeIt * normal);\
00504           \n    }\
00505           \n  else\
00506           \n    {\
00507           \n    normal = vec3(0.0, 0.0, 0.0);\
00508           \n    }\
00509           \n  for (int lightNum = 0; lightNum < in_numberOfLights; lightNum++)\
00510           \n    {\
00511           \n    vec3 ldir = in_lightDirection[lightNum].xyz;\
00512           \n    vec3 h = normalize(ldir + vdir);\
00513           \n    float nDotH = dot(normal, h);\
00514           \n    if (nDotH < 0.0 && in_twoSidedLighting)\
00515           \n     {\
00516           \n     nDotH = -nDotH;\
00517           \n     }\
00518           \n  float nDotL = dot(normal, ldir);\
00519           \n  if (nDotL < 0.0 && in_twoSidedLighting)\
00520           \n    {\
00521           \n    nDotL = -nDotL;\
00522           \n    }\
00523           \n  if (nDotL > 0)\
00524           \n    {\
00525           \n    diffuse += in_lightDiffuseColor[lightNum] * nDotL;\
00526           \n    }\
00527           \n  if (nDotH > 0)\
00528           \n    {\
00529           \n    specular = in_lightSpecularColor[lightNum] * pow(nDotH, in_shininess);\
00530           \n    }\
00531           \n  ambient += in_lightAmbientColor[lightNum];\
00532           \n  }\
00533           \n  vec3 finalColor = in_ambient * ambient +\
00534           \n                    in_diffuse * diffuse * color.rgb +\
00535           \n                    in_specular * specular;"
00536           );
00537         }
00538       else if (lightingComplexity == 3)
00539         {
00540         shaderStr += std::string("\
00541           \n  vec4 fragWorldPos = in_modelViewMatrix * in_volumeMatrix *\
00542           \n                      in_textureDatasetMatrix * vec4(g_dataPos, 1.0);\
00543           \n  if (fragWorldPos.w != 0.0)\
00544           \n    {\
00545           \n    fragWorldPos /= fragWorldPos.w;\
00546           \n    }\
00547           \n  vec3 viewDirection = normalize(-fragWorldPos.xyz);\
00548           \n  vec3 ambient = vec3(0,0,0);\
00549           \n  vec3 diffuse = vec3(0,0,0);\
00550           \n  vec3 specular = vec3(0,0,0);\
00551           \n  vec3 vertLightDirection;\
00552           \n  vec3 normal = normalize(in_texureToEyeIt * gradient.xyz);\
00553           \n  vec3 lightDir;\
00554           \n  for (int lightNum = 0; lightNum < in_numberOfLights; lightNum++)\
00555           \n    {\
00556           \n    float attenuation = 1.0;\
00557           \n    // directional\
00558           \n    lightDir = in_lightDirection[lightNum];\
00559           \n    if (in_lightPositional[lightNum] == 0)\
00560           \n      {\
00561           \n      vertLightDirection = lightDir;\
00562           \n      }\
00563           \n    else\
00564           \n      {\
00565           \n      vertLightDirection = (fragWorldPos.xyz - in_lightPosition[lightNum]);\
00566           \n      float distance = length(vertLightDirection);\
00567           \n      vertLightDirection = normalize(vertLightDirection);\
00568           \n      attenuation = 1.0 /\
00569           \n                    (in_lightAttenuation[lightNum].x\
00570           \n                    + in_lightAttenuation[lightNum].y * distance\
00571           \n                    + in_lightAttenuation[lightNum].z * distance * distance);\
00572           \n      // per OpenGL standard cone angle is 90 or less for a spot light\
00573           \n      if (in_lightConeAngle[lightNum] <= 90.0)\
00574           \n        {\
00575           \n        float coneDot = dot(vertLightDirection, lightDir);\
00576           \n        // if inside the cone\
00577           \n        if (coneDot >= cos(radians(in_lightConeAngle[lightNum])))\
00578           \n          {\
00579           \n          attenuation = attenuation * pow(coneDot, in_lightExponent[lightNum]);\
00580           \n          }\
00581           \n        else\
00582           \n          {\
00583           \n          attenuation = 0.0;\
00584           \n          }\
00585           \n        }\
00586           \n      }\
00587           \n  // diffuse and specular lighting\
00588           \n  float nDotL = dot(normal, vertLightDirection);\
00589           \n  if (nDotL < 0.0 && in_twoSidedLighting)\
00590           \n    {\
00591           \n    nDotL = -nDotL;\
00592           \n    }\
00593           \n  if (nDotL > 0)\
00594           \n    {\
00595           \n    float df = max(0.0, attenuation * nDotL);\
00596           \n    diffuse += (df * in_lightDiffuseColor[lightNum]);\
00597           \n    }\
00598           \n  vec3 h = normalize(vertLightDirection + viewDirection);\
00599           \n  float nDotH = dot(normal, h);\
00600           \n  if (nDotH < 0.0 && in_twoSidedLighting)\
00601           \n    {\
00602           \n    nDotH = -nDotH;\
00603           \n    }\
00604           \n  if (nDotH > 0)\
00605           \n    {\
00606           \n    float sf = attenuation * pow(nDotH, in_shininess);\
00607           \n    specular += (sf * in_lightSpecularColor[lightNum]);\
00608           \n    }\
00609           \n    ambient += in_lightAmbientColor[lightNum];\
00610           \n  }\
00611           \n  vec3 finalColor = in_ambient * ambient + in_diffuse *\
00612           \n                    diffuse * color.rgb + in_specular * specular;\
00613         ");
00614         }
00615       }
00616     else
00617       {
00618       shaderStr += std::string(
00619         "\n  vec3 finalColor = color.rgb;"
00620       );
00621       }
00622 
00623     if (noOfComponents == 1 && volProperty->HasGradientOpacity())
00624       {
00625       shaderStr += std::string("\
00626         \n  if (gradient.w >= 0.0)\
00627         \n    {\
00628         \n    color.a = color.a *\
00629         \n    computeGradientOpacity(gradient);\
00630         \n    }"
00631       );
00632       }
00633     else if (noOfComponents > 1 && independentComponents &&
00634              volProperty->HasGradientOpacity())
00635       {
00636       shaderStr += std::string("\
00637       \n  if (gradient.w >= 0.0)\
00638       \n    {\
00639       \n    for (int i = 0; i < in_noOfComponents; ++i)\
00640       \n      {\
00641       \n      color.a = color.a *\
00642       \n      computeGradientOpacity(gradient, i) * in_componentWeight[i];\
00643       \n      }"
00644       );
00645       }
00646 
00647     shaderStr += std::string("\
00648       \n  return vec4(finalColor, color.a);\
00649       \n  }"
00650     );
00651 
00652     return shaderStr;
00653     }
00654 
00655   //--------------------------------------------------------------------------
00656   std::string RayDirectionFunc(vtkRenderer* ren,
00657                                vtkVolumeMapper* vtkNotUsed(mapper),
00658                                vtkVolume* vtkNotUsed(vol),
00659                                int vtkNotUsed(noOfComponents))
00660     {
00661     if (!ren->GetActiveCamera()->GetParallelProjection())
00662       {
00663       return std::string("\
00664         \nvec3 computeRayDirection()\
00665         \n  {\
00666         \n  return normalize(ip_vertexPos.xyz - g_eyePosObj.xyz);\
00667         \n  }");
00668       }
00669     else
00670       {
00671       return std::string("\
00672         \nuniform vec3 in_projectionDirection;\
00673         \nvec3 computeRayDirection()\
00674         \n  {\
00675         \n  return normalize((in_inverseVolumeMatrix *\
00676         \n                   vec4(in_projectionDirection, 0.0)).xyz);\
00677         \n  }");
00678       }
00679     }
00680 
00681   //--------------------------------------------------------------------------
00682   std::string ColorTransferFunc(vtkRenderer* vtkNotUsed(ren),
00683                                 vtkVolumeMapper* vtkNotUsed(mapper),
00684                                 vtkVolume* vtkNotUsed(vol),
00685                                 int noOfComponents,
00686                                 int independentComponents,
00687                                 std::map<int, std::string> colorTableMap)
00688     {
00689       if (noOfComponents == 1)
00690         {
00691         return std::string("\
00692           \nuniform sampler1D in_colorTransferFunc;\
00693           \nvec4 computeColor(vec4 scalar)\
00694           \n  {\
00695           \n  return computeLighting(vec4(texture1D(in_colorTransferFunc,\
00696           \n                                        scalar.w).xyz,\
00697           \n                              computeOpacity(scalar)));\
00698           \n  }");
00699         }
00700       else if (noOfComponents > 1 && independentComponents)
00701         {
00702         std::string shaderStr;
00703         for (int i = 0; i < noOfComponents; ++i)
00704           {
00705           shaderStr += std::string("\n uniform sampler1D ") +
00706                        colorTableMap[i] + std::string(";");
00707           }
00708 
00709         shaderStr += std::string("\
00710           \nvec4 computeColor(vec4 scalar, int component)\
00711           \n  {\
00712           \n  if (component == 0)\
00713           \n    {\
00714           \n    return computeLighting(vec4(texture1D(\
00715           \n      in_colorTransferFunc,\
00716           \n      scalar[component]).xyz,\
00717           \n      computeOpacity(scalar, component)));\
00718           \n    }\
00719           \n  if (component == 1)\
00720           \n    {\
00721           \n    return computeLighting(vec4(texture1D(\
00722           \n      in_colorTransferFunc1,\
00723           \n      scalar[component]).xyz,\
00724           \n      computeOpacity(scalar, component)));\
00725           \n    }\
00726           \n  if (component == 2)\
00727           \n    {\
00728           \n      return computeLighting(vec4(texture1D(\
00729           \n        in_colorTransferFunc2,\
00730           \n        scalar[component]).xyz,\
00731           \n        computeOpacity(scalar, component)));\
00732           \n    }\
00733           \n  if (component == 3)\
00734           \n    {\
00735           \n      return computeLighting(vec4(texture1D(\
00736           \n        in_colorTransferFunc3,\
00737           \n        scalar[component]).xyz,\
00738           \n        computeOpacity(scalar, component)));\
00739           \n    }\
00740           \n  }");
00741 
00742           return shaderStr;
00743         }
00744 
00745       return std::string("\
00746         \nvec4 computeColor(vec4 scalar)\
00747         \n  {\
00748         \n  return computeLighting(vec4(scalar.xyz, computeOpacity(scalar)));\
00749         \n  }");
00750     }
00751 
00752   //--------------------------------------------------------------------------
00753   std::string OpacityTransferFunc(vtkRenderer* vtkNotUsed(ren),
00754                                   vtkVolumeMapper* vtkNotUsed(mapper),
00755                                   vtkVolume* vtkNotUsed(vol),
00756                                   int noOfComponents,
00757                                   int independentComponents,
00758                                   std::map<int, std::string> opacityTableMap)
00759     {
00760     if (noOfComponents > 1 && independentComponents)
00761       {
00762       std::string shaderStr;
00763       for (int i = 0; i < noOfComponents; ++i)
00764         {
00765         shaderStr += std::string("\n uniform sampler1D ") +
00766                      opacityTableMap[i] + std::string(";");
00767         }
00768 
00769       shaderStr += std::string("\
00770         \nfloat computeOpacity(vec4 scalar, int component)\
00771         \n  {\
00772         \n  if (component == 0)\
00773         \n    {\
00774         \n    return texture1D(in_opacityTransferFunc,\
00775         \n                     scalar[component]).w;\
00776         \n    }\
00777         \n  if (component == 1)\
00778         \n    {\
00779         \n    return texture1D(in_opacityTransferFunc1,\
00780         \n                     scalar[component]).w;\
00781         \n    }\
00782         \n  if (component == 2)\
00783         \n    {\
00784         \n      return texture1D(in_opacityTransferFunc2,\
00785         \n                       scalar[component]).w;\
00786         \n    }\
00787         \n  if (component == 3)\
00788         \n    {\
00789         \n      return texture1D(in_opacityTransferFunc3,\
00790         \n                       scalar[component]).w;\
00791         \n    }\
00792         \n  }");
00793 
00794         return shaderStr;
00795       }
00796     else
00797       {
00798       return std::string("\
00799         \nuniform sampler1D in_opacityTransferFunc;\
00800         \nfloat computeOpacity(vec4 scalar)\
00801         \n  {\
00802         \n  return texture1D(in_opacityTransferFunc, scalar.w).w;\
00803         \n  }");
00804       }
00805     }
00806 
00807   //--------------------------------------------------------------------------
00808   std::string ShadingGlobalsVert(vtkRenderer* vtkNotUsed(ren),
00809                                  vtkVolumeMapper* vtkNotUsed(mapper),
00810                                  vtkVolume* vtkNotUsed(vol))
00811     {
00812     return std::string();
00813     }
00814 
00815   //--------------------------------------------------------------------------
00816   std::string ShadingGlobalsFrag(vtkRenderer* vtkNotUsed(ren),
00817                                  vtkVolumeMapper* vtkNotUsed(mapper),
00818                                  vtkVolume* vtkNotUsed(vol))
00819     {
00820     return std::string();
00821     }
00822 
00823   //--------------------------------------------------------------------------
00824   std::string ShadingInit(vtkRenderer* vtkNotUsed(ren),
00825                           vtkVolumeMapper* mapper,
00826                           vtkVolume* vtkNotUsed(vol))
00827     {
00828     if (mapper->GetBlendMode() == vtkVolumeMapper::MAXIMUM_INTENSITY_BLEND)
00829       {
00830       return std::string("\
00831         \n  // We get data between 0.0 - 1.0 range\
00832         \n  bool l_firstValue = true;\
00833         \n  vec4 l_maxValue = vec4(0.0);"
00834       );
00835       }
00836     else if (mapper->GetBlendMode() == vtkVolumeMapper::MINIMUM_INTENSITY_BLEND)
00837       {
00838       return std::string("\
00839         \n  //We get data between 0.0 - 1.0 range\
00840         \n  bool l_firstValue = true;\
00841         \n  vec4 l_minValue = vec4(1.0);"
00842       );
00843       }
00844     else if (mapper->GetBlendMode() == vtkVolumeMapper::ADDITIVE_BLEND)
00845       {
00846       return std::string("\
00847         \n  //We get data between 0.0 - 1.0 range\
00848         \n  float l_sumValue = 0.0;"
00849       );
00850       }
00851     else
00852       {
00853       return std::string();
00854       }
00855     }
00856 
00857   //--------------------------------------------------------------------------
00858   std::string ShadingIncrement(vtkRenderer* vtkNotUsed(ren),
00859                                vtkVolumeMapper* mapper,
00860                                vtkVolume* vtkNotUsed(vol),
00861                                vtkImageData* maskInput,
00862                                vtkVolumeMask* mask, int maskType,
00863                                int noOfComponents,
00864                                int independentComponents = 0)
00865     {
00866     std::string shaderStr = std::string("\
00867       \n    if (!l_skip)\
00868       \n      {"
00869     );
00870 
00871     if (mapper->GetBlendMode() == vtkVolumeMapper::MAXIMUM_INTENSITY_BLEND)
00872       {
00873       if (noOfComponents == 4)
00874         {
00875         shaderStr += std::string("\
00876           \n      vec4 scalar = texture3D(in_volume, g_dataPos);\
00877           \n      if (l_maxValue.w < scalar.w || l_firstValue)\
00878           \n        {\
00879           \n        l_maxValue = scalar;\
00880           \n        }\
00881           \n\
00882           \n     if (l_firstValue)\
00883           \n        {\
00884           \n        l_firstValue = false;\
00885           \n        }"
00886         );
00887         }
00888       else
00889         {
00890         shaderStr += std::string("\
00891           \n      vec4 scalar = texture3D(in_volume, g_dataPos);\
00892           \n      if (l_maxValue.w < scalar.x || l_firstValue)\
00893           \n        {\
00894           \n        l_maxValue.w = scalar.x;\
00895           \n        }\
00896           \n\
00897           \n     if (l_firstValue)\
00898           \n        {\
00899           \n        l_firstValue = false;\
00900           \n        }"
00901         );
00902         }
00903       }
00904     else if (mapper->GetBlendMode() == vtkVolumeMapper::MINIMUM_INTENSITY_BLEND)
00905       {
00906       if (noOfComponents == 4)
00907         {
00908         shaderStr += std::string("\
00909           \n      vec4 scalar = texture3D(in_volume, g_dataPos);\
00910           \n      if (l_minValue.w > scalar.w || l_firstValue)\
00911           \n        {\
00912           \n        l_minValue = scalar;\
00913           \n        }\
00914           \n\
00915           \n     if (l_firstValue)\
00916           \n        {\
00917           \n        l_firstValue = false;\
00918           \n        }"
00919         );
00920         }
00921       else
00922         {
00923         shaderStr += std::string("\
00924           \n      vec4 scalar = texture3D(in_volume, g_dataPos);\
00925           \n      if (l_minValue.w > scalar.x || l_firstValue)\
00926           \n        {\
00927           \n        l_minValue.w = scalar.x;\
00928           \n        }\
00929           \n\
00930           \n     if (l_firstValue)\
00931           \n        {\
00932           \n        l_firstValue = false;\
00933           \n        }"
00934         );
00935         }
00936       }
00937     else if (mapper->GetBlendMode() == vtkVolumeMapper::ADDITIVE_BLEND)
00938       {
00939       shaderStr += std::string("\
00940         \n      vec4 scalar = texture3D(in_volume, g_dataPos);\
00941         \n      float opacity = computeOpacity(scalar);\
00942         \n      l_sumValue = l_sumValue + opacity * scalar.x;"
00943       );
00944       }
00945     else if (mapper->GetBlendMode() == vtkVolumeMapper::COMPOSITE_BLEND)
00946       {
00947       if (noOfComponents > 1 && independentComponents)
00948         {
00949         shaderStr += std::string("\
00950         \n       vec4 color[4]; vec4 tmp = vec4(0.0);\
00951         \n       float totalAlpha = 0.0;\
00952         \n       vec4 scalar = texture3D(in_volume, g_dataPos);\
00953         \n       for (int i = 0; i < in_noOfComponents; ++i)\
00954         \n         {\
00955         ");
00956         if (!mask || !maskInput ||
00957             maskType != vtkGPUVolumeRayCastMapper::LabelMapMaskType)
00958           {
00959           shaderStr += std::string("\
00960           \n          // Data fetching from the red channel of volume texture\
00961           \n          color[i] = vec4(computeColor(scalar, i));\
00962           \n          totalAlpha += color[i][3] * in_componentWeight[i];\
00963           \n          }\
00964           \n       if (totalAlpha > 0.0)\
00965           \n         {\
00966           \n         for (int i = 0; i < in_noOfComponents; ++i)\
00967           \n           {\
00968           \n           tmp.x += color[i].x * color[i].w * in_componentWeight[i] ;\
00969           \n           tmp.y += color[i].y * color[i].w * in_componentWeight[i];\
00970           \n           tmp.z += color[i].z * color[i].w * in_componentWeight[i];\
00971           \n           tmp.w += ((color[i].w * color[i].w)/totalAlpha);\
00972           \n           }\
00973           \n         }\
00974           \n       g_fragColor = (1.0f - g_fragColor.a) * tmp + g_fragColor;"
00975           );
00976           }
00977         }
00978       else
00979         {
00980          if (!mask || !maskInput ||
00981              maskType != vtkGPUVolumeRayCastMapper::LabelMapMaskType)
00982            {
00983            shaderStr += std::string("\
00984              \n      // Data fetching from the red channel of volume texture\
00985              \n      vec4 scalar = texture3D(in_volume, g_dataPos);\
00986              \n      vec4 g_srcColor = computeColor(scalar);"
00987            );
00988            }
00989 
00990          shaderStr += std::string("\
00991            \n      // Opacity calculation using compositing:\
00992            \n      // here we use front to back compositing scheme whereby the current\
00993            \n      // sample value is multiplied to the currently accumulated alpha\
00994            \n      // and then this product is subtracted from the sample value to\
00995            \n      // get the alpha from the previous steps.\
00996            \n      // Next, this alpha is multiplied with the current sample colour\
00997            \n      // and accumulated to the composited colour. The alpha value from\
00998            \n      // the previous steps is then accumulated to the composited colour\
00999            \n      // alpha.\
01000            \n      g_srcColor.rgb *= g_srcColor.a;\
01001            \n      g_fragColor = (1.0f - g_fragColor.a) * g_srcColor + g_fragColor;"
01002          );
01003         }
01004       }
01005      else
01006         {
01007         shaderStr += std::string();
01008         }
01009 
01010       shaderStr += std::string("\
01011         \n      }"
01012       );
01013       return shaderStr;
01014     }
01015 
01016   //--------------------------------------------------------------------------
01017   std::string ShadingExit(vtkRenderer* vtkNotUsed(ren),
01018                           vtkVolumeMapper* mapper,
01019                           vtkVolume* vtkNotUsed(vol),
01020                           int noOfComponents,
01021                           int independentComponents = 0)
01022     {
01023     if (mapper->GetBlendMode() == vtkVolumeMapper::MAXIMUM_INTENSITY_BLEND)
01024       {
01025       if (noOfComponents > 1 && independentComponents)
01026         {
01027         return std::string("\
01028           \n   vec4 g_srcColor = vec4(0);\
01029           \n   for (int i = 0; i < in_noOfComponents; ++i)\
01030           \n     {\
01031           \n     vec4 tmp = computeColor(l_maxValue, i);\
01032           \n     g_srcColor[0] += tmp[0] * tmp[3] * in_componentWeight[i];\
01033           \n     g_srcColor[1] += tmp[1] * tmp[3] * in_componentWeight[i];\
01034           \n     g_srcColor[2] += tmp[2] * tmp[3] * in_componentWeight[i];\
01035           \n     g_srcColor[3] += tmp[3] * in_componentWeight[i];\
01036           \n     }\
01037           \n   g_fragColor = g_srcColor;"
01038         );
01039         }
01040       else
01041         {
01042         return std::string("\
01043          \n  vec4 g_srcColor = vec4(computeColor(l_maxValue).xyz,\
01044          \n                         computeOpacity(l_maxValue));\
01045          \n  g_fragColor.rgb = g_srcColor.rgb * g_srcColor.a;\
01046          \n  g_fragColor.a = g_srcColor.a;"
01047         );
01048         }
01049       }
01050     else if (mapper->GetBlendMode() == vtkVolumeMapper::MINIMUM_INTENSITY_BLEND)
01051       {
01052       if (noOfComponents > 1 && independentComponents)
01053         {
01054         return std::string("\
01055           \n  vec4 g_srcColor = vec4(0);\
01056           \n  for (int i = 0; i < in_noOfComponents; ++i)\
01057           \n    {\
01058           \n    vec4 tmp = computeColor(l_minValue, i);\
01059           \n    g_srcColor[0] += tmp[0] * tmp[3] * in_componentWeight[i];\
01060           \n    g_srcColor[1] += tmp[1] * tmp[3] * in_componentWeight[i];\
01061           \n    g_srcColor[2] += tmp[2] * tmp[3] * in_componentWeight[i];\
01062           \n    g_srcColor[2] += tmp[3] * tmp[3] * in_componentWeight[i];\
01063           \n    }\
01064           \n  g_fragColor = g_srcColor;"
01065         );
01066         }
01067       else
01068         {
01069         return std::string("\
01070           \n  vec4 g_srcColor = vec4(computeColor(l_minValue).xyz,\
01071           \n                         computeOpacity(l_minValue));\
01072           \n  g_fragColor.rgb = g_srcColor.rgb * g_srcColor.a;\
01073           \n  g_fragColor.a = g_srcColor.a;"
01074         );
01075         }
01076       }
01077     else if (mapper->GetBlendMode() == vtkVolumeMapper::ADDITIVE_BLEND)
01078       {
01079       return std::string("\
01080         \n  l_sumValue = clamp(l_sumValue, 0.0, 1.0);\
01081         \n  g_fragColor = vec4(vec3(l_sumValue), 1.0);"
01082       );
01083       }
01084     else
01085       {
01086       return std::string();
01087       }
01088   }
01089 
01090   //--------------------------------------------------------------------------
01091   std::string TerminationGlobalsVert(vtkRenderer* vtkNotUsed(ren),
01092                                      vtkVolumeMapper* vtkNotUsed(mapper),
01093                                      vtkVolume* vtkNotUsed(vol))
01094     {
01095     return std::string();
01096     }
01097 
01098   //--------------------------------------------------------------------------
01099   std::string TerminationGlobalsFrag(vtkRenderer* vtkNotUsed(ren),
01100                                      vtkVolumeMapper* vtkNotUsed(mapper),
01101                                      vtkVolume* vtkNotUsed(vol))
01102     {
01103     return std::string();
01104     }
01105 
01106   //--------------------------------------------------------------------------
01107   std::string TerminationInit(vtkRenderer* vtkNotUsed(ren),
01108                               vtkVolumeMapper* vtkNotUsed(mapper),
01109                               vtkVolume* vtkNotUsed(vol))
01110     {
01111     return std::string("\
01112       \n  // Minimum texture access coordinate\
01113       \n  const vec3 l_tex_min = vec3(0);\
01114       \n\
01115       \n  // Maximum texture access coordinate\
01116       \n  const vec3 l_tex_max = vec3(1);\
01117       \n\
01118       \n  // Flag to indicate if the raymarch loop should terminate \
01119       \n  bool stop = false;\
01120       \n\
01121       \n  // 2D Texture fragment coordinates [0,1] from fragment coordinates \
01122       \n  // the frame buffer texture has the size of the plain buffer but \
01123       \n  // we use a fraction of it. The texture coordinates is less than 1 if \
01124       \n  // the reduction factor is less than 1. \
01125       \n  // Device coordinates are between -1 and 1. We need texture \
01126       \n  // coordinates between 0 and 1 the in_depthSampler buffer has the \
01127       \n  // original size buffer. \
01128       \n  vec2 fragTexCoord = (gl_FragCoord.xy - in_windowLowerLeftCorner) *\
01129       \n                      in_inverseWindowSize;\
01130       \n  vec4 l_depthValue = texture2D(in_depthSampler, fragTexCoord);\
01131       \n  float l_terminatePointMax = 0.0;\
01132       \n\
01133       \n  // Depth test\
01134       \n  if(gl_FragCoord.z >= l_depthValue.x)\
01135       \n    {\
01136       \n    discard;\
01137       \n    }\
01138       \n\
01139       \n  // color buffer or max scalar buffer have a reduced size.\
01140       \n  fragTexCoord = (gl_FragCoord.xy - in_windowLowerLeftCorner) *\
01141       \n                 in_inverseOriginalWindowSize;\
01142       \n\
01143       \n  // Compute max number of iterations it will take before we hit\
01144       \n  // the termination point\
01145       \n\
01146       \n  // Abscissa of the point on the depth buffer along the ray.\
01147       \n  // point in texture coordinates\
01148       \n  vec4 terminatePoint;\
01149       \n  terminatePoint.x = (gl_FragCoord.x - in_windowLowerLeftCorner.x) * 2.0 *\
01150       \n                     in_inverseWindowSize.x - 1.0;\
01151       \n  terminatePoint.y = (gl_FragCoord.y - in_windowLowerLeftCorner.y) * 2.0 *\
01152       \n                     in_inverseWindowSize.y - 1.0;\
01153       \n  terminatePoint.z = (2.0 * l_depthValue.x - (gl_DepthRange.near +\
01154       \n                     gl_DepthRange.far)) / gl_DepthRange.diff;\
01155       \n  terminatePoint.w = 1.0;\
01156       \n\
01157       \n  // From normalized device coordinates to eye coordinates.\
01158       \n  // in_projectionMatrix is inversed because of way VT\
01159       \n  // From eye coordinates to texture coordinates\
01160       \n  terminatePoint = in_inverseTextureDatasetMatrix *\
01161       \n                   in_inverseVolumeMatrix *\
01162       \n                   in_inverseModelViewMatrix *\
01163       \n                   in_inverseProjectionMatrix *\
01164       \n                   terminatePoint;\
01165       \n  terminatePoint /= terminatePoint.w;\
01166       \n\
01167       \n  l_terminatePointMax = length(terminatePoint.xyz - g_dataPos.xyz) /\
01168       \n                        length(g_dirStep);\
01169       \n  float l_currentT = 0.0;");
01170     }
01171 
01172   //--------------------------------------------------------------------------
01173   std::string TerminationIncrement(vtkRenderer* vtkNotUsed(ren),
01174                                    vtkVolumeMapper* vtkNotUsed(mapper),
01175                                    vtkVolume* vtkNotUsed(vol))
01176     {
01177     return std::string("\
01178       \n    // The two constants l_tex_min and l_tex_max have a value of\
01179       \n    // vec3(-1,-1,-1) and vec3(1,1,1) respectively. To determine if the\
01180       \n    // data value is outside the in_volume data, we use the sign function.\
01181       \n    // The sign function return -1 if the value is less than 0, 0 if the\
01182       \n    // value is equal to 0 and 1 if value is greater than 0. Hence, the\
01183       \n    // sign function for the calculation (sign(g_dataPos-l_tex_min) and\
01184       \n    // sign (l_tex_max-g_dataPos)) will give us vec3(1,1,1) at the\
01185       \n    // possible minimum and maximum position.\
01186       \n    // When we do a dot product between two vec3(1,1,1) we get answer 3.\
01187       \n    // So to be within the dataset limits, the dot product will return a\
01188       \n    // value less than 3. If it is greater than 3, we are already out of\
01189       \n    // the in_volume dataset\
01190       \n    stop = dot(sign(g_dataPos - l_tex_min), sign(l_tex_max - g_dataPos))\
01191       \n           < 3.0;\
01192       \n\
01193       \n    // If the stopping condition is true we brek out of the ray marching\
01194       \n    // loop\
01195       \n    if (stop)\
01196       \n      {\
01197       \n      break;\
01198       \n      }\
01199       \n    // Early ray termination\
01200       \n    // if the currently composited colour alpha is already fully saturated\
01201       \n    // we terminated the loop or if we have hit an obstacle in the\
01202       \n    // direction of they ray (using depth buffer) we terminate as well.\
01203       \n    if((g_fragColor.a > (1 - 1/255.0)) || \
01204       \n       l_currentT >= l_terminatePointMax)\
01205       \n      {\
01206       \n      break;\
01207       \n      }\
01208       \n    ++l_currentT;"
01209     );
01210     }
01211 
01212   //--------------------------------------------------------------------------
01213   std::string TerminationExit(vtkRenderer* vtkNotUsed(ren),
01214                               vtkVolumeMapper* vtkNotUsed(mapper),
01215                               vtkVolume* vtkNotUsed(vol))
01216    {
01217     return std::string();
01218    }
01219 
01220   //--------------------------------------------------------------------------
01221   std::string CroppingGlobalsVert(vtkRenderer* vtkNotUsed(ren),
01222                                   vtkVolumeMapper* vtkNotUsed(mapper),
01223                                   vtkVolume* vtkNotUsed(vol))
01224   {
01225     return std::string();
01226   }
01227 
01228   //--------------------------------------------------------------------------
01229   std::string CroppingGlobalsFrag(vtkRenderer* vtkNotUsed(ren),
01230                                   vtkVolumeMapper* mapper,
01231                                   vtkVolume* vtkNotUsed(vol))
01232   {
01233     if (!mapper->GetCropping()) {
01234       return std::string();
01235     }
01236 
01237     return std::string("\
01238       \nuniform float cropping_planes[6];\
01239       \nuniform int cropping_flags [32];\
01240       \n// X: axis = 0, Y: axis = 1, Z: axis = 2\
01241       \n// cp Cropping plane bounds (minX, maxX, minY, maxY, minZ, maxZ)\
01242       \nint computeRegionCoord(float cp[6], vec3 pos, int axis)\
01243       \n  {\
01244       \n  int cpmin = axis * 2;\
01245       \n  int cpmax = cpmin + 1;\
01246       \n\
01247       \n  if (pos[axis] < cp[cpmin])\
01248       \n    {\
01249       \n    return 1;\
01250       \n    }\
01251       \n  else if (pos[axis] >= cp[cpmin] &&\
01252       \n           pos[axis]  < cp[cpmax])\
01253       \n    {\
01254       \n    return 2;\
01255       \n    }\
01256       \n  else if (pos[axis] >= cp[cpmax])\
01257       \n    {\
01258       \n    return 3;\
01259       \n    }\
01260       \n  return 0;\
01261       \n  }\
01262       \n\
01263       \nint computeRegion(float cp[6], vec3 pos)\
01264       \n  {\
01265       \n  return (computeRegionCoord(cp, pos, 0) +\
01266       \n         (computeRegionCoord(cp, pos, 1) - 1) * 3 +\
01267       \n         (computeRegionCoord(cp, pos, 2) - 1) * 9);\
01268       \n  }"
01269     );
01270   }
01271 
01272   //--------------------------------------------------------------------------
01273   std::string CroppingInit(vtkRenderer* vtkNotUsed(ren),
01274                            vtkVolumeMapper* mapper,
01275                            vtkVolume* vtkNotUsed(vol))
01276   {
01277     if (!mapper->GetCropping()) {
01278       return std::string();
01279     }
01280 
01281     return std::string("\
01282       \n  // Convert cropping region to texture space\
01283       \n  float cropping_planes_ts[6];\
01284       \n  mat4  datasetToTextureMat = in_inverseTextureDatasetMatrix;\
01285       \n  vec4 temp = vec4(cropping_planes[0], cropping_planes[1], 0.0, 1.0);\
01286       \n  temp = datasetToTextureMat * temp;\
01287       \n  if (temp[3] != 0.0)\
01288       \n   {\
01289       \n   temp[0] /= temp[3]; temp[1] /= temp[3];\
01290       \n   }\
01291       \n  cropping_planes_ts[0] = temp[0];\
01292       \n  cropping_planes_ts[1] = temp[1];\
01293       \n\
01294       \n  temp = vec4(cropping_planes[2], cropping_planes[3], 0.0, 1.0);\
01295       \n  temp = datasetToTextureMat * temp;\
01296       \n  if (temp[3] != 0.0)\
01297       \n    {\
01298       \n    temp[0] /= temp[3]; temp[1] /= temp[3];\
01299       \n    }\
01300       \n  cropping_planes_ts[2] = temp[0];\
01301       \n  cropping_planes_ts[3] = temp[1];\
01302       \n\
01303       \n  temp = vec4(cropping_planes[4], cropping_planes[5], 0.0, 1.0);\
01304       \n  temp = datasetToTextureMat * temp;\
01305       \n  if (temp[3] != 0.0)\
01306       \n    {\
01307       \n    temp[0] /= temp[3]; temp[1] /= temp[3];\
01308       \n    }\
01309       \n  cropping_planes_ts[4] = temp[0];\
01310       \n  cropping_planes_ts[5] = temp[1];"
01311     );
01312   }
01313 
01314   //--------------------------------------------------------------------------
01315   std::string CroppingIncrement(vtkRenderer* vtkNotUsed(ren),
01316                                 vtkVolumeMapper* mapper,
01317                                 vtkVolume* vtkNotUsed(vol))
01318   {
01319     if (!mapper->GetCropping()) {
01320       return std::string();
01321     }
01322 
01323     return std::string("\
01324       \n    // Determine region\
01325       \n    int regionNo = computeRegion(cropping_planes_ts, g_dataPos);\
01326       \n\
01327       \n    // Do & operation with cropping flags\
01328       \n    // Pass the flag that its Ok to sample or not to sample\
01329       \n    if (cropping_flags[regionNo] == 0)\
01330       \n      {\
01331       \n      // Skip this voxel\
01332       \n      l_skip = true;\
01333       \n      }"
01334     );
01335   }
01336 
01337   //--------------------------------------------------------------------------
01338   std::string CroppingExit(vtkRenderer* vtkNotUsed(ren),
01339                            vtkVolumeMapper* vtkNotUsed(mapper),
01340                            vtkVolume* vtkNotUsed(vol))
01341   {
01342     return std::string();
01343   }
01344 
01345   //--------------------------------------------------------------------------
01346   std::string ClippingGlobalsVert(vtkRenderer* vtkNotUsed(ren),
01347                                   vtkVolumeMapper* vtkNotUsed(mapper),
01348                                   vtkVolume* vtkNotUsed(vol))
01349   {
01350     return std::string();
01351   }
01352 
01353   //--------------------------------------------------------------------------
01354   std::string ClippingGlobalsFrag(vtkRenderer* vtkNotUsed(ren),
01355                                   vtkVolumeMapper* vtkNotUsed(mapper),
01356                                   vtkVolume* vtkNotUsed(vol))
01357   {
01358     return std::string();
01359   }
01360 
01361   //--------------------------------------------------------------------------
01362   std::string ClippingInit(vtkRenderer* vtkNotUsed(ren),
01363                            vtkVolumeMapper* mapper,
01364                            vtkVolume* vtkNotUsed(vol))
01365   {
01366     if (!mapper->GetClippingPlanes())
01367       {
01368       return std::string();
01369       }
01370    else
01371       {
01372       return std::string("\
01373         \nfloat clippingPlanesTexture[48];\
01374         \nint clippingPlanesSize = int(in_clippingPlanes[0]);\
01375         \n\
01376         \nmat4 world_to_texture_mat = in_inverseTextureDatasetMatrix *\
01377         \n                            in_inverseVolumeMatrix;\
01378         \nfor (int i = 0; i < clippingPlanesSize; i = i + 6)\
01379         \n  {\
01380         \n  vec4 origin = vec4(in_clippingPlanes[i + 1],\
01381         \n                     in_clippingPlanes[i + 2],\
01382         \n                     in_clippingPlanes[i + 3], 1.0);\
01383         \n  vec4 normal = vec4(in_clippingPlanes[i + 4],\
01384         \n                     in_clippingPlanes[i + 5],\
01385         \n                     in_clippingPlanes[i + 6], 0.0);\
01386         \n\
01387         \n  origin = world_to_texture_mat * origin;\
01388         \n  normal = world_to_texture_mat * normal;\
01389         \n\
01390         \n  if (origin[3] != 0.0)\
01391         \n    {\
01392         \n    origin[0] = origin[0] / origin[3];\
01393         \n    origin[1] = origin[1] / origin[3];\
01394         \n    origin[2] = origin[2] / origin[3];\
01395         \n    }\
01396         \n  if (normal[3] != 0.0)\
01397         \n    {\
01398         \n    normal[0] = normal[0] / normal[3];\
01399         \n    normal[1] = normal[1] / normal[3];\
01400         \n    normal[2] = normal[2] / normal[3];\
01401         \n    }\
01402         \n\
01403         \n  clippingPlanesTexture[i]     = origin[0];\
01404         \n  clippingPlanesTexture[i + 1] = origin[1];\
01405         \n  clippingPlanesTexture[i + 2] = origin[2];\
01406         \n\
01407         \n  clippingPlanesTexture[i + 3] = normal[0];\
01408         \n  clippingPlanesTexture[i + 4] = normal[1];\
01409         \n  clippingPlanesTexture[i + 5] = normal[2];\
01410         \n  }"
01411       );
01412       }
01413   }
01414 
01415   //--------------------------------------------------------------------------
01416   std::string ClippingIncrement(vtkRenderer* vtkNotUsed(ren),
01417                                 vtkVolumeMapper* mapper,
01418                                 vtkVolume* vtkNotUsed(vol))
01419   {
01420     if (!mapper->GetClippingPlanes())
01421       {
01422       return std::string();
01423       }
01424     else
01425       {
01426       return std::string("\
01427         \n    for (int i = 0; i < (clippingPlanesSize) && !l_skip; i = i + 6)\
01428         \n      {\
01429         \n      if (dot(vec3(g_dataPos - vec3(clippingPlanesTexture[i],\
01430         \n                                    clippingPlanesTexture[i + 1],\
01431         \n                                    clippingPlanesTexture[i + 2])),\
01432         \n              vec3(clippingPlanesTexture[i + 3],\
01433         \n                   clippingPlanesTexture[i + 4],\
01434         \n                   clippingPlanesTexture[i + 5])) < 0)\
01435         \n        {\
01436         \n        l_skip = true;\
01437         \n        break;\
01438         \n        }\
01439         \n      }"
01440       );
01441       }
01442   }
01443 
01444   //--------------------------------------------------------------------------
01445   std::string ClippingExit(vtkRenderer* vtkNotUsed(ren),
01446                            vtkVolumeMapper* vtkNotUsed(mapper),
01447                            vtkVolume* vtkNotUsed(vol))
01448   {
01449     return std::string();
01450   }
01451 
01452   //--------------------------------------------------------------------------
01453   std::string BinaryMaskGlobalsFrag(vtkRenderer* vtkNotUsed(ren),
01454                                     vtkVolumeMapper* vtkNotUsed(mapper),
01455                                     vtkVolume* vtkNotUsed(vol),
01456                                     vtkImageData* maskInput,
01457                                     vtkVolumeMask* mask,
01458                                     int vtkNotUsed(maskType))
01459   {
01460     if (!mask || !maskInput)
01461       {
01462       return std::string();
01463       }
01464     else
01465       {
01466       return std::string("uniform sampler3D in_mask;");
01467       }
01468   }
01469 
01470   //--------------------------------------------------------------------------
01471   std::string BinaryMaskIncrement(vtkRenderer* vtkNotUsed(ren),
01472                                   vtkVolumeMapper* vtkNotUsed(mapper),
01473                                   vtkVolume* vtkNotUsed(vol),
01474                                   vtkImageData* maskInput,
01475                                   vtkVolumeMask* mask,
01476                                   int maskType)
01477   {
01478     if (!mask || !maskInput ||
01479         maskType == vtkGPUVolumeRayCastMapper::LabelMapMaskType)
01480       {
01481       return std::string();
01482       }
01483     else
01484       {
01485       return std::string("\
01486         \nvec4 maskValue = texture3D(in_mask, g_dataPos);\
01487         \nif(maskValue.a <= 0.0)\
01488         \n  {\
01489         \n  l_skip = true;\
01490         \n  }"
01491       );
01492       }
01493   }
01494 
01495   //--------------------------------------------------------------------------
01496   std::string CompositeMaskGlobalsFrag(vtkRenderer* vtkNotUsed(ren),
01497                                        vtkVolumeMapper* vtkNotUsed(mapper),
01498                                        vtkVolume* vtkNotUsed(vol),
01499                                        vtkImageData* maskInput,
01500                                        vtkVolumeMask* mask,
01501                                        int maskType)
01502   {
01503     if (!mask || !maskInput ||
01504         maskType != vtkGPUVolumeRayCastMapper::LabelMapMaskType)
01505       {
01506       return std::string();
01507       }
01508     else
01509       {
01510       return std::string("\
01511         \nuniform float in_maskBlendFactor;\
01512         \nuniform sampler1D in_mask1;\
01513         \nuniform sampler1D in_mask2;"
01514       );
01515       }
01516   }
01517 
01518   //--------------------------------------------------------------------------
01519   std::string CompositeMaskIncrement(vtkRenderer* vtkNotUsed(ren),
01520                                      vtkVolumeMapper* vtkNotUsed(mapper),
01521                                      vtkVolume* vtkNotUsed(vol),
01522                                      vtkImageData* maskInput,
01523                                      vtkVolumeMask* mask,
01524                                      int maskType)
01525   {
01526     if (!mask || !maskInput ||
01527         maskType != vtkGPUVolumeRayCastMapper::LabelMapMaskType)
01528       {
01529       return std::string();
01530       }
01531     else
01532       {
01533       return std::string("\
01534         \nvec4 scalar = texture3D(in_volume, g_dataPos);\
01535         \nif (in_maskBlendFactor == 0.0)\
01536         \n  {\
01537         \n  g_srcColor = computeColor(scalar);\
01538         \n  }\
01539         \nelse\
01540         \n  {\
01541         \n  // Get the mask value at this same location\
01542         \n  vec4 maskValue = texture3D(in_mask, g_dataPos);\
01543         \n  if(maskValue.a == 0.0)\
01544         \n    {\
01545         \n    g_srcColor = computeColor(scalar);\
01546         \n    }\
01547         \n  else\
01548         \n    {\
01549         \n    if (maskValue.a == 1.0/255.0)\
01550         \n      {\
01551         \n      g_srcColor = texture1D(in_mask1, scalar.w);\
01552         \n      }\
01553         \n    else\
01554         \n      {\
01555         \n      // maskValue.a == 2.0/255.0\
01556         \n      g_srcColor = texture1D(in_mask2, scalar.w);\
01557         \n      }\
01558         \n    g_srcColor.a = 1.0;\
01559         \n    if(in_maskBlendFactor < 1.0)\
01560         \n      {\
01561         \n      g_srcColor = (1.0 - in_maskBlendFactor) * computeColor(scalar)\
01562         \n                   + in_maskBlendFactor * g_srcColor;\
01563         \n      }\
01564         \n    }\
01565         \n    g_srcColor.a = computeOpacity(scalar);\
01566         \n  }"
01567       );
01568       }
01569   }
01570 }
01571 
01572 #endif // _vtkVolumeShaderComposer_h
01573 // VTK-HeaderTest-Exclude: vtkVolumeShaderComposer.h