LCOV - code coverage report
Current view: top level - shared - glemu.cpp (source / functions) Hit Total Coverage
Test: Libprimis Test Coverage Lines: 1 369 0.3 %
Date: 2024-11-22 05:07:59 Functions: 1 61 1.6 %

          Line data    Source code
       1             : /**
       2             :  * @brief GL immediate mode EMUlation layer (glemu).
       3             :  *
       4             :  * This file replicates some of the functionality of the long since removed glBegin/glEnd
       5             :  * features from extremely outdated versions of OpenGL.
       6             :  */
       7             : #include "../libprimis-headers/cube.h"
       8             : 
       9             : #include "glemu.h"
      10             : #include "glexts.h"
      11             : namespace gle
      12             : {
      13             :     struct attribinfo
      14             :     {
      15             :         int type, size, formatsize, offset;
      16             :         GLenum format;
      17             : 
      18          16 :         attribinfo() : type(0), size(0), formatsize(0), offset(0), format(GL_FALSE) {}
      19             : 
      20             :         bool operator==(const attribinfo &a) const
      21             :         {
      22             :             return type == a.type && size == a.size && format == a.format && offset == a.offset;
      23             :         }
      24           0 :         bool operator!=(const attribinfo &a) const
      25             :         {
      26           0 :             return type != a.type || size != a.size || format != a.format || offset != a.offset;
      27             :         }
      28             :     };
      29             :     ucharbuf attribbuf;
      30             :     static uchar *attribdata;
      31             :     static attribinfo attribdefs[Attribute_NumAttributes], lastattribs[Attribute_NumAttributes];
      32             :     static int enabled = 0;
      33             :     static int numattribs = 0,
      34             :                attribmask = 0,
      35             :                numlastattribs = 0,
      36             :                lastattribmask = 0,
      37             :                vertexsize = 0,
      38             :                lastvertexsize = 0;
      39             :     static GLenum primtype = GL_TRIANGLES;
      40             :     static uchar *lastbuf = nullptr;
      41             :     static bool changedattribs = false;
      42             :     static std::vector<GLint> multidrawstart;
      43             :     static std::vector<GLsizei> multidrawcount;
      44             : 
      45             :     static constexpr int maxquads = (0x10000/4); //65635/4 = 16384
      46             :     static GLuint quadindexes = 0;
      47             :     static bool quadsenabled = false;
      48             : 
      49             :     static constexpr int maxvbosize = (1024*1024*4);
      50             :     static GLuint vbo = 0;
      51             :     static int vbooffset = maxvbosize;
      52             : 
      53             :     static GLuint defaultvao = 0;
      54             : 
      55           0 :     void enablequads()
      56             :     {
      57           0 :         quadsenabled = true;
      58           0 :         if(quadindexes)
      59             :         {
      60           0 :             glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, quadindexes);
      61           0 :             return;
      62             :         }
      63             : 
      64           0 :         glGenBuffers(1, &quadindexes);
      65           0 :         ushort *data = new ushort[maxquads*6],
      66           0 :                *dst = data;
      67           0 :         for(int idx = 0; idx < maxquads*4; idx += 4, dst += 6)
      68             :         {
      69           0 :             dst[0] = idx;
      70           0 :             dst[1] = idx + 1;
      71           0 :             dst[2] = idx + 2;
      72           0 :             dst[3] = idx + 0;
      73           0 :             dst[4] = idx + 2;
      74           0 :             dst[5] = idx + 3;
      75             :         }
      76           0 :         glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, quadindexes);
      77           0 :         glBufferData(GL_ELEMENT_ARRAY_BUFFER, maxquads*6*sizeof(ushort), data, GL_STATIC_DRAW);
      78           0 :         delete[] data;
      79             :     }
      80             : 
      81           0 :     void disablequads()
      82             :     {
      83           0 :         quadsenabled = false;
      84           0 :         glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
      85           0 :     }
      86             : 
      87           0 :     void drawquads(int offset, int count)
      88             :     {
      89           0 :         if(count <= 0)
      90             :         {
      91           0 :             return;
      92             :         }
      93           0 :         if(offset + count > maxquads)
      94             :         {
      95           0 :             if(offset >= maxquads)
      96             :             {
      97           0 :                 return;
      98             :             }
      99           0 :             count = maxquads - offset;
     100             :         }
     101           0 :         glDrawRangeElements(GL_TRIANGLES, offset*4, (offset + count)*4-1, count*6, GL_UNSIGNED_SHORT, (ushort *)0 + offset*6);
     102             :     }
     103             : 
     104           0 :     static void defattrib(int type, int size, int format)
     105             :     {
     106           0 :         if(type == Attribute_Vertex)
     107             :         {
     108           0 :             numattribs = attribmask = 0;
     109           0 :             vertexsize = 0;
     110             :         }
     111           0 :         changedattribs = true;
     112           0 :         attribmask |= 1<<type;
     113           0 :         attribinfo &a = attribdefs[numattribs++];
     114           0 :         a.type = type;
     115           0 :         a.size = size;
     116           0 :         a.format = format;
     117           0 :         switch(format)
     118             :         {
     119           0 :             case 'B':
     120             :             case GL_UNSIGNED_BYTE:
     121             :             {
     122           0 :                 a.formatsize = 1;
     123           0 :                 a.format = GL_UNSIGNED_BYTE;
     124           0 :                 break;
     125             :             }
     126           0 :             case 'b':
     127             :             case GL_BYTE:
     128             :             {
     129           0 :                 a.formatsize = 1;
     130           0 :                 a.format = GL_BYTE;
     131           0 :                 break;
     132             :             }
     133           0 :             case 'S':
     134             :             case GL_UNSIGNED_SHORT:
     135             :             {
     136           0 :                 a.formatsize = 2;
     137           0 :                 a.format = GL_UNSIGNED_SHORT;
     138           0 :                 break;
     139             :             }
     140           0 :             case 's':
     141             :             case GL_SHORT:
     142             :             {
     143           0 :                 a.formatsize = 2;
     144           0 :                 a.format = GL_SHORT;
     145           0 :                 break;
     146             :             }
     147           0 :             case 'I':
     148             :             case GL_UNSIGNED_INT:
     149             :             {
     150           0 :                 a.formatsize = 4;
     151           0 :                 a.format = GL_UNSIGNED_INT;
     152           0 :                 break;
     153             :             }
     154           0 :             case 'i':
     155             :             case GL_INT:
     156             :             {
     157           0 :                 a.formatsize = 4;
     158           0 :                 a.format = GL_INT;
     159           0 :                 break;
     160             :             }
     161           0 :             case 'f':
     162             :             case GL_FLOAT:
     163             :             {
     164           0 :                 a.formatsize = 4;
     165           0 :                 a.format = GL_FLOAT;
     166           0 :                 break;
     167             :             }
     168           0 :             case 'd':
     169             :             case GL_DOUBLE:
     170             :             {
     171           0 :                 a.formatsize = 8;
     172           0 :                 a.format = GL_DOUBLE;
     173           0 :                 break;
     174             :             }
     175           0 :             default:
     176             :             {
     177           0 :                 a.formatsize = 0;
     178           0 :                 a.format = GL_FALSE;
     179           0 :                 break;
     180             :             }
     181             :         }
     182           0 :         a.formatsize *= size;
     183           0 :         a.offset = vertexsize;
     184           0 :         vertexsize += a.formatsize;
     185           0 :     }
     186             : 
     187           0 :     static void setattrib(const attribinfo &a, uchar *buf)
     188             :     {
     189           0 :         switch(a.type)
     190             :         {
     191           0 :             case Attribute_Vertex:
     192             :             case Attribute_TexCoord0:
     193             :             case Attribute_TexCoord1:
     194             :             case Attribute_BoneIndex:
     195             :             {
     196           0 :                 glVertexAttribPointer(a.type, a.size, a.format, GL_FALSE, vertexsize, buf);
     197           0 :                 break;
     198             :             }
     199           0 :             case Attribute_Color:
     200             :             case Attribute_Normal:
     201             :             case Attribute_Tangent:
     202             :             case Attribute_BoneWeight:
     203             :             {
     204           0 :                 glVertexAttribPointer(a.type, a.size, a.format, GL_TRUE, vertexsize, buf);
     205           0 :                 break;
     206             :             }
     207             :         }
     208           0 :         if(!(enabled&(1<<a.type)))
     209             :         {
     210           0 :             glEnableVertexAttribArray(a.type);
     211           0 :             enabled |= 1<<a.type;
     212             :         }
     213           0 :     }
     214             : 
     215           0 :     static void unsetattrib(const attribinfo &a)
     216             :     {
     217           0 :         glDisableVertexAttribArray(a.type);
     218           0 :         enabled &= ~(1<<a.type);
     219           0 :     }
     220             : 
     221           0 :     static void setattribs(uchar *buf)
     222             :     {
     223           0 :         bool forceattribs = numattribs != numlastattribs || vertexsize != lastvertexsize || buf != lastbuf;
     224           0 :         if(forceattribs || changedattribs)
     225             :         {
     226             :             //bitwise AND of attribs
     227           0 :             int diffmask = enabled & lastattribmask & ~attribmask;
     228           0 :             if(diffmask)
     229             :             {
     230           0 :                 for(int i = 0; i < numlastattribs; ++i)
     231             :                 {
     232           0 :                     const attribinfo &a = lastattribs[i];
     233           0 :                     if(diffmask & (1<<a.type))
     234             :                     {
     235           0 :                         unsetattrib(a);
     236             :                     }
     237             :                 }
     238             :             }
     239           0 :             uchar *src = buf;
     240           0 :             for(int i = 0; i < numattribs; ++i)
     241             :             {
     242           0 :                 const attribinfo &a = attribdefs[i];
     243           0 :                 if(forceattribs || a != lastattribs[i])
     244             :                 {
     245           0 :                     setattrib(a, src);
     246           0 :                     lastattribs[i] = a;
     247             :                 }
     248           0 :                 src += a.formatsize;
     249             :             }
     250           0 :             lastbuf = buf;
     251           0 :             numlastattribs = numattribs;
     252           0 :             lastattribmask = attribmask;
     253           0 :             lastvertexsize = vertexsize;
     254           0 :             changedattribs = false;
     255             :         }
     256           0 :     }
     257             : 
     258           0 :     void begin(GLenum mode)
     259             :     {
     260           0 :         primtype = mode;
     261           0 :     }
     262             : 
     263           0 :     void begin(GLenum mode, int numverts)
     264             :     {
     265           0 :         primtype = mode;
     266           0 :         int len = numverts * vertexsize;
     267           0 :         if(vbooffset + len >= maxvbosize)
     268             :         {
     269           0 :             len = std::min(len, maxvbosize);
     270           0 :             if(!vbo)
     271             :             {
     272           0 :                 glGenBuffers(1, &vbo);
     273             :             }
     274           0 :             glBindBuffer(GL_ARRAY_BUFFER, vbo);
     275           0 :             glBufferData(GL_ARRAY_BUFFER, maxvbosize, nullptr, GL_STREAM_DRAW);
     276           0 :             vbooffset = 0;
     277             :         }
     278           0 :         else if(!lastvertexsize)
     279             :         {
     280           0 :             glBindBuffer(GL_ARRAY_BUFFER, vbo);
     281             :         }
     282           0 :         void *buf = glMapBufferRange(GL_ARRAY_BUFFER, vbooffset, len, GL_MAP_WRITE_BIT|GL_MAP_INVALIDATE_RANGE_BIT|GL_MAP_UNSYNCHRONIZED_BIT);
     283           0 :         if(buf)
     284             :         {
     285           0 :             attribbuf.reset(static_cast<uchar *>(buf), len);
     286             :         }
     287           0 :     }
     288             : 
     289           0 :     void multidraw()
     290             :     {
     291           0 :         int start = multidrawstart.size() ? multidrawstart.back() + multidrawcount.back() : 0,
     292           0 :             count = attribbuf.length()/vertexsize - start;
     293           0 :         if(count > 0)
     294             :         {
     295           0 :             multidrawstart.push_back(start);
     296           0 :             multidrawcount.push_back(count);
     297             :         }
     298           0 :     }
     299             : 
     300           0 :     int end()
     301             :     {
     302           0 :         uchar *buf = attribbuf.getbuf();
     303           0 :         if(attribbuf.empty())
     304             :         {
     305           0 :             if(buf != attribdata)
     306             :             {
     307           0 :                 glUnmapBuffer(GL_ARRAY_BUFFER);
     308           0 :                 attribbuf.reset(attribdata, maxvbosize);
     309             :             }
     310           0 :             return 0;
     311             :         }
     312           0 :         int start = 0;
     313           0 :         if(buf == attribdata)
     314             :         {
     315           0 :             if(vbooffset + attribbuf.length() >= maxvbosize)
     316             :             {
     317           0 :                 if(!vbo)
     318             :                 {
     319           0 :                     glGenBuffers(1, &vbo);
     320             :                 }
     321           0 :                 glBindBuffer(GL_ARRAY_BUFFER, vbo);
     322           0 :                 glBufferData(GL_ARRAY_BUFFER, maxvbosize, nullptr, GL_STREAM_DRAW);
     323           0 :                 vbooffset = 0;
     324             :             }
     325           0 :             else if(!lastvertexsize)
     326             :             {
     327           0 :                 glBindBuffer(GL_ARRAY_BUFFER, vbo);
     328             :             }
     329             :             //void pointer warning!
     330           0 :             void *dst = glMapBufferRange(GL_ARRAY_BUFFER, vbooffset, attribbuf.length(), GL_MAP_WRITE_BIT|GL_MAP_INVALIDATE_RANGE_BIT|GL_MAP_UNSYNCHRONIZED_BIT);
     331           0 :             std::memcpy(dst, attribbuf.getbuf(), attribbuf.length());
     332           0 :             glUnmapBuffer(GL_ARRAY_BUFFER);
     333             :         }
     334             :         else
     335             :         {
     336           0 :             glUnmapBuffer(GL_ARRAY_BUFFER);
     337             :         }
     338           0 :         buf = static_cast<uchar *>(nullptr) + vbooffset;
     339           0 :         if(vertexsize == lastvertexsize && buf >= lastbuf)
     340             :         {
     341           0 :             start = static_cast<int>(buf - lastbuf)/vertexsize;
     342           0 :             buf = lastbuf;
     343             :         }
     344           0 :         vbooffset += attribbuf.length();
     345           0 :         setattribs(buf);
     346           0 :         int numvertexes = attribbuf.length()/vertexsize;
     347           0 :         if(multidrawstart.size())
     348             :         {
     349           0 :             multidraw();
     350           0 :             if(start)
     351             :             {
     352             :                 //offset the buffer indices by start point
     353           0 :                 for(GLint &i : multidrawstart)
     354             :                 {
     355           0 :                     i += start;
     356             :                 }
     357             :             }
     358           0 :             glMultiDrawArrays(primtype, multidrawstart.data(), multidrawcount.data(), multidrawstart.size());
     359           0 :             multidrawstart.clear();
     360           0 :             multidrawcount.clear();
     361             :         }
     362             :         else
     363             :         {
     364           0 :             glDrawArrays(primtype, start, numvertexes);
     365             :         }
     366           0 :         attribbuf.reset(attribdata, maxvbosize);
     367           0 :         return numvertexes;
     368             :     }
     369             : 
     370           0 :     static void forcedisable()
     371             :     {
     372           0 :         for(int i = 0; enabled; i++)
     373             :         {
     374           0 :             if(enabled&(1<<i))
     375             :             {
     376           0 :                 glDisableVertexAttribArray(i);
     377           0 :                 enabled &= ~(1<<i);
     378             :             }
     379             :         }
     380           0 :         numlastattribs = lastattribmask = lastvertexsize = 0;
     381           0 :         lastbuf = nullptr;
     382           0 :         if(quadsenabled)
     383             :         {
     384           0 :             disablequads();
     385             :         }
     386           0 :         glBindBuffer(GL_ARRAY_BUFFER, 0);
     387           0 :     }
     388             : 
     389           0 :     void disable()
     390             :     {
     391           0 :         if(enabled)
     392             :         {
     393           0 :             forcedisable();
     394             :         }
     395           0 :     }
     396             : 
     397           0 :     void setup()
     398             :     {
     399           0 :         if(!defaultvao)
     400             :         {
     401           0 :             glGenVertexArrays(1, &defaultvao);
     402             :         }
     403           0 :         glBindVertexArray(defaultvao);
     404           0 :         attribdata = new uchar[maxvbosize];
     405           0 :         attribbuf.reset(attribdata, maxvbosize);
     406           0 :     }
     407             : 
     408           0 :     void cleanup()
     409             :     {
     410           0 :         disable();
     411           0 :         if(quadindexes)
     412             :         {
     413           0 :             glDeleteBuffers(1, &quadindexes);
     414           0 :             quadindexes = 0;
     415             :         }
     416           0 :         if(vbo)
     417             :         {
     418           0 :             glDeleteBuffers(1, &vbo);
     419           0 :             vbo = 0;
     420             :         }
     421           0 :         vbooffset = maxvbosize;
     422           0 :         if(defaultvao)
     423             :         {
     424           0 :             glDeleteVertexArrays(1, &defaultvao);
     425           0 :             defaultvao = 0;
     426             :         }
     427           0 :     }
     428             : 
     429           0 :     void defvertex(int size, int format)
     430             :     {
     431           0 :         defattrib(Attribute_Vertex, size, format);
     432           0 :     }
     433             : 
     434           0 :     void defcolor(int size, int format)
     435             :     {
     436           0 :         defattrib(Attribute_Color, size, format);
     437           0 :     }
     438             : 
     439           0 :     void deftexcoord0(int size, int format)
     440             :     {
     441           0 :         defattrib(Attribute_TexCoord0, size, format);
     442           0 :     }
     443             : 
     444           0 :     void defnormal(int size, int format)
     445             :     {
     446           0 :         defattrib(Attribute_Normal, size, format);
     447           0 :     }
     448             : 
     449           0 :     void colorf(float x, float y, float z, float w)
     450             :     {
     451           0 :         if(w != 0.0f)
     452             :         {
     453           0 :             glVertexAttrib4f(Attribute_Color, x, y, z, w);
     454             :         }
     455             :         else
     456             :         {
     457           0 :             glVertexAttrib3f(Attribute_Color, x, y, z);
     458             :         }
     459           0 :     }
     460             : 
     461           0 :     void color(const vec &v)
     462             :     {
     463           0 :         glVertexAttrib3fv(Attribute_Color, v.v);
     464           0 :     }
     465             : 
     466           0 :     void color(const vec &v, float w)
     467             :     {
     468           0 :         glVertexAttrib4f(Attribute_Color, v.x, v.y, v.z, w);
     469           0 :     }
     470             : 
     471           0 :     void colorub(uchar x, uchar y, uchar z, uchar w)
     472             :     {
     473           0 :         glVertexAttrib4Nub(Attribute_Color, x, y, z, w);
     474           0 :     }
     475             : 
     476           0 :     void color(const bvec &v, uchar alpha)
     477             :     {
     478           0 :         glVertexAttrib4Nub(Attribute_Color, v.x, v.y, v.z, alpha);
     479           0 :     }
     480             : 
     481           0 :     void enablevertex()
     482             :     {
     483           0 :         disable();
     484           0 :         glEnableVertexAttribArray(Attribute_Vertex);
     485           0 :     }
     486             : 
     487           0 :     void disablevertex()
     488             :     {
     489           0 :         glDisableVertexAttribArray(Attribute_Vertex);
     490           0 :     }
     491           0 :     void vertexpointer(int stride, const void *data, GLenum type, int size, GLenum normalized)
     492             :     {
     493           0 :         disable();
     494           0 :         glVertexAttribPointer(Attribute_Vertex, size, type, normalized, stride, data);
     495           0 :     }
     496           0 :     void enablecolor()
     497             :     {
     498           0 :         glEnableVertexAttribArray(Attribute_Color);
     499           0 :     }
     500           0 :     void disablecolor()
     501             :     {
     502           0 :         glDisableVertexAttribArray(Attribute_Color);
     503           0 :     }
     504           0 :     void colorpointer(int stride, const void *data, GLenum type, int size, GLenum normalized)
     505             :     {
     506           0 :         glVertexAttribPointer(Attribute_Color, size, type, normalized, stride, data);
     507           0 :     }
     508             : 
     509           0 :     void enabletexcoord0()
     510             :     {
     511           0 :         glEnableVertexAttribArray(Attribute_TexCoord0);
     512           0 :     }
     513             : 
     514           0 :     void disabletexcoord0()
     515             :     {
     516           0 :         glDisableVertexAttribArray(Attribute_TexCoord0);
     517           0 :     }
     518             : 
     519           0 :     void texcoord0pointer(int stride, const void *data, GLenum type, int size, GLenum normalized)
     520             :     {
     521           0 :         glVertexAttribPointer(Attribute_TexCoord0, size, type, normalized, stride, data);
     522           0 :     }
     523             : 
     524           0 :     void enablenormal()
     525             :     {
     526           0 :         glEnableVertexAttribArray(Attribute_Normal);
     527           0 :     }
     528             : 
     529           0 :     void disablenormal()
     530             :     {
     531           0 :         glDisableVertexAttribArray(Attribute_Normal);
     532           0 :     }
     533             : 
     534           0 :     void normalpointer(int stride, const void *data, GLenum type, int size, GLenum normalized)
     535             :     {
     536           0 :         glVertexAttribPointer(Attribute_Normal, size, type, normalized, stride, data);
     537           0 :     }
     538             : 
     539           0 :     void enabletangent()
     540             :     {
     541           0 :         glEnableVertexAttribArray(Attribute_Tangent);
     542           0 :     }
     543             : 
     544           0 :     void disabletangent()
     545             :     {
     546           0 :         glDisableVertexAttribArray(Attribute_Tangent);
     547           0 :     }
     548             : 
     549           0 :     void tangentpointer(int stride, const void *data, GLenum type, int size, GLenum normalized)
     550             :     {
     551           0 :         glVertexAttribPointer(Attribute_Tangent, size, type, normalized, stride, data);
     552           0 :     }
     553             : 
     554           0 :     void enableboneweight()
     555             :     {
     556           0 :         glEnableVertexAttribArray(Attribute_BoneWeight);
     557           0 :     }
     558             : 
     559           0 :     void disableboneweight()
     560             :     {
     561           0 :         glDisableVertexAttribArray(Attribute_BoneWeight);
     562           0 :     }
     563             : 
     564           0 :     void boneweightpointer(int stride, const void *data, GLenum type, int size, GLenum normalized)
     565             :     {
     566           0 :         glVertexAttribPointer(Attribute_BoneWeight, size, type, normalized, stride, data);
     567           0 :     }
     568             : 
     569           0 :     void enableboneindex()
     570             :     {
     571           0 :         glEnableVertexAttribArray(Attribute_BoneIndex);
     572           0 :     }
     573             : 
     574           0 :     void disableboneindex()
     575             :     {
     576           0 :         glDisableVertexAttribArray(Attribute_BoneIndex);
     577           0 :     }
     578             : 
     579           0 :     void boneindexpointer(int stride, const void *data, GLenum type, int size, GLenum normalized)
     580             :     {
     581           0 :         glVertexAttribPointer(Attribute_BoneIndex, size, type, normalized, stride, data);
     582           0 :     }
     583             : 
     584           0 :     void bindebo(GLuint ebo)
     585             :     {
     586           0 :         disable();
     587           0 :         glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
     588           0 :     }
     589             : 
     590           0 :     void clearebo()
     591             :     {
     592           0 :         glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
     593           0 :     }
     594             : 
     595           0 :     void bindvbo(GLuint vbo)
     596             :     {
     597           0 :         disable();
     598           0 :         glBindBuffer(GL_ARRAY_BUFFER, vbo);
     599           0 :     }
     600             : 
     601           0 :     void clearvbo()
     602             :     {
     603           0 :         glBindBuffer(GL_ARRAY_BUFFER, 0);
     604           0 :     }
     605             : 
     606             :     template<class T>
     607           0 :     void attrib(T x, T y)
     608             :     {
     609           0 :         if(attribbuf.check(2*sizeof(T)))
     610             :         {
     611           0 :             T *buf = (T *)attribbuf.pad(2*sizeof(T));
     612           0 :             buf[0] = x;
     613           0 :             buf[1] = y;
     614             :         }
     615           0 :     }
     616             : 
     617             :     template<class T>
     618           0 :     void attrib(T x, T y, T z)
     619             :     {
     620           0 :         if(attribbuf.check(3*sizeof(T)))
     621             :         {
     622           0 :             T *buf = (T *)attribbuf.pad(3*sizeof(T));
     623           0 :             buf[0] = x;
     624           0 :             buf[1] = y;
     625           0 :             buf[2] = z;
     626             :         }
     627           0 :     }
     628             : 
     629             :     template<class T>
     630           0 :     void attrib(T x, T y, T z, T w)
     631             :     {
     632           0 :         if(attribbuf.check(4*sizeof(T)))
     633             :         {
     634           0 :             T *buf = (T *)attribbuf.pad(4*sizeof(T));
     635           0 :             buf[0] = x;
     636           0 :             buf[1] = y;
     637           0 :             buf[2] = z;
     638           0 :             buf[3] = w;
     639             :         }
     640           0 :     }
     641             : 
     642           0 :     void attribf(float x, float y)
     643             :     {
     644           0 :         attrib<float>(x, y);
     645           0 :     }
     646             : 
     647           0 :     void attribf(float x, float y, float z)
     648             :     {
     649           0 :         attrib<float>(x, y, z);
     650           0 :     }
     651             : 
     652           0 :     void attribub(uchar x, uchar y, uchar z, uchar w)
     653             :     {
     654           0 :         attrib<uchar>(x, y, z, w);
     655           0 :     }
     656             : 
     657           0 :     void attrib(const vec &v)
     658             :     {
     659           0 :         attrib<float>(v.x, v.y, v.z);
     660           0 :     }
     661             : 
     662           0 :     void attrib(const vec &v, float w)
     663             :     {
     664           0 :         attrib<float>(v.x, v.y, v.z, w);
     665           0 :     }
     666             : 
     667           0 :     void attrib(const vec2 &v)
     668             :     {
     669           0 :         attrib<float>(v.x, v.y);
     670           0 :     }
     671             : }
     672             : 

Generated by: LCOV version 1.14