rearranged r_speeds report a bit, and split up reporting of meshtris into normal...
authorlordhavoc <lordhavoc@d7cf8633-e32d-0410-b094-e92efae38249>
Sun, 3 Feb 2002 10:40:46 +0000 (10:40 +0000)
committerlordhavoc <lordhavoc@d7cf8633-e32d-0410-b094-e92efae38249>
Sun, 3 Feb 2002 10:40:46 +0000 (10:40 +0000)
made byte color array format work (byte format is very slightly faster than float)
disabled float color array format to save some memory
added gl_mesh_sorttransbymesh cvar (default: on) to get a performance gain in mingled mesh conditions (by never mingling triangles of different meshs), this mode can batch render transparent triangles too (unlike the other two modes)
increased default maxtriangles to 8192

git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@1484 d7cf8633-e32d-0410-b094-e92efae38249

gl_backend.c
gl_backend.h
gl_screen.c

index cf86ac6..e1bd699 100644 (file)
@@ -6,16 +6,21 @@ static int max_batch;
 static int max_verts; // always max_meshs * 3
 #define TRANSDEPTHRES 4096
 
+//#define FLOATCOLORS
+
 //static cvar_t gl_mesh_maxtriangles = {0, "gl_mesh_maxtriangles", "21760"};
-static cvar_t gl_mesh_maxtriangles = {0, "gl_mesh_maxtriangles", "4096"};
+static cvar_t gl_mesh_maxtriangles = {0, "gl_mesh_maxtriangles", "8192"};
 static cvar_t gl_mesh_batchtriangles = {0, "gl_mesh_batchtriangles", "1024"};
 static cvar_t gl_mesh_merge = {0, "gl_mesh_merge", "1"};
+#if FLOATCOLORS
 static cvar_t gl_mesh_floatcolors = {0, "gl_mesh_floatcolors", "1"};
+#endif
 static cvar_t gl_mesh_dupetransverts = {0, "gl_mesh_dupetransverts", "0"};
+static cvar_t gl_mesh_sorttransbymesh = {0, "gl_mesh_sorttransbymesh", "1"};
 
 typedef struct buf_mesh_s
 {
-       struct buf_mesh_s *next;
+       //struct buf_mesh_s *next;
        int depthmask;
        int depthtest;
        int blendfunc1, blendfunc2;
@@ -25,12 +30,16 @@ typedef struct buf_mesh_s
        int triangles;
        int firstvert;
        int lastvert;
+       struct buf_mesh_s *chain;
+       struct buf_transtri_s *transchain;
+       //struct buf_transtri_s **transchainpointer;
 }
 buf_mesh_t;
 
 typedef struct buf_transtri_s
 {
        struct buf_transtri_s *next;
+       struct buf_transtri_s *meshsortchain;
        buf_mesh_t *mesh;
        int index[3];
 }
@@ -48,11 +57,13 @@ typedef struct
 }
 buf_vertex_t;
 
+#if FLOATCOLORS
 typedef struct
 {
        float c[4];
 }
 buf_fcolor_t;
+#endif
 
 typedef struct
 {
@@ -67,11 +78,16 @@ typedef struct
 buf_texcoord_t;
 
 static float meshfarclip;
-static int currentmesh, currenttriangle, currentvertex, backendunits, backendactive, meshmerge, floatcolors, transranout;
+static int currentmesh, currenttriangle, currentvertex, backendunits, backendactive, meshmerge, transranout;
+#if FLOATCOLORS
+static int floatcolors;
+#endif
 static buf_mesh_t *buf_mesh;
 static buf_tri_t *buf_tri;
 static buf_vertex_t *buf_vertex;
+#if FLOATCOLORS
 static buf_fcolor_t *buf_fcolor;
+#endif
 static buf_bcolor_t *buf_bcolor;
 static buf_texcoord_t *buf_texcoord[MAX_TEXTUREUNITS];
 
@@ -80,7 +96,9 @@ static buf_mesh_t *buf_transmesh;
 static buf_transtri_t *buf_transtri;
 static buf_transtri_t **buf_transtri_list;
 static buf_vertex_t *buf_transvertex;
+#if FLOATCOLORS
 static buf_fcolor_t *buf_transfcolor;
+#endif
 static buf_bcolor_t *buf_transbcolor;
 static buf_texcoord_t *buf_transtexcoord[MAX_TEXTUREUNITS];
 
@@ -107,14 +125,18 @@ static void gl_backend_start(void)
        BACKENDALLOC(buf_mesh, max_meshs, buf_mesh_t)
        BACKENDALLOC(buf_tri, max_meshs, buf_tri_t)
        BACKENDALLOC(buf_vertex, max_verts, buf_vertex_t)
+#if FLOATCOLORS
        BACKENDALLOC(buf_fcolor, max_verts, buf_fcolor_t)
+#endif
        BACKENDALLOC(buf_bcolor, max_verts, buf_bcolor_t)
 
        BACKENDALLOC(buf_transmesh, max_meshs, buf_mesh_t)
        BACKENDALLOC(buf_transtri, max_meshs, buf_transtri_t)
        BACKENDALLOC(buf_transtri_list, TRANSDEPTHRES, buf_transtri_t *)
        BACKENDALLOC(buf_transvertex, max_verts, buf_vertex_t)
+#if FLOATCOLORS
        BACKENDALLOC(buf_transfcolor, max_verts, buf_fcolor_t)
+#endif
        BACKENDALLOC(buf_transbcolor, max_verts, buf_bcolor_t)
 
        for (i = 0;i < MAX_TEXTUREUNITS;i++)
@@ -152,14 +174,18 @@ static void gl_backend_shutdown(void)
        BACKENDFREE(buf_mesh)
        BACKENDFREE(buf_tri)
        BACKENDFREE(buf_vertex)
+#if FLOATCOLORS
        BACKENDFREE(buf_fcolor)
+#endif
        BACKENDFREE(buf_bcolor)
 
        BACKENDFREE(buf_transmesh)
        BACKENDFREE(buf_transtri)
        BACKENDFREE(buf_transtri_list)
        BACKENDFREE(buf_transvertex)
+#if FLOATCOLORS
        BACKENDFREE(buf_transfcolor)
+#endif
        BACKENDFREE(buf_transbcolor)
 
        for (i = 0;i < MAX_TEXTUREUNITS;i++)
@@ -222,8 +248,11 @@ void gl_backend_init(void)
        Cvar_RegisterVariable(&gl_mesh_maxtriangles);
        Cvar_RegisterVariable(&gl_mesh_batchtriangles);
        Cvar_RegisterVariable(&gl_mesh_merge);
+#if FLOATCOLORS
        Cvar_RegisterVariable(&gl_mesh_floatcolors);
+#endif
        Cvar_RegisterVariable(&gl_mesh_dupetransverts);
+       Cvar_RegisterVariable(&gl_mesh_sorttransbymesh);
        R_RegisterModule("GL_Backend", gl_backend_start, gl_backend_shutdown, gl_backend_newmap);
        gl_backend_bufferchanges(true);
        for (i = 0;i < 256;i++)
@@ -236,7 +265,7 @@ void gl_backend_init(void)
 
 static float viewdist;
 
-int c_meshtris;
+int c_meshs, c_meshtris, c_transmeshs, c_transtris;
 
 // called at beginning of frame
 void R_Mesh_Clear(void)
@@ -254,11 +283,16 @@ void R_Mesh_Clear(void)
        currenttransvertex = 0;
        meshfarclip = 0;
        meshmerge = gl_mesh_merge.integer;
+#if FLOATCOLORS
        floatcolors = gl_mesh_floatcolors.integer;
+#endif
        transranout = false;
        viewdist = DotProduct(r_origin, vpn);
 
+       c_meshs = 0;
        c_meshtris = 0;
+       c_transmeshs = 0;
+       c_transtris = 0;
 }
 
 #ifdef DEBUGGL
@@ -350,6 +384,7 @@ CHECKGLERROR
 CHECKGLERROR
        glEnableClientState(GL_VERTEX_ARRAY);
 CHECKGLERROR
+#if FLOATCOLORS
        if (floatcolors)
        {
                glColorPointer(4, GL_FLOAT, sizeof(buf_fcolor_t), buf_fcolor);
@@ -357,9 +392,12 @@ CHECKGLERROR
        }
        else
        {
+#endif
                glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(buf_bcolor_t), buf_bcolor);
 CHECKGLERROR
+#if FLOATCOLORS
        }
+#endif
        glEnableClientState(GL_COLOR_ARRAY);
 CHECKGLERROR
 
@@ -693,7 +731,191 @@ CHECKGLERROR
 
 void R_Mesh_AddTransparent(void)
 {
-       if (gl_mesh_dupetransverts.integer)
+       if (gl_mesh_sorttransbymesh.integer)
+       {
+               int i, j, k;
+               float viewdistcompare, centerscaler, dist1, dist2, dist3, center, maxdist;
+               buf_vertex_t *vert1, *vert2, *vert3;
+               buf_transtri_t *tri;
+               buf_mesh_t *mesh, *transmesh;
+
+               // process and add transparent mesh triangles
+               if (!currenttranstriangle)
+                       return;
+
+               // map farclip to 0-4095 list range
+               centerscaler = (TRANSDEPTHRES / r_farclip) * (1.0f / 3.0f);
+               viewdistcompare = viewdist + 4.0f;
+
+               memset(buf_transtri_list, 0, TRANSDEPTHRES * sizeof(buf_transtri_t *));
+
+               k = 0;
+               for (j = 0;j < currenttranstriangle;j++)
+               {
+                       tri = &buf_transtri[j];
+
+                       vert1 = &buf_transvertex[tri->index[0]];
+                       vert2 = &buf_transvertex[tri->index[1]];
+                       vert3 = &buf_transvertex[tri->index[2]];
+
+                       dist1 = DotProduct(vert1->v, vpn);
+                       dist2 = DotProduct(vert2->v, vpn);
+                       dist3 = DotProduct(vert3->v, vpn);
+
+                       maxdist = max(dist1, max(dist2, dist3));
+                       if (maxdist < viewdistcompare)
+                               continue;
+
+                       center = (dist1 + dist2 + dist3) * centerscaler - viewdist;
+       #if SLOWMATH
+                       i = (int) center;
+                       i = bound(0, i, (TRANSDEPTHRES - 1));
+       #else
+                       if (center < 0.0f)
+                               center = 0.0f;
+                       center += 8388608.0f;
+                       i = *((long *)&center) & 0x7FFFFF;
+                       i = min(i, (TRANSDEPTHRES - 1));
+       #endif
+                       tri->next = buf_transtri_list[i];
+                       buf_transtri_list[i] = tri;
+                       k++;
+               }
+
+               #ifndef TRANSBATCH
+               if (currentmesh + k > max_meshs || currenttriangle + k > max_batch || currentvertex + currenttransvertex > max_verts)
+                       R_Mesh_Render();
+
+               // note: can't batch these because they can be rendered in any order
+               // there can never be more transparent triangles than fit in main buffers
+               memcpy(&buf_vertex[currentvertex], &buf_transvertex[0], currenttransvertex * sizeof(buf_vertex_t));
+#if FLOATCOLORS
+               if (floatcolors)
+                       memcpy(&buf_fcolor[currentvertex], &buf_transfcolor[0], currenttransvertex * sizeof(buf_fcolor_t));
+               else
+#endif
+                       memcpy(&buf_bcolor[currentvertex], &buf_transbcolor[0], currenttransvertex * sizeof(buf_bcolor_t));
+               for (i = 0;i < backendunits;i++)
+                       memcpy(&buf_texcoord[i][currentvertex], &buf_transtexcoord[i][0], currenttransvertex * sizeof(buf_texcoord_t));
+               #endif
+
+               for (i = 0;i < currenttransmesh;i++)
+               {
+                       buf_transmesh[i].transchain = NULL;
+                       //buf_transmesh[i].transchainpointer = &buf_transmesh[i].transchain;
+                       buf_transmesh[i].triangles = 0;
+               }
+               transmesh = NULL;
+               for (j = 0;j < TRANSDEPTHRES;j++)
+               {
+                       if ((tri = buf_transtri_list[j]))
+                       {
+                               for (;tri;tri = tri->next)
+                               {
+                                       if (!tri->mesh->transchain)
+                                       {
+                                               tri->mesh->chain = transmesh;
+                                               transmesh = tri->mesh;
+                                       }
+                                       tri->meshsortchain = tri->mesh->transchain;
+                                       tri->mesh->transchain = tri;
+                                       /*
+                                       *tri->mesh->transchainpointer = tri;
+                                       tri->meshsortchain = NULL;
+                                       tri->mesh->transchainpointer = &tri->meshsortchain;
+                                       */
+                                       tri->mesh->triangles++;
+                               }
+                       }
+               }
+
+               #if TRANSBATCH
+               for (;transmesh;transmesh = transmesh->chain)
+               {
+                       int meshvertexadjust;
+                       int numverts = transmesh->lastvert - transmesh->firstvert + 1;
+                       if (currentmesh >= max_meshs || currenttriangle + transmesh->triangles > max_batch || currentvertex + numverts > max_verts)
+                               R_Mesh_Render();
+
+                       memcpy(&buf_vertex[currentvertex], &buf_transvertex[transmesh->firstvert], numverts * sizeof(buf_vertex_t));
+#if FLOATCOLORS
+                       if (floatcolors)
+                               memcpy(&buf_fcolor[currentvertex], &buf_transfcolor[transmesh->firstvert], numverts * sizeof(buf_fcolor_t));
+                       else
+#endif
+                               memcpy(&buf_bcolor[currentvertex], &buf_transbcolor[transmesh->firstvert], numverts * sizeof(buf_bcolor_t));
+                       for (i = 0;i < backendunits && transmesh->textures[i];i++)
+                               memcpy(&buf_texcoord[i][currentvertex], &buf_transtexcoord[i][transmesh->firstvert], numverts * sizeof(buf_texcoord_t));
+
+                       mesh = &buf_mesh[currentmesh++];
+                       *mesh = *transmesh; // copy mesh properties
+                       mesh->firstvert = currentvertex;
+                       mesh->lastvert = currentvertex + numverts - 1;
+                       currentvertex += numverts;
+                       meshvertexadjust = mesh->firstvert - transmesh->firstvert;
+                       mesh->firsttriangle = currenttriangle;
+                       for (tri = transmesh->transchain;tri;tri = tri->meshsortchain)
+                       {
+                               buf_tri[currenttriangle].index[0] = tri->index[0] + meshvertexadjust;
+                               buf_tri[currenttriangle].index[1] = tri->index[1] + meshvertexadjust;
+                               buf_tri[currenttriangle].index[2] = tri->index[2] + meshvertexadjust;
+                               /*
+                               if (tri->mesh != transmesh)
+                                       Sys_Error("!?!");
+                               if ((unsigned int) buf_tri[currenttriangle].index[0] < (unsigned int) mesh->firstvert
+                                || (unsigned int) buf_tri[currenttriangle].index[0] > (unsigned int) mesh->lastvert
+                                || (unsigned int) buf_tri[currenttriangle].index[1] < (unsigned int) mesh->firstvert
+                                || (unsigned int) buf_tri[currenttriangle].index[1] > (unsigned int) mesh->lastvert
+                                || (unsigned int) buf_tri[currenttriangle].index[2] < (unsigned int) mesh->firstvert
+                                || (unsigned int) buf_tri[currenttriangle].index[2] > (unsigned int) mesh->lastvert)
+                                       Sys_Error("!?");
+                               */
+                               currenttriangle++;
+                       }
+                       /*
+                       if (mesh->triangles != currenttriangle - mesh->firsttriangle)
+                               Sys_Error("!");
+                       */
+               }
+               #else
+               for (;transmesh;transmesh = transmesh->chain)
+               {
+                       mesh = &buf_mesh[currentmesh++];
+                       *mesh = *transmesh; // copy mesh properties
+                       mesh->firstvert += currentvertex;
+                       mesh->lastvert += currentvertex;
+                       mesh->firsttriangle = currenttriangle;
+                       for (tri = transmesh->transchain;tri;tri = tri->meshsortchain)
+                       {
+                               buf_tri[currenttriangle].index[0] = tri->index[0] + currentvertex;
+                               buf_tri[currenttriangle].index[1] = tri->index[1] + currentvertex;
+                               buf_tri[currenttriangle].index[2] = tri->index[2] + currentvertex;
+                               /*
+                               if (tri->mesh != transmesh)
+                                       Sys_Error("!?!");
+                               if ((unsigned int) buf_tri[currenttriangle].index[0] < (unsigned int) mesh->firstvert
+                                || (unsigned int) buf_tri[currenttriangle].index[0] > (unsigned int) mesh->lastvert
+                                || (unsigned int) buf_tri[currenttriangle].index[1] < (unsigned int) mesh->firstvert
+                                || (unsigned int) buf_tri[currenttriangle].index[1] > (unsigned int) mesh->lastvert
+                                || (unsigned int) buf_tri[currenttriangle].index[2] < (unsigned int) mesh->firstvert
+                                || (unsigned int) buf_tri[currenttriangle].index[2] > (unsigned int) mesh->lastvert)
+                                       Sys_Error("!?");
+                               */
+                               currenttriangle++;
+                       }
+                       /*
+                       if (mesh->triangles != currenttriangle - mesh->firsttriangle)
+                               Sys_Error("!");
+                       */
+               }
+               currentvertex += currenttransvertex;
+               #endif
+
+               currenttransmesh = 0;
+               currenttranstriangle = 0;
+               currenttransvertex = 0;
+       }
+       else if (gl_mesh_dupetransverts.integer)
        {
                int i, j, k, index;
                float viewdistcompare, centerscaler, dist1, dist2, dist3, center, maxdist;
@@ -771,9 +993,11 @@ void R_Mesh_AddTransparent(void)
                                                index = tri->index[k];
                                                buf_tri[currenttriangle].index[k] = currentvertex;
                                                memcpy(buf_vertex[currentvertex].v, buf_transvertex[index].v, sizeof(buf_vertex_t));
+#if FLOATCOLORS
                                                if (floatcolors)
                                                        memcpy(buf_fcolor[currentvertex].c, buf_transfcolor[index].c, sizeof(buf_fcolor_t));
                                                else
+#endif
                                                        memcpy(buf_bcolor[currentvertex].c, buf_transbcolor[index].c, sizeof(buf_bcolor_t));
                                                for (i = 0;i < backendunits && tri->mesh->textures[i];i++)
                                                        memcpy(buf_texcoord[i][currentvertex].t, buf_transtexcoord[i][index].t, sizeof(buf_texcoord_t));
@@ -843,10 +1067,12 @@ void R_Mesh_AddTransparent(void)
                // note: can't batch these because they can be rendered in any order
                // there can never be more transparent triangles than fit in main buffers
                memcpy(&buf_vertex[currentvertex], &buf_transvertex[0], currenttransvertex * sizeof(buf_vertex_t));
+#if FLOATCOLORS
                if (floatcolors)
                        memcpy(&buf_fcolor[currentvertex], &buf_transfcolor[0], currenttransvertex * sizeof(buf_fcolor_t));
                else
-                       memcpy(&buf_fcolor[currentvertex], &buf_transbcolor[0], currenttransvertex * sizeof(buf_bcolor_t));
+#endif
+                       memcpy(&buf_bcolor[currentvertex], &buf_transbcolor[0], currenttransvertex * sizeof(buf_bcolor_t));
                for (i = 0;i < backendunits;i++)
                        memcpy(&buf_texcoord[i][currentvertex], &buf_transtexcoord[i][0], currenttransvertex * sizeof(buf_texcoord_t));
 
@@ -880,14 +1106,19 @@ void R_Mesh_Draw(const rmeshinfo_t *m)
 {
        // these are static because gcc runs out of virtual registers otherwise
        static int i, j, *index, overbright;
-       static float c, *in, scaler, cr, cg, cb, ca;
+       static float c, *in, scaler;
+#if FLOATCOLORS
+       static float cr, cg, cb, ca;
+#endif
        static buf_mesh_t *mesh;
        static buf_vertex_t *vert;
+#if FLOATCOLORS
        static buf_fcolor_t *fcolor;
+#endif
        static buf_bcolor_t *bcolor;
        static buf_texcoord_t *texcoord[MAX_TEXTUREUNITS];
        static buf_transtri_t *tri;
-       static byte br, bg, bb, ba;
+       static buf_bcolor_t flatbcolor;
 
        if (m->index == NULL
         || !m->numtriangles
@@ -942,8 +1173,12 @@ void R_Mesh_Draw(const rmeshinfo_t *m)
                        return;
                }
 
+               c_transmeshs++;
+               c_transtris += m->numtriangles;
                vert = &buf_transvertex[currenttransvertex];
+#if FLOATCOLORS
                fcolor = &buf_transfcolor[currenttransvertex];
+#endif
                bcolor = &buf_transbcolor[currenttransvertex];
                for (i = 0;i < backendunits;i++)
                        texcoord[i] = &buf_transtexcoord[i][currenttransvertex];
@@ -951,21 +1186,6 @@ void R_Mesh_Draw(const rmeshinfo_t *m)
                // transmesh is only for storage of transparent meshs until they
                // are inserted into the main mesh array
                mesh = &buf_transmesh[currenttransmesh++];
-               mesh->blendfunc1 = m->blendfunc1;
-               mesh->blendfunc2 = m->blendfunc2;
-               mesh->depthmask = false;
-               mesh->depthtest = !m->depthdisable;
-               j = -1;
-               for (i = 0;i < backendunits;i++)
-               {
-                       if ((mesh->textures[i] = m->tex[i]))
-                               j = i;
-                       mesh->texturergbscale[i] = m->texrgbscale[i];
-                       if (mesh->texturergbscale[i] != 1 && mesh->texturergbscale[i] != 2 && mesh->texturergbscale[i] != 4)
-                               mesh->texturergbscale[i] = 1;
-               }
-               if (overbright && j >= 0)
-                       mesh->texturergbscale[j] = 4;
 
                // transparent meshs are broken up into individual triangles which can
                // be sorted by depth
@@ -979,6 +1199,8 @@ void R_Mesh_Draw(const rmeshinfo_t *m)
                        tri->index[2] = *index++ + currenttransvertex;
                }
 
+               mesh->firstvert = currenttransvertex;
+               mesh->lastvert = currenttransvertex + m->numverts - 1;
                currenttransvertex += m->numverts;
        }
        else
@@ -992,44 +1214,46 @@ void R_Mesh_Draw(const rmeshinfo_t *m)
                if (currentmesh >= max_meshs || (currenttriangle + m->numtriangles) > max_batch || (currentvertex + m->numverts) > max_verts)
                        R_Mesh_Render();
 
+               c_meshs++;
+               c_meshtris += m->numtriangles;
                vert = &buf_vertex[currentvertex];
+#if FLOATCOLORS
                fcolor = &buf_fcolor[currentvertex];
+#endif
                bcolor = &buf_bcolor[currentvertex];
                for (i = 0;i < backendunits;i++)
                        texcoord[i] = &buf_texcoord[i][currentvertex];
 
                mesh = &buf_mesh[currentmesh++];
-               mesh->blendfunc1 = m->blendfunc1;
-               mesh->blendfunc2 = m->blendfunc2;
-               mesh->depthmask = (m->blendfunc2 == GL_ZERO || m->depthwrite);
-               mesh->depthtest = !m->depthdisable;
-               mesh->firsttriangle = currenttriangle;
-               mesh->triangles = m->numtriangles;
-               j = -1;
-               for (i = 0;i < backendunits;i++)
-               {
-                       if ((mesh->textures[i] = m->tex[i]))
-                               j = i;
-                       mesh->texturergbscale[i] = m->texrgbscale[i];
-                       if (mesh->texturergbscale[i] != 1 && mesh->texturergbscale[i] != 2 && mesh->texturergbscale[i] != 4)
-                               mesh->texturergbscale[i] = 1;
-               }
-               if (overbright && j >= 0)
-                       mesh->texturergbscale[j] = 4;
-
                // opaque meshs are rendered directly
                index = (int *)&buf_tri[currenttriangle];
+               mesh->firsttriangle = currenttriangle;
+               currenttriangle += m->numtriangles;
                for (i = 0;i < m->numtriangles * 3;i++)
                        index[i] = m->index[i] + currentvertex;
+
                mesh->firstvert = currentvertex;
-               currenttriangle += m->numtriangles;
+               mesh->lastvert = currentvertex + m->numverts - 1;
                currentvertex += m->numverts;
-               mesh->lastvert = currentvertex - 1;
        }
 
-       // vertex array code is shared for transparent and opaque meshs
-
-       c_meshtris += m->numtriangles;
+       // code shared for transparent and opaque meshs
+       mesh->blendfunc1 = m->blendfunc1;
+       mesh->blendfunc2 = m->blendfunc2;
+       mesh->depthmask = (m->blendfunc2 == GL_ZERO || m->depthwrite);
+       mesh->depthtest = !m->depthdisable;
+       mesh->triangles = m->numtriangles;
+       j = -1;
+       for (i = 0;i < backendunits;i++)
+       {
+               if ((mesh->textures[i] = m->tex[i]))
+                       j = i;
+               mesh->texturergbscale[i] = m->texrgbscale[i];
+               if (mesh->texturergbscale[i] != 1 && mesh->texturergbscale[i] != 2 && mesh->texturergbscale[i] != 4)
+                       mesh->texturergbscale[i] = 1;
+       }
+       if (overbright && j >= 0)
+               mesh->texturergbscale[j] = 4;
 
        if (m->vertexstep != sizeof(buf_vertex_t))
        {
@@ -1043,6 +1267,7 @@ void R_Mesh_Draw(const rmeshinfo_t *m)
        else
                memcpy(vert, m->vertex, m->numverts * sizeof(buf_vertex_t));
 
+#if FLOATCOLORS
        if (floatcolors)
        {
                if (m->color)
@@ -1072,6 +1297,7 @@ void R_Mesh_Draw(const rmeshinfo_t *m)
        }
        else
        {
+#endif
                if (m->color)
                {
                        for (i = 0, in = m->color;i < m->numverts;i++, (int)in += m->colorstep)
@@ -1086,19 +1312,16 @@ void R_Mesh_Draw(const rmeshinfo_t *m)
                }
                else
                {
-                       c = in[0] * scaler + 32768.0f;j = (*((long *)&c) & 0x7FFFFF);if (j > 255) j = 255;br = (byte) j;
-                       c = in[1] * scaler + 32768.0f;j = (*((long *)&c) & 0x7FFFFF);if (j > 255) j = 255;bg = (byte) j;
-                       c = in[2] * scaler + 32768.0f;j = (*((long *)&c) & 0x7FFFFF);if (j > 255) j = 255;bb = (byte) j;
-                       c = in[3]          + 32768.0f;j = (*((long *)&c) & 0x7FFFFF);if (j > 255) j = 255;ba = (byte) j;
+                       c = m->cr * scaler + 32768.0f;j = (*((long *)&c) & 0x7FFFFF);if (j > 255) j = 255;flatbcolor.c[0] = (byte) j;
+                       c = m->cg * scaler + 32768.0f;j = (*((long *)&c) & 0x7FFFFF);if (j > 255) j = 255;flatbcolor.c[1] = (byte) j;
+                       c = m->cb * scaler + 32768.0f;j = (*((long *)&c) & 0x7FFFFF);if (j > 255) j = 255;flatbcolor.c[2] = (byte) j;
+                       c = m->ca          + 32768.0f;j = (*((long *)&c) & 0x7FFFFF);if (j > 255) j = 255;flatbcolor.c[3] = (byte) j;
                        for (i = 0;i < m->numverts;i++)
-                       {
-                               bcolor[i].c[0] = br;
-                               bcolor[i].c[1] = bg;
-                               bcolor[i].c[2] = bb;
-                               bcolor[i].c[3] = ba;
-                       }
+                               bcolor[i] = flatbcolor;
                }
+#if FLOATCOLORS
        }
+#endif
 
        for (j = 0;j < MAX_TEXTUREUNITS && m->tex[j];j++)
        {
@@ -1144,14 +1367,19 @@ void R_Mesh_DrawDecal(const rmeshinfo_t *m)
 {
        // these are static because gcc runs out of virtual registers otherwise
        static int i, j, *index, overbright;
-       static float c, *in, scaler, cr, cg, cb, ca;
+       static float c, scaler;
+#if FLOATCOLORS
+       static float cr, cg, cb, ca;
+#endif
        static buf_mesh_t *mesh;
        static buf_vertex_t *vert;
+#if FLOATCOLORS
        static buf_fcolor_t *fcolor;
+#endif
        static buf_bcolor_t *bcolor;
        static buf_texcoord_t *texcoord;
        static buf_transtri_t *tri;
-       static byte br, bg, bb, ba;
+       static buf_bcolor_t flatbcolor;
 
        if (!backendactive)
                Sys_Error("R_Mesh_Draw: called when backend is not active\n");
@@ -1178,8 +1406,12 @@ void R_Mesh_DrawDecal(const rmeshinfo_t *m)
                        return;
                }
 
+               c_transmeshs++;
+               c_transtris += 2;
                vert = &buf_transvertex[currenttransvertex];
+#if FLOATCOLORS
                fcolor = &buf_transfcolor[currenttransvertex];
+#endif
                bcolor = &buf_transbcolor[currenttransvertex];
                texcoord = &buf_transtexcoord[0][currenttransvertex];
 
@@ -1190,6 +1422,7 @@ void R_Mesh_DrawDecal(const rmeshinfo_t *m)
                mesh->blendfunc2 = m->blendfunc2;
                mesh->depthmask = false;
                mesh->depthtest = true;
+               mesh->triangles = 2;
                mesh->textures[0] = m->tex[0];
                mesh->texturergbscale[0] = overbright ? 4 : 1;
                for (i = 1;i < backendunits;i++)
@@ -1197,6 +1430,7 @@ void R_Mesh_DrawDecal(const rmeshinfo_t *m)
                        mesh->textures[i] = 0;
                        mesh->texturergbscale[i] = 1;
                }
+               mesh->chain = NULL;
 
                // transparent meshs are broken up into individual triangles which can
                // be sorted by depth
@@ -1212,6 +1446,8 @@ void R_Mesh_DrawDecal(const rmeshinfo_t *m)
                tri->index[1] = 2 + currenttransvertex;
                tri->index[2] = 3 + currenttransvertex;
 
+               mesh->firstvert = currenttransvertex;
+               mesh->lastvert = currenttransvertex + 3;
                currenttransvertex += 4;
        }
        else
@@ -1225,8 +1461,12 @@ void R_Mesh_DrawDecal(const rmeshinfo_t *m)
                if (currentmesh >= max_meshs || (currenttriangle + 2) > max_batch || (currentvertex + 4) > max_verts)
                        R_Mesh_Render();
 
+               c_meshs++;
+               c_meshtris += 2;
                vert = &buf_vertex[currentvertex];
+#if FLOATCOLORS
                fcolor = &buf_fcolor[currentvertex];
+#endif
                bcolor = &buf_bcolor[currentvertex];
                texcoord = &buf_texcoord[0][currentvertex];
 
@@ -1254,18 +1494,15 @@ void R_Mesh_DrawDecal(const rmeshinfo_t *m)
                index[4] = 2 + currentvertex;
                index[5] = 3 + currentvertex;
                mesh->firstvert = currentvertex;
+               mesh->lastvert = currentvertex + 3;
                currenttriangle += 2;
                currentvertex += 4;
-               mesh->lastvert = currentvertex - 1;
        }
 
-       // vertex array code is shared for transparent and opaque meshs
-
-       c_meshtris += 2;
-
        // buf_vertex_t must match the size of the decal vertex array (or vice versa)
        memcpy(vert, m->vertex, 4 * sizeof(buf_vertex_t));
 
+#if FLOATCOLORS
        if (floatcolors)
        {
                cr = m->cr * scaler;
@@ -1291,27 +1528,18 @@ void R_Mesh_DrawDecal(const rmeshinfo_t *m)
        }
        else
        {
-               c = in[0] * scaler + 32768.0f;j = (*((long *)&c) & 0x7FFFFF);if (j > 255) j = 255;br = (byte) j;
-               c = in[1] * scaler + 32768.0f;j = (*((long *)&c) & 0x7FFFFF);if (j > 255) j = 255;bg = (byte) j;
-               c = in[2] * scaler + 32768.0f;j = (*((long *)&c) & 0x7FFFFF);if (j > 255) j = 255;bb = (byte) j;
-               c = in[3]          + 32768.0f;j = (*((long *)&c) & 0x7FFFFF);if (j > 255) j = 255;ba = (byte) j;
-               bcolor[0].c[0] = br;
-               bcolor[0].c[1] = bg;
-               bcolor[0].c[2] = bb;
-               bcolor[0].c[3] = ba;
-               bcolor[1].c[0] = br;
-               bcolor[1].c[1] = bg;
-               bcolor[1].c[2] = bb;
-               bcolor[1].c[3] = ba;
-               bcolor[2].c[0] = br;
-               bcolor[2].c[1] = bg;
-               bcolor[2].c[2] = bb;
-               bcolor[2].c[3] = ba;
-               bcolor[3].c[0] = br;
-               bcolor[3].c[1] = bg;
-               bcolor[3].c[2] = bb;
-               bcolor[3].c[3] = ba;
+#endif
+               c = m->cr * scaler + 32768.0f;j = (*((long *)&c) & 0x7FFFFF);if (j > 255) j = 255;flatbcolor.c[0] = (byte) j;
+               c = m->cg * scaler + 32768.0f;j = (*((long *)&c) & 0x7FFFFF);if (j > 255) j = 255;flatbcolor.c[1] = (byte) j;
+               c = m->cb * scaler + 32768.0f;j = (*((long *)&c) & 0x7FFFFF);if (j > 255) j = 255;flatbcolor.c[2] = (byte) j;
+               c = m->ca          + 32768.0f;j = (*((long *)&c) & 0x7FFFFF);if (j > 255) j = 255;flatbcolor.c[3] = (byte) j;
+               bcolor[0] = flatbcolor;
+               bcolor[1] = flatbcolor;
+               bcolor[2] = flatbcolor;
+               bcolor[3] = flatbcolor;
+#if FLOATCOLORS
        }
+#endif
 
        // buf_texcoord_t must be the same size as the decal texcoord array (or vice versa)
        memcpy(&texcoord[0].t[0], m->texcoords[0], 4 * sizeof(buf_texcoord_t));
index 9d13092..6363c54 100644 (file)
@@ -1,7 +1,7 @@
 
 #define MAX_TEXTUREUNITS 4
 
-extern int c_meshtris;
+extern int c_meshtris, c_meshs, c_transtris, c_transmeshs;
 
 typedef struct
 {
index 6eaf808..9aa96b0 100644 (file)
@@ -815,13 +815,15 @@ void R_TimeReport_Start(void)
                //      r_refdef.vieworg[0] < 0 ? '-' : ' ', fabs(r_refdef.vieworg[0]), r_refdef.vieworg[1] < 0 ? '-' : ' ', fabs(r_refdef.vieworg[1]), r_refdef.vieworg[2] < 0 ? '-' : ' ', fabs(r_refdef.vieworg[2]),
                //      r_refdef.viewangles[0] < 0 ? '-' : ' ', fabs(r_refdef.viewangles[0]), r_refdef.viewangles[1] < 0 ? '-' : ' ', fabs(r_refdef.viewangles[1]), r_refdef.viewangles[2] < 0 ? '-' : ' ', fabs(r_refdef.viewangles[2]),
                //      vpn[0] < 0 ? '-' : ' ', fabs(vpn[0]), vpn[1] < 0 ? '-' : ' ', fabs(vpn[1]), vpn[2] < 0 ? '-' : ' ', fabs(vpn[2]),
-               sprintf(r_speeds_string, "org:'%+8.2f %+8.2f %+8.2f' ang:'%+4.0f %+4.0f %+4.0f' dir:'%+2.3f %+2.3f %+2.3f'\n%6i walls %6i dlitwalls %7i modeltris %7i meshtris\nBSP: %6i faces %6i nodes %6i leafs\n%4i models %4i bmodels %4i sprites %5i particles %3i dlights\n",
-                       r_refdef.vieworg[0], r_refdef.vieworg[1], r_refdef.vieworg[2],
-                       r_refdef.viewangles[0], r_refdef.viewangles[1], r_refdef.viewangles[2],
-                       vpn[0], vpn[1], vpn[2],
-                       c_brush_polys, c_light_polys, c_alias_polys, c_meshtris,
-                       c_faces, c_nodes, c_leafs,
-                       c_models, c_bmodels, c_sprites, c_particles, c_dlights);
+               sprintf(r_speeds_string,
+                       "org:'%+8.2f %+8.2f %+8.2f' ang:'%+4.0f %+4.0f %+4.0f' dir:'%+2.3f %+2.3f %+2.3f'\n"
+                       "world:%6i faces%6i nodes%6i leafs%6i walls%6i dlitwalls\n"
+                       "%5i models%5i bmodels%5i sprites%6i particles%4i dlights\n"
+                       "%6i modeltris%6i transmeshs%6i transtris%6i meshs%6i meshtris\n",
+                       r_refdef.vieworg[0], r_refdef.vieworg[1], r_refdef.vieworg[2], r_refdef.viewangles[0], r_refdef.viewangles[1], r_refdef.viewangles[2], vpn[0], vpn[1], vpn[2],
+                       c_faces, c_nodes, c_leafs, c_brush_polys, c_light_polys,
+                       c_models, c_bmodels, c_sprites, c_particles, c_dlights,
+                       c_alias_polys, c_transmeshs, c_transtris, c_meshs, c_meshtris);
 
                c_brush_polys = 0;
                c_alias_polys = 0;