Beispiel #1
0
void HWDrawInfo::DispatchRenderHacks()
{
	TMap<int, gl_subsectorrendernode*>::Pair *pair;
	TMap<int, gl_floodrendernode*>::Pair *fpair;
	TMap<int, gl_subsectorrendernode*>::Iterator ofi(otherFloorPlanes);
	GLFlat glflat;
	glflat.section = nullptr;
	while (ofi.NextPair(pair))
	{
		auto sec = hw_FakeFlat(&Level->sectors[pair->Key], in_area, false);
		glflat.ProcessSector(this, sec, SSRF_RENDERFLOOR | SSRF_PLANEHACK);
	}

	TMap<int, gl_subsectorrendernode*>::Iterator oci(otherCeilingPlanes);
	while (oci.NextPair(pair))
	{
		auto sec = hw_FakeFlat(&Level->sectors[pair->Key], in_area, false);
		glflat.ProcessSector(this, sec, SSRF_RENDERCEILING | SSRF_PLANEHACK);
	}

	TMap<int, gl_floodrendernode*>::Iterator ffi(floodFloorSegs);
	while (ffi.NextPair(fpair))
	{
		auto sec = hw_FakeFlat(&Level->sectors[fpair->Key], in_area, false);
		glflat.ProcessSector(this, sec, SSRF_RENDERFLOOR | SSRF_FLOODHACK);
	}

	TMap<int, gl_floodrendernode*>::Iterator fci(floodCeilingSegs);
	while (fci.NextPair(fpair))
	{
		auto sec = hw_FakeFlat(&Level->sectors[fpair->Key], in_area, false);
		glflat.ProcessSector(this, sec, SSRF_RENDERCEILING | SSRF_FLOODHACK);
	}
}
Beispiel #2
0
void HWDrawInfo::PrepareLowerGap(seg_t * seg)
{
	wallseg ws;
	sector_t * fakefsector = hw_FakeFlat(seg->frontsector, in_area, false);
	sector_t * fakebsector = hw_FakeFlat(seg->backsector, in_area, true);

	vertex_t * v1, *v2;

	// Although the plane can be sloped this code will only be called
	// when the edge itself is not.
	double backz = fakebsector->floorplane.ZatPoint(seg->v1);
	double frontz = fakefsector->floorplane.ZatPoint(seg->v1);


	if (fakebsector->GetTexture(sector_t::floor) == skyflatnum) return;
	if (fakebsector->GetPlaneTexZ(sector_t::floor) > Viewpoint.Pos.Z) return;

	if (seg->sidedef == seg->linedef->sidedef[0])
	{
		v1 = seg->linedef->v1;
		v2 = seg->linedef->v2;
	}
	else
	{
		v1 = seg->linedef->v2;
		v2 = seg->linedef->v1;
	}

	ws.x1 = v1->fX();
	ws.y1 = v1->fY();
	ws.x2 = v2->fX();
	ws.y2 = v2->fY();

	ws.z2 = frontz;
	ws.z1 = backz;

	auto vertices = screen->mVertexData->AllocVertices(8);

	CreateFloodStencilPoly(&ws, vertices.first);
	CreateFloodPoly(&ws, vertices.first+4, ws.z1, fakebsector, false);

	gl_floodrendernode *node = NewFloodRenderNode();
    auto pNode = floodFloorSegs.CheckKey(fakebsector->sectornum);
    
    node->next = pNode? *pNode : nullptr;

	node->seg = seg;
	node->vertexindex = vertices.second;
	floodFloorSegs[fakebsector->sectornum] = node;
}
Beispiel #3
0
void FDrawInfo::FloodLowerGap(seg_t * seg)
{
	wallseg ws;
	sector_t ffake, bfake;
	sector_t * fakefsector = hw_FakeFlat(seg->frontsector, &ffake, in_area, true);
	sector_t * fakebsector = hw_FakeFlat(seg->backsector, &bfake, in_area, false);

	vertex_t * v1, * v2;

	// Although the plane can be sloped this code will only be called
	// when the edge itself is not.
	double backz = fakebsector->floorplane.ZatPoint(seg->v1);
	double frontz = fakefsector->floorplane.ZatPoint(seg->v1);


	if (fakebsector->GetTexture(sector_t::floor) == skyflatnum) return;
	if (fakebsector->GetPlaneTexZ(sector_t::floor) > Viewpoint.Pos.Z) return;

	if (seg->sidedef == seg->linedef->sidedef[0])
	{
		v1=seg->linedef->v1;
		v2=seg->linedef->v2;
	}
	else
	{
		v1=seg->linedef->v2;
		v2=seg->linedef->v1;
	}

	ws.x1 = v1->fX();
	ws.y1 = v1->fY();
	ws.x2 = v2->fX();
	ws.y2 = v2->fY();

	ws.z2= frontz;
	ws.z1= backz;

	// Step1: Draw a stencil into the gap
	SetupFloodStencil(&ws);

	// Step2: Project the ceiling plane into the gap
	DrawFloodedPlane(&ws, ws.z1, fakebsector, false);

	// Step3: Delete the stencil
	ClearFloodStencil(&ws);
}
Beispiel #4
0
//==========================================================================
//
// 
//
//==========================================================================
bool HWDrawInfo::DoOneSectorLower(subsector_t * subsec, float Planez, area_t in_area)
{
	// Is there a one-sided wall in this subsector?
	// Do this first to avoid unnecessary recursion
	for (uint32_t i = 0; i < subsec->numlines; i++)
	{
		if (subsec->firstline[i].backsector == NULL) return false;
		if (subsec->firstline[i].PartnerSeg == NULL) return false;
	}

	for (uint32_t 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 = hw_FakeFlat(seg->backsector, in_area, true);

			// Don't bother with slopes
			if (sec->floorplane.isSlope())  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.GetTexture(seg->sidedef->GetTexture(side_t::bottom));
				if (!tex || !tex->isValid()) continue;
				else return false;
			}
		}
		if (!DoOneSectorLower(backsub, Planez, in_area)) return false;
	}
	// all checked ok. This sector is part of the current fake plane

	HandledSubsectors.Push(subsec);
	return 1;
}
Beispiel #5
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;
		}
	}
}