Merge branch 'master' into NDK
Former-commit-id: f118c029ca94296495957816f910d412ae8a56f2
This commit is contained in:
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user