]> de.git.xonotic.org Git - xonotic/darkplaces.git/commitdiff
gl_draw, model_shared: Refactor vertex adding. Add faster codepath that skips hash...
authorcloudwalk <cloudwalk@d7cf8633-e32d-0410-b094-e92efae38249>
Sat, 14 Nov 2020 16:26:31 +0000 (16:26 +0000)
committercloudwalk <cloudwalk@d7cf8633-e32d-0410-b094-e92efae38249>
Sat, 14 Nov 2020 16:26:31 +0000 (16:26 +0000)
git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@13044 d7cf8633-e32d-0410-b094-e92efae38249

cl_screen.c
clvm_cmds.c
draw.h
gl_draw.c
model_shared.c
model_shared.h
r_stats.c

index 186342d1b34b18c9767a25637df17afc4f0d28b6..5b97ccb6c1786cad9d98707ed371aa2ce3155e60 100644 (file)
@@ -285,12 +285,12 @@ static void SCR_DrawNetGraph_DrawGraph (int graphx, int graphy, int graphwidth,
                b = g[(j+1)%NETGRAPH_PACKETS];
                if (a[0] < 0.0f || b[0] > 1.0f || b[0] < a[0])
                        continue;
-               DrawQ_Line(1, graphx + graphwidth * a[0], graphy + graphheight * a[2], graphx + graphwidth * b[0], graphy + graphheight * b[2], 1.0f, 1.0f, 1.0f, 1.0f, 0);
-               DrawQ_Line(1, graphx + graphwidth * a[0], graphy + graphheight * a[1], graphx + graphwidth * b[0], graphy + graphheight * b[1], 1.0f, 0.0f, 0.0f, 1.0f, 0);
-               DrawQ_Line(1, graphx + graphwidth * a[0], graphy + graphheight * a[5], graphx + graphwidth * b[0], graphy + graphheight * b[5], 0.0f, 1.0f, 0.0f, 1.0f, 0);
-               DrawQ_Line(1, graphx + graphwidth * a[0], graphy + graphheight * a[4], graphx + graphwidth * b[0], graphy + graphheight * b[4], 1.0f, 1.0f, 1.0f, 1.0f, 0);
-               DrawQ_Line(1, graphx + graphwidth * a[0], graphy + graphheight * a[3], graphx + graphwidth * b[0], graphy + graphheight * b[3], 1.0f, 0.5f, 0.0f, 1.0f, 0);
-               DrawQ_Line(1, graphx + graphwidth * a[0], graphy + graphheight * a[6], graphx + graphwidth * b[0], graphy + graphheight * b[6], 0.0f, 0.0f, 1.0f, 1.0f, 0);
+               DrawQ_Line(1, graphx + graphwidth * a[0], graphy + graphheight * a[2], graphx + graphwidth * b[0], graphy + graphheight * b[2], 1.0f, 1.0f, 1.0f, 1.0f, 0, true);
+               DrawQ_Line(1, graphx + graphwidth * a[0], graphy + graphheight * a[1], graphx + graphwidth * b[0], graphy + graphheight * b[1], 1.0f, 0.0f, 0.0f, 1.0f, 0, true);
+               DrawQ_Line(1, graphx + graphwidth * a[0], graphy + graphheight * a[5], graphx + graphwidth * b[0], graphy + graphheight * b[5], 0.0f, 1.0f, 0.0f, 1.0f, 0, true);
+               DrawQ_Line(1, graphx + graphwidth * a[0], graphy + graphheight * a[4], graphx + graphwidth * b[0], graphy + graphheight * b[4], 1.0f, 1.0f, 1.0f, 1.0f, 0, true);
+               DrawQ_Line(1, graphx + graphwidth * a[0], graphy + graphheight * a[3], graphx + graphwidth * b[0], graphy + graphheight * b[3], 1.0f, 0.5f, 0.0f, 1.0f, 0, true);
+               DrawQ_Line(1, graphx + graphwidth * a[0], graphy + graphheight * a[6], graphx + graphwidth * b[0], graphy + graphheight * b[6], 0.0f, 0.0f, 1.0f, 1.0f, 0, true);
        }
        x = graphx;
        y = graphy + graphheight;
index adf201441b0e3571c9591d916465d92ef4cb7768..7f2dffbead888798778a99e5c518a02484457ec4 100644 (file)
@@ -1215,7 +1215,7 @@ void VM_drawline (prvm_prog_t *prog)
        rgb             = PRVM_G_VECTOR(OFS_PARM3);
        alpha   = PRVM_G_FLOAT(OFS_PARM4);
        flags   = (int)PRVM_G_FLOAT(OFS_PARM5);
-       DrawQ_Line(width, c1[0], c1[1], c2[0], c2[1], rgb[0], rgb[1], rgb[2], alpha, flags);
+       DrawQ_Line(width, c1[0], c1[1], c2[0], c2[1], rgb[0], rgb[1], rgb[2], alpha, flags, false);
 }
 
 /*
diff --git a/draw.h b/draw.h
index 381dd35ebadc63e4da6d2b2d60237eab4ac2643a..e06f19aab7ed03b6a0d7c536fa89526405dfcc39 100644 (file)
--- a/draw.h
+++ b/draw.h
@@ -174,7 +174,7 @@ void DrawQ_SetClipArea(float x, float y, float width, float height);
 // reset the clipping area
 void DrawQ_ResetClipArea(void);
 // draw a line
-void DrawQ_Line(float width, float x1, float y1, float x2, float y2, float r, float g, float b, float alpha, int flags);
+void DrawQ_Line(float width, float x1, float y1, float x2, float y2, float r, float g, float b, float alpha, int flags, qbool fast);
 
 const char *Draw_GetPicName(cachepic_t *pic);
 int Draw_GetPicWidth(cachepic_t *pic);
index 2211f261cdd99eb5ddff18a567048d03ba57ae77..3de01e19d5c3443f6989a24851d893f1a3b3ef1d 100644 (file)
--- a/gl_draw.c
+++ b/gl_draw.c
@@ -1404,7 +1404,7 @@ void DrawQ_SuperPic(float x, float y, cachepic_t *pic, float width, float height
        Mod_Mesh_AddTriangle(mod, surf, e0, e2, e3);
 }
 
-void DrawQ_Line (float width, float x1, float y1, float x2, float y2, float r, float g, float b, float alpha, int flags)
+void DrawQ_Line (float width, float x1, float y1, float x2, float y2, float r, float g, float b, float alpha, int flags, qbool fast)
 {
        model_t *mod = CL_Mesh_UI();
        msurface_t *surf;
@@ -1422,10 +1422,21 @@ void DrawQ_Line (float width, float x1, float y1, float x2, float y2, float r, f
                offsety = 0;
        }
        surf = Mod_Mesh_AddSurface(mod, Mod_Mesh_GetTexture(mod, "white", 0, 0, MATERIALFLAG_WALL | MATERIALFLAG_VERTEXCOLOR | MATERIALFLAG_ALPHAGEN_VERTEX | MATERIALFLAG_ALPHA | MATERIALFLAG_BLENDED | MATERIALFLAG_NOSHADOW), true);
-       e0 = Mod_Mesh_IndexForVertex(mod, surf, x1 - offsetx, y1 - offsety, 10, 0, 0, -1, 0, 0, 0, 0, r, g, b, alpha);
-       e1 = Mod_Mesh_IndexForVertex(mod, surf, x2 - offsetx, y2 - offsety, 10, 0, 0, -1, 0, 0, 0, 0, r, g, b, alpha);
-       e2 = Mod_Mesh_IndexForVertex(mod, surf, x2 + offsetx, y2 + offsety, 10, 0, 0, -1, 0, 0, 0, 0, r, g, b, alpha);
-       e3 = Mod_Mesh_IndexForVertex(mod, surf, x1 + offsetx, y1 + offsety, 10, 0, 0, -1, 0, 0, 0, 0, r, g, b, alpha);
+       if (fast)
+       {
+               Mod_Mesh_CheckResize_Vertex(mod, surf);
+               e0 = Mod_Mesh_AddVertex(mod, surf, x1 - offsetx, y1 - offsety, 10, 0, 0, -1, 0, 0, 0, 0, r, g, b, alpha);
+               e1 = Mod_Mesh_AddVertex(mod, surf, x2 - offsetx, y2 - offsety, 10, 0, 0, -1, 0, 0, 0, 0, r, g, b, alpha);
+               e2 = Mod_Mesh_AddVertex(mod, surf, x2 + offsetx, y2 + offsety, 10, 0, 0, -1, 0, 0, 0, 0, r, g, b, alpha);
+               e3 = Mod_Mesh_AddVertex(mod, surf, x1 + offsetx, y1 + offsety, 10, 0, 0, -1, 0, 0, 0, 0, r, g, b, alpha);
+       }
+       else
+       {
+               e0 = Mod_Mesh_IndexForVertex(mod, surf, x1 - offsetx, y1 - offsety, 10, 0, 0, -1, 0, 0, 0, 0, r, g, b, alpha);
+               e1 = Mod_Mesh_IndexForVertex(mod, surf, x2 - offsetx, y2 - offsety, 10, 0, 0, -1, 0, 0, 0, 0, r, g, b, alpha);
+               e2 = Mod_Mesh_IndexForVertex(mod, surf, x2 + offsetx, y2 + offsety, 10, 0, 0, -1, 0, 0, 0, 0, r, g, b, alpha);
+               e3 = Mod_Mesh_IndexForVertex(mod, surf, x1 + offsetx, y1 + offsety, 10, 0, 0, -1, 0, 0, 0, 0, r, g, b, alpha);
+       }
        Mod_Mesh_AddTriangle(mod, surf, e0, e1, e2);
        Mod_Mesh_AddTriangle(mod, surf, e0, e2, e3);
 }
index 5c69dd23e1d1d575e74f693eecaf7f425f89b46a..55b4673ea351138c79d11f01c6998a9856e21831 100644 (file)
@@ -4506,10 +4506,31 @@ msurface_t *Mod_Mesh_AddSurface(model_t *mod, texture_t *tex, qbool batchwithpre
        return surf;
 }
 
-int Mod_Mesh_IndexForVertex(model_t *mod, msurface_t *surf, float x, float y, float z, float nx, float ny, float nz, float s, float t, float u, float v, float r, float g, float b, float a)
+static void Mod_Mesh_RebuildHashTable(model_t *mod, msurface_t *surf)
 {
        int hashindex, h, vnum, mask;
        surfmesh_t *mesh = &mod->surfmesh;
+
+       // rebuild the hash table
+       mesh->num_vertexhashsize = 4 * mesh->max_vertices;
+       mesh->num_vertexhashsize &= ~(mesh->num_vertexhashsize - 1); // round down to pow2
+       mesh->data_vertexhash = (int *)Mem_Realloc(mod->mempool, mesh->data_vertexhash, mesh->num_vertexhashsize * sizeof(*mesh->data_vertexhash));
+       memset(mesh->data_vertexhash, -1, mesh->num_vertexhashsize * sizeof(*mesh->data_vertexhash));
+       mask = mod->surfmesh.num_vertexhashsize - 1;
+       // no need to hash the vertices for the entire model, the latest surface will suffice.
+       for (vnum = surf ? surf->num_firstvertex : 0; vnum < mesh->num_vertices; vnum++)
+       {
+               // this uses prime numbers intentionally for computing the hash
+               hashindex = (unsigned int)(mesh->data_vertex3f[vnum * 3 + 0] * 2003 + mesh->data_vertex3f[vnum * 3 + 1] * 4001 + mesh->data_vertex3f[vnum * 3 + 2] * 7919 + mesh->data_normal3f[vnum * 3 + 0] * 4097 + mesh->data_normal3f[vnum * 3 + 1] * 257 + mesh->data_normal3f[vnum * 3 + 2] * 17) & mask;
+               for (h = hashindex; mesh->data_vertexhash[h] >= 0; h = (h + 1) & mask)
+                       ; // just iterate until we find the terminator
+               mesh->data_vertexhash[h] = vnum;
+       }
+}
+
+void Mod_Mesh_CheckResize_Vertex(model_t *mod, msurface_t *surf)
+{
+       surfmesh_t *mesh = &mod->surfmesh;
        if (mesh->max_vertices == mesh->num_vertices)
        {
                mesh->max_vertices = max(mesh->num_vertices * 2, 256);
@@ -4520,36 +4541,15 @@ int Mod_Mesh_IndexForVertex(model_t *mod, msurface_t *surf, float x, float y, fl
                mesh->data_texcoordtexture2f = (float *)Mem_Realloc(mod->mempool, mesh->data_texcoordtexture2f, mesh->max_vertices * sizeof(float[2]));
                mesh->data_texcoordlightmap2f = (float *)Mem_Realloc(mod->mempool, mesh->data_texcoordlightmap2f, mesh->max_vertices * sizeof(float[2]));
                mesh->data_lightmapcolor4f = (float *)Mem_Realloc(mod->mempool, mesh->data_lightmapcolor4f, mesh->max_vertices * sizeof(float[4]));
-               // rebuild the hash table
-               mesh->num_vertexhashsize = 4 * mesh->max_vertices;
-               mesh->num_vertexhashsize &= ~(mesh->num_vertexhashsize - 1); // round down to pow2
-               mesh->data_vertexhash = (int *)Mem_Realloc(mod->mempool, mesh->data_vertexhash, mesh->num_vertexhashsize * sizeof(*mesh->data_vertexhash));
-               memset(mesh->data_vertexhash, -1, mesh->num_vertexhashsize * sizeof(*mesh->data_vertexhash));
-               mask = mod->surfmesh.num_vertexhashsize - 1;
-               // no need to hash the vertices for the entire model, the latest surface will suffice.
-               for (vnum = surf ? surf->num_firstvertex : 0; vnum < mesh->num_vertices; vnum++)
-               {
-                       // this uses prime numbers intentionally for computing the hash
-                       hashindex = (unsigned int)(mesh->data_vertex3f[vnum * 3 + 0] * 2003 + mesh->data_vertex3f[vnum * 3 + 1] * 4001 + mesh->data_vertex3f[vnum * 3 + 2] * 7919 + mesh->data_normal3f[vnum * 3 + 0] * 4097 + mesh->data_normal3f[vnum * 3 + 1] * 257 + mesh->data_normal3f[vnum * 3 + 2] * 17) & mask;
-                       for (h = hashindex; mesh->data_vertexhash[h] >= 0; h = (h + 1) & mask)
-                               ; // just iterate until we find the terminator
-                       mesh->data_vertexhash[h] = vnum;
-               }
-       }
-       mask = mod->surfmesh.num_vertexhashsize - 1;
-       // this uses prime numbers intentionally for computing the hash
-       hashindex = (unsigned int)(x * 2003 + y * 4001 + z * 7919 + nx * 4097 + ny * 257 + nz * 17) & mask;
-       // when possible find an identical vertex within the same surface and return it
-       for(h = hashindex;(vnum = mesh->data_vertexhash[h]) >= 0;h = (h + 1) & mask)
-       {
-               if (vnum >= surf->num_firstvertex
-                && mesh->data_vertex3f[vnum * 3 + 0] == x && mesh->data_vertex3f[vnum * 3 + 1] == y && mesh->data_vertex3f[vnum * 3 + 2] == z
-                && mesh->data_normal3f[vnum * 3 + 0] == nx && mesh->data_normal3f[vnum * 3 + 1] == ny && mesh->data_normal3f[vnum * 3 + 2] == nz
-                && mesh->data_texcoordtexture2f[vnum * 2 + 0] == s && mesh->data_texcoordtexture2f[vnum * 2 + 1] == t
-                && mesh->data_texcoordlightmap2f[vnum * 2 + 0] == u && mesh->data_texcoordlightmap2f[vnum * 2 + 1] == v
-                && mesh->data_lightmapcolor4f[vnum * 4 + 0] == r && mesh->data_lightmapcolor4f[vnum * 4 + 1] == g && mesh->data_lightmapcolor4f[vnum * 4 + 2] == b && mesh->data_lightmapcolor4f[vnum * 4 + 3] == a)
-                       return vnum;
+               Mod_Mesh_RebuildHashTable(mod, surf);
        }
+}
+
+int Mod_Mesh_AddVertex(model_t *mod, msurface_t *surf, float x, float y, float z, float nx, float ny, float nz, float s, float t, float u, float v, float r, float g, float b, float a)
+{
+       int vnum;
+       surfmesh_t *mesh = &mod->surfmesh;
+
        // add the new vertex
        vnum = mesh->num_vertices++;
        if (surf->num_vertices > 0)
@@ -4567,7 +4567,6 @@ int Mod_Mesh_IndexForVertex(model_t *mod, msurface_t *surf, float x, float y, fl
                VectorSet(surf->maxs, x, y, z);
        }
        surf->num_vertices = mesh->num_vertices - surf->num_firstvertex;
-       mesh->data_vertexhash[h] = vnum;
        mesh->data_vertex3f[vnum * 3 + 0] = x;
        mesh->data_vertex3f[vnum * 3 + 1] = y;
        mesh->data_vertex3f[vnum * 3 + 2] = z;
@@ -4585,6 +4584,32 @@ int Mod_Mesh_IndexForVertex(model_t *mod, msurface_t *surf, float x, float y, fl
        return vnum;
 }
 
+int Mod_Mesh_IndexForVertex(model_t *mod, msurface_t *surf, float x, float y, float z, float nx, float ny, float nz, float s, float t, float u, float v, float r, float g, float b, float a)
+{
+       int hashindex, h, vnum, mask;
+       surfmesh_t *mesh = &mod->surfmesh;
+
+       Mod_Mesh_CheckResize_Vertex(mod, surf);
+
+       mask = mod->surfmesh.num_vertexhashsize - 1;
+       // this uses prime numbers intentionally for computing the hash
+       hashindex = (unsigned int)(x * 2003 + y * 4001 + z * 7919 + nx * 4097 + ny * 257 + nz * 17) & mask;
+       // when possible find an identical vertex within the same surface and return it
+       for(h = hashindex;(vnum = mesh->data_vertexhash[h]) >= 0;h = (h + 1) & mask)
+       {
+               if (vnum >= surf->num_firstvertex
+                && mesh->data_vertex3f[vnum * 3 + 0] == x && mesh->data_vertex3f[vnum * 3 + 1] == y && mesh->data_vertex3f[vnum * 3 + 2] == z
+                && mesh->data_normal3f[vnum * 3 + 0] == nx && mesh->data_normal3f[vnum * 3 + 1] == ny && mesh->data_normal3f[vnum * 3 + 2] == nz
+                && mesh->data_texcoordtexture2f[vnum * 2 + 0] == s && mesh->data_texcoordtexture2f[vnum * 2 + 1] == t
+                && mesh->data_texcoordlightmap2f[vnum * 2 + 0] == u && mesh->data_texcoordlightmap2f[vnum * 2 + 1] == v
+                && mesh->data_lightmapcolor4f[vnum * 4 + 0] == r && mesh->data_lightmapcolor4f[vnum * 4 + 1] == g && mesh->data_lightmapcolor4f[vnum * 4 + 2] == b && mesh->data_lightmapcolor4f[vnum * 4 + 3] == a)
+                       return vnum;
+       }
+       vnum = Mod_Mesh_AddVertex(mod, surf, x, y, z, nx, ny, nz, s, t, u, v, r, g, b, a);
+       mesh->data_vertexhash[h] = vnum;
+       return vnum;
+}
+
 void Mod_Mesh_AddTriangle(model_t *mod, msurface_t *surf, int e0, int e1, int e2)
 {
        surfmesh_t *mesh = &mod->surfmesh;
index 0e47778975f340f03aa463641469fdc893460e09..6b0530a889c43c09e0955c74b32e6672d9898da0 100644 (file)
@@ -698,6 +698,8 @@ void Mod_Mesh_Destroy(model_t *mod);
 void Mod_Mesh_Reset(model_t *mod);
 texture_t *Mod_Mesh_GetTexture(model_t *mod, const char *name, int defaultdrawflags, int defaulttexflags, int defaultmaterialflags);
 msurface_t *Mod_Mesh_AddSurface(model_t *mod, texture_t *tex, qbool batchwithprevioussurface);
+void Mod_Mesh_CheckResize_Vertex(model_t *mod, msurface_t *surf);
+int Mod_Mesh_AddVertex(model_t *mod, msurface_t *surf, float x, float y, float z, float nx, float ny, float nz, float s, float t, float u, float v, float r, float g, float b, float a);
 int Mod_Mesh_IndexForVertex(model_t *mod, msurface_t *surf, float x, float y, float z, float nx, float ny, float nz, float s, float t, float u, float v, float r, float g, float b, float a);
 void Mod_Mesh_AddTriangle(model_t *mod, msurface_t *surf, int e0, int e1, int e2);
 void Mod_Mesh_Validate(model_t *mod);
index 6dfc7938f917c294aa551e31af936c77f44e1e26..edb4625f54804640bdb7e25c3aaa2c7f2723b982 100644 (file)
--- a/r_stats.c
+++ b/r_stats.c
@@ -504,7 +504,7 @@ void R_TimeReport_EndFrame(void)
                                        i++;
                                        x2 = max(x, x + width - sum * scalex);
                                        y2 = y + height - (data[index] - range_min) * scaley;
-                                       DrawQ_Line(1, x1, y1, x2, y2, r_speeds_graph_colors[color][0], r_speeds_graph_colors[color][1], r_speeds_graph_colors[color][2], r_speeds_graph_colors[color][3], 0);
+                                       DrawQ_Line(1, x1, y1, x2, y2, r_speeds_graph_colors[color][0], r_speeds_graph_colors[color][1], r_speeds_graph_colors[color][2], r_speeds_graph_colors[color][3], 0, true);
                                }
                        }
                }