From cd9114bfd0ea23fcf6ea9f38621099113352e9c6 Mon Sep 17 00:00:00 2001 From: Henrik Hautakoski Date: Sun, 18 Sep 2022 12:26:01 +0200 Subject: [PATCH] Adding Spectre/GfxDriver/ShaderProgram base class. --- include/Spectre/GfxDriver/ShaderProgram.h | 77 +++++++++++++++++++++++ source/GfxDriver/ShaderProgram.cpp | 69 ++++++++++++++++++++ 2 files changed, 146 insertions(+) create mode 100644 include/Spectre/GfxDriver/ShaderProgram.h create mode 100644 source/GfxDriver/ShaderProgram.cpp diff --git a/include/Spectre/GfxDriver/ShaderProgram.h b/include/Spectre/GfxDriver/ShaderProgram.h new file mode 100644 index 0000000..872e137 --- /dev/null +++ b/include/Spectre/GfxDriver/ShaderProgram.h @@ -0,0 +1,77 @@ + +#ifndef SPECTRE_GFXDRIVER_SHADERPROGRAM_H +#define SPECTRE_GFXDRIVER_SHADERPROGRAM_H + +#include +#include + +namespace sp { + +enum ShaderType { + Vertex, + Fragment +}; + +class ShaderProgram +{ +public: + virtual ~ShaderProgram(); + + // Load a shader program from file. + virtual bool loadFromFile(const std::string& filename); + + // Load a shader from file. + virtual bool loadFromFile(const std::string& filename, ShaderType type); + + // Load a shader from memory. + virtual bool loadFromMemory(const std::string& source, ShaderType type) = 0; + + // Link the program. + virtual bool link() = 0; + + // Returns true if the program was linked successfully + virtual bool isLinked() const; + + // Enable this shader + // All shader operations after this call will affect this shader. + virtual void enable() const = 0; + + // Disable this shader + // Operations will no longer affect this shader after this call. + virtual void disable() const = 0; + + // Get the last shader error. + virtual std::string getLastError() const; + + // --------------------- + // Variables. + // --------------------- + // TODO: Move this to a ShaderParameter class + + virtual bool setMVPMatrix(const Matrix4f& matrix) = 0; + + // --------------------- + // General Variables. + // --------------------- + + virtual bool setAttribute(const std::string& name, float value) const = 0; + + virtual bool setAttribute(const std::string& name, const Matrix4f& matrix) const = 0; + + virtual bool setUniform(const std::string& name, const Matrix4f& matrix) const = 0; + + virtual bool setUniform(const std::string& name, const Color& color) const = 0; + + +protected: + + std::string m_extension; + + mutable std::string m_error; + + bool m_linked; +}; + +} // namespace sp + +#endif /* SECTRE_GRAPHICS_SHADERPROGRAM_H */ diff --git a/source/GfxDriver/ShaderProgram.cpp b/source/GfxDriver/ShaderProgram.cpp new file mode 100644 index 0000000..61ed11a --- /dev/null +++ b/source/GfxDriver/ShaderProgram.cpp @@ -0,0 +1,69 @@ + +#include +#include +#include +#include + +namespace sp +{ + +ShaderProgram::~ShaderProgram() +{ +} + +bool ShaderProgram::loadFromFile(const std::string& filename) +{ + std::string extension = Path::getExtension(filename); + + // Meta file. load real shaders. + if (extension == "shader." + m_extension) { + + // FIXME: This is ugly :) + std::string base_name = filename.substr(0, filename.length() - extension.length()); + + // vert and frag are not optional. they must exist. + return loadFromFile(base_name + "vert." + m_extension, ShaderType::Vertex) && + loadFromFile(base_name + "frag." + m_extension, ShaderType::Fragment); + + } else if (extension == "vert." + m_extension) { + return loadFromFile(filename, ShaderType::Vertex); + } else if (extension == "frag." + m_extension) { + return loadFromFile(filename, ShaderType::Fragment); + } + + m_error = "Invalid file extension: " + extension; + + return false; +} + +bool ShaderProgram::loadFromFile(const std::string& filename, ShaderType type) +{ + std::string src; + File file; + + if (!file.open(filename)) { + m_error = "Can't open file: " + filename; + return false; + } + + // Load file into memory. + if (!file.read(src)) { + m_error = "Could not read file: " + filename; + return false; + } + + return loadFromMemory(src, type); +} + + +bool ShaderProgram::isLinked() const +{ + return m_linked; +} + +std::string ShaderProgram::getLastError() const +{ + return m_error; +} + +} // namespace sp \ No newline at end of file