mirror of
https://git.do.srb2.org/STJr/SRB2.git
synced 2025-02-23 04:11:17 +00:00
Support polyobject planes in software renderer
Backported from private trunk (it's all my work so shoosh) so other people can check out how it's done (and maybe provide some additional bugfixes? hint hint?)
This commit is contained in:
parent
5b07cf8ff0
commit
2df51dc151
6 changed files with 161 additions and 23 deletions
|
@ -453,7 +453,7 @@ extern const char *compdate, *comptime, *comprevision;
|
|||
//#define CHAOSISNOTDEADYET
|
||||
|
||||
/// Polyobject fake flat code
|
||||
//#define POLYOBJECTS_PLANES
|
||||
#define POLYOBJECTS_PLANES
|
||||
|
||||
/// Blue spheres for future use.
|
||||
/// \todo Remove this define.
|
||||
|
|
68
src/r_bsp.c
68
src/r_bsp.c
|
@ -683,6 +683,33 @@ void R_SortPolyObjects(subsector_t *sub)
|
|||
}
|
||||
}
|
||||
|
||||
//
|
||||
// R_PolysegCompare
|
||||
//
|
||||
// Callback for qsort to sort the segs of a polyobject. Returns such that the
|
||||
// closer one is sorted first. I sure hope this doesn't break anything. -Red
|
||||
//
|
||||
static int R_PolysegCompare(const void *p1, const void *p2)
|
||||
{
|
||||
const seg_t *seg1 = *(const seg_t * const *)p1;
|
||||
const seg_t *seg2 = *(const seg_t * const *)p2;
|
||||
fixed_t dist1, dist2;
|
||||
|
||||
// TODO might be a better way to get distance?
|
||||
#define vxdist(v) FixedMul(R_PointToDist(v->x, v->y), FINECOSINE((R_PointToAngle(v->x, v->y)-viewangle)>>ANGLETOFINESHIFT))+0xFFFFFFF
|
||||
|
||||
dist1 = min(vxdist(seg1->v1), vxdist(seg1->v2));
|
||||
dist2 = min(vxdist(seg2->v1), vxdist(seg2->v2));
|
||||
|
||||
if (dist1 == dist2) { // Segs connect toward the front, so use the back verts to determine order!
|
||||
dist1 = max(vxdist(seg1->v1), vxdist(seg1->v2));
|
||||
dist2 = max(vxdist(seg2->v1), vxdist(seg2->v2));
|
||||
}
|
||||
#undef vxdist
|
||||
|
||||
return dist1-dist2;
|
||||
}
|
||||
|
||||
//
|
||||
// R_AddPolyObjects
|
||||
//
|
||||
|
@ -709,6 +736,7 @@ static void R_AddPolyObjects(subsector_t *sub)
|
|||
// render polyobjects
|
||||
for (i = 0; i < numpolys; ++i)
|
||||
{
|
||||
qsort(po_ptrs[i]->segs, po_ptrs[i]->segCount, sizeof(seg_t *), R_PolysegCompare);
|
||||
for (j = 0; j < po_ptrs[i]->segCount; ++j)
|
||||
R_AddLine(po_ptrs[i]->segs[j]);
|
||||
}
|
||||
|
@ -909,15 +937,28 @@ static void R_Subsector(size_t num)
|
|||
&& polysec->floorheight >= frontsector->floorheight
|
||||
&& (viewz < polysec->floorheight))
|
||||
{
|
||||
fixed_t xoff, yoff;
|
||||
xoff = polysec->floor_xoffs;
|
||||
yoff = polysec->floor_yoffs;
|
||||
|
||||
if (po->angle != 0) {
|
||||
angle_t fineshift = po->angle >> ANGLETOFINESHIFT;
|
||||
|
||||
xoff -= FixedMul(FINECOSINE(fineshift), po->centerPt.x)+FixedMul(FINESINE(fineshift), po->centerPt.y);
|
||||
yoff -= FixedMul(FINESINE(fineshift), po->centerPt.x)-FixedMul(FINECOSINE(fineshift), po->centerPt.y);
|
||||
} else {
|
||||
xoff -= po->centerPt.x;
|
||||
yoff += po->centerPt.y;
|
||||
}
|
||||
|
||||
light = R_GetPlaneLight(frontsector, polysec->floorheight, viewz < polysec->floorheight);
|
||||
light = 0;
|
||||
ffloor[numffloors].plane = R_FindPlane(polysec->floorheight, polysec->floorpic,
|
||||
polysec->lightlevel, polysec->floor_xoffs,
|
||||
polysec->floor_yoffs,
|
||||
polysec->floorpic_angle,
|
||||
polysec->lightlevel, xoff, yoff,
|
||||
polysec->floorpic_angle-po->angle,
|
||||
NULL,
|
||||
NULL);
|
||||
ffloor[numffloors].plane->polyobj = true;
|
||||
ffloor[numffloors].plane->polyobj = po;
|
||||
|
||||
ffloor[numffloors].height = polysec->floorheight;
|
||||
ffloor[numffloors].polyobj = po;
|
||||
|
@ -934,12 +975,27 @@ static void R_Subsector(size_t num)
|
|||
&& polysec->ceilingheight <= frontsector->ceilingheight
|
||||
&& (viewz > polysec->ceilingheight))
|
||||
{
|
||||
fixed_t xoff, yoff;
|
||||
xoff = polysec->ceiling_xoffs;
|
||||
yoff = polysec->ceiling_yoffs;
|
||||
|
||||
if (po->angle != 0) {
|
||||
angle_t fineshift = po->angle >> ANGLETOFINESHIFT;
|
||||
|
||||
xoff -= FixedMul(FINECOSINE(fineshift), po->centerPt.x)+FixedMul(FINESINE(fineshift), po->centerPt.y);
|
||||
yoff -= FixedMul(FINESINE(fineshift), po->centerPt.x)-FixedMul(FINECOSINE(fineshift), po->centerPt.y);
|
||||
} else {
|
||||
xoff -= po->centerPt.x;
|
||||
yoff += po->centerPt.y;
|
||||
}
|
||||
|
||||
light = R_GetPlaneLight(frontsector, polysec->ceilingheight, viewz < polysec->ceilingheight);
|
||||
light = 0;
|
||||
ffloor[numffloors].plane = R_FindPlane(polysec->ceilingheight, polysec->ceilingpic,
|
||||
polysec->lightlevel, polysec->ceiling_xoffs, polysec->ceiling_yoffs, polysec->ceilingpic_angle,
|
||||
polysec->lightlevel, xoff, yoff, polysec->ceilingpic_angle-po->angle,
|
||||
NULL, NULL);
|
||||
ffloor[numffloors].plane->polyobj = true;
|
||||
ffloor[numffloors].plane->polyobj = po;
|
||||
|
||||
ffloor[numffloors].polyobj = po;
|
||||
ffloor[numffloors].height = polysec->ceilingheight;
|
||||
// ffloor[numffloors].ffloor = rover;
|
||||
|
|
|
@ -409,6 +409,10 @@ visplane_t *R_FindPlane(fixed_t height, INT32 picnum, INT32 lightlevel,
|
|||
|
||||
for (check = visplanes[hash]; check; check = check->next)
|
||||
{
|
||||
#ifdef POLYOBJECTS_PLANES
|
||||
if (check->polyobj && pfloor)
|
||||
continue;
|
||||
#endif
|
||||
if (height == check->height && picnum == check->picnum
|
||||
&& lightlevel == check->lightlevel
|
||||
&& xoff == check->xoffs && yoff == check->yoffs
|
||||
|
@ -434,6 +438,9 @@ visplane_t *R_FindPlane(fixed_t height, INT32 picnum, INT32 lightlevel,
|
|||
check->viewz = viewz;
|
||||
check->viewangle = viewangle + plangle;
|
||||
check->plangle = plangle;
|
||||
#ifdef POLYOBJECTS_PLANES
|
||||
check->polyobj = NULL;
|
||||
#endif
|
||||
|
||||
memset(check->top, 0xff, sizeof (check->top));
|
||||
memset(check->bottom, 0x00, sizeof (check->bottom));
|
||||
|
@ -666,6 +673,42 @@ void R_DrawSinglePlane(visplane_t *pl)
|
|||
itswater = false;
|
||||
#endif
|
||||
spanfunc = basespanfunc;
|
||||
|
||||
#ifdef POLYOBJECTS_PLANES
|
||||
if (pl->polyobj && pl->polyobj->translucency != 0) {
|
||||
spanfunc = R_DrawTranslucentSpan_8;
|
||||
|
||||
// Hacked up support for alpha value in software mode Tails 09-24-2002 (sidenote: ported to polys 10-15-2014, there was no time travel involved -Red)
|
||||
if (pl->polyobj->translucency >= 10)
|
||||
return; // Don't even draw it
|
||||
else if (pl->polyobj->translucency == 9)
|
||||
ds_transmap = ((tr_trans90)<<FF_TRANSSHIFT) - 0x10000 + transtables;
|
||||
else if (pl->polyobj->translucency == 8)
|
||||
ds_transmap = ((tr_trans80)<<FF_TRANSSHIFT) - 0x10000 + transtables;
|
||||
else if (pl->polyobj->translucency == 7)
|
||||
ds_transmap = ((tr_trans70)<<FF_TRANSSHIFT) - 0x10000 + transtables;
|
||||
else if (pl->polyobj->translucency == 6)
|
||||
ds_transmap = ((tr_trans60)<<FF_TRANSSHIFT) - 0x10000 + transtables;
|
||||
else if (pl->polyobj->translucency == 5)
|
||||
ds_transmap = ((tr_trans50)<<FF_TRANSSHIFT) - 0x10000 + transtables;
|
||||
else if (pl->polyobj->translucency == 4)
|
||||
ds_transmap = ((tr_trans40)<<FF_TRANSSHIFT) - 0x10000 + transtables;
|
||||
else if (pl->polyobj->translucency == 3)
|
||||
ds_transmap = ((tr_trans30)<<FF_TRANSSHIFT) - 0x10000 + transtables;
|
||||
else if (pl->polyobj->translucency == 2)
|
||||
ds_transmap = ((tr_trans20)<<FF_TRANSSHIFT) - 0x10000 + transtables;
|
||||
else if (pl->polyobj->translucency == 1)
|
||||
ds_transmap = ((tr_trans10)<<FF_TRANSSHIFT) - 0x10000 + transtables;
|
||||
else // Opaque, but allow transparent flat pixels
|
||||
spanfunc = splatfunc;
|
||||
|
||||
if (pl->extra_colormap && pl->extra_colormap->fog)
|
||||
light = (pl->lightlevel >> LIGHTSEGSHIFT);
|
||||
else
|
||||
light = LIGHTLEVELS-1;
|
||||
|
||||
} else
|
||||
#endif
|
||||
if (pl->ffloor)
|
||||
{
|
||||
// Don't draw planes that shouldn't be drawn.
|
||||
|
|
|
@ -59,7 +59,7 @@ typedef struct visplane_s
|
|||
|
||||
struct ffloor_s *ffloor;
|
||||
#ifdef POLYOBJECTS_PLANES
|
||||
boolean polyobj;
|
||||
polyobj_t *polyobj;
|
||||
#endif
|
||||
} visplane_t;
|
||||
|
||||
|
|
55
src/r_segs.c
55
src/r_segs.c
|
@ -589,7 +589,8 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2)
|
|||
// draw the texture
|
||||
col = (column_t *)((UINT8 *)R_GetColumn(texnum, maskedtexturecol[dc_x]) - 3);
|
||||
|
||||
#ifdef POLYOBJECTS_PLANES
|
||||
//#ifdef POLYOBJECTS_PLANES
|
||||
#if 0 // Disabling this allows inside edges to render below the planes, for until the clipping is fixed to work right when POs are near the camera. -Red
|
||||
if (curline->dontrenderme && curline->polyseg && (curline->polyseg->flags & POF_RENDERPLANES))
|
||||
{
|
||||
fixed_t my_topscreen;
|
||||
|
@ -611,7 +612,7 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2)
|
|||
|
||||
for (i = 0; i < numffloors; i++)
|
||||
{
|
||||
if (!ffloor[i].polyobj)
|
||||
if (!ffloor[i].polyobj || ffloor[i].polyobj != curline->polyseg)
|
||||
continue;
|
||||
|
||||
if (ffloor[i].height < viewz)
|
||||
|
@ -1120,8 +1121,16 @@ static void R_RenderSegLoop (void)
|
|||
for (i = 0; i < numffloors; i++)
|
||||
{
|
||||
#ifdef POLYOBJECTS_PLANES
|
||||
if (curline->polyseg && !ffloor[i].polyobj)
|
||||
continue;
|
||||
//if (curline->polyseg && (!ffloor[i].polyobj || ffloor[i].polyobj != curline->polyseg))
|
||||
//continue; // Causes issues with FOF planes in The Wall -Red
|
||||
|
||||
// FIXME hack to fix planes disappearing when a seg goes behind the camera. This NEEDS to be changed to be done properly. -Red
|
||||
if (curline->polyseg) {
|
||||
if (ffloor[i].plane->minx > rw_x)
|
||||
ffloor[i].plane->minx = rw_x;
|
||||
else if (ffloor[i].plane->maxx < rw_x)
|
||||
ffloor[i].plane->maxx = rw_x;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (ffloor[i].height < viewz)
|
||||
|
@ -1135,6 +1144,13 @@ static void R_RenderSegLoop (void)
|
|||
if (bottom_w > bottom)
|
||||
bottom_w = bottom;
|
||||
|
||||
#ifdef POLYOBJECTS_PLANES
|
||||
// Polyobject-specific hack to fix plane leaking -Red
|
||||
if (curline->polyseg && ffloor[i].polyobj && ffloor[i].polyobj == curline->polyseg && top_w >= bottom_w) {
|
||||
ffloor[i].plane->top[rw_x] = ffloor[i].plane->bottom[rw_x] = 0xFFFF;
|
||||
} else
|
||||
#endif
|
||||
|
||||
if (top_w <= bottom_w)
|
||||
{
|
||||
ffloor[i].plane->top[rw_x] = (INT16)top_w;
|
||||
|
@ -1152,6 +1168,13 @@ static void R_RenderSegLoop (void)
|
|||
if (bottom_w > bottom)
|
||||
bottom_w = bottom;
|
||||
|
||||
#ifdef POLYOBJECTS_PLANES
|
||||
// Polyobject-specific hack to fix plane leaking -Red
|
||||
if (curline->polyseg && ffloor[i].polyobj && ffloor[i].polyobj == curline->polyseg && top_w >= bottom_w) {
|
||||
ffloor[i].plane->top[rw_x] = ffloor[i].plane->bottom[rw_x] = 0xFFFF;
|
||||
} else
|
||||
#endif
|
||||
|
||||
if (top_w <= bottom_w)
|
||||
{
|
||||
ffloor[i].plane->top[rw_x] = (INT16)top_w;
|
||||
|
@ -1327,9 +1350,9 @@ static void R_RenderSegLoop (void)
|
|||
|
||||
for (i = 0; i < numffloors; i++)
|
||||
{
|
||||
#ifdef POLYOBJECTS_PLANES
|
||||
if (curline->polyseg && !ffloor[i].polyobj)
|
||||
continue;
|
||||
#if 0 //#ifdef POLYOBJECTS_PLANES
|
||||
if (curline->polyseg && (!ffloor[i].polyobj || ffloor[i].polyobj != curline->polyseg))
|
||||
continue; // Causes issues with FOF planes in The Wall -Red
|
||||
#endif
|
||||
|
||||
ffloor[i].f_frac += ffloor[i].f_step;
|
||||
|
@ -1339,9 +1362,9 @@ static void R_RenderSegLoop (void)
|
|||
{
|
||||
INT32 y_w;
|
||||
|
||||
#ifdef POLYOBJECTS_PLANES
|
||||
if (curline->polyseg && !ffloor[i].polyobj)
|
||||
continue;
|
||||
#if 0 //#ifdef POLYOBJECTS_PLANES
|
||||
if (curline->polyseg && (!ffloor[i].polyobj || ffloor[i].polyobj != curline->polyseg))
|
||||
continue; // Causes issues with FOF planes in The Wall -Red
|
||||
#endif
|
||||
y_w = ffloor[i].b_frac >> HEIGHTBITS;
|
||||
|
||||
|
@ -1488,9 +1511,9 @@ void R_StoreWallRange(INT32 start, INT32 stop)
|
|||
{
|
||||
for (i = 0; i < numffloors; i++)
|
||||
{
|
||||
#ifdef POLYOBJECTS_PLANES
|
||||
if (ds_p->curline->polyseg && !ffloor[i].polyobj)
|
||||
continue;
|
||||
#if 0 //#ifdef POLYOBJECTS_PLANES
|
||||
if (ds_p->curline->polyseg && (!ffloor[i].polyobj || ffloor[i].polyobj != ds_p->curline->polyseg))
|
||||
continue; // Causes issues with FOF planes in The Wall -Red
|
||||
#endif
|
||||
ffloor[i].f_pos = ffloor[i].height - viewz;
|
||||
}
|
||||
|
@ -1989,8 +2012,10 @@ void R_StoreWallRange(INT32 start, INT32 stop)
|
|||
{
|
||||
for (i = 0; i < numffloors; i++)
|
||||
{
|
||||
// if (curline->polyseg && !ffloor[i].polyobj)
|
||||
// continue;
|
||||
#if 0 //#ifdef POLYOBJECTS_PLANES
|
||||
if (curline->polyseg && (!ffloor[i].polyobj || ffloor[i].polyobj != curline->polyseg))
|
||||
continue; // Causes issues with FOF planes in The Wall -Red
|
||||
#endif
|
||||
|
||||
ffloor[i].f_pos >>= 4;
|
||||
ffloor[i].f_step = FixedMul(-rw_scalestep, ffloor[i].f_pos);
|
||||
|
|
|
@ -1830,6 +1830,20 @@ static void R_CreateDrawNodes(void)
|
|||
}
|
||||
else if (r2->seg)
|
||||
{
|
||||
#ifdef POLYOBJECTS_PLANES
|
||||
if (r2->seg->curline->polyseg && rover->mobj && P_MobjInsidePolyobj(r2->seg->curline->polyseg, rover->mobj)) {
|
||||
// Determine if we need to sort in front of the polyobj, based on the planes. This fixes the issue where
|
||||
// polyobject planes render above the object standing on them. (A bit hacky... but it works.) -Red
|
||||
mobj_t *mo = rover->mobj;
|
||||
sector_t *po = r2->seg->curline->backsector;
|
||||
|
||||
if (po->ceilingheight < viewz && mo->z+mo->height > po->ceilingheight)
|
||||
continue;
|
||||
|
||||
if (po->floorheight > viewz && mo->z < po->floorheight)
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
if (rover->x1 > r2->seg->x2 || rover->x2 < r2->seg->x1)
|
||||
continue;
|
||||
|
||||
|
|
Loading…
Reference in a new issue