diff --git a/src/polyrenderer/drawers/poly_draw_args.cpp b/src/polyrenderer/drawers/poly_draw_args.cpp index 29d32a2fc7..028d76c769 100644 --- a/src/polyrenderer/drawers/poly_draw_args.cpp +++ b/src/polyrenderer/drawers/poly_draw_args.cpp @@ -37,14 +37,6 @@ #include "poly_draw_args.h" #include "swrenderer/viewport/r_viewport.h" -void PolyDrawArgs::SetClipPlane(const PolyClipPlane &plane) -{ - mClipPlane[0] = plane.A; - mClipPlane[1] = plane.B; - mClipPlane[2] = plane.C; - mClipPlane[3] = plane.D; -} - void PolyDrawArgs::SetTexture(const uint8_t *texels, int width, int height) { mTexturePixels = texels; diff --git a/src/polyrenderer/drawers/poly_draw_args.h b/src/polyrenderer/drawers/poly_draw_args.h index 0d84d24dfb..1bc1c1ccac 100644 --- a/src/polyrenderer/drawers/poly_draw_args.h +++ b/src/polyrenderer/drawers/poly_draw_args.h @@ -48,7 +48,7 @@ public: class PolyDrawArgs { public: - void SetClipPlane(const PolyClipPlane &plane); + void SetClipPlane(int index, const PolyClipPlane &plane) { mClipPlane[index] = plane; } void SetTexture(const uint8_t *texels, int width, int height); void SetTexture(FTexture *texture); void SetTexture(FTexture *texture, uint32_t translationID, bool forcePal = false); @@ -66,7 +66,7 @@ public: void DrawArray(const TriVertex *vertices, int vcount, PolyDrawMode mode = PolyDrawMode::Triangles); const TriMatrix *ObjectToClip() const { return mObjectToClip; } - const float *ClipPlane() const { return mClipPlane; } + const PolyClipPlane &ClipPlane(int index) const { return mClipPlane[index]; } const TriVertex *Vertices() const { return mVertices; } int VertexCount() const { return mVertexCount; } @@ -126,7 +126,7 @@ private: uint8_t mStencilTestValue = 0; uint8_t mStencilWriteValue = 0; const uint8_t *mColormaps = nullptr; - float mClipPlane[4] = { 0.0f, 0.0f, 0.0f, 1.0f }; + PolyClipPlane mClipPlane[3]; TriBlendMode mBlendMode = TriBlendMode::FillOpaque; uint32_t mLight = 0; uint32_t mColor = 0; diff --git a/src/polyrenderer/drawers/poly_triangle.cpp b/src/polyrenderer/drawers/poly_triangle.cpp index c411dff275..3d4b08dc42 100644 --- a/src/polyrenderer/drawers/poly_triangle.cpp +++ b/src/polyrenderer/drawers/poly_triangle.cpp @@ -111,28 +111,28 @@ void PolyTriangleDrawer::draw_arrays(const PolyDrawArgs &drawargs, WorkerThreadD for (int i = 0; i < vcount / 3; i++) { for (int j = 0; j < 3; j++) - vert[j] = shade_vertex(*drawargs.ObjectToClip(), drawargs.ClipPlane(), *(vinput++)); + vert[j] = shade_vertex(drawargs, *(vinput++)); draw_shaded_triangle(vert, ccw, &args, thread); } } else if (drawargs.DrawMode() == PolyDrawMode::TriangleFan) { - vert[0] = shade_vertex(*drawargs.ObjectToClip(), drawargs.ClipPlane(), *(vinput++)); - vert[1] = shade_vertex(*drawargs.ObjectToClip(), drawargs.ClipPlane(), *(vinput++)); + vert[0] = shade_vertex(drawargs, *(vinput++)); + vert[1] = shade_vertex(drawargs, *(vinput++)); for (int i = 2; i < vcount; i++) { - vert[2] = shade_vertex(*drawargs.ObjectToClip(), drawargs.ClipPlane(), *(vinput++)); + vert[2] = shade_vertex(drawargs, *(vinput++)); draw_shaded_triangle(vert, ccw, &args, thread); vert[1] = vert[2]; } } else // TriangleDrawMode::TriangleStrip { - vert[0] = shade_vertex(*drawargs.ObjectToClip(), drawargs.ClipPlane(), *(vinput++)); - vert[1] = shade_vertex(*drawargs.ObjectToClip(), drawargs.ClipPlane(), *(vinput++)); + vert[0] = shade_vertex(drawargs, *(vinput++)); + vert[1] = shade_vertex(drawargs, *(vinput++)); for (int i = 2; i < vcount; i++) { - vert[2] = shade_vertex(*drawargs.ObjectToClip(), drawargs.ClipPlane(), *(vinput++)); + vert[2] = shade_vertex(drawargs, *(vinput++)); draw_shaded_triangle(vert, ccw, &args, thread); vert[0] = vert[1]; vert[1] = vert[2]; @@ -141,13 +141,20 @@ void PolyTriangleDrawer::draw_arrays(const PolyDrawArgs &drawargs, WorkerThreadD } } -ShadedTriVertex PolyTriangleDrawer::shade_vertex(const TriMatrix &objectToClip, const float *clipPlane, const TriVertex &v) +ShadedTriVertex PolyTriangleDrawer::shade_vertex(const PolyDrawArgs &drawargs, const TriVertex &v) { - // Apply transform to get clip coordinates: - ShadedTriVertex sv = objectToClip * v; + const TriMatrix &objectToClip = *drawargs.ObjectToClip(); - // Calculate gl_ClipDistance[0] - sv.clipDistance0 = v.x * clipPlane[0] + v.y * clipPlane[1] + v.z * clipPlane[2] + v.w * clipPlane[3]; + // Apply transform to get clip coordinates: + ShadedTriVertex sv; + sv.position = objectToClip * v; + + // Calculate gl_ClipDistance[i] + for (int i = 0; i < 3; i++) + { + const auto &clipPlane = drawargs.ClipPlane(i); + sv.clipDistance[i] = v.x * clipPlane.A + v.y * clipPlane.B + v.z * clipPlane.C + v.w * clipPlane.D; + } return sv; } @@ -155,12 +162,12 @@ ShadedTriVertex PolyTriangleDrawer::shade_vertex(const TriMatrix &objectToClip, bool PolyTriangleDrawer::is_degenerate(const ShadedTriVertex *vert) { // A degenerate triangle has a zero cross product for two of its sides. - float ax = vert[1].x - vert[0].x; - float ay = vert[1].y - vert[0].y; - float az = vert[1].w - vert[0].w; - float bx = vert[2].x - vert[0].x; - float by = vert[2].y - vert[0].y; - float bz = vert[2].w - vert[0].w; + float ax = vert[1].position.x - vert[0].position.x; + float ay = vert[1].position.y - vert[0].position.y; + float az = vert[1].position.w - vert[0].position.w; + float bx = vert[2].position.x - vert[0].position.x; + float by = vert[2].position.y - vert[0].position.y; + float bz = vert[2].position.w - vert[0].position.w; float crossx = ay * bz - az * by; float crossy = az * bx - ax * bz; float crossz = ax * by - ay * bx; @@ -274,22 +281,25 @@ int PolyTriangleDrawer::clipedge(const ShadedTriVertex *verts, TriVertex *clippe // -v.w <= v.z <= v.w // halfspace clip distances - static const int numclipdistances = 7; + static const int numclipdistances = 9; #ifdef NO_SSE float clipdistance[numclipdistances * 3]; bool needsclipping = false; float *clipd = clipdistance; for (int i = 0; i < 3; i++) { - const auto &v = verts[i]; + const auto &v = verts[i].position; clipd[0] = v.x + v.w; clipd[1] = v.w - v.x; clipd[2] = v.y + v.w; clipd[3] = v.w - v.y; clipd[4] = v.z + v.w; clipd[5] = v.w - v.z; - clipd[6] = v.clipDistance0; - needsclipping = needsclipping || clipd[0] < 0.0f || clipd[1] < 0.0f || clipd[2] < 0.0f || clipd[3] < 0.0f || clipd[4] < 0.0f || clipd[5] < 0.0f || clipd[6] < 0.0f; + clipd[6] = verts[i].clipDistance[0]; + clipd[7] = verts[i].clipDistance[1]; + clipd[8] = verts[i].clipDistance[2]; + for (int j = 0; j < 9; j++) + needsclipping = needsclipping || clipd[i]; clipd += numclipdistances; } @@ -298,14 +308,14 @@ int PolyTriangleDrawer::clipedge(const ShadedTriVertex *verts, TriVertex *clippe { for (int i = 0; i < 3; i++) { - memcpy(clippedvert + i, verts + i, sizeof(TriVertex)); + memcpy(clippedvert + i, &verts[i].position, sizeof(TriVertex)); } return 3; } #else - __m128 mx = _mm_loadu_ps(&verts[0].x); - __m128 my = _mm_loadu_ps(&verts[1].x); - __m128 mz = _mm_loadu_ps(&verts[2].x); + __m128 mx = _mm_loadu_ps(&verts[0].position.x); + __m128 my = _mm_loadu_ps(&verts[1].position.x); + __m128 mz = _mm_loadu_ps(&verts[2].position.x); __m128 mw = _mm_setzero_ps(); _MM_TRANSPOSE4_PS(mx, my, mz, mw); __m128 clipd0 = _mm_add_ps(mx, mw); @@ -314,7 +324,9 @@ int PolyTriangleDrawer::clipedge(const ShadedTriVertex *verts, TriVertex *clippe __m128 clipd3 = _mm_sub_ps(mw, my); __m128 clipd4 = _mm_add_ps(mz, mw); __m128 clipd5 = _mm_sub_ps(mw, mz); - __m128 clipd6 = _mm_setr_ps(verts[0].clipDistance0, verts[1].clipDistance0, verts[2].clipDistance0, 0.0f); + __m128 clipd6 = _mm_setr_ps(verts[0].clipDistance[0], verts[1].clipDistance[0], verts[2].clipDistance[0], 0.0f); + __m128 clipd7 = _mm_setr_ps(verts[0].clipDistance[1], verts[1].clipDistance[1], verts[2].clipDistance[1], 0.0f); + __m128 clipd8 = _mm_setr_ps(verts[0].clipDistance[2], verts[1].clipDistance[2], verts[2].clipDistance[2], 0.0f); __m128 mneedsclipping = _mm_cmplt_ps(clipd0, _mm_setzero_ps()); mneedsclipping = _mm_or_ps(mneedsclipping, _mm_cmplt_ps(clipd1, _mm_setzero_ps())); mneedsclipping = _mm_or_ps(mneedsclipping, _mm_cmplt_ps(clipd2, _mm_setzero_ps())); @@ -322,11 +334,13 @@ int PolyTriangleDrawer::clipedge(const ShadedTriVertex *verts, TriVertex *clippe mneedsclipping = _mm_or_ps(mneedsclipping, _mm_cmplt_ps(clipd4, _mm_setzero_ps())); mneedsclipping = _mm_or_ps(mneedsclipping, _mm_cmplt_ps(clipd5, _mm_setzero_ps())); mneedsclipping = _mm_or_ps(mneedsclipping, _mm_cmplt_ps(clipd6, _mm_setzero_ps())); + mneedsclipping = _mm_or_ps(mneedsclipping, _mm_cmplt_ps(clipd7, _mm_setzero_ps())); + mneedsclipping = _mm_or_ps(mneedsclipping, _mm_cmplt_ps(clipd8, _mm_setzero_ps())); if (_mm_movemask_ps(mneedsclipping) == 0) { for (int i = 0; i < 3; i++) { - memcpy(clippedvert + i, verts + i, sizeof(TriVertex)); + memcpy(clippedvert + i, &verts[i].position, sizeof(TriVertex)); } return 3; } @@ -338,6 +352,8 @@ int PolyTriangleDrawer::clipedge(const ShadedTriVertex *verts, TriVertex *clippe _mm_storeu_ps(clipdistance + 16, clipd4); _mm_storeu_ps(clipdistance + 20, clipd5); _mm_storeu_ps(clipdistance + 24, clipd6); + _mm_storeu_ps(clipdistance + 28, clipd7); + _mm_storeu_ps(clipdistance + 32, clipd8); #endif // use barycentric weights while clipping vertices @@ -417,12 +433,12 @@ int PolyTriangleDrawer::clipedge(const ShadedTriVertex *verts, TriVertex *clippe for (int w = 0; w < 3; w++) { float weight = input[i * 3 + w]; - v.x += verts[w].x * weight; - v.y += verts[w].y * weight; - v.z += verts[w].z * weight; - v.w += verts[w].w * weight; - v.u += verts[w].u * weight; - v.v += verts[w].v * weight; + v.x += verts[w].position.x * weight; + v.y += verts[w].position.y * weight; + v.z += verts[w].position.z * weight; + v.w += verts[w].position.w * weight; + v.u += verts[w].position.u * weight; + v.v += verts[w].position.v * weight; } } return inputverts; diff --git a/src/polyrenderer/drawers/poly_triangle.h b/src/polyrenderer/drawers/poly_triangle.h index c663cd2d00..d48a64e993 100644 --- a/src/polyrenderer/drawers/poly_triangle.h +++ b/src/polyrenderer/drawers/poly_triangle.h @@ -29,9 +29,10 @@ #include "polyrenderer/drawers/poly_buffer.h" #include "polyrenderer/drawers/poly_draw_args.h" -struct ShadedTriVertex : public TriVertex +struct ShadedTriVertex { - float clipDistance0; + TriVertex position; + float clipDistance[3]; }; typedef void(*PolyDrawFuncPtr)(const TriDrawTriangleArgs *, WorkerThreadData *); @@ -44,7 +45,7 @@ public: static bool is_mirror(); private: - static ShadedTriVertex shade_vertex(const TriMatrix &objectToClip, const float *clipPlane, const TriVertex &v); + static ShadedTriVertex shade_vertex(const PolyDrawArgs &drawargs, const TriVertex &v); static void draw_arrays(const PolyDrawArgs &args, WorkerThreadData *thread); static void draw_shaded_triangle(const ShadedTriVertex *vertices, bool ccw, TriDrawTriangleArgs *args, WorkerThreadData *thread); static bool is_degenerate(const ShadedTriVertex *vertices); diff --git a/src/polyrenderer/math/tri_matrix.cpp b/src/polyrenderer/math/tri_matrix.cpp index f6bb03a5e3..9c4b347724 100644 --- a/src/polyrenderer/math/tri_matrix.cpp +++ b/src/polyrenderer/math/tri_matrix.cpp @@ -173,14 +173,14 @@ TriMatrix TriMatrix::operator*(const TriMatrix &mult) const return result; } -ShadedTriVertex TriMatrix::operator*(TriVertex v) const +TriVertex TriMatrix::operator*(TriVertex v) const { #ifdef NO_SSE float vx = matrix[0 * 4 + 0] * v.x + matrix[1 * 4 + 0] * v.y + matrix[2 * 4 + 0] * v.z + matrix[3 * 4 + 0] * v.w; float vy = matrix[0 * 4 + 1] * v.x + matrix[1 * 4 + 1] * v.y + matrix[2 * 4 + 1] * v.z + matrix[3 * 4 + 1] * v.w; float vz = matrix[0 * 4 + 2] * v.x + matrix[1 * 4 + 2] * v.y + matrix[2 * 4 + 2] * v.z + matrix[3 * 4 + 2] * v.w; float vw = matrix[0 * 4 + 3] * v.x + matrix[1 * 4 + 3] * v.y + matrix[2 * 4 + 3] * v.z + matrix[3 * 4 + 3] * v.w; - ShadedTriVertex sv; + TriVertex sv; sv.x = vx; sv.y = vy; sv.z = vz; @@ -196,7 +196,7 @@ ShadedTriVertex TriMatrix::operator*(TriVertex v) const m2 = _mm_mul_ps(m2, _mm_shuffle_ps(mv, mv, _MM_SHUFFLE(2, 2, 2, 2))); m3 = _mm_mul_ps(m3, _mm_shuffle_ps(mv, mv, _MM_SHUFFLE(3, 3, 3, 3))); mv = _mm_add_ps(_mm_add_ps(_mm_add_ps(m0, m1), m2), m3); - ShadedTriVertex sv; + TriVertex sv; _mm_storeu_ps(&sv.x, mv); #endif sv.u = v.u; diff --git a/src/polyrenderer/math/tri_matrix.h b/src/polyrenderer/math/tri_matrix.h index 960d5d0282..d6212316ea 100644 --- a/src/polyrenderer/math/tri_matrix.h +++ b/src/polyrenderer/math/tri_matrix.h @@ -23,7 +23,6 @@ #pragma once struct TriVertex; -struct ShadedTriVertex; struct FRenderViewpoint; struct TriMatrix @@ -40,7 +39,7 @@ struct TriMatrix //static TriMatrix worldToView(const FRenderViewpoint &viewpoint); // Software renderer world to view space transform //static TriMatrix viewToClip(double focalTangent, double centerY, double invZtoScale); // Software renderer shearing projection - ShadedTriVertex operator*(TriVertex v) const; + TriVertex operator*(TriVertex v) const; TriMatrix operator*(const TriMatrix &m) const; float matrix[16]; diff --git a/src/polyrenderer/scene/poly_decal.cpp b/src/polyrenderer/scene/poly_decal.cpp index 6ffd24439f..5aa177051e 100644 --- a/src/polyrenderer/scene/poly_decal.cpp +++ b/src/polyrenderer/scene/poly_decal.cpp @@ -189,7 +189,7 @@ void RenderPolyDecal::Render(const TriMatrix &worldToClip, const PolyClipPlane & args.SetFaceCullCCW(true); args.SetStencilTestValue(stencilValue); args.SetWriteStencil(true, stencilValue); - args.SetClipPlane(clipPlane); + args.SetClipPlane(0, clipPlane); args.SetDepthTest(true); args.SetWriteStencil(false); args.SetWriteDepth(false); diff --git a/src/polyrenderer/scene/poly_particle.cpp b/src/polyrenderer/scene/poly_particle.cpp index 1a67de786f..088d38b172 100644 --- a/src/polyrenderer/scene/poly_particle.cpp +++ b/src/polyrenderer/scene/poly_particle.cpp @@ -83,7 +83,7 @@ void RenderPolyParticle::Render(const TriMatrix &worldToClip, const PolyClipPlan args.SetStencilTestValue(stencilValue); args.SetWriteStencil(false); args.SetWriteDepth(false); - args.SetClipPlane(clipPlane); + args.SetClipPlane(0, clipPlane); args.SetTexture(GetParticleTexture(), ParticleTextureSize, ParticleTextureSize); args.DrawArray(vertices, 4, PolyDrawMode::TriangleFan); } diff --git a/src/polyrenderer/scene/poly_plane.cpp b/src/polyrenderer/scene/poly_plane.cpp index 6ad9eb0549..c8eb3baa2a 100644 --- a/src/polyrenderer/scene/poly_plane.cpp +++ b/src/polyrenderer/scene/poly_plane.cpp @@ -146,7 +146,7 @@ void RenderPolyPlane::Render3DFloor(const TriMatrix &worldToClip, const PolyClip args.SetStencilTestValue(stencilValue); args.SetWriteStencil(true, stencilValue + 1); args.SetTexture(tex); - args.SetClipPlane(clipPlane); + args.SetClipPlane(0, clipPlane); args.DrawArray(vertices, sub->numlines, PolyDrawMode::TriangleFan); } @@ -313,13 +313,13 @@ void RenderPolyPlane::Render(const TriMatrix &worldToClip, const PolyClipPlane & lightlevel = clamp(lightlevel + actualextralight, 0, 255); PolyDrawArgs args; - args.SetLight(GetColorTable(frontsector->Colormap, frontsector->SpecialColors[ceiling]), lightlevel, PolyRenderer::Instance()->Light.WallGlobVis(foggy), false); + args.SetLight(GetColorTable(frontsector->Colormap, frontsector->SpecialColors[ceiling ? sector_t::ceiling : sector_t::floor]), lightlevel, PolyRenderer::Instance()->Light.WallGlobVis(foggy), false); //args.SetSubsectorDepth(isSky ? RenderPolyScene::SkySubsectorDepth : subsectorDepth); args.SetTransform(&worldToClip); args.SetFaceCullCCW(ccw); args.SetStencilTestValue(stencilValue); args.SetWriteStencil(true, stencilValue + 1); - args.SetClipPlane(clipPlane); + args.SetClipPlane(0, clipPlane); if (!isSky) { diff --git a/src/polyrenderer/scene/poly_scene.cpp b/src/polyrenderer/scene/poly_scene.cpp index b37e2027aa..c85fc7575a 100644 --- a/src/polyrenderer/scene/poly_scene.cpp +++ b/src/polyrenderer/scene/poly_scene.cpp @@ -376,7 +376,7 @@ void RenderPolyScene::RenderPortals(int portalDepth) args.SetTransform(&WorldToClip); args.SetLight(&NormalLight, 255, PolyRenderer::Instance()->Light.WallGlobVis(foggy), true); args.SetColor(0, 0); - args.SetClipPlane(PortalPlane); + args.SetClipPlane(0, PortalPlane); args.SetStyle(TriBlendMode::FillOpaque); for (auto &portal : SectorPortals) @@ -416,7 +416,7 @@ void RenderPolyScene::RenderTranslucent(int portalDepth) args.SetTransform(&WorldToClip); args.SetStencilTestValue(portal->StencilValue + 1); args.SetWriteStencil(true, StencilValue + 1); - args.SetClipPlane(PortalPlane); + args.SetClipPlane(0, PortalPlane); for (const auto &verts : portal->Shape) { args.SetFaceCullCCW(verts.Ccw); @@ -434,7 +434,7 @@ void RenderPolyScene::RenderTranslucent(int portalDepth) args.SetTransform(&WorldToClip); args.SetStencilTestValue(portal->StencilValue + 1); args.SetWriteStencil(true, StencilValue + 1); - args.SetClipPlane(PortalPlane); + args.SetClipPlane(0, PortalPlane); for (const auto &verts : portal->Shape) { args.SetFaceCullCCW(verts.Ccw); diff --git a/src/polyrenderer/scene/poly_sky.cpp b/src/polyrenderer/scene/poly_sky.cpp index 531fb6be5c..5b90b623cd 100644 --- a/src/polyrenderer/scene/poly_sky.cpp +++ b/src/polyrenderer/scene/poly_sky.cpp @@ -86,7 +86,7 @@ void PolySkyDome::Render(const TriMatrix &worldToClip) args.SetTransform(&objectToClip); args.SetStencilTestValue(255); args.SetWriteStencil(true, 1); - args.SetClipPlane(PolyClipPlane(0.0f, 0.0f, 0.0f, 1.0f)); + args.SetClipPlane(0, PolyClipPlane(0.0f, 0.0f, 0.0f, 1.0f)); RenderCapColorRow(args, mCurrentSetup.frontskytex, 0, false); RenderCapColorRow(args, mCurrentSetup.frontskytex, rc, true); diff --git a/src/polyrenderer/scene/poly_sprite.cpp b/src/polyrenderer/scene/poly_sprite.cpp index 02667b19b9..ab35b11c1a 100644 --- a/src/polyrenderer/scene/poly_sprite.cpp +++ b/src/polyrenderer/scene/poly_sprite.cpp @@ -158,7 +158,7 @@ void RenderPolySprite::Render(const TriMatrix &worldToClip, const PolyClipPlane args.SetFaceCullCCW(true); args.SetStencilTestValue(stencilValue); args.SetWriteStencil(true, stencilValue); - args.SetClipPlane(clipPlane); + args.SetClipPlane(0, clipPlane); if ((thing->renderflags & RF_ZDOOMTRANS) && r_UseVanillaTransparency) args.SetStyle(LegacyRenderStyles[STYLE_Normal], 1.0f, thing->fillcolor, thing->Translation, tex, fullbrightSprite); else diff --git a/src/polyrenderer/scene/poly_wall.cpp b/src/polyrenderer/scene/poly_wall.cpp index 0a882cee40..83bc0d3d3b 100644 --- a/src/polyrenderer/scene/poly_wall.cpp +++ b/src/polyrenderer/scene/poly_wall.cpp @@ -289,7 +289,7 @@ void RenderPolyWall::Render(const TriMatrix &worldToClip, const PolyClipPlane &c args.SetWriteStencil(true, StencilValue + 1); if (tex && !Polyportal) args.SetTexture(tex); - args.SetClipPlane(clipPlane); + args.SetClipPlane(0, clipPlane); if (FogBoundary) { @@ -314,7 +314,7 @@ void RenderPolyWall::Render(const TriMatrix &worldToClip, const PolyClipPlane &c else if (!Masked) { args.SetStyle(TriBlendMode::TextureOpaque); - args.DrawArray(vertices, 4, PolyDrawMode::TriangleFan); + DrawStripes(args, vertices); } else { @@ -325,12 +325,66 @@ void RenderPolyWall::Render(const TriMatrix &worldToClip, const PolyClipPlane &c args.SetDepthTest(true); args.SetWriteDepth(true); args.SetWriteStencil(false); - args.DrawArray(vertices, 4, PolyDrawMode::TriangleFan); + DrawStripes(args, vertices); } RenderPolyDecal::RenderWallDecals(worldToClip, clipPlane, LineSeg, StencilValue); } +void RenderPolyWall::DrawStripes(PolyDrawArgs &args, TriVertex *vertices) +{ + const auto &lightlist = Line->frontsector->e->XFloor.lightlist; + if (lightlist.Size() > 0) + { + PolyClipPlane topPlane; + + for (unsigned int i = 0; i < lightlist.Size(); i++) + { + lightlist_t *lit = &lightlist[i]; + + DVector3 normal = lit->plane.Normal(); + double d = lit->plane.fD(); + if (normal.Z < 0.0) + { + normal = -normal; + d = -d; + } + + PolyClipPlane bottomPlane = { (float)normal.X, (float)normal.Y, (float)normal.Z, (float)d }; + + args.SetClipPlane(1, topPlane); + args.SetClipPlane(2, bottomPlane); + args.DrawArray(vertices, 4, PolyDrawMode::TriangleFan); + + FDynamicColormap *basecolormap = GetColorTable(lit->extra_colormap, Line->frontsector->SpecialColors[sector_t::walltop]); + + bool foggy = false; + int lightlevel; + PolyCameraLight *cameraLight = PolyCameraLight::Instance(); + if (cameraLight->FixedLightLevel() >= 0 || cameraLight->FixedColormap()) + { + lightlevel = 255; + } + else + { + int actualextralight = foggy ? 0 : PolyRenderer::Instance()->Viewpoint.extralight << 4; + lightlevel = clamp(Side->GetLightLevel(foggy, *lit->p_lightlevel) + actualextralight, 0, 255); + } + args.SetLight(basecolormap, lightlevel, PolyRenderer::Instance()->Light.WallGlobVis(foggy), false); + + topPlane = { (float)-normal.X, (float)-normal.Y, (float)-normal.Z, (float)-d }; + } + + args.SetClipPlane(1, topPlane); + args.SetClipPlane(2, PolyClipPlane()); + args.DrawArray(vertices, 4, PolyDrawMode::TriangleFan); + } + else + { + args.DrawArray(vertices, 4, PolyDrawMode::TriangleFan); + } +} + void RenderPolyWall::ClampHeight(TriVertex &v1, TriVertex &v2) { float top = v1.z; diff --git a/src/polyrenderer/scene/poly_wall.h b/src/polyrenderer/scene/poly_wall.h index 49be175431..3c91da1e1d 100644 --- a/src/polyrenderer/scene/poly_wall.h +++ b/src/polyrenderer/scene/poly_wall.h @@ -65,6 +65,8 @@ private: FTexture *GetTexture(); int GetLightLevel(); + void DrawStripes(PolyDrawArgs &args, TriVertex *vertices); + static bool IsFogBoundary(sector_t *front, sector_t *back); }; diff --git a/src/polyrenderer/scene/poly_wallsprite.cpp b/src/polyrenderer/scene/poly_wallsprite.cpp index 36e02fbb47..de27ad43b3 100644 --- a/src/polyrenderer/scene/poly_wallsprite.cpp +++ b/src/polyrenderer/scene/poly_wallsprite.cpp @@ -105,7 +105,7 @@ void RenderPolyWallSprite::Render(const TriMatrix &worldToClip, const PolyClipPl args.SetFaceCullCCW(true); args.SetStencilTestValue(stencilValue); args.SetTexture(tex); - args.SetClipPlane(clipPlane); + args.SetClipPlane(0, clipPlane); args.SetDepthTest(true); args.SetWriteDepth(false); args.SetWriteStencil(false);