示例#1
0
文件: r_bsp.c 项目: twinaphex/sdcell
static dboolean CheckClip(seg_t * seg, sector_t * frontsector, sector_t * backsector)
{
  static sector_t tempsec_back, tempsec_front;

  backsector = R_FakeFlat(backsector, &tempsec_back, NULL, NULL, true);
  frontsector = R_FakeFlat(frontsector, &tempsec_front, NULL, NULL, false);

  // check for closed sectors!
  if (backsector->ceilingheight <= frontsector->floorheight) 
  {
    if (seg->sidedef->toptexture == NO_TEXTURE)
      return false;

    if (backsector->ceilingpic == skyflatnum && frontsector->ceilingpic == skyflatnum)
      return false;

    return true;
  }

  if (frontsector->ceilingheight <= backsector->floorheight) 
  {
    if (seg->sidedef->bottomtexture == NO_TEXTURE)
      return false;

    // properly render skies (consider door "open" if both floors are sky):
    if (backsector->ceilingpic == skyflatnum && frontsector->ceilingpic == skyflatnum)
      return false;

    return true;
  }

  if (backsector->ceilingheight <= backsector->floorheight)
  {
    // preserve a kind of transparent door/lift special effect:
    if (backsector->ceilingheight < frontsector->ceilingheight) 
    {
      if (seg->sidedef->toptexture == NO_TEXTURE)
        return false;
    }
    if (backsector->floorheight > frontsector->floorheight)
    {
      if (seg->sidedef->bottomtexture == NO_TEXTURE)
        return false;
    }
    if (backsector->ceilingpic == skyflatnum && frontsector->ceilingpic == skyflatnum)
      return false;

    if (backsector->floorpic == skyflatnum && frontsector->floorpic == skyflatnum)
      return false;

    return true;
  }

  return false;
}
示例#2
0
void GL_RecalcSeg(seg_t *seg, sector_t *controlSector)
{
   int index;
   bool fogBoundary = false;
   sector_t *backSector, ts;

   index = numsubsectors * 2;
   index += (seg - segs) * 3;

   backSector = R_FakeFlat(seg->backsector, &ts, NULL, NULL, false);
   if (backSector)
   {
      fogBoundary = IsFogBoundary(controlSector, backSector);
   }

   if (seg->linedef && seg->sidedef)
   {
      if (seg->backsector && seg->sidedef->toptexture)
      {
         GL_RecalcUpperWall(seg, controlSector, gl_polys + index);
      }

      if (seg->sidedef->midtexture || fogBoundary)
      {
         GL_RecalcMidWall(seg, controlSector, gl_polys + (index + 1));
      }

      if (seg->backsector && seg->sidedef->bottomtexture)
      {
         GL_RecalcLowerWall(seg, controlSector, gl_polys + (index + 2));
      }
   }
}
示例#3
0
文件: r_bsp.c 项目: bnied/doomretro
//
// R_Subsector
// Determine floor/ceiling planes.
// Add sprites of things in sector.
// Draw one or more line segments.
//
static void R_Subsector(int num)
{
    subsector_t *sub = &subsectors[num];
    sector_t    tempsec;              // killough 3/7/98: deep water hack
    int         floorlightlevel;      // killough 3/16/98: set floor lightlevel
    int         ceilinglightlevel;    // killough 4/11/98
    int         count = sub->numlines;
    seg_t       *line = &segs[sub->firstline];

    frontsector = sub->sector;

    // [AM] Interpolate sector movement. Usually only needed
    //      when you're standing inside the sector.
    R_MaybeInterpolateSector(frontsector);

    // killough 3/8/98, 4/4/98: Deep water / fake ceiling effect
    frontsector = R_FakeFlat(frontsector, &tempsec, &floorlightlevel, &ceilinglightlevel, false);

    floorplane = (frontsector->interpfloorheight < viewz        // killough 3/7/98
        || (frontsector->heightsec != -1
        && sectors[frontsector->heightsec].ceilingpic == skyflatnum) ?
        R_FindPlane(frontsector->interpfloorheight,
            (frontsector->floorpic == skyflatnum                // killough 10/98
                && (frontsector->sky & PL_SKYFLAT) ? frontsector->sky : frontsector->floorpic),
            floorlightlevel,                                    // killough 3/16/98
            frontsector->floor_xoffs,                           // killough 3/7/98
            frontsector->floor_yoffs) : NULL);

    ceilingplane = (frontsector->interpceilingheight > viewz
        || frontsector->ceilingpic == skyflatnum
        || (frontsector->heightsec != -1
        && sectors[frontsector->heightsec].floorpic == skyflatnum) ?
        R_FindPlane(frontsector->interpceilingheight,           // killough 3/8/98
            (frontsector->ceilingpic == skyflatnum              // killough 10/98
                && (frontsector->sky & PL_SKYFLAT) ? frontsector->sky : frontsector->ceilingpic),
            ceilinglightlevel,                                  // killough 4/11/98
            frontsector->ceiling_xoffs,                         // killough 3/7/98
            frontsector->ceiling_yoffs) : NULL);

    // killough 9/18/98: Fix underwater slowdown, by passing real sector
    // instead of fake one. Improve sprite lighting by basing sprite
    // lightlevels on floor & ceiling lightlevels in the surrounding area.
    //
    // 10/98 killough:
    //
    // NOTE: TeamTNT fixed this bug incorrectly, messing up sprite lighting!!!
    // That is part of the 242 effect!!! If you simply pass sub->sector to
    // the old code you will not get correct lighting for underwater sprites!!!
    // Either you must pass the fake sector and handle validcount here, on the
    // real sector, or you must account for the lighting in some other way,
    // like passing it as an argument.
    if (sub->sector->validcount != validcount)
    {
        sub->sector->validcount = validcount;
        R_AddSprites(sub->sector, floorlightlevel);
    }

    while (count--)
        R_AddLine(line++);
}
示例#4
0
文件: r_bsp.c 项目: jezze/doom
static void R_Subsector(int num)
{

    subsector_t *sub = &subsectors[num];
    int count = sub->numlines;
    seg_t *line = &segs[sub->firstline];
    sector_t tempsec;
    int floorlightlevel;
    int ceilinglightlevel;

    frontsector = sub->sector;
    frontsector = R_FakeFlat(frontsector, &tempsec, &floorlightlevel, &ceilinglightlevel, false);
    floorplane = frontsector->floorheight < viewz || (frontsector->heightsec != -1 && sectors[frontsector->heightsec].ceilingpic == skyflatnum) ? R_FindPlane(frontsector->floorheight, frontsector->floorpic == skyflatnum && frontsector->sky & PL_SKYFLAT ? frontsector->sky : frontsector->floorpic, floorlightlevel, frontsector->floor_xoffs, frontsector->floor_yoffs) : NULL;
    ceilingplane = frontsector->ceilingheight > viewz || frontsector->ceilingpic == skyflatnum || (frontsector->heightsec != -1 && sectors[frontsector->heightsec].floorpic == skyflatnum) ? R_FindPlane(frontsector->ceilingheight, frontsector->ceilingpic == skyflatnum && frontsector->sky & PL_SKYFLAT ? frontsector->sky : frontsector->ceilingpic, ceilinglightlevel, frontsector->ceiling_xoffs, frontsector->ceiling_yoffs) : NULL;

    R_AddSprites(sub, (floorlightlevel + ceilinglightlevel) / 2);

    while (count--)
    {

        if (line->miniseg == false)
            R_AddLine(line);

        line++;
        curline = NULL;

    }

}
示例#5
0
void GL_RecalcMidWall(seg_t *seg, sector_t *frontSector, gl_poly_t *poly)
{
   float height1, height2, v1[5], v2[5], v3[5], v4[5], txScale, tyScale;
   float yOffset1, yOffset2, yOffset, xOffset;
   float upperHeight, lowerHeight;
   float tmpOffset = seg->sidedef->rowoffset * INV_FRACUNIT;
   long offset = 0;
   int texHeight;
   FTexture *tex = NULL;
   texcoord_t ll, ul, lr, ur;
   sector_t *backSector, ts2;
   vertex_t *vert1, *vert2;

   if (!poly->initialized) GL_InitPolygon(poly);
   poly->lastUpdate = frameStartMS;
   poly->initialized = true;

   tex = TexMan(seg->sidedef->midtexture);

   vert1 = seg->v1;
   vert2 = seg->v2;

   backSector = R_FakeFlat(seg->backsector, &ts2, NULL, NULL, false);

   v1[0] = -vert1->x * MAP_SCALE;
   v1[2] = vert1->y * MAP_SCALE;
   v2[0] = -vert2->x * MAP_SCALE;
   v2[2] = vert2->y * MAP_SCALE;
   v1[1] = (float)frontSector->floorplane.ZatPoint(seg->v1);
   v2[1] = (float)frontSector->floorplane.ZatPoint(seg->v2);

   if ((seg->linedef->special == Line_Mirror && seg->backsector == NULL) || tex == NULL)
   {
      if (backSector)
      {
         height1 = (float)backSector->ceilingplane.ZatPoint(vert1);
         height2 = (float)backSector->ceilingplane.ZatPoint(vert2);
      }
      else
      {
         height1 = (float)frontSector->ceilingplane.ZatPoint(vert1);
         height2 = (float)frontSector->ceilingplane.ZatPoint(vert2);
      }
   }
   else
   {
      //yOffset = seg->sidedef->rowoffset * INV_FRACUNIT;
      yOffset = 0.f;
      tmpOffset = 0.f;
      offset = seg->sidedef->rowoffset;
      yOffset1 = yOffset2 = yOffset;

      // texscale: 8 = 1.0, 16 = 2.0, 4 = 0.5
      txScale = tex->ScaleX ? tex->ScaleX / 8.f : 1.f;
      tyScale = tex->ScaleY ? tex->ScaleY / 8.f : 1.f;

      xOffset = (seg->offset * txScale) * INV_FRACUNIT;
   
      texHeight = (int)(tex->GetHeight() / tyScale);
      textureList.GetTexture(seg->sidedef->midtexture, true);

      ll.x = xOffset / tex->GetWidth();
      ul.x = ll.x;
      lr.x = ll.x + (seg->length / tex->GetWidth() * txScale);
      ur.x = lr.x;

      if (backSector)
      {
         height1 = (float)MIN(frontSector->ceilingplane.ZatPoint(vert1), backSector->ceilingplane.ZatPoint(vert1));
         height2 = (float)MIN(frontSector->ceilingplane.ZatPoint(vert2), backSector->ceilingplane.ZatPoint(vert2));
      }
      else
      {
         height1 = (float)frontSector->ceilingplane.ZatPoint(vert1);
         height2 = (float)frontSector->ceilingplane.ZatPoint(vert2);
      }

      if (backSector && (textureList.IsTransparent() || seg->linedef->flags & ML_TWOSIDED))
      {
         int h = texHeight;

#if 0
         if (seg->linedef->flags & ML_DONTPEGBOTTOM)
         {
            if (backSector)
            {
               v1[1] = MAX (frontSector->floortexz, backSector->floortexz) + offset;
               v2[1] = MAX (frontSector->floortexz, backSector->floortexz) + offset;
            }
            else
            {
               v1[1] = frontSector->floortexz + offset;
               v2[1] = frontSector->floortexz + offset;
            }
         }
         else
         {
            if (backSector)
            {
               v1[1] = MIN (frontSector->ceilingtexz, backSector->ceilingtexz) + offset - (h << FRACBITS);
               v2[1] = MIN (frontSector->ceilingtexz, backSector->ceilingtexz) + offset - (h << FRACBITS);
            }
            else
            {
               v1[1] = frontSector->ceilingtexz + offset - (h << FRACBITS);
               v2[1] = frontSector->ceilingtexz + offset - (h << FRACBITS);
            }
         }

         height1 = (h << FRACBITS) + v1[1];
         height2 = (h << FRACBITS) + v2[1];
#else
         float rbceil = (float)backSector->ceilingtexz,
				rbfloor = (float)backSector->floortexz,
				rfceil = (float)frontSector->ceilingtexz,
				rffloor = (float)frontSector->floortexz;
			float gaptop, gapbottom;

         yOffset = (float)seg->sidedef->rowoffset;
         height1 = gaptop = MIN(rbceil, rfceil);
         v1[1] = gapbottom = MAX(rbfloor, rffloor);

         if (seg->linedef->flags & ML_DONTPEGBOTTOM)
         {
            v1[1] += yOffset;
            height1 = v1[1] + (tex->GetHeight() * FRACUNIT);
         }
         else
         {
            height1 += yOffset;
            v1[1] = height1 - (tex->GetHeight() * FRACUNIT);
         }

         height2 = height1;
         v2[1] = v1[1];
#endif
      }
   }

   // make sure to clip the geometry to the back sector...
   if (backSector)
   {
      if (seg->sidedef->bottomtexture)
      {
         v1[1] = MAX(v1[1], backSector->floorplane.ZatPoint(seg->v1));
         v2[1] = MAX(v2[1], backSector->floorplane.ZatPoint(seg->v2));
      }
      if (seg->sidedef->toptexture)
      {
         height1 = MIN(height1, backSector->ceilingplane.ZatPoint(seg->v1));
         height2 = MIN(height2, backSector->ceilingplane.ZatPoint(seg->v2));
      }
   }

   memcpy(v3, v1, sizeof(float) * 3);
   memcpy(v4, v2, sizeof(float) * 3);

   ul.y = ur.y = 1.f;
   ll.y = lr.y = 0.f;

   if (tex)
   {
      yOffset = 0.f;

      // code borrowed from Legacy ;)
      // damn pegged/unpegged/two sided lines!
      if (backSector)
      {
         float worldHigh = backSector->ceilingtexz * INV_FRACUNIT;
         float worldLow = backSector->floortexz * INV_FRACUNIT;
         float polyBottom, polyTop;

         lowerHeight = frontSector->floortexz * INV_FRACUNIT;
         upperHeight = frontSector->ceilingtexz * INV_FRACUNIT;

         float openTop = upperHeight < worldHigh ? upperHeight : worldHigh;
         float openBottom = lowerHeight > worldLow ? lowerHeight : worldLow;

         if (seg->linedef->flags & ML_DONTPEGBOTTOM)
         {
            polyBottom = openBottom + seg->sidedef->rowoffset * INV_FRACUNIT;
            polyTop = polyBottom + texHeight;

            upperHeight = MIN(openTop, polyTop);
            lowerHeight = MAX(openBottom, polyBottom);

            yOffset = lowerHeight + texHeight - upperHeight + polyBottom - lowerHeight;
         }
         else
         {
            polyTop = openTop + seg->sidedef->rowoffset * INV_FRACUNIT;
            polyBottom = polyTop - texHeight;

            yOffset = polyTop - upperHeight;
         }
      }
      else
      {
         lowerHeight = frontSector->floortexz * INV_FRACUNIT;
         upperHeight = frontSector->ceilingtexz * INV_FRACUNIT;
         yOffset = 0.f;

         if (seg->linedef->flags & ML_DONTPEGBOTTOM)
         {
            yOffset += lowerHeight + texHeight - upperHeight;
         }
      }

      ll.y = lr.y = yOffset / texHeight;
      ul.y = ur.y = ll.y + ((upperHeight - lowerHeight) / texHeight);

      // scale the coordinates
      //ul.y *= tyScale;
      //ur.y *= tyScale;
      //ll.y *= tyScale;
      //lr.y *= tyScale;

      // clip to slopes
      ul.y -= ((v1[1] * INV_FRACUNIT) - lowerHeight) / texHeight;
      ur.y -= ((v2[1] * INV_FRACUNIT) - lowerHeight) / texHeight;
      ll.y += (upperHeight - (height1 * INV_FRACUNIT)) / texHeight;
      lr.y += (upperHeight - (height2 * INV_FRACUNIT)) / texHeight;
   }

   v1[1] *= MAP_SCALE;
   v2[1] *= MAP_SCALE;
   v3[1] = height1 * MAP_SCALE;
   v4[1] = height2 * MAP_SCALE;

   v1[3] = ul.x; v1[4] = ul.y;
   v2[3] = ur.x; v2[4] = ur.y;
   v3[3] = ll.x; v3[4] = ll.y;
   v4[3] = lr.x; v4[4] = lr.y;

   memcpy(poly->vertices + (0 * 3), v3, sizeof(float) * 3);
   memcpy(poly->vertices + (1 * 3), v1, sizeof(float) * 3);
   memcpy(poly->vertices + (2 * 3), v2, sizeof(float) * 3);
   memcpy(poly->vertices + (3 * 3), v4, sizeof(float) * 3);

   memcpy(poly->texCoords + (0 * 2), v3 + 3, sizeof(float) * 2);
   memcpy(poly->texCoords + (1 * 2), v1 + 3, sizeof(float) * 2);
   memcpy(poly->texCoords + (2 * 2), v2 + 3, sizeof(float) * 2);
   memcpy(poly->texCoords + (3 * 2), v4 + 3, sizeof(float) * 2);
}
示例#6
0
文件: r_bsp.cpp 项目: Edward850/zdoom
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;
	}
}
示例#7
0
文件: r_bsp.c 项目: Yukitty/SRB2
//
// R_AddLine
// Clips the given segment and adds any visible pieces to the line list.
//
static void R_AddLine(seg_t *line)
{
	INT32 x1, x2;
	angle_t angle1, angle2, span, tspan;
	static sector_t tempsec; // ceiling/water hack

	if (line->polyseg && !(line->polyseg->flags & POF_RENDERSIDES))
		return;

	curline = line;

	// OPTIMIZE: quickly reject orthogonal back sides.
	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 >= ANGLE_180)
		return;

	// Global angle needed by segcalc.
	rw_angle1 = angle1;
	angle1 -= viewangle;
	angle2 -= viewangle;

	tspan = angle1 + clipangle;
	if (tspan > doubleclipangle)
	{
		tspan -= doubleclipangle;

		// Totally off the left edge?
		if (tspan >= span)
			return;

		angle1 = clipangle;
	}
	tspan = clipangle - angle2;
	if (tspan > doubleclipangle)
	{
		tspan -= doubleclipangle;

		// Totally off the left edge?
		if (tspan >= span)
			return;

		angle2 = -(signed)clipangle;
	}

	// The seg is in the view range, but not necessarily visible.
	angle1 = (angle1+ANGLE_90)>>ANGLETOFINESHIFT;
	angle2 = (angle2+ANGLE_90)>>ANGLETOFINESHIFT;
	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;

	// Portal line
	if (line->linedef->special == 40 && P_PointOnLineSide(viewx, viewy, line->linedef) == 0)
	{
		if (portalrender < cv_maxportals.value)
		{
			// Find the other side!
			INT32 line2 = P_FindSpecialLineFromTag(40, line->linedef->tag, -1);
			if (line->linedef == &lines[line2])
				line2 = P_FindSpecialLineFromTag(40, line->linedef->tag, line2);
			if (line2 >= 0) // found it!
			{
				R_AddPortal(line->linedef-lines, line2, x1, x2); // Remember the lines for later rendering
				//return; // Don't fill in that space now!
				goto clipsolid;
			}
		}
		// Recursed TOO FAR (viewing a portal within a portal)
		// So uhhh, render it as a normal wall instead or something ???
	}

	// Single sided line?
	if (!backsector)
		goto clipsolid;

	backsector = R_FakeFlat(backsector, &tempsec, NULL, NULL, true);

	doorclosed = 0;

	// Closed door.
#ifdef ESLOPE
	// Just don't bother checking this if one side is sloped. This is probably inefficient, but it's better than
	// random renderer stopping around slopes...
	if (!(frontsector->f_slope || frontsector->c_slope || backsector->f_slope || backsector->c_slope))
#endif
	if (backsector->ceilingheight <= frontsector->floorheight
		|| backsector->floorheight >= frontsector->ceilingheight)
	{
		goto clipsolid;
	}

	// Check for automap fix. Store in doorclosed for r_segs.c
	doorclosed = R_DoorClosed();
	if (doorclosed)
		goto clipsolid;

	// Window.
	if (backsector->ceilingheight != frontsector->ceilingheight
		|| backsector->floorheight != frontsector->floorheight)
	{
		goto clippass;
	}

	// 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 (
#ifdef POLYOBJECTS
		!line->polyseg &&
#endif
		backsector->ceilingpic == frontsector->ceilingpic
		&& backsector->floorpic == frontsector->floorpic
#ifdef ESLOPE
		&& backsector->f_slope == frontsector->f_slope
		&& backsector->c_slope == frontsector->c_slope
#endif
		&& backsector->lightlevel == frontsector->lightlevel
		&& !curline->sidedef->midtexture
		// Check offsets too!
		&& backsector->floor_xoffs == frontsector->floor_xoffs
		&& backsector->floor_yoffs == frontsector->floor_yoffs
		&& backsector->floorpic_angle == frontsector->floorpic_angle
		&& backsector->ceiling_xoffs == frontsector->ceiling_xoffs
		&& backsector->ceiling_yoffs == frontsector->ceiling_yoffs
		&& backsector->ceilingpic_angle == frontsector->ceilingpic_angle
		// Consider altered lighting.
		&& backsector->floorlightsec == frontsector->floorlightsec
		&& backsector->ceilinglightsec == frontsector->ceilinglightsec
		// Consider colormaps
		&& backsector->extra_colormap == frontsector->extra_colormap
		&& ((!frontsector->ffloors && !backsector->ffloors)
		|| frontsector->tag == backsector->tag))
	{
		return;
	}


clippass:
	R_ClipPassWallSegment(x1, x2 - 1);
	return;

clipsolid:
	R_ClipSolidWallSegment(x1, x2 - 1);
}
示例#8
0
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);
}
示例#9
0
文件: r_bsp.c 项目: Arc0re/prboom3ds
static void R_Subsector(int num)
{
  int         count;
  seg_t       *line;
  subsector_t *sub;
  sector_t    tempsec;              // killough 3/7/98: deep water hack
  int         floorlightlevel;      // killough 3/16/98: set floor lightlevel
  int         ceilinglightlevel;    // killough 4/11/98
#ifdef GL_DOOM
  visplane_t dummyfloorplane;
  visplane_t dummyceilingplane;
#endif

#ifdef RANGECHECK
  if (num>=numsubsectors)
    I_Error ("R_Subsector: ss %i with numss = %i", num, numsubsectors);
#endif

  sub = &subsectors[num];
  frontsector = sub->sector;
  count = sub->numlines;
  line = &segs[sub->firstline];

  // killough 3/8/98, 4/4/98: Deep water / fake ceiling effect
  frontsector = R_FakeFlat(frontsector, &tempsec, &floorlightlevel,
                           &ceilinglightlevel, false);   // killough 4/11/98

  // killough 3/7/98: Add (x,y) offsets to flats, add deep water check
  // killough 3/16/98: add floorlightlevel
  // killough 10/98: add support for skies transferred from sidedefs

  floorplane = frontsector->floorheight < viewz || // killough 3/7/98
    (frontsector->heightsec != -1 &&
     sectors[frontsector->heightsec].ceilingpic == skyflatnum) ?
    R_FindPlane(frontsector->floorheight,
                frontsector->floorpic == skyflatnum &&  // kilough 10/98
                frontsector->sky & PL_SKYFLAT ? frontsector->sky :
                frontsector->floorpic,
                floorlightlevel,                // killough 3/16/98
                frontsector->floor_xoffs,       // killough 3/7/98
                frontsector->floor_yoffs
                ) : NULL;

  ceilingplane = frontsector->ceilingheight > viewz ||
    frontsector->ceilingpic == skyflatnum ||
    (frontsector->heightsec != -1 &&
     sectors[frontsector->heightsec].floorpic == skyflatnum) ?
    R_FindPlane(frontsector->ceilingheight,     // killough 3/8/98
                frontsector->ceilingpic == skyflatnum &&  // kilough 10/98
                frontsector->sky & PL_SKYFLAT ? frontsector->sky :
                frontsector->ceilingpic,
                ceilinglightlevel,              // killough 4/11/98
                frontsector->ceiling_xoffs,     // killough 3/7/98
                frontsector->ceiling_yoffs
                ) : NULL;
#ifdef GL_DOOM
  // check if the sector is faked
  if ((frontsector==sub->sector)  && (V_GetMode() == VID_MODEGL))
  {
    // if the sector has bottomtextures, then the floorheight will be set to the
    // highest surounding floorheight
    if ((frontsector->no_bottomtextures) || (!floorplane))
    {
      int i=frontsector->linecount;

      dummyfloorplane.height=INT_MIN;
      while (i--)
      {
        line_t *tmpline=frontsector->lines[i];
        if (tmpline->backsector)
          if (tmpline->backsector != frontsector)
            if (tmpline->backsector->floorheight>dummyfloorplane.height)
            {
              dummyfloorplane.height=tmpline->backsector->floorheight;
              dummyfloorplane.lightlevel=tmpline->backsector->lightlevel;
            }
        if (tmpline->frontsector)
          if (tmpline->frontsector != frontsector)
            if (tmpline->frontsector->floorheight>dummyfloorplane.height)
            {
              dummyfloorplane.height=tmpline->frontsector->floorheight;
              dummyfloorplane.lightlevel=tmpline->frontsector->lightlevel;
            }
      }
      if (dummyfloorplane.height!=INT_MIN)
        floorplane=&dummyfloorplane;
    }
    // the same for ceilings. they will be set to the lowest ceilingheight
    if ((frontsector->no_toptextures) || (!ceilingplane))
    {
      int i=frontsector->linecount;

      dummyceilingplane.height=INT_MAX;
      while (i--)
      {
        line_t *tmpline=frontsector->lines[i];
        if (tmpline->backsector)
          if (tmpline->backsector != frontsector)
            if (tmpline->backsector->ceilingheight<dummyceilingplane.height)
            {
              dummyceilingplane.height=tmpline->backsector->ceilingheight;
              dummyceilingplane.lightlevel=tmpline->backsector->lightlevel;
            }
        if (tmpline->frontsector)
          if (tmpline->frontsector != frontsector)
            if (tmpline->frontsector->ceilingheight<dummyceilingplane.height)
            {
              dummyceilingplane.height=tmpline->frontsector->ceilingheight;
              dummyceilingplane.lightlevel=tmpline->frontsector->lightlevel;
            }
      }
      if (dummyceilingplane.height!=INT_MAX)
        ceilingplane=&dummyceilingplane;
    }
  }
#endif

  // killough 9/18/98: Fix underwater slowdown, by passing real sector
  // instead of fake one. Improve sprite lighting by basing sprite
  // lightlevels on floor & ceiling lightlevels in the surrounding area.
  //
  // 10/98 killough:
  //
  // NOTE: TeamTNT fixed this bug incorrectly, messing up sprite lighting!!!
  // That is part of the 242 effect!!!  If you simply pass sub->sector to
  // the old code you will not get correct lighting for underwater sprites!!!
  // Either you must pass the fake sector and handle validcount here, on the
  // real sector, or you must account for the lighting in some other way,
  // like passing it as an argument.

  R_AddSprites(sub, (floorlightlevel+ceilinglightlevel)/2);
  while (count--)
  {
    if (line->miniseg == false)
      R_AddLine (line);
    line++;
    curline = NULL; /* cph 2001/11/18 - must clear curline now we're done with it, so R_ColourMap doesn't try using it for other things */
  }
#ifdef GL_DOOM
  if (V_GetMode() == VID_MODEGL)
    gld_AddPlane(num, floorplane, ceilingplane);
#endif
}
示例#10
0
void R_RenderMaskedSegRange(drawseg_t *ds, int x1, int x2)
{
  int      texnum;
  sector_t tempsec;      // killough 4/13/98
  const rpatch_t *patch;
  R_DrawColumn_f colfunc;
  draw_column_vars_t dcvars;
  angle_t angle;

  R_SetDefaultDrawColumnVars(&dcvars);

  // Calculate light table.
  // Use different light tables
  //   for horizontal / vertical / diagonal. Diagonal?

  curline = ds->curline;  // OPTIMIZE: get rid of LIGHTSEGSHIFT globally

  // killough 4/11/98: draw translucent 2s normal textures

  colfunc = R_GetDrawColumnFunc(RDC_PIPELINE_STANDARD, drawvars.filterwall, drawvars.filterz);
  if (curline->linedef->tranlump >= 0 && general_translucency)
    {
      colfunc = R_GetDrawColumnFunc(RDC_PIPELINE_TRANSLUCENT, drawvars.filterwall, drawvars.filterz);
      tranmap = main_tranmap;
      if (curline->linedef->tranlump > 0)
        tranmap = W_CacheLumpNum(curline->linedef->tranlump-1);
    }
  // killough 4/11/98: end translucent 2s normal code

  frontsector = curline->frontsector;
  backsector = curline->backsector;

  // cph 2001/11/25 - middle textures did not animate in v1.2
  texnum = curline->sidedef->midtexture;
  if (!comp[comp_maskedanim])
    texnum = texturetranslation[texnum];

  // killough 4/13/98: get correct lightlevel for 2s normal textures
  rw_lightlevel = R_FakeFlat(frontsector, &tempsec, NULL, NULL, false) ->lightlevel;
  walllights = GetLightTable(rw_lightlevel);
  walllightsnext = GetLightTable(rw_lightlevel + 1);

  maskedtexturecol = ds->maskedtexturecol;

  rw_scalestep = ds->scalestep;
  spryscale = ds->scale1 + (x1 - ds->x1)*rw_scalestep;
  mfloorclip = ds->sprbottomclip;
  mceilingclip = ds->sprtopclip;

  // find positioning
  if (curline->linedef->flags & ML_DONTPEGBOTTOM)
    {
      dcvars.texturemid = frontsector->floorheight > backsector->floorheight
        ? frontsector->floorheight : backsector->floorheight;
      dcvars.texturemid = dcvars.texturemid + textureheight[texnum] - viewz;
    }
  else
    {
      dcvars.texturemid =frontsector->ceilingheight<backsector->ceilingheight
        ? frontsector->ceilingheight : backsector->ceilingheight;
      dcvars.texturemid = dcvars.texturemid - viewz;
    }

  dcvars.texturemid += curline->sidedef->rowoffset;

  if (fixedcolormap) {
    dcvars.colormap = fixedcolormap;
    dcvars.nextcolormap = dcvars.colormap; // for filtering -- POPE
  }

  patch = R_CacheTextureCompositePatchNum(texnum);

  // draw the columns
  for (dcvars.x = x1 ; dcvars.x <= x2 ; dcvars.x++, spryscale += rw_scalestep)
    if (maskedtexturecol[dcvars.x] != INT_MAX) // dropoff overflow
      {
        // calculate texture offset - POPE
        angle = (ds->rw_centerangle + xtoviewangle[dcvars.x]) >> ANGLETOFINESHIFT;
        dcvars.texu = ds->rw_offset - FixedMul(finetangent[angle], ds->rw_distance);
        if (drawvars.filterwall == RDRAW_FILTER_LINEAR)
          dcvars.texu -= (FRACUNIT>>1);

        if (!fixedcolormap)
          dcvars.z = spryscale; // for filtering -- POPE

        if (!fixedcolormap)
        {
          int index = ((spryscale * 160 / wide_centerx) >> LIGHTSCALESHIFT);
          if (index >= MAXLIGHTSCALE)
            index = MAXLIGHTSCALE - 1;

          dcvars.colormap = walllights[index];
          dcvars.nextcolormap = walllightsnext[index];
        }
示例#11
0
文件: r_bsp.c 项目: bnied/doomretro
//
// R_AddLine
// Clips the given segment
// and adds any visible pieces to the line list.
//
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_PointToAngleEx(line->v1->x, line->v1->y);
    angle2 = R_PointToAngleEx(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.
    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)
        return;

    backsector = line->backsector;

    // Single sided line?
    if (!backsector)
        goto clipsolid;

    // [AM] Interpolate sector movement before
    //      running clipping tests. Frontsector
    //      should already be interpolated.
    R_MaybeInterpolateSector(backsector);

    // killough 3/8/98, 4/4/98: hack for invisible ceilings / deep water
    backsector = R_FakeFlat(backsector, &tempsec, NULL, NULL, true);

    doorclosed = false; // killough 4/16/98

    // Closed door.
    if (backsector->interpceilingheight <= frontsector->interpfloorheight
        || backsector->interpfloorheight >= frontsector->interpceilingheight)
        goto clipsolid;

    // 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 ((doorclosed = R_DoorClosed()))
        goto clipsolid;

    // Window.
    if (backsector->interpceilingheight != frontsector->interpceilingheight
        || backsector->interpfloorheight != frontsector->interpfloorheight)
        goto clippass;

    // 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 (backsector->ceilingpic == frontsector->ceilingpic
        && backsector->floorpic == frontsector->floorpic
        && backsector->lightlevel == frontsector->lightlevel
        && !curline->sidedef->midtexture

        // killough 3/7/98: Take flats offsets into account:
        && backsector->floor_xoffs == frontsector->floor_xoffs
        && backsector->floor_yoffs == frontsector->floor_yoffs
        && backsector->ceiling_xoffs == frontsector->ceiling_xoffs
        && backsector->ceiling_yoffs == frontsector->ceiling_yoffs

        // killough 4/16/98: consider altered lighting
        && backsector->floorlightsec == frontsector->floorlightsec
        && backsector->ceilinglightsec == frontsector->ceilinglightsec)
        return;

clippass:
    R_ClipPassWallSegment(x1, x2 - 1);
    return;

clipsolid:
    R_ClipSolidWallSegment(x1, x2 - 1);
}
示例#12
0
文件: r_bsp.c 项目: jezze/doom
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);

}
示例#13
0
//
// R_AddLine
// Clips the given segment
// and adds any visible pieces to the line list.
//
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;

	// [RH] Color if not texturing line
	dc_color = ((line - segs) & 31) * 4;

	// OPTIMIZE: quickly reject orthogonal back sides.
	angle1 = R_PointToAngle (line->v1->x, line->v1->y);
	angle2 = R_PointToAngle (line->v2->x, line->v2->y);

	// Clip to view edges.
	// OPTIMIZE: make constant out of 2*clipangle (FIELDOFVIEW).
	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)
	{
		// Totally off the left edge?
		if (tspan - 2*clipangle >= span)
			return;

		angle1 = clipangle;
	}
	tspan = clipangle - angle2;
	if (tspan > 2*clipangle)
	{
		// Totally off the left edge?
		if (tspan - 2*clipangle >= span)
			return;
		angle2 = (unsigned) (-(int)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;

	rw_start = x1;
	rw_stop = x2 - 1;
	
	rw_frontcz1 = P_CeilingHeight(line->v1->x, line->v1->y, frontsector);
	rw_frontfz1 = P_FloorHeight(line->v1->x, line->v1->y, frontsector);
	rw_frontcz2 = P_CeilingHeight(line->v2->x, line->v2->y, frontsector);
	rw_frontfz2 = P_FloorHeight(line->v2->x, line->v2->y, frontsector);	
	
	backsector = line->backsector;
	// Single sided line?
	if (!backsector)
		goto clipsolid;

	// killough 3/8/98, 4/4/98: hack for invisible ceilings / deep water
	backsector = R_FakeFlat (backsector, &tempsec, NULL, NULL, true);
		
	rw_backcz1 = P_CeilingHeight(line->v1->x, line->v1->y, backsector);
	rw_backfz1 = P_FloorHeight(line->v1->x, line->v1->y, backsector);
	rw_backcz2 = P_CeilingHeight(line->v2->x, line->v2->y, backsector);
	rw_backfz2 = P_FloorHeight(line->v2->x, line->v2->y, backsector);

	// [SL] Check for 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 (!(line->linedef->flags & ML_TWOSIDED) ||
		 (rw_backcz1 <= rw_frontfz1 && rw_backcz2 <= rw_frontfz2) ||
		 (rw_backfz1 >= rw_frontcz1 && rw_backfz2 >= rw_frontcz2) ||

		// handle a case where the backsector slopes one direction
		// and the frontsector slopes the opposite:
		(rw_backcz1 <= rw_frontfz1 && rw_backfz1 >= rw_frontcz1) ||
		(rw_backcz2 <= rw_frontfz2 && 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;
		goto clipsolid;
	}
	else
	{
		doorclosed = false;
	}

	// Window.
	if (!P_IdenticalPlanes(&frontsector->ceilingplane, &backsector->ceilingplane) ||
		!P_IdenticalPlanes(&frontsector->floorplane, &backsector->floorplane))
		goto clippass;

	// 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 (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->floorcolormap == frontsector->floorcolormap
		&& backsector->ceilingcolormap == frontsector->ceilingcolormap

		// [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;
	}

  clippass:
	R_ClipPassWallSegment (x1, x2-1);
	return;

  clipsolid:
	R_ClipSolidWallSegment (x1, x2-1);
}
示例#14
0
文件: r_bsp.c 项目: TehRealSalt/SRB2
//
// R_AddLine
// Clips the given segment and adds any visible pieces to the line list.
//
static void R_AddLine(seg_t *line)
{
	INT32 x1, x2;
	angle_t angle1, angle2, span, tspan;
	static sector_t tempsec; // ceiling/water hack

	if (line->polyseg && !(line->polyseg->flags & POF_RENDERSIDES))
		return;

	curline = line;
	portalline = false;

	// OPTIMIZE: quickly reject orthogonal back sides.
	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 >= ANGLE_180)
		return;

	// Global angle needed by segcalc.
	rw_angle1 = angle1;
	angle1 -= viewangle;
	angle2 -= viewangle;

	tspan = angle1 + clipangle;
	if (tspan > doubleclipangle)
	{
		tspan -= doubleclipangle;

		// Totally off the left edge?
		if (tspan >= span)
			return;

		angle1 = clipangle;
	}
	tspan = clipangle - angle2;
	if (tspan > doubleclipangle)
	{
		tspan -= doubleclipangle;

		// Totally off the left edge?
		if (tspan >= span)
			return;

		angle2 = -(signed)clipangle;
	}

	// The seg is in the view range, but not necessarily visible.
	angle1 = (angle1+ANGLE_90)>>ANGLETOFINESHIFT;
	angle2 = (angle2+ANGLE_90)>>ANGLETOFINESHIFT;
	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;

	// Portal line
	if (line->linedef->special == 40 && line->side == 0)
	{
		if (portalrender < cv_maxportals.value)
		{
			// Find the other side!
			INT32 line2 = P_FindSpecialLineFromTag(40, line->linedef->tag, -1);
			if (line->linedef == &lines[line2])
				line2 = P_FindSpecialLineFromTag(40, line->linedef->tag, line2);
			if (line2 >= 0) // found it!
			{
				R_AddPortal(line->linedef-lines, line2, x1, x2); // Remember the lines for later rendering
				//return; // Don't fill in that space now!
				goto clipsolid;
			}
		}
		// Recursed TOO FAR (viewing a portal within a portal)
		// So uhhh, render it as a normal wall instead or something ???
	}

	// Single sided line?
	if (!backsector)
		goto clipsolid;

	backsector = R_FakeFlat(backsector, &tempsec, NULL, NULL, true);

	doorclosed = 0;

	// Closed door.
#ifdef ESLOPE
	if (frontsector->f_slope || frontsector->c_slope || backsector->f_slope || backsector->c_slope)
	{
		fixed_t frontf1,frontf2, frontc1, frontc2; // front floor/ceiling ends
		fixed_t backf1, backf2, backc1, backc2; // back floor ceiling ends
#define SLOPEPARAMS(slope, end1, end2, normalheight) \
		if (slope) { \
			end1 = P_GetZAt(slope, line->v1->x, line->v1->y); \
			end2 = P_GetZAt(slope, line->v2->x, line->v2->y); \
		} else \
			end1 = end2 = normalheight;

		SLOPEPARAMS(frontsector->f_slope, frontf1, frontf2, frontsector->floorheight)
		SLOPEPARAMS(frontsector->c_slope, frontc1, frontc2, frontsector->ceilingheight)
		SLOPEPARAMS( backsector->f_slope, backf1,  backf2,  backsector->floorheight)
		SLOPEPARAMS( backsector->c_slope, backc1,  backc2,  backsector->ceilingheight)
#undef SLOPEPARAMS
		if ((backc1 <= frontf1 && backc2 <= frontf2)
			|| (backf1 >= frontc1 && backf2 >= frontc2))
		{
			goto clipsolid;
		}

		// Check for automap fix. Store in doorclosed for r_segs.c
		doorclosed = (backc1 <= backf1 && backc2 <= backf2
		&& ((backc1 >= frontc1 && backc2 >= frontc2) || curline->sidedef->toptexture)
		&& ((backf1 <= frontf1 && backf2 >= frontf2) || curline->sidedef->bottomtexture)
		&& (backsector->ceilingpic != skyflatnum || frontsector->ceilingpic != skyflatnum));

		if (doorclosed)
			goto clipsolid;

		// Window.
		if (backc1 != frontc1 || backc2 != frontc2
			|| backf1 != frontf1 || backf2 != frontf2)
		{
			goto clippass;
		}
	}
示例#15
0
文件: r_bsp.c 项目: twinaphex/sdcell
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);
}
示例#16
0
void GL_RecalcLowerWall(seg_t *seg, sector_t *frontSector, gl_poly_t *poly)
{
   FTexture *tex = TexMan(seg->sidedef->bottomtexture);
   float txScale, tyScale, yOffset, xOffset, dist, texHeight;
   float v1[5], v2[5], v3[5], v4[5];
   float upperHeight, lowerHeight;
   texcoord_t ll, ul, lr, ur;
   sector_t *backSector, ts2;
   vertex_t *vert1, *vert2;
   fixed_t h1, h2;

   if (!poly->initialized) GL_InitPolygon(poly);
   poly->lastUpdate = frameStartMS;
   poly->initialized = true;

   vert1 = seg->v1;
   vert2 = seg->v2;
   dist = seg->length;

   backSector = R_FakeFlat(seg->backsector, &ts2, NULL, NULL, false);

   h1 = (backSector->floorplane.ZatPoint(vert1) - frontSector->floorplane.ZatPoint(vert1));
   h2 = (backSector->floorplane.ZatPoint(vert2) - frontSector->floorplane.ZatPoint(vert2));

   v1[0] = v3[0] = -vert1->x * MAP_SCALE;
   v1[2] = v3[2] = vert1->y * MAP_SCALE;
   v2[0] = v4[0] = -vert2->x * MAP_SCALE;
   v2[2] = v4[2] = vert2->y * MAP_SCALE;

   v1[1] = (float)frontSector->floorplane.ZatPoint(vert1);
   v2[1] = (float)frontSector->floorplane.ZatPoint(vert2);
   v3[1] = v1[1] + h1;
   v4[1] = v2[1] + h2;

   // texscale: 8 = 1.0, 16 = 2.0, 4 = 0.5
   txScale = tex->ScaleX ? tex->ScaleX / 8.f : 1.f;
   tyScale = tex->ScaleY ? tex->ScaleY / 8.f : 1.f;

   xOffset = (seg->offset * txScale) * INV_FRACUNIT;

   ll.x = xOffset / tex->GetWidth();
   ul.x = ll.x;
   lr.x = ll.x + (dist / tex->GetWidth() * txScale);
   ur.x = lr.x;

   ul.y = ur.y = 1.f;
   ll.y = lr.y = 0.f;

   if (tex)
   {
      texHeight = tex->GetHeight() / tyScale;

      lowerHeight = frontSector->floortexz * INV_FRACUNIT;
      upperHeight = backSector->floortexz * INV_FRACUNIT;

      if (seg->linedef->flags & ML_DONTPEGBOTTOM)
      {
         yOffset = (frontSector->ceilingtexz - backSector->floortexz) * INV_FRACUNIT;
      }
      else
      {
         yOffset = 0.f;
      }

      ul.y = ur.y = (yOffset + upperHeight - lowerHeight) / texHeight;
      ll.y = lr.y = yOffset / texHeight;

      // scale the coordinates
      //ul.y *= tyScale;
      //ur.y *= tyScale;
      //ll.y *= tyScale;
      //lr.y *= tyScale;

      // adjust for slopes
      ul.y -= ((v1[1] * INV_FRACUNIT) - lowerHeight) / texHeight;
      ur.y -= ((v2[1] * INV_FRACUNIT) - lowerHeight) / texHeight;
      ll.y += (upperHeight - (v3[1] * INV_FRACUNIT)) / texHeight;
      lr.y += (upperHeight - (v4[1] * INV_FRACUNIT)) / texHeight;
   }

   v1[1] *= MAP_SCALE;
   v2[1] *= MAP_SCALE;
   v3[1] *= MAP_SCALE;
   v4[1] *= MAP_SCALE;

   v1[3] = ul.x; v1[4] = ul.y;
   v2[3] = ur.x; v2[4] = ur.y;
   v3[3] = ll.x; v3[4] = ll.y;
   v4[3] = lr.x; v4[4] = lr.y;

   memcpy(poly->vertices + (0 * 3), v3, sizeof(float) * 3);
   memcpy(poly->vertices + (1 * 3), v1, sizeof(float) * 3);
   memcpy(poly->vertices + (2 * 3), v2, sizeof(float) * 3);
   memcpy(poly->vertices + (3 * 3), v4, sizeof(float) * 3);

   memcpy(poly->texCoords + (0 * 2), v3 + 3, sizeof(float) * 2);
   memcpy(poly->texCoords + (1 * 2), v1 + 3, sizeof(float) * 2);
   memcpy(poly->texCoords + (2 * 2), v2 + 3, sizeof(float) * 2);
   memcpy(poly->texCoords + (3 * 2), v4 + 3, sizeof(float) * 2);
}
示例#17
0
//
// 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);
}
示例#18
0
//
// R_Subsector
// Determine floor/ceiling planes.
// Add sprites of things in sector.
// Draw one or more line segments.
//
void R_Subsector (int num)
{
	int 		 count;
	seg_t*		 line;
	subsector_t *sub;
	sector_t     tempsec;				// killough 3/7/98: deep water hack
	int          floorlightlevel;		// killough 3/16/98: set floor lightlevel
	int          ceilinglightlevel;		// killough 4/11/98

#ifdef RANGECHECK
    if (num>=numsubsectors)
		I_Error ("R_Subsector: ss %i with numss = %i",
				 num,
				 numsubsectors);
#endif

	sub = &subsectors[num];
	frontsector = sub->sector;
	count = sub->numlines;
	line = &segs[sub->firstline];

	// killough 3/8/98, 4/4/98: Deep water / fake ceiling effect
	frontsector = R_FakeFlat(frontsector, &tempsec, &floorlightlevel,
						   &ceilinglightlevel, false);	// killough 4/11/98

	basecolormap = frontsector->colormap->maps;

	ceilingplane = P_CeilingHeight(camera) > viewz ||
		frontsector->ceilingpic == skyflatnum ||
		(frontsector->heightsec && 
		!(frontsector->heightsec->MoreFlags & SECF_IGNOREHEIGHTSEC) && 
		frontsector->heightsec->floorpic == skyflatnum) ?
		R_FindPlane(frontsector->ceilingplane,		// killough 3/8/98
					frontsector->ceilingpic == skyflatnum &&  // killough 10/98
						frontsector->sky & PL_SKYFLAT ? frontsector->sky :
						frontsector->ceilingpic,
					ceilinglightlevel,				// killough 4/11/98
					frontsector->ceiling_xoffs,		// killough 3/7/98
					frontsector->ceiling_yoffs + frontsector->base_ceiling_yoffs,
					frontsector->ceiling_xscale,
					frontsector->ceiling_yscale,
					frontsector->ceiling_angle + frontsector->base_ceiling_angle
					) : NULL;

	// killough 3/7/98: Add (x,y) offsets to flats, add deep water check
	// killough 3/16/98: add floorlightlevel
	// killough 10/98: add support for skies transferred from sidedefs
	floorplane = P_FloorHeight(camera) < viewz || // killough 3/7/98
		(frontsector->heightsec &&
		!(frontsector->heightsec->MoreFlags & SECF_IGNOREHEIGHTSEC) &&
		frontsector->heightsec->ceilingpic == skyflatnum) ?
		R_FindPlane(frontsector->floorplane,
					frontsector->floorpic == skyflatnum &&  // killough 10/98
						frontsector->sky & PL_SKYFLAT ? frontsector->sky :
						frontsector->floorpic,
					floorlightlevel,				// killough 3/16/98
					frontsector->floor_xoffs,		// killough 3/7/98
					frontsector->floor_yoffs + frontsector->base_floor_yoffs,
					frontsector->floor_xscale,
					frontsector->floor_yscale,
					frontsector->floor_angle + frontsector->base_floor_angle
					) : NULL;

	// [RH] set foggy flag
	foggy = level.fadeto_color[0] || level.fadeto_color[1] || level.fadeto_color[2] || level.fadeto_color[3]
				|| frontsector->colormap->fade;

	// killough 9/18/98: Fix underwater slowdown, by passing real sector
	// instead of fake one. Improve sprite lighting by basing sprite
	// lightlevels on floor & ceiling lightlevels in the surrounding area.
	R_AddSprites (sub->sector, (floorlightlevel + ceilinglightlevel) / 2, FakeSide);

	// [RH] Add particles
	if (r_particles)
	{
		for (WORD i = ParticlesInSubsec[num]; i != NO_PARTICLE; i = Particles[i].nextinsubsector)
			R_ProjectParticle(Particles + i, subsectors[num].sector, FakeSide);
	}		

	if (sub->poly)
	{ // Render the polyobj in the subsector first
		int polyCount = sub->poly->numsegs;
		seg_t **polySeg = sub->poly->segs;
		while (polyCount--)
			R_AddLine (*polySeg++);
	}
	
	while (count--)
		R_AddLine (line++);
}
示例#19
0
文件: r_bsp.c 项目: Arc0re/prboom3ds
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);
}
示例#20
0
//
// R_AddLine
// Clips the given segment
// and adds any visible pieces to the line list.
//
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;

	// [RH] Color if not texturing line
	dc_color = ((line - segs) & 31) * 4;

	// OPTIMIZE: quickly reject orthogonal back sides.
	angle1 = R_PointToAngle (line->v1->x, line->v1->y);
	angle2 = R_PointToAngle (line->v2->x, line->v2->y);

	// Clip to view edges.
	// OPTIMIZE: make constant out of 2*clipangle (FIELDOFVIEW).
	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)
	{
		// Totally off the left edge?
		if (tspan - 2*clipangle >= span)
			return;

		angle1 = clipangle;
	}
	tspan = clipangle - angle2;
	if (tspan > 2*clipangle)
	{
		// Totally off the left edge?
		if (tspan - 2*clipangle >= span)
			return;
		angle2 = (unsigned) (-(int)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)
		goto clipsolid;

	// 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

	// Closed door.
	if (backsector->ceilingheight <= frontsector->floorheight
		|| backsector->floorheight >= frontsector->ceilingheight)
		goto clipsolid;

	// 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 ((doorclosed = R_DoorClosed()))
		goto clipsolid;

	// Window.
	if (backsector->ceilingheight != frontsector->ceilingheight
		|| backsector->floorheight != frontsector->floorheight)
		goto clippass;

	// 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 (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->floorcolormap == frontsector->floorcolormap
		&& backsector->ceilingcolormap == frontsector->ceilingcolormap

		// [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;
	}


  clippass:
	R_ClipPassWallSegment (x1, x2-1);
	return;

  clipsolid:
	R_ClipSolidWallSegment (x1, x2-1);
}
示例#21
0
static void R_Subsector(int num)
{
  int         count;
  seg_t       *line;
  subsector_t *sub;
  sector_t    tempsec;              // killough 3/7/98: deep water hack
  int         floorlightlevel;      // killough 3/16/98: set floor lightlevel
  int         ceilinglightlevel;    // killough 4/11/98

  sub = &subsectors[num];
  frontsector = sub->sector;
  count = sub->numlines;
  line = &segs[sub->firstline];

  // killough 3/8/98, 4/4/98: Deep water / fake ceiling effect
  frontsector = R_FakeFlat(frontsector, &tempsec, &floorlightlevel,
                           &ceilinglightlevel, FALSE);   // killough 4/11/98

  // killough 3/7/98: Add (x,y) offsets to flats, add deep water check
  // killough 3/16/98: add floorlightlevel
  // killough 10/98: add support for skies transferred from sidedefs

  floorplane = frontsector->floorheight < viewz || // killough 3/7/98
    (frontsector->heightsec != -1 &&
     sectors[frontsector->heightsec].ceilingpic == skyflatnum) ?
    R_FindPlane(frontsector->floorheight,
                frontsector->floorpic == skyflatnum &&  // kilough 10/98
                frontsector->sky & PL_SKYFLAT ? frontsector->sky :
                frontsector->floorpic,
                floorlightlevel,                // killough 3/16/98
                frontsector->floor_xoffs,       // killough 3/7/98
                frontsector->floor_yoffs
                ) : NULL;

  ceilingplane = frontsector->ceilingheight > viewz ||
    frontsector->ceilingpic == skyflatnum ||
    (frontsector->heightsec != -1 &&
     sectors[frontsector->heightsec].floorpic == skyflatnum) ?
    R_FindPlane(frontsector->ceilingheight,     // killough 3/8/98
                frontsector->ceilingpic == skyflatnum &&  // kilough 10/98
                frontsector->sky & PL_SKYFLAT ? frontsector->sky :
                frontsector->ceilingpic,
                ceilinglightlevel,              // killough 4/11/98
                frontsector->ceiling_xoffs,     // killough 3/7/98
                frontsector->ceiling_yoffs
                ) : NULL;

  // killough 9/18/98: Fix underwater slowdown, by passing real sector
  // instead of fake one. Improve sprite lighting by basing sprite
  // lightlevels on floor & ceiling lightlevels in the surrounding area.
  //
  // 10/98 killough:
  //
  // NOTE: TeamTNT fixed this bug incorrectly, messing up sprite lighting!!!
  // That is part of the 242 effect!!!  If you simply pass sub->sector to
  // the old code you will not get correct lighting for underwater sprites!!!
  // Either you must pass the fake sector and handle validcount here, on the
  // real sector, or you must account for the lighting in some other way,
  // like passing it as an argument.

  R_AddSprites(sub, (floorlightlevel+ceilinglightlevel)/2);
  while (count--)
  {
    if (line->miniseg == FALSE)
      R_AddLine (line);
    line++;
    curline = NULL; /* cph 2001/11/18 - must clear curline now we're done with it, so R_ColourMap doesn't try using it for other things */
  }
}
示例#22
0
//
// R_Subsector
// Determine floor/ceiling planes.
// Add sprites of things in sector.
// Draw one or more line segments.
//
void R_Subsector (int num)
{
	int 		 count;
	seg_t*		 line;
	subsector_t *sub;
	sector_t     tempsec;				// killough 3/7/98: deep water hack
	int          floorlightlevel;		// killough 3/16/98: set floor lightlevel
	int          ceilinglightlevel;		// killough 4/11/98

#ifdef RANGECHECK
    if (num>=numsubsectors)
		I_Error ("R_Subsector: ss %i with numss = %i",
				 num,
				 numsubsectors);
#endif

	sub = &subsectors[num];
	frontsector = sub->sector;
	count = sub->numlines;
	line = &segs[sub->firstline];

	// killough 3/8/98, 4/4/98: Deep water / fake ceiling effect
	frontsector = R_FakeFlat(frontsector, &tempsec, &floorlightlevel,
						   &ceilinglightlevel, false);	// killough 4/11/98

	basecolormap = frontsector->ceilingcolormap->maps;

	ceilingplane = frontsector->ceilingheight > viewz ||
		frontsector->ceilingpic == skyflatnum ||
		(frontsector->heightsec && frontsector->heightsec->floorpic == skyflatnum) ?
		R_FindPlane(frontsector->ceilingheight,		// killough 3/8/98
					frontsector->ceilingpic == skyflatnum &&  // killough 10/98
						frontsector->sky & PL_SKYFLAT ? frontsector->sky :
						frontsector->ceilingpic,
					ceilinglightlevel,				// killough 4/11/98
					frontsector->ceiling_xoffs,		// killough 3/7/98
					frontsector->ceiling_yoffs + frontsector->base_ceiling_yoffs,
					frontsector->ceiling_xscale,
					frontsector->ceiling_yscale,
					frontsector->ceiling_angle + frontsector->base_ceiling_angle
					) : NULL;

	basecolormap = frontsector->floorcolormap->maps;	// [RH] set basecolormap

	// killough 3/7/98: Add (x,y) offsets to flats, add deep water check
	// killough 3/16/98: add floorlightlevel
	// killough 10/98: add support for skies transferred from sidedefs
	floorplane = frontsector->floorheight < viewz || // killough 3/7/98
		(frontsector->heightsec && frontsector->heightsec->ceilingpic == skyflatnum) ?
		R_FindPlane(frontsector->floorheight,
					frontsector->floorpic == skyflatnum &&  // killough 10/98
						frontsector->sky & PL_SKYFLAT ? frontsector->sky :
						frontsector->floorpic,
					floorlightlevel,				// killough 3/16/98
					frontsector->floor_xoffs,		// killough 3/7/98
					frontsector->floor_yoffs + frontsector->base_floor_yoffs,
					frontsector->floor_xscale,
					frontsector->floor_yscale,
					frontsector->floor_angle + frontsector->base_floor_angle
					) : NULL;

	// [RH] set foggy flag
	foggy = level.fadeto || frontsector->floorcolormap->fade
						 || frontsector->ceilingcolormap->fade;

	// killough 9/18/98: Fix underwater slowdown, by passing real sector
	// instead of fake one. Improve sprite lighting by basing sprite
	// lightlevels on floor & ceiling lightlevels in the surrounding area.
	R_AddSprites (sub->sector, (floorlightlevel + ceilinglightlevel) / 2);

	if (sub->poly)
	{ // Render the polyobj in the subsector first
		int polyCount = sub->poly->numsegs;
		seg_t **polySeg = sub->poly->segs;
		while (polyCount--)
		{
			R_AddLine (*polySeg++);
		}
	}
	
	while (count--)
	{
		R_AddLine (line++);
	}
}
示例#23
0
static void R_Subsector(int num)
{
  int         count;
  seg_t       *line;
  subsector_t *sub;
  sector_t    tempsec;              // killough 3/7/98: deep water hack
  int         floorlightlevel;      // killough 3/16/98: set floor lightlevel
  int         ceilinglightlevel;    // killough 4/11/98

#ifdef RANGECHECK
  if (num>=numsubsectors)
    I_Error ("R_Subsector: ss %i with numss = %i", num, numsubsectors);
#endif

  sub = &subsectors[num];
  frontsector = sub->sector;
  count = sub->numlines;
  line = &segs[sub->firstline];

  // killough 3/8/98, 4/4/98: Deep water / fake ceiling effect
  frontsector = R_FakeFlat(frontsector, &tempsec, &floorlightlevel,
                           &ceilinglightlevel, false);   // killough 4/11/98

  // killough 3/7/98: Add (x,y) offsets to flats, add deep water check
  // killough 3/16/98: add floorlightlevel

  floorplane = frontsector->floorheight < viewz || // killough 3/7/98
    (frontsector->heightsec != -1 &&
     sectors[frontsector->heightsec].ceilingpic == skyflatnum) ?
    R_FindPlane(frontsector->floorheight,
		frontsector->floorpic == skyflatnum &&  // kilough 10/98
		frontsector->sky & PL_SKYFLAT ? frontsector->sky :
                frontsector->floorpic,
                floorlightlevel,                // killough 3/16/98
                frontsector->floor_xoffs,       // killough 3/7/98
                frontsector->floor_yoffs
                ) : NULL;

  ceilingplane = frontsector->ceilingheight > viewz ||
    frontsector->ceilingpic == skyflatnum ||
    (frontsector->heightsec != -1 &&
     sectors[frontsector->heightsec].floorpic == skyflatnum) ?
    R_FindPlane(frontsector->ceilingheight,     // killough 3/8/98
		frontsector->ceilingpic == skyflatnum &&  // kilough 10/98
		frontsector->sky & PL_SKYFLAT ? frontsector->sky :
                frontsector->ceilingpic,
                ceilinglightlevel,              // killough 4/11/98
                frontsector->ceiling_xoffs,     // killough 3/7/98
                frontsector->ceiling_yoffs
                ) : NULL;

  // killough 9/18/98: Fix underwater slowdown, by passing real sector 
  // instead of fake one. Improve sprite lighting by basing sprite
  // lightlevels on floor & ceiling lightlevels in the surrounding area.
  //
  // 10/98 killough:
  //
  // NOTE: TeamTNT fixed this bug incorrectly, messing up sprite lighting!!!
  // That is part of the 242 effect!!!  If you simply pass sub->sector to
  // the old code you will not get correct lighting for underwater sprites!!!
  // Either you must pass the fake sector and handle validcount here, on the
  // real sector, or you must account for the lighting in some other way, 
  // like passing it as an argument.

  R_AddSprites(sub->sector, (floorlightlevel+ceilinglightlevel)/2);

  while (count--)
    R_AddLine (line++);
}
示例#24
0
sector_t *FSoftwareRenderer::FakeFlat(sector_t *sec, sector_t *tempsec, int *floorlightlevel, int *ceilinglightlevel, bool back)
{
	return R_FakeFlat(sec, tempsec, floorlightlevel, ceilinglightlevel, back);
}
示例#25
0
文件: r_bsp.c 项目: Yukitty/SRB2
static void R_Subsector(size_t num)
{
	INT32 count, floorlightlevel, ceilinglightlevel, light;
	seg_t *line;
	subsector_t *sub;
	static sector_t tempsec; // Deep water hack
	extracolormap_t *floorcolormap;
	extracolormap_t *ceilingcolormap;

#ifdef RANGECHECK
	if (num >= numsubsectors)
		I_Error("R_Subsector: ss %s with numss = %s\n", sizeu1(num), sizeu2(numsubsectors));
#endif

	// subsectors added at run-time
	if (num >= numsubsectors)
		return;

	sub = &subsectors[num];
	frontsector = sub->sector;
	count = sub->numlines;
	line = &segs[sub->firstline];

	// Deep water/fake ceiling effect.
	frontsector = R_FakeFlat(frontsector, &tempsec, &floorlightlevel, &ceilinglightlevel, false);

	floorcolormap = ceilingcolormap = frontsector->extra_colormap;

	// Check and prep all 3D floors. Set the sector floor/ceiling light levels and colormaps.
	if (frontsector->ffloors)
	{
		if (frontsector->moved)
		{
			frontsector->numlights = sub->sector->numlights = 0;
			R_Prep3DFloors(frontsector);
			sub->sector->lightlist = frontsector->lightlist;
			sub->sector->numlights = frontsector->numlights;
			sub->sector->moved = frontsector->moved = false;
		}

		light = R_GetPlaneLight(frontsector,
#ifdef ESLOPE
								frontsector->f_slope ? P_GetZAt(frontsector->f_slope, frontsector->soundorg.x, frontsector->soundorg.y) :
#endif
								frontsector->floorheight, false);
		if (frontsector->floorlightsec == -1)
			floorlightlevel = *frontsector->lightlist[light].lightlevel;
		floorcolormap = frontsector->lightlist[light].extra_colormap;
		light = R_GetPlaneLight(frontsector,
#ifdef ESLOPE
								frontsector->c_slope ? P_GetZAt(frontsector->c_slope, frontsector->soundorg.x, frontsector->soundorg.y) :
#endif
								frontsector->ceilingheight, false);
		if (frontsector->ceilinglightsec == -1)
			ceilinglightlevel = *frontsector->lightlist[light].lightlevel;
		ceilingcolormap = frontsector->lightlist[light].extra_colormap;
	}

	sub->sector->extra_colormap = frontsector->extra_colormap;

	if (((
#ifdef ESLOPE
			frontsector->f_slope ? P_GetZAt(frontsector->f_slope, viewx, viewy) :
#endif
		frontsector->floorheight) < viewz || (frontsector->heightsec != -1
		&& sectors[frontsector->heightsec].ceilingpic == skyflatnum)))
	{
		floorplane = R_FindPlane(frontsector->floorheight, frontsector->floorpic, floorlightlevel,
			frontsector->floor_xoffs, frontsector->floor_yoffs, frontsector->floorpic_angle, floorcolormap, NULL
#ifdef ESLOPE
			, frontsector->f_slope
#endif
			);
	}
	else
		floorplane = NULL;

	if (((
#ifdef ESLOPE
			frontsector->c_slope ? P_GetZAt(frontsector->c_slope, viewx, viewy) :
#endif
		frontsector->ceilingheight) > viewz || frontsector->ceilingpic == skyflatnum
		|| (frontsector->heightsec != -1
		&& sectors[frontsector->heightsec].floorpic == skyflatnum)))
	{
		ceilingplane = R_FindPlane(frontsector->ceilingheight, frontsector->ceilingpic,
			ceilinglightlevel, frontsector->ceiling_xoffs, frontsector->ceiling_yoffs, frontsector->ceilingpic_angle,
			ceilingcolormap, NULL
#ifdef ESLOPE
			, frontsector->c_slope
#endif
			);
	}
	else
		ceilingplane = NULL;

	numffloors = 0;
#ifdef ESLOPE
	ffloor[numffloors].slope = NULL;
#endif
	ffloor[numffloors].plane = NULL;
	ffloor[numffloors].polyobj = NULL;
	if (frontsector->ffloors)
	{
		ffloor_t *rover;
		fixed_t heightcheck;

		for (rover = frontsector->ffloors; rover && numffloors < MAXFFLOORS; rover = rover->next)
		{
			if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_RENDERPLANES))
				continue;

			if (frontsector->cullheight)
			{
				if (R_DoCulling(frontsector->cullheight, viewsector->cullheight, viewz, *rover->bottomheight, *rover->topheight))
				{
					rover->norender = leveltime;
					continue;
				}
			}

			ffloor[numffloors].plane = NULL;
			ffloor[numffloors].polyobj = NULL;

			heightcheck =
#ifdef ESLOPE
				*rover->b_slope ? P_GetZAt(*rover->b_slope, viewx, viewy) :
#endif
				*rover->bottomheight;
			if (*rover->bottomheight <= frontsector->ceilingheight
				&& *rover->bottomheight >= frontsector->floorheight
				&& ((viewz < heightcheck && !(rover->flags & FF_INVERTPLANES))
				|| (viewz > heightcheck && (rover->flags & FF_BOTHPLANES))))
			{
#ifdef ESLOPE
				light = R_GetPlaneLight(frontsector,
					*rover->b_slope ? P_GetZAt(*rover->b_slope, frontsector->soundorg.x, frontsector->soundorg.y) : *rover->bottomheight,
					viewz < heightcheck);
#else
				light = R_GetPlaneLight(frontsector, *rover->bottomheight,
					viewz < *rover->bottomheight);
#endif
				ffloor[numffloors].plane = R_FindPlane(*rover->bottomheight, *rover->bottompic,
					*frontsector->lightlist[light].lightlevel, *rover->bottomxoffs,
					*rover->bottomyoffs, *rover->bottomangle, frontsector->lightlist[light].extra_colormap, rover
#ifdef ESLOPE
					, *rover->b_slope
#endif
					);

#ifdef ESLOPE
				ffloor[numffloors].slope = *rover->b_slope;

				// Tell the renderer this sector has slopes in it.
				if (ffloor[numffloors].slope)
					frontsector->hasslope = true;
#endif

				ffloor[numffloors].height =
#ifdef ESLOPE
				*rover->b_slope ? P_GetZAt(*rover->b_slope, viewx, viewy) :
#endif
				*rover->bottomheight;

				ffloor[numffloors].ffloor = rover;
				numffloors++;
			}
			if (numffloors >= MAXFFLOORS)
				break;
			ffloor[numffloors].plane = NULL;
			ffloor[numffloors].polyobj = NULL;

			heightcheck =
#ifdef ESLOPE
				*rover->t_slope ? P_GetZAt(*rover->t_slope, viewx, viewy) :
#endif
				*rover->topheight;
			if (*rover->topheight >= frontsector->floorheight
				&& *rover->topheight <= frontsector->ceilingheight
				&& ((viewz > heightcheck && !(rover->flags & FF_INVERTPLANES))
				|| (viewz < heightcheck && (rover->flags & FF_BOTHPLANES))))
			{
#ifdef ESLOPE
				light = R_GetPlaneLight(frontsector,
					*rover->t_slope ? P_GetZAt(*rover->t_slope, frontsector->soundorg.x, frontsector->soundorg.y) : *rover->topheight,
					viewz < heightcheck);
#else
				light = R_GetPlaneLight(frontsector, *rover->topheight, viewz < *rover->topheight);
#endif
				ffloor[numffloors].plane = R_FindPlane(*rover->topheight, *rover->toppic,
					*frontsector->lightlist[light].lightlevel, *rover->topxoffs, *rover->topyoffs, *rover->topangle,
					frontsector->lightlist[light].extra_colormap, rover
#ifdef ESLOPE
					, *rover->t_slope
#endif
					);

#ifdef ESLOPE
				ffloor[numffloors].slope = *rover->t_slope;

				// Tell the renderer this sector has slopes in it.
				if (ffloor[numffloors].slope)
					frontsector->hasslope = true;
#endif

				ffloor[numffloors].height =
#ifdef ESLOPE
				*rover->t_slope ? P_GetZAt(*rover->t_slope, viewx, viewy) :
#endif
				*rover->topheight;

				ffloor[numffloors].ffloor = rover;
				numffloors++;
			}
		}
	}

#ifdef POLYOBJECTS_PLANES
	// Polyobjects have planes, too!
	if (sub->polyList)
	{
		polyobj_t *po = sub->polyList;
		sector_t *polysec;

		while (po)
		{
			if (numffloors >= MAXFFLOORS)
				break;

			if (!(po->flags & POF_RENDERPLANES)) // Don't draw planes
			{
				po = (polyobj_t *)(po->link.next);
				continue;
			}

			polysec = po->lines[0]->backsector;
			ffloor[numffloors].plane = NULL;

			if (polysec->floorheight <= frontsector->ceilingheight
				&& 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 {
示例#26
0
//
// R_Subsector
// Determine floor/ceiling planes.
// Add sprites of things in sector.
// Draw one or more line segments.
//
void R_Subsector (subsector_t *sub)
{
	int 		 count;
	seg_t*		 line;
	sector_t     tempsec;				// killough 3/7/98: deep water hack
	int          floorlightlevel;		// killough 3/16/98: set floor lightlevel
	int          ceilinglightlevel;		// killough 4/11/98
	bool		 outersubsector;
	int	fll, cll, position;
	FSectorPortal *portal;

	// kg3D - fake floor stuff
	visplane_t *backupfp;
	visplane_t *backupcp;
	//secplane_t templane;
	lightlist_t *light;

	if (InSubsector != NULL)
	{ // InSubsector is not NULL. This means we are rendering from a mini-BSP.
		outersubsector = false;
	}
	else
	{
		outersubsector = true;
		InSubsector = sub;
	}

#ifdef RANGECHECK
	if (outersubsector && sub - subsectors >= (ptrdiff_t)numsubsectors)
		I_Error ("R_Subsector: ss %ti with numss = %i", sub - subsectors, numsubsectors);
#endif

	assert(sub->sector != NULL);

	if (sub->polys)
	{ // Render the polyobjs in the subsector first
		R_AddPolyobjs(sub);
		if (outersubsector)
		{
			InSubsector = NULL;
		}
		return;
	}

	frontsector = sub->sector;
	frontsector->MoreFlags |= SECF_DRAWN;
	count = sub->numlines;
	line = sub->firstline;

	// killough 3/8/98, 4/4/98: Deep water / fake ceiling effect
	frontsector = R_FakeFlat(frontsector, &tempsec, &floorlightlevel,
						   &ceilinglightlevel, false);	// killough 4/11/98

	fll = floorlightlevel;
	cll = ceilinglightlevel;

	// [RH] set foggy flag
	foggy = level.fadeto || frontsector->ColorMap->Fade || (level.flags & LEVEL_HASFADETABLE);
	r_actualextralight = foggy ? 0 : extralight << 4;

	// kg3D - fake lights
	if (fixedlightlev < 0 && frontsector->e && frontsector->e->XFloor.lightlist.Size())
	{
		light = P_GetPlaneLight(frontsector, &frontsector->ceilingplane, false);
		basecolormap = light->extra_colormap;
		// If this is the real ceiling, don't discard plane lighting R_FakeFlat()
		// accounted for.
		if (light->p_lightlevel != &frontsector->lightlevel)
		{
			ceilinglightlevel = *light->p_lightlevel;
		}
	}
	else
	{
		basecolormap = frontsector->ColorMap;
	}

	portal = frontsector->ValidatePortal(sector_t::ceiling);

	ceilingplane = frontsector->ceilingplane.PointOnSide(ViewPos) > 0 ||
		frontsector->GetTexture(sector_t::ceiling) == skyflatnum ||
		portal != NULL ||
		(frontsector->heightsec && 
		 !(frontsector->heightsec->MoreFlags & SECF_IGNOREHEIGHTSEC) &&
		 frontsector->heightsec->GetTexture(sector_t::floor) == skyflatnum) ?
		R_FindPlane(frontsector->ceilingplane,		// killough 3/8/98
					frontsector->GetTexture(sector_t::ceiling),
					ceilinglightlevel + r_actualextralight,				// killough 4/11/98
					frontsector->GetAlpha(sector_t::ceiling),
					!!(frontsector->GetFlags(sector_t::ceiling) & PLANEF_ADDITIVE),
					frontsector->planes[sector_t::ceiling].xform,
					frontsector->sky,
					portal
					) : NULL;

	if (fixedlightlev < 0 && frontsector->e && frontsector->e->XFloor.lightlist.Size())
	{
		light = P_GetPlaneLight(frontsector, &frontsector->floorplane, false);
		basecolormap = light->extra_colormap;
		// If this is the real floor, don't discard plane lighting R_FakeFlat()
		// accounted for.
		if (light->p_lightlevel != &frontsector->lightlevel)
		{
			floorlightlevel = *light->p_lightlevel;
		}
	}
	else
	{
		basecolormap = frontsector->ColorMap;
	}

	// killough 3/7/98: Add (x,y) offsets to flats, add deep water check
	// killough 3/16/98: add floorlightlevel
	// killough 10/98: add support for skies transferred from sidedefs
	portal = frontsector->ValidatePortal(sector_t::floor);

	floorplane = frontsector->floorplane.PointOnSide(ViewPos) > 0 || // killough 3/7/98
		frontsector->GetTexture(sector_t::floor) == skyflatnum ||
		portal != NULL ||
		(frontsector->heightsec &&
		 !(frontsector->heightsec->MoreFlags & SECF_IGNOREHEIGHTSEC) &&
		 frontsector->heightsec->GetTexture(sector_t::ceiling) == skyflatnum) ?
		R_FindPlane(frontsector->floorplane,
					frontsector->GetTexture(sector_t::floor),
					floorlightlevel + r_actualextralight,				// killough 3/16/98
					frontsector->GetAlpha(sector_t::floor),
					!!(frontsector->GetFlags(sector_t::floor) & PLANEF_ADDITIVE),
					frontsector->planes[sector_t::floor].xform,
					frontsector->sky,
					portal
					) : NULL;

	// kg3D - fake planes rendering
	if (r_3dfloors && frontsector->e && frontsector->e->XFloor.ffloors.Size())
	{
		backupfp = floorplane;
		backupcp = ceilingplane;
		// first check all floors
		for (int i = 0; i < (int)frontsector->e->XFloor.ffloors.Size(); i++)
		{
			fakeFloor = frontsector->e->XFloor.ffloors[i];
			if (!(fakeFloor->flags & FF_EXISTS)) continue;
			if (!fakeFloor->model) continue;
			if (fakeFloor->bottom.plane->isSlope()) continue;
			if (!(fakeFloor->flags & FF_NOSHADE) || (fakeFloor->flags & (FF_RENDERPLANES|FF_RENDERSIDES)))
			{
				R_3D_AddHeight(fakeFloor->top.plane, frontsector);
			}
			if (!(fakeFloor->flags & FF_RENDERPLANES)) continue;
			if (fakeFloor->alpha == 0) continue;
			if (fakeFloor->flags & FF_THISINSIDE && fakeFloor->flags & FF_INVERTSECTOR) continue;
			fakeAlpha = MIN<fixed_t>(Scale(fakeFloor->alpha, OPAQUE, 255), OPAQUE);
			if (fakeFloor->validcount != validcount)
			{
				fakeFloor->validcount = validcount;
				R_3D_NewClip();
			}
			double fakeHeight = fakeFloor->top.plane->ZatPoint(frontsector->centerspot);
			if (fakeHeight < ViewPos.Z &&
				fakeHeight > frontsector->floorplane.ZatPoint(frontsector->centerspot))
			{
				fake3D = FAKE3D_FAKEFLOOR;
				tempsec = *fakeFloor->model;
				tempsec.floorplane = *fakeFloor->top.plane;
				tempsec.ceilingplane = *fakeFloor->bottom.plane;
				if (!(fakeFloor->flags & FF_THISINSIDE) && !(fakeFloor->flags & FF_INVERTSECTOR))
				{
					tempsec.SetTexture(sector_t::floor, tempsec.GetTexture(sector_t::ceiling));
					position = sector_t::ceiling;
				} else position = sector_t::floor;
				frontsector = &tempsec;

				if (fixedlightlev < 0 && sub->sector->e->XFloor.lightlist.Size())
				{
					light = P_GetPlaneLight(sub->sector, &frontsector->floorplane, false);
					basecolormap = light->extra_colormap;
					floorlightlevel = *light->p_lightlevel;
				}

				ceilingplane = NULL;
				floorplane = R_FindPlane(frontsector->floorplane,
					frontsector->GetTexture(sector_t::floor),
					floorlightlevel + r_actualextralight,				// killough 3/16/98
					frontsector->GetAlpha(sector_t::floor),
					!!(fakeFloor->flags & FF_ADDITIVETRANS),
					frontsector->planes[position].xform,
					frontsector->sky,
					NULL);

				R_FakeDrawLoop(sub);
				fake3D = 0;
				frontsector = sub->sector;
			}
		}
		// and now ceilings
		for (unsigned int i = 0; i < frontsector->e->XFloor.ffloors.Size(); i++)
		{
			fakeFloor = frontsector->e->XFloor.ffloors[i];
			if (!(fakeFloor->flags & FF_EXISTS)) continue;
			if (!fakeFloor->model) continue;
			if (fakeFloor->top.plane->isSlope()) continue;
			if (!(fakeFloor->flags & FF_NOSHADE) || (fakeFloor->flags & (FF_RENDERPLANES|FF_RENDERSIDES)))
			{
				R_3D_AddHeight(fakeFloor->bottom.plane, frontsector);
			}
			if (!(fakeFloor->flags & FF_RENDERPLANES)) continue;
			if (fakeFloor->alpha == 0) continue;
			if (!(fakeFloor->flags & FF_THISINSIDE) && (fakeFloor->flags & (FF_SWIMMABLE|FF_INVERTSECTOR)) == (FF_SWIMMABLE|FF_INVERTSECTOR)) continue;
			fakeAlpha = MIN<fixed_t>(Scale(fakeFloor->alpha, OPAQUE, 255), OPAQUE);

			if (fakeFloor->validcount != validcount)
			{
				fakeFloor->validcount = validcount;
				R_3D_NewClip();
			}
			double fakeHeight = fakeFloor->bottom.plane->ZatPoint(frontsector->centerspot);
			if (fakeHeight > ViewPos.Z &&
				fakeHeight < frontsector->ceilingplane.ZatPoint(frontsector->centerspot))
			{
				fake3D = FAKE3D_FAKECEILING;
				tempsec = *fakeFloor->model;
				tempsec.floorplane = *fakeFloor->top.plane;
				tempsec.ceilingplane = *fakeFloor->bottom.plane;
				if ((!(fakeFloor->flags & FF_THISINSIDE) && !(fakeFloor->flags & FF_INVERTSECTOR)) ||
					(fakeFloor->flags & FF_THISINSIDE && fakeFloor->flags & FF_INVERTSECTOR))
				{
					tempsec.SetTexture(sector_t::ceiling, tempsec.GetTexture(sector_t::floor));
					position = sector_t::floor;
				} else position = sector_t::ceiling;
				frontsector = &tempsec;

				tempsec.ceilingplane.ChangeHeight(-1 / 65536.);
				if (fixedlightlev < 0 && sub->sector->e->XFloor.lightlist.Size())
				{
					light = P_GetPlaneLight(sub->sector, &frontsector->ceilingplane, false);
					basecolormap = light->extra_colormap;
					ceilinglightlevel = *light->p_lightlevel;
				}
				tempsec.ceilingplane.ChangeHeight(1 / 65536.);

				floorplane = NULL;
				ceilingplane = R_FindPlane(frontsector->ceilingplane,		// killough 3/8/98
					frontsector->GetTexture(sector_t::ceiling),
					ceilinglightlevel + r_actualextralight,				// killough 4/11/98
					frontsector->GetAlpha(sector_t::ceiling),
					!!(fakeFloor->flags & FF_ADDITIVETRANS),
					frontsector->planes[position].xform,
					frontsector->sky,
					NULL);

				R_FakeDrawLoop(sub);
				fake3D = 0;
				frontsector = sub->sector;
			}
		}
		fakeFloor = NULL;
		floorplane = backupfp;
		ceilingplane = backupcp;
	}

	basecolormap = frontsector->ColorMap;
	floorlightlevel = fll;
	ceilinglightlevel = cll;

	// killough 9/18/98: Fix underwater slowdown, by passing real sector 
	// instead of fake one. Improve sprite lighting by basing sprite
	// lightlevels on floor & ceiling lightlevels in the surrounding area.
	// [RH] Handle sprite lighting like Duke 3D: If the ceiling is a sky, sprites are lit by
	// it, otherwise they are lit by the floor.
	R_AddSprites (sub->sector, frontsector->GetTexture(sector_t::ceiling) == skyflatnum ?
		ceilinglightlevel : floorlightlevel, FakeSide);

	// [RH] Add particles
	if ((unsigned int)(sub - subsectors) < (unsigned int)numsubsectors)
	{ // Only do it for the main BSP.
		int shade = LIGHT2SHADE((floorlightlevel + ceilinglightlevel)/2 + r_actualextralight);
		for (WORD i = ParticlesInSubsec[(unsigned int)(sub-subsectors)]; i != NO_PARTICLE; i = Particles[i].snext)
		{
			R_ProjectParticle (Particles + i, subsectors[sub-subsectors].sector, shade, FakeSide);
		}
	}

	count = sub->numlines;
	line = sub->firstline;

	while (count--)
	{
		if (!outersubsector || line->sidedef == NULL || !(line->sidedef->Flags & WALLF_POLYOBJ))
		{
			// kg3D - fake planes bounding calculation
			if (r_3dfloors && line->backsector && frontsector->e && line->backsector->e->XFloor.ffloors.Size())
			{
				backupfp = floorplane;
				backupcp = ceilingplane;
				floorplane = NULL;
				ceilingplane = NULL;
				for (unsigned int i = 0; i < line->backsector->e->XFloor.ffloors.Size(); i++)
				{
					fakeFloor = line->backsector->e->XFloor.ffloors[i];
					if (!(fakeFloor->flags & FF_EXISTS)) continue;
					if (!(fakeFloor->flags & FF_RENDERPLANES)) continue;
					if (!fakeFloor->model) continue;
					fake3D = FAKE3D_FAKEBACK;
					tempsec = *fakeFloor->model;
					tempsec.floorplane = *fakeFloor->top.plane;
					tempsec.ceilingplane = *fakeFloor->bottom.plane;
					backsector = &tempsec;
					if (fakeFloor->validcount != validcount)
					{
						fakeFloor->validcount = validcount;
						R_3D_NewClip();
					}
					if (frontsector->CenterFloor() >= backsector->CenterFloor())
					{
						fake3D |= FAKE3D_CLIPBOTFRONT;
					}
					if (frontsector->CenterCeiling() <= backsector->CenterCeiling())
					{
						fake3D |= FAKE3D_CLIPTOPFRONT;
					}
					R_AddLine(line); // fake
				}
				fakeFloor = NULL;
				fake3D = 0;
				floorplane = backupfp;
				ceilingplane = backupcp;
			}
			R_AddLine (line); // now real
		}
		line++;
	}
	if (outersubsector)
	{
		InSubsector = NULL;
	}
}