Remove stuff to rewrite

This commit is contained in:
bailwillharr 2022-12-01 19:08:21 +00:00
parent 60d1452f01
commit a278b7d035
26 changed files with 0 additions and 1530 deletions

View File

@ -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);
}
}

View File

@ -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;
};
}

View File

@ -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;
};
}

View File

@ -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) {}
};
}

View File

@ -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;
};
}

View File

@ -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;
};
}

View File

@ -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;
};
}

View File

@ -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();
};
}

View File

@ -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;
};
}

View File

@ -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;
};
}

View File

@ -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{};
};
}

View File

@ -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 };
};
}

View File

@ -1,11 +0,0 @@
#pragma once
#include "object.hpp"
#include <string>
namespace engine::util {
Object* loadAssimpMeshFromFile(Object* parent, const std::string& path);
}

View File

@ -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;
}
}

View File

@ -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);
}
}

View File

@ -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;
}
}

View File

@ -1,15 +0,0 @@
#include "components/custom.hpp"
namespace engine::components {
CustomComponent::CustomComponent(Object* parent) : Component(parent, TypeEnum::CUSTOM)
{
}
CustomComponent::~CustomComponent()
{
}
}

View File

@ -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);
}
}
}

View File

@ -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;
}
}
}

View File

@ -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

View File

@ -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

View File

@ -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];
}
}

View File

@ -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);
}
}

View File

@ -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;
}
}

View File

@ -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);
}
}

View File

@ -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;
}
}