From 196f02bdbbd372b77141201f045fcfea318093b1 Mon Sep 17 00:00:00 2001 From: Daniel Karbach Date: Wed, 15 Nov 2017 22:09:46 +0100 Subject: [PATCH] basic creature model --- assets | 2 +- src/app/Assets.hpp | 5 ++ src/app/app.cpp | 29 +++++++- src/app/states.cpp | 44 ++++++++---- src/blobs.cpp | 7 ++ src/graphics/CreatureSkin.hpp | 67 ++++++++++++++++++ src/graphics/shader.cpp | 123 ++++++++++++++++++++++++++++++++++ src/world/Body.hpp | 8 +++ src/world/Creature.hpp | 61 +++++++++++++++++ src/world/Planet.hpp | 6 +- src/world/creature.cpp | 114 +++++++++++++++++++++++++++++++ src/world/world.cpp | 20 ++++-- 12 files changed, 462 insertions(+), 24 deletions(-) create mode 100644 src/graphics/CreatureSkin.hpp create mode 100644 src/world/Creature.hpp create mode 100644 src/world/creature.cpp diff --git a/assets b/assets index a8e34c5..cc06227 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit a8e34c508dc619ed8643875431baac64d88765b2 +Subproject commit cc062273ae5591bfa7910ca7fd71f23a35a3270e diff --git a/src/app/Assets.hpp b/src/app/Assets.hpp index b95ee48..4ea7f57 100644 --- a/src/app/Assets.hpp +++ b/src/app/Assets.hpp @@ -2,6 +2,7 @@ #define BLOBS_APP_ASSETS_HPP_ #include "../graphics/ArrayTexture.hpp" +#include "../graphics/CreatureSkin.hpp" #include "../graphics/PlanetSurface.hpp" #include "../graphics/SunSurface.hpp" @@ -15,14 +16,17 @@ struct Assets { std::string path; std::string tile_path; + std::string skin_path; struct { graphics::ArrayTexture tiles; + graphics::ArrayTexture skins; } textures; struct { graphics::PlanetSurface planet_surface; graphics::SunSurface sun_surface; + graphics::CreatureSkin creature_skin; } shaders; Assets(); @@ -35,6 +39,7 @@ struct Assets { Assets &operator =(Assets &&) = delete; void LoadTileTexture(const std::string &name, graphics::ArrayTexture &, int layer) const; + void LoadSkinTexture(const std::string &name, graphics::ArrayTexture &, int layer) const; }; diff --git a/src/app/app.cpp b/src/app/app.cpp index 8c0f8e1..6b8cfbf 100644 --- a/src/app/app.cpp +++ b/src/app/app.cpp @@ -167,7 +167,8 @@ void State::OnQuit() { Assets::Assets() : path("assets/") -, tile_path(path + "tiles/") { +, tile_path(path + "tiles/") +, skin_path(path + "skins/") { graphics::Format format; textures.tiles.Bind(); textures.tiles.Reserve(256, 256, 9, format); @@ -180,6 +181,17 @@ Assets::Assets() LoadTileTexture("7", textures.tiles, 6); LoadTileTexture("8", textures.tiles, 7); LoadTileTexture("9", textures.tiles, 8); + textures.skins.Bind(); + textures.skins.Reserve(256, 256, 9, format); + LoadSkinTexture("1", textures.skins, 0); + LoadSkinTexture("2", textures.skins, 1); + LoadSkinTexture("3", textures.skins, 2); + LoadSkinTexture("4", textures.skins, 3); + LoadSkinTexture("5", textures.skins, 4); + LoadSkinTexture("6", textures.skins, 5); + LoadSkinTexture("7", textures.skins, 6); + LoadSkinTexture("8", textures.skins, 7); + LoadSkinTexture("9", textures.skins, 8); } Assets::~Assets() { @@ -200,5 +212,20 @@ void Assets::LoadTileTexture(const std::string &name, graphics::ArrayTexture &te SDL_FreeSurface(srf); } +void Assets::LoadSkinTexture(const std::string &name, graphics::ArrayTexture &tex, int layer) const { + std::string path = skin_path + name + ".png"; + SDL_Surface *srf = IMG_Load(path.c_str()); + if (!srf) { + throw SDLError("IMG_Load"); + } + try { + tex.Data(layer, *srf); + } catch (...) { + SDL_FreeSurface(srf); + throw; + } + SDL_FreeSurface(srf); +} + } } diff --git a/src/app/states.cpp b/src/app/states.cpp index 86b2e82..5a9ae0a 100644 --- a/src/app/states.cpp +++ b/src/app/states.cpp @@ -1,6 +1,7 @@ #include "MasterState.hpp" #include "../world/Body.hpp" +#include "../world/Creature.hpp" #include "../world/Planet.hpp" #include "../world/Simulation.hpp" #include "../world/Sun.hpp" @@ -56,36 +57,43 @@ void MasterState::OnKeyDown(const SDL_KeyboardEvent &e) { } void MasterState::OnRender(graphics::Viewport &viewport) { - assets.shaders.planet_surface.Activate(); - assets.shaders.planet_surface.SetTexture(assets.textures.tiles); int num_lights = 0; for (auto sun : sim.Suns()) { // TODO: source sun's light color and strength - assets.shaders.planet_surface.SetLight( - num_lights, - glm::vec3(cam.View() * cam.Model(*sun)[3]), - glm::vec3(1.0f, 1.0f, 1.0f), - 1.0e6f); + glm::vec3 pos(cam.View() * cam.Model(*sun)[3]); + glm::vec3 col(1.0f, 1.0f, 1.0f); + float str = 1.0e6f; + assets.shaders.planet_surface.Activate(); + assets.shaders.planet_surface.SetLight(num_lights, pos, col, str); + assets.shaders.creature_skin.Activate(); + assets.shaders.creature_skin.SetLight(num_lights, pos, col, str); ++num_lights; - if (num_lights >= graphics::PlanetSurface::MAX_LIGHTS) { + if (num_lights >= graphics::PlanetSurface::MAX_LIGHTS || num_lights >= graphics::CreatureSkin::MAX_LIGHTS) { break; } } for (auto planet : sim.Planets()) { // TODO: indirect light from planets, calculate strength and get color somehow - assets.shaders.planet_surface.SetLight( - num_lights, - glm::vec3(cam.View() * cam.Model(*planet)[3]), - glm::vec3(1.0f, 1.0f, 1.0f), - 10.0f); + glm::vec3 pos(cam.View() * cam.Model(*planet)[3]); + glm::vec3 col(1.0f, 1.0f, 1.0f); + float str = 10.0f; + assets.shaders.planet_surface.Activate(); + assets.shaders.planet_surface.SetLight(num_lights, pos, col, str); + assets.shaders.creature_skin.Activate(); + assets.shaders.creature_skin.SetLight(num_lights, pos, col, str); ++num_lights; - if (num_lights >= graphics::PlanetSurface::MAX_LIGHTS) { + if (num_lights >= graphics::PlanetSurface::MAX_LIGHTS || num_lights >= graphics::CreatureSkin::MAX_LIGHTS) { break; } } + assets.shaders.planet_surface.Activate(); assets.shaders.planet_surface.SetNumLights(num_lights); + assets.shaders.creature_skin.Activate(); + assets.shaders.creature_skin.SetNumLights(num_lights); + assets.shaders.planet_surface.Activate(); + assets.shaders.planet_surface.SetTexture(assets.textures.tiles); for (auto planet : sim.Planets()) { assets.shaders.planet_surface.SetMVP(cam.Model(*planet), cam.View(), cam.Projection()); planet->Draw(assets, viewport); @@ -100,6 +108,14 @@ void MasterState::OnRender(graphics::Viewport &viewport) { assets.shaders.sun_surface.SetLight(glm::vec3(1.0f, 1.0f, 1.0f), 1.0e6f); assets.shaders.sun_surface.Draw(); } + + assets.shaders.creature_skin.Activate(); + assets.shaders.creature_skin.SetTexture(assets.textures.skins); + // TODO: extend to nearby bodies as well + for (auto c : cam.Reference().Creatures()) { + assets.shaders.creature_skin.SetMVP(cam.Model(c->GetBody()) * glm::mat4(c->LocalTransform()), cam.View(), cam.Projection()); + c->Draw(assets, viewport); + } } } diff --git a/src/blobs.cpp b/src/blobs.cpp index b1fb631..c09aea6 100644 --- a/src/blobs.cpp +++ b/src/blobs.cpp @@ -3,6 +3,7 @@ #include "app/Assets.hpp" #include "app/init.hpp" #include "app/MasterState.hpp" +#include "world/Creature.hpp" #include "world/Planet.hpp" #include "world/Simulation.hpp" #include "world/Sun.hpp" @@ -76,6 +77,12 @@ int main(int argc, char *argv[]) { std::cout << "moon cycle in days: " << (moon.OrbitalPeriod() / planet.RotationalPeriod()) << std::endl; std::cout << "moon cycles per year: " << (planet.OrbitalPeriod() / moon.OrbitalPeriod()) << std::endl; + auto blob = new world::Creature; + blob->BuildVAO(); + planet.AddCreature(blob); + blob->Surface(0); + blob->Position(glm::dvec3(0.0, 0.0, 0.0)); + app::MasterState state(assets, sim); state.GetCamera() .Reference(planet) diff --git a/src/graphics/CreatureSkin.hpp b/src/graphics/CreatureSkin.hpp new file mode 100644 index 0000000..78cf658 --- /dev/null +++ b/src/graphics/CreatureSkin.hpp @@ -0,0 +1,67 @@ +#ifndef BLOBS_GRAPHICS_CREATURESKIN_HPP_ +#define BLOBS_GRAPHICS_CREATURESKIN_HPP_ + +#include "Program.hpp" + +#include "glm.hpp" + + +namespace blobs { +namespace graphics { + +class ArrayTexture; + +class CreatureSkin { + +public: + static constexpr int MAX_LIGHTS = 8; + +public: + CreatureSkin(); + ~CreatureSkin(); + + CreatureSkin(const CreatureSkin &) = delete; + CreatureSkin &operator =(const CreatureSkin &) = delete; + + CreatureSkin(CreatureSkin &&) = delete; + CreatureSkin &operator =(CreatureSkin &&) = delete; + +public: + void Activate() noexcept; + + void SetMVP(const glm::mat4 &m, const glm::mat4 &v, const glm::mat4 &p) noexcept; + void SetTexture(ArrayTexture &) noexcept; + void SetLight(int n, const glm::vec3 &pos, const glm::vec3 &color, float strength) noexcept; + void SetNumLights(int n) noexcept; + + const glm::mat4 &M() const noexcept { return m; } + const glm::mat4 &V() const noexcept { return v; } + const glm::mat4 &P() const noexcept { return p; } + const glm::mat4 &MV() const noexcept { return mv; } + const glm::mat4 &MVP() const noexcept { return mvp; } + +private: + Program prog; + + int num_lights; + + glm::mat4 m; + glm::mat4 v; + glm::mat4 p; + glm::mat4 mv; + glm::mat4 mvp; + + GLuint m_handle; + GLuint mv_handle; + GLuint mvp_handle; + GLuint sampler_handle; + + GLuint num_lights_handle; + GLuint light_handle[MAX_LIGHTS * 3]; + +}; + +} +} + +#endif diff --git a/src/graphics/shader.cpp b/src/graphics/shader.cpp index 573e90c..c7b5fdd 100644 --- a/src/graphics/shader.cpp +++ b/src/graphics/shader.cpp @@ -1,3 +1,4 @@ +#include "CreatureSkin.hpp" #include "PlanetSurface.hpp" #include "Program.hpp" #include "Shader.hpp" @@ -447,5 +448,127 @@ void SunSurface::Draw() const noexcept { vao.DrawTriangles(36); } + +constexpr int CreatureSkin::MAX_LIGHTS; + +CreatureSkin::CreatureSkin() +: prog() { + prog.LoadShader( + GL_VERTEX_SHADER, + "#version 330 core\n" + + "layout(location = 0) in vec3 vtx_position;\n" + "layout(location = 1) in vec3 vtx_normal;\n" + "layout(location = 2) in vec3 vtx_tex_uv;\n" + + "uniform mat4 M;\n" + "uniform mat4 MV;\n" + "uniform mat4 MVP;\n" + + "out vec3 vtx_viewspace;\n" + "out vec3 frag_tex_uv;\n" + "out vec3 normal;\n" + + "void main() {\n" + "gl_Position = MVP * vec4(vtx_position, 1);\n" + "vtx_viewspace = (MV * vec4(vtx_position, 1)).xyz;\n" + "normal = normalize((MV * vec4(vtx_normal, 0)).xyz);\n" + "frag_tex_uv = vtx_tex_uv;\n" + "}\n" + ); + prog.LoadShader( + GL_FRAGMENT_SHADER, + "#version 330 core\n" + + "struct LightSource {\n" + "vec3 position;\n" + "vec3 color;\n" + "float strength;\n" + "};\n" + + "in vec3 vtx_viewspace;\n" + "in vec3 frag_tex_uv;\n" + "in vec3 normal;\n" + + "uniform sampler2DArray tex_sampler;\n" + "uniform int num_lights;\n" + "uniform LightSource light[8];\n" + + "out vec3 color;\n" + + "void main() {\n" + "vec3 tex_color = texture(tex_sampler, frag_tex_uv).rgb;\n" + "vec3 total_light = tex_color * vec3(0.01, 0.01, 0.01);\n" + "for (int i = 0; i < num_lights; ++i) {\n" + "vec3 to_light = light[i].position - vtx_viewspace;\n" + "float distance = length(to_light) + length(vtx_viewspace);\n" + "vec3 light_dir = normalize(to_light);\n" + "float attenuation = light[i].strength / (distance * distance);\n" + "vec3 diffuse = attenuation * max(0.0, dot(normal, light_dir)) * light[i].color * tex_color;\n" + "vec3 view_dir = vec3(0.0, 0.0, 1.0);\n" + "vec3 specular = vec3(0.0, 0.0, 0.0);\n" + "if (dot(normal, light_dir) >= 0.0) {\n" + "attenuation * light[i].color * pow(max(0.0, dot(reflect(-light_dir, normal), view_dir)), 25.0);\n" + "}\n" + "total_light = total_light + diffuse + specular;\n" + "}\n" + "color = total_light;\n" + "}\n" + ); + prog.Link(); + if (!prog.Linked()) { + prog.Log(std::cerr); + throw std::runtime_error("link program"); + } + m_handle = prog.UniformLocation("M"); + mv_handle = prog.UniformLocation("MV"); + mvp_handle = prog.UniformLocation("MVP"); + sampler_handle = prog.UniformLocation("tex_sampler"); + num_lights_handle = prog.UniformLocation("num_lights"); + for (int i = 0; i < MAX_LIGHTS; ++i) { + light_handle[3 * i + 0] = prog.UniformLocation("light[" + std::to_string(i) + "].position"); + light_handle[3 * i + 1] = prog.UniformLocation("light[" + std::to_string(i) + "].color"); + light_handle[3 * i + 2] = prog.UniformLocation("light[" + std::to_string(i) + "].strength"); + } +} + +CreatureSkin::~CreatureSkin() { +} + +void CreatureSkin::Activate() noexcept { + prog.Use(); + glEnable(GL_DEPTH_TEST); + glDepthFunc(GL_LESS); + glEnable(GL_CULL_FACE); + glDisable(GL_BLEND); +} + +void CreatureSkin::SetMVP(const glm::mat4 &mm, const glm::mat4 &vv, const glm::mat4 &pp) noexcept { + m = mm; + v = vv; + p = pp; + mv = v * m; + mvp = p * mv; + prog.Uniform(m_handle, m); + prog.Uniform(mv_handle, mv); + prog.Uniform(mvp_handle, mvp); +} + +void CreatureSkin::SetTexture(ArrayTexture &tex) noexcept { + glActiveTexture(GL_TEXTURE0); + tex.Bind(); + prog.Uniform(sampler_handle, GLint(0)); +} + +void CreatureSkin::SetLight(int n, const glm::vec3 &pos, const glm::vec3 &color, float strength) noexcept { + prog.Uniform(light_handle[3 * n + 0], pos); + prog.Uniform(light_handle[3 * n + 1], color); + prog.Uniform(light_handle[3 * n + 2], strength); +} + +void CreatureSkin::SetNumLights(int n) noexcept { + prog.Uniform(num_lights_handle, std::min(MAX_LIGHTS, n)); +} + } } diff --git a/src/world/Body.hpp b/src/world/Body.hpp index 5f82be2..fba121b 100644 --- a/src/world/Body.hpp +++ b/src/world/Body.hpp @@ -16,6 +16,7 @@ namespace graphics { } namespace world { +class Creature; class Simulation; class Body { @@ -83,6 +84,11 @@ public: void Cache() noexcept; + // body takes over ownership of given pointer + void AddCreature(Creature *); + std::vector &Creatures() noexcept { return creatures; } + const std::vector &Creatures() const noexcept { return creatures; } + private: void AddChild(Body &); void RemoveChild(Body &); @@ -104,6 +110,8 @@ private: glm::dmat4 local; glm::dmat4 inverse_local; + std::vector creatures; + }; } diff --git a/src/world/Creature.hpp b/src/world/Creature.hpp new file mode 100644 index 0000000..170d52b --- /dev/null +++ b/src/world/Creature.hpp @@ -0,0 +1,61 @@ +#ifndef BLOBS_WORLD_CREATURE_HPP_ +#define BLOBS_WORLD_CREATURE_HPP_ + +#include "../graphics/glm.hpp" +#include "../graphics/SimpleVAO.hpp" + + +namespace blobs { +namespace app { + struct Assets; +} +namespace graphics { + class Viewport; +} +namespace world { + +class Body; + +class Creature { + +public: + Creature(); + ~Creature(); + + Creature(const Creature &) = delete; + Creature &operator =(const Creature &) = delete; + + Creature(Creature &&) = delete; + Creature &operator =(Creature &&) = delete; + +public: + void SetBody(Body &b) noexcept { body = &b; } + Body &GetBody() noexcept { return *body; } + const Body &GetBody() const noexcept { return *body; } + + void Surface(int s) noexcept { surface = s; } + void Position(const glm::dvec3 &p) noexcept { position = p; } + + glm::dmat4 LocalTransform() noexcept; + + void BuildVAO(); + void Draw(app::Assets &, graphics::Viewport &); + +private: + Body *body; + int surface; + glm::dvec3 position; + + struct Attributes { + glm::vec3 position; + glm::vec3 normal; + glm::vec3 texture; + }; + graphics::SimpleVAO vao; + +}; + +} +} + +#endif diff --git a/src/world/Planet.hpp b/src/world/Planet.hpp index a95238a..900ebbb 100644 --- a/src/world/Planet.hpp +++ b/src/world/Planet.hpp @@ -8,7 +8,7 @@ #include "../graphics/SimpleVAO.hpp" #include -#include +#include #include @@ -63,12 +63,12 @@ public: glm::dvec3 TileCenter(int surface, int x, int y) const noexcept; - void BuildVAOs(const TileSet &); + void BuildVAO(const TileSet &); void Draw(app::Assets &, graphics::Viewport &) override; private: int sidelength; - std::unique_ptr tiles; + std::vector tiles; struct Attributes { glm::vec3 position; diff --git a/src/world/creature.cpp b/src/world/creature.cpp new file mode 100644 index 0000000..aa85b59 --- /dev/null +++ b/src/world/creature.cpp @@ -0,0 +1,114 @@ +#include "Creature.hpp" + +#include "Body.hpp" + +#include + + +namespace blobs { +namespace world { + +Creature::Creature() +: vao() { +} + +Creature::~Creature() { +} + + +glm::dmat4 Creature::LocalTransform() noexcept { + // TODO: surface transform + constexpr double half_height = 0.25; + return glm::translate(glm::dvec3(position.x, position.y, position.z + body->Radius() + half_height)) + * glm::scale(glm::dvec3(half_height, half_height, half_height)); +} + +void Creature::BuildVAO() { + vao.Bind(); + vao.BindAttributes(); + vao.EnableAttribute(0); + vao.EnableAttribute(1); + vao.EnableAttribute(2); + vao.AttributePointer(0, false, offsetof(Attributes, position)); + vao.AttributePointer(1, false, offsetof(Attributes, normal)); + vao.AttributePointer(2, false, offsetof(Attributes, texture)); + vao.ReserveAttributes(6 * 4, GL_STATIC_DRAW); + { + auto attrib = vao.MapAttributes(GL_WRITE_ONLY); + const float offset = 1.0f; + for (int surface = 0; surface < 6; ++surface) { + const float tex_u_begin = surface < 3 ? 1.0f : 0.0f; + const float tex_u_end = surface < 3 ? 0.0f : 1.0f; + + attrib[4 * surface + 0].position[(surface + 0) % 3] = -offset; + attrib[4 * surface + 0].position[(surface + 1) % 3] = -offset; + attrib[4 * surface + 0].position[(surface + 2) % 3] = surface < 3 ? offset : -offset; + attrib[4 * surface + 0].normal[(surface + 0) % 3] = 0.0f; + attrib[4 * surface + 0].normal[(surface + 1) % 3] = 0.0f; + attrib[4 * surface + 0].normal[(surface + 2) % 3] = surface < 3 ? 1.0f : -1.0f; + attrib[4 * surface + 0].texture.x = tex_u_begin; + attrib[4 * surface + 0].texture.y = 1.0f; + attrib[4 * surface + 0].texture.z = surface; + + attrib[4 * surface + 1].position[(surface + 0) % 3] = -offset; + attrib[4 * surface + 1].position[(surface + 1) % 3] = offset; + attrib[4 * surface + 1].position[(surface + 2) % 3] = surface < 3 ? offset : -offset; + attrib[4 * surface + 1].normal[(surface + 0) % 3] = 0.0f; + attrib[4 * surface + 1].normal[(surface + 1) % 3] = 0.0f; + attrib[4 * surface + 1].normal[(surface + 2) % 3] = surface < 3 ? 1.0f : -1.0f; + attrib[4 * surface + 1].texture.x = tex_u_end; + attrib[4 * surface + 1].texture.y = 1.0f; + attrib[4 * surface + 1].texture.z = surface; + + attrib[4 * surface + 2].position[(surface + 0) % 3] = offset; + attrib[4 * surface + 2].position[(surface + 1) % 3] = -offset; + attrib[4 * surface + 2].position[(surface + 2) % 3] = surface < 3 ? offset : -offset; + attrib[4 * surface + 2].normal[(surface + 0) % 3] = 0.0f; + attrib[4 * surface + 2].normal[(surface + 1) % 3] = 0.0f; + attrib[4 * surface + 2].normal[(surface + 2) % 3] = surface < 3 ? 1.0f : -1.0f; + attrib[4 * surface + 2].texture.x = tex_u_begin; + attrib[4 * surface + 2].texture.y = 0.0f; + attrib[4 * surface + 2].texture.z = surface; + + attrib[4 * surface + 3].position[(surface + 0) % 3] = offset; + attrib[4 * surface + 3].position[(surface + 1) % 3] = offset; + attrib[4 * surface + 3].position[(surface + 2) % 3] = surface < 3 ? offset : -offset; + attrib[4 * surface + 3].normal[(surface + 0) % 3] = 0.0f; + attrib[4 * surface + 3].normal[(surface + 1) % 3] = 0.0f; + attrib[4 * surface + 3].normal[(surface + 2) % 3] = surface < 3 ? 1.0f : -1.0f; + attrib[4 * surface + 3].texture.x = tex_u_end; + attrib[4 * surface + 3].texture.y = 0.0f; + attrib[4 * surface + 3].texture.z = surface; + } + } + vao.BindElements(); + vao.ReserveElements(6 * 6, GL_STATIC_DRAW); + { + auto element = vao.MapElements(GL_WRITE_ONLY); + for (int surface = 0; surface < 3; ++surface) { + element[6 * surface + 0] = 4 * surface + 0; + element[6 * surface + 1] = 4 * surface + 2; + element[6 * surface + 2] = 4 * surface + 1; + element[6 * surface + 3] = 4 * surface + 1; + element[6 * surface + 4] = 4 * surface + 2; + element[6 * surface + 5] = 4 * surface + 3; + } + for (int surface = 3; surface < 6; ++surface) { + element[6 * surface + 0] = 4 * surface + 0; + element[6 * surface + 1] = 4 * surface + 1; + element[6 * surface + 2] = 4 * surface + 2; + element[6 * surface + 3] = 4 * surface + 2; + element[6 * surface + 4] = 4 * surface + 1; + element[6 * surface + 5] = 4 * surface + 3; + } + } + vao.Unbind(); +} + +void Creature::Draw(app::Assets &assets, graphics::Viewport &viewport) { + vao.Bind(); + vao.DrawTriangles(6 * 6); +} + +} +} diff --git a/src/world/world.cpp b/src/world/world.cpp index a939b3e..fb57c7c 100644 --- a/src/world/world.cpp +++ b/src/world/world.cpp @@ -7,6 +7,7 @@ #include "TileSet.hpp" #include "TileType.hpp" +#include "Creature.hpp" #include "../const.hpp" #include "../app/Assets.hpp" #include "../graphics/Viewport.hpp" @@ -47,10 +48,14 @@ Body::Body() , orbital(1.0) , inverse_orbital(1.0) , local(1.0) -, inverse_local(1.0) { +, inverse_local(1.0) +, creatures() { } Body::~Body() { + for (Creature *c : creatures) { + delete c; + } } void Body::SetSimulation(Simulation &s) noexcept { @@ -151,6 +156,11 @@ void Body::Cache() noexcept { * glm::eulerAngleY(-rotation); } +void Body::AddCreature(Creature *c) { + c->SetBody(*this); + creatures.push_back(c); +} + Orbit::Orbit() : sma(1.0) @@ -256,7 +266,7 @@ glm::dmat4 Orbit::InverseMatrix(double t) const noexcept { Planet::Planet(int sidelength) : Body() , sidelength(sidelength) -, tiles(new Tile[TilesTotal()]) +, tiles(TilesTotal()) , vao() { Radius(double(sidelength) / 2.0); } @@ -272,7 +282,7 @@ glm::dvec3 Planet::TileCenter(int surface, int x, int y) const noexcept { return center; } -void Planet::BuildVAOs(const TileSet &ts) { +void Planet::BuildVAO(const TileSet &ts) { vao.Bind(); vao.BindAttributes(); vao.EnableAttribute(0); @@ -421,7 +431,7 @@ void GenerateEarthlike(const TileSet &tiles, Planet &p) noexcept { } } } - p.BuildVAOs(tiles); + p.BuildVAO(tiles); } void GenerateTest(const TileSet &tiles, Planet &p) noexcept { @@ -436,7 +446,7 @@ void GenerateTest(const TileSet &tiles, Planet &p) noexcept { } } } - p.BuildVAOs(tiles); + p.BuildVAO(tiles); } -- 2.39.2