diff --git a/source/CMakeLists.txt b/source/CMakeLists.txt index 236daa0df..7c20121a2 100644 --- a/source/CMakeLists.txt +++ b/source/CMakeLists.txt @@ -1077,6 +1077,7 @@ set (PCH_SOURCES core/rendering/scene/hw_drawlistadd.cpp core/rendering/scene/hw_drawlist.cpp core/rendering/scene/hw_drawinfo.cpp + core/rendering/scene/hw_bunchdrawer.cpp core/console/c_notifybuffer.cpp core/console/d_event.cpp diff --git a/source/core/rendering/scene/hw_bunchdrawer.cpp b/source/core/rendering/scene/hw_bunchdrawer.cpp new file mode 100644 index 000000000..058cf31ac --- /dev/null +++ b/source/core/rendering/scene/hw_bunchdrawer.cpp @@ -0,0 +1,496 @@ +/* +** hw_bunchdrawer.cpp +** +**--------------------------------------------------------------------------- +** Copyright 2008-2921 Christoph Oelckers +** All rights reserved. +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** +** 1. Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** 2. Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** 3. The name of the author may not be used to endorse or promote products +** derived from this software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**--------------------------------------------------------------------------- +** +*/ + +#include "hw_drawinfo.h" +#include "hw_bunchdrawer.h" +#include "hw_clipper.h" +#include "hw_clock.h" +#include "hw_drawstructs.h" +#include "automap.h" +#include "render.h" + + + +//========================================================================== +// +// +// +//========================================================================== + +void BunchDrawer::Init(FDrawInfo *_di, Clipper* c, vec2_t& view) +{ + di = _di; + clipper = c; + viewx = view.x * (1/ 16.f); + viewy = view.y * -(1/ 16.f); + StartScene(); + clipper->SetViewpoint(DVector2(viewx, viewy)); + for (int i = 0; i < numwalls; i++) + { + // Precalculate the clip angles to avoid doing this repeatedly during level traversal. + // Reverse the orientation so that startangle and endangle are properly ordered. + wall[i].clipangle = 0 - clipper->PointToPseudoAngle(wall[i].x * (1 / 16.f), wall[i].y * (-1 / 16.f)); + } +} + +//========================================================================== +// +// +// +//========================================================================== + +void BunchDrawer::StartScene() +{ + LastBunch = 0; + StartTime = I_msTime(); + Bunches.Clear(); + CompareData.Clear(); + gotsector.Zero(); +} + +//========================================================================== +// +// +// +//========================================================================== + +void BunchDrawer::StartBunch(int sectnum, int linenum, angle_t startan, angle_t endan) +{ + FBunch* bunch = &Bunches[LastBunch = Bunches.Reserve(1)]; + + bunch->sectnum = sectnum; + bunch->startline = bunch->endline = linenum; + bunch->startangle = startan; + bunch->endangle = endan; +} + +//========================================================================== +// +// +// +//========================================================================== + +void BunchDrawer::AddLineToBunch(int line, int newan) +{ + Bunches[LastBunch].endline++; + Bunches[LastBunch].endangle = newan; +} + +//========================================================================== +// +// +// +//========================================================================== + +void BunchDrawer::DeleteBunch(int index) +{ + Bunches[index] = Bunches.Last(); + Bunches.Pop(); +} + +bool BunchDrawer::CheckClip(walltype* wal) +{ + auto pt2 = &wall[wal->point2]; + sectortype* backsector = §or[wal->nextsector]; + sectortype* frontsector = §or[wall[wal->nextwall].nextsector]; + float bs_floorheight1; + float bs_floorheight2; + float bs_ceilingheight1; + float bs_ceilingheight2; + float fs_floorheight1; + float fs_floorheight2; + float fs_ceilingheight1; + float fs_ceilingheight2; + + // Mirrors and horizons always block the view + //if (linedef->special==Line_Mirror || linedef->special==Line_Horizon) return true; + + PlanesAtPoint(frontsector, wal->x, wal->y, &fs_ceilingheight1, &fs_floorheight1); + PlanesAtPoint(frontsector, pt2->x, pt2->y, &fs_ceilingheight2, &fs_floorheight2); + + PlanesAtPoint(backsector, wal->x, wal->y, &bs_ceilingheight1, &bs_floorheight1); + PlanesAtPoint(backsector, pt2->x, pt2->y, &bs_ceilingheight2, &bs_floorheight2); + + // now check for closed sectors! No idea if we really need the sky checks. We'll see. + if (bs_ceilingheight1 <= fs_floorheight1 && bs_ceilingheight2 <= fs_floorheight2) + { + // backsector's ceiling is below frontsector's floor. + if (frontsector->ceilingstat & backsector->ceilingstat & CSTAT_SECTOR_SKY) return false; + return true; + } + + if (fs_ceilingheight1 <= bs_floorheight1 && fs_ceilingheight2 <= bs_floorheight2) + { + // backsector's floor is above frontsector's ceiling + if (frontsector->floorstat & backsector->floorstat & CSTAT_SECTOR_SKY) return false; + return true; + } + + if (bs_ceilingheight1 <= bs_floorheight1 && bs_ceilingheight2 <= bs_floorheight2) + { + // backsector is closed + if (frontsector->ceilingstat & backsector->ceilingstat & CSTAT_SECTOR_SKY) return false; + if (frontsector->floorstat & backsector->floorstat & CSTAT_SECTOR_SKY) return false; + return true; + } + + return false; +} + +//========================================================================== +// +// ClipLine +// Clips the given segment +// +//========================================================================== + +int BunchDrawer::ClipLine(int line) +{ + angle_t startAngle, endAngle; + auto wal = &wall[line]; + + startAngle = wal->clipangle; + endAngle = wall[wal->point2].clipangle; + + // Back side, i.e. backface culling - read: endAngle >= startAngle! + if (startAngle - endAngle < ANGLE_180) + { + return CL_Skip; + } + + if (!clipper->SafeCheckRange(startAngle, endAngle)) + { + return CL_Skip; + } + + if (wal->nextwall == -1 || (wal->cstat & CSTAT_WALL_1WAY) || CheckClip(wal)) + { + // one-sided + clipper->SafeAddClipRange(startAngle, endAngle); + return CL_Draw; + } + else + { + return CL_Draw | CL_Pass; + } +} + +//========================================================================== +// +// +// +//========================================================================== + +void BunchDrawer::ProcessBunch(int bnch) +{ + FBunch* bunch = &Bunches[bnch]; + + ClipWall.Clock(); + for (int i = bunch->startline; i <= bunch->endline; i++) + { + int clipped = ClipLine(i); + + if (clipped & CL_Draw) + { + show2dwall.Set(i); + + //if (gl_render_walls) + { + SetupWall.Clock(); + + HWWall hwwall; + //Printf("Rendering wall %d\n", i); + hwwall.Process(nullptr, &wall[i], §or[bunch->sectnum], wall[i].nextsector<0? nullptr : §or[wall[i].nextsector]); + rendered_lines++; + + SetupWall.Unclock(); + } + } + + if (clipped & CL_Pass) + { + ClipWall.Unclock(); + ProcessSector(wall[i].nextsector); + ClipWall.Clock(); + } + } + ClipWall.Unclock(); +} + +//========================================================================== +// +// +// +//========================================================================== + +int BunchDrawer::WallInFront(int wall1, int wall2) +{ + 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); + + double dx = x1e - x1s; + double dy = y1e - y1s; + + double t1 = PointOnLineSide(x2s, y2s, x1s, y1s, dx, dy); + double t2 = PointOnLineSide(x2e, y2e, x1s, y1s, dx, dy); + if (t1 == 0) + { + if (t2 == 0) return(-1); + t1 = t2; + } + if (t2 == 0) t2 = t1; + + if ((t1 * t2) >= 0) + { + t2 = PointOnLineSide(viewx, viewy, x1s, y1s, dx, dy); + return((t2 * t1) < 0); + } + + dx = x2e - x2s; + dy = y2e - y2s; + t1 = PointOnLineSide(x1s, y1s, x2s, y2s, dx, dy); + t2 = PointOnLineSide(x1e, y1e, x2s, y2s, dx, dy); + if (t1 == 0) + { + if (t2 == 0) return(-1); + t1 = t2; + } + if (t2 == 0) t2 = t1; + if ((t1 * t2) >= 0) + { + t2 = PointOnLineSide(viewx, viewy, x2s, y2s, dx, dy); + return((t2 * t1) >= 0); + } + return(-2); +} + +//========================================================================== +// +// This is a bit more complicated than it looks because angles can wrap +// around so we can only compare angle differences. +// +// Rules: +// 1. Any bunch can span at most 180°. +// 2. 2 bunches can never overlap at both ends +// 3. if there is an overlap one of the 2 starting points must be in the +// overlapping area. +// +//========================================================================== + +int BunchDrawer::BunchInFront(FBunch* b1, FBunch* b2) +{ + angle_t anglecheck, endang; + + if (b2->startangle - b1->startangle < b1->endangle - b1->startangle) + { + // we have an overlap at b2->startangle + anglecheck = b2->startangle - b1->startangle; + + // Find the wall in b1 that overlaps b2->startangle + for (int i = b1->startline; i <= b1->endline; i++) + { + endang = wall[wall[i].point2].clipangle - b1->startangle; + if (endang > anglecheck) + { + // found a line + int ret = WallInFront(b2->startline, i); + return ret; + } + } + } + else if (b1->startangle - b2->startangle < b2->endangle - b2->startangle) + { + // we have an overlap at b1->startangle + anglecheck = b1->startangle - b2->startangle; + + // Find the wall in b2 that overlaps b1->startangle + for (int i = b2->startline; i <= b2->endline; i++) + { + endang = wall[wall[i].point2].clipangle - b2->startangle; + if (endang > anglecheck) + { + // found a line + int ret = WallInFront(i, b1->startline); + return ret; + } + } + } + // we have no overlap + return -1; +} + +//========================================================================== +// +// +// +//========================================================================== + +int BunchDrawer::FindClosestBunch() +{ + int closest = 0; //Almost works, but not quite :( + + CompareData.Clear(); + for (unsigned i = 1; i < Bunches.Size(); i++) + { + switch (BunchInFront(&Bunches[i], &Bunches[closest])) + { + case 0: // i is in front + closest = i; + continue; + + case 1: // i is behind + continue; + + default: // can't determine + CompareData.Push(i); // mark for later comparison + continue; + } + } + + // we need to do a second pass to see how the marked bunches relate to the currently closest one. + for (unsigned i = 0; i < CompareData.Size(); i++) + { + switch (BunchInFront(&Bunches[CompareData[i]], &Bunches[closest])) + { + case 0: // is in front + closest = CompareData[i]; + CompareData[i] = CompareData.Last(); + CompareData.Pop(); + i = 0; // we need to recheck everything that's still marked. + continue; + + case 1: // is behind + CompareData[i] = CompareData.Last(); + CompareData.Pop(); + i--; + continue; + + default: + continue; + + } + } + return closest; +} + +//========================================================================== +// +// +// +//========================================================================== + +void BunchDrawer::ProcessSector(int sectnum) +{ + if (gotsector[sectnum]) return; + gotsector.Set(sectnum); + + Bsp.Clock(); + + auto sect = §or[sectnum]; + bool inbunch; + angle_t startangle; + + //if (sect->validcount == StartTime) return; + //sect->validcount = StartTime; + +#if 0//ndef BUILD_TEST + DoSector(sectnum, false); +#endif + + //Todo: process subsectors + inbunch = false; + for (int i = 0; i < sect->wallnum; i++) + { + auto thiswall = &wall[sect->wallptr + i]; + +#ifdef _DEBUG + // For displaying positions in debugger + DVector2 start = { WallStartX(thiswall), WallStartY(thiswall) }; + DVector2 end = { WallStartX(thiswall->point2), WallStartY(thiswall->point2) }; +#endif + angle_t ang1 = thiswall->clipangle; + angle_t ang2 = wall[thiswall->point2].clipangle; + + if (ang1 - ang2 < ANGLE_180) + { + // Backside + inbunch = false; + } + else if (!clipper->SafeCheckRange(ang1, ang2)) + { + // is it visible? + inbunch = false; + } + else if (!inbunch || ang2 - startangle >= ANGLE_180) + { + // don't let a bunch span more than 180° to avoid problems. + // This limitation ensures that the combined range of 2 + // bunches will always be less than 360° which simplifies + // the distance comparison code because it prevents a + // situation where 2 bunches may overlap at both ends. + + startangle = ang1; + StartBunch(sectnum, sect->wallptr + i, ang1, ang2); + inbunch = true; + } + else + { + AddLineToBunch(sect->wallptr + i, ang2); + } + if (thiswall->point2 != sect->wallptr + i + 1) inbunch = false; + } + Bsp.Unclock(); +} + +//========================================================================== +// +// +// +//========================================================================== + +void BunchDrawer::RenderScene(int viewsector) +{ + ProcessSector(viewsector); + while (Bunches.Size() > 0) + { + int closest = FindClosestBunch(); + ProcessBunch(closest); + DeleteBunch(closest); + } +} diff --git a/source/core/rendering/scene/hw_bunchdrawer.h b/source/core/rendering/scene/hw_bunchdrawer.h new file mode 100644 index 000000000..f1a40e359 --- /dev/null +++ b/source/core/rendering/scene/hw_bunchdrawer.h @@ -0,0 +1,54 @@ +#pragma once + +#include "tarray.h" +#include "basics.h" + +class FDrawInfo; +class Clipper; + +struct FBunch +{ + int sectnum; + int startline; + int endline; + angle_t startangle; // in pseudo angles for the clipper + angle_t endangle; +}; + +class BunchDrawer +{ + FDrawInfo *di; + Clipper *clipper; + int LastBunch; + int StartTime; + TArray Bunches; + TArray CompareData; + double viewx, viewy; + FixedBitArray gotsector; + +private: + + enum + { + CL_Skip = 0, + CL_Draw = 1, + CL_Pass = 2, + }; + + + void StartScene(); + void StartBunch(int sectnum, int linenum, angle_t startan, angle_t endan); + void AddLineToBunch(int line, int newan); + void DeleteBunch(int index); + bool CheckClip(walltype* wal); + int ClipLine(int line); + void ProcessBunch(int bnch); + int WallInFront(int wall1, int wall2); + int BunchInFront(FBunch* b1, FBunch* b2); + int FindClosestBunch(); + void ProcessSector(int sectnum); + +public: + void Init(FDrawInfo* _di, Clipper* c, vec2_t& view); + void RenderScene(int viewsector); +}; diff --git a/source/core/rendering/scene/hw_drawinfo.cpp b/source/core/rendering/scene/hw_drawinfo.cpp index 8410626b5..c92c421a2 100644 --- a/source/core/rendering/scene/hw_drawinfo.cpp +++ b/source/core/rendering/scene/hw_drawinfo.cpp @@ -142,12 +142,11 @@ void HWDrawInfo::StartScene(FRenderViewpoint &parentvp, HWViewpointUniforms *uni VPUniforms.mClipLine.X = -10000000.0f; VPUniforms.mShadowmapFilter = gl_shadowmap_filter; } - mClipper->SetViewpoint(Viewpoint); + mClipper->SetViewpoint(Viewpoint.Pos.XY()); ClearBuffers(); for (int i = 0; i < GLDL_TYPES; i++) drawlists[i].Reset(); - hudsprites.Clear(); vpIndex = 0; // Fullbright information needs to be propagated from the main view. @@ -295,14 +294,17 @@ HWDecal* HWDrawInfo::AddDecal(bool onmirror) // //----------------------------------------------------------------------------- -void HWDrawInfo::CreateScene(bool drawpsprites) +void HWDrawInfo::CreateScene() { const auto &vp = Viewpoint; - angle_t a1 = FrustumAngle(); - mClipper->SafeAddClipRangeRealAngles(vp.Angles.Yaw.BAMs() + a1, vp.Angles.Yaw.BAMs() - a1); + angle_t a1 = FrustumAngle(); + mClipper->SafeAddClipRangeRealAngles(vp.RotAngle + a1, vp.RotAngle - a1); + +#if 0 // reset the portal manager portalState.StartFrame(); +#endif ProcessAll.Clock(); @@ -380,7 +382,9 @@ void HWDrawInfo::RenderScene(FRenderState &state) // Part 4: Draw decals (not a real pass) state.SetDepthFunc(DF_LEqual); +#if 0 DrawDecals(state, Decals[0]); +#endif RenderAll.Unclock(); } @@ -422,6 +426,7 @@ void HWDrawInfo::RenderTranslucent(FRenderState &state) void HWDrawInfo::RenderPortal(HWPortal *p, FRenderState &state, bool usestencil) { +#if 0 auto gp = static_cast(p); gp->SetupStencil(this, state, usestencil); auto new_di = StartDrawInfo(this, Viewpoint, &VPUniforms); @@ -432,7 +437,7 @@ void HWDrawInfo::RenderPortal(HWPortal *p, FRenderState &state, bool usestencil) state.SetVertexBuffer(screen->mVertexData); screen->mViewpoints->Bind(state, vpIndex); gp->RemoveStencil(this, state, usestencil); - +#endif } //----------------------------------------------------------------------------- @@ -544,11 +549,13 @@ void HWDrawInfo::DrawScene(int drawmode) ssao_portals_available--; } - CreateScene(false); + CreateScene(); auto& RenderState = *screen->RenderState(); RenderState.SetDepthMask(true); +#if 0 if (!gl_no_skyclear) portalState.RenderFirstSkyPortal(recursion, this, RenderState); +#endif RenderScene(RenderState); @@ -561,7 +568,9 @@ void HWDrawInfo::DrawScene(int drawmode) // Handle all portals after rendering the opaque objects but before // doing all translucent stuff recursion++; +#if 0 portalState.EndFrame(this, RenderState); +#endif recursion--; RenderTranslucent(RenderState); } @@ -575,9 +584,10 @@ void HWDrawInfo::DrawScene(int drawmode) void HWDrawInfo::ProcessScene(bool toscreen) { +#if 0 portalState.BeginScene(); +#endif DrawScene(toscreen ? DM_MAINVIEW : DM_OFFSCREEN); - } //========================================================================== diff --git a/source/core/rendering/scene/hw_drawinfo.h b/source/core/rendering/scene/hw_drawinfo.h index 236d807f3..8c0182e36 100644 --- a/source/core/rendering/scene/hw_drawinfo.h +++ b/source/core/rendering/scene/hw_drawinfo.h @@ -7,7 +7,8 @@ #include "hw_viewpointuniforms.h" #include "v_video.h" #include "hw_drawlist.h" -#include "r_viewpoint.h" +#include "hw_bunchdrawer.h" +//#include "r_viewpoint.h" enum EDrawMode { @@ -25,7 +26,6 @@ class HWSprite; struct HWDecal; class IShadowMap; struct FDynLightData; -struct HUDSprite; class Clipper; class HWPortal; class FFlatVertexBuffer; @@ -33,6 +33,13 @@ class IRenderQueue; class HWScenePortalBase; class FRenderState; +struct FRenderViewpoint +{ + DVector3 Pos; + FRotator HWAngles; + FAngle FieldOfView; + angle_t RotAngle; +}; //========================================================================== // // these are used to link faked planes due to missing textures to a sector @@ -89,12 +96,12 @@ struct HWDrawInfo HWPortal *mClipPortal; HWPortal *mCurrentPortal; //FRotator mAngles; + BunchDrawer mDrawer; Clipper *mClipper; - //FRenderViewpoint Viewpoint; + FRenderViewpoint Viewpoint; HWViewpointUniforms VPUniforms; // per-viewpoint uniform state TArray Portals; TArray Decals[2]; // the second slot is for mirrors which get rendered in a separate pass. - TArray hudsprites; // These may just be stored by value. TArray HandledSubsectors; @@ -105,10 +112,7 @@ struct HWDrawInfo bool multithread; private: - // For ProcessLowerMiniseg bool inview; -// sectortype * viewsubsector; -// sectortype *currentsubsector; // used by the line processing code. sectortype *currentsector; void WorkerThread(); @@ -150,13 +154,13 @@ public: HWPortal * FindPortal(const void * src); - //static HWDrawInfo *StartDrawInfo(HWDrawInfo *parent, FRenderViewpoint &parentvp, HWViewpointUniforms *uniforms); - //void StartScene(FRenderViewpoint &parentvp, HWViewpointUniforms *uniforms); + static HWDrawInfo *StartDrawInfo(HWDrawInfo *parent, FRenderViewpoint &parentvp, HWViewpointUniforms *uniforms); + void StartScene(FRenderViewpoint &parentvp, HWViewpointUniforms *uniforms); void ClearBuffers(); HWDrawInfo *EndDrawInfo(); void DrawScene(int drawmode); - void CreateScene(bool drawpsprites); + void CreateScene(); void RenderScene(FRenderState &state); void RenderTranslucent(FRenderState &state); void RenderPortal(HWPortal *p, FRenderState &state, bool usestencil); diff --git a/source/core/rendering/scene/hw_drawlist.cpp b/source/core/rendering/scene/hw_drawlist.cpp index 13adce468..7ac13ff16 100644 --- a/source/core/rendering/scene/hw_drawlist.cpp +++ b/source/core/rendering/scene/hw_drawlist.cpp @@ -507,12 +507,12 @@ void HWDrawList::SortSpriteIntoWall(HWDrawInfo *di, SortNode * head,SortNode * s { const bool drawWithXYBillboard = false;// - const bool drawBillboardFacingCamera = gl_billboard_faces_camera; // [Nash] has +ROLLSPRITE const bool rotated = false;// // cannot sort them at the moment. This requires more complex splitting. /* + const bool drawBillboardFacingCamera = gl_billboard_faces_camera; if (drawWithXYBillboard || drawBillboardFacingCamera || rotated) { float v1 = wh->PointOnSide(ss->x, ss->y); diff --git a/source/core/rendering/scene/hw_drawstructs.h b/source/core/rendering/scene/hw_drawstructs.h index 02a2ced5e..56fe42c85 100644 --- a/source/core/rendering/scene/hw_drawstructs.h +++ b/source/core/rendering/scene/hw_drawstructs.h @@ -279,10 +279,7 @@ public: void ProcessSector(HWDrawInfo *di, sectortype * frontsector, int which = 7 /*SSRF_RENDERALL*/); // cannot use constant due to circular dependencies. void DrawSubsectors(HWDrawInfo *di, FRenderState &state); - void DrawFlat(HWDrawInfo *di, FRenderState &state, bool translucent); - - void DrawOtherPlanes(HWDrawInfo *di, FRenderState &state); - void DrawFloodPlanes(HWDrawInfo *di, FRenderState &state); + void DrawFlat(HWDrawInfo* di, FRenderState& state, bool translucent) {} }; //========================================================================== @@ -334,11 +331,11 @@ public: public: - void CreateVertices(HWDrawInfo *di); + void CreateVertices(HWDrawInfo* di) {} void PutSprite(HWDrawInfo *di, bool translucent); void Process(HWDrawInfo *di, AActor* thing,sectortype * sector, int thruportal = false); - void DrawSprite(HWDrawInfo *di, FRenderState &state, bool translucent); + void DrawSprite(HWDrawInfo* di, FRenderState& state, bool translucent) {} }; diff --git a/source/core/rendering/scene/hw_walls.cpp b/source/core/rendering/scene/hw_walls.cpp index 9ab5bf1f0..3e4d21c38 100644 --- a/source/core/rendering/scene/hw_walls.cpp +++ b/source/core/rendering/scene/hw_walls.cpp @@ -41,6 +41,42 @@ #include "glbackend/glbackend.h" +//========================================================================== +// +// Create vertices for one wall +// +//========================================================================== + +int HWWall::CreateVertices(FFlatVertex*& ptr, bool split) +{ + auto oo = ptr; + ptr->Set(glseg.x1, zbottom[0], glseg.y1, tcs[LOLFT].u, tcs[LOLFT].v); + ptr++; + ptr->Set(glseg.x1, ztop[0], glseg.y1, tcs[UPLFT].u, tcs[UPLFT].v); + ptr++; + ptr->Set(glseg.x2, ztop[1], glseg.y2, tcs[UPRGT].u, tcs[UPRGT].v); + ptr++; + ptr->Set(glseg.x2, zbottom[1], glseg.y2, tcs[LORGT].u, tcs[LORGT].v); + ptr++; + return int(ptr - oo); +} + +//========================================================================== +// +// build the vertices for this wall +// +//========================================================================== + +void HWWall::MakeVertices(HWDrawInfo* di, bool nosplit) +{ + if (vertcount == 0) + { + auto ret = screen->mVertexData->AllocVertices(4); + vertindex = ret.second; + vertcount = CreateVertices(ret.first, false); + } +} + //========================================================================== // // General purpose wall rendering function diff --git a/source/glbackend/glbackend.cpp b/source/glbackend/glbackend.cpp index f967a8923..c10742a92 100644 --- a/source/glbackend/glbackend.cpp +++ b/source/glbackend/glbackend.cpp @@ -58,7 +58,7 @@ CUSTOM_CVARD(Bool, hw_useindexedcolortextures, false, CVAR_ARCHIVE | CVAR_GLOBAL if (screen) screen->SetTextureFilterMode(); } -CVAR(Bool, gl_texture, true, 0) +EXTERN_CVAR(Bool, gl_texture) F2DDrawer twodpsp; static int BufferLock = 0;