示例#1
0
//==========================================================================
//
//
//
//==========================================================================
bool FDrawInfo::DoOneSectorLower(subsector_t * subsec, fixed_t planez)
{
    // Is there a one-sided wall in this subsector?
    // Do this first to avoid unnecessary recursion
    for(DWORD i=0; i< subsec->numlines; i++)
    {
        if (subsec->firstline[i].backsector == NULL) return false;
        if (subsec->firstline[i].PartnerSeg == NULL) return false;
    }

    for(DWORD i=0; i< subsec->numlines; i++)
    {
        seg_t * seg = subsec->firstline + i;
        subsector_t * backsub = seg->PartnerSeg->Subsector;

        // already checked?
        if (backsub->validcount == validcount) continue;
        backsub->validcount=validcount;

        if (seg->frontsector != seg->backsector && seg->linedef)
        {
            // Note: if this is a real line between sectors
            // we can be sure that render_sector is the real sector!

            sector_t * sec = gl_FakeFlat(seg->backsector, &fakesec, true);

            // Don't bother with slopes
            if (sec->floorplane.a!=0 || sec->floorplane.b!=0)  return false;

            // Is the neighboring floor higher than the desired height?
            if (sec->GetPlaneTexZ(sector_t::floor)>planez)
            {
                // todo: check for missing textures.
                return false;
            }

            // This is an exact height match which means we don't have to do any further checks for this sector
            if (sec->GetPlaneTexZ(sector_t::floor)==planez)
            {
                // If there's a texture abort
                FTexture * tex = TexMan[seg->sidedef->GetTexture(side_t::bottom)];
                if (!tex || tex->UseType==FTexture::TEX_Null) continue;
                else return false;
            }
        }
        if (!DoOneSectorLower(backsub, planez)) return false;
    }
    // all checked ok. This sector is part of the current fake plane

    HandledSubsectors.Push(subsec);
    return 1;
}
示例#2
0
//==========================================================================
//
// Draws the fake planes
//
//==========================================================================
void FDrawInfo::HandleMissingTextures()
{
    sector_t fake;
    totalms.Clock();
    totalupper=MissingUpperTextures.Size();
    totallower=MissingLowerTextures.Size();

    for(unsigned int i=0; i<MissingUpperTextures.Size(); i++)
    {
        if (!MissingUpperTextures[i].seg) continue;
        HandledSubsectors.Clear();
        validcount++;

        if (MissingUpperTextures[i].planez > viewz)
        {
            // close the hole only if all neighboring sectors are an exact height match
            // Otherwise just fill in the missing textures.
            MissingUpperTextures[i].sub->validcount=validcount;
            if (DoOneSectorUpper(MissingUpperTextures[i].sub, MissingUpperTextures[i].planez))
            {
                sector_t * sec = MissingUpperTextures[i].seg->backsector;
                // The mere fact that this seg has been added to the list means that the back sector
                // will be rendered so we can safely assume that it is already in the render list

                for(unsigned int j=0; j<HandledSubsectors.Size(); j++)
                {
                    gl_subsectorrendernode * node = SSR_List.GetNew();
                    node->sub = HandledSubsectors[j];

                    AddOtherCeilingPlane(sec->sectornum, node);
                }

                if (HandledSubsectors.Size()!=1)
                {
                    // mark all subsectors in the missing list that got processed by this
                    for(unsigned int j=0; j<HandledSubsectors.Size(); j++)
                    {
                        for(unsigned int k=0; k<MissingUpperTextures.Size(); k++)
                        {
                            if (MissingUpperTextures[k].sub==HandledSubsectors[j])
                            {
                                MissingUpperTextures[k].seg=NULL;
                            }
                        }
                    }
                }
                else MissingUpperTextures[i].seg=NULL;
                continue;
            }
        }

        if (!MissingUpperTextures[i].seg->PartnerSeg) continue;
        if (!MissingUpperTextures[i].seg->PartnerSeg->Subsector) continue;
        validcount++;
        HandledSubsectors.Clear();

        {
            // It isn't a hole. Now check whether it might be a fake bridge
            sector_t * fakesector = gl_FakeFlat(MissingUpperTextures[i].seg->frontsector, &fake, false);
            fixed_t planez = fakesector->GetPlaneTexZ(sector_t::ceiling);

            MissingUpperTextures[i].seg->PartnerSeg->Subsector->validcount=validcount;
            if (DoFakeCeilingBridge(MissingUpperTextures[i].seg->PartnerSeg->Subsector, planez))
            {
                // The mere fact that this seg has been added to the list means that the back sector
                // will be rendered so we can safely assume that it is already in the render list

                for(unsigned int j=0; j<HandledSubsectors.Size(); j++)
                {
                    gl_subsectorrendernode * node = SSR_List.GetNew();
                    node->sub = HandledSubsectors[j];
                    AddOtherCeilingPlane(fakesector->sectornum, node);
                }
            }
            continue;
        }
    }

    for(unsigned int i=0; i<MissingLowerTextures.Size(); i++)
    {
        if (!MissingLowerTextures[i].seg) continue;
        HandledSubsectors.Clear();
        validcount++;

        if (MissingLowerTextures[i].planez < viewz)
        {
            // close the hole only if all neighboring sectors are an exact height match
            // Otherwise just fill in the missing textures.
            MissingLowerTextures[i].sub->validcount=validcount;
            if (DoOneSectorLower(MissingLowerTextures[i].sub, MissingLowerTextures[i].planez))
            {
                sector_t * sec = MissingLowerTextures[i].seg->backsector;
                // The mere fact that this seg has been added to the list means that the back sector
                // will be rendered so we can safely assume that it is already in the render list

                for(unsigned int j=0; j<HandledSubsectors.Size(); j++)
                {
                    gl_subsectorrendernode * node = SSR_List.GetNew();
                    node->sub = HandledSubsectors[j];
                    AddOtherFloorPlane(sec->sectornum, node);
                }

                if (HandledSubsectors.Size()!=1)
                {
                    // mark all subsectors in the missing list that got processed by this
                    for(unsigned int j=0; j<HandledSubsectors.Size(); j++)
                    {
                        for(unsigned int k=0; k<MissingLowerTextures.Size(); k++)
                        {
                            if (MissingLowerTextures[k].sub==HandledSubsectors[j])
                            {
                                MissingLowerTextures[k].seg=NULL;
                            }
                        }
                    }
                }
                else MissingLowerTextures[i].seg=NULL;
                continue;
            }
        }

        if (!MissingLowerTextures[i].seg->PartnerSeg) continue;
        if (!MissingLowerTextures[i].seg->PartnerSeg->Subsector) continue;
        validcount++;
        HandledSubsectors.Clear();

        {
            // It isn't a hole. Now check whether it might be a fake bridge
            sector_t * fakesector = gl_FakeFlat(MissingLowerTextures[i].seg->frontsector, &fake, false);
            fixed_t planez = fakesector->GetPlaneTexZ(sector_t::floor);

            MissingLowerTextures[i].seg->PartnerSeg->Subsector->validcount=validcount;
            if (DoFakeBridge(MissingLowerTextures[i].seg->PartnerSeg->Subsector, planez))
            {
                // The mere fact that this seg has been added to the list means that the back sector
                // will be rendered so we can safely assume that it is already in the render list

                for(unsigned int j=0; j<HandledSubsectors.Size(); j++)
                {
                    gl_subsectorrendernode * node = SSR_List.GetNew();
                    node->sub = HandledSubsectors[j];
                    AddOtherFloorPlane(fakesector->sectornum, node);
                }
            }
            continue;
        }
    }

    totalms.Unclock();
    showtotalms=totalms;
    totalms.Reset();
}
示例#3
0
//==========================================================================
//
// Draws the fake planes
//
//==========================================================================
void HWDrawInfo::HandleMissingTextures(area_t in_area)
{
	for (unsigned int i = 0; i < MissingUpperTextures.Size(); i++)
	{
		if (!MissingUpperTextures[i].seg) continue;
		HandledSubsectors.Clear();
		validcount++;

		if (MissingUpperTextures[i].Planez > Viewpoint.Pos.Z)
		{
			// close the hole only if all neighboring sectors are an exact height match
			// Otherwise just fill in the missing textures.
			MissingUpperTextures[i].sub->validcount = validcount;
			if (DoOneSectorUpper(MissingUpperTextures[i].sub, MissingUpperTextures[i].Planez, in_area))
			{
				sector_t * sec = MissingUpperTextures[i].seg->backsector;
				for (unsigned int j = 0; j < HandledSubsectors.Size(); j++)
				{
                    gl_subsectorrendernode * node = NewSubsectorRenderNode();
					node->sub = HandledSubsectors[j];

					AddOtherCeilingPlane(sec->sectornum, node);
				}

				if (HandledSubsectors.Size() != 1)
				{
					// mark all subsectors in the missing list that got processed by this
					for (unsigned int j = 0; j < HandledSubsectors.Size(); j++)
					{
						for (unsigned int k = 0; k < MissingUpperTextures.Size(); k++)
						{
							if (MissingUpperTextures[k].sub == HandledSubsectors[j])
							{
								MissingUpperTextures[k].seg = NULL;
							}
						}
					}
				}
				else MissingUpperTextures[i].seg = NULL;
				continue;
			}
		}

		if (!MissingUpperTextures[i].seg->PartnerSeg) continue;
		subsector_t *backsub = MissingUpperTextures[i].seg->PartnerSeg->Subsector;
		if (!backsub) continue;
		validcount++;
		HandledSubsectors.Clear();

		{
			// It isn't a hole. Now check whether it might be a fake bridge
			sector_t * fakesector = hw_FakeFlat(MissingUpperTextures[i].seg->frontsector, in_area, false);
			float planez = (float)fakesector->GetPlaneTexZ(sector_t::ceiling);

			backsub->validcount = validcount;
			if (DoFakeCeilingBridge(backsub, planez, in_area))
			{
				for (unsigned int j = 0; j < HandledSubsectors.Size(); j++)
				{
                    gl_subsectorrendernode * node = NewSubsectorRenderNode();
					node->sub = HandledSubsectors[j];
					AddOtherCeilingPlane(fakesector->sectornum, node);
				}
			}
			continue;
		}
	}

	for (unsigned int i = 0; i < MissingLowerTextures.Size(); i++)
	{
		if (!MissingLowerTextures[i].seg) continue;
		HandledSubsectors.Clear();
		validcount++;

		if (MissingLowerTextures[i].Planez < Viewpoint.Pos.Z)
		{
			// close the hole only if all neighboring sectors are an exact height match
			// Otherwise just fill in the missing textures.
			MissingLowerTextures[i].sub->validcount = validcount;
			if (DoOneSectorLower(MissingLowerTextures[i].sub, MissingLowerTextures[i].Planez, in_area))
			{
				sector_t * sec = MissingLowerTextures[i].seg->backsector;

				for (unsigned int j = 0; j < HandledSubsectors.Size(); j++)
				{
                    gl_subsectorrendernode * node = NewSubsectorRenderNode();
					node->sub = HandledSubsectors[j];
					AddOtherFloorPlane(sec->sectornum, node);
				}

				if (HandledSubsectors.Size() != 1)
				{
					// mark all subsectors in the missing list that got processed by this
					for (unsigned int j = 0; j < HandledSubsectors.Size(); j++)
					{
						for (unsigned int k = 0; k < MissingLowerTextures.Size(); k++)
						{
							if (MissingLowerTextures[k].sub == HandledSubsectors[j])
							{
								MissingLowerTextures[k].seg = NULL;
							}
						}
					}
				}
				else MissingLowerTextures[i].seg = NULL;
				continue;
			}
		}

		if (!MissingLowerTextures[i].seg->PartnerSeg) continue;
		subsector_t *backsub = MissingLowerTextures[i].seg->PartnerSeg->Subsector;
		if (!backsub) continue;
		validcount++;
		HandledSubsectors.Clear();

		{
			// It isn't a hole. Now check whether it might be a fake bridge
			sector_t * fakesector = hw_FakeFlat(MissingLowerTextures[i].seg->frontsector, in_area, false);
			float planez = (float)fakesector->GetPlaneTexZ(sector_t::floor);

			backsub->validcount = validcount;
			if (DoFakeBridge(backsub, planez, in_area))
			{
				for (unsigned int j = 0; j < HandledSubsectors.Size(); j++)
				{
                    gl_subsectorrendernode * node = NewSubsectorRenderNode();
					node->sub = HandledSubsectors[j];
					AddOtherFloorPlane(fakesector->sectornum, node);
				}
			}
			continue;
		}
	}
}