mirror of
https://github.com/ZDoom/gzdoom-gles.git
synced 2024-11-11 15:22:15 +00:00
Add 3D floor planes
This commit is contained in:
parent
71b4f57058
commit
f457f0340c
4 changed files with 162 additions and 32 deletions
|
@ -36,7 +36,24 @@ void RenderPolyScene::Render()
|
||||||
if (!r_swtruecolor) // Disable pal rendering for now
|
if (!r_swtruecolor) // Disable pal rendering for now
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Setup working buffers
|
ClearBuffers();
|
||||||
|
SetupPerspectiveMatrix();
|
||||||
|
Cull.CullScene(WorldToClip);
|
||||||
|
RenderSectors();
|
||||||
|
skydome.Render(WorldToClip);
|
||||||
|
RenderTranslucent();
|
||||||
|
PlayerSprites.Render();
|
||||||
|
|
||||||
|
DrawerCommandQueue::WaitForWorkers();
|
||||||
|
}
|
||||||
|
|
||||||
|
void RenderPolyScene::RenderRemainingPlayerSprites()
|
||||||
|
{
|
||||||
|
PlayerSprites.RenderRemainingSprites();
|
||||||
|
}
|
||||||
|
|
||||||
|
void RenderPolyScene::ClearBuffers()
|
||||||
|
{
|
||||||
PolyVertexBuffer::Clear();
|
PolyVertexBuffer::Clear();
|
||||||
SectorSpriteRanges.clear();
|
SectorSpriteRanges.clear();
|
||||||
SectorSpriteRanges.resize(numsectors);
|
SectorSpriteRanges.resize(numsectors);
|
||||||
|
@ -45,8 +62,10 @@ void RenderPolyScene::Render()
|
||||||
PolyStencilBuffer::Instance()->Clear(viewwidth, viewheight, 0);
|
PolyStencilBuffer::Instance()->Clear(viewwidth, viewheight, 0);
|
||||||
PolySubsectorGBuffer::Instance()->Resize(dc_pitch, viewheight);
|
PolySubsectorGBuffer::Instance()->Resize(dc_pitch, viewheight);
|
||||||
NextSubsectorDepth = 0;
|
NextSubsectorDepth = 0;
|
||||||
|
}
|
||||||
|
|
||||||
// Setup perspective matrix:
|
void RenderPolyScene::SetupPerspectiveMatrix()
|
||||||
|
{
|
||||||
float ratio = WidescreenRatio;
|
float ratio = WidescreenRatio;
|
||||||
float fovratio = (WidescreenRatio >= 1.3f) ? 1.333333f : ratio;
|
float fovratio = (WidescreenRatio >= 1.3f) ? 1.333333f : ratio;
|
||||||
float fovy = (float)(2 * DAngle::ToDegrees(atan(tan(FieldOfView.Radians() / 2) / fovratio)).Degrees);
|
float fovy = (float)(2 * DAngle::ToDegrees(atan(tan(FieldOfView.Radians() / 2) / fovratio)).Degrees);
|
||||||
|
@ -57,8 +76,10 @@ void RenderPolyScene::Render()
|
||||||
TriMatrix::swapYZ() *
|
TriMatrix::swapYZ() *
|
||||||
TriMatrix::translate((float)-ViewPos.X, (float)-ViewPos.Y, (float)-ViewPos.Z);
|
TriMatrix::translate((float)-ViewPos.X, (float)-ViewPos.Y, (float)-ViewPos.Z);
|
||||||
WorldToClip = TriMatrix::perspective(fovy, ratio, 5.0f, 65535.0f) * worldToView;
|
WorldToClip = TriMatrix::perspective(fovy, ratio, 5.0f, 65535.0f) * worldToView;
|
||||||
|
}
|
||||||
|
|
||||||
Cull.CullScene(WorldToClip);
|
void RenderPolyScene::RenderSectors()
|
||||||
|
{
|
||||||
if (r_debug_cull)
|
if (r_debug_cull)
|
||||||
{
|
{
|
||||||
for (auto it = Cull.PvsSectors.rbegin(); it != Cull.PvsSectors.rend(); ++it)
|
for (auto it = Cull.PvsSectors.rbegin(); it != Cull.PvsSectors.rend(); ++it)
|
||||||
|
@ -69,19 +90,6 @@ void RenderPolyScene::Render()
|
||||||
for (auto it = Cull.PvsSectors.begin(); it != Cull.PvsSectors.end(); ++it)
|
for (auto it = Cull.PvsSectors.begin(); it != Cull.PvsSectors.end(); ++it)
|
||||||
RenderSubsector(*it);
|
RenderSubsector(*it);
|
||||||
}
|
}
|
||||||
|
|
||||||
skydome.Render(WorldToClip);
|
|
||||||
|
|
||||||
RenderTranslucent();
|
|
||||||
|
|
||||||
PlayerSprites.Render();
|
|
||||||
DrawerCommandQueue::WaitForWorkers();
|
|
||||||
RenderRemainingPlayerSprites(); // To do: should be called by FSoftwareRenderer::DrawRemainingPlayerSprites instead of here
|
|
||||||
}
|
|
||||||
|
|
||||||
void RenderPolyScene::RenderRemainingPlayerSprites()
|
|
||||||
{
|
|
||||||
PlayerSprites.RenderRemainingSprites();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void RenderPolyScene::RenderSubsector(subsector_t *sub)
|
void RenderPolyScene::RenderSubsector(subsector_t *sub)
|
||||||
|
@ -93,9 +101,7 @@ void RenderPolyScene::RenderSubsector(subsector_t *sub)
|
||||||
|
|
||||||
if (sub->sector->CenterFloor() != sub->sector->CenterCeiling())
|
if (sub->sector->CenterFloor() != sub->sector->CenterCeiling())
|
||||||
{
|
{
|
||||||
RenderPolyPlane plane;
|
RenderPolyPlane::RenderPlanes(WorldToClip, sub, subsectorDepth, Cull.MaxCeilingHeight, Cull.MinFloorHeight);
|
||||||
plane.Render(WorldToClip, sub, subsectorDepth, true, Cull.MaxCeilingHeight);
|
|
||||||
plane.Render(WorldToClip, sub, subsectorDepth, false, Cull.MinFloorHeight);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (uint32_t i = 0; i < sub->numlines; i++)
|
for (uint32_t i = 0; i < sub->numlines; i++)
|
||||||
|
|
|
@ -84,6 +84,9 @@ public:
|
||||||
static RenderPolyScene *Instance();
|
static RenderPolyScene *Instance();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void ClearBuffers();
|
||||||
|
void SetupPerspectiveMatrix();
|
||||||
|
void RenderSectors();
|
||||||
void RenderSubsector(subsector_t *sub);
|
void RenderSubsector(subsector_t *sub);
|
||||||
void RenderLine(subsector_t *sub, seg_t *line, sector_t *frontsector, uint32_t subsectorDepth);
|
void RenderLine(subsector_t *sub, seg_t *line, sector_t *frontsector, uint32_t subsectorDepth);
|
||||||
|
|
||||||
|
|
|
@ -29,6 +29,125 @@
|
||||||
#include "r_poly.h"
|
#include "r_poly.h"
|
||||||
#include "r_sky.h" // for skyflatnum
|
#include "r_sky.h" // for skyflatnum
|
||||||
|
|
||||||
|
EXTERN_CVAR(Int, r_3dfloors)
|
||||||
|
|
||||||
|
void RenderPolyPlane::RenderPlanes(const TriMatrix &worldToClip, subsector_t *sub, uint32_t subsectorDepth, double skyCeilingHeight, double skyFloorHeight)
|
||||||
|
{
|
||||||
|
RenderPolyPlane plane;
|
||||||
|
|
||||||
|
if (r_3dfloors)
|
||||||
|
{
|
||||||
|
auto frontsector = sub->sector;
|
||||||
|
auto &ffloors = frontsector->e->XFloor.ffloors;
|
||||||
|
|
||||||
|
// 3D floor floors
|
||||||
|
for (int i = 0; i < (int)ffloors.Size(); i++)
|
||||||
|
{
|
||||||
|
F3DFloor *fakeFloor = ffloors[i];
|
||||||
|
if (!(fakeFloor->flags & FF_EXISTS)) continue;
|
||||||
|
if (!fakeFloor->model) continue;
|
||||||
|
if (fakeFloor->bottom.plane->isSlope()) continue;
|
||||||
|
//if (!(fakeFloor->flags & FF_NOSHADE) || (fakeFloor->flags & (FF_RENDERPLANES | FF_RENDERSIDES)))
|
||||||
|
// R_3D_AddHeight(fakeFloor->top.plane, frontsector);
|
||||||
|
if (!(fakeFloor->flags & FF_RENDERPLANES)) continue;
|
||||||
|
if (fakeFloor->alpha == 0) continue;
|
||||||
|
if (fakeFloor->flags & FF_THISINSIDE && fakeFloor->flags & FF_INVERTSECTOR) continue;
|
||||||
|
//fakeFloor->alpha
|
||||||
|
|
||||||
|
double fakeHeight = fakeFloor->top.plane->ZatPoint(frontsector->centerspot);
|
||||||
|
if (fakeHeight < ViewPos.Z && fakeHeight > frontsector->floorplane.ZatPoint(frontsector->centerspot))
|
||||||
|
{
|
||||||
|
plane.Render3DFloor(worldToClip, sub, subsectorDepth, false, fakeFloor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3D floor ceilings
|
||||||
|
for (int i = 0; i < (int)ffloors.Size(); i++)
|
||||||
|
{
|
||||||
|
F3DFloor *fakeFloor = ffloors[i];
|
||||||
|
if (!(fakeFloor->flags & FF_EXISTS)) continue;
|
||||||
|
if (!fakeFloor->model) continue;
|
||||||
|
if (fakeFloor->top.plane->isSlope()) continue;
|
||||||
|
//if (!(fakeFloor->flags & FF_NOSHADE) || (fakeFloor->flags & (FF_RENDERPLANES | FF_RENDERSIDES)))
|
||||||
|
// R_3D_AddHeight(fakeFloor->bottom.plane, frontsector);
|
||||||
|
if (!(fakeFloor->flags & FF_RENDERPLANES)) continue;
|
||||||
|
if (fakeFloor->alpha == 0) continue;
|
||||||
|
if (!(fakeFloor->flags & FF_THISINSIDE) && (fakeFloor->flags & (FF_SWIMMABLE | FF_INVERTSECTOR)) == (FF_SWIMMABLE | FF_INVERTSECTOR)) continue;
|
||||||
|
//fakeFloor->alpha
|
||||||
|
|
||||||
|
double fakeHeight = fakeFloor->bottom.plane->ZatPoint(frontsector->centerspot);
|
||||||
|
if (fakeHeight > ViewPos.Z && fakeHeight < frontsector->ceilingplane.ZatPoint(frontsector->centerspot))
|
||||||
|
{
|
||||||
|
plane.Render3DFloor(worldToClip, sub, subsectorDepth, true, fakeFloor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
plane.Render(worldToClip, sub, subsectorDepth, true, skyCeilingHeight);
|
||||||
|
plane.Render(worldToClip, sub, subsectorDepth, false, skyFloorHeight);
|
||||||
|
}
|
||||||
|
|
||||||
|
void RenderPolyPlane::Render3DFloor(const TriMatrix &worldToClip, subsector_t *sub, uint32_t subsectorDepth, bool ceiling, F3DFloor *fakeFloor)
|
||||||
|
{
|
||||||
|
FTextureID picnum = ceiling ? *fakeFloor->bottom.texture : *fakeFloor->top.texture;
|
||||||
|
FTexture *tex = TexMan(picnum);
|
||||||
|
if (tex->UseType == FTexture::TEX_Null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
int lightlevel = 255;
|
||||||
|
if (fixedlightlev < 0 && sub->sector->e->XFloor.lightlist.Size())
|
||||||
|
{
|
||||||
|
lightlist_t *light = P_GetPlaneLight(sub->sector, &sub->sector->ceilingplane, false);
|
||||||
|
basecolormap = light->extra_colormap;
|
||||||
|
lightlevel = *light->p_lightlevel;
|
||||||
|
}
|
||||||
|
|
||||||
|
TriUniforms uniforms;
|
||||||
|
uniforms.objectToClip = worldToClip;
|
||||||
|
uniforms.light = (uint32_t)(lightlevel / 255.0f * 256.0f);
|
||||||
|
if (fixedlightlev >= 0 || fixedcolormap)
|
||||||
|
uniforms.light = 256;
|
||||||
|
uniforms.flags = 0;
|
||||||
|
uniforms.subsectorDepth = subsectorDepth;
|
||||||
|
|
||||||
|
TriVertex *vertices = PolyVertexBuffer::GetVertices(sub->numlines);
|
||||||
|
if (!vertices)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (ceiling)
|
||||||
|
{
|
||||||
|
for (uint32_t i = 0; i < sub->numlines; i++)
|
||||||
|
{
|
||||||
|
seg_t *line = &sub->firstline[i];
|
||||||
|
vertices[sub->numlines - 1 - i] = PlaneVertex(line->v1, fakeFloor->bottom.plane->ZatPoint(line->v1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (uint32_t i = 0; i < sub->numlines; i++)
|
||||||
|
{
|
||||||
|
seg_t *line = &sub->firstline[i];
|
||||||
|
vertices[i] = PlaneVertex(line->v1, fakeFloor->top.plane->ZatPoint(line->v1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
args.SetTexture(tex);
|
||||||
|
PolyTriangleDrawer::draw(args, TriDrawVariant::Draw);
|
||||||
|
PolyTriangleDrawer::draw(args, TriDrawVariant::Stencil);
|
||||||
|
}
|
||||||
|
|
||||||
void RenderPolyPlane::Render(const TriMatrix &worldToClip, subsector_t *sub, uint32_t subsectorDepth, bool ceiling, double skyHeight)
|
void RenderPolyPlane::Render(const TriMatrix &worldToClip, subsector_t *sub, uint32_t subsectorDepth, bool ceiling, double skyHeight)
|
||||||
{
|
{
|
||||||
sector_t *fakesector = sub->sector->heightsec;
|
sector_t *fakesector = sub->sector->heightsec;
|
||||||
|
@ -96,7 +215,7 @@ void RenderPolyPlane::Render(const TriMatrix &worldToClip, subsector_t *sub, uin
|
||||||
for (uint32_t i = 0; i < sub->numlines; i++)
|
for (uint32_t i = 0; i < sub->numlines; i++)
|
||||||
{
|
{
|
||||||
seg_t *line = &sub->firstline[i];
|
seg_t *line = &sub->firstline[i];
|
||||||
vertices[sub->numlines - 1 - i] = PlaneVertex(line->v1, frontsector, isSky ? skyHeight : frontsector->ceilingplane.ZatPoint(line->v1));
|
vertices[sub->numlines - 1 - i] = PlaneVertex(line->v1, isSky ? skyHeight : frontsector->ceilingplane.ZatPoint(line->v1));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -104,7 +223,7 @@ void RenderPolyPlane::Render(const TriMatrix &worldToClip, subsector_t *sub, uin
|
||||||
for (uint32_t i = 0; i < sub->numlines; i++)
|
for (uint32_t i = 0; i < sub->numlines; i++)
|
||||||
{
|
{
|
||||||
seg_t *line = &sub->firstline[i];
|
seg_t *line = &sub->firstline[i];
|
||||||
vertices[i] = PlaneVertex(line->v1, frontsector, isSky ? skyHeight : frontsector->floorplane.ZatPoint(line->v1));
|
vertices[i] = PlaneVertex(line->v1, isSky ? skyHeight : frontsector->floorplane.ZatPoint(line->v1));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -183,17 +302,17 @@ void RenderPolyPlane::Render(const TriMatrix &worldToClip, subsector_t *sub, uin
|
||||||
|
|
||||||
if (ceiling)
|
if (ceiling)
|
||||||
{
|
{
|
||||||
wallvert[0] = PlaneVertex(line->v1, frontsector, skyHeight);
|
wallvert[0] = PlaneVertex(line->v1, skyHeight);
|
||||||
wallvert[1] = PlaneVertex(line->v2, frontsector, skyHeight);
|
wallvert[1] = PlaneVertex(line->v2, skyHeight);
|
||||||
wallvert[2] = PlaneVertex(line->v2, frontsector, skyBottomz2);
|
wallvert[2] = PlaneVertex(line->v2, skyBottomz2);
|
||||||
wallvert[3] = PlaneVertex(line->v1, frontsector, skyBottomz1);
|
wallvert[3] = PlaneVertex(line->v1, skyBottomz1);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
wallvert[0] = PlaneVertex(line->v1, frontsector, frontsector->floorplane.ZatPoint(line->v1));
|
wallvert[0] = PlaneVertex(line->v1, frontsector->floorplane.ZatPoint(line->v1));
|
||||||
wallvert[1] = PlaneVertex(line->v2, frontsector, frontsector->floorplane.ZatPoint(line->v2));
|
wallvert[1] = PlaneVertex(line->v2, frontsector->floorplane.ZatPoint(line->v2));
|
||||||
wallvert[2] = PlaneVertex(line->v2, frontsector, skyHeight);
|
wallvert[2] = PlaneVertex(line->v2, skyHeight);
|
||||||
wallvert[3] = PlaneVertex(line->v1, frontsector, skyHeight);
|
wallvert[3] = PlaneVertex(line->v1, skyHeight);
|
||||||
}
|
}
|
||||||
|
|
||||||
args.vinput = wallvert;
|
args.vinput = wallvert;
|
||||||
|
@ -203,7 +322,7 @@ void RenderPolyPlane::Render(const TriMatrix &worldToClip, subsector_t *sub, uin
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TriVertex RenderPolyPlane::PlaneVertex(vertex_t *v1, sector_t *sector, double height)
|
TriVertex RenderPolyPlane::PlaneVertex(vertex_t *v1, double height)
|
||||||
{
|
{
|
||||||
TriVertex v;
|
TriVertex v;
|
||||||
v.x = (float)v1->fPos().X;
|
v.x = (float)v1->fPos().X;
|
||||||
|
|
|
@ -27,8 +27,10 @@
|
||||||
class RenderPolyPlane
|
class RenderPolyPlane
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
void Render(const TriMatrix &worldToClip, subsector_t *sub, uint32_t subsectorDepth, bool ceiling, double skyHeight);
|
static void RenderPlanes(const TriMatrix &worldToClip, subsector_t *sub, uint32_t subsectorDepth, double skyCeilingHeight, double skyFloorHeight);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
TriVertex PlaneVertex(vertex_t *v1, sector_t *sector, double height);
|
void Render3DFloor(const TriMatrix &worldToClip, subsector_t *sub, uint32_t subsectorDepth, bool ceiling, F3DFloor *fakefloor);
|
||||||
|
void Render(const TriMatrix &worldToClip, subsector_t *sub, uint32_t subsectorDepth, bool ceiling, double skyHeight);
|
||||||
|
TriVertex PlaneVertex(vertex_t *v1, double height);
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue