- GLSprite rework.

This commit is contained in:
Christoph Oelckers 2018-04-28 20:02:17 +02:00
parent 6d308ca67e
commit d1720ad790
9 changed files with 166 additions and 165 deletions

View file

@ -363,9 +363,12 @@ void GLSceneDrawer::RenderThings(subsector_t * sub, sector_t * sector)
continue;
}
}
GLSprite sprite(this);
sprite.Process(thing, sector, false);
// If this thing is in a map section that's not in view it can't possibly be visible
if (CurrentMapSections[thing->subsector->mapsection])
{
GLSprite sprite;
sprite.Process(gl_drawinfo, thing, sector, in_area, false);
}
}
for (msecnode_t *node = sec->sectorportal_thinglist; node; node = node->m_snext)
@ -382,8 +385,8 @@ void GLSceneDrawer::RenderThings(subsector_t * sub, sector_t * sector)
}
}
GLSprite sprite(this);
sprite.Process(thing, sector, true);
GLSprite sprite;
sprite.Process(gl_drawinfo, thing, sector, gl_drawinfo->mDrawer->in_area, true);
}
SetupSprite.Unclock();
}
@ -455,8 +458,8 @@ void GLSceneDrawer::DoSubsector(subsector_t * sub)
for (i = ParticlesInSubsec[sub->Index()]; i != NO_PARTICLE; i = Particles[i].snext)
{
GLSprite sprite(this);
sprite.ProcessParticle(&Particles[i], fakesector);
GLSprite sprite;
sprite.ProcessParticle(gl_drawinfo, &Particles[i], fakesector);
}
SetupSprite.Unclock();
}

View file

@ -94,27 +94,6 @@ void GLDrawList::Reset()
drawitems.Clear();
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Translucent polygon sorting - uses a BSP algorithm with an additional 'equal' branch
inline double GLSprite::CalcIntersectionVertex(GLWall * w2)
{
float ax = x1, ay=y1;
float bx = x2, by=y2;
float cx = w2->glseg.x1, cy=w2->glseg.y1;
float dx = w2->glseg.x2, dy=w2->glseg.y2;
return ((ay-cy)*(dx-cx)-(ax-cx)*(dy-cy)) / ((bx-ax)*(dy-cy)-(by-ay)*(dx-cx));
}
//==========================================================================
//
//
@ -404,7 +383,6 @@ void GLDrawList::SortSpriteIntoPlane(SortNode * head, SortNode * sort)
}
}
//==========================================================================
//
//
@ -412,6 +390,16 @@ void GLDrawList::SortSpriteIntoPlane(SortNode * head, SortNode * sort)
//==========================================================================
#define MIN_EQ (0.0005f)
// Lines start-end and fdiv must intersect.
inline double CalcIntersectionVertex(GLWall *w1, GLWall * w2)
{
float ax = w1->glseg.x1, ay = w1->glseg.y1;
float bx = w1->glseg.x2, by = w1->glseg.y2;
float cx = w2->glseg.x1, cy = w2->glseg.y1;
float dx = w2->glseg.x2, dy = w2->glseg.y2;
return ((ay - cy)*(dx - cx) - (ax - cx)*(dy - cy)) / ((bx - ax)*(dy - cy) - (by - ay)*(dx - cx));
}
void GLDrawList::SortWallIntoWall(SortNode * head,SortNode * sort)
{
GLWall * wh= walls[drawitems[head->itemindex].index];
@ -444,7 +432,7 @@ void GLDrawList::SortWallIntoWall(SortNode * head,SortNode * sort)
}
else
{
double r=ws->CalcIntersectionVertex(wh);
double r = CalcIntersectionVertex(ws, wh);
float ix=(float)(ws->glseg.x1+r*(ws->glseg.x2-ws->glseg.x1));
float iy=(float)(ws->glseg.y1+r*(ws->glseg.y2-ws->glseg.y1));
@ -492,6 +480,19 @@ EXTERN_CVAR(Int, gl_billboard_mode)
EXTERN_CVAR(Bool, gl_billboard_faces_camera)
EXTERN_CVAR(Bool, gl_billboard_particles)
inline double CalcIntersectionVertex(GLSprite *s, GLWall * w2)
{
float ax = s->x1, ay = s->y1;
float bx = s->x2, by = s->y2;
float cx = w2->glseg.x1, cy = w2->glseg.y1;
float dx = w2->glseg.x2, dy = w2->glseg.y2;
return ((ay - cy)*(dx - cx) - (ax - cx)*(dy - cy)) / ((bx - ax)*(dy - cy) - (by - ay)*(dx - cx));
}
void GLDrawList::SortSpriteIntoWall(SortNode * head,SortNode * sort)
{
GLWall *wh= walls[drawitems[head->itemindex].index];
@ -542,7 +543,7 @@ void GLDrawList::SortSpriteIntoWall(SortNode * head,SortNode * sort)
}
return;
}
double r=ss->CalcIntersectionVertex(wh);
double r=CalcIntersectionVertex(ss, wh);
float ix=(float)(ss->x1 + r * (ss->x2-ss->x1));
float iy=(float)(ss->y1 + r * (ss->y2-ss->y1));
@ -726,7 +727,7 @@ void GLDrawList::DoDraw(int pass, int i, bool trans)
{
GLSprite * s= sprites[drawitems[i].index];
RenderSprite.Clock();
s->Draw(pass);
gl_drawinfo->DrawSprite(s, pass);
RenderSprite.Unclock();
}
break;

View file

@ -165,10 +165,8 @@ public:
struct FDrawInfo : public HWDrawInfo
{
GLSceneDrawer *mDrawer;
FDrawInfo * next;
GLDrawList drawlists[GLDL_TYPES];
TArray<GLDecal *> decals[2]; // the second slot is for mirrors which get rendered in a separate pass.
@ -182,8 +180,8 @@ struct FDrawInfo : public HWDrawInfo
GLDecal *AddDecal(bool onmirror) override;
void AddPortal(GLWall *w, int portaltype) override;
void AddFlat(GLFlat *flat, bool fog) override;
void AddSprite(GLSprite *sprite, bool translucent) override;
void ProcessActorsInPortal(FLinePortalSpan *glport) override;
std::pair<FFlatVertex *, unsigned int> AllocVertices(unsigned int count) override;
// Legacy GL only.
@ -222,6 +220,8 @@ struct FDrawInfo : public HWDrawInfo
void DrawSubsector(GLFlat *flat, subsector_t * sub);
void SetupSubsectorLights(GLFlat *flat, int pass, subsector_t * sub, int *dli);
// Sprite drawer
void DrawSprite(GLSprite *sprite, int pass);
// These two may be moved to the API independent part of the renderer later.
void ProcessLowerMinisegs(TArray<seg_t *> &lowersegs) override;

View file

@ -1060,7 +1060,7 @@ void GLLineToLinePortal::DrawContents()
void GLLineToLinePortal::RenderAttached()
{
gl_drawinfo->ProcessActorsInPortal(glport);
gl_drawinfo->ProcessActorsInPortal(glport, gl_drawinfo->mDrawer->in_area);
}
//-----------------------------------------------------------------------------

View file

@ -73,14 +73,6 @@ extern TArray<spritedef_t> sprites;
extern TArray<spriteframe_t> SpriteFrames;
extern uint32_t r_renderercaps;
enum HWRenderStyle
{
STYLEHW_Normal, // default
STYLEHW_Solid, // drawn solid (needs special treatment for sprites)
STYLEHW_NoAlphaTest, // disable alpha test
};
void gl_SetRenderStyle(FRenderStyle style, bool drawopaque, bool allowcolorblending)
{
int tm, sb, db, be;
@ -102,7 +94,7 @@ static const float LARGE_VALUE = 1e19f;
//
//==========================================================================
void GLSprite::CalculateVertices(FVector3 *v)
bool GLSprite::CalculateVertices(FVector3 *v)
{
if (actor != nullptr && (actor->renderflags & RF_SPRITETYPEMASK) == RF_FLATSPRITE)
{
@ -140,14 +132,12 @@ void GLSprite::CalculateVertices(FVector3 *v)
v[2] = mat * FVector3(x2, z, y1);
v[3] = mat * FVector3(x1, z, y1);
glEnable(GL_POLYGON_OFFSET_FILL);
glPolygonOffset(-1.0f, -128.0f);
return;
return true;
}
// [BB] Billboard stuff
const bool drawWithXYBillboard = ((particle && gl_billboard_particles) || (!(actor && actor->renderflags & RF_FORCEYBILLBOARD)
//&& GLRenderer->mViewActor != NULL
//&& GLRenderer->mViewActor != nullptr
&& (gl_billboard_mode == 1 || (actor && actor->renderflags & RF_FORCEXYBILLBOARD))));
const bool drawBillboardFacingCamera = gl_billboard_faces_camera;
@ -243,6 +233,7 @@ void GLSprite::CalculateVertices(FVector3 *v)
v[2] = FVector3(x1, z2, y1);
v[3] = FVector3(x2, z2, y2);
}
return false;
}
//==========================================================================
@ -251,21 +242,22 @@ void GLSprite::CalculateVertices(FVector3 *v)
//
//==========================================================================
void GLSprite::Draw(int pass)
void FDrawInfo::DrawSprite(GLSprite *sprite, int pass)
{
if (pass == GLPASS_DECALS) return;
auto RenderStyle = sprite->RenderStyle;
if (pass == GLPASS_LIGHTSONLY)
{
if (modelframe)
if (sprite->modelframe)
{
if (RenderStyle.BlendOp != STYLEOP_Shadow)
{
if (gl_lights && GLRenderer->mLightCount && mDrawer->FixedColormap == CM_DEFAULT && !fullbright)
if (gl_lights && GLRenderer->mLightCount && mDrawer->FixedColormap == CM_DEFAULT && !sprite->fullbright)
{
if (!particle)
if (!sprite->particle)
{
dynlightindex = gl_SetDynModelLight(gl_light_sprites ? actor : nullptr, -1);
sprite->dynlightindex = gl_SetDynModelLight(gl_light_sprites ? sprite->actor : nullptr, -1);
}
}
}
@ -275,7 +267,7 @@ void GLSprite::Draw(int pass)
bool additivefog = false;
bool foglayer = false;
int rel = fullbright? 0 : getExtraLight();
int rel = sprite->fullbright? 0 : getExtraLight();
if (pass==GLPASS_TRANSLUCENT)
{
@ -289,10 +281,10 @@ void GLSprite::Draw(int pass)
gl_SetRenderStyle(RenderStyle, false,
// The rest of the needed checks are done inside gl_SetRenderStyle
trans > 1.f - FLT_EPSILON && gl_usecolorblending && mDrawer->FixedColormap == CM_DEFAULT && actor &&
fullbright && gltexture && !gltexture->tex->GetTranslucency());
sprite->trans > 1.f - FLT_EPSILON && gl_usecolorblending && mDrawer->FixedColormap == CM_DEFAULT && sprite->actor &&
sprite->fullbright && sprite->gltexture && !sprite->gltexture->tex->GetTranslucency());
if (hw_styleflags == STYLEHW_NoAlphaTest)
if (sprite->hw_styleflags == STYLEHW_NoAlphaTest)
{
gl_RenderState.AlphaFunc(GL_GEQUAL, 0.f);
}
@ -307,10 +299,10 @@ void GLSprite::Draw(int pass)
float minalpha=0.1f;
// fog + fuzz don't work well without some fiddling with the alpha value!
if (!Colormap.FadeColor.isBlack())
if (!sprite->Colormap.FadeColor.isBlack())
{
float dist=Dist2(r_viewpoint.Pos.X, r_viewpoint.Pos.Y, x,y);
int fogd = hw_GetFogDensity(lightlevel, Colormap.FadeColor, Colormap.FogDensity);
float dist=Dist2(r_viewpoint.Pos.X, r_viewpoint.Pos.Y, sprite->x, sprite->y);
int fogd = hw_GetFogDensity(sprite->lightlevel, sprite->Colormap.FadeColor, sprite->Colormap.FogDensity);
// this value was determined by trial and error and is scale dependent!
float factor = 0.05f + exp(-fogd*dist / 62500.f);
@ -319,16 +311,16 @@ void GLSprite::Draw(int pass)
}
gl_RenderState.AlphaFunc(GL_GEQUAL, gl_mask_sprite_threshold);
gl_RenderState.SetColor(0.2f,0.2f,0.2f,fuzzalpha, Colormap.Desaturation);
gl_RenderState.SetColor(0.2f,0.2f,0.2f,fuzzalpha, sprite->Colormap.Desaturation);
additivefog = true;
lightlist = nullptr; // the fuzz effect does not use the sector's light level so splitting is not needed.
sprite->lightlist = nullptr; // the fuzz effect does not use the sector's light level so splitting is not needed.
}
else if (RenderStyle.BlendOp == STYLEOP_Add && RenderStyle.DestAlpha == STYLEALPHA_One)
{
additivefog = true;
}
}
else if (modelframe == nullptr)
else if (sprite->modelframe == nullptr)
{
int tm, sb, db, be;
@ -341,40 +333,40 @@ void GLSprite::Draw(int pass)
}
if (RenderStyle.BlendOp != STYLEOP_Shadow)
{
if (gl_lights && GLRenderer->mLightCount && mDrawer->FixedColormap == CM_DEFAULT && !fullbright)
if (gl_lights && GLRenderer->mLightCount && mDrawer->FixedColormap == CM_DEFAULT && !sprite->fullbright)
{
if (modelframe && !particle)
dynlightindex = gl_SetDynModelLight(gl_light_sprites ? actor : NULL, dynlightindex);
if (sprite->modelframe && !sprite->particle)
sprite->dynlightindex = gl_SetDynModelLight(gl_light_sprites ? sprite->actor : nullptr, sprite->dynlightindex);
else
gl_SetDynSpriteLight(gl_light_sprites ? actor : NULL, gl_light_particles ? particle : NULL);
gl_SetDynSpriteLight(gl_light_sprites ? sprite->actor : nullptr, gl_light_particles ? sprite->particle : nullptr);
}
sector_t *cursec = actor ? actor->Sector : particle ? particle->subsector->sector : nullptr;
sector_t *cursec = sprite->actor ? sprite->actor->Sector : sprite->particle ? sprite->particle->subsector->sector : nullptr;
if (cursec != nullptr)
{
const PalEntry finalcol = fullbright
? ThingColor
: ThingColor.Modulate(cursec->SpecialColors[sector_t::sprites]);
const PalEntry finalcol = sprite->fullbright
? sprite->ThingColor
: sprite->ThingColor.Modulate(cursec->SpecialColors[sector_t::sprites]);
gl_RenderState.SetObjectColor(finalcol);
}
mDrawer->SetColor(lightlevel, rel, Colormap, trans);
mDrawer->SetColor(sprite->lightlevel, rel, sprite->Colormap, sprite->trans);
}
if (Colormap.FadeColor.isBlack()) foglevel=lightlevel;
if (sprite->Colormap.FadeColor.isBlack()) sprite->foglevel = sprite->lightlevel;
if (RenderStyle.Flags & STYLEF_FadeToBlack)
{
Colormap.FadeColor=0;
sprite->Colormap.FadeColor=0;
additivefog = true;
}
if (RenderStyle.BlendOp == STYLEOP_RevSub || RenderStyle.BlendOp == STYLEOP_Sub)
{
if (!modelframe)
if (!sprite->modelframe)
{
// non-black fog with subtractive style needs special treatment
if (!Colormap.FadeColor.isBlack())
if (!sprite->Colormap.FadeColor.isBlack())
{
foglayer = true;
// Due to the two-layer approach we need to force an alpha test that lets everything pass
@ -384,28 +376,29 @@ void GLSprite::Draw(int pass)
else RenderStyle.BlendOp = STYLEOP_Fuzz; // subtractive with models is not going to work.
}
if (!foglayer) mDrawer->SetFog(foglevel, rel, &Colormap, additivefog);
if (!foglayer) mDrawer->SetFog(sprite->foglevel, rel, &sprite->Colormap, additivefog);
else
{
gl_RenderState.EnableFog(false);
gl_RenderState.SetFog(0, 0);
}
if (gltexture) gl_RenderState.SetMaterial(gltexture, CLAMP_XY, translation, OverrideShader, !!(RenderStyle.Flags & STYLEF_RedIsAlpha));
else if (!modelframe) gl_RenderState.EnableTexture(false);
if (sprite->gltexture) gl_RenderState.SetMaterial(sprite->gltexture, CLAMP_XY, sprite->translation, sprite->OverrideShader, !!(RenderStyle.Flags & STYLEF_RedIsAlpha));
else if (!sprite->modelframe) gl_RenderState.EnableTexture(false);
//mDrawer->SetColor(lightlevel, rel, Colormap, trans);
unsigned int iter = lightlist? lightlist->Size() : 1;
unsigned int iter = sprite->lightlist? sprite->lightlist->Size() : 1;
bool clipping = false;
if (lightlist || topclip != LARGE_VALUE || bottomclip != -LARGE_VALUE)
auto lightlist = sprite->lightlist;
if (lightlist || sprite->topclip != LARGE_VALUE || sprite->bottomclip != -LARGE_VALUE)
{
clipping = true;
gl_RenderState.EnableSplit(true);
}
secplane_t bottomp = { { 0, 0, -1. }, bottomclip };
secplane_t topp = { { 0, 0, -1. }, topclip };
secplane_t bottomp = { { 0, 0, -1. }, sprite->bottomclip };
secplane_t topp = { { 0, 0, -1. }, sprite->topclip };
for (unsigned i = 0; i < iter; i++)
{
if (lightlist)
@ -414,18 +407,18 @@ void GLSprite::Draw(int pass)
secplane_t *topplane = i == 0 ? &topp : &(*lightlist)[i].plane;
secplane_t *lowplane = i == (*lightlist).Size() - 1 ? &bottomp : &(*lightlist)[i + 1].plane;
int thislight = (*lightlist)[i].caster != NULL ? hw_ClampLight(*(*lightlist)[i].p_lightlevel) : lightlevel;
int thisll = actor == nullptr? thislight : (uint8_t)actor->Sector->CheckSpriteGlow(thislight, actor->InterpolatedPosition(r_viewpoint.TicFrac));
int thislight = (*lightlist)[i].caster != nullptr ? hw_ClampLight(*(*lightlist)[i].p_lightlevel) : sprite->lightlevel;
int thisll = sprite->actor == nullptr? thislight : (uint8_t)sprite->actor->Sector->CheckSpriteGlow(thislight, sprite->actor->InterpolatedPosition(r_viewpoint.TicFrac));
FColormap thiscm;
thiscm.CopyFog(Colormap);
thiscm.CopyFog(sprite->Colormap);
thiscm.CopyFrom3DLight(&(*lightlist)[i]);
if (level.flags3 & LEVEL3_NOCOLOREDSPRITELIGHTING)
{
thiscm.Decolorize();
}
mDrawer->SetColor(thisll, rel, thiscm, trans);
mDrawer->SetColor(thisll, rel, thiscm, sprite->trans);
if (!foglayer)
{
mDrawer->SetFog(thislight, rel, &thiscm, additivefog);
@ -437,25 +430,29 @@ void GLSprite::Draw(int pass)
gl_RenderState.SetSplitPlanes(topp, bottomp);
}
if (!modelframe)
if (!sprite->modelframe)
{
gl_RenderState.Apply();
FVector3 v[4];
gl_RenderState.SetNormal(0, 0, 0);
CalculateVertices(v);
if (sprite->CalculateVertices(v))
{
glEnable(GL_POLYGON_OFFSET_FILL);
glPolygonOffset(-1.0f, -128.0f);
}
FQuadDrawer qd;
qd.Set(0, v[0][0], v[0][1], v[0][2], ul, vt);
qd.Set(1, v[1][0], v[1][1], v[1][2], ur, vt);
qd.Set(2, v[2][0], v[2][1], v[2][2], ul, vb);
qd.Set(3, v[3][0], v[3][1], v[3][2], ur, vb);
qd.Set(0, v[0][0], v[0][1], v[0][2], sprite->ul, sprite->vt);
qd.Set(1, v[1][0], v[1][1], v[1][2], sprite->ur, sprite->vt);
qd.Set(2, v[2][0], v[2][1], v[2][2], sprite->ul, sprite->vb);
qd.Set(3, v[3][0], v[3][1], v[3][2], sprite->ur, sprite->vb);
qd.Render(GL_TRIANGLE_STRIP);
if (foglayer)
{
// If we get here we know that we have colored fog and no fixed colormap.
mDrawer->SetFog(foglevel, rel, &Colormap, additivefog);
mDrawer->SetFog(sprite->foglevel, rel, &sprite->Colormap, additivefog);
gl_RenderState.SetFixedColormap(CM_FOGLAYER);
gl_RenderState.BlendEquation(GL_FUNC_ADD);
gl_RenderState.BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
@ -466,7 +463,7 @@ void GLSprite::Draw(int pass)
}
else
{
gl_RenderModel(this, dynlightindex);
gl_RenderModel(sprite, sprite->dynlightindex);
}
}
@ -481,13 +478,13 @@ void GLSprite::Draw(int pass)
gl_RenderState.BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
gl_RenderState.BlendEquation(GL_FUNC_ADD);
gl_RenderState.SetTextureMode(TM_MODULATE);
if (actor != nullptr && (actor->renderflags & RF_SPRITETYPEMASK) == RF_FLATSPRITE)
if (sprite->actor != nullptr && (sprite->actor->renderflags & RF_SPRITETYPEMASK) == RF_FLATSPRITE)
{
glPolygonOffset(0.0f, 0.0f);
glDisable(GL_POLYGON_OFFSET_FILL);
}
}
else if (modelframe == nullptr)
else if (sprite->modelframe == nullptr)
{
glPolygonOffset(0.0f, 0.0f);
glDisable(GL_POLYGON_OFFSET_FILL);
@ -504,11 +501,11 @@ void GLSprite::Draw(int pass)
//
//
//==========================================================================
inline void GLSprite::PutSprite(bool translucent)
void FDrawInfo::AddSprite(GLSprite *sprite, bool translucent)
{
int list;
// [BB] Allow models to be drawn in the GLDL_TRANSLUCENT pass.
if (translucent || actor == nullptr || (!modelframe && (actor->renderflags & RF_SPRITETYPEMASK) != RF_WALLSPRITE))
if (translucent || sprite->actor == nullptr || (!sprite->modelframe && (sprite->actor->renderflags & RF_SPRITETYPEMASK) != RF_WALLSPRITE))
{
list = GLDL_TRANSLUCENT;
}
@ -516,9 +513,9 @@ inline void GLSprite::PutSprite(bool translucent)
{
list = GLDL_MODELS;
}
dynlightindex = -1;
sprite->dynlightindex = -1;
auto newsprt = gl_drawinfo->drawlists[list].NewSprite();
*newsprt = *this;
*newsprt = *sprite;
}
//==========================================================================
@ -526,9 +523,21 @@ inline void GLSprite::PutSprite(bool translucent)
//
//
//==========================================================================
void GLSprite::SplitSprite(sector_t * frontsector, bool translucent)
inline void GLSprite::PutSprite(HWDrawInfo *di, bool translucent)
{
GLSprite copySprite(mDrawer);
di->AddSprite(this, translucent);
}
//==========================================================================
//
//
//
//==========================================================================
void GLSprite::SplitSprite(HWDrawInfo *di, sector_t * frontsector, bool translucent)
{
GLSprite copySprite;
double lightbottom;
unsigned int i;
bool put=false;
@ -536,7 +545,7 @@ void GLSprite::SplitSprite(sector_t * frontsector, bool translucent)
for(i=0;i<lightlist.Size();i++)
{
// Particles don't go through here so we can safely assume that actor is not NULL
// Particles don't go through here so we can safely assume that actor is not nullptr
if (i<lightlist.Size()-1) lightbottom=lightlist[i+1].plane.ZatPoint(actor);
else lightbottom=frontsector->floorplane.ZatPoint(actor);
@ -563,7 +572,7 @@ void GLSprite::SplitSprite(sector_t * frontsector, bool translucent)
z1=copySprite.z2=lightbottom;
vt=copySprite.vb=copySprite.vt+
(lightbottom-copySprite.z1)*(copySprite.vb-copySprite.vt)/(z2-copySprite.z1);
copySprite.PutSprite(translucent);
copySprite.PutSprite(di, translucent);
put=true;
}
}
@ -675,7 +684,7 @@ void GLSprite::PerformSpriteClipAdjustment(AActor *thing, const DVector2 &thingp
//
//==========================================================================
void GLSprite::Process(AActor* thing, sector_t * sector, int thruportal)
void GLSprite::Process(HWDrawInfo *di, AActor* thing, sector_t * sector, area_t in_area, int thruportal)
{
sector_t rs;
sector_t * rendersector;
@ -696,7 +705,7 @@ void GLSprite::Process(AActor* thing, sector_t * sector, int thruportal)
if (thing->renderflags & RF_INVISIBLE || !thing->RenderStyle.IsVisible(thing->Alpha))
{
if (!(thing->flags & MF_STEALTH) || !mDrawer->FixedColormap || !gl_enhanced_nightvision || thing == camera)
if (!(thing->flags & MF_STEALTH) || !di->FixedColormap || !gl_enhanced_nightvision || thing == camera)
return;
}
@ -708,14 +717,11 @@ void GLSprite::Process(AActor* thing, sector_t * sector, int thruportal)
int spritenum = thing->sprite;
DVector2 sprscale = thing->Scale;
if (thing->player != NULL)
if (thing->player != nullptr)
{
P_CheckPlayerSprite(thing, spritenum, sprscale);
}
// If this thing is in a map section that's not in view it can't possibly be visible
if (!thruportal && !mDrawer->CurrentMapSections[thing->subsector->mapsection]) return;
// [RH] Interpolate the sprite's position to make it look smooth
DVector3 thingpos = thing->InterpolatedPosition(r_viewpoint.TicFrac);
if (thruportal == 1) thingpos += level.Displacements.getOffset(thing->Sector->PortalGroup, sector->PortalGroup);
@ -752,7 +758,7 @@ void GLSprite::Process(AActor* thing, sector_t * sector, int thruportal)
// 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 != nullptr)
{
double speed = thing->Vel.Length();
if (speed >= thing->target->radius / 2)
@ -780,7 +786,7 @@ void GLSprite::Process(AActor* thing, sector_t * sector, int thruportal)
if (sector->sectornum != thing->Sector->sectornum && !thruportal)
{
rendersector = hw_FakeFlat(thing->Sector, &rs, mDrawer->in_area, false);
rendersector = hw_FakeFlat(thing->Sector, &rs, in_area, false);
}
else
{
@ -921,7 +927,7 @@ void GLSprite::Process(AActor* thing, sector_t * sector, int thruportal)
x1 = x2 = x;
y1 = y2 = y;
z1 = z2 = z;
gltexture = NULL;
gltexture = nullptr;
}
depth = FloatToFixed((x - r_viewpoint.Pos.X) * r_viewpoint.TanCos + (y - r_viewpoint.Pos.Y) * r_viewpoint.TanSin);
@ -947,16 +953,16 @@ void GLSprite::Process(AActor* thing, sector_t * sector, int thruportal)
RenderStyle = thing->RenderStyle;
// colormap stuff is a little more complicated here...
if (mDrawer->FixedColormap)
if (di->FixedColormap)
{
if ((gl_enhanced_nv_stealth > 0 && mDrawer->FixedColormap == CM_LITE) // Infrared powerup only
|| (gl_enhanced_nv_stealth == 2 && mDrawer->FixedColormap >= CM_TORCH)// Also torches
if ((gl_enhanced_nv_stealth > 0 && di->FixedColormap == CM_LITE) // Infrared powerup only
|| (gl_enhanced_nv_stealth == 2 && di->FixedColormap >= CM_TORCH)// Also torches
|| (gl_enhanced_nv_stealth == 3)) // Any fixed colormap
enhancedvision = true;
Colormap.Clear();
if (mDrawer->FixedColormap == CM_LITE)
if (di->FixedColormap == CM_LITE)
{
if (gl_enhanced_nightvision &&
(thing->IsKindOf(RUNTIME_CLASS(AInventory)) || thing->flags3&MF3_ISMONSTER || thing->flags&MF_MISSILE || thing->flags&MF_CORPSE))
@ -970,7 +976,7 @@ void GLSprite::Process(AActor* thing, sector_t * sector, int thruportal)
Colormap = rendersector->Colormap;
if (fullbright)
{
if (rendersector == &level.sectors[rendersector->sectornum] || mDrawer->in_area != area_below)
if (rendersector == &level.sectors[rendersector->sectornum] || in_area != area_below)
// under water areas keep their color for fullbright objects
{
// Only make the light white but keep everything else (fog, desaturation and Boom colormap.)
@ -1088,7 +1094,7 @@ void GLSprite::Process(AActor* thing, sector_t * sector, int thruportal)
actor = thing;
index = GLRenderer->gl_spriteindex++;
particle = NULL;
particle = nullptr;
const bool drawWithXYBillboard = (!(actor->renderflags & RF_FORCEYBILLBOARD)
&& (actor->renderflags & RF_SPRITETYPEMASK) == RF_FACESPRITE
@ -1102,15 +1108,15 @@ void GLSprite::Process(AActor* thing, sector_t * sector, int thruportal)
// 3. any bright object
// 4. any with render style shadow (which doesn't use the sector light)
// 5. anything with render style reverse subtract (light effect is not what would be desired here)
if (thing->Sector->e->XFloor.lightlist.Size() != 0 && mDrawer->FixedColormap == CM_DEFAULT && !fullbright &&
if (thing->Sector->e->XFloor.lightlist.Size() != 0 && di->FixedColormap == CM_DEFAULT && !fullbright &&
RenderStyle.BlendOp != STYLEOP_Shadow && RenderStyle.BlendOp != STYLEOP_RevSub)
{
if (gl.flags & RFL_NO_CLIP_PLANES) // on old hardware we are rather limited...
{
lightlist = NULL;
lightlist = nullptr;
if (!drawWithXYBillboard && !modelframe)
{
SplitSprite(thing->Sector, hw_styleflags != STYLEHW_Solid);
SplitSprite(di, thing->Sector, hw_styleflags != STYLEHW_Solid);
}
}
else
@ -1120,10 +1126,10 @@ void GLSprite::Process(AActor* thing, sector_t * sector, int thruportal)
}
else
{
lightlist = NULL;
lightlist = nullptr;
}
PutSprite(hw_styleflags != STYLEHW_Solid);
PutSprite(di, hw_styleflags != STYLEHW_Solid);
rendered_sprites++;
}
@ -1134,7 +1140,7 @@ void GLSprite::Process(AActor* thing, sector_t * sector, int thruportal)
//
//==========================================================================
void GLSprite::ProcessParticle (particle_t *particle, sector_t *sector)//, int shade, int fakeside)
void GLSprite::ProcessParticle (HWDrawInfo *di, particle_t *particle, sector_t *sector)//, int shade, int fakeside)
{
if (GLRenderer->mClipPortal)
{
@ -1150,7 +1156,7 @@ void GLSprite::ProcessParticle (particle_t *particle, sector_t *sector)//, int s
sector->GetCeilingLight() : sector->GetFloorLight());
foglevel = (uint8_t)clamp<short>(sector->lightlevel, 0, 255);
if (mDrawer->FixedColormap)
if (di->FixedColormap)
{
Colormap.Clear();
}
@ -1191,8 +1197,8 @@ void GLSprite::ProcessParticle (particle_t *particle, sector_t *sector)//, int s
ThingColor = particle->color;
ThingColor.a = 255;
modelframe=NULL;
gltexture=NULL;
modelframe=nullptr;
gltexture=nullptr;
topclip = LARGE_VALUE;
bottomclip = -LARGE_VALUE;
@ -1253,7 +1259,7 @@ void GLSprite::ProcessParticle (particle_t *particle, sector_t *sector)//, int s
depth = FloatToFixed((x - r_viewpoint.Pos.X) * r_viewpoint.TanCos + (y - r_viewpoint.Pos.Y) * r_viewpoint.TanSin);
actor=NULL;
actor=nullptr;
this->particle=particle;
fullbright = !!particle->bright;
@ -1261,12 +1267,12 @@ void GLSprite::ProcessParticle (particle_t *particle, sector_t *sector)//, int s
if (gl_particles_style != 2 && trans>=1.0f-FLT_EPSILON) hw_styleflags = STYLEHW_Solid;
else hw_styleflags = STYLEHW_NoAlphaTest;
if (sector->e->XFloor.lightlist.Size() != 0 && mDrawer->FixedColormap == CM_DEFAULT && !fullbright)
if (sector->e->XFloor.lightlist.Size() != 0 && di->FixedColormap == CM_DEFAULT && !fullbright)
lightlist = &sector->e->XFloor.lightlist;
else
lightlist = NULL;
lightlist = nullptr;
PutSprite(hw_styleflags != STYLEHW_Solid);
PutSprite(di, hw_styleflags != STYLEHW_Solid);
rendered_sprites++;
}
@ -1276,7 +1282,7 @@ void GLSprite::ProcessParticle (particle_t *particle, sector_t *sector)//, int s
//
//==========================================================================
void FDrawInfo::ProcessActorsInPortal(FLinePortalSpan *glport)
void HWDrawInfo::ProcessActorsInPortal(FLinePortalSpan *glport, area_t in_area)
{
TMap<AActor*, bool> processcheck;
if (glport->validcount == validcount) return; // only process once per frame
@ -1318,8 +1324,8 @@ void FDrawInfo::ProcessActorsInPortal(FLinePortalSpan *glport)
th->SetXYZ(newpos);
th->Prev += newpos - savedpos;
GLSprite spr(mDrawer);
spr.Process(th, hw_FakeFlat(th->Sector, &fakesector, mDrawer->in_area, false), 2);
GLSprite spr;
spr.Process(this, th, hw_FakeFlat(th->Sector, &fakesector, in_area, false), in_area, 2);
th->Angles.Yaw = savedangle;
th->SetXYZ(savedpos);
th->Prev -= newpos - savedpos;

View file

@ -30,6 +30,7 @@ struct FFlatVertex;
struct FLinePortalSpan;
class GLSceneDrawer;
struct FDynLightData;
enum area_t : int;
struct FDrawInfo;
struct HWDrawInfo;
@ -47,7 +48,6 @@ public:
friend struct GLDrawList;
friend void Mod_RenderModel(GLSprite * spr, model_t * mdl, int framenumber);
GLSceneDrawer *mDrawer;
int lightlevel;
uint8_t foglevel;
uint8_t hw_styleflags;
@ -81,25 +81,16 @@ public:
int dynlightindex;
void SplitSprite(sector_t * frontsector, bool translucent);
void SetLowerParam();
void SplitSprite(HWDrawInfo *di, sector_t * frontsector, bool translucent);
void PerformSpriteClipAdjustment(AActor *thing, const DVector2 &thingpos, float spriteheight);
void CalculateVertices(FVector3 *v);
bool CalculateVertices(FVector3 *v);
public:
GLSprite(GLSceneDrawer *drawer)
{
mDrawer = drawer;
}
void Draw(int pass);
void PutSprite(bool translucent);
void Process(AActor* thing,sector_t * sector, int thruportal = false);
void ProcessParticle (particle_t *particle, sector_t *sector);//, int shade, int fakeside)
void SetThingColor(PalEntry);
// Lines start-end and fdiv must intersect.
double CalcIntersectionVertex(GLWall * w2);
GLSprite() {}
void PutSprite(HWDrawInfo *di, bool translucent);
void Process(HWDrawInfo *di, AActor* thing,sector_t * sector, area_t in_area, int thruportal = false);
void ProcessParticle (HWDrawInfo *di, particle_t *particle, sector_t *sector);//, int shade, int fakeside)
GLSprite(const GLSprite &other)
{

View file

@ -455,7 +455,7 @@ void FDrawInfo::AddPortal(GLWall *wall, int ptype)
line_t *otherside = wall->lineportal->lines[0]->mDestination;
if (otherside != NULL && otherside->portalindex < level.linePortals.Size())
{
ProcessActorsInPortal(otherside->getPortal()->mGroup);
ProcessActorsInPortal(otherside->getPortal()->mGroup, mDrawer->in_area);
}
portal = new GLLineToLinePortal(wall->lineportal);
}

View file

@ -7,6 +7,7 @@ struct FLinePortalSpan;
struct FFlatVertex;
class GLWall;
class GLFlat;
class GLSprite;
struct GLDecal;
//==========================================================================
@ -118,6 +119,8 @@ public:
void AddCeilingStack(sector_t * sec);
void ProcessSectorStacks(area_t in_area);
void ProcessActorsInPortal(FLinePortalSpan *glport, area_t in_area);
void AddOtherFloorPlane(int sector, gl_subsectorrendernode * node);
void AddOtherCeilingPlane(int sector, gl_subsectorrendernode * node);
@ -130,9 +133,9 @@ public:
virtual void AddPortal(GLWall *w, int portaltype) = 0;
virtual void AddMirrorSurface(GLWall *w) = 0;
virtual void AddFlat(GLFlat *flat, bool fog) = 0;
virtual void AddSprite(GLSprite *sprite, bool translucent) = 0;
virtual GLDecal *AddDecal(bool onmirror) = 0;
virtual void ProcessActorsInPortal(FLinePortalSpan *glport) = 0;
virtual std::pair<FFlatVertex *, unsigned int> AllocVertices(unsigned int count) = 0;

View file

@ -24,6 +24,13 @@ struct FLinePortalSpan;
struct FDynLightData;
class VSMatrix;
enum HWRenderStyle
{
STYLEHW_Normal, // default
STYLEHW_Solid, // drawn solid (needs special treatment for sprites)
STYLEHW_NoAlphaTest, // disable alpha test
};
enum WallTypes
{
RENDERWALL_NONE,
@ -270,16 +277,6 @@ public:
return -((y-glseg.y1)*(glseg.x2-glseg.x1)-(x-glseg.x1)*(glseg.y2-glseg.y1));
}
// Lines start-end and fdiv must intersect.
double CalcIntersectionVertex(GLWall * w2)
{
float ax = glseg.x1, ay=glseg.y1;
float bx = glseg.x2, by=glseg.y2;
float cx = w2->glseg.x1, cy=w2->glseg.y1;
float dx = w2->glseg.x2, dy=w2->glseg.y2;
return ((ay-cy)*(dx-cx)-(ax-cx)*(dy-cy)) / ((bx-ax)*(dy-cy)-(by-ay)*(dx-cx));
}
};
//==========================================================================