diff --git a/ChangeLog.md b/ChangeLog.md index f821d1910..ad2dd0a55 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -153,6 +153,8 @@ Nazara Engine: - It is now possible to set elasticity/friction/surface bodies of 2D colliders and change it at runtime on RigidBody2D - ObjectHandle were remade and should be way more optimized now - Added ENetHost and ENetPeer accessor to total packet/data received/sent/lost +- ⚠ **Changed the way resources were Loaded, almost every LoadFromX and OpenFromX methods are now static and create the object themselves.** +- ⚠ SoundStream is now responsible for loaders instead of Music, and is now threadsafe (you can now load a stream only once and play it multiple times at the same time) Nazara Development Kit: - Added ImageWidget (#139) diff --git a/SDK/include/NDK/LuaAPI.inl b/SDK/include/NDK/LuaAPI.inl index 40fe33ec7..e2b1095dc 100644 --- a/SDK/include/NDK/LuaAPI.inl +++ b/SDK/include/NDK/LuaAPI.inl @@ -402,7 +402,7 @@ namespace Nz return 1; } - inline unsigned int LuaImplQueryArg(const LuaState& state, int index, MusicParams* params, TypeTag) + inline unsigned int LuaImplQueryArg(const LuaState& state, int index, SoundBufferParams* params, TypeTag) { state.CheckType(index, Nz::LuaType_Table); @@ -411,7 +411,7 @@ namespace Nz return 1; } - inline unsigned int LuaImplQueryArg(const LuaState& state, int index, SoundBufferParams* params, TypeTag) + inline unsigned int LuaImplQueryArg(const LuaState& state, int index, SoundStreamParams* params, TypeTag) { state.CheckType(index, Nz::LuaType_Table); @@ -635,12 +635,24 @@ namespace Nz return 1; } + inline int LuaImplReplyVal(const LuaState& state, ModelRef&& handle, TypeTag) + { + state.PushInstance("Model", handle); + return 1; + } + inline int LuaImplReplyVal(const LuaState& state, const SoundBuffer* val, TypeTag) { state.PushInstance("SoundBuffer", val); return 1; } + inline int LuaImplReplyVal(const LuaState& state, SoundBufferRef&& handle, TypeTag) + { + state.PushInstance("SoundBuffer", handle); + return 1; + } + inline int LuaImplReplyVal(const LuaState& state, SpriteRef&& handle, TypeTag) { state.PushInstance("Sprite", handle); diff --git a/SDK/src/NDK/Lua/LuaBinding_Audio.cpp b/SDK/src/NDK/Lua/LuaBinding_Audio.cpp index 1611c1b8c..c95b5d0ce 100644 --- a/SDK/src/NDK/Lua/LuaBinding_Audio.cpp +++ b/SDK/src/NDK/Lua/LuaBinding_Audio.cpp @@ -67,7 +67,7 @@ namespace Ndk music.BindMethod("IsLooping", &Nz::Music::IsLooping); - music.BindMethod("OpenFromFile", &Nz::Music::OpenFromFile, Nz::MusicParams()); + music.BindMethod("OpenFromFile", &Nz::Music::OpenFromFile, Nz::SoundStreamParams()); music.BindMethod("Pause", &Nz::Music::Pause); music.BindMethod("Play", &Nz::Music::Play); @@ -138,7 +138,7 @@ namespace Ndk soundBuffer.BindMethod("IsValid", &Nz::SoundBuffer::IsValid); - soundBuffer.BindMethod("LoadFromFile", &Nz::SoundBuffer::LoadFromFile, Nz::SoundBufferParams()); + soundBuffer.BindStaticMethod("LoadFromFile", &Nz::SoundBuffer::LoadFromFile, Nz::SoundBufferParams()); soundBuffer.BindStaticMethod("IsFormatSupported", &Nz::SoundBuffer::IsFormatSupported); diff --git a/SDK/src/NDK/Lua/LuaBinding_Graphics.cpp b/SDK/src/NDK/Lua/LuaBinding_Graphics.cpp index 14105eb3c..fc764866a 100644 --- a/SDK/src/NDK/Lua/LuaBinding_Graphics.cpp +++ b/SDK/src/NDK/Lua/LuaBinding_Graphics.cpp @@ -181,8 +181,6 @@ namespace Ndk material.BindMethod("IsShadowCastingEnabled", &Nz::Material::IsShadowCastingEnabled); material.BindMethod("IsShadowReceiveEnabled", &Nz::Material::IsShadowReceiveEnabled); - material.BindMethod("LoadFromFile", &Nz::Material::LoadFromFile, Nz::MaterialParams()); - material.BindMethod("Reset", &Nz::Material::Reset); material.BindMethod("SetAlphaThreshold", &Nz::Material::SetAlphaThreshold); @@ -205,6 +203,7 @@ namespace Ndk material.BindMethod("SetSrcBlend", &Nz::Material::SetSrcBlend); material.BindStaticMethod("GetDefault", &Nz::Material::GetDefault); + material.BindStaticMethod("LoadFromFile", &Nz::Material::LoadFromFile, Nz::MaterialParams()); material.BindMethod("SetAlphaMap", [] (Nz::LuaState& lua, Nz::MaterialRef& instance, std::size_t /*argumentCount*/) -> int { @@ -308,8 +307,6 @@ namespace Ndk //modelClass.SetMethod("GetMesh", &Nz::Model::GetMesh); model.BindMethod("IsAnimated", &Nz::Model::IsAnimated); - model.BindMethod("LoadFromFile", &Nz::Model::LoadFromFile, Nz::ModelParameters()); - model.BindMethod("SetMaterial", [] (Nz::LuaState& lua, Nz::Model* instance, std::size_t argumentCount) -> int { @@ -371,6 +368,8 @@ namespace Ndk //modelClass.SetMethod("SetMesh", &Nz::Model::SetMesh); //modelClass.SetMethod("SetSequence", &Nz::Model::SetSequence); + + model.BindStaticMethod("LoadFromFile", &Nz::Model::LoadFromFile, Nz::ModelParameters()); } /*********************************** Nz::Sprite ***********************************/ diff --git a/SDK/src/NDK/Lua/LuaBinding_Renderer.cpp b/SDK/src/NDK/Lua/LuaBinding_Renderer.cpp index 108941880..8aacf2a1f 100644 --- a/SDK/src/NDK/Lua/LuaBinding_Renderer.cpp +++ b/SDK/src/NDK/Lua/LuaBinding_Renderer.cpp @@ -44,21 +44,6 @@ namespace Ndk texture.BindMethod("InvalidateMipmaps", &Nz::Texture::InvalidateMipmaps); texture.BindMethod("IsValid", &Nz::Texture::IsValid); - texture.BindMethod("LoadFromFile", &Nz::Texture::LoadFromFile, true, Nz::ImageParams()); - //bool LoadFromImage(const Image& image, bool generateMipmaps = true); - //bool LoadFromMemory(const void* data, std::size_t size, const ImageParams& params = ImageParams(), bool generateMipmaps = true); - //bool LoadFromStream(Stream& stream, const ImageParams& params = ImageParams(), bool generateMipmaps = true); - - texture.BindMethod("LoadArrayFromFile", &Nz::Texture::LoadArrayFromFile, Nz::Vector2ui(2, 2), true, Nz::ImageParams()); - //bool LoadArrayFromImage(const Image& image, bool generateMipmaps = true, const Vector2ui& atlasSize = Vector2ui(2, 2)); - //bool LoadArrayFromMemory(const void* data, std::size_t size, const ImageParams& imageParams = ImageParams(), bool generateMipmaps = true, const Vector2ui& atlasSize = Vector2ui(2, 2)); - //bool LoadArrayFromStream(Stream& stream, const ImageParams& imageParams = ImageParams(), bool generateMipmaps = true, const Vector2ui& atlasSize = Vector2ui(2, 2)); - - //bool LoadCubemapFromFile(const String& filePath, const ImageParams& imageParams = ImageParams(), bool generateMipmaps = true, const CubemapParams& cubemapParams = CubemapParams()); - //bool LoadCubemapFromImage(const Image& image, bool generateMipmaps = true, const CubemapParams& params = CubemapParams()); - //bool LoadCubemapFromMemory(const void* data, std::size_t size, const ImageParams& imageParams = ImageParams(), bool generateMipmaps = true, const CubemapParams& cubemapParams = CubemapParams()); - //bool LoadCubemapFromStream(Stream& stream, const ImageParams& imageParams = ImageParams(), bool generateMipmaps = true, const CubemapParams& cubemapParams = CubemapParams()); - texture.BindMethod("LoadFaceFromFile", &Nz::Texture::LoadFaceFromFile, Nz::ImageParams()); //bool LoadFaceFromMemory(CubemapFace face, const void* data, std::size_t size, const ImageParams& params = ImageParams()); //bool LoadFaceFromStream(CubemapFace face, Stream& stream, const ImageParams& params = ImageParams()); @@ -71,6 +56,21 @@ namespace Ndk texture.BindStaticMethod("IsFormatSupported", &Nz::Texture::IsFormatSupported); texture.BindStaticMethod("IsMipmappingSupported", &Nz::Texture::IsMipmappingSupported); texture.BindStaticMethod("IsTypeSupported", &Nz::Texture::IsTypeSupported); + + texture.BindStaticMethod("LoadFromFile", &Nz::Texture::LoadFromFile, true, Nz::ImageParams()); + //TextureRef LoadFromImage(const Image& image, bool generateMipmaps = true); + //TextureRef LoadFromMemory(const void* data, std::size_t size, const ImageParams& params = ImageParams(), bool generateMipmaps = true); + //TextureRef LoadFromStream(Stream& stream, const ImageParams& params = ImageParams(), bool generateMipmaps = true); + + texture.BindStaticMethod("LoadArrayFromFile", &Nz::Texture::LoadArrayFromFile, Nz::Vector2ui(2, 2), true, Nz::ImageParams()); + //TextureRef LoadArrayFromImage(const Image& image, bool generateMipmaps = true, const Vector2ui& atlasSize = Vector2ui(2, 2)); + //TextureRef LoadArrayFromMemory(const void* data, std::size_t size, const ImageParams& imageParams = ImageParams(), bool generateMipmaps = true, const Vector2ui& atlasSize = Vector2ui(2, 2)); + //TextureRef LoadArrayFromStream(Stream& stream, const ImageParams& imageParams = ImageParams(), bool generateMipmaps = true, const Vector2ui& atlasSize = Vector2ui(2, 2)); + + //TextureRef LoadCubemapFromFile(const String& filePath, const ImageParams& imageParams = ImageParams(), bool generateMipmaps = true, const CubemapParams& cubemapParams = CubemapParams()); + //TextureRef LoadCubemapFromImage(const Image& image, bool generateMipmaps = true, const CubemapParams& params = CubemapParams()); + //TextureRef LoadCubemapFromMemory(const void* data, std::size_t size, const ImageParams& imageParams = ImageParams(), bool generateMipmaps = true, const CubemapParams& cubemapParams = CubemapParams()); + //TextureRef LoadCubemapFromStream(Stream& stream, const ImageParams& imageParams = ImageParams(), bool generateMipmaps = true, const CubemapParams& cubemapParams = CubemapParams()); } /*********************************** Nz::TextureLibrary ***********************************/ diff --git a/SDK/src/NDK/Lua/LuaBinding_Utility.cpp b/SDK/src/NDK/Lua/LuaBinding_Utility.cpp index 5fdd52d01..43ea4a8c7 100644 --- a/SDK/src/NDK/Lua/LuaBinding_Utility.cpp +++ b/SDK/src/NDK/Lua/LuaBinding_Utility.cpp @@ -148,8 +148,6 @@ namespace Ndk font.BindMethod("Precache", (bool(Nz::Font::*)(unsigned int, Nz::UInt32, const Nz::String&) const) &Nz::Font::Precache); - font.BindMethod("OpenFromFile", &Nz::Font::OpenFromFile, Nz::FontParams()); - font.BindMethod("SetGlyphBorder", &Nz::Font::SetGlyphBorder); font.BindMethod("SetMinimumStepSize", &Nz::Font::SetMinimumStepSize); @@ -157,6 +155,8 @@ namespace Ndk font.BindStaticMethod("GetDefaultGlyphBorder", &Nz::Font::GetDefaultGlyphBorder); font.BindStaticMethod("GetDefaultMinimumStepSize", &Nz::Font::GetDefaultMinimumStepSize); + font.BindStaticMethod("OpenFromFile", &Nz::Font::OpenFromFile, Nz::FontParams()); + font.BindStaticMethod("SetDefaultGlyphBorder", &Nz::Font::SetDefaultGlyphBorder); font.BindStaticMethod("SetDefaultMinimumStepSize", &Nz::Font::SetDefaultMinimumStepSize); } diff --git a/SDK/src/NDK/Widgets/CheckboxWidget.cpp b/SDK/src/NDK/Widgets/CheckboxWidget.cpp index 7ea3969de..7d906d8d1 100644 --- a/SDK/src/NDK/Widgets/CheckboxWidget.cpp +++ b/SDK/src/NDK/Widgets/CheckboxWidget.cpp @@ -57,14 +57,14 @@ namespace Ndk #include }; - Nz::TextureRef checkmarkTexture = Nz::Texture::New(); - if (!checkmarkTexture->LoadFromMemory(r_checkmark, sizeof(r_checkmark) / sizeof(r_checkmark[0]))) + Nz::TextureRef checkmarkTexture = Nz::Texture::LoadFromMemory(r_checkmark, sizeof(r_checkmark) / sizeof(r_checkmark[0])); + if (!checkmarkTexture) { NazaraError("Failed to load embedded checkmark"); return false; } - Nz::TextureLibrary::Register("Ndk::CheckboxWidget::checkmark", checkmarkTexture); + Nz::TextureLibrary::Register("Ndk::CheckboxWidget::checkmark", std::move(checkmarkTexture)); return true; } diff --git a/examples/FirstScene/main.cpp b/examples/FirstScene/main.cpp index a4ce40454..0e3f8f8a2 100644 --- a/examples/FirstScene/main.cpp +++ b/examples/FirstScene/main.cpp @@ -56,8 +56,8 @@ int main() // En réalité les textures "cubemap" regroupent six faces en une, pour faciliter leur utilisation. // Nous créons une nouvelle texture et prenons une référence sur celle-ci (à la manière des pointeurs intelligents) - Nz::TextureRef texture = Nz::Texture::New(); - if (texture->LoadCubemapFromFile("resources/skybox-space.png")) + Nz::TextureRef texture = Nz::Texture::LoadCubemapFromFile("resources/skybox-space.png"); + if (texture) { // Si la création du cubemap a fonctionné @@ -83,9 +83,6 @@ int main() // Les modèles représentent, globalement, tout ce qui est visible en trois dimensions. // Nous choisirons ici un vaisseau spatial (Quoi de mieux pour une scène spatiale ?) - // Encore une fois, nous récupérons une référence plutôt que l'objet lui-même (cela va être très utile par la suite) - Nz::ModelRef spaceshipModel = Nz::Model::New(); - // Nous allons charger notre modèle depuis un fichier, mais nous pouvons ajuster le modèle lors du chargement via // une structure permettant de paramétrer le chargement des modèles Nz::ModelParameters params; @@ -104,7 +101,8 @@ int main() // On charge ensuite le modèle depuis son fichier // Le moteur va charger le fichier et essayer de retrouver les fichiers associés (comme les matériaux, textures, ...) - if (!spaceshipModel->LoadFromFile("resources/Spaceship/spaceship.obj", params)) + Nz::ModelRef spaceshipModel = Nz::Model::LoadFromFile("resources/Spaceship/spaceship.obj", params); + if (!spaceshipModel) { // Si le chargement a échoué (fichier inexistant/invalide), il ne sert à rien de continuer std::cout << "Failed to load spaceship" << std::endl; diff --git a/examples/MeshInfos/main.cpp b/examples/MeshInfos/main.cpp index bac5398fe..e7b3feaeb 100644 --- a/examples/MeshInfos/main.cpp +++ b/examples/MeshInfos/main.cpp @@ -71,15 +71,15 @@ int main() if (iChoice == 0) break; - Nz::Mesh mesh; - if (!mesh.LoadFromFile(resourceDirectory.GetPath() + '/' + models[iChoice-1])) + Nz::MeshRef mesh = Nz::Mesh::LoadFromFile(resourceDirectory.GetPath() + '/' + models[iChoice-1]); + if (!mesh) { std::cout << "Failed to load mesh" << std::endl; std::getchar(); return EXIT_FAILURE; } - switch (mesh.GetAnimationType()) + switch (mesh->GetAnimationType()) { case Nz::AnimationType_Skeletal: std::cout << "This is a skeletal-animated mesh" << std::endl; @@ -92,13 +92,13 @@ int main() // Inutile de faire un case default (GetAnimationType renverra toujours une valeur correcte) } - std::cout << "It has a total of " << mesh.GetVertexCount() << " vertices for " << mesh.GetSubMeshCount() << " submesh(es)." << std::endl; + std::cout << "It has a total of " << mesh->GetVertexCount() << " vertices for " << mesh->GetSubMeshCount() << " submesh(es)." << std::endl; - if (mesh.IsAnimable()) + if (mesh->IsAnimable()) { - if (mesh.GetAnimationType() == Nz::AnimationType_Skeletal) + if (mesh->GetAnimationType() == Nz::AnimationType_Skeletal) { - const Nz::Skeleton* skeleton = mesh.GetSkeleton(); + const Nz::Skeleton* skeleton = mesh->GetSkeleton(); unsigned int jointCount = skeleton->GetJointCount(); std::cout << "It has a skeleton made of " << skeleton->GetJointCount() << " joint(s)." << std::endl; std::cout << "Print joints ? (Y/N) "; @@ -123,14 +123,14 @@ int main() } } - Nz::String animationPath = mesh.GetAnimation(); + Nz::String animationPath = mesh->GetAnimation(); if (!animationPath.IsEmpty()) { - Nz::Animation animation; - if (animation.LoadFromFile(animationPath)) + Nz::AnimationRef animation = Nz::Animation::LoadFromFile(animationPath); + if (animation) { - unsigned int sequenceCount = animation.GetSequenceCount(); - std::cout << "It has an animation made of " << animation.GetFrameCount() << " frame(s) for " << sequenceCount << " sequence(s)." << std::endl; + unsigned int sequenceCount = animation->GetSequenceCount(); + std::cout << "It has an animation made of " << animation->GetFrameCount() << " frame(s) for " << sequenceCount << " sequence(s)." << std::endl; std::cout << "Print sequences ? (Y/N) "; char cChoice; @@ -141,7 +141,7 @@ int main() { for (unsigned int i = 0; i < sequenceCount; ++i) { - const Nz::Sequence* sequence = animation.GetSequence(i); + const Nz::Sequence* sequence = animation->GetSequence(i); std::cout << "\t" << (i+1) << ": " << sequence->name << std::endl; std::cout << "\t\tStart frame: " << sequence->firstFrame << std::endl; std::cout << "\t\tFrame count: " << sequence->frameCount << std::endl; @@ -157,10 +157,10 @@ int main() std::cout << "It's animable but has no animation information" << std::endl; } - Nz::Boxf cube = mesh.GetAABB(); + Nz::Boxf cube = mesh->GetAABB(); std::cout << "Mesh is " << cube.width << " units wide, " << cube.height << " units height and " << cube.depth << " units depth" << std::endl; - unsigned int materialCount = mesh.GetMaterialCount(); + unsigned int materialCount = mesh->GetMaterialCount(); std::cout << "It has " << materialCount << " materials registred" << std::endl; std::cout << "Print materials ? (Y/N) "; @@ -172,7 +172,7 @@ int main() { for (unsigned int i = 0; i < materialCount; ++i) { - const Nz::ParameterList& matData = mesh.GetMaterialData(i); + const Nz::ParameterList& matData = mesh->GetMaterialData(i); Nz::String data; if (!matData.GetStringParameter(Nz::MaterialData::FilePath, &data)) diff --git a/examples/Particles/LogoDemo.cpp b/examples/Particles/LogoDemo.cpp index 0811191e1..f04ce43ad 100644 --- a/examples/Particles/LogoDemo.cpp +++ b/examples/Particles/LogoDemo.cpp @@ -107,7 +107,7 @@ class SpriteRenderer : public Nz::ParticleRenderer { } - void Render(const Nz::ParticleGroup& system, const Nz::ParticleMapper& mapper, unsigned int startId, unsigned int endId, Nz::AbstractRenderQueue* renderQueue) + void Render(const Nz::ParticleGroup& system, const Nz::ParticleMapper& mapper, unsigned int startId, unsigned int endId, Nz::AbstractRenderQueue* renderQueue) override { Nz::Vector2f size(1.f, 1.f); Nz::SparsePtr sizePtr(&size, 0); @@ -126,18 +126,19 @@ ParticleDemo("Logo", sharedData) Nz::ImageParams params; params.loadFormat = Nz::PixelFormatType_RGBA8; - if (!m_logo.LoadFromFile("resources/Logo.png", params)) + m_logo = Nz::Image::LoadFromFile("resources/Logo.png", params); + if (!m_logo) NazaraError("Failed to load logo!"); - unsigned int width = m_logo.GetWidth(); - unsigned int height = m_logo.GetHeight(); + unsigned int width = m_logo->GetWidth(); + unsigned int height = m_logo->GetHeight(); m_pixels.reserve(width * height); for (unsigned int x = 0; x < width; ++x) { for (unsigned int y = 0; y < height; ++y) { - Nz::Color color = m_logo.GetPixelColor(x, y); + Nz::Color color = m_logo->GetPixelColor(x, y); if (color.a == 0) continue; @@ -173,8 +174,8 @@ void LogoExample::Enter(Ndk::StateMachine& fsm) m_shared.world3D->GetSystem().SetDefaultBackground(nullptr); - Nz::TextureRef backgroundTexture = Nz::Texture::New(); - if (backgroundTexture->LoadFromFile("resources/stars-background.jpg")) + Nz::TextureRef backgroundTexture = Nz::Texture::LoadFromFile("resources/stars-background.jpg"); + if (backgroundTexture) m_shared.world2D->GetSystem().SetDefaultBackground(Nz::TextureBackground::New(std::move(backgroundTexture))); Ndk::EntityHandle particleGroupEntity = m_shared.world2D->CreateEntity(); @@ -254,7 +255,7 @@ void LogoExample::ResetParticles(float elapsed) Nz::Vector2ui size = m_shared.target->GetSize(); Nz::Vector2f center = {size.x / 2.f, size.y / 2.f}; - Nz::Vector2f offset = center - Nz::Vector2f(Nz::Vector2ui(m_logo.GetSize()) / 2); + Nz::Vector2f offset = center - Nz::Vector2f(Nz::Vector2ui(m_logo->GetSize()) / 2); std::uniform_real_distribution disX(0.f, float(size.x)); std::uniform_real_distribution disY(-float(size.y) * 0.5f, float(size.y) * 1.5f); diff --git a/examples/Particles/LogoDemo.hpp b/examples/Particles/LogoDemo.hpp index 7ce594080..bd0536edf 100644 --- a/examples/Particles/LogoDemo.hpp +++ b/examples/Particles/LogoDemo.hpp @@ -32,7 +32,7 @@ class LogoExample : public ParticleDemo Nz::BackgroundRef m_oldBackground; void* m_particles; Nz::Clock m_mouseClock; - Nz::Image m_logo; + Nz::ImageRef m_logo; Nz::ParticleControllerRef m_controller; Nz::ParticleDeclarationRef m_declaration; Nz::ParticleRendererRef m_renderer; diff --git a/examples/Particles/SpacebattleDemo.cpp b/examples/Particles/SpacebattleDemo.cpp index 2bd30940c..65336ad13 100644 --- a/examples/Particles/SpacebattleDemo.cpp +++ b/examples/Particles/SpacebattleDemo.cpp @@ -234,52 +234,59 @@ ParticleDemo("Space battle", sharedData) Nz::Color grey(100, 100, 100); - if (!m_turret.baseModel.LoadFromFile("resources/Turret/base.obj", parameters)) + m_turret.baseModel = Nz::Model::LoadFromFile("resources/Turret/base.obj", parameters); + if (!m_turret.baseModel) NazaraWarning("Failed to load base.obj"); - for (unsigned int i = 0; i < m_turret.baseModel.GetMaterialCount(); ++i) - m_turret.baseModel.GetMaterial(i)->SetDiffuseColor(grey); + for (unsigned int i = 0; i < m_turret.baseModel->GetMaterialCount(); ++i) + m_turret.baseModel->GetMaterial(i)->SetDiffuseColor(grey); - if (!m_turret.rotatingBaseModel.LoadFromFile("resources/Turret/rotating_base.obj", parameters)) + m_turret.rotatingBaseModel = Nz::Model::LoadFromFile("resources/Turret/rotating_base.obj", parameters); + if (!m_turret.rotatingBaseModel) NazaraWarning("Failed to load rotating_base.obj"); - for (unsigned int i = 0; i < m_turret.rotatingBaseModel.GetMaterialCount(); ++i) - m_turret.rotatingBaseModel.GetMaterial(i)->SetDiffuseColor(grey); + for (unsigned int i = 0; i < m_turret.rotatingBaseModel->GetMaterialCount(); ++i) + m_turret.rotatingBaseModel->GetMaterial(i)->SetDiffuseColor(grey); - if (!m_turret.cannonBaseModel.LoadFromFile("resources/Turret/cannon_base.obj", parameters)) + m_turret.cannonBaseModel = Nz::Model::LoadFromFile("resources/Turret/cannon_base.obj", parameters); + if (!m_turret.cannonBaseModel) NazaraWarning("Failed to load cannon_base.obj"); - for (unsigned int i = 0; i < m_turret.cannonBaseModel.GetMaterialCount(); ++i) - m_turret.cannonBaseModel.GetMaterial(i)->SetDiffuseColor(grey); + for (unsigned int i = 0; i < m_turret.cannonBaseModel->GetMaterialCount(); ++i) + m_turret.cannonBaseModel->GetMaterial(i)->SetDiffuseColor(grey); parameters.mesh.texCoordScale.Set(40.f, 40.f); parameters.mesh.matrix = Nz::Matrix4f::Rotate(Nz::EulerAnglesf(0.f, 180.f, 0.f)); - if (!m_turret.cannonModel.LoadFromFile("resources/Turret/cannon.obj", parameters)) + + m_turret.cannonModel = Nz::Model::LoadFromFile("resources/Turret/cannon.obj", parameters); + if (!m_turret.cannonModel) NazaraWarning("Failed to load cannon.obj"); - // Since OBJ don't support normal maps.. - m_turret.cannonModel.GetMaterial(0)->SetNormalMap("resources/Turret/198_norm.jpg"); + // Since OBJ doesn't support normal maps.. + m_turret.cannonModel->GetMaterial(0)->SetNormalMap("resources/Turret/198_norm.jpg"); parameters.mesh.matrix.MakeIdentity(); parameters.mesh.texCoordScale.Set(1.f, 1.f); parameters.mesh.center = true; - if (!m_spacestationModel.LoadFromFile("resources/SpaceStation/space_station.obj", parameters)) + m_spacestationModel = Nz::Model::LoadFromFile("resources/SpaceStation/space_station.obj", parameters); + if (!m_spacestationModel) NazaraWarning("Failed to load space_station.obj"); - m_spacestationModel.GetMesh()->GenerateNormalsAndTangents(); + m_spacestationModel->GetMesh()->GenerateNormalsAndTangents(); parameters.mesh.texCoordScale.Set(1.f, -1.f); parameters.mesh.matrix.MakeRotation(Nz::EulerAnglesf(0.f, -90.f, 0.f)); - if (!m_spaceshipModel.LoadFromFile("resources/space_frigate_6/space_frigate_6.obj", parameters)) + m_spaceshipModel = Nz::Model::LoadFromFile("resources/space_frigate_6/space_frigate_6.obj", parameters); + if (!m_spaceshipModel) NazaraWarning("Failed to load space_frigate_6.obj"); - // Since OBJ don't support normal maps.. - for (unsigned int i = 0; i < m_spaceshipModel.GetMaterialCount(); ++i) + // Since OBJ doesn't support normal maps.. + for (unsigned int i = 0; i < m_spaceshipModel->GetMaterialCount(); ++i) { - m_spaceshipModel.GetMaterial(i)->SetEmissiveMap("resources/space_frigate_6/space_frigate_6_illumination.jpg"); - m_spaceshipModel.GetMaterial(i)->SetNormalMap("resources/space_frigate_6/space_frigate_6_normal.png"); + m_spaceshipModel->GetMaterial(i)->SetEmissiveMap("resources/space_frigate_6/space_frigate_6_illumination.jpg"); + m_spaceshipModel->GetMaterial(i)->SetNormalMap("resources/space_frigate_6/space_frigate_6_normal.png"); } Nz::TextureRef skyboxCubemap = Nz::Texture::New(); @@ -324,7 +331,7 @@ ParticleDemo("Space battle", sharedData) m_spaceshipTemplate->AddComponent(); m_spaceshipTemplate->AddComponent(); auto& gfxComponent = m_spaceshipTemplate->AddComponent(); - gfxComponent.Attach(&m_spaceshipModel); + gfxComponent.Attach(m_spaceshipModel); m_ambientMusic.OpenFromFile("resources/ambience.ogg"); m_ambientMusic.SetVolume(60.f); @@ -762,7 +769,7 @@ void SpacebattleExample::CreateSpaceShip() spacestationNode.SetScale(0.1f); Ndk::GraphicsComponent& spacestationGfx = m_spacestationEntity->AddComponent(); - spacestationGfx.Attach(&m_spacestationModel); + spacestationGfx.Attach(m_spacestationModel); } void SpacebattleExample::CreateTurret() @@ -776,7 +783,7 @@ void SpacebattleExample::CreateTurret() baseNode.SetRotation(Nz::EulerAnglesf(0.f, 180.f, 0.f)); Ndk::GraphicsComponent& baseGfx = m_turret.baseEntity->AddComponent(); - baseGfx.Attach(&m_turret.baseModel); + baseGfx.Attach(m_turret.baseModel); // Rotating base m_turret.rotatingBaseEntity = m_shared.world3D->CreateEntity(); @@ -786,7 +793,7 @@ void SpacebattleExample::CreateTurret() rotatingBaseNode.SetParent(m_turret.baseEntity); Ndk::GraphicsComponent& rotatingBaseGfx = m_turret.rotatingBaseEntity->AddComponent(); - rotatingBaseGfx.Attach(&m_turret.rotatingBaseModel); + rotatingBaseGfx.Attach(m_turret.rotatingBaseModel); // Cannon base m_turret.cannonBaseEntity = m_shared.world3D->CreateEntity(); @@ -797,7 +804,7 @@ void SpacebattleExample::CreateTurret() cannonBaseNode.SetParent(m_turret.rotatingBaseEntity); Ndk::GraphicsComponent& cannonBaseGfx = m_turret.cannonBaseEntity->AddComponent(); - cannonBaseGfx.Attach(&m_turret.cannonBaseModel); + cannonBaseGfx.Attach(m_turret.cannonBaseModel); // Cannon anchor m_turret.cannonAnchorEntity = m_shared.world3D->CreateEntity(); @@ -816,7 +823,7 @@ void SpacebattleExample::CreateTurret() cannonNode.SetRotation(Nz::EulerAnglesf(0.f, 180.f, 0.f)); Ndk::GraphicsComponent& cannonGfx = m_turret.cannonEntity->AddComponent(); - cannonGfx.Attach(&m_turret.cannonModel); + cannonGfx.Attach(m_turret.cannonModel); } void SpacebattleExample::OnMouseMoved(const Nz::EventHandler* /*eventHandler*/, const Nz::WindowEvent::MouseMoveEvent& event) diff --git a/examples/Particles/SpacebattleDemo.hpp b/examples/Particles/SpacebattleDemo.hpp index a41be7504..e0b928e19 100644 --- a/examples/Particles/SpacebattleDemo.hpp +++ b/examples/Particles/SpacebattleDemo.hpp @@ -33,10 +33,10 @@ class SpacebattleExample : public ParticleDemo struct Turret { - Nz::Model baseModel; - Nz::Model cannonModel; - Nz::Model cannonBaseModel; - Nz::Model rotatingBaseModel; + Nz::ModelRef baseModel; + Nz::ModelRef cannonModel; + Nz::ModelRef cannonBaseModel; + Nz::ModelRef rotatingBaseModel; Ndk::EntityHandle baseEntity; Ndk::EntityHandle cannonAnchorEntity; Ndk::EntityHandle cannonEntity; @@ -50,8 +50,8 @@ class SpacebattleExample : public ParticleDemo float m_turretBaseRotation; float m_turretCannonBaseRotation; float m_turretShootTimer; - Nz::Model m_spaceshipModel; - Nz::Model m_spacestationModel; + Nz::ModelRef m_spaceshipModel; + Nz::ModelRef m_spacestationModel; Nz::Music m_ambientMusic; Nz::ParticleDeclarationRef m_torpedoDeclaration; Nz::ParticleRendererRef m_laserBeamRenderer; diff --git a/include/Nazara/Audio/Music.hpp b/include/Nazara/Audio/Music.hpp index 27e742063..331624a8d 100644 --- a/include/Nazara/Audio/Music.hpp +++ b/include/Nazara/Audio/Music.hpp @@ -10,31 +10,15 @@ #include #include #include +#include #include -#include -#include -#include namespace Nz { - struct MusicParams : ResourceParameters - { - bool forceMono = false; - - bool IsValid() const; - }; - - class Music; - class SoundStream; - - using MusicLoader = ResourceLoader; - struct MusicImpl; class NAZARA_AUDIO_API Music : public Resource, public SoundEmitter { - friend MusicLoader; - public: Music() = default; Music(const Music&) = delete; @@ -55,9 +39,9 @@ namespace Nz bool IsLooping() const override; - bool OpenFromFile(const String& filePath, const MusicParams& params = MusicParams()); - bool OpenFromMemory(const void* data, std::size_t size, const MusicParams& params = MusicParams()); - bool OpenFromStream(Stream& stream, const MusicParams& params = MusicParams()); + bool OpenFromFile(const String& filePath, const SoundStreamParams& params = SoundStreamParams()); + bool OpenFromMemory(const void* data, std::size_t size, const SoundStreamParams& params = SoundStreamParams()); + bool OpenFromStream(Stream& stream, const SoundStreamParams& params = SoundStreamParams()); void Pause() override; void Play() override; @@ -75,8 +59,6 @@ namespace Nz bool FillAndQueueBuffer(unsigned int buffer); void MusicThread(); void StopThread(); - - static MusicLoader::LoaderList s_loaders; }; } diff --git a/include/Nazara/Audio/SoundBuffer.hpp b/include/Nazara/Audio/SoundBuffer.hpp index 46f37ab05..4cf5e50df 100644 --- a/include/Nazara/Audio/SoundBuffer.hpp +++ b/include/Nazara/Audio/SoundBuffer.hpp @@ -66,16 +66,17 @@ namespace Nz bool IsValid() const; - bool LoadFromFile(const String& filePath, const SoundBufferParams& params = SoundBufferParams()); - bool LoadFromMemory(const void* data, std::size_t size, const SoundBufferParams& params = SoundBufferParams()); - bool LoadFromStream(Stream& stream, const SoundBufferParams& params = SoundBufferParams()); - - static bool IsFormatSupported(AudioFormat format); - template static SoundBufferRef New(Args&&... args); - SoundBuffer& operator=(const SoundBuffer&) = delete; SoundBuffer& operator=(SoundBuffer&&) = delete; + static bool IsFormatSupported(AudioFormat format); + + static SoundBufferRef LoadFromFile(const String& filePath, const SoundBufferParams& params = SoundBufferParams()); + static SoundBufferRef LoadFromMemory(const void* data, std::size_t size, const SoundBufferParams& params = SoundBufferParams()); + static SoundBufferRef LoadFromStream(Stream& stream, const SoundBufferParams& params = SoundBufferParams()); + + template static SoundBufferRef New(Args&&... args); + // Signals: NazaraSignal(OnSoundBufferDestroy, const SoundBuffer* /*soundBuffer*/); NazaraSignal(OnSoundBufferRelease, const SoundBuffer* /*soundBuffer*/); diff --git a/include/Nazara/Audio/SoundStream.hpp b/include/Nazara/Audio/SoundStream.hpp index 9b9731b41..d33997d26 100644 --- a/include/Nazara/Audio/SoundStream.hpp +++ b/include/Nazara/Audio/SoundStream.hpp @@ -10,22 +10,50 @@ #include #include #include +#include +#include +#include +#include namespace Nz { - class NAZARA_AUDIO_API SoundStream + struct SoundStreamParams : public ResourceParameters { + bool forceMono = false; + + bool IsValid() const; + }; + + class Mutex; + class SoundStream; + + using SoundStreamLoader = ResourceLoader; + using SoundStreamRef = Nz::ObjectRef; + + class NAZARA_AUDIO_API SoundStream : public RefCounted, public Resource + { + friend SoundStreamLoader; + public: SoundStream() = default; virtual ~SoundStream(); virtual UInt32 GetDuration() const = 0; virtual AudioFormat GetFormat() const = 0; + virtual Mutex& GetMutex() = 0; virtual UInt64 GetSampleCount() const = 0; virtual UInt32 GetSampleRate() const = 0; virtual UInt64 Read(void* buffer, UInt64 sampleCount) = 0; virtual void Seek(UInt64 offset) = 0; + virtual UInt64 Tell() = 0; + + static SoundStreamRef OpenFromFile(const String& filePath, const SoundStreamParams& params = SoundStreamParams()); + static SoundStreamRef OpenFromMemory(const void* data, std::size_t size, const SoundStreamParams& params = SoundStreamParams()); + static SoundStreamRef OpenFromStream(Stream& stream, const SoundStreamParams& params = SoundStreamParams()); + + private: + static SoundStreamLoader::LoaderList s_loaders; }; } diff --git a/include/Nazara/Core/ObjectRef.hpp b/include/Nazara/Core/ObjectRef.hpp index c7959efc8..cb100c554 100644 --- a/include/Nazara/Core/ObjectRef.hpp +++ b/include/Nazara/Core/ObjectRef.hpp @@ -68,6 +68,10 @@ namespace Nz template bool operator>=(const T& lhs, const ObjectRef& rhs); template bool operator>=(const ObjectRef& lhs, const T& rhs); + template ObjectRef ConstRefCast(const ObjectRef& ref); + template ObjectRef DynamicRefCast(const ObjectRef& ref); + template ObjectRef ReinterpretRefCast(const ObjectRef& ref); + template ObjectRef StaticRefCast(const ObjectRef& ref); template struct PointedType> { using type = T; }; template struct PointedType const> { using type = T; }; diff --git a/include/Nazara/Core/ObjectRef.inl b/include/Nazara/Core/ObjectRef.inl index b4d89531c..f592fd501 100644 --- a/include/Nazara/Core/ObjectRef.inl +++ b/include/Nazara/Core/ObjectRef.inl @@ -480,6 +480,60 @@ namespace Nz { return !(lhs < rhs); } + + /*! + * \brief Casts an ObjectRef from one type to another using static_cast + * \return Reference to the casted object + * + * \param ref The reference to convert + * + * \remark It is an undefined behavior to cast between incompatible types + */ + template + ObjectRef ConstRefCast(const ObjectRef& ref) + { + return ObjectRef(const_cast(ref.Get())); + } + + /*! + * \brief Casts an ObjectRef from one type to another using static_cast + * \return Reference to the casted object + * + * \param ref The reference to convert + */ + template + ObjectRef DynamicRefCast(const ObjectRef& ref) + { + return ObjectRef(dynamic_cast(ref.Get())); + } + + /*! + * \brief Casts an ObjectRef from one type to another using static_cast + * \return Reference to the casted object + * + * \param ref The reference to convert + * + * \remark It is an undefined behavior to cast between incompatible types + */ + template + ObjectRef ReinterpretRefCast(const ObjectRef& ref) + { + return ObjectRef(static_cast(ref.Get())); + } + + /*! + * \brief Casts an ObjectRef from one type to another using static_cast + * \return Reference to the casted object + * + * \param ref The reference to convert + * + * \remark It is an undefined behavior to cast between incompatible types + */ + template + ObjectRef StaticRefCast(const ObjectRef& ref) + { + return ObjectRef(static_cast(ref.Get())); + } } namespace std @@ -504,3 +558,4 @@ namespace std } #include +#include "ObjectRef.hpp" diff --git a/include/Nazara/Core/ResourceLoader.hpp b/include/Nazara/Core/ResourceLoader.hpp index 3fce094e0..1bee093ee 100644 --- a/include/Nazara/Core/ResourceLoader.hpp +++ b/include/Nazara/Core/ResourceLoader.hpp @@ -8,6 +8,8 @@ #define NAZARA_RESOURCELOADER_HPP #include +#include +#include #include #include #include @@ -28,19 +30,19 @@ namespace Nz public: using ExtensionGetter = bool (*)(const String& extension); - using FileLoader = bool (*)(Type* resource, const String& filePath, const Parameters& parameters); - using MemoryLoader = bool (*)(Type* resource, const void* data, std::size_t size, const Parameters& parameters); + using FileLoader = ObjectRef (*)(const String& filePath, const Parameters& parameters); + using MemoryLoader = ObjectRef (*)(const void* data, std::size_t size, const Parameters& parameters); using StreamChecker = Ternary (*)(Stream& stream, const Parameters& parameters); - using StreamLoader = bool (*)(Type* resource, Stream& stream, const Parameters& parameters); + using StreamLoader = ObjectRef (*)(Stream& stream, const Parameters& parameters); ResourceLoader() = delete; ~ResourceLoader() = delete; static bool IsExtensionSupported(const String& extension); - static bool LoadFromFile(Type* resource, const String& filePath, const Parameters& parameters = Parameters()); - static bool LoadFromMemory(Type* resource, const void* data, std::size_t size, const Parameters& parameters = Parameters()); - static bool LoadFromStream(Type* resource, Stream& stream, const Parameters& parameters = Parameters()); + static ObjectRef LoadFromFile(const String& filePath, const Parameters& parameters = Parameters()); + static ObjectRef LoadFromMemory(const void* data, std::size_t size, const Parameters& parameters = Parameters()); + static ObjectRef LoadFromStream(Stream& stream, const Parameters& parameters = Parameters()); static void RegisterLoader(ExtensionGetter extensionGetter, StreamChecker checkFunc, StreamLoader streamLoader, FileLoader fileLoader = nullptr, MemoryLoader memoryLoader = nullptr); static void UnregisterLoader(ExtensionGetter extensionGetter, StreamChecker checkFunc, StreamLoader streamLoader, FileLoader fileLoader = nullptr, MemoryLoader memoryLoader = nullptr); diff --git a/include/Nazara/Core/ResourceLoader.inl b/include/Nazara/Core/ResourceLoader.inl index c60be5674..db143c3b0 100644 --- a/include/Nazara/Core/ResourceLoader.inl +++ b/include/Nazara/Core/ResourceLoader.inl @@ -53,9 +53,8 @@ namespace Nz * \remark Produces a NazaraError if all loaders failed or no loader was found */ template - bool ResourceLoader::LoadFromFile(Type* resource, const String& filePath, const Parameters& parameters) + ObjectRef ResourceLoader::LoadFromFile(const String& filePath, const Parameters& parameters) { - NazaraAssert(resource, "Invalid resource"); NazaraAssert(parameters.IsValid(), "Invalid parameters"); String path = File::NormalizePath(filePath); @@ -63,7 +62,7 @@ namespace Nz if (ext.IsEmpty()) { NazaraError("Failed to get file extension from \"" + filePath + '"'); - return false; + return nullptr; } File file(path); // Open only if needed @@ -84,7 +83,7 @@ namespace Nz if (!file.Open(OpenMode_ReadOnly)) { NazaraError("Failed to load file: unable to open \"" + filePath + '"'); - return false; + return nullptr; } } @@ -107,10 +106,11 @@ namespace Nz found = true; } - if (fileLoader(resource, filePath, parameters)) + ObjectRef resource = fileLoader(filePath, parameters); + if (resource) { resource->SetFilePath(filePath); - return true; + return resource; } } else @@ -125,10 +125,11 @@ namespace Nz file.SetCursorPos(0); - if (streamLoader(resource, file, parameters)) + ObjectRef resource = streamLoader(file, parameters); + if (resource) { resource->SetFilePath(filePath); - return true; + return resource; } } @@ -141,7 +142,7 @@ namespace Nz else NazaraError("Failed to load file: no loader found for extension \"" + ext + '"'); - return false; + return nullptr; } /*! @@ -160,9 +161,8 @@ namespace Nz * \remark Produces a NazaraError if all loaders failed or no loader was found */ template - bool ResourceLoader::LoadFromMemory(Type* resource, const void* data, std::size_t size, const Parameters& parameters) + ObjectRef ResourceLoader::LoadFromMemory(const void* data, std::size_t size, const Parameters& parameters) { - NazaraAssert(resource, "Invalid resource"); NazaraAssert(data, "Invalid data pointer"); NazaraAssert(size, "No data to load"); NazaraAssert(parameters.IsValid(), "Invalid parameters"); @@ -195,8 +195,9 @@ namespace Nz found = true; } - if (memoryLoader(resource, data, size, parameters)) - return true; + ObjectRef resource = memoryLoader(data, size, parameters); + if (resource) + return resource; } else { @@ -210,8 +211,9 @@ namespace Nz stream.SetCursorPos(0); - if (streamLoader(resource, stream, parameters)) - return true; + ObjectRef resource = streamLoader(stream, parameters); + if (resource) + return resource; } if (recognized == Ternary_True) @@ -223,7 +225,7 @@ namespace Nz else NazaraError("Failed to load file: no loader found"); - return false; + return nullptr; } /*! @@ -241,9 +243,8 @@ namespace Nz * \remark Produces a NazaraError if all loaders failed or no loader was found */ template - bool ResourceLoader::LoadFromStream(Type* resource, Stream& stream, const Parameters& parameters) + ObjectRef ResourceLoader::LoadFromStream(Stream& stream, const Parameters& parameters) { - NazaraAssert(resource, "Invalid resource"); NazaraAssert(stream.GetCursorPos() < stream.GetSize(), "No data to load"); NazaraAssert(parameters.IsValid(), "Invalid parameters"); @@ -267,8 +268,9 @@ namespace Nz stream.SetCursorPos(streamPos); // Load of the resource - if (streamLoader(resource, stream, parameters)) - return true; + ObjectRef resource = streamLoader(stream, parameters); + if (resource) + return resource; if (recognized == Ternary_True) NazaraWarning("Loader failed"); @@ -279,7 +281,7 @@ namespace Nz else NazaraError("Failed to load file: no loader found"); - return false; + return nullptr; } /*! diff --git a/include/Nazara/Core/ResourceManager.inl b/include/Nazara/Core/ResourceManager.inl index d590cc680..ca381fce7 100644 --- a/include/Nazara/Core/ResourceManager.inl +++ b/include/Nazara/Core/ResourceManager.inl @@ -37,14 +37,8 @@ namespace Nz auto it = Type::s_managerMap.find(absolutePath); if (it == Type::s_managerMap.end()) { - ObjectRef resource = Type::New(); + ObjectRef resource = Type::LoadFromFile(absolutePath, GetDefaultParameters()); if (!resource) - { - NazaraError("Failed to create resource"); - return ObjectRef(); - } - - if (!resource->LoadFromFile(absolutePath, GetDefaultParameters())) { NazaraError("Failed to load resource from file: " + absolutePath); return ObjectRef(); diff --git a/include/Nazara/Graphics/Material.hpp b/include/Nazara/Graphics/Material.hpp index 9903553a5..00cbbcbdb 100644 --- a/include/Nazara/Graphics/Material.hpp +++ b/include/Nazara/Graphics/Material.hpp @@ -137,10 +137,6 @@ namespace Nz inline bool IsShadowCastingEnabled() const; inline bool IsShadowReceiveEnabled() const; - inline bool LoadFromFile(const String& filePath, const MaterialParams& params = MaterialParams()); - inline bool LoadFromMemory(const void* data, std::size_t size, const MaterialParams& params = MaterialParams()); - inline bool LoadFromStream(Stream& stream, const MaterialParams& params = MaterialParams()); - void Reset(); void SaveToParameters(ParameterList* matData); @@ -180,6 +176,11 @@ namespace Nz inline static MaterialRef GetDefault(); inline static int GetTextureUnit(TextureMap textureMap); + + static inline MaterialRef LoadFromFile(const String& filePath, const MaterialParams& params = MaterialParams()); + static inline MaterialRef LoadFromMemory(const void* data, std::size_t size, const MaterialParams& params = MaterialParams()); + static inline MaterialRef LoadFromStream(Stream& stream, const MaterialParams& params = MaterialParams()); + template static MaterialRef New(Args&&... args); // Signals: diff --git a/include/Nazara/Graphics/Material.inl b/include/Nazara/Graphics/Material.inl index bf96d6bc5..32a59b1bb 100644 --- a/include/Nazara/Graphics/Material.inl +++ b/include/Nazara/Graphics/Material.inl @@ -895,43 +895,6 @@ namespace Nz return m_pipelineInfo.shadowReceive; } - /*! - * \brief Loads the material from file - * \return true if loading is successful - * - * \param filePath Path to the file - * \param params Parameters for the material - */ - inline bool Material::LoadFromFile(const String& filePath, const MaterialParams& params) - { - return MaterialLoader::LoadFromFile(this, filePath, params); - } - - /*! - * \brief Loads the material from memory - * \return true if loading is successful - * - * \param data Raw memory - * \param size Size of the memory - * \param params Parameters for the material - */ - inline bool Material::LoadFromMemory(const void* data, std::size_t size, const MaterialParams& params) - { - return MaterialLoader::LoadFromMemory(this, data, size, params); - } - - /*! - * \brief Loads the material from stream - * \return true if loading is successful - * - * \param stream Stream to the material - * \param params Parameters for the material - */ - inline bool Material::LoadFromStream(Stream& stream, const MaterialParams& params) - { - return MaterialLoader::LoadFromStream(this, stream, params); - } - /*! * \brief Sets the alpha map by name * \return true If successful @@ -1466,6 +1429,43 @@ namespace Nz return s_textureUnits[textureMap]; } + /*! + * \brief Loads the material from file + * \return true if loading is successful + * + * \param filePath Path to the file + * \param params Parameters for the material + */ + inline MaterialRef Material::LoadFromFile(const String& filePath, const MaterialParams& params) + { + return MaterialLoader::LoadFromFile(filePath, params); + } + + /*! + * \brief Loads the material from memory + * \return true if loading is successful + * + * \param data Raw memory + * \param size Size of the memory + * \param params Parameters for the material + */ + inline MaterialRef Material::LoadFromMemory(const void* data, std::size_t size, const MaterialParams& params) + { + return MaterialLoader::LoadFromMemory(data, size, params); + } + + /*! + * \brief Loads the material from stream + * \return true if loading is successful + * + * \param stream Stream to the material + * \param params Parameters for the material + */ + inline MaterialRef Material::LoadFromStream(Stream& stream, const MaterialParams& params) + { + return MaterialLoader::LoadFromStream(stream, params); + } + inline void Material::InvalidatePipeline() { m_pipelineUpdated = false; diff --git a/include/Nazara/Graphics/Model.hpp b/include/Nazara/Graphics/Model.hpp index dd2258e26..db73d4f98 100644 --- a/include/Nazara/Graphics/Model.hpp +++ b/include/Nazara/Graphics/Model.hpp @@ -65,10 +65,6 @@ namespace Nz virtual bool IsAnimated() const; - bool LoadFromFile(const String& filePath, const ModelParameters& params = ModelParameters()); - bool LoadFromMemory(const void* data, std::size_t size, const ModelParameters& params = ModelParameters()); - bool LoadFromStream(Stream& stream, const ModelParameters& params = ModelParameters()); - using InstancedRenderable::SetMaterial; bool SetMaterial(const String& subMeshName, MaterialRef material); bool SetMaterial(std::size_t skinIndex, const String& subMeshName, MaterialRef material); @@ -78,6 +74,10 @@ namespace Nz Model& operator=(const Model& node) = default; Model& operator=(Model&& node) = delete; + static ModelRef LoadFromFile(const String& filePath, const ModelParameters& params = ModelParameters()); + static ModelRef LoadFromMemory(const void* data, std::size_t size, const ModelParameters& params = ModelParameters()); + static ModelRef LoadFromStream(Stream& stream, const ModelParameters& params = ModelParameters()); + template static ModelRef New(Args&&... args); protected: diff --git a/include/Nazara/Graphics/Model.inl b/include/Nazara/Graphics/Model.inl index ee0ce7a41..9c1809368 100644 --- a/include/Nazara/Graphics/Model.inl +++ b/include/Nazara/Graphics/Model.inl @@ -59,7 +59,6 @@ namespace Nz * * \param args Arguments for the model */ - template ModelRef Model::New(Args&&... args) { diff --git a/include/Nazara/Graphics/SkeletalModel.hpp b/include/Nazara/Graphics/SkeletalModel.hpp index a36082619..b7ed266e2 100644 --- a/include/Nazara/Graphics/SkeletalModel.hpp +++ b/include/Nazara/Graphics/SkeletalModel.hpp @@ -26,12 +26,10 @@ namespace Nz class SkeletalModel; - using SkeletalModelLoader = ResourceLoader; + using SkeletalModelRef = ObjectRef; class NAZARA_GRAPHICS_API SkeletalModel : public Model, Updatable { - friend SkeletalModelLoader; - public: SkeletalModel(); SkeletalModel(const SkeletalModel& model) = default; @@ -55,10 +53,6 @@ namespace Nz bool IsAnimated() const override; bool IsAnimationEnabled() const; - bool LoadFromFile(const String& filePath, const SkeletalModelParameters& params = SkeletalModelParameters()); - bool LoadFromMemory(const void* data, std::size_t size, const SkeletalModelParameters& params = SkeletalModelParameters()); - bool LoadFromStream(Stream& stream, const SkeletalModelParameters& params = SkeletalModelParameters()); - bool SetAnimation(Animation* animation); void SetMesh(Mesh* mesh) override; bool SetSequence(const String& sequenceName); @@ -67,6 +61,8 @@ namespace Nz SkeletalModel& operator=(const SkeletalModel& node) = default; SkeletalModel& operator=(SkeletalModel&& node) = default; + template static SkeletalModelRef New(Args&&... args); + private: void MakeBoundingVolume() const override; /*void Register() override; @@ -80,9 +76,9 @@ namespace Nz float m_interpolation; unsigned int m_currentFrame; unsigned int m_nextFrame; - - static SkeletalModelLoader::LoaderList s_loaders; }; } +#include + #endif // NAZARA_SKELETALMODEL_HPP diff --git a/include/Nazara/Graphics/SkeletalModel.inl b/include/Nazara/Graphics/SkeletalModel.inl new file mode 100644 index 000000000..4bb2df2b6 --- /dev/null +++ b/include/Nazara/Graphics/SkeletalModel.inl @@ -0,0 +1,27 @@ +// Copyright (C) 2017 Jérôme Leclercq +// This file is part of the "Nazara Engine - Graphics module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#include +#include +#include + +namespace Nz +{ + /*! + * \brief Creates a new SkeletalModel from the arguments + * \return A reference to the newly created SkeletalModel + * + * \param args Arguments for the skeletal model + */ + template + SkeletalModelRef SkeletalModel::New(Args&&... args) + { + std::unique_ptr object(new SkeletalModel(std::forward(args)...)); + object->SetPersistent(false); + + return object.release(); + } +} + +#include diff --git a/include/Nazara/Renderer/Texture.hpp b/include/Nazara/Renderer/Texture.hpp index ef90efcf6..6d33dcdd5 100644 --- a/include/Nazara/Renderer/Texture.hpp +++ b/include/Nazara/Renderer/Texture.hpp @@ -38,7 +38,7 @@ namespace Nz public: Texture() = default; Texture(ImageType type, PixelFormatType format, unsigned int width, unsigned int height, unsigned int depth = 1, UInt8 levelCount = 1); - explicit Texture(const Image& image); + explicit Texture(const Image* image); Texture(const Texture&) = delete; Texture(Texture&&) = delete; ~Texture(); @@ -68,24 +68,6 @@ namespace Nz void InvalidateMipmaps(); bool IsValid() const; - // Load - bool LoadFromFile(const String& filePath, const ImageParams& params = ImageParams(), bool generateMipmaps = true); - bool LoadFromImage(const Image& image, bool generateMipmaps = true); - bool LoadFromMemory(const void* data, std::size_t size, const ImageParams& params = ImageParams(), bool generateMipmaps = true); - bool LoadFromStream(Stream& stream, const ImageParams& params = ImageParams(), bool generateMipmaps = true); - - // LoadArray - bool LoadArrayFromFile(const String& filePath, const ImageParams& imageParams = ImageParams(), bool generateMipmaps = true, const Vector2ui& atlasSize = Vector2ui(2, 2)); - bool LoadArrayFromImage(const Image& image, bool generateMipmaps = true, const Vector2ui& atlasSize = Vector2ui(2, 2)); - bool LoadArrayFromMemory(const void* data, std::size_t size, const ImageParams& imageParams = ImageParams(), bool generateMipmaps = true, const Vector2ui& atlasSize = Vector2ui(2, 2)); - bool LoadArrayFromStream(Stream& stream, const ImageParams& imageParams = ImageParams(), bool generateMipmaps = true, const Vector2ui& atlasSize = Vector2ui(2, 2)); - - // LoadCubemap - bool LoadCubemapFromFile(const String& filePath, const ImageParams& imageParams = ImageParams(), bool generateMipmaps = true, const CubemapParams& cubemapParams = CubemapParams()); - bool LoadCubemapFromImage(const Image& image, bool generateMipmaps = true, const CubemapParams& params = CubemapParams()); - bool LoadCubemapFromMemory(const void* data, std::size_t size, const ImageParams& imageParams = ImageParams(), bool generateMipmaps = true, const CubemapParams& cubemapParams = CubemapParams()); - bool LoadCubemapFromStream(Stream& stream, const ImageParams& imageParams = ImageParams(), bool generateMipmaps = true, const CubemapParams& cubemapParams = CubemapParams()); - // LoadFace bool LoadFaceFromFile(CubemapFace face, const String& filePath, const ImageParams& params = ImageParams()); bool LoadFaceFromMemory(CubemapFace face, const void* data, std::size_t size, const ImageParams& params = ImageParams()); @@ -97,9 +79,9 @@ namespace Nz bool SetMipmapRange(UInt8 minLevel, UInt8 maxLevel); - bool Update(const Image& image, UInt8 level = 0); - bool Update(const Image& image, const Boxui& box, UInt8 level = 0); - bool Update(const Image& image, const Rectui& rect, unsigned int z = 0, UInt8 level = 0); + bool Update(const Image* image, UInt8 level = 0); + bool Update(const Image* image, const Boxui& box, UInt8 level = 0); + bool Update(const Image* image, const Rectui& rect, unsigned int z = 0, UInt8 level = 0); bool Update(const UInt8* pixels, unsigned int srcWidth = 0, unsigned int srcHeight = 0, UInt8 level = 0) override; bool Update(const UInt8* pixels, const Boxui& box, unsigned int srcWidth = 0, unsigned int srcHeight = 0, UInt8 level = 0) override; bool Update(const UInt8* pixels, const Rectui& rect, unsigned int z = 0, unsigned int srcWidth = 0, unsigned int srcHeight = 0, UInt8 level = 0) override; @@ -113,6 +95,25 @@ namespace Nz static bool IsFormatSupported(PixelFormatType format); static bool IsMipmappingSupported(); static bool IsTypeSupported(ImageType type); + + // Load + static TextureRef LoadFromFile(const String& filePath, const ImageParams& params = ImageParams(), bool generateMipmaps = true); + static TextureRef LoadFromImage(const Image* image, bool generateMipmaps = true); + static TextureRef LoadFromMemory(const void* data, std::size_t size, const ImageParams& params = ImageParams(), bool generateMipmaps = true); + static TextureRef LoadFromStream(Stream& stream, const ImageParams& params = ImageParams(), bool generateMipmaps = true); + + // LoadArray + static TextureRef LoadArrayFromFile(const String& filePath, const ImageParams& imageParams = ImageParams(), bool generateMipmaps = true, const Vector2ui& atlasSize = Vector2ui(2, 2)); + static TextureRef LoadArrayFromImage(const Image* image, bool generateMipmaps = true, const Vector2ui& atlasSize = Vector2ui(2, 2)); + static TextureRef LoadArrayFromMemory(const void* data, std::size_t size, const ImageParams& imageParams = ImageParams(), bool generateMipmaps = true, const Vector2ui& atlasSize = Vector2ui(2, 2)); + static TextureRef LoadArrayFromStream(Stream& stream, const ImageParams& imageParams = ImageParams(), bool generateMipmaps = true, const Vector2ui& atlasSize = Vector2ui(2, 2)); + + // LoadCubemap + static TextureRef LoadCubemapFromFile(const String& filePath, const ImageParams& imageParams = ImageParams(), bool generateMipmaps = true, const CubemapParams& cubemapParams = CubemapParams()); + static TextureRef LoadCubemapFromImage(const Image* image, bool generateMipmaps = true, const CubemapParams& params = CubemapParams()); + static TextureRef LoadCubemapFromMemory(const void* data, std::size_t size, const ImageParams& imageParams = ImageParams(), bool generateMipmaps = true, const CubemapParams& cubemapParams = CubemapParams()); + static TextureRef LoadCubemapFromStream(Stream& stream, const ImageParams& imageParams = ImageParams(), bool generateMipmaps = true, const CubemapParams& cubemapParams = CubemapParams()); + template static TextureRef New(Args&&... args); // Signals: diff --git a/include/Nazara/Utility/Animation.hpp b/include/Nazara/Utility/Animation.hpp index f714aa5a6..85f3f3bc8 100644 --- a/include/Nazara/Utility/Animation.hpp +++ b/include/Nazara/Utility/Animation.hpp @@ -83,15 +83,15 @@ namespace Nz bool IsLoopPointInterpolationEnabled() const; bool IsValid() const; - bool LoadFromFile(const String& filePath, const AnimationParams& params = AnimationParams()); - bool LoadFromMemory(const void* data, std::size_t size, const AnimationParams& params = AnimationParams()); - bool LoadFromStream(Stream& stream, const AnimationParams& params = AnimationParams()); - void RemoveSequence(const String& sequenceName); void RemoveSequence(UInt32 index); template static AnimationRef New(Args&&... args); + static AnimationRef LoadFromFile(const String& filePath, const AnimationParams& params = AnimationParams()); + static AnimationRef LoadFromMemory(const void* data, std::size_t size, const AnimationParams& params = AnimationParams()); + static AnimationRef LoadFromStream(Stream& stream, const AnimationParams& params = AnimationParams()); + // Signals: NazaraSignal(OnAnimationDestroy, const Animation* /*animation*/); NazaraSignal(OnAnimationRelease, const Animation* /*animation*/); diff --git a/include/Nazara/Utility/Font.hpp b/include/Nazara/Utility/Font.hpp index 7f1a411cd..be67c92e7 100644 --- a/include/Nazara/Utility/Font.hpp +++ b/include/Nazara/Utility/Font.hpp @@ -76,11 +76,6 @@ namespace Nz bool Precache(unsigned int characterSize, UInt32 style, char32_t character) const; bool Precache(unsigned int characterSize, UInt32 style, const String& characterSet) const; - // Open - bool OpenFromFile(const String& filePath, const FontParams& params = FontParams()); - bool OpenFromMemory(const void* data, std::size_t size, const FontParams& params = FontParams()); - bool OpenFromStream(Stream& stream, const FontParams& params = FontParams()); - void SetAtlas(const std::shared_ptr& atlas); void SetGlyphBorder(unsigned int borderSize); void SetMinimumStepSize(unsigned int minimumStepSize); @@ -93,6 +88,10 @@ namespace Nz static unsigned int GetDefaultGlyphBorder(); static unsigned int GetDefaultMinimumStepSize(); + static FontRef OpenFromFile(const String& filePath, const FontParams& params = FontParams()); + static FontRef OpenFromMemory(const void* data, std::size_t size, const FontParams& params = FontParams()); + static FontRef OpenFromStream(Stream& stream, const FontParams& params = FontParams()); + template static FontRef New(Args&&... args); static void SetDefaultAtlas(const std::shared_ptr& atlas); diff --git a/include/Nazara/Utility/Image.hpp b/include/Nazara/Utility/Image.hpp index ccefd2fee..3c3427b88 100644 --- a/include/Nazara/Utility/Image.hpp +++ b/include/Nazara/Utility/Image.hpp @@ -63,7 +63,7 @@ namespace Nz bool Convert(PixelFormatType format); - void Copy(const Image& source, const Boxui& srcBox, const Vector3ui& dstPos); + void Copy(const Image* source, const Boxui& srcBox, const Vector3ui& dstPos); bool Create(ImageType type, PixelFormatType format, unsigned int width, unsigned int height, unsigned int depth = 1, UInt8 levelCount = 1); void Destroy(); @@ -93,23 +93,6 @@ namespace Nz bool IsValid() const; - // Load - bool LoadFromFile(const String& filePath, const ImageParams& params = ImageParams()); - bool LoadFromMemory(const void* data, std::size_t size, const ImageParams& params = ImageParams()); - bool LoadFromStream(Stream& stream, const ImageParams& params = ImageParams()); - - // LoadArray - bool LoadArrayFromFile(const String& filePath, const ImageParams& imageParams = ImageParams(), const Vector2ui& atlasSize = Vector2ui(2, 2)); - bool LoadArrayFromImage(const Image& image, const Vector2ui& atlasSize = Vector2ui(2, 2)); - bool LoadArrayFromMemory(const void* data, std::size_t size, const ImageParams& imageParams = ImageParams(), const Vector2ui& atlasSize = Vector2ui(2, 2)); - bool LoadArrayFromStream(Stream& stream, const ImageParams& imageParams = ImageParams(), const Vector2ui& atlasSize = Vector2ui(2, 2)); - - // LoadCubemap - bool LoadCubemapFromFile(const String& filePath, const ImageParams& imageParams = ImageParams(), const CubemapParams& cubemapParams = CubemapParams()); - bool LoadCubemapFromImage(const Image& image, const CubemapParams& params = CubemapParams()); - bool LoadCubemapFromMemory(const void* data, std::size_t size, const ImageParams& imageParams = ImageParams(), const CubemapParams& cubemapParams = CubemapParams()); - bool LoadCubemapFromStream(Stream& stream, const ImageParams& imageParams = ImageParams(), const CubemapParams& cubemapParams = CubemapParams()); - // LoadFace bool LoadFaceFromFile(CubemapFace face, const String& filePath, const ImageParams& params = ImageParams()); bool LoadFaceFromMemory(CubemapFace face, const void* data, std::size_t size, const ImageParams& params = ImageParams()); @@ -133,6 +116,24 @@ namespace Nz static void Copy(UInt8* destination, const UInt8* source, PixelFormatType format, unsigned int width, unsigned int height, unsigned int depth = 1, unsigned int dstWidth = 0, unsigned int dstHeight = 0, unsigned int srcWidth = 0, unsigned int srcHeight = 0); static UInt8 GetMaxLevel(unsigned int width, unsigned int height, unsigned int depth = 1); static UInt8 GetMaxLevel(ImageType type, unsigned int width, unsigned int height, unsigned int depth = 1); + + // Load + static ImageRef LoadFromFile(const String& filePath, const ImageParams& params = ImageParams()); + static ImageRef LoadFromMemory(const void* data, std::size_t size, const ImageParams& params = ImageParams()); + static ImageRef LoadFromStream(Stream& stream, const ImageParams& params = ImageParams()); + + // LoadArray + static ImageRef LoadArrayFromFile(const String& filePath, const ImageParams& imageParams = ImageParams(), const Vector2ui& atlasSize = Vector2ui(2, 2)); + static ImageRef LoadArrayFromImage(const Image* image, const Vector2ui& atlasSize = Vector2ui(2, 2)); + static ImageRef LoadArrayFromMemory(const void* data, std::size_t size, const ImageParams& imageParams = ImageParams(), const Vector2ui& atlasSize = Vector2ui(2, 2)); + static ImageRef LoadArrayFromStream(Stream& stream, const ImageParams& imageParams = ImageParams(), const Vector2ui& atlasSize = Vector2ui(2, 2)); + + // LoadCubemap + static ImageRef LoadCubemapFromFile(const String& filePath, const ImageParams& imageParams = ImageParams(), const CubemapParams& cubemapParams = CubemapParams()); + static ImageRef LoadCubemapFromImage(const Image* image, const CubemapParams& params = CubemapParams()); + static ImageRef LoadCubemapFromMemory(const void* data, std::size_t size, const ImageParams& imageParams = ImageParams(), const CubemapParams& cubemapParams = CubemapParams()); + static ImageRef LoadCubemapFromStream(Stream& stream, const ImageParams& imageParams = ImageParams(), const CubemapParams& cubemapParams = CubemapParams()); + template static ImageRef New(Args&&... args); struct SharedImage diff --git a/include/Nazara/Utility/Mesh.hpp b/include/Nazara/Utility/Mesh.hpp index 0ecd9eb3a..3c1169bfc 100644 --- a/include/Nazara/Utility/Mesh.hpp +++ b/include/Nazara/Utility/Mesh.hpp @@ -128,10 +128,6 @@ namespace Nz bool IsAnimable() const; bool IsValid() const; - bool LoadFromFile(const String& filePath, const MeshParams& params = MeshParams()); - bool LoadFromMemory(const void* data, std::size_t size, const MeshParams& params = MeshParams()); - bool LoadFromStream(Stream& stream, const MeshParams& params = MeshParams()); - void Recenter(); void RemoveSubMesh(const String& identifier); @@ -149,6 +145,10 @@ namespace Nz Mesh& operator=(const Mesh&) = delete; Mesh& operator=(Mesh&&) = delete; + static MeshRef LoadFromFile(const String& filePath, const MeshParams& params = MeshParams()); + static MeshRef LoadFromMemory(const void* data, std::size_t size, const MeshParams& params = MeshParams()); + static MeshRef LoadFromStream(Stream& stream, const MeshParams& params = MeshParams()); + template static MeshRef New(Args&&... args); // Signals: diff --git a/plugins/Assimp/Plugin.cpp b/plugins/Assimp/Plugin.cpp index 4320ae098..b91337f9a 100644 --- a/plugins/Assimp/Plugin.cpp +++ b/plugins/Assimp/Plugin.cpp @@ -59,6 +59,8 @@ void ProcessJoints(aiNode* node, Skeleton* skeleton, const std::set& node->mTransformation.c1, node->mTransformation.c2, node->mTransformation.c3, node->mTransformation.c4, node->mTransformation.d1, node->mTransformation.d2, node->mTransformation.d3, node->mTransformation.d4); + transformMatrix.Transpose(); + transformMatrix.InverseAffine(); joint->SetInverseBindMatrix(transformMatrix); @@ -84,7 +86,7 @@ Ternary Check(Stream& /*stream*/, const MeshParams& parameters) return Ternary_Unknown; } -bool Load(Mesh* mesh, Stream& stream, const MeshParams& parameters) +MeshRef Load(Stream& stream, const MeshParams& parameters) { Nz::String streamPath = stream.GetPath(); @@ -147,7 +149,7 @@ bool Load(Mesh* mesh, Stream& stream, const MeshParams& parameters) if (!scene) { NazaraError("Assimp failed to import file: " + Nz::String(aiGetErrorString())); - return false; + return nullptr; } std::set joints; @@ -167,6 +169,7 @@ bool Load(Mesh* mesh, Stream& stream, const MeshParams& parameters) } } + MeshRef mesh = Mesh::New(); if (animatedMesh) { mesh->CreateSkeletal(UInt32(joints.size())); @@ -180,7 +183,7 @@ bool Load(Mesh* mesh, Stream& stream, const MeshParams& parameters) ProcessJoints(scene->mRootNode, skeleton, joints); - return false; + return nullptr; } else { @@ -375,7 +378,7 @@ bool Load(Mesh* mesh, Stream& stream, const MeshParams& parameters) aiReleaseImport(scene); - return true; + return mesh; } extern "C" diff --git a/src/Nazara/Audio/Formats/sndfileLoader.cpp b/src/Nazara/Audio/Formats/sndfileLoader.cpp index 25c30e4ad..75bb3e62f 100644 --- a/src/Nazara/Audio/Formats/sndfileLoader.cpp +++ b/src/Nazara/Audio/Formats/sndfileLoader.cpp @@ -14,7 +14,9 @@ #include #include #include +#include #include +#include #include #include #include @@ -97,6 +99,11 @@ namespace Nz return m_format; } + Mutex& GetMutex() override + { + return m_mutex; + } + UInt64 GetSampleCount() const override { return m_sampleCount; @@ -124,7 +131,7 @@ namespace Nz bool Open(const void* data, std::size_t size, bool forceMono) { - m_ownedStream.reset(new MemoryView(data, size)); + m_ownedStream = std::make_unique(data, size); return Open(*m_ownedStream, forceMono); } @@ -201,12 +208,18 @@ namespace Nz sf_seek(m_handle, offset*m_sampleRate / 1000, SEEK_SET); } + UInt64 Tell() override + { + return sf_seek(m_handle, 0, SEEK_CUR) * 1000 / m_sampleRate; + } + private: std::vector m_mixBuffer; std::unique_ptr m_ownedStream; AudioFormat m_format; SNDFILE* m_handle; bool m_mixToMono; + Mutex m_mutex; UInt32 m_duration; UInt32 m_sampleRate; UInt64 m_sampleCount; @@ -222,7 +235,7 @@ namespace Nz return supportedExtensions.find(extension) != supportedExtensions.end(); } - Ternary CheckMusic(Stream& stream, const MusicParams& parameters) + Ternary CheckSoundStream(Stream& stream, const SoundStreamParams& parameters) { NazaraUnused(parameters); @@ -240,67 +253,43 @@ namespace Nz return Ternary_False; } - bool LoadMusicFile(Music* music, const String& filePath, const MusicParams& parameters) + SoundStreamRef LoadSoundStreamFile(const String& filePath, const SoundStreamParams& parameters) { - std::unique_ptr musicStream(new sndfileStream); - if (!musicStream->Open(filePath, parameters.forceMono)) + std::unique_ptr soundStream(new sndfileStream); + if (!soundStream->Open(filePath, parameters.forceMono)) { - NazaraError("Failed to open music stream"); - return false; + NazaraError("Failed to open sound stream"); + return nullptr; } - if (!music->Create(musicStream.get())) // Transfert de propriété - { - NazaraError("Failed to create music"); - return false; - } - - // Le pointeur a été transféré avec succès, nous pouvons laisser tomber la propriété - musicStream.release(); - - return true; + soundStream->SetPersistent(false); + return soundStream.release(); } - bool LoadMusicMemory(Music* music, const void* data, std::size_t size, const MusicParams& parameters) + SoundStreamRef LoadSoundStreamMemory(const void* data, std::size_t size, const SoundStreamParams& parameters) { - std::unique_ptr musicStream(new sndfileStream); - if (!musicStream->Open(data, size, parameters.forceMono)) + std::unique_ptr soundStream(new sndfileStream); + if (!soundStream->Open(data, size, parameters.forceMono)) { NazaraError("Failed to open music stream"); - return false; + return nullptr; } - if (!music->Create(musicStream.get())) // Transfert de propriété - { - NazaraError("Failed to create music"); - return false; - } - - // Le pointeur a été transféré avec succès, nous pouvons laisser tomber la propriété - musicStream.release(); - - return true; + soundStream->SetPersistent(false); + return soundStream.release(); } - bool LoadMusicStream(Music* music, Stream& stream, const MusicParams& parameters) + SoundStreamRef LoadSoundStreamStream(Stream& stream, const SoundStreamParams& parameters) { - std::unique_ptr musicStream(new sndfileStream); - if (!musicStream->Open(stream, parameters.forceMono)) + std::unique_ptr soundStream(new sndfileStream); + if (!soundStream->Open(stream, parameters.forceMono)) { NazaraError("Failed to open music stream"); - return false; + return nullptr; } - if (!music->Create(musicStream.get())) // Transfert de propriété - { - NazaraError("Failed to create music"); - return false; - } - - // Le pointeur a été transféré avec succès, nous pouvons laisser tomber la propriété - musicStream.release(); - - return true; + soundStream->SetPersistent(false); + return soundStream.release(); } Ternary CheckSoundBuffer(Stream& stream, const SoundBufferParams& parameters) @@ -320,7 +309,7 @@ namespace Nz return Ternary_False; } - bool LoadSoundBuffer(SoundBuffer* soundBuffer, Stream& stream, const SoundBufferParams& parameters) + SoundBufferRef LoadSoundBuffer(Stream& stream, const SoundBufferParams& parameters) { SF_INFO info; info.format = 0; @@ -329,7 +318,7 @@ namespace Nz if (!file) { NazaraError("Failed to load sound file: " + String(sf_strerror(file))); - return false; + return nullptr; } // Lynix utilise RAII... @@ -344,7 +333,7 @@ namespace Nz if (format == AudioFormat_Unknown) { NazaraError("Channel count not handled"); - return false; + return nullptr; } // https://github.com/LaurentGomila/SFML/issues/271 @@ -359,7 +348,7 @@ namespace Nz if (sf_read_short(file, samples.get(), sampleCount) != sampleCount) { NazaraError("Failed to read samples"); - return false; + return nullptr; } // Une conversion en mono est-elle nécessaire ? @@ -372,13 +361,7 @@ namespace Nz sampleCount = static_cast(info.frames); } - if (!soundBuffer->Create(format, sampleCount, info.samplerate, samples.get())) - { - NazaraError("Failed to create sound buffer"); - return false; - } - - return true; + return SoundBuffer::New(format, sampleCount, info.samplerate, samples.get()); } } @@ -386,14 +369,14 @@ namespace Nz { void Register_sndfile() { - MusicLoader::RegisterLoader(Detail::IsSupported, Detail::CheckMusic, Detail::LoadMusicStream, Detail::LoadMusicFile, Detail::LoadMusicMemory); SoundBufferLoader::RegisterLoader(Detail::IsSupported, Detail::CheckSoundBuffer, Detail::LoadSoundBuffer); + SoundStreamLoader::RegisterLoader(Detail::IsSupported, Detail::CheckSoundStream, Detail::LoadSoundStreamStream, Detail::LoadSoundStreamFile, Detail::LoadSoundStreamMemory); } void Unregister_sndfile() { - MusicLoader::UnregisterLoader(Detail::IsSupported, Detail::CheckMusic, Detail::LoadMusicStream, Detail::LoadMusicFile, Detail::LoadMusicMemory); SoundBufferLoader::UnregisterLoader(Detail::IsSupported, Detail::CheckSoundBuffer, Detail::LoadSoundBuffer); + SoundStreamLoader::UnregisterLoader(Detail::IsSupported, Detail::CheckSoundStream, Detail::LoadSoundStreamStream, Detail::LoadSoundStreamFile, Detail::LoadSoundStreamMemory); } } } diff --git a/src/Nazara/Audio/Music.cpp b/src/Nazara/Audio/Music.cpp index 221cb9d50..356b1b51a 100644 --- a/src/Nazara/Audio/Music.cpp +++ b/src/Nazara/Audio/Music.cpp @@ -5,9 +5,12 @@ #include #include #include +#include #include #include +#include #include +#include #include #include @@ -21,24 +24,15 @@ namespace Nz * \remark Module Audio needs to be initialized to use this class */ - /*! - * \brief Checks whether the parameters for the loading of the music are correct - * \return true If parameters are valid - */ - - bool MusicParams::IsValid() const - { - return true; - } - struct MusicImpl { ALenum audioFormat; - std::unique_ptr stream; + std::atomic processedSamples; std::vector chunkSamples; Mutex bufferLock; + SoundStreamRef stream; Thread thread; - UInt64 processedSamples; + UInt64 playingOffset; bool loop = false; bool streaming = false; unsigned int sampleRate; @@ -74,7 +68,7 @@ namespace Nz m_impl->sampleRate = soundStream->GetSampleRate(); m_impl->audioFormat = OpenAL::AudioFormat[format]; m_impl->chunkSamples.resize(format * m_impl->sampleRate); // One second of samples - m_impl->stream.reset(soundStream); + m_impl->stream = soundStream; SetPlayingOffset(0); @@ -221,9 +215,12 @@ namespace Nz * \param filePath Path to the file * \param params Parameters for the music */ - bool Music::OpenFromFile(const String& filePath, const MusicParams& params) + bool Music::OpenFromFile(const String& filePath, const SoundStreamParams& params) { - return MusicLoader::LoadFromFile(this, filePath, params); + if (SoundStreamRef soundStream = SoundStream::OpenFromFile(filePath, params)) + return Create(soundStream); + else + return false; } /*! @@ -236,9 +233,12 @@ namespace Nz * * \remark The memory pointer must stay valid (accessible) as long as the music is playing */ - bool Music::OpenFromMemory(const void* data, std::size_t size, const MusicParams& params) + bool Music::OpenFromMemory(const void* data, std::size_t size, const SoundStreamParams& params) { - return MusicLoader::LoadFromMemory(this, data, size, params); + if (SoundStreamRef soundStream = SoundStream::OpenFromMemory(data, size, params)) + return Create(soundStream); + else + return false; } /*! @@ -250,9 +250,12 @@ namespace Nz * * \remark The stream must stay valid as long as the music is playing */ - bool Music::OpenFromStream(Stream& stream, const MusicParams& params) + bool Music::OpenFromStream(Stream& stream, const SoundStreamParams& params) { - return MusicLoader::LoadFromStream(this, stream, params); + if (SoundStreamRef soundStream = SoundStream::OpenFromStream(stream, params)) + return Create(soundStream); + else + return false; } /*! @@ -324,7 +327,7 @@ namespace Nz if (isPlaying) Stop(); - m_impl->stream->Seek(offset); + m_impl->playingOffset = offset; m_impl->processedSamples = UInt64(offset) * m_impl->sampleRate * m_impl->stream->GetFormat() / 1000ULL; if (isPlaying) @@ -349,6 +352,10 @@ namespace Nz std::size_t sampleCount = m_impl->chunkSamples.size(); std::size_t sampleRead = 0; + Nz::LockGuard lock(m_impl->stream->GetMutex()); + + m_impl->stream->Seek(m_impl->playingOffset); + // Fill the buffer by reading from the stream for (;;) { @@ -364,6 +371,10 @@ namespace Nz break; } + m_impl->playingOffset = m_impl->stream->Tell(); + + lock.Unlock(); + // Update the buffer (send it to OpenAL) and queue it if we got any data if (sampleRead > 0) { @@ -380,9 +391,9 @@ namespace Nz ALuint buffers[NAZARA_AUDIO_STREAMED_BUFFER_COUNT]; alGenBuffers(NAZARA_AUDIO_STREAMED_BUFFER_COUNT, buffers); - for (unsigned int i = 0; i < NAZARA_AUDIO_STREAMED_BUFFER_COUNT; ++i) + for (unsigned int buffer : buffers) { - if (FillAndQueueBuffer(buffers[i])) + if (FillAndQueueBuffer(buffer)) break; // We have reached the end of the stream, there is no use to add new buffers } @@ -448,6 +459,4 @@ namespace Nz m_impl->thread.Join(); } } - - MusicLoader::LoaderList Music::s_loaders; } diff --git a/src/Nazara/Audio/Sound.cpp b/src/Nazara/Audio/Sound.cpp index 6937e1ec2..d4a9e8e06 100644 --- a/src/Nazara/Audio/Sound.cpp +++ b/src/Nazara/Audio/Sound.cpp @@ -151,8 +151,8 @@ namespace Nz */ bool Sound::LoadFromFile(const String& filePath, const SoundBufferParams& params) { - SoundBufferRef buffer = SoundBuffer::New(); - if (!buffer->LoadFromFile(filePath, params)) + SoundBufferRef buffer = SoundBuffer::LoadFromFile(filePath, params); + if (!buffer) { NazaraError("Failed to load buffer from file (" + filePath + ')'); return false; @@ -174,8 +174,8 @@ namespace Nz */ bool Sound::LoadFromMemory(const void* data, std::size_t size, const SoundBufferParams& params) { - SoundBufferRef buffer = SoundBuffer::New(); - if (!buffer->LoadFromMemory(data, size, params)) + SoundBufferRef buffer = SoundBuffer::LoadFromMemory(data, size, params); + if (!buffer) { NazaraError("Failed to load buffer from memory (" + String::Pointer(data) + ')'); return false; @@ -196,8 +196,8 @@ namespace Nz */ bool Sound::LoadFromStream(Stream& stream, const SoundBufferParams& params) { - SoundBufferRef buffer = SoundBuffer::New(); - if (!buffer->LoadFromStream(stream, params)) + SoundBufferRef buffer = SoundBuffer::LoadFromStream(stream, params); + if (!buffer) { NazaraError("Failed to load buffer from stream"); return false; diff --git a/src/Nazara/Audio/SoundBuffer.cpp b/src/Nazara/Audio/SoundBuffer.cpp index 2888710f1..e1570b36e 100644 --- a/src/Nazara/Audio/SoundBuffer.cpp +++ b/src/Nazara/Audio/SoundBuffer.cpp @@ -152,7 +152,7 @@ namespace Nz m_impl->format = format; m_impl->sampleCount = sampleCount; m_impl->sampleRate = sampleRate; - m_impl->samples.reset(new Int16[sampleCount]); + m_impl->samples = std::make_unique(sampleCount); std::memcpy(&m_impl->samples[0], samples, sampleCount*sizeof(Int16)); clearBufferOnExit.Reset(); @@ -251,6 +251,17 @@ namespace Nz return m_impl != nullptr; } + /*! + * \brief Checks whether the format is supported by the engine + * \return true if it is the case + * + * \param format Format to check + */ + bool SoundBuffer::IsFormatSupported(AudioFormat format) + { + return Audio::IsFormatSupported(format); + } + /*! * \brief Loads the sound buffer from file * \return true if loading is successful @@ -258,9 +269,9 @@ namespace Nz * \param filePath Path to the file * \param params Parameters for the sound buffer */ - bool SoundBuffer::LoadFromFile(const String& filePath, const SoundBufferParams& params) + SoundBufferRef SoundBuffer::LoadFromFile(const String& filePath, const SoundBufferParams& params) { - return SoundBufferLoader::LoadFromFile(this, filePath, params); + return SoundBufferLoader::LoadFromFile(filePath, params); } /*! @@ -271,9 +282,9 @@ namespace Nz * \param size Size of the memory * \param params Parameters for the sound buffer */ - bool SoundBuffer::LoadFromMemory(const void* data, std::size_t size, const SoundBufferParams& params) + SoundBufferRef SoundBuffer::LoadFromMemory(const void* data, std::size_t size, const SoundBufferParams& params) { - return SoundBufferLoader::LoadFromMemory(this, data, size, params); + return SoundBufferLoader::LoadFromMemory(data, size, params); } /*! @@ -283,20 +294,9 @@ namespace Nz * \param stream Stream to the sound buffer * \param params Parameters for the sound buffer */ - bool SoundBuffer::LoadFromStream(Stream& stream, const SoundBufferParams& params) + SoundBufferRef SoundBuffer::LoadFromStream(Stream& stream, const SoundBufferParams& params) { - return SoundBufferLoader::LoadFromStream(this, stream, params); - } - - /*! - * \brief Checks whether the format is supported by the engine - * \return true if it is the case - * - * \param format Format to check - */ - bool SoundBuffer::IsFormatSupported(AudioFormat format) - { - return Audio::IsFormatSupported(format); + return SoundBufferLoader::LoadFromStream(stream, params); } /*! diff --git a/src/Nazara/Audio/SoundStream.cpp b/src/Nazara/Audio/SoundStream.cpp index eec87ccc1..0051b5596 100644 --- a/src/Nazara/Audio/SoundStream.cpp +++ b/src/Nazara/Audio/SoundStream.cpp @@ -6,6 +6,11 @@ namespace Nz { + bool SoundStreamParams::IsValid() const + { + return true; + } + /*! * \ingroup audio * \class Nz::SoundStream @@ -15,4 +20,21 @@ namespace Nz */ SoundStream::~SoundStream() = default; + + SoundStreamRef SoundStream::OpenFromFile(const String& filePath, const SoundStreamParams& params) + { + return SoundStreamLoader::LoadFromFile(filePath, params); + } + + SoundStreamRef SoundStream::OpenFromMemory(const void* data, std::size_t size, const SoundStreamParams& params) + { + return SoundStreamLoader::LoadFromMemory(data, size, params); + } + + SoundStreamRef SoundStream::OpenFromStream(Stream& stream, const SoundStreamParams& params) + { + return SoundStreamLoader::LoadFromStream(stream, params); + } + + SoundStreamLoader::LoaderList SoundStream::s_loaders; } diff --git a/src/Nazara/Graphics/Formats/MeshLoader.cpp b/src/Nazara/Graphics/Formats/MeshLoader.cpp index 439039cad..d21ed58c1 100644 --- a/src/Nazara/Graphics/Formats/MeshLoader.cpp +++ b/src/Nazara/Graphics/Formats/MeshLoader.cpp @@ -31,8 +31,7 @@ namespace Nz filePath += ".tga"; } - MaterialRef material = Material::New(); - if (material->LoadFromFile(filePath, parameters.material)) + if (MaterialRef material = Material::LoadFromFile(filePath, parameters.material)) model->SetMaterial(i, std::move(material)); else NazaraWarning("Failed to load material from file " + String::Number(i)); @@ -47,7 +46,7 @@ namespace Nz } } - Ternary CheckStatic(Stream& stream, const ModelParameters& parameters) + Ternary Check(Stream& stream, const ModelParameters& parameters) { NazaraUnused(stream); @@ -58,65 +57,29 @@ namespace Nz return Ternary_Unknown; } - bool LoadStatic(Model* model, Stream& stream, const ModelParameters& parameters) + ModelRef Load(Stream& stream, const ModelParameters& parameters) { NazaraUnused(parameters); - MeshRef mesh = Mesh::New(); - if (!mesh->LoadFromStream(stream, parameters.mesh)) + MeshRef mesh = Mesh::LoadFromStream(stream, parameters.mesh); + if (!mesh) { NazaraError("Failed to load model mesh"); - return false; + return nullptr; } + ModelRef model; if (mesh->IsAnimable()) - { - NazaraError("Can't load animated mesh into static model"); - return false; - } + model = SkeletalModel::New(); + else + model = Model::New(); model->SetMesh(mesh); if (parameters.loadMaterials) LoadMaterials(model, parameters); - return true; - } - - Ternary CheckAnimated(Stream& stream, const SkeletalModelParameters& parameters) - { - NazaraUnused(stream); - - bool skip; - if (parameters.custom.GetBooleanParameter("SkipNativeAnimatedMeshLoader", &skip) && skip) - return Ternary_False; - - return Ternary_Unknown; - } - - bool LoadAnimated(SkeletalModel* model, Stream& stream, const SkeletalModelParameters& parameters) - { - NazaraUnused(parameters); - - MeshRef mesh = Mesh::New(); - if (!mesh->LoadFromStream(stream, parameters.mesh)) - { - NazaraError("Failed to load model mesh"); - return false; - } - - if (!mesh->IsAnimable()) - { - NazaraError("Can't load static mesh into animated model"); - return false; - } - - model->SetMesh(mesh); - - if (parameters.loadMaterials) - LoadMaterials(model, parameters); - - return true; + return model; } } @@ -124,14 +87,12 @@ namespace Nz { void RegisterMesh() { - ModelLoader::RegisterLoader(MeshLoader::IsExtensionSupported, CheckStatic, LoadStatic); - SkeletalModelLoader::RegisterLoader(MeshLoader::IsExtensionSupported, CheckAnimated, LoadAnimated); + ModelLoader::RegisterLoader(MeshLoader::IsExtensionSupported, Check, Load); } void UnregisterMesh() { - ModelLoader::UnregisterLoader(MeshLoader::IsExtensionSupported, CheckStatic, LoadStatic); - SkeletalModelLoader::UnregisterLoader(MeshLoader::IsExtensionSupported, CheckAnimated, LoadAnimated); + ModelLoader::UnregisterLoader(MeshLoader::IsExtensionSupported, Check, Load); } } } diff --git a/src/Nazara/Graphics/Formats/TextureLoader.cpp b/src/Nazara/Graphics/Formats/TextureLoader.cpp index 02f51d5ad..cda56c187 100644 --- a/src/Nazara/Graphics/Formats/TextureLoader.cpp +++ b/src/Nazara/Graphics/Formats/TextureLoader.cpp @@ -22,22 +22,22 @@ namespace Nz return Ternary_Unknown; } - bool Load(Material* material, Stream& stream, const MaterialParams& parameters) + MaterialRef Load(Stream& stream, const MaterialParams& parameters) { NazaraUnused(parameters); - TextureRef texture = Texture::New(); - if (!texture->LoadFromStream(stream)) + TextureRef texture = Texture::LoadFromStream(stream); + if (!texture) { NazaraError("Failed to load diffuse map"); - return false; + return nullptr; } - material->Reset(); + MaterialRef material = Material::New(); material->SetDiffuseMap(texture); material->SetShader(parameters.shaderName); - return true; + return material; } } diff --git a/src/Nazara/Graphics/GuillotineTextureAtlas.cpp b/src/Nazara/Graphics/GuillotineTextureAtlas.cpp index 16ae46be4..9c59baa7b 100644 --- a/src/Nazara/Graphics/GuillotineTextureAtlas.cpp +++ b/src/Nazara/Graphics/GuillotineTextureAtlas.cpp @@ -52,7 +52,7 @@ namespace Nz return nullptr; } - if (!newTexture->Update(image, Rectui(0, 0, image.GetWidth(), image.GetHeight()))) + if (!newTexture->Update(&image, Rectui(0, 0, image.GetWidth(), image.GetHeight()))) { NazaraError("Failed to update texture"); return nullptr; diff --git a/src/Nazara/Graphics/Model.cpp b/src/Nazara/Graphics/Model.cpp index b725caef8..5a6b1cfca 100644 --- a/src/Nazara/Graphics/Model.cpp +++ b/src/Nazara/Graphics/Model.cpp @@ -149,46 +149,6 @@ namespace Nz return false; } - /*! - * \brief Loads the model from file - * \return true if loading is successful - * - * \param filePath Path to the file - * \param params Parameters for the model - */ - - bool Model::LoadFromFile(const String& filePath, const ModelParameters& params) - { - return ModelLoader::LoadFromFile(this, filePath, params); - } - - /*! - * \brief Loads the model from memory - * \return true if loading is successful - * - * \param data Raw memory - * \param size Size of the memory - * \param params Parameters for the model - */ - - bool Model::LoadFromMemory(const void* data, std::size_t size, const ModelParameters& params) - { - return ModelLoader::LoadFromMemory(this, data, size, params); - } - - /*! - * \brief Loads the model from stream - * \return true if loading is successful - * - * \param stream Stream to the model - * \param params Parameters for the model - */ - - bool Model::LoadFromStream(Stream& stream, const ModelParameters& params) - { - return ModelLoader::LoadFromStream(this, stream, params); - } - /*! * \brief Sets the material of the named submesh * \return true If successful @@ -272,6 +232,43 @@ namespace Nz InvalidateBoundingVolume(); } + /*! + * \brief Loads the model from file + * \return true if loading is successful + * + * \param filePath Path to the file + * \param params Parameters for the model + */ + ModelRef Model::LoadFromFile(const String& filePath, const ModelParameters& params) + { + return ModelLoader::LoadFromFile(filePath, params); + } + + /*! + * \brief Loads the model from memory + * \return true if loading is successful + * + * \param data Raw memory + * \param size Size of the memory + * \param params Parameters for the model + */ + ModelRef Model::LoadFromMemory(const void* data, std::size_t size, const ModelParameters& params) + { + return ModelLoader::LoadFromMemory(data, size, params); + } + + /*! + * \brief Loads the model from stream + * \return true if loading is successful + * + * \param stream Stream to the model + * \param params Parameters for the model + */ + ModelRef Model::LoadFromStream(Stream& stream, const ModelParameters& params) + { + return ModelLoader::LoadFromStream(stream, params); + } + /* * \brief Makes the bounding volume of this billboard */ diff --git a/src/Nazara/Graphics/SkeletalModel.cpp b/src/Nazara/Graphics/SkeletalModel.cpp index 03d22f648..30ee9396d 100644 --- a/src/Nazara/Graphics/SkeletalModel.cpp +++ b/src/Nazara/Graphics/SkeletalModel.cpp @@ -220,46 +220,6 @@ namespace Nz return m_animationEnabled; } - /*! - * \brief Loads the skeleton model from file - * \return true if loading is successful - * - * \param filePath Path to the file - * \param params Parameters for the skeleton model - */ - - bool SkeletalModel::LoadFromFile(const String& filePath, const SkeletalModelParameters& params) - { - return SkeletalModelLoader::LoadFromFile(this, filePath, params); - } - - /*! - * \brief Loads the skeleton model from memory - * \return true if loading is successful - * - * \param data Raw memory - * \param size Size of the memory - * \param params Parameters for the skeleton model - */ - - bool SkeletalModel::LoadFromMemory(const void* data, std::size_t size, const SkeletalModelParameters& params) - { - return SkeletalModelLoader::LoadFromMemory(this, data, size, params); - } - - /*! - * \brief Loads the skeleton model from stream - * \return true if loading is successful - * - * \param stream Stream to the skeleton model - * \param params Parameters for the skeleton model - */ - - bool SkeletalModel::LoadFromStream(Stream& stream, const SkeletalModelParameters& params) - { - return SkeletalModelLoader::LoadFromStream(this, stream, params); - } - /*! * \brief Sets the animation for the model * \return true If successful @@ -432,6 +392,4 @@ namespace Nz /*if (m_animationEnabled && m_animation) AdvanceAnimation(m_scene->GetUpdateTime());*/ } - - SkeletalModelLoader::LoaderList SkeletalModel::s_loaders; } diff --git a/src/Nazara/Renderer/Texture.cpp b/src/Nazara/Renderer/Texture.cpp index bba567cf4..483f60709 100644 --- a/src/Nazara/Renderer/Texture.cpp +++ b/src/Nazara/Renderer/Texture.cpp @@ -54,7 +54,7 @@ namespace Nz Create(type, format, width, height, depth, levelCount); } - Texture::Texture(const Image& image) + Texture::Texture(const Image* image) { ErrorFlags flags(ErrorFlag_ThrowException); LoadFromImage(image); @@ -489,225 +489,6 @@ namespace Nz return m_impl != nullptr; } - bool Texture::LoadFromFile(const String& filePath, const ImageParams& params, bool generateMipmaps) - { - Image image; - if (!image.LoadFromFile(filePath, params)) - { - NazaraError("Failed to load image"); - return false; - } - - return LoadFromImage(image, generateMipmaps); - } - - bool Texture::LoadFromImage(const Image& image, bool generateMipmaps) - { - #if NAZARA_RENDERER_SAFE - if (!image.IsValid()) - { - NazaraError("Image must be valid"); - return false; - } - #endif - - // Vive le Copy-On-Write - Image newImage(image); - - PixelFormatType format = newImage.GetFormat(); - if (!IsFormatSupported(format)) - { - ///TODO: Sélectionner le format le plus adapté selon les composantes présentes dans le premier format - PixelFormatType newFormat = (PixelFormat::HasAlpha(format)) ? PixelFormatType_BGRA8 : PixelFormatType_BGR8; - NazaraWarning("Format " + PixelFormat::GetName(format) + " not supported, trying to convert it to " + PixelFormat::GetName(newFormat) + "..."); - - if (PixelFormat::IsConversionSupported(format, newFormat)) - { - if (newImage.Convert(newFormat)) - { - NazaraWarning("Conversion succeed"); - format = newFormat; - } - else - { - NazaraError("Conversion failed"); - return false; - } - } - else - { - NazaraError("Conversion not supported"); - return false; - } - } - - ImageType type = newImage.GetType(); - UInt8 levelCount = newImage.GetLevelCount(); - if (!Create(type, format, newImage.GetWidth(), newImage.GetHeight(), newImage.GetDepth(), (generateMipmaps) ? 0xFF : levelCount)) - { - NazaraError("Failed to create texture"); - return false; - } - - CallOnExit destroyOnExit([this]() - { - Destroy(); - }); - - if (type == ImageType_Cubemap) - { - for (UInt8 level = 0; level < levelCount; ++level) - { - for (unsigned int i = 0; i <= CubemapFace_Max; ++i) - { - if (!Update(newImage.GetConstPixels(0, 0, i, level), Rectui(0, 0, newImage.GetWidth(level), newImage.GetHeight(level)), i, level)) - { - NazaraError("Failed to update texture"); - return false; - } - } - } - } - else - { - for (UInt8 level = 0; level < levelCount; ++level) - { - if (!Update(newImage.GetConstPixels(0, 0, 0, level), level)) - { - NazaraError("Failed to update texture"); - return false; - } - } - } - - // Keep resource path info - SetFilePath(image.GetFilePath()); - - destroyOnExit.Reset(); - - return true; - } - - bool Texture::LoadFromMemory(const void* data, std::size_t size, const ImageParams& params, bool generateMipmaps) - { - Image image; - if (!image.LoadFromMemory(data, size, params)) - { - NazaraError("Failed to load image"); - return false; - } - - return LoadFromImage(image, generateMipmaps); - } - - bool Texture::LoadFromStream(Stream& stream, const ImageParams& params, bool generateMipmaps) - { - Image image; - if (!image.LoadFromStream(stream, params)) - { - NazaraError("Failed to load image"); - return false; - } - - return LoadFromImage(image, generateMipmaps); - } - - bool Texture::LoadArrayFromFile(const String& filePath, const ImageParams& imageParams, bool generateMipmaps, const Vector2ui& atlasSize) - { - Image cubemap; - if (!cubemap.LoadArrayFromFile(filePath, imageParams, atlasSize)) - { - NazaraError("Failed to load cubemap"); - return false; - } - - return LoadFromImage(cubemap, generateMipmaps); - } - - bool Texture::LoadArrayFromImage(const Image& image, bool generateMipmaps, const Vector2ui& atlasSize) - { - Image cubemap; - if (!cubemap.LoadArrayFromImage(image, atlasSize)) - { - NazaraError("Failed to load cubemap"); - return false; - } - - return LoadFromImage(cubemap, generateMipmaps); - } - - bool Texture::LoadArrayFromMemory(const void* data, std::size_t size, const ImageParams& imageParams, bool generateMipmaps, const Vector2ui& atlasSize) - { - Image cubemap; - if (!cubemap.LoadArrayFromMemory(data, size, imageParams, atlasSize)) - { - NazaraError("Failed to load cubemap"); - return false; - } - - return LoadFromImage(cubemap, generateMipmaps); - } - - bool Texture::LoadArrayFromStream(Stream& stream, const ImageParams& imageParams, bool generateMipmaps, const Vector2ui& atlasSize) - { - Image cubemap; - if (!cubemap.LoadArrayFromStream(stream, imageParams, atlasSize)) - { - NazaraError("Failed to load cubemap"); - return false; - } - - return LoadFromImage(cubemap, generateMipmaps); - } - - bool Texture::LoadCubemapFromFile(const String& filePath, const ImageParams& imageParams, bool generateMipmaps, const CubemapParams& cubemapParams) - { - Image cubemap; - if (!cubemap.LoadCubemapFromFile(filePath, imageParams, cubemapParams)) - { - NazaraError("Failed to load cubemap"); - return false; - } - - return LoadFromImage(cubemap, generateMipmaps); - } - - bool Texture::LoadCubemapFromImage(const Image& image, bool generateMipmaps, const CubemapParams& params) - { - Image cubemap; - if (!cubemap.LoadCubemapFromImage(image, params)) - { - NazaraError("Failed to load cubemap"); - return false; - } - - return LoadFromImage(cubemap, generateMipmaps); - } - - bool Texture::LoadCubemapFromMemory(const void* data, std::size_t size, const ImageParams& imageParams, bool generateMipmaps, const CubemapParams& cubemapParams) - { - Image cubemap; - if (!cubemap.LoadCubemapFromMemory(data, size, imageParams, cubemapParams)) - { - NazaraError("Failed to load cubemap"); - return false; - } - - return LoadFromImage(cubemap, generateMipmaps); - } - - bool Texture::LoadCubemapFromStream(Stream& stream, const ImageParams& imageParams, bool generateMipmaps, const CubemapParams& cubemapParams) - { - Image cubemap; - if (!cubemap.LoadCubemapFromStream(stream, imageParams, cubemapParams)) - { - NazaraError("Failed to load cubemap"); - return false; - } - - return LoadFromImage(cubemap, generateMipmaps); - } - bool Texture::LoadFaceFromFile(CubemapFace face, const String& filePath, const ImageParams& params) { #if NAZARA_RENDERER_SAFE @@ -724,21 +505,21 @@ namespace Nz } #endif - Image image; - if (!image.LoadFromFile(filePath, params)) + ImageRef image = Image::LoadFromFile(filePath, params); + if (!image) { NazaraError("Failed to load image"); return false; } - if (!image.Convert(m_impl->format)) + if (!image->Convert(m_impl->format)) { NazaraError("Failed to convert image to texture format"); return false; } unsigned int faceSize = m_impl->width; - if (image.GetWidth() != faceSize || image.GetHeight() != faceSize) + if (image->GetWidth() != faceSize || image->GetHeight() != faceSize) { NazaraError("Image size must match texture face size"); return false; @@ -763,21 +544,21 @@ namespace Nz } #endif - Image image; - if (!image.LoadFromMemory(data, size, params)) + ImageRef image = Image::LoadFromMemory(data, size, params); + if (!image) { NazaraError("Failed to load image"); return false; } - if (!image.Convert(m_impl->format)) + if (!image->Convert(m_impl->format)) { NazaraError("Failed to convert image to texture format"); return false; } unsigned int faceSize = m_impl->width; - if (image.GetWidth() != faceSize || image.GetHeight() != faceSize) + if (image->GetWidth() != faceSize || image->GetHeight() != faceSize) { NazaraError("Image size must match texture face size"); return false; @@ -802,14 +583,14 @@ namespace Nz } #endif - Image image; - if (!image.LoadFromStream(stream, params)) + ImageRef image = Image::LoadFromStream(stream, params); + if (!image) { NazaraError("Failed to load image"); return false; } - if (!image.Convert(m_impl->format)) + if (!image->Convert(m_impl->format)) { NazaraError("Failed to convert image to texture format"); return false; @@ -817,7 +598,7 @@ namespace Nz unsigned int faceSize = m_impl->width; - if (image.GetWidth() != faceSize || image.GetHeight() != faceSize) + if (image->GetWidth() != faceSize || image->GetHeight() != faceSize) { NazaraError("Image size must match texture face size"); return false; @@ -879,82 +660,49 @@ namespace Nz return true; } - bool Texture::Update(const Image& image, UInt8 level) + bool Texture::Update(const Image* image, UInt8 level) { - #if NAZARA_RENDERER_SAFE - if (!image.IsValid()) - { - NazaraError("Image must be valid"); - return false; - } + NazaraAssert(image && image->IsValid(), "Invalid image"); + NazaraAssert(image->GetFormat() == m_impl->format, "Image format doesn't match texture format"); - if (image.GetFormat() != m_impl->format) - { - NazaraError("Image format does not match texture format"); - return false; - } - #endif - - const UInt8* pixels = image.GetConstPixels(0, 0, 0, level); + const UInt8* pixels = image->GetConstPixels(0, 0, 0, level); if (!pixels) { NazaraError("Failed to access image's pixels"); return false; } - return Update(pixels, image.GetWidth(level), image.GetHeight(level), level); + return Update(pixels, image->GetWidth(level), image->GetHeight(level), level); } - bool Texture::Update(const Image& image, const Boxui& box, UInt8 level) + bool Texture::Update(const Image* image, const Boxui& box, UInt8 level) { - #if NAZARA_RENDERER_SAFE - if (!image.IsValid()) - { - NazaraError("Image must be valid"); - return false; - } + NazaraAssert(image && image->IsValid(), "Invalid image"); + NazaraAssert(image->GetFormat() == m_impl->format, "Image format doesn't match texture format"); - if (image.GetFormat() != m_impl->format) - { - NazaraError("Image format does not match texture format"); - return false; - } - #endif - - const UInt8* pixels = image.GetConstPixels(0, 0, 0, level); + const UInt8* pixels = image->GetConstPixels(0, 0, 0, level); if (!pixels) { NazaraError("Failed to access image's pixels"); return false; } - return Update(pixels, box, image.GetWidth(level), image.GetHeight(level), level); + return Update(pixels, box, image->GetWidth(level), image->GetHeight(level), level); } - bool Texture::Update(const Image& image, const Rectui& rect, unsigned int z, UInt8 level) + bool Texture::Update(const Image* image, const Rectui& rect, unsigned int z, UInt8 level) { - #if NAZARA_RENDERER_SAFE - if (!image.IsValid()) - { - NazaraError("Image must be valid"); - return false; - } + NazaraAssert(image && image->IsValid(), "Invalid image"); + NazaraAssert(image->GetFormat() == m_impl->format, "Image format doesn't match texture format"); - if (image.GetFormat() != m_impl->format) - { - NazaraError("Image format does not match texture format"); - return false; - } - #endif - - const UInt8* pixels = image.GetConstPixels(0, 0, 0, level); + const UInt8* pixels = image->GetConstPixels(0, 0, 0, level); if (!pixels) { NazaraError("Failed to access image's pixels"); return false; } - return Update(pixels, rect, z, image.GetWidth(level), image.GetHeight(level), level); + return Update(pixels, rect, z, image->GetWidth(level), image->GetHeight(level), level); } bool Texture::Update(const UInt8* pixels, unsigned int srcWidth, unsigned int srcHeight, UInt8 level) @@ -1193,6 +941,214 @@ namespace Nz return false; } + TextureRef Texture::LoadFromFile(const String& filePath, const ImageParams& params, bool generateMipmaps) + { + ImageRef image = Image::LoadFromFile(filePath, params); + if (!image) + { + NazaraError("Failed to load image"); + return nullptr; + } + + return LoadFromImage(image, generateMipmaps); + } + + TextureRef Texture::LoadFromImage(const Image* image, bool generateMipmaps) + { + NazaraAssert(image && image->IsValid(), "Invalid image"); + + // Make use of COW + Image newImage(*image); + + PixelFormatType format = newImage.GetFormat(); + if (!IsFormatSupported(format)) + { + ///TODO: Sélectionner le format le plus adapté selon les composantes présentes dans le premier format + PixelFormatType newFormat = (PixelFormat::HasAlpha(format)) ? PixelFormatType_BGRA8 : PixelFormatType_BGR8; + NazaraWarning("Format " + PixelFormat::GetName(format) + " not supported, trying to convert it to " + PixelFormat::GetName(newFormat) + "..."); + + if (PixelFormat::IsConversionSupported(format, newFormat)) + { + if (newImage.Convert(newFormat)) + { + NazaraWarning("Conversion succeed"); + format = newFormat; + } + else + { + NazaraError("Conversion failed"); + return nullptr; + } + } + else + { + NazaraError("Conversion not supported"); + return nullptr; + } + } + + ImageType type = newImage.GetType(); + UInt8 levelCount = newImage.GetLevelCount(); + + TextureRef texture = New(); + if (!texture->Create(type, format, newImage.GetWidth(), newImage.GetHeight(), newImage.GetDepth(), (generateMipmaps) ? 0xFF : levelCount)) + { + NazaraError("Failed to create texture"); + return nullptr; + } + + if (type == ImageType_Cubemap) + { + for (UInt8 level = 0; level < levelCount; ++level) + { + for (unsigned int i = 0; i <= CubemapFace_Max; ++i) + { + if (!texture->Update(newImage.GetConstPixels(0, 0, i, level), Rectui(0, 0, newImage.GetWidth(level), newImage.GetHeight(level)), i, level)) + { + NazaraError("Failed to update texture"); + return nullptr; + } + } + } + } + else + { + for (UInt8 level = 0; level < levelCount; ++level) + { + if (!texture->Update(newImage.GetConstPixels(0, 0, 0, level), level)) + { + NazaraError("Failed to update texture"); + return nullptr; + } + } + } + + // Keep resource path info + texture->SetFilePath(image->GetFilePath()); + + return texture; + } + + TextureRef Texture::LoadFromMemory(const void* data, std::size_t size, const ImageParams& params, bool generateMipmaps) + { + ImageRef image = Image::LoadFromMemory(data, size, params); + if (!image) + { + NazaraError("Failed to load image"); + return nullptr; + } + + return LoadFromImage(image, generateMipmaps); + } + + TextureRef Texture::LoadFromStream(Stream& stream, const ImageParams& params, bool generateMipmaps) + { + ImageRef image = Image::LoadFromStream(stream, params); + if (!image) + { + NazaraError("Failed to load image"); + return nullptr; + } + + return LoadFromImage(image, generateMipmaps); + } + + TextureRef Texture::LoadArrayFromFile(const String& filePath, const ImageParams& imageParams, bool generateMipmaps, const Vector2ui& atlasSize) + { + ImageRef cubemap = Image::LoadArrayFromFile(filePath, imageParams, atlasSize); + if (!cubemap) + { + NazaraError("Failed to load cubemap"); + return nullptr; + } + + return LoadFromImage(cubemap, generateMipmaps); + } + + TextureRef Texture::LoadArrayFromImage(const Image* image, bool generateMipmaps, const Vector2ui& atlasSize) + { + ImageRef cubemap = Image::LoadArrayFromImage(image, atlasSize); + if (!cubemap) + { + NazaraError("Failed to load cubemap"); + return nullptr; + } + + return LoadFromImage(cubemap, generateMipmaps); + } + + TextureRef Texture::LoadArrayFromMemory(const void* data, std::size_t size, const ImageParams& imageParams, bool generateMipmaps, const Vector2ui& atlasSize) + { + ImageRef cubemap = Image::LoadArrayFromMemory(data, size, imageParams, atlasSize); + if (!cubemap) + { + NazaraError("Failed to load cubemap"); + return nullptr; + } + + return LoadFromImage(cubemap, generateMipmaps); + } + + TextureRef Texture::LoadArrayFromStream(Stream& stream, const ImageParams& imageParams, bool generateMipmaps, const Vector2ui& atlasSize) + { + ImageRef cubemap = Image::LoadArrayFromStream(stream, imageParams, atlasSize); + if (!cubemap) + { + NazaraError("Failed to load cubemap"); + return nullptr; + } + + return LoadFromImage(cubemap, generateMipmaps); + } + + TextureRef Texture::LoadCubemapFromFile(const String& filePath, const ImageParams& imageParams, bool generateMipmaps, const CubemapParams& cubemapParams) + { + ImageRef cubemap = Image::LoadCubemapFromFile(filePath, imageParams, cubemapParams); + if (!cubemap) + { + NazaraError("Failed to load cubemap"); + return nullptr; + } + + return LoadFromImage(cubemap, generateMipmaps); + } + + TextureRef Texture::LoadCubemapFromImage(const Image* image, bool generateMipmaps, const CubemapParams& params) + { + ImageRef cubemap = Image::LoadCubemapFromImage(image, params); + if (!cubemap) + { + NazaraError("Failed to load cubemap"); + return nullptr; + } + + return LoadFromImage(cubemap, generateMipmaps); + } + + TextureRef Texture::LoadCubemapFromMemory(const void* data, std::size_t size, const ImageParams& imageParams, bool generateMipmaps, const CubemapParams& cubemapParams) + { + ImageRef cubemap = Image::LoadCubemapFromMemory(data, size, imageParams, cubemapParams); + if (!cubemap) + { + NazaraError("Failed to load cubemap"); + return nullptr; + } + + return LoadFromImage(cubemap, generateMipmaps); + } + + TextureRef Texture::LoadCubemapFromStream(Stream& stream, const ImageParams& imageParams, bool generateMipmaps, const CubemapParams& cubemapParams) + { + ImageRef cubemap = Image::LoadCubemapFromStream(stream, imageParams, cubemapParams); + if (!cubemap) + { + NazaraError("Failed to load cubemap"); + return nullptr; + } + + return LoadFromImage(cubemap, generateMipmaps); + } + bool Texture::CreateTexture(bool proxy) { OpenGL::Format openGLFormat; diff --git a/src/Nazara/Utility/Animation.cpp b/src/Nazara/Utility/Animation.cpp index f851a430b..d60e095ee 100644 --- a/src/Nazara/Utility/Animation.cpp +++ b/src/Nazara/Utility/Animation.cpp @@ -261,21 +261,6 @@ namespace Nz return m_impl != nullptr; } - bool Animation::LoadFromFile(const String& filePath, const AnimationParams& params) - { - return AnimationLoader::LoadFromFile(this, filePath, params); - } - - bool Animation::LoadFromMemory(const void* data, std::size_t size, const AnimationParams& params) - { - return AnimationLoader::LoadFromMemory(this, data, size, params); - } - - bool Animation::LoadFromStream(Stream& stream, const AnimationParams& params) - { - return AnimationLoader::LoadFromStream(this, stream, params); - } - void Animation::RemoveSequence(const String& identifier) { NazaraAssert(m_impl, "Animation not created"); @@ -304,6 +289,21 @@ namespace Nz m_impl->sequences.erase(it); } + AnimationRef Animation::LoadFromFile(const String& filePath, const AnimationParams& params) + { + return AnimationLoader::LoadFromFile(filePath, params); + } + + AnimationRef Animation::LoadFromMemory(const void* data, std::size_t size, const AnimationParams& params) + { + return AnimationLoader::LoadFromMemory(data, size, params); + } + + AnimationRef Animation::LoadFromStream(Stream& stream, const AnimationParams& params) + { + return AnimationLoader::LoadFromStream(stream, params); + } + bool Animation::Initialize() { if (!AnimationLibrary::Initialize()) diff --git a/src/Nazara/Utility/Font.cpp b/src/Nazara/Utility/Font.cpp index a0264b9ee..731557628 100644 --- a/src/Nazara/Utility/Font.cpp +++ b/src/Nazara/Utility/Font.cpp @@ -280,21 +280,6 @@ namespace Nz return true; } - bool Font::OpenFromFile(const String& filePath, const FontParams& params) - { - return FontLoader::LoadFromFile(this, filePath, params); - } - - bool Font::OpenFromMemory(const void* data, std::size_t size, const FontParams& params) - { - return FontLoader::LoadFromMemory(this, data, size, params); - } - - bool Font::OpenFromStream(Stream& stream, const FontParams& params) - { - return FontLoader::LoadFromStream(this, stream, params); - } - void Font::SetAtlas(const std::shared_ptr& atlas) { if (m_atlas != atlas) @@ -358,10 +343,8 @@ namespace Nz if (!s_defaultFont) { - FontRef cabin = Font::New(); - if (cabin->OpenFromMemory(r_cabinRegular, sizeof(r_cabinRegular))) - s_defaultFont = cabin; - else + s_defaultFont = Font::OpenFromMemory(r_cabinRegular, sizeof(r_cabinRegular)); + if (!s_defaultFont) NazaraError("Failed to open default font"); } @@ -378,6 +361,21 @@ namespace Nz return s_defaultMinimumStepSize; } + FontRef Font::OpenFromFile(const String& filePath, const FontParams& params) + { + return FontLoader::LoadFromFile(filePath, params); + } + + FontRef Font::OpenFromMemory(const void* data, std::size_t size, const FontParams& params) + { + return FontLoader::LoadFromMemory(data, size, params); + } + + FontRef Font::OpenFromStream(Stream& stream, const FontParams& params) + { + return FontLoader::LoadFromStream(stream, params); + } + void Font::SetDefaultAtlas(const std::shared_ptr& atlas) { s_defaultAtlas = atlas; diff --git a/src/Nazara/Utility/Formats/DDSLoader.cpp b/src/Nazara/Utility/Formats/DDSLoader.cpp index dd24a1469..e4c6f2d57 100644 --- a/src/Nazara/Utility/Formats/DDSLoader.cpp +++ b/src/Nazara/Utility/Formats/DDSLoader.cpp @@ -38,7 +38,7 @@ namespace Nz return (magic == DDS_Magic) ? Ternary_True : Ternary_False; } - static bool Load(Image* image, Stream& stream, const ImageParams& parameters) + static ImageRef Load(Stream& stream, const ImageParams& parameters) { NazaraUnused(parameters); @@ -81,14 +81,14 @@ namespace Nz // First, identify the type ImageType type; if (!IdentifyImageType(header, headerDX10, &type)) - return false; + return nullptr; // Then the format PixelFormatType format; if (!IdentifyPixelFormat(header, headerDX10, &format)) - return false; + return nullptr; - image->Create(type, format, width, height, depth, levelCount); + ImageRef image = Image::New(type, format, width, height, depth, levelCount); // Read all mipmap levels for (unsigned int i = 0; i < image->GetLevelCount(); i++) @@ -100,7 +100,7 @@ namespace Nz if (byteStream.Read(ptr, byteCount) != byteCount) { NazaraError("Failed to read level #" + String::Number(i)); - return false; + return nullptr; } if (width > 1) @@ -117,7 +117,7 @@ namespace Nz if (parameters.loadFormat != PixelFormatType_Undefined) image->Convert(parameters.loadFormat); - return true; + return image; } private: diff --git a/src/Nazara/Utility/Formats/FreeTypeLoader.cpp b/src/Nazara/Utility/Formats/FreeTypeLoader.cpp index f6ab78b1d..2cd2c51e3 100644 --- a/src/Nazara/Utility/Formats/FreeTypeLoader.cpp +++ b/src/Nazara/Utility/Formats/FreeTypeLoader.cpp @@ -361,7 +361,7 @@ namespace Nz return Ternary_False; } - bool LoadFile(Font* font, const String& filePath, const FontParams& parameters) + FontRef LoadFile(const String& filePath, const FontParams& parameters) { NazaraUnused(parameters); @@ -370,25 +370,26 @@ namespace Nz if (!face->SetFile(filePath)) { NazaraError("Failed to open file"); - return false; + return nullptr; } if (!face->Open()) { NazaraError("Failed to open face"); - return false; + return nullptr; } + FontRef font = Font::New(); if (font->Create(face.get())) { face.release(); - return true; + return font; } else - return false; + return nullptr; } - bool LoadMemory(Font* font, const void* data, std::size_t size, const FontParams& parameters) + FontRef LoadMemory(const void* data, std::size_t size, const FontParams& parameters) { NazaraUnused(parameters); @@ -398,19 +399,20 @@ namespace Nz if (!face->Open()) { NazaraError("Failed to open face"); - return false; + return nullptr; } + FontRef font = Font::New(); if (font->Create(face.get())) { face.release(); - return true; + return font; } else - return false; + return nullptr; } - bool LoadStream(Font* font, Stream& stream, const FontParams& parameters) + FontRef LoadStream(Stream& stream, const FontParams& parameters) { NazaraUnused(parameters); @@ -420,16 +422,17 @@ namespace Nz if (!face->Open()) { NazaraError("Failed to open face"); - return false; + return nullptr; } + FontRef font = Font::New(); if (font->Create(face.get())) { face.release(); - return true; + return font; } else - return false; + return nullptr; } } @@ -439,7 +442,7 @@ namespace Nz { if (FT_Init_FreeType(&s_library) == 0) { - s_libraryOwner.reset(new FreeTypeLibrary); + s_libraryOwner = std::make_shared(); FontLoader::RegisterLoader(IsSupported, Check, LoadStream, LoadFile, LoadMemory); } else diff --git a/src/Nazara/Utility/Formats/MD2Loader.cpp b/src/Nazara/Utility/Formats/MD2Loader.cpp index ac7d6e5d7..b58799978 100644 --- a/src/Nazara/Utility/Formats/MD2Loader.cpp +++ b/src/Nazara/Utility/Formats/MD2Loader.cpp @@ -46,13 +46,13 @@ namespace Nz return Ternary_False; } - bool Load(Mesh* mesh, Stream& stream, const MeshParams& parameters) + MeshRef Load(Stream& stream, const MeshParams& parameters) { MD2_Header header; if (stream.Read(&header, sizeof(MD2_Header)) != sizeof(MD2_Header)) { NazaraError("Failed to read header"); - return false; + return nullptr; } #ifdef NAZARA_BIG_ENDIAN @@ -76,14 +76,15 @@ namespace Nz if (stream.GetSize() < header.offset_end) { NazaraError("Incomplete MD2 file"); - return false; + return nullptr; } // Since the engine no longer supports keyframe animations, let's make a static mesh + MeshRef mesh = Nz::Mesh::New(); if (!mesh->CreateStatic()) { NazaraInternalError("Failed to create mesh"); - return false; + return nullptr; } // Extract skins (texture name) @@ -253,7 +254,7 @@ namespace Nz if (parameters.center) mesh->Recenter(); - return true; + return mesh; } } diff --git a/src/Nazara/Utility/Formats/MD5AnimLoader.cpp b/src/Nazara/Utility/Formats/MD5AnimLoader.cpp index e67389409..84f0baeaf 100644 --- a/src/Nazara/Utility/Formats/MD5AnimLoader.cpp +++ b/src/Nazara/Utility/Formats/MD5AnimLoader.cpp @@ -28,7 +28,7 @@ namespace Nz return parser.Check(); } - bool Load(Animation* animation, Stream& stream, const AnimationParams& /*parameters*/) + AnimationRef Load(Stream& stream, const AnimationParams& /*parameters*/) { ///TODO: Utiliser les paramètres MD5AnimParser parser(stream); @@ -36,7 +36,7 @@ namespace Nz if (!parser.Parse()) { NazaraError("MD5Anim parser failed"); - return false; + return nullptr; } const MD5AnimParser::Frame* frames = parser.GetFrames(); @@ -46,6 +46,7 @@ namespace Nz UInt32 jointCount = parser.GetJointCount(); // À ce stade, nous sommes censés avoir assez d'informations pour créer l'animation + AnimationRef animation = Animation::New(); animation->CreateSkeletal(frameCount, jointCount); Sequence sequence; @@ -84,7 +85,7 @@ namespace Nz } } - return true; + return animation; } } diff --git a/src/Nazara/Utility/Formats/MD5MeshLoader.cpp b/src/Nazara/Utility/Formats/MD5MeshLoader.cpp index 84197e1c9..31b3a64a7 100644 --- a/src/Nazara/Utility/Formats/MD5MeshLoader.cpp +++ b/src/Nazara/Utility/Formats/MD5MeshLoader.cpp @@ -35,13 +35,13 @@ namespace Nz return parser.Check(); } - bool Load(Mesh* mesh, Stream& stream, const MeshParams& parameters) + MeshRef Load(Stream& stream, const MeshParams& parameters) { MD5MeshParser parser(stream); if (!parser.Parse()) { NazaraError("MD5Mesh parser failed"); - return false; + return nullptr; } // Pour que le squelette soit correctement aligné, il faut appliquer un quaternion "de correction" aux joints à la base du squelette @@ -62,6 +62,7 @@ namespace Nz if (parameters.animated) { + MeshRef mesh = Mesh::New(); mesh->CreateSkeletal(jointCount); Skeleton* skeleton = mesh->GetSkeleton(); @@ -218,13 +219,16 @@ namespace Nz mesh->SetAnimation(path); } } + + return mesh; } else { + MeshRef mesh = Mesh::New(); if (!mesh->CreateStatic()) // Ne devrait jamais échouer { NazaraInternalError("Failed to create mesh"); - return false; + return nullptr; } mesh->SetMaterialCount(meshCount); @@ -309,9 +313,9 @@ namespace Nz if (parameters.center) mesh->Recenter(); - } - return true; + return mesh; + } } } diff --git a/src/Nazara/Utility/Formats/OBJLoader.cpp b/src/Nazara/Utility/Formats/OBJLoader.cpp index 23a569337..b8ff362f1 100644 --- a/src/Nazara/Utility/Formats/OBJLoader.cpp +++ b/src/Nazara/Utility/Formats/OBJLoader.cpp @@ -153,7 +153,7 @@ namespace Nz return true; } - bool Load(Mesh* mesh, Stream& stream, const MeshParams& parameters) + MeshRef Load(Stream& stream, const MeshParams& parameters) { long long reservedVertexCount; if (!parameters.custom.GetIntegerParameter("NativeOBJLoader_VertexCount", &reservedVertexCount)) @@ -163,9 +163,10 @@ namespace Nz if (!parser.Parse(stream, reservedVertexCount)) { NazaraError("OBJ parser failed"); - return false; + return nullptr; } + MeshRef mesh = Mesh::New(); mesh->CreateStatic(); const String* materials = parser.GetMaterials(); @@ -341,7 +342,7 @@ namespace Nz ParseMTL(mesh, stream.GetDirectory() + mtlLib, materials, meshes, meshCount); } - return true; + return mesh; } } diff --git a/src/Nazara/Utility/Formats/PCXLoader.cpp b/src/Nazara/Utility/Formats/PCXLoader.cpp index bb0e1b43b..5de1aa29d 100644 --- a/src/Nazara/Utility/Formats/PCXLoader.cpp +++ b/src/Nazara/Utility/Formats/PCXLoader.cpp @@ -61,7 +61,7 @@ namespace Nz return Ternary_False; } - bool Load(Image* image, Stream& stream, const ImageParams& parameters) + ImageRef Load(Stream& stream, const ImageParams& parameters) { NazaraUnused(parameters); @@ -69,7 +69,7 @@ namespace Nz if (stream.Read(&header, sizeof(pcx_header)) != sizeof(pcx_header)) { NazaraError("Failed to read header"); - return false; + return nullptr; } #ifdef NAZARA_BIG_ENDIAN @@ -91,10 +91,11 @@ namespace Nz unsigned int width = header.xmax - header.xmin+1; unsigned int height = header.ymax - header.ymin+1; + ImageRef image = Image::New(); if (!image->Create(ImageType_2D, PixelFormatType_RGB8, width, height, 1, (parameters.levelCount > 0) ? parameters.levelCount : 1)) { NazaraError("Failed to create image"); - return false; + return nullptr; } UInt8* pixels = image->GetPixels(); @@ -119,7 +120,7 @@ namespace Nz if (!stream.Read(&rle_value, 1)) { NazaraError("Failed to read stream (byte " + String::Number(stream.GetCursorPos()) + ')'); - return false; + return nullptr; } if (rle_value < 0xc0) @@ -130,7 +131,7 @@ namespace Nz if (!stream.Read(&rle_value, 1)) { NazaraError("Failed to read stream (byte " + String::Number(stream.GetCursorPos()) + ')'); - return false; + return nullptr; } } } @@ -174,7 +175,7 @@ namespace Nz if (!stream.Read(&rle_value, 1)) { NazaraError("Failed to read stream (byte " + String::Number(stream.GetCursorPos()) + ')'); - return false; + return nullptr; } if (rle_value < 0xc0) @@ -185,7 +186,7 @@ namespace Nz if (!stream.Read(&rle_value, 1)) { NazaraError("Failed to read stream (byte " + String::Number(stream.GetCursorPos()) + ')'); - return false; + return nullptr; } } } @@ -225,21 +226,21 @@ namespace Nz if (!stream.Read(&magic, 1)) { NazaraError("Failed to read stream (byte " + String::Number(stream.GetCursorPos()) + ')'); - return false; + return nullptr; } /* first byte must be equal to 0x0c (12) */ if (magic != 0x0c) { NazaraError("Colormap's first byte must be 0x0c (0x" + String::Number(magic, 16) + ')'); - return false; + return nullptr; } /* read palette */ if (stream.Read(palette, 768) != 768) { NazaraError("Failed to read palette"); - return false; + return nullptr; } stream.SetCursorPos(curPos); @@ -258,7 +259,7 @@ namespace Nz if (!stream.Read(&rle_value, 1)) { NazaraError("Failed to read stream (byte " + String::Number(stream.GetCursorPos()) + ')'); - return false; + return nullptr; } if (rle_value < 0xc0) @@ -269,7 +270,7 @@ namespace Nz if (!stream.Read(&rle_value, 1)) { NazaraError("Failed to read stream (byte " + String::Number(stream.GetCursorPos()) + ')'); - return false; + return nullptr; } } } @@ -302,7 +303,7 @@ namespace Nz if (!stream.Read(&rle_value, 1)) { NazaraError("Failed to read stream (byte " + String::Number(stream.GetCursorPos()) + ')'); - return false; + return nullptr; } if (rle_value < 0xc0) @@ -313,7 +314,7 @@ namespace Nz if (!stream.Read(&rle_value, 1)) { NazaraError("Failed to read stream (byte " + String::Number(stream.GetCursorPos()) + ')'); - return false; + return nullptr; } } } @@ -329,13 +330,13 @@ namespace Nz default: NazaraError("Unsupported " + String::Number(bitCount) + " bitcount for pcx files"); - return false; + return nullptr; } if (parameters.loadFormat != PixelFormatType_Undefined) image->Convert(parameters.loadFormat); - return true; + return image; } } diff --git a/src/Nazara/Utility/Formats/STBLoader.cpp b/src/Nazara/Utility/Formats/STBLoader.cpp index c7fcc7e8f..132886175 100644 --- a/src/Nazara/Utility/Formats/STBLoader.cpp +++ b/src/Nazara/Utility/Formats/STBLoader.cpp @@ -4,6 +4,7 @@ #include #include +#include #include #include #include @@ -54,7 +55,7 @@ namespace Nz return Ternary_False; } - bool Load(Image* image, Stream& stream, const ImageParams& parameters) + ImageRef Load(Stream& stream, const ImageParams& parameters) { // Je charge tout en RGBA8 et je converti ensuite via la méthode Convert // Ceci à cause d'un bug de STB lorsqu'il s'agit de charger certaines images (ex: JPG) en "default" @@ -64,24 +65,29 @@ namespace Nz if (!ptr) { NazaraError("Failed to load image: " + String(stbi_failure_reason())); - return false; + return nullptr; } + CallOnExit freeStbiImage([ptr]() + { + stbi_image_free(ptr); + }); + + ImageRef image = Image::New(); if (!image->Create(ImageType_2D, PixelFormatType_RGBA8, width, height, 1, (parameters.levelCount > 0) ? parameters.levelCount : 1)) { NazaraError("Failed to create image"); - stbi_image_free(ptr); - - return false; + return nullptr; } image->Update(ptr); - stbi_image_free(ptr); + + freeStbiImage.CallAndReset(); if (parameters.loadFormat != PixelFormatType_Undefined) image->Convert(parameters.loadFormat); - return true; + return image; } } diff --git a/src/Nazara/Utility/GuillotineImageAtlas.cpp b/src/Nazara/Utility/GuillotineImageAtlas.cpp index 74cff70db..4660a69b8 100644 --- a/src/Nazara/Utility/GuillotineImageAtlas.cpp +++ b/src/Nazara/Utility/GuillotineImageAtlas.cpp @@ -166,8 +166,7 @@ namespace Nz std::unique_ptr newImage(new Image(ImageType_2D, PixelFormatType_A8, size.x, size.y)); if (oldImage) { - Image& image = *static_cast(oldImage); - newImage->Copy(image, Rectui(size), Vector2ui(0, 0)); // Copie des anciennes données + newImage->Copy(static_cast(oldImage), Rectui(size), Vector2ui(0, 0)); // Copie des anciennes données } return newImage.release(); diff --git a/src/Nazara/Utility/Image.cpp b/src/Nazara/Utility/Image.cpp index 81a810e1a..da5ec120c 100644 --- a/src/Nazara/Utility/Image.cpp +++ b/src/Nazara/Utility/Image.cpp @@ -106,7 +106,7 @@ namespace Nz for (unsigned int i = 0; i < levels.size(); ++i) { unsigned int pixelsPerFace = width * height; - levels[i].reset(new UInt8[pixelsPerFace * depth * PixelFormat::GetBytesPerPixel(newFormat)]); + levels[i] = std::make_unique(pixelsPerFace * depth * PixelFormat::GetBytesPerPixel(newFormat)); UInt8* dst = levels[i].get(); UInt8* src = m_sharedImage->levels[i].get(); @@ -143,29 +143,13 @@ namespace Nz return true; } - void Image::Copy(const Image& source, const Boxui& srcBox, const Vector3ui& dstPos) + void Image::Copy(const Image* source, const Boxui& srcBox, const Vector3ui& dstPos) { - #if NAZARA_UTILITY_SAFE - if (m_sharedImage == &emptyImage) - { - NazaraError("Image must be valid"); - return; - } + NazaraAssert(IsValid(), "Invalid image"); + NazaraAssert(source && source->IsValid(), "Invalid source image"); + NazaraAssert(source->GetFormat() == m_sharedImage->format, "Image formats don't match"); - if (!source.IsValid()) - { - NazaraError("Source image must be valid"); - return; - } - - if (source.GetFormat() != m_sharedImage->format) - { - NazaraError("Source image format does not match destination image format"); - return; - } - #endif - - const UInt8* srcPtr = source.GetConstPixels(srcBox.x, srcBox.y, srcBox.z); + const UInt8* srcPtr = source->GetConstPixels(srcBox.x, srcBox.y, srcBox.z); #if NAZARA_UTILITY_SAFE if (!srcPtr) { @@ -177,7 +161,7 @@ namespace Nz UInt8 bpp = PixelFormat::GetBytesPerPixel(m_sharedImage->format); UInt8* dstPtr = GetPixelPtr(m_sharedImage->levels[0].get(), bpp, dstPos.x, dstPos.y, dstPos.z, m_sharedImage->width, m_sharedImage->height); - Copy(dstPtr, srcPtr, m_sharedImage->format, srcBox.width, srcBox.height, srcBox.depth, m_sharedImage->width, m_sharedImage->height, source.GetWidth(), source.GetHeight()); + Copy(dstPtr, srcPtr, m_sharedImage->format, srcBox.width, srcBox.height, srcBox.depth, m_sharedImage->width, m_sharedImage->height, source->GetWidth(), source->GetHeight()); } bool Image::Create(ImageType type, PixelFormatType format, unsigned int width, unsigned int height, unsigned int depth, UInt8 levelCount) @@ -271,7 +255,7 @@ namespace Nz // Cette allocation est protégée car sa taille dépend directement de paramètres utilisateurs try { - levels[i].reset(new UInt8[PixelFormat::ComputeSize(format, w, h, d)]); + levels[i] = std::make_unique(PixelFormat::ComputeSize(format, w, h, d)); if (w > 1) w >>= 1; @@ -337,12 +321,12 @@ namespace Nz // Les images 3D et cubemaps sont stockés de la même façon unsigned int depth = (m_sharedImage->type == ImageType_Cubemap) ? 6 : m_sharedImage->depth; - for (unsigned int i = 0; i < levels.size(); ++i) + for (auto & level : levels) { std::size_t size = PixelFormat::ComputeSize(m_sharedImage->format, width, height, depth); - levels[i].reset(new UInt8[size]); + level = std::make_unique(size); - UInt8* ptr = levels[i].get(); + UInt8* ptr = level.get(); UInt8* end = &ptr[size]; while (ptr < end) @@ -514,9 +498,9 @@ namespace Nz unsigned int width = m_sharedImage->width; unsigned int height = m_sharedImage->height; unsigned int depth = (m_sharedImage->type == ImageType_Cubemap) ? 6 : m_sharedImage->depth; - for (unsigned int level = 0; level < m_sharedImage->levels.size(); ++level) + for (auto& level : m_sharedImage->levels) { - UInt8* ptr = m_sharedImage->levels[level].get(); + UInt8* ptr = level.get(); if (!PixelFormat::Flip(PixelFlipping_Horizontally, m_sharedImage->format, width, height, depth, ptr, ptr)) { NazaraError("Failed to flip image"); @@ -557,9 +541,9 @@ namespace Nz unsigned int width = m_sharedImage->width; unsigned int height = m_sharedImage->height; unsigned int depth = (m_sharedImage->type == ImageType_Cubemap) ? 6 : m_sharedImage->depth; - for (unsigned int level = 0; level < m_sharedImage->levels.size(); ++level) + for (auto& level : m_sharedImage->levels) { - UInt8* ptr = m_sharedImage->levels[level].get(); + UInt8* ptr = level.get(); if (!PixelFormat::Flip(PixelFlipping_Vertically, m_sharedImage->format, width, height, depth, ptr, ptr)) { NazaraError("Failed to flip image"); @@ -805,7 +789,7 @@ namespace Nz return Vector3ui(GetLevelSize(m_sharedImage->width, level), GetLevelSize(m_sharedImage->height, level), GetLevelSize(m_sharedImage->depth, level)); } - ImageType Image::GetType() const + ImageType Image::GetType() const { return m_sharedImage->type; } @@ -865,67 +849,48 @@ namespace Nz return m_sharedImage != &emptyImage; } - bool Image::LoadFromFile(const String& filePath, const ImageParams& params) - { - return ImageLoader::LoadFromFile(this, filePath, params); - } - - bool Image::LoadFromMemory(const void* data, std::size_t size, const ImageParams& params) - { - return ImageLoader::LoadFromMemory(this, data, size, params); - } - - bool Image::LoadFromStream(Stream& stream, const ImageParams& params) - { - return ImageLoader::LoadFromStream(this, stream, params); - } - // LoadArray - bool Image::LoadArrayFromFile(const String& filePath, const ImageParams& imageParams, const Vector2ui& atlasSize) + ImageRef Image::LoadArrayFromFile(const String& filePath, const ImageParams& imageParams, const Vector2ui& atlasSize) { - Image image; - if (!image.LoadFromFile(filePath, imageParams)) + ImageRef image = Image::LoadFromFile(filePath, imageParams); + if (!image) { NazaraError("Failed to load image"); - return false; + return nullptr; } return LoadArrayFromImage(image, atlasSize); } - bool Image::LoadArrayFromImage(const Image& image, const Vector2ui& atlasSize) + ImageRef Image::LoadArrayFromImage(const Image* image, const Vector2ui& atlasSize) { - #if NAZARA_UTILITY_SAFE - if (!image.IsValid()) - { - NazaraError("Image must be valid"); - return false; - } + NazaraAssert(image && image->IsValid(), "Invalid image"); + #if NAZARA_UTILITY_SAFE if (atlasSize.x == 0) { NazaraError("Atlas width must be over zero"); - return false; + return nullptr; } if (atlasSize.y == 0) { NazaraError("Atlas height must be over zero"); - return false; + return nullptr; } #endif - ImageType type = image.GetType(); + ImageType type = image->GetType(); #if NAZARA_UTILITY_SAFE if (type != ImageType_1D && type != ImageType_2D) { NazaraError("Image type not handled (0x" + String::Number(type, 16) + ')'); - return false; + return nullptr; } #endif - Vector2ui imageSize(image.GetWidth(), image.GetHeight()); + Vector2ui imageSize(image->GetWidth(), image->GetHeight()); if (imageSize.x % atlasSize.x != 0) { @@ -941,82 +906,85 @@ namespace Nz unsigned int layerCount = atlasSize.x*atlasSize.y; + ImageRef arrayImage = New(); // Selon le type de l'image de base, on va créer un array d'images 2D ou 1D if (type == ImageType_2D) - Create(ImageType_2D_Array, image.GetFormat(), faceSize.x, faceSize.y, layerCount); + arrayImage->Create(ImageType_2D_Array, image->GetFormat(), faceSize.x, faceSize.y, layerCount); else - Create(ImageType_1D_Array, image.GetFormat(), faceSize.x, layerCount); + arrayImage->Create(ImageType_1D_Array, image->GetFormat(), faceSize.x, layerCount); + + if (!arrayImage->IsValid()) + { + NazaraError("Failed to create image"); + return nullptr; + } unsigned int layer = 0; for (unsigned int j = 0; j < atlasSize.y; ++j) for (unsigned int i = 0; i < atlasSize.x; ++i) - Copy(image, Rectui(i*faceSize.x, j*faceSize.y, faceSize.x, faceSize.y), Vector3ui(0, 0, layer++)); + arrayImage->Copy(image, Rectui(i*faceSize.x, j*faceSize.y, faceSize.x, faceSize.y), Vector3ui(0, 0, layer++)); - return true; + return arrayImage; } - bool Image::LoadArrayFromMemory(const void* data, std::size_t size, const ImageParams& imageParams, const Vector2ui& atlasSize) + ImageRef Image::LoadArrayFromMemory(const void* data, std::size_t size, const ImageParams& imageParams, const Vector2ui& atlasSize) { - Image image; - if (!image.LoadFromMemory(data, size, imageParams)) + ImageRef image = Image::LoadFromMemory(data, size, imageParams); + if (!image) { NazaraError("Failed to load image"); - return false; + return nullptr; } return LoadArrayFromImage(image, atlasSize); } - bool Image::LoadArrayFromStream(Stream& stream, const ImageParams& imageParams, const Vector2ui& atlasSize) + ImageRef Image::LoadArrayFromStream(Stream& stream, const ImageParams& imageParams, const Vector2ui& atlasSize) { - Image image; - if (!image.LoadFromStream(stream, imageParams)) + ImageRef image = Image::LoadFromStream(stream, imageParams); + if (!image) { NazaraError("Failed to load image"); - return false; + return nullptr; } return LoadArrayFromImage(image, atlasSize); } - bool Image::LoadCubemapFromFile(const String& filePath, const ImageParams& imageParams, const CubemapParams& cubemapParams) + ImageRef Image::LoadCubemapFromFile(const String& filePath, const ImageParams& imageParams, const CubemapParams& cubemapParams) { - Image image; - if (!image.LoadFromFile(filePath, imageParams)) + ImageRef image = Image::LoadFromFile(filePath, imageParams); + if (!image) { NazaraError("Failed to load image"); - return false; + return nullptr; } return LoadCubemapFromImage(image, cubemapParams); } - bool Image::LoadCubemapFromImage(const Image& image, const CubemapParams& params) + ImageRef Image::LoadCubemapFromImage(const Image* image, const CubemapParams& params) { - #if NAZARA_UTILITY_SAFE - if (!image.IsValid()) - { - NazaraError("Image must be valid"); - return false; - } + NazaraAssert(image && image->IsValid(), "Invalid image"); - ImageType type = image.GetType(); + #if NAZARA_UTILITY_SAFE + ImageType type = image->GetType(); if (type != ImageType_2D) { NazaraError("Image type not handled (0x" + String::Number(type, 16) + ')'); - return false; + return nullptr; } #endif - unsigned int width = image.GetWidth(); - unsigned int height = image.GetHeight(); + unsigned int width = image->GetWidth(); + unsigned int height = image->GetHeight(); unsigned int faceSize = (params.faceSize == 0) ? std::max(width, height)/4 : params.faceSize; // Sans cette vérification, celles des rectangles pourrait réussir via un overflow if (width < faceSize || height < faceSize) { NazaraError("Image is too small for this face size"); - return false; + return nullptr; } // Calcul et vérification des surfaces @@ -1027,84 +995,80 @@ namespace Nz if (backPos.x > limitX || backPos.y > limitY) { NazaraError("Back rectangle is out of image"); - return false; + return nullptr; } Vector2ui downPos = params.downPosition * faceSize; if (downPos.x > limitX || downPos.y > limitY) { NazaraError("Down rectangle is out of image"); - return false; + return nullptr; } Vector2ui forwardPos = params.forwardPosition * faceSize; if (forwardPos.x > limitX || forwardPos.y > limitY) { NazaraError("Forward rectangle is out of image"); - return false; + return nullptr; } Vector2ui leftPos = params.leftPosition * faceSize; if (leftPos.x > limitX || leftPos.y > limitY) { NazaraError("Left rectangle is out of image"); - return false; + return nullptr; } Vector2ui rightPos = params.rightPosition * faceSize; if (rightPos.x > limitX || rightPos.y > limitY) { NazaraError("Right rectangle is out of image"); - return false; + return nullptr; } Vector2ui upPos = params.upPosition * faceSize; if (upPos.x > limitX || upPos.y > limitY) { NazaraError("Up rectangle is out of image"); - return false; + return nullptr; } - Create(ImageType_Cubemap, image.GetFormat(), faceSize, faceSize); - - #ifdef NAZARA_DEBUG - // Les paramètres sont valides, que Create ne fonctionne pas relèverait d'un bug - if (m_sharedImage == &emptyImage) + ImageRef cubemap = New(); + if (!cubemap->Create(ImageType_Cubemap, image->GetFormat(), faceSize, faceSize)) { - NazaraInternalError("Failed to create cubemap"); - return false; + NazaraError("Failed to create cubemap"); + return nullptr; } - #endif - Copy(image, Rectui(backPos.x, backPos.y, faceSize, faceSize), Vector3ui(0, 0, CubemapFace_NegativeZ)); - Copy(image, Rectui(downPos.x, downPos.y, faceSize, faceSize), Vector3ui(0, 0, CubemapFace_NegativeY)); - Copy(image, Rectui(forwardPos.x, forwardPos.y, faceSize, faceSize), Vector3ui(0, 0, CubemapFace_PositiveZ)); - Copy(image, Rectui(leftPos.x, leftPos.y, faceSize, faceSize), Vector3ui(0, 0, CubemapFace_NegativeX)); - Copy(image, Rectui(rightPos.x, rightPos.y, faceSize, faceSize), Vector3ui(0, 0, CubemapFace_PositiveX)); - Copy(image, Rectui(upPos.x, upPos.y, faceSize, faceSize), Vector3ui(0, 0, CubemapFace_PositiveY)); + cubemap->Copy(image, Rectui(backPos.x, backPos.y, faceSize, faceSize), Vector3ui(0, 0, CubemapFace_NegativeZ)); + cubemap->Copy(image, Rectui(downPos.x, downPos.y, faceSize, faceSize), Vector3ui(0, 0, CubemapFace_NegativeY)); + cubemap->Copy(image, Rectui(forwardPos.x, forwardPos.y, faceSize, faceSize), Vector3ui(0, 0, CubemapFace_PositiveZ)); + cubemap->Copy(image, Rectui(leftPos.x, leftPos.y, faceSize, faceSize), Vector3ui(0, 0, CubemapFace_NegativeX)); + cubemap->Copy(image, Rectui(rightPos.x, rightPos.y, faceSize, faceSize), Vector3ui(0, 0, CubemapFace_PositiveX)); + cubemap->Copy(image, Rectui(upPos.x, upPos.y, faceSize, faceSize), Vector3ui(0, 0, CubemapFace_PositiveY)); - return true; + return cubemap; } - bool Image::LoadCubemapFromMemory(const void* data, std::size_t size, const ImageParams& imageParams, const CubemapParams& cubemapParams) + ImageRef Image::LoadCubemapFromMemory(const void* data, std::size_t size, const ImageParams& imageParams, const CubemapParams& cubemapParams) { - Image image; - if (!image.LoadFromMemory(data, size, imageParams)) + ImageRef image = Image::LoadFromMemory(data, size, imageParams); + if (!image) { NazaraError("Failed to load image"); - return false; + return nullptr; } return LoadCubemapFromImage(image, cubemapParams); } - bool Image::LoadCubemapFromStream(Stream& stream, const ImageParams& imageParams, const CubemapParams& cubemapParams) + ImageRef Image::LoadCubemapFromStream(Stream& stream, const ImageParams& imageParams, const CubemapParams& cubemapParams) { - Image image; - if (!image.LoadFromStream(stream, imageParams)) + ImageRef image = Image::LoadFromStream(stream, imageParams); + if (!image) { NazaraError("Failed to load image"); - return false; + return nullptr; } return LoadCubemapFromImage(image, cubemapParams); @@ -1114,21 +1078,21 @@ namespace Nz { NazaraAssert(IsValid() && IsCubemap(), "Texture must be a valid cubemap"); - Image image; - if (!image.LoadFromFile(filePath, params)) + ImageRef image = Image::LoadFromFile(filePath, params); + if (!image) { NazaraError("Failed to load image"); return false; } - if (!image.Convert(GetFormat())) + if (!image->Convert(GetFormat())) { NazaraError("Failed to convert image to texture format"); return false; } unsigned int faceSize = GetWidth(); - if (image.GetWidth() != faceSize || image.GetHeight() != faceSize) + if (image->GetWidth() != faceSize || image->GetHeight() != faceSize) { NazaraError("Image size must match texture face size"); return false; @@ -1142,21 +1106,21 @@ namespace Nz { NazaraAssert(IsValid() && IsCubemap(), "Texture must be a valid cubemap"); - Image image; - if (!image.LoadFromMemory(data, size, params)) + ImageRef image = Image::LoadFromMemory(data, size, params); + if (!image) { NazaraError("Failed to load image"); return false; } - if (!image.Convert(GetFormat())) + if (!image->Convert(GetFormat())) { NazaraError("Failed to convert image to texture format"); return false; } unsigned int faceSize = GetWidth(); - if (image.GetWidth() != faceSize || image.GetHeight() != faceSize) + if (image->GetWidth() != faceSize || image->GetHeight() != faceSize) { NazaraError("Image size must match texture face size"); return false; @@ -1170,21 +1134,21 @@ namespace Nz { NazaraAssert(IsValid() && IsCubemap(), "Texture must be a valid cubemap"); - Image image; - if (!image.LoadFromStream(stream, params)) + ImageRef image = Image::LoadFromStream(stream, params); + if (!image) { NazaraError("Failed to load image"); return false; } - if (!image.Convert(GetFormat())) + if (!image->Convert(GetFormat())) { NazaraError("Failed to convert image to texture format"); return false; } unsigned int faceSize = GetWidth(); - if (image.GetWidth() != faceSize || image.GetHeight() != faceSize) + if (image->GetWidth() != faceSize || image->GetHeight() != faceSize) { NazaraError("Image size must match texture face size"); return false; @@ -1232,7 +1196,7 @@ namespace Nz m_sharedImage->levels.resize(levelCount); for (UInt8 i = oldLevelCount; i < maxLevelCount; ++i) - m_sharedImage->levels[i].reset(new UInt8[GetMemoryUsage(i)]); + m_sharedImage->levels[i] = std::make_unique(GetMemoryUsage(i)); } bool Image::SetPixelColor(const Color& color, unsigned int x, unsigned int y, unsigned int z) @@ -1463,7 +1427,21 @@ namespace Nz NazaraError("Image type not handled (0x" + String::Number(type, 16) + ')'); return 0; + } + ImageRef Image::LoadFromFile(const String& filePath, const ImageParams& params) + { + return ImageLoader::LoadFromFile(filePath, params); + } + + ImageRef Image::LoadFromMemory(const void* data, std::size_t size, const ImageParams& params) + { + return ImageLoader::LoadFromMemory(data, size, params); + } + + ImageRef Image::LoadFromStream(Stream& stream, const ImageParams& params) + { + return ImageLoader::LoadFromStream(stream, params); } void Image::EnsureOwnership() @@ -1477,7 +1455,7 @@ namespace Nz for (unsigned int i = 0; i < levels.size(); ++i) { std::size_t size = GetMemoryUsage(i); - levels[i].reset(new UInt8[size]); + levels[i] = std::make_unique(size); std::memcpy(levels[i].get(), m_sharedImage->levels[i].get(), size); } diff --git a/src/Nazara/Utility/Mesh.cpp b/src/Nazara/Utility/Mesh.cpp index 015ee520d..890577de4 100644 --- a/src/Nazara/Utility/Mesh.cpp +++ b/src/Nazara/Utility/Mesh.cpp @@ -521,21 +521,6 @@ namespace Nz return m_isValid; } - bool Mesh::LoadFromFile(const String& filePath, const MeshParams& params) - { - return MeshLoader::LoadFromFile(this, filePath, params); - } - - bool Mesh::LoadFromMemory(const void* data, std::size_t size, const MeshParams& params) - { - return MeshLoader::LoadFromMemory(this, data, size, params); - } - - bool Mesh::LoadFromStream(Stream& stream, const MeshParams& params) - { - return MeshLoader::LoadFromStream(this, stream, params); - } - void Mesh::Recenter() { NazaraAssert(m_isValid, "Mesh should be created first"); @@ -663,6 +648,21 @@ namespace Nz } } + MeshRef Mesh::LoadFromFile(const String& filePath, const MeshParams& params) + { + return MeshLoader::LoadFromFile(filePath, params); + } + + MeshRef Mesh::LoadFromMemory(const void* data, std::size_t size, const MeshParams& params) + { + return MeshLoader::LoadFromMemory(data, size, params); + } + + MeshRef Mesh::LoadFromStream(Stream& stream, const MeshParams& params) + { + return MeshLoader::LoadFromStream(stream, params); + } + bool Mesh::Initialize() { if (!MeshLibrary::Initialize()) diff --git a/tests/Engine/Audio/Music.cpp b/tests/Engine/Audio/Music.cpp index 404c57c5f..2e0edd8c3 100644 --- a/tests/Engine/Audio/Music.cpp +++ b/tests/Engine/Audio/Music.cpp @@ -16,22 +16,22 @@ SCENARIO("Music", "[AUDIO][MUSIC]") THEN("We can ask the informations of the file") { - REQUIRE(music.GetDuration() <= 64000); // 1 min 03 = 63s = 63000ms - REQUIRE(music.GetDuration() >= 63000); - REQUIRE(music.GetFormat() == Nz::AudioFormat_Stereo); - REQUIRE(music.GetPlayingOffset() == 0); - REQUIRE(music.GetSampleCount() <= 5644800); // 64s * 44100 Hz * 2 (stereo) - REQUIRE(music.GetSampleCount() >= 5556600); // 63s * 44100 Hz * 2 (stereo) - REQUIRE(music.GetSampleRate() == 44100 /* Hz */); - REQUIRE(music.GetStatus() == Nz::SoundStatus_Stopped); - REQUIRE(music.IsLooping() == false); + CHECK(music.GetDuration() <= 64000); // 1 min 03 = 63s = 63000ms + CHECK(music.GetDuration() >= 63000); + CHECK(music.GetFormat() == Nz::AudioFormat_Stereo); + CHECK(music.GetPlayingOffset() == 0); + CHECK(music.GetSampleCount() <= 5644800); // 64s * 44100 Hz * 2 (stereo) + CHECK(music.GetSampleCount() >= 5556600); // 63s * 44100 Hz * 2 (stereo) + CHECK(music.GetSampleRate() == 44100 /* Hz */); + CHECK(music.GetStatus() == Nz::SoundStatus_Stopped); + CHECK(music.IsLooping() == false); } THEN("We can play it and get the time offset") { Nz::Audio::SetGlobalVolume(0.f); - music.Play(); + music.Play(); Nz::Thread::Sleep(1000); REQUIRE(music.GetPlayingOffset() >= 950); Nz::Thread::Sleep(200); diff --git a/tests/Engine/Audio/SoundBuffer.cpp b/tests/Engine/Audio/SoundBuffer.cpp index ed5f2f6c6..292a1e98e 100644 --- a/tests/Engine/Audio/SoundBuffer.cpp +++ b/tests/Engine/Audio/SoundBuffer.cpp @@ -5,16 +5,15 @@ SCENARIO("SoundBuffer", "[AUDIO][SOUNDBUFFER]") { GIVEN("A sound buffer") { - Nz::SoundBuffer soundBuffer; - WHEN("We load our sound") { - REQUIRE(soundBuffer.LoadFromFile("resources/Engine/Audio/Cat.flac")); + Nz::SoundBufferRef soundBuffer = Nz::SoundBuffer::LoadFromFile("resources/Engine/Audio/Cat.flac"); + REQUIRE(soundBuffer.IsValid()); THEN("We can ask the informations of the file") { - REQUIRE(soundBuffer.GetDuration() <= 8500); // 8s = 8000ms - REQUIRE(soundBuffer.GetDuration() >= 8000); + REQUIRE(soundBuffer->GetDuration() <= 8500); // 8s = 8000ms + REQUIRE(soundBuffer->GetDuration() >= 8000); } } } diff --git a/tests/Engine/Graphics/Billboard.cpp b/tests/Engine/Graphics/Billboard.cpp index 651274bfd..376d990b1 100644 --- a/tests/Engine/Graphics/Billboard.cpp +++ b/tests/Engine/Graphics/Billboard.cpp @@ -9,8 +9,7 @@ SCENARIO("Billboard", "[GRAPHICS][BILLBOARD]") WHEN("We assign it to another") { - Nz::MaterialRef materialRef = Nz::Material::New(); - materialRef->LoadFromFile("resources/Engine/Graphics/Nazara.png"); + Nz::MaterialRef materialRef = Nz::Material::LoadFromFile("resources/Engine/Graphics/Nazara.png"); Nz::Color materialColor = materialRef->GetDiffuseColor(); Nz::BillboardRef otherBillboard = Nz::Billboard::New(materialRef); diff --git a/tests/Engine/Graphics/Model.cpp b/tests/Engine/Graphics/Model.cpp index 270d15a0e..89c1988f0 100644 --- a/tests/Engine/Graphics/Model.cpp +++ b/tests/Engine/Graphics/Model.cpp @@ -12,8 +12,8 @@ SCENARIO("Model", "[GRAPHICS][MODEL]") Nz::ModelParameters params; params.mesh.optimizeIndexBuffers = false; - Nz::ModelRef model = Nz::Model::New(); - REQUIRE(model->LoadFromFile("resources/Engine/Graphics/dragon_recon/dragon_vrip_res4.obj", params)); + Nz::ModelRef model = Nz::Model::LoadFromFile("resources/Engine/Graphics/dragon_recon/dragon_vrip_res4.obj", params); + REQUIRE(model); REQUIRE(model->GetMaterialCount() == 1); REQUIRE(model->GetSkin() == 0); diff --git a/tests/Engine/Graphics/SkeletalModel.cpp b/tests/Engine/Graphics/SkeletalModel.cpp index 87d2e43f1..95d819c9a 100644 --- a/tests/Engine/Graphics/SkeletalModel.cpp +++ b/tests/Engine/Graphics/SkeletalModel.cpp @@ -5,21 +5,20 @@ SCENARIO("SkeletalModel", "[GRAPHICS][SKELETALMODEL]") { GIVEN("A default skeletal model") { - Nz::SkeletalModel skeletalModel; - Nz::AnimationRef animation = Nz::Animation::New(); - WHEN("We can load the bob lamp") { - REQUIRE(skeletalModel.LoadFromFile("resources/Engine/Graphics/Bob lamp/bob_lamp_update.md5mesh")); - REQUIRE(animation->LoadFromFile("resources/Engine/Graphics/Bob lamp/bob_lamp_update.md5anim")); - skeletalModel.SetAnimation(animation); + Nz::AnimationRef animation = Nz::Animation::LoadFromFile("resources/Engine/Graphics/Bob lamp/bob_lamp_update.md5anim"); + Nz::SkeletalModelRef skeletalModel = Nz::StaticRefCast(Nz::SkeletalModel::LoadFromFile("resources/Engine/Graphics/Bob lamp/bob_lamp_update.md5mesh")); + REQUIRE(skeletalModel); + REQUIRE(animation); + skeletalModel->SetAnimation(animation); THEN("We can enable its animation") { - REQUIRE(skeletalModel.HasAnimation()); - skeletalModel.EnableAnimation(true); - skeletalModel.AdvanceAnimation(0.10f); - REQUIRE(skeletalModel.IsAnimationEnabled()); + REQUIRE(skeletalModel->HasAnimation()); + skeletalModel->EnableAnimation(true); + skeletalModel->AdvanceAnimation(0.10f); + REQUIRE(skeletalModel->IsAnimationEnabled()); } } } diff --git a/tests/Engine/Graphics/SkyboxBackground.cpp b/tests/Engine/Graphics/SkyboxBackground.cpp index 36ceb0db5..c2b1910ab 100644 --- a/tests/Engine/Graphics/SkyboxBackground.cpp +++ b/tests/Engine/Graphics/SkyboxBackground.cpp @@ -5,8 +5,7 @@ SCENARIO("SkyboxBackground", "[GRAPHICS][SKYBOXBACKGROUND]") { GIVEN("A skybox background with a loaded image") { - Nz::TextureRef textureRef = Nz::Texture::New(); - textureRef->LoadCubemapFromFile("resources/Engine/Graphics/skybox.png"); + Nz::TextureRef textureRef = Nz::Texture::LoadCubemapFromFile("resources/Engine/Graphics/skybox.png"); Nz::SkyboxBackgroundRef skyboxBackgroundRef = Nz::SkyboxBackground::New(textureRef); WHEN("We assign it parameters") diff --git a/tests/Engine/Graphics/TextureBackground.cpp b/tests/Engine/Graphics/TextureBackground.cpp index 33178d87f..ff89cc46f 100644 --- a/tests/Engine/Graphics/TextureBackground.cpp +++ b/tests/Engine/Graphics/TextureBackground.cpp @@ -5,8 +5,7 @@ SCENARIO("TextureBackground", "[GRAPHICS][TEXTUREBACKGROUND]") { GIVEN("A default texture background") { - Nz::TextureRef textureRef = Nz::Texture::New(); - textureRef->LoadFromFile("resources/Engine/Graphics/skybox.png"); + Nz::TextureRef textureRef = Nz::Texture::LoadFromFile("resources/Engine/Graphics/skybox.png"); Nz::TextureBackgroundRef textureBackgroundRef = Nz::TextureBackground::New(textureRef); WHEN("We assign it parameters") @@ -17,4 +16,4 @@ SCENARIO("TextureBackground", "[GRAPHICS][TEXTUREBACKGROUND]") } } } -} \ No newline at end of file +}