From 627aa88ad2559f41d5be62d36cdbf536a97e4246 Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Mon, 18 Jan 2021 02:08:01 +0000 Subject: Factor to support worlds, objects, windows etc --- Jamroot.jam | 1 + application/main.cpp | 65 +++++++++++++++++++++++++++++++------------------- game/physical.cpp | 15 ++++++++++++ game/physical.h | 31 ++++++++++++++++++++++++ game/world.h | 11 +++++++++ game/worldobject.h | 19 +++++++++++++++ gfx/gl/transform.h | 6 +++++ gfx/models/mesh.cpp | 2 +- gfx/models/mesh.h | 2 +- utility/collection.hpp | 31 ++++++++++++++++++++++++ 10 files changed, 157 insertions(+), 26 deletions(-) create mode 100644 game/physical.cpp create mode 100644 game/physical.h create mode 100644 game/world.h create mode 100644 game/worldobject.h create mode 100644 utility/collection.hpp diff --git a/Jamroot.jam b/Jamroot.jam index e67a00c..38a759d 100644 --- a/Jamroot.jam +++ b/Jamroot.jam @@ -19,6 +19,7 @@ project : requirements tidy:bugprone-* tidy:clang-* tidy:misc-* + tidy:misc-non-private-member-variables-in-classes tidy:modernize-* tidy:modernize-use-trailing-return-type tidy:hicpp-* diff --git a/application/main.cpp b/application/main.cpp index acf3c95..73f337b 100644 --- a/application/main.cpp +++ b/application/main.cpp @@ -1,11 +1,14 @@ #include "gfx/window.h" #include +#include #include +#include +#include +#include +#include #include #include #include -#include -#include #include #include #include @@ -14,6 +17,22 @@ static const int DISPLAY_WIDTH = 800; static const int DISPLAY_HEIGHT = 600; +class Monkey : public WorldObject, public Physical { +public: + Monkey() : Physical {{}, "res/monkey3.obj", "res/bricks.jpg"} { } + + void + tick(TickDuration elapsed) override + { + counter += 0.000625F * elapsed.count(); + location.GetRot().y = std::numbers::pi_v + sin(counter); + location.GetRot().z = 0.3 * cos(counter * 10); + } + +private: + float counter {}; +}; + class SDL_Application { public: SDL_Application() @@ -38,17 +57,21 @@ public: void run() { - Window main_window(DISPLAY_WIDTH, DISPLAY_HEIGHT, "OpenGL"); + Collection windows; + windows.create(DISPLAY_WIDTH, DISPLAY_HEIGHT, "OpenGL"); + + World world; + world.create(); - Mesh monkey("./res/monkey3.obj"); Shader shader("./res/basicShader"); - Texture texture("./res/bricks.jpg"); - Transform transform; - Camera camera(glm::vec3(0.0F, 0.0F, -5.0F), 70.0F, (float)DISPLAY_WIDTH / (float)DISPLAY_HEIGHT, 0.1F, 100.0F); + Camera camera({0.0F, 0.0F, -5.0F}, 70.0F, (float)DISPLAY_WIDTH / (float)DISPLAY_HEIGHT, 0.1F, 100.0F); SDL_Event e; bool isRunning = true; - float counter = 0.0F; + + auto t_start = std::chrono::high_resolution_clock::now(); + const auto framelen = std::chrono::milliseconds {1000} / 120; + while (isRunning) { while (SDL_PollEvent(&e)) { if (e.type == SDL_QUIT) { @@ -56,25 +79,19 @@ public: } } - main_window.Clear(0.0F, 0.0F, 0.0F, 1.0F); - - // float sinCounter = sinf(counter); - // float absSinCounter = abs(sinCounter); - - // transform.GetPos()->x = sinCounter; - transform.GetRot().y = std::numbers::pi_v + sin(counter); - transform.GetRot().z = 0.3 * cos(counter * 10); - // transform.GetScale()->x = absSinCounter; - // transform.GetScale()->y = absSinCounter; + const auto t_end = std::chrono::high_resolution_clock::now(); + const auto t_passed = std::chrono::duration_cast(t_end - t_start); + world.apply(&WorldObject::tick, t_passed); + windows.apply(&Window::Clear, 0.0F, 0.0F, 0.0F, 1.0F); shader.Bind(); - texture.Bind(); - shader.Update(transform, camera); - monkey.Draw(); + world.apply(&Physical::render, shader, camera); + windows.apply(&Window::SwapBuffers); - main_window.SwapBuffers(); - SDL_Delay(1); - counter += 0.01F; + if (const auto snz = framelen - t_passed; snz.count() > 0) { + SDL_Delay(snz.count()); + } + t_start = t_end; } } }; diff --git a/game/physical.cpp b/game/physical.cpp new file mode 100644 index 0000000..f4c17d4 --- /dev/null +++ b/game/physical.cpp @@ -0,0 +1,15 @@ +#include "physical.h" +#include + +Physical::Physical(glm::vec3 where, const std::string & m, const std::string & t) : + location {where}, mesh {m}, texture {t} +{ +} + +void +Physical::render(const Shader & shader, const Camera & camera) const +{ + shader.Update(location, camera); + texture.Bind(); + mesh.Draw(); +} diff --git a/game/physical.h b/game/physical.h new file mode 100644 index 0000000..ff9d316 --- /dev/null +++ b/game/physical.h @@ -0,0 +1,31 @@ +#ifndef PHYSICAL_H +#define PHYSICAL_H + +#include "gfx/models/mesh.h" +#include "gfx/models/texture.h" +#include +#include +#include + +class Camera; +class Shader; + +class Physical { +public: + Physical(glm::vec3 where, const std::string & m, const std::string & t); + + void render(const Shader & shader, const Camera & camera) const; + + [[nodiscard]] const auto & + getPosition() const + { + return location.GetPos(); + } + +protected: + Transform location; + Mesh mesh; + Texture texture; +}; + +#endif diff --git a/game/world.h b/game/world.h new file mode 100644 index 0000000..a0185e7 --- /dev/null +++ b/game/world.h @@ -0,0 +1,11 @@ +#ifndef WORLD_H +#define WORLD_H + +#include "worldobject.h" +#include + +class World : public Collection { +public: +}; + +#endif diff --git a/game/worldobject.h b/game/worldobject.h new file mode 100644 index 0000000..6c75b8a --- /dev/null +++ b/game/worldobject.h @@ -0,0 +1,19 @@ +#ifndef WORLDOBJECT_H +#define WORLDOBJECT_H + +#include +#include + +class WorldObject { +public: + using TickDuration = std::chrono::milliseconds; + + WorldObject() = default; + virtual ~WorldObject() = default; + NO_COPY(WorldObject); + NO_MOVE(WorldObject); + + virtual void tick(TickDuration elapsed) = 0; +}; + +#endif diff --git a/gfx/gl/transform.h b/gfx/gl/transform.h index 07040ae..70fe38f 100644 --- a/gfx/gl/transform.h +++ b/gfx/gl/transform.h @@ -19,6 +19,12 @@ public: return pos; } + [[nodiscard]] inline const glm::vec3 & + GetPos() const + { + return pos; + } + [[nodiscard]] inline glm::vec3 & GetRot() { diff --git a/gfx/models/mesh.cpp b/gfx/models/mesh.cpp index 8c304b3..df48e8d 100644 --- a/gfx/models/mesh.cpp +++ b/gfx/models/mesh.cpp @@ -65,7 +65,7 @@ Mesh::~Mesh() } void -Mesh::Draw() +Mesh::Draw() const { glBindVertexArray(m_vertexArrayObject); diff --git a/gfx/models/mesh.h b/gfx/models/mesh.h index 453e54a..6dc5c32 100644 --- a/gfx/models/mesh.h +++ b/gfx/models/mesh.h @@ -22,7 +22,7 @@ public: NO_COPY(Mesh); NO_MOVE(Mesh); - void Draw(); + void Draw() const; private: static constexpr unsigned int NUM_BUFFERS {4}; diff --git a/utility/collection.hpp b/utility/collection.hpp new file mode 100644 index 0000000..1422a84 --- /dev/null +++ b/utility/collection.hpp @@ -0,0 +1,31 @@ +#ifndef COLLECTION_H +#define COLLECTION_H + +#include +#include + +template class Collection { +public: + using Ptr = std::unique_ptr; + std::vector objects; + + template + const auto & + create(Params &&... params) + { + return objects.emplace_back(std::make_unique(std::forward(params)...)); + } + + template + void + apply(const M & m, Params &&... params) const + { + std::for_each(objects.cbegin(), objects.cend(), [&m, ¶ms...](auto && op) { + if (auto o = dynamic_cast(op.get())) { + std::invoke(m, o, std::forward(params)...); + } + }); + } +}; + +#endif -- cgit v1.2.3