/*****************************************************************//** * \file shader.hpp * \brief Contains functions and objects relevant to shading * * \author Robert * \date January 2021 *********************************************************************/ #ifndef SHADER_HPP #define SHADER_HPP #include namespace oglu { class Color; class AbstractTexture; class Transformable; class AmbientLight; typedef std::shared_ptr Texture; class AbstractShader; typedef std::shared_ptr Shader; /** * @brief An object representing an OpenGL Shader Program. * * This class contains the OpenGL Shader Program and supplies the user * with functions to operate on this program. * * This class cannot be instantiated, this should be done via MakeShader(const char* vertexShaderFile, const char* fragmentShaderFile). */ class OGLU_API AbstractShader { public: /** * @brief Constructs a new shader program. * * Use this function to create new shaders. * * @param[in] vertexShaderFile Filepath to the vertex shader * @param[in] fragmentShaderFile Filepath to the fragment shader * * @return A shared pointer to the shader program. */ friend Shader OGLU_API MakeShader(const char* vertexShaderFile, const char* fragmentShaderFile); /** * @brief Copy constructor. * * Copying a shader is generally possible. Since the user is given a shared pointer the * shader program is only deleted once every instance has been deconstructed. * * @param[in] other Shader to copy from */ AbstractShader(const AbstractShader& other); ~AbstractShader(); /** * @brief Use this shader. */ void Use(); /** * @brief Get the uniform location within the program. * * @param[in] name Name of the uniform * * @return Location of the uniform. */ GLint GetUniformLocation(const GLchar* name); #pragma region Uniforms /** * @brief Set uniform float. * * @param[in] name Name of the uniform * @param[in] v0 Value to set the uniform to */ void SetUniform(const GLchar* name, GLfloat v0); /** * @brief Set uniform float. * * @param[in] location Location of the uniform * @param[in] v0 Value to set the uniform to */ void SetUniform(GLint location, GLfloat v0); /** * @brief Set uniform vec2. * * @param[in] name Name of the uniform * @param[in] v0, v1 Value to set the uniform to */ void SetUniform(const GLchar* name, GLfloat v0, GLfloat v1); /** * @brief Set uniform vec2. * * @param[in] location Location of the uniform * @param[in] v0, v1 Value to set the uniform to */ void SetUniform(GLint location, GLfloat v0, GLfloat v1); /** * @brief Set uniform vec3. * * @param[in] name Name of the uniform * @param[in] v0, v1, v2 Value to set the uniform to */ void SetUniform(const GLchar* name, GLfloat v0, GLfloat v1, GLfloat v2); /** * @brief Set uniform vec3. * * @param[in] location Location of the uniform * @param[in] v0, v1, v2 Value to set the uniform to */ void SetUniform(GLint location, GLfloat v0, GLfloat v1, GLfloat v2); /** * @brief Set uniform vec4. * * @param[in] name Name of the uniform * @param[in] v0, v1, v2, v3 Value to set the uniform to */ void SetUniform(const GLchar* name, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); /** * @brief Set uniform vec4. * * @param[in] location Location of the uniform * @param[in] v0, v1, v2, v3 Value to set the uniform to */ void SetUniform(GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); /** * @brief Set uniform int. * * @param[in] name Name of the uniform * @param[in] v0 Value to set the uniform to */ void SetUniform(const GLchar* name, GLint v0); /** * @brief Set uniform int. * * @param[in] location Location of the uniform * @param[in] v0 Value to set the uniform to */ void SetUniform(GLint location, GLint v0); /** * @brief Set uniform ivec2. * * @param[in] name Name of the uniform * @param[in] v0, v1 Value to set the uniform to */ void SetUniform(const GLchar* name, GLint v0, GLint v1); /** * @brief Set uniform ivec2. * * @param[in] location Location of the uniform * @param[in] v0, v1 Value to set the uniform to */ void SetUniform(GLint location, GLint v0, GLint v1); /** * @brief Set uniform ivec3. * * @param[in] name Name of the uniform * @param[in] v0, v1, v2 Value to set the uniform to */ void SetUniform(const GLchar* name, GLint v0, GLint v1, GLint v2); /** * @brief Set uniform ivec3. * * @param[in] location Location of the uniform * @param[in] v0, v1, v2 Value to set the uniform to */ void SetUniform(GLint location, GLint v0, GLint v1, GLint v2); /** * @brief Set uniform ivec4. * * @param[in] name Name of the uniform * @param[in] v0, v1, v2, v3 Value to set the uniform to */ void SetUniform(const GLchar* name, GLint v0, GLint v1, GLint v2, GLint v3); /** * @brief Set uniform ivec4. * * @param[in] location Location of the uniform * @param[in] v0, v1, v2, v3 Value to set the uniform to */ void SetUniform(GLint location, GLint v0, GLint v1, GLint v2, GLint v3); /** * @brief Set uniform uint. * * @param[in] name Name of the uniform * @param[in] v0 Value to set the uniform to */ void SetUniform(const GLchar* name, GLuint v0); /** * @brief Set uniform uint. * * @param[in] location Location of the uniform * @param[in] v0 Value to set the uniform to */ void SetUniform(GLint location, GLuint v0); /** * @brief Set uniform uvec2. * * @param[in] name Name of the uniform * @param[in] v0, v1 Value to set the uniform to */ void SetUniform(const GLchar* name, GLuint v0, GLuint v1); /** * @brief Set uniform uvec2. * * @param[in] location Location of the uniform * @param[in] v0, v1 Value to set the uniform to */ void SetUniform(GLint location, GLuint v0, GLuint v1); /** * @brief Set uniform uvec3. * * @param[in] name Name of the uniform * @param[in] v0, v1, v2 Value to set the uniform to */ void SetUniform(const GLchar* name, GLuint v0, GLuint v1, GLuint v2); /** * @brief Set uniform uvec3. * * @param[in] location Location of the uniform * @param[in] v0, v1, v2 Value to set the uniform to */ void SetUniform(GLint location, GLuint v0, GLuint v1, GLuint v2); /** * @brief Set uniform uvec4. * * @param[in] name Name of the uniform * @param[in] v0, v1, v2, v3 Value to set the uniform to */ void SetUniform(const GLchar* name, GLuint v0, GLuint v1, GLuint v2, GLuint v3); /** * @brief Set uniform uvec4. * * @param[in] location Location of the uniform * @param[in] v0, v1, v2, v3 Value to set the uniform to */ void SetUniform(GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); /** * @brief Set uniform color. * * Sets either a uniform vec3 or vec4, depending on wether alpha is enabled. * * @param[in] name Name of the uniform * @param[in] v0 Value to set the uniform to * @param[in] ignoreAlpha Toggles the alpha channel */ void SetUniform(const GLchar* name, const Color& v0, bool ignoreAlpha = false); /** * @brief Set uniform color. * * Sets either a uniform vec3 or vec4, depending on wether alpha is enabled. * * @param[in] location Location of the uniform * @param[in] v0 Value to set the uniform to * @param[in] ignoreAlpha Toggles the alpha channel */ void SetUniform(GLint location, const Color& v0, bool ignoreAlpha = false); /** * @brief Set uniform sampler2D. * * Activates and binds the given texture, then sets the uniform. * Note: In many cases, using AbstractTexture::BindAs(GLbyte index) to activate and bind the textures * seperately and then using SetUniform(GLint location, GLint v0) to set the uniform might * be more efficient. * * @param[in] name Name of the uniform * @param[in] v0 Value to set the uniform to * @param[in] index Index of the texture unit */ void SetUniformTexture(const GLchar* name, const Texture& v0, GLbyte index = 0); /** * @brief Set uniform color. * * Activates and binds the given texture, then sets the uniform * Note: In many cases, using AbstractTexture::BindAs(GLbyte index) to activate and bind the textures * seperately and then using SetUniform(const GLchar* name, GLint v0) to set the uniform might * be more efficient. * * @param[in] location Location of the uniform * @param[in] v0 Value to set the uniform to * @param[in] index Index of the texture unit */ void SetUniformTexture(GLint location, const Texture& v0, GLbyte index = 0); /** * @brief Set uniform mat4. * * Sets the specified uniform to the transformation matrix of a * Transformable object * * @param[in] name Name of the uniform * @param[in] v0 Value to set the uniform to * @param[in] transpose Transpose matrix before setting the uniform */ void SetUniform(const GLchar* name, Transformable& v0, GLboolean transpose = GL_FALSE); /** * @brief Set uniform mat4. * * Sets the specified uniform to the transformation matrix of a * Transformable object * * @param[in] location Location of the uniform * @param[in] v0 Value to set the uniform to * @param[in] transpose Transpose matrix before setting the uniform */ void SetUniform(GLint location, Transformable& v0, GLboolean transpose = GL_FALSE); /** * @brief Set the ambient lighting. * * This function sets two variables, the ambient color and the intensity * * @param[in] colorName The name of the uniform holding the color information (must be vec3) * @param[in] intensityName The name of the uniform holding the intensity information (must be float) * @param[in] v0 A reference to an AmbientLight */ void SetUniform(const GLchar* colorName, const GLchar* intensityName, const AmbientLight& v0); /** * @brief Set the ambient lighting. * * This function sets two variables, the ambient color and the intensity * * @param[in] colorLocation The location of the uniform holding the color information (must be vec3) * @param[in] intensityLocation The location of the uniform holding the intensity information (must be float) * @param[in] v0 A reference to an AmbientLight */ void SetUniform(GLint colorLocation, GLint intensityLocation, const AmbientLight& v0); /** * @brief Set array of uniform float. * * @param[in] name Name of the uniform * @param[in] count Amount of elements to set * @param[in] value Values to set uniforms to */ void SetUniform1fv(const GLchar* name, GLsizei count, const GLfloat* value); /** * @brief Set array of uniform float. * * @param[in] location Location of the uniform * @param[in] count Amount of elements to set * @param[in] value Values to set uniforms to */ void SetUniform1fv(GLint location, GLsizei count, const GLfloat* value); /** * @brief Set array of uniform vec2. * * @param[in] name Name of the uniform * @param[in] count Amount of elements to set * @param[in] value Values to set uniforms to */ void SetUniform2fv(const GLchar* name, GLsizei count, const GLfloat* value); /** * @brief Set array of uniform vec2. * * @param[in] location Location of the uniform * @param[in] count Amount of elements to set * @param[in] value Values to set uniforms to */ void SetUniform2fv(GLint location, GLsizei count, const GLfloat* value); /** * @brief Set array of uniform vec3. * * @param[in] name Name of the uniform * @param[in] count Amount of elements to set * @param[in] value Values to set uniforms to */ void SetUniform3fv(const GLchar* name, GLsizei count, const GLfloat* value); /** * @brief Set array of uniform vec3. * * @param[in] location Location of the uniform * @param[in] count Amount of elements to set * @param[in] value Values to set uniforms to */ void SetUniform3fv(GLint location, GLsizei count, const GLfloat* value); /** * @brief Set array of uniform vec4. * * @param[in] name Name of the uniform * @param[in] count Amount of elements to set * @param[in] value Values to set uniforms to */ void SetUniform4fv(const GLchar* name, GLsizei count, const GLfloat* value); /** * @brief Set array of uniform vec4. * * @param[in] location Location of the uniform * @param[in] count Amount of elements to set * @param[in] value Values to set uniforms to */ void SetUniform4fv(GLint location, GLsizei count, const GLfloat* value); /** * @brief Set array of uniform int. * * @param[in] name Name of the uniform * @param[in] count Amount of elements to set * @param[in] value Values to set uniforms to */ void SetUniform1iv(const GLchar* name, GLsizei count, const GLint* value); /** * @brief Set array of uniform int. * * @param[in] location Location of the uniform * @param[in] count Amount of elements to set * @param[in] value Values to set uniforms to */ void SetUniform1iv(GLint location, GLsizei count, const GLint* value); /** * @brief Set array of uniform ivec2. * * @param[in] name Name of the uniform * @param[in] count Amount of elements to set * @param[in] value Values to set uniforms to */ void SetUniform2iv(const GLchar* name, GLsizei count, const GLint* value); /** * @brief Set array of uniform ivec2. * * @param[in] location Location of the uniform * @param[in] count Amount of elements to set * @param[in] value Values to set uniforms to */ void SetUniform2iv(GLint location, GLsizei count, const GLint* value); /** * @brief Set array of uniform ivec3. * * @param[in] name Name of the uniform * @param[in] count Amount of elements to set * @param[in] value Values to set uniforms to */ void SetUniform3iv(const GLchar* name, GLsizei count, const GLint* value); /** * @brief Set array of uniform ivec3. * * @param[in] location Location of the uniform * @param[in] count Amount of elements to set * @param[in] value Values to set uniforms to */ void SetUniform3iv(GLint location, GLsizei count, const GLint* value); /** * @brief Set array of uniform ivec4. * * @param[in] name Name of the uniform * @param[in] count Amount of elements to set * @param[in] value Values to set uniforms to */ void SetUniform4iv(const GLchar* name, GLsizei count, const GLint* value); /** * @brief Set array of uniform ivec4. * * @param[in] location Location of the uniform * @param[in] count Amount of elements to set * @param[in] value Values to set uniforms to */ void SetUniform4iv(GLint location, GLsizei count, const GLint* value); /** * @brief Set array of uniform uint. * * @param[in] name Name of the uniform * @param[in] count Amount of elements to set * @param[in] value Values to set uniforms to */ void SetUniform1uiv(const GLchar* name, GLsizei count, const GLuint* value); /** * @brief Set array of uniform uint. * * @param[in] location Location of the uniform * @param[in] count Amount of elements to set * @param[in] value Values to set uniforms to */ void SetUniform1uiv(GLint location, GLsizei count, const GLuint* value); /** * @brief Set array of uniform uvec2. * * @param[in] name Name of the uniform * @param[in] count Amount of elements to set * @param[in] value Values to set uniforms to */ void SetUniform2uiv(const GLchar* name, GLsizei count, const GLuint* value); /** * @brief Set array of uniform uvec2. * * @param[in] location Location of the uniform * @param[in] count Amount of elements to set * @param[in] value Values to set uniforms to */ void SetUniform2uiv(GLint location, GLsizei count, const GLuint* value); /** * @brief Set array of uniform uvec3. * * @param[in] name Name of the uniform * @param[in] count Amount of elements to set * @param[in] value Values to set uniforms to */ void SetUniform3uiv(const GLchar* name, GLsizei count, const GLuint* value); /** * @brief Set array of uniform uvec3. * * @param[in] location Location of the uniform * @param[in] count Amount of elements to set * @param[in] value Values to set uniforms to */ void SetUniform3uiv(GLint location, GLsizei count, const GLuint* value); /** * @brief Set array of uniform uvec4. * * @param[in] name Name of the uniform * @param[in] count Amount of elements to set * @param[in] value Values to set uniforms to */ void SetUniform4uiv(const GLchar* name, GLsizei count, const GLuint* value); /** * @brief Set array of uniform uvec4. * * @param[in] location Location of the uniform * @param[in] count Amount of elements to set * @param[in] value Values to set uniforms to */ void SetUniform4uiv(GLint location, GLsizei count, const GLuint* value); /** * @brief Set (array of) uniform 2x2 matrix. * * @param[in] name Name of the uniform * @param[in] count Amount of elements to set * @param[in] transpose Wether to transpose the supplied matrix * @param[in] value Values to set uniforms to */ void SetUniformMatrix2fv(const GLchar* name, GLsizei count, GLboolean transpose, const GLfloat* value); /** * @brief Set (array of) uniform 2x2 matrix. * * @param[in] location Location of the uniform * @param[in] count Amount of elements to set * @param[in] transpose Wether to transpose the supplied matrix * @param[in] value Values to set uniforms to */ void SetUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); /** * @brief Set (array of) uniform 3x3 matrix. * * @param[in] name Name of the uniform * @param[in] count Amount of elements to set * @param[in] transpose Wether to transpose the supplied matrix * @param[in] value Values to set uniforms to */ void SetUniformMatrix3fv(const GLchar* name, GLsizei count, GLboolean transpose, const GLfloat* value); /** * @brief Set (array of) uniform 3x3 matrix. * * @param[in] location Location of the uniform * @param[in] count Amount of elements to set * @param[in] transpose Wether to transpose the supplied matrix * @param[in] value Values to set uniforms to */ void SetUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); /** * @brief Set (array of) uniform 4x4 matrix. * * @param[in] name Name of the uniform * @param[in] count Amount of elements to set * @param[in] transpose Wether to transpose the supplied matrix * @param[in] value Values to set uniforms to */ void SetUniformMatrix4fv(const GLchar* name, GLsizei count, GLboolean transpose, const GLfloat* value); /** * @brief Set (array of) uniform 4x4 matrix. * * @param[in] location Location of the uniform * @param[in] count Amount of elements to set * @param[in] transpose Wether to transpose the supplied matrix * @param[in] value Values to set uniforms to */ void SetUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); /** * @brief Set (array of) uniform 2x3 matrix. * * @param[in] name Name of the uniform * @param[in] count Amount of elements to set * @param[in] transpose Wether to transpose the supplied matrix * @param[in] value Values to set uniforms to */ void SetUniformMatrix2x3fv(const GLchar* name, GLsizei count, GLboolean transpose, const GLfloat* value); /** * @brief Set (array of) uniform 2x3 matrix. * * @param[in] location Location of the uniform * @param[in] count Amount of elements to set * @param[in] transpose Wether to transpose the supplied matrix * @param[in] value Values to set uniforms to */ void SetUniformMatrix2x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); /** * @brief Set (array of) uniform 3x2 matrix. * * @param[in] name Name of the uniform * @param[in] count Amount of elements to set * @param[in] transpose Wether to transpose the supplied matrix * @param[in] value Values to set uniforms to */ void SetUniformMatrix3x2fv(const GLchar* name, GLsizei count, GLboolean transpose, const GLfloat* value); /** * @brief Set (array of) uniform 3x2 matrix. * * @param[in] location Location of the uniform * @param[in] count Amount of elements to set * @param[in] transpose Wether to transpose the supplied matrix * @param[in] value Values to set uniforms to */ void SetUniformMatrix3x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); /** * @brief Set (array of) uniform 2x4 matrix. * * @param[in] name Name of the uniform * @param[in] count Amount of elements to set * @param[in] transpose Wether to transpose the supplied matrix * @param[in] value Values to set uniforms to */ void SetUniformMatrix2x4fv(const GLchar* name, GLsizei count, GLboolean transpose, const GLfloat* value); /** * @brief Set (array of) uniform 2x4 matrix. * * @param[in] location Location of the uniform * @param[in] count Amount of elements to set * @param[in] transpose Wether to transpose the supplied matrix * @param[in] value Values to set uniforms to */ void SetUniformMatrix2x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); /** * @brief Set (array of) uniform 4x2 matrix. * * @param[in] name Name of the uniform * @param[in] count Amount of elements to set * @param[in] transpose Wether to transpose the supplied matrix * @param[in] value Values to set uniforms to */ void SetUniformMatrix4x2fv(const GLchar* name, GLsizei count, GLboolean transpose, const GLfloat* value); /** * @brief Set (array of) uniform 4x2 matrix. * * @param[in] location Location of the uniform * @param[in] count Amount of elements to set * @param[in] transpose Wether to transpose the supplied matrix * @param[in] value Values to set uniforms to */ void SetUniformMatrix4x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); /** * @brief Set (array of) uniform 3x4 matrix. * * @param[in] name Name of the uniform * @param[in] count Amount of elements to set * @param[in] transpose Wether to transpose the supplied matrix * @param[in] value Values to set uniforms to */ void SetUniformMatrix3x4fv(const GLchar* name, GLsizei count, GLboolean transpose, const GLfloat* value); /** * @brief Set (array of) uniform 3x4 matrix. * * @param[in] location Location of the uniform * @param[in] count Amount of elements to set * @param[in] transpose Wether to transpose the supplied matrix * @param[in] value Values to set uniforms to */ void SetUniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); /** * @brief Set (array of) uniform 4x3 matrix. * * @param[in] name Name of the uniform * @param[in] count Amount of elements to set * @param[in] transpose Wether to transpose the supplied matrix * @param[in] value Values to set uniforms to */ void SetUniformMatrix4x3fv(const GLchar* name, GLsizei count, GLboolean transpose, const GLfloat* value); /** * @brief Set (array of) uniform 4x3 matrix. * * @param[in] location Location of the uniform * @param[in] count Amount of elements to set * @param[in] transpose Wether to transpose the supplied matrix * @param[in] value Values to set uniforms to */ void SetUniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); #pragma endregion Uniforms private: /** * @brief Construct a shader program. * * To avoid accidental deletion of shader programs while they're still in use, * this constructor has been made private. To create a shader program use * MakeShader(const char* vertexShaderFile, const char* fragmentShaderFile). * * @param[in] vertexShaderFile Filepath to the vertex shader * @param[in] fragmentShaderFile Filepath to the fragment shader */ AbstractShader(const char* vertexShaderFile, const char* fragmentShaderFile); /** * @brief Loads a shader file from disk * * @param[in] filename Filepath to the shader * @param[out] buffer Contents of the shader file */ void LoadShaderSource(const char* filename, char** buffer); private: GLuint program; ///< Handle to the Shader program }; Shader OGLU_API MakeShader(const char* vertexShaderFile, const char* fragmentShaderFile); } #endif