From 1fc7244a1c7338d74968fd726447d6148611543c Mon Sep 17 00:00:00 2001 From: Aashish Chaudhary Date: Wed, 21 Jan 2015 02:12:19 -0500 Subject: [PATCH 01/15] Adding GPU independent component feature Change-Id: Ib778d1b05c46ca886575049a2e23af7a17f0b5be --- .../Volume/Testing/Python/CMakeLists.txt | 1 + .../TestGPURayCastIndependentComponent.py | 119 ++++++++++++++++++ 2 files changed, 120 insertions(+) create mode 100755 Rendering/Volume/Testing/Python/TestGPURayCastIndependentComponent.py diff --git a/Rendering/Volume/Testing/Python/CMakeLists.txt b/Rendering/Volume/Testing/Python/CMakeLists.txt index f9d41e29d6a..15e10fd9dd4 100644 --- a/Rendering/Volume/Testing/Python/CMakeLists.txt +++ b/Rendering/Volume/Testing/Python/CMakeLists.txt @@ -11,6 +11,7 @@ set (GenericVolumePythonTests volRCRotateClip.py VolumePickerCrop.py VolumePicker.py,NO_RT + TestGPURayCastIndependentComponent.py ) # These tests are only built when the rendering backend is OpenGL diff --git a/Rendering/Volume/Testing/Python/TestGPURayCastIndependentComponent.py b/Rendering/Volume/Testing/Python/TestGPURayCastIndependentComponent.py new file mode 100755 index 00000000000..247a1b854fc --- /dev/null +++ b/Rendering/Volume/Testing/Python/TestGPURayCastIndependentComponent.py @@ -0,0 +1,119 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +''' +========================================================================= + + Program: Visualization Toolkit + Module: TestNamedColorsIntegration.py + + Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen + All rights reserved. + See Copyright.txt or http://www.kitware.com/Copyright.htm for details. + + This software is distributed WITHOUT ANY WARRANTY; without even + the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + PURPOSE. See the above copyright notice for more information. + +========================================================================= +''' + +import sys +import vtk +import vtk.test.Testing +from vtk.util.misc import vtkGetDataRoot +VTK_DATA_ROOT = vtkGetDataRoot() + +''' + Prevent .pyc files from being created. + Stops the vtk source being polluted + by .pyc files. +''' +sys.dont_write_bytecode = True + +class TestGPURayCastIndependentComponent(vtk.test.Testing.vtkTest): + + def test(self): + dataRoot = vtkGetDataRoot() + reader = vtk.vtkXMLImageDataReader() + reader.SetFileName("" + str(dataRoot) + "/Data/vase_4comp.vti") + + volume = vtk.vtkVolume() + mapper = vtk.vtkFixedPointVolumeRayCastMapper() + ren = vtk.vtkRenderer() + renWin = vtk.vtkRenderWindow() + iRen = vtk.vtkRenderWindowInteractor() + + # Set connections + mapper.SetInputConnection(reader.GetOutputPort()); + volume.SetMapper(mapper) + ren.AddViewProp(volume) + renWin.AddRenderer(ren) + iRen.SetRenderWindow(renWin) + + # Define opacity transfer function and color functions + opacityFunc1 = vtk.vtkPiecewiseFunction() + opacityFunc1.AddPoint(0.0,0.0); + opacityFunc1.AddPoint(80.0,1.0); + opacityFunc1.AddPoint(255.0,0.0); + + opacityFunc2 = vtk.vtkPiecewiseFunction() + opacityFunc2.AddPoint(0.0,0.0); + opacityFunc2.AddPoint(80.0,1.0); + opacityFunc2.AddPoint(255.0,0.0); + + opacityFunc3 = vtk.vtkPiecewiseFunction() + opacityFunc3.AddPoint(0.0,0.0); + opacityFunc3.AddPoint(80.0,1.0); + opacityFunc3.AddPoint(255.0,0.0); + + opacityFunc4 = vtk.vtkPiecewiseFunction() + opacityFunc4.AddPoint(0.0,0.0); + opacityFunc4.AddPoint(80.0,1.0); + opacityFunc4.AddPoint(255.0,0.0); + + # Color transfer functions + color1 = vtk.vtkColorTransferFunction() + color1.AddRGBPoint(0.0, 0.0, 0.0, 1.0); + color1.AddRGBPoint(40.0, 1.0, 0.0, 0.0); + color1.AddRGBPoint(255.0, 1.0, 1.0, 1.0); + + color2 = vtk.vtkColorTransferFunction() + color2.AddRGBPoint(0.0, 0.0, 0.0, 1.0); + color2.AddRGBPoint(40.0, 1.0, 0.0, 0.0); + color2.AddRGBPoint(255.0, 1.0, 1.0, 1.0); + + color3 = vtk.vtkColorTransferFunction() + color3.AddRGBPoint(0.0, 0.0, 0.0, 1.0); + color3.AddRGBPoint(40.0, 1.0, 0.0, 0.0); + color3.AddRGBPoint(255.0, 1.0, 1.0, 1.0); + + color4 = vtk.vtkColorTransferFunction() + color4.AddRGBPoint(0.0, 0.0, 0.0, 1.0); + color4.AddRGBPoint(40.0, 1.0, 0.0, 0.0); + color4.AddRGBPoint(255.0, 1.0, 1.0, 1.0); + + # Now set the opacity and the color + volumeProperty = volume.GetProperty() + volumeProperty.SetScalarOpacity(0, opacityFunc1); + volumeProperty.SetScalarOpacity(0, opacityFunc2); + volumeProperty.SetScalarOpacity(0, opacityFunc3); + volumeProperty.SetScalarOpacity(0, opacityFunc4); + volumeProperty.SetColor(0, color1); + volumeProperty.SetColor(1, color2); + volumeProperty.SetColor(2, color3); + volumeProperty.SetColor(3, color4); + + iRen.Initialize(); + ren.SetBackground(0.1,0.4,0.2); + ren.ResetCamera(); + renWin.Render() + + #img_file = "TestGPURayCastIndependentComponent.png" + #vtk.test.Testing.compareImage( + # iRen.GetRenderWindow(), vtk.test.Testing.getAbsImagePath(img_file), threshold=10) + #vtk.test.Testing.interact() + iRen.Start() + +if __name__ == "__main__": + vtk.test.Testing.main([(TestGPURayCastIndependentComponent, 'test')]) From e69ee9e7e2ac880959eab190ca3cff31b10cb41e Mon Sep 17 00:00:00 2001 From: Aashish Chaudhary Date: Wed, 21 Jan 2015 03:26:19 -0500 Subject: [PATCH 02/15] Updated test to highlight mappings Change-Id: I418c76542b8cf9e2b549e9fec61535347a1d52b4 --- .../TestGPURayCastIndependentComponent.py | 67 +++++++++---------- 1 file changed, 33 insertions(+), 34 deletions(-) diff --git a/Rendering/Volume/Testing/Python/TestGPURayCastIndependentComponent.py b/Rendering/Volume/Testing/Python/TestGPURayCastIndependentComponent.py index 247a1b854fc..73b8c74f17c 100755 --- a/Rendering/Volume/Testing/Python/TestGPURayCastIndependentComponent.py +++ b/Rendering/Volume/Testing/Python/TestGPURayCastIndependentComponent.py @@ -53,60 +53,59 @@ def test(self): # Define opacity transfer function and color functions opacityFunc1 = vtk.vtkPiecewiseFunction() - opacityFunc1.AddPoint(0.0,0.0); - opacityFunc1.AddPoint(80.0,1.0); - opacityFunc1.AddPoint(255.0,0.0); + opacityFunc1.AddPoint(0.0, 0.0); + opacityFunc1.AddPoint(60.0, 0.1); + opacityFunc1.AddPoint(255.0, 0.0); opacityFunc2 = vtk.vtkPiecewiseFunction() - opacityFunc2.AddPoint(0.0,0.0); - opacityFunc2.AddPoint(80.0,1.0); - opacityFunc2.AddPoint(255.0,0.0); + opacityFunc2.AddPoint(0.0, 0.0); + opacityFunc2.AddPoint(60.0, 0.0); + opacityFunc2.AddPoint(120.0, 0.1); + opacityFunc1.AddPoint(255.0, 0.0); opacityFunc3 = vtk.vtkPiecewiseFunction() - opacityFunc3.AddPoint(0.0,0.0); - opacityFunc3.AddPoint(80.0,1.0); - opacityFunc3.AddPoint(255.0,0.0); + opacityFunc3.AddPoint(0.0, 0.0); + opacityFunc3.AddPoint(120.0, 0.0); + opacityFunc3.AddPoint(180.0, 0.1); + opacityFunc3.AddPoint(255.0, 0.0); opacityFunc4 = vtk.vtkPiecewiseFunction() - opacityFunc4.AddPoint(0.0,0.0); - opacityFunc4.AddPoint(80.0,1.0); - opacityFunc4.AddPoint(255.0,0.0); + opacityFunc4.AddPoint(0.0, 0.0); + opacityFunc4.AddPoint(180.0, 0.0); + opacityFunc4.AddPoint(255.0, 0.1); # Color transfer functions color1 = vtk.vtkColorTransferFunction() - color1.AddRGBPoint(0.0, 0.0, 0.0, 1.0); - color1.AddRGBPoint(40.0, 1.0, 0.0, 0.0); - color1.AddRGBPoint(255.0, 1.0, 1.0, 1.0); + color1.AddRGBPoint(0.0, 1.0, 0.0, 0.0); + color1.AddRGBPoint(60.0, 1.0, 0.0, 0.0); color2 = vtk.vtkColorTransferFunction() - color2.AddRGBPoint(0.0, 0.0, 0.0, 1.0); - color2.AddRGBPoint(40.0, 1.0, 0.0, 0.0); - color2.AddRGBPoint(255.0, 1.0, 1.0, 1.0); + color2.AddRGBPoint(60.0, 0.0, 0.0, 1.0); + color2.AddRGBPoint(120.0, 0.0, 0.0, 1.0); color3 = vtk.vtkColorTransferFunction() - color3.AddRGBPoint(0.0, 0.0, 0.0, 1.0); - color3.AddRGBPoint(40.0, 1.0, 0.0, 0.0); - color3.AddRGBPoint(255.0, 1.0, 1.0, 1.0); + color3.AddRGBPoint(120.0, 0.0, 1.0, 0.0); + color3.AddRGBPoint(180.0, 0.0, 1.0, 0.0); color4 = vtk.vtkColorTransferFunction() - color4.AddRGBPoint(0.0, 0.0, 0.0, 1.0); - color4.AddRGBPoint(40.0, 1.0, 0.0, 0.0); - color4.AddRGBPoint(255.0, 1.0, 1.0, 1.0); + color4.AddRGBPoint(180.0, 0.0, 0.0, 0.0); + color4.AddRGBPoint(239.0, 0.0, 0.0, 0.0); # Now set the opacity and the color volumeProperty = volume.GetProperty() - volumeProperty.SetScalarOpacity(0, opacityFunc1); - volumeProperty.SetScalarOpacity(0, opacityFunc2); - volumeProperty.SetScalarOpacity(0, opacityFunc3); - volumeProperty.SetScalarOpacity(0, opacityFunc4); - volumeProperty.SetColor(0, color1); - volumeProperty.SetColor(1, color2); - volumeProperty.SetColor(2, color3); - volumeProperty.SetColor(3, color4); + volumeProperty.SetIndependentComponents(1) + volumeProperty.SetScalarOpacity(0, opacityFunc1) + volumeProperty.SetScalarOpacity(1, opacityFunc2) + volumeProperty.SetScalarOpacity(2, opacityFunc3) + volumeProperty.SetScalarOpacity(3, opacityFunc4) + volumeProperty.SetColor(0, color1) + volumeProperty.SetColor(1, color2) + volumeProperty.SetColor(2, color3) + volumeProperty.SetColor(3, color4) iRen.Initialize(); - ren.SetBackground(0.1,0.4,0.2); - ren.ResetCamera(); + ren.SetBackground(0.1,0.4,0.2) + ren.ResetCamera() renWin.Render() #img_file = "TestGPURayCastIndependentComponent.png" From be36e1a108c639367b3e611f375baf734eb8235c Mon Sep 17 00:00:00 2001 From: Aashish Chaudhary Date: Wed, 21 Jan 2015 03:35:27 -0500 Subject: [PATCH 03/15] Adding support for multiple components in GPU RayCast Change-Id: Ief0f8073205d43c54ec61df8fe035e230952862b --- .../vtkOpenGLGPUVolumeRayCastMapper.cxx | 56 +++++++++++-------- 1 file changed, 32 insertions(+), 24 deletions(-) diff --git a/Rendering/VolumeOpenGL2/vtkOpenGLGPUVolumeRayCastMapper.cxx b/Rendering/VolumeOpenGL2/vtkOpenGLGPUVolumeRayCastMapper.cxx index 5925b747fa0..dba54f234d8 100644 --- a/Rendering/VolumeOpenGL2/vtkOpenGLGPUVolumeRayCastMapper.cxx +++ b/Rendering/VolumeOpenGL2/vtkOpenGLGPUVolumeRayCastMapper.cxx @@ -226,19 +226,20 @@ class vtkOpenGLGPUVolumeRayCastMapper::vtkInternal // TODO Deal with numberOfScalarComponents > 1 int UpdateColorTransferFunction(vtkRenderer* ren, vtkVolume* vol, - int numberOfScalarComponents); + int numberOfScalarComponents, + unsigned int component); // Update opacity transfer function (not gradient opacity) int UpdateOpacityTransferFunction(vtkRenderer* ren, vtkVolume* vol, int numberOfScalarComponents, - unsigned int level); + unsigned int component); // Update gradient opacity function int UpdateGradientOpacityTransferFunction(vtkRenderer* ren, vtkVolume* vol, int numberOfScalarComponents, - unsigned int level); + unsigned int component); // Update noise texture (used to reduce rendering artifacts // specifically banding effects) @@ -450,9 +451,8 @@ void vtkOpenGLGPUVolumeRayCastMapper::vtkInternal::Initialize( } } - // TODO Currently we are supporting only one level - // Create opacity lookup table - this->OpacityTables = new vtkOpenGLOpacityTables(1); + // We support upto four components + this->OpacityTables = new vtkOpenGLOpacityTables(4); this->Initialized = true; } @@ -844,7 +844,8 @@ void vtkOpenGLGPUVolumeRayCastMapper::vtkInternal::ComputeBounds( //---------------------------------------------------------------------------- int vtkOpenGLGPUVolumeRayCastMapper::vtkInternal::UpdateColorTransferFunction( - vtkRenderer* ren, vtkVolume* vol, int numberOfScalarComponents) + vtkRenderer* ren, vtkVolume* vol, int numberOfScalarComponents, + unsigned int component) { // Build the colormap in a 1D texture. // 1D RGB-texture=mapping from scalar values to color values @@ -896,7 +897,7 @@ int vtkOpenGLGPUVolumeRayCastMapper::vtkInternal::UpdateColorTransferFunction( //---------------------------------------------------------------------------- int vtkOpenGLGPUVolumeRayCastMapper::vtkInternal::UpdateOpacityTransferFunction( vtkRenderer* ren, vtkVolume* vol, int vtkNotUsed(numberOfScalarComponents), - unsigned int level) + unsigned int component) { if (!vol) { @@ -919,7 +920,7 @@ int vtkOpenGLGPUVolumeRayCastMapper::vtkInternal::UpdateOpacityTransferFunction( volumeProperty->GetInterpolationType() == VTK_LINEAR_INTERPOLATION ? vtkTextureObject::Linear : vtkTextureObject::Nearest; - this->OpacityTables->GetTable(level)->Update( + this->OpacityTables->GetTable(component)->Update( scalarOpacity,this->Parent->BlendMode, this->ActualSampleDistance, this->ScalarsRange, @@ -933,7 +934,7 @@ int vtkOpenGLGPUVolumeRayCastMapper::vtkInternal::UpdateOpacityTransferFunction( //---------------------------------------------------------------------------- int vtkOpenGLGPUVolumeRayCastMapper::vtkInternal:: UpdateGradientOpacityTransferFunction(vtkRenderer* ren, vtkVolume* vol, - int vtkNotUsed(numberOfScalarComponents), unsigned int level) + int vtkNotUsed(numberOfScalarComponents), unsigned int component) { if (!vol) { @@ -968,7 +969,7 @@ int vtkOpenGLGPUVolumeRayCastMapper::vtkInternal:: volumeProperty->GetInterpolationType() == VTK_LINEAR_INTERPOLATION ? vtkTextureObject::Linear : vtkTextureObject::Nearest; - this->GradientOpacityTables->GetTable(level)->Update( + this->GradientOpacityTables->GetTable(component)->Update( gradientOpacity, this->ActualSampleDistance, this->ScalarsRange, @@ -2044,8 +2045,12 @@ void vtkOpenGLGPUVolumeRayCastMapper::GPURender(vtkRenderer* ren, // Update in_volume first to make sure states are current vol->Update(); + // Get the input vtkImageData* input = this->GetTransformedInput(); + // Get the volume property (must have one) + vtkVolumeProperty* volumeProperty = vol->GetProperty(); + // Set OpenGL states vtkVolumeStateRAII glState; @@ -2128,7 +2133,7 @@ void vtkOpenGLGPUVolumeRayCastMapper::GPURender(vtkRenderer* ren, vtkOpenGLRenderWindow::SafeDownCast(ren->GetRenderWindow()); this->Impl->ShaderCache = renWin->GetShaderCache(); - if (vol->GetProperty()->GetMTime() > + if (volumeProperty->GetMTime() > this->Impl->ShaderBuildTime.GetMTime() || this->GetMTime() > this->Impl->ShaderBuildTime.GetMTime() || ren->GetActiveCamera()->GetParallelProjection() != @@ -2148,16 +2153,19 @@ void vtkOpenGLGPUVolumeRayCastMapper::GPURender(vtkRenderer* ren, this->Impl->UpdateVolumeGeometry(ren, vol, input); // Update opacity transfer function - // TODO Passing level 0 for now - this->Impl->UpdateOpacityTransferFunction(ren, vol, - scalars->GetNumberOfComponents(), 0); + for (int i = 0; i < volumeProperty->GetIndependentComponents() ? + numberOfScalarComponents : 1; ++i) + { + this->Impl->UpdateOpacityTransferFunction(ren, vol, + scalars->GetNumberOfComponents(), i); - this->Impl->UpdateGradientOpacityTransferFunction(ren, vol, - scalars->GetNumberOfComponents(), 0); + this->Impl->UpdateGradientOpacityTransferFunction(ren, vol, + scalars->GetNumberOfComponents(), i); - // Update transfer color functions - this->Impl->UpdateColorTransferFunction(ren, vol, - scalars->GetNumberOfComponents()); + // Update transfer color functions + this->Impl->UpdateColorTransferFunction(ren, vol, + scalars->GetNumberOfComponents(), i); + } // Update noise sampler texture this->Impl->UpdateNoiseTexture(ren); @@ -2277,16 +2285,16 @@ void vtkOpenGLGPUVolumeRayCastMapper::GPURender(vtkRenderer* ren, } } - fvalue3[0] = fvalue3[1] = fvalue3[2] = vol->GetProperty()->GetAmbient(); + fvalue3[0] = fvalue3[1] = fvalue3[2] = volumeProperty->GetAmbient(); this->Impl->ShaderProgram->SetUniform3f("in_ambient", fvalue3); - fvalue3[0] = fvalue3[1] = fvalue3[2] = vol->GetProperty()->GetDiffuse(); + fvalue3[0] = fvalue3[1] = fvalue3[2] = volumeProperty->GetDiffuse(); this->Impl->ShaderProgram->SetUniform3f("in_diffuse", fvalue3); - fvalue3[0] = fvalue3[1] = fvalue3[2] = vol->GetProperty()->GetSpecular(); + fvalue3[0] = fvalue3[1] = fvalue3[2] = volumeProperty->GetSpecular(); this->Impl->ShaderProgram->SetUniform3f("in_specular", fvalue3); - fvalue3[0] = vol->GetProperty()->GetSpecularPower(); + fvalue3[0] = volumeProperty->GetSpecularPower(); this->Impl->ShaderProgram->SetUniformf("in_shininess", fvalue3[0]); // Look at the OpenGL Camera for the exact aspect computation From 0b0d480ef07d88703cbe9501b32eb83e01f7692b Mon Sep 17 00:00:00 2001 From: Aashish Chaudhary Date: Wed, 21 Jan 2015 10:21:14 -0500 Subject: [PATCH 04/15] Remove limiting check for independent components Change-Id: I0e2b8f5d7d49ec048e36b9d89331a34134d572cf --- .../Testing/Python/TestGPURayCastIndependentComponent.py | 3 ++- Rendering/Volume/vtkGPUVolumeRayCastMapper.cxx | 7 +++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Rendering/Volume/Testing/Python/TestGPURayCastIndependentComponent.py b/Rendering/Volume/Testing/Python/TestGPURayCastIndependentComponent.py index 73b8c74f17c..35d895ef4ab 100755 --- a/Rendering/Volume/Testing/Python/TestGPURayCastIndependentComponent.py +++ b/Rendering/Volume/Testing/Python/TestGPURayCastIndependentComponent.py @@ -39,7 +39,8 @@ def test(self): reader.SetFileName("" + str(dataRoot) + "/Data/vase_4comp.vti") volume = vtk.vtkVolume() - mapper = vtk.vtkFixedPointVolumeRayCastMapper() + #mapper = vtk.vtkFixedPointVolumeRayCastMapper() + mapper = vtk.vtkGPUVolumeRayCastMapper() ren = vtk.vtkRenderer() renWin = vtk.vtkRenderWindow() iRen = vtk.vtkRenderWindowInteractor() diff --git a/Rendering/Volume/vtkGPUVolumeRayCastMapper.cxx b/Rendering/Volume/vtkGPUVolumeRayCastMapper.cxx index c8e66d6e066..c696ca079c0 100644 --- a/Rendering/Volume/vtkGPUVolumeRayCastMapper.cxx +++ b/Rendering/Volume/vtkGPUVolumeRayCastMapper.cxx @@ -374,10 +374,9 @@ int vtkGPUVolumeRayCastMapper::ValidateRender(vtkRenderer *ren, int numberOfComponents = 0; if ( goodSoFar ) { - numberOfComponents=scalars->GetNumberOfComponents(); - if( !( numberOfComponents==1 || - (numberOfComponents==4 && - vol->GetProperty()->GetIndependentComponents()==0))) + numberOfComponents = scalars->GetNumberOfComponents(); + if( !(numberOfComponents ==1 || + numberOfComponents == 4) ) { goodSoFar = 0; vtkErrorMacro(<< "Only one component scalars, or four " From 3a6fcb1c7dbc9671349254c962274d6fa105fba5 Mon Sep 17 00:00:00 2001 From: Aashish Chaudhary Date: Wed, 21 Jan 2015 10:36:43 -0500 Subject: [PATCH 05/15] Adding support for multi RGB tables Change-Id: I155f07cab27ab0f89e11074fa47988f4d65c849d --- .../vtkOpenGLGPUVolumeRayCastMapper.cxx | 40 +++++----- ...GLRGBTable.h => vtkOpenGLVolumeRGBTable.h} | 74 +++++++++++++++++-- 2 files changed, 86 insertions(+), 28 deletions(-) rename Rendering/VolumeOpenGL2/{vtkOpenGLRGBTable.h => vtkOpenGLVolumeRGBTable.h} (68%) diff --git a/Rendering/VolumeOpenGL2/vtkOpenGLGPUVolumeRayCastMapper.cxx b/Rendering/VolumeOpenGL2/vtkOpenGLGPUVolumeRayCastMapper.cxx index dba54f234d8..cfe96ad433a 100644 --- a/Rendering/VolumeOpenGL2/vtkOpenGLGPUVolumeRayCastMapper.cxx +++ b/Rendering/VolumeOpenGL2/vtkOpenGLGPUVolumeRayCastMapper.cxx @@ -17,7 +17,7 @@ #include "vtkOpenGLGradientOpacityTable.h" #include "vtkOpenGLOpacityTable.h" -#include "vtkOpenGLRGBTable.h" +#include "vtkOpenGLVolumeRGBTable.h" #include "vtkVolumeShaderComposer.h" #include "vtkVolumeStateRAII.h" @@ -97,7 +97,7 @@ class vtkOpenGLGPUVolumeRayCastMapper::vtkInternal this->DepthTextureObject = 0; this->TextureWidth = 1024; this->ActualSampleDistance = 1.0; - this->RGBTable = 0; + this->RGBTables = 0; this->OpacityTables = 0; this->Mask1RGBTable = 0; this->Mask2RGBTable = 0; @@ -125,10 +125,10 @@ class vtkOpenGLGPUVolumeRayCastMapper::vtkInternal //-------------------------------------------------------------------------- ~vtkInternal() { - if (this->RGBTable) + if (this->RGBTables) { - delete this->RGBTable; - this->RGBTable = 0; + delete this->RGBTables; + this->RGBTables = 0; } if(this->Mask1RGBTable!=0) @@ -325,10 +325,10 @@ class vtkOpenGLGPUVolumeRayCastMapper::vtkInternal std::ostringstream ExtensionsStringStream; - vtkOpenGLRGBTable* RGBTable; + vtkOpenGLVolumeRGBTables* RGBTables; vtkOpenGLOpacityTables* OpacityTables; - vtkOpenGLRGBTable* Mask1RGBTable; - vtkOpenGLRGBTable* Mask2RGBTable; + vtkOpenGLVolumeRGBTable* Mask1RGBTable; + vtkOpenGLVolumeRGBTable* Mask2RGBTable; vtkOpenGLGradientOpacityTables* GradientOpacityTables; vtkTimeStamp ShaderBuildTime; @@ -436,18 +436,18 @@ void vtkOpenGLGPUVolumeRayCastMapper::vtkInternal::Initialize( err = glGetError(); // Create RGB lookup table - this->RGBTable = new vtkOpenGLRGBTable(); + this->RGBTables = new vtkOpenGLVolumeRGBTables(4); if (this->Parent->MaskInput != 0 && this->Parent->MaskType == LabelMapMaskType) { if(this->Mask1RGBTable == 0) { - this->Mask1RGBTable = new vtkOpenGLRGBTable(); + this->Mask1RGBTable = new vtkOpenGLVolumeRGBTable(); } if(this->Mask2RGBTable == 0) { - this->Mask2RGBTable = new vtkOpenGLRGBTable(); + this->Mask2RGBTable = new vtkOpenGLVolumeRGBTable(); } } @@ -866,10 +866,10 @@ int vtkOpenGLGPUVolumeRayCastMapper::vtkInternal::UpdateColorTransferFunction( int filterVal = volumeProperty->GetInterpolationType() == VTK_LINEAR_INTERPOLATION ? vtkTextureObject::Linear : vtkTextureObject::Nearest; - this->RGBTable->Update( + this->RGBTables->GetTable(component)->Update( colorTransferFunction, this->ScalarsRange, - filterVal, - vtkOpenGLRenderWindow::SafeDownCast(ren->GetRenderWindow())); + filterVal, + vtkOpenGLRenderWindow::SafeDownCast(ren->GetRenderWindow())); } if (this->Parent->MaskInput != 0 && @@ -1770,11 +1770,11 @@ void vtkOpenGLGPUVolumeRayCastMapper::ReleaseGraphicsResources( } } - if(this->Impl->RGBTable) + if(this->Impl->RGBTables) { - this->Impl->RGBTable->ReleaseGraphicsResources(window); - delete this->Impl->RGBTable; - this->Impl->RGBTable = 0; + this->Impl->RGBTables->ReleaseGraphicsResources(window); + delete this->Impl->RGBTables; + this->Impl->RGBTables = 0; } if(this->Impl->Mask1RGBTable) @@ -2267,9 +2267,9 @@ void vtkOpenGLGPUVolumeRayCastMapper::GPURender(vtkRenderer* ren, if(numberOfScalarComponents == 1 && this->BlendMode!=vtkGPUVolumeRayCastMapper::ADDITIVE_BLEND) { - this->Impl->RGBTable->Bind(); + this->Impl->RGBTables->GetTable(0)->Bind(); this->Impl->ShaderProgram->SetUniformi("in_colorTransferFunc", - this->Impl->RGBTable->GetTextureUnit()); + this->Impl->RGBTables->GetTable(0)->GetTextureUnit()); if (this->MaskInput != 0 && this->MaskType == LabelMapMaskType) { diff --git a/Rendering/VolumeOpenGL2/vtkOpenGLRGBTable.h b/Rendering/VolumeOpenGL2/vtkOpenGLVolumeRGBTable.h similarity index 68% rename from Rendering/VolumeOpenGL2/vtkOpenGLRGBTable.h rename to Rendering/VolumeOpenGL2/vtkOpenGLVolumeRGBTable.h index ae7022abefe..14e78948b8b 100644 --- a/Rendering/VolumeOpenGL2/vtkOpenGLRGBTable.h +++ b/Rendering/VolumeOpenGL2/vtkOpenGLVolumeRGBTable.h @@ -1,7 +1,7 @@ /*========================================================================= Program: Visualization Toolkit - Module: vtkOpenGLRGBTable.h + Module: vtkOpenGLVolumeRGBTable.h Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen All rights reserved. @@ -13,19 +13,19 @@ =========================================================================*/ -#ifndef vtkOpenGLRGBTable_h_ -#define vtkOpenGLRGBTable_h_ +#ifndef vtkOpenGLVolumeRGBTable_h_ +#define vtkOpenGLVolumeRGBTable_h_ #include #include #include //---------------------------------------------------------------------------- -class vtkOpenGLRGBTable +class vtkOpenGLVolumeRGBTable { public: //-------------------------------------------------------------------------- - vtkOpenGLRGBTable() + vtkOpenGLVolumeRGBTable() { this->TextureWidth = 1024; this->NumberOfColorComponents = 3; @@ -36,7 +36,7 @@ class vtkOpenGLRGBTable } //-------------------------------------------------------------------------- - ~vtkOpenGLRGBTable() + ~vtkOpenGLVolumeRGBTable() { if (this->TextureObject) { @@ -151,5 +151,63 @@ class vtkOpenGLRGBTable vtkTimeStamp BuildTime; }; -#endif // vtkOpenGLRGBTable_h_ -// VTK-HeaderTest-Exclude: vtkOpenGLRGBTable.h +//---------------------------------------------------------------------------- +class vtkOpenGLVolumeRGBTables +{ +public: + //-------------------------------------------------------------------------- + vtkOpenGLVolumeRGBTables(unsigned int numberOfTables) + { + this->Tables = new vtkOpenGLVolumeRGBTable[numberOfTables]; + this->NumberOfTables = numberOfTables; + } + + //-------------------------------------------------------------------------- + ~vtkOpenGLVolumeRGBTables() + { + delete [] this->Tables; + } + + // brief Get opacity table at a given index. + //-------------------------------------------------------------------------- + vtkOpenGLVolumeRGBTable* GetTable(unsigned int i) + { + if (i >= this->NumberOfTables) + { + return NULL; + } + return &this->Tables[i]; + } + + // Get number of opacity tables. + //-------------------------------------------------------------------------- + unsigned int GetNumberOfTables() + { + return this->NumberOfTables; + } + + //-------------------------------------------------------------------------- + void ReleaseGraphicsResources(vtkWindow *window) + { + for (unsigned int i = 0; i NumberOfTables; ++i) + { + this->Tables[i].ReleaseGraphicsResources(window); + } + } + +private: + unsigned int NumberOfTables; + vtkOpenGLVolumeRGBTable* Tables; + + // vtkOpenGLVolumeRGBTables (Not implemented) + vtkOpenGLVolumeRGBTables(); + + // vtkOpenGLVolumeRGBTables (Not implemented) + vtkOpenGLVolumeRGBTables(const vtkOpenGLVolumeRGBTables &other); + + // operator = (Not implemented) + vtkOpenGLVolumeRGBTables &operator=(const vtkOpenGLVolumeRGBTables &other); +}; + +#endif // vtkOpenGLVolumeRGBTable_h_ +// VTK-HeaderTest-Exclude: vtkOpenGLVolumeRGBTable.h From c4f763b846e6719d9504497b981237293b544b0e Mon Sep 17 00:00:00 2001 From: Aashish Chaudhary Date: Wed, 21 Jan 2015 11:45:51 -0500 Subject: [PATCH 06/15] Fixed erroneous logic Change-Id: Ia7da69a5fbc51e541aa055affab76e6ee8f484cb --- Rendering/VolumeOpenGL2/vtkOpenGLGPUVolumeRayCastMapper.cxx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Rendering/VolumeOpenGL2/vtkOpenGLGPUVolumeRayCastMapper.cxx b/Rendering/VolumeOpenGL2/vtkOpenGLGPUVolumeRayCastMapper.cxx index cfe96ad433a..90378e655b9 100644 --- a/Rendering/VolumeOpenGL2/vtkOpenGLGPUVolumeRayCastMapper.cxx +++ b/Rendering/VolumeOpenGL2/vtkOpenGLGPUVolumeRayCastMapper.cxx @@ -2153,8 +2153,8 @@ void vtkOpenGLGPUVolumeRayCastMapper::GPURender(vtkRenderer* ren, this->Impl->UpdateVolumeGeometry(ren, vol, input); // Update opacity transfer function - for (int i = 0; i < volumeProperty->GetIndependentComponents() ? - numberOfScalarComponents : 1; ++i) + for (int i = 0; i < (volumeProperty->GetIndependentComponents() ? + numberOfScalarComponents : 1); ++i) { this->Impl->UpdateOpacityTransferFunction(ren, vol, scalars->GetNumberOfComponents(), i); From 10661b2aa869940e144776bc57a7260efb519545 Mon Sep 17 00:00:00 2001 From: Aashish Chaudhary Date: Wed, 21 Jan 2015 12:16:06 -0500 Subject: [PATCH 07/15] Updating shader code to support independent components Change-Id: I6bd22dd6b9c1c6a2fcd2b3042b5ca323bd97afc5 --- .../TestGPURayCastIndependentComponent.py | 2 +- .../vtkOpenGLGPUVolumeRayCastMapper.cxx | 28 +++++++---- .../VolumeOpenGL2/vtkVolumeShaderComposer.h | 49 ++++++++++++++----- 3 files changed, 58 insertions(+), 21 deletions(-) diff --git a/Rendering/Volume/Testing/Python/TestGPURayCastIndependentComponent.py b/Rendering/Volume/Testing/Python/TestGPURayCastIndependentComponent.py index 35d895ef4ab..0652b53019b 100755 --- a/Rendering/Volume/Testing/Python/TestGPURayCastIndependentComponent.py +++ b/Rendering/Volume/Testing/Python/TestGPURayCastIndependentComponent.py @@ -5,7 +5,7 @@ ========================================================================= Program: Visualization Toolkit - Module: TestNamedColorsIntegration.py + Module: TestGPURayCastIndependentComponent.py Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen All rights reserved. diff --git a/Rendering/VolumeOpenGL2/vtkOpenGLGPUVolumeRayCastMapper.cxx b/Rendering/VolumeOpenGL2/vtkOpenGLGPUVolumeRayCastMapper.cxx index 90378e655b9..3d2979f2be4 100644 --- a/Rendering/VolumeOpenGL2/vtkOpenGLGPUVolumeRayCastMapper.cxx +++ b/Rendering/VolumeOpenGL2/vtkOpenGLGPUVolumeRayCastMapper.cxx @@ -1814,7 +1814,10 @@ void vtkOpenGLGPUVolumeRayCastMapper::BuildShader(vtkRenderer* ren, std::string vertexShader (raycastervs); std::string fragmentShader (raycasterfs); - if (vol->GetProperty()->GetShade()) + // Every volume should have a property (cannot be NULL); + vtkVolumeProperty* volumeProperty = vol->GetProperty(); + + if (volumeProperty->GetShade()) { vtkLightCollection* lc = ren->GetLights(); vtkLight* light; @@ -1890,18 +1893,25 @@ void vtkOpenGLGPUVolumeRayCastMapper::BuildShader(vtkRenderer* ren, fragmentShader = vtkvolume::replace(fragmentShader, "//VTK::Shading::Exit", vtkvolume::ShadingExit(ren, this, vol), true); - fragmentShader = vtkvolume::replace(fragmentShader, "//VTK::ComputeOpacity::Dec", - vtkvolume::OpacityTransferFunc(ren, this, vol, noOfComponents), true); + fragmentShader = vtkvolume::replace(fragmentShader, + "//VTK::ComputeOpacity::Dec", + vtkvolume::OpacityTransferFunc(ren, this, vol, noOfComponents, + volumeProperty->GetIndependentComponents()), + true); fragmentShader = vtkvolume::replace(fragmentShader, "//VTK::ComputeGradient::Dec", vtkvolume::GradientsComputeFunc(ren, this, vol, noOfComponents), true); - fragmentShader = vtkvolume::replace(fragmentShader, "//VTK::ColorTransferFunc::Dec", - vtkvolume::ColorTransferFunc(ren, this, vol, noOfComponents), true); - fragmentShader = vtkvolume::replace(fragmentShader, "//VTK::ComputeLighting::Dec", + fragmentShader = vtkvolume::replace(fragmentShader, + "//VTK::ColorTransferFunc::Dec", + vtkvolume::ColorTransferFunc(ren, this, vol, noOfComponents, + volumeProperty->GetIndependentComponents()), + true); + fragmentShader = vtkvolume::replace(fragmentShader, + "//VTK::ComputeLighting::Dec", vtkvolume::LightComputeFunc(ren, this, vol, noOfComponents, - this->Impl->NumberOfLights, - this->Impl->LightComplexity), true); + this->Impl->NumberOfLights, + this->Impl->LightComplexity), true); fragmentShader = vtkvolume::replace(fragmentShader, - "//VTK::RayDirectionFunc::Dec", + "//VTK::RayDirectionFunc::Dec", vtkvolume::RayDirectionFunc(ren, this, vol,noOfComponents), true); vertexShader = vtkvolume::replace(vertexShader, "//VTK::Cropping::Dec", diff --git a/Rendering/VolumeOpenGL2/vtkVolumeShaderComposer.h b/Rendering/VolumeOpenGL2/vtkVolumeShaderComposer.h index 302226d21ca..78d96647fb1 100644 --- a/Rendering/VolumeOpenGL2/vtkVolumeShaderComposer.h +++ b/Rendering/VolumeOpenGL2/vtkVolumeShaderComposer.h @@ -624,7 +624,8 @@ namespace vtkvolume std::string ColorTransferFunc(vtkRenderer* vtkNotUsed(ren), vtkVolumeMapper* vtkNotUsed(mapper), vtkVolume* vtkNotUsed(vol), - int numberOfComponents) + int numberOfComponents, + bool independentComponents = false) { if (numberOfComponents == 1) { @@ -637,26 +638,52 @@ namespace vtkvolume \n computeOpacity(scalar)));\ \n }"); } - + else if (numberOfComponents > 1 && independentComponents) + { return std::string("\ - \nvec4 computeColor(vec4 scalar)\ + \nuniform sampler1D in_colorTransferFunc[4];\ + \nvec4 computeColor(vec4 scalar, int component)\ \n {\ - \n return computeLighting(vec4(scalar.xyz, computeOpacity(scalar)));\ + \n return computeLighting(vec4(texture1D(\ + \n in_colorTransferFunc[component],\ + \n scalar[component]).xyz,\ + \n computeOpacity(scalar, component)));\ \n }"); + } + + return std::string("\ + \nvec4 computeColor(vec4 scalar)\ + \n {\ + \n return computeLighting(vec4(scalar.xyz, computeOpacity(scalar)));\ + \n }"); } //-------------------------------------------------------------------------- std::string OpacityTransferFunc(vtkRenderer* vtkNotUsed(ren), vtkVolumeMapper* vtkNotUsed(mapper), vtkVolume* vtkNotUsed(vol), - int vtkNotUsed(numberOfComponents)) + int numberOfComponents, + bool independentComponents = false) { - return std::string("\ - \nuniform sampler1D in_opacityTransferFunc;\ - \nfloat computeOpacity(vec4 scalar)\ - \n {\ - \n return texture1D(in_opacityTransferFunc, scalar.w).w;\ - \n }"); + if (numberOfComponents > 1 && independentComponents) + { + return std::string("\ + \nuniform sampler1D in_opacityTransferFunc[4];\ + \nfloat computeOpacity(vec4 scalar, int component)\ + \n {\ + \n return texture1D(in_opacityTransferFunc[component],\ + \n scalar[component]).w;\ + \n }"); + } + else + { + return std::string("\ + \nuniform sampler1D in_opacityTransferFunc;\ + \nfloat computeOpacity(vec4 scalar)\ + \n {\ + \n return texture1D(in_opacityTransferFunc, scalar.w).w;\ + \n }"); + } } //-------------------------------------------------------------------------- From 825429b528e83e4e3ad4b50b44629ca8a5e6a810 Mon Sep 17 00:00:00 2001 From: Aashish Chaudhary Date: Wed, 21 Jan 2015 13:02:12 -0500 Subject: [PATCH 08/15] Adding support for independent components for opacity and color function Change-Id: Idba427521e44552c6c07fcfbf5b6c819db4b9f2d --- .../vtkOpenGLGPUVolumeRayCastMapper.cxx | 19 +++-- .../VolumeOpenGL2/vtkVolumeShaderComposer.h | 74 +++++++++++++------ 2 files changed, 66 insertions(+), 27 deletions(-) diff --git a/Rendering/VolumeOpenGL2/vtkOpenGLGPUVolumeRayCastMapper.cxx b/Rendering/VolumeOpenGL2/vtkOpenGLGPUVolumeRayCastMapper.cxx index 3d2979f2be4..8c2159b87f3 100644 --- a/Rendering/VolumeOpenGL2/vtkOpenGLGPUVolumeRayCastMapper.cxx +++ b/Rendering/VolumeOpenGL2/vtkOpenGLGPUVolumeRayCastMapper.cxx @@ -1816,6 +1816,7 @@ void vtkOpenGLGPUVolumeRayCastMapper::BuildShader(vtkRenderer* ren, // Every volume should have a property (cannot be NULL); vtkVolumeProperty* volumeProperty = vol->GetProperty(); + bool independentComponents = volumeProperty->GetIndependentComponents(); if (volumeProperty->GetShade()) { @@ -1861,7 +1862,8 @@ void vtkOpenGLGPUVolumeRayCastMapper::BuildShader(vtkRenderer* ren, vtkvolume::BaseGlobalsVert(ren, this, vol), true); fragmentShader = vtkvolume::replace(fragmentShader, "//VTK::Base::Dec", vtkvolume::BaseGlobalsFrag(ren, this, vol, this->Impl->NumberOfLights, - this->Impl->LightComplexity), true); + this->Impl->LightComplexity, noOfComponents, + independentComponents), true); fragmentShader = vtkvolume::replace(fragmentShader, "//VTK::Base::Init", vtkvolume::BaseInit(ren, this, vol), true); fragmentShader = vtkvolume::replace(fragmentShader, "//VTK::Base::Impl", @@ -1889,22 +1891,21 @@ void vtkOpenGLGPUVolumeRayCastMapper::BuildShader(vtkRenderer* ren, fragmentShader = vtkvolume::replace(fragmentShader, "//VTK::Shading::Impl", vtkvolume::ShadingIncrement(ren, this, vol, this->MaskInput, this->Impl->CurrentMask, - this->MaskType, noOfComponents), true); + this->MaskType, noOfComponents, + independentComponents), true); fragmentShader = vtkvolume::replace(fragmentShader, "//VTK::Shading::Exit", vtkvolume::ShadingExit(ren, this, vol), true); fragmentShader = vtkvolume::replace(fragmentShader, "//VTK::ComputeOpacity::Dec", vtkvolume::OpacityTransferFunc(ren, this, vol, noOfComponents, - volumeProperty->GetIndependentComponents()), - true); + independentComponents), true); fragmentShader = vtkvolume::replace(fragmentShader, "//VTK::ComputeGradient::Dec", vtkvolume::GradientsComputeFunc(ren, this, vol, noOfComponents), true); fragmentShader = vtkvolume::replace(fragmentShader, "//VTK::ColorTransferFunc::Dec", vtkvolume::ColorTransferFunc(ren, this, vol, noOfComponents, - volumeProperty->GetIndependentComponents()), - true); + independentComponents), true); fragmentShader = vtkvolume::replace(fragmentShader, "//VTK::ComputeLighting::Dec", vtkvolume::LightComputeFunc(ren, this, vol, noOfComponents, @@ -2226,6 +2227,12 @@ void vtkOpenGLGPUVolumeRayCastMapper::GPURender(vtkRenderer* ren, } // Pass constant uniforms at initialization + this->Impl->ShaderProgram->SetUniformi("in_noOfComponents", + numberOfScalarComponents); + this->Impl->ShaderProgram->SetUniformi("in_independentComponents", + volumeProperty->GetIndependentComponents()); + + // Step should be dependant on the bounds and not on the texture size // since we can have non uniform voxel size / spacing / aspect ratio vtkInternal::ToFloat(this->Impl->CellStep, fvalue3); diff --git a/Rendering/VolumeOpenGL2/vtkVolumeShaderComposer.h b/Rendering/VolumeOpenGL2/vtkVolumeShaderComposer.h index 78d96647fb1..6408c293a51 100644 --- a/Rendering/VolumeOpenGL2/vtkVolumeShaderComposer.h +++ b/Rendering/VolumeOpenGL2/vtkVolumeShaderComposer.h @@ -100,11 +100,15 @@ namespace vtkvolume vtkVolumeMapper* vtkNotUsed(mapper), vtkVolume* vtkNotUsed(vol), int vtkNotUsed(numberOfLights), - int lightingComplexity) + int lightingComplexity, + int noOfComponents = 1, + bool independentComponents = false) { std::string shaderStr = std::string("\ \n// Volume dataset\ \nuniform sampler3D in_volume;\ + \nuniform int in_noOfComponents;\ + \nuniform int in_independentComponents;\ \n\ \nuniform sampler2D in_noiseSampler;\ \nuniform sampler2D in_depthSampler;\ @@ -740,7 +744,8 @@ namespace vtkvolume vtkVolume* vtkNotUsed(vol), vtkImageData* maskInput, vtkVolumeMask* mask, int maskType, - int noOfComponents) + int noOfComponents, + bool independentComponents = false) { std::string shaderStr = std::string("\ \n if (!l_skip)\ @@ -803,29 +808,56 @@ namespace vtkvolume } else if (mapper->GetBlendMode() == vtkVolumeMapper::COMPOSITE_BLEND) { - if (!mask || !maskInput || - maskType != vtkGPUVolumeRayCastMapper::LabelMapMaskType) + if (noOfComponents > 1 && independentComponents) { shaderStr += std::string("\ - \n // Data fetching from the red channel of volume texture\ - \n vec4 scalar = texture3D(in_volume, g_dataPos);\ - \n vec4 g_srcColor = computeColor(scalar);" - ); + \n for (int i = 0; i < in_noOfComponents; ++i)\ + \n {\ + "); + // TODO Remove duplication + if (!mask || !maskInput || + maskType != vtkGPUVolumeRayCastMapper::LabelMapMaskType) + { + shaderStr += std::string("\ + \n // Data fetching from the red channel of volume texture\ + \n vec4 scalar = texture3D(in_volume, g_dataPos);\ + \n vec4 g_srcColor = computeColor(scalar, i);" + ); + } + + shaderStr += std::string("\ + \n g_srcColor.rgb *= g_srcColor.a;\ + \n g_fragColor += (1.0f - g_fragColor.a) * g_srcColor + g_fragColor;\ + \n }\ + \n g_fragColor /= in_noOfComponents;" + ); } + else + { + if (!mask || !maskInput || + maskType != vtkGPUVolumeRayCastMapper::LabelMapMaskType) + { + shaderStr += std::string("\ + \n // Data fetching from the red channel of volume texture\ + \n vec4 scalar = texture3D(in_volume, g_dataPos);\ + \n vec4 g_srcColor = computeColor(scalar);" + ); + } - shaderStr += std::string("\ - \n // Opacity calculation using compositing:\ - \n // here we use front to back compositing scheme whereby the current\ - \n // sample value is multiplied to the currently accumulated alpha\ - \n // and then this product is subtracted from the sample value to\ - \n // get the alpha from the previous steps.\ - \n // Next, this alpha is multiplied with the current sample colour\ - \n // and accumulated to the composited colour. The alpha value from\ - \n // the previous steps is then accumulated to the composited colour\ - \n // alpha.\ - \n g_srcColor.rgb *= g_srcColor.a;\ - \n g_fragColor = (1.0f - g_fragColor.a) * g_srcColor + g_fragColor;" - ); + shaderStr += std::string("\ + \n // Opacity calculation using compositing:\ + \n // here we use front to back compositing scheme whereby the current\ + \n // sample value is multiplied to the currently accumulated alpha\ + \n // and then this product is subtracted from the sample value to\ + \n // get the alpha from the previous steps.\ + \n // Next, this alpha is multiplied with the current sample colour\ + \n // and accumulated to the composited colour. The alpha value from\ + \n // the previous steps is then accumulated to the composited colour\ + \n // alpha.\ + \n g_srcColor.rgb *= g_srcColor.a;\ + \n g_fragColor = (1.0f - g_fragColor.a) * g_srcColor + g_fragColor;" + ); + } } else { From 840c9ee7308e02bc6d618874b5224dfe1962e4d4 Mon Sep 17 00:00:00 2001 From: Aashish Chaudhary Date: Wed, 21 Jan 2015 17:55:43 -0500 Subject: [PATCH 09/15] Some more updates to support independent components Change-Id: Ie4209bbdefb00e09f6d716c3ff275734c8b98abb --- .../TestGPURayCastIndependentComponent.py | 2 + .../vtkOpenGLGPUVolumeRayCastMapper.cxx | 104 ++++++++++++------ 2 files changed, 70 insertions(+), 36 deletions(-) diff --git a/Rendering/Volume/Testing/Python/TestGPURayCastIndependentComponent.py b/Rendering/Volume/Testing/Python/TestGPURayCastIndependentComponent.py index 0652b53019b..8970eebb742 100755 --- a/Rendering/Volume/Testing/Python/TestGPURayCastIndependentComponent.py +++ b/Rendering/Volume/Testing/Python/TestGPURayCastIndependentComponent.py @@ -41,6 +41,8 @@ def test(self): volume = vtk.vtkVolume() #mapper = vtk.vtkFixedPointVolumeRayCastMapper() mapper = vtk.vtkGPUVolumeRayCastMapper() + mapper.SetSampleDistance(0.1) + mapper.SetAutoAdjustSampleDistances(0) ren = vtk.vtkRenderer() renWin = vtk.vtkRenderWindow() iRen = vtk.vtkRenderWindowInteractor() diff --git a/Rendering/VolumeOpenGL2/vtkOpenGLGPUVolumeRayCastMapper.cxx b/Rendering/VolumeOpenGL2/vtkOpenGLGPUVolumeRayCastMapper.cxx index 8c2159b87f3..6a7075f609e 100644 --- a/Rendering/VolumeOpenGL2/vtkOpenGLGPUVolumeRayCastMapper.cxx +++ b/Rendering/VolumeOpenGL2/vtkOpenGLGPUVolumeRayCastMapper.cxx @@ -844,33 +844,34 @@ void vtkOpenGLGPUVolumeRayCastMapper::vtkInternal::ComputeBounds( //---------------------------------------------------------------------------- int vtkOpenGLGPUVolumeRayCastMapper::vtkInternal::UpdateColorTransferFunction( - vtkRenderer* ren, vtkVolume* vol, int numberOfScalarComponents, + vtkRenderer* ren, vtkVolume* vol, int vtkNotUsed(numberOfScalarComponents), unsigned int component) { + // Volume property cannot be null. + vtkVolumeProperty* volumeProperty = vol->GetProperty(); + // Build the colormap in a 1D texture. // 1D RGB-texture=mapping from scalar values to color values // build the table. - if(numberOfScalarComponents == 1) + vtkColorTransferFunction* colorTransferFunction = + volumeProperty->GetRGBTransferFunction(component); + + // Add points only if its not being added before + if (colorTransferFunction->GetSize() < 1) { - vtkVolumeProperty* volumeProperty = vol->GetProperty(); - vtkColorTransferFunction* colorTransferFunction = - volumeProperty->GetRGBTransferFunction(0); + colorTransferFunction->AddRGBPoint(this->ScalarsRange[0], 0.0, 0.0, 0.0); + colorTransferFunction->AddRGBPoint(this->ScalarsRange[1], 1.0, 1.0, 1.0); + } - // Add points only if its not being added before - if (colorTransferFunction->GetSize() < 1) - { - colorTransferFunction->AddRGBPoint(this->ScalarsRange[0], 0.0, 0.0, 0.0); - colorTransferFunction->AddRGBPoint(this->ScalarsRange[1], 1.0, 1.0, 1.0); - } + int filterVal = + volumeProperty->GetInterpolationType() == VTK_LINEAR_INTERPOLATION ? + vtkTextureObject::Linear : vtkTextureObject::Nearest; - int filterVal = - volumeProperty->GetInterpolationType() == VTK_LINEAR_INTERPOLATION ? - vtkTextureObject::Linear : vtkTextureObject::Nearest; - this->RGBTables->GetTable(component)->Update( - colorTransferFunction, this->ScalarsRange, - filterVal, - vtkOpenGLRenderWindow::SafeDownCast(ren->GetRenderWindow())); - } + this->RGBTables->GetTable(component)->Update( + volumeProperty->GetRGBTransferFunction(component), + this->ScalarsRange, + filterVal, + vtkOpenGLRenderWindow::SafeDownCast(ren->GetRenderWindow())); if (this->Parent->MaskInput != 0 && this->Parent->MaskType == LabelMapMaskType) @@ -906,7 +907,8 @@ int vtkOpenGLGPUVolumeRayCastMapper::vtkInternal::UpdateOpacityTransferFunction( } vtkVolumeProperty* volumeProperty = vol->GetProperty(); - vtkPiecewiseFunction* scalarOpacity = volumeProperty->GetScalarOpacity(); + vtkPiecewiseFunction* scalarOpacity = + volumeProperty->GetScalarOpacity(component); // TODO: Do a better job to create the default opacity map // Add points only if its not being added before @@ -924,7 +926,7 @@ int vtkOpenGLGPUVolumeRayCastMapper::vtkInternal::UpdateOpacityTransferFunction( scalarOpacity,this->Parent->BlendMode, this->ActualSampleDistance, this->ScalarsRange, - volumeProperty->GetScalarOpacityUnitDistance(), + volumeProperty->GetScalarOpacityUnitDistance(component), filterVal, vtkOpenGLRenderWindow::SafeDownCast(ren->GetRenderWindow())); @@ -2255,10 +2257,50 @@ void vtkOpenGLGPUVolumeRayCastMapper::GPURender(vtkRenderer* ren, this->Impl->ShaderProgram->SetUniformi("in_volume", this->Impl->VolumeTextureObject->GetTextureUnit()); - // TODO Supports only one table for now - this->Impl->OpacityTables->GetTable(0)->Bind(); - this->Impl->ShaderProgram->SetUniformi("in_opacityTransferFunc", - this->Impl->OpacityTables->GetTable(0)->GetTextureUnit()); + // Opacity, color, and gradient opacity samplers / textures + int opacitySamplers[4]; + int colorSamplers[4]; + int gradientOpacitySamplers[4]; + int numberOfSamplers = (volumeProperty->GetIndependentComponents() ? + numberOfScalarComponents : 1); + for (int i = 0; i < numberOfSamplers; ++i) + { + this->Impl->OpacityTables->GetTable(i)->Bind(); + opacitySamplers[i] = + this->Impl->OpacityTables->GetTable(i)->GetTextureUnit(); + + if (this->BlendMode != vtkGPUVolumeRayCastMapper::ADDITIVE_BLEND) + { + this->Impl->RGBTables->GetTable(i)->Bind(); + colorSamplers[i] = + this->Impl->RGBTables->GetTable(i)->GetTextureUnit(); + std::cerr << colorSamplers[i] << std::endl; + } + + if (this->Impl->GradientOpacityTables) + { + gradientOpacitySamplers[i] = + this->Impl->GradientOpacityTables->GetTable(i)->GetTextureUnit(); + } + } + + this->Impl->ShaderProgram->SetUniform1iv("in_opacityTransferFunc", + numberOfSamplers, opacitySamplers); + vtkOpenGLCheckErrorMacro("failed at glBindTexture"); + + if (this->BlendMode != vtkGPUVolumeRayCastMapper::ADDITIVE_BLEND) + { + this->Impl->ShaderProgram->SetUniform1iv("in_colorTransferFunc", + numberOfSamplers, colorSamplers); + vtkOpenGLCheckErrorMacro("failed at glBindTexture"); + } + + if (this->Impl->GradientOpacityTables) + { + this->Impl->ShaderProgram->SetUniform1iv("in_gradientTransferFunc", + numberOfSamplers, gradientOpacitySamplers); + vtkOpenGLCheckErrorMacro("failed at glBindTexture"); + } this->Impl->NoiseTextureObject->Activate(); this->Impl->ShaderProgram->SetUniformi("in_noiseSampler", @@ -2268,12 +2310,6 @@ void vtkOpenGLGPUVolumeRayCastMapper::GPURender(vtkRenderer* ren, this->Impl->ShaderProgram->SetUniformi("in_depthSampler", this->Impl->DepthTextureObject->GetTextureUnit()); - if (this->Impl->GradientOpacityTables) - { - this->Impl->ShaderProgram->SetUniformi("in_gradientTransferFunc", - this->Impl->GradientOpacityTables->GetTable(0)->GetTextureUnit()); - } - if (this->Impl->CurrentMask) { this->Impl->CurrentMask->Bind(); @@ -2282,12 +2318,8 @@ void vtkOpenGLGPUVolumeRayCastMapper::GPURender(vtkRenderer* ren, } if(numberOfScalarComponents == 1 && - this->BlendMode!=vtkGPUVolumeRayCastMapper::ADDITIVE_BLEND) + this->BlendMode != vtkGPUVolumeRayCastMapper::ADDITIVE_BLEND) { - this->Impl->RGBTables->GetTable(0)->Bind(); - this->Impl->ShaderProgram->SetUniformi("in_colorTransferFunc", - this->Impl->RGBTables->GetTable(0)->GetTextureUnit()); - if (this->MaskInput != 0 && this->MaskType == LabelMapMaskType) { this->Impl->Mask1RGBTable->Bind(); From 77db23fc7eacf0561baba0080cfabff5931eb338 Mon Sep 17 00:00:00 2001 From: Aashish Chaudhary Date: Thu, 22 Jan 2015 11:53:32 -0500 Subject: [PATCH 10/15] Fixed composite blend mode Change-Id: I6233d13505a5f64aa9ddc5d7a758b03d68be3d87 --- ...TestGPURayCastIndependentComponent.png.md5 | 1 + .../TestGPURayCastIndependentComponent.py | 8 ++--- .../VolumeOpenGL2/shaders/raycasterfs.glsl | 2 +- .../vtkOpenGLGPUVolumeRayCastMapper.cxx | 2 +- .../VolumeOpenGL2/vtkVolumeShaderComposer.h | 31 ++++++++++++------- 5 files changed, 26 insertions(+), 18 deletions(-) create mode 100644 Rendering/Volume/Testing/Data/Baseline/TestGPURayCastIndependentComponent.png.md5 diff --git a/Rendering/Volume/Testing/Data/Baseline/TestGPURayCastIndependentComponent.png.md5 b/Rendering/Volume/Testing/Data/Baseline/TestGPURayCastIndependentComponent.png.md5 new file mode 100644 index 00000000000..302cee81ae6 --- /dev/null +++ b/Rendering/Volume/Testing/Data/Baseline/TestGPURayCastIndependentComponent.png.md5 @@ -0,0 +1 @@ +78563a50396d621fd24dfed38106d820 diff --git a/Rendering/Volume/Testing/Python/TestGPURayCastIndependentComponent.py b/Rendering/Volume/Testing/Python/TestGPURayCastIndependentComponent.py index 8970eebb742..2161b7ab382 100755 --- a/Rendering/Volume/Testing/Python/TestGPURayCastIndependentComponent.py +++ b/Rendering/Volume/Testing/Python/TestGPURayCastIndependentComponent.py @@ -111,10 +111,10 @@ def test(self): ren.ResetCamera() renWin.Render() - #img_file = "TestGPURayCastIndependentComponent.png" - #vtk.test.Testing.compareImage( - # iRen.GetRenderWindow(), vtk.test.Testing.getAbsImagePath(img_file), threshold=10) - #vtk.test.Testing.interact() + img_file = "TestGPURayCastIndependentComponent.png" + vtk.test.Testing.compareImage( + iRen.GetRenderWindow(), vtk.test.Testing.getAbsImagePath(img_file), threshold=10) + vtk.test.Testing.interact() iRen.Start() if __name__ == "__main__": diff --git a/Rendering/VolumeOpenGL2/shaders/raycasterfs.glsl b/Rendering/VolumeOpenGL2/shaders/raycasterfs.glsl index 4cf4c739e27..aaa6a281df1 100644 --- a/Rendering/VolumeOpenGL2/shaders/raycasterfs.glsl +++ b/Rendering/VolumeOpenGL2/shaders/raycasterfs.glsl @@ -34,7 +34,7 @@ varying vec3 ip_vertexPos; /// ////////////////////////////////////////////////////////////////////////////// -vec4 g_fragColor; +vec4 g_fragColor = vec4(0.0); ////////////////////////////////////////////////////////////////////////////// /// diff --git a/Rendering/VolumeOpenGL2/vtkOpenGLGPUVolumeRayCastMapper.cxx b/Rendering/VolumeOpenGL2/vtkOpenGLGPUVolumeRayCastMapper.cxx index 6a7075f609e..646a4ffca38 100644 --- a/Rendering/VolumeOpenGL2/vtkOpenGLGPUVolumeRayCastMapper.cxx +++ b/Rendering/VolumeOpenGL2/vtkOpenGLGPUVolumeRayCastMapper.cxx @@ -1967,7 +1967,7 @@ void vtkOpenGLGPUVolumeRayCastMapper::BuildShader(vtkRenderer* ren, vtkErrorMacro("Shader failed to compile"); } - //std::cerr << "fragment shader " << fragmentShader << std::endl; + std::cerr << "fragment shader " << fragmentShader << std::endl; this->Impl->ShaderBuildTime.Modified(); } diff --git a/Rendering/VolumeOpenGL2/vtkVolumeShaderComposer.h b/Rendering/VolumeOpenGL2/vtkVolumeShaderComposer.h index 6408c293a51..ac9c9ae9d29 100644 --- a/Rendering/VolumeOpenGL2/vtkVolumeShaderComposer.h +++ b/Rendering/VolumeOpenGL2/vtkVolumeShaderComposer.h @@ -811,26 +811,33 @@ namespace vtkvolume if (noOfComponents > 1 && independentComponents) { shaderStr += std::string("\ + \n vec4 color[4]; vec4 tmp = vec4(0.0);\ + \n float totalAlpha = 0.0;\ \n for (int i = 0; i < in_noOfComponents; ++i)\ \n {\ "); - // TODO Remove duplication if (!mask || !maskInput || - maskType != vtkGPUVolumeRayCastMapper::LabelMapMaskType) + maskType != vtkGPUVolumeRayCastMapper::LabelMapMaskType) { shaderStr += std::string("\ - \n // Data fetching from the red channel of volume texture\ - \n vec4 scalar = texture3D(in_volume, g_dataPos);\ - \n vec4 g_srcColor = computeColor(scalar, i);" + \n // Data fetching from the red channel of volume texture\ + \n vec4 scalar = texture3D(in_volume, g_dataPos);\ + \n color[i] = vec4(computeColor(scalar, i));\ + \n totalAlpha += color[i][3];\ + \n }\ + \n if (totalAlpha > 0.0)\ + \n {\ + \n for (int i = 0; i < in_noOfComponents; ++i)\ + \n {\ + \n tmp.x += color[i].x * color[i].w;\ + \n tmp.y += color[i].y * color[i].w;\ + \n tmp.z += color[i].z * color[i].w;\ + \n tmp.w += ((color[i].w * color[i].w)/totalAlpha);\ + \n }\ + \n }\ + \n g_fragColor = (1.0f - g_fragColor.a) * tmp + g_fragColor;" ); } - - shaderStr += std::string("\ - \n g_srcColor.rgb *= g_srcColor.a;\ - \n g_fragColor += (1.0f - g_fragColor.a) * g_srcColor + g_fragColor;\ - \n }\ - \n g_fragColor /= in_noOfComponents;" - ); } else { From 96c0d17dced906e3af6c9de9d013f60c4bd818e1 Mon Sep 17 00:00:00 2001 From: Aashish Chaudhary Date: Thu, 29 Jan 2015 15:52:55 -0500 Subject: [PATCH 11/15] Added independent support for min and max projections Change-Id: I3bb31263d8831fe3f8480bc31004837ecb358198 --- .../vtkOpenGLGPUVolumeRayCastMapper.cxx | 3 +- .../VolumeOpenGL2/vtkVolumeShaderComposer.h | 74 +++++++++++++++---- 2 files changed, 60 insertions(+), 17 deletions(-) diff --git a/Rendering/VolumeOpenGL2/vtkOpenGLGPUVolumeRayCastMapper.cxx b/Rendering/VolumeOpenGL2/vtkOpenGLGPUVolumeRayCastMapper.cxx index 646a4ffca38..8a04684eadb 100644 --- a/Rendering/VolumeOpenGL2/vtkOpenGLGPUVolumeRayCastMapper.cxx +++ b/Rendering/VolumeOpenGL2/vtkOpenGLGPUVolumeRayCastMapper.cxx @@ -1896,7 +1896,8 @@ void vtkOpenGLGPUVolumeRayCastMapper::BuildShader(vtkRenderer* ren, this->MaskType, noOfComponents, independentComponents), true); fragmentShader = vtkvolume::replace(fragmentShader, "//VTK::Shading::Exit", - vtkvolume::ShadingExit(ren, this, vol), true); + vtkvolume::ShadingExit(ren, this, vol, noOfComponents, + independentComponents), true); fragmentShader = vtkvolume::replace(fragmentShader, "//VTK::ComputeOpacity::Dec", diff --git a/Rendering/VolumeOpenGL2/vtkVolumeShaderComposer.h b/Rendering/VolumeOpenGL2/vtkVolumeShaderComposer.h index ac9c9ae9d29..b2fa97a997b 100644 --- a/Rendering/VolumeOpenGL2/vtkVolumeShaderComposer.h +++ b/Rendering/VolumeOpenGL2/vtkVolumeShaderComposer.h @@ -101,8 +101,8 @@ namespace vtkvolume vtkVolume* vtkNotUsed(vol), int vtkNotUsed(numberOfLights), int lightingComplexity, - int noOfComponents = 1, - bool independentComponents = false) + int vtkNotUsed(noOfComponents), + bool vtkNotUsed(independentComponents)) { std::string shaderStr = std::string("\ \n// Volume dataset\ @@ -880,29 +880,71 @@ namespace vtkvolume //-------------------------------------------------------------------------- std::string ShadingExit(vtkRenderer* vtkNotUsed(ren), vtkVolumeMapper* mapper, - vtkVolume* vtkNotUsed(vol)) + vtkVolume* vtkNotUsed(vol), + int noOfComponents, + bool independentComponents = false) { if (mapper->GetBlendMode() == vtkVolumeMapper::MAXIMUM_INTENSITY_BLEND) { - return std::string("\ - \n vec4 g_srcColor = vec4(computeColor(l_maxValue).xyz,\ - \n computeOpacity(l_maxValue));\ - \n g_fragColor.rgb = g_srcColor.rgb * g_srcColor.a;\ - \n g_fragColor.a = g_srcColor.a;" - ); + if (noOfComponents > 1 && independentComponents) + { + return std::string("\ + \n for (int i = 0; i < in_noOfComponents; ++i)\ + \n {\ + \n vec4 g_srcColor = vec4(0);\ + \n for (int i = 0; i < in_noOfComponents; ++i)\ + \n {\ \ + \n vec4 tmp = vec4(computeColor(l_maxValue, i);\ + \n g_srcColor[0] += tmp[0] * tmp[3];\ + \n g_srcColor[1] += tmp[1] * tmp[3];\ + \n g_srcColor[2] += tmp[2] * tmp[3];\ + \n g_srcColor[2] += tmp[3] * tmp[3];\ + \n }\ + \n }" + ); + } + else + { + return std::string("\ + \n vec4 g_srcColor = vec4(computeColor(l_maxValue).xyz,\ + \n computeOpacity(l_maxValue));\ + \n g_fragColor.rgb = g_srcColor.rgb * g_srcColor.a;\ + \n g_fragColor.a = g_srcColor.a;" + ); + } } else if (mapper->GetBlendMode() == vtkVolumeMapper::MINIMUM_INTENSITY_BLEND) { - return std::string("\ - \n vec4 g_srcColor = vec4(computeColor(l_minValue).xyz,\ - \n computeOpacity(l_minValue));\ - \n g_fragColor.rgb = g_srcColor.rgb * g_srcColor.a;\ - \n g_fragColor.a = g_srcColor.a;" - ); + if (noOfComponents > 1 && independentComponents) + { + return std::string ("\ + \n for (int i = 0; i < in_noOfComponents; ++i)\ + \n {\ + \n vec4 g_srcColor = vec4(0);\ + \n for (int i = 0; i < in_noOfComponents; ++i)\ + \n {\ \ + \n vec4 tmp = vec4(computeColor(l_maxValue, i);\ + \n g_srcColor[0] += tmp[0] * tmp[3];\ + \n g_srcColor[1] += tmp[1] * tmp[3];\ + \n g_srcColor[2] += tmp[2] * tmp[3];\ + \n g_srcColor[2] += tmp[3] * tmp[3];\ + \n }\ + \n }" + ); + } + else + { + return std::string ("\ + \n vec4 g_srcColor = vec4(computeColor(l_minValue).xyz,\ + \n computeOpacity(l_minValue));\ + \n g_fragColor.rgb = g_srcColor.rgb * g_srcColor.a;\ + \n g_fragColor.a = g_srcColor.a;" + ); + } } else if (mapper->GetBlendMode() == vtkVolumeMapper::ADDITIVE_BLEND) { - return std::string("\ + return std::string ("\ \n l_sumValue = clamp(l_sumValue, 0.0, 1.0);\ \n g_fragColor = vec4(vec3(l_sumValue), 1.0);" ); From b54489a909dc518aa00b3dc8df211dfe29983132 Mon Sep 17 00:00:00 2001 From: Aashish Chaudhary Date: Thu, 29 Jan 2015 16:47:54 -0500 Subject: [PATCH 12/15] Pass component weights to the shader Change-Id: I0dffb7685d4508a87ebedd26f94de7feed512559 --- .../vtkOpenGLGPUVolumeRayCastMapper.cxx | 11 ++++++ .../VolumeOpenGL2/vtkVolumeShaderComposer.h | 34 +++++++++++-------- 2 files changed, 31 insertions(+), 14 deletions(-) diff --git a/Rendering/VolumeOpenGL2/vtkOpenGLGPUVolumeRayCastMapper.cxx b/Rendering/VolumeOpenGL2/vtkOpenGLGPUVolumeRayCastMapper.cxx index 8a04684eadb..f19af1ff95c 100644 --- a/Rendering/VolumeOpenGL2/vtkOpenGLGPUVolumeRayCastMapper.cxx +++ b/Rendering/VolumeOpenGL2/vtkOpenGLGPUVolumeRayCastMapper.cxx @@ -2194,6 +2194,7 @@ void vtkOpenGLGPUVolumeRayCastMapper::GPURender(vtkRenderer* ren, // Temporary variables float fvalue2[2]; float fvalue3[3]; + float fvalue4[4]; float fvalue16[16]; // Update sampling distance @@ -2494,6 +2495,16 @@ void vtkOpenGLGPUVolumeRayCastMapper::GPURender(vtkRenderer* ren, this->Impl->ShaderProgram->SetUniformf("in_bias", (0.5 - (this->FinalColorLevel/this->FinalColorWindow))); + if (numberOfScalarComponents > 1 && + volumeProperty->GetIndependentComponents()) + { + for (int i = 0; i < numberOfScalarComponents; ++i) + { + fvalue4[i] = static_cast(volumeProperty->GetComponentWeight(i)); + } + this->Impl->ShaderProgram->SetUniform4fv("in_componentWeight", 1, &fvalue4); + } + #ifndef __APPLE__ glBindVertexArray(this->Impl->CubeVAOId); #endif diff --git a/Rendering/VolumeOpenGL2/vtkVolumeShaderComposer.h b/Rendering/VolumeOpenGL2/vtkVolumeShaderComposer.h index b2fa97a997b..f7d2b51d5ab 100644 --- a/Rendering/VolumeOpenGL2/vtkVolumeShaderComposer.h +++ b/Rendering/VolumeOpenGL2/vtkVolumeShaderComposer.h @@ -101,8 +101,8 @@ namespace vtkvolume vtkVolume* vtkNotUsed(vol), int vtkNotUsed(numberOfLights), int lightingComplexity, - int vtkNotUsed(noOfComponents), - bool vtkNotUsed(independentComponents)) + int noOfComponents, + bool independentComponents) { std::string shaderStr = std::string("\ \n// Volume dataset\ @@ -193,6 +193,12 @@ namespace vtkvolume "); } + if (noOfComponents > 1 && independentComponents) + { + shaderStr += std::string("\ + uniform vec4 in_componentWeight;"); + } + return shaderStr; } @@ -823,15 +829,15 @@ namespace vtkvolume \n // Data fetching from the red channel of volume texture\ \n vec4 scalar = texture3D(in_volume, g_dataPos);\ \n color[i] = vec4(computeColor(scalar, i));\ - \n totalAlpha += color[i][3];\ + \n totalAlpha += color[i][3] * in_componentWeight[i];\ \n }\ \n if (totalAlpha > 0.0)\ \n {\ \n for (int i = 0; i < in_noOfComponents; ++i)\ \n {\ - \n tmp.x += color[i].x * color[i].w;\ - \n tmp.y += color[i].y * color[i].w;\ - \n tmp.z += color[i].z * color[i].w;\ + \n tmp.x += color[i].x * color[i].w * in_componentWeight[i] ;\ + \n tmp.y += color[i].y * color[i].w * in_componentWeight[i];\ + \n tmp.z += color[i].z * color[i].w * in_componentWeight[i];\ \n tmp.w += ((color[i].w * color[i].w)/totalAlpha);\ \n }\ \n }\ @@ -895,10 +901,10 @@ namespace vtkvolume \n for (int i = 0; i < in_noOfComponents; ++i)\ \n {\ \ \n vec4 tmp = vec4(computeColor(l_maxValue, i);\ - \n g_srcColor[0] += tmp[0] * tmp[3];\ - \n g_srcColor[1] += tmp[1] * tmp[3];\ - \n g_srcColor[2] += tmp[2] * tmp[3];\ - \n g_srcColor[2] += tmp[3] * tmp[3];\ + \n g_srcColor[0] += tmp[0] * tmp[3] * in_componentWeight[i];\ + \n g_srcColor[1] += tmp[1] * tmp[3] * in_componentWeight[i];\ + \n g_srcColor[2] += tmp[2] * tmp[3] * in_componentWeight[i];\ + \n g_srcColor[2] += tmp[3] * tmp[3] * in_componentWeight[i];\ \n }\ \n }" ); @@ -924,10 +930,10 @@ namespace vtkvolume \n for (int i = 0; i < in_noOfComponents; ++i)\ \n {\ \ \n vec4 tmp = vec4(computeColor(l_maxValue, i);\ - \n g_srcColor[0] += tmp[0] * tmp[3];\ - \n g_srcColor[1] += tmp[1] * tmp[3];\ - \n g_srcColor[2] += tmp[2] * tmp[3];\ - \n g_srcColor[2] += tmp[3] * tmp[3];\ + \n g_srcColor[0] += tmp[0] * tmp[3] * in_componentWeight[i];\ + \n g_srcColor[1] += tmp[1] * tmp[3] * in_componentWeight[i];\ + \n g_srcColor[2] += tmp[2] * tmp[3] * in_componentWeight[i];\ + \n g_srcColor[2] += tmp[3] * tmp[3] * in_componentWeight[i];\ \n }\ \n }" ); From 3c9eaf177fb45e6da0785372de2b5d87266e0495 Mon Sep 17 00:00:00 2001 From: Aashish Chaudhary Date: Thu, 29 Jan 2015 17:57:47 -0500 Subject: [PATCH 13/15] Fixed testing Change-Id: I556bf645861b1978e4a7998da5fafbf3295a51e1 --- Rendering/Volume/Testing/Python/CMakeLists.txt | 2 +- .../Volume/Testing/Python/TestGPURayCastIndependentComponent.py | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/Rendering/Volume/Testing/Python/CMakeLists.txt b/Rendering/Volume/Testing/Python/CMakeLists.txt index 15e10fd9dd4..46425cd7b5d 100644 --- a/Rendering/Volume/Testing/Python/CMakeLists.txt +++ b/Rendering/Volume/Testing/Python/CMakeLists.txt @@ -11,7 +11,7 @@ set (GenericVolumePythonTests volRCRotateClip.py VolumePickerCrop.py VolumePicker.py,NO_RT - TestGPURayCastIndependentComponent.py + TestGPURayCastIndependentComponent.py,NO_RT ) # These tests are only built when the rendering backend is OpenGL diff --git a/Rendering/Volume/Testing/Python/TestGPURayCastIndependentComponent.py b/Rendering/Volume/Testing/Python/TestGPURayCastIndependentComponent.py index 2161b7ab382..da7991bfe64 100755 --- a/Rendering/Volume/Testing/Python/TestGPURayCastIndependentComponent.py +++ b/Rendering/Volume/Testing/Python/TestGPURayCastIndependentComponent.py @@ -115,7 +115,6 @@ def test(self): vtk.test.Testing.compareImage( iRen.GetRenderWindow(), vtk.test.Testing.getAbsImagePath(img_file), threshold=10) vtk.test.Testing.interact() - iRen.Start() if __name__ == "__main__": vtk.test.Testing.main([(TestGPURayCastIndependentComponent, 'test')]) From 8297391276b4389fb4dd09ce11e24ab88317eedd Mon Sep 17 00:00:00 2001 From: Aashish Chaudhary Date: Fri, 30 Jan 2015 11:29:15 -0500 Subject: [PATCH 14/15] Renaming classes for consistency Change-Id: Ie4f28bef7c8352e2639ec2137431fc9bbb87a50e --- .../vtkOpenGLGPUVolumeRayCastMapper.cxx | 12 +++--- ... => vtkOpenGLVolumeGradientOpacityTable.h} | 42 +++++++++---------- ...yTable.h => vtkOpenGLVolumeOpacityTable.h} | 36 ++++++++-------- 3 files changed, 45 insertions(+), 45 deletions(-) rename Rendering/VolumeOpenGL2/{vtkOpenGLGradientOpacityTable.h => vtkOpenGLVolumeGradientOpacityTable.h} (81%) rename Rendering/VolumeOpenGL2/{vtkOpenGLOpacityTable.h => vtkOpenGLVolumeOpacityTable.h} (88%) diff --git a/Rendering/VolumeOpenGL2/vtkOpenGLGPUVolumeRayCastMapper.cxx b/Rendering/VolumeOpenGL2/vtkOpenGLGPUVolumeRayCastMapper.cxx index f19af1ff95c..895ace1edb5 100644 --- a/Rendering/VolumeOpenGL2/vtkOpenGLGPUVolumeRayCastMapper.cxx +++ b/Rendering/VolumeOpenGL2/vtkOpenGLGPUVolumeRayCastMapper.cxx @@ -15,8 +15,8 @@ #include "vtkOpenGLGPUVolumeRayCastMapper.h" -#include "vtkOpenGLGradientOpacityTable.h" -#include "vtkOpenGLOpacityTable.h" +#include "vtkOpenGLVolumeGradientOpacityTable.h" +#include "vtkOpenGLVolumeOpacityTable.h" #include "vtkOpenGLVolumeRGBTable.h" #include "vtkVolumeShaderComposer.h" #include "vtkVolumeStateRAII.h" @@ -326,10 +326,10 @@ class vtkOpenGLGPUVolumeRayCastMapper::vtkInternal std::ostringstream ExtensionsStringStream; vtkOpenGLVolumeRGBTables* RGBTables; - vtkOpenGLOpacityTables* OpacityTables; + vtkOpenGLVolumeOpacityTables* OpacityTables; vtkOpenGLVolumeRGBTable* Mask1RGBTable; vtkOpenGLVolumeRGBTable* Mask2RGBTable; - vtkOpenGLGradientOpacityTables* GradientOpacityTables; + vtkOpenGLVolumeGradientOpacityTables* GradientOpacityTables; vtkTimeStamp ShaderBuildTime; @@ -452,7 +452,7 @@ void vtkOpenGLGPUVolumeRayCastMapper::vtkInternal::Initialize( } // We support upto four components - this->OpacityTables = new vtkOpenGLOpacityTables(4); + this->OpacityTables = new vtkOpenGLVolumeOpacityTables(4); this->Initialized = true; } @@ -956,7 +956,7 @@ int vtkOpenGLGPUVolumeRayCastMapper::vtkInternal:: if (!this->GradientOpacityTables && gradientOpacity) { // NOTE Handling only one component - this->GradientOpacityTables = new vtkOpenGLGradientOpacityTables(1); + this->GradientOpacityTables = new vtkOpenGLVolumeGradientOpacityTables(1); } // TODO: Do a better job to create the default opacity map diff --git a/Rendering/VolumeOpenGL2/vtkOpenGLGradientOpacityTable.h b/Rendering/VolumeOpenGL2/vtkOpenGLVolumeGradientOpacityTable.h similarity index 81% rename from Rendering/VolumeOpenGL2/vtkOpenGLGradientOpacityTable.h rename to Rendering/VolumeOpenGL2/vtkOpenGLVolumeGradientOpacityTable.h index a6c69ec0da1..8ccca5a0c64 100644 --- a/Rendering/VolumeOpenGL2/vtkOpenGLGradientOpacityTable.h +++ b/Rendering/VolumeOpenGL2/vtkOpenGLVolumeGradientOpacityTable.h @@ -1,7 +1,7 @@ /*========================================================================= Program: Visualization Toolkit - Module: vtkOpenGLGradientOpacityTable.h + Module: vtkOpenGLVolumeGradientOpacityTable.h Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen All rights reserved. @@ -13,8 +13,8 @@ =========================================================================*/ -#ifndef vtkOpenGLGradientOpacityTable_h_ -#define vtkOpenGLGradientOpacityTable_h_ +#ifndef vtkOpenGLVolumeGradientOpacityTable_h_ +#define vtkOpenGLVolumeGradientOpacityTable_h_ #include #include @@ -23,11 +23,11 @@ #include //---------------------------------------------------------------------------- -class vtkOpenGLGradientOpacityTable +class vtkOpenGLVolumeGradientOpacityTable { public: //-------------------------------------------------------------------------- - vtkOpenGLGradientOpacityTable(int width = 1024) + vtkOpenGLVolumeGradientOpacityTable(int width = 1024) { this->TextureObject = 0; this->TextureWidth = width; @@ -38,7 +38,7 @@ class vtkOpenGLGradientOpacityTable } //-------------------------------------------------------------------------- - ~vtkOpenGLGradientOpacityTable() + ~vtkOpenGLVolumeGradientOpacityTable() { if (this->TextureObject) { @@ -157,30 +157,30 @@ class vtkOpenGLGradientOpacityTable int LastInterpolation; double LastRange[2]; private: - vtkOpenGLGradientOpacityTable(const vtkOpenGLGradientOpacityTable&); - vtkOpenGLGradientOpacityTable& operator=(const vtkOpenGLGradientOpacityTable&); + vtkOpenGLVolumeGradientOpacityTable(const vtkOpenGLVolumeGradientOpacityTable&); + vtkOpenGLVolumeGradientOpacityTable& operator=(const vtkOpenGLVolumeGradientOpacityTable&); }; //----------------------------------------------------------------------------- -class vtkOpenGLGradientOpacityTables +class vtkOpenGLVolumeGradientOpacityTables { public: //-------------------------------------------------------------------------- - vtkOpenGLGradientOpacityTables(unsigned int numberOfTables) + vtkOpenGLVolumeGradientOpacityTables(unsigned int numberOfTables) { - this->Tables = new vtkOpenGLGradientOpacityTable[numberOfTables]; + this->Tables = new vtkOpenGLVolumeGradientOpacityTable[numberOfTables]; this->NumberOfTables = numberOfTables; } //-------------------------------------------------------------------------- - ~vtkOpenGLGradientOpacityTables() + ~vtkOpenGLVolumeGradientOpacityTables() { delete [] this->Tables; } // Get opacity table at a given index. //-------------------------------------------------------------------------- - vtkOpenGLGradientOpacityTable* GetTable(unsigned int i) + vtkOpenGLVolumeGradientOpacityTable* GetTable(unsigned int i) { if (i >= this->NumberOfTables) { @@ -206,17 +206,17 @@ class vtkOpenGLGradientOpacityTables } private: unsigned int NumberOfTables; - vtkOpenGLGradientOpacityTable* Tables; + vtkOpenGLVolumeGradientOpacityTable* Tables; - // vtkOpenGLGradientOpacityTables (Not implemented) - vtkOpenGLGradientOpacityTables(); + // vtkOpenGLVolumeGradientOpacityTables (Not implemented) + vtkOpenGLVolumeGradientOpacityTables(); - // vtkOpenGLGradientOpacityTables (Not implemented) - vtkOpenGLGradientOpacityTables(const vtkOpenGLGradientOpacityTables &other); + // vtkOpenGLVolumeGradientOpacityTables (Not implemented) + vtkOpenGLVolumeGradientOpacityTables(const vtkOpenGLVolumeGradientOpacityTables &other); // operator = (Not implemented) - vtkOpenGLGradientOpacityTables &operator=(const vtkOpenGLGradientOpacityTables &other); + vtkOpenGLVolumeGradientOpacityTables &operator=(const vtkOpenGLVolumeGradientOpacityTables &other); }; -#endif // vtkOpenGLGradientOpacityTable_h_ -// VTK-HeaderTest-Exclude: vtkOpenGLGradientOpacityTable.h +#endif // vtkOpenGLVolumeGradientOpacityTable_h_ +// VTK-HeaderTest-Exclude: vtkOpenGLVolumeGradientOpacityTable.h diff --git a/Rendering/VolumeOpenGL2/vtkOpenGLOpacityTable.h b/Rendering/VolumeOpenGL2/vtkOpenGLVolumeOpacityTable.h similarity index 88% rename from Rendering/VolumeOpenGL2/vtkOpenGLOpacityTable.h rename to Rendering/VolumeOpenGL2/vtkOpenGLVolumeOpacityTable.h index 67e678a42e5..6ddee1923ed 100644 --- a/Rendering/VolumeOpenGL2/vtkOpenGLOpacityTable.h +++ b/Rendering/VolumeOpenGL2/vtkOpenGLVolumeOpacityTable.h @@ -1,7 +1,7 @@ /*========================================================================= Program: Visualization Toolkit - Module: vtkOpenGLOpacityTable.h + Module: vtkOpenGLVolumeOpacityTable.h Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen All rights reserved. @@ -23,11 +23,11 @@ #include //---------------------------------------------------------------------------- -class vtkOpenGLOpacityTable +class vtkOpenGLVolumeOpacityTable { public: //-------------------------------------------------------------------------- - vtkOpenGLOpacityTable(int width = 1024) + vtkOpenGLVolumeOpacityTable(int width = 1024) { this->TextureObject = 0; this->LastBlendMode = vtkVolumeMapper::MAXIMUM_INTENSITY_BLEND; @@ -39,7 +39,7 @@ class vtkOpenGLOpacityTable } //-------------------------------------------------------------------------- - ~vtkOpenGLOpacityTable() + ~vtkOpenGLVolumeOpacityTable() { if (this->TextureObject) { @@ -199,30 +199,30 @@ class vtkOpenGLOpacityTable int LastInterpolation; double LastRange[2]; private: - vtkOpenGLOpacityTable(const vtkOpenGLOpacityTable&); - vtkOpenGLOpacityTable& operator=(const vtkOpenGLOpacityTable&); + vtkOpenGLVolumeOpacityTable(const vtkOpenGLVolumeOpacityTable&); + vtkOpenGLVolumeOpacityTable& operator=(const vtkOpenGLVolumeOpacityTable&); }; //---------------------------------------------------------------------------- -class vtkOpenGLOpacityTables +class vtkOpenGLVolumeOpacityTables { public: //-------------------------------------------------------------------------- - vtkOpenGLOpacityTables(unsigned int numberOfTables) + vtkOpenGLVolumeOpacityTables(unsigned int numberOfTables) { - this->Tables = new vtkOpenGLOpacityTable[numberOfTables]; + this->Tables = new vtkOpenGLVolumeOpacityTable[numberOfTables]; this->NumberOfTables = numberOfTables; } //-------------------------------------------------------------------------- - ~vtkOpenGLOpacityTables() + ~vtkOpenGLVolumeOpacityTables() { delete [] this->Tables; } // brief Get opacity table at a given index. //-------------------------------------------------------------------------- - vtkOpenGLOpacityTable* GetTable(unsigned int i) + vtkOpenGLVolumeOpacityTable* GetTable(unsigned int i) { if (i >= this->NumberOfTables) { @@ -249,17 +249,17 @@ class vtkOpenGLOpacityTables private: unsigned int NumberOfTables; - vtkOpenGLOpacityTable *Tables; + vtkOpenGLVolumeOpacityTable *Tables; - // vtkOpenGLOpacityTables (Not implemented) - vtkOpenGLOpacityTables(); + // vtkOpenGLVolumeOpacityTables (Not implemented) + vtkOpenGLVolumeOpacityTables(); - // vtkOpenGLOpacityTables (Not implemented) - vtkOpenGLOpacityTables(const vtkOpenGLOpacityTables &other); + // vtkOpenGLVolumeOpacityTables (Not implemented) + vtkOpenGLVolumeOpacityTables(const vtkOpenGLVolumeOpacityTables &other); // operator = (Not implemented) - vtkOpenGLOpacityTables &operator=(const vtkOpenGLOpacityTables &other); + vtkOpenGLVolumeOpacityTables &operator=(const vtkOpenGLVolumeOpacityTables &other); }; #endif // vtkOpenGLVolumeOpacityTable_h_ -// VTK-HeaderTest-Exclude: vtkOpenGLOpacityTable.h +// VTK-HeaderTest-Exclude: vtkOpenGLVolumeOpacityTable.h From 28c476fa1bd219c8445ac5f03531ab5f465e52e2 Mon Sep 17 00:00:00 2001 From: Aashish Chaudhary Date: Fri, 30 Jan 2015 12:06:04 -0500 Subject: [PATCH 15/15] Added support for independent components for gradient opacity Change-Id: I47131b3704edd252e0166ab14d1ceddabd1386b1 --- .../vtkOpenGLGPUVolumeRayCastMapper.cxx | 440 ++++++++++++------ .../vtkOpenGLGPUVolumeRayCastMapper.h | 4 +- .../VolumeOpenGL2/vtkVolumeShaderComposer.h | 50 +- 3 files changed, 346 insertions(+), 148 deletions(-) diff --git a/Rendering/VolumeOpenGL2/vtkOpenGLGPUVolumeRayCastMapper.cxx b/Rendering/VolumeOpenGL2/vtkOpenGLGPUVolumeRayCastMapper.cxx index 895ace1edb5..a76a20367a3 100644 --- a/Rendering/VolumeOpenGL2/vtkOpenGLGPUVolumeRayCastMapper.cxx +++ b/Rendering/VolumeOpenGL2/vtkOpenGLGPUVolumeRayCastMapper.cxx @@ -198,7 +198,7 @@ class vtkOpenGLGPUVolumeRayCastMapper::vtkInternal static void ToFloat(const T& in1, const T& in2, const T& in3, float (&out)[3]); template - static void ToFloat(T* in, float* out, int numberOfComponents); + static void ToFloat(T* in, float* out, int noOfComponents); template static void ToFloat(T (&in)[3], float (&out)[3]); template @@ -208,7 +208,8 @@ class vtkOpenGLGPUVolumeRayCastMapper::vtkInternal static void VtkToGlMatrix(vtkMatrix4x4* in, float (&out)[16], int row = 4, int col = 4); - void Initialize(vtkRenderer* ren, vtkVolume* vol); + void Initialize(vtkRenderer* ren, vtkVolume* vol, + int noOfComponents, int independentComponents); bool LoadVolume(vtkRenderer* ren, vtkImageData* imageData, vtkDataArray* scalars); @@ -223,22 +224,22 @@ class vtkOpenGLGPUVolumeRayCastMapper::vtkInternal // Update transfer color function based on the incoming inputs and number of // scalar components. - // TODO Deal with numberOfScalarComponents > 1 + // TODO Deal with noOfComponents > 1 int UpdateColorTransferFunction(vtkRenderer* ren, vtkVolume* vol, - int numberOfScalarComponents, + int noOfComponents, unsigned int component); // Update opacity transfer function (not gradient opacity) int UpdateOpacityTransferFunction(vtkRenderer* ren, vtkVolume* vol, - int numberOfScalarComponents, + int noOfComponents, unsigned int component); // Update gradient opacity function int UpdateGradientOpacityTransferFunction(vtkRenderer* ren, vtkVolume* vol, - int numberOfScalarComponents, + int noOfComponents, unsigned int component); // Update noise texture (used to reduce rendering artifacts @@ -374,9 +375,9 @@ void vtkOpenGLGPUVolumeRayCastMapper::vtkInternal::ToFloat( //---------------------------------------------------------------------------- template void vtkOpenGLGPUVolumeRayCastMapper::vtkInternal::ToFloat( - T* in, float* out, int numberOfComponents) + T* in, float* out, int noOfComponents) { - for (int i = 0; i < numberOfComponents; ++i) + for (int i = 0; i < noOfComponents; ++i) { out[i] = static_cast(in[i]); } @@ -424,7 +425,8 @@ void vtkOpenGLGPUVolumeRayCastMapper::vtkInternal::VtkToGlMatrix( //---------------------------------------------------------------------------- void vtkOpenGLGPUVolumeRayCastMapper::vtkInternal::Initialize( - vtkRenderer* vtkNotUsed(ren), vtkVolume* vtkNotUsed(vol)) + vtkRenderer* vtkNotUsed(ren), vtkVolume* vol, int + noOfComponents, int independentComponents) { GLenum err = glewInit(); if (GLEW_OK != err) @@ -436,7 +438,14 @@ void vtkOpenGLGPUVolumeRayCastMapper::vtkInternal::Initialize( err = glGetError(); // Create RGB lookup table - this->RGBTables = new vtkOpenGLVolumeRGBTables(4); + if (noOfComponents > 1 && independentComponents) + { + this->RGBTables = new vtkOpenGLVolumeRGBTables(noOfComponents); + } + else + { + this->RGBTables = new vtkOpenGLVolumeRGBTables(1); + } if (this->Parent->MaskInput != 0 && this->Parent->MaskType == LabelMapMaskType) @@ -452,8 +461,30 @@ void vtkOpenGLGPUVolumeRayCastMapper::vtkInternal::Initialize( } // We support upto four components - this->OpacityTables = new vtkOpenGLVolumeOpacityTables(4); + if (noOfComponents > 1 && independentComponents) + { + this->OpacityTables = new vtkOpenGLVolumeOpacityTables(noOfComponents); + } + else + { + this->OpacityTables = new vtkOpenGLVolumeOpacityTables(1); + } + if (noOfComponents > 1 && independentComponents) + { + // Assuming that all four components has gradient opacity for now + this->GradientOpacityTables = + new vtkOpenGLVolumeGradientOpacityTables(noOfComponents); + } + else + { + if (vol->GetProperty()->HasGradientOpacity()) + { + this->GradientOpacityTables = + new vtkOpenGLVolumeGradientOpacityTables(1); + } + + } this->Initialized = true; } @@ -844,7 +875,7 @@ void vtkOpenGLGPUVolumeRayCastMapper::vtkInternal::ComputeBounds( //---------------------------------------------------------------------------- int vtkOpenGLGPUVolumeRayCastMapper::vtkInternal::UpdateColorTransferFunction( - vtkRenderer* ren, vtkVolume* vol, int vtkNotUsed(numberOfScalarComponents), + vtkRenderer* ren, vtkVolume* vol, int vtkNotUsed(noOfComponents), unsigned int component) { // Volume property cannot be null. @@ -897,12 +928,11 @@ int vtkOpenGLGPUVolumeRayCastMapper::vtkInternal::UpdateColorTransferFunction( //---------------------------------------------------------------------------- int vtkOpenGLGPUVolumeRayCastMapper::vtkInternal::UpdateOpacityTransferFunction( - vtkRenderer* ren, vtkVolume* vol, int vtkNotUsed(numberOfScalarComponents), + vtkRenderer* ren, vtkVolume* vol, int vtkNotUsed(noOfComponents), unsigned int component) { if (!vol) { - std::cerr << "Invalid in_volume" << std::endl; return 1; } @@ -910,8 +940,6 @@ int vtkOpenGLGPUVolumeRayCastMapper::vtkInternal::UpdateOpacityTransferFunction( vtkPiecewiseFunction* scalarOpacity = volumeProperty->GetScalarOpacity(component); - // TODO: Do a better job to create the default opacity map - // Add points only if its not being added before if (scalarOpacity->GetSize() < 1) { scalarOpacity->AddPoint(this->ScalarsRange[0], 0.0); @@ -936,7 +964,7 @@ int vtkOpenGLGPUVolumeRayCastMapper::vtkInternal::UpdateOpacityTransferFunction( //---------------------------------------------------------------------------- int vtkOpenGLGPUVolumeRayCastMapper::vtkInternal:: UpdateGradientOpacityTransferFunction(vtkRenderer* ren, vtkVolume* vol, - int vtkNotUsed(numberOfScalarComponents), unsigned int component) + int vtkNotUsed(noOfComponents), unsigned int component) { if (!vol) { @@ -945,22 +973,18 @@ int vtkOpenGLGPUVolumeRayCastMapper::vtkInternal:: vtkVolumeProperty* volumeProperty = vol->GetProperty(); - // TODO Currently checking on index 0 only - if (!volumeProperty->HasGradientOpacity()) + // TODO Currently we expect the all of the tables will + // be initialized once and if at that time, the gradient + // opacity was not enabled then it is not used later. + if (!volumeProperty->HasGradientOpacity(component) || + !this->GradientOpacityTables) { return 1; } - vtkPiecewiseFunction* gradientOpacity = volumeProperty->GetGradientOpacity(); + vtkPiecewiseFunction* gradientOpacity = + volumeProperty->GetGradientOpacity(component); - if (!this->GradientOpacityTables && gradientOpacity) - { - // NOTE Handling only one component - this->GradientOpacityTables = new vtkOpenGLVolumeGradientOpacityTables(1); - } - - // TODO: Do a better job to create the default opacity map - // Add points only if its not being added before if (gradientOpacity->GetSize() < 1) { gradientOpacity->AddPoint(this->ScalarsRange[0], 0.0); @@ -984,7 +1008,7 @@ int vtkOpenGLGPUVolumeRayCastMapper::vtkInternal:: //---------------------------------------------------------------------------- void vtkOpenGLGPUVolumeRayCastMapper::vtkInternal::UpdateNoiseTexture( - vtkRenderer* ren) + vtkRenderer* ren) { if (!this->NoiseTextureObject) { @@ -1818,7 +1842,7 @@ void vtkOpenGLGPUVolumeRayCastMapper::BuildShader(vtkRenderer* ren, // Every volume should have a property (cannot be NULL); vtkVolumeProperty* volumeProperty = vol->GetProperty(); - bool independentComponents = volumeProperty->GetIndependentComponents(); + int independentComponents = volumeProperty->GetIndependentComponents(); if (volumeProperty->GetShade()) { @@ -1855,112 +1879,259 @@ void vtkOpenGLGPUVolumeRayCastMapper::BuildShader(vtkRenderer* ren, } } - vertexShader = vtkvolume::replace(vertexShader, "//VTK::ComputeClipPos::Impl", - vtkvolume::ComputeClip(ren, this, vol), true); - vertexShader = vtkvolume::replace(vertexShader, "//VTK::ComputeTextureCoords::Impl", - vtkvolume::ComputeTextureCoords(ren, this, vol), true); - - vertexShader = vtkvolume::replace(vertexShader, "//VTK::Base::Dec", - vtkvolume::BaseGlobalsVert(ren, this, vol), true); - fragmentShader = vtkvolume::replace(fragmentShader, "//VTK::Base::Dec", + // Base methods replacements + //-------------------------------------------------------------------------- + vertexShader = vtkvolume::replace( + vertexShader, + "//VTK::ComputeClipPos::Impl", + vtkvolume::ComputeClip(ren, this, vol), + true); + + vertexShader = vtkvolume::replace( + vertexShader, + "//VTK::ComputeTextureCoords::Impl", + vtkvolume::ComputeTextureCoords(ren, this, vol), + true); + + vertexShader = vtkvolume::replace( + vertexShader, + "//VTK::Base::Dec", + vtkvolume::BaseGlobalsVert(ren, this, vol), + true); + + fragmentShader = vtkvolume::replace( + fragmentShader, + "//VTK::Base::Dec", vtkvolume::BaseGlobalsFrag(ren, this, vol, this->Impl->NumberOfLights, this->Impl->LightComplexity, noOfComponents, - independentComponents), true); - fragmentShader = vtkvolume::replace(fragmentShader, "//VTK::Base::Init", - vtkvolume::BaseInit(ren, this, vol), true); - fragmentShader = vtkvolume::replace(fragmentShader, "//VTK::Base::Impl", - vtkvolume::BaseIncrement(ren, this, vol), true); - fragmentShader = vtkvolume::replace(fragmentShader, "//VTK::Base::Exit", - vtkvolume::BaseExit(ren, this, vol), true); - - vertexShader = vtkvolume::replace(vertexShader, "//VTK::Termination::Dec", - vtkvolume::TerminationGlobalsVert(ren, this, vol), true); - fragmentShader = vtkvolume::replace(fragmentShader, "//VTK::Termination::Dec", - vtkvolume::TerminationGlobalsFrag(ren, this, vol), true); - fragmentShader = vtkvolume::replace(fragmentShader, "//VTK::Terminate::Init", - vtkvolume::TerminationInit(ren, this, vol), true); - fragmentShader = vtkvolume::replace(fragmentShader, "//VTK::Terminate::Impl", - vtkvolume::TerminationIncrement(ren, this, vol), true); - fragmentShader = vtkvolume::replace(fragmentShader, "//VTK::Terminate::Exit", - vtkvolume::TerminationExit(ren, this, vol), true); - - vertexShader = vtkvolume::replace(vertexShader, "//VTK::Shading::Dec", - vtkvolume::ShadingGlobalsVert(ren, this, vol), true); - fragmentShader = vtkvolume::replace(fragmentShader, "//VTK::Shading::Dec", - vtkvolume::ShadingGlobalsFrag(ren, this, vol), true); - fragmentShader = vtkvolume::replace(fragmentShader, "//VTK::Shading::Init", - vtkvolume::ShadingInit(ren, this, vol), true); - fragmentShader = vtkvolume::replace(fragmentShader, "//VTK::Shading::Impl", + independentComponents), + true); + + fragmentShader = vtkvolume::replace( + fragmentShader, + "//VTK::Base::Init", + vtkvolume::BaseInit(ren, this, vol), + true); + + fragmentShader = vtkvolume::replace( + fragmentShader, + "//VTK::Base::Impl", + vtkvolume::BaseIncrement(ren, this, vol), + true); + + fragmentShader = vtkvolume::replace( + fragmentShader, + "//VTK::Base::Exit", + vtkvolume::BaseExit(ren, this, vol), + true); + + // Termination methods replacements + //-------------------------------------------------------------------------- + vertexShader = vtkvolume::replace( + vertexShader, + "//VTK::Termination::Dec", + vtkvolume::TerminationGlobalsVert(ren, this, vol), + true); + + fragmentShader = vtkvolume::replace( + fragmentShader, + "//VTK::Termination::Dec", + vtkvolume::TerminationGlobalsFrag(ren, this, vol), + true); + + fragmentShader = vtkvolume::replace( + fragmentShader, + "//VTK::Terminate::Init", + vtkvolume::TerminationInit(ren, this, vol), + true); + + fragmentShader = vtkvolume::replace( + fragmentShader, + "//VTK::Terminate::Impl", + vtkvolume::TerminationIncrement(ren, this, vol), + true); + + fragmentShader = vtkvolume::replace( + fragmentShader, + "//VTK::Terminate::Exit", + vtkvolume::TerminationExit(ren, this, vol), + true); + + // Shading methods replacements + //-------------------------------------------------------------------------- + vertexShader = vtkvolume::replace( + vertexShader, + "//VTK::Shading::Dec", + vtkvolume::ShadingGlobalsVert(ren, this, vol), + true); + + fragmentShader = vtkvolume::replace( + fragmentShader, + "//VTK::Shading::Dec", + vtkvolume::ShadingGlobalsFrag(ren, this, vol), + true); + + fragmentShader = vtkvolume::replace( + fragmentShader, + "//VTK::Shading::Init", + vtkvolume::ShadingInit(ren, this, vol), + true); + + fragmentShader = vtkvolume::replace( + fragmentShader, + "//VTK::Shading::Impl", vtkvolume::ShadingIncrement(ren, this, vol, this->MaskInput, this->Impl->CurrentMask, this->MaskType, noOfComponents, - independentComponents), true); - fragmentShader = vtkvolume::replace(fragmentShader, "//VTK::Shading::Exit", + independentComponents), + true); + + fragmentShader = vtkvolume::replace( + fragmentShader, + "//VTK::Shading::Exit", vtkvolume::ShadingExit(ren, this, vol, noOfComponents, - independentComponents), true); + independentComponents), + true); - fragmentShader = vtkvolume::replace(fragmentShader, + + // Compute methods replacements + //-------------------------------------------------------------------------- + fragmentShader = vtkvolume::replace( + fragmentShader, "//VTK::ComputeOpacity::Dec", vtkvolume::OpacityTransferFunc(ren, this, vol, noOfComponents, - independentComponents), true); - fragmentShader = vtkvolume::replace(fragmentShader, "//VTK::ComputeGradient::Dec", - vtkvolume::GradientsComputeFunc(ren, this, vol, noOfComponents), true); - fragmentShader = vtkvolume::replace(fragmentShader, + independentComponents), + true); + + fragmentShader = vtkvolume::replace( + fragmentShader, + "//VTK::ComputeGradient::Dec", + vtkvolume::GradientsComputeFunc(ren, this, vol, noOfComponents, + independentComponents), + true); + + fragmentShader = vtkvolume::replace( + fragmentShader, "//VTK::ColorTransferFunc::Dec", vtkvolume::ColorTransferFunc(ren, this, vol, noOfComponents, - independentComponents), true); - fragmentShader = vtkvolume::replace(fragmentShader, + independentComponents), + true); + + fragmentShader = vtkvolume::replace( + fragmentShader, "//VTK::ComputeLighting::Dec", vtkvolume::LightComputeFunc(ren, this, vol, noOfComponents, - this->Impl->NumberOfLights, - this->Impl->LightComplexity), true); - fragmentShader = vtkvolume::replace(fragmentShader, + independentComponents, + this->Impl->NumberOfLights, + this->Impl->LightComplexity), + true); + + fragmentShader = vtkvolume::replace( + fragmentShader, "//VTK::RayDirectionFunc::Dec", - vtkvolume::RayDirectionFunc(ren, this, vol,noOfComponents), true); - - vertexShader = vtkvolume::replace(vertexShader, "//VTK::Cropping::Dec", - vtkvolume::CroppingGlobalsVert(ren, this, vol), true); - fragmentShader = vtkvolume::replace(fragmentShader, "//VTK::Cropping::Dec", - vtkvolume::CroppingGlobalsFrag(ren, this, vol), true); - fragmentShader = vtkvolume::replace(fragmentShader, "//VTK::Cropping::Init", - vtkvolume::CroppingInit(ren, this, vol), true); - fragmentShader = vtkvolume::replace(fragmentShader, "//VTK::Cropping::Impl", - vtkvolume::CroppingIncrement(ren, this, vol), true); - fragmentShader = vtkvolume::replace(fragmentShader, "//VTK::Cropping::Exit", - vtkvolume::CroppingExit(ren, this, vol), true); - - vertexShader = vtkvolume::replace(vertexShader, "//VTK::Clipping::Dec", - vtkvolume::ClippingGlobalsVert(ren, this, vol), true); - fragmentShader = vtkvolume::replace(fragmentShader, "//VTK::Clipping::Dec", - vtkvolume::ClippingGlobalsFrag(ren, this, vol), true); - fragmentShader = vtkvolume::replace(fragmentShader, "//VTK::Clipping::Init", - vtkvolume::ClippingInit(ren, this, vol), true); - fragmentShader = vtkvolume::replace(fragmentShader, "//VTK::Clipping::Impl", - vtkvolume::ClippingIncrement(ren, this, vol), true); - fragmentShader = vtkvolume::replace(fragmentShader, "//VTK::Clipping::Exit", - vtkvolume::ClippingExit(ren, this, vol), true); - - fragmentShader = vtkvolume::replace(fragmentShader, - "//VTK::BinaryMask::Dec", + vtkvolume::RayDirectionFunc(ren, this, vol,noOfComponents), + true); + + // Cropping methods replacements + //-------------------------------------------------------------------------- + vertexShader = vtkvolume::replace( + vertexShader, + "//VTK::Cropping::Dec", + vtkvolume::CroppingGlobalsVert(ren, this, vol), + true); + + fragmentShader = vtkvolume::replace( + fragmentShader, + "//VTK::Cropping::Dec", + vtkvolume::CroppingGlobalsFrag(ren, this, vol), + true); + + fragmentShader = vtkvolume::replace( + fragmentShader, + "//VTK::Cropping::Init", + vtkvolume::CroppingInit(ren, this, vol), + true); + + fragmentShader = vtkvolume::replace( + fragmentShader, + "//VTK::Cropping::Impl", + vtkvolume::CroppingIncrement(ren, this, vol), + true); + + fragmentShader = vtkvolume::replace( + fragmentShader, + "//VTK::Cropping::Exit", + vtkvolume::CroppingExit(ren, this, vol), + true); + + // Clipping methods replacements + //-------------------------------------------------------------------------- + vertexShader = vtkvolume::replace( + vertexShader, + "//VTK::Clipping::Dec", + vtkvolume::ClippingGlobalsVert(ren, this, vol), + true); + + fragmentShader = vtkvolume::replace( + fragmentShader, + "//VTK::Clipping::Dec", + vtkvolume::ClippingGlobalsFrag(ren, this, vol), + true); + + fragmentShader = vtkvolume::replace( + fragmentShader, + "//VTK::Clipping::Init", + vtkvolume::ClippingInit(ren, this, vol), + true); + + fragmentShader = vtkvolume::replace( + fragmentShader, + "//VTK::Clipping::Impl", + vtkvolume::ClippingIncrement(ren, this, vol), + true); + + fragmentShader = vtkvolume::replace( + fragmentShader, + "//VTK::Clipping::Exit", + vtkvolume::ClippingExit(ren, this, vol), + true); + + // Masking methods replacements + //-------------------------------------------------------------------------- + fragmentShader = vtkvolume::replace( + fragmentShader, + "//VTK::BinaryMask::Dec", vtkvolume::BinaryMaskGlobalsFrag(ren, this, vol, this->MaskInput, this->Impl->CurrentMask, - this->MaskType), true); - fragmentShader = vtkvolume::replace(fragmentShader, "//VTK::BinaryMask::Impl", + this->MaskType), + true); + + fragmentShader = vtkvolume::replace( + fragmentShader, + "//VTK::BinaryMask::Impl", vtkvolume::BinaryMaskIncrement(ren, this, vol, this->MaskInput, this->Impl->CurrentMask, - this->MaskType), true); + this->MaskType), + true); - fragmentShader = vtkvolume::replace(fragmentShader, - "//VTK::CompositeMask::Dec", + fragmentShader = vtkvolume::replace( + fragmentShader, + "//VTK::CompositeMask::Dec", vtkvolume::CompositeMaskGlobalsFrag(ren, this, vol, this->MaskInput, this->Impl->CurrentMask, - this->MaskType), true); - fragmentShader = vtkvolume::replace(fragmentShader, - "//VTK::CompositeMask::Impl", + this->MaskType), + true); + + fragmentShader = vtkvolume::replace( + fragmentShader, + "//VTK::CompositeMask::Impl", vtkvolume::CompositeMaskIncrement(ren, this, vol, this->MaskInput, this->Impl->CurrentMask, - this->MaskType), true); + this->MaskType), + true); + // Now compile the shader + //-------------------------------------------------------------------------- this->Impl->ShaderProgram = this->Impl->ShaderCache->ReadyShader( vertexShader.c_str(), fragmentShader.c_str(), ""); if (!this->Impl->ShaderProgram->GetCompiled()) @@ -1968,7 +2139,7 @@ void vtkOpenGLGPUVolumeRayCastMapper::BuildShader(vtkRenderer* ren, vtkErrorMacro("Shader failed to compile"); } - std::cerr << "fragment shader " << fragmentShader << std::endl; + //std::cerr << "fragment shader " << fragmentShader << std::endl; this->Impl->ShaderBuildTime.Modified(); } @@ -2065,13 +2236,8 @@ void vtkOpenGLGPUVolumeRayCastMapper::GPURender(vtkRenderer* ren, // Get the volume property (must have one) vtkVolumeProperty* volumeProperty = vol->GetProperty(); - // Set OpenGL states - vtkVolumeStateRAII glState; - - if (!this->Impl->IsInitialized()) - { - this->Impl->Initialize(ren, vol); - } + // Check whether we have independent components or not + int independentComponents = volumeProperty->GetIndependentComponents(); vtkDataArray* scalars = this->GetScalars(input, this->ScalarMode, @@ -2081,10 +2247,19 @@ void vtkOpenGLGPUVolumeRayCastMapper::GPURender(vtkRenderer* ren, this->CellFlag); // How many components are there? - int numberOfScalarComponents = scalars->GetNumberOfComponents(); + int noOfComponents = scalars->GetNumberOfComponents(); + + // Set OpenGL states + vtkVolumeStateRAII glState; + + if (!this->Impl->IsInitialized()) + { + this->Impl->Initialize(ren, vol, noOfComponents, + independentComponents); + } // If it is just one, then get the range from the scalars - if(numberOfScalarComponents == 1) + if(noOfComponents == 1) { // NOTE: here, we ignore the blank cells. scalars->GetRange(this->Impl->ScalarsRange); @@ -2155,7 +2330,7 @@ void vtkOpenGLGPUVolumeRayCastMapper::GPURender(vtkRenderer* ren, { this->Impl->LastProjectionParallel = ren->GetActiveCamera()->GetParallelProjection(); - this->BuildShader(ren, vol, numberOfScalarComponents); + this->BuildShader(ren, vol, noOfComponents); } // Bind the shader @@ -2167,8 +2342,8 @@ void vtkOpenGLGPUVolumeRayCastMapper::GPURender(vtkRenderer* ren, this->Impl->UpdateVolumeGeometry(ren, vol, input); // Update opacity transfer function - for (int i = 0; i < (volumeProperty->GetIndependentComponents() ? - numberOfScalarComponents : 1); ++i) + for (int i = 0; i < (independentComponents ? + noOfComponents : 1); ++i) { this->Impl->UpdateOpacityTransferFunction(ren, vol, scalars->GetNumberOfComponents(), i); @@ -2232,9 +2407,9 @@ void vtkOpenGLGPUVolumeRayCastMapper::GPURender(vtkRenderer* ren, // Pass constant uniforms at initialization this->Impl->ShaderProgram->SetUniformi("in_noOfComponents", - numberOfScalarComponents); + noOfComponents); this->Impl->ShaderProgram->SetUniformi("in_independentComponents", - volumeProperty->GetIndependentComponents()); + independentComponents); // Step should be dependant on the bounds and not on the texture size @@ -2263,8 +2438,7 @@ void vtkOpenGLGPUVolumeRayCastMapper::GPURender(vtkRenderer* ren, int opacitySamplers[4]; int colorSamplers[4]; int gradientOpacitySamplers[4]; - int numberOfSamplers = (volumeProperty->GetIndependentComponents() ? - numberOfScalarComponents : 1); + int numberOfSamplers = (independentComponents ? noOfComponents : 1); for (int i = 0; i < numberOfSamplers; ++i) { this->Impl->OpacityTables->GetTable(i)->Bind(); @@ -2276,7 +2450,6 @@ void vtkOpenGLGPUVolumeRayCastMapper::GPURender(vtkRenderer* ren, this->Impl->RGBTables->GetTable(i)->Bind(); colorSamplers[i] = this->Impl->RGBTables->GetTable(i)->GetTextureUnit(); - std::cerr << colorSamplers[i] << std::endl; } if (this->Impl->GradientOpacityTables) @@ -2319,7 +2492,7 @@ void vtkOpenGLGPUVolumeRayCastMapper::GPURender(vtkRenderer* ren, "in_mask", this->Impl->CurrentMask->GetTextureUnit()); } - if(numberOfScalarComponents == 1 && + if(noOfComponents == 1 && this->BlendMode != vtkGPUVolumeRayCastMapper::ADDITIVE_BLEND) { if (this->MaskInput != 0 && this->MaskType == LabelMapMaskType) @@ -2495,10 +2668,9 @@ void vtkOpenGLGPUVolumeRayCastMapper::GPURender(vtkRenderer* ren, this->Impl->ShaderProgram->SetUniformf("in_bias", (0.5 - (this->FinalColorLevel/this->FinalColorWindow))); - if (numberOfScalarComponents > 1 && - volumeProperty->GetIndependentComponents()) + if (noOfComponents > 1 && independentComponents) { - for (int i = 0; i < numberOfScalarComponents; ++i) + for (int i = 0; i < noOfComponents; ++i) { fvalue4[i] = static_cast(volumeProperty->GetComponentWeight(i)); } diff --git a/Rendering/VolumeOpenGL2/vtkOpenGLGPUVolumeRayCastMapper.h b/Rendering/VolumeOpenGL2/vtkOpenGLGPUVolumeRayCastMapper.h index aebd68a0201..26d5c9565cd 100644 --- a/Rendering/VolumeOpenGL2/vtkOpenGLGPUVolumeRayCastMapper.h +++ b/Rendering/VolumeOpenGL2/vtkOpenGLGPUVolumeRayCastMapper.h @@ -49,7 +49,7 @@ class VTKRENDERINGVOLUMEOPENGL2_EXPORT vtkOpenGLGPUVolumeRayCastMapper : vtkVolume *vtkNotUsed(vol), double vtkNotUsed(datasetBounds)[6], double vtkNotUsed(scalarRange)[2], - int vtkNotUsed(numberOfScalarComponents), + int vtkNotUsed(noOfComponents), unsigned int vtkNotUsed(numberOfLevels)) {} // \pre input is up-to-date @@ -58,7 +58,7 @@ class VTKRENDERINGVOLUMEOPENGL2_EXPORT vtkOpenGLGPUVolumeRayCastMapper : unsigned int vtkNotUsed(level)) {} virtual void PostRender(vtkRenderer *vtkNotUsed(ren), - int vtkNotUsed(numberOfScalarComponents)) {} + int vtkNotUsed(noOfComponents)) {} // Description: // Rendering volume on GPU diff --git a/Rendering/VolumeOpenGL2/vtkVolumeShaderComposer.h b/Rendering/VolumeOpenGL2/vtkVolumeShaderComposer.h index f7d2b51d5ab..f3ad87eba48 100644 --- a/Rendering/VolumeOpenGL2/vtkVolumeShaderComposer.h +++ b/Rendering/VolumeOpenGL2/vtkVolumeShaderComposer.h @@ -257,10 +257,11 @@ namespace vtkvolume std::string GradientsComputeFunc(vtkRenderer* vtkNotUsed(ren), vtkVolumeMapper* vtkNotUsed(mapper), vtkVolume* vol, - int vtkNotUsed(numberOfComponents)) + int noOfComponents, + int independentComponents) { std::string shaderStr; - if (vol->GetProperty()->HasGradientOpacity()) + if (noOfComponents == 1 && vol->GetProperty()->HasGradientOpacity()) { shaderStr += std::string("\ \nuniform sampler1D in_gradientTransferFunc;\ @@ -270,6 +271,17 @@ namespace vtkvolume \n }" ); } + else if (noOfComponents > 1 && independentComponents && + vol->GetProperty()->HasGradientOpacity()) + { + shaderStr += std::string("\ + \nuniform sampler1D in_gradientTransferFunc[4];\ + \nfloat computeGradientOpacity(vec4 grad, int component)\ + \n {\ + \n return texture1D(in_gradientTransferFunc[component], grad.w).w;\ + \n }" + ); + } if (vol->GetProperty()->GetShade() && !vol->GetProperty()->HasGradientOpacity()) @@ -300,7 +312,7 @@ namespace vtkvolume \n {\ \n vec3 g1;\ \n vec4 g2;\ - \n vec3 xvec = vec3(in_cellStep[0], 0.0, 0.0);\ + \n vec3 xvec = vec3(in_cellStep[0], 0.0, 0.0);\ \n vec3 yvec = vec3(0.0, in_cellStep[1], 0.0);\ \n vec3 zvec = vec3(0.0, 0.0, in_cellStep[2]);\ \n g1.x = texture3D(in_volume, vec3(g_dataPos + xvec)).x;\ @@ -373,7 +385,8 @@ namespace vtkvolume std::string LightComputeFunc(vtkRenderer* vtkNotUsed(ren), vtkVolumeMapper* vtkNotUsed(mapper), vtkVolume* vol, - int vtkNotUsed(numberOfComponents), + int noOfComponents, + int independentComponents, int vtkNotUsed(numberOfLights), int lightingComplexity) { @@ -585,16 +598,29 @@ namespace vtkvolume ); } - if (volProperty->HasGradientOpacity()) + if (noOfComponents == 1 && volProperty->HasGradientOpacity()) { shaderStr += std::string("\ \n if (gradient.w >= 0.0)\ \n {\ \n color.a = color.a *\ - \n texture1D(in_gradientTransferFunc, gradient.w).w;\ + \n computeGradientOpacity(gradient);\ \n }" ); } + else if (noOfComponents > 1 && independentComponents && + volProperty->HasGradientOpacity()) + { + shaderStr += std::string("\ + \n if (gradient.w >= 0.0)\ + \n {\ + \n for (int i = 0; i < in_noOfComponents; ++i)\ + \n {\ + \n color.a = color.a *\ + \n computeGradientOpacity(gradient, i) * in_componentWeight[i];\ + \n }" + ); + } shaderStr += std::string("\ \n return vec4(finalColor, color.a);\ @@ -635,7 +661,7 @@ namespace vtkvolume vtkVolumeMapper* vtkNotUsed(mapper), vtkVolume* vtkNotUsed(vol), int numberOfComponents, - bool independentComponents = false) + int independentComponents = 0) { if (numberOfComponents == 1) { @@ -673,7 +699,7 @@ namespace vtkvolume vtkVolumeMapper* vtkNotUsed(mapper), vtkVolume* vtkNotUsed(vol), int numberOfComponents, - bool independentComponents = false) + int independentComponents = 0) { if (numberOfComponents > 1 && independentComponents) { @@ -751,7 +777,7 @@ namespace vtkvolume vtkImageData* maskInput, vtkVolumeMask* mask, int maskType, int noOfComponents, - bool independentComponents = false) + int independentComponents = 0) { std::string shaderStr = std::string("\ \n if (!l_skip)\ @@ -888,7 +914,7 @@ namespace vtkvolume vtkVolumeMapper* mapper, vtkVolume* vtkNotUsed(vol), int noOfComponents, - bool independentComponents = false) + int independentComponents = 0) { if (mapper->GetBlendMode() == vtkVolumeMapper::MAXIMUM_INTENSITY_BLEND) { @@ -899,7 +925,7 @@ namespace vtkvolume \n {\ \n vec4 g_srcColor = vec4(0);\ \n for (int i = 0; i < in_noOfComponents; ++i)\ - \n {\ \ + \n {\ \n vec4 tmp = vec4(computeColor(l_maxValue, i);\ \n g_srcColor[0] += tmp[0] * tmp[3] * in_componentWeight[i];\ \n g_srcColor[1] += tmp[1] * tmp[3] * in_componentWeight[i];\ @@ -928,7 +954,7 @@ namespace vtkvolume \n {\ \n vec4 g_srcColor = vec4(0);\ \n for (int i = 0; i < in_noOfComponents; ++i)\ - \n {\ \ + \n {\ \n vec4 tmp = vec4(computeColor(l_maxValue, i);\ \n g_srcColor[0] += tmp[0] * tmp[3] * in_componentWeight[i];\ \n g_srcColor[1] += tmp[1] * tmp[3] * in_componentWeight[i];\