mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-12-01 16:41:09 +00:00
Add plane clipping to the triangle drawer
This commit is contained in:
parent
8bbb63e913
commit
c37ce1fdbc
19 changed files with 146 additions and 99 deletions
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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:
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
};
|
};
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
};
|
};
|
||||||
|
|
|
@ -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>> §orPortals)
|
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>> §orPortals)
|
||||||
{
|
{
|
||||||
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>> §orPortals)
|
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>> §orPortals)
|
||||||
{
|
{
|
||||||
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)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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>> §orPortals);
|
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>> §orPortals);
|
||||||
|
|
||||||
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>> §orPortals);
|
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>> §orPortals);
|
||||||
TriVertex PlaneVertex(vertex_t *v1, double height);
|
TriVertex PlaneVertex(vertex_t *v1, double height);
|
||||||
};
|
};
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue