X-Git-Url: http://de.git.xonotic.org/?a=blobdiff_plain;ds=sidebyside;f=gl_rsurf.c;h=e3429922df8fb731dd812cb674838c570c620009;hb=668a437d46dfad040c8e32398fd7cb916345f7d1;hp=b0650a996f2bfb6e75d74b2e0f45cab8a2ee8a48;hpb=1e4a164d8f889ef98d916c14df672405622a7e25;p=xonotic%2Fdarkplaces.git diff --git a/gl_rsurf.c b/gl_rsurf.c index b0650a99..e3429922 100644 --- a/gl_rsurf.c +++ b/gl_rsurf.c @@ -25,7 +25,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. static signed int blocklights[MAX_LIGHTMAP_SIZE*MAX_LIGHTMAP_SIZE*3]; // LordHavoc: *3 for colored lighting -static byte templight[MAX_LIGHTMAP_SIZE*MAX_LIGHTMAP_SIZE*4]; +static qbyte templight[MAX_LIGHTMAP_SIZE*MAX_LIGHTMAP_SIZE*4]; cvar_t r_ambient = {0, "r_ambient", "0"}; cvar_t r_vertexsurfaces = {0, "r_vertexsurfaces", "0"}; @@ -45,8 +45,15 @@ static void gl_surf_newmap(void) { } +static int dlightdivtable[32768]; + void GL_Surf_Init(void) { + int i; + dlightdivtable[0] = 4194304; + for (i = 1;i < 32768;i++) + dlightdivtable[i] = 4194304 / (i << 7); + Cvar_RegisterVariable(&r_ambient); Cvar_RegisterVariable(&r_vertexsurfaces); Cvar_RegisterVariable(&r_dlightmap); @@ -56,11 +63,9 @@ void GL_Surf_Init(void) R_RegisterModule("GL_Surf", gl_surf_start, gl_surf_shutdown, gl_surf_newmap); } -static int dlightdivtable[32768]; - static int R_AddDynamicLights (msurface_t *surf) { - int sdtable[18], lnum, td, maxdist, maxdist2, maxdist3, i, s, t, smax, tmax, smax3, red, green, blue, lit, dist2, impacts, impactt, subtract; + int sdtable[256], lnum, td, maxdist, maxdist2, maxdist3, i, s, t, smax, tmax, smax3, red, green, blue, lit, dist2, impacts, impactt, subtract; unsigned int *bl; float dist; vec3_t impact, local; @@ -74,13 +79,6 @@ static int R_AddDynamicLights (msurface_t *surf) lit = false; - if (!dlightdivtable[1]) - { - dlightdivtable[0] = 4194304; - for (s = 1; s < 32768; s++) - dlightdivtable[s] = 4194304 / (s << 7); - } - smax = (surf->extents[0] >> 4) + 1; tmax = (surf->extents[1] >> 4) + 1; @@ -90,25 +88,28 @@ static int R_AddDynamicLights (msurface_t *surf) continue; // not lit by this light softwareuntransform(r_dlight[lnum].origin, local); -// VectorSubtract (r_dlight[lnum].origin, currentrenderentity->origin, local); dist = DotProduct (local, surf->plane->normal) - surf->plane->dist; // for comparisons to minimum acceptable light - maxdist = (int) r_dlight[lnum].cullradius2; - - // already clamped, skip this - // clamp radius to avoid exceeding 32768 entry division table - //if (maxdist > 4194304) - // maxdist = 4194304; + // compensate for LIGHTOFFSET + maxdist = (int) r_dlight[lnum].cullradius2 + LIGHTOFFSET; dist2 = dist * dist; dist2 += LIGHTOFFSET; if (dist2 >= maxdist) continue; - impact[0] = local[0] - surf->plane->normal[0] * dist; - impact[1] = local[1] - surf->plane->normal[1] * dist; - impact[2] = local[2] - surf->plane->normal[2] * dist; + if (surf->plane->type < 3) + { + VectorCopy(local, impact); + impact[surf->plane->type] -= dist; + } + else + { + impact[0] = local[0] - surf->plane->normal[0] * dist; + impact[1] = local[1] - surf->plane->normal[1] * dist; + impact[2] = local[2] - surf->plane->normal[2] * dist; + } impacts = DotProduct (impact, surf->texinfo->vecs[0]) + surf->texinfo->vecs[0][3] - surf->texturemins[0]; impactt = DotProduct (impact, surf->texinfo->vecs[1]) + surf->texinfo->vecs[1][3] - surf->texturemins[1]; @@ -164,6 +165,191 @@ static int R_AddDynamicLights (msurface_t *surf) return lit; } +void R_StainNode (mnode_t *node, model_t *model, vec3_t origin, float radius, int icolor[8]) +{ + float ndist; + msurface_t *surf, *endsurf; + int sdtable[256], td, maxdist, maxdist2, maxdist3, i, s, t, smax, tmax, smax3, dist2, impacts, impactt, subtract, a, stained, cr, cg, cb, ca, ratio; + qbyte *bl; + vec3_t impact; + // LordHavoc: use 64bit integer... shame it's not very standardized... +#if _MSC_VER || __BORLANDC__ + __int64 k; +#else + long long k; +#endif + + + // for comparisons to minimum acceptable light + // compensate for 4096 offset + maxdist = radius * radius + 4096; + + // clamp radius to avoid exceeding 32768 entry division table + if (maxdist > 4194304) + maxdist = 4194304; + + subtract = (int) ((1.0f / maxdist) * 4194304.0f); + +loc0: + if (node->contents < 0) + return; + ndist = PlaneDiff(origin, node->plane); + if (ndist > radius) + { + node = node->children[0]; + goto loc0; + } + if (ndist < -radius) + { + node = node->children[1]; + goto loc0; + } + + dist2 = ndist * ndist; + dist2 += 4096.0f; + if (dist2 < maxdist) + { + maxdist3 = maxdist - dist2; + + if (node->plane->type < 3) + { + VectorCopy(origin, impact); + impact[node->plane->type] -= ndist; + } + else + { + impact[0] = origin[0] - node->plane->normal[0] * ndist; + impact[1] = origin[1] - node->plane->normal[1] * ndist; + impact[2] = origin[2] - node->plane->normal[2] * ndist; + } + + for (surf = model->surfaces + node->firstsurface, endsurf = surf + node->numsurfaces;surf < endsurf;surf++) + { + if (surf->stainsamples) + { + smax = (surf->extents[0] >> 4) + 1; + tmax = (surf->extents[1] >> 4) + 1; + + impacts = DotProduct (impact, surf->texinfo->vecs[0]) + surf->texinfo->vecs[0][3] - surf->texturemins[0]; + impactt = DotProduct (impact, surf->texinfo->vecs[1]) + surf->texinfo->vecs[1][3] - surf->texturemins[1]; + + s = bound(0, impacts, smax * 16) - impacts; + t = bound(0, impactt, tmax * 16) - impactt; + i = s * s + t * t + dist2; + if (i > maxdist) + continue; + + // reduce calculations + for (s = 0, i = impacts; s < smax; s++, i -= 16) + sdtable[s] = i * i + dist2; + + // convert to 8.8 blocklights format + bl = surf->stainsamples; + smax3 = smax * 3; + stained = false; + + i = impactt; + for (t = 0;t < tmax;t++, i -= 16) + { + td = i * i; + // make sure some part of it is visible on this line + if (td < maxdist3) + { + maxdist2 = maxdist - td; + for (s = 0;s < smax;s++) + { + if (sdtable[s] < maxdist2) + { + k = dlightdivtable[(sdtable[s] + td) >> 7] - subtract; + if (k > 0) + { + ratio = rand() & 255; + ca = (((icolor[7] - icolor[3]) * ratio) >> 8) + icolor[3]; + a = (ca * k) >> 8; + if (a > 0) + { + a = bound(0, a, 256); + cr = (((icolor[4] - icolor[0]) * ratio) >> 8) + icolor[0]; + cg = (((icolor[5] - icolor[1]) * ratio) >> 8) + icolor[1]; + cb = (((icolor[6] - icolor[2]) * ratio) >> 8) + icolor[2]; + bl[0] = (qbyte) ((((cr - (int) bl[0]) * a) >> 8) + (int) bl[0]); + bl[1] = (qbyte) ((((cg - (int) bl[1]) * a) >> 8) + (int) bl[1]); + bl[2] = (qbyte) ((((cb - (int) bl[2]) * a) >> 8) + (int) bl[2]); + stained = true; + } + } + } + bl += 3; + } + } + else // skip line + bl += smax3; + } + // force lightmap upload + if (stained) + surf->cached_dlight = true; + } + } + } + + if (node->children[0]->contents >= 0) + { + if (node->children[1]->contents >= 0) + { + R_StainNode(node->children[0], model, origin, radius, icolor); + node = node->children[1]; + goto loc0; + } + else + { + node = node->children[0]; + goto loc0; + } + } + else if (node->children[1]->contents >= 0) + { + node = node->children[1]; + goto loc0; + } +} + +void R_Stain (vec3_t origin, float radius, int cr1, int cg1, int cb1, int ca1, int cr2, int cg2, int cb2, int ca2) +{ + int n, icolor[8]; + entity_render_t *ent; + model_t *model; + vec3_t org; + icolor[0] = cr1; + icolor[1] = cg1; + icolor[2] = cb1; + icolor[3] = ca1; + icolor[4] = cr2; + icolor[5] = cg2; + icolor[6] = cb2; + icolor[7] = ca2; + + model = cl.worldmodel; + softwaretransformidentity(); + R_StainNode(model->nodes + model->hulls[0].firstclipnode, model, origin, radius, icolor); + + // look for embedded bmodels + for (n = 1;n < MAX_EDICTS;n++) + { + ent = &cl_entities[n].render; + model = ent->model; + if (model && model->name[0] == '*') + { + Mod_CheckLoaded(model); + if (model->type == mod_brush) + { + softwaretransformforentity(ent); + softwareuntransform(origin, org); + R_StainNode(model->nodes + model->hulls[0].firstclipnode, model, org, radius, icolor); + } + } + } +} + /* =============== R_BuildLightMap @@ -173,8 +359,8 @@ Combine and scale multiple lightmaps into the 8.8 format in blocklights */ static void R_BuildLightMap (msurface_t *surf, int dlightchanged) { - int smax, tmax, i, j, size, size3, shift, scale, maps, *bl, stride, l; - byte *lightmap, *out; + int smax, tmax, i, j, size, size3, shift, scale, maps, *bl, stride, l; + qbyte *lightmap, *out, *stain; // update cached lighting info surf->cached_dlight = 0; @@ -195,12 +381,8 @@ static void R_BuildLightMap (msurface_t *surf, int dlightchanged) if ((currentrenderentity->effects & EF_FULLBRIGHT) || !cl.worldmodel->lightdata) { bl = blocklights; - for (i = 0;i < size;i++) - { - *bl++ = 255*256; - *bl++ = 255*256; - *bl++ = 255*256; - } + for (i = 0;i < size3;i++) + bl[i] = 255*256; } else { @@ -226,15 +408,19 @@ static void R_BuildLightMap (msurface_t *surf, int dlightchanged) // add all the lightmaps if (lightmap) - for (maps = 0;maps < MAXLIGHTMAPS && surf->styles[maps] != 255;maps++) - for (scale = d_lightstylevalue[surf->styles[maps]], bl = blocklights, i = 0;i < size3;i++) - *bl++ += *lightmap++ * scale; + { + bl = blocklights; + for (maps = 0;maps < MAXLIGHTMAPS && surf->styles[maps] != 255;maps++, lightmap += size3) + for (scale = d_lightstylevalue[surf->styles[maps]], i = 0;i < size3;i++) + bl[i] += lightmap[i] * scale; + } } + stain = surf->stainsamples; bl = blocklights; out = templight; // deal with lightmap brightness scale - shift = 7 + lightscalebit; + shift = 15 + lightscalebit; if (currentrenderentity->model->lightmaprgba) { stride = (surf->lightmaptexturestride - smax) * 4; @@ -242,9 +428,9 @@ static void R_BuildLightMap (msurface_t *surf, int dlightchanged) { for (j = 0;j < smax;j++) { - l = *bl++ >> shift;*out++ = min(l, 255); - l = *bl++ >> shift;*out++ = min(l, 255); - l = *bl++ >> shift;*out++ = min(l, 255); + l = (*bl++ * *stain++) >> shift;*out++ = min(l, 255); + l = (*bl++ * *stain++) >> shift;*out++ = min(l, 255); + l = (*bl++ * *stain++) >> shift;*out++ = min(l, 255); *out++ = 255; } } @@ -256,9 +442,9 @@ static void R_BuildLightMap (msurface_t *surf, int dlightchanged) { for (j = 0;j < smax;j++) { - l = *bl++ >> shift;*out++ = min(l, 255); - l = *bl++ >> shift;*out++ = min(l, 255); - l = *bl++ >> shift;*out++ = min(l, 255); + l = (*bl++ * *stain++) >> shift;*out++ = min(l, 255); + l = (*bl++ * *stain++) >> shift;*out++ = min(l, 255); + l = (*bl++ * *stain++) >> shift;*out++ = min(l, 255); } } } @@ -266,27 +452,6 @@ static void R_BuildLightMap (msurface_t *surf, int dlightchanged) R_UpdateTexture(surf->lightmaptexture, templight); } -/* -=============== -R_TextureAnimation - -Returns the proper texture for a given time and base texture -=============== -*/ -/* -// note: this was manually inlined in R_PrepareSurfaces -static texture_t *R_TextureAnimation (texture_t *base) -{ - if (currentrenderentity->frame && base->alternate_anims != NULL) - base = base->alternate_anims; - - if (base->anim_total < 2) - return base; - - return base->anim_frames[(int)(cl.time * 5.0f) % base->anim_total]; -} -*/ - /* ============================================================= @@ -303,7 +468,8 @@ static float turbsin[256] = }; #define TURBSCALE (256.0 / (2 * M_PI)) -#define MAX_SURFVERTS 1024 +// only need to hold as many verts as the mesh splitter will allow in model_brush.c +#define MAX_SURFVERTS 3072 typedef struct { float v[4]; @@ -314,138 +480,144 @@ typedef struct surfvert_t; static surfvert_t svert[MAX_SURFVERTS]; // used by the following functions -static int RSurfShader_Sky(int stage, msurface_t *s) +static void RSurfShader_Sky(msurface_t *firstsurf) { - int i; - float number, length, dir[3], speedscale; - surfvertex_t *v; - surfvert_t *sv; - rmeshinfo_t m; + msurface_t *surf; + int i; + float number, length, dir[3], speedscale; + surfvertex_t *v; + surfvert_t *sv; + surfmesh_t *mesh; + rmeshinfo_t m; // LordHavoc: HalfLife maps have freaky skypolys... if (currentrenderentity->model->ishlbsp) - return true; + return; - if (stage == 0) + if (skyrendermasked) { - if (skyrendermasked) + if (skyrendernow) + { + skyrendernow = false; + R_Sky(); + } + for (surf = firstsurf;surf;surf = surf->chain) { - if (skyrendernow) - { - skyrendernow = false; - R_Sky(); - } // draw depth-only polys memset(&m, 0, sizeof(m)); m.transparent = false; m.blendfunc1 = GL_ZERO; m.blendfunc2 = GL_ONE; m.depthwrite = true; - m.numtriangles = s->mesh.numtriangles; - m.numverts = s->mesh.numverts; - m.index = s->mesh.index; - //m.cr = 0; - //m.cg = 0; - //m.cb = 0; - //m.ca = 0; - if (softwaretransform_complexity) + for (mesh = surf->mesh;mesh;mesh = mesh->chain) { - m.vertex = &svert[0].v[0]; - m.vertexstep = sizeof(surfvert_t); - for (i = 0, sv = svert, v = s->mesh.vertex;i < m.numverts;i++, sv++, v++) - softwaretransform(v->v, sv->v); - } - else - { - m.vertex = &s->mesh.vertex[0].v[0]; - m.vertexstep = sizeof(surfvertex_t); + m.numtriangles = mesh->numtriangles; + m.numverts = mesh->numverts; + m.index = mesh->index; + if (softwaretransform_complexity) + { + m.vertex = &svert[0].v[0]; + m.vertexstep = sizeof(surfvert_t); + for (i = 0, sv = svert, v = mesh->vertex;i < m.numverts;i++, sv++, v++) + softwaretransform(v->v, sv->v); + } + else + { + m.vertex = &mesh->vertex[0].v[0]; + m.vertexstep = sizeof(surfvertex_t); + } + R_Mesh_Draw(&m); } - R_Mesh_Draw(&m); } - else if (skyrenderglquake) + } + else if (skyrenderglquake) + { + for (surf = firstsurf;surf;surf = surf->chain) { memset(&m, 0, sizeof(m)); m.transparent = false; m.blendfunc1 = GL_ONE; m.blendfunc2 = GL_ZERO; - m.numtriangles = s->mesh.numtriangles; - m.numverts = s->mesh.numverts; - m.index = s->mesh.index; m.vertex = &svert[0].v[0]; m.vertexstep = sizeof(surfvert_t); m.cr = 1; m.cg = 1; m.cb = 1; m.ca = 1; - if (r_mergesky.integer) - m.tex[0] = R_GetTexture(mergeskytexture); - else - m.tex[0] = R_GetTexture(solidskytexture); + m.tex[0] = R_GetTexture(solidskytexture); m.texcoords[0] = &svert[0].st[0]; m.texcoordstep[0] = sizeof(surfvert_t); speedscale = cl.time * (8.0/128.0); speedscale -= (int)speedscale; - for (i = 0, sv = svert, v = s->mesh.vertex;i < m.numverts;i++, sv++, v++) + for (mesh = surf->mesh;mesh;mesh = mesh->chain) { - softwaretransform(v->v, sv->v); - VectorSubtract (sv->v, r_origin, dir); - // flatten the sphere - dir[2] *= 3; - - number = DotProduct(dir, dir); - #if SLOWMATH - length = 3.0f / sqrt(number); - #else - *((long *)&length) = 0x5f3759df - ((* (long *) &number) >> 1); - length = 3.0f * (length * (1.5f - (number * 0.5f * length * length))); - #endif - - sv->st[0] = speedscale + dir[0] * length; - sv->st[1] = speedscale + dir[1] * length; + m.numtriangles = mesh->numtriangles; + m.numverts = mesh->numverts; + m.index = mesh->index; + for (i = 0, sv = svert, v = mesh->vertex;i < m.numverts;i++, sv++, v++) + { + softwaretransform(v->v, sv->v); + VectorSubtract (sv->v, r_origin, dir); + // flatten the sphere + dir[2] *= 3; + + number = DotProduct(dir, dir); + #if SLOWMATH + length = 3.0f / sqrt(number); + #else + *((int *)&length) = 0x5f3759df - ((* (int *) &number) >> 1); + length = 3.0f * (length * (1.5f - (number * 0.5f * length * length))); + #endif + + sv->st[0] = speedscale + dir[0] * length; + sv->st[1] = speedscale + dir[1] * length; + } + R_Mesh_Draw(&m); } - R_Mesh_Draw(&m); } - else + } + else + { + for (surf = firstsurf;surf;surf = surf->chain) { // flat color memset(&m, 0, sizeof(m)); m.transparent = false; m.blendfunc1 = GL_ONE; m.blendfunc2 = GL_ZERO; - m.numtriangles = s->mesh.numtriangles; - m.numverts = s->mesh.numverts; - m.index = s->mesh.index; m.cr = fogcolor[0]; m.cg = fogcolor[1]; m.cb = fogcolor[2]; m.ca = 1; - if (softwaretransform_complexity) - { - m.vertex = &svert[0].v[0]; - m.vertexstep = sizeof(surfvert_t); - for (i = 0, sv = svert, v = s->mesh.vertex;i < m.numverts;i++, sv++, v++) - softwaretransform(v->v, sv->v); - } - else + for (mesh = surf->mesh;mesh;mesh = mesh->chain) { - m.vertex = &s->mesh.vertex[0].v[0]; - m.vertexstep = sizeof(surfvertex_t); + m.numtriangles = mesh->numtriangles; + m.numverts = mesh->numverts; + m.index = mesh->index; + if (softwaretransform_complexity) + { + m.vertex = &svert[0].v[0]; + m.vertexstep = sizeof(surfvert_t); + for (i = 0, sv = svert, v = mesh->vertex;i < m.numverts;i++, sv++, v++) + softwaretransform(v->v, sv->v); + } + else + { + m.vertex = &mesh->vertex[0].v[0]; + m.vertexstep = sizeof(surfvertex_t); + } + R_Mesh_Draw(&m); } - R_Mesh_Draw(&m); } - return false; } - else if (stage == 1) + if (skyrenderglquake) { - if (skyrenderglquake && !r_mergesky.integer) + for (surf = firstsurf;surf;surf = surf->chain) { memset(&m, 0, sizeof(m)); m.transparent = false; m.blendfunc1 = GL_SRC_ALPHA; m.blendfunc2 = GL_ONE_MINUS_SRC_ALPHA; - m.numtriangles = s->mesh.numtriangles; - m.numverts = s->mesh.numverts; - m.index = s->mesh.index; m.vertex = &svert[0].v[0]; m.vertexstep = sizeof(surfvert_t); m.cr = 1; @@ -457,31 +629,33 @@ static int RSurfShader_Sky(int stage, msurface_t *s) m.texcoordstep[0] = sizeof(surfvert_t); speedscale = cl.time * (16.0/128.0); speedscale -= (int)speedscale; - for (i = 0, sv = svert, v = s->mesh.vertex;i < m.numverts;i++, sv++, v++) + for (mesh = surf->mesh;mesh;mesh = mesh->chain) { - softwaretransform(v->v, sv->v); - VectorSubtract (sv->v, r_origin, dir); - // flatten the sphere - dir[2] *= 3; - - number = DotProduct(dir, dir); - #if SLOWMATH - length = 3.0f / sqrt(number); - #else - *((long *)&length) = 0x5f3759df - ((* (long *) &number) >> 1); - length = 3.0f * (length * (1.5f - (number * 0.5f * length * length))); - #endif - - sv->st[0] = speedscale + dir[0] * length; - sv->st[1] = speedscale + dir[1] * length; + m.numtriangles = mesh->numtriangles; + m.numverts = mesh->numverts; + m.index = mesh->index; + for (i = 0, sv = svert, v = mesh->vertex;i < m.numverts;i++, sv++, v++) + { + softwaretransform(v->v, sv->v); + VectorSubtract (sv->v, r_origin, dir); + // flatten the sphere + dir[2] *= 3; + + number = DotProduct(dir, dir); + #if SLOWMATH + length = 3.0f / sqrt(number); + #else + *((int *)&length) = 0x5f3759df - ((* (int *) &number) >> 1); + length = 3.0f * (length * (1.5f - (number * 0.5f * length * length))); + #endif + + sv->st[0] = speedscale + dir[0] * length; + sv->st[1] = speedscale + dir[1] * length; + } + R_Mesh_Draw(&m); } - R_Mesh_Draw(&m); - return false; } - return true; } - else - return true; } static int RSurf_Light(int *dlightbits, int numverts) @@ -515,17 +689,18 @@ static int RSurf_Light(int *dlightbits, int numverts) return lit; } -static void RSurfShader_Water_Pass_Base(msurface_t *s) +static void RSurfShader_Water_Pass_Base(msurface_t *surf) { - int i; - float diff[3], alpha, ifog; - surfvertex_t *v; - surfvert_t *sv; - rmeshinfo_t m; - alpha = s->flags & SURF_DRAWNOALPHA ? 1 : r_wateralpha.value; + int i; + float diff[3], alpha, ifog; + surfvertex_t *v; + surfvert_t *sv; + surfmesh_t *mesh; + rmeshinfo_t m; + alpha = currentrenderentity->alpha * (surf->flags & SURF_DRAWNOALPHA ? 1 : r_wateralpha.value); memset(&m, 0, sizeof(m)); - if (alpha != 1 || s->currenttexture->fogtexture != NULL) + if (alpha != 1 || surf->currenttexture->fogtexture != NULL) { m.transparent = true; m.blendfunc1 = GL_SRC_ALPHA; @@ -534,190 +709,191 @@ static void RSurfShader_Water_Pass_Base(msurface_t *s) else { m.transparent = false; - m.blendfunc1 = GL_SRC_ALPHA; + m.blendfunc1 = GL_ONE; m.blendfunc2 = GL_ZERO; } - m.numtriangles = s->mesh.numtriangles; - m.numverts = s->mesh.numverts; - m.index = s->mesh.index; m.vertex = &svert[0].v[0]; m.vertexstep = sizeof(surfvert_t); m.color = &svert[0].c[0]; m.colorstep = sizeof(surfvert_t); - m.tex[0] = R_GetTexture(s->currenttexture->texture); + m.tex[0] = R_GetTexture(surf->currenttexture->texture); m.texcoords[0] = &svert[0].st[0]; m.texcoordstep[0] = sizeof(surfvert_t); - for (i = 0, sv = svert, v = s->mesh.vertex;i < m.numverts;i++, sv++, v++) + for (mesh = surf->mesh;mesh;mesh = mesh->chain) { - softwaretransform(v->v, sv->v); - if (r_waterripple.value) - sv->v[2] += r_waterripple.value * (1.0f / 64.0f) * turbsin[(int)((v->v[0]*(1.0f/32.0f)+cl.time) * TURBSCALE) & 255] * turbsin[(int)((v->v[1]*(1.0f/32.0f)+cl.time) * TURBSCALE) & 255]; - if (s->flags & SURF_DRAWFULLBRIGHT) + m.numtriangles = mesh->numtriangles; + m.numverts = mesh->numverts; + m.index = mesh->index; + for (i = 0, sv = svert, v = mesh->vertex;i < m.numverts;i++, sv++, v++) { - sv->c[0] = 1; - sv->c[1] = 1; - sv->c[2] = 1; - sv->c[3] = alpha; - } - else - { - sv->c[0] = 0.5f; - sv->c[1] = 0.5f; - sv->c[2] = 0.5f; - sv->c[3] = alpha; + softwaretransform(v->v, sv->v); + if (r_waterripple.value) + sv->v[2] += r_waterripple.value * (1.0f / 64.0f) * turbsin[(int)((v->v[0]*(1.0f/32.0f)+cl.time) * TURBSCALE) & 255] * turbsin[(int)((v->v[1]*(1.0f/32.0f)+cl.time) * TURBSCALE) & 255]; + if (surf->flags & SURF_DRAWFULLBRIGHT) + { + sv->c[0] = 1; + sv->c[1] = 1; + sv->c[2] = 1; + sv->c[3] = alpha; + } + else + { + sv->c[0] = 0.5f; + sv->c[1] = 0.5f; + sv->c[2] = 0.5f; + sv->c[3] = alpha; + } + sv->st[0] = (v->st[0] + turbsin[(int)((v->st[1]*0.125f+cl.time) * TURBSCALE) & 255]) * (1.0f / 64.0f); + sv->st[1] = (v->st[1] + turbsin[(int)((v->st[0]*0.125f+cl.time) * TURBSCALE) & 255]) * (1.0f / 64.0f); } - sv->st[0] = (v->st[0] + turbsin[(int)((v->st[1]*0.125f+cl.time) * TURBSCALE) & 255]) * (1.0f / 64.0f); - sv->st[1] = (v->st[1] + turbsin[(int)((v->st[0]*0.125f+cl.time) * TURBSCALE) & 255]) * (1.0f / 64.0f); - } - if (s->dlightframe == r_framecount && !(s->flags & SURF_DRAWFULLBRIGHT)) - RSurf_Light(s->dlightbits, m.numverts); - if (fogenabled) - { - for (i = 0, sv = svert;i < m.numverts;i++, sv++) + if (surf->dlightframe == r_framecount && !(surf->flags & SURF_DRAWFULLBRIGHT)) + RSurf_Light(surf->dlightbits, m.numverts); + if (fogenabled && (surf->flags & SURF_DRAWNOALPHA)) { - VectorSubtract(sv->v, r_origin, diff); - ifog = 1 - exp(fogdensity/DotProduct(diff, diff)); - sv->c[0] *= ifog; - sv->c[1] *= ifog; - sv->c[2] *= ifog; + for (i = 0, sv = svert;i < m.numverts;i++, sv++) + { + VectorSubtract(sv->v, r_origin, diff); + ifog = 1 - exp(fogdensity/DotProduct(diff, diff)); + sv->c[0] *= ifog; + sv->c[1] *= ifog; + sv->c[2] *= ifog; + } } + R_Mesh_Draw(&m); } - R_Mesh_Draw(&m); } -static void RSurfShader_Water_Pass_Glow(msurface_t *s) +static void RSurfShader_Water_Pass_Glow(msurface_t *surf) { - int i; - float diff[3], alpha, ifog; - surfvertex_t *v; - surfvert_t *sv; - rmeshinfo_t m; - alpha = s->flags & SURF_DRAWNOALPHA ? 1 : r_wateralpha.value; + int i; + float diff[3], alpha, ifog; + surfvertex_t *v; + surfvert_t *sv; + surfmesh_t *mesh; + rmeshinfo_t m; + alpha = currentrenderentity->alpha * (surf->flags & SURF_DRAWNOALPHA ? 1 : r_wateralpha.value); memset(&m, 0, sizeof(m)); - m.transparent = alpha != 1 || s->currenttexture->fogtexture != NULL; + m.transparent = alpha != 1 || surf->currenttexture->fogtexture != NULL; m.blendfunc1 = GL_SRC_ALPHA; m.blendfunc2 = GL_ONE; - m.numtriangles = s->mesh.numtriangles; - m.numverts = s->mesh.numverts; - m.index = s->mesh.index; m.vertex = &svert[0].v[0]; m.vertexstep = sizeof(surfvert_t); m.cr = 1; m.cg = 1; m.cb = 1; m.ca = alpha; - m.tex[0] = R_GetTexture(s->currenttexture->glowtexture); + m.tex[0] = R_GetTexture(surf->currenttexture->glowtexture); m.texcoords[0] = &svert[0].st[0]; m.texcoordstep[0] = sizeof(surfvert_t); - if (fogenabled) + for (mesh = surf->mesh;mesh;mesh = mesh->chain) { - m.color = &svert[0].c[0]; - m.colorstep = sizeof(surfvert_t); - for (i = 0, sv = svert, v = s->mesh.vertex;i < m.numverts;i++, sv++, v++) + m.numtriangles = mesh->numtriangles; + m.numverts = mesh->numverts; + m.index = mesh->index; + if (fogenabled) { - softwaretransform(v->v, sv->v); - if (r_waterripple.value) - sv->v[2] += r_waterripple.value * (1.0f / 64.0f) * turbsin[(int)((v->v[0]*(1.0f/32.0f)+cl.time) * TURBSCALE) & 255] * turbsin[(int)((v->v[1]*(1.0f/32.0f)+cl.time) * TURBSCALE) & 255]; - sv->st[0] = (v->st[0] + turbsin[(int)((v->st[1]*0.125f+cl.time) * TURBSCALE) & 255]) * (1.0f / 64.0f); - sv->st[1] = (v->st[1] + turbsin[(int)((v->st[0]*0.125f+cl.time) * TURBSCALE) & 255]) * (1.0f / 64.0f); - VectorSubtract(sv->v, r_origin, diff); - ifog = 1 - exp(fogdensity/DotProduct(diff, diff)); - sv->c[0] = m.cr * ifog; - sv->c[1] = m.cg * ifog; - sv->c[2] = m.cb * ifog; - sv->c[3] = m.ca; + m.color = &svert[0].c[0]; + m.colorstep = sizeof(surfvert_t); + for (i = 0, sv = svert, v = mesh->vertex;i < m.numverts;i++, sv++, v++) + { + softwaretransform(v->v, sv->v); + if (r_waterripple.value) + sv->v[2] += r_waterripple.value * (1.0f / 64.0f) * turbsin[(int)((v->v[0]*(1.0f/32.0f)+cl.time) * TURBSCALE) & 255] * turbsin[(int)((v->v[1]*(1.0f/32.0f)+cl.time) * TURBSCALE) & 255]; + sv->st[0] = (v->st[0] + turbsin[(int)((v->st[1]*0.125f+cl.time) * TURBSCALE) & 255]) * (1.0f / 64.0f); + sv->st[1] = (v->st[1] + turbsin[(int)((v->st[0]*0.125f+cl.time) * TURBSCALE) & 255]) * (1.0f / 64.0f); + VectorSubtract(sv->v, r_origin, diff); + ifog = 1 - exp(fogdensity/DotProduct(diff, diff)); + sv->c[0] = m.cr * ifog; + sv->c[1] = m.cg * ifog; + sv->c[2] = m.cb * ifog; + sv->c[3] = m.ca; + } } - } - else - { - for (i = 0, sv = svert, v = s->mesh.vertex;i < m.numverts;i++, sv++, v++) + else { - softwaretransform(v->v, sv->v); - if (r_waterripple.value) - sv->v[2] += r_waterripple.value * (1.0f / 64.0f) * turbsin[(int)((v->v[0]*(1.0f/32.0f)+cl.time) * TURBSCALE) & 255] * turbsin[(int)((v->v[1]*(1.0f/32.0f)+cl.time) * TURBSCALE) & 255]; - sv->st[0] = (v->st[0] + turbsin[(int)((v->st[1]*0.125f+cl.time) * TURBSCALE) & 255]) * (1.0f / 64.0f); - sv->st[1] = (v->st[1] + turbsin[(int)((v->st[0]*0.125f+cl.time) * TURBSCALE) & 255]) * (1.0f / 64.0f); + for (i = 0, sv = svert, v = mesh->vertex;i < m.numverts;i++, sv++, v++) + { + softwaretransform(v->v, sv->v); + if (r_waterripple.value) + sv->v[2] += r_waterripple.value * (1.0f / 64.0f) * turbsin[(int)((v->v[0]*(1.0f/32.0f)+cl.time) * TURBSCALE) & 255] * turbsin[(int)((v->v[1]*(1.0f/32.0f)+cl.time) * TURBSCALE) & 255]; + sv->st[0] = (v->st[0] + turbsin[(int)((v->st[1]*0.125f+cl.time) * TURBSCALE) & 255]) * (1.0f / 64.0f); + sv->st[1] = (v->st[1] + turbsin[(int)((v->st[0]*0.125f+cl.time) * TURBSCALE) & 255]) * (1.0f / 64.0f); + } } + R_Mesh_Draw(&m); } - R_Mesh_Draw(&m); } -static void RSurfShader_Water_Pass_Fog(msurface_t *s) +static void RSurfShader_Water_Pass_Fog(msurface_t *surf) { - int i; - float alpha; - surfvertex_t *v; - surfvert_t *sv; - rmeshinfo_t m; - vec3_t diff; - alpha = s->flags & SURF_DRAWNOALPHA ? 1 : r_wateralpha.value; + int i; + float alpha; + surfvertex_t *v; + surfvert_t *sv; + surfmesh_t *mesh; + rmeshinfo_t m; + vec3_t diff; + alpha = currentrenderentity->alpha * (surf->flags & SURF_DRAWNOALPHA ? 1 : r_wateralpha.value); memset(&m, 0, sizeof(m)); - m.transparent = alpha != 1 || s->currenttexture->fogtexture != NULL; + m.transparent = alpha != 1 || surf->currenttexture->fogtexture != NULL; m.blendfunc1 = GL_SRC_ALPHA; m.blendfunc2 = GL_ONE; - m.numtriangles = s->mesh.numtriangles; - m.numverts = s->mesh.numverts; - m.index = s->mesh.index; m.vertex = &svert[0].v[0]; m.vertexstep = sizeof(surfvert_t); m.color = &svert[0].c[0]; m.colorstep = sizeof(surfvert_t); - m.tex[0] = R_GetTexture(s->currenttexture->fogtexture); + m.tex[0] = R_GetTexture(surf->currenttexture->fogtexture); m.texcoords[0] = &svert[0].st[0]; m.texcoordstep[0] = sizeof(surfvert_t); - for (i = 0, sv = svert, v = s->mesh.vertex;i < m.numverts;i++, sv++, v++) + for (mesh = surf->mesh;mesh;mesh = mesh->chain) { - softwaretransform(v->v, sv->v); - if (r_waterripple.value) - sv->v[2] += r_waterripple.value * (1.0f / 64.0f) * turbsin[(int)((v->v[0]*(1.0f/32.0f)+cl.time) * TURBSCALE) & 255] * turbsin[(int)((v->v[1]*(1.0f/32.0f)+cl.time) * TURBSCALE) & 255]; - if (m.tex[0]) + m.numtriangles = mesh->numtriangles; + m.numverts = mesh->numverts; + m.index = mesh->index; + for (i = 0, sv = svert, v = mesh->vertex;i < m.numverts;i++, sv++, v++) { - sv->st[0] = (v->st[0] + turbsin[(int)((v->st[1]*0.125f+cl.time) * TURBSCALE) & 255]) * (1.0f / 64.0f); - sv->st[1] = (v->st[1] + turbsin[(int)((v->st[0]*0.125f+cl.time) * TURBSCALE) & 255]) * (1.0f / 64.0f); + softwaretransform(v->v, sv->v); + if (r_waterripple.value) + sv->v[2] += r_waterripple.value * (1.0f / 64.0f) * turbsin[(int)((v->v[0]*(1.0f/32.0f)+cl.time) * TURBSCALE) & 255] * turbsin[(int)((v->v[1]*(1.0f/32.0f)+cl.time) * TURBSCALE) & 255]; + if (m.tex[0]) + { + sv->st[0] = (v->st[0] + turbsin[(int)((v->st[1]*0.125f+cl.time) * TURBSCALE) & 255]) * (1.0f / 64.0f); + sv->st[1] = (v->st[1] + turbsin[(int)((v->st[0]*0.125f+cl.time) * TURBSCALE) & 255]) * (1.0f / 64.0f); + } + VectorSubtract(sv->v, r_origin, diff); + sv->c[0] = fogcolor[0]; + sv->c[1] = fogcolor[1]; + sv->c[2] = fogcolor[2]; + sv->c[3] = alpha * exp(fogdensity/DotProduct(diff, diff)); } - VectorSubtract(sv->v, r_origin, diff); - sv->c[0] = fogcolor[0]; - sv->c[1] = fogcolor[1]; - sv->c[2] = fogcolor[2]; - sv->c[3] = alpha * exp(fogdensity/DotProduct(diff, diff)); + R_Mesh_Draw(&m); } - R_Mesh_Draw(&m); } -static int RSurfShader_Water(int stage, msurface_t *s) +static void RSurfShader_Water(msurface_t *firstsurf) { - switch(stage) - { - case 0: - RSurfShader_Water_Pass_Base(s); - return false; - case 1: - if (s->currenttexture->glowtexture) - RSurfShader_Water_Pass_Glow(s); - return false; - case 2: - if (fogenabled) - { - RSurfShader_Water_Pass_Fog(s); - return false; - } - else - return true; - default: - return true; - } + msurface_t *surf; + for (surf = firstsurf;surf;surf = surf->chain) + RSurfShader_Water_Pass_Base(surf); + for (surf = firstsurf;surf;surf = surf->chain) + if (surf->currenttexture->glowtexture) + RSurfShader_Water_Pass_Glow(surf); + if (fogenabled) + for (surf = firstsurf;surf;surf = surf->chain) + RSurfShader_Water_Pass_Fog(surf); } -static void RSurfShader_Wall_Pass_BaseMTex(msurface_t *s) +static void RSurfShader_Wall_Pass_BaseMTex(msurface_t *surf) { - int i; - float diff[3], ifog; - surfvertex_t *v; - surfvert_t *sv; - rmeshinfo_t m; + int i; + float diff[3], ifog; + surfvertex_t *v; + surfvert_t *sv; + surfmesh_t *mesh; + rmeshinfo_t m; memset(&m, 0, sizeof(m)); if (currentrenderentity->effects & EF_ADDITIVE) @@ -726,7 +902,7 @@ static void RSurfShader_Wall_Pass_BaseMTex(msurface_t *s) m.blendfunc1 = GL_SRC_ALPHA; m.blendfunc2 = GL_ONE; } - else if (currentrenderentity != &cl_entities[0].render && (s->currenttexture->fogtexture != NULL || currentrenderentity->alpha != 1)) + else if (surf->currenttexture->fogtexture != NULL || currentrenderentity->alpha != 1) { m.transparent = true; m.blendfunc1 = GL_SRC_ALPHA; @@ -738,206 +914,197 @@ static void RSurfShader_Wall_Pass_BaseMTex(msurface_t *s) m.blendfunc1 = GL_ONE; m.blendfunc2 = GL_ZERO; } - m.numtriangles = s->mesh.numtriangles; - m.numverts = s->mesh.numverts; - m.index = s->mesh.index; - m.cr = 1; - if (lighthalf) - m.cr *= 2; - if (gl_combine.integer) - m.cr *= 4; - m.cg = m.cr; - m.cb = m.cr; - m.ca = 1; - m.tex[0] = R_GetTexture(s->currenttexture->texture); - m.tex[1] = R_GetTexture(s->lightmaptexture); - m.texcoords[0] = &s->mesh.vertex->st[0]; - m.texcoords[1] = &s->mesh.vertex->uv[0]; + m.cr = m.cg = m.cb = (float) (1 << lightscalebit); + m.ca = currentrenderentity->alpha; + m.tex[0] = R_GetTexture(surf->currenttexture->texture); + m.tex[1] = R_GetTexture(surf->lightmaptexture); m.texcoordstep[0] = sizeof(surfvertex_t); m.texcoordstep[1] = sizeof(surfvertex_t); - if (fogenabled) + for (mesh = surf->mesh;mesh;mesh = mesh->chain) { - m.color = &svert[0].c[0]; - m.colorstep = sizeof(surfvert_t); - if (softwaretransform_complexity) + m.numtriangles = mesh->numtriangles; + m.numverts = mesh->numverts; + m.index = mesh->index; + m.texcoords[0] = &mesh->vertex->st[0]; + m.texcoords[1] = &mesh->vertex->uv[0]; + if (fogenabled) { - m.vertex = &svert[0].v[0]; - m.vertexstep = sizeof(surfvert_t); - for (i = 0, sv = svert, v = s->mesh.vertex;i < m.numverts;i++, sv++, v++) + m.color = &svert[0].c[0]; + m.colorstep = sizeof(surfvert_t); + if (softwaretransform_complexity) { - softwaretransform(v->v, sv->v); - VectorSubtract(sv->v, r_origin, diff); - ifog = 1 - exp(fogdensity/DotProduct(diff, diff)); - sv->c[0] = m.cr * ifog; - sv->c[1] = m.cg * ifog; - sv->c[2] = m.cb * ifog; - sv->c[3] = m.ca; + m.vertex = &svert[0].v[0]; + m.vertexstep = sizeof(surfvert_t); + for (i = 0, sv = svert, v = mesh->vertex;i < m.numverts;i++, sv++, v++) + { + softwaretransform(v->v, sv->v); + VectorSubtract(sv->v, r_origin, diff); + ifog = 1 - exp(fogdensity/DotProduct(diff, diff)); + sv->c[0] = m.cr * ifog; + sv->c[1] = m.cg * ifog; + sv->c[2] = m.cb * ifog; + sv->c[3] = m.ca; + } } - } - else - { - m.vertex = &s->mesh.vertex->v[0]; - m.vertexstep = sizeof(surfvertex_t); - for (i = 0, sv = svert, v = s->mesh.vertex;i < m.numverts;i++, sv++, v++) + else { - VectorSubtract(v->v, r_origin, diff); - ifog = 1 - exp(fogdensity/DotProduct(diff, diff)); - sv->c[0] = m.cr * ifog; - sv->c[1] = m.cg * ifog; - sv->c[2] = m.cb * ifog; - sv->c[3] = m.ca; + m.vertex = &mesh->vertex->v[0]; + m.vertexstep = sizeof(surfvertex_t); + for (i = 0, sv = svert, v = mesh->vertex;i < m.numverts;i++, sv++, v++) + { + VectorSubtract(v->v, r_origin, diff); + ifog = 1 - exp(fogdensity/DotProduct(diff, diff)); + sv->c[0] = m.cr * ifog; + sv->c[1] = m.cg * ifog; + sv->c[2] = m.cb * ifog; + sv->c[3] = m.ca; + } } } - } - else - { - if (softwaretransform_complexity) - { - m.vertex = &svert[0].v[0]; - m.vertexstep = sizeof(surfvert_t); - for (i = 0, sv = svert, v = s->mesh.vertex;i < m.numverts;i++, sv++, v++) - softwaretransform(v->v, sv->v); - } else { - m.vertex = &s->mesh.vertex->v[0]; - m.vertexstep = sizeof(surfvertex_t); + if (softwaretransform_complexity) + { + m.vertex = &svert[0].v[0]; + m.vertexstep = sizeof(surfvert_t); + for (i = 0, sv = svert, v = mesh->vertex;i < m.numverts;i++, sv++, v++) + softwaretransform(v->v, sv->v); + } + else + { + m.vertex = &mesh->vertex->v[0]; + m.vertexstep = sizeof(surfvertex_t); + } } + R_Mesh_Draw(&m); } - R_Mesh_Draw(&m); } -static void RSurfShader_Wall_Pass_BaseTexture(msurface_t *s) +static void RSurfShader_Wall_Pass_BaseTexture(msurface_t *surf) { - int i; - surfvertex_t *v; - surfvert_t *sv; - rmeshinfo_t m; + int i; + surfvertex_t *v; + surfvert_t *sv; + surfmesh_t *mesh; + rmeshinfo_t m; memset(&m, 0, sizeof(m)); m.transparent = false; m.blendfunc1 = GL_ONE; m.blendfunc2 = GL_ZERO; - m.numtriangles = s->mesh.numtriangles; - m.numverts = s->mesh.numverts; - m.index = s->mesh.index; - if (lighthalf) - { - m.cr = 2; - m.cg = 2; - m.cb = 2; - } - else - { - m.cr = 1; - m.cg = 1; - m.cb = 1; - } + m.cr = m.cg = m.cb = (float) (1 << v_overbrightbits.integer); m.ca = 1; - m.tex[0] = R_GetTexture(s->currenttexture->texture); - m.texcoords[0] = &s->mesh.vertex->st[0]; + m.tex[0] = R_GetTexture(surf->currenttexture->texture); m.texcoordstep[0] = sizeof(surfvertex_t); - if (softwaretransform_complexity) - { - m.vertex = &svert[0].v[0]; - m.vertexstep = sizeof(surfvert_t); - for (i = 0, sv = svert, v = s->mesh.vertex;i < m.numverts;i++, sv++, v++) - softwaretransform(v->v, sv->v); - } - else + for (mesh = surf->mesh;mesh;mesh = mesh->chain) { - m.vertex = &s->mesh.vertex->v[0]; - m.vertexstep = sizeof(surfvertex_t); + m.numtriangles = mesh->numtriangles; + m.numverts = mesh->numverts; + m.index = mesh->index; + m.texcoords[0] = &mesh->vertex->st[0]; + if (softwaretransform_complexity) + { + m.vertex = &svert[0].v[0]; + m.vertexstep = sizeof(surfvert_t); + for (i = 0, sv = svert, v = mesh->vertex;i < m.numverts;i++, sv++, v++) + softwaretransform(v->v, sv->v); + } + else + { + m.vertex = &mesh->vertex->v[0]; + m.vertexstep = sizeof(surfvertex_t); + } + R_Mesh_Draw(&m); } - R_Mesh_Draw(&m); } -static void RSurfShader_Wall_Pass_BaseLightmap(msurface_t *s) +static void RSurfShader_Wall_Pass_BaseLightmap(msurface_t *surf) { - int i; - float diff[3], ifog; - surfvertex_t *v; - surfvert_t *sv; - rmeshinfo_t m; + int i; + float diff[3], ifog; + surfvertex_t *v; + surfvert_t *sv; + surfmesh_t *mesh; + rmeshinfo_t m; memset(&m, 0, sizeof(m)); m.transparent = false; m.blendfunc1 = GL_ZERO; m.blendfunc2 = GL_SRC_COLOR; - m.numtriangles = s->mesh.numtriangles; - m.numverts = s->mesh.numverts; - m.index = s->mesh.index; - m.cr = 1; - if (lighthalf) - m.cr *= 2.0f; - m.cg = m.cr; - m.cb = m.cr; + m.cr = m.cg = m.cb = (float) (1 << v_overbrightbits.integer); m.ca = 1; - m.tex[0] = R_GetTexture(s->lightmaptexture); - m.texcoords[0] = &s->mesh.vertex->uv[0]; + m.tex[0] = R_GetTexture(surf->lightmaptexture); m.texcoordstep[0] = sizeof(surfvertex_t); - if (fogenabled) + for (mesh = surf->mesh;mesh;mesh = mesh->chain) { - m.color = &svert[0].c[0]; - m.colorstep = sizeof(surfvert_t); - if (softwaretransform_complexity) + m.numtriangles = mesh->numtriangles; + m.numverts = mesh->numverts; + m.index = mesh->index; + m.texcoords[0] = &mesh->vertex->uv[0]; + if (fogenabled) { - m.vertex = &svert[0].v[0]; - m.vertexstep = sizeof(surfvert_t); - for (i = 0, sv = svert, v = s->mesh.vertex;i < m.numverts;i++, sv++, v++) + m.color = &svert[0].c[0]; + m.colorstep = sizeof(surfvert_t); + if (softwaretransform_complexity) { - softwaretransform(v->v, sv->v); - VectorSubtract(sv->v, r_origin, diff); - ifog = 1 - exp(fogdensity/DotProduct(diff, diff)); - sv->c[0] = m.cr * ifog; - sv->c[1] = m.cg * ifog; - sv->c[2] = m.cb * ifog; - sv->c[3] = m.ca; + m.vertex = &svert[0].v[0]; + m.vertexstep = sizeof(surfvert_t); + for (i = 0, sv = svert, v = mesh->vertex;i < m.numverts;i++, sv++, v++) + { + softwaretransform(v->v, sv->v); + VectorSubtract(sv->v, r_origin, diff); + ifog = 1 - exp(fogdensity/DotProduct(diff, diff)); + sv->c[0] = m.cr * ifog; + sv->c[1] = m.cg * ifog; + sv->c[2] = m.cb * ifog; + sv->c[3] = m.ca; + } } - } - else - { - m.vertex = &s->mesh.vertex->v[0]; - m.vertexstep = sizeof(surfvertex_t); - for (i = 0, sv = svert, v = s->mesh.vertex;i < m.numverts;i++, sv++, v++) + else { - VectorSubtract(v->v, r_origin, diff); - ifog = 1 - exp(fogdensity/DotProduct(diff, diff)); - sv->c[0] = m.cr * ifog; - sv->c[1] = m.cg * ifog; - sv->c[2] = m.cb * ifog; - sv->c[3] = m.ca; + m.vertex = &mesh->vertex->v[0]; + m.vertexstep = sizeof(surfvertex_t); + for (i = 0, sv = svert, v = mesh->vertex;i < m.numverts;i++, sv++, v++) + { + VectorSubtract(v->v, r_origin, diff); + ifog = 1 - exp(fogdensity/DotProduct(diff, diff)); + sv->c[0] = m.cr * ifog; + sv->c[1] = m.cg * ifog; + sv->c[2] = m.cb * ifog; + sv->c[3] = m.ca; + } } } - } - else - { - if (softwaretransform_complexity) - { - m.vertex = &svert[0].v[0]; - m.vertexstep = sizeof(surfvert_t); - for (i = 0, sv = svert, v = s->mesh.vertex;i < m.numverts;i++, sv++, v++) - softwaretransform(v->v, sv->v); - } else { - m.vertex = &s->mesh.vertex->v[0]; - m.vertexstep = sizeof(surfvertex_t); + if (softwaretransform_complexity) + { + m.vertex = &svert[0].v[0]; + m.vertexstep = sizeof(surfvert_t); + for (i = 0, sv = svert, v = mesh->vertex;i < m.numverts;i++, sv++, v++) + softwaretransform(v->v, sv->v); + } + else + { + m.vertex = &mesh->vertex->v[0]; + m.vertexstep = sizeof(surfvertex_t); + } } + R_Mesh_Draw(&m); } - R_Mesh_Draw(&m); } -static void RSurfShader_Wall_Pass_BaseVertex(msurface_t *s) +static void RSurfShader_Wall_Pass_BaseVertex(msurface_t *surf) { - int i, size3; - float c[3], base[3], scale, diff[3], ifog; - surfvertex_t *v; - surfvert_t *sv; - rmeshinfo_t m; - byte *lm; + int i, size3; + float c[3], base[3], scale, diff[3], ifog; + surfvertex_t *v; + surfvert_t *sv; + surfmesh_t *mesh; + rmeshinfo_t m; + qbyte *lm; - size3 = ((s->extents[0]>>4)+1)*((s->extents[1]>>4)+1)*3; + size3 = ((surf->extents[0]>>4)+1)*((surf->extents[1]>>4)+1)*3; base[0] = base[1] = base[2] = r_ambient.value * (1.0f / 128.0f); @@ -948,7 +1115,7 @@ static void RSurfShader_Wall_Pass_BaseVertex(msurface_t *s) m.blendfunc1 = GL_SRC_ALPHA; m.blendfunc2 = GL_ONE; } - else if (currentrenderentity != &cl_entities[0].render && (s->currenttexture->fogtexture != NULL || currentrenderentity->alpha != 1)) + else if (surf->currenttexture->fogtexture != NULL || currentrenderentity->alpha != 1) { m.transparent = true; m.blendfunc1 = GL_SRC_ALPHA; @@ -960,72 +1127,76 @@ static void RSurfShader_Wall_Pass_BaseVertex(msurface_t *s) m.blendfunc1 = GL_ONE; m.blendfunc2 = GL_ZERO; } - m.numtriangles = s->mesh.numtriangles; - m.numverts = s->mesh.numverts; - m.index = s->mesh.index; m.vertex = &svert[0].v[0]; m.vertexstep = sizeof(surfvert_t); m.color = &svert[0].c[0]; m.colorstep = sizeof(surfvert_t); - m.tex[0] = R_GetTexture(s->currenttexture->texture); - m.texcoords[0] = &s->mesh.vertex->st[0]; + m.tex[0] = R_GetTexture(surf->currenttexture->texture); m.texcoordstep[0] = sizeof(surfvertex_t); - for (i = 0, sv = svert, v = s->mesh.vertex;i < m.numverts;i++, sv++, v++) + for (mesh = surf->mesh;mesh;mesh = mesh->chain) { - softwaretransform(v->v, sv->v); - VectorCopy(base, c); - if (s->styles[0] != 255) + m.numtriangles = mesh->numtriangles; + m.numverts = mesh->numverts; + m.index = mesh->index; + m.texcoords[0] = &mesh->vertex->st[0]; + for (i = 0, sv = svert, v = mesh->vertex;i < m.numverts;i++, sv++, v++) { - lm = s->samples + v->lightmapoffset; - scale = d_lightstylevalue[s->styles[0]] * (1.0f / 32768.0f); - VectorMA(c, scale, lm, c); - if (s->styles[1] != 255) + softwaretransform(v->v, sv->v); + VectorCopy(base, c); + if (surf->styles[0] != 255) { - lm += size3; - scale = d_lightstylevalue[s->styles[1]] * (1.0f / 32768.0f); + lm = surf->samples + v->lightmapoffset; + scale = d_lightstylevalue[surf->styles[0]] * (1.0f / 32768.0f); VectorMA(c, scale, lm, c); - if (s->styles[2] != 255) + if (surf->styles[1] != 255) { lm += size3; - scale = d_lightstylevalue[s->styles[2]] * (1.0f / 32768.0f); + scale = d_lightstylevalue[surf->styles[1]] * (1.0f / 32768.0f); VectorMA(c, scale, lm, c); - if (s->styles[3] != 255) + if (surf->styles[2] != 255) { lm += size3; - scale = d_lightstylevalue[s->styles[3]] * (1.0f / 32768.0f); + scale = d_lightstylevalue[surf->styles[2]] * (1.0f / 32768.0f); VectorMA(c, scale, lm, c); + if (surf->styles[3] != 255) + { + lm += size3; + scale = d_lightstylevalue[surf->styles[3]] * (1.0f / 32768.0f); + VectorMA(c, scale, lm, c); + } } } } + sv->c[0] = c[0]; + sv->c[1] = c[1]; + sv->c[2] = c[2]; + sv->c[3] = currentrenderentity->alpha; } - sv->c[0] = c[0]; - sv->c[1] = c[1]; - sv->c[2] = c[2]; - sv->c[3] = currentrenderentity->alpha; - } - if (s->dlightframe == r_framecount) - RSurf_Light(s->dlightbits, m.numverts); - if (fogenabled) - { - for (i = 0, sv = svert, v = s->mesh.vertex;i < m.numverts;i++, sv++, v++) + if (surf->dlightframe == r_framecount) + RSurf_Light(surf->dlightbits, m.numverts); + if (fogenabled) { - VectorSubtract(sv->v, r_origin, diff); - ifog = 1 - exp(fogdensity/DotProduct(diff, diff)); - sv->c[0] *= ifog; - sv->c[1] *= ifog; - sv->c[2] *= ifog; + for (i = 0, sv = svert, v = mesh->vertex;i < m.numverts;i++, sv++, v++) + { + VectorSubtract(sv->v, r_origin, diff); + ifog = 1 - exp(fogdensity/DotProduct(diff, diff)); + sv->c[0] *= ifog; + sv->c[1] *= ifog; + sv->c[2] *= ifog; + } } + R_Mesh_Draw(&m); } - R_Mesh_Draw(&m); } -static void RSurfShader_Wall_Pass_BaseFullbright(msurface_t *s) +static void RSurfShader_Wall_Pass_BaseFullbright(msurface_t *surf) { - int i; - float diff[3], ifog; - surfvertex_t *v; - surfvert_t *sv; - rmeshinfo_t m; + int i; + float diff[3], ifog; + surfvertex_t *v; + surfvert_t *sv; + surfmesh_t *mesh; + rmeshinfo_t m; memset(&m, 0, sizeof(m)); if (currentrenderentity->effects & EF_ADDITIVE) @@ -1034,7 +1205,7 @@ static void RSurfShader_Wall_Pass_BaseFullbright(msurface_t *s) m.blendfunc1 = GL_SRC_ALPHA; m.blendfunc2 = GL_ONE; } - else if (currentrenderentity != &cl_entities[0].render && (s->currenttexture->fogtexture != NULL || currentrenderentity->alpha != 1)) + else if (surf->currenttexture->fogtexture != NULL || currentrenderentity->alpha != 1) { m.transparent = true; m.blendfunc1 = GL_SRC_ALPHA; @@ -1046,382 +1217,377 @@ static void RSurfShader_Wall_Pass_BaseFullbright(msurface_t *s) m.blendfunc1 = GL_ONE; m.blendfunc2 = GL_ZERO; } - m.numtriangles = s->mesh.numtriangles; - m.numverts = s->mesh.numverts; - m.index = s->mesh.index; m.vertex = &svert[0].v[0]; m.vertexstep = sizeof(surfvert_t); - m.tex[0] = R_GetTexture(s->currenttexture->texture); - m.texcoords[0] = &s->mesh.vertex->st[0]; + m.tex[0] = R_GetTexture(surf->currenttexture->texture); m.texcoordstep[0] = sizeof(surfvertex_t); - if (fogenabled) + for (mesh = surf->mesh;mesh;mesh = mesh->chain) { - m.color = &svert[0].c[0]; - m.colorstep = sizeof(surfvert_t); - for (i = 0, sv = svert, v = s->mesh.vertex;i < m.numverts;i++, sv++, v++) + m.numtriangles = mesh->numtriangles; + m.numverts = mesh->numverts; + m.index = mesh->index; + m.texcoords[0] = &mesh->vertex->st[0]; + if (fogenabled) { - softwaretransform(v->v, sv->v); - VectorSubtract(sv->v, r_origin, diff); - ifog = 1 - exp(fogdensity/DotProduct(diff, diff)); - sv->c[0] = ifog; - sv->c[1] = ifog; - sv->c[2] = ifog; - sv->c[3] = currentrenderentity->alpha; + m.color = &svert[0].c[0]; + m.colorstep = sizeof(surfvert_t); + for (i = 0, sv = svert, v = mesh->vertex;i < m.numverts;i++, sv++, v++) + { + softwaretransform(v->v, sv->v); + VectorSubtract(sv->v, r_origin, diff); + ifog = 1 - exp(fogdensity/DotProduct(diff, diff)); + sv->c[0] = ifog; + sv->c[1] = ifog; + sv->c[2] = ifog; + sv->c[3] = currentrenderentity->alpha; + } } + else + { + m.cr = m.cg = m.cb = 1; + m.ca = currentrenderentity->alpha; + for (i = 0, sv = svert, v = mesh->vertex;i < m.numverts;i++, sv++, v++) + softwaretransform(v->v, sv->v); + } + R_Mesh_Draw(&m); } - else - { - m.cr = m.cg = m.cb = 1; - m.ca = currentrenderentity->alpha; - for (i = 0, sv = svert, v = s->mesh.vertex;i < m.numverts;i++, sv++, v++) - softwaretransform(v->v, sv->v); - } - R_Mesh_Draw(&m); } -static void RSurfShader_Wall_Pass_Light(msurface_t *s) +static void RSurfShader_Wall_Pass_Light(msurface_t *surf) { - int i; - float diff[3], ifog; - surfvertex_t *v; - surfvert_t *sv; - rmeshinfo_t m; + int i; + float diff[3], ifog; + surfvertex_t *v; + surfvert_t *sv; + surfmesh_t *mesh; + rmeshinfo_t m; memset(&m, 0, sizeof(m)); if (currentrenderentity->effects & EF_ADDITIVE) m.transparent = true; - else if (currentrenderentity != &cl_entities[0].render && (s->currenttexture->fogtexture != NULL || currentrenderentity->alpha != 1)) + else if (surf->currenttexture->fogtexture != NULL || currentrenderentity->alpha != 1) m.transparent = true; else m.transparent = false; m.blendfunc1 = GL_SRC_ALPHA; m.blendfunc2 = GL_ONE; - m.numtriangles = s->mesh.numtriangles; - m.numverts = s->mesh.numverts; - m.index = s->mesh.index; m.vertex = &svert[0].v[0]; m.vertexstep = sizeof(surfvert_t); m.color = &svert[0].c[0]; m.colorstep = sizeof(surfvert_t); - m.tex[0] = R_GetTexture(s->currenttexture->texture); - m.texcoords[0] = &s->mesh.vertex->st[0]; + m.tex[0] = R_GetTexture(surf->currenttexture->texture); m.texcoordstep[0] = sizeof(surfvertex_t); - for (i = 0, sv = svert, v = s->mesh.vertex;i < m.numverts;i++, sv++, v++) - { - softwaretransform(v->v, sv->v); - sv->c[0] = 0; - sv->c[1] = 0; - sv->c[2] = 0; - sv->c[3] = currentrenderentity->alpha; - } - if (RSurf_Light(s->dlightbits, m.numverts)) + for (mesh = surf->mesh;mesh;mesh = mesh->chain) { - if (fogenabled) + m.numtriangles = mesh->numtriangles; + m.numverts = mesh->numverts; + m.index = mesh->index; + m.texcoords[0] = &mesh->vertex->st[0]; + for (i = 0, sv = svert, v = mesh->vertex;i < m.numverts;i++, sv++, v++) { - for (i = 0, sv = svert;i < m.numverts;i++, sv++) + softwaretransform(v->v, sv->v); + sv->c[0] = 0; + sv->c[1] = 0; + sv->c[2] = 0; + sv->c[3] = currentrenderentity->alpha; + } + if (RSurf_Light(surf->dlightbits, m.numverts)) + { + if (fogenabled) { - VectorSubtract(sv->v, r_origin, diff); - ifog = 1 - exp(fogdensity/DotProduct(diff, diff)); - sv->c[0] *= ifog; - sv->c[1] *= ifog; - sv->c[2] *= ifog; + for (i = 0, sv = svert;i < m.numverts;i++, sv++) + { + VectorSubtract(sv->v, r_origin, diff); + ifog = 1 - exp(fogdensity/DotProduct(diff, diff)); + sv->c[0] *= ifog; + sv->c[1] *= ifog; + sv->c[2] *= ifog; + } } + R_Mesh_Draw(&m); } - R_Mesh_Draw(&m); } } -static void RSurfShader_Wall_Pass_Glow(msurface_t *s) +static void RSurfShader_Wall_Pass_Glow(msurface_t *surf) { - int i; - float diff[3], ifog; - surfvertex_t *v; - surfvert_t *sv; - rmeshinfo_t m; + int i; + float diff[3], ifog; + surfvertex_t *v; + surfvert_t *sv; + surfmesh_t *mesh; + rmeshinfo_t m; memset(&m, 0, sizeof(m)); if (currentrenderentity->effects & EF_ADDITIVE) m.transparent = true; - else if (currentrenderentity != &cl_entities[0].render && (s->currenttexture->fogtexture != NULL || currentrenderentity->alpha != 1)) + else if (surf->currenttexture->fogtexture != NULL || currentrenderentity->alpha != 1) m.transparent = true; else m.transparent = false; m.blendfunc1 = GL_SRC_ALPHA; m.blendfunc2 = GL_ONE; - m.numtriangles = s->mesh.numtriangles; - m.numverts = s->mesh.numverts; - m.index = s->mesh.index; m.cr = 1; m.cg = 1; m.cb = 1; m.ca = currentrenderentity->alpha; - m.tex[0] = R_GetTexture(s->currenttexture->glowtexture); - m.texcoords[0] = &s->mesh.vertex->st[0]; + m.tex[0] = R_GetTexture(surf->currenttexture->glowtexture); m.texcoordstep[0] = sizeof(surfvertex_t); - if (fogenabled) + for (mesh = surf->mesh;mesh;mesh = mesh->chain) { - m.color = &svert[0].c[0]; - m.colorstep = sizeof(surfvert_t); - if (softwaretransform_complexity) + m.numtriangles = mesh->numtriangles; + m.numverts = mesh->numverts; + m.index = mesh->index; + m.texcoords[0] = &mesh->vertex->st[0]; + if (fogenabled) { - m.vertex = &svert[0].v[0]; - m.vertexstep = sizeof(surfvert_t); - for (i = 0, sv = svert, v = s->mesh.vertex;i < m.numverts;i++, sv++, v++) + m.color = &svert[0].c[0]; + m.colorstep = sizeof(surfvert_t); + if (softwaretransform_complexity) { - softwaretransform(v->v, sv->v); - VectorSubtract(sv->v, r_origin, diff); - ifog = 1 - exp(fogdensity/DotProduct(diff, diff)); - sv->c[0] = m.cr * ifog; - sv->c[1] = m.cg * ifog; - sv->c[2] = m.cb * ifog; - sv->c[3] = m.ca; + m.vertex = &svert[0].v[0]; + m.vertexstep = sizeof(surfvert_t); + for (i = 0, sv = svert, v = mesh->vertex;i < m.numverts;i++, sv++, v++) + { + softwaretransform(v->v, sv->v); + VectorSubtract(sv->v, r_origin, diff); + ifog = 1 - exp(fogdensity/DotProduct(diff, diff)); + sv->c[0] = m.cr * ifog; + sv->c[1] = m.cg * ifog; + sv->c[2] = m.cb * ifog; + sv->c[3] = m.ca; + } } - } - else - { - m.vertex = &s->mesh.vertex->v[0]; - m.vertexstep = sizeof(surfvertex_t); - for (i = 0, sv = svert, v = s->mesh.vertex;i < m.numverts;i++, sv++, v++) + else { - VectorSubtract(v->v, r_origin, diff); - ifog = 1 - exp(fogdensity/DotProduct(diff, diff)); - sv->c[0] = m.cr * ifog; - sv->c[1] = m.cg * ifog; - sv->c[2] = m.cb * ifog; - sv->c[3] = m.ca; + m.vertex = &mesh->vertex->v[0]; + m.vertexstep = sizeof(surfvertex_t); + for (i = 0, sv = svert, v = mesh->vertex;i < m.numverts;i++, sv++, v++) + { + VectorSubtract(v->v, r_origin, diff); + ifog = 1 - exp(fogdensity/DotProduct(diff, diff)); + sv->c[0] = m.cr * ifog; + sv->c[1] = m.cg * ifog; + sv->c[2] = m.cb * ifog; + sv->c[3] = m.ca; + } } } - } - else - { - if (softwaretransform_complexity) - { - m.vertex = &svert[0].v[0]; - m.vertexstep = sizeof(surfvert_t); - for (i = 0, sv = svert, v = s->mesh.vertex;i < m.numverts;i++, sv++, v++) - softwaretransform(v->v, sv->v); - } else { - m.vertex = &s->mesh.vertex->v[0]; - m.vertexstep = sizeof(surfvertex_t); + if (softwaretransform_complexity) + { + m.vertex = &svert[0].v[0]; + m.vertexstep = sizeof(surfvert_t); + for (i = 0, sv = svert, v = mesh->vertex;i < m.numverts;i++, sv++, v++) + softwaretransform(v->v, sv->v); + } + else + { + m.vertex = &mesh->vertex->v[0]; + m.vertexstep = sizeof(surfvertex_t); + } } + R_Mesh_Draw(&m); } - R_Mesh_Draw(&m); } -static void RSurfShader_Wall_Pass_Fog(msurface_t *s) +static void RSurfShader_Wall_Pass_Fog(msurface_t *surf) { - int i; - surfvertex_t *v; - surfvert_t *sv; - rmeshinfo_t m; - vec3_t diff; + int i; + surfvertex_t *v; + surfvert_t *sv; + rmeshinfo_t m; + surfmesh_t *mesh; + vec3_t diff; memset(&m, 0, sizeof(m)); if (currentrenderentity->effects & EF_ADDITIVE) m.transparent = true; - else if (currentrenderentity != &cl_entities[0].render && (s->currenttexture->fogtexture != NULL || currentrenderentity->alpha != 1)) + else if (surf->currenttexture->fogtexture != NULL || currentrenderentity->alpha != 1) m.transparent = true; else m.transparent = false; m.blendfunc1 = GL_SRC_ALPHA; m.blendfunc2 = GL_ONE; - m.numtriangles = s->mesh.numtriangles; - m.numverts = s->mesh.numverts; - m.index = s->mesh.index; m.color = &svert[0].c[0]; m.colorstep = sizeof(surfvert_t); - m.tex[0] = R_GetTexture(s->currenttexture->fogtexture); - m.texcoords[0] = &s->mesh.vertex->st[0]; + m.tex[0] = R_GetTexture(surf->currenttexture->fogtexture); m.texcoordstep[0] = sizeof(surfvertex_t); - if (softwaretransform_complexity) + for (mesh = surf->mesh;mesh;mesh = mesh->chain) { - m.vertex = &svert[0].v[0]; - m.vertexstep = sizeof(surfvert_t); - for (i = 0, sv = svert, v = s->mesh.vertex;i < m.numverts;i++, sv++, v++) + m.numtriangles = mesh->numtriangles; + m.numverts = mesh->numverts; + m.index = mesh->index; + m.texcoords[0] = &mesh->vertex->st[0]; + if (softwaretransform_complexity) { - softwaretransform(v->v, sv->v); - VectorSubtract(sv->v, r_origin, diff); - sv->c[0] = fogcolor[0]; - sv->c[1] = fogcolor[1]; - sv->c[2] = fogcolor[2]; - sv->c[3] = currentrenderentity->alpha * exp(fogdensity/DotProduct(diff,diff)); + m.vertex = &svert[0].v[0]; + m.vertexstep = sizeof(surfvert_t); + for (i = 0, sv = svert, v = mesh->vertex;i < m.numverts;i++, sv++, v++) + { + softwaretransform(v->v, sv->v); + VectorSubtract(sv->v, r_origin, diff); + sv->c[0] = fogcolor[0]; + sv->c[1] = fogcolor[1]; + sv->c[2] = fogcolor[2]; + sv->c[3] = currentrenderentity->alpha * exp(fogdensity/DotProduct(diff,diff)); + } } - } - else - { - m.vertex = &s->mesh.vertex->v[0]; - m.vertexstep = sizeof(surfvertex_t); - for (i = 0, sv = svert, v = s->mesh.vertex;i < m.numverts;i++, sv++, v++) + else { - VectorSubtract(v->v, r_origin, diff); - sv->c[0] = fogcolor[0]; - sv->c[1] = fogcolor[1]; - sv->c[2] = fogcolor[2]; - sv->c[3] = currentrenderentity->alpha * exp(fogdensity/DotProduct(diff,diff)); + m.vertex = &mesh->vertex->v[0]; + m.vertexstep = sizeof(surfvertex_t); + for (i = 0, sv = svert, v = mesh->vertex;i < m.numverts;i++, sv++, v++) + { + VectorSubtract(v->v, r_origin, diff); + sv->c[0] = fogcolor[0]; + sv->c[1] = fogcolor[1]; + sv->c[2] = fogcolor[2]; + sv->c[3] = currentrenderentity->alpha * exp(fogdensity/DotProduct(diff,diff)); + } } + R_Mesh_Draw(&m); } - R_Mesh_Draw(&m); } -static int RSurfShader_Wall_Fullbright(int stage, msurface_t *s) +static void RSurfShader_Wall_Fullbright(msurface_t *firstsurf) { - switch(stage) + msurface_t *surf; + for (surf = firstsurf;surf;surf = surf->chain) { - case 0: - RSurfShader_Wall_Pass_BaseFullbright(s); - return false; - case 1: - if (s->currenttexture->glowtexture) - RSurfShader_Wall_Pass_Glow(s); - return false; - default: - return true; + c_brush_polys++; + RSurfShader_Wall_Pass_BaseFullbright(surf); } + for (surf = firstsurf;surf;surf = surf->chain) + if (surf->currenttexture->glowtexture) + RSurfShader_Wall_Pass_Glow(surf); + if (fogenabled) + for (surf = firstsurf;surf;surf = surf->chain) + RSurfShader_Wall_Pass_Fog(surf); } -static int RSurfShader_Wall_Vertex(int stage, msurface_t *s) +static void RSurfShader_Wall_Vertex(msurface_t *firstsurf) { - switch(stage) + msurface_t *surf; + for (surf = firstsurf;surf;surf = surf->chain) { - case 0: - RSurfShader_Wall_Pass_BaseVertex(s); - return false; - case 1: - if (s->currenttexture->glowtexture) - RSurfShader_Wall_Pass_Glow(s); - return false; - default: - return true; + c_brush_polys++; + RSurfShader_Wall_Pass_BaseVertex(surf); } + for (surf = firstsurf;surf;surf = surf->chain) + if (surf->currenttexture->glowtexture) + RSurfShader_Wall_Pass_Glow(surf); + if (fogenabled) + for (surf = firstsurf;surf;surf = surf->chain) + RSurfShader_Wall_Pass_Fog(surf); } -static int RSurfShader_Wall_Lightmap(int stage, msurface_t *s) +static void RSurfShader_Wall_Lightmap(msurface_t *firstsurf) { + msurface_t *surf; if (r_vertexsurfaces.integer) { - switch(stage) + for (surf = firstsurf;surf;surf = surf->chain) { - case 0: - RSurfShader_Wall_Pass_BaseVertex(s); - return false; - case 1: - if (s->currenttexture->glowtexture) - RSurfShader_Wall_Pass_Glow(s); - return false; - default: - return true; + c_brush_polys++; + RSurfShader_Wall_Pass_BaseVertex(surf); } + for (surf = firstsurf;surf;surf = surf->chain) + if (surf->currenttexture->glowtexture) + RSurfShader_Wall_Pass_Glow(surf); + if (fogenabled) + for (surf = firstsurf;surf;surf = surf->chain) + RSurfShader_Wall_Pass_Fog(surf); } else if (r_multitexture.integer) { if (r_dlightmap.integer) { - switch(stage) + for (surf = firstsurf;surf;surf = surf->chain) { - case 0: - RSurfShader_Wall_Pass_BaseMTex(s); - return false; - case 1: - if (s->currenttexture->glowtexture) - RSurfShader_Wall_Pass_Glow(s); - return false; - default: - return true; + c_brush_polys++; + RSurfShader_Wall_Pass_BaseMTex(surf); } + for (surf = firstsurf;surf;surf = surf->chain) + if (surf->currenttexture->glowtexture) + RSurfShader_Wall_Pass_Glow(surf); + if (fogenabled) + for (surf = firstsurf;surf;surf = surf->chain) + RSurfShader_Wall_Pass_Fog(surf); } else { - switch(stage) + for (surf = firstsurf;surf;surf = surf->chain) { - case 0: - RSurfShader_Wall_Pass_BaseMTex(s); - return false; - case 1: - if (s->dlightframe == r_framecount) - RSurfShader_Wall_Pass_Light(s); - return false; - case 2: - if (s->currenttexture->glowtexture) - RSurfShader_Wall_Pass_Glow(s); - return false; - default: - return true; + c_brush_polys++; + RSurfShader_Wall_Pass_BaseMTex(surf); } + for (surf = firstsurf;surf;surf = surf->chain) + if (surf->dlightframe == r_framecount) + RSurfShader_Wall_Pass_Light(surf); + for (surf = firstsurf;surf;surf = surf->chain) + if (surf->currenttexture->glowtexture) + RSurfShader_Wall_Pass_Glow(surf); + if (fogenabled) + for (surf = firstsurf;surf;surf = surf->chain) + RSurfShader_Wall_Pass_Fog(surf); } } - else if (currentrenderentity != &cl_entities[0].render && (s->currenttexture->fogtexture != NULL || currentrenderentity->alpha != 1 || currentrenderentity->effects & EF_ADDITIVE)) + else if (firstsurf->currenttexture->fogtexture != NULL || currentrenderentity->alpha != 1 || currentrenderentity->effects & EF_ADDITIVE) { - switch(stage) + for (surf = firstsurf;surf;surf = surf->chain) { - case 0: - RSurfShader_Wall_Pass_BaseVertex(s); - return false; - case 1: - if (s->currenttexture->glowtexture) - RSurfShader_Wall_Pass_Glow(s); - return false; - default: - return true; + c_brush_polys++; + RSurfShader_Wall_Pass_BaseVertex(surf); } + for (surf = firstsurf;surf;surf = surf->chain) + if (surf->currenttexture->glowtexture) + RSurfShader_Wall_Pass_Glow(surf); + if (fogenabled) + for (surf = firstsurf;surf;surf = surf->chain) + RSurfShader_Wall_Pass_Fog(surf); } else { if (r_dlightmap.integer) { - switch(stage) + for (surf = firstsurf;surf;surf = surf->chain) { - case 0: - RSurfShader_Wall_Pass_BaseTexture(s); - return false; - case 1: - RSurfShader_Wall_Pass_BaseLightmap(s); - return false; - case 2: - if (s->currenttexture->glowtexture) - RSurfShader_Wall_Pass_Glow(s); - return false; - default: - return true; + c_brush_polys++; + RSurfShader_Wall_Pass_BaseTexture(surf); } + for (surf = firstsurf;surf;surf = surf->chain) + RSurfShader_Wall_Pass_BaseLightmap(surf); + for (surf = firstsurf;surf;surf = surf->chain) + if (surf->currenttexture->glowtexture) + RSurfShader_Wall_Pass_Glow(surf); + if (fogenabled) + for (surf = firstsurf;surf;surf = surf->chain) + RSurfShader_Wall_Pass_Fog(surf); } else { - switch(stage) + for (surf = firstsurf;surf;surf = surf->chain) { - case 0: - RSurfShader_Wall_Pass_BaseTexture(s); - return false; - case 1: - RSurfShader_Wall_Pass_BaseLightmap(s); - return false; - case 2: - if (s->dlightframe == r_framecount) - RSurfShader_Wall_Pass_Light(s); - return false; - case 3: - if (s->currenttexture->glowtexture) - RSurfShader_Wall_Pass_Glow(s); - return false; - default: - return true; + c_brush_polys++; + RSurfShader_Wall_Pass_BaseTexture(surf); } + for (surf = firstsurf;surf;surf = surf->chain) + RSurfShader_Wall_Pass_BaseLightmap(surf); + for (surf = firstsurf;surf;surf = surf->chain) + if (surf->dlightframe == r_framecount) + RSurfShader_Wall_Pass_Light(surf); + for (surf = firstsurf;surf;surf = surf->chain) + if (surf->currenttexture->glowtexture) + RSurfShader_Wall_Pass_Glow(surf); + if (fogenabled) + for (surf = firstsurf;surf;surf = surf->chain) + RSurfShader_Wall_Pass_Fog(surf); } } } -static int RSurfShader_Wall_Fog(int stage, msurface_t *s) -{ - if (stage == 0 && fogenabled) - { - RSurfShader_Wall_Pass_Fog(s); - return false; - } - else - return true; -} - /* ============================================================= @@ -1649,7 +1815,7 @@ static void R_PVSWorldNode() msurface_t *surf, **mark, **endmark; mleaf_t *leaf; tinyplane_t plane; - byte *worldvis; + qbyte *worldvis; worldvis = Mod_LeafPVS (r_viewleaf, cl.worldmodel); @@ -1747,11 +1913,11 @@ loc1: goto loc1; } -Cshader_t Cshader_wall_vertex = {{NULL, RSurfShader_Wall_Vertex, RSurfShader_Wall_Fog}, NULL}; -Cshader_t Cshader_wall_lightmap = {{NULL, RSurfShader_Wall_Lightmap, RSurfShader_Wall_Fog}, NULL}; -Cshader_t Cshader_wall_fullbright = {{NULL, RSurfShader_Wall_Fullbright, RSurfShader_Wall_Fog}, NULL}; -Cshader_t Cshader_water = {{NULL, RSurfShader_Water, NULL}, NULL}; -Cshader_t Cshader_sky = {{RSurfShader_Sky, NULL, NULL}, NULL}; +Cshader_t Cshader_wall_vertex = {{NULL, RSurfShader_Wall_Vertex}, NULL}; +Cshader_t Cshader_wall_lightmap = {{NULL, RSurfShader_Wall_Lightmap}, NULL}; +Cshader_t Cshader_wall_fullbright = {{NULL, RSurfShader_Wall_Fullbright}, NULL}; +Cshader_t Cshader_water = {{NULL, RSurfShader_Water}, NULL}; +Cshader_t Cshader_sky = {{RSurfShader_Sky, NULL}, NULL}; int Cshader_count = 5; Cshader_t *Cshaders[5] = @@ -1765,7 +1931,7 @@ Cshader_t *Cshaders[5] = void R_PrepareSurfaces(void) { - int i; + int i, entframe, texframe, framecount; texture_t *t; model_t *model; msurface_t *surf; @@ -1774,6 +1940,8 @@ void R_PrepareSurfaces(void) Cshaders[i]->chain = NULL; model = currentrenderentity->model; + entframe = currentrenderentity->frame; + texframe = (int)(cl.time * 5.0f); for (i = 0;i < model->nummodelsurfaces;i++) { @@ -1784,14 +1952,28 @@ void R_PrepareSurfaces(void) { surf->insertframe = r_framecount; c_faces++; - // manually inlined R_TextureAnimation - //t = R_TextureAnimation(surf->texinfo->texture); t = surf->texinfo->texture; - if (t->alternate_anims != NULL && currentrenderentity->frame) - t = t->alternate_anims; - if (t->anim_total >= 2) - t = t->anim_frames[(int)(cl.time * 5.0f) % t->anim_total]; - surf->currenttexture = t; + if (t->animated) + { + if (entframe) + { + framecount = t->anim_total[1]; + if (framecount >= 2) + surf->currenttexture = t->anim_frames[1][texframe % framecount]; + else + surf->currenttexture = t->anim_frames[1][0]; + } + else + { + framecount = t->anim_total[0]; + if (framecount >= 2) + surf->currenttexture = t->anim_frames[0][texframe % framecount]; + else + surf->currenttexture = t->anim_frames[0][0]; + } + } + else + surf->currenttexture = t; } surf->chain = surf->shader->chain; @@ -1802,66 +1984,30 @@ void R_PrepareSurfaces(void) void R_DrawSurfaces (int type) { - int i, stage; - msurface_t *surf; + int i; Cshader_t *shader; for (i = 0;i < Cshader_count;i++) { shader = Cshaders[i]; if (shader->chain && shader->shaderfunc[type]) - for (stage = 0;stage < 1000;stage++) - for (surf = shader->chain;surf;surf = surf->chain) - if (shader->shaderfunc[type](stage, surf)) - goto done; -done:; + shader->shaderfunc[type](shader->chain); } } -void R_DrawSurfacesAll (void) -{ - R_DrawSurfaces(SHADERSTAGE_SKY); - R_DrawSurfaces(SHADERSTAGE_NORMAL); - R_DrawSurfaces(SHADERSTAGE_FOG); -} - static float portalpointbuffer[256][3]; void R_DrawPortals(void) { int drawportals, i; -// mleaf_t *leaf, *endleaf; mportal_t *portal, *endportal; - mvertex_t *point/*, *endpoint*/; + mvertex_t *point; rmeshinfo_t m; drawportals = r_drawportals.integer; + if (drawportals < 1) return; - /* - leaf = cl.worldmodel->leafs; - endleaf = leaf + cl.worldmodel->numleafs; - for (;leaf < endleaf;leaf++) - { - if (leaf->visframe == r_framecount && leaf->portals) - { - i = leaf - cl.worldmodel->leafs; - r = (i & 0x0007) << 5; - g = (i & 0x0038) << 2; - b = (i & 0x01C0) >> 1; - portal = leaf->portals; - while (portal) - { - transpolybegin(0, 0, 0, TPOLYTYPE_ALPHA); - point = portal->points + portal->numpoints - 1; - endpoint = portal->points; - for (;point >= endpoint;point--) - transpolyvertub(point->position[0], point->position[1], point->position[2], 0, 0, r, g, b, 32); - transpolyend(); - portal = portal->next; - } - } - } - */ + memset(&m, 0, sizeof(m)); m.transparent = true; m.blendfunc1 = GL_SRC_ALPHA; @@ -1899,7 +2045,7 @@ void R_DrawPortals(void) void R_SetupForBModelRendering(void) { int i; - msurface_t *s; + msurface_t *surf; model_t *model; vec3_t modelorg; @@ -1913,15 +2059,15 @@ void R_SetupForBModelRendering(void) for (i = 0;i < model->nummodelsurfaces;i++) { - s = model->modelsortedsurfaces[i]; - if (((s->flags & SURF_PLANEBACK) == 0) == (PlaneDiff(modelorg, s->plane) >= 0)) - s->visframe = r_framecount; + surf = model->modelsortedsurfaces[i]; + if (((surf->flags & SURF_PLANEBACK) == 0) == (PlaneDiff(modelorg, surf->plane) >= 0)) + surf->visframe = r_framecount; else - s->visframe = -1; - s->worldnodeframe = -1; - s->lightframe = -1; - s->dlightframe = -1; - s->insertframe = -1; + surf->visframe = -1; + surf->worldnodeframe = -1; + surf->lightframe = -1; + surf->dlightframe = -1; + surf->insertframe = -1; } } @@ -1937,7 +2083,7 @@ void R_SetupForWorldRendering(void) static void R_SurfMarkLights (void) { int i; - msurface_t *s; + msurface_t *surf; if (r_dynamic.integer) R_MarkLights(); @@ -1946,26 +2092,22 @@ static void R_SurfMarkLights (void) { for (i = 0;i < currentrenderentity->model->nummodelsurfaces;i++) { - s = currentrenderentity->model->modelsortedsurfaces[i]; - if (s->visframe == r_framecount && s->lightmaptexture != NULL) + surf = currentrenderentity->model->modelsortedsurfaces[i]; + if (surf->visframe == r_framecount && surf->lightmaptexture != NULL) { - if (s->cached_dlight - || s->cached_ambient != r_ambient.value - || s->cached_lightscalebit != lightscalebit) - R_BuildLightMap(s, false); // base lighting changed + if (surf->cached_dlight + || surf->cached_ambient != r_ambient.value + || surf->cached_lightscalebit != lightscalebit) + R_BuildLightMap(surf, false); // base lighting changed else if (r_dynamic.integer) { - if (s->styles[0] != 255 && (d_lightstylevalue[s->styles[0]] != s->cached_light[0] - || (s->styles[1] != 255 && (d_lightstylevalue[s->styles[1]] != s->cached_light[1] - || (s->styles[2] != 255 && (d_lightstylevalue[s->styles[2]] != s->cached_light[2] - || (s->styles[3] != 255 && (d_lightstylevalue[s->styles[3]] != s->cached_light[3])))))))) - //if (s->cached_light[0] != d_lightstylevalue[s->styles[0]] - // || s->cached_light[1] != d_lightstylevalue[s->styles[1]] - // || s->cached_light[2] != d_lightstylevalue[s->styles[2]] - // || s->cached_light[3] != d_lightstylevalue[s->styles[3]]) - R_BuildLightMap(s, false); // base lighting changed - else if (s->dlightframe == r_framecount && r_dlightmap.integer) - R_BuildLightMap(s, true); // only dlights + if (surf->styles[0] != 255 && (d_lightstylevalue[surf->styles[0]] != surf->cached_light[0] + || (surf->styles[1] != 255 && (d_lightstylevalue[surf->styles[1]] != surf->cached_light[1] + || (surf->styles[2] != 255 && (d_lightstylevalue[surf->styles[2]] != surf->cached_light[2] + || (surf->styles[3] != 255 && (d_lightstylevalue[surf->styles[3]] != surf->cached_light[3])))))))) + R_BuildLightMap(surf, false); // base lighting changed + else if (surf->dlightframe == r_framecount && r_dlightmap.integer) + R_BuildLightMap(surf, true); // only dlights } } } @@ -2022,5 +2164,5 @@ void R_DrawBrushModelNormal (void) if (!skyrendermasked) R_DrawSurfaces(SHADERSTAGE_SKY); R_DrawSurfaces(SHADERSTAGE_NORMAL); - R_DrawSurfaces(SHADERSTAGE_FOG); } +