From 389340f97c957880c7ad5a6d6e991ec2aeca4f5b Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 3 May 2021 00:15:09 +0200 Subject: [PATCH] - use sections for rendering. --- source/core/automap.cpp | 20 +-- .../core/rendering/scene/hw_bunchdrawer.cpp | 122 ++++++++++-------- source/core/rendering/scene/hw_bunchdrawer.h | 6 +- source/core/rendering/scene/hw_drawstructs.h | 3 +- source/core/rendering/scene/hw_flats.cpp | 7 +- 5 files changed, 89 insertions(+), 69 deletions(-) diff --git a/source/core/automap.cpp b/source/core/automap.cpp index fc68724d9..1b7ba5519 100644 --- a/source/core/automap.cpp +++ b/source/core/automap.cpp @@ -45,6 +45,7 @@ Modifications for JonoF's port by Jonathon Fowler (jf@jonof.id.au) #include "v_draw.h" #include "sectorgeometry.h" #include "gamefuncs.h" +#include "hw_sections.h" CVAR(Bool, am_followplayer, true, CVAR_ARCHIVE) CVAR(Bool, am_rotate, true, CVAR_ARCHIVE) @@ -590,15 +591,18 @@ void renderDrawMapView(int cposx, int cposy, int czoom, int cang) int picnum = sector[i].floorpicnum; if ((unsigned)picnum >= (unsigned)MAXTILES) continue; - auto mesh = sectorGeometry.get(i, 0, { 0.f,0.f }); - vertices.Resize(mesh->vertices.Size()); - for (unsigned j = 0; j < mesh->vertices.Size(); j++) + for (auto ii : sectionspersector[i]) { - int ox = int(mesh->vertices[j].X * 16.f) - cposx; - int oy = int(mesh->vertices[j].Y * -16.f) - cposy; - int x1 = DMulScale(ox, xvect, -oy, yvect, 16) + (width << 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 }; + auto mesh = sectorGeometry.get(ii, 0, { 0.f,0.f }); + vertices.Resize(mesh->vertices.Size()); + for (unsigned j = 0; j < mesh->vertices.Size(); j++) + { + int ox = int(mesh->vertices[j].X * 16.f) - cposx; + int oy = int(mesh->vertices[j].Y * -16.f) - cposy; + int x1 = DMulScale(ox, xvect, -oy, yvect, 16) + (width << 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 }; + } } int translation = TRANSLATION(Translation_Remap + curbasepal, sector[i].floorpal); diff --git a/source/core/rendering/scene/hw_bunchdrawer.cpp b/source/core/rendering/scene/hw_bunchdrawer.cpp index 0033157a0..e6299e618 100644 --- a/source/core/rendering/scene/hw_bunchdrawer.cpp +++ b/source/core/rendering/scene/hw_bunchdrawer.cpp @@ -43,6 +43,7 @@ #include "hw_voxels.h" #include "mapinfo.h" #include "gamecontrol.h" +#include "hw_sections.h" extern TArray 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. wall[i].clipangle = clipper->PointToAngle(wall[i].pos); } - for (int i = 0; i < numsectors; i++) - { - sectstartang[i] = -1; - sectendang[i] = -1; - } + memset(sectionstartang, -1, sizeof(sectionstartang)); + memset(sectionendang, -1, sizeof(sectionendang)); } //========================================================================== @@ -93,7 +91,7 @@ void BunchDrawer::StartScene() Bunches.Clear(); CompareData.Clear(); gotsector.Zero(); - gotsector2.Zero(); + gotsection2.Zero(); gotwall.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 = §ionLines[aline]; + int section = cline->section; + int line = cline->wall; - auto wal = &wall[line]; - - auto startAngleBam = wal->clipangle; - auto endAngleBam = wall[wal->point2].clipangle; + auto startAngleBam = wall[cline->startpoint].clipangle; + auto endAngleBam = wall[cline->endpoint].clipangle; // Back side, i.e. backface culling - read: endAngle <= startAngle! if (startAngleBam.asbam() - endAngleBam.asbam() < ANGLE_180) { return CL_Skip; } + if (line >= 0 && blockwall[line]) return CL_Draw; + // convert to clipper coordinates and clamp to valid range. int startAngle = startAngleBam.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; // since these values are derived from previous calls of this function they cannot be out of range. - int sect = wal->sector; - int sectStartAngle = sectstartang[sect]; - auto sectEndAngle = sectendang[sect]; + int sectStartAngle = sectionstartang[section]; + auto sectEndAngle = sectionendang[section]; // 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. @@ -239,7 +238,8 @@ int BunchDrawer::ClipLine(int line, bool portal) 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 if (!portal) clipper->AddClipRange(startAngle, endAngle); @@ -250,16 +250,16 @@ int BunchDrawer::ClipLine(int line, bool portal) if (portal) clipper->RemoveClipRange(startAngle, endAngle); // set potentially visible viewing range for this line's back sector. - int nsect = wal->nextsector; - if (sectstartang[nsect] == -1) + int nsection = cline->partnersection; + if (sectionstartang[nsection] == -1) { - sectstartang[nsect] = startAngle; - sectendang[nsect] = endAngle; + sectionstartang[nsection] = startAngle; + sectionendang[nsection] = endAngle; } else { - if (startAngle < sectstartang[nsect]) sectstartang[nsect] = startAngle; - if (endAngle > sectendang[nsect]) sectendang[nsect] = endAngle; + if (startAngle < sectionstartang[nsection]) sectionstartang[nsection] = startAngle; + if (endAngle > sectionendang[nsection]) sectionendang[nsection] = endAngle; } return CL_Draw | CL_Pass; @@ -283,8 +283,8 @@ void BunchDrawer::ProcessBunch(int bnch) if (clipped & CL_Draw) { - for (auto p : blockingpairs[i]) blockwall.Set(p); - show2dwall.Set(i); + for (auto p : blockingpairs[i]) blockwall.Set(sectionLines[p].wall); + show2dwall.Set(sectionLines[i].wall); if (!gotwall[i]) { @@ -294,7 +294,8 @@ void BunchDrawer::ProcessBunch(int bnch) SetupWall.Clock(); HWWall hwwall; - hwwall.Process(di, &wall[i], §or[bunch->sectnum], wall[i].nextsector < 0 ? nullptr : §or[wall[i].nextsector]); + int j = sectionLines[i].wall; + hwwall.Process(di, &wall[j], §or[bunch->sectnum], wall[j].nextsector < 0 ? nullptr : §or[wall[j].nextsector]); rendered_lines++; SetupWall.Unclock(); @@ -306,7 +307,7 @@ void BunchDrawer::ProcessBunch(int bnch) if (clipped & CL_Pass) { ClipWall.Unclock(); - ProcessSector(wall[i].nextsector, false); + ProcessSection(sectionLines[i].partnersection, false); 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); - double y1s = WallStartY(wall1); - double x1e = WallEndX(wall1); - double y1e = WallEndY(wall1); - double x2s = WallStartX(wall2); - double y2s = WallStartY(wall2); - double x2e = WallEndX(wall2); - double y2e = WallEndY(wall2); + int wall1s = sectionLines[line1].startpoint; + int wall1e = sectionLines[line1].endpoint; + int wall2s = sectionLines[line2].startpoint; + int wall2e = sectionLines[line2].endpoint; + + double x1s = WallStartX(wall1s); + double y1s = WallStartY(wall1s); + 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 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; - gotsector2.Set(sectnum); + if (gotsection2[sectionnum]) return; + gotsection2.Set(sectionnum); - auto sect = §or[sectnum]; bool inbunch; binangle startangle; SetupSprite.Clock(); int z; + int sectnum = sections[sectionnum].sector; if (!gotsector[sectnum]) { gotsector.Set(sectnum); @@ -526,22 +532,23 @@ void BunchDrawer::ProcessSector(int sectnum, bool portal) SetupFlat.Clock(); HWFlat flat; - flat.ProcessSector(di, §or[sectnum]); + flat.ProcessSector(di, §or[sectnum], sectionnum); SetupFlat.Unclock(); //Todo: process subsectors inbunch = false; - for (int i = 0; i < sect->wallnum; i++) + auto section = §ions[sectionnum]; + for (unsigned i = 0; i < section->lines.Size(); i++) { - auto thiswall = &wall[sect->wallptr + i]; + auto thisline = §ionLines[section->lines[i]]; #ifdef _DEBUG // For displaying positions in debugger - DVector2 start = { WallStartX(thiswall), WallStartY(thiswall) }; - DVector2 end = { WallStartX(thiswall->point2), WallStartY(thiswall->point2) }; + //DVector2 start = { WallStartX(thiswall), WallStartY(thiswall) }; + //DVector2 end = { WallStartX(thiswall->point2), WallStartY(thiswall->point2) }; #endif - binangle walang1 = thiswall->clipangle; - binangle walang2 = wall[thiswall->point2].clipangle; + binangle walang1 = wall[thisline->startpoint].clipangle; + binangle walang2 = wall[thisline->endpoint].clipangle; // outside the visible area or seen from the backside. 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; //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 { //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++) { - sectstartang[viewsectors[i]] = 0; - sectendang[viewsectors[i]] = int (ang2.asbam() - ang1.asbam()); + for (auto j : sectionspersector[viewsectors[i]]) + { + sectionstartang[j] = 0; + sectionendang[j] = int(ang2.asbam() - ang1.asbam()); + } } - for (unsigned i = 0; i < sectcount; i++) - ProcessSector(viewsectors[i], portal); + { + for (auto j : sectionspersector[viewsectors[i]]) + { + ProcessSection(j, portal); + } + } while (Bunches.Size() > 0) { int closest = FindClosestBunch(); @@ -607,7 +621,7 @@ void BunchDrawer::RenderScene(const int* viewsectors, unsigned sectcount, bool p ang1 = bamang(rotang - ANGLE_90); ang2 = bamang(rotang + ANGLE_90 - 1); process(); - gotsector2.Zero(); + gotsection2.Zero(); ang1 = bamang(rotang + ANGLE_90); ang2 = bamang(rotang - ANGLE_90 - 1); process(); diff --git a/source/core/rendering/scene/hw_bunchdrawer.h b/source/core/rendering/scene/hw_bunchdrawer.h index f230fb570..685ca25bc 100644 --- a/source/core/rendering/scene/hw_bunchdrawer.h +++ b/source/core/rendering/scene/hw_bunchdrawer.h @@ -28,12 +28,12 @@ class BunchDrawer vec2_t iview; float gcosang, gsinang; FixedBitArray gotsector; - FixedBitArray gotsector2; + FixedBitArray gotsection2; FixedBitArray gotwall; FixedBitArray blockwall; binangle ang1, ang2; - int sectstartang[MAXSECTORS], sectendang[MAXSECTORS]; + int sectionstartang[MAXSECTORS*5/4], sectionendang[MAXSECTORS*5/4]; private: @@ -54,7 +54,7 @@ private: int WallInFront(int wall1, int wall2); int BunchInFront(FBunch* b1, FBunch* b2); int FindClosestBunch(); - void ProcessSector(int sectnum, bool portal); + void ProcessSection(int sectnum, bool portal); public: void Init(HWDrawInfo* _di, Clipper* c, vec2_t& view, binangle a1, binangle a2); diff --git a/source/core/rendering/scene/hw_drawstructs.h b/source/core/rendering/scene/hw_drawstructs.h index d68fec358..244bb39e1 100644 --- a/source/core/rendering/scene/hw_drawstructs.h +++ b/source/core/rendering/scene/hw_drawstructs.h @@ -249,6 +249,7 @@ public: class HWFlat { public: + int section; sectortype * sec; spritetype* sprite; // for flat sprites. FGameTexture *texture; @@ -275,7 +276,7 @@ public: //void SetupLights(HWDrawInfo *di, FLightNode *head, FDynLightData &lightdata, int portalgroup); 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 DrawSubsectors(HWDrawInfo *di, FRenderState &state); diff --git a/source/core/rendering/scene/hw_flats.cpp b/source/core/rendering/scene/hw_flats.cpp index 8c4160e3f..3b1257d5e 100644 --- a/source/core/rendering/scene/hw_flats.cpp +++ b/source/core/rendering/scene/hw_flats.cpp @@ -98,7 +98,7 @@ void HWFlat::MakeVertices() bool canvas = texture->isHardwareCanvas(); if (sprite == nullptr) { - auto mesh = sectorGeometry.get(sec - sector, plane, geoofs); + auto mesh = sectorGeometry.get(section, plane, geoofs); if (!mesh) return; auto ret = screen->mVertexData->AllocVertices(mesh->vertices.Size()); auto vp = ret.first; @@ -158,7 +158,7 @@ void HWFlat::DrawFlat(HWDrawInfo *di, FRenderState &state, bool translucent) if (!sprite) { - auto mesh = sectorGeometry.get(sec - sector, plane, geoofs); + auto mesh = sectorGeometry.get(section, plane, geoofs); state.SetNormal(mesh->normal); } 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 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. visibility = sectorVisibility(frontsector); sec = frontsector; + section = section_; sprite = nullptr; geoofs = di->geoofs;