mirror of
https://github.com/bailwillharr/engine.git
synced 2024-09-21 04:51:18 +00:00
Remove stuff to rewrite
This commit is contained in:
parent
60d1452f01
commit
a278b7d035
@ -1,85 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "engine_api.h"
|
|
||||||
|
|
||||||
#include "resources/resource.hpp"
|
|
||||||
|
|
||||||
#include <vector>
|
|
||||||
#include <unordered_map>
|
|
||||||
|
|
||||||
// Doesn't own resources, only holds weak_ptrs
|
|
||||||
|
|
||||||
namespace engine {
|
|
||||||
|
|
||||||
class ENGINE_API ResourceManager {
|
|
||||||
|
|
||||||
public:
|
|
||||||
ResourceManager();
|
|
||||||
ResourceManager(const ResourceManager&) = delete;
|
|
||||||
ResourceManager& operator=(const ResourceManager&) = delete;
|
|
||||||
~ResourceManager() = default;
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
std::shared_ptr<T> create(const std::string& name);
|
|
||||||
|
|
||||||
// creates the resource if it is not in the map or the weak_ptr has expired
|
|
||||||
template <class T>
|
|
||||||
std::shared_ptr<T> get(const std::string& name);
|
|
||||||
|
|
||||||
std::unique_ptr<std::string> getResourcesListString();
|
|
||||||
|
|
||||||
std::vector<std::weak_ptr<Resource>> getAllResourcesOfType(const std::string& type);
|
|
||||||
|
|
||||||
std::filesystem::path getFilePath(const std::string& name);
|
|
||||||
|
|
||||||
private:
|
|
||||||
std::filesystem::path m_resourcesPath;
|
|
||||||
std::unordered_map<std::string, std::weak_ptr<Resource>> m_resources;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
std::shared_ptr<T> ResourceManager::create(const std::string& name)
|
|
||||||
{
|
|
||||||
if (std::is_base_of<Resource, T>::value == false) {
|
|
||||||
throw std::runtime_error("ResourceManager::create() error: specified type is not a subclass of 'Resource'");
|
|
||||||
}
|
|
||||||
auto resource = std::make_shared<T>(getFilePath(name));
|
|
||||||
m_resources.emplace(name, std::dynamic_pointer_cast<Resource>(resource));
|
|
||||||
return resource;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
std::shared_ptr<T> ResourceManager::get(const std::string& name)
|
|
||||||
{
|
|
||||||
|
|
||||||
if (std::is_base_of<Resource, T>::value == false) {
|
|
||||||
throw std::runtime_error("ResourceManager::get() error: specified type is not a subclass of 'Resource'");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_resources.contains(name)) {
|
|
||||||
|
|
||||||
std::weak_ptr<Resource> res = m_resources.at(name);
|
|
||||||
|
|
||||||
if (res.expired() == false) {
|
|
||||||
// resource definitely exists
|
|
||||||
auto castedSharedPtr = std::dynamic_pointer_cast<T>(res.lock());
|
|
||||||
if (castedSharedPtr == nullptr) {
|
|
||||||
throw std::runtime_error("error: attempt to get Resource which already exists as another type");
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return castedSharedPtr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// Resource in map but no longer exists. Delete it.
|
|
||||||
m_resources.erase(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
return create<T>(name);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,56 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "engine_api.h"
|
|
||||||
|
|
||||||
#include "component.hpp"
|
|
||||||
|
|
||||||
#include "object.hpp"
|
|
||||||
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
#include <glm/vec3.hpp>
|
|
||||||
#include <glm/vec4.hpp>
|
|
||||||
#include <glm/mat4x4.hpp>
|
|
||||||
|
|
||||||
namespace engine::components {
|
|
||||||
|
|
||||||
class ENGINE_API Camera : public Component {
|
|
||||||
|
|
||||||
public:
|
|
||||||
Camera(Object* parent);
|
|
||||||
~Camera();
|
|
||||||
|
|
||||||
// called every frame, don't call manually
|
|
||||||
void updateCam(glm::mat4 transform, glm::mat4* viewMatrix);
|
|
||||||
|
|
||||||
void makeActive();
|
|
||||||
bool isActive();
|
|
||||||
|
|
||||||
void usePerspective(float fovDeg);
|
|
||||||
void useOrtho();
|
|
||||||
|
|
||||||
bool m_noClear = false;
|
|
||||||
|
|
||||||
glm::vec3 m_lightPos = { 0.0f, 100.0f, 0.0f };
|
|
||||||
|
|
||||||
glm::vec4 clearColor{0.1f, 0.1f, 0.1f, 1.0f};
|
|
||||||
|
|
||||||
glm::mat4 m_projMatrix{ 1.0f };
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
enum class Modes {
|
|
||||||
PERSPECTIVE,
|
|
||||||
ORTHOGRAPHIC
|
|
||||||
};
|
|
||||||
|
|
||||||
Modes m_mode = Modes::ORTHOGRAPHIC;
|
|
||||||
|
|
||||||
// perspective mode settings
|
|
||||||
float m_fovDeg = 90.0f;
|
|
||||||
|
|
||||||
static glm::vec4 s_clearColor;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
@ -1,47 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "engine_api.h"
|
|
||||||
|
|
||||||
namespace engine {
|
|
||||||
class Window;
|
|
||||||
class Input;
|
|
||||||
|
|
||||||
class Object;
|
|
||||||
class ResourceManager;
|
|
||||||
|
|
||||||
class ENGINE_API Component {
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
enum class TypeEnum {
|
|
||||||
TRANSFORM,
|
|
||||||
CAMERA,
|
|
||||||
RENDERER,
|
|
||||||
UI,
|
|
||||||
CUSTOM,
|
|
||||||
};
|
|
||||||
|
|
||||||
Component(Object* parent, TypeEnum type);
|
|
||||||
Component(const Component&) = delete;
|
|
||||||
Component& operator=(const Component&) = delete;
|
|
||||||
virtual ~Component() = 0;
|
|
||||||
|
|
||||||
int getID();
|
|
||||||
TypeEnum getType();
|
|
||||||
|
|
||||||
Object& parent;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
engine::Window& win;
|
|
||||||
engine::Input& inp;
|
|
||||||
ResourceManager& res;
|
|
||||||
|
|
||||||
private:
|
|
||||||
static int s_next_component_id;
|
|
||||||
|
|
||||||
int m_id = s_next_component_id;
|
|
||||||
TypeEnum m_type;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
@ -1,21 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "engine_api.h"
|
|
||||||
|
|
||||||
#include "component.hpp"
|
|
||||||
|
|
||||||
#include <glm/mat4x4.hpp>
|
|
||||||
|
|
||||||
namespace engine::components {
|
|
||||||
|
|
||||||
class ENGINE_API CustomComponent : public Component {
|
|
||||||
|
|
||||||
public:
|
|
||||||
CustomComponent(Object* parent);
|
|
||||||
virtual ~CustomComponent() = 0;
|
|
||||||
|
|
||||||
virtual void onUpdate(glm::mat4 t) {}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
@ -1,38 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "engine_api.h"
|
|
||||||
|
|
||||||
#include "component.hpp"
|
|
||||||
|
|
||||||
#include "resources/shader.hpp"
|
|
||||||
#include "resources/mesh.hpp"
|
|
||||||
#include "resources/texture.hpp"
|
|
||||||
|
|
||||||
#include <vector>
|
|
||||||
#include <string>
|
|
||||||
#include <memory>
|
|
||||||
|
|
||||||
namespace engine::components {
|
|
||||||
|
|
||||||
class ENGINE_API Renderer : public Component {
|
|
||||||
|
|
||||||
public:
|
|
||||||
Renderer(Object*);
|
|
||||||
~Renderer() override;
|
|
||||||
|
|
||||||
// called every frame, do not call manually
|
|
||||||
void render(glm::mat4 model, glm::mat4 view);
|
|
||||||
|
|
||||||
void setMesh(const std::string& name);
|
|
||||||
void setTexture(const std::string& name, bool invertV = false);
|
|
||||||
|
|
||||||
std::shared_ptr<resources::Mesh> m_mesh = nullptr;
|
|
||||||
std::shared_ptr<resources::Texture> m_texture;
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
std::shared_ptr<resources::Shader> m_shader;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
@ -1,43 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "engine_api.h"
|
|
||||||
|
|
||||||
#include "component.hpp"
|
|
||||||
|
|
||||||
#include "resources/font.hpp"
|
|
||||||
#include "resources/mesh.hpp"
|
|
||||||
#include "resources/shader.hpp"
|
|
||||||
|
|
||||||
#include <glm/mat4x4.hpp>
|
|
||||||
|
|
||||||
namespace engine::components {
|
|
||||||
|
|
||||||
class ENGINE_API UI : public Component {
|
|
||||||
|
|
||||||
public:
|
|
||||||
UI(Object*);
|
|
||||||
~UI() override;
|
|
||||||
|
|
||||||
// called every frame, do not call manually
|
|
||||||
void render(glm::mat4 transform, glm::mat4 view);
|
|
||||||
|
|
||||||
std::string m_text = "hello world";
|
|
||||||
glm::vec3 m_color = { 1.0f, 1.0f, 1.0f };
|
|
||||||
|
|
||||||
enum class Alignment {
|
|
||||||
NONE = 0,
|
|
||||||
LEFT = 1,
|
|
||||||
RIGHT = 2
|
|
||||||
};
|
|
||||||
Alignment m_alignment = Alignment::LEFT;
|
|
||||||
bool m_scaled = true;
|
|
||||||
|
|
||||||
private:
|
|
||||||
std::shared_ptr<resources::Font> m_font;
|
|
||||||
std::shared_ptr<resources::Shader> m_shader;
|
|
||||||
|
|
||||||
std::unique_ptr<resources::Mesh> m_atlasMesh;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
@ -1,40 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "engine_api.h"
|
|
||||||
|
|
||||||
#include "resource.hpp"
|
|
||||||
|
|
||||||
#include "gfx.hpp"
|
|
||||||
|
|
||||||
#include <glm/vec2.hpp>
|
|
||||||
|
|
||||||
#include <map>
|
|
||||||
|
|
||||||
namespace engine::resources {
|
|
||||||
|
|
||||||
class ENGINE_API Font : public Resource {
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
Font(const std::filesystem::path& resPath);
|
|
||||||
~Font() override;
|
|
||||||
|
|
||||||
struct CharData {
|
|
||||||
glm::vec2 atlas_top_left{};
|
|
||||||
glm::vec2 atlas_bottom_right{};
|
|
||||||
glm::vec2 char_top_left{};
|
|
||||||
glm::vec2 char_bottom_right{};
|
|
||||||
float xAdvance{};
|
|
||||||
};
|
|
||||||
|
|
||||||
const gfx::Texture* getAtlasTexture();
|
|
||||||
|
|
||||||
CharData getCharData(uint32_t charCode);
|
|
||||||
|
|
||||||
private:
|
|
||||||
const gfx::Texture* m_atlas;
|
|
||||||
std::map<uint32_t, CharData> m_charData;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
@ -1,43 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "engine_api.h"
|
|
||||||
|
|
||||||
#include "resource.hpp"
|
|
||||||
|
|
||||||
#include "gfx.hpp"
|
|
||||||
|
|
||||||
#include <glm/vec3.hpp>
|
|
||||||
#include <glm/vec2.hpp>
|
|
||||||
|
|
||||||
#include <vector>
|
|
||||||
#include <memory>
|
|
||||||
|
|
||||||
struct Vertex {
|
|
||||||
glm::vec3 pos;
|
|
||||||
glm::vec3 norm;
|
|
||||||
glm::vec2 uv;
|
|
||||||
};
|
|
||||||
|
|
||||||
namespace engine::resources {
|
|
||||||
|
|
||||||
class ENGINE_API Mesh : public Resource {
|
|
||||||
|
|
||||||
public:
|
|
||||||
Mesh(const std::vector<Vertex>& vertices);
|
|
||||||
Mesh(const std::vector<Vertex>& vertices, const std::vector<uint32_t>& indices);
|
|
||||||
Mesh(const std::filesystem::path& resPath);
|
|
||||||
~Mesh() override;
|
|
||||||
|
|
||||||
std::vector<Vertex> m_vertices;
|
|
||||||
std::vector<uint32_t> m_indices;
|
|
||||||
|
|
||||||
const gfx::Buffer* vb;
|
|
||||||
const gfx::Buffer* ib;
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
void initMesh();
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
@ -1,28 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "engine_api.h"
|
|
||||||
|
|
||||||
#include <string>
|
|
||||||
#include <filesystem>
|
|
||||||
|
|
||||||
namespace engine {
|
|
||||||
|
|
||||||
class ENGINE_API Resource {
|
|
||||||
|
|
||||||
public:
|
|
||||||
Resource(const std::filesystem::path& resPath, const std::string& type);
|
|
||||||
Resource(const Resource&) = delete;
|
|
||||||
Resource& operator=(const Resource&) = delete;
|
|
||||||
virtual ~Resource() = 0;
|
|
||||||
|
|
||||||
std::string getType();
|
|
||||||
|
|
||||||
protected:
|
|
||||||
std::filesystem::path m_resourcePath;
|
|
||||||
|
|
||||||
private:
|
|
||||||
const std::string m_type;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
@ -1,38 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "engine_api.h"
|
|
||||||
|
|
||||||
#include "resource.hpp"
|
|
||||||
|
|
||||||
#include <glm/mat4x4.hpp>
|
|
||||||
|
|
||||||
#include <string>
|
|
||||||
#include <map>
|
|
||||||
|
|
||||||
namespace engine::gfx {
|
|
||||||
struct Pipeline;
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace engine::resources {
|
|
||||||
|
|
||||||
class ENGINE_API Shader : public Resource {
|
|
||||||
|
|
||||||
public:
|
|
||||||
Shader(const std::filesystem::path& resPath);
|
|
||||||
~Shader() override;
|
|
||||||
|
|
||||||
struct UniformBuffer {
|
|
||||||
glm::mat4 p;
|
|
||||||
};
|
|
||||||
|
|
||||||
gfx::Pipeline* getPipeline()
|
|
||||||
{
|
|
||||||
return m_pipeline;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
gfx::Pipeline* m_pipeline = nullptr;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
@ -1,32 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "engine_api.h"
|
|
||||||
|
|
||||||
#include "object.hpp"
|
|
||||||
|
|
||||||
#include <filesystem>
|
|
||||||
|
|
||||||
namespace engine {
|
|
||||||
|
|
||||||
// Holds everything you would expect to find in a game scene
|
|
||||||
class ENGINE_API SceneRoot : public Object {
|
|
||||||
|
|
||||||
public:
|
|
||||||
// create a new empty scene
|
|
||||||
SceneRoot(struct GameIO things);
|
|
||||||
|
|
||||||
SceneRoot(const SceneRoot&) = delete;
|
|
||||||
SceneRoot& operator=(const SceneRoot&) = delete;
|
|
||||||
~SceneRoot();
|
|
||||||
|
|
||||||
void updateStuff();
|
|
||||||
|
|
||||||
void activateCam(int id);
|
|
||||||
void deactivateCam(int id);
|
|
||||||
|
|
||||||
private:
|
|
||||||
std::vector<int> m_activeCameras{};
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
@ -1,21 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "engine_api.h"
|
|
||||||
|
|
||||||
#include <glm/mat4x4.hpp>
|
|
||||||
#include <glm/vec3.hpp>
|
|
||||||
#include <glm/ext/quaternion_float.hpp>
|
|
||||||
|
|
||||||
namespace engine {
|
|
||||||
|
|
||||||
struct ENGINE_API Transform {
|
|
||||||
|
|
||||||
// Scale, rotate (XYZ), translate
|
|
||||||
|
|
||||||
glm::vec3 position{ 0.0f };
|
|
||||||
glm::quat rotation{};
|
|
||||||
glm::vec3 scale{ 1.0f };
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
@ -1,11 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "object.hpp"
|
|
||||||
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
namespace engine::util {
|
|
||||||
|
|
||||||
Object* loadAssimpMeshFromFile(Object* parent, const std::string& path);
|
|
||||||
|
|
||||||
}
|
|
@ -1,80 +0,0 @@
|
|||||||
#include "resource_manager.hpp"
|
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
#include <windows.h>
|
|
||||||
#include <direct.h>
|
|
||||||
#define MAX_PATH 260
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "log.hpp"
|
|
||||||
|
|
||||||
namespace engine {
|
|
||||||
|
|
||||||
ResourceManager::ResourceManager()
|
|
||||||
{
|
|
||||||
#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")) {
|
|
||||||
m_resourcesPath = cwd / "res";
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
m_resourcesPath = cwd.parent_path() / "share" / "sdltest";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (std::filesystem::is_directory(m_resourcesPath) == false) {
|
|
||||||
m_resourcesPath = cwd.root_path() / "usr" / "local" / "share" / "sdltest";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (std::filesystem::is_directory(m_resourcesPath) == false) {
|
|
||||||
throw std::runtime_error("Unable to determine resources location. CWD: " + cwd.string());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
std::unique_ptr<std::string> ResourceManager::getResourcesListString()
|
|
||||||
{
|
|
||||||
auto bufPtr = std::make_unique<std::string>();
|
|
||||||
std::string& buf = *bufPtr;
|
|
||||||
int maxLength = 0;
|
|
||||||
for (const auto& [name, ptr] : m_resources) {
|
|
||||||
if (name.length() > maxLength)
|
|
||||||
maxLength = name.length();
|
|
||||||
}
|
|
||||||
for (const auto& [name, ptr] : m_resources) {
|
|
||||||
buf += name;
|
|
||||||
for (int i = 0; i < (maxLength - name.length() + 4); i++) {
|
|
||||||
buf += " ";
|
|
||||||
}
|
|
||||||
buf += std::to_string(ptr.use_count()) + "\n";
|
|
||||||
}
|
|
||||||
return bufPtr;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
std::vector<std::weak_ptr<Resource>> ResourceManager::getAllResourcesOfType(const std::string& type)
|
|
||||||
{
|
|
||||||
std::vector<std::weak_ptr<Resource>> resources;
|
|
||||||
for (const auto& [name, ptr] : m_resources) {
|
|
||||||
if (ptr.expired() == false) {
|
|
||||||
if (ptr.lock()->getType() == type) {
|
|
||||||
resources.push_back(ptr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return resources;
|
|
||||||
}
|
|
||||||
|
|
||||||
// private
|
|
||||||
|
|
||||||
std::filesystem::path ResourceManager::getFilePath(const std::string& name)
|
|
||||||
{
|
|
||||||
return m_resourcesPath / name;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,98 +0,0 @@
|
|||||||
#include "components/camera.hpp"
|
|
||||||
|
|
||||||
#include "resource_manager.hpp"
|
|
||||||
#include "resources/shader.hpp"
|
|
||||||
|
|
||||||
#include "sceneroot.hpp"
|
|
||||||
|
|
||||||
#include "window.hpp"
|
|
||||||
|
|
||||||
#include "gfx_device.hpp"
|
|
||||||
|
|
||||||
#include "log.hpp"
|
|
||||||
|
|
||||||
#include <glm/ext/matrix_clip_space.hpp>
|
|
||||||
|
|
||||||
namespace engine::components {
|
|
||||||
|
|
||||||
glm::vec4 Camera::s_clearColor{-999.0f, -999.0f, -999.0f, -999.0f};
|
|
||||||
|
|
||||||
Camera::Camera(Object* parent) : Component(parent, TypeEnum::CAMERA)
|
|
||||||
{
|
|
||||||
parent->root.activateCam(getID());
|
|
||||||
}
|
|
||||||
|
|
||||||
Camera::~Camera()
|
|
||||||
{
|
|
||||||
parent.root.deactivateCam(getID());
|
|
||||||
}
|
|
||||||
|
|
||||||
void Camera::updateCam(glm::mat4 transform, glm::mat4* viewMatOut)
|
|
||||||
{
|
|
||||||
|
|
||||||
if (parent.win.getWindowResized()) {
|
|
||||||
if (m_mode == Modes::PERSPECTIVE) {
|
|
||||||
usePerspective(m_fovDeg);
|
|
||||||
} else {
|
|
||||||
useOrtho();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
glm::mat4 viewMatrix = glm::inverse(transform);
|
|
||||||
|
|
||||||
resources::Shader::UniformBuffer uniformData{};
|
|
||||||
|
|
||||||
uniformData.p = m_projMatrix;
|
|
||||||
|
|
||||||
using namespace resources;
|
|
||||||
|
|
||||||
auto resPtrs = parent.res.getAllResourcesOfType("shader");
|
|
||||||
for (const auto& resPtr : resPtrs) {
|
|
||||||
// shader ref count increased by 1, but only in this scope
|
|
||||||
auto lockedPtr = resPtr.lock();
|
|
||||||
auto shader = dynamic_cast<Shader*>(lockedPtr.get());
|
|
||||||
// SET VIEW TRANSFORM HERE
|
|
||||||
gfxdev->updateUniformBuffer(shader->getPipeline(), &uniformData.p, sizeof(uniformData.p), offsetof(resources::Shader::UniformBuffer, p));
|
|
||||||
}
|
|
||||||
|
|
||||||
*viewMatOut = viewMatrix;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
static glm::vec2 getViewportSize()
|
|
||||||
{
|
|
||||||
uint32_t width;
|
|
||||||
uint32_t height;
|
|
||||||
gfxdev->getViewportSize(&width, &height);
|
|
||||||
return {width, height};
|
|
||||||
}
|
|
||||||
|
|
||||||
void Camera::usePerspective(float fovDeg)
|
|
||||||
{
|
|
||||||
constexpr float NEAR = 0.1f;
|
|
||||||
constexpr float FAR = 100000.0f;
|
|
||||||
|
|
||||||
m_mode = Modes::PERSPECTIVE;
|
|
||||||
m_fovDeg = fovDeg;
|
|
||||||
|
|
||||||
float fovRad = glm::radians(fovDeg);
|
|
||||||
|
|
||||||
glm::vec2 viewportDim = getViewportSize();
|
|
||||||
float aspect = viewportDim.x / viewportDim.y;
|
|
||||||
|
|
||||||
float fovY = fovRad / aspect;
|
|
||||||
|
|
||||||
m_projMatrix = glm::perspectiveZO(fovY, aspect, NEAR, FAR);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Camera::useOrtho()
|
|
||||||
{
|
|
||||||
m_mode = Modes::ORTHOGRAPHIC;
|
|
||||||
|
|
||||||
glm::vec2 viewportDim = getViewportSize();
|
|
||||||
float aspect = viewportDim.x / viewportDim.y;
|
|
||||||
|
|
||||||
m_projMatrix = glm::orthoRH_ZO(-10.0f * aspect, 10.0f * aspect, -10.0f, 10.0f, -100.0f, 100.0f);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,34 +0,0 @@
|
|||||||
#include "components/component.hpp"
|
|
||||||
|
|
||||||
#include "object.hpp"
|
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
namespace engine {
|
|
||||||
|
|
||||||
int Component::s_next_component_id = 0;
|
|
||||||
|
|
||||||
Component::Component(Object* parent, TypeEnum type) :
|
|
||||||
m_type(type), parent(*parent),
|
|
||||||
win(parent->win),
|
|
||||||
inp(parent->inp),
|
|
||||||
res(parent->res)
|
|
||||||
{
|
|
||||||
s_next_component_id++;
|
|
||||||
}
|
|
||||||
|
|
||||||
Component::~Component()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
int Component::getID()
|
|
||||||
{
|
|
||||||
return m_id;
|
|
||||||
}
|
|
||||||
|
|
||||||
Component::TypeEnum Component::getType()
|
|
||||||
{
|
|
||||||
return m_type;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,15 +0,0 @@
|
|||||||
#include "components/custom.hpp"
|
|
||||||
|
|
||||||
namespace engine::components {
|
|
||||||
|
|
||||||
CustomComponent::CustomComponent(Object* parent) : Component(parent, TypeEnum::CUSTOM)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
CustomComponent::~CustomComponent()
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,52 +0,0 @@
|
|||||||
#include "components/mesh_renderer.hpp"
|
|
||||||
|
|
||||||
#include "resources/shader.hpp"
|
|
||||||
|
|
||||||
#include "object.hpp"
|
|
||||||
|
|
||||||
#include "resource_manager.hpp"
|
|
||||||
|
|
||||||
#include "gfx_device.hpp"
|
|
||||||
|
|
||||||
#include "log.hpp"
|
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
namespace engine::components {
|
|
||||||
|
|
||||||
Renderer::Renderer(Object* parent) : Component(parent, TypeEnum::RENDERER)
|
|
||||||
{
|
|
||||||
m_shader = this->parent.res.get<resources::Shader>("shaders/texture.glsl");
|
|
||||||
m_texture = this->parent.res.get<resources::Texture>("textures/white.png");
|
|
||||||
}
|
|
||||||
|
|
||||||
Renderer::~Renderer()
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void Renderer::render(glm::mat4 transform, glm::mat4 view)
|
|
||||||
{
|
|
||||||
resources::Shader::UniformBuffer uniformData{};
|
|
||||||
|
|
||||||
glm::mat4 pushConsts[] = { transform, view };
|
|
||||||
gfxdev->draw(m_shader->getPipeline(), m_mesh->vb, m_mesh->ib, m_mesh->m_indices.size(), pushConsts, sizeof(glm::mat4) * 2, m_texture->getHandle());
|
|
||||||
}
|
|
||||||
|
|
||||||
void Renderer::setMesh(const std::string& name)
|
|
||||||
{
|
|
||||||
m_mesh = parent.res.get<resources::Mesh>(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Renderer::setTexture(const std::string& name, bool invertV)
|
|
||||||
{
|
|
||||||
if (invertV) {
|
|
||||||
// append a special character to file name
|
|
||||||
m_texture = parent.res.get<resources::Texture>(name + "_");
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
m_texture = parent.res.get<resources::Texture>(name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,59 +0,0 @@
|
|||||||
#include "components/text_ui_renderer.hpp"
|
|
||||||
|
|
||||||
#include "object.hpp"
|
|
||||||
#include "resource_manager.hpp"
|
|
||||||
#include "resources/texture.hpp"
|
|
||||||
|
|
||||||
namespace engine::components {
|
|
||||||
|
|
||||||
UI::UI(Object* parent) : Component(parent, TypeEnum::UI)
|
|
||||||
{
|
|
||||||
const std::string FONTFILE{ "fonts/LiberationMono-Regular.ttf" };
|
|
||||||
m_font = parent->res.get<resources::Font>(FONTFILE);
|
|
||||||
m_shader = parent->res.get<resources::Shader>("shaders/font.glsl");
|
|
||||||
|
|
||||||
m_atlasMesh = std::make_unique<resources::Mesh>(std::vector<Vertex>{
|
|
||||||
{ { 0.0f, 0.0f, 0.0f }, { 0.0f, 1.0f, 0.0f }, { 0.0f, 0.0f } },
|
|
||||||
{ { 0.0f, 1.0f, 0.0f }, { 0.0f, 1.0f, 0.0f }, { 0.0f, 1.0f } },
|
|
||||||
{ { 1.0f, 1.0f, 0.0f }, { 0.0f, 1.0f, 0.0f }, { 1.0f, 1.0f } },
|
|
||||||
|
|
||||||
{ { 1.0f, 0.0f, 0.0f }, { 0.0f, 1.0f, 0.0f }, { 1.0f, 0.0f } },
|
|
||||||
{ { 0.0f, 0.0f, 0.0f }, { 0.0f, 1.0f, 0.0f }, { 0.0f, 0.0f } },
|
|
||||||
{ { 1.0f, 1.0f, 0.0f }, { 0.0f, 1.0f, 0.0f }, { 1.0f, 1.0f } },
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
UI::~UI()
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void UI::render(glm::mat4 transform, glm::mat4 view)
|
|
||||||
{
|
|
||||||
|
|
||||||
struct {
|
|
||||||
glm::mat4 m;
|
|
||||||
glm::vec2 atlas_top_left;
|
|
||||||
glm::vec2 atlas_bottom_right;
|
|
||||||
glm::vec2 offset;
|
|
||||||
glm::vec2 size;
|
|
||||||
} pushConsts{};
|
|
||||||
|
|
||||||
float advance = 0.0f;
|
|
||||||
for (char c : m_text) {
|
|
||||||
auto charData = m_font->getCharData(c);
|
|
||||||
charData.char_top_left.y *= -1;
|
|
||||||
pushConsts.m = transform;
|
|
||||||
pushConsts.atlas_top_left = charData.atlas_top_left;
|
|
||||||
pushConsts.atlas_bottom_right = charData.atlas_bottom_right;
|
|
||||||
pushConsts.size = (charData.char_bottom_right - charData.char_top_left);
|
|
||||||
pushConsts.offset = glm::vec2{ charData.char_top_left.x + advance, charData.char_top_left.y };
|
|
||||||
gfxdev->draw(
|
|
||||||
m_shader->getPipeline(), m_atlasMesh->vb, m_atlasMesh->ib, m_atlasMesh->m_indices.size(),
|
|
||||||
&pushConsts, sizeof(pushConsts), m_font->getAtlasTexture());
|
|
||||||
advance += charData.xAdvance;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,79 +0,0 @@
|
|||||||
// This implementation of the graphics layer does nothing
|
|
||||||
|
|
||||||
//#define ENGINE_BUILD_NULLGFX
|
|
||||||
#ifdef ENGINE_BUILD_NULLGFX
|
|
||||||
|
|
||||||
#include "gfx_device.hpp"
|
|
||||||
#include "util.hpp"
|
|
||||||
#include "config.h"
|
|
||||||
#include "log.hpp"
|
|
||||||
|
|
||||||
#include <SDL2/SDL.h>
|
|
||||||
|
|
||||||
#include <assert.h>
|
|
||||||
#include <unordered_set>
|
|
||||||
#include <array>
|
|
||||||
#include <fstream>
|
|
||||||
#include <filesystem>
|
|
||||||
#include <optional>
|
|
||||||
|
|
||||||
namespace engine {
|
|
||||||
|
|
||||||
// structures and enums
|
|
||||||
|
|
||||||
// class definitions
|
|
||||||
|
|
||||||
struct GFXDevice::Impl {
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
GFXDevice::GFXDevice(const char* appName, const char* appVersion, SDL_Window* window, bool vsync)
|
|
||||||
{
|
|
||||||
pimpl = std::make_unique<Impl>();
|
|
||||||
}
|
|
||||||
|
|
||||||
GFXDevice::~GFXDevice()
|
|
||||||
{
|
|
||||||
TRACE("Destroying GFXDevice...");
|
|
||||||
}
|
|
||||||
|
|
||||||
void GFXDevice::drawBuffer(const gfx::Pipeline* pipeline, const gfx::Buffer* vertexBuffer, uint32_t count)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void GFXDevice::drawIndexed(const gfx::Pipeline* pipeline, const gfx::Buffer* vertexBuffer, const gfx::Buffer* indexBuffer, uint32_t indexCount)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void GFXDevice::renderFrame()
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
gfx::Pipeline* GFXDevice::createPipeline(const char* vertShaderPath, const char* fragShaderPath, const gfx::VertexFormat& vertexFormat)
|
|
||||||
{
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
void GFXDevice::destroyPipeline(const gfx::Pipeline* pipeline)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
gfx::Buffer* GFXDevice::createBuffer(gfx::BufferType type, uint64_t size, const void* data)
|
|
||||||
{
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
void GFXDevice::destroyBuffer(const gfx::Buffer* buffer)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void GFXDevice::waitIdle()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,186 +0,0 @@
|
|||||||
// The implementation of the graphics layer using OpenGL 4.5
|
|
||||||
// This uses SDL specific code
|
|
||||||
|
|
||||||
#ifdef ENGINE_BUILD_OPENGL
|
|
||||||
|
|
||||||
#include "gfx_device.hpp"
|
|
||||||
|
|
||||||
#include "log.hpp"
|
|
||||||
|
|
||||||
#include <glad/glad.h>
|
|
||||||
|
|
||||||
#include <SDL_video.h>
|
|
||||||
|
|
||||||
#include <fstream>
|
|
||||||
|
|
||||||
namespace engine {
|
|
||||||
|
|
||||||
// EXTERNED GLOBAL VARIABLE
|
|
||||||
GFXDevice* gfxdev = nullptr;
|
|
||||||
|
|
||||||
// structures and enums
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// handles
|
|
||||||
|
|
||||||
struct gfx::Buffer {
|
|
||||||
gfx::BufferType type;
|
|
||||||
// TODO
|
|
||||||
};
|
|
||||||
|
|
||||||
struct gfx::Pipeline {
|
|
||||||
// TODO
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// enum converters
|
|
||||||
|
|
||||||
namespace vkinternal {
|
|
||||||
/*
|
|
||||||
static GLenum getVertexAttribFormat(gfx::VertexAttribFormat fmt)
|
|
||||||
{
|
|
||||||
switch (fmt) {
|
|
||||||
case gfx::VertexAttribFormat::VEC2:
|
|
||||||
return VK_FORMAT_R32G32_SFLOAT;
|
|
||||||
case gfx::VertexAttribFormat::VEC3:
|
|
||||||
return VK_FORMAT_R32G32B32_SFLOAT;
|
|
||||||
}
|
|
||||||
throw std::runtime_error("Unknown vertex attribute format");
|
|
||||||
}
|
|
||||||
|
|
||||||
static VkBufferUsageFlagBits getBufferUsageFlag(gfx::BufferType type)
|
|
||||||
{
|
|
||||||
switch (type) {
|
|
||||||
case gfx::BufferType::VERTEX:
|
|
||||||
return VK_BUFFER_USAGE_VERTEX_BUFFER_BIT;
|
|
||||||
case gfx::BufferType::INDEX:
|
|
||||||
return VK_BUFFER_USAGE_INDEX_BUFFER_BIT;
|
|
||||||
}
|
|
||||||
throw std::runtime_error("Unknown buffer type");
|
|
||||||
}*/
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// functions
|
|
||||||
|
|
||||||
static std::vector<char> readFile(const std::string& filename)
|
|
||||||
{
|
|
||||||
std::ifstream file(filename, std::ios::ate | std::ios::binary);
|
|
||||||
if (file.is_open() == false) {
|
|
||||||
throw std::runtime_error("Unable to open file " + filename);
|
|
||||||
}
|
|
||||||
std::vector<char> buffer(file.tellg());
|
|
||||||
file.seekg(0);
|
|
||||||
file.read(buffer.data(), buffer.size());
|
|
||||||
file.close();
|
|
||||||
return buffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
// class definitions
|
|
||||||
|
|
||||||
struct GFXDevice::Impl {
|
|
||||||
|
|
||||||
SDL_Window* window = nullptr;
|
|
||||||
|
|
||||||
uint64_t FRAMECOUNT = 0;
|
|
||||||
|
|
||||||
SDL_GLContext context;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
GFXDevice::GFXDevice(const char* appName, const char* appVersion, SDL_Window* window, bool vsync)
|
|
||||||
{
|
|
||||||
if (gfxdev != nullptr) {
|
|
||||||
throw std::runtime_error("There can only be one graphics device");
|
|
||||||
}
|
|
||||||
gfxdev = this;
|
|
||||||
|
|
||||||
pimpl = std::make_unique<Impl>();
|
|
||||||
|
|
||||||
pimpl->window = window;
|
|
||||||
|
|
||||||
pimpl->context = SDL_GL_CreateContext(window);
|
|
||||||
if (pimpl->context == NULL) {
|
|
||||||
throw std::runtime_error("Unable to create OpenGL context: " + std::string(SDL_GetError()));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!gladLoadGLLoader((GLADloadproc)SDL_GL_GetProcAddress)) {
|
|
||||||
throw std::runtime_error("Unable to initialise GLAD");
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
GFXDevice::~GFXDevice()
|
|
||||||
{
|
|
||||||
TRACE("Destroying GFXDevice...");
|
|
||||||
|
|
||||||
SDL_GL_DeleteContext(pimpl->context);
|
|
||||||
}
|
|
||||||
|
|
||||||
void GFXDevice::getViewportSize(uint32_t* w, uint32_t* h)
|
|
||||||
{
|
|
||||||
int width, height;
|
|
||||||
SDL_GL_GetDrawableSize(pimpl->window, &width, &height);
|
|
||||||
*w = (uint32_t)width;
|
|
||||||
*h = (uint32_t)height;
|
|
||||||
}
|
|
||||||
|
|
||||||
void draw(const gfx::Pipeline* pipeline, const gfx::Buffer* vertexBuffer, const gfx::Buffer* indexBuffer, uint32_t count, const void* pushConstantData, size_t pushConstantSize, const gfx::Texture* texture)
|
|
||||||
{
|
|
||||||
assert(vertexBuffer->type == gfx::BufferType::VERTEX);
|
|
||||||
assert(vertexBuffer != nullptr);
|
|
||||||
assert(indexBuffer == nullptr || indexBuffer->type == gfx::BufferType::INDEX);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void GFXDevice::renderFrame()
|
|
||||||
{
|
|
||||||
glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
|
|
||||||
glClear(GL_COLOR_BUFFER_BIT);
|
|
||||||
|
|
||||||
SDL_GL_SwapWindow(pimpl->window);
|
|
||||||
|
|
||||||
pimpl->FRAMECOUNT++;
|
|
||||||
}
|
|
||||||
|
|
||||||
gfx::Pipeline* GFXDevice::createPipeline(const char* vertShaderPath, const char* fragShaderPath, const gfx::VertexFormat& vertexFormat, uint64_t uniformBufferSize)
|
|
||||||
{
|
|
||||||
gfx::Pipeline* pipeline = new gfx::Pipeline{};
|
|
||||||
|
|
||||||
return pipeline;
|
|
||||||
}
|
|
||||||
|
|
||||||
void GFXDevice::destroyPipeline(const gfx::Pipeline* pipeline)
|
|
||||||
{
|
|
||||||
delete pipeline;
|
|
||||||
}
|
|
||||||
|
|
||||||
void GFXDevice::updateUniformBuffer(const gfx::Pipeline* pipeline, void* data)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
gfx::Buffer* GFXDevice::createBuffer(gfx::BufferType type, uint64_t size, const void* data)
|
|
||||||
{
|
|
||||||
auto out = new gfx::Buffer{};
|
|
||||||
|
|
||||||
out->type = type;
|
|
||||||
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
|
|
||||||
void GFXDevice::destroyBuffer(const gfx::Buffer* buffer)
|
|
||||||
{
|
|
||||||
delete buffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
void GFXDevice::waitIdle()
|
|
||||||
{
|
|
||||||
//glFinish();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,70 +0,0 @@
|
|||||||
#include "resources/font.hpp"
|
|
||||||
|
|
||||||
#define STB_TRUETYPE_IMPLEMENTATION
|
|
||||||
#include <stb_truetype.h>
|
|
||||||
|
|
||||||
#include "util/files.hpp"
|
|
||||||
#include "gfx_device.hpp"
|
|
||||||
|
|
||||||
#include "log.hpp"
|
|
||||||
|
|
||||||
namespace engine::resources {
|
|
||||||
|
|
||||||
Font::Font(const std::filesystem::path& resPath) : Resource(resPath, "font")
|
|
||||||
{
|
|
||||||
|
|
||||||
// TODO: load font
|
|
||||||
auto fontBuffer = util::readBinaryFile(resPath.string());
|
|
||||||
|
|
||||||
constexpr int FIRST_CHAR = 32;
|
|
||||||
constexpr int NUM_CHARS = 96;
|
|
||||||
|
|
||||||
constexpr float SCALE = 128.0f;
|
|
||||||
|
|
||||||
constexpr int BITMAP_WIDTH = 1024;
|
|
||||||
constexpr int BITMAP_HEIGHT = 1024;
|
|
||||||
auto pixels = std::make_unique<unsigned char[]>(BITMAP_WIDTH * BITMAP_HEIGHT);
|
|
||||||
auto bakedChars = std::make_unique<stbtt_bakedchar[]>(NUM_CHARS);
|
|
||||||
|
|
||||||
stbtt_BakeFontBitmap(fontBuffer->data(), 0, SCALE, pixels.get(), BITMAP_WIDTH, BITMAP_HEIGHT, FIRST_CHAR, NUM_CHARS, bakedChars.get());
|
|
||||||
|
|
||||||
auto textureData = std::make_unique<uint8_t[]>(BITMAP_WIDTH * BITMAP_HEIGHT * 4);
|
|
||||||
|
|
||||||
for (int i = 0; i < BITMAP_WIDTH * BITMAP_HEIGHT; i++) {
|
|
||||||
textureData[i * 4 + 0] = 255;
|
|
||||||
textureData[i * 4 + 1] = 255;
|
|
||||||
textureData[i * 4 + 2] = 255;
|
|
||||||
textureData[i * 4 + 3] = pixels[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
m_atlas = gfxdev->createTexture(textureData.get(), BITMAP_WIDTH, BITMAP_HEIGHT, gfx::TextureFilter::LINEAR, gfx::TextureFilter::LINEAR);
|
|
||||||
|
|
||||||
for (int i = FIRST_CHAR; i < FIRST_CHAR + NUM_CHARS; i++) {
|
|
||||||
CharData charData{};
|
|
||||||
stbtt_bakedchar baked = bakedChars[i - FIRST_CHAR];
|
|
||||||
charData.atlas_top_left = { (float)baked.x0 / (float)BITMAP_WIDTH, (float)baked.y0 / (float)BITMAP_HEIGHT };
|
|
||||||
charData.atlas_bottom_right = { (float)baked.x1 / (float)BITMAP_WIDTH, (float)baked.y1 / (float)BITMAP_HEIGHT};
|
|
||||||
charData.char_top_left = { baked.xoff, baked.yoff };
|
|
||||||
charData.char_bottom_right = charData.char_top_left + glm::vec2{ baked.x1 - baked.x0, baked.y1 - baked.y0 };
|
|
||||||
charData.xAdvance = baked.xadvance;
|
|
||||||
m_charData[i] = charData;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
Font::~Font()
|
|
||||||
{
|
|
||||||
gfxdev->destroyTexture(m_atlas);
|
|
||||||
}
|
|
||||||
|
|
||||||
const gfx::Texture* Font::getAtlasTexture()
|
|
||||||
{
|
|
||||||
return m_atlas;
|
|
||||||
}
|
|
||||||
|
|
||||||
Font::CharData Font::getCharData(uint32_t charCode)
|
|
||||||
{
|
|
||||||
return m_charData[charCode];
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,78 +0,0 @@
|
|||||||
#include "resources/mesh.hpp"
|
|
||||||
|
|
||||||
#include "gfx_device.hpp"
|
|
||||||
|
|
||||||
#include "log.hpp"
|
|
||||||
|
|
||||||
namespace engine::resources {
|
|
||||||
|
|
||||||
struct MeshFileHeader {
|
|
||||||
uint32_t vertex_count;
|
|
||||||
uint32_t index_count;
|
|
||||||
int32_t material;
|
|
||||||
};
|
|
||||||
|
|
||||||
static void loadCustomMeshFromFile(const std::filesystem::path& path, std::vector<Vertex>* vertices, std::vector<uint32_t>* indices)
|
|
||||||
{
|
|
||||||
|
|
||||||
struct MeshFileHeader header{};
|
|
||||||
|
|
||||||
FILE* fp = fopen(path.string().c_str(), "rb");
|
|
||||||
if (fp == NULL) {
|
|
||||||
throw std::runtime_error("Unable to open mesh file " + path.string());
|
|
||||||
}
|
|
||||||
|
|
||||||
fread(&header, sizeof(struct MeshFileHeader), 1, fp);
|
|
||||||
|
|
||||||
indices->resize(header.index_count);
|
|
||||||
vertices->resize(header.vertex_count);
|
|
||||||
|
|
||||||
fread(indices->data(), sizeof(uint32_t) * header.index_count, 1, fp);
|
|
||||||
fread(vertices->data(), sizeof(Vertex) * header.vertex_count, 1, fp);
|
|
||||||
fclose(fp);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void Mesh::initMesh()
|
|
||||||
{
|
|
||||||
vb = gfxdev->createBuffer(gfx::BufferType::VERTEX, m_vertices.size() * sizeof(Vertex), m_vertices.data());
|
|
||||||
ib = gfxdev->createBuffer(gfx::BufferType::INDEX, m_indices.size() * sizeof(uint32_t), m_indices.data());
|
|
||||||
}
|
|
||||||
|
|
||||||
Mesh::Mesh(const std::vector<Vertex>& vertices) : Resource("", "mesh")
|
|
||||||
{
|
|
||||||
// constructor for custom meshes without an index array
|
|
||||||
m_vertices = vertices; // COPY over vertices
|
|
||||||
for (uint32_t i = 0; i < m_vertices.size(); i++) {
|
|
||||||
m_indices.push_back(i);
|
|
||||||
}
|
|
||||||
initMesh();
|
|
||||||
}
|
|
||||||
|
|
||||||
Mesh::Mesh(const std::vector<Vertex>& vertices, const std::vector<uint32_t>& indices) : Resource("", "mesh")
|
|
||||||
{
|
|
||||||
m_vertices = vertices; // COPY over vertices
|
|
||||||
m_indices = indices; // COPY over indices;
|
|
||||||
initMesh();
|
|
||||||
}
|
|
||||||
|
|
||||||
// To be used with the resource manager
|
|
||||||
Mesh::Mesh(const std::filesystem::path& resPath) : Resource(resPath, "mesh")
|
|
||||||
{
|
|
||||||
if (resPath.extension() == ".mesh") {
|
|
||||||
loadCustomMeshFromFile(resPath, &m_vertices, &m_indices);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
throw std::runtime_error("Mesh load error, unknown file type");
|
|
||||||
}
|
|
||||||
|
|
||||||
initMesh();
|
|
||||||
}
|
|
||||||
|
|
||||||
Mesh::~Mesh()
|
|
||||||
{
|
|
||||||
gfxdev->destroyBuffer(ib);
|
|
||||||
gfxdev->destroyBuffer(vb);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,24 +0,0 @@
|
|||||||
#include "resources/resource.hpp"
|
|
||||||
|
|
||||||
#include <log.hpp>
|
|
||||||
|
|
||||||
namespace engine {
|
|
||||||
|
|
||||||
Resource::Resource(const std::filesystem::path& resPath, const std::string& type) : m_resourcePath(resPath), m_type(type)
|
|
||||||
{
|
|
||||||
if (m_type != "mesh")
|
|
||||||
TRACE("Creating {} resource: {}", type, resPath.filename().string());
|
|
||||||
}
|
|
||||||
|
|
||||||
Resource::~Resource()
|
|
||||||
{
|
|
||||||
if (m_type != "mesh")
|
|
||||||
TRACE("Destroyed {} resource: {}", m_type, m_resourcePath.filename().string());
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string Resource::getType()
|
|
||||||
{
|
|
||||||
return m_type;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,32 +0,0 @@
|
|||||||
#include "resources/shader.hpp"
|
|
||||||
|
|
||||||
#include "log.hpp"
|
|
||||||
|
|
||||||
#include "gfx_device.hpp"
|
|
||||||
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
namespace engine::resources {
|
|
||||||
|
|
||||||
Shader::Shader(const std::filesystem::path& resPath) : Resource(resPath, "shader")
|
|
||||||
{
|
|
||||||
|
|
||||||
gfx::VertexFormat vertexFormat {};
|
|
||||||
vertexFormat.stride = 8 * sizeof(float);
|
|
||||||
vertexFormat.attributeDescriptions.emplace_back(0, gfx::VertexAttribFormat::VEC3, 0); // pos
|
|
||||||
vertexFormat.attributeDescriptions.emplace_back(1, gfx::VertexAttribFormat::VEC3, sizeof(glm::vec3)); // norm
|
|
||||||
vertexFormat.attributeDescriptions.emplace_back(2, gfx::VertexAttribFormat::VEC2, sizeof(glm::vec3) + sizeof(glm::vec3)); // uv
|
|
||||||
|
|
||||||
const std::string vertexShaderPath = (resPath.parent_path()/std::filesystem::path(resPath.stem().string() + ".vert")).string();
|
|
||||||
const std::string fragmentShaderPath = (resPath.parent_path()/std::filesystem::path(resPath.stem().string() + ".frag")).string();
|
|
||||||
|
|
||||||
m_pipeline = gfxdev->createPipeline(vertexShaderPath.c_str(), fragmentShaderPath.c_str(), vertexFormat, sizeof(UniformBuffer), true, true);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
Shader::~Shader()
|
|
||||||
{
|
|
||||||
gfxdev->destroyPipeline(m_pipeline);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,220 +0,0 @@
|
|||||||
#include "util/model_loader.hpp"
|
|
||||||
|
|
||||||
#include "log.hpp"
|
|
||||||
|
|
||||||
#include "resources/texture.hpp"
|
|
||||||
#include "resources/mesh.hpp"
|
|
||||||
|
|
||||||
#include "components/mesh_renderer.hpp"
|
|
||||||
|
|
||||||
#include "resource_manager.hpp"
|
|
||||||
|
|
||||||
#include <assimp/Importer.hpp>
|
|
||||||
#include <assimp/LogStream.hpp>
|
|
||||||
#include <assimp/Logger.hpp>
|
|
||||||
#include <assimp/DefaultLogger.hpp>
|
|
||||||
#include <assimp/postprocess.h>
|
|
||||||
#include <assimp/mesh.h>
|
|
||||||
#include <assimp/scene.h>
|
|
||||||
|
|
||||||
#include <glm/gtc/quaternion.hpp>
|
|
||||||
|
|
||||||
|
|
||||||
#include <map>
|
|
||||||
|
|
||||||
namespace engine::util {
|
|
||||||
|
|
||||||
static void buildGraph(
|
|
||||||
const std::map<int, std::shared_ptr<resources::Texture>>& textures,
|
|
||||||
const std::vector<std::shared_ptr<resources::Mesh>>& meshes,
|
|
||||||
const std::vector<unsigned int>& meshTextureIndices,
|
|
||||||
aiNode* parentNode, Object* parentObj)
|
|
||||||
{
|
|
||||||
|
|
||||||
// convert to glm column major
|
|
||||||
glm::mat4 transform;
|
|
||||||
for (int i = 0; i < 4; i++) {
|
|
||||||
for (int j = 0; j < 4; j++) {
|
|
||||||
transform[i][j] = parentNode->mTransformation[j][i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// get position
|
|
||||||
glm::vec3 position{ transform[3][0], transform[3][1], transform[3][2] };
|
|
||||||
|
|
||||||
// remove position from matrix
|
|
||||||
transform[3][0] = 0.0f;
|
|
||||||
transform[3][1] = 0.0f;
|
|
||||||
transform[3][2] = 0.0f;
|
|
||||||
|
|
||||||
// get scale
|
|
||||||
glm::vec3 scale{};
|
|
||||||
scale.x = sqrt(transform[0][0] * transform[0][0] + transform[0][1] * transform[0][1] + transform[0][2] * transform[0][2]);
|
|
||||||
scale.y = sqrt(transform[1][0] * transform[1][0] + transform[1][1] * transform[1][1] + transform[1][2] * transform[1][2]);
|
|
||||||
scale.z = sqrt(transform[2][0] * transform[2][0] + transform[2][1] * transform[2][1] + transform[2][2] * transform[2][2]);
|
|
||||||
|
|
||||||
// remove scaling from matrix
|
|
||||||
for (int row = 0; row < 3; row++) {
|
|
||||||
transform[0][row] /= scale.x;
|
|
||||||
transform[1][row] /= scale.y;
|
|
||||||
transform[2][row] /= scale.z;
|
|
||||||
}
|
|
||||||
|
|
||||||
// get rotation
|
|
||||||
glm::quat rotation = glm::quat_cast(transform);
|
|
||||||
|
|
||||||
// update position, scale, rotation
|
|
||||||
parentObj->transform.position = position;
|
|
||||||
parentObj->transform.scale = scale;
|
|
||||||
parentObj->transform.rotation = rotation;
|
|
||||||
|
|
||||||
for (int i = 0; i < parentNode->mNumMeshes; i++) {
|
|
||||||
// create child node for each mesh
|
|
||||||
auto child = parentObj->createChild("_mesh" + std::to_string(i));
|
|
||||||
auto childRenderer = child->createComponent<components::Renderer>();
|
|
||||||
childRenderer->m_mesh = meshes[parentNode->mMeshes[i]];
|
|
||||||
if (textures.contains(meshTextureIndices[parentNode->mMeshes[i]])) {
|
|
||||||
childRenderer->m_texture = textures.at(meshTextureIndices[parentNode->mMeshes[i]]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < parentNode->mNumChildren; i++) {
|
|
||||||
buildGraph(textures, meshes, meshTextureIndices, parentNode->mChildren[i], parentObj->createChild("child" + std::to_string(i)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Object* loadAssimpMeshFromFile(Object* parent, const std::string& path)
|
|
||||||
{
|
|
||||||
Assimp::Importer importer;
|
|
||||||
|
|
||||||
class myStream : public Assimp::LogStream {
|
|
||||||
public:
|
|
||||||
void write(const char* message) override {
|
|
||||||
DEBUG("ASSIMP: {}", message);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const unsigned int severity = Assimp::Logger::Debugging | Assimp::Logger::Info | Assimp::Logger::Err | Assimp::Logger::Warn;
|
|
||||||
Assimp::DefaultLogger::get()->attachStream(new myStream, severity);
|
|
||||||
|
|
||||||
// remove everything but texcoords, normals, meshes, materials
|
|
||||||
importer.SetPropertyInteger(AI_CONFIG_PP_RVC_FLAGS,
|
|
||||||
aiComponent_ANIMATIONS |
|
|
||||||
aiComponent_BONEWEIGHTS |
|
|
||||||
aiComponent_CAMERAS |
|
|
||||||
aiComponent_COLORS |
|
|
||||||
aiComponent_LIGHTS |
|
|
||||||
aiComponent_TANGENTS_AND_BITANGENTS |
|
|
||||||
aiComponent_TEXTURES |
|
|
||||||
0
|
|
||||||
);
|
|
||||||
importer.SetPropertyInteger(AI_CONFIG_PP_SBP_REMOVE,
|
|
||||||
aiPrimitiveType_POINT |
|
|
||||||
aiPrimitiveType_LINE |
|
|
||||||
aiPrimitiveType_POLYGON
|
|
||||||
);
|
|
||||||
|
|
||||||
const aiScene* scene = importer.ReadFile(path,
|
|
||||||
aiProcess_JoinIdenticalVertices |
|
|
||||||
aiProcess_Triangulate |
|
|
||||||
aiProcess_SortByPType |
|
|
||||||
aiProcess_RemoveComponent |
|
|
||||||
aiProcess_SplitLargeMeshes | // leave at default maximum
|
|
||||||
aiProcess_ValidateDataStructure | // make sure to log the output
|
|
||||||
aiProcess_ImproveCacheLocality |
|
|
||||||
aiProcess_RemoveRedundantMaterials |
|
|
||||||
aiProcess_FindInvalidData |
|
|
||||||
aiProcess_GenSmoothNormals |
|
|
||||||
aiProcess_GenUVCoords |
|
|
||||||
aiProcess_TransformUVCoords |
|
|
||||||
aiProcess_FlipUVs | // Maybe?
|
|
||||||
0
|
|
||||||
);
|
|
||||||
|
|
||||||
const char* errString = importer.GetErrorString();
|
|
||||||
if (errString[0] != '\0' || scene == nullptr) {
|
|
||||||
throw std::runtime_error(errString);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (scene->mFlags & AI_SCENE_FLAGS_INCOMPLETE) {
|
|
||||||
throw std::runtime_error(errString);
|
|
||||||
}
|
|
||||||
|
|
||||||
assert(scene->HasAnimations() == false);
|
|
||||||
assert(scene->HasCameras() == false);
|
|
||||||
assert(scene->HasLights() == false);
|
|
||||||
assert(scene->hasSkeletons() == false);
|
|
||||||
|
|
||||||
INFO("material count: {}, mesh count: {}", scene->mNumMaterials, scene->mNumMeshes);
|
|
||||||
|
|
||||||
std::map<int, std::shared_ptr<resources::Texture>> textures{};
|
|
||||||
|
|
||||||
for (int i = 0; i < scene->mNumMaterials; i++) {
|
|
||||||
const aiMaterial* m = scene->mMaterials[i];
|
|
||||||
INFO("Material {}:", i);
|
|
||||||
INFO(" Name: {}", m->GetName().C_Str());
|
|
||||||
for (int j = 0; j < m->mNumProperties; j++) {
|
|
||||||
const aiMaterialProperty* p = m->mProperties[j];
|
|
||||||
INFO(" prop {}, key: {}", j, p->mKey.C_Str());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (aiGetMaterialTextureCount(m, aiTextureType_DIFFUSE) >= 1) {
|
|
||||||
aiString texPath{};
|
|
||||||
aiGetMaterialTexture(m, aiTextureType_DIFFUSE, 0, &texPath);
|
|
||||||
INFO(" Diffuse tex: {}", texPath.C_Str());
|
|
||||||
std::filesystem::path absPath = path;
|
|
||||||
absPath = absPath.parent_path();
|
|
||||||
absPath /= texPath.C_Str();
|
|
||||||
try {
|
|
||||||
textures[i] = std::make_shared<resources::Texture>(absPath);
|
|
||||||
} catch (const std::runtime_error& e) {
|
|
||||||
textures[i] = parent->res.get<resources::Texture>("textures/white.png");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<std::shared_ptr<resources::Mesh>> meshes{};
|
|
||||||
std::vector<unsigned int> meshMaterialIndices{};
|
|
||||||
for (int i = 0; i < scene->mNumMeshes; i++) {
|
|
||||||
const aiMesh* m = scene->mMeshes[i];
|
|
||||||
meshMaterialIndices.push_back(m->mMaterialIndex);
|
|
||||||
std::vector<Vertex> vertices(m->mNumVertices);
|
|
||||||
std::vector<uint32_t> indices(m->mNumFaces * 3);
|
|
||||||
INFO("Mesh {}: vertex count {}", i, vertices.size());
|
|
||||||
INFO("Mesh {}: index count {}", i, indices.size());
|
|
||||||
|
|
||||||
for (int j = 0; j < vertices.size(); j++) {
|
|
||||||
Vertex v{};
|
|
||||||
v.pos.x = m->mVertices[j].x;
|
|
||||||
v.pos.y = m->mVertices[j].y;
|
|
||||||
v.pos.z = m->mVertices[j].z;
|
|
||||||
v.norm.x = m->mNormals[j].x;
|
|
||||||
v.norm.y = m->mNormals[j].y;
|
|
||||||
v.norm.z = m->mNormals[j].z;
|
|
||||||
vertices[j] = v;
|
|
||||||
}
|
|
||||||
if (m->mNumUVComponents[0] >= 2) {
|
|
||||||
for (int j = 0; j < vertices.size(); j++) {
|
|
||||||
vertices[j].uv.x = m->mTextureCoords[0][j].x;
|
|
||||||
vertices[j].uv.y = m->mTextureCoords[0][j].y;
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int j = 0; j < indices.size() / 3; j++) {
|
|
||||||
indices[j * 3 + 0] = m->mFaces[j].mIndices[0];
|
|
||||||
indices[j * 3 + 1] = m->mFaces[j].mIndices[1];
|
|
||||||
indices[j * 3 + 2] = m->mFaces[j].mIndices[2];
|
|
||||||
}
|
|
||||||
meshes.push_back(std::make_shared<resources::Mesh>(vertices, indices));
|
|
||||||
}
|
|
||||||
|
|
||||||
Object* obj = parent->createChild(scene->GetShortFilename(path.c_str()));
|
|
||||||
|
|
||||||
buildGraph(textures, meshes, meshMaterialIndices, scene->mRootNode, obj);
|
|
||||||
|
|
||||||
Assimp::DefaultLogger::kill();
|
|
||||||
return obj;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user