|
All this code here LordHavoc's I just debugged some stuff and made it into a tutorial. This tutorial will make it so that your engine will use an external .lit file to apply colored lights to quake levels. I would not recommend using this tutorial if you already have BSP 30 support. In cl_main.c Find Cl_AllocDlight And add this: dl->color [0] = dl->color[1] = dl->color[2] = 1; //LordHavoc Lit. Support after every occurence of dl->key = key; Find the dlight_t struct add add this to it vec3_t color; //LordHavoc Lit. Support Find Mod_LoadLighting Replace that function with this one
void Mod_LoadLighting (lump_t *l)
{
// LordHavoc: .lit support begin
/* LordHavoc: original code
if (!l->filelen)
{
loadmodel->lightdata = NULL;
return;
}
loadmodel->lightdata = Hunk_AllocName ( l->filelen, loadname);
memcpy (loadmodel->lightdata, mod_base + l->fileofs, l->filelen);
*/
int i;
byte *in, *out, *data;
byte d;
char litfilename[1024];
loadmodel->lightdata = NULL;
// LordHavoc: check for a .lit file
strcpy(litfilename, loadmodel->name);
COM_StripExtension(litfilename, litfilename);
strcat(litfilename, ".lit");
data = (byte*) COM_LoadHunkFile (litfilename, false);
if (data)
{
if (data[0] == 'Q' && data[1] == 'L' && data[2] == 'I' && data[3] == 'T')
{
i = LittleLong(((int *)data)[1]);
if (i == 1)
{
Con_DPrintf("%s loaded", litfilename);
loadmodel->lightdata = data + 8;
return;
}
else
Con_Printf("Unknown .lit file version (%d)\n", i);
}
else
Con_Printf("Corrupt .lit file (old version?), ignoring\n");
}
// LordHavoc: no .lit found, expand the white lighting data to color
if (!l->filelen)
return;
loadmodel->lightdata = Hunk_AllocName ( l->filelen*3, litfilename);
in = loadmodel->lightdata + l->filelen*2; // place the file at the end, so it will not be overwritten until the very last write
out = loadmodel->lightdata;
memcpy (in, mod_base + l->fileofs, l->filelen);
for (i = 0;i < l->filelen;i++)
{
d = *in++;
*out++ = d;
*out++ = d;
*out++ = d;
}
// LordHavoc: .lit support end
}
out->samples = loadmodel->lightdata + i; and add this after it out->samples = loadmodel->lightdata + (i * 3); // LordHavoc
/*
=============
R_MarkLights
=============
*/
void R_MarkLights (dlight_t *light, int bit, mnode_t *node)
{
mplane_t *splitplane;
float dist;
msurface_t *surf;
int i;
// LordHavoc: .lit support begin (actually this is just a major lighting speedup, no relation to color :)
float l, maxdist;
int j, s, t;
vec3_t impact;
loc0:
// LordHavoc: .lit support end
if (node->contents < 0)
return;
splitplane = node->plane; // LordHavoc: original code
// LordHavoc: .lit support (actually this is just a major lighting speedup, no relation to color :)
if (splitplane->type < 3)
dist = light->origin[splitplane->type] - splitplane->dist;
else
dist = DotProduct (light->origin, splitplane->normal) - splitplane->dist; // LordHavoc: original code
// LordHavoc: .lit support end
if (dist > light->radius)
{
// LordHavoc: .lit support begin (actually this is just a major lighting speedup, no relation to color :)
//R_MarkLights (light, bit, node->children[0]); // LordHavoc: original code
//return; // LordHavoc: original code
node = node->children[0];
goto loc0;
// LordHavoc: .lit support end
}
if (dist < -light->radius)
{
// LordHavoc: .lit support begin (actually this is just a major lighting speedup, no relation to color :)
//R_MarkLights (light, bit, node->children[1]); // LordHavoc: original code
//return; // LordHavoc: original code
node = node->children[1];
goto loc0;
// LordHavoc: .lit support end
}
maxdist = light->radius*light->radius; // LordHavoc: .lit support (actually this is just a major lighting speedup, no relation to color :)
// mark the polygons
surf = cl.worldmodel->surfaces + node->firstsurface;
for (i=0 ; i
/*
=============================================================================
LIGHT SAMPLING
=============================================================================
*/
mplane_t *lightplane;
vec3_t lightspot;
// LordHavoc: .lit support begin
// LordHavoc: original code replaced entirely
int RecursiveLightPoint (vec3_t color, mnode_t *node, vec3_t start, vec3_t end)
{
float front, back, frac;
vec3_t mid;
loc0:
if (node->contents < 0)
return false; // didn't hit anything
// calculate mid point
if (node->plane->type < 3)
{
front = start[node->plane->type] - node->plane->dist;
back = end[node->plane->type] - node->plane->dist;
}
else
{
front = DotProduct(start, node->plane->normal) - node->plane->dist;
back = DotProduct(end, node->plane->normal) - node->plane->dist;
}
// LordHavoc: optimized recursion
if ((back < 0) == (front < 0))
// return RecursiveLightPoint (color, node->children[front < 0], start, end);
{
node = node->children[front < 0];
goto loc0;
}
frac = front / (front-back);
mid[0] = start[0] + (end[0] - start[0])*frac;
mid[1] = start[1] + (end[1] - start[1])*frac;
mid[2] = start[2] + (end[2] - start[2])*frac;
// go down front side
if (RecursiveLightPoint (color, node->children[front < 0], start, mid))
return true; // hit something
else
{
int i, ds, dt;
msurface_t *surf;
// check for impact on this node
VectorCopy (mid, lightspot);
lightplane = node->plane;
surf = cl.worldmodel->surfaces + node->firstsurface;
for (i = 0;i < node->numsurfaces;i++, surf++)
{
if (surf->flags & SURF_DRAWTILED)
continue; // no lightmaps
ds = (int) ((float) DotProduct (mid, surf->texinfo->vecs[0]) + surf->texinfo->vecs[0][3]);
dt = (int) ((float) DotProduct (mid, surf->texinfo->vecs[1]) + surf->texinfo->vecs[1][3]);
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])
continue;
if (surf->samples)
{
// LordHavoc: enhanced to interpolate lighting
byte *lightmap;
int maps, line3, dsfrac = ds & 15, dtfrac = dt & 15, r00 = 0, g00 = 0, b00 = 0, r01 = 0, g01 = 0, b01 = 0, r10 = 0, g10 = 0, b10 = 0, r11 = 0, g11 = 0, b11 = 0;
float scale;
line3 = ((surf->extents[0]>>4)+1)*3;
lightmap = surf->samples + ((dt>>4) * ((surf->extents[0]>>4)+1) + (ds>>4))*3; // LordHavoc: *3 for color
for (maps = 0;maps < MAXLIGHTMAPS && surf->styles[maps] != 255;maps++)
{
scale = (float) d_lightstylevalue[surf->styles[maps]] * 1.0 / 256.0;
r00 += (float) lightmap[ 0] * scale;g00 += (float) lightmap[ 1] * scale;b00 += (float) lightmap[2] * scale;
r01 += (float) lightmap[ 3] * scale;g01 += (float) lightmap[ 4] * scale;b01 += (float) lightmap[5] * scale;
r10 += (float) lightmap[line3+0] * scale;g10 += (float) lightmap[line3+1] * scale;b10 += (float) lightmap[line3+2] * scale;
r11 += (float) lightmap[line3+3] * scale;g11 += (float) lightmap[line3+4] * scale;b11 += (float) lightmap[line3+5] * scale;
lightmap += ((surf->extents[0]>>4)+1) * ((surf->extents[1]>>4)+1)*3; // LordHavoc: *3 for colored lighting
}
color[0] += (float) ((int) ((((((((r11-r10) * dsfrac) >> 4) + r10)-((((r01-r00) * dsfrac) >> 4) + r00)) * dtfrac) >> 4) + ((((r01-r00) * dsfrac) >> 4) + r00)));
color[1] += (float) ((int) ((((((((g11-g10) * dsfrac) >> 4) + g10)-((((g01-g00) * dsfrac) >> 4) + g00)) * dtfrac) >> 4) + ((((g01-g00) * dsfrac) >> 4) + g00)));
color[2] += (float) ((int) ((((((((b11-b10) * dsfrac) >> 4) + b10)-((((b01-b00) * dsfrac) >> 4) + b00)) * dtfrac) >> 4) + ((((b01-b00) * dsfrac) >> 4) + b00)));
}
return true; // success
}
// go down back side
return RecursiveLightPoint (color, node->children[front >= 0], mid, end);
}
}
vec3_t lightcolor; // LordHavoc: used by model rendering
int R_LightPoint (vec3_t p)
{
vec3_t end;
if (r_fullbright.value || !cl.worldmodel->lightdata)
{
lightcolor[0] = lightcolor[1] = lightcolor[2] = 255;
return 255;
}
end[0] = p[0];
end[1] = p[1];
end[2] = p[2] - 2048;
lightcolor[0] = lightcolor[1] = lightcolor[2] = 0;
RecursiveLightPoint (lightcolor, cl.worldmodel->nodes, p, end);
return ((lightcolor[0] + lightcolor[1] + lightcolor[2]) * (1.0f / 3.0f));
}
// LordHavoc: .lit support end
In gl_rmain.c find Alias Models Comment out float shadelight, ambientlight; Add extern vec3_t lightcolor; // LordHavoc: .lit support to the definitions at the top l = shadedots[verts->lightnormalindex] * shadelight; glColor3f (l, l, l); l = shadedots[verts->lightnormalindex]; glColor3f (l * lightcolor[0], l * lightcolor[1], l * lightcolor[2]); Now find R_DrawAliasModel Replace the entire function with this one
void R_DrawAliasModel (entity_t *e)
{
int i, j;
int lnum;
vec3_t dist;
float add;
model_t *clmodel;
vec3_t mins, maxs;
aliashdr_t *paliashdr;
trivertx_t *verts, *v;
int index;
float s, t, an;
int anim;
clmodel = currententity->model;
VectorAdd (currententity->origin, clmodel->mins, mins);
VectorAdd (currententity->origin, clmodel->maxs, maxs);
if (R_CullBox (mins, maxs))
return;
VectorCopy (currententity->origin, r_entorigin);
VectorSubtract (r_origin, r_entorigin, modelorg);
//
// get lighting information
//
// LordHavoc: .lit support begin
//ambientlight = shadelight = R_LightPoint (currententity->origin); // LordHavoc: original code, removed shadelight and ambientlight
R_LightPoint(currententity->origin); // LordHavoc: lightcolor is all that matters from this
// LordHavoc: .lit support end
// allways give the gun some light
// LordHavoc: .lit support begin
//if (e == &cl.viewent && ambientlight < 24) // LordHavoc: original code
// ambientlight = shadelight = 24; // LordHavoc: original code
if (e == &cl.viewent)
{
if (lightcolor[0] < 24)
lightcolor[0] = 24;
if (lightcolor[1] < 24)
lightcolor[1] = 24;
if (lightcolor[2] < 24)
lightcolor[2] = 24;
}
// LordHavoc: .lit support end
for (lnum=0 ; lnumComment out this
float ambient[4], diffuse[4];
int j;
int lnum;
vec3_t dist;
float add;
dlight_t *dl;
int ambientlight, shadelight;
j = R_LightPoint (currententity->origin); if (j < 24) j = 24; // allways give some light on gun ambientlight = j; shadelight = j; // add dynamic lights for (lnum=0 ; lnum Add: unsigned blocklights[18*18*3]; // LordHavoc: .lit support (*3 for RGB) to the definitions at the top unsigned blocklights[18*18]; And add this to the definitions at the top of the function // LordHavoc: .lit support begin float cred, cgreen, cblue, brightness; unsigned *bl; // LordHavoc: .lit support end local[0] -= surf->texturemins[0]; local[1] -= surf->texturemins[1]; // LordHavoc: .lit support begin bl = blocklights; cred = cl_dlights[lnum].color[0] * 256.0f; cgreen = cl_dlights[lnum].color[1] * 256.0f; cblue = cl_dlights[lnum].color[2] * 256.0f; // LordHavoc: .lit support end blocklights[t*smax + s] += (rad - dist)*256;
{
brightness = rad - dist;
bl[0] += (int) (brightness * cred);
bl[1] += (int) (brightness * cgreen);
bl[2] += (int) (brightness * cblue);
}
bl += 3;
void R_BuildLightMap (msurface_t *surf, byte *dest, int stride)
{
int smax, tmax;
int t;
int i, j, size;
byte *lightmap;
unsigned scale;
int maps;
int lightadj[4];
unsigned *bl;
surf->cached_dlight = (surf->dlightframe == r_framecount);
smax = (surf->extents[0]>>4)+1;
tmax = (surf->extents[1]>>4)+1;
size = smax*tmax;
lightmap = surf->samples;
// set to full bright if no light data
if (r_fullbright.value || !cl.worldmodel->lightdata)
{
// LordHavoc: .lit support begin
bl = blocklights;
for (i=0 ; iComment out glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_BLEND); // LordHavoc: .lit support begin if (gl_lightmap_format == GL_RGBA) glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); // LordHavoc: not inverse lighting else glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_BLEND); // LordHavoc: original code // LordHavoc: .lit support end Now find R_RenderDynamicLightMaps And add this after the first if statement
// LordHavoc: .lit support begin
if (gl_lightmap_format == GL_RGBA)
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); // LordHavoc: not inverse lighting
else
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_BLEND); // LordHavoc: original code
// LordHavoc: .lit support end
And add this after the elseif statement
// LordHavoc: .lit support begin
else if (gl_lightmap_format == GL_RGBA)
{
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glColor3f (1,1,1);
glBlendFunc(GL_ZERO, GL_SRC_COLOR);
}
// LordHavoc: .lit support end
// LordHavoc: .lit support begin else if (gl_lightmap_format == GL_RGBA) glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); // LordHavoc: .lit support end Find Gl_BuildLightMaps and comment out gl_lightmap_format = GL_LUMINANCE; if (isPermedia) gl_lightmap_format = GL_RGBA; gl_lightmap_format = GL_RGBA; Ok thats it compile and run and you will have an engine that supports .lits Goto http://www.geocities.com/mh_quake and get a program called mh_light and use it on your existing quake maps to make them colored. Any problems E-Mail at qghastlyq@hotmail.com |