Merge branch 'master' into NDK
Former-commit-id: f118c029ca94296495957816f910d412ae8a56f2
This commit is contained in:
commit
5c3720feb1
|
|
@ -18,13 +18,23 @@ SDK/lib/NazaraSDK*.so
|
|||
# CodeLite
|
||||
*.project
|
||||
|
||||
# Visual Studio
|
||||
*.filters
|
||||
*.vcxproj
|
||||
*.tlog
|
||||
*.sln
|
||||
*.vcxprojResolveAssemblyReference.cache
|
||||
*.exp
|
||||
|
||||
# Compiled Object files
|
||||
*.slo
|
||||
*.lo
|
||||
*.o
|
||||
*.obj
|
||||
|
||||
# Compiled Dynamic libraries
|
||||
*.so
|
||||
*.lib
|
||||
|
||||
# Compiled Static libraries
|
||||
*.lai
|
||||
|
|
|
|||
|
|
@ -0,0 +1,239 @@
|
|||
function PrintTable ( t, indent, done )
|
||||
done = done or {}
|
||||
indent = indent or 0
|
||||
|
||||
local txt = {}
|
||||
for key, value in pairs (t) do
|
||||
table.insert(txt, string.rep (" ", indent))
|
||||
if (type(value) == "table" and not done[value]) then
|
||||
done [value] = true
|
||||
table.insert(txt, tostring(key) .. ":" .. "\n")
|
||||
table.insert(txt, PrintTable (value, indent + 2, done))
|
||||
else
|
||||
table.insert(txt, tostring (key) .. "\t=\t" )
|
||||
table.insert(txt, tostring(value) .. "\n" )
|
||||
end
|
||||
end
|
||||
|
||||
return table.concat(txt)
|
||||
end
|
||||
|
||||
Feature = {}
|
||||
|
||||
-- Tables de vérité
|
||||
local andTable =
|
||||
{
|
||||
{0,0},
|
||||
{0,1},
|
||||
}
|
||||
local orTable =
|
||||
{
|
||||
{0,1},
|
||||
{1,1},
|
||||
}
|
||||
|
||||
local xorTable =
|
||||
{
|
||||
{0,1},
|
||||
{1,0},
|
||||
}
|
||||
|
||||
local bitFunc = function (a, b, truthTable)
|
||||
local power = 1
|
||||
local c = 0
|
||||
while (a > 0 or b > 0) do
|
||||
c = c + (truthTable[(a % 2)+1][(b % 2)+1] * power)
|
||||
a = math.floor(a/2)
|
||||
b = math.floor(b/2)
|
||||
power = power * 2
|
||||
end
|
||||
|
||||
return c
|
||||
end
|
||||
|
||||
function Feature.AND(a, b)
|
||||
return bitFunc(a, b, andTable)
|
||||
end
|
||||
|
||||
function Feature.OR(a, b)
|
||||
return bitFunc(a, b, orTable)
|
||||
end
|
||||
|
||||
function Feature.XOR(a, b)
|
||||
return bitFunc(a, b, xorTable)
|
||||
end
|
||||
|
||||
Feature.NotApplicable = 0
|
||||
Feature.Windows = 2 ^ 0
|
||||
Feature.Linux = 2 ^ 1
|
||||
Feature.MacOSX = 2 ^ 2
|
||||
Feature.RaspberryPi = 2 ^ 3
|
||||
Feature.POSIX = Feature.Linux + Feature.MacOSX + Feature.RaspberryPi
|
||||
|
||||
function Feature.CompleteData(tab, requiredPortability)
|
||||
if (not requiredPortability) then
|
||||
assert(tab.RequiredPortability)
|
||||
requiredPortability = tab.RequiredPortability
|
||||
elseif (tab.RequiredPortability) then
|
||||
requiredPortability = Feature.OR(requiredPortability, tab.RequiredPortability)
|
||||
end
|
||||
|
||||
tab.RequiredPortability = requiredPortability
|
||||
|
||||
if (not tab.Portability) then
|
||||
tab.Portability = Feature.NotApplicable
|
||||
end
|
||||
|
||||
if (tab.Features) then
|
||||
local acc = 0
|
||||
for k,v in pairs(tab.Features) do
|
||||
if (type(v) == "string") then
|
||||
v = {Title = v}
|
||||
tab.Features[k] = v
|
||||
end
|
||||
|
||||
Feature.CompleteData(v, requiredPortability)
|
||||
|
||||
v.Progress = v.Progress or 100
|
||||
|
||||
acc = acc + v.Progress
|
||||
end
|
||||
|
||||
tab.Progress = acc/#tab.Features
|
||||
end
|
||||
end
|
||||
|
||||
function Feature.Generate()
|
||||
local files = os.matchfiles("scripts/features/*.lua")
|
||||
|
||||
local modules = {}
|
||||
|
||||
for k, filePath in pairs(files) do
|
||||
local moduleName = filePath:match(".*/(.*).lua")
|
||||
|
||||
local data = dofile(filePath)
|
||||
Feature.CompleteData(data)
|
||||
|
||||
modules[moduleName] = data
|
||||
end
|
||||
|
||||
local content = {}
|
||||
|
||||
local contentType =
|
||||
{
|
||||
["(%s*)%%MODULELIST%%"] = Feature.GenerateModuleList,
|
||||
["(%s*)%%MODULEDESCRIPTION%%"] = Feature.GenerateModuleDescriptions,
|
||||
["(%s*)%%DATE%%"] = function (dontcare, space, content)
|
||||
table.insert(content, string.format("%s%s", space, os.date("%d/%m/%Y")))
|
||||
end,
|
||||
}
|
||||
|
||||
local index = io.open("scripts/features/index_template.html")
|
||||
for line in index:lines() do
|
||||
local matched = false
|
||||
for k,v in pairs(contentType) do
|
||||
local space = line:match(k)
|
||||
if (space) then
|
||||
matched = true
|
||||
v(modules, space, content)
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
if (not matched) then
|
||||
table.insert(content, line)
|
||||
end
|
||||
end
|
||||
|
||||
io.open("scripts/features/index.html", "w+"):write(table.concat(content, "\n"))
|
||||
end
|
||||
|
||||
function Feature.Interpolate(from, to, p)
|
||||
return from + (to - from)*p
|
||||
end
|
||||
|
||||
function Feature.ComputeColor(progress)
|
||||
local stable = {0, 200, 0}
|
||||
local partial = {255, 127, 0}
|
||||
local unusable = {255, 0, 0}
|
||||
|
||||
local a, b, p
|
||||
if (progress < 20) then
|
||||
a = unusable
|
||||
b = partial
|
||||
p = progress/20.0
|
||||
else
|
||||
a = partial
|
||||
b = stable
|
||||
p = math.min(20 * 1.020321705^(progress - 20), 100.0)/100.0 -- Je me complique certainement la vie pour ce qui est d'avoir une interpolation exponentielle, mais ça remonte tout ça ...
|
||||
end
|
||||
|
||||
local color = {nil, nil, nil}
|
||||
for i = 1, 3 do
|
||||
color[i] = Feature.Interpolate(a[i], b[i], p)
|
||||
end
|
||||
|
||||
return color
|
||||
end
|
||||
|
||||
function Feature.GenerateModuleList(modules, space, content)
|
||||
for k,v in pairs(modules) do
|
||||
local c = Feature.ComputeColor(v.Progress)
|
||||
|
||||
table.insert(content, string.format([[%s<tr>]], space))
|
||||
table.insert(content, string.format([[%s <td><a href="#%s">%s</a></td>]], space, k, v.Title))
|
||||
table.insert(content, string.format([[%s <td style="color: rgb(%d, %d, %d);">%d%%</td>]], space, c[1], c[2], c[3], v.Progress))
|
||||
table.insert(content, string.format([[%s</tr>]], space))
|
||||
end
|
||||
end
|
||||
|
||||
function Feature.GenerateModuleDescriptions(modules, space, content)
|
||||
for k,v in pairs(modules) do
|
||||
table.insert(content, string.format([[%s<div class="module">]], space))
|
||||
table.insert(content, string.format([[%s <hr />]], space, k, v.Title))
|
||||
table.insert(content, string.format([[%s <span id="%s" class="modulename">%s (%s) : %d%%</span>]], space, k, v.Title, v.LibName, math.floor(v.Progress)))
|
||||
|
||||
table.insert(content, string.format([[%s <h4>Fonctionnalités:</h4>]], space))
|
||||
Feature.GenerateFeatureList(v.Features, space .. "\t\t", content)
|
||||
|
||||
table.insert(content, string.format([[%s</div>]], space))
|
||||
end
|
||||
end
|
||||
|
||||
function Feature.GenerateFeatureList(featureTable, space, content)
|
||||
table.insert(content, string.format("%s<ul>", 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 <li>", space))
|
||||
table.insert(content, string.format([[%s <span style="color: rgb(%d, %d, %d);">%s%s</span>]], space, c[1], c[2], c[3], v.Title, desc))
|
||||
|
||||
if (v.Description) then
|
||||
table.insert(content, string.format([[%s <br><span class="description">%s</span>]], 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 <br><span class="note">Note: <span class="notedesc">%s</span></span>]], 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 <br><span class="portability">Il manque une implémentation sur au moins un des OS supportés</span>]], space))
|
||||
end
|
||||
|
||||
table.insert(content, string.format("%s </li>", space))
|
||||
end
|
||||
table.insert(content, string.format("%s</ul>", space))
|
||||
end
|
||||
|
||||
newaction
|
||||
{
|
||||
trigger = "generatefeatures",
|
||||
description = "Generate a web page describing each module's feature",
|
||||
execute = Feature.Generate
|
||||
}
|
||||
|
|
@ -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"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,75 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<link rel="stylesheet" href="style.css" />
|
||||
<title>Avancement de Nazara</title>
|
||||
</head>
|
||||
<body>
|
||||
<p class="centre">
|
||||
<img src="https://github.com/DigitalPulseSoftware/NazaraEngine/raw/master/Logo.png" alt="Nazara Engine" />
|
||||
<br>
|
||||
<br>
|
||||
Retrouvez le moteur sur GitHub !
|
||||
<br>
|
||||
<a href="https://github.com/DigitalPulseSoftware/NazaraEngine">Dépôt Github</a><br><br>
|
||||
Ou venez vous renseigner sur les topics dédiés à Nazara présents sur plusieurs site webs:
|
||||
<br>
|
||||
<a href="http://openclassrooms.com/forum/sujet/moteur-de-jeu-nazara-engine-69732">OpenClassrooms</a> ou <a href="http://pdp.microjoe.org/forums/sujet/354/projet-nazara-engine-moteur-de-jeu">Progdupeupl</a> ou <a href="http://zestedesavoir.com/forums/sujet/1039/nazara-engine">ZesteDeSavoir</a>
|
||||
<br>
|
||||
<br>
|
||||
... ou pourquoi ne pas venir faire un tour sur <a href="http://forum.digitalpulsesoftware.com">le forum dédié au moteur</a> ?
|
||||
</p>
|
||||
<div class="centre">
|
||||
<h1>Fonctionnalités de Nazara</h1>
|
||||
<br>
|
||||
Dernière mise à jour:
|
||||
<span class="lastupdate">
|
||||
%DATE%
|
||||
</span>
|
||||
<br>
|
||||
<br>
|
||||
<h2>Important:</h2><br>
|
||||
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.<br>
|
||||
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.<br>
|
||||
Gardez donc à l'esprit que le moteur possède plus de fonctionnalités que ce qui est décrit actuellement sur cette page.<br>
|
||||
<br>
|
||||
Oh et bien sûr je ne suis pas concepteur de site web, c'est pourquoi cette page est moche (j'ai <u>essayé</u> de minimiser les dégats).<br>
|
||||
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).
|
||||
<br>
|
||||
<br>
|
||||
Le pourcentage indiqué est calculé automatiquement en fonction des <u>fonctionnalités</u>,<br>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,<br><u>cela n'est donc pas une assurance qu'aucun bug n'existe concernant cette fonctionnalité</u> (cependant cela signifie que la fonctionnalité est utilisable).<br>
|
||||
Et bien entendu, un module ou une fonctionnalité ayant atteint les 100% peut toujours évoluer par la suite.
|
||||
<br>
|
||||
<br>
|
||||
<table>
|
||||
<caption>Sommaire</caption>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Module</th>
|
||||
<th>Avancement</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
%MODULELIST%
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
%MODULEDESCRIPTION%
|
||||
<hr />
|
||||
<div class="centre">
|
||||
<table>
|
||||
<caption>Sommaire</caption>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Module</th>
|
||||
<th>Pourcentage</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
%MODULELIST%
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -8,6 +8,7 @@
|
|||
template<typename T>
|
||||
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<std::is_unsigned<T>::value, nzUInt64, nzInt64>::type BiggestInt;
|
||||
typedef typename std::conditional<std::is_integral<T>::value, BiggestInt, double>::type Biggest;
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@
|
|||
/// Ce fichier sert à vérifier la valeur des constantes du fichier Config.hpp
|
||||
|
||||
#include <type_traits>
|
||||
#define CheckTypeAndVal(name, type, op, val, err) static_assert(std::is_ ##type <decltype(name)>::value && name op val, #type err)
|
||||
#define NazaraCheckTypeAndVal(name, type, op, val, err) static_assert(std::is_ ##type <decltype(name)>::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
|
||||
|
|
|
|||
|
|
@ -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 <Nazara/Prerequesites.hpp>
|
||||
#include <functional>
|
||||
#include <tuple>
|
||||
|
||||
template<typename T> void NzHashCombine(std::size_t& seed, const T& v);
|
||||
template<typename F, typename... ArgsT> void NzUnpackTuple(F func, const std::tuple<ArgsT...>& t);
|
||||
|
||||
#include <Nazara/Core/Tuple.inl>
|
||||
#include <Nazara/Core/Algorithm.inl>
|
||||
|
||||
#endif // NAZARA_TUPLE_HPP
|
||||
#endif // NAZARA_ALGORITHM_CORE_HPP
|
||||
|
|
@ -8,6 +8,8 @@
|
|||
|
||||
#include <Nazara/Core/Debug.hpp>
|
||||
|
||||
///TODO: Améliorer l'implémentation de UnpackTuple
|
||||
|
||||
template<unsigned int N>
|
||||
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<typename T>
|
||||
void NzHashCombine(std::size_t& seed, const T& v)
|
||||
{
|
||||
const nzUInt64 kMul = 0x9ddfea08eb382d69ULL;
|
||||
|
||||
std::hash<T> hasher;
|
||||
nzUInt64 a = (hasher(v) ^ seed) * kMul;
|
||||
a ^= (a >> 47);
|
||||
|
||||
nzUInt64 b = (seed ^ a) * kMul;
|
||||
b ^= (b >> 47);
|
||||
|
||||
seed = static_cast<std::size_t>(b * kMul);
|
||||
}
|
||||
|
||||
template<typename F, typename... ArgsT>
|
||||
void NzUnpackTuple(F func, const std::tuple<ArgsT...>& t)
|
||||
{
|
||||
|
|
@ -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<unsigned int>(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)));
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@
|
|||
/// Ce fichier sert à vérifier la valeur des constantes du fichier Config.hpp
|
||||
|
||||
#include <type_traits>
|
||||
#define CheckTypeAndVal(name, type, op, val, err) static_assert(std::is_ ##type <decltype(name)>::value && name op val, #type err)
|
||||
#define NazaraCheckTypeAndVal(name, type, op, val, err) static_assert(std::is_ ##type <decltype(name)>::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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
#ifndef NAZARA_FUNCTOR_HPP
|
||||
#define NAZARA_FUNCTOR_HPP
|
||||
|
||||
#include <Nazara/Core/Tuple.hpp>
|
||||
#include <Nazara/Core/Algorithm.hpp>
|
||||
|
||||
// Inspiré du code de la SFML par Laurent Gomila
|
||||
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -13,6 +13,8 @@
|
|||
#include <set>
|
||||
#include <unordered_map>
|
||||
|
||||
///TODO: Révision
|
||||
|
||||
class NzDynLib;
|
||||
|
||||
class NAZARA_API NzPluginManager
|
||||
|
|
|
|||
|
|
@ -50,8 +50,6 @@ class NAZARA_API NzRefCounted
|
|||
private:
|
||||
using ObjectListenerMap = std::unordered_map<NzObjectListener*, std::pair<int, unsigned int>>;
|
||||
|
||||
void RemoveObjectListenerIterator(ObjectListenerMap::iterator iterator) const;
|
||||
|
||||
NazaraMutexAttrib(m_mutex, mutable)
|
||||
|
||||
mutable ObjectListenerMap m_objectListeners;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@
|
|||
#include <Nazara/Prerequesites.hpp>
|
||||
#include <Nazara/Core/Functor.hpp>
|
||||
#include <Nazara/Core/NonCopyable.hpp>
|
||||
#include <ostream>
|
||||
#include <iosfwd>
|
||||
|
||||
class NzThreadImpl;
|
||||
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@
|
|||
/// Ce fichier sert à vérifier la valeur des constantes du fichier Config.hpp
|
||||
|
||||
#include <type_traits>
|
||||
#define CheckTypeAndVal(name, type, op, val, err) static_assert(std::is_ ##type <decltype(name)>::value && name op val, #type err)
|
||||
#define NazaraCheckTypeAndVal(name, type, op, val, err) static_assert(std::is_ ##type <decltype(name)>::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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@
|
|||
#include <Nazara/Graphics/ParticleRenderer.hpp>
|
||||
#include <Nazara/Graphics/SceneNode.hpp>
|
||||
#include <Nazara/Math/BoundingVolume.hpp>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <set>
|
||||
#include <vector>
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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<typename T>
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@
|
|||
/// Ce fichier sert à vérifier la valeur des constantes du fichier Config.hpp
|
||||
|
||||
#include <type_traits>
|
||||
#define CheckTypeAndVal(name, type, op, val, err) static_assert(std::is_ ##type <decltype(name)>::value && name op val, #type err)
|
||||
#define NazaraCheckTypeAndVal(name, type, op, val, err) static_assert(std::is_ ##type <decltype(name)>::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
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@
|
|||
/// Ce fichier sert à vérifier la valeur des constantes du fichier Config.hpp
|
||||
|
||||
#include <type_traits>
|
||||
#define CheckTypeAndVal(name, type, op, val, err) static_assert(std::is_ ##type <decltype(name)>::value && name op val, #type err)
|
||||
#define NazaraCheckTypeAndVal(name, type, op, val, err) static_assert(std::is_ ##type <decltype(name)>::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
|
||||
|
|
|
|||
|
|
@ -48,7 +48,6 @@ struct NAZARA_API NzMeshParams
|
|||
bool IsValid() const;
|
||||
};
|
||||
|
||||
class NzAnimation;
|
||||
class NzMesh;
|
||||
class NzPrimitiveList;
|
||||
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#include <Nazara/Core/Error.hpp>
|
||||
#include <algorithm>
|
||||
#include <cstring>
|
||||
#include <Nazara/Utility/Debug.hpp>
|
||||
|
||||
|
|
|
|||
|
|
@ -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<NzFile> 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<nzInt16*>(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<sndfileStream> 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<sndfileStream> 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<sndfileStream> 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<unsigned int>(info.frames * info.channels);
|
||||
std::unique_ptr<nzInt16[]> 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<nzInt16[]> 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<unsigned int>(info.channels), static_cast<unsigned int>(info.frames));
|
||||
|
||||
format = nzAudioFormat_Mono;
|
||||
samples = std::move(monoSamples);
|
||||
sampleCount = info.frames;
|
||||
sampleCount = static_cast<unsigned int>(info.frames);
|
||||
}
|
||||
|
||||
if (!soundBuffer->Create(format, static_cast<unsigned int>(sampleCount), info.samplerate, samples.get()))
|
||||
if (!soundBuffer->Create(format, sampleCount, info.samplerate, samples.get()))
|
||||
{
|
||||
NazaraError("Failed to create sound buffer");
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -733,7 +733,7 @@ bool NzFile::FillHash(NzAbstractHash* hash) const
|
|||
unsigned int size;
|
||||
while (remainingSize > 0)
|
||||
{
|
||||
size = std::min(remainingSize, static_cast<nzUInt64>(NAZARA_CORE_FILE_BUFFERSIZE));
|
||||
size = static_cast<unsigned int>(std::min(remainingSize, static_cast<nzUInt64>(NAZARA_CORE_FILE_BUFFERSIZE)));
|
||||
if (file.Read(&buffer[0], sizeof(char), size) != sizeof(char)*size)
|
||||
{
|
||||
NazaraError("Unable to read file");
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@
|
|||
#include <Nazara/Core/GuillotineBinPack.hpp>
|
||||
#include <Nazara/Core/Config.hpp>
|
||||
#include <algorithm>
|
||||
#include <cstdlib>
|
||||
#include <cmath>
|
||||
#include <limits>
|
||||
#include <Nazara/Core/Debug.hpp>
|
||||
|
|
@ -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<int>(freeRectSize.width - width));
|
||||
int leftoverVert = std::abs(static_cast<int>(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<int>(freeRectSize.width - width));
|
||||
int leftoverVert = std::abs(static_cast<int>(freeRectSize.height - height));
|
||||
int leftover = std::min(leftoverHoriz, leftoverVert);
|
||||
|
||||
return leftover;
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
#include <Nazara/Core/HardwareInfo.hpp>
|
||||
#include <Nazara/Core/Error.hpp>
|
||||
#include <algorithm>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
|
||||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -5,9 +5,9 @@
|
|||
#include <Nazara/Core/HashDigest.hpp>
|
||||
#include <Nazara/Core/Config.hpp>
|
||||
#include <Nazara/Core/Error.hpp>
|
||||
#include <algorithm>
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
#include <utility>
|
||||
#include <Nazara/Core/Debug.hpp>
|
||||
|
||||
NzHashDigest::NzHashDigest() :
|
||||
|
|
|
|||
|
|
@ -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<float>(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<float>(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<int>(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<int>::max() && converted >= std::numeric_limits<int>::min())
|
||||
{
|
||||
*value = converted;
|
||||
*value = static_cast<int>(converted);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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<char16_t> 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<const char*> it(m_sharedString->string);
|
||||
do
|
||||
{
|
||||
char32_t cp = *it;
|
||||
if (cp <= 0xFFFF && (cp < 0xD800 || cp > 0xDFFF)) // @Laurent Gomila
|
||||
*ptr++ = static_cast<wchar_t>(cp);
|
||||
str.push_back(static_cast<wchar_t>(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();
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@
|
|||
#include <Nazara/Core/Config.hpp>
|
||||
#include <Nazara/Core/Error.hpp>
|
||||
#include <Nazara/Core/HardwareInfo.hpp>
|
||||
#include <ostream>
|
||||
#include <stdexcept>
|
||||
|
||||
#if defined(NAZARA_PLATFORM_WINDOWS)
|
||||
|
|
|
|||
|
|
@ -62,9 +62,7 @@ bool NzDirectoryImpl::Open(const NzString& dirPath)
|
|||
{
|
||||
NzString searchPath = dirPath + "\\*";
|
||||
|
||||
std::unique_ptr<wchar_t[]> 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<wchar_t[]> 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<wchar_t[]> 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<wchar_t[]> 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;
|
||||
|
|
|
|||
|
|
@ -30,9 +30,7 @@ bool NzDynLibImpl::Load(const NzString& libraryPath, NzString* errorMessage)
|
|||
if (!path.EndsWith(".dll"))
|
||||
path += ".dll";
|
||||
|
||||
std::unique_ptr<wchar_t[]> 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
|
||||
|
|
|
|||
|
|
@ -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<wchar_t[]> 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<wchar_t[]> srcPath(sourcePath.GetWideBuffer());
|
||||
std::unique_ptr<wchar_t[]> 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<wchar_t[]> 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<wchar_t[]> 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<wchar_t[]> 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<wchar_t[]> 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<wchar_t[]> 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<wchar_t[]> 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<wchar_t[]> srcPath(sourcePath.GetWideBuffer());
|
||||
std::unique_ptr<wchar_t[]> 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
|
||||
{
|
||||
|
|
|
|||
|
|
@ -12,15 +12,18 @@
|
|||
|
||||
#include <Nazara/Core/Debug.hpp>
|
||||
|
||||
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<int*>(result), static_cast<int>(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<int*>(registers), static_cast<int>(functionId), static_cast<int>(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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -3,6 +3,8 @@
|
|||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#include <Nazara/Graphics/Loaders/OBJ.hpp>
|
||||
#include <Nazara/Core/Algorithm.hpp>
|
||||
#include <Nazara/Core/ErrorFlags.hpp>
|
||||
#include <Nazara/Graphics/Material.hpp>
|
||||
#include <Nazara/Graphics/Model.hpp>
|
||||
#include <Nazara/Graphics/Loaders/OBJ/MTLParser.hpp>
|
||||
|
|
@ -16,6 +18,8 @@
|
|||
#include <unordered_map>
|
||||
#include <Nazara/Graphics/Debug.hpp>
|
||||
|
||||
///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<NzString, NzMaterialRef> 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<nzUInt8>(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<unsigned int> 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<unsigned int> 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<unsigned int> 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<int, std::unordered_map<int, std::unordered_map<int, unsigned int>>> 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<NzOBJParser::FaceVertex, unsigned int, FaceVertexHasher, FaceVertexComparator> 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<NzVertexBuffer> vertexMapper(vertexBuffer, nzBufferAccess_WriteOnly);
|
||||
NzMeshVertex* meshVertices = static_cast<NzMeshVertex*>(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<NzString, NzMaterialRef> 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<nzUInt8>(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;
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
#include <Nazara/Core/Error.hpp>
|
||||
#include <Nazara/Core/Log.hpp>
|
||||
#include <Nazara/Utility/Config.hpp>
|
||||
#include <cstdio>
|
||||
#include <cctype>
|
||||
#include <memory>
|
||||
#include <unordered_map>
|
||||
#include <Nazara/Graphics/Debug.hpp>
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -333,6 +333,7 @@ bool NzTextSprite::OnAtlasLayerChange(const NzAbstractAtlas* atlas, NzAbstractIm
|
|||
NzTexture* oldTexture = static_cast<NzTexture*>(oldLayer);
|
||||
NzTexture* newTexture = static_cast<NzTexture*>(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<NzVector2f> 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();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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<int>(( normalized.x + 1.f) * viewport.width / 2.f + viewport.x);
|
||||
pixel.y = static_cast<int>((-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<float>(m_viewport.width), 0.f, static_cast<float>(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();
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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<char32_t[]> 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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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<char32_t[]> 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)));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
#include <Nazara/Utility/Win32/CursorImpl.hpp>
|
||||
#include <Nazara/Core/Error.hpp>
|
||||
#include <Nazara/Utility/Image.hpp>
|
||||
#include <Nazara/Utility/PixelFormat.hpp>
|
||||
#include <Nazara/Utility/Debug.hpp>
|
||||
|
||||
bool NzCursorImpl::Create(const NzImage& cursor, int hotSpotX, int hotSpotY)
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
#include <Nazara/Utility/Win32/IconImpl.hpp>
|
||||
#include <Nazara/Utility/Image.hpp>
|
||||
#include <Nazara/Utility/PixelFormat.hpp>
|
||||
#include <Nazara/Utility/Debug.hpp>
|
||||
|
||||
bool NzIconImpl::Create(const NzImage& icon)
|
||||
|
|
|
|||
|
|
@ -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<wchar_t[]> 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<wchar_t[]> 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
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@
|
|||
|
||||
#include <Nazara/Core/NonCopyable.hpp>
|
||||
#include <Nazara/Core/String.hpp>
|
||||
#include <Nazara/Core/Thread.hpp>
|
||||
#include <Nazara/Math/Vector2.hpp>
|
||||
#include <Nazara/Utility/Config.hpp>
|
||||
#include <Nazara/Utility/Keyboard.hpp>
|
||||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Reference in New Issue