From 63b6ae30eb111258c230af6cf97f96f46ccc4c51 Mon Sep 17 00:00:00 2001 From: lordhavoc Date: Mon, 16 Oct 2000 20:48:26 +0000 Subject: [PATCH] yet another rewrite of the dlight engine, this time FAST new stuff: much higher quality (loose shadowing) gl_vertex cvar to try vertex lighting (warning: very obvious transpoly sorting problems) git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@53 d7cf8633-e32d-0410-b094-e92efae38249 --- gl_rmain.c | 16 +- gl_rsurf.c | 1065 ++++++++++++++++++------------------------------- model_brush.h | 6 +- r_light.c | 168 ++------ 4 files changed, 422 insertions(+), 833 deletions(-) diff --git a/gl_rmain.c b/gl_rmain.c index 806a7b1f..4e0c6e2e 100644 --- a/gl_rmain.c +++ b/gl_rmain.c @@ -1567,6 +1567,9 @@ r_refdef must be set before the first call ================ */ extern qboolean intimerefresh; +extern qboolean skyisvisible; +extern void R_Sky(); +extern void UploadLightmaps(); void R_RenderView (void) { // double currtime, temptime; @@ -1579,7 +1582,10 @@ void R_RenderView (void) lighthalf = gl_lightmode.value; FOG_framebegin(); + skypolyclear(); + wallpolyclear(); transpolyclear(); + skyisvisible = false; // if (r_speeds2.value) // { @@ -1598,13 +1604,19 @@ void R_RenderView (void) R_DrawWorld (); // adds static entities to the list if (!intimerefresh) S_ExtraUpdate (); // don't let sound get messed up if going slow - wallpolyclear(); R_DrawEntitiesOnList1 (); // BSP models - wallpolyrender(); + + skypolyrender(); // fogged sky polys, affects depth + if (skyname[0] && skyisvisible && !fogenabled) + R_Sky(); // does not affect depth, draws over the sky polys + R_DrawEntitiesOnList2 (); // other models // R_RenderDlights (); R_DrawViewModel (); R_DrawParticles (); + + UploadLightmaps(); + wallpolyrender(); transpolyrender(); FOG_frameend(); diff --git a/gl_rsurf.c b/gl_rsurf.c index e7b3c1b1..d07668f3 100644 --- a/gl_rsurf.c +++ b/gl_rsurf.c @@ -47,6 +47,7 @@ cvar_t gl_lightmaprgba = {"gl_lightmaprgba", "1"}; cvar_t gl_nosubimagefragments = {"gl_nosubimagefragments", "0"}; cvar_t gl_nosubimage = {"gl_nosubimage", "0"}; cvar_t r_ambient = {"r_ambient", "0"}; +cvar_t gl_vertex = {"gl_vertex", "0"}; //cvar_t gl_funnywalls = {"gl_funnywalls", "0"}; // LordHavoc: see BuildSurfaceDisplayList qboolean lightmaprgba, nosubimagefragments, nosubimage; @@ -68,6 +69,7 @@ void glrsurf_init() Cvar_RegisterVariable(&gl_nosubimage); Cvar_RegisterVariable(&r_ambient); // Cvar_RegisterVariable(&gl_funnywalls); + Cvar_RegisterVariable(&gl_vertex); // check if it's the glquake minigl driver if (strncasecmp(gl_vendor,"3Dfx",4)==0) if (!gl_arrays) @@ -343,470 +345,430 @@ void UploadLightmaps() } } -/* -================ -DrawTextureChains -================ -*/ -extern qboolean hlbsp; -extern void R_Sky(); -extern char skyname[]; -//extern qboolean SV_TestLine (hull_t *hull, int num, vec3_t p1, vec3_t p2); -void DrawTextureChains (void) +void R_SkySurf(msurface_t *s, qboolean transform) { -// int i, j, l; - int i, j; - msurface_t *s; - texture_t *t; - glpoly_t *p; - float *v, os = turbsin[(int)(realtime * TURBSCALE) & 255], ot = turbsin[(int)(realtime * TURBSCALE + 96.0) & 255]; -// vec3_t shadecolor; - - // first the sky - skypolyclear(); - for (j = 0;j < cl.worldmodel->numtextures;j++) + glpoly_t *p; + int i; + float *v; + for (p=s->polys ; p ; p=p->next) { - if (!cl.worldmodel->textures[j] || !(s = cl.worldmodel->textures[j]->texturechain)) - continue; - // LordHavoc: decide the render type only once, because the surface properties were determined by texture anyway - if (s->flags & SURF_DRAWSKY) + if (currentskypoly < MAX_SKYPOLYS && currentskyvert + p->numverts <= MAX_SKYVERTS) { - cl.worldmodel->textures[j]->texturechain = NULL; - t = R_TextureAnimation (cl.worldmodel->textures[j]); - skyisvisible = true; - if (!hlbsp) // LordHavoc: HalfLife maps have freaky skypolys... + skypoly[currentskypoly].firstvert = currentskyvert; + skypoly[currentskypoly++].verts = p->numverts; + if (transform) { - for (;s;s = s->texturechain) + for (i = 0,v = p->verts[0];i < p->numverts;i++, v += VERTEXSIZE) { - for (p=s->polys ; p ; p=p->next) - { - if (currentskypoly < MAX_SKYPOLYS && currentskyvert + p->numverts <= MAX_SKYVERTS) - { - skypoly[currentskypoly].firstvert = currentskyvert; - skypoly[currentskypoly++].verts = p->numverts; - for (i = 0,v = p->verts[0];i < p->numverts;i++, v += VERTEXSIZE) - { - skyvert[currentskyvert].v[0] = v[0]; - skyvert[currentskyvert].v[1] = v[1]; - skyvert[currentskyvert++].v[2] = v[2]; - } - } - } + softwaretransform(v, skyvert[currentskyvert].v); + currentskyvert++; + } + } + else + { + for (i = 0,v = p->verts[0];i < p->numverts;i++, v += VERTEXSIZE) + { + skyvert[currentskyvert].v[0] = v[0]; + skyvert[currentskyvert].v[1] = v[1]; + skyvert[currentskyvert++].v[2] = v[2]; } } } } - skypolyrender(); // fogged sky polys, affects depth - - if (skyname[0] && skyisvisible && !fogenabled) - R_Sky(); // does not affect depth, draws over the sky polys +} - // then walls - wallpolyclear(); - for (j = 0;j < cl.worldmodel->numtextures;j++) +void R_WaterSurf(msurface_t *s, texture_t *t, qboolean transform, int alpha) +{ + int i, a, b; + unsigned int c; + float cr, cg, cb, radius, radius2, f; + float os = turbsin[(int)(realtime * TURBSCALE) & 255], ot = turbsin[(int)(realtime * TURBSCALE + 96.0) & 255]; + glpoly_t *p; + float wvert[64*6], *wv, *v, *lightorigin; + dlight_t *light; + wv = wvert; + for (p = s->polys;p;p = p->next) { - if (!cl.worldmodel->textures[j] || !(s = cl.worldmodel->textures[j]->texturechain)) - continue; - // subdivided water surface warp - if (!(s->flags & SURF_DRAWTURB)) + for (i = 0, v = p->verts[0];i < p->numverts;i++, v += VERTEXSIZE) { - cl.worldmodel->textures[j]->texturechain = NULL; - t = R_TextureAnimation (cl.worldmodel->textures[j]); - for (;s;s = s->texturechain) + if (transform) + softwaretransform(v, wv); + else + VectorCopy(v, wv); + if (r_waterripple.value) + wv[2] += r_waterripple.value * turbsin[(int)((wv[0]*0.125f+realtime) * TURBSCALE) & 255] * turbsin[(int)((wv[1]*0.125f+realtime) * TURBSCALE) & 255] * (1.0f / 64.0f); + wv[3] = wv[4] = wv[5] = 128.0f; + wv += 6; + } + } + if (s->dlightframe == r_dlightframecount && r_dynamic.value) + { + for (a = 0;a < 8;a++) + { + if (c = s->dlightbits[a]) { - // check for lightmap modification - if (r_dynamic.value) - { - if (r_ambient.value != s->cached_ambient || lighthalf != s->cached_lighthalf - || (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])) - R_UpdateLightmap(s, s->lightmaptexturenum); - } - for (p = s->polys;p;p = p->next) + for (b = 0;c && b < 32;b++) { - if (currentwallpoly >= MAX_WALLPOLYS) - break; - v = &s->polys->verts[0][0]; - wallpoly[currentwallpoly].texnum = (unsigned short) t->gl_texturenum; - wallpoly[currentwallpoly].lighttexnum = (unsigned short) lightmap_textures + s->lightmaptexturenum; - wallpoly[currentwallpoly].glowtexnum = (unsigned short) t->gl_glowtexturenum; - wallpoly[currentwallpoly].firstvert = currentwallvert; - wallpoly[currentwallpoly].numverts = p->numverts; - if (wallpoly[currentwallpoly++].lit = s->dlightframe == r_dlightframecount && r_dynamic.value) + if (c & (1 << b)) { - for (i = 0;inumverts;i++, v += VERTEXSIZE) + c -= (1 << b); + light = &cl_dlights[a * 32 + b]; + lightorigin = light->origin; + cr = light->color[0]; + cg = light->color[1]; + cb = light->color[2]; + radius = light->radius*light->radius*16.0f; + radius2 = radius * 16.0f; + wv = wvert; + for (p = s->polys;p;p = p->next) { - /* - int dj; - shadecolor[0] = shadecolor[1] = shadecolor[2] = 0; - for (dj = 0;dj < (MAX_DLIGHTS >> 5);dj++) + for (i = 0;i < p->numverts;i++, wv += 6) { - if (s->dlightbits[dj]) + f = VectorDistance2(wv, lightorigin); + if (f < radius) { - int di; - for (di=0 ; di<32 ; di++) - { - if ((1 << (di&31)) & s->dlightbits[di>>5]) - { - vec3_t ddist; - dlight_t *dl; - float dr; - float df; - float dt; - dl = &cl_dlights[(dj<<5)+di]; - VectorSubtract(dl->origin, v, ddist); - df = DotProduct(ddist, ddist) + 65536.0f; - dr = dl->radius * dl->radius * 16.0f; - if (df < dr) - { - VectorNormalize(ddist); - dt = DotProduct(ddist, s->plane->normal); - if (s->flags & SURF_PLANEBACK) - dt = -dt; - if (dt > 0.0f) - { - dr *= (dt * 0.5f + 0.5f); - if (df < dr) - { - */ - /* - vec3_t v2, v3; - VectorSubtract(v, ddist, v3); // pull off surface - if (s->flags & SURF_PLANEBACK) - { - VectorSubtract(dl->origin, s->plane->normal, v2); - VectorSubtract(v3, s->plane->normal, v3); - } - else - { - VectorAdd(dl->origin, s->plane->normal, v2); - VectorAdd(v3, s->plane->normal, v3); - } - if (SV_TestLine(&cl.worldmodel->hulls[0], 0, v2, v3)) -// if (SV_TestLine(&cl.worldmodel->hulls[0], 0, dl->origin, v)) - { - */ - /* - float dbrightness = dr * 16.0f / df; - shadecolor[0] += dbrightness * dl->color[0]; - shadecolor[1] += dbrightness * dl->color[1]; - shadecolor[2] += dbrightness * dl->color[2]; - //} - } - } - } - } - } + f = radius2 / (f + 65536.0f); + wv[3] += cr * f; + wv[4] += cg * f; + wv[5] += cb * f; } } - //R_DynamicLightPoint(shadecolor, v, s->dlightbits); - if (lighthalf) - { - shadecolor[0] *= 0.5f; - shadecolor[1] *= 0.5f; - shadecolor[2] *= 0.5f; - } - wallvert[currentwallvert].r = (byte) (bound(0, (int) shadecolor[0], 255)); - wallvert[currentwallvert].g = (byte) (bound(0, (int) shadecolor[1], 255)); - wallvert[currentwallvert].b = (byte) (bound(0, (int) shadecolor[2], 255)); - */ - wallvert[currentwallvert].r = (byte) (bound(0, (int) v[9], 255)); - wallvert[currentwallvert].g = (byte) (bound(0, (int) v[10], 255)); - wallvert[currentwallvert].b = (byte) (bound(0, (int) v[11], 255)); - wallvert[currentwallvert].a = 255; - wallvert[currentwallvert].vert[0] = v[0]; - wallvert[currentwallvert].vert[1] = v[1]; - wallvert[currentwallvert].vert[2] = v[2]; - wallvert[currentwallvert].s = v[3]; - wallvert[currentwallvert].t = v[4]; - wallvert[currentwallvert].u = v[5]; - wallvert[currentwallvert++].v = v[6]; - } - } - else - { - for (i = 0;inumverts;i++, v += VERTEXSIZE) - { - wallvert[currentwallvert].vert[0] = v[0]; - wallvert[currentwallvert].vert[1] = v[1]; - wallvert[currentwallvert].vert[2] = v[2]; - wallvert[currentwallvert].s = v[3]; - wallvert[currentwallvert].t = v[4]; - wallvert[currentwallvert].u = v[5]; - wallvert[currentwallvert++].v = v[6]; } } + c >>= 1; + b++; } } } } - UploadLightmaps(); - wallpolyrender(); + wv = wvert; + // FIXME: make fog texture if water texture is transparent? + if (lighthalf) + { + for (p=s->polys ; p ; p=p->next) + { + transpolybegin(t->gl_texturenum, t->gl_glowtexturenum, 0, TPOLYTYPE_ALPHA); + for (i = 0,v = p->verts[0];i < p->numverts;i++, v += VERTEXSIZE, wv += 6) + transpolyvert(wv[0], wv[1], wv[2], (v[3] + os) * (1.0f/64.0f), (v[4] + ot) * (1.0f/64.0f), (int) wv[3] >> 1,(int) wv[4] >> 1,(int) wv[5] >> 1,alpha); + transpolyend(); + } + } + else + { + for (p=s->polys ; p ; p=p->next) + { + transpolybegin(t->gl_texturenum, t->gl_glowtexturenum, 0, TPOLYTYPE_ALPHA); + for (i = 0,v = p->verts[0];i < p->numverts;i++, v += VERTEXSIZE, wv += 6) + transpolyvert(wv[0], wv[1], wv[2], (v[3] + os) * (1.0f/64.0f), (v[4] + ot) * (1.0f/64.0f), (int) wv[3],(int) wv[4],(int) wv[5],alpha); + transpolyend(); + } + } +} - // then water (water gets diverted to transpoly list) - for (j = 0;j < cl.worldmodel->numtextures;j++) +void R_WallSurf(msurface_t *s, texture_t *t, qboolean transform) +{ + int i, a, b; + unsigned int c; + glpoly_t *p; + float wvert[64*6], *wv, *v, cr, cg, cb, radius, radius2, f, *lightorigin; + dlight_t *light; + // check for lightmap modification + if (r_dynamic.value) { - if (!cl.worldmodel->textures[j] || !(s = cl.worldmodel->textures[j]->texturechain)) - continue; - cl.worldmodel->textures[j]->texturechain = NULL; - t = R_TextureAnimation (cl.worldmodel->textures[j]); - // LordHavoc: decide the render type only once, because the surface properties were determined by texture anyway - // subdivided water surface warp - if (s->flags & SURF_DRAWTURB) + if (r_ambient.value != s->cached_ambient || lighthalf != s->cached_lighthalf + || (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])) + R_UpdateLightmap(s, s->lightmaptexturenum); + } + wv = wvert; + for (p = s->polys;p;p = p->next) + { + for (i = 0, v = p->verts[0];i < p->numverts;i++, v += VERTEXSIZE) { - int alpha = s->flags & SURF_DRAWNOALPHA ? 255 : r_wateralpha.value*255.0f; - // FIXME: make fog texture if water texture is transparent? - if (r_waterripple.value) - { - if (lighthalf) - { - for (;s;s = s->texturechain) - { - for (p=s->polys ; p ; p=p->next) - { - transpolybegin(s->texinfo->texture->gl_texturenum, s->texinfo->texture->gl_glowtexturenum, 0, TPOLYTYPE_ALPHA); - for (i = 0,v = p->verts[0];i < p->numverts;i++, v += VERTEXSIZE) - transpolyvert(v[0], v[1], v[2] + r_waterripple.value * turbsin[(int)((v[3]*0.125f+realtime) * TURBSCALE) & 255] * turbsin[(int)((v[4]*0.125f+realtime) * TURBSCALE) & 255] * (1.0f / 64.0f), (v[3] + os) * (1.0f/64.0f), (v[4] + ot) * (1.0f/64.0f), (int) (v[9]+128) >> 1,(int) (v[10]+128) >> 1,(int) (v[11]+128) >> 1,alpha); - transpolyend(); - } - } - } - else - { - for (;s;s = s->texturechain) - { - for (p=s->polys ; p ; p=p->next) - { - transpolybegin(s->texinfo->texture->gl_texturenum, s->texinfo->texture->gl_glowtexturenum, 0, TPOLYTYPE_ALPHA); - for (i = 0,v = p->verts[0];i < p->numverts;i++, v += VERTEXSIZE) - transpolyvert(v[0], v[1], v[2] + r_waterripple.value * turbsin[(int)((v[3]*0.125f+realtime) * TURBSCALE) & 255] * turbsin[(int)((v[4]*0.125f+realtime) * TURBSCALE) & 255] * (1.0f / 64.0f), (v[3] + os) * (1.0f/64.0f), (v[4] + ot) * (1.0f/64.0f), (int) (v[9]+128),(int) (v[10]+128),(int) (v[11]+128),alpha); - transpolyend(); - } - } - } - } + if (transform) + softwaretransform(v, wv); else + VectorCopy(v, wv); + wv[3] = wv[4] = wv[5] = 0.0f; + wv += 6; + } + } + if (s->dlightframe == r_dlightframecount && r_dynamic.value) + { + for (a = 0;a < 8;a++) + { + if (c = s->dlightbits[a]) { - if (lighthalf) - { - for (;s;s = s->texturechain) - { - for (p=s->polys ; p ; p=p->next) - { - transpolybegin(s->texinfo->texture->gl_texturenum, s->texinfo->texture->gl_glowtexturenum, 0, TPOLYTYPE_ALPHA); - for (i = 0,v = p->verts[0];i < p->numverts;i++, v += VERTEXSIZE) - transpolyvert(v[0], v[1], v[2], (v[3] + os) * (1.0f/64.0f), (v[4] + ot) * (1.0f/64.0f), (int) (v[9]+128) >> 1,(int) (v[10]+128) >> 1,(int) (v[11]+128) >> 1,alpha); - transpolyend(); - } - } - } - else - { - for (;s;s = s->texturechain) - { - for (p=s->polys ; p ; p=p->next) - { - transpolybegin(s->texinfo->texture->gl_texturenum, s->texinfo->texture->gl_glowtexturenum, 0, TPOLYTYPE_ALPHA); - for (i = 0,v = p->verts[0];i < p->numverts;i++, v += VERTEXSIZE) - transpolyvert(v[0], v[1], v[2], (v[3] + os) * (1.0f/64.0f), (v[4] + ot) * (1.0f/64.0f), (int) (v[9]+128),(int) (v[10]+128),(int) (v[11]+128),alpha); - transpolyend(); - } - } - } - } - /* - int light, alpha, r = 0, g = 0, b = 0; - vec3_t nv, shadecolor; - alpha = s->flags & SURF_DRAWNOALPHA ? 255 : r_wateralpha.value*255.0f; - light = false; - if (s->flags & SURF_DRAWFULLBRIGHT) - r = g = b = lighthalf ? 128 : 255; - else if (s->dlightframe == r_dlightframecount && r_dynamic.value) - light = true; - else - r = g = b = (lighthalf ? 64 : 128) + (int) (r_ambient.value * 2.0f); - if (r_waterripple.value) - { - if (lighthalf) + for (b = 0;c && b < 32;b++) { - if (light) - { - for (;s;s = s->texturechain) - { - for (p=s->polys ; p ; p=p->next) - { - // FIXME: could be a transparent water texture - transpolybegin(s->texinfo->texture->gl_texturenum, s->texinfo->texture->gl_glowtexturenum, 0, TPOLYTYPE_ALPHA); - for (i = 0,v = p->verts[0];i < p->numverts;i++, v += VERTEXSIZE) - { - nv[0] = v[0]; - nv[1] = v[1]; - nv[2] = v[2] + r_waterripple.value * turbsin[(int)((v[3]*0.125f+realtime) * TURBSCALE) & 255] * turbsin[(int)((v[4]*0.125f+realtime) * TURBSCALE) & 255] * (1.0f / 64.0f); - shadecolor[0] = shadecolor[1] = shadecolor[2] = 128 + (int) (r_ambient.value * 2.0f); - R_DynamicLightPoint(shadecolor, nv, s->dlightbits); - transpolyvert(nv[0], nv[1], nv[2], (v[3] + os) * (1.0f/64.0f), (v[4] + ot) * (1.0f/64.0f), (int) shadecolor[0] >> 1,(int) shadecolor[1] >> 1,(int) shadecolor[2] >> 1,alpha); - } - transpolyend(); - } - } - } - else + if (c & (1 << b)) { - for (;s;s = s->texturechain) + c -= (1 << b); + light = &cl_dlights[a * 32 + b]; + lightorigin = light->origin; + cr = light->color[0]; + cg = light->color[1]; + cb = light->color[2]; + radius = light->radius*light->radius*16.0f; + radius2 = radius * 16.0f; + wv = wvert; + for (p = s->polys;p;p = p->next) { - for (p=s->polys ; p ; p=p->next) + for (i = 0, v = p->verts[0];i < p->numverts;i++, v += VERTEXSIZE) { - // FIXME: could be a transparent water texture - transpolybegin(s->texinfo->texture->gl_texturenum, s->texinfo->texture->gl_glowtexturenum, 0, TPOLYTYPE_ALPHA); - for (i = 0,v = p->verts[0];i < p->numverts;i++, v += VERTEXSIZE) + f = VectorDistance2(wv, lightorigin); + if (f < radius) { - nv[0] = v[0]; - nv[1] = v[1]; - nv[2] = v[2] + r_waterripple.value * turbsin[(int)((v[3]*0.125f+realtime) * TURBSCALE) & 255] * turbsin[(int)((v[4]*0.125f+realtime) * TURBSCALE) & 255] * (1.0f / 64.0f); - transpolyvert(nv[0], nv[1], nv[2], (v[3] + os) * (1.0f/64.0f), (v[4] + ot) * (1.0f/64.0f), r,g,b,alpha); + f = radius2 / (f + 65536.0f); + wv[3] += cr * f; + wv[4] += cg * f; + wv[5] += cb * f; } - transpolyend(); - } - } - } - } - else - { - if (light) - { - for (;s;s = s->texturechain) - { - for (p=s->polys ; p ; p=p->next) - { - // FIXME: could be a transparent water texture - transpolybegin(s->texinfo->texture->gl_texturenum, s->texinfo->texture->gl_glowtexturenum, 0, TPOLYTYPE_ALPHA); - for (i = 0,v = p->verts[0];i < p->numverts;i++, v += VERTEXSIZE) - { - nv[0] = v[0]; - nv[1] = v[1]; - nv[2] = v[2] + r_waterripple.value * turbsin[(int)((v[3]*0.125f+realtime) * TURBSCALE) & 255] * turbsin[(int)((v[4]*0.125f+realtime) * TURBSCALE) & 255] * (1.0f / 64.0f); - shadecolor[0] = shadecolor[1] = shadecolor[2] = 128 + (int) (r_ambient.value * 2.0f); - R_DynamicLightPoint(shadecolor, nv, s->dlightbits); - transpolyvert(nv[0], nv[1], nv[2], (v[3] + os) * (1.0f/64.0f), (v[4] + ot) * (1.0f/64.0f), shadecolor[0],shadecolor[1],shadecolor[2],alpha); - } - transpolyend(); - } - } - } - else - { - for (;s;s = s->texturechain) - { - for (p=s->polys ; p ; p=p->next) - { - // FIXME: could be a transparent water texture - transpolybegin(s->texinfo->texture->gl_texturenum, s->texinfo->texture->gl_glowtexturenum, 0, TPOLYTYPE_ALPHA); - for (i = 0,v = p->verts[0];i < p->numverts;i++, v += VERTEXSIZE) - { - nv[0] = v[0]; - nv[1] = v[1]; - nv[2] = v[2] + r_waterripple.value * turbsin[(int)((v[3]*0.125f+realtime) * TURBSCALE) & 255] * turbsin[(int)((v[4]*0.125f+realtime) * TURBSCALE) & 255] * (1.0f / 64.0f); - transpolyvert(nv[0], nv[1], nv[2], (v[3] + os) * (1.0f/64.0f), (v[4] + ot) * (1.0f/64.0f), r,g,b,alpha); - } - transpolyend(); + wv += 6; } } } } } + } + } + wv = wvert; + for (p = s->polys;p;p = p->next) + { + if (currentwallpoly >= MAX_WALLPOLYS) + break; + v = p->verts[0]; + wallpoly[currentwallpoly].texnum = (unsigned short) t->gl_texturenum; + wallpoly[currentwallpoly].lighttexnum = (unsigned short) lightmap_textures + s->lightmaptexturenum; + wallpoly[currentwallpoly].glowtexnum = (unsigned short) t->gl_glowtexturenum; + wallpoly[currentwallpoly].firstvert = currentwallvert; + wallpoly[currentwallpoly].numverts = p->numverts; + wallpoly[currentwallpoly++].lit = true; + for (i = 0;inumverts;i++, v += VERTEXSIZE) + { + wallvert[currentwallvert].r = (byte) (bound(0, (int) wv[3], 255)); + wallvert[currentwallvert].g = (byte) (bound(0, (int) wv[4], 255)); + wallvert[currentwallvert].b = (byte) (bound(0, (int) wv[5], 255)); + wallvert[currentwallvert].a = 255; + wallvert[currentwallvert].vert[0] = wv[0]; + wallvert[currentwallvert].vert[1] = wv[1]; + wallvert[currentwallvert].vert[2] = wv[2]; + wallvert[currentwallvert].s = v[3]; + wallvert[currentwallvert].t = v[4]; + wallvert[currentwallvert].u = v[5]; + wallvert[currentwallvert++].v = v[6]; + wv += 6; + } + } +} + +// LordHavoc: transparent brush models +extern int r_dlightframecount; +extern float modelalpha; +//extern vec3_t shadecolor; +//qboolean R_CullBox (vec3_t mins, vec3_t maxs); +//void R_DynamicLightPoint(vec3_t color, vec3_t org, int *dlightbits); +//void R_DynamicLightPointNoMask(vec3_t color, vec3_t org); +//void EmitWaterPolys (msurface_t *fa); + +void R_WallSurfVertex(msurface_t *s, texture_t *t, qboolean transform) +{ + int i, a, b, alpha; + unsigned int c; + glpoly_t *p; + float wvert[64*6], *wv, *v, cr, cg, cb, radius, radius2, f, *lightorigin; + int smax, tmax, size3; + float scale; + byte *lm; + dlight_t *light; + smax = (s->extents[0]>>4)+1; + tmax = (s->extents[1]>>4)+1; + size3 = smax*tmax*3; // *3 for colored lighting + alpha = (int) (modelalpha * 255.0f); + // check for lightmap modification + if (r_dynamic.value) + { + if (r_ambient.value != s->cached_ambient || lighthalf != s->cached_lighthalf + || (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])) + R_UpdateLightmap(s, s->lightmaptexturenum); + } + wv = wvert; + for (p = s->polys;p;p = p->next) + { + for (i = 0, v = p->verts[0];i < p->numverts;i++, v += VERTEXSIZE) + { + if (transform) + softwaretransform(v, wv); else + VectorCopy(v, wv); + wv[3] = wv[4] = wv[5] = r_ambient.value * 2.0f; + if (s->styles[0] != 255) { - if (lighthalf) + lm = (byte *)((long) s->samples + ((int) v[8] * smax + (int) v[7]) * 3); // LordHavoc: *3 for colored lighting + scale = d_lightstylevalue[s->styles[0]] * (1.0f / 128.0f);wv[3] += lm[size3*0+0] * scale;wv[4] += lm[size3*0+1] * scale;wv[5] += lm[size3*0+2] * scale; + if (s->styles[1] != 255) { - if (light) + scale = d_lightstylevalue[s->styles[1]] * (1.0f / 128.0f);wv[3] += lm[size3*1+0] * scale;wv[4] += lm[size3*1+1] * scale;wv[5] += lm[size3*1+2] * scale; + if (s->styles[2] != 255) { - for (;s;s = s->texturechain) + scale = d_lightstylevalue[s->styles[2]] * (1.0f / 128.0f);wv[3] += lm[size3*2+0] * scale;wv[4] += lm[size3*2+1] * scale;wv[5] += lm[size3*2+2] * scale; + if (s->styles[3] != 255) { - for (p=s->polys ; p ; p=p->next) - { - // FIXME: could be a transparent water texture - transpolybegin(s->texinfo->texture->gl_texturenum, s->texinfo->texture->gl_glowtexturenum, 0, TPOLYTYPE_ALPHA); - for (i = 0,v = p->verts[0];i < p->numverts;i++, v += VERTEXSIZE) - { - shadecolor[0] = shadecolor[1] = shadecolor[2] = 128 + (int) (r_ambient.value * 2.0f); - R_DynamicLightPoint(shadecolor, v, s->dlightbits); - transpolyvert(v[0], v[1], v[2], (v[3] + os) * (1.0f/64.0f), (v[4] + ot) * (1.0f/64.0f), (int) shadecolor[0] >> 1,(int) shadecolor[1] >> 1,(int) shadecolor[2] >> 1,alpha); - } - transpolyend(); - } - } - } - else - { - for (;s;s = s->texturechain) - { - for (p=s->polys ; p ; p=p->next) - { - // FIXME: could be a transparent water texture - transpolybegin(s->texinfo->texture->gl_texturenum, s->texinfo->texture->gl_glowtexturenum, 0, TPOLYTYPE_ALPHA); - for (i = 0,v = p->verts[0];i < p->numverts;i++, v += VERTEXSIZE) - { - transpolyvert(v[0], v[1], v[2], (v[3] + os) * (1.0f/64.0f), (v[4] + ot) * (1.0f/64.0f), r,g,b,alpha); - } - transpolyend(); - } + scale = d_lightstylevalue[s->styles[3]] * (1.0f / 128.0f);wv[3] += lm[size3*3+0] * scale;wv[4] += lm[size3*3+1] * scale;wv[5] += lm[size3*3+2] * scale; } } } - else + } + wv += 6; + } + } + if (s->dlightframe == r_dlightframecount && r_dynamic.value) + { + for (a = 0;a < 8;a++) + { + if (c = s->dlightbits[a]) + { + for (b = 0;c && b < 32;b++) { - if (light) - { - for (;s;s = s->texturechain) - { - for (p=s->polys ; p ; p=p->next) - { - // FIXME: could be a transparent water texture - transpolybegin(s->texinfo->texture->gl_texturenum, s->texinfo->texture->gl_glowtexturenum, 0, TPOLYTYPE_ALPHA); - for (i = 0,v = p->verts[0];i < p->numverts;i++, v += VERTEXSIZE) - { - shadecolor[0] = shadecolor[1] = shadecolor[2] = 128 + (int) (r_ambient.value * 2.0f); - R_DynamicLightPoint(shadecolor, v, s->dlightbits); - transpolyvert(v[0], v[1], v[2], (v[3] + os) * (1.0f/64.0f), (v[4] + ot) * (1.0f/64.0f), shadecolor[0],shadecolor[1],shadecolor[2],alpha); - } - transpolyend(); - } - } - } - else + if (c & (1 << b)) { - for (;s;s = s->texturechain) + c -= (1 << b); + light = &cl_dlights[a * 32 + b]; + lightorigin = light->origin; + cr = light->color[0]; + cg = light->color[1]; + cb = light->color[2]; + radius = light->radius*light->radius*16.0f; + radius2 = radius * 16.0f; + wv = wvert; + for (p = s->polys;p;p = p->next) { - for (p=s->polys ; p ; p=p->next) + for (i = 0, v = p->verts[0];i < p->numverts;i++, v += VERTEXSIZE) { - // FIXME: could be a transparent water texture - transpolybegin(s->texinfo->texture->gl_texturenum, s->texinfo->texture->gl_glowtexturenum, 0, TPOLYTYPE_ALPHA); - for (i = 0,v = p->verts[0];i < p->numverts;i++, v += VERTEXSIZE) + f = VectorDistance2(wv, lightorigin); + if (f < radius) { - transpolyvert(v[0], v[1], v[2], (v[3] + os) * (1.0f/64.0f), (v[4] + ot) * (1.0f/64.0f), r,g,b,alpha); + f = radius2 / (f + 65536.0f); + wv[3] += cr * f; + wv[4] += cg * f; + wv[5] += cb * f; } - transpolyend(); + wv += 6; } } } + c >>= 1; + b++; } } - */ + } + } + wv = wvert; + if (currententity->colormod[0] != 1 || currententity->colormod[1] != 1 || currententity->colormod[2] != 1) + { + if (lighthalf) + { + for (p = s->polys;p;p = p->next) + { + v = p->verts[0]; + transpolybegin(t->gl_texturenum, t->gl_glowtexturenum, 0, currententity->effects & EF_ADDITIVE ? TPOLYTYPE_ADD : TPOLYTYPE_ALPHA); + for (i = 0,v = p->verts[0];i < p->numverts;i++, v += VERTEXSIZE, wv += 6) + transpolyvert(wv[0], wv[1], wv[2], v[3], v[4], (int) (wv[3] * currententity->colormod[0]) >> 1,(int) (wv[4] * currententity->colormod[1]) >> 1,(int) (wv[5] * currententity->colormod[0]) >> 1,alpha); + transpolyend(); + } + } + else + { + for (p = s->polys;p;p = p->next) + { + v = p->verts[0]; + transpolybegin(t->gl_texturenum, t->gl_glowtexturenum, 0, currententity->effects & EF_ADDITIVE ? TPOLYTYPE_ADD : TPOLYTYPE_ALPHA); + for (i = 0,v = p->verts[0];i < p->numverts;i++, v += VERTEXSIZE, wv += 6) + transpolyvert(wv[0], wv[1], wv[2], v[3], v[4], (int) (wv[3] * currententity->colormod[0]),(int) (wv[4] * currententity->colormod[1]),(int) (wv[5] * currententity->colormod[2]),alpha); + transpolyend(); + } + } + } + else + { + if (lighthalf) + { + for (p = s->polys;p;p = p->next) + { + v = p->verts[0]; + transpolybegin(t->gl_texturenum, t->gl_glowtexturenum, 0, currententity->effects & EF_ADDITIVE ? TPOLYTYPE_ADD : TPOLYTYPE_ALPHA); + for (i = 0,v = p->verts[0];i < p->numverts;i++, v += VERTEXSIZE, wv += 6) + transpolyvert(wv[0], wv[1], wv[2], v[3], v[4], (int) wv[3] >> 1,(int) wv[4] >> 1,(int) wv[5] >> 1,alpha); + transpolyend(); + } + } + else + { + for (p = s->polys;p;p = p->next) + { + v = p->verts[0]; + transpolybegin(t->gl_texturenum, t->gl_glowtexturenum, 0, currententity->effects & EF_ADDITIVE ? TPOLYTYPE_ADD : TPOLYTYPE_ALPHA); + for (i = 0,v = p->verts[0];i < p->numverts;i++, v += VERTEXSIZE, wv += 6) + transpolyvert(wv[0], wv[1], wv[2], v[3], v[4], (int) wv[3],(int) wv[4],(int) wv[5],alpha); + transpolyend(); + } } } } -// LordHavoc: transparent brush models -extern int r_dlightframecount; -extern float modelalpha; -extern vec3_t shadecolor; -//qboolean R_CullBox (vec3_t mins, vec3_t maxs); -void R_DynamicLightPoint(vec3_t color, vec3_t org, int *dlightbits); -void R_DynamicLightPointNoMask(vec3_t color, vec3_t org); -void EmitWaterPolys (msurface_t *fa); -void R_OldMarkLights (vec3_t lightorigin, dlight_t *light, int bit, int bitindex, model_t *model); +/* +================ +DrawTextureChains +================ +*/ +extern qboolean hlbsp; +extern char skyname[]; +//extern qboolean SV_TestLine (hull_t *hull, int num, vec3_t p1, vec3_t p2); +void DrawTextureChains (void) +{ + int n; + msurface_t *s; + texture_t *t; + + for (n = 0;n < cl.worldmodel->numtextures;n++) + { + if (!cl.worldmodel->textures[n] || !(s = cl.worldmodel->textures[n]->texturechain)) + continue; + // LordHavoc: decide the render type only once, because the surface properties were determined by texture anyway + cl.worldmodel->textures[n]->texturechain = NULL; + t = R_TextureAnimation (cl.worldmodel->textures[n]); + // sky + if (s->flags & SURF_DRAWSKY) + { + skyisvisible = true; + if (!hlbsp) // LordHavoc: HalfLife maps have freaky skypolys... + for (;s;s = s->texturechain) + R_SkySurf(s, false); + continue; + } + // subdivided water surface warp + if (s->flags & SURF_DRAWTURB) + { + int alpha = s->flags & SURF_DRAWNOALPHA ? 255 : r_wateralpha.value*255.0f; + for (;s;s = s->texturechain) + R_WaterSurf(s, t, false, alpha); + continue; + } + if (gl_vertex.value) + for (;s;s = s->texturechain) + R_WallSurfVertex(s, t, false); + else + for (;s;s = s->texturechain) + R_WallSurf(s, t, false); + } +} + +void R_NoVisMarkLights (vec3_t lightorigin, dlight_t *light, int bit, int bitindex, model_t *model); /* ================= @@ -815,17 +777,13 @@ R_DrawBrushModel */ void R_DrawBrushModel (entity_t *e) { - int i, j/*, l*/, smax, tmax, size3, maps; - vec3_t mins, maxs, nv; + int i; + vec3_t mins, maxs; msurface_t *s; - mplane_t *pplane; model_t *clmodel; qboolean rotated, vertexlit = false; - float dot, *v, scale; texture_t *t; - byte *lm; - float os = turbsin[(int)(realtime * TURBSCALE) & 255], ot = turbsin[(int)(realtime * TURBSCALE + 96.0) & 255]; - glpoly_t *p; + vec3_t org; currententity = e; @@ -867,304 +825,40 @@ void R_DrawBrushModel (entity_t *e) // calculate dynamic lighting for bmodel if it's not an // instanced model - if (modelalpha == 1 && clmodel->firstmodelsurface != 0 && !(currententity->effects & EF_FULLBRIGHT) && currententity->colormod[0] == 1 && currententity->colormod[2] == 1 && currententity->colormod[2] == 1) + for (i = 0;i < MAX_DLIGHTS;i++) { - int k; - vec3_t org; - for (k=0 ; korigin, org); - R_OldMarkLights (org, &cl_dlights[k], 1<<(k&31), k >> 5, clmodel); //, clmodel->nodes + clmodel->hulls[0].firstclipnode); - } + VectorSubtract(cl_dlights[i].origin, currententity->origin, org); + R_NoVisMarkLights (org, &cl_dlights[i], 1<<(i&31), i >> 5, clmodel); } - else - vertexlit = true; + vertexlit = modelalpha != 1 || clmodel->firstmodelsurface == 0 || (currententity->effects & EF_FULLBRIGHT) || currententity->colormod[0] != 1 || currententity->colormod[2] != 1 || currententity->colormod[2] != 1; e->angles[0] = -e->angles[0]; // stupid quake bug softwaretransformforentity (e); e->angles[0] = -e->angles[0]; // stupid quake bug // draw texture - for (j = 0;j < clmodel->nummodelsurfaces;j++, s++) + for (i = 0;i < clmodel->nummodelsurfaces;i++, s++) { - // find which side of the node we are on - pplane = s->plane; - - dot = DotProduct (modelorg, pplane->normal) - pplane->dist; - - // draw the polygon - if (((s->flags & SURF_PLANEBACK) && (dot < -BACKFACE_EPSILON)) || - (!(s->flags & SURF_PLANEBACK) && (dot > BACKFACE_EPSILON))) + if (((s->flags & SURF_PLANEBACK) == 0) == (PlaneDiff(modelorg, s->plane) >= 0)) { if (s->flags & SURF_DRAWSKY) - continue; - if (s->flags & SURF_DRAWTURB) { - int alpha = s->flags & SURF_DRAWNOALPHA ? 255 : r_wateralpha.value*255.0f; - // FIXME: make fog texture if water texture is transparent? - if (r_waterripple.value) - { - if (lighthalf) - { - for (p=s->polys ; p ; p=p->next) - { - transpolybegin(s->texinfo->texture->gl_texturenum, s->texinfo->texture->gl_glowtexturenum, 0, TPOLYTYPE_ALPHA); - for (i = 0,v = p->verts[0];i < p->numverts;i++, v += VERTEXSIZE) - { - softwaretransform(v, nv); - transpolyvert(nv[0], nv[1], nv[2] + r_waterripple.value * turbsin[(int)((v[3]*0.125f+realtime) * TURBSCALE) & 255] * turbsin[(int)((v[4]*0.125f+realtime) * TURBSCALE) & 255] * (1.0f / 64.0f), (v[3] + os) * (1.0f/64.0f), (v[4] + ot) * (1.0f/64.0f), (int) (v[9]+128) >> 1,(int) (v[10]+128) >> 1,(int) (v[11]+128) >> 1,alpha); - } - transpolyend(); - } - } - else - { - for (p=s->polys ; p ; p=p->next) - { - transpolybegin(s->texinfo->texture->gl_texturenum, s->texinfo->texture->gl_glowtexturenum, 0, TPOLYTYPE_ALPHA); - for (i = 0,v = p->verts[0];i < p->numverts;i++, v += VERTEXSIZE) - { - softwaretransform(v, nv); - transpolyvert(nv[0], nv[1], nv[2] + r_waterripple.value * turbsin[(int)((v[3]*0.125f+realtime) * TURBSCALE) & 255] * turbsin[(int)((v[4]*0.125f+realtime) * TURBSCALE) & 255] * (1.0f / 64.0f), (v[3] + os) * (1.0f/64.0f), (v[4] + ot) * (1.0f/64.0f), (int) (v[9]+128),(int) (v[10]+128),(int) (v[11]+128),alpha); - } - transpolyend(); - } - } - } - else - { - if (lighthalf) - { - for (p=s->polys ; p ; p=p->next) - { - transpolybegin(s->texinfo->texture->gl_texturenum, s->texinfo->texture->gl_glowtexturenum, 0, TPOLYTYPE_ALPHA); - for (i = 0,v = p->verts[0];i < p->numverts;i++, v += VERTEXSIZE) - { - softwaretransform(v, nv); - transpolyvert(nv[0], nv[1], nv[2], (v[3] + os) * (1.0f/64.0f), (v[4] + ot) * (1.0f/64.0f), (int) (v[9]+128) >> 1,(int) (v[10]+128) >> 1,(int) (v[11]+128) >> 1,alpha); - } - transpolyend(); - } - } - else - { - for (p=s->polys ; p ; p=p->next) - { - transpolybegin(s->texinfo->texture->gl_texturenum, s->texinfo->texture->gl_glowtexturenum, 0, TPOLYTYPE_ALPHA); - for (i = 0,v = p->verts[0];i < p->numverts;i++, v += VERTEXSIZE) - { - softwaretransform(v, nv); - transpolyvert(nv[0], nv[1], nv[2], (v[3] + os) * (1.0f/64.0f), (v[4] + ot) * (1.0f/64.0f), (int) (v[9]+128),(int) (v[10]+128),(int) (v[11]+128),alpha); - } - transpolyend(); - } - } - } - /* - glpoly_t *p; - int light, alpha, r = 0, g = 0, b = 0; - vec3_t shadecolor; - - if (s->flags & SURF_DRAWNOALPHA) - alpha = modelalpha*255.0f; - else - alpha = r_wateralpha.value*modelalpha*255.0f; - light = false; - if (s->flags & SURF_DRAWFULLBRIGHT || currententity->effects & EF_FULLBRIGHT) - { - if (lighthalf) - { - r = 128.0f * currententity->colormod[0]; - g = 128.0f * currententity->colormod[1]; - b = 128.0f * currententity->colormod[2]; - } - else - { - r = 255.0f * currententity->colormod[0]; - g = 255.0f * currententity->colormod[1]; - b = 255.0f * currententity->colormod[2]; - } - } - else if (s->dlightframe == r_dlightframecount && r_dynamic.value) - light = true; - else - { - if (lighthalf) - { - r = 64.0f * currententity->colormod[0] + (int) r_ambient.value; - g = 64.0f * currententity->colormod[1] + (int) r_ambient.value; - b = 64.0f * currententity->colormod[2] + (int) r_ambient.value; - } - else - { - r = 128.0f * currententity->colormod[0] + (int) (r_ambient.value * 2.0f); - g = 128.0f * currententity->colormod[1] + (int) (r_ambient.value * 2.0f); - b = 128.0f * currententity->colormod[2] + (int) (r_ambient.value * 2.0f); - } - } - for (p=s->polys ; p ; p=p->next) - { - // FIXME: could be a transparent water texture - transpolybegin(s->texinfo->texture->gl_texturenum, s->texinfo->texture->gl_glowtexturenum, 0, currententity->effects & EF_ADDITIVE ? TPOLYTYPE_ADD : TPOLYTYPE_ALPHA); - for (i = 0,v = p->verts[0];i < p->numverts;i++, v += VERTEXSIZE) - { - softwaretransform(v, nv); - if (r_waterripple.value) - nv[2] += r_waterripple.value * turbsin[(int)((v[3]*0.125f+realtime) * TURBSCALE) & 255] * turbsin[(int)((v[4]*0.125f+realtime) * TURBSCALE) & 255] * (1.0f / 64.0f); - if (light) - { - shadecolor[0] = shadecolor[1] = shadecolor[2] = 128 + (int) (r_ambient.value * 2.0f); - R_DynamicLightPoint(shadecolor, nv, s->dlightbits); - if (lighthalf) - { - r = (int) ((float) (shadecolor[0] * currententity->colormod[0])) >> 1; - g = (int) ((float) (shadecolor[1] * currententity->colormod[1])) >> 1; - b = (int) ((float) (shadecolor[2] * currententity->colormod[2])) >> 1; - } - else - { - r = (int) ((float) (shadecolor[0] * currententity->colormod[0])); - g = (int) ((float) (shadecolor[1] * currententity->colormod[1])); - b = (int) ((float) (shadecolor[2] * currententity->colormod[2])); - } - } - transpolyvert(nv[0], nv[1], nv[2], (v[3] + os) * (1.0f/64.0f), (v[4] + ot) * (1.0f/64.0f), r,g,b,alpha); - } - transpolyend(); - } - */ + R_SkySurf(s, true); continue; } t = R_TextureAnimation (s->texinfo->texture); - if (vertexlit || s->texinfo->texture->transparent) + if (s->flags & SURF_DRAWTURB) { - // FIXME: could be a transparent water texture - if ((currententity->effects & EF_FULLBRIGHT) || !s->samples) - { - for (p = s->polys;p;p = p->next) - { - if (currenttranspoly >= MAX_TRANSPOLYS) - continue; - v = &p->verts[0][0]; - transpolybegin(t->gl_texturenum, t->gl_glowtexturenum, 0, currententity->effects & EF_ADDITIVE ? TPOLYTYPE_ADD : TPOLYTYPE_ALPHA); - for (i = 0;i < p->numverts;i++, v += VERTEXSIZE) - { - softwaretransform(v, nv); - transpolyvert(nv[0], nv[1], nv[2], v[3], v[4], 255,255,255,modelalpha*255.0f); - } - transpolyend(); - } - } - else - { - smax = (s->extents[0]>>4)+1; - tmax = (s->extents[1]>>4)+1; - size3 = smax*tmax*3; // *3 for colored lighting - for (p = s->polys;p;p = p->next) - { - if (currenttranspoly >= MAX_TRANSPOLYS) - continue; - v = &p->verts[0][0]; - transpolybegin(t->gl_texturenum, t->gl_glowtexturenum, 0, currententity->effects & EF_ADDITIVE ? TPOLYTYPE_ADD : TPOLYTYPE_ALPHA); - for (i = 0;i < p->numverts;i++, v += VERTEXSIZE) - { - shadecolor[0] = shadecolor[1] = shadecolor[2] = r_ambient.value * 2.0f; - lm = (byte *)((long) s->samples + ((int) v[8] * smax + (int) v[7]) * 3); // LordHavoc: *3 for colored lighting - for (maps = 0;maps < MAXLIGHTMAPS && s->styles[maps] != 255;maps++) - { - scale = d_lightstylevalue[s->styles[maps]] * (1.0 / 128.0); - shadecolor[0] += lm[0] * scale; - shadecolor[1] += lm[1] * scale; - shadecolor[2] += lm[2] * scale; - lm += size3; // LordHavoc: *3 for colored lighting - } - softwaretransform(v, nv); - R_DynamicLightPointNoMask(shadecolor, nv); // LordHavoc: dynamic lighting - if (lighthalf) - { - transpolyvert(nv[0], nv[1], nv[2], v[3], v[4], (int) shadecolor[0] >> 1, (int) shadecolor[1] >> 1, (int) shadecolor[2] >> 1, modelalpha*255.0f); - } - else - { - transpolyvert(nv[0], nv[1], nv[2], v[3], v[4], shadecolor[0], shadecolor[1], shadecolor[2], modelalpha*255.0f); - } - } - transpolyend(); - } - } + R_WaterSurf(s, t, true, s->flags & SURF_DRAWNOALPHA ? 255 : r_wateralpha.value*255.0f); + continue; } + if (vertexlit || s->texinfo->texture->transparent) + R_WallSurfVertex(s, t, true); else - { - // check for lightmap modification - if (r_dynamic.value) - { - if (r_ambient.value != s->cached_ambient || lighthalf != s->cached_lighthalf - || (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])) - R_UpdateLightmap(s, s->lightmaptexturenum); - } - for (p = s->polys;p;p = p->next) - { - if (currentwallpoly >= MAX_WALLPOLYS) - break; - v = &s->polys->verts[0][0]; - wallpoly[currentwallpoly].texnum = (unsigned short) t->gl_texturenum; - wallpoly[currentwallpoly].lighttexnum = (unsigned short) lightmap_textures + s->lightmaptexturenum; - wallpoly[currentwallpoly].glowtexnum = (unsigned short) t->gl_glowtexturenum; - wallpoly[currentwallpoly].firstvert = currentwallvert; - wallpoly[currentwallpoly].numverts = p->numverts; - if (wallpoly[currentwallpoly++].lit = s->dlightframe == r_dlightframecount && r_dynamic.value) - { - for (i = 0;inumverts;i++, v += VERTEXSIZE) - { - /* - softwaretransform(v, nv); - shadecolor[0] = shadecolor[1] = shadecolor[2] = 0; -// R_DynamicLightPoint(shadecolor, nv, s->dlightbits); - R_DynamicLightPointNoMask(shadecolor, nv); - if (lighthalf) - { - shadecolor[0] *= 0.5f; - shadecolor[1] *= 0.5f; - shadecolor[2] *= 0.5f; - } - wallvert[currentwallvert].r = (byte) (bound(0, (int) shadecolor[0], 255)); - wallvert[currentwallvert].g = (byte) (bound(0, (int) shadecolor[1], 255)); - wallvert[currentwallvert].b = (byte) (bound(0, (int) shadecolor[2], 255)); - wallvert[currentwallvert].a = 255; - wallvert[currentwallvert].vert[0] = nv[0]; - wallvert[currentwallvert].vert[1] = nv[1]; - wallvert[currentwallvert].vert[2] = nv[2]; - */ - softwaretransform(v, wallvert[currentwallvert].vert); - wallvert[currentwallvert].r = (byte) (bound(0, (int) v[9], 255)); - wallvert[currentwallvert].g = (byte) (bound(0, (int) v[10], 255)); - wallvert[currentwallvert].b = (byte) (bound(0, (int) v[11], 255)); - wallvert[currentwallvert].a = 255; - wallvert[currentwallvert].s = v[3]; - wallvert[currentwallvert].t = v[4]; - wallvert[currentwallvert].u = v[5]; - wallvert[currentwallvert++].v = v[6]; - } - } - else - { - for (i = 0;inumverts;i++, v += VERTEXSIZE) - { - softwaretransform(v, wallvert[currentwallvert].vert); - wallvert[currentwallvert].s = v[3]; - wallvert[currentwallvert].t = v[4]; - wallvert[currentwallvert].u = v[5]; - wallvert[currentwallvert++].v = v[6]; - } - } - } - } + R_WallSurf(s, t, true); } } UploadLightmaps(); @@ -1319,7 +1013,6 @@ void R_DrawWorld (void) currententity = &ent; softwaretransformidentity(); // LordHavoc: clear transform - skyisvisible = false; if (cl.worldmodel) R_WorldNode (); diff --git a/model_brush.h b/model_brush.h index 84e3f8e1..55f5bcf7 100644 --- a/model_brush.h +++ b/model_brush.h @@ -93,8 +93,8 @@ typedef struct int flags; } mtexinfo_t; -// LordHavoc: was 7, I added two more for raw lightmap coordinates, and then 3 more for light accumulation -#define VERTEXSIZE 12 +// LordHavoc: was 7, I added two more for raw lightmap coordinates +#define VERTEXSIZE 9 typedef struct glpoly_s { @@ -127,7 +127,7 @@ typedef struct msurface_s // lighting info int dlightframe; -// int dlightbits[8]; + int dlightbits[8]; int lightframe; // avoid redundent addition of dlights diff --git a/r_light.c b/r_light.c index 502a8ae8..775beee8 100644 --- a/r_light.c +++ b/r_light.c @@ -75,21 +75,11 @@ void R_OldMarkLights (vec3_t lightorigin, dlight_t *light, int bit, int bitindex float dist; msurface_t *surf; int i; -// float l, maxdist; -// int j, s, t; -// vec3_t impact; - float cr = light->color[0]; - float cg = light->color[1]; - float cb = light->color[2]; - float radius = light->radius*light->radius*16.0f; - float radius2 = radius * 16.0f; - radius -= 65536.0f; // for comparisons loc0: if (node->contents < 0) return; -// dist = DotProduct (lightorigin, node->plane->normal) - node->plane->dist; dist = PlaneDiff(lightorigin, node->plane); if (dist > light->radius) @@ -118,94 +108,16 @@ loc0: } node->dlightbits[bitindex] |= bit; -// maxdist = light->radius*light->radius; - // mark the polygons surf = cl.worldmodel->surfaces + node->firstsurface; for (i=0 ; inumsurfaces ; i++, surf++) { - glpoly_t *p; - float f; - int j; - float *v; if (surf->dlightframe != r_dlightframecount) // not dynamic until now { -// surf->dlightbits[0] = surf->dlightbits[1] = surf->dlightbits[2] = surf->dlightbits[3] = surf->dlightbits[4] = surf->dlightbits[5] = surf->dlightbits[6] = surf->dlightbits[7] = 0; -// surf->dlightframe = r_dlightframecount; -// surf->dlightbits[bitindex] = bit; - for (p = surf->polys;p;p = p->next) - { - for (j = 0, v = p->verts[0];j < p->numverts;j++, v += VERTEXSIZE) - { - f = VectorDistance2(v, lightorigin); - if (f < radius) - { - surf->dlightframe = r_dlightframecount; - f = radius2 / (f + 65536.0f); - v[ 9] = cr * f; - v[10] = cg * f; - v[11] = cb * f; - } - else - v[9] = v[10] = v[11] = 0; - } - } + surf->dlightbits[0] = surf->dlightbits[1] = surf->dlightbits[2] = surf->dlightbits[3] = surf->dlightbits[4] = surf->dlightbits[5] = surf->dlightbits[6] = surf->dlightbits[7] = 0; + surf->dlightframe = r_dlightframecount; } - else - { -// surf->dlightbits[bitindex] |= bit; - for (p = surf->polys;p;p = p->next) - { - for (j = 0, v = p->verts[0];j < p->numverts;j++, v += VERTEXSIZE) - { - f = VectorDistance2(v, lightorigin); - if (f < radius) - { - f = radius2 / (f + 65536.0f); - v[ 9] += cr * f; - v[10] += cg * f; - v[11] += cb * f; - } - } - } - } -/* - if (surf->flags & SURF_DRAWTURB) // water - { - if (surf->dlightframe != r_dlightframecount) // not dynamic until now - { - surf->dlightbits[0] = surf->dlightbits[1] = surf->dlightbits[2] = surf->dlightbits[3] = surf->dlightbits[4] = surf->dlightbits[5] = surf->dlightbits[6] = surf->dlightbits[7] = 0; - surf->dlightframe = r_dlightframecount; - } - surf->dlightbits[bitindex] |= bit; - } - // LordHavoc: MAJOR dynamic light speedup here, eliminates marking of surfaces that are too far away from light, thus preventing unnecessary uploads -// else if (r_dynamicbothsides.value || (((surf->flags & SURF_PLANEBACK) && (dist < -BACKFACE_EPSILON)) || (!(surf->flags & SURF_PLANEBACK) && (dist > BACKFACE_EPSILON)))) - else if (((surf->flags & SURF_PLANEBACK) != 0) != (dist >= 0)) - { - // passed the plane side check - for (j=0 ; j<3 ; j++) - impact[j] = lightorigin[j] - surf->plane->normal[j]*dist; - - // clamp center of light to corner and check brightness - l = DotProduct (impact, surf->texinfo->vecs[0]) + surf->texinfo->vecs[0][3] - surf->texturemins[0]; - s = l+0.5;if (s < 0) s = 0;else if (s > surf->extents[0]) s = surf->extents[0]; - s = l - s; - l = DotProduct (impact, surf->texinfo->vecs[1]) + surf->texinfo->vecs[1][3] - surf->texturemins[1]; - t = l+0.5;if (t < 0) t = 0;else if (t > surf->extents[1]) t = surf->extents[1]; - t = l - t; - // compare to minimum light - if ((s*s+t*t+dist*dist) < maxdist) - { - if (surf->dlightframe != r_dlightframecount) // not dynamic until now - { - surf->dlightbits[0] = surf->dlightbits[1] = surf->dlightbits[2] = surf->dlightbits[3] = surf->dlightbits[4] = surf->dlightbits[5] = surf->dlightbits[6] = surf->dlightbits[7] = 0; - surf->dlightframe = r_dlightframecount; - } - surf->dlightbits[bitindex] |= bit; - } - } -*/ + surf->dlightbits[bitindex] |= bit; } if (node->children[0]->contents >= 0) @@ -229,6 +141,11 @@ loc0: } } +void R_NoVisMarkLights (vec3_t lightorigin, dlight_t *light, int bit, int bitindex, model_t *model) +{ + R_OldMarkLights(lightorigin, light, bit, bitindex, model->nodes + model->hulls[0].firstclipnode); +} + void R_VisMarkLights (vec3_t lightorigin, dlight_t *light, int bit, int bitindex, model_t *model) { mleaf_t *pvsleaf = Mod_PointInLeaf (lightorigin, model); @@ -240,20 +157,17 @@ void R_VisMarkLights (vec3_t lightorigin, dlight_t *light, int bit, int bitindex } else { - int i, j, k, l, m, c; + int i, k, l, m, c; msurface_t *surf, **mark; mleaf_t *leaf; static int lightframe = 0; byte *in = pvsleaf->compressed_vis; int row = (model->numleafs+7)>>3; - float cr = light->color[0]; - float cg = light->color[1]; - float cb = light->color[2]; - float radius = light->radius*light->radius*16.0f; - float radius2 = radius * 16.0f; - glpoly_t *p; - float f; - float *v; + float low[3], high[3], radius; + + radius = light->radius * 4.0f; + low[0] = lightorigin[0] - radius;low[1] = lightorigin[1] - radius;low[2] = lightorigin[2] - radius; + high[0] = lightorigin[0] + radius;high[1] = lightorigin[1] + radius;high[2] = lightorigin[2] + radius; lightframe++; k = 0; @@ -270,11 +184,16 @@ void R_VisMarkLights (vec3_t lightorigin, dlight_t *light, int bit, int bitindex if (c & (1<leafs[(k << 3)+i+1]; + leaf->lightframe = lightframe; if (leaf->visframe != r_visframecount) continue; if (leaf->contents == CONTENTS_SOLID) continue; - leaf->lightframe = lightframe; + // if out of the light radius, skip + if (leaf->minmaxs[0] > high[0] || leaf->minmaxs[3] < low[0] + || leaf->minmaxs[1] > high[1] || leaf->minmaxs[4] < low[1] + || leaf->minmaxs[2] > high[2] || leaf->minmaxs[5] < low[2]) + continue; if (leaf->dlightframe != r_dlightframecount) // not dynamic until now { leaf->dlightbits[0] = leaf->dlightbits[1] = leaf->dlightbits[2] = leaf->dlightbits[3] = leaf->dlightbits[4] = leaf->dlightbits[5] = leaf->dlightbits[6] = leaf->dlightbits[7] = 0; @@ -290,50 +209,15 @@ void R_VisMarkLights (vec3_t lightorigin, dlight_t *light, int bit, int bitindex if (surf->visframe != r_framecount || surf->lightframe == lightframe) continue; surf->lightframe = lightframe; -// if (((surf->flags & SURF_PLANEBACK) == 0) == ((PlaneDiff(lightorigin, surf->plane)) >= 0)) -// { + if (((surf->flags & SURF_PLANEBACK) == 0) == ((PlaneDiff(lightorigin, surf->plane)) >= 0)) + { if (surf->dlightframe != r_dlightframecount) // not dynamic until now { -// surf->dlightbits[0] = surf->dlightbits[1] = surf->dlightbits[2] = surf->dlightbits[3] = surf->dlightbits[4] = surf->dlightbits[5] = surf->dlightbits[6] = surf->dlightbits[7] = 0; -// surf->dlightframe = r_dlightframecount; -// surf->dlightbits[bitindex] = bit; - for (p = surf->polys;p;p = p->next) - { - for (j = 0, v = p->verts[0];j < p->numverts;j++, v += VERTEXSIZE) - { - f = VectorDistance2(v, lightorigin); - if (f < radius) - { - surf->dlightframe = r_dlightframecount; - f = radius2 / (f + 65536.0f); - v[ 9] = cr * f; - v[10] = cg * f; - v[11] = cb * f; - } - else - v[9] = v[10] = v[11] = 0; - } - } - } - else - { -// surf->dlightbits[bitindex] |= bit; - for (p = surf->polys;p;p = p->next) - { - for (j = 0, v = p->verts[0];j < p->numverts;j++, v += VERTEXSIZE) - { - f = VectorDistance2(v, lightorigin); - if (f < radius) - { - f = radius2 / (f + 65536.0f); - v[ 9] += cr * f; - v[10] += cg * f; - v[11] += cb * f; - } - } - } + surf->dlightbits[0] = surf->dlightbits[1] = surf->dlightbits[2] = surf->dlightbits[3] = surf->dlightbits[4] = surf->dlightbits[5] = surf->dlightbits[6] = surf->dlightbits[7] = 0; + surf->dlightframe = r_dlightframecount; } -// } + surf->dlightbits[bitindex] |= bit; + } } while (--m); } -- 2.39.2