Merge branch 'Clip3DLights'

This commit is contained in:
Christoph Oelckers 2016-02-01 01:50:56 +01:00
commit bddad29acb
13 changed files with 201 additions and 387 deletions

View file

@ -413,7 +413,6 @@ static void InitVertexData()
TArray<int> * vt_sectorlists;
int i,j,k;
unsigned int l;
vt_sectorlists = new TArray<int>[numvertexes];
@ -436,15 +435,6 @@ static void InitVertexData()
AddToVertex(sec, vt_sectorlists[v-vertexes]);
if (sec->heightsec) AddToVertex(sec->heightsec, vt_sectorlists[v-vertexes]);
for(l=0;l<x.ffloors.Size();l++)
{
F3DFloor * rover = x.ffloors[l];
if(!(rover->flags & FF_EXISTS)) continue;
if (rover->flags&FF_NOSHADE) continue; // FF_NOSHADE doesn't create any wall splits
AddToVertex(rover->model, vt_sectorlists[v-vertexes]);
}
}
}
}

View file

@ -69,7 +69,7 @@ TArray<VSMatrix> gl_MatrixStack;
void FRenderState::Reset()
{
mTextureEnabled = true;
mBrightmapEnabled = mFogEnabled = mGlowEnabled = false;
mSplitEnabled = mBrightmapEnabled = mFogEnabled = mGlowEnabled = false;
mColorMask[0] = mColorMask[1] = mColorMask[2] = mColorMask[3] = true;
currentColorMask[0] = currentColorMask[1] = currentColorMask[2] = currentColorMask[3] = true;
mFogColor.d = -1;
@ -104,6 +104,7 @@ void FRenderState::Reset()
bool FRenderState::ApplyShader()
{
static const float nulvec[] = { 0.f, 0.f, 0.f, 0.f };
if (mSpecialEffect > EFF_NONE)
{
activeShader = GLRenderer->mShaderManager->BindEffect(mSpecialEffect);
@ -157,7 +158,6 @@ bool FRenderState::ApplyShader()
else if (activeShader->currentglowstate)
{
// if glowing is on, disable it.
static const float nulvec[] = { 0.f, 0.f, 0.f, 0.f };
activeShader->muGlowTopColor.Set(nulvec);
activeShader->muGlowBottomColor.Set(nulvec);
activeShader->muGlowTopPlane.Set(nulvec);
@ -165,6 +165,18 @@ bool FRenderState::ApplyShader()
activeShader->currentglowstate = 0;
}
if (mSplitEnabled)
{
activeShader->muSplitTopPlane.Set(mSplitTopPlane.vec);
activeShader->muSplitBottomPlane.Set(mSplitBottomPlane.vec);
activeShader->currentsplitstate = 1;
}
else
{
activeShader->muSplitTopPlane.Set(nulvec);
activeShader->muSplitBottomPlane.Set(nulvec);
}
if (mColormapState != activeShader->currentfixedcolormap)
{
float r, g, b;

View file

@ -46,6 +46,7 @@ class FRenderState
bool mTextureEnabled;
bool mFogEnabled;
bool mGlowEnabled;
bool mSplitEnabled;
bool mBrightmapEnabled;
bool mColorMask[4];
bool currentColorMask[4];
@ -72,6 +73,7 @@ class FRenderState
FStateVec4 mCameraPos;
FStateVec4 mGlowTop, mGlowBottom;
FStateVec4 mGlowTopPlane, mGlowBottomPlane;
FStateVec4 mSplitTopPlane, mSplitBottomPlane;
PalEntry mFogColor;
PalEntry mObjectColor;
FStateVec4 mDynColor;
@ -229,6 +231,11 @@ public:
mGlowEnabled = on;
}
void EnableSplit(bool on)
{
mSplitEnabled = on;
}
void SetLightIndex(int n)
{
mLightIndex = n;
@ -272,6 +279,12 @@ public:
mGlowBottomPlane.Set(FIXED2FLOAT(bottom.a), FIXED2FLOAT(bottom.b), FIXED2FLOAT(bottom.ic), FIXED2FLOAT(bottom.d));
}
void SetSplitPlanes(const secplane_t &top, const secplane_t &bottom)
{
mSplitTopPlane.Set(FIXED2FLOAT(top.a), FIXED2FLOAT(top.b), FIXED2FLOAT(top.ic), FIXED2FLOAT(top.d));
mSplitBottomPlane.Set(FIXED2FLOAT(bottom.a), FIXED2FLOAT(bottom.b), FIXED2FLOAT(bottom.ic), FIXED2FLOAT(bottom.d));
}
void SetDynLight(float r, float g, float b)
{
mDynColor.Set(r, g, b, 0);

View file

@ -137,11 +137,12 @@ void GLSkyInfo::init(int sky1, PalEntry FadeColor)
void GLWall::SkyPlane(sector_t *sector, int plane, bool allowreflect)
{
int ptype = -1;
FPortal *portal = sector->portals[plane];
if (portal != NULL)
{
if (GLPortal::instack[1 - plane]) return;
type = RENDERWALL_SECTORSTACK;
ptype = PORTALTYPE_SECTORSTACK;
this->portal = portal;
}
else
@ -156,13 +157,13 @@ void GLWall::SkyPlane(sector_t *sector, int plane, bool allowreflect)
if (!gl_noskyboxes && skyboxx && GLRenderer->mViewActor != skyboxx && !(skyboxx->flags&MF_JUSTHIT))
{
type = RENDERWALL_SKYBOX;
ptype = PORTALTYPE_SKYBOX;
skybox = skyboxx;
}
else
{
skyinfo.init(sector->sky, Colormap.FadeColor);
type = RENDERWALL_SKY;
ptype = PORTALTYPE_SKY;
sky = UniqueSkies.Get(&skyinfo);
}
}
@ -170,12 +171,14 @@ void GLWall::SkyPlane(sector_t *sector, int plane, bool allowreflect)
{
if ((plane == sector_t::ceiling && viewz > sector->ceilingplane.d) ||
(plane == sector_t::floor && viewz < -sector->floorplane.d)) return;
type = RENDERWALL_PLANEMIRROR;
ptype = PORTALTYPE_PLANEMIRROR;
planemirror = plane == sector_t::ceiling ? &sector->ceilingplane : &sector->floorplane;
}
else return;
}
PutWall(0);
if (ptype != -1)
{
PutPortal(ptype);
}
}
@ -189,22 +192,23 @@ void GLWall::SkyLine(line_t *line)
{
ASkyViewpoint * skyboxx = line->skybox;
GLSkyInfo skyinfo;
int ptype;
// JUSTHIT is used as an indicator that a skybox is in use.
// This is to avoid recursion
if (!gl_noskyboxes && skyboxx && GLRenderer->mViewActor != skyboxx && !(skyboxx->flags&MF_JUSTHIT))
{
type = RENDERWALL_SKYBOX;
ptype = PORTALTYPE_SKYBOX;
skybox = skyboxx;
}
else
{
skyinfo.init(line->frontsector->sky, Colormap.FadeColor);
type = RENDERWALL_SKY;
ptype = PORTALTYPE_SKY;
sky = UniqueSkies.Get(&skyinfo);
}
PutWall(0);
PutPortal(ptype);
}

View file

@ -30,13 +30,7 @@ enum WallTypes
RENDERWALL_M1S,
RENDERWALL_M2S,
RENDERWALL_BOTTOM,
RENDERWALL_SKY,
RENDERWALL_FOGBOUNDARY,
RENDERWALL_HORIZON,
RENDERWALL_SKYBOX,
RENDERWALL_SECTORSTACK,
RENDERWALL_PLANEMIRROR,
RENDERWALL_MIRROR,
RENDERWALL_MIRRORSURFACE,
RENDERWALL_M2SNF,
RENDERWALL_COLOR,
@ -44,6 +38,16 @@ enum WallTypes
// Insert new types at the end!
};
enum PortalTypes
{
PORTALTYPE_SKY,
PORTALTYPE_HORIZON,
PORTALTYPE_SKYBOX,
PORTALTYPE_SECTORSTACK,
PORTALTYPE_PLANEMIRROR,
PORTALTYPE_MIRROR,
};
struct GLSeg
{
float x1,x2;
@ -85,7 +89,6 @@ struct GLSectorPlane
};
class GLWall
{
public:
@ -105,7 +108,6 @@ public:
{
RWF_BLANK = 0,
RWF_TEXTURED = 1, // actually not being used anymore because with buffers it's even less efficient not writing the texture coordinates - but leave it here
RWF_GLOW = 2,
RWF_NOSPLIT = 4,
RWF_NORENDER = 8,
};
@ -126,6 +128,7 @@ public:
fixed_t viewdistance;
TArray<lightlist_t> *lightlist;
int lightlevel;
BYTE type;
BYTE flags;
@ -160,12 +163,14 @@ public:
private:
void CheckGlowing();
void PutWall(bool translucent);
void PutWall(sector_t *sec, bool translucent);
void PutPortal(int ptype);
void CheckTexturePosition();
void SetupLights();
bool PrepareLight(texcoord * tcs, ADynamicLight * light);
void RenderWall(int textured, unsigned int *store = NULL);
void RenderTextured(int rflags);
void FloodPlane(int pass);
@ -175,8 +180,6 @@ private:
void SkyTop(seg_t * seg,sector_t * fs,sector_t * bs,vertex_t * v1,vertex_t * v2);
void SkyBottom(seg_t * seg,sector_t * fs,sector_t * bs,vertex_t * v1,vertex_t * v2);
void Put3DWall(lightlist_t * lightlist, bool translucent);
void SplitWall(sector_t * frontsector, bool translucent);
void LightPass();
void SetHorizon(vertex_t * ul, vertex_t * ur, vertex_t * ll, vertex_t * lr);
bool DoHorizon(seg_t * seg,sector_t * fs, vertex_t * v1,vertex_t * v2);

View file

@ -96,30 +96,24 @@ void GLWall::CheckGlowing()
//
//
//==========================================================================
void GLWall::PutWall(bool translucent)
void GLWall::PutWall(sector_t *sec, bool translucent)
{
GLPortal * portal;
int list;
static char passflag[]={
static char passflag[] = {
0, //RENDERWALL_NONE,
1, //RENDERWALL_TOP, // unmasked
1, //RENDERWALL_M1S, // unmasked
2, //RENDERWALL_M2S, // depends on render and texture settings
1, //RENDERWALL_BOTTOM, // unmasked
4, //RENDERWALL_SKYDOME, // special
3, //RENDERWALL_FOGBOUNDARY, // translucent
4, //RENDERWALL_HORIZON, // special
4, //RENDERWALL_SKYBOX, // special
4, //RENDERWALL_SECTORSTACK, // special
4, //RENDERWALL_PLANEMIRROR, // special
4, //RENDERWALL_MIRROR, // special
1, //RENDERWALL_MIRRORSURFACE, // only created here from RENDERWALL_MIRROR
1, //RENDERWALL_MIRRORSURFACE, // only created from PORTALTYPE_MIRROR
2, //RENDERWALL_M2SNF, // depends on render and texture settings, no fog, used on mid texture lines with a fog boundary.
3, //RENDERWALL_COLOR, // translucent
2, //RENDERWALL_FFBLOCK // depends on render and texture settings
};
if (gltexture && gltexture->GetTransparent() && passflag[type] == 2)
{
translucent = true;
@ -128,25 +122,28 @@ void GLWall::PutWall(bool translucent)
if (gl_fixedcolormap)
{
// light planes don't get drawn with fullbright rendering
if (!gltexture && passflag[type]!=4) return;
if (gltexture == NULL) return;
Colormap.Clear();
}
else if (sec->e->XFloor.lightlist.Size() > 0 && gltexture != NULL)
{
lightlist = &sec->e->XFloor.lightlist;
}
CheckGlowing();
if (translucent) // translucent walls
{
viewdistance = P_AproxDistance( ((seg->linedef->v1->x+seg->linedef->v2->x)>>1) - viewx,
((seg->linedef->v1->y+seg->linedef->v2->y)>>1) - viewy);
viewdistance = P_AproxDistance(((seg->linedef->v1->x + seg->linedef->v2->x) >> 1) - viewx,
((seg->linedef->v1->y + seg->linedef->v2->y) >> 1) - viewy);
gl_drawinfo->drawlists[GLDL_TRANSLUCENT].AddWall(this);
}
else if (passflag[type]!=4) // non-translucent walls
else
{
bool masked;
masked = passflag[type]==1? false : (gltexture && gltexture->isMasked());
masked = passflag[type] == 1 ? false : (gltexture && gltexture->isMasked());
if ((flags&GLWF_SKYHACK && type == RENDERWALL_M2S))
{
@ -159,18 +156,25 @@ void GLWall::PutWall(bool translucent)
gl_drawinfo->drawlists[list].AddWall(this);
}
else switch (type)
lightlist = NULL;
}
void GLWall::PutPortal(int ptype)
{
GLPortal * portal;
switch (ptype)
{
// portals don't go into the draw list.
// Instead they are added to the portal manager
case RENDERWALL_HORIZON:
case PORTALTYPE_HORIZON:
horizon=UniqueHorizons.Get(horizon);
portal=GLPortal::FindPortal(horizon);
if (!portal) portal=new GLHorizonPortal(horizon);
portal->AddLine(this);
break;
case RENDERWALL_SKYBOX:
case PORTALTYPE_SKYBOX:
portal = GLPortal::FindPortal(skybox);
if (!portal)
{
@ -181,12 +185,12 @@ void GLWall::PutWall(bool translucent)
portal->AddLine(this);
break;
case RENDERWALL_SECTORSTACK:
case PORTALTYPE_SECTORSTACK:
portal = this->portal->GetGLPortal();
portal->AddLine(this);
break;
case RENDERWALL_PLANEMIRROR:
case PORTALTYPE_PLANEMIRROR:
if (GLPortal::PlaneMirrorMode * planemirror->c <=0)
{
//@sync-portal
@ -197,7 +201,7 @@ void GLWall::PutWall(bool translucent)
}
break;
case RENDERWALL_MIRROR:
case PORTALTYPE_MIRROR:
portal=GLPortal::FindPortal(seg->linedef);
if (!portal) portal=new GLMirrorPortal(seg->linedef);
portal->AddLine(this);
@ -209,7 +213,7 @@ void GLWall::PutWall(bool translucent)
}
break;
case RENDERWALL_SKY:
case PORTALTYPE_SKY:
portal=GLPortal::FindPortal(sky);
if (!portal) portal=new GLSkyPortal(sky);
portal->AddLine(this);
@ -217,222 +221,6 @@ void GLWall::PutWall(bool translucent)
}
}
//==========================================================================
//
// Sets 3D-floor lighting info
//
//==========================================================================
void GLWall::Put3DWall(lightlist_t * lightlist, bool translucent)
{
// only modify the light level if it doesn't originate from the seg's frontsector. This is to account for light transferring effects
if (lightlist->p_lightlevel != &seg->sidedef->sector->lightlevel)
{
lightlevel = gl_ClampLight(*lightlist->p_lightlevel);
}
// relative light won't get changed here. It is constant across the entire wall.
Colormap.CopyFrom3DLight(lightlist);
PutWall(translucent);
}
//==========================================================================
//
// Splits a wall vertically if a 3D-floor
// creates different lighting across the wall
//
//==========================================================================
void GLWall::SplitWall(sector_t * frontsector, bool translucent)
{
GLWall copyWall1,copyWall2;
float maplightbottomleft;
float maplightbottomright;
unsigned int i;
int origlight = lightlevel;
TArray<lightlist_t> & lightlist=frontsector->e->XFloor.lightlist;
if (glseg.x1==glseg.x2 && glseg.y1==glseg.y2)
{
return;
}
::SplitWall.Clock();
#ifdef _DEBUG
if (seg->linedef-lines==1)
{
int a = 0;
}
#endif
if (lightlist.Size()>1)
{
for(i=0;i<lightlist.Size()-1;i++)
{
if (i<lightlist.Size()-1)
{
secplane_t &p = lightlist[i+1].plane;
if (p.a | p.b)
{
maplightbottomleft = p.ZatPoint(glseg.x1,glseg.y1);
maplightbottomright= p.ZatPoint(glseg.x2,glseg.y2);
}
else
{
maplightbottomleft =
maplightbottomright= p.ZatPoint(glseg.x2,glseg.y2);
}
}
else
{
maplightbottomright = maplightbottomleft = -32000;
}
// The light is completely above the wall!
if (maplightbottomleft>=ztop[0] && maplightbottomright>=ztop[1])
{
continue;
}
// check for an intersection with the upper plane
if ((maplightbottomleft<ztop[0] && maplightbottomright>ztop[1]) ||
(maplightbottomleft>ztop[0] && maplightbottomright<ztop[1]))
{
float clen = MAX<float>(fabsf(glseg.x2-glseg.x1), fabsf(glseg.y2-glseg.y2));
float dch=ztop[1]-ztop[0];
float dfh=maplightbottomright-maplightbottomleft;
float coeff= (ztop[0]-maplightbottomleft)/(dfh-dch);
// check for inaccuracies - let's be a little generous here!
if (coeff*clen<.1f)
{
maplightbottomleft=ztop[0];
}
else if (coeff*clen>clen-.1f)
{
maplightbottomright=ztop[1];
}
else
{
// split the wall in 2 at the intersection and recursively split both halves
copyWall1=copyWall2=*this;
copyWall1.glseg.x2 = copyWall2.glseg.x1 = glseg.x1 + coeff * (glseg.x2-glseg.x1);
copyWall1.glseg.y2 = copyWall2.glseg.y1 = glseg.y1 + coeff * (glseg.y2-glseg.y1);
copyWall1.ztop[1] = copyWall2.ztop[0] = ztop[0] + coeff * (ztop[1]-ztop[0]);
copyWall1.zbottom[1] = copyWall2.zbottom[0] = zbottom[0] + coeff * (zbottom[1]-zbottom[0]);
copyWall1.glseg.fracright = copyWall2.glseg.fracleft = glseg.fracleft + coeff * (glseg.fracright-glseg.fracleft);
copyWall1.uprgt.u = copyWall2.uplft.u = uplft.u + coeff * (uprgt.u-uplft.u);
copyWall1.uprgt.v = copyWall2.uplft.v = uplft.v + coeff * (uprgt.v-uplft.v);
copyWall1.lorgt.u = copyWall2.lolft.u = lolft.u + coeff * (lorgt.u-lolft.u);
copyWall1.lorgt.v = copyWall2.lolft.v = lolft.v + coeff * (lorgt.v-lolft.v);
::SplitWall.Unclock();
copyWall1.SplitWall(frontsector, translucent);
copyWall2.SplitWall(frontsector, translucent);
return;
}
}
// check for an intersection with the lower plane
if ((maplightbottomleft<zbottom[0] && maplightbottomright>zbottom[1]) ||
(maplightbottomleft>zbottom[0] && maplightbottomright<zbottom[1]))
{
float clen = MAX<float>(fabsf(glseg.x2-glseg.x1), fabsf(glseg.y2-glseg.y2));
float dch=zbottom[1]-zbottom[0];
float dfh=maplightbottomright-maplightbottomleft;
float coeff= (zbottom[0]-maplightbottomleft)/(dfh-dch);
// check for inaccuracies - let's be a little generous here because there's
// some conversions between floats and fixed_t's involved
if (coeff*clen<.1f)
{
maplightbottomleft=zbottom[0];
}
else if (coeff*clen>clen-.1f)
{
maplightbottomright=zbottom[1];
}
else
{
// split the wall in 2 at the intersection and recursively split both halves
copyWall1=copyWall2=*this;
copyWall1.glseg.x2 = copyWall2.glseg.x1 = glseg.x1 + coeff * (glseg.x2-glseg.x1);
copyWall1.glseg.y2 = copyWall2.glseg.y1 = glseg.y1 + coeff * (glseg.y2-glseg.y1);
copyWall1.ztop[1] = copyWall2.ztop[0] = ztop[0] + coeff * (ztop[1]-ztop[0]);
copyWall1.zbottom[1] = copyWall2.zbottom[0] = zbottom[0] + coeff * (zbottom[1]-zbottom[0]);
copyWall1.glseg.fracright = copyWall2.glseg.fracleft = glseg.fracleft + coeff * (glseg.fracright-glseg.fracleft);
copyWall1.uprgt.u = copyWall2.uplft.u = uplft.u + coeff * (uprgt.u-uplft.u);
copyWall1.uprgt.v = copyWall2.uplft.v = uplft.v + coeff * (uprgt.v-uplft.v);
copyWall1.lorgt.u = copyWall2.lolft.u = lolft.u + coeff * (lorgt.u-lolft.u);
copyWall1.lorgt.v = copyWall2.lolft.v = lolft.v + coeff * (lorgt.v-lolft.v);
::SplitWall.Unclock();
copyWall1.SplitWall(frontsector, translucent);
copyWall2.SplitWall(frontsector, translucent);
return;
}
}
// 3D floor is completely within this light
if (maplightbottomleft<=zbottom[0] && maplightbottomright<=zbottom[1])
{
// These values must not be destroyed!
int ll=lightlevel;
FColormap lc=Colormap;
Put3DWall(&lightlist[i], translucent);
lightlevel=ll;
Colormap=lc;
::SplitWall.Unclock();
return;
}
if (maplightbottomleft<=ztop[0] && maplightbottomright<=ztop[1] &&
(maplightbottomleft!=ztop[0] || maplightbottomright!=ztop[1]))
{
copyWall1=*this;
copyWall1.flags |= GLWF_NOSPLITLOWER;
flags |= GLWF_NOSPLITUPPER;
ztop[0]=copyWall1.zbottom[0]=maplightbottomleft;
ztop[1]=copyWall1.zbottom[1]=maplightbottomright;
uplft.v=copyWall1.lolft.v=copyWall1.uplft.v+
(maplightbottomleft-copyWall1.ztop[0])*(copyWall1.lolft.v-copyWall1.uplft.v)/(zbottom[0]-copyWall1.ztop[0]);
uprgt.v=copyWall1.lorgt.v=copyWall1.uprgt.v+
(maplightbottomright-copyWall1.ztop[1])*(copyWall1.lorgt.v-copyWall1.uprgt.v)/(zbottom[1]-copyWall1.ztop[1]);
copyWall1.Put3DWall(&lightlist[i], translucent);
}
if (ztop[0]==zbottom[0] && ztop[1]==zbottom[1])
{
::SplitWall.Unclock();
return;
}
}
}
// These values must not be destroyed!
int ll=lightlevel;
FColormap lc=Colormap;
Put3DWall(&lightlist[lightlist.Size()-1], translucent);
lightlevel=ll;
Colormap=lc;
flags &= ~GLWF_NOSPLITUPPER;
::SplitWall.Unclock();
}
//==========================================================================
//
//
@ -458,7 +246,6 @@ bool GLWall::DoHorizon(seg_t * seg,sector_t * fs, vertex_t * v1,vertex_t * v2)
}
else
{
type = RENDERWALL_HORIZON;
hi.plane.GetFromSector(fs, true);
hi.lightlevel = gl_ClampLight(fs->GetCeilingLight());
hi.colormap = fs->ColorMap;
@ -473,7 +260,7 @@ bool GLWall::DoHorizon(seg_t * seg,sector_t * fs, vertex_t * v1,vertex_t * v2)
if (gl_fixedcolormap) hi.colormap.Clear();
horizon = &hi;
PutWall(0);
PutPortal(PORTALTYPE_HORIZON);
}
ztop[1] = ztop[0] = zbottom[0];
}
@ -487,7 +274,6 @@ bool GLWall::DoHorizon(seg_t * seg,sector_t * fs, vertex_t * v1,vertex_t * v2)
}
else
{
type = RENDERWALL_HORIZON;
hi.plane.GetFromSector(fs, false);
hi.lightlevel = gl_ClampLight(fs->GetFloorLight());
hi.colormap = fs->ColorMap;
@ -502,7 +288,7 @@ bool GLWall::DoHorizon(seg_t * seg,sector_t * fs, vertex_t * v1,vertex_t * v2)
if (gl_fixedcolormap) hi.colormap.Clear();
horizon = &hi;
PutWall(0);
PutPortal(PORTALTYPE_HORIZON);
}
}
return true;
@ -712,7 +498,7 @@ void GLWall::DoTexture(int _type,seg_t * seg, int peg,
gltexture->GetTexCoordInfo(&tci, seg->sidedef->GetTextureXScale(texpos), seg->sidedef->GetTextureYScale(texpos));
type = (seg->linedef->special == Line_Mirror && _type == RENDERWALL_M1S && gl_mirrors) ? RENDERWALL_MIRROR : _type;
type = _type;
float floatceilingref = FIXED2FLOAT(ceilingrefheight + tci.RowOffset(seg->sidedef->GetTextureYOffset(texpos)));
if (peg) floatceilingref += tci.mRenderHeight - FIXED2FLOAT(lh + v_offset);
@ -720,13 +506,16 @@ void GLWall::DoTexture(int _type,seg_t * seg, int peg,
if (!SetWallCoordinates(seg, &tci, floatceilingref, topleft, topright, bottomleft, bottomright,
seg->sidedef->GetTextureXOffset(texpos))) return;
if (seg->linedef->special == Line_Mirror && _type == RENDERWALL_M1S && gl_mirrors)
{
PutPortal(PORTALTYPE_MIRROR);
}
else
{
CheckTexturePosition();
// Add this wall to the render list
sector_t * sec = sub? sub->sector : seg->frontsector;
if (sec->e->XFloor.lightlist.Size()==0 || gl_fixedcolormap) PutWall(false);
else SplitWall(sec, false);
PutWall(sub ? sub->sector : seg->frontsector, false);
}
glseg=glsave;
flags&=~GLT_CLAMPY;
@ -924,12 +713,15 @@ void GLWall::DoMidTexture(seg_t * seg, bool drawfogboundary,
{
flags |= GLWF_NOSPLITUPPER|GLWF_NOSPLITLOWER;
type=RENDERWALL_FOGBOUNDARY;
PutWall(true);
if (!gltexture)
FMaterial *savetex = gltexture;
gltexture = NULL;
PutWall(seg->frontsector, true);
if (!savetex)
{
flags &= ~(GLWF_NOSPLITUPPER|GLWF_NOSPLITLOWER);
return;
}
gltexture = savetex;
type=RENDERWALL_M2SNF;
}
else type=RENDERWALL_M2S;
@ -1014,8 +806,7 @@ void GLWall::DoMidTexture(seg_t * seg, bool drawfogboundary,
// Draw the stuff
//
//
if (realfront->e->XFloor.lightlist.Size()==0 || gl_fixedcolormap) split.PutWall(translucent);
else split.SplitWall(realfront, translucent);
split.PutWall(realfront, translucent);
t=1;
}
@ -1023,13 +814,7 @@ void GLWall::DoMidTexture(seg_t * seg, bool drawfogboundary,
}
else
{
//
//
// Draw the stuff without splitting
//
//
if (realfront->e->XFloor.lightlist.Size()==0 || gl_fixedcolormap) PutWall(translucent);
else SplitWall(realfront, translucent);
PutWall(realfront, translucent);
}
alpha=1.0f;
}
@ -1138,10 +923,7 @@ void GLWall::BuildFFBlock(seg_t * seg, F3DFloor * rover,
translucent=false;
}
sector_t * sec = sub? sub->sector : seg->frontsector;
if (sec->e->XFloor.lightlist.Size()==0 || gl_fixedcolormap) PutWall(translucent);
else SplitWall(sec, translucent);
PutWall(sub? sub->sector : seg->frontsector, translucent);
alpha=1.0f;
lightlevel = savelight;
@ -1476,6 +1258,7 @@ void GLWall::Process(seg_t *seg, sector_t * frontsector, sector_t * backsector)
Colormap = frontsector->ColorMap;
flags = 0;
dynlightindex = UINT_MAX;
lightlist = NULL;
int rel = 0;
int orglightlevel = gl_ClampLight(frontsector->lightlevel);
@ -1768,7 +1551,7 @@ void GLWall::ProcessLowerMiniseg(seg_t *seg, sector_t * frontsector, sector_t *
type = RENDERWALL_BOTTOM;
gltexture->GetTexCoordInfo(&tci, FRACUNIT, FRACUNIT);
SetWallCoordinates(seg, &tci, FIXED2FLOAT(bfh), bfh, bfh, ffh, ffh, 0);
PutWall(false);
PutWall(seg->frontsector, false);
}
}
}

View file

@ -182,11 +182,6 @@ void GLWall::RenderWall(int textured, unsigned int *store)
tcs[1]=uplft;
tcs[2]=uprgt;
tcs[3]=lorgt;
if ((flags&GLWF_GLOW) && (textured & RWF_GLOW))
{
gl_RenderState.SetGlowPlanes(topplane, bottomplane);
gl_RenderState.SetGlowParams(topglowcolor, bottomglowcolor);
}
if (!(textured & RWF_NORENDER))
{
@ -306,6 +301,66 @@ void GLWall::RenderMirrorSurface()
}
}
//==========================================================================
//
//
//
//==========================================================================
void GLWall::RenderTextured(int rflags)
{
int tmode = gl_RenderState.GetTextureMode();
int rel = getExtraLight();
if (flags & GLWF_GLOW)
{
gl_RenderState.EnableGlow(true);
gl_RenderState.SetGlowPlanes(topplane, bottomplane);
gl_RenderState.SetGlowParams(topglowcolor, bottomglowcolor);
}
gl_RenderState.SetMaterial(gltexture, flags & 3, 0, -1, false);
if (type == RENDERWALL_M2SNF)
{
if (flags & GLT_CLAMPY)
{
if (tmode == TM_MODULATE) gl_RenderState.SetTextureMode(TM_CLAMPY);
}
gl_SetFog(255, 0, NULL, false);
}
float absalpha = fabsf(alpha);
if (lightlist == NULL)
{
gl_SetColor(lightlevel, rel, Colormap, absalpha);
if (type != RENDERWALL_M2SNF) gl_SetFog(lightlevel, rel, &Colormap, RenderStyle == STYLE_Add);
RenderWall(rflags);
}
else
{
gl_RenderState.EnableSplit(true);
glEnable(GL_CLIP_DISTANCE3);
glEnable(GL_CLIP_DISTANCE4);
for (unsigned i = 0; i < lightlist->Size(); i++)
{
int thisll = (*lightlist)[i].caster != NULL? gl_ClampLight(*(*lightlist)[i].p_lightlevel) : lightlevel;
FColormap thiscm;
thiscm.FadeColor = Colormap.FadeColor;
thiscm.CopyFrom3DLight(&(*lightlist)[i]);
gl_SetColor(thisll, rel, thiscm, absalpha);
if (type != RENDERWALL_M2SNF) gl_SetFog(thisll, rel, &thiscm, RenderStyle == STYLE_Add);
gl_RenderState.SetSplitPlanes((*lightlist)[i].plane, i == (*lightlist).Size() - 1 ? bottomplane : (*lightlist)[i + 1].plane);
RenderWall(rflags);
}
glDisable(GL_CLIP_DISTANCE3);
glDisable(GL_CLIP_DISTANCE4);
gl_RenderState.EnableSplit(false);
}
gl_RenderState.SetTextureMode(tmode);
gl_RenderState.EnableGlow(false);
}
//==========================================================================
//
@ -315,57 +370,27 @@ void GLWall::RenderMirrorSurface()
void GLWall::RenderTranslucentWall()
{
bool transparent = gltexture? gltexture->GetTransparent() : false;
// currently the only modes possible are solid, additive or translucent
// and until that changes I won't fix this code for the new blending modes!
bool isadditive = RenderStyle == STYLE_Add;
if (gltexture)
{
if (gl_fixedcolormap == CM_DEFAULT && gl_lights && (gl.flags & RFL_BUFFER_STORAGE))
{
SetupLights();
}
if (!transparent) gl_RenderState.AlphaFunc(GL_GEQUAL, gl_mask_threshold);
if (!gltexture->GetTransparent()) gl_RenderState.AlphaFunc(GL_GEQUAL, gl_mask_threshold);
else gl_RenderState.AlphaFunc(GL_GEQUAL, 0.f);
if (isadditive) gl_RenderState.BlendFunc(GL_SRC_ALPHA,GL_ONE);
int extra;
if (gltexture)
{
gl_RenderState.EnableGlow(!!(flags & GLWF_GLOW));
gl_RenderState.SetMaterial(gltexture, flags & 3, 0, -1, false);
extra = getExtraLight();
if (RenderStyle == STYLE_Add) gl_RenderState.BlendFunc(GL_SRC_ALPHA,GL_ONE);
RenderTextured(RWF_TEXTURED | RWF_NOSPLIT);
if (RenderStyle == STYLE_Add) gl_RenderState.BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
}
else
{
gl_RenderState.AlphaFunc(GL_GEQUAL, 0.f);
gl_SetColor(lightlevel, 0, Colormap, fabsf(alpha));
gl_SetFog(lightlevel, 0, &Colormap, RenderStyle == STYLE_Add);
gl_RenderState.EnableTexture(false);
extra = 0;
}
int tmode = gl_RenderState.GetTextureMode();
gl_SetColor(lightlevel, extra, Colormap, fabsf(alpha));
if (type!=RENDERWALL_M2SNF) gl_SetFog(lightlevel, extra, &Colormap, isadditive);
else
{
if (flags & GLT_CLAMPY)
{
if (tmode == TM_MODULATE) gl_RenderState.SetTextureMode(TM_CLAMPY);
}
gl_SetFog(255, 0, NULL, false);
}
RenderWall(RWF_TEXTURED|RWF_NOSPLIT);
// restore default settings
if (isadditive) gl_RenderState.BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
if (!gltexture)
{
RenderWall(RWF_NOSPLIT);
gl_RenderState.EnableTexture(true);
}
gl_RenderState.EnableGlow(false);
gl_RenderState.SetTextureMode(tmode);
}
//==========================================================================
@ -375,17 +400,6 @@ void GLWall::RenderTranslucentWall()
//==========================================================================
void GLWall::Draw(int pass)
{
int rel;
int tmode;
#ifdef _DEBUG
if (seg->linedef-lines==879)
{
int a = 0;
}
#endif
switch (pass)
{
case GLPASS_LIGHTSONLY:
@ -396,28 +410,11 @@ void GLWall::Draw(int pass)
SetupLights();
// fall through
case GLPASS_PLAIN:
rel = rellight + getExtraLight();
gl_SetColor(lightlevel, rel, Colormap,1.0f);
tmode = gl_RenderState.GetTextureMode();
if (type!=RENDERWALL_M2SNF) gl_SetFog(lightlevel, rel, &Colormap, false);
else
{
if (flags & GLT_CLAMPY)
{
if (tmode == TM_MODULATE) gl_RenderState.SetTextureMode(TM_CLAMPY);
}
gl_SetFog(255, 0, NULL, false);
}
gl_RenderState.EnableGlow(!!(flags & GLWF_GLOW));
gl_RenderState.SetMaterial(gltexture, flags & 3, false, -1, false);
RenderWall(RWF_TEXTURED|RWF_GLOW);
gl_RenderState.EnableGlow(false);
gl_RenderState.SetTextureMode(tmode);
RenderTextured(RWF_TEXTURED);
break;
case GLPASS_TRANSLUCENT:
switch (type)
{
case RENDERWALL_MIRRORSURFACE:

View file

@ -216,6 +216,8 @@ bool FShader::Load(const char * name, const char * vert_prog_lump, const char *
muGlowTopColor.Init(hShader, "uGlowTopColor");
muGlowBottomPlane.Init(hShader, "uGlowBottomPlane");
muGlowTopPlane.Init(hShader, "uGlowTopPlane");
muSplitBottomPlane.Init(hShader, "uSplitBottomPlane");
muSplitTopPlane.Init(hShader, "uSplitTopPlane");
muFixedColormap.Init(hShader, "uFixedColormap");
muInterpolationFactor.Init(hShader, "uInterpolationFactor");
muClipHeightTop.Init(hShader, "uClipHeightTop");

View file

@ -218,6 +218,8 @@ class FShader
FUniform4f muGlowTopColor;
FUniform4f muGlowBottomPlane;
FUniform4f muGlowTopPlane;
FUniform4f muSplitBottomPlane;
FUniform4f muSplitTopPlane;
FBufferedUniform1f muInterpolationFactor;
FBufferedUniform1f muClipHeightTop;
FBufferedUniform1f muClipHeightBottom;
@ -233,6 +235,7 @@ public:
int fakevb_index;
private:
int currentglowstate;
int currentsplitstate;
int currentfixedcolormap;
bool currentTextureMatrixState;
bool currentModelMatrixState;
@ -243,6 +246,7 @@ public:
{
hShader = hVertProg = hFragProg = 0;
currentglowstate = 0;
currentsplitstate = 0;
currentfixedcolormap = 0;
currentTextureMatrixState = true; // by setting the matrix state to 'true' it is guaranteed to be set the first time the render state gets applied.
currentModelMatrixState = true;

View file

@ -174,7 +174,7 @@ void gl_LoadExtensions()
void gl_PrintStartupLog()
{
int v = 0;
glGetIntegerv(GL_CONTEXT_PROFILE_MASK, &v);
if (gl.version >= 3.2) glGetIntegerv(GL_CONTEXT_PROFILE_MASK, &v);
Printf ("GL_VENDOR: %s\n", glGetString(GL_VENDOR));
Printf ("GL_RENDERER: %s\n", glGetString(GL_RENDERER));

View file

@ -16,7 +16,7 @@
#include "gl/utility/gl_convert.h"
glcycle_t RenderWall,SetupWall,ClipWall,SplitWall;
glcycle_t RenderWall,SetupWall,ClipWall;
glcycle_t RenderFlat,SetupFlat;
glcycle_t RenderSprite,SetupSprite;
glcycle_t All, Finish, PortalAll, Bsp;
@ -91,7 +91,6 @@ void ResetProfilingData()
ProcessAll.Reset();
RenderWall.Reset();
SetupWall.Reset();
SplitWall.Reset();
ClipWall.Reset();
RenderFlat.Reset();
SetupFlat.Reset();
@ -111,15 +110,15 @@ void ResetProfilingData()
static void AppendRenderTimes(FString &str)
{
double setupwall = SetupWall.TimeMS() - SplitWall.TimeMS();
double setupwall = SetupWall.TimeMS();
double clipwall = ClipWall.TimeMS() - SetupWall.TimeMS();
double bsp = Bsp.TimeMS() - ClipWall.TimeMS() - SetupFlat.TimeMS() - SetupSprite.TimeMS();
str.AppendFormat("W: Render=%2.3f, Split = %2.3f, Setup=%2.3f, Clip=%2.3f\n"
str.AppendFormat("W: Render=%2.3f, Setup=%2.3f, Clip=%2.3f\n"
"F: Render=%2.3f, Setup=%2.3f\n"
"S: Render=%2.3f, Setup=%2.3f\n"
"All=%2.3f, Render=%2.3f, Setup=%2.3f, BSP = %2.3f, Portal=%2.3f, Drawcalls=%2.3f, Finish=%2.3f\n",
RenderWall.TimeMS(), SplitWall.TimeMS(), setupwall, clipwall, RenderFlat.TimeMS(), SetupFlat.TimeMS(),
RenderWall.TimeMS(), setupwall, clipwall, RenderFlat.TimeMS(), SetupFlat.TimeMS(),
RenderSprite.TimeMS(), SetupSprite.TimeMS(), All.TimeMS() + Finish.TimeMS(), RenderAll.TimeMS(),
ProcessAll.TimeMS(), bsp, PortalAll.TimeMS(), drawcalls.TimeMS(), Finish.TimeMS());
}

View file

@ -102,7 +102,7 @@ private:
#endif // __APPLE__
extern glcycle_t RenderWall,SetupWall,ClipWall,SplitWall;
extern glcycle_t RenderWall,SetupWall,ClipWall;
extern glcycle_t RenderFlat,SetupFlat;
extern glcycle_t RenderSprite,SetupSprite;
extern glcycle_t All, Finish, PortalAll, Bsp;

View file

@ -29,6 +29,12 @@ void main()
glowdist.x = -((uGlowTopPlane.w + uGlowTopPlane.x * worldcoord.x + uGlowTopPlane.y * worldcoord.z) * uGlowTopPlane.z) - worldcoord.y;
glowdist.y = worldcoord.y + ((uGlowBottomPlane.w + uGlowBottomPlane.x * worldcoord.x + uGlowBottomPlane.y * worldcoord.z) * uGlowBottomPlane.z);
if (uSplitBottomPlane.z != 0)
{
gl_ClipDistance[3] = -((uSplitTopPlane.w + uSplitTopPlane.x * worldcoord.x + uSplitTopPlane.y * worldcoord.z) * uSplitTopPlane.z) - worldcoord.y;
gl_ClipDistance[4] = worldcoord.y + ((uSplitBottomPlane.w + uSplitBottomPlane.x * worldcoord.x + uSplitBottomPlane.y * worldcoord.z) * uSplitBottomPlane.z);
}
#endif
#ifdef SPHEREMAP
@ -56,4 +62,5 @@ void main()
gl_ClipDistance[1] = worldcoord.y - uClipSplit.x;
gl_ClipDistance[2] = uClipSplit.y - worldcoord.y;
}