From 52fd8ad8787eceef59e944c4f702cd3f101b5949 Mon Sep 17 00:00:00 2001 From: Kyle Lutz <kyle.lutz@kitware.com> Date: Sat, 20 Apr 2013 10:28:31 -0400 Subject: [PATCH] Refactoring code to set color/opacity/visibility for blocks. This commit refactors some of the code added in recent weeks to add ability for users to set display paramaters for blocks within a composite dataset. This commit additionally adds support for changing block opacity. Blocks colors/opacities can also be overridden when using scalar coloring. The only issue is when depth-peeling gets used. In that case, point-data coloring with texture (i.e. using interpolate scalars before mapping) results in color bleeds. We need to dig into the depth peeling code to address that issue. Change-Id: I2c86912b45bc0516dc4dc726df9448e0569c8312 --- .../vtkCompositeDataDisplayAttributes.cxx | 47 +++ .../Core/vtkCompositeDataDisplayAttributes.h | 30 ++ Rendering/Core/vtkCompositePainter.cxx | 231 ++++++++----- Rendering/Core/vtkCompositePainter.h | 48 ++- .../Core/vtkCompositePolyDataMapper2.cxx | 75 +++-- Rendering/Core/vtkCompositePolyDataMapper2.h | 17 + Rendering/Core/vtkPainter.cxx | 17 - Rendering/Core/vtkPainter.h | 9 - Rendering/Core/vtkPainterDeviceAdapter.cxx | 11 - Rendering/Core/vtkPainterDeviceAdapter.h | 9 - Rendering/Core/vtkProperty.cxx | 39 ++- Rendering/Core/vtkProperty.h | 19 +- Rendering/OpenGL/CMakeLists.txt | 2 + Rendering/OpenGL/Testing/Cxx/CMakeLists.txt | 3 +- .../Cxx/TestMultiblockDisplayProperties.cxx | 103 ++++++ .../OpenGL/vtkOpenGLCompositePainter.cxx | 117 +++++++ Rendering/OpenGL/vtkOpenGLCompositePainter.h | 47 +++ .../OpenGL/vtkOpenGLPainterDeviceAdapter.cxx | 128 ------- .../OpenGL/vtkOpenGLPainterDeviceAdapter.h | 20 -- Rendering/OpenGL/vtkOpenGLProperty.cxx | 313 ++++++++---------- Rendering/OpenGL/vtkOpenGLProperty.h | 46 +-- .../vtkOpenGLScalarsToColorsPainter.cxx | 4 +- 22 files changed, 807 insertions(+), 528 deletions(-) create mode 100644 Rendering/OpenGL/Testing/Cxx/TestMultiblockDisplayProperties.cxx create mode 100644 Rendering/OpenGL/vtkOpenGLCompositePainter.cxx create mode 100644 Rendering/OpenGL/vtkOpenGLCompositePainter.h diff --git a/Rendering/Core/vtkCompositeDataDisplayAttributes.cxx b/Rendering/Core/vtkCompositeDataDisplayAttributes.cxx index c64f3d32271..21c47d329ad 100644 --- a/Rendering/Core/vtkCompositeDataDisplayAttributes.cxx +++ b/Rendering/Core/vtkCompositeDataDisplayAttributes.cxx @@ -47,6 +47,11 @@ bool vtkCompositeDataDisplayAttributes::GetBlockVisibility(unsigned int flat_ind } } +bool vtkCompositeDataDisplayAttributes::HasBlockVisibilities() const +{ + return !this->BlockVisibilities.empty(); +} + bool vtkCompositeDataDisplayAttributes::HasBlockVisibility(unsigned int flat_index) const { return this->BlockVisibilities.count(flat_index) == size_t(1); @@ -91,6 +96,11 @@ vtkColor3d vtkCompositeDataDisplayAttributes::GetBlockColor( return vtkColor3d(); } +bool vtkCompositeDataDisplayAttributes::HasBlockColors() const +{ + return !this->BlockColors.empty(); +} + bool vtkCompositeDataDisplayAttributes::HasBlockColor( unsigned int flat_index) const { @@ -112,3 +122,40 @@ void vtkCompositeDataDisplayAttributes::PrintSelf(ostream& os, vtkIndent indent) { this->Superclass::PrintSelf(os, indent); } + +void vtkCompositeDataDisplayAttributes::SetBlockOpacity(unsigned int flat_index, double opacity) +{ + this->BlockOpacities[flat_index] = opacity; +} + +double vtkCompositeDataDisplayAttributes::GetBlockOpacity(unsigned int flat_index) const +{ + std::map<unsigned int, double>::const_iterator iter = this->BlockOpacities.find(flat_index); + + if(iter != this->BlockOpacities.end()) + { + return iter->second; + } + + return 0; +} + +bool vtkCompositeDataDisplayAttributes::HasBlockOpacities() const +{ + return !this->BlockOpacities.empty(); +} + +bool vtkCompositeDataDisplayAttributes::HasBlockOpacity(unsigned int flat_index) const +{ + return this->BlockOpacities.find(flat_index) != this->BlockOpacities.end(); +} + +void vtkCompositeDataDisplayAttributes::RemoveBlockOpacity(unsigned int flat_index) +{ + this->BlockOpacities.erase(flat_index); +} + +void vtkCompositeDataDisplayAttributes::RemoveBlockOpacities() +{ + this->BlockOpacities.clear(); +} diff --git a/Rendering/Core/vtkCompositeDataDisplayAttributes.h b/Rendering/Core/vtkCompositeDataDisplayAttributes.h index 64caadf20db..13768610247 100644 --- a/Rendering/Core/vtkCompositeDataDisplayAttributes.h +++ b/Rendering/Core/vtkCompositeDataDisplayAttributes.h @@ -34,6 +34,10 @@ public: vtkTypeMacro(vtkCompositeDataDisplayAttributes, vtkObject) void PrintSelf(ostream& os, vtkIndent indent); + // Description: + // Returns true if any block has any block visibility is set. + bool HasBlockVisibilities() const; + // Description: // Set/get the visibility for the block with \p flat_index. void SetBlockVisibility(unsigned int flat_index, bool visible); @@ -59,6 +63,10 @@ public: void GetBlockColor(unsigned int flat_index, double color[3]) const; vtkColor3d GetBlockColor(unsigned int flat_index) const; + // Description: + // Returns true if any block has any block color is set. + bool HasBlockColors() const; + // Description: // Returns true if the block with the given \p flat_index has a color. bool HasBlockColor(unsigned int flat_index) const; @@ -71,6 +79,27 @@ public: // Removes all block colors. void RemoveBlockColors(); + // Description: + // Set/get the opacity for the block with flat_index. + void SetBlockOpacity(unsigned int flat_index, double opacity); + double GetBlockOpacity(unsigned int flat_index) const; + + // Description: + // Returns true if any block has an opacity set. + bool HasBlockOpacities() const; + + // Description: + // Returns true if the block with flat_index has an opacity set. + bool HasBlockOpacity(unsigned int flat_index) const; + + // Description: + // Removes the set opacity for the block with flat_index. + void RemoveBlockOpacity(unsigned int flat_index); + + // Description: + // Removes all block opacities. + void RemoveBlockOpacities(); + protected: vtkCompositeDataDisplayAttributes(); ~vtkCompositeDataDisplayAttributes(); @@ -82,6 +111,7 @@ private: private: std::map<unsigned int, bool> BlockVisibilities; std::map<unsigned int, vtkColor3d> BlockColors; + std::map<unsigned int, double> BlockOpacities; }; #endif // __vtkCompositeDataDisplayAttributes_h diff --git a/Rendering/Core/vtkCompositePainter.cxx b/Rendering/Core/vtkCompositePainter.cxx index fb645d53c2f..303db35f420 100644 --- a/Rendering/Core/vtkCompositePainter.cxx +++ b/Rendering/Core/vtkCompositePainter.cxx @@ -14,30 +14,40 @@ =========================================================================*/ #include "vtkCompositePainter.h" +#include "vtkColor.h" +#include "vtkCompositeDataDisplayAttributes.h" #include "vtkCompositeDataIterator.h" #include "vtkCompositeDataSet.h" #include "vtkGarbageCollector.h" #include "vtkHardwareSelector.h" -#include "vtkObjectFactory.h" -#include "vtkRenderer.h" -#include "vtkPolyData.h" +#include "vtkInformation.h" +#include "vtkInformationObjectBaseKey.h" #include "vtkMultiBlockDataSet.h" #include "vtkMultiPieceDataSet.h" -#include "vtkCompositeDataDisplayAttributes.h" -#include "vtkRenderWindow.h" -#include "vtkColor.h" +#include "vtkObjectFactory.h" +#include "vtkPolyData.h" #include "vtkProperty.h" +#include "vtkRenderer.h" +#include "vtkRenderWindow.h" + +#include <assert.h> -vtkStandardNewMacro(vtkCompositePainter); +// Return NULL if no override is supplied. +vtkAbstractObjectFactoryNewMacro(vtkCompositePainter) + +vtkInformationKeyMacro(vtkCompositePainter, DISPLAY_ATTRIBUTES, ObjectBase); +vtkCxxSetObjectMacro(vtkCompositePainter, CompositeDataDisplayAttributes, vtkCompositeDataDisplayAttributes); //---------------------------------------------------------------------------- vtkCompositePainter::vtkCompositePainter() { this->OutputData = 0; + this->CompositeDataDisplayAttributes = 0; } //---------------------------------------------------------------------------- vtkCompositePainter::~vtkCompositePainter() { + this->SetCompositeDataDisplayAttributes(0); } //---------------------------------------------------------------------------- @@ -62,20 +72,39 @@ void vtkCompositePainter::RenderInternal(vtkRenderer* renderer, vtkHardwareSelector* selector = renderer->GetSelector(); - if(this->CompositeDataDisplayAttributes) + if (this->CompositeDataDisplayAttributes && + (this->CompositeDataDisplayAttributes->HasBlockOpacities() || + this->CompositeDataDisplayAttributes->HasBlockVisibilities() || + this->CompositeDataDisplayAttributes->HasBlockColors())) { + vtkProperty* prop = actor->GetProperty(); + RenderBlockState state; + + // Push base-values on the state stack. + state.Visibility.push(true); + state.Opacity.push(prop->GetOpacity()); + state.AmbientColor.push(vtkColor3d(prop->GetAmbientColor())); + state.DiffuseColor.push(vtkColor3d(prop->GetDiffuseColor())); + state.SpecularColor.push(vtkColor3d(prop->GetSpecularColor())); + + // OpenGL currently knows how to render *this* state. + state.RenderedOpacity = state.Opacity.top(); + state.RenderedAmbientColor = state.AmbientColor.top(); + state.RenderedDiffuseColor = state.DiffuseColor.top(); + state.RenderedSpecularColor = state.SpecularColor.top(); + // render using the composite data attributes unsigned int flat_index = 0; - bool visible = true; - vtkColor3d color(0.5, 0.5, 0.5); this->RenderBlock(renderer, actor, typeflags, forceCompileOnly, input, flat_index, - visible, - color); + state); + + // restore OpenGL state, if it was changed. + this->UpdateRenderingState(renderer->GetRenderWindow(), actor->GetProperty(), state); } else { @@ -117,101 +146,103 @@ void vtkCompositePainter::RenderBlock(vtkRenderer *renderer, bool forceCompileOnly, vtkDataObject *dobj, unsigned int &flat_index, - bool &visible, - vtkColor3d &color) + vtkCompositePainter::RenderBlockState &state) { - vtkHardwareSelector *selector = renderer->GetSelector(); - vtkProperty *property = actor->GetProperty(); + assert("Sanity Check" && + (state.Visibility.size() > 0) && + (state.Opacity.size() > 0) && + (state.AmbientColor.size() > 0) && + (state.DiffuseColor.size() > 0) && + (state.SpecularColor.size() > 0)); - // push display attributes - bool pop_visibility = false; - bool prev_visible = visible; - if(this->CompositeDataDisplayAttributes->HasBlockVisibility(flat_index)) - { - visible = this->CompositeDataDisplayAttributes->GetBlockVisibility(flat_index); - pop_visibility = true; - } + vtkHardwareSelector *selector = renderer->GetSelector(); + vtkProperty *property = actor->GetProperty(); + vtkCompositeDataDisplayAttributes* cda = this->CompositeDataDisplayAttributes; - bool pop_color = false; - vtkColor3d prev_color = color; - if(this->CompositeDataDisplayAttributes->HasBlockColor(flat_index)) - { - color = this->CompositeDataDisplayAttributes->GetBlockColor(flat_index); - pop_color = true; + // A block always *has* a visibility state, either explicitly set or + // inherited. + state.Visibility.push( + cda->HasBlockVisibility(flat_index) ? + cda->GetBlockVisibility(flat_index) : state.Visibility.top()); - double color4[] = { color[0], color[1], color[2], 1. }; - property->RenderMaterial(actor, renderer, color4, color4, color4, 1.); - } + bool overrides_opacity = cda->HasBlockOpacity(flat_index); + if (overrides_opacity) + { + state.Opacity.push(cda->GetBlockOpacity(flat_index)); + } - vtkMultiBlockDataSet *mbds = vtkMultiBlockDataSet::SafeDownCast(dobj); - vtkMultiPieceDataSet *mpds = vtkMultiPieceDataSet::SafeDownCast(dobj); - if(mbds || mpds) - { - // move flat_index to first child - flat_index++; + bool overrides_color = cda->HasBlockColor(flat_index); + if (overrides_color) + { + vtkColor3d color = cda->GetBlockColor(flat_index); + state.AmbientColor.push(color); + state.DiffuseColor.push(color); + state.SpecularColor.push(color); + } + + unsigned int my_flat_index = flat_index; + // Advance flat-index. After this point, flat_index no longer points to this + // block. + flat_index++; - // recurse down to child blocks - unsigned int childCount = - mbds ? mbds->GetNumberOfBlocks() : mpds->GetNumberOfPieces(); - for(unsigned int i = 0; i < childCount; i++) + vtkMultiBlockDataSet *mbds = vtkMultiBlockDataSet::SafeDownCast(dobj); + vtkMultiPieceDataSet *mpds = vtkMultiPieceDataSet::SafeDownCast(dobj); + if (mbds || mpds) + { + unsigned int numChildren = mbds? mbds->GetNumberOfBlocks() : + mpds->GetNumberOfPieces(); + for (unsigned int cc=0 ; cc < numChildren; cc++) + { + vtkDataObject* child = mbds ? mbds->GetBlock(cc) : mpds->GetPiece(cc); + if (child == NULL) { - this->RenderBlock(renderer, - actor, - typeflags, - forceCompileOnly, - mbds ? mbds->GetBlock(i) : mpds->GetPiece(i), - flat_index, - visible, - color); + // speeds things up when dealing with NULL blocks (which is common with + // AMRs). + flat_index++; + continue; } + this->RenderBlock(renderer, actor, typeflags, forceCompileOnly, + child, flat_index, state); } - else if(dobj) + } + else if (dobj && state.Visibility.top() == true && state.Opacity.top() > 0.0) + { + // Implies that the block is a non-null leaf node. + // The top of the "stacks" have the state that this block must be rendered + // with. + if (selector) { - // render leaf-node - if(visible) - { - if(selector) - { - selector->BeginRenderProp(); - // If hardware selection is in progress, we need to pass the composite - // index to the selection framework, - selector->RenderCompositeIndex(flat_index); - } - - this->DelegatePainter->SetInput(dobj); - this->OutputData = dobj; - this->Superclass::RenderInternal(renderer, - actor, - typeflags, - forceCompileOnly); - this->OutputData = 0; - - if(selector) - { - selector->EndRenderProp(); - } - } - - flat_index++; + selector->BeginRenderProp(); + selector->RenderCompositeIndex(my_flat_index); } else { - flat_index++; + // Not selecting, render the colors and stuff correctly for this block. + // For that. + this->UpdateRenderingState(renderer->GetRenderWindow(), property, state); } - // pop display attributes (if neccessary) - if(pop_visibility) - { - visible = prev_visible; + this->DelegatePainter->SetInput(dobj); + this->OutputData = dobj; + this->Superclass::RenderInternal(renderer, actor, typeflags, forceCompileOnly); + this->OutputData = 0; + if (selector) + { + selector->EndRenderProp(); + } } - if(pop_color) + if (overrides_color) { - color = prev_color; - - double color4[] = { color[0], color[1], color[2], 1. }; - property->RenderMaterial(actor, renderer, color4, color4, color4, 1.); + state.AmbientColor.pop(); + state.DiffuseColor.pop(); + state.SpecularColor.pop(); } + if (overrides_opacity) + { + state.Opacity.pop(); + } + state.Visibility.pop(); } //----------------------------------------------------------------------------- @@ -222,9 +253,33 @@ void vtkCompositePainter::ReportReferences(vtkGarbageCollector *collector) vtkGarbageCollectorReport(collector, this->OutputData, "Output"); } +//---------------------------------------------------------------------------- +void vtkCompositePainter::ProcessInformation(vtkInformation* info) +{ + this->Superclass::ProcessInformation(info); + + if (info->Has(DISPLAY_ATTRIBUTES())) + { + this->SetCompositeDataDisplayAttributes( + vtkCompositeDataDisplayAttributes::SafeDownCast( + info->Get(DISPLAY_ATTRIBUTES()))); + } +} + //---------------------------------------------------------------------------- void vtkCompositePainter::PrintSelf(ostream& os, vtkIndent indent) { this->Superclass::PrintSelf(os, indent); + + os << indent << "CompositeDataDisplayAttributes: " ; + if (this->CompositeDataDisplayAttributes) + { + os << endl; + this->CompositeDataDisplayAttributes->PrintSelf(os, indent.GetNextIndent()); + } + else + { + os << "(none)" << endl; + } } diff --git a/Rendering/Core/vtkCompositePainter.h b/Rendering/Core/vtkCompositePainter.h index 9ed7bdad0cd..dc7dd760a55 100644 --- a/Rendering/Core/vtkCompositePainter.h +++ b/Rendering/Core/vtkCompositePainter.h @@ -24,8 +24,13 @@ #include "vtkRenderingCoreModule.h" // For export macro #include "vtkPainter.h" +#include "vtkColor.h" // needed for vtkColor3d +#include <stack> // needed for RenderBlockState. -class vtkColor3d; +class vtkCompositeDataDisplayAttributes; +class vtkInformationObjectBaseKey; +class vtkProperty; +class vtkRenderWindow; class VTKRENDERINGCORE_EXPORT vtkCompositePainter : public vtkPainter { @@ -39,6 +44,18 @@ public: // simply forwards the input data object as the output. virtual vtkDataObject* GetOutput(); + // Description: + // Key used to pass a vtkCompositeDataDisplayAttributes instance doing the + // painter pipeline. + static vtkInformationObjectBaseKey* DISPLAY_ATTRIBUTES(); + + // Description: + // Set/get the composite data set display attributes. If set, these attributes + // can be used by the painter to control specific rendering attributes on a + // per-block basis for a multi-block dataset. + void SetCompositeDataDisplayAttributes(vtkCompositeDataDisplayAttributes *attributes); + vtkGetObjectMacro(CompositeDataDisplayAttributes, vtkCompositeDataDisplayAttributes) + //BTX protected: vtkCompositePainter(); @@ -48,6 +65,11 @@ protected: // Take part in garbage collection. virtual void ReportReferences(vtkGarbageCollector *collector); + // Description: + // Called before RenderInternal() if the Information has been changed + // since the last time this method was called. + virtual void ProcessInformation(vtkInformation* information); + // Description: // Performs the actual rendering. Subclasses may override this method. // default implementation merely call a Render on the DelegatePainter, @@ -57,16 +79,36 @@ protected: virtual void RenderInternal(vtkRenderer* renderer, vtkActor* actor, unsigned long typeflags, bool forceCompileOnly); + class RenderBlockState + { + public: + std::stack<bool> Visibility; + std::stack<double> Opacity; + std::stack<vtkColor3d> AmbientColor; + std::stack<vtkColor3d> DiffuseColor; + std::stack<vtkColor3d> SpecularColor; + + double RenderedOpacity; + vtkColor3d RenderedAmbientColor; + vtkColor3d RenderedDiffuseColor; + vtkColor3d RenderedSpecularColor; + }; + void RenderBlock(vtkRenderer *renderer, vtkActor *actor, unsigned long typeflags, bool forceCompileOnly, vtkDataObject *dobj, unsigned int &flat_index, - bool &visible, - vtkColor3d &color); + RenderBlockState &state); + + // Description: + // Overridden in vtkOpenGLCompositePainter to pass attributes to OpenGL. + virtual void UpdateRenderingState( + vtkRenderWindow*, vtkProperty*, RenderBlockState&) {} vtkDataObject* OutputData; + vtkCompositeDataDisplayAttributes *CompositeDataDisplayAttributes; private: vtkCompositePainter(const vtkCompositePainter&); // Not implemented. void operator=(const vtkCompositePainter&); // Not implemented. diff --git a/Rendering/Core/vtkCompositePolyDataMapper2.cxx b/Rendering/Core/vtkCompositePolyDataMapper2.cxx index 7f60fc4f046..1798c7ebfba 100644 --- a/Rendering/Core/vtkCompositePolyDataMapper2.cxx +++ b/Rendering/Core/vtkCompositePolyDataMapper2.cxx @@ -137,6 +137,12 @@ bool vtkCompositePolyDataMapper2::GetIsOpaque() } } } + else if(this->CompositeAttributes && + this->CompositeAttributes->HasBlockOpacities()) + { + return false; + } + return this->Superclass::GetIsOpaque(); } @@ -221,6 +227,46 @@ void vtkCompositePolyDataMapper2::RemoveBlockColors() } } +//---------------------------------------------------------------------------- +void vtkCompositePolyDataMapper2::SetBlockOpacity(unsigned int index, double opacity) +{ + if(this->CompositeAttributes) + { + this->CompositeAttributes->SetBlockOpacity(index, opacity); + this->Modified(); + } +} + +//---------------------------------------------------------------------------- +double vtkCompositePolyDataMapper2::GetBlockOpacity(unsigned int index) +{ + if(this->CompositeAttributes) + { + return this->CompositeAttributes->GetBlockOpacity(index); + } + return 1.; +} + +//---------------------------------------------------------------------------- +void vtkCompositePolyDataMapper2::RemoveBlockOpacity(unsigned int index) +{ + if(this->CompositeAttributes) + { + this->CompositeAttributes->RemoveBlockOpacity(index); + this->Modified(); + } +} + +//---------------------------------------------------------------------------- +void vtkCompositePolyDataMapper2::RemoveBlockOpacities() +{ + if(this->CompositeAttributes) + { + this->CompositeAttributes->RemoveBlockOpacities(); + this->Modified(); + } +} + //---------------------------------------------------------------------------- void vtkCompositePolyDataMapper2::SetCompositeDataDisplayAttributes( vtkCompositeDataDisplayAttributes *attributes) @@ -228,25 +274,7 @@ void vtkCompositePolyDataMapper2::SetCompositeDataDisplayAttributes( if(this->CompositeAttributes != attributes) { this->CompositeAttributes = attributes; - - // set composite display attributes on the composite painter - vtkDefaultPainter *defaultPainter = - vtkDefaultPainter::SafeDownCast(this->Painter); - if(defaultPainter) - { - vtkCompositePainter *compositePainter = - defaultPainter->GetCompositePainter(); - - compositePainter-> - SetCompositeDataDisplayAttributes(this->CompositeAttributes); - } - - // set composite display attributes on the selection painter - if(this->SelectionCompositePainter) - { - this->SelectionCompositePainter-> - SetCompositeDataDisplayAttributes(this->CompositeAttributes); - } + this->Modified(); } } @@ -257,6 +285,15 @@ vtkCompositePolyDataMapper2::GetCompositeDataDisplayAttributes() return this->CompositeAttributes; } +//---------------------------------------------------------------------------- +void vtkCompositePolyDataMapper2::UpdatePainterInformation() +{ + this->Superclass::UpdatePainterInformation(); + this->PainterInformation->Set( + vtkCompositePainter::DISPLAY_ATTRIBUTES(), + this->CompositeAttributes); +} + //---------------------------------------------------------------------------- void vtkCompositePolyDataMapper2::PrintSelf(ostream& os, vtkIndent indent) { diff --git a/Rendering/Core/vtkCompositePolyDataMapper2.h b/Rendering/Core/vtkCompositePolyDataMapper2.h index 4278c440e89..4d7d5017cfb 100644 --- a/Rendering/Core/vtkCompositePolyDataMapper2.h +++ b/Rendering/Core/vtkCompositePolyDataMapper2.h @@ -61,10 +61,22 @@ public: // Description: // Set/get the color for a block given its flat index. void SetBlockColor(unsigned int index, double color[3]); + void SetBlockColor(unsigned int index, double r, double g, double b) + { + double color[3] = {r, g, b}; + this->SetBlockColor(index, color); + } double* GetBlockColor(unsigned int index); void RemoveBlockColor(unsigned int index); void RemoveBlockColors(); + // Description: + // Set/get the opacity for a block given its flat index. + void SetBlockOpacity(unsigned int index, double opacity); + double GetBlockOpacity(unsigned int index); + void RemoveBlockOpacity(unsigned int index); + void RemoveBlockOpacities(); + //BTX protected: vtkCompositePolyDataMapper2(); @@ -84,6 +96,11 @@ protected: // Need to loop over the hierarchy to compute bounds virtual void ComputeBounds(); + // Description: + // Called when the PainterInformation becomes obsolete. Overridden to pass + // CompositeDataDisplayAttributes to the painters. + virtual void UpdatePainterInformation(); + // Description: // Time stamp for computation of bounds. vtkTimeStamp BoundsMTime; diff --git a/Rendering/Core/vtkPainter.cxx b/Rendering/Core/vtkPainter.cxx index 38ed028ef59..0c62da9cf14 100644 --- a/Rendering/Core/vtkPainter.cxx +++ b/Rendering/Core/vtkPainter.cxx @@ -26,7 +26,6 @@ #include "vtkCellData.h" #include "vtkCommand.h" -#include "vtkCompositeDataDisplayAttributes.h" #include "vtkDataSet.h" #include "vtkDebugLeaks.h" #include "vtkGarbageCollector.h" @@ -40,7 +39,6 @@ vtkCxxSetObjectMacro(vtkPainter, Input, vtkDataObject); vtkCxxSetObjectMacro(vtkPainter, Information, vtkInformation); -vtkCxxSetObjectMacro(vtkPainter, CompositeDataDisplayAttributes, vtkCompositeDataDisplayAttributes) vtkInformationKeyMacro(vtkPainter, STATIC_DATA, Integer); vtkInformationKeyMacro(vtkPainter, CONSERVE_MEMORY, Integer); vtkInformationKeyMacro(vtkPainter, HIGH_QUALITY, Integer); @@ -89,8 +87,6 @@ vtkPainter::vtkPainter() vtkPainter::STATIC_DATA()->Set(this->Information, 0); vtkPainter::CONSERVE_MEMORY()->Set(this->Information, 0); vtkPainter::HIGH_QUALITY()->Set(this->Information, 1); - - this->CompositeDataDisplayAttributes = 0; } //----------------------------------------------------------------------------- @@ -110,8 +106,6 @@ vtkPainter::~vtkPainter() } this->Timer->Delete(); - - this->SetCompositeDataDisplayAttributes(0); } //----------------------------------------------------------------------------- @@ -372,15 +366,4 @@ void vtkPainter::PrintSelf(ostream &os, vtkIndent indent) { os << "(none)" << endl; } - - os << indent << "CompositeDataDisplayAttributes: " ; - if (this->CompositeDataDisplayAttributes) - { - os << endl; - this->CompositeDataDisplayAttributes->PrintSelf(os, indent.GetNextIndent()); - } - else - { - os << "(none)" << endl; - } } diff --git a/Rendering/Core/vtkPainter.h b/Rendering/Core/vtkPainter.h index 5a11cca15a6..e35459532da 100644 --- a/Rendering/Core/vtkPainter.h +++ b/Rendering/Core/vtkPainter.h @@ -46,7 +46,6 @@ class vtkAbstractArray; class vtkActor; -class vtkCompositeDataDisplayAttributes; class vtkDataObject; class vtkDataSet; class vtkInformation; @@ -151,13 +150,6 @@ public: virtual vtkDataObject* GetOutput() { return this->Input; } - // Description: - // Set/get the composite data set display attributes. If set, these attributes - // can be used by the painter to control specific rendering attributes on a - // per-block basis for a multi-block dataset. - void SetCompositeDataDisplayAttributes(vtkCompositeDataDisplayAttributes *attributes); - vtkGetObjectMacro(CompositeDataDisplayAttributes, vtkCompositeDataDisplayAttributes) - //BTX protected: vtkPainter(); @@ -246,7 +238,6 @@ protected: double TimeToDraw; vtkTimerLog* Timer; - vtkCompositeDataDisplayAttributes *CompositeDataDisplayAttributes; vtkWeakPointer<vtkWindow> LastWindow; // Window used for previous render. // This is not reference counted. diff --git a/Rendering/Core/vtkPainterDeviceAdapter.cxx b/Rendering/Core/vtkPainterDeviceAdapter.cxx index b78a186e9c7..7094b70a625 100644 --- a/Rendering/Core/vtkPainterDeviceAdapter.cxx +++ b/Rendering/Core/vtkPainterDeviceAdapter.cxx @@ -38,17 +38,6 @@ vtkPainterDeviceAdapter::~vtkPainterDeviceAdapter() { } -//----------------------------------------------------------------------------- -void vtkPainterDeviceAdapter::SendMaterialProperties(int, - int, - const void*, - const void*, - const void*, - const void*) -{ - // should be implemented by subclasses -} - //----------------------------------------------------------------------------- void vtkPainterDeviceAdapter::PrintSelf(ostream &os, vtkIndent indent) { diff --git a/Rendering/Core/vtkPainterDeviceAdapter.h b/Rendering/Core/vtkPainterDeviceAdapter.h index 0be5bb6c60f..18da12c5481 100644 --- a/Rendering/Core/vtkPainterDeviceAdapter.h +++ b/Rendering/Core/vtkPainterDeviceAdapter.h @@ -96,15 +96,6 @@ public: virtual void SendAttribute(int index, int components, int type, const void *attribute, vtkIdType offset=0) = 0; - // Description: - // Sends material properties to the graphics card. - virtual void SendMaterialProperties(int components, - int type, - const void *ambient, - const void *diffuse, - const void *specular, - const void *specular_power); - // Description: // Sets an array of attributes. This allows you to send all the data for // a particular attribute with one call, thus greatly reducing function diff --git a/Rendering/Core/vtkProperty.cxx b/Rendering/Core/vtkProperty.cxx index 3a6d1a744e2..67b3d9b7689 100644 --- a/Rendering/Core/vtkProperty.cxx +++ b/Rendering/Core/vtkProperty.cxx @@ -279,24 +279,34 @@ void vtkProperty::SetColor(double r, double g, double b) } //---------------------------------------------------------------------------- -// Return composite color of object (ambient + diffuse + specular). Return value -// is a pointer to rgb values. -double *vtkProperty::GetColor() +void vtkProperty::ComputeCompositeColor(double result[3], + double ambient, const double ambient_color[3], + double diffuse, const double diffuse_color[3], + double specular, const double specular_color[3]) { double norm = 0.0; - - if ((this->Ambient + this->Diffuse + this->Specular)>0) + if ((ambient + diffuse + specular)>0) { - norm = 1.0 / (this->Ambient + this->Diffuse + this->Specular); + norm = 1.0 / (ambient + diffuse + specular); } for (int i = 0; i < 3; i ++) { - this->Color[i] = this->AmbientColor[i] * this->Ambient * norm; - this->Color[i] = this->Color[i] + this->DiffuseColor[i] * this->Diffuse * norm; - this->Color[i] = this->Color[i] + this->SpecularColor[i] * this->Specular * norm; + result[i] = ( ambient * ambient_color[i] + + diffuse * diffuse_color[i] + + specular * specular_color[i] ) * norm; } +} +//---------------------------------------------------------------------------- +// Return composite color of object (ambient + diffuse + specular). Return value +// is a pointer to rgb values. +double *vtkProperty::GetColor() +{ + vtkProperty::ComputeCompositeColor(this->Color, + this->Ambient, this->AmbientColor, + this->Diffuse, this->DiffuseColor, + this->Specular, this->SpecularColor); return this->Color; } @@ -904,17 +914,6 @@ void vtkProperty::PostRender(vtkActor* actor, vtkRenderer* renderer) } } -//---------------------------------------------------------------------------- -void vtkProperty::RenderMaterial(vtkActor *, - vtkRenderer *, - double *, - double *, - double *, - double) -{ - // should be implemented by subclasses -} - //---------------------------------------------------------------------------- void vtkProperty::AddShaderVariable(const char* name, int numVars, int* x) { diff --git a/Rendering/Core/vtkProperty.h b/Rendering/Core/vtkProperty.h index 09417bd91bf..efe6bce3180 100644 --- a/Rendering/Core/vtkProperty.h +++ b/Rendering/Core/vtkProperty.h @@ -92,18 +92,6 @@ public: virtual void PostRender(vtkActor*, vtkRenderer*); //ETX - // Description: - // Render the material for the face. This method should be implemented - // by subclasses. The default implementation does nothing. - // - // Warning: Experimental. This API may change in future releases. - virtual void RenderMaterial(vtkActor *actor, - vtkRenderer *renderer, - double *ambient, - double *diffuse, - double *specular, - double specular_power); - // Description: // Set/Get lighting flag for an object. Initial value is true. vtkGetMacro(Lighting, bool); @@ -390,6 +378,13 @@ protected: vtkProperty(); ~vtkProperty(); + // Description: + // Computes composite color. Used by GetColor(). + static void ComputeCompositeColor(double result[3], + double ambient, const double ambient_color[3], + double diffuse, const double diffuse_color[3], + double specular, const double specular_color[3]); + // Description: // Load property iVar values from the Material XML. void LoadProperty(); diff --git a/Rendering/OpenGL/CMakeLists.txt b/Rendering/OpenGL/CMakeLists.txt index 09ee6322544..c2ae0c03515 100644 --- a/Rendering/OpenGL/CMakeLists.txt +++ b/Rendering/OpenGL/CMakeLists.txt @@ -58,6 +58,7 @@ set(Module_SRCS vtkOpenGLCamera.cxx vtkOpenGLClipPlanesPainter.cxx vtkOpenGLCoincidentTopologyResolutionPainter.cxx + vtkOpenGLCompositePainter.cxx vtkOpenGLDisplayListPainter.cxx vtkOpenGLExtensionManager.cxx vtkOpenGLGL2PSHelper.cxx @@ -274,6 +275,7 @@ set(opengl_overrides Camera ClipPlanesPainter CoincidentTopologyResolutionPainter + CompositePainter DisplayListPainter Glyph3DMapper ImageSliceMapper diff --git a/Rendering/OpenGL/Testing/Cxx/CMakeLists.txt b/Rendering/OpenGL/Testing/Cxx/CMakeLists.txt index 629957e339e..d61e724c446 100644 --- a/Rendering/OpenGL/Testing/Cxx/CMakeLists.txt +++ b/Rendering/OpenGL/Testing/Cxx/CMakeLists.txt @@ -93,9 +93,10 @@ if(VTK_DATA_ROOT) set(RenderingTestsWithArguments ${RenderingTestsWithArguments} TestAreaSelections.cxx + TestGlyph3DMapperArrow.cxx + TestMultiblockDisplayProperties.cxx TestMultiTexturing.cxx TestMultiTexturingTransform.cxx - TestGlyph3DMapperArrow.cxx TestImageSliceMapperBorder.cxx TestImageResliceMapperBorder.cxx TestScalarBar.cxx diff --git a/Rendering/OpenGL/Testing/Cxx/TestMultiblockDisplayProperties.cxx b/Rendering/OpenGL/Testing/Cxx/TestMultiblockDisplayProperties.cxx new file mode 100644 index 00000000000..86cc96fe7be --- /dev/null +++ b/Rendering/OpenGL/Testing/Cxx/TestMultiblockDisplayProperties.cxx @@ -0,0 +1,103 @@ +/*========================================================================= + + Program: Visualization Toolkit + Module: TestMultiblockDisplayProperties.cxx + + 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. + +=========================================================================*/ +// This test tests setting up of display properties of individual blocks in +// composite datasets. + +#include "vtkActor.h" +#include "vtkCamera.h" +#include "vtkCompositeDataDisplayAttributes.h" +#include "vtkCompositePolyDataMapper2.h" +#include "vtkDataObject.h" +#include "vtkNew.h" +#include "vtkProperty.h" +#include "vtkRegressionTestImage.h" +#include "vtkRenderer.h" +#include "vtkRenderWindow.h" +#include "vtkRenderWindowInteractor.h" +#include "vtkTestUtilities.h" +#include "vtkXMLMultiBlockDataReader.h" + +int TestMultiblockDisplayProperties(int argc, char* argv[]) +{ + vtkNew<vtkXMLMultiBlockDataReader> reader; + char * fname = vtkTestUtilities::ExpandDataFileName( + argc, argv, "Data/many_blocks/many_blocks.vtm"); + reader->SetFileName(fname); + delete[] fname; + + vtkNew<vtkRenderWindow> renWin; + + vtkNew<vtkRenderWindowInteractor> iren; + iren->SetRenderWindow(renWin.GetPointer()); + + vtkNew<vtkRenderer> renderer; + renWin->AddRenderer(renderer.GetPointer()); + + vtkNew<vtkActor> actor; + renderer->AddActor(actor.GetPointer()); + + vtkNew<vtkCompositePolyDataMapper2> mapper; + mapper->SetInputConnection(reader->GetOutputPort()); + actor->SetMapper(mapper.GetPointer()); + + renWin->SetSize(400,400); + renderer->GetActiveCamera()->SetViewUp(0, 0, 1); + renderer->GetActiveCamera()->SetPosition(-1.3, 0, 1.7); + renderer->GetActiveCamera()->SetFocalPoint(0, 0, 1.6); + renderer->SetBackground(0.1,0.2,0.4); + renderer->ResetCamera(); + renWin->Render(); + + vtkNew<vtkCompositeDataDisplayAttributes> attributes; + mapper->SetCompositeDataDisplayAttributes(attributes.GetPointer()); + + mapper->SetBlockVisibility(1, 0); + mapper->SetBlockVisibility(23, 1); + mapper->SetBlockVisibility(27, 0); + mapper->SetBlockVisibility(29, 0); + renWin->Render(); + + mapper->RemoveBlockVisibility(29); + renWin->Render(); + + // Color "Group B" green. + mapper->SetBlockColor(67, 0, 0.33, 0.0); + renWin->Render(); + + // Show "Group ACAA" and color it yellow. + mapper->SetBlockVisibility(46, true); + mapper->SetBlockColor(46, 1, 1, 0.5); + renWin->Render(); + + // Set opacity on "Group AC" to 0.5 + mapper->SetBlockOpacity(34, 0.5); + renWin->Render(); + + // Change solid color. + actor->GetProperty()->SetColor(0.5, 0.1, 0.1); + renWin->Render(); + + // Remove all opacity overrides. + mapper->RemoveBlockOpacities(); + renWin->Render(); + + + int retVal = vtkRegressionTestImage(renWin.GetPointer()); + if (retVal == vtkRegressionTester::DO_INTERACTOR) + { + iren->Start(); + } + return !retVal; +} diff --git a/Rendering/OpenGL/vtkOpenGLCompositePainter.cxx b/Rendering/OpenGL/vtkOpenGLCompositePainter.cxx new file mode 100644 index 00000000000..f2ca91a7a2e --- /dev/null +++ b/Rendering/OpenGL/vtkOpenGLCompositePainter.cxx @@ -0,0 +1,117 @@ +/*========================================================================= + + Program: Visualization Toolkit + Module: vtkOpenGLCompositePainter.cxx + + 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. + +=========================================================================*/ +#include "vtkOpenGLCompositePainter.h" + +#include "vtkInformation.h" +#include "vtkObjectFactory.h" +#include "vtkOpenGL.h" +#include "vtkOpenGLProperty.h" +#include "vtkOpenGLRenderWindow.h" +#include "vtkPolyDataPainter.h" + +vtkStandardNewMacro(vtkOpenGLCompositePainter) + +//----------------------------------------------------------------------------- +vtkOpenGLCompositePainter::vtkOpenGLCompositePainter() +{ + this->PushedOpenGLAttribs = false; +} + +//----------------------------------------------------------------------------- +vtkOpenGLCompositePainter::~vtkOpenGLCompositePainter() +{ +} + +//----------------------------------------------------------------------------- +void vtkOpenGLCompositePainter::UpdateRenderingState( + vtkRenderWindow* window, vtkProperty* property, RenderBlockState& state) +{ + if (state.Opacity.top() == state.RenderedOpacity && + state.AmbientColor.top() == state.RenderedAmbientColor && + state.DiffuseColor.top() == state.RenderedDiffuseColor && + state.SpecularColor.top() == state.RenderedSpecularColor) + { + bool something_overridden = ( + state.Opacity.size() > 1 || state.AmbientColor.size() > 1 || + state.DiffuseColor.size() > 1 || state.SpecularColor.size() > 1); + if (something_overridden == this->PushedOpenGLAttribs) + { + // nothing to do. + return; + } + } + + state.RenderedOpacity = state.Opacity.top(); + state.RenderedAmbientColor = state.AmbientColor.top(); + state.RenderedDiffuseColor = state.DiffuseColor.top(); + state.RenderedSpecularColor = state.SpecularColor.top(); + + if (state.Opacity.size() == 1 && + state.AmbientColor.size() == 1 && + state.DiffuseColor.size() == 1 && + state.SpecularColor.size() == 1) + { + // We are returning to root state. + if (this->PushedOpenGLAttribs) + { + glPopAttrib(); + this->PushedOpenGLAttribs = false; + this->Information->Remove(vtkPolyDataPainter::DISABLE_SCALAR_COLOR()); + } + else + { + vtkWarningMacro("State mismatch. UpdateRenderingState() isn't being called " + "correctly."); + } + } + else + { + if (!this->PushedOpenGLAttribs) + { + this->PushedOpenGLAttribs = true; + glPushAttrib(GL_COLOR_BUFFER_BIT|GL_LIGHTING_BIT|GL_CURRENT_BIT|GL_ENABLE_BIT| + GL_TEXTURE_BIT); + + // disable state + glDisable(GL_ALPHA_TEST); + glDisable(GL_COLOR_MATERIAL); + glDisable(GL_TEXTURE_2D); + + // The following seems to overcome the color bleed when scalar coloring + // with point-data with InterpolateScalarsBeforeMapping ON. The real cause + // however, is some interactions with the depth-peeling code. + // That needs to tracked down, rather than just hacking the logic here. + // glBindTexture(GL_TEXTURE_2D, 0); + + this->Information->Set(vtkPolyDataPainter::DISABLE_SCALAR_COLOR(), 1); + } + + vtkOpenGLRenderWindow* windowGL = vtkOpenGLRenderWindow::SafeDownCast(window); + vtkOpenGLProperty::SetMaterialProperties( + static_cast<unsigned int>(GL_FRONT_AND_BACK), + property->GetAmbient(), state.RenderedAmbientColor.GetData(), + property->GetDiffuse(), state.RenderedDiffuseColor.GetData(), + property->GetSpecular(), state.RenderedSpecularColor.GetData(), + property->GetSpecularPower(), + state.RenderedOpacity, + windowGL); + } +} + +//----------------------------------------------------------------------------- +void vtkOpenGLCompositePainter::PrintSelf(ostream& os, vtkIndent indent) +{ + this->Superclass::PrintSelf(os, indent); +} diff --git a/Rendering/OpenGL/vtkOpenGLCompositePainter.h b/Rendering/OpenGL/vtkOpenGLCompositePainter.h new file mode 100644 index 00000000000..39ee5b32ef2 --- /dev/null +++ b/Rendering/OpenGL/vtkOpenGLCompositePainter.h @@ -0,0 +1,47 @@ +/*========================================================================= + + Program: Visualization Toolkit + Module: vtkOpenGLCompositePainter.h + + 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. + +=========================================================================*/ +// .NAME vtkOpenGLCompositePainter - composite painter for OpenGL. +// .SECTION Description + +#ifndef __vtkOpenGLCompositePainter_h +#define __vtkOpenGLCompositePainter_h + +#include "vtkRenderingOpenGLModule.h" // For export macro +#include "vtkCompositePainter.h" + +class VTKRENDERINGOPENGL_EXPORT vtkOpenGLCompositePainter : public vtkCompositePainter +{ +public: + static vtkOpenGLCompositePainter* New(); + vtkTypeMacro(vtkOpenGLCompositePainter, vtkCompositePainter); + void PrintSelf(ostream& os, vtkIndent indent); + +protected: + vtkOpenGLCompositePainter(); + ~vtkOpenGLCompositePainter(); + + // Description: + // Overridden in vtkOpenGLCompositePainter to pass attributes to OpenGL. + virtual void UpdateRenderingState( + vtkRenderWindow* window, vtkProperty* property, RenderBlockState& state); + +private: + vtkOpenGLCompositePainter(const vtkOpenGLCompositePainter&); // Not implemented. + void operator=(const vtkOpenGLCompositePainter&); // Not implemented. + + bool PushedOpenGLAttribs; +}; + +#endif diff --git a/Rendering/OpenGL/vtkOpenGLPainterDeviceAdapter.cxx b/Rendering/OpenGL/vtkOpenGLPainterDeviceAdapter.cxx index f6b80581582..9665177e850 100644 --- a/Rendering/OpenGL/vtkOpenGLPainterDeviceAdapter.cxx +++ b/Rendering/OpenGL/vtkOpenGLPainterDeviceAdapter.cxx @@ -644,134 +644,6 @@ void vtkOpenGLPainterDeviceAdapter::SendMultiTextureCoords(int numcomp, } -//----------------------------------------------------------------------------- -void vtkOpenGLPainterDeviceAdapter::SendMaterialProperties(int components, - int type, - const void *ambient, - const void *diffuse, - const void *specular, - const void *specular_power) -{ - this->SendMaterialPropertiesForFace(GL_FRONT_AND_BACK, - components, - type, - ambient, - diffuse, - specular, - specular_power); -} - -//----------------------------------------------------------------------------- -void vtkOpenGLPainterDeviceAdapter::SendMaterialPropertiesForFace(unsigned int face, - int components, - int type, - const void *ambient, - const void *diffuse, - const void *specular, - const void *specular_power) -{ - if(!(components == 3 || components == 4)) - { - vtkErrorMacro("Bad number of components."); - return; - } - - switch(VTK2OpenGLType(type)) - { - case GL_FLOAT: - { - if(components == 3) - { - const GLfloat ambient4[] = { - static_cast<const GLfloat *>(ambient)[0], - static_cast<const GLfloat *>(ambient)[1], - static_cast<const GLfloat *>(ambient)[2], - static_cast<GLfloat>(1) - }; - glMaterialfv(face, GL_AMBIENT, ambient4); - - const GLfloat diffuse4[] = { - static_cast<const GLfloat *>(diffuse)[0], - static_cast<const GLfloat *>(diffuse)[1], - static_cast<const GLfloat *>(diffuse)[2], - static_cast<GLfloat>(1) - }; - glMaterialfv(face, GL_DIFFUSE, diffuse4); - - const GLfloat specular4[] = { - static_cast<const GLfloat *>(specular)[0], - static_cast<const GLfloat *>(specular)[1], - static_cast<const GLfloat *>(specular)[2], - static_cast<GLfloat>(1) - }; - glMaterialfv(face, GL_SPECULAR, specular4); - } - else if(components == 4) - { - glMaterialfv(face, GL_AMBIENT, static_cast<const GLfloat *>(ambient)); - glMaterialfv(face, GL_DIFFUSE, static_cast<const GLfloat *>(diffuse)); - glMaterialfv(face, GL_SPECULAR, static_cast<const GLfloat *>(specular)); - } - - if(specular_power) - { - glMaterialfv(face, GL_SHININESS, static_cast<const GLfloat *>(specular_power)); - } - } - break; - case GL_DOUBLE: - { - GLfloat ambient_alpha = 1.0f; - GLfloat diffuse_alpha = 1.0f; - GLfloat specular_alpha = 1.0f; - - if(components == 4) - { - ambient_alpha = - static_cast<GLfloat>(static_cast<const double *>(ambient)[3]); - diffuse_alpha = - static_cast<GLfloat>(static_cast<const double *>(ambient)[3]); - specular_alpha = - static_cast<GLfloat>(static_cast<const double *>(ambient)[3]); - } - - const GLfloat ambient4[] = { - static_cast<GLfloat>(static_cast<const double *>(ambient)[0]), - static_cast<GLfloat>(static_cast<const double *>(ambient)[1]), - static_cast<GLfloat>(static_cast<const double *>(ambient)[2]), - ambient_alpha - }; - glMaterialfv(face, GL_AMBIENT, ambient4); - - const GLfloat diffuse4[] = { - static_cast<GLfloat>(static_cast<const double *>(diffuse)[0]), - static_cast<GLfloat>(static_cast<const double *>(diffuse)[1]), - static_cast<GLfloat>(static_cast<const double *>(diffuse)[2]), - diffuse_alpha - }; - glMaterialfv(face, GL_DIFFUSE, diffuse4); - - const GLfloat specular4[] = { - static_cast<GLfloat>(static_cast<const double *>(specular)[0]), - static_cast<GLfloat>(static_cast<const double *>(specular)[1]), - static_cast<GLfloat>(static_cast<const double *>(specular)[2]), - specular_alpha - }; - glMaterialfv(face, GL_SPECULAR, specular4); - - if(specular_power) - { - GLfloat specular_power_float = - static_cast<GLfloat>(static_cast<const double *>(specular_power)[0]); - glMaterialfv(face, GL_SHININESS, &specular_power_float); - } - } - break; - default: - vtkErrorMacro("Unsupported type for material properties: " << type); - } -} - //----------------------------------------------------------------------------- void vtkOpenGLPainterDeviceAdapter::SetAttributePointer(int index, diff --git a/Rendering/OpenGL/vtkOpenGLPainterDeviceAdapter.h b/Rendering/OpenGL/vtkOpenGLPainterDeviceAdapter.h index dd82df69385..a147aa2ba58 100644 --- a/Rendering/OpenGL/vtkOpenGLPainterDeviceAdapter.h +++ b/Rendering/OpenGL/vtkOpenGLPainterDeviceAdapter.h @@ -81,26 +81,6 @@ public: virtual void SendMultiTextureCoords(int numcomp, int type, const void *attribute, int idx, vtkIdType offset); - // Description: - // Calls glMaterial*() for the GL_FRONT_AND_BACK face. - virtual void SendMaterialProperties(int components, - int type, - const void *ambient, - const void *diffuse, - const void *specular, - const void *specular_power); - - // Description: - // Calls glMaterial*() for a face (either GL_FRONT, GL_BACK, or - // GL_FRONT_AND_BACK). - void SendMaterialPropertiesForFace(unsigned int face, - int components, - int type, - const void *ambient, - const void *diffuse, - const void *specular, - const void *specular_power); - // Description: // Calls one of glVertexPointer, glNormalPointer, glColorPointer, or // glTexCoordPointer. diff --git a/Rendering/OpenGL/vtkOpenGLProperty.cxx b/Rendering/OpenGL/vtkOpenGLProperty.cxx index bf1366a31c1..4013288a85f 100644 --- a/Rendering/OpenGL/vtkOpenGLProperty.cxx +++ b/Rendering/OpenGL/vtkOpenGLProperty.cxx @@ -38,6 +38,24 @@ #include <assert.h> +namespace +{ + void ComputeMaterialColor(GLfloat result[4], + bool premultiply_colors_with_alpha, + double color_factor, + const double color[3], + double opacity) + { + double opacity_factor = premultiply_colors_with_alpha? opacity : 1.0; + for (int cc=0; cc < 3; cc++) + { + result[cc] = static_cast<GLfloat>( + opacity_factor * color_factor * color[cc]); + } + result[3] = opacity; + } +} + vtkStandardNewMacro(vtkOpenGLProperty); extern const char *vtkOpenGLPropertyDefaultMain_vs; @@ -160,19 +178,17 @@ void vtkOpenGLProperty::AddShaderVariable(const char *name, } // ---------------------------------------------------------------------------- -// Implement base class method. -void vtkOpenGLProperty::Render(vtkActor *anActor, - vtkRenderer *ren) +bool vtkOpenGLProperty::RenderShaders(vtkActor* vtkNotUsed(anActor), vtkRenderer* ren) { // unbind any textures for starters vtkOpenGLRenderer *oRenderer = static_cast<vtkOpenGLRenderer *>(ren); if (!oRenderer) { vtkErrorMacro("the vtkOpenGLProperty need a vtkOpenGLRenderer to render."); - return; + return false; } vtkOpenGLRenderWindow* context = vtkOpenGLRenderWindow::SafeDownCast( - oRenderer->GetRenderWindow()); + ren->GetRenderWindow()); vtkShaderProgram2* prog = oRenderer->GetShaderProgram(); if (prog) { @@ -402,87 +418,49 @@ void vtkOpenGLProperty::Render(vtkActor *anActor, } } - glDisable(GL_TEXTURE_2D); // fixed-pipeline + // Previous implementation of Render() used to test the prog variable to + // determine if new style texture was to be used. We are letting that logic + // be. + return (prog != NULL); +} - // disable alpha testing (this may have been enabled - // by another actor in OpenGLTexture) - glDisable (GL_ALPHA_TEST); +// ---------------------------------------------------------------------------- +// Implement base class method. +void vtkOpenGLProperty::Render(vtkActor *anActor, vtkRenderer *ren) +{ + bool rendered_shader_program2 = this->RenderShaders(anActor, ren); - glDisable(GL_COLOR_MATERIAL); // fixed-pipeline + vtkOpenGLRenderWindow* context = vtkOpenGLRenderWindow::SafeDownCast( + ren->GetRenderWindow()); - // turn on/off backface culling - if (! this->BackfaceCulling && ! this->FrontfaceCulling) - { - glDisable (GL_CULL_FACE); - glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); - } - else if (this->BackfaceCulling) + if (!context) { - glCullFace (GL_BACK); - glEnable (GL_CULL_FACE); - } - else //if both front & back culling on, will fall into backface culling - { //if you really want both front and back, use the Actor's visibility flag - glCullFace (GL_FRONT); - glEnable (GL_CULL_FACE); + // must be an OpenGL context. + return; } - // set front and backface material properties - this->RenderMaterialForFace(anActor, - ren, - this->AmbientColor, - this->DiffuseColor, - this->SpecularColor, - this->SpecularPower, - GL_FRONT_AND_BACK); - - GLenum method; // set interpolation switch (this->Interpolation) { - case VTK_FLAT: - method = GL_FLAT; - break; - case VTK_GOURAUD: - case VTK_PHONG: - method = GL_SMOOTH; - break; - default: - method = GL_SMOOTH; - break; + case VTK_FLAT: + glShadeModel(GL_FLAT); + break; + case VTK_GOURAUD: + case VTK_PHONG: + default: + glShadeModel(GL_SMOOTH); + break; } - glShadeModel(method); - - // The material properties set above are used if shading is - // enabled. This color set here is used if shading is - // disabled. Shading is disabled in the - // vtkOpenGLPolyDataMapper::Draw() method if points or lines - // are encountered without normals. - GLint alphaBits = context->GetAlphaBitPlanes(); - - // Dealing with having a correct alpha (none square) in the framebuffer - // is only required if there is an alpha component in the framebuffer - // (doh...) and if we cannot deal directly with BlendFuncSeparate. - double factor; - if(vtkgl::BlendFuncSeparate==0 && alphaBits>0) + if (this->Lighting) // fixed-pipeline { - factor = this->Opacity; + glEnable(GL_LIGHTING); } else { - factor = 1.; + glDisable(GL_LIGHTING); } - double color[4]; - this->GetColor(color); - color[0] *= factor; - color[1] *= factor; - color[2] *= factor; - color[3] = this->Opacity; - - glColor4dv(color); - // Set the PointSize glPointSize(this->PointSize); vtkOpenGLGL2PSHelper::SetPointSize(this->PointSize); @@ -509,20 +487,104 @@ void vtkOpenGLProperty::Render(vtkActor *anActor, vtkOpenGLGL2PSHelper::DisableStipple(); } - if (this->Lighting) // fixed-pipeline + glDisable(GL_TEXTURE_2D); // fixed-pipeline + + // disable alpha testing (this may have been enabled + // by another actor in OpenGLTexture) + glDisable (GL_ALPHA_TEST); + + glDisable(GL_COLOR_MATERIAL); // fixed-pipeline + + // turn on/off backface culling + if (! this->BackfaceCulling && ! this->FrontfaceCulling) { - glEnable(GL_LIGHTING); + glDisable (GL_CULL_FACE); + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); } - else + else if (this->BackfaceCulling) { - glDisable(GL_LIGHTING); + glCullFace (GL_BACK); + glEnable (GL_CULL_FACE); } + else //if both front & back culling on, will fall into backface culling + { //if you really want both front and back, use the Actor's visibility flag + glCullFace (GL_FRONT); + glEnable (GL_CULL_FACE); + } + + vtkOpenGLProperty::SetMaterialProperties( + static_cast<unsigned int>(GL_FRONT_AND_BACK), + this->Ambient, this->AmbientColor, + this->Diffuse, this->DiffuseColor, + this->Specular, this->SpecularColor, this->SpecularPower, + this->Opacity, context); + + this->RenderTextures(anActor, ren, rendered_shader_program2); + this->Superclass::Render(anActor, ren); +} + +//----------------------------------------------------------------------------- +void vtkOpenGLProperty::SetMaterialProperties( + unsigned int _face, + double ambient, const double ambient_color[3], + double diffuse, const double diffuse_color[3], + double specular, const double specular_color[3], double specular_power, + double opacity, vtkOpenGLRenderWindow* context) +{ + GLenum face = static_cast<GLenum>(_face); + + // Dealing with having a correct alpha (none square) in the framebuffer + // is only required if there is an alpha component in the framebuffer + // (doh...) and if we cannot deal directly with BlendFuncSeparate. + GLint alphaBits = context->GetAlphaBitPlanes(); + bool premultiply_colors_with_alpha = + (vtkgl::BlendFuncSeparate==0 && alphaBits>0); + + GLfloat ambientGL[4]; + ComputeMaterialColor(ambientGL, premultiply_colors_with_alpha, + ambient, ambient_color, opacity); + + GLfloat diffuseGL[4]; + ComputeMaterialColor(diffuseGL, premultiply_colors_with_alpha, + diffuse, diffuse_color, opacity); + + GLfloat specularGL[4]; + ComputeMaterialColor(specularGL, premultiply_colors_with_alpha, + specular, specular_color, opacity); + + glMaterialfv(face, GL_AMBIENT, ambientGL); + glMaterialfv(face, GL_DIFFUSE, diffuseGL); + glMaterialfv(face, GL_SPECULAR, specularGL); + glMaterialf(face, GL_SHININESS, static_cast<GLfloat>(specular_power)); + + // The material properties set above are used if shading is + // enabled. This color set here is used if shading is + // disabled. Shading is disabled in the + // vtkOpenGLPolyDataMapper::Draw() method if points or lines + // are encountered without normals. + double composite_color[3]; + vtkProperty::ComputeCompositeColor(composite_color, + ambient, ambient_color, diffuse, diffuse_color, specular, specular_color); + + GLfloat colorGL[4]; + ComputeMaterialColor(colorGL, premultiply_colors_with_alpha, + 1.0, composite_color, opacity); + glColor4fv(colorGL); +} + +//----------------------------------------------------------------------------- +bool vtkOpenGLProperty::RenderTextures(vtkActor*, vtkRenderer* ren, + bool rendered_shader_program2) +{ + vtkOpenGLRenderWindow* context = vtkOpenGLRenderWindow::SafeDownCast( + ren->GetRenderWindow()); + assert(context!=NULL); // render any textures. int numTextures = this->GetNumberOfTextures(); if (numTextures > 0) { - if (!prog) // fixed-pipeline multitexturing or old XML shaders. + if (!rendered_shader_program2) // fixed-pipeline multitexturing or old XML shaders. { this->LoadMultiTexturingExtensions(ren); if (vtkgl::ActiveTexture) @@ -562,7 +624,7 @@ void vtkOpenGLProperty::Render(vtkActor *anActor, if (unit == -1) { vtkErrorMacro(<<" not enough texture units."); - return; + return false; } this->SetTexture(unit,tex); vtkgl::ActiveTexture(vtkgl::TEXTURE0 + static_cast<GLenum>(unit)); @@ -572,88 +634,7 @@ void vtkOpenGLProperty::Render(vtkActor *anActor, vtkgl::ActiveTexture(vtkgl::TEXTURE0); } } - - this->Superclass::Render(anActor, ren); -} - -//----------------------------------------------------------------------------- -void vtkOpenGLProperty::RenderMaterial(vtkActor *actor, - vtkRenderer *renderer, - double *ambient, - double *diffuse, - double *specular, - double specular_power) -{ - this->RenderMaterialForFace(actor, - renderer, - ambient, - diffuse, - specular, - specular_power, - GL_FRONT_AND_BACK); -} - -//----------------------------------------------------------------------------- -void vtkOpenGLProperty::RenderMaterialForFace(vtkActor *, - vtkRenderer *renderer, - double *ambient, - double *diffuse, - double *specular, - double specular_power, - unsigned int face) -{ - // get opengl render window - vtkOpenGLRenderWindow *oglRenderWindow = - vtkOpenGLRenderWindow::SafeDownCast(renderer->GetRenderWindow()); - - // get opengl device adaptor - vtkOpenGLPainterDeviceAdapter *oglDeviceAdapter = - vtkOpenGLPainterDeviceAdapter::SafeDownCast(oglRenderWindow->GetPainterDeviceAdapter()); - - // calculate factor - double factor; - GLint alphaBits = oglRenderWindow->GetAlphaBitPlanes(); - - // Dealing with having a correct alpha (none square) in the framebuffer - // is only required if there is an alpha component in the framebuffer - // (doh...) and if we cannot deal directly with BlendFuncSeparate. - if (vtkgl::BlendFuncSeparate == 0 && alphaBits > 0) - { - factor = this->Opacity; - } - else - { - factor = 1.; - } - - GLfloat ambient4[4]; - GLfloat diffuse4[4]; - GLfloat specular4[4]; - - // set rgb components for colors - for (int i = 0; i < 3; i++) - { - ambient4[i] = static_cast<GLfloat>(factor * this->Ambient * ambient[i]); - diffuse4[i] = static_cast<GLfloat>(factor * this->Diffuse * diffuse[i]); - specular4[i] = static_cast<GLfloat>(factor * this->Specular * specular[i]); - } - - // set alpha component for colors - ambient4[3] = static_cast<GLfloat>(this->Opacity); - diffuse4[3] = static_cast<GLfloat>(this->Opacity); - specular4[3] = static_cast<GLfloat>(this->Opacity); - - // get shininess - GLfloat shininess = static_cast<GLfloat>(specular_power); - - // send materials - oglDeviceAdapter->SendMaterialPropertiesForFace(face, - 4, - VTK_FLOAT, - ambient4, - diffuse4, - specular4, - &shininess); + return (numTextures > 0); } //----------------------------------------------------------------------------- @@ -722,16 +703,16 @@ void vtkOpenGLProperty::PostRender(vtkActor *actor, vtkRenderer *renderer) //----------------------------------------------------------------------------- // Implement base class method. -void vtkOpenGLProperty::BackfaceRender(vtkActor *actor, vtkRenderer *renderer) +void vtkOpenGLProperty::BackfaceRender(vtkActor *vtkNotUsed(anActor), vtkRenderer *ren) { - // set backface material properties - this->RenderMaterialForFace(actor, - renderer, - this->AmbientColor, - this->DiffuseColor, - this->SpecularColor, - this->SpecularPower, - GL_BACK); + vtkOpenGLRenderWindow* context = vtkOpenGLRenderWindow::SafeDownCast( + ren->GetRenderWindow()); + vtkOpenGLProperty::SetMaterialProperties( + static_cast<unsigned int>(GL_BACK), + this->Ambient, this->AmbientColor, + this->Diffuse, this->DiffuseColor, + this->Specular, this->SpecularColor, this->SpecularPower, + this->Opacity, context); } //----------------------------------------------------------------------------- diff --git a/Rendering/OpenGL/vtkOpenGLProperty.h b/Rendering/OpenGL/vtkOpenGLProperty.h index 1288f91d728..f0d4d68ef32 100644 --- a/Rendering/OpenGL/vtkOpenGLProperty.h +++ b/Rendering/OpenGL/vtkOpenGLProperty.h @@ -23,12 +23,13 @@ #include "vtkRenderingOpenGLModule.h" // For export macro #include "vtkProperty.h" +class vtkGLSLShaderDeviceAdapter2; class vtkOpenGLRenderer; +class vtkOpenGLRenderWindow; class vtkShader2; class vtkShader2Collection; -class vtkShaderProgram2; class vtkShaderDeviceAdapter2; -class vtkGLSLShaderDeviceAdapter2; +class vtkShaderProgram2; class VTKRENDERINGOPENGL_EXPORT vtkOpenGLProperty : public vtkProperty { @@ -53,27 +54,6 @@ public: virtual void PostRender(vtkActor *a, vtkRenderer *r); - // Description: - // Render the material for the face. - virtual void RenderMaterial(vtkActor *actor, - vtkRenderer *renderer, - double *ambient, - double *diffuse, - double *specular, - double specular_power); - - // Description: - // Render the material for the face. Face can either be GL_FRONT, GL_BACK, or - // GL_FRONT_AND_BACK. The rest of the arguments are the same as for - // RenderMaterial(). - void RenderMaterialForFace(vtkActor *actor, - vtkRenderer *renderer, - double *ambient, - double *diffuse, - double *specular, - double specular_power, - unsigned int face); - // Description: // Release any graphics resources that are being consumed by this // property. The parameter window could be used to determine which graphic @@ -106,10 +86,30 @@ public: virtual void AddShaderVariable(const char *name, int numVars, float *x); virtual void AddShaderVariable(const char *name, int numVars, double *x); + // Description: + // Helper method to set OpenGL material properties. + static void SetMaterialProperties(unsigned int face, + double ambient, const double ambient_color[3], + double diffuse, const double diffuse_color[3], + double specular, const double specular_color[3], double specular_power, + double opacity, vtkOpenGLRenderWindow* context); + protected: vtkOpenGLProperty(); ~vtkOpenGLProperty(); + // Description: + // Method called in vtkOpenGLProperty::Render() to render shaders and/or + // related entities like shader variables. Returns true if any shaders were + // rendered. + bool RenderShaders(vtkActor* actor, vtkRenderer* renderer); + + // Description: + // Method called in vtkOpenGLProperty::Render() to render textures. + // Last argument is the value returned from RenderShaders() call. + bool RenderTextures(vtkActor* actor, vtkRenderer* renderer, + bool using_shader_program2); + // Description: // Load OpenGL extensions for multi texturing. void LoadMultiTexturingExtensions(vtkRenderer* ren); diff --git a/Rendering/OpenGL/vtkOpenGLScalarsToColorsPainter.cxx b/Rendering/OpenGL/vtkOpenGLScalarsToColorsPainter.cxx index 1762fff1f2b..ea5488c88e3 100644 --- a/Rendering/OpenGL/vtkOpenGLScalarsToColorsPainter.cxx +++ b/Rendering/OpenGL/vtkOpenGLScalarsToColorsPainter.cxx @@ -225,8 +225,8 @@ void vtkOpenGLScalarsToColorsPainter::RenderInternal(vtkRenderer *renderer, { // Turn on color sum and separate specular color so specular works // with texturing. - glEnable(vtkgl::COLOR_SUM); - glLightModeli(vtkgl::LIGHT_MODEL_COLOR_CONTROL, vtkgl::SEPARATE_SPECULAR_COLOR); + //glEnable(vtkgl::COLOR_SUM); + //glLightModeli(vtkgl::LIGHT_MODEL_COLOR_CONTROL, vtkgl::SEPARATE_SPECULAR_COLOR); } this->Superclass::RenderInternal(renderer, actor, typeflags, forceCompileOnly); -- GitLab