diff --git a/src/r_poly.cpp b/src/r_poly.cpp index a58cb86a5..c641702e1 100644 --- a/src/r_poly.cpp +++ b/src/r_poly.cpp @@ -194,14 +194,29 @@ void RenderPolyBsp::RenderPlane(subsector_t *sub, uint32_t subsectorDepth, bool } } + PolyDrawArgs args; + args.uniforms = uniforms; + args.vinput = vertices; + args.vcount = sub->numlines; + args.mode = TriangleDrawMode::Fan; + args.ccw = true; + args.clipleft = 0; + args.cliptop = 0; + args.clipright = viewwidth; + args.clipbottom = viewheight; + args.stenciltestvalue = 0; + args.stencilwritevalue = 1; + if (!isSky) { - PolyTriangleDrawer::draw(uniforms, vertices, sub->numlines, TriangleDrawMode::Fan, true, 0, viewwidth, 0, viewheight, tex, 0); - PolyTriangleDrawer::stencil(uniforms, vertices, sub->numlines, TriangleDrawMode::Fan, true, 0, viewwidth, 0, viewheight, 0, 1); + args.SetTexture(tex); + PolyTriangleDrawer::draw(args, PolyDrawVariant::Draw); + PolyTriangleDrawer::draw(args, PolyDrawVariant::Stencil); } else { - PolyTriangleDrawer::stencil(uniforms, vertices, sub->numlines, TriangleDrawMode::Fan, true, 0, viewwidth, 0, viewheight, 0, 255); + args.stencilwritevalue = 255; + PolyTriangleDrawer::draw(args, PolyDrawVariant::Stencil); for (uint32_t i = 0; i < sub->numlines; i++) { @@ -284,7 +299,9 @@ void RenderPolyBsp::RenderPlane(subsector_t *sub, uint32_t subsectorDepth, bool wallvert[3] = PlaneVertex(line->v1, frontsector, skyHeight); } - PolyTriangleDrawer::stencil(uniforms, wallvert, 4, TriangleDrawMode::Fan, true, 0, viewwidth, 0, viewheight, 0, 255); + args.vinput = wallvert; + args.vcount = 4; + PolyTriangleDrawer::draw(args, PolyDrawVariant::Stencil); } } } @@ -525,7 +542,21 @@ void RenderPolyBsp::AddSprite(AActor *thing, subsector_t *sub, uint32_t subsecto uniforms.light = (uint32_t)((thing->Sector->lightlevel + actualextralight) / 255.0f * 256.0f); uniforms.flags = 0; uniforms.subsectorDepth = subsectorDepth; - PolyTriangleDrawer::draw(uniforms, vertices, 4, TriangleDrawMode::Fan, true, 0, viewwidth, 0, viewheight, tex, 0); + + PolyDrawArgs args; + args.uniforms = uniforms; + args.vinput = vertices; + args.vcount = 4; + args.mode = TriangleDrawMode::Fan; + args.ccw = true; + args.clipleft = 0; + args.cliptop = 0; + args.clipright = viewwidth; + args.clipbottom = viewheight; + args.stenciltestvalue = 0; + args.stencilwritevalue = 1; + args.SetTexture(tex); + PolyTriangleDrawer::draw(args, PolyDrawVariant::Draw); } void RenderPolyBsp::AddWallSprite(AActor *thing, subsector_t *sub, uint32_t subsectorDepth) @@ -1177,8 +1208,22 @@ void RenderPolyWall::Render(const TriMatrix &worldToClip) uniforms.flags = 0; uniforms.subsectorDepth = SubsectorDepth; - PolyTriangleDrawer::draw(uniforms, vertices, 4, TriangleDrawMode::Fan, true, 0, viewwidth, 0, viewheight, tex, 0); - PolyTriangleDrawer::stencil(uniforms, vertices, 4, TriangleDrawMode::Fan, true, 0, viewwidth, 0, viewheight, 0, 1); + PolyDrawArgs args; + args.uniforms = uniforms; + args.vinput = vertices; + args.vcount = 4; + args.mode = TriangleDrawMode::Fan; + args.ccw = true; + args.clipleft = 0; + args.cliptop = 0; + args.clipright = viewwidth; + args.clipbottom = viewheight; + args.stenciltestvalue = 0; + args.stencilwritevalue = 1; + args.SetTexture(tex); + + PolyTriangleDrawer::draw(args, PolyDrawVariant::Draw); + PolyTriangleDrawer::draw(args, PolyDrawVariant::Stencil); } FTexture *RenderPolyWall::GetTexture() @@ -1504,17 +1549,27 @@ void PolySkyDome::CreateDome() mPrimStart.Push(mVertices.Size()); } -void PolySkyDome::RenderRow(const TriUniforms &uniforms, FTexture *skytex, int row) +void PolySkyDome::RenderRow(PolyDrawArgs &args, int row) { - PolyTriangleDrawer::draw(uniforms, &mVertices[mPrimStart[row]], mPrimStart[row + 1] - mPrimStart[row], TriangleDrawMode::Strip, false, 0, viewwidth, 0, viewheight, skytex, 255); + args.vinput = &mVertices[mPrimStart[row]]; + args.vcount = mPrimStart[row + 1] - mPrimStart[row]; + args.mode = TriangleDrawMode::Strip; + args.ccw = false; + PolyTriangleDrawer::draw(args, PolyDrawVariant::Draw); } -void PolySkyDome::RenderCapColorRow(const TriUniforms &uniforms, FTexture *skytex, int row, bool bottomCap) +void PolySkyDome::RenderCapColorRow(PolyDrawArgs &args, FTexture *skytex, int row, bool bottomCap) { uint32_t solid = skytex->GetSkyCapColor(bottomCap); if (!r_swtruecolor) solid = RGB32k.RGB[(RPART(solid) >> 3)][(GPART(solid) >> 3)][(BPART(solid) >> 3)]; - PolyTriangleDrawer::fill(uniforms, &mVertices[mPrimStart[row]], mPrimStart[row + 1] - mPrimStart[row], TriangleDrawMode::Fan, bottomCap, 0, viewwidth, 0, viewheight, solid, 255); + + args.vinput = &mVertices[mPrimStart[row]]; + args.vcount = mPrimStart[row + 1] - mPrimStart[row]; + args.mode = TriangleDrawMode::Fan; + args.ccw = bottomCap; + args.solidcolor = solid; + PolyTriangleDrawer::draw(args, PolyDrawVariant::Fill); } void PolySkyDome::Render(const TriMatrix &worldToClip) @@ -1540,12 +1595,22 @@ void PolySkyDome::Render(const TriMatrix &worldToClip) int rc = mRows + 1; - RenderCapColorRow(uniforms, frontskytex, 0, false); - RenderCapColorRow(uniforms, frontskytex, rc, true); + PolyDrawArgs args; + args.uniforms = uniforms; + args.clipleft = 0; + args.cliptop = 0; + args.clipright = viewwidth; + args.clipbottom = viewheight; + args.stenciltestvalue = 255; + args.stencilwritevalue = 1; + args.SetTexture(frontskytex); + + RenderCapColorRow(args, frontskytex, 0, false); + RenderCapColorRow(args, frontskytex, rc, true); for (int i = 1; i <= mRows; i++) { - RenderRow(uniforms, frontskytex, i); - RenderRow(uniforms, frontskytex, rc + i); + RenderRow(args, i); + RenderRow(args, rc + i); } } diff --git a/src/r_poly.h b/src/r_poly.h index 55a3d16cf..18997c01d 100644 --- a/src/r_poly.h +++ b/src/r_poly.h @@ -83,8 +83,8 @@ private: void SkyVertex(int r, int c, bool yflip); void CreateSkyHemisphere(bool zflip); void CreateDome(); - void RenderRow(const TriUniforms &uniforms, FTexture *skytex, int row); - void RenderCapColorRow(const TriUniforms &uniforms, FTexture *skytex, int row, bool bottomCap); + void RenderRow(PolyDrawArgs &args, int row); + void RenderCapColorRow(PolyDrawArgs &args, FTexture *skytex, int row, bool bottomCap); TriVertex SetVertex(float xx, float yy, float zz, float uu = 0, float vv = 0); TriVertex SetVertexXYZ(float xx, float yy, float zz, float uu = 0, float vv = 0); diff --git a/src/r_poly_triangle.cpp b/src/r_poly_triangle.cpp index 57165736d..075b4432f 100644 --- a/src/r_poly_triangle.cpp +++ b/src/r_poly_triangle.cpp @@ -40,90 +40,79 @@ #include #endif -void PolyTriangleDrawer::draw(const TriUniforms &uniforms, const TriVertex *vinput, int vcount, TriangleDrawMode mode, bool ccw, int clipleft, int clipright, int cliptop, int clipbottom, FTexture *texture, int stenciltestvalue) +void PolyTriangleDrawer::draw(const PolyDrawArgs &args, PolyDrawVariant variant) { if (r_swtruecolor) - queue_arrays(uniforms, vinput, vcount, mode, ccw, clipleft, clipright, cliptop, clipbottom, (const uint8_t*)texture->GetPixelsBgra(), texture->GetWidth(), texture->GetHeight(), 0, stenciltestvalue, stenciltestvalue); + DrawerCommandQueue::QueueCommand(args, variant); else - draw_arrays(uniforms, vinput, vcount, mode, ccw, clipleft, clipright, cliptop, clipbottom, texture->GetPixels(), texture->GetWidth(), texture->GetHeight(), 0, stenciltestvalue, stenciltestvalue, nullptr, &ScreenPolyTriangleDrawer::draw); + draw_arrays(args, variant, nullptr); } -void PolyTriangleDrawer::fill(const TriUniforms &uniforms, const TriVertex *vinput, int vcount, TriangleDrawMode mode, bool ccw, int clipleft, int clipright, int cliptop, int clipbottom, int solidcolor, int stenciltestvalue) +void PolyTriangleDrawer::draw_arrays(const PolyDrawArgs &drawargs, PolyDrawVariant variant, DrawerThread *thread) { - if (r_swtruecolor) - queue_arrays(uniforms, vinput, vcount, mode, ccw, clipleft, clipright, cliptop, clipbottom, nullptr, 0, 0, solidcolor, stenciltestvalue, stenciltestvalue); - else - draw_arrays(uniforms, vinput, vcount, mode, ccw, clipleft, clipright, cliptop, clipbottom, nullptr, 0, 0, solidcolor, stenciltestvalue, stenciltestvalue, nullptr, &ScreenPolyTriangleDrawer::fill); -} - -void PolyTriangleDrawer::stencil(const TriUniforms &uniforms, const TriVertex *vinput, int vcount, TriangleDrawMode mode, bool ccw, int clipleft, int clipright, int cliptop, int clipbottom, int stenciltestvalue, int stencilwritevalue) -{ - if (r_swtruecolor) - queue_arrays(uniforms, vinput, vcount, mode, ccw, clipleft, clipright, cliptop, clipbottom, nullptr, 0, 0, 0xbeef, stenciltestvalue, stencilwritevalue); - else - draw_arrays(uniforms, vinput, vcount, mode, ccw, clipleft, clipright, cliptop, clipbottom, nullptr, 0, 0, 0, stenciltestvalue, stencilwritevalue, nullptr, &ScreenPolyTriangleDrawer::stencil); -} - -void PolyTriangleDrawer::queue_arrays(const TriUniforms &uniforms, const TriVertex *vinput, int vcount, TriangleDrawMode mode, bool ccw, int clipleft, int clipright, int cliptop, int clipbottom, const uint8_t *texturePixels, int textureWidth, int textureHeight, int solidcolor, int stenciltestvalue, int stencilwritevalue) -{ - if (clipright < clipleft || clipleft < 0 || clipright > MAXWIDTH || clipbottom < cliptop || cliptop < 0 || clipbottom > MAXHEIGHT) + if (drawargs.vcount < 3) return; - DrawerCommandQueue::QueueCommand(uniforms, vinput, vcount, mode, ccw, clipleft, clipright, cliptop, clipbottom, texturePixels, textureWidth, textureHeight, solidcolor, stenciltestvalue, stencilwritevalue); -} - -void PolyTriangleDrawer::draw_arrays(const TriUniforms &uniforms, const TriVertex *vinput, int vcount, TriangleDrawMode mode, bool ccw, int clipleft, int clipright, int cliptop, int clipbottom, const uint8_t *texturePixels, int textureWidth, int textureHeight, int solidcolor, int stenciltestvalue, int stencilwritevalue, DrawerThread *thread, void(*drawfunc)(const ScreenPolyTriangleDrawerArgs *, DrawerThread *)) -{ - if (vcount < 3) - return; + void(*drawfunc)(const ScreenPolyTriangleDrawerArgs *, DrawerThread *); + switch (variant) + { + default: + case PolyDrawVariant::Draw: drawfunc = r_swtruecolor ? ScreenPolyTriangleDrawer::draw32 : ScreenPolyTriangleDrawer::draw; break; + case PolyDrawVariant::Fill: drawfunc = r_swtruecolor ? ScreenPolyTriangleDrawer::fill32 : ScreenPolyTriangleDrawer::fill; break; + case PolyDrawVariant::Stencil: drawfunc = ScreenPolyTriangleDrawer::stencil; break; + } ScreenPolyTriangleDrawerArgs args; args.dest = dc_destorg; args.pitch = dc_pitch; - args.clipleft = clipleft; - args.clipright = clipright; - args.cliptop = cliptop; - args.clipbottom = clipbottom; - args.texturePixels = texturePixels; - args.textureWidth = textureWidth; - args.textureHeight = textureHeight; - args.solidcolor = solidcolor; - args.uniforms = &uniforms; - args.stencilTestValue = stenciltestvalue; - args.stencilWriteValue = stencilwritevalue; + args.clipleft = drawargs.clipleft; + args.clipright = drawargs.clipright; + args.cliptop = drawargs.cliptop; + args.clipbottom = drawargs.clipbottom; + args.texturePixels = drawargs.texturePixels; + args.textureWidth = drawargs.textureWidth; + args.textureHeight = drawargs.textureHeight; + args.solidcolor = drawargs.solidcolor; + args.uniforms = &drawargs.uniforms; + args.stencilTestValue = drawargs.stenciltestvalue; + args.stencilWriteValue = drawargs.stencilwritevalue; args.stencilPitch = PolyStencilBuffer::Instance()->BlockWidth(); args.stencilValues = PolyStencilBuffer::Instance()->Values(); args.stencilMasks = PolyStencilBuffer::Instance()->Masks(); args.subsectorGBuffer = PolySubsectorGBuffer::Instance()->Values(); + bool ccw = drawargs.ccw; + const TriVertex *vinput = drawargs.vinput; + int vcount = drawargs.vcount; + TriVertex vert[3]; - if (mode == TriangleDrawMode::Normal) + if (drawargs.mode == TriangleDrawMode::Normal) { for (int i = 0; i < vcount / 3; i++) { for (int j = 0; j < 3; j++) - vert[j] = shade_vertex(uniforms, *(vinput++)); + vert[j] = shade_vertex(drawargs.uniforms, *(vinput++)); draw_shaded_triangle(vert, ccw, &args, thread, drawfunc); } } - else if (mode == TriangleDrawMode::Fan) + else if (drawargs.mode == TriangleDrawMode::Fan) { - vert[0] = shade_vertex(uniforms, *(vinput++)); - vert[1] = shade_vertex(uniforms, *(vinput++)); + vert[0] = shade_vertex(drawargs.uniforms, *(vinput++)); + vert[1] = shade_vertex(drawargs.uniforms, *(vinput++)); for (int i = 2; i < vcount; i++) { - vert[2] = shade_vertex(uniforms, *(vinput++)); + vert[2] = shade_vertex(drawargs.uniforms, *(vinput++)); draw_shaded_triangle(vert, ccw, &args, thread, drawfunc); vert[1] = vert[2]; } } else // TriangleDrawMode::Strip { - vert[0] = shade_vertex(uniforms, *(vinput++)); - vert[1] = shade_vertex(uniforms, *(vinput++)); + vert[0] = shade_vertex(drawargs.uniforms, *(vinput++)); + vert[1] = shade_vertex(drawargs.uniforms, *(vinput++)); for (int i = 2; i < vcount; i++) { - vert[2] = shade_vertex(uniforms, *(vinput++)); + vert[2] = shade_vertex(drawargs.uniforms, *(vinput++)); draw_shaded_triangle(vert, ccw, &args, thread, drawfunc); vert[0] = vert[1]; vert[1] = vert[2]; @@ -1324,19 +1313,14 @@ float ScreenPolyTriangleDrawer::grady(float x0, float y0, float x1, float y1, fl ///////////////////////////////////////////////////////////////////////////// -DrawPolyTrianglesCommand::DrawPolyTrianglesCommand(const TriUniforms &uniforms, const TriVertex *vinput, int vcount, TriangleDrawMode mode, bool ccw, int clipleft, int clipright, int cliptop, int clipbottom, const uint8_t *texturePixels, int textureWidth, int textureHeight, int solidcolor, int stenciltestvalue, int stencilwritevalue) - : uniforms(uniforms), vinput(vinput), vcount(vcount), mode(mode), ccw(ccw), clipleft(clipleft), clipright(clipright), cliptop(cliptop), clipbottom(clipbottom), texturePixels(texturePixels), textureWidth(textureWidth), textureHeight(textureHeight), solidcolor(solidcolor), stenciltestvalue(stenciltestvalue), stencilwritevalue(stencilwritevalue) +DrawPolyTrianglesCommand::DrawPolyTrianglesCommand(const PolyDrawArgs &args, PolyDrawVariant variant) + : args(args), variant(variant) { } void DrawPolyTrianglesCommand::Execute(DrawerThread *thread) { - PolyTriangleDrawer::draw_arrays( - uniforms, vinput, vcount, mode, ccw, - clipleft, clipright, cliptop, clipbottom, - texturePixels, textureWidth, textureHeight, solidcolor, - stenciltestvalue, stencilwritevalue, - thread, texturePixels ? ScreenPolyTriangleDrawer::draw32 : solidcolor != 0xbeef ? ScreenPolyTriangleDrawer::fill32 : ScreenPolyTriangleDrawer::stencil); + PolyTriangleDrawer::draw_arrays(args, variant, thread); } FString DrawPolyTrianglesCommand::DebugInfo() diff --git a/src/r_poly_triangle.h b/src/r_poly_triangle.h index f0a93eb8c..d6e1d3341 100644 --- a/src/r_poly_triangle.h +++ b/src/r_poly_triangle.h @@ -28,22 +28,55 @@ struct ScreenPolyTriangleDrawerArgs; +enum class PolyDrawVariant +{ + Draw, + Fill, + Stencil +}; + +class PolyDrawArgs +{ +public: + TriUniforms uniforms; + const TriVertex *vinput = nullptr; + int vcount = 0; + TriangleDrawMode mode = TriangleDrawMode::Normal; + bool ccw = false; + int clipleft = 0; + int clipright = 0; + int cliptop = 0; + int clipbottom = 0; + const uint8_t *texturePixels = nullptr; + int textureWidth = 0; + int textureHeight = 0; + int solidcolor = 0; + int stenciltestvalue = 0; + int stencilwritevalue = 0; + + void SetTexture(FTexture *texture) + { + textureWidth = texture->GetWidth(); + textureHeight = texture->GetHeight(); + if (r_swtruecolor) + texturePixels = (const uint8_t *)texture->GetPixelsBgra(); + else + texturePixels = texture->GetPixels(); + } +}; + class PolyTriangleDrawer { public: - static void draw(const TriUniforms &uniforms, const TriVertex *vinput, int vcount, TriangleDrawMode mode, bool ccw, int clipleft, int clipright, int cliptop, int clipbottom, FTexture *texture, int stenciltestvalue); - static void fill(const TriUniforms &uniforms, const TriVertex *vinput, int vcount, TriangleDrawMode mode, bool ccw, int clipleft, int clipright, int cliptop, int clipbottom, int solidcolor, int stenciltestvalue); - static void stencil(const TriUniforms &uniforms, const TriVertex *vinput, int vcount, TriangleDrawMode mode, bool ccw, int clipleft, int clipright, int cliptop, int clipbottom, int stenciltestvalue, int stencilwritevalue); + static void draw(const PolyDrawArgs &args, PolyDrawVariant variant); private: static TriVertex shade_vertex(const TriUniforms &uniforms, TriVertex v); - static void draw_arrays(const TriUniforms &uniforms, const TriVertex *vinput, int vcount, TriangleDrawMode mode, bool ccw, int clipleft, int clipright, int cliptop, int clipbottom, const uint8_t *texturePixels, int textureWidth, int textureHeight, int solidcolor, int stenciltestvalue, int stencilwritevalue, DrawerThread *thread, void(*drawfunc)(const ScreenPolyTriangleDrawerArgs *, DrawerThread *)); + static void draw_arrays(const PolyDrawArgs &args, PolyDrawVariant variant, DrawerThread *thread); static void draw_shaded_triangle(const TriVertex *vertices, bool ccw, ScreenPolyTriangleDrawerArgs *args, DrawerThread *thread, void(*drawfunc)(const ScreenPolyTriangleDrawerArgs *, DrawerThread *)); static bool cullhalfspace(float clipdistance1, float clipdistance2, float &t1, float &t2); static void clipedge(const TriVertex *verts, TriVertex *clippedvert, int &numclipvert); - static void queue_arrays(const TriUniforms &uniforms, const TriVertex *vinput, int vcount, TriangleDrawMode mode, bool ccw, int clipleft, int clipright, int cliptop, int clipbottom, const uint8_t *texturePixels, int textureWidth, int textureHeight, int solidcolor, int stenciltestvalue, int stencilwritevalue); - enum { max_additional_vertices = 16 }; friend class DrawPolyTrianglesCommand; @@ -234,27 +267,14 @@ private: class DrawPolyTrianglesCommand : public DrawerCommand { public: - DrawPolyTrianglesCommand(const TriUniforms &uniforms, const TriVertex *vinput, int vcount, TriangleDrawMode mode, bool ccw, int clipleft, int clipright, int cliptop, int clipbottom, const uint8_t *texturePixels, int textureWidth, int textureHeight, int solidcolor, int stenciltestvalue, int stencilwritevalue); + DrawPolyTrianglesCommand(const PolyDrawArgs &args, PolyDrawVariant variant); void Execute(DrawerThread *thread) override; FString DebugInfo() override; private: - TriUniforms uniforms; - const TriVertex *vinput; - int vcount; - TriangleDrawMode mode; - bool ccw; - int clipleft; - int clipright; - int cliptop; - int clipbottom; - const uint8_t *texturePixels; - int textureWidth; - int textureHeight; - int solidcolor; - int stenciltestvalue; - int stencilwritevalue; + PolyDrawArgs args; + PolyDrawVariant variant; }; #endif