LCOV - code coverage report
Current view: top level - engine/render - shaderparam.h (source / functions) Hit Total Coverage
Test: Libprimis Test Coverage Lines: 5 16 31.2 %
Date: 2024-11-22 05:07:59 Functions: 1 8 12.5 %

          Line data    Source code
       1             : #ifndef SHADERPARAM_H_
       2             : #define SHADERPARAM_H_
       3             : 
       4             : struct UniformLoc
       5             : {
       6             :     const char *name, *blockname;
       7             :     GLint loc;
       8             :     int version, binding, stride, offset;
       9             :     GLint size;
      10             :     const void *data;
      11           0 :     UniformLoc(const char *name = nullptr, const char *blockname = nullptr, int binding = -1, int stride = -1) : name(name), blockname(blockname), loc(-1), version(-1), binding(binding), stride(stride), offset(-1), size(-1), data(nullptr) {}
      12             : };
      13             : 
      14             : struct GlobalShaderParamState
      15             : {
      16             :     union
      17             :     {
      18             :         GLfloat fval[32];
      19             :         GLint ival[32];
      20             :         GLuint uval[32];
      21             :         std::array<uchar, 32*sizeof(float)> buf;
      22             :     };
      23             :     int version;
      24             : 
      25             :     static int nextversion;
      26             : 
      27             :     void resetversions();
      28             : 
      29           0 :     void changed()
      30             :     {
      31           0 :         if(++nextversion < 0)
      32             :         {
      33           0 :             resetversions();
      34             :         }
      35           0 :         version = nextversion;
      36           0 :     }
      37             : };
      38             : 
      39             : extern std::map<std::string, GlobalShaderParamState> globalparams;
      40             : extern GlobalShaderParamState *getglobalparam(const char *name);
      41             : 
      42             : struct ShaderParamBinding
      43             : {
      44             :     GLint loc;
      45             :     GLsizei size;
      46             :     GLenum format;
      47             : 
      48             :     ShaderParamBinding(GLint loc, GLsizei size, GLenum format);
      49           0 :     ShaderParamBinding() {};
      50             : };
      51             : 
      52             : struct GlobalShaderParamUse : ShaderParamBinding
      53             : {
      54             : 
      55             :     const GlobalShaderParamState *param;
      56             :     int version;
      57             : 
      58             :     GlobalShaderParamUse(GLint loc, GLsizei size, GLenum format, const GlobalShaderParamState *param, int version);
      59             :     void flush();
      60             : };
      61             : 
      62             : struct LocalShaderParamState : ShaderParamBinding
      63             : {
      64             :     std::string name;
      65             : 
      66           0 :     LocalShaderParamState() {}
      67             :     LocalShaderParamState(GLint loc, GLsizei size, GLenum format);
      68             : 
      69             : };
      70             : 
      71             : struct SlotShaderParamState : LocalShaderParamState
      72             : {
      73             :     int flags;
      74             :     std::array<float, 4> val;
      75             : 
      76             :     SlotShaderParamState() {}
      77           1 :     SlotShaderParamState(const SlotShaderParam &p) : LocalShaderParamState(-1, 1, GL_FLOAT_VEC4)
      78             :     {
      79           1 :         name = p.name;
      80           1 :         flags = p.flags;
      81           1 :         std::memcpy(val.data(), p.val, sizeof(val));
      82           1 :     }
      83             : };
      84             : 
      85             : //a container containing a GLSL shader
      86             : class Shader
      87             : {
      88             :     public:
      89             :         static Shader *lastshader; //the current shader being used by glUseProgram()
      90             : 
      91             :         char *name, //name of the shader in shaders list
      92             :             *defer; //deferred shader contents
      93             :         int type; //type of shader, e.g. world, refractive, deferred, see enum
      94             :         GLuint program; //handle for GL program object
      95             :         std::vector<SlotShaderParamState> defaultparams;
      96             :         std::vector<GlobalShaderParamUse> globalparams;
      97             :         std::vector<LocalShaderParamState> localparams;
      98             :         std::vector<uchar> localparamremap;
      99             :         const Shader *variantshader;
     100             :         std::vector<Shader *> variants;
     101             :         bool standard, forced;
     102             :         std::vector<UniformLoc> uniformlocs;
     103             : 
     104             :         const void *owner;
     105             : 
     106             :         Shader();
     107             :         ~Shader();
     108             : 
     109             :         void flushparams();
     110             :         void force();
     111             :         bool invalid() const;
     112             :         bool deferred() const;
     113             :         bool loaded() const;
     114             :         bool isdynamic() const;
     115             :         int numvariants(int row) const;
     116             :         void addvariant(int row, Shader *s);
     117             :         void setvariant(int col, int row);
     118             :         void setvariant(int col, int row, const Slot &slot);
     119             :         void setvariant(int col, int row, const Slot &slot, const VSlot &vslot);
     120             :         void set();
     121             :         void set(const Slot &slot);
     122             :         void set(const Slot &slot, const VSlot &vslot);
     123             :         bool compile();
     124             :         void cleanup(bool full = false);
     125             :         void reusecleanup();
     126             : 
     127             :         static int uniformlocversion();
     128             :         Shader *setupshader(char *rname, const char *ps, const char *vs, Shader *variant, int row);
     129             : 
     130             :     private:
     131             :         char *vsstr, //a pointer to a `v`ertex `s`hader `str`ing
     132             :              *psstr; //a pointer to a `p`ixel `s`hader `str`ing
     133             :         struct AttribLoc
     134             :         {
     135             :             const char *name;
     136             :             int loc;
     137           0 :             AttribLoc(const char *name = nullptr, int loc = -1) : name(name), loc(loc) {}
     138             :         };
     139             :         std::vector<AttribLoc> attriblocs;
     140             :         GLuint vsobj, psobj;
     141             :         const Shader *reusevs, *reuseps; //may be equal to variantshader, or its getvariant()
     142             :         ushort *variantrows;
     143             :         bool used;
     144             :         void setslotparams(const Slot &slot);
     145             :         void setslotparams(const Slot &slot, const VSlot &vslot);
     146             :         void bindprograms();
     147             :         void setvariant_(int col, int row);
     148             :         void set_();
     149             :         void allocglslactiveuniforms();
     150             :         void setglsluniformformat(const char *name, GLenum format, int size);
     151             : 
     152             :         //attaches shaders to the Shader::program handle
     153             :         void linkglslprogram(bool msg = true);
     154             : 
     155             :         /**
     156             :          * @brief Sets an OpenGL int uniform
     157             :          * gets the uniform1i with name `name` and sets its value to `tmu`
     158             :          * no effect if no uniform with given name found
     159             :          */
     160             :         void uniformtex(std::string_view name, int tmu) const;
     161             : 
     162             :         /**
     163             :          * For each `//:attrib <string> <int>` found in the passed vertex shader,
     164             :          * adds an AttribLoc to this Shader's attriblocs comprising of a string (also stored in shaderparamnames),
     165             :          * and the location specified in the second parameter
     166             :          */
     167             :         void genattriblocs(const char *vs, const Shader *reusevs);
     168             :         void genuniformlocs(const char *vs, const Shader *reusevs, const Shader *reuseps);
     169             :         const Shader *getvariant(int col, int row) const;
     170             : };
     171             : 
     172             : class GlobalShaderParam
     173             : {
     174             :     public:
     175             :         GlobalShaderParam(const char *name);
     176             : 
     177             :         GlobalShaderParamState &resolve();
     178             :         void setf(float x = 0, float y = 0, float z = 0, float w = 0);
     179             :         void set(const vec &v, float w = 0);
     180             :         void set(const vec2 &v, float z = 0, float w = 0);
     181             :         void set(const matrix3 &m);
     182             :         void set(const matrix4 &m);
     183             : 
     184             :         template<class T>
     185           0 :         T *reserve()
     186             :         {
     187           0 :             return reinterpret_cast<T *>(resolve().buf.data());
     188             :         }
     189             :     private:
     190             :         const std::string name;
     191             :         GlobalShaderParamState *param;
     192             :         GlobalShaderParamState &getglobalparam(const std::string &name) const;
     193             : 
     194             : };
     195             : 
     196             : class LocalShaderParam
     197             : {
     198             :     public:
     199             :         LocalShaderParam(const char *name);
     200             :         void setf(float x = 0, float y = 0, float z = 0, float w = 0) const;
     201             :         void set(const vec &v, float w = 0) const;
     202             :         void set(const vec4<float> &v) const;
     203             :         void setv(const vec *v, int n = 1) const;
     204             :         void setv(const vec2 *v, int n = 1) const;
     205             :         void setv(const vec4<float> *v, int n = 1) const;
     206             :         void setv(const float *f, int n) const;
     207             :         void set(const matrix3 &m) const;
     208             :         void set(const matrix4 &m) const;
     209             :     private:
     210             :         void setv(const matrix3 *m, int n = 1) const;
     211             :         void setv(const matrix4 *m, int n = 1) const;
     212             :         const LocalShaderParamState *resolve() const;
     213             : 
     214             :         const char * const name;
     215             :         mutable int loc;
     216             : };
     217             : 
     218             : /**
     219             :  * @brief Defines a LocalShaderParam with static storage inside the function's scope
     220             :  *
     221             :  * This macro creates a LocalShaderParam named `param` and inserts it into the function
     222             :  *  as a static variable. This variable cannot be accessed later and remains defined
     223             :  * for as long as the program runs.
     224             :  *
     225             :  * @param name a string (or plain text, that will be stringized)
     226             :  * @param vals the values to set, must comply with one of the set() functions for LocalShaderParam
     227             :  */
     228             : #define LOCALPARAM(name, vals) \
     229             :     do \
     230             :     { \
     231             :         static LocalShaderParam param( #name ); \
     232             :         param.set(vals); \
     233             :     } \
     234             :     while(0)
     235             : 
     236             : //creates a localshaderparam like above but calls setf() instead
     237             : #define LOCALPARAMF(name, ...) \
     238             :     do \
     239             :     { \
     240             :         static LocalShaderParam param( #name ); \
     241             :         param.setf(__VA_ARGS__); \
     242             :     } while(0)
     243             : 
     244             : #define LOCALPARAMV(name, vals, num) \
     245             :     do \
     246             :     { \
     247             :         static LocalShaderParam param( #name ); \
     248             :         param.setv(vals, num); \
     249             :     } while(0)
     250             : 
     251             : //creates a globalshaderparam, either by calling set(), setf() or setv()
     252             : //this will create a temp object containing #name, and then attempt to set()
     253             : //it to a value in the global shader param map
     254             : //overrides exist for set() for various different types
     255             : #define GLOBALPARAM(name, vals) do { static GlobalShaderParam param( #name ); param.set(vals); } while(0)
     256             : 
     257             : //same as globalparam, but takes up to 4 float args
     258             : #define GLOBALPARAMF(name, ...) do { static GlobalShaderParam param( #name ); param.setf(__VA_ARGS__); } while(0)
     259             : 
     260             : //creates a new static variable inside the function called <name>setshader
     261             : //then sets to it any(if present) args passed to set to the shader
     262             : //can only be called once per function, and not in the global scope
     263             : //upon calling set(), the shader associated with the name is loaded into OpenGL
     264             : #define SETSHADER(name, ...) \
     265             :     do { \
     266             :         static Shader *name##shader = nullptr; \
     267             :         if(!name##shader) \
     268             :         { \
     269             :             name##shader = lookupshaderbyname(#name); \
     270             :         } \
     271             :         if(name##shader) \
     272             :         { \
     273             :             name##shader->set(__VA_ARGS__); \
     274             :         } \
     275             :     } while(0)
     276             : #define SETVARIANT(name, ...) \
     277             :     do { \
     278             :         static Shader *name##shader = nullptr; \
     279             :         if(!name##shader) name##shader = lookupshaderbyname(#name); \
     280             :         name##shader->setvariant(__VA_ARGS__); \
     281             :     } while(0)
     282             : 
     283             : #endif

Generated by: LCOV version 1.14