diff options
-rw-r--r-- | Jamroot.jam | 1 | ||||
-rw-r--r-- | application/main.cpp | 65 | ||||
-rw-r--r-- | game/physical.cpp | 15 | ||||
-rw-r--r-- | game/physical.h | 31 | ||||
-rw-r--r-- | game/world.h | 11 | ||||
-rw-r--r-- | game/worldobject.h | 19 | ||||
-rw-r--r-- | gfx/gl/transform.h | 6 | ||||
-rw-r--r-- | gfx/models/mesh.cpp | 2 | ||||
-rw-r--r-- | gfx/models/mesh.h | 2 | ||||
-rw-r--r-- | utility/collection.hpp | 31 |
10 files changed, 157 insertions, 26 deletions
diff --git a/Jamroot.jam b/Jamroot.jam index e67a00c..38a759d 100644 --- a/Jamroot.jam +++ b/Jamroot.jam @@ -19,6 +19,7 @@ project : requirements <toolset>tidy:<checkxx>bugprone-* <toolset>tidy:<checkxx>clang-* <toolset>tidy:<checkxx>misc-* + <toolset>tidy:<xcheckxx>misc-non-private-member-variables-in-classes <toolset>tidy:<checkxx>modernize-* <toolset>tidy:<xcheckxx>modernize-use-trailing-return-type <toolset>tidy:<checkxx>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 <SDL2/SDL.h> +#include <chrono> #include <cmath> +#include <collection.hpp> +#include <game/physical.h> +#include <game/world.h> +#include <game/worldobject.h> #include <gfx/gl/camera.h> #include <gfx/gl/shader.h> #include <gfx/gl/transform.h> -#include <gfx/models/mesh.h> -#include <gfx/models/texture.h> #include <glm/glm.hpp> #include <memory> #include <numbers> @@ -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<double> + 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<Window> windows; + windows.create(DISPLAY_WIDTH, DISPLAY_HEIGHT, "OpenGL"); + + World world; + world.create<Monkey>(); - 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<double> + 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<std::chrono::milliseconds>(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>(&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 <gfx/gl/shader.h> + +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 <gfx/gl/transform.h> +#include <glm/glm.hpp> +#include <string> + +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 <collection.hpp> + +class World : public Collection<WorldObject> { +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 <chrono> +#include <special_members.hpp> + +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 <algorithm> +#include <memory> + +template<typename Object> class Collection { +public: + using Ptr = std::unique_ptr<Object>; + std::vector<Ptr> objects; + + template<typename T = Object, typename... Params> + const auto & + create(Params &&... params) + { + return objects.emplace_back(std::make_unique<T>(std::forward<Params>(params)...)); + } + + template<typename T = Object, typename M = void, typename... Params> + void + apply(const M & m, Params &&... params) const + { + std::for_each(objects.cbegin(), objects.cend(), [&m, ¶ms...](auto && op) { + if (auto o = dynamic_cast<T *>(op.get())) { + std::invoke(m, o, std::forward<Params>(params)...); + } + }); + } +}; + +#endif |