Skip to content

Commit

Permalink
WallSpec: Added flags NearFade and SortDynLights
Browse files Browse the repository at this point in the history
  • Loading branch information
danij-deng committed May 25, 2013
1 parent 6bd775a commit e8b682d
Show file tree
Hide file tree
Showing 4 changed files with 69 additions and 50 deletions.
2 changes: 0 additions & 2 deletions doomsday/client/include/render/walledge.h
Expand Up @@ -93,8 +93,6 @@ class WallEdge : public WorldEdge

coord_t mapSideOffset() const;

inline Surface &surface() const { return mapSide().surface(spec().section); }

/// Implement IEdge.
bool isValid() const;

Expand Down
24 changes: 15 additions & 9 deletions doomsday/client/include/render/wallspec.h
Expand Up @@ -35,29 +35,35 @@ class WallSpec
enum Flag
{
/// Force the geometry to be opaque, irrespective of material opacity.
ForceOpaque = 0x01,
ForceOpaque = 0x001,

/// Fade out the geometry the closer it is to the viewer.
NearFade = 0x002,

/**
* Clip the geometry if the neighbor plane surface relevant for the
* specified section (i.e., the floor if @c Side::Bottom or ceiling
* if @c Side::Top) has a sky-masked material bound to it.
* specified section (i.e., the floor if @c Side::Bottom or ceiling if
* @c Side::Top) has a sky-masked material bound to it.
*/
SkyClip = 0x02,
SkyClip = 0x004,

/// Sort the dynamic light projections by descending luminosity.
SortDynLights = 0x008,

/// Do not generate geometry for dynamic lights.
NoDynLights = 0x04,
NoDynLights = 0x010,

/// Do not generate geometry for dynamic (mobj) shadows.
NoDynShadows = 0x08,
NoDynShadows = 0x020,

/// Do not generate geometry for faked radiosity.
NoFakeRadio = 0x10,
NoFakeRadio = 0x040,

/// Do not apply angle based light level deltas.
NoLightDeltas = 0x20,
NoLightDeltas = 0x080,

/// Do not smooth edge normals.
NoEdgeNormalSmoothing = 0x40,
NoEdgeNormalSmoothing = 0x100,

DefaultFlags = ForceOpaque | SkyClip
};
Expand Down
77 changes: 39 additions & 38 deletions doomsday/client/src/render/rend_main.cpp
Expand Up @@ -1333,38 +1333,46 @@ static uint projectSurfaceShadows(Surface &surface, float glowStrength,
surface.tangent(), surface.bitangent(), surface.normal());
}

static bool writeWallGeometry(WallEdge **edges, BiasSurface &biasSurface,
MapElement &mapElement, coord_t *bottomZ = 0, coord_t *topZ = 0)
static void writeWallGeometry(WallEdge **edges, BiasSurface &biasSurface,
MapElement &biasSurfaceOwner,
coord_t *retBottomZ = 0, coord_t *retTopZ = 0, bool *retWroteOpaque = 0)
{
BspLeaf *bspLeaf = currentBspLeaf;
DENG_ASSERT(!isNullLeaf(bspLeaf));

WallEdge const &leftEdge = *edges[0];
WallEdge const &rightEdge = *edges[1];
if(retBottomZ) *retBottomZ = 0;
if(retTopZ) *retTopZ = 0;
if(retWroteOpaque) *retWroteOpaque = false;

WallEdge const &leftEdge = *edges[0];
WallEdge const &rightEdge = *edges[1];

if(!leftEdge.isValid() || !rightEdge.isValid() ||
de::fequal(leftEdge.bottom().distance(), rightEdge.top().distance()))
return false;
return;

if(bottomZ) *bottomZ = leftEdge.bottom().distance();
if(topZ) *topZ = rightEdge.top().distance();
WallSpec const &wallSpec = leftEdge.spec();
Line::Side &side = leftEdge.mapSide();
Surface &surface = side.surface(wallSpec.section);
bool const isTwoSidedMiddle = (wallSpec.section == Line::Side::Middle && !side.considerOneSided());

WallSpec const &wallSpec = leftEdge.spec();
Line::Side &side = leftEdge.mapSide();
Surface &surface = leftEdge.surface();
float opacity = surface.opacity();
if(!(opacity > .001f))
return;

bool const isTwoSidedMiddle =
(wallSpec.section == Line::Side::Middle && !side.considerOneSided());
// Determine which Material to use.
/// @todo Should have chosen by now...
Material *material = chooseSurfaceMaterialForTexturingMode(surface);

float opacity = surface.opacity();
// A drawable material is required.
if(!material || !material->isDrawable())
return;

// Apply a fade out when the viewer is near to this geometry?
bool didNearFade = false;
if(isTwoSidedMiddle &&
((viewPlayer->shared.flags & (DDPF_NOCLIP|DDPF_CAMERA)) ||
!(side.line().isFlagged(DDLF_BLOCKING))) &&
(vOrigin[VY] > leftEdge.bottom().distance() &&
vOrigin[VY] < rightEdge.top().distance()))

if(wallSpec.flags.testFlag(WallSpec::NearFade) &&
(vOrigin[VY] > leftEdge.bottom().distance() && vOrigin[VY] < rightEdge.top().distance()))
{
mobj_t const *mo = viewPlayer->shared.mo;

Expand Down Expand Up @@ -1401,20 +1409,13 @@ static bool writeWallGeometry(WallEdge **edges, BiasSurface &biasSurface,
}
}

if(opacity <= 0) return false;

// Determine which Material to use.
Material *material = chooseSurfaceMaterialForTexturingMode(surface);

// Surfaces without a drawable material are never rendered.
if(!material || !material->isDrawable())
return false;
if(!(opacity > .001f))
return;

Vector2f materialScale((surface.flags() & DDSUF_MATERIAL_FLIPH)? -1 : 1,
(surface.flags() & DDSUF_MATERIAL_FLIPV)? -1 : 1);

Vector3d texTL(leftEdge.top().origin());
Vector3d texBR(rightEdge.bottom().origin());
Vector3d texQuad[] = { leftEdge.top().origin(), rightEdge.bottom().origin() };

// Calculate the light level deltas for this wall section?
float leftLightLevelDelta = 0, rightLightLevelDelta = 0;
Expand All @@ -1428,12 +1429,12 @@ static bool writeWallGeometry(WallEdge **edges, BiasSurface &biasSurface,
parm.flags = RPF_DEFAULT;
parm.forceOpaque = wallSpec.flags.testFlag(WallSpec::ForceOpaque);
parm.alpha = parm.forceOpaque? 1 : opacity;
parm.mapElement = &mapElement;
parm.mapElement = &biasSurfaceOwner;
parm.elmIdx = wallSpec.section;
parm.bsuf = &biasSurface;
parm.normal = &surface.normal();
parm.texTL = &texTL;
parm.texBR = &texBR;
parm.texTL = &texQuad[0];
parm.texBR = &texQuad[1];
parm.surfaceLightLevelDL = leftLightLevelDelta;
parm.surfaceLightLevelDR = rightLightLevelDelta;
parm.blendMode = BM_NORMAL;
Expand Down Expand Up @@ -1486,15 +1487,15 @@ static bool writeWallGeometry(WallEdge **edges, BiasSurface &biasSurface,
if(!wallSpec.flags.testFlag(WallSpec::NoDynLights) &&
!(parm.flags & RPF_SKYMASK))
{
parm.lightListIdx = projectSurfaceLights(surface, parm.glowing, texTL, texBR,
isTwoSidedMiddle);
parm.lightListIdx = projectSurfaceLights(surface, parm.glowing, texQuad[0], texQuad[1],
wallSpec.flags.testFlag(WallSpec::SortDynLights));
}

// Project dynamic shadows?
if(!wallSpec.flags.testFlag(WallSpec::NoDynShadows) &&
!(parm.flags & RPF_SKYMASK))
{
parm.shadowListIdx = projectSurfaceShadows(surface, parm.glowing, texTL, texBR);
parm.shadowListIdx = projectSurfaceShadows(surface, parm.glowing, texQuad[0], texQuad[1]);
}

/*
Expand Down Expand Up @@ -1569,7 +1570,9 @@ static bool writeWallGeometry(WallEdge **edges, BiasSurface &biasSurface,

R_FreeRendVertices(rvertices);

return opaque && !didNearFade;
if(retBottomZ) *retBottomZ = leftEdge.bottom().distance();
if(retTopZ) *retTopZ = rightEdge.top().distance();
if(retWroteOpaque) *retWroteOpaque = opaque && !didNearFade;
}

static void writeWallSection(HEdge &hedge, int section,
Expand All @@ -1585,9 +1588,7 @@ static void writeWallSection(HEdge &hedge, int section,
WallEdge rightEdge(spec, hedge, Line::To);
WallEdge *edges[] = { &leftEdge, &rightEdge };

bool wroteOpaque = writeWallGeometry(edges, biasSurface, hedge, retBottomZ, retTopZ);

if(retWroteOpaque) *retWroteOpaque = wroteOpaque;
writeWallGeometry(edges, biasSurface, hedge, retBottomZ, retTopZ, retWroteOpaque);
}

/**
Expand Down
16 changes: 15 additions & 1 deletion doomsday/client/src/render/wallspec.cpp
Expand Up @@ -17,6 +17,9 @@
* 02110-1301 USA</small>
*/

#include "de_base.h"

#include "map/p_players.h" // viewPlayer
#include "render/rend_main.h"

#include "render/walledge.h"
Expand All @@ -42,11 +45,22 @@ static bool useWallSectionLightLevelDeltas(Line::Side const &side, int section)

WallSpec WallSpec::fromMapSide(Line::Side const &side, int section) // static
{
bool const isTwoSidedMiddle = (section == Line::Side::Middle && !side.considerOneSided());

WallSpec spec(section);

if(side.line().definesPolyobj() || (section == Line::Side::Middle && !side.considerOneSided()))
if(side.line().definesPolyobj() || isTwoSidedMiddle)
spec.flags &= ~WallSpec::ForceOpaque;

if(isTwoSidedMiddle)
{
if(viewPlayer && ((viewPlayer->shared.flags & (DDPF_NOCLIP|DDPF_CAMERA)) ||
!side.line().isFlagged(DDLF_BLOCKING)))
spec.flags |= WallSpec::NearFade;

spec.flags |= WallSpec::SortDynLights;
}

// Suppress the sky clipping in debug mode.
if(devRendSkyMode)
spec.flags &= ~WallSpec::SkyClip;
Expand Down

0 comments on commit e8b682d

Please sign in to comment.