From f3e89550058d9f29bf011163033844d0bb6d9643 Mon Sep 17 00:00:00 2001 From: Joachim Pouderoux <joachim.pouderoux@perception4d.com> Date: Tue, 14 Jun 2022 13:09:05 +1100 Subject: [PATCH] Allow the shader code to set the point size --- Rendering/OpenGL2/Testing/Cxx/CMakeLists.txt | 1 + .../Testing/Cxx/TestProgramPointSize.cxx | 77 +++++++++++++++++++ .../Baseline/TestProgramPointSize.png.sha512 | 1 + Rendering/OpenGL2/vtkOpenGLPolyDataMapper.cxx | 17 ++++ Rendering/OpenGL2/vtkOpenGLPolyDataMapper.h | 13 ++++ 5 files changed, 109 insertions(+) create mode 100644 Rendering/OpenGL2/Testing/Cxx/TestProgramPointSize.cxx create mode 100644 Rendering/OpenGL2/Testing/Data/Baseline/TestProgramPointSize.png.sha512 diff --git a/Rendering/OpenGL2/Testing/Cxx/CMakeLists.txt b/Rendering/OpenGL2/Testing/Cxx/CMakeLists.txt index 6ea5bdf60b8..db4d6511634 100644 --- a/Rendering/OpenGL2/Testing/Cxx/CMakeLists.txt +++ b/Rendering/OpenGL2/Testing/Cxx/CMakeLists.txt @@ -71,6 +71,7 @@ vtk_add_test_cxx(vtkRenderingOpenGL2CxxTests tests TestPointGaussianMapper.cxx TestPointGaussianMapperOpacity.cxx TestPointGaussianSelection.cxx,NO_DATA + TestProgramPointSize.cxx TestPropPicker2Renderers.cxx,NO_DATA TestRemoveActorNonCurrentContext.cxx TestRenderToImage.cxx diff --git a/Rendering/OpenGL2/Testing/Cxx/TestProgramPointSize.cxx b/Rendering/OpenGL2/Testing/Cxx/TestProgramPointSize.cxx new file mode 100644 index 00000000000..eb7d1b2cfe1 --- /dev/null +++ b/Rendering/OpenGL2/Testing/Cxx/TestProgramPointSize.cxx @@ -0,0 +1,77 @@ +/*========================================================================= + + Program: Visualization Toolkit + + Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen + All rights reserved. + See Copyright.txt or http://www.kitware.com/Copyright.htm for details. + + This software is distributed WITHOUT ANY WARRANTY; without even + the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + PURPOSE. See the above copyright notice for more information. + +=========================================================================*/ + +#include "vtkActor.h" +#include "vtkCamera.h" +#include "vtkNew.h" +#include "vtkOpenGLPolyDataMapper.h" +#include "vtkOpenGLRenderWindow.h" +#include "vtkProperty.h" +#include "vtkRegressionTestImage.h" +#include "vtkRenderer.h" +#include "vtkShaderProperty.h" +#include "vtkSphereSource.h" +#include "vtkTestUtilities.h" + +#include "vtkRenderWindowInteractor.h" + +#include "vtkOpenGLRenderWindow.h" + +//------------------------------------------------------------------------------ +int TestProgramPointSize(int argc, char* argv[]) +{ + vtkNew<vtkRenderer> renderer; + renderer->SetBackground(0.0, 0.0, 0.0); + vtkNew<vtkRenderWindow> renderWindow; + renderWindow->SetSize(300, 300); + renderWindow->AddRenderer(renderer); + vtkNew<vtkRenderWindowInteractor> iren; + iren->SetRenderWindow(renderWindow); + + vtkNew<vtkSphereSource> sphere; + sphere->SetThetaResolution(16); + sphere->SetPhiResolution(16); + + vtkNew<vtkOpenGLPolyDataMapper> mapper; + mapper->SetInputConnection(sphere->GetOutputPort()); + mapper->UseProgramPointSizeOn(); + vtkNew<vtkActor> actor; + renderer->AddActor(actor); + actor->SetMapper(mapper); + actor->GetProperty()->SetRepresentationToPoints(); + + vtkShaderProperty* sp = actor->GetShaderProperty(); + sp->AddVertexShaderReplacement("//VTK::ValuePass::Impl", // replace the normal block + true, // before the standard replacements + "gl_PointSize = (1.0 - gl_Position.z) * 8.0;\n" + "///VTK::ValuePass::Impl\n", // we still want the default + false // only do it once + ); + + renderWindow->SetMultiSamples(0); + renderer->ResetCamera(); + renderer->GetActiveCamera()->Elevation(-45); + renderer->GetActiveCamera()->OrthogonalizeViewUp(); + renderer->GetActiveCamera()->Zoom(1.5); + renderer->ResetCameraClippingRange(); + renderWindow->Render(); + + int retVal = vtkRegressionTestImageThreshold(renderWindow, 0.5); + if (retVal == vtkRegressionTester::DO_INTERACTOR) + { + iren->Start(); + } + + return !retVal; +} diff --git a/Rendering/OpenGL2/Testing/Data/Baseline/TestProgramPointSize.png.sha512 b/Rendering/OpenGL2/Testing/Data/Baseline/TestProgramPointSize.png.sha512 new file mode 100644 index 00000000000..7cd47225f6c --- /dev/null +++ b/Rendering/OpenGL2/Testing/Data/Baseline/TestProgramPointSize.png.sha512 @@ -0,0 +1 @@ +21903f28c760e11b3775bb702a9ceb46f50a76c84520bfed90394eb1c3bca0d62cc5928801d874a29c243d7adca5042423a355b5bc7bfbb17a81372e374dc220 diff --git a/Rendering/OpenGL2/vtkOpenGLPolyDataMapper.cxx b/Rendering/OpenGL2/vtkOpenGLPolyDataMapper.cxx index bbe25ee4eeb..0370fd64f79 100644 --- a/Rendering/OpenGL2/vtkOpenGLPolyDataMapper.cxx +++ b/Rendering/OpenGL2/vtkOpenGLPolyDataMapper.cxx @@ -96,6 +96,7 @@ vtkOpenGLPolyDataMapper::vtkOpenGLPolyDataMapper() this->DrawingVertices = false; this->ForceTextureCoordinates = false; this->SelectionType = VTK_POINTS; + this->UseProgramPointSize = false; this->PrimitiveIDOffset = 0; this->ShiftScaleMethod = vtkOpenGLVertexBufferObject::AUTO_SHIFT_SCALE; @@ -3287,6 +3288,13 @@ void vtkOpenGLPolyDataMapper::RenderPieceStart(vtkRenderer* ren, vtkActor* actor vtkOpenGLState* ostate = renWin->GetState(); ostate->vtkglPointSize(actor->GetProperty()->GetPointSize()); +#ifdef GL_PROGRAM_POINT_SIZE + if (this->UseProgramPointSize) + { + ostate->vtkglEnable(GL_PROGRAM_POINT_SIZE); + } +#endif + // timer calls take time, for lots of "small" actors // the timer can be a big hit. So we only update // once per million cells or every 100 renders @@ -3434,6 +3442,15 @@ void vtkOpenGLPolyDataMapper::RenderPieceDraw(vtkRenderer* ren, vtkActor* actor) //------------------------------------------------------------------------------ void vtkOpenGLPolyDataMapper::RenderPieceFinish(vtkRenderer* ren, vtkActor*) { +#ifdef GL_PROGRAM_POINT_SIZE + if (this->UseProgramPointSize) + { + vtkOpenGLRenderWindow* renWin = static_cast<vtkOpenGLRenderWindow*>(ren->GetRenderWindow()); + vtkOpenGLState* ostate = renWin->GetState(); + ostate->vtkglDisable(GL_PROGRAM_POINT_SIZE); + } +#endif + vtkHardwareSelector* selector = ren->GetSelector(); // render points for point picking in a special way if (selector && selector->GetFieldAssociation() == vtkDataObject::FIELD_ASSOCIATION_POINTS) diff --git a/Rendering/OpenGL2/vtkOpenGLPolyDataMapper.h b/Rendering/OpenGL2/vtkOpenGLPolyDataMapper.h index d6a37e8e875..c4e76e1a11a 100644 --- a/Rendering/OpenGL2/vtkOpenGLPolyDataMapper.h +++ b/Rendering/OpenGL2/vtkOpenGLPolyDataMapper.h @@ -162,6 +162,18 @@ public: vtkGetMacro(PauseShiftScale, bool); vtkBooleanMacro(PauseShiftScale, bool); + /** + * Allow the shader code to set the point size (with gl_PointSize variable) + * instead of using the one defined by the property. Note that this flag is + * not available on OpenGLES as the feature is enabled by default. With + * OpenGL, the feature is turned off by default. + * Warning: on MacOS, enabling the feature result in non point drawing + * if the shaders do not set the point size. + */ + vtkGetMacro(UseProgramPointSize, bool); + vtkSetMacro(UseProgramPointSize, bool); + vtkBooleanMacro(UseProgramPointSize, bool); + enum PrimitiveTypes { PrimitiveStart = 0, @@ -440,6 +452,7 @@ protected: vtkNew<vtkMatrix4x4> VBOShiftScale; int ShiftScaleMethod; // for points bool PauseShiftScale; + bool UseProgramPointSize; // if set to true, tcoords will be passed to the // VBO even if the mapper knows of no texture maps -- GitLab