Added RenderTextures (And many others things)
-Added Forward, left and up vector (Vector3) -Added Matrix4::ConcatenateAffine shortcut -Added Quaternion::GetInverse() and Quaternion::Inverse() -Added Resource listeners -Added Depth and stencil pixel formats -All enums now have an ending "max" entry -Animation/Mesh::Add[Sequence/Skin/SubMesh] now returns a boolean -Contexts are now resources -Enhanced AnimatedMesh demo -Fixed MD2 facing -Fixed Vector3::CrossProduct -Made Resource thread-safe -Made OpenGL translation table global -Many bugfixes -MLT will now write malloc failure to the log -Most of the strcpy were replaced with faster memcpy -Occlusion queries availability is now always tested -OpenGL-related includes now requires NAZARA_RENDERER_OPENGL to be defined to have any effect -Pixel formats now have a type -Renamed RenderTarget::IsValid to IsRenderable -Renamed Quaternion::GetNormalized() to GetNormal() -Renamed Texture::Bind() to Prepare() -Renamed VectorX::Make[Ceil|Floor] to Maximize/Minimize -Removed MATH_MATRIX_COLUMN_MAJOR option (all matrices are column-major) -Removed RENDERER_ACTIVATE_RENDERWINDOW_ON_CREATION option (Render windows are active upon their creation) Former-commit-id: 0d1da1e32c156a958221edf04a5315c75b354450
This commit is contained in:
parent
a6ed70123b
commit
cd5a1b7a5e
|
|
@ -1,40 +1,42 @@
|
||||||
if (not _OPTIONS["one-library"]) then
|
if (not _OPTIONS["one-library"]) then
|
||||||
project "NazaraRenderer"
|
project "NazaraRenderer"
|
||||||
end
|
end
|
||||||
|
|
||||||
files
|
defines "NAZARA_RENDERER_OPENGL"
|
||||||
{
|
|
||||||
"../include/Nazara/Renderer/**.hpp",
|
files
|
||||||
"../include/Nazara/Renderer/**.inl",
|
{
|
||||||
"../src/Nazara/Renderer/**.hpp",
|
"../include/Nazara/Renderer/**.hpp",
|
||||||
"../src/Nazara/Renderer/**.cpp"
|
"../include/Nazara/Renderer/**.inl",
|
||||||
}
|
"../src/Nazara/Renderer/**.hpp",
|
||||||
|
"../src/Nazara/Renderer/**.cpp"
|
||||||
if (os.is("windows")) then
|
}
|
||||||
excludes { "../src/Nazara/Renderer/Posix/*.hpp", "../src/Nazara/Renderer/Posix/*.cpp" }
|
|
||||||
links "gdi32"
|
if (os.is("windows")) then
|
||||||
links "opengl32"
|
excludes { "../src/Nazara/Renderer/Posix/*.hpp", "../src/Nazara/Renderer/Posix/*.cpp" }
|
||||||
links "winmm"
|
links "gdi32"
|
||||||
else
|
links "opengl32"
|
||||||
excludes { "../src/Nazara/Renderer/Win32/*.hpp", "../src/Nazara/Renderer/Win32/*.cpp" }
|
links "winmm"
|
||||||
end
|
else
|
||||||
|
excludes { "../src/Nazara/Renderer/Win32/*.hpp", "../src/Nazara/Renderer/Win32/*.cpp" }
|
||||||
if (_OPTIONS["one-library"]) then
|
end
|
||||||
excludes "../src/Nazara/Renderer/Debug/Leaks.cpp"
|
|
||||||
else
|
if (_OPTIONS["one-library"]) then
|
||||||
configuration "DebugStatic"
|
excludes "../src/Nazara/Renderer/Debug/Leaks.cpp"
|
||||||
links "NazaraCore-s-d"
|
else
|
||||||
links "NazaraUtility-s-d"
|
configuration "DebugStatic"
|
||||||
|
links "NazaraCore-s-d"
|
||||||
configuration "ReleaseStatic"
|
links "NazaraUtility-s-d"
|
||||||
links "NazaraCore-s"
|
|
||||||
links "NazaraUtility-s"
|
configuration "ReleaseStatic"
|
||||||
|
links "NazaraCore-s"
|
||||||
configuration "DebugDLL"
|
links "NazaraUtility-s"
|
||||||
links "NazaraCore-d"
|
|
||||||
links "NazaraUtility-d"
|
configuration "DebugDLL"
|
||||||
|
links "NazaraCore-d"
|
||||||
configuration "ReleaseDLL"
|
links "NazaraUtility-d"
|
||||||
links "NazaraCore"
|
|
||||||
links "NazaraUtility"
|
configuration "ReleaseDLL"
|
||||||
|
links "NazaraCore"
|
||||||
|
links "NazaraUtility"
|
||||||
end
|
end
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -1,61 +1,62 @@
|
||||||
// This file was automatically generated by Nazara
|
// This file was automatically generated by Nazara
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Nazara Engine - Core module
|
Nazara Engine - Core module
|
||||||
|
|
||||||
Copyright (C) 2012 Jérôme "Lynix" Leclercq (Lynix680@gmail.com)
|
Copyright (C) 2012 Jérôme "Lynix" Leclercq (Lynix680@gmail.com)
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
this software and associated documentation files (the "Software"), to deal in
|
this software and associated documentation files (the "Software"), to deal in
|
||||||
the Software without restriction, including without limitation the rights to
|
the Software without restriction, including without limitation the rights to
|
||||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||||
of the Software, and to permit persons to whom the Software is furnished to do
|
of the Software, and to permit persons to whom the Software is furnished to do
|
||||||
so, subject to the following conditions:
|
so, subject to the following conditions:
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in all
|
The above copyright notice and this permission notice shall be included in all
|
||||||
copies or substantial portions of the Software.
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
SOFTWARE.
|
SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <Nazara/Core/ByteArray.hpp>
|
#include <Nazara/Core/ByteArray.hpp>
|
||||||
#include <Nazara/Core/Clock.hpp>
|
#include <Nazara/Core/Clock.hpp>
|
||||||
#include <Nazara/Core/Color.hpp>
|
#include <Nazara/Core/Color.hpp>
|
||||||
#include <Nazara/Core/ConditionVariable.hpp>
|
#include <Nazara/Core/ConditionVariable.hpp>
|
||||||
#include <Nazara/Core/Config.hpp>
|
#include <Nazara/Core/Config.hpp>
|
||||||
#include <Nazara/Core/Core.hpp>
|
#include <Nazara/Core/Core.hpp>
|
||||||
#include <Nazara/Core/Directory.hpp>
|
#include <Nazara/Core/Directory.hpp>
|
||||||
#include <Nazara/Core/DynLib.hpp>
|
#include <Nazara/Core/DynLib.hpp>
|
||||||
#include <Nazara/Core/Endianness.hpp>
|
#include <Nazara/Core/Endianness.hpp>
|
||||||
#include <Nazara/Core/Enums.hpp>
|
#include <Nazara/Core/Enums.hpp>
|
||||||
#include <Nazara/Core/Error.hpp>
|
#include <Nazara/Core/Error.hpp>
|
||||||
#include <Nazara/Core/File.hpp>
|
#include <Nazara/Core/File.hpp>
|
||||||
#include <Nazara/Core/Format.hpp>
|
#include <Nazara/Core/Format.hpp>
|
||||||
#include <Nazara/Core/Functor.hpp>
|
#include <Nazara/Core/Functor.hpp>
|
||||||
#include <Nazara/Core/Hash.hpp>
|
#include <Nazara/Core/Hash.hpp>
|
||||||
#include <Nazara/Core/Hashable.hpp>
|
#include <Nazara/Core/Hashable.hpp>
|
||||||
#include <Nazara/Core/HashDigest.hpp>
|
#include <Nazara/Core/HashDigest.hpp>
|
||||||
#include <Nazara/Core/HashImpl.hpp>
|
#include <Nazara/Core/HashImpl.hpp>
|
||||||
#include <Nazara/Core/Initializer.hpp>
|
#include <Nazara/Core/Initializer.hpp>
|
||||||
#include <Nazara/Core/InputStream.hpp>
|
#include <Nazara/Core/InputStream.hpp>
|
||||||
#include <Nazara/Core/LockGuard.hpp>
|
#include <Nazara/Core/LockGuard.hpp>
|
||||||
#include <Nazara/Core/Log.hpp>
|
#include <Nazara/Core/Log.hpp>
|
||||||
#include <Nazara/Core/MemoryStream.hpp>
|
#include <Nazara/Core/MemoryStream.hpp>
|
||||||
#include <Nazara/Core/Mutex.hpp>
|
#include <Nazara/Core/Mutex.hpp>
|
||||||
#include <Nazara/Core/NonCopyable.hpp>
|
#include <Nazara/Core/NonCopyable.hpp>
|
||||||
#include <Nazara/Core/Resource.hpp>
|
#include <Nazara/Core/Resource.hpp>
|
||||||
#include <Nazara/Core/ResourceLoader.hpp>
|
#include <Nazara/Core/ResourceListener.hpp>
|
||||||
#include <Nazara/Core/Semaphore.hpp>
|
#include <Nazara/Core/ResourceLoader.hpp>
|
||||||
#include <Nazara/Core/String.hpp>
|
#include <Nazara/Core/Semaphore.hpp>
|
||||||
#include <Nazara/Core/StringStream.hpp>
|
#include <Nazara/Core/String.hpp>
|
||||||
#include <Nazara/Core/Thread.hpp>
|
#include <Nazara/Core/StringStream.hpp>
|
||||||
#include <Nazara/Core/Tuple.hpp>
|
#include <Nazara/Core/Thread.hpp>
|
||||||
#include <Nazara/Core/Unicode.hpp>
|
#include <Nazara/Core/Tuple.hpp>
|
||||||
|
#include <Nazara/Core/Unicode.hpp>
|
||||||
|
|
|
||||||
|
|
@ -1,84 +1,85 @@
|
||||||
/*
|
/*
|
||||||
Nazara Engine - Core module
|
Nazara Engine - Core module
|
||||||
|
|
||||||
Copyright (C) 2012 Jérôme "Lynix" Leclercq (Lynix680@gmail.com)
|
Copyright (C) 2012 Jérôme "Lynix" Leclercq (Lynix680@gmail.com)
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
this software and associated documentation files (the "Software"), to deal in
|
this software and associated documentation files (the "Software"), to deal in
|
||||||
the Software without restriction, including without limitation the rights to
|
the Software without restriction, including without limitation the rights to
|
||||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||||
of the Software, and to permit persons to whom the Software is furnished to do
|
of the Software, and to permit persons to whom the Software is furnished to do
|
||||||
so, subject to the following conditions:
|
so, subject to the following conditions:
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in all
|
The above copyright notice and this permission notice shall be included in all
|
||||||
copies or substantial portions of the Software.
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
SOFTWARE.
|
SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#ifndef NAZARA_CONFIG_CORE_HPP
|
#ifndef NAZARA_CONFIG_CORE_HPP
|
||||||
#define NAZARA_CONFIG_CORE_HPP
|
#define NAZARA_CONFIG_CORE_HPP
|
||||||
|
|
||||||
/// Chaque modification d'un paramètre du module nécessite une recompilation de celui-ci
|
/// Chaque modification d'un paramètre du module nécessite une recompilation de celui-ci
|
||||||
|
|
||||||
// Appelle exit dès qu'une assertion est invalide
|
// Appelle exit dès qu'une assertion est invalide
|
||||||
#define NAZARA_CORE_EXIT_ON_ASSERT_FAILURE 1
|
#define NAZARA_CORE_EXIT_ON_ASSERT_FAILURE 1
|
||||||
|
|
||||||
// Teste les assertions
|
// Teste les assertions
|
||||||
#define NAZARA_CORE_ENABLE_ASSERTS 0
|
#define NAZARA_CORE_ENABLE_ASSERTS 0
|
||||||
|
|
||||||
// Taille du buffer lors d'une lecture complète d'un fichier (ex: Hash)
|
// Taille du buffer lors d'une lecture complète d'un fichier (ex: Hash)
|
||||||
#define NAZARA_CORE_FILE_BUFFERSIZE 4096
|
#define NAZARA_CORE_FILE_BUFFERSIZE 4096
|
||||||
|
|
||||||
// Le moteur doit-il incorporer les Unicode Character Data (Nécessaires pour faire fonctionner le flag NzString::HandleUTF8)
|
// Le moteur doit-il incorporer les Unicode Character Data (Nécessaires pour faire fonctionner le flag NzString::HandleUTF8)
|
||||||
#define NAZARA_CORE_INCLUDE_UNICODEDATA 0
|
#define NAZARA_CORE_INCLUDE_UNICODEDATA 0
|
||||||
|
|
||||||
// Utilise un tracker pour repérer les éventuels leaks (Ralentit l'exécution)
|
// Utilise un tracker pour repérer les éventuels leaks (Ralentit l'exécution)
|
||||||
#define NAZARA_CORE_MEMORYLEAKTRACKER 0
|
#define NAZARA_CORE_MEMORYLEAKTRACKER 0
|
||||||
|
|
||||||
// Standardise les séparateurs des dossiers selon le système d'exploitation courant (Léger coût à l'exécution)
|
// Standardise les séparateurs des dossiers selon le système d'exploitation courant (Léger coût à l'exécution)
|
||||||
#define NAZARA_CORE_NORMALIZE_DIRECTORY_SEPARATORS 1
|
#define NAZARA_CORE_NORMALIZE_DIRECTORY_SEPARATORS 1
|
||||||
|
|
||||||
// Précision des réels lors de la transformation en texte (Max. chiffres après la virgule)
|
// Précision des réels lors de la transformation en texte (Max. chiffres après la virgule)
|
||||||
#define NAZARA_CORE_REAL_PRECISION 6
|
#define NAZARA_CORE_REAL_PRECISION 6
|
||||||
|
|
||||||
// Duplique la sortie du log sur le flux de sortie standard (cout)
|
// Duplique la sortie du log sur le flux de sortie standard (cout)
|
||||||
#define NAZARA_CORE_DUPLICATE_TO_COUT 0
|
#define NAZARA_CORE_DUPLICATE_TO_COUT 0
|
||||||
|
|
||||||
// Active les tests de sécurité basés sur le code (Conseillé pour le développement)
|
// Active les tests de sécurité basés sur le code (Conseillé pour le développement)
|
||||||
#define NAZARA_CORE_SAFE 1
|
#define NAZARA_CORE_SAFE 1
|
||||||
|
|
||||||
// Protège les classes des accès concurrentiels
|
// Protège les classes des accès concurrentiels
|
||||||
#define NAZARA_CORE_THREADSAFE 1
|
#define NAZARA_CORE_THREADSAFE 1
|
||||||
|
|
||||||
// Les classes à protéger des accès concurrentiels
|
// Les classes à protéger des accès concurrentiels
|
||||||
#define NAZARA_THREADSAFETY_BYTEARRAY 1 // NzByteArray (COW)
|
#define NAZARA_THREADSAFETY_BYTEARRAY 1 // NzByteArray (COW)
|
||||||
#define NAZARA_THREADSAFETY_CLOCK 0 // NzClock
|
#define NAZARA_THREADSAFETY_CLOCK 0 // NzClock
|
||||||
#define NAZARA_THREADSAFETY_DIRECTORY 1 // NzDirectory
|
#define NAZARA_THREADSAFETY_DIRECTORY 1 // NzDirectory
|
||||||
#define NAZARA_THREADSAFETY_DYNLIB 1 // NzDynLib
|
#define NAZARA_THREADSAFETY_DYNLIB 1 // NzDynLib
|
||||||
#define NAZARA_THREADSAFETY_FILE 1 // NzFile
|
#define NAZARA_THREADSAFETY_FILE 1 // NzFile
|
||||||
#define NAZARA_THREADSAFETY_HASHDIGEST 0 // NzHashDigest
|
#define NAZARA_THREADSAFETY_HASHDIGEST 0 // NzHashDigest
|
||||||
#define NAZARA_THREADSAFETY_LOG 1 // NzLog
|
#define NAZARA_THREADSAFETY_LOG 1 // NzLog
|
||||||
#define NAZARA_THREADSAFETY_STRING 1 // NzString (COW)
|
#define NAZARA_THREADSAFETY_RESOURCE 1 // NzResource
|
||||||
#define NAZARA_THREADSAFETY_STRINGSTREAM 0 // NzStringStream
|
#define NAZARA_THREADSAFETY_STRING 1 // NzString (COW)
|
||||||
|
#define NAZARA_THREADSAFETY_STRINGSTREAM 0 // NzStringStream
|
||||||
// Le nombre de spinlocks à utiliser avec les critical sections de Windows (0 pour désactiver)
|
|
||||||
#define NAZARA_CORE_WINDOWS_CS_SPINLOCKS 4096
|
// Le nombre de spinlocks à utiliser avec les critical sections de Windows (0 pour désactiver)
|
||||||
|
#define NAZARA_CORE_WINDOWS_CS_SPINLOCKS 4096
|
||||||
// Optimise certaines parties du code avec certaines avancées venues de Windows Vista (Casse la compatibilité XP mais n'affecte pas les autres OS)
|
|
||||||
#define NAZARA_CORE_WINDOWS_VISTA 0
|
// Optimise certaines parties du code avec certaines avancées venues de Windows Vista (Casse la compatibilité XP mais n'affecte pas les autres OS)
|
||||||
|
#define NAZARA_CORE_WINDOWS_VISTA 0
|
||||||
/*
|
|
||||||
// Règle le temps entre le réveil du thread des timers et l'activation d'un timer (En millisecondes)
|
/*
|
||||||
#define NAZARA_CORE_TIMER_WAKEUPTIME 10
|
// Règle le temps entre le réveil du thread des timers et l'activation d'un timer (En millisecondes)
|
||||||
*/
|
#define NAZARA_CORE_TIMER_WAKEUPTIME 10
|
||||||
|
*/
|
||||||
#endif // NAZARA_CONFIG_CORE_HPP
|
|
||||||
|
#endif // NAZARA_CONFIG_CORE_HPP
|
||||||
|
|
|
||||||
|
|
@ -1,26 +1,30 @@
|
||||||
// Copyright (C) 2012 Jérôme Leclercq
|
// Copyright (C) 2012 Jérôme Leclercq
|
||||||
// This file is part of the "Nazara Engine - Core module"
|
// This file is part of the "Nazara Engine - Core module"
|
||||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#ifndef NAZARA_ENUMS_CORE_HPP
|
#ifndef NAZARA_ENUMS_CORE_HPP
|
||||||
#define NAZARA_ENUMS_CORE_HPP
|
#define NAZARA_ENUMS_CORE_HPP
|
||||||
|
|
||||||
enum nzEndianness
|
enum nzEndianness
|
||||||
{
|
{
|
||||||
nzEndianness_Unknown = -1,
|
nzEndianness_Unknown = -1,
|
||||||
|
|
||||||
nzEndianness_BigEndian,
|
nzEndianness_BigEndian,
|
||||||
nzEndianness_LittleEndian
|
nzEndianness_LittleEndian,
|
||||||
};
|
|
||||||
|
nzEndianness_Max = nzEndianness_LittleEndian
|
||||||
enum nzErrorType
|
};
|
||||||
{
|
|
||||||
nzErrorType_AssertFailed,
|
enum nzErrorType
|
||||||
nzErrorType_Internal,
|
{
|
||||||
nzErrorType_Normal,
|
nzErrorType_AssertFailed,
|
||||||
nzErrorType_Warning
|
nzErrorType_Internal,
|
||||||
};
|
nzErrorType_Normal,
|
||||||
|
nzErrorType_Warning,
|
||||||
#endif // NAZARA_ENUMS_CORE_HPP
|
|
||||||
|
nzErrorType_Max = nzErrorType_Warning
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // NAZARA_ENUMS_CORE_HPP
|
||||||
|
|
|
||||||
|
|
@ -1,30 +1,72 @@
|
||||||
// Copyright (C) 2012 Jérôme Leclercq
|
// Copyright (C) 2012 Jérôme Leclercq
|
||||||
// This file is part of the "Nazara Engine - Core module"
|
// This file is part of the "Nazara Engine - Core module"
|
||||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#ifndef NAZARA_RESOURCE_HPP
|
#ifndef NAZARA_RESOURCE_HPP
|
||||||
#define NAZARA_RESOURCE_HPP
|
#define NAZARA_RESOURCE_HPP
|
||||||
|
|
||||||
#include <Nazara/Prerequesites.hpp>
|
#include <Nazara/Prerequesites.hpp>
|
||||||
|
#include <set>
|
||||||
class NAZARA_API NzResource
|
|
||||||
{
|
#if NAZARA_CORE_THREADSAFE && NAZARA_THREADSAFETY_RESOURCE
|
||||||
public:
|
#include <Nazara/Core/ThreadSafety.hpp>
|
||||||
NzResource(bool persistent = true);
|
#else
|
||||||
NzResource(const NzResource& resource);
|
#include <Nazara/Core/ThreadSafetyOff.hpp>
|
||||||
virtual ~NzResource();
|
#endif
|
||||||
|
|
||||||
void AddResourceReference() const;
|
class NzResourceListener;
|
||||||
bool IsPersistent() const;
|
|
||||||
void RemoveResourceReference() const;
|
struct NzResourceEntry
|
||||||
void SetPersistent(bool persistent = true);
|
{
|
||||||
|
NzResourceEntry(NzResourceListener* resourceListener, int i = 0) :
|
||||||
private:
|
listener(resourceListener),
|
||||||
// Je fais précéder le nom par 'resource' pour éviter les éventuels conflits de noms
|
index(i)
|
||||||
mutable bool m_resourcePersistent;
|
{
|
||||||
mutable unsigned int m_resourceReferenceCount;
|
}
|
||||||
};
|
|
||||||
|
bool operator<(const NzResourceEntry& rhs) const
|
||||||
#endif // NAZARA_RESOURCE_HPP
|
{
|
||||||
|
return listener < rhs.listener;
|
||||||
|
}
|
||||||
|
|
||||||
|
NzResourceListener* listener;
|
||||||
|
int index;
|
||||||
|
};
|
||||||
|
|
||||||
|
class NAZARA_API NzResource
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
NzResource(bool persistent = true);
|
||||||
|
NzResource(const NzResource& resource);
|
||||||
|
virtual ~NzResource();
|
||||||
|
|
||||||
|
void AddResourceListener(NzResourceListener* listener, int index = 0) const;
|
||||||
|
void AddResourceReference() const;
|
||||||
|
|
||||||
|
bool IsPersistent() const;
|
||||||
|
|
||||||
|
void RemoveResourceListener(NzResourceListener* listener) const;
|
||||||
|
void RemoveResourceReference() const;
|
||||||
|
|
||||||
|
void SetPersistent(bool persistent = true);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void NotifyCreated();
|
||||||
|
void NotifyDestroy();
|
||||||
|
|
||||||
|
private:
|
||||||
|
void EnsureResourceListenerUpdate() const;
|
||||||
|
|
||||||
|
NazaraMutexAttrib(m_mutex, mutable)
|
||||||
|
|
||||||
|
// Je fais précéder le nom par 'resource' pour éviter les éventuels conflits de noms
|
||||||
|
mutable std::set<NzResourceEntry> m_resourceListeners;
|
||||||
|
mutable std::set<NzResourceEntry> m_resourceListenersCache;
|
||||||
|
mutable bool m_resourceListenerUpdated;
|
||||||
|
bool m_resourcePersistent;
|
||||||
|
mutable unsigned int m_resourceReferenceCount;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // NAZARA_RESOURCE_HPP
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,25 @@
|
||||||
|
// Copyright (C) 2012 Jérôme Leclercq
|
||||||
|
// This file is part of the "Nazara Engine - Core module"
|
||||||
|
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#ifndef NAZARA_RESOURCELISTENER_HPP
|
||||||
|
#define NAZARA_RESOURCELISTENER_HPP
|
||||||
|
|
||||||
|
#include <Nazara/Prerequesites.hpp>
|
||||||
|
|
||||||
|
class NzResource;
|
||||||
|
|
||||||
|
class NAZARA_API NzResourceListener
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
NzResourceListener() = default;
|
||||||
|
virtual ~NzResourceListener();
|
||||||
|
|
||||||
|
virtual void OnResourceCreated(const NzResource* resource, int index);
|
||||||
|
virtual void OnResourceDestroy(const NzResource* resource, int index);
|
||||||
|
virtual void OnResourceReleased(const NzResource* resource, int index);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // NAZARA_RESOURCELISTENER_HPP
|
||||||
|
|
@ -1,142 +1,142 @@
|
||||||
// Copyright (C) 2012 Jérôme Leclercq
|
// Copyright (C) 2012 Jérôme Leclercq
|
||||||
// This file is part of the "Nazara Engine - Utility module"
|
// This file is part of the "Nazara Engine - Utility module"
|
||||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||||
|
|
||||||
#include <Nazara/Core/Config.hpp>
|
#include <Nazara/Core/Config.hpp>
|
||||||
#include <Nazara/Core/Error.hpp>
|
#include <Nazara/Core/Error.hpp>
|
||||||
#include <Nazara/Core/File.hpp>
|
#include <Nazara/Core/File.hpp>
|
||||||
#include <Nazara/Core/InputStream.hpp>
|
#include <Nazara/Core/InputStream.hpp>
|
||||||
#include <Nazara/Core/MemoryStream.hpp>
|
#include <Nazara/Core/MemoryStream.hpp>
|
||||||
#include <Nazara/Core/Debug.hpp>
|
#include <Nazara/Core/Debug.hpp>
|
||||||
|
|
||||||
template<typename Type, typename Parameters>
|
template<typename Type, typename Parameters>
|
||||||
bool NzResourceLoader<Type, Parameters>::LoadFromFile(Type* resource, const NzString& filePath, const Parameters& parameters)
|
bool NzResourceLoader<Type, Parameters>::LoadFromFile(Type* resource, const NzString& filePath, const Parameters& parameters)
|
||||||
{
|
{
|
||||||
#if NAZARA_CORE_SAFE
|
#if NAZARA_CORE_SAFE
|
||||||
if (!parameters.IsValid())
|
if (!parameters.IsValid())
|
||||||
{
|
{
|
||||||
NazaraError("Invalid Parameters");
|
NazaraError("Invalid parameters");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
NzString path = NzFile::NormalizePath(filePath);
|
NzString path = NzFile::NormalizePath(filePath);
|
||||||
NzString ext = path.SubstrFrom('.', -1, true);
|
NzString ext = path.SubstrFrom('.', -1, true);
|
||||||
if (ext.IsEmpty())
|
if (ext.IsEmpty())
|
||||||
{
|
{
|
||||||
NazaraError("Failed to get file extension");
|
NazaraError("Failed to get file extension");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
NzFile file(path, NzFile::ReadOnly);
|
NzFile file(path, NzFile::ReadOnly);
|
||||||
if (!file.IsOpen())
|
if (!file.IsOpen())
|
||||||
{
|
{
|
||||||
NazaraError("Failed to open file");
|
NazaraError("Failed to open file");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto loader = Type::s_loaders.begin(); loader != Type::s_loaders.end(); ++loader)
|
for (auto loader = Type::s_loaders.begin(); loader != Type::s_loaders.end(); ++loader)
|
||||||
{
|
{
|
||||||
for (const NzString& loaderExt : std::get<0>(*loader))
|
for (const NzString& loaderExt : std::get<0>(*loader))
|
||||||
{
|
{
|
||||||
int cmp = NzString::Compare(loaderExt, ext);
|
int cmp = NzString::Compare(loaderExt, ext);
|
||||||
if (cmp == 0)
|
if (cmp == 0)
|
||||||
{
|
{
|
||||||
if (!std::get<1>(*loader)(file, parameters))
|
if (!std::get<1>(*loader)(file, parameters))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
file.SetCursorPos(0);
|
file.SetCursorPos(0);
|
||||||
|
|
||||||
// Chargement de la ressource
|
// Chargement de la ressource
|
||||||
if (std::get<2>(*loader)(resource, file, parameters))
|
if (std::get<2>(*loader)(resource, file, parameters))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
NazaraWarning("Loader failed");
|
NazaraWarning("Loader failed");
|
||||||
|
|
||||||
file.SetCursorPos(0);
|
file.SetCursorPos(0);
|
||||||
}
|
}
|
||||||
else if (cmp < 0) // S'il est encore possible que l'extension se situe après
|
else if (cmp < 0) // S'il est encore possible que l'extension se situe après
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
NazaraError("Failed to load file: no loader");
|
NazaraError("Failed to load file: no loader");
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Type, typename Parameters>
|
template<typename Type, typename Parameters>
|
||||||
bool NzResourceLoader<Type, Parameters>::LoadFromMemory(Type* resource, const void* data, unsigned int size, const Parameters& parameters)
|
bool NzResourceLoader<Type, Parameters>::LoadFromMemory(Type* resource, const void* data, unsigned int size, const Parameters& parameters)
|
||||||
{
|
{
|
||||||
NzMemoryStream stream(data, size);
|
NzMemoryStream stream(data, size);
|
||||||
|
|
||||||
return LoadFromStream(resource, stream, parameters);
|
return LoadFromStream(resource, stream, parameters);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Type, typename Parameters>
|
template<typename Type, typename Parameters>
|
||||||
bool NzResourceLoader<Type, Parameters>::LoadFromStream(Type* resource, NzInputStream& stream, const Parameters& parameters)
|
bool NzResourceLoader<Type, Parameters>::LoadFromStream(Type* resource, NzInputStream& stream, const Parameters& parameters)
|
||||||
{
|
{
|
||||||
#if NAZARA_CORE_SAFE
|
#if NAZARA_CORE_SAFE
|
||||||
if (!parameters.IsValid())
|
if (!parameters.IsValid())
|
||||||
{
|
{
|
||||||
NazaraError("Invalid Parameters");
|
NazaraError("Invalid parameters");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (stream.GetSize() == 0 || stream.GetCursorPos() >= stream.GetSize())
|
if (stream.GetSize() == 0 || stream.GetCursorPos() >= stream.GetSize())
|
||||||
{
|
{
|
||||||
NazaraError("No data to load");
|
NazaraError("No data to load");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
nzUInt64 streamPos = stream.GetCursorPos();
|
nzUInt64 streamPos = stream.GetCursorPos();
|
||||||
for (auto loader = Type::s_loaders.begin(); loader != Type::s_loaders.end(); ++loader)
|
for (auto loader = Type::s_loaders.begin(); loader != Type::s_loaders.end(); ++loader)
|
||||||
{
|
{
|
||||||
// Le loader supporte-t-il les données ?
|
// Le loader supporte-t-il les données ?
|
||||||
if (!std::get<1>(*loader)(stream, parameters))
|
if (!std::get<1>(*loader)(stream, parameters))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// On repositionne le stream au début
|
// On repositionne le stream au début
|
||||||
stream.SetCursorPos(streamPos);
|
stream.SetCursorPos(streamPos);
|
||||||
|
|
||||||
// Chargement de la ressource
|
// Chargement de la ressource
|
||||||
if (std::get<2>(*loader)(resource, stream, parameters))
|
if (std::get<2>(*loader)(resource, stream, parameters))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
NazaraWarning("Loader failed");
|
NazaraWarning("Loader failed");
|
||||||
stream.SetCursorPos(streamPos); // On repositionne au début
|
stream.SetCursorPos(streamPos); // On repositionne au début
|
||||||
}
|
}
|
||||||
|
|
||||||
NazaraError("Failed to load file: no loader");
|
NazaraError("Failed to load file: no loader");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Type, typename Parameters>
|
template<typename Type, typename Parameters>
|
||||||
void NzResourceLoader<Type, Parameters>::RegisterLoader(const NzString& fileExtensions, CheckFunction checkFunc, LoadFunction loadFunc)
|
void NzResourceLoader<Type, Parameters>::RegisterLoader(const NzString& fileExtensions, CheckFunction checkFunc, LoadFunction loadFunc)
|
||||||
{
|
{
|
||||||
/// Trouver une alternative à ce code monstrueux
|
///FIXME: Trouver une alternative à ce code monstrueux
|
||||||
std::vector<NzString> exts;
|
std::vector<NzString> exts;
|
||||||
fileExtensions.SplitAny(exts, " /\\.,;|-_");
|
fileExtensions.SplitAny(exts, " /\\.,;|-_");
|
||||||
|
|
||||||
std::set<NzString> extensions;
|
std::set<NzString> extensions;
|
||||||
std::copy(exts.begin(), exts.end(), std::inserter(extensions, extensions.begin()));
|
std::copy(exts.begin(), exts.end(), std::inserter(extensions, extensions.begin()));
|
||||||
|
|
||||||
Type::s_loaders.insert(std::make_tuple(std::move(extensions), checkFunc, loadFunc));
|
Type::s_loaders.insert(std::make_tuple(std::move(extensions), checkFunc, loadFunc));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Type, typename Parameters>
|
template<typename Type, typename Parameters>
|
||||||
void NzResourceLoader<Type, Parameters>::UnregisterLoader(const NzString& fileExtensions, CheckFunction checkFunc, LoadFunction loadFunc)
|
void NzResourceLoader<Type, Parameters>::UnregisterLoader(const NzString& fileExtensions, CheckFunction checkFunc, LoadFunction loadFunc)
|
||||||
{
|
{
|
||||||
std::vector<NzString> exts;
|
std::vector<NzString> exts;
|
||||||
fileExtensions.SplitAny(exts, " /\\.,;|-_");
|
fileExtensions.SplitAny(exts, " /\\.,;|-_");
|
||||||
|
|
||||||
std::set<NzString> extensions;
|
std::set<NzString> extensions;
|
||||||
std::copy(exts.begin(), exts.end(), std::inserter(extensions, extensions.begin()));
|
std::copy(exts.begin(), exts.end(), std::inserter(extensions, extensions.begin()));
|
||||||
|
|
||||||
Type::s_loaders.erase(std::make_tuple(std::move(extensions), checkFunc, loadFunc));
|
Type::s_loaders.erase(std::make_tuple(std::move(extensions), checkFunc, loadFunc));
|
||||||
}
|
}
|
||||||
|
|
||||||
#include <Nazara/Core/DebugOff.hpp>
|
#include <Nazara/Core/DebugOff.hpp>
|
||||||
|
|
|
||||||
|
|
@ -1,321 +1,321 @@
|
||||||
// Copyright (C) 2012 Jérôme Leclercq
|
// Copyright (C) 2012 Jérôme Leclercq
|
||||||
// This file is part of the "Nazara Engine - Core module"
|
// This file is part of the "Nazara Engine - Core module"
|
||||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#ifndef NAZARA_STRING_HPP
|
#ifndef NAZARA_STRING_HPP
|
||||||
#define NAZARA_STRING_HPP
|
#define NAZARA_STRING_HPP
|
||||||
|
|
||||||
#include <Nazara/Prerequesites.hpp>
|
#include <Nazara/Prerequesites.hpp>
|
||||||
#include <Nazara/Core/Hashable.hpp>
|
#include <Nazara/Core/Hashable.hpp>
|
||||||
#include <iosfwd>
|
#include <iosfwd>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#if NAZARA_CORE_THREADSAFE && NAZARA_THREADSAFETY_STRING
|
#if NAZARA_CORE_THREADSAFE && NAZARA_THREADSAFETY_STRING
|
||||||
#include <Nazara/Core/ThreadSafety.hpp>
|
#include <Nazara/Core/ThreadSafety.hpp>
|
||||||
#else
|
#else
|
||||||
#include <Nazara/Core/ThreadSafetyOff.hpp>
|
#include <Nazara/Core/ThreadSafetyOff.hpp>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
class NzAbstractHash;
|
class NzAbstractHash;
|
||||||
class NzHashDigest;
|
class NzHashDigest;
|
||||||
|
|
||||||
class NAZARA_API NzString : public NzHashable
|
class NAZARA_API NzString : public NzHashable
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
enum Flags
|
enum Flags
|
||||||
{
|
{
|
||||||
None = 0x00, // Mode par défaut
|
None = 0x00, // Mode par défaut
|
||||||
CaseInsensitive = 0x01, // Insensible à la casse
|
CaseInsensitive = 0x01, // Insensible à la casse
|
||||||
HandleUtf8 = 0x02, // Traite les octets comme une suite de caractères UTF-8
|
HandleUtf8 = 0x02, // Traite les octets comme une suite de caractères UTF-8
|
||||||
TrimOnlyLeft = 0x04, // Trim(med), ne coupe que la partie gauche de la chaîne
|
TrimOnlyLeft = 0x04, // Trim(med), ne coupe que la partie gauche de la chaîne
|
||||||
TrimOnlyRight = 0x08 // Trim(med), ne coupe que la partie droite de la chaîne
|
TrimOnlyRight = 0x08 // Trim(med), ne coupe que la partie droite de la chaîne
|
||||||
};
|
};
|
||||||
|
|
||||||
struct SharedString;
|
struct SharedString;
|
||||||
|
|
||||||
NzString();
|
NzString();
|
||||||
NzString(char character);
|
NzString(char character);
|
||||||
NzString(const char* string);
|
NzString(const char* string);
|
||||||
NzString(const std::string& string);
|
NzString(const std::string& string);
|
||||||
NzString(const NzString& string);
|
NzString(const NzString& string);
|
||||||
NzString(NzString&& string) noexcept;
|
NzString(NzString&& string) noexcept;
|
||||||
NzString(SharedString* sharedString);
|
NzString(SharedString* sharedString);
|
||||||
~NzString();
|
~NzString();
|
||||||
|
|
||||||
NzString& Append(char character);
|
NzString& Append(char character);
|
||||||
NzString& Append(const char* string);
|
NzString& Append(const char* string);
|
||||||
NzString& Append(const NzString& string);
|
NzString& Append(const NzString& string);
|
||||||
|
|
||||||
void Clear(bool keepBuffer = false);
|
void Clear(bool keepBuffer = false);
|
||||||
|
|
||||||
bool Contains(char character, int start = 0, nzUInt32 flags = None) const;
|
bool Contains(char character, int start = 0, nzUInt32 flags = None) const;
|
||||||
bool Contains(const char* string, int start = 0, nzUInt32 flags = None) const;
|
bool Contains(const char* string, int start = 0, nzUInt32 flags = None) const;
|
||||||
bool Contains(const NzString& string, int start = 0, nzUInt32 flags = None) const;
|
bool Contains(const NzString& string, int start = 0, nzUInt32 flags = None) const;
|
||||||
|
|
||||||
unsigned int Count(char character, int start = 0, nzUInt32 flags = None) const;
|
unsigned int Count(char character, int start = 0, nzUInt32 flags = None) const;
|
||||||
unsigned int Count(const char* string, int start = 0, nzUInt32 flags = None) const;
|
unsigned int Count(const char* string, int start = 0, nzUInt32 flags = None) const;
|
||||||
unsigned int Count(const NzString& string, int start = 0, nzUInt32 flags = None) const;
|
unsigned int Count(const NzString& string, int start = 0, nzUInt32 flags = None) const;
|
||||||
unsigned int CountAny(const char* string, int start = 0, nzUInt32 flags = None) const;
|
unsigned int CountAny(const char* string, int start = 0, nzUInt32 flags = None) const;
|
||||||
unsigned int CountAny(const NzString& string, int start = 0, nzUInt32 flags = None) const;
|
unsigned int CountAny(const NzString& string, int start = 0, nzUInt32 flags = None) const;
|
||||||
|
|
||||||
bool EndsWith(char character, nzUInt32 flags = None) const;
|
bool EndsWith(char character, nzUInt32 flags = None) const;
|
||||||
bool EndsWith(const char* string, nzUInt32 flags = None) const;
|
bool EndsWith(const char* string, nzUInt32 flags = None) const;
|
||||||
bool EndsWith(const NzString& string, nzUInt32 flags = None) const;
|
bool EndsWith(const NzString& string, nzUInt32 flags = None) const;
|
||||||
|
|
||||||
unsigned int Find(char character, int start = 0, nzUInt32 flags = None) const;
|
unsigned int Find(char character, int start = 0, nzUInt32 flags = None) const;
|
||||||
unsigned int Find(const char* string, int start = 0, nzUInt32 flags = None) const;
|
unsigned int Find(const char* string, int start = 0, nzUInt32 flags = None) const;
|
||||||
unsigned int Find(const NzString& string, int start = 0, nzUInt32 flags = None) const;
|
unsigned int Find(const NzString& string, int start = 0, nzUInt32 flags = None) const;
|
||||||
unsigned int FindAny(const char* string, int start = 0, nzUInt32 flags = None) const;
|
unsigned int FindAny(const char* string, int start = 0, nzUInt32 flags = None) const;
|
||||||
unsigned int FindAny(const NzString& string, int start = 0, nzUInt32 flags = None) const;
|
unsigned int FindAny(const NzString& string, int start = 0, nzUInt32 flags = None) const;
|
||||||
unsigned int FindLast(char character, int start = -1, nzUInt32 flags = None) const;
|
unsigned int FindLast(char character, int start = -1, nzUInt32 flags = None) const;
|
||||||
unsigned int FindLast(const char *string, int start = -1, nzUInt32 flags = None) const;
|
unsigned int FindLast(const char *string, int start = -1, nzUInt32 flags = None) const;
|
||||||
unsigned int FindLast(const NzString& string, int start = -1, nzUInt32 flags = None) const;
|
unsigned int FindLast(const NzString& string, int start = -1, nzUInt32 flags = None) const;
|
||||||
unsigned int FindLastAny(const char* string, int start = -1, nzUInt32 flags = None) const;
|
unsigned int FindLastAny(const char* string, int start = -1, nzUInt32 flags = None) const;
|
||||||
unsigned int FindLastAny(const NzString& string, int start = -1, nzUInt32 flags = None) const;
|
unsigned int FindLastAny(const NzString& string, int start = -1, nzUInt32 flags = None) const;
|
||||||
unsigned int FindLastWord(const char* string, int start = -1, nzUInt32 flags = None) const;
|
unsigned int FindLastWord(const char* string, int start = -1, nzUInt32 flags = None) const;
|
||||||
unsigned int FindLastWord(const NzString& string, int start = -1, nzUInt32 flags = None) const;
|
unsigned int FindLastWord(const NzString& string, int start = -1, nzUInt32 flags = None) const;
|
||||||
unsigned int FindWord(const char* string, int start = 0, nzUInt32 flags = None) const;
|
unsigned int FindWord(const char* string, int start = 0, nzUInt32 flags = None) const;
|
||||||
unsigned int FindWord(const NzString& string, int start = 0, nzUInt32 flags = None) const;
|
unsigned int FindWord(const NzString& string, int start = 0, nzUInt32 flags = None) const;
|
||||||
|
|
||||||
char* GetBuffer();
|
char* GetBuffer();
|
||||||
unsigned int GetCapacity() const;
|
unsigned int GetCapacity() const;
|
||||||
const char* GetConstBuffer() const;
|
const char* GetConstBuffer() const;
|
||||||
unsigned int GetLength() const;
|
unsigned int GetLength() const;
|
||||||
unsigned int GetSize() const;
|
unsigned int GetSize() const;
|
||||||
char* GetUtf8Buffer(unsigned int* size = nullptr) const;
|
char* GetUtf8Buffer(unsigned int* size = nullptr) const;
|
||||||
char16_t* GetUtf16Buffer(unsigned int* size = nullptr) const;
|
char16_t* GetUtf16Buffer(unsigned int* size = nullptr) const;
|
||||||
char32_t* GetUtf32Buffer(unsigned int* size = nullptr) const;
|
char32_t* GetUtf32Buffer(unsigned int* size = nullptr) const;
|
||||||
wchar_t* GetWideBuffer(unsigned int* size = nullptr) const;
|
wchar_t* GetWideBuffer(unsigned int* size = nullptr) const;
|
||||||
|
|
||||||
NzString GetWord(unsigned int index, nzUInt32 flags = None) const;
|
NzString GetWord(unsigned int index, nzUInt32 flags = None) const;
|
||||||
unsigned int GetWordPosition(unsigned int index, nzUInt32 flags = None) const;
|
unsigned int GetWordPosition(unsigned int index, nzUInt32 flags = None) const;
|
||||||
|
|
||||||
NzString& Insert(int pos, char character);
|
NzString& Insert(int pos, char character);
|
||||||
NzString& Insert(int pos, const char* string);
|
NzString& Insert(int pos, const char* string);
|
||||||
NzString& Insert(int pos, const NzString& string);
|
NzString& Insert(int pos, const NzString& string);
|
||||||
|
|
||||||
bool IsEmpty() const;
|
bool IsEmpty() const;
|
||||||
bool IsNull() const;
|
bool IsNull() const;
|
||||||
bool IsNumber(nzUInt8 radix = 10, nzUInt32 flags = CaseInsensitive) const;
|
bool IsNumber(nzUInt8 radix = 10, nzUInt32 flags = CaseInsensitive) const;
|
||||||
|
|
||||||
bool Match(const char* pattern) const;
|
bool Match(const char* pattern) const;
|
||||||
bool Match(const NzString& pattern) const;
|
bool Match(const NzString& pattern) const;
|
||||||
|
|
||||||
NzString& Prepend(char character);
|
NzString& Prepend(char character);
|
||||||
NzString& Prepend(const char* string);
|
NzString& Prepend(const char* string);
|
||||||
NzString& Prepend(const NzString& string);
|
NzString& Prepend(const NzString& string);
|
||||||
|
|
||||||
unsigned int Replace(char oldCharacter, char newCharacter, int start = 0, nzUInt32 flags = None);
|
unsigned int Replace(char oldCharacter, char newCharacter, int start = 0, nzUInt32 flags = None);
|
||||||
unsigned int Replace(const char* oldString, const char* replaceString, int start = 0, nzUInt32 flags = None);
|
unsigned int Replace(const char* oldString, const char* replaceString, int start = 0, nzUInt32 flags = None);
|
||||||
unsigned int Replace(const NzString& oldString, const NzString& replaceString, int start = 0, nzUInt32 flags = None);
|
unsigned int Replace(const NzString& oldString, const NzString& replaceString, int start = 0, nzUInt32 flags = None);
|
||||||
unsigned int ReplaceAny(const char* oldCharacters, char replaceCharacter, int start = 0, nzUInt32 flags = None);
|
unsigned int ReplaceAny(const char* oldCharacters, char replaceCharacter, int start = 0, nzUInt32 flags = None);
|
||||||
//unsigned int ReplaceAny(const char* oldCharacters, const char* replaceString, int start = 0, nzUInt32 flags = None);
|
//unsigned int ReplaceAny(const char* oldCharacters, const char* replaceString, int start = 0, nzUInt32 flags = None);
|
||||||
//unsigned int ReplaceAny(const NzString& oldCharacters, const NzString& replaceString, int start = 0, nzUInt32 flags = None);
|
//unsigned int ReplaceAny(const NzString& oldCharacters, const NzString& replaceString, int start = 0, nzUInt32 flags = None);
|
||||||
|
|
||||||
void Reserve(unsigned int bufferSize);
|
void Reserve(unsigned int bufferSize);
|
||||||
|
|
||||||
NzString& Resize(int size, char character = ' ');
|
NzString& Resize(int size, char character = ' ');
|
||||||
NzString Resized(int size, char character = ' ') const;
|
NzString Resized(int size, char character = ' ') const;
|
||||||
|
|
||||||
NzString& Reverse();
|
NzString& Reverse();
|
||||||
NzString Reversed() const;
|
NzString Reversed() const;
|
||||||
|
|
||||||
NzString Simplified(nzUInt32 flags = None) const;
|
NzString Simplified(nzUInt32 flags = None) const;
|
||||||
NzString& Simplify(nzUInt32 flags = None);
|
NzString& Simplify(nzUInt32 flags = None);
|
||||||
|
|
||||||
unsigned int Split(std::vector<NzString>& result, char separation = ' ', int start = 0, nzUInt32 flags = None) const;
|
unsigned int Split(std::vector<NzString>& result, char separation = ' ', int start = 0, nzUInt32 flags = None) const;
|
||||||
unsigned int Split(std::vector<NzString>& result, const char* separation, int start = 0, nzUInt32 flags = None) const;
|
unsigned int Split(std::vector<NzString>& result, const char* separation, int start = 0, nzUInt32 flags = None) const;
|
||||||
unsigned int Split(std::vector<NzString>& result, const NzString& separation, int start = 0, nzUInt32 flags = None) const;
|
unsigned int Split(std::vector<NzString>& result, const NzString& separation, int start = 0, nzUInt32 flags = None) const;
|
||||||
unsigned int SplitAny(std::vector<NzString>& result, const char* separations, int start = 0, nzUInt32 flags = None) const;
|
unsigned int SplitAny(std::vector<NzString>& result, const char* separations, int start = 0, nzUInt32 flags = None) const;
|
||||||
unsigned int SplitAny(std::vector<NzString>& result, const NzString& separations, int start = 0, nzUInt32 flags = None) const;
|
unsigned int SplitAny(std::vector<NzString>& result, const NzString& separations, int start = 0, nzUInt32 flags = None) const;
|
||||||
|
|
||||||
bool StartsWith(char character, nzUInt32 flags = None) const;
|
bool StartsWith(char character, nzUInt32 flags = None) const;
|
||||||
bool StartsWith(const char* string, nzUInt32 flags = None) const;
|
bool StartsWith(const char* string, nzUInt32 flags = None) const;
|
||||||
bool StartsWith(const NzString& string, nzUInt32 flags = None) const;
|
bool StartsWith(const NzString& string, nzUInt32 flags = None) const;
|
||||||
|
|
||||||
NzString Substr(int startPos, int endPos = -1) const;
|
NzString Substr(int startPos, int endPos = -1) const;
|
||||||
NzString SubstrFrom(char character, int startPos = 0, bool fromLast = false, bool include = false, nzUInt32 flags = None) const;
|
NzString SubstrFrom(char character, int startPos = 0, bool fromLast = false, bool include = false, nzUInt32 flags = None) const;
|
||||||
NzString SubstrFrom(const char *string, int startPos = 0, bool fromLast = false, bool include = false, nzUInt32 flags = None) const;
|
NzString SubstrFrom(const char *string, int startPos = 0, bool fromLast = false, bool include = false, nzUInt32 flags = None) const;
|
||||||
NzString SubstrFrom(const NzString& string, int startPos = 0, bool fromLast = false, bool include = false, nzUInt32 flags = None) const;
|
NzString SubstrFrom(const NzString& string, int startPos = 0, bool fromLast = false, bool include = false, nzUInt32 flags = None) const;
|
||||||
NzString SubstrTo(char character, int startPos = 0, bool toLast = false, bool include = false, nzUInt32 flags = None) const;
|
NzString SubstrTo(char character, int startPos = 0, bool toLast = false, bool include = false, nzUInt32 flags = None) const;
|
||||||
NzString SubstrTo(const char *string, int startPos = 0, bool toLast = false, bool include = false, nzUInt32 flags = None) const;
|
NzString SubstrTo(const char *string, int startPos = 0, bool toLast = false, bool include = false, nzUInt32 flags = None) const;
|
||||||
NzString SubstrTo(const NzString& string, int startPos = 0, bool toLast = false, bool include = false, nzUInt32 flags = None) const;
|
NzString SubstrTo(const NzString& string, int startPos = 0, bool toLast = false, bool include = false, nzUInt32 flags = None) const;
|
||||||
|
|
||||||
void Swap(NzString& str);
|
void Swap(NzString& str);
|
||||||
|
|
||||||
bool ToBool(bool* value, nzUInt32 flags = None) const;
|
bool ToBool(bool* value, nzUInt32 flags = None) const;
|
||||||
bool ToDouble(double* value) const;
|
bool ToDouble(double* value) const;
|
||||||
bool ToInteger(long long* value, nzUInt8 radix = 10) const;
|
bool ToInteger(long long* value, nzUInt8 radix = 10) const;
|
||||||
NzString ToLower(nzUInt32 flags = None) const;
|
NzString ToLower(nzUInt32 flags = None) const;
|
||||||
NzString ToUpper(nzUInt32 flags = None) const;
|
NzString ToUpper(nzUInt32 flags = None) const;
|
||||||
|
|
||||||
NzString& Trim(nzUInt32 flags = None);
|
NzString& Trim(nzUInt32 flags = None);
|
||||||
NzString& Trim(char character, nzUInt32 flags = None);
|
NzString& Trim(char character, nzUInt32 flags = None);
|
||||||
NzString Trimmed(nzUInt32 flags = None) const;
|
NzString Trimmed(nzUInt32 flags = None) const;
|
||||||
NzString Trimmed(char character, nzUInt32 flags = None) const;
|
NzString Trimmed(char character, nzUInt32 flags = None) const;
|
||||||
|
|
||||||
// Méthodes STD
|
// Méthodes STD
|
||||||
char* begin();
|
char* begin();
|
||||||
const char* begin() const;
|
const char* begin() const;
|
||||||
char* end();
|
char* end();
|
||||||
const char* end() const;
|
const char* end() const;
|
||||||
void push_front(char c);
|
void push_front(char c);
|
||||||
void push_back(char c);
|
void push_back(char c);
|
||||||
/*char* rbegin();
|
/*char* rbegin();
|
||||||
const char* rbegin() const;
|
const char* rbegin() const;
|
||||||
char* rend();
|
char* rend();
|
||||||
const char* rend() const;*/
|
const char* rend() const;*/
|
||||||
|
|
||||||
typedef const char& const_reference;
|
typedef const char& const_reference;
|
||||||
typedef char* iterator;
|
typedef char* iterator;
|
||||||
//typedef char* reverse_iterator;
|
//typedef char* reverse_iterator;
|
||||||
typedef char value_type;
|
typedef char value_type;
|
||||||
// Méthodes STD
|
// Méthodes STD
|
||||||
|
|
||||||
operator std::string() const;
|
operator std::string() const;
|
||||||
|
|
||||||
char& operator[](unsigned int pos);
|
char& operator[](unsigned int pos);
|
||||||
char operator[](unsigned int pos) const;
|
char operator[](unsigned int pos) const;
|
||||||
|
|
||||||
NzString& operator=(char character);
|
NzString& operator=(char character);
|
||||||
NzString& operator=(const char* string);
|
NzString& operator=(const char* string);
|
||||||
NzString& operator=(const std::string& string);
|
NzString& operator=(const std::string& string);
|
||||||
NzString& operator=(const NzString& string);
|
NzString& operator=(const NzString& string);
|
||||||
NzString& operator=(NzString&& string) noexcept;
|
NzString& operator=(NzString&& string) noexcept;
|
||||||
|
|
||||||
NzString operator+(char character) const;
|
NzString operator+(char character) const;
|
||||||
NzString operator+(const char* string) const;
|
NzString operator+(const char* string) const;
|
||||||
NzString operator+(const std::string& string) const;
|
NzString operator+(const std::string& string) const;
|
||||||
NzString operator+(const NzString& string) const;
|
NzString operator+(const NzString& string) const;
|
||||||
|
|
||||||
NzString& operator+=(char character);
|
NzString& operator+=(char character);
|
||||||
NzString& operator+=(const char* string);
|
NzString& operator+=(const char* string);
|
||||||
NzString& operator+=(const std::string& string);
|
NzString& operator+=(const std::string& string);
|
||||||
NzString& operator+=(const NzString& string);
|
NzString& operator+=(const NzString& string);
|
||||||
|
|
||||||
bool operator==(char character) const;
|
bool operator==(char character) const;
|
||||||
bool operator==(const char* string) const;
|
bool operator==(const char* string) const;
|
||||||
bool operator==(const std::string& string) const;
|
bool operator==(const std::string& string) const;
|
||||||
|
|
||||||
bool operator!=(char character) const;
|
bool operator!=(char character) const;
|
||||||
bool operator!=(const char* string) const;
|
bool operator!=(const char* string) const;
|
||||||
bool operator!=(const std::string& string) const;
|
bool operator!=(const std::string& string) const;
|
||||||
|
|
||||||
bool operator<(char character) const;
|
bool operator<(char character) const;
|
||||||
bool operator<(const char* string) const;
|
bool operator<(const char* string) const;
|
||||||
bool operator<(const std::string& string) const;
|
bool operator<(const std::string& string) const;
|
||||||
|
|
||||||
bool operator<=(char character) const;
|
bool operator<=(char character) const;
|
||||||
bool operator<=(const char* string) const;
|
bool operator<=(const char* string) const;
|
||||||
bool operator<=(const std::string& string) const;
|
bool operator<=(const std::string& string) const;
|
||||||
|
|
||||||
bool operator>(char character) const;
|
bool operator>(char character) const;
|
||||||
bool operator>(const char* string) const;
|
bool operator>(const char* string) const;
|
||||||
bool operator>(const std::string& string) const;
|
bool operator>(const std::string& string) const;
|
||||||
|
|
||||||
bool operator>=(char character) const;
|
bool operator>=(char character) const;
|
||||||
bool operator>=(const char* string) const;
|
bool operator>=(const char* string) const;
|
||||||
bool operator>=(const std::string& string) const;
|
bool operator>=(const std::string& string) const;
|
||||||
|
|
||||||
static NzString Boolean(bool boolean);
|
static NzString Boolean(bool boolean);
|
||||||
static int Compare(const NzString& first, const NzString& second);
|
static int Compare(const NzString& first, const NzString& second);
|
||||||
static NzString Number(float number);
|
static NzString Number(float number);
|
||||||
static NzString Number(double number);
|
static NzString Number(double number);
|
||||||
static NzString Number(long double number);
|
static NzString Number(long double number);
|
||||||
static NzString Number(signed char number, nzUInt8 radix = 10);
|
static NzString Number(signed char number, nzUInt8 radix = 10);
|
||||||
static NzString Number(unsigned char number, nzUInt8 radix = 10);
|
static NzString Number(unsigned char number, nzUInt8 radix = 10);
|
||||||
static NzString Number(short number, nzUInt8 radix = 10);
|
static NzString Number(short number, nzUInt8 radix = 10);
|
||||||
static NzString Number(unsigned short number, nzUInt8 radix = 10);
|
static NzString Number(unsigned short number, nzUInt8 radix = 10);
|
||||||
static NzString Number(int number, nzUInt8 radix = 10);
|
static NzString Number(int number, nzUInt8 radix = 10);
|
||||||
static NzString Number(unsigned int number, nzUInt8 radix = 10);
|
static NzString Number(unsigned int number, nzUInt8 radix = 10);
|
||||||
static NzString Number(long number, nzUInt8 radix = 10);
|
static NzString Number(long number, nzUInt8 radix = 10);
|
||||||
static NzString Number(unsigned long number, nzUInt8 radix = 10);
|
static NzString Number(unsigned long number, nzUInt8 radix = 10);
|
||||||
static NzString Number(long long number, nzUInt8 radix = 10);
|
static NzString Number(long long number, nzUInt8 radix = 10);
|
||||||
static NzString Number(unsigned long long number, nzUInt8 radix = 10);
|
static NzString Number(unsigned long long number, nzUInt8 radix = 10);
|
||||||
static NzString Pointer(const void* ptr);
|
static NzString Pointer(const void* ptr);
|
||||||
static NzString Unicode(char32_t character);
|
static NzString Unicode(char32_t character);
|
||||||
static NzString Unicode(const char* u8String);
|
static NzString Unicode(const char* u8String);
|
||||||
static NzString Unicode(const char16_t* u16String);
|
static NzString Unicode(const char16_t* u16String);
|
||||||
static NzString Unicode(const char32_t* u32String);
|
static NzString Unicode(const char32_t* u32String);
|
||||||
static NzString Unicode(const wchar_t* wString);
|
static NzString Unicode(const wchar_t* wString);
|
||||||
|
|
||||||
NAZARA_API friend std::istream& operator>>(std::istream& in, NzString& string);
|
NAZARA_API friend std::istream& operator>>(std::istream& in, NzString& string);
|
||||||
NAZARA_API friend std::ostream& operator<<(std::ostream& out, const NzString& string);
|
NAZARA_API friend std::ostream& operator<<(std::ostream& out, const NzString& string);
|
||||||
|
|
||||||
NAZARA_API friend NzString operator+(char character, const NzString& string);
|
NAZARA_API friend NzString operator+(char character, const NzString& string);
|
||||||
NAZARA_API friend NzString operator+(const char* string, const NzString& nstring);
|
NAZARA_API friend NzString operator+(const char* string, const NzString& nstring);
|
||||||
NAZARA_API friend NzString operator+(const std::string& string, const NzString& nstring);
|
NAZARA_API friend NzString operator+(const std::string& string, const NzString& nstring);
|
||||||
|
|
||||||
NAZARA_API friend bool operator==(const NzString& first, const NzString& second);
|
NAZARA_API friend bool operator==(const NzString& first, const NzString& second);
|
||||||
NAZARA_API friend bool operator!=(const NzString& first, const NzString& second);
|
NAZARA_API friend bool operator!=(const NzString& first, const NzString& second);
|
||||||
NAZARA_API friend bool operator<(const NzString& first, const NzString& second);
|
NAZARA_API friend bool operator<(const NzString& first, const NzString& second);
|
||||||
NAZARA_API friend bool operator<=(const NzString& first, const NzString& second);
|
NAZARA_API friend bool operator<=(const NzString& first, const NzString& second);
|
||||||
NAZARA_API friend bool operator>(const NzString& first, const NzString& second);
|
NAZARA_API friend bool operator>(const NzString& first, const NzString& second);
|
||||||
NAZARA_API friend bool operator>=(const NzString& first, const NzString& second);
|
NAZARA_API friend bool operator>=(const NzString& first, const NzString& second);
|
||||||
|
|
||||||
NAZARA_API friend bool operator==(char character, const NzString& nstring);
|
NAZARA_API friend bool operator==(char character, const NzString& nstring);
|
||||||
NAZARA_API friend bool operator==(const char* string, const NzString& nstring);
|
NAZARA_API friend bool operator==(const char* string, const NzString& nstring);
|
||||||
NAZARA_API friend bool operator==(const std::string& string, const NzString& nstring);
|
NAZARA_API friend bool operator==(const std::string& string, const NzString& nstring);
|
||||||
|
|
||||||
NAZARA_API friend bool operator!=(char character, const NzString& nstring);
|
NAZARA_API friend bool operator!=(char character, const NzString& nstring);
|
||||||
NAZARA_API friend bool operator!=(const char* string, const NzString& nstring);
|
NAZARA_API friend bool operator!=(const char* string, const NzString& nstring);
|
||||||
NAZARA_API friend bool operator!=(const std::string& string, const NzString& nstring);
|
NAZARA_API friend bool operator!=(const std::string& string, const NzString& nstring);
|
||||||
|
|
||||||
NAZARA_API friend bool operator<(char character, const NzString& nstring);
|
NAZARA_API friend bool operator<(char character, const NzString& nstring);
|
||||||
NAZARA_API friend bool operator<(const char* string, const NzString& nstring);
|
NAZARA_API friend bool operator<(const char* string, const NzString& nstring);
|
||||||
NAZARA_API friend bool operator<(const std::string& string, const NzString& nstring);
|
NAZARA_API friend bool operator<(const std::string& string, const NzString& nstring);
|
||||||
|
|
||||||
NAZARA_API friend bool operator<=(char character, const NzString& nstring);
|
NAZARA_API friend bool operator<=(char character, const NzString& nstring);
|
||||||
NAZARA_API friend bool operator<=(const char* string, const NzString& nstring);
|
NAZARA_API friend bool operator<=(const char* string, const NzString& nstring);
|
||||||
NAZARA_API friend bool operator<=(const std::string& string, const NzString& nstring);
|
NAZARA_API friend bool operator<=(const std::string& string, const NzString& nstring);
|
||||||
|
|
||||||
NAZARA_API friend bool operator>(char character, const NzString& nstring);
|
NAZARA_API friend bool operator>(char character, const NzString& nstring);
|
||||||
NAZARA_API friend bool operator>(const char* string, const NzString& nstring);
|
NAZARA_API friend bool operator>(const char* string, const NzString& nstring);
|
||||||
NAZARA_API friend bool operator>(const std::string& string, const NzString& nstring);
|
NAZARA_API friend bool operator>(const std::string& string, const NzString& nstring);
|
||||||
|
|
||||||
NAZARA_API friend bool operator>=(char character, const NzString& nstring);
|
NAZARA_API friend bool operator>=(char character, const NzString& nstring);
|
||||||
NAZARA_API friend bool operator>=(const char* string, const NzString& nstring);
|
NAZARA_API friend bool operator>=(const char* string, const NzString& nstring);
|
||||||
NAZARA_API friend bool operator>=(const std::string& string, const NzString& nstring);
|
NAZARA_API friend bool operator>=(const std::string& string, const NzString& nstring);
|
||||||
|
|
||||||
struct NAZARA_API SharedString
|
struct NAZARA_API SharedString
|
||||||
{
|
{
|
||||||
SharedString() = default;
|
SharedString() = default;
|
||||||
|
|
||||||
SharedString(unsigned short referenceCount, unsigned int bufferSize, unsigned int stringSize, char* str) :
|
SharedString(unsigned short referenceCount, unsigned int bufferSize, unsigned int stringSize, char* str) :
|
||||||
capacity(bufferSize),
|
capacity(bufferSize),
|
||||||
size(stringSize),
|
size(stringSize),
|
||||||
string(str),
|
string(str),
|
||||||
refCount(referenceCount)
|
refCount(referenceCount)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int capacity;
|
unsigned int capacity;
|
||||||
unsigned int size;
|
unsigned int size;
|
||||||
char* string;
|
char* string;
|
||||||
|
|
||||||
unsigned short refCount = 1;
|
unsigned short refCount = 1;
|
||||||
NazaraMutex(mutex)
|
NazaraMutex(mutex)
|
||||||
};
|
};
|
||||||
|
|
||||||
static SharedString emptyString;
|
static SharedString emptyString;
|
||||||
static unsigned int npos;
|
static const unsigned int npos;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void EnsureOwnership();
|
void EnsureOwnership();
|
||||||
bool FillHash(NzHashImpl* hash) const;
|
bool FillHash(NzHashImpl* hash) const;
|
||||||
void ReleaseString();
|
void ReleaseString();
|
||||||
|
|
||||||
SharedString* m_sharedString;
|
SharedString* m_sharedString;
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace std
|
namespace std
|
||||||
{
|
{
|
||||||
NAZARA_API istream& getline(istream& is, NzString& str);
|
NAZARA_API istream& getline(istream& is, NzString& str);
|
||||||
NAZARA_API istream& getline(istream& is, NzString& str, char delim);
|
NAZARA_API istream& getline(istream& is, NzString& str, char delim);
|
||||||
NAZARA_API void swap(NzString& lhs, NzString& rhs);
|
NAZARA_API void swap(NzString& lhs, NzString& rhs);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // NAZARA_STRING_HPP
|
#endif // NAZARA_STRING_HPP
|
||||||
|
|
|
||||||
|
|
@ -1,52 +1,49 @@
|
||||||
/*
|
/*
|
||||||
Nazara Engine - Mathematics module
|
Nazara Engine - Mathematics module
|
||||||
|
|
||||||
Copyright (C) 2012 Jérôme "Lynix" Leclercq (Lynix680@gmail.com)
|
Copyright (C) 2012 Jérôme "Lynix" Leclercq (Lynix680@gmail.com)
|
||||||
Rémi "overdrivr" Bèges (remi.beges@laposte.net)
|
Rémi "overdrivr" Bèges (remi.beges@laposte.net)
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
this software and associated documentation files (the "Software"), to deal in
|
this software and associated documentation files (the "Software"), to deal in
|
||||||
the Software without restriction, including without limitation the rights to
|
the Software without restriction, including without limitation the rights to
|
||||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||||
of the Software, and to permit persons to whom the Software is furnished to do
|
of the Software, and to permit persons to whom the Software is furnished to do
|
||||||
so, subject to the following conditions:
|
so, subject to the following conditions:
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in all
|
The above copyright notice and this permission notice shall be included in all
|
||||||
copies or substantial portions of the Software.
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
SOFTWARE.
|
SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#ifndef NAZARA_CONFIG_MATH_HPP
|
#ifndef NAZARA_CONFIG_MATH_HPP
|
||||||
#define NAZARA_CONFIG_MATH_HPP
|
#define NAZARA_CONFIG_MATH_HPP
|
||||||
|
|
||||||
/// Chaque modification d'un paramètre du module nécessite une recompilation de celui-ci
|
/// Chaque modification d'un paramètre du module nécessite une recompilation de celui-ci
|
||||||
|
|
||||||
// Définit le radian comme l'unité utilisée pour les angles
|
// Définit le radian comme l'unité utilisée pour les angles
|
||||||
#define NAZARA_MATH_ANGLE_RADIAN 0
|
#define NAZARA_MATH_ANGLE_RADIAN 0
|
||||||
|
|
||||||
// Définit la disposition des matrices en colonnes (Façon OpenGL)
|
// Optimise les opérations entre matrices affines (Demande plusieurs comparaisons pour déterminer si une matrice est affine)
|
||||||
#define NAZARA_MATH_MATRIX_COLUMN_MAJOR 1
|
#define NAZARA_MATH_MATRIX4_CHECK_AFFINE 0
|
||||||
|
|
||||||
// Optimise les opérations entre matrices affines (Demande plusieurs comparaisons pour déterminer si une matrice est affine)
|
// Active les tests de sécurité basés sur le code (Conseillé pour le développement)
|
||||||
#define NAZARA_MATH_MATRIX4_CHECK_AFFINE 0
|
#define NAZARA_MATH_SAFE 1
|
||||||
|
|
||||||
// Active les tests de sécurité basés sur le code (Conseillé pour le développement)
|
// Protège les classes des accès concurrentiels
|
||||||
#define NAZARA_MATH_SAFE 1
|
#define NAZARA_MATH_THREADSAFE 1
|
||||||
|
|
||||||
// Protège les classes des accès concurrentiels
|
// Les classes à protéger des accès concurrentiels
|
||||||
#define NAZARA_MATH_THREADSAFE 1
|
#define NAZARA_THREADSAFETY_MATRIX3 1 // NzMatrix3 (COW)
|
||||||
|
#define NAZARA_THREADSAFETY_MATRIX4 1 // NzMatrix4 (COW)
|
||||||
// Les classes à protéger des accès concurrentiels
|
|
||||||
#define NAZARA_THREADSAFETY_MATRIX3 1 // NzMatrix3 (COW)
|
#endif // NAZARA_CONFIG_MATH_HPP
|
||||||
#define NAZARA_THREADSAFETY_MATRIX4 1 // NzMatrix4 (COW)
|
|
||||||
|
|
||||||
#endif // NAZARA_CONFIG_MATH_HPP
|
|
||||||
|
|
|
||||||
|
|
@ -1,144 +1,145 @@
|
||||||
// Copyright (C) 2012 Jérôme Leclercq
|
// Copyright (C) 2012 Jérôme Leclercq
|
||||||
// This file is part of the "Nazara Engine - Mathematics module"
|
// This file is part of the "Nazara Engine - Mathematics module"
|
||||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#ifndef NAZARA_MATRIX4_HPP
|
#ifndef NAZARA_MATRIX4_HPP
|
||||||
#define NAZARA_MATRIX4_HPP
|
#define NAZARA_MATRIX4_HPP
|
||||||
|
|
||||||
#include <Nazara/Core/String.hpp>
|
#include <Nazara/Core/String.hpp>
|
||||||
#include <Nazara/Math/Config.hpp>
|
#include <Nazara/Math/Config.hpp>
|
||||||
|
|
||||||
#if NAZARA_MATH_THREADSAFE && NAZARA_THREADSAFETY_MATRIX4
|
#if NAZARA_MATH_THREADSAFE && NAZARA_THREADSAFETY_MATRIX4
|
||||||
#include <Nazara/Core/ThreadSafety.hpp>
|
#include <Nazara/Core/ThreadSafety.hpp>
|
||||||
#else
|
#else
|
||||||
#include <Nazara/Core/ThreadSafetyOff.hpp>
|
#include <Nazara/Core/ThreadSafetyOff.hpp>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
template<typename T> class NzEulerAngles;
|
template<typename T> class NzEulerAngles;
|
||||||
template<typename T> class NzQuaternion;
|
template<typename T> class NzQuaternion;
|
||||||
template<typename T> class NzVector2;
|
template<typename T> class NzVector2;
|
||||||
template<typename T> class NzVector3;
|
template<typename T> class NzVector3;
|
||||||
template<typename T> class NzVector4;
|
template<typename T> class NzVector4;
|
||||||
|
|
||||||
template<typename T> class NzMatrix4
|
template<typename T> class NzMatrix4
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
NzMatrix4();
|
NzMatrix4();
|
||||||
NzMatrix4(T r11, T r12, T r13, T r14,
|
NzMatrix4(T r11, T r12, T r13, T r14,
|
||||||
T r21, T r22, T r23, T r24,
|
T r21, T r22, T r23, T r24,
|
||||||
T r31, T r32, T r33, T r34,
|
T r31, T r32, T r33, T r34,
|
||||||
T r41, T r42, T r43, T r44);
|
T r41, T r42, T r43, T r44);
|
||||||
NzMatrix4(const T matrix[16]);
|
NzMatrix4(const T matrix[16]);
|
||||||
//NzMatrix4(const NzMatrix3<T>& matrix);
|
//NzMatrix4(const NzMatrix3<T>& matrix);
|
||||||
template<typename U> explicit NzMatrix4(const NzMatrix4<U>& matrix);
|
template<typename U> explicit NzMatrix4(const NzMatrix4<U>& matrix);
|
||||||
NzMatrix4(const NzMatrix4& matrix);
|
NzMatrix4(const NzMatrix4& matrix);
|
||||||
NzMatrix4(NzMatrix4&& matrix) noexcept;
|
NzMatrix4(NzMatrix4&& matrix) noexcept;
|
||||||
~NzMatrix4();
|
~NzMatrix4();
|
||||||
|
|
||||||
NzMatrix4 Concatenate(const NzMatrix4& matrix) const;
|
NzMatrix4 Concatenate(const NzMatrix4& matrix) const;
|
||||||
|
NzMatrix4 ConcatenateAffine(const NzMatrix4& matrix) const;
|
||||||
T GetDeterminant() const;
|
|
||||||
NzMatrix4 GetInverse() const;
|
T GetDeterminant() const;
|
||||||
NzQuaternion<T> GetRotation() const;
|
NzMatrix4 GetInverse() const;
|
||||||
//NzMatrix3 GetRotationMatrix() const;
|
NzQuaternion<T> GetRotation() const;
|
||||||
NzVector3<T> GetScale() const;
|
//NzMatrix3 GetRotationMatrix() const;
|
||||||
NzVector3<T> GetTranslation() const;
|
NzVector3<T> GetScale() const;
|
||||||
NzMatrix4 GetTransposed() const;
|
NzVector3<T> GetTranslation() const;
|
||||||
|
NzMatrix4 GetTransposed() const;
|
||||||
bool HasNegativeScale() const;
|
|
||||||
bool HasScale() const;
|
bool HasNegativeScale() const;
|
||||||
|
bool HasScale() const;
|
||||||
bool IsAffine() const;
|
|
||||||
bool IsDefined() const;
|
bool IsAffine() const;
|
||||||
|
bool IsDefined() const;
|
||||||
void MakeIdentity();
|
|
||||||
void MakeLookAt(const NzVector3<T>& eye, const NzVector3<T>& center, const NzVector3<T>& up);
|
void MakeIdentity();
|
||||||
void MakeOrtho(T left, T top, T width, T height, T zNear = -1.0, T zFar = 1.0);
|
void MakeLookAt(const NzVector3<T>& eye, const NzVector3<T>& target, const NzVector3<T>& up = NzVector3<T>::Up());
|
||||||
void MakePerspective(T angle, T ratio, T zNear, T zFar);
|
void MakeOrtho(T left, T top, T width, T height, T zNear = -1.0, T zFar = 1.0);
|
||||||
void MakeRotation(const NzQuaternion<T>& rotation);
|
void MakePerspective(T angle, T ratio, T zNear, T zFar);
|
||||||
void MakeScale(const NzVector3<T>& scale);
|
void MakeRotation(const NzQuaternion<T>& rotation);
|
||||||
void MakeTranslation(const NzVector3<T>& translation);
|
void MakeScale(const NzVector3<T>& scale);
|
||||||
void MakeZero();
|
void MakeTranslation(const NzVector3<T>& translation);
|
||||||
|
void MakeZero();
|
||||||
void Set(T r11, T r12, T r13, T r14,
|
|
||||||
T r21, T r22, T r23, T r24,
|
void Set(T r11, T r12, T r13, T r14,
|
||||||
T r31, T r32, T r33, T r34,
|
T r21, T r22, T r23, T r24,
|
||||||
T r41, T r42, T r43, T r44);
|
T r31, T r32, T r33, T r34,
|
||||||
void Set(const T matrix[16]);
|
T r41, T r42, T r43, T r44);
|
||||||
//NzMatrix4(const NzMatrix3<T>& matrix);
|
void Set(const T matrix[16]);
|
||||||
void Set(const NzMatrix4& matrix);
|
//NzMatrix4(const NzMatrix3<T>& matrix);
|
||||||
void Set(NzMatrix4&& matrix);
|
void Set(const NzMatrix4& matrix);
|
||||||
template<typename U> void Set(const NzMatrix4<U>& matrix);
|
void Set(NzMatrix4&& matrix);
|
||||||
void SetRotation(const NzQuaternion<T>& rotation);
|
template<typename U> void Set(const NzMatrix4<U>& matrix);
|
||||||
void SetScale(const NzVector3<T>& scale);
|
void SetRotation(const NzQuaternion<T>& rotation);
|
||||||
void SetTranslation(const NzVector3<T>& translation);
|
void SetScale(const NzVector3<T>& scale);
|
||||||
|
void SetTranslation(const NzVector3<T>& translation);
|
||||||
NzString ToString() const;
|
|
||||||
|
NzString ToString() const;
|
||||||
NzVector2<T> Transform(const NzVector2<T>& vector, T z = 0.0, T w = 1.0) const;
|
|
||||||
NzVector3<T> Transform(const NzVector3<T>& vector, T w = 1.0) const;
|
NzVector2<T> Transform(const NzVector2<T>& vector, T z = 0.0, T w = 1.0) const;
|
||||||
NzVector4<T> Transform(const NzVector4<T>& vector) const;
|
NzVector3<T> Transform(const NzVector3<T>& vector, T w = 1.0) const;
|
||||||
|
NzVector4<T> Transform(const NzVector4<T>& vector) const;
|
||||||
NzMatrix4& Transpose();
|
|
||||||
|
NzMatrix4& Transpose();
|
||||||
operator NzString() const;
|
|
||||||
|
operator NzString() const;
|
||||||
operator T*();
|
|
||||||
operator const T*() const;
|
operator T*();
|
||||||
|
operator const T*() const;
|
||||||
T& operator()(unsigned int x, unsigned int y);
|
|
||||||
const T& operator()(unsigned int x, unsigned int y) const;
|
T& operator()(unsigned int x, unsigned int y);
|
||||||
|
const T& operator()(unsigned int x, unsigned int y) const;
|
||||||
NzMatrix4& operator=(const NzMatrix4& matrix);
|
|
||||||
NzMatrix4& operator=(NzMatrix4&& matrix) noexcept;
|
NzMatrix4& operator=(const NzMatrix4& matrix);
|
||||||
|
NzMatrix4& operator=(NzMatrix4&& matrix) noexcept;
|
||||||
NzMatrix4 operator*(const NzMatrix4& matrix) const;
|
|
||||||
NzVector2<T> operator*(const NzVector2<T>& vector) const;
|
NzMatrix4 operator*(const NzMatrix4& matrix) const;
|
||||||
NzVector3<T> operator*(const NzVector3<T>& vector) const;
|
NzVector2<T> operator*(const NzVector2<T>& vector) const;
|
||||||
NzVector4<T> operator*(const NzVector4<T>& vector) const;
|
NzVector3<T> operator*(const NzVector3<T>& vector) const;
|
||||||
NzMatrix4 operator*(T scalar) const;
|
NzVector4<T> operator*(const NzVector4<T>& vector) const;
|
||||||
|
NzMatrix4 operator*(T scalar) const;
|
||||||
NzMatrix4& operator*=(const NzMatrix4& matrix);
|
|
||||||
NzMatrix4& operator*=(T scalar);
|
NzMatrix4& operator*=(const NzMatrix4& matrix);
|
||||||
|
NzMatrix4& operator*=(T scalar);
|
||||||
static NzMatrix4 Concatenate(const NzMatrix4& m1, const NzMatrix4& m2);
|
|
||||||
static NzMatrix4 ConcatenateAffine(const NzMatrix4& m1, const NzMatrix4& m2);
|
static NzMatrix4 Concatenate(const NzMatrix4& m1, const NzMatrix4& m2);
|
||||||
static NzMatrix4 Identity();
|
static NzMatrix4 ConcatenateAffine(const NzMatrix4& m1, const NzMatrix4& m2);
|
||||||
static NzMatrix4 LookAt(const NzVector3<T>& eye, const NzVector3<T>& center, const NzVector3<T>& up);
|
static NzMatrix4 Identity();
|
||||||
static NzMatrix4 Ortho(T left, T top, T width, T height, T zNear = -1.0, T zFar = 1.0);
|
static NzMatrix4 LookAt(const NzVector3<T>& eye, const NzVector3<T>& target, const NzVector3<T>& up = NzVector3<T>::Up());
|
||||||
static NzMatrix4 Perspective(T angle, T ratio, T zNear, T zFar);
|
static NzMatrix4 Ortho(T left, T top, T width, T height, T zNear = -1.0, T zFar = 1.0);
|
||||||
static NzMatrix4 Rotate(const NzQuaternion<T>& rotation);
|
static NzMatrix4 Perspective(T angle, T ratio, T zNear, T zFar);
|
||||||
static NzMatrix4 Scale(const NzVector3<T>& scale);
|
static NzMatrix4 Rotate(const NzQuaternion<T>& rotation);
|
||||||
static NzMatrix4 Translate(const NzVector3<T>& translation);
|
static NzMatrix4 Scale(const NzVector3<T>& scale);
|
||||||
static NzMatrix4 Zero();
|
static NzMatrix4 Translate(const NzVector3<T>& translation);
|
||||||
|
static NzMatrix4 Zero();
|
||||||
struct SharedMatrix
|
|
||||||
{
|
struct SharedMatrix
|
||||||
T m11, m12, m13, m14,
|
{
|
||||||
m21, m22, m23, m24,
|
T m11, m12, m13, m14,
|
||||||
m31, m32, m33, m34,
|
m21, m22, m23, m24,
|
||||||
m41, m42, m43, m44;
|
m31, m32, m33, m34,
|
||||||
|
m41, m42, m43, m44;
|
||||||
unsigned short refCount = 1;
|
|
||||||
NazaraMutex(mutex)
|
unsigned short refCount = 1;
|
||||||
};
|
NazaraMutex(mutex)
|
||||||
|
};
|
||||||
private:
|
|
||||||
void EnsureOwnership();
|
private:
|
||||||
void ReleaseMatrix();
|
void EnsureOwnership();
|
||||||
|
void ReleaseMatrix();
|
||||||
SharedMatrix* m_sharedMatrix = nullptr;
|
|
||||||
};
|
SharedMatrix* m_sharedMatrix = nullptr;
|
||||||
|
};
|
||||||
template<typename T> std::ostream& operator<<(std::ostream& out, const NzMatrix4<T>& matrix);
|
|
||||||
|
template<typename T> std::ostream& operator<<(std::ostream& out, const NzMatrix4<T>& matrix);
|
||||||
template<typename T> NzMatrix4<T> operator*(T scale, const NzMatrix4<T>& matrix);
|
|
||||||
|
template<typename T> NzMatrix4<T> operator*(T scale, const NzMatrix4<T>& matrix);
|
||||||
typedef NzMatrix4<double> NzMatrix4d;
|
|
||||||
typedef NzMatrix4<float> NzMatrix4f;
|
typedef NzMatrix4<double> NzMatrix4d;
|
||||||
|
typedef NzMatrix4<float> NzMatrix4f;
|
||||||
#include <Nazara/Math/Matrix4.inl>
|
|
||||||
|
#include <Nazara/Math/Matrix4.inl>
|
||||||
#endif // NAZARA_MATRIX4_HPP
|
|
||||||
|
#endif // NAZARA_MATRIX4_HPP
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -1,90 +1,93 @@
|
||||||
// Copyright (C) 2012 Rémi Bèges - Jérôme Leclercq
|
// Copyright (C) 2012 Rémi Bèges - Jérôme Leclercq
|
||||||
// This file is part of the "Nazara Engine - Mathematics module"
|
// This file is part of the "Nazara Engine - Mathematics module"
|
||||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#ifndef NAZARA_QUATERNION_HPP
|
#ifndef NAZARA_QUATERNION_HPP
|
||||||
#define NAZARA_QUATERNION_HPP
|
#define NAZARA_QUATERNION_HPP
|
||||||
|
|
||||||
#include <Nazara/Core/String.hpp>
|
#include <Nazara/Core/String.hpp>
|
||||||
|
|
||||||
template<typename T> class NzEulerAngles;
|
template<typename T> class NzEulerAngles;
|
||||||
template<typename T> class NzVector3;
|
template<typename T> class NzVector3;
|
||||||
|
|
||||||
template<typename T> class NzQuaternion
|
template<typename T> class NzQuaternion
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
NzQuaternion();
|
NzQuaternion();
|
||||||
NzQuaternion(T W, T X, T Y, T Z);
|
NzQuaternion(T W, T X, T Y, T Z);
|
||||||
NzQuaternion(T quat[4]);
|
NzQuaternion(T quat[4]);
|
||||||
NzQuaternion(T angle, const NzVector3<T>& axis);
|
NzQuaternion(T angle, const NzVector3<T>& axis);
|
||||||
NzQuaternion(const NzEulerAngles<T>& angles);
|
NzQuaternion(const NzEulerAngles<T>& angles);
|
||||||
//NzQuaternion(const NzMatrix3<T>& mat);
|
//NzQuaternion(const NzMatrix3<T>& mat);
|
||||||
template<typename U> explicit NzQuaternion(const NzQuaternion<U>& quat);
|
template<typename U> explicit NzQuaternion(const NzQuaternion<U>& quat);
|
||||||
NzQuaternion(const NzQuaternion& quat) = default;
|
NzQuaternion(const NzQuaternion& quat) = default;
|
||||||
~NzQuaternion() = default;
|
~NzQuaternion() = default;
|
||||||
|
|
||||||
T DotProduct(const NzQuaternion& vec) const;
|
T DotProduct(const NzQuaternion& vec) const;
|
||||||
|
|
||||||
NzQuaternion GetConjugate() const;
|
NzQuaternion GetConjugate() const;
|
||||||
NzQuaternion GetNormalized() const;
|
NzQuaternion GetInverse() const;
|
||||||
|
NzQuaternion GetNormal() const;
|
||||||
void MakeIdentity();
|
|
||||||
void MakeZero();
|
void Inverse();
|
||||||
|
|
||||||
T Magnitude() const;
|
void MakeIdentity();
|
||||||
|
void MakeZero();
|
||||||
T Normalize();
|
|
||||||
|
T Magnitude() const;
|
||||||
void Set(T W, T X, T Y, T Z);
|
|
||||||
void Set(T quat[4]);
|
T Normalize();
|
||||||
void Set(T angle, const NzVector3<T>& normalizedAxis);
|
|
||||||
void Set(const NzEulerAngles<T>& angles);
|
void Set(T W, T X, T Y, T Z);
|
||||||
//void Set(const NzMatrix3<T>& mat);
|
void Set(T quat[4]);
|
||||||
void Set(const NzQuaternion& quat);
|
void Set(T angle, const NzVector3<T>& normalizedAxis);
|
||||||
template<typename U> void Set(const NzQuaternion<U>& quat);
|
void Set(const NzEulerAngles<T>& angles);
|
||||||
|
//void Set(const NzMatrix3<T>& mat);
|
||||||
T SquaredMagnitude() const;
|
void Set(const NzQuaternion& quat);
|
||||||
|
template<typename U> void Set(const NzQuaternion<U>& quat);
|
||||||
NzEulerAngles<T> ToEulerAngles() const;
|
|
||||||
//NzMatrix3<T> ToRotationMatrix() const;
|
T SquaredMagnitude() const;
|
||||||
NzString ToString() const;
|
|
||||||
|
NzEulerAngles<T> ToEulerAngles() const;
|
||||||
operator NzString() const;
|
//NzMatrix3<T> ToRotationMatrix() const;
|
||||||
|
NzString ToString() const;
|
||||||
NzQuaternion& operator=(const NzQuaternion& quat);
|
|
||||||
|
operator NzString() const;
|
||||||
NzQuaternion operator+(const NzQuaternion& quat) const;
|
|
||||||
NzQuaternion operator*(const NzQuaternion& quat) const;
|
NzQuaternion& operator=(const NzQuaternion& quat);
|
||||||
NzVector3<T> operator*(const NzVector3<T>& vec) const;
|
|
||||||
NzQuaternion operator*(T scale) const;
|
NzQuaternion operator+(const NzQuaternion& quat) const;
|
||||||
NzQuaternion operator/(const NzQuaternion& quat) const;
|
NzQuaternion operator*(const NzQuaternion& quat) const;
|
||||||
|
NzVector3<T> operator*(const NzVector3<T>& vec) const;
|
||||||
NzQuaternion& operator+=(const NzQuaternion& quat);
|
NzQuaternion operator*(T scale) const;
|
||||||
NzQuaternion& operator*=(const NzQuaternion& quat);
|
NzQuaternion operator/(const NzQuaternion& quat) const;
|
||||||
NzQuaternion& operator*=(T scale);
|
|
||||||
NzQuaternion& operator/=(const NzQuaternion& quat);
|
NzQuaternion& operator+=(const NzQuaternion& quat);
|
||||||
|
NzQuaternion& operator*=(const NzQuaternion& quat);
|
||||||
bool operator==(const NzQuaternion& quat) const;
|
NzQuaternion& operator*=(T scale);
|
||||||
bool operator!=(const NzQuaternion& quat) const;
|
NzQuaternion& operator/=(const NzQuaternion& quat);
|
||||||
bool operator<(const NzQuaternion& quat) const;
|
|
||||||
bool operator<=(const NzQuaternion& quat) const;
|
bool operator==(const NzQuaternion& quat) const;
|
||||||
bool operator>(const NzQuaternion& quat) const;
|
bool operator!=(const NzQuaternion& quat) const;
|
||||||
bool operator>=(const NzQuaternion& quat) const;
|
bool operator<(const NzQuaternion& quat) const;
|
||||||
|
bool operator<=(const NzQuaternion& quat) const;
|
||||||
static NzQuaternion Identity();
|
bool operator>(const NzQuaternion& quat) const;
|
||||||
static NzQuaternion Slerp(const NzQuaternion& quatA, const NzQuaternion& quatB, T interp);
|
bool operator>=(const NzQuaternion& quat) const;
|
||||||
static NzQuaternion Zero();
|
|
||||||
|
static NzQuaternion Identity();
|
||||||
T w, x, y, z;
|
static NzQuaternion Slerp(const NzQuaternion& quatA, const NzQuaternion& quatB, T interp);
|
||||||
};
|
static NzQuaternion Zero();
|
||||||
|
|
||||||
template<typename T> std::ostream& operator<<(std::ostream& out, const NzQuaternion<T>& quat);
|
T w, x, y, z;
|
||||||
|
};
|
||||||
typedef NzQuaternion<double> NzQuaterniond;
|
|
||||||
typedef NzQuaternion<float> NzQuaternionf;
|
template<typename T> std::ostream& operator<<(std::ostream& out, const NzQuaternion<T>& quat);
|
||||||
|
|
||||||
#include <Nazara/Math/Quaternion.inl>
|
typedef NzQuaternion<double> NzQuaterniond;
|
||||||
|
typedef NzQuaternion<float> NzQuaternionf;
|
||||||
#endif // NAZARA_QUATERNION_HPP
|
|
||||||
|
#include <Nazara/Math/Quaternion.inl>
|
||||||
|
|
||||||
|
#endif // NAZARA_QUATERNION_HPP
|
||||||
|
|
|
||||||
|
|
@ -1,403 +1,428 @@
|
||||||
// Copyright (C) 2012 Rémi Bèges - Jérôme Leclercq
|
// Copyright (C) 2012 Rémi Bèges - Jérôme Leclercq
|
||||||
// This file is part of the "Nazara Engine - Mathematics module"
|
// This file is part of the "Nazara Engine - Mathematics module"
|
||||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||||
|
|
||||||
#include <Nazara/Core/StringStream.hpp>
|
#include <Nazara/Core/StringStream.hpp>
|
||||||
#include <Nazara/Math/Basic.hpp>
|
#include <Nazara/Math/Basic.hpp>
|
||||||
#include <Nazara/Math/Config.hpp>
|
#include <Nazara/Math/Config.hpp>
|
||||||
#include <Nazara/Math/EulerAngles.hpp>
|
#include <Nazara/Math/EulerAngles.hpp>
|
||||||
#include <Nazara/Math/Vector3.hpp>
|
#include <Nazara/Math/Vector3.hpp>
|
||||||
#include <limits>
|
#include <limits>
|
||||||
#include <Nazara/Core/Debug.hpp>
|
#include <Nazara/Core/Debug.hpp>
|
||||||
|
|
||||||
#define F(a) static_cast<T>(a)
|
#define F(a) static_cast<T>(a)
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
NzQuaternion<T>::NzQuaternion()
|
NzQuaternion<T>::NzQuaternion()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
NzQuaternion<T>::NzQuaternion(T W, T X, T Y, T Z)
|
NzQuaternion<T>::NzQuaternion(T W, T X, T Y, T Z)
|
||||||
{
|
{
|
||||||
Set(W, X, Y, Z);
|
Set(W, X, Y, Z);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
NzQuaternion<T>::NzQuaternion(T quat[4])
|
NzQuaternion<T>::NzQuaternion(T quat[4])
|
||||||
{
|
{
|
||||||
Set(quat);
|
Set(quat);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
NzQuaternion<T>::NzQuaternion(T angle, const NzVector3<T>& axis)
|
NzQuaternion<T>::NzQuaternion(T angle, const NzVector3<T>& axis)
|
||||||
{
|
{
|
||||||
Set(angle, axis);
|
Set(angle, axis);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
NzQuaternion<T>::NzQuaternion(const NzEulerAngles<T>& angles)
|
NzQuaternion<T>::NzQuaternion(const NzEulerAngles<T>& angles)
|
||||||
{
|
{
|
||||||
Set(angles);
|
Set(angles);
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
template<typename T>
|
template<typename T>
|
||||||
NzQuaternion<T>::NzQuaternion(const NzMatrix3<T>& mat)
|
NzQuaternion<T>::NzQuaternion(const NzMatrix3<T>& mat)
|
||||||
{
|
{
|
||||||
Set(mat);
|
Set(mat);
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
template<typename T>
|
template<typename T>
|
||||||
template<typename U>
|
template<typename U>
|
||||||
NzQuaternion<T>::NzQuaternion(const NzQuaternion<U>& quat)
|
NzQuaternion<T>::NzQuaternion(const NzQuaternion<U>& quat)
|
||||||
{
|
{
|
||||||
Set(quat);
|
Set(quat);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
T NzQuaternion<T>::DotProduct(const NzQuaternion& quat) const
|
T NzQuaternion<T>::DotProduct(const NzQuaternion& quat) const
|
||||||
{
|
{
|
||||||
return w*quat.w + x*quat.x + y*quat.y + z*quat.z;
|
return w*quat.w + x*quat.x + y*quat.y + z*quat.z;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
NzQuaternion<T> NzQuaternion<T>::GetConjugate() const
|
NzQuaternion<T> NzQuaternion<T>::GetConjugate() const
|
||||||
{
|
{
|
||||||
return NzQuaternion(w, -x, -y, -z);
|
return NzQuaternion(w, -x, -y, -z);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
NzQuaternion<T> NzQuaternion<T>::GetNormalized() const
|
NzQuaternion<T> NzQuaternion<T>::GetInverse() const
|
||||||
{
|
{
|
||||||
NzQuaternion<T> quat(*this);
|
NzQuaternion<T> quat(*this);
|
||||||
quat.Normalize();
|
quat.Inverse();
|
||||||
|
|
||||||
return quat;
|
return quat;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
void NzQuaternion<T>::MakeIdentity()
|
NzQuaternion<T> NzQuaternion<T>::GetNormal() const
|
||||||
{
|
{
|
||||||
Set(1.0, 0.0, 0.0, 0.0);
|
NzQuaternion<T> quat(*this);
|
||||||
}
|
quat.Normalize();
|
||||||
|
|
||||||
template<typename T>
|
return quat;
|
||||||
void NzQuaternion<T>::MakeZero()
|
}
|
||||||
{
|
|
||||||
Set(0.0, 0.0, 0.0, 0.0);
|
template<typename T>
|
||||||
}
|
void NzQuaternion<T>::Inverse()
|
||||||
|
{
|
||||||
template<typename T>
|
T norm = SquaredMagnitude();
|
||||||
T NzQuaternion<T>::Magnitude() const
|
if (norm > F(0.0))
|
||||||
{
|
{
|
||||||
return std::sqrt(SquaredMagnitude());
|
T invNorm = F(1.0) / norm;
|
||||||
}
|
|
||||||
|
w *= invNorm;
|
||||||
template<typename T>
|
x *= -invNorm;
|
||||||
T NzQuaternion<T>::Normalize()
|
y *= -invNorm;
|
||||||
{
|
z *= -invNorm;
|
||||||
T squaredMagnitude = SquaredMagnitude();
|
}
|
||||||
|
}
|
||||||
if (squaredMagnitude-F(1.0) > std::numeric_limits<T>::epsilon())
|
|
||||||
{
|
template<typename T>
|
||||||
T magnitude = std::sqrt(squaredMagnitude);
|
void NzQuaternion<T>::MakeIdentity()
|
||||||
|
{
|
||||||
w /= magnitude;
|
Set(F(1.0), F(0.0), F(0.0), F(0.0));
|
||||||
x /= magnitude;
|
}
|
||||||
y /= magnitude;
|
|
||||||
z /= magnitude;
|
template<typename T>
|
||||||
|
void NzQuaternion<T>::MakeZero()
|
||||||
return magnitude;
|
{
|
||||||
}
|
Set(F(0.0), F(0.0), F(0.0), F(0.0));
|
||||||
else
|
}
|
||||||
return F(1.0); // Le quaternion est déjà normalisé
|
|
||||||
}
|
template<typename T>
|
||||||
|
T NzQuaternion<T>::Magnitude() const
|
||||||
template<typename T>
|
{
|
||||||
void NzQuaternion<T>::Set(T W, T X, T Y, T Z)
|
return std::sqrt(SquaredMagnitude());
|
||||||
{
|
}
|
||||||
w = W;
|
|
||||||
x = X;
|
template<typename T>
|
||||||
y = Y;
|
T NzQuaternion<T>::Normalize()
|
||||||
z = Z;
|
{
|
||||||
}
|
T squaredMagnitude = SquaredMagnitude();
|
||||||
|
|
||||||
template<typename T>
|
// Inutile de vérifier si la magnitude au carrée est négative (Elle ne peut pas l'être)
|
||||||
void NzQuaternion<T>::Set(T quat[4])
|
if (!NzNumberEquals(squaredMagnitude, F(1.0)))
|
||||||
{
|
{
|
||||||
w = quat[0];
|
T norm = std::sqrt(squaredMagnitude);
|
||||||
x = quat[1];
|
T invNorm = F(1.0) / norm;
|
||||||
y = quat[2];
|
|
||||||
z = quat[3];
|
w *= invNorm;
|
||||||
}
|
x *= invNorm;
|
||||||
|
y *= invNorm;
|
||||||
template<typename T>
|
z *= invNorm;
|
||||||
void NzQuaternion<T>::Set(T angle, const NzVector3<T>& normalizedAxis)
|
|
||||||
{
|
return norm;
|
||||||
#if !NAZARA_MATH_ANGLE_RADIAN
|
}
|
||||||
angle = NzDegreeToRadian(angle);
|
else
|
||||||
#endif
|
return F(1.0); // Le quaternion est déjà normalisé
|
||||||
|
}
|
||||||
angle /= 2;
|
|
||||||
|
template<typename T>
|
||||||
auto sinAngle = std::sin(angle);
|
void NzQuaternion<T>::Set(T W, T X, T Y, T Z)
|
||||||
|
{
|
||||||
w = std::cos(angle);
|
w = W;
|
||||||
x = normalizedAxis.x * sinAngle;
|
x = X;
|
||||||
y = normalizedAxis.y * sinAngle;
|
y = Y;
|
||||||
z = normalizedAxis.z * sinAngle;
|
z = Z;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
void NzQuaternion<T>::Set(const NzEulerAngles<T>& angles)
|
void NzQuaternion<T>::Set(T quat[4])
|
||||||
{
|
{
|
||||||
Set(angles.ToQuaternion());
|
w = quat[0];
|
||||||
}
|
x = quat[1];
|
||||||
|
y = quat[2];
|
||||||
template<typename T>
|
z = quat[3];
|
||||||
template<typename U>
|
}
|
||||||
void NzQuaternion<T>::Set(const NzQuaternion<U>& quat)
|
|
||||||
{
|
template<typename T>
|
||||||
w = static_cast<T>(quat.w);
|
void NzQuaternion<T>::Set(T angle, const NzVector3<T>& axis)
|
||||||
x = static_cast<T>(quat.x);
|
{
|
||||||
y = static_cast<T>(quat.y);
|
angle /= F(2.0);
|
||||||
z = static_cast<T>(quat.z);
|
|
||||||
}
|
#if !NAZARA_MATH_ANGLE_RADIAN
|
||||||
|
angle = NzDegreeToRadian(angle);
|
||||||
template<typename T>
|
#endif
|
||||||
void NzQuaternion<T>::Set(const NzQuaternion& quat)
|
|
||||||
{
|
NzVector3<T> normalizedAxis = axis.GetNormal();
|
||||||
w = quat.w;
|
|
||||||
x = quat.x;
|
T sinAngle = std::sin(angle);
|
||||||
y = quat.y;
|
|
||||||
z = quat.z;
|
w = std::cos(angle);
|
||||||
}
|
x = normalizedAxis.x * sinAngle;
|
||||||
|
y = normalizedAxis.y * sinAngle;
|
||||||
template<typename T>
|
z = normalizedAxis.z * sinAngle;
|
||||||
T NzQuaternion<T>::SquaredMagnitude() const
|
|
||||||
{
|
Normalize();
|
||||||
return w*w + x*x + y*y + z*z;
|
}
|
||||||
}
|
|
||||||
|
template<typename T>
|
||||||
template<typename T>
|
void NzQuaternion<T>::Set(const NzEulerAngles<T>& angles)
|
||||||
NzEulerAngles<T> NzQuaternion<T>::ToEulerAngles() const
|
{
|
||||||
{
|
Set(angles.ToQuaternion());
|
||||||
T test = x*y + z*w;
|
}
|
||||||
if (test > F(0.499))
|
|
||||||
// singularity at north pole
|
template<typename T>
|
||||||
return NzEulerAngles<T>(NzDegrees(F(90.0)), NzRadians(F(2.0) * std::atan2(x, w)), F(0.0));
|
template<typename U>
|
||||||
|
void NzQuaternion<T>::Set(const NzQuaternion<U>& quat)
|
||||||
if (test < F(-0.499))
|
{
|
||||||
return NzEulerAngles<T>(NzDegrees(F(-90.0)), NzRadians(F(-2.0) * std::atan2(x, w)), F(0.0));
|
w = static_cast<T>(quat.w);
|
||||||
|
x = static_cast<T>(quat.x);
|
||||||
T xx = x*x;
|
y = static_cast<T>(quat.y);
|
||||||
T yy = y*y;
|
z = static_cast<T>(quat.z);
|
||||||
T zz = z*z;
|
}
|
||||||
|
|
||||||
return NzEulerAngles<T>(NzRadians(std::atan2(F(2.0)*x*w - F(2.0)*y*z, F(1.0) - F(2.0)*xx - F(2.0)*zz)),
|
template<typename T>
|
||||||
NzRadians(std::atan2(F(2.0)*y*w - F(2.0)*x*z, F(1.0) - F(2.0)*yy - F(2.0)*zz)),
|
void NzQuaternion<T>::Set(const NzQuaternion& quat)
|
||||||
NzRadians(std::asin(F(2.0)*test)));
|
{
|
||||||
}
|
w = quat.w;
|
||||||
|
x = quat.x;
|
||||||
template<typename T>
|
y = quat.y;
|
||||||
NzString NzQuaternion<T>::ToString() const
|
z = quat.z;
|
||||||
{
|
}
|
||||||
NzStringStream ss;
|
|
||||||
|
template<typename T>
|
||||||
return ss << "Quaternion(" << w << " | " << x << ", " << y << ", " << z << ')';
|
T NzQuaternion<T>::SquaredMagnitude() const
|
||||||
}
|
{
|
||||||
|
return w*w + x*x + y*y + z*z;
|
||||||
template<typename T>
|
}
|
||||||
NzQuaternion<T>::operator NzString() const
|
|
||||||
{
|
template<typename T>
|
||||||
return ToString();
|
NzEulerAngles<T> NzQuaternion<T>::ToEulerAngles() const
|
||||||
}
|
{
|
||||||
|
T test = x*y + z*w;
|
||||||
template<typename T>
|
if (test > F(0.499))
|
||||||
NzQuaternion<T>& NzQuaternion<T>::operator=(const NzQuaternion& quat)
|
// singularity at north pole
|
||||||
{
|
return NzEulerAngles<T>(NzDegrees(F(90.0)), NzRadians(F(2.0) * std::atan2(x, w)), F(0.0));
|
||||||
Set(quat);
|
|
||||||
|
if (test < F(-0.499))
|
||||||
return *this;
|
return NzEulerAngles<T>(NzDegrees(F(-90.0)), NzRadians(F(-2.0) * std::atan2(x, w)), F(0.0));
|
||||||
}
|
|
||||||
|
return NzEulerAngles<T>(NzRadians(std::atan2(F(2.0)*x*w - F(2.0)*y*z, F(1.0) - F(2.0)*x* - F(2.0)*z*z)),
|
||||||
template<typename T>
|
NzRadians(std::atan2(F(2.0)*y*w - F(2.0)*x*z, F(1.0) - F(2.0)*y*y - F(2.0)*z*z)),
|
||||||
NzQuaternion<T> NzQuaternion<T>::operator+(const NzQuaternion& quat) const
|
NzRadians(std::asin(F(2.0)*test)));
|
||||||
{
|
}
|
||||||
return NzQuaternion(w + quat.w,
|
|
||||||
x + quat.x,
|
template<typename T>
|
||||||
y + quat.y,
|
NzString NzQuaternion<T>::ToString() const
|
||||||
z + quat.z);
|
{
|
||||||
}
|
NzStringStream ss;
|
||||||
|
|
||||||
template<typename T>
|
return ss << "Quaternion(" << w << " | " << x << ", " << y << ", " << z << ')';
|
||||||
NzQuaternion<T> NzQuaternion<T>::operator*(const NzQuaternion& quat) const
|
}
|
||||||
{
|
|
||||||
return NzQuaternion(w*quat.w - x*quat.x - y*quat.y - z*quat.z,
|
template<typename T>
|
||||||
w*quat.x + x*quat.w + y*quat.z - z*quat.y,
|
NzQuaternion<T>::operator NzString() const
|
||||||
w*quat.y + y*quat.w + z*quat.x - x*quat.z,
|
{
|
||||||
w*quat.z + z*quat.w + x*quat.y - y*quat.x);
|
return ToString();
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
NzVector3<T> NzQuaternion<T>::operator*(const NzVector3<T>& vec) const
|
NzQuaternion<T>& NzQuaternion<T>::operator=(const NzQuaternion& quat)
|
||||||
{
|
{
|
||||||
NzVector3<T> normal(vec);
|
Set(quat);
|
||||||
normal.Normalize();
|
|
||||||
|
return *this;
|
||||||
NzQuaternion qvec(0.0, normal.x, normal.y, normal.z);
|
}
|
||||||
NzQuaternion result(operator*(qvec * GetConjugate()));
|
|
||||||
|
template<typename T>
|
||||||
return NzVector3<T>(result.x, result.y, result.z);
|
NzQuaternion<T> NzQuaternion<T>::operator+(const NzQuaternion& quat) const
|
||||||
|
{
|
||||||
}
|
return NzQuaternion(w + quat.w,
|
||||||
|
x + quat.x,
|
||||||
template<typename T>
|
y + quat.y,
|
||||||
NzQuaternion<T> NzQuaternion<T>::operator*(T scale) const
|
z + quat.z);
|
||||||
{
|
}
|
||||||
return NzQuaternion(w * scale,
|
|
||||||
x * scale,
|
template<typename T>
|
||||||
y * scale,
|
NzQuaternion<T> NzQuaternion<T>::operator*(const NzQuaternion& quat) const
|
||||||
z * scale);
|
{
|
||||||
}
|
return NzQuaternion(w*quat.w - x*quat.x - y*quat.y - z*quat.z,
|
||||||
|
w*quat.x + x*quat.w + y*quat.z - z*quat.y,
|
||||||
template<typename T>
|
w*quat.y + y*quat.w + z*quat.x - x*quat.z,
|
||||||
NzQuaternion<T> NzQuaternion<T>::operator/(const NzQuaternion& quat) const
|
w*quat.z + z*quat.w + x*quat.y - y*quat.x);
|
||||||
{
|
}
|
||||||
return GetConjugate(quat) * (*this);
|
|
||||||
}
|
template<typename T>
|
||||||
|
NzVector3<T> NzQuaternion<T>::operator*(const NzVector3<T>& vec) const
|
||||||
template<typename T>
|
{
|
||||||
NzQuaternion<T>& NzQuaternion<T>::operator+=(const NzQuaternion& quat)
|
NzVector3f quatVec(x, y, z);
|
||||||
{
|
NzVector3f uv = quatVec.CrossProduct(vec);
|
||||||
return operator=(operator+(quat));
|
NzVector3f uuv = quatVec.CrossProduct(uv);
|
||||||
}
|
uv *= F(2.0) * w;
|
||||||
|
uuv *= F(2.0);
|
||||||
template<typename T>
|
|
||||||
NzQuaternion<T>& NzQuaternion<T>::operator*=(const NzQuaternion& quat)
|
return vec + uv + uuv;
|
||||||
{
|
}
|
||||||
return operator=(operator*(quat));
|
|
||||||
}
|
template<typename T>
|
||||||
|
NzQuaternion<T> NzQuaternion<T>::operator*(T scale) const
|
||||||
template<typename T>
|
{
|
||||||
NzQuaternion<T>& NzQuaternion<T>::operator*=(T scale)
|
return NzQuaternion(w * scale,
|
||||||
{
|
x * scale,
|
||||||
return operator=(operator*(scale));
|
y * scale,
|
||||||
}
|
z * scale);
|
||||||
|
}
|
||||||
template<typename T>
|
|
||||||
NzQuaternion<T>& NzQuaternion<T>::operator/=(const NzQuaternion& quat)
|
template<typename T>
|
||||||
{
|
NzQuaternion<T> NzQuaternion<T>::operator/(const NzQuaternion& quat) const
|
||||||
return operator=(operator/(quat));
|
{
|
||||||
}
|
return GetConjugate(quat) * (*this);
|
||||||
|
}
|
||||||
template<typename T>
|
|
||||||
bool NzQuaternion<T>::operator==(const NzQuaternion& quat) const
|
template<typename T>
|
||||||
{
|
NzQuaternion<T>& NzQuaternion<T>::operator+=(const NzQuaternion& quat)
|
||||||
return NzNumberEquals(w, quat.w) &&
|
{
|
||||||
NzNumberEquals(x, quat.x) &&
|
return operator=(operator+(quat));
|
||||||
NzNumberEquals(y, quat.y) &&
|
}
|
||||||
NzNumberEquals(z, quat.z);
|
|
||||||
}
|
template<typename T>
|
||||||
|
NzQuaternion<T>& NzQuaternion<T>::operator*=(const NzQuaternion& quat)
|
||||||
template<typename T>
|
{
|
||||||
bool NzQuaternion<T>::operator!=(const NzQuaternion& quat) const
|
return operator=(operator*(quat));
|
||||||
{
|
}
|
||||||
return !operator==(quat);
|
|
||||||
}
|
template<typename T>
|
||||||
|
NzQuaternion<T>& NzQuaternion<T>::operator*=(T scale)
|
||||||
template<typename T>
|
{
|
||||||
bool NzQuaternion<T>::operator<(const NzQuaternion& quat) const
|
return operator=(operator*(scale));
|
||||||
{
|
}
|
||||||
return w < quat.w && x < quat.x && y < quat.y && z < quat.z;
|
|
||||||
}
|
template<typename T>
|
||||||
|
NzQuaternion<T>& NzQuaternion<T>::operator/=(const NzQuaternion& quat)
|
||||||
template<typename T>
|
{
|
||||||
bool NzQuaternion<T>::operator<=(const NzQuaternion& quat) const
|
return operator=(operator/(quat));
|
||||||
{
|
}
|
||||||
return operator<(quat) || operator==(quat);
|
|
||||||
}
|
template<typename T>
|
||||||
|
bool NzQuaternion<T>::operator==(const NzQuaternion& quat) const
|
||||||
template<typename T>
|
{
|
||||||
bool NzQuaternion<T>::operator>(const NzQuaternion& quat) const
|
return NzNumberEquals(w, quat.w) &&
|
||||||
{
|
NzNumberEquals(x, quat.x) &&
|
||||||
return !operator<=(quat);
|
NzNumberEquals(y, quat.y) &&
|
||||||
}
|
NzNumberEquals(z, quat.z);
|
||||||
|
}
|
||||||
template<typename T>
|
|
||||||
bool NzQuaternion<T>::operator>=(const NzQuaternion& quat) const
|
template<typename T>
|
||||||
{
|
bool NzQuaternion<T>::operator!=(const NzQuaternion& quat) const
|
||||||
return !operator<(quat);
|
{
|
||||||
}
|
return !operator==(quat);
|
||||||
|
}
|
||||||
template<typename T>
|
|
||||||
NzQuaternion<T> NzQuaternion<T>::Identity()
|
template<typename T>
|
||||||
{
|
bool NzQuaternion<T>::operator<(const NzQuaternion& quat) const
|
||||||
NzQuaternion quaternion;
|
{
|
||||||
quaternion.MakeIdentity();
|
return w < quat.w && x < quat.x && y < quat.y && z < quat.z;
|
||||||
|
}
|
||||||
return quaternion;
|
|
||||||
}
|
template<typename T>
|
||||||
|
bool NzQuaternion<T>::operator<=(const NzQuaternion& quat) const
|
||||||
template<typename T>
|
{
|
||||||
NzQuaternion<T> NzQuaternion<T>::Slerp(const NzQuaternion& quatA, const NzQuaternion& quatB, T interp)
|
return operator<(quat) || operator==(quat);
|
||||||
{
|
}
|
||||||
if (interp <= F(0.0))
|
|
||||||
return quatA;
|
template<typename T>
|
||||||
|
bool NzQuaternion<T>::operator>(const NzQuaternion& quat) const
|
||||||
if (interp >= F(1.0))
|
{
|
||||||
return quatB;
|
return !operator<=(quat);
|
||||||
|
}
|
||||||
NzQuaternion q;
|
|
||||||
|
template<typename T>
|
||||||
T cosOmega = quatA.DotProduct(quatB);
|
bool NzQuaternion<T>::operator>=(const NzQuaternion& quat) const
|
||||||
if (cosOmega < F(0.0))
|
{
|
||||||
{
|
return !operator<(quat);
|
||||||
// On inverse tout
|
}
|
||||||
q.Set(-quatB.w, -quatB.x, -quatB.y, -quatB.z);
|
|
||||||
cosOmega = -cosOmega;
|
template<typename T>
|
||||||
}
|
NzQuaternion<T> NzQuaternion<T>::Identity()
|
||||||
else
|
{
|
||||||
q.Set(quatB);
|
NzQuaternion quaternion;
|
||||||
|
quaternion.MakeIdentity();
|
||||||
T k0, k1;
|
|
||||||
if (cosOmega > F(0.9999))
|
return quaternion;
|
||||||
{
|
}
|
||||||
// Interpolation linéaire pour éviter une division par zéro
|
|
||||||
k0 = F(1.0) - interp;
|
template<typename T>
|
||||||
k1 = interp;
|
NzQuaternion<T> NzQuaternion<T>::Slerp(const NzQuaternion& quatA, const NzQuaternion& quatB, T interp)
|
||||||
}
|
{
|
||||||
else
|
if (interp <= F(0.0))
|
||||||
{
|
return quatA;
|
||||||
T sinOmega = std::sqrt(F(1.0) - cosOmega*cosOmega);
|
|
||||||
T omega = std::atan2(sinOmega, cosOmega);
|
if (interp >= F(1.0))
|
||||||
|
return quatB;
|
||||||
// Pour éviter deux divisions
|
|
||||||
sinOmega = F(1.0)/sinOmega;
|
NzQuaternion q;
|
||||||
|
|
||||||
k0 = std::sin((F(1.0) - interp) * omega) * sinOmega;
|
T cosOmega = quatA.DotProduct(quatB);
|
||||||
k1 = std::sin(interp*omega) * sinOmega;
|
if (cosOmega < F(0.0))
|
||||||
}
|
{
|
||||||
|
// On inverse tout
|
||||||
NzQuaternion result(k0 * quatA.w, k0 * quatA.x, k0 * quatA.y, k0 * quatA.z);
|
q.Set(-quatB.w, -quatB.x, -quatB.y, -quatB.z);
|
||||||
return result += q*k1;
|
cosOmega = -cosOmega;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
template<typename T>
|
q.Set(quatB);
|
||||||
NzQuaternion<T> NzQuaternion<T>::Zero()
|
|
||||||
{
|
T k0, k1;
|
||||||
NzQuaternion quaternion;
|
if (cosOmega > F(0.9999))
|
||||||
quaternion.MakeZero();
|
{
|
||||||
|
// Interpolation linéaire pour éviter une division par zéro
|
||||||
return quaternion;
|
k0 = F(1.0) - interp;
|
||||||
}
|
k1 = interp;
|
||||||
|
}
|
||||||
template<typename T>
|
else
|
||||||
std::ostream& operator<<(std::ostream& out, const NzQuaternion<T>& quat)
|
{
|
||||||
{
|
T sinOmega = std::sqrt(F(1.0) - cosOmega*cosOmega);
|
||||||
return out << quat.ToString();
|
T omega = std::atan2(sinOmega, cosOmega);
|
||||||
}
|
|
||||||
|
// Pour éviter deux divisions
|
||||||
#undef F
|
sinOmega = F(1.0)/sinOmega;
|
||||||
|
|
||||||
#include <Nazara/Core/DebugOff.hpp>
|
k0 = std::sin((F(1.0) - interp) * omega) * sinOmega;
|
||||||
|
k1 = std::sin(interp*omega) * sinOmega;
|
||||||
|
}
|
||||||
|
|
||||||
|
NzQuaternion result(k0 * quatA.w, k0 * quatA.x, k0 * quatA.y, k0 * quatA.z);
|
||||||
|
return result += q*k1;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
NzQuaternion<T> NzQuaternion<T>::Zero()
|
||||||
|
{
|
||||||
|
NzQuaternion quaternion;
|
||||||
|
quaternion.MakeZero();
|
||||||
|
|
||||||
|
return quaternion;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
std::ostream& operator<<(std::ostream& out, const NzQuaternion<T>& quat)
|
||||||
|
{
|
||||||
|
return out << quat.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
#undef F
|
||||||
|
|
||||||
|
#include <Nazara/Core/DebugOff.hpp>
|
||||||
|
|
|
||||||
|
|
@ -1,104 +1,105 @@
|
||||||
// Copyright (C) 2012 Jérôme Leclercq
|
// Copyright (C) 2012 Jérôme Leclercq
|
||||||
// This file is part of the "Nazara Engine - Mathematics module"
|
// This file is part of the "Nazara Engine - Mathematics module"
|
||||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#ifndef NAZARA_VECTOR2_HPP
|
#ifndef NAZARA_VECTOR2_HPP
|
||||||
#define NAZARA_VECTOR2_HPP
|
#define NAZARA_VECTOR2_HPP
|
||||||
|
|
||||||
#include <Nazara/Core/String.hpp>
|
#include <Nazara/Core/String.hpp>
|
||||||
|
|
||||||
template<typename T> class NzVector2
|
template<typename T> class NzVector2
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
NzVector2();
|
NzVector2();
|
||||||
NzVector2(T X, T Y);
|
NzVector2(T X, T Y);
|
||||||
explicit NzVector2(T scale);
|
explicit NzVector2(T scale);
|
||||||
NzVector2(T vec[2]);
|
NzVector2(T vec[2]);
|
||||||
template<typename U> explicit NzVector2(const NzVector2<U>& vec);
|
template<typename U> explicit NzVector2(const NzVector2<U>& vec);
|
||||||
NzVector2(const NzVector2& vec) = default;
|
NzVector2(const NzVector2& vec) = default;
|
||||||
~NzVector2() = default;
|
~NzVector2() = default;
|
||||||
|
|
||||||
T AbsDotProduct(const NzVector2& vec) const;
|
T AbsDotProduct(const NzVector2& vec) const;
|
||||||
|
|
||||||
T Distance(const NzVector2& vec) const;
|
T Distance(const NzVector2& vec) const;
|
||||||
float Distancef(const NzVector2& vec) const;
|
float Distancef(const NzVector2& vec) const;
|
||||||
|
|
||||||
T DotProduct(const NzVector2& vec) const;
|
T DotProduct(const NzVector2& vec) const;
|
||||||
|
|
||||||
NzVector2 GetNormal() const;
|
NzVector2 GetNormal() const;
|
||||||
|
|
||||||
void MakeCeil(const NzVector2& vec);
|
T Length() const;
|
||||||
void MakeFloor(const NzVector2& vec);
|
float Lengthf() const;
|
||||||
void MakeUnitX();
|
|
||||||
void MakeUnitY();
|
void MakeUnitX();
|
||||||
void MakeZero();
|
void MakeUnitY();
|
||||||
|
void MakeZero();
|
||||||
T Length() const;
|
|
||||||
float Lengthf() const;
|
void Maximize(const NzVector2& vec);
|
||||||
|
void Minimize(const NzVector2& vec);
|
||||||
void Normalize();
|
|
||||||
|
void Normalize();
|
||||||
void Set(T X, T Y);
|
|
||||||
void Set(T scale);
|
void Set(T X, T Y);
|
||||||
void Set(T vec[2]);
|
void Set(T scale);
|
||||||
template<typename U> void Set(const NzVector2<U>& vec);
|
void Set(T vec[2]);
|
||||||
|
template<typename U> void Set(const NzVector2<U>& vec);
|
||||||
T SquaredDistance(const NzVector2& vec) const;
|
|
||||||
T SquaredLength() const;
|
T SquaredDistance(const NzVector2& vec) const;
|
||||||
|
T SquaredLength() const;
|
||||||
NzString ToString() const;
|
|
||||||
|
NzString ToString() const;
|
||||||
operator NzString() const;
|
|
||||||
|
operator NzString() const;
|
||||||
operator T*();
|
|
||||||
operator const T*() const;
|
operator T*();
|
||||||
|
operator const T*() const;
|
||||||
T& operator[](unsigned int i);
|
|
||||||
T operator[](unsigned int i) const;
|
T& operator[](unsigned int i);
|
||||||
|
T operator[](unsigned int i) const;
|
||||||
const NzVector2& operator+() const;
|
|
||||||
NzVector2 operator-() const;
|
const NzVector2& operator+() const;
|
||||||
|
NzVector2 operator-() const;
|
||||||
NzVector2 operator+(const NzVector2& vec) const;
|
|
||||||
NzVector2 operator-(const NzVector2& vec) const;
|
NzVector2 operator+(const NzVector2& vec) const;
|
||||||
NzVector2 operator*(const NzVector2& vec) const;
|
NzVector2 operator-(const NzVector2& vec) const;
|
||||||
NzVector2 operator*(T scale) const;
|
NzVector2 operator*(const NzVector2& vec) const;
|
||||||
NzVector2 operator/(const NzVector2& vec) const;
|
NzVector2 operator*(T scale) const;
|
||||||
NzVector2 operator/(T scale) const;
|
NzVector2 operator/(const NzVector2& vec) const;
|
||||||
|
NzVector2 operator/(T scale) const;
|
||||||
NzVector2& operator+=(const NzVector2& vec);
|
|
||||||
NzVector2& operator-=(const NzVector2& vec);
|
NzVector2& operator+=(const NzVector2& vec);
|
||||||
NzVector2& operator*=(const NzVector2& vec);
|
NzVector2& operator-=(const NzVector2& vec);
|
||||||
NzVector2& operator*=(T scale);
|
NzVector2& operator*=(const NzVector2& vec);
|
||||||
NzVector2& operator/=(const NzVector2& vec);
|
NzVector2& operator*=(T scale);
|
||||||
NzVector2& operator/=(T scale);
|
NzVector2& operator/=(const NzVector2& vec);
|
||||||
|
NzVector2& operator/=(T scale);
|
||||||
bool operator==(const NzVector2& vec) const;
|
|
||||||
bool operator!=(const NzVector2& vec) const;
|
bool operator==(const NzVector2& vec) const;
|
||||||
bool operator<(const NzVector2& vec) const;
|
bool operator!=(const NzVector2& vec) const;
|
||||||
bool operator<=(const NzVector2& vec) const;
|
bool operator<(const NzVector2& vec) const;
|
||||||
bool operator>(const NzVector2& vec) const;
|
bool operator<=(const NzVector2& vec) const;
|
||||||
bool operator>=(const NzVector2& vec) const;
|
bool operator>(const NzVector2& vec) const;
|
||||||
|
bool operator>=(const NzVector2& vec) const;
|
||||||
static NzVector2 UnitX();
|
|
||||||
static NzVector2 UnitY();
|
static NzVector2 UnitX();
|
||||||
static NzVector2 Zero();
|
static NzVector2 UnitY();
|
||||||
|
static NzVector2 Zero();
|
||||||
T x, y;
|
|
||||||
};
|
T x, y;
|
||||||
|
};
|
||||||
template<typename T> std::ostream& operator<<(std::ostream& out, const NzVector2<T>& vec);
|
|
||||||
|
template<typename T> std::ostream& operator<<(std::ostream& out, const NzVector2<T>& vec);
|
||||||
template<typename T> NzVector2<T> operator*(T scale, const NzVector2<T>& vec);
|
|
||||||
template<typename T> NzVector2<T> operator/(T scale, const NzVector2<T>& vec);
|
template<typename T> NzVector2<T> operator*(T scale, const NzVector2<T>& vec);
|
||||||
|
template<typename T> NzVector2<T> operator/(T scale, const NzVector2<T>& vec);
|
||||||
typedef NzVector2<double> NzVector2d;
|
|
||||||
typedef NzVector2<float> NzVector2f;
|
typedef NzVector2<double> NzVector2d;
|
||||||
typedef NzVector2<int> NzVector2i;
|
typedef NzVector2<float> NzVector2f;
|
||||||
typedef NzVector2<unsigned int> NzVector2ui;
|
typedef NzVector2<int> NzVector2i;
|
||||||
|
typedef NzVector2<unsigned int> NzVector2ui;
|
||||||
#include <Nazara/Math/Vector2.inl>
|
|
||||||
|
#include <Nazara/Math/Vector2.inl>
|
||||||
#endif // NAZARA_VECTOR2_HPP
|
|
||||||
|
#endif // NAZARA_VECTOR2_HPP
|
||||||
|
|
|
||||||
|
|
@ -1,488 +1,488 @@
|
||||||
// Copyright (C) 2012 Jérôme Leclercq
|
// Copyright (C) 2012 Jérôme Leclercq
|
||||||
// This file is part of the "Nazara Engine - Mathematics module"
|
// This file is part of the "Nazara Engine - Mathematics module"
|
||||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||||
|
|
||||||
#include <Nazara/Core/StringStream.hpp>
|
#include <Nazara/Core/StringStream.hpp>
|
||||||
#include <Nazara/Math/Basic.hpp>
|
#include <Nazara/Math/Basic.hpp>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <limits>
|
#include <limits>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include <Nazara/Core/Debug.hpp>
|
#include <Nazara/Core/Debug.hpp>
|
||||||
|
|
||||||
#define F(a) static_cast<T>(a)
|
#define F(a) static_cast<T>(a)
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
NzVector2<T>::NzVector2()
|
NzVector2<T>::NzVector2()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
NzVector2<T>::NzVector2(T X, T Y)
|
NzVector2<T>::NzVector2(T X, T Y)
|
||||||
{
|
{
|
||||||
Set(X, Y);
|
Set(X, Y);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
NzVector2<T>::NzVector2(T scale)
|
NzVector2<T>::NzVector2(T scale)
|
||||||
{
|
{
|
||||||
Set(scale);
|
Set(scale);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
NzVector2<T>::NzVector2(T vec[2])
|
NzVector2<T>::NzVector2(T vec[2])
|
||||||
{
|
{
|
||||||
Set(vec);
|
Set(vec);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
template<typename U>
|
template<typename U>
|
||||||
NzVector2<T>::NzVector2(const NzVector2<U>& vec)
|
NzVector2<T>::NzVector2(const NzVector2<U>& vec)
|
||||||
{
|
{
|
||||||
Set(vec);
|
Set(vec);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
T NzVector2<T>::AbsDotProduct(const NzVector2& vec) const
|
T NzVector2<T>::AbsDotProduct(const NzVector2& vec) const
|
||||||
{
|
{
|
||||||
return std::fabs(x * vec.x) + std::fabs(y * vec.y);
|
return std::fabs(x * vec.x) + std::fabs(y * vec.y);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
inline int NzVector2<int>::AbsDotProduct(const NzVector2<int>& vec) const
|
inline int NzVector2<int>::AbsDotProduct(const NzVector2<int>& vec) const
|
||||||
{
|
{
|
||||||
return std::labs(x * vec.x) + std::labs(y * vec.y);
|
return std::labs(x * vec.x) + std::labs(y * vec.y);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
inline unsigned int NzVector2<unsigned int>::AbsDotProduct(const NzVector2<unsigned int>& vec) const
|
inline unsigned int NzVector2<unsigned int>::AbsDotProduct(const NzVector2<unsigned int>& vec) const
|
||||||
{
|
{
|
||||||
return std::labs(x * vec.x) + std::labs(y * vec.y);
|
return std::labs(x * vec.x) + std::labs(y * vec.y);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
T NzVector2<T>::Distance(const NzVector2& vec) const
|
T NzVector2<T>::Distance(const NzVector2& vec) const
|
||||||
{
|
{
|
||||||
return std::sqrt(SquaredDistance(vec));
|
return std::sqrt(SquaredDistance(vec));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
float NzVector2<T>::Distancef(const NzVector2& vec) const
|
float NzVector2<T>::Distancef(const NzVector2& vec) const
|
||||||
{
|
{
|
||||||
return std::sqrt(static_cast<float>(SquaredDistance(vec)));
|
return std::sqrt(static_cast<float>(SquaredDistance(vec)));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
T NzVector2<T>::DotProduct(const NzVector2& vec) const
|
T NzVector2<T>::DotProduct(const NzVector2& vec) const
|
||||||
{
|
{
|
||||||
return x*vec.x + y*vec.y;
|
return x*vec.x + y*vec.y;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
NzVector2<T> NzVector2<T>::GetNormal() const
|
NzVector2<T> NzVector2<T>::GetNormal() const
|
||||||
{
|
{
|
||||||
NzVector2 vec(*this);
|
NzVector2 vec(*this);
|
||||||
vec.Normalize();
|
vec.Normalize();
|
||||||
|
|
||||||
return vec;
|
return vec;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
T NzVector2<T>::Length() const
|
T NzVector2<T>::Length() const
|
||||||
{
|
{
|
||||||
return std::sqrt(SquaredLength());
|
return std::sqrt(SquaredLength());
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
float NzVector2<T>::Lengthf() const
|
float NzVector2<T>::Lengthf() const
|
||||||
{
|
{
|
||||||
return std::sqrt(static_cast<float>(SquaredLength()));
|
return std::sqrt(static_cast<float>(SquaredLength()));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
void NzVector2<T>::MakeCeil(const NzVector2& vec)
|
void NzVector2<T>::MakeUnitX()
|
||||||
{
|
{
|
||||||
if (vec.x > x)
|
Set(F(1.0), F(0.0));
|
||||||
x = vec.x;
|
}
|
||||||
|
|
||||||
if (vec.y > y)
|
template<typename T>
|
||||||
y = vec.y;
|
void NzVector2<T>::MakeUnitY()
|
||||||
}
|
{
|
||||||
|
Set(F(0.0), F(1.0));
|
||||||
template<typename T>
|
}
|
||||||
void NzVector2<T>::MakeFloor(const NzVector2& vec)
|
|
||||||
{
|
template<typename T>
|
||||||
if (vec.x < x)
|
void NzVector2<T>::MakeZero()
|
||||||
x = vec.x;
|
{
|
||||||
|
Set(F(0.0), F(0.0));
|
||||||
if (vec.y < y)
|
}
|
||||||
y = vec.y;
|
|
||||||
}
|
template<typename T>
|
||||||
|
void NzVector2<T>::Maximize(const NzVector2& vec)
|
||||||
template<typename T>
|
{
|
||||||
void NzVector2<T>::MakeUnitX()
|
if (vec.x > x)
|
||||||
{
|
x = vec.x;
|
||||||
Set(F(1.0), F(0.0));
|
|
||||||
}
|
if (vec.y > y)
|
||||||
|
y = vec.y;
|
||||||
template<typename T>
|
}
|
||||||
void NzVector2<T>::MakeUnitY()
|
|
||||||
{
|
template<typename T>
|
||||||
Set(F(0.0), F(1.0));
|
void NzVector2<T>::Minimize(const NzVector2& vec)
|
||||||
}
|
{
|
||||||
|
if (vec.x < x)
|
||||||
template<typename T>
|
x = vec.x;
|
||||||
void NzVector2<T>::MakeZero()
|
|
||||||
{
|
if (vec.y < y)
|
||||||
Set(F(0.0), F(0.0));
|
y = vec.y;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
void NzVector2<T>::Normalize()
|
void NzVector2<T>::Normalize()
|
||||||
{
|
{
|
||||||
T squaredLength = SquaredLength();
|
T squaredLength = SquaredLength();
|
||||||
|
|
||||||
if (squaredLength-F(1.0) > std::numeric_limits<T>::epsilon())
|
if (squaredLength-F(1.0) > std::numeric_limits<T>::epsilon())
|
||||||
{
|
{
|
||||||
T length = std::sqrt(squaredLength);
|
T length = std::sqrt(squaredLength);
|
||||||
|
|
||||||
x /= length;
|
x /= length;
|
||||||
y /= length;
|
y /= length;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
void NzVector2<T>::Set(T X, T Y)
|
void NzVector2<T>::Set(T X, T Y)
|
||||||
{
|
{
|
||||||
x = X;
|
x = X;
|
||||||
y = Y;
|
y = Y;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
void NzVector2<T>::Set(T scale)
|
void NzVector2<T>::Set(T scale)
|
||||||
{
|
{
|
||||||
x = scale;
|
x = scale;
|
||||||
y = scale;
|
y = scale;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
void NzVector2<T>::Set(T vec[2])
|
void NzVector2<T>::Set(T vec[2])
|
||||||
{
|
{
|
||||||
std::memcpy(&x, vec, 2*sizeof(T));
|
std::memcpy(&x, vec, 2*sizeof(T));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
template<typename U>
|
template<typename U>
|
||||||
void NzVector2<T>::Set(const NzVector2<U>& vec)
|
void NzVector2<T>::Set(const NzVector2<U>& vec)
|
||||||
{
|
{
|
||||||
x = F(vec.x);
|
x = F(vec.x);
|
||||||
y = F(vec.y);
|
y = F(vec.y);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
T NzVector2<T>::SquaredDistance(const NzVector2& vec) const
|
T NzVector2<T>::SquaredDistance(const NzVector2& vec) const
|
||||||
{
|
{
|
||||||
return operator-(vec).SquaredLength();
|
return operator-(vec).SquaredLength();
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
T NzVector2<T>::SquaredLength() const
|
T NzVector2<T>::SquaredLength() const
|
||||||
{
|
{
|
||||||
return x*x + y*y;
|
return x*x + y*y;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
NzString NzVector2<T>::ToString() const
|
NzString NzVector2<T>::ToString() const
|
||||||
{
|
{
|
||||||
NzStringStream ss;
|
NzStringStream ss;
|
||||||
|
|
||||||
return ss << "Vector2(" << x << ", " << y << ')';
|
return ss << "Vector2(" << x << ", " << y << ')';
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
NzVector2<T>::operator NzString() const
|
NzVector2<T>::operator NzString() const
|
||||||
{
|
{
|
||||||
return ToString();
|
return ToString();
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
NzVector2<T>::operator T*()
|
NzVector2<T>::operator T*()
|
||||||
{
|
{
|
||||||
return &x;
|
return &x;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
NzVector2<T>::operator const T*() const
|
NzVector2<T>::operator const T*() const
|
||||||
{
|
{
|
||||||
return &x;
|
return &x;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
T& NzVector2<T>::operator[](unsigned int i)
|
T& NzVector2<T>::operator[](unsigned int i)
|
||||||
{
|
{
|
||||||
#if NAZARA_MATH_SAFE
|
#if NAZARA_MATH_SAFE
|
||||||
if (i >= 2)
|
if (i >= 2)
|
||||||
{
|
{
|
||||||
NzStringStream ss;
|
NzStringStream ss;
|
||||||
ss << __FILE__ << ':' << __LINE__ << ": Index out of range (" << i << " >= 2)";
|
ss << __FILE__ << ':' << __LINE__ << ": Index out of range (" << i << " >= 2)";
|
||||||
|
|
||||||
throw std::domain_error(ss.ToString());
|
throw std::domain_error(ss.ToString());
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return *(&x+i);
|
return *(&x+i);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
T NzVector2<T>::operator[](unsigned int i) const
|
T NzVector2<T>::operator[](unsigned int i) const
|
||||||
{
|
{
|
||||||
#if NAZARA_MATH_SAFE
|
#if NAZARA_MATH_SAFE
|
||||||
if (i >= 2)
|
if (i >= 2)
|
||||||
{
|
{
|
||||||
NzStringStream ss;
|
NzStringStream ss;
|
||||||
ss << __FILE__ << ':' << __LINE__ << ": Index out of range (" << i << " >= 2)";
|
ss << __FILE__ << ':' << __LINE__ << ": Index out of range (" << i << " >= 2)";
|
||||||
|
|
||||||
throw std::domain_error(ss.ToString());
|
throw std::domain_error(ss.ToString());
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return *(&x+i);
|
return *(&x+i);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
const NzVector2<T>& NzVector2<T>::operator+() const
|
const NzVector2<T>& NzVector2<T>::operator+() const
|
||||||
{
|
{
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
NzVector2<T> NzVector2<T>::operator-() const
|
NzVector2<T> NzVector2<T>::operator-() const
|
||||||
{
|
{
|
||||||
return NzVector2(-x, -y);
|
return NzVector2(-x, -y);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
NzVector2<T> NzVector2<T>::operator+(const NzVector2& vec) const
|
NzVector2<T> NzVector2<T>::operator+(const NzVector2& vec) const
|
||||||
{
|
{
|
||||||
return NzVector2(x + vec.x, y + vec.y);
|
return NzVector2(x + vec.x, y + vec.y);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
NzVector2<T> NzVector2<T>::operator-(const NzVector2& vec) const
|
NzVector2<T> NzVector2<T>::operator-(const NzVector2& vec) const
|
||||||
{
|
{
|
||||||
return NzVector2(x - vec.x, y - vec.y);
|
return NzVector2(x - vec.x, y - vec.y);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
NzVector2<T> NzVector2<T>::operator*(const NzVector2& vec) const
|
NzVector2<T> NzVector2<T>::operator*(const NzVector2& vec) const
|
||||||
{
|
{
|
||||||
return NzVector2(x * vec.x, y * vec.y);
|
return NzVector2(x * vec.x, y * vec.y);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
NzVector2<T> NzVector2<T>::operator*(T scale) const
|
NzVector2<T> NzVector2<T>::operator*(T scale) const
|
||||||
{
|
{
|
||||||
return NzVector2(x * scale, y * scale);
|
return NzVector2(x * scale, y * scale);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
NzVector2<T> NzVector2<T>::operator/(const NzVector2& vec) const
|
NzVector2<T> NzVector2<T>::operator/(const NzVector2& vec) const
|
||||||
{
|
{
|
||||||
#if NAZARA_MATH_SAFE
|
#if NAZARA_MATH_SAFE
|
||||||
if (NzNumberEquals(vec.x, F(0.0)) || NzNumberEquals(vec.y, F(0.0)))
|
if (NzNumberEquals(vec.x, F(0.0)) || NzNumberEquals(vec.y, F(0.0)))
|
||||||
{
|
{
|
||||||
NzStringStream ss;
|
NzStringStream ss;
|
||||||
ss << __FILE__ << ':' << __LINE__ << ": Division by zero";
|
ss << __FILE__ << ':' << __LINE__ << ": Division by zero";
|
||||||
|
|
||||||
throw std::domain_error(ss.ToString());
|
throw std::domain_error(ss.ToString());
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return NzVector2(x / vec.x, y / vec.y);
|
return NzVector2(x / vec.x, y / vec.y);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
NzVector2<T> NzVector2<T>::operator/(T scale) const
|
NzVector2<T> NzVector2<T>::operator/(T scale) const
|
||||||
{
|
{
|
||||||
#if NAZARA_MATH_SAFE
|
#if NAZARA_MATH_SAFE
|
||||||
if (NzNumberEquals(scale, F(0.0)))
|
if (NzNumberEquals(scale, F(0.0)))
|
||||||
{
|
{
|
||||||
NzStringStream ss;
|
NzStringStream ss;
|
||||||
ss << __FILE__ << ':' << __LINE__ << ": Division by zero";
|
ss << __FILE__ << ':' << __LINE__ << ": Division by zero";
|
||||||
|
|
||||||
throw std::domain_error(ss.ToString());
|
throw std::domain_error(ss.ToString());
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return NzVector2(x / scale, y / scale);
|
return NzVector2(x / scale, y / scale);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
NzVector2<T>& NzVector2<T>::operator+=(const NzVector2& vec)
|
NzVector2<T>& NzVector2<T>::operator+=(const NzVector2& vec)
|
||||||
{
|
{
|
||||||
x += vec.x;
|
x += vec.x;
|
||||||
y += vec.y;
|
y += vec.y;
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
NzVector2<T>& NzVector2<T>::operator-=(const NzVector2& vec)
|
NzVector2<T>& NzVector2<T>::operator-=(const NzVector2& vec)
|
||||||
{
|
{
|
||||||
x -= vec.x;
|
x -= vec.x;
|
||||||
y -= vec.y;
|
y -= vec.y;
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
NzVector2<T>& NzVector2<T>::operator*=(const NzVector2& vec)
|
NzVector2<T>& NzVector2<T>::operator*=(const NzVector2& vec)
|
||||||
{
|
{
|
||||||
x *= vec.x;
|
x *= vec.x;
|
||||||
y *= vec.y;
|
y *= vec.y;
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
NzVector2<T>& NzVector2<T>::operator*=(T scale)
|
NzVector2<T>& NzVector2<T>::operator*=(T scale)
|
||||||
{
|
{
|
||||||
x *= scale;
|
x *= scale;
|
||||||
y *= scale;
|
y *= scale;
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
NzVector2<T>& NzVector2<T>::operator/=(const NzVector2& vec)
|
NzVector2<T>& NzVector2<T>::operator/=(const NzVector2& vec)
|
||||||
{
|
{
|
||||||
#if NAZARA_MATH_SAFE
|
#if NAZARA_MATH_SAFE
|
||||||
if (NzNumberEquals(vec.x, F(0.0)) || NzNumberEquals(vec.y, F(0.0)) || NzNumberEquals(vec.z, F(0.0)))
|
if (NzNumberEquals(vec.x, F(0.0)) || NzNumberEquals(vec.y, F(0.0)) || NzNumberEquals(vec.z, F(0.0)))
|
||||||
{
|
{
|
||||||
NzStringStream ss;
|
NzStringStream ss;
|
||||||
ss << __FILE__ << ':' << __LINE__ << ": Division by zero";
|
ss << __FILE__ << ':' << __LINE__ << ": Division by zero";
|
||||||
|
|
||||||
throw std::domain_error(ss.ToString());
|
throw std::domain_error(ss.ToString());
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
x /= vec.x;
|
x /= vec.x;
|
||||||
y /= vec.y;
|
y /= vec.y;
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
NzVector2<T>& NzVector2<T>::operator/=(T scale)
|
NzVector2<T>& NzVector2<T>::operator/=(T scale)
|
||||||
{
|
{
|
||||||
#if NAZARA_MATH_SAFE
|
#if NAZARA_MATH_SAFE
|
||||||
if (NzNumberEquals(scale, F(0.0)))
|
if (NzNumberEquals(scale, F(0.0)))
|
||||||
{
|
{
|
||||||
NzStringStream ss;
|
NzStringStream ss;
|
||||||
ss << __FILE__ << ':' << __LINE__ << ": Division by zero";
|
ss << __FILE__ << ':' << __LINE__ << ": Division by zero";
|
||||||
|
|
||||||
throw std::domain_error(ss.ToString());
|
throw std::domain_error(ss.ToString());
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
x /= scale;
|
x /= scale;
|
||||||
y /= scale;
|
y /= scale;
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
bool NzVector2<T>::operator==(const NzVector2& vec) const
|
bool NzVector2<T>::operator==(const NzVector2& vec) const
|
||||||
{
|
{
|
||||||
return NzNumberEquals(x, vec.x) &&
|
return NzNumberEquals(x, vec.x) &&
|
||||||
NzNumberEquals(y, vec.y);
|
NzNumberEquals(y, vec.y);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
bool NzVector2<T>::operator!=(const NzVector2& vec) const
|
bool NzVector2<T>::operator!=(const NzVector2& vec) const
|
||||||
{
|
{
|
||||||
return !operator==(vec);
|
return !operator==(vec);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
bool NzVector2<T>::operator<(const NzVector2& vec) const
|
bool NzVector2<T>::operator<(const NzVector2& vec) const
|
||||||
{
|
{
|
||||||
return x < vec.x && y < vec.y;
|
return x < vec.x && y < vec.y;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
bool NzVector2<T>::operator<=(const NzVector2& vec) const
|
bool NzVector2<T>::operator<=(const NzVector2& vec) const
|
||||||
{
|
{
|
||||||
return operator<(vec) || operator==(vec);
|
return operator<(vec) || operator==(vec);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
bool NzVector2<T>::operator>(const NzVector2& vec) const
|
bool NzVector2<T>::operator>(const NzVector2& vec) const
|
||||||
{
|
{
|
||||||
return !operator<=(vec);
|
return !operator<=(vec);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
bool NzVector2<T>::operator>=(const NzVector2& vec) const
|
bool NzVector2<T>::operator>=(const NzVector2& vec) const
|
||||||
{
|
{
|
||||||
return !operator<(vec);
|
return !operator<(vec);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
NzVector2<T> NzVector2<T>::UnitX()
|
NzVector2<T> NzVector2<T>::UnitX()
|
||||||
{
|
{
|
||||||
NzVector2 vector;
|
NzVector2 vector;
|
||||||
vector.MakeUnitX();
|
vector.MakeUnitX();
|
||||||
|
|
||||||
return vector;
|
return vector;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
NzVector2<T> NzVector2<T>::UnitY()
|
NzVector2<T> NzVector2<T>::UnitY()
|
||||||
{
|
{
|
||||||
NzVector2 vector;
|
NzVector2 vector;
|
||||||
vector.MakeUnitY();
|
vector.MakeUnitY();
|
||||||
|
|
||||||
return vector;
|
return vector;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
NzVector2<T> NzVector2<T>::Zero()
|
NzVector2<T> NzVector2<T>::Zero()
|
||||||
{
|
{
|
||||||
NzVector2 vector;
|
NzVector2 vector;
|
||||||
vector.MakeZero();
|
vector.MakeZero();
|
||||||
|
|
||||||
return vector;
|
return vector;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
std::ostream& operator<<(std::ostream& out, const NzVector2<T>& vec)
|
std::ostream& operator<<(std::ostream& out, const NzVector2<T>& vec)
|
||||||
{
|
{
|
||||||
return out << vec.ToString();
|
return out << vec.ToString();
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
NzVector2<T> operator*(T scale, const NzVector2<T>& vec)
|
NzVector2<T> operator*(T scale, const NzVector2<T>& vec)
|
||||||
{
|
{
|
||||||
return NzVector2<T>(scale * vec.x, scale * vec.y);
|
return NzVector2<T>(scale * vec.x, scale * vec.y);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
NzVector2<T> operator/(T scale, const NzVector2<T>& vec)
|
NzVector2<T> operator/(T scale, const NzVector2<T>& vec)
|
||||||
{
|
{
|
||||||
#if NAZARA_MATH_SAFE
|
#if NAZARA_MATH_SAFE
|
||||||
if (NzNumberEquals(vec.x, F(0.0)) || NzNumberEquals(vec.y, F(0.0)) || NzNumberEquals(vec.z, F(0.0)))
|
if (NzNumberEquals(vec.x, F(0.0)) || NzNumberEquals(vec.y, F(0.0)) || NzNumberEquals(vec.z, F(0.0)))
|
||||||
{
|
{
|
||||||
NzStringStream ss;
|
NzStringStream ss;
|
||||||
ss << __FILE__ << ':' << __LINE__ << ": Division by zero";
|
ss << __FILE__ << ':' << __LINE__ << ": Division by zero";
|
||||||
|
|
||||||
throw std::domain_error(ss.ToString());
|
throw std::domain_error(ss.ToString());
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return NzVector2<T>(scale/vec.x, scale/vec.y);
|
return NzVector2<T>(scale/vec.x, scale/vec.y);
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef F
|
#undef F
|
||||||
|
|
||||||
#include <Nazara/Core/DebugOff.hpp>
|
#include <Nazara/Core/DebugOff.hpp>
|
||||||
|
|
|
||||||
|
|
@ -1,111 +1,121 @@
|
||||||
// Copyright (C) 2012 Rémi Bèges - Jérôme Leclercq
|
// Copyright (C) 2012 Rémi Bèges - Jérôme Leclercq
|
||||||
// This file is part of the "Nazara Engine - Mathematics module"
|
// This file is part of the "Nazara Engine - Mathematics module"
|
||||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#ifndef NAZARA_VECTOR3_HPP
|
#ifndef NAZARA_VECTOR3_HPP
|
||||||
#define NAZARA_VECTOR3_HPP
|
#define NAZARA_VECTOR3_HPP
|
||||||
|
|
||||||
#include <Nazara/Core/String.hpp>
|
#include <Nazara/Core/String.hpp>
|
||||||
#include <Nazara/Math/Vector2.hpp>
|
#include <Nazara/Math/Vector2.hpp>
|
||||||
|
|
||||||
template<typename T> class NzVector3
|
template<typename T> class NzVector3
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
NzVector3();
|
NzVector3();
|
||||||
NzVector3(T X, T Y, T Z);
|
NzVector3(T X, T Y, T Z);
|
||||||
explicit NzVector3(T scale);
|
explicit NzVector3(T scale);
|
||||||
NzVector3(T vec[3]);
|
NzVector3(T vec[3]);
|
||||||
NzVector3(const NzVector2<T>& vec, T Z = 0.0);
|
NzVector3(const NzVector2<T>& vec, T Z = 0.0);
|
||||||
template<typename U> explicit NzVector3(const NzVector3<U>& vec);
|
template<typename U> explicit NzVector3(const NzVector3<U>& vec);
|
||||||
NzVector3(const NzVector3& vec) = default;
|
NzVector3(const NzVector3& vec) = default;
|
||||||
~NzVector3() = default;
|
~NzVector3() = default;
|
||||||
|
|
||||||
T AbsDotProduct(const NzVector3& vec) const;
|
T AbsDotProduct(const NzVector3& vec) const;
|
||||||
|
|
||||||
NzVector3 CrossProduct(const NzVector3& vec) const;
|
NzVector3 CrossProduct(const NzVector3& vec) const;
|
||||||
|
|
||||||
T Distance(const NzVector3& vec) const;
|
T Distance(const NzVector3& vec) const;
|
||||||
float Distancef(const NzVector3& vec) const;
|
float Distancef(const NzVector3& vec) const;
|
||||||
|
|
||||||
T DotProduct(const NzVector3& vec) const;
|
T DotProduct(const NzVector3& vec) const;
|
||||||
|
|
||||||
NzVector3 GetNormal() const;
|
NzVector3 GetNormal() const;
|
||||||
|
|
||||||
T Length() const;
|
T Length() const;
|
||||||
float Lengthf() const;
|
float Lengthf() const;
|
||||||
|
|
||||||
void MakeCeil(const NzVector3& vec);
|
void MakeForward();
|
||||||
void MakeFloor(const NzVector3& vec);
|
void MakeLeft();
|
||||||
void MakeUnitX();
|
void MakeUnitX();
|
||||||
void MakeUnitY();
|
void MakeUnitY();
|
||||||
void MakeUnitZ();
|
void MakeUnitZ();
|
||||||
void MakeZero();
|
void MakeUp();
|
||||||
|
void MakeZero();
|
||||||
void Normalize();
|
|
||||||
|
void Maximize(const NzVector3& vec);
|
||||||
void Set(T X, T Y, T Z);
|
void Minimize(const NzVector3& vec);
|
||||||
void Set(T scale);
|
|
||||||
void Set(T vec[3]);
|
void Normalize();
|
||||||
void Set(const NzVector2<T>& vec, T Z = 0.0);
|
|
||||||
template<typename U> void Set(const NzVector3<U>& vec);
|
void Set(T X, T Y, T Z);
|
||||||
|
void Set(T scale);
|
||||||
T SquaredDistance(const NzVector3& vec) const;
|
void Set(T vec[3]);
|
||||||
T SquaredLength() const;
|
void Set(const NzVector2<T>& vec, T Z = 0.0);
|
||||||
|
template<typename U> void Set(const NzVector3<U>& vec);
|
||||||
NzString ToString() const;
|
|
||||||
|
T SquaredDistance(const NzVector3& vec) const;
|
||||||
operator NzString() const;
|
T SquaredLength() const;
|
||||||
|
|
||||||
operator T*();
|
NzString ToString() const;
|
||||||
operator const T*() const;
|
|
||||||
|
operator NzString() const;
|
||||||
T& operator[](unsigned int i);
|
|
||||||
T operator[](unsigned int i) const;
|
operator T*();
|
||||||
|
operator const T*() const;
|
||||||
const NzVector3& operator+() const;
|
|
||||||
NzVector3 operator-() const;
|
T& operator[](unsigned int i);
|
||||||
|
T operator[](unsigned int i) const;
|
||||||
NzVector3 operator+(const NzVector3& vec) const;
|
|
||||||
NzVector3 operator-(const NzVector3& vec) const;
|
const NzVector3& operator+() const;
|
||||||
NzVector3 operator*(const NzVector3& vec) const;
|
NzVector3 operator-() const;
|
||||||
NzVector3 operator*(T scale) const;
|
|
||||||
NzVector3 operator/(const NzVector3& vec) const;
|
NzVector3 operator+(const NzVector3& vec) const;
|
||||||
NzVector3 operator/(T scale) const;
|
NzVector3 operator-(const NzVector3& vec) const;
|
||||||
|
NzVector3 operator*(const NzVector3& vec) const;
|
||||||
NzVector3& operator+=(const NzVector3& vec);
|
NzVector3 operator*(T scale) const;
|
||||||
NzVector3& operator-=(const NzVector3& vec);
|
NzVector3 operator/(const NzVector3& vec) const;
|
||||||
NzVector3& operator*=(const NzVector3& vec);
|
NzVector3 operator/(T scale) const;
|
||||||
NzVector3& operator*=(T scale);
|
|
||||||
NzVector3& operator/=(const NzVector3& vec);
|
NzVector3& operator+=(const NzVector3& vec);
|
||||||
NzVector3& operator/=(T scale);
|
NzVector3& operator-=(const NzVector3& vec);
|
||||||
|
NzVector3& operator*=(const NzVector3& vec);
|
||||||
bool operator==(const NzVector3& vec) const;
|
NzVector3& operator*=(T scale);
|
||||||
bool operator!=(const NzVector3& vec) const;
|
NzVector3& operator/=(const NzVector3& vec);
|
||||||
bool operator<(const NzVector3& vec) const;
|
NzVector3& operator/=(T scale);
|
||||||
bool operator<=(const NzVector3& vec) const;
|
|
||||||
bool operator>(const NzVector3& vec) const;
|
bool operator==(const NzVector3& vec) const;
|
||||||
bool operator>=(const NzVector3& vec) const;
|
bool operator!=(const NzVector3& vec) const;
|
||||||
|
bool operator<(const NzVector3& vec) const;
|
||||||
static NzVector3 UnitX();
|
bool operator<=(const NzVector3& vec) const;
|
||||||
static NzVector3 UnitY();
|
bool operator>(const NzVector3& vec) const;
|
||||||
static NzVector3 UnitZ();
|
bool operator>=(const NzVector3& vec) const;
|
||||||
static NzVector3 Zero();
|
|
||||||
|
static NzVector3 CrossProduct(const NzVector3& vec1, const NzVector3& vec2);
|
||||||
T x, y, z;
|
static T DotProduct(const NzVector3& vec1, const NzVector3& vec2);
|
||||||
};
|
static NzVector3 Forward();
|
||||||
|
static NzVector3 Left();
|
||||||
template<typename T> std::ostream& operator<<(std::ostream& out, const NzVector3<T>& vec);
|
static NzVector3 Normalize(const NzVector3& vec);
|
||||||
|
static NzVector3 UnitX();
|
||||||
template<typename T> NzVector3<T> operator*(T scale, const NzVector3<T>& vec);
|
static NzVector3 UnitY();
|
||||||
template<typename T> NzVector3<T> operator/(T scale, const NzVector3<T>& vec);
|
static NzVector3 UnitZ();
|
||||||
|
static NzVector3 Up();
|
||||||
typedef NzVector3<double> NzVector3d;
|
static NzVector3 Zero();
|
||||||
typedef NzVector3<float> NzVector3f;
|
|
||||||
typedef NzVector3<int> NzVector3i;
|
T x, y, z;
|
||||||
typedef NzVector3<unsigned int> NzVector3ui;
|
};
|
||||||
|
|
||||||
#include <Nazara/Math/Vector3.inl>
|
template<typename T> std::ostream& operator<<(std::ostream& out, const NzVector3<T>& vec);
|
||||||
|
|
||||||
#endif // NAZARA_VECTOR3_HPP
|
template<typename T> NzVector3<T> operator*(T scale, const NzVector3<T>& vec);
|
||||||
|
template<typename T> NzVector3<T> operator/(T scale, const NzVector3<T>& vec);
|
||||||
|
|
||||||
|
typedef NzVector3<double> NzVector3d;
|
||||||
|
typedef NzVector3<float> NzVector3f;
|
||||||
|
typedef NzVector3<int> NzVector3i;
|
||||||
|
typedef NzVector3<unsigned int> NzVector3ui;
|
||||||
|
|
||||||
|
#include <Nazara/Math/Vector3.inl>
|
||||||
|
|
||||||
|
#endif // NAZARA_VECTOR3_HPP
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -1,97 +1,98 @@
|
||||||
// Copyright (C) 2012 Rémi Bèges - Jérôme Leclercq
|
// Copyright (C) 2012 Rémi Bèges - Jérôme Leclercq
|
||||||
// This file is part of the "Nazara Engine - Mathematics module"
|
// This file is part of the "Nazara Engine - Mathematics module"
|
||||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#ifndef NAZARA_VECTOR4_HPP
|
#ifndef NAZARA_VECTOR4_HPP
|
||||||
#define NAZARA_VECTOR4_HPP
|
#define NAZARA_VECTOR4_HPP
|
||||||
|
|
||||||
#include <Nazara/Core/String.hpp>
|
#include <Nazara/Core/String.hpp>
|
||||||
#include <Nazara/Math/Vector3.hpp>
|
#include <Nazara/Math/Vector3.hpp>
|
||||||
|
|
||||||
template<typename T> class NzVector4
|
template<typename T> class NzVector4
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
NzVector4();
|
NzVector4();
|
||||||
NzVector4(T X, T Y, T Z, T W = 1.0);
|
NzVector4(T X, T Y, T Z, T W = 1.0);
|
||||||
explicit NzVector4(T scale);
|
explicit NzVector4(T scale);
|
||||||
NzVector4(T vec[4]);
|
NzVector4(T vec[4]);
|
||||||
NzVector4(const NzVector3<T>& vec, T W = 1.0);
|
NzVector4(const NzVector3<T>& vec, T W = 1.0);
|
||||||
template<typename U> explicit NzVector4(const NzVector4<U>& vec);
|
template<typename U> explicit NzVector4(const NzVector4<U>& vec);
|
||||||
NzVector4(const NzVector4& vec) = default;
|
NzVector4(const NzVector4& vec) = default;
|
||||||
~NzVector4() = default;
|
~NzVector4() = default;
|
||||||
|
|
||||||
T AbsDotProduct(const NzVector4& vec) const;
|
T AbsDotProduct(const NzVector4& vec) const;
|
||||||
|
|
||||||
T DotProduct(const NzVector4& vec) const;
|
T DotProduct(const NzVector4& vec) const;
|
||||||
|
|
||||||
void MakeCeil(const NzVector4& vec);
|
void MakeUnitX();
|
||||||
void MakeFloor(const NzVector4& vec);
|
void MakeUnitY();
|
||||||
void MakeUnitX();
|
void MakeUnitZ();
|
||||||
void MakeUnitY();
|
void MakeZero();
|
||||||
void MakeUnitZ();
|
|
||||||
void MakeZero();
|
void Maximize(const NzVector4& vec);
|
||||||
|
void Minimize(const NzVector4& vec);
|
||||||
void Normalize();
|
|
||||||
|
void Normalize();
|
||||||
void Set(T X, T Y, T Z, T W = 1.0);
|
|
||||||
void Set(T scale);
|
void Set(T X, T Y, T Z, T W = 1.0);
|
||||||
void Set(T vec[4]);
|
void Set(T scale);
|
||||||
void Set(const NzVector3<T>& vec, T W = 1.0);
|
void Set(T vec[4]);
|
||||||
template<typename U> void Set(const NzVector4<U>& vec);
|
void Set(const NzVector3<T>& vec, T W = 1.0);
|
||||||
|
template<typename U> void Set(const NzVector4<U>& vec);
|
||||||
NzString ToString() const;
|
|
||||||
|
NzString ToString() const;
|
||||||
operator NzString() const;
|
|
||||||
|
operator NzString() const;
|
||||||
operator T*();
|
|
||||||
operator const T*() const;
|
operator T*();
|
||||||
|
operator const T*() const;
|
||||||
T& operator[](unsigned int i);
|
|
||||||
T operator[](unsigned int i) const;
|
T& operator[](unsigned int i);
|
||||||
|
T operator[](unsigned int i) const;
|
||||||
const NzVector4& operator+() const;
|
|
||||||
NzVector4 operator-() const;
|
const NzVector4& operator+() const;
|
||||||
|
NzVector4 operator-() const;
|
||||||
NzVector4 operator+(const NzVector4& vec) const;
|
|
||||||
NzVector4 operator-(const NzVector4& vec) const;
|
NzVector4 operator+(const NzVector4& vec) const;
|
||||||
NzVector4 operator*(const NzVector4& vec) const;
|
NzVector4 operator-(const NzVector4& vec) const;
|
||||||
NzVector4 operator*(T scale) const;
|
NzVector4 operator*(const NzVector4& vec) const;
|
||||||
NzVector4 operator/(const NzVector4& vec) const;
|
NzVector4 operator*(T scale) const;
|
||||||
NzVector4 operator/(T scale) const;
|
NzVector4 operator/(const NzVector4& vec) const;
|
||||||
|
NzVector4 operator/(T scale) const;
|
||||||
NzVector4& operator+=(const NzVector4& vec);
|
|
||||||
NzVector4& operator-=(const NzVector4& vec);
|
NzVector4& operator+=(const NzVector4& vec);
|
||||||
NzVector4& operator*=(const NzVector4& vec);
|
NzVector4& operator-=(const NzVector4& vec);
|
||||||
NzVector4& operator*=(T scale);
|
NzVector4& operator*=(const NzVector4& vec);
|
||||||
NzVector4& operator/=(const NzVector4& vec);
|
NzVector4& operator*=(T scale);
|
||||||
NzVector4& operator/=(T scale);
|
NzVector4& operator/=(const NzVector4& vec);
|
||||||
|
NzVector4& operator/=(T scale);
|
||||||
bool operator==(const NzVector4& vec) const;
|
|
||||||
bool operator!=(const NzVector4& vec) const;
|
bool operator==(const NzVector4& vec) const;
|
||||||
bool operator<(const NzVector4& vec) const;
|
bool operator!=(const NzVector4& vec) const;
|
||||||
bool operator<=(const NzVector4& vec) const;
|
bool operator<(const NzVector4& vec) const;
|
||||||
bool operator>(const NzVector4& vec) const;
|
bool operator<=(const NzVector4& vec) const;
|
||||||
bool operator>=(const NzVector4& vec) const;
|
bool operator>(const NzVector4& vec) const;
|
||||||
|
bool operator>=(const NzVector4& vec) const;
|
||||||
static NzVector4 UnitX();
|
|
||||||
static NzVector4 UnitY();
|
static NzVector4 UnitX();
|
||||||
static NzVector4 UnitZ();
|
static NzVector4 UnitY();
|
||||||
static NzVector4 Zero();
|
static NzVector4 UnitZ();
|
||||||
|
static NzVector4 Zero();
|
||||||
T x, y, z, w;
|
|
||||||
};
|
T x, y, z, w;
|
||||||
|
};
|
||||||
template<typename T> std::ostream& operator<<(std::ostream& out, const NzVector4<T>& vec);
|
|
||||||
|
template<typename T> std::ostream& operator<<(std::ostream& out, const NzVector4<T>& vec);
|
||||||
template<typename T> NzVector4<T> operator*(T scale, const NzVector4<T>& vec);
|
|
||||||
template<typename T> NzVector4<T> operator/(T scale, const NzVector4<T>& vec);
|
template<typename T> NzVector4<T> operator*(T scale, const NzVector4<T>& vec);
|
||||||
|
template<typename T> NzVector4<T> operator/(T scale, const NzVector4<T>& vec);
|
||||||
typedef NzVector4<double> NzVector4d;
|
|
||||||
typedef NzVector4<float> NzVector4f;
|
typedef NzVector4<double> NzVector4d;
|
||||||
typedef NzVector4<int> NzVector4i;
|
typedef NzVector4<float> NzVector4f;
|
||||||
|
typedef NzVector4<int> NzVector4i;
|
||||||
#include <Nazara/Math/Vector4.inl>
|
|
||||||
|
#include <Nazara/Math/Vector4.inl>
|
||||||
#endif // NAZARA_VECTOR4_HPP
|
|
||||||
|
#endif // NAZARA_VECTOR4_HPP
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -1,40 +1,41 @@
|
||||||
// This file was automatically generated by Nazara
|
// This file was automatically generated by Nazara
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Nazara Engine - Renderer module
|
Nazara Engine - Renderer module
|
||||||
|
|
||||||
Copyright (C) 2012 Jérôme "Lynix" Leclercq (Lynix680@gmail.com)
|
Copyright (C) 2012 Jérôme "Lynix" Leclercq (Lynix680@gmail.com)
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
this software and associated documentation files (the "Software"), to deal in
|
this software and associated documentation files (the "Software"), to deal in
|
||||||
the Software without restriction, including without limitation the rights to
|
the Software without restriction, including without limitation the rights to
|
||||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||||
of the Software, and to permit persons to whom the Software is furnished to do
|
of the Software, and to permit persons to whom the Software is furnished to do
|
||||||
so, subject to the following conditions:
|
so, subject to the following conditions:
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in all
|
The above copyright notice and this permission notice shall be included in all
|
||||||
copies or substantial portions of the Software.
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
SOFTWARE.
|
SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <Nazara/Renderer/Config.hpp>
|
#include <Nazara/Renderer/Config.hpp>
|
||||||
#include <Nazara/Renderer/Context.hpp>
|
#include <Nazara/Renderer/Context.hpp>
|
||||||
#include <Nazara/Renderer/ContextParameters.hpp>
|
#include <Nazara/Renderer/ContextParameters.hpp>
|
||||||
#include <Nazara/Renderer/Enums.hpp>
|
#include <Nazara/Renderer/Enums.hpp>
|
||||||
#include <Nazara/Renderer/OcclusionQuery.hpp>
|
#include <Nazara/Renderer/OcclusionQuery.hpp>
|
||||||
#include <Nazara/Renderer/OpenGL.hpp>
|
#include <Nazara/Renderer/OpenGL.hpp>
|
||||||
#include <Nazara/Renderer/Renderer.hpp>
|
#include <Nazara/Renderer/Renderer.hpp>
|
||||||
#include <Nazara/Renderer/RenderTarget.hpp>
|
#include <Nazara/Renderer/RenderTarget.hpp>
|
||||||
#include <Nazara/Renderer/RenderTargetParameters.hpp>
|
#include <Nazara/Renderer/RenderTargetParameters.hpp>
|
||||||
#include <Nazara/Renderer/RenderWindow.hpp>
|
#include <Nazara/Renderer/RenderTexture.hpp>
|
||||||
#include <Nazara/Renderer/Shader.hpp>
|
#include <Nazara/Renderer/RenderWindow.hpp>
|
||||||
#include <Nazara/Renderer/Texture.hpp>
|
#include <Nazara/Renderer/Shader.hpp>
|
||||||
|
#include <Nazara/Renderer/Texture.hpp>
|
||||||
|
|
|
||||||
|
|
@ -1,44 +1,41 @@
|
||||||
/*
|
/*
|
||||||
Nazara Engine - Renderer module
|
Nazara Engine - Renderer module
|
||||||
|
|
||||||
Copyright (C) 2012 Jérôme "Lynix" Leclercq (Lynix680@gmail.com)
|
Copyright (C) 2012 Jérôme "Lynix" Leclercq (Lynix680@gmail.com)
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
this software and associated documentation files (the "Software"), to deal in
|
this software and associated documentation files (the "Software"), to deal in
|
||||||
the Software without restriction, including without limitation the rights to
|
the Software without restriction, including without limitation the rights to
|
||||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||||
of the Software, and to permit persons to whom the Software is furnished to do
|
of the Software, and to permit persons to whom the Software is furnished to do
|
||||||
so, subject to the following conditions:
|
so, subject to the following conditions:
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in all
|
The above copyright notice and this permission notice shall be included in all
|
||||||
copies or substantial portions of the Software.
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
SOFTWARE.
|
SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#ifndef NAZARA_CONFIG_RENDERER_HPP
|
#ifndef NAZARA_CONFIG_RENDERER_HPP
|
||||||
#define NAZARA_CONFIG_RENDERER_HPP
|
#define NAZARA_CONFIG_RENDERER_HPP
|
||||||
|
|
||||||
/// Chaque modification d'un paramètre du module nécessite une recompilation de celui-ci
|
/// Chaque modification d'un paramètre du module nécessite une recompilation de celui-ci
|
||||||
|
|
||||||
// Active une fenêtre de rendu (NzRenderWindow) lors de sa création
|
// Utilise un tracker pour repérer les éventuels leaks (Ralentit l'exécution)
|
||||||
#define NAZARA_RENDERER_ACTIVATE_RENDERWINDOW_ON_CREATION 1
|
#define NAZARA_RENDERER_MEMORYLEAKTRACKER 0
|
||||||
|
|
||||||
// Utilise un tracker pour repérer les éventuels leaks (Ralentit l'exécution)
|
// Active le paramère debug des paramètres des contextes par défaut (Perte de performances mais capable de recevoir des messages d'OpenGL)
|
||||||
#define NAZARA_RENDERER_MEMORYLEAKTRACKER 0
|
#define NAZARA_RENDERER_OPENGL_DEBUG 0
|
||||||
|
|
||||||
// Active le paramère debug des paramètres des contextes par défaut (Perte de performances mais capable de recevoir des messages d'OpenGL)
|
// Active les tests de sécurité basés sur le code (Conseillé pour le développement)
|
||||||
#define NAZARA_RENDERER_OPENGL_DEBUG 0
|
#define NAZARA_RENDERER_SAFE 1
|
||||||
|
|
||||||
// Active les tests de sécurité basés sur le code (Conseillé pour le développement)
|
#endif // NAZARA_CONFIG_MODULENAME_HPP
|
||||||
#define NAZARA_RENDERER_SAFE 1
|
|
||||||
|
|
||||||
#endif // NAZARA_CONFIG_MODULENAME_HPP
|
|
||||||
|
|
|
||||||
|
|
@ -1,47 +1,49 @@
|
||||||
// Copyright (C) 2012 Jérôme Leclercq
|
// Copyright (C) 2012 Jérôme Leclercq
|
||||||
// This file is part of the "Nazara Engine - Renderer module"
|
// This file is part of the "Nazara Engine - Renderer module"
|
||||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||||
|
|
||||||
#ifdef NAZARA_RENDERER_COMMON
|
#pragma once
|
||||||
#error This file is not part of the common renderer interface, you must undefine NAZARA_RENDERER_COMMON to use it
|
|
||||||
#endif
|
#ifndef NAZARA_CONTEXT_HPP
|
||||||
|
#define NAZARA_CONTEXT_HPP
|
||||||
#pragma once
|
|
||||||
|
#ifdef NAZARA_RENDERER_OPENGL
|
||||||
#ifndef NAZARA_CONTEXT_HPP
|
|
||||||
#define NAZARA_CONTEXT_HPP
|
#include <Nazara/Core/Resource.hpp>
|
||||||
|
#include <Nazara/Renderer/ContextParameters.hpp>
|
||||||
#include <Nazara/Renderer/ContextParameters.hpp>
|
|
||||||
|
class NzContextImpl;
|
||||||
class NzContextImpl;
|
|
||||||
|
class NAZARA_API NzContext : public NzResource
|
||||||
class NAZARA_API NzContext
|
{
|
||||||
{
|
friend NzContextImpl;
|
||||||
friend NzContextImpl;
|
|
||||||
|
public:
|
||||||
public:
|
NzContext();
|
||||||
NzContext();
|
~NzContext();
|
||||||
~NzContext();
|
|
||||||
|
bool Create(const NzContextParameters& parameters = NzContextParameters());
|
||||||
bool Create(const NzContextParameters& parameters = NzContextParameters());
|
void Destroy();
|
||||||
void Destroy();
|
|
||||||
const NzContextParameters& GetParameters() const;
|
const NzContextParameters& GetParameters() const;
|
||||||
bool IsActive() const;
|
bool IsActive() const;
|
||||||
bool SetActive(bool active);
|
bool SetActive(bool active);
|
||||||
void SwapBuffers();
|
void SwapBuffers();
|
||||||
|
|
||||||
static bool EnsureContext();
|
static bool EnsureContext();
|
||||||
static NzContext* GetCurrent();
|
static NzContext* GetCurrent();
|
||||||
static const NzContext* GetReference();
|
static const NzContext* GetReference();
|
||||||
static NzContext* GetThreadContext();
|
static NzContext* GetThreadContext();
|
||||||
static bool Initialize();
|
static bool Initialize();
|
||||||
static void Uninitialize();
|
static void Uninitialize();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
NzContextParameters m_parameters;
|
NzContextParameters m_parameters;
|
||||||
NzContextImpl* m_impl;
|
NzContextImpl* m_impl;
|
||||||
|
|
||||||
static NzContext* s_reference;
|
static NzContext* s_reference;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // NAZARA_CONTEXT_HPP
|
#endif // NAZARA_RENDERER_OPENGL
|
||||||
|
|
||||||
|
#endif // NAZARA_CONTEXT_HPP
|
||||||
|
|
|
||||||
|
|
@ -1,141 +1,174 @@
|
||||||
// Copyright (C) 2012 Jérôme Leclercq
|
// Copyright (C) 2012 Jérôme Leclercq
|
||||||
// This file is part of the "Nazara Engine - Renderer module"
|
// This file is part of the "Nazara Engine - Renderer module"
|
||||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#ifndef NAZARA_ENUMS_RENDERER_HPP
|
#ifndef NAZARA_ENUMS_RENDERER_HPP
|
||||||
#define NAZARA_ENUMS_RENDERER_HPP
|
#define NAZARA_ENUMS_RENDERER_HPP
|
||||||
|
|
||||||
enum nzBlendFunc
|
enum nzAttachmentPoint
|
||||||
{
|
{
|
||||||
nzBlendFunc_DestAlpha,
|
nzAttachmentPoint_Color,
|
||||||
nzBlendFunc_DestColor,
|
nzAttachmentPoint_Depth,
|
||||||
nzBlendFunc_SrcAlpha,
|
nzAttachmentPoint_DepthStencil,
|
||||||
nzBlendFunc_SrcColor,
|
nzAttachmentPoint_Stencil,
|
||||||
nzBlendFunc_InvDestAlpha,
|
|
||||||
nzBlendFunc_InvDestColor,
|
nzAttachmentPoint_Max = nzAttachmentPoint_Stencil
|
||||||
nzBlendFunc_InvSrcAlpha,
|
};
|
||||||
nzBlendFunc_InvSrcColor,
|
|
||||||
nzBlendFunc_One,
|
enum nzBlendFunc
|
||||||
nzBlendFunc_Zero
|
{
|
||||||
};
|
nzBlendFunc_DestAlpha,
|
||||||
|
nzBlendFunc_DestColor,
|
||||||
enum nzFaceCulling
|
nzBlendFunc_SrcAlpha,
|
||||||
{
|
nzBlendFunc_SrcColor,
|
||||||
nzFaceCulling_Back,
|
nzBlendFunc_InvDestAlpha,
|
||||||
nzFaceCulling_Front,
|
nzBlendFunc_InvDestColor,
|
||||||
nzFaceCulling_FrontAndBack
|
nzBlendFunc_InvSrcAlpha,
|
||||||
};
|
nzBlendFunc_InvSrcColor,
|
||||||
|
nzBlendFunc_One,
|
||||||
enum nzFaceFilling
|
nzBlendFunc_Zero,
|
||||||
{
|
|
||||||
nzFaceFilling_Point,
|
nzBlendFunc_Max = nzBlendFunc_Zero
|
||||||
nzFaceFilling_Line,
|
};
|
||||||
nzFaceFilling_Fill
|
|
||||||
};
|
enum nzFaceCulling
|
||||||
|
{
|
||||||
enum nzMatrixType
|
nzFaceCulling_Back,
|
||||||
{
|
nzFaceCulling_Front,
|
||||||
nzMatrixType_Projection,
|
nzFaceCulling_FrontAndBack,
|
||||||
nzMatrixType_View,
|
|
||||||
nzMatrixType_World,
|
nzFaceCulling_Max = nzFaceCulling_FrontAndBack
|
||||||
|
};
|
||||||
nzMatrixType_Max = nzMatrixType_World
|
|
||||||
};
|
enum nzFaceFilling
|
||||||
|
{
|
||||||
enum nzPixelBufferType
|
nzFaceFilling_Point,
|
||||||
{
|
nzFaceFilling_Line,
|
||||||
nzPixelBufferType_Pack,
|
nzFaceFilling_Fill,
|
||||||
nzPixelBufferType_Unpack
|
|
||||||
};
|
nzFaceFilling_Max = nzFaceFilling_Fill
|
||||||
|
};
|
||||||
enum nzRendererCap
|
|
||||||
{
|
enum nzMatrixType
|
||||||
nzRendererCap_AnisotropicFilter,
|
{
|
||||||
nzRendererCap_FP64,
|
nzMatrixType_Projection,
|
||||||
nzRendererCap_HardwareBuffer,
|
nzMatrixType_View,
|
||||||
nzRendererCap_MultipleRenderTargets,
|
nzMatrixType_World,
|
||||||
nzRendererCap_OcclusionQuery,
|
|
||||||
nzRendererCap_PixelBufferObject,
|
nzMatrixType_Max = nzMatrixType_World
|
||||||
nzRendererCap_Texture3D,
|
};
|
||||||
nzRendererCap_TextureCubemap,
|
|
||||||
nzRendererCap_TextureMulti,
|
enum nzPixelBufferType
|
||||||
nzRendererCap_TextureNPOT,
|
{
|
||||||
|
nzPixelBufferType_Pack,
|
||||||
nzRendererCap_Max = nzRendererCap_TextureNPOT
|
nzPixelBufferType_Unpack,
|
||||||
};
|
|
||||||
|
nzPixelBufferType_Max = nzPixelBufferType_Unpack
|
||||||
enum nzRendererClear
|
};
|
||||||
{
|
|
||||||
nzRendererClear_Color = 0x01,
|
enum nzRendererCap
|
||||||
nzRendererClear_Depth = 0x02,
|
{
|
||||||
nzRendererClear_Stencil = 0x04
|
nzRendererCap_AnisotropicFilter,
|
||||||
};
|
nzRendererCap_FP64,
|
||||||
|
nzRendererCap_HardwareBuffer,
|
||||||
enum nzRendererComparison
|
nzRendererCap_MultipleRenderTargets,
|
||||||
{
|
nzRendererCap_OcclusionQuery,
|
||||||
nzRendererComparison_Always,
|
nzRendererCap_PixelBufferObject,
|
||||||
nzRendererComparison_Equal,
|
nzRendererCap_RenderTexture,
|
||||||
nzRendererComparison_Greater,
|
nzRendererCap_Texture3D,
|
||||||
nzRendererComparison_GreaterOrEqual,
|
nzRendererCap_TextureCubemap,
|
||||||
nzRendererComparison_Less,
|
nzRendererCap_TextureMulti,
|
||||||
nzRendererComparison_LessOrEqual,
|
nzRendererCap_TextureNPOT,
|
||||||
nzRendererComparison_Never
|
|
||||||
};
|
nzRendererCap_Max = nzRendererCap_TextureNPOT
|
||||||
|
};
|
||||||
enum nzRendererParameter
|
|
||||||
{
|
enum nzRendererClearFlags
|
||||||
nzRendererParameter_Blend,
|
{
|
||||||
nzRendererParameter_ColorWrite,
|
nzRendererClear_Color = 0x01,
|
||||||
nzRendererParameter_DepthTest,
|
nzRendererClear_Depth = 0x02,
|
||||||
nzRendererParameter_DepthWrite,
|
nzRendererClear_Stencil = 0x04
|
||||||
nzRendererParameter_FaceCulling,
|
};
|
||||||
nzRendererParameter_Stencil
|
|
||||||
};
|
enum nzRendererComparison
|
||||||
|
{
|
||||||
enum nzShaderLanguage
|
nzRendererComparison_Always,
|
||||||
{
|
nzRendererComparison_Equal,
|
||||||
nzShaderLanguage_Unknown,
|
nzRendererComparison_Greater,
|
||||||
|
nzRendererComparison_GreaterOrEqual,
|
||||||
nzShaderLanguage_Cg,
|
nzRendererComparison_Less,
|
||||||
nzShaderLanguage_GLSL
|
nzRendererComparison_LessOrEqual,
|
||||||
};
|
nzRendererComparison_Never,
|
||||||
|
|
||||||
enum nzShaderType
|
nzRendererComparison_Max = nzRendererComparison_Never
|
||||||
{
|
};
|
||||||
nzShaderType_Fragment,
|
|
||||||
nzShaderType_Geometry,
|
enum nzRendererParameter
|
||||||
nzShaderType_Vertex,
|
{
|
||||||
|
nzRendererParameter_Blend,
|
||||||
nzShaderType_Max = nzShaderType_Vertex
|
nzRendererParameter_ColorWrite,
|
||||||
};
|
nzRendererParameter_DepthTest,
|
||||||
|
nzRendererParameter_DepthWrite,
|
||||||
enum nzStencilOperation
|
nzRendererParameter_FaceCulling,
|
||||||
{
|
nzRendererParameter_Stencil,
|
||||||
nzStencilOperation_Decrement,
|
|
||||||
nzStencilOperation_DecrementToSaturation,
|
nzRendererParameter_Max = nzRendererParameter_Stencil
|
||||||
nzStencilOperation_Increment,
|
};
|
||||||
nzStencilOperation_IncrementToSaturation,
|
|
||||||
nzStencilOperation_Invert,
|
enum nzShaderLanguage
|
||||||
nzStencilOperation_Keep,
|
{
|
||||||
nzStencilOperation_Replace,
|
nzShaderLanguage_Unknown = -1,
|
||||||
nzStencilOperation_Zero
|
|
||||||
};
|
nzShaderLanguage_Cg,
|
||||||
|
nzShaderLanguage_GLSL,
|
||||||
enum nzTextureFilter
|
|
||||||
{
|
nzShaderLanguage_Max = nzShaderLanguage_GLSL
|
||||||
nzTextureFilter_Bilinear,
|
};
|
||||||
nzTextureFilter_Nearest,
|
|
||||||
nzTextureFilter_Trilinear,
|
enum nzShaderType
|
||||||
nzTextureFilter_Unknown
|
{
|
||||||
};
|
nzShaderType_Fragment,
|
||||||
|
nzShaderType_Geometry,
|
||||||
enum nzTextureWrap
|
nzShaderType_Vertex,
|
||||||
{
|
|
||||||
nzTextureWrap_Clamp,
|
nzShaderType_Max = nzShaderType_Vertex
|
||||||
nzTextureWrap_Repeat,
|
};
|
||||||
nzTextureWrap_Unknown
|
|
||||||
};
|
enum nzStencilOperation
|
||||||
|
{
|
||||||
#endif // NAZARA_ENUMS_RENDERER_HPP
|
nzStencilOperation_Decrement,
|
||||||
|
nzStencilOperation_DecrementToSaturation,
|
||||||
|
nzStencilOperation_Increment,
|
||||||
|
nzStencilOperation_IncrementToSaturation,
|
||||||
|
nzStencilOperation_Invert,
|
||||||
|
nzStencilOperation_Keep,
|
||||||
|
nzStencilOperation_Replace,
|
||||||
|
nzStencilOperation_Zero,
|
||||||
|
|
||||||
|
nzStencilOperation_Max = nzStencilOperation_Zero
|
||||||
|
};
|
||||||
|
|
||||||
|
enum nzTextureFilter
|
||||||
|
{
|
||||||
|
nzTextureFilter_Unknown = -1,
|
||||||
|
|
||||||
|
nzTextureFilter_Bilinear,
|
||||||
|
nzTextureFilter_Nearest,
|
||||||
|
nzTextureFilter_Trilinear,
|
||||||
|
|
||||||
|
nzTextureFilter_Max = nzTextureFilter_Trilinear
|
||||||
|
};
|
||||||
|
|
||||||
|
enum nzTextureWrap
|
||||||
|
{
|
||||||
|
nzTextureWrap_Unknown = -1,
|
||||||
|
|
||||||
|
nzTextureWrap_Clamp,
|
||||||
|
nzTextureWrap_Repeat,
|
||||||
|
|
||||||
|
nzTextureWrap_Max = nzTextureWrap_Repeat
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // NAZARA_ENUMS_RENDERER_HPP
|
||||||
|
|
|
||||||
|
|
@ -1,192 +1,233 @@
|
||||||
// Copyright (C) 2012 Jérôme Leclercq
|
// Copyright (C) 2012 Jérôme Leclercq
|
||||||
// This file is part of the "Nazara Engine - Renderer module"
|
// This file is part of the "Nazara Engine - Renderer module"
|
||||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||||
|
|
||||||
#ifdef NAZARA_RENDERER_COMMON
|
#pragma once
|
||||||
#error This file is not part of the common renderer interface, you must undefine NAZARA_RENDERER_COMMON to use it
|
|
||||||
#endif
|
#ifndef NAZARA_OPENGL_HPP
|
||||||
|
#define NAZARA_OPENGL_HPP
|
||||||
#pragma once
|
|
||||||
|
#ifdef NAZARA_RENDERER_OPENGL
|
||||||
#ifndef NAZARA_OPENGL_HPP
|
|
||||||
#define NAZARA_OPENGL_HPP
|
// gl3.h définit WIN32_LEAN_AND_MEAN qui entre en conflit avec la définition de Nazara et doit donc être inclut en premier
|
||||||
|
#include <GL3/glcorearb.h>
|
||||||
// gl3.h définit WIN32_LEAN_AND_MEAN qui entre en conflit avec la définition de Nazara et doit donc être inclut en premier
|
#include <Nazara/Prerequesites.hpp>
|
||||||
#include <GL3/glcorearb.h>
|
#include <Nazara/Core/String.hpp>
|
||||||
#include <Nazara/Prerequesites.hpp>
|
#include <Nazara/Utility/Enums.hpp>
|
||||||
#include <Nazara/Core/String.hpp>
|
#include <Nazara/Renderer/Enums.hpp>
|
||||||
|
|
||||||
// Inclusion des extensions
|
// Inclusion des extensions
|
||||||
#include <GL3/glext.h>
|
#include <GL3/glext.h>
|
||||||
#if defined(NAZARA_PLATFORM_WINDOWS)
|
#if defined(NAZARA_PLATFORM_WINDOWS)
|
||||||
#include <GL3/wglext.h>
|
#include <GL3/wglext.h>
|
||||||
#elif defined(NAZARA_PLATFORM_LINUX)
|
#elif defined(NAZARA_PLATFORM_LINUX)
|
||||||
#include <GL3/glxext.h>
|
#include <GL3/glxext.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
using NzOpenGLFunc = void (*)();
|
enum nzOpenGLExtension
|
||||||
|
{
|
||||||
class NAZARA_API NzOpenGL
|
nzOpenGLExtension_AnisotropicFilter,
|
||||||
{
|
nzOpenGLExtension_DebugOutput,
|
||||||
public:
|
nzOpenGLExtension_FP64,
|
||||||
enum Extension
|
nzOpenGLExtension_FrameBufferObject,
|
||||||
{
|
nzOpenGLExtension_PixelBufferObject,
|
||||||
AnisotropicFilter,
|
nzOpenGLExtension_SeparateShaderObjects,
|
||||||
DebugOutput,
|
nzOpenGLExtension_TextureArray,
|
||||||
FP64,
|
nzOpenGLExtension_TextureCompression_s3tc,
|
||||||
FrameBufferObject,
|
nzOpenGLExtension_TextureStorage,
|
||||||
PixelBufferObject,
|
nzOpenGLExtension_VertexArrayObject,
|
||||||
SeparateShaderObjects,
|
|
||||||
Texture3D,
|
nzOpenGLExtension_Max = nzOpenGLExtension_VertexArrayObject
|
||||||
TextureArray,
|
};
|
||||||
TextureCompression_s3tc,
|
|
||||||
TextureStorage,
|
using NzOpenGLFunc = void (*)();
|
||||||
VertexArrayObject,
|
|
||||||
|
namespace NzOpenGL
|
||||||
Max = VertexArrayObject
|
{
|
||||||
};
|
enum FormatType
|
||||||
|
{
|
||||||
static NzOpenGLFunc GetEntry(const NzString& entryPoint);
|
FormatType_RenderBuffer,
|
||||||
static unsigned int GetVersion();
|
// FormatType_MultisampleTexture,
|
||||||
static bool Initialize();
|
FormatType_Texture
|
||||||
static bool IsSupported(Extension extension);
|
};
|
||||||
static bool IsSupported(const NzString& string);
|
|
||||||
static void Uninitialize();
|
struct Format
|
||||||
};
|
{
|
||||||
|
GLenum dataFormat;
|
||||||
NAZARA_API extern PFNGLACTIVETEXTUREPROC glActiveTexture;
|
GLenum dataType;
|
||||||
NAZARA_API extern PFNGLATTACHSHADERPROC glAttachShader;
|
GLint internalFormat;
|
||||||
NAZARA_API extern PFNGLBEGINQUERYPROC glBeginQuery;
|
};
|
||||||
NAZARA_API extern PFNGLBINDATTRIBLOCATIONPROC glBindAttribLocation;
|
|
||||||
NAZARA_API extern PFNGLBINDBUFFERPROC glBindBuffer;
|
NzOpenGLFunc GetEntry(const NzString& entryPoint);
|
||||||
NAZARA_API extern PFNGLBINDFRAMEBUFFERPROC glBindFramebuffer;
|
unsigned int GetVersion();
|
||||||
NAZARA_API extern PFNGLBINDRENDERBUFFERPROC glBindRenderbuffer;
|
bool Initialize();
|
||||||
NAZARA_API extern PFNGLBINDTEXTUREPROC glBindTexture;
|
bool IsSupported(nzOpenGLExtension extension);
|
||||||
NAZARA_API extern PFNGLBINDVERTEXARRAYPROC glBindVertexArray;
|
bool IsSupported(const NzString& string);
|
||||||
NAZARA_API extern PFNGLBLENDFUNCPROC glBlendFunc;
|
bool TranslateFormat(nzPixelFormat pixelFormat, Format* format, FormatType target);
|
||||||
NAZARA_API extern PFNGLBUFFERDATAPROC glBufferData;
|
void Uninitialize();
|
||||||
NAZARA_API extern PFNGLBUFFERSUBDATAPROC glBufferSubData;
|
|
||||||
NAZARA_API extern PFNGLCLEARPROC glClear;
|
extern GLenum Attachment[nzAttachmentPoint_Max+1];
|
||||||
NAZARA_API extern PFNGLCLEARCOLORPROC glClearColor;
|
extern nzUInt8 AttributeIndex[nzElementUsage_Max+1];
|
||||||
NAZARA_API extern PFNGLCLEARDEPTHPROC glClearDepth;
|
extern GLenum BlendFunc[nzBlendFunc_Max+1];
|
||||||
NAZARA_API extern PFNGLCLEARSTENCILPROC glClearStencil;
|
extern GLenum BufferLock[nzBufferAccess_Max+1];
|
||||||
NAZARA_API extern PFNGLCREATEPROGRAMPROC glCreateProgram;
|
extern GLenum BufferLockRange[nzBufferAccess_Max+1];
|
||||||
NAZARA_API extern PFNGLCREATESHADERPROC glCreateShader;
|
extern GLenum BufferTarget[nzBufferType_Max+1];
|
||||||
NAZARA_API extern PFNGLCHECKFRAMEBUFFERSTATUSPROC glCheckFramebufferStatus;
|
extern GLenum BufferTargetBinding[nzBufferType_Max+1];
|
||||||
NAZARA_API extern PFNGLCOLORMASKPROC glColorMask;
|
extern GLenum BufferUsage[nzBufferUsage_Max+1];
|
||||||
NAZARA_API extern PFNGLCULLFACEPROC glCullFace;
|
extern GLenum CubemapFace[6]; // Un cube possède six faces et ça n'est pas prêt de changer
|
||||||
NAZARA_API extern PFNGLCOMPILESHADERPROC glCompileShader;
|
extern GLenum ElementType[nzElementType_Max+1];
|
||||||
NAZARA_API extern PFNGLCOPYTEXSUBIMAGE2DPROC glCopyTexSubImage2D;
|
extern GLenum FaceCulling[nzFaceCulling_Max+1];
|
||||||
NAZARA_API extern PFNGLDEBUGMESSAGECALLBACKPROC glDebugMessageCallback;
|
extern GLenum FaceFilling[nzFaceFilling_Max+1];
|
||||||
NAZARA_API extern PFNGLDEBUGMESSAGECONTROLPROC glDebugMessageControl;
|
extern GLenum PrimitiveType[nzPrimitiveType_Max+1];
|
||||||
NAZARA_API extern PFNGLDEBUGMESSAGEINSERTPROC glDebugMessageInsert;
|
extern GLenum RendererComparison[nzRendererComparison_Max+1];
|
||||||
NAZARA_API extern PFNGLDELETEBUFFERSPROC glDeleteBuffers;
|
extern GLenum RendererParameter[nzRendererParameter_Max+1];
|
||||||
NAZARA_API extern PFNGLDELETEFRAMEBUFFERSPROC glDeleteFramebuffers;
|
extern GLenum ShaderType[nzShaderType_Max+1];
|
||||||
NAZARA_API extern PFNGLDELETEPROGRAMPROC glDeleteProgram;
|
extern GLenum StencilOperation[nzStencilOperation_Max+1];
|
||||||
NAZARA_API extern PFNGLDELETEQUERIESPROC glDeleteQueries;
|
extern GLenum TextureTarget[nzImageType_Max+1];
|
||||||
NAZARA_API extern PFNGLDELETERENDERBUFFERSPROC glDeleteRenderbuffers;
|
extern GLenum TextureTargetBinding[nzImageType_Max+1];
|
||||||
NAZARA_API extern PFNGLDELETESHADERPROC glDeleteShader;
|
extern GLenum TextureTargetProxy[nzImageType_Max+1];
|
||||||
NAZARA_API extern PFNGLDELETETEXTURESPROC glDeleteTextures;
|
}
|
||||||
NAZARA_API extern PFNGLDELETEVERTEXARRAYSPROC glDeleteVertexArrays;
|
|
||||||
NAZARA_API extern PFNGLDEPTHFUNCPROC glDepthFunc;
|
NAZARA_API extern PFNGLACTIVETEXTUREPROC glActiveTexture;
|
||||||
NAZARA_API extern PFNGLDEPTHMASKPROC glDepthMask;
|
NAZARA_API extern PFNGLATTACHSHADERPROC glAttachShader;
|
||||||
NAZARA_API extern PFNGLDISABLEPROC glDisable;
|
NAZARA_API extern PFNGLBEGINQUERYPROC glBeginQuery;
|
||||||
NAZARA_API extern PFNGLDISABLEVERTEXATTRIBARRAYPROC glDisableVertexAttribArray;
|
NAZARA_API extern PFNGLBINDATTRIBLOCATIONPROC glBindAttribLocation;
|
||||||
NAZARA_API extern PFNGLDRAWARRAYSPROC glDrawArrays;
|
NAZARA_API extern PFNGLBINDBUFFERPROC glBindBuffer;
|
||||||
NAZARA_API extern PFNGLDRAWBUFFERPROC glDrawBuffer;
|
NAZARA_API extern PFNGLBINDFRAMEBUFFERPROC glBindFramebuffer;
|
||||||
NAZARA_API extern PFNGLDRAWBUFFERSPROC glDrawBuffers;
|
NAZARA_API extern PFNGLBINDFRAGDATALOCATIONPROC glBindFragDataLocation;
|
||||||
NAZARA_API extern PFNGLDRAWELEMENTSPROC glDrawElements;
|
NAZARA_API extern PFNGLBINDRENDERBUFFERPROC glBindRenderbuffer;
|
||||||
NAZARA_API extern PFNGLENDQUERYPROC glEndQuery;
|
NAZARA_API extern PFNGLBINDTEXTUREPROC glBindTexture;
|
||||||
NAZARA_API extern PFNGLFLUSHPROC glFlush;
|
NAZARA_API extern PFNGLBINDVERTEXARRAYPROC glBindVertexArray;
|
||||||
NAZARA_API extern PFNGLFRAMEBUFFERRENDERBUFFERPROC glFramebufferRenderbuffer;
|
NAZARA_API extern PFNGLBLENDFUNCPROC glBlendFunc;
|
||||||
NAZARA_API extern PFNGLFRAMEBUFFERTEXTURE2DPROC glFramebufferTexture2D;
|
NAZARA_API extern PFNGLBUFFERDATAPROC glBufferData;
|
||||||
NAZARA_API extern PFNGLENABLEPROC glEnable;
|
NAZARA_API extern PFNGLBUFFERSUBDATAPROC glBufferSubData;
|
||||||
NAZARA_API extern PFNGLENABLEVERTEXATTRIBARRAYPROC glEnableVertexAttribArray;
|
NAZARA_API extern PFNGLCLEARPROC glClear;
|
||||||
NAZARA_API extern PFNGLGENERATEMIPMAPPROC glGenerateMipmap;
|
NAZARA_API extern PFNGLCLEARCOLORPROC glClearColor;
|
||||||
NAZARA_API extern PFNGLGENBUFFERSPROC glGenBuffers;
|
NAZARA_API extern PFNGLCLEARDEPTHPROC glClearDepth;
|
||||||
NAZARA_API extern PFNGLGENFRAMEBUFFERSPROC glGenFramebuffers;
|
NAZARA_API extern PFNGLCLEARSTENCILPROC glClearStencil;
|
||||||
NAZARA_API extern PFNGLGENQUERIESPROC glGenQueries;
|
NAZARA_API extern PFNGLCREATEPROGRAMPROC glCreateProgram;
|
||||||
NAZARA_API extern PFNGLGENRENDERBUFFERSPROC glGenRenderbuffers;
|
NAZARA_API extern PFNGLCREATESHADERPROC glCreateShader;
|
||||||
NAZARA_API extern PFNGLGENTEXTURESPROC glGenTextures;
|
NAZARA_API extern PFNGLCHECKFRAMEBUFFERSTATUSPROC glCheckFramebufferStatus;
|
||||||
NAZARA_API extern PFNGLGENVERTEXARRAYSPROC glGenVertexArrays;
|
NAZARA_API extern PFNGLCOLORMASKPROC glColorMask;
|
||||||
NAZARA_API extern PFNGLGETBUFFERPARAMETERIVPROC glGetBufferParameteriv;
|
NAZARA_API extern PFNGLCULLFACEPROC glCullFace;
|
||||||
NAZARA_API extern PFNGLGETDEBUGMESSAGELOGPROC glGetDebugMessageLog;
|
NAZARA_API extern PFNGLCOMPILESHADERPROC glCompileShader;
|
||||||
NAZARA_API extern PFNGLGETERRORPROC glGetError;
|
NAZARA_API extern PFNGLCOPYTEXSUBIMAGE2DPROC glCopyTexSubImage2D;
|
||||||
NAZARA_API extern PFNGLGETINTEGERVPROC glGetIntegerv;
|
NAZARA_API extern PFNGLDEBUGMESSAGECALLBACKPROC glDebugMessageCallback;
|
||||||
NAZARA_API extern PFNGLGETPROGRAMIVPROC glGetProgramiv;
|
NAZARA_API extern PFNGLDEBUGMESSAGECONTROLPROC glDebugMessageControl;
|
||||||
NAZARA_API extern PFNGLGETPROGRAMINFOLOGPROC glGetProgramInfoLog;
|
NAZARA_API extern PFNGLDEBUGMESSAGEINSERTPROC glDebugMessageInsert;
|
||||||
NAZARA_API extern PFNGLGETQUERYIVPROC glGetQueryiv;
|
NAZARA_API extern PFNGLDELETEBUFFERSPROC glDeleteBuffers;
|
||||||
NAZARA_API extern PFNGLGETQUERYOBJECTIVPROC glGetQueryObjectiv;
|
NAZARA_API extern PFNGLDELETEFRAMEBUFFERSPROC glDeleteFramebuffers;
|
||||||
NAZARA_API extern PFNGLGETQUERYOBJECTUIVPROC glGetQueryObjectuiv;
|
NAZARA_API extern PFNGLDELETEPROGRAMPROC glDeleteProgram;
|
||||||
NAZARA_API extern PFNGLGETSHADERINFOLOGPROC glGetShaderInfoLog;
|
NAZARA_API extern PFNGLDELETEQUERIESPROC glDeleteQueries;
|
||||||
NAZARA_API extern PFNGLGETSHADERIVPROC glGetShaderiv;
|
NAZARA_API extern PFNGLDELETERENDERBUFFERSPROC glDeleteRenderbuffers;
|
||||||
NAZARA_API extern PFNGLGETSHADERSOURCEPROC glGetShaderSource;
|
NAZARA_API extern PFNGLDELETESHADERPROC glDeleteShader;
|
||||||
NAZARA_API extern PFNGLGETSTRINGPROC glGetString;
|
NAZARA_API extern PFNGLDELETETEXTURESPROC glDeleteTextures;
|
||||||
NAZARA_API extern PFNGLGETSTRINGIPROC glGetStringi;
|
NAZARA_API extern PFNGLDELETEVERTEXARRAYSPROC glDeleteVertexArrays;
|
||||||
NAZARA_API extern PFNGLGETTEXIMAGEPROC glGetTexImage;
|
NAZARA_API extern PFNGLDEPTHFUNCPROC glDepthFunc;
|
||||||
NAZARA_API extern PFNGLGETTEXLEVELPARAMETERFVPROC glGetTexLevelParameterfv;
|
NAZARA_API extern PFNGLDEPTHMASKPROC glDepthMask;
|
||||||
NAZARA_API extern PFNGLGETTEXLEVELPARAMETERIVPROC glGetTexLevelParameteriv;
|
NAZARA_API extern PFNGLDISABLEPROC glDisable;
|
||||||
NAZARA_API extern PFNGLGETTEXPARAMETERFVPROC glGetTexParameterfv;
|
NAZARA_API extern PFNGLDISABLEVERTEXATTRIBARRAYPROC glDisableVertexAttribArray;
|
||||||
NAZARA_API extern PFNGLGETTEXPARAMETERIVPROC glGetTexParameteriv;
|
NAZARA_API extern PFNGLDRAWARRAYSPROC glDrawArrays;
|
||||||
NAZARA_API extern PFNGLGETUNIFORMLOCATIONPROC glGetUniformLocation;
|
NAZARA_API extern PFNGLDRAWBUFFERPROC glDrawBuffer;
|
||||||
NAZARA_API extern PFNGLLINKPROGRAMPROC glLinkProgram;
|
NAZARA_API extern PFNGLDRAWBUFFERSPROC glDrawBuffers;
|
||||||
NAZARA_API extern PFNGLMAPBUFFERPROC glMapBuffer;
|
NAZARA_API extern PFNGLDRAWELEMENTSPROC glDrawElements;
|
||||||
NAZARA_API extern PFNGLMAPBUFFERRANGEPROC glMapBufferRange;
|
NAZARA_API extern PFNGLENDQUERYPROC glEndQuery;
|
||||||
NAZARA_API extern PFNGLPIXELSTOREIPROC glPixelStorei;
|
NAZARA_API extern PFNGLFLUSHPROC glFlush;
|
||||||
NAZARA_API extern PFNGLPOLYGONMODEPROC glPolygonMode;
|
NAZARA_API extern PFNGLFRAMEBUFFERRENDERBUFFERPROC glFramebufferRenderbuffer;
|
||||||
NAZARA_API extern PFNGLPROGRAMUNIFORM1DPROC glProgramUniform1d;
|
NAZARA_API extern PFNGLFRAMEBUFFERTEXTUREPROC glFramebufferTexture;
|
||||||
NAZARA_API extern PFNGLPROGRAMUNIFORM1FPROC glProgramUniform1f;
|
NAZARA_API extern PFNGLFRAMEBUFFERTEXTURE1DPROC glFramebufferTexture1D;
|
||||||
NAZARA_API extern PFNGLPROGRAMUNIFORM1IPROC glProgramUniform1i;
|
NAZARA_API extern PFNGLFRAMEBUFFERTEXTURE2DPROC glFramebufferTexture2D;
|
||||||
NAZARA_API extern PFNGLPROGRAMUNIFORM2DVPROC glProgramUniform2dv;
|
NAZARA_API extern PFNGLFRAMEBUFFERTEXTURE3DPROC glFramebufferTexture3D;
|
||||||
NAZARA_API extern PFNGLPROGRAMUNIFORM2FVPROC glProgramUniform2fv;
|
NAZARA_API extern PFNGLFRAMEBUFFERTEXTURELAYERPROC glFramebufferTextureLayer;
|
||||||
NAZARA_API extern PFNGLPROGRAMUNIFORM3DVPROC glProgramUniform3dv;
|
NAZARA_API extern PFNGLENABLEPROC glEnable;
|
||||||
NAZARA_API extern PFNGLPROGRAMUNIFORM3FVPROC glProgramUniform3fv;
|
NAZARA_API extern PFNGLENABLEVERTEXATTRIBARRAYPROC glEnableVertexAttribArray;
|
||||||
NAZARA_API extern PFNGLPROGRAMUNIFORM4DVPROC glProgramUniform4dv;
|
NAZARA_API extern PFNGLGENERATEMIPMAPPROC glGenerateMipmap;
|
||||||
NAZARA_API extern PFNGLPROGRAMUNIFORM4FVPROC glProgramUniform4fv;
|
NAZARA_API extern PFNGLGENBUFFERSPROC glGenBuffers;
|
||||||
NAZARA_API extern PFNGLPROGRAMUNIFORMMATRIX4DVPROC glProgramUniformMatrix4dv;
|
NAZARA_API extern PFNGLGENFRAMEBUFFERSPROC glGenFramebuffers;
|
||||||
NAZARA_API extern PFNGLPROGRAMUNIFORMMATRIX4FVPROC glProgramUniformMatrix4fv;
|
NAZARA_API extern PFNGLGENQUERIESPROC glGenQueries;
|
||||||
NAZARA_API extern PFNGLREADPIXELSPROC glReadPixels;
|
NAZARA_API extern PFNGLGENRENDERBUFFERSPROC glGenRenderbuffers;
|
||||||
NAZARA_API extern PFNGLRENDERBUFFERSTORAGEPROC glRenderbufferStorage;
|
NAZARA_API extern PFNGLGENTEXTURESPROC glGenTextures;
|
||||||
NAZARA_API extern PFNGLSCISSORPROC glScissor;
|
NAZARA_API extern PFNGLGENVERTEXARRAYSPROC glGenVertexArrays;
|
||||||
NAZARA_API extern PFNGLSHADERSOURCEPROC glShaderSource;
|
NAZARA_API extern PFNGLGETBUFFERPARAMETERIVPROC glGetBufferParameteriv;
|
||||||
NAZARA_API extern PFNGLSTENCILFUNCPROC glStencilFunc;
|
NAZARA_API extern PFNGLGETDEBUGMESSAGELOGPROC glGetDebugMessageLog;
|
||||||
NAZARA_API extern PFNGLSTENCILOPPROC glStencilOp;
|
NAZARA_API extern PFNGLGETERRORPROC glGetError;
|
||||||
NAZARA_API extern PFNGLTEXIMAGE1DPROC glTexImage1D;
|
NAZARA_API extern PFNGLGETINTEGERVPROC glGetIntegerv;
|
||||||
NAZARA_API extern PFNGLTEXIMAGE2DPROC glTexImage2D;
|
NAZARA_API extern PFNGLGETPROGRAMIVPROC glGetProgramiv;
|
||||||
NAZARA_API extern PFNGLTEXIMAGE3DPROC glTexImage3D;
|
NAZARA_API extern PFNGLGETPROGRAMINFOLOGPROC glGetProgramInfoLog;
|
||||||
NAZARA_API extern PFNGLTEXPARAMETERFPROC glTexParameterf;
|
NAZARA_API extern PFNGLGETQUERYIVPROC glGetQueryiv;
|
||||||
NAZARA_API extern PFNGLTEXPARAMETERIPROC glTexParameteri;
|
NAZARA_API extern PFNGLGETQUERYOBJECTIVPROC glGetQueryObjectiv;
|
||||||
NAZARA_API extern PFNGLTEXSTORAGE1DPROC glTexStorage1D;
|
NAZARA_API extern PFNGLGETQUERYOBJECTUIVPROC glGetQueryObjectuiv;
|
||||||
NAZARA_API extern PFNGLTEXSTORAGE2DPROC glTexStorage2D;
|
NAZARA_API extern PFNGLGETSHADERINFOLOGPROC glGetShaderInfoLog;
|
||||||
NAZARA_API extern PFNGLTEXSTORAGE3DPROC glTexStorage3D;
|
NAZARA_API extern PFNGLGETSHADERIVPROC glGetShaderiv;
|
||||||
NAZARA_API extern PFNGLTEXSUBIMAGE1DPROC glTexSubImage1D;
|
NAZARA_API extern PFNGLGETSHADERSOURCEPROC glGetShaderSource;
|
||||||
NAZARA_API extern PFNGLTEXSUBIMAGE2DPROC glTexSubImage2D;
|
NAZARA_API extern PFNGLGETSTRINGPROC glGetString;
|
||||||
NAZARA_API extern PFNGLTEXSUBIMAGE3DPROC glTexSubImage3D;
|
NAZARA_API extern PFNGLGETSTRINGIPROC glGetStringi;
|
||||||
NAZARA_API extern PFNGLUNIFORM1DPROC glUniform1d;
|
NAZARA_API extern PFNGLGETTEXIMAGEPROC glGetTexImage;
|
||||||
NAZARA_API extern PFNGLUNIFORM1FPROC glUniform1f;
|
NAZARA_API extern PFNGLGETTEXLEVELPARAMETERFVPROC glGetTexLevelParameterfv;
|
||||||
NAZARA_API extern PFNGLUNIFORM1IPROC glUniform1i;
|
NAZARA_API extern PFNGLGETTEXLEVELPARAMETERIVPROC glGetTexLevelParameteriv;
|
||||||
NAZARA_API extern PFNGLUNIFORM2DVPROC glUniform2dv;
|
NAZARA_API extern PFNGLGETTEXPARAMETERFVPROC glGetTexParameterfv;
|
||||||
NAZARA_API extern PFNGLUNIFORM2FVPROC glUniform2fv;
|
NAZARA_API extern PFNGLGETTEXPARAMETERIVPROC glGetTexParameteriv;
|
||||||
NAZARA_API extern PFNGLUNIFORM3DVPROC glUniform3dv;
|
NAZARA_API extern PFNGLGETUNIFORMLOCATIONPROC glGetUniformLocation;
|
||||||
NAZARA_API extern PFNGLUNIFORM3FVPROC glUniform3fv;
|
NAZARA_API extern PFNGLLINKPROGRAMPROC glLinkProgram;
|
||||||
NAZARA_API extern PFNGLUNIFORM4DVPROC glUniform4dv;
|
NAZARA_API extern PFNGLMAPBUFFERPROC glMapBuffer;
|
||||||
NAZARA_API extern PFNGLUNIFORM4FVPROC glUniform4fv;
|
NAZARA_API extern PFNGLMAPBUFFERRANGEPROC glMapBufferRange;
|
||||||
NAZARA_API extern PFNGLUNIFORMMATRIX4DVPROC glUniformMatrix4dv;
|
NAZARA_API extern PFNGLPIXELSTOREIPROC glPixelStorei;
|
||||||
NAZARA_API extern PFNGLUNIFORMMATRIX4FVPROC glUniformMatrix4fv;
|
NAZARA_API extern PFNGLPOLYGONMODEPROC glPolygonMode;
|
||||||
NAZARA_API extern PFNGLUNMAPBUFFERPROC glUnmapBuffer;
|
NAZARA_API extern PFNGLPROGRAMUNIFORM1DPROC glProgramUniform1d;
|
||||||
NAZARA_API extern PFNGLUSEPROGRAMPROC glUseProgram;
|
NAZARA_API extern PFNGLPROGRAMUNIFORM1FPROC glProgramUniform1f;
|
||||||
NAZARA_API extern PFNGLVERTEXATTRIB4FPROC glVertexAttrib4f;
|
NAZARA_API extern PFNGLPROGRAMUNIFORM1IPROC glProgramUniform1i;
|
||||||
NAZARA_API extern PFNGLVERTEXATTRIBPOINTERPROC glVertexAttribPointer;
|
NAZARA_API extern PFNGLPROGRAMUNIFORM2DVPROC glProgramUniform2dv;
|
||||||
NAZARA_API extern PFNGLVIEWPORTPROC glViewport;
|
NAZARA_API extern PFNGLPROGRAMUNIFORM2FVPROC glProgramUniform2fv;
|
||||||
#if defined(NAZARA_PLATFORM_WINDOWS)
|
NAZARA_API extern PFNGLPROGRAMUNIFORM3DVPROC glProgramUniform3dv;
|
||||||
NAZARA_API extern PFNWGLCHOOSEPIXELFORMATARBPROC wglChoosePixelFormat;
|
NAZARA_API extern PFNGLPROGRAMUNIFORM3FVPROC glProgramUniform3fv;
|
||||||
NAZARA_API extern PFNWGLCREATECONTEXTATTRIBSARBPROC wglCreateContextAttribs;
|
NAZARA_API extern PFNGLPROGRAMUNIFORM4DVPROC glProgramUniform4dv;
|
||||||
NAZARA_API extern PFNWGLGETEXTENSIONSSTRINGARBPROC wglGetExtensionsStringARB;
|
NAZARA_API extern PFNGLPROGRAMUNIFORM4FVPROC glProgramUniform4fv;
|
||||||
NAZARA_API extern PFNWGLGETEXTENSIONSSTRINGEXTPROC wglGetExtensionsStringEXT;
|
NAZARA_API extern PFNGLPROGRAMUNIFORMMATRIX4DVPROC glProgramUniformMatrix4dv;
|
||||||
NAZARA_API extern PFNWGLSWAPINTERVALEXTPROC wglSwapInterval;
|
NAZARA_API extern PFNGLPROGRAMUNIFORMMATRIX4FVPROC glProgramUniformMatrix4fv;
|
||||||
#elif defined(NAZARA_PLATFORM_LINUX)
|
NAZARA_API extern PFNGLREADPIXELSPROC glReadPixels;
|
||||||
NAZARA_API extern PFNGLXCREATECONTEXTATTRIBSARBPROC glXCreateContextAttribs;
|
NAZARA_API extern PFNGLRENDERBUFFERSTORAGEPROC glRenderbufferStorage;
|
||||||
NAZARA_API extern PFNGLXSWAPINTERVALSGIPROC glXSwapInterval;
|
NAZARA_API extern PFNGLSCISSORPROC glScissor;
|
||||||
#endif
|
NAZARA_API extern PFNGLSHADERSOURCEPROC glShaderSource;
|
||||||
|
NAZARA_API extern PFNGLSTENCILFUNCPROC glStencilFunc;
|
||||||
#endif // NAZARA_OPENGL_HPP
|
NAZARA_API extern PFNGLSTENCILOPPROC glStencilOp;
|
||||||
|
NAZARA_API extern PFNGLTEXIMAGE1DPROC glTexImage1D;
|
||||||
|
NAZARA_API extern PFNGLTEXIMAGE2DPROC glTexImage2D;
|
||||||
|
NAZARA_API extern PFNGLTEXIMAGE3DPROC glTexImage3D;
|
||||||
|
NAZARA_API extern PFNGLTEXPARAMETERFPROC glTexParameterf;
|
||||||
|
NAZARA_API extern PFNGLTEXPARAMETERIPROC glTexParameteri;
|
||||||
|
NAZARA_API extern PFNGLTEXSTORAGE1DPROC glTexStorage1D;
|
||||||
|
NAZARA_API extern PFNGLTEXSTORAGE2DPROC glTexStorage2D;
|
||||||
|
NAZARA_API extern PFNGLTEXSTORAGE3DPROC glTexStorage3D;
|
||||||
|
NAZARA_API extern PFNGLTEXSUBIMAGE1DPROC glTexSubImage1D;
|
||||||
|
NAZARA_API extern PFNGLTEXSUBIMAGE2DPROC glTexSubImage2D;
|
||||||
|
NAZARA_API extern PFNGLTEXSUBIMAGE3DPROC glTexSubImage3D;
|
||||||
|
NAZARA_API extern PFNGLUNIFORM1DPROC glUniform1d;
|
||||||
|
NAZARA_API extern PFNGLUNIFORM1FPROC glUniform1f;
|
||||||
|
NAZARA_API extern PFNGLUNIFORM1IPROC glUniform1i;
|
||||||
|
NAZARA_API extern PFNGLUNIFORM2DVPROC glUniform2dv;
|
||||||
|
NAZARA_API extern PFNGLUNIFORM2FVPROC glUniform2fv;
|
||||||
|
NAZARA_API extern PFNGLUNIFORM3DVPROC glUniform3dv;
|
||||||
|
NAZARA_API extern PFNGLUNIFORM3FVPROC glUniform3fv;
|
||||||
|
NAZARA_API extern PFNGLUNIFORM4DVPROC glUniform4dv;
|
||||||
|
NAZARA_API extern PFNGLUNIFORM4FVPROC glUniform4fv;
|
||||||
|
NAZARA_API extern PFNGLUNIFORMMATRIX4DVPROC glUniformMatrix4dv;
|
||||||
|
NAZARA_API extern PFNGLUNIFORMMATRIX4FVPROC glUniformMatrix4fv;
|
||||||
|
NAZARA_API extern PFNGLUNMAPBUFFERPROC glUnmapBuffer;
|
||||||
|
NAZARA_API extern PFNGLUSEPROGRAMPROC glUseProgram;
|
||||||
|
NAZARA_API extern PFNGLVERTEXATTRIB4FPROC glVertexAttrib4f;
|
||||||
|
NAZARA_API extern PFNGLVERTEXATTRIBPOINTERPROC glVertexAttribPointer;
|
||||||
|
NAZARA_API extern PFNGLVIEWPORTPROC glViewport;
|
||||||
|
#if defined(NAZARA_PLATFORM_WINDOWS)
|
||||||
|
NAZARA_API extern PFNWGLCHOOSEPIXELFORMATARBPROC wglChoosePixelFormat;
|
||||||
|
NAZARA_API extern PFNWGLCREATECONTEXTATTRIBSARBPROC wglCreateContextAttribs;
|
||||||
|
NAZARA_API extern PFNWGLGETEXTENSIONSSTRINGARBPROC wglGetExtensionsStringARB;
|
||||||
|
NAZARA_API extern PFNWGLGETEXTENSIONSSTRINGEXTPROC wglGetExtensionsStringEXT;
|
||||||
|
NAZARA_API extern PFNWGLSWAPINTERVALEXTPROC wglSwapInterval;
|
||||||
|
#elif defined(NAZARA_PLATFORM_LINUX)
|
||||||
|
NAZARA_API extern PFNGLXCREATECONTEXTATTRIBSARBPROC glXCreateContextAttribs;
|
||||||
|
NAZARA_API extern PFNGLXSWAPINTERVALSGIPROC glXSwapInterval;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // NAZARA_RENDERER_OPENGL
|
||||||
|
|
||||||
|
#endif // NAZARA_OPENGL_HPP
|
||||||
|
|
|
||||||
|
|
@ -1,42 +1,41 @@
|
||||||
// Copyright (C) 2012 Jérôme Leclercq
|
// Copyright (C) 2012 Jérôme Leclercq
|
||||||
// This file is part of the "Nazara Engine - Renderer module"
|
// This file is part of the "Nazara Engine - Renderer module"
|
||||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#ifndef NAZARA_RENDERTARGET_HPP
|
#ifndef NAZARA_RENDERTARGET_HPP
|
||||||
#define NAZARA_RENDERTARGET_HPP
|
#define NAZARA_RENDERTARGET_HPP
|
||||||
|
|
||||||
#include <Nazara/Prerequesites.hpp>
|
#include <Nazara/Prerequesites.hpp>
|
||||||
#include <Nazara/Renderer/Config.hpp>
|
#include <Nazara/Renderer/Config.hpp>
|
||||||
#include <Nazara/Renderer/RenderTargetParameters.hpp>
|
#include <Nazara/Renderer/RenderTargetParameters.hpp>
|
||||||
|
|
||||||
class NzRenderer;
|
class NzRenderer;
|
||||||
|
|
||||||
class NAZARA_API NzRenderTarget
|
class NAZARA_API NzRenderTarget
|
||||||
{
|
{
|
||||||
friend class NzRenderer;
|
friend class NzRenderer;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
NzRenderTarget() = default;
|
NzRenderTarget() = default;
|
||||||
virtual ~NzRenderTarget();
|
virtual ~NzRenderTarget();
|
||||||
|
|
||||||
#ifndef NAZARA_RENDERER_COMMON
|
virtual unsigned int GetHeight() const = 0;
|
||||||
virtual bool HasContext() const = 0;
|
virtual NzRenderTargetParameters GetParameters() const = 0;
|
||||||
#endif
|
virtual unsigned int GetWidth() const = 0;
|
||||||
|
|
||||||
virtual unsigned int GetHeight() const = 0;
|
bool IsActive() const;
|
||||||
virtual NzRenderTargetParameters GetParameters() const = 0;
|
virtual bool IsRenderable() const = 0;
|
||||||
virtual unsigned int GetWidth() const = 0;
|
|
||||||
|
bool SetActive(bool active);
|
||||||
bool IsActive() const;
|
|
||||||
virtual bool IsValid() const = 0;
|
// Fonctions OpenGL
|
||||||
|
virtual bool HasContext() const = 0;
|
||||||
bool SetActive(bool active);
|
|
||||||
|
protected:
|
||||||
protected:
|
virtual bool Activate() = 0;
|
||||||
virtual bool Activate() = 0;
|
virtual void Desactivate();
|
||||||
virtual void Desactivate();
|
};
|
||||||
};
|
|
||||||
|
#endif // NAZARA_RENDERTARGET_HPP
|
||||||
#endif // NAZARA_RENDERTARGET_HPP
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,60 @@
|
||||||
|
// Copyright (C) 2012 Jérôme Leclercq
|
||||||
|
// This file is part of the "Nazara Engine - Renderer module"
|
||||||
|
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#ifndef NAZARA_RENDERTEXTURE_HPP
|
||||||
|
#define NAZARA_RENDERTEXTURE_HPP
|
||||||
|
|
||||||
|
#include <Nazara/Prerequesites.hpp>
|
||||||
|
#include <Nazara/Core/NonCopyable.hpp>
|
||||||
|
#include <Nazara/Core/ResourceListener.hpp>
|
||||||
|
#include <Nazara/Renderer/Config.hpp>
|
||||||
|
#include <Nazara/Renderer/RenderTarget.hpp>
|
||||||
|
#include <Nazara/Renderer/Texture.hpp>
|
||||||
|
|
||||||
|
struct NzRenderTextureImpl;
|
||||||
|
|
||||||
|
class NAZARA_API NzRenderTexture : public NzRenderTarget, NzResourceListener, NzNonCopyable
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
NzRenderTexture() = default;
|
||||||
|
~NzRenderTexture();
|
||||||
|
|
||||||
|
bool AttachBuffer(nzAttachmentPoint attachmentPoint, nzUInt8 index, nzPixelFormat format);
|
||||||
|
bool AttachTexture(nzAttachmentPoint attachmentPoint, nzUInt8 index, NzTexture* texture);
|
||||||
|
bool AttachTexture(nzAttachmentPoint attachmentPoint, nzUInt8 index, NzTexture* texture, unsigned int z);
|
||||||
|
|
||||||
|
bool Create(unsigned int width, unsigned int height, bool lock = false);
|
||||||
|
void Destroy();
|
||||||
|
|
||||||
|
void Detach(nzAttachmentPoint attachmentPoint, nzUInt8 index);
|
||||||
|
|
||||||
|
unsigned int GetHeight() const;
|
||||||
|
NzRenderTargetParameters GetParameters() const;
|
||||||
|
unsigned int GetWidth() const;
|
||||||
|
|
||||||
|
bool IsComplete() const;
|
||||||
|
bool IsRenderable() const;
|
||||||
|
bool IsValid() const;
|
||||||
|
|
||||||
|
bool Lock() const;
|
||||||
|
void Unlock() const;
|
||||||
|
|
||||||
|
// Fonctions OpenGL
|
||||||
|
bool HasContext() const;
|
||||||
|
|
||||||
|
static bool IsSupported();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool Activate() override;
|
||||||
|
void Desactivate() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void OnResourceDestroy(const NzResource* resource, int index) override;
|
||||||
|
|
||||||
|
NzRenderTextureImpl* m_impl = nullptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // NAZARA_RENDERTEXTURE_HPP
|
||||||
|
|
@ -1,71 +1,68 @@
|
||||||
// Copyright (C) 2012 Jérôme Leclercq
|
// Copyright (C) 2012 Jérôme Leclercq
|
||||||
// This file is part of the "Nazara Engine - Renderer module"
|
// This file is part of the "Nazara Engine - Renderer module"
|
||||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||||
|
|
||||||
// Interface inspirée de la SFML par Laurent Gomila
|
// Interface inspirée de la SFML par Laurent Gomila
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#ifndef NAZARA_RENDERWINDOW_HPP
|
#ifndef NAZARA_RENDERWINDOW_HPP
|
||||||
#define NAZARA_RENDERWINDOW_HPP
|
#define NAZARA_RENDERWINDOW_HPP
|
||||||
|
|
||||||
#include <Nazara/Prerequesites.hpp>
|
#include <Nazara/Prerequesites.hpp>
|
||||||
#include <Nazara/Core/Clock.hpp>
|
#include <Nazara/Core/Clock.hpp>
|
||||||
#include <Nazara/Renderer/Config.hpp>
|
#include <Nazara/Renderer/Config.hpp>
|
||||||
#include <Nazara/Renderer/ContextParameters.hpp>
|
#include <Nazara/Renderer/ContextParameters.hpp>
|
||||||
#include <Nazara/Renderer/RenderTarget.hpp>
|
#include <Nazara/Renderer/RenderTarget.hpp>
|
||||||
#include <Nazara/Utility/Window.hpp>
|
#include <Nazara/Utility/Window.hpp>
|
||||||
|
|
||||||
class NzContext;
|
class NzContext;
|
||||||
class NzImage;
|
class NzImage;
|
||||||
class NzTexture;
|
class NzTexture;
|
||||||
struct NzContextParameters;
|
struct NzContextParameters;
|
||||||
|
|
||||||
class NAZARA_API NzRenderWindow : public NzRenderTarget, public NzWindow
|
class NAZARA_API NzRenderWindow : public NzRenderTarget, public NzWindow
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
NzRenderWindow() = default;
|
NzRenderWindow() = default;
|
||||||
NzRenderWindow(NzVideoMode mode, const NzString& title, nzUInt32 style = nzWindowStyle_Default, const NzContextParameters& parameters = NzContextParameters());
|
NzRenderWindow(NzVideoMode mode, const NzString& title, nzUInt32 style = nzWindowStyle_Default, const NzContextParameters& parameters = NzContextParameters());
|
||||||
NzRenderWindow(NzWindowHandle handle, const NzContextParameters& parameters = NzContextParameters());
|
NzRenderWindow(NzWindowHandle handle, const NzContextParameters& parameters = NzContextParameters());
|
||||||
virtual ~NzRenderWindow();
|
virtual ~NzRenderWindow();
|
||||||
|
|
||||||
bool CopyToImage(NzImage* image); ///TODO: Const
|
bool CopyToImage(NzImage* image); ///TODO: Const
|
||||||
bool CopyToTexture(NzTexture* texture); ///TODO: Const
|
bool CopyToTexture(NzTexture* texture); ///TODO: Const
|
||||||
|
|
||||||
bool Create(NzVideoMode mode, const NzString& title, nzUInt32 style = nzWindowStyle_Default, const NzContextParameters& parameters = NzContextParameters());
|
bool Create(NzVideoMode mode, const NzString& title, nzUInt32 style = nzWindowStyle_Default, const NzContextParameters& parameters = NzContextParameters());
|
||||||
bool Create(NzWindowHandle handle, const NzContextParameters& parameters = NzContextParameters());
|
bool Create(NzWindowHandle handle, const NzContextParameters& parameters = NzContextParameters());
|
||||||
|
|
||||||
void Display();
|
void Display();
|
||||||
|
|
||||||
void EnableVerticalSync(bool enabled);
|
void EnableVerticalSync(bool enabled);
|
||||||
|
|
||||||
#ifndef NAZARA_RENDERER_COMMON
|
unsigned int GetHeight() const;
|
||||||
NzContextParameters GetContextParameters() const;
|
NzRenderTargetParameters GetParameters() const;
|
||||||
#endif
|
unsigned int GetWidth() const;
|
||||||
|
|
||||||
unsigned int GetHeight() const;
|
bool IsRenderable() const;
|
||||||
NzRenderTargetParameters GetParameters() const;
|
bool IsValid() const;
|
||||||
unsigned int GetWidth() const;
|
|
||||||
|
void SetFramerateLimit(unsigned int limit);
|
||||||
#ifndef NAZARA_RENDERER_COMMON
|
|
||||||
bool HasContext() const;
|
// Fonctions OpenGL
|
||||||
#endif
|
NzContextParameters GetContextParameters() const;
|
||||||
|
bool HasContext() const;
|
||||||
bool IsValid() const;
|
|
||||||
|
protected:
|
||||||
void SetFramerateLimit(unsigned int limit);
|
bool Activate() override;
|
||||||
|
|
||||||
protected:
|
private:
|
||||||
virtual bool Activate() override;
|
bool OnWindowCreated() override;
|
||||||
|
void OnWindowDestroy() override;
|
||||||
private:
|
|
||||||
virtual void OnWindowDestroying() override;
|
NzClock m_clock;
|
||||||
virtual bool OnWindowCreated() override;
|
NzContextParameters m_parameters;
|
||||||
|
NzContext* m_context = nullptr;
|
||||||
NzClock m_clock;
|
unsigned int m_framerateLimit = 0;
|
||||||
NzContextParameters m_parameters;
|
};
|
||||||
NzContext* m_context = nullptr;
|
|
||||||
unsigned int m_framerateLimit = 0;
|
#endif // NAZARA_RENDERWINDOW_HPP
|
||||||
};
|
|
||||||
|
|
||||||
#endif // NAZARA_RENDERWINDOW_HPP
|
|
||||||
|
|
|
||||||
|
|
@ -1,89 +1,92 @@
|
||||||
// Copyright (C) 2012 Jérôme Leclercq
|
// Copyright (C) 2012 Jérôme Leclercq
|
||||||
// This file is part of the "Nazara Engine - Renderer module"
|
// This file is part of the "Nazara Engine - Renderer module"
|
||||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#ifndef NAZARA_TEXTURE_HPP
|
#ifndef NAZARA_TEXTURE_HPP
|
||||||
#define NAZARA_TEXTURE_HPP
|
#define NAZARA_TEXTURE_HPP
|
||||||
|
|
||||||
#include <Nazara/Prerequesites.hpp>
|
#include <Nazara/Prerequesites.hpp>
|
||||||
#include <Nazara/Core/NonCopyable.hpp>
|
#include <Nazara/Core/NonCopyable.hpp>
|
||||||
#include <Nazara/Renderer/Enums.hpp>
|
#include <Nazara/Renderer/Enums.hpp>
|
||||||
#include <Nazara/Utility/Image.hpp>
|
#include <Nazara/Utility/Image.hpp>
|
||||||
#include <Nazara/Utility/PixelFormat.hpp>
|
#include <Nazara/Utility/PixelFormat.hpp>
|
||||||
|
|
||||||
struct NzTextureImpl;
|
class NzRenderTexture;
|
||||||
|
struct NzTextureImpl;
|
||||||
class NAZARA_API NzTexture : public NzResource, NzNonCopyable
|
|
||||||
{
|
class NAZARA_API NzTexture : public NzResource, NzNonCopyable
|
||||||
friend class NzShader;
|
{
|
||||||
|
friend NzRenderTexture;
|
||||||
public:
|
friend class NzShader;
|
||||||
NzTexture();
|
|
||||||
explicit NzTexture(const NzImage& image);
|
public:
|
||||||
~NzTexture();
|
NzTexture();
|
||||||
|
explicit NzTexture(const NzImage& image);
|
||||||
#ifndef NAZARA_RENDERER_COMMON
|
~NzTexture();
|
||||||
bool Bind() const;
|
|
||||||
#endif
|
bool Create(nzImageType type, nzPixelFormat format, unsigned int width, unsigned int height, unsigned int depth = 1, nzUInt8 levelCount = 1, bool lock = false);
|
||||||
|
void Destroy();
|
||||||
bool Create(nzImageType type, nzPixelFormat format, unsigned int width, unsigned int height, unsigned int depth = 1, nzUInt8 levelCount = 1, bool lock = false);
|
|
||||||
void Destroy();
|
bool Download(NzImage* image) const;
|
||||||
|
|
||||||
bool Download(NzImage* image) const;
|
bool EnableMipmapping(bool enable);
|
||||||
|
|
||||||
bool EnableMipmapping(bool enable);
|
unsigned int GetAnisotropyLevel() const;
|
||||||
|
nzUInt8 GetBPP() const;
|
||||||
unsigned int GetAnisotropyLevel() const;
|
unsigned int GetDepth() const;
|
||||||
nzUInt8 GetBPP() const;
|
nzTextureFilter GetFilterMode() const;
|
||||||
unsigned int GetDepth() const;
|
nzPixelFormat GetFormat() const;
|
||||||
nzTextureFilter GetFilterMode() const;
|
unsigned int GetHeight() const;
|
||||||
nzPixelFormat GetFormat() const;
|
nzImageType GetType() const;
|
||||||
unsigned int GetHeight() const;
|
unsigned int GetWidth() const;
|
||||||
nzImageType GetType() const;
|
nzTextureWrap GetWrapMode() const;
|
||||||
unsigned int GetWidth() const;
|
|
||||||
nzTextureWrap GetWrapMode() const;
|
bool IsCompressed() const;
|
||||||
|
bool IsCubemap() const;
|
||||||
bool IsCompressed() const;
|
bool IsTarget() const;
|
||||||
bool IsCubemap() const;
|
bool IsValid() const;
|
||||||
bool IsTarget() const;
|
|
||||||
bool IsValid() const;
|
bool LoadFromFile(const NzString& filePath, const NzImageParams& params = NzImageParams());
|
||||||
|
bool LoadFromImage(const NzImage& image);
|
||||||
bool LoadFromFile(const NzString& filePath, const NzImageParams& params = NzImageParams());
|
bool LoadFromMemory(const void* data, std::size_t size, const NzImageParams& params = NzImageParams());
|
||||||
bool LoadFromImage(const NzImage& image);
|
bool LoadFromStream(NzInputStream& stream, const NzImageParams& params = NzImageParams());
|
||||||
bool LoadFromMemory(const void* data, std::size_t size, const NzImageParams& params = NzImageParams());
|
|
||||||
bool LoadFromStream(NzInputStream& stream, const NzImageParams& params = NzImageParams());
|
bool Lock();
|
||||||
|
|
||||||
bool Lock();
|
bool SetAnisotropyLevel(unsigned int anistropyLevel);
|
||||||
|
bool SetFilterMode(nzTextureFilter filter);
|
||||||
bool SetAnisotropyLevel(unsigned int anistropyLevel);
|
bool SetMipmapRange(nzUInt8 minLevel, nzUInt8 maxLevel);
|
||||||
bool SetFilterMode(nzTextureFilter filter);
|
bool SetWrapMode(nzTextureWrap wrap);
|
||||||
bool SetMipmapRange(nzUInt8 minLevel, nzUInt8 maxLevel);
|
|
||||||
bool SetWrapMode(nzTextureWrap wrap);
|
bool Update(const NzImage& image, nzUInt8 level = 0);
|
||||||
|
bool Update(const NzImage& image, const NzRectui& rect, unsigned int z = 0, nzUInt8 level = 0);
|
||||||
bool Update(const NzImage& image, nzUInt8 level = 0);
|
bool Update(const NzImage& image, const NzCubeui& cube, nzUInt8 level = 0);
|
||||||
bool Update(const NzImage& image, const NzRectui& rect, unsigned int z = 0, nzUInt8 level = 0);
|
bool Update(const nzUInt8* pixels, nzUInt8 level = 0);
|
||||||
bool Update(const NzImage& image, const NzCubeui& cube, nzUInt8 level = 0);
|
bool Update(const nzUInt8* pixels, const NzRectui& rect, unsigned int z = 0, nzUInt8 level = 0);
|
||||||
bool Update(const nzUInt8* pixels, nzUInt8 level = 0);
|
bool Update(const nzUInt8* pixels, const NzCubeui& cube, nzUInt8 level = 0);
|
||||||
bool Update(const nzUInt8* pixels, const NzRectui& rect, unsigned int z = 0, nzUInt8 level = 0);
|
bool UpdateFace(nzCubemapFace face, const NzImage& image, nzUInt8 level = 0);
|
||||||
bool Update(const nzUInt8* pixels, const NzCubeui& cube, nzUInt8 level = 0);
|
bool UpdateFace(nzCubemapFace face, const NzImage& image, const NzRectui& rect, nzUInt8 level = 0);
|
||||||
bool UpdateFace(nzCubemapFace face, const NzImage& image, nzUInt8 level = 0);
|
bool UpdateFace(nzCubemapFace face, const nzUInt8* pixels, nzUInt8 level = 0);
|
||||||
bool UpdateFace(nzCubemapFace face, const NzImage& image, const NzRectui& rect, nzUInt8 level = 0);
|
bool UpdateFace(nzCubemapFace face, const nzUInt8* pixels, const NzRectui& rect, nzUInt8 level = 0);
|
||||||
bool UpdateFace(nzCubemapFace face, const nzUInt8* pixels, nzUInt8 level = 0);
|
|
||||||
bool UpdateFace(nzCubemapFace face, const nzUInt8* pixels, const NzRectui& rect, nzUInt8 level = 0);
|
void Unlock();
|
||||||
|
|
||||||
void Unlock();
|
// Fonctions OpenGL
|
||||||
|
unsigned int GetOpenGLID() const;
|
||||||
static unsigned int GetValidSize(unsigned int size);
|
bool Prepare() const;
|
||||||
static bool IsFormatSupported(nzPixelFormat format);
|
|
||||||
static bool IsMipmappingSupported();
|
static unsigned int GetValidSize(unsigned int size);
|
||||||
static bool IsTypeSupported(nzImageType type);
|
static bool IsFormatSupported(nzPixelFormat format);
|
||||||
|
static bool IsMipmappingSupported();
|
||||||
private:
|
static bool IsTypeSupported(nzImageType type);
|
||||||
void SetTarget(bool isTarget);
|
|
||||||
|
private:
|
||||||
NzTextureImpl* m_impl;
|
NzRenderTexture* GetRenderTexture() const;
|
||||||
};
|
void SetRenderTexture(NzRenderTexture* renderTexture);
|
||||||
|
|
||||||
#endif // NAZARA_TEXTURE_HPP
|
NzTextureImpl* m_impl;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // NAZARA_TEXTURE_HPP
|
||||||
|
|
|
||||||
|
|
@ -1,77 +1,78 @@
|
||||||
// Copyright (C) 2012 Jérôme Leclercq
|
// Copyright (C) 2012 Jérôme Leclercq
|
||||||
// This file is part of the "Nazara Engine - Utility module"
|
// This file is part of the "Nazara Engine - Utility module"
|
||||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#ifndef NAZARA_ANIMATION_HPP
|
#ifndef NAZARA_ANIMATION_HPP
|
||||||
#define NAZARA_ANIMATION_HPP
|
#define NAZARA_ANIMATION_HPP
|
||||||
|
|
||||||
#include <Nazara/Prerequesites.hpp>
|
#include <Nazara/Prerequesites.hpp>
|
||||||
#include <Nazara/Core/Resource.hpp>
|
#include <Nazara/Core/Resource.hpp>
|
||||||
#include <Nazara/Core/ResourceLoader.hpp>
|
#include <Nazara/Core/ResourceLoader.hpp>
|
||||||
#include <Nazara/Core/String.hpp>
|
#include <Nazara/Core/String.hpp>
|
||||||
#include <Nazara/Utility/Enums.hpp>
|
#include <Nazara/Utility/Enums.hpp>
|
||||||
|
|
||||||
struct NzAnimationParams
|
struct NzAnimationParams
|
||||||
{
|
{
|
||||||
unsigned int endFrame = static_cast<unsigned int>(-1);
|
unsigned int endFrame = static_cast<unsigned int>(-1);
|
||||||
unsigned int startFrame = 0;
|
unsigned int startFrame = 0;
|
||||||
|
|
||||||
bool IsValid() const;
|
bool IsValid() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct NzSequence
|
struct NzSequence
|
||||||
{
|
{
|
||||||
NzString name;
|
NzString name;
|
||||||
unsigned int firstFrame;
|
unsigned int firstFrame;
|
||||||
unsigned int lastFrame;
|
unsigned int lastFrame;
|
||||||
unsigned int framePerSecond;
|
unsigned int framePerSecond;
|
||||||
};
|
};
|
||||||
|
|
||||||
class NzAnimation;
|
class NzAnimation;
|
||||||
|
|
||||||
using NzAnimationLoader = NzResourceLoader<NzAnimation, NzAnimationParams>;
|
using NzAnimationLoader = NzResourceLoader<NzAnimation, NzAnimationParams>;
|
||||||
|
|
||||||
struct NzAnimationImpl;
|
struct NzAnimationImpl;
|
||||||
|
|
||||||
class NAZARA_API NzAnimation : public NzResource
|
class NAZARA_API NzAnimation : public NzResource
|
||||||
{
|
{
|
||||||
friend NzAnimationLoader;
|
friend NzAnimationLoader;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
NzAnimation() = default;
|
NzAnimation() = default;
|
||||||
~NzAnimation();
|
~NzAnimation();
|
||||||
|
|
||||||
unsigned int AddSequence(const NzSequence& sequence);
|
bool AddSequence(const NzSequence& sequence);
|
||||||
|
|
||||||
bool Create(nzAnimationType type, unsigned int frameCount);
|
bool Create(nzAnimationType type, unsigned int frameCount);
|
||||||
void Destroy();
|
void Destroy();
|
||||||
|
|
||||||
unsigned int GetFrameCount() const;
|
unsigned int GetFrameCount() const;
|
||||||
NzSequence* GetSequence(const NzString& sequenceName);
|
NzSequence* GetSequence(const NzString& sequenceName);
|
||||||
NzSequence* GetSequence(unsigned int index);
|
NzSequence* GetSequence(unsigned int index);
|
||||||
const NzSequence* GetSequence(const NzString& sequenceName) const;
|
const NzSequence* GetSequence(const NzString& sequenceName) const;
|
||||||
const NzSequence* GetSequence(unsigned int index) const;
|
const NzSequence* GetSequence(unsigned int index) const;
|
||||||
unsigned int GetSequenceCount() const;
|
unsigned int GetSequenceCount() const;
|
||||||
nzAnimationType GetType() const;
|
int GetSequenceIndex(const NzString& sequenceName) const;
|
||||||
|
nzAnimationType GetType() const;
|
||||||
bool HasSequence(const NzString& sequenceName) const;
|
|
||||||
bool HasSequence(unsigned int index = 0) const;
|
bool HasSequence(const NzString& sequenceName) const;
|
||||||
|
bool HasSequence(unsigned int index = 0) const;
|
||||||
bool IsValid() const;
|
|
||||||
|
bool IsValid() const;
|
||||||
bool LoadFromFile(const NzString& filePath, const NzAnimationParams& params = NzAnimationParams());
|
|
||||||
bool LoadFromMemory(const void* data, std::size_t size, const NzAnimationParams& params = NzAnimationParams());
|
bool LoadFromFile(const NzString& filePath, const NzAnimationParams& params = NzAnimationParams());
|
||||||
bool LoadFromStream(NzInputStream& stream, const NzAnimationParams& params = NzAnimationParams());
|
bool LoadFromMemory(const void* data, std::size_t size, const NzAnimationParams& params = NzAnimationParams());
|
||||||
|
bool LoadFromStream(NzInputStream& stream, const NzAnimationParams& params = NzAnimationParams());
|
||||||
void RemoveSequence(const NzString& sequenceName);
|
|
||||||
void RemoveSequence(unsigned int index);
|
void RemoveSequence(const NzString& sequenceName);
|
||||||
|
void RemoveSequence(unsigned int index);
|
||||||
private:
|
|
||||||
NzAnimationImpl* m_impl = nullptr;
|
private:
|
||||||
|
NzAnimationImpl* m_impl = nullptr;
|
||||||
static NzAnimationLoader::LoaderList s_loaders;
|
|
||||||
};
|
static NzAnimationLoader::LoaderList s_loaders;
|
||||||
|
};
|
||||||
#endif // NAZARA_ANIMATION_HPP
|
|
||||||
|
#endif // NAZARA_ANIMATION_HPP
|
||||||
|
|
|
||||||
|
|
@ -1,220 +1,250 @@
|
||||||
// Copyright (C) 2012 Jérôme Leclercq
|
// Copyright (C) 2012 Jérôme Leclercq
|
||||||
// This file is part of the "Nazara Engine - Utility module"
|
// This file is part of the "Nazara Engine - Utility module"
|
||||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#ifndef NAZARA_ENUMS_UTILITY_HPP
|
#ifndef NAZARA_ENUMS_UTILITY_HPP
|
||||||
#define NAZARA_ENUMS_UTILITY_HPP
|
#define NAZARA_ENUMS_UTILITY_HPP
|
||||||
|
|
||||||
enum nzAnimationType
|
enum nzAnimationType
|
||||||
{
|
{
|
||||||
nzAnimationType_Keyframe,
|
nzAnimationType_Keyframe,
|
||||||
nzAnimationType_Skeletal,
|
nzAnimationType_Skeletal,
|
||||||
nzAnimationType_Static
|
nzAnimationType_Static,
|
||||||
};
|
|
||||||
|
nzAnimationType_Max = nzAnimationType_Static
|
||||||
enum nzBufferAccess
|
};
|
||||||
{
|
|
||||||
nzBufferAccess_DiscardAndWrite,
|
enum nzBufferAccess
|
||||||
nzBufferAccess_ReadOnly,
|
{
|
||||||
nzBufferAccess_ReadWrite,
|
nzBufferAccess_DiscardAndWrite,
|
||||||
nzBufferAccess_WriteOnly
|
nzBufferAccess_ReadOnly,
|
||||||
};
|
nzBufferAccess_ReadWrite,
|
||||||
|
nzBufferAccess_WriteOnly,
|
||||||
enum nzBufferStorage
|
|
||||||
{
|
nzBufferAccess_Max = nzBufferAccess_WriteOnly
|
||||||
//nzBufferStorage_Both,
|
};
|
||||||
nzBufferStorage_Hardware,
|
|
||||||
nzBufferStorage_Software,
|
enum nzBufferStorage
|
||||||
|
{
|
||||||
nzBufferStorage_Max = nzBufferStorage_Software
|
//nzBufferStorage_Both,
|
||||||
};
|
nzBufferStorage_Hardware,
|
||||||
|
nzBufferStorage_Software,
|
||||||
enum nzBufferType
|
|
||||||
{
|
nzBufferStorage_Max = nzBufferStorage_Software
|
||||||
nzBufferType_Index,
|
};
|
||||||
nzBufferType_Vertex
|
|
||||||
};
|
enum nzBufferType
|
||||||
|
{
|
||||||
enum nzBufferUsage
|
nzBufferType_Index,
|
||||||
{
|
nzBufferType_Vertex,
|
||||||
nzBufferUsage_Dynamic,
|
|
||||||
nzBufferUsage_Static
|
nzBufferType_Max = nzBufferType_Vertex
|
||||||
};
|
};
|
||||||
|
|
||||||
enum nzCubemapFace
|
enum nzBufferUsage
|
||||||
{
|
{
|
||||||
// Cette énumération est prévue pour remplacer l'argument "z" des méthodes de NzImage contenant un cubemap
|
nzBufferUsage_Dynamic,
|
||||||
// L'ordre est X, -X, Y, -Y, Z, -Z
|
nzBufferUsage_Static,
|
||||||
nzCubemapFace_PositiveX = 0,
|
|
||||||
nzCubemapFace_PositiveY = 2,
|
nzBufferUsage_Max = nzBufferUsage_Static
|
||||||
nzCubemapFace_PositiveZ = 4,
|
};
|
||||||
nzCubemapFace_NegativeX = 1,
|
|
||||||
nzCubemapFace_NegativeY = 3,
|
enum nzCubemapFace
|
||||||
nzCubemapFace_NegativeZ = 5
|
{
|
||||||
};
|
// Cette énumération est prévue pour remplacer l'argument "z" des méthodes de NzImage contenant un cubemap
|
||||||
|
// L'ordre est X, -X, Y, -Y, Z, -Z
|
||||||
enum nzElementStream
|
nzCubemapFace_PositiveX = 0,
|
||||||
{
|
nzCubemapFace_PositiveY = 2,
|
||||||
nzElementStream_VertexData,
|
nzCubemapFace_PositiveZ = 4,
|
||||||
nzElementStream_InstancedData,
|
nzCubemapFace_NegativeX = 1,
|
||||||
|
nzCubemapFace_NegativeY = 3,
|
||||||
nzElementStream_Max = nzElementStream_InstancedData
|
nzCubemapFace_NegativeZ = 5,
|
||||||
};
|
|
||||||
|
nzCubemapFace_Max = nzCubemapFace_NegativeZ
|
||||||
enum nzElementType
|
};
|
||||||
{
|
|
||||||
nzElementType_Color,
|
enum nzElementStream
|
||||||
nzElementType_Double1,
|
{
|
||||||
nzElementType_Double2,
|
nzElementStream_VertexData,
|
||||||
nzElementType_Double3,
|
nzElementStream_InstancedData,
|
||||||
nzElementType_Double4,
|
|
||||||
nzElementType_Float1,
|
nzElementStream_Max = nzElementStream_InstancedData
|
||||||
nzElementType_Float2,
|
};
|
||||||
nzElementType_Float3,
|
|
||||||
nzElementType_Float4
|
enum nzElementType
|
||||||
};
|
{
|
||||||
|
nzElementType_Color,
|
||||||
enum nzElementUsage
|
nzElementType_Double1,
|
||||||
{
|
nzElementType_Double2,
|
||||||
nzElementUsage_Diffuse,
|
nzElementType_Double3,
|
||||||
nzElementUsage_Normal,
|
nzElementType_Double4,
|
||||||
nzElementUsage_Position,
|
nzElementType_Float1,
|
||||||
nzElementUsage_Tangent,
|
nzElementType_Float2,
|
||||||
nzElementUsage_TexCoord,
|
nzElementType_Float3,
|
||||||
|
nzElementType_Float4,
|
||||||
nzElementUsage_Max = nzElementUsage_TexCoord
|
|
||||||
};
|
nzElementType_Max = nzElementType_Float4
|
||||||
|
};
|
||||||
enum nzEventType
|
|
||||||
{
|
enum nzElementUsage
|
||||||
nzEventType_GainedFocus,
|
{
|
||||||
nzEventType_LostFocus,
|
nzElementUsage_Diffuse,
|
||||||
nzEventType_KeyPressed,
|
nzElementUsage_Normal,
|
||||||
nzEventType_KeyReleased,
|
nzElementUsage_Position,
|
||||||
nzEventType_MouseButtonDoubleClicked,
|
nzElementUsage_Tangent,
|
||||||
nzEventType_MouseButtonPressed,
|
nzElementUsage_TexCoord,
|
||||||
nzEventType_MouseButtonReleased,
|
|
||||||
nzEventType_MouseEntered,
|
nzElementUsage_Max = nzElementUsage_TexCoord
|
||||||
nzEventType_MouseLeft,
|
};
|
||||||
nzEventType_MouseMoved,
|
|
||||||
nzEventType_MouseWheelMoved,
|
enum nzEventType
|
||||||
nzEventType_Moved,
|
{
|
||||||
nzEventType_Quit,
|
nzEventType_GainedFocus,
|
||||||
nzEventType_Resized,
|
nzEventType_LostFocus,
|
||||||
nzEventType_TextEntered
|
nzEventType_KeyPressed,
|
||||||
};
|
nzEventType_KeyReleased,
|
||||||
|
nzEventType_MouseButtonDoubleClicked,
|
||||||
enum nzExtend
|
nzEventType_MouseButtonPressed,
|
||||||
{
|
nzEventType_MouseButtonReleased,
|
||||||
nzExtend_Finite,
|
nzEventType_MouseEntered,
|
||||||
nzExtend_Infinite,
|
nzEventType_MouseLeft,
|
||||||
nzExtend_Null
|
nzEventType_MouseMoved,
|
||||||
};
|
nzEventType_MouseWheelMoved,
|
||||||
|
nzEventType_Moved,
|
||||||
enum nzImageType
|
nzEventType_Quit,
|
||||||
{
|
nzEventType_Resized,
|
||||||
nzImageType_1D,
|
nzEventType_TextEntered,
|
||||||
nzImageType_1D_Array,
|
|
||||||
nzImageType_2D,
|
nzEventType_Max = nzEventType_TextEntered
|
||||||
nzImageType_2D_Array,
|
};
|
||||||
nzImageType_3D,
|
|
||||||
nzImageType_Cubemap,
|
enum nzExtend
|
||||||
|
{
|
||||||
nzImageType_Max = nzImageType_Cubemap
|
nzExtend_Finite,
|
||||||
};
|
nzExtend_Infinite,
|
||||||
|
nzExtend_Null,
|
||||||
enum nzPixelFormat
|
|
||||||
{
|
nzExtend_Max = nzExtend_Null
|
||||||
nzPixelFormat_Undefined = -1,
|
};
|
||||||
|
|
||||||
nzPixelFormat_BGR8, // 3*nzUInt8
|
enum nzImageType
|
||||||
nzPixelFormat_BGRA8, // 4*nzUInt8
|
{
|
||||||
nzPixelFormat_DXT1,
|
nzImageType_1D,
|
||||||
nzPixelFormat_DXT3,
|
nzImageType_1D_Array,
|
||||||
nzPixelFormat_DXT5,
|
nzImageType_2D,
|
||||||
nzPixelFormat_L8, // 1*nzUInt8
|
nzImageType_2D_Array,
|
||||||
nzPixelFormat_LA8, // 2*nzUInt8
|
nzImageType_3D,
|
||||||
/*
|
nzImageType_Cubemap,
|
||||||
nzPixelFormat_RGB16F,
|
|
||||||
nzPixelFormat_RGB16I, // 4*nzUInt16
|
nzImageType_Max = nzImageType_Cubemap
|
||||||
nzPixelFormat_RGB32F,
|
};
|
||||||
nzPixelFormat_RGB32I, // 4*nzUInt32
|
|
||||||
nzPixelFormat_RGBA16F,
|
enum nzPixelFormat
|
||||||
nzPixelFormat_RGBA16I, // 4*nzUInt16
|
{
|
||||||
nzPixelFormat_RGBA32F,
|
nzPixelFormat_Undefined = -1,
|
||||||
nzPixelFormat_RGBA32I, // 4*nzUInt32
|
|
||||||
*/
|
nzPixelFormat_BGR8, // 3*nzUInt8
|
||||||
nzPixelFormat_RGBA4, // 1*nzUInt16
|
nzPixelFormat_BGRA8, // 4*nzUInt8
|
||||||
nzPixelFormat_RGB5A1, // 1*nzUInt16
|
nzPixelFormat_DXT1,
|
||||||
nzPixelFormat_RGB8, // 3*nzUInt8
|
nzPixelFormat_DXT3,
|
||||||
nzPixelFormat_RGBA8, // 4*nzUInt8
|
nzPixelFormat_DXT5,
|
||||||
/*
|
nzPixelFormat_L8, // 1*nzUInt8
|
||||||
nzPixelFormat_Depth16,
|
nzPixelFormat_LA8, // 2*nzUInt8
|
||||||
nzPixelFormat_Depth24,
|
/*
|
||||||
nzPixelFormat_Depth24Stencil8,
|
nzPixelFormat_RGB16F,
|
||||||
nzPixelFormat_Depth32,
|
nzPixelFormat_RGB16I, // 4*nzUInt16
|
||||||
nzPixelFormat_Stencil1,
|
nzPixelFormat_RGB32F,
|
||||||
nzPixelFormat_Stencil4,
|
nzPixelFormat_RGB32I, // 4*nzUInt32
|
||||||
nzPixelFormat_Stencil8,
|
nzPixelFormat_RGBA16F,
|
||||||
nzPixelFormat_Stencil16,
|
nzPixelFormat_RGBA16I, // 4*nzUInt16
|
||||||
*/
|
nzPixelFormat_RGBA32F,
|
||||||
|
nzPixelFormat_RGBA32I, // 4*nzUInt32
|
||||||
nzPixelFormat_Max = nzPixelFormat_RGBA8
|
*/
|
||||||
};
|
nzPixelFormat_RGBA4, // 1*nzUInt16
|
||||||
|
nzPixelFormat_RGB5A1, // 1*nzUInt16
|
||||||
enum nzPixelFlipping
|
nzPixelFormat_RGB8, // 3*nzUInt8
|
||||||
{
|
nzPixelFormat_RGBA8, // 4*nzUInt8
|
||||||
nzPixelFlipping_Horizontally,
|
nzPixelFormat_Depth16,
|
||||||
nzPixelFlipping_Vertically,
|
nzPixelFormat_Depth24,
|
||||||
|
nzPixelFormat_Depth24Stencil8,
|
||||||
nzPixelFlipping_Max = nzPixelFlipping_Vertically
|
nzPixelFormat_Depth32,
|
||||||
};
|
nzPixelFormat_Stencil1,
|
||||||
|
nzPixelFormat_Stencil4,
|
||||||
enum nzPrimitiveType
|
nzPixelFormat_Stencil8,
|
||||||
{
|
nzPixelFormat_Stencil16,
|
||||||
nzPrimitiveType_LineList,
|
|
||||||
nzPrimitiveType_LineStrip,
|
nzPixelFormat_Max = nzPixelFormat_Stencil16
|
||||||
nzPrimitiveType_PointList,
|
};
|
||||||
nzPrimitiveType_TriangleList,
|
|
||||||
nzPrimitiveType_TriangleStrip,
|
enum nzPixelFormatType
|
||||||
nzPrimitiveType_TriangleFan
|
{
|
||||||
};
|
nzPixelFormatType_Undefined = -1,
|
||||||
|
|
||||||
enum nzWindowCursor
|
nzPixelFormatType_Color,
|
||||||
{
|
nzPixelFormatType_Depth,
|
||||||
nzWindowCursor_None,
|
nzPixelFormatType_DepthStencil,
|
||||||
nzWindowCursor_Default,
|
nzPixelFormatType_Stencil,
|
||||||
|
|
||||||
nzWindowCursor_Crosshair,
|
nzPixelFormatType_Max = nzPixelFormatType_Stencil
|
||||||
nzWindowCursor_Hand,
|
};
|
||||||
nzWindowCursor_Help,
|
|
||||||
nzWindowCursor_Move,
|
enum nzPixelFlipping
|
||||||
nzWindowCursor_Pointer,
|
{
|
||||||
nzWindowCursor_Progress,
|
nzPixelFlipping_Horizontally,
|
||||||
nzWindowCursor_ResizeE,
|
nzPixelFlipping_Vertically,
|
||||||
nzWindowCursor_ResizeN,
|
|
||||||
nzWindowCursor_ResizeNE,
|
nzPixelFlipping_Max = nzPixelFlipping_Vertically
|
||||||
nzWindowCursor_ResizeNW,
|
};
|
||||||
nzWindowCursor_ResizeS,
|
|
||||||
nzWindowCursor_ResizeSE,
|
enum nzPrimitiveType
|
||||||
nzWindowCursor_ResizeSW,
|
{
|
||||||
nzWindowCursor_ResizeW,
|
nzPrimitiveType_LineList,
|
||||||
nzWindowCursor_Text,
|
nzPrimitiveType_LineStrip,
|
||||||
nzWindowCursor_Wait
|
nzPrimitiveType_PointList,
|
||||||
};
|
nzPrimitiveType_TriangleList,
|
||||||
|
nzPrimitiveType_TriangleStrip,
|
||||||
enum nzWindowStyle
|
nzPrimitiveType_TriangleFan,
|
||||||
{
|
|
||||||
nzWindowStyle_None = 0x0,
|
nzPrimitiveType_Max = nzPrimitiveType_TriangleFan
|
||||||
nzWindowStyle_Fullscreen = 0x1,
|
};
|
||||||
|
|
||||||
nzWindowStyle_Closable = 0x2,
|
enum nzWindowCursor
|
||||||
nzWindowStyle_Resizable = 0x4,
|
{
|
||||||
nzWindowStyle_Titlebar = 0x4,
|
nzWindowCursor_None,
|
||||||
|
nzWindowCursor_Default,
|
||||||
nzWindowStyle_Default = nzWindowStyle_Closable | nzWindowStyle_Resizable | nzWindowStyle_Titlebar
|
|
||||||
};
|
nzWindowCursor_Crosshair,
|
||||||
|
nzWindowCursor_Hand,
|
||||||
#endif // NAZARA_ENUMS_UTILITY_HPP
|
nzWindowCursor_Help,
|
||||||
|
nzWindowCursor_Move,
|
||||||
|
nzWindowCursor_Pointer,
|
||||||
|
nzWindowCursor_Progress,
|
||||||
|
nzWindowCursor_ResizeE,
|
||||||
|
nzWindowCursor_ResizeN,
|
||||||
|
nzWindowCursor_ResizeNE,
|
||||||
|
nzWindowCursor_ResizeNW,
|
||||||
|
nzWindowCursor_ResizeS,
|
||||||
|
nzWindowCursor_ResizeSE,
|
||||||
|
nzWindowCursor_ResizeSW,
|
||||||
|
nzWindowCursor_ResizeW,
|
||||||
|
nzWindowCursor_Text,
|
||||||
|
nzWindowCursor_Wait,
|
||||||
|
|
||||||
|
nzWindowCursor_Max = nzWindowCursor_Wait
|
||||||
|
};
|
||||||
|
|
||||||
|
enum nzWindowStyleFlags
|
||||||
|
{
|
||||||
|
nzWindowStyle_None = 0x0,
|
||||||
|
nzWindowStyle_Fullscreen = 0x1,
|
||||||
|
|
||||||
|
nzWindowStyle_Closable = 0x2,
|
||||||
|
nzWindowStyle_Resizable = 0x4,
|
||||||
|
nzWindowStyle_Titlebar = 0x4,
|
||||||
|
|
||||||
|
nzWindowStyle_Default = nzWindowStyle_Closable | nzWindowStyle_Resizable | nzWindowStyle_Titlebar
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // NAZARA_ENUMS_UTILITY_HPP
|
||||||
|
|
|
||||||
|
|
@ -1,93 +1,98 @@
|
||||||
// Copyright (C) 2012 Jérôme Leclercq
|
// Copyright (C) 2012 Jérôme Leclercq
|
||||||
// This file is part of the "Nazara Engine - Utility module"
|
// This file is part of the "Nazara Engine - Utility module"
|
||||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#ifndef NAZARA_MESH_HPP
|
#ifndef NAZARA_MESH_HPP
|
||||||
#define NAZARA_MESH_HPP
|
#define NAZARA_MESH_HPP
|
||||||
|
|
||||||
#include <Nazara/Prerequesites.hpp>
|
#include <Nazara/Prerequesites.hpp>
|
||||||
#include <Nazara/Core/InputStream.hpp>
|
#include <Nazara/Core/InputStream.hpp>
|
||||||
#include <Nazara/Core/Resource.hpp>
|
#include <Nazara/Core/Resource.hpp>
|
||||||
#include <Nazara/Core/ResourceLoader.hpp>
|
#include <Nazara/Core/ResourceListener.hpp>
|
||||||
#include <Nazara/Core/String.hpp>
|
#include <Nazara/Core/ResourceLoader.hpp>
|
||||||
#include <Nazara/Utility/Animation.hpp>
|
#include <Nazara/Core/String.hpp>
|
||||||
#include <Nazara/Utility/AxisAlignedBox.hpp>
|
#include <Nazara/Utility/Animation.hpp>
|
||||||
#include <Nazara/Utility/SubMesh.hpp>
|
#include <Nazara/Utility/AxisAlignedBox.hpp>
|
||||||
|
#include <Nazara/Utility/SubMesh.hpp>
|
||||||
class NzVertexDeclaration;
|
|
||||||
|
class NzVertexDeclaration;
|
||||||
struct NzMeshParams
|
|
||||||
{
|
struct NzMeshParams
|
||||||
NzAnimationParams animation;
|
{
|
||||||
//const NzVertexDeclaration* declaration = nullptr;
|
NzAnimationParams animation;
|
||||||
nzBufferStorage storage = nzBufferStorage_Hardware;
|
//const NzVertexDeclaration* declaration = nullptr;
|
||||||
bool loadAnimations = true;
|
nzBufferStorage storage = nzBufferStorage_Hardware;
|
||||||
|
bool loadAnimations = true;
|
||||||
bool IsValid() const;
|
|
||||||
};
|
bool IsValid() const;
|
||||||
|
};
|
||||||
class NzMesh;
|
|
||||||
|
class NzMesh;
|
||||||
using NzMeshLoader = NzResourceLoader<NzMesh, NzMeshParams>;
|
|
||||||
|
using NzMeshLoader = NzResourceLoader<NzMesh, NzMeshParams>;
|
||||||
struct NzMeshImpl;
|
|
||||||
|
struct NzMeshImpl;
|
||||||
class NAZARA_API NzMesh : public NzResource
|
|
||||||
{
|
class NAZARA_API NzMesh : public NzResource, NzResourceListener
|
||||||
friend NzMeshLoader;
|
{
|
||||||
|
friend NzMeshLoader;
|
||||||
public:
|
|
||||||
NzMesh() = default;
|
public:
|
||||||
~NzMesh();
|
NzMesh() = default;
|
||||||
|
~NzMesh();
|
||||||
unsigned int AddSkin(const NzString& skin, bool setDefault = false);
|
|
||||||
nzUInt8 AddSubMesh(NzSubMesh* subMesh);
|
bool AddSkin(const NzString& skin, bool setDefault = false);
|
||||||
nzUInt8 AddSubMesh(const NzString& identifier, NzSubMesh* subMesh);
|
bool AddSubMesh(NzSubMesh* subMesh);
|
||||||
|
bool AddSubMesh(const NzString& identifier, NzSubMesh* subMesh);
|
||||||
void Animate(unsigned int frameA, unsigned int frameB, float interpolation);
|
|
||||||
|
void Animate(unsigned int frameA, unsigned int frameB, float interpolation);
|
||||||
bool Create(nzAnimationType type);
|
|
||||||
void Destroy();
|
bool Create(nzAnimationType type);
|
||||||
|
void Destroy();
|
||||||
const NzAxisAlignedBox& GetAABB() const;
|
|
||||||
const NzAnimation* GetAnimation() const;
|
const NzAxisAlignedBox& GetAABB() const;
|
||||||
nzAnimationType GetAnimationType() const;
|
const NzAnimation* GetAnimation() const;
|
||||||
unsigned int GetFrameCount() const;
|
nzAnimationType GetAnimationType() const;
|
||||||
NzString GetSkin(unsigned int index = 0) const;
|
unsigned int GetFrameCount() const;
|
||||||
unsigned int GetSkinCount() const;
|
NzString GetSkin(unsigned int index = 0) const;
|
||||||
NzSubMesh* GetSubMesh(const NzString& identifier);
|
unsigned int GetSkinCount() const;
|
||||||
NzSubMesh* GetSubMesh(nzUInt8 index);
|
NzSubMesh* GetSubMesh(const NzString& identifier);
|
||||||
const NzSubMesh* GetSubMesh(const NzString& identifier) const;
|
NzSubMesh* GetSubMesh(unsigned int index);
|
||||||
const NzSubMesh* GetSubMesh(nzUInt8 index) const;
|
const NzSubMesh* GetSubMesh(const NzString& identifier) const;
|
||||||
nzUInt8 GetSubMeshCount() const;
|
const NzSubMesh* GetSubMesh(unsigned int index) const;
|
||||||
unsigned int GetVertexCount() const;
|
unsigned int GetSubMeshCount() const;
|
||||||
|
int GetSubMeshIndex(const NzString& identifier) const;
|
||||||
bool HasAnimation() const;
|
unsigned int GetVertexCount() const;
|
||||||
bool HasSkin(unsigned int index = 0) const;
|
|
||||||
bool HasSubMesh(const NzString& identifier) const;
|
bool HasAnimation() const;
|
||||||
bool HasSubMesh(nzUInt8 index = 0) const;
|
bool HasSkin(unsigned int index = 0) const;
|
||||||
|
bool HasSubMesh(const NzString& identifier) const;
|
||||||
void InvalidateAABB() const;
|
bool HasSubMesh(unsigned int index = 0) const;
|
||||||
|
|
||||||
bool IsAnimable() const;
|
void InvalidateAABB() const;
|
||||||
bool IsValid() const;
|
|
||||||
|
bool IsAnimable() const;
|
||||||
bool LoadFromFile(const NzString& filePath, const NzMeshParams& params = NzMeshParams());
|
bool IsValid() const;
|
||||||
bool LoadFromMemory(const void* data, std::size_t size, const NzMeshParams& params = NzMeshParams());
|
|
||||||
bool LoadFromStream(NzInputStream& stream, const NzMeshParams& params = NzMeshParams());
|
bool LoadFromFile(const NzString& filePath, const NzMeshParams& params = NzMeshParams());
|
||||||
|
bool LoadFromMemory(const void* data, std::size_t size, const NzMeshParams& params = NzMeshParams());
|
||||||
void RemoveSkin(unsigned int index = 0);
|
bool LoadFromStream(NzInputStream& stream, const NzMeshParams& params = NzMeshParams());
|
||||||
void RemoveSubMesh(const NzString& identifier);
|
|
||||||
void RemoveSubMesh(nzUInt8 index = 0);
|
void RemoveSkin(unsigned int index = 0);
|
||||||
|
void RemoveSubMesh(const NzString& identifier);
|
||||||
bool SetAnimation(const NzAnimation* animation);
|
void RemoveSubMesh(unsigned int index = 0);
|
||||||
|
|
||||||
private:
|
bool SetAnimation(const NzAnimation* animation);
|
||||||
NzMeshImpl* m_impl = nullptr;
|
|
||||||
|
private:
|
||||||
static NzMeshLoader::LoaderList s_loaders;
|
void OnResourceCreated(const NzResource* resource, int index) override;
|
||||||
};
|
void OnResourceReleased(const NzResource* resource, int index) override;
|
||||||
|
|
||||||
#endif // NAZARA_MESH_HPP
|
NzMeshImpl* m_impl = nullptr;
|
||||||
|
|
||||||
|
static NzMeshLoader::LoaderList s_loaders;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // NAZARA_MESH_HPP
|
||||||
|
|
|
||||||
|
|
@ -1,53 +1,54 @@
|
||||||
// Copyright (C) 2012 Jérôme Leclercq
|
// Copyright (C) 2012 Jérôme Leclercq
|
||||||
// This file is part of the "Nazara Engine - Utility module"
|
// This file is part of the "Nazara Engine - Utility module"
|
||||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#ifndef NAZARA_PIXELFORMAT_HPP
|
#ifndef NAZARA_PIXELFORMAT_HPP
|
||||||
#define NAZARA_PIXELFORMAT_HPP
|
#define NAZARA_PIXELFORMAT_HPP
|
||||||
|
|
||||||
#include <Nazara/Prerequesites.hpp>
|
#include <Nazara/Prerequesites.hpp>
|
||||||
#include <Nazara/Core/String.hpp>
|
#include <Nazara/Core/String.hpp>
|
||||||
#include <Nazara/Utility/Enums.hpp>
|
#include <Nazara/Utility/Enums.hpp>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
class NzUtility;
|
class NzUtility;
|
||||||
|
|
||||||
class NzPixelFormat
|
class NzPixelFormat
|
||||||
{
|
{
|
||||||
friend class NzUtility;
|
friend class NzUtility;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
using ConvertFunction = nzUInt8* (*)(const nzUInt8* start, const nzUInt8* end, nzUInt8* dst);
|
using ConvertFunction = nzUInt8* (*)(const nzUInt8* start, const nzUInt8* end, nzUInt8* dst);
|
||||||
using FlipFunction = void (*)(unsigned int width, unsigned int height, unsigned int depth, const nzUInt8* src, nzUInt8* dst);
|
using FlipFunction = void (*)(unsigned int width, unsigned int height, unsigned int depth, const nzUInt8* src, nzUInt8* dst);
|
||||||
|
|
||||||
static bool Convert(nzPixelFormat srcFormat, nzPixelFormat dstFormat, const void* src, void* dst);
|
static bool Convert(nzPixelFormat srcFormat, nzPixelFormat dstFormat, const void* src, void* dst);
|
||||||
static bool Convert(nzPixelFormat srcFormat, nzPixelFormat dstFormat, const void* start, const void* end, void* dst);
|
static bool Convert(nzPixelFormat srcFormat, nzPixelFormat dstFormat, const void* start, const void* end, void* dst);
|
||||||
|
|
||||||
static bool Flip(nzPixelFlipping flipping, nzPixelFormat format, unsigned int width, unsigned int height, unsigned int depth, const void* src, void* dst);
|
static bool Flip(nzPixelFlipping flipping, nzPixelFormat format, unsigned int width, unsigned int height, unsigned int depth, const void* src, void* dst);
|
||||||
|
|
||||||
static nzUInt8 GetBPP(nzPixelFormat format);
|
static nzUInt8 GetBPP(nzPixelFormat format);
|
||||||
|
static nzPixelFormatType GetType(nzPixelFormat format);
|
||||||
static bool HasAlpha(nzPixelFormat format);
|
|
||||||
|
static bool HasAlpha(nzPixelFormat format);
|
||||||
static bool IsCompressed(nzPixelFormat format);
|
|
||||||
static bool IsConversionSupported(nzPixelFormat srcFormat, nzPixelFormat dstFormat);
|
static bool IsCompressed(nzPixelFormat format);
|
||||||
static bool IsValid(nzPixelFormat format);
|
static bool IsConversionSupported(nzPixelFormat srcFormat, nzPixelFormat dstFormat);
|
||||||
|
static bool IsValid(nzPixelFormat format);
|
||||||
static void SetConvertFunction(nzPixelFormat srcFormat, nzPixelFormat dstFormat, ConvertFunction func);
|
|
||||||
static void SetFlipFunction(nzPixelFlipping flipping, nzPixelFormat format, FlipFunction func);
|
static void SetConvertFunction(nzPixelFormat srcFormat, nzPixelFormat dstFormat, ConvertFunction func);
|
||||||
|
static void SetFlipFunction(nzPixelFlipping flipping, nzPixelFormat format, FlipFunction func);
|
||||||
static NzString ToString(nzPixelFormat format);
|
|
||||||
|
static NzString ToString(nzPixelFormat format);
|
||||||
private:
|
|
||||||
static bool Initialize();
|
private:
|
||||||
static void Uninitialize();
|
static bool Initialize();
|
||||||
|
static void Uninitialize();
|
||||||
static NAZARA_API ConvertFunction s_convertFunctions[nzPixelFormat_Max+1][nzPixelFormat_Max+1];
|
|
||||||
static NAZARA_API std::map<nzPixelFormat, FlipFunction> s_flipFunctions[nzPixelFlipping_Max+1];
|
static NAZARA_API ConvertFunction s_convertFunctions[nzPixelFormat_Max+1][nzPixelFormat_Max+1];
|
||||||
};
|
static NAZARA_API std::map<nzPixelFormat, FlipFunction> s_flipFunctions[nzPixelFlipping_Max+1];
|
||||||
|
};
|
||||||
#include <Nazara/Utility/PixelFormat.inl>
|
|
||||||
|
#include <Nazara/Utility/PixelFormat.inl>
|
||||||
#endif // NAZARA_PIXELFORMAT_HPP
|
|
||||||
|
#endif // NAZARA_PIXELFORMAT_HPP
|
||||||
|
|
|
||||||
|
|
@ -1,371 +1,487 @@
|
||||||
// Copyright (C) 2012 Jérôme Leclercq
|
// Copyright (C) 2012 Jérôme Leclercq
|
||||||
// This file is part of the "Nazara Engine - Utility module"
|
// This file is part of the "Nazara Engine - Utility module"
|
||||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||||
|
|
||||||
#include <Nazara/Core/Error.hpp>
|
#include <Nazara/Core/Error.hpp>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <Nazara/Utility/Debug.hpp>
|
#include <Nazara/Utility/Debug.hpp>
|
||||||
|
|
||||||
inline bool NzPixelFormat::Convert(nzPixelFormat srcFormat, nzPixelFormat dstFormat, const void* src, void* dst)
|
inline bool NzPixelFormat::Convert(nzPixelFormat srcFormat, nzPixelFormat dstFormat, const void* src, void* dst)
|
||||||
{
|
{
|
||||||
if (srcFormat == dstFormat)
|
if (srcFormat == dstFormat)
|
||||||
{
|
{
|
||||||
std::memcpy(dst, src, GetBPP(srcFormat));
|
std::memcpy(dst, src, GetBPP(srcFormat));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if NAZARA_UTILITY_SAFE
|
#if NAZARA_UTILITY_SAFE
|
||||||
if (IsCompressed(srcFormat))
|
if (IsCompressed(srcFormat))
|
||||||
{
|
{
|
||||||
NazaraError("Cannot convert single pixel from compressed format");
|
NazaraError("Cannot convert single pixel from compressed format");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IsCompressed(dstFormat))
|
if (IsCompressed(dstFormat))
|
||||||
{
|
{
|
||||||
NazaraError("Cannot convert single pixel to compressed format");
|
NazaraError("Cannot convert single pixel to compressed format");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
ConvertFunction func = s_convertFunctions[srcFormat][dstFormat];
|
ConvertFunction func = s_convertFunctions[srcFormat][dstFormat];
|
||||||
if (!func)
|
if (!func)
|
||||||
{
|
{
|
||||||
NazaraError("Pixel format conversion from " + ToString(srcFormat) + " to " + ToString(dstFormat) + " is not supported");
|
NazaraError("Pixel format conversion from " + ToString(srcFormat) + " to " + ToString(dstFormat) + " is not supported");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!func(reinterpret_cast<const nzUInt8*>(src), reinterpret_cast<const nzUInt8*>(src) + GetBPP(srcFormat), reinterpret_cast<nzUInt8*>(dst)))
|
if (!func(reinterpret_cast<const nzUInt8*>(src), reinterpret_cast<const nzUInt8*>(src) + GetBPP(srcFormat), reinterpret_cast<nzUInt8*>(dst)))
|
||||||
{
|
{
|
||||||
NazaraError("Pixel format conversion from " + ToString(srcFormat) + " to " + ToString(dstFormat) + " failed");
|
NazaraError("Pixel format conversion from " + ToString(srcFormat) + " to " + ToString(dstFormat) + " failed");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool NzPixelFormat::Convert(nzPixelFormat srcFormat, nzPixelFormat dstFormat, const void* start, const void* end, void* dst)
|
inline bool NzPixelFormat::Convert(nzPixelFormat srcFormat, nzPixelFormat dstFormat, const void* start, const void* end, void* dst)
|
||||||
{
|
{
|
||||||
if (srcFormat == dstFormat)
|
if (srcFormat == dstFormat)
|
||||||
{
|
{
|
||||||
std::memcpy(dst, start, reinterpret_cast<const nzUInt8*>(end)-reinterpret_cast<const nzUInt8*>(start));
|
std::memcpy(dst, start, reinterpret_cast<const nzUInt8*>(end)-reinterpret_cast<const nzUInt8*>(start));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
ConvertFunction func = s_convertFunctions[srcFormat][dstFormat];
|
ConvertFunction func = s_convertFunctions[srcFormat][dstFormat];
|
||||||
if (!func)
|
if (!func)
|
||||||
{
|
{
|
||||||
NazaraError("Pixel format conversion from " + ToString(srcFormat) + " to " + ToString(dstFormat) + " is not supported");
|
NazaraError("Pixel format conversion from " + ToString(srcFormat) + " to " + ToString(dstFormat) + " is not supported");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!func(reinterpret_cast<const nzUInt8*>(start), reinterpret_cast<const nzUInt8*>(end), reinterpret_cast<nzUInt8*>(dst)))
|
if (!func(reinterpret_cast<const nzUInt8*>(start), reinterpret_cast<const nzUInt8*>(end), reinterpret_cast<nzUInt8*>(dst)))
|
||||||
{
|
{
|
||||||
NazaraError("Pixel format conversion from " + ToString(srcFormat) + " to " + ToString(dstFormat) + " failed");
|
NazaraError("Pixel format conversion from " + ToString(srcFormat) + " to " + ToString(dstFormat) + " failed");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool NzPixelFormat::Flip(nzPixelFlipping flipping, nzPixelFormat format, unsigned int width, unsigned int height, unsigned int depth, const void* src, void* dst)
|
inline bool NzPixelFormat::Flip(nzPixelFlipping flipping, nzPixelFormat format, unsigned int width, unsigned int height, unsigned int depth, const void* src, void* dst)
|
||||||
{
|
{
|
||||||
#if NAZARA_UTILITY_SAFE
|
#if NAZARA_UTILITY_SAFE
|
||||||
if (!IsValid(format))
|
if (!IsValid(format))
|
||||||
{
|
{
|
||||||
NazaraError("Invalid pixel format");
|
NazaraError("Invalid pixel format");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
auto it = s_flipFunctions[flipping].find(format);
|
auto it = s_flipFunctions[flipping].find(format);
|
||||||
if (it != s_flipFunctions[flipping].end())
|
if (it != s_flipFunctions[flipping].end())
|
||||||
it->second(width, height, depth, reinterpret_cast<const nzUInt8*>(src), reinterpret_cast<nzUInt8*>(dst));
|
it->second(width, height, depth, reinterpret_cast<const nzUInt8*>(src), reinterpret_cast<nzUInt8*>(dst));
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Flipping générique
|
// Flipping générique
|
||||||
|
|
||||||
#if NAZARA_UTILITY_SAFE
|
#if NAZARA_UTILITY_SAFE
|
||||||
if (IsCompressed(format))
|
if (IsCompressed(format))
|
||||||
{
|
{
|
||||||
NazaraError("No function to flip compressed format");
|
NazaraError("No function to flip compressed format");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
nzUInt8 bpp = GetBPP(format);
|
nzUInt8 bpp = GetBPP(format);
|
||||||
unsigned int lineStride = width*bpp;
|
unsigned int lineStride = width*bpp;
|
||||||
switch (flipping)
|
switch (flipping)
|
||||||
{
|
{
|
||||||
case nzPixelFlipping_Horizontally:
|
case nzPixelFlipping_Horizontally:
|
||||||
{
|
{
|
||||||
if (src == dst)
|
if (src == dst)
|
||||||
{
|
{
|
||||||
for (unsigned int z = 0; z < depth; ++z)
|
for (unsigned int z = 0; z < depth; ++z)
|
||||||
{
|
{
|
||||||
nzUInt8* ptr = reinterpret_cast<nzUInt8*>(dst) + width*height*z;
|
nzUInt8* ptr = reinterpret_cast<nzUInt8*>(dst) + width*height*z;
|
||||||
for (unsigned int y = 0; y < height; ++y)
|
for (unsigned int y = 0; y < height; ++y)
|
||||||
{
|
{
|
||||||
for (unsigned int x = 0; x < width/2; ++x)
|
for (unsigned int x = 0; x < width/2; ++x)
|
||||||
std::swap_ranges(&ptr[x*bpp], &ptr[(x+1)*bpp], &ptr[(width-x)*bpp]);
|
std::swap_ranges(&ptr[x*bpp], &ptr[(x+1)*bpp], &ptr[(width-x)*bpp]);
|
||||||
|
|
||||||
ptr += lineStride;
|
ptr += lineStride;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for (unsigned int z = 0; z < depth; ++z)
|
for (unsigned int z = 0; z < depth; ++z)
|
||||||
{
|
{
|
||||||
nzUInt8* ptr = reinterpret_cast<nzUInt8*>(dst) + width*height*z;
|
nzUInt8* ptr = reinterpret_cast<nzUInt8*>(dst) + width*height*z;
|
||||||
for (unsigned int y = 0; y < height; ++y)
|
for (unsigned int y = 0; y < height; ++y)
|
||||||
{
|
{
|
||||||
for (unsigned int x = 0; x < width; ++x)
|
for (unsigned int x = 0; x < width; ++x)
|
||||||
std::memcpy(&ptr[x*bpp], &ptr[(width-x)*bpp], bpp);
|
std::memcpy(&ptr[x*bpp], &ptr[(width-x)*bpp], bpp);
|
||||||
|
|
||||||
ptr += lineStride;
|
ptr += lineStride;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case nzPixelFlipping_Vertically:
|
case nzPixelFlipping_Vertically:
|
||||||
{
|
{
|
||||||
if (src == dst)
|
if (src == dst)
|
||||||
{
|
{
|
||||||
for (unsigned int z = 0; z < depth; ++z)
|
for (unsigned int z = 0; z < depth; ++z)
|
||||||
{
|
{
|
||||||
nzUInt8* ptr = reinterpret_cast<nzUInt8*>(dst) + width*height*z;
|
nzUInt8* ptr = reinterpret_cast<nzUInt8*>(dst) + width*height*z;
|
||||||
for (unsigned int y = 0; y < height/2; ++y)
|
for (unsigned int y = 0; y < height/2; ++y)
|
||||||
std::swap_ranges(&ptr[y*lineStride], &ptr[(y+1)*lineStride-1], &ptr[(height-y-1)*lineStride]);
|
std::swap_ranges(&ptr[y*lineStride], &ptr[(y+1)*lineStride-1], &ptr[(height-y-1)*lineStride]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for (unsigned int z = 0; z < depth; ++z)
|
for (unsigned int z = 0; z < depth; ++z)
|
||||||
{
|
{
|
||||||
const nzUInt8* srcPtr = reinterpret_cast<const nzUInt8*>(src);
|
const nzUInt8* srcPtr = reinterpret_cast<const nzUInt8*>(src);
|
||||||
nzUInt8* dstPtr = reinterpret_cast<nzUInt8*>(dst) + (width-1)*height*depth*bpp;
|
nzUInt8* dstPtr = reinterpret_cast<nzUInt8*>(dst) + (width-1)*height*depth*bpp;
|
||||||
for (unsigned int y = 0; y < height; ++y)
|
for (unsigned int y = 0; y < height; ++y)
|
||||||
{
|
{
|
||||||
std::memcpy(dstPtr, srcPtr, lineStride);
|
std::memcpy(dstPtr, srcPtr, lineStride);
|
||||||
|
|
||||||
srcPtr += lineStride;
|
srcPtr += lineStride;
|
||||||
dstPtr -= lineStride;
|
dstPtr -= lineStride;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline nzUInt8 NzPixelFormat::GetBPP(nzPixelFormat format)
|
inline nzUInt8 NzPixelFormat::GetBPP(nzPixelFormat format)
|
||||||
{
|
{
|
||||||
switch (format)
|
switch (format)
|
||||||
{
|
{
|
||||||
case nzPixelFormat_BGR8:
|
case nzPixelFormat_BGR8:
|
||||||
return 3;
|
return 3;
|
||||||
|
|
||||||
case nzPixelFormat_BGRA8:
|
case nzPixelFormat_BGRA8:
|
||||||
return 4;
|
return 4;
|
||||||
|
|
||||||
case nzPixelFormat_DXT1:
|
case nzPixelFormat_DXT1:
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
case nzPixelFormat_DXT3:
|
case nzPixelFormat_DXT3:
|
||||||
return 2;
|
return 2;
|
||||||
|
|
||||||
case nzPixelFormat_DXT5:
|
case nzPixelFormat_DXT5:
|
||||||
return 2;
|
return 2;
|
||||||
|
|
||||||
case nzPixelFormat_L8:
|
case nzPixelFormat_L8:
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
case nzPixelFormat_LA8:
|
case nzPixelFormat_LA8:
|
||||||
return 2;
|
return 2;
|
||||||
/*
|
/*
|
||||||
case nzPixelFormat_RGB16F:
|
case nzPixelFormat_RGB16F:
|
||||||
return 6;
|
return 6;
|
||||||
|
|
||||||
case nzPixelFormat_RGB16I:
|
case nzPixelFormat_RGB16I:
|
||||||
return 6;
|
return 6;
|
||||||
|
|
||||||
case nzPixelFormat_RGB32F:
|
case nzPixelFormat_RGB32F:
|
||||||
return 12;
|
return 12;
|
||||||
|
|
||||||
case nzPixelFormat_RGB32I:
|
case nzPixelFormat_RGB32I:
|
||||||
return 12;
|
return 12;
|
||||||
|
|
||||||
case nzPixelFormat_RGBA16F:
|
case nzPixelFormat_RGBA16F:
|
||||||
return 8;
|
return 8;
|
||||||
|
|
||||||
case nzPixelFormat_RGBA16I:
|
case nzPixelFormat_RGBA16I:
|
||||||
return 8;
|
return 8;
|
||||||
|
|
||||||
case nzPixelFormat_RGBA32F:
|
case nzPixelFormat_RGBA32F:
|
||||||
return 16;
|
return 16;
|
||||||
|
|
||||||
case nzPixelFormat_RGBA32I:
|
case nzPixelFormat_RGBA32I:
|
||||||
return 16;
|
return 16;
|
||||||
*/
|
*/
|
||||||
case nzPixelFormat_RGBA4:
|
case nzPixelFormat_RGBA4:
|
||||||
return 2;
|
return 2;
|
||||||
|
|
||||||
case nzPixelFormat_RGB5A1:
|
case nzPixelFormat_RGB5A1:
|
||||||
return 2;
|
return 2;
|
||||||
|
|
||||||
case nzPixelFormat_RGB8:
|
case nzPixelFormat_RGB8:
|
||||||
return 3;
|
return 3;
|
||||||
|
|
||||||
case nzPixelFormat_RGBA8:
|
case nzPixelFormat_RGBA8:
|
||||||
return 4;
|
return 4;
|
||||||
|
|
||||||
case nzPixelFormat_Undefined:
|
case nzPixelFormat_Depth16:
|
||||||
NazaraError("Invalid pixel format");
|
return 2;
|
||||||
return 0;
|
|
||||||
}
|
case nzPixelFormat_Depth24:
|
||||||
|
return 3;
|
||||||
NazaraInternalError("Invalid pixel format");
|
|
||||||
|
case nzPixelFormat_Depth24Stencil8:
|
||||||
return 0;
|
return 4;
|
||||||
}
|
|
||||||
|
case nzPixelFormat_Depth32:
|
||||||
inline bool NzPixelFormat::HasAlpha(nzPixelFormat format)
|
return 4;
|
||||||
{
|
|
||||||
switch (format)
|
case nzPixelFormat_Stencil1:
|
||||||
{
|
NazaraWarning("This format uses less than one byte per pixel");
|
||||||
case nzPixelFormat_BGRA8:
|
return 0;
|
||||||
case nzPixelFormat_DXT3:
|
|
||||||
case nzPixelFormat_DXT5:
|
case nzPixelFormat_Stencil4:
|
||||||
case nzPixelFormat_LA8:
|
NazaraWarning("This format uses less than one byte per pixel");
|
||||||
case nzPixelFormat_RGB5A1:
|
return 0;
|
||||||
case nzPixelFormat_RGBA4:
|
|
||||||
case nzPixelFormat_RGBA8:
|
case nzPixelFormat_Stencil8:
|
||||||
return true;
|
return 1;
|
||||||
|
|
||||||
case nzPixelFormat_BGR8:
|
case nzPixelFormat_Stencil16:
|
||||||
case nzPixelFormat_DXT1:
|
return 2;
|
||||||
case nzPixelFormat_L8:
|
|
||||||
case nzPixelFormat_RGB8:
|
case nzPixelFormat_Undefined:
|
||||||
return false;
|
break;
|
||||||
|
}
|
||||||
case nzPixelFormat_Undefined:
|
|
||||||
break;
|
NazaraError("Invalid pixel format");
|
||||||
}
|
return 0;
|
||||||
|
}
|
||||||
NazaraError("Invalid pixel format");
|
|
||||||
return false;
|
inline nzPixelFormatType NzPixelFormat::GetType(nzPixelFormat format)
|
||||||
}
|
{
|
||||||
|
switch (format)
|
||||||
inline bool NzPixelFormat::IsCompressed(nzPixelFormat format)
|
{
|
||||||
{
|
case nzPixelFormat_BGR8:
|
||||||
switch (format)
|
case nzPixelFormat_BGRA8:
|
||||||
{
|
case nzPixelFormat_DXT1:
|
||||||
case nzPixelFormat_DXT1:
|
case nzPixelFormat_DXT3:
|
||||||
case nzPixelFormat_DXT3:
|
case nzPixelFormat_DXT5:
|
||||||
case nzPixelFormat_DXT5:
|
case nzPixelFormat_L8:
|
||||||
return true;
|
case nzPixelFormat_LA8:
|
||||||
|
case nzPixelFormat_RGB5A1:
|
||||||
default:
|
case nzPixelFormat_RGB8:
|
||||||
return false;
|
case nzPixelFormat_RGBA4:
|
||||||
}
|
case nzPixelFormat_RGBA8:
|
||||||
}
|
return nzPixelFormatType_Color;
|
||||||
|
|
||||||
inline bool NzPixelFormat::IsConversionSupported(nzPixelFormat srcFormat, nzPixelFormat dstFormat)
|
case nzPixelFormat_Depth16:
|
||||||
{
|
case nzPixelFormat_Depth24:
|
||||||
if (srcFormat == dstFormat)
|
case nzPixelFormat_Depth32:
|
||||||
return true;
|
return nzPixelFormatType_Depth;
|
||||||
|
|
||||||
return s_convertFunctions[srcFormat][dstFormat] != nullptr;
|
case nzPixelFormat_Depth24Stencil8:
|
||||||
}
|
return nzPixelFormatType_DepthStencil;
|
||||||
|
|
||||||
inline bool NzPixelFormat::IsValid(nzPixelFormat format)
|
case nzPixelFormat_Stencil1:
|
||||||
{
|
case nzPixelFormat_Stencil4:
|
||||||
return format != nzPixelFormat_Undefined;
|
case nzPixelFormat_Stencil8:
|
||||||
}
|
case nzPixelFormat_Stencil16:
|
||||||
|
return nzPixelFormatType_Stencil;
|
||||||
inline void NzPixelFormat::SetConvertFunction(nzPixelFormat srcFormat, nzPixelFormat dstFormat, ConvertFunction func)
|
|
||||||
{
|
case nzPixelFormat_Undefined:
|
||||||
s_convertFunctions[srcFormat][dstFormat] = func;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void NzPixelFormat::SetFlipFunction(nzPixelFlipping flipping, nzPixelFormat format, FlipFunction func)
|
NazaraError("Invalid pixel format");
|
||||||
{
|
return nzPixelFormatType_Undefined;
|
||||||
s_flipFunctions[flipping][format] = func;
|
}
|
||||||
}
|
|
||||||
|
inline bool NzPixelFormat::HasAlpha(nzPixelFormat format)
|
||||||
inline NzString NzPixelFormat::ToString(nzPixelFormat format)
|
{
|
||||||
{
|
switch (format)
|
||||||
switch (format)
|
{
|
||||||
{
|
case nzPixelFormat_BGRA8:
|
||||||
case nzPixelFormat_BGR8:
|
case nzPixelFormat_DXT3:
|
||||||
return "BGR8";
|
case nzPixelFormat_DXT5:
|
||||||
|
case nzPixelFormat_LA8:
|
||||||
case nzPixelFormat_BGRA8:
|
case nzPixelFormat_RGB5A1:
|
||||||
return "BGRA8";
|
case nzPixelFormat_RGBA4:
|
||||||
|
case nzPixelFormat_RGBA8:
|
||||||
case nzPixelFormat_DXT1:
|
return true;
|
||||||
return "DXT1";
|
|
||||||
|
case nzPixelFormat_BGR8:
|
||||||
case nzPixelFormat_DXT3:
|
case nzPixelFormat_DXT1:
|
||||||
return "DXT3";
|
case nzPixelFormat_L8:
|
||||||
|
case nzPixelFormat_RGB8:
|
||||||
case nzPixelFormat_DXT5:
|
case nzPixelFormat_Depth16:
|
||||||
return "DXT5";
|
case nzPixelFormat_Depth24:
|
||||||
|
case nzPixelFormat_Depth24Stencil8:
|
||||||
case nzPixelFormat_L8:
|
case nzPixelFormat_Depth32:
|
||||||
return "L8";
|
case nzPixelFormat_Stencil1:
|
||||||
|
case nzPixelFormat_Stencil4:
|
||||||
case nzPixelFormat_LA8:
|
case nzPixelFormat_Stencil8:
|
||||||
return "LA8";
|
case nzPixelFormat_Stencil16:
|
||||||
/*
|
return false;
|
||||||
case nzPixelFormat_RGB16F:
|
|
||||||
return "RGB16F";
|
case nzPixelFormat_Undefined:
|
||||||
|
break;
|
||||||
case nzPixelFormat_RGB16I:
|
}
|
||||||
return "RGB16I";
|
|
||||||
|
NazaraError("Invalid pixel format");
|
||||||
case nzPixelFormat_RGB32F:
|
return false;
|
||||||
return "RGB32F";
|
}
|
||||||
|
|
||||||
case nzPixelFormat_RGB32I:
|
inline bool NzPixelFormat::IsCompressed(nzPixelFormat format)
|
||||||
return "RGB32I";
|
{
|
||||||
|
switch (format)
|
||||||
case nzPixelFormat_RGBA16F:
|
{
|
||||||
return "RGBA16F";
|
case nzPixelFormat_DXT1:
|
||||||
|
case nzPixelFormat_DXT3:
|
||||||
case nzPixelFormat_RGBA16I:
|
case nzPixelFormat_DXT5:
|
||||||
return "RGBA16I";
|
return true;
|
||||||
|
|
||||||
case nzPixelFormat_RGBA32F:
|
case nzPixelFormat_BGRA8:
|
||||||
return "RGBA32F";
|
case nzPixelFormat_LA8:
|
||||||
|
case nzPixelFormat_RGB5A1:
|
||||||
case nzPixelFormat_RGBA32I:
|
case nzPixelFormat_RGBA4:
|
||||||
return "RGBA32I";
|
case nzPixelFormat_RGBA8:
|
||||||
*/
|
case nzPixelFormat_BGR8:
|
||||||
case nzPixelFormat_RGBA4:
|
case nzPixelFormat_L8:
|
||||||
return "RGBA4";
|
case nzPixelFormat_RGB8:
|
||||||
|
case nzPixelFormat_Depth16:
|
||||||
case nzPixelFormat_RGB5A1:
|
case nzPixelFormat_Depth24:
|
||||||
return "RGB5A1";
|
case nzPixelFormat_Depth24Stencil8:
|
||||||
|
case nzPixelFormat_Depth32:
|
||||||
case nzPixelFormat_RGB8:
|
case nzPixelFormat_Stencil1:
|
||||||
return "RGB8";
|
case nzPixelFormat_Stencil4:
|
||||||
|
case nzPixelFormat_Stencil8:
|
||||||
case nzPixelFormat_RGBA8:
|
case nzPixelFormat_Stencil16:
|
||||||
return "RGBA8";
|
return false;
|
||||||
|
|
||||||
case nzPixelFormat_Undefined:
|
case nzPixelFormat_Undefined:
|
||||||
return "Undefined";
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
NazaraError("Invalid pixel format");
|
NazaraError("Invalid pixel format");
|
||||||
return "Invalid format";
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
#include <Nazara/Utility/DebugOff.hpp>
|
inline bool NzPixelFormat::IsConversionSupported(nzPixelFormat srcFormat, nzPixelFormat dstFormat)
|
||||||
|
{
|
||||||
|
if (srcFormat == dstFormat)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return s_convertFunctions[srcFormat][dstFormat] != nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool NzPixelFormat::IsValid(nzPixelFormat format)
|
||||||
|
{
|
||||||
|
return format != nzPixelFormat_Undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void NzPixelFormat::SetConvertFunction(nzPixelFormat srcFormat, nzPixelFormat dstFormat, ConvertFunction func)
|
||||||
|
{
|
||||||
|
s_convertFunctions[srcFormat][dstFormat] = func;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void NzPixelFormat::SetFlipFunction(nzPixelFlipping flipping, nzPixelFormat format, FlipFunction func)
|
||||||
|
{
|
||||||
|
s_flipFunctions[flipping][format] = func;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline NzString NzPixelFormat::ToString(nzPixelFormat format)
|
||||||
|
{
|
||||||
|
switch (format)
|
||||||
|
{
|
||||||
|
case nzPixelFormat_BGR8:
|
||||||
|
return "BGR8";
|
||||||
|
|
||||||
|
case nzPixelFormat_BGRA8:
|
||||||
|
return "BGRA8";
|
||||||
|
|
||||||
|
case nzPixelFormat_DXT1:
|
||||||
|
return "DXT1";
|
||||||
|
|
||||||
|
case nzPixelFormat_DXT3:
|
||||||
|
return "DXT3";
|
||||||
|
|
||||||
|
case nzPixelFormat_DXT5:
|
||||||
|
return "DXT5";
|
||||||
|
|
||||||
|
case nzPixelFormat_L8:
|
||||||
|
return "L8";
|
||||||
|
|
||||||
|
case nzPixelFormat_LA8:
|
||||||
|
return "LA8";
|
||||||
|
/*
|
||||||
|
case nzPixelFormat_RGB16F:
|
||||||
|
return "RGB16F";
|
||||||
|
|
||||||
|
case nzPixelFormat_RGB16I:
|
||||||
|
return "RGB16I";
|
||||||
|
|
||||||
|
case nzPixelFormat_RGB32F:
|
||||||
|
return "RGB32F";
|
||||||
|
|
||||||
|
case nzPixelFormat_RGB32I:
|
||||||
|
return "RGB32I";
|
||||||
|
|
||||||
|
case nzPixelFormat_RGBA16F:
|
||||||
|
return "RGBA16F";
|
||||||
|
|
||||||
|
case nzPixelFormat_RGBA16I:
|
||||||
|
return "RGBA16I";
|
||||||
|
|
||||||
|
case nzPixelFormat_RGBA32F:
|
||||||
|
return "RGBA32F";
|
||||||
|
|
||||||
|
case nzPixelFormat_RGBA32I:
|
||||||
|
return "RGBA32I";
|
||||||
|
*/
|
||||||
|
case nzPixelFormat_RGBA4:
|
||||||
|
return "RGBA4";
|
||||||
|
|
||||||
|
case nzPixelFormat_RGB5A1:
|
||||||
|
return "RGB5A1";
|
||||||
|
|
||||||
|
case nzPixelFormat_RGB8:
|
||||||
|
return "RGB8";
|
||||||
|
|
||||||
|
case nzPixelFormat_RGBA8:
|
||||||
|
return "RGBA8";
|
||||||
|
|
||||||
|
case nzPixelFormat_Depth16:
|
||||||
|
return "Depth16";
|
||||||
|
|
||||||
|
case nzPixelFormat_Depth24:
|
||||||
|
return "Depth24";
|
||||||
|
|
||||||
|
case nzPixelFormat_Depth24Stencil8:
|
||||||
|
return "Depth24Stencil8";
|
||||||
|
|
||||||
|
case nzPixelFormat_Depth32:
|
||||||
|
return "Depth32";
|
||||||
|
|
||||||
|
case nzPixelFormat_Stencil1:
|
||||||
|
return "Stencil1";
|
||||||
|
|
||||||
|
case nzPixelFormat_Stencil4:
|
||||||
|
return "Stencil4";
|
||||||
|
|
||||||
|
case nzPixelFormat_Stencil8:
|
||||||
|
return "Stencil8";
|
||||||
|
|
||||||
|
case nzPixelFormat_Stencil16:
|
||||||
|
return "Stencil16";
|
||||||
|
|
||||||
|
case nzPixelFormat_Undefined:
|
||||||
|
return "Undefined";
|
||||||
|
}
|
||||||
|
|
||||||
|
NazaraError("Invalid pixel format");
|
||||||
|
return "Invalid format";
|
||||||
|
}
|
||||||
|
|
||||||
|
#include <Nazara/Utility/DebugOff.hpp>
|
||||||
|
|
|
||||||
|
|
@ -1,49 +1,51 @@
|
||||||
// Copyright (C) 2012 Jérôme Leclercq
|
// Copyright (C) 2012 Jérôme Leclercq
|
||||||
// This file is part of the "Nazara Engine - Utility module"
|
// This file is part of the "Nazara Engine - Utility module"
|
||||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#ifndef NAZARA_STATICMESH_HPP
|
#ifndef NAZARA_STATICMESH_HPP
|
||||||
#define NAZARA_STATICMESH_HPP
|
#define NAZARA_STATICMESH_HPP
|
||||||
|
|
||||||
#include <Nazara/Prerequesites.hpp>
|
#include <Nazara/Prerequesites.hpp>
|
||||||
#include <Nazara/Utility/SubMesh.hpp>
|
#include <Nazara/Core/ResourceListener.hpp>
|
||||||
|
#include <Nazara/Utility/SubMesh.hpp>
|
||||||
class NAZARA_API NzStaticMesh final : public NzSubMesh
|
|
||||||
{
|
class NAZARA_API NzStaticMesh final : public NzSubMesh, NzResourceListener
|
||||||
public:
|
{
|
||||||
NzStaticMesh(const NzMesh* parent);
|
public:
|
||||||
NzStaticMesh(const NzMesh* parent, const NzVertexDeclaration* vertexDeclaration, NzVertexBuffer* vertexBuffer, NzIndexBuffer* indexBuffer = nullptr);
|
NzStaticMesh(const NzMesh* parent);
|
||||||
virtual ~NzStaticMesh();
|
NzStaticMesh(const NzMesh* parent, const NzVertexDeclaration* vertexDeclaration, NzVertexBuffer* vertexBuffer, NzIndexBuffer* indexBuffer = nullptr);
|
||||||
|
virtual ~NzStaticMesh();
|
||||||
bool Create(const NzVertexDeclaration* vertexDeclaration, NzVertexBuffer* vertexBuffer, NzIndexBuffer* indexBuffer = nullptr);
|
|
||||||
void Destroy();
|
bool Create(const NzVertexDeclaration* vertexDeclaration, NzVertexBuffer* vertexBuffer, NzIndexBuffer* indexBuffer = nullptr);
|
||||||
|
void Destroy();
|
||||||
bool GenerateAABB();
|
|
||||||
|
bool GenerateAABB();
|
||||||
const NzAxisAlignedBox& GetAABB() const;
|
|
||||||
nzAnimationType GetAnimationType() const;
|
const NzAxisAlignedBox& GetAABB() const;
|
||||||
unsigned int GetFrameCount() const;
|
nzAnimationType GetAnimationType() const;
|
||||||
const NzIndexBuffer* GetIndexBuffer() const;
|
unsigned int GetFrameCount() const;
|
||||||
nzPrimitiveType GetPrimitiveType() const;
|
const NzIndexBuffer* GetIndexBuffer() const;
|
||||||
const NzVertexBuffer* GetVertexBuffer() const;
|
nzPrimitiveType GetPrimitiveType() const;
|
||||||
const NzVertexDeclaration* GetVertexDeclaration() const;
|
const NzVertexBuffer* GetVertexBuffer() const;
|
||||||
|
const NzVertexDeclaration* GetVertexDeclaration() const;
|
||||||
bool IsAnimated() const;
|
|
||||||
bool IsValid() const;
|
bool IsAnimated() const;
|
||||||
|
bool IsValid() const;
|
||||||
void SetAABB(const NzAxisAlignedBox& aabb);
|
|
||||||
void SetPrimitiveType(nzPrimitiveType primitiveType);
|
void SetAABB(const NzAxisAlignedBox& aabb);
|
||||||
|
void SetPrimitiveType(nzPrimitiveType primitiveType);
|
||||||
private:
|
|
||||||
void AnimateImpl(unsigned int frameA, unsigned int frameB, float interpolation);
|
private:
|
||||||
|
void AnimateImpl(unsigned int frameA, unsigned int frameB, float interpolation);
|
||||||
nzPrimitiveType m_primitiveType = nzPrimitiveType_TriangleList;
|
void OnResourceReleased(const NzResource* resource, int index) override;
|
||||||
NzAxisAlignedBox m_aabb;
|
|
||||||
NzIndexBuffer* m_indexBuffer = nullptr;
|
nzPrimitiveType m_primitiveType = nzPrimitiveType_TriangleList;
|
||||||
NzVertexBuffer* m_vertexBuffer = nullptr;
|
NzAxisAlignedBox m_aabb;
|
||||||
const NzVertexDeclaration* m_vertexDeclaration = nullptr;
|
NzIndexBuffer* m_indexBuffer = nullptr;
|
||||||
};
|
NzVertexBuffer* m_vertexBuffer = nullptr;
|
||||||
|
const NzVertexDeclaration* m_vertexDeclaration = nullptr;
|
||||||
#endif // NAZARA_STATICMESH_HPP
|
};
|
||||||
|
|
||||||
|
#endif // NAZARA_STATICMESH_HPP
|
||||||
|
|
|
||||||
|
|
@ -1,53 +1,56 @@
|
||||||
// Copyright (C) 2012 Jérôme Leclercq
|
// Copyright (C) 2012 Jérôme Leclercq
|
||||||
// This file is part of the "Nazara Engine - Utility module"
|
// This file is part of the "Nazara Engine - Utility module"
|
||||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||||
|
|
||||||
#ifndef NAZARA_VERTEXDECLARATION_HPP
|
#ifndef NAZARA_VERTEXDECLARATION_HPP
|
||||||
#define NAZARA_VERTEXDECLARATION_HPP
|
#define NAZARA_VERTEXDECLARATION_HPP
|
||||||
|
|
||||||
#include <Nazara/Prerequesites.hpp>
|
#include <Nazara/Prerequesites.hpp>
|
||||||
#include <Nazara/Core/Resource.hpp>
|
#include <Nazara/Core/Resource.hpp>
|
||||||
#include <Nazara/Utility/Enums.hpp>
|
#include <Nazara/Utility/Enums.hpp>
|
||||||
|
|
||||||
struct NzVertexElement
|
struct NzVertexElement
|
||||||
{
|
{
|
||||||
unsigned int offset;
|
unsigned int offset;
|
||||||
unsigned int usageIndex = 0;
|
unsigned int usageIndex = 0;
|
||||||
nzElementStream stream = nzElementStream_VertexData;
|
nzElementStream stream = nzElementStream_VertexData;
|
||||||
nzElementType type;
|
nzElementType type;
|
||||||
nzElementUsage usage;
|
nzElementUsage usage;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct NzVertexDeclarationImpl;
|
struct NzVertexDeclarationImpl;
|
||||||
|
|
||||||
class NAZARA_API NzVertexDeclaration : public NzResource
|
class NAZARA_API NzVertexDeclaration : public NzResource
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
NzVertexDeclaration() = default;
|
NzVertexDeclaration() = default;
|
||||||
NzVertexDeclaration(const NzVertexElement* elements, unsigned int elementCount);
|
NzVertexDeclaration(const NzVertexElement* elements, unsigned int elementCount);
|
||||||
NzVertexDeclaration(const NzVertexDeclaration& declaration);
|
NzVertexDeclaration(const NzVertexDeclaration& declaration);
|
||||||
NzVertexDeclaration(NzVertexDeclaration&& declaration) noexcept;
|
NzVertexDeclaration(NzVertexDeclaration&& declaration) noexcept;
|
||||||
~NzVertexDeclaration();
|
~NzVertexDeclaration();
|
||||||
|
|
||||||
bool Create(const NzVertexElement* elements, unsigned int elementCount);
|
bool Create(const NzVertexElement* elements, unsigned int elementCount);
|
||||||
void Destroy();
|
void Destroy();
|
||||||
|
|
||||||
const NzVertexElement* GetElement(unsigned int i) const;
|
const NzVertexElement* GetElement(unsigned int i) const;
|
||||||
const NzVertexElement* GetElement(nzElementStream stream, unsigned int i) const;
|
const NzVertexElement* GetElement(nzElementStream stream, unsigned int i) const;
|
||||||
const NzVertexElement* GetElement(nzElementStream stream, nzElementUsage usage, unsigned int usageIndex = 0) const;
|
const NzVertexElement* GetElement(nzElementStream stream, nzElementUsage usage, unsigned int usageIndex = 0) const;
|
||||||
unsigned int GetElementCount() const;
|
unsigned int GetElementCount() const;
|
||||||
unsigned int GetElementCount(nzElementStream stream) const;
|
unsigned int GetElementCount(nzElementStream stream) const;
|
||||||
unsigned int GetStride(nzElementStream stream) const;
|
unsigned int GetStride(nzElementStream stream) const;
|
||||||
|
|
||||||
bool HasStream(nzElementStream stream) const;
|
bool HasStream(nzElementStream stream) const;
|
||||||
|
|
||||||
bool IsValid() const;
|
bool IsValid() const;
|
||||||
|
|
||||||
NzVertexDeclaration& operator=(const NzVertexDeclaration& declaration);
|
NzVertexDeclaration& operator=(const NzVertexDeclaration& declaration);
|
||||||
NzVertexDeclaration& operator=(NzVertexDeclaration&& declaration) noexcept;
|
NzVertexDeclaration& operator=(NzVertexDeclaration&& declaration) noexcept;
|
||||||
|
|
||||||
private:
|
static unsigned int GetElementCount(nzElementType type);
|
||||||
NzVertexDeclarationImpl* m_sharedImpl = nullptr;
|
static unsigned int GetElementSize(nzElementType type);
|
||||||
};
|
|
||||||
|
private:
|
||||||
#endif // NAZARA_VERTEXDECLARATION_HPP
|
NzVertexDeclarationImpl* m_sharedImpl = nullptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // NAZARA_VERTEXDECLARATION_HPP
|
||||||
|
|
|
||||||
|
|
@ -1,111 +1,112 @@
|
||||||
// Copyright (C) 2012 Jérôme Leclercq
|
// Copyright (C) 2012 Jérôme Leclercq
|
||||||
// This file is part of the "Nazara Engine - Utility module"
|
// This file is part of the "Nazara Engine - Utility module"
|
||||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||||
|
|
||||||
// Interface inspirée de la SFML par Laurent Gomila
|
// Interface inspirée de la SFML par Laurent Gomila
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#ifndef NAZARA_WINDOW_HPP
|
#ifndef NAZARA_WINDOW_HPP
|
||||||
#define NAZARA_WINDOW_HPP
|
#define NAZARA_WINDOW_HPP
|
||||||
|
|
||||||
#include <Nazara/Prerequesites.hpp>
|
#include <Nazara/Prerequesites.hpp>
|
||||||
#include <Nazara/Core/NonCopyable.hpp>
|
#include <Nazara/Core/NonCopyable.hpp>
|
||||||
#include <Nazara/Core/String.hpp>
|
#include <Nazara/Core/String.hpp>
|
||||||
#include <Nazara/Math/Vector2.hpp>
|
#include <Nazara/Math/Vector2.hpp>
|
||||||
#include <Nazara/Utility/Config.hpp>
|
#include <Nazara/Utility/Config.hpp>
|
||||||
#include <Nazara/Utility/Enums.hpp>
|
#include <Nazara/Utility/Enums.hpp>
|
||||||
#include <Nazara/Utility/Event.hpp>
|
#include <Nazara/Utility/Event.hpp>
|
||||||
#include <Nazara/Utility/VideoMode.hpp>
|
#include <Nazara/Utility/VideoMode.hpp>
|
||||||
#include <Nazara/Utility/WindowHandle.hpp>
|
#include <Nazara/Utility/WindowHandle.hpp>
|
||||||
#include <queue>
|
#include <queue>
|
||||||
|
|
||||||
#if NAZARA_UTILITY_THREADED_WINDOW
|
#if NAZARA_UTILITY_THREADED_WINDOW
|
||||||
#include <Nazara/Core/Mutex.hpp>
|
#include <Nazara/Core/ConditionVariable.hpp>
|
||||||
#include <Nazara/Core/ThreadCondition.hpp>
|
#include <Nazara/Core/Mutex.hpp>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
class NzCursor;
|
class NzCursor;
|
||||||
class NzImage;
|
class NzImage;
|
||||||
class NzIcon;
|
class NzIcon;
|
||||||
class NzWindowImpl;
|
class NzWindowImpl;
|
||||||
|
|
||||||
class NAZARA_API NzWindow : NzNonCopyable
|
class NAZARA_API NzWindow : NzNonCopyable
|
||||||
{
|
{
|
||||||
friend NzWindowImpl;
|
friend NzWindowImpl;
|
||||||
friend class NzMouse;
|
friend class NzMouse;
|
||||||
friend class NzUtility;
|
friend class NzUtility;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
NzWindow();
|
NzWindow();
|
||||||
NzWindow(NzVideoMode mode, const NzString& title, nzUInt32 style = nzWindowStyle_Default);
|
NzWindow(NzVideoMode mode, const NzString& title, nzUInt32 style = nzWindowStyle_Default);
|
||||||
NzWindow(NzWindowHandle handle);
|
NzWindow(NzWindowHandle handle);
|
||||||
virtual ~NzWindow();
|
virtual ~NzWindow();
|
||||||
|
|
||||||
bool Create(NzVideoMode mode, const NzString& title, nzUInt32 style = nzWindowStyle_Default);
|
bool Create(NzVideoMode mode, const NzString& title, nzUInt32 style = nzWindowStyle_Default);
|
||||||
bool Create(NzWindowHandle handle);
|
bool Create(NzWindowHandle handle);
|
||||||
|
|
||||||
void Destroy();
|
void Destroy();
|
||||||
|
|
||||||
void EnableKeyRepeat(bool enable);
|
void EnableKeyRepeat(bool enable);
|
||||||
void EnableSmoothScrolling(bool enable);
|
void EnableSmoothScrolling(bool enable);
|
||||||
|
|
||||||
NzWindowHandle GetHandle() const;
|
NzWindowHandle GetHandle() const;
|
||||||
unsigned int GetHeight() const;
|
unsigned int GetHeight() const;
|
||||||
NzVector2i GetPosition() const;
|
NzVector2i GetPosition() const;
|
||||||
NzVector2ui GetSize() const;
|
NzVector2ui GetSize() const;
|
||||||
NzString GetTitle() const;
|
NzString GetTitle() const;
|
||||||
unsigned int GetWidth() const;
|
unsigned int GetWidth() const;
|
||||||
|
|
||||||
bool HasFocus() const;
|
bool HasFocus() const;
|
||||||
|
|
||||||
bool IsMinimized() const;
|
bool IsMinimized() const;
|
||||||
bool IsOpen() const;
|
bool IsOpen() const;
|
||||||
bool IsVisible() const;
|
bool IsValid() const;
|
||||||
|
bool IsVisible() const;
|
||||||
bool PollEvent(NzEvent* event);
|
|
||||||
|
bool PollEvent(NzEvent* event);
|
||||||
void SetCursor(nzWindowCursor cursor);
|
|
||||||
void SetCursor(const NzCursor& cursor);
|
void SetCursor(nzWindowCursor cursor);
|
||||||
void SetEventListener(bool listener);
|
void SetCursor(const NzCursor& cursor);
|
||||||
void SetFocus();
|
void SetEventListener(bool listener);
|
||||||
void SetIcon(const NzIcon& icon);
|
void SetFocus();
|
||||||
void SetMaximumSize(const NzVector2i& maxSize);
|
void SetIcon(const NzIcon& icon);
|
||||||
void SetMaximumSize(int width, int height);
|
void SetMaximumSize(const NzVector2i& maxSize);
|
||||||
void SetMinimumSize(const NzVector2i& minSize);
|
void SetMaximumSize(int width, int height);
|
||||||
void SetMinimumSize(int width, int height);
|
void SetMinimumSize(const NzVector2i& minSize);
|
||||||
void SetPosition(const NzVector2i& position);
|
void SetMinimumSize(int width, int height);
|
||||||
void SetPosition(int x, int y);
|
void SetPosition(const NzVector2i& position);
|
||||||
void SetSize(const NzVector2i& size);
|
void SetPosition(int x, int y);
|
||||||
void SetSize(unsigned int width, unsigned int height);
|
void SetSize(const NzVector2i& size);
|
||||||
void SetStayOnTop(bool stayOnTop);
|
void SetSize(unsigned int width, unsigned int height);
|
||||||
void SetTitle(const NzString& title);
|
void SetStayOnTop(bool stayOnTop);
|
||||||
void SetVisible(bool visible);
|
void SetTitle(const NzString& title);
|
||||||
|
void SetVisible(bool visible);
|
||||||
bool WaitEvent(NzEvent* event);
|
|
||||||
|
bool WaitEvent(NzEvent* event);
|
||||||
protected:
|
|
||||||
virtual void OnWindowDestroying();
|
protected:
|
||||||
virtual bool OnWindowCreated();
|
virtual bool OnWindowCreated();
|
||||||
|
virtual void OnWindowDestroy();
|
||||||
NzWindowImpl* m_impl;
|
|
||||||
|
NzWindowImpl* m_impl;
|
||||||
private:
|
|
||||||
void IgnoreNextMouseEvent(int mouseX, int mouseY) const;
|
private:
|
||||||
void PushEvent(const NzEvent& event);
|
void IgnoreNextMouseEvent(int mouseX, int mouseY) const;
|
||||||
|
void PushEvent(const NzEvent& event);
|
||||||
static bool Initialize();
|
|
||||||
static void Uninitialize();
|
static bool Initialize();
|
||||||
|
static void Uninitialize();
|
||||||
std::queue<NzEvent> m_events;
|
|
||||||
#if NAZARA_UTILITY_THREADED_WINDOW
|
std::queue<NzEvent> m_events;
|
||||||
NzConditionVariable m_eventCondition;
|
#if NAZARA_UTILITY_THREADED_WINDOW
|
||||||
NzMutex m_eventMutex;
|
NzConditionVariable m_eventCondition;
|
||||||
NzMutex m_eventConditionMutex;
|
NzMutex m_eventMutex;
|
||||||
bool m_eventListener;
|
NzMutex m_eventConditionMutex;
|
||||||
bool m_waitForEvent;
|
bool m_eventListener;
|
||||||
#endif
|
bool m_waitForEvent;
|
||||||
bool m_ownsWindow;
|
#endif
|
||||||
};
|
bool m_ownsWindow;
|
||||||
|
};
|
||||||
#endif // NAZARA_WINDOW_HPP
|
|
||||||
|
#endif // NAZARA_WINDOW_HPP
|
||||||
|
|
|
||||||
|
|
@ -1,223 +1,229 @@
|
||||||
// Copyright (C) 2012 Jérôme Leclercq
|
// Copyright (C) 2012 Jérôme Leclercq
|
||||||
// This file is part of the "Nazara Engine - Audio module"
|
// This file is part of the "Nazara Engine - Audio module"
|
||||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||||
|
|
||||||
#include <Nazara/Audio/SoundBuffer.hpp>
|
#include <Nazara/Audio/SoundBuffer.hpp>
|
||||||
#include <Nazara/Audio/Audio.hpp>
|
#include <Nazara/Audio/Audio.hpp>
|
||||||
#include <Nazara/Audio/Config.hpp>
|
#include <Nazara/Audio/Config.hpp>
|
||||||
#include <Nazara/Core/Error.hpp>
|
#include <Nazara/Core/Error.hpp>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include <AL/al.h>
|
#include <AL/al.h>
|
||||||
#include <Nazara/Audio/Debug.hpp>
|
#include <Nazara/Audio/Debug.hpp>
|
||||||
|
|
||||||
///FIXME: Adapter la création
|
///FIXME: Adapter la création
|
||||||
|
|
||||||
bool NzSoundBufferParams::IsValid() const
|
bool NzSoundBufferParams::IsValid() const
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct NzSoundBufferImpl
|
struct NzSoundBufferImpl
|
||||||
{
|
{
|
||||||
ALuint buffer;
|
ALuint buffer;
|
||||||
nzAudioFormat format;
|
nzAudioFormat format;
|
||||||
nzUInt32 duration;
|
nzUInt32 duration;
|
||||||
nzInt16* samples;
|
nzInt16* samples;
|
||||||
unsigned int sampleCount;
|
unsigned int sampleCount;
|
||||||
unsigned int sampleRate;
|
unsigned int sampleRate;
|
||||||
};
|
};
|
||||||
|
|
||||||
NzSoundBuffer::NzSoundBuffer(nzAudioFormat format, unsigned int sampleCount, unsigned int sampleRate, const nzInt16* samples)
|
NzSoundBuffer::NzSoundBuffer(nzAudioFormat format, unsigned int sampleCount, unsigned int sampleRate, const nzInt16* samples)
|
||||||
{
|
{
|
||||||
Create(format, sampleCount, sampleRate, samples);
|
Create(format, sampleCount, sampleRate, samples);
|
||||||
|
|
||||||
#ifdef NAZARA_DEBUG
|
#ifdef NAZARA_DEBUG
|
||||||
if (!m_impl)
|
if (!m_impl)
|
||||||
{
|
{
|
||||||
NazaraError("Failed to create sound buffer");
|
NazaraError("Failed to create sound buffer");
|
||||||
throw std::runtime_error("Constructor failed");
|
throw std::runtime_error("Constructor failed");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
NzSoundBuffer::~NzSoundBuffer()
|
NzSoundBuffer::~NzSoundBuffer()
|
||||||
{
|
{
|
||||||
Destroy();
|
Destroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NzSoundBuffer::Create(nzAudioFormat format, unsigned int sampleCount, unsigned int sampleRate, const nzInt16* samples)
|
bool NzSoundBuffer::Create(nzAudioFormat format, unsigned int sampleCount, unsigned int sampleRate, const nzInt16* samples)
|
||||||
{
|
{
|
||||||
Destroy();
|
Destroy();
|
||||||
|
|
||||||
if (sampleCount == 0)
|
#if NAZARA_AUDIO_SAFE
|
||||||
return true;
|
if (!IsFormatSupported(format))
|
||||||
|
{
|
||||||
#if NAZARA_AUDIO_SAFE
|
NazaraError("Audio format is not supported");
|
||||||
if (!IsFormatSupported(format))
|
return false;
|
||||||
{
|
}
|
||||||
NazaraError("Audio format is not supported");
|
|
||||||
return false;
|
if (sampleCount == 0)
|
||||||
}
|
{
|
||||||
|
NazaraError("Sample rate must be different from zero");
|
||||||
if (sampleRate == 0)
|
return false;
|
||||||
{
|
}
|
||||||
NazaraError("Sample rate must be different from zero");
|
|
||||||
return false;
|
if (sampleRate == 0)
|
||||||
}
|
{
|
||||||
|
NazaraError("Sample rate must be different from zero");
|
||||||
if (!samples)
|
return false;
|
||||||
{
|
}
|
||||||
NazaraError("Invalid sample source");
|
|
||||||
return false;
|
if (!samples)
|
||||||
}
|
{
|
||||||
#endif
|
NazaraError("Invalid sample source");
|
||||||
|
return false;
|
||||||
// On vide le stack d'erreurs
|
}
|
||||||
while (alGetError() != AL_NO_ERROR);
|
#endif
|
||||||
|
|
||||||
ALuint buffer;
|
// On vide le stack d'erreurs
|
||||||
alGenBuffers(1, &buffer);
|
while (alGetError() != AL_NO_ERROR);
|
||||||
|
|
||||||
if (alGetError() != AL_NO_ERROR)
|
ALuint buffer;
|
||||||
{
|
alGenBuffers(1, &buffer);
|
||||||
NazaraError("Failed to create OpenAL buffer");
|
|
||||||
return false;
|
if (alGetError() != AL_NO_ERROR)
|
||||||
}
|
{
|
||||||
|
NazaraError("Failed to create OpenAL buffer");
|
||||||
alBufferData(buffer, NzAudio::GetOpenALFormat(format), samples, sampleCount*sizeof(nzInt16), sampleRate);
|
return false;
|
||||||
|
}
|
||||||
if (alGetError() != AL_NO_ERROR)
|
|
||||||
{
|
alBufferData(buffer, NzAudio::GetOpenALFormat(format), samples, sampleCount*sizeof(nzInt16), sampleRate);
|
||||||
NazaraError("Failed to set OpenAL buffer");
|
|
||||||
alDeleteBuffers(1, &buffer);
|
if (alGetError() != AL_NO_ERROR)
|
||||||
|
{
|
||||||
return false;
|
NazaraError("Failed to set OpenAL buffer");
|
||||||
}
|
alDeleteBuffers(1, &buffer);
|
||||||
|
|
||||||
m_impl = new NzSoundBufferImpl;
|
return false;
|
||||||
m_impl->buffer = buffer;
|
}
|
||||||
m_impl->duration = 1000 * (sampleCount / (format * sampleRate));
|
|
||||||
m_impl->format = format;
|
m_impl = new NzSoundBufferImpl;
|
||||||
m_impl->sampleCount = sampleCount;
|
m_impl->buffer = buffer;
|
||||||
m_impl->sampleRate = sampleRate;
|
m_impl->duration = 1000 * (sampleCount / (format * sampleRate));
|
||||||
m_impl->samples = new nzInt16[sampleCount];
|
m_impl->format = format;
|
||||||
std::memcpy(&m_impl->samples[0], samples, sampleCount*sizeof(nzInt16));
|
m_impl->sampleCount = sampleCount;
|
||||||
|
m_impl->sampleRate = sampleRate;
|
||||||
return true;
|
m_impl->samples = new nzInt16[sampleCount];
|
||||||
}
|
std::memcpy(&m_impl->samples[0], samples, sampleCount*sizeof(nzInt16));
|
||||||
|
|
||||||
void NzSoundBuffer::Destroy()
|
NotifyCreated();
|
||||||
{
|
return true;
|
||||||
if (m_impl)
|
}
|
||||||
{
|
|
||||||
delete[] m_impl->samples;
|
void NzSoundBuffer::Destroy()
|
||||||
delete m_impl;
|
{
|
||||||
m_impl = nullptr;
|
if (m_impl)
|
||||||
}
|
{
|
||||||
}
|
NotifyDestroy();
|
||||||
|
|
||||||
nzUInt32 NzSoundBuffer::GetDuration() const
|
delete[] m_impl->samples;
|
||||||
{
|
delete m_impl;
|
||||||
#if NAZARA_AUDIO_SAFE
|
m_impl = nullptr;
|
||||||
if (!m_impl)
|
}
|
||||||
{
|
}
|
||||||
NazaraError("Sound buffer not created");
|
|
||||||
return 0;
|
nzUInt32 NzSoundBuffer::GetDuration() const
|
||||||
}
|
{
|
||||||
#endif
|
#if NAZARA_AUDIO_SAFE
|
||||||
|
if (!m_impl)
|
||||||
return m_impl->duration;
|
{
|
||||||
}
|
NazaraError("Sound buffer not created");
|
||||||
|
return 0;
|
||||||
nzAudioFormat NzSoundBuffer::GetFormat() const
|
}
|
||||||
{
|
#endif
|
||||||
#if NAZARA_AUDIO_SAFE
|
|
||||||
if (!m_impl)
|
return m_impl->duration;
|
||||||
{
|
}
|
||||||
NazaraError("Sound buffer not created");
|
|
||||||
return nzAudioFormat_Unknown;
|
nzAudioFormat NzSoundBuffer::GetFormat() const
|
||||||
}
|
{
|
||||||
#endif
|
#if NAZARA_AUDIO_SAFE
|
||||||
|
if (!m_impl)
|
||||||
return m_impl->format;
|
{
|
||||||
}
|
NazaraError("Sound buffer not created");
|
||||||
|
return nzAudioFormat_Unknown;
|
||||||
const nzInt16* NzSoundBuffer::GetSamples() const
|
}
|
||||||
{
|
#endif
|
||||||
#if NAZARA_AUDIO_SAFE
|
|
||||||
if (!m_impl)
|
return m_impl->format;
|
||||||
{
|
}
|
||||||
NazaraError("Sound buffer not created");
|
|
||||||
return nullptr;
|
const nzInt16* NzSoundBuffer::GetSamples() const
|
||||||
}
|
{
|
||||||
#endif
|
#if NAZARA_AUDIO_SAFE
|
||||||
|
if (!m_impl)
|
||||||
return m_impl->samples;
|
{
|
||||||
}
|
NazaraError("Sound buffer not created");
|
||||||
|
return nullptr;
|
||||||
unsigned int NzSoundBuffer::GetSampleCount() const
|
}
|
||||||
{
|
#endif
|
||||||
#if NAZARA_AUDIO_SAFE
|
|
||||||
if (!m_impl)
|
return m_impl->samples;
|
||||||
{
|
}
|
||||||
NazaraError("Sound buffer not created");
|
|
||||||
return 0;
|
unsigned int NzSoundBuffer::GetSampleCount() const
|
||||||
}
|
{
|
||||||
#endif
|
#if NAZARA_AUDIO_SAFE
|
||||||
|
if (!m_impl)
|
||||||
return m_impl->sampleCount;
|
{
|
||||||
}
|
NazaraError("Sound buffer not created");
|
||||||
|
return 0;
|
||||||
unsigned int NzSoundBuffer::GetSampleRate() const
|
}
|
||||||
{
|
#endif
|
||||||
#if NAZARA_AUDIO_SAFE
|
|
||||||
if (!m_impl)
|
return m_impl->sampleCount;
|
||||||
{
|
}
|
||||||
NazaraError("Sound buffer not created");
|
|
||||||
return 0;
|
unsigned int NzSoundBuffer::GetSampleRate() const
|
||||||
}
|
{
|
||||||
#endif
|
#if NAZARA_AUDIO_SAFE
|
||||||
|
if (!m_impl)
|
||||||
return m_impl->sampleRate;
|
{
|
||||||
}
|
NazaraError("Sound buffer not created");
|
||||||
|
return 0;
|
||||||
bool NzSoundBuffer::IsValid() const
|
}
|
||||||
{
|
#endif
|
||||||
return m_impl != nullptr;
|
|
||||||
}
|
return m_impl->sampleRate;
|
||||||
|
}
|
||||||
bool NzSoundBuffer::LoadFromFile(const NzString& filePath, const NzSoundBufferParams& params)
|
|
||||||
{
|
bool NzSoundBuffer::IsValid() const
|
||||||
return NzSoundBufferLoader::LoadFromFile(this, filePath, params);
|
{
|
||||||
}
|
return m_impl != nullptr;
|
||||||
|
}
|
||||||
bool NzSoundBuffer::LoadFromMemory(const void* data, std::size_t size, const NzSoundBufferParams& params)
|
|
||||||
{
|
bool NzSoundBuffer::LoadFromFile(const NzString& filePath, const NzSoundBufferParams& params)
|
||||||
return NzSoundBufferLoader::LoadFromMemory(this, data, size, params);
|
{
|
||||||
}
|
return NzSoundBufferLoader::LoadFromFile(this, filePath, params);
|
||||||
|
}
|
||||||
bool NzSoundBuffer::LoadFromStream(NzInputStream& stream, const NzSoundBufferParams& params)
|
|
||||||
{
|
bool NzSoundBuffer::LoadFromMemory(const void* data, std::size_t size, const NzSoundBufferParams& params)
|
||||||
return NzSoundBufferLoader::LoadFromStream(this, stream, params);
|
{
|
||||||
}
|
return NzSoundBufferLoader::LoadFromMemory(this, data, size, params);
|
||||||
|
}
|
||||||
bool NzSoundBuffer::IsFormatSupported(nzAudioFormat format)
|
|
||||||
{
|
bool NzSoundBuffer::LoadFromStream(NzInputStream& stream, const NzSoundBufferParams& params)
|
||||||
return NzAudio::IsFormatSupported(format);
|
{
|
||||||
}
|
return NzSoundBufferLoader::LoadFromStream(this, stream, params);
|
||||||
|
}
|
||||||
unsigned int NzSoundBuffer::GetOpenALBuffer() const
|
|
||||||
{
|
bool NzSoundBuffer::IsFormatSupported(nzAudioFormat format)
|
||||||
#ifdef NAZARA_DEBUG
|
{
|
||||||
if (!m_impl)
|
return NzAudio::IsFormatSupported(format);
|
||||||
{
|
}
|
||||||
NazaraInternalError("Sound buffer not created");
|
|
||||||
return AL_NONE;
|
unsigned int NzSoundBuffer::GetOpenALBuffer() const
|
||||||
}
|
{
|
||||||
#endif
|
#ifdef NAZARA_DEBUG
|
||||||
|
if (!m_impl)
|
||||||
return m_impl->buffer;
|
{
|
||||||
}
|
NazaraInternalError("Sound buffer not created");
|
||||||
|
return AL_NONE;
|
||||||
NzSoundBufferLoader::LoaderList NzSoundBuffer::s_loaders;
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return m_impl->buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
NzSoundBufferLoader::LoaderList NzSoundBuffer::s_loaders;
|
||||||
|
|
|
||||||
|
|
@ -1,265 +1,265 @@
|
||||||
/*
|
// Copyright (C) 2012 Jérôme Leclercq
|
||||||
// Copyright (C) 2012 Jérôme Leclercq
|
// This file is part of the "Nazara Engine - Core module"
|
||||||
// This file is part of the "Nazara Engine - Core module"
|
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
|
||||||
|
/*
|
||||||
#include <Nazara/Core/ByteArray.hpp>
|
#include <Nazara/Core/ByteArray.hpp>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <Nazara/Core/Debug.hpp>
|
#include <Nazara/Core/Debug.hpp>
|
||||||
|
|
||||||
inline unsigned int nzPow2(unsigned int n)
|
inline unsigned int nzPow2(unsigned int n)
|
||||||
{
|
{
|
||||||
unsigned int x = 1;
|
unsigned int x = 1;
|
||||||
|
|
||||||
while(x <= n)
|
while(x <= n)
|
||||||
x <<= 1;
|
x <<= 1;
|
||||||
|
|
||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
// Cet algorithme est inspiré de la documentation de Qt
|
// Cet algorithme est inspiré de la documentation de Qt
|
||||||
inline unsigned int nzGetNewSize(unsigned int newSize)
|
inline unsigned int nzGetNewSize(unsigned int newSize)
|
||||||
{
|
{
|
||||||
if (newSize < 20)
|
if (newSize < 20)
|
||||||
return newSize+4;
|
return newSize+4;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (newSize < (1 << 12)-12)
|
if (newSize < (1 << 12)-12)
|
||||||
return nzPow2(newSize << 1)-12;
|
return nzPow2(newSize << 1)-12;
|
||||||
else
|
else
|
||||||
return newSize + (1 << 11);
|
return newSize + (1 << 11);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
NzByteArray::NzByteArray() :
|
NzByteArray::NzByteArray() :
|
||||||
m_sharedArray(&emptyArray)
|
m_sharedArray(&emptyArray)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
NzByteArray::NzByteArray(const nzUInt8* buffer, unsigned int bufferLength)
|
NzByteArray::NzByteArray(const nzUInt8* buffer, unsigned int bufferLength)
|
||||||
{
|
{
|
||||||
if (bufferLength > 0)
|
if (bufferLength > 0)
|
||||||
{
|
{
|
||||||
m_sharedArray = new SharedArray;
|
m_sharedArray = new SharedArray;
|
||||||
m_sharedArray->buffer = new nzUInt8[bufferLength];
|
m_sharedArray->buffer = new nzUInt8[bufferLength];
|
||||||
m_sharedArray->capacity = bufferLength;
|
m_sharedArray->capacity = bufferLength;
|
||||||
m_sharedArray->size = bufferLength;
|
m_sharedArray->size = bufferLength;
|
||||||
std::memcpy(m_sharedArray->buffer, buffer, bufferLength);
|
std::memcpy(m_sharedArray->buffer, buffer, bufferLength);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
m_sharedArray = &emptyArray;
|
m_sharedArray = &emptyArray;
|
||||||
}
|
}
|
||||||
|
|
||||||
NzByteArray::NzByteArray(const NzByteArray& buffer) :
|
NzByteArray::NzByteArray(const NzByteArray& buffer) :
|
||||||
m_sharedArray(buffer.m_sharedArray)
|
m_sharedArray(buffer.m_sharedArray)
|
||||||
{
|
{
|
||||||
if (m_sharedArray != &emptyArray)
|
if (m_sharedArray != &emptyArray)
|
||||||
{
|
{
|
||||||
NazaraMutexLock(m_sharedArray->mutex);
|
NazaraMutexLock(m_sharedArray->mutex);
|
||||||
m_sharedArray->refCount++;
|
m_sharedArray->refCount++;
|
||||||
NazaraMutexUnlock(m_sharedArray->mutex);
|
NazaraMutexUnlock(m_sharedArray->mutex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
NzByteArray::NzByteArray(NzByteArray&& buffer) :
|
NzByteArray::NzByteArray(NzByteArray&& buffer) noexcept :
|
||||||
m_sharedArray(buffer.m_sharedArray)
|
m_sharedArray(buffer.m_sharedArray)
|
||||||
{
|
{
|
||||||
buffer.m_sharedArray = &emptyArray;
|
buffer.m_sharedArray = &emptyArray;
|
||||||
}
|
}
|
||||||
|
|
||||||
NzByteArray::NzByteArray(SharedArray* sharedArray) :
|
NzByteArray::NzByteArray(SharedArray* sharedArray) :
|
||||||
m_sharedArray(sharedArray)
|
m_sharedArray(sharedArray)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
NzByteArray::~NzByteArray()
|
NzByteArray::~NzByteArray()
|
||||||
{
|
{
|
||||||
ReleaseArray();
|
ReleaseArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
NzByteArray& NzByteArray::Append(const NzByteArray& byteArray)
|
NzByteArray& NzByteArray::Append(const NzByteArray& byteArray)
|
||||||
{
|
{
|
||||||
if (byteArray.m_sharedArray->size == 0)
|
if (byteArray.m_sharedArray->size == 0)
|
||||||
return *this;
|
return *this;
|
||||||
|
|
||||||
if (m_sharedArray->size == 0 && m_sharedArray->capacity < byteArray.m_sharedArray->size)
|
if (m_sharedArray->size == 0 && m_sharedArray->capacity < byteArray.m_sharedArray->size)
|
||||||
return operator=(byteArray);
|
return operator=(byteArray);
|
||||||
|
|
||||||
if (m_sharedArray->capacity >= m_sharedArray->size + byteArray.m_sharedArray->size)
|
if (m_sharedArray->capacity >= m_sharedArray->size + byteArray.m_sharedArray->size)
|
||||||
{
|
{
|
||||||
EnsureOwnership();
|
EnsureOwnership();
|
||||||
|
|
||||||
std::memcpy(&m_sharedArray->buffer[m_sharedArray->size], byteArray.m_sharedArray->buffer, byteArray.m_sharedArray->size);
|
std::memcpy(&m_sharedArray->buffer[m_sharedArray->size], byteArray.m_sharedArray->buffer, byteArray.m_sharedArray->size);
|
||||||
m_sharedArray->size += byteArray.m_sharedArray->size;
|
m_sharedArray->size += byteArray.m_sharedArray->size;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
unsigned int newSize = m_sharedArray->size + byteArray.m_sharedArray->size;
|
unsigned int newSize = m_sharedArray->size + byteArray.m_sharedArray->size;
|
||||||
unsigned int bufferSize = nzGetNewSize(newSize);
|
unsigned int bufferSize = nzGetNewSize(newSize);
|
||||||
|
|
||||||
nzUInt8* buffer = new nzUInt8[bufferSize+1];
|
nzUInt8* buffer = new nzUInt8[bufferSize+1];
|
||||||
std::memcpy(buffer, m_sharedArray->buffer, m_sharedArray->size);
|
std::memcpy(buffer, m_sharedArray->buffer, m_sharedArray->size);
|
||||||
std::memcpy(&buffer[m_sharedArray->size], byteArray.m_sharedArray->buffer, byteArray.m_sharedArray->size);
|
std::memcpy(&buffer[m_sharedArray->size], byteArray.m_sharedArray->buffer, byteArray.m_sharedArray->size);
|
||||||
|
|
||||||
ReleaseArray();
|
ReleaseArray();
|
||||||
m_sharedArray = new SharedArray;
|
m_sharedArray = new SharedArray;
|
||||||
m_sharedArray->buffer = buffer;
|
m_sharedArray->buffer = buffer;
|
||||||
m_sharedArray->capacity = bufferSize;
|
m_sharedArray->capacity = bufferSize;
|
||||||
m_sharedArray->size = newSize;
|
m_sharedArray->size = newSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
void NzByteArray::Clear()
|
void NzByteArray::Clear()
|
||||||
{
|
{
|
||||||
ReleaseArray();
|
ReleaseArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
nzUInt8* NzByteArray::GetBuffer()
|
nzUInt8* NzByteArray::GetBuffer()
|
||||||
{
|
{
|
||||||
EnsureOwnership();
|
EnsureOwnership();
|
||||||
|
|
||||||
return m_sharedArray->buffer;
|
return m_sharedArray->buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int NzByteArray::GetCapacity() const
|
unsigned int NzByteArray::GetCapacity() const
|
||||||
{
|
{
|
||||||
return m_sharedArray->capacity;
|
return m_sharedArray->capacity;
|
||||||
}
|
}
|
||||||
|
|
||||||
const nzUInt8* NzByteArray::GetConstBuffer() const
|
const nzUInt8* NzByteArray::GetConstBuffer() const
|
||||||
{
|
{
|
||||||
return m_sharedArray->buffer;
|
return m_sharedArray->buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int NzByteArray::GetSize() const
|
unsigned int NzByteArray::GetSize() const
|
||||||
{
|
{
|
||||||
return m_sharedArray->size;
|
return m_sharedArray->size;
|
||||||
}
|
}
|
||||||
|
|
||||||
NzByteArray& NzByteArray::Insert(int pos, const nzUInt8* buffer, unsigned int bufferLength)
|
NzByteArray& NzByteArray::Insert(int pos, const nzUInt8* buffer, unsigned int bufferLength)
|
||||||
{
|
{
|
||||||
if (bufferLength == 0)
|
if (bufferLength == 0)
|
||||||
return *this;
|
return *this;
|
||||||
|
|
||||||
if (m_sharedArray->size == 0)
|
if (m_sharedArray->size == 0)
|
||||||
return operator=(string);
|
return operator=(string);
|
||||||
|
|
||||||
if (pos < 0)
|
if (pos < 0)
|
||||||
pos = std::max(static_cast<int>(m_sharedArray->size + pos), 0);
|
pos = std::max(static_cast<int>(m_sharedArray->size + pos), 0);
|
||||||
|
|
||||||
unsigned int start = std::min(static_cast<unsigned int>(pos), m_sharedArray->size);
|
unsigned int start = std::min(static_cast<unsigned int>(pos), m_sharedArray->size);
|
||||||
|
|
||||||
// Si le buffer est déjà suffisamment grand
|
// Si le buffer est déjà suffisamment grand
|
||||||
if (m_sharedArray->capacity >= m_sharedArray->size + bufferLength)
|
if (m_sharedArray->capacity >= m_sharedArray->size + bufferLength)
|
||||||
{
|
{
|
||||||
EnsureOwnership();
|
EnsureOwnership();
|
||||||
|
|
||||||
std::memmove(&m_sharedArray->buffer[start+bufferLength], &m_sharedArray->buffer[start], m_sharedArray->size);
|
std::memmove(&m_sharedArray->buffer[start+bufferLength], &m_sharedArray->buffer[start], m_sharedArray->size);
|
||||||
std::memcpy(&m_sharedArray->buffer[start], buffer, bufferLength);
|
std::memcpy(&m_sharedArray->buffer[start], buffer, bufferLength);
|
||||||
|
|
||||||
m_sharedArray->size += bufferLength;
|
m_sharedArray->size += bufferLength;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
unsigned int newSize = m_sharedArray->size+bufferLength;
|
unsigned int newSize = m_sharedArray->size+bufferLength;
|
||||||
nzUInt8* newBuffer = new nzUInt8[newSize+1];
|
nzUInt8* newBuffer = new nzUInt8[newSize+1];
|
||||||
|
|
||||||
nzUInt8* ptr = newBuffer;
|
nzUInt8* ptr = newBuffer;
|
||||||
const nzUInt8* s = m_sharedArray->buffer;
|
const nzUInt8* s = m_sharedArray->buffer;
|
||||||
|
|
||||||
while (ptr != &newBuffer[start])
|
while (ptr != &newBuffer[start])
|
||||||
*ptr++ = *s++;
|
*ptr++ = *s++;
|
||||||
|
|
||||||
while (ptr != &newBuffer[start+bufferLength])
|
while (ptr != &newBuffer[start+bufferLength])
|
||||||
*ptr++ = *buffer++;
|
*ptr++ = *buffer++;
|
||||||
|
|
||||||
std::strcpy(ptr, s);
|
std::strcpy(ptr, s);
|
||||||
|
|
||||||
ReleaseString();
|
ReleaseString();
|
||||||
m_sharedArray = new SharedString;
|
m_sharedArray = new SharedString;
|
||||||
m_sharedArray->allocatedSize = newSize;
|
m_sharedArray->allocatedSize = newSize;
|
||||||
m_sharedArray->buffer = newBuffer;
|
m_sharedArray->buffer = newBuffer;
|
||||||
m_sharedArray->size = newSize;
|
m_sharedArray->size = newSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
NzByteArray& NzByteArray::Insert(int pos, const NzByteArray& byteArray)
|
NzByteArray& NzByteArray::Insert(int pos, const NzByteArray& byteArray)
|
||||||
{
|
{
|
||||||
if (string.m_sharedArray->size == 0)
|
if (string.m_sharedArray->size == 0)
|
||||||
return *this;
|
return *this;
|
||||||
|
|
||||||
if (m_sharedArray->size == 0 && m_sharedArray->capacity < string.m_sharedArray->size)
|
if (m_sharedArray->size == 0 && m_sharedArray->capacity < string.m_sharedArray->size)
|
||||||
return operator=(string);
|
return operator=(string);
|
||||||
|
|
||||||
if (pos < 0)
|
if (pos < 0)
|
||||||
pos = std::max(static_cast<int>(m_sharedArray->size + pos), 0);
|
pos = std::max(static_cast<int>(m_sharedArray->size + pos), 0);
|
||||||
|
|
||||||
unsigned int start = std::min(static_cast<unsigned int>(pos), m_sharedArray->size);
|
unsigned int start = std::min(static_cast<unsigned int>(pos), m_sharedArray->size);
|
||||||
|
|
||||||
// Si le buffer est déjà suffisamment grand
|
// Si le buffer est déjà suffisamment grand
|
||||||
if (m_sharedArray->capacity >= m_sharedArray->size + string.m_sharedArray->size)
|
if (m_sharedArray->capacity >= m_sharedArray->size + string.m_sharedArray->size)
|
||||||
{
|
{
|
||||||
EnsureOwnership();
|
EnsureOwnership();
|
||||||
|
|
||||||
std::memmove(&m_sharedArray->string[start+string.m_sharedArray->size], &m_sharedArray->string[start], m_sharedArray->size*sizeof(char));
|
std::memmove(&m_sharedArray->string[start+string.m_sharedArray->size], &m_sharedArray->string[start], m_sharedArray->size*sizeof(char));
|
||||||
std::memcpy(&m_sharedArray->string[start], string.m_sharedArray->string, string.m_sharedArray->size*sizeof(char));
|
std::memcpy(&m_sharedArray->string[start], string.m_sharedArray->string, string.m_sharedArray->size*sizeof(char));
|
||||||
|
|
||||||
m_sharedArray->size += string.m_sharedArray->size;
|
m_sharedArray->size += string.m_sharedArray->size;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
unsigned int newSize = m_sharedArray->size+string.m_sharedArray->size;
|
unsigned int newSize = m_sharedArray->size+string.m_sharedArray->size;
|
||||||
char* newString = new char[newSize+1];
|
char* newString = new char[newSize+1];
|
||||||
|
|
||||||
char* ptr = newString;
|
char* ptr = newString;
|
||||||
const char* s = m_sharedArray->string;
|
const char* s = m_sharedArray->string;
|
||||||
|
|
||||||
while (ptr != &newString[start])
|
while (ptr != &newString[start])
|
||||||
*ptr++ = *s++;
|
*ptr++ = *s++;
|
||||||
|
|
||||||
const char* p = string.m_sharedArray->string;
|
const char* p = string.m_sharedArray->string;
|
||||||
while (ptr != &newString[start+string.m_sharedArray->size])
|
while (ptr != &newString[start+string.m_sharedArray->size])
|
||||||
*ptr++ = *p++;
|
*ptr++ = *p++;
|
||||||
|
|
||||||
std::strcpy(ptr, s);
|
std::strcpy(ptr, s);
|
||||||
|
|
||||||
ReleaseString();
|
ReleaseString();
|
||||||
m_sharedArray = new SharedString;
|
m_sharedArray = new SharedString;
|
||||||
m_sharedArray->capacity = newSize;
|
m_sharedArray->capacity = newSize;
|
||||||
m_sharedArray->size = newSize;
|
m_sharedArray->size = newSize;
|
||||||
m_sharedArray->string = newString;
|
m_sharedArray->string = newString;
|
||||||
}
|
}
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NzByteArray::IsEmpty() const
|
bool NzByteArray::IsEmpty() const
|
||||||
{
|
{
|
||||||
return m_sharedArray->size == 0;
|
return m_sharedArray->size == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void NzByteArray::Reserve(unsigned int bufferSize)
|
void NzByteArray::Reserve(unsigned int bufferSize)
|
||||||
{
|
{
|
||||||
if (m_sharedArray->allocatedSize >= bufferSize)
|
if (m_sharedArray->allocatedSize >= bufferSize)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
nzUInt8* ptr = new nzUInt8[bufferSize+1];
|
nzUInt8* ptr = new nzUInt8[bufferSize+1];
|
||||||
if (m_sharedArray->size > 0)
|
if (m_sharedArray->size > 0)
|
||||||
std::memcpy(ptr, m_sharedArray->buffer, m_sharedArray->size);
|
std::memcpy(ptr, m_sharedArray->buffer, m_sharedArray->size);
|
||||||
|
|
||||||
unsigned int size = m_sharedArray->size;
|
unsigned int size = m_sharedArray->size;
|
||||||
|
|
||||||
ReleaseArray();
|
ReleaseArray();
|
||||||
m_sharedArray = new SharedString;
|
m_sharedArray = new SharedString;
|
||||||
m_sharedArray->allocatedSize = bufferSize;
|
m_sharedArray->allocatedSize = bufferSize;
|
||||||
m_sharedArray->buffer = ptr;
|
m_sharedArray->buffer = ptr;
|
||||||
m_sharedArray->size = size;
|
m_sharedArray->size = size;
|
||||||
}
|
}
|
||||||
|
|
||||||
NzByteArray::SharedString NzByteArray::emptyArray(0, 0, 0, nullptr);
|
NzByteArray::SharedString NzByteArray::emptyArray(0, 0, 0, nullptr);
|
||||||
unsigned int NzByteArray::npos(static_cast<unsigned int>(-1));
|
unsigned int NzByteArray::npos(static_cast<unsigned int>(-1));
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -1,264 +1,271 @@
|
||||||
// Copyright (C) 2012 Jérôme Leclercq
|
// Copyright (C) 2012 Jérôme Leclercq
|
||||||
// This file is part of the "Nazara Engine - Core module"
|
// This file is part of the "Nazara Engine - Core module"
|
||||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||||
|
|
||||||
#include <Nazara/Core/Debug/MemoryLeakTracker.hpp>
|
#include <Nazara/Core/Debug/MemoryLeakTracker.hpp>
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <ctime>
|
#include <ctime>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
|
||||||
#if defined(NAZARA_PLATFORM_WINDOWS)
|
#if defined(NAZARA_PLATFORM_WINDOWS)
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#elif defined(NAZARA_PLATFORM_POSIX)
|
#elif defined(NAZARA_PLATFORM_POSIX)
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
struct Block
|
struct Block
|
||||||
{
|
{
|
||||||
std::size_t size;
|
std::size_t size;
|
||||||
const char* file;
|
const char* file;
|
||||||
Block* prev;
|
Block* prev;
|
||||||
Block* next;
|
Block* next;
|
||||||
bool array;
|
bool array;
|
||||||
unsigned int line;
|
unsigned int line;
|
||||||
unsigned int magic;
|
unsigned int magic;
|
||||||
};
|
};
|
||||||
|
|
||||||
bool initialized = false;
|
bool initialized = false;
|
||||||
const unsigned int magic = 0x51429EE;
|
const unsigned int magic = 0x51429EE;
|
||||||
const char* MLTFileName = "NazaraLeaks.log";
|
const char* MLTFileName = "NazaraLeaks.log";
|
||||||
const char* nextFreeFile = "Internal error";
|
const char* nextFreeFile = "Internal error";
|
||||||
unsigned int nextFreeLine = 0;
|
unsigned int nextFreeLine = 0;
|
||||||
|
|
||||||
Block ptrList =
|
Block ptrList =
|
||||||
{
|
{
|
||||||
0,
|
0,
|
||||||
nullptr,
|
nullptr,
|
||||||
&ptrList,
|
&ptrList,
|
||||||
&ptrList,
|
&ptrList,
|
||||||
false,
|
false,
|
||||||
0,
|
0,
|
||||||
magic
|
magic
|
||||||
};
|
};
|
||||||
|
|
||||||
#if defined(NAZARA_PLATFORM_WINDOWS)
|
#if defined(NAZARA_PLATFORM_WINDOWS)
|
||||||
CRITICAL_SECTION mutex;
|
CRITICAL_SECTION mutex;
|
||||||
#elif defined(NAZARA_PLATFORM_POSIX)
|
#elif defined(NAZARA_PLATFORM_POSIX)
|
||||||
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
|
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
NzMemoryManager::NzMemoryManager()
|
NzMemoryManager::NzMemoryManager()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
NzMemoryManager::~NzMemoryManager()
|
NzMemoryManager::~NzMemoryManager()
|
||||||
{
|
{
|
||||||
Uninitialize();
|
Uninitialize();
|
||||||
}
|
}
|
||||||
|
|
||||||
void* NzMemoryManager::Allocate(std::size_t size, bool multi, const char* file, unsigned int line)
|
void* NzMemoryManager::Allocate(std::size_t size, bool multi, const char* file, unsigned int line)
|
||||||
{
|
{
|
||||||
if (!initialized)
|
if (!initialized)
|
||||||
Initialize();
|
Initialize();
|
||||||
|
|
||||||
#if defined(NAZARA_PLATFORM_WINDOWS)
|
#if defined(NAZARA_PLATFORM_WINDOWS)
|
||||||
EnterCriticalSection(&mutex);
|
EnterCriticalSection(&mutex);
|
||||||
#elif defined(NAZARA_PLATFORM_POSIX)
|
#elif defined(NAZARA_PLATFORM_POSIX)
|
||||||
pthread_mutex_lock(&mutex);
|
pthread_mutex_lock(&mutex);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
Block* ptr = reinterpret_cast<Block*>(std::malloc(size+sizeof(Block)));
|
Block* ptr = reinterpret_cast<Block*>(std::malloc(size+sizeof(Block)));
|
||||||
if (!ptr)
|
if (!ptr)
|
||||||
return nullptr; // Impossible d'envoyer une exception car cela allouerait de la mémoire avec new (boucle infinie)
|
{
|
||||||
|
// Pas d'information de temps (Car nécessitant une allocation)
|
||||||
ptr->array = multi;
|
FILE* log = std::fopen(MLTFileName, "a");
|
||||||
ptr->file = file;
|
std::fprintf(log, "Failed to allocate memory (%d bytes)\n", size);
|
||||||
ptr->line = line;
|
std::fclose(log);
|
||||||
ptr->size = size;
|
|
||||||
ptr->magic = magic;
|
return nullptr; // Impossible d'envoyer une exception car cela allouerait de la mémoire avec new (boucle infinie)
|
||||||
|
}
|
||||||
ptr->prev = ptrList.prev;
|
|
||||||
ptr->next = &ptrList;
|
ptr->array = multi;
|
||||||
ptrList.prev->next = ptr;
|
ptr->file = file;
|
||||||
ptrList.prev = ptr;
|
ptr->line = line;
|
||||||
|
ptr->size = size;
|
||||||
#if defined(NAZARA_PLATFORM_WINDOWS)
|
ptr->magic = magic;
|
||||||
LeaveCriticalSection(&mutex);
|
|
||||||
#elif defined(NAZARA_PLATFORM_POSIX)
|
ptr->prev = ptrList.prev;
|
||||||
pthread_mutex_unlock(&mutex);
|
ptr->next = &ptrList;
|
||||||
#endif
|
ptrList.prev->next = ptr;
|
||||||
|
ptrList.prev = ptr;
|
||||||
return reinterpret_cast<char*>(ptr)+sizeof(Block);
|
|
||||||
}
|
#if defined(NAZARA_PLATFORM_WINDOWS)
|
||||||
|
LeaveCriticalSection(&mutex);
|
||||||
void NzMemoryManager::Free(void* pointer, bool multi)
|
#elif defined(NAZARA_PLATFORM_POSIX)
|
||||||
{
|
pthread_mutex_unlock(&mutex);
|
||||||
if (!pointer)
|
#endif
|
||||||
return;
|
|
||||||
|
return reinterpret_cast<char*>(ptr)+sizeof(Block);
|
||||||
Block* ptr = reinterpret_cast<Block*>(reinterpret_cast<char*>(pointer)-sizeof(Block));
|
}
|
||||||
if (ptr->magic != magic)
|
|
||||||
return;
|
void NzMemoryManager::Free(void* pointer, bool multi)
|
||||||
|
{
|
||||||
#if defined(NAZARA_PLATFORM_WINDOWS)
|
if (!pointer)
|
||||||
EnterCriticalSection(&mutex);
|
return;
|
||||||
#elif defined(NAZARA_PLATFORM_POSIX)
|
|
||||||
pthread_mutex_lock(&mutex);
|
Block* ptr = reinterpret_cast<Block*>(reinterpret_cast<char*>(pointer)-sizeof(Block));
|
||||||
#endif
|
if (ptr->magic != magic)
|
||||||
|
return;
|
||||||
if (ptr->array != multi)
|
|
||||||
{
|
#if defined(NAZARA_PLATFORM_WINDOWS)
|
||||||
char* time = TimeInfo();
|
EnterCriticalSection(&mutex);
|
||||||
|
#elif defined(NAZARA_PLATFORM_POSIX)
|
||||||
FILE* log = std::fopen(MLTFileName, "a");
|
pthread_mutex_lock(&mutex);
|
||||||
|
#endif
|
||||||
if (nextFreeFile)
|
|
||||||
{
|
if (ptr->array != multi)
|
||||||
if (multi)
|
{
|
||||||
std::fprintf(log, "%s Warning: delete[] after new at %s:%d\n", time, nextFreeFile, nextFreeLine);
|
char* time = TimeInfo();
|
||||||
else
|
|
||||||
std::fprintf(log, "%s Warning: delete after new[] at %s:%d\n", time, nextFreeFile, nextFreeLine);
|
FILE* log = std::fopen(MLTFileName, "a");
|
||||||
}
|
|
||||||
else
|
if (nextFreeFile)
|
||||||
{
|
{
|
||||||
if (multi)
|
if (multi)
|
||||||
std::fprintf(log, "%s Warning: delete[] after new at unknown position\n", time);
|
std::fprintf(log, "%s Warning: delete[] after new at %s:%d\n", time, nextFreeFile, nextFreeLine);
|
||||||
else
|
else
|
||||||
std::fprintf(log, "%s Warning: delete after new[] at unknown position\n", time);
|
std::fprintf(log, "%s Warning: delete after new[] at %s:%d\n", time, nextFreeFile, nextFreeLine);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
std::fclose(log);
|
{
|
||||||
|
if (multi)
|
||||||
std::free(time);
|
std::fprintf(log, "%s Warning: delete[] after new at unknown position\n", time);
|
||||||
}
|
else
|
||||||
|
std::fprintf(log, "%s Warning: delete after new[] at unknown position\n", time);
|
||||||
ptr->magic = 0;
|
}
|
||||||
ptr->prev->next = ptr->next;
|
|
||||||
ptr->next->prev = ptr->prev;
|
std::fclose(log);
|
||||||
|
|
||||||
std::free(ptr);
|
std::free(time);
|
||||||
|
}
|
||||||
nextFreeFile = nullptr;
|
|
||||||
nextFreeLine = 0;
|
ptr->magic = 0;
|
||||||
|
ptr->prev->next = ptr->next;
|
||||||
#if defined(NAZARA_PLATFORM_WINDOWS)
|
ptr->next->prev = ptr->prev;
|
||||||
LeaveCriticalSection(&mutex);
|
|
||||||
#elif defined(NAZARA_PLATFORM_POSIX)
|
std::free(ptr);
|
||||||
pthread_mutex_unlock(&mutex);
|
|
||||||
#endif
|
nextFreeFile = nullptr;
|
||||||
}
|
nextFreeLine = 0;
|
||||||
|
|
||||||
void NzMemoryManager::NextFree(const char* file, unsigned int line)
|
#if defined(NAZARA_PLATFORM_WINDOWS)
|
||||||
{
|
LeaveCriticalSection(&mutex);
|
||||||
nextFreeFile = file;
|
#elif defined(NAZARA_PLATFORM_POSIX)
|
||||||
nextFreeLine = line;
|
pthread_mutex_unlock(&mutex);
|
||||||
}
|
#endif
|
||||||
|
}
|
||||||
void NzMemoryManager::Initialize()
|
|
||||||
{
|
void NzMemoryManager::NextFree(const char* file, unsigned int line)
|
||||||
char* time = TimeInfo();
|
{
|
||||||
|
nextFreeFile = file;
|
||||||
FILE* file = std::fopen(MLTFileName, "w");
|
nextFreeLine = line;
|
||||||
std::fprintf(file, "%s ==============================\n", time);
|
}
|
||||||
std::fprintf(file, "%s Nazara Memory Leak Tracker \n", time);
|
|
||||||
std::fprintf(file, "%s ==============================\n", time);
|
void NzMemoryManager::Initialize()
|
||||||
std::fclose(file);
|
{
|
||||||
|
char* time = TimeInfo();
|
||||||
std::free(time);
|
|
||||||
|
FILE* file = std::fopen(MLTFileName, "w");
|
||||||
if (std::atexit(Uninitialize) != 0)
|
std::fprintf(file, "%s ==============================\n", time);
|
||||||
{
|
std::fprintf(file, "%s Nazara Memory Leak Tracker \n", time);
|
||||||
static NzMemoryManager manager;
|
std::fprintf(file, "%s ==============================\n", time);
|
||||||
}
|
std::fclose(file);
|
||||||
|
|
||||||
#ifdef NAZARA_PLATFORM_WINDOWS
|
std::free(time);
|
||||||
InitializeCriticalSection(&mutex);
|
|
||||||
#endif
|
if (std::atexit(Uninitialize) != 0)
|
||||||
|
{
|
||||||
initialized = true;
|
static NzMemoryManager manager;
|
||||||
}
|
}
|
||||||
|
|
||||||
char* NzMemoryManager::TimeInfo()
|
#ifdef NAZARA_PLATFORM_WINDOWS
|
||||||
{
|
InitializeCriticalSection(&mutex);
|
||||||
char* buffer = reinterpret_cast<char*>(std::malloc(23*sizeof(char)));
|
#endif
|
||||||
|
|
||||||
time_t currentTime = std::time(nullptr);
|
initialized = true;
|
||||||
std::strftime(buffer, 23, "%d/%m/%Y - %H:%M:%S:", std::localtime(¤tTime));
|
}
|
||||||
|
|
||||||
return buffer;
|
char* NzMemoryManager::TimeInfo()
|
||||||
}
|
{
|
||||||
|
char* buffer = reinterpret_cast<char*>(std::malloc(23*sizeof(char)));
|
||||||
void NzMemoryManager::Uninitialize()
|
|
||||||
{
|
time_t currentTime = std::time(nullptr);
|
||||||
#ifdef NAZARA_PLATFORM_WINDOWS
|
std::strftime(buffer, 23, "%d/%m/%Y - %H:%M:%S:", std::localtime(¤tTime));
|
||||||
DeleteCriticalSection(&mutex);
|
|
||||||
#endif
|
return buffer;
|
||||||
|
}
|
||||||
FILE* log = std::fopen(MLTFileName, "a");
|
|
||||||
|
void NzMemoryManager::Uninitialize()
|
||||||
char* time = TimeInfo();
|
{
|
||||||
|
#ifdef NAZARA_PLATFORM_WINDOWS
|
||||||
std::fprintf(log, "%s Application finished, checking leaks...\n", time);
|
DeleteCriticalSection(&mutex);
|
||||||
|
#endif
|
||||||
if (ptrList.next == &ptrList)
|
|
||||||
{
|
FILE* log = std::fopen(MLTFileName, "a");
|
||||||
std::fprintf(log, "%s ==============================\n", time);
|
|
||||||
std::fprintf(log, "%s No leak detected \n", time);
|
char* time = TimeInfo();
|
||||||
std::fprintf(log, "%s ==============================", time);
|
|
||||||
}
|
std::fprintf(log, "%s Application finished, checking leaks...\n", time);
|
||||||
else
|
|
||||||
{
|
if (ptrList.next == &ptrList)
|
||||||
std::fprintf(log, "%s ==============================\n", time);
|
{
|
||||||
std::fprintf(log, "%s Leaks have been detected \n", time);
|
std::fprintf(log, "%s ==============================\n", time);
|
||||||
std::fprintf(log, "%s ==============================\n\n", time);
|
std::fprintf(log, "%s No leak detected \n", time);
|
||||||
std::fputs("Leak list:\n", log);
|
std::fprintf(log, "%s ==============================", time);
|
||||||
|
}
|
||||||
Block* ptr = ptrList.next;
|
else
|
||||||
unsigned int count = 0;
|
{
|
||||||
unsigned int totalSize = 0;
|
std::fprintf(log, "%s ==============================\n", time);
|
||||||
while (ptr != &ptrList)
|
std::fprintf(log, "%s Leaks have been detected \n", time);
|
||||||
{
|
std::fprintf(log, "%s ==============================\n\n", time);
|
||||||
count++;
|
std::fputs("Leak list:\n", log);
|
||||||
totalSize += ptr->size;
|
|
||||||
if (ptr->file)
|
Block* ptr = ptrList.next;
|
||||||
std::fprintf(log, "-0x%p -> %d bytes allocated at %s:%d\n", reinterpret_cast<char*>(ptr)+sizeof(Block), ptr->size, ptr->file, ptr->line);
|
unsigned int count = 0;
|
||||||
else
|
unsigned int totalSize = 0;
|
||||||
std::fprintf(log, "-0x%p -> %d bytes allocated at unknown position\n", reinterpret_cast<char*>(ptr)+sizeof(Block), ptr->size);
|
while (ptr != &ptrList)
|
||||||
|
{
|
||||||
void* pointer = ptr;
|
count++;
|
||||||
ptr = ptr->next;
|
totalSize += ptr->size;
|
||||||
std::free(pointer);
|
if (ptr->file)
|
||||||
}
|
std::fprintf(log, "-0x%p -> %d bytes allocated at %s:%d\n", reinterpret_cast<char*>(ptr)+sizeof(Block), ptr->size, ptr->file, ptr->line);
|
||||||
|
else
|
||||||
std::fprintf(log, "\n%d blocks leaked (%d bytes)", count, totalSize);
|
std::fprintf(log, "-0x%p -> %d bytes allocated at unknown position\n", reinterpret_cast<char*>(ptr)+sizeof(Block), ptr->size);
|
||||||
}
|
|
||||||
|
void* pointer = ptr;
|
||||||
std::free(time);
|
ptr = ptr->next;
|
||||||
std::fclose(log);
|
std::free(pointer);
|
||||||
}
|
}
|
||||||
|
|
||||||
void* operator new(std::size_t size, const char* file, unsigned int line)
|
std::fprintf(log, "\n%d blocks leaked (%d bytes)", count, totalSize);
|
||||||
{
|
}
|
||||||
return NzMemoryManager::Allocate(size, false, file, line);
|
|
||||||
}
|
std::free(time);
|
||||||
|
std::fclose(log);
|
||||||
void* operator new[](std::size_t size, const char* file, unsigned int line)
|
}
|
||||||
{
|
|
||||||
return NzMemoryManager::Allocate(size, true, file, line);
|
void* operator new(std::size_t size, const char* file, unsigned int line)
|
||||||
}
|
{
|
||||||
|
return NzMemoryManager::Allocate(size, false, file, line);
|
||||||
void operator delete(void* ptr, const char* file, unsigned int line) throw()
|
}
|
||||||
{
|
|
||||||
NzMemoryManager::NextFree(file, line);
|
void* operator new[](std::size_t size, const char* file, unsigned int line)
|
||||||
NzMemoryManager::Free(ptr, false);
|
{
|
||||||
}
|
return NzMemoryManager::Allocate(size, true, file, line);
|
||||||
|
}
|
||||||
void operator delete[](void* ptr, const char* file, unsigned int line) throw()
|
|
||||||
{
|
void operator delete(void* ptr, const char* file, unsigned int line) throw()
|
||||||
NzMemoryManager::NextFree(file, line);
|
{
|
||||||
NzMemoryManager::Free(ptr, true);
|
NzMemoryManager::NextFree(file, line);
|
||||||
}
|
NzMemoryManager::Free(ptr, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void operator delete[](void* ptr, const char* file, unsigned int line) throw()
|
||||||
|
{
|
||||||
|
NzMemoryManager::NextFree(file, line);
|
||||||
|
NzMemoryManager::Free(ptr, true);
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,54 +1,138 @@
|
||||||
// Copyright (C) 2012 Jérôme Leclercq
|
// Copyright (C) 2012 Jérôme Leclercq
|
||||||
// This file is part of the "Nazara Engine - Core module"
|
// This file is part of the "Nazara Engine - Core module"
|
||||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||||
|
|
||||||
#include <Nazara/Core/Resource.hpp>
|
#include <Nazara/Core/Resource.hpp>
|
||||||
#include <Nazara/Core/Config.hpp>
|
#include <Nazara/Core/Config.hpp>
|
||||||
#include <Nazara/Core/Error.hpp>
|
#include <Nazara/Core/Error.hpp>
|
||||||
#include <Nazara/Core/Debug.hpp>
|
#include <Nazara/Core/ResourceListener.hpp>
|
||||||
|
#include <Nazara/Core/Debug.hpp>
|
||||||
NzResource::NzResource(bool persistent) :
|
|
||||||
m_resourcePersistent(persistent),
|
NzResource::NzResource(bool persistent) :
|
||||||
m_resourceReferenceCount(0)
|
m_resourcePersistent(persistent),
|
||||||
{
|
m_resourceReferenceCount(0)
|
||||||
}
|
{
|
||||||
|
}
|
||||||
NzResource::NzResource(const NzResource& resource) :
|
|
||||||
m_resourcePersistent(resource.m_resourcePersistent),
|
NzResource::NzResource(const NzResource& resource) :
|
||||||
m_resourceReferenceCount(0)
|
m_resourcePersistent(resource.m_resourcePersistent),
|
||||||
{
|
m_resourceReferenceCount(0)
|
||||||
}
|
{
|
||||||
|
}
|
||||||
NzResource::~NzResource() = default;
|
|
||||||
|
NzResource::~NzResource()
|
||||||
void NzResource::AddResourceReference() const
|
{
|
||||||
{
|
EnsureResourceListenerUpdate();
|
||||||
m_resourceReferenceCount++;
|
|
||||||
}
|
for (auto it = m_resourceListenersCache.begin(); it != m_resourceListenersCache.end(); ++it)
|
||||||
|
(*it).listener->OnResourceReleased(this, (*it).index);
|
||||||
bool NzResource::IsPersistent() const
|
}
|
||||||
{
|
|
||||||
return m_resourcePersistent;
|
void NzResource::AddResourceListener(NzResourceListener* listener, int index) const
|
||||||
}
|
{
|
||||||
|
NazaraLock(m_mutex)
|
||||||
void NzResource::RemoveResourceReference() const
|
|
||||||
{
|
if (m_resourceListeners.insert(NzResourceEntry(listener, index)).second)
|
||||||
#if NAZARA_CORE_SAFE
|
{
|
||||||
if (m_resourceReferenceCount == 0)
|
m_resourceListenerUpdated = false;
|
||||||
{
|
|
||||||
NazaraError("Impossible to remove reference (Ref. counter is already 0)");
|
// AddResourceReference()
|
||||||
return;
|
m_resourceReferenceCount++;
|
||||||
}
|
}
|
||||||
#endif
|
}
|
||||||
|
|
||||||
if (--m_resourceReferenceCount == 0 && !m_resourcePersistent)
|
void NzResource::AddResourceReference() const
|
||||||
delete this;
|
{
|
||||||
}
|
NazaraLock(m_mutex)
|
||||||
|
|
||||||
void NzResource::SetPersistent(bool persistent)
|
m_resourceReferenceCount++;
|
||||||
{
|
}
|
||||||
m_resourcePersistent = persistent;
|
|
||||||
|
bool NzResource::IsPersistent() const
|
||||||
if (!persistent && m_resourceReferenceCount == 0)
|
{
|
||||||
delete this;
|
NazaraLock(m_mutex)
|
||||||
}
|
|
||||||
|
return m_resourcePersistent;
|
||||||
|
}
|
||||||
|
|
||||||
|
void NzResource::RemoveResourceListener(NzResourceListener* listener) const
|
||||||
|
{
|
||||||
|
NazaraLock(m_mutex)
|
||||||
|
|
||||||
|
if (m_resourceListeners.erase(listener) != 0)
|
||||||
|
m_resourceListenerUpdated = false;
|
||||||
|
else
|
||||||
|
NazaraError(NzString::Pointer(listener) + " is not listening to " + NzString::Pointer(this));
|
||||||
|
|
||||||
|
RemoveResourceReference();
|
||||||
|
}
|
||||||
|
|
||||||
|
void NzResource::RemoveResourceReference() const
|
||||||
|
{
|
||||||
|
NazaraMutexLock(m_mutex);
|
||||||
|
|
||||||
|
#if NAZARA_CORE_SAFE
|
||||||
|
if (m_resourceReferenceCount == 0)
|
||||||
|
{
|
||||||
|
NazaraError("Impossible to remove reference (Ref. counter is already 0)");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (--m_resourceReferenceCount == 0 && !m_resourcePersistent)
|
||||||
|
{
|
||||||
|
NazaraMutexUnlock(m_mutex);
|
||||||
|
delete this;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
NazaraMutexUnlock(m_mutex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void NzResource::SetPersistent(bool persistent)
|
||||||
|
{
|
||||||
|
NazaraMutexLock(m_mutex);
|
||||||
|
|
||||||
|
m_resourcePersistent = persistent;
|
||||||
|
|
||||||
|
if (!persistent && m_resourceReferenceCount == 0)
|
||||||
|
{
|
||||||
|
NazaraMutexUnlock(m_mutex);
|
||||||
|
delete this;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
NazaraMutexUnlock(m_mutex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void NzResource::NotifyCreated()
|
||||||
|
{
|
||||||
|
NazaraLock(m_mutex)
|
||||||
|
|
||||||
|
EnsureResourceListenerUpdate();
|
||||||
|
|
||||||
|
for (auto it = m_resourceListenersCache.begin(); it != m_resourceListenersCache.end(); ++it)
|
||||||
|
(*it).listener->OnResourceCreated(this, (*it).index);
|
||||||
|
}
|
||||||
|
|
||||||
|
void NzResource::NotifyDestroy()
|
||||||
|
{
|
||||||
|
NazaraLock(m_mutex)
|
||||||
|
|
||||||
|
EnsureResourceListenerUpdate();
|
||||||
|
|
||||||
|
for (auto it = m_resourceListenersCache.begin(); it != m_resourceListenersCache.end(); ++it)
|
||||||
|
(*it).listener->OnResourceDestroy(this, (*it).index);
|
||||||
|
}
|
||||||
|
|
||||||
|
void NzResource::EnsureResourceListenerUpdate() const
|
||||||
|
{
|
||||||
|
// Déjà bloqué par une mutex
|
||||||
|
if (!m_resourceListenerUpdated)
|
||||||
|
{
|
||||||
|
m_resourceListenersCache = m_resourceListeners;
|
||||||
|
m_resourceListenerUpdated = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,26 @@
|
||||||
|
// Copyright (C) 2012 Jérôme Leclercq
|
||||||
|
// This file is part of the "Nazara Engine - Core module"
|
||||||
|
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||||
|
|
||||||
|
#include <Nazara/Core/ResourceListener.hpp>
|
||||||
|
#include <Nazara/Core/Debug.hpp>
|
||||||
|
|
||||||
|
NzResourceListener::~NzResourceListener() = default;
|
||||||
|
|
||||||
|
void NzResourceListener::OnResourceCreated(const NzResource* resource, int index)
|
||||||
|
{
|
||||||
|
NazaraUnused(resource);
|
||||||
|
NazaraUnused(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
void NzResourceListener::OnResourceDestroy(const NzResource* resource, int index)
|
||||||
|
{
|
||||||
|
NazaraUnused(resource);
|
||||||
|
NazaraUnused(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
void NzResourceListener::OnResourceReleased(const NzResource* resource, int index)
|
||||||
|
{
|
||||||
|
NazaraUnused(resource);
|
||||||
|
NazaraUnused(index);
|
||||||
|
}
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -1,355 +1,359 @@
|
||||||
// Copyright (C) 2012 Jérôme Leclercq
|
// Copyright (C) 2012 Jérôme Leclercq
|
||||||
// This file is part of the "Nazara Engine - Renderer module"
|
// This file is part of the "Nazara Engine - Renderer module"
|
||||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||||
|
|
||||||
#include <Nazara/Renderer/OpenGL.hpp>
|
#include <Nazara/Renderer/OpenGL.hpp>
|
||||||
#include <Nazara/Renderer/Context.hpp>
|
#include <Nazara/Renderer/Context.hpp>
|
||||||
#include <Nazara/Core/Error.hpp>
|
#include <Nazara/Core/Error.hpp>
|
||||||
#include <Nazara/Core/Log.hpp>
|
#include <Nazara/Core/Log.hpp>
|
||||||
#include <Nazara/Core/StringStream.hpp>
|
#include <Nazara/Core/StringStream.hpp>
|
||||||
#include <Nazara/Renderer/Config.hpp>
|
#include <Nazara/Renderer/Config.hpp>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#if defined(NAZARA_PLATFORM_WINDOWS)
|
#if defined(NAZARA_PLATFORM_WINDOWS)
|
||||||
#include <Nazara/Renderer/Win32/ContextImpl.hpp>
|
#include <Nazara/Renderer/Win32/ContextImpl.hpp>
|
||||||
#elif defined(NAZARA_PLATFORM_LINUX)
|
#elif defined(NAZARA_PLATFORM_LINUX)
|
||||||
#include <Nazara/Renderer/Linux/ContextImpl.hpp>
|
#include <Nazara/Renderer/Linux/ContextImpl.hpp>
|
||||||
#else
|
#else
|
||||||
#error Lack of implementation: Context
|
#error Lack of implementation: Context
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <Nazara/Renderer/Debug.hpp>
|
#include <Nazara/Renderer/Debug.hpp>
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
NAZARA_THREADLOCAL NzContext* currentContext = nullptr;
|
NAZARA_THREADLOCAL NzContext* currentContext = nullptr;
|
||||||
NAZARA_THREADLOCAL NzContext* threadContext = nullptr;
|
NAZARA_THREADLOCAL NzContext* threadContext = nullptr;
|
||||||
|
|
||||||
std::vector<NzContext*> contexts;
|
std::vector<NzContext*> contexts;
|
||||||
|
|
||||||
void CALLBACK DebugCallback(unsigned int source, unsigned int type, unsigned int id, unsigned int severity, int length, const char* message, void* userParam)
|
void CALLBACK DebugCallback(unsigned int source, unsigned int type, unsigned int id, unsigned int severity, int length, const char* message, void* userParam)
|
||||||
{
|
{
|
||||||
NazaraUnused(length);
|
NazaraUnused(length);
|
||||||
|
|
||||||
NzStringStream ss;
|
NzStringStream ss;
|
||||||
ss << "OpenGL debug message (ID: 0x" << NzString::Number(id, 16) << "):\n";
|
ss << "OpenGL debug message (ID: 0x" << NzString::Number(id, 16) << "):\n";
|
||||||
ss << "Sent by context: " << userParam;
|
ss << "Sent by context: " << userParam;
|
||||||
ss << "\n-Source: ";
|
ss << "\n-Source: ";
|
||||||
switch (source)
|
switch (source)
|
||||||
{
|
{
|
||||||
case GL_DEBUG_SOURCE_API_ARB:
|
case GL_DEBUG_SOURCE_API_ARB:
|
||||||
ss << "OpenGL";
|
ss << "OpenGL";
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GL_DEBUG_SOURCE_WINDOW_SYSTEM_ARB:
|
case GL_DEBUG_SOURCE_WINDOW_SYSTEM_ARB:
|
||||||
ss << "Operating system";
|
ss << "Operating system";
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GL_DEBUG_SOURCE_SHADER_COMPILER_ARB:
|
case GL_DEBUG_SOURCE_SHADER_COMPILER_ARB:
|
||||||
ss << "Shader compiler";
|
ss << "Shader compiler";
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GL_DEBUG_SOURCE_THIRD_PARTY_ARB:
|
case GL_DEBUG_SOURCE_THIRD_PARTY_ARB:
|
||||||
ss << "Shader compiler";
|
ss << "Shader compiler";
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GL_DEBUG_SOURCE_APPLICATION_ARB:
|
case GL_DEBUG_SOURCE_APPLICATION_ARB:
|
||||||
ss << "Application";
|
ss << "Application";
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GL_DEBUG_SOURCE_OTHER_ARB:
|
case GL_DEBUG_SOURCE_OTHER_ARB:
|
||||||
ss << "Other";
|
ss << "Other";
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
// Peut être rajouté par une extension
|
// Peut être rajouté par une extension
|
||||||
ss << "Unknown";
|
ss << "Unknown";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
ss << '\n';
|
ss << '\n';
|
||||||
|
|
||||||
ss << "-Type: ";
|
ss << "-Type: ";
|
||||||
switch (type)
|
switch (type)
|
||||||
{
|
{
|
||||||
case GL_DEBUG_TYPE_ERROR_ARB:
|
case GL_DEBUG_TYPE_ERROR_ARB:
|
||||||
ss << "Error";
|
ss << "Error";
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_ARB:
|
case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_ARB:
|
||||||
ss << "Deprecated behavior";
|
ss << "Deprecated behavior";
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_ARB:
|
case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_ARB:
|
||||||
ss << "Undefined behavior";
|
ss << "Undefined behavior";
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GL_DEBUG_TYPE_PORTABILITY_ARB:
|
case GL_DEBUG_TYPE_PORTABILITY_ARB:
|
||||||
ss << "Portability";
|
ss << "Portability";
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GL_DEBUG_TYPE_PERFORMANCE_ARB:
|
case GL_DEBUG_TYPE_PERFORMANCE_ARB:
|
||||||
ss << "Performance";
|
ss << "Performance";
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GL_DEBUG_TYPE_OTHER_ARB:
|
case GL_DEBUG_TYPE_OTHER_ARB:
|
||||||
ss << "Other";
|
ss << "Other";
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
// Peut être rajouté par une extension
|
// Peut être rajouté par une extension
|
||||||
ss << "Unknown";
|
ss << "Unknown";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
ss << '\n';
|
ss << '\n';
|
||||||
|
|
||||||
ss << "-Severity: ";
|
ss << "-Severity: ";
|
||||||
switch (severity)
|
switch (severity)
|
||||||
{
|
{
|
||||||
case GL_DEBUG_SEVERITY_HIGH_ARB:
|
case GL_DEBUG_SEVERITY_HIGH_ARB:
|
||||||
ss << "High";
|
ss << "High";
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GL_DEBUG_SEVERITY_MEDIUM_ARB:
|
case GL_DEBUG_SEVERITY_MEDIUM_ARB:
|
||||||
ss << "Medium";
|
ss << "Medium";
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GL_DEBUG_SEVERITY_LOW_ARB:
|
case GL_DEBUG_SEVERITY_LOW_ARB:
|
||||||
ss << "Low";
|
ss << "Low";
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
// Peut être rajouté par une extension
|
// Peut être rajouté par une extension
|
||||||
ss << "Unknown";
|
ss << "Unknown";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
ss << '\n';
|
ss << '\n';
|
||||||
|
|
||||||
ss << "Message: " << message << '\n';
|
ss << "Message: " << message << '\n';
|
||||||
|
|
||||||
NazaraNotice(ss);
|
NazaraNotice(ss);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
NzContext::NzContext() :
|
NzContext::NzContext() :
|
||||||
m_impl(nullptr)
|
m_impl(nullptr)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
NzContext::~NzContext()
|
NzContext::~NzContext()
|
||||||
{
|
{
|
||||||
Destroy();
|
Destroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NzContext::Create(const NzContextParameters& parameters)
|
bool NzContext::Create(const NzContextParameters& parameters)
|
||||||
{
|
{
|
||||||
Destroy();
|
Destroy();
|
||||||
|
|
||||||
m_parameters = parameters;
|
m_parameters = parameters;
|
||||||
if (m_parameters.shared && !m_parameters.shareContext)
|
if (m_parameters.shared && !m_parameters.shareContext)
|
||||||
m_parameters.shareContext = s_reference;
|
m_parameters.shareContext = s_reference;
|
||||||
|
|
||||||
m_impl = new NzContextImpl;
|
m_impl = new NzContextImpl;
|
||||||
if (!m_impl->Create(m_parameters))
|
if (!m_impl->Create(m_parameters))
|
||||||
{
|
{
|
||||||
NazaraError("Failed to create context implementation");
|
NazaraError("Failed to create context implementation");
|
||||||
delete m_impl;
|
delete m_impl;
|
||||||
m_impl = nullptr;
|
m_impl = nullptr;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!m_impl->Activate())
|
if (!m_impl->Activate())
|
||||||
{
|
{
|
||||||
NazaraError("Failed to activate context");
|
NazaraError("Failed to activate context");
|
||||||
|
|
||||||
m_impl->Destroy();
|
m_impl->Destroy();
|
||||||
delete m_impl;
|
delete m_impl;
|
||||||
m_impl = nullptr;
|
m_impl = nullptr;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_parameters.antialiasingLevel > 0)
|
if (m_parameters.antialiasingLevel > 0)
|
||||||
glEnable(GL_MULTISAMPLE);
|
glEnable(GL_MULTISAMPLE);
|
||||||
|
|
||||||
if (NzOpenGL::IsSupported(NzOpenGL::DebugOutput) && m_parameters.debugMode)
|
if (NzOpenGL::IsSupported(nzOpenGLExtension_DebugOutput) && m_parameters.debugMode)
|
||||||
{
|
{
|
||||||
glDebugMessageCallback(&DebugCallback, this);
|
glDebugMessageCallback(&DebugCallback, this);
|
||||||
|
|
||||||
#ifdef NAZARA_DEBUG
|
#ifdef NAZARA_DEBUG
|
||||||
glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB);
|
glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
NotifyCreated();
|
||||||
}
|
|
||||||
|
return true;
|
||||||
void NzContext::Destroy()
|
}
|
||||||
{
|
|
||||||
if (m_impl)
|
void NzContext::Destroy()
|
||||||
{
|
{
|
||||||
if (currentContext == this)
|
if (m_impl)
|
||||||
NzContextImpl::Desactivate();
|
{
|
||||||
|
NotifyDestroy();
|
||||||
m_impl->Destroy();
|
|
||||||
delete m_impl;
|
if (currentContext == this)
|
||||||
m_impl = nullptr;
|
NzContextImpl::Desactivate();
|
||||||
}
|
|
||||||
}
|
m_impl->Destroy();
|
||||||
|
delete m_impl;
|
||||||
const NzContextParameters& NzContext::GetParameters() const
|
m_impl = nullptr;
|
||||||
{
|
}
|
||||||
#ifdef NAZARA_RENDERER_SAFE
|
}
|
||||||
if (!m_impl)
|
|
||||||
NazaraError("No context has been created");
|
const NzContextParameters& NzContext::GetParameters() const
|
||||||
#endif
|
{
|
||||||
|
#ifdef NAZARA_RENDERER_SAFE
|
||||||
return m_parameters;
|
if (!m_impl)
|
||||||
}
|
NazaraError("No context has been created");
|
||||||
|
#endif
|
||||||
bool NzContext::IsActive() const
|
|
||||||
{
|
return m_parameters;
|
||||||
#ifdef NAZARA_RENDERER_SAFE
|
}
|
||||||
if (!m_impl)
|
|
||||||
{
|
bool NzContext::IsActive() const
|
||||||
NazaraError("No context has been created");
|
{
|
||||||
return false;
|
#ifdef NAZARA_RENDERER_SAFE
|
||||||
}
|
if (!m_impl)
|
||||||
#endif
|
{
|
||||||
|
NazaraError("No context has been created");
|
||||||
return currentContext == this;
|
return false;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
bool NzContext::SetActive(bool active)
|
|
||||||
{
|
return currentContext == this;
|
||||||
#ifdef NAZARA_RENDERER_SAFE
|
}
|
||||||
if (!m_impl)
|
|
||||||
{
|
bool NzContext::SetActive(bool active)
|
||||||
NazaraError("No context has been created");
|
{
|
||||||
return false;
|
#ifdef NAZARA_RENDERER_SAFE
|
||||||
}
|
if (!m_impl)
|
||||||
#endif
|
{
|
||||||
|
NazaraError("No context has been created");
|
||||||
// Si le contexte est déjà activé/désactivé
|
return false;
|
||||||
if ((currentContext == this) == active)
|
}
|
||||||
return true;
|
#endif
|
||||||
|
|
||||||
if (active)
|
// Si le contexte est déjà activé/désactivé
|
||||||
{
|
if ((currentContext == this) == active)
|
||||||
if (!m_impl->Activate())
|
return true;
|
||||||
return false;
|
|
||||||
|
if (active)
|
||||||
currentContext = this;
|
{
|
||||||
}
|
if (!m_impl->Activate())
|
||||||
else
|
return false;
|
||||||
{
|
|
||||||
if (!NzContextImpl::Desactivate())
|
currentContext = this;
|
||||||
return false;
|
}
|
||||||
|
else
|
||||||
currentContext = nullptr;
|
{
|
||||||
}
|
if (!NzContextImpl::Desactivate())
|
||||||
|
return false;
|
||||||
return true;
|
|
||||||
}
|
currentContext = nullptr;
|
||||||
|
}
|
||||||
void NzContext::SwapBuffers()
|
|
||||||
{
|
return true;
|
||||||
#ifdef NAZARA_RENDERER_SAFE
|
}
|
||||||
if (!m_impl)
|
|
||||||
{
|
void NzContext::SwapBuffers()
|
||||||
NazaraError("No context has been created");
|
{
|
||||||
return;
|
#ifdef NAZARA_RENDERER_SAFE
|
||||||
}
|
if (!m_impl)
|
||||||
|
{
|
||||||
if (!m_parameters.doubleBuffered)
|
NazaraError("No context has been created");
|
||||||
{
|
return;
|
||||||
NazaraError("Context is not double buffered");
|
}
|
||||||
return;
|
|
||||||
}
|
if (!m_parameters.doubleBuffered)
|
||||||
#endif
|
{
|
||||||
|
NazaraError("Context is not double buffered");
|
||||||
m_impl->SwapBuffers();
|
return;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
bool NzContext::EnsureContext()
|
|
||||||
{
|
m_impl->SwapBuffers();
|
||||||
if (!currentContext)
|
}
|
||||||
{
|
|
||||||
if (!threadContext)
|
bool NzContext::EnsureContext()
|
||||||
{
|
{
|
||||||
NzContext* context = new NzContext;
|
if (!currentContext)
|
||||||
if (!context->Create())
|
{
|
||||||
{
|
if (!threadContext)
|
||||||
NazaraError("Failed to create context");
|
{
|
||||||
delete context;
|
NzContext* context = new NzContext;
|
||||||
|
if (!context->Create())
|
||||||
return false;
|
{
|
||||||
}
|
NazaraError("Failed to create context");
|
||||||
|
delete context;
|
||||||
contexts.push_back(context);
|
|
||||||
|
return false;
|
||||||
threadContext = context;
|
}
|
||||||
}
|
|
||||||
|
contexts.push_back(context);
|
||||||
if (!threadContext->SetActive(true))
|
|
||||||
{
|
threadContext = context;
|
||||||
NazaraError("Failed to active thread context");
|
}
|
||||||
return false;
|
|
||||||
}
|
if (!threadContext->SetActive(true))
|
||||||
}
|
{
|
||||||
|
NazaraError("Failed to active thread context");
|
||||||
return true;
|
return false;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
NzContext* NzContext::GetCurrent()
|
|
||||||
{
|
return true;
|
||||||
return currentContext;
|
}
|
||||||
}
|
|
||||||
|
NzContext* NzContext::GetCurrent()
|
||||||
const NzContext* NzContext::GetReference()
|
{
|
||||||
{
|
return currentContext;
|
||||||
return s_reference;
|
}
|
||||||
}
|
|
||||||
|
const NzContext* NzContext::GetReference()
|
||||||
NzContext* NzContext::GetThreadContext()
|
{
|
||||||
{
|
return s_reference;
|
||||||
EnsureContext();
|
}
|
||||||
|
|
||||||
return threadContext;
|
NzContext* NzContext::GetThreadContext()
|
||||||
}
|
{
|
||||||
|
EnsureContext();
|
||||||
bool NzContext::Initialize()
|
|
||||||
{
|
return threadContext;
|
||||||
NzContextParameters parameters;
|
}
|
||||||
// parameters.compatibilityProfile = true;
|
|
||||||
parameters.shared = false; // Difficile de partager le contexte de référence avec lui-même
|
bool NzContext::Initialize()
|
||||||
|
{
|
||||||
s_reference = new NzContext;
|
NzContextParameters parameters;
|
||||||
if (!s_reference->Create(parameters))
|
// parameters.compatibilityProfile = true;
|
||||||
{
|
parameters.shared = false; // Difficile de partager le contexte de référence avec lui-même
|
||||||
delete s_reference;
|
|
||||||
s_reference = nullptr;
|
s_reference = new NzContext;
|
||||||
|
if (!s_reference->Create(parameters))
|
||||||
return false;
|
{
|
||||||
}
|
delete s_reference;
|
||||||
|
s_reference = nullptr;
|
||||||
// Le contexte de référence doit rester désactivé pour le partage
|
|
||||||
s_reference->SetActive(false);
|
return false;
|
||||||
|
}
|
||||||
NzContextParameters::defaultShareContext = s_reference;
|
|
||||||
|
// Le contexte de référence doit rester désactivé pour le partage
|
||||||
return true;
|
s_reference->SetActive(false);
|
||||||
}
|
|
||||||
|
NzContextParameters::defaultShareContext = s_reference;
|
||||||
void NzContext::Uninitialize()
|
|
||||||
{
|
return true;
|
||||||
for (NzContext* context : contexts)
|
}
|
||||||
delete context;
|
|
||||||
|
void NzContext::Uninitialize()
|
||||||
contexts.clear(); // On supprime tous les contextes créés
|
{
|
||||||
|
for (NzContext* context : contexts)
|
||||||
delete s_reference;
|
delete context;
|
||||||
s_reference = nullptr;
|
|
||||||
}
|
contexts.clear(); // On supprime tous les contextes créés
|
||||||
|
|
||||||
NzContext* NzContext::s_reference = nullptr;
|
delete s_reference;
|
||||||
|
s_reference = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
NzContext* NzContext::s_reference = nullptr;
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -1,73 +1,81 @@
|
||||||
// Copyright (C) 2012 Jérôme Leclercq
|
// Copyright (C) 2012 Jérôme Leclercq
|
||||||
// This file is part of the "Nazara Engine - Renderer module"
|
// This file is part of the "Nazara Engine - Renderer module"
|
||||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#ifndef NAZARA_GLSLSHADER_HPP
|
#ifndef NAZARA_GLSLSHADER_HPP
|
||||||
#define NAZARA_GLSLSHADER_HPP
|
#define NAZARA_GLSLSHADER_HPP
|
||||||
|
|
||||||
#include <Nazara/Core/String.hpp>
|
#include <Nazara/Core/ResourceListener.hpp>
|
||||||
#include <Nazara/Renderer/OpenGL.hpp>
|
#include <Nazara/Core/String.hpp>
|
||||||
#include <Nazara/Renderer/Shader.hpp>
|
#include <Nazara/Renderer/OpenGL.hpp>
|
||||||
#include <Nazara/Renderer/ShaderImpl.hpp>
|
#include <Nazara/Renderer/Shader.hpp>
|
||||||
#include <map>
|
#include <Nazara/Renderer/ShaderImpl.hpp>
|
||||||
|
#include <map>
|
||||||
class NzGLSLShader : public NzShaderImpl
|
|
||||||
{
|
class NzResource;
|
||||||
public:
|
|
||||||
NzGLSLShader(NzShader* parent);
|
class NzGLSLShader : public NzShaderImpl, NzResourceListener
|
||||||
~NzGLSLShader();
|
{
|
||||||
|
public:
|
||||||
bool Bind();
|
NzGLSLShader(NzShader* parent);
|
||||||
bool BindTextures();
|
~NzGLSLShader();
|
||||||
|
|
||||||
bool Compile();
|
bool Bind();
|
||||||
|
bool BindTextures();
|
||||||
bool Create();
|
|
||||||
void Destroy();
|
bool Compile();
|
||||||
|
|
||||||
NzString GetLog() const;
|
bool Create();
|
||||||
nzShaderLanguage GetLanguage() const;
|
void Destroy();
|
||||||
NzString GetSourceCode(nzShaderType type) const;
|
|
||||||
int GetUniformLocation(const NzString& name) const;
|
NzString GetLog() const;
|
||||||
|
nzShaderLanguage GetLanguage() const;
|
||||||
bool IsLoaded(nzShaderType type) const;
|
NzString GetSourceCode(nzShaderType type) const;
|
||||||
|
int GetUniformLocation(const NzString& name) const;
|
||||||
bool Load(nzShaderType type, const NzString& source);
|
|
||||||
bool Lock();
|
bool IsLoaded(nzShaderType type) const;
|
||||||
|
|
||||||
bool SendBoolean(int location, bool value);
|
bool Load(nzShaderType type, const NzString& source);
|
||||||
bool SendDouble(int location, double value);
|
bool Lock();
|
||||||
bool SendFloat(int location, float value);
|
|
||||||
bool SendInteger(int location, int value);
|
bool SendBoolean(int location, bool value);
|
||||||
bool SendMatrix(int location, const NzMatrix4d& matrix);
|
bool SendDouble(int location, double value);
|
||||||
bool SendMatrix(int location, const NzMatrix4f& matrix);
|
bool SendFloat(int location, float value);
|
||||||
bool SendTexture(int location, const NzTexture* texture);
|
bool SendInteger(int location, int value);
|
||||||
bool SendVector(int location, const NzVector2d& vector);
|
bool SendMatrix(int location, const NzMatrix4d& matrix);
|
||||||
bool SendVector(int location, const NzVector2f& vector);
|
bool SendMatrix(int location, const NzMatrix4f& matrix);
|
||||||
bool SendVector(int location, const NzVector3d& vector);
|
bool SendTexture(int location, const NzTexture* texture);
|
||||||
bool SendVector(int location, const NzVector3f& vector);
|
bool SendVector(int location, const NzVector2d& vector);
|
||||||
bool SendVector(int location, const NzVector4d& vector);
|
bool SendVector(int location, const NzVector2f& vector);
|
||||||
bool SendVector(int location, const NzVector4f& vector);
|
bool SendVector(int location, const NzVector3d& vector);
|
||||||
|
bool SendVector(int location, const NzVector3f& vector);
|
||||||
void Unbind();
|
bool SendVector(int location, const NzVector4d& vector);
|
||||||
void Unlock();
|
bool SendVector(int location, const NzVector4f& vector);
|
||||||
|
|
||||||
private:
|
void Unbind();
|
||||||
struct TextureSlot
|
void Unlock();
|
||||||
{
|
|
||||||
bool updated = false;
|
private:
|
||||||
nzUInt8 unit;
|
void OnResourceCreated(const NzResource* resource, int index) override;
|
||||||
const NzTexture* texture;
|
void OnResourceDestroy(const NzResource* resource, int index) override;
|
||||||
};
|
void OnResourceReleased(const NzResource* resource, int index) override;
|
||||||
|
|
||||||
mutable std::map<NzString, GLint> m_idCache;
|
struct TextureSlot
|
||||||
std::map<GLint, TextureSlot> m_textures;
|
{
|
||||||
GLuint m_program;
|
bool enabled;
|
||||||
GLuint m_shaders[nzShaderType_Max+1];
|
bool updated = false;
|
||||||
NzShader* m_parent;
|
nzUInt8 unit;
|
||||||
NzString m_log;
|
const NzTexture* texture;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // NAZARA_GLSLSHADER_HPPs
|
mutable std::map<NzString, GLint> m_idCache;
|
||||||
|
std::map<GLint, TextureSlot> m_textures;
|
||||||
|
GLuint m_program;
|
||||||
|
GLuint m_shaders[nzShaderType_Max+1];
|
||||||
|
NzShader* m_parent;
|
||||||
|
NzString m_log;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // NAZARA_GLSLSHADER_HPPs
|
||||||
|
|
|
||||||
|
|
@ -1,250 +1,218 @@
|
||||||
// Copyright (C) 2012 Jérôme Leclercq
|
// Copyright (C) 2012 Jérôme Leclercq
|
||||||
// This file is part of the "Nazara Engine - Renderer module"
|
// This file is part of the "Nazara Engine - Renderer module"
|
||||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||||
|
|
||||||
#include <Nazara/Renderer/OpenGL.hpp>
|
#include <Nazara/Renderer/OpenGL.hpp>
|
||||||
#include <Nazara/Renderer/HardwareBuffer.hpp>
|
#include <Nazara/Renderer/HardwareBuffer.hpp>
|
||||||
#include <Nazara/Core/Error.hpp>
|
#include <Nazara/Core/Error.hpp>
|
||||||
#include <Nazara/Renderer/Context.hpp>
|
#include <Nazara/Renderer/Context.hpp>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include <Nazara/Renderer/Debug.hpp>
|
#include <Nazara/Renderer/Debug.hpp>
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
GLenum bufferLock[] = {
|
using LockRoutine = nzUInt8* (*)(nzBufferType type, nzBufferAccess access, unsigned int offset, unsigned int size);
|
||||||
GL_WRITE_ONLY, // nzBufferAccess_DiscardAndWrite
|
|
||||||
GL_READ_ONLY, // nzBufferAccess_ReadOnly
|
nzUInt8* LockBuffer(nzBufferType type, nzBufferAccess access, unsigned int offset, unsigned int size)
|
||||||
GL_READ_WRITE, // nzBufferAccess_ReadWrite
|
{
|
||||||
GL_WRITE_ONLY // nzBufferAccess_WriteOnly
|
NazaraUnused(size);
|
||||||
};
|
|
||||||
|
if (access == nzBufferAccess_DiscardAndWrite)
|
||||||
GLenum bufferLockRange[] = {
|
{
|
||||||
GL_MAP_INVALIDATE_BUFFER_BIT | GL_MAP_WRITE_BIT, // nzBufferAccess_DiscardAndWrite
|
GLint bufSize;
|
||||||
GL_MAP_READ_BIT, // nzBufferAccess_ReadOnly
|
glGetBufferParameteriv(NzOpenGL::BufferTargetBinding[type], GL_BUFFER_SIZE, &bufSize);
|
||||||
GL_MAP_READ_BIT | GL_MAP_WRITE_BIT, // nzBufferAccess_ReadWrite
|
|
||||||
GL_MAP_WRITE_BIT // nzBufferAccess_WriteOnly
|
GLint bufUsage;
|
||||||
};
|
glGetBufferParameteriv(NzOpenGL::BufferTargetBinding[type], GL_BUFFER_USAGE, &bufUsage);
|
||||||
|
|
||||||
GLenum bufferTarget[] = {
|
// On discard le buffer
|
||||||
GL_ELEMENT_ARRAY_BUFFER, // nzBufferType_Index,
|
glBufferData(NzOpenGL::BufferTargetBinding[type], bufSize, nullptr, bufUsage);
|
||||||
GL_ARRAY_BUFFER, // nzBufferType_Vertex
|
}
|
||||||
};
|
|
||||||
|
void* ptr = glMapBuffer(NzOpenGL::BufferTarget[type], NzOpenGL::BufferLock[access]);
|
||||||
GLenum bufferTargetBinding[] = {
|
if (ptr)
|
||||||
GL_ELEMENT_ARRAY_BUFFER_BINDING, // nzBufferType_Index,
|
return reinterpret_cast<nzUInt8*>(ptr) + offset;
|
||||||
GL_ARRAY_BUFFER_BINDING, // nzBufferType_Vertex
|
else
|
||||||
};
|
return nullptr;
|
||||||
|
}
|
||||||
GLenum bufferUsage[] = {
|
|
||||||
// J'ai choisi DYNAMIC à la place de STREAM car DYNAMIC semble plus adapté au profil "une mise à jour pour quelques rendus"
|
nzUInt8* LockBufferRange(nzBufferType type, nzBufferAccess access, unsigned int offset, unsigned int size)
|
||||||
// Ce qui est je pense le scénario qui arrivera le plus souvent (Prévoir une option pour permettre d'utiliser le STREAM_DRAW ?)
|
{
|
||||||
// Source: http://www.opengl.org/discussion_boards/ubbthreads.php?ubb=showflat&Number=160839
|
return reinterpret_cast<nzUInt8*>(glMapBufferRange(NzOpenGL::BufferTarget[type], offset, size, NzOpenGL::BufferLockRange[access]));
|
||||||
GL_DYNAMIC_DRAW, // nzBufferUsage_Dynamic
|
}
|
||||||
GL_STATIC_DRAW // nzBufferUsage_Static
|
|
||||||
};
|
nzUInt8* LockBufferFirstRun(nzBufferType type, nzBufferAccess access, unsigned int offset, unsigned int size);
|
||||||
|
|
||||||
using LockRoutine = nzUInt8* (*)(nzBufferType type, nzBufferAccess access, unsigned int offset, unsigned int size);
|
LockRoutine mapBuffer = LockBufferFirstRun;
|
||||||
|
|
||||||
nzUInt8* LockBuffer(nzBufferType type, nzBufferAccess access, unsigned int offset, unsigned int size)
|
nzUInt8* LockBufferFirstRun(nzBufferType type, nzBufferAccess access, unsigned int offset, unsigned int size)
|
||||||
{
|
{
|
||||||
NazaraUnused(size);
|
if (glMapBufferRange)
|
||||||
|
mapBuffer = LockBufferRange;
|
||||||
if (access == nzBufferAccess_DiscardAndWrite)
|
else
|
||||||
{
|
mapBuffer = LockBuffer;
|
||||||
GLint bufSize;
|
|
||||||
glGetBufferParameteriv(bufferTargetBinding[type], GL_BUFFER_SIZE, &bufSize);
|
return mapBuffer(type, access, offset, size);
|
||||||
|
}
|
||||||
GLint bufUsage;
|
}
|
||||||
glGetBufferParameteriv(bufferTargetBinding[type], GL_BUFFER_USAGE, &bufUsage);
|
|
||||||
|
NzHardwareBuffer::NzHardwareBuffer(NzBuffer* parent, nzBufferType type) :
|
||||||
// On discard le buffer
|
m_type(type),
|
||||||
glBufferData(bufferTargetBinding[type], bufSize, nullptr, bufUsage);
|
m_parent(parent)
|
||||||
}
|
{
|
||||||
|
}
|
||||||
void* ptr = glMapBuffer(bufferTarget[type], bufferLock[access]);
|
|
||||||
if (ptr)
|
NzHardwareBuffer::~NzHardwareBuffer()
|
||||||
return reinterpret_cast<nzUInt8*>(ptr) + offset;
|
{
|
||||||
else
|
}
|
||||||
return nullptr;
|
|
||||||
}
|
void NzHardwareBuffer::Bind()
|
||||||
|
{
|
||||||
nzUInt8* LockBufferRange(nzBufferType type, nzBufferAccess access, unsigned int offset, unsigned int size)
|
#ifdef NAZARA_DEBUG
|
||||||
{
|
if (NzContext::GetCurrent() == nullptr)
|
||||||
return reinterpret_cast<nzUInt8*>(glMapBufferRange(bufferTarget[type], offset, size, bufferLockRange[access]));
|
{
|
||||||
}
|
NazaraError("No active context");
|
||||||
|
return;
|
||||||
nzUInt8* LockBufferFirstRun(nzBufferType type, nzBufferAccess access, unsigned int offset, unsigned int size);
|
}
|
||||||
|
#endif
|
||||||
LockRoutine mapBuffer = LockBufferFirstRun;
|
|
||||||
|
glBindBuffer(NzOpenGL::BufferTarget[m_type], m_buffer);
|
||||||
nzUInt8* LockBufferFirstRun(nzBufferType type, nzBufferAccess access, unsigned int offset, unsigned int size)
|
}
|
||||||
{
|
|
||||||
if (glMapBufferRange)
|
bool NzHardwareBuffer::Create(unsigned int size, nzBufferUsage usage)
|
||||||
mapBuffer = LockBufferRange;
|
{
|
||||||
else
|
NzContext::EnsureContext();
|
||||||
mapBuffer = LockBuffer;
|
|
||||||
|
m_buffer = 0;
|
||||||
return mapBuffer(type, access, offset, size);
|
glGenBuffers(1, &m_buffer);
|
||||||
}
|
|
||||||
}
|
GLint previous;
|
||||||
|
glGetIntegerv(NzOpenGL::BufferTargetBinding[m_type], &previous);
|
||||||
NzHardwareBuffer::NzHardwareBuffer(NzBuffer* parent, nzBufferType type) :
|
|
||||||
m_type(type),
|
glBindBuffer(NzOpenGL::BufferTarget[m_type], m_buffer);
|
||||||
m_parent(parent)
|
glBufferData(NzOpenGL::BufferTarget[m_type], size, nullptr, NzOpenGL::BufferUsage[usage]);
|
||||||
{
|
|
||||||
}
|
// Pour ne pas perturber le rendu, on interfère pas avec le binding déjà présent
|
||||||
|
if (previous != 0)
|
||||||
NzHardwareBuffer::~NzHardwareBuffer()
|
glBindBuffer(NzOpenGL::BufferTarget[m_type], previous);
|
||||||
{
|
|
||||||
}
|
return true;
|
||||||
|
}
|
||||||
void NzHardwareBuffer::Bind()
|
|
||||||
{
|
void NzHardwareBuffer::Destroy()
|
||||||
#ifdef NAZARA_DEBUG
|
{
|
||||||
if (NzContext::GetCurrent() == nullptr)
|
NzContext::EnsureContext();
|
||||||
{
|
|
||||||
NazaraError("No active context");
|
glDeleteBuffers(1, &m_buffer);
|
||||||
return;
|
}
|
||||||
}
|
|
||||||
#endif
|
bool NzHardwareBuffer::Fill(const void* data, unsigned int offset, unsigned int size)
|
||||||
|
{
|
||||||
glBindBuffer(bufferTarget[m_type], m_buffer);
|
NzContext::EnsureContext();
|
||||||
}
|
|
||||||
|
GLuint previous;
|
||||||
bool NzHardwareBuffer::Create(unsigned int size, nzBufferUsage usage)
|
glGetIntegerv(NzOpenGL::BufferTargetBinding[m_type], reinterpret_cast<GLint*>(&previous));
|
||||||
{
|
|
||||||
NzContext::EnsureContext();
|
if (previous != m_buffer)
|
||||||
|
glBindBuffer(NzOpenGL::BufferTarget[m_type], m_buffer);
|
||||||
m_buffer = 0;
|
|
||||||
glGenBuffers(1, &m_buffer);
|
// Il semblerait que glBuffer(Sub)Data soit plus performant que glMapBuffer(Range) en dessous d'un certain seuil
|
||||||
|
// http://www.stevestreeting.com/2007/03/17/glmapbuffer-vs-glbuffersubdata-the-return/
|
||||||
GLint previous;
|
if (size < 32*1024)
|
||||||
glGetIntegerv(bufferTargetBinding[m_type], &previous);
|
{
|
||||||
|
// http://www.opengl.org/wiki/Vertex_Specification_Best_Practices
|
||||||
glBindBuffer(bufferTarget[m_type], m_buffer);
|
if (size == m_parent->GetSize())
|
||||||
glBufferData(bufferTarget[m_type], size, nullptr, bufferUsage[usage]);
|
glBufferData(NzOpenGL::BufferTarget[m_type], m_parent->GetSize(), nullptr, NzOpenGL::BufferUsage[m_parent->GetUsage()]); // Discard
|
||||||
|
|
||||||
// Pour ne pas perturber le rendu, on interfère pas avec le binding déjà présent
|
glBufferSubData(NzOpenGL::BufferTarget[m_type], offset, size, data);
|
||||||
if (previous != 0)
|
}
|
||||||
glBindBuffer(bufferTarget[m_type], previous);
|
else
|
||||||
|
{
|
||||||
return true;
|
nzUInt8* ptr = mapBuffer(m_type, (size == m_parent->GetSize()) ? nzBufferAccess_DiscardAndWrite : nzBufferAccess_WriteOnly, offset, size);
|
||||||
}
|
if (!ptr)
|
||||||
|
{
|
||||||
void NzHardwareBuffer::Destroy()
|
NazaraError("Failed to map buffer");
|
||||||
{
|
return false;
|
||||||
NzContext::EnsureContext();
|
}
|
||||||
|
|
||||||
glDeleteBuffers(1, &m_buffer);
|
std::memcpy(ptr, data, size);
|
||||||
}
|
|
||||||
|
if (glUnmapBuffer(NzOpenGL::BufferTarget[m_type]) != GL_TRUE)
|
||||||
bool NzHardwareBuffer::Fill(const void* data, unsigned int offset, unsigned int size)
|
{
|
||||||
{
|
// Une erreur rare est survenue, nous devons réinitialiser le buffer
|
||||||
NzContext::EnsureContext();
|
NazaraError("Failed to unmap buffer, reinitialising content... (OpenGL error : 0x" + NzString::Number(glGetError(), 16) + ')');
|
||||||
|
|
||||||
GLuint previous;
|
glBufferData(NzOpenGL::BufferTarget[m_type], m_parent->GetSize(), nullptr, NzOpenGL::BufferUsage[m_parent->GetStorage()]);
|
||||||
glGetIntegerv(bufferTargetBinding[m_type], reinterpret_cast<GLint*>(&previous));
|
|
||||||
|
return false;
|
||||||
if (previous != m_buffer)
|
}
|
||||||
glBindBuffer(bufferTarget[m_type], m_buffer);
|
}
|
||||||
|
|
||||||
// Il semblerait que glBuffer(Sub)Data soit plus performant que glMapBuffer(Range) en dessous d'un certain seuil
|
// Inutile de rebinder s'il n'y avait aucun buffer (Optimise les opérations chaînées)
|
||||||
// http://www.stevestreeting.com/2007/03/17/glmapbuffer-vs-glbuffersubdata-the-return/
|
if (previous != m_buffer && previous != 0)
|
||||||
if (size < 32*1024)
|
glBindBuffer(NzOpenGL::BufferTarget[m_type], previous);
|
||||||
{
|
|
||||||
// http://www.opengl.org/wiki/Vertex_Specification_Best_Practices
|
return true;
|
||||||
if (size == m_parent->GetSize())
|
}
|
||||||
glBufferData(bufferTarget[m_type], m_parent->GetSize(), nullptr, bufferUsage[m_parent->GetUsage()]); // Discard
|
|
||||||
|
void* NzHardwareBuffer::GetPointer()
|
||||||
glBufferSubData(bufferTarget[m_type], offset, size, data);
|
{
|
||||||
}
|
return nullptr;
|
||||||
else
|
}
|
||||||
{
|
|
||||||
nzUInt8* ptr = mapBuffer(m_type, (size == m_parent->GetSize()) ? nzBufferAccess_DiscardAndWrite : nzBufferAccess_WriteOnly, offset, size);
|
bool NzHardwareBuffer::IsHardware() const
|
||||||
if (!ptr)
|
{
|
||||||
{
|
return true;
|
||||||
NazaraError("Failed to map buffer");
|
}
|
||||||
return false;
|
|
||||||
}
|
void* NzHardwareBuffer::Map(nzBufferAccess access, unsigned int offset, unsigned int size)
|
||||||
|
{
|
||||||
std::memcpy(ptr, data, size);
|
NzContext::EnsureContext();
|
||||||
|
|
||||||
if (glUnmapBuffer(bufferTarget[m_type]) != GL_TRUE)
|
// Pour ne pas perturber le rendu, on interfère pas avec le binding déjà présent
|
||||||
{
|
GLuint previous;
|
||||||
// Une erreur rare est survenue, nous devons réinitialiser le buffer
|
glGetIntegerv(NzOpenGL::BufferTargetBinding[m_type], reinterpret_cast<GLint*>(&previous));
|
||||||
NazaraError("Failed to unmap buffer, reinitialising content... (OpenGL error : 0x" + NzString::Number(glGetError(), 16) + ')');
|
|
||||||
|
if (previous != m_buffer)
|
||||||
glBufferData(bufferTarget[m_type], m_parent->GetSize(), nullptr, bufferUsage[m_parent->GetStorage()]);
|
glBindBuffer(NzOpenGL::BufferTarget[m_type], m_buffer);
|
||||||
|
|
||||||
return false;
|
void* ptr = mapBuffer(m_type, access, offset, size);
|
||||||
}
|
|
||||||
}
|
// Inutile de rebinder s'il n'y avait aucun buffer (Optimise les opérrations chaînées)
|
||||||
|
if (previous != m_buffer && previous != 0)
|
||||||
// Inutile de rebinder s'il n'y avait aucun buffer (Optimise les opérations chaînées)
|
glBindBuffer(NzOpenGL::BufferTarget[m_type], previous);
|
||||||
if (previous != m_buffer && previous != 0)
|
|
||||||
glBindBuffer(bufferTarget[m_type], previous);
|
return ptr;
|
||||||
|
}
|
||||||
return true;
|
|
||||||
}
|
bool NzHardwareBuffer::Unmap()
|
||||||
|
{
|
||||||
void* NzHardwareBuffer::GetPointer()
|
NzContext::EnsureContext();
|
||||||
{
|
|
||||||
return nullptr;
|
GLuint previous;
|
||||||
}
|
glGetIntegerv(NzOpenGL::BufferTargetBinding[m_type], reinterpret_cast<GLint*>(&previous));
|
||||||
|
|
||||||
bool NzHardwareBuffer::IsHardware() const
|
if (previous != m_buffer)
|
||||||
{
|
glBindBuffer(NzOpenGL::BufferTarget[m_type], m_buffer);
|
||||||
return true;
|
|
||||||
}
|
if (glUnmapBuffer(NzOpenGL::BufferTarget[m_type]) != GL_TRUE)
|
||||||
|
{
|
||||||
void* NzHardwareBuffer::Map(nzBufferAccess access, unsigned int offset, unsigned int size)
|
// Une erreur rare est survenue, nous devons réinitialiser le buffer
|
||||||
{
|
NazaraError("Failed to unmap buffer, reinitialising content... (OpenGL error : 0x" + NzString::Number(glGetError(), 16) + ')');
|
||||||
NzContext::EnsureContext();
|
|
||||||
|
glBufferData(NzOpenGL::BufferTarget[m_type], m_parent->GetSize(), nullptr, NzOpenGL::BufferUsage[m_parent->GetStorage()]);
|
||||||
// Pour ne pas perturber le rendu, on interfère pas avec le binding déjà présent
|
|
||||||
GLuint previous;
|
// Inutile de rebinder s'il n'y avait aucun buffer (Optimise les opérations chaînées)
|
||||||
glGetIntegerv(bufferTargetBinding[m_type], reinterpret_cast<GLint*>(&previous));
|
if (previous != m_buffer && previous != 0)
|
||||||
|
glBindBuffer(NzOpenGL::BufferTarget[m_type], previous);
|
||||||
if (previous != m_buffer)
|
|
||||||
glBindBuffer(bufferTarget[m_type], m_buffer);
|
return false;
|
||||||
|
}
|
||||||
void* ptr = mapBuffer(m_type, access, offset, size);
|
|
||||||
|
// Inutile de rebinder s'il n'y avait aucun buffer (Optimise les opérations chaînées)
|
||||||
// Inutile de rebinder s'il n'y avait aucun buffer (Optimise les opérrations chaînées)
|
if (previous != m_buffer && previous != 0)
|
||||||
if (previous != m_buffer && previous != 0)
|
glBindBuffer(NzOpenGL::BufferTarget[m_type], previous);
|
||||||
glBindBuffer(bufferTarget[m_type], previous);
|
|
||||||
|
return true;
|
||||||
return ptr;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
bool NzHardwareBuffer::Unmap()
|
|
||||||
{
|
|
||||||
NzContext::EnsureContext();
|
|
||||||
|
|
||||||
GLuint previous;
|
|
||||||
glGetIntegerv(bufferTargetBinding[m_type], reinterpret_cast<GLint*>(&previous));
|
|
||||||
|
|
||||||
if (previous != m_buffer)
|
|
||||||
glBindBuffer(bufferTarget[m_type], m_buffer);
|
|
||||||
|
|
||||||
if (glUnmapBuffer(bufferTarget[m_type]) != GL_TRUE)
|
|
||||||
{
|
|
||||||
// Une erreur rare est survenue, nous devons réinitialiser le buffer
|
|
||||||
NazaraError("Failed to unmap buffer, reinitialising content... (OpenGL error : 0x" + NzString::Number(glGetError(), 16) + ')');
|
|
||||||
|
|
||||||
glBufferData(bufferTarget[m_type], m_parent->GetSize(), nullptr, bufferUsage[m_parent->GetStorage()]);
|
|
||||||
|
|
||||||
// Inutile de rebinder s'il n'y avait aucun buffer (Optimise les opérations chaînées)
|
|
||||||
if (previous != m_buffer && previous != 0)
|
|
||||||
glBindBuffer(bufferTarget[m_type], previous);
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Inutile de rebinder s'il n'y avait aucun buffer (Optimise les opérations chaînées)
|
|
||||||
if (previous != m_buffer && previous != 0)
|
|
||||||
glBindBuffer(bufferTarget[m_type], previous);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -1,102 +1,98 @@
|
||||||
// Copyright (C) 2012 Jérôme Leclercq
|
// Copyright (C) 2012 Jérôme Leclercq
|
||||||
// This file is part of the "Nazara Engine - Renderer module"
|
// This file is part of the "Nazara Engine - Renderer module"
|
||||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||||
|
|
||||||
#include <Nazara/Renderer/OpenGL.hpp>
|
#include <Nazara/Renderer/OpenGL.hpp>
|
||||||
#include <Nazara/Renderer/OcclusionQuery.hpp>
|
#include <Nazara/Renderer/OcclusionQuery.hpp>
|
||||||
#include <Nazara/Core/Error.hpp>
|
#include <Nazara/Core/Error.hpp>
|
||||||
#include <Nazara/Renderer/Config.hpp>
|
#include <Nazara/Renderer/Config.hpp>
|
||||||
#include <Nazara/Renderer/Context.hpp>
|
#include <Nazara/Renderer/Context.hpp>
|
||||||
#include <Nazara/Renderer/Renderer.hpp>
|
#include <Nazara/Renderer/Renderer.hpp>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include <Nazara/Renderer/Debug.hpp>
|
#include <Nazara/Renderer/Debug.hpp>
|
||||||
|
|
||||||
NzOcclusionQuery::NzOcclusionQuery() :
|
NzOcclusionQuery::NzOcclusionQuery() :
|
||||||
m_id(0)
|
m_id(0)
|
||||||
{
|
{
|
||||||
#if NAZARA_RENDERER_SAFE
|
if (IsSupported())
|
||||||
if (IsSupported())
|
{
|
||||||
{
|
NzContext::EnsureContext();
|
||||||
#endif
|
|
||||||
NzContext::EnsureContext();
|
glGenQueries(1, reinterpret_cast<GLuint*>(&m_id));
|
||||||
|
}
|
||||||
glGenQueries(1, reinterpret_cast<GLuint*>(&m_id));
|
else
|
||||||
#if NAZARA_RENDERER_SAFE
|
{
|
||||||
}
|
NazaraError("Occlusion queries not supported");
|
||||||
else
|
return;
|
||||||
{
|
}
|
||||||
NazaraError("Occlusion queries not supported");
|
|
||||||
return;
|
#ifdef NAZARA_DEBUG
|
||||||
}
|
if (!m_id)
|
||||||
#endif
|
{
|
||||||
|
NazaraError("Failed to create occlusion query");
|
||||||
#ifdef NAZARA_DEBUG
|
throw std::runtime_error("Constructor failed");
|
||||||
if (!m_id)
|
}
|
||||||
{
|
#endif
|
||||||
NazaraError("Failed to create occlusion query");
|
}
|
||||||
throw std::runtime_error("Constructor failed");
|
|
||||||
}
|
NzOcclusionQuery::~NzOcclusionQuery()
|
||||||
#endif
|
{
|
||||||
}
|
if (m_id)
|
||||||
|
{
|
||||||
NzOcclusionQuery::~NzOcclusionQuery()
|
NzContext::EnsureContext();
|
||||||
{
|
|
||||||
if (m_id)
|
GLuint query = static_cast<GLuint>(m_id);
|
||||||
{
|
glDeleteQueries(1, &query);
|
||||||
NzContext::EnsureContext();
|
}
|
||||||
|
}
|
||||||
GLuint query = static_cast<GLuint>(m_id);
|
|
||||||
glDeleteQueries(1, &query);
|
void NzOcclusionQuery::Begin()
|
||||||
}
|
{
|
||||||
}
|
#ifdef NAZARA_DEBUG
|
||||||
|
if (NzContext::GetCurrent() == nullptr)
|
||||||
void NzOcclusionQuery::Begin()
|
{
|
||||||
{
|
NazaraError("No active context");
|
||||||
#ifdef NAZARA_DEBUG
|
return;
|
||||||
if (NzContext::GetCurrent() == nullptr)
|
}
|
||||||
{
|
#endif
|
||||||
NazaraError("No active context");
|
|
||||||
return;
|
glBeginQuery(GL_SAMPLES_PASSED, m_id);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
void NzOcclusionQuery::End()
|
||||||
glBeginQuery(GL_SAMPLES_PASSED, m_id);
|
{
|
||||||
}
|
#ifdef NAZARA_DEBUG
|
||||||
|
if (NzContext::GetCurrent() == nullptr)
|
||||||
void NzOcclusionQuery::End()
|
{
|
||||||
{
|
NazaraError("No active context");
|
||||||
#ifdef NAZARA_DEBUG
|
return;
|
||||||
if (NzContext::GetCurrent() == nullptr)
|
}
|
||||||
{
|
#endif
|
||||||
NazaraError("No active context");
|
|
||||||
return;
|
glEndQuery(GL_SAMPLES_PASSED);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
unsigned int NzOcclusionQuery::GetResult() const
|
||||||
glEndQuery(GL_SAMPLES_PASSED);
|
{
|
||||||
}
|
NzContext::EnsureContext();
|
||||||
|
|
||||||
unsigned int NzOcclusionQuery::GetResult() const
|
GLuint result;
|
||||||
{
|
glGetQueryObjectuiv(m_id, GL_QUERY_RESULT, &result);
|
||||||
NzContext::EnsureContext();
|
|
||||||
|
return result;
|
||||||
GLuint result;
|
}
|
||||||
glGetQueryObjectuiv(m_id, GL_QUERY_RESULT, &result);
|
|
||||||
|
bool NzOcclusionQuery::IsResultAvailable() const
|
||||||
return result;
|
{
|
||||||
}
|
NzContext::EnsureContext();
|
||||||
|
|
||||||
bool NzOcclusionQuery::IsResultAvailable() const
|
GLint available;
|
||||||
{
|
glGetQueryObjectiv(m_id, GL_QUERY_RESULT_AVAILABLE, &available);
|
||||||
NzContext::EnsureContext();
|
|
||||||
|
return available == GL_TRUE;
|
||||||
GLint available;
|
}
|
||||||
glGetQueryObjectiv(m_id, GL_QUERY_RESULT_AVAILABLE, &available);
|
|
||||||
|
bool NzOcclusionQuery::IsSupported()
|
||||||
return available == GL_TRUE;
|
{
|
||||||
}
|
return NzRenderer::HasCapability(nzRendererCap_OcclusionQuery);
|
||||||
|
}
|
||||||
bool NzOcclusionQuery::IsSupported()
|
|
||||||
{
|
|
||||||
return NzRenderer::HasCapability(nzRendererCap_OcclusionQuery);
|
|
||||||
}
|
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,728 @@
|
||||||
|
// Copyright (C) 2012 Jérôme Leclercq
|
||||||
|
// This file is part of the "Nazara Engine - Renderer module"
|
||||||
|
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||||
|
|
||||||
|
#include <Nazara/Renderer/OpenGL.hpp>
|
||||||
|
#include <Nazara/Renderer/RenderTexture.hpp>
|
||||||
|
#include <Nazara/Core/Error.hpp>
|
||||||
|
#include <Nazara/Renderer/Context.hpp>
|
||||||
|
#include <Nazara/Renderer/Renderer.hpp>
|
||||||
|
#include <vector>
|
||||||
|
#include <Nazara/Renderer/Debug.hpp>
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
struct Attachment
|
||||||
|
{
|
||||||
|
union
|
||||||
|
{
|
||||||
|
GLuint buffer;
|
||||||
|
NzTexture* texture;
|
||||||
|
};
|
||||||
|
|
||||||
|
bool isBuffer;
|
||||||
|
bool isUsed = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
unsigned int attachmentIndex[nzAttachmentPoint_Max+1] =
|
||||||
|
{
|
||||||
|
2, // nzAttachmentPoint_Color
|
||||||
|
0, // nzAttachmentPoint_Depth
|
||||||
|
0, // nzAttachmentPoint_DepthStencil
|
||||||
|
1 // nzAttachmentPoint_Stencil
|
||||||
|
};
|
||||||
|
|
||||||
|
nzAttachmentPoint formatTypeToAttachment[nzPixelFormatType_Max+1] =
|
||||||
|
{
|
||||||
|
nzAttachmentPoint_Color, // nzPixelFormatType_Color
|
||||||
|
nzAttachmentPoint_Depth, // nzPixelFormatType_Depth
|
||||||
|
nzAttachmentPoint_DepthStencil, // nzPixelFormatType_DepthStencil
|
||||||
|
nzAttachmentPoint_Stencil // nzPixelFormatType_Stencil
|
||||||
|
};
|
||||||
|
|
||||||
|
GLuint lockedPrevious = 0;
|
||||||
|
nzUInt8 lockedLevel = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct NzRenderTextureImpl
|
||||||
|
{
|
||||||
|
GLuint fbo;
|
||||||
|
std::vector<Attachment> attachements;
|
||||||
|
std::vector<GLenum> drawBuffers;
|
||||||
|
NzContext* context;
|
||||||
|
bool checked = false;
|
||||||
|
bool complete = false;
|
||||||
|
bool drawBuffersUpdated = true;
|
||||||
|
unsigned int height;
|
||||||
|
unsigned int width;
|
||||||
|
};
|
||||||
|
|
||||||
|
NzRenderTexture::~NzRenderTexture()
|
||||||
|
{
|
||||||
|
Destroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NzRenderTexture::AttachBuffer(nzAttachmentPoint attachmentPoint, nzUInt8 index, nzPixelFormat format)
|
||||||
|
{
|
||||||
|
#if NAZARA_RENDERER_SAFE
|
||||||
|
if (!m_impl)
|
||||||
|
{
|
||||||
|
NazaraError("Render texture not created");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (attachmentPoint != nzAttachmentPoint_Color && index > 0)
|
||||||
|
{
|
||||||
|
NazaraError("Index must be 0 for non-color attachments");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int depthStencilIndex = attachmentIndex[nzAttachmentPoint_DepthStencil];
|
||||||
|
if (attachmentPoint == nzAttachmentPoint_Stencil && m_impl->attachements.size() > depthStencilIndex &&
|
||||||
|
m_impl->attachements[depthStencilIndex].isUsed)
|
||||||
|
{
|
||||||
|
NazaraError("Stencil target already attached by DepthStencil attachment");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (formatTypeToAttachment[NzPixelFormat::GetType(format)] != attachmentPoint)
|
||||||
|
{
|
||||||
|
NazaraError("Pixel format type does not match attachment point type");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
NzOpenGL::Format openglFormat;
|
||||||
|
if (!NzOpenGL::TranslateFormat(format, &openglFormat, NzOpenGL::FormatType_RenderBuffer))
|
||||||
|
{
|
||||||
|
NazaraError("Failed to translate pixel format into OpenGL format");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!Lock())
|
||||||
|
{
|
||||||
|
NazaraError("Failed to lock render texture");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Détachement de l'attache précédente (Si il y a)
|
||||||
|
Detach(attachmentPoint, index);
|
||||||
|
|
||||||
|
GLuint renderBuffer = 0;
|
||||||
|
|
||||||
|
glGenRenderbuffers(1, &renderBuffer);
|
||||||
|
if (!renderBuffer)
|
||||||
|
{
|
||||||
|
NazaraError("Failed to create renderbuffer");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
GLint previous;
|
||||||
|
glGetIntegerv(GL_RENDERBUFFER_BINDING, &previous);
|
||||||
|
|
||||||
|
glBindRenderbuffer(GL_RENDERBUFFER, renderBuffer);
|
||||||
|
glRenderbufferStorage(GL_RENDERBUFFER, openglFormat.internalFormat, m_impl->width, m_impl->height);
|
||||||
|
|
||||||
|
if (previous != 0)
|
||||||
|
glBindRenderbuffer(GL_RENDERBUFFER, previous);
|
||||||
|
|
||||||
|
glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, NzOpenGL::Attachment[attachmentPoint]+index, GL_RENDERBUFFER, renderBuffer);
|
||||||
|
Unlock();
|
||||||
|
|
||||||
|
unsigned int minSize = attachmentIndex[attachmentPoint]+index+1;
|
||||||
|
if (m_impl->attachements.size() < minSize)
|
||||||
|
m_impl->attachements.resize(minSize);
|
||||||
|
|
||||||
|
Attachment& attachment = m_impl->attachements[minSize-1];
|
||||||
|
attachment.isBuffer = true;
|
||||||
|
attachment.isUsed = true;
|
||||||
|
attachment.buffer = renderBuffer;
|
||||||
|
|
||||||
|
m_impl->checked = false;
|
||||||
|
m_impl->drawBuffersUpdated = false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NzRenderTexture::AttachTexture(nzAttachmentPoint attachmentPoint, nzUInt8 index, NzTexture* texture)
|
||||||
|
{
|
||||||
|
#if NAZARA_RENDERER_SAFE
|
||||||
|
if (!m_impl)
|
||||||
|
{
|
||||||
|
NazaraError("Render texture not created");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (attachmentPoint != nzAttachmentPoint_Color && index > 0)
|
||||||
|
{
|
||||||
|
NazaraError("Index must be 0 for non-color attachments");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int depthStencilIndex = attachmentIndex[nzAttachmentPoint_DepthStencil];
|
||||||
|
if (attachmentPoint == nzAttachmentPoint_Stencil && m_impl->attachements.size() > depthStencilIndex &&
|
||||||
|
m_impl->attachements[depthStencilIndex].isUsed)
|
||||||
|
{
|
||||||
|
NazaraError("Stencil target already attached by DepthStencil attachment");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!texture || !texture->IsValid())
|
||||||
|
{
|
||||||
|
NazaraError("Invalid texture");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (texture->GetWidth() < m_impl->width || texture->GetHeight() < m_impl->height)
|
||||||
|
{
|
||||||
|
NazaraError("Texture cannot be smaller than render texture");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (texture->GetRenderTexture() != nullptr)
|
||||||
|
{
|
||||||
|
NazaraError("Texture already used by another render texture");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (formatTypeToAttachment[NzPixelFormat::GetType(texture->GetFormat())] != attachmentPoint)
|
||||||
|
{
|
||||||
|
NazaraError("Pixel format type does not match attachment point type");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (!Lock())
|
||||||
|
{
|
||||||
|
NazaraError("Failed to lock render texture");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Détachement de l'attache précédente (Si il y a)
|
||||||
|
Detach(attachmentPoint, index);
|
||||||
|
|
||||||
|
glFramebufferTexture(GL_DRAW_FRAMEBUFFER, NzOpenGL::Attachment[attachmentPoint]+index, texture->GetOpenGLID(), 0);
|
||||||
|
Unlock();
|
||||||
|
|
||||||
|
unsigned int minSize = attachmentIndex[attachmentPoint]+index+1;
|
||||||
|
if (m_impl->attachements.size() < minSize)
|
||||||
|
m_impl->attachements.resize(minSize);
|
||||||
|
|
||||||
|
Attachment& attachment = m_impl->attachements[minSize-1];
|
||||||
|
attachment.isBuffer = true;
|
||||||
|
attachment.isUsed = true;
|
||||||
|
attachment.texture = texture;
|
||||||
|
|
||||||
|
texture->AddResourceListener(this, minSize-1);
|
||||||
|
texture->SetRenderTexture(this);
|
||||||
|
|
||||||
|
m_impl->checked = false;
|
||||||
|
m_impl->drawBuffersUpdated = false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NzRenderTexture::AttachTexture(nzAttachmentPoint attachmentPoint, nzUInt8 index, NzTexture* texture, unsigned int z)
|
||||||
|
{
|
||||||
|
#if NAZARA_RENDERER_SAFE
|
||||||
|
if (!m_impl)
|
||||||
|
{
|
||||||
|
NazaraError("Render texture not created");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (attachmentPoint != nzAttachmentPoint_Color && index > 0)
|
||||||
|
{
|
||||||
|
NazaraError("Index must be 0 for non-color attachments");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (attachmentPoint == nzAttachmentPoint_Stencil)
|
||||||
|
{
|
||||||
|
NazaraError("Targeting stencil-only textures is not supported");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int depthStencilIndex = attachmentIndex[nzAttachmentPoint_DepthStencil];
|
||||||
|
if (attachmentPoint == nzAttachmentPoint_Stencil && m_impl->attachements.size() > depthStencilIndex &&
|
||||||
|
m_impl->attachements[depthStencilIndex].isUsed)
|
||||||
|
{
|
||||||
|
NazaraError("Stencil target already attached by DepthStencil attachment");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!texture || !texture->IsValid())
|
||||||
|
{
|
||||||
|
NazaraError("Invalid texture");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (texture->GetWidth() < m_impl->width || texture->GetHeight() < m_impl->height)
|
||||||
|
{
|
||||||
|
NazaraError("Texture cannot be smaller than render texture");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int depth = (texture->GetType() == nzImageType_Cubemap) ? 6 : texture->GetDepth();
|
||||||
|
if (z >= depth)
|
||||||
|
{
|
||||||
|
NazaraError("Z value exceeds depth (" + NzString::Number(z) + " >= (" + NzString::Number(depth) + ')');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (texture->GetRenderTexture() != nullptr)
|
||||||
|
{
|
||||||
|
NazaraError("Texture already used by another render texture");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (formatTypeToAttachment[NzPixelFormat::GetType(texture->GetFormat())] != attachmentPoint)
|
||||||
|
{
|
||||||
|
NazaraError("Pixel format type does not match attachment point type");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (!Lock())
|
||||||
|
{
|
||||||
|
NazaraError("Failed to lock render texture");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Détachement de l'attache précédente (Si il y a)
|
||||||
|
Detach(attachmentPoint, index);
|
||||||
|
|
||||||
|
switch (texture->GetType())
|
||||||
|
{
|
||||||
|
case nzImageType_1D:
|
||||||
|
glFramebufferTexture1D(GL_DRAW_FRAMEBUFFER, NzOpenGL::Attachment[attachmentPoint]+index, GL_TEXTURE_1D, texture->GetOpenGLID(), 0);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case nzImageType_1D_Array:
|
||||||
|
case nzImageType_2D_Array:
|
||||||
|
glFramebufferTextureLayer(GL_DRAW_FRAMEBUFFER, NzOpenGL::Attachment[attachmentPoint]+index, texture->GetOpenGLID(), 0, z);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case nzImageType_2D:
|
||||||
|
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, NzOpenGL::Attachment[attachmentPoint]+index, NzOpenGL::TextureTarget[texture->GetType()], texture->GetOpenGLID(), 0);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case nzImageType_3D:
|
||||||
|
glFramebufferTexture3D(GL_DRAW_FRAMEBUFFER, NzOpenGL::Attachment[attachmentPoint]+index, GL_TEXTURE_3D, texture->GetOpenGLID(), 0, z);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case nzImageType_Cubemap:
|
||||||
|
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, NzOpenGL::Attachment[attachmentPoint]+index, NzOpenGL::CubemapFace[z], texture->GetOpenGLID(), 0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
Unlock();
|
||||||
|
|
||||||
|
unsigned int minSize = attachmentIndex[attachmentPoint]+index+1;
|
||||||
|
if (m_impl->attachements.size() < minSize)
|
||||||
|
m_impl->attachements.resize(minSize);
|
||||||
|
|
||||||
|
Attachment& attachment = m_impl->attachements[minSize-1];
|
||||||
|
attachment.isBuffer = true;
|
||||||
|
attachment.isUsed = true;
|
||||||
|
attachment.texture = texture;
|
||||||
|
|
||||||
|
texture->AddResourceListener(this);
|
||||||
|
texture->SetRenderTexture(this);
|
||||||
|
|
||||||
|
m_impl->checked = false;
|
||||||
|
m_impl->drawBuffersUpdated = false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NzRenderTexture::Create(unsigned int width, unsigned int height, bool lock)
|
||||||
|
{
|
||||||
|
if (!IsSupported())
|
||||||
|
{
|
||||||
|
NazaraError("Render textures not supported");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Destroy();
|
||||||
|
|
||||||
|
#if NAZARA_RENDERER_SAFE
|
||||||
|
if (width == 0)
|
||||||
|
{
|
||||||
|
NazaraError("Width must be at least 1 (0)");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (height == 0)
|
||||||
|
{
|
||||||
|
NazaraError("Height must be at least 1 (0)");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (NzContext::GetCurrent() == nullptr)
|
||||||
|
{
|
||||||
|
NazaraError("No active context");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
NzRenderTextureImpl* impl = new NzRenderTextureImpl;
|
||||||
|
impl->width = width;
|
||||||
|
impl->height = height;
|
||||||
|
|
||||||
|
impl->context = NzContext::GetCurrent();
|
||||||
|
impl->context->AddResourceListener(this);
|
||||||
|
|
||||||
|
impl->fbo = 0;
|
||||||
|
glGenFramebuffers(1, &impl->fbo);
|
||||||
|
|
||||||
|
if (!impl->fbo)
|
||||||
|
{
|
||||||
|
NazaraError("Failed to create framebuffer");
|
||||||
|
delete impl;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_impl = impl;
|
||||||
|
|
||||||
|
if (lock && !Lock())
|
||||||
|
{
|
||||||
|
NazaraError("Failed to lock render texture");
|
||||||
|
delete impl;
|
||||||
|
m_impl = nullptr;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void NzRenderTexture::Destroy()
|
||||||
|
{
|
||||||
|
if (m_impl)
|
||||||
|
{
|
||||||
|
#if NAZARA_RENDERER_SAFE
|
||||||
|
if (NzContext::GetCurrent() != m_impl->context)
|
||||||
|
{
|
||||||
|
NazaraError("RenderTexture can only be used with it's creation context");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
m_impl->context->RemoveResourceListener(this);
|
||||||
|
|
||||||
|
for (Attachment& attachment : m_impl->attachements)
|
||||||
|
{
|
||||||
|
if (attachment.isUsed)
|
||||||
|
{
|
||||||
|
if (attachment.isBuffer)
|
||||||
|
glDeleteRenderbuffers(1, &attachment.buffer);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
attachment.texture->RemoveResourceListener(this);
|
||||||
|
attachment.texture->SetRenderTexture(nullptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
glDeleteFramebuffers(1, &m_impl->fbo);
|
||||||
|
|
||||||
|
delete m_impl;
|
||||||
|
m_impl = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void NzRenderTexture::Detach(nzAttachmentPoint attachmentPoint, nzUInt8 index)
|
||||||
|
{
|
||||||
|
#if NAZARA_RENDERER_SAFE
|
||||||
|
if (!m_impl)
|
||||||
|
{
|
||||||
|
NazaraError("Render texture not created");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (attachmentPoint != nzAttachmentPoint_Color && index > 0)
|
||||||
|
{
|
||||||
|
NazaraError("Index must be 0 for non-color attachments");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
unsigned int attachIndex = attachmentIndex[attachmentPoint]+index;
|
||||||
|
if (attachIndex >= m_impl->attachements.size())
|
||||||
|
return;
|
||||||
|
|
||||||
|
Attachment& attachement = m_impl->attachements[attachIndex];
|
||||||
|
if (!attachement.isUsed)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!Lock())
|
||||||
|
{
|
||||||
|
NazaraError("Failed to lock render texture");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
attachement.isUsed = false;
|
||||||
|
|
||||||
|
if (attachement.isBuffer)
|
||||||
|
{
|
||||||
|
glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, NzOpenGL::Attachment[attachmentPoint]+index, GL_RENDERBUFFER, 0);
|
||||||
|
glDeleteRenderbuffers(1, &attachement.buffer);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
glFramebufferTexture(GL_DRAW_FRAMEBUFFER, NzOpenGL::Attachment[attachmentPoint]+index, 0, 0);
|
||||||
|
attachement.texture->RemoveResourceListener(this);
|
||||||
|
attachement.texture->SetRenderTexture(nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
Unlock();
|
||||||
|
|
||||||
|
m_impl->checked = false;
|
||||||
|
m_impl->drawBuffersUpdated = false;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int NzRenderTexture::GetHeight() const
|
||||||
|
{
|
||||||
|
#if NAZARA_RENDERER_SAFE
|
||||||
|
if (!m_impl)
|
||||||
|
{
|
||||||
|
NazaraError("Render texture not created");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return m_impl->height;
|
||||||
|
}
|
||||||
|
|
||||||
|
NzRenderTargetParameters NzRenderTexture::GetParameters() const
|
||||||
|
{
|
||||||
|
#if NAZARA_RENDERER_SAFE
|
||||||
|
if (!m_impl)
|
||||||
|
{
|
||||||
|
NazaraError("Render texture not created");
|
||||||
|
return NzRenderTargetParameters();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return NzRenderTargetParameters();
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int NzRenderTexture::GetWidth() const
|
||||||
|
{
|
||||||
|
#if NAZARA_RENDERER_SAFE
|
||||||
|
if (!m_impl)
|
||||||
|
{
|
||||||
|
NazaraError("Render texture not created");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return m_impl->width;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NzRenderTexture::IsComplete() const
|
||||||
|
{
|
||||||
|
#if NAZARA_RENDERER_SAFE
|
||||||
|
if (!m_impl)
|
||||||
|
{
|
||||||
|
NazaraError("Render texture not created");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (!m_impl->checked)
|
||||||
|
{
|
||||||
|
if (!Lock())
|
||||||
|
{
|
||||||
|
NazaraError("Failed to lock render texture");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
GLenum status = glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER);
|
||||||
|
Unlock();
|
||||||
|
|
||||||
|
m_impl->complete = false;
|
||||||
|
|
||||||
|
switch (status)
|
||||||
|
{
|
||||||
|
case GL_FRAMEBUFFER_COMPLETE:
|
||||||
|
m_impl->complete = true;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT:
|
||||||
|
NazaraError("Incomplete attachment");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER:
|
||||||
|
NazaraInternalError("Incomplete draw buffer");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER:
|
||||||
|
NazaraInternalError("Incomplete read buffer");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:
|
||||||
|
NazaraError("Incomplete missing attachment");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE:
|
||||||
|
NazaraError("Incomplete multisample");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS:
|
||||||
|
NazaraError("Incomplete layer targets");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GL_FRAMEBUFFER_UNSUPPORTED:
|
||||||
|
NazaraError("Render texture has unsupported attachments");
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
NazaraInternalError("Unknown error");
|
||||||
|
}
|
||||||
|
|
||||||
|
m_impl->checked = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return m_impl->complete;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NzRenderTexture::IsRenderable() const
|
||||||
|
{
|
||||||
|
return IsComplete();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NzRenderTexture::IsValid() const
|
||||||
|
{
|
||||||
|
return m_impl != nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NzRenderTexture::Lock() const
|
||||||
|
{
|
||||||
|
#if NAZARA_RENDERER_SAFE
|
||||||
|
if (!m_impl)
|
||||||
|
{
|
||||||
|
NazaraError("Render texture not created");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (NzContext::GetCurrent() != m_impl->context)
|
||||||
|
{
|
||||||
|
NazaraError("RenderTexture cannot be used with this context");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (lockedLevel++ == 0)
|
||||||
|
{
|
||||||
|
GLint previous;
|
||||||
|
glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &previous);
|
||||||
|
|
||||||
|
lockedPrevious = previous;
|
||||||
|
|
||||||
|
if (lockedPrevious != m_impl->fbo)
|
||||||
|
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_impl->fbo);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void NzRenderTexture::Unlock() const
|
||||||
|
{
|
||||||
|
#if NAZARA_RENDERER_SAFE
|
||||||
|
if (!m_impl)
|
||||||
|
{
|
||||||
|
NazaraError("Render texture not created");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (NzContext::GetCurrent() != m_impl->context)
|
||||||
|
{
|
||||||
|
NazaraError("RenderTexture cannot be used with this context");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lockedLevel == 0)
|
||||||
|
{
|
||||||
|
NazaraWarning("Unlock called on non-locked texture");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (--lockedLevel == 0 && lockedPrevious != m_impl->fbo) // Ici, il est important qu'un FBO soit débindé si l'ancien était 0
|
||||||
|
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, lockedPrevious);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NzRenderTexture::HasContext() const
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NzRenderTexture::IsSupported()
|
||||||
|
{
|
||||||
|
return NzRenderer::HasCapability(nzRendererCap_RenderTexture);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NzRenderTexture::Activate()
|
||||||
|
{
|
||||||
|
#if NAZARA_RENDERER_SAFE
|
||||||
|
if (NzContext::GetCurrent() != m_impl->context)
|
||||||
|
{
|
||||||
|
NazaraError("RenderTexture cannot be used with this context");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (!m_impl->drawBuffersUpdated)
|
||||||
|
{
|
||||||
|
m_impl->drawBuffers.clear();
|
||||||
|
m_impl->drawBuffers.reserve(m_impl->attachements.size());
|
||||||
|
for (unsigned int i = attachmentIndex[nzAttachmentPoint_Color]; i < m_impl->attachements.size(); ++i)
|
||||||
|
{
|
||||||
|
if (m_impl->attachements[i].isUsed)
|
||||||
|
m_impl->drawBuffers.push_back(GL_COLOR_ATTACHMENT0 + i - attachmentIndex[nzAttachmentPoint_Color]);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_impl->drawBuffersUpdated = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
glDrawBuffers(m_impl->drawBuffers.size(), &m_impl->drawBuffers[0]);
|
||||||
|
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_impl->fbo);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void NzRenderTexture::Desactivate()
|
||||||
|
{
|
||||||
|
#if NAZARA_RENDERER_SAFE
|
||||||
|
if (NzContext::GetCurrent() != m_impl->context)
|
||||||
|
{
|
||||||
|
NazaraError("RenderTexture cannot be used with this context");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
glFlush();
|
||||||
|
|
||||||
|
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void NzRenderTexture::OnResourceDestroy(const NzResource* resource, int index)
|
||||||
|
{
|
||||||
|
if (resource == m_impl->context)
|
||||||
|
// Notre context a été détruit, libérons la RenderTexture pour éviter un leak
|
||||||
|
Destroy();
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Sinon, c'est une texture
|
||||||
|
|
||||||
|
// La ressource n'est plus, du coup nous mettons à jour
|
||||||
|
Attachment& attachement = m_impl->attachements[index];
|
||||||
|
attachement.isUsed = false;
|
||||||
|
|
||||||
|
m_impl->checked = false;
|
||||||
|
m_impl->drawBuffersUpdated = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,278 +1,276 @@
|
||||||
// Copyright (C) 2012 Jérôme Leclercq
|
// Copyright (C) 2012 Jérôme Leclercq
|
||||||
// This file is part of the "Nazara Engine - Renderer module"
|
// This file is part of the "Nazara Engine - Renderer module"
|
||||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||||
|
|
||||||
#include <Nazara/Renderer/OpenGL.hpp>
|
#include <Nazara/Renderer/OpenGL.hpp>
|
||||||
#include <Nazara/Renderer/RenderWindow.hpp>
|
#include <Nazara/Renderer/RenderWindow.hpp>
|
||||||
#include <Nazara/Core/Error.hpp>
|
#include <Nazara/Core/Error.hpp>
|
||||||
#include <Nazara/Core/Thread.hpp>
|
#include <Nazara/Core/Thread.hpp>
|
||||||
#include <Nazara/Renderer/Context.hpp>
|
#include <Nazara/Renderer/Context.hpp>
|
||||||
#include <Nazara/Renderer/Texture.hpp>
|
#include <Nazara/Renderer/Texture.hpp>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include <Nazara/Renderer/Debug.hpp>
|
#include <Nazara/Renderer/Debug.hpp>
|
||||||
|
|
||||||
NzRenderWindow::NzRenderWindow(NzVideoMode mode, const NzString& title, nzUInt32 style, const NzContextParameters& parameters)
|
NzRenderWindow::NzRenderWindow(NzVideoMode mode, const NzString& title, nzUInt32 style, const NzContextParameters& parameters)
|
||||||
{
|
{
|
||||||
Create(mode, title, style, parameters);
|
Create(mode, title, style, parameters);
|
||||||
|
|
||||||
#ifdef NAZARA_DEBUG
|
#ifdef NAZARA_DEBUG
|
||||||
if (!m_impl)
|
if (!m_impl)
|
||||||
{
|
{
|
||||||
NazaraError("Failed to create render window");
|
NazaraError("Failed to create render window");
|
||||||
throw std::runtime_error("Constructor failed");
|
throw std::runtime_error("Constructor failed");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
NzRenderWindow::NzRenderWindow(NzWindowHandle handle, const NzContextParameters& parameters)
|
NzRenderWindow::NzRenderWindow(NzWindowHandle handle, const NzContextParameters& parameters)
|
||||||
{
|
{
|
||||||
Create(handle, parameters);
|
Create(handle, parameters);
|
||||||
|
|
||||||
#ifdef NAZARA_DEBUG
|
#ifdef NAZARA_DEBUG
|
||||||
if (!m_impl)
|
if (!m_impl)
|
||||||
{
|
{
|
||||||
NazaraError("Failed to create render window");
|
NazaraError("Failed to create render window");
|
||||||
throw std::runtime_error("Constructor failed");
|
throw std::runtime_error("Constructor failed");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
NzRenderWindow::~NzRenderWindow()
|
NzRenderWindow::~NzRenderWindow()
|
||||||
{
|
{
|
||||||
// Nécessaire si NzWindow::Destroy est appelé par son destructeur
|
// Nécessaire si NzWindow::Destroy est appelé par son destructeur
|
||||||
OnWindowDestroying();
|
OnWindowDestroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NzRenderWindow::CopyToImage(NzImage* image)
|
bool NzRenderWindow::CopyToImage(NzImage* image)
|
||||||
{
|
{
|
||||||
#if NAZARA_RENDERER_SAFE
|
#if NAZARA_RENDERER_SAFE
|
||||||
if (!m_context)
|
if (!m_context)
|
||||||
{
|
{
|
||||||
NazaraError("Window has not been created");
|
NazaraError("Window has not been created");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!image)
|
if (!image)
|
||||||
{
|
{
|
||||||
NazaraError("Image must be valid");
|
NazaraError("Image must be valid");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (!m_context->SetActive(true))
|
if (!m_context->SetActive(true))
|
||||||
{
|
{
|
||||||
NazaraError("Failed to activate context");
|
NazaraError("Failed to activate context");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
NzVector2ui size = GetSize();
|
NzVector2ui size = GetSize();
|
||||||
|
|
||||||
if (!image->Create(nzImageType_2D, nzPixelFormat_RGBA8, size.x, size.y, 1, 1))
|
if (!image->Create(nzImageType_2D, nzPixelFormat_RGBA8, size.x, size.y, 1, 1))
|
||||||
{
|
{
|
||||||
NazaraError("Failed to create image");
|
NazaraError("Failed to create image");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
nzUInt8* pixels = image->GetPixels();
|
nzUInt8* pixels = image->GetPixels();
|
||||||
glReadPixels(0, 0, size.x, size.y, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
|
glReadPixels(0, 0, size.x, size.y, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
|
||||||
|
|
||||||
image->FlipVertically();
|
image->FlipVertically();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NzRenderWindow::CopyToTexture(NzTexture* texture)
|
bool NzRenderWindow::CopyToTexture(NzTexture* texture)
|
||||||
{
|
{
|
||||||
#if NAZARA_RENDERER_SAFE
|
#if NAZARA_RENDERER_SAFE
|
||||||
if (!m_context)
|
if (!m_context)
|
||||||
{
|
{
|
||||||
NazaraError("Window has not been created");
|
NazaraError("Window has not been created");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!texture)
|
if (!texture)
|
||||||
{
|
{
|
||||||
NazaraError("Texture must be valid");
|
NazaraError("Texture must be valid");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (!m_context->SetActive(true))
|
if (!m_context->SetActive(true))
|
||||||
{
|
{
|
||||||
NazaraError("Failed to activate context");
|
NazaraError("Failed to activate context");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
NzVector2ui size = GetSize();
|
NzVector2ui size = GetSize();
|
||||||
|
|
||||||
if (!texture->Create(nzImageType_2D, nzPixelFormat_RGBA8, size.x, size.y, 1, 1, true))
|
if (!texture->Create(nzImageType_2D, nzPixelFormat_RGBA8, size.x, size.y, 1, 1, true))
|
||||||
{
|
{
|
||||||
NazaraError("Failed to create texture");
|
NazaraError("Failed to create texture");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, size.x, size.y);
|
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, size.x, size.y);
|
||||||
|
|
||||||
texture->Unlock();
|
texture->Unlock();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NzRenderWindow::Create(NzVideoMode mode, const NzString& title, nzUInt32 style, const NzContextParameters& parameters)
|
bool NzRenderWindow::Create(NzVideoMode mode, const NzString& title, nzUInt32 style, const NzContextParameters& parameters)
|
||||||
{
|
{
|
||||||
m_parameters = parameters;
|
m_parameters = parameters;
|
||||||
return NzWindow::Create(mode, title, style);
|
return NzWindow::Create(mode, title, style);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NzRenderWindow::Create(NzWindowHandle handle, const NzContextParameters& parameters)
|
bool NzRenderWindow::Create(NzWindowHandle handle, const NzContextParameters& parameters)
|
||||||
{
|
{
|
||||||
m_parameters = parameters;
|
m_parameters = parameters;
|
||||||
return NzWindow::Create(handle);
|
return NzWindow::Create(handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
void NzRenderWindow::Display()
|
void NzRenderWindow::Display()
|
||||||
{
|
{
|
||||||
if (m_framerateLimit > 0)
|
if (m_framerateLimit > 0)
|
||||||
{
|
{
|
||||||
int remainingTime = 1000/m_framerateLimit - m_clock.GetMilliseconds();
|
int remainingTime = 1000/m_framerateLimit - m_clock.GetMilliseconds();
|
||||||
if (remainingTime > 0)
|
if (remainingTime > 0)
|
||||||
NzThread::Sleep(remainingTime);
|
NzThread::Sleep(remainingTime);
|
||||||
|
|
||||||
m_clock.Restart();
|
m_clock.Restart();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_context && m_parameters.doubleBuffered)
|
if (m_context && m_parameters.doubleBuffered)
|
||||||
m_context->SwapBuffers();
|
m_context->SwapBuffers();
|
||||||
}
|
}
|
||||||
|
|
||||||
void NzRenderWindow::EnableVerticalSync(bool enabled)
|
void NzRenderWindow::EnableVerticalSync(bool enabled)
|
||||||
{
|
{
|
||||||
if (m_context)
|
if (m_context)
|
||||||
{
|
{
|
||||||
#if defined(NAZARA_PLATFORM_WINDOWS)
|
#if defined(NAZARA_PLATFORM_WINDOWS)
|
||||||
if (!m_context->SetActive(true))
|
if (!m_context->SetActive(true))
|
||||||
{
|
{
|
||||||
NazaraError("Failed to activate context");
|
NazaraError("Failed to activate context");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (wglSwapInterval)
|
if (wglSwapInterval)
|
||||||
wglSwapInterval(enabled ? 1 : 0);
|
wglSwapInterval(enabled ? 1 : 0);
|
||||||
else
|
else
|
||||||
#elif defined(NAZARA_PLATFORM_LINUX)
|
#elif defined(NAZARA_PLATFORM_LINUX)
|
||||||
if (!m_context->SetActive(true))
|
if (!m_context->SetActive(true))
|
||||||
{
|
{
|
||||||
NazaraError("Failed to activate context");
|
NazaraError("Failed to activate context");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (glXSwapInterval)
|
if (glXSwapInterval)
|
||||||
glXSwapInterval(enabled ? 1 : 0);
|
glXSwapInterval(enabled ? 1 : 0);
|
||||||
else
|
else
|
||||||
#else
|
#else
|
||||||
#error Vertical Sync is not supported on this platform
|
#error Vertical Sync is not supported on this platform
|
||||||
#endif
|
#endif
|
||||||
NazaraError("Vertical Sync is not supported on this platform");
|
NazaraError("Vertical Sync is not supported on this platform");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
NazaraError("No context");
|
NazaraError("No context");
|
||||||
}
|
}
|
||||||
|
|
||||||
NzContextParameters NzRenderWindow::GetContextParameters() const
|
unsigned int NzRenderWindow::GetHeight() const
|
||||||
{
|
{
|
||||||
if (m_context)
|
return NzWindow::GetHeight();
|
||||||
return m_context->GetParameters();
|
}
|
||||||
else
|
|
||||||
{
|
NzRenderTargetParameters NzRenderWindow::GetParameters() const
|
||||||
NazaraError("Window not created/context not initialized");
|
{
|
||||||
return NzContextParameters();
|
if (m_context)
|
||||||
}
|
{
|
||||||
}
|
const NzContextParameters& parameters = m_context->GetParameters();
|
||||||
|
return NzRenderTargetParameters(parameters.antialiasingLevel, parameters.depthBits, parameters.stencilBits);
|
||||||
unsigned int NzRenderWindow::GetHeight() const
|
}
|
||||||
{
|
else
|
||||||
return NzWindow::GetHeight();
|
{
|
||||||
}
|
NazaraError("Window not created/context not initialized");
|
||||||
|
return NzRenderTargetParameters();
|
||||||
NzRenderTargetParameters NzRenderWindow::GetParameters() const
|
}
|
||||||
{
|
}
|
||||||
if (m_context)
|
|
||||||
{
|
unsigned int NzRenderWindow::GetWidth() const
|
||||||
const NzContextParameters& parameters = m_context->GetParameters();
|
{
|
||||||
return NzRenderTargetParameters(parameters.antialiasingLevel, parameters.depthBits, parameters.stencilBits);
|
return NzWindow::GetWidth();
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
bool NzRenderWindow::IsRenderable() const
|
||||||
NazaraError("Window not created/context not initialized");
|
{
|
||||||
return NzRenderTargetParameters();
|
return m_impl != nullptr; // Si m_impl est valide, alors m_context l'est aussi
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
void NzRenderWindow::SetFramerateLimit(unsigned int limit)
|
||||||
unsigned int NzRenderWindow::GetWidth() const
|
{
|
||||||
{
|
m_framerateLimit = limit;
|
||||||
return NzWindow::GetWidth();
|
}
|
||||||
}
|
|
||||||
|
NzContextParameters NzRenderWindow::GetContextParameters() const
|
||||||
bool NzRenderWindow::HasContext() const
|
{
|
||||||
{
|
if (m_context)
|
||||||
return true;
|
return m_context->GetParameters();
|
||||||
}
|
else
|
||||||
|
{
|
||||||
bool NzRenderWindow::IsValid() const
|
NazaraError("Window not created/context not initialized");
|
||||||
{
|
return NzContextParameters();
|
||||||
return m_impl != nullptr && m_context != nullptr;
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void NzRenderWindow::SetFramerateLimit(unsigned int limit)
|
bool NzRenderWindow::HasContext() const
|
||||||
{
|
{
|
||||||
m_framerateLimit = limit;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NzRenderWindow::Activate()
|
bool NzRenderWindow::Activate()
|
||||||
{
|
{
|
||||||
if (m_context->SetActive(true))
|
if (m_context->SetActive(true))
|
||||||
{
|
{
|
||||||
glDrawBuffer((m_parameters.doubleBuffered) ? GL_BACK : GL_FRONT);
|
glDrawBuffer((m_parameters.doubleBuffered) ? GL_BACK : GL_FRONT);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
NazaraError("Failed to activate window's context");
|
NazaraError("Failed to activate window's context");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void NzRenderWindow::OnWindowDestroying()
|
bool NzRenderWindow::OnWindowCreated()
|
||||||
{
|
{
|
||||||
if (m_context)
|
m_parameters.doubleBuffered = true;
|
||||||
{
|
m_parameters.window = GetHandle();
|
||||||
delete m_context;
|
|
||||||
m_context = nullptr;
|
m_context = new NzContext;
|
||||||
}
|
if (!m_context->Create(m_parameters))
|
||||||
}
|
{
|
||||||
|
NazaraError("Failed not create context");
|
||||||
bool NzRenderWindow::OnWindowCreated()
|
delete m_context;
|
||||||
{
|
|
||||||
m_parameters.doubleBuffered = true;
|
return false;
|
||||||
m_parameters.window = GetHandle();
|
}
|
||||||
|
|
||||||
m_context = new NzContext;
|
EnableVerticalSync(false);
|
||||||
if (!m_context->Create(m_parameters))
|
|
||||||
{
|
if (!SetActive(true)) // Les fenêtres s'activent à la création
|
||||||
NazaraError("Failed not create context");
|
NazaraWarning("Failed to activate window");
|
||||||
delete m_context;
|
|
||||||
|
m_clock.Restart();
|
||||||
return false;
|
|
||||||
}
|
return true;
|
||||||
|
}
|
||||||
EnableVerticalSync(false);
|
|
||||||
|
void NzRenderWindow::OnWindowDestroy()
|
||||||
#if NAZARA_RENDERER_ACTIVATE_RENDERWINDOW_ON_CREATION
|
{
|
||||||
if (!SetActive(true)) // Les fenêtres s'activent à la création
|
if (m_context)
|
||||||
NazaraWarning("Failed to activate window");
|
{
|
||||||
#endif
|
delete m_context;
|
||||||
|
m_context = nullptr;
|
||||||
m_clock.Restart();
|
}
|
||||||
|
}
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
|
@ -1,231 +1,234 @@
|
||||||
// Copyright (C) 2012 Jérôme Leclercq
|
// Copyright (C) 2012 Jérôme Leclercq
|
||||||
// This file is part of the "Nazara Engine - Renderer module"
|
// This file is part of the "Nazara Engine - Renderer module"
|
||||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||||
|
|
||||||
// Code inspiré de NeHe (Lesson1) et de la SFML par Laurent Gomila
|
// Code inspiré de NeHe (Lesson1) et de la SFML par Laurent Gomila
|
||||||
|
|
||||||
#include <Nazara/Renderer/OpenGL.hpp>
|
#include <Nazara/Renderer/OpenGL.hpp>
|
||||||
#include <Nazara/Renderer/Win32/ContextImpl.hpp>
|
#include <Nazara/Renderer/Win32/ContextImpl.hpp>
|
||||||
#include <Nazara/Core/Error.hpp>
|
#include <Nazara/Core/Error.hpp>
|
||||||
#include <Nazara/Core/LockGuard.hpp>
|
#include <Nazara/Core/LockGuard.hpp>
|
||||||
#include <Nazara/Core/Mutex.hpp>
|
#include <Nazara/Core/Mutex.hpp>
|
||||||
#include <Nazara/Renderer/Context.hpp>
|
#include <Nazara/Renderer/Context.hpp>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <Nazara/Renderer/Debug.hpp>
|
#include <Nazara/Renderer/Debug.hpp>
|
||||||
|
|
||||||
NzContextImpl::NzContextImpl()
|
NzContextImpl::NzContextImpl()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NzContextImpl::Activate()
|
bool NzContextImpl::Activate()
|
||||||
{
|
{
|
||||||
return wglMakeCurrent(m_deviceContext, m_context);
|
return wglMakeCurrent(m_deviceContext, m_context);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NzContextImpl::Create(NzContextParameters& parameters)
|
bool NzContextImpl::Create(NzContextParameters& parameters)
|
||||||
{
|
{
|
||||||
if (parameters.window)
|
if (parameters.window)
|
||||||
{
|
{
|
||||||
m_window = static_cast<HWND>(parameters.window);
|
m_window = static_cast<HWND>(parameters.window);
|
||||||
m_ownsWindow = false;
|
m_ownsWindow = false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
m_window = CreateWindowA("STATIC", nullptr, WS_DISABLED | WS_POPUP, 0, 0, 1, 1, nullptr, nullptr, GetModuleHandle(nullptr), nullptr);
|
m_window = CreateWindowA("STATIC", nullptr, WS_DISABLED | WS_POPUP, 0, 0, 1, 1, nullptr, nullptr, GetModuleHandle(nullptr), nullptr);
|
||||||
if (!m_window)
|
if (!m_window)
|
||||||
{
|
{
|
||||||
NazaraError("Failed to create window");
|
NazaraError("Failed to create window");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
ShowWindow(m_window, SW_HIDE);
|
ShowWindow(m_window, SW_HIDE);
|
||||||
m_ownsWindow = true;
|
m_ownsWindow = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_deviceContext = GetDC(m_window);
|
m_deviceContext = GetDC(m_window);
|
||||||
if (!m_deviceContext)
|
if (!m_deviceContext)
|
||||||
{
|
{
|
||||||
NazaraError("Failed to get device context");
|
NazaraError("Failed to get device context");
|
||||||
Destroy();
|
Destroy();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
int pixelFormat = 0;
|
int pixelFormat = 0;
|
||||||
if (parameters.antialiasingLevel > 0)
|
if (parameters.antialiasingLevel > 0)
|
||||||
{
|
{
|
||||||
if (wglChoosePixelFormat)
|
if (wglChoosePixelFormat)
|
||||||
{
|
{
|
||||||
bool valid;
|
bool valid;
|
||||||
UINT numFormats;
|
UINT numFormats;
|
||||||
|
|
||||||
int attributes[] = {
|
int attributes[] = {
|
||||||
WGL_DRAW_TO_WINDOW_ARB, GL_TRUE,
|
WGL_DRAW_TO_WINDOW_ARB, GL_TRUE,
|
||||||
WGL_SUPPORT_OPENGL_ARB, GL_TRUE,
|
WGL_SUPPORT_OPENGL_ARB, GL_TRUE,
|
||||||
WGL_ACCELERATION_ARB, WGL_FULL_ACCELERATION_ARB,
|
WGL_ACCELERATION_ARB, WGL_FULL_ACCELERATION_ARB,
|
||||||
WGL_COLOR_BITS_ARB, (parameters.bitsPerPixel == 32) ? 24 : parameters.bitsPerPixel,
|
WGL_COLOR_BITS_ARB, (parameters.bitsPerPixel == 32) ? 24 : parameters.bitsPerPixel,
|
||||||
WGL_ALPHA_BITS_ARB, (parameters.bitsPerPixel == 32) ? 8 : 0,
|
WGL_ALPHA_BITS_ARB, (parameters.bitsPerPixel == 32) ? 8 : 0,
|
||||||
WGL_DEPTH_BITS_ARB, parameters.depthBits,
|
WGL_DEPTH_BITS_ARB, parameters.depthBits,
|
||||||
WGL_STENCIL_BITS_ARB, parameters.stencilBits,
|
WGL_STENCIL_BITS_ARB, parameters.stencilBits,
|
||||||
WGL_DOUBLE_BUFFER_ARB, (parameters.doubleBuffered) ? GL_TRUE : GL_FALSE,
|
WGL_DOUBLE_BUFFER_ARB, (parameters.doubleBuffered) ? GL_TRUE : GL_FALSE,
|
||||||
WGL_SAMPLE_BUFFERS_ARB, GL_TRUE,
|
WGL_SAMPLE_BUFFERS_ARB, GL_TRUE,
|
||||||
WGL_SAMPLES_ARB, parameters.antialiasingLevel,
|
WGL_SAMPLES_ARB, parameters.antialiasingLevel,
|
||||||
0, 0
|
0, 0
|
||||||
};
|
};
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
valid = wglChoosePixelFormat(m_deviceContext, attributes, nullptr, 1, &pixelFormat, &numFormats);
|
valid = wglChoosePixelFormat(m_deviceContext, attributes, nullptr, 1, &pixelFormat, &numFormats);
|
||||||
}
|
}
|
||||||
while ((!valid || numFormats == 0) && --attributes[19] > 0);
|
while ((!valid || numFormats == 0) && --attributes[19] > 0);
|
||||||
|
|
||||||
if (!valid)
|
if (!valid)
|
||||||
{
|
{
|
||||||
NazaraWarning("Could not find a format matching requirements, disabling antialiasing...");
|
NazaraWarning("Could not find a format matching requirements, disabling antialiasing...");
|
||||||
pixelFormat = 0;
|
pixelFormat = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
parameters.antialiasingLevel = attributes[19];
|
parameters.antialiasingLevel = attributes[19];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
NazaraWarning("Antialiasing is not supported");
|
NazaraWarning("Antialiasing is not supported");
|
||||||
parameters.antialiasingLevel = 0;
|
parameters.antialiasingLevel = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
PIXELFORMATDESCRIPTOR descriptor;
|
PIXELFORMATDESCRIPTOR descriptor;
|
||||||
ZeroMemory(&descriptor, sizeof(PIXELFORMATDESCRIPTOR));
|
ZeroMemory(&descriptor, sizeof(PIXELFORMATDESCRIPTOR));
|
||||||
descriptor.nSize = sizeof(PIXELFORMATDESCRIPTOR);
|
descriptor.nSize = sizeof(PIXELFORMATDESCRIPTOR);
|
||||||
descriptor.nVersion = 1;
|
descriptor.nVersion = 1;
|
||||||
|
|
||||||
if (pixelFormat == 0)
|
if (pixelFormat == 0)
|
||||||
{
|
{
|
||||||
descriptor.cColorBits = parameters.bitsPerPixel;
|
descriptor.cColorBits = parameters.bitsPerPixel;
|
||||||
descriptor.cDepthBits = parameters.depthBits;
|
descriptor.cDepthBits = parameters.depthBits;
|
||||||
descriptor.cStencilBits = parameters.stencilBits;
|
descriptor.cStencilBits = parameters.stencilBits;
|
||||||
descriptor.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL;
|
descriptor.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL;
|
||||||
descriptor.iPixelType = PFD_TYPE_RGBA;
|
descriptor.iPixelType = PFD_TYPE_RGBA;
|
||||||
|
|
||||||
if (parameters.bitsPerPixel == 32)
|
if (parameters.bitsPerPixel == 32)
|
||||||
descriptor.cAlphaBits = 8;
|
descriptor.cAlphaBits = 8;
|
||||||
|
|
||||||
if (parameters.doubleBuffered)
|
if (parameters.doubleBuffered)
|
||||||
descriptor.dwFlags |= PFD_DOUBLEBUFFER;
|
descriptor.dwFlags |= PFD_DOUBLEBUFFER;
|
||||||
|
|
||||||
pixelFormat = ChoosePixelFormat(m_deviceContext, &descriptor);
|
pixelFormat = ChoosePixelFormat(m_deviceContext, &descriptor);
|
||||||
if (pixelFormat == 0)
|
if (pixelFormat == 0)
|
||||||
{
|
{
|
||||||
NazaraError("Failed to choose pixel format");
|
NazaraError("Failed to choose pixel format");
|
||||||
Destroy();
|
Destroy();
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!SetPixelFormat(m_deviceContext, pixelFormat, &descriptor))
|
if (!SetPixelFormat(m_deviceContext, pixelFormat, &descriptor))
|
||||||
{
|
{
|
||||||
NazaraError("Failed to set pixel format");
|
NazaraError("Failed to set pixel format");
|
||||||
Destroy();
|
Destroy();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Arrivé ici, le format de pixel est choisi, nous récupérons donc les paramètres réels du futur contexte
|
// Arrivé ici, le format de pixel est choisi, nous récupérons donc les paramètres réels du futur contexte
|
||||||
if (DescribePixelFormat(m_deviceContext, pixelFormat, sizeof(PIXELFORMATDESCRIPTOR), &descriptor) != 0)
|
if (DescribePixelFormat(m_deviceContext, pixelFormat, sizeof(PIXELFORMATDESCRIPTOR), &descriptor) != 0)
|
||||||
{
|
{
|
||||||
parameters.bitsPerPixel = descriptor.cColorBits + descriptor.cAlphaBits;
|
parameters.bitsPerPixel = descriptor.cColorBits + descriptor.cAlphaBits;
|
||||||
parameters.depthBits = descriptor.cDepthBits;
|
parameters.depthBits = descriptor.cDepthBits;
|
||||||
parameters.stencilBits = descriptor.cDepthBits;
|
parameters.stencilBits = descriptor.cDepthBits;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
NazaraWarning("Failed to get context's parameters");
|
NazaraWarning("Failed to get context's parameters");
|
||||||
|
|
||||||
HGLRC shareContext = (parameters.shared) ? static_cast<NzContextImpl*>(parameters.shareContext->m_impl)->m_context : nullptr;
|
HGLRC shareContext = (parameters.shared) ? static_cast<NzContextImpl*>(parameters.shareContext->m_impl)->m_context : nullptr;
|
||||||
|
|
||||||
m_context = nullptr;
|
m_context = nullptr;
|
||||||
if (wglCreateContextAttribs)
|
if (wglCreateContextAttribs)
|
||||||
{
|
{
|
||||||
int attributes[4*2+1];
|
int attributes[4*2+1];
|
||||||
int* attrib = attributes;
|
int* attrib = attributes;
|
||||||
|
|
||||||
*attrib++ = WGL_CONTEXT_MAJOR_VERSION_ARB;
|
*attrib++ = WGL_CONTEXT_MAJOR_VERSION_ARB;
|
||||||
*attrib++ = parameters.majorVersion;
|
*attrib++ = parameters.majorVersion;
|
||||||
|
|
||||||
*attrib++ = WGL_CONTEXT_MINOR_VERSION_ARB;
|
*attrib++ = WGL_CONTEXT_MINOR_VERSION_ARB;
|
||||||
*attrib++ = parameters.minorVersion;
|
*attrib++ = parameters.minorVersion;
|
||||||
|
|
||||||
int flags = 0;
|
if (parameters.majorVersion >= 3)
|
||||||
|
{
|
||||||
if (parameters.majorVersion >= 3)
|
*attrib++ = WGL_CONTEXT_PROFILE_MASK_ARB;
|
||||||
{
|
*attrib++ = (parameters.compatibilityProfile) ? WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB : WGL_CONTEXT_CORE_PROFILE_BIT_ARB;
|
||||||
*attrib++ = WGL_CONTEXT_PROFILE_MASK_ARB;
|
}
|
||||||
if (parameters.compatibilityProfile)
|
|
||||||
*attrib++ = WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB;
|
if (parameters.debugMode)
|
||||||
else
|
{
|
||||||
{
|
*attrib++ = WGL_CONTEXT_FLAGS_ARB;
|
||||||
*attrib++ = WGL_CONTEXT_CORE_PROFILE_BIT_ARB;
|
*attrib++ = WGL_CONTEXT_DEBUG_BIT_ARB;
|
||||||
|
|
||||||
flags |= WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB;
|
// Les contextes forward-compatible ne sont plus utilisés pour cette raison :
|
||||||
}
|
// http://www.opengl.org/discussion_boards/showthread.php/175052-Forward-compatible-vs-Core-profile
|
||||||
}
|
}
|
||||||
|
|
||||||
if (parameters.debugMode)
|
*attrib++ = 0;
|
||||||
flags |= WGL_CONTEXT_DEBUG_BIT_ARB;
|
|
||||||
|
m_context = wglCreateContextAttribs(m_deviceContext, shareContext, attributes);
|
||||||
if (flags)
|
}
|
||||||
{
|
|
||||||
*attrib++ = WGL_CONTEXT_FLAGS_ARB;
|
if (!m_context)
|
||||||
*attrib++ = flags;
|
{
|
||||||
}
|
m_context = wglCreateContext(m_deviceContext);
|
||||||
|
|
||||||
*attrib++ = 0;
|
if (shareContext)
|
||||||
|
{
|
||||||
m_context = wglCreateContextAttribs(m_deviceContext, shareContext, attributes);
|
// wglShareLists n'est pas thread-safe (source: SFML)
|
||||||
}
|
static NzMutex mutex;
|
||||||
|
NzLockGuard lock(mutex);
|
||||||
if (!m_context)
|
|
||||||
{
|
if (!wglShareLists(shareContext, m_context))
|
||||||
m_context = wglCreateContext(m_deviceContext);
|
NazaraWarning("Failed to share the context: " + NzGetLastSystemError());
|
||||||
|
}
|
||||||
if (shareContext)
|
}
|
||||||
{
|
|
||||||
// wglShareLists n'est pas thread-safe (source: SFML)
|
if (!m_context)
|
||||||
static NzMutex mutex;
|
{
|
||||||
NzLockGuard lock(mutex);
|
NazaraError("Failed to create context");
|
||||||
|
Destroy();
|
||||||
if (!wglShareLists(shareContext, m_context))
|
return false;
|
||||||
NazaraWarning("Failed to share the context: " + NzGetLastSystemError());
|
}
|
||||||
}
|
|
||||||
}
|
return true;
|
||||||
|
}
|
||||||
if (!m_context)
|
|
||||||
{
|
void NzContextImpl::Destroy()
|
||||||
NazaraError("Failed to create context");
|
{
|
||||||
Destroy();
|
if (m_context)
|
||||||
return false;
|
{
|
||||||
}
|
if (wglGetCurrentContext() == m_context)
|
||||||
|
wglMakeCurrent(nullptr, nullptr);
|
||||||
return true;
|
|
||||||
}
|
wglDeleteContext(m_context);
|
||||||
|
m_context = nullptr;
|
||||||
void NzContextImpl::Destroy()
|
}
|
||||||
{
|
|
||||||
if (m_context)
|
if (m_deviceContext)
|
||||||
wglDeleteContext(m_context);
|
{
|
||||||
|
ReleaseDC(m_window, m_deviceContext);
|
||||||
if (m_deviceContext)
|
m_deviceContext = nullptr;
|
||||||
ReleaseDC(m_window, m_deviceContext);
|
}
|
||||||
|
|
||||||
if (m_ownsWindow)
|
if (m_ownsWindow)
|
||||||
DestroyWindow(m_window);
|
{
|
||||||
}
|
DestroyWindow(m_window);
|
||||||
|
m_window = nullptr;
|
||||||
void NzContextImpl::SwapBuffers()
|
}
|
||||||
{
|
}
|
||||||
::SwapBuffers(m_deviceContext);
|
|
||||||
}
|
void NzContextImpl::SwapBuffers()
|
||||||
|
{
|
||||||
bool NzContextImpl::Desactivate()
|
::SwapBuffers(m_deviceContext);
|
||||||
{
|
}
|
||||||
return wglMakeCurrent(nullptr, nullptr);
|
|
||||||
}
|
bool NzContextImpl::Desactivate()
|
||||||
|
{
|
||||||
|
return wglMakeCurrent(nullptr, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,317 +1,342 @@
|
||||||
// Copyright (C) 2012 Jérôme Leclercq
|
// Copyright (C) 2012 Jérôme Leclercq
|
||||||
// This file is part of the "Nazara Engine - Utility module"
|
// This file is part of the "Nazara Engine - Utility module"
|
||||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||||
|
|
||||||
#include <Nazara/Utility/Animation.hpp>
|
#include <Nazara/Utility/Animation.hpp>
|
||||||
#include <Nazara/Core/Error.hpp>
|
#include <Nazara/Core/Error.hpp>
|
||||||
#include <Nazara/Utility/Config.hpp>
|
#include <Nazara/Utility/Config.hpp>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <Nazara/Utility/Debug.hpp>
|
#include <Nazara/Utility/Debug.hpp>
|
||||||
|
|
||||||
struct NzAnimationImpl
|
struct NzAnimationImpl
|
||||||
{
|
{
|
||||||
std::map<NzString, unsigned int> sequenceMap;
|
std::map<NzString, unsigned int> sequenceMap;
|
||||||
std::vector<NzSequence> sequences;
|
std::vector<NzSequence> sequences;
|
||||||
nzAnimationType type;
|
nzAnimationType type;
|
||||||
unsigned int frameCount;
|
unsigned int frameCount;
|
||||||
};
|
};
|
||||||
|
|
||||||
bool NzAnimationParams::IsValid() const
|
bool NzAnimationParams::IsValid() const
|
||||||
{
|
{
|
||||||
if (startFrame > endFrame)
|
if (startFrame > endFrame)
|
||||||
{
|
{
|
||||||
NazaraError("Start frame must be lower than end frame");
|
NazaraError("Start frame must be lower than end frame");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
NzAnimation::~NzAnimation()
|
NzAnimation::~NzAnimation()
|
||||||
{
|
{
|
||||||
Destroy();
|
Destroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int NzAnimation::AddSequence(const NzSequence& sequence)
|
bool NzAnimation::AddSequence(const NzSequence& sequence)
|
||||||
{
|
{
|
||||||
#if NAZARA_UTILITY_SAFE
|
#if NAZARA_UTILITY_SAFE
|
||||||
if (!m_impl)
|
if (!m_impl)
|
||||||
{
|
{
|
||||||
NazaraError("Animation not created");
|
NazaraError("Animation not created");
|
||||||
return 0;
|
return false;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
unsigned int index = m_impl->sequences.size();
|
unsigned int index = m_impl->sequences.size();
|
||||||
|
|
||||||
if (!sequence.name.IsEmpty())
|
if (!sequence.name.IsEmpty())
|
||||||
{
|
{
|
||||||
#if NAZARA_UTILITY_SAFE
|
#if NAZARA_UTILITY_SAFE
|
||||||
auto it = m_impl->sequenceMap.find(sequence.name);
|
auto it = m_impl->sequenceMap.find(sequence.name);
|
||||||
if (it != m_impl->sequenceMap.end())
|
if (it != m_impl->sequenceMap.end())
|
||||||
{
|
{
|
||||||
NazaraError("Sequence name \"" + sequence.name + "\" is already used");
|
NazaraError("Sequence name \"" + sequence.name + "\" is already used");
|
||||||
return 0;
|
return false;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
m_impl->sequenceMap[sequence.name] = index;
|
m_impl->sequenceMap[sequence.name] = index;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_impl->sequences.push_back(sequence);
|
m_impl->sequences.push_back(sequence);
|
||||||
|
|
||||||
return index;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NzAnimation::Create(nzAnimationType type, unsigned int frameCount)
|
bool NzAnimation::Create(nzAnimationType type, unsigned int frameCount)
|
||||||
{
|
{
|
||||||
Destroy();
|
Destroy();
|
||||||
|
|
||||||
#if NAZARA_UTILITY_SAFE
|
#if NAZARA_UTILITY_SAFE
|
||||||
if (type == nzAnimationType_Static)
|
if (type == nzAnimationType_Static)
|
||||||
{
|
{
|
||||||
NazaraError("Invalid type");
|
NazaraError("Invalid type");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (frameCount == 0)
|
if (frameCount == 0)
|
||||||
{
|
{
|
||||||
NazaraError("Frame count must be over zero");
|
NazaraError("Frame count must be over zero");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
m_impl = new NzAnimationImpl;
|
m_impl = new NzAnimationImpl;
|
||||||
m_impl->frameCount = frameCount;
|
m_impl->frameCount = frameCount;
|
||||||
m_impl->type = type;
|
m_impl->type = type;
|
||||||
|
|
||||||
return true;
|
NotifyCreated();
|
||||||
}
|
return true;
|
||||||
|
}
|
||||||
void NzAnimation::Destroy()
|
|
||||||
{
|
void NzAnimation::Destroy()
|
||||||
if (m_impl)
|
{
|
||||||
{
|
if (m_impl)
|
||||||
delete m_impl;
|
{
|
||||||
m_impl = nullptr;
|
NotifyDestroy();
|
||||||
}
|
|
||||||
}
|
delete m_impl;
|
||||||
|
m_impl = nullptr;
|
||||||
unsigned int NzAnimation::GetFrameCount() const
|
}
|
||||||
{
|
}
|
||||||
#if NAZARA_UTILITY_SAFE
|
|
||||||
if (!m_impl)
|
unsigned int NzAnimation::GetFrameCount() const
|
||||||
{
|
{
|
||||||
NazaraError("Animation not created");
|
#if NAZARA_UTILITY_SAFE
|
||||||
return false;
|
if (!m_impl)
|
||||||
}
|
{
|
||||||
#endif
|
NazaraError("Animation not created");
|
||||||
|
return false;
|
||||||
return m_impl->frameCount;
|
}
|
||||||
}
|
#endif
|
||||||
|
|
||||||
NzSequence* NzAnimation::GetSequence(const NzString& sequenceName)
|
return m_impl->frameCount;
|
||||||
{
|
}
|
||||||
#if NAZARA_UTILITY_SAFE
|
|
||||||
if (!m_impl)
|
NzSequence* NzAnimation::GetSequence(const NzString& sequenceName)
|
||||||
{
|
{
|
||||||
NazaraError("Animation not created");
|
#if NAZARA_UTILITY_SAFE
|
||||||
return nullptr;
|
if (!m_impl)
|
||||||
}
|
{
|
||||||
|
NazaraError("Animation not created");
|
||||||
auto it = m_impl->sequenceMap.find(sequenceName);
|
return nullptr;
|
||||||
if (it == m_impl->sequenceMap.end())
|
}
|
||||||
{
|
|
||||||
NazaraError("Sequence not found");
|
auto it = m_impl->sequenceMap.find(sequenceName);
|
||||||
return nullptr;
|
if (it == m_impl->sequenceMap.end())
|
||||||
}
|
{
|
||||||
|
NazaraError("Sequence not found");
|
||||||
return &m_impl->sequences[it->second];
|
return nullptr;
|
||||||
#else
|
}
|
||||||
return &m_impl->sequences[m_impl->sequenceMap[sequenceName]];
|
|
||||||
#endif
|
return &m_impl->sequences[it->second];
|
||||||
}
|
#else
|
||||||
|
return &m_impl->sequences[m_impl->sequenceMap[sequenceName]];
|
||||||
NzSequence* NzAnimation::GetSequence(unsigned int index)
|
#endif
|
||||||
{
|
}
|
||||||
#if NAZARA_UTILITY_SAFE
|
|
||||||
if (!m_impl)
|
NzSequence* NzAnimation::GetSequence(unsigned int index)
|
||||||
{
|
{
|
||||||
NazaraError("Animation not created");
|
#if NAZARA_UTILITY_SAFE
|
||||||
return nullptr;
|
if (!m_impl)
|
||||||
}
|
{
|
||||||
|
NazaraError("Animation not created");
|
||||||
if (index >= m_impl->sequences.size())
|
return nullptr;
|
||||||
{
|
}
|
||||||
NazaraError("Sequence index out of range (" + NzString::Number(index) + " >= " + NzString::Number(m_impl->sequences.size()) + ')');
|
|
||||||
return nullptr;
|
if (index >= m_impl->sequences.size())
|
||||||
}
|
{
|
||||||
#endif
|
NazaraError("Sequence index out of range (" + NzString::Number(index) + " >= " + NzString::Number(m_impl->sequences.size()) + ')');
|
||||||
|
return nullptr;
|
||||||
return &m_impl->sequences[index];
|
}
|
||||||
}
|
#endif
|
||||||
|
|
||||||
const NzSequence* NzAnimation::GetSequence(const NzString& sequenceName) const
|
return &m_impl->sequences[index];
|
||||||
{
|
}
|
||||||
#if NAZARA_UTILITY_SAFE
|
|
||||||
if (!m_impl)
|
const NzSequence* NzAnimation::GetSequence(const NzString& sequenceName) const
|
||||||
{
|
{
|
||||||
NazaraError("Animation not created");
|
#if NAZARA_UTILITY_SAFE
|
||||||
return nullptr;
|
if (!m_impl)
|
||||||
}
|
{
|
||||||
|
NazaraError("Animation not created");
|
||||||
auto it = m_impl->sequenceMap.find(sequenceName);
|
return nullptr;
|
||||||
if (it == m_impl->sequenceMap.end())
|
}
|
||||||
{
|
|
||||||
NazaraError("Sequence not found");
|
auto it = m_impl->sequenceMap.find(sequenceName);
|
||||||
return nullptr;
|
if (it == m_impl->sequenceMap.end())
|
||||||
}
|
{
|
||||||
|
NazaraError("Sequence not found");
|
||||||
return &m_impl->sequences[it->second];
|
return nullptr;
|
||||||
#else
|
}
|
||||||
return &m_impl->sequences[m_impl->sequenceMap[sequenceName]];
|
|
||||||
#endif
|
return &m_impl->sequences[it->second];
|
||||||
}
|
#else
|
||||||
|
return &m_impl->sequences[m_impl->sequenceMap[sequenceName]];
|
||||||
const NzSequence* NzAnimation::GetSequence(unsigned int index) const
|
#endif
|
||||||
{
|
}
|
||||||
#if NAZARA_UTILITY_SAFE
|
|
||||||
if (!m_impl)
|
const NzSequence* NzAnimation::GetSequence(unsigned int index) const
|
||||||
{
|
{
|
||||||
NazaraError("Animation not created");
|
#if NAZARA_UTILITY_SAFE
|
||||||
return nullptr;
|
if (!m_impl)
|
||||||
}
|
{
|
||||||
|
NazaraError("Animation not created");
|
||||||
if (index >= m_impl->sequences.size())
|
return nullptr;
|
||||||
{
|
}
|
||||||
NazaraError("Sequence index out of range (" + NzString::Number(index) + " >= " + NzString::Number(m_impl->sequences.size()) + ')');
|
|
||||||
return nullptr;
|
if (index >= m_impl->sequences.size())
|
||||||
}
|
{
|
||||||
#endif
|
NazaraError("Sequence index out of range (" + NzString::Number(index) + " >= " + NzString::Number(m_impl->sequences.size()) + ')');
|
||||||
|
return nullptr;
|
||||||
return &m_impl->sequences[index];
|
}
|
||||||
}
|
#endif
|
||||||
|
|
||||||
unsigned int NzAnimation::GetSequenceCount() const
|
return &m_impl->sequences[index];
|
||||||
{
|
}
|
||||||
#if NAZARA_UTILITY_SAFE
|
|
||||||
if (!m_impl)
|
unsigned int NzAnimation::GetSequenceCount() const
|
||||||
{
|
{
|
||||||
NazaraError("Animation not created");
|
#if NAZARA_UTILITY_SAFE
|
||||||
return 0;
|
if (!m_impl)
|
||||||
}
|
{
|
||||||
#endif
|
NazaraError("Animation not created");
|
||||||
|
return 0;
|
||||||
return m_impl->sequences.size();
|
}
|
||||||
}
|
#endif
|
||||||
|
|
||||||
nzAnimationType NzAnimation::GetType() const
|
return m_impl->sequences.size();
|
||||||
{
|
}
|
||||||
#if NAZARA_UTILITY_SAFE
|
|
||||||
if (!m_impl)
|
int NzAnimation::GetSequenceIndex(const NzString& sequenceName) const
|
||||||
{
|
{
|
||||||
NazaraError("Animation not created");
|
#if NAZARA_UTILITY_SAFE
|
||||||
return nzAnimationType_Static; // Ce qui est une valeur invalide pour NzAnimation
|
if (!m_impl)
|
||||||
}
|
{
|
||||||
#endif
|
NazaraError("Animation not created");
|
||||||
|
return -1;
|
||||||
return m_impl->type;
|
}
|
||||||
}
|
|
||||||
|
auto it = m_impl->sequenceMap.find(sequenceName);
|
||||||
bool NzAnimation::HasSequence(const NzString& sequenceName) const
|
if (it == m_impl->sequenceMap.end())
|
||||||
{
|
{
|
||||||
#if NAZARA_UTILITY_SAFE
|
NazaraError("Sequence not found");
|
||||||
if (!m_impl)
|
return -1;
|
||||||
{
|
}
|
||||||
NazaraError("Animation not created");
|
|
||||||
return false;
|
return it->second;
|
||||||
}
|
#else
|
||||||
#endif
|
return m_impl->sequenceMap[sequenceName];
|
||||||
|
#endif
|
||||||
return m_impl->sequenceMap.find(sequenceName) != m_impl->sequenceMap.end();
|
}
|
||||||
}
|
|
||||||
|
nzAnimationType NzAnimation::GetType() const
|
||||||
bool NzAnimation::HasSequence(unsigned int index) const
|
{
|
||||||
{
|
#if NAZARA_UTILITY_SAFE
|
||||||
#if NAZARA_UTILITY_SAFE
|
if (!m_impl)
|
||||||
if (!m_impl)
|
{
|
||||||
{
|
NazaraError("Animation not created");
|
||||||
NazaraError("Animation not created");
|
return nzAnimationType_Static; // Ce qui est une valeur invalide pour NzAnimation
|
||||||
return false;
|
}
|
||||||
}
|
#endif
|
||||||
#endif
|
|
||||||
|
return m_impl->type;
|
||||||
return index >= m_impl->sequences.size();
|
}
|
||||||
}
|
|
||||||
|
bool NzAnimation::HasSequence(const NzString& sequenceName) const
|
||||||
bool NzAnimation::IsValid() const
|
{
|
||||||
{
|
#if NAZARA_UTILITY_SAFE
|
||||||
return m_impl != nullptr;
|
if (!m_impl)
|
||||||
}
|
{
|
||||||
|
NazaraError("Animation not created");
|
||||||
bool NzAnimation::LoadFromFile(const NzString& filePath, const NzAnimationParams& params)
|
return false;
|
||||||
{
|
}
|
||||||
return NzAnimationLoader::LoadFromFile(this, filePath, params);
|
#endif
|
||||||
}
|
|
||||||
|
return m_impl->sequenceMap.find(sequenceName) != m_impl->sequenceMap.end();
|
||||||
bool NzAnimation::LoadFromMemory(const void* data, std::size_t size, const NzAnimationParams& params)
|
}
|
||||||
{
|
|
||||||
return NzAnimationLoader::LoadFromMemory(this, data, size, params);
|
bool NzAnimation::HasSequence(unsigned int index) const
|
||||||
}
|
{
|
||||||
|
#if NAZARA_UTILITY_SAFE
|
||||||
bool NzAnimation::LoadFromStream(NzInputStream& stream, const NzAnimationParams& params)
|
if (!m_impl)
|
||||||
{
|
{
|
||||||
return NzAnimationLoader::LoadFromStream(this, stream, params);
|
NazaraError("Animation not created");
|
||||||
}
|
return false;
|
||||||
|
}
|
||||||
void NzAnimation::RemoveSequence(const NzString& identifier)
|
#endif
|
||||||
{
|
|
||||||
#if NAZARA_UTILITY_SAFE
|
return index >= m_impl->sequences.size();
|
||||||
if (!m_impl)
|
}
|
||||||
{
|
|
||||||
NazaraError("Animation not created");
|
bool NzAnimation::IsValid() const
|
||||||
return;
|
{
|
||||||
}
|
return m_impl != nullptr;
|
||||||
|
}
|
||||||
auto it = m_impl->sequenceMap.find(identifier);
|
|
||||||
if (it == m_impl->sequenceMap.end())
|
bool NzAnimation::LoadFromFile(const NzString& filePath, const NzAnimationParams& params)
|
||||||
{
|
{
|
||||||
NazaraError("SubMesh not found");
|
return NzAnimationLoader::LoadFromFile(this, filePath, params);
|
||||||
return;
|
}
|
||||||
}
|
|
||||||
|
bool NzAnimation::LoadFromMemory(const void* data, std::size_t size, const NzAnimationParams& params)
|
||||||
unsigned int index = it->second;
|
{
|
||||||
#else
|
return NzAnimationLoader::LoadFromMemory(this, data, size, params);
|
||||||
unsigned int index = m_impl->sequenceMap[identifier];
|
}
|
||||||
#endif
|
|
||||||
|
bool NzAnimation::LoadFromStream(NzInputStream& stream, const NzAnimationParams& params)
|
||||||
auto it2 = m_impl->sequences.begin();
|
{
|
||||||
std::advance(it2, index);
|
return NzAnimationLoader::LoadFromStream(this, stream, params);
|
||||||
|
}
|
||||||
m_impl->sequences.erase(it2);
|
|
||||||
}
|
void NzAnimation::RemoveSequence(const NzString& identifier)
|
||||||
|
{
|
||||||
void NzAnimation::RemoveSequence(unsigned int index)
|
#if NAZARA_UTILITY_SAFE
|
||||||
{
|
if (!m_impl)
|
||||||
#if NAZARA_UTILITY_SAFE
|
{
|
||||||
if (!m_impl)
|
NazaraError("Animation not created");
|
||||||
{
|
return;
|
||||||
NazaraError("Animation not created");
|
}
|
||||||
return;
|
|
||||||
}
|
auto it = m_impl->sequenceMap.find(identifier);
|
||||||
|
if (it == m_impl->sequenceMap.end())
|
||||||
if (index >= m_impl->sequences.size())
|
{
|
||||||
{
|
NazaraError("Sequence not found");
|
||||||
NazaraError("Sequence index out of range (" + NzString::Number(index) + " >= " + NzString::Number(m_impl->sequences.size()) + ')');
|
return;
|
||||||
return;
|
}
|
||||||
}
|
|
||||||
#endif
|
int index = it->second;
|
||||||
|
#else
|
||||||
auto it = m_impl->sequences.begin();
|
int index = m_impl->sequenceMap[identifier];
|
||||||
std::advance(it, index);
|
#endif
|
||||||
|
|
||||||
m_impl->sequences.erase(it);
|
auto it2 = m_impl->sequences.begin();
|
||||||
}
|
std::advance(it2, index);
|
||||||
|
|
||||||
NzAnimationLoader::LoaderList NzAnimation::s_loaders;
|
m_impl->sequences.erase(it2);
|
||||||
|
}
|
||||||
|
|
||||||
|
void NzAnimation::RemoveSequence(unsigned int index)
|
||||||
|
{
|
||||||
|
#if NAZARA_UTILITY_SAFE
|
||||||
|
if (!m_impl)
|
||||||
|
{
|
||||||
|
NazaraError("Animation not created");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (index >= m_impl->sequences.size())
|
||||||
|
{
|
||||||
|
NazaraError("Sequence index out of range (" + NzString::Number(index) + " >= " + NzString::Number(m_impl->sequences.size()) + ')');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
auto it = m_impl->sequences.begin();
|
||||||
|
std::advance(it, index);
|
||||||
|
|
||||||
|
m_impl->sequences.erase(it);
|
||||||
|
}
|
||||||
|
|
||||||
|
NzAnimationLoader::LoaderList NzAnimation::s_loaders;
|
||||||
|
|
|
||||||
|
|
@ -1,337 +1,339 @@
|
||||||
// Copyright (C) 2012 Jérôme Leclercq
|
// Copyright (C) 2012 Jérôme Leclercq
|
||||||
// This file is part of the "Nazara Engine - Utility module"
|
// This file is part of the "Nazara Engine - Utility module"
|
||||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||||
|
|
||||||
#include <Nazara/Utility/Buffer.hpp>
|
#include <Nazara/Utility/Buffer.hpp>
|
||||||
#include <Nazara/Core/Error.hpp>
|
#include <Nazara/Core/Error.hpp>
|
||||||
#include <Nazara/Utility/BufferImpl.hpp>
|
#include <Nazara/Utility/BufferImpl.hpp>
|
||||||
#include <Nazara/Utility/Config.hpp>
|
#include <Nazara/Utility/Config.hpp>
|
||||||
#include <Nazara/Utility/SoftwareBuffer.hpp>
|
#include <Nazara/Utility/SoftwareBuffer.hpp>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include <Nazara/Utility/Debug.hpp>
|
#include <Nazara/Utility/Debug.hpp>
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
NzBufferImpl* SoftwareBufferFunction(NzBuffer* parent, nzBufferType type)
|
NzBufferImpl* SoftwareBufferFunction(NzBuffer* parent, nzBufferType type)
|
||||||
{
|
{
|
||||||
return new NzSoftwareBuffer(parent, type);
|
return new NzSoftwareBuffer(parent, type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
NzBuffer::NzBuffer(nzBufferType type) :
|
NzBuffer::NzBuffer(nzBufferType type) :
|
||||||
m_type(type),
|
m_type(type),
|
||||||
m_typeSize(0),
|
m_typeSize(0),
|
||||||
m_impl(nullptr),
|
m_impl(nullptr),
|
||||||
m_length(0)
|
m_length(0)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
NzBuffer::NzBuffer(nzBufferType type, unsigned int length, nzUInt8 typeSize, nzBufferStorage storage, nzBufferUsage usage) :
|
NzBuffer::NzBuffer(nzBufferType type, unsigned int length, nzUInt8 typeSize, nzBufferStorage storage, nzBufferUsage usage) :
|
||||||
m_type(type),
|
m_type(type),
|
||||||
m_impl(nullptr)
|
m_impl(nullptr)
|
||||||
{
|
{
|
||||||
Create(length, typeSize, storage, usage);
|
Create(length, typeSize, storage, usage);
|
||||||
|
|
||||||
#ifdef NAZARA_DEBUG
|
#ifdef NAZARA_DEBUG
|
||||||
if (!m_impl)
|
if (!m_impl)
|
||||||
{
|
{
|
||||||
NazaraError("Failed to create buffer");
|
NazaraError("Failed to create buffer");
|
||||||
throw std::runtime_error("Constructor failed");
|
throw std::runtime_error("Constructor failed");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
NzBuffer::~NzBuffer()
|
NzBuffer::~NzBuffer()
|
||||||
{
|
{
|
||||||
Destroy();
|
Destroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NzBuffer::CopyContent(NzBuffer& buffer)
|
bool NzBuffer::CopyContent(NzBuffer& buffer)
|
||||||
{
|
{
|
||||||
#if NAZARA_UTILITY_SAFE
|
#if NAZARA_UTILITY_SAFE
|
||||||
if (!m_impl)
|
if (!m_impl)
|
||||||
{
|
{
|
||||||
NazaraError("Buffer must be valid");
|
NazaraError("Buffer must be valid");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!buffer.IsValid())
|
if (!buffer.IsValid())
|
||||||
{
|
{
|
||||||
NazaraError("Source buffer must be valid");
|
NazaraError("Source buffer must be valid");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!buffer.GetTypeSize() != m_typeSize)
|
if (!buffer.GetTypeSize() != m_typeSize)
|
||||||
{
|
{
|
||||||
NazaraError("Source buffer type size does not match buffer type size");
|
NazaraError("Source buffer type size does not match buffer type size");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void* ptr = buffer.Map(nzBufferAccess_ReadOnly);
|
void* ptr = buffer.Map(nzBufferAccess_ReadOnly);
|
||||||
if (!ptr)
|
if (!ptr)
|
||||||
{
|
{
|
||||||
NazaraError("Failed to map source buffer");
|
NazaraError("Failed to map source buffer");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool r = Fill(ptr, 0, buffer.GetLength());
|
bool r = Fill(ptr, 0, buffer.GetLength());
|
||||||
|
|
||||||
if (!buffer.Unmap())
|
if (!buffer.Unmap())
|
||||||
NazaraWarning("Failed to unmap source buffer");
|
NazaraWarning("Failed to unmap source buffer");
|
||||||
|
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NzBuffer::Create(unsigned int length, nzUInt8 typeSize, nzBufferStorage storage, nzBufferUsage usage)
|
bool NzBuffer::Create(unsigned int length, nzUInt8 typeSize, nzBufferStorage storage, nzBufferUsage usage)
|
||||||
{
|
{
|
||||||
Destroy();
|
Destroy();
|
||||||
|
|
||||||
// On tente d'abord de faire un buffer hardware, si supporté
|
// On tente d'abord de faire un buffer hardware, si supporté
|
||||||
if (s_bufferFunctions[storage])
|
if (s_bufferFunctions[storage])
|
||||||
{
|
{
|
||||||
NzBufferImpl* impl = s_bufferFunctions[storage](this, m_type);
|
NzBufferImpl* impl = s_bufferFunctions[storage](this, m_type);
|
||||||
if (!impl->Create(length*typeSize, usage))
|
if (!impl->Create(length*typeSize, usage))
|
||||||
{
|
{
|
||||||
NazaraError("Failed to create buffer");
|
NazaraError("Failed to create buffer");
|
||||||
delete impl;
|
delete impl;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_impl = impl;
|
m_impl = impl;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
NazaraError("Buffer storage not supported");
|
NazaraError("Buffer storage not supported");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_length = length;
|
m_length = length;
|
||||||
m_typeSize = typeSize;
|
m_typeSize = typeSize;
|
||||||
m_storage = storage;
|
m_storage = storage;
|
||||||
m_usage = usage;
|
m_usage = usage;
|
||||||
|
|
||||||
// Si on arrive ici c'est que tout s'est bien passé.
|
NotifyCreated();
|
||||||
return true;
|
return true; // Si on arrive ici c'est que tout s'est bien passé.
|
||||||
}
|
}
|
||||||
|
|
||||||
void NzBuffer::Destroy()
|
void NzBuffer::Destroy()
|
||||||
{
|
{
|
||||||
if (m_impl)
|
if (m_impl)
|
||||||
{
|
{
|
||||||
m_impl->Destroy();
|
NotifyDestroy();
|
||||||
delete m_impl;
|
|
||||||
m_impl = nullptr;
|
m_impl->Destroy();
|
||||||
}
|
delete m_impl;
|
||||||
}
|
m_impl = nullptr;
|
||||||
|
}
|
||||||
bool NzBuffer::Fill(const void* data, unsigned int offset, unsigned int length)
|
}
|
||||||
{
|
|
||||||
#if NAZARA_UTILITY_SAFE
|
bool NzBuffer::Fill(const void* data, unsigned int offset, unsigned int length)
|
||||||
if (!m_impl)
|
{
|
||||||
{
|
#if NAZARA_UTILITY_SAFE
|
||||||
NazaraError("Buffer not valid");
|
if (!m_impl)
|
||||||
return false;
|
{
|
||||||
}
|
NazaraError("Buffer not valid");
|
||||||
|
return false;
|
||||||
if (offset+length > m_length)
|
}
|
||||||
{
|
|
||||||
NazaraError("Exceeding buffer size");
|
if (offset+length > m_length)
|
||||||
return false;
|
{
|
||||||
}
|
NazaraError("Exceeding buffer size");
|
||||||
#endif
|
return false;
|
||||||
|
}
|
||||||
return m_impl->Fill(data, offset*m_typeSize, ((length == 0) ? m_length-offset : length)*m_typeSize);
|
#endif
|
||||||
}
|
|
||||||
|
return m_impl->Fill(data, offset*m_typeSize, ((length == 0) ? m_length-offset : length)*m_typeSize);
|
||||||
NzBufferImpl* NzBuffer::GetImpl() const
|
}
|
||||||
{
|
|
||||||
return m_impl;
|
NzBufferImpl* NzBuffer::GetImpl() const
|
||||||
}
|
{
|
||||||
|
return m_impl;
|
||||||
unsigned int NzBuffer::GetLength() const
|
}
|
||||||
{
|
|
||||||
return m_length;
|
unsigned int NzBuffer::GetLength() const
|
||||||
}
|
{
|
||||||
|
return m_length;
|
||||||
void* NzBuffer::GetPointer()
|
}
|
||||||
{
|
|
||||||
#if NAZARA_UTILITY_SAFE
|
void* NzBuffer::GetPointer()
|
||||||
if (!m_impl)
|
{
|
||||||
{
|
#if NAZARA_UTILITY_SAFE
|
||||||
NazaraError("Buffer not valid");
|
if (!m_impl)
|
||||||
return nullptr;
|
{
|
||||||
}
|
NazaraError("Buffer not valid");
|
||||||
#endif
|
return nullptr;
|
||||||
|
}
|
||||||
return m_impl->GetPointer();
|
#endif
|
||||||
}
|
|
||||||
|
return m_impl->GetPointer();
|
||||||
const void* NzBuffer::GetPointer() const
|
}
|
||||||
{
|
|
||||||
#if NAZARA_UTILITY_SAFE
|
const void* NzBuffer::GetPointer() const
|
||||||
if (!m_impl)
|
{
|
||||||
{
|
#if NAZARA_UTILITY_SAFE
|
||||||
NazaraError("Buffer not valid");
|
if (!m_impl)
|
||||||
return nullptr;
|
{
|
||||||
}
|
NazaraError("Buffer not valid");
|
||||||
#endif
|
return nullptr;
|
||||||
|
}
|
||||||
return m_impl->GetPointer();
|
#endif
|
||||||
}
|
|
||||||
|
return m_impl->GetPointer();
|
||||||
unsigned int NzBuffer::GetSize() const
|
}
|
||||||
{
|
|
||||||
return m_length*m_typeSize;
|
unsigned int NzBuffer::GetSize() const
|
||||||
}
|
{
|
||||||
|
return m_length*m_typeSize;
|
||||||
nzBufferStorage NzBuffer::GetStorage() const
|
}
|
||||||
{
|
|
||||||
return m_storage;
|
nzBufferStorage NzBuffer::GetStorage() const
|
||||||
}
|
{
|
||||||
|
return m_storage;
|
||||||
nzBufferType NzBuffer::GetType() const
|
}
|
||||||
{
|
|
||||||
return m_type;
|
nzBufferType NzBuffer::GetType() const
|
||||||
}
|
{
|
||||||
|
return m_type;
|
||||||
nzUInt8 NzBuffer::GetTypeSize() const
|
}
|
||||||
{
|
|
||||||
return m_typeSize;
|
nzUInt8 NzBuffer::GetTypeSize() const
|
||||||
}
|
{
|
||||||
|
return m_typeSize;
|
||||||
nzBufferUsage NzBuffer::GetUsage() const
|
}
|
||||||
{
|
|
||||||
return m_usage;
|
nzBufferUsage NzBuffer::GetUsage() const
|
||||||
}
|
{
|
||||||
|
return m_usage;
|
||||||
bool NzBuffer::IsHardware() const
|
}
|
||||||
{
|
|
||||||
return m_storage == nzBufferStorage_Hardware;
|
bool NzBuffer::IsHardware() const
|
||||||
}
|
{
|
||||||
|
return m_storage == nzBufferStorage_Hardware;
|
||||||
bool NzBuffer::IsValid() const
|
}
|
||||||
{
|
|
||||||
return m_impl != nullptr;
|
bool NzBuffer::IsValid() const
|
||||||
}
|
{
|
||||||
|
return m_impl != nullptr;
|
||||||
void* NzBuffer::Map(nzBufferAccess access, unsigned int offset, unsigned int length)
|
}
|
||||||
{
|
|
||||||
#if NAZARA_UTILITY_SAFE
|
void* NzBuffer::Map(nzBufferAccess access, unsigned int offset, unsigned int length)
|
||||||
if (!m_impl)
|
{
|
||||||
{
|
#if NAZARA_UTILITY_SAFE
|
||||||
NazaraError("Buffer not valid");
|
if (!m_impl)
|
||||||
return nullptr;
|
{
|
||||||
}
|
NazaraError("Buffer not valid");
|
||||||
|
return nullptr;
|
||||||
if (offset+length > m_length)
|
}
|
||||||
{
|
|
||||||
NazaraError("Exceeding buffer size");
|
if (offset+length > m_length)
|
||||||
return nullptr;
|
{
|
||||||
}
|
NazaraError("Exceeding buffer size");
|
||||||
#endif
|
return nullptr;
|
||||||
|
}
|
||||||
return m_impl->Map(access, offset*m_typeSize, ((length == 0) ? m_length-offset : length)*m_typeSize);
|
#endif
|
||||||
}
|
|
||||||
|
return m_impl->Map(access, offset*m_typeSize, ((length == 0) ? m_length-offset : length)*m_typeSize);
|
||||||
bool NzBuffer::SetStorage(nzBufferStorage storage)
|
}
|
||||||
{
|
|
||||||
#if NAZARA_UTILITY_SAFE
|
bool NzBuffer::SetStorage(nzBufferStorage storage)
|
||||||
if (!m_impl)
|
{
|
||||||
{
|
#if NAZARA_UTILITY_SAFE
|
||||||
NazaraError("Buffer not valid");
|
if (!m_impl)
|
||||||
return false;
|
{
|
||||||
}
|
NazaraError("Buffer not valid");
|
||||||
#endif
|
return false;
|
||||||
|
}
|
||||||
if (m_storage == storage)
|
#endif
|
||||||
return true;
|
|
||||||
|
if (m_storage == storage)
|
||||||
#if NAZARA_UTILITY_SAFE
|
return true;
|
||||||
if (!IsSupported(storage))
|
|
||||||
{
|
#if NAZARA_UTILITY_SAFE
|
||||||
NazaraError("Storage not supported");
|
if (!IsSupported(storage))
|
||||||
return false;
|
{
|
||||||
}
|
NazaraError("Storage not supported");
|
||||||
#endif
|
return false;
|
||||||
|
}
|
||||||
void* ptr = m_impl->Map(nzBufferAccess_ReadOnly, 0, m_length*m_typeSize);
|
#endif
|
||||||
if (!ptr)
|
|
||||||
{
|
void* ptr = m_impl->Map(nzBufferAccess_ReadOnly, 0, m_length*m_typeSize);
|
||||||
NazaraError("Failed to map buffer");
|
if (!ptr)
|
||||||
return false;
|
{
|
||||||
}
|
NazaraError("Failed to map buffer");
|
||||||
|
return false;
|
||||||
NzBufferImpl* impl = s_bufferFunctions[storage](this, m_type);
|
}
|
||||||
if (!impl->Create(m_length*m_typeSize, m_usage))
|
|
||||||
{
|
NzBufferImpl* impl = s_bufferFunctions[storage](this, m_type);
|
||||||
NazaraError("Failed to create buffer");
|
if (!impl->Create(m_length*m_typeSize, m_usage))
|
||||||
delete impl;
|
{
|
||||||
|
NazaraError("Failed to create buffer");
|
||||||
if (!m_impl->Unmap())
|
delete impl;
|
||||||
NazaraWarning("Failed to unmap buffer");
|
|
||||||
|
if (!m_impl->Unmap())
|
||||||
return false;
|
NazaraWarning("Failed to unmap buffer");
|
||||||
}
|
|
||||||
|
return false;
|
||||||
if (!impl->Fill(ptr, 0, m_length*m_typeSize))
|
}
|
||||||
{
|
|
||||||
NazaraError("Failed to fill buffer");
|
if (!impl->Fill(ptr, 0, m_length*m_typeSize))
|
||||||
impl->Destroy();
|
{
|
||||||
delete impl;
|
NazaraError("Failed to fill buffer");
|
||||||
|
impl->Destroy();
|
||||||
if (!m_impl->Unmap())
|
delete impl;
|
||||||
NazaraWarning("Failed to unmap buffer");
|
|
||||||
|
if (!m_impl->Unmap())
|
||||||
return false;
|
NazaraWarning("Failed to unmap buffer");
|
||||||
}
|
|
||||||
|
return false;
|
||||||
m_impl->Unmap();
|
}
|
||||||
m_impl->Destroy();
|
|
||||||
|
m_impl->Unmap();
|
||||||
delete m_impl;
|
m_impl->Destroy();
|
||||||
m_impl = impl;
|
|
||||||
|
delete m_impl;
|
||||||
m_storage = storage;
|
m_impl = impl;
|
||||||
|
|
||||||
return true;
|
m_storage = storage;
|
||||||
}
|
|
||||||
|
return true;
|
||||||
bool NzBuffer::Unmap()
|
}
|
||||||
{
|
|
||||||
#if NAZARA_UTILITY_SAFE
|
bool NzBuffer::Unmap()
|
||||||
if (!m_impl)
|
{
|
||||||
{
|
#if NAZARA_UTILITY_SAFE
|
||||||
NazaraError("Buffer not valid");
|
if (!m_impl)
|
||||||
return false;
|
{
|
||||||
}
|
NazaraError("Buffer not valid");
|
||||||
#endif
|
return false;
|
||||||
|
}
|
||||||
return m_impl->Unmap();
|
#endif
|
||||||
}
|
|
||||||
|
return m_impl->Unmap();
|
||||||
bool NzBuffer::IsSupported(nzBufferStorage storage)
|
}
|
||||||
{
|
|
||||||
return s_bufferFunctions[storage] != nullptr;
|
bool NzBuffer::IsSupported(nzBufferStorage storage)
|
||||||
}
|
{
|
||||||
|
return s_bufferFunctions[storage] != nullptr;
|
||||||
void NzBuffer::SetBufferFunction(nzBufferStorage storage, BufferFunction func)
|
}
|
||||||
{
|
|
||||||
s_bufferFunctions[storage] = func;
|
void NzBuffer::SetBufferFunction(nzBufferStorage storage, BufferFunction func)
|
||||||
}
|
{
|
||||||
|
s_bufferFunctions[storage] = func;
|
||||||
bool NzBuffer::Initialize()
|
}
|
||||||
{
|
|
||||||
s_bufferFunctions[nzBufferStorage_Software] = SoftwareBufferFunction;
|
bool NzBuffer::Initialize()
|
||||||
|
{
|
||||||
return true;
|
s_bufferFunctions[nzBufferStorage_Software] = SoftwareBufferFunction;
|
||||||
}
|
|
||||||
|
return true;
|
||||||
void NzBuffer::Uninitialize()
|
}
|
||||||
{
|
|
||||||
std::memset(s_bufferFunctions, 0, (nzBufferStorage_Max+1)*sizeof(NzBuffer::BufferFunction));
|
void NzBuffer::Uninitialize()
|
||||||
}
|
{
|
||||||
|
std::memset(s_bufferFunctions, 0, (nzBufferStorage_Max+1)*sizeof(NzBuffer::BufferFunction));
|
||||||
NzBuffer::BufferFunction NzBuffer::s_bufferFunctions[nzBufferStorage_Max+1] = {0};
|
}
|
||||||
|
|
||||||
|
NzBuffer::BufferFunction NzBuffer::s_bufferFunctions[nzBufferStorage_Max+1] = {0};
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -1,221 +1,200 @@
|
||||||
// Copyright (C) 2012 Jérôme Leclercq
|
// Copyright (C) 2012 Jérôme Leclercq
|
||||||
// This file is part of the "Nazara Engine - Utility module"
|
// This file is part of the "Nazara Engine - Utility module"
|
||||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||||
|
|
||||||
#include <Nazara/Utility/Loaders/MD2.hpp>
|
#include <Nazara/Utility/Loaders/MD2.hpp>
|
||||||
#include <Nazara/Core/Endianness.hpp>
|
#include <Nazara/Core/Endianness.hpp>
|
||||||
#include <Nazara/Core/Error.hpp>
|
#include <Nazara/Core/Error.hpp>
|
||||||
#include <Nazara/Core/File.hpp>
|
#include <Nazara/Core/File.hpp>
|
||||||
#include <Nazara/Core/InputStream.hpp>
|
#include <Nazara/Core/InputStream.hpp>
|
||||||
#include <Nazara/Core/MemoryStream.hpp>
|
#include <Nazara/Core/MemoryStream.hpp>
|
||||||
#include <Nazara/Math/Basic.hpp>
|
#include <Nazara/Math/Basic.hpp>
|
||||||
#include <Nazara/Utility/Mesh.hpp>
|
#include <Nazara/Utility/Mesh.hpp>
|
||||||
#include <Nazara/Utility/Loaders/MD2/Constants.hpp>
|
#include <Nazara/Utility/Loaders/MD2/Constants.hpp>
|
||||||
#include <Nazara/Utility/Loaders/MD2/Mesh.hpp>
|
#include <Nazara/Utility/Loaders/MD2/Mesh.hpp>
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <Nazara/Utility/Debug.hpp>
|
#include <Nazara/Utility/Debug.hpp>
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
bool NzLoader_MD2_Check(NzInputStream& stream, const NzMeshParams& parameters)
|
bool NzLoader_MD2_Check(NzInputStream& stream, const NzMeshParams& parameters)
|
||||||
{
|
{
|
||||||
NazaraUnused(parameters);
|
NazaraUnused(parameters);
|
||||||
|
|
||||||
nzUInt32 magic[2];
|
nzUInt32 magic[2];
|
||||||
if (stream.Read(&magic[0], 2*sizeof(nzUInt32)) != 2*sizeof(nzUInt32))
|
if (stream.Read(&magic[0], 2*sizeof(nzUInt32)) != 2*sizeof(nzUInt32))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
#if defined(NAZARA_BIG_ENDIAN)
|
#if defined(NAZARA_BIG_ENDIAN)
|
||||||
NzByteSwap(&magic[0], sizeof(nzUInt32));
|
NzByteSwap(&magic[0], sizeof(nzUInt32));
|
||||||
NzByteSwap(&magic[1], sizeof(nzUInt32));
|
NzByteSwap(&magic[1], sizeof(nzUInt32));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return magic[0] == md2Ident && magic[1] == 8;
|
return magic[0] == md2Ident && magic[1] == 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NzLoader_MD2_Load(NzMesh* mesh, NzInputStream& stream, const NzMeshParams& parameters)
|
bool NzLoader_MD2_Load(NzMesh* mesh, NzInputStream& stream, const NzMeshParams& parameters)
|
||||||
{
|
{
|
||||||
md2_header header;
|
md2_header header;
|
||||||
if (stream.Read(&header, sizeof(md2_header)) != sizeof(md2_header))
|
if (stream.Read(&header, sizeof(md2_header)) != sizeof(md2_header))
|
||||||
{
|
{
|
||||||
NazaraError("Failed to read header");
|
NazaraError("Failed to read header");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Les fichiers MD2 sont en little endian
|
#if defined(NAZARA_BIG_ENDIAN)
|
||||||
#if defined(NAZARA_BIG_ENDIAN)
|
NzByteSwap(&header.skinwidth, sizeof(nzUInt32));
|
||||||
NzByteSwap(&header.ident, sizeof(nzUInt32));
|
NzByteSwap(&header.skinheight, sizeof(nzUInt32));
|
||||||
#endif
|
NzByteSwap(&header.framesize, sizeof(nzUInt32));
|
||||||
|
NzByteSwap(&header.num_skins, sizeof(nzUInt32));
|
||||||
if (header.ident != md2Ident)
|
NzByteSwap(&header.num_vertices, sizeof(nzUInt32));
|
||||||
{
|
NzByteSwap(&header.num_st, sizeof(nzUInt32));
|
||||||
NazaraError("Invalid MD2 file");
|
NzByteSwap(&header.num_tris, sizeof(nzUInt32));
|
||||||
return false;
|
NzByteSwap(&header.num_glcmds, sizeof(nzUInt32));
|
||||||
}
|
NzByteSwap(&header.num_frames, sizeof(nzUInt32));
|
||||||
|
NzByteSwap(&header.offset_skins, sizeof(nzUInt32));
|
||||||
#if defined(NAZARA_BIG_ENDIAN)
|
NzByteSwap(&header.offset_st, sizeof(nzUInt32));
|
||||||
NzByteSwap(&header.version, sizeof(nzUInt32));
|
NzByteSwap(&header.offset_tris, sizeof(nzUInt32));
|
||||||
#endif
|
NzByteSwap(&header.offset_frames, sizeof(nzUInt32));
|
||||||
|
NzByteSwap(&header.offset_glcmds, sizeof(nzUInt32));
|
||||||
if (header.version != 8)
|
NzByteSwap(&header.offset_end, sizeof(nzUInt32));
|
||||||
{
|
#endif
|
||||||
NazaraError("Bad version number (" + NzString::Number(header.version) + ')');
|
|
||||||
return false;
|
if (stream.GetSize() < header.offset_end)
|
||||||
}
|
{
|
||||||
|
NazaraError("Incomplete MD2 file");
|
||||||
#if defined(NAZARA_BIG_ENDIAN)
|
return false;
|
||||||
NzByteSwap(&header.skinwidth, sizeof(nzUInt32));
|
}
|
||||||
NzByteSwap(&header.skinheight, sizeof(nzUInt32));
|
|
||||||
NzByteSwap(&header.framesize, sizeof(nzUInt32));
|
/// Création du mesh
|
||||||
NzByteSwap(&header.num_skins, sizeof(nzUInt32));
|
// Animé ou statique, c'est la question
|
||||||
NzByteSwap(&header.num_vertices, sizeof(nzUInt32));
|
bool animated;
|
||||||
NzByteSwap(&header.num_st, sizeof(nzUInt32));
|
unsigned int startFrame = NzClamp(parameters.animation.startFrame, 0U, static_cast<unsigned int>(header.num_frames-1));
|
||||||
NzByteSwap(&header.num_tris, sizeof(nzUInt32));
|
unsigned int endFrame = NzClamp(parameters.animation.endFrame, 0U, static_cast<unsigned int>(header.num_frames-1));
|
||||||
NzByteSwap(&header.num_glcmds, sizeof(nzUInt32));
|
|
||||||
NzByteSwap(&header.num_frames, sizeof(nzUInt32));
|
if (parameters.loadAnimations && startFrame != endFrame)
|
||||||
NzByteSwap(&header.offset_skins, sizeof(nzUInt32));
|
animated = true;
|
||||||
NzByteSwap(&header.offset_st, sizeof(nzUInt32));
|
else
|
||||||
NzByteSwap(&header.offset_tris, sizeof(nzUInt32));
|
animated = false;
|
||||||
NzByteSwap(&header.offset_frames, sizeof(nzUInt32));
|
|
||||||
NzByteSwap(&header.offset_glcmds, sizeof(nzUInt32));
|
if (!mesh->Create((animated) ? nzAnimationType_Keyframe : nzAnimationType_Static)) // Ne devrait jamais échouer
|
||||||
NzByteSwap(&header.offset_end, sizeof(nzUInt32));
|
{
|
||||||
#endif
|
NazaraInternalError("Failed to create mesh");
|
||||||
|
return false;
|
||||||
if (stream.GetSize() < header.offset_end)
|
}
|
||||||
{
|
|
||||||
NazaraError("Incomplete MD2 file");
|
/// Chargement des skins
|
||||||
return false;
|
if (header.num_skins > 0)
|
||||||
}
|
{
|
||||||
|
stream.SetCursorPos(header.offset_skins);
|
||||||
/// Création du mesh
|
{
|
||||||
// Animé ou statique, c'est la question
|
char skin[68];
|
||||||
bool animated;
|
for (unsigned int i = 0; i < header.num_skins; ++i)
|
||||||
unsigned int startFrame = NzClamp(parameters.animation.startFrame, 0U, static_cast<unsigned int>(header.num_frames-1));
|
{
|
||||||
unsigned int endFrame = NzClamp(parameters.animation.endFrame, 0U, static_cast<unsigned int>(header.num_frames-1));
|
stream.Read(skin, 68*sizeof(char));
|
||||||
|
mesh->AddSkin(skin);
|
||||||
if (parameters.loadAnimations && startFrame != endFrame)
|
}
|
||||||
animated = true;
|
}
|
||||||
else
|
}
|
||||||
animated = false;
|
|
||||||
|
/// Chargement des animmations
|
||||||
if (!mesh->Create((animated) ? nzAnimationType_Keyframe : nzAnimationType_Static)) // Ne devrait pas échouer
|
if (animated)
|
||||||
{
|
{
|
||||||
NazaraInternalError("Failed to create mesh");
|
NzAnimation* animation = new NzAnimation;
|
||||||
return false;
|
if (animation->Create(nzAnimationType_Keyframe, endFrame-startFrame+1))
|
||||||
}
|
{
|
||||||
|
// Décodage des séquences
|
||||||
/// Chargement des skins
|
NzString frameName;
|
||||||
if (header.num_skins > 0)
|
|
||||||
{
|
NzSequence sequence;
|
||||||
stream.SetCursorPos(header.offset_skins);
|
sequence.framePerSecond = 10; // Par défaut pour les animations MD2
|
||||||
{
|
|
||||||
char skin[68];
|
char name[16], last[16];
|
||||||
for (unsigned int i = 0; i < header.num_skins; ++i)
|
stream.SetCursorPos(header.offset_frames + startFrame*header.framesize + offsetof(md2_frame, name));
|
||||||
{
|
stream.Read(last, 16*sizeof(char));
|
||||||
stream.Read(skin, 68*sizeof(char));
|
|
||||||
mesh->AddSkin(skin);
|
int pos = std::strlen(last)-1;
|
||||||
}
|
for (unsigned int j = 0; j < 2; ++j)
|
||||||
}
|
{
|
||||||
}
|
if (!std::isdigit(last[pos]))
|
||||||
|
break;
|
||||||
/// Chargement des animmations
|
|
||||||
if (animated)
|
pos--;
|
||||||
{
|
}
|
||||||
NzAnimation* animation = new NzAnimation;
|
last[pos+1] = '\0';
|
||||||
if (animation->Create(nzAnimationType_Keyframe, endFrame-startFrame+1))
|
|
||||||
{
|
unsigned int numFrames = 0;
|
||||||
// Décodage des séquences
|
for (unsigned int i = startFrame; i <= endFrame; ++i)
|
||||||
NzString frameName;
|
{
|
||||||
|
stream.SetCursorPos(header.offset_frames + i*header.framesize + offsetof(md2_frame, name));
|
||||||
NzSequence sequence;
|
stream.Read(name, 16*sizeof(char));
|
||||||
sequence.framePerSecond = 10; // Par défaut pour les animations MD2
|
|
||||||
|
pos = std::strlen(name)-1;
|
||||||
char name[16], last[16];
|
for (unsigned int j = 0; j < 2; ++j)
|
||||||
stream.SetCursorPos(header.offset_frames + startFrame*header.framesize + offsetof(md2_frame, name));
|
{
|
||||||
stream.Read(last, 16*sizeof(char));
|
if (!std::isdigit(name[pos]))
|
||||||
|
break;
|
||||||
int pos = std::strlen(last)-1;
|
|
||||||
for (unsigned int j = 0; j < 2; ++j)
|
pos--;
|
||||||
{
|
}
|
||||||
if (!std::isdigit(last[pos]))
|
name[pos+1] = '\0';
|
||||||
break;
|
|
||||||
|
if (std::strcmp(name, last) != 0) // Si les deux frames n'ont pas le même nom
|
||||||
pos--;
|
{
|
||||||
}
|
// Alors on enregistre la séquence
|
||||||
last[pos+1] = '\0';
|
sequence.firstFrame = i-numFrames;
|
||||||
|
sequence.lastFrame = i-1;
|
||||||
unsigned int numFrames = 0;
|
sequence.name = last;
|
||||||
for (unsigned int i = startFrame; i <= endFrame; ++i)
|
animation->AddSequence(sequence);
|
||||||
{
|
|
||||||
stream.SetCursorPos(header.offset_frames + i*header.framesize + offsetof(md2_frame, name));
|
std::strcpy(last, name);
|
||||||
stream.Read(name, 16*sizeof(char));
|
|
||||||
|
numFrames = 0;
|
||||||
pos = std::strlen(name)-1;
|
}
|
||||||
for (unsigned int j = 0; j < 2; ++j)
|
|
||||||
{
|
numFrames++;
|
||||||
if (!std::isdigit(name[pos]))
|
}
|
||||||
break;
|
|
||||||
|
// On ajoute la dernière frame (Qui n'a pas été traitée par la boucle)
|
||||||
pos--;
|
sequence.firstFrame = endFrame-numFrames;
|
||||||
}
|
sequence.lastFrame = endFrame;
|
||||||
name[pos+1] = '\0';
|
sequence.name = last;
|
||||||
|
animation->AddSequence(sequence);
|
||||||
if (std::strcmp(name, last) != 0) // Si les deux frames n'ont pas le même nom
|
|
||||||
{
|
mesh->SetAnimation(animation);
|
||||||
// Alors on enregistre la séquence
|
animation->SetPersistent(false);
|
||||||
sequence.firstFrame = i-numFrames;
|
}
|
||||||
sequence.lastFrame = i-1;
|
else
|
||||||
sequence.name = last;
|
NazaraInternalError("Failed to create animaton");
|
||||||
animation->AddSequence(sequence);
|
}
|
||||||
|
|
||||||
std::strcpy(last, name);
|
/// Chargement des submesh
|
||||||
|
// Actuellement le loader ne charge qu'un submesh
|
||||||
numFrames = 0;
|
// TODO: Utiliser les commandes OpenGL pour accélérer le rendu
|
||||||
}
|
NzMD2Mesh* subMesh = new NzMD2Mesh(mesh);
|
||||||
|
if (!subMesh->Create(header, stream, parameters))
|
||||||
numFrames++;
|
{
|
||||||
}
|
NazaraError("Failed to create MD2 mesh");
|
||||||
|
return false;
|
||||||
// On ajoute la dernière frame (Qui n'a pas été traitée par la boucle)
|
}
|
||||||
sequence.firstFrame = endFrame-numFrames;
|
|
||||||
sequence.lastFrame = endFrame;
|
mesh->AddSubMesh(subMesh);
|
||||||
sequence.name = last;
|
|
||||||
animation->AddSequence(sequence);
|
return true;
|
||||||
|
}
|
||||||
mesh->SetAnimation(animation);
|
}
|
||||||
animation->SetPersistent(false);
|
|
||||||
}
|
void NzLoaders_MD2_Register()
|
||||||
else
|
{
|
||||||
NazaraInternalError("Failed to create animaton");
|
NzMD2Mesh::Initialize();
|
||||||
}
|
|
||||||
|
NzMeshLoader::RegisterLoader("md2", NzLoader_MD2_Check, NzLoader_MD2_Load);
|
||||||
/// Chargement des submesh
|
}
|
||||||
// Actuellement le loader ne charge qu'un submesh
|
|
||||||
// TODO: Utiliser les commandes OpenGL pour accélérer le rendu
|
void NzLoaders_MD2_Unregister()
|
||||||
NzMD2Mesh* subMesh = new NzMD2Mesh(mesh);
|
{
|
||||||
if (!subMesh->Create(header, stream, parameters))
|
NzMeshLoader::UnregisterLoader("md2", NzLoader_MD2_Check, NzLoader_MD2_Load);
|
||||||
{
|
|
||||||
NazaraError("Failed to create MD2 mesh");
|
NzMD2Mesh::Uninitialize();
|
||||||
return false;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
mesh->AddSubMesh(subMesh);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void NzLoaders_MD2_Register()
|
|
||||||
{
|
|
||||||
NzMD2Mesh::Initialize();
|
|
||||||
|
|
||||||
NzMeshLoader::RegisterLoader("md2", NzLoader_MD2_Check, NzLoader_MD2_Load);
|
|
||||||
}
|
|
||||||
|
|
||||||
void NzLoaders_MD2_Unregister()
|
|
||||||
{
|
|
||||||
NzMeshLoader::UnregisterLoader("md2", NzLoader_MD2_Check, NzLoader_MD2_Load);
|
|
||||||
|
|
||||||
NzMD2Mesh::Uninitialize();
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -1,287 +1,292 @@
|
||||||
// Copyright (C) 2012 Jérôme Leclercq
|
// Copyright (C) 2012 Jérôme Leclercq
|
||||||
// This file is part of the "Nazara Engine - Utility module"
|
// This file is part of the "Nazara Engine - Utility module"
|
||||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||||
|
|
||||||
#include <Nazara/Utility/Loaders/MD2/Mesh.hpp>
|
#include <Nazara/Utility/Loaders/MD2/Mesh.hpp>
|
||||||
#include <Nazara/Core/InputStream.hpp>
|
#include <Nazara/Core/InputStream.hpp>
|
||||||
#include <Nazara/Math/Matrix4.hpp>
|
#include <Nazara/Math/Matrix4.hpp>
|
||||||
#include <Nazara/Utility/IndexBuffer.hpp>
|
#include <Nazara/Utility/IndexBuffer.hpp>
|
||||||
#include <Nazara/Utility/Mesh.hpp>
|
#include <Nazara/Utility/Mesh.hpp>
|
||||||
#include <Nazara/Utility/VertexBuffer.hpp>
|
#include <Nazara/Utility/VertexBuffer.hpp>
|
||||||
#include <Nazara/Utility/Debug.hpp>
|
#include <Nazara/Utility/Debug.hpp>
|
||||||
|
|
||||||
NzMD2Mesh::NzMD2Mesh(const NzMesh* parent) :
|
NzMD2Mesh::NzMD2Mesh(const NzMesh* parent) :
|
||||||
NzKeyframeMesh(parent),
|
NzKeyframeMesh(parent),
|
||||||
m_frames(nullptr),
|
m_frames(nullptr),
|
||||||
m_indexBuffer(nullptr),
|
m_indexBuffer(nullptr),
|
||||||
m_vertexBuffer(nullptr)
|
m_vertexBuffer(nullptr)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
NzMD2Mesh::~NzMD2Mesh()
|
NzMD2Mesh::~NzMD2Mesh()
|
||||||
{
|
{
|
||||||
Destroy();
|
Destroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NzMD2Mesh::Create(const md2_header& header, NzInputStream& stream, const NzMeshParams& parameters)
|
bool NzMD2Mesh::Create(const md2_header& header, NzInputStream& stream, const NzMeshParams& parameters)
|
||||||
{
|
{
|
||||||
Destroy();
|
Destroy();
|
||||||
|
|
||||||
unsigned int startFrame = NzClamp(parameters.animation.startFrame, 0U, static_cast<unsigned int>(header.num_frames-1));
|
unsigned int startFrame = NzClamp(parameters.animation.startFrame, 0U, static_cast<unsigned int>(header.num_frames-1));
|
||||||
unsigned int endFrame = NzClamp(parameters.animation.endFrame, 0U, static_cast<unsigned int>(header.num_frames-1));
|
unsigned int endFrame = NzClamp(parameters.animation.endFrame, 0U, static_cast<unsigned int>(header.num_frames-1));
|
||||||
|
|
||||||
m_frameCount = endFrame - startFrame + 1;
|
m_frameCount = endFrame - startFrame + 1;
|
||||||
m_vertexCount = header.num_tris*3;
|
m_vertexCount = header.num_tris * 3;
|
||||||
|
|
||||||
/// Chargement des vertices
|
/// Chargement des vertices
|
||||||
std::vector<md2_texCoord> texCoords(header.num_st);
|
std::vector<md2_texCoord> texCoords(header.num_st);
|
||||||
std::vector<md2_triangle> triangles(header.num_tris);
|
std::vector<md2_triangle> triangles(header.num_tris);
|
||||||
|
|
||||||
// Lecture des coordonnées de texture
|
// Lecture des coordonnées de texture
|
||||||
stream.SetCursorPos(header.offset_st);
|
stream.SetCursorPos(header.offset_st);
|
||||||
stream.Read(&texCoords[0], header.num_st*sizeof(md2_texCoord));
|
stream.Read(&texCoords[0], header.num_st*sizeof(md2_texCoord));
|
||||||
|
|
||||||
#if defined(NAZARA_BIG_ENDIAN)
|
#if defined(NAZARA_BIG_ENDIAN)
|
||||||
for (unsigned int i = 0; i < header.num_st; ++i)
|
for (unsigned int i = 0; i < header.num_st; ++i)
|
||||||
{
|
{
|
||||||
NzByteSwap(&texCoords[i].u, sizeof(nzInt16));
|
NzByteSwap(&texCoords[i].u, sizeof(nzInt16));
|
||||||
NzByteSwap(&texCoords[i].v, sizeof(nzInt16));
|
NzByteSwap(&texCoords[i].v, sizeof(nzInt16));
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
stream.SetCursorPos(header.offset_tris);
|
stream.SetCursorPos(header.offset_tris);
|
||||||
stream.Read(&triangles[0], header.num_tris*sizeof(md2_triangle));
|
stream.Read(&triangles[0], header.num_tris*sizeof(md2_triangle));
|
||||||
|
|
||||||
#if defined(NAZARA_BIG_ENDIAN)
|
#if defined(NAZARA_BIG_ENDIAN)
|
||||||
for (unsigned int i = 0; i < header.num_tris; ++i)
|
for (unsigned int i = 0; i < header.num_tris; ++i)
|
||||||
{
|
{
|
||||||
NzByteSwap(&triangles[i].vertices[0], sizeof(nzUInt16));
|
NzByteSwap(&triangles[i].vertices[0], sizeof(nzUInt16));
|
||||||
NzByteSwap(&texCoords[i].texCoords[0], sizeof(nzUInt16));
|
NzByteSwap(&texCoords[i].texCoords[0], sizeof(nzUInt16));
|
||||||
|
|
||||||
NzByteSwap(&triangles[i].vertices[1], sizeof(nzUInt16));
|
NzByteSwap(&triangles[i].vertices[1], sizeof(nzUInt16));
|
||||||
NzByteSwap(&texCoords[i].texCoords[1], sizeof(nzUInt16));
|
NzByteSwap(&texCoords[i].texCoords[1], sizeof(nzUInt16));
|
||||||
|
|
||||||
NzByteSwap(&triangles[i].vertices[2], sizeof(nzUInt16));
|
NzByteSwap(&triangles[i].vertices[2], sizeof(nzUInt16));
|
||||||
NzByteSwap(&texCoords[i].texCoords[2], sizeof(nzUInt16));
|
NzByteSwap(&texCoords[i].texCoords[2], sizeof(nzUInt16));
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
stream.SetCursorPos(header.offset_frames + header.framesize*startFrame);
|
stream.SetCursorPos(header.offset_frames + header.framesize*startFrame);
|
||||||
|
|
||||||
md2_frame frame;
|
md2_frame frame;
|
||||||
frame.vertices.resize(header.num_vertices);
|
frame.vertices.resize(header.num_vertices);
|
||||||
|
|
||||||
// Pour que le modèle soit correctement aligné, on génère une matrice de rotation que nous appliquerons à chacune des vertices
|
// Pour que le modèle soit correctement aligné, on génère un quaternion que nous appliquerons à chacune des vertices
|
||||||
NzMatrix4f rotationMatrix = NzMatrix4f::Rotate(NzEulerAnglesf(90.f, -90.f, 0.f));
|
NzQuaternionf rotationQuat = NzEulerAnglesf(-90.f, 90.f, 0.f);
|
||||||
|
//NzMatrix4f rotationMatrix = NzMatrix4f::Rotate(NzEulerAnglesf(-90.f, -90.f, 0.f));
|
||||||
unsigned int stride = s_declaration.GetStride(nzElementStream_VertexData);
|
|
||||||
|
unsigned int stride = s_declaration.GetStride(nzElementStream_VertexData);
|
||||||
m_frames = new Frame[m_frameCount];
|
|
||||||
for (unsigned int i = 0; i < m_frameCount; ++i)
|
m_frames = new Frame[m_frameCount];
|
||||||
{
|
for (unsigned int i = 0; i < m_frameCount; ++i)
|
||||||
stream.Read(&frame.scale, sizeof(NzVector3f));
|
{
|
||||||
stream.Read(&frame.translate, sizeof(NzVector3f));
|
stream.Read(&frame.scale, sizeof(NzVector3f));
|
||||||
stream.Read(&frame.name, 16*sizeof(char));
|
stream.Read(&frame.translate, sizeof(NzVector3f));
|
||||||
stream.Read(&frame.vertices[0], header.num_vertices*sizeof(md2_vertex));
|
stream.Read(&frame.name, 16*sizeof(char));
|
||||||
|
stream.Read(&frame.vertices[0], header.num_vertices*sizeof(md2_vertex));
|
||||||
#if defined(NAZARA_BIG_ENDIAN)
|
|
||||||
NzByteSwap(&frame.scale.x, sizeof(float));
|
#if defined(NAZARA_BIG_ENDIAN)
|
||||||
NzByteSwap(&frame.scale.y, sizeof(float));
|
NzByteSwap(&frame.scale.x, sizeof(float));
|
||||||
NzByteSwap(&frame.scale.z, sizeof(float));
|
NzByteSwap(&frame.scale.y, sizeof(float));
|
||||||
|
NzByteSwap(&frame.scale.z, sizeof(float));
|
||||||
NzByteSwap(&frame.translate.x, sizeof(float));
|
|
||||||
NzByteSwap(&frame.translate.y, sizeof(float));
|
NzByteSwap(&frame.translate.x, sizeof(float));
|
||||||
NzByteSwap(&frame.translate.z, sizeof(float));
|
NzByteSwap(&frame.translate.y, sizeof(float));
|
||||||
#endif
|
NzByteSwap(&frame.translate.z, sizeof(float));
|
||||||
|
#endif
|
||||||
m_frames[i].normal = new nzUInt8[m_vertexCount]; // Nous stockons l'indice de la normale plutôt que la normale (gain d'espace)
|
|
||||||
m_frames[i].vertices = new NzVector3f[m_vertexCount];
|
m_frames[i].normal = new nzUInt8[m_vertexCount]; // Nous stockons l'indice MD2 de la normale plutôt que la normale (gain d'espace)
|
||||||
|
m_frames[i].vertices = new NzVector3f[m_vertexCount];
|
||||||
NzVector3f max, min;
|
|
||||||
for (unsigned int t = 0; t < header.num_tris; ++t)
|
NzVector3f max, min;
|
||||||
{
|
for (unsigned int t = 0; t < header.num_tris; ++t)
|
||||||
for (unsigned int v = 0; v < 3; ++v)
|
{
|
||||||
{
|
for (unsigned int v = 0; v < 3; ++v)
|
||||||
const md2_vertex& vert = frame.vertices[triangles[t].vertices[v]];
|
{
|
||||||
|
const md2_vertex& vert = frame.vertices[triangles[t].vertices[v]];
|
||||||
NzVector3f vertex = rotationMatrix * NzVector3f(vert.x * frame.scale.x + frame.translate.x, vert.y * frame.scale.y + frame.translate.y, vert.z * frame.scale.z + frame.translate.z);
|
|
||||||
max.MakeCeil(vertex);
|
NzVector3f vertex = rotationQuat * NzVector3f(vert.x * frame.scale.x + frame.translate.x, vert.y * frame.scale.y + frame.translate.y, vert.z * frame.scale.z + frame.translate.z);
|
||||||
min.MakeFloor(vertex);
|
|
||||||
|
// On fait en sorte d'avoir deux vertices de délimitation, définissant un rectangle dans l'espace
|
||||||
m_frames[i].normal[t*3+v] = vert.n;
|
max.Maximize(vertex);
|
||||||
m_frames[i].vertices[t*3+v] = vertex;
|
min.Minimize(vertex);
|
||||||
}
|
|
||||||
}
|
// Le MD2 ne définit pas ses vertices dans le bon ordre, il nous faut donc les ajouter dans l'ordre inverse
|
||||||
|
unsigned int index = m_vertexCount - (t*3 + v) - 1;
|
||||||
m_frames[i].aabb.SetExtends(min, max);
|
m_frames[i].normal[index] = vert.n;
|
||||||
}
|
m_frames[i].vertices[index] = vertex;
|
||||||
|
}
|
||||||
m_indexBuffer = nullptr; // Pas d'indexbuffer pour l'instant
|
}
|
||||||
m_vertexBuffer = new NzVertexBuffer(m_vertexCount, (3+3+2)*sizeof(float), parameters.storage, nzBufferUsage_Dynamic);
|
|
||||||
|
m_frames[i].aabb.SetExtends(min, max);
|
||||||
nzUInt8* ptr = reinterpret_cast<nzUInt8*>(m_vertexBuffer->Map(nzBufferAccess_WriteOnly));
|
}
|
||||||
if (!ptr)
|
|
||||||
{
|
m_indexBuffer = nullptr; // Pas d'indexbuffer pour l'instant
|
||||||
NazaraError("Failed to map vertex buffer");
|
m_vertexBuffer = new NzVertexBuffer(m_vertexCount, (3+3+2)*sizeof(float), parameters.storage, nzBufferUsage_Dynamic);
|
||||||
Destroy();
|
|
||||||
|
nzUInt8* ptr = reinterpret_cast<nzUInt8*>(m_vertexBuffer->Map(nzBufferAccess_WriteOnly));
|
||||||
return false;
|
if (!ptr)
|
||||||
}
|
{
|
||||||
|
NazaraError("Failed to map vertex buffer");
|
||||||
// On avance jusqu'aux premières coordonnées de texture
|
Destroy();
|
||||||
ptr += s_declaration.GetElement(nzElementStream_VertexData, nzElementUsage_TexCoord)->offset;
|
|
||||||
for (unsigned int t = 0; t < header.num_tris; ++t)
|
return false;
|
||||||
{
|
}
|
||||||
for (unsigned int v = 0; v < 3; ++v)
|
|
||||||
{
|
// On avance jusqu'aux dernières coordonnées de texture et on les définit dans l'ordre inverse
|
||||||
const md2_texCoord& texC = texCoords[triangles[t].texCoords[v]];
|
ptr += s_declaration.GetElement(nzElementStream_VertexData, nzElementUsage_TexCoord)->offset + stride * (m_vertexCount-1);
|
||||||
|
for (unsigned int t = 0; t < header.num_tris; ++t)
|
||||||
NzVector2f* coords = reinterpret_cast<NzVector2f*>(ptr);
|
{
|
||||||
coords->x = texC.u / static_cast<float>(header.skinwidth);
|
for (unsigned int v = 0; v < 3; ++v)
|
||||||
coords->y = 1.f - texC.v / static_cast<float>(header.skinheight);
|
{
|
||||||
|
const md2_texCoord& texC = texCoords[triangles[t].texCoords[v]];
|
||||||
ptr += stride;
|
|
||||||
}
|
NzVector2f* coords = reinterpret_cast<NzVector2f*>(ptr);
|
||||||
}
|
coords->x = texC.u / static_cast<float>(header.skinwidth);
|
||||||
|
coords->y = 1.f - texC.v / static_cast<float>(header.skinheight);
|
||||||
if (!m_vertexBuffer->Unmap())
|
|
||||||
{
|
ptr -= stride;
|
||||||
NazaraError("Failed to unmap buffer");
|
}
|
||||||
Destroy();
|
}
|
||||||
|
|
||||||
return false;
|
if (!m_vertexBuffer->Unmap())
|
||||||
}
|
{
|
||||||
|
NazaraError("Failed to unmap buffer");
|
||||||
m_vertexBuffer->AddResourceReference();
|
Destroy();
|
||||||
m_vertexBuffer->SetPersistent(false);
|
|
||||||
|
return false;
|
||||||
AnimateImpl(0, 0, 0.f);
|
}
|
||||||
|
|
||||||
return true;
|
m_vertexBuffer->AddResourceReference();
|
||||||
}
|
m_vertexBuffer->SetPersistent(false);
|
||||||
|
|
||||||
void NzMD2Mesh::Destroy()
|
AnimateImpl(0, 0, 0.f);
|
||||||
{
|
|
||||||
if (m_frames)
|
return true;
|
||||||
{
|
}
|
||||||
for (unsigned int i = 0; i < m_frameCount; ++i)
|
|
||||||
{
|
void NzMD2Mesh::Destroy()
|
||||||
delete[] m_frames[i].normal;
|
{
|
||||||
delete[] m_frames[i].vertices;
|
if (m_frames)
|
||||||
}
|
{
|
||||||
|
for (unsigned int i = 0; i < m_frameCount; ++i)
|
||||||
delete[] m_frames;
|
{
|
||||||
m_frames = nullptr;
|
delete[] m_frames[i].normal;
|
||||||
}
|
delete[] m_frames[i].vertices;
|
||||||
|
}
|
||||||
if (m_indexBuffer)
|
|
||||||
{
|
delete[] m_frames;
|
||||||
m_indexBuffer->RemoveResourceReference();
|
m_frames = nullptr;
|
||||||
m_indexBuffer = nullptr;
|
}
|
||||||
}
|
|
||||||
|
if (m_indexBuffer)
|
||||||
if (m_vertexBuffer)
|
{
|
||||||
{
|
m_indexBuffer->RemoveResourceReference();
|
||||||
m_vertexBuffer->RemoveResourceReference();
|
m_indexBuffer = nullptr;
|
||||||
m_vertexBuffer = nullptr;
|
}
|
||||||
}
|
|
||||||
}
|
if (m_vertexBuffer)
|
||||||
|
{
|
||||||
const NzAxisAlignedBox& NzMD2Mesh::GetAABB() const
|
m_vertexBuffer->RemoveResourceReference();
|
||||||
{
|
m_vertexBuffer = nullptr;
|
||||||
return m_aabb;
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
nzAnimationType NzMD2Mesh::GetAnimationType() const
|
const NzAxisAlignedBox& NzMD2Mesh::GetAABB() const
|
||||||
{
|
{
|
||||||
if (m_frameCount > 1)
|
return m_aabb;
|
||||||
return nzAnimationType_Keyframe;
|
}
|
||||||
else
|
|
||||||
return nzAnimationType_Static;
|
nzAnimationType NzMD2Mesh::GetAnimationType() const
|
||||||
}
|
{
|
||||||
|
if (m_frameCount > 1)
|
||||||
unsigned int NzMD2Mesh::GetFrameCount() const
|
return nzAnimationType_Keyframe;
|
||||||
{
|
else
|
||||||
return m_frameCount;
|
return nzAnimationType_Static;
|
||||||
}
|
}
|
||||||
|
|
||||||
const NzIndexBuffer* NzMD2Mesh::GetIndexBuffer() const
|
unsigned int NzMD2Mesh::GetFrameCount() const
|
||||||
{
|
{
|
||||||
return nullptr;
|
return m_frameCount;
|
||||||
//return m_indexBuffer;
|
}
|
||||||
}
|
|
||||||
|
const NzIndexBuffer* NzMD2Mesh::GetIndexBuffer() const
|
||||||
nzPrimitiveType NzMD2Mesh::GetPrimitiveType() const
|
{
|
||||||
{
|
return nullptr;
|
||||||
return nzPrimitiveType_TriangleList;
|
//return m_indexBuffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
const NzVertexBuffer* NzMD2Mesh::GetVertexBuffer() const
|
nzPrimitiveType NzMD2Mesh::GetPrimitiveType() const
|
||||||
{
|
{
|
||||||
return m_vertexBuffer;
|
return nzPrimitiveType_TriangleList;
|
||||||
}
|
}
|
||||||
|
|
||||||
const NzVertexDeclaration* NzMD2Mesh::GetVertexDeclaration() const
|
const NzVertexBuffer* NzMD2Mesh::GetVertexBuffer() const
|
||||||
{
|
{
|
||||||
return &s_declaration;
|
return m_vertexBuffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
void NzMD2Mesh::Initialize()
|
const NzVertexDeclaration* NzMD2Mesh::GetVertexDeclaration() const
|
||||||
{
|
{
|
||||||
NzVertexElement elements[3];
|
return &s_declaration;
|
||||||
elements[0].offset = 0;
|
}
|
||||||
elements[0].type = nzElementType_Float3;
|
|
||||||
elements[0].usage = nzElementUsage_Position;
|
void NzMD2Mesh::Initialize()
|
||||||
|
{
|
||||||
elements[1].offset = 3*sizeof(float);
|
NzVertexElement elements[3];
|
||||||
elements[1].type = nzElementType_Float3;
|
elements[0].offset = 0;
|
||||||
elements[1].usage = nzElementUsage_Normal;
|
elements[0].type = nzElementType_Float3;
|
||||||
|
elements[0].usage = nzElementUsage_Position;
|
||||||
elements[2].offset = 3*sizeof(float) + 3*sizeof(float);
|
|
||||||
elements[2].type = nzElementType_Float2;
|
elements[1].offset = 3*sizeof(float);
|
||||||
elements[2].usage = nzElementUsage_TexCoord;
|
elements[1].type = nzElementType_Float3;
|
||||||
|
elements[1].usage = nzElementUsage_Normal;
|
||||||
s_declaration.Create(elements, 3);
|
|
||||||
}
|
elements[2].offset = 3*sizeof(float) + 3*sizeof(float);
|
||||||
|
elements[2].type = nzElementType_Float2;
|
||||||
void NzMD2Mesh::Uninitialize()
|
elements[2].usage = nzElementUsage_TexCoord;
|
||||||
{
|
|
||||||
s_declaration.Destroy();
|
s_declaration.Create(elements, 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
void NzMD2Mesh::AnimateImpl(unsigned int frameA, unsigned int frameB, float interpolation)
|
void NzMD2Mesh::Uninitialize()
|
||||||
{
|
{
|
||||||
nzUInt8* ptr = reinterpret_cast<nzUInt8*>(m_vertexBuffer->Map(nzBufferAccess_WriteOnly));
|
s_declaration.Destroy();
|
||||||
if (!ptr)
|
}
|
||||||
{
|
|
||||||
NazaraError("Failed to map vertex buffer");
|
void NzMD2Mesh::AnimateImpl(unsigned int frameA, unsigned int frameB, float interpolation)
|
||||||
return;
|
{
|
||||||
}
|
nzUInt8* ptr = reinterpret_cast<nzUInt8*>(m_vertexBuffer->Map(nzBufferAccess_WriteOnly));
|
||||||
|
if (!ptr)
|
||||||
unsigned int stride = s_declaration.GetStride(nzElementStream_VertexData);
|
{
|
||||||
unsigned int positionOffset = s_declaration.GetElement(nzElementStream_VertexData, nzElementUsage_Position)->offset;
|
NazaraError("Failed to map vertex buffer");
|
||||||
unsigned int normalOffset = s_declaration.GetElement(nzElementStream_VertexData, nzElementUsage_Normal)->offset;
|
return;
|
||||||
|
}
|
||||||
Frame* fA = &m_frames[frameA];
|
|
||||||
Frame* fB = &m_frames[frameB];
|
unsigned int stride = s_declaration.GetStride(nzElementStream_VertexData);
|
||||||
for (unsigned int i = 0; i < m_vertexCount; ++i)
|
unsigned int positionOffset = s_declaration.GetElement(nzElementStream_VertexData, nzElementUsage_Position)->offset;
|
||||||
{
|
unsigned int normalOffset = s_declaration.GetElement(nzElementStream_VertexData, nzElementUsage_Normal)->offset;
|
||||||
NzVector3f* position = reinterpret_cast<NzVector3f*>(ptr + positionOffset);
|
|
||||||
NzVector3f* normal = reinterpret_cast<NzVector3f*>(ptr + normalOffset);
|
Frame* fA = &m_frames[frameA];
|
||||||
|
Frame* fB = &m_frames[frameB];
|
||||||
*position = fA->vertices[i] + interpolation * (fB->vertices[i] - fA->vertices[i]);
|
for (unsigned int i = 0; i < m_vertexCount; ++i)
|
||||||
*normal = md2Normals[fA->normal[i]] + interpolation * (md2Normals[fB->normal[i]] - md2Normals[fA->normal[i]]);
|
{
|
||||||
|
NzVector3f* position = reinterpret_cast<NzVector3f*>(ptr + positionOffset);
|
||||||
ptr += stride;
|
NzVector3f* normal = reinterpret_cast<NzVector3f*>(ptr + normalOffset);
|
||||||
}
|
|
||||||
|
*position = fA->vertices[i] + interpolation * (fB->vertices[i] - fA->vertices[i]);
|
||||||
if (!m_vertexBuffer->Unmap())
|
*normal = md2Normals[fA->normal[i]] + interpolation * (md2Normals[fB->normal[i]] - md2Normals[fA->normal[i]]);
|
||||||
NazaraWarning("Failed to unmap vertex buffer, expect mesh corruption");
|
|
||||||
|
ptr += stride;
|
||||||
// Interpolation de l'AABB
|
}
|
||||||
NzVector3f max1 = fA->aabb.GetMaximum();
|
|
||||||
NzVector3f min1 = fA->aabb.GetMinimum();
|
if (!m_vertexBuffer->Unmap())
|
||||||
m_aabb.SetExtends(min1 + interpolation * (fB->aabb.GetMinimum() - min1), max1 + interpolation * (fB->aabb.GetMaximum() - max1));
|
NazaraWarning("Failed to unmap vertex buffer, expect mesh corruption");
|
||||||
}
|
|
||||||
|
// Interpolation de l'AABB
|
||||||
NzVertexDeclaration NzMD2Mesh::s_declaration;
|
NzVector3f max1 = fA->aabb.GetMaximum();
|
||||||
|
NzVector3f min1 = fA->aabb.GetMinimum();
|
||||||
|
m_aabb.SetExtends(min1 + interpolation * (fB->aabb.GetMinimum() - min1), max1 + interpolation * (fB->aabb.GetMaximum() - max1));
|
||||||
|
}
|
||||||
|
|
||||||
|
NzVertexDeclaration NzMD2Mesh::s_declaration;
|
||||||
|
|
|
||||||
|
|
@ -1,352 +1,346 @@
|
||||||
// Copyright (C) 2012 Jérôme Leclercq
|
// Copyright (C) 2012 Jérôme Leclercq
|
||||||
// This file is part of the "Nazara Engine - Utility module"
|
// This file is part of the "Nazara Engine - Utility module"
|
||||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||||
|
|
||||||
#include <Nazara/Utility/Loaders/PCX.hpp>
|
#include <Nazara/Utility/Loaders/PCX.hpp>
|
||||||
#include <Nazara/Core/Endianness.hpp>
|
#include <Nazara/Core/Endianness.hpp>
|
||||||
#include <Nazara/Core/Error.hpp>
|
#include <Nazara/Core/Error.hpp>
|
||||||
#include <Nazara/Core/File.hpp>
|
#include <Nazara/Core/File.hpp>
|
||||||
#include <Nazara/Core/InputStream.hpp>
|
#include <Nazara/Core/InputStream.hpp>
|
||||||
#include <Nazara/Core/MemoryStream.hpp>
|
#include <Nazara/Core/MemoryStream.hpp>
|
||||||
#include <Nazara/Utility/Image.hpp>
|
#include <Nazara/Utility/Image.hpp>
|
||||||
#include <Nazara/Utility/Debug.hpp>
|
#include <Nazara/Utility/Debug.hpp>
|
||||||
|
|
||||||
// Auteur du loader original : David Henry
|
// Auteur du loader original : David Henry
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
struct pcx_header
|
struct pcx_header
|
||||||
{
|
{
|
||||||
nzUInt8 manufacturer;
|
nzUInt8 manufacturer;
|
||||||
nzUInt8 version;
|
nzUInt8 version;
|
||||||
nzUInt8 encoding;
|
nzUInt8 encoding;
|
||||||
nzUInt8 bitsPerPixel;
|
nzUInt8 bitsPerPixel;
|
||||||
|
|
||||||
nzUInt16 xmin, ymin;
|
nzUInt16 xmin, ymin;
|
||||||
nzUInt16 xmax, ymax;
|
nzUInt16 xmax, ymax;
|
||||||
nzUInt16 horzRes, vertRes;
|
nzUInt16 horzRes, vertRes;
|
||||||
|
|
||||||
nzUInt8 palette[48];
|
nzUInt8 palette[48];
|
||||||
nzUInt8 reserved;
|
nzUInt8 reserved;
|
||||||
nzUInt8 numColorPlanes;
|
nzUInt8 numColorPlanes;
|
||||||
|
|
||||||
nzUInt16 bytesPerScanLine;
|
nzUInt16 bytesPerScanLine;
|
||||||
nzUInt16 paletteType;
|
nzUInt16 paletteType;
|
||||||
nzUInt16 horzSize, vertSize;
|
nzUInt16 horzSize, vertSize;
|
||||||
|
|
||||||
nzUInt8 padding[54];
|
nzUInt8 padding[54];
|
||||||
};
|
};
|
||||||
|
|
||||||
bool NzLoader_PCX_Check(NzInputStream& stream, const NzImageParams& parameters)
|
bool NzLoader_PCX_Check(NzInputStream& stream, const NzImageParams& parameters)
|
||||||
{
|
{
|
||||||
NazaraUnused(parameters);
|
NazaraUnused(parameters);
|
||||||
|
|
||||||
nzUInt8 manufacturer;
|
nzUInt8 manufacturer;
|
||||||
if (stream.Read(&manufacturer, 1) != 1)
|
if (stream.Read(&manufacturer, 1) != 1)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return manufacturer == 0x0a;
|
return manufacturer == 0x0a;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NzLoader_PCX_Load(NzImage* image, NzInputStream& stream, const NzImageParams& parameters)
|
bool NzLoader_PCX_Load(NzImage* image, NzInputStream& stream, const NzImageParams& parameters)
|
||||||
{
|
{
|
||||||
NazaraUnused(parameters);
|
NazaraUnused(parameters);
|
||||||
|
|
||||||
pcx_header header;
|
pcx_header header;
|
||||||
if (stream.Read(&header, sizeof(pcx_header)) != sizeof(pcx_header))
|
if (stream.Read(&header, sizeof(pcx_header)) != sizeof(pcx_header))
|
||||||
{
|
{
|
||||||
NazaraError("Failed to read header");
|
NazaraError("Failed to read header");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (header.manufacturer != 0x0a)
|
#if defined(NAZARA_BIG_ENDIAN)
|
||||||
{
|
// Les fichiers PCX sont en little endian
|
||||||
NazaraError("Bad version number (" + NzString::Number(header.manufacturer) + ')');
|
NzByteSwap(&header.xmin, sizeof(nzUInt16));
|
||||||
return false;
|
NzByteSwap(&header.ymin, sizeof(nzUInt16));
|
||||||
}
|
NzByteSwap(&header.xmax, sizeof(nzUInt16));
|
||||||
|
NzByteSwap(&header.ymax, sizeof(nzUInt16));
|
||||||
#if defined(NAZARA_BIG_ENDIAN)
|
NzByteSwap(&header.horzRes, sizeof(nzUInt16));
|
||||||
// Les fichiers PCX sont en little endian
|
NzByteSwap(&header.vertRes, sizeof(nzUInt16));
|
||||||
NzByteSwap(&header.xmin, sizeof(nzUInt16));
|
|
||||||
NzByteSwap(&header.ymin, sizeof(nzUInt16));
|
NzByteSwap(&header.bytesPerScanLine, sizeof(nzUInt16));
|
||||||
NzByteSwap(&header.xmax, sizeof(nzUInt16));
|
NzByteSwap(&header.paletteType, sizeof(nzUInt16));
|
||||||
NzByteSwap(&header.ymax, sizeof(nzUInt16));
|
NzByteSwap(&header.horzSize, sizeof(nzUInt16));
|
||||||
NzByteSwap(&header.horzRes, sizeof(nzUInt16));
|
NzByteSwap(&header.vertSize, sizeof(nzUInt16));
|
||||||
NzByteSwap(&header.vertRes, sizeof(nzUInt16));
|
#endif
|
||||||
|
|
||||||
NzByteSwap(&header.bytesPerScanLine, sizeof(nzUInt16));
|
unsigned int bitCount = header.bitsPerPixel * header.numColorPlanes;
|
||||||
NzByteSwap(&header.paletteType, sizeof(nzUInt16));
|
unsigned int width = header.xmax - header.xmin+1;
|
||||||
NzByteSwap(&header.horzSize, sizeof(nzUInt16));
|
unsigned int height = header.ymax - header.ymin+1;
|
||||||
NzByteSwap(&header.vertSize, sizeof(nzUInt16));
|
|
||||||
#endif
|
if (!image->Create(nzImageType_2D, nzPixelFormat_RGB8, width, height, 1, (parameters.levelCount > 0) ? parameters.levelCount : 1))
|
||||||
|
{
|
||||||
unsigned int bitCount = header.bitsPerPixel * header.numColorPlanes;
|
NazaraError("Failed to create image");
|
||||||
unsigned int width = header.xmax - header.xmin+1;
|
return false;
|
||||||
unsigned int height = header.ymax - header.ymin+1;
|
}
|
||||||
|
|
||||||
if (!image->Create(nzImageType_2D, nzPixelFormat_RGB8, width, height, 1, (parameters.levelCount > 0) ? parameters.levelCount : 1))
|
nzUInt8* pixels = image->GetPixels();
|
||||||
{
|
|
||||||
NazaraError("Failed to create image");
|
int rle_value = 0;
|
||||||
return false;
|
unsigned int rle_count = 0;
|
||||||
}
|
|
||||||
|
switch (bitCount)
|
||||||
nzUInt8* pixels = image->GetPixels();
|
{
|
||||||
|
case 1:
|
||||||
int rle_value = 0;
|
{
|
||||||
unsigned int rle_count = 0;
|
for (unsigned int y = 0; y < height; ++y)
|
||||||
|
{
|
||||||
switch (bitCount)
|
nzUInt8* ptr = &pixels[y * width * 3];
|
||||||
{
|
int bytes = header.bytesPerScanLine;
|
||||||
case 1:
|
|
||||||
{
|
/* decode line number y */
|
||||||
for (unsigned int y = 0; y < height; ++y)
|
while (bytes--)
|
||||||
{
|
{
|
||||||
nzUInt8* ptr = &pixels[y * width * 3];
|
if (rle_count == 0)
|
||||||
int bytes = header.bytesPerScanLine;
|
{
|
||||||
|
if (!stream.Read(&rle_value, 1))
|
||||||
/* decode line number y */
|
{
|
||||||
while (bytes--)
|
NazaraError("Failed to read stream (byte " + NzString::Number(stream.GetCursorPos()) + ')');
|
||||||
{
|
return false;
|
||||||
if (rle_count == 0)
|
}
|
||||||
{
|
|
||||||
if (!stream.Read(&rle_value, 1))
|
if (rle_value < 0xc0)
|
||||||
{
|
rle_count = 1;
|
||||||
NazaraError("Failed to read stream (byte " + NzString::Number(stream.GetCursorPos()) + ')');
|
else
|
||||||
return false;
|
{
|
||||||
}
|
rle_count = rle_value - 0xc0;
|
||||||
|
if (!stream.Read(&rle_value, 1))
|
||||||
if (rle_value < 0xc0)
|
{
|
||||||
rle_count = 1;
|
NazaraError("Failed to read stream (byte " + NzString::Number(stream.GetCursorPos()) + ')');
|
||||||
else
|
return false;
|
||||||
{
|
}
|
||||||
rle_count = rle_value - 0xc0;
|
}
|
||||||
if (!stream.Read(&rle_value, 1))
|
}
|
||||||
{
|
|
||||||
NazaraError("Failed to read stream (byte " + NzString::Number(stream.GetCursorPos()) + ')');
|
rle_count--;
|
||||||
return false;
|
|
||||||
}
|
for (int i = 7; i >= 0; --i)
|
||||||
}
|
{
|
||||||
}
|
int colorIndex = ((rle_value & (1 << i)) > 0);
|
||||||
|
|
||||||
rle_count--;
|
*ptr++ = header.palette[colorIndex * 3 + 0];
|
||||||
|
*ptr++ = header.palette[colorIndex * 3 + 1];
|
||||||
for (int i = 7; i >= 0; --i)
|
*ptr++ = header.palette[colorIndex * 3 + 2];
|
||||||
{
|
}
|
||||||
int colorIndex = ((rle_value & (1 << i)) > 0);
|
}
|
||||||
|
}
|
||||||
*ptr++ = header.palette[colorIndex * 3 + 0];
|
break;
|
||||||
*ptr++ = header.palette[colorIndex * 3 + 1];
|
}
|
||||||
*ptr++ = header.palette[colorIndex * 3 + 2];
|
|
||||||
}
|
case 4:
|
||||||
}
|
{
|
||||||
}
|
nzUInt8* colorIndex = new nzUInt8[width];
|
||||||
break;
|
nzUInt8* line = new nzUInt8[header.bytesPerScanLine];
|
||||||
}
|
|
||||||
|
for (unsigned int y = 0; y < height; ++y)
|
||||||
case 4:
|
{
|
||||||
{
|
nzUInt8* ptr = &pixels[y * width * 3];
|
||||||
nzUInt8* colorIndex = new nzUInt8[width];
|
|
||||||
nzUInt8* line = new nzUInt8[header.bytesPerScanLine];
|
std::memset(colorIndex, 0, width);
|
||||||
|
|
||||||
for (unsigned int y = 0; y < height; ++y)
|
for (unsigned int c = 0; c < 4; ++c)
|
||||||
{
|
{
|
||||||
nzUInt8* ptr = &pixels[y * width * 3];
|
nzUInt8* pLine = line;
|
||||||
|
int bytes = header.bytesPerScanLine;
|
||||||
std::memset(colorIndex, 0, width);
|
|
||||||
|
/* decode line number y */
|
||||||
for (unsigned int c = 0; c < 4; ++c)
|
while (bytes--)
|
||||||
{
|
{
|
||||||
nzUInt8* pLine = line;
|
if (rle_count == 0)
|
||||||
int bytes = header.bytesPerScanLine;
|
{
|
||||||
|
if (!stream.Read(&rle_value, 1))
|
||||||
/* decode line number y */
|
{
|
||||||
while (bytes--)
|
NazaraError("Failed to read stream (byte " + NzString::Number(stream.GetCursorPos()) + ')');
|
||||||
{
|
delete[] colorIndex;
|
||||||
if (rle_count == 0)
|
delete[] line;
|
||||||
{
|
|
||||||
if (!stream.Read(&rle_value, 1))
|
return false;
|
||||||
{
|
}
|
||||||
NazaraError("Failed to read stream (byte " + NzString::Number(stream.GetCursorPos()) + ')');
|
|
||||||
delete[] colorIndex;
|
if (rle_value < 0xc0)
|
||||||
delete[] line;
|
rle_count = 1;
|
||||||
|
else
|
||||||
return false;
|
{
|
||||||
}
|
rle_count = rle_value - 0xc0;
|
||||||
|
if (!stream.Read(&rle_value, 1))
|
||||||
if (rle_value < 0xc0)
|
{
|
||||||
rle_count = 1;
|
NazaraError("Failed to read stream (byte " + NzString::Number(stream.GetCursorPos()) + ')');
|
||||||
else
|
delete[] colorIndex;
|
||||||
{
|
delete[] line;
|
||||||
rle_count = rle_value - 0xc0;
|
|
||||||
if (!stream.Read(&rle_value, 1))
|
return false;
|
||||||
{
|
}
|
||||||
NazaraError("Failed to read stream (byte " + NzString::Number(stream.GetCursorPos()) + ')');
|
}
|
||||||
delete[] colorIndex;
|
}
|
||||||
delete[] line;
|
|
||||||
|
rle_count--;
|
||||||
return false;
|
*(pLine++) = rle_value;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
/* compute line's color indexes */
|
||||||
|
for (unsigned int x = 0; x < width; ++x)
|
||||||
rle_count--;
|
{
|
||||||
*(pLine++) = rle_value;
|
if (line[x / 8] & (128 >> (x % 8)))
|
||||||
}
|
colorIndex[x] += (1 << c);
|
||||||
|
}
|
||||||
/* compute line's color indexes */
|
}
|
||||||
for (unsigned int x = 0; x < width; ++x)
|
|
||||||
{
|
/* decode scan line. color index => rgb */
|
||||||
if (line[x / 8] & (128 >> (x % 8)))
|
for (unsigned int x = 0; x < width; ++x)
|
||||||
colorIndex[x] += (1 << c);
|
{
|
||||||
}
|
*ptr++ = header.palette[colorIndex[x] * 3 + 0];
|
||||||
}
|
*ptr++ = header.palette[colorIndex[x] * 3 + 1];
|
||||||
|
*ptr++ = header.palette[colorIndex[x] * 3 + 2];
|
||||||
/* decode scan line. color index => rgb */
|
}
|
||||||
for (unsigned int x = 0; x < width; ++x)
|
}
|
||||||
{
|
|
||||||
*ptr++ = header.palette[colorIndex[x] * 3 + 0];
|
/* release memory */
|
||||||
*ptr++ = header.palette[colorIndex[x] * 3 + 1];
|
delete[] colorIndex;
|
||||||
*ptr++ = header.palette[colorIndex[x] * 3 + 2];
|
delete[] line;
|
||||||
}
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* release memory */
|
case 8:
|
||||||
delete[] colorIndex;
|
{
|
||||||
delete[] line;
|
nzUInt8 palette[768];
|
||||||
break;
|
|
||||||
}
|
/* the palette is contained in the last 769 bytes of the file */
|
||||||
|
unsigned int curPos = stream.GetCursorPos();
|
||||||
case 8:
|
stream.SetCursorPos(stream.GetSize()-769);
|
||||||
{
|
nzUInt8 magic;
|
||||||
nzUInt8 palette[768];
|
if (!stream.Read(&magic, 1))
|
||||||
|
{
|
||||||
/* the palette is contained in the last 769 bytes of the file */
|
NazaraError("Failed to read stream (byte " + NzString::Number(stream.GetCursorPos()) + ')');
|
||||||
unsigned int curPos = stream.GetCursorPos();
|
return false;
|
||||||
stream.SetCursorPos(stream.GetSize()-769);
|
}
|
||||||
nzUInt8 magic;
|
|
||||||
if (!stream.Read(&magic, 1))
|
/* first byte must be equal to 0x0c (12) */
|
||||||
{
|
if (magic != 0x0c)
|
||||||
NazaraError("Failed to read stream (byte " + NzString::Number(stream.GetCursorPos()) + ')');
|
{
|
||||||
return false;
|
NazaraError("Colormap's first byte must be 0x0c (0x" + NzString::Number(magic, 16) + ')');
|
||||||
}
|
return false;
|
||||||
|
}
|
||||||
/* first byte must be equal to 0x0c (12) */
|
|
||||||
if (magic != 0x0c)
|
/* read palette */
|
||||||
{
|
if (stream.Read(palette, 768) != 768)
|
||||||
NazaraError("Colormap's first byte must be 0x0c (0x" + NzString::Number(magic, 16) + ')');
|
{
|
||||||
return false;
|
NazaraError("Failed to read palette");
|
||||||
}
|
return false;
|
||||||
|
}
|
||||||
/* read palette */
|
|
||||||
if (stream.Read(palette, 768) != 768)
|
stream.SetCursorPos(curPos);
|
||||||
{
|
|
||||||
NazaraError("Failed to read palette");
|
/* read pixel data */
|
||||||
return false;
|
for (unsigned int y = 0; y < height; ++y)
|
||||||
}
|
{
|
||||||
|
nzUInt8* ptr = &pixels[y * width * 3];
|
||||||
stream.SetCursorPos(curPos);
|
int bytes = header.bytesPerScanLine;
|
||||||
|
|
||||||
/* read pixel data */
|
/* decode line number y */
|
||||||
for (unsigned int y = 0; y < height; ++y)
|
while (bytes--)
|
||||||
{
|
{
|
||||||
nzUInt8* ptr = &pixels[y * width * 3];
|
if (rle_count == 0)
|
||||||
int bytes = header.bytesPerScanLine;
|
{
|
||||||
|
if (!stream.Read(&rle_value, 1))
|
||||||
/* decode line number y */
|
{
|
||||||
while (bytes--)
|
NazaraError("Failed to read stream (byte " + NzString::Number(stream.GetCursorPos()) + ')');
|
||||||
{
|
return false;
|
||||||
if (rle_count == 0)
|
}
|
||||||
{
|
|
||||||
if (!stream.Read(&rle_value, 1))
|
if (rle_value < 0xc0)
|
||||||
{
|
rle_count = 1;
|
||||||
NazaraError("Failed to read stream (byte " + NzString::Number(stream.GetCursorPos()) + ')');
|
else
|
||||||
return false;
|
{
|
||||||
}
|
rle_count = rle_value - 0xc0;
|
||||||
|
if (!stream.Read(&rle_value, 1))
|
||||||
if (rle_value < 0xc0)
|
{
|
||||||
rle_count = 1;
|
NazaraError("Failed to read stream (byte " + NzString::Number(stream.GetCursorPos()) + ')');
|
||||||
else
|
return false;
|
||||||
{
|
}
|
||||||
rle_count = rle_value - 0xc0;
|
}
|
||||||
if (!stream.Read(&rle_value, 1))
|
}
|
||||||
{
|
|
||||||
NazaraError("Failed to read stream (byte " + NzString::Number(stream.GetCursorPos()) + ')');
|
rle_count--;
|
||||||
return false;
|
|
||||||
}
|
*ptr++ = palette[rle_value * 3 + 0];
|
||||||
}
|
*ptr++ = palette[rle_value * 3 + 1];
|
||||||
}
|
*ptr++ = palette[rle_value * 3 + 2];
|
||||||
|
}
|
||||||
rle_count--;
|
}
|
||||||
|
break;
|
||||||
*ptr++ = palette[rle_value * 3 + 0];
|
}
|
||||||
*ptr++ = palette[rle_value * 3 + 1];
|
|
||||||
*ptr++ = palette[rle_value * 3 + 2];
|
case 24:
|
||||||
}
|
{
|
||||||
}
|
for (unsigned int y = 0; y < height; ++y)
|
||||||
break;
|
{
|
||||||
}
|
/* for each color plane */
|
||||||
|
for (int c = 0; c < 3; ++c)
|
||||||
case 24:
|
{
|
||||||
{
|
nzUInt8* ptr = &pixels[y * width * 4];
|
||||||
for (unsigned int y = 0; y < height; ++y)
|
int bytes = header.bytesPerScanLine;
|
||||||
{
|
|
||||||
/* for each color plane */
|
/* decode line number y */
|
||||||
for (int c = 0; c < 3; ++c)
|
while (bytes--)
|
||||||
{
|
{
|
||||||
nzUInt8* ptr = &pixels[y * width * 4];
|
if (rle_count == 0)
|
||||||
int bytes = header.bytesPerScanLine;
|
{
|
||||||
|
if (!stream.Read(&rle_value, 1))
|
||||||
/* decode line number y */
|
{
|
||||||
while (bytes--)
|
NazaraError("Failed to read stream (byte " + NzString::Number(stream.GetCursorPos()) + ')');
|
||||||
{
|
return false;
|
||||||
if (rle_count == 0)
|
}
|
||||||
{
|
|
||||||
if (!stream.Read(&rle_value, 1))
|
if (rle_value < 0xc0)
|
||||||
{
|
rle_count = 1;
|
||||||
NazaraError("Failed to read stream (byte " + NzString::Number(stream.GetCursorPos()) + ')');
|
else
|
||||||
return false;
|
{
|
||||||
}
|
rle_count = rle_value - 0xc0;
|
||||||
|
if (!stream.Read(&rle_value, 1))
|
||||||
if (rle_value < 0xc0)
|
{
|
||||||
rle_count = 1;
|
NazaraError("Failed to read stream (byte " + NzString::Number(stream.GetCursorPos()) + ')');
|
||||||
else
|
return false;
|
||||||
{
|
}
|
||||||
rle_count = rle_value - 0xc0;
|
}
|
||||||
if (!stream.Read(&rle_value, 1))
|
}
|
||||||
{
|
|
||||||
NazaraError("Failed to read stream (byte " + NzString::Number(stream.GetCursorPos()) + ')');
|
rle_count--;
|
||||||
return false;
|
ptr[c] = static_cast<nzUInt8>(rle_value);
|
||||||
}
|
ptr += 3;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
rle_count--;
|
break;
|
||||||
ptr[c] = static_cast<nzUInt8>(rle_value);
|
}
|
||||||
ptr += 3;
|
|
||||||
}
|
default:
|
||||||
}
|
NazaraError("Failed to load " + NzString::Number(bitCount) + " bitcount pcx files");
|
||||||
}
|
return false;
|
||||||
break;
|
}
|
||||||
}
|
|
||||||
|
if (parameters.loadFormat != nzPixelFormat_Undefined)
|
||||||
default:
|
image->Convert(parameters.loadFormat);
|
||||||
NazaraError("Failed to load " + NzString::Number(bitCount) + " bitcount pcx files");
|
|
||||||
return false;
|
return true;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if (parameters.loadFormat != nzPixelFormat_Undefined)
|
|
||||||
image->Convert(parameters.loadFormat);
|
void NzLoaders_PCX_Register()
|
||||||
|
{
|
||||||
return true;
|
NzImageLoader::RegisterLoader("pcx", NzLoader_PCX_Check, NzLoader_PCX_Load);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
void NzLoaders_PCX_Unregister()
|
||||||
void NzLoaders_PCX_Register()
|
{
|
||||||
{
|
NzImageLoader::UnregisterLoader("pcx", NzLoader_PCX_Check, NzLoader_PCX_Load);
|
||||||
NzImageLoader::RegisterLoader("pcx", NzLoader_PCX_Check, NzLoader_PCX_Load);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
void NzLoaders_PCX_Unregister()
|
|
||||||
{
|
|
||||||
NzImageLoader::UnregisterLoader("pcx", NzLoader_PCX_Check, NzLoader_PCX_Load);
|
|
||||||
}
|
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -1,186 +1,199 @@
|
||||||
// Copyright (C) 2012 Jérôme Leclercq
|
// Copyright (C) 2012 Jérôme Leclercq
|
||||||
// This file is part of the "Nazara Engine - Utility module"
|
// This file is part of the "Nazara Engine - Utility module"
|
||||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||||
|
|
||||||
#include <Nazara/Utility/StaticMesh.hpp>
|
#include <Nazara/Utility/StaticMesh.hpp>
|
||||||
#include <Nazara/Core/Error.hpp>
|
#include <Nazara/Core/Error.hpp>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include <Nazara/Utility/Debug.hpp>
|
#include <Nazara/Utility/Debug.hpp>
|
||||||
|
|
||||||
NzStaticMesh::NzStaticMesh(const NzMesh* parent) :
|
NzStaticMesh::NzStaticMesh(const NzMesh* parent) :
|
||||||
NzSubMesh(parent)
|
NzSubMesh(parent)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
NzStaticMesh::NzStaticMesh(const NzMesh* parent, const NzVertexDeclaration* vertexDeclaration, NzVertexBuffer* vertexBuffer, NzIndexBuffer* indexBuffer) :
|
NzStaticMesh::NzStaticMesh(const NzMesh* parent, const NzVertexDeclaration* vertexDeclaration, NzVertexBuffer* vertexBuffer, NzIndexBuffer* indexBuffer) :
|
||||||
NzSubMesh(parent)
|
NzSubMesh(parent)
|
||||||
{
|
{
|
||||||
#ifdef NAZARA_DEBUG
|
#ifdef NAZARA_DEBUG
|
||||||
if (!Create(vertexDeclaration, vertexBuffer, indexBuffer))
|
if (!Create(vertexDeclaration, vertexBuffer, indexBuffer))
|
||||||
{
|
{
|
||||||
NazaraError("Failed to create mesh");
|
NazaraError("Failed to create mesh");
|
||||||
throw std::runtime_error("Constructor failed");
|
throw std::runtime_error("Constructor failed");
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
Create(vertexDeclaration, vertexBuffer, indexBuffer);
|
Create(vertexDeclaration, vertexBuffer, indexBuffer);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
NzStaticMesh::~NzStaticMesh()
|
NzStaticMesh::~NzStaticMesh()
|
||||||
{
|
{
|
||||||
Destroy();
|
Destroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NzStaticMesh::Create(const NzVertexDeclaration* vertexDeclaration, NzVertexBuffer* vertexBuffer, NzIndexBuffer* indexBuffer)
|
bool NzStaticMesh::Create(const NzVertexDeclaration* vertexDeclaration, NzVertexBuffer* vertexBuffer, NzIndexBuffer* indexBuffer)
|
||||||
{
|
{
|
||||||
Destroy();
|
Destroy();
|
||||||
|
|
||||||
#if NAZARA_UTILITY_SAFE
|
#if NAZARA_UTILITY_SAFE
|
||||||
if (!vertexDeclaration)
|
if (!vertexDeclaration)
|
||||||
{
|
{
|
||||||
NazaraError("Vertex declaration is null");
|
NazaraError("Invalid vertex declaration");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!vertexBuffer)
|
if (!vertexBuffer)
|
||||||
{
|
{
|
||||||
NazaraError("Vertex buffer is null");
|
NazaraError("Invalid vertex buffer");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (indexBuffer)
|
if (indexBuffer)
|
||||||
{
|
indexBuffer->AddResourceListener(this);
|
||||||
m_indexBuffer = indexBuffer;
|
|
||||||
m_indexBuffer->AddResourceReference();
|
m_indexBuffer = indexBuffer;
|
||||||
}
|
|
||||||
|
m_vertexBuffer = vertexBuffer;
|
||||||
m_vertexBuffer = vertexBuffer;
|
m_vertexBuffer->AddResourceListener(this);
|
||||||
m_vertexBuffer->AddResourceReference();
|
|
||||||
|
m_vertexDeclaration = vertexDeclaration;
|
||||||
m_vertexDeclaration = vertexDeclaration;
|
m_vertexDeclaration->AddResourceListener(this);
|
||||||
m_vertexDeclaration->AddResourceReference();
|
|
||||||
|
return true;
|
||||||
return true;
|
}
|
||||||
}
|
|
||||||
|
void NzStaticMesh::Destroy()
|
||||||
void NzStaticMesh::Destroy()
|
{
|
||||||
{
|
m_aabb.SetNull();
|
||||||
m_aabb.SetNull();
|
|
||||||
|
if (m_indexBuffer)
|
||||||
if (m_indexBuffer)
|
{
|
||||||
{
|
m_indexBuffer->RemoveResourceListener(this);
|
||||||
m_indexBuffer->RemoveResourceReference();
|
m_indexBuffer = nullptr;
|
||||||
m_indexBuffer = nullptr;
|
}
|
||||||
}
|
|
||||||
|
if (m_vertexBuffer)
|
||||||
if (m_vertexBuffer)
|
{
|
||||||
{
|
m_vertexBuffer->RemoveResourceListener(this);
|
||||||
m_vertexBuffer->RemoveResourceReference();
|
m_vertexBuffer = nullptr;
|
||||||
m_vertexBuffer = nullptr;
|
}
|
||||||
}
|
|
||||||
|
if (m_vertexDeclaration)
|
||||||
if (m_vertexDeclaration)
|
{
|
||||||
{
|
m_vertexDeclaration->RemoveResourceListener(this);
|
||||||
m_vertexDeclaration->RemoveResourceReference();
|
m_vertexDeclaration = nullptr;
|
||||||
m_vertexDeclaration = nullptr;
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
bool NzStaticMesh::GenerateAABB()
|
||||||
bool NzStaticMesh::GenerateAABB()
|
{
|
||||||
{
|
if (!m_aabb.IsNull())
|
||||||
if (!m_aabb.IsNull())
|
return true;
|
||||||
return true;
|
|
||||||
|
const NzVertexElement* position = m_vertexDeclaration->GetElement(nzElementStream_VertexData, nzElementUsage_Position);
|
||||||
const NzVertexElement* position = m_vertexDeclaration->GetElement(nzElementStream_VertexData, nzElementUsage_Position);
|
if (position && position->type == nzElementType_Float3) // Si nous avons des positions du type Vec3
|
||||||
if (position && position->type == nzElementType_Float3) // Si nous avons des positions du type Vec3
|
{
|
||||||
{
|
// On lock le buffer pour itérer sur toutes les positions et composer notre AABB
|
||||||
// On lock le buffer pour itérer sur toutes les positions et composer notre AABB
|
nzUInt8* buffer = reinterpret_cast<nzUInt8*>(m_vertexBuffer->Map(nzBufferAccess_ReadOnly));
|
||||||
nzUInt8* buffer = reinterpret_cast<nzUInt8*>(m_vertexBuffer->Map(nzBufferAccess_ReadOnly));
|
if (!buffer)
|
||||||
if (!buffer)
|
{
|
||||||
{
|
NazaraWarning("Failed to lock vertex buffer");
|
||||||
NazaraWarning("Failed to lock vertex buffer");
|
return false;
|
||||||
return false;
|
}
|
||||||
}
|
|
||||||
|
buffer += position->offset;
|
||||||
buffer += position->offset;
|
unsigned int stride = m_vertexDeclaration->GetStride(nzElementStream_VertexData);
|
||||||
unsigned int stride = m_vertexDeclaration->GetStride(nzElementStream_VertexData);
|
unsigned int vertexCount = m_vertexBuffer->GetVertexCount();
|
||||||
unsigned int vertexCount = m_vertexBuffer->GetVertexCount();
|
for (unsigned int i = 0; i < vertexCount; ++i)
|
||||||
for (unsigned int i = 0; i < vertexCount; ++i)
|
{
|
||||||
{
|
m_aabb.ExtendTo(*reinterpret_cast<NzVector3f*>(buffer));
|
||||||
m_aabb.ExtendTo(*reinterpret_cast<NzVector3f*>(buffer));
|
|
||||||
|
buffer += stride;
|
||||||
buffer += stride;
|
}
|
||||||
}
|
|
||||||
|
if (!m_vertexBuffer->Unmap())
|
||||||
if (!m_vertexBuffer->Unmap())
|
NazaraWarning("Failed to unmap vertex buffer");
|
||||||
NazaraWarning("Failed to unmap vertex buffer");
|
}
|
||||||
}
|
|
||||||
|
return true;
|
||||||
return true;
|
}
|
||||||
}
|
|
||||||
|
const NzAxisAlignedBox& NzStaticMesh::GetAABB() const
|
||||||
const NzAxisAlignedBox& NzStaticMesh::GetAABB() const
|
{
|
||||||
{
|
return m_aabb;
|
||||||
return m_aabb;
|
}
|
||||||
}
|
|
||||||
|
nzAnimationType NzStaticMesh::GetAnimationType() const
|
||||||
nzAnimationType NzStaticMesh::GetAnimationType() const
|
{
|
||||||
{
|
return nzAnimationType_Static;
|
||||||
return nzAnimationType_Static;
|
}
|
||||||
}
|
|
||||||
|
unsigned int NzStaticMesh::GetFrameCount() const
|
||||||
unsigned int NzStaticMesh::GetFrameCount() const
|
{
|
||||||
{
|
return 1;
|
||||||
return 1;
|
}
|
||||||
}
|
|
||||||
|
const NzIndexBuffer* NzStaticMesh::GetIndexBuffer() const
|
||||||
const NzIndexBuffer* NzStaticMesh::GetIndexBuffer() const
|
{
|
||||||
{
|
return m_indexBuffer;
|
||||||
return m_indexBuffer;
|
}
|
||||||
}
|
|
||||||
|
nzPrimitiveType NzStaticMesh::GetPrimitiveType() const
|
||||||
nzPrimitiveType NzStaticMesh::GetPrimitiveType() const
|
{
|
||||||
{
|
return m_primitiveType;
|
||||||
return m_primitiveType;
|
}
|
||||||
}
|
|
||||||
|
const NzVertexBuffer* NzStaticMesh::GetVertexBuffer() const
|
||||||
const NzVertexBuffer* NzStaticMesh::GetVertexBuffer() const
|
{
|
||||||
{
|
return m_vertexBuffer;
|
||||||
return m_vertexBuffer;
|
}
|
||||||
}
|
|
||||||
|
const NzVertexDeclaration* NzStaticMesh::GetVertexDeclaration() const
|
||||||
const NzVertexDeclaration* NzStaticMesh::GetVertexDeclaration() const
|
{
|
||||||
{
|
return m_vertexDeclaration;
|
||||||
return m_vertexDeclaration;
|
}
|
||||||
}
|
|
||||||
|
bool NzStaticMesh::IsAnimated() const
|
||||||
bool NzStaticMesh::IsAnimated() const
|
{
|
||||||
{
|
return false;
|
||||||
return false;
|
}
|
||||||
}
|
|
||||||
|
bool NzStaticMesh::IsValid() const
|
||||||
bool NzStaticMesh::IsValid() const
|
{
|
||||||
{
|
return m_vertexBuffer != nullptr && m_vertexDeclaration != nullptr;
|
||||||
return m_vertexBuffer != nullptr && m_vertexDeclaration != nullptr;
|
}
|
||||||
}
|
|
||||||
|
void NzStaticMesh::SetAABB(const NzAxisAlignedBox& aabb)
|
||||||
void NzStaticMesh::SetAABB(const NzAxisAlignedBox& aabb)
|
{
|
||||||
{
|
m_aabb = aabb;
|
||||||
m_aabb = aabb;
|
}
|
||||||
}
|
|
||||||
|
void NzStaticMesh::SetPrimitiveType(nzPrimitiveType primitiveType)
|
||||||
void NzStaticMesh::SetPrimitiveType(nzPrimitiveType primitiveType)
|
{
|
||||||
{
|
m_primitiveType = primitiveType;
|
||||||
m_primitiveType = primitiveType;
|
}
|
||||||
}
|
|
||||||
|
void NzStaticMesh::AnimateImpl(unsigned int frameA, unsigned int frameB, float interpolation)
|
||||||
void NzStaticMesh::AnimateImpl(unsigned int frameA, unsigned int frameB, float interpolation)
|
{
|
||||||
{
|
NazaraUnused(frameA);
|
||||||
NazaraUnused(frameA);
|
NazaraUnused(frameB);
|
||||||
NazaraUnused(frameB);
|
NazaraUnused(interpolation);
|
||||||
NazaraUnused(interpolation);
|
|
||||||
|
// Le safe mode est censé nous protéger de cet appel
|
||||||
// Le safe mode est censé nous protéger de cet appel
|
NazaraError("Static mesh have no animation, please enable safe mode");
|
||||||
NazaraError("Static mesh have no animation, please enable safe mode");
|
}
|
||||||
}
|
|
||||||
|
void NzStaticMesh::OnResourceReleased(const NzResource* resource, int index)
|
||||||
|
{
|
||||||
|
NazaraUnused(index);
|
||||||
|
|
||||||
|
if (resource == m_indexBuffer)
|
||||||
|
m_indexBuffer = nullptr;
|
||||||
|
else if (resource == m_vertexBuffer)
|
||||||
|
m_vertexBuffer = nullptr;
|
||||||
|
else if (resource == m_vertexDeclaration)
|
||||||
|
m_vertexDeclaration = nullptr;
|
||||||
|
else
|
||||||
|
NazaraInternalError("Not listening to " + NzString::Pointer(resource));
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,346 +1,372 @@
|
||||||
// Copyright (C) 2012 Jérôme Leclercq
|
// Copyright (C) 2012 Jérôme Leclercq
|
||||||
// This file is part of the "Nazara Engine - Utility module"
|
// This file is part of the "Nazara Engine - Utility module"
|
||||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||||
|
|
||||||
#include <Nazara/Utility/VertexDeclaration.hpp>
|
#include <Nazara/Utility/VertexDeclaration.hpp>
|
||||||
#include <Nazara/Core/Error.hpp>
|
#include <Nazara/Core/Error.hpp>
|
||||||
#include <Nazara/Utility/Config.hpp>
|
#include <Nazara/Utility/Config.hpp>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#if NAZARA_UTILITY_THREADSAFE && NAZARA_THREADSAFETY_VERTEXDECLARATION
|
#if NAZARA_UTILITY_THREADSAFE && NAZARA_THREADSAFETY_VERTEXDECLARATION
|
||||||
#include <Nazara/Core/ThreadSafety.hpp>
|
#include <Nazara/Core/ThreadSafety.hpp>
|
||||||
#else
|
#else
|
||||||
#include <Nazara/Core/ThreadSafetyOff.hpp>
|
#include <Nazara/Core/ThreadSafetyOff.hpp>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <Nazara/Utility/Debug.hpp>
|
#include <Nazara/Utility/Debug.hpp>
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
const unsigned int size[] =
|
const unsigned int elementCount[] =
|
||||||
{
|
{
|
||||||
sizeof(nzUInt32), // nzElementType_Color
|
4, // nzElementType_Color
|
||||||
1*sizeof(double), // nzElementType_Double1
|
1, // nzElementType_Double1
|
||||||
2*sizeof(double), // nzElementType_Double2
|
2, // nzElementType_Double2
|
||||||
3*sizeof(double), // nzElementType_Double3
|
3, // nzElementType_Double3
|
||||||
4*sizeof(double), // nzElementType_Double4
|
4, // nzElementType_Double4
|
||||||
1*sizeof(float), // nzElementType_Float1
|
1, // nzElementType_Float1
|
||||||
2*sizeof(float), // nzElementType_Float2
|
2, // nzElementType_Float2
|
||||||
3*sizeof(float), // nzElementType_Float3
|
3, // nzElementType_Float3
|
||||||
4*sizeof(float) // nzElementType_Float4
|
4 // nzElementType_Float4
|
||||||
};
|
};
|
||||||
|
|
||||||
bool VertexElementCompare(const NzVertexElement& elementA, const NzVertexElement& elementB)
|
const unsigned int elementSize[] =
|
||||||
{
|
{
|
||||||
// Nous classons d'abord par stream
|
4*sizeof(nzUInt8), // nzElementType_Color
|
||||||
if (elementA.stream == elementB.stream)
|
1*sizeof(double), // nzElementType_Double1
|
||||||
{
|
2*sizeof(double), // nzElementType_Double2
|
||||||
// Ensuite par usage
|
3*sizeof(double), // nzElementType_Double3
|
||||||
if (elementA.usage == elementB.usage)
|
4*sizeof(double), // nzElementType_Double4
|
||||||
// Et finalement par usageIndex
|
1*sizeof(float), // nzElementType_Float1
|
||||||
return elementA.usageIndex < elementB.usageIndex;
|
2*sizeof(float), // nzElementType_Float2
|
||||||
else
|
3*sizeof(float), // nzElementType_Float3
|
||||||
return elementA.usage < elementB.usage;
|
4*sizeof(float) // nzElementType_Float4
|
||||||
}
|
};
|
||||||
else
|
|
||||||
return elementA.stream < elementB.stream;
|
bool VertexElementCompare(const NzVertexElement& elementA, const NzVertexElement& elementB)
|
||||||
}
|
{
|
||||||
}
|
// Nous classons d'abord par stream
|
||||||
|
if (elementA.stream == elementB.stream)
|
||||||
struct NzVertexDeclarationImpl
|
{
|
||||||
{
|
// Ensuite par usage
|
||||||
std::vector<NzVertexElement> elements;
|
if (elementA.usage == elementB.usage)
|
||||||
int elementPos[nzElementStream_Max+1][nzElementUsage_Max+1];
|
// Et finalement par usageIndex
|
||||||
int streamPos[nzElementStream_Max+1];
|
return elementA.usageIndex < elementB.usageIndex;
|
||||||
unsigned int stride[nzElementStream_Max+1] = {0};
|
else
|
||||||
|
return elementA.usage < elementB.usage;
|
||||||
unsigned short refCount = 1;
|
}
|
||||||
NazaraMutex(mutex)
|
else
|
||||||
};
|
return elementA.stream < elementB.stream;
|
||||||
|
}
|
||||||
NzVertexDeclaration::NzVertexDeclaration(const NzVertexElement* elements, unsigned int elementCount)
|
}
|
||||||
{
|
|
||||||
#ifdef NAZARA_DEBUG
|
struct NzVertexDeclarationImpl
|
||||||
if (!Create(elements, elementCount))
|
{
|
||||||
{
|
std::vector<NzVertexElement> elements;
|
||||||
NazaraError("Failed to create declaration");
|
int elementPos[nzElementStream_Max+1][nzElementUsage_Max+1];
|
||||||
throw std::runtime_error("Constructor failed");
|
int streamPos[nzElementStream_Max+1];
|
||||||
}
|
unsigned int stride[nzElementStream_Max+1] = {0};
|
||||||
#else
|
|
||||||
Create(elements, elementCount);
|
unsigned short refCount = 1;
|
||||||
#endif
|
NazaraMutex(mutex)
|
||||||
}
|
};
|
||||||
|
|
||||||
NzVertexDeclaration::NzVertexDeclaration(const NzVertexDeclaration& declaration) :
|
NzVertexDeclaration::NzVertexDeclaration(const NzVertexElement* elements, unsigned int elementCount)
|
||||||
NzResource(),
|
{
|
||||||
m_sharedImpl(declaration.m_sharedImpl)
|
#ifdef NAZARA_DEBUG
|
||||||
{
|
if (!Create(elements, elementCount))
|
||||||
if (m_sharedImpl)
|
{
|
||||||
{
|
NazaraError("Failed to create declaration");
|
||||||
NazaraMutexLock(m_sharedImpl->mutex);
|
throw std::runtime_error("Constructor failed");
|
||||||
m_sharedImpl->refCount++;
|
}
|
||||||
NazaraMutexUnlock(m_sharedImpl->mutex);
|
#else
|
||||||
}
|
Create(elements, elementCount);
|
||||||
}
|
#endif
|
||||||
|
}
|
||||||
NzVertexDeclaration::NzVertexDeclaration(NzVertexDeclaration&& declaration) noexcept :
|
|
||||||
m_sharedImpl(declaration.m_sharedImpl)
|
NzVertexDeclaration::NzVertexDeclaration(const NzVertexDeclaration& declaration) :
|
||||||
{
|
NzResource(),
|
||||||
declaration.m_sharedImpl = nullptr;
|
m_sharedImpl(declaration.m_sharedImpl)
|
||||||
}
|
{
|
||||||
|
if (m_sharedImpl)
|
||||||
NzVertexDeclaration::~NzVertexDeclaration()
|
{
|
||||||
{
|
NazaraMutexLock(m_sharedImpl->mutex);
|
||||||
Destroy();
|
m_sharedImpl->refCount++;
|
||||||
}
|
NazaraMutexUnlock(m_sharedImpl->mutex);
|
||||||
|
}
|
||||||
bool NzVertexDeclaration::Create(const NzVertexElement* elements, unsigned int elementCount)
|
}
|
||||||
{
|
|
||||||
Destroy();
|
NzVertexDeclaration::NzVertexDeclaration(NzVertexDeclaration&& declaration) noexcept :
|
||||||
|
m_sharedImpl(declaration.m_sharedImpl)
|
||||||
#if NAZARA_UTILITY_SAFE
|
{
|
||||||
if (!elements || elementCount == 0)
|
declaration.m_sharedImpl = nullptr;
|
||||||
{
|
}
|
||||||
NazaraError("No element");
|
|
||||||
return false;
|
NzVertexDeclaration::~NzVertexDeclaration()
|
||||||
}
|
{
|
||||||
#endif
|
Destroy();
|
||||||
|
}
|
||||||
NzVertexDeclarationImpl* impl = new NzVertexDeclarationImpl;
|
|
||||||
std::memset(&impl->elementPos, -1, (nzElementStream_Max+1)*(nzElementUsage_Max+1)*sizeof(int));
|
bool NzVertexDeclaration::Create(const NzVertexElement* elements, unsigned int elementCount)
|
||||||
std::memset(&impl->streamPos, -1, (nzElementStream_Max+1)*sizeof(int));
|
{
|
||||||
|
Destroy();
|
||||||
// On copie et trie les éléments
|
|
||||||
impl->elements.resize(elementCount);
|
#if NAZARA_UTILITY_SAFE
|
||||||
std::memcpy(&impl->elements[0], elements, elementCount*sizeof(NzVertexElement));
|
if (!elements || elementCount == 0)
|
||||||
std::sort(impl->elements.begin(), impl->elements.end(), VertexElementCompare);
|
{
|
||||||
|
NazaraError("No element");
|
||||||
for (unsigned int i = 0; i < elementCount; ++i)
|
return false;
|
||||||
{
|
}
|
||||||
NzVertexElement& current = impl->elements[i];
|
#endif
|
||||||
#if NAZARA_UTILITY_SAFE
|
|
||||||
// Notre tableau étant trié, s'il y a collision, les deux éléments identiques se suivent...
|
NzVertexDeclarationImpl* impl = new NzVertexDeclarationImpl;
|
||||||
if (i > 0)
|
std::memset(&impl->elementPos, -1, (nzElementStream_Max+1)*(nzElementUsage_Max+1)*sizeof(int));
|
||||||
{
|
std::memset(&impl->streamPos, -1, (nzElementStream_Max+1)*sizeof(int));
|
||||||
NzVertexElement& previous = impl->elements[i-1]; // On accède à l'élément précédent
|
|
||||||
if (previous.usage == current.usage && previous.usageIndex == current.usageIndex && previous.stream == current.stream)
|
// On copie et trie les éléments
|
||||||
{
|
impl->elements.resize(elementCount);
|
||||||
// Les deux éléments sont identiques là où ils ne devraient pas, nous avons une collision...
|
std::memcpy(&impl->elements[0], elements, elementCount*sizeof(NzVertexElement));
|
||||||
NazaraError("Element usage 0x" + NzString::Number(current.usage, 16) + " collision with usage index " + NzString::Number(current.usageIndex) + " on stream 0x" + NzString::Number(current.stream, 16));
|
std::sort(impl->elements.begin(), impl->elements.end(), VertexElementCompare);
|
||||||
delete impl;
|
|
||||||
|
for (unsigned int i = 0; i < elementCount; ++i)
|
||||||
return false;
|
{
|
||||||
}
|
NzVertexElement& current = impl->elements[i];
|
||||||
}
|
#if NAZARA_UTILITY_SAFE
|
||||||
#endif
|
// Notre tableau étant trié, s'il y a collision, les deux éléments identiques se suivent...
|
||||||
|
if (i > 0)
|
||||||
if (current.usageIndex == 0)
|
{
|
||||||
impl->elementPos[current.stream][current.usage] = i;
|
NzVertexElement& previous = impl->elements[i-1]; // On accède à l'élément précédent
|
||||||
|
if (previous.usage == current.usage && previous.usageIndex == current.usageIndex && previous.stream == current.stream)
|
||||||
if (impl->streamPos[current.stream] == -1)
|
{
|
||||||
impl->streamPos[current.stream] = i; // Premier élément du stream (via le triage)
|
// Les deux éléments sont identiques là où ils ne devraient pas, nous avons une collision...
|
||||||
|
NazaraError("Element usage 0x" + NzString::Number(current.usage, 16) + " collision with usage index " + NzString::Number(current.usageIndex) + " on stream 0x" + NzString::Number(current.stream, 16));
|
||||||
impl->stride[current.stream] += size[current.type];
|
delete impl;
|
||||||
}
|
|
||||||
|
return false;
|
||||||
#if NAZARA_UTILITY_FORCE_DECLARATION_STRIDE_MULTIPLE_OF_32
|
}
|
||||||
for (unsigned int& stride : impl->stride)
|
}
|
||||||
stride = ((static_cast<int>(stride)-1)/32+1)*32;
|
#endif
|
||||||
#endif
|
|
||||||
|
if (current.usageIndex == 0)
|
||||||
m_sharedImpl = impl;
|
impl->elementPos[current.stream][current.usage] = i;
|
||||||
|
|
||||||
return true;
|
if (impl->streamPos[current.stream] == -1)
|
||||||
}
|
impl->streamPos[current.stream] = i; // Premier élément du stream (via le triage)
|
||||||
|
|
||||||
void NzVertexDeclaration::Destroy()
|
impl->stride[current.stream] += elementSize[current.type];
|
||||||
{
|
}
|
||||||
if (!m_sharedImpl)
|
|
||||||
return;
|
#if NAZARA_UTILITY_FORCE_DECLARATION_STRIDE_MULTIPLE_OF_32
|
||||||
|
for (unsigned int& stride : impl->stride)
|
||||||
NazaraMutexLock(m_sharedImpl->mutex);
|
stride = ((static_cast<int>(stride)-1)/32+1)*32;
|
||||||
bool freeSharedImpl = (--m_sharedImpl->refCount == 0);
|
#endif
|
||||||
NazaraMutexUnlock(m_sharedImpl->mutex);
|
|
||||||
|
m_sharedImpl = impl;
|
||||||
if (freeSharedImpl)
|
|
||||||
delete m_sharedImpl;
|
NotifyCreated();
|
||||||
|
return true;
|
||||||
m_sharedImpl = nullptr;
|
}
|
||||||
}
|
|
||||||
|
void NzVertexDeclaration::Destroy()
|
||||||
const NzVertexElement* NzVertexDeclaration::GetElement(unsigned int i) const
|
{
|
||||||
{
|
if (!m_sharedImpl)
|
||||||
#if NAZARA_UTILITY_SAFE
|
return;
|
||||||
if (!m_sharedImpl)
|
|
||||||
{
|
NotifyDestroy();
|
||||||
NazaraError("Declaration not created");
|
|
||||||
return nullptr;
|
NazaraMutexLock(m_sharedImpl->mutex);
|
||||||
}
|
bool freeSharedImpl = (--m_sharedImpl->refCount == 0);
|
||||||
|
NazaraMutexUnlock(m_sharedImpl->mutex);
|
||||||
if (i >= m_sharedImpl->elements.size())
|
|
||||||
{
|
if (freeSharedImpl)
|
||||||
NazaraError("Element index out of range (" + NzString::Number(i) + " >= " + NzString::Number(m_sharedImpl->elements.size()) + ')');
|
delete m_sharedImpl;
|
||||||
return nullptr;
|
|
||||||
}
|
m_sharedImpl = nullptr;
|
||||||
#endif
|
}
|
||||||
|
|
||||||
return &m_sharedImpl->elements[i];
|
const NzVertexElement* NzVertexDeclaration::GetElement(unsigned int i) const
|
||||||
}
|
{
|
||||||
|
#if NAZARA_UTILITY_SAFE
|
||||||
const NzVertexElement* NzVertexDeclaration::GetElement(nzElementStream stream, unsigned int i) const
|
if (!m_sharedImpl)
|
||||||
{
|
{
|
||||||
#if NAZARA_UTILITY_SAFE
|
NazaraError("Declaration not created");
|
||||||
if (!m_sharedImpl)
|
return nullptr;
|
||||||
{
|
}
|
||||||
NazaraError("Declaration not created");
|
|
||||||
return nullptr;
|
if (i >= m_sharedImpl->elements.size())
|
||||||
}
|
{
|
||||||
|
NazaraError("Element index out of range (" + NzString::Number(i) + " >= " + NzString::Number(m_sharedImpl->elements.size()) + ')');
|
||||||
int streamPos = m_sharedImpl->streamPos[stream];
|
return nullptr;
|
||||||
if (streamPos == -1)
|
}
|
||||||
{
|
#endif
|
||||||
NazaraError("Declaration has no stream 0x" + NzString::Number(stream, 16));
|
|
||||||
return nullptr;
|
return &m_sharedImpl->elements[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int upperLimit = GetElementCount(stream);
|
const NzVertexElement* NzVertexDeclaration::GetElement(nzElementStream stream, unsigned int i) const
|
||||||
if (i >= upperLimit)
|
{
|
||||||
{
|
#if NAZARA_UTILITY_SAFE
|
||||||
NazaraError("Element index out of range (" + NzString::Number(i) + " >= " + NzString::Number(upperLimit) + ')');
|
if (!m_sharedImpl)
|
||||||
return nullptr;
|
{
|
||||||
}
|
NazaraError("Declaration not created");
|
||||||
#endif
|
return nullptr;
|
||||||
|
}
|
||||||
return &m_sharedImpl->elements[m_sharedImpl->streamPos[stream]+i];
|
|
||||||
}
|
int streamPos = m_sharedImpl->streamPos[stream];
|
||||||
|
if (streamPos == -1)
|
||||||
const NzVertexElement* NzVertexDeclaration::GetElement(nzElementStream stream, nzElementUsage usage, unsigned int usageIndex) const
|
{
|
||||||
{
|
NazaraError("Declaration has no stream 0x" + NzString::Number(stream, 16));
|
||||||
#if NAZARA_UTILITY_SAFE
|
return nullptr;
|
||||||
if (!m_sharedImpl)
|
}
|
||||||
{
|
|
||||||
NazaraError("Declaration not created");
|
unsigned int upperLimit = GetElementCount(stream);
|
||||||
return nullptr;
|
if (i >= upperLimit)
|
||||||
}
|
{
|
||||||
#endif
|
NazaraError("Element index out of range (" + NzString::Number(i) + " >= " + NzString::Number(upperLimit) + ')');
|
||||||
|
return nullptr;
|
||||||
int elementPos = m_sharedImpl->elementPos[stream][usage];
|
}
|
||||||
if (elementPos == -1)
|
#endif
|
||||||
return nullptr;
|
|
||||||
|
return &m_sharedImpl->elements[m_sharedImpl->streamPos[stream]+i];
|
||||||
elementPos += usageIndex;
|
}
|
||||||
if (static_cast<unsigned int>(elementPos) >= m_sharedImpl->elements.size())
|
|
||||||
return nullptr;
|
const NzVertexElement* NzVertexDeclaration::GetElement(nzElementStream stream, nzElementUsage usage, unsigned int usageIndex) const
|
||||||
|
{
|
||||||
NzVertexElement& element = m_sharedImpl->elements[elementPos];
|
#if NAZARA_UTILITY_SAFE
|
||||||
if (element.stream != stream || element.usage != usage || element.usageIndex != usageIndex)
|
if (!m_sharedImpl)
|
||||||
return nullptr;
|
{
|
||||||
|
NazaraError("Declaration not created");
|
||||||
return &element;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
unsigned int NzVertexDeclaration::GetElementCount() const
|
|
||||||
{
|
int elementPos = m_sharedImpl->elementPos[stream][usage];
|
||||||
#if NAZARA_UTILITY_SAFE
|
if (elementPos == -1)
|
||||||
if (!m_sharedImpl)
|
return nullptr;
|
||||||
{
|
|
||||||
NazaraError("Declaration not created");
|
elementPos += usageIndex;
|
||||||
return 0;
|
if (static_cast<unsigned int>(elementPos) >= m_sharedImpl->elements.size())
|
||||||
}
|
return nullptr;
|
||||||
#endif
|
|
||||||
|
NzVertexElement& element = m_sharedImpl->elements[elementPos];
|
||||||
return m_sharedImpl->elements.size();
|
if (element.stream != stream || element.usage != usage || element.usageIndex != usageIndex)
|
||||||
}
|
return nullptr;
|
||||||
|
|
||||||
unsigned int NzVertexDeclaration::GetElementCount(nzElementStream stream) const
|
return &element;
|
||||||
{
|
}
|
||||||
#if NAZARA_UTILITY_SAFE
|
|
||||||
if (!m_sharedImpl)
|
unsigned int NzVertexDeclaration::GetElementCount() const
|
||||||
{
|
{
|
||||||
NazaraError("Declaration not created");
|
#if NAZARA_UTILITY_SAFE
|
||||||
return 0;
|
if (!m_sharedImpl)
|
||||||
}
|
{
|
||||||
#endif
|
NazaraError("Declaration not created");
|
||||||
|
return 0;
|
||||||
int streamPos = m_sharedImpl->streamPos[stream];
|
}
|
||||||
if (streamPos == -1)
|
#endif
|
||||||
return 0;
|
|
||||||
|
return m_sharedImpl->elements.size();
|
||||||
unsigned int upperLimit = 0;
|
}
|
||||||
if (stream == nzElementStream_Max)
|
|
||||||
upperLimit = m_sharedImpl->elements.size();
|
unsigned int NzVertexDeclaration::GetElementCount(nzElementStream stream) const
|
||||||
else
|
{
|
||||||
{
|
#if NAZARA_UTILITY_SAFE
|
||||||
for (unsigned int upperStream = stream+1; upperStream <= nzElementStream_Max; ++upperStream)
|
if (!m_sharedImpl)
|
||||||
{
|
{
|
||||||
if (m_sharedImpl->streamPos[upperStream] != -1)
|
NazaraError("Declaration not created");
|
||||||
{
|
return 0;
|
||||||
upperLimit = m_sharedImpl->streamPos[upperStream];
|
}
|
||||||
break;
|
#endif
|
||||||
}
|
|
||||||
else if (upperStream == nzElementStream_Max) // Dernier stream, toujours pas de limite
|
int streamPos = m_sharedImpl->streamPos[stream];
|
||||||
upperLimit = m_sharedImpl->elements.size();
|
if (streamPos == -1)
|
||||||
}
|
return 0;
|
||||||
}
|
|
||||||
|
unsigned int upperLimit = 0;
|
||||||
return upperLimit-streamPos;
|
if (stream == nzElementStream_Max)
|
||||||
}
|
upperLimit = m_sharedImpl->elements.size();
|
||||||
|
else
|
||||||
unsigned int NzVertexDeclaration::GetStride(nzElementStream stream) const
|
{
|
||||||
{
|
for (unsigned int upperStream = stream+1; upperStream <= nzElementStream_Max; ++upperStream)
|
||||||
#if NAZARA_UTILITY_SAFE
|
{
|
||||||
if (!m_sharedImpl)
|
if (m_sharedImpl->streamPos[upperStream] != -1)
|
||||||
{
|
{
|
||||||
NazaraError("Declaration not created");
|
upperLimit = m_sharedImpl->streamPos[upperStream];
|
||||||
return 0;
|
break;
|
||||||
}
|
}
|
||||||
#endif
|
else if (upperStream == nzElementStream_Max) // Dernier stream, toujours pas de limite
|
||||||
|
upperLimit = m_sharedImpl->elements.size();
|
||||||
return m_sharedImpl->stride[stream];
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NzVertexDeclaration::HasStream(nzElementStream stream) const
|
return upperLimit-streamPos;
|
||||||
{
|
}
|
||||||
#if NAZARA_UTILITY_SAFE
|
|
||||||
if (!m_sharedImpl)
|
unsigned int NzVertexDeclaration::GetStride(nzElementStream stream) const
|
||||||
{
|
{
|
||||||
NazaraError("Declaration not created");
|
#if NAZARA_UTILITY_SAFE
|
||||||
return false;
|
if (!m_sharedImpl)
|
||||||
}
|
{
|
||||||
#endif
|
NazaraError("Declaration not created");
|
||||||
|
return 0;
|
||||||
return m_sharedImpl->streamPos[stream] != -1;
|
}
|
||||||
}
|
#endif
|
||||||
|
|
||||||
bool NzVertexDeclaration::IsValid() const
|
return m_sharedImpl->stride[stream];
|
||||||
{
|
}
|
||||||
return m_sharedImpl != nullptr;
|
|
||||||
}
|
bool NzVertexDeclaration::HasStream(nzElementStream stream) const
|
||||||
|
{
|
||||||
NzVertexDeclaration& NzVertexDeclaration::operator=(const NzVertexDeclaration& declaration)
|
#if NAZARA_UTILITY_SAFE
|
||||||
{
|
if (!m_sharedImpl)
|
||||||
Destroy();
|
{
|
||||||
|
NazaraError("Declaration not created");
|
||||||
m_sharedImpl = declaration.m_sharedImpl;
|
return false;
|
||||||
if (m_sharedImpl)
|
}
|
||||||
{
|
#endif
|
||||||
NazaraMutexLock(m_sharedImpl->mutex);
|
|
||||||
m_sharedImpl->refCount++;
|
return m_sharedImpl->streamPos[stream] != -1;
|
||||||
NazaraMutexUnlock(m_sharedImpl->mutex);
|
}
|
||||||
}
|
|
||||||
|
bool NzVertexDeclaration::IsValid() const
|
||||||
return *this;
|
{
|
||||||
}
|
return m_sharedImpl != nullptr;
|
||||||
|
}
|
||||||
NzVertexDeclaration& NzVertexDeclaration::operator=(NzVertexDeclaration&& declaration) noexcept
|
|
||||||
{
|
NzVertexDeclaration& NzVertexDeclaration::operator=(const NzVertexDeclaration& declaration)
|
||||||
Destroy();
|
{
|
||||||
|
Destroy();
|
||||||
m_sharedImpl = declaration.m_sharedImpl;
|
|
||||||
declaration.m_sharedImpl = nullptr;
|
m_sharedImpl = declaration.m_sharedImpl;
|
||||||
|
if (m_sharedImpl)
|
||||||
return *this;
|
{
|
||||||
}
|
NazaraMutexLock(m_sharedImpl->mutex);
|
||||||
|
m_sharedImpl->refCount++;
|
||||||
|
NazaraMutexUnlock(m_sharedImpl->mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
NzVertexDeclaration& NzVertexDeclaration::operator=(NzVertexDeclaration&& declaration) noexcept
|
||||||
|
{
|
||||||
|
Destroy();
|
||||||
|
|
||||||
|
m_sharedImpl = declaration.m_sharedImpl;
|
||||||
|
declaration.m_sharedImpl = nullptr;
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int NzVertexDeclaration::GetElementCount(nzElementType type)
|
||||||
|
{
|
||||||
|
return elementCount[type];
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int NzVertexDeclaration::GetElementSize(nzElementType type)
|
||||||
|
{
|
||||||
|
return elementSize[type];
|
||||||
|
}
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue