mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-11 23:32:02 +00:00
Move AddSprites to r_bsp and R_ProjectSprite to r_sprite
This commit is contained in:
parent
82ee9e7399
commit
72762e583f
6 changed files with 525 additions and 537 deletions
|
@ -35,6 +35,7 @@
|
||||||
#include "swrenderer/r_main.h"
|
#include "swrenderer/r_main.h"
|
||||||
#include "swrenderer/drawers/r_draw.h"
|
#include "swrenderer/drawers/r_draw.h"
|
||||||
#include "swrenderer/plane/r_visibleplane.h"
|
#include "swrenderer/plane/r_visibleplane.h"
|
||||||
|
#include "swrenderer/things/r_sprite.h"
|
||||||
#include "swrenderer/things/r_particle.h"
|
#include "swrenderer/things/r_particle.h"
|
||||||
#include "swrenderer/segments/r_clipsegment.h"
|
#include "swrenderer/segments/r_clipsegment.h"
|
||||||
#include "swrenderer/line/r_wallsetup.h"
|
#include "swrenderer/line/r_wallsetup.h"
|
||||||
|
@ -76,12 +77,12 @@ namespace swrenderer
|
||||||
// Similar for ceiling, only reflected.
|
// Similar for ceiling, only reflected.
|
||||||
|
|
||||||
// [RH] allow per-plane lighting
|
// [RH] allow per-plane lighting
|
||||||
if (floorlightlevel != NULL)
|
if (floorlightlevel != nullptr)
|
||||||
{
|
{
|
||||||
*floorlightlevel = sec->GetFloorLight();
|
*floorlightlevel = sec->GetFloorLight();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ceilinglightlevel != NULL)
|
if (ceilinglightlevel != nullptr)
|
||||||
{
|
{
|
||||||
*ceilinglightlevel = sec->GetCeilingLight();
|
*ceilinglightlevel = sec->GetCeilingLight();
|
||||||
}
|
}
|
||||||
|
@ -89,7 +90,7 @@ namespace swrenderer
|
||||||
FakeSide = WaterFakeSide::Center;
|
FakeSide = WaterFakeSide::Center;
|
||||||
|
|
||||||
const sector_t *s = sec->GetHeightSec();
|
const sector_t *s = sec->GetHeightSec();
|
||||||
if (s != NULL)
|
if (s != nullptr)
|
||||||
{
|
{
|
||||||
sector_t *heightsec = viewsector->heightsec;
|
sector_t *heightsec = viewsector->heightsec;
|
||||||
bool underwater = r_fakingunderwater ||
|
bool underwater = r_fakingunderwater ||
|
||||||
|
@ -116,12 +117,12 @@ namespace swrenderer
|
||||||
{
|
{
|
||||||
tempsec->lightlevel = s->lightlevel;
|
tempsec->lightlevel = s->lightlevel;
|
||||||
|
|
||||||
if (floorlightlevel != NULL)
|
if (floorlightlevel != nullptr)
|
||||||
{
|
{
|
||||||
*floorlightlevel = s->GetFloorLight();
|
*floorlightlevel = s->GetFloorLight();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ceilinglightlevel != NULL)
|
if (ceilinglightlevel != nullptr)
|
||||||
{
|
{
|
||||||
*ceilinglightlevel = s->GetCeilingLight();
|
*ceilinglightlevel = s->GetCeilingLight();
|
||||||
}
|
}
|
||||||
|
@ -160,7 +161,7 @@ namespace swrenderer
|
||||||
// are underwater but not in a water sector themselves.
|
// are underwater but not in a water sector themselves.
|
||||||
// Only works if you cannot see the top surface of any deep water
|
// Only works if you cannot see the top surface of any deep water
|
||||||
// sectors at the same time.
|
// sectors at the same time.
|
||||||
if (backline && !r_fakingunderwater && backline->frontsector->heightsec == NULL)
|
if (backline && !r_fakingunderwater && backline->frontsector->heightsec == nullptr)
|
||||||
{
|
{
|
||||||
if (frontcz1 <= s->floorplane.ZatPoint(backline->v1) &&
|
if (frontcz1 <= s->floorplane.ZatPoint(backline->v1) &&
|
||||||
frontcz2 <= s->floorplane.ZatPoint(backline->v2))
|
frontcz2 <= s->floorplane.ZatPoint(backline->v2))
|
||||||
|
@ -215,12 +216,12 @@ namespace swrenderer
|
||||||
{
|
{
|
||||||
tempsec->lightlevel = s->lightlevel;
|
tempsec->lightlevel = s->lightlevel;
|
||||||
|
|
||||||
if (floorlightlevel != NULL)
|
if (floorlightlevel != nullptr)
|
||||||
{
|
{
|
||||||
*floorlightlevel = s->GetFloorLight();
|
*floorlightlevel = s->GetFloorLight();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ceilinglightlevel != NULL)
|
if (ceilinglightlevel != nullptr)
|
||||||
{
|
{
|
||||||
*ceilinglightlevel = s->GetCeilingLight();
|
*ceilinglightlevel = s->GetCeilingLight();
|
||||||
}
|
}
|
||||||
|
@ -252,12 +253,12 @@ namespace swrenderer
|
||||||
{
|
{
|
||||||
tempsec->lightlevel = s->lightlevel;
|
tempsec->lightlevel = s->lightlevel;
|
||||||
|
|
||||||
if (floorlightlevel != NULL)
|
if (floorlightlevel != nullptr)
|
||||||
{
|
{
|
||||||
*floorlightlevel = s->GetFloorLight();
|
*floorlightlevel = s->GetFloorLight();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ceilinglightlevel != NULL)
|
if (ceilinglightlevel != nullptr)
|
||||||
{
|
{
|
||||||
*ceilinglightlevel = s->GetCeilingLight();
|
*ceilinglightlevel = s->GetCeilingLight();
|
||||||
}
|
}
|
||||||
|
@ -376,7 +377,7 @@ namespace swrenderer
|
||||||
|
|
||||||
void RenderBSP::AddPolyobjs(subsector_t *sub)
|
void RenderBSP::AddPolyobjs(subsector_t *sub)
|
||||||
{
|
{
|
||||||
if (sub->BSP == NULL || sub->BSP->bDirty)
|
if (sub->BSP == nullptr || sub->BSP->bDirty)
|
||||||
{
|
{
|
||||||
sub->BuildPolyBSP();
|
sub->BuildPolyBSP();
|
||||||
}
|
}
|
||||||
|
@ -430,8 +431,8 @@ namespace swrenderer
|
||||||
//secplane_t templane;
|
//secplane_t templane;
|
||||||
lightlist_t *light;
|
lightlist_t *light;
|
||||||
|
|
||||||
if (InSubsector != NULL)
|
if (InSubsector != nullptr)
|
||||||
{ // InSubsector is not NULL. This means we are rendering from a mini-BSP.
|
{ // InSubsector is not nullptr. This means we are rendering from a mini-BSP.
|
||||||
outersubsector = false;
|
outersubsector = false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -445,14 +446,14 @@ namespace swrenderer
|
||||||
I_Error("RenderSubsector: ss %ti with numss = %i", sub - subsectors, numsubsectors);
|
I_Error("RenderSubsector: ss %ti with numss = %i", sub - subsectors, numsubsectors);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
assert(sub->sector != NULL);
|
assert(sub->sector != nullptr);
|
||||||
|
|
||||||
if (sub->polys)
|
if (sub->polys)
|
||||||
{ // Render the polyobjs in the subsector first
|
{ // Render the polyobjs in the subsector first
|
||||||
AddPolyobjs(sub);
|
AddPolyobjs(sub);
|
||||||
if (outersubsector)
|
if (outersubsector)
|
||||||
{
|
{
|
||||||
InSubsector = NULL;
|
InSubsector = nullptr;
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -493,7 +494,7 @@ namespace swrenderer
|
||||||
|
|
||||||
visplane_t *ceilingplane = frontsector->ceilingplane.PointOnSide(ViewPos) > 0 ||
|
visplane_t *ceilingplane = frontsector->ceilingplane.PointOnSide(ViewPos) > 0 ||
|
||||||
frontsector->GetTexture(sector_t::ceiling) == skyflatnum ||
|
frontsector->GetTexture(sector_t::ceiling) == skyflatnum ||
|
||||||
portal != NULL ||
|
portal != nullptr ||
|
||||||
(frontsector->heightsec &&
|
(frontsector->heightsec &&
|
||||||
!(frontsector->heightsec->MoreFlags & SECF_IGNOREHEIGHTSEC) &&
|
!(frontsector->heightsec->MoreFlags & SECF_IGNOREHEIGHTSEC) &&
|
||||||
frontsector->heightsec->GetTexture(sector_t::floor) == skyflatnum) ?
|
frontsector->heightsec->GetTexture(sector_t::floor) == skyflatnum) ?
|
||||||
|
@ -505,7 +506,7 @@ namespace swrenderer
|
||||||
frontsector->planes[sector_t::ceiling].xform,
|
frontsector->planes[sector_t::ceiling].xform,
|
||||||
frontsector->sky,
|
frontsector->sky,
|
||||||
portal
|
portal
|
||||||
) : NULL;
|
) : nullptr;
|
||||||
|
|
||||||
if (ceilingplane)
|
if (ceilingplane)
|
||||||
R_AddPlaneLights(ceilingplane, frontsector->lighthead);
|
R_AddPlaneLights(ceilingplane, frontsector->lighthead);
|
||||||
|
@ -533,7 +534,7 @@ namespace swrenderer
|
||||||
|
|
||||||
visplane_t *floorplane = frontsector->floorplane.PointOnSide(ViewPos) > 0 || // killough 3/7/98
|
visplane_t *floorplane = frontsector->floorplane.PointOnSide(ViewPos) > 0 || // killough 3/7/98
|
||||||
frontsector->GetTexture(sector_t::floor) == skyflatnum ||
|
frontsector->GetTexture(sector_t::floor) == skyflatnum ||
|
||||||
portal != NULL ||
|
portal != nullptr ||
|
||||||
(frontsector->heightsec &&
|
(frontsector->heightsec &&
|
||||||
!(frontsector->heightsec->MoreFlags & SECF_IGNOREHEIGHTSEC) &&
|
!(frontsector->heightsec->MoreFlags & SECF_IGNOREHEIGHTSEC) &&
|
||||||
frontsector->heightsec->GetTexture(sector_t::ceiling) == skyflatnum) ?
|
frontsector->heightsec->GetTexture(sector_t::ceiling) == skyflatnum) ?
|
||||||
|
@ -545,7 +546,7 @@ namespace swrenderer
|
||||||
frontsector->planes[sector_t::floor].xform,
|
frontsector->planes[sector_t::floor].xform,
|
||||||
frontsector->sky,
|
frontsector->sky,
|
||||||
portal
|
portal
|
||||||
) : NULL;
|
) : nullptr;
|
||||||
|
|
||||||
if (floorplane)
|
if (floorplane)
|
||||||
R_AddPlaneLights(floorplane, frontsector->lighthead);
|
R_AddPlaneLights(floorplane, frontsector->lighthead);
|
||||||
|
@ -601,7 +602,7 @@ namespace swrenderer
|
||||||
floorlightlevel = *light->p_lightlevel;
|
floorlightlevel = *light->p_lightlevel;
|
||||||
}
|
}
|
||||||
|
|
||||||
ceilingplane = NULL;
|
ceilingplane = nullptr;
|
||||||
floorplane = R_FindPlane(frontsector->floorplane,
|
floorplane = R_FindPlane(frontsector->floorplane,
|
||||||
frontsector->GetTexture(sector_t::floor),
|
frontsector->GetTexture(sector_t::floor),
|
||||||
floorlightlevel + r_actualextralight, // killough 3/16/98
|
floorlightlevel + r_actualextralight, // killough 3/16/98
|
||||||
|
@ -609,7 +610,7 @@ namespace swrenderer
|
||||||
!!(clip3d->fakeFloor->flags & FF_ADDITIVETRANS),
|
!!(clip3d->fakeFloor->flags & FF_ADDITIVETRANS),
|
||||||
frontsector->planes[position].xform,
|
frontsector->planes[position].xform,
|
||||||
frontsector->sky,
|
frontsector->sky,
|
||||||
NULL);
|
nullptr);
|
||||||
|
|
||||||
if (floorplane)
|
if (floorplane)
|
||||||
R_AddPlaneLights(floorplane, frontsector->lighthead);
|
R_AddPlaneLights(floorplane, frontsector->lighthead);
|
||||||
|
@ -666,7 +667,7 @@ namespace swrenderer
|
||||||
}
|
}
|
||||||
tempsec.ceilingplane.ChangeHeight(1 / 65536.);
|
tempsec.ceilingplane.ChangeHeight(1 / 65536.);
|
||||||
|
|
||||||
floorplane = NULL;
|
floorplane = nullptr;
|
||||||
ceilingplane = R_FindPlane(frontsector->ceilingplane, // killough 3/8/98
|
ceilingplane = R_FindPlane(frontsector->ceilingplane, // killough 3/8/98
|
||||||
frontsector->GetTexture(sector_t::ceiling),
|
frontsector->GetTexture(sector_t::ceiling),
|
||||||
ceilinglightlevel + r_actualextralight, // killough 4/11/98
|
ceilinglightlevel + r_actualextralight, // killough 4/11/98
|
||||||
|
@ -674,7 +675,7 @@ namespace swrenderer
|
||||||
!!(clip3d->fakeFloor->flags & FF_ADDITIVETRANS),
|
!!(clip3d->fakeFloor->flags & FF_ADDITIVETRANS),
|
||||||
frontsector->planes[position].xform,
|
frontsector->planes[position].xform,
|
||||||
frontsector->sky,
|
frontsector->sky,
|
||||||
NULL);
|
nullptr);
|
||||||
|
|
||||||
if (ceilingplane)
|
if (ceilingplane)
|
||||||
R_AddPlaneLights(ceilingplane, frontsector->lighthead);
|
R_AddPlaneLights(ceilingplane, frontsector->lighthead);
|
||||||
|
@ -684,7 +685,7 @@ namespace swrenderer
|
||||||
frontsector = sub->sector;
|
frontsector = sub->sector;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
clip3d->fakeFloor = NULL;
|
clip3d->fakeFloor = nullptr;
|
||||||
floorplane = backupfp;
|
floorplane = backupfp;
|
||||||
ceilingplane = backupcp;
|
ceilingplane = backupcp;
|
||||||
}
|
}
|
||||||
|
@ -698,7 +699,7 @@ namespace swrenderer
|
||||||
// lightlevels on floor & ceiling lightlevels in the surrounding area.
|
// lightlevels on floor & ceiling lightlevels in the surrounding area.
|
||||||
// [RH] Handle sprite lighting like Duke 3D: If the ceiling is a sky, sprites are lit by
|
// [RH] Handle sprite lighting like Duke 3D: If the ceiling is a sky, sprites are lit by
|
||||||
// it, otherwise they are lit by the floor.
|
// it, otherwise they are lit by the floor.
|
||||||
R_AddSprites(sub->sector, frontsector->GetTexture(sector_t::ceiling) == skyflatnum ? ceilinglightlevel : floorlightlevel, FakeSide);
|
AddSprites(sub->sector, frontsector->GetTexture(sector_t::ceiling) == skyflatnum ? ceilinglightlevel : floorlightlevel, FakeSide);
|
||||||
|
|
||||||
// [RH] Add particles
|
// [RH] Add particles
|
||||||
if ((unsigned int)(sub - subsectors) < (unsigned int)numsubsectors)
|
if ((unsigned int)(sub - subsectors) < (unsigned int)numsubsectors)
|
||||||
|
@ -715,15 +716,15 @@ namespace swrenderer
|
||||||
|
|
||||||
while (count--)
|
while (count--)
|
||||||
{
|
{
|
||||||
if (!outersubsector || line->sidedef == NULL || !(line->sidedef->Flags & WALLF_POLYOBJ))
|
if (!outersubsector || line->sidedef == nullptr || !(line->sidedef->Flags & WALLF_POLYOBJ))
|
||||||
{
|
{
|
||||||
// kg3D - fake planes bounding calculation
|
// kg3D - fake planes bounding calculation
|
||||||
if (r_3dfloors && line->backsector && frontsector->e && line->backsector->e->XFloor.ffloors.Size())
|
if (r_3dfloors && line->backsector && frontsector->e && line->backsector->e->XFloor.ffloors.Size())
|
||||||
{
|
{
|
||||||
backupfp = floorplane;
|
backupfp = floorplane;
|
||||||
backupcp = ceilingplane;
|
backupcp = ceilingplane;
|
||||||
floorplane = NULL;
|
floorplane = nullptr;
|
||||||
ceilingplane = NULL;
|
ceilingplane = nullptr;
|
||||||
Clip3DFloors *clip3d = Clip3DFloors::Instance();
|
Clip3DFloors *clip3d = Clip3DFloors::Instance();
|
||||||
for (unsigned int i = 0; i < line->backsector->e->XFloor.ffloors.Size(); i++)
|
for (unsigned int i = 0; i < line->backsector->e->XFloor.ffloors.Size(); i++)
|
||||||
{
|
{
|
||||||
|
@ -742,7 +743,7 @@ namespace swrenderer
|
||||||
}
|
}
|
||||||
renderline.Render(line, InSubsector, frontsector, &tempsec, floorplane, ceilingplane); // fake
|
renderline.Render(line, InSubsector, frontsector, &tempsec, floorplane, ceilingplane); // fake
|
||||||
}
|
}
|
||||||
clip3d->fakeFloor = NULL;
|
clip3d->fakeFloor = nullptr;
|
||||||
clip3d->fake3D = 0;
|
clip3d->fake3D = 0;
|
||||||
floorplane = backupfp;
|
floorplane = backupfp;
|
||||||
ceilingplane = backupcp;
|
ceilingplane = backupcp;
|
||||||
|
@ -753,7 +754,7 @@ namespace swrenderer
|
||||||
}
|
}
|
||||||
if (outersubsector)
|
if (outersubsector)
|
||||||
{
|
{
|
||||||
InSubsector = NULL;
|
InSubsector = nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -802,4 +803,62 @@ namespace swrenderer
|
||||||
fillshort(floorclip, viewwidth, viewheight);
|
fillshort(floorclip, viewwidth, viewheight);
|
||||||
fillshort(ceilingclip, viewwidth, !screen->Accel2D && ConBottom > viewwindowy && !bRenderingToCanvas ? (ConBottom - viewwindowy) : 0);
|
fillshort(ceilingclip, viewwidth, !screen->Accel2D && ConBottom > viewwindowy && !bRenderingToCanvas ? (ConBottom - viewwindowy) : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RenderBSP::AddSprites(sector_t *sec, int lightlevel, WaterFakeSide fakeside)
|
||||||
|
{
|
||||||
|
F3DFloor *fakeceiling = nullptr;
|
||||||
|
F3DFloor *fakefloor = nullptr;
|
||||||
|
|
||||||
|
// BSP is traversed by subsector.
|
||||||
|
// A sector might have been split into several
|
||||||
|
// subsectors during BSP building.
|
||||||
|
// Thus we check whether it was already added.
|
||||||
|
if (sec->touching_renderthings == nullptr || sec->validcount == validcount)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Well, now it will be done.
|
||||||
|
sec->validcount = validcount;
|
||||||
|
|
||||||
|
int spriteshade = LIGHT2SHADE(lightlevel + r_actualextralight);
|
||||||
|
|
||||||
|
// Handle all things in sector.
|
||||||
|
for (auto p = sec->touching_renderthings; p != nullptr; p = p->m_snext)
|
||||||
|
{
|
||||||
|
auto thing = p->m_thing;
|
||||||
|
if (thing->validcount == validcount) continue;
|
||||||
|
thing->validcount = validcount;
|
||||||
|
|
||||||
|
FIntCVar *cvar = thing->GetClass()->distancecheck;
|
||||||
|
if (cvar != nullptr && *cvar >= 0)
|
||||||
|
{
|
||||||
|
double dist = (thing->Pos() - ViewPos).LengthSquared();
|
||||||
|
double check = (double)**cvar;
|
||||||
|
if (dist >= check * check)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// find fake level
|
||||||
|
for (auto rover : thing->Sector->e->XFloor.ffloors)
|
||||||
|
{
|
||||||
|
if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_RENDERPLANES)) continue;
|
||||||
|
if (!(rover->flags & FF_SOLID) || rover->alpha != 255) continue;
|
||||||
|
if (!fakefloor)
|
||||||
|
{
|
||||||
|
if (!rover->top.plane->isSlope())
|
||||||
|
{
|
||||||
|
if (rover->top.plane->ZatPoint(0., 0.) <= thing->Z()) fakefloor = rover;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!rover->bottom.plane->isSlope())
|
||||||
|
{
|
||||||
|
if (rover->bottom.plane->ZatPoint(0., 0.) >= thing->Top()) fakeceiling = rover;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
R_ProjectSprite(thing, fakeside, fakefloor, fakeceiling, sec, spriteshade);
|
||||||
|
fakeceiling = nullptr;
|
||||||
|
fakefloor = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,6 +57,8 @@ namespace swrenderer
|
||||||
void AddPolyobjs(subsector_t *sub);
|
void AddPolyobjs(subsector_t *sub);
|
||||||
void FakeDrawLoop(subsector_t *sub, visplane_t *floorplane, visplane_t *ceilingplane);
|
void FakeDrawLoop(subsector_t *sub, visplane_t *floorplane, visplane_t *ceilingplane);
|
||||||
|
|
||||||
|
void AddSprites(sector_t *sec, int lightlevel, WaterFakeSide fakeside);
|
||||||
|
|
||||||
subsector_t *InSubsector = nullptr;
|
subsector_t *InSubsector = nullptr;
|
||||||
sector_t *frontsector = nullptr;
|
sector_t *frontsector = nullptr;
|
||||||
WaterFakeSide FakeSide = WaterFakeSide::Center;
|
WaterFakeSide FakeSide = WaterFakeSide::Center;
|
||||||
|
|
|
@ -66,6 +66,7 @@
|
||||||
#include "swrenderer/things/r_playersprite.h"
|
#include "swrenderer/things/r_playersprite.h"
|
||||||
#include "swrenderer/things/r_wallsprite.h"
|
#include "swrenderer/things/r_wallsprite.h"
|
||||||
#include "swrenderer/things/r_sprite.h"
|
#include "swrenderer/things/r_sprite.h"
|
||||||
|
#include "swrenderer/plane/r_visibleplane.h"
|
||||||
#include "swrenderer/r_memory.h"
|
#include "swrenderer/r_memory.h"
|
||||||
#include "g_levellocals.h"
|
#include "g_levellocals.h"
|
||||||
|
|
||||||
|
@ -172,503 +173,6 @@ bool R_ClipSpriteColumnWithPortals(int x, vissprite_t* spr)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
|
||||||
// R_ProjectSprite
|
|
||||||
// Generates a vissprite for a thing if it might be visible.
|
|
||||||
//
|
|
||||||
void R_ProjectSprite (AActor *thing, WaterFakeSide fakeside, F3DFloor *fakefloor, F3DFloor *fakeceiling, sector_t *current_sector, int spriteshade)
|
|
||||||
{
|
|
||||||
double tr_x;
|
|
||||||
double tr_y;
|
|
||||||
|
|
||||||
double gzt; // killough 3/27/98
|
|
||||||
double gzb; // [RH] use bottom of sprite, not actor
|
|
||||||
double tx;// , tx2;
|
|
||||||
double tz;
|
|
||||||
|
|
||||||
double xscale = 1, yscale = 1;
|
|
||||||
|
|
||||||
int x1;
|
|
||||||
int x2;
|
|
||||||
|
|
||||||
FTextureID picnum;
|
|
||||||
FTexture *tex;
|
|
||||||
FVoxelDef *voxel;
|
|
||||||
|
|
||||||
vissprite_t* vis;
|
|
||||||
|
|
||||||
fixed_t iscale;
|
|
||||||
|
|
||||||
sector_t* heightsec; // killough 3/27/98
|
|
||||||
|
|
||||||
// Don't waste time projecting sprites that are definitely not visible.
|
|
||||||
if (thing == NULL ||
|
|
||||||
(thing->renderflags & RF_INVISIBLE) ||
|
|
||||||
!thing->RenderStyle.IsVisible(thing->Alpha) ||
|
|
||||||
!thing->IsVisibleToPlayer() ||
|
|
||||||
!thing->IsInsideVisibleAngles())
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
RenderPortal *renderportal = RenderPortal::Instance();
|
|
||||||
|
|
||||||
// [ZZ] Or less definitely not visible (hue)
|
|
||||||
// [ZZ] 10.01.2016: don't try to clip stuff inside a skybox against the current portal.
|
|
||||||
if (!renderportal->CurrentPortalInSkybox && renderportal->CurrentPortal && !!P_PointOnLineSidePrecise(thing->Pos(), renderportal->CurrentPortal->dst))
|
|
||||||
return;
|
|
||||||
|
|
||||||
// [RH] Interpolate the sprite's position to make it look smooth
|
|
||||||
DVector3 pos = thing->InterpolatedPosition(r_TicFracF);
|
|
||||||
pos.Z += thing->GetBobOffset(r_TicFracF);
|
|
||||||
|
|
||||||
tex = NULL;
|
|
||||||
voxel = NULL;
|
|
||||||
|
|
||||||
int spritenum = thing->sprite;
|
|
||||||
DVector2 spriteScale = thing->Scale;
|
|
||||||
int renderflags = thing->renderflags;
|
|
||||||
if (spriteScale.Y < 0)
|
|
||||||
{
|
|
||||||
spriteScale.Y = -spriteScale.Y;
|
|
||||||
renderflags ^= RF_YFLIP;
|
|
||||||
}
|
|
||||||
if (thing->player != NULL)
|
|
||||||
{
|
|
||||||
P_CheckPlayerSprite(thing, spritenum, spriteScale);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (thing->picnum.isValid())
|
|
||||||
{
|
|
||||||
picnum = thing->picnum;
|
|
||||||
|
|
||||||
tex = TexMan(picnum);
|
|
||||||
if (tex->UseType == FTexture::TEX_Null)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tex->Rotations != 0xFFFF)
|
|
||||||
{
|
|
||||||
// choose a different rotation based on player view
|
|
||||||
spriteframe_t *sprframe = &SpriteFrames[tex->Rotations];
|
|
||||||
DAngle ang = (pos - ViewPos).Angle();
|
|
||||||
angle_t rot;
|
|
||||||
if (sprframe->Texture[0] == sprframe->Texture[1])
|
|
||||||
{
|
|
||||||
if (thing->flags7 & MF7_SPRITEANGLE)
|
|
||||||
rot = (thing->SpriteAngle + 45.0 / 2 * 9).BAMs() >> 28;
|
|
||||||
else
|
|
||||||
rot = (ang - (thing->Angles.Yaw + thing->SpriteRotation) + 45.0 / 2 * 9).BAMs() >> 28;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (thing->flags7 & MF7_SPRITEANGLE)
|
|
||||||
rot = (thing->SpriteAngle + (45.0 / 2 * 9 - 180.0 / 16)).BAMs() >> 28;
|
|
||||||
else
|
|
||||||
rot = (ang - (thing->Angles.Yaw + thing->SpriteRotation) + (45.0 / 2 * 9 - 180.0 / 16)).BAMs() >> 28;
|
|
||||||
}
|
|
||||||
picnum = sprframe->Texture[rot];
|
|
||||||
if (sprframe->Flip & (1 << rot))
|
|
||||||
{
|
|
||||||
renderflags ^= RF_XFLIP;
|
|
||||||
}
|
|
||||||
tex = TexMan[picnum]; // Do not animate the rotation
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// decide which texture to use for the sprite
|
|
||||||
if ((unsigned)spritenum >= sprites.Size ())
|
|
||||||
{
|
|
||||||
DPrintf (DMSG_ERROR, "R_ProjectSprite: invalid sprite number %u\n", spritenum);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
spritedef_t *sprdef = &sprites[spritenum];
|
|
||||||
if (thing->frame >= sprdef->numframes)
|
|
||||||
{
|
|
||||||
// If there are no frames at all for this sprite, don't draw it.
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
//picnum = SpriteFrames[sprdef->spriteframes + thing->frame].Texture[0];
|
|
||||||
// choose a different rotation based on player view
|
|
||||||
spriteframe_t *sprframe = &SpriteFrames[sprdef->spriteframes + thing->frame];
|
|
||||||
DAngle ang = (pos - ViewPos).Angle();
|
|
||||||
angle_t rot;
|
|
||||||
if (sprframe->Texture[0] == sprframe->Texture[1])
|
|
||||||
{
|
|
||||||
if (thing->flags7 & MF7_SPRITEANGLE)
|
|
||||||
rot = (thing->SpriteAngle + 45.0 / 2 * 9).BAMs() >> 28;
|
|
||||||
else
|
|
||||||
rot = (ang - (thing->Angles.Yaw + thing->SpriteRotation) + 45.0 / 2 * 9).BAMs() >> 28;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (thing->flags7 & MF7_SPRITEANGLE)
|
|
||||||
rot = (thing->SpriteAngle + (45.0 / 2 * 9 - 180.0 / 16)).BAMs() >> 28;
|
|
||||||
else
|
|
||||||
rot = (ang - (thing->Angles.Yaw + thing->SpriteRotation) + (45.0 / 2 * 9 - 180.0 / 16)).BAMs() >> 28;
|
|
||||||
}
|
|
||||||
picnum = sprframe->Texture[rot];
|
|
||||||
if (sprframe->Flip & (1 << rot))
|
|
||||||
{
|
|
||||||
renderflags ^= RF_XFLIP;
|
|
||||||
}
|
|
||||||
tex = TexMan[picnum]; // Do not animate the rotation
|
|
||||||
if (r_drawvoxels)
|
|
||||||
{
|
|
||||||
voxel = sprframe->Voxel;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (spriteScale.X < 0)
|
|
||||||
{
|
|
||||||
spriteScale.X = -spriteScale.X;
|
|
||||||
renderflags ^= RF_XFLIP;
|
|
||||||
}
|
|
||||||
if (voxel == NULL && (tex == NULL || tex->UseType == FTexture::TEX_Null))
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((renderflags & RF_SPRITETYPEMASK) == RF_WALLSPRITE)
|
|
||||||
{
|
|
||||||
R_ProjectWallSprite(thing, pos, picnum, spriteScale, renderflags, spriteshade);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// transform the origin point
|
|
||||||
tr_x = pos.X - ViewPos.X;
|
|
||||||
tr_y = pos.Y - ViewPos.Y;
|
|
||||||
|
|
||||||
tz = tr_x * ViewTanCos + tr_y * ViewTanSin;
|
|
||||||
|
|
||||||
// thing is behind view plane?
|
|
||||||
if (voxel == NULL && tz < MINZ)
|
|
||||||
return;
|
|
||||||
|
|
||||||
tx = tr_x * ViewSin - tr_y * ViewCos;
|
|
||||||
|
|
||||||
// [RH] Flip for mirrors
|
|
||||||
if (renderportal->MirrorFlags & RF_XFLIP)
|
|
||||||
{
|
|
||||||
tx = -tx;
|
|
||||||
}
|
|
||||||
//tx2 = tx >> 4;
|
|
||||||
|
|
||||||
// too far off the side?
|
|
||||||
// if it's a voxel, it can be further off the side
|
|
||||||
if ((voxel == NULL && (fabs(tx / 64) > fabs(tz))) ||
|
|
||||||
(voxel != NULL && (fabs(tx / 128) > fabs(tz))))
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (voxel == NULL)
|
|
||||||
{
|
|
||||||
// [RH] Added scaling
|
|
||||||
int scaled_to = tex->GetScaledTopOffset();
|
|
||||||
int scaled_bo = scaled_to - tex->GetScaledHeight();
|
|
||||||
gzt = pos.Z + spriteScale.Y * scaled_to;
|
|
||||||
gzb = pos.Z + spriteScale.Y * scaled_bo;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
xscale = spriteScale.X * voxel->Scale;
|
|
||||||
yscale = spriteScale.Y * voxel->Scale;
|
|
||||||
double piv = voxel->Voxel->Mips[0].Pivot.Z;
|
|
||||||
gzt = pos.Z + yscale * piv - thing->Floorclip;
|
|
||||||
gzb = pos.Z + yscale * (piv - voxel->Voxel->Mips[0].SizeZ);
|
|
||||||
if (gzt <= gzb)
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// killough 3/27/98: exclude things totally separated
|
|
||||||
// from the viewer, by either water or fake ceilings
|
|
||||||
// killough 4/11/98: improve sprite clipping for underwater/fake ceilings
|
|
||||||
|
|
||||||
heightsec = thing->Sector->GetHeightSec();
|
|
||||||
|
|
||||||
if (heightsec != NULL) // only clip things which are in special sectors
|
|
||||||
{
|
|
||||||
if (fakeside == WaterFakeSide::AboveCeiling)
|
|
||||||
{
|
|
||||||
if (gzt < heightsec->ceilingplane.ZatPoint(pos))
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else if (fakeside == WaterFakeSide::BelowFloor)
|
|
||||||
{
|
|
||||||
if (gzb >= heightsec->floorplane.ZatPoint(pos))
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (gzt < heightsec->floorplane.ZatPoint(pos))
|
|
||||||
return;
|
|
||||||
if (!(heightsec->MoreFlags & SECF_FAKEFLOORONLY) && gzb >= heightsec->ceilingplane.ZatPoint(pos))
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (voxel == NULL)
|
|
||||||
{
|
|
||||||
xscale = CenterX / tz;
|
|
||||||
|
|
||||||
// [RH] Reject sprites that are off the top or bottom of the screen
|
|
||||||
if (globaluclip * tz > ViewPos.Z - gzb || globaldclip * tz < ViewPos.Z - gzt)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// [RH] Flip for mirrors
|
|
||||||
renderflags ^= renderportal->MirrorFlags & RF_XFLIP;
|
|
||||||
|
|
||||||
// calculate edges of the shape
|
|
||||||
const double thingxscalemul = spriteScale.X / tex->Scale.X;
|
|
||||||
|
|
||||||
tx -= ((renderflags & RF_XFLIP) ? (tex->GetWidth() - tex->LeftOffset - 1) : tex->LeftOffset) * thingxscalemul;
|
|
||||||
double dtx1 = tx * xscale;
|
|
||||||
x1 = centerx + xs_RoundToInt(dtx1);
|
|
||||||
|
|
||||||
// off the right side?
|
|
||||||
if (x1 >= renderportal->WindowRight)
|
|
||||||
return;
|
|
||||||
|
|
||||||
tx += tex->GetWidth() * thingxscalemul;
|
|
||||||
x2 = centerx + xs_RoundToInt(tx * xscale);
|
|
||||||
|
|
||||||
// off the left side or too small?
|
|
||||||
if ((x2 < renderportal->WindowLeft || x2 <= x1))
|
|
||||||
return;
|
|
||||||
|
|
||||||
xscale = spriteScale.X * xscale / tex->Scale.X;
|
|
||||||
iscale = (fixed_t)(FRACUNIT / xscale); // Round towards zero to avoid wrapping in edge cases
|
|
||||||
|
|
||||||
double yscale = spriteScale.Y / tex->Scale.Y;
|
|
||||||
|
|
||||||
// store information in a vissprite
|
|
||||||
vis = R_NewVisSprite();
|
|
||||||
|
|
||||||
vis->CurrentPortalUniq = renderportal->CurrentPortalUniq;
|
|
||||||
vis->xscale = FLOAT2FIXED(xscale);
|
|
||||||
vis->yscale = float(InvZtoScale * yscale / tz);
|
|
||||||
vis->idepth = float(1 / tz);
|
|
||||||
vis->floorclip = thing->Floorclip / yscale;
|
|
||||||
vis->texturemid = tex->TopOffset - (ViewPos.Z - pos.Z + thing->Floorclip) / yscale;
|
|
||||||
vis->x1 = x1 < renderportal->WindowLeft ? renderportal->WindowLeft : x1;
|
|
||||||
vis->x2 = x2 > renderportal->WindowRight ? renderportal->WindowRight : x2;
|
|
||||||
vis->Angle = thing->Angles.Yaw;
|
|
||||||
|
|
||||||
if (renderflags & RF_XFLIP)
|
|
||||||
{
|
|
||||||
vis->startfrac = (tex->GetWidth() << FRACBITS) - 1;
|
|
||||||
vis->xiscale = -iscale;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
vis->startfrac = 0;
|
|
||||||
vis->xiscale = iscale;
|
|
||||||
}
|
|
||||||
|
|
||||||
vis->startfrac += (fixed_t)(vis->xiscale * (vis->x1 - centerx + 0.5 - dtx1));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
vis = R_NewVisSprite();
|
|
||||||
|
|
||||||
vis->CurrentPortalUniq = renderportal->CurrentPortalUniq;
|
|
||||||
vis->xscale = FLOAT2FIXED(xscale);
|
|
||||||
vis->yscale = (float)yscale;
|
|
||||||
vis->x1 = renderportal->WindowLeft;
|
|
||||||
vis->x2 = renderportal->WindowRight;
|
|
||||||
vis->idepth = 1 / MINZ;
|
|
||||||
vis->floorclip = thing->Floorclip;
|
|
||||||
|
|
||||||
pos.Z -= thing->Floorclip;
|
|
||||||
|
|
||||||
vis->Angle = thing->Angles.Yaw + voxel->AngleOffset;
|
|
||||||
|
|
||||||
int voxelspin = (thing->flags & MF_DROPPED) ? voxel->DroppedSpin : voxel->PlacedSpin;
|
|
||||||
if (voxelspin != 0)
|
|
||||||
{
|
|
||||||
DAngle ang = double(I_FPSTime()) * voxelspin / 1000;
|
|
||||||
vis->Angle -= ang;
|
|
||||||
}
|
|
||||||
|
|
||||||
vis->pa.vpos = { (float)ViewPos.X, (float)ViewPos.Y, (float)ViewPos.Z };
|
|
||||||
vis->pa.vang = FAngle((float)ViewAngle.Degrees);
|
|
||||||
}
|
|
||||||
|
|
||||||
// killough 3/27/98: save sector for special clipping later
|
|
||||||
vis->heightsec = heightsec;
|
|
||||||
vis->sector = thing->Sector;
|
|
||||||
|
|
||||||
vis->depth = (float)tz;
|
|
||||||
vis->gpos = { (float)pos.X, (float)pos.Y, (float)pos.Z };
|
|
||||||
vis->gzb = (float)gzb; // [RH] use gzb, not thing->z
|
|
||||||
vis->gzt = (float)gzt; // killough 3/27/98
|
|
||||||
vis->deltax = float(pos.X - ViewPos.X);
|
|
||||||
vis->deltay = float(pos.Y - ViewPos.Y);
|
|
||||||
vis->renderflags = renderflags;
|
|
||||||
if(thing->flags5 & MF5_BRIGHT)
|
|
||||||
vis->renderflags |= RF_FULLBRIGHT; // kg3D
|
|
||||||
vis->Style.RenderStyle = thing->RenderStyle;
|
|
||||||
vis->FillColor = thing->fillcolor;
|
|
||||||
vis->Translation = thing->Translation; // [RH] thing translation table
|
|
||||||
vis->FakeFlatStat = fakeside;
|
|
||||||
vis->Style.Alpha = float(thing->Alpha);
|
|
||||||
vis->fakefloor = fakefloor;
|
|
||||||
vis->fakeceiling = fakeceiling;
|
|
||||||
vis->Style.ColormapNum = 0;
|
|
||||||
vis->bInMirror = renderportal->MirrorFlags & RF_XFLIP;
|
|
||||||
vis->bSplitSprite = false;
|
|
||||||
|
|
||||||
if (voxel != NULL)
|
|
||||||
{
|
|
||||||
vis->voxel = voxel->Voxel;
|
|
||||||
vis->bIsVoxel = true;
|
|
||||||
vis->bWallSprite = false;
|
|
||||||
DrewAVoxel = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
vis->pic = tex;
|
|
||||||
vis->bIsVoxel = false;
|
|
||||||
vis->bWallSprite = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// The software renderer cannot invert the source without inverting the overlay
|
|
||||||
// too. That means if the source is inverted, we need to do the reverse of what
|
|
||||||
// the invert overlay flag says to do.
|
|
||||||
INTBOOL invertcolormap = (vis->Style.RenderStyle.Flags & STYLEF_InvertOverlay);
|
|
||||||
|
|
||||||
if (vis->Style.RenderStyle.Flags & STYLEF_InvertSource)
|
|
||||||
{
|
|
||||||
invertcolormap = !invertcolormap;
|
|
||||||
}
|
|
||||||
|
|
||||||
FDynamicColormap *mybasecolormap = basecolormap;
|
|
||||||
if (current_sector->sectornum != thing->Sector->sectornum) // compare sectornums to account for R_FakeFlat copies.
|
|
||||||
{
|
|
||||||
// Todo: The actor is from a different sector so we have to retrieve the proper basecolormap for that sector.
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sprites that are added to the scene must fade to black.
|
|
||||||
if (vis->Style.RenderStyle == LegacyRenderStyles[STYLE_Add] && mybasecolormap->Fade != 0)
|
|
||||||
{
|
|
||||||
mybasecolormap = GetSpecialLights(mybasecolormap->Color, 0, mybasecolormap->Desaturate);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (vis->Style.RenderStyle.Flags & STYLEF_FadeToBlack)
|
|
||||||
{
|
|
||||||
if (invertcolormap)
|
|
||||||
{ // Fade to white
|
|
||||||
mybasecolormap = GetSpecialLights(mybasecolormap->Color, MAKERGB(255,255,255), mybasecolormap->Desaturate);
|
|
||||||
invertcolormap = false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{ // Fade to black
|
|
||||||
mybasecolormap = GetSpecialLights(mybasecolormap->Color, MAKERGB(0,0,0), mybasecolormap->Desaturate);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// get light level
|
|
||||||
if (fixedcolormap != NULL)
|
|
||||||
{ // fixed map
|
|
||||||
vis->Style.BaseColormap = fixedcolormap;
|
|
||||||
vis->Style.ColormapNum = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (invertcolormap)
|
|
||||||
{
|
|
||||||
mybasecolormap = GetSpecialLights(mybasecolormap->Color, mybasecolormap->Fade.InverseColor(), mybasecolormap->Desaturate);
|
|
||||||
}
|
|
||||||
if (fixedlightlev >= 0)
|
|
||||||
{
|
|
||||||
vis->Style.BaseColormap = mybasecolormap;
|
|
||||||
vis->Style.ColormapNum = fixedlightlev >> COLORMAPSHIFT;
|
|
||||||
}
|
|
||||||
else if (!foggy && ((renderflags & RF_FULLBRIGHT) || (thing->flags5 & MF5_BRIGHT)))
|
|
||||||
{ // full bright
|
|
||||||
vis->Style.BaseColormap = (r_fullbrightignoresectorcolor) ? &FullNormalLight : mybasecolormap;
|
|
||||||
vis->Style.ColormapNum = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{ // diminished light
|
|
||||||
vis->Style.ColormapNum = GETPALOOKUP(
|
|
||||||
r_SpriteVisibility / MAX(tz, MINZ), spriteshade);
|
|
||||||
vis->Style.BaseColormap = mybasecolormap;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// R_AddSprites
|
|
||||||
// During BSP traversal, this adds sprites by sector.
|
|
||||||
//
|
|
||||||
// killough 9/18/98: add lightlevel as parameter, fixing underwater lighting
|
|
||||||
// [RH] Save which side of heightsec sprite is on here.
|
|
||||||
void R_AddSprites (sector_t *sec, int lightlevel, WaterFakeSide fakeside)
|
|
||||||
{
|
|
||||||
F3DFloor *fakeceiling = NULL;
|
|
||||||
F3DFloor *fakefloor = NULL;
|
|
||||||
|
|
||||||
// BSP is traversed by subsector.
|
|
||||||
// A sector might have been split into several
|
|
||||||
// subsectors during BSP building.
|
|
||||||
// Thus we check whether it was already added.
|
|
||||||
if (sec->touching_renderthings == nullptr || sec->validcount == validcount)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// Well, now it will be done.
|
|
||||||
sec->validcount = validcount;
|
|
||||||
|
|
||||||
int spriteshade = LIGHT2SHADE(lightlevel + r_actualextralight);
|
|
||||||
|
|
||||||
// Handle all things in sector.
|
|
||||||
for(auto p = sec->touching_renderthings; p != nullptr; p = p->m_snext)
|
|
||||||
{
|
|
||||||
auto thing = p->m_thing;
|
|
||||||
if (thing->validcount == validcount) continue;
|
|
||||||
thing->validcount = validcount;
|
|
||||||
|
|
||||||
FIntCVar *cvar = thing->GetClass()->distancecheck;
|
|
||||||
if (cvar != NULL && *cvar >= 0)
|
|
||||||
{
|
|
||||||
double dist = (thing->Pos() - ViewPos).LengthSquared();
|
|
||||||
double check = (double)**cvar;
|
|
||||||
if (dist >= check * check)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// find fake level
|
|
||||||
for(auto rover : thing->Sector->e->XFloor.ffloors)
|
|
||||||
{
|
|
||||||
if(!(rover->flags & FF_EXISTS) || !(rover->flags & FF_RENDERPLANES)) continue;
|
|
||||||
if(!(rover->flags & FF_SOLID) || rover->alpha != 255) continue;
|
|
||||||
if(!fakefloor)
|
|
||||||
{
|
|
||||||
if(!rover->top.plane->isSlope())
|
|
||||||
{
|
|
||||||
if(rover->top.plane->ZatPoint(0., 0.) <= thing->Z()) fakefloor = rover;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(!rover->bottom.plane->isSlope())
|
|
||||||
{
|
|
||||||
if(rover->bottom.plane->ZatPoint(0., 0.) >= thing->Top()) fakeceiling = rover;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
R_ProjectSprite (thing, fakeside, fakefloor, fakeceiling, sec, spriteshade);
|
|
||||||
fakeceiling = NULL;
|
|
||||||
fakefloor = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// R_SortVisSprites
|
// R_SortVisSprites
|
||||||
|
@ -1196,8 +700,6 @@ void R_DrawMaskedSingle (bool renew)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void R_DrawHeightPlanes(double height); // kg3D - fake planes
|
|
||||||
|
|
||||||
void R_DrawMasked ()
|
void R_DrawMasked ()
|
||||||
{
|
{
|
||||||
R_CollectPortals();
|
R_CollectPortals();
|
||||||
|
@ -1255,11 +757,4 @@ void R_DrawMasked ()
|
||||||
R_DrawPlayerSprites();
|
R_DrawPlayerSprites();
|
||||||
}
|
}
|
||||||
|
|
||||||
extern double BaseYaspectMul;;
|
|
||||||
|
|
||||||
inline int sgn(int v)
|
|
||||||
{
|
|
||||||
return v < 0 ? -1 : v > 0 ? 1 : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,7 +43,6 @@ bool R_ClipSpriteColumnWithPortals(int x, vissprite_t* spr);
|
||||||
|
|
||||||
void R_CacheSprite (spritedef_t *sprite);
|
void R_CacheSprite (spritedef_t *sprite);
|
||||||
void R_SortVisSprites (int (*compare)(const void *, const void *), size_t first);
|
void R_SortVisSprites (int (*compare)(const void *, const void *), size_t first);
|
||||||
void R_AddSprites (sector_t *sec, int lightlevel, WaterFakeSide fakeside);
|
|
||||||
void R_DrawSprites ();
|
void R_DrawSprites ();
|
||||||
void R_ClearSprites ();
|
void R_ClearSprites ();
|
||||||
void R_DrawMasked ();
|
void R_DrawMasked ();
|
||||||
|
@ -52,6 +51,7 @@ enum { DVF_OFFSCREEN = 1, DVF_SPANSONLY = 2, DVF_MIRRORED = 4 };
|
||||||
|
|
||||||
void R_ClipVisSprite (vissprite_t *vis, int xl, int xh);
|
void R_ClipVisSprite (vissprite_t *vis, int xl, int xh);
|
||||||
|
|
||||||
|
extern bool DrewAVoxel;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -55,8 +55,439 @@
|
||||||
#include "swrenderer/things/r_sprite.h"
|
#include "swrenderer/things/r_sprite.h"
|
||||||
#include "swrenderer/r_memory.h"
|
#include "swrenderer/r_memory.h"
|
||||||
|
|
||||||
|
EXTERN_CVAR(Bool, r_drawvoxels)
|
||||||
|
|
||||||
namespace swrenderer
|
namespace swrenderer
|
||||||
{
|
{
|
||||||
|
void R_ProjectSprite(AActor *thing, WaterFakeSide fakeside, F3DFloor *fakefloor, F3DFloor *fakeceiling, sector_t *current_sector, int spriteshade)
|
||||||
|
{
|
||||||
|
double tr_x;
|
||||||
|
double tr_y;
|
||||||
|
|
||||||
|
double gzt; // killough 3/27/98
|
||||||
|
double gzb; // [RH] use bottom of sprite, not actor
|
||||||
|
double tx;// , tx2;
|
||||||
|
double tz;
|
||||||
|
|
||||||
|
double xscale = 1, yscale = 1;
|
||||||
|
|
||||||
|
int x1;
|
||||||
|
int x2;
|
||||||
|
|
||||||
|
FTextureID picnum;
|
||||||
|
FTexture *tex;
|
||||||
|
FVoxelDef *voxel;
|
||||||
|
|
||||||
|
vissprite_t* vis;
|
||||||
|
|
||||||
|
fixed_t iscale;
|
||||||
|
|
||||||
|
sector_t* heightsec; // killough 3/27/98
|
||||||
|
|
||||||
|
// Don't waste time projecting sprites that are definitely not visible.
|
||||||
|
if (thing == nullptr ||
|
||||||
|
(thing->renderflags & RF_INVISIBLE) ||
|
||||||
|
!thing->RenderStyle.IsVisible(thing->Alpha) ||
|
||||||
|
!thing->IsVisibleToPlayer() ||
|
||||||
|
!thing->IsInsideVisibleAngles())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
RenderPortal *renderportal = RenderPortal::Instance();
|
||||||
|
|
||||||
|
// [ZZ] Or less definitely not visible (hue)
|
||||||
|
// [ZZ] 10.01.2016: don't try to clip stuff inside a skybox against the current portal.
|
||||||
|
if (!renderportal->CurrentPortalInSkybox && renderportal->CurrentPortal && !!P_PointOnLineSidePrecise(thing->Pos(), renderportal->CurrentPortal->dst))
|
||||||
|
return;
|
||||||
|
|
||||||
|
// [RH] Interpolate the sprite's position to make it look smooth
|
||||||
|
DVector3 pos = thing->InterpolatedPosition(r_TicFracF);
|
||||||
|
pos.Z += thing->GetBobOffset(r_TicFracF);
|
||||||
|
|
||||||
|
tex = nullptr;
|
||||||
|
voxel = nullptr;
|
||||||
|
|
||||||
|
int spritenum = thing->sprite;
|
||||||
|
DVector2 spriteScale = thing->Scale;
|
||||||
|
int renderflags = thing->renderflags;
|
||||||
|
if (spriteScale.Y < 0)
|
||||||
|
{
|
||||||
|
spriteScale.Y = -spriteScale.Y;
|
||||||
|
renderflags ^= RF_YFLIP;
|
||||||
|
}
|
||||||
|
if (thing->player != nullptr)
|
||||||
|
{
|
||||||
|
P_CheckPlayerSprite(thing, spritenum, spriteScale);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (thing->picnum.isValid())
|
||||||
|
{
|
||||||
|
picnum = thing->picnum;
|
||||||
|
|
||||||
|
tex = TexMan(picnum);
|
||||||
|
if (tex->UseType == FTexture::TEX_Null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tex->Rotations != 0xFFFF)
|
||||||
|
{
|
||||||
|
// choose a different rotation based on player view
|
||||||
|
spriteframe_t *sprframe = &SpriteFrames[tex->Rotations];
|
||||||
|
DAngle ang = (pos - ViewPos).Angle();
|
||||||
|
angle_t rot;
|
||||||
|
if (sprframe->Texture[0] == sprframe->Texture[1])
|
||||||
|
{
|
||||||
|
if (thing->flags7 & MF7_SPRITEANGLE)
|
||||||
|
rot = (thing->SpriteAngle + 45.0 / 2 * 9).BAMs() >> 28;
|
||||||
|
else
|
||||||
|
rot = (ang - (thing->Angles.Yaw + thing->SpriteRotation) + 45.0 / 2 * 9).BAMs() >> 28;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (thing->flags7 & MF7_SPRITEANGLE)
|
||||||
|
rot = (thing->SpriteAngle + (45.0 / 2 * 9 - 180.0 / 16)).BAMs() >> 28;
|
||||||
|
else
|
||||||
|
rot = (ang - (thing->Angles.Yaw + thing->SpriteRotation) + (45.0 / 2 * 9 - 180.0 / 16)).BAMs() >> 28;
|
||||||
|
}
|
||||||
|
picnum = sprframe->Texture[rot];
|
||||||
|
if (sprframe->Flip & (1 << rot))
|
||||||
|
{
|
||||||
|
renderflags ^= RF_XFLIP;
|
||||||
|
}
|
||||||
|
tex = TexMan[picnum]; // Do not animate the rotation
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// decide which texture to use for the sprite
|
||||||
|
if ((unsigned)spritenum >= sprites.Size())
|
||||||
|
{
|
||||||
|
DPrintf(DMSG_ERROR, "R_ProjectSprite: invalid sprite number %u\n", spritenum);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
spritedef_t *sprdef = &sprites[spritenum];
|
||||||
|
if (thing->frame >= sprdef->numframes)
|
||||||
|
{
|
||||||
|
// If there are no frames at all for this sprite, don't draw it.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//picnum = SpriteFrames[sprdef->spriteframes + thing->frame].Texture[0];
|
||||||
|
// choose a different rotation based on player view
|
||||||
|
spriteframe_t *sprframe = &SpriteFrames[sprdef->spriteframes + thing->frame];
|
||||||
|
DAngle ang = (pos - ViewPos).Angle();
|
||||||
|
angle_t rot;
|
||||||
|
if (sprframe->Texture[0] == sprframe->Texture[1])
|
||||||
|
{
|
||||||
|
if (thing->flags7 & MF7_SPRITEANGLE)
|
||||||
|
rot = (thing->SpriteAngle + 45.0 / 2 * 9).BAMs() >> 28;
|
||||||
|
else
|
||||||
|
rot = (ang - (thing->Angles.Yaw + thing->SpriteRotation) + 45.0 / 2 * 9).BAMs() >> 28;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (thing->flags7 & MF7_SPRITEANGLE)
|
||||||
|
rot = (thing->SpriteAngle + (45.0 / 2 * 9 - 180.0 / 16)).BAMs() >> 28;
|
||||||
|
else
|
||||||
|
rot = (ang - (thing->Angles.Yaw + thing->SpriteRotation) + (45.0 / 2 * 9 - 180.0 / 16)).BAMs() >> 28;
|
||||||
|
}
|
||||||
|
picnum = sprframe->Texture[rot];
|
||||||
|
if (sprframe->Flip & (1 << rot))
|
||||||
|
{
|
||||||
|
renderflags ^= RF_XFLIP;
|
||||||
|
}
|
||||||
|
tex = TexMan[picnum]; // Do not animate the rotation
|
||||||
|
if (r_drawvoxels)
|
||||||
|
{
|
||||||
|
voxel = sprframe->Voxel;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (spriteScale.X < 0)
|
||||||
|
{
|
||||||
|
spriteScale.X = -spriteScale.X;
|
||||||
|
renderflags ^= RF_XFLIP;
|
||||||
|
}
|
||||||
|
if (voxel == nullptr && (tex == nullptr || tex->UseType == FTexture::TEX_Null))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((renderflags & RF_SPRITETYPEMASK) == RF_WALLSPRITE)
|
||||||
|
{
|
||||||
|
R_ProjectWallSprite(thing, pos, picnum, spriteScale, renderflags, spriteshade);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// transform the origin point
|
||||||
|
tr_x = pos.X - ViewPos.X;
|
||||||
|
tr_y = pos.Y - ViewPos.Y;
|
||||||
|
|
||||||
|
tz = tr_x * ViewTanCos + tr_y * ViewTanSin;
|
||||||
|
|
||||||
|
// thing is behind view plane?
|
||||||
|
if (voxel == nullptr && tz < MINZ)
|
||||||
|
return;
|
||||||
|
|
||||||
|
tx = tr_x * ViewSin - tr_y * ViewCos;
|
||||||
|
|
||||||
|
// [RH] Flip for mirrors
|
||||||
|
if (renderportal->MirrorFlags & RF_XFLIP)
|
||||||
|
{
|
||||||
|
tx = -tx;
|
||||||
|
}
|
||||||
|
//tx2 = tx >> 4;
|
||||||
|
|
||||||
|
// too far off the side?
|
||||||
|
// if it's a voxel, it can be further off the side
|
||||||
|
if ((voxel == nullptr && (fabs(tx / 64) > fabs(tz))) ||
|
||||||
|
(voxel != nullptr && (fabs(tx / 128) > fabs(tz))))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (voxel == nullptr)
|
||||||
|
{
|
||||||
|
// [RH] Added scaling
|
||||||
|
int scaled_to = tex->GetScaledTopOffset();
|
||||||
|
int scaled_bo = scaled_to - tex->GetScaledHeight();
|
||||||
|
gzt = pos.Z + spriteScale.Y * scaled_to;
|
||||||
|
gzb = pos.Z + spriteScale.Y * scaled_bo;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
xscale = spriteScale.X * voxel->Scale;
|
||||||
|
yscale = spriteScale.Y * voxel->Scale;
|
||||||
|
double piv = voxel->Voxel->Mips[0].Pivot.Z;
|
||||||
|
gzt = pos.Z + yscale * piv - thing->Floorclip;
|
||||||
|
gzb = pos.Z + yscale * (piv - voxel->Voxel->Mips[0].SizeZ);
|
||||||
|
if (gzt <= gzb)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// killough 3/27/98: exclude things totally separated
|
||||||
|
// from the viewer, by either water or fake ceilings
|
||||||
|
// killough 4/11/98: improve sprite clipping for underwater/fake ceilings
|
||||||
|
|
||||||
|
heightsec = thing->Sector->GetHeightSec();
|
||||||
|
|
||||||
|
if (heightsec != nullptr) // only clip things which are in special sectors
|
||||||
|
{
|
||||||
|
if (fakeside == WaterFakeSide::AboveCeiling)
|
||||||
|
{
|
||||||
|
if (gzt < heightsec->ceilingplane.ZatPoint(pos))
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if (fakeside == WaterFakeSide::BelowFloor)
|
||||||
|
{
|
||||||
|
if (gzb >= heightsec->floorplane.ZatPoint(pos))
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (gzt < heightsec->floorplane.ZatPoint(pos))
|
||||||
|
return;
|
||||||
|
if (!(heightsec->MoreFlags & SECF_FAKEFLOORONLY) && gzb >= heightsec->ceilingplane.ZatPoint(pos))
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (voxel == nullptr)
|
||||||
|
{
|
||||||
|
xscale = CenterX / tz;
|
||||||
|
|
||||||
|
// [RH] Reject sprites that are off the top or bottom of the screen
|
||||||
|
if (globaluclip * tz > ViewPos.Z - gzb || globaldclip * tz < ViewPos.Z - gzt)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// [RH] Flip for mirrors
|
||||||
|
renderflags ^= renderportal->MirrorFlags & RF_XFLIP;
|
||||||
|
|
||||||
|
// calculate edges of the shape
|
||||||
|
const double thingxscalemul = spriteScale.X / tex->Scale.X;
|
||||||
|
|
||||||
|
tx -= ((renderflags & RF_XFLIP) ? (tex->GetWidth() - tex->LeftOffset - 1) : tex->LeftOffset) * thingxscalemul;
|
||||||
|
double dtx1 = tx * xscale;
|
||||||
|
x1 = centerx + xs_RoundToInt(dtx1);
|
||||||
|
|
||||||
|
// off the right side?
|
||||||
|
if (x1 >= renderportal->WindowRight)
|
||||||
|
return;
|
||||||
|
|
||||||
|
tx += tex->GetWidth() * thingxscalemul;
|
||||||
|
x2 = centerx + xs_RoundToInt(tx * xscale);
|
||||||
|
|
||||||
|
// off the left side or too small?
|
||||||
|
if ((x2 < renderportal->WindowLeft || x2 <= x1))
|
||||||
|
return;
|
||||||
|
|
||||||
|
xscale = spriteScale.X * xscale / tex->Scale.X;
|
||||||
|
iscale = (fixed_t)(FRACUNIT / xscale); // Round towards zero to avoid wrapping in edge cases
|
||||||
|
|
||||||
|
double yscale = spriteScale.Y / tex->Scale.Y;
|
||||||
|
|
||||||
|
// store information in a vissprite
|
||||||
|
vis = R_NewVisSprite();
|
||||||
|
|
||||||
|
vis->CurrentPortalUniq = renderportal->CurrentPortalUniq;
|
||||||
|
vis->xscale = FLOAT2FIXED(xscale);
|
||||||
|
vis->yscale = float(InvZtoScale * yscale / tz);
|
||||||
|
vis->idepth = float(1 / tz);
|
||||||
|
vis->floorclip = thing->Floorclip / yscale;
|
||||||
|
vis->texturemid = tex->TopOffset - (ViewPos.Z - pos.Z + thing->Floorclip) / yscale;
|
||||||
|
vis->x1 = x1 < renderportal->WindowLeft ? renderportal->WindowLeft : x1;
|
||||||
|
vis->x2 = x2 > renderportal->WindowRight ? renderportal->WindowRight : x2;
|
||||||
|
vis->Angle = thing->Angles.Yaw;
|
||||||
|
|
||||||
|
if (renderflags & RF_XFLIP)
|
||||||
|
{
|
||||||
|
vis->startfrac = (tex->GetWidth() << FRACBITS) - 1;
|
||||||
|
vis->xiscale = -iscale;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
vis->startfrac = 0;
|
||||||
|
vis->xiscale = iscale;
|
||||||
|
}
|
||||||
|
|
||||||
|
vis->startfrac += (fixed_t)(vis->xiscale * (vis->x1 - centerx + 0.5 - dtx1));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
vis = R_NewVisSprite();
|
||||||
|
|
||||||
|
vis->CurrentPortalUniq = renderportal->CurrentPortalUniq;
|
||||||
|
vis->xscale = FLOAT2FIXED(xscale);
|
||||||
|
vis->yscale = (float)yscale;
|
||||||
|
vis->x1 = renderportal->WindowLeft;
|
||||||
|
vis->x2 = renderportal->WindowRight;
|
||||||
|
vis->idepth = 1 / MINZ;
|
||||||
|
vis->floorclip = thing->Floorclip;
|
||||||
|
|
||||||
|
pos.Z -= thing->Floorclip;
|
||||||
|
|
||||||
|
vis->Angle = thing->Angles.Yaw + voxel->AngleOffset;
|
||||||
|
|
||||||
|
int voxelspin = (thing->flags & MF_DROPPED) ? voxel->DroppedSpin : voxel->PlacedSpin;
|
||||||
|
if (voxelspin != 0)
|
||||||
|
{
|
||||||
|
DAngle ang = double(I_FPSTime()) * voxelspin / 1000;
|
||||||
|
vis->Angle -= ang;
|
||||||
|
}
|
||||||
|
|
||||||
|
vis->pa.vpos = { (float)ViewPos.X, (float)ViewPos.Y, (float)ViewPos.Z };
|
||||||
|
vis->pa.vang = FAngle((float)ViewAngle.Degrees);
|
||||||
|
}
|
||||||
|
|
||||||
|
// killough 3/27/98: save sector for special clipping later
|
||||||
|
vis->heightsec = heightsec;
|
||||||
|
vis->sector = thing->Sector;
|
||||||
|
|
||||||
|
vis->depth = (float)tz;
|
||||||
|
vis->gpos = { (float)pos.X, (float)pos.Y, (float)pos.Z };
|
||||||
|
vis->gzb = (float)gzb; // [RH] use gzb, not thing->z
|
||||||
|
vis->gzt = (float)gzt; // killough 3/27/98
|
||||||
|
vis->deltax = float(pos.X - ViewPos.X);
|
||||||
|
vis->deltay = float(pos.Y - ViewPos.Y);
|
||||||
|
vis->renderflags = renderflags;
|
||||||
|
if (thing->flags5 & MF5_BRIGHT)
|
||||||
|
vis->renderflags |= RF_FULLBRIGHT; // kg3D
|
||||||
|
vis->Style.RenderStyle = thing->RenderStyle;
|
||||||
|
vis->FillColor = thing->fillcolor;
|
||||||
|
vis->Translation = thing->Translation; // [RH] thing translation table
|
||||||
|
vis->FakeFlatStat = fakeside;
|
||||||
|
vis->Style.Alpha = float(thing->Alpha);
|
||||||
|
vis->fakefloor = fakefloor;
|
||||||
|
vis->fakeceiling = fakeceiling;
|
||||||
|
vis->Style.ColormapNum = 0;
|
||||||
|
vis->bInMirror = renderportal->MirrorFlags & RF_XFLIP;
|
||||||
|
vis->bSplitSprite = false;
|
||||||
|
|
||||||
|
if (voxel != nullptr)
|
||||||
|
{
|
||||||
|
vis->voxel = voxel->Voxel;
|
||||||
|
vis->bIsVoxel = true;
|
||||||
|
vis->bWallSprite = false;
|
||||||
|
DrewAVoxel = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
vis->pic = tex;
|
||||||
|
vis->bIsVoxel = false;
|
||||||
|
vis->bWallSprite = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The software renderer cannot invert the source without inverting the overlay
|
||||||
|
// too. That means if the source is inverted, we need to do the reverse of what
|
||||||
|
// the invert overlay flag says to do.
|
||||||
|
INTBOOL invertcolormap = (vis->Style.RenderStyle.Flags & STYLEF_InvertOverlay);
|
||||||
|
|
||||||
|
if (vis->Style.RenderStyle.Flags & STYLEF_InvertSource)
|
||||||
|
{
|
||||||
|
invertcolormap = !invertcolormap;
|
||||||
|
}
|
||||||
|
|
||||||
|
FDynamicColormap *mybasecolormap = basecolormap;
|
||||||
|
if (current_sector->sectornum != thing->Sector->sectornum) // compare sectornums to account for R_FakeFlat copies.
|
||||||
|
{
|
||||||
|
// Todo: The actor is from a different sector so we have to retrieve the proper basecolormap for that sector.
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sprites that are added to the scene must fade to black.
|
||||||
|
if (vis->Style.RenderStyle == LegacyRenderStyles[STYLE_Add] && mybasecolormap->Fade != 0)
|
||||||
|
{
|
||||||
|
mybasecolormap = GetSpecialLights(mybasecolormap->Color, 0, mybasecolormap->Desaturate);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (vis->Style.RenderStyle.Flags & STYLEF_FadeToBlack)
|
||||||
|
{
|
||||||
|
if (invertcolormap)
|
||||||
|
{ // Fade to white
|
||||||
|
mybasecolormap = GetSpecialLights(mybasecolormap->Color, MAKERGB(255, 255, 255), mybasecolormap->Desaturate);
|
||||||
|
invertcolormap = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{ // Fade to black
|
||||||
|
mybasecolormap = GetSpecialLights(mybasecolormap->Color, MAKERGB(0, 0, 0), mybasecolormap->Desaturate);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// get light level
|
||||||
|
if (fixedcolormap != nullptr)
|
||||||
|
{ // fixed map
|
||||||
|
vis->Style.BaseColormap = fixedcolormap;
|
||||||
|
vis->Style.ColormapNum = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (invertcolormap)
|
||||||
|
{
|
||||||
|
mybasecolormap = GetSpecialLights(mybasecolormap->Color, mybasecolormap->Fade.InverseColor(), mybasecolormap->Desaturate);
|
||||||
|
}
|
||||||
|
if (fixedlightlev >= 0)
|
||||||
|
{
|
||||||
|
vis->Style.BaseColormap = mybasecolormap;
|
||||||
|
vis->Style.ColormapNum = fixedlightlev >> COLORMAPSHIFT;
|
||||||
|
}
|
||||||
|
else if (!foggy && ((renderflags & RF_FULLBRIGHT) || (thing->flags5 & MF5_BRIGHT)))
|
||||||
|
{ // full bright
|
||||||
|
vis->Style.BaseColormap = (r_fullbrightignoresectorcolor) ? &FullNormalLight : mybasecolormap;
|
||||||
|
vis->Style.ColormapNum = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{ // diminished light
|
||||||
|
vis->Style.ColormapNum = GETPALOOKUP(
|
||||||
|
r_SpriteVisibility / MAX(tz, MINZ), spriteshade);
|
||||||
|
vis->Style.BaseColormap = mybasecolormap;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void R_DrawVisSprite(vissprite_t *vis, const short *mfloorclip, const short *mceilingclip)
|
void R_DrawVisSprite(vissprite_t *vis, const short *mfloorclip, const short *mceilingclip)
|
||||||
{
|
{
|
||||||
fixed_t frac;
|
fixed_t frac;
|
||||||
|
|
|
@ -17,5 +17,6 @@
|
||||||
|
|
||||||
namespace swrenderer
|
namespace swrenderer
|
||||||
{
|
{
|
||||||
|
void R_ProjectSprite(AActor *thing, WaterFakeSide fakeside, F3DFloor *fakefloor, F3DFloor *fakeceiling, sector_t *current_sector, int spriteshade);
|
||||||
void R_DrawVisSprite(vissprite_t *vis, const short *mfloorclip, const short *mceilingclip);
|
void R_DrawVisSprite(vissprite_t *vis, const short *mfloorclip, const short *mceilingclip);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue