Files
UnrealEngine/Engine/Source/ThirdParty/MaterialX/MaterialX-1.38.10/source/MaterialXRenderGlsl/GlslProgram.h
2025-05-18 13:04:45 +08:00

277 lines
8.7 KiB
C++

//
// 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 <MaterialXRenderGlsl/Export.h>
#include <MaterialXRender/Camera.h>
#include <MaterialXRender/GeometryHandler.h>
#include <MaterialXRender/ImageHandler.h>
#include <MaterialXRender/LightHandler.h>
#include <MaterialXGenShader/Shader.h>
MATERIALX_NAMESPACE_BEGIN
// Shared pointer to a GlslProgram
using GlslProgramPtr = std::shared_ptr<class GlslProgram>;
/// @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<Input>;
/// Program input shaded pointer map type
using InputMap = std::unordered_map<string, InputPtr>;
/// 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<string, unsigned int> _attributeBufferIds;
// Attribute indexing buffer handle
std::map<MeshPartitionPtr, unsigned int> _indexBufferIds;
// Attribute vertex array handle
unsigned int _vertexArray;
// Currently bound mesh
MeshPtr _boundMesh;
// Program texture map
std::unordered_map<string, unsigned int> _programTextures;
// Enabled vertex stream program locations
std::set<int> _enabledStreamLocations;
};
MATERIALX_NAMESPACE_END
#endif