diff options
79 files changed, 211 insertions, 5 deletions
diff --git a/application/main.cpp b/application/main.cpp index 532c23d..0e880c0 100644 --- a/application/main.cpp +++ b/application/main.cpp @@ -34,6 +34,7 @@ static const int DISPLAY_HEIGHT = 1024; class MainApplication : public GameState, public ApplicationBase { public: using Windows = Collection<Window>; + int run() { diff --git a/assetFactory/assimp.cpp b/assetFactory/assimp.cpp index 9dc7842..bd5467b 100644 --- a/assetFactory/assimp.cpp +++ b/assetFactory/assimp.cpp @@ -30,6 +30,7 @@ operator!(const aiVector3t<T> & v) } using SceneCPtr = std::shared_ptr<const aiScene>; + class AssImpNode : public Shape { public: AssImpNode(SceneCPtr scene, const aiNode * node) : scene(std::move(scene)), node(node) { } diff --git a/assetFactory/faceController.h b/assetFactory/faceController.h index 0376241..fb89d25 100644 --- a/assetFactory/faceController.h +++ b/assetFactory/faceController.h @@ -18,12 +18,14 @@ public: private: friend Persistence::SelectionPtrBase<std::unique_ptr<Split>>; bool persist(Persistence::PersistenceStore & store) override; + std::string getId() const override { return {}; }; }; + using FaceControllers = std::map<std::string, std::unique_ptr<FaceController>>; using Splits = std::map<std::string, std::unique_ptr<Split>>; @@ -38,6 +40,7 @@ public: private: friend Persistence::SelectionPtrBase<std::unique_ptr<FaceController>>; bool persist(Persistence::PersistenceStore & store) override; + std::string getId() const override { diff --git a/assetFactory/mutation.cpp b/assetFactory/mutation.cpp index 9a6a988..c5c3f5b 100644 --- a/assetFactory/mutation.cpp +++ b/assetFactory/mutation.cpp @@ -27,6 +27,7 @@ Mutation::relativeLevelOfDetail() const { return std::max({scale.x, scale.y, scale.z}); } + bool Mutation::persist(Persistence::PersistenceStore & store) { diff --git a/assetFactory/object.h b/assetFactory/object.h index f47c512..77e1469 100644 --- a/assetFactory/object.h +++ b/assetFactory/object.h @@ -18,6 +18,7 @@ public: private: friend Persistence::SelectionPtrBase<std::shared_ptr<Object>>; bool persist(Persistence::PersistenceStore & store) override; + std::string getId() const override { diff --git a/assetFactory/style.cpp b/assetFactory/style.cpp index ea67fc2..81a5441 100644 --- a/assetFactory/style.cpp +++ b/assetFactory/style.cpp @@ -61,6 +61,7 @@ Style::persist(Persistence::PersistenceStore & store) struct ColourParser : public Persistence::SelectionV<ColourAlpha> { using Persistence::SelectionV<ColourAlpha>::SelectionV; using Persistence::SelectionV<ColourAlpha>::setValue; + void setValue(std::string && str) override { diff --git a/assetFactory/texturePacker.h b/assetFactory/texturePacker.h index a1b270b..93413eb 100644 --- a/assetFactory/texturePacker.h +++ b/assetFactory/texturePacker.h @@ -16,12 +16,14 @@ public: Position position; Size size; + bool operator<(const Area & other) const { return area(size) < area(other.size); } }; + using Image = Size; using Space = Area; using Positions = std::vector<Position>; diff --git a/assetFactory/use.cpp b/assetFactory/use.cpp index 5314321..0994c8c 100644 --- a/assetFactory/use.cpp +++ b/assetFactory/use.cpp @@ -35,6 +35,7 @@ Use::createMesh(ModelFactoryMesh & mesh, float levelOfDetailFactor) const struct Lookup : public Persistence::SelectionV<Shape::CPtr> { using Persistence::SelectionV<Shape::CPtr>::SelectionV; using Persistence::SelectionV<Shape::CPtr>::setValue; + void setValue(std::string && str) override { diff --git a/assetFactory/use.h b/assetFactory/use.h index a91685b..289bf6e 100644 --- a/assetFactory/use.h +++ b/assetFactory/use.h @@ -19,6 +19,7 @@ public: private: friend Persistence::SelectionPtrBase<std::shared_ptr<Use>>; bool persist(Persistence::PersistenceStore & store) override; + std::string getId() const override { diff --git a/game/activity.h b/game/activity.h index e0585f7..38f6524 100644 --- a/game/activity.h +++ b/game/activity.h @@ -16,10 +16,12 @@ public: template<typename T> class Of; }; + using ActivityPtr = std::unique_ptr<Activity>; template<typename T> concept ActivityConcept = std::is_base_of_v<Activity, T>; + template<ActivityConcept AC> class Can { public: Can() = default; diff --git a/game/gamestate.h b/game/gamestate.h index 6f3f382..f07f844 100644 --- a/game/gamestate.h +++ b/game/gamestate.h @@ -19,4 +19,5 @@ public: std::shared_ptr<GeoData> geoData; AssetFactory::Assets assets; }; + extern GameState * gameState; diff --git a/game/geoData.cpp b/game/geoData.cpp index 34a1030..76550cc 100644 --- a/game/geoData.cpp +++ b/game/geoData.cpp @@ -100,6 +100,7 @@ GeoData::positionAt(const glm::vec2 wcoord) const } GeoData::RayTracer::RayTracer(glm::vec2 p0, glm::vec2 p1) : RayTracer {p0, p1, glm::abs(p1)} { } + GeoData::RayTracer::RayTracer(glm::vec2 p0, glm::vec2 p1, glm::vec2 d) : RayTracer {p0, d, byAxis(p0, p1, d, 0), byAxis(p0, p1, d, 1)} { diff --git a/game/geoData.h b/game/geoData.h index f433a5c..f9a7d7b 100644 --- a/game/geoData.h +++ b/game/geoData.h @@ -15,6 +15,7 @@ public: struct Node { float height {-1.5F}; }; + using Quad = std::array<glm::vec3, 4>; using Limits = std::pair<glm::ivec2, glm::ivec2>; diff --git a/game/network/link.h b/game/network/link.h index 4a9f83f..0d66c42 100644 --- a/game/network/link.h +++ b/game/network/link.h @@ -71,6 +71,7 @@ public: [[nodiscard]] Location positionAt(float dist, unsigned char start) const override; [[nodiscard]] bool intersectRay(const Ray &) const override; }; + LinkStraight::~LinkStraight() = default; class LinkCurve : public virtual Link { @@ -87,4 +88,5 @@ public: float radius; Arc arc; }; + LinkCurve::~LinkCurve() = default; diff --git a/game/network/rail.cpp b/game/network/rail.cpp index bd24a2b..5a4f1e1 100644 --- a/game/network/rail.cpp +++ b/game/network/rail.cpp @@ -21,6 +21,7 @@ constexpr auto RAIL_CROSSSECTION_VERTICES {5U}; constexpr glm::vec3 RAIL_HEIGHT {0, 0, .25F}; RailLinks::RailLinks() : NetworkOf<RailLink> {"rails.jpg"} { } + void RailLinks::tick(TickDuration) { diff --git a/game/network/rail.h b/game/network/rail.h index 611eb67..6684801 100644 --- a/game/network/rail.h +++ b/game/network/rail.h @@ -18,6 +18,7 @@ struct Arc; // A piece of rail track class RailLinkStraight; class RailLinkCurve; + class RailLink : public virtual Link, public Renderable { public: RailLink() = default; @@ -36,6 +37,7 @@ protected: Mesh::Ptr mesh; }; + RailLink::~RailLink() = default; class RailLinkStraight : public RailLink, public LinkStraight { diff --git a/game/objective.h b/game/objective.h index 130015f..f5c6e48 100644 --- a/game/objective.h +++ b/game/objective.h @@ -10,6 +10,7 @@ class Orders; class Objective { public: explicit Objective(Orders * os) : orders(os) { } + DEFAULT_MOVE_COPY(Objective); virtual ~Objective() = default; @@ -19,4 +20,5 @@ public: Orders * orders; }; + using ObjectivePtr = std::unique_ptr<Objective>; diff --git a/game/orders.h b/game/orders.h index f29e208..ca5cfdb 100644 --- a/game/orders.h +++ b/game/orders.h @@ -10,4 +10,5 @@ public: [[nodiscard]] Objective * current() const; Objective * next(); }; + using OrdersPtr = std::shared_ptr<Orders>; diff --git a/game/vehicles/railVehicle.h b/game/vehicles/railVehicle.h index f34643e..be88142 100644 --- a/game/vehicles/railVehicle.h +++ b/game/vehicles/railVehicle.h @@ -25,4 +25,5 @@ public: BLocation location; std::array<BLocation, 2> bogies; }; + using RailVehiclePtr = std::unique_ptr<RailVehicle>; diff --git a/game/vehicles/railVehicleClass.h b/game/vehicles/railVehicleClass.h index 80b3fda..4668d7d 100644 --- a/game/vehicles/railVehicleClass.h +++ b/game/vehicles/railVehicleClass.h @@ -41,4 +41,5 @@ private: glVertexArray instanceVAO; std::array<glVertexArray, 2> instancesBogiesVAO; }; + using RailVehicleClassPtr = std::shared_ptr<RailVehicleClass>; diff --git a/game/vehicles/vehicle.h b/game/vehicles/vehicle.h index 763ade9..354f904 100644 --- a/game/vehicles/vehicle.h +++ b/game/vehicles/vehicle.h @@ -27,4 +27,5 @@ protected: void move(TickDuration dur); LinkHistory linkHist; }; + using VehicleWPtr = std::weak_ptr<Vehicle>; diff --git a/gfx/gl/camera.h b/gfx/gl/camera.h index 3f1c3a7..7956ec3 100644 --- a/gfx/gl/camera.h +++ b/gfx/gl/camera.h @@ -13,6 +13,7 @@ public: { return viewProjection; } + [[nodiscard]] Ray unProject(const glm::vec2 &) const; void @@ -21,11 +22,13 @@ public: position = p; updateView(); } + void setForward(const glm::vec3 & f) { setForward(f, upFromForward(f)); } + void setForward(const glm::vec3 & f, const glm::vec3 & u) { @@ -33,28 +36,33 @@ public: up = u; updateView(); } + void setView(const glm::vec3 & p, const glm::vec3 & f) { position = p; setForward(f); } + void setView(const glm::vec3 & p, const glm::vec3 & f, const glm::vec3 & u) { position = p; setView(f, u); } + void lookAt(const glm::vec3 & target) { setForward(glm::normalize(target - position)); } + [[nodiscard]] auto getForward() const { return forward; } + [[nodiscard]] auto getPosition() const { diff --git a/gfx/gl/instanceVertices.h b/gfx/gl/instanceVertices.h index 7b0341b..a89aa78 100644 --- a/gfx/gl/instanceVertices.h +++ b/gfx/gl/instanceVertices.h @@ -13,9 +13,11 @@ public: class [[nodiscard]] InstanceProxy { public: InstanceProxy(InstanceVertices * iv, std::size_t idx) : instances {iv}, index {idx} { } + InstanceProxy(InstanceProxy && other) : instances {std::exchange(other.instances, nullptr)}, index {other.index} { } + NO_COPY(InstanceProxy); ~InstanceProxy() @@ -35,6 +37,7 @@ public: index = other.index; return *this; } + template<typename U> T & operator=(U && v) @@ -42,40 +45,46 @@ public: return instances->lookup(index) = std::forward<U>(v); } - [[nodiscard]] - operator T &() + [[nodiscard]] operator T &() { return instances->lookup(index); } + [[nodiscard]] operator const T &() const { return instances->lookup(index); } + [[nodiscard]] T * get() { return &instances->lookup(index); } + [[nodiscard]] const T * get() const { return &instances->lookup(index); } + [[nodiscard]] T * operator->() { return get(); } + [[nodiscard]] const T * operator->() const { return get(); } + [[nodiscard]] T & operator*() { return instances->lookup(index); } + [[nodiscard]] const T & operator*() const { diff --git a/gfx/gl/program.h b/gfx/gl/program.h index 76b6742..1a1c306 100644 --- a/gfx/gl/program.h +++ b/gfx/gl/program.h @@ -9,6 +9,7 @@ class Location; using ProgramRef = glRef<GLuint, &glCreateProgram, &glDeleteProgram>; + class Program { public: template<typename... S> explicit Program(const S &... srcs) @@ -16,12 +17,14 @@ public: (glAttachShader(m_program, srcs.compile()), ...); linkAndValidate(); } + virtual ~Program() = default; DEFAULT_MOVE_NO_COPY(Program); class UniformLocation { public: UniformLocation(GLuint prog, const char * name); + // NOLINTNEXTLINE(hicpp-explicit-conversions) operator auto() const { diff --git a/gfx/gl/sceneProvider.cpp b/gfx/gl/sceneProvider.cpp index 0163b36..2e8604c 100644 --- a/gfx/gl/sceneProvider.cpp +++ b/gfx/gl/sceneProvider.cpp @@ -7,6 +7,7 @@ SceneProvider::environment(const SceneShader &, const SceneRenderer & renderer) renderer.setAmbientLight({0.5F, 0.5F, 0.5F}); renderer.setDirectionalLight({0.6F, 0.6F, 0.6F}, {-1, 1, -1}, *this); } + void SceneProvider::shadows(const ShadowMapper &) const { diff --git a/gfx/gl/sceneRenderer.cpp b/gfx/gl/sceneRenderer.cpp index aa9453a..5799daf 100644 --- a/gfx/gl/sceneRenderer.cpp +++ b/gfx/gl/sceneRenderer.cpp @@ -13,6 +13,7 @@ static constexpr const std::array<const glm::i8vec4, 4> displayVAOdata {{ {1, 1, 1, 1}, {1, -1, 1, 0}, }}; + SceneRenderer::SceneRenderer(glm::ivec2 s, GLuint o) : camera {{-1250.0F, -1250.0F, 35.0F}, quarter_pi, ratio(s), 0.1F, 10000.0F}, size {s}, output {o}, lighting {lighting_vs, lighting_fs}, shadowMapper {{2048, 2048}} diff --git a/gfx/gl/sceneRenderer.h b/gfx/gl/sceneRenderer.h index d4af665..55df84d 100644 --- a/gfx/gl/sceneRenderer.h +++ b/gfx/gl/sceneRenderer.h @@ -27,11 +27,13 @@ private: glFrameBuffer gBuffer; glTexture gPosition, gNormal, gAlbedoSpec, gIllumination; glRenderBuffer depth; + class DeferredLightProgram : public Program { public: using Program::Program; using Program::use; }; + class DirectionalLightProgram : public Program { public: DirectionalLightProgram(); diff --git a/gfx/gl/shader.h b/gfx/gl/shader.h index 0810e6b..cff2281 100644 --- a/gfx/gl/shader.h +++ b/gfx/gl/shader.h @@ -8,6 +8,7 @@ class Shader { public: using ShaderRef = glRef<GLuint, &glCreateShader, &glDeleteShader>; + constexpr Shader(const GLchar * text, GLint len, GLuint type) : text {text}, len {len}, type {type} { } [[nodiscard]] ShaderRef compile() const; diff --git a/gfx/gl/shadowMapper.cpp b/gfx/gl/shadowMapper.cpp index 55d986c..79b39c0 100644 --- a/gfx/gl/shadowMapper.cpp +++ b/gfx/gl/shadowMapper.cpp @@ -94,11 +94,13 @@ struct DefinitionsInserter { { return out.maps++; }; + auto operator*() { return std::tie(out.projections[out.maps], out.regions[out.maps]); } + ShadowMapper::Definitions & out; }; @@ -161,12 +163,14 @@ ShadowMapper::update(const SceneProvider & scene, const glm::vec3 & dir, const C } ShadowMapper::FixedPoint::FixedPoint(const Shader & vs) : Program {vs}, viewProjectionLoc {*this, "viewProjection"} { } + void ShadowMapper::FixedPoint::setViewProjection(const glm::mat4 & viewProjection) const { use(); glUniformMatrix4fv(viewProjectionLoc, 1, GL_FALSE, glm::value_ptr(viewProjection)); } + void ShadowMapper::FixedPoint::use() const { @@ -177,12 +181,14 @@ ShadowMapper::DynamicPoint::DynamicPoint() : Program {shadowDynamicPoint_vs}, viewProjectionLoc {*this, "viewProjection"}, modelLoc {*this, "model"} { } + void ShadowMapper::DynamicPoint::setViewProjection(const glm::mat4 & viewProjection) const { glUseProgram(*this); glUniformMatrix4fv(viewProjectionLoc, 1, GL_FALSE, glm::value_ptr(viewProjection)); } + void ShadowMapper::DynamicPoint::use(const Location & location) const { @@ -191,6 +197,7 @@ ShadowMapper::DynamicPoint::use(const Location & location) const const auto model = glm::translate(location.pos) * rotate_ypr(location.rot); glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glm::value_ptr(model)); } + void ShadowMapper::DynamicPoint::setModel(const Location & location) const { diff --git a/gfx/gl/shadowMapper.h b/gfx/gl/shadowMapper.h index 36371eb..cd1b975 100644 --- a/gfx/gl/shadowMapper.h +++ b/gfx/gl/shadowMapper.h @@ -8,16 +8,19 @@ class SceneProvider; class Camera; #include <gfx/models/texture.h> + class ShadowMapper { public: explicit ShadowMapper(const glm::ivec2 & size); static constexpr std::size_t SHADOW_BANDS {4}; + struct Definitions { std::array<glm::mat4x4, SHADOW_BANDS> projections {}; std::array<glm::vec4, SHADOW_BANDS> regions {}; size_t maps {}; }; + [[nodiscard]] Definitions update(const SceneProvider &, const glm::vec3 & direction, const Camera &) const; class FixedPoint : public Program { @@ -29,6 +32,7 @@ public: private: RequiredUniformLocation viewProjectionLoc; }; + class DynamicPoint : public Program { public: DynamicPoint(); @@ -40,6 +44,7 @@ public: RequiredUniformLocation viewProjectionLoc; RequiredUniformLocation modelLoc; }; + FixedPoint fixedPoint, dynamicPointInst; DynamicPoint dynamicPoint; diff --git a/gfx/gl/uiShader.cpp b/gfx/gl/uiShader.cpp index 78e0064..0b47211 100644 --- a/gfx/gl/uiShader.cpp +++ b/gfx/gl/uiShader.cpp @@ -9,6 +9,7 @@ #include <initializer_list> UIShader::IconProgram::IconProgram(const glm::mat4 & vp) : UIProgram {vp, uiShader_vs, uiShader_fs} { } + UIShader::TextProgram::TextProgram(const glm::mat4 & vp) : UIProgram {vp, uiShader_vs, uiShaderFont_fs}, colorLoc {*this, "colour"} { @@ -18,6 +19,7 @@ UIShader::UIShader(size_t width, size_t height) : UIShader {glm::ortho<float>(0, static_cast<float>(width), 0, static_cast<float>(height))} { } + UIShader::UIShader(const glm::mat4 & viewProjection) : icon {viewProjection}, text {viewProjection} { } void diff --git a/gfx/gl/vertexArrayObject.h b/gfx/gl/vertexArrayObject.h index fa6baa3..57daaf3 100644 --- a/gfx/gl/vertexArrayObject.h +++ b/gfx/gl/vertexArrayObject.h @@ -11,22 +11,27 @@ public: { glBindVertexArray(arrayObject); } + ~VertexArrayObject() { glBindVertexArray(0); } + NO_MOVE(VertexArrayObject); NO_COPY(VertexArrayObject); template<typename m, typename T> struct MP { constexpr MP(m T::*p) : P {p} { } + operator void *() const { return &(static_cast<T *>(nullptr)->*P); } + m T::*P; using value_type = m; }; + template<typename m, typename T> MP(m T::*) -> MP<m, T>; template<typename VertexT, MP... attribs> diff --git a/gfx/image.h b/gfx/image.h index 8bb4067..6fbbdd1 100644 --- a/gfx/image.h +++ b/gfx/image.h @@ -7,7 +7,9 @@ class Image { public: Image(const char * fileName, int flags); + Image(const std::string & fileName, int flags) : Image(fileName.c_str(), flags) { } + Image(std::span<unsigned char> data, int flags); ~Image(); diff --git a/gfx/models/texture.cpp b/gfx/models/texture.cpp index 380f2e0..b7f1bee 100644 --- a/gfx/models/texture.cpp +++ b/gfx/models/texture.cpp @@ -139,11 +139,13 @@ GLuint TextureAtlas::add(glm::ivec2 position, glm::ivec2 size, void * data, TextureOptions to) { glTextureSubImage2D(m_texture, 0, position.x, position.y, size.x, size.y, GL_RGBA, GL_UNSIGNED_BYTE, data); + struct Material { glm::vec<2, uint16_t> position, size; TextureOptions::MapMode wrapU; TextureOptions::MapMode wrapV; } material {position, size, to.wrapU, to.wrapV}; + static_assert(sizeof(Material) <= 32); glTextureSubImage2D(m_atlas, 0, 0, static_cast<GLsizei>(used), 2, 1, GL_RGBA_INTEGER, GL_UNSIGNED_SHORT, &material); return ++used; diff --git a/gfx/models/tga.h b/gfx/models/tga.h index 1f400ef..52db220 100644 --- a/gfx/models/tga.h +++ b/gfx/models/tga.h @@ -11,4 +11,5 @@ struct TGAHead { uint8_t pixelDepth {}; uint8_t descriptor {}; }; + static_assert(sizeof(TGAHead) == 18); diff --git a/gfx/renderable.cpp b/gfx/renderable.cpp index 539efb1..0340189 100644 --- a/gfx/renderable.cpp +++ b/gfx/renderable.cpp @@ -4,6 +4,7 @@ void Renderable::lights(const SceneShader &) const { } + void Renderable::shadows(const ShadowMapper &) const { diff --git a/lib/cache.h b/lib/cache.h index 2c3975b..f5fd227 100644 --- a/lib/cache.h +++ b/lib/cache.h @@ -35,4 +35,5 @@ public: private: std::map<Key, Ptr, std::less<>> cached; }; + // IWYU pragma: no_forward_declare Cache diff --git a/lib/collections.h b/lib/collections.h index 7d78ef9..943b986 100644 --- a/lib/collections.h +++ b/lib/collections.h @@ -149,11 +149,14 @@ template<typename T> struct pair_range { { return pair.first; } + constexpr auto & end() const noexcept { return pair.second; } + const std::pair<T, T> & pair; }; + template<typename T> pair_range(std::pair<T, T>) -> pair_range<T>; diff --git a/lib/enumDetails.h b/lib/enumDetails.h index 5966be2..b6ff046 100644 --- a/lib/enumDetails.h +++ b/lib/enumDetails.h @@ -26,11 +26,13 @@ template<typename E> struct EnumTypeDetails : EnumDetailsBase { protected: #endif constexpr static std::string_view SEARCH_TYPE {"E = "}; + constexpr static auto typeraw() { return std::string_view {__PRETTY_FUNCTION__}; }; + constexpr static auto typeNameStart {typeraw().find(SEARCH_TYPE) + SEARCH_TYPE.length()}; constexpr static auto typeNameEnd {typeraw().find_first_of("];", typeNameStart)}; constexpr static auto typeNameLen {typeNameEnd - typeNameStart}; @@ -47,11 +49,13 @@ template<auto value> struct EnumValueDetails : public EnumTypeDetails<decltype(v private: #endif using T = EnumTypeDetails<decltype(value)>; + constexpr static auto raw() { return std::string_view {__PRETTY_FUNCTION__}; }; + constexpr static auto nameStart {raw().find_last_of(": ") + 1}; constexpr static auto nameEnd {raw().find_first_of("];", nameStart)}; constexpr static auto nameLen {nameEnd - nameStart}; @@ -84,12 +88,14 @@ private: return std::array {EnumValueDetails<static_cast<E>(n)>::valid...}; #pragma GCC diagnostic pop } + template<auto... n> constexpr static auto get_values(std::integer_sequence<int, n...>) { return std::array {EnumValueDetails<static_cast<E>(n)>::raw_value...}; } + template<auto... n> constexpr static auto get_valueNames(std::integer_sequence<int, n...>) diff --git a/lib/glArrays.h b/lib/glArrays.h index 86385d9..787ea17 100644 --- a/lib/glArrays.h +++ b/lib/glArrays.h @@ -15,7 +15,8 @@ public: CUSTOM_MOVE(glArraysBase); // NOLINTNEXTLINE(hicpp-explicit-conversions) - inline operator GLuint() const + inline + operator GLuint() const { static_assert(N == 1, "Implicit cast only if N == 1"); return ids.front(); diff --git a/lib/glContainer.h b/lib/glContainer.h index 993170e..8177618 100644 --- a/lib/glContainer.h +++ b/lib/glContainer.h @@ -9,6 +9,7 @@ template<typename I, typename Direction> class basic_glContainer_iterator { public: explicit basic_glContainer_iterator(I * i) : i {i} { } + template<typename OtherI> basic_glContainer_iterator(const basic_glContainer_iterator<OtherI, Direction> & other) : i {&*other} { @@ -20,17 +21,20 @@ public: i = Direction {}(i, 1); return *this; } + auto operator++(int) noexcept { return basic_glContainer_iterator<I, Direction> {std::exchange(i, Direction {}(i, 1))}; } + auto & operator--() noexcept { i = Direction {}(i, -1); return *this; } + auto operator--(int) noexcept { @@ -76,6 +80,7 @@ public: { return this->i == other.i; } + [[nodiscard]] bool operator!=(const basic_glContainer_iterator & other) const noexcept { @@ -87,6 +92,7 @@ public: { return i; } + [[nodiscard]] auto & operator*() const noexcept { diff --git a/lib/gl_traits.h b/lib/gl_traits.h index a930eba..934b505 100644 --- a/lib/gl_traits.h +++ b/lib/gl_traits.h @@ -6,9 +6,11 @@ #include <glm/fwd.hpp> template<typename T> struct gl_traits; + struct gl_traits_base { static constexpr GLint size {1}; }; + struct gl_traits_float : public gl_traits_base { static constexpr auto vertexAttribFunc { [](GLuint index, GLint size, GLenum type, GLsizei stride, const void * pointer) -> GLuint { @@ -16,6 +18,7 @@ struct gl_traits_float : public gl_traits_base { return 1; }}; }; + struct gl_traits_longfloat : public gl_traits_base { static constexpr auto vertexAttribFunc { [](GLuint index, GLint size, GLenum type, GLsizei stride, const void * pointer) -> GLuint { @@ -23,6 +26,7 @@ struct gl_traits_longfloat : public gl_traits_base { return 1; }}; }; + struct gl_traits_integer : public gl_traits_base { static constexpr auto vertexAttribFunc { [](GLuint index, GLint size, GLenum type, GLsizei stride, const void * pointer) -> GLuint { @@ -30,27 +34,35 @@ struct gl_traits_integer : public gl_traits_base { return 1; }}; }; + template<> struct gl_traits<glm::f32> : public gl_traits_float { static constexpr GLenum type {GL_FLOAT}; }; + template<> struct gl_traits<glm::f64> : public gl_traits_longfloat { static constexpr GLenum type {GL_DOUBLE}; }; + template<> struct gl_traits<glm::int8> : public gl_traits_integer { static constexpr GLenum type {GL_BYTE}; }; + template<> struct gl_traits<glm::int16> : public gl_traits_integer { static constexpr GLenum type {GL_SHORT}; }; + template<> struct gl_traits<glm::int32> : public gl_traits_integer { static constexpr GLenum type {GL_INT}; }; + template<> struct gl_traits<glm::uint8> : public gl_traits_integer { static constexpr GLenum type {GL_UNSIGNED_BYTE}; }; + template<> struct gl_traits<glm::uint16> : public gl_traits_integer { static constexpr GLenum type {GL_UNSIGNED_SHORT}; }; + template<> struct gl_traits<glm::uint32> : public gl_traits_integer { static constexpr GLenum type {GL_UNSIGNED_INT}; }; diff --git a/lib/jsonParse-persistence.cpp b/lib/jsonParse-persistence.cpp index fe8bf8d..5c0011a 100644 --- a/lib/jsonParse-persistence.cpp +++ b/lib/jsonParse-persistence.cpp @@ -93,17 +93,20 @@ namespace Persistence { { strm.put(ch); } + static inline void wrh(std::ostream & strm, char ch) { using namespace std::literals; strm << R"(\u)"sv << std::setw(4) << std::hex << static_cast<int>(ch) << std::setw(1); } + static inline void wre(std::ostream & strm, char e) { strm << '\\' << e; } + template<char E> static inline void wre(std::ostream & strm, char) diff --git a/lib/maths.cpp b/lib/maths.cpp index b8dbd34..7594b59 100644 --- a/lib/maths.cpp +++ b/lib/maths.cpp @@ -177,12 +177,14 @@ find_arcs_radius(glm::vec2 start, glm::vec2 ad, glm::vec2 end, glm::vec2 bd) / (2 * (sq(X) - 2 * X * Z + sq(Z) + sq(Y) - 2 * Y * W + sq(W) - 4)); } -float operator"" _mph(const long double v) +float +operator"" _mph(const long double v) { return static_cast<float>(mph_to_ms(v)); } -float operator"" _kph(const long double v) +float +operator"" _kph(const long double v) { return static_cast<float>(kph_to_ms(v)); } diff --git a/lib/persistence.cpp b/lib/persistence.cpp index e22d74d..38e2ac6 100644 --- a/lib/persistence.cpp +++ b/lib/persistence.cpp @@ -167,6 +167,7 @@ namespace Persistence { { throw std::logic_error("Default write op shouldn't ever get called"); } + /// LCOV_EXCL_STOP ParseBase::ParseBase() : sharedObjectsInstance {std::make_shared<SharedObjects>()} diff --git a/lib/persistence.h b/lib/persistence.h index 5d71d4c..92f3052 100644 --- a/lib/persistence.h +++ b/lib/persistence.h @@ -153,6 +153,7 @@ namespace Persistence { }; struct Persistable; + struct PersistenceStore { using SelectionFactory = std::function<SelectionPtr()>; PersistenceStore() = default; @@ -163,6 +164,7 @@ namespace Persistence { enum class NameAction { Push, HandleAndContinue, Ignore }; using NameActionSelection = std::pair<NameAction, SelectionPtr>; + template<typename Helper, typename T> [[nodiscard]] inline bool persistValue(const std::string_view key, T & value) @@ -267,6 +269,7 @@ namespace Persistence { template<glm::length_t L, typename T, glm::qualifier Q> struct SelectionT<glm::vec<L, T, Q>> : public SelectionT<std::span<T>> { SelectionT(glm::vec<L, T, Q> & v) : SelectionT<std::span<T>> {spn}, spn {&v[0], L} { } + std::span<T> spn; }; @@ -316,6 +319,7 @@ namespace Persistence { MapByMember(Map & m) : Persistence::SelectionT<Type> {s}, map {m} { } using Persistence::SelectionT<Type>::SelectionT; + void endObject(Persistence::Stack & stk) override { @@ -332,7 +336,9 @@ namespace Persistence { template<typename Container, typename Type = typename Container::value_type> struct Appender : public Persistence::SelectionT<Type> { Appender(Container & c) : Persistence::SelectionT<Type> {s}, container {c} { } + using Persistence::SelectionT<Type>::SelectionT; + void endObject(Persistence::Stack & stk) override { @@ -407,6 +413,7 @@ namespace Persistence { { return std::dynamic_pointer_cast<T>(Persistence::ParseBase::sharedObjects.lock()->at(k)); } + template<typename... T> static auto emplaceShared(T &&... v) @@ -421,6 +428,7 @@ namespace Persistence { inline static thread_local SharedObjectsWPtr sharedObjects; SharedObjectsPtr sharedObjectsInstance; }; + // TODO Move these using SeenSharedObjects = std::map<void *, std::string>; inline SeenSharedObjects seenSharedObjects; @@ -428,6 +436,7 @@ namespace Persistence { template<typename Ptr> struct SelectionPtrBase : public SelectionV<Ptr> { static constexpr auto shared = std::is_copy_assignable_v<Ptr>; using T = typename Ptr::element_type; + struct SelectionObj : public SelectionV<Ptr> { struct MakeObjectByTypeName : public SelectionV<Ptr> { using SelectionV<Ptr>::SelectionV; @@ -55,6 +55,7 @@ public: protected: explicit wrapped_ptr(Obj * o) : obj {o} { } + Obj * obj; }; diff --git a/lib/resource.h b/lib/resource.h index 37dd657..9af3632 100644 --- a/lib/resource.h +++ b/lib/resource.h @@ -16,5 +16,6 @@ public: Resource::setBasePath(RESDIR); } }; + BOOST_GLOBAL_FIXTURE(SetResourcePath); #endif diff --git a/lib/saxParse-persistence.h b/lib/saxParse-persistence.h index 6043b25..bd5db57 100644 --- a/lib/saxParse-persistence.h +++ b/lib/saxParse-persistence.h @@ -10,6 +10,7 @@ namespace Persistence { private: template<typename T> struct Root : public Persistable { T t {}; + bool persist(PersistenceStore & store) { diff --git a/lib/stdTypeDefs.h b/lib/stdTypeDefs.h index 317cdb3..beab630 100644 --- a/lib/stdTypeDefs.h +++ b/lib/stdTypeDefs.h @@ -6,18 +6,22 @@ template<typename T> struct AnyPtr { // cppcheck-suppress noExplicitConstructor AnyPtr(T * p) : ptr {p} { } + // cppcheck-suppress noExplicitConstructor template<typename S> AnyPtr(const S & p) : ptr {p.get()} { } + auto get() const { return ptr; } + auto operator->() const { return ptr; } + auto & operator*() const { diff --git a/lib/unicode.h b/lib/unicode.h index f69c43c..bc491f3 100644 --- a/lib/unicode.h +++ b/lib/unicode.h @@ -50,6 +50,7 @@ struct utf8_string_view { constexpr utf8_string_view(const Str & str) : begin_ {str.data()}, end_ {str.data() + str.length()} { } + // cppcheck-suppress noExplicitConstructor; NOLINTNEXTLINE(hicpp-explicit-conversions) constexpr utf8_string_view(const char * const str) : utf8_string_view {std::string_view {str}} { } @@ -70,6 +71,7 @@ struct utf8_string_view { private: const char *begin_, *end_; }; + template<> struct std::iterator_traits<utf8_string_view::iter> { using difference_type = size_t; using value_type = uint32_t; diff --git a/lib/worker.h b/lib/worker.h index 0d15ca2..95bb4ec 100644 --- a/lib/worker.h +++ b/lib/worker.h @@ -16,6 +16,7 @@ public: class WorkItem { protected: WorkItem(Worker * worker) : worker {worker} { } + virtual ~WorkItem() = default; NO_MOVE(WorkItem); NO_COPY(WorkItem); @@ -25,6 +26,7 @@ public: { worker->assist(); } + Worker * worker; public: @@ -57,6 +59,7 @@ public: { return instance.addWorkImpl(std::forward<Params>(params)...); } + template<typename T> using WorkPtrT = std::shared_ptr<WorkItemT<T>>; private: diff --git a/test/enumDetailsData.h b/test/enumDetailsData.h index 713d742..b7bd601 100644 --- a/test/enumDetailsData.h +++ b/test/enumDetailsData.h @@ -3,13 +3,16 @@ enum GlobalUnscoped { aa, b, c }; enum class GlobalScoped { aa, b, c }; + namespace ns { enum Unscoped { aa, b, c }; enum class Scoped { aa, b, c }; } + namespace test1 { enum class DefaultDense { a, bee, ci, de }; } + namespace test2 { enum class NumberedSparse { a = 0, bee = 3, ci = -20, de = 100 }; } diff --git a/test/test-assetFactory.cpp b/test/test-assetFactory.cpp index 18dc778..145481e 100644 --- a/test/test-assetFactory.cpp +++ b/test/test-assetFactory.cpp @@ -24,44 +24,52 @@ BOOST_GLOBAL_FIXTURE(ApplicationBase); BOOST_GLOBAL_FIXTURE(TestMainWindow); const std::filesystem::path TMP {"/tmp"}; + class FactoryFixture : public TestRenderOutputSize<glm::ivec2 {2048, 1024}>, public SceneProvider { public: FactoryFixture() : sceneRenderer {size, output} { } + ~FactoryFixture() { auto outpath = (TMP / boost::unit_test::framework::current_test_case().full_name()).replace_extension(".tga"); std::filesystem::create_directories(outpath.parent_path()); Texture::save(outImage, outpath.c_str()); } + void content(const SceneShader & shader) const override { shader.basic.use(Location {{0, 0, 0}, {0, 0, 0}}); objects.apply(&Renderable::render, shader); } + void lights(const SceneShader & shader) const override { shader.pointLight.add({-3, 1, 5}, {1, 1, 1}, .1F); } + void environment(const SceneShader &, const SceneRenderer & sceneRenderer) const override { sceneRenderer.setAmbientLight({.4, .4, .4}); sceneRenderer.setDirectionalLight({.6, .6, .6}, east + south + south + down, *this); } + void shadows(const ShadowMapper & mapper) const override { mapper.dynamicPoint.use(Location {{0, 0, 0}, {0, 0, 0}}); objects.apply(&Renderable::shadows, mapper); } + void render(float dist = 10.f) { sceneRenderer.camera.setView({-dist, dist * 1.2f, dist * 1.2f}, south + east + down); sceneRenderer.render(*this); } + Collection<const Renderable> objects; private: @@ -69,6 +77,7 @@ private: }; BOOST_FIXTURE_TEST_SUITE(m, FactoryFixture); + BOOST_AUTO_TEST_CASE(brush47xml, *boost::unit_test::timeout(5)) { auto mf = AssetFactory::loadXML(RESDIR "/brush47.xml"); @@ -115,6 +124,7 @@ BOOST_AUTO_TEST_CASE(foliage, *boost::unit_test::timeout(5)) render(5); } + BOOST_AUTO_TEST_SUITE_END(); BOOST_AUTO_TEST_CASE(loadall) @@ -125,6 +135,7 @@ BOOST_AUTO_TEST_CASE(loadall) } template<typename T> using InOut = std::tuple<T, T>; + BOOST_DATA_TEST_CASE(normalizeColourName, boost::unit_test::data::make<InOut<std::string>>({ {"", ""}, diff --git a/test/test-collection.cpp b/test/test-collection.cpp index 16db792..00204fc 100644 --- a/test/test-collection.cpp +++ b/test/test-collection.cpp @@ -13,12 +13,14 @@ public: Base() = default; virtual ~Base() = default; DEFAULT_MOVE_COPY(Base); + virtual bool add() { total += 1; return false; } + unsigned int total {0}; }; diff --git a/test/test-geo.cpp b/test/test-geo.cpp index e672e54..9874fb7 100644 --- a/test/test-geo.cpp +++ b/test/test-geo.cpp @@ -108,6 +108,7 @@ BOOST_AUTO_TEST_CASE(get_height_at) using TestRayTracerData = std::tuple<glm::vec2, glm::vec2, glm::vec2::value_type, std::vector<glm::vec2>>; BOOST_TEST_DECORATOR(*boost::unit_test::timeout(1)) + BOOST_DATA_TEST_CASE(raytracer, boost::unit_test::data::make<TestRayTracerData>({ {{1, 2}, {4, 5}, 4, @@ -145,6 +146,7 @@ BOOST_DATA_TEST_CASE(raytracer, using TestRayData = std::tuple<glm::vec3, glm::vec3, glm::vec3>; BOOST_TEST_DECORATOR(*boost::unit_test::timeout(1)) + BOOST_DATA_TEST_CASE(intersect_ray, boost::unit_test::data::make<TestRayData>({ {{-1, -1, 1.0}, {1, 1, 0}, {0, 0, 1}}, @@ -169,6 +171,7 @@ BOOST_DATA_TEST_CASE(intersect_ray, nodes[at(1, 1)].height = 4; const auto intersect = intersectRay({start, glm::normalize(dir)}); + BOOST_CHECK_IF(has_intersect, intersect) { BOOST_CHECK_CLOSE_VEC(*intersect, pos); } @@ -178,6 +181,7 @@ auto xs = boost::unit_test::data::xrange(-20.F, 0.F, 0.6F), ys = boost::unit_tes auto targetsx = boost::unit_test::data::xrange(0.2F, 4.9F, 1.3F), targetsy = boost::unit_test::data::xrange(0.3F, 4.9F, 1.3F); BOOST_TEST_DECORATOR(*boost::unit_test::timeout(1)) + BOOST_DATA_TEST_CASE(intersect_ray_many, xs * ys * targetsx * targetsy, x, y, targetx, targety) { // at(x,y) is index based @@ -189,8 +193,10 @@ BOOST_DATA_TEST_CASE(intersect_ray_many, xs * ys * targetsx * targetsy, x, y, ta const glm::vec3 start {x, y, 10}; const auto target {this->positionAt({targetx, targety})}; const Ray ray {start, glm::normalize(target - start)}; + BOOST_TEST_CONTEXT(ray) { const auto intersect = intersectRay(ray); + BOOST_CHECK_IF(has_intersect, intersect) { BOOST_CHECK_CLOSE_VEC(*intersect, target); } @@ -198,6 +204,7 @@ BOOST_DATA_TEST_CASE(intersect_ray_many, xs * ys * targetsx * targetsy, x, y, ta } BOOST_TEST_DECORATOR(*boost::unit_test::timeout(1)) + BOOST_DATA_TEST_CASE(intersect_ray_miss, boost::unit_test::data::make<Ray>({ {{3, 3, 5}, {-1, -1, 0}}, diff --git a/test/test-glContainer.cpp b/test/test-glContainer.cpp index 33ec992..cd57a6b 100644 --- a/test/test-glContainer.cpp +++ b/test/test-glContainer.cpp @@ -281,6 +281,7 @@ struct C { int x; float y; }; + static_assert(std::is_trivially_destructible_v<C>); BOOST_FIXTURE_TEST_SUITE(c, glContainer<C>) @@ -307,9 +308,11 @@ struct CC { { ++x; } + int x; float y; }; + static_assert(!std::is_trivially_destructible_v<CC>); BOOST_FIXTURE_TEST_SUITE(cc, glContainer<CC>) diff --git a/test/test-glContextBhvr.cpp b/test/test-glContextBhvr.cpp index 769f61f..26b45d9 100644 --- a/test/test-glContextBhvr.cpp +++ b/test/test-glContextBhvr.cpp @@ -11,12 +11,14 @@ BOOST_GLOBAL_FIXTURE(ApplicationBase); #define TEST_WINDOW_PARAMS __FILE__, 0, 0, 640, 480, static_cast<Uint32>(SDL_WINDOW_OPENGL | SDL_WINDOW_HIDDEN) + static void CreateProgramTest() { const ProgramRef p; BOOST_REQUIRE(p); } + BOOST_AUTO_TEST_CASE(windowContextThingsBehaviour1) { BOOST_REQUIRE(!glCreateProgram); // Init not called yet diff --git a/test/test-instancing.cpp b/test/test-instancing.cpp index 7d8ea55..c1860a4 100644 --- a/test/test-instancing.cpp +++ b/test/test-instancing.cpp @@ -163,6 +163,7 @@ BOOST_DATA_TEST_CASE(shuffle_random, boost::unit_test::data::xrange(0, 10), x) iused.emplace(index[i]); } } + BOOST_TEST_CONTEXT(index) { BOOST_REQUIRE_EQUAL(iused.size(), size()); if (!iused.empty()) { diff --git a/test/test-lib.cpp b/test/test-lib.cpp index aaf6292..58b769a 100644 --- a/test/test-lib.cpp +++ b/test/test-lib.cpp @@ -9,6 +9,7 @@ #include <set> std::set<GLuint> active; + void generator(GLsizei n, GLuint * out) { diff --git a/test/test-maths.cpp b/test/test-maths.cpp index a4a881d..2560319 100644 --- a/test/test-maths.cpp +++ b/test/test-maths.cpp @@ -36,6 +36,7 @@ static_assert(east.x > 0); static_assert(west == -east); // (-ve, y, z) is "west" static_assert(west.x < 0); + // // Therefore, the geographic world exists west -ve to east +ve and from south -ve to north +ve. Forward shall be // considered +ve motion; the "front" of a vehicle shall have a +ve value in y axis. @@ -110,9 +111,11 @@ const auto rots = boost::unit_test::data::make<std::tuple<glm::vec3, glm::mat4 ( {east, rotate_pitch, "pitch"}, {north, rotate_roll, "roll"}, }); + BOOST_DATA_TEST_CASE(test_rotations, (angs + random_angs) * rots, angle, ai, axis, ilt_func, name) { (void)ai; + BOOST_TEST_CONTEXT(name) { const auto g {glm::rotate(angle, axis)}, ilt {ilt_func(angle)}; for (glm::length_t c = 0; c < 4; c++) { @@ -130,6 +133,7 @@ BOOST_DATA_TEST_CASE(test_rotations, (angs + random_angs) * rots, angle, ai, axi // An arc shall be defined as a centre point, start point and end point. The arc shall progress positively from start to // end in a clockwise manner. Arc start shall be the yaw from centre to start, arc end shall be greater than arc start. using pos3_to_arc = std::tuple<glm::vec3, glm::vec3, glm::vec3, Arc>; + BOOST_DATA_TEST_CASE(test_create_arc, boost::unit_test::data::make<pos3_to_arc>({ {{0, 0, 0}, north, east, {0, half_pi}}, @@ -148,6 +152,7 @@ BOOST_DATA_TEST_CASE(test_create_arc, } using fac = std::tuple<glm::vec2, float, glm::vec2, float, glm::vec2, bool>; + BOOST_DATA_TEST_CASE(test_find_arc_centre, boost::unit_test::data::make<fac>({ {{2, 2}, pi, {3, 3}, half_pi, {3, 2}, true}, @@ -178,6 +183,7 @@ struct TestLinkStraight : public LinkStraight { }; using StraightsData = std::tuple<glm::vec3, float /*angFor*/, float /* angBack*/>; + BOOST_DATA_TEST_CASE(straight1, boost::unit_test::data::make<StraightsData>({ {north, 0, pi}, @@ -210,6 +216,7 @@ struct TestLinkCurve : public LinkCurve { }; using CurvesData = std::tuple<glm::vec3 /*e1*/, glm::vec3 /*ctr*/, float /*angFor*/, float /* angBack*/>; + BOOST_DATA_TEST_CASE(curve1, boost::unit_test::data::make<CurvesData>({ {north + east, east, 0, -half_pi}, diff --git a/test/test-network.cpp b/test/test-network.cpp index a8db2b6..ab0818a 100644 --- a/test/test-network.cpp +++ b/test/test-network.cpp @@ -25,8 +25,11 @@ BOOST_GLOBAL_FIXTURE(TestMainWindow); struct TestLink : public LinkStraight { TestLink(const Node::Ptr & a, const Node::Ptr & b) : TestLink {a, b, (a->pos - b->pos)} { } + TestLink(Node::Ptr a, Node::Ptr b, glm::vec2 l) : Link {{std::move(a), 0}, {std::move(b), pi}, glm::length(l)} { } + TestLink(Node::Ptr a, Node::Ptr b, float l) : Link {{std::move(a), 0}, {std::move(b), pi}, l} { } + using StraightLink = TestLink; using CurveLink = TestLink; }; diff --git a/test/test-persistence.cpp b/test/test-persistence.cpp index 38bbf2f..abb68c2 100644 --- a/test/test-persistence.cpp +++ b/test/test-persistence.cpp @@ -26,6 +26,7 @@ struct JPP { BOOST_REQUIRE(to); return to; } + // Presumably BOOST_TEST_CONTEXT is implemented as an if (...) { } throw std::logic_error("We shouldn't ever get here, but apparently we can!"); } @@ -213,6 +214,7 @@ auto const TEST_STRINGS_DECODE_ONLY = boost::unit_test::data::make<svs>({ {R"J("\u056b ARMENIAN SMALL LETTER INI")J", "ի ARMENIAN SMALL LETTER INI"}, {R"J("\u0833 SAMARITAN PUNCTUATION BAU")J", "࠳ SAMARITAN PUNCTUATION BAU"}, }); + BOOST_DATA_TEST_CASE(load_strings, TEST_STRINGS + TEST_STRINGS_DECODE_ONLY, in, exp) { std::stringstream str {in}; @@ -220,6 +222,7 @@ BOOST_DATA_TEST_CASE(load_strings, TEST_STRINGS + TEST_STRINGS_DECODE_ONLY, in, } using cpstr = std::tuple<unsigned long, std::string_view>; + BOOST_DATA_TEST_CASE(utf8_decode, boost::unit_test::data::make<cpstr>({ {9, "\t"}, @@ -296,6 +299,7 @@ BOOST_AUTO_TEST_CASE(get_default_id) { SubObject2 so; const auto id {so.getId()}; + BOOST_TEST_CONTEXT(id) { auto ptr = std::stoul(id, nullptr, 16); BOOST_CHECK_EQUAL(ptr, reinterpret_cast<decltype(ptr)>(&so)); diff --git a/test/test-render.cpp b/test/test-render.cpp index 0d384a3..b16f241 100644 --- a/test/test-render.cpp +++ b/test/test-render.cpp @@ -43,16 +43,19 @@ public: train2->bogies.front().setPosition(train2->bogies.front().position() + train2->location.position()); train2->bogies.back().setPosition(train2->bogies.back().position() + train2->location.position()); } + void content(const SceneShader & shader) const override { terrain.render(shader); brush47rvc->render(shader); } + void lights(const SceneShader &) const override { } + void shadows(const ShadowMapper & shadowMapper) const override { @@ -95,6 +98,7 @@ BOOST_AUTO_TEST_CASE(pointlight) { SceneRenderer ss {size, output}; ss.camera.setView({-10, -10, 60}, glm::normalize(glm::vec3 {1, 1, -0.5F})); + class PointLightScene : public TestScene { public: void @@ -103,6 +107,7 @@ BOOST_AUTO_TEST_CASE(pointlight) r.setAmbientLight({0.2F, 0.2F, 0.2F}); r.setDirectionalLight({0.2F, 0.2F, 0.2F}, west + down, *this); } + void lights(const SceneShader & shader) const override { @@ -113,6 +118,7 @@ BOOST_AUTO_TEST_CASE(pointlight) } } }; + const PointLightScene scene; ss.render(scene); Texture::save(outImage, "/tmp/pointlight.tga"); @@ -122,6 +128,7 @@ BOOST_AUTO_TEST_CASE(spotlight) { SceneRenderer ss {size, output}; ss.camera.setView({-10, -10, 60}, glm::normalize(glm::vec3 {1, 1, -0.5F})); + class PointLightScene : public TestScene { public: void @@ -130,6 +137,7 @@ BOOST_AUTO_TEST_CASE(spotlight) r.setAmbientLight({0.2F, 0.2F, 0.2F}); r.setDirectionalLight({0.2F, 0.2F, 0.2F}, west + down, *this); } + void lights(const SceneShader & shader) const override { @@ -139,6 +147,7 @@ BOOST_AUTO_TEST_CASE(spotlight) shader.spotLight.add({60, 50, 3}, north + east, {1.0, 1.0, 1.0}, 0.0001F, .7F); } }; + const PointLightScene scene; ss.render(scene); Texture::save(outImage, "/tmp/spotlight.tga"); diff --git a/test/test-text.cpp b/test/test-text.cpp index 629892f..166a6fa 100644 --- a/test/test-text.cpp +++ b/test/test-text.cpp @@ -36,6 +36,7 @@ struct FontTest : public Font { BOOST_TEST_DONT_PRINT_LOG_VALUE(Font::CharData); using TextureSizeTestData = std::tuple<unsigned, unsigned, unsigned>; + BOOST_DATA_TEST_CASE(fontTextureSize, boost::unit_test::data::make<unsigned>({2, 3, 10, 50, 250}), fontHeight) { auto isPowerOfTwo = [](auto x) { @@ -64,6 +65,7 @@ BOOST_AUTO_TEST_CASE(initialize_chardata) } using CharDataTest = std::tuple<decltype(get_codepoint(nullptr)), Font::CharData>; + BOOST_DATA_TEST_CASE(initialize_chardata_A, boost::unit_test::data::make<CharDataTest>({ {'A', {0, {34, 35}, {627, 0}, {-1, 35}, 32}}, diff --git a/test/testMainWindow.h b/test/testMainWindow.h index bc9c0bd..445491d 100644 --- a/test/testMainWindow.h +++ b/test/testMainWindow.h @@ -7,6 +7,7 @@ class TestMainWindow : public Window { // in the same way a real main window would always exist. public: TestMainWindow(); + void tick(TickDuration) override { diff --git a/test/testRenderOutput.h b/test/testRenderOutput.h index f5cd56b..13c380f 100644 --- a/test/testRenderOutput.h +++ b/test/testRenderOutput.h @@ -17,6 +17,7 @@ public: glRenderBuffer depth; glTexture outImage; }; + template<glm::ivec2 Size> class TestRenderOutputSize : public TestRenderOutput { public: TestRenderOutputSize() : TestRenderOutput {Size} { } diff --git a/ui/font.cpp b/ui/font.cpp index 108f905..ebd856d 100644 --- a/ui/font.cpp +++ b/ui/font.cpp @@ -14,6 +14,7 @@ #include <unicode.h> #include <util.h> #include <utility> + // IWYU pragma: no_forward_declare FT_LibraryRec_ std::string @@ -31,6 +31,7 @@ public: glm::ivec2 bearing; long advance; }; + struct FontTexture { glTexture texture; unsigned int used; diff --git a/ui/gameMainSelector.cpp b/ui/gameMainSelector.cpp index 081718d..6c6935c 100644 --- a/ui/gameMainSelector.cpp +++ b/ui/gameMainSelector.cpp @@ -15,6 +15,7 @@ #include <vector> GameMainSelector::GameMainSelector(const Camera * c, glm::vec2 size) : UIComponent {{{}, size}}, camera {c} { } + constexpr glm::vec2 TargetPos {5, 45}; void diff --git a/ui/gameMainWindow.cpp b/ui/gameMainWindow.cpp index c35c9c6..b94accd 100644 --- a/ui/gameMainWindow.cpp +++ b/ui/gameMainWindow.cpp @@ -48,6 +48,7 @@ GameMainWindow::render() const SceneRenderer::render(*this); Window::render(); } + void GameMainWindow::content(const SceneShader & shader) const { @@ -59,17 +60,20 @@ GameMainWindow::content(const SceneShader & shader) const gameState->world.apply<Renderable>(&Renderable::render, shader); uiComponents.apply<WorldOverlay>(&WorldOverlay::render, shader); } + void GameMainWindow::environment(const SceneShader & s, const SceneRenderer & r) const { // default for now SceneProvider::environment(s, r); } + void GameMainWindow::lights(const SceneShader & shader) const { gameState->world.apply<Renderable>(&Renderable::lights, shader); } + void GameMainWindow::shadows(const ShadowMapper & shadowMapper) const { diff --git a/ui/iconButton.h b/ui/iconButton.h index 6ac9317..0afe92d 100644 --- a/ui/iconButton.h +++ b/ui/iconButton.h @@ -10,6 +10,7 @@ class UIShader; union SDL_Event; static const constexpr glm::vec2 ICON_SIZE {32.F, 32.F}; + class IconButton : public UIComponent { public: IconButton(const std::string & icon, glm::vec2 position, UIEvent click); diff --git a/ui/modeHelper.h b/ui/modeHelper.h index 77707f2..d20f2db 100644 --- a/ui/modeHelper.h +++ b/ui/modeHelper.h @@ -4,6 +4,7 @@ union SDL_Event; enum ModeSecondClick { Unset, Reset, NoAction }; + template<typename Target, ModeSecondClick msc = ModeSecondClick::Unset> class Mode { public: explicit Mode(Target & t) : target {t} { } diff --git a/ui/text.cpp b/ui/text.cpp index d24c268..b776b90 100644 --- a/ui/text.cpp +++ b/ui/text.cpp @@ -12,6 +12,7 @@ #include <utility> const std::filesystem::path font {"/usr/share/fonts/hack/Hack-Regular.ttf"}; + Text::Text(std::string_view s, Position pos, glm::vec3 c) : UIComponent {pos}, colour {c} { for (const auto & textureQuads : @@ -25,6 +25,7 @@ private: glVertexArray vao; glBuffer vbo; }; + std::vector<Model> models; glm::vec3 colour; }; diff --git a/ui/uiComponent.cpp b/ui/uiComponent.cpp index e480fbc..aa4838d 100644 --- a/ui/uiComponent.cpp +++ b/ui/uiComponent.cpp @@ -20,6 +20,7 @@ UIComponent::Position::operator&(const glm::vec2 & pos) const { return (pos.x >= origin.x && pos.y >= origin.y && pos.x < origin.x + size.x && pos.y < origin.y + size.y); } + bool UIComponent::Position::operator&(const SDL_MouseButtonEvent & pos) const { diff --git a/ui/uiComponent.h b/ui/uiComponent.h index 75c2284..71d2659 100644 --- a/ui/uiComponent.h +++ b/ui/uiComponent.h @@ -18,6 +18,7 @@ public: bool operator&(const SDL_MouseButtonEvent &) const; bool operator&(const glm::vec2 &) const; }; + explicit UIComponent(Position); virtual ~UIComponent() = default; diff --git a/ui/uiComponentPlacer.cpp b/ui/uiComponentPlacer.cpp index 368e772..5e645d8 100644 --- a/ui/uiComponentPlacer.cpp +++ b/ui/uiComponentPlacer.cpp @@ -16,6 +16,7 @@ UIComponentPlacer::next(glm::vec2 size) max = std::max(max, size[1 - axis]); return n; } + glm::vec2 UIComponentPlacer::getLimit() const { diff --git a/ui/window.h b/ui/window.h index 369228a..183a65a 100644 --- a/ui/window.h +++ b/ui/window.h @@ -31,6 +31,7 @@ public: protected: virtual void render() const; + struct GLInitHelper { GLInitHelper(); }; |