// SPDX-FileCopyrightText: Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen // SPDX-License-Identifier: BSD-3-Clause /** * @class vtkGLSLModPixelDebugger * @brief Allow live pixel debugging by overwriting gl_FragData[0] output. * * This modification significantly simplifies the lives of VTK OpenGL developers, enabling them to * debug and adjust GLSL code in real-time while the application is running. * * This eliminates the need to recompile VTK for minor shader code adjustments. Developers can * conveniently keep the JSON and associated GLSL files open in a code editor, making changes while * a unit test or VTK application is actively running. Ultimately, you can just move your mouse in * the render window to witness your modifications taking effect! * * Shader substitutions will need to be defined in a json file. An example is provided in * Rendering/CellGrid/LiveGLSLDebugSample/sample.json file. If you've built VTK from source, * you may live edit that json file and glsl files under the LiveGLSLDebugSample directory. * Here is what it looks like: * { * "Substitutions": [ * { * "Target": "//VTK::Light::Impl", * "ShaderType": "Fragment", * "FileName": "normal-debug.glsl", * "ReplaceAllOccurrences": false, * "FileNameIsAbsolute": false, * "Enabled": false * }, * { * "Target": "//VTK::Light::Impl", * "ShaderType": "Fragment", * "FileName": "parametric-debug.glsl", * "ReplaceAllOccurrences": false, * "FileNameIsAbsolute": false, * "Enabled": false * } * ] * } * In the sample, both substitutions are disabled. Please enable either to view it. * Here is detailed information about the keys: * * \li \c Substitutions: This is a list of maps that contain information about a substitution. * * \li \c Target: This must be a string of type "//VTK::Feature::[Dec,Impl]". * These are found in the shader templates. * * \li \c ShaderType: This must be either "Fragment" or "Vertex" or "Geometry". * * \li \c FileName: Path to a file which has glsl code which will be pasted in place of the 'Target' * string. * * \li \c ReplaceAllOccurrences: Whether to replace all occurrences of 'Target' string with the * contents from the 'FileName' file. * * \li \c FileNameIsAbsolute: Whether 'FileName' is an absolute path or relative to the json file. * * \li \c Enabled: When enabled is true, the mod will perform the substitution, otherwise, the * substitution is not applied. */ #ifndef vtkGLSLModPixelDebugger_h #define vtkGLSLModPixelDebugger_h #include "vtkGLSLModifierBase.h" #include "vtkOpenGLRenderer.h" // for ivar #include "vtkRenderingOpenGL2Module.h" // for export macro #include "vtkStringToken.h" // for ivar VTK_ABI_NAMESPACE_BEGIN class vtkActor; class vtkInformationObjectBaseKey; class vtkOpenGLRenderer; class VTKRENDERINGOPENGL2_EXPORT vtkGLSLModPixelDebugger : public vtkGLSLModifierBase { public: static vtkGLSLModPixelDebugger* New(); vtkTypeMacro(vtkGLSLModPixelDebugger, vtkGLSLModifierBase); void PrintSelf(ostream& os, vtkIndent indent) override; /// Set this to a json file on your file system. Look inside /// Rendering/CellGrid/LiveGLSLDebugSample/ for an example. inline void SetSubstitutionJSONFileName(const std::string& filename) { this->SubstitutionJSONFileName = filename; } // vtkGLSLModifierBase virtuals: bool ReplaceShaderValues(vtkOpenGLRenderer* renderer, std::string& vertexShader, std::string& tessControlShader, std::string& tessEvalShader, std::string& geometryShader, std::string& fragmentShader, vtkAbstractMapper* mapper, vtkActor* actor) override; bool SetShaderParameters(vtkOpenGLRenderer* renderer, vtkShaderProgram* program, vtkAbstractMapper* mapper, vtkActor* actor, vtkOpenGLVertexArrayObject* VAO = nullptr) override; bool IsUpToDate(vtkOpenGLRenderer* vtkNotUsed(renderer), vtkAbstractMapper* vtkNotUsed(mapper), vtkActor* vtkNotUsed(actor)) override { return this->HashSubstitutionJSONFileContents() == this->LastSubstitutionJSONFileContentsToken && this->HashGLSLFilesContents() == this->LastGLSLFilesContentsToken; } protected: vtkGLSLModPixelDebugger(); ~vtkGLSLModPixelDebugger() override; std::string SubstitutionJSONFileName; vtkStringToken LastSubstitutionJSONFileContentsToken; // computed internally vtkStringToken LastGLSLFilesContentsToken; // computed internally vtkStringToken HashSubstitutionJSONFileContents(); vtkStringToken HashGLSLFilesContents(); private: vtkGLSLModPixelDebugger(const vtkGLSLModPixelDebugger&) = delete; void operator=(const vtkGLSLModPixelDebugger&) = delete; }; VTK_ABI_NAMESPACE_END #endif