Merge branch 'master' into NDK

Former-commit-id: f118c029ca94296495957816f910d412ae8a56f2
This commit is contained in:
Lynix
2015-03-18 20:44:52 +01:00
66 changed files with 1430 additions and 599 deletions

View File

@@ -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;

View File

@@ -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()

View File

@@ -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");

View 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;

View File

@@ -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, &registers[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;

View File

@@ -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() :

View File

@@ -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;
}
}

View File

@@ -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

View File

@@ -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();

View File

@@ -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)

View File

@@ -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;

View File

@@ -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

View File

@@ -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
{

View File

@@ -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
}

View File

@@ -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();
};

View File

@@ -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
*/

View File

@@ -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;

View File

@@ -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>

View File

@@ -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();
}

View File

@@ -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;

View File

@@ -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

View File

@@ -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();
}

View File

@@ -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();

View File

@@ -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);

View File

@@ -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);

View File

@@ -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;
}

View File

@@ -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()

View File

@@ -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)

View File

@@ -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);
}

View File

@@ -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)));
}

View File

@@ -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)

View File

@@ -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)

View File

@@ -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

View File

@@ -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;