mirror of
https://github.com/bailwillharr/engine.git
synced 2024-09-21 04:51:18 +00:00
Get ecs to a somewhat functional state
This commit is contained in:
parent
1e06df5dc2
commit
2f880981ac
@ -15,7 +15,7 @@ set(SRC_FILES
|
||||
"src/input_manager.cpp"
|
||||
"src/scene_manager.cpp"
|
||||
|
||||
"src/texture.cpp"
|
||||
"src/resources/texture.cpp"
|
||||
|
||||
"src/gfx_device_vulkan.cpp"
|
||||
|
||||
@ -38,13 +38,14 @@ set(INCLUDE_FILES
|
||||
"include/scene_manager.hpp"
|
||||
|
||||
"include/resource_manager.hpp"
|
||||
"include/texture.hpp"
|
||||
"include/resources/texture.hpp"
|
||||
|
||||
"include/gfx.hpp"
|
||||
"include/gfx_device.hpp"
|
||||
|
||||
"include/scene.hpp"
|
||||
"include/ecs_system.hpp"
|
||||
"include/ecs/ecs_system.hpp"
|
||||
"include/ecs/mesh_renderer.hpp"
|
||||
|
||||
"include/util/files.hpp"
|
||||
)
|
||||
|
@ -1,6 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <filesystem>
|
||||
|
||||
namespace engine {
|
||||
|
||||
@ -26,12 +28,16 @@ namespace engine {
|
||||
InputManager* inputManager() { return m_inputManager.get(); }
|
||||
SceneManager* sceneManager() { return m_sceneManager.get(); }
|
||||
|
||||
std::string getResourcePath(const std::string relativePath) { return (m_resourcesPath / relativePath).string(); }
|
||||
|
||||
private:
|
||||
std::unique_ptr<Window> m_window;
|
||||
std::unique_ptr<GFXDevice> m_gfx;
|
||||
std::unique_ptr<InputManager> m_inputManager;
|
||||
std::unique_ptr<SceneManager> m_sceneManager;
|
||||
|
||||
std::filesystem::path m_resourcesPath;
|
||||
|
||||
};
|
||||
|
||||
}
|
@ -1,9 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
namespace engine::components {
|
||||
|
||||
struct MeshRenderer {
|
||||
int placeholder;
|
||||
};
|
||||
|
||||
}
|
@ -3,10 +3,10 @@
|
||||
#include <map>
|
||||
#include <memory>
|
||||
|
||||
namespace engine::ecs {
|
||||
namespace engine {
|
||||
|
||||
template <class T>
|
||||
class System {
|
||||
class EcsSystem {
|
||||
|
||||
public:
|
||||
std::map<uint32_t, T> m_components{};
|
29
include/ecs/mesh_renderer.hpp
Normal file
29
include/ecs/mesh_renderer.hpp
Normal file
@ -0,0 +1,29 @@
|
||||
#pragma once
|
||||
|
||||
#include "ecs_system.hpp"
|
||||
|
||||
#include "resources/texture.hpp"
|
||||
#include "log.hpp"
|
||||
|
||||
namespace engine::ecs {
|
||||
|
||||
struct MeshRendererComponent {
|
||||
int number;
|
||||
const resources::Texture* texture;
|
||||
};
|
||||
|
||||
class RendererSystem : public EcsSystem<MeshRendererComponent> {
|
||||
|
||||
public:
|
||||
void onUpdate(float ts) override
|
||||
{
|
||||
for (const auto& [id, data] : m_components) {
|
||||
DEBUG("rendering entity {}\tts={}", id, ts);
|
||||
DEBUG(" with texture: {}, number = {}", (void*)data.texture, data.number);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
}
|
@ -16,32 +16,27 @@ namespace engine {
|
||||
ResourceManager(const ResourceManager&) = delete;
|
||||
ResourceManager& operator=(const ResourceManager&) = delete;
|
||||
|
||||
std::shared_ptr<T> add(const std::string& name, std::unique_ptr<T>&& resource)
|
||||
T* add(const std::string& name, std::unique_ptr<T>&& resource)
|
||||
{
|
||||
if (m_resources.contains(name) == false) {
|
||||
std::shared_ptr<T> ptr = std::move(resource);
|
||||
m_resources.emplace(name, ptr);
|
||||
m_resources.emplace(name, std::move(resource));
|
||||
}
|
||||
else {
|
||||
throw std::runtime_error("Cannot add a resource which already exists");
|
||||
}
|
||||
return m_resources.at(name).lock();
|
||||
return m_resources.at(name).get();
|
||||
}
|
||||
|
||||
std::shared_ptr<T> get(const std::string& name)
|
||||
T* get(const std::string& name)
|
||||
{
|
||||
if (m_resources.contains(name)) {
|
||||
std::weak_ptr<T> resource = m_resources.at(name);
|
||||
if (resource.expired() == false) {
|
||||
return resource.lock();
|
||||
}
|
||||
return m_resources.at(name).get();
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
private:
|
||||
// weak ptrs are used to check a resource's use count. If the use count of a resource hits 0, the resource can safely be deleted.
|
||||
std::unordered_map<std::string, std::weak_ptr<T>> m_resources{};
|
||||
std::unordered_map<std::string, std::unique_ptr<T>> m_resources{};
|
||||
|
||||
};
|
||||
|
||||
|
22
include/resources/texture.hpp
Normal file
22
include/resources/texture.hpp
Normal file
@ -0,0 +1,22 @@
|
||||
#pragma once
|
||||
|
||||
#include "gfx_device.hpp"
|
||||
|
||||
namespace engine::resources {
|
||||
|
||||
class Texture {
|
||||
|
||||
public:
|
||||
Texture(GFXDevice* gfxDevice, const std::string& path);
|
||||
~Texture();
|
||||
Texture(const Texture&) = delete;
|
||||
Texture& operator=(const Texture&) = delete;
|
||||
|
||||
gfx::Texture* getHandle();
|
||||
|
||||
private:
|
||||
GFXDevice* m_gfxDevice;
|
||||
gfx::Texture* m_gpuTexture;
|
||||
};
|
||||
|
||||
}
|
@ -1,7 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include "ecs_system.hpp"
|
||||
#include "components/mesh_renderer.hpp"
|
||||
#include "ecs/mesh_renderer.hpp"
|
||||
|
||||
#include "log.hpp"
|
||||
|
||||
@ -9,17 +8,6 @@
|
||||
|
||||
namespace engine {
|
||||
|
||||
class RendererSystem : public ecs::System<components::MeshRenderer> {
|
||||
|
||||
public:
|
||||
void onUpdate(float ts) override
|
||||
{
|
||||
for (const auto& [id, data] : m_components) {
|
||||
DEBUG("rendering entity {}\tts={}", id, ts);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
class Scene {
|
||||
|
||||
public:
|
||||
@ -35,7 +23,7 @@ namespace engine {
|
||||
return m_nextEntityID++;
|
||||
}
|
||||
|
||||
std::unique_ptr<RendererSystem> m_renderSystem;
|
||||
std::unique_ptr<ecs::RendererSystem> m_renderSystem;
|
||||
|
||||
private:
|
||||
uint32_t m_nextEntityID = 1000;
|
||||
|
@ -8,6 +8,9 @@
|
||||
namespace engine {
|
||||
|
||||
class Scene; // "scene.hpp"
|
||||
namespace resources {
|
||||
class Texture;
|
||||
}
|
||||
|
||||
class SceneManager {
|
||||
|
||||
@ -21,11 +24,14 @@ namespace engine {
|
||||
|
||||
void updateActiveScene(float ts);
|
||||
|
||||
/* getters */
|
||||
ResourceManager<resources::Texture>* getTextureManager() { return m_textureManager.get(); }
|
||||
|
||||
private:
|
||||
std::vector<std::unique_ptr<Scene>> m_scenes;
|
||||
int m_activeSceneIndex = -1;
|
||||
|
||||
// const std::unique_ptr<ResourceManager<Texture>> m_textureManager;
|
||||
std::unique_ptr<ResourceManager<resources::Texture>> m_textureManager;
|
||||
|
||||
};
|
||||
|
||||
|
@ -1,25 +0,0 @@
|
||||
#if 0
|
||||
#pragma once
|
||||
|
||||
#include "engine_api.h"
|
||||
|
||||
#include "resource.hpp"
|
||||
|
||||
#include "gfx_device.hpp"
|
||||
|
||||
namespace engine::resources {
|
||||
|
||||
class ENGINE_API Texture : public Resource {
|
||||
|
||||
public:
|
||||
Texture(const std::filesystem::path& resPath);
|
||||
~Texture() override;
|
||||
|
||||
gfx::Texture* getHandle();
|
||||
|
||||
private:
|
||||
gfx::Texture* m_gpuTexture;
|
||||
};
|
||||
|
||||
}
|
||||
#endif
|
@ -8,5 +8,6 @@ namespace engine::util {
|
||||
|
||||
std::unique_ptr<std::vector<char>> readTextFile(const std::string& path);
|
||||
std::unique_ptr<std::vector<uint8_t>> readBinaryFile(const std::string& path);
|
||||
std::unique_ptr<std::vector<uint8_t>> readImageFile(const std::string& path, int *width, int *height);
|
||||
|
||||
}
|
||||
|
@ -12,6 +12,43 @@
|
||||
// To allow the FPS-limiter to put the thread to sleep
|
||||
#include <thread>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#include <windows.h>
|
||||
#include <direct.h>
|
||||
#define MAX_PATH 260
|
||||
#endif
|
||||
|
||||
static std::filesystem::path getResourcesPath()
|
||||
{
|
||||
std::filesystem::path resourcesPath{};
|
||||
|
||||
#ifdef _MSC_VER
|
||||
CHAR exeDirBuf[MAX_PATH + 1];
|
||||
GetModuleFileNameA(NULL, exeDirBuf, MAX_PATH + 1);
|
||||
std::filesystem::path cwd = std::filesystem::path(exeDirBuf).parent_path();
|
||||
(void)_chdir((const char*)std::filesystem::absolute(cwd).c_str());
|
||||
#else
|
||||
std::filesystem::path cwd = std::filesystem::current_path();
|
||||
#endif
|
||||
|
||||
if (std::filesystem::is_directory(cwd / "res")) {
|
||||
resourcesPath = cwd / "res";
|
||||
}
|
||||
else {
|
||||
resourcesPath = cwd.parent_path() / "share" / "sdltest";
|
||||
}
|
||||
|
||||
if (std::filesystem::is_directory(resourcesPath) == false) {
|
||||
resourcesPath = cwd.root_path() / "usr" / "local" / "share" / "sdltest";
|
||||
}
|
||||
|
||||
if (std::filesystem::is_directory(resourcesPath) == false) {
|
||||
throw std::runtime_error("Unable to determine resources location. CWD: " + cwd.string());
|
||||
}
|
||||
|
||||
return resourcesPath;
|
||||
}
|
||||
|
||||
namespace engine {
|
||||
|
||||
Application::Application(const char* appName, const char* appVersion)
|
||||
@ -20,6 +57,9 @@ namespace engine {
|
||||
m_gfx = std::make_unique<GFXDevice>(appName, appVersion, m_window->getHandle());
|
||||
m_inputManager = std::make_unique<InputManager>(window());
|
||||
m_sceneManager = std::make_unique<SceneManager>();
|
||||
|
||||
// get base path for resources
|
||||
m_resourcesPath = getResourcesPath();
|
||||
}
|
||||
|
||||
Application::~Application() {}
|
||||
|
38
src/resources/texture.cpp
Normal file
38
src/resources/texture.cpp
Normal file
@ -0,0 +1,38 @@
|
||||
#include "resources/texture.hpp"
|
||||
|
||||
#include "util/files.hpp"
|
||||
#include "log.hpp"
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace engine::resources {
|
||||
|
||||
Texture::Texture(GFXDevice* gfxDevice, const std::string& path)
|
||||
: m_gfxDevice(gfxDevice)
|
||||
{
|
||||
|
||||
int width, height;
|
||||
auto texbuf = util::readImageFile(path, &width, &height);
|
||||
|
||||
gfx::TextureFilter filter = gfx::TextureFilter::LINEAR;
|
||||
if (width <= 8 || height <= 8) {
|
||||
filter = gfx::TextureFilter::NEAREST;
|
||||
}
|
||||
|
||||
m_gpuTexture = m_gfxDevice->createTexture(texbuf->data(), (uint32_t)width, (uint32_t)height, gfx::TextureFilter::LINEAR, filter);
|
||||
|
||||
DEBUG("loaded texture {}, width: {} height: {} size: {}", path, width, height, texbuf->size());
|
||||
|
||||
}
|
||||
|
||||
Texture::~Texture()
|
||||
{
|
||||
m_gfxDevice->destroyTexture(m_gpuTexture);
|
||||
}
|
||||
|
||||
gfx::Texture* Texture::getHandle()
|
||||
{
|
||||
return m_gpuTexture;
|
||||
}
|
||||
|
||||
}
|
@ -1,12 +1,10 @@
|
||||
#include "scene.hpp"
|
||||
|
||||
#include "components/mesh_renderer.hpp"
|
||||
|
||||
namespace engine {
|
||||
|
||||
Scene::Scene()
|
||||
{
|
||||
m_renderSystem = std::make_unique<RendererSystem>();
|
||||
m_renderSystem = std::make_unique<ecs::RendererSystem>();
|
||||
}
|
||||
|
||||
Scene::~Scene() {}
|
||||
|
@ -1,7 +1,7 @@
|
||||
#include "scene_manager.hpp"
|
||||
|
||||
#include "scene.hpp"
|
||||
#include "log.hpp"
|
||||
#include "resources/texture.hpp"
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
@ -9,6 +9,7 @@ namespace engine {
|
||||
|
||||
SceneManager::SceneManager()
|
||||
{
|
||||
m_textureManager = std::make_unique<ResourceManager<resources::Texture>>();
|
||||
}
|
||||
|
||||
SceneManager::~SceneManager() {}
|
||||
|
122
src/texture.cpp
122
src/texture.cpp
@ -1,122 +0,0 @@
|
||||
#if 0
|
||||
|
||||
#include "resources/texture.hpp"
|
||||
|
||||
#define STB_IMAGE_IMPLEMENTATION
|
||||
#include "stb_image.h"
|
||||
|
||||
#include <log.hpp>
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace engine::resources {
|
||||
|
||||
// returns false if unable to open file
|
||||
static bool readPNG(const std::string& path, std::vector<uint8_t>* texbuf, int *width, int *height, bool *isRGBA)
|
||||
{
|
||||
int x, y, n;
|
||||
unsigned char *data = stbi_load(path.c_str(), &x, &y, &n, STBI_rgb_alpha);
|
||||
|
||||
|
||||
if (data == nullptr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const size_t size = (size_t)x * (size_t)y * 4;
|
||||
|
||||
texbuf->resize(size);
|
||||
memcpy(texbuf->data(), data, size);
|
||||
|
||||
*width = x;
|
||||
*height = y;
|
||||
*isRGBA = true;
|
||||
|
||||
stbi_image_free(data);
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
static bool readGLRaw(const std::string& path, std::vector<uint8_t>* texbuf, int *width, int *height, bool *isRGBA)
|
||||
{
|
||||
FILE *fp = fopen(path.c_str(), "rb");
|
||||
if (!fp) {
|
||||
return false;
|
||||
}
|
||||
|
||||
fseek(fp, 0x02, SEEK_SET);
|
||||
uint64_t tex_data_offset;
|
||||
fread(&tex_data_offset, sizeof(uint64_t), 1, fp);
|
||||
|
||||
fseek(fp, 0L, SEEK_END);
|
||||
uint64_t end = ftell(fp);
|
||||
|
||||
texbuf->resize(end);
|
||||
fseek(fp, (long)tex_data_offset, SEEK_SET);
|
||||
fread(texbuf->data(), 1, end, fp);
|
||||
|
||||
fclose(fp);
|
||||
|
||||
*width = 4096;
|
||||
*height = 4096;
|
||||
*isRGBA = false;
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
Texture::Texture(const std::filesystem::path& originalResPath) : Resource(originalResPath, "texture")
|
||||
{
|
||||
|
||||
std::string resString = originalResPath.string();
|
||||
bool flipV = false;
|
||||
if (resString.back() == '_') {
|
||||
flipV = true;
|
||||
resString.pop_back();
|
||||
}
|
||||
|
||||
std::filesystem::path resPath{ resString };
|
||||
|
||||
auto texbuf = std::make_unique<std::vector<uint8_t>>();
|
||||
|
||||
int width, height;
|
||||
bool isRGBA, success;
|
||||
|
||||
if (resPath.extension() == ".png" || resPath.extension() == ".jpg") {
|
||||
success = readPNG(resPath.string(), texbuf.get(), &width, &height, &isRGBA);
|
||||
} else {
|
||||
success = readGLRaw(resPath.string(), texbuf.get(), &width, &height, &isRGBA);
|
||||
}
|
||||
|
||||
if (!success) {
|
||||
throw std::runtime_error("Unable to open texture: " + resPath.string());
|
||||
}
|
||||
|
||||
if (isRGBA == false) {
|
||||
throw std::runtime_error("Currently, only RGBA textures are supported. Size: " + std::to_string(texbuf->size()));
|
||||
}
|
||||
|
||||
gfx::TextureFilter filter = gfx::TextureFilter::LINEAR;
|
||||
if (width <= 8 || height <= 8) {
|
||||
filter = gfx::TextureFilter::NEAREST;
|
||||
}
|
||||
|
||||
m_gpuTexture = gfxdev->createTexture(texbuf->data(), (uint32_t)width, (uint32_t)height, gfx::TextureFilter::LINEAR, filter);
|
||||
|
||||
DEBUG("loaded texture {} width: {} height: {} size: {}", resPath.filename().string(), width, height, texbuf->size());
|
||||
|
||||
}
|
||||
|
||||
Texture::~Texture()
|
||||
{
|
||||
gfxdev->destroyTexture(m_gpuTexture);
|
||||
}
|
||||
|
||||
gfx::Texture* Texture::getHandle()
|
||||
{
|
||||
return m_gpuTexture;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
@ -1,5 +1,8 @@
|
||||
#include "util/files.hpp"
|
||||
|
||||
#define STB_IMAGE_IMPLEMENTATION
|
||||
#include "stb_image.h"
|
||||
|
||||
#include <fstream>
|
||||
|
||||
namespace engine::util {
|
||||
@ -48,5 +51,28 @@ namespace engine::util {
|
||||
return buffer;
|
||||
}
|
||||
|
||||
// returns false if unable to open file
|
||||
std::unique_ptr<std::vector<uint8_t>> readImageFile(const std::string& path, int *width, int *height)
|
||||
{
|
||||
int x, y, n;
|
||||
unsigned char *data = stbi_load(path.c_str(), &x, &y, &n, STBI_rgb_alpha);
|
||||
|
||||
if (data == nullptr) {
|
||||
throw std::runtime_error("Unable to open file " + path);
|
||||
}
|
||||
|
||||
const size_t size = (size_t)x * (size_t)y * 4;
|
||||
|
||||
auto buffer = std::make_unique<std::vector<uint8_t>>(size);
|
||||
memcpy(buffer->data(), data, buffer->size());
|
||||
|
||||
*width = x;
|
||||
*height = y;
|
||||
|
||||
stbi_image_free(data);
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
#include "window.hpp"
|
||||
#include "scene_manager.hpp"
|
||||
#include "scene.hpp"
|
||||
#include "components/mesh_renderer.hpp"
|
||||
#include "ecs/mesh_renderer.hpp"
|
||||
|
||||
void playGame()
|
||||
{
|
||||
@ -17,7 +17,16 @@ void playGame()
|
||||
|
||||
auto entity1 = myScene->createEntity();
|
||||
|
||||
myScene->m_renderSystem->m_components.emplace(entity1, engine::components::MeshRenderer());
|
||||
auto myTexture = std::make_unique<engine::resources::Texture>(app.gfx(), app.getResourcePath("textures/grass.jpg"));
|
||||
|
||||
app.sceneManager()->getTextureManager()->add("GRASS", std::move(myTexture));
|
||||
myScene->m_renderSystem->m_components.emplace(
|
||||
entity1,
|
||||
engine::ecs::MeshRendererComponent{
|
||||
.number = 69,
|
||||
.texture = app.sceneManager()->getTextureManager()->get("GRASS"),
|
||||
}
|
||||
);
|
||||
|
||||
app.sceneManager()->createScene(std::move(myScene));
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user