This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
#include "quakedef.h"
-#define MAX_DECALS 2048
+cvar_t r_drawdecals = {0, "r_drawdecals", "1"};
-typedef struct decal_s
+static void r_decals_start(void)
{
- vec3_t org;
- vec3_t direction;
- vec3_t vert[4];
- byte color[4];
- rtexture_t *tex;
- msurface_t *surface;
- byte *lightmapaddress;
- int lightmapstep;
}
-decal_t;
-decal_t *decals;
-int currentdecal; // wraps around in decal array, replacing old ones when a new one is needed
-
-cvar_t r_drawdecals = {"r_drawdecals", "1"};
-cvar_t r_decals_lighting = {"r_decals_lighting", "1"};
-
-void r_decals_start()
-{
- decals = (decal_t *) qmalloc(MAX_DECALS * sizeof(decal_t));
- memset(decals, 0, MAX_DECALS * sizeof(decal_t));
- currentdecal = 0;
-}
-
-void r_decals_shutdown()
+static void r_decals_shutdown(void)
{
- qfree(decals);
}
-void r_decals_newmap()
+static void r_decals_newmap(void)
{
- memset(decals, 0, MAX_DECALS * sizeof(decal_t));
- currentdecal = 0;
}
-void R_Decals_Init()
+void R_Decals_Init(void)
{
Cvar_RegisterVariable (&r_drawdecals);
- Cvar_RegisterVariable (&r_decals_lighting);
R_RegisterModule("R_Decals", r_decals_start, r_decals_shutdown, r_decals_newmap);
}
-void R_Decal(vec3_t org, rtexture_t *tex, float scale, int cred, int cgreen, int cblue, int alpha)
+/*
+static int decalindexarray[2*3] =
{
- int i, ds, dt, bestlightmapofs;
- float bestdist, dist;
- vec3_t impact, right, up;
- decal_t *decal;
-// mleaf_t *leaf;
- msurface_t *surf/*, **mark, **endmark*/, *bestsurf;
-
- if (alpha < 1)
+ 0, 1, 2,
+ 0, 2, 3,
+};
+*/
+
+void R_DrawDecals (void)
+{
+ renderdecal_t *r;
+ int i, j, lightmapstep, ds, dt;
+ float fscale, fr, fg, fb, dist, f, fog, ifog, fogvec[3], impact[3], v[3], org[3], dir[3], right[3], up[3], tvxyz[4][4], tvst[4][2];
+ particletexture_t *tex, *texfog;
+ byte *lightmap;
+ msurface_t *surf;
+ rdlight_t *rd;
+ rmeshinfo_t m;
+
+ if (!r_drawdecals.integer)
return;
-// leaf = Mod_PointInLeaf(org, cl.worldmodel);
-// if (!leaf->nummarksurfaces)
-// return;
-
-// mark = leaf->firstmarksurface;
-// endmark = mark + leaf->nummarksurfaces;
-
- // find the best surface to place the decal on
- bestsurf = NULL;
- bestdist = 16;
- bestlightmapofs = 0;
-// while(mark < endmark)
-// {
-// surf = *mark++;
- surf = &cl.worldmodel->surfaces[cl.worldmodel->firstmodelsurface];
- for (i = 0;i < cl.worldmodel->nummodelsurfaces;i++, surf++)
+ fog = 0;
+ ifog = 1;
+
+ Mod_CheckLoaded(cl.worldmodel);
+
+ // LordHavoc: this meshinfo must match up with R_Mesh_DrawDecal
+ // LordHavoc: the commented out lines are hardwired behavior in R_Mesh_DrawDecal
+ memset(&m, 0, sizeof(m));
+ m.blendfunc1 = GL_SRC_ALPHA;
+ m.blendfunc2 = GL_ONE_MINUS_SRC_ALPHA;
+ //m.numtriangles = 2;
+ //m.numverts = 4;
+ //m.index = decalindexarray;
+ m.vertex = &tvxyz[0][0];
+ //m.vertexstep = sizeof(float[4]);
+ m.tex[0] = R_GetTexture(particlefonttexture);
+ m.texcoords[0] = &tvst[0][0];
+ //m.texcoordstep[0] = sizeof(float[2]);
+
+ for (i = 0, r = r_refdef.decals;i < r_refdef.numdecals;i++, r++)
{
- if (surf->flags & SURF_DRAWTILED)
- continue; // no lightmaps
+ if (r->ent)
+ {
+ if (r->ent->visframe != r_framecount)
+ continue;
- dist = PlaneDiff(org, surf->plane);
- if (surf->flags & SURF_PLANEBACK)
- dist = -dist;
- if (dist < 0)
- continue;
- if (dist >= bestdist)
- continue;
+ Mod_CheckLoaded(r->ent->model);
+ if (r->ent->model->type != mod_brush)
+ continue;
- impact[0] = org[0] - surf->plane->normal[0] * dist;
- impact[1] = org[1] - surf->plane->normal[1] * dist;
- impact[2] = org[2] - surf->plane->normal[2] * dist;
+ surf = r->ent->model->surfaces + r->surface;
- ds = (int) (DotProduct(impact, surf->texinfo->vecs[0]) + surf->texinfo->vecs[0][3]);
- dt = (int) (DotProduct(impact, surf->texinfo->vecs[1]) + surf->texinfo->vecs[1][3]);
+ // skip decals on surfaces that aren't visible in this frame
+ if (surf->visframe != r_framecount)
+ continue;
- if (ds < surf->texturemins[0] || dt < surf->texturemins[1])
- continue;
-
- ds -= surf->texturemins[0];
- dt -= surf->texturemins[1];
-
- if (ds > surf->extents[0] || dt > surf->extents[1])
+ softwaretransformforentity(r->ent);
+ softwaretransform(r->org, org);
+ softwaretransformdirection(r->dir, dir);
+
+ // do not render if the view origin is behind the decal
+ VectorSubtract(org, r_origin, fogvec);
+ if (DotProduct(dir, fogvec) < 0)
+ continue;
+ }
+ else
+ {
+ surf = cl.worldmodel->surfaces + r->surface;
+
+ // skip decals on surfaces that aren't visible in this frame
+ if (surf->visframe != r_framecount)
+ continue;
+
+ // do not render if the view origin is behind the decal
+ VectorSubtract(r->org, r_origin, fogvec);
+ if (DotProduct(r->dir, fogvec) < 0)
+ continue;
+
+ VectorCopy(r->org, org);
+ VectorCopy(r->dir, dir);
+ }
+
+ dist = -PlaneDiff(r->org, surf->plane);
+ VectorMA(r->org, dist, surf->plane->normal, impact);
+
+ ds = (int) (DotProduct(impact, surf->texinfo->vecs[0]) + surf->texinfo->vecs[0][3]) - surf->texturemins[0];
+ dt = (int) (DotProduct(impact, surf->texinfo->vecs[1]) + surf->texinfo->vecs[1][3]) - surf->texturemins[1];
+
+ if (ds < 0 || dt < 0 || ds > surf->extents[0] || dt > surf->extents[1])
+ {
+ // this should never happen
continue;
+ }
- bestsurf = surf;
- bestdist = dist;
- bestlightmapofs = (dt >> 4) * ((surf->extents[0] >> 4) + 1) + (ds >> 4);
- }
- // abort if no suitable surface was found
- if (bestsurf == NULL)
- return;
+ tex = &particletexture[r->tex][0];
+ VectorVectors(dir, right, up);
+ VectorScale(right, r->scale, right);
+ VectorScale(up, r->scale, up);
+ tvxyz[0][0] = org[0] - right[0] - up[0];
+ tvxyz[0][1] = org[1] - right[1] - up[1];
+ tvxyz[0][2] = org[2] - right[2] - up[2];
+ tvxyz[1][0] = org[0] - right[0] + up[0];
+ tvxyz[1][1] = org[1] - right[1] + up[1];
+ tvxyz[1][2] = org[2] - right[2] + up[2];
+ tvxyz[2][0] = org[0] + right[0] + up[0];
+ tvxyz[2][1] = org[1] + right[1] + up[1];
+ tvxyz[2][2] = org[2] + right[2] + up[2];
+ tvxyz[3][0] = org[0] + right[0] - up[0];
+ tvxyz[3][1] = org[1] + right[1] - up[1];
+ tvxyz[3][2] = org[2] + right[2] - up[2];
+ tvst[0][0] = tex->s1;
+ tvst[0][1] = tex->t1;
+ tvst[1][0] = tex->s1;
+ tvst[1][1] = tex->t2;
+ tvst[2][0] = tex->s2;
+ tvst[2][1] = tex->t2;
+ tvst[3][0] = tex->s2;
+ tvst[3][1] = tex->t1;
+
+ // lighting
+ fr = fg = fb = 0.0f;
- // grab a decal from the array and advance to the next decal to replace, wrapping to replace an old decal if necessary
- decal = decals + currentdecal;
- currentdecal++;
- if (currentdecal >= MAX_DECALS)
- currentdecal = 0;
- decal->tex = tex;
- // reverse direction
- if (bestsurf->flags & SURF_PLANEBACK)
- {
- VectorCopy(bestsurf->plane->normal, decal->direction);
- }
- else
- {
- VectorNegate(bestsurf->plane->normal, decal->direction);
+ if ((lightmap = surf->samples))
+ {
+ if (surf->styles[0] != 255)
+ {
+ lightmap += ((dt >> 4) * ((surf->extents[0] >> 4) + 1) + (ds >> 4)) * 3;
+ fscale = d_lightstylevalue[surf->styles[0]] * (1.0f / 32768.0f);
+ fr += lightmap[0] * fscale;
+ fg += lightmap[1] * fscale;
+ fb += lightmap[2] * fscale;
+ if (surf->styles[1] != 255)
+ {
+ lightmapstep = (((surf->extents[0] >> 4) + 1) * ((surf->extents[1] >> 4) + 1)) * 3;
+ lightmap += lightmapstep;
+ fscale = d_lightstylevalue[surf->styles[1]] * (1.0f / 32768.0f);
+ fr += lightmap[0] * fscale;
+ fg += lightmap[1] * fscale;
+ fb += lightmap[2] * fscale;
+ if (surf->styles[2] != 255)
+ {
+ lightmap += lightmapstep;
+ fscale = d_lightstylevalue[surf->styles[2]] * (1.0f / 32768.0f);
+ fr += lightmap[0] * fscale;
+ fg += lightmap[1] * fscale;
+ fb += lightmap[2] * fscale;
+ if (surf->styles[3] != 255)
+ {
+ lightmap += lightmapstep;
+ fscale = d_lightstylevalue[surf->styles[3]] * (1.0f / 32768.0f);
+ fr += lightmap[0] * fscale;
+ fg += lightmap[1] * fscale;
+ fb += lightmap[2] * fscale;
+ }
+ }
+ }
+ }
+ }
+
+ if (surf->dlightframe == r_framecount)
+ {
+ for (j = 0;j < r_numdlights;j++)
+ {
+ if (surf->dlightbits[j >> 5] & (1 << (j & 31)))
+ {
+ rd = &r_dlight[j];
+ VectorSubtract(r->org, rd->origin, v);
+ dist = DotProduct(v, v) + LIGHTOFFSET;
+ if (dist < rd->cullradius2)
+ {
+ f = (1.0f / dist) - rd->lightsubtract;
+ if (f > 0)
+ {
+ fr += f * rd->light[0];
+ fg += f * rd->light[1];
+ fb += f * rd->light[2];
+ }
+ }
+ }
+ }
+ }
+
+ // if the surface is transparent, render as transparent
+ m.transparent = !(surf->flags & SURF_CLIPSOLID);
+ m.cr = r->color[0] * fr;
+ m.cg = r->color[1] * fg;
+ m.cb = r->color[2] * fb;
+ m.ca = r->color[3];
+
+ if (fogenabled)
+ {
+ fog = exp(fogdensity/DotProduct(fogvec,fogvec));
+ texfog = &particletexture[r->tex][1];
+ if (fog >= (1.0f / 64.0f))
+ {
+ if (fog >= (1.0f - (1.0f / 64.0f)))
+ {
+ // fully fogged, just use the fog texture and render as alpha
+ m.cr = fogcolor[0];
+ m.cg = fogcolor[1];
+ m.cb = fogcolor[2];
+ m.ca = r->color[3];
+ tvst[0][0] = texfog->s1;
+ tvst[0][1] = texfog->t1;
+ tvst[1][0] = texfog->s1;
+ tvst[1][1] = texfog->t2;
+ tvst[2][0] = texfog->s2;
+ tvst[2][1] = texfog->t2;
+ tvst[3][0] = texfog->s2;
+ tvst[3][1] = texfog->t1;
+ R_Mesh_DrawDecal(&m);
+ }
+ else
+ {
+ // partially fogged, darken the first pass
+ ifog = 1 - fog;
+ m.cr *= ifog;
+ m.cg *= ifog;
+ m.cb *= ifog;
+ if (tex->s1 == texfog->s1 && tex->t1 == texfog->t1)
+ {
+ // fog texture is the same as the base, just change the color
+ m.cr += fogcolor[0] * fog;
+ m.cg += fogcolor[1] * fog;
+ m.cb += fogcolor[2] * fog;
+ R_Mesh_DrawDecal(&m);
+ }
+ else
+ {
+ // render the first pass (alpha), then do additive fog
+ R_Mesh_DrawDecal(&m);
+ m.blendfunc2 = GL_ONE;
+ m.cr = fogcolor[0];
+ m.cg = fogcolor[1];
+ m.cb = fogcolor[2];
+ m.ca = r->color[3] * fog;
+ tvst[0][0] = texfog->s1;
+ tvst[0][1] = texfog->t1;
+ tvst[1][0] = texfog->s1;
+ tvst[1][1] = texfog->t2;
+ tvst[2][0] = texfog->s2;
+ tvst[2][1] = texfog->t2;
+ tvst[3][0] = texfog->s2;
+ tvst[3][1] = texfog->t1;
+ R_Mesh_DrawDecal(&m);
+ m.blendfunc2 = GL_ONE_MINUS_SRC_ALPHA;
+ }
+ }
+ }
+ else
+ R_Mesh_DrawDecal(&m);
+ }
+ else
+ R_Mesh_DrawDecal(&m);
}
- // - 0.25 to push it off the surface a bit
- decal->org[0] = impact[0] = org[0] + decal->direction[0] * (bestdist - 0.25f);
- decal->org[1] = impact[1] = org[1] + decal->direction[1] * (bestdist - 0.25f);
- decal->org[2] = impact[2] = org[2] + decal->direction[2] * (bestdist - 0.25f);
- // set up the 4 corners
- scale *= 0.5f;
- VectorVectors(decal->direction, right, up);
- decal->vert[0][0] = impact[0] - up[0] * scale - right[0] * scale;
- decal->vert[0][1] = impact[1] - up[1] * scale - right[1] * scale;
- decal->vert[0][2] = impact[2] - up[2] * scale - right[2] * scale;
- decal->vert[1][0] = impact[0] + up[0] * scale - right[0] * scale;
- decal->vert[1][1] = impact[1] + up[1] * scale - right[1] * scale;
- decal->vert[1][2] = impact[2] + up[2] * scale - right[2] * scale;
- decal->vert[2][0] = impact[0] + up[0] * scale + right[0] * scale;
- decal->vert[2][1] = impact[1] + up[1] * scale + right[1] * scale;
- decal->vert[2][2] = impact[2] + up[2] * scale + right[2] * scale;
- decal->vert[3][0] = impact[0] - up[0] * scale + right[0] * scale;
- decal->vert[3][1] = impact[1] - up[1] * scale + right[1] * scale;
- decal->vert[3][2] = impact[2] - up[2] * scale + right[2] * scale;
- // store the color
- decal->color[0] = (byte) bound(0, cred, 255);
- decal->color[1] = (byte) bound(0, cgreen, 255);
- decal->color[2] = (byte) bound(0, cblue, 255);
- decal->color[3] = (byte) bound(0, alpha, 255);
- // store the surface information for lighting
- decal->surface = bestsurf;
- decal->lightmapstep = ((bestsurf->extents[0]>>4)+1) * ((bestsurf->extents[1]>>4)+1)*3; // LordHavoc: *3 for colored lighting
- if (bestsurf->samples)
- decal->lightmapaddress = bestsurf->samples + bestlightmapofs * 3; // LordHavoc: *3 for colored lighitng
- else
- decal->lightmapaddress = NULL;
}
+/*
void R_DrawDecals (void)
{
- decal_t *p;
- int i, j, k, dynamiclight, ir, ig, ib, maps, bits;
- byte br, bg, bb, ba;
- float scale, fr, fg, fb, dist, rad, mindist;
+ renderdecal_t *r;
+ int i, j, lightmapstep, ds, dt;
+ float fscale, fr, fg, fb, dist, f, fog, ifog, impact[3], v[3], org[3], dir[3], right[3], up[3], tv[4][5];
+ particletexture_t *tex;
byte *lightmap;
- vec3_t v;
msurface_t *surf;
- dlight_t *dl;
+ rdlight_t *rd;
+ rmeshinfo_t m;
- if (!r_drawdecals.value)
+ if (!r_drawdecals.integer)
return;
- dynamiclight = (int) r_dynamic.value != 0 && (int) r_decals_lighting.value != 0;
+ ifog = 1;
- mindist = DotProduct(r_refdef.vieworg, vpn) + 4.0f;
+ Mod_CheckLoaded(cl.worldmodel);
- for (i = 0, p = decals;i < MAX_DECALS;i++, p++)
+ memset(&m, 0, sizeof(m));
+ m.blendfunc1 = GL_SRC_ALPHA;
+ m.blendfunc2 = GL_ONE_MINUS_SRC_ALPHA;
+ m.numtriangles = 2;
+ m.numverts = 4;
+ m.index = decalindexarray;
+ m.vertex = &tv[0][0];
+ m.vertexstep = sizeof(float[5]);
+ m.tex[0] = R_GetTexture(particlefonttexture);
+ m.texcoords[0] = &tv[0][3];
+ m.texcoordstep[0] = sizeof(float[5]);
+
+ for (i = 0, r = r_refdef.decals;i < r_refdef.numdecals;i++, r++)
{
- if (p->tex == NULL)
- break;
+ if (r->ent)
+ {
+ if (r->ent->visframe != r_framecount)
+ continue;
- // do not render if the decal is behind the view
- if (DotProduct(p->org, vpn) < mindist)
- continue;
+ Mod_CheckLoaded(r->ent->model);
+ if (r->ent->model->type != mod_brush)
+ continue;
+
+ surf = r->ent->model->surfaces + r->surface;
- // do not render if the view origin is behind the decal
- VectorSubtract(p->org, r_refdef.vieworg, v);
- if (DotProduct(p->direction, v) < 0)
+ // skip decals on surfaces that aren't visible in this frame
+ if (surf->visframe != r_framecount)
+ continue;
+
+ softwaretransformforentity(r->ent);
+ softwaretransform(r->org, org);
+ softwaretransformdirection(r->dir, dir);
+
+ // do not render if the view origin is behind the decal
+ VectorSubtract(org, r_origin, v);
+ if (DotProduct(dir, v) < 0)
+ continue;
+ }
+ else
+ {
+ surf = cl.worldmodel->surfaces + r->surface;
+
+ // skip decals on surfaces that aren't visible in this frame
+ if (surf->visframe != r_framecount)
+ continue;
+
+ // do not render if the view origin is behind the decal
+ VectorSubtract(r->org, r_origin, v);
+ if (DotProduct(r->dir, v) < 0)
+ continue;
+
+ VectorCopy(r->org, org);
+ VectorCopy(r->dir, dir);
+ }
+
+ dist = -PlaneDiff(r->org, surf->plane);
+ VectorMA(r->org, dist, surf->plane->normal, impact);
+
+ ds = (int) (DotProduct(impact, surf->texinfo->vecs[0]) + surf->texinfo->vecs[0][3]) - surf->texturemins[0];
+ dt = (int) (DotProduct(impact, surf->texinfo->vecs[1]) + surf->texinfo->vecs[1][3]) - surf->texturemins[1];
+
+ if (ds < 0 || dt < 0 || ds > surf->extents[0] || dt > surf->extents[1])
+ {
+ // this should never happen
continue;
+ }
+
+ if (fogenabled)
+ {
+ ifog = 1 - exp(fogdensity/DotProduct(v,v));
+ ifog = bound(0, ifog, 1);
+ }
- // get the surface lighting
- surf = p->surface;
- lightmap = p->lightmapaddress;
+ tex = &particletexture[r->tex][0];
+ VectorVectors(dir, right, up);
+ VectorScale(right, r->scale, right);
+ VectorScale(up, r->scale, up);
+ tv[0][0] = org[0] - right[0] - up[0];
+ tv[0][1] = org[1] - right[1] - up[1];
+ tv[0][2] = org[2] - right[2] - up[2];
+ tv[0][3] = tex->s1;
+ tv[0][4] = tex->t1;
+ tv[1][0] = org[0] - right[0] + up[0];
+ tv[1][1] = org[1] - right[1] + up[1];
+ tv[1][2] = org[2] - right[2] + up[2];
+ tv[1][3] = tex->s1;
+ tv[1][4] = tex->t2;
+ tv[2][0] = org[0] + right[0] + up[0];
+ tv[2][1] = org[1] + right[1] + up[1];
+ tv[2][2] = org[2] + right[2] + up[2];
+ tv[2][3] = tex->s2;
+ tv[2][4] = tex->t2;
+ tv[3][0] = org[0] + right[0] - up[0];
+ tv[3][1] = org[1] + right[1] - up[1];
+ tv[3][2] = org[2] + right[2] - up[2];
+ tv[3][3] = tex->s2;
+ tv[3][4] = tex->t1;
+
+ // lighting
fr = fg = fb = 0.0f;
- if (lightmap)
+
+ if ((lightmap = surf->samples))
{
- for (maps = 0;maps < MAXLIGHTMAPS && surf->styles[maps] != 255;maps++)
+ if (surf->styles[0] != 255)
{
- scale = d_lightstylevalue[surf->styles[maps]];
- fr += lightmap[0] * scale;
- fg += lightmap[1] * scale;
- fb += lightmap[2] * scale;
- lightmap += p->lightmapstep;
+ lightmap += ((dt >> 4) * ((surf->extents[0] >> 4) + 1) + (ds >> 4)) * 3;
+ fscale = d_lightstylevalue[surf->styles[0]] * (1.0f / 32768.0f);
+ fr += lightmap[0] * fscale;
+ fg += lightmap[1] * fscale;
+ fb += lightmap[2] * fscale;
+ if (surf->styles[1] != 255)
+ {
+ lightmapstep = (((surf->extents[0] >> 4) + 1) * ((surf->extents[1] >> 4) + 1)) * 3;
+ lightmap += lightmapstep;
+ fscale = d_lightstylevalue[surf->styles[1]] * (1.0f / 32768.0f);
+ fr += lightmap[0] * fscale;
+ fg += lightmap[1] * fscale;
+ fb += lightmap[2] * fscale;
+ if (surf->styles[2] != 255)
+ {
+ lightmap += lightmapstep;
+ fscale = d_lightstylevalue[surf->styles[2]] * (1.0f / 32768.0f);
+ fr += lightmap[0] * fscale;
+ fg += lightmap[1] * fscale;
+ fb += lightmap[2] * fscale;
+ if (surf->styles[3] != 255)
+ {
+ lightmap += lightmapstep;
+ fscale = d_lightstylevalue[surf->styles[3]] * (1.0f / 32768.0f);
+ fr += lightmap[0] * fscale;
+ fg += lightmap[1] * fscale;
+ fb += lightmap[2] * fscale;
+ }
+ }
+ }
}
}
- fr *= (1.0f / 256.0f);
- fg *= (1.0f / 256.0f);
- fb *= (1.0f / 256.0f);
- // dynamic lighting
- if (dynamiclight)
+
+ if (surf->dlightframe == r_framecount)
{
- if (surf->dlightframe == r_dlightframecount)
+ for (j = 0;j < r_numdlights;j++)
{
- for (j = 0;j < 8;j++)
+ if (surf->dlightbits[j >> 5] & (1 << (j & 31)))
{
- bits = surf->dlightbits[j];
- if (bits)
+ rd = &r_dlight[j];
+ VectorSubtract(r->org, rd->origin, v);
+ dist = DotProduct(v, v) + LIGHTOFFSET;
+ if (dist < rd->cullradius2)
{
- for (k = 0, dl = cl_dlights + j * 32;bits;k++, dl++)
+ f = (1.0f / dist) - rd->lightsubtract;
+ if (f > 0)
{
- if (bits & (1 << k))
- {
- bits -= 1 << k;
- VectorSubtract(p->org, dl->origin, v);
- dist = DotProduct(v, v) + LIGHTOFFSET;
- rad = dl->radius * dl->radius;
- if (dist < rad)
- {
- rad *= 128.0f / dist;
- fr += rad * dl->color[0];
- fg += rad * dl->color[1];
- fb += rad * dl->color[2];
- }
- }
+ fr += f * rd->light[0];
+ fg += f * rd->light[1];
+ fb += f * rd->light[2];
}
}
}
}
}
- // apply color to lighting
- ir = (int) (fr * p->color[0] * (1.0f / 128.0f));
- ig = (int) (fg * p->color[1] * (1.0f / 128.0f));
- ib = (int) (fb * p->color[2] * (1.0f / 128.0f));
- // compute byte color
- br = (byte) min(ir, 255);
- bg = (byte) min(ig, 255);
- bb = (byte) min(ib, 255);
- ba = p->color[3];
- // put into transpoly system for sorted drawing later
- transpolybegin(R_GetTexture(p->tex), 0, R_GetTexture(p->tex), TPOLYTYPE_ALPHA);
- transpolyvertub(p->vert[0][0], p->vert[0][1], p->vert[0][2], 0,1,br,bg,bb,ba);
- transpolyvertub(p->vert[1][0], p->vert[1][1], p->vert[1][2], 0,0,br,bg,bb,ba);
- transpolyvertub(p->vert[2][0], p->vert[2][1], p->vert[2][2], 1,0,br,bg,bb,ba);
- transpolyvertub(p->vert[3][0], p->vert[3][1], p->vert[3][2], 1,1,br,bg,bb,ba);
- transpolyend();
+
+ // if the surface is transparent, render as transparent
+ m.transparent = !(surf->flags & SURF_CLIPSOLID);
+ m.cr = r->color[0] * fr;
+ m.cg = r->color[1] * fg;
+ m.cb = r->color[2] * fb;
+ m.ca = r->color[3];
+
+ if (fogenabled)
+ {
+ m.cr *= ifog;
+ m.cg *= ifog;
+ m.cb *= ifog;
+ }
+
+ R_Mesh_DrawDecal(&m);
+ }
+
+ if (!fogenabled)
+ return;
+
+ m.blendfunc2 = GL_ONE;
+ m.cr = fogcolor[0];
+ m.cg = fogcolor[1];
+ m.cb = fogcolor[2];
+
+ for (i = 0, r = r_refdef.decals;i < r_refdef.numdecals;i++, r++)
+ {
+ if (r->ent)
+ {
+ if (r->ent->visframe != r_framecount)
+ continue;
+
+ Mod_CheckLoaded(r->ent->model);
+
+ surf = r->ent->model->surfaces + r->surface;
+
+ // skip decals on surfaces that aren't visible in this frame
+ if (surf->visframe != r_framecount)
+ continue;
+
+ softwaretransformforentity(r->ent);
+ softwaretransform(r->org, org);
+ softwaretransformdirection(r->dir, dir);
+
+ // do not render if the view origin is behind the decal
+ VectorSubtract(org, r_origin, v);
+ if (DotProduct(dir, v) < 0)
+ continue;
+ }
+ else
+ {
+ surf = cl.worldmodel->surfaces + r->surface;
+
+ // skip decals on surfaces that aren't visible in this frame
+ if (surf->visframe != r_framecount)
+ continue;
+
+ // do not render if the view origin is behind the decal
+ VectorSubtract(r->org, r_origin, v);
+ if (DotProduct(r->dir, v) < 0)
+ continue;
+
+ VectorCopy(r->org, org);
+ VectorCopy(r->dir, dir);
+ }
+
+ fog = exp(fogdensity/DotProduct(v,v));
+ fog = bound(0, fog, 1);
+ m.ca = r->color[3] * fog;
+
+ if (m.ca >= 0.01f)
+ {
+ dist = -PlaneDiff(r->org, surf->plane);
+ VectorMA(r->org, dist, surf->plane->normal, impact);
+
+ ds = (int) (DotProduct(impact, surf->texinfo->vecs[0]) + surf->texinfo->vecs[0][3]) - surf->texturemins[0];
+ dt = (int) (DotProduct(impact, surf->texinfo->vecs[1]) + surf->texinfo->vecs[1][3]) - surf->texturemins[1];
+
+ if (ds < 0 || dt < 0 || ds > surf->extents[0] || dt > surf->extents[1])
+ {
+ // this should never happen
+ continue;
+ }
+
+ tex = &particletexture[r->tex][1];
+ VectorVectors(dir, right, up);
+ VectorScale(right, r->scale, right);
+ VectorScale(up, r->scale, up);
+ tv[0][0] = org[0] - right[0] - up[0];
+ tv[0][1] = org[1] - right[1] - up[1];
+ tv[0][2] = org[2] - right[2] - up[2];
+ tv[0][3] = tex->s1;
+ tv[0][4] = tex->t1;
+ tv[1][0] = org[0] - right[0] + up[0];
+ tv[1][1] = org[1] - right[1] + up[1];
+ tv[1][2] = org[2] - right[2] + up[2];
+ tv[1][3] = tex->s1;
+ tv[1][4] = tex->t2;
+ tv[2][0] = org[0] + right[0] + up[0];
+ tv[2][1] = org[1] + right[1] + up[1];
+ tv[2][2] = org[2] + right[2] + up[2];
+ tv[2][3] = tex->s2;
+ tv[2][4] = tex->t2;
+ tv[3][0] = org[0] + right[0] - up[0];
+ tv[3][1] = org[1] + right[1] - up[1];
+ tv[3][2] = org[2] + right[2] - up[2];
+ tv[3][3] = tex->s2;
+ tv[3][4] = tex->t1;
+
+ // if the surface is transparent, render as transparent
+ m.transparent = !(surf->flags & SURF_CLIPSOLID);
+ R_Mesh_DrawDecal(&m);
+ }
}
}
+*/