// // Copyright Contributors to the MaterialX Project // SPDX-License-Identifier: Apache-2.0 // #ifndef MATERIALX_GLSLPROGRAM_H #define MATERIALX_GLSLPROGRAM_H /// @file /// GLSL Program interfaces #include #include #include #include #include #include MATERIALX_NAMESPACE_BEGIN // Shared pointer to a GlslProgram using GlslProgramPtr = std::shared_ptr; /// @class GlslProgram /// A class representing an executable GLSL program. /// /// There are two main interfaces which can be used. One which takes in a HwShader and one which /// allows for explicit setting of shader stage code. class MX_RENDERGLSL_API GlslProgram { public: /// Create a GLSL program instance static GlslProgramPtr create() { return GlslProgramPtr(new GlslProgram()); } /// Destructor virtual ~GlslProgram(); /// @name Shader code setup /// @{ /// Set up code stages to validate based on an input hardware shader. /// @param shader Hardware shader to use void setStages(ShaderPtr shader); /// Set the code stages based on a list of stage strings. /// Refer to the ordering of stages as defined by a HwShader. /// @param stage Name of the shader stage. /// @param sourceCode Source code of the shader stage. void addStage(const string& stage, const string& sourceCode); /// Get source code string for a given stage. /// @return Shader stage string. String is empty if not found. const string& getStageSourceCode(const string& stage) const; /// Return the shader, if any, used to generate this program. ShaderPtr getShader() const { return _shader; } /// @} /// @name Program building /// @{ /// Build shader program data from the source code set for /// each shader stage. /// /// An exception is thrown if the program cannot be built. /// The exception will contain a list of compilation errors. void build(); /// Return true if built shader program data is present. bool hasBuiltData(); // Clear built shader program data, if any. void clearBuiltData(); /// @} /// @name Program introspection /// @{ /// Structure to hold information about program inputs. /// The structure is populated by directly scanning the program so may not contain /// some inputs listed on any associated HwShader as those inputs may have been /// optimized out if they are unused. struct MX_RENDERGLSL_API Input { static int INVALID_OPENGL_TYPE; /// Program location. -1 means an invalid location int location; /// OpenGL type of the input. -1 means an invalid type int gltype; /// Size. int size; /// Input type string. Will only be non-empty if initialized stages with a HwShader string typeString; /// Input value. Will only be non-empty if initialized stages with a HwShader and a value was set during /// shader generation. MaterialX::ValuePtr value; /// Is this a constant bool isConstant; /// Element path (if any) string path; /// Unit string unit; /// Colorspace string colorspace; /// Program input constructor Input(int inputLocation, int inputType, int inputSize, const string& inputPath) : location(inputLocation), gltype(inputType), size(inputSize), isConstant(false), path(inputPath) { } }; /// Program input structure shared pointer type using InputPtr = std::shared_ptr; /// Program input shaded pointer map type using InputMap = std::unordered_map; /// Get list of program input uniforms. /// The program must have been created successfully first. /// An exception is thrown if the parsing of the program for uniforms cannot be performed. /// @return Program uniforms list. const InputMap& getUniformsList(); /// Get list of program input attributes. /// The program must have been created successfully first. /// An exception is thrown if the parsing of the program for attribute cannot be performed. /// @return Program attributes list. const InputMap& getAttributesList(); /// Find the locations in the program which starts with a given variable name /// @param variable Variable to search for /// @param variableList List of program inputs to search /// @param foundList Returned list of found program inputs. Empty if none found. /// @param exactMatch Search for exact variable name match. void findInputs(const string& variable, const InputMap& variableList, InputMap& foundList, bool exactMatch); /// @} /// @name Program activation /// @{ /// Bind the program. /// @return False if failed bool bind(); /// Return true if the program has active attributes. bool hasActiveAttributes() const; /// Return true if a uniform with the given name is present. bool hasUniform(const string& name); /// Bind a value to the uniform with the given name. void bindUniform(const string& name, ConstValuePtr value, bool errorIfMissing = true); /// Bind attribute buffers to attribute inputs. /// A hardware buffer of the given attribute type is created and bound to the program locations /// for the input attribute. /// @param inputs Attribute inputs to bind to /// @param mesh Mesh containing streams to bind void bindAttribute(const GlslProgram::InputMap& inputs, MeshPtr mesh); /// Bind input geometry partition (indexing) void bindPartition(MeshPartitionPtr partition); /// Bind input geometry streams void bindMesh(MeshPtr mesh); /// Unbind any bound geometry void unbindGeometry(); /// Bind any input textures void bindTextures(ImageHandlerPtr imageHandler); /// Bind lighting void bindLighting(LightHandlerPtr lightHandler, ImageHandlerPtr imageHandler); /// Bind view information void bindViewInformation(CameraPtr camera); /// Bind time and frame void bindTimeAndFrame(float time = 1.0f, float frame = 1.0f); /// Unbind the program. Equivalent to binding no program void unbind() const; /// @} /// @name Utilities /// @{ /// Print all uniforms to the given stream. void printUniforms(std::ostream& outputStream); /// Print all attributes to the given stream. void printAttributes(std::ostream& outputStream); /// @} public: static unsigned int UNDEFINED_OPENGL_RESOURCE_ID; static int UNDEFINED_OPENGL_PROGRAM_LOCATION; protected: GlslProgram(); // Update a list of program input uniforms const InputMap& updateUniformsList(); // Update a list of program input attributes const InputMap& updateAttributesList(); // Utility to find a uniform value in an uniform list. // If uniform cannot be found a null pointer will be return. ValuePtr findUniformValue(const string& uniformName, const InputMap& uniformList); // Bind an individual texture to a program uniform location ImagePtr bindTexture(unsigned int uniformType, int uniformLocation, const FilePath& filePath, ImageHandlerPtr imageHandler, const ImageSamplingProperties& imageProperties); // Utility to map a MaterialX type to an OpenGL type static int mapTypeToOpenGLType(const TypeDesc* type); // Bind a value to the uniform at the given location. void bindUniformLocation(int location, ConstValuePtr value); private: // Stages used to create program // Map of stage name and its source code StringMap _stages; // Generated program. A non-zero number indicates a valid shader program. unsigned int _programId; // List of program input uniforms InputMap _uniformList; // List of program input attributes InputMap _attributeList; // Hardware shader (if any) used for program creation ShaderPtr _shader; // Attribute buffer resource handles // for each attribute identifier in the program std::unordered_map _attributeBufferIds; // Attribute indexing buffer handle std::map _indexBufferIds; // Attribute vertex array handle unsigned int _vertexArray; // Currently bound mesh MeshPtr _boundMesh; // Program texture map std::unordered_map _programTextures; // Enabled vertex stream program locations std::set _enabledStreamLocations; }; MATERIALX_NAMESPACE_END #endif