From ae9ed9b6acd2b4f0052ae163904b13506a1199a0 Mon Sep 17 00:00:00 2001 From: lordhavoc Date: Wed, 15 May 2002 08:56:45 +0000 Subject: [PATCH] muzzleflash fades out changed .lights file format very slightly to add customizable distance bias (softness) now splits surface meshs bigger than 1000 tris into multiple smaller ones automatically while loading git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@1841 d7cf8633-e32d-0410-b094-e92efae38249 --- cl_main.c | 28 +- client.h | 107 ++++-- gl_rsurf.c | 953 ++++++++++++++++++++++++++------------------------ model_brush.c | 143 +++++--- model_brush.h | 5 +- r_light.c | 4 +- 6 files changed, 696 insertions(+), 544 deletions(-) diff --git a/cl_main.c b/cl_main.c index 11155759..b387596d 100644 --- a/cl_main.c +++ b/cl_main.c @@ -476,18 +476,7 @@ static void CL_RelinkNetworkEntities() if (effects & EF_BRIGHTFIELD) CL_EntityParticles (ent); if (effects & EF_MUZZLEFLASH) - { - vec3_t v, v2; - - AngleVectors (ent->render.angles, v, NULL, NULL); - - v2[0] = v[0] * 18 + neworg[0]; - v2[1] = v[1] * 18 + neworg[1]; - v2[2] = v[2] * 18 + neworg[2] + 16; - TraceLine(neworg, v2, v, NULL, 0, true); - - CL_AllocDlight (NULL, v, 100, 1, 1, 1, 0, 0); - } + ent->persistent.muzzleflash = 100.0f; if (effects & EF_DIMLIGHT) { dlightcolor[0] += 200.0f; @@ -591,6 +580,21 @@ static void CL_RelinkNetworkEntities() } } + if (ent->persistent.muzzleflash > 0) + { + vec3_t v, v2; + + AngleVectors (ent->render.angles, v, NULL, NULL); + + v2[0] = v[0] * 18 + neworg[0]; + v2[1] = v[1] * 18 + neworg[1]; + v2[2] = v[2] * 18 + neworg[2] + 16; + TraceLine(neworg, v2, v, NULL, 0, true); + + CL_AllocDlight (NULL, v, ent->persistent.muzzleflash, 1, 1, 1, 0, 0); + ent->persistent.muzzleflash -= cl.frametime * 1000; + } + // LordHavoc: if the model has no flags, don't check each if (ent->render.model && ent->render.model->flags) { diff --git a/client.h b/client.h index 9430e3a4..a2fccefb 100644 --- a/client.h +++ b/client.h @@ -29,57 +29,96 @@ frameblend_t; // LordHavoc: nothing in this structure is persistant, it may be overwritten by the client every frame, for persistant data use entity_lerp_t. typedef struct entity_render_s { - vec3_t origin; // location - vec3_t angles; // orientation - float alpha; // opacity (alpha) of the model - float scale; // size the model is shown - - model_t *model; // NULL = no model - int frame; // current uninterpolated animation frame (for things which do not use interpolation) - int colormap; // entity shirt and pants colors - int effects; // light, particles, etc - int skinnum; // for Alias models - int flags; // render flags + // location + vec3_t origin; + // orientation + vec3_t angles; + // opacity (alpha) of the model + float alpha; + // size the model is shown + float scale; + + // NULL = no model + model_t *model; + // current uninterpolated animation frame (for things which do not use interpolation) + int frame; + // entity shirt and pants colors + int colormap; + // light, particles, etc + int effects; + // for Alias models + int skinnum; + // render flags + int flags; // these are copied from the persistent data - int frame1; // frame that the model is interpolating from - int frame2; // frame that the model is interpolating to - double framelerp; // interpolation factor, usually computed from frame2time - double frame1time; // time frame1 began playing (for framegroup animations) - double frame2time; // time frame2 began playing (for framegroup animations) + + // frame that the model is interpolating from + int frame1; + // frame that the model is interpolating to + int frame2; + // interpolation factor, usually computed from frame2time + double framelerp; + // time frame1 began playing (for framegroup animations) + double frame1time; + // time frame2 began playing (for framegroup animations) + double frame2time; // calculated by the renderer (but not persistent) - int visframe; // if visframe == r_framecount, it is visible - vec3_t mins, maxs; // calculated during R_AddModelEntities - frameblend_t frameblend[4]; // 4 frame numbers (-1 if not used) and their blending scalers (0-1), if interpolation is not desired, use frame instead + + // if visframe == r_framecount, it is visible + int visframe; + // calculated during R_AddModelEntities + vec3_t mins, maxs; + // 4 frame numbers (-1 if not used) and their blending scalers (0-1), if interpolation is not desired, use frame instead + frameblend_t frameblend[4]; } entity_render_t; typedef struct entity_persistent_s { // particles - vec3_t trail_origin; // trail rendering - float trail_time; // trail rendering + + // trail rendering + vec3_t trail_origin; + float trail_time; + + // effects + + // muzzleflash fading + float muzzleflash; // interpolated animation - int modelindex; // lerp resets when model changes - int frame1; // frame that the model is interpolating from - int frame2; // frame that the model is interpolating to - double framelerp; // interpolation factor, usually computed from frame2time - double frame1time; // time frame1 began playing (for framegroup animations) - double frame2time; // time frame2 began playing (for framegroup animations) + + // lerp resets when model changes + int modelindex; + // frame that the model is interpolating from + int frame1; + // frame that the model is interpolating to + int frame2; + // interpolation factor, usually computed from frame2time + double framelerp; + // time frame1 began playing (for framegroup animations) + double frame1time; + // time frame2 began playing (for framegroup animations) + double frame2time; } entity_persistent_t; typedef struct entity_s { - entity_state_t state_baseline; // baseline state (default values) - entity_state_t state_previous; // previous state (interpolating from this) - entity_state_t state_current; // current state (interpolating to this) - - entity_persistent_t persistent; // used for regenerating parts of render - - entity_render_t render; // the only data the renderer should know about + // baseline state (default values) + entity_state_t state_baseline; + // previous state (interpolating from this) + entity_state_t state_previous; + // current state (interpolating to this) + entity_state_t state_current; + + // used for regenerating parts of render + entity_persistent_t persistent; + + // the only data the renderer should know about + entity_render_t render; } entity_t; diff --git a/gl_rsurf.c b/gl_rsurf.c index 76493932..edfe4cdb 100644 --- a/gl_rsurf.c +++ b/gl_rsurf.c @@ -503,6 +503,7 @@ static void RSurfShader_Sky(msurface_t *firstsurf) float number, length, dir[3], speedscale; surfvertex_t *v; surfvert_t *sv; + surfmesh_t *mesh; rmeshinfo_t m; // LordHavoc: HalfLife maps have freaky skypolys... @@ -524,26 +525,29 @@ static void RSurfShader_Sky(msurface_t *firstsurf) m.blendfunc1 = GL_ZERO; m.blendfunc2 = GL_ONE; m.depthwrite = true; - m.numtriangles = surf->mesh.numtriangles; - m.numverts = surf->mesh.numverts; - m.index = surf->mesh.index; - //m.cr = 0; - //m.cg = 0; - //m.cb = 0; - //m.ca = 0; - if (softwaretransform_complexity) - { - m.vertex = &svert[0].v[0]; - m.vertexstep = sizeof(surfvert_t); - for (i = 0, sv = svert, v = surf->mesh.vertex;i < m.numverts;i++, sv++, v++) - softwaretransform(v->v, sv->v); - } - else + for (mesh = surf->mesh;mesh;mesh = mesh->chain) { - m.vertex = &surf->mesh.vertex[0].v[0]; - m.vertexstep = sizeof(surfvertex_t); + m.numtriangles = mesh->numtriangles; + m.numverts = mesh->numverts; + m.index = mesh->index; + //m.cr = 0; + //m.cg = 0; + //m.cb = 0; + //m.ca = 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[0].v[0]; + m.vertexstep = sizeof(surfvertex_t); + } + R_Mesh_Draw(&m); } - R_Mesh_Draw(&m); } } else if (skyrenderglquake) @@ -554,9 +558,6 @@ static void RSurfShader_Sky(msurface_t *firstsurf) m.transparent = false; m.blendfunc1 = GL_ONE; m.blendfunc2 = GL_ZERO; - m.numtriangles = surf->mesh.numtriangles; - m.numverts = surf->mesh.numverts; - m.index = surf->mesh.index; m.vertex = &svert[0].v[0]; m.vertexstep = sizeof(surfvert_t); m.cr = 1; @@ -568,25 +569,31 @@ static void RSurfShader_Sky(msurface_t *firstsurf) m.texcoordstep[0] = sizeof(surfvert_t); speedscale = cl.time * (8.0/128.0); speedscale -= (int)speedscale; - for (i = 0, sv = svert, v = surf->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 - *((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; + 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 @@ -598,26 +605,29 @@ static void RSurfShader_Sky(msurface_t *firstsurf) m.transparent = false; m.blendfunc1 = GL_ONE; m.blendfunc2 = GL_ZERO; - m.numtriangles = surf->mesh.numtriangles; - m.numverts = surf->mesh.numverts; - m.index = surf->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 = surf->mesh.vertex;i < m.numverts;i++, sv++, v++) - softwaretransform(v->v, sv->v); - } - else + for (mesh = surf->mesh;mesh;mesh = mesh->chain) { - m.vertex = &surf->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); } } if (skyrenderglquake) @@ -628,9 +638,6 @@ static void RSurfShader_Sky(msurface_t *firstsurf) m.transparent = false; m.blendfunc1 = GL_SRC_ALPHA; m.blendfunc2 = GL_ONE_MINUS_SRC_ALPHA; - m.numtriangles = surf->mesh.numtriangles; - m.numverts = surf->mesh.numverts; - m.index = surf->mesh.index; m.vertex = &svert[0].v[0]; m.vertexstep = sizeof(surfvert_t); m.cr = 1; @@ -642,25 +649,31 @@ static void RSurfShader_Sky(msurface_t *firstsurf) m.texcoordstep[0] = sizeof(surfvert_t); speedscale = cl.time * (16.0/128.0); speedscale -= (int)speedscale; - for (i = 0, sv = svert, v = surf->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 - *((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; + 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); } } } @@ -698,11 +711,12 @@ static int RSurf_Light(int *dlightbits, int numverts) 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; + 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)); @@ -718,9 +732,6 @@ static void RSurfShader_Water_Pass_Base(msurface_t *surf) m.blendfunc1 = GL_ONE; m.blendfunc2 = GL_ZERO; } - m.numtriangles = surf->mesh.numtriangles; - m.numverts = surf->mesh.numverts; - m.index = surf->mesh.index; m.vertex = &svert[0].v[0]; m.vertexstep = sizeof(surfvert_t); m.color = &svert[0].c[0]; @@ -728,60 +739,64 @@ static void RSurfShader_Water_Pass_Base(msurface_t *surf) 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 = surf->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 (surf->flags & SURF_DRAWFULLBRIGHT) - { - sv->c[0] = 1; - sv->c[1] = 1; - sv->c[2] = 1; - sv->c[3] = alpha; - } - else + 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] = 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 (surf->dlightframe == r_framecount && !(surf->flags & SURF_DRAWFULLBRIGHT)) - RSurf_Light(surf->dlightbits, m.numverts); - if (fogenabled && (surf->flags & SURF_DRAWNOALPHA)) - { - 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 *surf) { - int i; - float diff[3], alpha, ifog; - surfvertex_t *v; - surfvert_t *sv; - rmeshinfo_t m; + 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 || surf->currenttexture->fogtexture != NULL; m.blendfunc1 = GL_SRC_ALPHA; m.blendfunc2 = GL_ONE; - m.numtriangles = surf->mesh.numtriangles; - m.numverts = surf->mesh.numverts; - m.index = surf->mesh.index; m.vertex = &svert[0].v[0]; m.vertexstep = sizeof(surfvert_t); m.cr = 1; @@ -791,56 +806,60 @@ static void RSurfShader_Water_Pass_Glow(msurface_t *surf) 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 = surf->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 = surf->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 *surf) { - int i; - float alpha; - surfvertex_t *v; - surfvert_t *sv; - rmeshinfo_t m; - vec3_t diff; + 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 || surf->currenttexture->fogtexture != NULL; m.blendfunc1 = GL_SRC_ALPHA; m.blendfunc2 = GL_ONE; - m.numtriangles = surf->mesh.numtriangles; - m.numverts = surf->mesh.numverts; - m.index = surf->mesh.index; m.vertex = &svert[0].v[0]; m.vertexstep = sizeof(surfvert_t); m.color = &svert[0].c[0]; @@ -849,23 +868,29 @@ static void RSurfShader_Water_Pass_Fog(msurface_t *surf) m.texcoords[0] = &svert[0].st[0]; m.texcoordstep[0] = sizeof(surfvert_t); - for (i = 0, sv = svert, v = surf->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 void RSurfShader_Water(msurface_t *firstsurf) @@ -884,11 +909,12 @@ static void RSurfShader_Water(msurface_t *firstsurf) 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) @@ -909,173 +935,184 @@ static void RSurfShader_Wall_Pass_BaseMTex(msurface_t *surf) m.blendfunc1 = GL_ONE; m.blendfunc2 = GL_ZERO; } - m.numtriangles = surf->mesh.numtriangles; - m.numverts = surf->mesh.numverts; - m.index = surf->mesh.index; 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.texcoords[0] = &surf->mesh.vertex->st[0]; - m.texcoords[1] = &surf->mesh.vertex->uv[0]; 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 = surf->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 = &surf->mesh.vertex->v[0]; - m.vertexstep = sizeof(surfvertex_t); - for (i = 0, sv = svert, v = surf->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 = surf->mesh.vertex;i < m.numverts;i++, sv++, v++) - softwaretransform(v->v, sv->v); - } else { - m.vertex = &surf->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 *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 = surf->mesh.numtriangles; - m.numverts = surf->mesh.numverts; - m.index = surf->mesh.index; m.cr = m.cg = m.cb = (float) (1 << v_overbrightbits.integer); m.ca = 1; m.tex[0] = R_GetTexture(surf->currenttexture->texture); - m.texcoords[0] = &surf->mesh.vertex->st[0]; 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 = surf->mesh.vertex;i < m.numverts;i++, sv++, v++) - softwaretransform(v->v, sv->v); - } - else + for (mesh = surf->mesh;mesh;mesh = mesh->chain) { - m.vertex = &surf->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 *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 = surf->mesh.numtriangles; - m.numverts = surf->mesh.numverts; - m.index = surf->mesh.index; m.cr = m.cg = m.cb = (float) (1 << v_overbrightbits.integer); m.ca = 1; m.tex[0] = R_GetTexture(surf->lightmaptexture); - m.texcoords[0] = &surf->mesh.vertex->uv[0]; 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 = surf->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 = &surf->mesh.vertex->v[0]; - m.vertexstep = sizeof(surfvertex_t); - for (i = 0, sv = svert, v = surf->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 = surf->mesh.vertex;i < m.numverts;i++, sv++, v++) - softwaretransform(v->v, sv->v); - } else { - m.vertex = &surf->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 *surf) @@ -1084,6 +1121,7 @@ static void RSurfShader_Wall_Pass_BaseVertex(msurface_t *surf) float c[3], base[3], scale, diff[3], ifog; surfvertex_t *v; surfvert_t *sv; + surfmesh_t *mesh; rmeshinfo_t m; qbyte *lm; @@ -1110,72 +1148,76 @@ static void RSurfShader_Wall_Pass_BaseVertex(msurface_t *surf) m.blendfunc1 = GL_ONE; m.blendfunc2 = GL_ZERO; } - m.numtriangles = surf->mesh.numtriangles; - m.numverts = surf->mesh.numverts; - m.index = surf->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(surf->currenttexture->texture); - m.texcoords[0] = &surf->mesh.vertex->st[0]; m.texcoordstep[0] = sizeof(surfvertex_t); - for (i = 0, sv = svert, v = surf->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 (surf->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 = surf->samples + v->lightmapoffset; - scale = d_lightstylevalue[surf->styles[0]] * (1.0f / 32768.0f); - VectorMA(c, scale, lm, c); - if (surf->styles[1] != 255) + softwaretransform(v->v, sv->v); + VectorCopy(base, c); + if (surf->styles[0] != 255) { - lm += size3; - scale = d_lightstylevalue[surf->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 (surf->styles[2] != 255) + if (surf->styles[1] != 255) { lm += size3; - scale = d_lightstylevalue[surf->styles[2]] * (1.0f / 32768.0f); + scale = d_lightstylevalue[surf->styles[1]] * (1.0f / 32768.0f); VectorMA(c, scale, lm, c); - if (surf->styles[3] != 255) + if (surf->styles[2] != 255) { lm += size3; - scale = d_lightstylevalue[surf->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 (surf->dlightframe == r_framecount) - RSurf_Light(surf->dlightbits, m.numverts); - if (fogenabled) - { - for (i = 0, sv = svert, v = surf->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 *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) @@ -1196,46 +1238,50 @@ static void RSurfShader_Wall_Pass_BaseFullbright(msurface_t *surf) m.blendfunc1 = GL_ONE; m.blendfunc2 = GL_ZERO; } - m.numtriangles = surf->mesh.numtriangles; - m.numverts = surf->mesh.numverts; - m.index = surf->mesh.index; m.vertex = &svert[0].v[0]; m.vertexstep = sizeof(surfvert_t); m.tex[0] = R_GetTexture(surf->currenttexture->texture); - m.texcoords[0] = &surf->mesh.vertex->st[0]; 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 = surf->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 = surf->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 *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) @@ -1246,48 +1292,52 @@ static void RSurfShader_Wall_Pass_Light(msurface_t *surf) m.transparent = false; m.blendfunc1 = GL_SRC_ALPHA; m.blendfunc2 = GL_ONE; - m.numtriangles = surf->mesh.numtriangles; - m.numverts = surf->mesh.numverts; - m.index = surf->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(surf->currenttexture->texture); - m.texcoords[0] = &surf->mesh.vertex->st[0]; m.texcoordstep[0] = sizeof(surfvertex_t); - for (i = 0, sv = svert, v = surf->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(surf->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 *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) @@ -1298,75 +1348,79 @@ static void RSurfShader_Wall_Pass_Glow(msurface_t *surf) m.transparent = false; m.blendfunc1 = GL_SRC_ALPHA; m.blendfunc2 = GL_ONE; - m.numtriangles = surf->mesh.numtriangles; - m.numverts = surf->mesh.numverts; - m.index = surf->mesh.index; m.cr = 1; m.cg = 1; m.cb = 1; m.ca = currentrenderentity->alpha; m.tex[0] = R_GetTexture(surf->currenttexture->glowtexture); - m.texcoords[0] = &surf->mesh.vertex->st[0]; 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 = surf->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 = &surf->mesh.vertex->v[0]; - m.vertexstep = sizeof(surfvertex_t); - for (i = 0, sv = svert, v = surf->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 = surf->mesh.vertex;i < m.numverts;i++, sv++, v++) - softwaretransform(v->v, sv->v); - } else { - m.vertex = &surf->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 *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) @@ -1377,42 +1431,45 @@ static void RSurfShader_Wall_Pass_Fog(msurface_t *surf) m.transparent = false; m.blendfunc1 = GL_SRC_ALPHA; m.blendfunc2 = GL_ONE; - m.numtriangles = surf->mesh.numtriangles; - m.numverts = surf->mesh.numverts; - m.index = surf->mesh.index; m.color = &svert[0].c[0]; m.colorstep = sizeof(surfvert_t); m.tex[0] = R_GetTexture(surf->currenttexture->fogtexture); - m.texcoords[0] = &surf->mesh.vertex->st[0]; 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 = surf->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 = &surf->mesh.vertex->v[0]; - m.vertexstep = sizeof(surfvertex_t); - for (i = 0, sv = svert, v = surf->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 void RSurfShader_Wall_Fullbright(msurface_t *firstsurf) diff --git a/model_brush.c b/model_brush.c index 0c87d8b8..5aecaa77 100644 --- a/model_brush.c +++ b/model_brush.c @@ -586,9 +586,9 @@ void Mod_LoadLightList(void) } e = loadmodel->lights + n; *s = 0; - a = sscanf(t, "%f %f %f %f %f %f %f %f %f %f %f %f %d", &e->origin[0], &e->origin[1], &e->origin[2], &e->falloff, &e->light[0], &e->light[1], &e->light[2], &e->subtract, &e->spotdir[0], &e->spotdir[1], &e->spotdir[2], &e->spotcone, &e->style); + a = sscanf(t, "%f %f %f %f %f %f %f %f %f %f %f %f %f %d", &e->origin[0], &e->origin[1], &e->origin[2], &e->falloff, &e->light[0], &e->light[1], &e->light[2], &e->subtract, &e->spotdir[0], &e->spotdir[1], &e->spotdir[2], &e->spotcone, &e->distbias, &e->style); *s = '\n'; - if (a != 13) + if (a != 14) { Mem_Free(lightsstring); Host_Error("invalid lights file, found %d parameters on line %i, should be 13 parameters (origin[0] origin[1] origin[2] falloff light[0] light[1] light[2] subtract spotdir[0] spotdir[1] spotdir[2] spotcone style)\n", a, n + 1); @@ -1028,14 +1028,14 @@ void Mod_GenerateWarpMesh (msurface_t *surf) subdivpolytriangles = 0; subdivpolyverts = 0; SubdividePolygon (surf->poly_numverts, surf->poly_verts); + if (subdivpolytriangles < 1) + Host_Error("Mod_GenerateWarpMesh: no triangles?\n"); - mesh = &surf->mesh; + surf->mesh = mesh = Mem_Alloc(loadmodel->mempool, sizeof(surfmesh_t) + subdivpolytriangles * sizeof(int[3]) + subdivpolyverts * sizeof(surfvertex_t)); mesh->numverts = subdivpolyverts; mesh->numtriangles = subdivpolytriangles; - if (mesh->numtriangles < 1) - Host_Error("Mod_GenerateWarpMesh: no triangles?\n"); - mesh->index = Mem_Alloc(loadmodel->mempool, mesh->numtriangles * sizeof(int[3]) + mesh->numverts * sizeof(surfvertex_t)); - mesh->vertex = (surfvertex_t *)((qbyte *) mesh->index + mesh->numtriangles * sizeof(int[3])); + mesh->vertex = (surfvertex_t *)(mesh + 1); + mesh->index = (int *)(mesh->vertex + mesh->numverts); memset(mesh->vertex, 0, mesh->numverts * sizeof(surfvertex_t)); for (i = 0;i < mesh->numtriangles;i++) @@ -1069,11 +1069,11 @@ void Mod_GenerateVertexLitMesh (msurface_t *surf) surf->lightmaptexturestride = 0; surf->lightmaptexture = NULL; - mesh = &surf->mesh; + surf->mesh = mesh = Mem_Alloc(loadmodel->mempool, sizeof(surfmesh_t) + (surf->poly_numverts - 2) * sizeof(int[3]) + surf->poly_numverts * sizeof(surfvertex_t)); mesh->numverts = surf->poly_numverts; mesh->numtriangles = surf->poly_numverts - 2; - mesh->index = Mem_Alloc(loadmodel->mempool, mesh->numtriangles * sizeof(int[3]) + mesh->numverts * sizeof(surfvertex_t)); - mesh->vertex = (surfvertex_t *)((qbyte *) mesh->index + mesh->numtriangles * sizeof(int[3])); + mesh->vertex = (surfvertex_t *)(mesh + 1); + mesh->index = (int *)(mesh->vertex + mesh->numverts); memset(mesh->vertex, 0, mesh->numverts * sizeof(surfvertex_t)); index = mesh->index; @@ -1136,11 +1136,11 @@ void Mod_GenerateLightmappedMesh (msurface_t *surf) xscale = (xscale - xbase) * 16.0 / ((surf->extents[0] & ~15) + 16); yscale = (yscale - ybase) * 16.0 / ((surf->extents[1] & ~15) + 16); - mesh = &surf->mesh; + surf->mesh = mesh = Mem_Alloc(loadmodel->mempool, sizeof(surfmesh_t) + (surf->poly_numverts - 2) * sizeof(int[3]) + surf->poly_numverts * sizeof(surfvertex_t)); mesh->numverts = surf->poly_numverts; mesh->numtriangles = surf->poly_numverts - 2; - mesh->index = Mem_Alloc(loadmodel->mempool, mesh->numtriangles * sizeof(int[3]) + mesh->numverts * sizeof(surfvertex_t)); - mesh->vertex = (surfvertex_t *)((qbyte *) mesh->index + mesh->numtriangles * sizeof(int[3])); + mesh->vertex = (surfvertex_t *)(mesh + 1); + mesh->index = (int *)(mesh->vertex + mesh->numverts); memset(mesh->vertex, 0, mesh->numverts * sizeof(surfvertex_t)); index = mesh->index; @@ -1187,11 +1187,11 @@ void Mod_GenerateVertexMesh (msurface_t *surf) surf->lightmaptexturestride = 0; surf->lightmaptexture = NULL; - mesh = &surf->mesh; + surf->mesh = mesh = Mem_Alloc(loadmodel->mempool, sizeof(surfmesh_t) + (surf->poly_numverts - 2) * sizeof(int[3]) + surf->poly_numverts * sizeof(surfvertex_t)); mesh->numverts = surf->poly_numverts; mesh->numtriangles = surf->poly_numverts - 2; - mesh->index = Mem_Alloc(loadmodel->mempool, mesh->numtriangles * sizeof(int[3]) + mesh->numverts * sizeof(surfvertex_t)); - mesh->vertex = (surfvertex_t *)((qbyte *) mesh->index + mesh->numtriangles * sizeof(int[3])); + mesh->vertex = (surfvertex_t *)(mesh + 1); + mesh->index = (int *)(mesh->vertex + mesh->numverts); memset(mesh->vertex, 0, mesh->numverts * sizeof(surfvertex_t)); index = mesh->index; @@ -1232,6 +1232,55 @@ void Mod_GenerateSurfacePolygon (msurface_t *surf) } } +static void Mod_SplitSurfMeshIfTooBig(msurface_t *s) +{ + int j, base, tricount, newvertexcount, *index, *vertexremap; + surfmesh_t *newmesh, *oldmesh, *firstmesh; + if (s->mesh->numtriangles > 1000) + { + vertexremap = Mem_Alloc(tempmempool, s->mesh->numverts * sizeof(int)); + memset(vertexremap, -1, s->mesh->numverts * sizeof(int)); + base = 0; + oldmesh = NULL; + firstmesh = NULL; + newmesh = NULL; + while (base < s->mesh->numtriangles) + { + tricount = s->mesh->numtriangles - base; + if (tricount > 1000) + tricount = 1000; + index = s->mesh->index + base * 3; + base += tricount; + + newvertexcount = 0; + for (j = 0;j < tricount * 3;j++) + if (vertexremap[index[j]] < 0) + vertexremap[index[j]] = newvertexcount++; + + newmesh = Mem_Alloc(loadmodel->mempool, sizeof(surfmesh_t) + newvertexcount * sizeof(surfvertex_t) + tricount * sizeof(int[3])); + newmesh->chain = NULL; + newmesh->numverts = newvertexcount; + newmesh->numtriangles = tricount; + newmesh->vertex = (surfvertex_t *)(newmesh + 1); + newmesh->index = (int *)(newmesh->vertex + newvertexcount); + for (j = 0;j < tricount * 3;j++) + { + newmesh->index[j] = vertexremap[index[j]]; + // yes this copies the same vertex multiple times in many cases... but that's ok... + memcpy(&newmesh->vertex[newmesh->index[j]], &s->mesh->vertex[index[j]], sizeof(surfvertex_t)); + } + if (oldmesh) + oldmesh->chain = newmesh; + else + firstmesh = newmesh; + oldmesh = newmesh; + } + Mem_Free(vertexremap); + Mem_Free(s->mesh); + s->mesh = firstmesh; + } +} + /* ================= Mod_LoadFaces @@ -1299,10 +1348,8 @@ static void Mod_LoadFaces (lump_t *l) out->shader = &Cshader_sky; out->samples = NULL; Mod_GenerateWarpMesh (out); - continue; } - - if (out->texinfo->texture->flags & SURF_DRAWTURB) + else if (out->texinfo->texture->flags & SURF_DRAWTURB) { out->shader = &Cshader_water; /* @@ -1314,43 +1361,45 @@ static void Mod_LoadFaces (lump_t *l) */ out->samples = NULL; Mod_GenerateWarpMesh (out); - continue; - } - - if (!R_TextureHasAlpha(out->texinfo->texture->texture)) - out->flags |= SURF_CLIPSOLID; - if (out->texinfo->flags & TEX_SPECIAL) - { - // qbsp couldn't find the texture for this surface, but it was either turb or sky... assume turb - out->shader = &Cshader_water; - out->shader = &Cshader_water; - out->samples = NULL; - Mod_GenerateWarpMesh (out); - } - else if ((out->extents[0]+1) > (256*16) || (out->extents[1]+1) > (256*16)) - { - Con_Printf ("Bad surface extents, converting to fullbright polygon"); - out->shader = &Cshader_wall_fullbright; - out->samples = NULL; - Mod_GenerateVertexMesh(out); } else { - // stainmap for permanent marks on walls - out->stainsamples = Mem_Alloc(loadmodel->mempool, ssize * tsize * 3); - // clear to white - memset(out->stainsamples, 255, ssize * tsize * 3); - if (out->extents[0] < r_vertexsurfacesthreshold.integer && out->extents[1] < r_vertexsurfacesthreshold.integer) + if (!R_TextureHasAlpha(out->texinfo->texture->texture)) + out->flags |= SURF_CLIPSOLID; + if (out->texinfo->flags & TEX_SPECIAL) + { + // qbsp couldn't find the texture for this surface, but it was either turb or sky... assume turb + out->shader = &Cshader_water; + out->shader = &Cshader_water; + out->samples = NULL; + Mod_GenerateWarpMesh (out); + } + else if ((out->extents[0]+1) > (256*16) || (out->extents[1]+1) > (256*16)) { - out->shader = &Cshader_wall_vertex; - Mod_GenerateVertexLitMesh(out); + Con_Printf ("Bad surface extents, converting to fullbright polygon"); + out->shader = &Cshader_wall_fullbright; + out->samples = NULL; + Mod_GenerateVertexMesh(out); } else { - out->shader = &Cshader_wall_lightmap; - Mod_GenerateLightmappedMesh(out); + // stainmap for permanent marks on walls + out->stainsamples = Mem_Alloc(loadmodel->mempool, ssize * tsize * 3); + // clear to white + memset(out->stainsamples, 255, ssize * tsize * 3); + if (out->extents[0] < r_vertexsurfacesthreshold.integer && out->extents[1] < r_vertexsurfacesthreshold.integer) + { + out->shader = &Cshader_wall_vertex; + Mod_GenerateVertexLitMesh(out); + } + else + { + out->shader = &Cshader_wall_lightmap; + Mod_GenerateLightmappedMesh(out); + } } } + Mod_SplitSurfMeshIfTooBig(out); } } diff --git a/model_brush.h b/model_brush.h index 1ab081b0..40ea1a64 100644 --- a/model_brush.h +++ b/model_brush.h @@ -111,6 +111,8 @@ surfvertex_t; // LordHavoc: replaces glpoly, triangle mesh typedef struct surfmesh_s { + // can be multiple meshs per surface + struct surfmesh_s *chain; int numverts; int numtriangles; surfvertex_t *vertex; @@ -153,7 +155,7 @@ typedef struct msurface_s // the stride when building lightmaps to comply with fragment update int lightmaptexturestride; // mesh for rendering - surfmesh_t mesh; + surfmesh_t *mesh; // these are just 3D points defining the outline of the polygon, // no texcoord info (that can be generated from these) @@ -285,6 +287,7 @@ typedef struct mlight_s float subtract; vec3_t spotdir; float spotcone; // cosine of spotlight cone angle (or 0 if not a spotlight) + float distbias; int style; int numleafs; // used only for loading calculations, number of leafs this shines on } diff --git a/r_light.c b/r_light.c index 2e99dfff..6860122a 100644 --- a/r_light.c +++ b/r_light.c @@ -755,7 +755,7 @@ void R_CompleteLightPoint (vec3_t color, vec3_t p, int dynamic, mleaf_t *leaf) if (d_lightstylevalue[sl->style] > 0) { VectorSubtract (p, sl->origin, dist); - f = DotProduct(dist, dist) + 65536.0f; + f = DotProduct(dist, dist) + sl->distbias; f = (1.0f / f) - sl->subtract; if (f > 0) { @@ -897,7 +897,7 @@ void R_LightModel(int numverts, float colorr, float colorg, float colorb, int wo VectorScale(sl->light, f, nl->light); nl->cullradius2 = 99999999; nl->lightsubtract = sl->subtract; - nl->offset = 65536.0f; + nl->offset = sl->distbias; nl++; nearlights++; } -- 2.39.2