From 859321ff938fe9ba4c653edc794732c983582a6f Mon Sep 17 00:00:00 2001 From: lordhavoc Date: Sun, 3 Feb 2002 10:40:46 +0000 Subject: [PATCH] rearranged r_speeds report a bit, and split up reporting of meshtris into normal and transparent categories, also displays number of meshs of each type 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 | 394 ++++++++++++++++++++++++++++++++++++++++----------- gl_backend.h | 2 +- gl_screen.c | 16 ++- 3 files changed, 321 insertions(+), 91 deletions(-) diff --git a/gl_backend.c b/gl_backend.c index cf86ac63..e1bd699f 100644 --- a/gl_backend.c +++ b/gl_backend.c @@ -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 *)¢er) & 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)); diff --git a/gl_backend.h b/gl_backend.h index 9d130921..6363c547 100644 --- a/gl_backend.h +++ b/gl_backend.h @@ -1,7 +1,7 @@ #define MAX_TEXTUREUNITS 4 -extern int c_meshtris; +extern int c_meshtris, c_meshs, c_transtris, c_transmeshs; typedef struct { diff --git a/gl_screen.c b/gl_screen.c index 6eaf808f..9aa96b08 100644 --- a/gl_screen.c +++ b/gl_screen.c @@ -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; -- 2.39.2