Refactored lighting manager

This commit is contained in:
Michaël Lemaire 2015-09-25 00:12:31 +02:00
parent ba02442fea
commit 6f2d23d960
16 changed files with 269 additions and 143 deletions

View file

@ -15,6 +15,7 @@
#include "Scenery.h" #include "Scenery.h"
#include "AtmosphereDefinition.h" #include "AtmosphereDefinition.h"
#include "AtmosphereRenderer.h" #include "AtmosphereRenderer.h"
#include "AtmosphereResult.h"
#include "SoftwareRenderer.h" #include "SoftwareRenderer.h"
#include "WaterRenderer.h" #include "WaterRenderer.h"
#include "LightComponent.h" #include "LightComponent.h"
@ -1153,6 +1154,10 @@ AtmosphereModelBruneton::AtmosphereModelBruneton(SoftwareRenderer *parent):
{ {
} }
AtmosphereModelBruneton::~AtmosphereModelBruneton()
{
}
AtmosphereResult AtmosphereModelBruneton::getSkyColor(Vector3 eye, const Vector3 &direction, const Vector3 &sun_position, const Color &base) AtmosphereResult AtmosphereModelBruneton::getSkyColor(Vector3 eye, const Vector3 &direction, const Vector3 &sun_position, const Color &base)
{ {
Vector3 x = {0.0, Rg + eye.y * WORLD_SCALING, 0.0}; Vector3 x = {0.0, Rg + eye.y * WORLD_SCALING, 0.0};
@ -1215,12 +1220,12 @@ AtmosphereResult AtmosphereModelBruneton::applyAerialPerspective(Vector3 locatio
return result; return result;
} }
void AtmosphereModelBruneton::fillLightingStatus(LightStatus *status, const Vector3 &, int) bool AtmosphereModelBruneton::getLightsAt(std::vector<LightComponent> &result, const Vector3 &location) const
{ {
LightComponent sun, irradiance; LightComponent sun, irradiance;
double muS; double muS;
double altitude = status->getLocation().y * WORLD_SCALING; double altitude = location.y * WORLD_SCALING;
double r0 = Rg + WORKAROUND_OFFSET + altitude; double r0 = Rg + WORKAROUND_OFFSET + altitude;
Vector3 up = {0.0, 1.0, 0.0}; Vector3 up = {0.0, 1.0, 0.0};
@ -1241,14 +1246,16 @@ void AtmosphereModelBruneton::fillLightingStatus(LightStatus *status, const Vect
sun.reflection = ISun; sun.reflection = ISun;
sun.altered = 1; sun.altered = 1;
status->pushComponent(sun); result.push_back(sun);
irradiance.color = _irradiance(_irradianceTexture, r0, muS); irradiance.color = _irradiance(_irradianceTexture, r0, muS);
irradiance.direction = VECTOR_DOWN; irradiance.direction = VECTOR_DOWN;
irradiance.reflection = 0.0; irradiance.reflection = 0.0;
irradiance.altered = 0; irradiance.altered = 0;
status->pushComponent(irradiance); result.push_back(irradiance);
return true;
} }
Texture2D *AtmosphereModelBruneton::getTextureTransmittance() const Texture2D *AtmosphereModelBruneton::getTextureTransmittance() const

View file

@ -3,19 +3,20 @@
#include "software_global.h" #include "software_global.h"
#include "AtmosphereResult.h" #include "LightSource.h"
namespace paysages { namespace paysages {
namespace software { namespace software {
class SOFTWARESHARED_EXPORT AtmosphereModelBruneton class SOFTWARESHARED_EXPORT AtmosphereModelBruneton: public LightSource
{ {
public: public:
AtmosphereModelBruneton(SoftwareRenderer *parent); AtmosphereModelBruneton(SoftwareRenderer *parent);
virtual ~AtmosphereModelBruneton();
AtmosphereResult getSkyColor(Vector3 eye, const Vector3 &direction, const Vector3 &sun_position, const Color &base); AtmosphereResult getSkyColor(Vector3 eye, const Vector3 &direction, const Vector3 &sun_position, const Color &base);
AtmosphereResult applyAerialPerspective(Vector3 location, const Color &base); AtmosphereResult applyAerialPerspective(Vector3 location, const Color &base);
void fillLightingStatus(LightStatus *status, const Vector3 &normal, int opaque); virtual bool getLightsAt(std::vector<LightComponent> &result, const Vector3 &location) const override;
/* Functions to get access to internal textures (for opengl shaders) */ /* Functions to get access to internal textures (for opengl shaders) */
Texture2D* getTextureTransmittance() const; Texture2D* getTextureTransmittance() const;

View file

@ -80,15 +80,6 @@ static inline void _applyWeatherEffects(AtmosphereDefinition* definition, Atmosp
BaseAtmosphereRenderer::BaseAtmosphereRenderer(SoftwareRenderer* renderer): BaseAtmosphereRenderer::BaseAtmosphereRenderer(SoftwareRenderer* renderer):
parent(renderer) parent(renderer)
{ {
}
void BaseAtmosphereRenderer::getLightingStatus(LightStatus* status, Vector3, int)
{
for (LightComponent light:lights)
{
status->pushComponent(light);
}
} }
AtmosphereResult BaseAtmosphereRenderer::applyAerialPerspective(Vector3, Color base) AtmosphereResult BaseAtmosphereRenderer::applyAerialPerspective(Vector3, Color base)
@ -109,50 +100,14 @@ AtmosphereResult BaseAtmosphereRenderer::getSkyColor(Vector3)
Vector3 BaseAtmosphereRenderer::getSunDirection(bool cache) const Vector3 BaseAtmosphereRenderer::getSunDirection(bool cache) const
{ {
if (cache and lights.size() > 0)
{
return lights[0].direction.scale(-1.0);
}
else
{
AtmosphereDefinition* atmosphere = getDefinition(); AtmosphereDefinition* atmosphere = getDefinition();
double sun_angle = (atmosphere->propDayTime()->getValue() + 0.75) * M_PI * 2.0; double sun_angle = (atmosphere->propDayTime()->getValue() + 0.75) * M_PI * 2.0;
return Vector3(cos(sun_angle), sin(sun_angle), 0.0); return Vector3(cos(sun_angle), sin(sun_angle), 0.0);
}
} }
void BaseAtmosphereRenderer::setBasicLights() bool BaseAtmosphereRenderer::getLightsAt(std::vector<LightComponent> &, const Vector3 &) const
{ {
LightComponent light; return false;
lights.clear();
light.color.r = 0.6;
light.color.g = 0.6;
light.color.b = 0.6;
light.direction.x = -1.0;
light.direction.y = -0.5;
light.direction.z = 1.0;
light.direction = light.direction.normalize();
light.altered = 1;
light.reflection = 0.0;
lights.push_back(light);
light.color.r = 0.2;
light.color.g = 0.2;
light.color.b = 0.2;
light.direction.x = 1.0;
light.direction.y = -0.5;
light.direction.z = -1.0;
light.direction = light.direction.normalize();
light.altered = 0;
light.reflection = 0.0;
lights.push_back(light);
}
void BaseAtmosphereRenderer::setStaticLights(const std::vector<LightComponent> &lights)
{
this->lights = lights;
} }
AtmosphereDefinition* BaseAtmosphereRenderer::getDefinition() const AtmosphereDefinition* BaseAtmosphereRenderer::getDefinition() const
@ -171,12 +126,6 @@ SoftwareBrunetonAtmosphereRenderer::~SoftwareBrunetonAtmosphereRenderer()
delete model; delete model;
} }
void SoftwareBrunetonAtmosphereRenderer::getLightingStatus(LightStatus* status, Vector3 normal, int opaque)
{
model->fillLightingStatus(status, normal, opaque);
parent->getNightSky()->fillLightingStatus(status, normal, opaque);
}
AtmosphereResult SoftwareBrunetonAtmosphereRenderer::applyAerialPerspective(Vector3 location, Color base) AtmosphereResult SoftwareBrunetonAtmosphereRenderer::applyAerialPerspective(Vector3 location, Color base)
{ {
AtmosphereDefinition* definition = getDefinition(); AtmosphereDefinition* definition = getDefinition();
@ -258,3 +207,11 @@ AtmosphereResult SoftwareBrunetonAtmosphereRenderer::getSkyColor(Vector3 directi
return result; return result;
} }
bool SoftwareBrunetonAtmosphereRenderer::getLightsAt(std::vector<LightComponent> &result, const Vector3 &location) const
{
bool changed = false;
changed |= model->getLightsAt(result, location);
changed |= parent->getNightSky()->getLightsAt(result, location);
return changed;
}

View file

@ -3,30 +3,26 @@
#include "software_global.h" #include "software_global.h"
#include "Color.h" #include "LightSource.h"
#include "LightComponent.h"
namespace paysages { namespace paysages {
namespace software { namespace software {
class BaseAtmosphereRenderer class BaseAtmosphereRenderer: public LightSource
{ {
public: public:
BaseAtmosphereRenderer(SoftwareRenderer* parent); BaseAtmosphereRenderer(SoftwareRenderer* parent);
virtual ~BaseAtmosphereRenderer() {} virtual ~BaseAtmosphereRenderer() {}
virtual void getLightingStatus(LightStatus* status, Vector3 normal, int opaque);
virtual AtmosphereResult applyAerialPerspective(Vector3 location, Color base); virtual AtmosphereResult applyAerialPerspective(Vector3 location, Color base);
virtual AtmosphereResult getSkyColor(Vector3 direction); virtual AtmosphereResult getSkyColor(Vector3 direction);
virtual Vector3 getSunDirection(bool cache=true) const; virtual Vector3 getSunDirection(bool cache=true) const;
void setBasicLights(); virtual bool getLightsAt(std::vector<LightComponent> &result, const Vector3 &location) const override;
void setStaticLights(const std::vector<LightComponent> &lights);
protected: protected:
virtual AtmosphereDefinition* getDefinition() const; virtual AtmosphereDefinition* getDefinition() const;
SoftwareRenderer* parent; SoftwareRenderer* parent;
std::vector<LightComponent> lights;
}; };
class SoftwareBrunetonAtmosphereRenderer: public BaseAtmosphereRenderer class SoftwareBrunetonAtmosphereRenderer: public BaseAtmosphereRenderer
@ -35,10 +31,11 @@ public:
SoftwareBrunetonAtmosphereRenderer(SoftwareRenderer* parent); SoftwareBrunetonAtmosphereRenderer(SoftwareRenderer* parent);
virtual ~SoftwareBrunetonAtmosphereRenderer(); virtual ~SoftwareBrunetonAtmosphereRenderer();
virtual void getLightingStatus(LightStatus* status, Vector3 normal, int opaque) override;
virtual AtmosphereResult applyAerialPerspective(Vector3 location, Color base) override; virtual AtmosphereResult applyAerialPerspective(Vector3 location, Color base) override;
virtual AtmosphereResult getSkyColor(Vector3 direction) override; virtual AtmosphereResult getSkyColor(Vector3 direction) override;
virtual bool getLightsAt(std::vector<LightComponent> &result, const Vector3 &location) const override;
inline const AtmosphereModelBruneton* getModel() const {return model;} inline const AtmosphereModelBruneton* getModel() const {return model;}
private: private:

View file

@ -0,0 +1 @@
#include "LightSource.h"

View file

@ -0,0 +1,28 @@
#ifndef LIGHTSOURCE_H
#define LIGHTSOURCE_H
#include "software_global.h"
namespace paysages {
namespace software {
/**
* Source of dynamic lights.
*/
class SOFTWARESHARED_EXPORT LightSource
{
public:
LightSource() = default;
/**
* Get the list of raw lights that may be applied at a given location.
*
* Returns true if lights were added to *result*.
*/
virtual bool getLightsAt(std::vector<LightComponent> &result, const Vector3 &location) const = 0;
};
}
}
#endif // LIGHTSOURCE_H

View file

@ -2,6 +2,8 @@
#include "LightFilter.h" #include "LightFilter.h"
#include "LightComponent.h" #include "LightComponent.h"
#include "LightStatus.h"
#include "LightSource.h"
#include "Color.h" #include "Color.h"
#include "SurfaceMaterial.h" #include "SurfaceMaterial.h"
@ -10,9 +12,55 @@ LightingManager::LightingManager()
specularity = true; specularity = true;
} }
int LightingManager::getStaticLightsCount() const
{
return static_lights.size();
}
int LightingManager::getSourcesCount() const
{
return sources.size();
}
int LightingManager::getFiltersCount() const
{
return filters.size();
}
void LightingManager::clearStaticLights()
{
static_lights.clear();
}
void LightingManager::addStaticLight(const LightComponent &light)
{
static_lights.push_back(light);
}
void LightingManager::registerSource(LightSource *source)
{
if (std::find(sources.begin(), sources.end(), source) == sources.end())
{
sources.push_back(source);
}
}
void LightingManager::unregisterSource(LightSource *source)
{
sources.erase(std::find(sources.begin(), sources.end(), source));
}
void LightingManager::registerFilter(LightFilter* filter) void LightingManager::registerFilter(LightFilter* filter)
{ {
if (std::find(filters.begin(), filters.end(), filter) == filters.end())
{
filters.push_back(filter); filters.push_back(filter);
}
}
void LightingManager::unregisterFilter(LightFilter *filter)
{
filters.erase(std::find(filters.begin(), filters.end(), filter));
} }
bool LightingManager::alterLight(LightComponent &component, const Vector3 &location) bool LightingManager::alterLight(LightComponent &component, const Vector3 &location)
@ -119,3 +167,26 @@ Color LightingManager::applyFinalComponent(const LightComponent &component, cons
return result; return result;
} }
Color LightingManager::apply(const Vector3 &eye, const Vector3 &location, const Vector3 &normal, const SurfaceMaterial &material)
{
LightStatus status(this, location, eye);
for (auto &light: static_lights)
{
status.pushComponent(light);
}
for (auto source: sources)
{
std::vector<LightComponent> lights;
if (source->getLightsAt(lights, location))
{
for (auto &light: lights)
{
status.pushComponent(light);
}
}
}
return status.apply(normal, material);
}

View file

@ -3,44 +3,86 @@
#include "software_global.h" #include "software_global.h"
#include "LightComponent.h"
namespace paysages { namespace paysages {
namespace software { namespace software {
/** /**
* @brief Global lighting manager. * @brief Global lighting manager.
* *
* This manager handles the light filters and final light rendering. * This manager handles the lights, light filters and final light rendering.
*
* There are both static and dynamic lights.
* A dynamic light depends on the location at which the lighting occurs.
*/ */
class SOFTWARESHARED_EXPORT LightingManager class SOFTWARESHARED_EXPORT LightingManager
{ {
public: public:
LightingManager(); LightingManager();
/** int getStaticLightsCount() const;
* @brief Register a filter that will receive all alterable lights. int getSourcesCount() const;
*/ int getFiltersCount() const;
void registerFilter(LightFilter* filter);
/** /**
* @brief Alter the light component at a given location. * Clear the static lights.
* @return true if the light is useful */
void clearStaticLights();
/**
* Add a static light.
*/
void addStaticLight(const LightComponent &light);
/**
* Register a source of dynamic lighting.
*/
void registerSource(LightSource *source);
/**
* Remove a registered light source.
*/
void unregisterSource(LightSource *source);
/**
* Register a filter that will receive all alterable lights.
*/
void registerFilter(LightFilter *filter);
/**
* Remove a registered light filter.
*/
void unregisterFilter(LightFilter *filter);
/**
* Alter the light component at a given location.
*
* Returns true if the light is useful
*/ */
bool alterLight(LightComponent &component, const Vector3 &location); bool alterLight(LightComponent &component, const Vector3 &location);
/** /**
* @brief Enable or disable the specularity lighting. * Enable or disable the specularity lighting.
*/ */
void setSpecularity(bool enabled); void setSpecularity(bool enabled);
/** /**
* @brief Apply a final component on a surface material. * Apply a final component on a surface material.
*/ */
Color applyFinalComponent(const LightComponent &component, const Vector3 &eye, const Vector3 &location, const Vector3 &normal, const SurfaceMaterial &material); Color applyFinalComponent(const LightComponent &component, const Vector3 &eye, const Vector3 &location, const Vector3 &normal, const SurfaceMaterial &material);
/**
* Apply lighting to a surface at a given location.
*/
Color apply(const Vector3 &eye, const Vector3 &location, const Vector3 &normal, const SurfaceMaterial &material);
private: private:
int specularity; int specularity;
std::vector<LightComponent> static_lights;
std::vector<LightFilter *> filters;
std::vector<LightSource *> sources;
std::vector<LightFilter*> filters;
}; };
} }

View file

@ -95,7 +95,7 @@ const Color NightSky::getColor(double altitude, const Vector3 &direction)
} }
void NightSky::fillLightingStatus(LightStatus *status, const Vector3 &, int) bool NightSky::getLightsAt(std::vector<LightComponent> &result, const Vector3 &location) const
{ {
LightComponent moon, sky; LightComponent moon, sky;
@ -107,12 +107,14 @@ void NightSky::fillLightingStatus(LightStatus *status, const Vector3 &, int)
moon.reflection = 0.2; moon.reflection = 0.2;
moon.altered = 1; moon.altered = 1;
status->pushComponent(moon); result.push_back(moon);
sky.color = Color(0.01, 0.012, 0.03); sky.color = Color(0.01, 0.012, 0.03);
sky.direction = VECTOR_DOWN; sky.direction = VECTOR_DOWN;
sky.reflection = 0.0; sky.reflection = 0.0;
sky.altered = 0; sky.altered = 0;
status->pushComponent(sky); result.push_back(sky);
return true;
} }

View file

@ -3,13 +3,15 @@
#include "software_global.h" #include "software_global.h"
#include "LightSource.h"
namespace paysages { namespace paysages {
namespace software { namespace software {
/*! /*!
* \brief Night sky renderer. * \brief Night sky renderer.
*/ */
class SOFTWARESHARED_EXPORT NightSky class SOFTWARESHARED_EXPORT NightSky: public LightSource
{ {
public: public:
NightSky(SoftwareRenderer* renderer); NightSky(SoftwareRenderer* renderer);
@ -26,7 +28,7 @@ public:
*/ */
virtual const Color getColor(double altitude, const Vector3 &direction); virtual const Color getColor(double altitude, const Vector3 &direction);
virtual void fillLightingStatus(LightStatus *status, const Vector3 &normal, int opaque); virtual bool getLightsAt(std::vector<LightComponent> &result, const Vector3 &location) const override;
private: private:
SoftwareRenderer* renderer; SoftwareRenderer* renderer;

View file

@ -41,6 +41,7 @@ SoftwareRenderer::SoftwareRenderer(Scenery* scenery):
lighting->registerFilter(water_renderer); lighting->registerFilter(water_renderer);
lighting->registerFilter(terrain_renderer); lighting->registerFilter(terrain_renderer);
lighting->registerFilter(clouds_renderer); lighting->registerFilter(clouds_renderer);
lighting->registerSource(atmosphere_renderer);
setQuality(0.5); setQuality(0.5);
} }
@ -66,7 +67,8 @@ void SoftwareRenderer::prepare()
scenery->validate(); scenery->validate();
// Prepare sub renderers // Prepare sub renderers
// TODO Don't recreate the renderer each time // TODO Don't recreate the renderer each time, only when it changes
lighting->unregisterSource(atmosphere_renderer);
delete atmosphere_renderer; delete atmosphere_renderer;
if (getScenery()->getAtmosphere()->model == AtmosphereDefinition::ATMOSPHERE_MODEL_BRUNETON) if (getScenery()->getAtmosphere()->model == AtmosphereDefinition::ATMOSPHERE_MODEL_BRUNETON)
{ {
@ -76,6 +78,7 @@ void SoftwareRenderer::prepare()
{ {
atmosphere_renderer = new BaseAtmosphereRenderer(this); atmosphere_renderer = new BaseAtmosphereRenderer(this);
} }
lighting->registerSource(atmosphere_renderer);
clouds_renderer->update(); clouds_renderer->update();
terrain_renderer->update(); terrain_renderer->update();
@ -98,50 +101,9 @@ void SoftwareRenderer::setQuality(double quality)
render_quality = (int)(quality * 9.0) + 1; render_quality = (int)(quality * 9.0) + 1;
} }
void SoftwareRenderer::disableAtmosphere()
{
LightComponent light;
std::vector<LightComponent> lights;
light.color.r = 1.5;
light.color.g = 1.5;
light.color.b = 1.5;
light.direction.x = -1.0;
light.direction.y = -0.3;
light.direction.z = 1.0;
light.direction = light.direction.normalize();
light.altered = 1;
light.reflection = 0.0;
lights.push_back(light);
light.color.r = 0.25;
light.color.g = 0.25;
light.color.b = 0.265;
light.direction.x = 1.0;
light.direction.y = -0.5;
light.direction.z = -1.0;
light.direction = light.direction.normalize();
light.altered = 0;
light.reflection = 0.0;
lights.push_back(light);
disableAtmosphere(lights);
}
void SoftwareRenderer::disableAtmosphere(const std::vector<LightComponent> &lights)
{
scenery->getAtmosphere()->model = AtmosphereDefinition::ATMOSPHERE_MODEL_DISABLED;
delete atmosphere_renderer;
atmosphere_renderer = new BaseAtmosphereRenderer(this);
atmosphere_renderer->setStaticLights(lights);
}
Color SoftwareRenderer::applyLightingToSurface(const Vector3 &location, const Vector3 &normal, const SurfaceMaterial &material) Color SoftwareRenderer::applyLightingToSurface(const Vector3 &location, const Vector3 &normal, const SurfaceMaterial &material)
{ {
LightStatus status(lighting, location, getCameraLocation(location)); return lighting->apply(getCameraLocation(location), location, normal, material);
atmosphere_renderer->getLightingStatus(&status, normal, 0);
return status.apply(normal, material);
} }
Color SoftwareRenderer::applyMediumTraversal(Vector3 location, Color color) Color SoftwareRenderer::applyMediumTraversal(Vector3 location, Color color)

View file

@ -45,16 +45,6 @@ public:
*/ */
virtual void setQuality(double quality); virtual void setQuality(double quality);
/*!
* \brief Disable atmosphere and sky lighting, replacing it by static lights.
*
* This function needs to be called after each prepare().
*
* WARNING : This method changes the scenery attached to the renderer !
*/
void disableAtmosphere();
void disableAtmosphere(const std::vector<LightComponent> &lights);
inline Scenery* getScenery() const {return scenery;} inline Scenery* getScenery() const {return scenery;}
inline BaseAtmosphereRenderer* getAtmosphereRenderer() const {return atmosphere_renderer;} inline BaseAtmosphereRenderer* getAtmosphereRenderer() const {return atmosphere_renderer;}

View file

@ -51,7 +51,8 @@ SOURCES += SoftwareRenderer.cpp \
clouds/CloudModelAltoCumulus.cpp \ clouds/CloudModelAltoCumulus.cpp \
clouds/CloudModelCirrus.cpp \ clouds/CloudModelCirrus.cpp \
clouds/CloudModelCumuloNimbus.cpp \ clouds/CloudModelCumuloNimbus.cpp \
RenderProgress.cpp RenderProgress.cpp \
LightSource.cpp
HEADERS += SoftwareRenderer.h\ HEADERS += SoftwareRenderer.h\
software_global.h \ software_global.h \
@ -92,7 +93,8 @@ HEADERS += SoftwareRenderer.h\
clouds/CloudModelAltoCumulus.h \ clouds/CloudModelAltoCumulus.h \
clouds/CloudModelCirrus.h \ clouds/CloudModelCirrus.h \
clouds/CloudModelCumuloNimbus.h \ clouds/CloudModelCumuloNimbus.h \
RenderProgress.h RenderProgress.h \
LightSource.h
unix:!symbian { unix:!symbian {
maemo5 { maemo5 {

View file

@ -43,6 +43,7 @@ namespace software {
class LightStatus; class LightStatus;
class LightFilter; class LightFilter;
class LightComponent; class LightComponent;
class LightSource;
class NightSky; class NightSky;

View file

@ -0,0 +1,62 @@
#include "BaseTestCase.h"
#include "LightingManager.h"
#include "LightSource.h"
#include "LightFilter.h"
class FakeLightSource: public LightSource
{
virtual bool getLightsAt(std::vector<LightComponent> &, const Vector3 &) const override
{
return false;
}
};
TEST(LightingManager, registerSource)
{
LightingManager manager;
FakeLightSource source;
EXPECT_EQ(0, manager.getSourcesCount());
manager.registerSource(&source);
EXPECT_EQ(1, manager.getSourcesCount());
manager.registerSource(&source);
EXPECT_EQ(1, manager.getSourcesCount());
manager.unregisterSource(&source);
EXPECT_EQ(0, manager.getSourcesCount());
}
class FakeLightFilter: public LightFilter
{
virtual bool applyLightFilter(LightComponent &, const Vector3 &) override
{
return false;
}
};
TEST(LightingManager, registerFilter)
{
LightingManager manager;
FakeLightFilter filter;
EXPECT_EQ(0, manager.getFiltersCount());
manager.registerFilter(&filter);
EXPECT_EQ(1, manager.getFiltersCount());
manager.registerFilter(&filter);
EXPECT_EQ(1, manager.getFiltersCount());
manager.unregisterFilter(&filter);
EXPECT_EQ(0, manager.getFiltersCount());
}

View file

@ -28,7 +28,8 @@ SOURCES += main.cpp \
DiffManager_Test.cpp \ DiffManager_Test.cpp \
ColorHSL_Test.cpp \ ColorHSL_Test.cpp \
RenderProgress_Test.cpp \ RenderProgress_Test.cpp \
IntNode_Test.cpp IntNode_Test.cpp \
LightingManager_Test.cpp
HEADERS += \ HEADERS += \
BaseTestCase.h BaseTestCase.h