diff --git a/src/graphics/engine/engine.h b/src/graphics/engine/engine.h index 0647fbda..f9dfd451 100644 --- a/src/graphics/engine/engine.h +++ b/src/graphics/engine/engine.h @@ -729,7 +729,7 @@ public: //@{ //! Management of game pause mode void SetPause(bool pause); - bool GetPause(); + TEST_VIRTUAL bool GetPause(); //@} //@{ @@ -1170,9 +1170,9 @@ public: //! Returns the view matrix const Math::Matrix& GetMatView(); //! Returns the camera center point - Math::Vector GetEyePt(); + TEST_VIRTUAL Math::Vector GetEyePt(); //! Returns the camera target point - Math::Vector GetLookatPt(); + TEST_VIRTUAL Math::Vector GetLookatPt(); //! Returns the horizontal direction angle of view float GetEyeDirH(); //! Returns the vertical direction angle of view diff --git a/src/graphics/engine/lightman.cpp b/src/graphics/engine/lightman.cpp index 4a8fd609..628ebf51 100644 --- a/src/graphics/engine/lightman.cpp +++ b/src/graphics/engine/lightman.cpp @@ -26,6 +26,7 @@ #include +#include // Graphics module namespace @@ -386,39 +387,10 @@ void CLightManager::UpdateDeviceLights(EngineObjectType type) for (int i = 0; i < static_cast( m_lightMap.size() ); ++i) m_lightMap[i] = -1; - // High priority - for (int i = 0; i < static_cast( m_dynLights.size() ); i++) - { - if (! m_dynLights[i].used) - continue; - if (! m_dynLights[i].enabled) - continue; - if (Math::IsZero(m_dynLights[i].intensity.current)) - continue; - if (m_dynLights[i].priority == LIGHT_PRI_LOW) - continue; + std::vector sortedLights = m_dynLights; + std::sort(sortedLights.begin(), sortedLights.end(), LightsComparator(m_engine->GetEyePt(), type)); - bool enabled = true; - if (m_dynLights[i].includeType != ENG_OBJTYPE_NULL) - enabled = (m_dynLights[i].includeType == type); - - if (m_dynLights[i].excludeType != ENG_OBJTYPE_NULL) - enabled = (m_dynLights[i].excludeType != type); - - if (enabled) - { - for (int j = 0; j < static_cast( m_lightMap.size() ); ++j) - { - if (m_lightMap[j] == -1) - { - m_lightMap[j] = i; - break; - } - } - } - } - - // Low priority + int lightMapIndex = 0; for (int i = 0; i < static_cast( m_dynLights.size() ); i++) { if (! m_dynLights[i].used) @@ -427,8 +399,6 @@ void CLightManager::UpdateDeviceLights(EngineObjectType type) continue; if (m_dynLights[i].intensity.current == 0.0f) continue; - if (m_dynLights[i].priority == LIGHT_PRI_HIGH) - continue; bool enabled = true; if (m_dynLights[i].includeType != ENG_OBJTYPE_NULL) @@ -439,15 +409,12 @@ void CLightManager::UpdateDeviceLights(EngineObjectType type) if (enabled) { - for (int j = 0; j < static_cast( m_lightMap.size() ); ++j) - { - if (m_lightMap[j] == -1) - { - m_lightMap[j] = i; - break; - } - } + m_lightMap[lightMapIndex] = i; + ++lightMapIndex; } + + if (lightMapIndex >= static_cast( m_lightMap.size() )) + break; } for (int i = 0; i < static_cast( m_lightMap.size() ); ++i) @@ -465,5 +432,33 @@ void CLightManager::UpdateDeviceLights(EngineObjectType type) } } +// ----------- + +CLightManager::LightsComparator::LightsComparator(Math::Vector eyePos, EngineObjectType objectType) +{ + m_eyePos = eyePos; + m_objectType = objectType; +} + +float CLightManager::LightsComparator::GetLightWeight(const DynamicLight& dynLight) +{ + bool enabled = true; + if (!dynLight.used || !dynLight.enabled || dynLight.intensity.current == 0.0f) + enabled = false; + else if (dynLight.includeType != ENG_OBJTYPE_NULL) + enabled = dynLight.includeType == m_objectType; + else if (dynLight.excludeType != ENG_OBJTYPE_NULL) + enabled = dynLight.excludeType != m_objectType; + + return enabled ? ( (dynLight.light.position - m_eyePos).Length() * dynLight.priority ) : 10000.0f; +} + +bool CLightManager::LightsComparator::operator()(const DynamicLight& left, const DynamicLight& right) +{ + float leftWeight = GetLightWeight(left); + float rightWeight = GetLightWeight(right); + + return leftWeight >= rightWeight; +} } // namespace Gfx diff --git a/src/graphics/engine/lightman.h b/src/graphics/engine/lightman.h index 07dfe6a2..ab66524d 100644 --- a/src/graphics/engine/lightman.h +++ b/src/graphics/engine/lightman.h @@ -71,8 +71,8 @@ struct LightProgression */ enum LightPriority { - LIGHT_PRI_HIGH, - LIGHT_PRI_LOW + LIGHT_PRI_HIGH = 1, + LIGHT_PRI_LOW = 2 }; /** @@ -188,6 +188,21 @@ public: //! Enables or disables dynamic lights affecting the given object type void UpdateDeviceLights(EngineObjectType type); +protected: + class LightsComparator + { + public: + LightsComparator(Math::Vector eyePos, EngineObjectType objectType); + + bool operator()(const DynamicLight& left, const DynamicLight& right); + + private: + float GetLightWeight(const DynamicLight& dynLight); + + Math::Vector m_eyePos; + EngineObjectType m_objectType; + }; + protected: CEngine* m_engine; CDevice* m_device; @@ -196,7 +211,7 @@ protected: float m_time; //! List of dynamic lights std::vector m_dynLights; - //! Map of current light allotment: graphics light -> dynamic light + //! Map of current light allocation: graphics light -> dynamic light std::vector m_lightMap; }; diff --git a/test/unit/CMakeLists.txt b/test/unit/CMakeLists.txt index f6a1d758..21d19862 100644 --- a/test/unit/CMakeLists.txt +++ b/test/unit/CMakeLists.txt @@ -1,21 +1,174 @@ set(SRC_DIR ${colobot_SOURCE_DIR}/src) -include_directories( -${SRC_DIR} -${GTEST_INCLUDE_DIR} -math -common +# Additional libraries per platform +if (${MXE}) # MXE requires special treatment + set(PLATFORM_LIBS ${MXE_LIBS}) +elseif (${PLATFORM_WINDOWS}) + # because it isn't included in standard linking libraries + set(PLATFORM_LIBS "-lintl") +elseif(${PLATFORM_LINUX}) + # for clock_gettime + set(PLATFORM_LIBS "-lrt") +endif() + + +# Configure file +configure_file(${SRC_DIR}/common/config.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/common/config.h) + +# Code sources +set(COLOBOT_SOURCES +${SRC_DIR}/app/app.cpp +${SRC_DIR}/app/system.cpp +${SRC_DIR}/common/event.cpp +${SRC_DIR}/common/image.cpp +${SRC_DIR}/common/iman.cpp +${SRC_DIR}/common/logger.cpp +${SRC_DIR}/common/misc.cpp +${SRC_DIR}/common/profile.cpp +${SRC_DIR}/common/restext.cpp +${SRC_DIR}/common/stringutils.cpp +${SRC_DIR}/graphics/core/color.cpp +${SRC_DIR}/graphics/engine/camera.cpp +${SRC_DIR}/graphics/engine/cloud.cpp +${SRC_DIR}/graphics/engine/engine.cpp +${SRC_DIR}/graphics/engine/lightman.cpp +${SRC_DIR}/graphics/engine/lightning.cpp +${SRC_DIR}/graphics/engine/modelfile.cpp +${SRC_DIR}/graphics/engine/modelmanager.cpp +${SRC_DIR}/graphics/engine/particle.cpp +${SRC_DIR}/graphics/engine/planet.cpp +${SRC_DIR}/graphics/engine/pyro.cpp +${SRC_DIR}/graphics/engine/terrain.cpp +${SRC_DIR}/graphics/engine/text.cpp +${SRC_DIR}/graphics/engine/water.cpp +${SRC_DIR}/graphics/opengl/gldevice.cpp +${SRC_DIR}/object/auto/auto.cpp +${SRC_DIR}/object/auto/autobase.cpp +${SRC_DIR}/object/auto/autoconvert.cpp +${SRC_DIR}/object/auto/autoderrick.cpp +${SRC_DIR}/object/auto/autodestroyer.cpp +${SRC_DIR}/object/auto/autoegg.cpp +${SRC_DIR}/object/auto/autoenergy.cpp +${SRC_DIR}/object/auto/autofactory.cpp +${SRC_DIR}/object/auto/autoflag.cpp +${SRC_DIR}/object/auto/autohuston.cpp +${SRC_DIR}/object/auto/autoinfo.cpp +${SRC_DIR}/object/auto/autojostle.cpp +${SRC_DIR}/object/auto/autokid.cpp +${SRC_DIR}/object/auto/autolabo.cpp +${SRC_DIR}/object/auto/automush.cpp +${SRC_DIR}/object/auto/autonest.cpp +${SRC_DIR}/object/auto/autonuclear.cpp +${SRC_DIR}/object/auto/autopara.cpp +${SRC_DIR}/object/auto/autoportico.cpp +${SRC_DIR}/object/auto/autoradar.cpp +${SRC_DIR}/object/auto/autorepair.cpp +${SRC_DIR}/object/auto/autoresearch.cpp +${SRC_DIR}/object/auto/autoroot.cpp +${SRC_DIR}/object/auto/autosafe.cpp +${SRC_DIR}/object/auto/autostation.cpp +${SRC_DIR}/object/auto/autotower.cpp +${SRC_DIR}/object/brain.cpp +${SRC_DIR}/object/mainmovie.cpp +${SRC_DIR}/object/motion/motion.cpp +${SRC_DIR}/object/motion/motionant.cpp +${SRC_DIR}/object/motion/motionbee.cpp +${SRC_DIR}/object/motion/motionhuman.cpp +${SRC_DIR}/object/motion/motionmother.cpp +${SRC_DIR}/object/motion/motionspider.cpp +${SRC_DIR}/object/motion/motiontoto.cpp +${SRC_DIR}/object/motion/motionvehicle.cpp +${SRC_DIR}/object/motion/motionworm.cpp +${SRC_DIR}/object/object.cpp +${SRC_DIR}/object/robotmain.cpp +${SRC_DIR}/object/task/task.cpp +${SRC_DIR}/object/task/taskadvance.cpp +${SRC_DIR}/object/task/taskbuild.cpp +${SRC_DIR}/object/task/taskfire.cpp +${SRC_DIR}/object/task/taskfireant.cpp +${SRC_DIR}/object/task/taskflag.cpp +${SRC_DIR}/object/task/taskgoto.cpp +${SRC_DIR}/object/task/taskgungoal.cpp +${SRC_DIR}/object/task/taskinfo.cpp +${SRC_DIR}/object/task/taskmanager.cpp +${SRC_DIR}/object/task/taskmanip.cpp +${SRC_DIR}/object/task/taskpen.cpp +${SRC_DIR}/object/task/taskrecover.cpp +${SRC_DIR}/object/task/taskreset.cpp +${SRC_DIR}/object/task/tasksearch.cpp +${SRC_DIR}/object/task/taskshield.cpp +${SRC_DIR}/object/task/taskspiderexplo.cpp +${SRC_DIR}/object/task/tasktake.cpp +${SRC_DIR}/object/task/taskterraform.cpp +${SRC_DIR}/object/task/taskturn.cpp +${SRC_DIR}/object/task/taskwait.cpp +${SRC_DIR}/physics/physics.cpp +${SRC_DIR}/script/cbottoken.cpp +${SRC_DIR}/script/cmdtoken.cpp +${SRC_DIR}/script/script.cpp +${SRC_DIR}/ui/button.cpp +${SRC_DIR}/ui/check.cpp +${SRC_DIR}/ui/color.cpp +${SRC_DIR}/ui/compass.cpp +${SRC_DIR}/ui/control.cpp +${SRC_DIR}/ui/displayinfo.cpp +${SRC_DIR}/ui/displaytext.cpp +${SRC_DIR}/ui/edit.cpp +${SRC_DIR}/ui/editvalue.cpp +${SRC_DIR}/ui/gauge.cpp +${SRC_DIR}/ui/group.cpp +${SRC_DIR}/ui/image.cpp +${SRC_DIR}/ui/interface.cpp +${SRC_DIR}/ui/key.cpp +${SRC_DIR}/ui/label.cpp +${SRC_DIR}/ui/list.cpp +${SRC_DIR}/ui/maindialog.cpp +${SRC_DIR}/ui/mainmap.cpp +${SRC_DIR}/ui/mainshort.cpp +${SRC_DIR}/ui/map.cpp +${SRC_DIR}/ui/scroll.cpp +${SRC_DIR}/ui/shortcut.cpp +${SRC_DIR}/ui/slider.cpp +${SRC_DIR}/ui/studio.cpp +${SRC_DIR}/ui/target.cpp +${SRC_DIR}/ui/window.cpp ) set(UT_SOURCES main.cpp +graphics/engine/lightman_test.cpp math/geometry_test.cpp math/matrix_test.cpp math/vector_test.cpp ) -add_executable(colobot_ut ${UT_SOURCES}) -target_link_libraries(colobot_ut gtest) +include_directories( +${CMAKE_CURRENT_BINARY_DIR} +${SRC_DIR} +${GTEST_INCLUDE_DIR} +${GMOCK_INCLUDE_DIR} +. +common +math +) + +set(LIBS +gtest +gmock +CBot +${SDL_LIBRARY} +${SDLIMAGE_LIBRARY} +${SDLTTF_LIBRARY} +${OPENGL_LIBRARY} +${PNG_LIBRARIES} +${GLEW_LIBRARY} +${Boost_LIBRARIES} +${OPTIONAL_LIBS} +${PLATFORM_LIBS} +) + +add_executable(colobot_ut ${COLOBOT_SOURCES} ${UT_SOURCES}) +target_link_libraries(colobot_ut ${LIBS}) add_test(colobot_ut ./colobot_ut) diff --git a/test/unit/graphics/core/device_mock.h b/test/unit/graphics/core/device_mock.h new file mode 100644 index 00000000..80e214fe --- /dev/null +++ b/test/unit/graphics/core/device_mock.h @@ -0,0 +1,107 @@ +#pragma once + +#include "graphics/core/device.h" + +#include + +class CDeviceMock : public Gfx::CDevice +{ +public: + CDeviceMock() {} + + MOCK_METHOD0(DebugHook, void()); + + MOCK_METHOD0(Create, bool()); + MOCK_METHOD0(Destroy, void()); + + MOCK_METHOD0(BeginScene, void()); + MOCK_METHOD0(EndScene, void()); + + MOCK_METHOD0(Clear, void()); + + MOCK_METHOD2(SetTransform, void(Gfx::TransformType type, const Math::Matrix &matrix)); + MOCK_METHOD1(GetTransform, const Math::Matrix& (Gfx::TransformType type)); + MOCK_METHOD2(MultiplyTransform, void(Gfx::TransformType type, const Math::Matrix &matrix)); + + MOCK_METHOD1(SetMaterial, void(const Gfx::Material &material)); + MOCK_METHOD0(GetMaterial, const Gfx::Material&()); + + MOCK_METHOD0(GetMaxLightCount, int()); + + MOCK_METHOD2(SetLight, void(int index, const Gfx::Light &light)); + MOCK_METHOD1(GetLight, const Gfx::Light&(int index)); + + MOCK_METHOD2(SetLightEnabled, void(int index, bool enabled)); + MOCK_METHOD1(GetLightEnabled, bool(int index)); + + MOCK_METHOD2(CreateTexture, Gfx::Texture(CImage *image, const Gfx::TextureCreateParams ¶ms)); + MOCK_METHOD2(CreateTexture, Gfx::Texture(ImageData *data, const Gfx::TextureCreateParams ¶ms)); + + MOCK_METHOD1(DestroyTexture, void(const Gfx::Texture &texture)); + MOCK_METHOD0(DestroyAllTextures, void()); + + MOCK_METHOD0(GetMaxTextureStageCount, int()); + + MOCK_METHOD2(SetTexture, void(int index, const Gfx::Texture &texture)); + MOCK_METHOD2(SetTexture, void(int index, unsigned int textureId)); + MOCK_METHOD1(GetTexture, Gfx::Texture(int index)); + + MOCK_METHOD2(SetTextureEnabled, void(int index, bool enabled)); + MOCK_METHOD1(GetTextureEnabled, bool(int index)); + + MOCK_METHOD2(SetTextureStageParams, void(int index, const Gfx::TextureStageParams ¶ms)); + MOCK_METHOD1(GetTextureStageParams, Gfx::TextureStageParams(int index)); + + MOCK_METHOD3(SetTextureStageWrap, void(int index, Gfx::TexWrapMode wrapS, Gfx::TexWrapMode wrapT)); + + MOCK_METHOD4(DrawPrimitive, void(Gfx::PrimitiveType type, const Gfx::Vertex *vertices, int vertexCount, Gfx::Color color)); + MOCK_METHOD4(DrawPrimitive, void(Gfx::PrimitiveType type, const Gfx::VertexTex2 *vertices, int vertexCount, Gfx::Color color)); + MOCK_METHOD3(DrawPrimitive, void(Gfx::PrimitiveType type, const Gfx::VertexCol *vertices, int vertexCount)); + + MOCK_METHOD3(CreateStaticBuffer, unsigned int(Gfx::PrimitiveType primitiveType, const Gfx::Vertex* vertices, int vertexCount)); + MOCK_METHOD3(CreateStaticBuffer, unsigned int(Gfx::PrimitiveType primitiveType, const Gfx::VertexTex2* vertices, int vertexCount)); + MOCK_METHOD3(CreateStaticBuffer, unsigned int(Gfx::PrimitiveType primitiveType, const Gfx::VertexCol* vertices, int vertexCount)); + + MOCK_METHOD4(UpdateStaticBuffer, void(unsigned int bufferId, Gfx::PrimitiveType primitiveType, const Gfx::Vertex* vertices, int vertexCount)); + MOCK_METHOD4(UpdateStaticBuffer, void(unsigned int bufferId, Gfx::PrimitiveType primitiveType, const Gfx::VertexTex2* vertices, int vertexCount)); + MOCK_METHOD4(UpdateStaticBuffer, void(unsigned int bufferId, Gfx::PrimitiveType primitiveType, const Gfx::VertexCol* vertices, int vertexCount)); + + MOCK_METHOD1(DrawStaticBuffer, void(unsigned int bufferId)); + + MOCK_METHOD1(DestroyStaticBuffer, void(unsigned int bufferId)); + + MOCK_METHOD2(ComputeSphereVisibility, int(const Math::Vector ¢er, float radius)); + + MOCK_METHOD2(SetRenderState, void(Gfx::RenderState state, bool enabled)); + MOCK_METHOD1(GetRenderState, bool(Gfx::RenderState state)); + + MOCK_METHOD1(SetDepthTestFunc, void(Gfx::CompFunc func)); + MOCK_METHOD0(GetDepthTestFunc, Gfx::CompFunc()); + + MOCK_METHOD1(SetDepthBias, void(float factor)); + MOCK_METHOD0(GetDepthBias, float()); + + MOCK_METHOD2(SetAlphaTestFunc, void(Gfx::CompFunc func, float refValue)); + MOCK_METHOD2(GetAlphaTestFunc, void(Gfx::CompFunc &func, float &refValue)); + + MOCK_METHOD2(SetBlendFunc, void(Gfx::BlendFunc srcBlend, Gfx::BlendFunc dstBlend)); + MOCK_METHOD2(GetBlendFunc, void(Gfx::BlendFunc &srcBlend, Gfx::BlendFunc &dstBlend)); + + MOCK_METHOD1(SetClearColor, void(const Gfx::Color &color)); + MOCK_METHOD0(GetClearColor, Gfx::Color()); + + MOCK_METHOD1(SetGlobalAmbient, void(const Gfx::Color &color)); + MOCK_METHOD0(GetGlobalAmbient, Gfx::Color()); + + MOCK_METHOD5(SetFogParams, void(Gfx::FogMode mode, const Gfx::Color &color, float start, float end, float density)); + MOCK_METHOD5(GetFogParams, void(Gfx::FogMode &mode, Gfx::Color &color, float &start, float &end, float &density)); + + MOCK_METHOD1(SetCullMode, void(Gfx::CullMode mode)); + MOCK_METHOD0(GetCullMode, Gfx::CullMode()); + + MOCK_METHOD1(SetShadeModel, void(Gfx::ShadeModel model)); + MOCK_METHOD0(GetShadeModel, Gfx::ShadeModel()); + + MOCK_METHOD1(SetFillMode, void(Gfx::FillMode mode)); + MOCK_METHOD0(GetFillMode, Gfx::FillMode()); +}; diff --git a/test/unit/graphics/engine/engine_mock.h b/test/unit/graphics/engine/engine_mock.h new file mode 100644 index 00000000..1a15eca5 --- /dev/null +++ b/test/unit/graphics/engine/engine_mock.h @@ -0,0 +1,14 @@ +#include "graphics/engine/engine.h" + +#include + +class CEngineMock : public Gfx::CEngine +{ +public: + CEngineMock() : Gfx::CEngine(nullptr) {} + + MOCK_METHOD0(GetPause, bool()); + + MOCK_METHOD0(GetEyePt, Math::Vector()); + MOCK_METHOD0(GetLookatPt, Math::Vector()); +}; diff --git a/test/unit/graphics/engine/lightman_test.cpp b/test/unit/graphics/engine/lightman_test.cpp new file mode 100644 index 00000000..529cee81 --- /dev/null +++ b/test/unit/graphics/engine/lightman_test.cpp @@ -0,0 +1,145 @@ +#include "graphics/engine/lightman.h" + +#include "graphics/core/device_mock.h" +#include "graphics/engine/engine_mock.h" + +#include + +using namespace Gfx; + +using testing::_; +using testing::Invoke; +using testing::Return; + +class LightManagerUT : public testing::Test +{ +protected: + LightManagerUT() + : lightManager(&engine) + {} + + void PrepareLightTesting(int maxLights, Math::Vector eyePos); + void CheckLightSorting(EngineObjectType objectType, const std::vector& expectedLights); + void CheckLight(int index, const Light& light); + void AddLight(int type, LightPriority priority, bool used, bool enabled, + Math::Vector pos, EngineObjectType includeType, EngineObjectType excludeType); + + + CLightManager lightManager; + CEngineMock engine; + CDeviceMock device; + +private: + std::vector dynamicLights; + std::vector expectedLightTypes; + int maxLightsCount; +}; + +void LightManagerUT::PrepareLightTesting(int maxLights, Math::Vector eyePos) +{ + maxLightsCount = maxLights; + + EXPECT_CALL(device, GetMaxLightCount()).WillOnce(Return(maxLights)); + lightManager.SetDevice(&device); + + ON_CALL(device, SetLight(_, _)).WillByDefault(Invoke(this, &LightManagerUT::CheckLight)); + + EXPECT_CALL(engine, GetEyePt()).WillRepeatedly(Return(eyePos)); +} + +void LightManagerUT::CheckLightSorting(EngineObjectType objectType, const std::vector& expectedLights) +{ + expectedLightTypes = expectedLights; + + EXPECT_CALL(device, SetLight(_, _)).Times(expectedLights.size()); + + for (int i = 0; i < static_cast( expectedLights.size() ); ++i) + EXPECT_CALL(device, SetLightEnabled(i, true)); + + for (int i = expectedLights.size(); i < maxLightsCount; ++i) + EXPECT_CALL(device, SetLightEnabled(i, false)); + + lightManager.UpdateDeviceLights(objectType); +} + +void LightManagerUT::CheckLight(int index, const Light& light) +{ + ASSERT_TRUE(index >= 0 && index < static_cast( expectedLightTypes.size() )); + ASSERT_EQ(expectedLightTypes[index], light.type); +} + +void LightManagerUT::AddLight(int type, LightPriority priority, bool used, bool enabled, + Math::Vector pos, EngineObjectType includeType, EngineObjectType excludeType) +{ + int rank = lightManager.CreateLight(priority); + + Light light; + light.type = static_cast(type); + lightManager.SetLight(rank, light); + + lightManager.SetLightEnabled(rank, enabled); + lightManager.SetLightIncludeType(rank, includeType); + lightManager.SetLightExcludeType(rank, excludeType); + + if (!used) + lightManager.DeleteLight(rank); +} + +TEST_F(LightManagerUT, LightSorting_UnusedOrDisabledAreSkipped) +{ + const int lightCount = 10; + const Math::Vector eyePos(0.0f, 0.0f, 0.0f); + PrepareLightTesting(lightCount, eyePos); + + AddLight(1, LIGHT_PRI_LOW, false, true, Math::Vector(0.0f, 0.0f, 0.0f), ENG_OBJTYPE_NULL, ENG_OBJTYPE_NULL); + AddLight(2, LIGHT_PRI_LOW, true, false, Math::Vector(0.0f, 0.0f, 0.0f), ENG_OBJTYPE_NULL, ENG_OBJTYPE_NULL); + AddLight(3, LIGHT_PRI_LOW, false, false, Math::Vector(0.0f, 0.0f, 0.0f), ENG_OBJTYPE_NULL, ENG_OBJTYPE_NULL); + + std::vector expectedLights; + CheckLightSorting(ENG_OBJTYPE_TERRAIN, expectedLights); +} + +TEST_F(LightManagerUT, LightSorting_IncludeTypesAreIncluded) +{ + const int lightCount = 10; + const Math::Vector eyePos(0.0f, 0.0f, 0.0f); + PrepareLightTesting(lightCount, eyePos); + + AddLight(1, LIGHT_PRI_LOW, true, true, Math::Vector(0.0f, 0.0f, 0.0f), ENG_OBJTYPE_NULL, ENG_OBJTYPE_NULL); + AddLight(2, LIGHT_PRI_LOW, true, true, Math::Vector(0.0f, 0.0f, 0.0f), ENG_OBJTYPE_TERRAIN, ENG_OBJTYPE_NULL); + AddLight(3, LIGHT_PRI_LOW, true, true, Math::Vector(0.0f, 0.0f, 0.0f), ENG_OBJTYPE_QUARTZ, ENG_OBJTYPE_NULL); + + std::vector expectedLights = { 1, 2 }; + CheckLightSorting(ENG_OBJTYPE_TERRAIN, expectedLights); +} + +TEST_F(LightManagerUT, LightSorting_ExcludeTypesAreExcluded) +{ + const int lightCount = 10; + const Math::Vector eyePos(0.0f, 0.0f, 0.0f); + PrepareLightTesting(lightCount, eyePos); + + AddLight(1, LIGHT_PRI_LOW, true, true, Math::Vector(0.0f, 0.0f, 0.0f), ENG_OBJTYPE_NULL, ENG_OBJTYPE_NULL); + AddLight(2, LIGHT_PRI_LOW, true, true, Math::Vector(0.0f, 0.0f, 0.0f), ENG_OBJTYPE_NULL, ENG_OBJTYPE_TERRAIN); + AddLight(3, LIGHT_PRI_LOW, true, true, Math::Vector(0.0f, 0.0f, 0.0f), ENG_OBJTYPE_NULL, ENG_OBJTYPE_QUARTZ); + + std::vector expectedLights = { 1, 3 }; + CheckLightSorting(ENG_OBJTYPE_TERRAIN, expectedLights); +} + +TEST_F(LightManagerUT, LightSorting_SortingAccordingToDistance) +{ + const int lightCount = 3; + const Math::Vector eyePos(0.0f, 0.0f, 0.0f); + PrepareLightTesting(lightCount, eyePos); + + AddLight(1, LIGHT_PRI_HIGH, true, true, Math::Vector(10.0f, 0.0f, 0.0f), ENG_OBJTYPE_NULL, ENG_OBJTYPE_NULL); + AddLight(2, LIGHT_PRI_LOW, true, true, Math::Vector(4.0f, 0.0f, 0.0f), ENG_OBJTYPE_NULL, ENG_OBJTYPE_NULL); + AddLight(3, LIGHT_PRI_HIGH, true, true, Math::Vector(20.0f, 0.0f, 0.0f), ENG_OBJTYPE_NULL, ENG_OBJTYPE_NULL); + AddLight(4, LIGHT_PRI_LOW, true, true, Math::Vector(11.0f, 0.0f, 0.0f), ENG_OBJTYPE_NULL, ENG_OBJTYPE_NULL); + AddLight(5, LIGHT_PRI_LOW, true, true, Math::Vector(100.0f, 0.0f, 0.0f), ENG_OBJTYPE_NULL, ENG_OBJTYPE_NULL); + AddLight(6, LIGHT_PRI_HIGH, true, true, Math::Vector(21.0f, 0.0f, 0.0f), ENG_OBJTYPE_NULL, ENG_OBJTYPE_NULL); + + std::vector expectedLights = { 1, 2, 3 }; + CheckLightSorting(ENG_OBJTYPE_TERRAIN, expectedLights); +} diff --git a/test/unit/ui/stubs/engine_stub.cpp b/test/unit/ui/stubs/engine_stub.cpp index 40886da1..0a2777cf 100644 --- a/test/unit/ui/stubs/engine_stub.cpp +++ b/test/unit/ui/stubs/engine_stub.cpp @@ -77,11 +77,28 @@ int CEngine::GetEditIndentValue() void CEngine::DeleteTexture(const std::string& /* texName */) { } + Texture CEngine::LoadTexture(const std::string& /* name */) { Texture texture; return texture; } +Math::Vector CEngine::GetEyePt() +{ + return Math::Vector(); +} + +Math::Vector CEngine::GetLookatPt() +{ + return Math::Vector(); +} + +bool CEngine::GetPause() +{ + return false; +} + + } /* Gfx */