- }
- if (depthtest != mesh->depthtest)
- {
- depthtest = mesh->depthtest;
- if (depthtest)
- glEnable(GL_DEPTH_TEST);
- else
- glDisable(GL_DEPTH_TEST);
- }
- if (depthmask != mesh->depthmask)
- {
- depthmask = mesh->depthmask;
- glDepthMask((GLboolean) depthmask);
-CHECKGLERROR
- }
-
- firsttriangle = mesh->firsttriangle;
- triangles = mesh->triangles;
- firstvert = mesh->firstvert;
- lastvert = mesh->lastvert;
- mesh = &buf_mesh[++k];
-
- if (meshmerge)
- {
- #if MAX_TEXTUREUNITS != 4
- #error update this code
- #endif
- while (k < currentmesh
- && mesh->blendfunc1 == blendfunc1
- && mesh->blendfunc2 == blendfunc2
- && mesh->depthtest == depthtest
- && mesh->depthmask == depthmask
- && mesh->textures[0] == texture[0]
- && mesh->textures[1] == texture[1]
- && mesh->textures[2] == texture[2]
- && mesh->textures[3] == texture[3]
- && mesh->texturergbscale[0] == texturergbscale[0]
- && mesh->texturergbscale[1] == texturergbscale[1]
- && mesh->texturergbscale[2] == texturergbscale[2]
- && mesh->texturergbscale[3] == texturergbscale[3])
- {
- triangles += mesh->triangles;
- if (firstvert > mesh->firstvert)
- firstvert = mesh->firstvert;
- if (lastvert < mesh->lastvert)
- lastvert = mesh->lastvert;
- mesh = &buf_mesh[++k];
- }
- }
-
-#ifdef WIN32
- // FIXME: dynamic link to GL so we can get DrawRangeElements on WIN32
- glDrawElements(GL_TRIANGLES, triangles * 3, GL_UNSIGNED_INT, (unsigned int *)&buf_tri[firsttriangle]);
-#else
- glDrawRangeElements(GL_TRIANGLES, firstvert, lastvert + 1, triangles * 3, GL_UNSIGNED_INT, (unsigned int *)&buf_tri[firsttriangle]);
-#endif
-CHECKGLERROR
- }
-
- currentmesh = 0;
- currenttriangle = 0;
- currentvertex = 0;
-
- GL_UnlockArray();
-CHECKGLERROR
-
- if (backendunits > 1)
- {
- for (i = backendunits - 1;i >= 0;i--)
- {
- qglActiveTexture(GL_TEXTURE0_ARB + (unit = i));
-CHECKGLERROR
- glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
-CHECKGLERROR
- if (gl_combine.integer)
- {
- glTexEnvf(GL_TEXTURE_ENV, GL_RGB_SCALE_ARB, 1.0f);
-CHECKGLERROR
- }
- if (i > 0)
- {
- glDisable(GL_TEXTURE_2D);
-CHECKGLERROR
- }
- else
- {
- glEnable(GL_TEXTURE_2D);
-CHECKGLERROR
- }
- glBindTexture(GL_TEXTURE_2D, 0);
-CHECKGLERROR
-
- qglClientActiveTexture(GL_TEXTURE0_ARB + (clientunit = i));
-CHECKGLERROR
- glDisableClientState(GL_TEXTURE_COORD_ARRAY);
-CHECKGLERROR
- }
- }
- else
- {
- glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
-CHECKGLERROR
- glEnable(GL_TEXTURE_2D);
-CHECKGLERROR
- glDisableClientState(GL_TEXTURE_COORD_ARRAY);
-CHECKGLERROR
- }
- glDisableClientState(GL_COLOR_ARRAY);
-CHECKGLERROR
- glDisableClientState(GL_VERTEX_ARRAY);
-CHECKGLERROR
-
- glDisable(GL_BLEND);
-CHECKGLERROR
- glEnable(GL_DEPTH_TEST);
-CHECKGLERROR
- glDepthMask(true);
-CHECKGLERROR
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
-CHECKGLERROR
-}
-
-void R_Mesh_AddTransparent(void)
-{
- 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;
- buf_vertex_t *vert1, *vert2, *vert3;
- buf_transtri_t *tri;
- buf_mesh_t *mesh;
-
- // 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 *));
-
- // process in reverse because transtri_list adding code is in reverse as well
- k = 0;
- for (j = currenttranstriangle - 1;j >= 0;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++;
- }
-
- if (currentmesh + k > max_meshs || currenttriangle + k > max_batch || currentvertex + k * 3 > max_verts)
- R_Mesh_Render();
-
- currenttransmesh = 0;
- currenttranstriangle = 0;
- currenttransvertex = 0;
-
- // 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
- for (j = TRANSDEPTHRES - 1;j >= 0;j--)
- {
- if ((tri = buf_transtri_list[j]))
- {
- while(tri)
- {
- mesh = &buf_mesh[currentmesh++];
- *mesh = *tri->mesh; // copy mesh properties
- mesh->firstvert = currentvertex;
- mesh->lastvert = currentvertex + 2;
- mesh->firsttriangle = currenttriangle;
- mesh->triangles = 1;
- for (k = 0;k < 3;k++)
- {
- 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));
- currentvertex++;
- }
- currenttriangle++;
- tri = tri->next;
- }