mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-28 15:02:01 +00:00
- GLWall is mostly clean, except some smaller things in gl_sky.cpp
This commit is contained in:
parent
937a2cf69f
commit
dd524b046e
32 changed files with 674 additions and 854 deletions
|
@ -1058,6 +1058,7 @@ set (PCH_SOURCES
|
|||
hwrenderer/textures/hw_precache.cpp
|
||||
hwrenderer/utility/hw_clock.cpp
|
||||
hwrenderer/utility/hw_cvars.cpp
|
||||
hwrenderer/utility/hw_lighting.cpp
|
||||
|
||||
menu/joystickmenu.cpp
|
||||
menu/loadsavemenu.cpp
|
||||
|
|
|
@ -495,7 +495,7 @@ bool gl_SetupLightTexture()
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
static bool gl_CheckFog(FColormap *cm, int lightlevel)
|
||||
static bool CheckFog(FColormap *cm, int lightlevel)
|
||||
{
|
||||
bool frontfog;
|
||||
|
||||
|
@ -549,7 +549,7 @@ bool FDrawInfo::PutWallCompat(GLWall *wall, int passflag)
|
|||
if (wall->sub->lighthead == nullptr) return false;
|
||||
}
|
||||
|
||||
bool foggy = gl_CheckFog(&wall->Colormap, wall->lightlevel) || (level.flags&LEVEL_HASFADETABLE) || gl_lights_additive;
|
||||
bool foggy = CheckFog(&wall->Colormap, wall->lightlevel) || (level.flags&LEVEL_HASFADETABLE) || gl_lights_additive;
|
||||
bool masked = passflag == 2 && wall->gltexture->isMasked();
|
||||
|
||||
int list = list_indices[masked][foggy];
|
||||
|
@ -574,7 +574,7 @@ bool GLFlat::PutFlatCompat(bool fog)
|
|||
{ { GLLDL_FLATS_PLAIN, GLLDL_FLATS_FOG },{ GLLDL_FLATS_MASKED, GLLDL_FLATS_FOGMASKED } };
|
||||
|
||||
bool masked = gltexture->isMasked() && ((renderflags&SSRF_RENDER3DPLANES) || stack);
|
||||
bool foggy = gl_CheckFog(&Colormap, lightlevel) || (level.flags&LEVEL_HASFADETABLE) || gl_lights_additive;
|
||||
bool foggy = CheckFog(&Colormap, lightlevel) || (level.flags&LEVEL_HASFADETABLE) || gl_lights_additive;
|
||||
|
||||
|
||||
int list = list_indices[masked][foggy];
|
||||
|
@ -600,7 +600,7 @@ void FDrawInfo::RenderFogBoundaryCompat(GLWall *wall)
|
|||
auto ztop = wall->ztop;
|
||||
auto zbottom = wall->zbottom;
|
||||
|
||||
float fogdensity = gl_GetFogDensity(wall->lightlevel, Colormap.FadeColor, Colormap.FogDensity);
|
||||
float fogdensity = hw_GetFogDensity(wall->lightlevel, Colormap.FadeColor, Colormap.FogDensity);
|
||||
|
||||
float dist1 = Dist2(r_viewpoint.Pos.X, r_viewpoint.Pos.Y, glseg.x1, glseg.y1);
|
||||
float dist2 = Dist2(r_viewpoint.Pos.X, r_viewpoint.Pos.Y, glseg.x2, glseg.y2);
|
||||
|
@ -832,7 +832,7 @@ void FDrawInfo::RenderLightsCompat(GLWall *wall, int pass)
|
|||
if (PrepareLight(wall, light, pass))
|
||||
{
|
||||
wall->vertcount = 0;
|
||||
wall->RenderWall(GLWall::RWF_TEXTURED);
|
||||
RenderWall(wall, GLWall::RWF_TEXTURED);
|
||||
}
|
||||
node = node->nextLight;
|
||||
}
|
||||
|
|
|
@ -28,7 +28,6 @@
|
|||
#include "gl/system/gl_system.h"
|
||||
#include "gl/system/gl_interface.h"
|
||||
#include "hwrenderer/utility/hw_cvars.h"
|
||||
#include "gl/renderer/gl_colormap.h"
|
||||
#include "gl/renderer/gl_lightdata.h"
|
||||
#include "gl/renderer/gl_renderstate.h"
|
||||
#include "gl/shaders/gl_shader.h"
|
||||
|
@ -36,62 +35,6 @@
|
|||
#include "p_local.h"
|
||||
#include "r_sky.h"
|
||||
|
||||
// externally settable lighting properties
|
||||
static float distfogtable[2][256]; // light to fog conversion table for black fog
|
||||
|
||||
CVAR(Int, gl_weaponlight, 8, CVAR_ARCHIVE);
|
||||
CUSTOM_CVAR(Bool, gl_enhanced_nightvision, true, CVAR_ARCHIVE|CVAR_NOINITCALL)
|
||||
{
|
||||
// The fixed colormap state needs to be reset because if this happens when
|
||||
// a shader is set to CM_LITE or CM_TORCH it won't register the change in behavior caused by this CVAR.
|
||||
if (GLRenderer != nullptr && GLRenderer->mShaderManager != nullptr)
|
||||
{
|
||||
GLRenderer->mShaderManager->ResetFixedColormap();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Sets up the fog tables
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
CUSTOM_CVAR (Int, gl_distfog, 70, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
|
||||
{
|
||||
for (int i=0;i<256;i++)
|
||||
{
|
||||
|
||||
if (i<164)
|
||||
{
|
||||
distfogtable[0][i]= (gl_distfog>>1) + (gl_distfog)*(164-i)/164;
|
||||
}
|
||||
else if (i<230)
|
||||
{
|
||||
distfogtable[0][i]= (gl_distfog>>1) - (gl_distfog>>1)*(i-164)/(230-164);
|
||||
}
|
||||
else distfogtable[0][i]=0;
|
||||
|
||||
if (i<128)
|
||||
{
|
||||
distfogtable[1][i]= 6.f + (gl_distfog>>1) + (gl_distfog)*(128-i)/48;
|
||||
}
|
||||
else if (i<216)
|
||||
{
|
||||
distfogtable[1][i]= (216.f-i) / ((216.f-128.f)) * gl_distfog / 10;
|
||||
}
|
||||
else distfogtable[1][i]=0;
|
||||
}
|
||||
}
|
||||
|
||||
CUSTOM_CVAR(Int,gl_fogmode,1,CVAR_ARCHIVE|CVAR_NOINITCALL)
|
||||
{
|
||||
if (self>2) self=2;
|
||||
if (self<0) self=0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -146,79 +89,6 @@ void gl_GetRenderStyle(FRenderStyle style, bool drawopaque, bool allowcolorblend
|
|||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Get current light level
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
int gl_CalcLightLevel(int lightlevel, int rellight, bool weapon)
|
||||
{
|
||||
int light;
|
||||
|
||||
if (lightlevel == 0) return 0;
|
||||
|
||||
if ((level.lightmode & 2) && lightlevel < 192 && !weapon)
|
||||
{
|
||||
if (lightlevel > 100)
|
||||
{
|
||||
light = xs_CRoundToInt(192.f - (192 - lightlevel)* 1.87f);
|
||||
if (light + rellight < 20)
|
||||
{
|
||||
light = 20 + (light + rellight - 20) / 5;
|
||||
}
|
||||
else
|
||||
{
|
||||
light += rellight;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
light = (lightlevel + rellight) / 5;
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
light=lightlevel+rellight;
|
||||
}
|
||||
|
||||
return clamp(light, 0, 255);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Get current light color
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
static PalEntry gl_CalcLightColor(int light, PalEntry pe, int blendfactor)
|
||||
{
|
||||
int r,g,b;
|
||||
|
||||
if (level.lightmode == 8)
|
||||
{
|
||||
return pe;
|
||||
}
|
||||
else if (blendfactor == 0)
|
||||
{
|
||||
r = pe.r * light / 255;
|
||||
g = pe.g * light / 255;
|
||||
b = pe.b * light / 255;
|
||||
}
|
||||
else
|
||||
{
|
||||
// This is what Legacy does with colored light in 3D volumes. No, it doesn't really make sense...
|
||||
// It also doesn't translate well to software style lighting.
|
||||
int mixlight = light * (255 - blendfactor);
|
||||
|
||||
r = (mixlight + pe.r * blendfactor) / 255;
|
||||
g = (mixlight + pe.g * blendfactor) / 255;
|
||||
b = (mixlight + pe.b * blendfactor) / 255;
|
||||
}
|
||||
return PalEntry(255, uint8_t(r), uint8_t(g), uint8_t(b));
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// set current light color
|
||||
|
@ -233,144 +103,13 @@ void gl_SetColor(int sectorlightlevel, int rellight, bool fullbright, const FCol
|
|||
}
|
||||
else
|
||||
{
|
||||
int hwlightlevel = gl_CalcLightLevel(sectorlightlevel, rellight, weapon);
|
||||
PalEntry pe = gl_CalcLightColor(hwlightlevel, cm.LightColor, cm.BlendFactor);
|
||||
int hwlightlevel = hw_CalcLightLevel(sectorlightlevel, rellight, weapon);
|
||||
PalEntry pe = hw_CalcLightColor(hwlightlevel, cm.LightColor, cm.BlendFactor);
|
||||
gl_RenderState.SetColorAlpha(pe, alpha, cm.Desaturation);
|
||||
gl_RenderState.SetSoftLightLevel(gl_ClampLight(sectorlightlevel + rellight));
|
||||
gl_RenderState.SetSoftLightLevel(hw_ClampLight(sectorlightlevel + rellight));
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// calculates the current fog density
|
||||
//
|
||||
// Rules for fog:
|
||||
//
|
||||
// 1. If bit 4 of gl_lightmode is set always use the level's fog density.
|
||||
// This is what Legacy's GL render does.
|
||||
// 2. black fog means no fog and always uses the distfogtable based on the level's fog density setting
|
||||
// 3. If outside fog is defined and the current fog color is the same as the outside fog
|
||||
// the engine always uses the outside fog density to make the fog uniform across the level.
|
||||
// If the outside fog's density is undefined it uses the level's fog density and if that is
|
||||
// not defined it uses a default of 70.
|
||||
// 4. If a global fog density is specified it is being used for all fog on the level
|
||||
// 5. If none of the above apply fog density is based on the light level as for the software renderer.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
float gl_GetFogDensity(int lightlevel, PalEntry fogcolor, int sectorfogdensity)
|
||||
{
|
||||
float density;
|
||||
|
||||
if (level.lightmode & 4)
|
||||
{
|
||||
// uses approximations of Legacy's default settings.
|
||||
density = level.fogdensity ? level.fogdensity : 18;
|
||||
}
|
||||
else if (sectorfogdensity != 0)
|
||||
{
|
||||
// case 1: Sector has an explicit fog density set.
|
||||
density = sectorfogdensity;
|
||||
}
|
||||
else if ((fogcolor.d & 0xffffff) == 0)
|
||||
{
|
||||
// case 2: black fog
|
||||
if (level.lightmode != 8 && !(level.flags3 & LEVEL3_NOLIGHTFADE))
|
||||
{
|
||||
density = distfogtable[level.lightmode != 0][gl_ClampLight(lightlevel)];
|
||||
}
|
||||
else
|
||||
{
|
||||
density = 0;
|
||||
}
|
||||
}
|
||||
else if (level.outsidefogdensity != 0 && APART(level.info->outsidefog) != 0xff && (fogcolor.d & 0xffffff) == (level.info->outsidefog & 0xffffff))
|
||||
{
|
||||
// case 3. outsidefogdensity has already been set as needed
|
||||
density = level.outsidefogdensity;
|
||||
}
|
||||
else if (level.fogdensity != 0)
|
||||
{
|
||||
// case 4: level has fog density set
|
||||
density = level.fogdensity;
|
||||
}
|
||||
else if (lightlevel < 248)
|
||||
{
|
||||
// case 5: use light level
|
||||
density = clamp<int>(255 - lightlevel, 30, 255);
|
||||
}
|
||||
else
|
||||
{
|
||||
density = 0.f;
|
||||
}
|
||||
return density;
|
||||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Check if the current linedef is a candidate for a fog boundary
|
||||
//
|
||||
// Requirements for a fog boundary:
|
||||
// - front sector has no fog
|
||||
// - back sector has fog
|
||||
// - at least one of both does not have a sky ceiling.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
bool gl_CheckFog(sector_t *frontsector, sector_t *backsector)
|
||||
{
|
||||
if (frontsector == backsector) return false; // there can't be a boundary if both sides are in the same sector.
|
||||
|
||||
// Check for fog boundaries. This needs a few more checks for the sectors
|
||||
|
||||
PalEntry fogcolor = frontsector->Colormap.FadeColor;
|
||||
|
||||
if ((fogcolor.d & 0xffffff) == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else if (fogcolor.a != 0)
|
||||
{
|
||||
}
|
||||
else if (level.outsidefogdensity != 0 && APART(level.info->outsidefog) != 0xff && (fogcolor.d & 0xffffff) == (level.info->outsidefog & 0xffffff))
|
||||
{
|
||||
}
|
||||
else if (level.fogdensity!=0 || (level.lightmode & 4))
|
||||
{
|
||||
// case 3: level has fog density set
|
||||
}
|
||||
else
|
||||
{
|
||||
// case 4: use light level
|
||||
if (frontsector->lightlevel >= 248) return false;
|
||||
}
|
||||
|
||||
fogcolor = backsector->Colormap.FadeColor;
|
||||
|
||||
if ((fogcolor.d & 0xffffff) == 0)
|
||||
{
|
||||
}
|
||||
else if (level.outsidefogdensity != 0 && APART(level.info->outsidefog) != 0xff && (fogcolor.d & 0xffffff) == (level.info->outsidefog & 0xffffff))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else if (level.fogdensity!=0 || (level.lightmode & 4))
|
||||
{
|
||||
// case 3: level has fog density set
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
// case 4: use light level
|
||||
if (backsector->lightlevel < 248) return false;
|
||||
}
|
||||
|
||||
// in all other cases this might create more problems than it solves.
|
||||
return ((frontsector->GetTexture(sector_t::ceiling)!=skyflatnum ||
|
||||
backsector->GetTexture(sector_t::ceiling)!=skyflatnum));
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Lighting stuff
|
||||
|
@ -424,7 +163,7 @@ void gl_SetFog(int lightlevel, int rellight, bool fullbright, const FColormap *c
|
|||
else if (cmap != NULL && !fullbright)
|
||||
{
|
||||
fogcolor = cmap->FadeColor;
|
||||
fogdensity = gl_GetFogDensity(lightlevel, fogcolor, cmap->FogDensity);
|
||||
fogdensity = hw_GetFogDensity(lightlevel, fogcolor, cmap->FogDensity);
|
||||
fogcolor.a=0;
|
||||
}
|
||||
else
|
||||
|
@ -447,7 +186,7 @@ void gl_SetFog(int lightlevel, int rellight, bool fullbright, const FColormap *c
|
|||
{
|
||||
if (level.lightmode == 2 && fogcolor == 0)
|
||||
{
|
||||
float light = gl_CalcLightLevel(lightlevel, rellight, false);
|
||||
float light = hw_CalcLightLevel(lightlevel, rellight, false);
|
||||
gl_SetShaderLight(light, lightlevel);
|
||||
}
|
||||
else
|
||||
|
|
|
@ -4,23 +4,13 @@
|
|||
#include "v_palette.h"
|
||||
#include "p_3dfloors.h"
|
||||
#include "r_data/renderstyle.h"
|
||||
#include "gl/renderer/gl_colormap.h"
|
||||
|
||||
inline int gl_ClampLight(int lightlevel)
|
||||
{
|
||||
return clamp(lightlevel, 0, 255);
|
||||
}
|
||||
#include "hwrenderer/utility/hw_lighting.h"
|
||||
#include "r_data/colormaps.h"
|
||||
|
||||
void gl_GetRenderStyle(FRenderStyle style, bool drawopaque, bool allowcolorblending,
|
||||
int *tm, int *sb, int *db, int *be);
|
||||
|
||||
int gl_CalcLightLevel(int lightlevel, int rellight, bool weapon);
|
||||
void gl_SetColor(int light, int rellight, bool fullbright, const FColormap &cm, float alpha, bool weapon=false);
|
||||
|
||||
float gl_GetFogDensity(int lightlevel, PalEntry fogcolor, int sectorfogdensity);
|
||||
struct sector_t;
|
||||
bool gl_CheckFog(sector_t *frontsector, sector_t *backsector);
|
||||
|
||||
void gl_SetFog(int lightlevel, int rellight, bool fullbright, const FColormap *cm, bool isadditive);
|
||||
|
||||
|
||||
|
|
|
@ -27,13 +27,13 @@
|
|||
|
||||
#include "templates.h"
|
||||
#include "doomstat.h"
|
||||
#include "r_data/colormaps.h"
|
||||
#include "gl/system/gl_system.h"
|
||||
#include "gl/system/gl_interface.h"
|
||||
#include "gl/data/gl_vertexbuffer.h"
|
||||
#include "hwrenderer/utility/hw_cvars.h"
|
||||
#include "gl/shaders/gl_shader.h"
|
||||
#include "gl/renderer/gl_renderer.h"
|
||||
#include "gl/renderer/gl_colormap.h"
|
||||
#include "gl/dynlights//gl_lightbuffer.h"
|
||||
#include "gl/renderer/gl_renderbuffers.h"
|
||||
|
||||
|
|
|
@ -166,7 +166,7 @@ void GLSceneDrawer::AddLine (seg_t *seg, bool portalclip)
|
|||
{
|
||||
SetupWall.Clock();
|
||||
|
||||
GLWall wall(this);
|
||||
GLWall wall;
|
||||
wall.sub = currentsubsector;
|
||||
wall.Process(gl_drawinfo, seg, currentsector, backsector);
|
||||
rendered_lines++;
|
||||
|
|
|
@ -339,7 +339,7 @@ void FDrawInfo::DrawDecal(GLWall *wall, DBaseDecal *decal)
|
|||
|
||||
if (low1 < dv[1].z || low2 < dv[2].z)
|
||||
{
|
||||
int thisll = lightlist[k].caster != NULL ? gl_ClampLight(*lightlist[k].p_lightlevel) : wall->lightlevel;
|
||||
int thisll = lightlist[k].caster != NULL ? hw_ClampLight(*lightlist[k].p_lightlevel) : wall->lightlevel;
|
||||
FColormap thiscm;
|
||||
thiscm.FadeColor = wall->Colormap.FadeColor;
|
||||
thiscm.CopyFrom3DLight(&lightlist[k]);
|
||||
|
|
|
@ -717,7 +717,7 @@ void GLDrawList::DoDraw(int pass, int i, bool trans)
|
|||
{
|
||||
GLWall * w= walls[drawitems[i].index];
|
||||
RenderWall.Clock();
|
||||
w->Draw(pass);
|
||||
gl_drawinfo->DrawWall(w, pass);
|
||||
RenderWall.Unclock();
|
||||
}
|
||||
break;
|
||||
|
@ -845,9 +845,9 @@ void GLDrawList::Draw(int pass, bool trans)
|
|||
void GLDrawList::DrawWalls(int pass)
|
||||
{
|
||||
RenderWall.Clock();
|
||||
for(unsigned i=0;i<drawitems.Size();i++)
|
||||
for(auto &item : drawitems)
|
||||
{
|
||||
walls[drawitems[i].index]->Draw(pass);
|
||||
gl_drawinfo->DrawWall(walls[item.index], pass);
|
||||
}
|
||||
RenderWall.Unclock();
|
||||
}
|
||||
|
@ -1305,7 +1305,7 @@ void FDrawInfo::ProcessLowerMinisegs(TArray<seg_t *> &lowersegs)
|
|||
for(unsigned int j=0;j<lowersegs.Size();j++)
|
||||
{
|
||||
seg_t * seg=lowersegs[j];
|
||||
GLWall wall(mDrawer);
|
||||
GLWall wall;
|
||||
wall.ProcessLowerMiniseg(this, seg, seg->Subsector->render_sector, seg->PartnerSeg->Subsector->render_sector);
|
||||
rendered_lines++;
|
||||
}
|
||||
|
|
|
@ -179,6 +179,8 @@ struct FDrawInfo : public HWDrawInfo
|
|||
|
||||
void AddWall(GLWall *wall) override;
|
||||
void AddMirrorSurface(GLWall *w) override;
|
||||
void AddPortal(GLWall *w, int portaltype) override;
|
||||
|
||||
void ProcessActorsInPortal(FLinePortalSpan *glport) override;
|
||||
std::pair<FFlatVertex *, unsigned int> AllocVertices(unsigned int count) override;
|
||||
|
||||
|
@ -197,6 +199,15 @@ struct FDrawInfo : public HWDrawInfo
|
|||
void DrawFloodedPlane(wallseg * ws, float planez, sector_t * sec, bool ceiling);
|
||||
void FloodUpperGap(seg_t * seg) override;
|
||||
void FloodLowerGap(seg_t * seg) override;
|
||||
|
||||
// Wall drawer
|
||||
void RenderWall(GLWall *wall, int textured);
|
||||
void RenderFogBoundary(GLWall *wall);
|
||||
void RenderMirrorSurface(GLWall *wall);
|
||||
void RenderTranslucentWall(GLWall *wall);
|
||||
void RenderTexturedWall(GLWall *wall, int rflags);
|
||||
void DrawWall(GLWall *wall, int pass);
|
||||
|
||||
|
||||
// These two may be moved to the API independent part of the renderer later.
|
||||
void ProcessLowerMinisegs(TArray<seg_t *> &lowersegs) override;
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
#include "d_player.h"
|
||||
#include "g_levellocals.h"
|
||||
#include "actorinlines.h"
|
||||
#include "p_lnspec.h"
|
||||
#include "hwrenderer/dynlights/hw_dynlightdata.h"
|
||||
|
||||
#include "gl/system/gl_interface.h"
|
||||
|
@ -543,7 +544,7 @@ void GLFlat::SetFrom3DFloor(F3DFloor *rover, bool top, bool underside)
|
|||
|
||||
// FF_FOG requires an inverted logic where to get the light from
|
||||
lightlist_t *light = P_GetPlaneLight(sector, plane.plane, underside);
|
||||
lightlevel = gl_ClampLight(*light->p_lightlevel);
|
||||
lightlevel = hw_ClampLight(*light->p_lightlevel);
|
||||
|
||||
if (rover->flags & FF_FOG)
|
||||
{
|
||||
|
@ -609,7 +610,7 @@ void GLFlat::ProcessSector(sector_t * frontsector)
|
|||
|
||||
srf |= SSRF_RENDERFLOOR;
|
||||
|
||||
lightlevel = gl_ClampLight(frontsector->GetFloorLight());
|
||||
lightlevel = hw_ClampLight(frontsector->GetFloorLight());
|
||||
Colormap = frontsector->Colormap;
|
||||
FlatColor = frontsector->SpecialColors[sector_t::floor];
|
||||
port = frontsector->ValidatePortal(sector_t::floor);
|
||||
|
@ -646,7 +647,7 @@ void GLFlat::ProcessSector(sector_t * frontsector)
|
|||
if ((!(sector->GetFlags(sector_t::floor)&PLANEF_ABSLIGHTING) || light->lightsource == NULL)
|
||||
&& (light->p_lightlevel != &frontsector->lightlevel))
|
||||
{
|
||||
lightlevel = gl_ClampLight(*light->p_lightlevel);
|
||||
lightlevel = hw_ClampLight(*light->p_lightlevel);
|
||||
}
|
||||
|
||||
Colormap.CopyFrom3DLight(light);
|
||||
|
@ -669,7 +670,7 @@ void GLFlat::ProcessSector(sector_t * frontsector)
|
|||
|
||||
srf |= SSRF_RENDERCEILING;
|
||||
|
||||
lightlevel = gl_ClampLight(frontsector->GetCeilingLight());
|
||||
lightlevel = hw_ClampLight(frontsector->GetCeilingLight());
|
||||
Colormap = frontsector->Colormap;
|
||||
FlatColor = frontsector->SpecialColors[sector_t::ceiling];
|
||||
port = frontsector->ValidatePortal(sector_t::ceiling);
|
||||
|
@ -707,7 +708,7 @@ void GLFlat::ProcessSector(sector_t * frontsector)
|
|||
if ((!(sector->GetFlags(sector_t::ceiling)&PLANEF_ABSLIGHTING))
|
||||
&& (light->p_lightlevel != &frontsector->lightlevel))
|
||||
{
|
||||
lightlevel = gl_ClampLight(*light->p_lightlevel);
|
||||
lightlevel = hw_ClampLight(*light->p_lightlevel);
|
||||
}
|
||||
Colormap.CopyFrom3DLight(light);
|
||||
}
|
||||
|
@ -801,7 +802,7 @@ void GLFlat::ProcessSector(sector_t * frontsector)
|
|||
|
||||
if (rover->flags&FF_FIX)
|
||||
{
|
||||
lightlevel = gl_ClampLight(rover->model->lightlevel);
|
||||
lightlevel = hw_ClampLight(rover->model->lightlevel);
|
||||
Colormap = rover->GetColormap();
|
||||
}
|
||||
|
||||
|
|
|
@ -1240,7 +1240,7 @@ void GLEEHorizonPortal::DrawContents()
|
|||
{
|
||||
GLHorizonInfo horz;
|
||||
horz.plane.GetFromSector(sector, sector_t::ceiling);
|
||||
horz.lightlevel = gl_ClampLight(sector->GetCeilingLight());
|
||||
horz.lightlevel = hw_ClampLight(sector->GetCeilingLight());
|
||||
horz.colormap = sector->Colormap;
|
||||
horz.specialcolor = 0xffffffff;
|
||||
if (portal->mType == PORTS_PLANE)
|
||||
|
@ -1254,7 +1254,7 @@ void GLEEHorizonPortal::DrawContents()
|
|||
{
|
||||
GLHorizonInfo horz;
|
||||
horz.plane.GetFromSector(sector, sector_t::floor);
|
||||
horz.lightlevel = gl_ClampLight(sector->GetFloorLight());
|
||||
horz.lightlevel = hw_ClampLight(sector->GetFloorLight());
|
||||
horz.colormap = sector->Colormap;
|
||||
horz.specialcolor = 0xffffffff;
|
||||
if (portal->mType == PORTS_PLANE)
|
||||
|
|
|
@ -40,36 +40,8 @@
|
|||
#include "actor.h"
|
||||
#include "gl/renderer/gl_renderer.h"
|
||||
#include "gl/scene/gl_drawinfo.h"
|
||||
|
||||
struct GLHorizonInfo
|
||||
{
|
||||
GLSectorPlane plane;
|
||||
int lightlevel;
|
||||
FColormap colormap;
|
||||
PalEntry specialcolor;
|
||||
};
|
||||
|
||||
struct GLSkyInfo
|
||||
{
|
||||
float x_offset[2];
|
||||
float y_offset; // doubleskies don't have a y-offset
|
||||
FMaterial * texture[2];
|
||||
FTextureID skytexno1;
|
||||
bool mirrored;
|
||||
bool doublesky;
|
||||
bool sky2;
|
||||
PalEntry fadecolor; // if this isn't made part of the dome things will become more complicated when sky fog is used.
|
||||
|
||||
bool operator==(const GLSkyInfo & inf)
|
||||
{
|
||||
return !memcmp(this, &inf, sizeof(*this));
|
||||
}
|
||||
bool operator!=(const GLSkyInfo & inf)
|
||||
{
|
||||
return !!memcmp(this, &inf, sizeof(*this));
|
||||
}
|
||||
void init(int sky1, PalEntry fadecolor);
|
||||
};
|
||||
#include "hwrenderer/scene/hw_drawstructs.h"
|
||||
#include "hwrenderer/scene/hw_portal.h"
|
||||
|
||||
extern UniqueList<GLSkyInfo> UniqueSkies;
|
||||
extern UniqueList<GLHorizonInfo> UniqueHorizons;
|
||||
|
|
|
@ -100,7 +100,7 @@ public:
|
|||
bool CheckFog(sector_t *frontsector, sector_t *backsector)
|
||||
{
|
||||
if (FixedColormap != CM_DEFAULT) return false;
|
||||
return gl_CheckFog(frontsector, backsector);
|
||||
return hw_CheckFog(frontsector, backsector);
|
||||
}
|
||||
|
||||
void SetFog(int lightlevel, int rellight, const FColormap *cmap, bool isadditive)
|
||||
|
|
|
@ -26,12 +26,16 @@
|
|||
#include "r_utility.h"
|
||||
#include "doomdata.h"
|
||||
#include "g_levellocals.h"
|
||||
|
||||
#include "gl/renderer/gl_lightdata.h"
|
||||
#include "gl/scene/gl_drawinfo.h"
|
||||
#include "gl/scene/gl_portal.h"
|
||||
#include "p_lnspec.h"
|
||||
#include "hwrenderer/scene/hw_drawinfo.h"
|
||||
#include "hwrenderer/scene/hw_drawstructs.h"
|
||||
#include "hwrenderer/scene/hw_portal.h"
|
||||
#include "hwrenderer/utility/hw_lighting.h"
|
||||
#include "hwrenderer/textures/hw_material.h"
|
||||
|
||||
#include "gl/renderer/gl_renderer.h"
|
||||
#include "gl/scene/gl_portal.h"
|
||||
|
||||
CVAR(Bool,gl_noskyboxes, false, 0)
|
||||
|
||||
//==========================================================================
|
||||
|
|
|
@ -310,7 +310,7 @@ void GLSprite::Draw(int pass)
|
|||
if (!Colormap.FadeColor.isBlack())
|
||||
{
|
||||
float dist=Dist2(r_viewpoint.Pos.X, r_viewpoint.Pos.Y, x,y);
|
||||
int fogd = gl_GetFogDensity(lightlevel, Colormap.FadeColor, Colormap.FogDensity);
|
||||
int fogd = hw_GetFogDensity(lightlevel, Colormap.FadeColor, Colormap.FogDensity);
|
||||
|
||||
// this value was determined by trial and error and is scale dependent!
|
||||
float factor = 0.05f + exp(-fogd*dist / 62500.f);
|
||||
|
@ -414,7 +414,7 @@ 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 ? gl_ClampLight(*(*lightlist)[i].p_lightlevel) : lightlevel;
|
||||
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));
|
||||
|
||||
FColormap thiscm;
|
||||
|
@ -545,7 +545,7 @@ void GLSprite::SplitSprite(sector_t * frontsector, bool translucent)
|
|||
if (lightbottom<z1)
|
||||
{
|
||||
copySprite=*this;
|
||||
copySprite.lightlevel = gl_ClampLight(*lightlist[i].p_lightlevel);
|
||||
copySprite.lightlevel = hw_ClampLight(*lightlist[i].p_lightlevel);
|
||||
copySprite.Colormap.CopyLight(lightlist[i].extra_colormap);
|
||||
|
||||
if (level.flags3 & LEVEL3_NOCOLOREDSPRITELIGHTING)
|
||||
|
@ -936,7 +936,7 @@ void GLSprite::Process(AActor* thing, sector_t * sector, int thruportal)
|
|||
((thing->renderflags & RF_FULLBRIGHT) && (!gltexture || !gltexture->tex->bDisableFullbright));
|
||||
|
||||
lightlevel = fullbright ? 255 :
|
||||
gl_ClampLight(rendersector->GetTexture(sector_t::ceiling) == skyflatnum ?
|
||||
hw_ClampLight(rendersector->GetTexture(sector_t::ceiling) == skyflatnum ?
|
||||
rendersector->GetCeilingLight() : rendersector->GetFloorLight());
|
||||
foglevel = (uint8_t)clamp<short>(rendersector->lightlevel, 0, 255);
|
||||
|
||||
|
@ -1146,7 +1146,7 @@ void GLSprite::ProcessParticle (particle_t *particle, sector_t *sector)//, int s
|
|||
|
||||
if (particle->alpha==0) return;
|
||||
|
||||
lightlevel = gl_ClampLight(sector->GetTexture(sector_t::ceiling) == skyflatnum ?
|
||||
lightlevel = hw_ClampLight(sector->GetTexture(sector_t::ceiling) == skyflatnum ?
|
||||
sector->GetCeilingLight() : sector->GetFloorLight());
|
||||
foglevel = (uint8_t)clamp<short>(sector->lightlevel, 0, 255);
|
||||
|
||||
|
@ -1167,7 +1167,7 @@ void GLSprite::ProcessParticle (particle_t *particle, sector_t *sector)//, int s
|
|||
|
||||
if (lightbottom < particle->Pos.Z)
|
||||
{
|
||||
lightlevel = gl_ClampLight(*lightlist[i].p_lightlevel);
|
||||
lightlevel = hw_ClampLight(*lightlist[i].p_lightlevel);
|
||||
Colormap.CopyLight(lightlist[i].extra_colormap);
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
#include "r_defs.h"
|
||||
#include "hwrenderer/data/flatvertices.h"
|
||||
#include "hwrenderer/scene/hw_drawinfo.h"
|
||||
#include "gl/scene/gl_wall.h"
|
||||
#include "hwrenderer/scene/hw_drawstructs.h"
|
||||
|
||||
EXTERN_CVAR(Bool, gl_seamless)
|
||||
|
||||
|
|
|
@ -8,7 +8,8 @@
|
|||
#include "r_defs.h"
|
||||
#include "r_data/renderstyle.h"
|
||||
#include "textures/textures.h"
|
||||
#include "gl/renderer/gl_colormap.h"
|
||||
#include "r_data/colormaps.h"
|
||||
#include "hwrenderer/scene/hw_drawstructs.h"
|
||||
|
||||
#pragma warning(disable:4244)
|
||||
|
||||
|
@ -28,286 +29,9 @@ struct FLinePortalSpan;
|
|||
class GLSceneDrawer;
|
||||
struct FDynLightData;
|
||||
|
||||
enum
|
||||
{
|
||||
GLSector_NoSkyDraw = 89,
|
||||
GLSector_Skybox = 90,
|
||||
};
|
||||
|
||||
enum WallTypes
|
||||
{
|
||||
RENDERWALL_NONE,
|
||||
RENDERWALL_TOP,
|
||||
RENDERWALL_M1S,
|
||||
RENDERWALL_M2S,
|
||||
RENDERWALL_BOTTOM,
|
||||
RENDERWALL_FOGBOUNDARY,
|
||||
RENDERWALL_MIRRORSURFACE,
|
||||
RENDERWALL_M2SNF,
|
||||
RENDERWALL_COLOR,
|
||||
RENDERWALL_FFBLOCK,
|
||||
// Insert new types at the end!
|
||||
};
|
||||
|
||||
enum PortalTypes
|
||||
{
|
||||
PORTALTYPE_SKY,
|
||||
PORTALTYPE_HORIZON,
|
||||
PORTALTYPE_SKYBOX,
|
||||
PORTALTYPE_SECTORSTACK,
|
||||
PORTALTYPE_PLANEMIRROR,
|
||||
PORTALTYPE_MIRROR,
|
||||
PORTALTYPE_LINETOLINE,
|
||||
};
|
||||
|
||||
struct GLSeg
|
||||
{
|
||||
float x1,x2;
|
||||
float y1,y2;
|
||||
float fracleft, fracright; // fractional offset of the 2 vertices on the linedef
|
||||
|
||||
FVector3 Normal() const
|
||||
{
|
||||
// we do not use the vector math inlines here because they are not optimized for speed but accuracy in the playsim and this is called quite frequently.
|
||||
float x = y2 - y1;
|
||||
float y = x1 - x2;
|
||||
float ilength = 1.f / sqrtf(x*x + y*y);
|
||||
return FVector3(x * ilength, 0, y * ilength);
|
||||
}
|
||||
};
|
||||
|
||||
struct texcoord
|
||||
{
|
||||
float u,v;
|
||||
};
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// One sector plane, still in fixed point
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
struct GLSectorPlane
|
||||
{
|
||||
FTextureID texture;
|
||||
secplane_t plane;
|
||||
float Texheight;
|
||||
float Angle;
|
||||
FVector2 Offs;
|
||||
FVector2 Scale;
|
||||
|
||||
void GetFromSector(sector_t * sec, int ceiling)
|
||||
{
|
||||
Offs.X = (float)sec->GetXOffset(ceiling);
|
||||
Offs.Y = (float)sec->GetYOffset(ceiling);
|
||||
Scale.X = (float)sec->GetXScale(ceiling);
|
||||
Scale.Y = (float)sec->GetYScale(ceiling);
|
||||
Angle = (float)sec->GetAngle(ceiling).Degrees;
|
||||
texture = sec->GetTexture(ceiling);
|
||||
plane = sec->GetSecPlane(ceiling);
|
||||
Texheight = (float)((ceiling == sector_t::ceiling)? plane.fD() : -plane.fD());
|
||||
}
|
||||
};
|
||||
|
||||
struct FDrawInfo;
|
||||
struct HWDrawInfo;
|
||||
|
||||
class GLWall
|
||||
{
|
||||
friend struct FDrawInfo;
|
||||
public:
|
||||
static const char passflag[];
|
||||
|
||||
enum
|
||||
{
|
||||
GLWF_CLAMPX=1,
|
||||
GLWF_CLAMPY=2,
|
||||
GLWF_SKYHACK=4,
|
||||
GLWF_GLOW=8, // illuminated by glowing flats
|
||||
GLWF_NOSPLITUPPER=16,
|
||||
GLWF_NOSPLITLOWER=32,
|
||||
GLWF_NOSPLIT=64,
|
||||
GLWF_TRANSLUCENT = 128
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
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_NOSPLIT = 4,
|
||||
RWF_NORENDER = 8,
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
LOLFT,
|
||||
UPLFT,
|
||||
UPRGT,
|
||||
LORGT,
|
||||
};
|
||||
|
||||
friend struct GLDrawList;
|
||||
friend class GLPortal;
|
||||
|
||||
GLSceneDrawer *mDrawer;
|
||||
vertex_t * vertexes[2]; // required for polygon splitting
|
||||
FMaterial *gltexture;
|
||||
TArray<lightlist_t> *lightlist;
|
||||
|
||||
GLSeg glseg;
|
||||
float ztop[2],zbottom[2];
|
||||
texcoord tcs[4];
|
||||
float alpha;
|
||||
|
||||
FColormap Colormap;
|
||||
ERenderStyle RenderStyle;
|
||||
|
||||
float ViewDistance;
|
||||
|
||||
int lightlevel;
|
||||
uint8_t type;
|
||||
uint8_t flags;
|
||||
short rellight;
|
||||
|
||||
float topglowcolor[4];
|
||||
float bottomglowcolor[4];
|
||||
|
||||
int dynlightindex;
|
||||
|
||||
union
|
||||
{
|
||||
// it's either one of them but never more!
|
||||
FSectorPortal *secportal; // sector portal (formerly skybox)
|
||||
GLSkyInfo * sky; // for normal sky
|
||||
GLHorizonInfo * horizon; // for horizon information
|
||||
FSectorPortalGroup * portal; // stacked sector portals
|
||||
secplane_t * planemirror; // for plane mirrors
|
||||
FLinePortalSpan *lineportal; // line-to-line portals
|
||||
};
|
||||
|
||||
|
||||
secplane_t topplane, bottomplane; // we need to save these to pass them to the shader for calculating glows.
|
||||
|
||||
// these are not the same as ytop and ybottom!!!
|
||||
float zceil[2];
|
||||
float zfloor[2];
|
||||
|
||||
unsigned int vertindex;
|
||||
unsigned int vertcount;
|
||||
|
||||
public:
|
||||
seg_t * seg; // this gives the easiest access to all other structs involved
|
||||
subsector_t * sub; // For polyobjects
|
||||
private:
|
||||
|
||||
void CheckGlowing();
|
||||
bool PutWallCompat(int passflag);
|
||||
void PutWall(HWDrawInfo *di, bool translucent);
|
||||
void PutPortal(HWDrawInfo *di, int ptype);
|
||||
void CheckTexturePosition(FTexCoordInfo *tci);
|
||||
|
||||
void Put3DWall(HWDrawInfo *di, lightlist_t * lightlist, bool translucent);
|
||||
bool SplitWallComplex(HWDrawInfo *di, sector_t * frontsector, bool translucent, float& maplightbottomleft, float& maplightbottomright);
|
||||
void SplitWall(HWDrawInfo *di, sector_t * frontsector, bool translucent);
|
||||
|
||||
bool SetupLights(FDynLightData &lightdata);
|
||||
void RenderWall(int textured);
|
||||
void RenderTextured(int rflags);
|
||||
|
||||
void FloodPlane(int pass);
|
||||
|
||||
void MakeVertices(HWDrawInfo *di, bool nosplit);
|
||||
|
||||
void SkyPlane(HWDrawInfo *di, sector_t *sector, int plane, bool allowmirror);
|
||||
void SkyLine(HWDrawInfo *di, sector_t *sec, line_t *line);
|
||||
void SkyNormal(HWDrawInfo *di, sector_t * fs,vertex_t * v1,vertex_t * v2);
|
||||
void SkyTop(HWDrawInfo *di, seg_t * seg,sector_t * fs,sector_t * bs,vertex_t * v1,vertex_t * v2);
|
||||
void SkyBottom(HWDrawInfo *di, seg_t * seg,sector_t * fs,sector_t * bs,vertex_t * v1,vertex_t * v2);
|
||||
|
||||
void LightPass();
|
||||
bool DoHorizon(HWDrawInfo *di, seg_t * seg,sector_t * fs, vertex_t * v1,vertex_t * v2);
|
||||
|
||||
bool SetWallCoordinates(seg_t * seg, FTexCoordInfo *tci, float ceilingrefheight,
|
||||
float topleft, float topright, float bottomleft, float bottomright, float t_ofs);
|
||||
|
||||
void DoTexture(HWDrawInfo *di, int type,seg_t * seg,int peg,
|
||||
float ceilingrefheight, float floorrefheight,
|
||||
float CeilingHeightstart,float CeilingHeightend,
|
||||
float FloorHeightstart,float FloorHeightend,
|
||||
float v_offset);
|
||||
|
||||
void DoMidTexture(HWDrawInfo *di, seg_t * seg, bool drawfogboundary,
|
||||
sector_t * front, sector_t * back,
|
||||
sector_t * realfront, sector_t * realback,
|
||||
float fch1, float fch2, float ffh1, float ffh2,
|
||||
float bch1, float bch2, float bfh1, float bfh2);
|
||||
|
||||
void GetPlanePos(F3DFloor::planeref * planeref, float & left, float & right);
|
||||
|
||||
void BuildFFBlock(HWDrawInfo *di, seg_t * seg, F3DFloor * rover,
|
||||
float ff_topleft, float ff_topright,
|
||||
float ff_bottomleft, float ff_bottomright);
|
||||
void InverseFloors(HWDrawInfo *di, seg_t * seg, sector_t * frontsector,
|
||||
float topleft, float topright,
|
||||
float bottomleft, float bottomright);
|
||||
void ClipFFloors(HWDrawInfo *di, seg_t * seg, F3DFloor * ffloor, sector_t * frontsector,
|
||||
float topleft, float topright,
|
||||
float bottomleft, float bottomright);
|
||||
void DoFFloorBlocks(HWDrawInfo *di, seg_t * seg, sector_t * frontsector, sector_t * backsector,
|
||||
float fch1, float fch2, float ffh1, float ffh2,
|
||||
float bch1, float bch2, float bfh1, float bfh2);
|
||||
|
||||
void RenderFogBoundary();
|
||||
void RenderMirrorSurface();
|
||||
void RenderTranslucentWall();
|
||||
|
||||
void CreateVertices(FFlatVertex *&ptr, bool nosplit);
|
||||
void SplitLeftEdge (FFlatVertex *&ptr);
|
||||
void SplitRightEdge(FFlatVertex *&ptr);
|
||||
void SplitUpperEdge(FFlatVertex *&ptr);
|
||||
void SplitLowerEdge(FFlatVertex *&ptr);
|
||||
|
||||
int CountVertices();
|
||||
|
||||
public:
|
||||
|
||||
GLWall(GLSceneDrawer *drawer)
|
||||
{
|
||||
mDrawer = drawer;
|
||||
}
|
||||
|
||||
GLWall(const GLWall &other)
|
||||
{
|
||||
memcpy(this, &other, sizeof(GLWall));
|
||||
}
|
||||
|
||||
GLWall & operator=(const GLWall &other)
|
||||
{
|
||||
memcpy(this, &other, sizeof(GLWall));
|
||||
return *this;
|
||||
}
|
||||
|
||||
void Process(HWDrawInfo *di, seg_t *seg, sector_t *frontsector, sector_t *backsector);
|
||||
void ProcessLowerMiniseg(HWDrawInfo *di, seg_t *seg, sector_t *frontsector, sector_t *backsector);
|
||||
void Draw(int pass);
|
||||
|
||||
float PointOnSide(float x,float y)
|
||||
{
|
||||
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));
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// One flat plane in the draw list
|
||||
|
@ -455,11 +179,6 @@ public:
|
|||
|
||||
};
|
||||
|
||||
inline float Dist2(float x1,float y1,float x2,float y2)
|
||||
{
|
||||
return sqrtf((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
|
||||
}
|
||||
|
||||
// Light + color
|
||||
|
||||
void gl_SetDynSpriteLight(AActor *self, float x, float y, float z, subsector_t *subsec);
|
||||
|
|
|
@ -31,61 +31,14 @@
|
|||
#include "g_levellocals.h"
|
||||
#include "hwrenderer/dynlights/hw_dynlightdata.h"
|
||||
#include "hwrenderer/textures/hw_material.h"
|
||||
|
||||
#include "gl/renderer/gl_lightdata.h"
|
||||
#include "hwrenderer/utility/hw_cvars.h"
|
||||
#include "gl/system/gl_interface.h"
|
||||
|
||||
#include "gl/scene/gl_drawinfo.h"
|
||||
#include "gl/scene/gl_portal.h"
|
||||
|
||||
#include "hwrenderer/utility/hw_clock.h"
|
||||
#include "hwrenderer/utility/hw_lighting.h"
|
||||
#include "hwrenderer/scene/hw_drawinfo.h"
|
||||
#include "hwrenderer/scene/hw_drawstructs.h"
|
||||
#include "hwrenderer/scene/hw_portal.h"
|
||||
|
||||
|
||||
void FDrawInfo::AddWall(GLWall *wall)
|
||||
{
|
||||
bool translucent = !!(wall->flags & GLWall::GLWF_TRANSLUCENT);
|
||||
int list;
|
||||
|
||||
if (translucent) // translucent walls
|
||||
{
|
||||
wall->ViewDistance = (r_viewpoint.Pos - (wall->seg->linedef->v1->fPos() + wall->seg->linedef->Delta() / 2)).XY().LengthSquared();
|
||||
wall->MakeVertices(this, true);
|
||||
auto newwall = drawlists[GLDL_TRANSLUCENT].NewWall();
|
||||
*newwall = *wall;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (gl.legacyMode)
|
||||
{
|
||||
if (PutWallCompat(wall, GLWall::passflag[wall->type])) return;
|
||||
}
|
||||
|
||||
bool masked;
|
||||
|
||||
masked = GLWall::passflag[wall->type] == 1 ? false : (wall->gltexture && wall->gltexture->isMasked());
|
||||
|
||||
if ((wall->flags & GLWall::GLWF_SKYHACK && wall->type == RENDERWALL_M2S))
|
||||
{
|
||||
list = GLDL_MASKEDWALLSOFS;
|
||||
}
|
||||
else
|
||||
{
|
||||
list = masked ? GLDL_MASKEDWALLS : GLDL_PLAINWALLS;
|
||||
}
|
||||
wall->MakeVertices(this, false);
|
||||
auto newwall = drawlists[list].NewWall();
|
||||
*newwall = *wall;
|
||||
}
|
||||
}
|
||||
|
||||
void FDrawInfo::AddMirrorSurface(GLWall *w)
|
||||
{
|
||||
w->type=RENDERWALL_MIRRORSURFACE;
|
||||
auto newwall = drawlists[GLDL_TRANSLUCENTBORDER].NewWall();
|
||||
*newwall = *w;
|
||||
|
||||
}
|
||||
|
||||
|
||||
const char GLWall::passflag[] = {
|
||||
|
@ -131,80 +84,9 @@ void GLWall::PutWall(HWDrawInfo *di, bool translucent)
|
|||
|
||||
void GLWall::PutPortal(HWDrawInfo *di, int ptype)
|
||||
{
|
||||
GLPortal * portal;
|
||||
|
||||
MakeVertices(di, false);
|
||||
switch (ptype)
|
||||
{
|
||||
// portals don't go into the draw list.
|
||||
// Instead they are added to the portal manager
|
||||
case PORTALTYPE_HORIZON:
|
||||
horizon=UniqueHorizons.Get(horizon);
|
||||
portal=GLPortal::FindPortal(horizon);
|
||||
if (!portal) portal=new GLHorizonPortal(horizon);
|
||||
portal->AddLine(this);
|
||||
break;
|
||||
|
||||
case PORTALTYPE_SKYBOX:
|
||||
portal = GLPortal::FindPortal(secportal);
|
||||
if (!portal)
|
||||
{
|
||||
// either a regular skybox or an Eternity-style horizon
|
||||
if (secportal->mType != PORTS_SKYVIEWPOINT) portal = new GLEEHorizonPortal(secportal);
|
||||
else portal = new GLSkyboxPortal(secportal);
|
||||
}
|
||||
portal->AddLine(this);
|
||||
break;
|
||||
|
||||
case PORTALTYPE_SECTORSTACK:
|
||||
portal = this->portal->GetRenderState();
|
||||
portal->AddLine(this);
|
||||
break;
|
||||
|
||||
case PORTALTYPE_PLANEMIRROR:
|
||||
if (GLPortal::PlaneMirrorMode * planemirror->fC() <=0)
|
||||
{
|
||||
//@sync-portal
|
||||
planemirror=UniquePlaneMirrors.Get(planemirror);
|
||||
portal=GLPortal::FindPortal(planemirror);
|
||||
if (!portal) portal=new GLPlaneMirrorPortal(planemirror);
|
||||
portal->AddLine(this);
|
||||
}
|
||||
break;
|
||||
|
||||
case PORTALTYPE_MIRROR:
|
||||
portal=GLPortal::FindPortal(seg->linedef);
|
||||
if (!portal) portal=new GLMirrorPortal(seg->linedef);
|
||||
portal->AddLine(this);
|
||||
if (gl_mirror_envmap)
|
||||
{
|
||||
// draw a reflective layer over the mirror
|
||||
di->AddMirrorSurface(this);
|
||||
}
|
||||
break;
|
||||
|
||||
case PORTALTYPE_LINETOLINE:
|
||||
portal=GLPortal::FindPortal(lineportal);
|
||||
if (!portal)
|
||||
{
|
||||
line_t *otherside = lineportal->lines[0]->mDestination;
|
||||
if (otherside != NULL && otherside->portalindex < level.linePortals.Size())
|
||||
{
|
||||
di->ProcessActorsInPortal(otherside->getPortal()->mGroup);
|
||||
}
|
||||
portal = new GLLineToLinePortal(lineportal);
|
||||
}
|
||||
portal->AddLine(this);
|
||||
break;
|
||||
|
||||
case PORTALTYPE_SKY:
|
||||
portal=GLPortal::FindPortal(sky);
|
||||
if (!portal) portal=new GLSkyPortal(sky);
|
||||
portal->AddLine(this);
|
||||
break;
|
||||
}
|
||||
vertcount = 0;
|
||||
di->AddPortal(this, ptype);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Sets 3D-floor lighting info
|
||||
|
@ -216,7 +98,7 @@ void GLWall::Put3DWall(HWDrawInfo *di, 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);
|
||||
lightlevel = hw_ClampLight(*lightlist->p_lightlevel);
|
||||
}
|
||||
// relative light won't get changed here. It is constant across the entire wall.
|
||||
|
||||
|
@ -367,7 +249,7 @@ void GLWall::SplitWall(HWDrawInfo *di, sector_t * frontsector, bool translucent)
|
|||
(maplightbottomleft<zbottom[0] && maplightbottomright>zbottom[1]) ||
|
||||
(maplightbottomleft > zbottom[0] && maplightbottomright < zbottom[1]))
|
||||
{
|
||||
if (!(gl.flags & RFL_NO_CLIP_PLANES))
|
||||
if (!(screen->hwcaps & RFL_NO_CLIP_PLANES))
|
||||
{
|
||||
// Use hardware clipping if this cannot be done cleanly.
|
||||
this->lightlist = &lightlist;
|
||||
|
@ -449,7 +331,7 @@ bool GLWall::DoHorizon(HWDrawInfo *di, seg_t * seg,sector_t * fs, vertex_t * v1,
|
|||
else
|
||||
{
|
||||
hi.plane.GetFromSector(fs, sector_t::ceiling);
|
||||
hi.lightlevel = gl_ClampLight(fs->GetCeilingLight());
|
||||
hi.lightlevel = hw_ClampLight(fs->GetCeilingLight());
|
||||
hi.colormap = fs->Colormap;
|
||||
hi.specialcolor = fs->SpecialColors[sector_t::ceiling];
|
||||
|
||||
|
@ -457,7 +339,7 @@ bool GLWall::DoHorizon(HWDrawInfo *di, seg_t * seg,sector_t * fs, vertex_t * v1,
|
|||
{
|
||||
light = P_GetPlaneLight(fs, &fs->ceilingplane, true);
|
||||
|
||||
if(!(fs->GetFlags(sector_t::ceiling)&PLANEF_ABSLIGHTING)) hi.lightlevel = gl_ClampLight(*light->p_lightlevel);
|
||||
if(!(fs->GetFlags(sector_t::ceiling)&PLANEF_ABSLIGHTING)) hi.lightlevel = hw_ClampLight(*light->p_lightlevel);
|
||||
hi.colormap.CopyLight(light->extra_colormap);
|
||||
}
|
||||
|
||||
|
@ -478,7 +360,7 @@ bool GLWall::DoHorizon(HWDrawInfo *di, seg_t * seg,sector_t * fs, vertex_t * v1,
|
|||
else
|
||||
{
|
||||
hi.plane.GetFromSector(fs, sector_t::floor);
|
||||
hi.lightlevel = gl_ClampLight(fs->GetFloorLight());
|
||||
hi.lightlevel = hw_ClampLight(fs->GetFloorLight());
|
||||
hi.colormap = fs->Colormap;
|
||||
hi.specialcolor = fs->SpecialColors[sector_t::floor];
|
||||
|
||||
|
@ -486,7 +368,7 @@ bool GLWall::DoHorizon(HWDrawInfo *di, seg_t * seg,sector_t * fs, vertex_t * v1,
|
|||
{
|
||||
light = P_GetPlaneLight(fs, &fs->floorplane, false);
|
||||
|
||||
if(!(fs->GetFlags(sector_t::floor)&PLANEF_ABSLIGHTING)) hi.lightlevel = gl_ClampLight(*light->p_lightlevel);
|
||||
if(!(fs->GetFlags(sector_t::floor)&PLANEF_ABSLIGHTING)) hi.lightlevel = hw_ClampLight(*light->p_lightlevel);
|
||||
hi.colormap.CopyLight(light->extra_colormap);
|
||||
}
|
||||
|
||||
|
@ -1124,7 +1006,7 @@ void GLWall::BuildFFBlock(HWDrawInfo *di, seg_t * seg, F3DFloor * rover,
|
|||
Colormap.Clear();
|
||||
Colormap.LightColor = light->extra_colormap.FadeColor;
|
||||
// the fog plane defines the light level, not the front sector
|
||||
lightlevel = gl_ClampLight(*light->p_lightlevel);
|
||||
lightlevel = hw_ClampLight(*light->p_lightlevel);
|
||||
gltexture = NULL;
|
||||
type = RENDERWALL_FFBLOCK;
|
||||
}
|
||||
|
@ -1531,9 +1413,9 @@ void GLWall::Process(HWDrawInfo *di, seg_t *seg, sector_t * frontsector, sector_
|
|||
lightlist = NULL;
|
||||
|
||||
int rel = 0;
|
||||
int orglightlevel = gl_ClampLight(frontsector->lightlevel);
|
||||
int orglightlevel = hw_ClampLight(frontsector->lightlevel);
|
||||
bool foggy = (!Colormap.FadeColor.isBlack() || level.flags&LEVEL_HASFADETABLE); // fog disables fake contrast
|
||||
lightlevel = gl_ClampLight(seg->sidedef->GetLightLevel(foggy, orglightlevel, false, &rel));
|
||||
lightlevel = hw_ClampLight(seg->sidedef->GetLightLevel(foggy, orglightlevel, false, &rel));
|
||||
if (orglightlevel >= 253) // with the software renderer fake contrast won't be visible above this.
|
||||
{
|
||||
rellight = 0;
|
||||
|
@ -1664,7 +1546,7 @@ void GLWall::Process(HWDrawInfo *di, seg_t *seg, sector_t * frontsector, sector_
|
|||
bool isportal = seg->linedef->isVisualPortal() && seg->sidedef == seg->linedef->sidedef[0];
|
||||
sector_t *backsec = isportal? seg->linedef->getPortalDestination()->frontsector : backsector;
|
||||
|
||||
bool drawfogboundary = di->FixedColormap == CM_DEFAULT && gl_CheckFog(frontsector, backsec);
|
||||
bool drawfogboundary = di->FixedColormap == CM_DEFAULT && hw_CheckFog(frontsector, backsec);
|
||||
FTexture *tex = TexMan(seg->sidedef->GetTexture(side_t::mid));
|
||||
if (tex != NULL)
|
||||
{
|
||||
|
@ -1781,7 +1663,7 @@ void GLWall::ProcessLowerMiniseg(HWDrawInfo *di, seg_t *seg, sector_t * frontsec
|
|||
flags = 0;
|
||||
|
||||
// can't do fake contrast without a sidedef
|
||||
lightlevel = gl_ClampLight(frontsector->lightlevel);
|
||||
lightlevel = hw_ClampLight(frontsector->lightlevel);
|
||||
rellight = 0;
|
||||
|
||||
alpha = 1.0f;
|
||||
|
|
|
@ -151,13 +151,13 @@ bool GLWall::SetupLights(FDynLightData &lightdata)
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
void GLWall::RenderWall(int textured)
|
||||
void FDrawInfo::RenderWall(GLWall *wall, int textured)
|
||||
{
|
||||
assert(vertcount > 0);
|
||||
gl_RenderState.Apply();
|
||||
gl_RenderState.ApplyLightIndex(dynlightindex);
|
||||
GLRenderer->mVBO->RenderArray(GL_TRIANGLE_FAN, vertindex, vertcount);
|
||||
vertexcount += vertcount;
|
||||
gl_RenderState.ApplyLightIndex(wall->dynlightindex);
|
||||
GLRenderer->mVBO->RenderArray(GL_TRIANGLE_FAN, wall->vertindex, wall->vertcount);
|
||||
vertexcount += wall->vertcount;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -166,20 +166,20 @@ void GLWall::RenderWall(int textured)
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
void GLWall::RenderFogBoundary()
|
||||
void FDrawInfo::RenderFogBoundary(GLWall *wall)
|
||||
{
|
||||
if (gl_fogmode && mDrawer->FixedColormap == 0)
|
||||
{
|
||||
if (!gl.legacyMode)
|
||||
{
|
||||
int rel = rellight + getExtraLight();
|
||||
mDrawer->SetFog(lightlevel, rel, &Colormap, false);
|
||||
int rel = wall->rellight + getExtraLight();
|
||||
mDrawer->SetFog(wall->lightlevel, rel, &wall->Colormap, false);
|
||||
gl_RenderState.EnableDrawBuffers(1);
|
||||
gl_RenderState.SetEffect(EFF_FOGBOUNDARY);
|
||||
gl_RenderState.AlphaFunc(GL_GEQUAL, 0.f);
|
||||
glEnable(GL_POLYGON_OFFSET_FILL);
|
||||
glPolygonOffset(-1.0f, -128.0f);
|
||||
RenderWall(RWF_BLANK);
|
||||
RenderWall(wall, GLWall::RWF_BLANK);
|
||||
glPolygonOffset(0.0f, 0.0f);
|
||||
glDisable(GL_POLYGON_OFFSET_FILL);
|
||||
gl_RenderState.SetEffect(EFF_NONE);
|
||||
|
@ -187,7 +187,7 @@ void GLWall::RenderFogBoundary()
|
|||
}
|
||||
else
|
||||
{
|
||||
gl_drawinfo->RenderFogBoundaryCompat(this);
|
||||
RenderFogBoundaryCompat(wall);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -198,32 +198,27 @@ void GLWall::RenderFogBoundary()
|
|||
//
|
||||
//
|
||||
//==========================================================================
|
||||
void GLWall::RenderMirrorSurface()
|
||||
void FDrawInfo::RenderMirrorSurface(GLWall *wall)
|
||||
{
|
||||
if (!GLRenderer->mirrorTexture.isValid()) return;
|
||||
|
||||
// For the sphere map effect we need a normal of the mirror surface,
|
||||
FVector3 v = glseg.Normal();
|
||||
|
||||
if (!gl.legacyMode)
|
||||
{
|
||||
// we use texture coordinates and texture matrix to pass the normal stuff to the shader so that the default vertex buffer format can be used as is.
|
||||
tcs[LOLFT].u = tcs[LORGT].u = tcs[UPLFT].u = tcs[UPRGT].u = v.X;
|
||||
tcs[LOLFT].v = tcs[LORGT].v = tcs[UPLFT].v = tcs[UPRGT].v = v.Z;
|
||||
|
||||
gl_RenderState.EnableTextureMatrix(true);
|
||||
gl_RenderState.mTextureMatrix.computeNormalMatrix(gl_RenderState.mViewMatrix);
|
||||
}
|
||||
else
|
||||
{
|
||||
FVector3 v = wall->glseg.Normal();
|
||||
glNormal3fv(&v[0]);
|
||||
}
|
||||
|
||||
// Use sphere mapping for this
|
||||
gl_RenderState.SetEffect(EFF_SPHEREMAP);
|
||||
|
||||
mDrawer->SetColor(lightlevel, 0, Colormap ,0.1f);
|
||||
mDrawer->SetFog(lightlevel, 0, &Colormap, true);
|
||||
mDrawer->SetColor(wall->lightlevel, 0, wall->Colormap ,0.1f);
|
||||
mDrawer->SetFog(wall->lightlevel, 0, &wall->Colormap, true);
|
||||
gl_RenderState.BlendFunc(GL_SRC_ALPHA,GL_ONE);
|
||||
gl_RenderState.AlphaFunc(GL_GREATER,0);
|
||||
glDepthFunc(GL_LEQUAL);
|
||||
|
@ -231,8 +226,8 @@ void GLWall::RenderMirrorSurface()
|
|||
FMaterial * pat=FMaterial::ValidateTexture(GLRenderer->mirrorTexture, false, false);
|
||||
gl_RenderState.SetMaterial(pat, CLAMP_NONE, 0, -1, false);
|
||||
|
||||
flags &= ~GLWF_GLOW;
|
||||
RenderWall(RWF_BLANK);
|
||||
wall->flags &= ~GLWall::GLWF_GLOW;
|
||||
RenderWall(wall, GLWall::RWF_BLANK);
|
||||
|
||||
gl_RenderState.EnableTextureMatrix(false);
|
||||
gl_RenderState.SetEffect(EFF_NONE);
|
||||
|
@ -244,12 +239,12 @@ void GLWall::RenderMirrorSurface()
|
|||
|
||||
// This is drawn in the translucent pass which is done after the decal pass
|
||||
// As a result the decals have to be drawn here.
|
||||
if (seg->sidedef->AttachedDecals)
|
||||
if (wall->seg->sidedef->AttachedDecals)
|
||||
{
|
||||
glEnable(GL_POLYGON_OFFSET_FILL);
|
||||
glPolygonOffset(-1.0f, -128.0f);
|
||||
glDepthMask(false);
|
||||
gl_drawinfo->DoDrawDecals(this);
|
||||
gl_drawinfo->DoDrawDecals(wall);
|
||||
glDepthMask(true);
|
||||
glPolygonOffset(0.0f, 0.0f);
|
||||
glDisable(GL_POLYGON_OFFSET_FILL);
|
||||
|
@ -264,61 +259,61 @@ void GLWall::RenderMirrorSurface()
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
void GLWall::RenderTextured(int rflags)
|
||||
void FDrawInfo::RenderTexturedWall(GLWall *wall, int rflags)
|
||||
{
|
||||
int tmode = gl_RenderState.GetTextureMode();
|
||||
int rel = rellight + getExtraLight();
|
||||
int rel = wall->rellight + getExtraLight();
|
||||
|
||||
if (flags & GLWF_GLOW)
|
||||
if (wall->flags & GLWall::GLWF_GLOW)
|
||||
{
|
||||
gl_RenderState.EnableGlow(true);
|
||||
gl_RenderState.SetGlowParams(topglowcolor, bottomglowcolor);
|
||||
gl_RenderState.SetGlowParams(wall->topglowcolor, wall->bottomglowcolor);
|
||||
}
|
||||
gl_RenderState.SetGlowPlanes(topplane, bottomplane);
|
||||
gl_RenderState.SetMaterial(gltexture, flags & 3, 0, -1, false);
|
||||
gl_RenderState.SetGlowPlanes(wall->topplane, wall->bottomplane);
|
||||
gl_RenderState.SetMaterial(wall->gltexture, wall->flags & 3, 0, -1, false);
|
||||
|
||||
if (type == RENDERWALL_M2SNF)
|
||||
if (wall->type == RENDERWALL_M2SNF)
|
||||
{
|
||||
if (flags & GLWF_CLAMPY)
|
||||
if (wall->flags & GLWall::GLWF_CLAMPY)
|
||||
{
|
||||
if (tmode == TM_MODULATE) gl_RenderState.SetTextureMode(TM_CLAMPY);
|
||||
}
|
||||
mDrawer->SetFog(255, 0, NULL, false);
|
||||
mDrawer->SetFog(255, 0, nullptr, false);
|
||||
}
|
||||
gl_RenderState.SetObjectColor(seg->frontsector->SpecialColors[sector_t::walltop] | 0xff000000);
|
||||
gl_RenderState.SetObjectColor2(seg->frontsector->SpecialColors[sector_t::wallbottom] | 0xff000000);
|
||||
gl_RenderState.SetObjectColor(wall->seg->frontsector->SpecialColors[sector_t::walltop] | 0xff000000);
|
||||
gl_RenderState.SetObjectColor2(wall->seg->frontsector->SpecialColors[sector_t::wallbottom] | 0xff000000);
|
||||
|
||||
float absalpha = fabsf(alpha);
|
||||
if (lightlist == NULL)
|
||||
float absalpha = fabsf(wall->alpha);
|
||||
if (wall->lightlist == nullptr)
|
||||
{
|
||||
if (type != RENDERWALL_M2SNF) mDrawer->SetFog(lightlevel, rel, &Colormap, RenderStyle == STYLE_Add);
|
||||
mDrawer->SetColor(lightlevel, rel, Colormap, absalpha);
|
||||
RenderWall(rflags);
|
||||
if (wall->type != RENDERWALL_M2SNF) mDrawer->SetFog(wall->lightlevel, rel, &wall->Colormap, wall->RenderStyle == STYLE_Add);
|
||||
mDrawer->SetColor(wall->lightlevel, rel, wall->Colormap, absalpha);
|
||||
RenderWall(wall, rflags);
|
||||
}
|
||||
else
|
||||
{
|
||||
gl_RenderState.EnableSplit(true);
|
||||
|
||||
for (unsigned i = 0; i < lightlist->Size(); i++)
|
||||
for (unsigned i = 0; i < wall->lightlist->Size(); i++)
|
||||
{
|
||||
secplane_t &lowplane = i == (*lightlist).Size() - 1 ? bottomplane : (*lightlist)[i + 1].plane;
|
||||
secplane_t &lowplane = i == (*wall->lightlist).Size() - 1 ? wall->bottomplane : (*wall->lightlist)[i + 1].plane;
|
||||
// this must use the exact same calculation method as GLWall::Process etc.
|
||||
float low1 = lowplane.ZatPoint(vertexes[0]);
|
||||
float low2 = lowplane.ZatPoint(vertexes[1]);
|
||||
float low1 = lowplane.ZatPoint(wall->vertexes[0]);
|
||||
float low2 = lowplane.ZatPoint(wall->vertexes[1]);
|
||||
|
||||
if (low1 < ztop[0] || low2 < ztop[1])
|
||||
if (low1 < wall->ztop[0] || low2 < wall->ztop[1])
|
||||
{
|
||||
int thisll = (*lightlist)[i].caster != NULL ? gl_ClampLight(*(*lightlist)[i].p_lightlevel) : lightlevel;
|
||||
int thisll = (*wall->lightlist)[i].caster != NULL ? hw_ClampLight(*(*wall->lightlist)[i].p_lightlevel) : wall->lightlevel;
|
||||
FColormap thiscm;
|
||||
thiscm.FadeColor = Colormap.FadeColor;
|
||||
thiscm.FogDensity = Colormap.FogDensity;
|
||||
thiscm.CopyFrom3DLight(&(*lightlist)[i]);
|
||||
thiscm.FadeColor = wall->Colormap.FadeColor;
|
||||
thiscm.FogDensity = wall->Colormap.FogDensity;
|
||||
thiscm.CopyFrom3DLight(&(*wall->lightlist)[i]);
|
||||
mDrawer->SetColor(thisll, rel, thiscm, absalpha);
|
||||
if (type != RENDERWALL_M2SNF) mDrawer->SetFog(thisll, rel, &thiscm, RenderStyle == STYLE_Add);
|
||||
gl_RenderState.SetSplitPlanes((*lightlist)[i].plane, lowplane);
|
||||
RenderWall(rflags);
|
||||
if (wall->type != RENDERWALL_M2SNF) mDrawer->SetFog(thisll, rel, &thiscm, wall->RenderStyle == STYLE_Add);
|
||||
gl_RenderState.SetSplitPlanes((*wall->lightlist)[i].plane, lowplane);
|
||||
RenderWall(wall, rflags);
|
||||
}
|
||||
if (low1 <= zbottom[0] && low2 <= zbottom[1]) break;
|
||||
if (low1 <= wall->zbottom[0] && low2 <= wall->zbottom[1]) break;
|
||||
}
|
||||
|
||||
gl_RenderState.EnableSplit(false);
|
||||
|
@ -335,28 +330,28 @@ void GLWall::RenderTextured(int rflags)
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
void GLWall::RenderTranslucentWall()
|
||||
void FDrawInfo::RenderTranslucentWall(GLWall *wall)
|
||||
{
|
||||
if (gltexture)
|
||||
if (wall->gltexture)
|
||||
{
|
||||
if (mDrawer->FixedColormap == CM_DEFAULT && gl_lights && gl.lightmethod == LM_DIRECT)
|
||||
{
|
||||
if (SetupLights(lightdata))
|
||||
dynlightindex = GLRenderer->mLights->UploadLights(lightdata);
|
||||
if (wall->SetupLights(lightdata))
|
||||
wall->dynlightindex = GLRenderer->mLights->UploadLights(lightdata);
|
||||
}
|
||||
if (!gltexture->tex->GetTranslucency()) gl_RenderState.AlphaFunc(GL_GEQUAL, gl_mask_threshold);
|
||||
if (!wall->gltexture->tex->GetTranslucency()) gl_RenderState.AlphaFunc(GL_GEQUAL, gl_mask_threshold);
|
||||
else gl_RenderState.AlphaFunc(GL_GEQUAL, 0.f);
|
||||
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);
|
||||
if (wall->RenderStyle == STYLE_Add) gl_RenderState.BlendFunc(GL_SRC_ALPHA,GL_ONE);
|
||||
RenderTexturedWall(wall, GLWall::RWF_TEXTURED | GLWall::RWF_NOSPLIT);
|
||||
if (wall->RenderStyle == STYLE_Add) gl_RenderState.BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
}
|
||||
else
|
||||
{
|
||||
gl_RenderState.AlphaFunc(GL_GEQUAL, 0.f);
|
||||
mDrawer->SetColor(lightlevel, 0, Colormap, fabsf(alpha));
|
||||
mDrawer->SetFog(lightlevel, 0, &Colormap, RenderStyle == STYLE_Add);
|
||||
mDrawer->SetColor(wall->lightlevel, 0, wall->Colormap, fabsf(wall->alpha));
|
||||
mDrawer->SetFog(wall->lightlevel, 0, &wall->Colormap, wall->RenderStyle == STYLE_Add);
|
||||
gl_RenderState.EnableTexture(false);
|
||||
RenderWall(RWF_NOSPLIT);
|
||||
RenderWall(wall, GLWall::RWF_NOSPLIT);
|
||||
gl_RenderState.EnableTexture(true);
|
||||
}
|
||||
}
|
||||
|
@ -366,38 +361,38 @@ void GLWall::RenderTranslucentWall()
|
|||
//
|
||||
//
|
||||
//==========================================================================
|
||||
void GLWall::Draw(int pass)
|
||||
void FDrawInfo::DrawWall(GLWall *wall, int pass)
|
||||
{
|
||||
gl_RenderState.SetNormal(glseg.Normal());
|
||||
gl_RenderState.SetNormal(wall->glseg.Normal());
|
||||
switch (pass)
|
||||
{
|
||||
case GLPASS_LIGHTSONLY:
|
||||
if (SetupLights(lightdata))
|
||||
dynlightindex = GLRenderer->mLights->UploadLights(lightdata);
|
||||
if (wall->SetupLights(lightdata))
|
||||
wall->dynlightindex = GLRenderer->mLights->UploadLights(lightdata);
|
||||
break;
|
||||
|
||||
case GLPASS_ALL:
|
||||
if (SetupLights(lightdata))
|
||||
dynlightindex = GLRenderer->mLights->UploadLights(lightdata);
|
||||
if (wall->SetupLights(lightdata))
|
||||
wall->dynlightindex = GLRenderer->mLights->UploadLights(lightdata);
|
||||
// fall through
|
||||
case GLPASS_PLAIN:
|
||||
RenderTextured(RWF_TEXTURED);
|
||||
RenderTexturedWall(wall, GLWall::RWF_TEXTURED);
|
||||
break;
|
||||
|
||||
case GLPASS_TRANSLUCENT:
|
||||
|
||||
switch (type)
|
||||
switch (wall->type)
|
||||
{
|
||||
case RENDERWALL_MIRRORSURFACE:
|
||||
RenderMirrorSurface();
|
||||
RenderMirrorSurface(wall);
|
||||
break;
|
||||
|
||||
case RENDERWALL_FOGBOUNDARY:
|
||||
RenderFogBoundary();
|
||||
RenderFogBoundary(wall);
|
||||
break;
|
||||
|
||||
default:
|
||||
RenderTranslucentWall();
|
||||
RenderTranslucentWall(wall);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
@ -405,12 +400,169 @@ void GLWall::Draw(int pass)
|
|||
case GLPASS_LIGHTTEX:
|
||||
case GLPASS_LIGHTTEX_ADDITIVE:
|
||||
case GLPASS_LIGHTTEX_FOGGY:
|
||||
gl_drawinfo->RenderLightsCompat(this, pass);
|
||||
gl_drawinfo->RenderLightsCompat(wall, pass);
|
||||
break;
|
||||
|
||||
case GLPASS_TEXONLY:
|
||||
gl_RenderState.SetMaterial(gltexture, flags & 3, 0, -1, false);
|
||||
RenderWall(RWF_TEXTURED);
|
||||
gl_RenderState.SetMaterial(wall->gltexture, wall->flags & 3, 0, -1, false);
|
||||
RenderWall(wall, GLWall::RWF_TEXTURED);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void FDrawInfo::AddWall(GLWall *wall)
|
||||
{
|
||||
bool translucent = !!(wall->flags & GLWall::GLWF_TRANSLUCENT);
|
||||
int list;
|
||||
|
||||
if (translucent) // translucent walls
|
||||
{
|
||||
if (!gl.legacyMode && mDrawer->FixedColormap == CM_DEFAULT && wall->gltexture != nullptr)
|
||||
{
|
||||
if (wall->SetupLights(lightdata))
|
||||
wall->dynlightindex = GLRenderer->mLights->UploadLights(lightdata);
|
||||
}
|
||||
wall->ViewDistance = (r_viewpoint.Pos - (wall->seg->linedef->v1->fPos() + wall->seg->linedef->Delta() / 2)).XY().LengthSquared();
|
||||
wall->MakeVertices(this, true);
|
||||
auto newwall = drawlists[GLDL_TRANSLUCENT].NewWall();
|
||||
*newwall = *wall;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (gl.legacyMode)
|
||||
{
|
||||
if (PutWallCompat(wall, GLWall::passflag[wall->type])) return;
|
||||
}
|
||||
else if (mDrawer->FixedColormap == CM_DEFAULT)
|
||||
{
|
||||
if (wall->SetupLights(lightdata))
|
||||
wall->dynlightindex = GLRenderer->mLights->UploadLights(lightdata);
|
||||
}
|
||||
|
||||
|
||||
bool masked;
|
||||
|
||||
masked = GLWall::passflag[wall->type] == 1 ? false : (wall->gltexture && wall->gltexture->isMasked());
|
||||
|
||||
if ((wall->flags & GLWall::GLWF_SKYHACK && wall->type == RENDERWALL_M2S))
|
||||
{
|
||||
list = GLDL_MASKEDWALLSOFS;
|
||||
}
|
||||
else
|
||||
{
|
||||
list = masked ? GLDL_MASKEDWALLS : GLDL_PLAINWALLS;
|
||||
}
|
||||
wall->MakeVertices(this, false);
|
||||
auto newwall = drawlists[list].NewWall();
|
||||
*newwall = *wall;
|
||||
}
|
||||
wall->dynlightindex = -1;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void FDrawInfo::AddMirrorSurface(GLWall *w)
|
||||
{
|
||||
w->type = RENDERWALL_MIRRORSURFACE;
|
||||
auto newwall = drawlists[GLDL_TRANSLUCENTBORDER].NewWall();
|
||||
*newwall = *w;
|
||||
|
||||
FVector3 v = newwall->glseg.Normal();
|
||||
auto tcs = newwall->tcs;
|
||||
tcs[GLWall::LOLFT].u = tcs[GLWall::LORGT].u = tcs[GLWall::UPLFT].u = tcs[GLWall::UPRGT].u = v.X;
|
||||
tcs[GLWall::LOLFT].v = tcs[GLWall::LORGT].v = tcs[GLWall::UPLFT].v = tcs[GLWall::UPRGT].v = v.Z;
|
||||
newwall->MakeVertices(this, false);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void FDrawInfo::AddPortal(GLWall *wall, int ptype)
|
||||
{
|
||||
GLPortal * portal;
|
||||
|
||||
wall->MakeVertices(this, false);
|
||||
switch (ptype)
|
||||
{
|
||||
// portals don't go into the draw list.
|
||||
// Instead they are added to the portal manager
|
||||
case PORTALTYPE_HORIZON:
|
||||
wall->horizon = UniqueHorizons.Get(wall->horizon);
|
||||
portal = GLPortal::FindPortal(wall->horizon);
|
||||
if (!portal) portal = new GLHorizonPortal(wall->horizon);
|
||||
portal->AddLine(wall);
|
||||
break;
|
||||
|
||||
case PORTALTYPE_SKYBOX:
|
||||
portal = GLPortal::FindPortal(wall->secportal);
|
||||
if (!portal)
|
||||
{
|
||||
// either a regular skybox or an Eternity-style horizon
|
||||
if (wall->secportal->mType != PORTS_SKYVIEWPOINT) portal = new GLEEHorizonPortal(wall->secportal);
|
||||
else portal = new GLSkyboxPortal(wall->secportal);
|
||||
}
|
||||
portal->AddLine(wall);
|
||||
break;
|
||||
|
||||
case PORTALTYPE_SECTORSTACK:
|
||||
portal = wall->portal->GetRenderState();
|
||||
portal->AddLine(wall);
|
||||
break;
|
||||
|
||||
case PORTALTYPE_PLANEMIRROR:
|
||||
if (GLPortal::PlaneMirrorMode * wall->planemirror->fC() <= 0)
|
||||
{
|
||||
//@sync-portal
|
||||
wall->planemirror = UniquePlaneMirrors.Get(wall->planemirror);
|
||||
portal = GLPortal::FindPortal(wall->planemirror);
|
||||
if (!portal) portal = new GLPlaneMirrorPortal(wall->planemirror);
|
||||
portal->AddLine(wall);
|
||||
}
|
||||
break;
|
||||
|
||||
case PORTALTYPE_MIRROR:
|
||||
portal = GLPortal::FindPortal(wall->seg->linedef);
|
||||
if (!portal) portal = new GLMirrorPortal(wall->seg->linedef);
|
||||
portal->AddLine(wall);
|
||||
if (gl_mirror_envmap)
|
||||
{
|
||||
// draw a reflective layer over the mirror
|
||||
AddMirrorSurface(wall);
|
||||
}
|
||||
break;
|
||||
|
||||
case PORTALTYPE_LINETOLINE:
|
||||
portal = GLPortal::FindPortal(wall->lineportal);
|
||||
if (!portal)
|
||||
{
|
||||
line_t *otherside = wall->lineportal->lines[0]->mDestination;
|
||||
if (otherside != NULL && otherside->portalindex < level.linePortals.Size())
|
||||
{
|
||||
ProcessActorsInPortal(otherside->getPortal()->mGroup);
|
||||
}
|
||||
portal = new GLLineToLinePortal(wall->lineportal);
|
||||
}
|
||||
portal->AddLine(wall);
|
||||
break;
|
||||
|
||||
case PORTALTYPE_SKY:
|
||||
portal = GLPortal::FindPortal(wall->sky);
|
||||
if (!portal) portal = new GLSkyPortal(wall->sky);
|
||||
portal->AddLine(wall);
|
||||
break;
|
||||
}
|
||||
wall->vertcount = 0;
|
||||
}
|
||||
|
|
|
@ -275,7 +275,7 @@ void GLSceneDrawer::DrawPlayerSprites(sector_t * viewsector, bool hudModelStep)
|
|||
fakesec = hw_FakeFlat(viewsector, &fs, in_area, false);
|
||||
|
||||
// calculate light level for weapon sprites
|
||||
lightlevel = gl_ClampLight(fakesec->lightlevel);
|
||||
lightlevel = hw_ClampLight(fakesec->lightlevel);
|
||||
|
||||
// calculate colormap for weapon sprites
|
||||
if (viewsector->e->XFloor.ffloors.Size() && !(level.flags3 & LEVEL3_NOCOLOREDSPRITELIGHTING))
|
||||
|
@ -297,7 +297,7 @@ void GLSceneDrawer::DrawPlayerSprites(sector_t * viewsector, bool hudModelStep)
|
|||
if (lightbottom<player->viewz)
|
||||
{
|
||||
cm = lightlist[i].extra_colormap;
|
||||
lightlevel = gl_ClampLight(*lightlist[i].p_lightlevel);
|
||||
lightlevel = hw_ClampLight(*lightlist[i].p_lightlevel);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -308,7 +308,7 @@ void GLSceneDrawer::DrawPlayerSprites(sector_t * viewsector, bool hudModelStep)
|
|||
if (level.flags3 & LEVEL3_NOCOLOREDSPRITELIGHTING) cm.ClearColor();
|
||||
}
|
||||
|
||||
lightlevel = gl_CalcLightLevel(lightlevel, getExtraLight(), true);
|
||||
lightlevel = hw_CalcLightLevel(lightlevel, getExtraLight(), true);
|
||||
|
||||
if (level.lightmode == 8 || lightlevel < 92)
|
||||
{
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#include "gl/system/gl_interface.h"
|
||||
#include "c_cvars.h"
|
||||
#include "r_defs.h"
|
||||
#include "v_video.h"
|
||||
|
||||
class FGLDebug
|
||||
{
|
||||
|
|
|
@ -86,6 +86,8 @@ OpenGLFrameBuffer::OpenGLFrameBuffer(void *hMonitor, int width, int height, int
|
|||
mDebug = std::make_shared<FGLDebug>();
|
||||
mDebug->Update();
|
||||
DoSetGamma();
|
||||
hwcaps = gl.flags;
|
||||
if (gl.legacyMode) hwcaps |= RFL_NO_SHADERS;
|
||||
}
|
||||
|
||||
OpenGLFrameBuffer::~OpenGLFrameBuffer()
|
||||
|
@ -413,6 +415,13 @@ void OpenGLFrameBuffer::TextureFilterChanged()
|
|||
if (GLRenderer != NULL && GLRenderer->mSamplerManager != NULL) GLRenderer->mSamplerManager->SetTextureFilterMode();
|
||||
}
|
||||
|
||||
void OpenGLFrameBuffer::ResetFixedColormap()
|
||||
{
|
||||
if (GLRenderer != nullptr && GLRenderer->mShaderManager != nullptr)
|
||||
{
|
||||
GLRenderer->mShaderManager->ResetFixedColormap();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void OpenGLFrameBuffer::UpdatePalette()
|
||||
|
|
|
@ -48,6 +48,7 @@ public:
|
|||
void UnbindTexUnit(int no) override;
|
||||
void FlushTextures() override;
|
||||
void TextureFilterChanged() override;
|
||||
void ResetFixedColormap() override;
|
||||
|
||||
// Retrieves a buffer containing image data for a screenshot.
|
||||
// Hint: Pitch can be negative for upside-down images, in which case buffer
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
#include "doomtype.h"
|
||||
#include "m_argv.h"
|
||||
#include "version.h"
|
||||
#include "v_video.h"
|
||||
#include "gl/system/gl_interface.h"
|
||||
#include "hwrenderer/utility/hw_cvars.h"
|
||||
|
||||
|
|
|
@ -11,22 +11,6 @@ enum GLCompat
|
|||
CMPT_GL4
|
||||
};
|
||||
|
||||
enum RenderFlags
|
||||
{
|
||||
// [BB] Added texture compression flags.
|
||||
RFL_TEXTURE_COMPRESSION=1,
|
||||
RFL_TEXTURE_COMPRESSION_S3TC=2,
|
||||
|
||||
RFL_SHADER_STORAGE_BUFFER = 4,
|
||||
RFL_BUFFER_STORAGE = 8,
|
||||
RFL_SAMPLER_OBJECTS = 16,
|
||||
|
||||
RFL_NO_CLIP_PLANES = 32,
|
||||
|
||||
RFL_INVALIDATE_BUFFER = 64,
|
||||
RFL_DEBUG = 128
|
||||
};
|
||||
|
||||
enum TexMode
|
||||
{
|
||||
TM_SWCANVAS = -1, // special case for the legacy renderer, do not use for anything but the SW renderer's canvas.
|
||||
|
|
|
@ -29,13 +29,13 @@
|
|||
#include "gl/system/gl_system.h"
|
||||
#include "templates.h"
|
||||
#include "c_cvars.h"
|
||||
#include "r_data/colormaps.h"
|
||||
#include "hwrenderer/textures/hw_material.h"
|
||||
|
||||
#include "gl/system/gl_interface.h"
|
||||
#include "hwrenderer/utility/hw_cvars.h"
|
||||
#include "gl/system/gl_debug.h"
|
||||
#include "gl/renderer/gl_renderer.h"
|
||||
#include "gl/renderer/gl_colormap.h"
|
||||
#include "gl/textures/gl_samplers.h"
|
||||
|
||||
|
||||
|
|
|
@ -125,6 +125,7 @@ public:
|
|||
virtual void AddSubsectorToPortal(FSectorPortalGroup *portal, subsector_t *sub) = 0;
|
||||
|
||||
virtual void AddWall(GLWall *w) = 0;
|
||||
virtual void AddPortal(GLWall *w, int portaltype) = 0;
|
||||
virtual void AddMirrorSurface(GLWall *w) = 0;
|
||||
virtual void ProcessActorsInPortal(FLinePortalSpan *glport) = 0;
|
||||
virtual std::pair<FFlatVertex *, unsigned int> AllocVertices(unsigned int count) = 0;
|
||||
|
|
288
src/hwrenderer/utility/hw_lighting.cpp
Normal file
288
src/hwrenderer/utility/hw_lighting.cpp
Normal file
|
@ -0,0 +1,288 @@
|
|||
//
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// Copyright(C) 2002-2018 Christoph Oelckers
|
||||
// All rights reserved.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with this program. If not, see http://www.gnu.org/licenses/
|
||||
//
|
||||
//--------------------------------------------------------------------------
|
||||
//
|
||||
/*
|
||||
** gl_light.cpp
|
||||
** Light level / fog management / dynamic lights
|
||||
**
|
||||
**/
|
||||
|
||||
#include "c_cvars.h"
|
||||
#include "r_sky.h"
|
||||
#include "g_levellocals.h"
|
||||
#include "hw_lighting.h"
|
||||
|
||||
// externally settable lighting properties
|
||||
static float distfogtable[2][256]; // light to fog conversion table for black fog
|
||||
|
||||
CVAR(Int, gl_weaponlight, 8, CVAR_ARCHIVE);
|
||||
CUSTOM_CVAR(Bool, gl_enhanced_nightvision, true, CVAR_ARCHIVE|CVAR_NOINITCALL)
|
||||
{
|
||||
// The fixed colormap state needs to be reset because if this happens when
|
||||
// a shader is set to CM_LITE or CM_TORCH it won't register the change in behavior caused by this CVAR.
|
||||
screen->ResetFixedColormap();
|
||||
}
|
||||
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Sets up the fog tables
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
CUSTOM_CVAR(Int, gl_distfog, 70, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
|
||||
{
|
||||
for (int i = 0; i < 256; i++)
|
||||
{
|
||||
|
||||
if (i < 164)
|
||||
{
|
||||
distfogtable[0][i] = (float)((gl_distfog >> 1) + (gl_distfog)*(164 - i) / 164);
|
||||
}
|
||||
else if (i < 230)
|
||||
{
|
||||
distfogtable[0][i] = (float)((gl_distfog >> 1) - (gl_distfog >> 1)*(i - 164) / (230 - 164));
|
||||
}
|
||||
else distfogtable[0][i] = 0;
|
||||
|
||||
if (i < 128)
|
||||
{
|
||||
distfogtable[1][i] = 6.f + (float)((gl_distfog >> 1) + (gl_distfog)*(128 - i) / 48);
|
||||
}
|
||||
else if (i < 216)
|
||||
{
|
||||
distfogtable[1][i] = (216.f - i) / ((216.f - 128.f)) * gl_distfog / 10;
|
||||
}
|
||||
else distfogtable[1][i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
CUSTOM_CVAR(Int,gl_fogmode,1,CVAR_ARCHIVE|CVAR_NOINITCALL)
|
||||
{
|
||||
if (self>2) self=2;
|
||||
if (self<0) self=0;
|
||||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Get current light level
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
int hw_CalcLightLevel(int lightlevel, int rellight, bool weapon)
|
||||
{
|
||||
int light;
|
||||
|
||||
if (lightlevel == 0) return 0;
|
||||
|
||||
if ((level.lightmode & 2) && lightlevel < 192 && !weapon)
|
||||
{
|
||||
if (lightlevel > 100)
|
||||
{
|
||||
light = xs_CRoundToInt(192.f - (192 - lightlevel)* 1.87f);
|
||||
if (light + rellight < 20)
|
||||
{
|
||||
light = 20 + (light + rellight - 20) / 5;
|
||||
}
|
||||
else
|
||||
{
|
||||
light += rellight;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
light = (lightlevel + rellight) / 5;
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
light=lightlevel+rellight;
|
||||
}
|
||||
|
||||
return clamp(light, 0, 255);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Get current light color
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
PalEntry hw_CalcLightColor(int light, PalEntry pe, int blendfactor)
|
||||
{
|
||||
int r,g,b;
|
||||
|
||||
if (level.lightmode == 8)
|
||||
{
|
||||
return pe;
|
||||
}
|
||||
else if (blendfactor == 0)
|
||||
{
|
||||
r = pe.r * light / 255;
|
||||
g = pe.g * light / 255;
|
||||
b = pe.b * light / 255;
|
||||
}
|
||||
else
|
||||
{
|
||||
// This is what Legacy does with colored light in 3D volumes. No, it doesn't really make sense...
|
||||
// It also doesn't translate well to software style lighting.
|
||||
int mixlight = light * (255 - blendfactor);
|
||||
|
||||
r = (mixlight + pe.r * blendfactor) / 255;
|
||||
g = (mixlight + pe.g * blendfactor) / 255;
|
||||
b = (mixlight + pe.b * blendfactor) / 255;
|
||||
}
|
||||
return PalEntry(255, uint8_t(r), uint8_t(g), uint8_t(b));
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// calculates the current fog density
|
||||
//
|
||||
// Rules for fog:
|
||||
//
|
||||
// 1. If bit 4 of gl_lightmode is set always use the level's fog density.
|
||||
// This is what Legacy's GL render does.
|
||||
// 2. black fog means no fog and always uses the distfogtable based on the level's fog density setting
|
||||
// 3. If outside fog is defined and the current fog color is the same as the outside fog
|
||||
// the engine always uses the outside fog density to make the fog uniform across the level.
|
||||
// If the outside fog's density is undefined it uses the level's fog density and if that is
|
||||
// not defined it uses a default of 70.
|
||||
// 4. If a global fog density is specified it is being used for all fog on the level
|
||||
// 5. If none of the above apply fog density is based on the light level as for the software renderer.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
float hw_GetFogDensity(int lightlevel, PalEntry fogcolor, int sectorfogdensity)
|
||||
{
|
||||
float density;
|
||||
|
||||
if (level.lightmode & 4)
|
||||
{
|
||||
// uses approximations of Legacy's default settings.
|
||||
density = level.fogdensity ? (float)level.fogdensity : 18;
|
||||
}
|
||||
else if (sectorfogdensity != 0)
|
||||
{
|
||||
// case 1: Sector has an explicit fog density set.
|
||||
density = (float)sectorfogdensity;
|
||||
}
|
||||
else if ((fogcolor.d & 0xffffff) == 0)
|
||||
{
|
||||
// case 2: black fog
|
||||
if (level.lightmode != 8 && !(level.flags3 & LEVEL3_NOLIGHTFADE))
|
||||
{
|
||||
density = distfogtable[level.lightmode != 0][hw_ClampLight(lightlevel)];
|
||||
}
|
||||
else
|
||||
{
|
||||
density = 0;
|
||||
}
|
||||
}
|
||||
else if (level.outsidefogdensity != 0 && APART(level.info->outsidefog) != 0xff && (fogcolor.d & 0xffffff) == (level.info->outsidefog & 0xffffff))
|
||||
{
|
||||
// case 3. outsidefogdensity has already been set as needed
|
||||
density = (float)level.outsidefogdensity;
|
||||
}
|
||||
else if (level.fogdensity != 0)
|
||||
{
|
||||
// case 4: level has fog density set
|
||||
density = (float)level.fogdensity;
|
||||
}
|
||||
else if (lightlevel < 248)
|
||||
{
|
||||
// case 5: use light level
|
||||
density = (float)clamp<int>(255 - lightlevel, 30, 255);
|
||||
}
|
||||
else
|
||||
{
|
||||
density = 0.f;
|
||||
}
|
||||
return density;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Check if the current linedef is a candidate for a fog boundary
|
||||
//
|
||||
// Requirements for a fog boundary:
|
||||
// - front sector has no fog
|
||||
// - back sector has fog
|
||||
// - at least one of both does not have a sky ceiling.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
bool hw_CheckFog(sector_t *frontsector, sector_t *backsector)
|
||||
{
|
||||
if (frontsector == backsector) return false; // there can't be a boundary if both sides are in the same sector.
|
||||
|
||||
// Check for fog boundaries. This needs a few more checks for the sectors
|
||||
|
||||
PalEntry fogcolor = frontsector->Colormap.FadeColor;
|
||||
|
||||
if ((fogcolor.d & 0xffffff) == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else if (fogcolor.a != 0)
|
||||
{
|
||||
}
|
||||
else if (level.outsidefogdensity != 0 && APART(level.info->outsidefog) != 0xff && (fogcolor.d & 0xffffff) == (level.info->outsidefog & 0xffffff))
|
||||
{
|
||||
}
|
||||
else if (level.fogdensity!=0 || (level.lightmode & 4))
|
||||
{
|
||||
// case 3: level has fog density set
|
||||
}
|
||||
else
|
||||
{
|
||||
// case 4: use light level
|
||||
if (frontsector->lightlevel >= 248) return false;
|
||||
}
|
||||
|
||||
fogcolor = backsector->Colormap.FadeColor;
|
||||
|
||||
if ((fogcolor.d & 0xffffff) == 0)
|
||||
{
|
||||
}
|
||||
else if (level.outsidefogdensity != 0 && APART(level.info->outsidefog) != 0xff && (fogcolor.d & 0xffffff) == (level.info->outsidefog & 0xffffff))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else if (level.fogdensity!=0 || (level.lightmode & 4))
|
||||
{
|
||||
// case 3: level has fog density set
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
// case 4: use light level
|
||||
if (backsector->lightlevel < 248) return false;
|
||||
}
|
||||
|
||||
// in all other cases this might create more problems than it solves.
|
||||
return ((frontsector->GetTexture(sector_t::ceiling)!=skyflatnum ||
|
||||
backsector->GetTexture(sector_t::ceiling)!=skyflatnum));
|
||||
}
|
||||
|
17
src/hwrenderer/utility/hw_lighting.h
Normal file
17
src/hwrenderer/utility/hw_lighting.h
Normal file
|
@ -0,0 +1,17 @@
|
|||
#pragma once
|
||||
|
||||
#include "v_palette.h"
|
||||
#include "templates.h"
|
||||
|
||||
struct Colormap;
|
||||
|
||||
int hw_CalcLightLevel(int lightlevel, int rellight, bool weapon);
|
||||
PalEntry hw_CalcLightColor(int light, PalEntry pe, int blendfactor);
|
||||
float hw_GetFogDensity(int lightlevel, PalEntry fogcolor, int sectorfogdensity);
|
||||
bool hw_CheckFog(sector_t *frontsector, sector_t *backsector);
|
||||
|
||||
inline int hw_ClampLight(int lightlevel)
|
||||
{
|
||||
return clamp(lightlevel, 0, 255);
|
||||
}
|
||||
|
|
@ -108,6 +108,9 @@ typedef enum {
|
|||
hDamage_Sludge = 85,
|
||||
Sector_Outside = 87,
|
||||
|
||||
GLSector_NoSkyDraw = 89,
|
||||
GLSector_Skybox = 90,
|
||||
|
||||
// And here are some for Strife
|
||||
sLight_Strobe_Hurt = 104,
|
||||
sDamage_Hellslime = 105,
|
||||
|
|
|
@ -125,4 +125,25 @@ int AddSpecialColormap(float r1, float g1, float b1, float r2, float g2, float b
|
|||
|
||||
extern uint8_t DesaturateColormap[31][256];
|
||||
|
||||
|
||||
enum EColorManipulation
|
||||
{
|
||||
CM_SPECIAL2D = -3, // the special colormaps get passed as color pair from the 2D drawer so they need a different value here.
|
||||
CM_PLAIN2D = -2, // regular 2D drawing.
|
||||
CM_INVALID = -1,
|
||||
CM_DEFAULT = 0, // untranslated
|
||||
CM_FIRSTSPECIALCOLORMAP, // first special fixed colormap
|
||||
CM_FIRSTSPECIALCOLORMAPFORCED = 0x08000000, // first special fixed colormap, application forced (for 2D overlays)
|
||||
|
||||
CM_FOGLAYER = 0x10000000, // Sprite shaped fog layer
|
||||
|
||||
// These are not to be passed to the texture manager
|
||||
CM_LITE = 0x20000000, // special values to handle these items without excessive hacking
|
||||
CM_TORCH = 0x20000010, // These are not real color manipulations
|
||||
};
|
||||
|
||||
#define CM_MAXCOLORMAP int(CM_FIRSTSPECIALCOLORMAP + SpecialColormaps.Size())
|
||||
#define CM_MAXCOLORMAPFORCED int(CM_FIRSTSPECIALCOLORMAPFORCED + SpecialColormaps.Size())
|
||||
|
||||
|
||||
#endif
|
||||
|
|
|
@ -44,6 +44,25 @@
|
|||
#include "v_colortables.h"
|
||||
#include "v_2ddrawer.h"
|
||||
|
||||
enum EHWCaps
|
||||
{
|
||||
// [BB] Added texture compression flags.
|
||||
RFL_TEXTURE_COMPRESSION = 1,
|
||||
RFL_TEXTURE_COMPRESSION_S3TC = 2,
|
||||
|
||||
RFL_SHADER_STORAGE_BUFFER = 4,
|
||||
RFL_BUFFER_STORAGE = 8,
|
||||
RFL_SAMPLER_OBJECTS = 16,
|
||||
|
||||
RFL_NO_CLIP_PLANES = 32,
|
||||
|
||||
RFL_INVALIDATE_BUFFER = 64,
|
||||
RFL_DEBUG = 128,
|
||||
RFL_NO_SHADERS = 256
|
||||
};
|
||||
|
||||
|
||||
|
||||
extern int CleanWidth, CleanHeight, CleanXfac, CleanYfac;
|
||||
extern int CleanWidth_1, CleanHeight_1, CleanXfac_1, CleanYfac_1;
|
||||
extern int DisplayWidth, DisplayHeight, DisplayBits;
|
||||
|
@ -306,6 +325,9 @@ protected:
|
|||
bool Bgra = 0;
|
||||
int clipleft = 0, cliptop = 0, clipwidth = -1, clipheight = -1;
|
||||
|
||||
public:
|
||||
int hwcaps = 0;
|
||||
|
||||
public:
|
||||
DFrameBuffer (int width, int height, bool bgra);
|
||||
virtual ~DFrameBuffer() {}
|
||||
|
@ -359,6 +381,7 @@ public:
|
|||
virtual void UnbindTexUnit(int no) {}
|
||||
virtual void FlushTextures() {}
|
||||
virtual void TextureFilterChanged() {}
|
||||
virtual void ResetFixedColormap() {}
|
||||
|
||||
// Begin 2D drawing operations.
|
||||
// Returns true if hardware-accelerated 2D has been entered, false if not.
|
||||
|
|
Loading…
Reference in a new issue