// // R_AddLine // Clips the given segment // and adds any visible pieces to the line list. // static void R_AddLine(const seg_t* segline) { dcol.color = ((segline - segs) & 31) * 4; // [RH] Color if not texturing line drawseg_t ds; wall_t wall; if (!R_ProjectSeg(segline, &ds, &wall, NEARCLIP)) return; R_PrepWall(&ds, &wall); if (R_SolidLineSeg(segline, &wall)) { doorclosed = true; R_ClipWallSegment(ds.x1, ds.x2, true); } else if (!R_EmptyLineSeg(segline, &wall)) { doorclosed = false; R_ClipWallSegment(ds.x1, ds.x2, false); } }
static void R_AddLine (seg_t *line) { int x1; int x2; angle_t angle1; angle_t angle2; angle_t span; angle_t tspan; static sector_t tempsec; // killough 3/8/98: ceiling/water hack // boolean solid = true; curline = line; angle1 = R_PointToAngle (line->v1->x, line->v1->y); angle2 = R_PointToAngle (line->v2->x, line->v2->y); // Clip to view edges. span = angle1 - angle2; // Back side, i.e. backface culling if (span >= ANG180) return; // Global angle needed by segcalc. rw_angle1 = angle1; angle1 -= viewangle; angle2 -= viewangle; tspan = angle1 + clipangle; if (tspan > 2*clipangle) { tspan -= 2*clipangle; // Totally off the left edge? if (tspan >= span) return; angle1 = clipangle; } tspan = clipangle - angle2; if (tspan > 2*clipangle) { tspan -= 2*clipangle; // Totally off the left edge? if (tspan >= span) return; angle2 = -clipangle; } // The seg is in the view range, // but not necessarily visible. angle1 = (angle1+ANG90)>>ANGLETOFINESHIFT; angle2 = (angle2+ANG90)>>ANGLETOFINESHIFT; // killough 1/31/98: Here is where "slime trails" can SOMETIMES occur: x1 = viewangletox[angle1]; x2 = viewangletox[angle2]; // Does not cross a pixel? if (x1 >= x2) // killough 1/31/98 -- change == to >= for robustness return; backsector = line->backsector; /* cph - roll up linedef properties in flags */ if ((linedef = curline->linedef)->r_validcount != gametic) R_RecalcLineFlags(); // Single sided line? if (backsector) // killough 3/8/98, 4/4/98: hack for invisible ceilings / deep water backsector = R_FakeFlat(backsector, &tempsec, NULL, NULL, true); if (linedef->r_flags & RF_IGNORE) return; else R_ClipWallSegment (x1, x2, linedef->r_flags & RF_CLOSED); }
static void R_AddLine (seg_t *line) { int x1; int x2; angle_t angle1; angle_t angle2; angle_t span; angle_t tspan; static sector_t tempsec; // killough 3/8/98: ceiling/water hack curline = line; angle1 = R_PointToAngle (line->v1->x, line->v1->y); angle2 = R_PointToAngle (line->v2->x, line->v2->y); // Clip to view edges. span = angle1 - angle2; // Back side, i.e. backface culling if (span >= ANG180) return; // Global angle needed by segcalc. rw_angle1 = angle1; angle1 -= viewangle; angle2 -= viewangle; tspan = angle1 + clipangle; if (tspan > 2*clipangle) { tspan -= 2*clipangle; // Totally off the left edge? if (tspan >= span) return; angle1 = clipangle; } tspan = clipangle - angle2; if (tspan > 2*clipangle) { tspan -= 2*clipangle; // Totally off the left edge? if (tspan >= span) return; angle2 = 0-clipangle; } // The seg is in the view range, // but not necessarily visible. angle1 = (angle1+ANG90)>>ANGLETOFINESHIFT; angle2 = (angle2+ANG90)>>ANGLETOFINESHIFT; // killough 1/31/98: Here is where "slime trails" can SOMETIMES occur: x1 = viewangletox[angle1]; x2 = viewangletox[angle2]; #ifdef GL_DOOM // proff 11/99: we have to add these segs to avoid gaps in OpenGL if (x1 >= x2) // killough 1/31/98 -- change == to >= for robustness { if (V_GetMode() == VID_MODEGL) { if (ds_p == drawsegs+maxdrawsegs) // killough 1/98 -- fix 2s line HOM { unsigned pos = ds_p - drawsegs; // jff 8/9/98 fix from ZDOOM1.14a unsigned newmax = maxdrawsegs ? maxdrawsegs*2 : 128; // killough drawsegs = realloc(drawsegs,newmax*sizeof(*drawsegs)); //ds_p = drawsegs+maxdrawsegs; ds_p = drawsegs + pos; // jff 8/9/98 fix from ZDOOM1.14a maxdrawsegs = newmax; } ds_p->curline = curline; ds_p++; gld_AddWall(curline); return; } else return; } #else // Does not cross a pixel? if (x1 >= x2) // killough 1/31/98 -- change == to >= for robustness return; #endif backsector = line->backsector; // Single sided line? if (backsector) // killough 3/8/98, 4/4/98: hack for invisible ceilings / deep water backsector = R_FakeFlat(backsector, &tempsec, NULL, NULL, true); /* cph - roll up linedef properties in flags */ if ((linedef = curline->linedef)->r_validcount != gametic) R_RecalcLineFlags(); if (linedef->r_flags & RF_IGNORE) { return; } else R_ClipWallSegment (x1, x2, linedef->r_flags & RF_CLOSED); }
void R_AddLine (seg_t *line) { static sector_t tempsec; // killough 3/8/98: ceiling/water hack bool solid; fixed_t tx1, tx2, ty1, ty2; curline = line; // [RH] Color if not texturing line dc_color = (((int)(line - segs) * 8) + 4) & 255; tx1 = line->v1->x - viewx; tx2 = line->v2->x - viewx; ty1 = line->v1->y - viewy; ty2 = line->v2->y - viewy; // Reject lines not facing viewer if (DMulScale32 (ty1, tx1-tx2, tx1, ty2-ty1) >= 0) return; if (WallC.Init(tx1, ty1, tx2, ty2, 32)) return; if (WallC.sx1 >= WindowRight || WallC.sx2 <= WindowLeft) return; if (line->linedef == NULL) { if (R_CheckClipWallSegment (WallC.sx1, WallC.sx2)) { InSubsector->flags |= SSECF_DRAWN; } return; } // reject lines that aren't seen from the portal (if any) // [ZZ] 10.01.2016: lines inside a skybox shouldn't be clipped, although this imposes some limitations on portals in skyboxes. if (!CurrentPortalInSkybox && CurrentPortal && P_ClipLineToPortal(line->linedef, CurrentPortal->dst, viewx, viewy)) return; vertex_t *v1, *v2; v1 = line->linedef->v1; v2 = line->linedef->v2; if ((v1 == line->v1 && v2 == line->v2) || (v2 == line->v1 && v1 == line->v2)) { // The seg is the entire wall. WallT.InitFromWallCoords(&WallC); } else { // The seg is only part of the wall. if (line->linedef->sidedef[0] != line->sidedef) { swapvalues (v1, v2); } WallT.InitFromLine(v1->x - viewx, v1->y - viewy, v2->x - viewx, v2->y - viewy); } if (!(fake3D & FAKE3D_FAKEBACK)) { backsector = line->backsector; } rw_frontcz1 = frontsector->ceilingplane.ZatPoint (line->v1->x, line->v1->y); rw_frontfz1 = frontsector->floorplane.ZatPoint (line->v1->x, line->v1->y); rw_frontcz2 = frontsector->ceilingplane.ZatPoint (line->v2->x, line->v2->y); rw_frontfz2 = frontsector->floorplane.ZatPoint (line->v2->x, line->v2->y); rw_mustmarkfloor = rw_mustmarkceiling = false; rw_havehigh = rw_havelow = false; // Single sided line? if (backsector == NULL || (line->linedef->isVisualPortal() && line->sidedef == line->linedef->sidedef[0])) { solid = true; } else { // kg3D - its fake, no transfer_heights if (!(fake3D & FAKE3D_FAKEBACK)) { // killough 3/8/98, 4/4/98: hack for invisible ceilings / deep water backsector = R_FakeFlat (backsector, &tempsec, NULL, NULL, true); } doorclosed = 0; // killough 4/16/98 rw_backcz1 = backsector->ceilingplane.ZatPoint (line->v1->x, line->v1->y); rw_backfz1 = backsector->floorplane.ZatPoint (line->v1->x, line->v1->y); rw_backcz2 = backsector->ceilingplane.ZatPoint (line->v2->x, line->v2->y); rw_backfz2 = backsector->floorplane.ZatPoint (line->v2->x, line->v2->y); // Cannot make these walls solid, because it can result in // sprite clipping problems for sprites near the wall if (rw_frontcz1 > rw_backcz1 || rw_frontcz2 > rw_backcz2) { rw_havehigh = true; WallMost (wallupper, backsector->ceilingplane, &WallC); } if (rw_frontfz1 < rw_backfz1 || rw_frontfz2 < rw_backfz2) { rw_havelow = true; WallMost (walllower, backsector->floorplane, &WallC); } // Closed door. if ((rw_backcz1 <= rw_frontfz1 && rw_backcz2 <= rw_frontfz2) || (rw_backfz1 >= rw_frontcz1 && rw_backfz2 >= rw_frontcz2)) { solid = true; } else if ( // properly render skies (consider door "open" if both ceilings are sky): (backsector->GetTexture(sector_t::ceiling) != skyflatnum || frontsector->GetTexture(sector_t::ceiling) != skyflatnum) // if door is closed because back is shut: && rw_backcz1 <= rw_backfz1 && rw_backcz2 <= rw_backfz2 // preserve a kind of transparent door/lift special effect: && ((rw_backcz1 >= rw_frontcz1 && rw_backcz2 >= rw_frontcz2) || line->sidedef->GetTexture(side_t::top).isValid()) && ((rw_backfz1 <= rw_frontfz1 && rw_backfz2 <= rw_frontfz2) || line->sidedef->GetTexture(side_t::bottom).isValid())) { // killough 1/18/98 -- This function is used to fix the automap bug which // showed lines behind closed doors simply because the door had a dropoff. // // It assumes that Doom has already ruled out a door being closed because // of front-back closure (e.g. front floor is taller than back ceiling). // This fixes the automap floor height bug -- killough 1/18/98: // killough 4/7/98: optimize: save result in doorclosed for use in r_segs.c doorclosed = true; solid = true; } else if (frontsector->ceilingplane != backsector->ceilingplane || frontsector->floorplane != backsector->floorplane) { // Window. solid = false; } else if (backsector->lightlevel != frontsector->lightlevel || backsector->GetTexture(sector_t::floor) != frontsector->GetTexture(sector_t::floor) || backsector->GetTexture(sector_t::ceiling) != frontsector->GetTexture(sector_t::ceiling) || curline->sidedef->GetTexture(side_t::mid).isValid() // killough 3/7/98: Take flats offsets into account: || backsector->GetXOffset(sector_t::floor) != frontsector->GetXOffset(sector_t::floor) || backsector->GetYOffset(sector_t::floor) != frontsector->GetYOffset(sector_t::floor) || backsector->GetXOffset(sector_t::ceiling) != frontsector->GetXOffset(sector_t::ceiling) || backsector->GetYOffset(sector_t::ceiling) != frontsector->GetYOffset(sector_t::ceiling) || backsector->GetPlaneLight(sector_t::floor) != frontsector->GetPlaneLight(sector_t::floor) || backsector->GetPlaneLight(sector_t::ceiling) != frontsector->GetPlaneLight(sector_t::ceiling) || backsector->GetFlags(sector_t::floor) != frontsector->GetFlags(sector_t::floor) || backsector->GetFlags(sector_t::ceiling) != frontsector->GetFlags(sector_t::ceiling) // [RH] Also consider colormaps || backsector->ColorMap != frontsector->ColorMap // [RH] and scaling || backsector->GetXScale(sector_t::floor) != frontsector->GetXScale(sector_t::floor) || backsector->GetYScale(sector_t::floor) != frontsector->GetYScale(sector_t::floor) || backsector->GetXScale(sector_t::ceiling) != frontsector->GetXScale(sector_t::ceiling) || backsector->GetYScale(sector_t::ceiling) != frontsector->GetYScale(sector_t::ceiling) // [RH] and rotation || backsector->GetAngle(sector_t::floor) != frontsector->GetAngle(sector_t::floor) || backsector->GetAngle(sector_t::ceiling) != frontsector->GetAngle(sector_t::ceiling) // kg3D - and fake lights || (frontsector->e && frontsector->e->XFloor.lightlist.Size()) || (backsector->e && backsector->e->XFloor.lightlist.Size()) ) { solid = false; } else { // Reject empty lines used for triggers and special events. // Identical floor and ceiling on both sides, identical light levels // on both sides, and no middle texture. // When using GL nodes, do a clipping test for these lines so we can // mark their subsectors as visible for automap texturing. if (hasglnodes && !(InSubsector->flags & SSECF_DRAWN)) { if (R_CheckClipWallSegment(WallC.sx1, WallC.sx2)) { InSubsector->flags |= SSECF_DRAWN; } } return; } } rw_prepped = false; if (line->linedef->special == Line_Horizon) { // Be aware: Line_Horizon does not work properly with sloped planes clearbufshort (walltop+WallC.sx1, WallC.sx2 - WallC.sx1, centery); clearbufshort (wallbottom+WallC.sx1, WallC.sx2 - WallC.sx1, centery); } else { rw_ceilstat = WallMost (walltop, frontsector->ceilingplane, &WallC); rw_floorstat = WallMost (wallbottom, frontsector->floorplane, &WallC); // [RH] treat off-screen walls as solid #if 0 // Maybe later... if (!solid) { if (rw_ceilstat == 12 && line->sidedef->GetTexture(side_t::top) != 0) { rw_mustmarkceiling = true; solid = true; } if (rw_floorstat == 3 && line->sidedef->GetTexture(side_t::bottom) != 0) { rw_mustmarkfloor = true; solid = true; } } #endif } if (R_ClipWallSegment (WallC.sx1, WallC.sx2, solid)) { InSubsector->flags |= SSECF_DRAWN; } }
// // R_AddLine // Clips the given segment // and adds any visible pieces to the line list. // void R_AddLine (seg_t *line) { curline = line; // skip this line if it's not facing the camera if (R_PointOnSegSide(viewx, viewy, line) != 0) return; dcol.color = ((line - segs) & 31) * 4; // [RH] Color if not texturing line // translate the line seg endpoints from world-space to camera-space // and store in (t1.x, t1.y) and (t2.x, t2.y) v2fixed_t t1, t2; R_RotatePoint(line->v1->x - viewx, line->v1->y - viewy, ANG90 - viewangle, t1.x, t1.y); R_RotatePoint(line->v2->x - viewx, line->v2->y - viewy, ANG90 - viewangle, t2.x, t2.y); // Clip the line seg to the viewing window int32_t lclip, rclip; if (!R_ClipLineToFrustum(&t1, &t2, NEARCLIP, lclip, rclip)) return; // apply the view frustum clipping to t1 & t2 R_ClipLine(&t1, &t2, lclip, rclip, &t1, &t2); // project the line endpoints to determine which columns the line seg occupies int x1 = R_ProjectPointX(t1.x, t1.y); int x2 = R_ProjectPointX(t2.x, t2.y) - 1; if (!R_CheckProjectionX(x1, x2)) return; rw_start = x1; rw_stop = x2; // clip the line seg endpoints in world-space // and store in (w1.x, w1.y) and (w2.x, w2.y) v2fixed_t w1, w2; R_ClipLine(line->v1, line->v2, lclip, rclip, &w1, &w2); // killough 3/8/98, 4/4/98: hack for invisible ceilings / deep water static sector_t tempsec; backsector = line->backsector ? R_FakeFlat(line->backsector, &tempsec, NULL, NULL, true) : NULL; R_PrepWall(w1.x, w1.y, w2.x, w2.y, t1.y, t2.y, x1, x2); // [SL] Check for single-sided line, closed doors or other scenarios that // would make this line seg solid. // // This fixes the automap floor height bug -- killough 1/18/98: // killough 4/7/98: optimize: save result in doorclosed for use in r_segs.c if (!backsector || !(line->linedef->flags & ML_TWOSIDED) || (rw_backcz1 <= rw_frontfz1 && rw_backcz2 <= rw_frontfz2) || (rw_backfz1 >= rw_frontcz1 && rw_backfz2 >= rw_frontcz2) || // if door is closed because back is shut: ((rw_backcz1 <= rw_backfz1 && rw_backcz2 <= rw_backfz2) && // preserve a kind of transparent door/lift special effect: ((rw_backcz1 >= rw_frontcz1 && rw_backcz2 >= rw_frontcz2) || line->sidedef->toptexture) && ((rw_backfz1 <= rw_frontfz1 && rw_backfz2 <= rw_frontfz2) || line->sidedef->bottomtexture) && // properly render skies (consider door "open" if both ceilings are sky): (backsector->ceilingpic !=skyflatnum || frontsector->ceilingpic!=skyflatnum))) { doorclosed = true; R_ClipWallSegment(x1, x2, true); return; } // Reject empty lines used for triggers and special events. // Identical floor and ceiling on both sides, // identical light levels on both sides, and no middle texture. if (P_IdenticalPlanes(&frontsector->ceilingplane, &backsector->ceilingplane) && P_IdenticalPlanes(&frontsector->floorplane, &backsector->floorplane) && backsector->lightlevel == frontsector->lightlevel && backsector->floorpic == frontsector->floorpic && backsector->ceilingpic == frontsector->ceilingpic && curline->sidedef->midtexture == 0 // killough 3/7/98: Take flats offsets into account: && backsector->floor_xoffs == frontsector->floor_xoffs && (backsector->floor_yoffs + backsector->base_floor_yoffs) == (frontsector->floor_yoffs + backsector->base_floor_yoffs) && backsector->ceiling_xoffs == frontsector->ceiling_xoffs && (backsector->ceiling_yoffs + backsector->base_ceiling_yoffs) == (frontsector->ceiling_yoffs + frontsector->base_ceiling_yoffs) // killough 4/16/98: consider altered lighting && backsector->floorlightsec == frontsector->floorlightsec && backsector->ceilinglightsec == frontsector->ceilinglightsec // [RH] Also consider colormaps && backsector->colormap == frontsector->colormap // [RH] and scaling && backsector->floor_xscale == frontsector->floor_xscale && backsector->floor_yscale == frontsector->floor_yscale && backsector->ceiling_xscale == frontsector->ceiling_xscale && backsector->ceiling_yscale == frontsector->ceiling_yscale // [RH] and rotation && (backsector->floor_angle + backsector->base_floor_angle) == (frontsector->floor_angle + frontsector->base_floor_angle) && (backsector->ceiling_angle + backsector->base_ceiling_angle) == (frontsector->ceiling_angle + frontsector->base_ceiling_angle) ) { return; } doorclosed = false; R_ClipWallSegment(x1, x2, false); }
static void R_AddLine (seg_t *line) { int x1; int x2; angle_t angle1; angle_t angle2; angle_t span; angle_t tspan; static sector_t tempsec; curline = line; angle1 = R_PointToAngle(line->v1->x, line->v1->y); angle2 = R_PointToAngle(line->v2->x, line->v2->y); span = angle1 - angle2; if (span >= ANG180) return; rw_angle1 = angle1; angle1 -= viewangle; angle2 -= viewangle; tspan = angle1 + clipangle; if (tspan > 2 * clipangle) { tspan -= 2 * clipangle; if (tspan >= span) return; angle1 = clipangle; } tspan = clipangle - angle2; if (tspan > 2 * clipangle) { tspan -= 2 * clipangle; if (tspan >= span) return; angle2 = 0-clipangle; } angle1 = (angle1 + ANG90) >> ANGLETOFINESHIFT; angle2 = (angle2 + ANG90) >> ANGLETOFINESHIFT; x1 = viewangletox[angle1]; x2 = viewangletox[angle2]; if (x1 >= x2) return; backsector = line->backsector; if (backsector) backsector = R_FakeFlat(backsector, &tempsec, NULL, NULL, true); if ((linedef = curline->linedef)->r_validcount != gametic) R_RecalcLineFlags(); if (linedef->r_flags & RF_IGNORE) return; else R_ClipWallSegment (x1, x2, linedef->r_flags & RF_CLOSED); }
static void R_AddLine (seg_t *line) { int x1; int x2; angle_t angle1; angle_t angle2; angle_t span; angle_t tspan; static sector_t tempsec; // killough 3/8/98: ceiling/water hack curline = line; angle1 = R_GetVertexViewAngle(line->v1); angle2 = R_GetVertexViewAngle(line->v2); #ifdef GL_DOOM if (V_GetMode() == VID_MODEGL) { if (curline->linedef->r_flags & RF_IGNORE_CURRENT) return; // Back side, i.e. backface culling - read: endAngle >= startAngle! if (angle2 - angle1 < ANG180 || !line->linedef) { return; } if (!gld_clipper_SafeCheckRange(angle2, angle1)) { return; } map_subsectors[currentsubsectornum] = 1; if (!line->backsector) { gld_clipper_SafeAddClipRange(angle2, angle1); } else { if (line->frontsector == line->backsector) { if (texturetranslation[line->sidedef->midtexture] == NO_TEXTURE) { //e6y: nothing to do here! return; } } if (CheckClip(line, line->frontsector, line->backsector)) { gld_clipper_SafeAddClipRange(angle2, angle1); } } if (ds_p == drawsegs+maxdrawsegs) // killough 1/98 -- fix 2s line HOM { unsigned pos = ds_p - drawsegs; // jff 8/9/98 fix from ZDOOM1.14a unsigned newmax = maxdrawsegs ? maxdrawsegs*2 : 128; // killough drawsegs = realloc(drawsegs,newmax*sizeof(*drawsegs)); ds_p = drawsegs + pos; // jff 8/9/98 fix from ZDOOM1.14a maxdrawsegs = newmax; } if(curline->miniseg == false) // figgi -- skip minisegs curline->linedef->flags |= ML_MAPPED; // proff 11/99: the rest of the calculations is not needed for OpenGL ds_p++->curline = curline; gld_AddWall(curline); return; } #endif // Clip to view edges. span = angle1 - angle2; // Back side, i.e. backface culling if (span >= ANG180) return; // Global angle needed by segcalc. rw_angle1 = angle1; angle1 -= viewangle; angle2 -= viewangle; tspan = angle1 + clipangle; if (tspan > 2*clipangle) { tspan -= 2*clipangle; // Totally off the left edge? if (tspan >= span) return; angle1 = clipangle; } tspan = clipangle - angle2; if (tspan > 2*clipangle) { tspan -= 2*clipangle; // Totally off the left edge? if (tspan >= span) return; angle2 = 0-clipangle; } // The seg is in the view range, // but not necessarily visible. angle1 = (angle1+ANG90)>>ANGLETOFINESHIFT; angle2 = (angle2+ANG90)>>ANGLETOFINESHIFT; // killough 1/31/98: Here is where "slime trails" can SOMETIMES occur: x1 = viewangletox[angle1]; x2 = viewangletox[angle2]; // Does not cross a pixel? if (x1 >= x2) // killough 1/31/98 -- change == to >= for robustness return; backsector = line->backsector; // Single sided line? if (backsector) // killough 3/8/98, 4/4/98: hack for invisible ceilings / deep water backsector = R_FakeFlat(backsector, &tempsec, NULL, NULL, true); /* cph - roll up linedef properties in flags */ if ((linedef = curline->linedef)->r_validcount != gametic) R_RecalcLineFlags(linedef); if (linedef->r_flags & RF_IGNORE_CURRENT) { return; } else R_ClipWallSegment (x1, x2, linedef->r_flags & RF_CLOSED); }