Skip to content

Commit

Permalink
Added light component Serialise and Deserialise functions and unit te…
Browse files Browse the repository at this point in the history
…sts. #70
  • Loading branch information
MStachowicz committed Apr 1, 2024
1 parent e56a80b commit 95c6941
Show file tree
Hide file tree
Showing 6 changed files with 259 additions and 12 deletions.
2 changes: 2 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ source/Test/MemoryCorrectnessItem.hpp
source/Test/MemoryCorrectnessItem.cpp
source/Test/TestManager.hpp
source/Test/TestManager.cpp
source/Test/Tests/ComponentSerialiseTester.hpp
source/Test/Tests/ComponentSerialiseTester.cpp
source/Test/Tests/ECSTester.hpp
source/Test/Tests/ECSTester.cpp
source/Test/Tests/ResourceManagerTester.hpp
Expand Down
84 changes: 83 additions & 1 deletion source/Component/Lights.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include "Lights.hpp"
#include "Component/Transform.hpp"
#include "Geometry/AABB.hpp"
#include "Utility/Serialise.hpp"

#include "glm/trigonometric.hpp"
#include "imgui.h"
Expand Down Expand Up @@ -51,6 +52,32 @@ namespace Component
}
}

void DirectionalLight::Serialise(const DirectionalLight& p_light, std::ofstream& p_out, uint16_t p_version)
{ (void)p_version;
Utility::write_binary(p_out, p_light.m_direction);
Utility::write_binary(p_out, p_light.m_colour);
Utility::write_binary(p_out, p_light.m_ambient_intensity);
Utility::write_binary(p_out, p_light.m_diffuse_intensity);
Utility::write_binary(p_out, p_light.m_specular_intensity);
Utility::write_binary(p_out, p_light.m_shadow_near_plane);
Utility::write_binary(p_out, p_light.m_shadow_far_plane);
Utility::write_binary(p_out, p_light.m_ortho_size);
}

DirectionalLight DirectionalLight::Deserialise(std::ifstream& p_in, uint16_t p_version)
{ (void)p_version;
DirectionalLight light;
Utility::read_binary(p_in, light.m_direction);
Utility::read_binary(p_in, light.m_colour);
Utility::read_binary(p_in, light.m_ambient_intensity);
Utility::read_binary(p_in, light.m_diffuse_intensity);
Utility::read_binary(p_in, light.m_specular_intensity);
Utility::read_binary(p_in, light.m_shadow_near_plane);
Utility::read_binary(p_in, light.m_shadow_far_plane);
Utility::read_binary(p_in, light.m_ortho_size);
return light;
}

glm::mat4 DirectionalLight::get_view_proj(const Geometry::AABB& p_scene_AABB)
{
// DirectionalLight has no position, instead consider at the extents of the scene in the opposite direction its casting.
Expand Down Expand Up @@ -99,6 +126,31 @@ namespace Component
}
}

void PointLight::Serialise(const PointLight& p_light, std::ofstream& p_out, uint16_t p_version)
{ (void)p_version;
Utility::write_binary(p_out, p_light.m_position);
Utility::write_binary(p_out, p_light.m_colour);
Utility::write_binary(p_out, p_light.m_ambient_intensity);
Utility::write_binary(p_out, p_light.m_diffuse_intensity);
Utility::write_binary(p_out, p_light.m_specular_intensity);
Utility::write_binary(p_out, p_light.m_constant);
Utility::write_binary(p_out, p_light.m_linear);
Utility::write_binary(p_out, p_light.m_quadratic);
}
PointLight PointLight::Deserialise(std::ifstream& p_in, uint16_t p_version)
{ (void)p_version;
PointLight light;
Utility::read_binary(p_in, light.m_position);
Utility::read_binary(p_in, light.m_colour);
Utility::read_binary(p_in, light.m_ambient_intensity);
Utility::read_binary(p_in, light.m_diffuse_intensity);
Utility::read_binary(p_in, light.m_specular_intensity);
Utility::read_binary(p_in, light.m_constant);
Utility::read_binary(p_in, light.m_linear);
Utility::read_binary(p_in, light.m_quadratic);
return light;
}

SpotLight::SpotLight() noexcept
: m_position{glm::vec3(0.f, 0.f, 0.f)}
, m_direction{glm::vec3(0.f, 0.f, -1.f)}
Expand Down Expand Up @@ -131,4 +183,34 @@ namespace Component
ImGui::TreePop();
}
}
}
void SpotLight::Serialise(const SpotLight& p_light, std::ofstream& p_out, uint16_t p_version)
{ (void)p_version;
Utility::write_binary(p_out, p_light.m_position);
Utility::write_binary(p_out, p_light.m_direction);
Utility::write_binary(p_out, p_light.m_colour);
Utility::write_binary(p_out, p_light.m_ambient_intensity);
Utility::write_binary(p_out, p_light.m_diffuse_intensity);
Utility::write_binary(p_out, p_light.m_specular_intensity);
Utility::write_binary(p_out, p_light.m_constant);
Utility::write_binary(p_out, p_light.m_linear);
Utility::write_binary(p_out, p_light.m_quadratic);
Utility::write_binary(p_out, p_light.m_cutoff);
Utility::write_binary(p_out, p_light.m_outer_cutoff);
}
SpotLight SpotLight::Deserialise(std::ifstream& p_in, uint16_t p_version)
{ (void)p_version;
SpotLight light;
Utility::read_binary(p_in, light.m_position);
Utility::read_binary(p_in, light.m_direction);
Utility::read_binary(p_in, light.m_colour);
Utility::read_binary(p_in, light.m_ambient_intensity);
Utility::read_binary(p_in, light.m_diffuse_intensity);
Utility::read_binary(p_in, light.m_specular_intensity);
Utility::read_binary(p_in, light.m_constant);
Utility::read_binary(p_in, light.m_linear);
Utility::read_binary(p_in, light.m_quadratic);
Utility::read_binary(p_in, light.m_cutoff);
Utility::read_binary(p_in, light.m_outer_cutoff);
return light;
}
} // namespace Component
8 changes: 8 additions & 0 deletions source/Component/Lights.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
#include "glm/vec3.hpp"
#include "glm/mat4x4.hpp"

#include <fstream>

namespace Geometry
{
class AABB;
Expand Down Expand Up @@ -32,6 +34,8 @@ namespace Component
glm::mat4 get_view_proj(const Geometry::AABB& scene_AABB);

void draw_UI();
static void Serialise(const DirectionalLight& p_light, std::ofstream& p_out, uint16_t p_version);
static DirectionalLight Deserialise(std::ifstream& p_in, uint16_t p_version);
};

class PointLight
Expand All @@ -54,6 +58,8 @@ namespace Component
float m_quadratic;

void draw_UI();
static void Serialise(const PointLight& p_light, std::ofstream& p_out, uint16_t p_version);
static PointLight Deserialise(std::ifstream& p_in, uint16_t p_version);
};

class SpotLight
Expand All @@ -78,5 +84,7 @@ namespace Component
float m_outer_cutoff;

void draw_UI();
static void Serialise(const SpotLight& p_light, std::ofstream& p_out, uint16_t p_version);
static SpotLight Deserialise(std::ifstream& p_in, uint16_t p_version);
};
}
24 changes: 13 additions & 11 deletions source/Test/TestMain.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include "Test/TestManager.hpp"
#include "Test/Tests/ComponentSerialiseTester.hpp"
#include "Test/Tests/ECSTester.hpp"
#include "Test/Tests/GeometryTester.hpp"
#include "Test/Tests/ResourceManagerTester.hpp"
Expand All @@ -25,6 +26,7 @@ int main(int argc, char* argv[])
const char* seperator = "--------------------------------------------------\n";

std::vector<std::unique_ptr<Test::TestManager>> test_managers;
test_managers.emplace_back(std::make_unique<Test::ComponentSerialiseTester>());
test_managers.emplace_back(std::make_unique<Test::ECSTester>());
test_managers.emplace_back(std::make_unique<Test::GeometryTester>());
test_managers.emplace_back(std::make_unique<Test::ResourceManagerTester>());
Expand All @@ -40,23 +42,23 @@ int main(int argc, char* argv[])
Utility::Stopwatch tester_stopwatch;
tester->run_unit_tests();
printf("***************** %s SUMMARY *****************\nTOTAL TESTS: %zu\nPASSED: %zu\nFAILED: %zu\nTIME TAKEN: %fms\n%s\n\n",
tester->m_name.c_str(),
tester->m_unit_tests_pass_count + tester->m_unit_tests_fail_count,
tester->m_unit_tests_pass_count,
tester->m_unit_tests_fail_count,
tester_stopwatch.duration_since_start<float, std::milli>().count(),
seperator);
tester->m_name.c_str(),
tester->m_unit_tests_pass_count + tester->m_unit_tests_fail_count,
tester->m_unit_tests_pass_count,
tester->m_unit_tests_fail_count,
tester_stopwatch.duration_since_start<float, std::milli>().count(),
seperator);

unit_test_overall_pass_count += tester->m_unit_tests_pass_count;
unit_test_overall_fail_count += tester->m_unit_tests_fail_count;
unit_tests_failed_messages += tester->m_unit_tests_failed_messages;
}
printf("\n\n***************** OVERALL SUMMARY *****************\nTOTAL TESTS: %zu\nPASSED: %zu\nFAILED: %zu\nTIME TAKEN: %fms\n%s",
unit_test_overall_pass_count + unit_test_overall_fail_count,
unit_test_overall_pass_count,
unit_test_overall_fail_count,
all_unit_tests_stopwatch.duration_since_start<float, std::milli>().count(),
seperator);
unit_test_overall_pass_count + unit_test_overall_fail_count,
unit_test_overall_pass_count,
unit_test_overall_fail_count,
all_unit_tests_stopwatch.duration_since_start<float, std::milli>().count(),
seperator);

if (unit_test_overall_fail_count > 0)
printf("***************** FAILED TESTS *****************\n%s", unit_tests_failed_messages.c_str());
Expand Down
132 changes: 132 additions & 0 deletions source/Test/Tests/ComponentSerialiseTester.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
#include "ComponentSerialiseTester.hpp"

#include "Component/Lights.hpp"
#include "Utility/Logger.hpp"

#include <fstream>

namespace Test
{
// Helper function to serialise and deserialise a component into a file.
//@param p_to_serialise The component to serialise.
//@param p_deserialised The component to deserialise into.
//@return True if the serialisation and deserialisation was successful, false otherwise.
template<typename ComponentType>
bool ComponentSerialiseTester::test_serialisation(const ComponentType& p_to_serialise, ComponentType& p_deserialised)
{
try
{
std::ofstream out("test.bin", std::ios::binary);
out.exceptions(std::ofstream::failbit | std::ofstream::badbit);
ComponentType::Serialise(p_to_serialise, out, 0);
out.close();

std::ifstream in("test.bin", std::ios::binary);
in.exceptions(std::ifstream::failbit | std::ifstream::badbit);
p_deserialised = ComponentType::Deserialise(in, 0);
in.close();
}
catch (std::ofstream::failure& e)
{
CHECK_TRUE(false, e.what());
std::remove("test.bin");
return false;
}

std::remove("test.bin");
return true;
}

void ComponentSerialiseTester::run_unit_tests()
{
SCOPE_SECTION("Component serialise");

{SCOPE_SECTION("Directional light");

Component::DirectionalLight serialised_light;
serialised_light.m_direction = glm::vec3(0.8f, 0.2f, 0.1f);
serialised_light.m_colour = glm::vec3(0.7f, 0.4f, 1.0f);
serialised_light.m_ambient_intensity = 0.42f;
serialised_light.m_diffuse_intensity = 0.7f;
serialised_light.m_specular_intensity = 0.11f;
serialised_light.m_shadow_near_plane = 0.57f;
serialised_light.m_shadow_far_plane = 0.2f;
serialised_light.m_ortho_size = 0.7f;

Component::DirectionalLight deserialised_light;
if (test_serialisation(serialised_light, deserialised_light))
{
CHECK_EQUAL(serialised_light.m_direction, deserialised_light.m_direction, "Direction");
CHECK_EQUAL(serialised_light.m_colour, deserialised_light.m_colour, "Colour");
CHECK_EQUAL(serialised_light.m_ambient_intensity, deserialised_light.m_ambient_intensity, "Ambient intensity");
CHECK_EQUAL(serialised_light.m_diffuse_intensity, deserialised_light.m_diffuse_intensity, "Diffuse intensity");
CHECK_EQUAL(serialised_light.m_specular_intensity, deserialised_light.m_specular_intensity, "Specular intensity");
CHECK_EQUAL(serialised_light.m_shadow_near_plane, deserialised_light.m_shadow_near_plane, "Shadow near plane");
CHECK_EQUAL(serialised_light.m_shadow_far_plane, deserialised_light.m_shadow_far_plane, "Shadow far plane");
CHECK_EQUAL(serialised_light.m_ortho_size, deserialised_light.m_ortho_size, "Ortho size");
}
}

{SCOPE_SECTION("Point light");

Component::PointLight serialised_light;
serialised_light.m_position = glm::vec3(0.8f, 0.2f, 0.1f);
serialised_light.m_colour = glm::vec3(0.7f, 0.4f, 1.0f);
serialised_light.m_ambient_intensity = 0.42f;
serialised_light.m_diffuse_intensity = 0.7f;
serialised_light.m_specular_intensity = 0.11f;
serialised_light.m_constant = 0.57f;
serialised_light.m_linear = 0.2f;
serialised_light.m_quadratic = 0.7f;

Component::PointLight deserialised_light;
if (test_serialisation(serialised_light, deserialised_light))
{
CHECK_EQUAL(serialised_light.m_position, deserialised_light.m_position, "Position");
CHECK_EQUAL(serialised_light.m_colour, deserialised_light.m_colour, "Colour");
CHECK_EQUAL(serialised_light.m_ambient_intensity, deserialised_light.m_ambient_intensity, "Ambient intensity");
CHECK_EQUAL(serialised_light.m_diffuse_intensity, deserialised_light.m_diffuse_intensity, "Diffuse intensity");
CHECK_EQUAL(serialised_light.m_specular_intensity, deserialised_light.m_specular_intensity, "Specular intensity");
CHECK_EQUAL(serialised_light.m_constant, deserialised_light.m_constant, "Constant");
CHECK_EQUAL(serialised_light.m_linear, deserialised_light.m_linear, "Linear");
CHECK_EQUAL(serialised_light.m_quadratic, deserialised_light.m_quadratic, "Quadratic");
}
}

{SCOPE_SECTION("Spotlight");

Component::SpotLight serialised_light;
serialised_light.m_position = glm::vec3(0.8f, 0.2f, 0.1f);
serialised_light.m_direction = glm::vec3(0.7f, 0.4f, 1.0f);
serialised_light.m_colour = glm::vec3(0.7f, 0.4f, 1.0f);
serialised_light.m_ambient_intensity = 0.42f;
serialised_light.m_diffuse_intensity = 0.7f;
serialised_light.m_specular_intensity = 0.11f;
serialised_light.m_constant = 0.57f;
serialised_light.m_linear = 0.2f;
serialised_light.m_quadratic = 0.7f;
serialised_light.m_cutoff = 0.5f;
serialised_light.m_outer_cutoff = 0.7f;

Component::SpotLight deserialised_light;
if (test_serialisation(serialised_light, deserialised_light))
{
CHECK_EQUAL(serialised_light.m_position, deserialised_light.m_position, "Position");
CHECK_EQUAL(serialised_light.m_direction, deserialised_light.m_direction, "Direction");
CHECK_EQUAL(serialised_light.m_colour, deserialised_light.m_colour, "Colour");
CHECK_EQUAL(serialised_light.m_ambient_intensity, deserialised_light.m_ambient_intensity, "Ambient intensity");
CHECK_EQUAL(serialised_light.m_diffuse_intensity, deserialised_light.m_diffuse_intensity, "Diffuse intensity");
CHECK_EQUAL(serialised_light.m_specular_intensity, deserialised_light.m_specular_intensity, "Specular intensity");
CHECK_EQUAL(serialised_light.m_constant, deserialised_light.m_constant, "Constant");
CHECK_EQUAL(serialised_light.m_linear, deserialised_light.m_linear, "Linear");
CHECK_EQUAL(serialised_light.m_quadratic, deserialised_light.m_quadratic, "Quadratic");
CHECK_EQUAL(serialised_light.m_cutoff, deserialised_light.m_cutoff, "Cutoff");
CHECK_EQUAL(serialised_light.m_outer_cutoff, deserialised_light.m_outer_cutoff, "Outer cutoff");
}
}
}

void ComponentSerialiseTester::run_performance_tests()
{
}
} // namespace Test
21 changes: 21 additions & 0 deletions source/Test/Tests/ComponentSerialiseTester.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#pragma once

#include "TestManager.hpp"

namespace Test
{
class ComponentSerialiseTester : public TestManager
{
public:
ComponentSerialiseTester() : TestManager(std::string("Component serialisation")) {}

protected:
void run_unit_tests() override;
void run_performance_tests() override;

private:
// Used only inside ComponentSerialiseTester.cpp, no need to expose it to the public.
template<typename ComponentType>
bool test_serialisation(const ComponentType& p_to_serialise, ComponentType& p_deserialised);
};
} // namespace Test

0 comments on commit 95c6941

Please sign in to comment.