- use sections for rendering.

This commit is contained in:
Christoph Oelckers 2021-05-03 00:15:09 +02:00
parent 30b1b046e4
commit 389340f97c
5 changed files with 89 additions and 69 deletions

View file

@ -45,6 +45,7 @@ Modifications for JonoF's port by Jonathon Fowler (jf@jonof.id.au)
#include "v_draw.h" #include "v_draw.h"
#include "sectorgeometry.h" #include "sectorgeometry.h"
#include "gamefuncs.h" #include "gamefuncs.h"
#include "hw_sections.h"
CVAR(Bool, am_followplayer, true, CVAR_ARCHIVE) CVAR(Bool, am_followplayer, true, CVAR_ARCHIVE)
CVAR(Bool, am_rotate, true, CVAR_ARCHIVE) CVAR(Bool, am_rotate, true, CVAR_ARCHIVE)
@ -590,7 +591,9 @@ void renderDrawMapView(int cposx, int cposy, int czoom, int cang)
int picnum = sector[i].floorpicnum; int picnum = sector[i].floorpicnum;
if ((unsigned)picnum >= (unsigned)MAXTILES) continue; if ((unsigned)picnum >= (unsigned)MAXTILES) continue;
auto mesh = sectorGeometry.get(i, 0, { 0.f,0.f }); for (auto ii : sectionspersector[i])
{
auto mesh = sectorGeometry.get(ii, 0, { 0.f,0.f });
vertices.Resize(mesh->vertices.Size()); vertices.Resize(mesh->vertices.Size());
for (unsigned j = 0; j < mesh->vertices.Size(); j++) for (unsigned j = 0; j < mesh->vertices.Size(); j++)
{ {
@ -600,6 +603,7 @@ void renderDrawMapView(int cposx, int cposy, int czoom, int cang)
int y1 = DMulScale(oy, xvect, ox, yvect, 16) + (height << 11); int y1 = DMulScale(oy, xvect, ox, yvect, 16) + (height << 11);
vertices[j] = { x1 / 4096.f, y1 / 4096.f, mesh->texcoords[j].X, mesh->texcoords[j].Y }; vertices[j] = { x1 / 4096.f, y1 / 4096.f, mesh->texcoords[j].X, mesh->texcoords[j].Y };
} }
}
int translation = TRANSLATION(Translation_Remap + curbasepal, sector[i].floorpal); int translation = TRANSLATION(Translation_Remap + curbasepal, sector[i].floorpal);
setgotpic(picnum); setgotpic(picnum);

View file

@ -43,6 +43,7 @@
#include "hw_voxels.h" #include "hw_voxels.h"
#include "mapinfo.h" #include "mapinfo.h"
#include "gamecontrol.h" #include "gamecontrol.h"
#include "hw_sections.h"
extern TArray<int> blockingpairs[MAXWALLS]; extern TArray<int> blockingpairs[MAXWALLS];
@ -73,11 +74,8 @@ void BunchDrawer::Init(HWDrawInfo *_di, Clipper* c, vec2_t& view, binangle a1, b
// Reverse the orientation so that startangle and endangle are properly ordered. // Reverse the orientation so that startangle and endangle are properly ordered.
wall[i].clipangle = clipper->PointToAngle(wall[i].pos); wall[i].clipangle = clipper->PointToAngle(wall[i].pos);
} }
for (int i = 0; i < numsectors; i++) memset(sectionstartang, -1, sizeof(sectionstartang));
{ memset(sectionendang, -1, sizeof(sectionendang));
sectstartang[i] = -1;
sectendang[i] = -1;
}
} }
//========================================================================== //==========================================================================
@ -93,7 +91,7 @@ void BunchDrawer::StartScene()
Bunches.Clear(); Bunches.Clear();
CompareData.Clear(); CompareData.Clear();
gotsector.Zero(); gotsector.Zero();
gotsector2.Zero(); gotsection2.Zero();
gotwall.Zero(); gotwall.Zero();
blockwall.Zero(); blockwall.Zero();
} }
@ -198,20 +196,22 @@ bool BunchDrawer::CheckClip(walltype* wal)
// //
//========================================================================== //==========================================================================
int BunchDrawer::ClipLine(int line, bool portal) int BunchDrawer::ClipLine(int aline, bool portal)
{ {
if (blockwall[line]) return CL_Draw; auto cline = &sectionLines[aline];
int section = cline->section;
int line = cline->wall;
auto wal = &wall[line]; auto startAngleBam = wall[cline->startpoint].clipangle;
auto endAngleBam = wall[cline->endpoint].clipangle;
auto startAngleBam = wal->clipangle;
auto endAngleBam = wall[wal->point2].clipangle;
// Back side, i.e. backface culling - read: endAngle <= startAngle! // Back side, i.e. backface culling - read: endAngle <= startAngle!
if (startAngleBam.asbam() - endAngleBam.asbam() < ANGLE_180) if (startAngleBam.asbam() - endAngleBam.asbam() < ANGLE_180)
{ {
return CL_Skip; return CL_Skip;
} }
if (line >= 0 && blockwall[line]) return CL_Draw;
// convert to clipper coordinates and clamp to valid range. // convert to clipper coordinates and clamp to valid range.
int startAngle = startAngleBam.asbam() - ang1.asbam(); int startAngle = startAngleBam.asbam() - ang1.asbam();
int endAngle = endAngleBam.asbam() - ang1.asbam(); int endAngle = endAngleBam.asbam() - ang1.asbam();
@ -219,9 +219,8 @@ int BunchDrawer::ClipLine(int line, bool portal)
if (endAngle < 0) endAngle = INT_MAX; if (endAngle < 0) endAngle = INT_MAX;
// since these values are derived from previous calls of this function they cannot be out of range. // since these values are derived from previous calls of this function they cannot be out of range.
int sect = wal->sector; int sectStartAngle = sectionstartang[section];
int sectStartAngle = sectstartang[sect]; auto sectEndAngle = sectionendang[section];
auto sectEndAngle = sectendang[sect];
// check against the maximum possible viewing range of the sector. // check against the maximum possible viewing range of the sector.
// Todo: check if this is sufficient or if we really have to do a more costly check against the single visible segments. // Todo: check if this is sufficient or if we really have to do a more costly check against the single visible segments.
@ -239,7 +238,8 @@ int BunchDrawer::ClipLine(int line, bool portal)
return CL_Skip; return CL_Skip;
} }
if (wal->nextwall == -1 || (wal->cstat & CSTAT_WALL_1WAY) || CheckClip(wal)) auto wal = &wall[line];
if (cline->partner == -1 || (wal->cstat & CSTAT_WALL_1WAY) || CheckClip(wal))
{ {
// one-sided // one-sided
if (!portal) clipper->AddClipRange(startAngle, endAngle); if (!portal) clipper->AddClipRange(startAngle, endAngle);
@ -250,16 +250,16 @@ int BunchDrawer::ClipLine(int line, bool portal)
if (portal) clipper->RemoveClipRange(startAngle, endAngle); if (portal) clipper->RemoveClipRange(startAngle, endAngle);
// set potentially visible viewing range for this line's back sector. // set potentially visible viewing range for this line's back sector.
int nsect = wal->nextsector; int nsection = cline->partnersection;
if (sectstartang[nsect] == -1) if (sectionstartang[nsection] == -1)
{ {
sectstartang[nsect] = startAngle; sectionstartang[nsection] = startAngle;
sectendang[nsect] = endAngle; sectionendang[nsection] = endAngle;
} }
else else
{ {
if (startAngle < sectstartang[nsect]) sectstartang[nsect] = startAngle; if (startAngle < sectionstartang[nsection]) sectionstartang[nsection] = startAngle;
if (endAngle > sectendang[nsect]) sectendang[nsect] = endAngle; if (endAngle > sectionendang[nsection]) sectionendang[nsection] = endAngle;
} }
return CL_Draw | CL_Pass; return CL_Draw | CL_Pass;
@ -283,8 +283,8 @@ void BunchDrawer::ProcessBunch(int bnch)
if (clipped & CL_Draw) if (clipped & CL_Draw)
{ {
for (auto p : blockingpairs[i]) blockwall.Set(p); for (auto p : blockingpairs[i]) blockwall.Set(sectionLines[p].wall);
show2dwall.Set(i); show2dwall.Set(sectionLines[i].wall);
if (!gotwall[i]) if (!gotwall[i])
{ {
@ -294,7 +294,8 @@ void BunchDrawer::ProcessBunch(int bnch)
SetupWall.Clock(); SetupWall.Clock();
HWWall hwwall; HWWall hwwall;
hwwall.Process(di, &wall[i], &sector[bunch->sectnum], wall[i].nextsector < 0 ? nullptr : &sector[wall[i].nextsector]); int j = sectionLines[i].wall;
hwwall.Process(di, &wall[j], &sector[bunch->sectnum], wall[j].nextsector < 0 ? nullptr : &sector[wall[j].nextsector]);
rendered_lines++; rendered_lines++;
SetupWall.Unclock(); SetupWall.Unclock();
@ -306,7 +307,7 @@ void BunchDrawer::ProcessBunch(int bnch)
if (clipped & CL_Pass) if (clipped & CL_Pass)
{ {
ClipWall.Unclock(); ClipWall.Unclock();
ProcessSector(wall[i].nextsector, false); ProcessSection(sectionLines[i].partnersection, false);
ClipWall.Clock(); ClipWall.Clock();
} }
} }
@ -319,16 +320,21 @@ void BunchDrawer::ProcessBunch(int bnch)
// //
//========================================================================== //==========================================================================
int BunchDrawer::WallInFront(int wall1, int wall2) int BunchDrawer::WallInFront(int line1, int line2)
{ {
double x1s = WallStartX(wall1); int wall1s = sectionLines[line1].startpoint;
double y1s = WallStartY(wall1); int wall1e = sectionLines[line1].endpoint;
double x1e = WallEndX(wall1); int wall2s = sectionLines[line2].startpoint;
double y1e = WallEndY(wall1); int wall2e = sectionLines[line2].endpoint;
double x2s = WallStartX(wall2);
double y2s = WallStartY(wall2); double x1s = WallStartX(wall1s);
double x2e = WallEndX(wall2); double y1s = WallStartY(wall1s);
double y2e = WallEndY(wall2); double x1e = WallStartX(wall1e);
double y1e = WallStartY(wall1e);
double x2s = WallStartX(wall2s);
double y2s = WallStartY(wall2s);
double x2e = WallStartX(wall2e);
double y2e = WallStartY(wall2e);
double dx = x1e - x1s; double dx = x1e - x1s;
double dy = y1e - y1s; double dy = y1e - y1s;
@ -482,18 +488,18 @@ int BunchDrawer::FindClosestBunch()
// //
//========================================================================== //==========================================================================
void BunchDrawer::ProcessSector(int sectnum, bool portal) void BunchDrawer::ProcessSection(int sectionnum, bool portal)
{ {
if (gotsector2[sectnum]) return; if (gotsection2[sectionnum]) return;
gotsector2.Set(sectnum); gotsection2.Set(sectionnum);
auto sect = &sector[sectnum];
bool inbunch; bool inbunch;
binangle startangle; binangle startangle;
SetupSprite.Clock(); SetupSprite.Clock();
int z; int z;
int sectnum = sections[sectionnum].sector;
if (!gotsector[sectnum]) if (!gotsector[sectnum])
{ {
gotsector.Set(sectnum); gotsector.Set(sectnum);
@ -526,22 +532,23 @@ void BunchDrawer::ProcessSector(int sectnum, bool portal)
SetupFlat.Clock(); SetupFlat.Clock();
HWFlat flat; HWFlat flat;
flat.ProcessSector(di, &sector[sectnum]); flat.ProcessSector(di, &sector[sectnum], sectionnum);
SetupFlat.Unclock(); SetupFlat.Unclock();
//Todo: process subsectors //Todo: process subsectors
inbunch = false; inbunch = false;
for (int i = 0; i < sect->wallnum; i++) auto section = &sections[sectionnum];
for (unsigned i = 0; i < section->lines.Size(); i++)
{ {
auto thiswall = &wall[sect->wallptr + i]; auto thisline = &sectionLines[section->lines[i]];
#ifdef _DEBUG #ifdef _DEBUG
// For displaying positions in debugger // For displaying positions in debugger
DVector2 start = { WallStartX(thiswall), WallStartY(thiswall) }; //DVector2 start = { WallStartX(thiswall), WallStartY(thiswall) };
DVector2 end = { WallStartX(thiswall->point2), WallStartY(thiswall->point2) }; //DVector2 end = { WallStartX(thiswall->point2), WallStartY(thiswall->point2) };
#endif #endif
binangle walang1 = thiswall->clipangle; binangle walang1 = wall[thisline->startpoint].clipangle;
binangle walang2 = wall[thiswall->point2].clipangle; binangle walang2 = wall[thisline->endpoint].clipangle;
// outside the visible area or seen from the backside. // outside the visible area or seen from the backside.
if ((walang1.asbam() - ang1.asbam() > ANGLE_180 && walang2.asbam() - ang1.asbam() > ANGLE_180) || if ((walang1.asbam() - ang1.asbam() > ANGLE_180 && walang2.asbam() - ang1.asbam() > ANGLE_180) ||
@ -554,14 +561,14 @@ void BunchDrawer::ProcessSector(int sectnum, bool portal)
{ {
startangle = walang1; startangle = walang1;
//Printf("Starting bunch:\n\tWall %d\n", sect->wallptr + i); //Printf("Starting bunch:\n\tWall %d\n", sect->wallptr + i);
inbunch = StartBunch(sectnum, sect->wallptr + i, walang1, walang2, portal); inbunch = StartBunch(sectnum, section->lines[i], walang1, walang2, portal);
} }
else else
{ {
//Printf("\tWall %d\n", sect->wallptr + i); //Printf("\tWall %d\n", sect->wallptr + i);
inbunch = AddLineToBunch(sect->wallptr + i, walang2); inbunch = AddLineToBunch(section->lines[i], walang2);
} }
if (thiswall->point2 != sect->wallptr + i + 1) inbunch = false; if (thisline->endpoint != section->lines[i] + 1) inbunch = false;
} }
} }
@ -580,12 +587,19 @@ void BunchDrawer::RenderScene(const int* viewsectors, unsigned sectcount, bool p
for (unsigned i = 0; i < sectcount; i++) for (unsigned i = 0; i < sectcount; i++)
{ {
sectstartang[viewsectors[i]] = 0; for (auto j : sectionspersector[viewsectors[i]])
sectendang[viewsectors[i]] = int (ang2.asbam() - ang1.asbam()); {
sectionstartang[j] = 0;
sectionendang[j] = int(ang2.asbam() - ang1.asbam());
}
} }
for (unsigned i = 0; i < sectcount; i++) for (unsigned i = 0; i < sectcount; i++)
ProcessSector(viewsectors[i], portal); {
for (auto j : sectionspersector[viewsectors[i]])
{
ProcessSection(j, portal);
}
}
while (Bunches.Size() > 0) while (Bunches.Size() > 0)
{ {
int closest = FindClosestBunch(); int closest = FindClosestBunch();
@ -607,7 +621,7 @@ void BunchDrawer::RenderScene(const int* viewsectors, unsigned sectcount, bool p
ang1 = bamang(rotang - ANGLE_90); ang1 = bamang(rotang - ANGLE_90);
ang2 = bamang(rotang + ANGLE_90 - 1); ang2 = bamang(rotang + ANGLE_90 - 1);
process(); process();
gotsector2.Zero(); gotsection2.Zero();
ang1 = bamang(rotang + ANGLE_90); ang1 = bamang(rotang + ANGLE_90);
ang2 = bamang(rotang - ANGLE_90 - 1); ang2 = bamang(rotang - ANGLE_90 - 1);
process(); process();

View file

@ -28,12 +28,12 @@ class BunchDrawer
vec2_t iview; vec2_t iview;
float gcosang, gsinang; float gcosang, gsinang;
FixedBitArray<MAXSECTORS> gotsector; FixedBitArray<MAXSECTORS> gotsector;
FixedBitArray<MAXSECTORS> gotsector2; FixedBitArray<MAXSECTORS*5/4> gotsection2;
FixedBitArray<MAXWALLS> gotwall; FixedBitArray<MAXWALLS> gotwall;
FixedBitArray<MAXWALLS> blockwall; FixedBitArray<MAXWALLS> blockwall;
binangle ang1, ang2; binangle ang1, ang2;
int sectstartang[MAXSECTORS], sectendang[MAXSECTORS]; int sectionstartang[MAXSECTORS*5/4], sectionendang[MAXSECTORS*5/4];
private: private:
@ -54,7 +54,7 @@ private:
int WallInFront(int wall1, int wall2); int WallInFront(int wall1, int wall2);
int BunchInFront(FBunch* b1, FBunch* b2); int BunchInFront(FBunch* b1, FBunch* b2);
int FindClosestBunch(); int FindClosestBunch();
void ProcessSector(int sectnum, bool portal); void ProcessSection(int sectnum, bool portal);
public: public:
void Init(HWDrawInfo* _di, Clipper* c, vec2_t& view, binangle a1, binangle a2); void Init(HWDrawInfo* _di, Clipper* c, vec2_t& view, binangle a1, binangle a2);

View file

@ -249,6 +249,7 @@ public:
class HWFlat class HWFlat
{ {
public: public:
int section;
sectortype * sec; sectortype * sec;
spritetype* sprite; // for flat sprites. spritetype* sprite; // for flat sprites.
FGameTexture *texture; FGameTexture *texture;
@ -275,7 +276,7 @@ public:
//void SetupLights(HWDrawInfo *di, FLightNode *head, FDynLightData &lightdata, int portalgroup); //void SetupLights(HWDrawInfo *di, FLightNode *head, FDynLightData &lightdata, int portalgroup);
void PutFlat(HWDrawInfo* di, int whichplane); void PutFlat(HWDrawInfo* di, int whichplane);
void ProcessSector(HWDrawInfo *di, sectortype * frontsector, int which = 7 /*SSRF_RENDERALL*/); // cannot use constant due to circular dependencies. void ProcessSector(HWDrawInfo *di, sectortype * frontsector, int sectionnum, int which = 7 /*SSRF_RENDERALL*/); // cannot use constant due to circular dependencies.
void ProcessFlatSprite(HWDrawInfo* di, spritetype* sprite, sectortype* sector); void ProcessFlatSprite(HWDrawInfo* di, spritetype* sprite, sectortype* sector);
void DrawSubsectors(HWDrawInfo *di, FRenderState &state); void DrawSubsectors(HWDrawInfo *di, FRenderState &state);

View file

@ -98,7 +98,7 @@ void HWFlat::MakeVertices()
bool canvas = texture->isHardwareCanvas(); bool canvas = texture->isHardwareCanvas();
if (sprite == nullptr) if (sprite == nullptr)
{ {
auto mesh = sectorGeometry.get(sec - sector, plane, geoofs); auto mesh = sectorGeometry.get(section, plane, geoofs);
if (!mesh) return; if (!mesh) return;
auto ret = screen->mVertexData->AllocVertices(mesh->vertices.Size()); auto ret = screen->mVertexData->AllocVertices(mesh->vertices.Size());
auto vp = ret.first; auto vp = ret.first;
@ -158,7 +158,7 @@ void HWFlat::DrawFlat(HWDrawInfo *di, FRenderState &state, bool translucent)
if (!sprite) if (!sprite)
{ {
auto mesh = sectorGeometry.get(sec - sector, plane, geoofs); auto mesh = sectorGeometry.get(section, plane, geoofs);
state.SetNormal(mesh->normal); state.SetNormal(mesh->normal);
} }
else else
@ -230,7 +230,7 @@ void HWFlat::PutFlat(HWDrawInfo *di, int whichplane)
// //
//========================================================================== //==========================================================================
void HWFlat::ProcessSector(HWDrawInfo *di, sectortype * frontsector, int which) void HWFlat::ProcessSector(HWDrawInfo *di, sectortype * frontsector, int section_, int which)
{ {
#ifdef _DEBUG #ifdef _DEBUG
if (frontsector - sector == gl_breaksec) if (frontsector - sector == gl_breaksec)
@ -249,6 +249,7 @@ void HWFlat::ProcessSector(HWDrawInfo *di, sectortype * frontsector, int which)
fade = lookups.getFade(frontsector->floorpal); // fog is per sector. fade = lookups.getFade(frontsector->floorpal); // fog is per sector.
visibility = sectorVisibility(frontsector); visibility = sectorVisibility(frontsector);
sec = frontsector; sec = frontsector;
section = section_;
sprite = nullptr; sprite = nullptr;
geoofs = di->geoofs; geoofs = di->geoofs;