Replacing Quake2's RecursiveLightPoint with DarkPlaces'
Moderator: InsideQC Admins
6 posts
• Page 1 of 1
Replacing Quake2's RecursiveLightPoint with DarkPlaces'
The DarkPlaces version has some nice features like axis optimization and bilinear filtering. I was mostly able to copy/paste it with minor changes.
So, here we go: Open gl_light.c and replace RecursiveLightPoint() with this:
Now go to R_LightPoint(), remove "vec3_t end;", and change:
to
Easy peasy!
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
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;
}
}
Now go to R_LightPoint(), remove "vec3_t end;", and change:
- 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)
to
- 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)
Easy peasy!
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
Last edited by jitspoe on Sun Jun 16, 2013 2:28 am, edited 2 times in total.
- jitspoe
- Posts: 217
- Joined: Mon Jan 17, 2005 5:27 am
Re: Replacing Quake2's RecursiveLightPoint with DarkPlaces'
It can also be applied to the software renderer as well.
i should not be here
- leileilol
- Posts: 2783
- Joined: Fri Oct 15, 2004 3:23 am
Re: Replacing Quake2's RecursiveLightPoint with DarkPlaces'
I have seen a strange issue with flag models in some maps in Paintball2 after using this. They will be dark at spawn, but if I pick up the flag and drop it, it's fine. I tried moving the starting point for the light trace up a little, as I thought the flag may be spawning slightly in the ground, but that didn't appear to fix it. I'll have to investigate further. I'm wondering if the flag spawn is exactly on a brush split or something causing this oddity.
- jitspoe
- Posts: 217
- Joined: Mon Jan 17, 2005 5:27 am
Re: Replacing Quake2's RecursiveLightPoint with DarkPlaces'
i should not be here
- leileilol
- Posts: 2783
- Joined: Fri Oct 15, 2004 3:23 am
Re: Replacing Quake2's RecursiveLightPoint with DarkPlaces'
I've tracked down the issue and posted a reply in the thread you linked. In short, it's because the entities are exactly on the edge of the lightmap. I've modified the code with a simple tweak that fixes that particular issue, but it may result in others (haven't seen any yet).
- jitspoe
- Posts: 217
- Joined: Mon Jan 17, 2005 5:27 am
Re: Replacing Quake2's RecursiveLightPoint with DarkPlaces'
Updated with another fix for negative values being returned.
- jitspoe
- Posts: 217
- Joined: Mon Jan 17, 2005 5:27 am
6 posts
• Page 1 of 1
Return to Programming Tutorials
Who is online
Users browsing this forum: No registered users and 1 guest