Add plane clipping to the triangle drawer

This commit is contained in:
Magnus Norddahl 2016-11-26 10:49:29 +01:00
parent 8bbb63e913
commit c37ce1fdbc
19 changed files with 146 additions and 99 deletions

View file

@ -191,26 +191,6 @@ struct TriVertex
float varying[NumVarying]; float varying[NumVarying];
}; };
struct TriMatrix
{
static TriMatrix null();
static TriMatrix identity();
static TriMatrix translate(float x, float y, float z);
static TriMatrix scale(float x, float y, float z);
static TriMatrix rotate(float angle, float x, float y, float z);
static TriMatrix swapYZ();
static TriMatrix perspective(float fovy, float aspect, float near, float far);
static TriMatrix frustum(float left, float right, float bottom, float top, float near, float far);
static TriMatrix worldToView(); // Software renderer world to view space transform
static TriMatrix viewToClip(); // Software renderer shearing projection
TriVertex operator*(TriVertex v) const;
TriMatrix operator*(const TriMatrix &m) const;
float matrix[16];
};
struct TriUniforms struct TriUniforms
{ {
uint32_t light; uint32_t light;

View file

@ -44,7 +44,7 @@ void RenderPolyScene::Render()
ClearBuffers(); ClearBuffers();
SetSceneViewport(); SetSceneViewport();
SetupPerspectiveMatrix(); SetupPerspectiveMatrix();
MainPortal.SetViewpoint(WorldToClip, Vec4f(0.0f), GetNextStencilValue()); MainPortal.SetViewpoint(WorldToClip, Vec4f(0.0f, 0.0f, 0.0f, 1.0f), GetNextStencilValue());
MainPortal.Render(0); MainPortal.Render(0);
Skydome.Render(WorldToClip); Skydome.Render(WorldToClip);
MainPortal.RenderTranslucent(0); MainPortal.RenderTranslucent(0);

View file

@ -177,7 +177,7 @@ bool PolyCull::CheckBBox(float *bspcoord)
// Skip if its in front of the portal: // Skip if its in front of the portal:
if (PortalClipPlane != Vec4f(0.0f) && IntersectionTest::plane_aabb(PortalClipPlane, aabb) == IntersectionTest::outside) if (IntersectionTest::plane_aabb(PortalClipPlane, aabb) == IntersectionTest::outside)
return false; return false;
// Occlusion test using solid segments: // Occlusion test using solid segments:

View file

@ -29,7 +29,7 @@
#include "r_poly.h" #include "r_poly.h"
#include "a_sharedglobal.h" #include "a_sharedglobal.h"
void RenderPolyDecal::RenderWallDecals(const TriMatrix &worldToClip, const seg_t *line, uint32_t subsectorDepth, uint32_t stencilValue) void RenderPolyDecal::RenderWallDecals(const TriMatrix &worldToClip, const Vec4f &clipPlane, const seg_t *line, uint32_t subsectorDepth, uint32_t stencilValue)
{ {
if (line->linedef == nullptr && line->sidedef == nullptr) if (line->linedef == nullptr && line->sidedef == nullptr)
return; return;
@ -37,11 +37,11 @@ void RenderPolyDecal::RenderWallDecals(const TriMatrix &worldToClip, const seg_t
for (DBaseDecal *decal = line->sidedef->AttachedDecals; decal != nullptr; decal = decal->WallNext) for (DBaseDecal *decal = line->sidedef->AttachedDecals; decal != nullptr; decal = decal->WallNext)
{ {
RenderPolyDecal render; RenderPolyDecal render;
render.Render(worldToClip, decal, line, subsectorDepth, stencilValue); render.Render(worldToClip, clipPlane, decal, line, subsectorDepth, stencilValue);
} }
} }
void RenderPolyDecal::Render(const TriMatrix &worldToClip, DBaseDecal *decal, const seg_t *line, uint32_t subsectorDepth, uint32_t stencilValue) void RenderPolyDecal::Render(const TriMatrix &worldToClip, const Vec4f &clipPlane, DBaseDecal *decal, const seg_t *line, uint32_t subsectorDepth, uint32_t stencilValue)
{ {
if (decal->RenderFlags & RF_INVISIBLE || !viewactive || !decal->PicNum.isValid()) if (decal->RenderFlags & RF_INVISIBLE || !viewactive || !decal->PicNum.isValid())
return; return;
@ -166,5 +166,6 @@ void RenderPolyDecal::Render(const TriMatrix &worldToClip, DBaseDecal *decal, co
args.stenciltestvalue = stencilValue; args.stenciltestvalue = stencilValue;
args.stencilwritevalue = stencilValue; args.stencilwritevalue = stencilValue;
//mode = R_SetPatchStyle (decal->RenderStyle, (float)decal->Alpha, decal->Translation, decal->AlphaColor); //mode = R_SetPatchStyle (decal->RenderStyle, (float)decal->Alpha, decal->Translation, decal->AlphaColor);
args.SetClipPlane(clipPlane.x, clipPlane.y, clipPlane.z, clipPlane.w);
PolyTriangleDrawer::draw(args, TriDrawVariant::DrawSubsector, TriBlendMode::Shaded); PolyTriangleDrawer::draw(args, TriDrawVariant::DrawSubsector, TriBlendMode::Shaded);
} }

View file

@ -24,11 +24,13 @@
#include "r_poly_triangle.h" #include "r_poly_triangle.h"
class Vec4f;
class RenderPolyDecal class RenderPolyDecal
{ {
public: public:
static void RenderWallDecals(const TriMatrix &worldToClip, const seg_t *line, uint32_t subsectorDepth, uint32_t stencilValue); static void RenderWallDecals(const TriMatrix &worldToClip, const Vec4f &clipPlane, const seg_t *line, uint32_t subsectorDepth, uint32_t stencilValue);
private: private:
void Render(const TriMatrix &worldToClip, DBaseDecal *decal, const seg_t *line, uint32_t subsectorDepth, uint32_t stencilValue); void Render(const TriMatrix &worldToClip, const Vec4f &clipPlane, DBaseDecal *decal, const seg_t *line, uint32_t subsectorDepth, uint32_t stencilValue);
}; };

View file

@ -28,7 +28,7 @@
#include "r_poly_particle.h" #include "r_poly_particle.h"
#include "r_poly.h" #include "r_poly.h"
void RenderPolyParticle::Render(const TriMatrix &worldToClip, particle_t *particle, subsector_t *sub, uint32_t subsectorDepth, uint32_t stencilValue) void RenderPolyParticle::Render(const TriMatrix &worldToClip, const Vec4f &clipPlane, particle_t *particle, subsector_t *sub, uint32_t subsectorDepth, uint32_t stencilValue)
{ {
DVector3 pos = particle->Pos; DVector3 pos = particle->Pos;
double psize = particle->size / 8.0; double psize = particle->size / 8.0;
@ -104,5 +104,6 @@ void RenderPolyParticle::Render(const TriMatrix &worldToClip, particle_t *partic
args.stenciltestvalue = stencilValue; args.stenciltestvalue = stencilValue;
args.stencilwritevalue = stencilValue; args.stencilwritevalue = stencilValue;
args.SetColormap(sub->sector->ColorMap); args.SetColormap(sub->sector->ColorMap);
args.SetClipPlane(clipPlane.x, clipPlane.y, clipPlane.z, clipPlane.w);
PolyTriangleDrawer::draw(args, TriDrawVariant::FillSubsector, TriBlendMode::AlphaBlend); PolyTriangleDrawer::draw(args, TriDrawVariant::FillSubsector, TriBlendMode::AlphaBlend);
} }

View file

@ -25,8 +25,10 @@
#include "r_poly_triangle.h" #include "r_poly_triangle.h"
#include "p_effect.h" #include "p_effect.h"
class Vec4f;
class RenderPolyParticle class RenderPolyParticle
{ {
public: public:
void Render(const TriMatrix &worldToClip, particle_t *particle, subsector_t *sub, uint32_t subsectorDepth, uint32_t stencilValue); void Render(const TriMatrix &worldToClip, const Vec4f &clipPlane, particle_t *particle, subsector_t *sub, uint32_t subsectorDepth, uint32_t stencilValue);
}; };

View file

@ -32,7 +32,7 @@
EXTERN_CVAR(Int, r_3dfloors) EXTERN_CVAR(Int, r_3dfloors)
void RenderPolyPlane::RenderPlanes(const TriMatrix &worldToClip, subsector_t *sub, uint32_t subsectorDepth, uint32_t stencilValue, double skyCeilingHeight, double skyFloorHeight, std::vector<std::unique_ptr<PolyDrawSectorPortal>> &sectorPortals) void RenderPolyPlane::RenderPlanes(const TriMatrix &worldToClip, const Vec4f &clipPlane, subsector_t *sub, uint32_t subsectorDepth, uint32_t stencilValue, double skyCeilingHeight, double skyFloorHeight, std::vector<std::unique_ptr<PolyDrawSectorPortal>> &sectorPortals)
{ {
RenderPolyPlane plane; RenderPolyPlane plane;
@ -58,7 +58,7 @@ void RenderPolyPlane::RenderPlanes(const TriMatrix &worldToClip, subsector_t *su
double fakeHeight = fakeFloor->top.plane->ZatPoint(frontsector->centerspot); double fakeHeight = fakeFloor->top.plane->ZatPoint(frontsector->centerspot);
if (fakeHeight < ViewPos.Z && fakeHeight > frontsector->floorplane.ZatPoint(frontsector->centerspot)) if (fakeHeight < ViewPos.Z && fakeHeight > frontsector->floorplane.ZatPoint(frontsector->centerspot))
{ {
plane.Render3DFloor(worldToClip, sub, subsectorDepth, stencilValue, false, fakeFloor); plane.Render3DFloor(worldToClip, clipPlane, sub, subsectorDepth, stencilValue, false, fakeFloor);
} }
} }
@ -79,16 +79,16 @@ void RenderPolyPlane::RenderPlanes(const TriMatrix &worldToClip, subsector_t *su
double fakeHeight = fakeFloor->bottom.plane->ZatPoint(frontsector->centerspot); double fakeHeight = fakeFloor->bottom.plane->ZatPoint(frontsector->centerspot);
if (fakeHeight > ViewPos.Z && fakeHeight < frontsector->ceilingplane.ZatPoint(frontsector->centerspot)) if (fakeHeight > ViewPos.Z && fakeHeight < frontsector->ceilingplane.ZatPoint(frontsector->centerspot))
{ {
plane.Render3DFloor(worldToClip, sub, subsectorDepth, stencilValue, true, fakeFloor); plane.Render3DFloor(worldToClip, clipPlane, sub, subsectorDepth, stencilValue, true, fakeFloor);
} }
} }
} }
plane.Render(worldToClip, sub, subsectorDepth, stencilValue, true, skyCeilingHeight, sectorPortals); plane.Render(worldToClip, clipPlane, sub, subsectorDepth, stencilValue, true, skyCeilingHeight, sectorPortals);
plane.Render(worldToClip, sub, subsectorDepth, stencilValue, false, skyFloorHeight, sectorPortals); plane.Render(worldToClip, clipPlane, sub, subsectorDepth, stencilValue, false, skyFloorHeight, sectorPortals);
} }
void RenderPolyPlane::Render3DFloor(const TriMatrix &worldToClip, subsector_t *sub, uint32_t subsectorDepth, uint32_t stencilValue, bool ceiling, F3DFloor *fakeFloor) void RenderPolyPlane::Render3DFloor(const TriMatrix &worldToClip, const Vec4f &clipPlane, subsector_t *sub, uint32_t subsectorDepth, uint32_t stencilValue, bool ceiling, F3DFloor *fakeFloor)
{ {
FTextureID picnum = ceiling ? *fakeFloor->bottom.texture : *fakeFloor->top.texture; FTextureID picnum = ceiling ? *fakeFloor->bottom.texture : *fakeFloor->top.texture;
FTexture *tex = TexMan(picnum); FTexture *tex = TexMan(picnum);
@ -140,11 +140,12 @@ void RenderPolyPlane::Render3DFloor(const TriMatrix &worldToClip, subsector_t *s
args.stencilwritevalue = stencilValue + 1; args.stencilwritevalue = stencilValue + 1;
args.SetTexture(tex); args.SetTexture(tex);
args.SetColormap(sub->sector->ColorMap); args.SetColormap(sub->sector->ColorMap);
args.SetClipPlane(clipPlane.x, clipPlane.y, clipPlane.z, clipPlane.w);
PolyTriangleDrawer::draw(args, TriDrawVariant::DrawNormal, TriBlendMode::Copy); PolyTriangleDrawer::draw(args, TriDrawVariant::DrawNormal, TriBlendMode::Copy);
PolyTriangleDrawer::draw(args, TriDrawVariant::Stencil, TriBlendMode::Copy); PolyTriangleDrawer::draw(args, TriDrawVariant::Stencil, TriBlendMode::Copy);
} }
void RenderPolyPlane::Render(const TriMatrix &worldToClip, subsector_t *sub, uint32_t subsectorDepth, uint32_t stencilValue, bool ceiling, double skyHeight, std::vector<std::unique_ptr<PolyDrawSectorPortal>> &sectorPortals) void RenderPolyPlane::Render(const TriMatrix &worldToClip, const Vec4f &clipPlane, subsector_t *sub, uint32_t subsectorDepth, uint32_t stencilValue, bool ceiling, double skyHeight, std::vector<std::unique_ptr<PolyDrawSectorPortal>> &sectorPortals)
{ {
FSectorPortal *portal = sub->sector->ValidatePortal(ceiling ? sector_t::ceiling : sector_t::floor); FSectorPortal *portal = sub->sector->ValidatePortal(ceiling ? sector_t::ceiling : sector_t::floor);
PolyDrawSectorPortal *polyportal = nullptr; PolyDrawSectorPortal *polyportal = nullptr;
@ -251,6 +252,7 @@ void RenderPolyPlane::Render(const TriMatrix &worldToClip, subsector_t *sub, uin
args.stenciltestvalue = stencilValue; args.stenciltestvalue = stencilValue;
args.stencilwritevalue = stencilValue + 1; args.stencilwritevalue = stencilValue + 1;
args.SetColormap(frontsector->ColorMap); args.SetColormap(frontsector->ColorMap);
args.SetClipPlane(clipPlane.x, clipPlane.y, clipPlane.z, clipPlane.w);
if (!isSky) if (!isSky)
{ {

View file

@ -25,14 +25,15 @@
#include "r_poly_triangle.h" #include "r_poly_triangle.h"
class PolyDrawSectorPortal; class PolyDrawSectorPortal;
class Vec4f;
class RenderPolyPlane class RenderPolyPlane
{ {
public: public:
static void RenderPlanes(const TriMatrix &worldToClip, subsector_t *sub, uint32_t subsectorDepth, uint32_t stencilValue, double skyCeilingHeight, double skyFloorHeight, std::vector<std::unique_ptr<PolyDrawSectorPortal>> &sectorPortals); static void RenderPlanes(const TriMatrix &worldToClip, const Vec4f &clipPlane, subsector_t *sub, uint32_t subsectorDepth, uint32_t stencilValue, double skyCeilingHeight, double skyFloorHeight, std::vector<std::unique_ptr<PolyDrawSectorPortal>> &sectorPortals);
private: private:
void Render3DFloor(const TriMatrix &worldToClip, subsector_t *sub, uint32_t subsectorDepth, uint32_t stencilValue, bool ceiling, F3DFloor *fakefloor); void Render3DFloor(const TriMatrix &worldToClip, const Vec4f &clipPlane, subsector_t *sub, uint32_t subsectorDepth, uint32_t stencilValue, bool ceiling, F3DFloor *fakefloor);
void Render(const TriMatrix &worldToClip, subsector_t *sub, uint32_t subsectorDepth, uint32_t stencilValue, bool ceiling, double skyHeight, std::vector<std::unique_ptr<PolyDrawSectorPortal>> &sectorPortals); void Render(const TriMatrix &worldToClip, const Vec4f &clipPlane, subsector_t *sub, uint32_t subsectorDepth, uint32_t stencilValue, bool ceiling, double skyHeight, std::vector<std::unique_ptr<PolyDrawSectorPortal>> &sectorPortals);
TriVertex PlaneVertex(vertex_t *v1, double height); TriVertex PlaneVertex(vertex_t *v1, double height);
}; };

View file

@ -94,7 +94,7 @@ void RenderPolyPortal::RenderSubsector(subsector_t *sub)
if (sub->sector->CenterFloor() != sub->sector->CenterCeiling()) if (sub->sector->CenterFloor() != sub->sector->CenterCeiling())
{ {
RenderPolyPlane::RenderPlanes(WorldToClip, sub, subsectorDepth, StencilValue, Cull.MaxCeilingHeight, Cull.MinFloorHeight, SectorPortals); RenderPolyPlane::RenderPlanes(WorldToClip, PortalPlane, sub, subsectorDepth, StencilValue, Cull.MaxCeilingHeight, Cull.MinFloorHeight, SectorPortals);
} }
for (uint32_t i = 0; i < sub->numlines; i++) for (uint32_t i = 0; i < sub->numlines; i++)
@ -178,12 +178,12 @@ void RenderPolyPortal::RenderLine(subsector_t *sub, seg_t *line, sector_t *front
if (!(fakeFloor->flags & FF_EXISTS)) continue; if (!(fakeFloor->flags & FF_EXISTS)) continue;
if (!(fakeFloor->flags & FF_RENDERPLANES)) continue; if (!(fakeFloor->flags & FF_RENDERPLANES)) continue;
if (!fakeFloor->model) continue; if (!fakeFloor->model) continue;
RenderPolyWall::Render3DFloorLine(WorldToClip, line, frontsector, subsectorDepth, StencilValue, fakeFloor, SubsectorTranslucentWalls); RenderPolyWall::Render3DFloorLine(WorldToClip, PortalPlane, line, frontsector, subsectorDepth, StencilValue, fakeFloor, SubsectorTranslucentWalls);
} }
} }
// Render wall, and update culling info if its an occlusion blocker // Render wall, and update culling info if its an occlusion blocker
if (RenderPolyWall::RenderLine(WorldToClip, line, frontsector, subsectorDepth, StencilValue, SubsectorTranslucentWalls, LinePortals)) if (RenderPolyWall::RenderLine(WorldToClip, PortalPlane, line, frontsector, subsectorDepth, StencilValue, SubsectorTranslucentWalls, LinePortals))
{ {
if (hasSegmentRange) if (hasSegmentRange)
Cull.MarkSegmentCulled(sx1, sx2); Cull.MarkSegmentCulled(sx1, sx2);
@ -208,6 +208,7 @@ void RenderPolyPortal::RenderPortals(int portalDepth)
args.uniforms.color = 0; args.uniforms.color = 0;
args.uniforms.light = 256; args.uniforms.light = 256;
args.uniforms.flags = TriUniforms::fixed_light; args.uniforms.flags = TriUniforms::fixed_light;
args.SetClipPlane(PortalPlane.x, PortalPlane.y, PortalPlane.z, PortalPlane.w);
for (auto &portal : SectorPortals) for (auto &portal : SectorPortals)
{ {
@ -253,6 +254,7 @@ void RenderPolyPortal::RenderTranslucent(int portalDepth)
args.mode = TriangleDrawMode::Fan; args.mode = TriangleDrawMode::Fan;
args.stenciltestvalue = portal->StencilValue + 1; args.stenciltestvalue = portal->StencilValue + 1;
args.stencilwritevalue = StencilValue; args.stencilwritevalue = StencilValue;
args.SetClipPlane(PortalPlane.x, PortalPlane.y, PortalPlane.z, PortalPlane.w);
for (const auto &verts : portal->Shape) for (const auto &verts : portal->Shape)
{ {
args.vinput = verts.Vertices; args.vinput = verts.Vertices;
@ -273,6 +275,7 @@ void RenderPolyPortal::RenderTranslucent(int portalDepth)
args.mode = TriangleDrawMode::Fan; args.mode = TriangleDrawMode::Fan;
args.stenciltestvalue = portal->StencilValue + 1; args.stenciltestvalue = portal->StencilValue + 1;
args.stencilwritevalue = StencilValue; args.stencilwritevalue = StencilValue;
args.SetClipPlane(PortalPlane.x, PortalPlane.y, PortalPlane.z, PortalPlane.w);
for (const auto &verts : portal->Shape) for (const auto &verts : portal->Shape)
{ {
args.vinput = verts.Vertices; args.vinput = verts.Vertices;
@ -290,21 +293,21 @@ void RenderPolyPortal::RenderTranslucent(int portalDepth)
if (obj.particle) if (obj.particle)
{ {
RenderPolyParticle spr; RenderPolyParticle spr;
spr.Render(WorldToClip, obj.particle, obj.sub, obj.subsectorDepth, StencilValue + 1); spr.Render(WorldToClip, PortalPlane, obj.particle, obj.sub, obj.subsectorDepth, StencilValue + 1);
} }
else if (!obj.thing) else if (!obj.thing)
{ {
obj.wall.Render(WorldToClip); obj.wall.Render(WorldToClip, PortalPlane);
} }
else if ((obj.thing->renderflags & RF_SPRITETYPEMASK) == RF_WALLSPRITE) else if ((obj.thing->renderflags & RF_SPRITETYPEMASK) == RF_WALLSPRITE)
{ {
RenderPolyWallSprite wallspr; RenderPolyWallSprite wallspr;
wallspr.Render(WorldToClip, obj.thing, obj.sub, obj.subsectorDepth, StencilValue + 1); wallspr.Render(WorldToClip, PortalPlane, obj.thing, obj.sub, obj.subsectorDepth, StencilValue + 1);
} }
else else
{ {
RenderPolySprite spr; RenderPolySprite spr;
spr.Render(WorldToClip, obj.thing, obj.sub, obj.subsectorDepth, StencilValue + 1); spr.Render(WorldToClip, PortalPlane, obj.thing, obj.sub, obj.subsectorDepth, StencilValue + 1);
} }
} }
} }
@ -341,7 +344,7 @@ void PolyDrawSectorPortal::Render(int portalDepth)
TriMatrix::translate((float)-ViewPos.X, (float)-ViewPos.Y, (float)-ViewPos.Z); TriMatrix::translate((float)-ViewPos.X, (float)-ViewPos.Y, (float)-ViewPos.Z);
TriMatrix worldToClip = TriMatrix::perspective(fovy, ratio, 5.0f, 65535.0f) * worldToView; TriMatrix worldToClip = TriMatrix::perspective(fovy, ratio, 5.0f, 65535.0f) * worldToView;
RenderPortal.SetViewpoint(worldToClip, Vec4f(0.0f), StencilValue); RenderPortal.SetViewpoint(worldToClip, Vec4f(0.0f, 0.0f, 0.0f, 1.0f), StencilValue);
RenderPortal.Render(portalDepth); RenderPortal.Render(portalDepth);
RestoreGlobals(); RestoreGlobals();
@ -445,7 +448,7 @@ void PolyDrawLinePortal::Render(int portalDepth)
DVector2 planePos = Portal->mDestination->v1->fPos(); DVector2 planePos = Portal->mDestination->v1->fPos();
DVector2 planeNormal = (Portal->mDestination->v2->fPos() - Portal->mDestination->v1->fPos()).Rotated90CW(); DVector2 planeNormal = (Portal->mDestination->v2->fPos() - Portal->mDestination->v1->fPos()).Rotated90CW();
planeNormal.MakeUnit(); planeNormal.MakeUnit();
double planeD = -(planeNormal | (planePos + planeNormal * 5.0)); double planeD = -(planeNormal | (planePos + planeNormal * 0.001));
Vec4f portalPlane((float)planeNormal.X, (float)planeNormal.Y, 0.0f, (float)planeD); Vec4f portalPlane((float)planeNormal.X, (float)planeNormal.Y, 0.0f, (float)planeD);
RenderPortal.SetViewpoint(worldToClip, portalPlane, StencilValue); RenderPortal.SetViewpoint(worldToClip, portalPlane, StencilValue);

View file

@ -61,6 +61,7 @@ void PolySkyDome::Render(const TriMatrix &worldToClip)
args.stencilwritevalue = 255; args.stencilwritevalue = 255;
args.SetTexture(frontskytex); args.SetTexture(frontskytex);
args.SetColormap(&NormalLight); args.SetColormap(&NormalLight);
args.SetClipPlane(0.0f, 0.0f, 0.0f, 0.0f);
RenderCapColorRow(args, frontskytex, 0, false); RenderCapColorRow(args, frontskytex, 0, false);
RenderCapColorRow(args, frontskytex, rc, true); RenderCapColorRow(args, frontskytex, rc, true);

View file

@ -27,11 +27,12 @@
#include "r_data/r_translate.h" #include "r_data/r_translate.h"
#include "r_poly_sprite.h" #include "r_poly_sprite.h"
#include "r_poly.h" #include "r_poly.h"
#include "r_poly_intersection.h"
EXTERN_CVAR(Float, transsouls) EXTERN_CVAR(Float, transsouls)
EXTERN_CVAR(Int, r_drawfuzz) EXTERN_CVAR(Int, r_drawfuzz)
void RenderPolySprite::Render(const TriMatrix &worldToClip, AActor *thing, subsector_t *sub, uint32_t subsectorDepth, uint32_t stencilValue) void RenderPolySprite::Render(const TriMatrix &worldToClip, const Vec4f &clipPlane, AActor *thing, subsector_t *sub, uint32_t subsectorDepth, uint32_t stencilValue)
{ {
if (IsThingCulled(thing)) if (IsThingCulled(thing))
return; return;
@ -138,6 +139,7 @@ void RenderPolySprite::Render(const TriMatrix &worldToClip, AActor *thing, subse
args.stencilwritevalue = stencilValue; args.stencilwritevalue = stencilValue;
args.SetTexture(tex, thing->Translation); args.SetTexture(tex, thing->Translation);
args.SetColormap(sub->sector->ColorMap); args.SetColormap(sub->sector->ColorMap);
args.SetClipPlane(clipPlane.x, clipPlane.y, clipPlane.z, clipPlane.w);
TriBlendMode blendmode; TriBlendMode blendmode;

View file

@ -24,10 +24,12 @@
#include "r_poly_triangle.h" #include "r_poly_triangle.h"
class Vec4f;
class RenderPolySprite class RenderPolySprite
{ {
public: public:
void Render(const TriMatrix &worldToClip, AActor *thing, subsector_t *sub, uint32_t subsectorDepth, uint32_t stencilValue); void Render(const TriMatrix &worldToClip, const Vec4f &clipPlane, AActor *thing, subsector_t *sub, uint32_t subsectorDepth, uint32_t stencilValue);
static bool IsThingCulled(AActor *thing); static bool IsThingCulled(AActor *thing);
static FTexture *GetSpriteTexture(AActor *thing, /*out*/ bool &flipX); static FTexture *GetSpriteTexture(AActor *thing, /*out*/ bool &flipX);

View file

@ -119,34 +119,34 @@ void PolyTriangleDrawer::draw_arrays(const PolyDrawArgs &drawargs, TriDrawVarian
const TriVertex *vinput = drawargs.vinput; const TriVertex *vinput = drawargs.vinput;
int vcount = drawargs.vcount; int vcount = drawargs.vcount;
TriVertex vert[3]; ShadedTriVertex vert[3];
if (drawargs.mode == TriangleDrawMode::Normal) if (drawargs.mode == TriangleDrawMode::Normal)
{ {
for (int i = 0; i < vcount / 3; i++) for (int i = 0; i < vcount / 3; i++)
{ {
for (int j = 0; j < 3; j++) for (int j = 0; j < 3; j++)
vert[j] = shade_vertex(*drawargs.objectToClip, *(vinput++)); vert[j] = shade_vertex(*drawargs.objectToClip, drawargs.clipPlane, *(vinput++));
draw_shaded_triangle(vert, ccw, &args, thread, drawfunc); draw_shaded_triangle(vert, ccw, &args, thread, drawfunc);
} }
} }
else if (drawargs.mode == TriangleDrawMode::Fan) else if (drawargs.mode == TriangleDrawMode::Fan)
{ {
vert[0] = shade_vertex(*drawargs.objectToClip, *(vinput++)); vert[0] = shade_vertex(*drawargs.objectToClip, drawargs.clipPlane, *(vinput++));
vert[1] = shade_vertex(*drawargs.objectToClip, *(vinput++)); vert[1] = shade_vertex(*drawargs.objectToClip, drawargs.clipPlane, *(vinput++));
for (int i = 2; i < vcount; i++) for (int i = 2; i < vcount; i++)
{ {
vert[2] = shade_vertex(*drawargs.objectToClip, *(vinput++)); vert[2] = shade_vertex(*drawargs.objectToClip, drawargs.clipPlane, *(vinput++));
draw_shaded_triangle(vert, ccw, &args, thread, drawfunc); draw_shaded_triangle(vert, ccw, &args, thread, drawfunc);
vert[1] = vert[2]; vert[1] = vert[2];
} }
} }
else // TriangleDrawMode::Strip else // TriangleDrawMode::Strip
{ {
vert[0] = shade_vertex(*drawargs.objectToClip, *(vinput++)); vert[0] = shade_vertex(*drawargs.objectToClip, drawargs.clipPlane, *(vinput++));
vert[1] = shade_vertex(*drawargs.objectToClip, *(vinput++)); vert[1] = shade_vertex(*drawargs.objectToClip, drawargs.clipPlane, *(vinput++));
for (int i = 2; i < vcount; i++) for (int i = 2; i < vcount; i++)
{ {
vert[2] = shade_vertex(*drawargs.objectToClip, *(vinput++)); vert[2] = shade_vertex(*drawargs.objectToClip, drawargs.clipPlane, *(vinput++));
draw_shaded_triangle(vert, ccw, &args, thread, drawfunc); draw_shaded_triangle(vert, ccw, &args, thread, drawfunc);
vert[0] = vert[1]; vert[0] = vert[1];
vert[1] = vert[2]; vert[1] = vert[2];
@ -155,13 +155,18 @@ void PolyTriangleDrawer::draw_arrays(const PolyDrawArgs &drawargs, TriDrawVarian
} }
} }
TriVertex PolyTriangleDrawer::shade_vertex(const TriMatrix &objectToClip, TriVertex v) ShadedTriVertex PolyTriangleDrawer::shade_vertex(const TriMatrix &objectToClip, const float *clipPlane, const TriVertex &v)
{ {
// Apply transform to get clip coordinates: // Apply transform to get clip coordinates:
return objectToClip * v; ShadedTriVertex sv = objectToClip * v;
// Calculate gl_ClipDistance[0]
sv.clipDistance0 = v.x * clipPlane[0] + v.y * clipPlane[1] + v.z * clipPlane[2] + v.w * clipPlane[3];
return sv;
} }
void PolyTriangleDrawer::draw_shaded_triangle(const TriVertex *vert, bool ccw, TriDrawTriangleArgs *args, WorkerThreadData *thread, void(*drawfunc)(const TriDrawTriangleArgs *, WorkerThreadData *)) void PolyTriangleDrawer::draw_shaded_triangle(const ShadedTriVertex *vert, bool ccw, TriDrawTriangleArgs *args, WorkerThreadData *thread, void(*drawfunc)(const TriDrawTriangleArgs *, WorkerThreadData *))
{ {
// Cull, clip and generate additional vertices as needed // Cull, clip and generate additional vertices as needed
TriVertex clippedvert[max_additional_vertices]; TriVertex clippedvert[max_additional_vertices];
@ -225,7 +230,7 @@ bool PolyTriangleDrawer::cullhalfspace(float clipdistance1, float clipdistance2,
return false; return false;
} }
void PolyTriangleDrawer::clipedge(const TriVertex *verts, TriVertex *clippedvert, int &numclipvert) void PolyTriangleDrawer::clipedge(const ShadedTriVertex *verts, TriVertex *clippedvert, int &numclipvert)
{ {
// Clip and cull so that the following is true for all vertices: // Clip and cull so that the following is true for all vertices:
// -v.w <= v.x <= v.w // -v.w <= v.x <= v.w
@ -243,16 +248,18 @@ void PolyTriangleDrawer::clipedge(const TriVertex *verts, TriVertex *clippedvert
} }
// halfspace clip distances // halfspace clip distances
float clipdistance[6 * 3]; static const int numclipdistances = 7;
float clipdistance[numclipdistances * 3];
for (int i = 0; i < 3; i++) for (int i = 0; i < 3; i++)
{ {
const auto &v = verts[i]; const auto &v = verts[i];
clipdistance[i * 6 + 0] = v.x + v.w; clipdistance[i * numclipdistances + 0] = v.x + v.w;
clipdistance[i * 6 + 1] = v.w - v.x; clipdistance[i * numclipdistances + 1] = v.w - v.x;
clipdistance[i * 6 + 2] = v.y + v.w; clipdistance[i * numclipdistances + 2] = v.y + v.w;
clipdistance[i * 6 + 3] = v.w - v.y; clipdistance[i * numclipdistances + 3] = v.w - v.y;
clipdistance[i * 6 + 4] = v.z + v.w; clipdistance[i * numclipdistances + 4] = v.z + v.w;
clipdistance[i * 6 + 5] = v.w - v.z; clipdistance[i * numclipdistances + 5] = v.w - v.z;
clipdistance[i * numclipdistances + 6] = v.clipDistance0;
} }
// Clip against each halfspace // Clip against each halfspace
@ -260,7 +267,7 @@ void PolyTriangleDrawer::clipedge(const TriVertex *verts, TriVertex *clippedvert
float *output = weights + max_additional_vertices * 3; float *output = weights + max_additional_vertices * 3;
int inputverts = 3; int inputverts = 3;
int outputverts = 0; int outputverts = 0;
for (int p = 0; p < 6; p++) for (int p = 0; p < numclipdistances; p++)
{ {
// Clip each edge // Clip each edge
outputverts = 0; outputverts = 0;
@ -268,14 +275,14 @@ void PolyTriangleDrawer::clipedge(const TriVertex *verts, TriVertex *clippedvert
{ {
int j = (i + 1) % inputverts; int j = (i + 1) % inputverts;
float clipdistance1 = float clipdistance1 =
clipdistance[0 * 6 + p] * input[i * 3 + 0] + clipdistance[0 * numclipdistances + p] * input[i * 3 + 0] +
clipdistance[1 * 6 + p] * input[i * 3 + 1] + clipdistance[1 * numclipdistances + p] * input[i * 3 + 1] +
clipdistance[2 * 6 + p] * input[i * 3 + 2]; clipdistance[2 * numclipdistances + p] * input[i * 3 + 2];
float clipdistance2 = float clipdistance2 =
clipdistance[0 * 6 + p] * input[j * 3 + 0] + clipdistance[0 * numclipdistances + p] * input[j * 3 + 0] +
clipdistance[1 * 6 + p] * input[j * 3 + 1] + clipdistance[1 * numclipdistances + p] * input[j * 3 + 1] +
clipdistance[2 * 6 + p] * input[j * 3 + 2]; clipdistance[2 * numclipdistances + p] * input[j * 3 + 2];
float t1, t2; float t1, t2;
if (!cullhalfspace(clipdistance1, clipdistance2, t1, t2) && outputverts + 1 < max_additional_vertices) if (!cullhalfspace(clipdistance1, clipdistance2, t1, t2) && outputverts + 1 < max_additional_vertices)
@ -512,17 +519,20 @@ TriMatrix TriMatrix::operator*(const TriMatrix &mult) const
return result; return result;
} }
TriVertex TriMatrix::operator*(TriVertex v) const ShadedTriVertex TriMatrix::operator*(TriVertex v) const
{ {
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 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 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 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; 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;
v.x = vx; ShadedTriVertex sv;
v.y = vy; sv.x = vx;
v.z = vz; sv.y = vy;
v.w = vw; sv.z = vz;
return v; sv.w = vw;
for (int i = 0; i < TriVertex::NumVarying; i++)
sv.varying[i] = v.varying[i];
return sv;
} }
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////

View file

@ -38,6 +38,7 @@ enum class TriangleDrawMode
}; };
struct TriDrawTriangleArgs; struct TriDrawTriangleArgs;
struct TriMatrix;
class PolyDrawArgs class PolyDrawArgs
{ {
@ -55,6 +56,15 @@ public:
uint8_t stenciltestvalue = 0; uint8_t stenciltestvalue = 0;
uint8_t stencilwritevalue = 0; uint8_t stencilwritevalue = 0;
const uint8_t *colormaps = nullptr; const uint8_t *colormaps = nullptr;
float clipPlane[4];
void SetClipPlane(float a, float b, float c, float d)
{
clipPlane[0] = a;
clipPlane[1] = b;
clipPlane[2] = c;
clipPlane[3] = d;
}
void SetTexture(FTexture *texture) void SetTexture(FTexture *texture)
{ {
@ -118,6 +128,31 @@ public:
} }
}; };
struct ShadedTriVertex : public TriVertex
{
float clipDistance0;
};
struct TriMatrix
{
static TriMatrix null();
static TriMatrix identity();
static TriMatrix translate(float x, float y, float z);
static TriMatrix scale(float x, float y, float z);
static TriMatrix rotate(float angle, float x, float y, float z);
static TriMatrix swapYZ();
static TriMatrix perspective(float fovy, float aspect, float near, float far);
static TriMatrix frustum(float left, float right, float bottom, float top, float near, float far);
static TriMatrix worldToView(); // Software renderer world to view space transform
static TriMatrix viewToClip(); // Software renderer shearing projection
ShadedTriVertex operator*(TriVertex v) const;
TriMatrix operator*(const TriMatrix &m) const;
float matrix[16];
};
class PolyTriangleDrawer class PolyTriangleDrawer
{ {
public: public:
@ -125,11 +160,11 @@ public:
static void draw(const PolyDrawArgs &args, TriDrawVariant variant, TriBlendMode blendmode); static void draw(const PolyDrawArgs &args, TriDrawVariant variant, TriBlendMode blendmode);
private: private:
static TriVertex shade_vertex(const TriMatrix &objectToClip, TriVertex v); static ShadedTriVertex shade_vertex(const TriMatrix &objectToClip, const float *clipPlane, const TriVertex &v);
static void draw_arrays(const PolyDrawArgs &args, TriDrawVariant variant, TriBlendMode blendmode, WorkerThreadData *thread); static void draw_arrays(const PolyDrawArgs &args, TriDrawVariant variant, TriBlendMode blendmode, WorkerThreadData *thread);
static void draw_shaded_triangle(const TriVertex *vertices, bool ccw, TriDrawTriangleArgs *args, WorkerThreadData *thread, void(*drawfunc)(const TriDrawTriangleArgs *, WorkerThreadData *)); static void draw_shaded_triangle(const ShadedTriVertex *vertices, bool ccw, TriDrawTriangleArgs *args, WorkerThreadData *thread, void(*drawfunc)(const TriDrawTriangleArgs *, WorkerThreadData *));
static bool cullhalfspace(float clipdistance1, float clipdistance2, float &t1, float &t2); static bool cullhalfspace(float clipdistance1, float clipdistance2, float &t1, float &t2);
static void clipedge(const TriVertex *verts, TriVertex *clippedvert, int &numclipvert); static void clipedge(const ShadedTriVertex *verts, TriVertex *clippedvert, int &numclipvert);
static int viewport_x, viewport_y, viewport_width, viewport_height, dest_pitch, dest_width, dest_height; static int viewport_x, viewport_y, viewport_width, viewport_height, dest_pitch, dest_width, dest_height;
static bool dest_bgra; static bool dest_bgra;

View file

@ -35,7 +35,7 @@
EXTERN_CVAR(Bool, r_drawmirrors) EXTERN_CVAR(Bool, r_drawmirrors)
bool RenderPolyWall::RenderLine(const TriMatrix &worldToClip, seg_t *line, sector_t *frontsector, uint32_t subsectorDepth, uint32_t stencilValue, std::vector<PolyTranslucentObject> &translucentWallsOutput, std::vector<std::unique_ptr<PolyDrawLinePortal>> &linePortals) bool RenderPolyWall::RenderLine(const TriMatrix &worldToClip, const Vec4f &clipPlane, seg_t *line, sector_t *frontsector, uint32_t subsectorDepth, uint32_t stencilValue, std::vector<PolyTranslucentObject> &translucentWallsOutput, std::vector<std::unique_ptr<PolyDrawLinePortal>> &linePortals)
{ {
PolyDrawLinePortal *polyportal = nullptr; PolyDrawLinePortal *polyportal = nullptr;
if (line->backsector == nullptr && line->sidedef == line->linedef->sidedef[0] && (line->linedef->special == Line_Mirror && r_drawmirrors)) if (line->backsector == nullptr && line->sidedef == line->linedef->sidedef[0] && (line->linedef->special == Line_Mirror && r_drawmirrors))
@ -85,7 +85,7 @@ bool RenderPolyWall::RenderLine(const TriMatrix &worldToClip, seg_t *line, secto
wall.UnpeggedCeil = frontceilz1; wall.UnpeggedCeil = frontceilz1;
wall.Texpart = side_t::mid; wall.Texpart = side_t::mid;
wall.Polyportal = polyportal; wall.Polyportal = polyportal;
wall.Render(worldToClip); wall.Render(worldToClip, clipPlane);
return true; return true;
} }
} }
@ -120,7 +120,7 @@ bool RenderPolyWall::RenderLine(const TriMatrix &worldToClip, seg_t *line, secto
wall.BottomZ = topfloorz1; wall.BottomZ = topfloorz1;
wall.UnpeggedCeil = topceilz1; wall.UnpeggedCeil = topceilz1;
wall.Texpart = side_t::top; wall.Texpart = side_t::top;
wall.Render(worldToClip); wall.Render(worldToClip, clipPlane);
} }
if ((bottomfloorz1 < bottomceilz1 || bottomfloorz2 < bottomceilz2) && line->sidedef) if ((bottomfloorz1 < bottomceilz1 || bottomfloorz2 < bottomceilz2) && line->sidedef)
@ -130,7 +130,7 @@ bool RenderPolyWall::RenderLine(const TriMatrix &worldToClip, seg_t *line, secto
wall.BottomZ = bottomfloorz2; wall.BottomZ = bottomfloorz2;
wall.UnpeggedCeil = topceilz1; wall.UnpeggedCeil = topceilz1;
wall.Texpart = side_t::bottom; wall.Texpart = side_t::bottom;
wall.Render(worldToClip); wall.Render(worldToClip, clipPlane);
} }
if (line->sidedef) if (line->sidedef)
@ -149,14 +149,14 @@ bool RenderPolyWall::RenderLine(const TriMatrix &worldToClip, seg_t *line, secto
if (polyportal) if (polyportal)
{ {
wall.Polyportal = polyportal; wall.Polyportal = polyportal;
wall.Render(worldToClip); wall.Render(worldToClip, clipPlane);
} }
} }
} }
return polyportal != nullptr; return polyportal != nullptr;
} }
void RenderPolyWall::Render3DFloorLine(const TriMatrix &worldToClip, seg_t *line, sector_t *frontsector, uint32_t subsectorDepth, uint32_t stencilValue, F3DFloor *fakeFloor, std::vector<PolyTranslucentObject> &translucentWallsOutput) void RenderPolyWall::Render3DFloorLine(const TriMatrix &worldToClip, const Vec4f &clipPlane, seg_t *line, sector_t *frontsector, uint32_t subsectorDepth, uint32_t stencilValue, F3DFloor *fakeFloor, std::vector<PolyTranslucentObject> &translucentWallsOutput)
{ {
double frontceilz1 = fakeFloor->top.plane->ZatPoint(line->v1); double frontceilz1 = fakeFloor->top.plane->ZatPoint(line->v1);
double frontfloorz1 = fakeFloor->bottom.plane->ZatPoint(line->v1); double frontfloorz1 = fakeFloor->bottom.plane->ZatPoint(line->v1);
@ -176,7 +176,7 @@ void RenderPolyWall::Render3DFloorLine(const TriMatrix &worldToClip, seg_t *line
wall.BottomZ = frontfloorz1; wall.BottomZ = frontfloorz1;
wall.UnpeggedCeil = frontceilz1; wall.UnpeggedCeil = frontceilz1;
wall.Texpart = side_t::mid; wall.Texpart = side_t::mid;
wall.Render(worldToClip); wall.Render(worldToClip, clipPlane);
} }
void RenderPolyWall::SetCoords(const DVector2 &v1, const DVector2 &v2, double ceil1, double floor1, double ceil2, double floor2) void RenderPolyWall::SetCoords(const DVector2 &v1, const DVector2 &v2, double ceil1, double floor1, double ceil2, double floor2)
@ -189,7 +189,7 @@ void RenderPolyWall::SetCoords(const DVector2 &v1, const DVector2 &v2, double ce
this->floor2 = floor2; this->floor2 = floor2;
} }
void RenderPolyWall::Render(const TriMatrix &worldToClip) void RenderPolyWall::Render(const TriMatrix &worldToClip, const Vec4f &clipPlane)
{ {
FTexture *tex = GetTexture(); FTexture *tex = GetTexture();
if (!tex && !Polyportal) if (!tex && !Polyportal)
@ -253,6 +253,7 @@ void RenderPolyWall::Render(const TriMatrix &worldToClip)
if (tex) if (tex)
args.SetTexture(tex); args.SetTexture(tex);
args.SetColormap(Line->frontsector->ColorMap); args.SetColormap(Line->frontsector->ColorMap);
args.SetClipPlane(clipPlane.x, clipPlane.y, clipPlane.z, clipPlane.w);
if (Polyportal) if (Polyportal)
{ {
@ -275,7 +276,7 @@ void RenderPolyWall::Render(const TriMatrix &worldToClip)
PolyTriangleDrawer::draw(args, TriDrawVariant::DrawSubsector, TriBlendMode::Add); PolyTriangleDrawer::draw(args, TriDrawVariant::DrawSubsector, TriBlendMode::Add);
} }
RenderPolyDecal::RenderWallDecals(worldToClip, LineSeg, SubsectorDepth, StencilValue); RenderPolyDecal::RenderWallDecals(worldToClip, clipPlane, LineSeg, SubsectorDepth, StencilValue);
} }
void RenderPolyWall::ClampHeight(TriVertex &v1, TriVertex &v2) void RenderPolyWall::ClampHeight(TriVertex &v1, TriVertex &v2)

View file

@ -26,15 +26,16 @@
class PolyTranslucentObject; class PolyTranslucentObject;
class PolyDrawLinePortal; class PolyDrawLinePortal;
class Vec4f;
class RenderPolyWall class RenderPolyWall
{ {
public: public:
static bool RenderLine(const TriMatrix &worldToClip, seg_t *line, sector_t *frontsector, uint32_t subsectorDepth, uint32_t stencilValue, std::vector<PolyTranslucentObject> &translucentWallsOutput, std::vector<std::unique_ptr<PolyDrawLinePortal>> &linePortals); static bool RenderLine(const TriMatrix &worldToClip, const Vec4f &clipPlane, seg_t *line, sector_t *frontsector, uint32_t subsectorDepth, uint32_t stencilValue, std::vector<PolyTranslucentObject> &translucentWallsOutput, std::vector<std::unique_ptr<PolyDrawLinePortal>> &linePortals);
static void Render3DFloorLine(const TriMatrix &worldToClip, seg_t *line, sector_t *frontsector, uint32_t subsectorDepth, uint32_t stencilValue, F3DFloor *fakeFloor, std::vector<PolyTranslucentObject> &translucentWallsOutput); static void Render3DFloorLine(const TriMatrix &worldToClip, const Vec4f &clipPlane, seg_t *line, sector_t *frontsector, uint32_t subsectorDepth, uint32_t stencilValue, F3DFloor *fakeFloor, std::vector<PolyTranslucentObject> &translucentWallsOutput);
void SetCoords(const DVector2 &v1, const DVector2 &v2, double ceil1, double floor1, double ceil2, double floor2); void SetCoords(const DVector2 &v1, const DVector2 &v2, double ceil1, double floor1, double ceil2, double floor2);
void Render(const TriMatrix &worldToClip); void Render(const TriMatrix &worldToClip, const Vec4f &clipPlane);
DVector2 v1; DVector2 v1;
DVector2 v2; DVector2 v2;

View file

@ -28,7 +28,7 @@
#include "r_poly_wallsprite.h" #include "r_poly_wallsprite.h"
#include "r_poly.h" #include "r_poly.h"
void RenderPolyWallSprite::Render(const TriMatrix &worldToClip, AActor *thing, subsector_t *sub, uint32_t subsectorDepth, uint32_t stencilValue) void RenderPolyWallSprite::Render(const TriMatrix &worldToClip, const Vec4f &clipPlane, AActor *thing, subsector_t *sub, uint32_t subsectorDepth, uint32_t stencilValue)
{ {
if (RenderPolySprite::IsThingCulled(thing)) if (RenderPolySprite::IsThingCulled(thing))
return; return;
@ -120,5 +120,6 @@ void RenderPolyWallSprite::Render(const TriMatrix &worldToClip, AActor *thing, s
args.stencilwritevalue = stencilValue; args.stencilwritevalue = stencilValue;
args.SetTexture(tex); args.SetTexture(tex);
args.SetColormap(sub->sector->ColorMap); args.SetColormap(sub->sector->ColorMap);
args.SetClipPlane(clipPlane.x, clipPlane.y, clipPlane.z, clipPlane.w);
PolyTriangleDrawer::draw(args, TriDrawVariant::DrawSubsector, TriBlendMode::AlphaBlend); PolyTriangleDrawer::draw(args, TriDrawVariant::DrawSubsector, TriBlendMode::AlphaBlend);
} }

View file

@ -24,8 +24,10 @@
#include "r_poly_triangle.h" #include "r_poly_triangle.h"
class Vec4f;
class RenderPolyWallSprite class RenderPolyWallSprite
{ {
public: public:
void Render(const TriMatrix &worldToClip, AActor *thing, subsector_t *sub, uint32_t subsectorDepth, uint32_t stencilValue); void Render(const TriMatrix &worldToClip, const Vec4f &clipPlane, AActor *thing, subsector_t *sub, uint32_t subsectorDepth, uint32_t stencilValue);
}; };