diff --git a/Interaction/Widgets/vtk.module b/Interaction/Widgets/vtk.module index 59b771d3624f3af292ae1024f152d3ca9f3520ab..4bfd44d354e39ac39a720ea4f28277d4e43dd6f1 100644 --- a/Interaction/Widgets/vtk.module +++ b/Interaction/Widgets/vtk.module @@ -42,7 +42,6 @@ PRIVATE_DEPENDS VTK::RenderingAnnotation VTK::RenderingFreeType VTK::RenderingVolume - VTK::RenderingOpenGL2 TEST_DEPENDS VTK::CommonComputationalGeometry diff --git a/Interaction/Widgets/vtk3DCursorRepresentation.cxx b/Interaction/Widgets/vtk3DCursorRepresentation.cxx index bc432583525889a9539a30e1a9b0a1478291e607..acdc10f520c34e3ab3ee327ffd63ac5d8dac9375 100644 --- a/Interaction/Widgets/vtk3DCursorRepresentation.cxx +++ b/Interaction/Widgets/vtk3DCursorRepresentation.cxx @@ -7,7 +7,6 @@ #include "vtkHardwarePicker.h" #include "vtkMath.h" #include "vtkObjectFactory.h" -#include "vtkOpenGLPolyDataMapper.h" #include "vtkPolyDataMapper.h" #include "vtkProperty.h" #include "vtkRenderer.h" @@ -178,7 +177,7 @@ void vtk3DCursorRepresentation::WidgetInteraction(double newEventPos[2]) cpdm->SetCellIdArrayName(nullptr); } } - else if (auto glMapper = vtkOpenGLPolyDataMapper::SafeDownCast(actor->GetMapper())) + else if (auto glMapper = vtkPolyDataMapper::SafeDownCast(actor->GetMapper())) { if (glMapper->GetPointIdArrayName()) { @@ -202,7 +201,7 @@ void vtk3DCursorRepresentation::WidgetInteraction(double newEventPos[2]) { cpdm->SetPointIdArrayName(item->second.c_str()); } - else if (auto glMapper = vtkOpenGLPolyDataMapper::SafeDownCast(item->first)) + else if (auto glMapper = vtkPolyDataMapper::SafeDownCast(item->first)) { glMapper->SetPointIdArrayName(item->second.c_str()); } @@ -213,7 +212,7 @@ void vtk3DCursorRepresentation::WidgetInteraction(double newEventPos[2]) { cpdm->SetCellIdArrayName(item->second.c_str()); } - else if (auto glMapper = vtkOpenGLPolyDataMapper::SafeDownCast(item->first)) + else if (auto glMapper = vtkPolyDataMapper::SafeDownCast(item->first)) { glMapper->SetCellIdArrayName(item->second.c_str()); } diff --git a/Rendering/Core/vtkCompositePolyDataMapper.cxx b/Rendering/Core/vtkCompositePolyDataMapper.cxx index 92d005293d08633c3ef40aef197089fbe66b9204..bd5ba2855769f7851634646117a6dda83b49a2b3 100644 --- a/Rendering/Core/vtkCompositePolyDataMapper.cxx +++ b/Rendering/Core/vtkCompositePolyDataMapper.cxx @@ -85,13 +85,7 @@ vtkCompositePolyDataMapper::vtkCompositePolyDataMapper() } //------------------------------------------------------------------------------ -vtkCompositePolyDataMapper::~vtkCompositePolyDataMapper() -{ - this->SetPointIdArrayName(nullptr); - this->SetCellIdArrayName(nullptr); - this->SetProcessIdArrayName(nullptr); - this->SetCompositeIdArrayName(nullptr); -} +vtkCompositePolyDataMapper::~vtkCompositePolyDataMapper() = default; //------------------------------------------------------------------------------ // Specify the type of data this mapper can handle. If we are @@ -175,10 +169,7 @@ void vtkCompositePolyDataMapper::ShallowCopy(vtkAbstractMapper* mapper) { this->SetCompositeDataDisplayAttributes(cpdm->GetCompositeDataDisplayAttributes()); this->SetColorMissingArraysWithNanColor(cpdm->GetColorMissingArraysWithNanColor()); - this->SetCellIdArrayName(cpdm->GetCellIdArrayName()); this->SetCompositeIdArrayName(cpdm->GetCompositeIdArrayName()); - this->SetPointIdArrayName(cpdm->GetPointIdArrayName()); - this->SetProcessIdArrayName(cpdm->GetProcessIdArrayName()); } // Now do superclass this->vtkPolyDataMapper::ShallowCopy(mapper); diff --git a/Rendering/Core/vtkCompositePolyDataMapper.h b/Rendering/Core/vtkCompositePolyDataMapper.h index 2252b2dbd139d5fa346ae673b471ba52febb32a0..8c3ad39a05e4f3112eebe1d00c144e59373a1362 100644 --- a/Rendering/Core/vtkCompositePolyDataMapper.h +++ b/Rendering/Core/vtkCompositePolyDataMapper.h @@ -236,45 +236,6 @@ public: */ vtkMTimeType GetMTime() override; - ///@{ - /** - * By default, this class uses the dataset's point and cell ids during - * rendering. However, one can override those by specifying cell and point - * data arrays to use instead. Currently, only vtkIdType array is supported. - * Set to NULL string (default) to use the point ids instead. - */ - vtkSetStringMacro(PointIdArrayName); - vtkGetStringMacro(PointIdArrayName); - vtkSetStringMacro(CellIdArrayName); - vtkGetStringMacro(CellIdArrayName); - ///@} - - ///@{ - /** - * If this class should override the process id using a data-array, - * set this variable to the name of the array to use. It must be a - * point-array. - * The array's DataType *MUST* be VTK_UNSIGNED_INT. - */ - vtkSetStringMacro(ProcessIdArrayName); - vtkGetStringMacro(ProcessIdArrayName); - ///@} - - ///@{ - /** - * Generally, this class can render the composite id when iterating - * over composite datasets. However in some cases (as in AMR), the rendered - * structure may not correspond to the input data, in which case we need - * to provide a cell array that can be used to render in the composite id in - * selection passes. Set to NULL (default) to not override the composite id - * color set by vtkCompositePainter if any. - * The array *MUST* be a cell array. - * The array's DataType *MUST* be VTK_UNSIGNED_INT. - */ - vtkSetStringMacro(CompositeIdArrayName); - vtkGetStringMacro(CompositeIdArrayName); - ///@} - protected: vtkCompositePolyDataMapper(); ~vtkCompositePolyDataMapper() override; @@ -364,12 +325,6 @@ protected: */ vtkTimeStamp BoundsMTime; - // additional picking indirection - char* PointIdArrayName = nullptr; - char* CellIdArrayName = nullptr; - char* ProcessIdArrayName = nullptr; - char* CompositeIdArrayName = nullptr; - vtkStateStorage TranslucentState; bool HasTranslucentGeometry = false; vtkStateStorage RenderValuesState; diff --git a/Rendering/Core/vtkPolyDataMapper.cxx b/Rendering/Core/vtkPolyDataMapper.cxx index 4aa767c0c8180035993493cf29165b217e99a875..9a93c2c1c8e463d4baf7153beb695118a460c307 100644 --- a/Rendering/Core/vtkPolyDataMapper.cxx +++ b/Rendering/Core/vtkPolyDataMapper.cxx @@ -25,6 +25,19 @@ vtkPolyDataMapper::vtkPolyDataMapper() this->SeamlessV = false; this->PauseShiftScale = false; this->ShiftScaleMethod = ShiftScaleMethodType::AUTO_SHIFT_SCALE; + this->SetPointIdArrayName(nullptr); + this->SetCellIdArrayName(nullptr); + this->SetCompositeIdArrayName(nullptr); + this->SetProcessIdArrayName(nullptr); +} + +//------------------------------------------------------------------------------ +vtkPolyDataMapper::~vtkPolyDataMapper() +{ + this->SetPointIdArrayName(nullptr); + this->SetCellIdArrayName(nullptr); + this->SetCompositeIdArrayName(nullptr); + this->SetProcessIdArrayName(nullptr); } //------------------------------------------------------------------------------ @@ -156,6 +169,9 @@ void vtkPolyDataMapper::ShallowCopy(vtkAbstractMapper* mapper) this->SetSeamlessV(m->GetSeamlessV()); this->SetVBOShiftScaleMethod(m->GetVBOShiftScaleMethod()); this->SetPauseShiftScale(m->GetPauseShiftScale()); + this->SetCellIdArrayName(m->GetCellIdArrayName()); + this->SetPointIdArrayName(m->GetPointIdArrayName()); + this->SetProcessIdArrayName(m->GetProcessIdArrayName()); } // Now do superclass diff --git a/Rendering/Core/vtkPolyDataMapper.h b/Rendering/Core/vtkPolyDataMapper.h index 0e31f9f3f066198136a7c6ccbb4e8edaa2406984..06b0869f2d5b8707a4db51afaee9385e84ad3451 100644 --- a/Rendering/Core/vtkPolyDataMapper.h +++ b/Rendering/Core/vtkPolyDataMapper.h @@ -107,6 +107,45 @@ public: vtkBooleanMacro(SeamlessV, bool); ///@} + ///@{ + /** + * By default, this class uses the dataset's point and cell ids during + * rendering. However, one can override those by specifying cell and point + * data arrays to use instead. Currently, only vtkIdType array is supported. + * Set to NULL string (default) to use the point ids instead. + */ + vtkSetStringMacro(PointIdArrayName); + vtkGetStringMacro(PointIdArrayName); + vtkSetStringMacro(CellIdArrayName); + vtkGetStringMacro(CellIdArrayName); + ///@} + + ///@{ + /** + * Generally, this class can render the composite id when iterating + * over composite datasets. However in some cases (as in AMR), the rendered + * structure may not correspond to the input data, in which case we need + * to provide a cell array that can be used to render in the composite id in + * selection passes. Set to NULL (default) to not override the composite id + * color set by vtkCompositePainter if any. + * The array *MUST* be a cell array. + * The array's DataType *MUST* be VTK_UNSIGNED_INT. + */ + vtkSetStringMacro(CompositeIdArrayName); + vtkGetStringMacro(CompositeIdArrayName); + ///@} + + ///@{ + /** + * If this class should override the process id using a data-array, + * set this variable to the name of the array to use. It must be a + * point-array. + * The array's DataType *MUST* be VTK_UNSIGNED_INT. + */ + vtkSetStringMacro(ProcessIdArrayName); + vtkGetStringMacro(ProcessIdArrayName); + ///@} + /** * Return bounding box (array of six doubles) of data expressed as * (xmin,xmax, ymin,ymax, zmin,zmax). @@ -213,7 +252,7 @@ public: protected: vtkPolyDataMapper(); - ~vtkPolyDataMapper() override = default; + ~vtkPolyDataMapper() override; /** * Called in GetBounds(). When this method is called, the consider the input @@ -230,6 +269,12 @@ protected: int ShiftScaleMethod; // for points bool PauseShiftScale; + // additional picking indirection + char* PointIdArrayName = nullptr; + char* CellIdArrayName = nullptr; + char* CompositeIdArrayName = nullptr; + char* ProcessIdArrayName = nullptr; + int FillInputPortInformation(int, vtkInformation*) override; private: diff --git a/Rendering/OpenGL2/vtkOpenGLLowMemoryBatchedPolyDataMapper.cxx b/Rendering/OpenGL2/vtkOpenGLLowMemoryBatchedPolyDataMapper.cxx index 86895396aee72cdcfd5cf98693b13aeba5333a79..aa86cf40e7ffdecb81be5e919fb696b0a99e83a7 100644 --- a/Rendering/OpenGL2/vtkOpenGLLowMemoryBatchedPolyDataMapper.cxx +++ b/Rendering/OpenGL2/vtkOpenGLLowMemoryBatchedPolyDataMapper.cxx @@ -451,9 +451,7 @@ void vtkOpenGLLowMemoryBatchedPolyDataMapper::ProcessCompositePixelBuffers(vtkHa if (sel->GetUseProcessIdFromData()) { - processArray = !this->ProcessIdArrayName.empty() - ? pd->GetArray(this->ProcessIdArrayName.c_str()) - : nullptr; + processArray = this->ProcessIdArrayName ? pd->GetArray(this->ProcessIdArrayName) : nullptr; } if (processdata && (processArray && processArray->GetDataType() == VTK_UNSIGNED_INT) && @@ -474,8 +472,8 @@ void vtkOpenGLLowMemoryBatchedPolyDataMapper::ProcessCompositePixelBuffers(vtkHa // do we need to do anything to the point id data? if (currPass == vtkHardwareSelector::POINT_ID_LOW24) { - vtkIdTypeArray* pointArrayId = !this->PointIdArrayName.empty() - ? vtkArrayDownCast<vtkIdTypeArray>(pd->GetArray(this->PointIdArrayName.c_str())) + vtkIdTypeArray* pointArrayId = this->PointIdArrayName + ? vtkArrayDownCast<vtkIdTypeArray>(pd->GetArray(this->PointIdArrayName)) : nullptr; // do we need to do anything to the point id data? @@ -517,8 +515,8 @@ void vtkOpenGLLowMemoryBatchedPolyDataMapper::ProcessCompositePixelBuffers(vtkHa if (currPass == vtkHardwareSelector::POINT_ID_HIGH24) { - vtkIdTypeArray* pointArrayId = !this->PointIdArrayName.empty() - ? vtkArrayDownCast<vtkIdTypeArray>(pd->GetArray(this->PointIdArrayName.c_str())) + vtkIdTypeArray* pointArrayId = this->PointIdArrayName + ? vtkArrayDownCast<vtkIdTypeArray>(pd->GetArray(this->PointIdArrayName)) : nullptr; // do we need to do anything to the point id data? @@ -557,9 +555,8 @@ void vtkOpenGLLowMemoryBatchedPolyDataMapper::ProcessCompositePixelBuffers(vtkHa { unsigned char* compositedata = sel->GetPixelBuffer(vtkHardwareSelector::COMPOSITE_INDEX_PASS); - vtkDataArray* compositeArray = !this->CompositeIdArrayName.empty() - ? cd->GetArray(this->CompositeIdArrayName.c_str()) - : nullptr; + vtkDataArray* compositeArray = + this->CompositeIdArrayName ? cd->GetArray(this->CompositeIdArrayName) : nullptr; if (compositedata && (compositeArray && compositeArray->GetDataType() == VTK_UNSIGNED_INT) && rawclowdata) @@ -578,8 +575,8 @@ void vtkOpenGLLowMemoryBatchedPolyDataMapper::ProcessCompositePixelBuffers(vtkHa if (currPass == vtkHardwareSelector::CELL_ID_LOW24) { - vtkIdTypeArray* cellArrayId = !this->CellIdArrayName.empty() - ? vtkArrayDownCast<vtkIdTypeArray>(cd->GetArray(this->CellIdArrayName.c_str())) + vtkIdTypeArray* cellArrayId = this->CellIdArrayName + ? vtkArrayDownCast<vtkIdTypeArray>(cd->GetArray(this->CellIdArrayName)) : nullptr; unsigned char* clowdata = sel->GetPixelBuffer(vtkHardwareSelector::CELL_ID_LOW24); bool hasHighCellIds = sel->HasHighCellIds(); @@ -620,8 +617,8 @@ void vtkOpenGLLowMemoryBatchedPolyDataMapper::ProcessCompositePixelBuffers(vtkHa if (currPass == vtkHardwareSelector::CELL_ID_HIGH24) { - vtkIdTypeArray* cellArrayId = !this->CellIdArrayName.empty() - ? vtkArrayDownCast<vtkIdTypeArray>(cd->GetArray(this->CellIdArrayName.c_str())) + vtkIdTypeArray* cellArrayId = this->CellIdArrayName + ? vtkArrayDownCast<vtkIdTypeArray>(cd->GetArray(this->CellIdArrayName)) : nullptr; unsigned char* chighdata = sel->GetPixelBuffer(vtkHardwareSelector::CELL_ID_HIGH24); diff --git a/Rendering/OpenGL2/vtkOpenGLLowMemoryPolyDataMapper.cxx b/Rendering/OpenGL2/vtkOpenGLLowMemoryPolyDataMapper.cxx index 75d4619048af1c54a0c9d99e895c1fd3932e8181..dfacbef2601ac7f72926b71d3a49e0cc985adb94 100644 --- a/Rendering/OpenGL2/vtkOpenGLLowMemoryPolyDataMapper.cxx +++ b/Rendering/OpenGL2/vtkOpenGLLowMemoryPolyDataMapper.cxx @@ -2764,9 +2764,7 @@ void vtkOpenGLLowMemoryPolyDataMapper::ProcessSelectorPixelBuffers( if (sel->GetUseProcessIdFromData()) { - processArray = !this->ProcessIdArrayName.empty() - ? pd->GetArray(this->ProcessIdArrayName.c_str()) - : nullptr; + processArray = this->ProcessIdArrayName ? pd->GetArray(this->ProcessIdArrayName) : nullptr; } // do we need to do anything to the process pass data? @@ -2788,8 +2786,8 @@ void vtkOpenGLLowMemoryPolyDataMapper::ProcessSelectorPixelBuffers( if (currPass == vtkHardwareSelector::POINT_ID_LOW24) { - vtkIdTypeArray* pointArrayId = !this->PointIdArrayName.empty() - ? vtkArrayDownCast<vtkIdTypeArray>(pd->GetArray(this->PointIdArrayName.c_str())) + vtkIdTypeArray* pointArrayId = this->PointIdArrayName + ? vtkArrayDownCast<vtkIdTypeArray>(pd->GetArray(this->PointIdArrayName)) : nullptr; // do we need to do anything to the point id data? @@ -2820,8 +2818,8 @@ void vtkOpenGLLowMemoryPolyDataMapper::ProcessSelectorPixelBuffers( if (currPass == vtkHardwareSelector::POINT_ID_HIGH24) { - vtkIdTypeArray* pointArrayId = !this->PointIdArrayName.empty() - ? vtkArrayDownCast<vtkIdTypeArray>(pd->GetArray(this->PointIdArrayName.c_str())) + vtkIdTypeArray* pointArrayId = this->PointIdArrayName + ? vtkArrayDownCast<vtkIdTypeArray>(pd->GetArray(this->PointIdArrayName)) : nullptr; // do we need to do anything to the point id data? @@ -2855,9 +2853,8 @@ void vtkOpenGLLowMemoryPolyDataMapper::ProcessSelectorPixelBuffers( { unsigned char* compositedata = sel->GetPixelBuffer(vtkHardwareSelector::COMPOSITE_INDEX_PASS); - vtkDataArray* compositeArray = !this->CompositeIdArrayName.empty() - ? cd->GetArray(this->CompositeIdArrayName.c_str()) - : nullptr; + vtkDataArray* compositeArray = + this->CompositeIdArrayName ? cd->GetArray(this->CompositeIdArrayName) : nullptr; if (compositedata && (compositeArray && compositeArray->GetDataType() == VTK_UNSIGNED_INT) && rawclowdata) @@ -2877,8 +2874,8 @@ void vtkOpenGLLowMemoryPolyDataMapper::ProcessSelectorPixelBuffers( // process the cellid array? if (currPass == vtkHardwareSelector::CELL_ID_LOW24) { - vtkIdTypeArray* cellArrayId = !this->CellIdArrayName.empty() - ? vtkArrayDownCast<vtkIdTypeArray>(cd->GetArray(this->CellIdArrayName.c_str())) + vtkIdTypeArray* cellArrayId = this->CellIdArrayName + ? vtkArrayDownCast<vtkIdTypeArray>(cd->GetArray(this->CellIdArrayName)) : nullptr; unsigned char* clowdata = sel->GetPixelBuffer(vtkHardwareSelector::CELL_ID_LOW24); @@ -2911,8 +2908,8 @@ void vtkOpenGLLowMemoryPolyDataMapper::ProcessSelectorPixelBuffers( if (currPass == vtkHardwareSelector::CELL_ID_HIGH24) { - vtkIdTypeArray* cellArrayId = !this->CellIdArrayName.empty() - ? vtkArrayDownCast<vtkIdTypeArray>(cd->GetArray(this->CellIdArrayName.c_str())) + vtkIdTypeArray* cellArrayId = this->CellIdArrayName + ? vtkArrayDownCast<vtkIdTypeArray>(cd->GetArray(this->CellIdArrayName)) : nullptr; unsigned char* chighdata = sel->GetPixelBuffer(vtkHardwareSelector::CELL_ID_HIGH24); @@ -2955,9 +2952,8 @@ void vtkOpenGLLowMemoryPolyDataMapper::UpdateMaximumPointCellIds(vtkRenderer* re vtkIdType maxPointId = mesh->GetPoints()->GetNumberOfPoints() - 1; if (mesh && mesh->GetPointData()) { - vtkIdTypeArray* pointArrayId = !this->PointIdArrayName.empty() - ? vtkArrayDownCast<vtkIdTypeArray>( - mesh->GetPointData()->GetArray(this->PointIdArrayName.c_str())) + vtkIdTypeArray* pointArrayId = this->PointIdArrayName + ? vtkArrayDownCast<vtkIdTypeArray>(mesh->GetPointData()->GetArray(this->PointIdArrayName)) : nullptr; if (pointArrayId) { @@ -2973,9 +2969,8 @@ void vtkOpenGLLowMemoryPolyDataMapper::UpdateMaximumPointCellIds(vtkRenderer* re vtkIdType maxCellId = mesh->GetNumberOfCells() - 1; if (mesh && mesh->GetCellData()) { - vtkIdTypeArray* cellArrayId = !this->CellIdArrayName.empty() - ? vtkArrayDownCast<vtkIdTypeArray>( - mesh->GetCellData()->GetArray(this->CellIdArrayName.c_str())) + vtkIdTypeArray* cellArrayId = this->CellIdArrayName + ? vtkArrayDownCast<vtkIdTypeArray>(mesh->GetCellData()->GetArray(this->CellIdArrayName)) : nullptr; if (cellArrayId) { diff --git a/Rendering/OpenGL2/vtkOpenGLLowMemoryPolyDataMapper.h b/Rendering/OpenGL2/vtkOpenGLLowMemoryPolyDataMapper.h index 9525e742e1a22e7cdd7565a742cfa1e17be8a301..32d5b29a90898437d17ecd0ad066fa03d8805c05 100644 --- a/Rendering/OpenGL2/vtkOpenGLLowMemoryPolyDataMapper.h +++ b/Rendering/OpenGL2/vtkOpenGLLowMemoryPolyDataMapper.h @@ -78,45 +78,6 @@ public: */ bool GetSupportsSelection() override { return true; } - ///@{ - /** - * By default, this class uses the dataset's point and cell ids during - * rendering. However, one can override those by specifying cell and point - * data arrays to use instead. Currently, only vtkIdType array is supported. - * Set to NULL string (default) to use the point ids instead. - */ - vtkSetStdStringFromCharMacro(PointIdArrayName); - vtkGetCharFromStdStringMacro(PointIdArrayName); - vtkSetStdStringFromCharMacro(CellIdArrayName); - vtkGetCharFromStdStringMacro(CellIdArrayName); - ///@} - - ///@{ - /** - * If this class should override the process id using a data-array, - * set this variable to the name of the array to use. It must be a - * point-array. - * The array's DataType *MUST* be VTK_UNSIGNED_INT. - */ - vtkSetStdStringFromCharMacro(ProcessIdArrayName); - vtkGetCharFromStdStringMacro(ProcessIdArrayName); - ///@} - - ///@{ - /** - * Generally, this class can render the composite id when iterating - * over composite datasets. However in some cases (as in AMR), the rendered - * structure may not correspond to the input data, in which case we need - * to provide a cell array that can be used to render in the composite id in - * selection passes. Set to NULL (default) to not override the composite id - * color set by vtkCompositePainter if any. - * The array *MUST* be a cell array. - * The array's DataType *MUST* be VTK_UNSIGNED_INT. - */ - vtkSetStdStringFromCharMacro(CompositeIdArrayName); - vtkGetCharFromStdStringMacro(CompositeIdArrayName); - ///@} - /// If you removed all mods, call this to go back to default setting. virtual void ResetModsToDefault(); void AddMod(const std::string& className); @@ -342,11 +303,6 @@ protected: /// @name Selection data bool PopulateSelectionSettings = true; bool PointPicking = false; - // additional picking indirection - std::string PointIdArrayName; - std::string CellIdArrayName; - std::string ProcessIdArrayName; - std::string CompositeIdArrayName; /// @name Cached PBR information bool HasAnisotropy = false; diff --git a/Rendering/OpenGL2/vtkOpenGLPolyDataMapper.cxx b/Rendering/OpenGL2/vtkOpenGLPolyDataMapper.cxx index 8f31a36c14f7e24d65866768443730dbf289d362..cc0c5de95e0902d9a61e22c1c7f3aed5bc718985 100644 --- a/Rendering/OpenGL2/vtkOpenGLPolyDataMapper.cxx +++ b/Rendering/OpenGL2/vtkOpenGLPolyDataMapper.cxx @@ -177,10 +177,6 @@ vtkOpenGLPolyDataMapper::~vtkOpenGLPolyDataMapper() this->CellNormalBuffer = nullptr; } - this->SetPointIdArrayName(nullptr); - this->SetCellIdArrayName(nullptr); - this->SetProcessIdArrayName(nullptr); - this->SetCompositeIdArrayName(nullptr); this->VBOs->Delete(); this->VBOs = nullptr; diff --git a/Rendering/OpenGL2/vtkOpenGLPolyDataMapper.h b/Rendering/OpenGL2/vtkOpenGLPolyDataMapper.h index ef3c5280e60ba4654bd1f51e1321f82218c35b6e..711e3c9a60f9ab76a63cc7e270484510ba08f6c8 100644 --- a/Rendering/OpenGL2/vtkOpenGLPolyDataMapper.h +++ b/Rendering/OpenGL2/vtkOpenGLPolyDataMapper.h @@ -93,45 +93,6 @@ public: // other polydata (not the input) vtkPolyData* CurrentInput; - ///@{ - /** - * By default, this class uses the dataset's point and cell ids during - * rendering. However, one can override those by specifying cell and point - * data arrays to use instead. Currently, only vtkIdType array is supported. - * Set to NULL string (default) to use the point ids instead. - */ - vtkSetStringMacro(PointIdArrayName); - vtkGetStringMacro(PointIdArrayName); - vtkSetStringMacro(CellIdArrayName); - vtkGetStringMacro(CellIdArrayName); - ///@} - - ///@{ - /** - * If this class should override the process id using a data-array, - * set this variable to the name of the array to use. It must be a - * point-array. - * The array's DataType *MUST* be VTK_UNSIGNED_INT. - */ - vtkSetStringMacro(ProcessIdArrayName); - vtkGetStringMacro(ProcessIdArrayName); - ///@} - - ///@{ - /** - * Generally, this class can render the composite id when iterating - * over composite datasets. However in some cases (as in AMR), the rendered - * structure may not correspond to the input data, in which case we need - * to provide a cell array that can be used to render in the composite id in - * selection passes. Set to NULL (default) to not override the composite id - * color set by vtkCompositePainter if any. - * The array *MUST* be a cell array. - * The array's DataType *MUST* be VTK_UNSIGNED_INT. - */ - vtkSetStringMacro(CompositeIdArrayName); - vtkGetStringMacro(CompositeIdArrayName); - ///@} - /** * Make a shallow copy of this mapper. */ @@ -460,12 +421,6 @@ protected: std::vector<unsigned char> EdgeValues; virtual bool DrawingEdges(vtkRenderer*, vtkActor*); - // additional picking indirection - char* PointIdArrayName; - char* CellIdArrayName; - char* ProcessIdArrayName; - char* CompositeIdArrayName; - class ExtraAttributeValue { public: diff --git a/Rendering/WebGPU/Private/vtkWebGPURenderPassDescriptorInternals.cxx b/Rendering/WebGPU/Private/vtkWebGPURenderPassDescriptorInternals.cxx index 789ea8bfe7a60d2ce80795d0a263d4f9f6f4af5d..aa6d8d738bae8e6d20651681a5e56256e7f990c2 100644 --- a/Rendering/WebGPU/Private/vtkWebGPURenderPassDescriptorInternals.cxx +++ b/Rendering/WebGPU/Private/vtkWebGPURenderPassDescriptorInternals.cxx @@ -9,21 +9,24 @@ vtkWebGPURenderPassDescriptorInternals::~vtkWebGPURenderPassDescriptorInternals( //------------------------------------------------------------------------------ vtkWebGPURenderPassDescriptorInternals::vtkWebGPURenderPassDescriptorInternals( const std::vector<wgpu::TextureView>& colorAttachmentInfo, - wgpu::TextureView depthStencil /*= wgpu::TextureView()*/, bool doClear /*= true*/) + wgpu::TextureView depthStencil /*= wgpu::TextureView()*/, bool clearColor /*= true*/, + bool clearDepth /*= true*/, bool clearStencil /*= true*/) { - wgpu::LoadOp loadOp = doClear ? wgpu::LoadOp::Clear : wgpu::LoadOp::Load; + const wgpu::LoadOp colorLoadOp = clearColor ? wgpu::LoadOp::Clear : wgpu::LoadOp::Load; for (uint32_t i = 0; i < kMaxColorAttachments; ++i) { - this->ColorAttachments[i].loadOp = loadOp; + this->ColorAttachments[i].loadOp = colorLoadOp; this->ColorAttachments[i].storeOp = wgpu::StoreOp::Store; this->ColorAttachments[i].clearValue = { 0.0f, 0.0f, 0.0f, 0.0f }; } + const wgpu::LoadOp depthLoadOp = clearDepth ? wgpu::LoadOp::Clear : wgpu::LoadOp::Load; + const wgpu::LoadOp stencilLoadOp = clearStencil ? wgpu::LoadOp::Clear : wgpu::LoadOp::Load; this->DepthStencilAttachmentInfo.depthClearValue = 1.0f; this->DepthStencilAttachmentInfo.stencilClearValue = 0; - this->DepthStencilAttachmentInfo.depthLoadOp = loadOp; + this->DepthStencilAttachmentInfo.depthLoadOp = depthLoadOp; this->DepthStencilAttachmentInfo.depthStoreOp = wgpu::StoreOp::Store; - this->DepthStencilAttachmentInfo.stencilLoadOp = loadOp; + this->DepthStencilAttachmentInfo.stencilLoadOp = stencilLoadOp; this->DepthStencilAttachmentInfo.stencilStoreOp = wgpu::StoreOp::Store; colorAttachmentCount = static_cast<uint32_t>(colorAttachmentInfo.size()); diff --git a/Rendering/WebGPU/Private/vtkWebGPURenderPassDescriptorInternals.h b/Rendering/WebGPU/Private/vtkWebGPURenderPassDescriptorInternals.h index 428ed8d0b9d8168a29c88eb992d5c3e251edf074..6915ffdb6f4a9268b25c9be6c93ad107bc796a00 100644 --- a/Rendering/WebGPU/Private/vtkWebGPURenderPassDescriptorInternals.h +++ b/Rendering/WebGPU/Private/vtkWebGPURenderPassDescriptorInternals.h @@ -16,7 +16,8 @@ class VTKRENDERINGWEBGPU_NO_EXPORT vtkWebGPURenderPassDescriptorInternals public: static constexpr int kMaxColorAttachments = 8u; vtkWebGPURenderPassDescriptorInternals(const std::vector<wgpu::TextureView>& colorAttachmentInfo, - wgpu::TextureView depthStencil = wgpu::TextureView(), bool doClear = true); + wgpu::TextureView depthStencil = wgpu::TextureView(), bool clearColor = true, + bool clearDepth = true, bool clearStencil = true); ~vtkWebGPURenderPassDescriptorInternals(); vtkWebGPURenderPassDescriptorInternals( diff --git a/Rendering/WebGPU/Testing/Cxx/CMakeLists.txt b/Rendering/WebGPU/Testing/Cxx/CMakeLists.txt index 8c4eccbbb5bf03a278c5c57b75b911173aa86086..378ba559e96913e8a0a23e106182f5ac3088016a 100644 --- a/Rendering/WebGPU/Testing/Cxx/CMakeLists.txt +++ b/Rendering/WebGPU/Testing/Cxx/CMakeLists.txt @@ -14,6 +14,7 @@ endif () # (vtk/vtk#19322): Add baselines for these unit tests vtk_add_test_cxx(vtkRenderingWebGPUCxxTests tests TestActorFaceCullingProperty.cxx,NO_DATA + TestAxesActor.cxx,NO_DATA TestCellScalarMappedColors.cxx,NO_DATA TestCompositePolyDataMapper.cxx,NO_DATA TestComputeDoublePipelineRenderBuffer.cxx,NO_DATA @@ -34,7 +35,12 @@ vtk_add_test_cxx(vtkRenderingWebGPUCxxTests tests TestComputeTexture.cxx,NO_DATA,NO_VALID TestLineRendering.cxx,NO_DATA TestLowPowerRenderWindow.cxx,NO_DATA - TestManyActorsOneMapper.cxx,NO_DATA,NO_VALID + TestNActorsNMappersOneInput.cxx,NO_DATA + TestNActorsOneMapper.cxx,NO_DATA + TestNViewportsNActorsNMappersNInputs.cxx,NO_DATA + TestNViewportsNActorsNMappersOneInput.cxx,NO_DATA + TestNViewportsNActorsOneMapper.cxx,NO_DATA + TestNViewportsOneActor.cxx,NO_DATA TestPointScalarMappedColors.cxx,NO_DATA TestReadPixels.cxx,NO_DATA,NO_VALID TestRenderPointsAsSpheres.cxx,NO_DATA diff --git a/Rendering/WebGPU/Testing/Cxx/TestAxesActor.cxx b/Rendering/WebGPU/Testing/Cxx/TestAxesActor.cxx new file mode 100644 index 0000000000000000000000000000000000000000..8467ec41c30bda48e1c945b96f09747e7a23427b --- /dev/null +++ b/Rendering/WebGPU/Testing/Cxx/TestAxesActor.cxx @@ -0,0 +1,65 @@ +// SPDX-FileCopyrightText: Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen +// SPDX-License-Identifier: BSD-3-Clause + +#include "vtkActor.h" +#include "vtkAxesActor.h" +#include "vtkCamera.h" +#include "vtkConeSource.h" +#include "vtkNew.h" +#include "vtkOrientationMarkerWidget.h" +#include "vtkPolyDataMapper.h" +#include "vtkProperty.h" +#include "vtkRegressionTestImage.h" +#include "vtkRenderWindow.h" +#include "vtkRenderWindowInteractor.h" +#include "vtkRenderer.h" + +//------------------------------------------------------------------------------ +int TestAxesActor(int argc, char* argv[]) +{ + vtkNew<vtkRenderer> renderer; + renderer->SetBackground(0.1, 0.1, 0.1); + + vtkNew<vtkRenderWindow> renderWindow; + renderWindow->SetSize(800, 800); + renderWindow->AddRenderer(renderer); + + vtkNew<vtkRenderWindowInteractor> iren; + iren->SetRenderWindow(renderWindow); + + vtkNew<vtkConeSource> cone; + // map elevation output to graphics primitives. + vtkNew<vtkPolyDataMapper> mapper; + // mapper->SetLookupTable(lut); + mapper->SetInputConnection(cone->GetOutputPort()); + vtkNew<vtkActor> actor; + actor->SetMapper(mapper); + renderer->AddActor(actor); + + vtkNew<vtkAxesActor> axes; + axes->SetShaftTypeToCylinder(); + axes->SetNormalizedTipLength(0.4, 0.4, 0.4); + // FIXME: the vtkCaptionActor2D does not render text with webgpu. An override for + // vtkPolyDataMapper2D must be implemented in webgpu. + // https://gitlab.kitware.com/vtk/vtk/-/issues/19551 + axes->SetAxisLabels(false); + vtkNew<vtkOrientationMarkerWidget> om; + om->SetOrientationMarker(axes); + om->SetInteractor(iren); + om->EnabledOn(); + om->InteractiveOn(); + + renderer->ResetCamera(); + renderer->GetActiveCamera()->Azimuth(45); + renderer->GetActiveCamera()->Elevation(45); + renderer->GetActiveCamera()->OrthogonalizeViewUp(); + renderWindow->Render(); + + int retVal = vtkRegressionTestImageThreshold(renderWindow, 0.05); + if (retVal == vtkRegressionTester::DO_INTERACTOR) + { + iren->Start(); + } + + return !retVal; +} diff --git a/Rendering/WebGPU/Testing/Cxx/TestNActorsNMappersOneInput.cxx b/Rendering/WebGPU/Testing/Cxx/TestNActorsNMappersOneInput.cxx new file mode 100644 index 0000000000000000000000000000000000000000..bc570306cfaf2ee25e6b4c06c3bc91ced9dd39e7 --- /dev/null +++ b/Rendering/WebGPU/Testing/Cxx/TestNActorsNMappersOneInput.cxx @@ -0,0 +1,75 @@ +// SPDX-FileCopyrightText: Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen +// SPDX-License-Identifier: BSD-3-Clause +#include "vtkActor.h" +#include "vtkCamera.h" +#include "vtkConeSource.h" +#include "vtkInteractorStyleTrackballCamera.h" +#include "vtkNew.h" +#include "vtkPolyDataMapper.h" +#include "vtkProperty.h" +#include "vtkRegressionTestImage.h" +#include "vtkRenderWindow.h" +#include "vtkRenderWindowInteractor.h" +#include "vtkRenderer.h" + +// In this unit test, there are 4 actors, each connected to a mapper. All mappers share a common +// source. +int TestNActorsNMappersOneInput(int argc, char* argv[]) +{ + vtkNew<vtkRenderWindow> renWin; + renWin->SetWindowName(__func__); + renWin->SetSize(800, 800); + renWin->SetMultiSamples(0); + + vtkNew<vtkRenderer> renderer; + renderer->SetBackground(1.0, 1.0, 1.0); + renWin->AddRenderer(renderer); + + vtkNew<vtkConeSource> cone; + + double x = 0.0, y = 0.0, z = 0.0; + double spacingX = 2.0, spacingY = 2.0, spacingZ = 2.0; + for (int k = 0; k < 8; ++k) + { + for (int j = 0; j < 8; ++j) + { + for (int i = 0; i < 8; ++i) + { + x += spacingX; + vtkNew<vtkPolyDataMapper> mapper; + mapper->SetInputConnection(cone->GetOutputPort()); + vtkNew<vtkActor> actor; + actor->SetMapper(mapper); + mapper->Update(); + mapper->SetStatic(1); + actor->GetProperty()->SetEdgeVisibility(true); + actor->GetProperty()->SetLineWidth(2); + actor->GetProperty()->SetEdgeColor((8.0 - j) / 8.0, k / 16.0, i / 8.0); + actor->GetProperty()->SetDiffuseColor(i / 8.0, (8.0 - j) / 8.0, k / 16.0); + actor->SetPosition(x, y, z); + renderer->AddActor(actor); + } + x = 0.0; + y += spacingY; + } + y = 0.0; + z += spacingZ; + } + + renderer->ResetCamera(); + renWin->Render(); + + vtkNew<vtkRenderWindowInteractor> iren; + iren->SetRenderWindow(renWin); + vtkNew<vtkInteractorStyleTrackballCamera> style; + iren->SetInteractorStyle(style); + style->SetDefaultRenderer(renderer); + renWin->Render(); + + const int retVal = vtkRegressionTestImage(renWin); + if (retVal == vtkRegressionTester::DO_INTERACTOR) + { + iren->Start(); + } + return !retVal; +} diff --git a/Rendering/WebGPU/Testing/Cxx/TestManyActorsOneMapper.cxx b/Rendering/WebGPU/Testing/Cxx/TestNActorsOneMapper.cxx similarity index 83% rename from Rendering/WebGPU/Testing/Cxx/TestManyActorsOneMapper.cxx rename to Rendering/WebGPU/Testing/Cxx/TestNActorsOneMapper.cxx index 3a34225c7b663893c71897d3d93a48a8b6137e72..cafa9d68125048d350c8e6aa0ddaea3f4ed86fa4 100644 --- a/Rendering/WebGPU/Testing/Cxx/TestManyActorsOneMapper.cxx +++ b/Rendering/WebGPU/Testing/Cxx/TestNActorsOneMapper.cxx @@ -12,13 +12,16 @@ #include "vtkRenderWindowInteractor.h" #include "vtkRenderer.h" -int TestManyActorsOneMapper(int argc, char* argv[]) +// In this unit test, there are 4 actors. All share a common mapper. +int TestNActorsOneMapper(int argc, char* argv[]) { vtkNew<vtkRenderWindow> renWin; renWin->SetWindowName(__func__); + renWin->SetSize(800, 800); renWin->SetMultiSamples(0); vtkNew<vtkRenderer> renderer; + renderer->SetBackground(1.0, 1.0, 1.0); renWin->AddRenderer(renderer); vtkNew<vtkConeSource> cone; @@ -40,7 +43,8 @@ int TestManyActorsOneMapper(int argc, char* argv[]) mapper->SetStatic(1); actor->GetProperty()->SetEdgeVisibility(true); actor->GetProperty()->SetLineWidth(2); - actor->GetProperty()->SetEdgeColor(1.0, 0.0, 0.0); + actor->GetProperty()->SetEdgeColor((8.0 - j) / 8.0, k / 16.0, i / 8.0); + actor->GetProperty()->SetDiffuseColor(i / 8.0, (8.0 - j) / 8.0, k / 16.0); actor->SetPosition(x, y, z); renderer->AddActor(actor); } @@ -52,7 +56,6 @@ int TestManyActorsOneMapper(int argc, char* argv[]) } renderer->ResetCamera(); - renderer->SetBackground(0.1, 0.1, 0.1); renWin->Render(); vtkNew<vtkRenderWindowInteractor> iren; diff --git a/Rendering/WebGPU/Testing/Cxx/TestNViewportsNActorsNMappersNInputs.cxx b/Rendering/WebGPU/Testing/Cxx/TestNViewportsNActorsNMappersNInputs.cxx new file mode 100644 index 0000000000000000000000000000000000000000..51a237b0e59811a00645f6a354415cc07481f90f --- /dev/null +++ b/Rendering/WebGPU/Testing/Cxx/TestNViewportsNActorsNMappersNInputs.cxx @@ -0,0 +1,54 @@ +// SPDX-FileCopyrightText: Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen +// SPDX-License-Identifier: BSD-3-Clause + +#include "vtkActor.h" +#include "vtkCompositePolyDataMapper.h" +#include "vtkPartitionedDataSetCollectionSource.h" +#include "vtkProperty.h" +#include "vtkRegressionTestImage.h" +#include "vtkRenderWindow.h" +#include "vtkRenderWindowInteractor.h" +#include "vtkRenderer.h" +#include "vtkTesting.h" + +#include <cstdlib> + +// In this unit test, there are 4 viewports. Each viewport displays an actor +// that is connected to a mapper which is then connected to a partitioned dataset collection source +// which has as many shapes as the index of the mapper. +int TestNViewportsNActorsNMappersNInputs(int argc, char* argv[]) +{ + vtkNew<vtkRenderWindow> renderWindow; + vtkNew<vtkRenderWindowInteractor> interactor; + vtkNew<vtkRenderer> renderers[4]; + + double xmins[4] = { 0.0, 0.4, 0.0, 0.0 }; + double ymins[4] = { 0.0, 0.0, 0.25, 0.5 }; + double xmaxs[4] = { 0.4, 1.0, 1.0, 1.0 }; + double ymaxs[4] = { 0.25, 0.25, 0.5, 1.0 }; + for (int i = 0; i < 4; ++i) + { + auto ren = renderers[i].Get(); + vtkNew<vtkPartitionedDataSetCollectionSource> source; + source->SetNumberOfShapes(i + 1); // generates i + 1 shapes. + vtkNew<vtkCompositePolyDataMapper> mapper; + mapper->SetInputConnection(source->GetOutputPort()); + vtkNew<vtkActor> actor; + actor->SetMapper(mapper); + actor->GetProperty()->SetDiffuseColor(0.5, i / 4.0, (4.0 - i) / 4); + ren->AddActor(actor); + ren->SetBackground(i / 4.0, (4.0 - i) / 4, 1); + ren->SetViewport(xmins[i], ymins[i], xmaxs[i], ymaxs[i]); + renderWindow->AddRenderer(ren); + } + renderWindow->SetSize(800, 800); + renderWindow->SetInteractor(interactor); + interactor->Initialize(); + + const int retVal = vtkRegressionTestImage(renderWindow); + if (retVal == vtkRegressionTester::DO_INTERACTOR) + { + interactor->Start(); + } + return !retVal; +} diff --git a/Rendering/WebGPU/Testing/Cxx/TestNViewportsNActorsNMappersOneInput.cxx b/Rendering/WebGPU/Testing/Cxx/TestNViewportsNActorsNMappersOneInput.cxx new file mode 100644 index 0000000000000000000000000000000000000000..80f714224e5bff2772838d988d09eb85ca068242 --- /dev/null +++ b/Rendering/WebGPU/Testing/Cxx/TestNViewportsNActorsNMappersOneInput.cxx @@ -0,0 +1,52 @@ +// SPDX-FileCopyrightText: Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen +// SPDX-License-Identifier: BSD-3-Clause + +#include "vtkActor.h" +#include "vtkConeSource.h" +#include "vtkPolyDataMapper.h" +#include "vtkProperty.h" +#include "vtkRegressionTestImage.h" +#include "vtkRenderWindow.h" +#include "vtkRenderWindowInteractor.h" +#include "vtkRenderer.h" +#include "vtkTesting.h" + +#include <cstdlib> + +// In this unit test, there are 4 viewports. Each viewport displays an actor +// that is connected to a mapper. All mappers share a common cone source. +int TestNViewportsNActorsNMappersOneInput(int argc, char* argv[]) +{ + vtkNew<vtkRenderWindow> renderWindow; + vtkNew<vtkRenderWindowInteractor> interactor; + vtkNew<vtkRenderer> renderers[4]; + vtkNew<vtkConeSource> cone; + + double xmins[4] = { 0.0, 0.4, 0.0, 0.0 }; + double ymins[4] = { 0.0, 0.0, 0.25, 0.5 }; + double xmaxs[4] = { 0.4, 1.0, 1.0, 1.0 }; + double ymaxs[4] = { 0.25, 0.25, 0.5, 1.0 }; + for (int i = 0; i < 4; ++i) + { + auto ren = renderers[i].Get(); + vtkNew<vtkPolyDataMapper> mapper; + mapper->SetInputConnection(cone->GetOutputPort()); + vtkNew<vtkActor> actor; + actor->SetMapper(mapper); + actor->GetProperty()->SetDiffuseColor(0.5, i / 4.0, (4.0 - i) / 4); + ren->AddActor(actor); + ren->SetBackground(i / 4.0, (4.0 - i) / 4, 1); + ren->SetViewport(xmins[i], ymins[i], xmaxs[i], ymaxs[i]); + renderWindow->AddRenderer(ren); + } + renderWindow->SetSize(800, 800); + renderWindow->SetInteractor(interactor); + interactor->Initialize(); + + const int retVal = vtkRegressionTestImage(renderWindow); + if (retVal == vtkRegressionTester::DO_INTERACTOR) + { + interactor->Start(); + } + return !retVal; +} diff --git a/Rendering/WebGPU/Testing/Cxx/TestNViewportsNActorsOneMapper.cxx b/Rendering/WebGPU/Testing/Cxx/TestNViewportsNActorsOneMapper.cxx new file mode 100644 index 0000000000000000000000000000000000000000..ab6047fedc847f7bb6ad0c132a6e6583e29c16cd --- /dev/null +++ b/Rendering/WebGPU/Testing/Cxx/TestNViewportsNActorsOneMapper.cxx @@ -0,0 +1,52 @@ +// SPDX-FileCopyrightText: Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen +// SPDX-License-Identifier: BSD-3-Clause + +#include "vtkActor.h" +#include "vtkConeSource.h" +#include "vtkPolyDataMapper.h" +#include "vtkProperty.h" +#include "vtkRegressionTestImage.h" +#include "vtkRenderWindow.h" +#include "vtkRenderWindowInteractor.h" +#include "vtkRenderer.h" +#include "vtkTesting.h" + +#include <cstdlib> + +// In this unit test, there are 4 viewports. Each viewport displays an actor. +// All actors share a common mapper. +int TestNViewportsNActorsOneMapper(int argc, char* argv[]) +{ + vtkNew<vtkRenderWindow> renderWindow; + vtkNew<vtkRenderWindowInteractor> interactor; + vtkNew<vtkRenderer> renderers[4]; + vtkNew<vtkConeSource> cone; + vtkNew<vtkPolyDataMapper> mapper; + + mapper->SetInputConnection(cone->GetOutputPort()); + double xmins[4] = { 0.0, 0.4, 0.0, 0.0 }; + double ymins[4] = { 0.0, 0.0, 0.25, 0.5 }; + double xmaxs[4] = { 0.4, 1.0, 1.0, 1.0 }; + double ymaxs[4] = { 0.25, 0.25, 0.5, 1.0 }; + for (int i = 0; i < 4; ++i) + { + auto ren = renderers[i].Get(); + vtkNew<vtkActor> actor; + actor->SetMapper(mapper); + actor->GetProperty()->SetDiffuseColor(0.5, i / 4.0, (4.0 - i) / 4); + ren->AddActor(actor); + ren->SetBackground(i / 4.0, (4.0 - i) / 4, 1); + ren->SetViewport(xmins[i], ymins[i], xmaxs[i], ymaxs[i]); + renderWindow->AddRenderer(ren); + } + renderWindow->SetSize(800, 800); + renderWindow->SetInteractor(interactor); + interactor->Initialize(); + + const int retVal = vtkRegressionTestImage(renderWindow); + if (retVal == vtkRegressionTester::DO_INTERACTOR) + { + interactor->Start(); + } + return !retVal; +} diff --git a/Rendering/WebGPU/Testing/Cxx/TestNViewportsOneActor.cxx b/Rendering/WebGPU/Testing/Cxx/TestNViewportsOneActor.cxx new file mode 100644 index 0000000000000000000000000000000000000000..cfbcd581b273bbd9091d55d483ad9ff3611828c3 --- /dev/null +++ b/Rendering/WebGPU/Testing/Cxx/TestNViewportsOneActor.cxx @@ -0,0 +1,50 @@ +// SPDX-FileCopyrightText: Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen +// SPDX-License-Identifier: BSD-3-Clause + +#include "vtkActor.h" +#include "vtkConeSource.h" +#include "vtkPolyDataMapper.h" +#include "vtkRegressionTestImage.h" +#include "vtkRenderWindow.h" +#include "vtkRenderWindowInteractor.h" +#include "vtkRenderer.h" +#include "vtkTesting.h" + +#include <cstdlib> + +// In this unit test, there are 4 viewports. +// All viewports display the same actor. +int TestNViewportsOneActor(int argc, char* argv[]) +{ + vtkNew<vtkRenderWindow> renderWindow; + vtkNew<vtkRenderWindowInteractor> interactor; + vtkNew<vtkRenderer> renderers[4]; + vtkNew<vtkConeSource> cone; + vtkNew<vtkPolyDataMapper> mapper; + vtkNew<vtkActor> actor; + actor->SetMapper(mapper); + + mapper->SetInputConnection(cone->GetOutputPort()); + double xmins[4] = { 0.0, 0.4, 0.0, 0.0 }; + double ymins[4] = { 0.0, 0.0, 0.25, 0.5 }; + double xmaxs[4] = { 0.4, 1.0, 1.0, 1.0 }; + double ymaxs[4] = { 0.25, 0.25, 0.5, 1.0 }; + for (int i = 0; i < 4; ++i) + { + auto ren = renderers[i].Get(); + ren->AddActor(actor); + ren->SetBackground(i / 4.0, (4.0 - i) / 4, 1); + ren->SetViewport(xmins[i], ymins[i], xmaxs[i], ymaxs[i]); + renderWindow->AddRenderer(ren); + } + renderWindow->SetSize(800, 800); + renderWindow->SetInteractor(interactor); + interactor->Initialize(); + + const int retVal = vtkRegressionTestImage(renderWindow); + if (retVal == vtkRegressionTester::DO_INTERACTOR) + { + interactor->Start(); + } + return !retVal; +} diff --git a/Rendering/WebGPU/Testing/Cxx/TestReadPixels.cxx b/Rendering/WebGPU/Testing/Cxx/TestReadPixels.cxx index c3f8858460224e00eeef5aeb702556f5fd72e034..bf1e409a8e1c69bd98425da49ab2cb83084fbb76 100644 --- a/Rendering/WebGPU/Testing/Cxx/TestReadPixels.cxx +++ b/Rendering/WebGPU/Testing/Cxx/TestReadPixels.cxx @@ -53,13 +53,13 @@ int TestReadPixels(int, char*[]) VTK_TEST_READ_PIXELS(ucharTuple[0] == 100); VTK_TEST_READ_PIXELS(ucharTuple[1] == 110); VTK_TEST_READ_PIXELS(ucharTuple[2] == 120); - VTK_TEST_READ_PIXELS(ucharTuple[3] == 255); + VTK_TEST_READ_PIXELS(ucharTuple[3] == 0); ucharRGBA->GetTypedTuple(299 * 299, ucharTuple); VTK_TEST_READ_PIXELS(ucharTuple[0] == 100); VTK_TEST_READ_PIXELS(ucharTuple[1] == 110); VTK_TEST_READ_PIXELS(ucharTuple[2] == 120); - VTK_TEST_READ_PIXELS(ucharTuple[3] == 255); + VTK_TEST_READ_PIXELS(ucharTuple[3] == 0); // Verify background color as normalized float32 RGBA values vtkNew<vtkFloatArray> f32RGBA; @@ -68,12 +68,12 @@ int TestReadPixels(int, char*[]) VTK_TEST_READ_PIXELS(static_cast<int>(f32RGBA->GetTuple(0)[0] * 255) == 100); VTK_TEST_READ_PIXELS(static_cast<int>(f32RGBA->GetTuple(0)[1] * 255) == 110); VTK_TEST_READ_PIXELS(static_cast<int>(f32RGBA->GetTuple(0)[2] * 255) == 120); - VTK_TEST_READ_PIXELS(static_cast<int>(f32RGBA->GetTuple(0)[3] * 255) == 255); + VTK_TEST_READ_PIXELS(static_cast<int>(f32RGBA->GetTuple(0)[3] * 255) == 0); VTK_TEST_READ_PIXELS(static_cast<int>(f32RGBA->GetTuple(299)[0] * 255) == 100); VTK_TEST_READ_PIXELS(static_cast<int>(f32RGBA->GetTuple(299)[1] * 255) == 110); VTK_TEST_READ_PIXELS(static_cast<int>(f32RGBA->GetTuple(299)[2] * 255) == 120); - VTK_TEST_READ_PIXELS(static_cast<int>(f32RGBA->GetTuple(299)[3] * 255) == 255); + VTK_TEST_READ_PIXELS(static_cast<int>(f32RGBA->GetTuple(299)[3] * 255) == 0); // Verify background color as unsigned char RGB values vtkNew<vtkUnsignedCharArray> ucharRGB; diff --git a/Rendering/WebGPU/Testing/Data/Baseline/TestActorFaceCullingProperty.png.sha512 b/Rendering/WebGPU/Testing/Data/Baseline/TestActorFaceCullingProperty.png.sha512 index 6658b637354231aa81e73cd26988b0645e238805..b413346ccaa9c3726f79d0fcfe360345d89568a0 100644 --- a/Rendering/WebGPU/Testing/Data/Baseline/TestActorFaceCullingProperty.png.sha512 +++ b/Rendering/WebGPU/Testing/Data/Baseline/TestActorFaceCullingProperty.png.sha512 @@ -1 +1 @@ -c1e634e12d7cc3272cfab7ea4072441803d1a0893cad1c5768abc33e0f12dbc44c365f64fedab5d72e92895705e3b1ead17816662cd955a10090032cc7ebce80 +0881aed8e7ce2111245509ce0b1ed4d9400f7ad6a74d3b72f93fb144df3ec42db7a0f774540b138cc52adfc4873b757dd7a5a49c0fe49422d589cd26faf0b27a diff --git a/Rendering/WebGPU/Testing/Data/Baseline/TestAxesActor.png.sha512 b/Rendering/WebGPU/Testing/Data/Baseline/TestAxesActor.png.sha512 new file mode 100644 index 0000000000000000000000000000000000000000..27b819d0c3790109b7fef214dd305c1f8c4eb9a9 --- /dev/null +++ b/Rendering/WebGPU/Testing/Data/Baseline/TestAxesActor.png.sha512 @@ -0,0 +1 @@ +886465c51a5139ff595b17bbde3a13fd90fe355aaeeae771ac075a97e6ffc424787870464929ead886dc9beac5a9361a5f49644112c5b10bafd076a0e82a4432 diff --git a/Rendering/WebGPU/Testing/Data/Baseline/TestCellScalarMappedColors.png.sha512 b/Rendering/WebGPU/Testing/Data/Baseline/TestCellScalarMappedColors.png.sha512 index 44aad9b8c698c44283e2c56188ccec31bc21ebc2..71b9fd7af39b0f3d4372f918bd784ee5a4e8bb5d 100644 --- a/Rendering/WebGPU/Testing/Data/Baseline/TestCellScalarMappedColors.png.sha512 +++ b/Rendering/WebGPU/Testing/Data/Baseline/TestCellScalarMappedColors.png.sha512 @@ -1 +1 @@ -5c61da1a5e627f69e222ac01c30ef7ade58462eb99838a268f5970d8485de10e17d558e90378aa492bf2371b72d3098f5dc4d446da48c52cff3100f730a350eb +1cb666a1e9287f450d66fabba6212fd88f1b494ae54f5e92c06d639c5c40d6b89aa6c72a10b2d0e0ff7cd29f23b75714f48b874838c7ee9e91633f7953bd3567 diff --git a/Rendering/WebGPU/Testing/Data/Baseline/TestComputeDoublePipelineRenderBuffer.png.sha512 b/Rendering/WebGPU/Testing/Data/Baseline/TestComputeDoublePipelineRenderBuffer.png.sha512 index a6153df495357572175fa750891e96f31a9dff1f..c17909de3e81420cbbfadf4b3679f26ecc623cf8 100644 --- a/Rendering/WebGPU/Testing/Data/Baseline/TestComputeDoublePipelineRenderBuffer.png.sha512 +++ b/Rendering/WebGPU/Testing/Data/Baseline/TestComputeDoublePipelineRenderBuffer.png.sha512 @@ -1 +1 @@ -38e8af3e7c0de9fce3baeb82f242bc277721930a1f4b2f927788a6dd19786d5311cefc46d6c0328cebf5269d0fc81e77235d3fdd460add6c4b7f52619c667344 +9a2618f6fb336a10be5a4557db4c6b03bad73431201798ed47e94c8c9c09a98c22204382062ddc72005c454f3a730a74fef0e7493f9f3d78816f3a2eb4297018 diff --git a/Rendering/WebGPU/Testing/Data/Baseline/TestComputeModifyCellColors.png.sha512 b/Rendering/WebGPU/Testing/Data/Baseline/TestComputeModifyCellColors.png.sha512 index c56a25fb43ee8be48e0c36dc9a27d56adf584159..14e1e503fc9c464baa432339a71e265efe3bc8e5 100644 --- a/Rendering/WebGPU/Testing/Data/Baseline/TestComputeModifyCellColors.png.sha512 +++ b/Rendering/WebGPU/Testing/Data/Baseline/TestComputeModifyCellColors.png.sha512 @@ -1 +1 @@ -2d12adc4a72f82289906c7397a9a7e7dc0a0a9b24fd623e847ce2640d308b145d2b26e72796f8b92a9bc5c357081e915435de059ec63b772144b8ea034cdf87c +8ca4501aed167f882e5742d2f5c89e4a58c9a02498c5766c0cc2a192ad26534f37b1b900c5b3d642f069c745ae12e2897b80269b2f19191aeb39babb01009f5c diff --git a/Rendering/WebGPU/Testing/Data/Baseline/TestComputeModifyPointColors.png.sha512 b/Rendering/WebGPU/Testing/Data/Baseline/TestComputeModifyPointColors.png.sha512 index 6a3d36c2d25b54f67cd6c8f75e87a7193f3cb0d3..979b8fec1e2094c50293f7bfd914a50637fc8fad 100644 --- a/Rendering/WebGPU/Testing/Data/Baseline/TestComputeModifyPointColors.png.sha512 +++ b/Rendering/WebGPU/Testing/Data/Baseline/TestComputeModifyPointColors.png.sha512 @@ -1 +1 @@ -02d4b7e76ac468c9f57c3d3fd57e91be28108279311a2e64e5d76cdb76990549d5d0ff2a85b04130c7d0f58e4efe60ebc5369c7f82aeb77de84cf3f0a659d339 +15f41b07ddb55503627fecc1a1c400da3a24f2577834f800257b5d7b8870b2e43a485c6009b6c5bf46034a330db402391d8968fa9828f0b8770ed4e36483b09b diff --git a/Rendering/WebGPU/Testing/Data/Baseline/TestComputePointCloudMapperColors.png.sha512 b/Rendering/WebGPU/Testing/Data/Baseline/TestComputePointCloudMapperColors.png.sha512 index 5a1268059c1832c90c4c3d656ea0e8bac20d6461..c2227cf2e339d9f70f3ca6a49bd43572c2891103 100644 --- a/Rendering/WebGPU/Testing/Data/Baseline/TestComputePointCloudMapperColors.png.sha512 +++ b/Rendering/WebGPU/Testing/Data/Baseline/TestComputePointCloudMapperColors.png.sha512 @@ -1 +1 @@ -deb0401974b7dcd09b3f7a1f4f1db3ec002e3c41d987fc8fcd2a5a280955e4a72528cc8c981ed7964011511d46c5c64e8fa705fc6ac19ff878acca457addabb2 +61fa867e1067095520724ba2f4f3185dbecac2ebe4b1b587054797c55cb1934bcec68e748ca600d663598affda84bb9961254fb4aae5edebae91c62d81b4792a diff --git a/Rendering/WebGPU/Testing/Data/Baseline/TestComputePointCloudMapperDepth.png.sha512 b/Rendering/WebGPU/Testing/Data/Baseline/TestComputePointCloudMapperDepth.png.sha512 index cee7e21627fd64d05f78c2144aa628cf7451e37a..4843614a2971eff0a61f47b49c938d849bf161df 100644 --- a/Rendering/WebGPU/Testing/Data/Baseline/TestComputePointCloudMapperDepth.png.sha512 +++ b/Rendering/WebGPU/Testing/Data/Baseline/TestComputePointCloudMapperDepth.png.sha512 @@ -1 +1 @@ -704bd115593340117ba08f93ba65b1da53d5c2e3eaa6aaefab29eceb99cf9335d1749711963b4975af5f1b4425ddd6efdde2701d792ec20866c63e3c66468aa3 +6a60a66a20b4d48e8c124a28360f4cf8030da70a5416ca75f7e3e94f6afc531c5ae899a5923cf4352225400a844b79827d2db37431ec04000b561dd53fa2befa diff --git a/Rendering/WebGPU/Testing/Data/Baseline/TestComputePointCloudMapperGeometry.png.sha512 b/Rendering/WebGPU/Testing/Data/Baseline/TestComputePointCloudMapperGeometry.png.sha512 index b7fd061be53992023cd8a31fc090a7f171475201..e3b9cd02cf94488c7cb8302955476386158ecef0 100644 --- a/Rendering/WebGPU/Testing/Data/Baseline/TestComputePointCloudMapperGeometry.png.sha512 +++ b/Rendering/WebGPU/Testing/Data/Baseline/TestComputePointCloudMapperGeometry.png.sha512 @@ -1 +1 @@ -5814217c48a8044b617c3197c642380aa038347a17d17d1e1802f44700507f39f28ef517c6de8681d9c66663820477125a91003a59b77826049ef1be1292c310 +7cb81a40d3d1cf88b305b6d35e21079494664374e188eaa67f937bc903bcd52c3591021f2afdde44663b121d28aed133a52c2c2204cf5ffd75c14662d56e745b diff --git a/Rendering/WebGPU/Testing/Data/Baseline/TestLineRendering.png.sha512 b/Rendering/WebGPU/Testing/Data/Baseline/TestLineRendering.png.sha512 index 9c6721265c895841c35b36eb64a9df2afc147c0f..2de791bf1685283fdf93d6a3ef29d5e7398bc2e9 100644 --- a/Rendering/WebGPU/Testing/Data/Baseline/TestLineRendering.png.sha512 +++ b/Rendering/WebGPU/Testing/Data/Baseline/TestLineRendering.png.sha512 @@ -1 +1 @@ -472dca61286c099be50129b5c5c2d8767e96fdf4f8cbd11867064524f82258320458719f9bedd949c6c4c91d49e8e6eae97cb3070658944b2d5b4e2ad7e977dc +2beffd3799e6c0b9b4d56b7508efd86d91124d6282b8ed993b68c36369f8d2d25b40d66945517b0698f3d015523131d949d4d2a2af888a422a5c1b8cb078c5e7 diff --git a/Rendering/WebGPU/Testing/Data/Baseline/TestLineRenderingTranslucent.png.sha512 b/Rendering/WebGPU/Testing/Data/Baseline/TestLineRenderingTranslucent.png.sha512 index a00e8ae2dae91c85bb91136fa04083fb1b7b2e54..8ac494e15313bbc65cce61bbeeca11274f7ec7e1 100644 --- a/Rendering/WebGPU/Testing/Data/Baseline/TestLineRenderingTranslucent.png.sha512 +++ b/Rendering/WebGPU/Testing/Data/Baseline/TestLineRenderingTranslucent.png.sha512 @@ -1 +1 @@ -a96b4282a009fe27a75b2ac2af60a87446d089b10cdda4d84daca579bfbb9664b79eed7c9c91e94932f77085ce9cf12273602c21e77af1a10c26cdd3bc4b92f2 +5f510959aa0a84d2aaf009b78feb250ba07745146228eb37f1b945fc65f6f3cee9512db620d8af258ab67409adcd2d3d0edfeb7016f5fcbc0ef454ccac545993 diff --git a/Rendering/WebGPU/Testing/Data/Baseline/TestLowPowerRenderWindow.png.sha512 b/Rendering/WebGPU/Testing/Data/Baseline/TestLowPowerRenderWindow.png.sha512 index d7ef5664f4b8944ea7774dd957b98b8f56536397..dfc1b341469cf2450cbf615bad90b9d538c2e067 100644 --- a/Rendering/WebGPU/Testing/Data/Baseline/TestLowPowerRenderWindow.png.sha512 +++ b/Rendering/WebGPU/Testing/Data/Baseline/TestLowPowerRenderWindow.png.sha512 @@ -1 +1 @@ -f111f7ae82d341adecdc19189537997c4243679e88f86fbcb48bc34bb6b95844812e2b3ba85b45664b987818cc47ac0620684d1bb12741b8189d5db24b7be9d9 +583a6e60c700b15874f9642274b3f2526cb2500c40622c7d73e52ddf4a9ef7a783d8f4ee1ba542de511764fd0408a9fc5a72677b85bf930c2524024046110853 diff --git a/Rendering/WebGPU/Testing/Data/Baseline/TestMixedGeometry_1.png.sha512 b/Rendering/WebGPU/Testing/Data/Baseline/TestMixedGeometry_1.png.sha512 index 244725e9c28c2119a2c42a44588795c14c178bd3..c3cdb32a0ecb89d4e70fa08e1f84b868b84adf43 100644 --- a/Rendering/WebGPU/Testing/Data/Baseline/TestMixedGeometry_1.png.sha512 +++ b/Rendering/WebGPU/Testing/Data/Baseline/TestMixedGeometry_1.png.sha512 @@ -1 +1 @@ -3cc8d874194d98165bdf1b5c95661cdf91b288bd943bbc43e5562555b4a5ef488b356d42038ca21ee50ebe5205ce4a5a0075e18f832dd4b7c6f45bcc903c490d +d2b5aa1a422339f7f1855238c7115424810f0cb5aef51f269d5caf529586166f0add237798ce065093f5dc40cfa4f4a14a9680f615bb8a4c476d99f1c8491446 diff --git a/Rendering/WebGPU/Testing/Data/Baseline/TestMixedGeometry_2.png.sha512 b/Rendering/WebGPU/Testing/Data/Baseline/TestMixedGeometry_2.png.sha512 index 1171c0fa5af9e22f2bc70848d985689e71854f88..c3cdb32a0ecb89d4e70fa08e1f84b868b84adf43 100644 --- a/Rendering/WebGPU/Testing/Data/Baseline/TestMixedGeometry_2.png.sha512 +++ b/Rendering/WebGPU/Testing/Data/Baseline/TestMixedGeometry_2.png.sha512 @@ -1 +1 @@ -804ca7f760436abe04e1cfbe7aa3958153a15f543d571e4f20b22c0e441e85a4a7ddc19ca7bed180837a63273d2baa10f5418f56a1d7d3b30210f981409c5930 +d2b5aa1a422339f7f1855238c7115424810f0cb5aef51f269d5caf529586166f0add237798ce065093f5dc40cfa4f4a14a9680f615bb8a4c476d99f1c8491446 diff --git a/Rendering/WebGPU/Testing/Data/Baseline/TestMixedGeometry_3.png.sha512 b/Rendering/WebGPU/Testing/Data/Baseline/TestMixedGeometry_3.png.sha512 index dd87dac8a11a895e3f5a2ec3b7b6ab0a9a9b2ce2..03c0383943fbb5b5de29dd0a3f2fb786bed34c96 100644 --- a/Rendering/WebGPU/Testing/Data/Baseline/TestMixedGeometry_3.png.sha512 +++ b/Rendering/WebGPU/Testing/Data/Baseline/TestMixedGeometry_3.png.sha512 @@ -1 +1 @@ -dbfc20dc04a072f4edb5d4188869fd1cf07d1fba799c03ebc7d7311a1adce3f935c966c3e5b21c60844e2e1658ca8cc791c8bd983d9b7a6edcc01711fc85a761 +5702f2b1225a8a6ec83586038d170b01f7f7a5c3c770993ff1198c87e36fc496c0c8cd2c3feb80e49f59e8cda74010e12aa395b277d3ba9fef6ca20c81506ce5 diff --git a/Rendering/WebGPU/Testing/Data/Baseline/TestNActorsNMappersOneInput.png.sha512 b/Rendering/WebGPU/Testing/Data/Baseline/TestNActorsNMappersOneInput.png.sha512 new file mode 100644 index 0000000000000000000000000000000000000000..34037e305cd03e54805e59621ab8a2c57c7ea60b --- /dev/null +++ b/Rendering/WebGPU/Testing/Data/Baseline/TestNActorsNMappersOneInput.png.sha512 @@ -0,0 +1 @@ +9d9e8df1b7313212f66dcadb977c67a7c2d5a56cefa9bd320a3cbf785ebb4caeac6415450cb1ded117a1151d9574764c405a894beb10a30e9bd67b542f858dd3 diff --git a/Rendering/WebGPU/Testing/Data/Baseline/TestNActorsOneMapper.png.sha512 b/Rendering/WebGPU/Testing/Data/Baseline/TestNActorsOneMapper.png.sha512 new file mode 100644 index 0000000000000000000000000000000000000000..34037e305cd03e54805e59621ab8a2c57c7ea60b --- /dev/null +++ b/Rendering/WebGPU/Testing/Data/Baseline/TestNActorsOneMapper.png.sha512 @@ -0,0 +1 @@ +9d9e8df1b7313212f66dcadb977c67a7c2d5a56cefa9bd320a3cbf785ebb4caeac6415450cb1ded117a1151d9574764c405a894beb10a30e9bd67b542f858dd3 diff --git a/Rendering/WebGPU/Testing/Data/Baseline/TestNViewportsNActorsNMappersNInputs.png.sha512 b/Rendering/WebGPU/Testing/Data/Baseline/TestNViewportsNActorsNMappersNInputs.png.sha512 new file mode 100644 index 0000000000000000000000000000000000000000..e143f48c34ee3896e9407b173a358fece9712d54 --- /dev/null +++ b/Rendering/WebGPU/Testing/Data/Baseline/TestNViewportsNActorsNMappersNInputs.png.sha512 @@ -0,0 +1 @@ +f813c389a7baf1591355b0b0b0ffe73d88b782222e886fcd813cbcdb175da4842b9e84925e5a78e979257e301e3374c9c9f586097e0d0065b29c55acee15df45 diff --git a/Rendering/WebGPU/Testing/Data/Baseline/TestNViewportsNActorsNMappersOneInput.png.sha512 b/Rendering/WebGPU/Testing/Data/Baseline/TestNViewportsNActorsNMappersOneInput.png.sha512 new file mode 100644 index 0000000000000000000000000000000000000000..57dd5c7975db2961d6de14fe188c89582ee5793d --- /dev/null +++ b/Rendering/WebGPU/Testing/Data/Baseline/TestNViewportsNActorsNMappersOneInput.png.sha512 @@ -0,0 +1 @@ +dd3762a9d6d73f5e23142ca839637f914bf6b1a17aa0047bff731e4f254f84b6106c847f07c64bc57ff1404611caa038f3fc44269b9a7e6583ce3e1854176aa9 diff --git a/Rendering/WebGPU/Testing/Data/Baseline/TestNViewportsNActorsOneMapper.png.sha512 b/Rendering/WebGPU/Testing/Data/Baseline/TestNViewportsNActorsOneMapper.png.sha512 new file mode 100644 index 0000000000000000000000000000000000000000..57dd5c7975db2961d6de14fe188c89582ee5793d --- /dev/null +++ b/Rendering/WebGPU/Testing/Data/Baseline/TestNViewportsNActorsOneMapper.png.sha512 @@ -0,0 +1 @@ +dd3762a9d6d73f5e23142ca839637f914bf6b1a17aa0047bff731e4f254f84b6106c847f07c64bc57ff1404611caa038f3fc44269b9a7e6583ce3e1854176aa9 diff --git a/Rendering/WebGPU/Testing/Data/Baseline/TestNViewportsOneActor.png.sha512 b/Rendering/WebGPU/Testing/Data/Baseline/TestNViewportsOneActor.png.sha512 new file mode 100644 index 0000000000000000000000000000000000000000..90dd4ff29c3888466be8e89700645c8df32265b2 --- /dev/null +++ b/Rendering/WebGPU/Testing/Data/Baseline/TestNViewportsOneActor.png.sha512 @@ -0,0 +1 @@ +850e585b4caa0e554619a1224fd8ea77824e911240885698a383982d1fa64bb140ab80b6b7421643c345c4fb95ee4275ba2c4dcee54facd1af78c83c6b27f2f0 diff --git a/Rendering/WebGPU/Testing/Data/Baseline/TestPointRenderingRound_1.png.sha512 b/Rendering/WebGPU/Testing/Data/Baseline/TestPointRenderingRound_1.png.sha512 index 0ef75aeb60dec2e62cfed44a8894b8191abb3fb1..ff5df878095d3ecad3bf54c9d6d0eb1a5f524a80 100644 --- a/Rendering/WebGPU/Testing/Data/Baseline/TestPointRenderingRound_1.png.sha512 +++ b/Rendering/WebGPU/Testing/Data/Baseline/TestPointRenderingRound_1.png.sha512 @@ -1 +1 @@ -30d078d518abe289c701c9482405b7ad9b3abe98bcbbeee9e7676d37b207233e3e0f1618c9a95958637bf34df62a092da32b803f5fe4fe5bf031c54727afdb77 +ee52547b00b29bab4e7b07ac9cdecc423ff1999e105e69d8f21a77ceec060388ff86eca2e3f11d3892bcccf576fb508a175e4e35faf7f0ebfe26d74cfde584e7 diff --git a/Rendering/WebGPU/Testing/Data/Baseline/TestPointRenderingRound_2.png.sha512 b/Rendering/WebGPU/Testing/Data/Baseline/TestPointRenderingRound_2.png.sha512 index 0ef75aeb60dec2e62cfed44a8894b8191abb3fb1..ff5df878095d3ecad3bf54c9d6d0eb1a5f524a80 100644 --- a/Rendering/WebGPU/Testing/Data/Baseline/TestPointRenderingRound_2.png.sha512 +++ b/Rendering/WebGPU/Testing/Data/Baseline/TestPointRenderingRound_2.png.sha512 @@ -1 +1 @@ -30d078d518abe289c701c9482405b7ad9b3abe98bcbbeee9e7676d37b207233e3e0f1618c9a95958637bf34df62a092da32b803f5fe4fe5bf031c54727afdb77 +ee52547b00b29bab4e7b07ac9cdecc423ff1999e105e69d8f21a77ceec060388ff86eca2e3f11d3892bcccf576fb508a175e4e35faf7f0ebfe26d74cfde584e7 diff --git a/Rendering/WebGPU/Testing/Data/Baseline/TestPointRenderingRound_3.png.sha512 b/Rendering/WebGPU/Testing/Data/Baseline/TestPointRenderingRound_3.png.sha512 index 0ad165767946db85306e416e20ee3e21d50cdfe0..0465dcf0616e5556954d04ec6c56e9eadb08d2ad 100644 --- a/Rendering/WebGPU/Testing/Data/Baseline/TestPointRenderingRound_3.png.sha512 +++ b/Rendering/WebGPU/Testing/Data/Baseline/TestPointRenderingRound_3.png.sha512 @@ -1 +1 @@ -6b85ed6f9134cbfaddc81e8623006a958c4a0c25d20a39be8872b3675bb916c906ac9e5dca24c560206af10709f5656c9dc0267f8c3afaf54e39edd36d8bd35c +721edb7808f8b9362bd2b5e2fa800da8747c0c158de06c6415ffddb9207cdb94539a9ac89f38d987fedd97656d2bdd6e551ec4e675609070d37dcd83d5dff9e6 diff --git a/Rendering/WebGPU/Testing/Data/Baseline/TestPointRenderingRound_4.png.sha512 b/Rendering/WebGPU/Testing/Data/Baseline/TestPointRenderingRound_4.png.sha512 index 6af059dc8abc7d0760a72aaa049b5ff467234324..c71f22864b2b1fd5e5d18298656ea19e28f83825 100644 --- a/Rendering/WebGPU/Testing/Data/Baseline/TestPointRenderingRound_4.png.sha512 +++ b/Rendering/WebGPU/Testing/Data/Baseline/TestPointRenderingRound_4.png.sha512 @@ -1 +1 @@ -ea726b0f44e548870be57ea8f1710fdae6d242342354e9702f0469af21c9b86c92c46d8e128d82b5eb985c6c4a663b81930ccb50ae6d5819bdb857aacea46378 +d4aa29fcad92161f7f17eaa302c73fc036f51465cf54950c76899b6eeba5d4dcf7cb34372450ee7d53f1ce1c7aca0a873b885a7152c2d3d39e28ec743fc51a61 diff --git a/Rendering/WebGPU/Testing/Data/Baseline/TestPointRendering_1.png.sha512 b/Rendering/WebGPU/Testing/Data/Baseline/TestPointRendering_1.png.sha512 index 42cbd6dae0d8f5f957676a9ced7e5d0dd57116a6..06380ab15a0303d3e26e166a16719a0b8ad8e953 100644 --- a/Rendering/WebGPU/Testing/Data/Baseline/TestPointRendering_1.png.sha512 +++ b/Rendering/WebGPU/Testing/Data/Baseline/TestPointRendering_1.png.sha512 @@ -1 +1 @@ -4e167bd563795d1085f01b91931c037839271194f3fe1ff47c104561e30019eae41df5bafb99bb275055127ce92f6d9872a9d3b9aa6996a9fb1ab29a80018713 +28b157c8a0a7f3a5c78b5554123aeac67b21e6506f1b14f7017d5709bae9e413402cb871ec0b9a715e8a8ff2153462e94f92965624121a07333b46eaddceaeec diff --git a/Rendering/WebGPU/Testing/Data/Baseline/TestPointRendering_2.png.sha512 b/Rendering/WebGPU/Testing/Data/Baseline/TestPointRendering_2.png.sha512 index 42cbd6dae0d8f5f957676a9ced7e5d0dd57116a6..06380ab15a0303d3e26e166a16719a0b8ad8e953 100644 --- a/Rendering/WebGPU/Testing/Data/Baseline/TestPointRendering_2.png.sha512 +++ b/Rendering/WebGPU/Testing/Data/Baseline/TestPointRendering_2.png.sha512 @@ -1 +1 @@ -4e167bd563795d1085f01b91931c037839271194f3fe1ff47c104561e30019eae41df5bafb99bb275055127ce92f6d9872a9d3b9aa6996a9fb1ab29a80018713 +28b157c8a0a7f3a5c78b5554123aeac67b21e6506f1b14f7017d5709bae9e413402cb871ec0b9a715e8a8ff2153462e94f92965624121a07333b46eaddceaeec diff --git a/Rendering/WebGPU/Testing/Data/Baseline/TestPointRendering_3.png.sha512 b/Rendering/WebGPU/Testing/Data/Baseline/TestPointRendering_3.png.sha512 index 977a3e3c14321cc65945e7fcbc0498975c447c25..bee975fb8c1107dd7bea2f96584d3e13d1f15199 100644 --- a/Rendering/WebGPU/Testing/Data/Baseline/TestPointRendering_3.png.sha512 +++ b/Rendering/WebGPU/Testing/Data/Baseline/TestPointRendering_3.png.sha512 @@ -1 +1 @@ -93e01d5ca995cd0ed47dc56c1888f02068ea3c81d2a04c807cbaf179a4d10e3f2b51bcfb8e648175fa8f560d3ff377f835f73bde688415105082180cf09dfa6d +a0667349c665a084530a0b1c49a0e51814886b2a1938f7137ffb6275075ea2e202d3a92e6b77f2f7cd168f4bf6b01a7ce3b3f1fb6323019efa3c7274b26c693e diff --git a/Rendering/WebGPU/Testing/Data/Baseline/TestPointRendering_4.png.sha512 b/Rendering/WebGPU/Testing/Data/Baseline/TestPointRendering_4.png.sha512 index 78ceb0fb9f0d6ffe1382607269af1e43b9dd37ae..c1fdde10061922053a5b254bbf298a7f2dadfffc 100644 --- a/Rendering/WebGPU/Testing/Data/Baseline/TestPointRendering_4.png.sha512 +++ b/Rendering/WebGPU/Testing/Data/Baseline/TestPointRendering_4.png.sha512 @@ -1 +1 @@ -1b61f02cfbade29d6b4ff6c55d12e6a786b9b047bc0ab2408b0682af576e77b9ed5cacc1daea400b5befca7f4ecfa1243ef09b202cf7619f7a64255f04d630e2 +6ac5225469b91cc54054478553f3af3197bba9d73c7cfb4a2bceeef6667114821818f2b3dc621d8665e29b4d6639eca880dde59e0ee55c5c30fd689746f8d8ec diff --git a/Rendering/WebGPU/Testing/Data/Baseline/TestPointScalarMappedColors.png.sha512 b/Rendering/WebGPU/Testing/Data/Baseline/TestPointScalarMappedColors.png.sha512 index 5154983f4acc3ba8f7ff1cd259a5c8d3501258fd..93c50090ce762df936df55111316841671c108be 100644 --- a/Rendering/WebGPU/Testing/Data/Baseline/TestPointScalarMappedColors.png.sha512 +++ b/Rendering/WebGPU/Testing/Data/Baseline/TestPointScalarMappedColors.png.sha512 @@ -1 +1 @@ -7d781c9819babbda35b638eddd120ad9b6164f0a6aa45b5f4bd95b6f22e4d405abcb0d7aecccac091aad28b198c28565d8b993a5f93557a16f4334c6f9b3133e +cde0cd07919ed186c63d188df1cb6bc21c28b924e25e88dfd0acbb592ad7261730e7c853a0b1e89a53ef08b6eddc0da7bf7029482d8c32bc48c75199edcaa2a4 diff --git a/Rendering/WebGPU/Testing/Data/Baseline/TestQuad.png.sha512 b/Rendering/WebGPU/Testing/Data/Baseline/TestQuad.png.sha512 index 7761c3855dd4175628fac6b057022c491007e00c..f814656ad47ac04303e0426332103e23709fe069 100644 --- a/Rendering/WebGPU/Testing/Data/Baseline/TestQuad.png.sha512 +++ b/Rendering/WebGPU/Testing/Data/Baseline/TestQuad.png.sha512 @@ -1 +1 @@ -b267115b993da75808f971524fbf97f7d5019a9aa2eac52cce3ba5502641cca369f924e2ffa58bee19f17d6a93e8b8b6289e6b93638697cada99f273f4414c6e +0e4502df4f4e1e99e729f8649e1ff27e090dc708204adfb8abe3635562b51861b715970201fad5db58c19eab6dae8162b8e78e3c2a566747a368cce87ad147f1 diff --git a/Rendering/WebGPU/Testing/Data/Baseline/TestQuadPointRep.png.sha512 b/Rendering/WebGPU/Testing/Data/Baseline/TestQuadPointRep.png.sha512 index 4da6d3d8c445972f9468d6b8ce3237ed2dda293f..a83a300f50628eeae545d6d019ace25c2a8cf99f 100644 --- a/Rendering/WebGPU/Testing/Data/Baseline/TestQuadPointRep.png.sha512 +++ b/Rendering/WebGPU/Testing/Data/Baseline/TestQuadPointRep.png.sha512 @@ -1 +1 @@ -91f685ee35dbbebfff125876440a7275e04dcb0bae2c5a62e4bc05cdf30edcabcb8a0cdf65c9291291a0c0cf4bb6faa6e001edb87b37ae37b077c029e07fe3b5 +54065c6a9eed2ed5ae39f721f8bd0e1d1f3e6acb1559d843c4347d5e5f44505ab75ecec6b34db63d815182865a42626b8491478103c304c2af229f7df0b586bb diff --git a/Rendering/WebGPU/Testing/Data/Baseline/TestRenderLinesAsTubes.png.sha512 b/Rendering/WebGPU/Testing/Data/Baseline/TestRenderLinesAsTubes.png.sha512 index 75e88241db1d17656673b9aafdc4133e795d9747..95312a9ae5602a55e612a7d91cb2d270dccb2268 100644 --- a/Rendering/WebGPU/Testing/Data/Baseline/TestRenderLinesAsTubes.png.sha512 +++ b/Rendering/WebGPU/Testing/Data/Baseline/TestRenderLinesAsTubes.png.sha512 @@ -1 +1 @@ -064a4dbc2a1582a48644537c53fb6b896540d7d5748e87f41c3230962c1cbfbca02f8c2201f1cd6a1e09bb0161251a645b7edc4a0b0efd2d0beb6d2ebdcf2c05 +e37091f7ca37c78b696e2df6da78d7c09a2e3311c2c305535997c86ad61c4abe505843c0e467c63b40cb735a1f588ea225458ab2d26a7d4bbe7f7f75dac2c93f diff --git a/Rendering/WebGPU/Testing/Data/Baseline/TestRenderLinesAsTubesOrthoCamera.png.sha512 b/Rendering/WebGPU/Testing/Data/Baseline/TestRenderLinesAsTubesOrthoCamera.png.sha512 index ffe2989f8418e5cf47d9e430e08e0ccd68507367..0a1af52022afc1064faf2853e5d13db438d32daf 100644 --- a/Rendering/WebGPU/Testing/Data/Baseline/TestRenderLinesAsTubesOrthoCamera.png.sha512 +++ b/Rendering/WebGPU/Testing/Data/Baseline/TestRenderLinesAsTubesOrthoCamera.png.sha512 @@ -1 +1 @@ -54e8a8dc61bef44333e10b66fb26f684052cea20f84679951436a2164c2337d383364389027fdc43ad458ce68970c10b2627d1a918b38d1e9339e97e8d94075d +3fe64733a33a65bf78ff350e03fd2be1c48717dd2c08940464a2a363e74d996cbd1bdff813ed6fe3021f9a7c819130beb415698fb8ba9293d7974fe17414e5ff diff --git a/Rendering/WebGPU/Testing/Data/Baseline/TestRenderPointsAsSpheres.png.sha512 b/Rendering/WebGPU/Testing/Data/Baseline/TestRenderPointsAsSpheres.png.sha512 index 07e05061f89a09ce88aae20954ad79f31c2abe37..8cefe76ec3877cc216f8383e22feb80428cccf8e 100644 --- a/Rendering/WebGPU/Testing/Data/Baseline/TestRenderPointsAsSpheres.png.sha512 +++ b/Rendering/WebGPU/Testing/Data/Baseline/TestRenderPointsAsSpheres.png.sha512 @@ -1 +1 @@ -5b005358c5e110bfa576153c2c371db80f00fd6a07c8ea0e98ce04d71805153a5aa8133c56a8915b63e98d16c7bef0d6162dc4296fc67c6ce3c1c20b82fab4d5 +4cafe2027593b9596d9e5bfc51ae784ec1c34573a9dbc9ec39ff67ac9b8dd7b252cd2b609d0e2e4d36c2860528f394bb57a7bbad72d38de3879a7d6952411083 diff --git a/Rendering/WebGPU/Testing/Data/Baseline/TestRenderPointsAsSpheresOrthoCamera.png.sha512 b/Rendering/WebGPU/Testing/Data/Baseline/TestRenderPointsAsSpheresOrthoCamera.png.sha512 index 4b7237d22837571c302fbe9873d52c16a2416cf2..4d5d0d8d2337b5e33dd746bda097a6cf56a43be8 100644 --- a/Rendering/WebGPU/Testing/Data/Baseline/TestRenderPointsAsSpheresOrthoCamera.png.sha512 +++ b/Rendering/WebGPU/Testing/Data/Baseline/TestRenderPointsAsSpheresOrthoCamera.png.sha512 @@ -1 +1 @@ -d19ae6919a75f7e656a47d7ddb4dcf5a646ef4ce240b64a52593ce2a94533f244a723dc16e003cd3ca7ee9c856fe4ddd368de56a8cf2ebbd4b2cacf168c279f2 +fa748691e72885453226191e044d2526a2ab98f40bb7a8f99b197fe25b412ed448a8da8f05202c60ae979fc140a80178ae9b42b34b8629ba3f1ebfd7e21c5de3 diff --git a/Rendering/WebGPU/Testing/Data/Baseline/TestRenderWindowChangeDeviceLater.png.sha512 b/Rendering/WebGPU/Testing/Data/Baseline/TestRenderWindowChangeDeviceLater.png.sha512 index d7ef5664f4b8944ea7774dd957b98b8f56536397..dfc1b341469cf2450cbf615bad90b9d538c2e067 100644 --- a/Rendering/WebGPU/Testing/Data/Baseline/TestRenderWindowChangeDeviceLater.png.sha512 +++ b/Rendering/WebGPU/Testing/Data/Baseline/TestRenderWindowChangeDeviceLater.png.sha512 @@ -1 +1 @@ -f111f7ae82d341adecdc19189537997c4243679e88f86fbcb48bc34bb6b95844812e2b3ba85b45664b987818cc47ac0620684d1bb12741b8189d5db24b7be9d9 +583a6e60c700b15874f9642274b3f2526cb2500c40622c7d73e52ddf4a9ef7a783d8f4ee1ba542de511764fd0408a9fc5a72677b85bf930c2524024046110853 diff --git a/Rendering/WebGPU/Testing/Data/Baseline/TestScalarModeToggle.png.sha512 b/Rendering/WebGPU/Testing/Data/Baseline/TestScalarModeToggle.png.sha512 index ce72704a5746f00ee6a53913586ce72cb1a83e19..bed06da2eb62b99ffc33cc4c61d6c88929aebd86 100644 --- a/Rendering/WebGPU/Testing/Data/Baseline/TestScalarModeToggle.png.sha512 +++ b/Rendering/WebGPU/Testing/Data/Baseline/TestScalarModeToggle.png.sha512 @@ -1 +1 @@ -922b963521eea93e5a33c1fa0a18d396b8087d3e8fbca10f7ff81ee9a7bfa672a2b06d059587fbc3ab66f6eae2971b2c80d0c925d751d9f163d0e927aa6db4e0 +ec605ce3d149e95431d7329d5ec05da9fc5203657ee76073f065ea384038fd3c2bcbcd4102dac4d4b9357cd68db1bb3d7399820f38231a9877456a691a3cc15e diff --git a/Rendering/WebGPU/Testing/Data/Baseline/TestSurfacePlusEdges.png.sha512 b/Rendering/WebGPU/Testing/Data/Baseline/TestSurfacePlusEdges.png.sha512 index 5303a3cc04e92ae183c2b317d7310d2671918d9a..1377665f933976eff976d5a560c8ad7bfd421a46 100644 --- a/Rendering/WebGPU/Testing/Data/Baseline/TestSurfacePlusEdges.png.sha512 +++ b/Rendering/WebGPU/Testing/Data/Baseline/TestSurfacePlusEdges.png.sha512 @@ -1 +1 @@ -1d2214369f96edc5a4b53ab0ae46e2ab68cdb62f02a7e7a31306bdb01fa829bcd47f0ff1a977cbee8bf86bda19fc48d473a1e1c85a11ac08e373151d3065f2a5 +5e6a31fa7fde75f080349de0a0e232e90b5212d23062483d42deac5de925228bbe12457c9e54cda49c7bfe3f0702f245606692ce9aa87afb1ff305545d4a0cc6 diff --git a/Rendering/WebGPU/Testing/Data/Baseline/TestVertexRendering.png.sha512 b/Rendering/WebGPU/Testing/Data/Baseline/TestVertexRendering.png.sha512 index ab5275de9236d8efa778cd9884c384696297d9f1..ba521867e1c4fdfcb5ec053d36025c76bbaa058b 100644 --- a/Rendering/WebGPU/Testing/Data/Baseline/TestVertexRendering.png.sha512 +++ b/Rendering/WebGPU/Testing/Data/Baseline/TestVertexRendering.png.sha512 @@ -1 +1 @@ -ccdb818a5c7c6053607474f74da970eff8177a339794750ea9eb2812a99c4eb6b68d7f40092ea664f786e264e3cf16827c98871d95f3b077bf222dc30b112cd9 +4560bd0959e7c53ae32821a6762a67c695b6dda7785a4fb7c910f79e014865678d5b19f18df25cc7c31c633cfe634d31d80b746616d1ad8dcd9e9a8210d29e70 diff --git a/Rendering/WebGPU/Testing/Data/Baseline/TestWireframe.png.sha512 b/Rendering/WebGPU/Testing/Data/Baseline/TestWireframe.png.sha512 index 6c58a2ad70761d2707633adf7a0d401d424c4f7b..112e470852e9082b8e76635808e0568b91c0ee4a 100644 --- a/Rendering/WebGPU/Testing/Data/Baseline/TestWireframe.png.sha512 +++ b/Rendering/WebGPU/Testing/Data/Baseline/TestWireframe.png.sha512 @@ -1 +1 @@ -be78db346b8e6546e1be90a8d471f44765fb64267b2c25d7682dbca0b223d21e4e127f854c7c14dd622a6e06fa3d9dca6dcc3a3934df503992ff0fee40f672c8 +927647d3209b1d0c9ada11d62d57c3ecb3eb3a62bf8fddf4e0b31aef4b8f37a0c755100f58d23346d26c56afaf0d2a94339d5224f3313a1914dcb6be56047668 diff --git a/Rendering/WebGPU/Testing/Python/TestReadPixels.py b/Rendering/WebGPU/Testing/Python/TestReadPixels.py index a3fbbf1d7cc5cdcebd4683528356e717462d45d4..0743921b49d50855910072d9e80a4a05046510e0 100644 --- a/Rendering/WebGPU/Testing/Python/TestReadPixels.py +++ b/Rendering/WebGPU/Testing/Python/TestReadPixels.py @@ -27,8 +27,8 @@ renderWindow.Render() # Verify background color as unsigned char RGBA values ucharRGBA = vtkUnsignedCharArray() renderWindow.GetRGBACharPixelData(0, 0, 299, 299, 0, ucharRGBA) -assert(ucharRGBA.GetTuple(0) == (100.0, 110.0, 120.0, 255.0)) -assert(ucharRGBA.GetTuple(299 * 299) == (100.0, 110.0, 120.0, 255.0)) +assert(ucharRGBA.GetTuple(0) == (100.0, 110.0, 120.0, 0.0)) +assert(ucharRGBA.GetTuple(299 * 299) == (100.0, 110.0, 120.0, 0.0)) # Verify background color as normalized float32 RGBA values f32RGBA = vtkFloatArray() @@ -36,11 +36,11 @@ renderWindow.GetRGBAPixelData(0, 0, 299, 299, 0, f32RGBA) assert(int(f32RGBA.GetTuple(0)[0] * 255) == 100) assert(int(f32RGBA.GetTuple(0)[1] * 255) == 110) assert(int(f32RGBA.GetTuple(0)[2] * 255) == 120) -assert(int(f32RGBA.GetTuple(0)[3] * 255) == 255) +assert(int(f32RGBA.GetTuple(0)[3] * 255) == 0) assert(int(f32RGBA.GetTuple(299)[0] * 255) == 100) assert(int(f32RGBA.GetTuple(299)[1] * 255) == 110) assert(int(f32RGBA.GetTuple(299)[2] * 255) == 120) -assert(int(f32RGBA.GetTuple(299)[3] * 255) == 255) +assert(int(f32RGBA.GetTuple(299)[3] * 255) == 0) # Verify background color as unsigned char RGB values ucharRGB = vtkUnsignedCharArray() diff --git a/Rendering/WebGPU/vtk.module b/Rendering/WebGPU/vtk.module index 0a57a63011665150f1558f3e37c7836e3c340809..412fcc1b583047fcb5b844b5e632484c44670d30 100644 --- a/Rendering/WebGPU/vtk.module +++ b/Rendering/WebGPU/vtk.module @@ -20,9 +20,11 @@ PRIVATE_DEPENDS VTK::fmt TEST_DEPENDS VTK::CommonColor + VTK::RenderingAnnotation VTK::FiltersGeneral VTK::FiltersSources VTK::RenderingUI VTK::InteractionStyle + VTK::InteractionWidgets VTK::TestingCore VTK::TestingRendering diff --git a/Rendering/WebGPU/vtkWebGPUActor.cxx b/Rendering/WebGPU/vtkWebGPUActor.cxx index 9df2df4034dfbda7c87957e246b5670b41c30a68..ef3e443c1d535ac0b1e6910c0ee28eb386856add 100644 --- a/Rendering/WebGPU/vtkWebGPUActor.cxx +++ b/Rendering/WebGPU/vtkWebGPUActor.cxx @@ -3,6 +3,9 @@ #include "vtkWebGPUActor.h" +#include "Private/vtkWebGPUBindGroupInternals.h" +#include "Private/vtkWebGPUBindGroupLayoutInternals.h" + #include "vtkMapper.h" #include "vtkMatrix3x3.h" #include "vtkObjectFactory.h" @@ -12,6 +15,7 @@ #include "vtkTexture.h" #include "vtkTransform.h" #include "vtkWebGPUComputePointCloudMapper.h" +#include "vtkWebGPURenderWindow.h" #include "vtkWebGPURenderer.h" #include "vtkWindow.h" @@ -19,6 +23,19 @@ VTK_ABI_NAMESPACE_BEGIN +//------------------------------------------------------------------------------ +void vtkWebGPUActor::MapperBooleanCache::SetValue(bool newValue) +{ + this->Value = newValue; + this->TimeStamp.Modified(); +} + +//------------------------------------------------------------------------------ +bool vtkWebGPUActor::MapperBooleanCache::IsOutdated(vtkMapper* mapper) +{ + return mapper->GetMTime() > this->TimeStamp; +} + //------------------------------------------------------------------------------ vtkStandardNewMacro(vtkWebGPUActor); @@ -35,7 +52,17 @@ void vtkWebGPUActor::PrintSelf(ostream& os, vtkIndent indent) os << indent << "ModelTransformsBuildTimestamp: " << this->ModelTransformsBuildTimestamp << '\n'; os << indent << "ShadingOptionsBuildTimestamp: " << this->ShadingOptionsBuildTimestamp << '\n'; os << indent << "RenderOptionsBuildTimestamp: " << this->RenderOptionsBuildTimestamp << '\n'; - os << indent << "BundleInvalidated: " << this->BundleInvalidated << '\n'; +} + +//------------------------------------------------------------------------------ +void vtkWebGPUActor::ReleaseGraphicsResources(vtkWindow* window) +{ + this->ActorBindGroupLayout = nullptr; + this->ActorBindGroup = nullptr; + this->ActorBuffer = nullptr; + this->MapperHasOpaqueGeometry = {}; + this->MapperHasTranslucentPolygonalGeometry = {}; + this->Superclass::ReleaseGraphicsResources(window); } //------------------------------------------------------------------------------ @@ -43,21 +70,46 @@ void vtkWebGPUActor::Render(vtkRenderer* renderer, vtkMapper* mapper) { if (auto* wgpuRenderer = vtkWebGPURenderer::SafeDownCast(renderer)) { + auto* wgpuRenderWindow = vtkWebGPURenderWindow::SafeDownCast(wgpuRenderer->GetRenderWindow()); + auto* wgpuConfiguration = wgpuRenderWindow->GetWGPUConfiguration(); switch (wgpuRenderer->GetRenderStage()) { case vtkWebGPURenderer::AwaitingPreparation: break; case vtkWebGPURenderer::UpdatingBuffers: + { + if (!(this->ActorBindGroup && this->ActorBindGroupLayout && this->ActorBuffer)) + { + this->AllocateResources(wgpuConfiguration); + } // reset this flag because the `mapper->Render()` call shall invalidate the bundle if it // determines that the render bundle needs to be recorded once again. - this->BundleInvalidated = false; mapper->Render(renderer, this); - this->CacheActorRenderOptions(); - this->CacheActorShadeOptions(); - this->CacheActorTransforms(); + bool updateBuffers = this->CacheActorRenderOptions(); + updateBuffers |= this->CacheActorShadeOptions(); + updateBuffers |= this->CacheActorTransforms(); + if (updateBuffers) + { + wgpuConfiguration->WriteBuffer(this->ActorBuffer, 0, this->GetCachedActorInformation(), + this->GetCacheSizeBytes(), "ActorBufferUpdate"); + } break; + } case vtkWebGPURenderer::RecordingCommands: - mapper->Render(renderer, this); + if (wgpuRenderer->GetUseRenderBundles() && this->SupportRenderBundles()) + { + if (wgpuRenderer->GetRebuildRenderBundle()) + { + wgpuRenderer->GetRenderBundleEncoder().SetBindGroup(1, this->ActorBindGroup); + mapper->Render(renderer, this); + } + // else, no need to record draw commands. + } + else + { + wgpuRenderer->GetRenderPassEncoder().SetBindGroup(1, this->ActorBindGroup); + mapper->Render(renderer, this); + } break; case vtkWebGPURenderer::Finished: default: @@ -85,6 +137,66 @@ bool vtkWebGPUActor::SupportRenderBundles() return true; } +//------------------------------------------------------------------------------ +vtkTypeBool vtkWebGPUActor::HasOpaqueGeometry() +{ + bool isOpaque = false; + if (this->Mapper) + { + if (this->MapperHasOpaqueGeometry.IsOutdated(this->Mapper)) + { + isOpaque = this->Superclass::HasOpaqueGeometry(); + this->MapperHasOpaqueGeometry.SetValue(isOpaque); + } + else + { + // nullify mapper so that superclass doesn't run the expensive + // code path in vtkMapper::HasOpaqueGeometry. + vtkMapper* tmpMapper = this->Mapper; + this->Mapper = nullptr; + isOpaque = this->Superclass::HasOpaqueGeometry(); + // restore + this->Mapper = tmpMapper; + isOpaque &= this->MapperHasOpaqueGeometry.GetValue(); + } + } + else + { + isOpaque = this->Superclass::HasOpaqueGeometry(); + } + return isOpaque; +} + +//------------------------------------------------------------------------------ +vtkTypeBool vtkWebGPUActor::HasTranslucentPolygonalGeometry() +{ + bool isTranslucent = false; + if (this->Mapper) + { + if (this->MapperHasTranslucentPolygonalGeometry.IsOutdated(this->Mapper)) + { + isTranslucent = this->Superclass::HasTranslucentPolygonalGeometry(); + this->MapperHasTranslucentPolygonalGeometry.SetValue(isTranslucent); + } + else + { + // nullify mapper so that superclass doesn't run the expensive + // code path in vtkMapper::HasTranslucentPolygonalGeometry. + vtkMapper* tmpMapper = this->Mapper; + this->Mapper = nullptr; + isTranslucent = this->Superclass::HasTranslucentPolygonalGeometry(); + // restore + this->Mapper = tmpMapper; + isTranslucent &= this->MapperHasTranslucentPolygonalGeometry.GetValue(); + } + } + else + { + isTranslucent = this->Superclass::HasTranslucentPolygonalGeometry(); + } + return isTranslucent; +} + //------------------------------------------------------------------------------ bool vtkWebGPUActor::UpdateKeyMatrices() { @@ -126,7 +238,7 @@ bool vtkWebGPUActor::UpdateKeyMatrices() } //------------------------------------------------------------------------------ -void vtkWebGPUActor::CacheActorTransforms() +bool vtkWebGPUActor::CacheActorTransforms() { if (this->UpdateKeyMatrices()) { @@ -142,11 +254,13 @@ void vtkWebGPUActor::CacheActorTransforms() transform.Normal[i][j] = this->NormalMatrix->GetElement(i, j); } } + return true; } + return false; } //------------------------------------------------------------------------------ -void vtkWebGPUActor::CacheActorRenderOptions() +bool vtkWebGPUActor::CacheActorRenderOptions() { auto* displayProperty = this->GetProperty(); if (displayProperty->GetMTime() > this->RenderOptionsBuildTimestamp || @@ -165,11 +279,13 @@ void vtkWebGPUActor::CacheActorRenderOptions() (displayProperty->GetRenderLinesAsTubes() << 6) | (static_cast<int>(displayProperty->GetPoint2DShape()) << 7); this->RenderOptionsBuildTimestamp.Modified(); + return true; } + return false; } //------------------------------------------------------------------------------ -void vtkWebGPUActor::CacheActorShadeOptions() +bool vtkWebGPUActor::CacheActorShadeOptions() { auto* displayProperty = this->GetProperty(); if (displayProperty->GetMTime() > this->ShadingOptionsBuildTimestamp || @@ -190,6 +306,42 @@ void vtkWebGPUActor::CacheActorShadeOptions() so.VertexColor[i] = displayProperty->GetVertexColor()[i]; } this->ShadingOptionsBuildTimestamp.Modified(); + return true; } + return false; +} + +//------------------------------------------------------------------------------ +void vtkWebGPUActor::AllocateResources(vtkWebGPUConfiguration* wgpuConfiguration) +{ + const auto& device = wgpuConfiguration->GetDevice(); + + const auto actorDescription = this->GetObjectDescription(); + const auto bufferLabel = "buffer@" + actorDescription; + const auto bufferSize = vtkWebGPUConfiguration::Align(vtkWebGPUActor::GetCacheSizeBytes(), 32); + this->ActorBuffer = wgpuConfiguration->CreateBuffer(bufferSize, + wgpu::BufferUsage::Storage | wgpu::BufferUsage::CopyDst, false, bufferLabel.c_str()); + + this->ActorBindGroupLayout = vtkWebGPUBindGroupLayoutInternals::MakeBindGroupLayout(device, + { + // clang-format off + // ActorBlocks + { 0, wgpu::ShaderStage::Vertex | wgpu::ShaderStage::Fragment, wgpu::BufferBindingType::ReadOnlyStorage }, + // clang-format on + }, + "bgl@" + actorDescription); + this->ActorBindGroup = + vtkWebGPUBindGroupInternals::MakeBindGroup(device, this->ActorBindGroupLayout, + { + // clang-format off + { 0, this->ActorBuffer, 0, bufferSize }, + // clang-format on + }, + "bg@" + actorDescription); + // Reset timestamps because the previous buffer is now gone and contents of the buffer will need + // to be re-uploaded. + this->ModelTransformsBuildTimestamp = vtkTimeStamp(); + this->ShadingOptionsBuildTimestamp = vtkTimeStamp(); + this->RenderOptionsBuildTimestamp = vtkTimeStamp(); } VTK_ABI_NAMESPACE_END diff --git a/Rendering/WebGPU/vtkWebGPUActor.h b/Rendering/WebGPU/vtkWebGPUActor.h index 01bc6d3873830d2593dd2712542ad795ad001aa0..002ace5cf247050a59100f95b5332fd2dce32bf2 100644 --- a/Rendering/WebGPU/vtkWebGPUActor.h +++ b/Rendering/WebGPU/vtkWebGPUActor.h @@ -10,6 +10,7 @@ VTK_ABI_NAMESPACE_BEGIN class vtkMatrix3x3; +class vtkWebGPUConfiguration; class vtkWebGPURenderPipelineCache; class VTKRENDERINGWEBGPU_EXPORT vtkWebGPUActor : public vtkActor @@ -19,6 +20,8 @@ public: vtkTypeMacro(vtkWebGPUActor, vtkActor); void PrintSelf(ostream& os, vtkIndent indent) override; + void ReleaseGraphicsResources(vtkWindow* window) override; + inline const void* GetCachedActorInformation() { return &(this->CachedActorInfo); } static std::size_t GetCacheSizeBytes() { return sizeof(ActorBlock); } @@ -35,28 +38,40 @@ public: */ bool SupportRenderBundles(); + inline void PopulateBindgroupLayouts(std::vector<wgpu::BindGroupLayout>& layouts) + { + layouts.emplace_back(this->ActorBindGroupLayout); + } + virtual bool UpdateKeyMatrices(); + ///@{ /** - * Forces the renderer to re-record draw commands into a render bundle associated with this actor. + * Does this prop have opaque/translucent polygonal geometry? + * These methods are overriden to skip redundant checks + * in different rendering stages. * - * @note This does not use vtkSetMacro because the actor MTime should not be affected when a - * render bundle is invalidated. - */ - inline void SetBundleInvalidated(bool value) { this->BundleInvalidated = value; } - - /** - * Get whether the render bundle associated with this actor must be reset by the renderer. + * If the mapper has already been checked for opaque geometry and the mapper + * has not been modified since the last check, this method uses the last result, + * instead of asking the mapper to check for opaque geometry again. The + * HasTranslucentPolygonalGeometry() similarly checks and caches the result of + * vtkMapper::HasTranslucentPolygonalGeometry() + * + * @sa vtkWebGPURenderer::GetRenderStage() */ - vtkGetMacro(BundleInvalidated, bool); + vtkTypeBool HasOpaqueGeometry() override; + vtkTypeBool HasTranslucentPolygonalGeometry() override; + ///@} protected: vtkWebGPUActor(); ~vtkWebGPUActor() override; - void CacheActorTransforms(); - void CacheActorRenderOptions(); - void CacheActorShadeOptions(); + bool CacheActorTransforms(); + bool CacheActorRenderOptions(); + bool CacheActorShadeOptions(); + + void AllocateResources(vtkWebGPUConfiguration* renderer); struct ActorBlock { @@ -116,7 +131,34 @@ protected: vtkTimeStamp ShadingOptionsBuildTimestamp; vtkTimeStamp RenderOptionsBuildTimestamp; - bool BundleInvalidated = false; + wgpu::BindGroupLayout ActorBindGroupLayout; + wgpu::BindGroup ActorBindGroup; + wgpu::Buffer ActorBuffer; + + class MapperBooleanCache + { + bool Value = false; + vtkTimeStamp TimeStamp; + + public: + /** + * Update the cached value with the new value. This also increments the TimeStamp. + */ + void SetValue(bool newValue); + + /** + * Returns the cached `Value`. + */ + inline bool GetValue() { return Value; } + + /** + * Returns true if the timestamp of the cached value is older than the mapper's MTime. + */ + bool IsOutdated(vtkMapper* mapper); + }; + + MapperBooleanCache MapperHasOpaqueGeometry; + MapperBooleanCache MapperHasTranslucentPolygonalGeometry; private: vtkWebGPUActor(const vtkWebGPUActor&) = delete; diff --git a/Rendering/WebGPU/vtkWebGPUBatchedPolyDataMapper.cxx b/Rendering/WebGPU/vtkWebGPUBatchedPolyDataMapper.cxx index dbaf78d08e74b22c999cafdc91d598d7d5220cf0..f1127874a16297ef81d291bbe7c573889baf710a 100644 --- a/Rendering/WebGPU/vtkWebGPUBatchedPolyDataMapper.cxx +++ b/Rendering/WebGPU/vtkWebGPUBatchedPolyDataMapper.cxx @@ -138,14 +138,14 @@ void vtkWebGPUBatchedPolyDataMapper::RenderPiece(vtkRenderer* renderer, vtkActor } auto* wgpuRenderWindow = vtkWebGPURenderWindow::SafeDownCast(renderer->GetRenderWindow()); - auto* wgpuActor = vtkWebGPUActor::SafeDownCast(actor); + auto* wgpuRenderer = vtkWebGPURenderer::SafeDownCast(renderer); auto* wgpuConfiguration = wgpuRenderWindow->GetWGPUConfiguration(); const auto& device = wgpuRenderWindow->GetDevice(); auto& batchElement = *(this->VTKPolyDataToBatchElement.begin()->second); if (this->LastBlockVisibility != batchElement.Visibility) { - wgpuActor->SetBundleInvalidated(true); + wgpuRenderer->InvalidateBundle(); } this->LastBlockVisibility = batchElement.Visibility; diff --git a/Rendering/WebGPU/vtkWebGPUCamera.cxx b/Rendering/WebGPU/vtkWebGPUCamera.cxx index aa36d2e8b920eb02312beefa0506afa9e164ece7..3e52a238a4e40e38edab7f9c125b0f9bbed3573c 100644 --- a/Rendering/WebGPU/vtkWebGPUCamera.cxx +++ b/Rendering/WebGPU/vtkWebGPUCamera.cxx @@ -5,6 +5,7 @@ #include "vtkMatrix3x3.h" #include "vtkMatrix4x4.h" #include "vtkObjectFactory.h" +#include "vtkRenderWindow.h" #include "vtkRenderer.h" #include "vtkWebGPURenderer.h" @@ -60,6 +61,7 @@ void vtkWebGPUCamera::CacheSceneTransforms(vtkRenderer* renderer) st.ProjectionMatrix[i][j] = projection->GetElement(j, i); } } + st.ProjectionMatrix[1][1] *= -1; // normal matrix for (int i = 0; i < 3; ++i) { @@ -119,13 +121,17 @@ void vtkWebGPUCamera::UpdateViewport(vtkRenderer* renderer) rpassEncoder.SetScissorRect(static_cast<uint32_t>(this->ScissorRect.GetLeft()), static_cast<uint32_t>(this->ScissorRect.GetBottom()), static_cast<uint32_t>(this->ScissorRect.GetWidth()), - static_cast<uint32_t>(this->ScissorRect.GetWidth())); + static_cast<uint32_t>(this->ScissorRect.GetHeight())); this->UseScissor = false; } else { rpassEncoder.SetScissorRect( - 0u, 0u, static_cast<uint32_t>(width), static_cast<uint32_t>(height)); + lowerLeft[0], lowerLeft[1], static_cast<uint32_t>(width), static_cast<uint32_t>(height)); + } + if ((renderer->GetRenderWindow())->GetErase() && renderer->GetErase()) + { + renderer->Clear(); } } diff --git a/Rendering/WebGPU/vtkWebGPUClearDrawPass.cxx b/Rendering/WebGPU/vtkWebGPUClearDrawPass.cxx index 33c33ac07cc734baaec2d5de9497edfa91be4219..7fac2cce1c94a450273ed30afddc4b5261f35216 100644 --- a/Rendering/WebGPU/vtkWebGPUClearDrawPass.cxx +++ b/Rendering/WebGPU/vtkWebGPUClearDrawPass.cxx @@ -7,7 +7,6 @@ #include "vtkRenderState.h" #include "vtkRenderer.h" #include "vtkWebGPURenderWindow.h" -#include <chrono> VTK_ABI_NAMESPACE_BEGIN @@ -29,7 +28,6 @@ void vtkWebGPUClearDrawPass::PrintSelf(ostream& os, vtkIndent indent) //------------------------------------------------------------------------------ wgpu::RenderPassEncoder vtkWebGPUClearDrawPass::Begin(const vtkRenderState* state) { - auto renderer = state->GetRenderer(); auto wgpuRenderWindow = vtkWebGPURenderWindow::SafeDownCast(state->GetRenderer()->GetRenderWindow()); @@ -39,17 +37,8 @@ wgpu::RenderPassEncoder vtkWebGPUClearDrawPass::Begin(const vtkRenderState* stat wgpu::TextureView depthStencilView = wgpuRenderWindow->GetDepthStencilView(); vtkWebGPURenderPassDescriptorInternals renderPassDescriptor( - backBufferViews, depthStencilView, this->DoClear); + backBufferViews, depthStencilView, this->ClearColor, this->ClearDepth, this->ClearStencil); renderPassDescriptor.label = "vtkWebGPUClearDrawPass::Begin"; - - double* bgColor = renderer->GetBackground(); - for (auto& colorAttachment : renderPassDescriptor.ColorAttachments) - { - colorAttachment.clearValue.r = bgColor[0]; - colorAttachment.clearValue.g = bgColor[1]; - colorAttachment.clearValue.b = bgColor[2]; - colorAttachment.clearValue.a = 1.0f; - } return wgpuRenderWindow->NewRenderPass(renderPassDescriptor); } diff --git a/Rendering/WebGPU/vtkWebGPUClearDrawPass.h b/Rendering/WebGPU/vtkWebGPUClearDrawPass.h index 0eb945c666dbd9ba5599e5cba26d166238032606..b205bd2919cd978c518811c515da81e4ab4b3b97 100644 --- a/Rendering/WebGPU/vtkWebGPUClearDrawPass.h +++ b/Rendering/WebGPU/vtkWebGPUClearDrawPass.h @@ -19,12 +19,31 @@ public: ///@{ /** - * Get/set the DoClear attribute. If true this clear pass will clear the color and depth buffer - * before rendering. Il false, this pass will render on top of the existing color and depth buffer + * Get/set the ClearColor attribute. If true this clear pass will clear the color buffer + * before rendering. If false, this pass will render on top of the existing color buffer */ - vtkGetMacro(DoClear, bool); - vtkSetMacro(DoClear, bool); + vtkGetMacro(ClearColor, bool); + vtkSetMacro(ClearColor, bool); ///@} + + ///@{ + /** + * Get/set the ClearDepth attribute. If true this clear pass will clear the depth buffer + * before rendering. If false, this pass will render on top of the existing depth buffer + */ + vtkGetMacro(ClearDepth, bool); + vtkSetMacro(ClearDepth, bool); + ///@} + + ///@{ + /** + * Get/set the ClearStencil attribute. If true this clear pass will clear the stencil buffer + * before rendering. If false, this pass will render on top of the existing stencil buffer + */ + vtkGetMacro(ClearStencil, bool); + vtkSetMacro(ClearStencil, bool); + ///@} + wgpu::RenderPassEncoder Begin(const vtkRenderState* state) override; protected: @@ -32,7 +51,9 @@ protected: ~vtkWebGPUClearDrawPass() override; private: - bool DoClear = true; + bool ClearColor = true; + bool ClearDepth = true; + bool ClearStencil = true; vtkWebGPUClearDrawPass(const vtkWebGPUClearDrawPass&) = delete; void operator=(const vtkWebGPUClearDrawPass&) = delete; diff --git a/Rendering/WebGPU/vtkWebGPUPolyDataMapper.cxx b/Rendering/WebGPU/vtkWebGPUPolyDataMapper.cxx index ffc9151f01df9f12b662437b86cb6c3849d92960..d47750841b29ad299b710e3b357989da1adfce2b 100644 --- a/Rendering/WebGPU/vtkWebGPUPolyDataMapper.cxx +++ b/Rendering/WebGPU/vtkWebGPUPolyDataMapper.cxx @@ -282,7 +282,6 @@ void vtkWebGPUPolyDataMapper::RenderPiece(vtkRenderer* renderer, vtkActor* actor const auto device = wgpuRenderWindow->GetDevice(); auto* wgpuConfiguration = wgpuRenderWindow->GetWGPUConfiguration(); - auto* wgpuActor = reinterpret_cast<vtkWebGPUActor*>(actor); auto* wgpuRenderer = vtkWebGPURenderer::SafeDownCast(renderer); auto* displayProperty = actor->GetProperty(); @@ -304,16 +303,16 @@ void vtkWebGPUPolyDataMapper::RenderPiece(vtkRenderer* renderer, vtkActor* actor wgpuConfiguration, mesh, /*representation=*/VTK_POINTS); } // setup graphics pipeline - if (this->GetNeedToRebuildGraphicsPipelines(actor)) + if (this->GetNeedToRebuildGraphicsPipelines(actor, renderer)) { // render bundle must reference new bind groups and/or pipelines - wgpuActor->SetBundleInvalidated(true); + wgpuRenderer->InvalidateBundle(); this->SetupGraphicsPipelines(device, renderer, actor); } // invalidate render bundle when any of the cached properties of an actor have changed. - if (this->CacheActorProperties(actor)) + if (this->CacheActorRendererProperties(actor, renderer)) { - wgpuActor->SetBundleInvalidated(true); + wgpuRenderer->InvalidateBundle(); } break; } @@ -333,16 +332,17 @@ void vtkWebGPUPolyDataMapper::RenderPiece(vtkRenderer* renderer, vtkActor* actor } //------------------------------------------------------------------------------ -bool vtkWebGPUPolyDataMapper::CacheActorProperties(vtkActor* actor) +bool vtkWebGPUPolyDataMapper::CacheActorRendererProperties(vtkActor* actor, vtkRenderer* renderer) { - auto it = this->CachedActorProperties.find(actor); + const auto key = std::make_pair(actor, renderer); + auto it = this->CachedActorRendererProperties.find(key); auto* displayProperty = actor->GetProperty(); bool hasTranslucentPolygonalGeometry = false; if (actor) { hasTranslucentPolygonalGeometry = actor->HasTranslucentPolygonalGeometry(); } - if (it == this->CachedActorProperties.end()) + if (it == this->CachedActorRendererProperties.end()) { ActorState state = {}; state.LastActorBackfaceCulling = displayProperty->GetBackfaceCulling(); @@ -350,7 +350,7 @@ bool vtkWebGPUPolyDataMapper::CacheActorProperties(vtkActor* actor) state.LastRepresentation = displayProperty->GetRepresentation(); state.LastVertexVisibility = displayProperty->GetVertexVisibility(); state.LastHasRenderingTranslucentGeometry = hasTranslucentPolygonalGeometry; - this->CachedActorProperties[actor] = state; + this->CachedActorRendererProperties[key] = state; return true; } else @@ -1257,7 +1257,7 @@ void vtkWebGPUPolyDataMapper::UpdateMeshGeometryBuffers(vtkWebGPURenderWindow* w vtkCellData* cellData = this->CurrentInput->GetCellData(); vtkDataArray* cellColors = nullptr; - vtkNew<vtkUnsignedCharArray> cellColorsFromFieldData; + vtkSmartPointer<vtkUnsignedCharArray> cellColorsFromFieldData; if (this->HasCellAttributes[CELL_COLORS]) { // are we using a single color value replicated over all cells? @@ -1265,6 +1265,7 @@ void vtkWebGPUPolyDataMapper::UpdateMeshGeometryBuffers(vtkWebGPURenderWindow* w { const vtkIdType numCells = this->CurrentInput->GetNumberOfCells(); const int numComponents = this->Colors->GetNumberOfComponents(); + cellColorsFromFieldData = vtk::TakeSmartPointer(vtkUnsignedCharArray::New()); cellColorsFromFieldData->SetNumberOfComponents(numComponents); cellColorsFromFieldData->SetNumberOfTuples(numCells); for (int i = 0; i < numComponents; ++i) @@ -1377,19 +1378,23 @@ void vtkWebGPUPolyDataMapper::UpdateMeshGeometryBuffers(vtkWebGPURenderWindow* w } } - const std::string meshAttrDescriptorLabel = - "MeshAttributeDescriptor-" + this->CurrentInput->GetObjectDescription(); - if (this->AttributeDescriptorBuffer == nullptr) - { - this->AttributeDescriptorBuffer = wgpuConfiguration->CreateBuffer(sizeof(meshAttrDescriptor), - wgpu::BufferUsage::Storage | wgpu::BufferUsage::CopyDst, - /*mappedAtCreation=*/false, meshAttrDescriptorLabel.c_str()); - } // handle partial updates if (updatePointDescriptor || updateCellArrayDescriptor) { + const std::string meshAttrDescriptorLabel = + "MeshAttributeDescriptor-" + this->CurrentInput->GetObjectDescription(); + if (this->AttributeDescriptorBuffer == nullptr) + { + this->AttributeDescriptorBuffer = wgpuConfiguration->CreateBuffer(sizeof(meshAttrDescriptor), + wgpu::BufferUsage::Storage | wgpu::BufferUsage::CopyDst, + /*mappedAtCreation=*/false, meshAttrDescriptorLabel.c_str()); + } wgpuConfiguration->WriteBuffer(this->AttributeDescriptorBuffer, 0, &meshAttrDescriptor, sizeof(meshAttrDescriptor), meshAttrDescriptorLabel.c_str()); + // Create bind group for the point/cell attribute buffers. + this->MeshAttributeBindGroup = + this->CreateMeshAttributeBindGroup(wgpuConfiguration->GetDevice(), "MeshAttributeBindGroup"); + this->RebuildGraphicsPipelines = true; } vtkDebugMacro(<< ((updatePointDescriptor || updateCellArrayDescriptor) ? "rebuilt" : "") @@ -1399,13 +1404,6 @@ void vtkWebGPUPolyDataMapper::UpdateMeshGeometryBuffers(vtkWebGPURenderWindow* w << ((updatePointDescriptor || updateCellArrayDescriptor) ? " buffers" : "reuse point and cell buffers")); - if (updatePointDescriptor || updateCellArrayDescriptor) - { - // Create bind group for the point/cell attribute buffers. - this->MeshAttributeBindGroup = - this->CreateMeshAttributeBindGroup(wgpuConfiguration->GetDevice(), "MeshAttributeBindGroup"); - this->RebuildGraphicsPipelines = true; - } } //------------------------------------------------------------------------------ @@ -1833,6 +1831,7 @@ void vtkWebGPUPolyDataMapper::DispatchCellToPrimitiveComputePipeline( void vtkWebGPUPolyDataMapper::SetupGraphicsPipelines( const wgpu::Device& device, vtkRenderer* renderer, vtkActor* actor) { + auto* wgpuActor = vtkWebGPUActor::SafeDownCast(actor); auto* wgpuRenderWindow = vtkWebGPURenderWindow::SafeDownCast(renderer->GetRenderWindow()); auto* wgpuRenderer = vtkWebGPURenderer::SafeDownCast(renderer); auto* wgpuPipelineCache = wgpuRenderWindow->GetWGPUPipelineCache(); @@ -1862,6 +1861,7 @@ void vtkWebGPUPolyDataMapper::SetupGraphicsPipelines( std::vector<wgpu::BindGroupLayout> bgls; wgpuRenderer->PopulateBindgroupLayouts(bgls); + wgpuActor->PopulateBindgroupLayouts(bgls); bgls.emplace_back( this->CreateMeshAttributeBindGroupLayout(device, "MeshAttributeBindGroupLayout")); bgls.emplace_back(this->CreateTopologyBindGroupLayout(device, "TopologyBindGroupLayout")); @@ -1885,14 +1885,16 @@ void vtkWebGPUPolyDataMapper::SetupGraphicsPipelines( } //------------------------------------------------------------------------------ -bool vtkWebGPUPolyDataMapper::GetNeedToRebuildGraphicsPipelines(vtkActor* actor) +bool vtkWebGPUPolyDataMapper::GetNeedToRebuildGraphicsPipelines( + vtkActor* actor, vtkRenderer* renderer) { if (this->RebuildGraphicsPipelines) { return true; } - auto it = this->CachedActorProperties.find(actor); - if (it == this->CachedActorProperties.end()) + const auto key = std::make_pair(actor, renderer); + auto it = this->CachedActorRendererProperties.find(key); + if (it == this->CachedActorRendererProperties.end()) { return true; } @@ -1939,7 +1941,7 @@ void vtkWebGPUPolyDataMapper::ReleaseGraphicsResources(vtkWindow* w) this->IndirectDrawBufferUploadTimeStamp[i] = vtkTimeStamp(); } this->RebuildGraphicsPipelines = true; - this->CachedActorProperties.clear(); + this->CachedActorRendererProperties.clear(); } //------------------------------------------------------------------------------ diff --git a/Rendering/WebGPU/vtkWebGPUPolyDataMapper.h b/Rendering/WebGPU/vtkWebGPUPolyDataMapper.h index 30c4aa4375aa0ee9c6964e23a563add20be86244..9c7e5dfb962b2ecd0b3cbc74cc1c31c9c355258e 100644 --- a/Rendering/WebGPU/vtkWebGPUPolyDataMapper.h +++ b/Rendering/WebGPU/vtkWebGPUPolyDataMapper.h @@ -7,6 +7,7 @@ #include "vtkProperty.h" // for VTK_SURFACE constants #include "vtkRenderingWebGPUModule.h" // for export macro +#include "vtkWeakPointer.h" // for vtkWeakPointer #include "vtkWebGPUComputePipeline.h" // for ivar #include "vtk_wgpu.h" // for webgpu @@ -203,7 +204,7 @@ protected: * This method returns true if the cached properties have changed or the properties of the actor * are cached for the first time, false otherwise. */ - bool CacheActorProperties(vtkActor* actor); + bool CacheActorRendererProperties(vtkActor* actor, vtkRenderer* renderer); /** * Record draw calls in the render pass encoder. It also sets the bind group, graphics pipeline to @@ -437,7 +438,7 @@ protected: * This method checks MTime of the vtkActor's vtkProperty instance against the build timestamp of * the graphics pipeline. */ - bool GetNeedToRebuildGraphicsPipelines(vtkActor* actor); + bool GetNeedToRebuildGraphicsPipelines(vtkActor* actor, vtkRenderer* renderer); struct MeshAttributeBuffers { @@ -542,7 +543,8 @@ protected: int LastRepresentation = VTK_SURFACE; bool LastHasRenderingTranslucentGeometry = false; }; - std::map<vtkWeakPointer<vtkActor>, ActorState> CachedActorProperties; + std::map<std::pair<vtkWeakPointer<vtkActor>, vtkWeakPointer<vtkRenderer>>, ActorState> + CachedActorRendererProperties; private: friend class vtkWebGPUComputeRenderBuffer; diff --git a/Rendering/WebGPU/vtkWebGPURenderWindow.cxx b/Rendering/WebGPU/vtkWebGPURenderWindow.cxx index fdaa98faf9c5f2348f0634e308dcd684492c2e3f..5ded0108e8c9246e2acdcc43c547df99940e3008 100644 --- a/Rendering/WebGPU/vtkWebGPURenderWindow.cxx +++ b/Rendering/WebGPU/vtkWebGPURenderWindow.cxx @@ -590,7 +590,6 @@ void vtkWebGPURenderWindow::CreateFSQGraphicsPipeline() wgpu::ShaderModule shaderModule = vtkWebGPUShaderModuleInternals::CreateFromWGSL(device, R"( struct VertexOutput { @builtin(position) position: vec4<f32>, - @location(0) uv: vec2<f32> } @vertex @@ -603,22 +602,20 @@ void vtkWebGPURenderWindow::CreateFSQGraphicsPipeline() vec2<f32>( 1, 1) // top-right ); output.position = vec4<f32>(coords[vertex_id].xy, 1.0, 1.0); - output.uv = output.position.xy * 0.5 + 0.5; - // fip y for texture coordinate. - output.uv.y = 1.0 - output.uv.y; return output; } struct FragmentInput { @builtin(position) position: vec4<f32>, - @location(0) uv: vec2<f32> } @group(0) @binding(0) var fsqTexture: texture_2d<f32>; @fragment fn fragmentMain(fragment: FragmentInput) -> @location(0) vec4<f32> { - let color = textureLoad(fsqTexture, vec2<i32>(fragment.position.xy), 0); + let dims = textureDimensions(fsqTexture); + let texCoord = vec2(u32(fragment.position.x), dims.y - 1u - u32(fragment.position.y)); + let color = textureLoad(fsqTexture, texCoord, 0); return vec4<f32>(color); } )"); diff --git a/Rendering/WebGPU/vtkWebGPURenderer.cxx b/Rendering/WebGPU/vtkWebGPURenderer.cxx index 3221de34516b87d46b0a3a12b914045fe58ace5e..75777e2d12672e3337558c508ca6e86ecfa5212f 100644 --- a/Rendering/WebGPU/vtkWebGPURenderer.cxx +++ b/Rendering/WebGPU/vtkWebGPURenderer.cxx @@ -3,8 +3,8 @@ #include "vtkWebGPURenderer.h" #include "Private/vtkWebGPUBindGroupInternals.h" #include "Private/vtkWebGPUBindGroupLayoutInternals.h" -#include "Private/vtkWebGPUBufferInternals.h" #include "Private/vtkWebGPUComputePassInternals.h" +#include "Private/vtkWebGPURenderPipelineDescriptorInternals.h" #include "vtkAbstractMapper.h" #include "vtkFrameBufferObjectBase.h" #include "vtkHardwareSelector.h" @@ -30,6 +30,53 @@ VTK_ABI_NAMESPACE_BEGIN +namespace +{ +const char* backgroundShaderSource = R"( + struct VertexOutput { + @builtin(position) position: vec4<f32>, + } + + @vertex + fn vertexMain(@builtin(vertex_index) vertex_id: u32) -> VertexOutput { + var output: VertexOutput; + var coords: array<vec2<f32>, 4> = array<vec2<f32>, 4>( + vec2<f32>(-1, -1), // bottom-left + vec2<f32>(-1, 1), // top-left + vec2<f32>( 1, -1), // bottom-right + vec2<f32>( 1, 1) // top-right + ); + output.position = vec4<f32>(coords[vertex_id].xy, 1.0, 1.0); + return output; + } + + struct FragmentInput { + @builtin(position) position: vec4<f32> + }; + struct FragmentOutput { + @location(0) color: vec4<f32> + }; + + @fragment + fn fragmentMain() -> FragmentOutput { + var output: FragmentOutput; + output.color = vec4<f32>(1, 1, 1, 1); + return output; + } + )"; + +vtkWebGPURenderPass* MakeClearDrawPass() +{ + auto* pass = vtkWebGPUClearDrawPass::New(); + // do not clear color because doing so would erase the contents of the entire + // color attachment, including other renderer's viewports! + pass->SetClearColor(false); + pass->SetClearDepth(false); + pass->SetClearStencil(false); + return pass; +} +} + //------------------------------------------------------------------------------ vtkStandardNewMacro(vtkWebGPURenderer); @@ -92,32 +139,6 @@ std::size_t vtkWebGPURenderer::WriteLightsBuffer(std::size_t offset /*=0*/) return wroteBytes; } -//------------------------------------------------------------------------------ -std::size_t vtkWebGPURenderer::WriteActorBlocksBuffer(std::size_t offset /*=0*/) -{ - std::size_t wroteBytes = 0; - auto* wgpuRenderWindow = vtkWebGPURenderWindow::SafeDownCast(this->GetRenderWindow()); - auto* wgpuConfiguration = wgpuRenderWindow->GetWGPUConfiguration(); - - const auto size = vtkWebGPUConfiguration::Align(vtkWebGPUActor::GetCacheSizeBytes(), 256); - std::vector<uint8_t> stage; - stage.resize(this->Props->GetNumberOfItems() * size); - vtkProp* aProp = nullptr; - vtkCollectionSimpleIterator piter; - for (this->Props->InitTraversal(piter); (aProp = this->Props->GetNextProp(piter));) - { - vtkWebGPUActor* wgpuActor = reinterpret_cast<vtkWebGPUActor*>(aProp); - assert(wgpuActor != nullptr); - - const auto data = wgpuActor->GetCachedActorInformation(); - std::memcpy(&stage[wroteBytes], data, size); - wroteBytes += size; - } - wgpuConfiguration->WriteBuffer( - this->ActorBlocksBuffer, offset, stage.data(), wroteBytes, "ActorInformation"); - return wroteBytes; -} - //------------------------------------------------------------------------------ void vtkWebGPURenderer::CreateBuffers() { @@ -128,15 +149,9 @@ void vtkWebGPURenderer::CreateBuffers() + this->LightIDs.size() * vtkWebGPULight::GetCacheSizeBytes(); const auto lightSizePadded = vtkWebGPUConfiguration::Align(lightSize, 32); - // use padded for actor because dynamic offsets are used. - const auto actorBlkSize = vtkMath::Max<std::size_t>(this->Props->GetNumberOfItems() * - vtkWebGPUConfiguration::Align(vtkWebGPUActor::GetCacheSizeBytes(), 256), - 256); - auto* wgpuRenderWindow = vtkWebGPURenderWindow::SafeDownCast(this->GetRenderWindow()); auto* wgpuConfiguration = wgpuRenderWindow->GetWGPUConfiguration(); bool createSceneBindGroup = false; - bool createActorBindGroup = false; if (this->SceneTransformBuffer == nullptr) { @@ -154,46 +169,65 @@ void vtkWebGPURenderer::CreateBuffers() createSceneBindGroup = true; } - if (actorBlkSize != this->LastActorBufferSize) - { - if (this->ActorBlocksBuffer != nullptr) - { - this->ActorBlocksBuffer.Destroy(); - this->ActorBlocksBuffer = nullptr; - } - } - if (this->ActorBlocksBuffer == nullptr) + if (createSceneBindGroup) { - const std::string label = "ActorInformation-" + this->GetObjectDescription(); - this->ActorBlocksBuffer = wgpuConfiguration->CreateBuffer( - actorBlkSize, wgpu::BufferUsage::Uniform | wgpu::BufferUsage::CopyDst, false, label.c_str()); - this->LastActorBufferSize = actorBlkSize; - createActorBindGroup = true; + this->SetupSceneBindGroup(); } +} - if (createSceneBindGroup) +//------------------------------------------------------------------------------ +void vtkWebGPURenderer::Clear() +{ + if (!this->DoClearPass) { - this->SetupSceneBindGroup(); + return; } - if (createActorBindGroup) + // Draw a quad as big as viewport and colored by the background color. + auto* wgpuRenderWindow = vtkWebGPURenderWindow::SafeDownCast(this->RenderWindow); + auto* wgpuPipelineCache = wgpuRenderWindow->GetWGPUPipelineCache(); + vtkWebGPURenderPipelineDescriptorInternals bkgPipelineDescriptor; + bkgPipelineDescriptor.vertex.entryPoint = "vertexMain"; + bkgPipelineDescriptor.vertex.bufferCount = 0; + bkgPipelineDescriptor.cFragment.entryPoint = "fragmentMain"; + bkgPipelineDescriptor.cTargets[0].format = wgpuRenderWindow->GetPreferredSurfaceTextureFormat(); + + auto depthState = + bkgPipelineDescriptor.EnableDepthStencil(wgpuRenderWindow->GetDepthStencilFormat()); + depthState->depthWriteEnabled = !this->PreserveDepthBuffer; + depthState->depthCompare = wgpu::CompareFunction::Always; + + bkgPipelineDescriptor.primitive.frontFace = wgpu::FrontFace::CCW; + bkgPipelineDescriptor.primitive.cullMode = wgpu::CullMode::Front; + bkgPipelineDescriptor.primitive.topology = wgpu::PrimitiveTopology::TriangleStrip; + + for (int i = 0; i < vtkWebGPURenderPipelineDescriptorInternals::kMaxColorAttachments; ++i) { - // delete outdated info. - this->PropWGPUItems.clear(); - this->SetupActorBindGroup(); - // build new cache for bundles and dynamic offsets. - vtkProp* aProp = nullptr; - vtkCollectionSimpleIterator piter; - const auto size = vtkWebGPUConfiguration::Align(vtkWebGPUActor::GetCacheSizeBytes(), 256); - int i = 0; - for (this->Props->InitTraversal(piter); (aProp = this->Props->GetNextProp(piter)); i++) + if (this->Transparent()) + { + bkgPipelineDescriptor.cBlends[i].color.srcFactor = wgpu::BlendFactor::Zero; + bkgPipelineDescriptor.cBlends[i].color.dstFactor = wgpu::BlendFactor::One; + bkgPipelineDescriptor.cBlends[i].alpha.srcFactor = wgpu::BlendFactor::Zero; + bkgPipelineDescriptor.cBlends[i].alpha.dstFactor = wgpu::BlendFactor::One; + } + else { - vtkWGPUPropItem item; - item.Bundle = nullptr; - item.DynamicOffset = i * size; - this->PropWGPUItems.emplace(aProp, item); + bkgPipelineDescriptor.cBlends[i].color.srcFactor = wgpu::BlendFactor::Constant; + bkgPipelineDescriptor.cBlends[i].color.dstFactor = wgpu::BlendFactor::Zero; + bkgPipelineDescriptor.cBlends[i].alpha.srcFactor = wgpu::BlendFactor::Constant; + bkgPipelineDescriptor.cBlends[i].alpha.dstFactor = wgpu::BlendFactor::Zero; } } + const auto pipelineKey = + wgpuPipelineCache->GetPipelineKey(&bkgPipelineDescriptor, backgroundShaderSource); + wgpuPipelineCache->CreateRenderPipeline(&bkgPipelineDescriptor, this, backgroundShaderSource); + auto pipeline = wgpuPipelineCache->GetRenderPipeline(pipelineKey); + + this->WGPURenderEncoder.SetPipeline(pipeline); + wgpu::Color bkgColor = { this->Background[0], this->Background[1], this->Background[2], + this->BackgroundAlpha }; + this->WGPURenderEncoder.SetBlendConstant(&bkgColor); + this->WGPURenderEncoder.Draw(4); } //------------------------------------------------------------------------------ @@ -228,12 +262,24 @@ void vtkWebGPURenderer::UpdateBuffers() this->UpdateCamera(); // brings the camera's transform matrices up-to-date. this->UpdateLightGeometry(); this->UpdateLights(); + + // Render bundle is rebuilt if any mapper needs to re-record render commands. + if (this->UseRenderBundles) + { + if (this->Bundle != nullptr) + { + this->RebuildRenderBundle = false; + } + else + { + this->RebuildRenderBundle = true; + } + } this->UpdateGeometry(); // mappers prepare geometry SSBO and pipeline layout. this->CreateBuffers(); this->WriteSceneTransformsBuffer(); this->WriteLightsBuffer(); - this->WriteActorBlocksBuffer(); } //------------------------------------------------------------------------------ @@ -349,14 +395,7 @@ int vtkWebGPURenderer::UpdateOpaquePolygonalGeometry() { for (int i = 0; i < this->PropArrayCount; i++) { - auto wgpuActor = reinterpret_cast<vtkWebGPUActor*>(this->PropArray[i]); - wgpuActor->RenderOpaqueGeometry(this); - if (wgpuActor->GetBundleInvalidated()) - { - // mapper's buffers and bind points have changed. bundle is outdated. - auto& wgpuPropItem = this->PropWGPUItems[this->PropArray[i]]; - wgpuPropItem.Bundle = nullptr; - } + this->PropArray[i]->RenderOpaqueGeometry(this); } result += this->PropArrayCount; } @@ -365,69 +404,12 @@ int vtkWebGPURenderer::UpdateOpaquePolygonalGeometry() { for (int i = 0; i < this->PropArrayCount; i++) { - if (auto* wgpuActor = vtkWebGPUActor::SafeDownCast(this->PropArray[i])) - { - int rendered = 0; - auto& wgpuPropItem = this->PropWGPUItems[this->PropArray[i]]; - if (wgpuActor->SupportRenderBundles() && this->UseRenderBundles) - { - this->BundleCacheStats.TotalRequests++; - if (wgpuPropItem.Bundle == nullptr) - { - const std::string label = this->GetObjectDescription(); - auto wgpuRenderWindow = vtkWebGPURenderWindow::SafeDownCast(this->GetRenderWindow()); - const auto colorFormat = wgpuRenderWindow->GetPreferredSurfaceTextureFormat(); - const int sampleCount = - wgpuRenderWindow->GetMultiSamples() ? wgpuRenderWindow->GetMultiSamples() : 1; - wgpu::RenderBundleEncoderDescriptor bundleEncDesc; - bundleEncDesc.colorFormatCount = 1; - bundleEncDesc.colorFormats = &colorFormat; - bundleEncDesc.depthStencilFormat = wgpuRenderWindow->GetDepthStencilFormat(); - bundleEncDesc.sampleCount = sampleCount; - bundleEncDesc.depthReadOnly = false; - bundleEncDesc.stencilReadOnly = false; - bundleEncDesc.label = label.c_str(); - bundleEncDesc.nextInChain = nullptr; - this->WGPUBundleEncoder = wgpuRenderWindow->NewRenderBundleEncoder(bundleEncDesc); - this->WGPUBundleEncoder.SetBindGroup(0, this->SceneBindGroup); - this->WGPUBundleEncoder.SetBindGroup( - 1, this->ActorBindGroup, 1, &wgpuPropItem.DynamicOffset); - rendered = wgpuActor->RenderOpaqueGeometry(this); - auto bundle = this->WGPUBundleEncoder.Finish(); - this->WGPUBundleEncoder = nullptr; - if (rendered > 0) - { - wgpuPropItem.Bundle = bundle; - this->Bundles.emplace_back(wgpuPropItem.Bundle); - } - this->BundleCacheStats.Misses++; - } - else - { - // bundle gets reused for this prop. - rendered = 1; - this->Bundles.emplace_back(wgpuPropItem.Bundle); - this->BundleCacheStats.Hits++; - } - } - else - { - this->WGPURenderEncoder.SetBindGroup( - 1, this->ActorBindGroup, 1, &wgpuPropItem.DynamicOffset); - rendered = wgpuActor->RenderOpaqueGeometry(this); - } - if (rendered > 0) - { - result += rendered; - - this->NumberOfPropsRendered += rendered; - this->PropsRendered.insert(wgpuActor); - } - } - else + const int rendered = this->PropArray[i]->RenderOpaqueGeometry(this); + if (rendered > 0) { - vtkWarningMacro(<< "Prop " << this->PropArray[i]->GetObjectDescription() - << " is unrecognized in the vtkWebGPURenderer."); + result += rendered; + this->NumberOfPropsRendered += rendered; + this->PropsRendered.insert(this->PropArray[i]); } } } @@ -449,14 +431,7 @@ int vtkWebGPURenderer::UpdateTranslucentPolygonalGeometry() { for (int i = 0; i < this->PropArrayCount; i++) { - auto wgpuActor = reinterpret_cast<vtkWebGPUActor*>(this->PropArray[i]); - wgpuActor->RenderTranslucentPolygonalGeometry(this); - if (wgpuActor->GetBundleInvalidated()) - { - // mapper's buffers and bind points have changed. bundle is outdated. - auto& wgpuPropItem = this->PropWGPUItems[this->PropArray[i]]; - wgpuPropItem.Bundle = nullptr; - } + this->PropArray[i]->RenderTranslucentPolygonalGeometry(this); } result += this->PropArrayCount; } @@ -465,69 +440,12 @@ int vtkWebGPURenderer::UpdateTranslucentPolygonalGeometry() { for (int i = 0; i < this->PropArrayCount; i++) { - if (auto* wgpuActor = vtkWebGPUActor::SafeDownCast(this->PropArray[i])) + const int rendered = this->PropArray[i]->RenderTranslucentPolygonalGeometry(this); + if (rendered > 0) { - int rendered = 0; - auto& wgpuPropItem = this->PropWGPUItems[this->PropArray[i]]; - if (wgpuActor->SupportRenderBundles() && this->UseRenderBundles) - { - this->BundleCacheStats.TotalRequests++; - if (wgpuPropItem.Bundle == nullptr) - { - const std::string label = this->GetObjectDescription(); - auto wgpuRenderWindow = vtkWebGPURenderWindow::SafeDownCast(this->GetRenderWindow()); - const auto colorFormat = wgpuRenderWindow->GetPreferredSurfaceTextureFormat(); - const int sampleCount = - wgpuRenderWindow->GetMultiSamples() ? wgpuRenderWindow->GetMultiSamples() : 1; - wgpu::RenderBundleEncoderDescriptor bundleEncDesc; - bundleEncDesc.colorFormatCount = 1; - bundleEncDesc.colorFormats = &colorFormat; - bundleEncDesc.depthStencilFormat = wgpuRenderWindow->GetDepthStencilFormat(); - bundleEncDesc.sampleCount = sampleCount; - bundleEncDesc.depthReadOnly = false; - bundleEncDesc.stencilReadOnly = false; - bundleEncDesc.label = label.c_str(); - bundleEncDesc.nextInChain = nullptr; - this->WGPUBundleEncoder = wgpuRenderWindow->NewRenderBundleEncoder(bundleEncDesc); - this->WGPUBundleEncoder.SetBindGroup(0, this->SceneBindGroup); - this->WGPUBundleEncoder.SetBindGroup( - 1, this->ActorBindGroup, 1, &wgpuPropItem.DynamicOffset); - rendered = wgpuActor->RenderTranslucentPolygonalGeometry(this); - auto bundle = this->WGPUBundleEncoder.Finish(); - this->WGPUBundleEncoder = nullptr; - if (rendered > 0) - { - wgpuPropItem.Bundle = bundle; - this->Bundles.emplace_back(wgpuPropItem.Bundle); - } - this->BundleCacheStats.Misses++; - } - else - { - // bundle gets reused for this prop. - rendered = 1; - this->Bundles.emplace_back(wgpuPropItem.Bundle); - this->BundleCacheStats.Hits++; - } - } - else - { - this->WGPURenderEncoder.SetBindGroup( - 1, this->ActorBindGroup, 1, &wgpuPropItem.DynamicOffset); - rendered = wgpuActor->RenderTranslucentPolygonalGeometry(this); - } - if (rendered > 0) - { - result += rendered; - - this->NumberOfPropsRendered += rendered; - this->PropsRendered.insert(wgpuActor); - } - } - else - { - vtkWarningMacro(<< "Prop " << this->PropArray[i]->GetObjectDescription() - << " is unrecognized in the vtkWebGPURenderer."); + result += rendered; + this->NumberOfPropsRendered += rendered; + this->PropsRendered.insert(this->PropArray[i]); } } } @@ -803,17 +721,14 @@ void vtkWebGPURenderer::SetEnvironmentTexture(vtkTexture*, bool vtkNotUsed(isSRG void vtkWebGPURenderer::ReleaseGraphicsResources(vtkWindow* w) { this->Superclass::ReleaseGraphicsResources(w); - this->Bundles.clear(); - this->PropWGPUItems.clear(); + this->Bundle = nullptr; + this->WGPUBundleEncoder = nullptr; this->WGPURenderEncoder = nullptr; this->SceneTransformBuffer = nullptr; this->SceneLightsBuffer = nullptr; - this->ActorBlocksBuffer = nullptr; this->LastActorBufferSize = 0; this->SceneBindGroup = nullptr; this->SceneBindGroupLayout = nullptr; - this->ActorBindGroup = nullptr; - this->ActorBindGroupLayout = nullptr; } //------------------------------------------------------------------------------ @@ -856,6 +771,7 @@ wgpu::CommandBuffer vtkWebGPURenderer::EncodePropListRenderCommand( this->PropArrayCount = listLength; this->BeginRecording(); + this->ActiveCamera->UpdateViewport(this); this->UpdateGeometry(); this->EndRecording(); @@ -884,20 +800,39 @@ void vtkWebGPURenderer::BeginRecording() vtkRenderState state(this); state.SetPropArrayAndCount(this->PropArray, this->PropArrayCount); state.SetFrameBuffer(nullptr); - this->Pass = vtkWebGPUClearDrawPass::New(); - - vtkWebGPUClearDrawPass::SafeDownCast(this->Pass)->SetDoClear(this->DoClearPass); + this->Pass = ::MakeClearDrawPass(); this->WGPURenderEncoder = vtkWebGPURenderPass::SafeDownCast(this->Pass)->Begin(&state); #ifndef NDEBUG this->WGPURenderEncoder.PushDebugGroup("Renderer start encoding"); #endif this->WGPURenderEncoder.SetBindGroup(0, this->SceneBindGroup); - - this->Bundles.clear(); - this->BundleCacheStats.TotalRequests = 0; - this->BundleCacheStats.Hits = 0; - this->BundleCacheStats.Misses = 0; + if (this->RebuildRenderBundle) + { + // destroy previous bundle. + this->Bundle = nullptr; + // create a new bundle encoder. + const std::string label = this->GetObjectDescription(); + auto wgpuRenderWindow = vtkWebGPURenderWindow::SafeDownCast(this->GetRenderWindow()); + const auto colorFormat = wgpuRenderWindow->GetPreferredSurfaceTextureFormat(); + const int sampleCount = + wgpuRenderWindow->GetMultiSamples() ? wgpuRenderWindow->GetMultiSamples() : 1; + wgpu::RenderBundleEncoderDescriptor bundleEncDesc; + bundleEncDesc.colorFormatCount = 1; + bundleEncDesc.colorFormats = &colorFormat; + bundleEncDesc.depthStencilFormat = wgpuRenderWindow->GetDepthStencilFormat(); + bundleEncDesc.sampleCount = sampleCount; + bundleEncDesc.depthReadOnly = false; + bundleEncDesc.stencilReadOnly = false; + bundleEncDesc.label = label.c_str(); + bundleEncDesc.nextInChain = nullptr; + this->WGPUBundleEncoder = wgpuRenderWindow->NewRenderBundleEncoder(bundleEncDesc); + this->WGPUBundleEncoder.SetBindGroup(0, this->SceneBindGroup); + } + else + { + this->WGPUBundleEncoder = nullptr; + } } //------------------------------------------------------------------------------ @@ -919,19 +854,6 @@ void vtkWebGPURenderer::SetupBindGroupLayouts() this->SceneBindGroupLayout.SetLabel("SceneBindGroupLayout"); } - - if (this->ActorBindGroupLayout.Get() == nullptr) - { - this->ActorBindGroupLayout = vtkWebGPUBindGroupLayoutInternals::MakeBindGroupLayout(device, - { - // clang-format off - // ActorBlocks - { 0, wgpu::ShaderStage::Vertex | wgpu::ShaderStage::Fragment, wgpu::BufferBindingType::Uniform, /*hasDynamicOffsets=*/true }, - // clang-format on - }); - - this->ActorBindGroupLayout.SetLabel("ActorBindGroupLayout"); - } } //------------------------------------------------------------------------------ @@ -951,21 +873,6 @@ void vtkWebGPURenderer::SetupSceneBindGroup() this->SceneBindGroup.SetLabel("SceneBindGroup"); } -//------------------------------------------------------------------------------ -void vtkWebGPURenderer::SetupActorBindGroup() -{ - auto wgpuRenderWindow = vtkWebGPURenderWindow::SafeDownCast(this->GetRenderWindow()); - wgpu::Device device = wgpuRenderWindow->GetDevice(); - this->ActorBindGroup = - vtkWebGPUBindGroupInternals::MakeBindGroup(device, this->ActorBindGroupLayout, - { - // clang-format off - { 0, this->ActorBlocksBuffer, 0, vtkWebGPUConfiguration::Align(vtkWebGPUActor::GetCacheSizeBytes(), 256) }, - // clang-format on - }); - this->ActorBindGroup.SetLabel("ActorBindGroup"); -} - //------------------------------------------------------------------------------ void vtkWebGPURenderer::EndRecording() { @@ -973,19 +880,13 @@ void vtkWebGPURenderer::EndRecording() this->RenderStage = RenderStageEnum::Finished; if (this->UseRenderBundles) { - if (!this->Bundles.empty() && this->BundleCacheStats.TotalRequests > 0) + if (this->WGPUBundleEncoder) + { + this->Bundle = this->WGPUBundleEncoder.Finish(); + } + if (this->Bundle != nullptr) { - vtkDebugMacro(<< "Bundle cache summary:\n" - << "Total requests: " << this->BundleCacheStats.TotalRequests << "\n" - << "Hit ratio: " - << (this->BundleCacheStats.Hits / this->BundleCacheStats.TotalRequests) * 100 - << "%\n" - << "Miss ratio: " - << (this->BundleCacheStats.Misses / this->BundleCacheStats.TotalRequests) * 100 - << "%\n" - << "Hit: " << this->BundleCacheStats.Hits << "\n" - << "Miss: " << this->BundleCacheStats.Misses << "\n"); - this->WGPURenderEncoder.ExecuteBundles(this->Bundles.size(), this->Bundles.data()); + this->WGPURenderEncoder.ExecuteBundles(1, &this->Bundle); } } #ifndef NDEBUG diff --git a/Rendering/WebGPU/vtkWebGPURenderer.h b/Rendering/WebGPU/vtkWebGPURenderer.h index 69b3b90bb33b09195bdd8fc42c86be59e66422f6..8c4eae9c612b27a17438084d6a60ab67d61b37bb 100644 --- a/Rendering/WebGPU/vtkWebGPURenderer.h +++ b/Rendering/WebGPU/vtkWebGPURenderer.h @@ -10,8 +10,6 @@ #include "vtkWebGPUComputePipeline.h" // for the compute pipelines used by this renderer #include "vtk_wgpu.h" // for webgpu -#include <string> // for ivar -#include <unordered_map> // for ivar #include <unordered_set> // for the set of actors rendered last frame class vtkAbstractMapper; @@ -58,6 +56,11 @@ public: RenderPostRasterization }; + /** + * Clear the image to the background color. + */ + void Clear() override; + /** * Create an image. */ @@ -110,13 +113,11 @@ public: inline wgpu::RenderPassEncoder GetRenderPassEncoder() { return this->WGPURenderEncoder; } inline wgpu::RenderBundleEncoder GetRenderBundleEncoder() { return this->WGPUBundleEncoder; } - inline wgpu::BindGroup GetActorBindGroup() { return this->ActorBindGroup; } inline wgpu::BindGroup GetSceneBindGroup() { return this->SceneBindGroup; } inline void PopulateBindgroupLayouts(std::vector<wgpu::BindGroupLayout>& layouts) { layouts.emplace_back(this->SceneBindGroupLayout); - layouts.emplace_back(this->ActorBindGroupLayout); } /// @{ @@ -165,6 +166,19 @@ public: */ vtkGetEnumMacro(RenderStage, RenderStageEnum); + /** + * Forces the renderer to re-record draw commands into a render bundle. + * + * @note This does not use vtkSetMacro because the actor MTime should not be affected when a + * render bundle is invalidated. + */ + inline void InvalidateBundle() { this->RebuildRenderBundle = true; } + + /** + * Get whether the render bundle associated with this actor must be reset by the renderer. + */ + vtkGetMacro(RebuildRenderBundle, bool); + protected: vtkWebGPURenderer(); ~vtkWebGPURenderer() override; @@ -184,8 +198,6 @@ protected: void CreateBuffers(); // Create scene bind group. void SetupSceneBindGroup(); - // Create actor bind group. - void SetupActorBindGroup(); // Start, finish recording commands with render pass encoder void BeginRecording(); @@ -193,35 +205,23 @@ protected: std::size_t WriteLightsBuffer(std::size_t offset = 0); std::size_t WriteSceneTransformsBuffer(std::size_t offset = 0); - std::size_t WriteActorBlocksBuffer(std::size_t offset = 0); wgpu::RenderPassEncoder WGPURenderEncoder; wgpu::RenderBundleEncoder WGPUBundleEncoder; wgpu::Buffer SceneTransformBuffer; wgpu::Buffer SceneLightsBuffer; - wgpu::Buffer ActorBlocksBuffer; std::size_t LastActorBufferSize = 0; wgpu::BindGroup SceneBindGroup; wgpu::BindGroupLayout SceneBindGroupLayout; - wgpu::BindGroup ActorBindGroup; - wgpu::BindGroupLayout ActorBindGroupLayout; - #ifdef __EMSCRIPTEN__ bool UseRenderBundles = true; #else bool UseRenderBundles = false; #endif - // one bundle per actor. bundle gets reused every frame. - // these bundles can be built in parallel with vtkSMPTools. holding off because not - // sure how to get emscripten to thread. - std::vector<wgpu::RenderBundle> Bundles; - struct vtkWGPUPropItem - { - wgpu::RenderBundle Bundle = nullptr; - vtkTypeUInt32 DynamicOffset = 0; - }; - std::unordered_map<vtkProp*, vtkWGPUPropItem> PropWGPUItems; + bool RebuildRenderBundle = false; + // the commands in bundle get reused every frame. + wgpu::RenderBundle Bundle; int LightingComplexity = 0; std::size_t NumberOfLightsUsed = 0; @@ -230,13 +230,6 @@ protected: vtkMTimeType LightingUpdateTime; vtkTimeStamp LightingUploadTimestamp; - struct - { - uint32_t Hits = 0; - uint32_t Misses = 0; - uint32_t TotalRequests = 0; - } BundleCacheStats; - /** * Optional user transform for lights */ diff --git a/Rendering/WebGPU/wgsl/LineMiterJoinVertexShader.wgsl b/Rendering/WebGPU/wgsl/LineMiterJoinVertexShader.wgsl index e25057be6186d522328ec8dad66e1e44cf9f06b3..f29e73cbe1a271bad78142c7c393300d51f21cd5 100644 --- a/Rendering/WebGPU/wgsl/LineMiterJoinVertexShader.wgsl +++ b/Rendering/WebGPU/wgsl/LineMiterJoinVertexShader.wgsl @@ -85,7 +85,7 @@ struct Topology { ///------------------------------------------------------------------- // Everything shader needs from the vtkActor and it's vtkProperty ///------------------------------------------------------------------- -@group(1) @binding(0) var<uniform> actor: ActorBlock; +@group(1) @binding(0) var<storage, read> actor: ActorBlock; ///-----------------------------------------------------------------/// // Mesh attributes. diff --git a/Rendering/WebGPU/wgsl/LineRoundJoinVertexShader.wgsl b/Rendering/WebGPU/wgsl/LineRoundJoinVertexShader.wgsl index 9e81b90a26d5e0d0b2ea0f6e3f5aeb9672d7b67c..a0773d1693f1354fa46b944c389224b9aa829d06 100644 --- a/Rendering/WebGPU/wgsl/LineRoundJoinVertexShader.wgsl +++ b/Rendering/WebGPU/wgsl/LineRoundJoinVertexShader.wgsl @@ -138,7 +138,7 @@ struct Topology { ///------------------------------------------------------------------- // Everything shader needs from the vtkActor and it's vtkProperty ///------------------------------------------------------------------- -@group(1) @binding(0) var<uniform> actor: ActorBlock; +@group(1) @binding(0) var<storage, read> actor: ActorBlock; ///-----------------------------------------------------------------/// // Mesh attributes. diff --git a/Rendering/WebGPU/wgsl/PointShader.wgsl b/Rendering/WebGPU/wgsl/PointShader.wgsl index 33f217c7c99cbce79959c5d7e87226dcb7b9dbb1..193197ff5f9c43d1c55e534cd745f7bff98c33c1 100644 --- a/Rendering/WebGPU/wgsl/PointShader.wgsl +++ b/Rendering/WebGPU/wgsl/PointShader.wgsl @@ -89,7 +89,7 @@ struct Topology { ///------------------------------------------------------------------- // Everything shader needs from the vtkActor and it's vtkProperty ///------------------------------------------------------------------- -@group(1) @binding(0) var<uniform> actor: ActorBlock; +@group(1) @binding(0) var<storage, read> actor: ActorBlock; ///-----------------------------------------------------------------/// // Mesh attributes. diff --git a/Rendering/WebGPU/wgsl/SurfaceMeshShader.wgsl b/Rendering/WebGPU/wgsl/SurfaceMeshShader.wgsl index c55ba3bfed2fe4a96f67d3dc21c67cf65d0f3df3..b918631485904e23a59003f52de2e4fdff104874 100644 --- a/Rendering/WebGPU/wgsl/SurfaceMeshShader.wgsl +++ b/Rendering/WebGPU/wgsl/SurfaceMeshShader.wgsl @@ -70,7 +70,7 @@ struct Topology { ///------------------------------------------------------------------- // Everything shader needs from the vtkActor and it's vtkProperty ///------------------------------------------------------------------- -@group(1) @binding(0) var<uniform> actor: ActorBlock; +@group(1) @binding(0) var<storage, read> actor: ActorBlock; ///-----------------------------------------------------------------/// // Mesh attributes.