LCOV - code coverage report
Current view: top level - engine/render - shaderparam.h (source / functions) Coverage Total Hit
Test: Libprimis Test Coverage Lines: 31.2 % 16 5
Test Date: 2025-02-21 06:59:27 Functions: 12.5 % 8 1

            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 setvariantandslot(int col, int row);
     119              :         void setvariant(int col, int row, const Slot &slot, const VSlot &vslot);
     120              :         void set();
     121              :         void setslot();
     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(int newtype, 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();
     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);
     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 2.0-1