Ajout du schéma JSON pour lecture de scènes + ajout des composants son avec OpenAL + composants scripts et libraire de script + ajout de librairies pour le son dr_libs et openAL + librairie schéma json validator + correctifs divers d'oubli et autres + entity et components factory fonctionnelles + rework API graphique et systèmes mergés dans Systèmes (audio physique, etc...) + rework sauvegarde des resources de façon unique pour éviter les reload (correctifs associés)
This commit is contained in:
@@ -0,0 +1,3 @@
|
||||
#include "CResourceAPI.hpp"
|
||||
|
||||
CResourceManager CResourceAPI::resourceManager;
|
||||
@@ -0,0 +1,13 @@
|
||||
#ifndef RESOURCEAPI_HPP
|
||||
#define RESOURCEAPI_HPP
|
||||
|
||||
#include "../CResourceManager.hpp"
|
||||
|
||||
class CResourceAPI{
|
||||
static CResourceManager resourceManager;
|
||||
public:
|
||||
static CResourceManager& resources(){return resourceManager;};
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,104 @@
|
||||
#include "CAudioManager.hpp"
|
||||
#include <algorithm>
|
||||
#include <vector>
|
||||
|
||||
#define DR_WAV_IMPLEMENTATION
|
||||
#include "dr_wav.h"
|
||||
#define DR_MP3_IMPLEMENTATION
|
||||
#include "dr_mp3.h"
|
||||
#define DR_FLAC_IMPLEMENTATION
|
||||
#include "dr_flac.h"
|
||||
CAudioClip* CAudioManager::loadClip(const std::string& path)
|
||||
{
|
||||
auto cached = get(path);
|
||||
if (cached) return cached.value();
|
||||
|
||||
auto clip = std::make_unique<CAudioClip>();
|
||||
clip->path = path;
|
||||
|
||||
// Détection du format par l'extension
|
||||
std::string ext = path.substr(path.find_last_of(".") + 1);
|
||||
std::transform(ext.begin(), ext.end(), ext.begin(), ::tolower);
|
||||
|
||||
void* pcmData = nullptr;
|
||||
unsigned int channels = 0;
|
||||
unsigned int sampleRate = 0;
|
||||
drwav_uint64 totalFrames = 0;
|
||||
ALenum format = AL_FORMAT_MONO16;
|
||||
int type = -1;
|
||||
|
||||
if (ext == "wav") {
|
||||
// Décodage WAV en 16-bit PCM
|
||||
pcmData = drwav_open_file_and_read_pcm_frames_s16(
|
||||
path.c_str(), &channels, &sampleRate, &totalFrames, NULL
|
||||
);
|
||||
type = 0;
|
||||
}
|
||||
//TODO MP3
|
||||
/*else if (ext == "mp3") {
|
||||
// Décodage MP3 en 16-bit PCM
|
||||
pcmData = drmp3_open_file_and_read_pcm_frames_s16(
|
||||
path.c_str(), &channels, &sampleRate, &totalFrames, NULL
|
||||
);
|
||||
type = 1;
|
||||
}*/
|
||||
else if (ext == "flac") {
|
||||
pcmData = drflac_open_file_and_read_pcm_frames_s16(
|
||||
path.c_str(), &channels, &sampleRate, &totalFrames, NULL
|
||||
);
|
||||
type = 2;
|
||||
}
|
||||
else {
|
||||
return nullptr; // Format non supporté
|
||||
}
|
||||
|
||||
if (pcmData) {
|
||||
// Déterminer le format OpenAL
|
||||
int16_t* finalData = static_cast<int16_t*>(pcmData);
|
||||
uint64_t finalFrames = totalFrames;
|
||||
std::vector<int16_t> monoBuffer; // pour garder les données en vie
|
||||
|
||||
// conversion stéréo → mono obligatoire pour la spatialisation
|
||||
if (channels == 2) {
|
||||
monoBuffer.resize(totalFrames);
|
||||
int16_t* src = static_cast<int16_t*>(pcmData);
|
||||
for (uint64_t i = 0; i < totalFrames; i++) {
|
||||
int32_t left = src[i * 2];
|
||||
int32_t right = src[i * 2 + 1];
|
||||
monoBuffer[i] = static_cast<int16_t>((left + right) / 2);
|
||||
}
|
||||
finalData = monoBuffer.data();
|
||||
finalFrames = totalFrames;
|
||||
format = AL_FORMAT_MONO16;
|
||||
} else if (channels == 1) {
|
||||
format = AL_FORMAT_MONO16;
|
||||
} else {
|
||||
// > 2 canaux non supporté
|
||||
switch(type) {
|
||||
case 0: drwav_free(pcmData, NULL); break;
|
||||
case 2: drflac_free(pcmData, NULL); break;
|
||||
default: break;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Créer le buffer OpenAL
|
||||
alGenBuffers(1, &clip->buffer);
|
||||
|
||||
ALsizei size = static_cast<ALsizei>(finalFrames * sizeof(int16_t));
|
||||
alBufferData(clip->buffer, format, finalData, size, static_cast<ALsizei>(sampleRate));
|
||||
|
||||
// Calculer la durée
|
||||
clip->duration = static_cast<float>(totalFrames) / static_cast<float>(sampleRate);
|
||||
|
||||
// Libérer les données PCM (OpenAL a sa propre copie)
|
||||
switch(type) {
|
||||
case 0: drwav_free(pcmData, NULL); break;
|
||||
case 2: drflac_free(pcmData, NULL); break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
return add(path, std::move(clip));
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
#ifndef CAUDIOMANAGER_HPP
|
||||
#define CAUDIOMANAGER_HPP
|
||||
#include "../../Audio/Sound/CAudioClip.hpp"
|
||||
#include "../CAbstractResourceManager.hpp"
|
||||
class CAudioManager : public CAbstractResourceManager<CAudioClip>{
|
||||
public:
|
||||
|
||||
CAudioClip* loadClip(const std::string& path);
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,71 @@
|
||||
#ifndef CABSTRACTRESOURCEMANAGERBASE_HPP
|
||||
#define CABSTRACTRESOURCEMANAGERBASE_HPP
|
||||
|
||||
#include <list>
|
||||
#include <memory>
|
||||
#include <unordered_map>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
|
||||
template<typename T>
|
||||
class CAbstractResourceManager {
|
||||
protected:
|
||||
std::list<std::unique_ptr<T>> m_resources;
|
||||
std::unordered_map<std::string, T*> m_map;
|
||||
|
||||
public:
|
||||
// ajout
|
||||
T* add(const std::string& key, std::unique_ptr<T>&& resource) {
|
||||
auto* ptr = resource.get();
|
||||
m_resources.push_back(std::move(resource));
|
||||
m_map[key] = ptr;
|
||||
return ptr;
|
||||
}
|
||||
|
||||
// ajout sans clé (généré automatiquement)
|
||||
/*T* add(std::unique_ptr<T>&& resource) {
|
||||
auto key = "_auto_" + std::to_string(m_resources.size());
|
||||
return add(key, std::move(resource));
|
||||
}*/
|
||||
|
||||
// get par clé
|
||||
std::optional<T*> get(const std::string& key) const {
|
||||
auto it = m_map.find(key);
|
||||
if (it != m_map.end()) return it->second;
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
// get ou créer
|
||||
template<typename... Args>
|
||||
T* getOrCreate(const std::string& key, Args&&... args) {
|
||||
auto cached = get(key);
|
||||
if (cached) return cached.value();
|
||||
return add(key, std::make_unique<T>(std::forward<Args>(args)...));
|
||||
}
|
||||
|
||||
// contient
|
||||
bool contains(const std::string& key) const {
|
||||
return m_map.find(key) != m_map.end();
|
||||
}
|
||||
|
||||
// remove
|
||||
void remove(const std::string& key) {
|
||||
auto it = m_map.find(key);
|
||||
if (it == m_map.end()) return;
|
||||
|
||||
T* ptr = it->second;
|
||||
m_map.erase(it);
|
||||
m_resources.remove_if([ptr](const auto& r) { return r.get() == ptr; });
|
||||
}
|
||||
|
||||
// itération
|
||||
auto begin() { return m_resources.begin(); }
|
||||
auto end() { return m_resources.end(); }
|
||||
auto begin() const { return m_resources.begin(); }
|
||||
auto end() const { return m_resources.end(); }
|
||||
|
||||
size_t size() const { return m_resources.size(); }
|
||||
|
||||
void clear() { m_resources.clear(); m_map.clear(); }
|
||||
};
|
||||
#endif
|
||||
@@ -0,0 +1,44 @@
|
||||
#ifndef CRESOURCEMANAGER_HPP
|
||||
#define CRESOURCEMANAGER_HPP
|
||||
|
||||
#include "Model/CModelManager.hpp"
|
||||
#include "Mesh/CMeshManager.hpp"
|
||||
#include "Material/CMaterialManager.hpp"
|
||||
#include "Audio/CAudioManager.hpp"
|
||||
#include "Shader/CShadersManager.hpp"
|
||||
#include "Texture/CTextureManager.hpp"
|
||||
|
||||
class CResourceManager{
|
||||
private:
|
||||
CModelManager m_modelManager;
|
||||
CMeshManager m_meshManager;
|
||||
CMaterialManager m_materialManager;
|
||||
CTextureManager m_textureManager;
|
||||
CAudioManager m_audioManager;
|
||||
CShadersManager m_shaderManager;
|
||||
public:
|
||||
CModelManager& models() { return m_modelManager; }
|
||||
CMeshManager& meshes() { return m_meshManager; }
|
||||
CMaterialManager& materials() { return m_materialManager; }
|
||||
CTextureManager& textures() { return m_textureManager; }
|
||||
CAudioManager& sounds() { return m_audioManager; }
|
||||
CShadersManager& shaders() { return m_shaderManager; }
|
||||
|
||||
const CModelManager& models() const { return m_modelManager; }
|
||||
const CMeshManager& meshes() const { return m_meshManager; }
|
||||
const CMaterialManager& materials() const { return m_materialManager; }
|
||||
const CTextureManager& textures() const { return m_textureManager; }
|
||||
const CAudioManager& sounds() const { return m_audioManager; }
|
||||
const CShadersManager& shaders() const { return m_shaderManager; }
|
||||
|
||||
void cleanup() {
|
||||
m_modelManager.clear();
|
||||
m_materialManager.clear();
|
||||
m_meshManager.clear();
|
||||
m_textureManager.clear();
|
||||
m_audioManager.clear();
|
||||
m_shaderManager.clear();
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,25 @@
|
||||
#ifndef CMATERIALMANAGER_HPP
|
||||
#define CMATERIALMANAGER_HPP
|
||||
|
||||
#include "../../Graphics/Data/Material/CMaterial.hpp"
|
||||
|
||||
#include "../CAbstractResourceManager.hpp"
|
||||
|
||||
class CMaterialManager : public CAbstractResourceManager<CMaterial>
|
||||
{
|
||||
public:
|
||||
CMaterial* createMaterial(const std::string& key,
|
||||
CShaderImplVulkan* shader,
|
||||
CTexture* albedo = nullptr,
|
||||
CTexture* normal = nullptr)
|
||||
{
|
||||
auto mat = std::make_unique<CMaterial>();
|
||||
mat->shader = shader;
|
||||
mat->textureAlbedo = albedo;
|
||||
mat->textureNormal = normal;
|
||||
mat->build();
|
||||
return add(key, std::move(mat));
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
#ifndef CMESHMANAGER_HPP
|
||||
#define CMESHMANAGER_HPP
|
||||
|
||||
#include "../../Graphics/Data/Mesh/CMesh.hpp"
|
||||
#include "../CAbstractResourceManager.hpp"
|
||||
|
||||
class CMeshManager : public CAbstractResourceManager<CMesh>
|
||||
{
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
#ifndef CMODELMANAGER_HPP
|
||||
#define CMODELMANAGER_HPP
|
||||
|
||||
#include "../../Graphics/Data//Model/CModel.hpp"
|
||||
|
||||
#include "../CAbstractResourceManager.hpp"
|
||||
class CModelManager : public CAbstractResourceManager<CModel>
|
||||
{
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,47 @@
|
||||
#include "CShadersManager.hpp"
|
||||
#include <filesystem>
|
||||
#include <fstream>
|
||||
#include <unordered_map>
|
||||
#include "../../../../Utils/Factory/CShaderFactory.hpp"
|
||||
|
||||
CShader* CShadersManager::get(std::string name) const {
|
||||
std::unordered_map<std::string, CShader*>::const_iterator it = m_map.find(name);
|
||||
if (it == m_map.end()) {
|
||||
return nullptr;
|
||||
}
|
||||
else {
|
||||
return it.operator*().second;
|
||||
}
|
||||
}
|
||||
|
||||
void CShadersManager::create(void) {
|
||||
std::filesystem::path shaderDir = std::filesystem::absolute(SHADERS_FOLDER);
|
||||
if (std::filesystem::is_directory(shaderDir)) {
|
||||
for (std::filesystem::directory_iterator itr(shaderDir); itr != std::filesystem::directory_iterator(); ++itr) {
|
||||
if (std::filesystem::is_regular_file(itr->status())) {
|
||||
|
||||
std::ifstream jsonfm(itr->path().string());
|
||||
try {
|
||||
|
||||
auto shader = CosmicUtils::CShaderFactory::create(itr->path().stem(), itr->path());
|
||||
m_resources.push_back(std::move(shader));
|
||||
m_map.insert(std::make_pair(itr->path().stem(), m_resources.back().get()));
|
||||
}
|
||||
catch (std::exception& e) {
|
||||
//throw CJsonException(std::string("Failed to parse and retrieve data from the json file ") + itr->path().string() + ": " + e.what());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
//throw CFileException(std::string("Failed to find the shaders folder : ") + CKernel::m_kernel->getEngineConfig()->getGlobalShadersPath().string());
|
||||
}
|
||||
}
|
||||
|
||||
void CShadersManager::compile(void) {
|
||||
|
||||
for (auto& el: m_resources)
|
||||
{
|
||||
el->init();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
#ifndef CSHADERSMANAGER_HPP
|
||||
#define CSHADERSMANAGER_HPP
|
||||
|
||||
#include <list>
|
||||
#include <string>
|
||||
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
#include "../../Graphics/Shader/CShader.hpp"
|
||||
#include "../CAbstractResourceManager.hpp"
|
||||
|
||||
#define SHADERS_FOLDER "assets/shaders/slang/spv"
|
||||
|
||||
|
||||
class CShadersManager : public CAbstractResourceManager<CShader>{
|
||||
public:
|
||||
CShader* get(std::string name) const;
|
||||
|
||||
std::list<std::unique_ptr<CShader>>::const_iterator beginShaders(){return m_resources.cbegin();};
|
||||
std::list<std::unique_ptr<CShader>>::const_iterator endShaders(){return m_resources.cend();};
|
||||
|
||||
void compile(void);
|
||||
|
||||
void create(void);
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,21 @@
|
||||
#ifndef CTEXTUREMANAGER_HPP
|
||||
#define CTEXTUREMANAGER_HPP
|
||||
|
||||
#include "../../Graphics/Data/Texture/CTexture.hpp"
|
||||
#include "../CAbstractResourceManager.hpp"
|
||||
|
||||
class CTextureManager : public CAbstractResourceManager<CTexture>
|
||||
{
|
||||
public:
|
||||
|
||||
CTexture* loadTexture(const std::string& path) {
|
||||
auto cached = get(path);
|
||||
if (cached) return cached.value();
|
||||
|
||||
auto tex = std::make_unique<CTexture>(path);
|
||||
tex->init();
|
||||
return add(path, std::move(tex));
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user