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

View file

@ -94,27 +94,6 @@ void GLDrawList::Reset()
drawitems.Clear(); 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) #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) void GLDrawList::SortWallIntoWall(SortNode * head,SortNode * sort)
{ {
GLWall * wh= walls[drawitems[head->itemindex].index]; GLWall * wh= walls[drawitems[head->itemindex].index];
@ -444,7 +432,7 @@ void GLDrawList::SortWallIntoWall(SortNode * head,SortNode * sort)
} }
else 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 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)); 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_faces_camera)
EXTERN_CVAR(Bool, gl_billboard_particles) 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) void GLDrawList::SortSpriteIntoWall(SortNode * head,SortNode * sort)
{ {
GLWall *wh= walls[drawitems[head->itemindex].index]; GLWall *wh= walls[drawitems[head->itemindex].index];
@ -542,7 +543,7 @@ void GLDrawList::SortSpriteIntoWall(SortNode * head,SortNode * sort)
} }
return; return;
} }
double r=ss->CalcIntersectionVertex(wh); double r=CalcIntersectionVertex(ss, wh);
float ix=(float)(ss->x1 + r * (ss->x2-ss->x1)); float ix=(float)(ss->x1 + r * (ss->x2-ss->x1));
float iy=(float)(ss->y1 + r * (ss->y2-ss->y1)); 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]; GLSprite * s= sprites[drawitems[i].index];
RenderSprite.Clock(); RenderSprite.Clock();
s->Draw(pass); gl_drawinfo->DrawSprite(s, pass);
RenderSprite.Unclock(); RenderSprite.Unclock();
} }
break; break;

View file

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

View file

@ -1060,7 +1060,7 @@ void GLLineToLinePortal::DrawContents()
void GLLineToLinePortal::RenderAttached() 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 TArray<spriteframe_t> SpriteFrames;
extern uint32_t r_renderercaps; 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) void gl_SetRenderStyle(FRenderStyle style, bool drawopaque, bool allowcolorblending)
{ {
int tm, sb, db, be; 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) 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[2] = mat * FVector3(x2, z, y1);
v[3] = mat * FVector3(x1, z, y1); v[3] = mat * FVector3(x1, z, y1);
glEnable(GL_POLYGON_OFFSET_FILL); return true;
glPolygonOffset(-1.0f, -128.0f);
return;
} }
// [BB] Billboard stuff // [BB] Billboard stuff
const bool drawWithXYBillboard = ((particle && gl_billboard_particles) || (!(actor && actor->renderflags & RF_FORCEYBILLBOARD) 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)))); && (gl_billboard_mode == 1 || (actor && actor->renderflags & RF_FORCEXYBILLBOARD))));
const bool drawBillboardFacingCamera = gl_billboard_faces_camera; const bool drawBillboardFacingCamera = gl_billboard_faces_camera;
@ -243,6 +233,7 @@ void GLSprite::CalculateVertices(FVector3 *v)
v[2] = FVector3(x1, z2, y1); v[2] = FVector3(x1, z2, y1);
v[3] = FVector3(x2, z2, y2); 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; if (pass == GLPASS_DECALS) return;
auto RenderStyle = sprite->RenderStyle;
if (pass == GLPASS_LIGHTSONLY) if (pass == GLPASS_LIGHTSONLY)
{ {
if (modelframe) if (sprite->modelframe)
{ {
if (RenderStyle.BlendOp != STYLEOP_Shadow) 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 additivefog = false;
bool foglayer = false; bool foglayer = false;
int rel = fullbright? 0 : getExtraLight(); int rel = sprite->fullbright? 0 : getExtraLight();
if (pass==GLPASS_TRANSLUCENT) if (pass==GLPASS_TRANSLUCENT)
{ {
@ -289,10 +281,10 @@ void GLSprite::Draw(int pass)
gl_SetRenderStyle(RenderStyle, false, gl_SetRenderStyle(RenderStyle, false,
// The rest of the needed checks are done inside gl_SetRenderStyle // The rest of the needed checks are done inside gl_SetRenderStyle
trans > 1.f - FLT_EPSILON && gl_usecolorblending && mDrawer->FixedColormap == CM_DEFAULT && actor && sprite->trans > 1.f - FLT_EPSILON && gl_usecolorblending && mDrawer->FixedColormap == CM_DEFAULT && sprite->actor &&
fullbright && gltexture && !gltexture->tex->GetTranslucency()); 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); gl_RenderState.AlphaFunc(GL_GEQUAL, 0.f);
} }
@ -307,10 +299,10 @@ void GLSprite::Draw(int pass)
float minalpha=0.1f; float minalpha=0.1f;
// fog + fuzz don't work well without some fiddling with the alpha value! // 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); float dist=Dist2(r_viewpoint.Pos.X, r_viewpoint.Pos.Y, sprite->x, sprite->y);
int fogd = hw_GetFogDensity(lightlevel, Colormap.FadeColor, Colormap.FogDensity); int fogd = hw_GetFogDensity(sprite->lightlevel, sprite->Colormap.FadeColor, sprite->Colormap.FogDensity);
// this value was determined by trial and error and is scale dependent! // this value was determined by trial and error and is scale dependent!
float factor = 0.05f + exp(-fogd*dist / 62500.f); 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.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; 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) else if (RenderStyle.BlendOp == STYLEOP_Add && RenderStyle.DestAlpha == STYLEALPHA_One)
{ {
additivefog = true; additivefog = true;
} }
} }
else if (modelframe == nullptr) else if (sprite->modelframe == nullptr)
{ {
int tm, sb, db, be; int tm, sb, db, be;
@ -341,40 +333,40 @@ void GLSprite::Draw(int pass)
} }
if (RenderStyle.BlendOp != STYLEOP_Shadow) 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) if (sprite->modelframe && !sprite->particle)
dynlightindex = gl_SetDynModelLight(gl_light_sprites ? actor : NULL, dynlightindex); sprite->dynlightindex = gl_SetDynModelLight(gl_light_sprites ? sprite->actor : nullptr, sprite->dynlightindex);
else 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) if (cursec != nullptr)
{ {
const PalEntry finalcol = fullbright const PalEntry finalcol = sprite->fullbright
? ThingColor ? sprite->ThingColor
: ThingColor.Modulate(cursec->SpecialColors[sector_t::sprites]); : sprite->ThingColor.Modulate(cursec->SpecialColors[sector_t::sprites]);
gl_RenderState.SetObjectColor(finalcol); 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) if (RenderStyle.Flags & STYLEF_FadeToBlack)
{ {
Colormap.FadeColor=0; sprite->Colormap.FadeColor=0;
additivefog = true; additivefog = true;
} }
if (RenderStyle.BlendOp == STYLEOP_RevSub || RenderStyle.BlendOp == STYLEOP_Sub) if (RenderStyle.BlendOp == STYLEOP_RevSub || RenderStyle.BlendOp == STYLEOP_Sub)
{ {
if (!modelframe) if (!sprite->modelframe)
{ {
// non-black fog with subtractive style needs special treatment // non-black fog with subtractive style needs special treatment
if (!Colormap.FadeColor.isBlack()) if (!sprite->Colormap.FadeColor.isBlack())
{ {
foglayer = true; foglayer = true;
// Due to the two-layer approach we need to force an alpha test that lets everything pass // 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. 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 else
{ {
gl_RenderState.EnableFog(false); gl_RenderState.EnableFog(false);
gl_RenderState.SetFog(0, 0); gl_RenderState.SetFog(0, 0);
} }
if (gltexture) gl_RenderState.SetMaterial(gltexture, CLAMP_XY, translation, OverrideShader, !!(RenderStyle.Flags & STYLEF_RedIsAlpha)); if (sprite->gltexture) gl_RenderState.SetMaterial(sprite->gltexture, CLAMP_XY, sprite->translation, sprite->OverrideShader, !!(RenderStyle.Flags & STYLEF_RedIsAlpha));
else if (!modelframe) gl_RenderState.EnableTexture(false); else if (!sprite->modelframe) gl_RenderState.EnableTexture(false);
//mDrawer->SetColor(lightlevel, rel, Colormap, trans); //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; 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; clipping = true;
gl_RenderState.EnableSplit(true); gl_RenderState.EnableSplit(true);
} }
secplane_t bottomp = { { 0, 0, -1. }, bottomclip }; secplane_t bottomp = { { 0, 0, -1. }, sprite->bottomclip };
secplane_t topp = { { 0, 0, -1. }, topclip }; secplane_t topp = { { 0, 0, -1. }, sprite->topclip };
for (unsigned i = 0; i < iter; i++) for (unsigned i = 0; i < iter; i++)
{ {
if (lightlist) if (lightlist)
@ -414,18 +407,18 @@ void GLSprite::Draw(int pass)
secplane_t *topplane = i == 0 ? &topp : &(*lightlist)[i].plane; secplane_t *topplane = i == 0 ? &topp : &(*lightlist)[i].plane;
secplane_t *lowplane = i == (*lightlist).Size() - 1 ? &bottomp : &(*lightlist)[i + 1].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 thislight = (*lightlist)[i].caster != nullptr ? hw_ClampLight(*(*lightlist)[i].p_lightlevel) : sprite->lightlevel;
int thisll = actor == nullptr? thislight : (uint8_t)actor->Sector->CheckSpriteGlow(thislight, actor->InterpolatedPosition(r_viewpoint.TicFrac)); int thisll = sprite->actor == nullptr? thislight : (uint8_t)sprite->actor->Sector->CheckSpriteGlow(thislight, sprite->actor->InterpolatedPosition(r_viewpoint.TicFrac));
FColormap thiscm; FColormap thiscm;
thiscm.CopyFog(Colormap); thiscm.CopyFog(sprite->Colormap);
thiscm.CopyFrom3DLight(&(*lightlist)[i]); thiscm.CopyFrom3DLight(&(*lightlist)[i]);
if (level.flags3 & LEVEL3_NOCOLOREDSPRITELIGHTING) if (level.flags3 & LEVEL3_NOCOLOREDSPRITELIGHTING)
{ {
thiscm.Decolorize(); thiscm.Decolorize();
} }
mDrawer->SetColor(thisll, rel, thiscm, trans); mDrawer->SetColor(thisll, rel, thiscm, sprite->trans);
if (!foglayer) if (!foglayer)
{ {
mDrawer->SetFog(thislight, rel, &thiscm, additivefog); mDrawer->SetFog(thislight, rel, &thiscm, additivefog);
@ -437,25 +430,29 @@ void GLSprite::Draw(int pass)
gl_RenderState.SetSplitPlanes(topp, bottomp); gl_RenderState.SetSplitPlanes(topp, bottomp);
} }
if (!modelframe) if (!sprite->modelframe)
{ {
gl_RenderState.Apply(); gl_RenderState.Apply();
FVector3 v[4]; FVector3 v[4];
gl_RenderState.SetNormal(0, 0, 0); gl_RenderState.SetNormal(0, 0, 0);
CalculateVertices(v); if (sprite->CalculateVertices(v))
{
glEnable(GL_POLYGON_OFFSET_FILL);
glPolygonOffset(-1.0f, -128.0f);
}
FQuadDrawer qd; FQuadDrawer qd;
qd.Set(0, v[0][0], v[0][1], v[0][2], ul, vt); 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], ur, 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], ul, vb); 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], ur, vb); qd.Set(3, v[3][0], v[3][1], v[3][2], sprite->ur, sprite->vb);
qd.Render(GL_TRIANGLE_STRIP); qd.Render(GL_TRIANGLE_STRIP);
if (foglayer) if (foglayer)
{ {
// If we get here we know that we have colored fog and no fixed colormap. // 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.SetFixedColormap(CM_FOGLAYER);
gl_RenderState.BlendEquation(GL_FUNC_ADD); gl_RenderState.BlendEquation(GL_FUNC_ADD);
gl_RenderState.BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); gl_RenderState.BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
@ -466,7 +463,7 @@ void GLSprite::Draw(int pass)
} }
else 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.BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
gl_RenderState.BlendEquation(GL_FUNC_ADD); gl_RenderState.BlendEquation(GL_FUNC_ADD);
gl_RenderState.SetTextureMode(TM_MODULATE); 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); glPolygonOffset(0.0f, 0.0f);
glDisable(GL_POLYGON_OFFSET_FILL); glDisable(GL_POLYGON_OFFSET_FILL);
} }
} }
else if (modelframe == nullptr) else if (sprite->modelframe == nullptr)
{ {
glPolygonOffset(0.0f, 0.0f); glPolygonOffset(0.0f, 0.0f);
glDisable(GL_POLYGON_OFFSET_FILL); 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; int list;
// [BB] Allow models to be drawn in the GLDL_TRANSLUCENT pass. // [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; list = GLDL_TRANSLUCENT;
} }
@ -516,9 +513,9 @@ inline void GLSprite::PutSprite(bool translucent)
{ {
list = GLDL_MODELS; list = GLDL_MODELS;
} }
dynlightindex = -1; sprite->dynlightindex = -1;
auto newsprt = gl_drawinfo->drawlists[list].NewSprite(); 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; double lightbottom;
unsigned int i; unsigned int i;
bool put=false; bool put=false;
@ -536,7 +545,7 @@ void GLSprite::SplitSprite(sector_t * frontsector, bool translucent)
for(i=0;i<lightlist.Size();i++) 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); if (i<lightlist.Size()-1) lightbottom=lightlist[i+1].plane.ZatPoint(actor);
else lightbottom=frontsector->floorplane.ZatPoint(actor); else lightbottom=frontsector->floorplane.ZatPoint(actor);
@ -563,7 +572,7 @@ void GLSprite::SplitSprite(sector_t * frontsector, bool translucent)
z1=copySprite.z2=lightbottom; z1=copySprite.z2=lightbottom;
vt=copySprite.vb=copySprite.vt+ vt=copySprite.vb=copySprite.vt+
(lightbottom-copySprite.z1)*(copySprite.vb-copySprite.vt)/(z2-copySprite.z1); (lightbottom-copySprite.z1)*(copySprite.vb-copySprite.vt)/(z2-copySprite.z1);
copySprite.PutSprite(translucent); copySprite.PutSprite(di, translucent);
put=true; 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 rs;
sector_t * rendersector; 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->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; return;
} }
@ -708,14 +717,11 @@ void GLSprite::Process(AActor* thing, sector_t * sector, int thruportal)
int spritenum = thing->sprite; int spritenum = thing->sprite;
DVector2 sprscale = thing->Scale; DVector2 sprscale = thing->Scale;
if (thing->player != NULL) if (thing->player != nullptr)
{ {
P_CheckPlayerSprite(thing, spritenum, sprscale); 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 // [RH] Interpolate the sprite's position to make it look smooth
DVector3 thingpos = thing->InterpolatedPosition(r_viewpoint.TicFrac); DVector3 thingpos = thing->InterpolatedPosition(r_viewpoint.TicFrac);
if (thruportal == 1) thingpos += level.Displacements.getOffset(thing->Sector->PortalGroup, sector->PortalGroup); 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 // don't draw first frame of a player missile
if (thing->flags&MF_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(); double speed = thing->Vel.Length();
if (speed >= thing->target->radius / 2) 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) 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 else
{ {
@ -921,7 +927,7 @@ void GLSprite::Process(AActor* thing, sector_t * sector, int thruportal)
x1 = x2 = x; x1 = x2 = x;
y1 = y2 = y; y1 = y2 = y;
z1 = z2 = z; 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); 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; RenderStyle = thing->RenderStyle;
// colormap stuff is a little more complicated here... // 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 if ((gl_enhanced_nv_stealth > 0 && di->FixedColormap == CM_LITE) // Infrared powerup only
|| (gl_enhanced_nv_stealth == 2 && mDrawer->FixedColormap >= CM_TORCH)// Also torches || (gl_enhanced_nv_stealth == 2 && di->FixedColormap >= CM_TORCH)// Also torches
|| (gl_enhanced_nv_stealth == 3)) // Any fixed colormap || (gl_enhanced_nv_stealth == 3)) // Any fixed colormap
enhancedvision = true; enhancedvision = true;
Colormap.Clear(); Colormap.Clear();
if (mDrawer->FixedColormap == CM_LITE) if (di->FixedColormap == CM_LITE)
{ {
if (gl_enhanced_nightvision && if (gl_enhanced_nightvision &&
(thing->IsKindOf(RUNTIME_CLASS(AInventory)) || thing->flags3&MF3_ISMONSTER || thing->flags&MF_MISSILE || thing->flags&MF_CORPSE)) (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; Colormap = rendersector->Colormap;
if (fullbright) 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 // under water areas keep their color for fullbright objects
{ {
// Only make the light white but keep everything else (fog, desaturation and Boom colormap.) // 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; actor = thing;
index = GLRenderer->gl_spriteindex++; index = GLRenderer->gl_spriteindex++;
particle = NULL; particle = nullptr;
const bool drawWithXYBillboard = (!(actor->renderflags & RF_FORCEYBILLBOARD) const bool drawWithXYBillboard = (!(actor->renderflags & RF_FORCEYBILLBOARD)
&& (actor->renderflags & RF_SPRITETYPEMASK) == RF_FACESPRITE && (actor->renderflags & RF_SPRITETYPEMASK) == RF_FACESPRITE
@ -1102,15 +1108,15 @@ void GLSprite::Process(AActor* thing, sector_t * sector, int thruportal)
// 3. any bright object // 3. any bright object
// 4. any with render style shadow (which doesn't use the sector light) // 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) // 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) RenderStyle.BlendOp != STYLEOP_Shadow && RenderStyle.BlendOp != STYLEOP_RevSub)
{ {
if (gl.flags & RFL_NO_CLIP_PLANES) // on old hardware we are rather limited... if (gl.flags & RFL_NO_CLIP_PLANES) // on old hardware we are rather limited...
{ {
lightlist = NULL; lightlist = nullptr;
if (!drawWithXYBillboard && !modelframe) if (!drawWithXYBillboard && !modelframe)
{ {
SplitSprite(thing->Sector, hw_styleflags != STYLEHW_Solid); SplitSprite(di, thing->Sector, hw_styleflags != STYLEHW_Solid);
} }
} }
else else
@ -1120,10 +1126,10 @@ void GLSprite::Process(AActor* thing, sector_t * sector, int thruportal)
} }
else else
{ {
lightlist = NULL; lightlist = nullptr;
} }
PutSprite(hw_styleflags != STYLEHW_Solid); PutSprite(di, hw_styleflags != STYLEHW_Solid);
rendered_sprites++; 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) if (GLRenderer->mClipPortal)
{ {
@ -1150,7 +1156,7 @@ void GLSprite::ProcessParticle (particle_t *particle, sector_t *sector)//, int s
sector->GetCeilingLight() : sector->GetFloorLight()); sector->GetCeilingLight() : sector->GetFloorLight());
foglevel = (uint8_t)clamp<short>(sector->lightlevel, 0, 255); foglevel = (uint8_t)clamp<short>(sector->lightlevel, 0, 255);
if (mDrawer->FixedColormap) if (di->FixedColormap)
{ {
Colormap.Clear(); Colormap.Clear();
} }
@ -1191,8 +1197,8 @@ void GLSprite::ProcessParticle (particle_t *particle, sector_t *sector)//, int s
ThingColor = particle->color; ThingColor = particle->color;
ThingColor.a = 255; ThingColor.a = 255;
modelframe=NULL; modelframe=nullptr;
gltexture=NULL; gltexture=nullptr;
topclip = LARGE_VALUE; topclip = LARGE_VALUE;
bottomclip = -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); 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; this->particle=particle;
fullbright = !!particle->bright; 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; if (gl_particles_style != 2 && trans>=1.0f-FLT_EPSILON) hw_styleflags = STYLEHW_Solid;
else hw_styleflags = STYLEHW_NoAlphaTest; 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; lightlist = &sector->e->XFloor.lightlist;
else else
lightlist = NULL; lightlist = nullptr;
PutSprite(hw_styleflags != STYLEHW_Solid); PutSprite(di, hw_styleflags != STYLEHW_Solid);
rendered_sprites++; 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; TMap<AActor*, bool> processcheck;
if (glport->validcount == validcount) return; // only process once per frame if (glport->validcount == validcount) return; // only process once per frame
@ -1318,8 +1324,8 @@ void FDrawInfo::ProcessActorsInPortal(FLinePortalSpan *glport)
th->SetXYZ(newpos); th->SetXYZ(newpos);
th->Prev += newpos - savedpos; th->Prev += newpos - savedpos;
GLSprite spr(mDrawer); GLSprite spr;
spr.Process(th, hw_FakeFlat(th->Sector, &fakesector, mDrawer->in_area, false), 2); spr.Process(this, th, hw_FakeFlat(th->Sector, &fakesector, in_area, false), in_area, 2);
th->Angles.Yaw = savedangle; th->Angles.Yaw = savedangle;
th->SetXYZ(savedpos); th->SetXYZ(savedpos);
th->Prev -= newpos - savedpos; th->Prev -= newpos - savedpos;

View file

@ -30,6 +30,7 @@ struct FFlatVertex;
struct FLinePortalSpan; struct FLinePortalSpan;
class GLSceneDrawer; class GLSceneDrawer;
struct FDynLightData; struct FDynLightData;
enum area_t : int;
struct FDrawInfo; struct FDrawInfo;
struct HWDrawInfo; struct HWDrawInfo;
@ -47,7 +48,6 @@ public:
friend struct GLDrawList; friend struct GLDrawList;
friend void Mod_RenderModel(GLSprite * spr, model_t * mdl, int framenumber); friend void Mod_RenderModel(GLSprite * spr, model_t * mdl, int framenumber);
GLSceneDrawer *mDrawer;
int lightlevel; int lightlevel;
uint8_t foglevel; uint8_t foglevel;
uint8_t hw_styleflags; uint8_t hw_styleflags;
@ -81,25 +81,16 @@ public:
int dynlightindex; int dynlightindex;
void SplitSprite(sector_t * frontsector, bool translucent); void SplitSprite(HWDrawInfo *di, sector_t * frontsector, bool translucent);
void SetLowerParam();
void PerformSpriteClipAdjustment(AActor *thing, const DVector2 &thingpos, float spriteheight); void PerformSpriteClipAdjustment(AActor *thing, const DVector2 &thingpos, float spriteheight);
void CalculateVertices(FVector3 *v); bool CalculateVertices(FVector3 *v);
public: public:
GLSprite(GLSceneDrawer *drawer) GLSprite() {}
{ void PutSprite(HWDrawInfo *di, bool translucent);
mDrawer = drawer; 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)
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(const GLSprite &other) 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; line_t *otherside = wall->lineportal->lines[0]->mDestination;
if (otherside != NULL && otherside->portalindex < level.linePortals.Size()) if (otherside != NULL && otherside->portalindex < level.linePortals.Size())
{ {
ProcessActorsInPortal(otherside->getPortal()->mGroup); ProcessActorsInPortal(otherside->getPortal()->mGroup, mDrawer->in_area);
} }
portal = new GLLineToLinePortal(wall->lineportal); portal = new GLLineToLinePortal(wall->lineportal);
} }

View file

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

View file

@ -24,6 +24,13 @@ struct FLinePortalSpan;
struct FDynLightData; struct FDynLightData;
class VSMatrix; class VSMatrix;
enum HWRenderStyle
{
STYLEHW_Normal, // default
STYLEHW_Solid, // drawn solid (needs special treatment for sprites)
STYLEHW_NoAlphaTest, // disable alpha test
};
enum WallTypes enum WallTypes
{ {
RENDERWALL_NONE, RENDERWALL_NONE,
@ -270,16 +277,6 @@ public:
return -((y-glseg.y1)*(glseg.x2-glseg.x1)-(x-glseg.x1)*(glseg.y2-glseg.y1)); 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));
}
}; };
//========================================================================== //==========================================================================