- moved particle storage into FLevelLocals.

- moved parts of the render setup out of the separate render functions.

Things like particle and polyobject linking were duplicated several times for rendering different things in different renderers.
These things only need to be set up once before the renderer is started so it makes a lot more sense to consolidate them into one place outside the actual rendering code.
This commit is contained in:
Christoph Oelckers 2019-01-29 01:09:02 +01:00
parent 50d59e99cb
commit 68667e5eaa
22 changed files with 139 additions and 128 deletions

View file

@ -25,6 +25,7 @@
#include "basictypes.h"
#include <functional>
//
@ -119,6 +120,7 @@ typedef enum
// Called by IO functions when input is detected.
void D_PostEvent (const event_t* ev);
void D_RemoveNextCharEvent();
void D_Render(std::function<void()> action, bool interpolate);
//

View file

@ -351,6 +351,35 @@ void D_RemoveNextCharEvent()
}
}
//==========================================================================
//
// Render wrapper.
// This function contains all the needed setup and cleanup for starting a render job.
//
//==========================================================================
void D_Render(std::function<void()> action, bool interpolate)
{
for (auto Level : AllLevels())
{
// Check for the presence of dynamic lights at the start of the frame once.
if ((gl_lights && vid_rendermode == 4) || (r_dynlights && vid_rendermode != 4))
{
Level->HasDynamicLights = !!level.lights;
}
else Level->HasDynamicLights = false; // lights are off so effectively we have none.
if (interpolate) Level->interpolator.DoInterpolations(I_GetTimeFrac());
P_FindParticleSubsectors(Level);
PO_LinkToSubsectors(Level);
}
action();
if (interpolate) for (auto Level : AllLevels())
{
Level->interpolator.RestoreInterpolations();
}
}
//==========================================================================
//
// CVAR dmflags
@ -746,22 +775,10 @@ void D_Display ()
//E_RenderFrame();
//
for (auto Level : AllLevels())
D_Render([&]()
{
// Check for the presence of dynamic lights at the start of the frame once.
if ((gl_lights && vid_rendermode == 4) || (r_dynlights && vid_rendermode != 4))
{
Level->HasDynamicLights = !!level.lights;
}
else Level->HasDynamicLights = false; // lights are off so effectively we have none.
Level->interpolator.DoInterpolations(I_GetTimeFrac());
}
viewsec = screen->RenderView(&players[consoleplayer]);
for (auto Level : AllLevels())
{
Level->interpolator.RestoreInterpolations();
}
viewsec = screen->RenderView(&players[consoleplayer]);
}, true);
screen->Begin2D();
screen->DrawBlend(viewsec);

View file

@ -72,6 +72,7 @@
#include "vm.h"
#include "dobjgc.h"
#include "gi.h"
#include "a_dynlight.h"
#include "g_hub.h"
#include "g_levellocals.h"
@ -2101,7 +2102,10 @@ static void PutSavePic (FileWriter *file, int width, int height)
}
else
{
screen->WriteSavePic(&players[consoleplayer], file, width, height);
D_Render([&]()
{
screen->WriteSavePic(&players[consoleplayer], file, width, height);
}, false);
}
}

View file

@ -80,6 +80,7 @@
#include "i_music.h"
#include "a_dynlight.h"
#include "p_conversation.h"
#include "p_effect.h"
#include "gi.h"
@ -1460,6 +1461,8 @@ int G_FinishTravel ()
void FLevelLocals::Init()
{
P_InitParticles(this);
P_ClearParticles(this);
BaseBlendA = 0.0f; // Remove underwater blend effect, if any
gravity = sv_gravity * 35/TICRATE;

View file

@ -47,6 +47,7 @@
#include "p_tags.h"
#include "p_spec.h"
#include "actor.h"
#include "p_effect.h"
#include "p_destructible.h"
#include "r_data/r_sections.h"
#include "r_data/r_canvastexture.h"
@ -491,6 +492,12 @@ public:
int ActiveSequences;
DSeqNode *SequenceListHead;
// [RH] particle globals
uint32_t ActiveParticles;
uint32_t InactiveParticles;
TArray<particle_t> Particles;
TArray<uint16_t> ParticlesInSubsec;
TArray<DVector2> Scrolls; // NULL if no DScrollers in this level
int8_t WallVertLight; // Light diffs for vert/horiz walls

View file

@ -245,8 +245,6 @@ sector_t *FGLRenderer::RenderView(player_t* player)
if (cl_capfps || r_NoInterpolate) r_viewpoint.TicFrac = 1.;
else r_viewpoint.TicFrac = I_GetTimeFrac();
P_FindParticleSubsectors();
screen->mLights->Clear();
screen->mViewpoints->Clear();
@ -358,7 +356,6 @@ void FGLRenderer::WriteSavePic (player_t *player, FileWriter *file, int width, i
mBuffers = mSaveBuffers;
hw_ClearFakeFlat();
P_FindParticleSubsectors(); // make sure that all recently spawned particles have a valid subsector.
gl_RenderState.SetVertexBuffer(screen->mVertexData);
screen->mVertexData->Reset();
screen->mLights->Clear();

View file

@ -554,16 +554,16 @@ void HWDrawInfo::RenderThings(subsector_t * sub, sector_t * sector)
void HWDrawInfo::RenderParticles(subsector_t *sub, sector_t *front)
{
SetupSprite.Clock();
for (int i = ParticlesInSubsec[sub->Index()]; i != NO_PARTICLE; i = Particles[i].snext)
for (int i = Level->ParticlesInSubsec[sub->Index()]; i != NO_PARTICLE; i = Level->Particles[i].snext)
{
if (mClipPortal)
{
int clipres = mClipPortal->ClipPoint(Particles[i].Pos);
int clipres = mClipPortal->ClipPoint(Level->Particles[i].Pos);
if (clipres == PClip_InFront) continue;
}
GLSprite sprite;
sprite.ProcessParticle(this, &Particles[i], front);
sprite.ProcessParticle(this, &Level->Particles[i], front);
}
SetupSprite.Unclock();
}
@ -626,7 +626,7 @@ void HWDrawInfo::DoSubsector(subsector_t * sub)
}
// [RH] Add particles
if (gl_render_things && ParticlesInSubsec[sub->Index()] != NO_PARTICLE)
if (gl_render_things && Level->ParticlesInSubsec[sub->Index()] != NO_PARTICLE)
{
if (multithread)
{

View file

@ -429,7 +429,6 @@ void HWDrawInfo::CreateScene()
// reset the portal manager
screen->mPortalState->StartFrame();
PO_LinkToSubsectors(Level);
ProcessAll.Clock();

View file

@ -152,6 +152,7 @@ void MapLoader::SpawnPolyobj (int index, int tag, int type)
unsigned int ii;
int i;
FPolyObj *po = &Level->Polyobjects[index];
po->Level = Level;
for (ii = 0; ii < KnownPolySides.Size(); ++ii)
{
@ -351,10 +352,6 @@ void MapLoader::PO_Init (void)
InitSideLists ();
Level->Polyobjects.Resize(NumPolyobjs);
for (auto p : Level->Polyobjects)
{
p.Level = Level;
}
polyIndex = 0; // index polyobj number
// Find the startSpot points, and spawn each polyobj

View file

@ -6447,7 +6447,7 @@ doplaysound: if (funcIndex == ACSF_PlayActorSound)
size = fabs(size);
if (lifetime != 0)
P_SpawnParticle(DVector3(ACSToDouble(x), ACSToDouble(y), ACSToDouble(z)),
P_SpawnParticle(Level, DVector3(ACSToDouble(x), ACSToDouble(y), ACSToDouble(z)),
DVector3(ACSToDouble(xvel), ACSToDouble(yvel), ACSToDouble(zvel)),
DVector3(ACSToDouble(accelx), ACSToDouble(accely), ACSToDouble(accelz)),
color, startalpha/255., lifetime, size, endsize, fadestep/255., fullbright);

View file

@ -1669,7 +1669,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_SpawnParticle)
acc.X = accelx * c + accely * s;
acc.Y = accelx * s - accely * c;
}
P_SpawnParticle(self->Vec3Offset(pos), vel, acc, color, startalpha, lifetime, size, fadestep, sizestep, flags);
P_SpawnParticle(self->Level, self->Vec3Offset(pos), vel, acc, color, startalpha, lifetime, size, fadestep, sizestep, flags);
}
return 0;
}

View file

@ -59,12 +59,6 @@ FRandom pr_railtrail("RailTrail");
#define FADEFROMTTL(a) (1.f/(a))
// [RH] particle globals
uint32_t ActiveParticles;
uint32_t InactiveParticles;
TArray<particle_t> Particles;
TArray<uint16_t> ParticlesInSubsec;
static int grey1, grey2, grey3, grey4, red, green, blue, yellow, black,
red1, green1, blue1, yellow1, purple, purple1, white,
rblue1, rblue2, rblue3, rblue4, orange, yorange, dred, grey5,
@ -103,15 +97,15 @@ static const struct ColorList {
{NULL, 0, 0, 0 }
};
inline particle_t *NewParticle (void)
inline particle_t *NewParticle (FLevelLocals *Level)
{
particle_t *result = nullptr;
if (InactiveParticles != NO_PARTICLE)
if (Level->InactiveParticles != NO_PARTICLE)
{
result = &Particles[InactiveParticles];
InactiveParticles = result->tnext;
result->tnext = ActiveParticles;
ActiveParticles = uint32_t(result - Particles.Data());
result = &Level->Particles[Level->InactiveParticles];
Level->InactiveParticles = result->tnext;
result->tnext = Level->ActiveParticles;
Level->ActiveParticles = uint32_t(result - Level->Particles.Data());
}
return result;
}
@ -119,7 +113,7 @@ inline particle_t *NewParticle (void)
//
// [RH] Particle functions
//
void P_InitParticles ();
void P_InitParticles (FLevelLocals *);
// [BC] Allow the maximum number of particles to be specified by a cvar (so people
// with lots of nice hardware can have lots of particles!).
@ -134,11 +128,14 @@ CUSTOM_CVAR( Int, r_maxparticles, 4000, CVAR_ARCHIVE )
if ( gamestate != GS_STARTUP )
{
P_InitParticles( );
for (auto Level : AllLevels())
{
P_InitParticles(Level);
}
}
}
void P_InitParticles ()
void P_InitParticles (FLevelLocals *Level)
{
const char *i;
int num;
@ -152,45 +149,45 @@ void P_InitParticles ()
// This should be good, but eh...
int NumParticles = clamp<int>(num, 100, 65535);
Particles.Resize(NumParticles);
P_ClearParticles ();
Level->Particles.Resize(NumParticles);
P_ClearParticles (Level);
}
void P_ClearParticles ()
void P_ClearParticles (FLevelLocals *Level)
{
int i = 0;
memset (Particles.Data(), 0, Particles.Size() * sizeof(particle_t));
ActiveParticles = NO_PARTICLE;
InactiveParticles = 0;
for (auto &p : Particles)
memset (Level->Particles.Data(), 0, Level->Particles.Size() * sizeof(particle_t));
Level->ActiveParticles = NO_PARTICLE;
Level->InactiveParticles = 0;
for (auto &p : Level->Particles)
p.tnext = ++i;
Particles.Last().tnext = NO_PARTICLE;
Level->Particles.Last().tnext = NO_PARTICLE;
}
// Group particles by subsectors. Because particles are always
// in motion, there is little benefit to caching this information
// from one frame to the next.
void P_FindParticleSubsectors ()
void P_FindParticleSubsectors (FLevelLocals *Level)
{
if (ParticlesInSubsec.Size() < level.subsectors.Size())
if (Level->ParticlesInSubsec.Size() < level.subsectors.Size())
{
ParticlesInSubsec.Reserve (level.subsectors.Size() - ParticlesInSubsec.Size());
Level->ParticlesInSubsec.Reserve (level.subsectors.Size() - Level->ParticlesInSubsec.Size());
}
fillshort (&ParticlesInSubsec[0], level.subsectors.Size(), NO_PARTICLE);
fillshort (&Level->ParticlesInSubsec[0], level.subsectors.Size(), NO_PARTICLE);
if (!r_particles)
{
return;
}
for (uint16_t i = ActiveParticles; i != NO_PARTICLE; i = Particles[i].tnext)
for (uint16_t i = Level->ActiveParticles; i != NO_PARTICLE; i = Level->Particles[i].tnext)
{
// Try to reuse the subsector from the last portal check, if still valid.
if (Particles[i].subsector == NULL) Particles[i].subsector = R_PointInSubsector(Particles[i].Pos);
int ssnum = Particles[i].subsector->Index();
Particles[i].snext = ParticlesInSubsec[ssnum];
ParticlesInSubsec[ssnum] = i;
if (Level->Particles[i].subsector == nullptr) Level->Particles[i].subsector = R_PointInSubsector(Level->Particles[i].Pos);
int ssnum = Level->Particles[i].subsector->Index();
Level->Particles[i].snext = Level->ParticlesInSubsec[ssnum];
Level->ParticlesInSubsec[ssnum] = i;
}
}
@ -220,7 +217,6 @@ void P_InitEffects ()
{
const struct ColorList *color = Colors;
P_InitParticles();
while (color->color)
{
*(color->color) = ParticleColor(color->r, color->g, color->b);
@ -232,16 +228,16 @@ void P_InitEffects ()
blood2 = ParticleColor(RPART(kind)/3, GPART(kind)/3, BPART(kind)/3);
}
void P_ThinkParticles ()
void P_ThinkParticles (FLevelLocals *Level)
{
int i;
particle_t *particle, *prev;
i = ActiveParticles;
i = Level->ActiveParticles;
prev = NULL;
while (i != NO_PARTICLE)
{
particle = &Particles[i];
particle = &Level->Particles[i];
i = particle->tnext;
if (!particle->notimefreeze && level.isFrozen())
{
@ -258,9 +254,9 @@ void P_ThinkParticles ()
if (prev)
prev->tnext = i;
else
ActiveParticles = i;
particle->tnext = InactiveParticles;
InactiveParticles = (int)(particle - Particles.Data());
Level->ActiveParticles = i;
particle->tnext = Level->InactiveParticles;
Level->InactiveParticles = (int)(particle - Level->Particles.Data());
continue;
}
@ -299,10 +295,10 @@ enum PSFlag
PS_NOTIMEFREEZE = 1 << 5,
};
void P_SpawnParticle(const DVector3 &pos, const DVector3 &vel, const DVector3 &accel, PalEntry color, double startalpha, int lifetime, double size,
void P_SpawnParticle(FLevelLocals *Level, const DVector3 &pos, const DVector3 &vel, const DVector3 &accel, PalEntry color, double startalpha, int lifetime, double size,
double fadestep, double sizestep, int flags)
{
particle_t *particle = NewParticle();
particle_t *particle = NewParticle(Level);
if (particle)
{
@ -326,7 +322,7 @@ void P_SpawnParticle(const DVector3 &pos, const DVector3 &vel, const DVector3 &a
//
// Run effects on all actors in the world
//
void P_RunEffects ()
void P_RunEffects (FLevelLocals *Level)
{
if (players[consoleplayer].camera == NULL) return;
@ -339,10 +335,7 @@ void P_RunEffects ()
{
if (actor->effects || actor->fountaincolor)
{
// Only run the effect if the actor is potentially visible
int rnum = pnum + actor->Sector->Index();
if (level.rejectmatrix.Size() == 0 || !(level.rejectmatrix[rnum>>3] & (1 << (rnum & 7))))
P_RunEffect (actor, actor->effects);
P_RunEffect (actor, actor->effects);
}
}
}
@ -352,14 +345,14 @@ void P_RunEffects ()
//
// Creates a particle with "jitter"
//
particle_t *JitterParticle (int ttl)
particle_t *JitterParticle (FLevelLocals *Level, int ttl)
{
return JitterParticle (ttl, 1.0);
return JitterParticle (Level, ttl, 1.0);
}
// [XA] Added "drift speed" multiplier setting for enhanced railgun stuffs.
particle_t *JitterParticle (int ttl, double drift)
particle_t *JitterParticle (FLevelLocals *Level, int ttl, double drift)
{
particle_t *particle = NewParticle ();
particle_t *particle = NewParticle (Level);
if (particle) {
int i;
@ -385,7 +378,7 @@ static void MakeFountain (AActor *actor, int color1, int color2)
if (!(level.time & 1))
return;
particle = JitterParticle (51);
particle = JitterParticle (actor->Level, 51);
if (particle)
{
@ -425,7 +418,7 @@ void P_RunEffect (AActor *actor, int effects)
DAngle an = moveangle + 90.;
double speed;
particle = JitterParticle (3 + (M_Random() & 31));
particle = JitterParticle (actor->Level, 3 + (M_Random() & 31));
if (particle) {
double pathdist = M_Random() / 256.;
DVector3 pos = actor->Vec3Offset(
@ -442,7 +435,7 @@ void P_RunEffect (AActor *actor, int effects)
particle->size = 2;
}
for (i = 6; i; i--) {
particle_t *particle = JitterParticle (3 + (M_Random() & 31));
particle_t *particle = JitterParticle (actor->Level, 3 + (M_Random() & 31));
if (particle) {
double pathdist = M_Random() / 256.;
DVector3 pos = actor->Vec3Offset(
@ -471,7 +464,7 @@ void P_RunEffect (AActor *actor, int effects)
DVector3 pos = actor->Vec3Angle(-actor->radius * 2, moveangle, -actor->Height * actor->Vel.Z / 8 + actor->Height * (2. / 3));
P_DrawSplash2 (6, pos, moveangle + 180, 2, 2);
P_DrawSplash2 (actor->Level, 6, pos, moveangle + 180, 2, 2);
}
if (actor->fountaincolor)
{
@ -498,7 +491,7 @@ void P_RunEffect (AActor *actor, int effects)
for (i = 3; i > 0; i--)
{
particle = JitterParticle (16);
particle = JitterParticle (actor->Level, 16);
if (particle != NULL)
{
DAngle ang = M_Random() * (360 / 256.);
@ -519,7 +512,7 @@ void P_RunEffect (AActor *actor, int effects)
}
}
void P_DrawSplash (int count, const DVector3 &pos, DAngle angle, int kind)
void P_DrawSplash (FLevelLocals *Level, int count, const DVector3 &pos, DAngle angle, int kind)
{
int color1, color2;
@ -535,7 +528,7 @@ void P_DrawSplash (int count, const DVector3 &pos, DAngle angle, int kind)
for (; count; count--)
{
particle_t *p = JitterParticle (10);
particle_t *p = JitterParticle (Level, 10);
if (!p)
break;
@ -553,7 +546,7 @@ void P_DrawSplash (int count, const DVector3 &pos, DAngle angle, int kind)
}
}
void P_DrawSplash2 (int count, const DVector3 &pos, DAngle angle, int updown, int kind)
void P_DrawSplash2 (FLevelLocals *Level, int count, const DVector3 &pos, DAngle angle, int updown, int kind)
{
int color1, color2, zadd;
double zvel, zspread;
@ -584,7 +577,7 @@ void P_DrawSplash2 (int count, const DVector3 &pos, DAngle angle, int updown, in
for (; count; count--)
{
particle_t *p = NewParticle ();
particle_t *p = NewParticle (Level);
DAngle an;
if (!p)
@ -724,7 +717,7 @@ void P_DrawRailTrail(AActor *source, TArray<SPortalHit> &portalhits, int color1,
deg = (double)SpiralOffset;
for (i = spiral_steps; i; i--)
{
particle_t *p = NewParticle ();
particle_t *p = NewParticle (source->Level);
DVector3 tempvec;
if (!p)
@ -795,7 +788,7 @@ void P_DrawRailTrail(AActor *source, TArray<SPortalHit> &portalhits, int color1,
{
// [XA] inner trail uses a different default duration (33).
int innerduration = (duration == 0) ? 33 : duration;
particle_t *p = JitterParticle (innerduration, (float)drift);
particle_t *p = JitterParticle (source->Level, innerduration, (float)drift);
if (!p)
return;
@ -915,7 +908,7 @@ void P_DisconnectEffect (AActor *actor)
for (i = 64; i; i--)
{
particle_t *p = JitterParticle (TICRATE*2);
particle_t *p = JitterParticle (actor->Level, TICRATE*2);
if (!p)
break;

View file

@ -41,6 +41,7 @@
#define FX_VISIBILITYPULSE 0x00000040
struct subsector_t;
struct FLevelLocals;
// [RH] Particle details
@ -62,24 +63,22 @@ struct particle_t
uint16_t snext;
};
extern TArray<particle_t> Particles;
extern TArray<uint16_t> ParticlesInSubsec;
const uint16_t NO_PARTICLE = 0xffff;
void P_ClearParticles ();
void P_FindParticleSubsectors ();
void P_InitParticles(FLevelLocals *);
void P_ClearParticles (FLevelLocals *Level);
void P_FindParticleSubsectors (FLevelLocals *Level);
class AActor;
particle_t *JitterParticle (int ttl);
particle_t *JitterParticle (int ttl, double drift);
particle_t *JitterParticle (FLevelLocals *Level, int ttl);
particle_t *JitterParticle (FLevelLocals *Level, int ttl, double drift);
void P_ThinkParticles (void);
void P_SpawnParticle(const DVector3 &pos, const DVector3 &vel, const DVector3 &accel, PalEntry color, double startalpha, int lifetime, double size, double fadestep, double sizestep, int flags = 0);
void P_ThinkParticles (FLevelLocals *Level);
void P_SpawnParticle(FLevelLocals *Level, const DVector3 &pos, const DVector3 &vel, const DVector3 &accel, PalEntry color, double startalpha, int lifetime, double size, double fadestep, double sizestep, int flags = 0);
void P_InitEffects (void);
void P_RunEffects (void);
void P_RunEffects (FLevelLocals *Level);
void P_RunEffect (AActor *actor, int effects);
@ -91,6 +90,6 @@ struct SPortalHit
};
void P_DrawRailTrail(AActor *source, TArray<SPortalHit> &portalhits, int color1, int color2, double maxdiff = 0, int flags = 0, PClassActor *spawnclass = NULL, DAngle angle = 0., int duration = 35, double sparsity = 1.0, double drift = 1.0, int SpiralOffset = 270, DAngle pitch = 0.);
void P_DrawSplash (int count, const DVector3 &pos, DAngle angle, int kind);
void P_DrawSplash2 (int count, const DVector3 &pos, DAngle angle, int updown, int kind);
void P_DrawSplash (FLevelLocals *Level, int count, const DVector3 &pos, DAngle angle, int kind);
void P_DrawSplash2 (FLevelLocals *Level, int count, const DVector3 &pos, DAngle angle, int updown, int kind);
void P_DisconnectEffect (AActor *actor);

View file

@ -6203,7 +6203,7 @@ void P_DoCrunch(AActor *thing, FChangePosition *cpos)
DAngle an = (M_Random() - 128) * (360./256);
if (cl_bloodtype >= 1)
{
P_DrawSplash2(32, thing->PosPlusZ(thing->Height/2), an, 2, thing->BloodColor);
P_DrawSplash2(thing->Level, 32, thing->PosPlusZ(thing->Height/2), an, 2, thing->BloodColor);
}
}
if (thing->CrushPainSound != 0 && !S_GetSoundPlayingInfo(thing, thing->CrushPainSound))

View file

@ -5619,7 +5619,7 @@ AActor *P_SpawnPuff (AActor *source, PClassActor *pufftype, const DVector3 &pos1
{
if (cl_pufftype && updown != 3 && (puff->flags4 & MF4_ALLOWPARTICLES))
{
P_DrawSplash2 (32, pos, particledir, updown, 1);
P_DrawSplash2 (source->Level, 32, pos, particledir, updown, 1);
if (cl_pufftype == 1) puff->renderflags |= RF_INVISIBLE;
}
@ -5743,7 +5743,7 @@ void P_SpawnBlood (const DVector3 &pos1, DAngle dir, int damage, AActor *origina
}
if (bloodtype >= 1)
P_DrawSplash2 (40, pos, dir, 2, originator->BloodColor);
P_DrawSplash2 (originator->Level, 40, pos, dir, 2, originator->BloodColor);
}
DEFINE_ACTION_FUNCTION(AActor, SpawnBlood)
@ -5794,7 +5794,7 @@ void P_BloodSplatter (const DVector3 &pos, AActor *originator, DAngle hitangle)
}
if (bloodtype >= 1)
{
P_DrawSplash2 (40, pos, hitangle-180., 2, originator->BloodColor);
P_DrawSplash2 (originator->Level, 40, pos, hitangle-180., 2, originator->BloodColor);
}
}
@ -5835,7 +5835,7 @@ void P_BloodSplatter2 (const DVector3 &pos, AActor *originator, DAngle hitangle)
}
if (bloodtype >= 1)
{
P_DrawSplash2(40, pos + add, hitangle - 180., 2, originator->BloodColor);
P_DrawSplash2(originator->Level, 40, pos + add, hitangle - 180., 2, originator->BloodColor);
}
}
@ -5895,7 +5895,7 @@ void P_RipperBlood (AActor *mo, AActor *bleeder)
}
if (bloodtype >= 1)
{
P_DrawSplash2(28, pos, bleeder->AngleTo(mo) + 180., 0, bleeder->BloodColor);
P_DrawSplash2(bleeder->Level, 28, pos, bleeder->AngleTo(mo) + 180., 0, bleeder->BloodColor);
}
}

View file

@ -509,7 +509,7 @@ void P_SetupLevel(FLevelLocals *Level, int position, bool newGame)
R_OldBlend = 0xffffffff;
// [RH] Remove all particles
P_ClearParticles();
P_ClearParticles(Level);
// preload graphics and sounds
if (precache)

View file

@ -135,12 +135,12 @@ void P_Ticker (void)
{
ac->ClearInterpolation();
}
P_ThinkParticles(Level); // [RH] make the particles think
}
// Since things will be moving, it's okay to interpolate them in the renderer.
r_NoInterpolate = false;
P_ThinkParticles(); // [RH] make the particles think
for (i = 0; i<MAXPLAYERS; i++)
if (playeringame[i])
@ -156,7 +156,7 @@ void P_Ticker (void)
if (!level.isFrozen())
{
P_UpdateSpecials (&level);
P_RunEffects (); // [RH] Run particle effects
P_RunEffects(&level); // [RH] Run particle effects
}
// for par times

View file

@ -135,9 +135,7 @@ void PolyRenderer::RenderActorView(AActor *actor, bool dontmaplines)
R_SetupFrame(Viewpoint, Viewwindow, actor);
Level = Viewpoint.ViewLevel;
P_FindParticleSubsectors();
PO_LinkToSubsectors(Level);
static bool firstcall = true;
if (firstcall)
{

View file

@ -146,6 +146,7 @@ void RenderPolyScene::RenderSectors()
void RenderPolyScene::RenderSubsector(PolyRenderThread *thread, subsector_t *sub, uint32_t subsectorDepth)
{
sector_t *frontsector = sub->sector;
auto Level = frontsector->Level;
frontsector->MoreFlags |= SECMF_DRAWN;
if (sub->polys)
@ -187,9 +188,9 @@ void RenderPolyScene::RenderSubsector(PolyRenderThread *thread, subsector_t *sub
}
int subsectorIndex = sub->Index();
for (int i = ParticlesInSubsec[subsectorIndex]; i != NO_PARTICLE; i = Particles[i].snext)
for (int i = Level->ParticlesInSubsec[subsectorIndex]; i != NO_PARTICLE; i = Level->Particles[i].snext)
{
particle_t *particle = &Particles[i];
particle_t *particle = &Level->Particles[i];
thread->TranslucentObjects.push_back(thread->FrameMemory->NewObject<PolyTranslucentParticle>(particle, sub, subsectorDepth, CurrentViewpoint->StencilValue));
}
}

View file

@ -1256,7 +1256,7 @@ DEFINE_ACTION_FUNCTION_NATIVE(AActor, GetReplacee, ZS_GetReplacee)
static void DrawSplash(AActor *self, int count, double angle, int kind)
{
P_DrawSplash(count, self->Pos(), angle, kind);
P_DrawSplash(self->Level, count, self->Pos(), angle, kind);
}
DEFINE_ACTION_FUNCTION_NATIVE(AActor, DrawSplash, DrawSplash)
@ -1265,7 +1265,7 @@ DEFINE_ACTION_FUNCTION_NATIVE(AActor, DrawSplash, DrawSplash)
PARAM_INT(count);
PARAM_FLOAT(angle);
PARAM_INT(kind);
P_DrawSplash(count, self->Pos(), angle, kind);
P_DrawSplash(self->Level, count, self->Pos(), angle, kind);
return 0;
}

View file

@ -615,9 +615,9 @@ namespace swrenderer
if ((unsigned int)(sub->Index()) < Level->subsectors.Size())
{ // Only do it for the main BSP.
int lightlevel = (floorlightlevel + ceilinglightlevel) / 2;
for (int i = ParticlesInSubsec[sub->Index()]; i != NO_PARTICLE; i = Particles[i].snext)
for (int i = frontsector->Level->ParticlesInSubsec[sub->Index()]; i != NO_PARTICLE; i = frontsector->Level->Particles[i].snext)
{
RenderParticle::Project(Thread, &Particles[i], sub->sector, lightlevel, FakeSide, foggy);
RenderParticle::Project(Thread, &frontsector->Level->Particles[i], sub->sector, lightlevel, FakeSide, foggy);
}
}

View file

@ -159,12 +159,6 @@ namespace swrenderer
this->dontmaplines = dontmaplines;
// [RH] Setup particles for this frame
P_FindParticleSubsectors();
// Link the polyobjects right before drawing the scene to reduce the amounts of calls to this function
PO_LinkToSubsectors(&level);
R_UpdateFuzzPosFrameStart();
if (r_modelscene)