]], space))
+ end
+end
+
+function Feature.GenerateModuleDescriptions(modules, space, content)
+ for k,v in pairs(modules) do
+ table.insert(content, string.format([[%s
", space))
+ for k,v in pairs(featureTable) do
+ local progress = v.Progress
+ local c = Feature.ComputeColor(progress)
+ local desc = (progress == 100) and "" or string.format(" (%d%%)", math.floor(progress))
+
+ table.insert(content, string.format("%s
", space))
+ table.insert(content, string.format([[%s %s%s]], space, c[1], c[2], c[3], v.Title, desc))
+
+ if (v.Description) then
+ table.insert(content, string.format([[%s %s]], space, v.Description))
+ end
+
+ if (v.Features) then
+ Feature.GenerateFeatureList(v.Features, space .. "\t\t\t", content)
+ end
+
+ if (v.Note) then
+ table.insert(content, string.format([[%s Note: %s]], space, v.Note))
+ end
+
+ if (v.Portability ~= Feature.NotApplicable and Feature.AND(v.Portability, v.RequiredPortability) ~= v.RequiredPortability) then
+ table.insert(content, string.format([[%s Il manque une implémentation sur au moins un des OS supportés]], space))
+ end
+
+ table.insert(content, string.format("%s
", space))
+ end
+ table.insert(content, string.format("%s
", space))
+end
+
+newaction
+{
+ trigger = "generatefeatures",
+ description = "Generate a web page describing each module's feature",
+ execute = Feature.Generate
+}
diff --git a/build/scripts/features/audio.lua b/build/scripts/features/audio.lua
new file mode 100644
index 000000000..3c6a7dea7
--- /dev/null
+++ b/build/scripts/features/audio.lua
@@ -0,0 +1,89 @@
+return {
+ Title = "Module audio",
+ LibName = "NazaraAudio",
+ Description = "Module permettant de charger et jouer des sons, ainsi que d'accéder au microphone",
+ RequiredPortability = Feature.Windows + Feature.POSIX,
+
+ Features =
+ {
+ {
+ Title = "Gestion des émetteurs de sons (SoundEmitter)",
+ Description = "Classe de base dont héritent les sources sonores (Music, Sound)",
+ Features =
+ {
+ "Positionnement 3D (spatialisation) si désiré",
+ "Configuration de l'atténuation",
+ "Prise en charge de l'effet Doppler (vitesse du son)",
+ "Altération du ton (pitch)"
+ }
+ },
+ {
+ Title = "Gestion des tampons sonores (SoundBuffer)",
+ Description = "Tampon (buffer) stockant les échantillons (samples) décompressés, chargés à partir de fichiers sonores.",
+ Features =
+ {
+ {
+ Title = "Mixage mono",
+ Description = "Permet de mixer les différents canaux en un seul (mono), permettant la spatialisation.",
+ Note = "Le mixage mono n'est actuellement possible qu'au chargement du tampon depuis un fichier",
+ Progress = 90
+ }
+ }
+ },
+ {
+ Title = "Gestion des flux sonores (SoundStream)",
+ Description = "Interface permettant de définir un flux sonore de source indéfinie (fichier, réseau, etc.)"
+ },
+ {
+ Title = "Sons (Sound)",
+ Description = "Classe permettant de jouer un tampon sonore",
+ Features =
+ {
+ "Bouclage",
+ "Mise en pause",
+ "Récupération/positionnement de l'indice de lecture (offset)"
+ }
+ },
+ {
+ Title = "Sons streamés (Music)",
+ Description = "Classe permettant de jouer un son depuis un flux quelconque (SoundStream)",
+ Features =
+ {
+ "Streaming depuis un fichier sonore (+ mixage mono si demandé)",
+ "Bouclage",
+ "Mise en pause",
+ {Title = "Mixage mono", Note = "Le mixage mono devrait être possible au niveau du son lui-même plutôt qu'au niveau du loader", Progress = 0},
+ {Title = "Récupération/positionnement de l'indice de lecture (offset)", Progress = 0}
+ }
+ },
+ {
+ Title = "Configuration globale (Audio)",
+ Description = "Classe permettant de régler les différents paramètres généraux de l'environnement sonore",
+ Features =
+ {
+ "Positionnement/Orientation du listener",
+ "Réglage du volume général",
+ "Réglage de la vitesse du son/facteur Doppler"
+ }
+ },
+ {
+ Title = "Microphone",
+ Description = "Classe permettant l'accès aux microphones connectés à l'ordinateur",
+ Progress = 0
+ },
+ {
+ Title = "Environnement (EFX)",
+ Description = "Prise en charge de l'environnement",
+ Progress = 0
+ },
+ {
+ Title = "Formats supportés (chargement/streaming)",
+ Description = "Liste des formats de fichiers supportés par le loader inclus par le module (libsndfile)",
+ Note = "Le populaire format MP3 n'est pas supporté pour des raisons de royalties (mais la flexibilité du moteur vous permet de rajouter votre propre loader MP3)",
+ Features =
+ {
+ "aiff", "au", "avr", "caf", "flac", "htk", "ircam", "mat4", "mat5", "mpc2k", "nist","ogg", "pvf", "raw", "rf64", "sd2", "sds", "svx", "voc", "w64", "wav", "wve"
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/build/scripts/features/core.lua b/build/scripts/features/core.lua
new file mode 100644
index 000000000..120917eab
--- /dev/null
+++ b/build/scripts/features/core.lua
@@ -0,0 +1,204 @@
+return {
+ Title = "Noyau",
+ LibName = "NazaraCore",
+ Description = "Noyau du moteur, possède les fonctionnalités utilisées partout ailleurs dans le moteur.",
+ RequiredPortability = Feature.Windows + Feature.POSIX,
+
+ Features =
+ {
+ {
+ Title = "Classes utilitaires de base",
+ Description = "Classes assurant certaines fonctionnalités de base destinées à aider le programmeur.",
+ Features =
+ {
+ {
+ Title = "Chaînes de caractère unicode (String)",
+ Description = "Classe supplantant std::string, rajoutant le support de l'UTF-8 et quelques opérations utiles (rechercher/remplacer, correspondance par motif, ..)."
+ },
+ {
+ Title = "Exécution de code lors de la destruction (CallOnExit)",
+ Description = "Permet l'appel d'une fonction/lambda à la destruction de cet objet, en accordance avec le RAII/RRID."
+ },
+ {
+ Title = "Gestion de l'initialisation/libération statique de classes, en accordance avec le RAII/RRID",
+ Description = "Permet d'initialiser et de libérer automatiquement des classes possédant des fonctions membres statiques Initialize/Uninitialize, selon un ordre de dépendance, comme par exemple les classes des modules du moteur lui-même."
+ },
+ {
+ Title = "Gestion des couleurs (Color)",
+ Description = "Classe permettant de stocker et effectuer des opérations sur des couleurs (conversion, mélange, etc.)."
+ },
+ {
+ Title = "Gestion de primitives, au sens géométrique (Primitive, PrimitiveList)",
+ Description = "Structures définissant certaines primitives géométriques (boite, cône, plan, sphère), utiles pour la génération de meshs (de rendu ou physiques)."
+ },
+ {
+ Title = "OffsetOf",
+ Description = "Fonction permettant de récupérer à la compilation l'adresse locale (décalage d'octets) d'un membre de n'importe quelle structure/classe."
+ },
+ {
+ Title = "Pointeurs à écart (stride) indépendant (SparsePtr)",
+ Description = "Classe se comportant comme un pointeur, à l'exception de l'écart entre deux éléments (opérations d'accès, d'addition et de soustraction) qui est indépendant du type pointé."
+ },
+ {
+ Title = "Stockage et gestion de champs de bits dynamiques (Bitset)",
+ Description = "Classe permettant le stockage et la manipulation optimisée d'un nombre élevé et dynamique de bits (=booléens, opérations de comptage, recherche de bits activés, opérations entre champs de bits, etc.)",
+ Note = "Il manque des opérateurs de comparaison et une spécialisation de la fonction de hachage",
+ Progress = 90
+ }
+ }
+ },
+ {
+ Title = "Gestion de fichiers et dossiers (File/Directory)",
+ Description = "Classes supportant les chemins unicodes et les tailles 64 bits, ainsi que quelques opérations sur les chemins (normalisation, transformation d'un chemin relatif en chemin absolu).",
+ Portability = Feature.Windows + Feature.POSIX
+ },
+ {
+ Title = "Gestion de l'endianness",
+ Description = "Boutisme, récupération à la compilation ou à l'exécution, possibilité de lire des fichiers en corrigeant le boutisme des objets lors de la lecture."
+ },
+ {
+ Title = "Gestion de bibliothèques dynamiques (DynLib)",
+ Description = "Classe permettant de charger à l'exécution des bibliothèques dynamiques (selon la plateforme: .dll/.so/.dynlib) et d'en extraire des fonctions.",
+ Portability = Feature.Windows + Feature.POSIX
+ },
+ {
+ Title = "Fonctions de hachage",
+ Description = "Possibilité de hacher (calculer une somme de contrôle) de n'importe quelles données, chaîne de caractère ou fichier.",
+ Features =
+ {
+ {Title = "CRC16", Progress = 0},
+ "CRC32",
+ "Fletcher16",
+ {Title = "Fletcher32", Progress = 0},
+ "MD5",
+ "SHA-1",
+ "SHA-224",
+ "SHA-256",
+ "SHA-384",
+ "SHA-512",
+ "Whirlpool"
+ }
+ },
+ {
+ Title = "Gestion de la mémoire",
+ Description = "Set de fonctionnalités permettant d'aider le programmeur à gérer la mémoire de son programme.",
+ Features =
+ {
+ {
+ Title = "MemoryManager",
+ Description = "Classe permettant de suivre les allocations de mémoire et éventuels leaks, peut suivre automatiquement chaque allocation du programme."
+ },
+ {
+ Title = "MemoryPool",
+ Description = "Classe permettant d'allouer/libérer des blocs de mémoire de taille prédéfinie à coût constant."
+ }
+ }
+ },
+ {
+ Title = "Gestion de l'exécution concurrentielle",
+ Description = "Set de fonctionnalités liées à l'exécution et la synchronisation entre processus légers (threads) sans dépendance sur la bibliothèque standard.",
+ Features =
+ {
+ {
+ Title = "Thread",
+ Description = "Classe permettant d'appeler une fonction (avec passage d'arguments) dans un thread, supporte une interface similaire à std::thread.",
+ Note = "Il n'est pas encore possible de récupérer le Thread::Id courant",
+ Progress = 95,
+ Portability = Feature.Windows + Feature.POSIX
+ },
+ {
+ Title = "Mutex",
+ Description = "Primitive de synchronisation binaire (exclusion mutuelle).",
+ Portability = Feature.Windows + Feature.POSIX
+ },
+ {
+ Title = "Semaphore",
+ Description = "Primitive de synchronisation à N concurrents simultanés.",
+ Portability = Feature.Windows + Feature.POSIX
+ },
+ {
+ Title = "ConditionVariable",
+ Description = "Primitive de synchronisation à signaux.",
+ Portability = Feature.Windows + Feature.POSIX
+ },
+ {
+ Title = "LockGuard",
+ Description = "Classe utilitaire permettant de verrouiller/déverrouiller une mutex en accordance avec le RAII/RRID."
+ },
+ {
+ Title = "TaskScheduler",
+ Description = "Classe permettant de répartir X tâches sur Y workers de façon efficace.",
+ Portability = Feature.Windows
+ }
+ }
+ },
+ {
+ Title = "Gestion du temps",
+ Description = "Classes/fonctions permettant de gérer le temps dans un programme.",
+ Features =
+ {
+ {
+ Title = "Récupération du temps en millisecondes ou en microsecondes",
+ Description = "Permet de récupérer le nombre de millisecondes ou de microsecondes (si supporté par le système) écoulées depuis un référentiel constant (référentiel indéterminé).",
+ Portability = Feature.Windows + Feature.POSIX
+ },
+ {
+ Title = "Clock",
+ Description = "Classe chronomètre permettant de mesurer le temps écoulé depuis un évènement précis, supporte la mise en pause."
+ }
+ }
+ },
+ {
+ Title = "Gestion de compteurs de référence",
+ Description = "Set de classes permettant de gérer des pointeurs intelligents partagés intrusifs.",
+ },
+ {
+ Title = "Gestion de liste de paramètres",
+ Description = "Classe gérant une liste de paramètres nommées à type variable.",
+ },
+ {
+ Title = "Gestion de ressources (chargement/gestion)",
+ Description = "Set de classes s'occupant du chargement et de la gestion de certaines classes spéciales, appartenant au groupe des ressources (ex: chargée depuis un fichier).",
+ Features =
+ {
+ {
+ Title = "ResourceLibrary",
+ Description = "Classe template chargée du stockage de ressources de façon nommée."
+ },
+ {
+ Title = "ResourceLoader",
+ Description = "Classe template chargée de stocker et gérer des loaders (fonctions s'occupant de transformer un flux de données en ressource)."
+ },
+ {
+ Title = "ResourceManager",
+ Description = "Classe template chargée de charger et mettre en cache des ressources depuis un chemin de fichier."
+ }
+ }
+ },
+ {
+ Title = "Gestion des plugins",
+ Description = "Capacité d'extension du moteur à l'aide de bibliothèques dynamiques conçues dans cette optique.",
+ Note = "Nécessite une révision, permettant aux plugins de se signaler (nom, version)",
+ Progress = 80
+ },
+ {
+ Title = "Gestion de l'empaquetage bidimensionnel",
+ Description = "Algorithmes permettant de placer des rectangles 2D arbitraires dans un espace prédéfini de façon à minimiser la perte d'espace.",
+ Note = "Algorithme Guillotine terminé, algorithme Skyline manquant",
+ Progress = 60
+ },
+ {
+ Title = "Gestion de l'Unicode",
+ Description = "Récupération d'informations sur les caractères Unicode (si les données Unicode sont incorporées au programme).",
+ Note = "Il manque l'intégration des UnicodeData dans le moteur",
+ Progress = 20
+ },
+ {
+ Title = "Récupération d'informations sur le hardware",
+ Description = "Classe permettant, si la plateforme le supporte, de récupérer des informations utiles sur le matériel: nom et fabricant du processeur, nombre de coeurs, support d'un set d'extension (exemple: SSE), quantité de mémoire vive, exécution de l'instruction CPUID.",
+ Note = "Il manque de quoi récupérer la quantité de mémoire vive",
+ Progress = 90,
+ Portability = Feature.Windows + Feature.POSIX
+ }
+ }
+}
\ No newline at end of file
diff --git a/build/scripts/features/index_template.html b/build/scripts/features/index_template.html
new file mode 100644
index 000000000..d06aeb4d9
--- /dev/null
+++ b/build/scripts/features/index_template.html
@@ -0,0 +1,75 @@
+
+
+
+
+
+ Avancement de Nazara
+
+
+
+
+
+
+ Retrouvez le moteur sur GitHub !
+
+ Dépôt Github
+ Afin de faciliter la mise à jour, la page que vous voyez ici a été généré automatiquement par un script Lua, ce qui m'oblige néanmoins à encoder les fonctionnalités de chaque module dans un premier temps.
+ C'est un travail assez long (pour vous donner une idée, les données du noyau représentent un fichier de 200 lignes), et il n'est pas encore complet, c'est pourquoi des modules manquent sur cette page.
+ Gardez donc à l'esprit que le moteur possède plus de fonctionnalités que ce qui est décrit actuellement sur cette page.
+
+ Oh et bien sûr je ne suis pas concepteur de site web, c'est pourquoi cette page est moche (j'ai essayé de minimiser les dégats).
+ Si vous sentez en vous l'irrésistible envie d'améliorer cette page, sachez que votre aide sera grandement appréciée (vous pouvez me contacter via le lien de votre choix plus haut).
+
+
+ Le pourcentage indiqué est calculé automatiquement en fonction des fonctionnalités, cela signifie qu'une fonctionnalité présente sera comptée à 100% à partir du moment où son implémentation de base est considérée fonctionnelle, cela n'est donc pas une assurance qu'aucun bug n'existe concernant cette fonctionnalité (cependant cela signifie que la fonctionnalité est utilisable).
+ Et bien entendu, un module ou une fonctionnalité ayant atteint les 100% peut toujours évoluer par la suite.
+
+
+
+
Sommaire
+
+
+
Module
+
Avancement
+
+
+
+ %MODULELIST%
+
+
+
+ %MODULEDESCRIPTION%
+
+
+
+
Sommaire
+
+
+
Module
+
Pourcentage
+
+
+
+ %MODULELIST%
+
+
+
+
+
\ No newline at end of file
diff --git a/build/scripts/features/style.css b/build/scripts/features/style.css
new file mode 100644
index 000000000..8a3399bad
--- /dev/null
+++ b/build/scripts/features/style.css
@@ -0,0 +1,108 @@
+/* Je ne suis pas développeur HTML/CSS, je dois y toucher une fois l'an, désolé pour les quelques atrocités que vous pourrez trouver ici */
+
+body
+{
+ background-color: black;
+ color: white;
+}
+
+a
+{
+ color: #007ACC;
+}
+
+a:hover
+{
+ color: lightblue;
+}
+
+h1
+{
+ display: inline;
+}
+
+h2
+{
+ display: inline;
+ text-decoration: underline;
+}
+
+h4
+{
+ text-decoration: underline;
+}
+
+ol
+{
+ list-style-type: none;
+}
+
+table
+{
+ border-collapse: collapse;
+ text-align: center;
+ display: inline-block;
+ border: white groove;
+ border-radius: 10px;
+ box-shadow: 0px 0px 10px lightblue;
+}
+
+th
+{
+ text-shadow: 2px 2px 4px black;
+}
+
+tr
+{
+ border: 1px solid white;
+}
+
+tbody tr:hover
+{
+ text-shadow: 0px 0px 4px white;
+}
+
+.centre
+{
+ text-align: center;
+}
+
+.description
+{
+ margin-left: 20px;
+}
+
+.lastupdate
+{
+ font-size: x-large;
+ font-weight: bold;
+ color: yellow;
+}
+
+.module
+{
+}
+
+.modulename
+{
+ font-size: x-large;
+ font-weight: bold;
+ text-shadow: 2px 2px 10px #007ACC;
+}
+
+.note
+{
+ margin-left: 20px;
+ color: #007ACC;
+}
+
+.notedesc
+{
+ color: rgb(200, 200, 255);
+}
+
+.portability
+{
+ margin-left: 20px;
+ color: red;
+}
\ No newline at end of file
diff --git a/include/Nazara/Audio/Algorithm.inl b/include/Nazara/Audio/Algorithm.inl
index c673d9601..ca4b28575 100644
--- a/include/Nazara/Audio/Algorithm.inl
+++ b/include/Nazara/Audio/Algorithm.inl
@@ -8,6 +8,7 @@
template
void NzMixToMono(T* input, T* output, unsigned int channelCount, unsigned int frameCount)
{
+ ///DOC: Le buffer d'entrée peut être le même que le buffer de sortie
// Pour éviter l'overflow, on utilise comme accumulateur un type assez grand, (u)int 64 bits pour les entiers, double pour les flottants
typedef typename std::conditional::value, nzUInt64, nzInt64>::type BiggestInt;
typedef typename std::conditional::value, BiggestInt, double>::type Biggest;
diff --git a/include/Nazara/Audio/ConfigCheck.hpp b/include/Nazara/Audio/ConfigCheck.hpp
index 7c32933bd..546f77dd0 100644
--- a/include/Nazara/Audio/ConfigCheck.hpp
+++ b/include/Nazara/Audio/ConfigCheck.hpp
@@ -10,7 +10,7 @@
/// Ce fichier sert à vérifier la valeur des constantes du fichier Config.hpp
#include
-#define CheckTypeAndVal(name, type, op, val, err) static_assert(std::is_ ##type ::value && name op val, #type err)
+#define NazaraCheckTypeAndVal(name, type, op, val, err) static_assert(std::is_ ##type ::value && name op val, #type err)
// On force la valeur de MANAGE_MEMORY en mode debug
#if defined(NAZARA_DEBUG) && !NAZARA_AUDIO_MANAGE_MEMORY
@@ -18,6 +18,8 @@
#define NAZARA_AUDIO_MANAGE_MEMORY 1
#endif
-CheckTypeAndVal(NAZARA_AUDIO_STREAMED_BUFFER_COUNT, integral, >, 0, " shall be a strictly positive integer");
+NazaraCheckTypeAndVal(NAZARA_AUDIO_STREAMED_BUFFER_COUNT, integral, >, 0, " shall be a strictly positive integer");
+
+#undef NazaraCheckTypeAndVal
#endif // NAZARA_CONFIG_CHECK_AUDIO_HPP
diff --git a/include/Nazara/Core/Tuple.hpp b/include/Nazara/Core/Algorithm.hpp
similarity index 53%
rename from include/Nazara/Core/Tuple.hpp
rename to include/Nazara/Core/Algorithm.hpp
index 1626e5177..26c9efbcf 100644
--- a/include/Nazara/Core/Tuple.hpp
+++ b/include/Nazara/Core/Algorithm.hpp
@@ -4,13 +4,16 @@
#pragma once
-#ifndef NAZARA_TUPLE_HPP
-#define NAZARA_TUPLE_HPP
+#ifndef NAZARA_ALGORITHM_CORE_HPP
+#define NAZARA_ALGORITHM_CORE_HPP
+#include
+#include
#include
+template void NzHashCombine(std::size_t& seed, const T& v);
template void NzUnpackTuple(F func, const std::tuple& t);
-#include
+#include
-#endif // NAZARA_TUPLE_HPP
+#endif // NAZARA_ALGORITHM_CORE_HPP
diff --git a/include/Nazara/Core/Tuple.inl b/include/Nazara/Core/Algorithm.inl
similarity index 66%
rename from include/Nazara/Core/Tuple.inl
rename to include/Nazara/Core/Algorithm.inl
index 46c6b5753..1fa2a9032 100644
--- a/include/Nazara/Core/Tuple.inl
+++ b/include/Nazara/Core/Algorithm.inl
@@ -8,6 +8,8 @@
#include
+///TODO: Améliorer l'implémentation de UnpackTuple
+
template
struct NzImplTupleUnpack
{
@@ -28,6 +30,23 @@ struct NzImplTupleUnpack<0>
}
};
+// Algorithme venant de CityHash par Google
+// http://stackoverflow.com/questions/8513911/how-to-create-a-good-hash-combine-with-64-bit-output-inspired-by-boosthash-co
+template
+void NzHashCombine(std::size_t& seed, const T& v)
+{
+ const nzUInt64 kMul = 0x9ddfea08eb382d69ULL;
+
+ std::hash hasher;
+ nzUInt64 a = (hasher(v) ^ seed) * kMul;
+ a ^= (a >> 47);
+
+ nzUInt64 b = (seed ^ a) * kMul;
+ b ^= (b >> 47);
+
+ seed = static_cast(b * kMul);
+}
+
template
void NzUnpackTuple(F func, const std::tuple& t)
{
diff --git a/include/Nazara/Core/Color.inl b/include/Nazara/Core/Color.inl
index 00b29321e..8e2caa76c 100644
--- a/include/Nazara/Core/Color.inl
+++ b/include/Nazara/Core/Color.inl
@@ -148,7 +148,7 @@ inline NzColor NzColor::FromHSV(float hue, float saturation, float value)
if (NzNumberEquals(h, 6.f))
h = 0; // hue must be < 1
- int i = h;
+ int i = static_cast(h);
float v1 = value * (1.f - s);
float v2 = value * (1.f - s * (h - i));
float v3 = value * (1.f - s * (1.f - (h - i)));
diff --git a/include/Nazara/Core/ConfigCheck.hpp b/include/Nazara/Core/ConfigCheck.hpp
index 503152153..4e02a55de 100644
--- a/include/Nazara/Core/ConfigCheck.hpp
+++ b/include/Nazara/Core/ConfigCheck.hpp
@@ -10,7 +10,7 @@
/// Ce fichier sert à vérifier la valeur des constantes du fichier Config.hpp
#include
-#define CheckTypeAndVal(name, type, op, val, err) static_assert(std::is_ ##type ::value && name op val, #type err)
+#define NazaraCheckTypeAndVal(name, type, op, val, err) static_assert(std::is_ ##type ::value && name op val, #type err)
// On force la valeur de MANAGE_MEMORY en mode debug
#if defined(NAZARA_DEBUG) && !NAZARA_CORE_MANAGE_MEMORY
@@ -18,8 +18,10 @@
#define NAZARA_CORE_MANAGE_MEMORY 1
#endif
-CheckTypeAndVal(NAZARA_CORE_DECIMAL_DIGITS, integral, >, 0, " shall be a strictly positive integer");
-CheckTypeAndVal(NAZARA_CORE_FILE_BUFFERSIZE, integral, >, 0, " shall be a strictly positive integer");
-CheckTypeAndVal(NAZARA_CORE_WINDOWS_CS_SPINLOCKS, integral, >=, 0, " shall be a positive integer");
+NazaraCheckTypeAndVal(NAZARA_CORE_DECIMAL_DIGITS, integral, >, 0, " shall be a strictly positive integer");
+NazaraCheckTypeAndVal(NAZARA_CORE_FILE_BUFFERSIZE, integral, >, 0, " shall be a strictly positive integer");
+NazaraCheckTypeAndVal(NAZARA_CORE_WINDOWS_CS_SPINLOCKS, integral, >=, 0, " shall be a positive integer");
+
+#undef NazaraCheckTypeAndVal
#endif // NAZARA_CONFIG_CHECK_CORE_HPP
diff --git a/include/Nazara/Core/Endianness.hpp b/include/Nazara/Core/Endianness.hpp
index 76b9e34ad..3f929f912 100644
--- a/include/Nazara/Core/Endianness.hpp
+++ b/include/Nazara/Core/Endianness.hpp
@@ -15,7 +15,8 @@
#if defined(__m68k__) || defined(mc68000) || defined(_M_M68K) || (defined(__MIPS__) && defined(__MISPEB__)) || \
defined(__ppc__) || defined(__POWERPC__) || defined(_M_PPC) || defined(__sparc__) || defined(__hppa__)
#define NAZARA_BIG_ENDIAN
- #elif defined(__i386__) || defined(__i386) || defined(__X86__) || defined (__x86_64)
+ #elif defined(__i386__) || defined(__i386) || defined(__X86__) || defined (__x86_64) || defined(_M_I86) || \
+ defined(_M_IX86) || defined(_M_X64)
#define NAZARA_LITTLE_ENDIAN
#else
#error Failed to identify endianness, you must define either NAZARA_BIG_ENDIAN or NAZARA_LITTLE_ENDIAN
diff --git a/include/Nazara/Core/Functor.hpp b/include/Nazara/Core/Functor.hpp
index a93ffb34b..46ffc634f 100644
--- a/include/Nazara/Core/Functor.hpp
+++ b/include/Nazara/Core/Functor.hpp
@@ -7,7 +7,7 @@
#ifndef NAZARA_FUNCTOR_HPP
#define NAZARA_FUNCTOR_HPP
-#include
+#include
// Inspiré du code de la SFML par Laurent Gomila
diff --git a/include/Nazara/Core/HardwareInfo.hpp b/include/Nazara/Core/HardwareInfo.hpp
index 575b3ebc9..73f0c9eb8 100644
--- a/include/Nazara/Core/HardwareInfo.hpp
+++ b/include/Nazara/Core/HardwareInfo.hpp
@@ -14,6 +14,8 @@
class NAZARA_API NzHardwareInfo
{
public:
+ static void Cpuid(nzUInt32 functionId, nzUInt32 subFunctionId, nzUInt32 result[4]);
+
static NzString GetProcessorBrandString();
static unsigned int GetProcessorCount();
static nzProcessorVendor GetProcessorVendor();
@@ -23,6 +25,7 @@ class NAZARA_API NzHardwareInfo
static bool Initialize();
+ static bool IsCpuidSupported();
static bool IsInitialized();
static void Uninitialize();
diff --git a/include/Nazara/Core/PluginManager.hpp b/include/Nazara/Core/PluginManager.hpp
index e4a1851b4..57e3f4687 100644
--- a/include/Nazara/Core/PluginManager.hpp
+++ b/include/Nazara/Core/PluginManager.hpp
@@ -13,6 +13,8 @@
#include
#include
+///TODO: Révision
+
class NzDynLib;
class NAZARA_API NzPluginManager
diff --git a/include/Nazara/Core/RefCounted.hpp b/include/Nazara/Core/RefCounted.hpp
index 401b712c9..70b1c1c15 100644
--- a/include/Nazara/Core/RefCounted.hpp
+++ b/include/Nazara/Core/RefCounted.hpp
@@ -50,8 +50,6 @@ class NAZARA_API NzRefCounted
private:
using ObjectListenerMap = std::unordered_map>;
- void RemoveObjectListenerIterator(ObjectListenerMap::iterator iterator) const;
-
NazaraMutexAttrib(m_mutex, mutable)
mutable ObjectListenerMap m_objectListeners;
diff --git a/include/Nazara/Core/String.hpp b/include/Nazara/Core/String.hpp
index b9be14585..419f23135 100644
--- a/include/Nazara/Core/String.hpp
+++ b/include/Nazara/Core/String.hpp
@@ -87,10 +87,10 @@ class NAZARA_API NzString : public NzHashable
const char* GetConstBuffer() const;
unsigned int GetLength() const;
unsigned int GetSize() const;
- char* GetUtf8Buffer(unsigned int* size = nullptr) const;
- char16_t* GetUtf16Buffer(unsigned int* size = nullptr) const;
- char32_t* GetUtf32Buffer(unsigned int* size = nullptr) const;
- wchar_t* GetWideBuffer(unsigned int* size = nullptr) const;
+ std::string GetUtf8String() const;
+ std::u16string GetUtf16String() const;
+ std::u32string GetUtf32String() const;
+ std::wstring GetWideString() const;
NzString GetWord(unsigned int index, nzUInt32 flags = None) const;
unsigned int GetWordPosition(unsigned int index, nzUInt32 flags = None) const;
diff --git a/include/Nazara/Core/Thread.hpp b/include/Nazara/Core/Thread.hpp
index ca5fd498a..3b5aca7d5 100644
--- a/include/Nazara/Core/Thread.hpp
+++ b/include/Nazara/Core/Thread.hpp
@@ -10,7 +10,7 @@
#include
#include
#include
-#include
+#include
class NzThreadImpl;
diff --git a/include/Nazara/Graphics/ConfigCheck.hpp b/include/Nazara/Graphics/ConfigCheck.hpp
index 98fee1840..1365688ac 100644
--- a/include/Nazara/Graphics/ConfigCheck.hpp
+++ b/include/Nazara/Graphics/ConfigCheck.hpp
@@ -10,7 +10,7 @@
/// Ce fichier sert à vérifier la valeur des constantes du fichier Config.hpp
#include
-#define CheckTypeAndVal(name, type, op, val, err) static_assert(std::is_ ##type ::value && name op val, #type err)
+#define NazaraCheckTypeAndVal(name, type, op, val, err) static_assert(std::is_ ##type ::value && name op val, #type err)
// On force la valeur de MANAGE_MEMORY en mode debug
#if defined(NAZARA_DEBUG) && !NAZARA_GRAPHICS_MANAGE_MEMORY
@@ -18,7 +18,9 @@
#define NAZARA_GRAPHICS_MANAGE_MEMORY 1
#endif
-CheckTypeAndVal(NAZARA_GRAPHICS_INSTANCING_MIN_INSTANCES_COUNT, integral, >, 0, " shall be a strictly positive integer");
-CheckTypeAndVal(NAZARA_GRAPHICS_MAX_LIGHT_PER_PASS, integral, >, 0, " shall be a strictly positive integer");
+NazaraCheckTypeAndVal(NAZARA_GRAPHICS_INSTANCING_MIN_INSTANCES_COUNT, integral, >, 0, " shall be a strictly positive integer");
+NazaraCheckTypeAndVal(NAZARA_GRAPHICS_MAX_LIGHT_PER_PASS, integral, >, 0, " shall be a strictly positive integer");
+
+#undef NazaraCheckTypeAndVal
#endif // NAZARA_CONFIG_CHECK_GRAPHICS_HPP
diff --git a/include/Nazara/Graphics/Material.hpp b/include/Nazara/Graphics/Material.hpp
index 08d6ae17a..0c3eb76f5 100644
--- a/include/Nazara/Graphics/Material.hpp
+++ b/include/Nazara/Graphics/Material.hpp
@@ -109,31 +109,31 @@ class NAZARA_API NzMaterial : public NzRefCounted, public NzResource
void Reset();
- bool SetAlphaMap(const NzString& name);
- void SetAlphaMap(NzTexture* map);
+ bool SetAlphaMap(const NzString& textureName);
+ void SetAlphaMap(NzTextureRef alphaMap);
void SetAlphaThreshold(float alphaThreshold);
void SetAmbientColor(const NzColor& ambient);
void SetDepthFunc(nzRendererComparison depthFunc);
void SetDiffuseColor(const NzColor& diffuse);
- bool SetDiffuseMap(const NzString& name);
- void SetDiffuseMap(NzTexture* map);
+ bool SetDiffuseMap(const NzString& textureName);
+ void SetDiffuseMap(NzTextureRef diffuseMap);
void SetDiffuseSampler(const NzTextureSampler& sampler);
void SetDstBlend(nzBlendFunc func);
- bool SetEmissiveMap(const NzString& name);
- void SetEmissiveMap(NzTexture* map);
+ bool SetEmissiveMap(const NzString& textureName);
+ void SetEmissiveMap(NzTextureRef textureName);
void SetFaceCulling(nzFaceSide faceSide);
void SetFaceFilling(nzFaceFilling filling);
- bool SetHeightMap(const NzString& name);
- void SetHeightMap(NzTexture* map);
- bool SetNormalMap(const NzString& name);
- void SetNormalMap(NzTexture* map);
+ bool SetHeightMap(const NzString& textureName);
+ void SetHeightMap(NzTextureRef textureName);
+ bool SetNormalMap(const NzString& textureName);
+ void SetNormalMap(NzTextureRef textureName);
void SetRenderStates(const NzRenderStates& states);
- void SetShader(const NzUberShader* uberShader);
+ void SetShader(NzUberShaderConstRef uberShader);
bool SetShader(const NzString& uberShaderName);
void SetShininess(float shininess);
void SetSpecularColor(const NzColor& specular);
- bool SetSpecularMap(const NzString& name);
- void SetSpecularMap(NzTexture* map);
+ bool SetSpecularMap(const NzString& textureName);
+ void SetSpecularMap(NzTextureRef specularMap);
void SetSpecularSampler(const NzTextureSampler& sampler);
void SetSrcBlend(nzBlendFunc func);
diff --git a/include/Nazara/Graphics/Model.hpp b/include/Nazara/Graphics/Model.hpp
index e93b65679..c46a0c5aa 100644
--- a/include/Nazara/Graphics/Model.hpp
+++ b/include/Nazara/Graphics/Model.hpp
@@ -40,14 +40,10 @@ class NAZARA_API NzModel : public NzResource, public NzSceneNode
virtual ~NzModel();
void AddToRenderQueue(NzAbstractRenderQueue* renderQueue) const override;
- void AdvanceAnimation(float elapsedTime);
NzModel* Clone() const;
NzModel* Create() const;
- void EnableAnimation(bool animation);
-
- NzAnimation* GetAnimation() const;
NzMaterial* GetMaterial(const NzString& subMeshName) const;
NzMaterial* GetMaterial(unsigned int matIndex) const;
NzMaterial* GetMaterial(unsigned int skinIndex, const NzString& subMeshName) const;
@@ -57,12 +53,7 @@ class NAZARA_API NzModel : public NzResource, public NzSceneNode
unsigned int GetSkinCount() const;
NzMesh* GetMesh() const;
nzSceneNodeType GetSceneNodeType() const override;
- NzSkeleton* GetSkeleton();
- const NzSkeleton* GetSkeleton() const;
- bool HasAnimation() const;
-
- bool IsAnimationEnabled() const;
virtual bool IsAnimated() const;
bool IsDrawable() const;
diff --git a/include/Nazara/Graphics/ParticleSystem.hpp b/include/Nazara/Graphics/ParticleSystem.hpp
index 8484f4628..d4abb84e6 100644
--- a/include/Nazara/Graphics/ParticleSystem.hpp
+++ b/include/Nazara/Graphics/ParticleSystem.hpp
@@ -16,6 +16,7 @@
#include
#include
#include
+#include
#include
#include
#include
diff --git a/include/Nazara/Graphics/SceneNode.hpp b/include/Nazara/Graphics/SceneNode.hpp
index e05d7e68b..d34214137 100644
--- a/include/Nazara/Graphics/SceneNode.hpp
+++ b/include/Nazara/Graphics/SceneNode.hpp
@@ -23,7 +23,7 @@ class NAZARA_API NzSceneNode : public NzNode
public:
NzSceneNode();
NzSceneNode(const NzSceneNode& sceneNode);
- NzSceneNode(NzSceneNode& sceneNode) = delete;
+ NzSceneNode(NzSceneNode&& sceneNode) = delete;
virtual ~NzSceneNode();
virtual void AddToRenderQueue(NzAbstractRenderQueue* renderQueue) const = 0;
diff --git a/include/Nazara/Graphics/View.hpp b/include/Nazara/Graphics/View.hpp
index 41cab8fe8..b10b30cc0 100644
--- a/include/Nazara/Graphics/View.hpp
+++ b/include/Nazara/Graphics/View.hpp
@@ -35,15 +35,20 @@ class NAZARA_API NzView : public NzAbstractViewer, public NzNode, NzRenderTarget
NzVector3f GetGlobalForward() const;
NzVector3f GetGlobalRight() const;
NzVector3f GetGlobalUp() const;
+ const NzMatrix4f& GetInvViewProjMatrix() const;
const NzMatrix4f& GetProjectionMatrix() const;
const NzVector2f& GetSize() const;
const NzRenderTarget* GetTarget() const;
const NzRectf& GetTargetRegion() const;
const NzMatrix4f& GetViewMatrix() const;
+ const NzMatrix4f& GetViewProjMatrix() const;
const NzRecti& GetViewport() const;
float GetZFar() const;
float GetZNear() const;
+ NzVector2i MapWorldToPixel(const NzVector2f& coords);
+ NzVector2f MapPixelToWorld(const NzVector2i& pixel);
+
void SetSize(const NzVector2f& size);
void SetSize(float width, float height);
void SetTarget(const NzRenderTarget* renderTarget);
@@ -61,20 +66,26 @@ class NAZARA_API NzView : public NzAbstractViewer, public NzNode, NzRenderTarget
bool OnRenderTargetSizeChange(const NzRenderTarget* renderTarget, void* userdata) override;
void UpdateFrustum() const;
+ void UpdateInvViewProjMatrix() const;
void UpdateProjectionMatrix() const;
void UpdateViewMatrix() const;
+ void UpdateViewProjMatrix() const;
void UpdateViewport() const;
mutable NzFrustumf m_frustum;
+ mutable NzMatrix4f m_invViewProjMatrix;
mutable NzMatrix4f m_projectionMatrix;
mutable NzMatrix4f m_viewMatrix;
+ mutable NzMatrix4f m_viewProjMatrix;
NzRectf m_targetRegion;
mutable NzRecti m_viewport;
NzVector2f m_size;
const NzRenderTarget* m_target;
mutable bool m_frustumUpdated;
+ mutable bool m_invViewProjMatrixUpdated;
mutable bool m_projectionMatrixUpdated;
mutable bool m_viewMatrixUpdated;
+ mutable bool m_viewProjMatrixUpdated;
mutable bool m_viewportUpdated;
float m_zFar;
float m_zNear;
diff --git a/include/Nazara/Lua/LuaInstance.hpp b/include/Nazara/Lua/LuaInstance.hpp
index f18c2dde8..f694c2fe7 100644
--- a/include/Nazara/Lua/LuaInstance.hpp
+++ b/include/Nazara/Lua/LuaInstance.hpp
@@ -38,8 +38,8 @@ class NAZARA_API NzLuaInstance : NzNonCopyable
void CheckAny(int index) const;
bool CheckBoolean(int index) const;
bool CheckBoolean(int index, bool defValue) const;
- int CheckInteger(int index) const;
- int CheckInteger(int index, int defValue) const;
+ long long CheckInteger(int index) const;
+ long long CheckInteger(int index, long long defValue) const;
double CheckNumber(int index) const;
double CheckNumber(int index, double defValue) const;
void CheckStack(int space, const char* error = nullptr) const;
@@ -47,8 +47,6 @@ class NAZARA_API NzLuaInstance : NzNonCopyable
const char* CheckString(int index, std::size_t* length = nullptr) const;
const char* CheckString(int index, const char* defValue, std::size_t* length = nullptr) const;
void CheckType(int index, nzLuaType type) const;
- unsigned int CheckUnsigned(int index) const;
- unsigned int CheckUnsigned(int index, unsigned int defValue) const;
void* CheckUserdata(int index, const char* tname) const;
void* CheckUserdata(int index, const NzString& tname) const;
@@ -71,19 +69,19 @@ class NAZARA_API NzLuaInstance : NzNonCopyable
bool ExecuteFromStream(NzInputStream& stream);
int GetAbsIndex(int index) const;
- void GetField(const char* fieldName, int index = -1) const;
- void GetField(const NzString& fieldName, int index = -1) const;
- void GetGlobal(const char* name) const;
- void GetGlobal(const NzString& name) const;
+ nzLuaType GetField(const char* fieldName, int index = -1) const;
+ nzLuaType GetField(const NzString& fieldName, int index = -1) const;
+ nzLuaType GetGlobal(const char* name) const;
+ nzLuaType GetGlobal(const NzString& name) const;
lua_State* GetInternalState() const;
NzString GetLastError() const;
nzUInt32 GetMemoryLimit() const;
nzUInt32 GetMemoryUsage() const;
- void GetMetatable(const char* tname) const;
- void GetMetatable(const NzString& tname) const;
+ nzLuaType GetMetatable(const char* tname) const;
+ nzLuaType GetMetatable(const NzString& tname) const;
bool GetMetatable(int index) const;
unsigned int GetStackTop() const;
- void GetTable(int index = -2) const;
+ nzLuaType GetTable(int index = -2) const;
nzUInt32 GetTimeLimit() const;
nzLuaType GetType(int index) const;
const char* GetTypeName(nzLuaType type) const;
@@ -108,7 +106,7 @@ class NAZARA_API NzLuaInstance : NzNonCopyable
void PushBoolean(bool value);
void PushCFunction(NzLuaCFunction func, int upvalueCount = 0);
void PushFunction(NzLuaFunction func);
- void PushInteger(int value);
+ void PushInteger(long long value);
void PushLightUserdata(void* value);
void PushMetatable(const char* str);
void PushMetatable(const NzString& str);
@@ -118,7 +116,6 @@ class NAZARA_API NzLuaInstance : NzNonCopyable
void PushString(const char* str);
void PushString(const NzString& str);
void PushTable(unsigned int sequenceElementCount = 0, unsigned int arrayElementCount = 0);
- void PushUnsigned(unsigned int value);
void* PushUserdata(unsigned int size);
void PushValue(int index);
@@ -137,11 +134,10 @@ class NAZARA_API NzLuaInstance : NzNonCopyable
void SetTimeLimit(nzUInt32 timeLimit);
bool ToBoolean(int index) const;
- int ToInteger(int index, bool* succeeded = nullptr) const;
+ long long ToInteger(int index, bool* succeeded = nullptr) const;
double ToNumber(int index, bool* succeeded = nullptr) const;
const void* ToPointer(int index) const;
const char* ToString(int index, std::size_t* length = nullptr) const;
- unsigned int ToUnsigned(int index, bool* succeeded = nullptr) const;
void* ToUserdata(int index) const;
void* ToUserdata(int index, const char* tname) const;
void* ToUserdata(int index, const NzString& tname) const;
diff --git a/include/Nazara/Math/Algorithm.inl b/include/Nazara/Math/Algorithm.inl
index d935bbe07..efc371a4c 100644
--- a/include/Nazara/Math/Algorithm.inl
+++ b/include/Nazara/Math/Algorithm.inl
@@ -369,15 +369,15 @@ inline NzString NzNumberToString(long long number, nzUInt8 radix)
do
{
- str += symbols[number % radix];
+ str.Append(symbols[number % radix]);
number /= radix;
}
while (number > 0);
if (negative)
- str += '-';
+ str.Append('-');
- return str.Reversed();
+ return str.Reverse();
}
template
diff --git a/include/Nazara/Prerequesites.hpp b/include/Nazara/Prerequesites.hpp
index ac58d90ea..6bd2b68e7 100644
--- a/include/Nazara/Prerequesites.hpp
+++ b/include/Nazara/Prerequesites.hpp
@@ -143,7 +143,7 @@
// Détection 64 bits
#if !defined(NAZARA_PLATFORM_x64) && (defined(_WIN64) || defined(__amd64__) || defined(__x86_64__) || defined(__ia64__) || defined(__ia64) || \
- defined(_M_IA64) || defined(__itanium__) || defined(__MINGW64__))
+ defined(_M_IA64) || defined(__itanium__) || defined(__MINGW64__) || defined(_M_AMD64) || defined (_M_X64))
#define NAZARA_PLATFORM_x64
#endif
diff --git a/include/Nazara/Renderer/ConfigCheck.hpp b/include/Nazara/Renderer/ConfigCheck.hpp
index 3860a809b..a90e79785 100644
--- a/include/Nazara/Renderer/ConfigCheck.hpp
+++ b/include/Nazara/Renderer/ConfigCheck.hpp
@@ -10,7 +10,7 @@
/// Ce fichier sert à vérifier la valeur des constantes du fichier Config.hpp
#include
-#define CheckTypeAndVal(name, type, op, val, err) static_assert(std::is_ ##type ::value && name op val, #type err)
+#define NazaraCheckTypeAndVal(name, type, op, val, err) static_assert(std::is_ ##type ::value && name op val, #type err)
// On force la valeur de MANAGE_MEMORY en mode debug
#if defined(NAZARA_DEBUG) && !NAZARA_RENDERER_MANAGE_MEMORY
@@ -18,6 +18,8 @@
#define NAZARA_RENDERER_MANAGE_MEMORY 1
#endif
-CheckTypeAndVal(NAZARA_RENDERER_INSTANCE_BUFFER_SIZE, integral, >, 0, " shall be a strictly positive integer");
+NazaraCheckTypeAndVal(NAZARA_RENDERER_INSTANCE_BUFFER_SIZE, integral, >, 0, " shall be a strictly positive integer");
+
+#undef NazaraCheckTypeAndVal
#endif // NAZARA_CONFIG_CHECK_RENDERER_HPP
diff --git a/include/Nazara/Utility/ConfigCheck.hpp b/include/Nazara/Utility/ConfigCheck.hpp
index b4c976edc..0018b6e9d 100644
--- a/include/Nazara/Utility/ConfigCheck.hpp
+++ b/include/Nazara/Utility/ConfigCheck.hpp
@@ -10,7 +10,7 @@
/// Ce fichier sert à vérifier la valeur des constantes du fichier Config.hpp
#include
-#define CheckTypeAndVal(name, type, op, val, err) static_assert(std::is_ ##type ::value && name op val, #type err)
+#define NazaraCheckTypeAndVal(name, type, op, val, err) static_assert(std::is_ ##type ::value && name op val, #type err)
// On force la valeur de MANAGE_MEMORY en mode debug
#if defined(NAZARA_DEBUG) && !NAZARA_UTILITY_MANAGE_MEMORY
@@ -18,6 +18,8 @@
#define NAZARA_UTILITY_MANAGE_MEMORY 1
#endif
-CheckTypeAndVal(NAZARA_UTILITY_SKINNING_MAX_WEIGHTS, integral, >, 0, " shall be a strictly positive integer");
+NazaraCheckTypeAndVal(NAZARA_UTILITY_SKINNING_MAX_WEIGHTS, integral, >, 0, " shall be a strictly positive integer");
+
+#undef NazaraCheckTypeAndVal
#endif // NAZARA_CONFIG_CHECK_UTILITY_HPP
diff --git a/include/Nazara/Utility/Mesh.hpp b/include/Nazara/Utility/Mesh.hpp
index ff0f49cac..cf96790e7 100644
--- a/include/Nazara/Utility/Mesh.hpp
+++ b/include/Nazara/Utility/Mesh.hpp
@@ -48,7 +48,6 @@ struct NAZARA_API NzMeshParams
bool IsValid() const;
};
-class NzAnimation;
class NzMesh;
class NzPrimitiveList;
diff --git a/include/Nazara/Utility/PixelFormat.inl b/include/Nazara/Utility/PixelFormat.inl
index e399e408f..296bdc503 100644
--- a/include/Nazara/Utility/PixelFormat.inl
+++ b/include/Nazara/Utility/PixelFormat.inl
@@ -3,6 +3,7 @@
// For conditions of distribution and use, see copyright notice in Config.hpp
#include
+#include
#include
#include
diff --git a/src/Nazara/Audio/Loaders/sndfile/Loader.cpp b/src/Nazara/Audio/Loaders/sndfile/Loader.cpp
index d1b8be31f..140798a80 100644
--- a/src/Nazara/Audio/Loaders/sndfile/Loader.cpp
+++ b/src/Nazara/Audio/Loaders/sndfile/Loader.cpp
@@ -88,6 +88,7 @@ namespace
nzAudioFormat GetFormat() const
{
+ // Nous avons besoin du nombre de canaux d'origine pour convertir en mono, nous trichons donc un peu...
if (m_mixToMono)
return nzAudioFormat_Mono;
else
@@ -106,14 +107,16 @@ namespace
bool Open(const NzString& filePath, bool forceMono)
{
+ // Nous devons gérer nous-même le flux car il doit rester ouvert après le passage du loader
+ // (les flux automatiquement ouverts par le ResourceLoader étant fermés après celui-ci)
std::unique_ptr file(new NzFile);
if (!file->Open(filePath, NzFile::ReadOnly))
{
NazaraError("Failed to open stream from file: " + NzError::GetLastError());
return false;
}
- m_ownedStream = std::move(file);
+ m_ownedStream = std::move(file);
return Open(*m_ownedStream, forceMono);
}
@@ -126,7 +129,7 @@ namespace
bool Open(NzInputStream& stream, bool forceMono)
{
SF_INFO infos;
- infos.format = 0;
+ infos.format = 0; // Format inconnu
m_handle = sf_open_virtual(&callbacks, SFM_READ, &infos, &stream);
if (!m_handle)
@@ -135,6 +138,7 @@ namespace
return false;
}
+ // Un peu de RAII
NzCallOnExit onExit([this]
{
sf_close(m_handle);
@@ -151,6 +155,7 @@ namespace
m_sampleCount = infos.channels*infos.frames;
m_sampleRate = infos.samplerate;
+ // Durée de la musique (s) = samples / channels*rate
m_duration = 1000*m_sampleCount / (m_format*m_sampleRate);
// https://github.com/LaurentGomila/SFML/issues/271
@@ -159,6 +164,7 @@ namespace
if (infos.format & SF_FORMAT_VORBIS)
sf_command(m_handle, SFC_SET_SCALE_FLOAT_INT_READ, nullptr, SF_TRUE);
+ // On mixera en mono lors de la lecture
if (forceMono && m_format != nzAudioFormat_Mono)
{
m_mixToMono = true;
@@ -174,8 +180,10 @@ namespace
unsigned int Read(void* buffer, unsigned int sampleCount)
{
+ // Si la musique a été demandée en mono, nous devons la convertir à la volée lors de la lecture
if (m_mixToMono)
{
+ // On garde un buffer sur le côté pour éviter la réallocation
m_mixBuffer.resize(m_format*sampleCount);
unsigned int readSampleCount = sf_read_short(m_handle, m_mixBuffer.data(), m_format*sampleCount);
NzMixToMono(m_mixBuffer.data(), static_cast(buffer), m_format, sampleCount);
@@ -217,8 +225,9 @@ namespace
NazaraUnused(parameters);
SF_INFO info;
- info.format = 0;
+ info.format = 0; // Format inconnu
+ // Si on peut ouvrir le flux, c'est qu'il est dans un format compatible
SNDFILE* file = sf_open_virtual(&callbacks, SFM_READ, &info, &stream);
if (file)
{
@@ -231,8 +240,6 @@ namespace
bool LoadMusicFile(NzMusic* music, const NzString& filePath, const NzMusicParams& parameters)
{
- NazaraUnused(parameters);
-
std::unique_ptr musicStream(new sndfileStream);
if (!musicStream->Open(filePath, parameters.forceMono))
{
@@ -240,12 +247,13 @@ namespace
return false;
}
- if (!music->Create(musicStream.get()))
+ 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;
@@ -253,8 +261,6 @@ namespace
bool LoadMusicMemory(NzMusic* music, const void* data, std::size_t size, const NzMusicParams& parameters)
{
- NazaraUnused(parameters);
-
std::unique_ptr musicStream(new sndfileStream);
if (!musicStream->Open(data, size, parameters.forceMono))
{
@@ -262,12 +268,13 @@ namespace
return false;
}
- if (!music->Create(musicStream.get()))
+ 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;
@@ -275,8 +282,6 @@ namespace
bool LoadMusicStream(NzMusic* music, NzInputStream& stream, const NzMusicParams& parameters)
{
- NazaraUnused(parameters);
-
std::unique_ptr musicStream(new sndfileStream);
if (!musicStream->Open(stream, parameters.forceMono))
{
@@ -284,12 +289,13 @@ namespace
return false;
}
- if (!music->Create(musicStream.get()))
+ 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;
@@ -314,8 +320,6 @@ namespace
bool LoadSoundBuffer(NzSoundBuffer* soundBuffer, NzInputStream& stream, const NzSoundBufferParams& parameters)
{
- NazaraUnused(parameters);
-
SF_INFO info;
info.format = 0;
@@ -326,7 +330,13 @@ namespace
return false;
}
- NzCallOnExit onExit([file] { sf_close(file); });
+ // Lynix utilise RAII...
+ // C'est très efficace !
+ // MemoryLeak est confus...
+ NzCallOnExit onExit([file]
+ {
+ sf_close(file);
+ });
nzAudioFormat format = NzAudio::GetAudioFormat(info.channels);
if (format == nzAudioFormat_Unknown)
@@ -341,7 +351,7 @@ namespace
if (info.format & SF_FORMAT_VORBIS)
sf_command(file, SFC_SET_SCALE_FLOAT_INT_READ, nullptr, SF_TRUE);
- sf_count_t sampleCount = info.frames * info.channels;
+ unsigned int sampleCount = static_cast(info.frames * info.channels);
std::unique_ptr samples(new nzInt16[sampleCount]);
if (sf_read_short(file, samples.get(), sampleCount) != sampleCount)
@@ -350,17 +360,17 @@ namespace
return false;
}
+ // Une conversion en mono est-elle nécessaire ?
if (parameters.forceMono && format != nzAudioFormat_Mono)
{
- std::unique_ptr monoSamples(new nzInt16[info.frames]);
- NzMixToMono(samples.get(), monoSamples.get(), info.channels, info.frames);
+ // Nous effectuons la conversion en mono dans le même buffer (il va de toute façon être copié)
+ NzMixToMono(samples.get(), samples.get(), static_cast(info.channels), static_cast(info.frames));
format = nzAudioFormat_Mono;
- samples = std::move(monoSamples);
- sampleCount = info.frames;
+ sampleCount = static_cast(info.frames);
}
- if (!soundBuffer->Create(format, static_cast(sampleCount), info.samplerate, samples.get()))
+ if (!soundBuffer->Create(format, sampleCount, info.samplerate, samples.get()))
{
NazaraError("Failed to create sound buffer");
return false;
diff --git a/src/Nazara/Core/Error.cpp b/src/Nazara/Core/Error.cpp
index 42a297076..921fff968 100644
--- a/src/Nazara/Core/Error.cpp
+++ b/src/Nazara/Core/Error.cpp
@@ -17,7 +17,7 @@
void NzError::Error(nzErrorType type, const NzString& error)
{
- if ((s_flags & nzErrorFlag_Silent) == 0 || (s_flags & nzErrorFlag_SilentDisabled) != 0)
+ if (type == nzErrorType_AssertFailed || (s_flags & nzErrorFlag_Silent) == 0 || (s_flags & nzErrorFlag_SilentDisabled) != 0)
NazaraLog->WriteError(type, error);
s_lastError = error;
@@ -27,16 +27,17 @@ void NzError::Error(nzErrorType type, const NzString& error)
#if NAZARA_CORE_EXIT_ON_ASSERT_FAILURE
if (type == nzErrorType_AssertFailed)
- std::exit(EXIT_FAILURE);
+ std::abort();
#endif
- if (type != nzErrorType_Warning && (s_flags & nzErrorFlag_ThrowException) != 0 && (s_flags & nzErrorFlag_ThrowExceptionDisabled) == 0)
+ if (type == nzErrorType_AssertFailed || (type != nzErrorType_Warning &&
+ (s_flags & nzErrorFlag_ThrowException) != 0 && (s_flags & nzErrorFlag_ThrowExceptionDisabled) == 0))
throw std::runtime_error(error);
}
void NzError::Error(nzErrorType type, const NzString& error, unsigned int line, const char* file, const char* function)
{
- if ((s_flags & nzErrorFlag_Silent) == 0 || (s_flags & nzErrorFlag_SilentDisabled) != 0)
+ if (type == nzErrorType_AssertFailed || (s_flags & nzErrorFlag_Silent) == 0 || (s_flags & nzErrorFlag_SilentDisabled) != 0)
NazaraLog->WriteError(type, error, line, file, function);
s_lastError = error;
@@ -44,13 +45,14 @@ void NzError::Error(nzErrorType type, const NzString& error, unsigned int line,
s_lastErrorFunction = function;
s_lastErrorLine = line;
- if (type != nzErrorType_Warning && (s_flags & nzErrorFlag_ThrowException) != 0 && (s_flags & nzErrorFlag_ThrowExceptionDisabled) == 0)
- throw std::runtime_error(error);
-
#if NAZARA_CORE_EXIT_ON_ASSERT_FAILURE
if (type == nzErrorType_AssertFailed)
- std::exit(EXIT_FAILURE);
+ std::abort();
#endif
+
+ if (type == nzErrorType_AssertFailed || (type != nzErrorType_Warning &&
+ (s_flags & nzErrorFlag_ThrowException) != 0 && (s_flags & nzErrorFlag_ThrowExceptionDisabled) == 0))
+ throw std::runtime_error(error);
}
nzUInt32 NzError::GetFlags()
diff --git a/src/Nazara/Core/File.cpp b/src/Nazara/Core/File.cpp
index 6c38f30f7..1acee0122 100644
--- a/src/Nazara/Core/File.cpp
+++ b/src/Nazara/Core/File.cpp
@@ -733,7 +733,7 @@ bool NzFile::FillHash(NzAbstractHash* hash) const
unsigned int size;
while (remainingSize > 0)
{
- size = std::min(remainingSize, static_cast(NAZARA_CORE_FILE_BUFFERSIZE));
+ size = static_cast(std::min(remainingSize, static_cast(NAZARA_CORE_FILE_BUFFERSIZE)));
if (file.Read(&buffer[0], sizeof(char), size) != sizeof(char)*size)
{
NazaraError("Unable to read file");
diff --git a/src/Nazara/Core/GuillotineBinPack.cpp b/src/Nazara/Core/GuillotineBinPack.cpp
index 3127c4203..1d89515db 100644
--- a/src/Nazara/Core/GuillotineBinPack.cpp
+++ b/src/Nazara/Core/GuillotineBinPack.cpp
@@ -9,6 +9,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -22,8 +23,8 @@ namespace
int ScoreBestLongSideFit(int width, int height, const NzRectui& freeRectSize)
{
- int leftoverHoriz = std::abs(freeRectSize.width - width);
- int leftoverVert = std::abs(freeRectSize.height - height);
+ int leftoverHoriz = std::abs(static_cast(freeRectSize.width - width));
+ int leftoverVert = std::abs(static_cast(freeRectSize.height - height));
int leftover = std::max(leftoverHoriz, leftoverVert);
return leftover;
@@ -31,8 +32,8 @@ namespace
int ScoreBestShortSideFit(int width, int height, const NzRectui& freeRectSize)
{
- int leftoverHoriz = std::abs(freeRectSize.width - width);
- int leftoverVert = std::abs(freeRectSize.height - height);
+ int leftoverHoriz = std::abs(static_cast(freeRectSize.width - width));
+ int leftoverVert = std::abs(static_cast(freeRectSize.height - height));
int leftover = std::min(leftoverHoriz, leftoverVert);
return leftover;
diff --git a/src/Nazara/Core/HardwareInfo.cpp b/src/Nazara/Core/HardwareInfo.cpp
index 6bc12835a..762012b8f 100644
--- a/src/Nazara/Core/HardwareInfo.cpp
+++ b/src/Nazara/Core/HardwareInfo.cpp
@@ -4,6 +4,7 @@
#include
#include
+#include
#include
#include
@@ -77,7 +78,11 @@ namespace
bool s_initialized = false;
char s_brandString[48] = "Not initialized";
- char s_vendor[12] = {'C', 'P', 'U', 'i', 's', 'U', 'n', 'k', 'n', 'o', 'w', 'n'};
+}
+
+void NzHardwareInfo::Cpuid(nzUInt32 functionId, nzUInt32 subFunctionId, nzUInt32 result[4])
+{
+ return NzHardwareInfoImpl::Cpuid(functionId, subFunctionId, result);
}
NzString NzHardwareInfo::GetProcessorBrandString()
@@ -137,67 +142,86 @@ bool NzHardwareInfo::Initialize()
s_initialized = true;
- nzUInt32 result[4];
+ nzUInt32 registers[4]; // Récupère les quatre registres (EAX, EBX, ECX et EDX)
- NzHardwareInfoImpl::Cpuid(0, result);
- std::memcpy(&s_vendor[0], &result[1], 4);
- std::memcpy(&s_vendor[4], &result[3], 4);
- std::memcpy(&s_vendor[8], &result[2], 4);
+ // Pour plus de clarté
+ nzUInt32& eax = registers[0];
+ nzUInt32& ebx = registers[1];
+ nzUInt32& ecx = registers[2];
+ nzUInt32& edx = registers[3];
+
+ // Pour commencer, on va récupérer l'identifiant du constructeur ainsi que l'id de fonction maximal supporté par le CPUID
+ NzHardwareInfoImpl::Cpuid(0, 0, registers);
+
+ // Attention à l'ordre : EBX, EDX, ECX
+ nzUInt32 manufacturerId[3] = {ebx, edx, ecx};
// Identification du concepteur
s_vendorEnum = nzProcessorVendor_Unknown;
for (const VendorString& vendorString : vendorStrings)
{
- if (std::memcmp(s_vendor, vendorString.vendor, 12) == 0)
+ if (std::memcmp(manufacturerId, vendorString.vendor, 12) == 0)
{
s_vendorEnum = vendorString.vendorEnum;
break;
}
}
- unsigned int ids = result[0];
-
- if (ids >= 1)
+ if (eax >= 1)
{
- NzHardwareInfoImpl::Cpuid(1, result);
- s_capabilities[nzProcessorCap_AVX] = (result[2] & (1U << 28)) != 0;
- s_capabilities[nzProcessorCap_FMA3] = (result[2] & (1U << 12)) != 0;
- s_capabilities[nzProcessorCap_MMX] = (result[3] & (1U << 23)) != 0;
- s_capabilities[nzProcessorCap_SSE] = (result[3] & (1U << 25)) != 0;
- s_capabilities[nzProcessorCap_SSE2] = (result[3] & (1U << 26)) != 0;
- s_capabilities[nzProcessorCap_SSE3] = (result[2] & (1U << 0)) != 0;
- s_capabilities[nzProcessorCap_SSSE3] = (result[2] & (1U << 9)) != 0;
- s_capabilities[nzProcessorCap_SSE41] = (result[2] & (1U << 19)) != 0;
- s_capabilities[nzProcessorCap_SSE42] = (result[2] & (1U << 20)) != 0;
+ // Récupération de certaines capacités du processeur (ECX et EDX, fonction 1)
+ NzHardwareInfoImpl::Cpuid(1, 0, registers);
- NzHardwareInfoImpl::Cpuid(0x80000000, result);
- unsigned int exIds = result[0];
+ s_capabilities[nzProcessorCap_AVX] = (ecx & (1U << 28)) != 0;
+ s_capabilities[nzProcessorCap_FMA3] = (ecx & (1U << 12)) != 0;
+ s_capabilities[nzProcessorCap_MMX] = (edx & (1U << 23)) != 0;
+ s_capabilities[nzProcessorCap_SSE] = (edx & (1U << 25)) != 0;
+ s_capabilities[nzProcessorCap_SSE2] = (edx & (1U << 26)) != 0;
+ s_capabilities[nzProcessorCap_SSE3] = (ecx & (1U << 0)) != 0;
+ s_capabilities[nzProcessorCap_SSSE3] = (ecx & (1U << 9)) != 0;
+ s_capabilities[nzProcessorCap_SSE41] = (ecx & (1U << 19)) != 0;
+ s_capabilities[nzProcessorCap_SSE42] = (ecx & (1U << 20)) != 0;
+ }
- if (exIds >= 0x80000001)
+ // Récupération de la plus grande fonction étendue supportée (EAX, fonction 0x80000000)
+ NzHardwareInfoImpl::Cpuid(0x80000000, 0, registers);
+
+ nzUInt32 maxSupportedExtendedFunction = eax;
+ if (maxSupportedExtendedFunction >= 0x80000001)
+ {
+ // Récupération des capacités étendues du processeur (ECX et EDX, fonction 0x80000001)
+ NzHardwareInfoImpl::Cpuid(0x80000001, 0, registers);
+
+ s_capabilities[nzProcessorCap_x64] = (edx & (1U << 29)) != 0; // Support du 64bits, indépendant de l'OS
+ s_capabilities[nzProcessorCap_FMA4] = (ecx & (1U << 16)) != 0;
+ s_capabilities[nzProcessorCap_SSE4a] = (ecx & (1U << 6)) != 0;
+ s_capabilities[nzProcessorCap_XOP] = (ecx & (1U << 11)) != 0;
+
+ if (maxSupportedExtendedFunction >= 0x80000004)
{
- NzHardwareInfoImpl::Cpuid(0x80000001, result);
- s_capabilities[nzProcessorCap_x64] = (result[3] & (1U << 29)) != 0;
- s_capabilities[nzProcessorCap_FMA4] = (result[2] & (1U << 16)) != 0;
- s_capabilities[nzProcessorCap_SSE4a] = (result[2] & (1U << 6)) != 0;
- s_capabilities[nzProcessorCap_XOP] = (result[2] & (1U << 11)) != 0;
-
- if (exIds >= 0x80000004)
+ // Récupération d'une chaîne de caractère décrivant le processeur (EAX, EBX, ECX et EDX,
+ // fonctions de 0x80000002 à 0x80000004 compris)
+ char* ptr = &s_brandString[0];
+ for (nzUInt32 code = 0x80000002; code <= 0x80000004; ++code)
{
- char* ptr = &s_brandString[0];
- for (nzUInt32 code = 0x80000002; code <= 0x80000004; ++code)
- {
- NzHardwareInfoImpl::Cpuid(code, result);
- std::memcpy(ptr, &result[0], 16);
+ NzHardwareInfoImpl::Cpuid(code, 0, registers);
+ std::memcpy(ptr, ®isters[0], 4*sizeof(nzUInt32)); // On rajoute les 16 octets à la chaîne
- ptr += 16;
- }
+ ptr += 4*sizeof(nzUInt32);
}
+
+ // Le caractère nul faisant partie de la chaîne retournée par le CPUID, pas besoin de le rajouter
}
}
return true;
}
+bool NzHardwareInfo::IsCpuidSupported()
+{
+ return NzHardwareInfoImpl::IsCpuidSupported();
+}
+
bool NzHardwareInfo::IsInitialized()
{
return s_initialized;
diff --git a/src/Nazara/Core/HashDigest.cpp b/src/Nazara/Core/HashDigest.cpp
index aeba77415..62baac0aa 100644
--- a/src/Nazara/Core/HashDigest.cpp
+++ b/src/Nazara/Core/HashDigest.cpp
@@ -5,9 +5,9 @@
#include
#include
#include
+#include
#include
#include
-#include
#include
NzHashDigest::NzHashDigest() :
diff --git a/src/Nazara/Core/ParameterList.cpp b/src/Nazara/Core/ParameterList.cpp
index 5b6e74b93..746f70ce6 100644
--- a/src/Nazara/Core/ParameterList.cpp
+++ b/src/Nazara/Core/ParameterList.cpp
@@ -91,7 +91,7 @@ bool NzParameterList::GetFloatParameter(const NzString& name, float* value) cons
return true;
case nzParameterType_Integer:
- *value = it->second.value.intVal;
+ *value = static_cast(it->second.value.intVal);
return true;
case nzParameterType_String:
@@ -99,7 +99,7 @@ bool NzParameterList::GetFloatParameter(const NzString& name, float* value) cons
double converted;
if (it->second.value.stringVal.ToDouble(&converted))
{
- *value = converted;
+ *value = static_cast(converted);
return true;
}
@@ -133,7 +133,7 @@ bool NzParameterList::GetIntegerParameter(const NzString& name, int* value) cons
return true;
case nzParameterType_Float:
- *value = it->second.value.floatVal;
+ *value = static_cast(it->second.value.floatVal);
return true;
case nzParameterType_Integer:
@@ -147,7 +147,7 @@ bool NzParameterList::GetIntegerParameter(const NzString& name, int* value) cons
{
if (converted <= std::numeric_limits::max() && converted >= std::numeric_limits::min())
{
- *value = converted;
+ *value = static_cast(converted);
return true;
}
}
diff --git a/src/Nazara/Core/Posix/MutexImpl.hpp b/src/Nazara/Core/Posix/MutexImpl.hpp
index 00c0d7432..ff1d0455f 100644
--- a/src/Nazara/Core/Posix/MutexImpl.hpp
+++ b/src/Nazara/Core/Posix/MutexImpl.hpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2014 Alexandre Janniaux
+// Copyright (C) 2015 Alexandre Janniaux
// This file is part of the "Nazara Engine - Core module"
// For conditions of distribution and use, see copyright notice in Config.hpp
diff --git a/src/Nazara/Core/String.cpp b/src/Nazara/Core/String.cpp
index 1b9fac697..d2ba08601 100644
--- a/src/Nazara/Core/String.cpp
+++ b/src/Nazara/Core/String.cpp
@@ -1776,96 +1776,63 @@ unsigned int NzString::GetSize() const
return m_sharedString->size;
}
-char* NzString::GetUtf8Buffer(unsigned int* size) const
+std::string NzString::GetUtf8String() const
{
- if (m_sharedString->size == 0)
- return nullptr;
-
- char* buffer = new char[m_sharedString->size+1];
- std::memcpy(buffer, m_sharedString->string, m_sharedString->size+1);
-
- if (size)
- *size = m_sharedString->size;
-
- return buffer;
+ return std::string(m_sharedString->string, m_sharedString->size);
}
-char16_t* NzString::GetUtf16Buffer(unsigned int* size) const
+std::u16string NzString::GetUtf16String() const
{
if (m_sharedString->size == 0)
- return nullptr;
+ return std::u16string();
- std::vector utf16;
- utf16.reserve(m_sharedString->size);
+ std::u16string str;
+ str.reserve(m_sharedString->size);
- utf8::utf8to16(m_sharedString->string, &m_sharedString->string[m_sharedString->size], std::back_inserter(utf16));
+ utf8::utf8to16(begin(), end(), std::back_inserter(str));
- unsigned int bufferSize = utf16.size();
- if (bufferSize == 0)
- return nullptr;
-
- char16_t* buffer = new char16_t[bufferSize+1];
- std::memcpy(buffer, &utf16[0], bufferSize*sizeof(char16_t));
- buffer[bufferSize] ='\0';
-
- if (size)
- *size = bufferSize;
-
- return buffer;
+ return str;
}
-char32_t* NzString::GetUtf32Buffer(unsigned int* size) const
+std::u32string NzString::GetUtf32String() const
{
if (m_sharedString->size == 0)
- return nullptr;
+ return std::u32string();
- unsigned int bufferSize = utf8::distance(m_sharedString->string, &m_sharedString->string[m_sharedString->size]);
- if (bufferSize == 0)
- return nullptr;
+ std::u32string str;
+ str.reserve(m_sharedString->size);
- char32_t* buffer = new char32_t[bufferSize+1];
- utf8::utf8to32(m_sharedString->string, &m_sharedString->string[m_sharedString->size], buffer);
- buffer[bufferSize] ='\0';
+ utf8::utf8to32(begin(), end(), std::back_inserter(str));
- if (size)
- *size = bufferSize;
-
- return buffer;
+ return str;
}
-wchar_t* NzString::GetWideBuffer(unsigned int* size) const
+std::wstring NzString::GetWideString() const
{
static_assert(sizeof(wchar_t) == 2 || sizeof(wchar_t) == 4, "wchar_t size is not supported");
if (m_sharedString->size == 0)
- return nullptr;
+ return std::wstring();
- unsigned int bufferSize = utf8::distance(m_sharedString->string, &m_sharedString->string[m_sharedString->size]);
- if (bufferSize == 0)
- return nullptr;
+ std::wstring str;
+ str.reserve(m_sharedString->size);
- wchar_t* buffer = new wchar_t[bufferSize+1];
if (sizeof(wchar_t) == 4) // Je veux du static_if :(
- utf8::utf8to32(m_sharedString->string, &m_sharedString->string[m_sharedString->size], buffer);
+ utf8::utf8to32(begin(), end(), std::back_inserter(str));
else
{
- wchar_t* ptr = buffer;
-
utf8::unchecked::iterator it(m_sharedString->string);
do
{
char32_t cp = *it;
if (cp <= 0xFFFF && (cp < 0xD800 || cp > 0xDFFF)) // @Laurent Gomila
- *ptr++ = static_cast(cp);
+ str.push_back(static_cast(cp));
else
- *ptr++ = L'?';
+ str.push_back(L'?');
}
while (*it++);
}
- if (size)
- *size = bufferSize;
-
- return buffer;
+ return str;
}
NzString NzString::GetWord(unsigned int index, nzUInt32 flags) const
@@ -3162,7 +3129,7 @@ NzString NzString::SubStringFrom(char character, int startPos, bool fromLast, bo
else
pos = Find(character, startPos, flags);
- if (pos == 0 and include)
+ if (pos == 0 && include)
return *this;
else if (pos == npos)
return NzString();
diff --git a/src/Nazara/Core/Thread.cpp b/src/Nazara/Core/Thread.cpp
index 47d7d102d..a25a6546e 100644
--- a/src/Nazara/Core/Thread.cpp
+++ b/src/Nazara/Core/Thread.cpp
@@ -6,6 +6,7 @@
#include
#include
#include
+#include
#include
#if defined(NAZARA_PLATFORM_WINDOWS)
diff --git a/src/Nazara/Core/Win32/DirectoryImpl.cpp b/src/Nazara/Core/Win32/DirectoryImpl.cpp
index f48a0c7f4..c0f97ab2b 100644
--- a/src/Nazara/Core/Win32/DirectoryImpl.cpp
+++ b/src/Nazara/Core/Win32/DirectoryImpl.cpp
@@ -62,9 +62,7 @@ bool NzDirectoryImpl::Open(const NzString& dirPath)
{
NzString searchPath = dirPath + "\\*";
- std::unique_ptr wPath(searchPath.GetWideBuffer());
- m_handle = FindFirstFileW(wPath.get(), &m_result);
-
+ m_handle = FindFirstFileW(searchPath.GetWideString().data(), &m_result);
if (m_handle == INVALID_HANDLE_VALUE)
{
NazaraError("Unable to open directory: " + NzError::GetLastSystemError());
@@ -78,16 +76,12 @@ bool NzDirectoryImpl::Open(const NzString& dirPath)
bool NzDirectoryImpl::Create(const NzString& dirPath)
{
- std::unique_ptr wPath(dirPath.GetWideBuffer());
-
- return (CreateDirectoryW(wPath.get(), nullptr) != 0) || GetLastError() == ERROR_ALREADY_EXISTS;
+ return (CreateDirectoryW(dirPath.GetWideString().data(), nullptr) != 0) || GetLastError() == ERROR_ALREADY_EXISTS;
}
bool NzDirectoryImpl::Exists(const NzString& dirPath)
{
- std::unique_ptr wPath(dirPath.GetWideBuffer());
- DWORD attributes = GetFileAttributesW(wPath.get());
-
+ DWORD attributes = GetFileAttributesW(dirPath.GetWideString().data());
if (attributes != INVALID_FILE_ATTRIBUTES)
return (attributes & FILE_ATTRIBUTE_DIRECTORY) != 0;
else
@@ -118,8 +112,7 @@ NzString NzDirectoryImpl::GetCurrent()
bool NzDirectoryImpl::Remove(const NzString& dirPath)
{
- std::unique_ptr path(dirPath.GetWideBuffer());
- bool success = RemoveDirectoryW(path.get()) != 0;
+ bool success = RemoveDirectoryW(dirPath.GetWideString().data()) != 0;
DWORD error = GetLastError();
return success || error == ERROR_FILE_NOT_FOUND || error == ERROR_PATH_NOT_FOUND;
diff --git a/src/Nazara/Core/Win32/DynLibImpl.cpp b/src/Nazara/Core/Win32/DynLibImpl.cpp
index b10ae8a38..d1afe2c05 100644
--- a/src/Nazara/Core/Win32/DynLibImpl.cpp
+++ b/src/Nazara/Core/Win32/DynLibImpl.cpp
@@ -30,9 +30,7 @@ bool NzDynLibImpl::Load(const NzString& libraryPath, NzString* errorMessage)
if (!path.EndsWith(".dll"))
path += ".dll";
- std::unique_ptr wPath(path.GetWideBuffer());
- m_handle = LoadLibraryExW(wPath.get(), nullptr, (NzFile::IsAbsolute(path)) ? LOAD_WITH_ALTERED_SEARCH_PATH : 0);
-
+ m_handle = LoadLibraryExW(path.GetWideString().data(), nullptr, (NzFile::IsAbsolute(path)) ? LOAD_WITH_ALTERED_SEARCH_PATH : 0);
if (m_handle)
return true;
else
diff --git a/src/Nazara/Core/Win32/FileImpl.cpp b/src/Nazara/Core/Win32/FileImpl.cpp
index 455c99e18..4ba16d90a 100644
--- a/src/Nazara/Core/Win32/FileImpl.cpp
+++ b/src/Nazara/Core/Win32/FileImpl.cpp
@@ -92,9 +92,7 @@ bool NzFileImpl::Open(const NzString& filePath, unsigned int mode)
if ((mode & NzFile::Lock) == 0)
shareMode |= FILE_SHARE_WRITE;
- std::unique_ptr path(filePath.GetWideBuffer());
- m_handle = CreateFileW(path.get(), access, shareMode, nullptr, openMode, 0, nullptr);
-
+ m_handle = CreateFileW(filePath.GetWideString().data(), access, shareMode, nullptr, openMode, 0, nullptr);
return m_handle != INVALID_HANDLE_VALUE;
}
@@ -184,117 +182,96 @@ std::size_t NzFileImpl::Write(const void* buffer, std::size_t size)
bool NzFileImpl::Copy(const NzString& sourcePath, const NzString& targetPath)
{
- std::unique_ptr srcPath(sourcePath.GetWideBuffer());
- std::unique_ptr dstPath(targetPath.GetWideBuffer());
-
- if (CopyFileW(srcPath.get(), dstPath.get(), false))
+ if (CopyFileW(sourcePath.GetWideString().data(), targetPath.GetWideString().data(), false))
return true;
else
{
NazaraError("Failed to copy file: " + NzError::GetLastSystemError());
-
return false;
}
}
bool NzFileImpl::Delete(const NzString& filePath)
{
- std::unique_ptr path(filePath.GetWideBuffer());
-
- if (DeleteFileW(path.get()))
+ if (DeleteFileW(filePath.GetWideString().data()))
return true;
else
{
NazaraError("Failed to delete file (" + filePath + "): " + NzError::GetLastSystemError());
-
return false;
}
}
bool NzFileImpl::Exists(const NzString& filePath)
{
- std::unique_ptr path(filePath.GetWideBuffer());
- HANDLE handle = CreateFileW(path.get(), 0, FILE_SHARE_READ | FILE_SHARE_WRITE, nullptr, OPEN_EXISTING, 0, nullptr);
-
+ HANDLE handle = CreateFileW(filePath.GetWideString().data(), 0, FILE_SHARE_READ | FILE_SHARE_WRITE, nullptr, OPEN_EXISTING, 0, nullptr);
if (handle == INVALID_HANDLE_VALUE)
return false;
CloseHandle(handle);
-
return true;
}
time_t NzFileImpl::GetCreationTime(const NzString& filePath)
{
- std::unique_ptr path(filePath.GetWideBuffer());
- HANDLE handle = CreateFileW(path.get(), 0, FILE_SHARE_READ | FILE_SHARE_WRITE, nullptr, OPEN_EXISTING, 0, nullptr);
-
+ HANDLE handle = CreateFileW(filePath.GetWideString().data(), 0, FILE_SHARE_READ | FILE_SHARE_WRITE, nullptr, OPEN_EXISTING, 0, nullptr);
if (handle == INVALID_HANDLE_VALUE)
return 0;
FILETIME creationTime;
if (!GetFileTime(handle, &creationTime, nullptr, nullptr))
{
- NazaraError("Unable to get creation time: " + NzError::GetLastSystemError());
-
CloseHandle(handle);
+
+ NazaraError("Unable to get creation time: " + NzError::GetLastSystemError());
return 0;
}
CloseHandle(handle);
-
return NzFileTimeToTime(&creationTime);
}
time_t NzFileImpl::GetLastAccessTime(const NzString& filePath)
{
- std::unique_ptr path(filePath.GetWideBuffer());
- HANDLE handle = CreateFileW(path.get(), 0, FILE_SHARE_READ, nullptr, OPEN_EXISTING, 0, nullptr);
-
+ HANDLE handle = CreateFileW(filePath.GetWideString().data(), 0, FILE_SHARE_READ, nullptr, OPEN_EXISTING, 0, nullptr);
if (handle == INVALID_HANDLE_VALUE)
return 0;
FILETIME accessTime;
if (!GetFileTime(handle, nullptr, &accessTime, nullptr))
{
- NazaraError("Unable to get last access time: " + NzError::GetLastSystemError());
-
CloseHandle(handle);
+
+ NazaraError("Unable to get last access time: " + NzError::GetLastSystemError());
return 0;
}
CloseHandle(handle);
-
return NzFileTimeToTime(&accessTime);
}
time_t NzFileImpl::GetLastWriteTime(const NzString& filePath)
{
- std::unique_ptr path(filePath.GetWideBuffer());
- HANDLE handle = CreateFileW(path.get(), 0, FILE_SHARE_READ, nullptr, OPEN_EXISTING, 0, nullptr);
-
+ HANDLE handle = CreateFileW(filePath.GetWideString().data(), 0, FILE_SHARE_READ, nullptr, OPEN_EXISTING, 0, nullptr);
if (handle == INVALID_HANDLE_VALUE)
return 0;
FILETIME writeTime;
if (!GetFileTime(handle, nullptr, nullptr, &writeTime))
{
- NazaraError("Unable to get last write time: " + NzError::GetLastSystemError());
CloseHandle(handle);
+ NazaraError("Unable to get last write time: " + NzError::GetLastSystemError());
return 0;
}
CloseHandle(handle);
-
return NzFileTimeToTime(&writeTime);
}
nzUInt64 NzFileImpl::GetSize(const NzString& filePath)
{
- std::unique_ptr path(filePath.GetWideBuffer());
- HANDLE handle = CreateFileW(path.get(), 0, FILE_SHARE_READ, nullptr, OPEN_EXISTING, 0, nullptr);
-
+ HANDLE handle = CreateFileW(filePath.GetWideString().data(), 0, FILE_SHARE_READ, nullptr, OPEN_EXISTING, 0, nullptr);
if (handle == INVALID_HANDLE_VALUE)
return 0;
@@ -303,16 +280,12 @@ nzUInt64 NzFileImpl::GetSize(const NzString& filePath)
fileSize.QuadPart = 0;
CloseHandle(handle);
-
return fileSize.QuadPart;
}
bool NzFileImpl::Rename(const NzString& sourcePath, const NzString& targetPath)
{
- std::unique_ptr srcPath(sourcePath.GetWideBuffer());
- std::unique_ptr dstPath(targetPath.GetWideBuffer());
-
- if (MoveFileExW(srcPath.get(), dstPath.get(), MOVEFILE_COPY_ALLOWED))
+ if (MoveFileExW(sourcePath.GetWideString().data(), targetPath.GetWideString().data(), MOVEFILE_COPY_ALLOWED))
return true;
else
{
diff --git a/src/Nazara/Core/Win32/HardwareInfoImpl.cpp b/src/Nazara/Core/Win32/HardwareInfoImpl.cpp
index 4fb664aca..9eb37c232 100644
--- a/src/Nazara/Core/Win32/HardwareInfoImpl.cpp
+++ b/src/Nazara/Core/Win32/HardwareInfoImpl.cpp
@@ -12,15 +12,18 @@
#include
-void NzHardwareInfoImpl::Cpuid(nzUInt32 code, nzUInt32 result[4])
+void NzHardwareInfoImpl::Cpuid(nzUInt32 functionId, nzUInt32 subFunctionId, nzUInt32 registers[4])
{
#if defined(NAZARA_COMPILER_MSVC)
- __cpuid(reinterpret_cast(result), static_cast(code)); // Visual propose une fonction intrinsèque pour le cpuid
+ static_assert(sizeof(nzUInt32) == sizeof(int), "Assertion failed");
+
+ // Visual propose une fonction intrinsèque pour le cpuid
+ __cpuidex(reinterpret_cast(registers), static_cast(functionId), static_cast(subFunctionId));
#elif defined(NAZARA_COMPILER_CLANG) || defined(NAZARA_COMPILER_GCC) || defined(NAZARA_COMPILER_INTEL)
// Source: http://stackoverflow.com/questions/1666093/cpuid-implementations-in-c
asm volatile ("cpuid" // Besoin d'être volatile ?
- : "=a" (result[0]), "=b" (result[1]), "=c" (result[2]), "=d" (result[3]) // output
- : "a" (code), "c" (0)); // input
+ : "=a" (registers[0]), "=b" (registers[1]), "=c" (registers[2]), "=d" (registers[3]) // output
+ : "a" (functionId), "c" (subFunctionId)); // input
#else
NazaraInternalError("Cpuid has been called although it is not supported");
#endif
@@ -37,10 +40,10 @@ unsigned int NzHardwareInfoImpl::GetProcessorCount()
bool NzHardwareInfoImpl::IsCpuidSupported()
{
-#if defined(NAZARA_COMPILER_MSVC)
- #ifdef NAZARA_PLATFORM_x64
+#ifdef NAZARA_PLATFORM_x64
return true; // Toujours supporté sur un processeur 64 bits
- #else
+#else
+ #if defined(NAZARA_COMPILER_MSVC)
int supported;
__asm
{
@@ -59,31 +62,27 @@ bool NzHardwareInfoImpl::IsCpuidSupported()
};
return supported != 0;
- #endif // NAZARA_PLATFORM_x64
-#elif defined(NAZARA_COMPILER_CLANG) || defined(NAZARA_COMPILER_GCC) || defined(NAZARA_COMPILER_INTEL)
- #ifdef NAZARA_PLATFORM_x64
- return true; // Toujours supporté sur un processeur 64 bits
- #else
+ #elif defined(NAZARA_COMPILER_CLANG) || defined(NAZARA_COMPILER_GCC) || defined(NAZARA_COMPILER_INTEL)
int supported;
- asm volatile (" pushfl\n"
- " pop %%eax\n"
- " mov %%eax, %%ecx\n"
- " xor $0x200000, %%eax\n"
- " push %%eax\n"
- " popfl\n"
- " pushfl\n"
- " pop %%eax\n"
- " xor %%ecx, %%eax\n"
- " mov %%eax, %0\n"
- " push %%ecx\n"
- " popfl"
- : "=m" (supported) // output
- : // input
- : "eax", "ecx", "memory"); // clobbered register
+ asm volatile (" pushfl\n"
+ " pop %%eax\n"
+ " mov %%eax, %%ecx\n"
+ " xor $0x200000, %%eax\n"
+ " push %%eax\n"
+ " popfl\n"
+ " pushfl\n"
+ " pop %%eax\n"
+ " xor %%ecx, %%eax\n"
+ " mov %%eax, %0\n"
+ " push %%ecx\n"
+ " popfl"
+ : "=m" (supported) // output
+ : // input
+ : "eax", "ecx", "memory"); // clobbered register
return supported != 0;
- #endif // NAZARA_PLATFORM_x64
-#else
+ #else
return false;
+ #endif
#endif
}
diff --git a/src/Nazara/Core/Win32/HardwareInfoImpl.hpp b/src/Nazara/Core/Win32/HardwareInfoImpl.hpp
index cd8f4264a..df8d9a5d7 100644
--- a/src/Nazara/Core/Win32/HardwareInfoImpl.hpp
+++ b/src/Nazara/Core/Win32/HardwareInfoImpl.hpp
@@ -12,7 +12,7 @@
class NzHardwareInfoImpl
{
public:
- static void Cpuid(nzUInt32 code, nzUInt32 result[4]);
+ static void Cpuid(nzUInt32 functionId, nzUInt32 subFunctionId, nzUInt32 registers[4]);
static unsigned int GetProcessorCount();
static bool IsCpuidSupported();
};
diff --git a/src/Nazara/Graphics/DeferredGeometryPass.cpp b/src/Nazara/Graphics/DeferredGeometryPass.cpp
index 4600213b3..61f0d922a 100644
--- a/src/Nazara/Graphics/DeferredGeometryPass.cpp
+++ b/src/Nazara/Graphics/DeferredGeometryPass.cpp
@@ -177,7 +177,7 @@ bool NzDeferredGeometryPass::Resize(const NzVector2ui& dimensions)
/*
G-Buffer:
Texture0: Diffuse Color + Flags
- Texture1: Normal map + Depth
+ Texture1: Encoded normal
Texture2: Specular value + Shininess
Texture3: N/A
*/
diff --git a/src/Nazara/Graphics/Loaders/OBJ/Loader.cpp b/src/Nazara/Graphics/Loaders/OBJ/Loader.cpp
index bab3cc8dc..190517f72 100644
--- a/src/Nazara/Graphics/Loaders/OBJ/Loader.cpp
+++ b/src/Nazara/Graphics/Loaders/OBJ/Loader.cpp
@@ -3,6 +3,8 @@
// For conditions of distribution and use, see copyright notice in Config.hpp
#include
+#include
+#include
#include
#include
#include
@@ -16,6 +18,8 @@
#include
#include
+///TODO: N'avoir qu'un seul VertexBuffer communs à tous les meshes
+
namespace
{
bool IsSupported(const NzString& extension)
@@ -31,10 +35,97 @@ namespace
return nzTernary_Unknown;
}
+ bool LoadMaterials(NzModel* model, const NzString& filePath, const NzMaterialParams& parameters, const NzString* materials, const NzOBJParser::Mesh* meshes, unsigned int meshCount)
+ {
+ NzFile file(filePath);
+ if (!file.Open(NzFile::ReadOnly | NzFile::Text))
+ {
+ NazaraError("Failed to open MTL file (" + file.GetPath() + ')');
+ return false;
+ }
+
+ NzMTLParser materialParser(file);
+ if (!materialParser.Parse())
+ {
+ NazaraError("MTL parser failed");
+ return false;
+ }
+
+ std::unordered_map materialCache;
+ NzString baseDir = file.GetDirectory();
+ for (unsigned int i = 0; i < meshCount; ++i)
+ {
+ const NzString& matName = materials[meshes[i].material];
+ const NzMTLParser::Material* mtlMat = materialParser.GetMaterial(matName);
+ if (!mtlMat)
+ {
+ NazaraWarning("MTL has no material \"" + matName + '"');
+ continue;
+ }
+
+ auto it = materialCache.find(matName);
+ if (it == materialCache.end())
+ {
+ NzMaterialRef material = NzMaterial::New();
+ material->SetShader(parameters.shaderName);
+
+ nzUInt8 alphaValue = static_cast(mtlMat->alpha*255.f);
+
+ NzColor ambientColor(mtlMat->ambient);
+ NzColor diffuseColor(mtlMat->diffuse);
+ NzColor specularColor(mtlMat->specular);
+ ambientColor.a = alphaValue;
+ diffuseColor.a = alphaValue;
+ specularColor.a = alphaValue;
+
+ material->SetAmbientColor(ambientColor);
+ material->SetDiffuseColor(diffuseColor);
+ material->SetSpecularColor(specularColor);
+ material->SetShininess(mtlMat->shininess);
+
+ bool isTranslucent = (alphaValue != 255);
+
+ if (parameters.loadAlphaMap && !mtlMat->alphaMap.IsEmpty())
+ {
+ if (material->SetAlphaMap(baseDir + mtlMat->alphaMap))
+ isTranslucent = true; // Une alpha map indique de la transparence
+ else
+ NazaraWarning("Failed to load alpha map (" + mtlMat->alphaMap + ')');
+ }
+
+ if (parameters.loadDiffuseMap && !mtlMat->diffuseMap.IsEmpty())
+ {
+ if (!material->SetDiffuseMap(baseDir + mtlMat->diffuseMap))
+ NazaraWarning("Failed to load diffuse map (" + mtlMat->diffuseMap + ')');
+ }
+
+ if (parameters.loadSpecularMap && !mtlMat->specularMap.IsEmpty())
+ {
+ if (!material->SetSpecularMap(baseDir + mtlMat->specularMap))
+ NazaraWarning("Failed to load specular map (" + mtlMat->specularMap + ')');
+ }
+
+ // Si nous avons une alpha map ou des couleurs transparentes,
+ // nous devons configurer le matériau pour accepter la transparence au mieux
+ if (isTranslucent)
+ {
+ // On paramètre le matériau pour accepter la transparence au mieux
+ material->Enable(nzRendererParameter_Blend, true);
+ material->Enable(nzRendererParameter_DepthWrite, false);
+ material->SetDstBlend(nzBlendFunc_InvSrcAlpha);
+ material->SetSrcBlend(nzBlendFunc_SrcAlpha);
+ }
+
+ it = materialCache.emplace(matName, std::move(material)).first;
+ }
+
+ model->SetMaterial(meshes[i].material, it->second);
+ }
+ }
+
bool Load(NzModel* model, NzInputStream& stream, const NzModelParameters& parameters)
{
NzOBJParser parser(stream);
-
if (!parser.Parse())
{
NazaraError("OBJ parser failed");
@@ -53,10 +144,15 @@ namespace
const NzVector3f* normals = parser.GetNormals();
const NzVector3f* texCoords = parser.GetTexCoords();
- std::vector faceIndices;
-
const NzOBJParser::Mesh* meshes = parser.GetMeshes();
unsigned int meshCount = parser.GetMeshCount();
+
+ NazaraAssert(materials != nullptr && positions != nullptr && normals != nullptr &&
+ texCoords != nullptr && meshes != nullptr && meshCount > 0,
+ "Invalid OBJParser output");
+
+ // Un conteneur temporaire pour contenir les indices de face avant triangulation
+ std::vector faceIndices(3); // Comme il y aura au moins trois sommets
for (unsigned int i = 0; i < meshCount; ++i)
{
unsigned int faceCount = meshes[i].faces.size();
@@ -66,8 +162,35 @@ namespace
std::vector indices;
indices.reserve(faceCount*3); // Pire cas si les faces sont des triangles
- // Bien plus rapide qu'un vector (pour la recherche)
- std::unordered_map>> vertices;
+ // Afin d'utiliser OBJParser::FaceVertex comme clé dans un unordered_map,
+ // nous devons fournir un foncteur de hash ainsi qu'un foncteur de comparaison
+
+ // Hash
+ struct FaceVertexHasher
+ {
+ std::size_t operator()(const NzOBJParser::FaceVertex& o) const
+ {
+ std::size_t seed = 0;
+ NzHashCombine(seed, o.normal);
+ NzHashCombine(seed, o.position);
+ NzHashCombine(seed, o.texCoord);
+
+ return seed;
+ }
+ };
+
+ // Comparaison
+ struct FaceVertexComparator
+ {
+ bool operator()(const NzOBJParser::FaceVertex& lhs, const NzOBJParser::FaceVertex& rhs) const
+ {
+ return lhs.normal == rhs.normal &&
+ lhs.position == rhs.position &&
+ lhs.texCoord == rhs.texCoord;
+ }
+ };
+
+ std::unordered_map vertices;
unsigned int vertexCount = 0;
for (unsigned int j = 0; j < faceCount; ++j)
@@ -79,15 +202,11 @@ namespace
{
const NzOBJParser::FaceVertex& vertex = meshes[i].faces[j].vertices[k];
- auto& map = vertices[vertex.texCoord][vertex.normal];
- auto it = map.find(vertex.position);
- if (it == map.end())
- {
- faceIndices[k] = vertexCount;
- map[vertex.position] = vertexCount++;
- }
- else
- faceIndices[k] = it->second;
+ auto it = vertices.find(vertex);
+ if (it == vertices.end())
+ it = vertices.emplace(vertex, vertexCount++).first;
+
+ faceIndices[k] = it->second;
}
for (unsigned int k = 1; k < faceVertexCount-1; ++k)
@@ -114,36 +233,29 @@ namespace
bool hasTexCoords = true;
NzBufferMapper vertexMapper(vertexBuffer, nzBufferAccess_WriteOnly);
NzMeshVertex* meshVertices = static_cast(vertexMapper.GetPointer());
- for (auto& uvIt : vertices)
+ for (auto& vertexPair : vertices)
{
- for (auto& normalIt : uvIt.second)
+ const NzOBJParser::FaceVertex& vertexIndices = vertexPair.first;
+ unsigned int index = vertexPair.second;
+
+ NzMeshVertex& vertex = meshVertices[index];
+
+ const NzVector4f& vec = positions[vertexIndices.position];
+ vertex.position.Set(vec.x, vec.y, vec.z);
+ vertex.position *= parameters.mesh.scale/vec.w;
+
+ if (vertexIndices.normal >= 0)
+ vertex.normal = normals[vertexIndices.normal];
+ else
+ hasNormals = false;
+
+ if (vertexIndices.texCoord >= 0)
{
- for (auto& positionIt : normalIt.second)
- {
- NzMeshVertex& vertex = meshVertices[positionIt.second];
-
- const NzVector4f& vec = positions[positionIt.first];
- vertex.position.Set(vec.x, vec.y, vec.z);
- vertex.position *= parameters.mesh.scale/vec.w;
-
- int index;
-
- index = normalIt.first; // Normale
- if (index >= 0)
- vertex.normal = normals[index];
- else
- hasNormals = false;
-
- index = uvIt.first; // Coordonnées de texture
- if (index >= 0)
- {
- const NzVector3f& uvw = texCoords[index];
- vertex.uv.Set(uvw.x, (parameters.mesh.flipUVs) ? 1.f - uvw.y : uvw.y); // Inversion des UVs si demandé
- }
- else
- hasTexCoords = false;
- }
+ const NzVector3f& uvw = texCoords[vertexIndices.texCoord];
+ vertex.uv.Set(uvw.x, (parameters.mesh.flipUVs) ? 1.f - uvw.y : uvw.y); // Inversion des UVs si demandé
}
+ else
+ hasTexCoords = false;
}
vertexMapper.Unmap();
@@ -184,90 +296,8 @@ namespace
NzString mtlLib = parser.GetMtlLib();
if (parameters.loadMaterials && !mtlLib.IsEmpty())
{
- NzFile file(stream.GetDirectory() + mtlLib);
- if (file.Open(NzFile::ReadOnly | NzFile::Text))
- {
- NzMTLParser materialParser(file);
- if (materialParser.Parse())
- {
- std::unordered_map materialCache;
- NzString baseDir = file.GetDirectory();
- for (unsigned int i = 0; i < meshCount; ++i)
- {
- const NzString& matName = materials[meshes[i].material];
- const NzMTLParser::Material* mtlMat = materialParser.GetMaterial(matName);
- if (mtlMat)
- {
- auto it = materialCache.find(matName);
- if (it != materialCache.end())
- model->SetMaterial(meshes[i].material, it->second);
- else
- {
- NzMaterialRef material = NzMaterial::New();
- material->SetShader(parameters.material.shaderName);
-
- nzUInt8 alphaValue = static_cast(mtlMat->alpha*255.f);
-
- NzColor ambientColor(mtlMat->ambient);
- ambientColor.a = alphaValue;
-
- NzColor diffuseColor(mtlMat->diffuse);
- diffuseColor.a = alphaValue;
-
- NzColor specularColor(mtlMat->specular);
- specularColor.a = alphaValue;
-
- material->SetAmbientColor(ambientColor);
- material->SetDiffuseColor(diffuseColor);
- material->SetSpecularColor(specularColor);
- material->SetShininess(mtlMat->shininess);
-
- bool hasAlphaMap = false;;
- if (parameters.material.loadAlphaMap && !mtlMat->alphaMap.IsEmpty())
- {
- if (material->SetAlphaMap(baseDir + mtlMat->alphaMap))
- hasAlphaMap = true;
- else
- NazaraWarning("Failed to load alpha map (" + mtlMat->alphaMap + ')');
- }
-
- if (parameters.material.loadDiffuseMap && !mtlMat->diffuseMap.IsEmpty())
- {
- if (!material->SetDiffuseMap(baseDir + mtlMat->diffuseMap))
- NazaraWarning("Failed to load diffuse map (" + mtlMat->diffuseMap + ')');
- }
-
- if (parameters.material.loadSpecularMap && !mtlMat->specularMap.IsEmpty())
- {
- if (!material->SetSpecularMap(baseDir + mtlMat->specularMap))
- NazaraWarning("Failed to load specular map (" + mtlMat->specularMap + ')');
- }
-
- // Si nous avons une alpha map ou des couleurs transparentes,
- // nous devons configurer le matériau pour accepter la transparence au mieux
- if (hasAlphaMap || alphaValue != 255)
- {
- // On paramètre le matériau pour accepter la transparence au mieux
- material->Enable(nzRendererParameter_Blend, true);
- material->Enable(nzRendererParameter_DepthWrite, false);
- material->SetDstBlend(nzBlendFunc_InvSrcAlpha);
- material->SetSrcBlend(nzBlendFunc_SrcAlpha);
- }
-
- materialCache[matName] = material;
-
- model->SetMaterial(meshes[i].material, material);
- }
- }
- else
- NazaraWarning("MTL has no material \"" + matName + '"');
- }
- }
- else
- NazaraWarning("MTL parser failed");
- }
- else
- NazaraWarning("Failed to open MTL file (" + file.GetPath() + ')');
+ NzErrorFlags flags(nzErrorFlag_ThrowExceptionDisabled);
+ LoadMaterials(model, stream.GetDirectory() + mtlLib, parameters.material, materials, meshes, meshCount);
}
return true;
diff --git a/src/Nazara/Graphics/Loaders/OBJ/OBJParser.cpp b/src/Nazara/Graphics/Loaders/OBJ/OBJParser.cpp
index 6bb87be56..fcefc2dd5 100644
--- a/src/Nazara/Graphics/Loaders/OBJ/OBJParser.cpp
+++ b/src/Nazara/Graphics/Loaders/OBJ/OBJParser.cpp
@@ -6,7 +6,7 @@
#include
#include
#include
-#include
+#include
#include
#include
#include
diff --git a/src/Nazara/Graphics/Material.cpp b/src/Nazara/Graphics/Material.cpp
index 0544067f5..e4f3fe965 100644
--- a/src/Nazara/Graphics/Material.cpp
+++ b/src/Nazara/Graphics/Material.cpp
@@ -406,23 +406,23 @@ void NzMaterial::Reset()
SetShader("Basic");
}
-bool NzMaterial::SetAlphaMap(const NzString& name)
+bool NzMaterial::SetAlphaMap(const NzString& textureName)
{
- NzTextureRef texture = NzTextureLibrary::Query(name);
+ NzTextureRef texture = NzTextureLibrary::Query(textureName);
if (!texture)
{
- texture = NzTextureManager::Get(name);
+ texture = NzTextureManager::Get(textureName);
if (!texture)
return false;
}
- SetAlphaMap(texture);
+ SetAlphaMap(std::move(texture));
return true;
}
-void NzMaterial::SetAlphaMap(NzTexture* map)
+void NzMaterial::SetAlphaMap(NzTextureRef alphaMap)
{
- m_alphaMap = map;
+ m_alphaMap = std::move(alphaMap);
InvalidateShaders();
}
@@ -447,23 +447,23 @@ void NzMaterial::SetDiffuseColor(const NzColor& diffuse)
m_diffuseColor = diffuse;
}
-bool NzMaterial::SetDiffuseMap(const NzString& name)
+bool NzMaterial::SetDiffuseMap(const NzString& textureName)
{
- NzTextureRef texture = NzTextureLibrary::Query(name);
+ NzTextureRef texture = NzTextureLibrary::Query(textureName);
if (!texture)
{
- texture = NzTextureManager::Get(name);
+ texture = NzTextureManager::Get(textureName);
if (!texture)
return false;
}
- SetDiffuseMap(texture);
+ SetDiffuseMap(std::move(texture));
return true;
}
-void NzMaterial::SetDiffuseMap(NzTexture* map)
+void NzMaterial::SetDiffuseMap(NzTextureRef diffuseMap)
{
- m_diffuseMap = map;
+ m_diffuseMap = std::move(diffuseMap);
InvalidateShaders();
}
@@ -478,23 +478,23 @@ void NzMaterial::SetDstBlend(nzBlendFunc func)
m_states.dstBlend = func;
}
-bool NzMaterial::SetEmissiveMap(const NzString& name)
+bool NzMaterial::SetEmissiveMap(const NzString& textureName)
{
- NzTextureRef texture = NzTextureLibrary::Query(name);
+ NzTextureRef texture = NzTextureLibrary::Query(textureName);
if (!texture)
{
- texture = NzTextureManager::Get(name);
+ texture = NzTextureManager::Get(textureName);
if (!texture)
return false;
}
- SetEmissiveMap(texture);
+ SetEmissiveMap(std::move(texture));
return true;
}
-void NzMaterial::SetEmissiveMap(NzTexture* map)
+void NzMaterial::SetEmissiveMap(NzTextureRef emissiveMap)
{
- m_emissiveMap = map;
+ m_emissiveMap = std::move(emissiveMap);
InvalidateShaders();
}
@@ -509,44 +509,44 @@ void NzMaterial::SetFaceFilling(nzFaceFilling filling)
m_states.faceFilling = filling;
}
-bool NzMaterial::SetHeightMap(const NzString& name)
+bool NzMaterial::SetHeightMap(const NzString& textureName)
{
- NzTextureRef texture = NzTextureLibrary::Query(name);
+ NzTextureRef texture = NzTextureLibrary::Query(textureName);
if (!texture)
{
- texture = NzTextureManager::Get(name);
+ texture = NzTextureManager::Get(textureName);
if (!texture)
return false;
}
- SetHeightMap(texture);
+ SetHeightMap(std::move(texture));
return true;
}
-void NzMaterial::SetHeightMap(NzTexture* map)
+void NzMaterial::SetHeightMap(NzTextureRef heightMap)
{
- m_heightMap = map;
+ m_heightMap = std::move(heightMap);
InvalidateShaders();
}
-bool NzMaterial::SetNormalMap(const NzString& name)
+bool NzMaterial::SetNormalMap(const NzString& textureName)
{
- NzTextureRef texture = NzTextureLibrary::Query(name);
+ NzTextureRef texture = NzTextureLibrary::Query(textureName);
if (!texture)
{
- texture = NzTextureManager::Get(name);
+ texture = NzTextureManager::Get(textureName);
if (!texture)
return false;
}
- SetNormalMap(texture);
+ SetNormalMap(std::move(texture));
return true;
}
-void NzMaterial::SetNormalMap(NzTexture* map)
+void NzMaterial::SetNormalMap(NzTextureRef normalMap)
{
- m_normalMap = map;
+ m_normalMap = std::move(normalMap);
InvalidateShaders();
}
@@ -556,20 +556,20 @@ void NzMaterial::SetRenderStates(const NzRenderStates& states)
m_states = states;
}
-void NzMaterial::SetShader(const NzUberShader* uberShader)
+void NzMaterial::SetShader(NzUberShaderConstRef uberShader)
{
- m_uberShader = uberShader;
+ m_uberShader = std::move(uberShader);
InvalidateShaders();
}
bool NzMaterial::SetShader(const NzString& uberShaderName)
{
- NzUberShader* uberShader = NzUberShaderLibrary::Get(uberShaderName);
+ NzUberShaderConstRef uberShader = NzUberShaderLibrary::Get(uberShaderName);
if (!uberShader)
return false;
- SetShader(uberShader);
+ SetShader(std::move(uberShader));
return true;
}
@@ -583,23 +583,23 @@ void NzMaterial::SetSpecularColor(const NzColor& specular)
m_specularColor = specular;
}
-bool NzMaterial::SetSpecularMap(const NzString& name)
+bool NzMaterial::SetSpecularMap(const NzString& textureName)
{
- NzTextureRef texture = NzTextureLibrary::Query(name);
+ NzTextureRef texture = NzTextureLibrary::Query(textureName);
if (!texture)
{
- texture = NzTextureManager::Get(name);
+ texture = NzTextureManager::Get(textureName);
if (!texture)
return false;
}
- SetSpecularMap(texture);
+ SetSpecularMap(std::move(texture));
return true;
}
-void NzMaterial::SetSpecularMap(NzTexture* map)
+void NzMaterial::SetSpecularMap(NzTextureRef specularMap)
{
- m_specularMap = map;
+ m_specularMap = std::move(specularMap);
InvalidateShaders();
}
diff --git a/src/Nazara/Graphics/Scene.cpp b/src/Nazara/Graphics/Scene.cpp
index 289ff1b1e..44e4b2610 100644
--- a/src/Nazara/Graphics/Scene.cpp
+++ b/src/Nazara/Graphics/Scene.cpp
@@ -81,12 +81,12 @@ void NzScene::Draw()
if (m_renderTechniqueRanking > 0)
{
m_renderTechnique.reset(NzRenderTechniques::GetByRanking(m_renderTechniqueRanking-1, &m_renderTechniqueRanking));
- NazaraError("Render technique \"" + oldName + "\" failed, falling back to \"" + m_renderTechnique->GetName() + '"');
+ NazaraError("Render technique \"" + oldName + "\" failed (" + NzString(e.what()) + "), falling back to \"" + m_renderTechnique->GetName() + '"');
}
else
{
NzErrorFlags errFlags(nzErrorFlag_ThrowException);
- NazaraError("Render technique \"" + oldName + "\" failed and no fallback is available");
+ NazaraError("Render technique \"" + oldName + "\" failed (" + NzString(e.what()) + ") and no fallback is available");
}
return;
diff --git a/src/Nazara/Graphics/SkeletalModel.cpp b/src/Nazara/Graphics/SkeletalModel.cpp
index 94af428b6..212461ef2 100644
--- a/src/Nazara/Graphics/SkeletalModel.cpp
+++ b/src/Nazara/Graphics/SkeletalModel.cpp
@@ -44,7 +44,8 @@ m_nextFrame(model.m_nextFrame)
NzSkeletalModel::~NzSkeletalModel()
{
- m_scene->UnregisterForUpdate(this);
+ if (m_scene)
+ m_scene->UnregisterForUpdate(this);
}
void NzSkeletalModel::AddToRenderQueue(NzAbstractRenderQueue* renderQueue) const
diff --git a/src/Nazara/Graphics/TextSprite.cpp b/src/Nazara/Graphics/TextSprite.cpp
index 465be492c..4259035a6 100644
--- a/src/Nazara/Graphics/TextSprite.cpp
+++ b/src/Nazara/Graphics/TextSprite.cpp
@@ -333,6 +333,7 @@ bool NzTextSprite::OnAtlasLayerChange(const NzAbstractAtlas* atlas, NzAbstractIm
NzTexture* oldTexture = static_cast(oldLayer);
NzTexture* newTexture = static_cast(newLayer);
+ // Il est possible que nous n'utilisions pas la texture en question (l'atlas nous prévenant pour chacun de ses layers)
auto it = m_renderInfos.find(oldTexture);
if (it != m_renderInfos.end())
{
@@ -343,7 +344,7 @@ bool NzTextSprite::OnAtlasLayerChange(const NzAbstractAtlas* atlas, NzAbstractIm
NzVector2ui newSize(newTexture->GetSize());
NzVector2f scale = NzVector2f(oldSize)/NzVector2f(newSize); // ratio ancienne et nouvelle taille
- // On va maintenant parcourir toutes les coordonnées de texture pour les multiplier par ce ratio
+ // On va maintenant parcourir toutes les coordonnées de texture concernées pour les multiplier par ce ratio
NzSparsePtr texCoordPtr(&m_vertices[indices.first].uv, sizeof(NzVertexStruct_XYZ_Color_UV));
for (unsigned int i = 0; i < indices.count; ++i)
{
@@ -372,7 +373,7 @@ void NzTextSprite::OnAtlasReleased(const NzAbstractAtlas* atlas, void* userdata)
#endif
// L'atlas a été libéré alors que le TextSprite l'utilisait encore, notre seule option (pour éviter un crash) est de nous réinitialiser
- NazaraWarning("TextSprite " + NzString::Pointer(this) + " has been cleared because atlas " + NzString::Pointer(atlas) + " that was under use has been released");
+ NazaraWarning("TextSprite " + NzString::Pointer(this) + " has been cleared because atlas " + NzString::Pointer(atlas) + " has been released");
Clear();
}
diff --git a/src/Nazara/Graphics/View.cpp b/src/Nazara/Graphics/View.cpp
index 0316b9e53..9662b3cc0 100644
--- a/src/Nazara/Graphics/View.cpp
+++ b/src/Nazara/Graphics/View.cpp
@@ -13,8 +13,10 @@ m_targetRegion(0.f, 0.f, 1.f, 1.f),
m_size(0.f),
m_target(nullptr),
m_frustumUpdated(false),
+m_invViewProjMatrixUpdated(false),
m_projectionMatrixUpdated(false),
m_viewMatrixUpdated(false),
+m_viewProjMatrixUpdated(false),
m_viewportUpdated(false),
m_zFar(1.f),
m_zNear(-1.f)
@@ -95,6 +97,14 @@ NzVector3f NzView::GetGlobalUp() const
return -NzVector3f::UnitY();
}
+const NzMatrix4f& NzView::GetInvViewProjMatrix() const
+{
+ if (!m_invViewProjMatrixUpdated)
+ UpdateInvViewProjMatrix();
+
+ return m_invViewProjMatrix;
+}
+
const NzMatrix4f& NzView::GetProjectionMatrix() const
{
if (!m_projectionMatrixUpdated)
@@ -121,6 +131,14 @@ const NzMatrix4f& NzView::GetViewMatrix() const
return m_viewMatrix;
}
+const NzMatrix4f& NzView::GetViewProjMatrix() const
+{
+ if (!m_viewProjMatrixUpdated)
+ UpdateViewProjMatrix();
+
+ return m_viewProjMatrix;
+}
+
const NzRecti& NzView::GetViewport() const
{
#if NAZARA_GRAPHICS_SAFE
@@ -147,6 +165,44 @@ float NzView::GetZNear() const
return m_zNear;
}
+NzVector2i NzView::MapWorldToPixel(const NzVector2f& coords)
+{
+ if (!m_viewProjMatrixUpdated)
+ UpdateViewProjMatrix();
+
+ if (!m_viewportUpdated)
+ UpdateViewport();
+
+ // Conversion du viewport en flottant
+ NzRectf viewport(m_viewport);
+
+ NzVector2f normalized = m_viewProjMatrix.Transform(coords);
+
+ NzVector2i pixel;
+ pixel.x = static_cast(( normalized.x + 1.f) * viewport.width / 2.f + viewport.x);
+ pixel.y = static_cast((-normalized.y + 1.f) * viewport.width / 2.f + viewport.y);
+
+ return pixel;
+}
+
+NzVector2f NzView::MapPixelToWorld(const NzVector2i& pixel)
+{
+ if (!m_invViewProjMatrixUpdated)
+ UpdateInvViewProjMatrix();
+
+ if (!m_viewportUpdated)
+ UpdateViewport();
+
+ // Conversion du viewport en flottant
+ NzRectf viewport(m_viewport);
+
+ NzVector2f normalized;
+ normalized.x = -1.f + 2.f * (pixel.x - viewport.x) / viewport.width;
+ normalized.y = 1.f - 2.f * (pixel.y - viewport.y) / viewport.height;
+
+ return m_invViewProjMatrix.Transform(normalized);
+}
+
void NzView::SetSize(const NzVector2f& size)
{
SetSize(size.x, size.y);
@@ -178,7 +234,9 @@ void NzView::SetTargetRegion(const NzRectf& region)
m_targetRegion = region;
m_frustumUpdated = false;
+ m_invViewProjMatrixUpdated = false;
m_projectionMatrixUpdated = false;
+ m_viewProjMatrixUpdated = false;
m_viewportUpdated = false;
}
@@ -204,7 +262,9 @@ void NzView::SetZFar(float zFar)
m_zFar = zFar;
m_frustumUpdated = false;
+ m_invViewProjMatrixUpdated = false;
m_projectionMatrixUpdated = false;
+ m_viewProjMatrixUpdated = false;
}
void NzView::SetZNear(float zNear)
@@ -212,7 +272,9 @@ void NzView::SetZNear(float zNear)
m_zNear = zNear;
m_frustumUpdated = false;
+ m_invViewProjMatrixUpdated = false;
m_projectionMatrixUpdated = false;
+ m_viewProjMatrixUpdated = false;
}
void NzView::ApplyView() const
@@ -246,7 +308,9 @@ void NzView::InvalidateNode()
// Le frustum et la view matrix dépendent des paramètres du node, invalidons-les
m_frustumUpdated = false;
+ m_invViewProjMatrixUpdated = false;
m_viewMatrixUpdated = false;
+ m_viewProjMatrixUpdated = false;
}
void NzView::OnRenderTargetReleased(const NzRenderTarget* renderTarget, void* userdata)
@@ -287,6 +351,15 @@ void NzView::UpdateFrustum() const
m_frustumUpdated = true;
}
+void NzView::UpdateInvViewProjMatrix() const
+{
+ if (!m_viewProjMatrixUpdated)
+ UpdateViewProjMatrix();
+
+ m_viewProjMatrix.GetInverseAffine(&m_invViewProjMatrix);
+ m_invViewProjMatrixUpdated = true;
+}
+
void NzView::UpdateProjectionMatrix() const
{
if (m_size.x <= 0.f || m_size.y <= 0.f) // Si la taille est nulle, on prendra la taille du viewport
@@ -294,7 +367,7 @@ void NzView::UpdateProjectionMatrix() const
if (!m_viewportUpdated)
UpdateViewport();
- m_projectionMatrix.MakeOrtho(0.f, m_viewport.width, 0.f, m_viewport.height, m_zNear, m_zFar);
+ m_projectionMatrix.MakeOrtho(0.f, static_cast(m_viewport.width), 0.f, static_cast(m_viewport.height), m_zNear, m_zFar);
}
else
m_projectionMatrix.MakeOrtho(0.f, m_size.x, 0.f, m_size.y, m_zNear, m_zFar);
@@ -311,6 +384,19 @@ void NzView::UpdateViewMatrix() const
m_viewMatrixUpdated = true;
}
+void NzView::UpdateViewProjMatrix() const
+{
+ if (!m_projectionMatrixUpdated)
+ UpdateProjectionMatrix();
+
+ if (!m_viewMatrixUpdated)
+ UpdateViewMatrix();
+
+ // La matrice de projection orthogonale est affine
+ m_viewProjMatrix = NzMatrix4f::ConcatenateAffine(m_viewMatrix, m_projectionMatrix);
+ m_viewProjMatrixUpdated = true;
+}
+
void NzView::UpdateViewport() const
{
unsigned int width = m_target->GetWidth();
diff --git a/src/Nazara/Lua/LuaInstance.cpp b/src/Nazara/Lua/LuaInstance.cpp
index 396fd4a35..c1e1fa875 100644
--- a/src/Nazara/Lua/LuaInstance.cpp
+++ b/src/Nazara/Lua/LuaInstance.cpp
@@ -19,6 +19,45 @@
namespace
{
+ nzLuaType FromLuaType(int type)
+ {
+ switch (type)
+ {
+ case LUA_TBOOLEAN:
+ return nzLuaType_Boolean;
+
+ case LUA_TFUNCTION:
+ return nzLuaType_Function;
+
+ case LUA_TLIGHTUSERDATA:
+ return nzLuaType_LightUserdata;
+
+ case LUA_TNIL:
+ return nzLuaType_Nil;
+
+ case LUA_TNONE:
+ return nzLuaType_None;
+
+ case LUA_TNUMBER:
+ return nzLuaType_Number;
+
+ case LUA_TSTRING:
+ return nzLuaType_String;
+
+ case LUA_TTABLE:
+ return nzLuaType_Table;
+
+ case LUA_TTHREAD:
+ return nzLuaType_Thread;
+
+ case LUA_TUSERDATA:
+ return nzLuaType_Userdata;
+
+ default:
+ return nzLuaType_None;
+ }
+ }
+
struct StreamData
{
NzInputStream* stream;
@@ -134,7 +173,7 @@ bool NzLuaInstance::CheckBoolean(int index) const
return false;
}
- return lua_toboolean(m_state, index);
+ return lua_toboolean(m_state, index) != 0;
}
bool NzLuaInstance::CheckBoolean(int index, bool defValue) const
@@ -142,17 +181,17 @@ bool NzLuaInstance::CheckBoolean(int index, bool defValue) const
if (lua_isnoneornil(m_state, index))
return defValue;
- return lua_toboolean(m_state, index);
+ return lua_toboolean(m_state, index) != 0;
}
-int NzLuaInstance::CheckInteger(int index) const
+long long NzLuaInstance::CheckInteger(int index) const
{
- return luaL_checkint(m_state, index);
+ return luaL_checkinteger(m_state, index);
}
-int NzLuaInstance::CheckInteger(int index, int defValue) const
+long long NzLuaInstance::CheckInteger(int index, long long defValue) const
{
- return luaL_optint(m_state, index, defValue);
+ return luaL_optinteger(m_state, index, defValue);
}
double NzLuaInstance::CheckNumber(int index) const
@@ -198,16 +237,6 @@ void NzLuaInstance::CheckType(int index, nzLuaType type) const
luaL_checktype(m_state, index, s_types[type]);
}
-unsigned int NzLuaInstance::CheckUnsigned(int index) const
-{
- return luaL_checkunsigned(m_state, index);
-}
-
-unsigned int NzLuaInstance::CheckUnsigned(int index, unsigned int defValue) const
-{
- return luaL_optunsigned(m_state, index, defValue);
-}
-
void* NzLuaInstance::CheckUserdata(int index, const char* tname) const
{
return luaL_checkudata(m_state, index, tname);
@@ -228,7 +257,7 @@ bool NzLuaInstance::Compare(int index1, int index2, nzLuaComparison comparison)
}
#endif
- return (lua_compare(m_state, index1, index2, s_comparisons[comparison]) == 1);
+ return (lua_compare(m_state, index1, index2, s_comparisons[comparison]) != 0);
}
void NzLuaInstance::Compute(nzLuaOperation operation)
@@ -395,24 +424,24 @@ int NzLuaInstance::GetAbsIndex(int index) const
return lua_absindex(m_state, index);
}
-void NzLuaInstance::GetField(const char* fieldName, int index) const
+nzLuaType NzLuaInstance::GetField(const char* fieldName, int index) const
{
- lua_getfield(m_state, index, fieldName);
+ return FromLuaType(lua_getfield(m_state, index, fieldName));
}
-void NzLuaInstance::GetField(const NzString& fieldName, int index) const
+nzLuaType NzLuaInstance::GetField(const NzString& fieldName, int index) const
{
- lua_getfield(m_state, index, fieldName.GetConstBuffer());
+ return FromLuaType(lua_getfield(m_state, index, fieldName.GetConstBuffer()));
}
-void NzLuaInstance::GetGlobal(const char* name) const
+nzLuaType NzLuaInstance::GetGlobal(const char* name) const
{
- lua_getglobal(m_state, name);
+ return FromLuaType(lua_getglobal(m_state, name));
}
-void NzLuaInstance::GetGlobal(const NzString& name) const
+nzLuaType NzLuaInstance::GetGlobal(const NzString& name) const
{
- lua_getglobal(m_state, name.GetConstBuffer());
+ return FromLuaType(lua_getglobal(m_state, name.GetConstBuffer()));
}
lua_State* NzLuaInstance::GetInternalState() const
@@ -435,19 +464,19 @@ nzUInt32 NzLuaInstance::GetMemoryUsage() const
return m_memoryUsage;
}
-void NzLuaInstance::GetMetatable(const char* tname) const
+nzLuaType NzLuaInstance::GetMetatable(const char* tname) const
{
- luaL_getmetatable(m_state, tname);
+ return FromLuaType(luaL_getmetatable(m_state, tname));
}
-void NzLuaInstance::GetMetatable(const NzString& tname) const
+nzLuaType NzLuaInstance::GetMetatable(const NzString& tname) const
{
- luaL_getmetatable(m_state, tname.GetConstBuffer());
+ return FromLuaType(luaL_getmetatable(m_state, tname.GetConstBuffer()));
}
bool NzLuaInstance::GetMetatable(int index) const
{
- return lua_getmetatable(m_state, index) == 1;
+ return lua_getmetatable(m_state, index) != 0;
}
unsigned int NzLuaInstance::GetStackTop() const
@@ -455,9 +484,9 @@ unsigned int NzLuaInstance::GetStackTop() const
return lua_gettop(m_state);
}
-void NzLuaInstance::GetTable(int index) const
+nzLuaType NzLuaInstance::GetTable(int index) const
{
- lua_gettable(m_state, index);
+ return FromLuaType(lua_gettable(m_state, index));
}
nzUInt32 NzLuaInstance::GetTimeLimit() const
@@ -467,41 +496,7 @@ nzUInt32 NzLuaInstance::GetTimeLimit() const
nzLuaType NzLuaInstance::GetType(int index) const
{
- switch (lua_type(m_state, index))
- {
- case LUA_TBOOLEAN:
- return nzLuaType_Boolean;
-
- case LUA_TFUNCTION:
- return nzLuaType_Function;
-
- case LUA_TLIGHTUSERDATA:
- return nzLuaType_LightUserdata;
-
- case LUA_TNIL:
- return nzLuaType_Nil;
-
- case LUA_TNONE:
- return nzLuaType_None;
-
- case LUA_TNUMBER:
- return nzLuaType_Number;
-
- case LUA_TSTRING:
- return nzLuaType_String;
-
- case LUA_TTABLE:
- return nzLuaType_Table;
-
- case LUA_TTHREAD:
- return nzLuaType_Thread;
-
- case LUA_TUSERDATA:
- return nzLuaType_Userdata;
-
- default:
- return nzLuaType_None;
- }
+ return FromLuaType(lua_type(m_state, index));
}
const char* NzLuaInstance::GetTypeName(nzLuaType type) const
@@ -527,34 +522,34 @@ bool NzLuaInstance::IsOfType(int index, nzLuaType type) const
switch (type)
{
case nzLuaType_Boolean:
- return lua_isboolean(m_state, index) == 1;
+ return lua_isboolean(m_state, index) != 0;
case nzLuaType_Function:
- return lua_isfunction(m_state, index) == 1;
+ return lua_isfunction(m_state, index) != 0;
case nzLuaType_LightUserdata:
- return lua_islightuserdata(m_state, index) == 1;
+ return lua_islightuserdata(m_state, index) != 0;
case nzLuaType_Nil:
- return lua_isnil(m_state, index) == 1;
+ return lua_isnil(m_state, index) != 0;
case nzLuaType_None:
- return lua_isnone(m_state, index) == 1;
+ return lua_isnone(m_state, index) != 0;
case nzLuaType_Number:
- return lua_isnumber(m_state, index) == 1;
+ return lua_isnumber(m_state, index) != 0;
case nzLuaType_String:
- return lua_isstring(m_state, index) == 1;
+ return lua_isstring(m_state, index) != 0;
case nzLuaType_Table:
- return lua_istable(m_state, index) == 1;
+ return lua_istable(m_state, index) != 0;
case nzLuaType_Thread:
- return lua_isthread(m_state, index) == 1;
+ return lua_isthread(m_state, index) != 0;
case nzLuaType_Userdata:
- return lua_isuserdata(m_state, index) == 1;
+ return lua_isuserdata(m_state, index) != 0;
}
NazaraError("Lua type not handled (0x" + NzString::Number(type, 16) + ')');
@@ -574,7 +569,7 @@ bool NzLuaInstance::IsOfType(int index, const NzString& tname) const
bool NzLuaInstance::IsValid(int index) const
{
- return !lua_isnoneornil(m_state, index);
+ return lua_isnoneornil(m_state, index) == 0;
}
unsigned int NzLuaInstance::Length(int index) const
@@ -589,17 +584,17 @@ void NzLuaInstance::MoveTo(NzLuaInstance* instance, int n)
bool NzLuaInstance::NewMetatable(const char* str)
{
- return luaL_newmetatable(m_state, str) == 1;
+ return luaL_newmetatable(m_state, str) != 0;
}
bool NzLuaInstance::NewMetatable(const NzString& str)
{
- return luaL_newmetatable(m_state, str.GetConstBuffer());
+ return luaL_newmetatable(m_state, str.GetConstBuffer()) != 0;
}
bool NzLuaInstance::Next(int index)
{
- return lua_next(m_state, index) == 1;
+ return lua_next(m_state, index) != 0;
}
void NzLuaInstance::Pop(unsigned int n)
@@ -609,7 +604,7 @@ void NzLuaInstance::Pop(unsigned int n)
void NzLuaInstance::PushBoolean(bool value)
{
- lua_pushboolean(m_state, value);
+ lua_pushboolean(m_state, (value) ? 1 : 0);
}
void NzLuaInstance::PushCFunction(NzLuaCFunction func, int upvalueCount)
@@ -625,7 +620,7 @@ void NzLuaInstance::PushFunction(NzLuaFunction func)
lua_pushcclosure(m_state, ProxyFunc, 1);
}
-void NzLuaInstance::PushInteger(int value)
+void NzLuaInstance::PushInteger(long long value)
{
lua_pushinteger(m_state, value);
}
@@ -675,11 +670,6 @@ void NzLuaInstance::PushTable(unsigned int sequenceElementCount, unsigned int ar
lua_createtable(m_state, sequenceElementCount, arrayElementCount);
}
-void NzLuaInstance::PushUnsigned(unsigned int value)
-{
- lua_pushunsigned(m_state, value);
-}
-
void* NzLuaInstance::PushUserdata(unsigned int size)
{
return lua_newuserdata(m_state, size);
@@ -760,16 +750,16 @@ void NzLuaInstance::SetTimeLimit(nzUInt32 timeLimit)
bool NzLuaInstance::ToBoolean(int index) const
{
- return lua_toboolean(m_state, index);
+ return lua_toboolean(m_state, index) != 0;
}
-int NzLuaInstance::ToInteger(int index, bool* succeeded) const
+long long NzLuaInstance::ToInteger(int index, bool* succeeded) const
{
int success;
- int result = lua_tointegerx(m_state, index, &success);
+ long long result = lua_tointegerx(m_state, index, &success);
if (succeeded)
- *succeeded = (success == 1);
+ *succeeded = (success != 0);
return result;
}
@@ -780,7 +770,7 @@ double NzLuaInstance::ToNumber(int index, bool* succeeded) const
double result = lua_tonumberx(m_state, index, &success);
if (succeeded)
- *succeeded = (success == 1);
+ *succeeded = (success != 0);
return result;
}
@@ -795,17 +785,6 @@ const char* NzLuaInstance::ToString(int index, std::size_t* length) const
return lua_tolstring(m_state, index, length);
}
-unsigned int NzLuaInstance::ToUnsigned(int index, bool* succeeded) const
-{
- int success;
- unsigned int result = lua_tounsignedx(m_state, index, &success);
-
- if (succeeded)
- *succeeded = (success == 1);
-
- return result;
-}
-
void* NzLuaInstance::ToUserdata(int index) const
{
return lua_touserdata(m_state, index);
diff --git a/src/Nazara/Renderer/UberShaderPreprocessor.cpp b/src/Nazara/Renderer/UberShaderPreprocessor.cpp
index 9654a9ee8..efcc492c5 100644
--- a/src/Nazara/Renderer/UberShaderPreprocessor.cpp
+++ b/src/Nazara/Renderer/UberShaderPreprocessor.cpp
@@ -92,7 +92,7 @@ NzUberShaderInstance* NzUberShaderPreprocessor::Get(const NzParameterList& param
// On construit l'instant
shaderIt = m_cache.emplace(flags, shader.Get()).first;
}
- catch (const std::exception& e)
+ catch (const std::exception&)
{
NzErrorFlags errFlags(nzErrorFlag_ThrowExceptionDisabled);
diff --git a/src/Nazara/Utility/Font.cpp b/src/Nazara/Utility/Font.cpp
index ae2f89298..754e9c455 100644
--- a/src/Nazara/Utility/Font.cpp
+++ b/src/Nazara/Utility/Font.cpp
@@ -253,9 +253,9 @@ bool NzFont::Precache(unsigned int characterSize, nzUInt32 style, char32_t chara
bool NzFont::Precache(unsigned int characterSize, nzUInt32 style, const NzString& characterSet) const
{
- unsigned int size;
- std::unique_ptr characters(characterSet.GetUtf32Buffer(&size));
- if (!characters)
+ ///TODO: Itération UTF-8 => UTF-32 sans allocation de buffer (Exposer utf8cpp ?)
+ std::u32string set = characterSet.GetUtf32String();
+ if (set.empty())
{
NazaraError("Invalid character set");
return false;
@@ -263,8 +263,8 @@ bool NzFont::Precache(unsigned int characterSize, nzUInt32 style, const NzString
nzUInt64 key = ComputeKey(characterSize, style);
auto& glyphMap = m_glyphes[key];
- for (unsigned int i = 0; i < size; ++i)
- PrecacheGlyph(glyphMap, characterSize, style, characters[i]);
+ for (char32_t character : set)
+ PrecacheGlyph(glyphMap, characterSize, style, character);
return true;
}
diff --git a/src/Nazara/Utility/Loaders/FreeType/Loader.cpp b/src/Nazara/Utility/Loaders/FreeType/Loader.cpp
index 70f65bc89..b16c89d02 100644
--- a/src/Nazara/Utility/Loaders/FreeType/Loader.cpp
+++ b/src/Nazara/Utility/Loaders/FreeType/Loader.cpp
@@ -212,12 +212,12 @@ namespace
bool HasKerning() const override
{
- return FT_HAS_KERNING(m_face);
+ return FT_HAS_KERNING(m_face) != 0;
}
bool IsScalable() const override
{
- return FT_IS_SCALABLE(m_face);
+ return FT_IS_SCALABLE(m_face) != 0;
}
bool Open()
diff --git a/src/Nazara/Utility/Loaders/MD2/Loader.cpp b/src/Nazara/Utility/Loaders/MD2/Loader.cpp
index f32490751..2b32eee17 100644
--- a/src/Nazara/Utility/Loaders/MD2/Loader.cpp
+++ b/src/Nazara/Utility/Loaders/MD2/Loader.cpp
@@ -220,11 +220,12 @@ namespace
vertexMapper.Unmap();
- subMesh->GenerateAABB();
- subMesh->GenerateTangents();
subMesh->SetIndexBuffer(indexBuffer);
subMesh->SetMaterialIndex(0);
+ subMesh->GenerateAABB();
+ subMesh->GenerateTangents();
+
mesh->AddSubMesh(subMesh);
if (parameters.center)
diff --git a/src/Nazara/Utility/Node.cpp b/src/Nazara/Utility/Node.cpp
index 2d7661e7a..aea97ce63 100644
--- a/src/Nazara/Utility/Node.cpp
+++ b/src/Nazara/Utility/Node.cpp
@@ -41,7 +41,12 @@ m_transformMatrixUpdated(false)
NzNode::~NzNode()
{
for (NzNode* child : m_childs)
- child->SetParent(nullptr);
+ {
+ // child->SetParent(nullptr); serait problématique car elle nous appellerait
+ child->m_parent = nullptr;
+ child->InvalidateNode();
+ child->OnParenting(nullptr);
+ }
SetParent(nullptr);
}
diff --git a/src/Nazara/Utility/SimpleTextDrawer.cpp b/src/Nazara/Utility/SimpleTextDrawer.cpp
index dc5e50dd0..020ad021d 100644
--- a/src/Nazara/Utility/SimpleTextDrawer.cpp
+++ b/src/Nazara/Utility/SimpleTextDrawer.cpp
@@ -192,9 +192,8 @@ void NzSimpleTextDrawer::UpdateGlyphs() const
return;
///TODO: Itération UTF-8 => UTF-32 sans allocation de buffer (Exposer utf8cpp ?)
- unsigned int size;
- std::unique_ptr characters(m_text.GetUtf32Buffer(&size));
- if (!characters)
+ std::u32string characters = m_text.GetUtf32String();
+ if (characters.empty())
{
NazaraError("Invalid character set");
return;
@@ -208,12 +207,11 @@ void NzSimpleTextDrawer::UpdateGlyphs() const
// On calcule les bornes en flottants pour accélérer les calculs (il est coûteux de changer de type trop souvent)
bool firstGlyph = true;
NzRectf textBounds = NzRectf::Zero();
- m_glyphs.reserve(size);
nzUInt32 previousCharacter = 0;
- for (unsigned int i = 0; i < size; ++i)
- {
- char32_t character = characters[i];
+ m_glyphs.reserve(characters.size());
+ for (char32_t character : characters)
+ {
if (previousCharacter != 0)
drawPos.x += m_font->GetKerning(m_characterSize, previousCharacter, character);
@@ -291,12 +289,12 @@ void NzSimpleTextDrawer::UpdateGlyphs() const
firstGlyph = false;
}
- for (unsigned int j = 0; j < 4; ++j)
- textBounds.ExtendTo(glyph.corners[j]);
+ for (unsigned int i = 0; i < 4; ++i)
+ textBounds.ExtendTo(glyph.corners[i]);
drawPos.x += advance;
m_glyphs.push_back(glyph);
}
- m_bounds.Set(std::floor(textBounds.x), std::floor(textBounds.y), std::ceil(textBounds.width), std::ceil(textBounds.height));
+ m_bounds.Set(NzRectf(std::floor(textBounds.x), std::floor(textBounds.y), std::ceil(textBounds.width), std::ceil(textBounds.height)));
}
diff --git a/src/Nazara/Utility/Win32/CursorImpl.cpp b/src/Nazara/Utility/Win32/CursorImpl.cpp
index 1b5f2ddf1..c772c1035 100644
--- a/src/Nazara/Utility/Win32/CursorImpl.cpp
+++ b/src/Nazara/Utility/Win32/CursorImpl.cpp
@@ -5,6 +5,7 @@
#include
#include
#include
+#include
#include
bool NzCursorImpl::Create(const NzImage& cursor, int hotSpotX, int hotSpotY)
diff --git a/src/Nazara/Utility/Win32/IconImpl.cpp b/src/Nazara/Utility/Win32/IconImpl.cpp
index 078a9fece..d4b6970bd 100644
--- a/src/Nazara/Utility/Win32/IconImpl.cpp
+++ b/src/Nazara/Utility/Win32/IconImpl.cpp
@@ -4,6 +4,7 @@
#include
#include
+#include
#include
bool NzIconImpl::Create(const NzImage& icon)
diff --git a/src/Nazara/Utility/Win32/WindowImpl.cpp b/src/Nazara/Utility/Win32/WindowImpl.cpp
index e1690def1..0119ccb2a 100644
--- a/src/Nazara/Utility/Win32/WindowImpl.cpp
+++ b/src/Nazara/Utility/Win32/WindowImpl.cpp
@@ -27,7 +27,7 @@
#define GWL_USERDATA GWLP_USERDATA
#endif
-// N'est pas définit avec MinGW
+// N'est pas défini avec MinGW
#ifndef MAPVK_VK_TO_VSC
#define MAPVK_VK_TO_VSC 0
#endif
@@ -145,8 +145,6 @@ bool NzWindowImpl::Create(const NzVideoMode& mode, const NzString& title, nzUInt
m_callback = 0;
- std::unique_ptr wtitle(title.GetWideBuffer());
-
#if NAZARA_UTILITY_THREADED_WINDOW
NzMutex mutex;
NzConditionVariable condition;
@@ -154,15 +152,18 @@ bool NzWindowImpl::Create(const NzVideoMode& mode, const NzString& title, nzUInt
// On attend que la fenêtre soit créée
mutex.Lock();
- m_thread = new NzThread(WindowThread, &m_handle, win32StyleEx, wtitle.get(), win32Style, x, y, width, height, this, &mutex, &condition);
+ m_thread = NzThread(WindowThread, &m_handle, win32StyleEx, title.GetWideString().data(), win32Style, x, y, width, height, this, &mutex, &condition);
condition.Wait(&mutex);
mutex.Unlock();
#else
- m_handle = CreateWindowExW(win32StyleEx, className, wtitle.get(), win32Style, x, y, width, height, nullptr, nullptr, GetModuleHandle(nullptr), this);
+ m_handle = CreateWindowExW(win32StyleEx, className, title.GetWideString().data(), win32Style, x, y, width, height, nullptr, nullptr, GetModuleHandle(nullptr), this);
#endif
if (!m_handle)
+ {
+ NazaraError("Failed to create window: " + NzError::GetLastSystemError());
return false;
+ }
if (fullscreen)
{
@@ -220,13 +221,12 @@ void NzWindowImpl::Destroy()
if (m_ownsWindow)
{
#if NAZARA_UTILITY_THREADED_WINDOW
- if (m_thread)
+ if (m_thread.IsJoinable())
{
m_threadActive = false;
PostMessageW(m_handle, WM_NULL, 0, 0); // Pour réveiller le thread
- m_thread->Join();
- delete m_thread;
+ m_thread.Join();
}
#else
if (m_handle)
@@ -445,8 +445,7 @@ void NzWindowImpl::SetStayOnTop(bool stayOnTop)
void NzWindowImpl::SetTitle(const NzString& title)
{
- std::unique_ptr wTitle(title.GetWideBuffer());
- SetWindowTextW(m_handle, wTitle.get());
+ SetWindowTextW(m_handle, title.GetWideString().data());
}
void NzWindowImpl::SetVisible(bool visible)
@@ -1192,6 +1191,6 @@ void NzWindowImpl::WindowThread(HWND* handle, DWORD styleEx, const wchar_t* titl
while (window->m_threadActive)
window->ProcessEvents(true);
- DestroyWindow(*handle);
+ DestroyWindow(winHandle);
}
#endif
diff --git a/src/Nazara/Utility/Win32/WindowImpl.hpp b/src/Nazara/Utility/Win32/WindowImpl.hpp
index 309cd20e7..472930b25 100644
--- a/src/Nazara/Utility/Win32/WindowImpl.hpp
+++ b/src/Nazara/Utility/Win32/WindowImpl.hpp
@@ -11,6 +11,7 @@
#include
#include
+#include
#include
#include
#include
@@ -22,7 +23,6 @@
#if NAZARA_UTILITY_THREADED_WINDOW
class NzConditionVariable;
class NzMutex;
-class NzThread;
#endif
class NzWindow;
@@ -95,7 +95,7 @@ class NzWindowImpl : NzNonCopyable
NzVector2i m_position;
NzVector2ui m_size;
#if NAZARA_UTILITY_THREADED_WINDOW
- NzThread* m_thread;
+ NzThread m_thread;
#endif
NzWindow* m_parent;
bool m_eventListener;