diff --git a/src/gl/scene/gl_sprite.cpp b/src/gl/scene/gl_sprite.cpp index 923cb819fd..9269734b40 100644 --- a/src/gl/scene/gl_sprite.cpp +++ b/src/gl/scene/gl_sprite.cpp @@ -107,6 +107,8 @@ void gl_SetRenderStyle(FRenderStyle style, bool drawopaque, bool allowcolorblend CVAR(Bool, gl_nolayer, false, 0) +static const float LARGE_VALUE = 1e19f; + //========================================================================== // // @@ -218,30 +220,25 @@ void GLSprite::Draw(int pass) //gl_SetColor(lightlevel, rel, Colormap, trans); - unsigned int iter; - - if (lightlist) + unsigned int iter = lightlist? lightlist->Size() : 1; + bool clipping = false; + if (lightlist || topclip != LARGE_VALUE || bottomclip != -LARGE_VALUE) { - iter = lightlist->Size(); + clipping = true; gl_RenderState.EnableSplit(true); glEnable(GL_CLIP_DISTANCE3); glEnable(GL_CLIP_DISTANCE4); } - else - { - iter = 1; - } + secplane_t bottomp = { { 0, 0, -1. }, bottomclip }; + secplane_t topp = { { 0, 0, -1. }, topclip }; for (unsigned i = 0; i < iter; i++) { if (lightlist) { // set up the light slice - static secplane_t bottommost = { {0, 0, 1.}, FLT_MAX }; - static secplane_t topmost = { { 0, 0, 1. }, -FLT_MAX }; - - secplane_t *topplane = i == 0 ? &topmost : &(*lightlist)[i].plane; - secplane_t *lowplane = i == (*lightlist).Size() - 1 ? &bottommost : &(*lightlist)[i + 1].plane; + secplane_t *topplane = i == 0 ? &topp : &(*lightlist)[i].plane; + secplane_t *lowplane = i == (*lightlist).Size() - 1 ? &bottomp : &(*lightlist)[i + 1].plane; int thisll = (*lightlist)[i].caster != NULL ? gl_ClampLight(*(*lightlist)[i].p_lightlevel) : lightlevel; FColormap thiscm; @@ -255,6 +252,10 @@ void GLSprite::Draw(int pass) gl_SetColor(thisll, rel, thiscm, trans); gl_RenderState.SetSplitPlanes(*topplane, *lowplane); } + else if (clipping) + { + gl_RenderState.SetSplitPlanes(topp, bottomp); + } if (!modelframe) { @@ -330,7 +331,7 @@ void GLSprite::Draw(int pass) } } - if (lightlist) + if (clipping) { glDisable(GL_CLIP_DISTANCE3); glDisable(GL_CLIP_DISTANCE4); @@ -476,12 +477,12 @@ void GLSprite::PerformSpriteClipAdjustment(AActor *thing, const DVector2 &thingp // //========================================================================== -void GLSprite::Process(AActor* thing,sector_t * sector) +void GLSprite::Process(AActor* thing, sector_t * sector, bool thruportal) { sector_t rs; sector_t * rendersector; // don't draw the thing that's used as camera (for viewshifts during quakes!) - if (thing==GLRenderer->mViewActor || (thing == players[consoleplayer].camera && !r_showviewer)) return; + if (thing == GLRenderer->mViewActor || (thing == players[consoleplayer].camera && !r_showviewer)) return; // Don't waste time projecting sprites that are definitely not visible. if (thing == NULL || thing->sprite == 0 || !thing->IsVisibleToPlayer()) @@ -496,14 +497,14 @@ void GLSprite::Process(AActor* thing,sector_t * sector) P_CheckPlayerSprite(thing, spritenum, sprscale); } - if (thing->renderflags & RF_INVISIBLE || !thing->RenderStyle.IsVisible(thing->Alpha)) + if (thing->renderflags & RF_INVISIBLE || !thing->RenderStyle.IsVisible(thing->Alpha)) { if (!(thing->flags & MF_STEALTH) || !gl_fixedcolormap || !gl_enhanced_nightvision) - return; + return; } // If this thing is in a map section that's not in view it can't possibly be visible - if (!(currentmapsection[thing->subsector->mapsection>>3] & (1 << (thing->subsector->mapsection & 7)))) return; + if (!(currentmapsection[thing->subsector->mapsection >> 3] & (1 << (thing->subsector->mapsection & 7)))) return; // [RH] Interpolate the sprite's position to make it look smooth DVector3 thingpos = thing->InterpolatedPosition(r_TicFracF); @@ -527,10 +528,10 @@ void GLSprite::Process(AActor* thing,sector_t * sector) // don't draw first frame of a player missile if (thing->flags&MF_MISSILE) { - if (!(thing->flags7 & MF7_FLYCHEAT) && thing->target==GLRenderer->mViewActor && GLRenderer->mViewActor != NULL) + if (!(thing->flags7 & MF7_FLYCHEAT) && thing->target == GLRenderer->mViewActor && GLRenderer->mViewActor != NULL) { - double clipdist = clamp(thing->Speed, thing->target->radius, thing->target->radius*2); - if ((thingpos-ViewPos).LengthSquared() < clipdist * clipdist) return; + double clipdist = clamp(thing->Speed, thing->target->radius, thing->target->radius * 2); + if ((thingpos - ViewPos).LengthSquared() < clipdist * clipdist) return; } thing->flags7 |= MF7_FLYCHEAT; // do this only once for the very first frame, but not if it gets into range again. } @@ -541,18 +542,20 @@ void GLSprite::Process(AActor* thing,sector_t * sector) if (clipres == GLPortal::PClip_InFront) return; } - player_t *player=&players[consoleplayer]; + player_t *player = &players[consoleplayer]; FloatRect r; - if (sector->sectornum!=thing->Sector->sectornum) + if (sector->sectornum != thing->Sector->sectornum && !thruportal) { - rendersector=gl_FakeFlat(thing->Sector, &rs, false); + rendersector = gl_FakeFlat(thing->Sector, &rs, false); } else { - rendersector=sector; + rendersector = sector; } - + topclip = rendersector->PortalBlocksMovement(sector_t::ceiling) ? LARGE_VALUE : rendersector->SkyBoxes[sector_t::ceiling]->specialf1; + bottomclip = rendersector->PortalBlocksMovement(sector_t::floor) ? -LARGE_VALUE : rendersector->SkyBoxes[sector_t::floor]->specialf1; + x = thingpos.X; z = thingpos.Z - thing->Floorclip; @@ -892,6 +895,8 @@ void GLSprite::ProcessParticle (particle_t *particle, sector_t *sector)//, int s modelframe=NULL; gltexture=NULL; + topclip = LARGE_VALUE; + bottomclip = -LARGE_VALUE; // [BB] Load the texture for round or smooth particles if (gl_particles_style) diff --git a/src/gl/scene/gl_wall.h b/src/gl/scene/gl_wall.h index 890ba980da..637737971d 100644 --- a/src/gl/scene/gl_wall.h +++ b/src/gl/scene/gl_wall.h @@ -334,6 +334,9 @@ public: int index; int depth; + float topclip; + float bottomclip; + float x,y,z; // needed for sorting! float ul,ur; @@ -354,7 +357,7 @@ public: void Draw(int pass); void PutSprite(bool translucent); - void Process(AActor* thing,sector_t * sector); + void Process(AActor* thing,sector_t * sector, bool thruportal = false); void ProcessParticle (particle_t *particle, sector_t *sector);//, int shade, int fakeside) void SetThingColor(PalEntry);