Refactor and make Shader and Mesh managment systems

This commit is contained in:
Arnau Alier Torres 2025-05-07 15:47:13 +02:00
parent f7bf0f64a7
commit 52d34f48ab
38 changed files with 300 additions and 243 deletions

View File

@ -1,87 +0,0 @@
#pragma once
#include <string>
#include <vector>
#include "Deer/DataStore.h"
#include "Deer/Log.h"
#include "Deer/Path.h"
#include "Deer/Memory.h"
// File to manage Assets
// TODO: Delete Assets and set a custom method of loading
namespace Deer {
template <typename T>
struct Asset {
public:
Asset() : id(0), name("null") {}
Asset(uint32_t id, const std::filesystem::path& assetLocation)
: id(id), name(assetLocation) {
try {
uint32_t size;
uint8_t* data = DataStore::readFile(assetLocation, &size);
value = T::create(data, size);
delete[] data;
} catch (const std::string& error) {
DEER_CORE_ERROR("Error loading asset {0}\n{1}",
assetLocation.generic_string().c_str(),
error.c_str());
}
}
inline uint32_t getAssetID() const { return id; }
inline Path& getAssetLocation() { return name; }
inline T& getValue() { return value; }
private:
Path name;
uint32_t id;
Scope<T> value;
};
template <>
class Asset<void> {
public:
Asset() : id(0), name("null") {}
Asset(uint32_t id, const std::filesystem::path& assetLocation)
: id(id), name(assetLocation) {}
inline uint32_t getAssetID() const { return id; }
inline Path& getAssetLocation() { return name; }
Ref<void> value;
private:
uint32_t id;
Path name;
};
namespace AssetManager {
extern std::vector<Asset<void>> assets;
template <typename T>
inline Asset<T>& getAsset(uint32_t assetID) {
return *(Asset<T>*)&(assets[assetID]);
}
template <typename T>
inline uint32_t loadAsset(const std::filesystem::path& assetLocation) {
for (size_t id = 0; id < assets.size(); ++id) {
if (assets[id].getAssetLocation() == assetLocation) return id;
}
uint32_t assetID = assets.size();
Asset<T> asset(assetID, assetLocation);
assets.push_back(*(Asset<void>*)&(asset));
return assetID;
}
inline const std::filesystem::path getAssetLocation(uint32_t assetID) {
return assets[assetID].getAssetLocation();
}
} // namespace AssetManager
} // namespace Deer

View File

@ -17,6 +17,7 @@
#define DEER_MESH_PATH "meshes" #define DEER_MESH_PATH "meshes"
#define DEER_MESH_EXTENSION ".dmesh" #define DEER_MESH_EXTENSION ".dmesh"
#define DEER_SHADER_EXTENSION ".glsl"
#define DEER_BIN_PATH "bin" #define DEER_BIN_PATH "bin"
#define DEER_TEMP_PATH "tmp" #define DEER_TEMP_PATH "tmp"

View File

@ -12,16 +12,20 @@
#define MAX_TEXTURE_BINDINGS 4 #define MAX_TEXTURE_BINDINGS 4
namespace Deer { namespace Deer {
struct MeshRenderComponent { struct MeshComponent {
MeshRenderComponent() = default; MeshComponent() = default;
MeshRenderComponent(const MeshRenderComponent&) = default; MeshComponent(uint16_t _meshId) : meshId(_meshId) { }
MeshRenderComponent(uint32_t _mesh, uint32_t _shader) : shaderAssetID(_shader), meshAssetID(_mesh) { } MeshComponent(const MeshComponent&) = default;
Ref<Shader> shader; uint16_t meshId;
Ref<VertexArray> vertexArray; };
uint32_t shaderAssetID = 0; struct ShaderComponent {
uint32_t meshAssetID = 0; ShaderComponent() = default;
ShaderComponent(uint16_t _shaderId) : shaderId(_shaderId) { }
ShaderComponent(const ShaderComponent&) = default;
uint16_t shaderId;
}; };
struct TextureBindingComponent { struct TextureBindingComponent {

View File

@ -4,6 +4,8 @@
#include "Deer/Path.h" #include "Deer/Path.h"
#include "DeerRender/Render/VertexArray.h" #include "DeerRender/Render/VertexArray.h"
#define SCENE_MAX_MESH_COUNT 1024
namespace Deer { namespace Deer {
// The real position is the axis divided by 256, the model precition is 1 / 256.0f // The real position is the axis divided by 256, the model precition is 1 / 256.0f
struct VertexPosition { struct VertexPosition {
@ -56,8 +58,11 @@ namespace Deer {
} }
}; };
namespace Mesh { namespace MeshManager {
Ref<VertexArray> loadModelToGPU(const MeshData&); uint16_t loadModel(const MeshData&);
VertexArray& getModel(uint16_t model_id);
void unloadAllModels();
} }
namespace DataStore { namespace DataStore {

View File

@ -21,6 +21,7 @@ namespace Deer {
static Ref<Shader> create(const std::string& filePath); static Ref<Shader> create(const std::string& filePath);
static Ref<Shader> create(uint8_t* data, uint32_t size); static Ref<Shader> create(uint8_t* data, uint32_t size);
static Ref<Shader> create(const std::string& vertexSrc, const std::string& fragmentSrc);
static Shader* create(const std::string& vertexSrc, const std::string& fragmentSrc);
}; };
} }

View File

@ -19,8 +19,10 @@ namespace Deer {
virtual const Ref<IndexBuffer>& getIndexBuffer() = 0; virtual const Ref<IndexBuffer>& getIndexBuffer() = 0;
static Ref<VertexArray> create(); //static Ref<VertexArray> create();
static Ref<VertexArray> create(uint8_t* data, uint32_t size); //static Ref<VertexArray> create(uint8_t* data, uint32_t size);
static VertexArray* create();
static VertexArray* create(uint8_t* data, uint32_t size);
}; };
} }

View File

@ -0,0 +1,36 @@
#pragma once
#include "DeerRender/Render/Shader.h"
#include "Deer/Path.h"
#include <cstdint>
#define SCENE_MAX_SHADER_COUNT 1024
namespace Deer {
struct ShaderData {
std::string vertexShader;
std::string fragmentShader;
ShaderData() = default;
~ShaderData() = default;
ShaderData(const ShaderData&) = delete;
ShaderData& operator=(const ShaderData&) = delete;
void freeData() {
vertexShader.clear();
fragmentShader.clear();
}
};
namespace ShaderManager {
uint16_t loadShader(const ShaderData&);
Shader& getShader(uint16_t);
void unloadAllShaders();
}
namespace DataStore {
void loadShader(ShaderData& data, const Path& name);
} // namespace DataStore
} // namespace Deer

View File

@ -1,6 +0,0 @@
#include "Deer/Asset.h"
namespace Deer {
std::vector<Asset<void>> AssetManager::assets;
}

View File

@ -55,10 +55,10 @@ namespace Deer {
getComponent<TransformComponent>(); getComponent<TransformComponent>();
#ifdef DEER_RENDER #ifdef DEER_RENDER
if (m_environment->m_registry.any_of<MeshRenderComponent>( if (m_environment->m_registry.any_of<MeshComponent>(
m_entityHandle)) m_entityHandle))
creation.addComponent<MeshRenderComponent>( creation.addComponent<MeshComponent>(
getComponent<MeshRenderComponent>()); getComponent<MeshComponent>());
if (m_environment->m_registry.any_of<CameraComponent>(m_entityHandle)) if (m_environment->m_registry.any_of<CameraComponent>(m_entityHandle))
creation.addComponent<CameraComponent>( creation.addComponent<CameraComponent>(

View File

@ -1,7 +1,6 @@
#include "Deer/Enviroment.h" #include "Deer/Enviroment.h"
#include "Deer/Application.h" #include "Deer/Application.h"
#include "Deer/Asset.h"
#include "Deer/Components.h" #include "Deer/Components.h"
#include "Deer/Log.h" #include "Deer/Log.h"
#include "DeerRender/Render/Render.h" #include "DeerRender/Render/Render.h"

View File

@ -17,12 +17,16 @@
#ifdef DEER_RENDER #ifdef DEER_RENDER
#include "DeerRender/Voxels/VoxelWorldRenderData.h" #include "DeerRender/Voxels/VoxelWorldRenderData.h"
#include "DeerRender/Mesh.h"
#endif #endif
namespace Deer { namespace Deer {
void Scene::clear() { void Scene::clear() {
environment.clear(); environment.clear();
VoxelWorld::clear(); VoxelWorld::clear();
#ifdef DEER_RENDER
MeshManager::unloadAllModels();
#endif
} }
bool Scene::getExecutingState() { bool Scene::getExecutingState() {

View File

@ -48,7 +48,7 @@ namespace Deer {
#ifdef DEER_RENDER #ifdef DEER_RENDER
if (!is_server_serialization) { if (!is_server_serialization) {
saveComponent<Archive, MeshRenderComponent>( saveComponent<Archive, MeshComponent>(
archive, "meshRenderComponent", entity); archive, "meshRenderComponent", entity);
saveComponent<Archive, CameraComponent>(archive, "cameraComponent", saveComponent<Archive, CameraComponent>(archive, "cameraComponent",
entity); entity);
@ -76,7 +76,7 @@ namespace Deer {
entity.setParent(m_entity.env->getEntity(rc.parent_id)); entity.setParent(m_entity.env->getEntity(rc.parent_id));
#ifdef DEER_RENDER #ifdef DEER_RENDER
if (!is_server_serialization) { if (!is_server_serialization) {
loadComponent<Archive, MeshRenderComponent>( loadComponent<Archive, MeshComponent>(
archive, "meshRenderComponent", entity); archive, "meshRenderComponent", entity);
loadComponent<Archive, CameraComponent>(archive, "cameraComponent", loadComponent<Archive, CameraComponent>(archive, "cameraComponent",
entity); entity);

View File

@ -1,10 +1,44 @@
#include "DeerRender/Mesh.h" #include "DeerRender/Mesh.h"
#include "Deer/Log.h" #include "Deer/Log.h"
#include "DeerRender/Render/Buffer.h"
namespace Deer { namespace Deer {
Ref<VertexArray> Mesh::loadModelToGPU(const MeshData& data) { namespace MeshManager {
Ref<VertexArray> vertexArray = VertexArray::create(); size_t minModelId = 0;
VertexArray* meshes[SCENE_MAX_MESH_COUNT]{};
VertexArray* loadModelToGPU(const MeshData& data);
}
void MeshManager::unloadAllModels() {
for (uint16_t i = 0; i < minModelId; i++) {
delete meshes[i];
meshes[i] = nullptr;
}
minModelId = 0;
}
uint16_t MeshManager::loadModel(const MeshData& meshData) {
if (minModelId >= SCENE_MAX_MESH_COUNT) {
DEER_CORE_ERROR("Max model loaded into a scene");
return -1;
}
uint16_t modelId = minModelId;
minModelId++;
meshes[modelId] = loadModelToGPU(meshData);
return modelId;
}
VertexArray& MeshManager::getModel(uint16_t model_id) {
DEER_CORE_ASSERT(model_id > 0 && model_id < minModelId, "Invalid model id, id is not loaded");
return *meshes[model_id];
}
VertexArray* MeshManager::loadModelToGPU(const MeshData& data) {
VertexArray* vertexArray = VertexArray::create();
vertexArray->bind(); vertexArray->bind();
Ref<VertexBuffer> vertexPositionBuffer = VertexBuffer::create(data.vertexPositionsData, data.vertexCount * sizeof(VertexPosition)); Ref<VertexBuffer> vertexPositionBuffer = VertexBuffer::create(data.vertexPositionsData, data.vertexCount * sizeof(VertexPosition));

View File

@ -1,21 +0,0 @@
#include "MeshUtils.h"
#include "DeerRender/Render/Buffer.h"
#include "DeerRender/Render/VertexArray.h"
namespace Deer {
Ref<VertexArray> MeshUtils::createMesh(int vertexCount, float* vertices, int indexCount, unsigned int* m_indices) {
Ref<VertexBuffer> vBuffer = VertexBuffer::create(vertices, vertexCount * sizeof(float));
Ref<IndexBuffer> iBuffer = IndexBuffer::create(m_indices, indexCount * sizeof(unsigned int), IndexDataType::Unsigned_Int);
BufferLayout layout({
{"a_Position", DataType::Float3, ShaderDataType::FloatingPoint}
});
vBuffer->setLayout(layout);
Ref<VertexArray> vertexArray = VertexArray::create();
vertexArray->addVertexBuffer(vBuffer);
vertexArray->setIndexBuffer(iBuffer);
return vertexArray;
}
}

View File

@ -1,12 +0,0 @@
#pragma once
#include "Deer/Memory.h"
namespace Deer {
class VertexArray;
class MeshUtils {
public:
static Ref<VertexArray> createMesh(int vertexCount, float* vertices, int indexCount, unsigned int* m_indices);
};
}

View File

@ -12,13 +12,13 @@ namespace Deer {
} }
void Render::submit(const Ref<VertexArray>& vertexArray) { void Render::submit(VertexArray& vertexArray) {
vertexArray->bind(); vertexArray.bind();
RenderCommand::drawIndex(vertexArray); RenderCommand::drawIndex(vertexArray);
} }
void Render::submitLine(const Ref<VertexArray>& vertexArray) { void Render::submitLine(VertexArray& vertexArray) {
vertexArray->bind(); vertexArray.bind();
RenderCommand::drawLines(vertexArray); RenderCommand::drawLines(vertexArray);
} }

View File

@ -9,8 +9,8 @@ namespace Deer {
static void beginExecution(); static void beginExecution();
static void endExecution(); static void endExecution();
static void submit(const Ref<VertexArray>& vertexArray); static void submit(VertexArray& vertexArray);
static void submitLine(const Ref<VertexArray>& vertexArray); static void submitLine(VertexArray& vertexArray);
static RenderAPI::API getAPI() { return RenderAPI::getAPI(); } static RenderAPI::API getAPI() { return RenderAPI::getAPI(); }
}; };
} }

View File

@ -20,8 +20,8 @@ namespace Deer {
virtual void setBackfaceCulling(bool enable) = 0; virtual void setBackfaceCulling(bool enable) = 0;
virtual void clear() = 0; virtual void clear() = 0;
virtual void drawIndex(const Ref<VertexArray>& vertexArray) = 0; virtual void drawIndex(VertexArray& vertexArray) = 0;
virtual void drawLines(const Ref<VertexArray>& vertexArray) = 0; virtual void drawLines(VertexArray& vertexArray) = 0;
inline static API getAPI() { return s_API; } inline static API getAPI() { return s_API; }
private: private:

View File

@ -1,6 +1,7 @@
#pragma once #pragma once
#include "Deer/Memory.h" #include "Deer/Memory.h"
#include "DeerRender/Render/RenderAPI.h" #include "DeerRender/Render/RenderAPI.h"
#include "DeerRender/Render/VertexArray.h"
#include "glm/glm.hpp" #include "glm/glm.hpp"
@ -18,11 +19,11 @@ namespace Deer {
s_renderAPI->clear(); s_renderAPI->clear();
} }
static inline void drawIndex(const Ref<VertexArray>& vertexArray) { static inline void drawIndex(VertexArray& vertexArray) {
s_renderAPI->drawIndex(vertexArray); s_renderAPI->drawIndex(vertexArray);
} }
static inline void drawLines(const Ref<VertexArray>& vertexArray) { static inline void drawLines(VertexArray& vertexArray) {
s_renderAPI->drawLines(vertexArray); s_renderAPI->drawLines(vertexArray);
} }

View File

@ -7,15 +7,15 @@
namespace Deer { namespace Deer {
namespace RenderUtils { namespace RenderUtils {
Ref<VertexArray> m_lineVertexArray; Scope<VertexArray> m_lineVertexArray;
Ref<VertexArray> m_faceVertexArray; Scope<VertexArray> m_faceVertexArray;
Ref<Shader> m_lineShader; Scope<Shader> m_lineShader;
Ref<Shader> m_faceShader; Scope<Shader> m_faceShader;
Ref<VertexArray> genLineVertexArray(); Scope<VertexArray> genLineVertexArray();
Ref<VertexArray> genFaceVertexArray(); Scope<VertexArray> genFaceVertexArray();
Ref<Shader> getLineShader(); Scope<Shader> getLineShader();
Ref<Shader> getFaceShader(); Scope<Shader> getFaceShader();
} }
void RenderUtils::initializeRenderUtils() { void RenderUtils::initializeRenderUtils() {
@ -25,10 +25,10 @@ namespace Deer {
m_faceShader = getFaceShader(); m_faceShader = getFaceShader();
} }
Ref<VertexArray> RenderUtils::genLineVertexArray() { Scope<VertexArray> RenderUtils::genLineVertexArray() {
unsigned int vertices[2] = { 0, 1 }; unsigned int vertices[2] = { 0, 1 };
Ref<VertexArray> vertexArray = VertexArray::create(); Scope<VertexArray> vertexArray = Scope<VertexArray>(VertexArray::create());
vertexArray->bind(); vertexArray->bind();
Ref<VertexBuffer> vertexBuffer = VertexBuffer::create(vertices, sizeof(vertices)); Ref<VertexBuffer> vertexBuffer = VertexBuffer::create(vertices, sizeof(vertices));
@ -45,7 +45,7 @@ namespace Deer {
return vertexArray; return vertexArray;
} }
Ref<Shader> RenderUtils::getLineShader() { Scope<Shader> RenderUtils::getLineShader() {
std::string vertexSrc = R"( std::string vertexSrc = R"(
#version 410 core #version 410 core
@ -82,10 +82,10 @@ void main()
fragColor = vec4(u_color, 1.0); fragColor = vec4(u_color, 1.0);
})"; })";
return Shader::create(vertexSrc, fragmentSrc); return Scope<Shader>(Shader::create(vertexSrc, fragmentSrc));
} }
Ref<VertexArray> RenderUtils::genFaceVertexArray() { Scope<VertexArray> RenderUtils::genFaceVertexArray() {
unsigned int vertices[4] = { unsigned int vertices[4] = {
0, 1, 2, 3 0, 1, 2, 3
}; };
@ -93,7 +93,7 @@ void main()
0, 2, 1, 1, 2, 3 0, 2, 1, 1, 2, 3
}; };
Ref<VertexArray> vertexArray = VertexArray::create(); Scope<VertexArray> vertexArray = Scope<VertexArray>(VertexArray::create());
vertexArray->bind(); vertexArray->bind();
Ref<VertexBuffer> vertexBuffer = VertexBuffer::create(vertices, sizeof(vertices)); Ref<VertexBuffer> vertexBuffer = VertexBuffer::create(vertices, sizeof(vertices));
@ -110,7 +110,7 @@ void main()
return vertexArray; return vertexArray;
} }
Ref<Shader> RenderUtils::getFaceShader() { Scope<Shader> RenderUtils::getFaceShader() {
std::string vertexSrc = R"( std::string vertexSrc = R"(
#version 410 core #version 410 core
@ -175,7 +175,7 @@ void main()
fragColor = color; fragColor = color;
})"; })";
return Shader::create(vertexSrc, fragmentSrc); return Scope<Shader>(Shader::create(vertexSrc, fragmentSrc));
} }
} }

View File

@ -6,10 +6,10 @@ namespace Deer {
class Shader; class Shader;
namespace RenderUtils { namespace RenderUtils {
extern Ref<VertexArray> m_lineVertexArray; extern Scope<VertexArray> m_lineVertexArray;
extern Ref<VertexArray> m_faceVertexArray; extern Scope<VertexArray> m_faceVertexArray;
extern Ref<Shader> m_lineShader; extern Scope<Shader> m_lineShader;
extern Ref<Shader> m_faceShader; extern Scope<Shader> m_faceShader;
void initializeRenderUtils(); void initializeRenderUtils();
} }

View File

@ -1,11 +1,12 @@
#include "Deer/Enviroment.h" #include "Deer/Enviroment.h"
#include "Deer/Application.h" #include "Deer/Application.h"
#include "Deer/Asset.h"
#include "Deer/Components.h" #include "Deer/Components.h"
#include "Deer/Voxel.h" #include "Deer/Voxel.h"
#include "DeerRender/Shader.h"
#include "DeerRender/Mesh.h"
#include "DeerRender/Render/Render.h" #include "DeerRender/Render/Render.h"
#include "DeerRender/Render/RenderUtils.h" #include "DeerRender/Render/RenderUtils.h"
#include "DeerRender/Render/Texture.h" #include "DeerRender/Render/Texture.h"
@ -21,30 +22,26 @@ namespace Deer {
// Lets invert the z axis for engine convenience // Lets invert the z axis for engine convenience
glm::mat4 cameraProjectionMatrix = projectionMatrix * invertZ * camMatrix; glm::mat4 cameraProjectionMatrix = projectionMatrix * invertZ * camMatrix;
{ {
auto view = m_registry.view<MeshRenderComponent, TagComponent>(); auto view = m_registry.view<MeshComponent, ShaderComponent, TagComponent>();
for (auto entityId : view) { for (auto entityId : view) {
auto& meshRender = view.get<MeshRenderComponent>(entityId); auto& meshComponent = view.get<MeshComponent>(entityId);
//if (meshRender.shaderAssetID == 0) auto& shaderComponent = view.get<ShaderComponent>(entityId);
// continue; auto& tagComponent = view.get<TagComponent>(entityId);
//if (meshRender.meshAssetID == 0)
// continue;
auto& tag = view.get<TagComponent>(entityId);
Entity& entity = getEntity(tag.entityUID);
Entity& entity = getEntity(tagComponent.entityUID);
glm::mat4 matrix = entity.getWorldMatrix(); glm::mat4 matrix = entity.getWorldMatrix();
//Asset<Shader>& shaderAsset = AssetManager::getAsset<Shader>(meshRender.shaderAssetID);
meshRender.shader->bind(); Shader& shader = ShaderManager::getShader(shaderComponent.shaderId);
meshRender.shader->uploadUniformMat4("u_viewMatrix", cameraProjectionMatrix);
meshRender.shader->uploadUniformMat4("u_worldMatrix", matrix);
meshRender.shader->uploadUniformInt("u_objectID", tag.entityUID);
//Asset<VertexArray> meshAsset = AssetManager::getAsset<VertexArray>(meshRender.meshAssetID); shader.bind();
meshRender.vertexArray->bind(); shader.uploadUniformMat4("u_viewMatrix", cameraProjectionMatrix);
shader.uploadUniformMat4("u_worldMatrix", matrix);
shader.uploadUniformInt("u_objectID", entity.getId());
Render::submit(meshRender.vertexArray); VertexArray& vertexArray = MeshManager::getModel(meshComponent.meshId);
vertexArray.bind();
Render::submit(vertexArray);
} }
} }
@ -57,13 +54,13 @@ namespace Deer {
RenderUtils::m_lineShader->uploadUniformFloat3("u_posA", glm::vec3(x, 0, 0)); RenderUtils::m_lineShader->uploadUniformFloat3("u_posA", glm::vec3(x, 0, 0));
RenderUtils::m_lineShader->uploadUniformFloat3("u_posB", glm::vec3(x, 0, CHUNK_SIZE_Z)); RenderUtils::m_lineShader->uploadUniformFloat3("u_posB", glm::vec3(x, 0, CHUNK_SIZE_Z));
Render::submitLine(RenderUtils::m_lineVertexArray); Render::submitLine(*RenderUtils::m_lineVertexArray.get());
} }
for (int z = 0; z < CHUNK_SIZE_Z + 1; z++) { for (int z = 0; z < CHUNK_SIZE_Z + 1; z++) {
RenderUtils::m_lineShader->uploadUniformFloat3("u_posA", glm::vec3(0, 0, z)); RenderUtils::m_lineShader->uploadUniformFloat3("u_posA", glm::vec3(0, 0, z));
RenderUtils::m_lineShader->uploadUniformFloat3("u_posB", glm::vec3(CHUNK_SIZE_X, 0, z)); RenderUtils::m_lineShader->uploadUniformFloat3("u_posB", glm::vec3(CHUNK_SIZE_X, 0, z));
Render::submitLine(RenderUtils::m_lineVertexArray); Render::submitLine(*RenderUtils::m_lineVertexArray.get());
} }
} }
@ -110,7 +107,7 @@ namespace Deer {
RenderUtils::m_lineShader->uploadUniformFloat3("u_posA", cameraAxisPoints[posA]); RenderUtils::m_lineShader->uploadUniformFloat3("u_posA", cameraAxisPoints[posA]);
RenderUtils::m_lineShader->uploadUniformFloat3("u_posB", cameraAxisPoints[posB]); RenderUtils::m_lineShader->uploadUniformFloat3("u_posB", cameraAxisPoints[posB]);
Render::submitLine(RenderUtils::m_lineVertexArray); Render::submitLine(*RenderUtils::m_lineVertexArray);
} }
} }
@ -122,7 +119,7 @@ namespace Deer {
RenderUtils::m_lineShader->uploadUniformFloat3("u_posA", cameraAxisPoints[posA]); RenderUtils::m_lineShader->uploadUniformFloat3("u_posA", cameraAxisPoints[posA]);
RenderUtils::m_lineShader->uploadUniformFloat3("u_posB", cameraAxisPoints[posB]); RenderUtils::m_lineShader->uploadUniformFloat3("u_posB", cameraAxisPoints[posB]);
Render::submitLine(RenderUtils::m_lineVertexArray); Render::submitLine(*RenderUtils::m_lineVertexArray);
} }
} }
@ -134,7 +131,7 @@ namespace Deer {
RenderUtils::m_lineShader->uploadUniformFloat3("u_posA", cameraAxisPoints[posA]); RenderUtils::m_lineShader->uploadUniformFloat3("u_posA", cameraAxisPoints[posA]);
RenderUtils::m_lineShader->uploadUniformFloat3("u_posB", cameraAxisPoints[posB]); RenderUtils::m_lineShader->uploadUniformFloat3("u_posB", cameraAxisPoints[posB]);
Render::submitLine(RenderUtils::m_lineVertexArray); Render::submitLine(*RenderUtils::m_lineVertexArray);
} }
} }
} }

View File

@ -139,7 +139,7 @@ namespace Deer {
RenderUtils::m_faceShader->uploadUniformFloat3( RenderUtils::m_faceShader->uploadUniformFloat3(
"u_posD", face.positions[3]); "u_posD", face.positions[3]);
Render::submit(RenderUtils::m_faceVertexArray); Render::submit(*RenderUtils::m_faceVertexArray);
} }
} }
@ -154,7 +154,7 @@ namespace Deer {
RenderUtils::m_lineShader->uploadUniformFloat3("u_posA", line[0]); RenderUtils::m_lineShader->uploadUniformFloat3("u_posA", line[0]);
RenderUtils::m_lineShader->uploadUniformFloat3("u_posB", line[1]); RenderUtils::m_lineShader->uploadUniformFloat3("u_posB", line[1]);
Render::submitLine(RenderUtils::m_lineVertexArray); Render::submitLine(*RenderUtils::m_lineVertexArray);
} }
} }

View File

@ -4,7 +4,7 @@
namespace Deer{ namespace Deer{
template<class Archive> template<class Archive>
void save(Archive& archive, void save(Archive& archive,
MeshRenderComponent const& meshRender) { MeshComponent const& meshRender) {
// TO IMPLEMENT // TO IMPLEMENT
/* /*
@ -17,7 +17,7 @@ namespace Deer{
template<class Archive> template<class Archive>
void load(Archive& archive, void load(Archive& archive,
MeshRenderComponent& meshRender) { MeshComponent& meshRender) {
// TO IMPLEMENT // TO IMPLEMENT
/* /*

View File

@ -0,0 +1,61 @@
#include "DeerRender/Shader.h"
#include "Deer/DataStore.h"
#include <unordered_map>
namespace Deer {
namespace DataStore {
std::unordered_map<std::string, std::string> preProcess(const std::string& source);
}
void DataStore::loadShader(ShaderData& shader_data, const Path& name) {
Path realName;
realName = name.string() + DEER_SHADER_EXTENSION;
uint32_t size;
uint8_t* data = DataStore::readFile(realName, &size);
DataStore::loadFileData(DEER_SHADER_PATH, realName, &data, &size);
std::string str_data((char*)data, size);
DataStore::freeFileData(data);
std::unordered_map<std::string, std::string> types = preProcess(str_data);
shader_data.freeData();
if (types.contains("vertex")) {
shader_data.vertexShader = types["vertex"];
}
if (types.contains("fragment")) {
shader_data.fragmentShader = types["fragment"];
}
}
std::unordered_map<std::string, std::string> preProcess(const std::string& source) {
std::unordered_map<std::string, std::string> shaderSource;
const std::string typeToken = "#type ";
size_t pos = 0;
while (pos < source.size()) {
size_t typePos = source.find(typeToken, pos);
if (typePos == std::string::npos) break;
size_t typeEnd = source.find_first_of("\n\r", typePos);
if (typeEnd == std::string::npos) break;
std::string shaderType = source.substr(typePos + typeToken.size(), typeEnd - typePos - typeToken.size());
size_t nextTypePos = source.find(typeToken, typeEnd);
std::string shaderSourceStr = source.substr(typeEnd + 1, nextTypePos - typeEnd - 1);
shaderSource[shaderType] = shaderSourceStr;
pos = nextTypePos;
}
return shaderSource;
}
}

View File

@ -0,0 +1,38 @@
#include "DeerRender/Shader.h"
#include "Deer/Log.h"
namespace Deer {
namespace ShaderManager {
size_t minShaderId = 0;
Shader* shaders[SCENE_MAX_SHADER_COUNT]{};
}
void ShaderManager::unloadAllShaders() {
for (uint16_t i = 0; i < minShaderId; i++) {
delete shaders[i];
shaders[i] = nullptr;
}
minShaderId = 0;
}
uint16_t ShaderManager::loadShader(const ShaderData& data) {
if (minShaderId >= SCENE_MAX_SHADER_COUNT) {
DEER_CORE_ERROR("Max shader loaded into a scene");
return -1;
}
uint16_t shaderId = minShaderId;
minShaderId++;
shaders[shaderId] = Shader::create(data.vertexShader, data.fragmentShader);
return shaderId;
}
Shader& ShaderManager::getShader(uint16_t shaderId) {
DEER_CORE_ASSERT(shaderId > 0 && shaderId < minShaderId, "Invalid shader id, id is not loaded");
return *shaders[shaderId];
}
}

View File

@ -1,7 +1,6 @@
#include "Deer/VoxelWorld.h" #include "Deer/VoxelWorld.h"
#include "Deer/Application.h" #include "Deer/Application.h"
#include "Deer/Asset.h"
#include "Deer/Components.h" #include "Deer/Components.h"
#include "Deer/Log.h" #include "Deer/Log.h"
#include "Deer/Memory.h" #include "Deer/Memory.h"
@ -80,7 +79,7 @@ namespace Deer {
shader->uploadUniformInt("u_chunkID_y", chunkID.y); shader->uploadUniformInt("u_chunkID_y", chunkID.y);
shader->uploadUniformInt("u_chunkID_z", chunkID.z); shader->uploadUniformInt("u_chunkID_z", chunkID.z);
Render::submit(chunkRender.solidVoxel); Render::submit(*chunkRender.solidVoxel);
} }
} }
} // namespace Deer } // namespace Deer

View File

@ -10,7 +10,7 @@
namespace Deer { namespace Deer {
struct ChunkRender { struct ChunkRender {
Ref<VertexArray> solidVoxel; Scope<VertexArray> solidVoxel;
bool hasData = false; bool hasData = false;
}; };

View File

@ -1,7 +1,6 @@
#include "Deer/VoxelWorld.h" #include "Deer/VoxelWorld.h"
#include "Deer/Voxels/Chunk.h" #include "Deer/Voxels/Chunk.h"
#include "Deer/Application.h" #include "Deer/Application.h"
#include "Deer/Asset.h"
#include "Deer/Components.h" #include "Deer/Components.h"
#include "Deer/Voxels/VoxelWorldData.h" #include "Deer/Voxels/VoxelWorldData.h"

View File

@ -1,5 +1,4 @@
#include "Deer/Application.h" #include "Deer/Application.h"
#include "Deer/Asset.h"
#include "Deer/Components.h" #include "Deer/Components.h"
#include "Deer/VoxelWorld.h" #include "Deer/VoxelWorld.h"
#include "Deer/Voxels/Chunk.h" #include "Deer/Voxels/Chunk.h"
@ -34,7 +33,7 @@ namespace Deer {
} }
// Pass the data to the GPU // Pass the data to the GPU
Ref<VertexArray> va = VertexArray::create(); Scope<VertexArray> va = Scope<VertexArray>(VertexArray::create());
va->bind(); va->bind();
Ref<VertexBuffer> vb = VertexBuffer::create( Ref<VertexBuffer> vb = VertexBuffer::create(
vertexData.data(), vertexData.data(),
@ -87,7 +86,7 @@ namespace Deer {
// Update the data to the chunk render // Update the data to the chunk render
int id = worldProps.getWorldChunkID(nextChunk); int id = worldProps.getWorldChunkID(nextChunk);
ChunkRender& chunkRender = chunksRender[id]; ChunkRender& chunkRender = chunksRender[id];
chunkRender.solidVoxel = va; chunkRender.solidVoxel = std::move(va);
chunkRender.hasData = true; chunkRender.hasData = true;
} }

View File

@ -48,11 +48,13 @@ namespace Deer {
glDisable(GL_CULL_FACE); glDisable(GL_CULL_FACE);
} }
void OpenGLRenderAPI::drawIndex(const Ref<VertexArray>& vertexArray) { void OpenGLRenderAPI::drawIndex(VertexArray& vertexArray) {
glDrawElements(GL_TRIANGLES, vertexArray->getIndexBuffer()->getCount(), getOpenGLIndexDataType(vertexArray->getIndexBuffer()->getIndexDataType()), nullptr); const Ref<IndexBuffer>& ib = vertexArray.getIndexBuffer();
glDrawElements(GL_TRIANGLES, ib->getCount(), getOpenGLIndexDataType(ib->getIndexDataType()), nullptr);
} }
void OpenGLRenderAPI::drawLines(const Ref<VertexArray>& vertexArray) { void OpenGLRenderAPI::drawLines(VertexArray& vertexArray) {
glDrawElements(GL_LINES, vertexArray->getIndexBuffer()->getCount(), getOpenGLIndexDataType(vertexArray->getIndexBuffer()->getIndexDataType()), nullptr); const Ref<IndexBuffer>& ib = vertexArray.getIndexBuffer();
glDrawElements(GL_LINES, ib->getCount(), getOpenGLIndexDataType(ib->getIndexDataType()), nullptr);
} }
} }

View File

@ -11,8 +11,8 @@ namespace Deer {
void setBackfaceCulling(bool enable) override; void setBackfaceCulling(bool enable) override;
void clear() override; void clear() override;
void drawIndex(const Ref<VertexArray>& vertexArray) override; void drawIndex(VertexArray& vertexArray) override;
void drawLines(const Ref<VertexArray>& vertexArray) override; void drawLines(VertexArray& vertexArray) override;
}; };
} }

View File

@ -21,8 +21,8 @@ namespace Deer {
return Ref<Shader>(new OpenGLShader(data, size)); return Ref<Shader>(new OpenGLShader(data, size));
} }
Ref<Shader> Shader::create(const std::string& vertexSrc, const std::string& fragmentSrc) { Shader* Shader::create(const std::string& vertexSrc, const std::string& fragmentSrc) {
return Ref<Shader>(new OpenGLShader(vertexSrc, fragmentSrc)); return new OpenGLShader(vertexSrc, fragmentSrc);
} }
OpenGLShader::OpenGLShader(const std::string& filePath) { OpenGLShader::OpenGLShader(const std::string& filePath) {

View File

@ -26,6 +26,7 @@ namespace Deer {
private: private:
std::string readFile(const std::string& source); std::string readFile(const std::string& source);
std::unordered_map<unsigned int, std::string> preProcess(const std::string& source); std::unordered_map<unsigned int, std::string> preProcess(const std::string& source);
void compile(const std::string& vertexSrc, const std::string& fragmentSrc); void compile(const std::string& vertexSrc, const std::string& fragmentSrc);
unsigned int m_shaderID; unsigned int m_shaderID;
}; };

View File

@ -7,12 +7,12 @@
#include "GLFW/glfw3.h" #include "GLFW/glfw3.h"
namespace Deer { namespace Deer {
Ref<VertexArray> VertexArray::create() { VertexArray* VertexArray::create() {
return Ref<VertexArray>(new OpenGLVertexArray()); return new OpenGLVertexArray();
} }
Ref<VertexArray> VertexArray::create(uint8_t* data, uint32_t size) { VertexArray* VertexArray::create(uint8_t* data, uint32_t size) {
return Ref<VertexArray>(new OpenGLVertexArray(data, size)); return new OpenGLVertexArray(data, size);
} }
OpenGLVertexArray::OpenGLVertexArray() { OpenGLVertexArray::OpenGLVertexArray() {

View File

@ -2,7 +2,6 @@
#include "DeerRender/Render/VertexArray.h" #include "DeerRender/Render/VertexArray.h"
#include "DeerRender/Render/Buffer.h" #include "DeerRender/Render/Buffer.h"
#include <vector> #include <vector>
#include <string> #include <string>

View File

@ -57,13 +57,14 @@ namespace Deer {
Environment& env = Scene::environment; Environment& env = Scene::environment;
Entity& exampleObject = env.createEntity("Example"); Entity& exampleObject = env.createEntity("Example");
MeshRenderComponent& renderComponent = exampleObject.addComponent<MeshRenderComponent>(); MeshComponent& renderComponent = exampleObject.addComponent<MeshComponent>();
MeshData meshData; MeshData meshData;
DataStore::loadModel(meshData, "example"); DataStore::loadModel(meshData, "example");
renderComponent.shader = Shader::create(DataStore::rootPath / DEER_SHADER_PATH / "shader.glsl"); renderComponent.meshId = MeshManager::loadModel(meshData);
renderComponent.vertexArray = Mesh::loadModelToGPU(meshData); // Shader::create(DataStore::rootPath / DEER_SHADER_PATH / "shader.glsl");
//renderComponent.vertexArray = Mesh::loadModelToGPU(meshData);
return 0; return 0;
} }

View File

@ -16,7 +16,7 @@ DockId=0x00000004,1
[Window][Game Window] [Window][Game Window]
Pos=258,24 Pos=258,24
Size=620,403 Size=620,474
Collapsed=0 Collapsed=0
DockId=0x00000006,0 DockId=0x00000006,0
@ -28,13 +28,13 @@ DockId=0x00000001,0
[Window][Terrain Editor] [Window][Terrain Editor]
Pos=880,24 Pos=880,24
Size=400,403 Size=400,474
Collapsed=0 Collapsed=0
DockId=0x00000004,1 DockId=0x00000004,1
[Window][Viewport] [Window][Viewport]
Pos=258,24 Pos=258,24
Size=620,403 Size=620,474
Collapsed=0 Collapsed=0
DockId=0x00000006,1 DockId=0x00000006,1
@ -57,14 +57,14 @@ Collapsed=0
DockId=0x00000008,1 DockId=0x00000008,1
[Window][MeshExplorer] [Window][MeshExplorer]
Pos=0,429 Pos=0,500
Size=1280,291 Size=1280,220
Collapsed=0 Collapsed=0
DockId=0x00000008,0 DockId=0x00000008,0
[Window][TreePannel] [Window][TreePannel]
Pos=0,24 Pos=0,24
Size=256,403 Size=256,474
Collapsed=0 Collapsed=0
DockId=0x00000005,0 DockId=0x00000005,0
@ -80,7 +80,7 @@ Collapsed=0
[Window][PropertiesPannel] [Window][PropertiesPannel]
Pos=880,24 Pos=880,24
Size=400,403 Size=400,474
Collapsed=0 Collapsed=0
DockId=0x00000004,0 DockId=0x00000004,0
@ -92,12 +92,12 @@ DockId=0x00000004,1
[Docking][Data] [Docking][Data]
DockSpace ID=0xA1672E74 Window=0x4647B76E Pos=0,24 Size=1280,696 Split=Y DockSpace ID=0xA1672E74 Window=0x4647B76E Pos=0,24 Size=1280,696 Split=Y
DockNode ID=0x00000007 Parent=0xA1672E74 SizeRef=1280,403 Split=Y DockNode ID=0x00000007 Parent=0xA1672E74 SizeRef=1280,474 Split=Y
DockNode ID=0x00000001 Parent=0x00000007 SizeRef=2560,363 Split=X Selected=0x13926F0B DockNode ID=0x00000001 Parent=0x00000007 SizeRef=2560,363 Split=X Selected=0x13926F0B
DockNode ID=0x00000003 Parent=0x00000001 SizeRef=878,338 Split=X Selected=0x13926F0B DockNode ID=0x00000003 Parent=0x00000001 SizeRef=878,338 Split=X Selected=0x13926F0B
DockNode ID=0x00000005 Parent=0x00000003 SizeRef=256,446 Selected=0xE45B9F93 DockNode ID=0x00000005 Parent=0x00000003 SizeRef=256,446 Selected=0xE45B9F93
DockNode ID=0x00000006 Parent=0x00000003 SizeRef=620,446 CentralNode=1 Selected=0x13926F0B DockNode ID=0x00000006 Parent=0x00000003 SizeRef=620,446 CentralNode=1 Selected=0x13926F0B
DockNode ID=0x00000004 Parent=0x00000001 SizeRef=400,338 Selected=0x2A2C795E DockNode ID=0x00000004 Parent=0x00000001 SizeRef=400,338 Selected=0xA35A27E3
DockNode ID=0x00000002 Parent=0x00000007 SizeRef=2560,331 Selected=0xCF339702 DockNode ID=0x00000002 Parent=0x00000007 SizeRef=2560,331 Selected=0xCF339702
DockNode ID=0x00000008 Parent=0xA1672E74 SizeRef=1280,291 Selected=0xD962995A DockNode ID=0x00000008 Parent=0xA1672E74 SizeRef=1280,220 Selected=0xD962995A