So, here we go: Open gl_light.c and replace RecursiveLightPoint() with this:
Code: Select all
// Taken from LordHavoc's DarkPlaces, slightly modified by jitspoe to be compatible with Quake2
static int LightPoint_RecursiveBSPNode (model_t *model, vec3_t ambientcolor, const mnode_t *node, float x, float y, float startz, float endz)
{
int side;
float front, back;
float mid, distz = endz - startz;
loc0:
//if (!node->plane)
if (node->contents != -1)
return false; // didn't hit anything
switch (node->plane->type)
{
case PLANE_X:
node = node->children[x < node->plane->dist];
goto loc0;
case PLANE_Y:
node = node->children[y < node->plane->dist];
goto loc0;
case PLANE_Z:
side = startz < node->plane->dist;
if ((endz < node->plane->dist) == side)
{
node = node->children[side];
goto loc0;
}
// found an intersection
mid = node->plane->dist;
break;
default:
back = front = x * node->plane->normal[0] + y * node->plane->normal[1];
front += startz * node->plane->normal[2];
back += endz * node->plane->normal[2];
side = front < node->plane->dist;
if ((back < node->plane->dist) == side)
{
node = node->children[side];
goto loc0;
}
// found an intersection
mid = startz + distz * (front - node->plane->dist) / (front - back);
break;
}
// go down front side
if (node->children[side]->plane && LightPoint_RecursiveBSPNode(model, ambientcolor, node->children[side], x, y, startz, mid))
{
return true; // hit something
}
else
{
// check for impact on this node
if (node->numsurfaces)
{
unsigned int i;
int dsi, dti, lmwidth, lmheight;
float ds, dt;
msurface_t *surface;
unsigned char *lightmap;
int maps, line3, size3;
float dsfrac;
float dtfrac;
float w00, w01, w10, w11;
surface = model->surfaces + node->firstsurface;
for (i = 0; i < node->numsurfaces; ++i, ++surface)
{
if (surface->flags & (SURF_DRAWTURB|SURF_DRAWSKY))
continue; // no lightmaps
// location we want to sample in the lightmap
ds = ((x * surface->texinfo->vecs[0][0] + y * surface->texinfo->vecs[0][1] + mid * surface->texinfo->vecs[0][2] + surface->texinfo->vecs[0][3]) - surface->texturemins[0]) * 0.0625f;
dt = ((x * surface->texinfo->vecs[1][0] + y * surface->texinfo->vecs[1][1] + mid * surface->texinfo->vecs[1][2] + surface->texinfo->vecs[1][3]) - surface->texturemins[1]) * 0.0625f;
if (ds >= 0.0f && dt >= 0.0f) // jit - fix for negative light values
{
int dsi = (int)ds;
int dti = (int)dt;
lmwidth = ((surface->extents[0] >> 4) + 1);
lmheight = ((surface->extents[1] >> 4) + 1);
// is it in bounds?
if (dsi < lmwidth && dti < lmheight) // jit - fix for black models right on brush splits.
{
// calculate bilinear interpolation factors
// and also multiply by fixedpoint conversion factors
dsfrac = ds - dsi;
dtfrac = dt - dti;
w00 = (1 - dsfrac) * (1 - dtfrac) * (1.0f / 255.0f);
w01 = ( dsfrac) * (1 - dtfrac) * (1.0f / 255.0f);
w10 = (1 - dsfrac) * ( dtfrac) * (1.0f / 255.0f);
w11 = ( dsfrac) * ( dtfrac) * (1.0f / 255.0f);
// values for pointer math
line3 = lmwidth * 3;
size3 = lmwidth * lmheight * 3;
// look up the pixel
//lightmap = surface->samples + dti * line3 + dsi * 3;
lightmap = surface->stain_samples + dti * line3 + dsi * 3; // Note: comment this line out and use the one above if you do not have stainmaps
// bilinear filter each lightmap style, and sum them
for (maps = 0; maps < MAXLIGHTMAPS && surface->styles[maps] != 255; maps++)
{
VectorMA(ambientcolor, w00, lightmap , ambientcolor);
VectorMA(ambientcolor, w01, lightmap + 3 , ambientcolor);
VectorMA(ambientcolor, w10, lightmap + line3 , ambientcolor);
VectorMA(ambientcolor, w11, lightmap + line3 + 3, ambientcolor);
lightmap += size3;
}
return true; // success
}
}
}
}
// go down back side
node = node->children[side ^ 1];
startz = mid;
distz = endz - startz;
goto loc0;
}
}
Code: Select all
end[0] = p[0];
end[1] = p[1];
end[2] = p[2] - 2048.0f;
r = RecursiveLightPoint(r_worldmodel->nodes, p, end);
if (r != -1)
Code: Select all
VectorClear(pointcolor);
r = LightPoint_RecursiveBSPNode(r_worldmodel, pointcolor, r_worldmodel->nodes, p[0], p[1], p[2], p[2] - 2048.0f);
if (r <= 0)
Not sure if my code is exactly the same as Quake2's there, but it should be close enough. There is one line you will have to change if you're not using stainmaps.vecs