Skip to content

Commit

Permalink
Map Renderer|Light Grid: Updated LightGrid implementation; addressed …
Browse files Browse the repository at this point in the history
…limitations

Revised the LightGrid, re-implementing it in C++ with Doomsday 2.0
components. The internal design of this component is mostly unchanged
however.

Noteworthy changes:
* The grid is initialized automatically should it be enabled after
the map has already loaded.
* Significantly reduced memory requirements through the use of a sparse
grid of block references and a special "null-block".
* An instance of LightGrid is now owned by the GameMap rather than a
global "singleton".
  • Loading branch information
danij-deng committed May 21, 2013
1 parent 3d294f4 commit 09c715b
Show file tree
Hide file tree
Showing 17 changed files with 891 additions and 913 deletions.
30 changes: 30 additions & 0 deletions doomsday/client/include/map/gamemap.h
Expand Up @@ -31,6 +31,10 @@
#include "p_particle.h"
#include "Polyobj"

#ifdef __CLIENT__
# include "render/r_lgrid.h"
#endif

class Vertex;
class Line;
class Sector;
Expand Down Expand Up @@ -76,6 +80,11 @@ struct clpolyobj_s;
class GameMap
{
public:
#ifdef __CLIENT__
/// Required light grid is missing. @ingroup errors
DENG2_ERROR(MissingLightGridError);
#endif

typedef QList<Vertex *> Vertexes;
typedef QList<Sector *> Sectors;
typedef QList<Line *> Lines;
Expand Down Expand Up @@ -603,6 +612,27 @@ class GameMap

#ifdef __CLIENT__
void buildSurfaceLists();

/**
* Returns @c true iff a LightGrid has been initialized for the map.
*
* @see lightGrid()
*/
bool hasLightGrid();

/**
* Provides access to the light grid for the map.
*
* @see hasLightGrid()
*/
de::LightGrid &lightGrid();

/**
* Initialize the ambient lighting grid (smoothed sector lighting).
* If the grid has already been initialized calling this will perform
* a full update.
*/
void initLightGrid();
#endif

bool buildBsp();
Expand Down
1 change: 0 additions & 1 deletion doomsday/client/include/map/sector.h
Expand Up @@ -43,7 +43,6 @@ class Surface;
*/
///@{
#define SIF_VISIBLE 0x1 ///< Sector is visible on this frame.
#define SIF_LIGHT_CHANGED 0x2

// Flags to clear before each frame.
#define SIF_FRAME_CLEAR SIF_VISIBLE
Expand Down
6 changes: 5 additions & 1 deletion doomsday/client/include/network/net_main.h
Expand Up @@ -251,7 +251,11 @@ int Net_TimeDelta(byte now, byte then);
void Net_Update(void);
void Net_ResetTimer(void);
void Net_Ticker(timespan_t time);
void Net_Drawer(void);

/**
* Does drawing for the engine's HUD, not just the net.
*/
void Net_Drawer(void);

boolean Net_IsLocalPlayer(int pNum);

Expand Down
129 changes: 93 additions & 36 deletions doomsday/client/include/render/r_lgrid.h
@@ -1,4 +1,4 @@
/** @file r_lgrid.h
/** @file render/r_lgrid.h Light Grid (Smoothed ambient sector lighting).
*
* @authors Copyright © 2003-2013 Jaakko Keränen <jaakko.keranen@iki.fi>
* @authors Copyright © 2006-2013 Daniel Swanson <danij@dengine.net>
Expand All @@ -17,51 +17,108 @@
* http://www.gnu.org/licenses</small>
*/

/**
* Smoothed ambient sector lighting.
*/

#ifndef LIBDENG_REFRESH_LIGHT_GRID_H
#define LIBDENG_REFRESH_LIGHT_GRID_H
#ifndef DENG_RENDER_LIGHT_GRID_H
#define DENG_RENDER_LIGHT_GRID_H

#include "dd_types.h"
#include "map/p_mapdata.h"

#ifdef __cplusplus
extern "C" {
#endif
#include <de/Vector>

void LG_Register(void);
void LG_InitForMap(void);
void LG_Update(void);

/**
* Called when a setting is changed which affects the lightgrid.
*/
void LG_MarkAllForUpdate(void);
class GameMap;
class Sector;

void LG_SectorChanged(Sector* sector);
namespace de {

/**
* Calculate the light color for a 3D point in the world.
* Simple global illumination method utilizing a 2D grid of light levels, achieving
* smoothed ambient sector lighting.
*
* @param point 3D point.
* @param destColor Evaluated color of the point (return value).
* @ingroup render
*/
void LG_Evaluate(coord_t const point[3], float destColor[3]);
class LightGrid
{
public:
/**
* Two dimensioned reference to a block in the grid [X, Y].
*/
typedef Vector2i Ref;

/**
* Calculate the light level for a 3D point in the world.
*
* @param point 3D point.
* @return Evaluated light level of the point.
*/
float LG_EvaluateLightLevel(coord_t const point[3]);
/**
* Linear reference to a block in the grid (X + Y * Grid Width).
*/
typedef int Index;

public:
/**
* Construct and initialize a new LightGrid for the specifed map.
*
* @note Initialization may take some time depending on the complexity of the map
* (world dimensions, number of sectors) and should therefore be done "off-line".
*/
LightGrid(GameMap &map);

/**
* Register the console comands and variables of this module.
*/
static void consoleRegister();

/**
* Update the grid by finding the strongest light source in each grid block.
* Should be called periodically to update/refresh the grid contents (e.g., when
* beginning a new render frame).
*/
void update();

/**
* To be called when an engine variable which affects the lightgrid changes.
*/
void markAllForUpdate();

/**
* Returns the dimensions of the light grid in blocks. For informational purposes.
*/
Vector2i const &dimensions() const;

/**
* Returns the size of grid block in map coordinate space units. For informational
* purposes.
*/
coord_t blockSize() const;

/**
* Determine the ambient light color for a point in the map coordinate space.
*
* @param point 3D point.
*
* @return Evaluated color at the specified point.
*/
Vector3f evaluate(Vector3d const &point);

/**
* Determine the ambient light level for a point in the map coordinate space.
*
* @param point 3D point.
*
* @return Evaluated light level at the specified point.
*/
float evaluateLightLevel(Vector3d const &point);

/**
* To be called when the ambient lighting properties in the sector change.
*
* @todo Replace with internal de::Observers based mechanism.
*/
void sectorChanged(Sector &sector);

/**
* Draw the light grid debug visual.
*/
void drawDebugVisual();

void LG_Debug(void);
private:
DENG2_PRIVATE(d)
};

#ifdef __cplusplus
} // extern "C"
#endif
} // namespace de

#endif // LIBDENG_REFRESH_LIGHT_GRID_H
#endif // DENG_RENDER_LIGHT_GRID_H
34 changes: 34 additions & 0 deletions doomsday/client/src/map/gamemap.cpp
Expand Up @@ -20,6 +20,8 @@

#include <cmath>

#include <de/libdeng2.h>

#include "de_base.h"
#include "de_console.h"
#include "de_play.h"
Expand Down Expand Up @@ -59,6 +61,8 @@ DENG2_PIMPL(GameMap)
#ifdef __CLIENT__
SurfaceSet decoratedSurfaces;
SurfaceSet glowingSurfaces;

QScopedPointer<LightGrid> lightGrid;
#endif

coord_t skyFix[2]; // [floor, ceiling]
Expand Down Expand Up @@ -690,6 +694,36 @@ void GameMap::buildSurfaceLists()
}
}

bool GameMap::hasLightGrid()
{
return !d->lightGrid.isNull();
}

LightGrid &GameMap::lightGrid()
{
if(!d->lightGrid.isNull())
{
return *d->lightGrid;
}
/// @throw MissingLightGrid Attempted with no LightGrid initialized.
throw MissingLightGridError("GameMap::lightGrid", "No light grid is initialized");
}

void GameMap::initLightGrid()
{
// Disabled?
if(!Con_GetInteger("rend-bias-grid"))
return;

// Time to initialize the LightGrid?
if(d->lightGrid.isNull())
{
d->lightGrid.reset(new LightGrid(*this));
}
// Perform a full update right away.
d->lightGrid->update();
}

#endif // __CLIENT__

de::Uri GameMap::uri() const
Expand Down
3 changes: 1 addition & 2 deletions doomsday/client/src/map/p_data.cpp
Expand Up @@ -228,8 +228,7 @@ DENG_EXTERN_C boolean P_LoadMap(char const *uriCString)
R_InitShadowProjectionListsForMap(); // Projected mobj shadows.
VL_InitForMap(); // Converted vlights (from lumobjs) management.

// Initialize the lighting grid.
LG_InitForMap();
theMap->initLightGrid();

R_InitRendPolyPools();
#endif
Expand Down
10 changes: 4 additions & 6 deletions doomsday/client/src/map/p_dmu.cpp
Expand Up @@ -833,15 +833,13 @@ static void updateSector(Sector &sector, bool forceUpdate = false)
sector._lightColor[1] != sector._oldLightColor[1] ||
sector._lightColor[2] != sector._oldLightColor[2]))
{
sector._frameFlags |= SIF_LIGHT_CHANGED;
sector._oldLightLevel = sector._lightLevel;
sector._oldLightColor = sector._lightColor;

LG_SectorChanged(&sector);
}
else
{
sector._frameFlags &= ~SIF_LIGHT_CHANGED;
if(theMap->hasLightGrid())
{
theMap->lightGrid().sectorChanged(sector);
}
}
#endif
}
Expand Down
11 changes: 1 addition & 10 deletions doomsday/client/src/network/net_main.cpp
Expand Up @@ -741,18 +741,9 @@ void Net_DrawDemoOverlay(void)

#endif // __CLIENT__

/**
* Does drawing for the engine's HUD, not just the net.
*/
void Net_Drawer(void)
void Net_Drawer()
{
#ifdef __CLIENT__
// Draw the Shadow Bias Editor HUD (if it is active).
SBE_DrawHUD();

// Draw lightgrid debug display.
LG_Debug();

// Draw the blockmap debug display.
Rend_BlockmapDebug();

Expand Down

0 comments on commit 09c715b

Please sign in to comment.