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
|
||||
project "NazaraRenderer"
|
||||
end
|
||||
|
||||
files
|
||||
{
|
||||
"../include/Nazara/Renderer/**.hpp",
|
||||
"../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"
|
||||
links "opengl32"
|
||||
links "winmm"
|
||||
else
|
||||
excludes { "../src/Nazara/Renderer/Win32/*.hpp", "../src/Nazara/Renderer/Win32/*.cpp" }
|
||||
end
|
||||
|
||||
if (_OPTIONS["one-library"]) then
|
||||
excludes "../src/Nazara/Renderer/Debug/Leaks.cpp"
|
||||
else
|
||||
configuration "DebugStatic"
|
||||
links "NazaraCore-s-d"
|
||||
links "NazaraUtility-s-d"
|
||||
|
||||
configuration "ReleaseStatic"
|
||||
links "NazaraCore-s"
|
||||
links "NazaraUtility-s"
|
||||
|
||||
configuration "DebugDLL"
|
||||
links "NazaraCore-d"
|
||||
links "NazaraUtility-d"
|
||||
|
||||
configuration "ReleaseDLL"
|
||||
links "NazaraCore"
|
||||
links "NazaraUtility"
|
||||
if (not _OPTIONS["one-library"]) then
|
||||
project "NazaraRenderer"
|
||||
end
|
||||
|
||||
defines "NAZARA_RENDERER_OPENGL"
|
||||
|
||||
files
|
||||
{
|
||||
"../include/Nazara/Renderer/**.hpp",
|
||||
"../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"
|
||||
links "opengl32"
|
||||
links "winmm"
|
||||
else
|
||||
excludes { "../src/Nazara/Renderer/Win32/*.hpp", "../src/Nazara/Renderer/Win32/*.cpp" }
|
||||
end
|
||||
|
||||
if (_OPTIONS["one-library"]) then
|
||||
excludes "../src/Nazara/Renderer/Debug/Leaks.cpp"
|
||||
else
|
||||
configuration "DebugStatic"
|
||||
links "NazaraCore-s-d"
|
||||
links "NazaraUtility-s-d"
|
||||
|
||||
configuration "ReleaseStatic"
|
||||
links "NazaraCore-s"
|
||||
links "NazaraUtility-s"
|
||||
|
||||
configuration "DebugDLL"
|
||||
links "NazaraCore-d"
|
||||
links "NazaraUtility-d"
|
||||
|
||||
configuration "ReleaseDLL"
|
||||
links "NazaraCore"
|
||||
links "NazaraUtility"
|
||||
end
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -1,61 +1,62 @@
|
|||
// This file was automatically generated by Nazara
|
||||
|
||||
/*
|
||||
Nazara Engine - Core module
|
||||
|
||||
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
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
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
|
||||
so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
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
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <Nazara/Core/ByteArray.hpp>
|
||||
#include <Nazara/Core/Clock.hpp>
|
||||
#include <Nazara/Core/Color.hpp>
|
||||
#include <Nazara/Core/ConditionVariable.hpp>
|
||||
#include <Nazara/Core/Config.hpp>
|
||||
#include <Nazara/Core/Core.hpp>
|
||||
#include <Nazara/Core/Directory.hpp>
|
||||
#include <Nazara/Core/DynLib.hpp>
|
||||
#include <Nazara/Core/Endianness.hpp>
|
||||
#include <Nazara/Core/Enums.hpp>
|
||||
#include <Nazara/Core/Error.hpp>
|
||||
#include <Nazara/Core/File.hpp>
|
||||
#include <Nazara/Core/Format.hpp>
|
||||
#include <Nazara/Core/Functor.hpp>
|
||||
#include <Nazara/Core/Hash.hpp>
|
||||
#include <Nazara/Core/Hashable.hpp>
|
||||
#include <Nazara/Core/HashDigest.hpp>
|
||||
#include <Nazara/Core/HashImpl.hpp>
|
||||
#include <Nazara/Core/Initializer.hpp>
|
||||
#include <Nazara/Core/InputStream.hpp>
|
||||
#include <Nazara/Core/LockGuard.hpp>
|
||||
#include <Nazara/Core/Log.hpp>
|
||||
#include <Nazara/Core/MemoryStream.hpp>
|
||||
#include <Nazara/Core/Mutex.hpp>
|
||||
#include <Nazara/Core/NonCopyable.hpp>
|
||||
#include <Nazara/Core/Resource.hpp>
|
||||
#include <Nazara/Core/ResourceLoader.hpp>
|
||||
#include <Nazara/Core/Semaphore.hpp>
|
||||
#include <Nazara/Core/String.hpp>
|
||||
#include <Nazara/Core/StringStream.hpp>
|
||||
#include <Nazara/Core/Thread.hpp>
|
||||
#include <Nazara/Core/Tuple.hpp>
|
||||
#include <Nazara/Core/Unicode.hpp>
|
||||
// This file was automatically generated by Nazara
|
||||
|
||||
/*
|
||||
Nazara Engine - Core module
|
||||
|
||||
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
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
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
|
||||
so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
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
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <Nazara/Core/ByteArray.hpp>
|
||||
#include <Nazara/Core/Clock.hpp>
|
||||
#include <Nazara/Core/Color.hpp>
|
||||
#include <Nazara/Core/ConditionVariable.hpp>
|
||||
#include <Nazara/Core/Config.hpp>
|
||||
#include <Nazara/Core/Core.hpp>
|
||||
#include <Nazara/Core/Directory.hpp>
|
||||
#include <Nazara/Core/DynLib.hpp>
|
||||
#include <Nazara/Core/Endianness.hpp>
|
||||
#include <Nazara/Core/Enums.hpp>
|
||||
#include <Nazara/Core/Error.hpp>
|
||||
#include <Nazara/Core/File.hpp>
|
||||
#include <Nazara/Core/Format.hpp>
|
||||
#include <Nazara/Core/Functor.hpp>
|
||||
#include <Nazara/Core/Hash.hpp>
|
||||
#include <Nazara/Core/Hashable.hpp>
|
||||
#include <Nazara/Core/HashDigest.hpp>
|
||||
#include <Nazara/Core/HashImpl.hpp>
|
||||
#include <Nazara/Core/Initializer.hpp>
|
||||
#include <Nazara/Core/InputStream.hpp>
|
||||
#include <Nazara/Core/LockGuard.hpp>
|
||||
#include <Nazara/Core/Log.hpp>
|
||||
#include <Nazara/Core/MemoryStream.hpp>
|
||||
#include <Nazara/Core/Mutex.hpp>
|
||||
#include <Nazara/Core/NonCopyable.hpp>
|
||||
#include <Nazara/Core/Resource.hpp>
|
||||
#include <Nazara/Core/ResourceListener.hpp>
|
||||
#include <Nazara/Core/ResourceLoader.hpp>
|
||||
#include <Nazara/Core/Semaphore.hpp>
|
||||
#include <Nazara/Core/String.hpp>
|
||||
#include <Nazara/Core/StringStream.hpp>
|
||||
#include <Nazara/Core/Thread.hpp>
|
||||
#include <Nazara/Core/Tuple.hpp>
|
||||
#include <Nazara/Core/Unicode.hpp>
|
||||
|
|
|
|||
|
|
@ -1,84 +1,85 @@
|
|||
/*
|
||||
Nazara Engine - Core module
|
||||
|
||||
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
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
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
|
||||
so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
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
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef NAZARA_CONFIG_CORE_HPP
|
||||
#define NAZARA_CONFIG_CORE_HPP
|
||||
|
||||
/// Chaque modification d'un paramètre du module nécessite une recompilation de celui-ci
|
||||
|
||||
// Appelle exit dès qu'une assertion est invalide
|
||||
#define NAZARA_CORE_EXIT_ON_ASSERT_FAILURE 1
|
||||
|
||||
// Teste les assertions
|
||||
#define NAZARA_CORE_ENABLE_ASSERTS 0
|
||||
|
||||
// Taille du buffer lors d'une lecture complète d'un fichier (ex: Hash)
|
||||
#define NAZARA_CORE_FILE_BUFFERSIZE 4096
|
||||
|
||||
// Le moteur doit-il incorporer les Unicode Character Data (Nécessaires pour faire fonctionner le flag NzString::HandleUTF8)
|
||||
#define NAZARA_CORE_INCLUDE_UNICODEDATA 0
|
||||
|
||||
// Utilise un tracker pour repérer les éventuels leaks (Ralentit l'exécution)
|
||||
#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)
|
||||
#define NAZARA_CORE_NORMALIZE_DIRECTORY_SEPARATORS 1
|
||||
|
||||
// Précision des réels lors de la transformation en texte (Max. chiffres après la virgule)
|
||||
#define NAZARA_CORE_REAL_PRECISION 6
|
||||
|
||||
// Duplique la sortie du log sur le flux de sortie standard (cout)
|
||||
#define NAZARA_CORE_DUPLICATE_TO_COUT 0
|
||||
|
||||
// Active les tests de sécurité basés sur le code (Conseillé pour le développement)
|
||||
#define NAZARA_CORE_SAFE 1
|
||||
|
||||
// Protège les classes des accès concurrentiels
|
||||
#define NAZARA_CORE_THREADSAFE 1
|
||||
|
||||
// Les classes à protéger des accès concurrentiels
|
||||
#define NAZARA_THREADSAFETY_BYTEARRAY 1 // NzByteArray (COW)
|
||||
#define NAZARA_THREADSAFETY_CLOCK 0 // NzClock
|
||||
#define NAZARA_THREADSAFETY_DIRECTORY 1 // NzDirectory
|
||||
#define NAZARA_THREADSAFETY_DYNLIB 1 // NzDynLib
|
||||
#define NAZARA_THREADSAFETY_FILE 1 // NzFile
|
||||
#define NAZARA_THREADSAFETY_HASHDIGEST 0 // NzHashDigest
|
||||
#define NAZARA_THREADSAFETY_LOG 1 // NzLog
|
||||
#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
|
||||
|
||||
// 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
|
||||
*/
|
||||
|
||||
#endif // NAZARA_CONFIG_CORE_HPP
|
||||
/*
|
||||
Nazara Engine - Core module
|
||||
|
||||
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
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
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
|
||||
so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
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
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef NAZARA_CONFIG_CORE_HPP
|
||||
#define NAZARA_CONFIG_CORE_HPP
|
||||
|
||||
/// Chaque modification d'un paramètre du module nécessite une recompilation de celui-ci
|
||||
|
||||
// Appelle exit dès qu'une assertion est invalide
|
||||
#define NAZARA_CORE_EXIT_ON_ASSERT_FAILURE 1
|
||||
|
||||
// Teste les assertions
|
||||
#define NAZARA_CORE_ENABLE_ASSERTS 0
|
||||
|
||||
// Taille du buffer lors d'une lecture complète d'un fichier (ex: Hash)
|
||||
#define NAZARA_CORE_FILE_BUFFERSIZE 4096
|
||||
|
||||
// Le moteur doit-il incorporer les Unicode Character Data (Nécessaires pour faire fonctionner le flag NzString::HandleUTF8)
|
||||
#define NAZARA_CORE_INCLUDE_UNICODEDATA 0
|
||||
|
||||
// Utilise un tracker pour repérer les éventuels leaks (Ralentit l'exécution)
|
||||
#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)
|
||||
#define NAZARA_CORE_NORMALIZE_DIRECTORY_SEPARATORS 1
|
||||
|
||||
// Précision des réels lors de la transformation en texte (Max. chiffres après la virgule)
|
||||
#define NAZARA_CORE_REAL_PRECISION 6
|
||||
|
||||
// Duplique la sortie du log sur le flux de sortie standard (cout)
|
||||
#define NAZARA_CORE_DUPLICATE_TO_COUT 0
|
||||
|
||||
// Active les tests de sécurité basés sur le code (Conseillé pour le développement)
|
||||
#define NAZARA_CORE_SAFE 1
|
||||
|
||||
// Protège les classes des accès concurrentiels
|
||||
#define NAZARA_CORE_THREADSAFE 1
|
||||
|
||||
// Les classes à protéger des accès concurrentiels
|
||||
#define NAZARA_THREADSAFETY_BYTEARRAY 1 // NzByteArray (COW)
|
||||
#define NAZARA_THREADSAFETY_CLOCK 0 // NzClock
|
||||
#define NAZARA_THREADSAFETY_DIRECTORY 1 // NzDirectory
|
||||
#define NAZARA_THREADSAFETY_DYNLIB 1 // NzDynLib
|
||||
#define NAZARA_THREADSAFETY_FILE 1 // NzFile
|
||||
#define NAZARA_THREADSAFETY_HASHDIGEST 0 // NzHashDigest
|
||||
#define NAZARA_THREADSAFETY_LOG 1 // NzLog
|
||||
#define NAZARA_THREADSAFETY_RESOURCE 1 // NzResource
|
||||
#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
|
||||
|
||||
// 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
|
||||
*/
|
||||
|
||||
#endif // NAZARA_CONFIG_CORE_HPP
|
||||
|
|
|
|||
|
|
@ -1,26 +1,30 @@
|
|||
// 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_ENUMS_CORE_HPP
|
||||
#define NAZARA_ENUMS_CORE_HPP
|
||||
|
||||
enum nzEndianness
|
||||
{
|
||||
nzEndianness_Unknown = -1,
|
||||
|
||||
nzEndianness_BigEndian,
|
||||
nzEndianness_LittleEndian
|
||||
};
|
||||
|
||||
enum nzErrorType
|
||||
{
|
||||
nzErrorType_AssertFailed,
|
||||
nzErrorType_Internal,
|
||||
nzErrorType_Normal,
|
||||
nzErrorType_Warning
|
||||
};
|
||||
|
||||
#endif // NAZARA_ENUMS_CORE_HPP
|
||||
// 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_ENUMS_CORE_HPP
|
||||
#define NAZARA_ENUMS_CORE_HPP
|
||||
|
||||
enum nzEndianness
|
||||
{
|
||||
nzEndianness_Unknown = -1,
|
||||
|
||||
nzEndianness_BigEndian,
|
||||
nzEndianness_LittleEndian,
|
||||
|
||||
nzEndianness_Max = nzEndianness_LittleEndian
|
||||
};
|
||||
|
||||
enum nzErrorType
|
||||
{
|
||||
nzErrorType_AssertFailed,
|
||||
nzErrorType_Internal,
|
||||
nzErrorType_Normal,
|
||||
nzErrorType_Warning,
|
||||
|
||||
nzErrorType_Max = nzErrorType_Warning
|
||||
};
|
||||
|
||||
#endif // NAZARA_ENUMS_CORE_HPP
|
||||
|
|
|
|||
|
|
@ -1,30 +1,72 @@
|
|||
// 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_RESOURCE_HPP
|
||||
#define NAZARA_RESOURCE_HPP
|
||||
|
||||
#include <Nazara/Prerequesites.hpp>
|
||||
|
||||
class NAZARA_API NzResource
|
||||
{
|
||||
public:
|
||||
NzResource(bool persistent = true);
|
||||
NzResource(const NzResource& resource);
|
||||
virtual ~NzResource();
|
||||
|
||||
void AddResourceReference() const;
|
||||
bool IsPersistent() const;
|
||||
void RemoveResourceReference() const;
|
||||
void SetPersistent(bool persistent = true);
|
||||
|
||||
private:
|
||||
// Je fais précéder le nom par 'resource' pour éviter les éventuels conflits de noms
|
||||
mutable bool m_resourcePersistent;
|
||||
mutable unsigned int m_resourceReferenceCount;
|
||||
};
|
||||
|
||||
#endif // NAZARA_RESOURCE_HPP
|
||||
// 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_RESOURCE_HPP
|
||||
#define NAZARA_RESOURCE_HPP
|
||||
|
||||
#include <Nazara/Prerequesites.hpp>
|
||||
#include <set>
|
||||
|
||||
#if NAZARA_CORE_THREADSAFE && NAZARA_THREADSAFETY_RESOURCE
|
||||
#include <Nazara/Core/ThreadSafety.hpp>
|
||||
#else
|
||||
#include <Nazara/Core/ThreadSafetyOff.hpp>
|
||||
#endif
|
||||
|
||||
class NzResourceListener;
|
||||
|
||||
struct NzResourceEntry
|
||||
{
|
||||
NzResourceEntry(NzResourceListener* resourceListener, int i = 0) :
|
||||
listener(resourceListener),
|
||||
index(i)
|
||||
{
|
||||
}
|
||||
|
||||
bool operator<(const NzResourceEntry& rhs) const
|
||||
{
|
||||
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
|
||||
// This file is part of the "Nazara Engine - Utility module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#include <Nazara/Core/Config.hpp>
|
||||
#include <Nazara/Core/Error.hpp>
|
||||
#include <Nazara/Core/File.hpp>
|
||||
#include <Nazara/Core/InputStream.hpp>
|
||||
#include <Nazara/Core/MemoryStream.hpp>
|
||||
#include <Nazara/Core/Debug.hpp>
|
||||
|
||||
template<typename Type, typename Parameters>
|
||||
bool NzResourceLoader<Type, Parameters>::LoadFromFile(Type* resource, const NzString& filePath, const Parameters& parameters)
|
||||
{
|
||||
#if NAZARA_CORE_SAFE
|
||||
if (!parameters.IsValid())
|
||||
{
|
||||
NazaraError("Invalid Parameters");
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
NzString path = NzFile::NormalizePath(filePath);
|
||||
NzString ext = path.SubstrFrom('.', -1, true);
|
||||
if (ext.IsEmpty())
|
||||
{
|
||||
NazaraError("Failed to get file extension");
|
||||
return false;
|
||||
}
|
||||
|
||||
NzFile file(path, NzFile::ReadOnly);
|
||||
if (!file.IsOpen())
|
||||
{
|
||||
NazaraError("Failed to open file");
|
||||
return false;
|
||||
}
|
||||
|
||||
for (auto loader = Type::s_loaders.begin(); loader != Type::s_loaders.end(); ++loader)
|
||||
{
|
||||
for (const NzString& loaderExt : std::get<0>(*loader))
|
||||
{
|
||||
int cmp = NzString::Compare(loaderExt, ext);
|
||||
if (cmp == 0)
|
||||
{
|
||||
if (!std::get<1>(*loader)(file, parameters))
|
||||
continue;
|
||||
|
||||
file.SetCursorPos(0);
|
||||
|
||||
// Chargement de la ressource
|
||||
if (std::get<2>(*loader)(resource, file, parameters))
|
||||
return true;
|
||||
|
||||
NazaraWarning("Loader failed");
|
||||
|
||||
file.SetCursorPos(0);
|
||||
}
|
||||
else if (cmp < 0) // S'il est encore possible que l'extension se situe après
|
||||
continue;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
NazaraError("Failed to load file: no loader");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
template<typename Type, typename Parameters>
|
||||
bool NzResourceLoader<Type, Parameters>::LoadFromMemory(Type* resource, const void* data, unsigned int size, const Parameters& parameters)
|
||||
{
|
||||
NzMemoryStream stream(data, size);
|
||||
|
||||
return LoadFromStream(resource, stream, parameters);
|
||||
}
|
||||
|
||||
template<typename Type, typename Parameters>
|
||||
bool NzResourceLoader<Type, Parameters>::LoadFromStream(Type* resource, NzInputStream& stream, const Parameters& parameters)
|
||||
{
|
||||
#if NAZARA_CORE_SAFE
|
||||
if (!parameters.IsValid())
|
||||
{
|
||||
NazaraError("Invalid Parameters");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (stream.GetSize() == 0 || stream.GetCursorPos() >= stream.GetSize())
|
||||
{
|
||||
NazaraError("No data to load");
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
nzUInt64 streamPos = stream.GetCursorPos();
|
||||
for (auto loader = Type::s_loaders.begin(); loader != Type::s_loaders.end(); ++loader)
|
||||
{
|
||||
// Le loader supporte-t-il les données ?
|
||||
if (!std::get<1>(*loader)(stream, parameters))
|
||||
continue;
|
||||
|
||||
// On repositionne le stream au début
|
||||
stream.SetCursorPos(streamPos);
|
||||
|
||||
// Chargement de la ressource
|
||||
if (std::get<2>(*loader)(resource, stream, parameters))
|
||||
return true;
|
||||
|
||||
NazaraWarning("Loader failed");
|
||||
stream.SetCursorPos(streamPos); // On repositionne au début
|
||||
}
|
||||
|
||||
NazaraError("Failed to load file: no loader");
|
||||
return false;
|
||||
}
|
||||
|
||||
template<typename Type, typename Parameters>
|
||||
void NzResourceLoader<Type, Parameters>::RegisterLoader(const NzString& fileExtensions, CheckFunction checkFunc, LoadFunction loadFunc)
|
||||
{
|
||||
/// Trouver une alternative à ce code monstrueux
|
||||
std::vector<NzString> exts;
|
||||
fileExtensions.SplitAny(exts, " /\\.,;|-_");
|
||||
|
||||
std::set<NzString> extensions;
|
||||
std::copy(exts.begin(), exts.end(), std::inserter(extensions, extensions.begin()));
|
||||
|
||||
Type::s_loaders.insert(std::make_tuple(std::move(extensions), checkFunc, loadFunc));
|
||||
}
|
||||
|
||||
template<typename Type, typename Parameters>
|
||||
void NzResourceLoader<Type, Parameters>::UnregisterLoader(const NzString& fileExtensions, CheckFunction checkFunc, LoadFunction loadFunc)
|
||||
{
|
||||
std::vector<NzString> exts;
|
||||
fileExtensions.SplitAny(exts, " /\\.,;|-_");
|
||||
|
||||
std::set<NzString> extensions;
|
||||
std::copy(exts.begin(), exts.end(), std::inserter(extensions, extensions.begin()));
|
||||
|
||||
Type::s_loaders.erase(std::make_tuple(std::move(extensions), checkFunc, loadFunc));
|
||||
}
|
||||
|
||||
#include <Nazara/Core/DebugOff.hpp>
|
||||
// Copyright (C) 2012 Jérôme Leclercq
|
||||
// This file is part of the "Nazara Engine - Utility module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#include <Nazara/Core/Config.hpp>
|
||||
#include <Nazara/Core/Error.hpp>
|
||||
#include <Nazara/Core/File.hpp>
|
||||
#include <Nazara/Core/InputStream.hpp>
|
||||
#include <Nazara/Core/MemoryStream.hpp>
|
||||
#include <Nazara/Core/Debug.hpp>
|
||||
|
||||
template<typename Type, typename Parameters>
|
||||
bool NzResourceLoader<Type, Parameters>::LoadFromFile(Type* resource, const NzString& filePath, const Parameters& parameters)
|
||||
{
|
||||
#if NAZARA_CORE_SAFE
|
||||
if (!parameters.IsValid())
|
||||
{
|
||||
NazaraError("Invalid parameters");
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
NzString path = NzFile::NormalizePath(filePath);
|
||||
NzString ext = path.SubstrFrom('.', -1, true);
|
||||
if (ext.IsEmpty())
|
||||
{
|
||||
NazaraError("Failed to get file extension");
|
||||
return false;
|
||||
}
|
||||
|
||||
NzFile file(path, NzFile::ReadOnly);
|
||||
if (!file.IsOpen())
|
||||
{
|
||||
NazaraError("Failed to open file");
|
||||
return false;
|
||||
}
|
||||
|
||||
for (auto loader = Type::s_loaders.begin(); loader != Type::s_loaders.end(); ++loader)
|
||||
{
|
||||
for (const NzString& loaderExt : std::get<0>(*loader))
|
||||
{
|
||||
int cmp = NzString::Compare(loaderExt, ext);
|
||||
if (cmp == 0)
|
||||
{
|
||||
if (!std::get<1>(*loader)(file, parameters))
|
||||
continue;
|
||||
|
||||
file.SetCursorPos(0);
|
||||
|
||||
// Chargement de la ressource
|
||||
if (std::get<2>(*loader)(resource, file, parameters))
|
||||
return true;
|
||||
|
||||
NazaraWarning("Loader failed");
|
||||
|
||||
file.SetCursorPos(0);
|
||||
}
|
||||
else if (cmp < 0) // S'il est encore possible que l'extension se situe après
|
||||
continue;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
NazaraError("Failed to load file: no loader");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
template<typename Type, typename Parameters>
|
||||
bool NzResourceLoader<Type, Parameters>::LoadFromMemory(Type* resource, const void* data, unsigned int size, const Parameters& parameters)
|
||||
{
|
||||
NzMemoryStream stream(data, size);
|
||||
|
||||
return LoadFromStream(resource, stream, parameters);
|
||||
}
|
||||
|
||||
template<typename Type, typename Parameters>
|
||||
bool NzResourceLoader<Type, Parameters>::LoadFromStream(Type* resource, NzInputStream& stream, const Parameters& parameters)
|
||||
{
|
||||
#if NAZARA_CORE_SAFE
|
||||
if (!parameters.IsValid())
|
||||
{
|
||||
NazaraError("Invalid parameters");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (stream.GetSize() == 0 || stream.GetCursorPos() >= stream.GetSize())
|
||||
{
|
||||
NazaraError("No data to load");
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
nzUInt64 streamPos = stream.GetCursorPos();
|
||||
for (auto loader = Type::s_loaders.begin(); loader != Type::s_loaders.end(); ++loader)
|
||||
{
|
||||
// Le loader supporte-t-il les données ?
|
||||
if (!std::get<1>(*loader)(stream, parameters))
|
||||
continue;
|
||||
|
||||
// On repositionne le stream au début
|
||||
stream.SetCursorPos(streamPos);
|
||||
|
||||
// Chargement de la ressource
|
||||
if (std::get<2>(*loader)(resource, stream, parameters))
|
||||
return true;
|
||||
|
||||
NazaraWarning("Loader failed");
|
||||
stream.SetCursorPos(streamPos); // On repositionne au début
|
||||
}
|
||||
|
||||
NazaraError("Failed to load file: no loader");
|
||||
return false;
|
||||
}
|
||||
|
||||
template<typename Type, typename Parameters>
|
||||
void NzResourceLoader<Type, Parameters>::RegisterLoader(const NzString& fileExtensions, CheckFunction checkFunc, LoadFunction loadFunc)
|
||||
{
|
||||
///FIXME: Trouver une alternative à ce code monstrueux
|
||||
std::vector<NzString> exts;
|
||||
fileExtensions.SplitAny(exts, " /\\.,;|-_");
|
||||
|
||||
std::set<NzString> extensions;
|
||||
std::copy(exts.begin(), exts.end(), std::inserter(extensions, extensions.begin()));
|
||||
|
||||
Type::s_loaders.insert(std::make_tuple(std::move(extensions), checkFunc, loadFunc));
|
||||
}
|
||||
|
||||
template<typename Type, typename Parameters>
|
||||
void NzResourceLoader<Type, Parameters>::UnregisterLoader(const NzString& fileExtensions, CheckFunction checkFunc, LoadFunction loadFunc)
|
||||
{
|
||||
std::vector<NzString> exts;
|
||||
fileExtensions.SplitAny(exts, " /\\.,;|-_");
|
||||
|
||||
std::set<NzString> extensions;
|
||||
std::copy(exts.begin(), exts.end(), std::inserter(extensions, extensions.begin()));
|
||||
|
||||
Type::s_loaders.erase(std::make_tuple(std::move(extensions), checkFunc, loadFunc));
|
||||
}
|
||||
|
||||
#include <Nazara/Core/DebugOff.hpp>
|
||||
|
|
|
|||
|
|
@ -1,321 +1,321 @@
|
|||
// 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_STRING_HPP
|
||||
#define NAZARA_STRING_HPP
|
||||
|
||||
#include <Nazara/Prerequesites.hpp>
|
||||
#include <Nazara/Core/Hashable.hpp>
|
||||
#include <iosfwd>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#if NAZARA_CORE_THREADSAFE && NAZARA_THREADSAFETY_STRING
|
||||
#include <Nazara/Core/ThreadSafety.hpp>
|
||||
#else
|
||||
#include <Nazara/Core/ThreadSafetyOff.hpp>
|
||||
#endif
|
||||
|
||||
class NzAbstractHash;
|
||||
class NzHashDigest;
|
||||
|
||||
class NAZARA_API NzString : public NzHashable
|
||||
{
|
||||
public:
|
||||
enum Flags
|
||||
{
|
||||
None = 0x00, // Mode par défaut
|
||||
CaseInsensitive = 0x01, // Insensible à la casse
|
||||
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
|
||||
TrimOnlyRight = 0x08 // Trim(med), ne coupe que la partie droite de la chaîne
|
||||
};
|
||||
|
||||
struct SharedString;
|
||||
|
||||
NzString();
|
||||
NzString(char character);
|
||||
NzString(const char* string);
|
||||
NzString(const std::string& string);
|
||||
NzString(const NzString& string);
|
||||
NzString(NzString&& string) noexcept;
|
||||
NzString(SharedString* sharedString);
|
||||
~NzString();
|
||||
|
||||
NzString& Append(char character);
|
||||
NzString& Append(const char* string);
|
||||
NzString& Append(const NzString& string);
|
||||
|
||||
void Clear(bool keepBuffer = false);
|
||||
|
||||
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 NzString& string, 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 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 NzString& string, int start = 0, nzUInt32 flags = None) const;
|
||||
|
||||
bool EndsWith(char character, nzUInt32 flags = None) const;
|
||||
bool EndsWith(const char* 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(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 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 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 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 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 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 NzString& string, int start = 0, nzUInt32 flags = None) const;
|
||||
|
||||
char* GetBuffer();
|
||||
unsigned int GetCapacity() const;
|
||||
const char* GetConstBuffer() const;
|
||||
unsigned int GetLength() const;
|
||||
unsigned int GetSize() const;
|
||||
char* GetUtf8Buffer(unsigned int* size = nullptr) const;
|
||||
char16_t* GetUtf16Buffer(unsigned int* size = nullptr) const;
|
||||
char32_t* GetUtf32Buffer(unsigned int* size = nullptr) const;
|
||||
wchar_t* GetWideBuffer(unsigned int* size = nullptr) const;
|
||||
|
||||
NzString GetWord(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, const char* string);
|
||||
NzString& Insert(int pos, const NzString& string);
|
||||
|
||||
bool IsEmpty() const;
|
||||
bool IsNull() const;
|
||||
bool IsNumber(nzUInt8 radix = 10, nzUInt32 flags = CaseInsensitive) const;
|
||||
|
||||
bool Match(const char* pattern) const;
|
||||
bool Match(const NzString& pattern) const;
|
||||
|
||||
NzString& Prepend(char character);
|
||||
NzString& Prepend(const char* string);
|
||||
NzString& Prepend(const NzString& string);
|
||||
|
||||
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 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, const char* 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);
|
||||
|
||||
NzString& Resize(int size, char character = ' ');
|
||||
NzString Resized(int size, char character = ' ') const;
|
||||
|
||||
NzString& Reverse();
|
||||
NzString Reversed() const;
|
||||
|
||||
NzString Simplified(nzUInt32 flags = None) const;
|
||||
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, 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 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;
|
||||
|
||||
bool StartsWith(char character, nzUInt32 flags = None) const;
|
||||
bool StartsWith(const char* string, nzUInt32 flags = None) const;
|
||||
bool StartsWith(const NzString& string, nzUInt32 flags = None) 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(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 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 NzString& string, int startPos = 0, bool toLast = false, bool include = false, nzUInt32 flags = None) const;
|
||||
|
||||
void Swap(NzString& str);
|
||||
|
||||
bool ToBool(bool* value, nzUInt32 flags = None) const;
|
||||
bool ToDouble(double* value) const;
|
||||
bool ToInteger(long long* value, nzUInt8 radix = 10) const;
|
||||
NzString ToLower(nzUInt32 flags = None) const;
|
||||
NzString ToUpper(nzUInt32 flags = None) const;
|
||||
|
||||
NzString& Trim(nzUInt32 flags = None);
|
||||
NzString& Trim(char character, nzUInt32 flags = None);
|
||||
NzString Trimmed(nzUInt32 flags = None) const;
|
||||
NzString Trimmed(char character, nzUInt32 flags = None) const;
|
||||
|
||||
// Méthodes STD
|
||||
char* begin();
|
||||
const char* begin() const;
|
||||
char* end();
|
||||
const char* end() const;
|
||||
void push_front(char c);
|
||||
void push_back(char c);
|
||||
/*char* rbegin();
|
||||
const char* rbegin() const;
|
||||
char* rend();
|
||||
const char* rend() const;*/
|
||||
|
||||
typedef const char& const_reference;
|
||||
typedef char* iterator;
|
||||
//typedef char* reverse_iterator;
|
||||
typedef char value_type;
|
||||
// Méthodes STD
|
||||
|
||||
operator std::string() const;
|
||||
|
||||
char& operator[](unsigned int pos);
|
||||
char operator[](unsigned int pos) const;
|
||||
|
||||
NzString& operator=(char character);
|
||||
NzString& operator=(const char* string);
|
||||
NzString& operator=(const std::string& string);
|
||||
NzString& operator=(const NzString& string);
|
||||
NzString& operator=(NzString&& string) noexcept;
|
||||
|
||||
NzString operator+(char character) const;
|
||||
NzString operator+(const char* string) const;
|
||||
NzString operator+(const std::string& string) const;
|
||||
NzString operator+(const NzString& string) const;
|
||||
|
||||
NzString& operator+=(char character);
|
||||
NzString& operator+=(const char* string);
|
||||
NzString& operator+=(const std::string& string);
|
||||
NzString& operator+=(const NzString& string);
|
||||
|
||||
bool operator==(char character) const;
|
||||
bool operator==(const char* string) const;
|
||||
bool operator==(const std::string& string) const;
|
||||
|
||||
bool operator!=(char character) const;
|
||||
bool operator!=(const char* string) const;
|
||||
bool operator!=(const std::string& string) const;
|
||||
|
||||
bool operator<(char character) const;
|
||||
bool operator<(const char* string) const;
|
||||
bool operator<(const std::string& string) const;
|
||||
|
||||
bool operator<=(char character) const;
|
||||
bool operator<=(const char* string) const;
|
||||
bool operator<=(const std::string& string) const;
|
||||
|
||||
bool operator>(char character) const;
|
||||
bool operator>(const char* string) const;
|
||||
bool operator>(const std::string& string) const;
|
||||
|
||||
bool operator>=(char character) const;
|
||||
bool operator>=(const char* string) const;
|
||||
bool operator>=(const std::string& string) const;
|
||||
|
||||
static NzString Boolean(bool boolean);
|
||||
static int Compare(const NzString& first, const NzString& second);
|
||||
static NzString Number(float number);
|
||||
static NzString Number(double number);
|
||||
static NzString Number(long double number);
|
||||
static NzString Number(signed 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(unsigned short number, nzUInt8 radix = 10);
|
||||
static NzString Number(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(unsigned 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 Pointer(const void* ptr);
|
||||
static NzString Unicode(char32_t character);
|
||||
static NzString Unicode(const char* u8String);
|
||||
static NzString Unicode(const char16_t* u16String);
|
||||
static NzString Unicode(const char32_t* u32String);
|
||||
static NzString Unicode(const wchar_t* wString);
|
||||
|
||||
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 NzString operator+(char character, const NzString& string);
|
||||
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 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==(const char* 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!=(const char* 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<(const char* 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<=(const char* 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>(const char* 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>=(const char* string, const NzString& nstring);
|
||||
NAZARA_API friend bool operator>=(const std::string& string, const NzString& nstring);
|
||||
|
||||
struct NAZARA_API SharedString
|
||||
{
|
||||
SharedString() = default;
|
||||
|
||||
SharedString(unsigned short referenceCount, unsigned int bufferSize, unsigned int stringSize, char* str) :
|
||||
capacity(bufferSize),
|
||||
size(stringSize),
|
||||
string(str),
|
||||
refCount(referenceCount)
|
||||
{
|
||||
}
|
||||
|
||||
unsigned int capacity;
|
||||
unsigned int size;
|
||||
char* string;
|
||||
|
||||
unsigned short refCount = 1;
|
||||
NazaraMutex(mutex)
|
||||
};
|
||||
|
||||
static SharedString emptyString;
|
||||
static unsigned int npos;
|
||||
|
||||
private:
|
||||
void EnsureOwnership();
|
||||
bool FillHash(NzHashImpl* hash) const;
|
||||
void ReleaseString();
|
||||
|
||||
SharedString* m_sharedString;
|
||||
};
|
||||
|
||||
namespace std
|
||||
{
|
||||
NAZARA_API istream& getline(istream& is, NzString& str);
|
||||
NAZARA_API istream& getline(istream& is, NzString& str, char delim);
|
||||
NAZARA_API void swap(NzString& lhs, NzString& rhs);
|
||||
}
|
||||
|
||||
#endif // NAZARA_STRING_HPP
|
||||
// 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_STRING_HPP
|
||||
#define NAZARA_STRING_HPP
|
||||
|
||||
#include <Nazara/Prerequesites.hpp>
|
||||
#include <Nazara/Core/Hashable.hpp>
|
||||
#include <iosfwd>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#if NAZARA_CORE_THREADSAFE && NAZARA_THREADSAFETY_STRING
|
||||
#include <Nazara/Core/ThreadSafety.hpp>
|
||||
#else
|
||||
#include <Nazara/Core/ThreadSafetyOff.hpp>
|
||||
#endif
|
||||
|
||||
class NzAbstractHash;
|
||||
class NzHashDigest;
|
||||
|
||||
class NAZARA_API NzString : public NzHashable
|
||||
{
|
||||
public:
|
||||
enum Flags
|
||||
{
|
||||
None = 0x00, // Mode par défaut
|
||||
CaseInsensitive = 0x01, // Insensible à la casse
|
||||
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
|
||||
TrimOnlyRight = 0x08 // Trim(med), ne coupe que la partie droite de la chaîne
|
||||
};
|
||||
|
||||
struct SharedString;
|
||||
|
||||
NzString();
|
||||
NzString(char character);
|
||||
NzString(const char* string);
|
||||
NzString(const std::string& string);
|
||||
NzString(const NzString& string);
|
||||
NzString(NzString&& string) noexcept;
|
||||
NzString(SharedString* sharedString);
|
||||
~NzString();
|
||||
|
||||
NzString& Append(char character);
|
||||
NzString& Append(const char* string);
|
||||
NzString& Append(const NzString& string);
|
||||
|
||||
void Clear(bool keepBuffer = false);
|
||||
|
||||
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 NzString& string, 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 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 NzString& string, int start = 0, nzUInt32 flags = None) const;
|
||||
|
||||
bool EndsWith(char character, nzUInt32 flags = None) const;
|
||||
bool EndsWith(const char* 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(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 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 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 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 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 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 NzString& string, int start = 0, nzUInt32 flags = None) const;
|
||||
|
||||
char* GetBuffer();
|
||||
unsigned int GetCapacity() const;
|
||||
const char* GetConstBuffer() const;
|
||||
unsigned int GetLength() const;
|
||||
unsigned int GetSize() const;
|
||||
char* GetUtf8Buffer(unsigned int* size = nullptr) const;
|
||||
char16_t* GetUtf16Buffer(unsigned int* size = nullptr) const;
|
||||
char32_t* GetUtf32Buffer(unsigned int* size = nullptr) const;
|
||||
wchar_t* GetWideBuffer(unsigned int* size = nullptr) const;
|
||||
|
||||
NzString GetWord(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, const char* string);
|
||||
NzString& Insert(int pos, const NzString& string);
|
||||
|
||||
bool IsEmpty() const;
|
||||
bool IsNull() const;
|
||||
bool IsNumber(nzUInt8 radix = 10, nzUInt32 flags = CaseInsensitive) const;
|
||||
|
||||
bool Match(const char* pattern) const;
|
||||
bool Match(const NzString& pattern) const;
|
||||
|
||||
NzString& Prepend(char character);
|
||||
NzString& Prepend(const char* string);
|
||||
NzString& Prepend(const NzString& string);
|
||||
|
||||
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 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, const char* 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);
|
||||
|
||||
NzString& Resize(int size, char character = ' ');
|
||||
NzString Resized(int size, char character = ' ') const;
|
||||
|
||||
NzString& Reverse();
|
||||
NzString Reversed() const;
|
||||
|
||||
NzString Simplified(nzUInt32 flags = None) const;
|
||||
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, 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 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;
|
||||
|
||||
bool StartsWith(char character, nzUInt32 flags = None) const;
|
||||
bool StartsWith(const char* string, nzUInt32 flags = None) const;
|
||||
bool StartsWith(const NzString& string, nzUInt32 flags = None) 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(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 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 NzString& string, int startPos = 0, bool toLast = false, bool include = false, nzUInt32 flags = None) const;
|
||||
|
||||
void Swap(NzString& str);
|
||||
|
||||
bool ToBool(bool* value, nzUInt32 flags = None) const;
|
||||
bool ToDouble(double* value) const;
|
||||
bool ToInteger(long long* value, nzUInt8 radix = 10) const;
|
||||
NzString ToLower(nzUInt32 flags = None) const;
|
||||
NzString ToUpper(nzUInt32 flags = None) const;
|
||||
|
||||
NzString& Trim(nzUInt32 flags = None);
|
||||
NzString& Trim(char character, nzUInt32 flags = None);
|
||||
NzString Trimmed(nzUInt32 flags = None) const;
|
||||
NzString Trimmed(char character, nzUInt32 flags = None) const;
|
||||
|
||||
// Méthodes STD
|
||||
char* begin();
|
||||
const char* begin() const;
|
||||
char* end();
|
||||
const char* end() const;
|
||||
void push_front(char c);
|
||||
void push_back(char c);
|
||||
/*char* rbegin();
|
||||
const char* rbegin() const;
|
||||
char* rend();
|
||||
const char* rend() const;*/
|
||||
|
||||
typedef const char& const_reference;
|
||||
typedef char* iterator;
|
||||
//typedef char* reverse_iterator;
|
||||
typedef char value_type;
|
||||
// Méthodes STD
|
||||
|
||||
operator std::string() const;
|
||||
|
||||
char& operator[](unsigned int pos);
|
||||
char operator[](unsigned int pos) const;
|
||||
|
||||
NzString& operator=(char character);
|
||||
NzString& operator=(const char* string);
|
||||
NzString& operator=(const std::string& string);
|
||||
NzString& operator=(const NzString& string);
|
||||
NzString& operator=(NzString&& string) noexcept;
|
||||
|
||||
NzString operator+(char character) const;
|
||||
NzString operator+(const char* string) const;
|
||||
NzString operator+(const std::string& string) const;
|
||||
NzString operator+(const NzString& string) const;
|
||||
|
||||
NzString& operator+=(char character);
|
||||
NzString& operator+=(const char* string);
|
||||
NzString& operator+=(const std::string& string);
|
||||
NzString& operator+=(const NzString& string);
|
||||
|
||||
bool operator==(char character) const;
|
||||
bool operator==(const char* string) const;
|
||||
bool operator==(const std::string& string) const;
|
||||
|
||||
bool operator!=(char character) const;
|
||||
bool operator!=(const char* string) const;
|
||||
bool operator!=(const std::string& string) const;
|
||||
|
||||
bool operator<(char character) const;
|
||||
bool operator<(const char* string) const;
|
||||
bool operator<(const std::string& string) const;
|
||||
|
||||
bool operator<=(char character) const;
|
||||
bool operator<=(const char* string) const;
|
||||
bool operator<=(const std::string& string) const;
|
||||
|
||||
bool operator>(char character) const;
|
||||
bool operator>(const char* string) const;
|
||||
bool operator>(const std::string& string) const;
|
||||
|
||||
bool operator>=(char character) const;
|
||||
bool operator>=(const char* string) const;
|
||||
bool operator>=(const std::string& string) const;
|
||||
|
||||
static NzString Boolean(bool boolean);
|
||||
static int Compare(const NzString& first, const NzString& second);
|
||||
static NzString Number(float number);
|
||||
static NzString Number(double number);
|
||||
static NzString Number(long double number);
|
||||
static NzString Number(signed 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(unsigned short number, nzUInt8 radix = 10);
|
||||
static NzString Number(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(unsigned 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 Pointer(const void* ptr);
|
||||
static NzString Unicode(char32_t character);
|
||||
static NzString Unicode(const char* u8String);
|
||||
static NzString Unicode(const char16_t* u16String);
|
||||
static NzString Unicode(const char32_t* u32String);
|
||||
static NzString Unicode(const wchar_t* wString);
|
||||
|
||||
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 NzString operator+(char character, const NzString& string);
|
||||
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 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==(const char* 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!=(const char* 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<(const char* 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<=(const char* 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>(const char* 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>=(const char* string, const NzString& nstring);
|
||||
NAZARA_API friend bool operator>=(const std::string& string, const NzString& nstring);
|
||||
|
||||
struct NAZARA_API SharedString
|
||||
{
|
||||
SharedString() = default;
|
||||
|
||||
SharedString(unsigned short referenceCount, unsigned int bufferSize, unsigned int stringSize, char* str) :
|
||||
capacity(bufferSize),
|
||||
size(stringSize),
|
||||
string(str),
|
||||
refCount(referenceCount)
|
||||
{
|
||||
}
|
||||
|
||||
unsigned int capacity;
|
||||
unsigned int size;
|
||||
char* string;
|
||||
|
||||
unsigned short refCount = 1;
|
||||
NazaraMutex(mutex)
|
||||
};
|
||||
|
||||
static SharedString emptyString;
|
||||
static const unsigned int npos;
|
||||
|
||||
private:
|
||||
void EnsureOwnership();
|
||||
bool FillHash(NzHashImpl* hash) const;
|
||||
void ReleaseString();
|
||||
|
||||
SharedString* m_sharedString;
|
||||
};
|
||||
|
||||
namespace std
|
||||
{
|
||||
NAZARA_API istream& getline(istream& is, NzString& str);
|
||||
NAZARA_API istream& getline(istream& is, NzString& str, char delim);
|
||||
NAZARA_API void swap(NzString& lhs, NzString& rhs);
|
||||
}
|
||||
|
||||
#endif // NAZARA_STRING_HPP
|
||||
|
|
|
|||
|
|
@ -1,52 +1,49 @@
|
|||
/*
|
||||
Nazara Engine - Mathematics module
|
||||
|
||||
Copyright (C) 2012 Jérôme "Lynix" Leclercq (Lynix680@gmail.com)
|
||||
Rémi "overdrivr" Bèges (remi.beges@laposte.net)
|
||||
|
||||
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
|
||||
the Software without restriction, including without limitation the rights to
|
||||
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
|
||||
so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
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
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef NAZARA_CONFIG_MATH_HPP
|
||||
#define NAZARA_CONFIG_MATH_HPP
|
||||
|
||||
/// 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
|
||||
#define NAZARA_MATH_ANGLE_RADIAN 0
|
||||
|
||||
// Définit la disposition des matrices en colonnes (Façon OpenGL)
|
||||
#define NAZARA_MATH_MATRIX_COLUMN_MAJOR 1
|
||||
|
||||
// Optimise les opérations entre matrices affines (Demande plusieurs comparaisons pour déterminer si une matrice est affine)
|
||||
#define NAZARA_MATH_MATRIX4_CHECK_AFFINE 0
|
||||
|
||||
// Active les tests de sécurité basés sur le code (Conseillé pour le développement)
|
||||
#define NAZARA_MATH_SAFE 1
|
||||
|
||||
// Protège les classes des accès concurrentiels
|
||||
#define NAZARA_MATH_THREADSAFE 1
|
||||
|
||||
// Les classes à protéger des accès concurrentiels
|
||||
#define NAZARA_THREADSAFETY_MATRIX3 1 // NzMatrix3 (COW)
|
||||
#define NAZARA_THREADSAFETY_MATRIX4 1 // NzMatrix4 (COW)
|
||||
|
||||
#endif // NAZARA_CONFIG_MATH_HPP
|
||||
/*
|
||||
Nazara Engine - Mathematics module
|
||||
|
||||
Copyright (C) 2012 Jérôme "Lynix" Leclercq (Lynix680@gmail.com)
|
||||
Rémi "overdrivr" Bèges (remi.beges@laposte.net)
|
||||
|
||||
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
|
||||
the Software without restriction, including without limitation the rights to
|
||||
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
|
||||
so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
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
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef NAZARA_CONFIG_MATH_HPP
|
||||
#define NAZARA_CONFIG_MATH_HPP
|
||||
|
||||
/// 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
|
||||
#define NAZARA_MATH_ANGLE_RADIAN 0
|
||||
|
||||
// Optimise les opérations entre matrices affines (Demande plusieurs comparaisons pour déterminer si une matrice est affine)
|
||||
#define NAZARA_MATH_MATRIX4_CHECK_AFFINE 0
|
||||
|
||||
// Active les tests de sécurité basés sur le code (Conseillé pour le développement)
|
||||
#define NAZARA_MATH_SAFE 1
|
||||
|
||||
// Protège les classes des accès concurrentiels
|
||||
#define NAZARA_MATH_THREADSAFE 1
|
||||
|
||||
// Les classes à protéger des accès concurrentiels
|
||||
#define NAZARA_THREADSAFETY_MATRIX3 1 // NzMatrix3 (COW)
|
||||
#define NAZARA_THREADSAFETY_MATRIX4 1 // NzMatrix4 (COW)
|
||||
|
||||
#endif // NAZARA_CONFIG_MATH_HPP
|
||||
|
|
|
|||
|
|
@ -1,144 +1,145 @@
|
|||
// Copyright (C) 2012 Jérôme Leclercq
|
||||
// This file is part of the "Nazara Engine - Mathematics module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef NAZARA_MATRIX4_HPP
|
||||
#define NAZARA_MATRIX4_HPP
|
||||
|
||||
#include <Nazara/Core/String.hpp>
|
||||
#include <Nazara/Math/Config.hpp>
|
||||
|
||||
#if NAZARA_MATH_THREADSAFE && NAZARA_THREADSAFETY_MATRIX4
|
||||
#include <Nazara/Core/ThreadSafety.hpp>
|
||||
#else
|
||||
#include <Nazara/Core/ThreadSafetyOff.hpp>
|
||||
#endif
|
||||
|
||||
template<typename T> class NzEulerAngles;
|
||||
template<typename T> class NzQuaternion;
|
||||
template<typename T> class NzVector2;
|
||||
template<typename T> class NzVector3;
|
||||
template<typename T> class NzVector4;
|
||||
|
||||
template<typename T> class NzMatrix4
|
||||
{
|
||||
public:
|
||||
NzMatrix4();
|
||||
NzMatrix4(T r11, T r12, T r13, T r14,
|
||||
T r21, T r22, T r23, T r24,
|
||||
T r31, T r32, T r33, T r34,
|
||||
T r41, T r42, T r43, T r44);
|
||||
NzMatrix4(const T matrix[16]);
|
||||
//NzMatrix4(const NzMatrix3<T>& matrix);
|
||||
template<typename U> explicit NzMatrix4(const NzMatrix4<U>& matrix);
|
||||
NzMatrix4(const NzMatrix4& matrix);
|
||||
NzMatrix4(NzMatrix4&& matrix) noexcept;
|
||||
~NzMatrix4();
|
||||
|
||||
NzMatrix4 Concatenate(const NzMatrix4& matrix) const;
|
||||
|
||||
T GetDeterminant() const;
|
||||
NzMatrix4 GetInverse() const;
|
||||
NzQuaternion<T> GetRotation() const;
|
||||
//NzMatrix3 GetRotationMatrix() const;
|
||||
NzVector3<T> GetScale() const;
|
||||
NzVector3<T> GetTranslation() const;
|
||||
NzMatrix4 GetTransposed() const;
|
||||
|
||||
bool HasNegativeScale() const;
|
||||
bool HasScale() const;
|
||||
|
||||
bool IsAffine() const;
|
||||
bool IsDefined() const;
|
||||
|
||||
void MakeIdentity();
|
||||
void MakeLookAt(const NzVector3<T>& eye, const NzVector3<T>& center, const NzVector3<T>& up);
|
||||
void MakeOrtho(T left, T top, T width, T height, T zNear = -1.0, T zFar = 1.0);
|
||||
void MakePerspective(T angle, T ratio, T zNear, T zFar);
|
||||
void MakeRotation(const NzQuaternion<T>& rotation);
|
||||
void MakeScale(const NzVector3<T>& scale);
|
||||
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,
|
||||
T r31, T r32, T r33, T r34,
|
||||
T r41, T r42, T r43, T r44);
|
||||
void Set(const T matrix[16]);
|
||||
//NzMatrix4(const NzMatrix3<T>& matrix);
|
||||
void Set(const NzMatrix4& matrix);
|
||||
void Set(NzMatrix4&& matrix);
|
||||
template<typename U> void Set(const NzMatrix4<U>& matrix);
|
||||
void SetRotation(const NzQuaternion<T>& rotation);
|
||||
void SetScale(const NzVector3<T>& scale);
|
||||
void SetTranslation(const NzVector3<T>& translation);
|
||||
|
||||
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;
|
||||
NzVector4<T> Transform(const NzVector4<T>& vector) const;
|
||||
|
||||
NzMatrix4& Transpose();
|
||||
|
||||
operator NzString() 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;
|
||||
|
||||
NzMatrix4& operator=(const NzMatrix4& matrix);
|
||||
NzMatrix4& operator=(NzMatrix4&& matrix) noexcept;
|
||||
|
||||
NzMatrix4 operator*(const NzMatrix4& matrix) const;
|
||||
NzVector2<T> operator*(const NzVector2<T>& vector) const;
|
||||
NzVector3<T> operator*(const NzVector3<T>& vector) const;
|
||||
NzVector4<T> operator*(const NzVector4<T>& vector) const;
|
||||
NzMatrix4 operator*(T scalar) const;
|
||||
|
||||
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 Identity();
|
||||
static NzMatrix4 LookAt(const NzVector3<T>& eye, const NzVector3<T>& center, const NzVector3<T>& up);
|
||||
static NzMatrix4 Ortho(T left, T top, T width, T height, T zNear = -1.0, T zFar = 1.0);
|
||||
static NzMatrix4 Perspective(T angle, T ratio, T zNear, T zFar);
|
||||
static NzMatrix4 Rotate(const NzQuaternion<T>& rotation);
|
||||
static NzMatrix4 Scale(const NzVector3<T>& scale);
|
||||
static NzMatrix4 Translate(const NzVector3<T>& translation);
|
||||
static NzMatrix4 Zero();
|
||||
|
||||
struct SharedMatrix
|
||||
{
|
||||
T m11, m12, m13, m14,
|
||||
m21, m22, m23, m24,
|
||||
m31, m32, m33, m34,
|
||||
m41, m42, m43, m44;
|
||||
|
||||
unsigned short refCount = 1;
|
||||
NazaraMutex(mutex)
|
||||
};
|
||||
|
||||
private:
|
||||
void EnsureOwnership();
|
||||
void ReleaseMatrix();
|
||||
|
||||
SharedMatrix* m_sharedMatrix = nullptr;
|
||||
};
|
||||
|
||||
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);
|
||||
|
||||
typedef NzMatrix4<double> NzMatrix4d;
|
||||
typedef NzMatrix4<float> NzMatrix4f;
|
||||
|
||||
#include <Nazara/Math/Matrix4.inl>
|
||||
|
||||
#endif // NAZARA_MATRIX4_HPP
|
||||
// Copyright (C) 2012 Jérôme Leclercq
|
||||
// This file is part of the "Nazara Engine - Mathematics module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef NAZARA_MATRIX4_HPP
|
||||
#define NAZARA_MATRIX4_HPP
|
||||
|
||||
#include <Nazara/Core/String.hpp>
|
||||
#include <Nazara/Math/Config.hpp>
|
||||
|
||||
#if NAZARA_MATH_THREADSAFE && NAZARA_THREADSAFETY_MATRIX4
|
||||
#include <Nazara/Core/ThreadSafety.hpp>
|
||||
#else
|
||||
#include <Nazara/Core/ThreadSafetyOff.hpp>
|
||||
#endif
|
||||
|
||||
template<typename T> class NzEulerAngles;
|
||||
template<typename T> class NzQuaternion;
|
||||
template<typename T> class NzVector2;
|
||||
template<typename T> class NzVector3;
|
||||
template<typename T> class NzVector4;
|
||||
|
||||
template<typename T> class NzMatrix4
|
||||
{
|
||||
public:
|
||||
NzMatrix4();
|
||||
NzMatrix4(T r11, T r12, T r13, T r14,
|
||||
T r21, T r22, T r23, T r24,
|
||||
T r31, T r32, T r33, T r34,
|
||||
T r41, T r42, T r43, T r44);
|
||||
NzMatrix4(const T matrix[16]);
|
||||
//NzMatrix4(const NzMatrix3<T>& matrix);
|
||||
template<typename U> explicit NzMatrix4(const NzMatrix4<U>& matrix);
|
||||
NzMatrix4(const NzMatrix4& matrix);
|
||||
NzMatrix4(NzMatrix4&& matrix) noexcept;
|
||||
~NzMatrix4();
|
||||
|
||||
NzMatrix4 Concatenate(const NzMatrix4& matrix) const;
|
||||
NzMatrix4 ConcatenateAffine(const NzMatrix4& matrix) const;
|
||||
|
||||
T GetDeterminant() const;
|
||||
NzMatrix4 GetInverse() const;
|
||||
NzQuaternion<T> GetRotation() const;
|
||||
//NzMatrix3 GetRotationMatrix() const;
|
||||
NzVector3<T> GetScale() const;
|
||||
NzVector3<T> GetTranslation() const;
|
||||
NzMatrix4 GetTransposed() const;
|
||||
|
||||
bool HasNegativeScale() const;
|
||||
bool HasScale() const;
|
||||
|
||||
bool IsAffine() const;
|
||||
bool IsDefined() const;
|
||||
|
||||
void MakeIdentity();
|
||||
void MakeLookAt(const NzVector3<T>& eye, const NzVector3<T>& target, const NzVector3<T>& up = NzVector3<T>::Up());
|
||||
void MakeOrtho(T left, T top, T width, T height, T zNear = -1.0, T zFar = 1.0);
|
||||
void MakePerspective(T angle, T ratio, T zNear, T zFar);
|
||||
void MakeRotation(const NzQuaternion<T>& rotation);
|
||||
void MakeScale(const NzVector3<T>& scale);
|
||||
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,
|
||||
T r31, T r32, T r33, T r34,
|
||||
T r41, T r42, T r43, T r44);
|
||||
void Set(const T matrix[16]);
|
||||
//NzMatrix4(const NzMatrix3<T>& matrix);
|
||||
void Set(const NzMatrix4& matrix);
|
||||
void Set(NzMatrix4&& matrix);
|
||||
template<typename U> void Set(const NzMatrix4<U>& matrix);
|
||||
void SetRotation(const NzQuaternion<T>& rotation);
|
||||
void SetScale(const NzVector3<T>& scale);
|
||||
void SetTranslation(const NzVector3<T>& translation);
|
||||
|
||||
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;
|
||||
NzVector4<T> Transform(const NzVector4<T>& vector) const;
|
||||
|
||||
NzMatrix4& Transpose();
|
||||
|
||||
operator NzString() 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;
|
||||
|
||||
NzMatrix4& operator=(const NzMatrix4& matrix);
|
||||
NzMatrix4& operator=(NzMatrix4&& matrix) noexcept;
|
||||
|
||||
NzMatrix4 operator*(const NzMatrix4& matrix) const;
|
||||
NzVector2<T> operator*(const NzVector2<T>& vector) const;
|
||||
NzVector3<T> operator*(const NzVector3<T>& vector) const;
|
||||
NzVector4<T> operator*(const NzVector4<T>& vector) const;
|
||||
NzMatrix4 operator*(T scalar) const;
|
||||
|
||||
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 Identity();
|
||||
static NzMatrix4 LookAt(const NzVector3<T>& eye, const NzVector3<T>& target, const NzVector3<T>& up = NzVector3<T>::Up());
|
||||
static NzMatrix4 Ortho(T left, T top, T width, T height, T zNear = -1.0, T zFar = 1.0);
|
||||
static NzMatrix4 Perspective(T angle, T ratio, T zNear, T zFar);
|
||||
static NzMatrix4 Rotate(const NzQuaternion<T>& rotation);
|
||||
static NzMatrix4 Scale(const NzVector3<T>& scale);
|
||||
static NzMatrix4 Translate(const NzVector3<T>& translation);
|
||||
static NzMatrix4 Zero();
|
||||
|
||||
struct SharedMatrix
|
||||
{
|
||||
T m11, m12, m13, m14,
|
||||
m21, m22, m23, m24,
|
||||
m31, m32, m33, m34,
|
||||
m41, m42, m43, m44;
|
||||
|
||||
unsigned short refCount = 1;
|
||||
NazaraMutex(mutex)
|
||||
};
|
||||
|
||||
private:
|
||||
void EnsureOwnership();
|
||||
void ReleaseMatrix();
|
||||
|
||||
SharedMatrix* m_sharedMatrix = nullptr;
|
||||
};
|
||||
|
||||
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);
|
||||
|
||||
typedef NzMatrix4<double> NzMatrix4d;
|
||||
typedef NzMatrix4<float> NzMatrix4f;
|
||||
|
||||
#include <Nazara/Math/Matrix4.inl>
|
||||
|
||||
#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
|
||||
// This file is part of the "Nazara Engine - Mathematics module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef NAZARA_QUATERNION_HPP
|
||||
#define NAZARA_QUATERNION_HPP
|
||||
|
||||
#include <Nazara/Core/String.hpp>
|
||||
|
||||
template<typename T> class NzEulerAngles;
|
||||
template<typename T> class NzVector3;
|
||||
|
||||
template<typename T> class NzQuaternion
|
||||
{
|
||||
public:
|
||||
NzQuaternion();
|
||||
NzQuaternion(T W, T X, T Y, T Z);
|
||||
NzQuaternion(T quat[4]);
|
||||
NzQuaternion(T angle, const NzVector3<T>& axis);
|
||||
NzQuaternion(const NzEulerAngles<T>& angles);
|
||||
//NzQuaternion(const NzMatrix3<T>& mat);
|
||||
template<typename U> explicit NzQuaternion(const NzQuaternion<U>& quat);
|
||||
NzQuaternion(const NzQuaternion& quat) = default;
|
||||
~NzQuaternion() = default;
|
||||
|
||||
T DotProduct(const NzQuaternion& vec) const;
|
||||
|
||||
NzQuaternion GetConjugate() const;
|
||||
NzQuaternion GetNormalized() const;
|
||||
|
||||
void MakeIdentity();
|
||||
void MakeZero();
|
||||
|
||||
T Magnitude() const;
|
||||
|
||||
T Normalize();
|
||||
|
||||
void Set(T W, T X, T Y, T Z);
|
||||
void Set(T quat[4]);
|
||||
void Set(T angle, const NzVector3<T>& normalizedAxis);
|
||||
void Set(const NzEulerAngles<T>& angles);
|
||||
//void Set(const NzMatrix3<T>& mat);
|
||||
void Set(const NzQuaternion& quat);
|
||||
template<typename U> void Set(const NzQuaternion<U>& quat);
|
||||
|
||||
T SquaredMagnitude() const;
|
||||
|
||||
NzEulerAngles<T> ToEulerAngles() const;
|
||||
//NzMatrix3<T> ToRotationMatrix() const;
|
||||
NzString ToString() const;
|
||||
|
||||
operator NzString() const;
|
||||
|
||||
NzQuaternion& operator=(const NzQuaternion& quat);
|
||||
|
||||
NzQuaternion operator+(const NzQuaternion& quat) const;
|
||||
NzQuaternion operator*(const NzQuaternion& quat) const;
|
||||
NzVector3<T> operator*(const NzVector3<T>& vec) const;
|
||||
NzQuaternion operator*(T scale) const;
|
||||
NzQuaternion operator/(const NzQuaternion& quat) const;
|
||||
|
||||
NzQuaternion& operator+=(const NzQuaternion& quat);
|
||||
NzQuaternion& operator*=(const NzQuaternion& quat);
|
||||
NzQuaternion& operator*=(T scale);
|
||||
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;
|
||||
|
||||
static NzQuaternion Identity();
|
||||
static NzQuaternion Slerp(const NzQuaternion& quatA, const NzQuaternion& quatB, T interp);
|
||||
static NzQuaternion Zero();
|
||||
|
||||
T w, x, y, z;
|
||||
};
|
||||
|
||||
template<typename T> std::ostream& operator<<(std::ostream& out, const NzQuaternion<T>& quat);
|
||||
|
||||
typedef NzQuaternion<double> NzQuaterniond;
|
||||
typedef NzQuaternion<float> NzQuaternionf;
|
||||
|
||||
#include <Nazara/Math/Quaternion.inl>
|
||||
|
||||
#endif // NAZARA_QUATERNION_HPP
|
||||
// Copyright (C) 2012 Rémi Bèges - Jérôme Leclercq
|
||||
// This file is part of the "Nazara Engine - Mathematics module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef NAZARA_QUATERNION_HPP
|
||||
#define NAZARA_QUATERNION_HPP
|
||||
|
||||
#include <Nazara/Core/String.hpp>
|
||||
|
||||
template<typename T> class NzEulerAngles;
|
||||
template<typename T> class NzVector3;
|
||||
|
||||
template<typename T> class NzQuaternion
|
||||
{
|
||||
public:
|
||||
NzQuaternion();
|
||||
NzQuaternion(T W, T X, T Y, T Z);
|
||||
NzQuaternion(T quat[4]);
|
||||
NzQuaternion(T angle, const NzVector3<T>& axis);
|
||||
NzQuaternion(const NzEulerAngles<T>& angles);
|
||||
//NzQuaternion(const NzMatrix3<T>& mat);
|
||||
template<typename U> explicit NzQuaternion(const NzQuaternion<U>& quat);
|
||||
NzQuaternion(const NzQuaternion& quat) = default;
|
||||
~NzQuaternion() = default;
|
||||
|
||||
T DotProduct(const NzQuaternion& vec) const;
|
||||
|
||||
NzQuaternion GetConjugate() const;
|
||||
NzQuaternion GetInverse() const;
|
||||
NzQuaternion GetNormal() const;
|
||||
|
||||
void Inverse();
|
||||
|
||||
void MakeIdentity();
|
||||
void MakeZero();
|
||||
|
||||
T Magnitude() const;
|
||||
|
||||
T Normalize();
|
||||
|
||||
void Set(T W, T X, T Y, T Z);
|
||||
void Set(T quat[4]);
|
||||
void Set(T angle, const NzVector3<T>& normalizedAxis);
|
||||
void Set(const NzEulerAngles<T>& angles);
|
||||
//void Set(const NzMatrix3<T>& mat);
|
||||
void Set(const NzQuaternion& quat);
|
||||
template<typename U> void Set(const NzQuaternion<U>& quat);
|
||||
|
||||
T SquaredMagnitude() const;
|
||||
|
||||
NzEulerAngles<T> ToEulerAngles() const;
|
||||
//NzMatrix3<T> ToRotationMatrix() const;
|
||||
NzString ToString() const;
|
||||
|
||||
operator NzString() const;
|
||||
|
||||
NzQuaternion& operator=(const NzQuaternion& quat);
|
||||
|
||||
NzQuaternion operator+(const NzQuaternion& quat) const;
|
||||
NzQuaternion operator*(const NzQuaternion& quat) const;
|
||||
NzVector3<T> operator*(const NzVector3<T>& vec) const;
|
||||
NzQuaternion operator*(T scale) const;
|
||||
NzQuaternion operator/(const NzQuaternion& quat) const;
|
||||
|
||||
NzQuaternion& operator+=(const NzQuaternion& quat);
|
||||
NzQuaternion& operator*=(const NzQuaternion& quat);
|
||||
NzQuaternion& operator*=(T scale);
|
||||
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;
|
||||
|
||||
static NzQuaternion Identity();
|
||||
static NzQuaternion Slerp(const NzQuaternion& quatA, const NzQuaternion& quatB, T interp);
|
||||
static NzQuaternion Zero();
|
||||
|
||||
T w, x, y, z;
|
||||
};
|
||||
|
||||
template<typename T> std::ostream& operator<<(std::ostream& out, const NzQuaternion<T>& quat);
|
||||
|
||||
typedef NzQuaternion<double> NzQuaterniond;
|
||||
typedef NzQuaternion<float> NzQuaternionf;
|
||||
|
||||
#include <Nazara/Math/Quaternion.inl>
|
||||
|
||||
#endif // NAZARA_QUATERNION_HPP
|
||||
|
|
|
|||
|
|
@ -1,403 +1,428 @@
|
|||
// Copyright (C) 2012 Rémi Bèges - Jérôme Leclercq
|
||||
// This file is part of the "Nazara Engine - Mathematics module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#include <Nazara/Core/StringStream.hpp>
|
||||
#include <Nazara/Math/Basic.hpp>
|
||||
#include <Nazara/Math/Config.hpp>
|
||||
#include <Nazara/Math/EulerAngles.hpp>
|
||||
#include <Nazara/Math/Vector3.hpp>
|
||||
#include <limits>
|
||||
#include <Nazara/Core/Debug.hpp>
|
||||
|
||||
#define F(a) static_cast<T>(a)
|
||||
|
||||
template<typename T>
|
||||
NzQuaternion<T>::NzQuaternion()
|
||||
{
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
NzQuaternion<T>::NzQuaternion(T W, T X, T Y, T Z)
|
||||
{
|
||||
Set(W, X, Y, Z);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
NzQuaternion<T>::NzQuaternion(T quat[4])
|
||||
{
|
||||
Set(quat);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
NzQuaternion<T>::NzQuaternion(T angle, const NzVector3<T>& axis)
|
||||
{
|
||||
Set(angle, axis);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
NzQuaternion<T>::NzQuaternion(const NzEulerAngles<T>& angles)
|
||||
{
|
||||
Set(angles);
|
||||
}
|
||||
/*
|
||||
template<typename T>
|
||||
NzQuaternion<T>::NzQuaternion(const NzMatrix3<T>& mat)
|
||||
{
|
||||
Set(mat);
|
||||
}
|
||||
*/
|
||||
template<typename T>
|
||||
template<typename U>
|
||||
NzQuaternion<T>::NzQuaternion(const NzQuaternion<U>& quat)
|
||||
{
|
||||
Set(quat);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T NzQuaternion<T>::DotProduct(const NzQuaternion& quat) const
|
||||
{
|
||||
return w*quat.w + x*quat.x + y*quat.y + z*quat.z;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
NzQuaternion<T> NzQuaternion<T>::GetConjugate() const
|
||||
{
|
||||
return NzQuaternion(w, -x, -y, -z);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
NzQuaternion<T> NzQuaternion<T>::GetNormalized() const
|
||||
{
|
||||
NzQuaternion<T> quat(*this);
|
||||
quat.Normalize();
|
||||
|
||||
return quat;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void NzQuaternion<T>::MakeIdentity()
|
||||
{
|
||||
Set(1.0, 0.0, 0.0, 0.0);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void NzQuaternion<T>::MakeZero()
|
||||
{
|
||||
Set(0.0, 0.0, 0.0, 0.0);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T NzQuaternion<T>::Magnitude() const
|
||||
{
|
||||
return std::sqrt(SquaredMagnitude());
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T NzQuaternion<T>::Normalize()
|
||||
{
|
||||
T squaredMagnitude = SquaredMagnitude();
|
||||
|
||||
if (squaredMagnitude-F(1.0) > std::numeric_limits<T>::epsilon())
|
||||
{
|
||||
T magnitude = std::sqrt(squaredMagnitude);
|
||||
|
||||
w /= magnitude;
|
||||
x /= magnitude;
|
||||
y /= magnitude;
|
||||
z /= magnitude;
|
||||
|
||||
return magnitude;
|
||||
}
|
||||
else
|
||||
return F(1.0); // Le quaternion est déjà normalisé
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void NzQuaternion<T>::Set(T W, T X, T Y, T Z)
|
||||
{
|
||||
w = W;
|
||||
x = X;
|
||||
y = Y;
|
||||
z = Z;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void NzQuaternion<T>::Set(T quat[4])
|
||||
{
|
||||
w = quat[0];
|
||||
x = quat[1];
|
||||
y = quat[2];
|
||||
z = quat[3];
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void NzQuaternion<T>::Set(T angle, const NzVector3<T>& normalizedAxis)
|
||||
{
|
||||
#if !NAZARA_MATH_ANGLE_RADIAN
|
||||
angle = NzDegreeToRadian(angle);
|
||||
#endif
|
||||
|
||||
angle /= 2;
|
||||
|
||||
auto sinAngle = std::sin(angle);
|
||||
|
||||
w = std::cos(angle);
|
||||
x = normalizedAxis.x * sinAngle;
|
||||
y = normalizedAxis.y * sinAngle;
|
||||
z = normalizedAxis.z * sinAngle;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void NzQuaternion<T>::Set(const NzEulerAngles<T>& angles)
|
||||
{
|
||||
Set(angles.ToQuaternion());
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
template<typename U>
|
||||
void NzQuaternion<T>::Set(const NzQuaternion<U>& quat)
|
||||
{
|
||||
w = static_cast<T>(quat.w);
|
||||
x = static_cast<T>(quat.x);
|
||||
y = static_cast<T>(quat.y);
|
||||
z = static_cast<T>(quat.z);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void NzQuaternion<T>::Set(const NzQuaternion& quat)
|
||||
{
|
||||
w = quat.w;
|
||||
x = quat.x;
|
||||
y = quat.y;
|
||||
z = quat.z;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T NzQuaternion<T>::SquaredMagnitude() const
|
||||
{
|
||||
return w*w + x*x + y*y + z*z;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
NzEulerAngles<T> NzQuaternion<T>::ToEulerAngles() const
|
||||
{
|
||||
T test = x*y + z*w;
|
||||
if (test > F(0.499))
|
||||
// singularity at north pole
|
||||
return NzEulerAngles<T>(NzDegrees(F(90.0)), NzRadians(F(2.0) * std::atan2(x, w)), F(0.0));
|
||||
|
||||
if (test < F(-0.499))
|
||||
return NzEulerAngles<T>(NzDegrees(F(-90.0)), NzRadians(F(-2.0) * std::atan2(x, w)), F(0.0));
|
||||
|
||||
T xx = x*x;
|
||||
T yy = y*y;
|
||||
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)),
|
||||
NzRadians(std::atan2(F(2.0)*y*w - F(2.0)*x*z, F(1.0) - F(2.0)*yy - F(2.0)*zz)),
|
||||
NzRadians(std::asin(F(2.0)*test)));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
NzString NzQuaternion<T>::ToString() const
|
||||
{
|
||||
NzStringStream ss;
|
||||
|
||||
return ss << "Quaternion(" << w << " | " << x << ", " << y << ", " << z << ')';
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
NzQuaternion<T>::operator NzString() const
|
||||
{
|
||||
return ToString();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
NzQuaternion<T>& NzQuaternion<T>::operator=(const NzQuaternion& quat)
|
||||
{
|
||||
Set(quat);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
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>
|
||||
NzQuaternion<T> NzQuaternion<T>::operator*(const NzQuaternion& quat) const
|
||||
{
|
||||
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,
|
||||
w*quat.y + y*quat.w + z*quat.x - x*quat.z,
|
||||
w*quat.z + z*quat.w + x*quat.y - y*quat.x);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
NzVector3<T> NzQuaternion<T>::operator*(const NzVector3<T>& vec) const
|
||||
{
|
||||
NzVector3<T> normal(vec);
|
||||
normal.Normalize();
|
||||
|
||||
NzQuaternion qvec(0.0, normal.x, normal.y, normal.z);
|
||||
NzQuaternion result(operator*(qvec * GetConjugate()));
|
||||
|
||||
return NzVector3<T>(result.x, result.y, result.z);
|
||||
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
NzQuaternion<T> NzQuaternion<T>::operator*(T scale) const
|
||||
{
|
||||
return NzQuaternion(w * scale,
|
||||
x * scale,
|
||||
y * scale,
|
||||
z * scale);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
NzQuaternion<T> NzQuaternion<T>::operator/(const NzQuaternion& quat) const
|
||||
{
|
||||
return GetConjugate(quat) * (*this);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
NzQuaternion<T>& NzQuaternion<T>::operator+=(const NzQuaternion& quat)
|
||||
{
|
||||
return operator=(operator+(quat));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
NzQuaternion<T>& NzQuaternion<T>::operator*=(const NzQuaternion& quat)
|
||||
{
|
||||
return operator=(operator*(quat));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
NzQuaternion<T>& NzQuaternion<T>::operator*=(T scale)
|
||||
{
|
||||
return operator=(operator*(scale));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
NzQuaternion<T>& NzQuaternion<T>::operator/=(const NzQuaternion& quat)
|
||||
{
|
||||
return operator=(operator/(quat));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool NzQuaternion<T>::operator==(const NzQuaternion& quat) const
|
||||
{
|
||||
return NzNumberEquals(w, quat.w) &&
|
||||
NzNumberEquals(x, quat.x) &&
|
||||
NzNumberEquals(y, quat.y) &&
|
||||
NzNumberEquals(z, quat.z);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool NzQuaternion<T>::operator!=(const NzQuaternion& quat) const
|
||||
{
|
||||
return !operator==(quat);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool NzQuaternion<T>::operator<(const NzQuaternion& quat) const
|
||||
{
|
||||
return w < quat.w && x < quat.x && y < quat.y && z < quat.z;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool NzQuaternion<T>::operator<=(const NzQuaternion& quat) const
|
||||
{
|
||||
return operator<(quat) || operator==(quat);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool NzQuaternion<T>::operator>(const NzQuaternion& quat) const
|
||||
{
|
||||
return !operator<=(quat);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool NzQuaternion<T>::operator>=(const NzQuaternion& quat) const
|
||||
{
|
||||
return !operator<(quat);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
NzQuaternion<T> NzQuaternion<T>::Identity()
|
||||
{
|
||||
NzQuaternion quaternion;
|
||||
quaternion.MakeIdentity();
|
||||
|
||||
return quaternion;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
NzQuaternion<T> NzQuaternion<T>::Slerp(const NzQuaternion& quatA, const NzQuaternion& quatB, T interp)
|
||||
{
|
||||
if (interp <= F(0.0))
|
||||
return quatA;
|
||||
|
||||
if (interp >= F(1.0))
|
||||
return quatB;
|
||||
|
||||
NzQuaternion q;
|
||||
|
||||
T cosOmega = quatA.DotProduct(quatB);
|
||||
if (cosOmega < F(0.0))
|
||||
{
|
||||
// On inverse tout
|
||||
q.Set(-quatB.w, -quatB.x, -quatB.y, -quatB.z);
|
||||
cosOmega = -cosOmega;
|
||||
}
|
||||
else
|
||||
q.Set(quatB);
|
||||
|
||||
T k0, k1;
|
||||
if (cosOmega > F(0.9999))
|
||||
{
|
||||
// Interpolation linéaire pour éviter une division par zéro
|
||||
k0 = F(1.0) - interp;
|
||||
k1 = interp;
|
||||
}
|
||||
else
|
||||
{
|
||||
T sinOmega = std::sqrt(F(1.0) - cosOmega*cosOmega);
|
||||
T omega = std::atan2(sinOmega, cosOmega);
|
||||
|
||||
// Pour éviter deux divisions
|
||||
sinOmega = F(1.0)/sinOmega;
|
||||
|
||||
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>
|
||||
// Copyright (C) 2012 Rémi Bèges - Jérôme Leclercq
|
||||
// This file is part of the "Nazara Engine - Mathematics module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#include <Nazara/Core/StringStream.hpp>
|
||||
#include <Nazara/Math/Basic.hpp>
|
||||
#include <Nazara/Math/Config.hpp>
|
||||
#include <Nazara/Math/EulerAngles.hpp>
|
||||
#include <Nazara/Math/Vector3.hpp>
|
||||
#include <limits>
|
||||
#include <Nazara/Core/Debug.hpp>
|
||||
|
||||
#define F(a) static_cast<T>(a)
|
||||
|
||||
template<typename T>
|
||||
NzQuaternion<T>::NzQuaternion()
|
||||
{
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
NzQuaternion<T>::NzQuaternion(T W, T X, T Y, T Z)
|
||||
{
|
||||
Set(W, X, Y, Z);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
NzQuaternion<T>::NzQuaternion(T quat[4])
|
||||
{
|
||||
Set(quat);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
NzQuaternion<T>::NzQuaternion(T angle, const NzVector3<T>& axis)
|
||||
{
|
||||
Set(angle, axis);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
NzQuaternion<T>::NzQuaternion(const NzEulerAngles<T>& angles)
|
||||
{
|
||||
Set(angles);
|
||||
}
|
||||
/*
|
||||
template<typename T>
|
||||
NzQuaternion<T>::NzQuaternion(const NzMatrix3<T>& mat)
|
||||
{
|
||||
Set(mat);
|
||||
}
|
||||
*/
|
||||
template<typename T>
|
||||
template<typename U>
|
||||
NzQuaternion<T>::NzQuaternion(const NzQuaternion<U>& quat)
|
||||
{
|
||||
Set(quat);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T NzQuaternion<T>::DotProduct(const NzQuaternion& quat) const
|
||||
{
|
||||
return w*quat.w + x*quat.x + y*quat.y + z*quat.z;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
NzQuaternion<T> NzQuaternion<T>::GetConjugate() const
|
||||
{
|
||||
return NzQuaternion(w, -x, -y, -z);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
NzQuaternion<T> NzQuaternion<T>::GetInverse() const
|
||||
{
|
||||
NzQuaternion<T> quat(*this);
|
||||
quat.Inverse();
|
||||
|
||||
return quat;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
NzQuaternion<T> NzQuaternion<T>::GetNormal() const
|
||||
{
|
||||
NzQuaternion<T> quat(*this);
|
||||
quat.Normalize();
|
||||
|
||||
return quat;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void NzQuaternion<T>::Inverse()
|
||||
{
|
||||
T norm = SquaredMagnitude();
|
||||
if (norm > F(0.0))
|
||||
{
|
||||
T invNorm = F(1.0) / norm;
|
||||
|
||||
w *= invNorm;
|
||||
x *= -invNorm;
|
||||
y *= -invNorm;
|
||||
z *= -invNorm;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void NzQuaternion<T>::MakeIdentity()
|
||||
{
|
||||
Set(F(1.0), F(0.0), F(0.0), F(0.0));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void NzQuaternion<T>::MakeZero()
|
||||
{
|
||||
Set(F(0.0), F(0.0), F(0.0), F(0.0));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T NzQuaternion<T>::Magnitude() const
|
||||
{
|
||||
return std::sqrt(SquaredMagnitude());
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T NzQuaternion<T>::Normalize()
|
||||
{
|
||||
T squaredMagnitude = SquaredMagnitude();
|
||||
|
||||
// Inutile de vérifier si la magnitude au carrée est négative (Elle ne peut pas l'être)
|
||||
if (!NzNumberEquals(squaredMagnitude, F(1.0)))
|
||||
{
|
||||
T norm = std::sqrt(squaredMagnitude);
|
||||
T invNorm = F(1.0) / norm;
|
||||
|
||||
w *= invNorm;
|
||||
x *= invNorm;
|
||||
y *= invNorm;
|
||||
z *= invNorm;
|
||||
|
||||
return norm;
|
||||
}
|
||||
else
|
||||
return F(1.0); // Le quaternion est déjà normalisé
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void NzQuaternion<T>::Set(T W, T X, T Y, T Z)
|
||||
{
|
||||
w = W;
|
||||
x = X;
|
||||
y = Y;
|
||||
z = Z;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void NzQuaternion<T>::Set(T quat[4])
|
||||
{
|
||||
w = quat[0];
|
||||
x = quat[1];
|
||||
y = quat[2];
|
||||
z = quat[3];
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void NzQuaternion<T>::Set(T angle, const NzVector3<T>& axis)
|
||||
{
|
||||
angle /= F(2.0);
|
||||
|
||||
#if !NAZARA_MATH_ANGLE_RADIAN
|
||||
angle = NzDegreeToRadian(angle);
|
||||
#endif
|
||||
|
||||
NzVector3<T> normalizedAxis = axis.GetNormal();
|
||||
|
||||
T sinAngle = std::sin(angle);
|
||||
|
||||
w = std::cos(angle);
|
||||
x = normalizedAxis.x * sinAngle;
|
||||
y = normalizedAxis.y * sinAngle;
|
||||
z = normalizedAxis.z * sinAngle;
|
||||
|
||||
Normalize();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void NzQuaternion<T>::Set(const NzEulerAngles<T>& angles)
|
||||
{
|
||||
Set(angles.ToQuaternion());
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
template<typename U>
|
||||
void NzQuaternion<T>::Set(const NzQuaternion<U>& quat)
|
||||
{
|
||||
w = static_cast<T>(quat.w);
|
||||
x = static_cast<T>(quat.x);
|
||||
y = static_cast<T>(quat.y);
|
||||
z = static_cast<T>(quat.z);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void NzQuaternion<T>::Set(const NzQuaternion& quat)
|
||||
{
|
||||
w = quat.w;
|
||||
x = quat.x;
|
||||
y = quat.y;
|
||||
z = quat.z;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T NzQuaternion<T>::SquaredMagnitude() const
|
||||
{
|
||||
return w*w + x*x + y*y + z*z;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
NzEulerAngles<T> NzQuaternion<T>::ToEulerAngles() const
|
||||
{
|
||||
T test = x*y + z*w;
|
||||
if (test > F(0.499))
|
||||
// singularity at north pole
|
||||
return NzEulerAngles<T>(NzDegrees(F(90.0)), NzRadians(F(2.0) * std::atan2(x, w)), F(0.0));
|
||||
|
||||
if (test < F(-0.499))
|
||||
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)),
|
||||
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)),
|
||||
NzRadians(std::asin(F(2.0)*test)));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
NzString NzQuaternion<T>::ToString() const
|
||||
{
|
||||
NzStringStream ss;
|
||||
|
||||
return ss << "Quaternion(" << w << " | " << x << ", " << y << ", " << z << ')';
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
NzQuaternion<T>::operator NzString() const
|
||||
{
|
||||
return ToString();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
NzQuaternion<T>& NzQuaternion<T>::operator=(const NzQuaternion& quat)
|
||||
{
|
||||
Set(quat);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
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>
|
||||
NzQuaternion<T> NzQuaternion<T>::operator*(const NzQuaternion& quat) const
|
||||
{
|
||||
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,
|
||||
w*quat.y + y*quat.w + z*quat.x - x*quat.z,
|
||||
w*quat.z + z*quat.w + x*quat.y - y*quat.x);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
NzVector3<T> NzQuaternion<T>::operator*(const NzVector3<T>& vec) const
|
||||
{
|
||||
NzVector3f quatVec(x, y, z);
|
||||
NzVector3f uv = quatVec.CrossProduct(vec);
|
||||
NzVector3f uuv = quatVec.CrossProduct(uv);
|
||||
uv *= F(2.0) * w;
|
||||
uuv *= F(2.0);
|
||||
|
||||
return vec + uv + uuv;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
NzQuaternion<T> NzQuaternion<T>::operator*(T scale) const
|
||||
{
|
||||
return NzQuaternion(w * scale,
|
||||
x * scale,
|
||||
y * scale,
|
||||
z * scale);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
NzQuaternion<T> NzQuaternion<T>::operator/(const NzQuaternion& quat) const
|
||||
{
|
||||
return GetConjugate(quat) * (*this);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
NzQuaternion<T>& NzQuaternion<T>::operator+=(const NzQuaternion& quat)
|
||||
{
|
||||
return operator=(operator+(quat));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
NzQuaternion<T>& NzQuaternion<T>::operator*=(const NzQuaternion& quat)
|
||||
{
|
||||
return operator=(operator*(quat));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
NzQuaternion<T>& NzQuaternion<T>::operator*=(T scale)
|
||||
{
|
||||
return operator=(operator*(scale));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
NzQuaternion<T>& NzQuaternion<T>::operator/=(const NzQuaternion& quat)
|
||||
{
|
||||
return operator=(operator/(quat));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool NzQuaternion<T>::operator==(const NzQuaternion& quat) const
|
||||
{
|
||||
return NzNumberEquals(w, quat.w) &&
|
||||
NzNumberEquals(x, quat.x) &&
|
||||
NzNumberEquals(y, quat.y) &&
|
||||
NzNumberEquals(z, quat.z);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool NzQuaternion<T>::operator!=(const NzQuaternion& quat) const
|
||||
{
|
||||
return !operator==(quat);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool NzQuaternion<T>::operator<(const NzQuaternion& quat) const
|
||||
{
|
||||
return w < quat.w && x < quat.x && y < quat.y && z < quat.z;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool NzQuaternion<T>::operator<=(const NzQuaternion& quat) const
|
||||
{
|
||||
return operator<(quat) || operator==(quat);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool NzQuaternion<T>::operator>(const NzQuaternion& quat) const
|
||||
{
|
||||
return !operator<=(quat);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool NzQuaternion<T>::operator>=(const NzQuaternion& quat) const
|
||||
{
|
||||
return !operator<(quat);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
NzQuaternion<T> NzQuaternion<T>::Identity()
|
||||
{
|
||||
NzQuaternion quaternion;
|
||||
quaternion.MakeIdentity();
|
||||
|
||||
return quaternion;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
NzQuaternion<T> NzQuaternion<T>::Slerp(const NzQuaternion& quatA, const NzQuaternion& quatB, T interp)
|
||||
{
|
||||
if (interp <= F(0.0))
|
||||
return quatA;
|
||||
|
||||
if (interp >= F(1.0))
|
||||
return quatB;
|
||||
|
||||
NzQuaternion q;
|
||||
|
||||
T cosOmega = quatA.DotProduct(quatB);
|
||||
if (cosOmega < F(0.0))
|
||||
{
|
||||
// On inverse tout
|
||||
q.Set(-quatB.w, -quatB.x, -quatB.y, -quatB.z);
|
||||
cosOmega = -cosOmega;
|
||||
}
|
||||
else
|
||||
q.Set(quatB);
|
||||
|
||||
T k0, k1;
|
||||
if (cosOmega > F(0.9999))
|
||||
{
|
||||
// Interpolation linéaire pour éviter une division par zéro
|
||||
k0 = F(1.0) - interp;
|
||||
k1 = interp;
|
||||
}
|
||||
else
|
||||
{
|
||||
T sinOmega = std::sqrt(F(1.0) - cosOmega*cosOmega);
|
||||
T omega = std::atan2(sinOmega, cosOmega);
|
||||
|
||||
// Pour éviter deux divisions
|
||||
sinOmega = F(1.0)/sinOmega;
|
||||
|
||||
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
|
||||
// This file is part of the "Nazara Engine - Mathematics module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef NAZARA_VECTOR2_HPP
|
||||
#define NAZARA_VECTOR2_HPP
|
||||
|
||||
#include <Nazara/Core/String.hpp>
|
||||
|
||||
template<typename T> class NzVector2
|
||||
{
|
||||
public:
|
||||
NzVector2();
|
||||
NzVector2(T X, T Y);
|
||||
explicit NzVector2(T scale);
|
||||
NzVector2(T vec[2]);
|
||||
template<typename U> explicit NzVector2(const NzVector2<U>& vec);
|
||||
NzVector2(const NzVector2& vec) = default;
|
||||
~NzVector2() = default;
|
||||
|
||||
T AbsDotProduct(const NzVector2& vec) const;
|
||||
|
||||
T Distance(const NzVector2& vec) const;
|
||||
float Distancef(const NzVector2& vec) const;
|
||||
|
||||
T DotProduct(const NzVector2& vec) const;
|
||||
|
||||
NzVector2 GetNormal() const;
|
||||
|
||||
void MakeCeil(const NzVector2& vec);
|
||||
void MakeFloor(const NzVector2& vec);
|
||||
void MakeUnitX();
|
||||
void MakeUnitY();
|
||||
void MakeZero();
|
||||
|
||||
T Length() const;
|
||||
float Lengthf() const;
|
||||
|
||||
void Normalize();
|
||||
|
||||
void Set(T X, T Y);
|
||||
void Set(T scale);
|
||||
void Set(T vec[2]);
|
||||
template<typename U> void Set(const NzVector2<U>& vec);
|
||||
|
||||
T SquaredDistance(const NzVector2& vec) const;
|
||||
T SquaredLength() const;
|
||||
|
||||
NzString ToString() const;
|
||||
|
||||
operator NzString() const;
|
||||
|
||||
operator T*();
|
||||
operator const T*() const;
|
||||
|
||||
T& operator[](unsigned int i);
|
||||
T operator[](unsigned int i) 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*(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*=(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;
|
||||
|
||||
static NzVector2 UnitX();
|
||||
static NzVector2 UnitY();
|
||||
static NzVector2 Zero();
|
||||
|
||||
T x, y;
|
||||
};
|
||||
|
||||
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);
|
||||
|
||||
typedef NzVector2<double> NzVector2d;
|
||||
typedef NzVector2<float> NzVector2f;
|
||||
typedef NzVector2<int> NzVector2i;
|
||||
typedef NzVector2<unsigned int> NzVector2ui;
|
||||
|
||||
#include <Nazara/Math/Vector2.inl>
|
||||
|
||||
#endif // NAZARA_VECTOR2_HPP
|
||||
// Copyright (C) 2012 Jérôme Leclercq
|
||||
// This file is part of the "Nazara Engine - Mathematics module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef NAZARA_VECTOR2_HPP
|
||||
#define NAZARA_VECTOR2_HPP
|
||||
|
||||
#include <Nazara/Core/String.hpp>
|
||||
|
||||
template<typename T> class NzVector2
|
||||
{
|
||||
public:
|
||||
NzVector2();
|
||||
NzVector2(T X, T Y);
|
||||
explicit NzVector2(T scale);
|
||||
NzVector2(T vec[2]);
|
||||
template<typename U> explicit NzVector2(const NzVector2<U>& vec);
|
||||
NzVector2(const NzVector2& vec) = default;
|
||||
~NzVector2() = default;
|
||||
|
||||
T AbsDotProduct(const NzVector2& vec) const;
|
||||
|
||||
T Distance(const NzVector2& vec) const;
|
||||
float Distancef(const NzVector2& vec) const;
|
||||
|
||||
T DotProduct(const NzVector2& vec) const;
|
||||
|
||||
NzVector2 GetNormal() const;
|
||||
|
||||
T Length() const;
|
||||
float Lengthf() const;
|
||||
|
||||
void MakeUnitX();
|
||||
void MakeUnitY();
|
||||
void MakeZero();
|
||||
|
||||
void Maximize(const NzVector2& vec);
|
||||
void Minimize(const NzVector2& vec);
|
||||
|
||||
void Normalize();
|
||||
|
||||
void Set(T X, T Y);
|
||||
void Set(T scale);
|
||||
void Set(T vec[2]);
|
||||
template<typename U> void Set(const NzVector2<U>& vec);
|
||||
|
||||
T SquaredDistance(const NzVector2& vec) const;
|
||||
T SquaredLength() const;
|
||||
|
||||
NzString ToString() const;
|
||||
|
||||
operator NzString() const;
|
||||
|
||||
operator T*();
|
||||
operator const T*() const;
|
||||
|
||||
T& operator[](unsigned int i);
|
||||
T operator[](unsigned int i) 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*(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*=(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;
|
||||
|
||||
static NzVector2 UnitX();
|
||||
static NzVector2 UnitY();
|
||||
static NzVector2 Zero();
|
||||
|
||||
T x, y;
|
||||
};
|
||||
|
||||
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);
|
||||
|
||||
typedef NzVector2<double> NzVector2d;
|
||||
typedef NzVector2<float> NzVector2f;
|
||||
typedef NzVector2<int> NzVector2i;
|
||||
typedef NzVector2<unsigned int> NzVector2ui;
|
||||
|
||||
#include <Nazara/Math/Vector2.inl>
|
||||
|
||||
#endif // NAZARA_VECTOR2_HPP
|
||||
|
|
|
|||
|
|
@ -1,488 +1,488 @@
|
|||
// Copyright (C) 2012 Jérôme Leclercq
|
||||
// This file is part of the "Nazara Engine - Mathematics module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#include <Nazara/Core/StringStream.hpp>
|
||||
#include <Nazara/Math/Basic.hpp>
|
||||
#include <cmath>
|
||||
#include <cstdlib>
|
||||
#include <limits>
|
||||
#include <stdexcept>
|
||||
#include <Nazara/Core/Debug.hpp>
|
||||
|
||||
#define F(a) static_cast<T>(a)
|
||||
|
||||
template<typename T>
|
||||
NzVector2<T>::NzVector2()
|
||||
{
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
NzVector2<T>::NzVector2(T X, T Y)
|
||||
{
|
||||
Set(X, Y);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
NzVector2<T>::NzVector2(T scale)
|
||||
{
|
||||
Set(scale);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
NzVector2<T>::NzVector2(T vec[2])
|
||||
{
|
||||
Set(vec);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
template<typename U>
|
||||
NzVector2<T>::NzVector2(const NzVector2<U>& vec)
|
||||
{
|
||||
Set(vec);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T NzVector2<T>::AbsDotProduct(const NzVector2& vec) const
|
||||
{
|
||||
return std::fabs(x * vec.x) + std::fabs(y * vec.y);
|
||||
}
|
||||
|
||||
template<>
|
||||
inline int NzVector2<int>::AbsDotProduct(const NzVector2<int>& vec) const
|
||||
{
|
||||
return std::labs(x * vec.x) + std::labs(y * vec.y);
|
||||
}
|
||||
|
||||
template<>
|
||||
inline unsigned int NzVector2<unsigned int>::AbsDotProduct(const NzVector2<unsigned int>& vec) const
|
||||
{
|
||||
return std::labs(x * vec.x) + std::labs(y * vec.y);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T NzVector2<T>::Distance(const NzVector2& vec) const
|
||||
{
|
||||
return std::sqrt(SquaredDistance(vec));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
float NzVector2<T>::Distancef(const NzVector2& vec) const
|
||||
{
|
||||
return std::sqrt(static_cast<float>(SquaredDistance(vec)));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T NzVector2<T>::DotProduct(const NzVector2& vec) const
|
||||
{
|
||||
return x*vec.x + y*vec.y;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
NzVector2<T> NzVector2<T>::GetNormal() const
|
||||
{
|
||||
NzVector2 vec(*this);
|
||||
vec.Normalize();
|
||||
|
||||
return vec;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T NzVector2<T>::Length() const
|
||||
{
|
||||
return std::sqrt(SquaredLength());
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
float NzVector2<T>::Lengthf() const
|
||||
{
|
||||
return std::sqrt(static_cast<float>(SquaredLength()));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void NzVector2<T>::MakeCeil(const NzVector2& vec)
|
||||
{
|
||||
if (vec.x > x)
|
||||
x = vec.x;
|
||||
|
||||
if (vec.y > y)
|
||||
y = vec.y;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void NzVector2<T>::MakeFloor(const NzVector2& vec)
|
||||
{
|
||||
if (vec.x < x)
|
||||
x = vec.x;
|
||||
|
||||
if (vec.y < y)
|
||||
y = vec.y;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void NzVector2<T>::MakeUnitX()
|
||||
{
|
||||
Set(F(1.0), F(0.0));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void NzVector2<T>::MakeUnitY()
|
||||
{
|
||||
Set(F(0.0), F(1.0));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void NzVector2<T>::MakeZero()
|
||||
{
|
||||
Set(F(0.0), F(0.0));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void NzVector2<T>::Normalize()
|
||||
{
|
||||
T squaredLength = SquaredLength();
|
||||
|
||||
if (squaredLength-F(1.0) > std::numeric_limits<T>::epsilon())
|
||||
{
|
||||
T length = std::sqrt(squaredLength);
|
||||
|
||||
x /= length;
|
||||
y /= length;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void NzVector2<T>::Set(T X, T Y)
|
||||
{
|
||||
x = X;
|
||||
y = Y;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void NzVector2<T>::Set(T scale)
|
||||
{
|
||||
x = scale;
|
||||
y = scale;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void NzVector2<T>::Set(T vec[2])
|
||||
{
|
||||
std::memcpy(&x, vec, 2*sizeof(T));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
template<typename U>
|
||||
void NzVector2<T>::Set(const NzVector2<U>& vec)
|
||||
{
|
||||
x = F(vec.x);
|
||||
y = F(vec.y);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T NzVector2<T>::SquaredDistance(const NzVector2& vec) const
|
||||
{
|
||||
return operator-(vec).SquaredLength();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T NzVector2<T>::SquaredLength() const
|
||||
{
|
||||
return x*x + y*y;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
NzString NzVector2<T>::ToString() const
|
||||
{
|
||||
NzStringStream ss;
|
||||
|
||||
return ss << "Vector2(" << x << ", " << y << ')';
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
NzVector2<T>::operator NzString() const
|
||||
{
|
||||
return ToString();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
NzVector2<T>::operator T*()
|
||||
{
|
||||
return &x;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
NzVector2<T>::operator const T*() const
|
||||
{
|
||||
return &x;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T& NzVector2<T>::operator[](unsigned int i)
|
||||
{
|
||||
#if NAZARA_MATH_SAFE
|
||||
if (i >= 2)
|
||||
{
|
||||
NzStringStream ss;
|
||||
ss << __FILE__ << ':' << __LINE__ << ": Index out of range (" << i << " >= 2)";
|
||||
|
||||
throw std::domain_error(ss.ToString());
|
||||
}
|
||||
#endif
|
||||
|
||||
return *(&x+i);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T NzVector2<T>::operator[](unsigned int i) const
|
||||
{
|
||||
#if NAZARA_MATH_SAFE
|
||||
if (i >= 2)
|
||||
{
|
||||
NzStringStream ss;
|
||||
ss << __FILE__ << ':' << __LINE__ << ": Index out of range (" << i << " >= 2)";
|
||||
|
||||
throw std::domain_error(ss.ToString());
|
||||
}
|
||||
#endif
|
||||
|
||||
return *(&x+i);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
const NzVector2<T>& NzVector2<T>::operator+() const
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
NzVector2<T> NzVector2<T>::operator-() const
|
||||
{
|
||||
return NzVector2(-x, -y);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
NzVector2<T> NzVector2<T>::operator+(const NzVector2& vec) const
|
||||
{
|
||||
return NzVector2(x + vec.x, y + vec.y);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
NzVector2<T> NzVector2<T>::operator-(const NzVector2& vec) const
|
||||
{
|
||||
return NzVector2(x - vec.x, y - vec.y);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
NzVector2<T> NzVector2<T>::operator*(const NzVector2& vec) const
|
||||
{
|
||||
return NzVector2(x * vec.x, y * vec.y);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
NzVector2<T> NzVector2<T>::operator*(T scale) const
|
||||
{
|
||||
return NzVector2(x * scale, y * scale);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
NzVector2<T> NzVector2<T>::operator/(const NzVector2& vec) const
|
||||
{
|
||||
#if NAZARA_MATH_SAFE
|
||||
if (NzNumberEquals(vec.x, F(0.0)) || NzNumberEquals(vec.y, F(0.0)))
|
||||
{
|
||||
NzStringStream ss;
|
||||
ss << __FILE__ << ':' << __LINE__ << ": Division by zero";
|
||||
|
||||
throw std::domain_error(ss.ToString());
|
||||
}
|
||||
#endif
|
||||
|
||||
return NzVector2(x / vec.x, y / vec.y);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
NzVector2<T> NzVector2<T>::operator/(T scale) const
|
||||
{
|
||||
#if NAZARA_MATH_SAFE
|
||||
if (NzNumberEquals(scale, F(0.0)))
|
||||
{
|
||||
NzStringStream ss;
|
||||
ss << __FILE__ << ':' << __LINE__ << ": Division by zero";
|
||||
|
||||
throw std::domain_error(ss.ToString());
|
||||
}
|
||||
#endif
|
||||
|
||||
return NzVector2(x / scale, y / scale);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
NzVector2<T>& NzVector2<T>::operator+=(const NzVector2& vec)
|
||||
{
|
||||
x += vec.x;
|
||||
y += vec.y;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
NzVector2<T>& NzVector2<T>::operator-=(const NzVector2& vec)
|
||||
{
|
||||
x -= vec.x;
|
||||
y -= vec.y;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
NzVector2<T>& NzVector2<T>::operator*=(const NzVector2& vec)
|
||||
{
|
||||
x *= vec.x;
|
||||
y *= vec.y;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
NzVector2<T>& NzVector2<T>::operator*=(T scale)
|
||||
{
|
||||
x *= scale;
|
||||
y *= scale;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
NzVector2<T>& NzVector2<T>::operator/=(const NzVector2& vec)
|
||||
{
|
||||
#if NAZARA_MATH_SAFE
|
||||
if (NzNumberEquals(vec.x, F(0.0)) || NzNumberEquals(vec.y, F(0.0)) || NzNumberEquals(vec.z, F(0.0)))
|
||||
{
|
||||
NzStringStream ss;
|
||||
ss << __FILE__ << ':' << __LINE__ << ": Division by zero";
|
||||
|
||||
throw std::domain_error(ss.ToString());
|
||||
}
|
||||
#endif
|
||||
|
||||
x /= vec.x;
|
||||
y /= vec.y;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
NzVector2<T>& NzVector2<T>::operator/=(T scale)
|
||||
{
|
||||
#if NAZARA_MATH_SAFE
|
||||
if (NzNumberEquals(scale, F(0.0)))
|
||||
{
|
||||
NzStringStream ss;
|
||||
ss << __FILE__ << ':' << __LINE__ << ": Division by zero";
|
||||
|
||||
throw std::domain_error(ss.ToString());
|
||||
}
|
||||
#endif
|
||||
|
||||
x /= scale;
|
||||
y /= scale;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool NzVector2<T>::operator==(const NzVector2& vec) const
|
||||
{
|
||||
return NzNumberEquals(x, vec.x) &&
|
||||
NzNumberEquals(y, vec.y);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool NzVector2<T>::operator!=(const NzVector2& vec) const
|
||||
{
|
||||
return !operator==(vec);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool NzVector2<T>::operator<(const NzVector2& vec) const
|
||||
{
|
||||
return x < vec.x && y < vec.y;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool NzVector2<T>::operator<=(const NzVector2& vec) const
|
||||
{
|
||||
return operator<(vec) || operator==(vec);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool NzVector2<T>::operator>(const NzVector2& vec) const
|
||||
{
|
||||
return !operator<=(vec);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool NzVector2<T>::operator>=(const NzVector2& vec) const
|
||||
{
|
||||
return !operator<(vec);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
NzVector2<T> NzVector2<T>::UnitX()
|
||||
{
|
||||
NzVector2 vector;
|
||||
vector.MakeUnitX();
|
||||
|
||||
return vector;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
NzVector2<T> NzVector2<T>::UnitY()
|
||||
{
|
||||
NzVector2 vector;
|
||||
vector.MakeUnitY();
|
||||
|
||||
return vector;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
NzVector2<T> NzVector2<T>::Zero()
|
||||
{
|
||||
NzVector2 vector;
|
||||
vector.MakeZero();
|
||||
|
||||
return vector;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
std::ostream& operator<<(std::ostream& out, const NzVector2<T>& vec)
|
||||
{
|
||||
return out << vec.ToString();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
NzVector2<T> operator*(T scale, const NzVector2<T>& vec)
|
||||
{
|
||||
return NzVector2<T>(scale * vec.x, scale * vec.y);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
NzVector2<T> operator/(T scale, const NzVector2<T>& vec)
|
||||
{
|
||||
#if NAZARA_MATH_SAFE
|
||||
if (NzNumberEquals(vec.x, F(0.0)) || NzNumberEquals(vec.y, F(0.0)) || NzNumberEquals(vec.z, F(0.0)))
|
||||
{
|
||||
NzStringStream ss;
|
||||
ss << __FILE__ << ':' << __LINE__ << ": Division by zero";
|
||||
|
||||
throw std::domain_error(ss.ToString());
|
||||
}
|
||||
#endif
|
||||
|
||||
return NzVector2<T>(scale/vec.x, scale/vec.y);
|
||||
}
|
||||
|
||||
#undef F
|
||||
|
||||
#include <Nazara/Core/DebugOff.hpp>
|
||||
// Copyright (C) 2012 Jérôme Leclercq
|
||||
// This file is part of the "Nazara Engine - Mathematics module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#include <Nazara/Core/StringStream.hpp>
|
||||
#include <Nazara/Math/Basic.hpp>
|
||||
#include <cmath>
|
||||
#include <cstdlib>
|
||||
#include <limits>
|
||||
#include <stdexcept>
|
||||
#include <Nazara/Core/Debug.hpp>
|
||||
|
||||
#define F(a) static_cast<T>(a)
|
||||
|
||||
template<typename T>
|
||||
NzVector2<T>::NzVector2()
|
||||
{
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
NzVector2<T>::NzVector2(T X, T Y)
|
||||
{
|
||||
Set(X, Y);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
NzVector2<T>::NzVector2(T scale)
|
||||
{
|
||||
Set(scale);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
NzVector2<T>::NzVector2(T vec[2])
|
||||
{
|
||||
Set(vec);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
template<typename U>
|
||||
NzVector2<T>::NzVector2(const NzVector2<U>& vec)
|
||||
{
|
||||
Set(vec);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T NzVector2<T>::AbsDotProduct(const NzVector2& vec) const
|
||||
{
|
||||
return std::fabs(x * vec.x) + std::fabs(y * vec.y);
|
||||
}
|
||||
|
||||
template<>
|
||||
inline int NzVector2<int>::AbsDotProduct(const NzVector2<int>& vec) const
|
||||
{
|
||||
return std::labs(x * vec.x) + std::labs(y * vec.y);
|
||||
}
|
||||
|
||||
template<>
|
||||
inline unsigned int NzVector2<unsigned int>::AbsDotProduct(const NzVector2<unsigned int>& vec) const
|
||||
{
|
||||
return std::labs(x * vec.x) + std::labs(y * vec.y);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T NzVector2<T>::Distance(const NzVector2& vec) const
|
||||
{
|
||||
return std::sqrt(SquaredDistance(vec));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
float NzVector2<T>::Distancef(const NzVector2& vec) const
|
||||
{
|
||||
return std::sqrt(static_cast<float>(SquaredDistance(vec)));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T NzVector2<T>::DotProduct(const NzVector2& vec) const
|
||||
{
|
||||
return x*vec.x + y*vec.y;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
NzVector2<T> NzVector2<T>::GetNormal() const
|
||||
{
|
||||
NzVector2 vec(*this);
|
||||
vec.Normalize();
|
||||
|
||||
return vec;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T NzVector2<T>::Length() const
|
||||
{
|
||||
return std::sqrt(SquaredLength());
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
float NzVector2<T>::Lengthf() const
|
||||
{
|
||||
return std::sqrt(static_cast<float>(SquaredLength()));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void NzVector2<T>::MakeUnitX()
|
||||
{
|
||||
Set(F(1.0), F(0.0));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void NzVector2<T>::MakeUnitY()
|
||||
{
|
||||
Set(F(0.0), F(1.0));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void NzVector2<T>::MakeZero()
|
||||
{
|
||||
Set(F(0.0), F(0.0));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void NzVector2<T>::Maximize(const NzVector2& vec)
|
||||
{
|
||||
if (vec.x > x)
|
||||
x = vec.x;
|
||||
|
||||
if (vec.y > y)
|
||||
y = vec.y;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void NzVector2<T>::Minimize(const NzVector2& vec)
|
||||
{
|
||||
if (vec.x < x)
|
||||
x = vec.x;
|
||||
|
||||
if (vec.y < y)
|
||||
y = vec.y;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void NzVector2<T>::Normalize()
|
||||
{
|
||||
T squaredLength = SquaredLength();
|
||||
|
||||
if (squaredLength-F(1.0) > std::numeric_limits<T>::epsilon())
|
||||
{
|
||||
T length = std::sqrt(squaredLength);
|
||||
|
||||
x /= length;
|
||||
y /= length;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void NzVector2<T>::Set(T X, T Y)
|
||||
{
|
||||
x = X;
|
||||
y = Y;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void NzVector2<T>::Set(T scale)
|
||||
{
|
||||
x = scale;
|
||||
y = scale;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void NzVector2<T>::Set(T vec[2])
|
||||
{
|
||||
std::memcpy(&x, vec, 2*sizeof(T));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
template<typename U>
|
||||
void NzVector2<T>::Set(const NzVector2<U>& vec)
|
||||
{
|
||||
x = F(vec.x);
|
||||
y = F(vec.y);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T NzVector2<T>::SquaredDistance(const NzVector2& vec) const
|
||||
{
|
||||
return operator-(vec).SquaredLength();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T NzVector2<T>::SquaredLength() const
|
||||
{
|
||||
return x*x + y*y;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
NzString NzVector2<T>::ToString() const
|
||||
{
|
||||
NzStringStream ss;
|
||||
|
||||
return ss << "Vector2(" << x << ", " << y << ')';
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
NzVector2<T>::operator NzString() const
|
||||
{
|
||||
return ToString();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
NzVector2<T>::operator T*()
|
||||
{
|
||||
return &x;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
NzVector2<T>::operator const T*() const
|
||||
{
|
||||
return &x;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T& NzVector2<T>::operator[](unsigned int i)
|
||||
{
|
||||
#if NAZARA_MATH_SAFE
|
||||
if (i >= 2)
|
||||
{
|
||||
NzStringStream ss;
|
||||
ss << __FILE__ << ':' << __LINE__ << ": Index out of range (" << i << " >= 2)";
|
||||
|
||||
throw std::domain_error(ss.ToString());
|
||||
}
|
||||
#endif
|
||||
|
||||
return *(&x+i);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T NzVector2<T>::operator[](unsigned int i) const
|
||||
{
|
||||
#if NAZARA_MATH_SAFE
|
||||
if (i >= 2)
|
||||
{
|
||||
NzStringStream ss;
|
||||
ss << __FILE__ << ':' << __LINE__ << ": Index out of range (" << i << " >= 2)";
|
||||
|
||||
throw std::domain_error(ss.ToString());
|
||||
}
|
||||
#endif
|
||||
|
||||
return *(&x+i);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
const NzVector2<T>& NzVector2<T>::operator+() const
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
NzVector2<T> NzVector2<T>::operator-() const
|
||||
{
|
||||
return NzVector2(-x, -y);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
NzVector2<T> NzVector2<T>::operator+(const NzVector2& vec) const
|
||||
{
|
||||
return NzVector2(x + vec.x, y + vec.y);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
NzVector2<T> NzVector2<T>::operator-(const NzVector2& vec) const
|
||||
{
|
||||
return NzVector2(x - vec.x, y - vec.y);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
NzVector2<T> NzVector2<T>::operator*(const NzVector2& vec) const
|
||||
{
|
||||
return NzVector2(x * vec.x, y * vec.y);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
NzVector2<T> NzVector2<T>::operator*(T scale) const
|
||||
{
|
||||
return NzVector2(x * scale, y * scale);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
NzVector2<T> NzVector2<T>::operator/(const NzVector2& vec) const
|
||||
{
|
||||
#if NAZARA_MATH_SAFE
|
||||
if (NzNumberEquals(vec.x, F(0.0)) || NzNumberEquals(vec.y, F(0.0)))
|
||||
{
|
||||
NzStringStream ss;
|
||||
ss << __FILE__ << ':' << __LINE__ << ": Division by zero";
|
||||
|
||||
throw std::domain_error(ss.ToString());
|
||||
}
|
||||
#endif
|
||||
|
||||
return NzVector2(x / vec.x, y / vec.y);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
NzVector2<T> NzVector2<T>::operator/(T scale) const
|
||||
{
|
||||
#if NAZARA_MATH_SAFE
|
||||
if (NzNumberEquals(scale, F(0.0)))
|
||||
{
|
||||
NzStringStream ss;
|
||||
ss << __FILE__ << ':' << __LINE__ << ": Division by zero";
|
||||
|
||||
throw std::domain_error(ss.ToString());
|
||||
}
|
||||
#endif
|
||||
|
||||
return NzVector2(x / scale, y / scale);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
NzVector2<T>& NzVector2<T>::operator+=(const NzVector2& vec)
|
||||
{
|
||||
x += vec.x;
|
||||
y += vec.y;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
NzVector2<T>& NzVector2<T>::operator-=(const NzVector2& vec)
|
||||
{
|
||||
x -= vec.x;
|
||||
y -= vec.y;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
NzVector2<T>& NzVector2<T>::operator*=(const NzVector2& vec)
|
||||
{
|
||||
x *= vec.x;
|
||||
y *= vec.y;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
NzVector2<T>& NzVector2<T>::operator*=(T scale)
|
||||
{
|
||||
x *= scale;
|
||||
y *= scale;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
NzVector2<T>& NzVector2<T>::operator/=(const NzVector2& vec)
|
||||
{
|
||||
#if NAZARA_MATH_SAFE
|
||||
if (NzNumberEquals(vec.x, F(0.0)) || NzNumberEquals(vec.y, F(0.0)) || NzNumberEquals(vec.z, F(0.0)))
|
||||
{
|
||||
NzStringStream ss;
|
||||
ss << __FILE__ << ':' << __LINE__ << ": Division by zero";
|
||||
|
||||
throw std::domain_error(ss.ToString());
|
||||
}
|
||||
#endif
|
||||
|
||||
x /= vec.x;
|
||||
y /= vec.y;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
NzVector2<T>& NzVector2<T>::operator/=(T scale)
|
||||
{
|
||||
#if NAZARA_MATH_SAFE
|
||||
if (NzNumberEquals(scale, F(0.0)))
|
||||
{
|
||||
NzStringStream ss;
|
||||
ss << __FILE__ << ':' << __LINE__ << ": Division by zero";
|
||||
|
||||
throw std::domain_error(ss.ToString());
|
||||
}
|
||||
#endif
|
||||
|
||||
x /= scale;
|
||||
y /= scale;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool NzVector2<T>::operator==(const NzVector2& vec) const
|
||||
{
|
||||
return NzNumberEquals(x, vec.x) &&
|
||||
NzNumberEquals(y, vec.y);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool NzVector2<T>::operator!=(const NzVector2& vec) const
|
||||
{
|
||||
return !operator==(vec);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool NzVector2<T>::operator<(const NzVector2& vec) const
|
||||
{
|
||||
return x < vec.x && y < vec.y;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool NzVector2<T>::operator<=(const NzVector2& vec) const
|
||||
{
|
||||
return operator<(vec) || operator==(vec);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool NzVector2<T>::operator>(const NzVector2& vec) const
|
||||
{
|
||||
return !operator<=(vec);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool NzVector2<T>::operator>=(const NzVector2& vec) const
|
||||
{
|
||||
return !operator<(vec);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
NzVector2<T> NzVector2<T>::UnitX()
|
||||
{
|
||||
NzVector2 vector;
|
||||
vector.MakeUnitX();
|
||||
|
||||
return vector;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
NzVector2<T> NzVector2<T>::UnitY()
|
||||
{
|
||||
NzVector2 vector;
|
||||
vector.MakeUnitY();
|
||||
|
||||
return vector;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
NzVector2<T> NzVector2<T>::Zero()
|
||||
{
|
||||
NzVector2 vector;
|
||||
vector.MakeZero();
|
||||
|
||||
return vector;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
std::ostream& operator<<(std::ostream& out, const NzVector2<T>& vec)
|
||||
{
|
||||
return out << vec.ToString();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
NzVector2<T> operator*(T scale, const NzVector2<T>& vec)
|
||||
{
|
||||
return NzVector2<T>(scale * vec.x, scale * vec.y);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
NzVector2<T> operator/(T scale, const NzVector2<T>& vec)
|
||||
{
|
||||
#if NAZARA_MATH_SAFE
|
||||
if (NzNumberEquals(vec.x, F(0.0)) || NzNumberEquals(vec.y, F(0.0)) || NzNumberEquals(vec.z, F(0.0)))
|
||||
{
|
||||
NzStringStream ss;
|
||||
ss << __FILE__ << ':' << __LINE__ << ": Division by zero";
|
||||
|
||||
throw std::domain_error(ss.ToString());
|
||||
}
|
||||
#endif
|
||||
|
||||
return NzVector2<T>(scale/vec.x, scale/vec.y);
|
||||
}
|
||||
|
||||
#undef F
|
||||
|
||||
#include <Nazara/Core/DebugOff.hpp>
|
||||
|
|
|
|||
|
|
@ -1,111 +1,121 @@
|
|||
// Copyright (C) 2012 Rémi Bèges - Jérôme Leclercq
|
||||
// This file is part of the "Nazara Engine - Mathematics module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef NAZARA_VECTOR3_HPP
|
||||
#define NAZARA_VECTOR3_HPP
|
||||
|
||||
#include <Nazara/Core/String.hpp>
|
||||
#include <Nazara/Math/Vector2.hpp>
|
||||
|
||||
template<typename T> class NzVector3
|
||||
{
|
||||
public:
|
||||
NzVector3();
|
||||
NzVector3(T X, T Y, T Z);
|
||||
explicit NzVector3(T scale);
|
||||
NzVector3(T vec[3]);
|
||||
NzVector3(const NzVector2<T>& vec, T Z = 0.0);
|
||||
template<typename U> explicit NzVector3(const NzVector3<U>& vec);
|
||||
NzVector3(const NzVector3& vec) = default;
|
||||
~NzVector3() = default;
|
||||
|
||||
T AbsDotProduct(const NzVector3& vec) const;
|
||||
|
||||
NzVector3 CrossProduct(const NzVector3& vec) const;
|
||||
|
||||
T Distance(const NzVector3& vec) const;
|
||||
float Distancef(const NzVector3& vec) const;
|
||||
|
||||
T DotProduct(const NzVector3& vec) const;
|
||||
|
||||
NzVector3 GetNormal() const;
|
||||
|
||||
T Length() const;
|
||||
float Lengthf() const;
|
||||
|
||||
void MakeCeil(const NzVector3& vec);
|
||||
void MakeFloor(const NzVector3& vec);
|
||||
void MakeUnitX();
|
||||
void MakeUnitY();
|
||||
void MakeUnitZ();
|
||||
void MakeZero();
|
||||
|
||||
void Normalize();
|
||||
|
||||
void Set(T X, T Y, T Z);
|
||||
void Set(T scale);
|
||||
void Set(T vec[3]);
|
||||
void Set(const NzVector2<T>& vec, T Z = 0.0);
|
||||
template<typename U> void Set(const NzVector3<U>& vec);
|
||||
|
||||
T SquaredDistance(const NzVector3& vec) const;
|
||||
T SquaredLength() const;
|
||||
|
||||
NzString ToString() const;
|
||||
|
||||
operator NzString() const;
|
||||
|
||||
operator T*();
|
||||
operator const T*() const;
|
||||
|
||||
T& operator[](unsigned int i);
|
||||
T operator[](unsigned int i) const;
|
||||
|
||||
const NzVector3& operator+() const;
|
||||
NzVector3 operator-() const;
|
||||
|
||||
NzVector3 operator+(const NzVector3& vec) 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/(T scale) const;
|
||||
|
||||
NzVector3& operator+=(const NzVector3& vec);
|
||||
NzVector3& operator-=(const NzVector3& vec);
|
||||
NzVector3& operator*=(const NzVector3& vec);
|
||||
NzVector3& operator*=(T scale);
|
||||
NzVector3& operator/=(const NzVector3& vec);
|
||||
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();
|
||||
static NzVector3 UnitY();
|
||||
static NzVector3 UnitZ();
|
||||
static NzVector3 Zero();
|
||||
|
||||
T x, y, z;
|
||||
};
|
||||
|
||||
template<typename T> std::ostream& operator<<(std::ostream& out, const NzVector3<T>& vec);
|
||||
|
||||
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
|
||||
// Copyright (C) 2012 Rémi Bèges - Jérôme Leclercq
|
||||
// This file is part of the "Nazara Engine - Mathematics module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef NAZARA_VECTOR3_HPP
|
||||
#define NAZARA_VECTOR3_HPP
|
||||
|
||||
#include <Nazara/Core/String.hpp>
|
||||
#include <Nazara/Math/Vector2.hpp>
|
||||
|
||||
template<typename T> class NzVector3
|
||||
{
|
||||
public:
|
||||
NzVector3();
|
||||
NzVector3(T X, T Y, T Z);
|
||||
explicit NzVector3(T scale);
|
||||
NzVector3(T vec[3]);
|
||||
NzVector3(const NzVector2<T>& vec, T Z = 0.0);
|
||||
template<typename U> explicit NzVector3(const NzVector3<U>& vec);
|
||||
NzVector3(const NzVector3& vec) = default;
|
||||
~NzVector3() = default;
|
||||
|
||||
T AbsDotProduct(const NzVector3& vec) const;
|
||||
|
||||
NzVector3 CrossProduct(const NzVector3& vec) const;
|
||||
|
||||
T Distance(const NzVector3& vec) const;
|
||||
float Distancef(const NzVector3& vec) const;
|
||||
|
||||
T DotProduct(const NzVector3& vec) const;
|
||||
|
||||
NzVector3 GetNormal() const;
|
||||
|
||||
T Length() const;
|
||||
float Lengthf() const;
|
||||
|
||||
void MakeForward();
|
||||
void MakeLeft();
|
||||
void MakeUnitX();
|
||||
void MakeUnitY();
|
||||
void MakeUnitZ();
|
||||
void MakeUp();
|
||||
void MakeZero();
|
||||
|
||||
void Maximize(const NzVector3& vec);
|
||||
void Minimize(const NzVector3& vec);
|
||||
|
||||
void Normalize();
|
||||
|
||||
void Set(T X, T Y, T Z);
|
||||
void Set(T scale);
|
||||
void Set(T vec[3]);
|
||||
void Set(const NzVector2<T>& vec, T Z = 0.0);
|
||||
template<typename U> void Set(const NzVector3<U>& vec);
|
||||
|
||||
T SquaredDistance(const NzVector3& vec) const;
|
||||
T SquaredLength() const;
|
||||
|
||||
NzString ToString() const;
|
||||
|
||||
operator NzString() const;
|
||||
|
||||
operator T*();
|
||||
operator const T*() const;
|
||||
|
||||
T& operator[](unsigned int i);
|
||||
T operator[](unsigned int i) const;
|
||||
|
||||
const NzVector3& operator+() const;
|
||||
NzVector3 operator-() const;
|
||||
|
||||
NzVector3 operator+(const NzVector3& vec) 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/(T scale) const;
|
||||
|
||||
NzVector3& operator+=(const NzVector3& vec);
|
||||
NzVector3& operator-=(const NzVector3& vec);
|
||||
NzVector3& operator*=(const NzVector3& vec);
|
||||
NzVector3& operator*=(T scale);
|
||||
NzVector3& operator/=(const NzVector3& vec);
|
||||
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 CrossProduct(const NzVector3& vec1, const NzVector3& vec2);
|
||||
static T DotProduct(const NzVector3& vec1, const NzVector3& vec2);
|
||||
static NzVector3 Forward();
|
||||
static NzVector3 Left();
|
||||
static NzVector3 Normalize(const NzVector3& vec);
|
||||
static NzVector3 UnitX();
|
||||
static NzVector3 UnitY();
|
||||
static NzVector3 UnitZ();
|
||||
static NzVector3 Up();
|
||||
static NzVector3 Zero();
|
||||
|
||||
T x, y, z;
|
||||
};
|
||||
|
||||
template<typename T> std::ostream& operator<<(std::ostream& out, const NzVector3<T>& vec);
|
||||
|
||||
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
|
||||
// This file is part of the "Nazara Engine - Mathematics module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef NAZARA_VECTOR4_HPP
|
||||
#define NAZARA_VECTOR4_HPP
|
||||
|
||||
#include <Nazara/Core/String.hpp>
|
||||
#include <Nazara/Math/Vector3.hpp>
|
||||
|
||||
template<typename T> class NzVector4
|
||||
{
|
||||
public:
|
||||
NzVector4();
|
||||
NzVector4(T X, T Y, T Z, T W = 1.0);
|
||||
explicit NzVector4(T scale);
|
||||
NzVector4(T vec[4]);
|
||||
NzVector4(const NzVector3<T>& vec, T W = 1.0);
|
||||
template<typename U> explicit NzVector4(const NzVector4<U>& vec);
|
||||
NzVector4(const NzVector4& vec) = default;
|
||||
~NzVector4() = default;
|
||||
|
||||
T AbsDotProduct(const NzVector4& vec) const;
|
||||
|
||||
T DotProduct(const NzVector4& vec) const;
|
||||
|
||||
void MakeCeil(const NzVector4& vec);
|
||||
void MakeFloor(const NzVector4& vec);
|
||||
void MakeUnitX();
|
||||
void MakeUnitY();
|
||||
void MakeUnitZ();
|
||||
void MakeZero();
|
||||
|
||||
void Normalize();
|
||||
|
||||
void Set(T X, T Y, T Z, T W = 1.0);
|
||||
void Set(T scale);
|
||||
void Set(T vec[4]);
|
||||
void Set(const NzVector3<T>& vec, T W = 1.0);
|
||||
template<typename U> void Set(const NzVector4<U>& vec);
|
||||
|
||||
NzString ToString() const;
|
||||
|
||||
operator NzString() const;
|
||||
|
||||
operator T*();
|
||||
operator const T*() const;
|
||||
|
||||
T& operator[](unsigned int i);
|
||||
T operator[](unsigned int i) 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*(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*=(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;
|
||||
|
||||
static NzVector4 UnitX();
|
||||
static NzVector4 UnitY();
|
||||
static NzVector4 UnitZ();
|
||||
static NzVector4 Zero();
|
||||
|
||||
T x, y, z, w;
|
||||
};
|
||||
|
||||
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);
|
||||
|
||||
typedef NzVector4<double> NzVector4d;
|
||||
typedef NzVector4<float> NzVector4f;
|
||||
typedef NzVector4<int> NzVector4i;
|
||||
|
||||
#include <Nazara/Math/Vector4.inl>
|
||||
|
||||
#endif // NAZARA_VECTOR4_HPP
|
||||
// Copyright (C) 2012 Rémi Bèges - Jérôme Leclercq
|
||||
// This file is part of the "Nazara Engine - Mathematics module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef NAZARA_VECTOR4_HPP
|
||||
#define NAZARA_VECTOR4_HPP
|
||||
|
||||
#include <Nazara/Core/String.hpp>
|
||||
#include <Nazara/Math/Vector3.hpp>
|
||||
|
||||
template<typename T> class NzVector4
|
||||
{
|
||||
public:
|
||||
NzVector4();
|
||||
NzVector4(T X, T Y, T Z, T W = 1.0);
|
||||
explicit NzVector4(T scale);
|
||||
NzVector4(T vec[4]);
|
||||
NzVector4(const NzVector3<T>& vec, T W = 1.0);
|
||||
template<typename U> explicit NzVector4(const NzVector4<U>& vec);
|
||||
NzVector4(const NzVector4& vec) = default;
|
||||
~NzVector4() = default;
|
||||
|
||||
T AbsDotProduct(const NzVector4& vec) const;
|
||||
|
||||
T DotProduct(const NzVector4& vec) const;
|
||||
|
||||
void MakeUnitX();
|
||||
void MakeUnitY();
|
||||
void MakeUnitZ();
|
||||
void MakeZero();
|
||||
|
||||
void Maximize(const NzVector4& vec);
|
||||
void Minimize(const NzVector4& vec);
|
||||
|
||||
void Normalize();
|
||||
|
||||
void Set(T X, T Y, T Z, T W = 1.0);
|
||||
void Set(T scale);
|
||||
void Set(T vec[4]);
|
||||
void Set(const NzVector3<T>& vec, T W = 1.0);
|
||||
template<typename U> void Set(const NzVector4<U>& vec);
|
||||
|
||||
NzString ToString() const;
|
||||
|
||||
operator NzString() const;
|
||||
|
||||
operator T*();
|
||||
operator const T*() const;
|
||||
|
||||
T& operator[](unsigned int i);
|
||||
T operator[](unsigned int i) 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*(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*=(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;
|
||||
|
||||
static NzVector4 UnitX();
|
||||
static NzVector4 UnitY();
|
||||
static NzVector4 UnitZ();
|
||||
static NzVector4 Zero();
|
||||
|
||||
T x, y, z, w;
|
||||
};
|
||||
|
||||
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);
|
||||
|
||||
typedef NzVector4<double> NzVector4d;
|
||||
typedef NzVector4<float> NzVector4f;
|
||||
typedef NzVector4<int> NzVector4i;
|
||||
|
||||
#include <Nazara/Math/Vector4.inl>
|
||||
|
||||
#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
|
||||
|
||||
/*
|
||||
Nazara Engine - Renderer module
|
||||
|
||||
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
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
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
|
||||
so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
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
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <Nazara/Renderer/Config.hpp>
|
||||
#include <Nazara/Renderer/Context.hpp>
|
||||
#include <Nazara/Renderer/ContextParameters.hpp>
|
||||
#include <Nazara/Renderer/Enums.hpp>
|
||||
#include <Nazara/Renderer/OcclusionQuery.hpp>
|
||||
#include <Nazara/Renderer/OpenGL.hpp>
|
||||
#include <Nazara/Renderer/Renderer.hpp>
|
||||
#include <Nazara/Renderer/RenderTarget.hpp>
|
||||
#include <Nazara/Renderer/RenderTargetParameters.hpp>
|
||||
#include <Nazara/Renderer/RenderWindow.hpp>
|
||||
#include <Nazara/Renderer/Shader.hpp>
|
||||
#include <Nazara/Renderer/Texture.hpp>
|
||||
// This file was automatically generated by Nazara
|
||||
|
||||
/*
|
||||
Nazara Engine - Renderer module
|
||||
|
||||
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
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
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
|
||||
so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
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
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <Nazara/Renderer/Config.hpp>
|
||||
#include <Nazara/Renderer/Context.hpp>
|
||||
#include <Nazara/Renderer/ContextParameters.hpp>
|
||||
#include <Nazara/Renderer/Enums.hpp>
|
||||
#include <Nazara/Renderer/OcclusionQuery.hpp>
|
||||
#include <Nazara/Renderer/OpenGL.hpp>
|
||||
#include <Nazara/Renderer/Renderer.hpp>
|
||||
#include <Nazara/Renderer/RenderTarget.hpp>
|
||||
#include <Nazara/Renderer/RenderTargetParameters.hpp>
|
||||
#include <Nazara/Renderer/RenderTexture.hpp>
|
||||
#include <Nazara/Renderer/RenderWindow.hpp>
|
||||
#include <Nazara/Renderer/Shader.hpp>
|
||||
#include <Nazara/Renderer/Texture.hpp>
|
||||
|
|
|
|||
|
|
@ -1,44 +1,41 @@
|
|||
/*
|
||||
Nazara Engine - Renderer module
|
||||
|
||||
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
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
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
|
||||
so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
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
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef NAZARA_CONFIG_RENDERER_HPP
|
||||
#define NAZARA_CONFIG_RENDERER_HPP
|
||||
|
||||
/// 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
|
||||
#define NAZARA_RENDERER_ACTIVATE_RENDERWINDOW_ON_CREATION 1
|
||||
|
||||
// Utilise un tracker pour repérer les éventuels leaks (Ralentit l'exécution)
|
||||
#define NAZARA_RENDERER_MEMORYLEAKTRACKER 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)
|
||||
#define NAZARA_RENDERER_OPENGL_DEBUG 0
|
||||
|
||||
// Active les tests de sécurité basés sur le code (Conseillé pour le développement)
|
||||
#define NAZARA_RENDERER_SAFE 1
|
||||
|
||||
#endif // NAZARA_CONFIG_MODULENAME_HPP
|
||||
/*
|
||||
Nazara Engine - Renderer module
|
||||
|
||||
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
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
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
|
||||
so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
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
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef NAZARA_CONFIG_RENDERER_HPP
|
||||
#define NAZARA_CONFIG_RENDERER_HPP
|
||||
|
||||
/// Chaque modification d'un paramètre du module nécessite une recompilation de celui-ci
|
||||
|
||||
// Utilise un tracker pour repérer les éventuels leaks (Ralentit l'exécution)
|
||||
#define NAZARA_RENDERER_MEMORYLEAKTRACKER 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)
|
||||
#define NAZARA_RENDERER_OPENGL_DEBUG 0
|
||||
|
||||
// Active les tests de sécurité basés sur le code (Conseillé pour le développement)
|
||||
#define NAZARA_RENDERER_SAFE 1
|
||||
|
||||
#endif // NAZARA_CONFIG_MODULENAME_HPP
|
||||
|
|
|
|||
|
|
@ -1,47 +1,49 @@
|
|||
// 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
|
||||
|
||||
#ifdef NAZARA_RENDERER_COMMON
|
||||
#error This file is not part of the common renderer interface, you must undefine NAZARA_RENDERER_COMMON to use it
|
||||
#endif
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef NAZARA_CONTEXT_HPP
|
||||
#define NAZARA_CONTEXT_HPP
|
||||
|
||||
#include <Nazara/Renderer/ContextParameters.hpp>
|
||||
|
||||
class NzContextImpl;
|
||||
|
||||
class NAZARA_API NzContext
|
||||
{
|
||||
friend NzContextImpl;
|
||||
|
||||
public:
|
||||
NzContext();
|
||||
~NzContext();
|
||||
|
||||
bool Create(const NzContextParameters& parameters = NzContextParameters());
|
||||
void Destroy();
|
||||
const NzContextParameters& GetParameters() const;
|
||||
bool IsActive() const;
|
||||
bool SetActive(bool active);
|
||||
void SwapBuffers();
|
||||
|
||||
static bool EnsureContext();
|
||||
static NzContext* GetCurrent();
|
||||
static const NzContext* GetReference();
|
||||
static NzContext* GetThreadContext();
|
||||
static bool Initialize();
|
||||
static void Uninitialize();
|
||||
|
||||
private:
|
||||
NzContextParameters m_parameters;
|
||||
NzContextImpl* m_impl;
|
||||
|
||||
static NzContext* s_reference;
|
||||
};
|
||||
|
||||
#endif // NAZARA_CONTEXT_HPP
|
||||
// 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_CONTEXT_HPP
|
||||
#define NAZARA_CONTEXT_HPP
|
||||
|
||||
#ifdef NAZARA_RENDERER_OPENGL
|
||||
|
||||
#include <Nazara/Core/Resource.hpp>
|
||||
#include <Nazara/Renderer/ContextParameters.hpp>
|
||||
|
||||
class NzContextImpl;
|
||||
|
||||
class NAZARA_API NzContext : public NzResource
|
||||
{
|
||||
friend NzContextImpl;
|
||||
|
||||
public:
|
||||
NzContext();
|
||||
~NzContext();
|
||||
|
||||
bool Create(const NzContextParameters& parameters = NzContextParameters());
|
||||
void Destroy();
|
||||
|
||||
const NzContextParameters& GetParameters() const;
|
||||
bool IsActive() const;
|
||||
bool SetActive(bool active);
|
||||
void SwapBuffers();
|
||||
|
||||
static bool EnsureContext();
|
||||
static NzContext* GetCurrent();
|
||||
static const NzContext* GetReference();
|
||||
static NzContext* GetThreadContext();
|
||||
static bool Initialize();
|
||||
static void Uninitialize();
|
||||
|
||||
private:
|
||||
NzContextParameters m_parameters;
|
||||
NzContextImpl* m_impl;
|
||||
|
||||
static NzContext* s_reference;
|
||||
};
|
||||
|
||||
#endif // NAZARA_RENDERER_OPENGL
|
||||
|
||||
#endif // NAZARA_CONTEXT_HPP
|
||||
|
|
|
|||
|
|
@ -1,141 +1,174 @@
|
|||
// 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_ENUMS_RENDERER_HPP
|
||||
#define NAZARA_ENUMS_RENDERER_HPP
|
||||
|
||||
enum nzBlendFunc
|
||||
{
|
||||
nzBlendFunc_DestAlpha,
|
||||
nzBlendFunc_DestColor,
|
||||
nzBlendFunc_SrcAlpha,
|
||||
nzBlendFunc_SrcColor,
|
||||
nzBlendFunc_InvDestAlpha,
|
||||
nzBlendFunc_InvDestColor,
|
||||
nzBlendFunc_InvSrcAlpha,
|
||||
nzBlendFunc_InvSrcColor,
|
||||
nzBlendFunc_One,
|
||||
nzBlendFunc_Zero
|
||||
};
|
||||
|
||||
enum nzFaceCulling
|
||||
{
|
||||
nzFaceCulling_Back,
|
||||
nzFaceCulling_Front,
|
||||
nzFaceCulling_FrontAndBack
|
||||
};
|
||||
|
||||
enum nzFaceFilling
|
||||
{
|
||||
nzFaceFilling_Point,
|
||||
nzFaceFilling_Line,
|
||||
nzFaceFilling_Fill
|
||||
};
|
||||
|
||||
enum nzMatrixType
|
||||
{
|
||||
nzMatrixType_Projection,
|
||||
nzMatrixType_View,
|
||||
nzMatrixType_World,
|
||||
|
||||
nzMatrixType_Max = nzMatrixType_World
|
||||
};
|
||||
|
||||
enum nzPixelBufferType
|
||||
{
|
||||
nzPixelBufferType_Pack,
|
||||
nzPixelBufferType_Unpack
|
||||
};
|
||||
|
||||
enum nzRendererCap
|
||||
{
|
||||
nzRendererCap_AnisotropicFilter,
|
||||
nzRendererCap_FP64,
|
||||
nzRendererCap_HardwareBuffer,
|
||||
nzRendererCap_MultipleRenderTargets,
|
||||
nzRendererCap_OcclusionQuery,
|
||||
nzRendererCap_PixelBufferObject,
|
||||
nzRendererCap_Texture3D,
|
||||
nzRendererCap_TextureCubemap,
|
||||
nzRendererCap_TextureMulti,
|
||||
nzRendererCap_TextureNPOT,
|
||||
|
||||
nzRendererCap_Max = nzRendererCap_TextureNPOT
|
||||
};
|
||||
|
||||
enum nzRendererClear
|
||||
{
|
||||
nzRendererClear_Color = 0x01,
|
||||
nzRendererClear_Depth = 0x02,
|
||||
nzRendererClear_Stencil = 0x04
|
||||
};
|
||||
|
||||
enum nzRendererComparison
|
||||
{
|
||||
nzRendererComparison_Always,
|
||||
nzRendererComparison_Equal,
|
||||
nzRendererComparison_Greater,
|
||||
nzRendererComparison_GreaterOrEqual,
|
||||
nzRendererComparison_Less,
|
||||
nzRendererComparison_LessOrEqual,
|
||||
nzRendererComparison_Never
|
||||
};
|
||||
|
||||
enum nzRendererParameter
|
||||
{
|
||||
nzRendererParameter_Blend,
|
||||
nzRendererParameter_ColorWrite,
|
||||
nzRendererParameter_DepthTest,
|
||||
nzRendererParameter_DepthWrite,
|
||||
nzRendererParameter_FaceCulling,
|
||||
nzRendererParameter_Stencil
|
||||
};
|
||||
|
||||
enum nzShaderLanguage
|
||||
{
|
||||
nzShaderLanguage_Unknown,
|
||||
|
||||
nzShaderLanguage_Cg,
|
||||
nzShaderLanguage_GLSL
|
||||
};
|
||||
|
||||
enum nzShaderType
|
||||
{
|
||||
nzShaderType_Fragment,
|
||||
nzShaderType_Geometry,
|
||||
nzShaderType_Vertex,
|
||||
|
||||
nzShaderType_Max = nzShaderType_Vertex
|
||||
};
|
||||
|
||||
enum nzStencilOperation
|
||||
{
|
||||
nzStencilOperation_Decrement,
|
||||
nzStencilOperation_DecrementToSaturation,
|
||||
nzStencilOperation_Increment,
|
||||
nzStencilOperation_IncrementToSaturation,
|
||||
nzStencilOperation_Invert,
|
||||
nzStencilOperation_Keep,
|
||||
nzStencilOperation_Replace,
|
||||
nzStencilOperation_Zero
|
||||
};
|
||||
|
||||
enum nzTextureFilter
|
||||
{
|
||||
nzTextureFilter_Bilinear,
|
||||
nzTextureFilter_Nearest,
|
||||
nzTextureFilter_Trilinear,
|
||||
nzTextureFilter_Unknown
|
||||
};
|
||||
|
||||
enum nzTextureWrap
|
||||
{
|
||||
nzTextureWrap_Clamp,
|
||||
nzTextureWrap_Repeat,
|
||||
nzTextureWrap_Unknown
|
||||
};
|
||||
|
||||
#endif // NAZARA_ENUMS_RENDERER_HPP
|
||||
// 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_ENUMS_RENDERER_HPP
|
||||
#define NAZARA_ENUMS_RENDERER_HPP
|
||||
|
||||
enum nzAttachmentPoint
|
||||
{
|
||||
nzAttachmentPoint_Color,
|
||||
nzAttachmentPoint_Depth,
|
||||
nzAttachmentPoint_DepthStencil,
|
||||
nzAttachmentPoint_Stencil,
|
||||
|
||||
nzAttachmentPoint_Max = nzAttachmentPoint_Stencil
|
||||
};
|
||||
|
||||
enum nzBlendFunc
|
||||
{
|
||||
nzBlendFunc_DestAlpha,
|
||||
nzBlendFunc_DestColor,
|
||||
nzBlendFunc_SrcAlpha,
|
||||
nzBlendFunc_SrcColor,
|
||||
nzBlendFunc_InvDestAlpha,
|
||||
nzBlendFunc_InvDestColor,
|
||||
nzBlendFunc_InvSrcAlpha,
|
||||
nzBlendFunc_InvSrcColor,
|
||||
nzBlendFunc_One,
|
||||
nzBlendFunc_Zero,
|
||||
|
||||
nzBlendFunc_Max = nzBlendFunc_Zero
|
||||
};
|
||||
|
||||
enum nzFaceCulling
|
||||
{
|
||||
nzFaceCulling_Back,
|
||||
nzFaceCulling_Front,
|
||||
nzFaceCulling_FrontAndBack,
|
||||
|
||||
nzFaceCulling_Max = nzFaceCulling_FrontAndBack
|
||||
};
|
||||
|
||||
enum nzFaceFilling
|
||||
{
|
||||
nzFaceFilling_Point,
|
||||
nzFaceFilling_Line,
|
||||
nzFaceFilling_Fill,
|
||||
|
||||
nzFaceFilling_Max = nzFaceFilling_Fill
|
||||
};
|
||||
|
||||
enum nzMatrixType
|
||||
{
|
||||
nzMatrixType_Projection,
|
||||
nzMatrixType_View,
|
||||
nzMatrixType_World,
|
||||
|
||||
nzMatrixType_Max = nzMatrixType_World
|
||||
};
|
||||
|
||||
enum nzPixelBufferType
|
||||
{
|
||||
nzPixelBufferType_Pack,
|
||||
nzPixelBufferType_Unpack,
|
||||
|
||||
nzPixelBufferType_Max = nzPixelBufferType_Unpack
|
||||
};
|
||||
|
||||
enum nzRendererCap
|
||||
{
|
||||
nzRendererCap_AnisotropicFilter,
|
||||
nzRendererCap_FP64,
|
||||
nzRendererCap_HardwareBuffer,
|
||||
nzRendererCap_MultipleRenderTargets,
|
||||
nzRendererCap_OcclusionQuery,
|
||||
nzRendererCap_PixelBufferObject,
|
||||
nzRendererCap_RenderTexture,
|
||||
nzRendererCap_Texture3D,
|
||||
nzRendererCap_TextureCubemap,
|
||||
nzRendererCap_TextureMulti,
|
||||
nzRendererCap_TextureNPOT,
|
||||
|
||||
nzRendererCap_Max = nzRendererCap_TextureNPOT
|
||||
};
|
||||
|
||||
enum nzRendererClearFlags
|
||||
{
|
||||
nzRendererClear_Color = 0x01,
|
||||
nzRendererClear_Depth = 0x02,
|
||||
nzRendererClear_Stencil = 0x04
|
||||
};
|
||||
|
||||
enum nzRendererComparison
|
||||
{
|
||||
nzRendererComparison_Always,
|
||||
nzRendererComparison_Equal,
|
||||
nzRendererComparison_Greater,
|
||||
nzRendererComparison_GreaterOrEqual,
|
||||
nzRendererComparison_Less,
|
||||
nzRendererComparison_LessOrEqual,
|
||||
nzRendererComparison_Never,
|
||||
|
||||
nzRendererComparison_Max = nzRendererComparison_Never
|
||||
};
|
||||
|
||||
enum nzRendererParameter
|
||||
{
|
||||
nzRendererParameter_Blend,
|
||||
nzRendererParameter_ColorWrite,
|
||||
nzRendererParameter_DepthTest,
|
||||
nzRendererParameter_DepthWrite,
|
||||
nzRendererParameter_FaceCulling,
|
||||
nzRendererParameter_Stencil,
|
||||
|
||||
nzRendererParameter_Max = nzRendererParameter_Stencil
|
||||
};
|
||||
|
||||
enum nzShaderLanguage
|
||||
{
|
||||
nzShaderLanguage_Unknown = -1,
|
||||
|
||||
nzShaderLanguage_Cg,
|
||||
nzShaderLanguage_GLSL,
|
||||
|
||||
nzShaderLanguage_Max = nzShaderLanguage_GLSL
|
||||
};
|
||||
|
||||
enum nzShaderType
|
||||
{
|
||||
nzShaderType_Fragment,
|
||||
nzShaderType_Geometry,
|
||||
nzShaderType_Vertex,
|
||||
|
||||
nzShaderType_Max = nzShaderType_Vertex
|
||||
};
|
||||
|
||||
enum nzStencilOperation
|
||||
{
|
||||
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
|
||||
// This file is part of the "Nazara Engine - Renderer module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#ifdef NAZARA_RENDERER_COMMON
|
||||
#error This file is not part of the common renderer interface, you must undefine NAZARA_RENDERER_COMMON to use it
|
||||
#endif
|
||||
|
||||
#pragma once
|
||||
|
||||
#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>
|
||||
#include <Nazara/Prerequesites.hpp>
|
||||
#include <Nazara/Core/String.hpp>
|
||||
|
||||
// Inclusion des extensions
|
||||
#include <GL3/glext.h>
|
||||
#if defined(NAZARA_PLATFORM_WINDOWS)
|
||||
#include <GL3/wglext.h>
|
||||
#elif defined(NAZARA_PLATFORM_LINUX)
|
||||
#include <GL3/glxext.h>
|
||||
#endif
|
||||
|
||||
using NzOpenGLFunc = void (*)();
|
||||
|
||||
class NAZARA_API NzOpenGL
|
||||
{
|
||||
public:
|
||||
enum Extension
|
||||
{
|
||||
AnisotropicFilter,
|
||||
DebugOutput,
|
||||
FP64,
|
||||
FrameBufferObject,
|
||||
PixelBufferObject,
|
||||
SeparateShaderObjects,
|
||||
Texture3D,
|
||||
TextureArray,
|
||||
TextureCompression_s3tc,
|
||||
TextureStorage,
|
||||
VertexArrayObject,
|
||||
|
||||
Max = VertexArrayObject
|
||||
};
|
||||
|
||||
static NzOpenGLFunc GetEntry(const NzString& entryPoint);
|
||||
static unsigned int GetVersion();
|
||||
static bool Initialize();
|
||||
static bool IsSupported(Extension extension);
|
||||
static bool IsSupported(const NzString& string);
|
||||
static void Uninitialize();
|
||||
};
|
||||
|
||||
NAZARA_API extern PFNGLACTIVETEXTUREPROC glActiveTexture;
|
||||
NAZARA_API extern PFNGLATTACHSHADERPROC glAttachShader;
|
||||
NAZARA_API extern PFNGLBEGINQUERYPROC glBeginQuery;
|
||||
NAZARA_API extern PFNGLBINDATTRIBLOCATIONPROC glBindAttribLocation;
|
||||
NAZARA_API extern PFNGLBINDBUFFERPROC glBindBuffer;
|
||||
NAZARA_API extern PFNGLBINDFRAMEBUFFERPROC glBindFramebuffer;
|
||||
NAZARA_API extern PFNGLBINDRENDERBUFFERPROC glBindRenderbuffer;
|
||||
NAZARA_API extern PFNGLBINDTEXTUREPROC glBindTexture;
|
||||
NAZARA_API extern PFNGLBINDVERTEXARRAYPROC glBindVertexArray;
|
||||
NAZARA_API extern PFNGLBLENDFUNCPROC glBlendFunc;
|
||||
NAZARA_API extern PFNGLBUFFERDATAPROC glBufferData;
|
||||
NAZARA_API extern PFNGLBUFFERSUBDATAPROC glBufferSubData;
|
||||
NAZARA_API extern PFNGLCLEARPROC glClear;
|
||||
NAZARA_API extern PFNGLCLEARCOLORPROC glClearColor;
|
||||
NAZARA_API extern PFNGLCLEARDEPTHPROC glClearDepth;
|
||||
NAZARA_API extern PFNGLCLEARSTENCILPROC glClearStencil;
|
||||
NAZARA_API extern PFNGLCREATEPROGRAMPROC glCreateProgram;
|
||||
NAZARA_API extern PFNGLCREATESHADERPROC glCreateShader;
|
||||
NAZARA_API extern PFNGLCHECKFRAMEBUFFERSTATUSPROC glCheckFramebufferStatus;
|
||||
NAZARA_API extern PFNGLCOLORMASKPROC glColorMask;
|
||||
NAZARA_API extern PFNGLCULLFACEPROC glCullFace;
|
||||
NAZARA_API extern PFNGLCOMPILESHADERPROC glCompileShader;
|
||||
NAZARA_API extern PFNGLCOPYTEXSUBIMAGE2DPROC glCopyTexSubImage2D;
|
||||
NAZARA_API extern PFNGLDEBUGMESSAGECALLBACKPROC glDebugMessageCallback;
|
||||
NAZARA_API extern PFNGLDEBUGMESSAGECONTROLPROC glDebugMessageControl;
|
||||
NAZARA_API extern PFNGLDEBUGMESSAGEINSERTPROC glDebugMessageInsert;
|
||||
NAZARA_API extern PFNGLDELETEBUFFERSPROC glDeleteBuffers;
|
||||
NAZARA_API extern PFNGLDELETEFRAMEBUFFERSPROC glDeleteFramebuffers;
|
||||
NAZARA_API extern PFNGLDELETEPROGRAMPROC glDeleteProgram;
|
||||
NAZARA_API extern PFNGLDELETEQUERIESPROC glDeleteQueries;
|
||||
NAZARA_API extern PFNGLDELETERENDERBUFFERSPROC glDeleteRenderbuffers;
|
||||
NAZARA_API extern PFNGLDELETESHADERPROC glDeleteShader;
|
||||
NAZARA_API extern PFNGLDELETETEXTURESPROC glDeleteTextures;
|
||||
NAZARA_API extern PFNGLDELETEVERTEXARRAYSPROC glDeleteVertexArrays;
|
||||
NAZARA_API extern PFNGLDEPTHFUNCPROC glDepthFunc;
|
||||
NAZARA_API extern PFNGLDEPTHMASKPROC glDepthMask;
|
||||
NAZARA_API extern PFNGLDISABLEPROC glDisable;
|
||||
NAZARA_API extern PFNGLDISABLEVERTEXATTRIBARRAYPROC glDisableVertexAttribArray;
|
||||
NAZARA_API extern PFNGLDRAWARRAYSPROC glDrawArrays;
|
||||
NAZARA_API extern PFNGLDRAWBUFFERPROC glDrawBuffer;
|
||||
NAZARA_API extern PFNGLDRAWBUFFERSPROC glDrawBuffers;
|
||||
NAZARA_API extern PFNGLDRAWELEMENTSPROC glDrawElements;
|
||||
NAZARA_API extern PFNGLENDQUERYPROC glEndQuery;
|
||||
NAZARA_API extern PFNGLFLUSHPROC glFlush;
|
||||
NAZARA_API extern PFNGLFRAMEBUFFERRENDERBUFFERPROC glFramebufferRenderbuffer;
|
||||
NAZARA_API extern PFNGLFRAMEBUFFERTEXTURE2DPROC glFramebufferTexture2D;
|
||||
NAZARA_API extern PFNGLENABLEPROC glEnable;
|
||||
NAZARA_API extern PFNGLENABLEVERTEXATTRIBARRAYPROC glEnableVertexAttribArray;
|
||||
NAZARA_API extern PFNGLGENERATEMIPMAPPROC glGenerateMipmap;
|
||||
NAZARA_API extern PFNGLGENBUFFERSPROC glGenBuffers;
|
||||
NAZARA_API extern PFNGLGENFRAMEBUFFERSPROC glGenFramebuffers;
|
||||
NAZARA_API extern PFNGLGENQUERIESPROC glGenQueries;
|
||||
NAZARA_API extern PFNGLGENRENDERBUFFERSPROC glGenRenderbuffers;
|
||||
NAZARA_API extern PFNGLGENTEXTURESPROC glGenTextures;
|
||||
NAZARA_API extern PFNGLGENVERTEXARRAYSPROC glGenVertexArrays;
|
||||
NAZARA_API extern PFNGLGETBUFFERPARAMETERIVPROC glGetBufferParameteriv;
|
||||
NAZARA_API extern PFNGLGETDEBUGMESSAGELOGPROC glGetDebugMessageLog;
|
||||
NAZARA_API extern PFNGLGETERRORPROC glGetError;
|
||||
NAZARA_API extern PFNGLGETINTEGERVPROC glGetIntegerv;
|
||||
NAZARA_API extern PFNGLGETPROGRAMIVPROC glGetProgramiv;
|
||||
NAZARA_API extern PFNGLGETPROGRAMINFOLOGPROC glGetProgramInfoLog;
|
||||
NAZARA_API extern PFNGLGETQUERYIVPROC glGetQueryiv;
|
||||
NAZARA_API extern PFNGLGETQUERYOBJECTIVPROC glGetQueryObjectiv;
|
||||
NAZARA_API extern PFNGLGETQUERYOBJECTUIVPROC glGetQueryObjectuiv;
|
||||
NAZARA_API extern PFNGLGETSHADERINFOLOGPROC glGetShaderInfoLog;
|
||||
NAZARA_API extern PFNGLGETSHADERIVPROC glGetShaderiv;
|
||||
NAZARA_API extern PFNGLGETSHADERSOURCEPROC glGetShaderSource;
|
||||
NAZARA_API extern PFNGLGETSTRINGPROC glGetString;
|
||||
NAZARA_API extern PFNGLGETSTRINGIPROC glGetStringi;
|
||||
NAZARA_API extern PFNGLGETTEXIMAGEPROC glGetTexImage;
|
||||
NAZARA_API extern PFNGLGETTEXLEVELPARAMETERFVPROC glGetTexLevelParameterfv;
|
||||
NAZARA_API extern PFNGLGETTEXLEVELPARAMETERIVPROC glGetTexLevelParameteriv;
|
||||
NAZARA_API extern PFNGLGETTEXPARAMETERFVPROC glGetTexParameterfv;
|
||||
NAZARA_API extern PFNGLGETTEXPARAMETERIVPROC glGetTexParameteriv;
|
||||
NAZARA_API extern PFNGLGETUNIFORMLOCATIONPROC glGetUniformLocation;
|
||||
NAZARA_API extern PFNGLLINKPROGRAMPROC glLinkProgram;
|
||||
NAZARA_API extern PFNGLMAPBUFFERPROC glMapBuffer;
|
||||
NAZARA_API extern PFNGLMAPBUFFERRANGEPROC glMapBufferRange;
|
||||
NAZARA_API extern PFNGLPIXELSTOREIPROC glPixelStorei;
|
||||
NAZARA_API extern PFNGLPOLYGONMODEPROC glPolygonMode;
|
||||
NAZARA_API extern PFNGLPROGRAMUNIFORM1DPROC glProgramUniform1d;
|
||||
NAZARA_API extern PFNGLPROGRAMUNIFORM1FPROC glProgramUniform1f;
|
||||
NAZARA_API extern PFNGLPROGRAMUNIFORM1IPROC glProgramUniform1i;
|
||||
NAZARA_API extern PFNGLPROGRAMUNIFORM2DVPROC glProgramUniform2dv;
|
||||
NAZARA_API extern PFNGLPROGRAMUNIFORM2FVPROC glProgramUniform2fv;
|
||||
NAZARA_API extern PFNGLPROGRAMUNIFORM3DVPROC glProgramUniform3dv;
|
||||
NAZARA_API extern PFNGLPROGRAMUNIFORM3FVPROC glProgramUniform3fv;
|
||||
NAZARA_API extern PFNGLPROGRAMUNIFORM4DVPROC glProgramUniform4dv;
|
||||
NAZARA_API extern PFNGLPROGRAMUNIFORM4FVPROC glProgramUniform4fv;
|
||||
NAZARA_API extern PFNGLPROGRAMUNIFORMMATRIX4DVPROC glProgramUniformMatrix4dv;
|
||||
NAZARA_API extern PFNGLPROGRAMUNIFORMMATRIX4FVPROC glProgramUniformMatrix4fv;
|
||||
NAZARA_API extern PFNGLREADPIXELSPROC glReadPixels;
|
||||
NAZARA_API extern PFNGLRENDERBUFFERSTORAGEPROC glRenderbufferStorage;
|
||||
NAZARA_API extern PFNGLSCISSORPROC glScissor;
|
||||
NAZARA_API extern PFNGLSHADERSOURCEPROC glShaderSource;
|
||||
NAZARA_API extern PFNGLSTENCILFUNCPROC glStencilFunc;
|
||||
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_OPENGL_HPP
|
||||
// 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_OPENGL_HPP
|
||||
#define NAZARA_OPENGL_HPP
|
||||
|
||||
#ifdef NAZARA_RENDERER_OPENGL
|
||||
|
||||
// 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>
|
||||
#include <Nazara/Prerequesites.hpp>
|
||||
#include <Nazara/Core/String.hpp>
|
||||
#include <Nazara/Utility/Enums.hpp>
|
||||
#include <Nazara/Renderer/Enums.hpp>
|
||||
|
||||
// Inclusion des extensions
|
||||
#include <GL3/glext.h>
|
||||
#if defined(NAZARA_PLATFORM_WINDOWS)
|
||||
#include <GL3/wglext.h>
|
||||
#elif defined(NAZARA_PLATFORM_LINUX)
|
||||
#include <GL3/glxext.h>
|
||||
#endif
|
||||
|
||||
enum nzOpenGLExtension
|
||||
{
|
||||
nzOpenGLExtension_AnisotropicFilter,
|
||||
nzOpenGLExtension_DebugOutput,
|
||||
nzOpenGLExtension_FP64,
|
||||
nzOpenGLExtension_FrameBufferObject,
|
||||
nzOpenGLExtension_PixelBufferObject,
|
||||
nzOpenGLExtension_SeparateShaderObjects,
|
||||
nzOpenGLExtension_TextureArray,
|
||||
nzOpenGLExtension_TextureCompression_s3tc,
|
||||
nzOpenGLExtension_TextureStorage,
|
||||
nzOpenGLExtension_VertexArrayObject,
|
||||
|
||||
nzOpenGLExtension_Max = nzOpenGLExtension_VertexArrayObject
|
||||
};
|
||||
|
||||
using NzOpenGLFunc = void (*)();
|
||||
|
||||
namespace NzOpenGL
|
||||
{
|
||||
enum FormatType
|
||||
{
|
||||
FormatType_RenderBuffer,
|
||||
// FormatType_MultisampleTexture,
|
||||
FormatType_Texture
|
||||
};
|
||||
|
||||
struct Format
|
||||
{
|
||||
GLenum dataFormat;
|
||||
GLenum dataType;
|
||||
GLint internalFormat;
|
||||
};
|
||||
|
||||
NzOpenGLFunc GetEntry(const NzString& entryPoint);
|
||||
unsigned int GetVersion();
|
||||
bool Initialize();
|
||||
bool IsSupported(nzOpenGLExtension extension);
|
||||
bool IsSupported(const NzString& string);
|
||||
bool TranslateFormat(nzPixelFormat pixelFormat, Format* format, FormatType target);
|
||||
void Uninitialize();
|
||||
|
||||
extern GLenum Attachment[nzAttachmentPoint_Max+1];
|
||||
extern nzUInt8 AttributeIndex[nzElementUsage_Max+1];
|
||||
extern GLenum BlendFunc[nzBlendFunc_Max+1];
|
||||
extern GLenum BufferLock[nzBufferAccess_Max+1];
|
||||
extern GLenum BufferLockRange[nzBufferAccess_Max+1];
|
||||
extern GLenum BufferTarget[nzBufferType_Max+1];
|
||||
extern GLenum BufferTargetBinding[nzBufferType_Max+1];
|
||||
extern GLenum BufferUsage[nzBufferUsage_Max+1];
|
||||
extern GLenum CubemapFace[6]; // Un cube possède six faces et ça n'est pas prêt de changer
|
||||
extern GLenum ElementType[nzElementType_Max+1];
|
||||
extern GLenum FaceCulling[nzFaceCulling_Max+1];
|
||||
extern GLenum FaceFilling[nzFaceFilling_Max+1];
|
||||
extern GLenum PrimitiveType[nzPrimitiveType_Max+1];
|
||||
extern GLenum RendererComparison[nzRendererComparison_Max+1];
|
||||
extern GLenum RendererParameter[nzRendererParameter_Max+1];
|
||||
extern GLenum ShaderType[nzShaderType_Max+1];
|
||||
extern GLenum StencilOperation[nzStencilOperation_Max+1];
|
||||
extern GLenum TextureTarget[nzImageType_Max+1];
|
||||
extern GLenum TextureTargetBinding[nzImageType_Max+1];
|
||||
extern GLenum TextureTargetProxy[nzImageType_Max+1];
|
||||
}
|
||||
|
||||
NAZARA_API extern PFNGLACTIVETEXTUREPROC glActiveTexture;
|
||||
NAZARA_API extern PFNGLATTACHSHADERPROC glAttachShader;
|
||||
NAZARA_API extern PFNGLBEGINQUERYPROC glBeginQuery;
|
||||
NAZARA_API extern PFNGLBINDATTRIBLOCATIONPROC glBindAttribLocation;
|
||||
NAZARA_API extern PFNGLBINDBUFFERPROC glBindBuffer;
|
||||
NAZARA_API extern PFNGLBINDFRAMEBUFFERPROC glBindFramebuffer;
|
||||
NAZARA_API extern PFNGLBINDFRAGDATALOCATIONPROC glBindFragDataLocation;
|
||||
NAZARA_API extern PFNGLBINDRENDERBUFFERPROC glBindRenderbuffer;
|
||||
NAZARA_API extern PFNGLBINDTEXTUREPROC glBindTexture;
|
||||
NAZARA_API extern PFNGLBINDVERTEXARRAYPROC glBindVertexArray;
|
||||
NAZARA_API extern PFNGLBLENDFUNCPROC glBlendFunc;
|
||||
NAZARA_API extern PFNGLBUFFERDATAPROC glBufferData;
|
||||
NAZARA_API extern PFNGLBUFFERSUBDATAPROC glBufferSubData;
|
||||
NAZARA_API extern PFNGLCLEARPROC glClear;
|
||||
NAZARA_API extern PFNGLCLEARCOLORPROC glClearColor;
|
||||
NAZARA_API extern PFNGLCLEARDEPTHPROC glClearDepth;
|
||||
NAZARA_API extern PFNGLCLEARSTENCILPROC glClearStencil;
|
||||
NAZARA_API extern PFNGLCREATEPROGRAMPROC glCreateProgram;
|
||||
NAZARA_API extern PFNGLCREATESHADERPROC glCreateShader;
|
||||
NAZARA_API extern PFNGLCHECKFRAMEBUFFERSTATUSPROC glCheckFramebufferStatus;
|
||||
NAZARA_API extern PFNGLCOLORMASKPROC glColorMask;
|
||||
NAZARA_API extern PFNGLCULLFACEPROC glCullFace;
|
||||
NAZARA_API extern PFNGLCOMPILESHADERPROC glCompileShader;
|
||||
NAZARA_API extern PFNGLCOPYTEXSUBIMAGE2DPROC glCopyTexSubImage2D;
|
||||
NAZARA_API extern PFNGLDEBUGMESSAGECALLBACKPROC glDebugMessageCallback;
|
||||
NAZARA_API extern PFNGLDEBUGMESSAGECONTROLPROC glDebugMessageControl;
|
||||
NAZARA_API extern PFNGLDEBUGMESSAGEINSERTPROC glDebugMessageInsert;
|
||||
NAZARA_API extern PFNGLDELETEBUFFERSPROC glDeleteBuffers;
|
||||
NAZARA_API extern PFNGLDELETEFRAMEBUFFERSPROC glDeleteFramebuffers;
|
||||
NAZARA_API extern PFNGLDELETEPROGRAMPROC glDeleteProgram;
|
||||
NAZARA_API extern PFNGLDELETEQUERIESPROC glDeleteQueries;
|
||||
NAZARA_API extern PFNGLDELETERENDERBUFFERSPROC glDeleteRenderbuffers;
|
||||
NAZARA_API extern PFNGLDELETESHADERPROC glDeleteShader;
|
||||
NAZARA_API extern PFNGLDELETETEXTURESPROC glDeleteTextures;
|
||||
NAZARA_API extern PFNGLDELETEVERTEXARRAYSPROC glDeleteVertexArrays;
|
||||
NAZARA_API extern PFNGLDEPTHFUNCPROC glDepthFunc;
|
||||
NAZARA_API extern PFNGLDEPTHMASKPROC glDepthMask;
|
||||
NAZARA_API extern PFNGLDISABLEPROC glDisable;
|
||||
NAZARA_API extern PFNGLDISABLEVERTEXATTRIBARRAYPROC glDisableVertexAttribArray;
|
||||
NAZARA_API extern PFNGLDRAWARRAYSPROC glDrawArrays;
|
||||
NAZARA_API extern PFNGLDRAWBUFFERPROC glDrawBuffer;
|
||||
NAZARA_API extern PFNGLDRAWBUFFERSPROC glDrawBuffers;
|
||||
NAZARA_API extern PFNGLDRAWELEMENTSPROC glDrawElements;
|
||||
NAZARA_API extern PFNGLENDQUERYPROC glEndQuery;
|
||||
NAZARA_API extern PFNGLFLUSHPROC glFlush;
|
||||
NAZARA_API extern PFNGLFRAMEBUFFERRENDERBUFFERPROC glFramebufferRenderbuffer;
|
||||
NAZARA_API extern PFNGLFRAMEBUFFERTEXTUREPROC glFramebufferTexture;
|
||||
NAZARA_API extern PFNGLFRAMEBUFFERTEXTURE1DPROC glFramebufferTexture1D;
|
||||
NAZARA_API extern PFNGLFRAMEBUFFERTEXTURE2DPROC glFramebufferTexture2D;
|
||||
NAZARA_API extern PFNGLFRAMEBUFFERTEXTURE3DPROC glFramebufferTexture3D;
|
||||
NAZARA_API extern PFNGLFRAMEBUFFERTEXTURELAYERPROC glFramebufferTextureLayer;
|
||||
NAZARA_API extern PFNGLENABLEPROC glEnable;
|
||||
NAZARA_API extern PFNGLENABLEVERTEXATTRIBARRAYPROC glEnableVertexAttribArray;
|
||||
NAZARA_API extern PFNGLGENERATEMIPMAPPROC glGenerateMipmap;
|
||||
NAZARA_API extern PFNGLGENBUFFERSPROC glGenBuffers;
|
||||
NAZARA_API extern PFNGLGENFRAMEBUFFERSPROC glGenFramebuffers;
|
||||
NAZARA_API extern PFNGLGENQUERIESPROC glGenQueries;
|
||||
NAZARA_API extern PFNGLGENRENDERBUFFERSPROC glGenRenderbuffers;
|
||||
NAZARA_API extern PFNGLGENTEXTURESPROC glGenTextures;
|
||||
NAZARA_API extern PFNGLGENVERTEXARRAYSPROC glGenVertexArrays;
|
||||
NAZARA_API extern PFNGLGETBUFFERPARAMETERIVPROC glGetBufferParameteriv;
|
||||
NAZARA_API extern PFNGLGETDEBUGMESSAGELOGPROC glGetDebugMessageLog;
|
||||
NAZARA_API extern PFNGLGETERRORPROC glGetError;
|
||||
NAZARA_API extern PFNGLGETINTEGERVPROC glGetIntegerv;
|
||||
NAZARA_API extern PFNGLGETPROGRAMIVPROC glGetProgramiv;
|
||||
NAZARA_API extern PFNGLGETPROGRAMINFOLOGPROC glGetProgramInfoLog;
|
||||
NAZARA_API extern PFNGLGETQUERYIVPROC glGetQueryiv;
|
||||
NAZARA_API extern PFNGLGETQUERYOBJECTIVPROC glGetQueryObjectiv;
|
||||
NAZARA_API extern PFNGLGETQUERYOBJECTUIVPROC glGetQueryObjectuiv;
|
||||
NAZARA_API extern PFNGLGETSHADERINFOLOGPROC glGetShaderInfoLog;
|
||||
NAZARA_API extern PFNGLGETSHADERIVPROC glGetShaderiv;
|
||||
NAZARA_API extern PFNGLGETSHADERSOURCEPROC glGetShaderSource;
|
||||
NAZARA_API extern PFNGLGETSTRINGPROC glGetString;
|
||||
NAZARA_API extern PFNGLGETSTRINGIPROC glGetStringi;
|
||||
NAZARA_API extern PFNGLGETTEXIMAGEPROC glGetTexImage;
|
||||
NAZARA_API extern PFNGLGETTEXLEVELPARAMETERFVPROC glGetTexLevelParameterfv;
|
||||
NAZARA_API extern PFNGLGETTEXLEVELPARAMETERIVPROC glGetTexLevelParameteriv;
|
||||
NAZARA_API extern PFNGLGETTEXPARAMETERFVPROC glGetTexParameterfv;
|
||||
NAZARA_API extern PFNGLGETTEXPARAMETERIVPROC glGetTexParameteriv;
|
||||
NAZARA_API extern PFNGLGETUNIFORMLOCATIONPROC glGetUniformLocation;
|
||||
NAZARA_API extern PFNGLLINKPROGRAMPROC glLinkProgram;
|
||||
NAZARA_API extern PFNGLMAPBUFFERPROC glMapBuffer;
|
||||
NAZARA_API extern PFNGLMAPBUFFERRANGEPROC glMapBufferRange;
|
||||
NAZARA_API extern PFNGLPIXELSTOREIPROC glPixelStorei;
|
||||
NAZARA_API extern PFNGLPOLYGONMODEPROC glPolygonMode;
|
||||
NAZARA_API extern PFNGLPROGRAMUNIFORM1DPROC glProgramUniform1d;
|
||||
NAZARA_API extern PFNGLPROGRAMUNIFORM1FPROC glProgramUniform1f;
|
||||
NAZARA_API extern PFNGLPROGRAMUNIFORM1IPROC glProgramUniform1i;
|
||||
NAZARA_API extern PFNGLPROGRAMUNIFORM2DVPROC glProgramUniform2dv;
|
||||
NAZARA_API extern PFNGLPROGRAMUNIFORM2FVPROC glProgramUniform2fv;
|
||||
NAZARA_API extern PFNGLPROGRAMUNIFORM3DVPROC glProgramUniform3dv;
|
||||
NAZARA_API extern PFNGLPROGRAMUNIFORM3FVPROC glProgramUniform3fv;
|
||||
NAZARA_API extern PFNGLPROGRAMUNIFORM4DVPROC glProgramUniform4dv;
|
||||
NAZARA_API extern PFNGLPROGRAMUNIFORM4FVPROC glProgramUniform4fv;
|
||||
NAZARA_API extern PFNGLPROGRAMUNIFORMMATRIX4DVPROC glProgramUniformMatrix4dv;
|
||||
NAZARA_API extern PFNGLPROGRAMUNIFORMMATRIX4FVPROC glProgramUniformMatrix4fv;
|
||||
NAZARA_API extern PFNGLREADPIXELSPROC glReadPixels;
|
||||
NAZARA_API extern PFNGLRENDERBUFFERSTORAGEPROC glRenderbufferStorage;
|
||||
NAZARA_API extern PFNGLSCISSORPROC glScissor;
|
||||
NAZARA_API extern PFNGLSHADERSOURCEPROC glShaderSource;
|
||||
NAZARA_API extern PFNGLSTENCILFUNCPROC glStencilFunc;
|
||||
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
|
||||
// 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_RENDERTARGET_HPP
|
||||
#define NAZARA_RENDERTARGET_HPP
|
||||
|
||||
#include <Nazara/Prerequesites.hpp>
|
||||
#include <Nazara/Renderer/Config.hpp>
|
||||
#include <Nazara/Renderer/RenderTargetParameters.hpp>
|
||||
|
||||
class NzRenderer;
|
||||
|
||||
class NAZARA_API NzRenderTarget
|
||||
{
|
||||
friend class NzRenderer;
|
||||
|
||||
public:
|
||||
NzRenderTarget() = default;
|
||||
virtual ~NzRenderTarget();
|
||||
|
||||
#ifndef NAZARA_RENDERER_COMMON
|
||||
virtual bool HasContext() const = 0;
|
||||
#endif
|
||||
|
||||
virtual unsigned int GetHeight() const = 0;
|
||||
virtual NzRenderTargetParameters GetParameters() const = 0;
|
||||
virtual unsigned int GetWidth() const = 0;
|
||||
|
||||
bool IsActive() const;
|
||||
virtual bool IsValid() const = 0;
|
||||
|
||||
bool SetActive(bool active);
|
||||
|
||||
protected:
|
||||
virtual bool Activate() = 0;
|
||||
virtual void Desactivate();
|
||||
};
|
||||
|
||||
#endif // NAZARA_RENDERTARGET_HPP
|
||||
// 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_RENDERTARGET_HPP
|
||||
#define NAZARA_RENDERTARGET_HPP
|
||||
|
||||
#include <Nazara/Prerequesites.hpp>
|
||||
#include <Nazara/Renderer/Config.hpp>
|
||||
#include <Nazara/Renderer/RenderTargetParameters.hpp>
|
||||
|
||||
class NzRenderer;
|
||||
|
||||
class NAZARA_API NzRenderTarget
|
||||
{
|
||||
friend class NzRenderer;
|
||||
|
||||
public:
|
||||
NzRenderTarget() = default;
|
||||
virtual ~NzRenderTarget();
|
||||
|
||||
virtual unsigned int GetHeight() const = 0;
|
||||
virtual NzRenderTargetParameters GetParameters() const = 0;
|
||||
virtual unsigned int GetWidth() const = 0;
|
||||
|
||||
bool IsActive() const;
|
||||
virtual bool IsRenderable() const = 0;
|
||||
|
||||
bool SetActive(bool active);
|
||||
|
||||
// Fonctions OpenGL
|
||||
virtual bool HasContext() const = 0;
|
||||
|
||||
protected:
|
||||
virtual bool Activate() = 0;
|
||||
virtual void Desactivate();
|
||||
};
|
||||
|
||||
#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
|
||||
// This file is part of the "Nazara Engine - Renderer module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
// Interface inspirée de la SFML par Laurent Gomila
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef NAZARA_RENDERWINDOW_HPP
|
||||
#define NAZARA_RENDERWINDOW_HPP
|
||||
|
||||
#include <Nazara/Prerequesites.hpp>
|
||||
#include <Nazara/Core/Clock.hpp>
|
||||
#include <Nazara/Renderer/Config.hpp>
|
||||
#include <Nazara/Renderer/ContextParameters.hpp>
|
||||
#include <Nazara/Renderer/RenderTarget.hpp>
|
||||
#include <Nazara/Utility/Window.hpp>
|
||||
|
||||
class NzContext;
|
||||
class NzImage;
|
||||
class NzTexture;
|
||||
struct NzContextParameters;
|
||||
|
||||
class NAZARA_API NzRenderWindow : public NzRenderTarget, public NzWindow
|
||||
{
|
||||
public:
|
||||
NzRenderWindow() = default;
|
||||
NzRenderWindow(NzVideoMode mode, const NzString& title, nzUInt32 style = nzWindowStyle_Default, const NzContextParameters& parameters = NzContextParameters());
|
||||
NzRenderWindow(NzWindowHandle handle, const NzContextParameters& parameters = NzContextParameters());
|
||||
virtual ~NzRenderWindow();
|
||||
|
||||
bool CopyToImage(NzImage* image); ///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(NzWindowHandle handle, const NzContextParameters& parameters = NzContextParameters());
|
||||
|
||||
void Display();
|
||||
|
||||
void EnableVerticalSync(bool enabled);
|
||||
|
||||
#ifndef NAZARA_RENDERER_COMMON
|
||||
NzContextParameters GetContextParameters() const;
|
||||
#endif
|
||||
|
||||
unsigned int GetHeight() const;
|
||||
NzRenderTargetParameters GetParameters() const;
|
||||
unsigned int GetWidth() const;
|
||||
|
||||
#ifndef NAZARA_RENDERER_COMMON
|
||||
bool HasContext() const;
|
||||
#endif
|
||||
|
||||
bool IsValid() const;
|
||||
|
||||
void SetFramerateLimit(unsigned int limit);
|
||||
|
||||
protected:
|
||||
virtual bool Activate() override;
|
||||
|
||||
private:
|
||||
virtual void OnWindowDestroying() override;
|
||||
virtual bool OnWindowCreated() override;
|
||||
|
||||
NzClock m_clock;
|
||||
NzContextParameters m_parameters;
|
||||
NzContext* m_context = nullptr;
|
||||
unsigned int m_framerateLimit = 0;
|
||||
};
|
||||
|
||||
#endif // NAZARA_RENDERWINDOW_HPP
|
||||
// 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
|
||||
|
||||
// Interface inspirée de la SFML par Laurent Gomila
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef NAZARA_RENDERWINDOW_HPP
|
||||
#define NAZARA_RENDERWINDOW_HPP
|
||||
|
||||
#include <Nazara/Prerequesites.hpp>
|
||||
#include <Nazara/Core/Clock.hpp>
|
||||
#include <Nazara/Renderer/Config.hpp>
|
||||
#include <Nazara/Renderer/ContextParameters.hpp>
|
||||
#include <Nazara/Renderer/RenderTarget.hpp>
|
||||
#include <Nazara/Utility/Window.hpp>
|
||||
|
||||
class NzContext;
|
||||
class NzImage;
|
||||
class NzTexture;
|
||||
struct NzContextParameters;
|
||||
|
||||
class NAZARA_API NzRenderWindow : public NzRenderTarget, public NzWindow
|
||||
{
|
||||
public:
|
||||
NzRenderWindow() = default;
|
||||
NzRenderWindow(NzVideoMode mode, const NzString& title, nzUInt32 style = nzWindowStyle_Default, const NzContextParameters& parameters = NzContextParameters());
|
||||
NzRenderWindow(NzWindowHandle handle, const NzContextParameters& parameters = NzContextParameters());
|
||||
virtual ~NzRenderWindow();
|
||||
|
||||
bool CopyToImage(NzImage* image); ///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(NzWindowHandle handle, const NzContextParameters& parameters = NzContextParameters());
|
||||
|
||||
void Display();
|
||||
|
||||
void EnableVerticalSync(bool enabled);
|
||||
|
||||
unsigned int GetHeight() const;
|
||||
NzRenderTargetParameters GetParameters() const;
|
||||
unsigned int GetWidth() const;
|
||||
|
||||
bool IsRenderable() const;
|
||||
bool IsValid() const;
|
||||
|
||||
void SetFramerateLimit(unsigned int limit);
|
||||
|
||||
// Fonctions OpenGL
|
||||
NzContextParameters GetContextParameters() const;
|
||||
bool HasContext() const;
|
||||
|
||||
protected:
|
||||
bool Activate() override;
|
||||
|
||||
private:
|
||||
bool OnWindowCreated() override;
|
||||
void OnWindowDestroy() override;
|
||||
|
||||
NzClock m_clock;
|
||||
NzContextParameters m_parameters;
|
||||
NzContext* m_context = nullptr;
|
||||
unsigned int m_framerateLimit = 0;
|
||||
};
|
||||
|
||||
#endif // NAZARA_RENDERWINDOW_HPP
|
||||
|
|
|
|||
|
|
@ -1,89 +1,92 @@
|
|||
// 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_TEXTURE_HPP
|
||||
#define NAZARA_TEXTURE_HPP
|
||||
|
||||
#include <Nazara/Prerequesites.hpp>
|
||||
#include <Nazara/Core/NonCopyable.hpp>
|
||||
#include <Nazara/Renderer/Enums.hpp>
|
||||
#include <Nazara/Utility/Image.hpp>
|
||||
#include <Nazara/Utility/PixelFormat.hpp>
|
||||
|
||||
struct NzTextureImpl;
|
||||
|
||||
class NAZARA_API NzTexture : public NzResource, NzNonCopyable
|
||||
{
|
||||
friend class NzShader;
|
||||
|
||||
public:
|
||||
NzTexture();
|
||||
explicit NzTexture(const NzImage& image);
|
||||
~NzTexture();
|
||||
|
||||
#ifndef NAZARA_RENDERER_COMMON
|
||||
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 Download(NzImage* image) const;
|
||||
|
||||
bool EnableMipmapping(bool enable);
|
||||
|
||||
unsigned int GetAnisotropyLevel() const;
|
||||
nzUInt8 GetBPP() const;
|
||||
unsigned int GetDepth() const;
|
||||
nzTextureFilter GetFilterMode() const;
|
||||
nzPixelFormat GetFormat() const;
|
||||
unsigned int GetHeight() const;
|
||||
nzImageType GetType() const;
|
||||
unsigned int GetWidth() const;
|
||||
nzTextureWrap GetWrapMode() const;
|
||||
|
||||
bool IsCompressed() const;
|
||||
bool IsCubemap() const;
|
||||
bool IsTarget() const;
|
||||
bool IsValid() const;
|
||||
|
||||
bool LoadFromFile(const NzString& filePath, const NzImageParams& params = NzImageParams());
|
||||
bool LoadFromImage(const NzImage& image);
|
||||
bool LoadFromMemory(const void* data, std::size_t size, const NzImageParams& params = NzImageParams());
|
||||
bool LoadFromStream(NzInputStream& stream, const NzImageParams& params = NzImageParams());
|
||||
|
||||
bool Lock();
|
||||
|
||||
bool SetAnisotropyLevel(unsigned int anistropyLevel);
|
||||
bool SetFilterMode(nzTextureFilter filter);
|
||||
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, const NzCubeui& cube, nzUInt8 level = 0);
|
||||
bool Update(const nzUInt8* pixels, nzUInt8 level = 0);
|
||||
bool Update(const nzUInt8* pixels, const NzRectui& rect, unsigned int z = 0, nzUInt8 level = 0);
|
||||
bool Update(const nzUInt8* pixels, const NzCubeui& cube, nzUInt8 level = 0);
|
||||
bool UpdateFace(nzCubemapFace face, const NzImage& image, nzUInt8 level = 0);
|
||||
bool UpdateFace(nzCubemapFace face, const NzImage& image, 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();
|
||||
|
||||
static unsigned int GetValidSize(unsigned int size);
|
||||
static bool IsFormatSupported(nzPixelFormat format);
|
||||
static bool IsMipmappingSupported();
|
||||
static bool IsTypeSupported(nzImageType type);
|
||||
|
||||
private:
|
||||
void SetTarget(bool isTarget);
|
||||
|
||||
NzTextureImpl* m_impl;
|
||||
};
|
||||
|
||||
#endif // NAZARA_TEXTURE_HPP
|
||||
// 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_TEXTURE_HPP
|
||||
#define NAZARA_TEXTURE_HPP
|
||||
|
||||
#include <Nazara/Prerequesites.hpp>
|
||||
#include <Nazara/Core/NonCopyable.hpp>
|
||||
#include <Nazara/Renderer/Enums.hpp>
|
||||
#include <Nazara/Utility/Image.hpp>
|
||||
#include <Nazara/Utility/PixelFormat.hpp>
|
||||
|
||||
class NzRenderTexture;
|
||||
struct NzTextureImpl;
|
||||
|
||||
class NAZARA_API NzTexture : public NzResource, NzNonCopyable
|
||||
{
|
||||
friend NzRenderTexture;
|
||||
friend class NzShader;
|
||||
|
||||
public:
|
||||
NzTexture();
|
||||
explicit NzTexture(const NzImage& image);
|
||||
~NzTexture();
|
||||
|
||||
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 EnableMipmapping(bool enable);
|
||||
|
||||
unsigned int GetAnisotropyLevel() const;
|
||||
nzUInt8 GetBPP() const;
|
||||
unsigned int GetDepth() const;
|
||||
nzTextureFilter GetFilterMode() const;
|
||||
nzPixelFormat GetFormat() const;
|
||||
unsigned int GetHeight() const;
|
||||
nzImageType GetType() const;
|
||||
unsigned int GetWidth() const;
|
||||
nzTextureWrap GetWrapMode() const;
|
||||
|
||||
bool IsCompressed() const;
|
||||
bool IsCubemap() const;
|
||||
bool IsTarget() const;
|
||||
bool IsValid() const;
|
||||
|
||||
bool LoadFromFile(const NzString& filePath, const NzImageParams& params = NzImageParams());
|
||||
bool LoadFromImage(const NzImage& image);
|
||||
bool LoadFromMemory(const void* data, std::size_t size, const NzImageParams& params = NzImageParams());
|
||||
bool LoadFromStream(NzInputStream& stream, const NzImageParams& params = NzImageParams());
|
||||
|
||||
bool Lock();
|
||||
|
||||
bool SetAnisotropyLevel(unsigned int anistropyLevel);
|
||||
bool SetFilterMode(nzTextureFilter filter);
|
||||
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, const NzCubeui& cube, nzUInt8 level = 0);
|
||||
bool Update(const nzUInt8* pixels, nzUInt8 level = 0);
|
||||
bool Update(const nzUInt8* pixels, const NzRectui& rect, unsigned int z = 0, nzUInt8 level = 0);
|
||||
bool Update(const nzUInt8* pixels, const NzCubeui& cube, nzUInt8 level = 0);
|
||||
bool UpdateFace(nzCubemapFace face, const NzImage& image, nzUInt8 level = 0);
|
||||
bool UpdateFace(nzCubemapFace face, const NzImage& image, 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();
|
||||
|
||||
// Fonctions OpenGL
|
||||
unsigned int GetOpenGLID() const;
|
||||
bool Prepare() const;
|
||||
|
||||
static unsigned int GetValidSize(unsigned int size);
|
||||
static bool IsFormatSupported(nzPixelFormat format);
|
||||
static bool IsMipmappingSupported();
|
||||
static bool IsTypeSupported(nzImageType type);
|
||||
|
||||
private:
|
||||
NzRenderTexture* GetRenderTexture() const;
|
||||
void SetRenderTexture(NzRenderTexture* renderTexture);
|
||||
|
||||
NzTextureImpl* m_impl;
|
||||
};
|
||||
|
||||
#endif // NAZARA_TEXTURE_HPP
|
||||
|
|
|
|||
|
|
@ -1,77 +1,78 @@
|
|||
// Copyright (C) 2012 Jérôme Leclercq
|
||||
// This file is part of the "Nazara Engine - Utility module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef NAZARA_ANIMATION_HPP
|
||||
#define NAZARA_ANIMATION_HPP
|
||||
|
||||
#include <Nazara/Prerequesites.hpp>
|
||||
#include <Nazara/Core/Resource.hpp>
|
||||
#include <Nazara/Core/ResourceLoader.hpp>
|
||||
#include <Nazara/Core/String.hpp>
|
||||
#include <Nazara/Utility/Enums.hpp>
|
||||
|
||||
struct NzAnimationParams
|
||||
{
|
||||
unsigned int endFrame = static_cast<unsigned int>(-1);
|
||||
unsigned int startFrame = 0;
|
||||
|
||||
bool IsValid() const;
|
||||
};
|
||||
|
||||
struct NzSequence
|
||||
{
|
||||
NzString name;
|
||||
unsigned int firstFrame;
|
||||
unsigned int lastFrame;
|
||||
unsigned int framePerSecond;
|
||||
};
|
||||
|
||||
class NzAnimation;
|
||||
|
||||
using NzAnimationLoader = NzResourceLoader<NzAnimation, NzAnimationParams>;
|
||||
|
||||
struct NzAnimationImpl;
|
||||
|
||||
class NAZARA_API NzAnimation : public NzResource
|
||||
{
|
||||
friend NzAnimationLoader;
|
||||
|
||||
public:
|
||||
NzAnimation() = default;
|
||||
~NzAnimation();
|
||||
|
||||
unsigned int AddSequence(const NzSequence& sequence);
|
||||
|
||||
bool Create(nzAnimationType type, unsigned int frameCount);
|
||||
void Destroy();
|
||||
|
||||
unsigned int GetFrameCount() const;
|
||||
NzSequence* GetSequence(const NzString& sequenceName);
|
||||
NzSequence* GetSequence(unsigned int index);
|
||||
const NzSequence* GetSequence(const NzString& sequenceName) const;
|
||||
const NzSequence* GetSequence(unsigned int index) const;
|
||||
unsigned int GetSequenceCount() const;
|
||||
nzAnimationType GetType() const;
|
||||
|
||||
bool HasSequence(const NzString& sequenceName) const;
|
||||
bool HasSequence(unsigned int index = 0) 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 LoadFromStream(NzInputStream& stream, const NzAnimationParams& params = NzAnimationParams());
|
||||
|
||||
void RemoveSequence(const NzString& sequenceName);
|
||||
void RemoveSequence(unsigned int index);
|
||||
|
||||
private:
|
||||
NzAnimationImpl* m_impl = nullptr;
|
||||
|
||||
static NzAnimationLoader::LoaderList s_loaders;
|
||||
};
|
||||
|
||||
#endif // NAZARA_ANIMATION_HPP
|
||||
// Copyright (C) 2012 Jérôme Leclercq
|
||||
// This file is part of the "Nazara Engine - Utility module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef NAZARA_ANIMATION_HPP
|
||||
#define NAZARA_ANIMATION_HPP
|
||||
|
||||
#include <Nazara/Prerequesites.hpp>
|
||||
#include <Nazara/Core/Resource.hpp>
|
||||
#include <Nazara/Core/ResourceLoader.hpp>
|
||||
#include <Nazara/Core/String.hpp>
|
||||
#include <Nazara/Utility/Enums.hpp>
|
||||
|
||||
struct NzAnimationParams
|
||||
{
|
||||
unsigned int endFrame = static_cast<unsigned int>(-1);
|
||||
unsigned int startFrame = 0;
|
||||
|
||||
bool IsValid() const;
|
||||
};
|
||||
|
||||
struct NzSequence
|
||||
{
|
||||
NzString name;
|
||||
unsigned int firstFrame;
|
||||
unsigned int lastFrame;
|
||||
unsigned int framePerSecond;
|
||||
};
|
||||
|
||||
class NzAnimation;
|
||||
|
||||
using NzAnimationLoader = NzResourceLoader<NzAnimation, NzAnimationParams>;
|
||||
|
||||
struct NzAnimationImpl;
|
||||
|
||||
class NAZARA_API NzAnimation : public NzResource
|
||||
{
|
||||
friend NzAnimationLoader;
|
||||
|
||||
public:
|
||||
NzAnimation() = default;
|
||||
~NzAnimation();
|
||||
|
||||
bool AddSequence(const NzSequence& sequence);
|
||||
|
||||
bool Create(nzAnimationType type, unsigned int frameCount);
|
||||
void Destroy();
|
||||
|
||||
unsigned int GetFrameCount() const;
|
||||
NzSequence* GetSequence(const NzString& sequenceName);
|
||||
NzSequence* GetSequence(unsigned int index);
|
||||
const NzSequence* GetSequence(const NzString& sequenceName) const;
|
||||
const NzSequence* GetSequence(unsigned int index) const;
|
||||
unsigned int GetSequenceCount() const;
|
||||
int GetSequenceIndex(const NzString& sequenceName) const;
|
||||
nzAnimationType GetType() const;
|
||||
|
||||
bool HasSequence(const NzString& sequenceName) const;
|
||||
bool HasSequence(unsigned int index = 0) 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 LoadFromStream(NzInputStream& stream, const NzAnimationParams& params = NzAnimationParams());
|
||||
|
||||
void RemoveSequence(const NzString& sequenceName);
|
||||
void RemoveSequence(unsigned int index);
|
||||
|
||||
private:
|
||||
NzAnimationImpl* m_impl = nullptr;
|
||||
|
||||
static NzAnimationLoader::LoaderList s_loaders;
|
||||
};
|
||||
|
||||
#endif // NAZARA_ANIMATION_HPP
|
||||
|
|
|
|||
|
|
@ -1,220 +1,250 @@
|
|||
// Copyright (C) 2012 Jérôme Leclercq
|
||||
// This file is part of the "Nazara Engine - Utility module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef NAZARA_ENUMS_UTILITY_HPP
|
||||
#define NAZARA_ENUMS_UTILITY_HPP
|
||||
|
||||
enum nzAnimationType
|
||||
{
|
||||
nzAnimationType_Keyframe,
|
||||
nzAnimationType_Skeletal,
|
||||
nzAnimationType_Static
|
||||
};
|
||||
|
||||
enum nzBufferAccess
|
||||
{
|
||||
nzBufferAccess_DiscardAndWrite,
|
||||
nzBufferAccess_ReadOnly,
|
||||
nzBufferAccess_ReadWrite,
|
||||
nzBufferAccess_WriteOnly
|
||||
};
|
||||
|
||||
enum nzBufferStorage
|
||||
{
|
||||
//nzBufferStorage_Both,
|
||||
nzBufferStorage_Hardware,
|
||||
nzBufferStorage_Software,
|
||||
|
||||
nzBufferStorage_Max = nzBufferStorage_Software
|
||||
};
|
||||
|
||||
enum nzBufferType
|
||||
{
|
||||
nzBufferType_Index,
|
||||
nzBufferType_Vertex
|
||||
};
|
||||
|
||||
enum nzBufferUsage
|
||||
{
|
||||
nzBufferUsage_Dynamic,
|
||||
nzBufferUsage_Static
|
||||
};
|
||||
|
||||
enum nzCubemapFace
|
||||
{
|
||||
// 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
|
||||
nzCubemapFace_PositiveX = 0,
|
||||
nzCubemapFace_PositiveY = 2,
|
||||
nzCubemapFace_PositiveZ = 4,
|
||||
nzCubemapFace_NegativeX = 1,
|
||||
nzCubemapFace_NegativeY = 3,
|
||||
nzCubemapFace_NegativeZ = 5
|
||||
};
|
||||
|
||||
enum nzElementStream
|
||||
{
|
||||
nzElementStream_VertexData,
|
||||
nzElementStream_InstancedData,
|
||||
|
||||
nzElementStream_Max = nzElementStream_InstancedData
|
||||
};
|
||||
|
||||
enum nzElementType
|
||||
{
|
||||
nzElementType_Color,
|
||||
nzElementType_Double1,
|
||||
nzElementType_Double2,
|
||||
nzElementType_Double3,
|
||||
nzElementType_Double4,
|
||||
nzElementType_Float1,
|
||||
nzElementType_Float2,
|
||||
nzElementType_Float3,
|
||||
nzElementType_Float4
|
||||
};
|
||||
|
||||
enum nzElementUsage
|
||||
{
|
||||
nzElementUsage_Diffuse,
|
||||
nzElementUsage_Normal,
|
||||
nzElementUsage_Position,
|
||||
nzElementUsage_Tangent,
|
||||
nzElementUsage_TexCoord,
|
||||
|
||||
nzElementUsage_Max = nzElementUsage_TexCoord
|
||||
};
|
||||
|
||||
enum nzEventType
|
||||
{
|
||||
nzEventType_GainedFocus,
|
||||
nzEventType_LostFocus,
|
||||
nzEventType_KeyPressed,
|
||||
nzEventType_KeyReleased,
|
||||
nzEventType_MouseButtonDoubleClicked,
|
||||
nzEventType_MouseButtonPressed,
|
||||
nzEventType_MouseButtonReleased,
|
||||
nzEventType_MouseEntered,
|
||||
nzEventType_MouseLeft,
|
||||
nzEventType_MouseMoved,
|
||||
nzEventType_MouseWheelMoved,
|
||||
nzEventType_Moved,
|
||||
nzEventType_Quit,
|
||||
nzEventType_Resized,
|
||||
nzEventType_TextEntered
|
||||
};
|
||||
|
||||
enum nzExtend
|
||||
{
|
||||
nzExtend_Finite,
|
||||
nzExtend_Infinite,
|
||||
nzExtend_Null
|
||||
};
|
||||
|
||||
enum nzImageType
|
||||
{
|
||||
nzImageType_1D,
|
||||
nzImageType_1D_Array,
|
||||
nzImageType_2D,
|
||||
nzImageType_2D_Array,
|
||||
nzImageType_3D,
|
||||
nzImageType_Cubemap,
|
||||
|
||||
nzImageType_Max = nzImageType_Cubemap
|
||||
};
|
||||
|
||||
enum nzPixelFormat
|
||||
{
|
||||
nzPixelFormat_Undefined = -1,
|
||||
|
||||
nzPixelFormat_BGR8, // 3*nzUInt8
|
||||
nzPixelFormat_BGRA8, // 4*nzUInt8
|
||||
nzPixelFormat_DXT1,
|
||||
nzPixelFormat_DXT3,
|
||||
nzPixelFormat_DXT5,
|
||||
nzPixelFormat_L8, // 1*nzUInt8
|
||||
nzPixelFormat_LA8, // 2*nzUInt8
|
||||
/*
|
||||
nzPixelFormat_RGB16F,
|
||||
nzPixelFormat_RGB16I, // 4*nzUInt16
|
||||
nzPixelFormat_RGB32F,
|
||||
nzPixelFormat_RGB32I, // 4*nzUInt32
|
||||
nzPixelFormat_RGBA16F,
|
||||
nzPixelFormat_RGBA16I, // 4*nzUInt16
|
||||
nzPixelFormat_RGBA32F,
|
||||
nzPixelFormat_RGBA32I, // 4*nzUInt32
|
||||
*/
|
||||
nzPixelFormat_RGBA4, // 1*nzUInt16
|
||||
nzPixelFormat_RGB5A1, // 1*nzUInt16
|
||||
nzPixelFormat_RGB8, // 3*nzUInt8
|
||||
nzPixelFormat_RGBA8, // 4*nzUInt8
|
||||
/*
|
||||
nzPixelFormat_Depth16,
|
||||
nzPixelFormat_Depth24,
|
||||
nzPixelFormat_Depth24Stencil8,
|
||||
nzPixelFormat_Depth32,
|
||||
nzPixelFormat_Stencil1,
|
||||
nzPixelFormat_Stencil4,
|
||||
nzPixelFormat_Stencil8,
|
||||
nzPixelFormat_Stencil16,
|
||||
*/
|
||||
|
||||
nzPixelFormat_Max = nzPixelFormat_RGBA8
|
||||
};
|
||||
|
||||
enum nzPixelFlipping
|
||||
{
|
||||
nzPixelFlipping_Horizontally,
|
||||
nzPixelFlipping_Vertically,
|
||||
|
||||
nzPixelFlipping_Max = nzPixelFlipping_Vertically
|
||||
};
|
||||
|
||||
enum nzPrimitiveType
|
||||
{
|
||||
nzPrimitiveType_LineList,
|
||||
nzPrimitiveType_LineStrip,
|
||||
nzPrimitiveType_PointList,
|
||||
nzPrimitiveType_TriangleList,
|
||||
nzPrimitiveType_TriangleStrip,
|
||||
nzPrimitiveType_TriangleFan
|
||||
};
|
||||
|
||||
enum nzWindowCursor
|
||||
{
|
||||
nzWindowCursor_None,
|
||||
nzWindowCursor_Default,
|
||||
|
||||
nzWindowCursor_Crosshair,
|
||||
nzWindowCursor_Hand,
|
||||
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
|
||||
};
|
||||
|
||||
enum nzWindowStyle
|
||||
{
|
||||
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
|
||||
// Copyright (C) 2012 Jérôme Leclercq
|
||||
// This file is part of the "Nazara Engine - Utility module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef NAZARA_ENUMS_UTILITY_HPP
|
||||
#define NAZARA_ENUMS_UTILITY_HPP
|
||||
|
||||
enum nzAnimationType
|
||||
{
|
||||
nzAnimationType_Keyframe,
|
||||
nzAnimationType_Skeletal,
|
||||
nzAnimationType_Static,
|
||||
|
||||
nzAnimationType_Max = nzAnimationType_Static
|
||||
};
|
||||
|
||||
enum nzBufferAccess
|
||||
{
|
||||
nzBufferAccess_DiscardAndWrite,
|
||||
nzBufferAccess_ReadOnly,
|
||||
nzBufferAccess_ReadWrite,
|
||||
nzBufferAccess_WriteOnly,
|
||||
|
||||
nzBufferAccess_Max = nzBufferAccess_WriteOnly
|
||||
};
|
||||
|
||||
enum nzBufferStorage
|
||||
{
|
||||
//nzBufferStorage_Both,
|
||||
nzBufferStorage_Hardware,
|
||||
nzBufferStorage_Software,
|
||||
|
||||
nzBufferStorage_Max = nzBufferStorage_Software
|
||||
};
|
||||
|
||||
enum nzBufferType
|
||||
{
|
||||
nzBufferType_Index,
|
||||
nzBufferType_Vertex,
|
||||
|
||||
nzBufferType_Max = nzBufferType_Vertex
|
||||
};
|
||||
|
||||
enum nzBufferUsage
|
||||
{
|
||||
nzBufferUsage_Dynamic,
|
||||
nzBufferUsage_Static,
|
||||
|
||||
nzBufferUsage_Max = nzBufferUsage_Static
|
||||
};
|
||||
|
||||
enum nzCubemapFace
|
||||
{
|
||||
// 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
|
||||
nzCubemapFace_PositiveX = 0,
|
||||
nzCubemapFace_PositiveY = 2,
|
||||
nzCubemapFace_PositiveZ = 4,
|
||||
nzCubemapFace_NegativeX = 1,
|
||||
nzCubemapFace_NegativeY = 3,
|
||||
nzCubemapFace_NegativeZ = 5,
|
||||
|
||||
nzCubemapFace_Max = nzCubemapFace_NegativeZ
|
||||
};
|
||||
|
||||
enum nzElementStream
|
||||
{
|
||||
nzElementStream_VertexData,
|
||||
nzElementStream_InstancedData,
|
||||
|
||||
nzElementStream_Max = nzElementStream_InstancedData
|
||||
};
|
||||
|
||||
enum nzElementType
|
||||
{
|
||||
nzElementType_Color,
|
||||
nzElementType_Double1,
|
||||
nzElementType_Double2,
|
||||
nzElementType_Double3,
|
||||
nzElementType_Double4,
|
||||
nzElementType_Float1,
|
||||
nzElementType_Float2,
|
||||
nzElementType_Float3,
|
||||
nzElementType_Float4,
|
||||
|
||||
nzElementType_Max = nzElementType_Float4
|
||||
};
|
||||
|
||||
enum nzElementUsage
|
||||
{
|
||||
nzElementUsage_Diffuse,
|
||||
nzElementUsage_Normal,
|
||||
nzElementUsage_Position,
|
||||
nzElementUsage_Tangent,
|
||||
nzElementUsage_TexCoord,
|
||||
|
||||
nzElementUsage_Max = nzElementUsage_TexCoord
|
||||
};
|
||||
|
||||
enum nzEventType
|
||||
{
|
||||
nzEventType_GainedFocus,
|
||||
nzEventType_LostFocus,
|
||||
nzEventType_KeyPressed,
|
||||
nzEventType_KeyReleased,
|
||||
nzEventType_MouseButtonDoubleClicked,
|
||||
nzEventType_MouseButtonPressed,
|
||||
nzEventType_MouseButtonReleased,
|
||||
nzEventType_MouseEntered,
|
||||
nzEventType_MouseLeft,
|
||||
nzEventType_MouseMoved,
|
||||
nzEventType_MouseWheelMoved,
|
||||
nzEventType_Moved,
|
||||
nzEventType_Quit,
|
||||
nzEventType_Resized,
|
||||
nzEventType_TextEntered,
|
||||
|
||||
nzEventType_Max = nzEventType_TextEntered
|
||||
};
|
||||
|
||||
enum nzExtend
|
||||
{
|
||||
nzExtend_Finite,
|
||||
nzExtend_Infinite,
|
||||
nzExtend_Null,
|
||||
|
||||
nzExtend_Max = nzExtend_Null
|
||||
};
|
||||
|
||||
enum nzImageType
|
||||
{
|
||||
nzImageType_1D,
|
||||
nzImageType_1D_Array,
|
||||
nzImageType_2D,
|
||||
nzImageType_2D_Array,
|
||||
nzImageType_3D,
|
||||
nzImageType_Cubemap,
|
||||
|
||||
nzImageType_Max = nzImageType_Cubemap
|
||||
};
|
||||
|
||||
enum nzPixelFormat
|
||||
{
|
||||
nzPixelFormat_Undefined = -1,
|
||||
|
||||
nzPixelFormat_BGR8, // 3*nzUInt8
|
||||
nzPixelFormat_BGRA8, // 4*nzUInt8
|
||||
nzPixelFormat_DXT1,
|
||||
nzPixelFormat_DXT3,
|
||||
nzPixelFormat_DXT5,
|
||||
nzPixelFormat_L8, // 1*nzUInt8
|
||||
nzPixelFormat_LA8, // 2*nzUInt8
|
||||
/*
|
||||
nzPixelFormat_RGB16F,
|
||||
nzPixelFormat_RGB16I, // 4*nzUInt16
|
||||
nzPixelFormat_RGB32F,
|
||||
nzPixelFormat_RGB32I, // 4*nzUInt32
|
||||
nzPixelFormat_RGBA16F,
|
||||
nzPixelFormat_RGBA16I, // 4*nzUInt16
|
||||
nzPixelFormat_RGBA32F,
|
||||
nzPixelFormat_RGBA32I, // 4*nzUInt32
|
||||
*/
|
||||
nzPixelFormat_RGBA4, // 1*nzUInt16
|
||||
nzPixelFormat_RGB5A1, // 1*nzUInt16
|
||||
nzPixelFormat_RGB8, // 3*nzUInt8
|
||||
nzPixelFormat_RGBA8, // 4*nzUInt8
|
||||
nzPixelFormat_Depth16,
|
||||
nzPixelFormat_Depth24,
|
||||
nzPixelFormat_Depth24Stencil8,
|
||||
nzPixelFormat_Depth32,
|
||||
nzPixelFormat_Stencil1,
|
||||
nzPixelFormat_Stencil4,
|
||||
nzPixelFormat_Stencil8,
|
||||
nzPixelFormat_Stencil16,
|
||||
|
||||
nzPixelFormat_Max = nzPixelFormat_Stencil16
|
||||
};
|
||||
|
||||
enum nzPixelFormatType
|
||||
{
|
||||
nzPixelFormatType_Undefined = -1,
|
||||
|
||||
nzPixelFormatType_Color,
|
||||
nzPixelFormatType_Depth,
|
||||
nzPixelFormatType_DepthStencil,
|
||||
nzPixelFormatType_Stencil,
|
||||
|
||||
nzPixelFormatType_Max = nzPixelFormatType_Stencil
|
||||
};
|
||||
|
||||
enum nzPixelFlipping
|
||||
{
|
||||
nzPixelFlipping_Horizontally,
|
||||
nzPixelFlipping_Vertically,
|
||||
|
||||
nzPixelFlipping_Max = nzPixelFlipping_Vertically
|
||||
};
|
||||
|
||||
enum nzPrimitiveType
|
||||
{
|
||||
nzPrimitiveType_LineList,
|
||||
nzPrimitiveType_LineStrip,
|
||||
nzPrimitiveType_PointList,
|
||||
nzPrimitiveType_TriangleList,
|
||||
nzPrimitiveType_TriangleStrip,
|
||||
nzPrimitiveType_TriangleFan,
|
||||
|
||||
nzPrimitiveType_Max = nzPrimitiveType_TriangleFan
|
||||
};
|
||||
|
||||
enum nzWindowCursor
|
||||
{
|
||||
nzWindowCursor_None,
|
||||
nzWindowCursor_Default,
|
||||
|
||||
nzWindowCursor_Crosshair,
|
||||
nzWindowCursor_Hand,
|
||||
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
|
||||
// This file is part of the "Nazara Engine - Utility module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef NAZARA_MESH_HPP
|
||||
#define NAZARA_MESH_HPP
|
||||
|
||||
#include <Nazara/Prerequesites.hpp>
|
||||
#include <Nazara/Core/InputStream.hpp>
|
||||
#include <Nazara/Core/Resource.hpp>
|
||||
#include <Nazara/Core/ResourceLoader.hpp>
|
||||
#include <Nazara/Core/String.hpp>
|
||||
#include <Nazara/Utility/Animation.hpp>
|
||||
#include <Nazara/Utility/AxisAlignedBox.hpp>
|
||||
#include <Nazara/Utility/SubMesh.hpp>
|
||||
|
||||
class NzVertexDeclaration;
|
||||
|
||||
struct NzMeshParams
|
||||
{
|
||||
NzAnimationParams animation;
|
||||
//const NzVertexDeclaration* declaration = nullptr;
|
||||
nzBufferStorage storage = nzBufferStorage_Hardware;
|
||||
bool loadAnimations = true;
|
||||
|
||||
bool IsValid() const;
|
||||
};
|
||||
|
||||
class NzMesh;
|
||||
|
||||
using NzMeshLoader = NzResourceLoader<NzMesh, NzMeshParams>;
|
||||
|
||||
struct NzMeshImpl;
|
||||
|
||||
class NAZARA_API NzMesh : public NzResource
|
||||
{
|
||||
friend NzMeshLoader;
|
||||
|
||||
public:
|
||||
NzMesh() = default;
|
||||
~NzMesh();
|
||||
|
||||
unsigned int AddSkin(const NzString& skin, bool setDefault = false);
|
||||
nzUInt8 AddSubMesh(NzSubMesh* subMesh);
|
||||
nzUInt8 AddSubMesh(const NzString& identifier, NzSubMesh* subMesh);
|
||||
|
||||
void Animate(unsigned int frameA, unsigned int frameB, float interpolation);
|
||||
|
||||
bool Create(nzAnimationType type);
|
||||
void Destroy();
|
||||
|
||||
const NzAxisAlignedBox& GetAABB() const;
|
||||
const NzAnimation* GetAnimation() const;
|
||||
nzAnimationType GetAnimationType() const;
|
||||
unsigned int GetFrameCount() const;
|
||||
NzString GetSkin(unsigned int index = 0) const;
|
||||
unsigned int GetSkinCount() const;
|
||||
NzSubMesh* GetSubMesh(const NzString& identifier);
|
||||
NzSubMesh* GetSubMesh(nzUInt8 index);
|
||||
const NzSubMesh* GetSubMesh(const NzString& identifier) const;
|
||||
const NzSubMesh* GetSubMesh(nzUInt8 index) const;
|
||||
nzUInt8 GetSubMeshCount() const;
|
||||
unsigned int GetVertexCount() const;
|
||||
|
||||
bool HasAnimation() const;
|
||||
bool HasSkin(unsigned int index = 0) const;
|
||||
bool HasSubMesh(const NzString& identifier) const;
|
||||
bool HasSubMesh(nzUInt8 index = 0) const;
|
||||
|
||||
void InvalidateAABB() const;
|
||||
|
||||
bool IsAnimable() const;
|
||||
bool IsValid() const;
|
||||
|
||||
bool LoadFromFile(const NzString& filePath, const NzMeshParams& params = NzMeshParams());
|
||||
bool LoadFromMemory(const void* data, std::size_t size, const NzMeshParams& params = NzMeshParams());
|
||||
bool LoadFromStream(NzInputStream& stream, const NzMeshParams& params = NzMeshParams());
|
||||
|
||||
void RemoveSkin(unsigned int index = 0);
|
||||
void RemoveSubMesh(const NzString& identifier);
|
||||
void RemoveSubMesh(nzUInt8 index = 0);
|
||||
|
||||
bool SetAnimation(const NzAnimation* animation);
|
||||
|
||||
private:
|
||||
NzMeshImpl* m_impl = nullptr;
|
||||
|
||||
static NzMeshLoader::LoaderList s_loaders;
|
||||
};
|
||||
|
||||
#endif // NAZARA_MESH_HPP
|
||||
// Copyright (C) 2012 Jérôme Leclercq
|
||||
// This file is part of the "Nazara Engine - Utility module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef NAZARA_MESH_HPP
|
||||
#define NAZARA_MESH_HPP
|
||||
|
||||
#include <Nazara/Prerequesites.hpp>
|
||||
#include <Nazara/Core/InputStream.hpp>
|
||||
#include <Nazara/Core/Resource.hpp>
|
||||
#include <Nazara/Core/ResourceListener.hpp>
|
||||
#include <Nazara/Core/ResourceLoader.hpp>
|
||||
#include <Nazara/Core/String.hpp>
|
||||
#include <Nazara/Utility/Animation.hpp>
|
||||
#include <Nazara/Utility/AxisAlignedBox.hpp>
|
||||
#include <Nazara/Utility/SubMesh.hpp>
|
||||
|
||||
class NzVertexDeclaration;
|
||||
|
||||
struct NzMeshParams
|
||||
{
|
||||
NzAnimationParams animation;
|
||||
//const NzVertexDeclaration* declaration = nullptr;
|
||||
nzBufferStorage storage = nzBufferStorage_Hardware;
|
||||
bool loadAnimations = true;
|
||||
|
||||
bool IsValid() const;
|
||||
};
|
||||
|
||||
class NzMesh;
|
||||
|
||||
using NzMeshLoader = NzResourceLoader<NzMesh, NzMeshParams>;
|
||||
|
||||
struct NzMeshImpl;
|
||||
|
||||
class NAZARA_API NzMesh : public NzResource, NzResourceListener
|
||||
{
|
||||
friend NzMeshLoader;
|
||||
|
||||
public:
|
||||
NzMesh() = default;
|
||||
~NzMesh();
|
||||
|
||||
bool AddSkin(const NzString& skin, bool setDefault = false);
|
||||
bool AddSubMesh(NzSubMesh* subMesh);
|
||||
bool AddSubMesh(const NzString& identifier, NzSubMesh* subMesh);
|
||||
|
||||
void Animate(unsigned int frameA, unsigned int frameB, float interpolation);
|
||||
|
||||
bool Create(nzAnimationType type);
|
||||
void Destroy();
|
||||
|
||||
const NzAxisAlignedBox& GetAABB() const;
|
||||
const NzAnimation* GetAnimation() const;
|
||||
nzAnimationType GetAnimationType() const;
|
||||
unsigned int GetFrameCount() const;
|
||||
NzString GetSkin(unsigned int index = 0) const;
|
||||
unsigned int GetSkinCount() const;
|
||||
NzSubMesh* GetSubMesh(const NzString& identifier);
|
||||
NzSubMesh* GetSubMesh(unsigned int index);
|
||||
const NzSubMesh* GetSubMesh(const NzString& identifier) const;
|
||||
const NzSubMesh* GetSubMesh(unsigned int index) const;
|
||||
unsigned int GetSubMeshCount() const;
|
||||
int GetSubMeshIndex(const NzString& identifier) const;
|
||||
unsigned int GetVertexCount() const;
|
||||
|
||||
bool HasAnimation() const;
|
||||
bool HasSkin(unsigned int index = 0) const;
|
||||
bool HasSubMesh(const NzString& identifier) const;
|
||||
bool HasSubMesh(unsigned int index = 0) const;
|
||||
|
||||
void InvalidateAABB() const;
|
||||
|
||||
bool IsAnimable() const;
|
||||
bool IsValid() const;
|
||||
|
||||
bool LoadFromFile(const NzString& filePath, const NzMeshParams& params = NzMeshParams());
|
||||
bool LoadFromMemory(const void* data, std::size_t size, const NzMeshParams& params = NzMeshParams());
|
||||
bool LoadFromStream(NzInputStream& stream, const NzMeshParams& params = NzMeshParams());
|
||||
|
||||
void RemoveSkin(unsigned int index = 0);
|
||||
void RemoveSubMesh(const NzString& identifier);
|
||||
void RemoveSubMesh(unsigned int index = 0);
|
||||
|
||||
bool SetAnimation(const NzAnimation* animation);
|
||||
|
||||
private:
|
||||
void OnResourceCreated(const NzResource* resource, int index) override;
|
||||
void OnResourceReleased(const NzResource* resource, int index) override;
|
||||
|
||||
NzMeshImpl* m_impl = nullptr;
|
||||
|
||||
static NzMeshLoader::LoaderList s_loaders;
|
||||
};
|
||||
|
||||
#endif // NAZARA_MESH_HPP
|
||||
|
|
|
|||
|
|
@ -1,53 +1,54 @@
|
|||
// Copyright (C) 2012 Jérôme Leclercq
|
||||
// This file is part of the "Nazara Engine - Utility module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef NAZARA_PIXELFORMAT_HPP
|
||||
#define NAZARA_PIXELFORMAT_HPP
|
||||
|
||||
#include <Nazara/Prerequesites.hpp>
|
||||
#include <Nazara/Core/String.hpp>
|
||||
#include <Nazara/Utility/Enums.hpp>
|
||||
#include <map>
|
||||
|
||||
class NzUtility;
|
||||
|
||||
class NzPixelFormat
|
||||
{
|
||||
friend class NzUtility;
|
||||
|
||||
public:
|
||||
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);
|
||||
|
||||
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 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 bool HasAlpha(nzPixelFormat format);
|
||||
|
||||
static bool IsCompressed(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 NzString ToString(nzPixelFormat format);
|
||||
|
||||
private:
|
||||
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];
|
||||
};
|
||||
|
||||
#include <Nazara/Utility/PixelFormat.inl>
|
||||
|
||||
#endif // NAZARA_PIXELFORMAT_HPP
|
||||
// Copyright (C) 2012 Jérôme Leclercq
|
||||
// This file is part of the "Nazara Engine - Utility module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef NAZARA_PIXELFORMAT_HPP
|
||||
#define NAZARA_PIXELFORMAT_HPP
|
||||
|
||||
#include <Nazara/Prerequesites.hpp>
|
||||
#include <Nazara/Core/String.hpp>
|
||||
#include <Nazara/Utility/Enums.hpp>
|
||||
#include <map>
|
||||
|
||||
class NzUtility;
|
||||
|
||||
class NzPixelFormat
|
||||
{
|
||||
friend class NzUtility;
|
||||
|
||||
public:
|
||||
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);
|
||||
|
||||
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 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 nzPixelFormatType GetType(nzPixelFormat format);
|
||||
|
||||
static bool HasAlpha(nzPixelFormat format);
|
||||
|
||||
static bool IsCompressed(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 NzString ToString(nzPixelFormat format);
|
||||
|
||||
private:
|
||||
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];
|
||||
};
|
||||
|
||||
#include <Nazara/Utility/PixelFormat.inl>
|
||||
|
||||
#endif // NAZARA_PIXELFORMAT_HPP
|
||||
|
|
|
|||
|
|
@ -1,371 +1,487 @@
|
|||
// Copyright (C) 2012 Jérôme Leclercq
|
||||
// This file is part of the "Nazara Engine - Utility module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#include <Nazara/Core/Error.hpp>
|
||||
#include <cstring>
|
||||
#include <Nazara/Utility/Debug.hpp>
|
||||
|
||||
inline bool NzPixelFormat::Convert(nzPixelFormat srcFormat, nzPixelFormat dstFormat, const void* src, void* dst)
|
||||
{
|
||||
if (srcFormat == dstFormat)
|
||||
{
|
||||
std::memcpy(dst, src, GetBPP(srcFormat));
|
||||
return true;
|
||||
}
|
||||
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (IsCompressed(srcFormat))
|
||||
{
|
||||
NazaraError("Cannot convert single pixel from compressed format");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (IsCompressed(dstFormat))
|
||||
{
|
||||
NazaraError("Cannot convert single pixel to compressed format");
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
ConvertFunction func = s_convertFunctions[srcFormat][dstFormat];
|
||||
if (!func)
|
||||
{
|
||||
NazaraError("Pixel format conversion from " + ToString(srcFormat) + " to " + ToString(dstFormat) + " is not supported");
|
||||
return false;
|
||||
}
|
||||
|
||||
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");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool NzPixelFormat::Convert(nzPixelFormat srcFormat, nzPixelFormat dstFormat, const void* start, const void* end, void* dst)
|
||||
{
|
||||
if (srcFormat == dstFormat)
|
||||
{
|
||||
std::memcpy(dst, start, reinterpret_cast<const nzUInt8*>(end)-reinterpret_cast<const nzUInt8*>(start));
|
||||
return true;
|
||||
}
|
||||
|
||||
ConvertFunction func = s_convertFunctions[srcFormat][dstFormat];
|
||||
if (!func)
|
||||
{
|
||||
NazaraError("Pixel format conversion from " + ToString(srcFormat) + " to " + ToString(dstFormat) + " is not supported");
|
||||
return false;
|
||||
}
|
||||
|
||||
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");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
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 (!IsValid(format))
|
||||
{
|
||||
NazaraError("Invalid pixel format");
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
auto it = s_flipFunctions[flipping].find(format);
|
||||
if (it != s_flipFunctions[flipping].end())
|
||||
it->second(width, height, depth, reinterpret_cast<const nzUInt8*>(src), reinterpret_cast<nzUInt8*>(dst));
|
||||
else
|
||||
{
|
||||
// Flipping générique
|
||||
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (IsCompressed(format))
|
||||
{
|
||||
NazaraError("No function to flip compressed format");
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
nzUInt8 bpp = GetBPP(format);
|
||||
unsigned int lineStride = width*bpp;
|
||||
switch (flipping)
|
||||
{
|
||||
case nzPixelFlipping_Horizontally:
|
||||
{
|
||||
if (src == dst)
|
||||
{
|
||||
for (unsigned int z = 0; z < depth; ++z)
|
||||
{
|
||||
nzUInt8* ptr = reinterpret_cast<nzUInt8*>(dst) + width*height*z;
|
||||
for (unsigned int y = 0; y < height; ++y)
|
||||
{
|
||||
for (unsigned int x = 0; x < width/2; ++x)
|
||||
std::swap_ranges(&ptr[x*bpp], &ptr[(x+1)*bpp], &ptr[(width-x)*bpp]);
|
||||
|
||||
ptr += lineStride;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (unsigned int z = 0; z < depth; ++z)
|
||||
{
|
||||
nzUInt8* ptr = reinterpret_cast<nzUInt8*>(dst) + width*height*z;
|
||||
for (unsigned int y = 0; y < height; ++y)
|
||||
{
|
||||
for (unsigned int x = 0; x < width; ++x)
|
||||
std::memcpy(&ptr[x*bpp], &ptr[(width-x)*bpp], bpp);
|
||||
|
||||
ptr += lineStride;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case nzPixelFlipping_Vertically:
|
||||
{
|
||||
if (src == dst)
|
||||
{
|
||||
for (unsigned int z = 0; z < depth; ++z)
|
||||
{
|
||||
nzUInt8* ptr = reinterpret_cast<nzUInt8*>(dst) + width*height*z;
|
||||
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]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (unsigned int z = 0; z < depth; ++z)
|
||||
{
|
||||
const nzUInt8* srcPtr = reinterpret_cast<const nzUInt8*>(src);
|
||||
nzUInt8* dstPtr = reinterpret_cast<nzUInt8*>(dst) + (width-1)*height*depth*bpp;
|
||||
for (unsigned int y = 0; y < height; ++y)
|
||||
{
|
||||
std::memcpy(dstPtr, srcPtr, lineStride);
|
||||
|
||||
srcPtr += lineStride;
|
||||
dstPtr -= lineStride;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
inline nzUInt8 NzPixelFormat::GetBPP(nzPixelFormat format)
|
||||
{
|
||||
switch (format)
|
||||
{
|
||||
case nzPixelFormat_BGR8:
|
||||
return 3;
|
||||
|
||||
case nzPixelFormat_BGRA8:
|
||||
return 4;
|
||||
|
||||
case nzPixelFormat_DXT1:
|
||||
return 1;
|
||||
|
||||
case nzPixelFormat_DXT3:
|
||||
return 2;
|
||||
|
||||
case nzPixelFormat_DXT5:
|
||||
return 2;
|
||||
|
||||
case nzPixelFormat_L8:
|
||||
return 1;
|
||||
|
||||
case nzPixelFormat_LA8:
|
||||
return 2;
|
||||
/*
|
||||
case nzPixelFormat_RGB16F:
|
||||
return 6;
|
||||
|
||||
case nzPixelFormat_RGB16I:
|
||||
return 6;
|
||||
|
||||
case nzPixelFormat_RGB32F:
|
||||
return 12;
|
||||
|
||||
case nzPixelFormat_RGB32I:
|
||||
return 12;
|
||||
|
||||
case nzPixelFormat_RGBA16F:
|
||||
return 8;
|
||||
|
||||
case nzPixelFormat_RGBA16I:
|
||||
return 8;
|
||||
|
||||
case nzPixelFormat_RGBA32F:
|
||||
return 16;
|
||||
|
||||
case nzPixelFormat_RGBA32I:
|
||||
return 16;
|
||||
*/
|
||||
case nzPixelFormat_RGBA4:
|
||||
return 2;
|
||||
|
||||
case nzPixelFormat_RGB5A1:
|
||||
return 2;
|
||||
|
||||
case nzPixelFormat_RGB8:
|
||||
return 3;
|
||||
|
||||
case nzPixelFormat_RGBA8:
|
||||
return 4;
|
||||
|
||||
case nzPixelFormat_Undefined:
|
||||
NazaraError("Invalid pixel format");
|
||||
return 0;
|
||||
}
|
||||
|
||||
NazaraInternalError("Invalid pixel format");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
inline bool NzPixelFormat::HasAlpha(nzPixelFormat format)
|
||||
{
|
||||
switch (format)
|
||||
{
|
||||
case nzPixelFormat_BGRA8:
|
||||
case nzPixelFormat_DXT3:
|
||||
case nzPixelFormat_DXT5:
|
||||
case nzPixelFormat_LA8:
|
||||
case nzPixelFormat_RGB5A1:
|
||||
case nzPixelFormat_RGBA4:
|
||||
case nzPixelFormat_RGBA8:
|
||||
return true;
|
||||
|
||||
case nzPixelFormat_BGR8:
|
||||
case nzPixelFormat_DXT1:
|
||||
case nzPixelFormat_L8:
|
||||
case nzPixelFormat_RGB8:
|
||||
return false;
|
||||
|
||||
case nzPixelFormat_Undefined:
|
||||
break;
|
||||
}
|
||||
|
||||
NazaraError("Invalid pixel format");
|
||||
return false;
|
||||
}
|
||||
|
||||
inline bool NzPixelFormat::IsCompressed(nzPixelFormat format)
|
||||
{
|
||||
switch (format)
|
||||
{
|
||||
case nzPixelFormat_DXT1:
|
||||
case nzPixelFormat_DXT3:
|
||||
case nzPixelFormat_DXT5:
|
||||
return true;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
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_Undefined:
|
||||
return "Undefined";
|
||||
}
|
||||
|
||||
NazaraError("Invalid pixel format");
|
||||
return "Invalid format";
|
||||
}
|
||||
|
||||
#include <Nazara/Utility/DebugOff.hpp>
|
||||
// Copyright (C) 2012 Jérôme Leclercq
|
||||
// This file is part of the "Nazara Engine - Utility module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#include <Nazara/Core/Error.hpp>
|
||||
#include <cstring>
|
||||
#include <Nazara/Utility/Debug.hpp>
|
||||
|
||||
inline bool NzPixelFormat::Convert(nzPixelFormat srcFormat, nzPixelFormat dstFormat, const void* src, void* dst)
|
||||
{
|
||||
if (srcFormat == dstFormat)
|
||||
{
|
||||
std::memcpy(dst, src, GetBPP(srcFormat));
|
||||
return true;
|
||||
}
|
||||
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (IsCompressed(srcFormat))
|
||||
{
|
||||
NazaraError("Cannot convert single pixel from compressed format");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (IsCompressed(dstFormat))
|
||||
{
|
||||
NazaraError("Cannot convert single pixel to compressed format");
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
ConvertFunction func = s_convertFunctions[srcFormat][dstFormat];
|
||||
if (!func)
|
||||
{
|
||||
NazaraError("Pixel format conversion from " + ToString(srcFormat) + " to " + ToString(dstFormat) + " is not supported");
|
||||
return false;
|
||||
}
|
||||
|
||||
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");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool NzPixelFormat::Convert(nzPixelFormat srcFormat, nzPixelFormat dstFormat, const void* start, const void* end, void* dst)
|
||||
{
|
||||
if (srcFormat == dstFormat)
|
||||
{
|
||||
std::memcpy(dst, start, reinterpret_cast<const nzUInt8*>(end)-reinterpret_cast<const nzUInt8*>(start));
|
||||
return true;
|
||||
}
|
||||
|
||||
ConvertFunction func = s_convertFunctions[srcFormat][dstFormat];
|
||||
if (!func)
|
||||
{
|
||||
NazaraError("Pixel format conversion from " + ToString(srcFormat) + " to " + ToString(dstFormat) + " is not supported");
|
||||
return false;
|
||||
}
|
||||
|
||||
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");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
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 (!IsValid(format))
|
||||
{
|
||||
NazaraError("Invalid pixel format");
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
auto it = s_flipFunctions[flipping].find(format);
|
||||
if (it != s_flipFunctions[flipping].end())
|
||||
it->second(width, height, depth, reinterpret_cast<const nzUInt8*>(src), reinterpret_cast<nzUInt8*>(dst));
|
||||
else
|
||||
{
|
||||
// Flipping générique
|
||||
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (IsCompressed(format))
|
||||
{
|
||||
NazaraError("No function to flip compressed format");
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
nzUInt8 bpp = GetBPP(format);
|
||||
unsigned int lineStride = width*bpp;
|
||||
switch (flipping)
|
||||
{
|
||||
case nzPixelFlipping_Horizontally:
|
||||
{
|
||||
if (src == dst)
|
||||
{
|
||||
for (unsigned int z = 0; z < depth; ++z)
|
||||
{
|
||||
nzUInt8* ptr = reinterpret_cast<nzUInt8*>(dst) + width*height*z;
|
||||
for (unsigned int y = 0; y < height; ++y)
|
||||
{
|
||||
for (unsigned int x = 0; x < width/2; ++x)
|
||||
std::swap_ranges(&ptr[x*bpp], &ptr[(x+1)*bpp], &ptr[(width-x)*bpp]);
|
||||
|
||||
ptr += lineStride;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (unsigned int z = 0; z < depth; ++z)
|
||||
{
|
||||
nzUInt8* ptr = reinterpret_cast<nzUInt8*>(dst) + width*height*z;
|
||||
for (unsigned int y = 0; y < height; ++y)
|
||||
{
|
||||
for (unsigned int x = 0; x < width; ++x)
|
||||
std::memcpy(&ptr[x*bpp], &ptr[(width-x)*bpp], bpp);
|
||||
|
||||
ptr += lineStride;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case nzPixelFlipping_Vertically:
|
||||
{
|
||||
if (src == dst)
|
||||
{
|
||||
for (unsigned int z = 0; z < depth; ++z)
|
||||
{
|
||||
nzUInt8* ptr = reinterpret_cast<nzUInt8*>(dst) + width*height*z;
|
||||
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]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (unsigned int z = 0; z < depth; ++z)
|
||||
{
|
||||
const nzUInt8* srcPtr = reinterpret_cast<const nzUInt8*>(src);
|
||||
nzUInt8* dstPtr = reinterpret_cast<nzUInt8*>(dst) + (width-1)*height*depth*bpp;
|
||||
for (unsigned int y = 0; y < height; ++y)
|
||||
{
|
||||
std::memcpy(dstPtr, srcPtr, lineStride);
|
||||
|
||||
srcPtr += lineStride;
|
||||
dstPtr -= lineStride;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
inline nzUInt8 NzPixelFormat::GetBPP(nzPixelFormat format)
|
||||
{
|
||||
switch (format)
|
||||
{
|
||||
case nzPixelFormat_BGR8:
|
||||
return 3;
|
||||
|
||||
case nzPixelFormat_BGRA8:
|
||||
return 4;
|
||||
|
||||
case nzPixelFormat_DXT1:
|
||||
return 1;
|
||||
|
||||
case nzPixelFormat_DXT3:
|
||||
return 2;
|
||||
|
||||
case nzPixelFormat_DXT5:
|
||||
return 2;
|
||||
|
||||
case nzPixelFormat_L8:
|
||||
return 1;
|
||||
|
||||
case nzPixelFormat_LA8:
|
||||
return 2;
|
||||
/*
|
||||
case nzPixelFormat_RGB16F:
|
||||
return 6;
|
||||
|
||||
case nzPixelFormat_RGB16I:
|
||||
return 6;
|
||||
|
||||
case nzPixelFormat_RGB32F:
|
||||
return 12;
|
||||
|
||||
case nzPixelFormat_RGB32I:
|
||||
return 12;
|
||||
|
||||
case nzPixelFormat_RGBA16F:
|
||||
return 8;
|
||||
|
||||
case nzPixelFormat_RGBA16I:
|
||||
return 8;
|
||||
|
||||
case nzPixelFormat_RGBA32F:
|
||||
return 16;
|
||||
|
||||
case nzPixelFormat_RGBA32I:
|
||||
return 16;
|
||||
*/
|
||||
case nzPixelFormat_RGBA4:
|
||||
return 2;
|
||||
|
||||
case nzPixelFormat_RGB5A1:
|
||||
return 2;
|
||||
|
||||
case nzPixelFormat_RGB8:
|
||||
return 3;
|
||||
|
||||
case nzPixelFormat_RGBA8:
|
||||
return 4;
|
||||
|
||||
case nzPixelFormat_Depth16:
|
||||
return 2;
|
||||
|
||||
case nzPixelFormat_Depth24:
|
||||
return 3;
|
||||
|
||||
case nzPixelFormat_Depth24Stencil8:
|
||||
return 4;
|
||||
|
||||
case nzPixelFormat_Depth32:
|
||||
return 4;
|
||||
|
||||
case nzPixelFormat_Stencil1:
|
||||
NazaraWarning("This format uses less than one byte per pixel");
|
||||
return 0;
|
||||
|
||||
case nzPixelFormat_Stencil4:
|
||||
NazaraWarning("This format uses less than one byte per pixel");
|
||||
return 0;
|
||||
|
||||
case nzPixelFormat_Stencil8:
|
||||
return 1;
|
||||
|
||||
case nzPixelFormat_Stencil16:
|
||||
return 2;
|
||||
|
||||
case nzPixelFormat_Undefined:
|
||||
break;
|
||||
}
|
||||
|
||||
NazaraError("Invalid pixel format");
|
||||
return 0;
|
||||
}
|
||||
|
||||
inline nzPixelFormatType NzPixelFormat::GetType(nzPixelFormat format)
|
||||
{
|
||||
switch (format)
|
||||
{
|
||||
case nzPixelFormat_BGR8:
|
||||
case nzPixelFormat_BGRA8:
|
||||
case nzPixelFormat_DXT1:
|
||||
case nzPixelFormat_DXT3:
|
||||
case nzPixelFormat_DXT5:
|
||||
case nzPixelFormat_L8:
|
||||
case nzPixelFormat_LA8:
|
||||
case nzPixelFormat_RGB5A1:
|
||||
case nzPixelFormat_RGB8:
|
||||
case nzPixelFormat_RGBA4:
|
||||
case nzPixelFormat_RGBA8:
|
||||
return nzPixelFormatType_Color;
|
||||
|
||||
case nzPixelFormat_Depth16:
|
||||
case nzPixelFormat_Depth24:
|
||||
case nzPixelFormat_Depth32:
|
||||
return nzPixelFormatType_Depth;
|
||||
|
||||
case nzPixelFormat_Depth24Stencil8:
|
||||
return nzPixelFormatType_DepthStencil;
|
||||
|
||||
case nzPixelFormat_Stencil1:
|
||||
case nzPixelFormat_Stencil4:
|
||||
case nzPixelFormat_Stencil8:
|
||||
case nzPixelFormat_Stencil16:
|
||||
return nzPixelFormatType_Stencil;
|
||||
|
||||
case nzPixelFormat_Undefined:
|
||||
break;
|
||||
}
|
||||
|
||||
NazaraError("Invalid pixel format");
|
||||
return nzPixelFormatType_Undefined;
|
||||
}
|
||||
|
||||
inline bool NzPixelFormat::HasAlpha(nzPixelFormat format)
|
||||
{
|
||||
switch (format)
|
||||
{
|
||||
case nzPixelFormat_BGRA8:
|
||||
case nzPixelFormat_DXT3:
|
||||
case nzPixelFormat_DXT5:
|
||||
case nzPixelFormat_LA8:
|
||||
case nzPixelFormat_RGB5A1:
|
||||
case nzPixelFormat_RGBA4:
|
||||
case nzPixelFormat_RGBA8:
|
||||
return true;
|
||||
|
||||
case nzPixelFormat_BGR8:
|
||||
case nzPixelFormat_DXT1:
|
||||
case nzPixelFormat_L8:
|
||||
case nzPixelFormat_RGB8:
|
||||
case nzPixelFormat_Depth16:
|
||||
case nzPixelFormat_Depth24:
|
||||
case nzPixelFormat_Depth24Stencil8:
|
||||
case nzPixelFormat_Depth32:
|
||||
case nzPixelFormat_Stencil1:
|
||||
case nzPixelFormat_Stencil4:
|
||||
case nzPixelFormat_Stencil8:
|
||||
case nzPixelFormat_Stencil16:
|
||||
return false;
|
||||
|
||||
case nzPixelFormat_Undefined:
|
||||
break;
|
||||
}
|
||||
|
||||
NazaraError("Invalid pixel format");
|
||||
return false;
|
||||
}
|
||||
|
||||
inline bool NzPixelFormat::IsCompressed(nzPixelFormat format)
|
||||
{
|
||||
switch (format)
|
||||
{
|
||||
case nzPixelFormat_DXT1:
|
||||
case nzPixelFormat_DXT3:
|
||||
case nzPixelFormat_DXT5:
|
||||
return true;
|
||||
|
||||
case nzPixelFormat_BGRA8:
|
||||
case nzPixelFormat_LA8:
|
||||
case nzPixelFormat_RGB5A1:
|
||||
case nzPixelFormat_RGBA4:
|
||||
case nzPixelFormat_RGBA8:
|
||||
case nzPixelFormat_BGR8:
|
||||
case nzPixelFormat_L8:
|
||||
case nzPixelFormat_RGB8:
|
||||
case nzPixelFormat_Depth16:
|
||||
case nzPixelFormat_Depth24:
|
||||
case nzPixelFormat_Depth24Stencil8:
|
||||
case nzPixelFormat_Depth32:
|
||||
case nzPixelFormat_Stencil1:
|
||||
case nzPixelFormat_Stencil4:
|
||||
case nzPixelFormat_Stencil8:
|
||||
case nzPixelFormat_Stencil16:
|
||||
return false;
|
||||
|
||||
case nzPixelFormat_Undefined:
|
||||
break;
|
||||
}
|
||||
|
||||
NazaraError("Invalid pixel format");
|
||||
return false;
|
||||
}
|
||||
|
||||
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
|
||||
// This file is part of the "Nazara Engine - Utility module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef NAZARA_STATICMESH_HPP
|
||||
#define NAZARA_STATICMESH_HPP
|
||||
|
||||
#include <Nazara/Prerequesites.hpp>
|
||||
#include <Nazara/Utility/SubMesh.hpp>
|
||||
|
||||
class NAZARA_API NzStaticMesh final : public NzSubMesh
|
||||
{
|
||||
public:
|
||||
NzStaticMesh(const NzMesh* parent);
|
||||
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 GenerateAABB();
|
||||
|
||||
const NzAxisAlignedBox& GetAABB() const;
|
||||
nzAnimationType GetAnimationType() const;
|
||||
unsigned int GetFrameCount() const;
|
||||
const NzIndexBuffer* GetIndexBuffer() const;
|
||||
nzPrimitiveType GetPrimitiveType() const;
|
||||
const NzVertexBuffer* GetVertexBuffer() const;
|
||||
const NzVertexDeclaration* GetVertexDeclaration() const;
|
||||
|
||||
bool IsAnimated() const;
|
||||
bool IsValid() const;
|
||||
|
||||
void SetAABB(const NzAxisAlignedBox& aabb);
|
||||
void SetPrimitiveType(nzPrimitiveType primitiveType);
|
||||
|
||||
private:
|
||||
void AnimateImpl(unsigned int frameA, unsigned int frameB, float interpolation);
|
||||
|
||||
nzPrimitiveType m_primitiveType = nzPrimitiveType_TriangleList;
|
||||
NzAxisAlignedBox m_aabb;
|
||||
NzIndexBuffer* m_indexBuffer = nullptr;
|
||||
NzVertexBuffer* m_vertexBuffer = nullptr;
|
||||
const NzVertexDeclaration* m_vertexDeclaration = nullptr;
|
||||
};
|
||||
|
||||
#endif // NAZARA_STATICMESH_HPP
|
||||
// Copyright (C) 2012 Jérôme Leclercq
|
||||
// This file is part of the "Nazara Engine - Utility module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef NAZARA_STATICMESH_HPP
|
||||
#define NAZARA_STATICMESH_HPP
|
||||
|
||||
#include <Nazara/Prerequesites.hpp>
|
||||
#include <Nazara/Core/ResourceListener.hpp>
|
||||
#include <Nazara/Utility/SubMesh.hpp>
|
||||
|
||||
class NAZARA_API NzStaticMesh final : public NzSubMesh, NzResourceListener
|
||||
{
|
||||
public:
|
||||
NzStaticMesh(const NzMesh* parent);
|
||||
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 GenerateAABB();
|
||||
|
||||
const NzAxisAlignedBox& GetAABB() const;
|
||||
nzAnimationType GetAnimationType() const;
|
||||
unsigned int GetFrameCount() const;
|
||||
const NzIndexBuffer* GetIndexBuffer() const;
|
||||
nzPrimitiveType GetPrimitiveType() const;
|
||||
const NzVertexBuffer* GetVertexBuffer() const;
|
||||
const NzVertexDeclaration* GetVertexDeclaration() const;
|
||||
|
||||
bool IsAnimated() const;
|
||||
bool IsValid() const;
|
||||
|
||||
void SetAABB(const NzAxisAlignedBox& aabb);
|
||||
void SetPrimitiveType(nzPrimitiveType primitiveType);
|
||||
|
||||
private:
|
||||
void AnimateImpl(unsigned int frameA, unsigned int frameB, float interpolation);
|
||||
void OnResourceReleased(const NzResource* resource, int index) override;
|
||||
|
||||
nzPrimitiveType m_primitiveType = nzPrimitiveType_TriangleList;
|
||||
NzAxisAlignedBox m_aabb;
|
||||
NzIndexBuffer* m_indexBuffer = nullptr;
|
||||
NzVertexBuffer* m_vertexBuffer = nullptr;
|
||||
const NzVertexDeclaration* m_vertexDeclaration = nullptr;
|
||||
};
|
||||
|
||||
#endif // NAZARA_STATICMESH_HPP
|
||||
|
|
|
|||
|
|
@ -1,53 +1,56 @@
|
|||
// Copyright (C) 2012 Jérôme Leclercq
|
||||
// This file is part of the "Nazara Engine - Utility module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#ifndef NAZARA_VERTEXDECLARATION_HPP
|
||||
#define NAZARA_VERTEXDECLARATION_HPP
|
||||
|
||||
#include <Nazara/Prerequesites.hpp>
|
||||
#include <Nazara/Core/Resource.hpp>
|
||||
#include <Nazara/Utility/Enums.hpp>
|
||||
|
||||
struct NzVertexElement
|
||||
{
|
||||
unsigned int offset;
|
||||
unsigned int usageIndex = 0;
|
||||
nzElementStream stream = nzElementStream_VertexData;
|
||||
nzElementType type;
|
||||
nzElementUsage usage;
|
||||
};
|
||||
|
||||
struct NzVertexDeclarationImpl;
|
||||
|
||||
class NAZARA_API NzVertexDeclaration : public NzResource
|
||||
{
|
||||
public:
|
||||
NzVertexDeclaration() = default;
|
||||
NzVertexDeclaration(const NzVertexElement* elements, unsigned int elementCount);
|
||||
NzVertexDeclaration(const NzVertexDeclaration& declaration);
|
||||
NzVertexDeclaration(NzVertexDeclaration&& declaration) noexcept;
|
||||
~NzVertexDeclaration();
|
||||
|
||||
bool Create(const NzVertexElement* elements, unsigned int elementCount);
|
||||
void Destroy();
|
||||
|
||||
const NzVertexElement* GetElement(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;
|
||||
unsigned int GetElementCount() const;
|
||||
unsigned int GetElementCount(nzElementStream stream) const;
|
||||
unsigned int GetStride(nzElementStream stream) const;
|
||||
|
||||
bool HasStream(nzElementStream stream) const;
|
||||
|
||||
bool IsValid() const;
|
||||
|
||||
NzVertexDeclaration& operator=(const NzVertexDeclaration& declaration);
|
||||
NzVertexDeclaration& operator=(NzVertexDeclaration&& declaration) noexcept;
|
||||
|
||||
private:
|
||||
NzVertexDeclarationImpl* m_sharedImpl = nullptr;
|
||||
};
|
||||
|
||||
#endif // NAZARA_VERTEXDECLARATION_HPP
|
||||
// Copyright (C) 2012 Jérôme Leclercq
|
||||
// This file is part of the "Nazara Engine - Utility module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#ifndef NAZARA_VERTEXDECLARATION_HPP
|
||||
#define NAZARA_VERTEXDECLARATION_HPP
|
||||
|
||||
#include <Nazara/Prerequesites.hpp>
|
||||
#include <Nazara/Core/Resource.hpp>
|
||||
#include <Nazara/Utility/Enums.hpp>
|
||||
|
||||
struct NzVertexElement
|
||||
{
|
||||
unsigned int offset;
|
||||
unsigned int usageIndex = 0;
|
||||
nzElementStream stream = nzElementStream_VertexData;
|
||||
nzElementType type;
|
||||
nzElementUsage usage;
|
||||
};
|
||||
|
||||
struct NzVertexDeclarationImpl;
|
||||
|
||||
class NAZARA_API NzVertexDeclaration : public NzResource
|
||||
{
|
||||
public:
|
||||
NzVertexDeclaration() = default;
|
||||
NzVertexDeclaration(const NzVertexElement* elements, unsigned int elementCount);
|
||||
NzVertexDeclaration(const NzVertexDeclaration& declaration);
|
||||
NzVertexDeclaration(NzVertexDeclaration&& declaration) noexcept;
|
||||
~NzVertexDeclaration();
|
||||
|
||||
bool Create(const NzVertexElement* elements, unsigned int elementCount);
|
||||
void Destroy();
|
||||
|
||||
const NzVertexElement* GetElement(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;
|
||||
unsigned int GetElementCount() const;
|
||||
unsigned int GetElementCount(nzElementStream stream) const;
|
||||
unsigned int GetStride(nzElementStream stream) const;
|
||||
|
||||
bool HasStream(nzElementStream stream) const;
|
||||
|
||||
bool IsValid() const;
|
||||
|
||||
NzVertexDeclaration& operator=(const NzVertexDeclaration& declaration);
|
||||
NzVertexDeclaration& operator=(NzVertexDeclaration&& declaration) noexcept;
|
||||
|
||||
static unsigned int GetElementCount(nzElementType type);
|
||||
static unsigned int GetElementSize(nzElementType type);
|
||||
|
||||
private:
|
||||
NzVertexDeclarationImpl* m_sharedImpl = nullptr;
|
||||
};
|
||||
|
||||
#endif // NAZARA_VERTEXDECLARATION_HPP
|
||||
|
|
|
|||
|
|
@ -1,111 +1,112 @@
|
|||
// Copyright (C) 2012 Jérôme Leclercq
|
||||
// This file is part of the "Nazara Engine - Utility module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
// Interface inspirée de la SFML par Laurent Gomila
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef NAZARA_WINDOW_HPP
|
||||
#define NAZARA_WINDOW_HPP
|
||||
|
||||
#include <Nazara/Prerequesites.hpp>
|
||||
#include <Nazara/Core/NonCopyable.hpp>
|
||||
#include <Nazara/Core/String.hpp>
|
||||
#include <Nazara/Math/Vector2.hpp>
|
||||
#include <Nazara/Utility/Config.hpp>
|
||||
#include <Nazara/Utility/Enums.hpp>
|
||||
#include <Nazara/Utility/Event.hpp>
|
||||
#include <Nazara/Utility/VideoMode.hpp>
|
||||
#include <Nazara/Utility/WindowHandle.hpp>
|
||||
#include <queue>
|
||||
|
||||
#if NAZARA_UTILITY_THREADED_WINDOW
|
||||
#include <Nazara/Core/Mutex.hpp>
|
||||
#include <Nazara/Core/ThreadCondition.hpp>
|
||||
#endif
|
||||
|
||||
class NzCursor;
|
||||
class NzImage;
|
||||
class NzIcon;
|
||||
class NzWindowImpl;
|
||||
|
||||
class NAZARA_API NzWindow : NzNonCopyable
|
||||
{
|
||||
friend NzWindowImpl;
|
||||
friend class NzMouse;
|
||||
friend class NzUtility;
|
||||
|
||||
public:
|
||||
NzWindow();
|
||||
NzWindow(NzVideoMode mode, const NzString& title, nzUInt32 style = nzWindowStyle_Default);
|
||||
NzWindow(NzWindowHandle handle);
|
||||
virtual ~NzWindow();
|
||||
|
||||
bool Create(NzVideoMode mode, const NzString& title, nzUInt32 style = nzWindowStyle_Default);
|
||||
bool Create(NzWindowHandle handle);
|
||||
|
||||
void Destroy();
|
||||
|
||||
void EnableKeyRepeat(bool enable);
|
||||
void EnableSmoothScrolling(bool enable);
|
||||
|
||||
NzWindowHandle GetHandle() const;
|
||||
unsigned int GetHeight() const;
|
||||
NzVector2i GetPosition() const;
|
||||
NzVector2ui GetSize() const;
|
||||
NzString GetTitle() const;
|
||||
unsigned int GetWidth() const;
|
||||
|
||||
bool HasFocus() const;
|
||||
|
||||
bool IsMinimized() const;
|
||||
bool IsOpen() const;
|
||||
bool IsVisible() const;
|
||||
|
||||
bool PollEvent(NzEvent* event);
|
||||
|
||||
void SetCursor(nzWindowCursor cursor);
|
||||
void SetCursor(const NzCursor& cursor);
|
||||
void SetEventListener(bool listener);
|
||||
void SetFocus();
|
||||
void SetIcon(const NzIcon& icon);
|
||||
void SetMaximumSize(const NzVector2i& maxSize);
|
||||
void SetMaximumSize(int width, int height);
|
||||
void SetMinimumSize(const NzVector2i& minSize);
|
||||
void SetMinimumSize(int width, int height);
|
||||
void SetPosition(const NzVector2i& position);
|
||||
void SetPosition(int x, int y);
|
||||
void SetSize(const NzVector2i& size);
|
||||
void SetSize(unsigned int width, unsigned int height);
|
||||
void SetStayOnTop(bool stayOnTop);
|
||||
void SetTitle(const NzString& title);
|
||||
void SetVisible(bool visible);
|
||||
|
||||
bool WaitEvent(NzEvent* event);
|
||||
|
||||
protected:
|
||||
virtual void OnWindowDestroying();
|
||||
virtual bool OnWindowCreated();
|
||||
|
||||
NzWindowImpl* m_impl;
|
||||
|
||||
private:
|
||||
void IgnoreNextMouseEvent(int mouseX, int mouseY) const;
|
||||
void PushEvent(const NzEvent& event);
|
||||
|
||||
static bool Initialize();
|
||||
static void Uninitialize();
|
||||
|
||||
std::queue<NzEvent> m_events;
|
||||
#if NAZARA_UTILITY_THREADED_WINDOW
|
||||
NzConditionVariable m_eventCondition;
|
||||
NzMutex m_eventMutex;
|
||||
NzMutex m_eventConditionMutex;
|
||||
bool m_eventListener;
|
||||
bool m_waitForEvent;
|
||||
#endif
|
||||
bool m_ownsWindow;
|
||||
};
|
||||
|
||||
#endif // NAZARA_WINDOW_HPP
|
||||
// Copyright (C) 2012 Jérôme Leclercq
|
||||
// This file is part of the "Nazara Engine - Utility module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
// Interface inspirée de la SFML par Laurent Gomila
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef NAZARA_WINDOW_HPP
|
||||
#define NAZARA_WINDOW_HPP
|
||||
|
||||
#include <Nazara/Prerequesites.hpp>
|
||||
#include <Nazara/Core/NonCopyable.hpp>
|
||||
#include <Nazara/Core/String.hpp>
|
||||
#include <Nazara/Math/Vector2.hpp>
|
||||
#include <Nazara/Utility/Config.hpp>
|
||||
#include <Nazara/Utility/Enums.hpp>
|
||||
#include <Nazara/Utility/Event.hpp>
|
||||
#include <Nazara/Utility/VideoMode.hpp>
|
||||
#include <Nazara/Utility/WindowHandle.hpp>
|
||||
#include <queue>
|
||||
|
||||
#if NAZARA_UTILITY_THREADED_WINDOW
|
||||
#include <Nazara/Core/ConditionVariable.hpp>
|
||||
#include <Nazara/Core/Mutex.hpp>
|
||||
#endif
|
||||
|
||||
class NzCursor;
|
||||
class NzImage;
|
||||
class NzIcon;
|
||||
class NzWindowImpl;
|
||||
|
||||
class NAZARA_API NzWindow : NzNonCopyable
|
||||
{
|
||||
friend NzWindowImpl;
|
||||
friend class NzMouse;
|
||||
friend class NzUtility;
|
||||
|
||||
public:
|
||||
NzWindow();
|
||||
NzWindow(NzVideoMode mode, const NzString& title, nzUInt32 style = nzWindowStyle_Default);
|
||||
NzWindow(NzWindowHandle handle);
|
||||
virtual ~NzWindow();
|
||||
|
||||
bool Create(NzVideoMode mode, const NzString& title, nzUInt32 style = nzWindowStyle_Default);
|
||||
bool Create(NzWindowHandle handle);
|
||||
|
||||
void Destroy();
|
||||
|
||||
void EnableKeyRepeat(bool enable);
|
||||
void EnableSmoothScrolling(bool enable);
|
||||
|
||||
NzWindowHandle GetHandle() const;
|
||||
unsigned int GetHeight() const;
|
||||
NzVector2i GetPosition() const;
|
||||
NzVector2ui GetSize() const;
|
||||
NzString GetTitle() const;
|
||||
unsigned int GetWidth() const;
|
||||
|
||||
bool HasFocus() const;
|
||||
|
||||
bool IsMinimized() const;
|
||||
bool IsOpen() const;
|
||||
bool IsValid() const;
|
||||
bool IsVisible() const;
|
||||
|
||||
bool PollEvent(NzEvent* event);
|
||||
|
||||
void SetCursor(nzWindowCursor cursor);
|
||||
void SetCursor(const NzCursor& cursor);
|
||||
void SetEventListener(bool listener);
|
||||
void SetFocus();
|
||||
void SetIcon(const NzIcon& icon);
|
||||
void SetMaximumSize(const NzVector2i& maxSize);
|
||||
void SetMaximumSize(int width, int height);
|
||||
void SetMinimumSize(const NzVector2i& minSize);
|
||||
void SetMinimumSize(int width, int height);
|
||||
void SetPosition(const NzVector2i& position);
|
||||
void SetPosition(int x, int y);
|
||||
void SetSize(const NzVector2i& size);
|
||||
void SetSize(unsigned int width, unsigned int height);
|
||||
void SetStayOnTop(bool stayOnTop);
|
||||
void SetTitle(const NzString& title);
|
||||
void SetVisible(bool visible);
|
||||
|
||||
bool WaitEvent(NzEvent* event);
|
||||
|
||||
protected:
|
||||
virtual bool OnWindowCreated();
|
||||
virtual void OnWindowDestroy();
|
||||
|
||||
NzWindowImpl* m_impl;
|
||||
|
||||
private:
|
||||
void IgnoreNextMouseEvent(int mouseX, int mouseY) const;
|
||||
void PushEvent(const NzEvent& event);
|
||||
|
||||
static bool Initialize();
|
||||
static void Uninitialize();
|
||||
|
||||
std::queue<NzEvent> m_events;
|
||||
#if NAZARA_UTILITY_THREADED_WINDOW
|
||||
NzConditionVariable m_eventCondition;
|
||||
NzMutex m_eventMutex;
|
||||
NzMutex m_eventConditionMutex;
|
||||
bool m_eventListener;
|
||||
bool m_waitForEvent;
|
||||
#endif
|
||||
bool m_ownsWindow;
|
||||
};
|
||||
|
||||
#endif // NAZARA_WINDOW_HPP
|
||||
|
|
|
|||
|
|
@ -1,223 +1,229 @@
|
|||
// Copyright (C) 2012 Jérôme Leclercq
|
||||
// This file is part of the "Nazara Engine - Audio module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#include <Nazara/Audio/SoundBuffer.hpp>
|
||||
#include <Nazara/Audio/Audio.hpp>
|
||||
#include <Nazara/Audio/Config.hpp>
|
||||
#include <Nazara/Core/Error.hpp>
|
||||
#include <cstring>
|
||||
#include <stdexcept>
|
||||
#include <AL/al.h>
|
||||
#include <Nazara/Audio/Debug.hpp>
|
||||
|
||||
///FIXME: Adapter la création
|
||||
|
||||
bool NzSoundBufferParams::IsValid() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
struct NzSoundBufferImpl
|
||||
{
|
||||
ALuint buffer;
|
||||
nzAudioFormat format;
|
||||
nzUInt32 duration;
|
||||
nzInt16* samples;
|
||||
unsigned int sampleCount;
|
||||
unsigned int sampleRate;
|
||||
};
|
||||
|
||||
NzSoundBuffer::NzSoundBuffer(nzAudioFormat format, unsigned int sampleCount, unsigned int sampleRate, const nzInt16* samples)
|
||||
{
|
||||
Create(format, sampleCount, sampleRate, samples);
|
||||
|
||||
#ifdef NAZARA_DEBUG
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraError("Failed to create sound buffer");
|
||||
throw std::runtime_error("Constructor failed");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
NzSoundBuffer::~NzSoundBuffer()
|
||||
{
|
||||
Destroy();
|
||||
}
|
||||
|
||||
bool NzSoundBuffer::Create(nzAudioFormat format, unsigned int sampleCount, unsigned int sampleRate, const nzInt16* samples)
|
||||
{
|
||||
Destroy();
|
||||
|
||||
if (sampleCount == 0)
|
||||
return true;
|
||||
|
||||
#if NAZARA_AUDIO_SAFE
|
||||
if (!IsFormatSupported(format))
|
||||
{
|
||||
NazaraError("Audio format is not supported");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (sampleRate == 0)
|
||||
{
|
||||
NazaraError("Sample rate must be different from zero");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!samples)
|
||||
{
|
||||
NazaraError("Invalid sample source");
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
// On vide le stack d'erreurs
|
||||
while (alGetError() != AL_NO_ERROR);
|
||||
|
||||
ALuint buffer;
|
||||
alGenBuffers(1, &buffer);
|
||||
|
||||
if (alGetError() != AL_NO_ERROR)
|
||||
{
|
||||
NazaraError("Failed to create OpenAL buffer");
|
||||
return false;
|
||||
}
|
||||
|
||||
alBufferData(buffer, NzAudio::GetOpenALFormat(format), samples, sampleCount*sizeof(nzInt16), sampleRate);
|
||||
|
||||
if (alGetError() != AL_NO_ERROR)
|
||||
{
|
||||
NazaraError("Failed to set OpenAL buffer");
|
||||
alDeleteBuffers(1, &buffer);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
m_impl = new NzSoundBufferImpl;
|
||||
m_impl->buffer = buffer;
|
||||
m_impl->duration = 1000 * (sampleCount / (format * sampleRate));
|
||||
m_impl->format = format;
|
||||
m_impl->sampleCount = sampleCount;
|
||||
m_impl->sampleRate = sampleRate;
|
||||
m_impl->samples = new nzInt16[sampleCount];
|
||||
std::memcpy(&m_impl->samples[0], samples, sampleCount*sizeof(nzInt16));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void NzSoundBuffer::Destroy()
|
||||
{
|
||||
if (m_impl)
|
||||
{
|
||||
delete[] m_impl->samples;
|
||||
delete m_impl;
|
||||
m_impl = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
nzUInt32 NzSoundBuffer::GetDuration() const
|
||||
{
|
||||
#if NAZARA_AUDIO_SAFE
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraError("Sound buffer not created");
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
return m_impl->duration;
|
||||
}
|
||||
|
||||
nzAudioFormat NzSoundBuffer::GetFormat() const
|
||||
{
|
||||
#if NAZARA_AUDIO_SAFE
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraError("Sound buffer not created");
|
||||
return nzAudioFormat_Unknown;
|
||||
}
|
||||
#endif
|
||||
|
||||
return m_impl->format;
|
||||
}
|
||||
|
||||
const nzInt16* NzSoundBuffer::GetSamples() const
|
||||
{
|
||||
#if NAZARA_AUDIO_SAFE
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraError("Sound buffer not created");
|
||||
return nullptr;
|
||||
}
|
||||
#endif
|
||||
|
||||
return m_impl->samples;
|
||||
}
|
||||
|
||||
unsigned int NzSoundBuffer::GetSampleCount() const
|
||||
{
|
||||
#if NAZARA_AUDIO_SAFE
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraError("Sound buffer not created");
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
return m_impl->sampleCount;
|
||||
}
|
||||
|
||||
unsigned int NzSoundBuffer::GetSampleRate() const
|
||||
{
|
||||
#if NAZARA_AUDIO_SAFE
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraError("Sound buffer not created");
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
return m_impl->sampleRate;
|
||||
}
|
||||
|
||||
bool NzSoundBuffer::IsValid() const
|
||||
{
|
||||
return m_impl != nullptr;
|
||||
}
|
||||
|
||||
bool NzSoundBuffer::LoadFromFile(const NzString& filePath, const NzSoundBufferParams& params)
|
||||
{
|
||||
return NzSoundBufferLoader::LoadFromFile(this, filePath, params);
|
||||
}
|
||||
|
||||
bool NzSoundBuffer::LoadFromMemory(const void* data, std::size_t size, const NzSoundBufferParams& params)
|
||||
{
|
||||
return NzSoundBufferLoader::LoadFromMemory(this, data, size, params);
|
||||
}
|
||||
|
||||
bool NzSoundBuffer::LoadFromStream(NzInputStream& stream, const NzSoundBufferParams& params)
|
||||
{
|
||||
return NzSoundBufferLoader::LoadFromStream(this, stream, params);
|
||||
}
|
||||
|
||||
bool NzSoundBuffer::IsFormatSupported(nzAudioFormat format)
|
||||
{
|
||||
return NzAudio::IsFormatSupported(format);
|
||||
}
|
||||
|
||||
unsigned int NzSoundBuffer::GetOpenALBuffer() const
|
||||
{
|
||||
#ifdef NAZARA_DEBUG
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraInternalError("Sound buffer not created");
|
||||
return AL_NONE;
|
||||
}
|
||||
#endif
|
||||
|
||||
return m_impl->buffer;
|
||||
}
|
||||
|
||||
NzSoundBufferLoader::LoaderList NzSoundBuffer::s_loaders;
|
||||
// Copyright (C) 2012 Jérôme Leclercq
|
||||
// This file is part of the "Nazara Engine - Audio module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#include <Nazara/Audio/SoundBuffer.hpp>
|
||||
#include <Nazara/Audio/Audio.hpp>
|
||||
#include <Nazara/Audio/Config.hpp>
|
||||
#include <Nazara/Core/Error.hpp>
|
||||
#include <cstring>
|
||||
#include <stdexcept>
|
||||
#include <AL/al.h>
|
||||
#include <Nazara/Audio/Debug.hpp>
|
||||
|
||||
///FIXME: Adapter la création
|
||||
|
||||
bool NzSoundBufferParams::IsValid() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
struct NzSoundBufferImpl
|
||||
{
|
||||
ALuint buffer;
|
||||
nzAudioFormat format;
|
||||
nzUInt32 duration;
|
||||
nzInt16* samples;
|
||||
unsigned int sampleCount;
|
||||
unsigned int sampleRate;
|
||||
};
|
||||
|
||||
NzSoundBuffer::NzSoundBuffer(nzAudioFormat format, unsigned int sampleCount, unsigned int sampleRate, const nzInt16* samples)
|
||||
{
|
||||
Create(format, sampleCount, sampleRate, samples);
|
||||
|
||||
#ifdef NAZARA_DEBUG
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraError("Failed to create sound buffer");
|
||||
throw std::runtime_error("Constructor failed");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
NzSoundBuffer::~NzSoundBuffer()
|
||||
{
|
||||
Destroy();
|
||||
}
|
||||
|
||||
bool NzSoundBuffer::Create(nzAudioFormat format, unsigned int sampleCount, unsigned int sampleRate, const nzInt16* samples)
|
||||
{
|
||||
Destroy();
|
||||
|
||||
#if NAZARA_AUDIO_SAFE
|
||||
if (!IsFormatSupported(format))
|
||||
{
|
||||
NazaraError("Audio format is not supported");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (sampleCount == 0)
|
||||
{
|
||||
NazaraError("Sample rate must be different from zero");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (sampleRate == 0)
|
||||
{
|
||||
NazaraError("Sample rate must be different from zero");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!samples)
|
||||
{
|
||||
NazaraError("Invalid sample source");
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
// On vide le stack d'erreurs
|
||||
while (alGetError() != AL_NO_ERROR);
|
||||
|
||||
ALuint buffer;
|
||||
alGenBuffers(1, &buffer);
|
||||
|
||||
if (alGetError() != AL_NO_ERROR)
|
||||
{
|
||||
NazaraError("Failed to create OpenAL buffer");
|
||||
return false;
|
||||
}
|
||||
|
||||
alBufferData(buffer, NzAudio::GetOpenALFormat(format), samples, sampleCount*sizeof(nzInt16), sampleRate);
|
||||
|
||||
if (alGetError() != AL_NO_ERROR)
|
||||
{
|
||||
NazaraError("Failed to set OpenAL buffer");
|
||||
alDeleteBuffers(1, &buffer);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
m_impl = new NzSoundBufferImpl;
|
||||
m_impl->buffer = buffer;
|
||||
m_impl->duration = 1000 * (sampleCount / (format * sampleRate));
|
||||
m_impl->format = format;
|
||||
m_impl->sampleCount = sampleCount;
|
||||
m_impl->sampleRate = sampleRate;
|
||||
m_impl->samples = new nzInt16[sampleCount];
|
||||
std::memcpy(&m_impl->samples[0], samples, sampleCount*sizeof(nzInt16));
|
||||
|
||||
NotifyCreated();
|
||||
return true;
|
||||
}
|
||||
|
||||
void NzSoundBuffer::Destroy()
|
||||
{
|
||||
if (m_impl)
|
||||
{
|
||||
NotifyDestroy();
|
||||
|
||||
delete[] m_impl->samples;
|
||||
delete m_impl;
|
||||
m_impl = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
nzUInt32 NzSoundBuffer::GetDuration() const
|
||||
{
|
||||
#if NAZARA_AUDIO_SAFE
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraError("Sound buffer not created");
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
return m_impl->duration;
|
||||
}
|
||||
|
||||
nzAudioFormat NzSoundBuffer::GetFormat() const
|
||||
{
|
||||
#if NAZARA_AUDIO_SAFE
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraError("Sound buffer not created");
|
||||
return nzAudioFormat_Unknown;
|
||||
}
|
||||
#endif
|
||||
|
||||
return m_impl->format;
|
||||
}
|
||||
|
||||
const nzInt16* NzSoundBuffer::GetSamples() const
|
||||
{
|
||||
#if NAZARA_AUDIO_SAFE
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraError("Sound buffer not created");
|
||||
return nullptr;
|
||||
}
|
||||
#endif
|
||||
|
||||
return m_impl->samples;
|
||||
}
|
||||
|
||||
unsigned int NzSoundBuffer::GetSampleCount() const
|
||||
{
|
||||
#if NAZARA_AUDIO_SAFE
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraError("Sound buffer not created");
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
return m_impl->sampleCount;
|
||||
}
|
||||
|
||||
unsigned int NzSoundBuffer::GetSampleRate() const
|
||||
{
|
||||
#if NAZARA_AUDIO_SAFE
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraError("Sound buffer not created");
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
return m_impl->sampleRate;
|
||||
}
|
||||
|
||||
bool NzSoundBuffer::IsValid() const
|
||||
{
|
||||
return m_impl != nullptr;
|
||||
}
|
||||
|
||||
bool NzSoundBuffer::LoadFromFile(const NzString& filePath, const NzSoundBufferParams& params)
|
||||
{
|
||||
return NzSoundBufferLoader::LoadFromFile(this, filePath, params);
|
||||
}
|
||||
|
||||
bool NzSoundBuffer::LoadFromMemory(const void* data, std::size_t size, const NzSoundBufferParams& params)
|
||||
{
|
||||
return NzSoundBufferLoader::LoadFromMemory(this, data, size, params);
|
||||
}
|
||||
|
||||
bool NzSoundBuffer::LoadFromStream(NzInputStream& stream, const NzSoundBufferParams& params)
|
||||
{
|
||||
return NzSoundBufferLoader::LoadFromStream(this, stream, params);
|
||||
}
|
||||
|
||||
bool NzSoundBuffer::IsFormatSupported(nzAudioFormat format)
|
||||
{
|
||||
return NzAudio::IsFormatSupported(format);
|
||||
}
|
||||
|
||||
unsigned int NzSoundBuffer::GetOpenALBuffer() const
|
||||
{
|
||||
#ifdef NAZARA_DEBUG
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraInternalError("Sound buffer not created");
|
||||
return AL_NONE;
|
||||
}
|
||||
#endif
|
||||
|
||||
return m_impl->buffer;
|
||||
}
|
||||
|
||||
NzSoundBufferLoader::LoaderList NzSoundBuffer::s_loaders;
|
||||
|
|
|
|||
|
|
@ -1,265 +1,265 @@
|
|||
/*
|
||||
// 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/ByteArray.hpp>
|
||||
#include <algorithm>
|
||||
#include <cstring>
|
||||
#include <Nazara/Core/Debug.hpp>
|
||||
|
||||
inline unsigned int nzPow2(unsigned int n)
|
||||
{
|
||||
unsigned int x = 1;
|
||||
|
||||
while(x <= n)
|
||||
x <<= 1;
|
||||
|
||||
return x;
|
||||
}
|
||||
// Cet algorithme est inspiré de la documentation de Qt
|
||||
inline unsigned int nzGetNewSize(unsigned int newSize)
|
||||
{
|
||||
if (newSize < 20)
|
||||
return newSize+4;
|
||||
else
|
||||
{
|
||||
if (newSize < (1 << 12)-12)
|
||||
return nzPow2(newSize << 1)-12;
|
||||
else
|
||||
return newSize + (1 << 11);
|
||||
}
|
||||
}
|
||||
|
||||
NzByteArray::NzByteArray() :
|
||||
m_sharedArray(&emptyArray)
|
||||
{
|
||||
}
|
||||
|
||||
NzByteArray::NzByteArray(const nzUInt8* buffer, unsigned int bufferLength)
|
||||
{
|
||||
if (bufferLength > 0)
|
||||
{
|
||||
m_sharedArray = new SharedArray;
|
||||
m_sharedArray->buffer = new nzUInt8[bufferLength];
|
||||
m_sharedArray->capacity = bufferLength;
|
||||
m_sharedArray->size = bufferLength;
|
||||
std::memcpy(m_sharedArray->buffer, buffer, bufferLength);
|
||||
}
|
||||
else
|
||||
m_sharedArray = &emptyArray;
|
||||
}
|
||||
|
||||
NzByteArray::NzByteArray(const NzByteArray& buffer) :
|
||||
m_sharedArray(buffer.m_sharedArray)
|
||||
{
|
||||
if (m_sharedArray != &emptyArray)
|
||||
{
|
||||
NazaraMutexLock(m_sharedArray->mutex);
|
||||
m_sharedArray->refCount++;
|
||||
NazaraMutexUnlock(m_sharedArray->mutex);
|
||||
}
|
||||
}
|
||||
|
||||
NzByteArray::NzByteArray(NzByteArray&& buffer) :
|
||||
m_sharedArray(buffer.m_sharedArray)
|
||||
{
|
||||
buffer.m_sharedArray = &emptyArray;
|
||||
}
|
||||
|
||||
NzByteArray::NzByteArray(SharedArray* sharedArray) :
|
||||
m_sharedArray(sharedArray)
|
||||
{
|
||||
}
|
||||
|
||||
NzByteArray::~NzByteArray()
|
||||
{
|
||||
ReleaseArray();
|
||||
}
|
||||
|
||||
NzByteArray& NzByteArray::Append(const NzByteArray& byteArray)
|
||||
{
|
||||
if (byteArray.m_sharedArray->size == 0)
|
||||
return *this;
|
||||
|
||||
if (m_sharedArray->size == 0 && m_sharedArray->capacity < byteArray.m_sharedArray->size)
|
||||
return operator=(byteArray);
|
||||
|
||||
if (m_sharedArray->capacity >= m_sharedArray->size + byteArray.m_sharedArray->size)
|
||||
{
|
||||
EnsureOwnership();
|
||||
|
||||
std::memcpy(&m_sharedArray->buffer[m_sharedArray->size], byteArray.m_sharedArray->buffer, byteArray.m_sharedArray->size);
|
||||
m_sharedArray->size += byteArray.m_sharedArray->size;
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned int newSize = m_sharedArray->size + byteArray.m_sharedArray->size;
|
||||
unsigned int bufferSize = nzGetNewSize(newSize);
|
||||
|
||||
nzUInt8* buffer = new nzUInt8[bufferSize+1];
|
||||
std::memcpy(buffer, m_sharedArray->buffer, m_sharedArray->size);
|
||||
std::memcpy(&buffer[m_sharedArray->size], byteArray.m_sharedArray->buffer, byteArray.m_sharedArray->size);
|
||||
|
||||
ReleaseArray();
|
||||
m_sharedArray = new SharedArray;
|
||||
m_sharedArray->buffer = buffer;
|
||||
m_sharedArray->capacity = bufferSize;
|
||||
m_sharedArray->size = newSize;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
void NzByteArray::Clear()
|
||||
{
|
||||
ReleaseArray();
|
||||
}
|
||||
|
||||
nzUInt8* NzByteArray::GetBuffer()
|
||||
{
|
||||
EnsureOwnership();
|
||||
|
||||
return m_sharedArray->buffer;
|
||||
}
|
||||
|
||||
unsigned int NzByteArray::GetCapacity() const
|
||||
{
|
||||
return m_sharedArray->capacity;
|
||||
}
|
||||
|
||||
const nzUInt8* NzByteArray::GetConstBuffer() const
|
||||
{
|
||||
return m_sharedArray->buffer;
|
||||
}
|
||||
|
||||
unsigned int NzByteArray::GetSize() const
|
||||
{
|
||||
return m_sharedArray->size;
|
||||
}
|
||||
|
||||
NzByteArray& NzByteArray::Insert(int pos, const nzUInt8* buffer, unsigned int bufferLength)
|
||||
{
|
||||
if (bufferLength == 0)
|
||||
return *this;
|
||||
|
||||
if (m_sharedArray->size == 0)
|
||||
return operator=(string);
|
||||
|
||||
if (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);
|
||||
|
||||
// Si le buffer est déjà suffisamment grand
|
||||
if (m_sharedArray->capacity >= m_sharedArray->size + bufferLength)
|
||||
{
|
||||
EnsureOwnership();
|
||||
|
||||
std::memmove(&m_sharedArray->buffer[start+bufferLength], &m_sharedArray->buffer[start], m_sharedArray->size);
|
||||
std::memcpy(&m_sharedArray->buffer[start], buffer, bufferLength);
|
||||
|
||||
m_sharedArray->size += bufferLength;
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned int newSize = m_sharedArray->size+bufferLength;
|
||||
nzUInt8* newBuffer = new nzUInt8[newSize+1];
|
||||
|
||||
nzUInt8* ptr = newBuffer;
|
||||
const nzUInt8* s = m_sharedArray->buffer;
|
||||
|
||||
while (ptr != &newBuffer[start])
|
||||
*ptr++ = *s++;
|
||||
|
||||
while (ptr != &newBuffer[start+bufferLength])
|
||||
*ptr++ = *buffer++;
|
||||
|
||||
std::strcpy(ptr, s);
|
||||
|
||||
ReleaseString();
|
||||
m_sharedArray = new SharedString;
|
||||
m_sharedArray->allocatedSize = newSize;
|
||||
m_sharedArray->buffer = newBuffer;
|
||||
m_sharedArray->size = newSize;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
NzByteArray& NzByteArray::Insert(int pos, const NzByteArray& byteArray)
|
||||
{
|
||||
if (string.m_sharedArray->size == 0)
|
||||
return *this;
|
||||
|
||||
if (m_sharedArray->size == 0 && m_sharedArray->capacity < string.m_sharedArray->size)
|
||||
return operator=(string);
|
||||
|
||||
if (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);
|
||||
|
||||
// Si le buffer est déjà suffisamment grand
|
||||
if (m_sharedArray->capacity >= m_sharedArray->size + string.m_sharedArray->size)
|
||||
{
|
||||
EnsureOwnership();
|
||||
|
||||
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));
|
||||
|
||||
m_sharedArray->size += string.m_sharedArray->size;
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned int newSize = m_sharedArray->size+string.m_sharedArray->size;
|
||||
char* newString = new char[newSize+1];
|
||||
|
||||
char* ptr = newString;
|
||||
const char* s = m_sharedArray->string;
|
||||
|
||||
while (ptr != &newString[start])
|
||||
*ptr++ = *s++;
|
||||
|
||||
const char* p = string.m_sharedArray->string;
|
||||
while (ptr != &newString[start+string.m_sharedArray->size])
|
||||
*ptr++ = *p++;
|
||||
|
||||
std::strcpy(ptr, s);
|
||||
|
||||
ReleaseString();
|
||||
m_sharedArray = new SharedString;
|
||||
m_sharedArray->capacity = newSize;
|
||||
m_sharedArray->size = newSize;
|
||||
m_sharedArray->string = newString;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool NzByteArray::IsEmpty() const
|
||||
{
|
||||
return m_sharedArray->size == 0;
|
||||
}
|
||||
|
||||
void NzByteArray::Reserve(unsigned int bufferSize)
|
||||
{
|
||||
if (m_sharedArray->allocatedSize >= bufferSize)
|
||||
return;
|
||||
|
||||
nzUInt8* ptr = new nzUInt8[bufferSize+1];
|
||||
if (m_sharedArray->size > 0)
|
||||
std::memcpy(ptr, m_sharedArray->buffer, m_sharedArray->size);
|
||||
|
||||
unsigned int size = m_sharedArray->size;
|
||||
|
||||
ReleaseArray();
|
||||
m_sharedArray = new SharedString;
|
||||
m_sharedArray->allocatedSize = bufferSize;
|
||||
m_sharedArray->buffer = ptr;
|
||||
m_sharedArray->size = size;
|
||||
}
|
||||
|
||||
NzByteArray::SharedString NzByteArray::emptyArray(0, 0, 0, nullptr);
|
||||
unsigned int NzByteArray::npos(static_cast<unsigned int>(-1));
|
||||
*/
|
||||
// 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/ByteArray.hpp>
|
||||
#include <algorithm>
|
||||
#include <cstring>
|
||||
#include <Nazara/Core/Debug.hpp>
|
||||
|
||||
inline unsigned int nzPow2(unsigned int n)
|
||||
{
|
||||
unsigned int x = 1;
|
||||
|
||||
while(x <= n)
|
||||
x <<= 1;
|
||||
|
||||
return x;
|
||||
}
|
||||
// Cet algorithme est inspiré de la documentation de Qt
|
||||
inline unsigned int nzGetNewSize(unsigned int newSize)
|
||||
{
|
||||
if (newSize < 20)
|
||||
return newSize+4;
|
||||
else
|
||||
{
|
||||
if (newSize < (1 << 12)-12)
|
||||
return nzPow2(newSize << 1)-12;
|
||||
else
|
||||
return newSize + (1 << 11);
|
||||
}
|
||||
}
|
||||
|
||||
NzByteArray::NzByteArray() :
|
||||
m_sharedArray(&emptyArray)
|
||||
{
|
||||
}
|
||||
|
||||
NzByteArray::NzByteArray(const nzUInt8* buffer, unsigned int bufferLength)
|
||||
{
|
||||
if (bufferLength > 0)
|
||||
{
|
||||
m_sharedArray = new SharedArray;
|
||||
m_sharedArray->buffer = new nzUInt8[bufferLength];
|
||||
m_sharedArray->capacity = bufferLength;
|
||||
m_sharedArray->size = bufferLength;
|
||||
std::memcpy(m_sharedArray->buffer, buffer, bufferLength);
|
||||
}
|
||||
else
|
||||
m_sharedArray = &emptyArray;
|
||||
}
|
||||
|
||||
NzByteArray::NzByteArray(const NzByteArray& buffer) :
|
||||
m_sharedArray(buffer.m_sharedArray)
|
||||
{
|
||||
if (m_sharedArray != &emptyArray)
|
||||
{
|
||||
NazaraMutexLock(m_sharedArray->mutex);
|
||||
m_sharedArray->refCount++;
|
||||
NazaraMutexUnlock(m_sharedArray->mutex);
|
||||
}
|
||||
}
|
||||
|
||||
NzByteArray::NzByteArray(NzByteArray&& buffer) noexcept :
|
||||
m_sharedArray(buffer.m_sharedArray)
|
||||
{
|
||||
buffer.m_sharedArray = &emptyArray;
|
||||
}
|
||||
|
||||
NzByteArray::NzByteArray(SharedArray* sharedArray) :
|
||||
m_sharedArray(sharedArray)
|
||||
{
|
||||
}
|
||||
|
||||
NzByteArray::~NzByteArray()
|
||||
{
|
||||
ReleaseArray();
|
||||
}
|
||||
|
||||
NzByteArray& NzByteArray::Append(const NzByteArray& byteArray)
|
||||
{
|
||||
if (byteArray.m_sharedArray->size == 0)
|
||||
return *this;
|
||||
|
||||
if (m_sharedArray->size == 0 && m_sharedArray->capacity < byteArray.m_sharedArray->size)
|
||||
return operator=(byteArray);
|
||||
|
||||
if (m_sharedArray->capacity >= m_sharedArray->size + byteArray.m_sharedArray->size)
|
||||
{
|
||||
EnsureOwnership();
|
||||
|
||||
std::memcpy(&m_sharedArray->buffer[m_sharedArray->size], byteArray.m_sharedArray->buffer, byteArray.m_sharedArray->size);
|
||||
m_sharedArray->size += byteArray.m_sharedArray->size;
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned int newSize = m_sharedArray->size + byteArray.m_sharedArray->size;
|
||||
unsigned int bufferSize = nzGetNewSize(newSize);
|
||||
|
||||
nzUInt8* buffer = new nzUInt8[bufferSize+1];
|
||||
std::memcpy(buffer, m_sharedArray->buffer, m_sharedArray->size);
|
||||
std::memcpy(&buffer[m_sharedArray->size], byteArray.m_sharedArray->buffer, byteArray.m_sharedArray->size);
|
||||
|
||||
ReleaseArray();
|
||||
m_sharedArray = new SharedArray;
|
||||
m_sharedArray->buffer = buffer;
|
||||
m_sharedArray->capacity = bufferSize;
|
||||
m_sharedArray->size = newSize;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
void NzByteArray::Clear()
|
||||
{
|
||||
ReleaseArray();
|
||||
}
|
||||
|
||||
nzUInt8* NzByteArray::GetBuffer()
|
||||
{
|
||||
EnsureOwnership();
|
||||
|
||||
return m_sharedArray->buffer;
|
||||
}
|
||||
|
||||
unsigned int NzByteArray::GetCapacity() const
|
||||
{
|
||||
return m_sharedArray->capacity;
|
||||
}
|
||||
|
||||
const nzUInt8* NzByteArray::GetConstBuffer() const
|
||||
{
|
||||
return m_sharedArray->buffer;
|
||||
}
|
||||
|
||||
unsigned int NzByteArray::GetSize() const
|
||||
{
|
||||
return m_sharedArray->size;
|
||||
}
|
||||
|
||||
NzByteArray& NzByteArray::Insert(int pos, const nzUInt8* buffer, unsigned int bufferLength)
|
||||
{
|
||||
if (bufferLength == 0)
|
||||
return *this;
|
||||
|
||||
if (m_sharedArray->size == 0)
|
||||
return operator=(string);
|
||||
|
||||
if (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);
|
||||
|
||||
// Si le buffer est déjà suffisamment grand
|
||||
if (m_sharedArray->capacity >= m_sharedArray->size + bufferLength)
|
||||
{
|
||||
EnsureOwnership();
|
||||
|
||||
std::memmove(&m_sharedArray->buffer[start+bufferLength], &m_sharedArray->buffer[start], m_sharedArray->size);
|
||||
std::memcpy(&m_sharedArray->buffer[start], buffer, bufferLength);
|
||||
|
||||
m_sharedArray->size += bufferLength;
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned int newSize = m_sharedArray->size+bufferLength;
|
||||
nzUInt8* newBuffer = new nzUInt8[newSize+1];
|
||||
|
||||
nzUInt8* ptr = newBuffer;
|
||||
const nzUInt8* s = m_sharedArray->buffer;
|
||||
|
||||
while (ptr != &newBuffer[start])
|
||||
*ptr++ = *s++;
|
||||
|
||||
while (ptr != &newBuffer[start+bufferLength])
|
||||
*ptr++ = *buffer++;
|
||||
|
||||
std::strcpy(ptr, s);
|
||||
|
||||
ReleaseString();
|
||||
m_sharedArray = new SharedString;
|
||||
m_sharedArray->allocatedSize = newSize;
|
||||
m_sharedArray->buffer = newBuffer;
|
||||
m_sharedArray->size = newSize;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
NzByteArray& NzByteArray::Insert(int pos, const NzByteArray& byteArray)
|
||||
{
|
||||
if (string.m_sharedArray->size == 0)
|
||||
return *this;
|
||||
|
||||
if (m_sharedArray->size == 0 && m_sharedArray->capacity < string.m_sharedArray->size)
|
||||
return operator=(string);
|
||||
|
||||
if (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);
|
||||
|
||||
// Si le buffer est déjà suffisamment grand
|
||||
if (m_sharedArray->capacity >= m_sharedArray->size + string.m_sharedArray->size)
|
||||
{
|
||||
EnsureOwnership();
|
||||
|
||||
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));
|
||||
|
||||
m_sharedArray->size += string.m_sharedArray->size;
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned int newSize = m_sharedArray->size+string.m_sharedArray->size;
|
||||
char* newString = new char[newSize+1];
|
||||
|
||||
char* ptr = newString;
|
||||
const char* s = m_sharedArray->string;
|
||||
|
||||
while (ptr != &newString[start])
|
||||
*ptr++ = *s++;
|
||||
|
||||
const char* p = string.m_sharedArray->string;
|
||||
while (ptr != &newString[start+string.m_sharedArray->size])
|
||||
*ptr++ = *p++;
|
||||
|
||||
std::strcpy(ptr, s);
|
||||
|
||||
ReleaseString();
|
||||
m_sharedArray = new SharedString;
|
||||
m_sharedArray->capacity = newSize;
|
||||
m_sharedArray->size = newSize;
|
||||
m_sharedArray->string = newString;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool NzByteArray::IsEmpty() const
|
||||
{
|
||||
return m_sharedArray->size == 0;
|
||||
}
|
||||
|
||||
void NzByteArray::Reserve(unsigned int bufferSize)
|
||||
{
|
||||
if (m_sharedArray->allocatedSize >= bufferSize)
|
||||
return;
|
||||
|
||||
nzUInt8* ptr = new nzUInt8[bufferSize+1];
|
||||
if (m_sharedArray->size > 0)
|
||||
std::memcpy(ptr, m_sharedArray->buffer, m_sharedArray->size);
|
||||
|
||||
unsigned int size = m_sharedArray->size;
|
||||
|
||||
ReleaseArray();
|
||||
m_sharedArray = new SharedString;
|
||||
m_sharedArray->allocatedSize = bufferSize;
|
||||
m_sharedArray->buffer = ptr;
|
||||
m_sharedArray->size = size;
|
||||
}
|
||||
|
||||
NzByteArray::SharedString NzByteArray::emptyArray(0, 0, 0, nullptr);
|
||||
unsigned int NzByteArray::npos(static_cast<unsigned int>(-1));
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -1,264 +1,271 @@
|
|||
// 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/Debug/MemoryLeakTracker.hpp>
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <ctime>
|
||||
#include <stdexcept>
|
||||
|
||||
#if defined(NAZARA_PLATFORM_WINDOWS)
|
||||
#include <windows.h>
|
||||
#elif defined(NAZARA_PLATFORM_POSIX)
|
||||
#include <pthread.h>
|
||||
#endif
|
||||
|
||||
namespace
|
||||
{
|
||||
struct Block
|
||||
{
|
||||
std::size_t size;
|
||||
const char* file;
|
||||
Block* prev;
|
||||
Block* next;
|
||||
bool array;
|
||||
unsigned int line;
|
||||
unsigned int magic;
|
||||
};
|
||||
|
||||
bool initialized = false;
|
||||
const unsigned int magic = 0x51429EE;
|
||||
const char* MLTFileName = "NazaraLeaks.log";
|
||||
const char* nextFreeFile = "Internal error";
|
||||
unsigned int nextFreeLine = 0;
|
||||
|
||||
Block ptrList =
|
||||
{
|
||||
0,
|
||||
nullptr,
|
||||
&ptrList,
|
||||
&ptrList,
|
||||
false,
|
||||
0,
|
||||
magic
|
||||
};
|
||||
|
||||
#if defined(NAZARA_PLATFORM_WINDOWS)
|
||||
CRITICAL_SECTION mutex;
|
||||
#elif defined(NAZARA_PLATFORM_POSIX)
|
||||
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
#endif
|
||||
}
|
||||
|
||||
NzMemoryManager::NzMemoryManager()
|
||||
{
|
||||
}
|
||||
|
||||
NzMemoryManager::~NzMemoryManager()
|
||||
{
|
||||
Uninitialize();
|
||||
}
|
||||
|
||||
void* NzMemoryManager::Allocate(std::size_t size, bool multi, const char* file, unsigned int line)
|
||||
{
|
||||
if (!initialized)
|
||||
Initialize();
|
||||
|
||||
#if defined(NAZARA_PLATFORM_WINDOWS)
|
||||
EnterCriticalSection(&mutex);
|
||||
#elif defined(NAZARA_PLATFORM_POSIX)
|
||||
pthread_mutex_lock(&mutex);
|
||||
#endif
|
||||
|
||||
Block* ptr = reinterpret_cast<Block*>(std::malloc(size+sizeof(Block)));
|
||||
if (!ptr)
|
||||
return nullptr; // Impossible d'envoyer une exception car cela allouerait de la mémoire avec new (boucle infinie)
|
||||
|
||||
ptr->array = multi;
|
||||
ptr->file = file;
|
||||
ptr->line = line;
|
||||
ptr->size = size;
|
||||
ptr->magic = magic;
|
||||
|
||||
ptr->prev = ptrList.prev;
|
||||
ptr->next = &ptrList;
|
||||
ptrList.prev->next = ptr;
|
||||
ptrList.prev = ptr;
|
||||
|
||||
#if defined(NAZARA_PLATFORM_WINDOWS)
|
||||
LeaveCriticalSection(&mutex);
|
||||
#elif defined(NAZARA_PLATFORM_POSIX)
|
||||
pthread_mutex_unlock(&mutex);
|
||||
#endif
|
||||
|
||||
return reinterpret_cast<char*>(ptr)+sizeof(Block);
|
||||
}
|
||||
|
||||
void NzMemoryManager::Free(void* pointer, bool multi)
|
||||
{
|
||||
if (!pointer)
|
||||
return;
|
||||
|
||||
Block* ptr = reinterpret_cast<Block*>(reinterpret_cast<char*>(pointer)-sizeof(Block));
|
||||
if (ptr->magic != magic)
|
||||
return;
|
||||
|
||||
#if defined(NAZARA_PLATFORM_WINDOWS)
|
||||
EnterCriticalSection(&mutex);
|
||||
#elif defined(NAZARA_PLATFORM_POSIX)
|
||||
pthread_mutex_lock(&mutex);
|
||||
#endif
|
||||
|
||||
if (ptr->array != multi)
|
||||
{
|
||||
char* time = TimeInfo();
|
||||
|
||||
FILE* log = std::fopen(MLTFileName, "a");
|
||||
|
||||
if (nextFreeFile)
|
||||
{
|
||||
if (multi)
|
||||
std::fprintf(log, "%s Warning: delete[] after new at %s:%d\n", time, nextFreeFile, nextFreeLine);
|
||||
else
|
||||
std::fprintf(log, "%s Warning: delete after new[] at %s:%d\n", time, nextFreeFile, nextFreeLine);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (multi)
|
||||
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);
|
||||
}
|
||||
|
||||
std::fclose(log);
|
||||
|
||||
std::free(time);
|
||||
}
|
||||
|
||||
ptr->magic = 0;
|
||||
ptr->prev->next = ptr->next;
|
||||
ptr->next->prev = ptr->prev;
|
||||
|
||||
std::free(ptr);
|
||||
|
||||
nextFreeFile = nullptr;
|
||||
nextFreeLine = 0;
|
||||
|
||||
#if defined(NAZARA_PLATFORM_WINDOWS)
|
||||
LeaveCriticalSection(&mutex);
|
||||
#elif defined(NAZARA_PLATFORM_POSIX)
|
||||
pthread_mutex_unlock(&mutex);
|
||||
#endif
|
||||
}
|
||||
|
||||
void NzMemoryManager::NextFree(const char* file, unsigned int line)
|
||||
{
|
||||
nextFreeFile = file;
|
||||
nextFreeLine = line;
|
||||
}
|
||||
|
||||
void NzMemoryManager::Initialize()
|
||||
{
|
||||
char* time = TimeInfo();
|
||||
|
||||
FILE* file = std::fopen(MLTFileName, "w");
|
||||
std::fprintf(file, "%s ==============================\n", time);
|
||||
std::fprintf(file, "%s Nazara Memory Leak Tracker \n", time);
|
||||
std::fprintf(file, "%s ==============================\n", time);
|
||||
std::fclose(file);
|
||||
|
||||
std::free(time);
|
||||
|
||||
if (std::atexit(Uninitialize) != 0)
|
||||
{
|
||||
static NzMemoryManager manager;
|
||||
}
|
||||
|
||||
#ifdef NAZARA_PLATFORM_WINDOWS
|
||||
InitializeCriticalSection(&mutex);
|
||||
#endif
|
||||
|
||||
initialized = true;
|
||||
}
|
||||
|
||||
char* NzMemoryManager::TimeInfo()
|
||||
{
|
||||
char* buffer = reinterpret_cast<char*>(std::malloc(23*sizeof(char)));
|
||||
|
||||
time_t currentTime = std::time(nullptr);
|
||||
std::strftime(buffer, 23, "%d/%m/%Y - %H:%M:%S:", std::localtime(¤tTime));
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
void NzMemoryManager::Uninitialize()
|
||||
{
|
||||
#ifdef NAZARA_PLATFORM_WINDOWS
|
||||
DeleteCriticalSection(&mutex);
|
||||
#endif
|
||||
|
||||
FILE* log = std::fopen(MLTFileName, "a");
|
||||
|
||||
char* time = TimeInfo();
|
||||
|
||||
std::fprintf(log, "%s Application finished, checking leaks...\n", time);
|
||||
|
||||
if (ptrList.next == &ptrList)
|
||||
{
|
||||
std::fprintf(log, "%s ==============================\n", time);
|
||||
std::fprintf(log, "%s No leak detected \n", time);
|
||||
std::fprintf(log, "%s ==============================", time);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::fprintf(log, "%s ==============================\n", time);
|
||||
std::fprintf(log, "%s Leaks have been detected \n", time);
|
||||
std::fprintf(log, "%s ==============================\n\n", time);
|
||||
std::fputs("Leak list:\n", log);
|
||||
|
||||
Block* ptr = ptrList.next;
|
||||
unsigned int count = 0;
|
||||
unsigned int totalSize = 0;
|
||||
while (ptr != &ptrList)
|
||||
{
|
||||
count++;
|
||||
totalSize += ptr->size;
|
||||
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, "-0x%p -> %d bytes allocated at unknown position\n", reinterpret_cast<char*>(ptr)+sizeof(Block), ptr->size);
|
||||
|
||||
void* pointer = ptr;
|
||||
ptr = ptr->next;
|
||||
std::free(pointer);
|
||||
}
|
||||
|
||||
std::fprintf(log, "\n%d blocks leaked (%d bytes)", count, totalSize);
|
||||
}
|
||||
|
||||
std::free(time);
|
||||
std::fclose(log);
|
||||
}
|
||||
|
||||
void* operator new(std::size_t size, const char* file, unsigned int line)
|
||||
{
|
||||
return NzMemoryManager::Allocate(size, false, file, line);
|
||||
}
|
||||
|
||||
void* operator new[](std::size_t size, const char* file, unsigned int line)
|
||||
{
|
||||
return NzMemoryManager::Allocate(size, true, file, line);
|
||||
}
|
||||
|
||||
void operator delete(void* ptr, const char* file, unsigned int line) throw()
|
||||
{
|
||||
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);
|
||||
}
|
||||
// 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/Debug/MemoryLeakTracker.hpp>
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <ctime>
|
||||
#include <stdexcept>
|
||||
|
||||
#if defined(NAZARA_PLATFORM_WINDOWS)
|
||||
#include <windows.h>
|
||||
#elif defined(NAZARA_PLATFORM_POSIX)
|
||||
#include <pthread.h>
|
||||
#endif
|
||||
|
||||
namespace
|
||||
{
|
||||
struct Block
|
||||
{
|
||||
std::size_t size;
|
||||
const char* file;
|
||||
Block* prev;
|
||||
Block* next;
|
||||
bool array;
|
||||
unsigned int line;
|
||||
unsigned int magic;
|
||||
};
|
||||
|
||||
bool initialized = false;
|
||||
const unsigned int magic = 0x51429EE;
|
||||
const char* MLTFileName = "NazaraLeaks.log";
|
||||
const char* nextFreeFile = "Internal error";
|
||||
unsigned int nextFreeLine = 0;
|
||||
|
||||
Block ptrList =
|
||||
{
|
||||
0,
|
||||
nullptr,
|
||||
&ptrList,
|
||||
&ptrList,
|
||||
false,
|
||||
0,
|
||||
magic
|
||||
};
|
||||
|
||||
#if defined(NAZARA_PLATFORM_WINDOWS)
|
||||
CRITICAL_SECTION mutex;
|
||||
#elif defined(NAZARA_PLATFORM_POSIX)
|
||||
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
#endif
|
||||
}
|
||||
|
||||
NzMemoryManager::NzMemoryManager()
|
||||
{
|
||||
}
|
||||
|
||||
NzMemoryManager::~NzMemoryManager()
|
||||
{
|
||||
Uninitialize();
|
||||
}
|
||||
|
||||
void* NzMemoryManager::Allocate(std::size_t size, bool multi, const char* file, unsigned int line)
|
||||
{
|
||||
if (!initialized)
|
||||
Initialize();
|
||||
|
||||
#if defined(NAZARA_PLATFORM_WINDOWS)
|
||||
EnterCriticalSection(&mutex);
|
||||
#elif defined(NAZARA_PLATFORM_POSIX)
|
||||
pthread_mutex_lock(&mutex);
|
||||
#endif
|
||||
|
||||
Block* ptr = reinterpret_cast<Block*>(std::malloc(size+sizeof(Block)));
|
||||
if (!ptr)
|
||||
{
|
||||
// Pas d'information de temps (Car nécessitant une allocation)
|
||||
FILE* log = std::fopen(MLTFileName, "a");
|
||||
std::fprintf(log, "Failed to allocate memory (%d bytes)\n", size);
|
||||
std::fclose(log);
|
||||
|
||||
return nullptr; // Impossible d'envoyer une exception car cela allouerait de la mémoire avec new (boucle infinie)
|
||||
}
|
||||
|
||||
ptr->array = multi;
|
||||
ptr->file = file;
|
||||
ptr->line = line;
|
||||
ptr->size = size;
|
||||
ptr->magic = magic;
|
||||
|
||||
ptr->prev = ptrList.prev;
|
||||
ptr->next = &ptrList;
|
||||
ptrList.prev->next = ptr;
|
||||
ptrList.prev = ptr;
|
||||
|
||||
#if defined(NAZARA_PLATFORM_WINDOWS)
|
||||
LeaveCriticalSection(&mutex);
|
||||
#elif defined(NAZARA_PLATFORM_POSIX)
|
||||
pthread_mutex_unlock(&mutex);
|
||||
#endif
|
||||
|
||||
return reinterpret_cast<char*>(ptr)+sizeof(Block);
|
||||
}
|
||||
|
||||
void NzMemoryManager::Free(void* pointer, bool multi)
|
||||
{
|
||||
if (!pointer)
|
||||
return;
|
||||
|
||||
Block* ptr = reinterpret_cast<Block*>(reinterpret_cast<char*>(pointer)-sizeof(Block));
|
||||
if (ptr->magic != magic)
|
||||
return;
|
||||
|
||||
#if defined(NAZARA_PLATFORM_WINDOWS)
|
||||
EnterCriticalSection(&mutex);
|
||||
#elif defined(NAZARA_PLATFORM_POSIX)
|
||||
pthread_mutex_lock(&mutex);
|
||||
#endif
|
||||
|
||||
if (ptr->array != multi)
|
||||
{
|
||||
char* time = TimeInfo();
|
||||
|
||||
FILE* log = std::fopen(MLTFileName, "a");
|
||||
|
||||
if (nextFreeFile)
|
||||
{
|
||||
if (multi)
|
||||
std::fprintf(log, "%s Warning: delete[] after new at %s:%d\n", time, nextFreeFile, nextFreeLine);
|
||||
else
|
||||
std::fprintf(log, "%s Warning: delete after new[] at %s:%d\n", time, nextFreeFile, nextFreeLine);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (multi)
|
||||
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);
|
||||
}
|
||||
|
||||
std::fclose(log);
|
||||
|
||||
std::free(time);
|
||||
}
|
||||
|
||||
ptr->magic = 0;
|
||||
ptr->prev->next = ptr->next;
|
||||
ptr->next->prev = ptr->prev;
|
||||
|
||||
std::free(ptr);
|
||||
|
||||
nextFreeFile = nullptr;
|
||||
nextFreeLine = 0;
|
||||
|
||||
#if defined(NAZARA_PLATFORM_WINDOWS)
|
||||
LeaveCriticalSection(&mutex);
|
||||
#elif defined(NAZARA_PLATFORM_POSIX)
|
||||
pthread_mutex_unlock(&mutex);
|
||||
#endif
|
||||
}
|
||||
|
||||
void NzMemoryManager::NextFree(const char* file, unsigned int line)
|
||||
{
|
||||
nextFreeFile = file;
|
||||
nextFreeLine = line;
|
||||
}
|
||||
|
||||
void NzMemoryManager::Initialize()
|
||||
{
|
||||
char* time = TimeInfo();
|
||||
|
||||
FILE* file = std::fopen(MLTFileName, "w");
|
||||
std::fprintf(file, "%s ==============================\n", time);
|
||||
std::fprintf(file, "%s Nazara Memory Leak Tracker \n", time);
|
||||
std::fprintf(file, "%s ==============================\n", time);
|
||||
std::fclose(file);
|
||||
|
||||
std::free(time);
|
||||
|
||||
if (std::atexit(Uninitialize) != 0)
|
||||
{
|
||||
static NzMemoryManager manager;
|
||||
}
|
||||
|
||||
#ifdef NAZARA_PLATFORM_WINDOWS
|
||||
InitializeCriticalSection(&mutex);
|
||||
#endif
|
||||
|
||||
initialized = true;
|
||||
}
|
||||
|
||||
char* NzMemoryManager::TimeInfo()
|
||||
{
|
||||
char* buffer = reinterpret_cast<char*>(std::malloc(23*sizeof(char)));
|
||||
|
||||
time_t currentTime = std::time(nullptr);
|
||||
std::strftime(buffer, 23, "%d/%m/%Y - %H:%M:%S:", std::localtime(¤tTime));
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
void NzMemoryManager::Uninitialize()
|
||||
{
|
||||
#ifdef NAZARA_PLATFORM_WINDOWS
|
||||
DeleteCriticalSection(&mutex);
|
||||
#endif
|
||||
|
||||
FILE* log = std::fopen(MLTFileName, "a");
|
||||
|
||||
char* time = TimeInfo();
|
||||
|
||||
std::fprintf(log, "%s Application finished, checking leaks...\n", time);
|
||||
|
||||
if (ptrList.next == &ptrList)
|
||||
{
|
||||
std::fprintf(log, "%s ==============================\n", time);
|
||||
std::fprintf(log, "%s No leak detected \n", time);
|
||||
std::fprintf(log, "%s ==============================", time);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::fprintf(log, "%s ==============================\n", time);
|
||||
std::fprintf(log, "%s Leaks have been detected \n", time);
|
||||
std::fprintf(log, "%s ==============================\n\n", time);
|
||||
std::fputs("Leak list:\n", log);
|
||||
|
||||
Block* ptr = ptrList.next;
|
||||
unsigned int count = 0;
|
||||
unsigned int totalSize = 0;
|
||||
while (ptr != &ptrList)
|
||||
{
|
||||
count++;
|
||||
totalSize += ptr->size;
|
||||
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, "-0x%p -> %d bytes allocated at unknown position\n", reinterpret_cast<char*>(ptr)+sizeof(Block), ptr->size);
|
||||
|
||||
void* pointer = ptr;
|
||||
ptr = ptr->next;
|
||||
std::free(pointer);
|
||||
}
|
||||
|
||||
std::fprintf(log, "\n%d blocks leaked (%d bytes)", count, totalSize);
|
||||
}
|
||||
|
||||
std::free(time);
|
||||
std::fclose(log);
|
||||
}
|
||||
|
||||
void* operator new(std::size_t size, const char* file, unsigned int line)
|
||||
{
|
||||
return NzMemoryManager::Allocate(size, false, file, line);
|
||||
}
|
||||
|
||||
void* operator new[](std::size_t size, const char* file, unsigned int line)
|
||||
{
|
||||
return NzMemoryManager::Allocate(size, true, file, line);
|
||||
}
|
||||
|
||||
void operator delete(void* ptr, const char* file, unsigned int line) throw()
|
||||
{
|
||||
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
|
||||
// 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/Resource.hpp>
|
||||
#include <Nazara/Core/Config.hpp>
|
||||
#include <Nazara/Core/Error.hpp>
|
||||
#include <Nazara/Core/Debug.hpp>
|
||||
|
||||
NzResource::NzResource(bool persistent) :
|
||||
m_resourcePersistent(persistent),
|
||||
m_resourceReferenceCount(0)
|
||||
{
|
||||
}
|
||||
|
||||
NzResource::NzResource(const NzResource& resource) :
|
||||
m_resourcePersistent(resource.m_resourcePersistent),
|
||||
m_resourceReferenceCount(0)
|
||||
{
|
||||
}
|
||||
|
||||
NzResource::~NzResource() = default;
|
||||
|
||||
void NzResource::AddResourceReference() const
|
||||
{
|
||||
m_resourceReferenceCount++;
|
||||
}
|
||||
|
||||
bool NzResource::IsPersistent() const
|
||||
{
|
||||
return m_resourcePersistent;
|
||||
}
|
||||
|
||||
void NzResource::RemoveResourceReference() const
|
||||
{
|
||||
#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)
|
||||
delete this;
|
||||
}
|
||||
|
||||
void NzResource::SetPersistent(bool persistent)
|
||||
{
|
||||
m_resourcePersistent = persistent;
|
||||
|
||||
if (!persistent && m_resourceReferenceCount == 0)
|
||||
delete this;
|
||||
}
|
||||
// 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/Resource.hpp>
|
||||
#include <Nazara/Core/Config.hpp>
|
||||
#include <Nazara/Core/Error.hpp>
|
||||
#include <Nazara/Core/ResourceListener.hpp>
|
||||
#include <Nazara/Core/Debug.hpp>
|
||||
|
||||
NzResource::NzResource(bool persistent) :
|
||||
m_resourcePersistent(persistent),
|
||||
m_resourceReferenceCount(0)
|
||||
{
|
||||
}
|
||||
|
||||
NzResource::NzResource(const NzResource& resource) :
|
||||
m_resourcePersistent(resource.m_resourcePersistent),
|
||||
m_resourceReferenceCount(0)
|
||||
{
|
||||
}
|
||||
|
||||
NzResource::~NzResource()
|
||||
{
|
||||
EnsureResourceListenerUpdate();
|
||||
|
||||
for (auto it = m_resourceListenersCache.begin(); it != m_resourceListenersCache.end(); ++it)
|
||||
(*it).listener->OnResourceReleased(this, (*it).index);
|
||||
}
|
||||
|
||||
void NzResource::AddResourceListener(NzResourceListener* listener, int index) const
|
||||
{
|
||||
NazaraLock(m_mutex)
|
||||
|
||||
if (m_resourceListeners.insert(NzResourceEntry(listener, index)).second)
|
||||
{
|
||||
m_resourceListenerUpdated = false;
|
||||
|
||||
// AddResourceReference()
|
||||
m_resourceReferenceCount++;
|
||||
}
|
||||
}
|
||||
|
||||
void NzResource::AddResourceReference() const
|
||||
{
|
||||
NazaraLock(m_mutex)
|
||||
|
||||
m_resourceReferenceCount++;
|
||||
}
|
||||
|
||||
bool NzResource::IsPersistent() const
|
||||
{
|
||||
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
|
||||
// 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/Context.hpp>
|
||||
#include <Nazara/Core/Error.hpp>
|
||||
#include <Nazara/Core/Log.hpp>
|
||||
#include <Nazara/Core/StringStream.hpp>
|
||||
#include <Nazara/Renderer/Config.hpp>
|
||||
#include <vector>
|
||||
|
||||
#if defined(NAZARA_PLATFORM_WINDOWS)
|
||||
#include <Nazara/Renderer/Win32/ContextImpl.hpp>
|
||||
#elif defined(NAZARA_PLATFORM_LINUX)
|
||||
#include <Nazara/Renderer/Linux/ContextImpl.hpp>
|
||||
#else
|
||||
#error Lack of implementation: Context
|
||||
#endif
|
||||
|
||||
#include <Nazara/Renderer/Debug.hpp>
|
||||
|
||||
namespace
|
||||
{
|
||||
NAZARA_THREADLOCAL NzContext* currentContext = nullptr;
|
||||
NAZARA_THREADLOCAL NzContext* threadContext = nullptr;
|
||||
|
||||
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)
|
||||
{
|
||||
NazaraUnused(length);
|
||||
|
||||
NzStringStream ss;
|
||||
ss << "OpenGL debug message (ID: 0x" << NzString::Number(id, 16) << "):\n";
|
||||
ss << "Sent by context: " << userParam;
|
||||
ss << "\n-Source: ";
|
||||
switch (source)
|
||||
{
|
||||
case GL_DEBUG_SOURCE_API_ARB:
|
||||
ss << "OpenGL";
|
||||
break;
|
||||
|
||||
case GL_DEBUG_SOURCE_WINDOW_SYSTEM_ARB:
|
||||
ss << "Operating system";
|
||||
break;
|
||||
|
||||
case GL_DEBUG_SOURCE_SHADER_COMPILER_ARB:
|
||||
ss << "Shader compiler";
|
||||
break;
|
||||
|
||||
case GL_DEBUG_SOURCE_THIRD_PARTY_ARB:
|
||||
ss << "Shader compiler";
|
||||
break;
|
||||
|
||||
case GL_DEBUG_SOURCE_APPLICATION_ARB:
|
||||
ss << "Application";
|
||||
break;
|
||||
|
||||
case GL_DEBUG_SOURCE_OTHER_ARB:
|
||||
ss << "Other";
|
||||
break;
|
||||
|
||||
default:
|
||||
// Peut être rajouté par une extension
|
||||
ss << "Unknown";
|
||||
break;
|
||||
}
|
||||
ss << '\n';
|
||||
|
||||
ss << "-Type: ";
|
||||
switch (type)
|
||||
{
|
||||
case GL_DEBUG_TYPE_ERROR_ARB:
|
||||
ss << "Error";
|
||||
break;
|
||||
|
||||
case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_ARB:
|
||||
ss << "Deprecated behavior";
|
||||
break;
|
||||
|
||||
case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_ARB:
|
||||
ss << "Undefined behavior";
|
||||
break;
|
||||
|
||||
case GL_DEBUG_TYPE_PORTABILITY_ARB:
|
||||
ss << "Portability";
|
||||
break;
|
||||
|
||||
case GL_DEBUG_TYPE_PERFORMANCE_ARB:
|
||||
ss << "Performance";
|
||||
break;
|
||||
|
||||
case GL_DEBUG_TYPE_OTHER_ARB:
|
||||
ss << "Other";
|
||||
break;
|
||||
|
||||
default:
|
||||
// Peut être rajouté par une extension
|
||||
ss << "Unknown";
|
||||
break;
|
||||
}
|
||||
ss << '\n';
|
||||
|
||||
ss << "-Severity: ";
|
||||
switch (severity)
|
||||
{
|
||||
case GL_DEBUG_SEVERITY_HIGH_ARB:
|
||||
ss << "High";
|
||||
break;
|
||||
|
||||
case GL_DEBUG_SEVERITY_MEDIUM_ARB:
|
||||
ss << "Medium";
|
||||
break;
|
||||
|
||||
case GL_DEBUG_SEVERITY_LOW_ARB:
|
||||
ss << "Low";
|
||||
break;
|
||||
|
||||
default:
|
||||
// Peut être rajouté par une extension
|
||||
ss << "Unknown";
|
||||
break;
|
||||
}
|
||||
ss << '\n';
|
||||
|
||||
ss << "Message: " << message << '\n';
|
||||
|
||||
NazaraNotice(ss);
|
||||
}
|
||||
}
|
||||
|
||||
NzContext::NzContext() :
|
||||
m_impl(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
NzContext::~NzContext()
|
||||
{
|
||||
Destroy();
|
||||
}
|
||||
|
||||
bool NzContext::Create(const NzContextParameters& parameters)
|
||||
{
|
||||
Destroy();
|
||||
|
||||
m_parameters = parameters;
|
||||
if (m_parameters.shared && !m_parameters.shareContext)
|
||||
m_parameters.shareContext = s_reference;
|
||||
|
||||
m_impl = new NzContextImpl;
|
||||
if (!m_impl->Create(m_parameters))
|
||||
{
|
||||
NazaraError("Failed to create context implementation");
|
||||
delete m_impl;
|
||||
m_impl = nullptr;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!m_impl->Activate())
|
||||
{
|
||||
NazaraError("Failed to activate context");
|
||||
|
||||
m_impl->Destroy();
|
||||
delete m_impl;
|
||||
m_impl = nullptr;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (m_parameters.antialiasingLevel > 0)
|
||||
glEnable(GL_MULTISAMPLE);
|
||||
|
||||
if (NzOpenGL::IsSupported(NzOpenGL::DebugOutput) && m_parameters.debugMode)
|
||||
{
|
||||
glDebugMessageCallback(&DebugCallback, this);
|
||||
|
||||
#ifdef NAZARA_DEBUG
|
||||
glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB);
|
||||
#endif
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void NzContext::Destroy()
|
||||
{
|
||||
if (m_impl)
|
||||
{
|
||||
if (currentContext == this)
|
||||
NzContextImpl::Desactivate();
|
||||
|
||||
m_impl->Destroy();
|
||||
delete m_impl;
|
||||
m_impl = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
const NzContextParameters& NzContext::GetParameters() const
|
||||
{
|
||||
#ifdef NAZARA_RENDERER_SAFE
|
||||
if (!m_impl)
|
||||
NazaraError("No context has been created");
|
||||
#endif
|
||||
|
||||
return m_parameters;
|
||||
}
|
||||
|
||||
bool NzContext::IsActive() const
|
||||
{
|
||||
#ifdef NAZARA_RENDERER_SAFE
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraError("No context has been created");
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
return currentContext == this;
|
||||
}
|
||||
|
||||
bool NzContext::SetActive(bool active)
|
||||
{
|
||||
#ifdef NAZARA_RENDERER_SAFE
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraError("No context has been created");
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Si le contexte est déjà activé/désactivé
|
||||
if ((currentContext == this) == active)
|
||||
return true;
|
||||
|
||||
if (active)
|
||||
{
|
||||
if (!m_impl->Activate())
|
||||
return false;
|
||||
|
||||
currentContext = this;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!NzContextImpl::Desactivate())
|
||||
return false;
|
||||
|
||||
currentContext = nullptr;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void NzContext::SwapBuffers()
|
||||
{
|
||||
#ifdef NAZARA_RENDERER_SAFE
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraError("No context has been created");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!m_parameters.doubleBuffered)
|
||||
{
|
||||
NazaraError("Context is not double buffered");
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
m_impl->SwapBuffers();
|
||||
}
|
||||
|
||||
bool NzContext::EnsureContext()
|
||||
{
|
||||
if (!currentContext)
|
||||
{
|
||||
if (!threadContext)
|
||||
{
|
||||
NzContext* context = new NzContext;
|
||||
if (!context->Create())
|
||||
{
|
||||
NazaraError("Failed to create context");
|
||||
delete context;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
contexts.push_back(context);
|
||||
|
||||
threadContext = context;
|
||||
}
|
||||
|
||||
if (!threadContext->SetActive(true))
|
||||
{
|
||||
NazaraError("Failed to active thread context");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
NzContext* NzContext::GetCurrent()
|
||||
{
|
||||
return currentContext;
|
||||
}
|
||||
|
||||
const NzContext* NzContext::GetReference()
|
||||
{
|
||||
return s_reference;
|
||||
}
|
||||
|
||||
NzContext* NzContext::GetThreadContext()
|
||||
{
|
||||
EnsureContext();
|
||||
|
||||
return threadContext;
|
||||
}
|
||||
|
||||
bool NzContext::Initialize()
|
||||
{
|
||||
NzContextParameters parameters;
|
||||
// parameters.compatibilityProfile = true;
|
||||
parameters.shared = false; // Difficile de partager le contexte de référence avec lui-même
|
||||
|
||||
s_reference = new NzContext;
|
||||
if (!s_reference->Create(parameters))
|
||||
{
|
||||
delete s_reference;
|
||||
s_reference = nullptr;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Le contexte de référence doit rester désactivé pour le partage
|
||||
s_reference->SetActive(false);
|
||||
|
||||
NzContextParameters::defaultShareContext = s_reference;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void NzContext::Uninitialize()
|
||||
{
|
||||
for (NzContext* context : contexts)
|
||||
delete context;
|
||||
|
||||
contexts.clear(); // On supprime tous les contextes créés
|
||||
|
||||
delete s_reference;
|
||||
s_reference = nullptr;
|
||||
}
|
||||
|
||||
NzContext* NzContext::s_reference = nullptr;
|
||||
// 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/Context.hpp>
|
||||
#include <Nazara/Core/Error.hpp>
|
||||
#include <Nazara/Core/Log.hpp>
|
||||
#include <Nazara/Core/StringStream.hpp>
|
||||
#include <Nazara/Renderer/Config.hpp>
|
||||
#include <vector>
|
||||
|
||||
#if defined(NAZARA_PLATFORM_WINDOWS)
|
||||
#include <Nazara/Renderer/Win32/ContextImpl.hpp>
|
||||
#elif defined(NAZARA_PLATFORM_LINUX)
|
||||
#include <Nazara/Renderer/Linux/ContextImpl.hpp>
|
||||
#else
|
||||
#error Lack of implementation: Context
|
||||
#endif
|
||||
|
||||
#include <Nazara/Renderer/Debug.hpp>
|
||||
|
||||
namespace
|
||||
{
|
||||
NAZARA_THREADLOCAL NzContext* currentContext = nullptr;
|
||||
NAZARA_THREADLOCAL NzContext* threadContext = nullptr;
|
||||
|
||||
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)
|
||||
{
|
||||
NazaraUnused(length);
|
||||
|
||||
NzStringStream ss;
|
||||
ss << "OpenGL debug message (ID: 0x" << NzString::Number(id, 16) << "):\n";
|
||||
ss << "Sent by context: " << userParam;
|
||||
ss << "\n-Source: ";
|
||||
switch (source)
|
||||
{
|
||||
case GL_DEBUG_SOURCE_API_ARB:
|
||||
ss << "OpenGL";
|
||||
break;
|
||||
|
||||
case GL_DEBUG_SOURCE_WINDOW_SYSTEM_ARB:
|
||||
ss << "Operating system";
|
||||
break;
|
||||
|
||||
case GL_DEBUG_SOURCE_SHADER_COMPILER_ARB:
|
||||
ss << "Shader compiler";
|
||||
break;
|
||||
|
||||
case GL_DEBUG_SOURCE_THIRD_PARTY_ARB:
|
||||
ss << "Shader compiler";
|
||||
break;
|
||||
|
||||
case GL_DEBUG_SOURCE_APPLICATION_ARB:
|
||||
ss << "Application";
|
||||
break;
|
||||
|
||||
case GL_DEBUG_SOURCE_OTHER_ARB:
|
||||
ss << "Other";
|
||||
break;
|
||||
|
||||
default:
|
||||
// Peut être rajouté par une extension
|
||||
ss << "Unknown";
|
||||
break;
|
||||
}
|
||||
ss << '\n';
|
||||
|
||||
ss << "-Type: ";
|
||||
switch (type)
|
||||
{
|
||||
case GL_DEBUG_TYPE_ERROR_ARB:
|
||||
ss << "Error";
|
||||
break;
|
||||
|
||||
case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_ARB:
|
||||
ss << "Deprecated behavior";
|
||||
break;
|
||||
|
||||
case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_ARB:
|
||||
ss << "Undefined behavior";
|
||||
break;
|
||||
|
||||
case GL_DEBUG_TYPE_PORTABILITY_ARB:
|
||||
ss << "Portability";
|
||||
break;
|
||||
|
||||
case GL_DEBUG_TYPE_PERFORMANCE_ARB:
|
||||
ss << "Performance";
|
||||
break;
|
||||
|
||||
case GL_DEBUG_TYPE_OTHER_ARB:
|
||||
ss << "Other";
|
||||
break;
|
||||
|
||||
default:
|
||||
// Peut être rajouté par une extension
|
||||
ss << "Unknown";
|
||||
break;
|
||||
}
|
||||
ss << '\n';
|
||||
|
||||
ss << "-Severity: ";
|
||||
switch (severity)
|
||||
{
|
||||
case GL_DEBUG_SEVERITY_HIGH_ARB:
|
||||
ss << "High";
|
||||
break;
|
||||
|
||||
case GL_DEBUG_SEVERITY_MEDIUM_ARB:
|
||||
ss << "Medium";
|
||||
break;
|
||||
|
||||
case GL_DEBUG_SEVERITY_LOW_ARB:
|
||||
ss << "Low";
|
||||
break;
|
||||
|
||||
default:
|
||||
// Peut être rajouté par une extension
|
||||
ss << "Unknown";
|
||||
break;
|
||||
}
|
||||
ss << '\n';
|
||||
|
||||
ss << "Message: " << message << '\n';
|
||||
|
||||
NazaraNotice(ss);
|
||||
}
|
||||
}
|
||||
|
||||
NzContext::NzContext() :
|
||||
m_impl(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
NzContext::~NzContext()
|
||||
{
|
||||
Destroy();
|
||||
}
|
||||
|
||||
bool NzContext::Create(const NzContextParameters& parameters)
|
||||
{
|
||||
Destroy();
|
||||
|
||||
m_parameters = parameters;
|
||||
if (m_parameters.shared && !m_parameters.shareContext)
|
||||
m_parameters.shareContext = s_reference;
|
||||
|
||||
m_impl = new NzContextImpl;
|
||||
if (!m_impl->Create(m_parameters))
|
||||
{
|
||||
NazaraError("Failed to create context implementation");
|
||||
delete m_impl;
|
||||
m_impl = nullptr;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!m_impl->Activate())
|
||||
{
|
||||
NazaraError("Failed to activate context");
|
||||
|
||||
m_impl->Destroy();
|
||||
delete m_impl;
|
||||
m_impl = nullptr;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (m_parameters.antialiasingLevel > 0)
|
||||
glEnable(GL_MULTISAMPLE);
|
||||
|
||||
if (NzOpenGL::IsSupported(nzOpenGLExtension_DebugOutput) && m_parameters.debugMode)
|
||||
{
|
||||
glDebugMessageCallback(&DebugCallback, this);
|
||||
|
||||
#ifdef NAZARA_DEBUG
|
||||
glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
|
||||
#endif
|
||||
}
|
||||
|
||||
NotifyCreated();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void NzContext::Destroy()
|
||||
{
|
||||
if (m_impl)
|
||||
{
|
||||
NotifyDestroy();
|
||||
|
||||
if (currentContext == this)
|
||||
NzContextImpl::Desactivate();
|
||||
|
||||
m_impl->Destroy();
|
||||
delete m_impl;
|
||||
m_impl = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
const NzContextParameters& NzContext::GetParameters() const
|
||||
{
|
||||
#ifdef NAZARA_RENDERER_SAFE
|
||||
if (!m_impl)
|
||||
NazaraError("No context has been created");
|
||||
#endif
|
||||
|
||||
return m_parameters;
|
||||
}
|
||||
|
||||
bool NzContext::IsActive() const
|
||||
{
|
||||
#ifdef NAZARA_RENDERER_SAFE
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraError("No context has been created");
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
return currentContext == this;
|
||||
}
|
||||
|
||||
bool NzContext::SetActive(bool active)
|
||||
{
|
||||
#ifdef NAZARA_RENDERER_SAFE
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraError("No context has been created");
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Si le contexte est déjà activé/désactivé
|
||||
if ((currentContext == this) == active)
|
||||
return true;
|
||||
|
||||
if (active)
|
||||
{
|
||||
if (!m_impl->Activate())
|
||||
return false;
|
||||
|
||||
currentContext = this;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!NzContextImpl::Desactivate())
|
||||
return false;
|
||||
|
||||
currentContext = nullptr;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void NzContext::SwapBuffers()
|
||||
{
|
||||
#ifdef NAZARA_RENDERER_SAFE
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraError("No context has been created");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!m_parameters.doubleBuffered)
|
||||
{
|
||||
NazaraError("Context is not double buffered");
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
m_impl->SwapBuffers();
|
||||
}
|
||||
|
||||
bool NzContext::EnsureContext()
|
||||
{
|
||||
if (!currentContext)
|
||||
{
|
||||
if (!threadContext)
|
||||
{
|
||||
NzContext* context = new NzContext;
|
||||
if (!context->Create())
|
||||
{
|
||||
NazaraError("Failed to create context");
|
||||
delete context;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
contexts.push_back(context);
|
||||
|
||||
threadContext = context;
|
||||
}
|
||||
|
||||
if (!threadContext->SetActive(true))
|
||||
{
|
||||
NazaraError("Failed to active thread context");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
NzContext* NzContext::GetCurrent()
|
||||
{
|
||||
return currentContext;
|
||||
}
|
||||
|
||||
const NzContext* NzContext::GetReference()
|
||||
{
|
||||
return s_reference;
|
||||
}
|
||||
|
||||
NzContext* NzContext::GetThreadContext()
|
||||
{
|
||||
EnsureContext();
|
||||
|
||||
return threadContext;
|
||||
}
|
||||
|
||||
bool NzContext::Initialize()
|
||||
{
|
||||
NzContextParameters parameters;
|
||||
// parameters.compatibilityProfile = true;
|
||||
parameters.shared = false; // Difficile de partager le contexte de référence avec lui-même
|
||||
|
||||
s_reference = new NzContext;
|
||||
if (!s_reference->Create(parameters))
|
||||
{
|
||||
delete s_reference;
|
||||
s_reference = nullptr;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Le contexte de référence doit rester désactivé pour le partage
|
||||
s_reference->SetActive(false);
|
||||
|
||||
NzContextParameters::defaultShareContext = s_reference;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void NzContext::Uninitialize()
|
||||
{
|
||||
for (NzContext* context : contexts)
|
||||
delete context;
|
||||
|
||||
contexts.clear(); // On supprime tous les contextes créés
|
||||
|
||||
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
|
||||
// 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_GLSLSHADER_HPP
|
||||
#define NAZARA_GLSLSHADER_HPP
|
||||
|
||||
#include <Nazara/Core/String.hpp>
|
||||
#include <Nazara/Renderer/OpenGL.hpp>
|
||||
#include <Nazara/Renderer/Shader.hpp>
|
||||
#include <Nazara/Renderer/ShaderImpl.hpp>
|
||||
#include <map>
|
||||
|
||||
class NzGLSLShader : public NzShaderImpl
|
||||
{
|
||||
public:
|
||||
NzGLSLShader(NzShader* parent);
|
||||
~NzGLSLShader();
|
||||
|
||||
bool Bind();
|
||||
bool BindTextures();
|
||||
|
||||
bool Compile();
|
||||
|
||||
bool Create();
|
||||
void Destroy();
|
||||
|
||||
NzString GetLog() const;
|
||||
nzShaderLanguage GetLanguage() const;
|
||||
NzString GetSourceCode(nzShaderType type) const;
|
||||
int GetUniformLocation(const NzString& name) const;
|
||||
|
||||
bool IsLoaded(nzShaderType type) const;
|
||||
|
||||
bool Load(nzShaderType type, const NzString& source);
|
||||
bool Lock();
|
||||
|
||||
bool SendBoolean(int location, bool value);
|
||||
bool SendDouble(int location, double value);
|
||||
bool SendFloat(int location, float value);
|
||||
bool SendInteger(int location, int value);
|
||||
bool SendMatrix(int location, const NzMatrix4d& matrix);
|
||||
bool SendMatrix(int location, const NzMatrix4f& matrix);
|
||||
bool SendTexture(int location, const NzTexture* texture);
|
||||
bool SendVector(int location, const NzVector2d& vector);
|
||||
bool SendVector(int location, const NzVector2f& vector);
|
||||
bool SendVector(int location, const NzVector3d& vector);
|
||||
bool SendVector(int location, const NzVector3f& vector);
|
||||
bool SendVector(int location, const NzVector4d& vector);
|
||||
bool SendVector(int location, const NzVector4f& vector);
|
||||
|
||||
void Unbind();
|
||||
void Unlock();
|
||||
|
||||
private:
|
||||
struct TextureSlot
|
||||
{
|
||||
bool updated = false;
|
||||
nzUInt8 unit;
|
||||
const NzTexture* texture;
|
||||
};
|
||||
|
||||
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
|
||||
// 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_GLSLSHADER_HPP
|
||||
#define NAZARA_GLSLSHADER_HPP
|
||||
|
||||
#include <Nazara/Core/ResourceListener.hpp>
|
||||
#include <Nazara/Core/String.hpp>
|
||||
#include <Nazara/Renderer/OpenGL.hpp>
|
||||
#include <Nazara/Renderer/Shader.hpp>
|
||||
#include <Nazara/Renderer/ShaderImpl.hpp>
|
||||
#include <map>
|
||||
|
||||
class NzResource;
|
||||
|
||||
class NzGLSLShader : public NzShaderImpl, NzResourceListener
|
||||
{
|
||||
public:
|
||||
NzGLSLShader(NzShader* parent);
|
||||
~NzGLSLShader();
|
||||
|
||||
bool Bind();
|
||||
bool BindTextures();
|
||||
|
||||
bool Compile();
|
||||
|
||||
bool Create();
|
||||
void Destroy();
|
||||
|
||||
NzString GetLog() const;
|
||||
nzShaderLanguage GetLanguage() const;
|
||||
NzString GetSourceCode(nzShaderType type) const;
|
||||
int GetUniformLocation(const NzString& name) const;
|
||||
|
||||
bool IsLoaded(nzShaderType type) const;
|
||||
|
||||
bool Load(nzShaderType type, const NzString& source);
|
||||
bool Lock();
|
||||
|
||||
bool SendBoolean(int location, bool value);
|
||||
bool SendDouble(int location, double value);
|
||||
bool SendFloat(int location, float value);
|
||||
bool SendInteger(int location, int value);
|
||||
bool SendMatrix(int location, const NzMatrix4d& matrix);
|
||||
bool SendMatrix(int location, const NzMatrix4f& matrix);
|
||||
bool SendTexture(int location, const NzTexture* texture);
|
||||
bool SendVector(int location, const NzVector2d& vector);
|
||||
bool SendVector(int location, const NzVector2f& vector);
|
||||
bool SendVector(int location, const NzVector3d& vector);
|
||||
bool SendVector(int location, const NzVector3f& vector);
|
||||
bool SendVector(int location, const NzVector4d& vector);
|
||||
bool SendVector(int location, const NzVector4f& vector);
|
||||
|
||||
void Unbind();
|
||||
void Unlock();
|
||||
|
||||
private:
|
||||
void OnResourceCreated(const NzResource* resource, int index) override;
|
||||
void OnResourceDestroy(const NzResource* resource, int index) override;
|
||||
void OnResourceReleased(const NzResource* resource, int index) override;
|
||||
|
||||
struct TextureSlot
|
||||
{
|
||||
bool enabled;
|
||||
bool updated = false;
|
||||
nzUInt8 unit;
|
||||
const NzTexture* texture;
|
||||
};
|
||||
|
||||
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
|
||||
// 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/HardwareBuffer.hpp>
|
||||
#include <Nazara/Core/Error.hpp>
|
||||
#include <Nazara/Renderer/Context.hpp>
|
||||
#include <cstring>
|
||||
#include <stdexcept>
|
||||
#include <Nazara/Renderer/Debug.hpp>
|
||||
|
||||
namespace
|
||||
{
|
||||
GLenum bufferLock[] = {
|
||||
GL_WRITE_ONLY, // nzBufferAccess_DiscardAndWrite
|
||||
GL_READ_ONLY, // nzBufferAccess_ReadOnly
|
||||
GL_READ_WRITE, // nzBufferAccess_ReadWrite
|
||||
GL_WRITE_ONLY // nzBufferAccess_WriteOnly
|
||||
};
|
||||
|
||||
GLenum bufferLockRange[] = {
|
||||
GL_MAP_INVALIDATE_BUFFER_BIT | GL_MAP_WRITE_BIT, // nzBufferAccess_DiscardAndWrite
|
||||
GL_MAP_READ_BIT, // nzBufferAccess_ReadOnly
|
||||
GL_MAP_READ_BIT | GL_MAP_WRITE_BIT, // nzBufferAccess_ReadWrite
|
||||
GL_MAP_WRITE_BIT // nzBufferAccess_WriteOnly
|
||||
};
|
||||
|
||||
GLenum bufferTarget[] = {
|
||||
GL_ELEMENT_ARRAY_BUFFER, // nzBufferType_Index,
|
||||
GL_ARRAY_BUFFER, // nzBufferType_Vertex
|
||||
};
|
||||
|
||||
GLenum bufferTargetBinding[] = {
|
||||
GL_ELEMENT_ARRAY_BUFFER_BINDING, // nzBufferType_Index,
|
||||
GL_ARRAY_BUFFER_BINDING, // nzBufferType_Vertex
|
||||
};
|
||||
|
||||
GLenum bufferUsage[] = {
|
||||
// J'ai choisi DYNAMIC à la place de STREAM car DYNAMIC semble plus adapté au profil "une mise à jour pour quelques rendus"
|
||||
// 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
|
||||
GL_DYNAMIC_DRAW, // nzBufferUsage_Dynamic
|
||||
GL_STATIC_DRAW // nzBufferUsage_Static
|
||||
};
|
||||
|
||||
using LockRoutine = nzUInt8* (*)(nzBufferType type, nzBufferAccess access, unsigned int offset, unsigned int size);
|
||||
|
||||
nzUInt8* LockBuffer(nzBufferType type, nzBufferAccess access, unsigned int offset, unsigned int size)
|
||||
{
|
||||
NazaraUnused(size);
|
||||
|
||||
if (access == nzBufferAccess_DiscardAndWrite)
|
||||
{
|
||||
GLint bufSize;
|
||||
glGetBufferParameteriv(bufferTargetBinding[type], GL_BUFFER_SIZE, &bufSize);
|
||||
|
||||
GLint bufUsage;
|
||||
glGetBufferParameteriv(bufferTargetBinding[type], GL_BUFFER_USAGE, &bufUsage);
|
||||
|
||||
// On discard le buffer
|
||||
glBufferData(bufferTargetBinding[type], bufSize, nullptr, bufUsage);
|
||||
}
|
||||
|
||||
void* ptr = glMapBuffer(bufferTarget[type], bufferLock[access]);
|
||||
if (ptr)
|
||||
return reinterpret_cast<nzUInt8*>(ptr) + offset;
|
||||
else
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nzUInt8* LockBufferRange(nzBufferType type, nzBufferAccess access, unsigned int offset, unsigned int size)
|
||||
{
|
||||
return reinterpret_cast<nzUInt8*>(glMapBufferRange(bufferTarget[type], offset, size, bufferLockRange[access]));
|
||||
}
|
||||
|
||||
nzUInt8* LockBufferFirstRun(nzBufferType type, nzBufferAccess access, unsigned int offset, unsigned int size);
|
||||
|
||||
LockRoutine mapBuffer = LockBufferFirstRun;
|
||||
|
||||
nzUInt8* LockBufferFirstRun(nzBufferType type, nzBufferAccess access, unsigned int offset, unsigned int size)
|
||||
{
|
||||
if (glMapBufferRange)
|
||||
mapBuffer = LockBufferRange;
|
||||
else
|
||||
mapBuffer = LockBuffer;
|
||||
|
||||
return mapBuffer(type, access, offset, size);
|
||||
}
|
||||
}
|
||||
|
||||
NzHardwareBuffer::NzHardwareBuffer(NzBuffer* parent, nzBufferType type) :
|
||||
m_type(type),
|
||||
m_parent(parent)
|
||||
{
|
||||
}
|
||||
|
||||
NzHardwareBuffer::~NzHardwareBuffer()
|
||||
{
|
||||
}
|
||||
|
||||
void NzHardwareBuffer::Bind()
|
||||
{
|
||||
#ifdef NAZARA_DEBUG
|
||||
if (NzContext::GetCurrent() == nullptr)
|
||||
{
|
||||
NazaraError("No active context");
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
glBindBuffer(bufferTarget[m_type], m_buffer);
|
||||
}
|
||||
|
||||
bool NzHardwareBuffer::Create(unsigned int size, nzBufferUsage usage)
|
||||
{
|
||||
NzContext::EnsureContext();
|
||||
|
||||
m_buffer = 0;
|
||||
glGenBuffers(1, &m_buffer);
|
||||
|
||||
GLint previous;
|
||||
glGetIntegerv(bufferTargetBinding[m_type], &previous);
|
||||
|
||||
glBindBuffer(bufferTarget[m_type], m_buffer);
|
||||
glBufferData(bufferTarget[m_type], size, nullptr, bufferUsage[usage]);
|
||||
|
||||
// Pour ne pas perturber le rendu, on interfère pas avec le binding déjà présent
|
||||
if (previous != 0)
|
||||
glBindBuffer(bufferTarget[m_type], previous);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void NzHardwareBuffer::Destroy()
|
||||
{
|
||||
NzContext::EnsureContext();
|
||||
|
||||
glDeleteBuffers(1, &m_buffer);
|
||||
}
|
||||
|
||||
bool NzHardwareBuffer::Fill(const void* data, unsigned int offset, unsigned int size)
|
||||
{
|
||||
NzContext::EnsureContext();
|
||||
|
||||
GLuint previous;
|
||||
glGetIntegerv(bufferTargetBinding[m_type], reinterpret_cast<GLint*>(&previous));
|
||||
|
||||
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
|
||||
// http://www.stevestreeting.com/2007/03/17/glmapbuffer-vs-glbuffersubdata-the-return/
|
||||
if (size < 32*1024)
|
||||
{
|
||||
// http://www.opengl.org/wiki/Vertex_Specification_Best_Practices
|
||||
if (size == m_parent->GetSize())
|
||||
glBufferData(bufferTarget[m_type], m_parent->GetSize(), nullptr, bufferUsage[m_parent->GetUsage()]); // Discard
|
||||
|
||||
glBufferSubData(bufferTarget[m_type], offset, size, data);
|
||||
}
|
||||
else
|
||||
{
|
||||
nzUInt8* ptr = mapBuffer(m_type, (size == m_parent->GetSize()) ? nzBufferAccess_DiscardAndWrite : nzBufferAccess_WriteOnly, offset, size);
|
||||
if (!ptr)
|
||||
{
|
||||
NazaraError("Failed to map buffer");
|
||||
return false;
|
||||
}
|
||||
|
||||
std::memcpy(ptr, data, size);
|
||||
|
||||
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()]);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
void* NzHardwareBuffer::GetPointer()
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool NzHardwareBuffer::IsHardware() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
void* NzHardwareBuffer::Map(nzBufferAccess access, unsigned int offset, unsigned int size)
|
||||
{
|
||||
NzContext::EnsureContext();
|
||||
|
||||
// Pour ne pas perturber le rendu, on interfère pas avec le binding déjà présent
|
||||
GLuint previous;
|
||||
glGetIntegerv(bufferTargetBinding[m_type], reinterpret_cast<GLint*>(&previous));
|
||||
|
||||
if (previous != m_buffer)
|
||||
glBindBuffer(bufferTarget[m_type], m_buffer);
|
||||
|
||||
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)
|
||||
glBindBuffer(bufferTarget[m_type], previous);
|
||||
|
||||
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;
|
||||
}
|
||||
// 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/HardwareBuffer.hpp>
|
||||
#include <Nazara/Core/Error.hpp>
|
||||
#include <Nazara/Renderer/Context.hpp>
|
||||
#include <cstring>
|
||||
#include <stdexcept>
|
||||
#include <Nazara/Renderer/Debug.hpp>
|
||||
|
||||
namespace
|
||||
{
|
||||
using LockRoutine = nzUInt8* (*)(nzBufferType type, nzBufferAccess access, unsigned int offset, unsigned int size);
|
||||
|
||||
nzUInt8* LockBuffer(nzBufferType type, nzBufferAccess access, unsigned int offset, unsigned int size)
|
||||
{
|
||||
NazaraUnused(size);
|
||||
|
||||
if (access == nzBufferAccess_DiscardAndWrite)
|
||||
{
|
||||
GLint bufSize;
|
||||
glGetBufferParameteriv(NzOpenGL::BufferTargetBinding[type], GL_BUFFER_SIZE, &bufSize);
|
||||
|
||||
GLint bufUsage;
|
||||
glGetBufferParameteriv(NzOpenGL::BufferTargetBinding[type], GL_BUFFER_USAGE, &bufUsage);
|
||||
|
||||
// On discard le buffer
|
||||
glBufferData(NzOpenGL::BufferTargetBinding[type], bufSize, nullptr, bufUsage);
|
||||
}
|
||||
|
||||
void* ptr = glMapBuffer(NzOpenGL::BufferTarget[type], NzOpenGL::BufferLock[access]);
|
||||
if (ptr)
|
||||
return reinterpret_cast<nzUInt8*>(ptr) + offset;
|
||||
else
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nzUInt8* LockBufferRange(nzBufferType type, nzBufferAccess access, unsigned int offset, unsigned int size)
|
||||
{
|
||||
return reinterpret_cast<nzUInt8*>(glMapBufferRange(NzOpenGL::BufferTarget[type], offset, size, NzOpenGL::BufferLockRange[access]));
|
||||
}
|
||||
|
||||
nzUInt8* LockBufferFirstRun(nzBufferType type, nzBufferAccess access, unsigned int offset, unsigned int size);
|
||||
|
||||
LockRoutine mapBuffer = LockBufferFirstRun;
|
||||
|
||||
nzUInt8* LockBufferFirstRun(nzBufferType type, nzBufferAccess access, unsigned int offset, unsigned int size)
|
||||
{
|
||||
if (glMapBufferRange)
|
||||
mapBuffer = LockBufferRange;
|
||||
else
|
||||
mapBuffer = LockBuffer;
|
||||
|
||||
return mapBuffer(type, access, offset, size);
|
||||
}
|
||||
}
|
||||
|
||||
NzHardwareBuffer::NzHardwareBuffer(NzBuffer* parent, nzBufferType type) :
|
||||
m_type(type),
|
||||
m_parent(parent)
|
||||
{
|
||||
}
|
||||
|
||||
NzHardwareBuffer::~NzHardwareBuffer()
|
||||
{
|
||||
}
|
||||
|
||||
void NzHardwareBuffer::Bind()
|
||||
{
|
||||
#ifdef NAZARA_DEBUG
|
||||
if (NzContext::GetCurrent() == nullptr)
|
||||
{
|
||||
NazaraError("No active context");
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
glBindBuffer(NzOpenGL::BufferTarget[m_type], m_buffer);
|
||||
}
|
||||
|
||||
bool NzHardwareBuffer::Create(unsigned int size, nzBufferUsage usage)
|
||||
{
|
||||
NzContext::EnsureContext();
|
||||
|
||||
m_buffer = 0;
|
||||
glGenBuffers(1, &m_buffer);
|
||||
|
||||
GLint previous;
|
||||
glGetIntegerv(NzOpenGL::BufferTargetBinding[m_type], &previous);
|
||||
|
||||
glBindBuffer(NzOpenGL::BufferTarget[m_type], m_buffer);
|
||||
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)
|
||||
glBindBuffer(NzOpenGL::BufferTarget[m_type], previous);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void NzHardwareBuffer::Destroy()
|
||||
{
|
||||
NzContext::EnsureContext();
|
||||
|
||||
glDeleteBuffers(1, &m_buffer);
|
||||
}
|
||||
|
||||
bool NzHardwareBuffer::Fill(const void* data, unsigned int offset, unsigned int size)
|
||||
{
|
||||
NzContext::EnsureContext();
|
||||
|
||||
GLuint previous;
|
||||
glGetIntegerv(NzOpenGL::BufferTargetBinding[m_type], reinterpret_cast<GLint*>(&previous));
|
||||
|
||||
if (previous != m_buffer)
|
||||
glBindBuffer(NzOpenGL::BufferTarget[m_type], 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/
|
||||
if (size < 32*1024)
|
||||
{
|
||||
// http://www.opengl.org/wiki/Vertex_Specification_Best_Practices
|
||||
if (size == m_parent->GetSize())
|
||||
glBufferData(NzOpenGL::BufferTarget[m_type], m_parent->GetSize(), nullptr, NzOpenGL::BufferUsage[m_parent->GetUsage()]); // Discard
|
||||
|
||||
glBufferSubData(NzOpenGL::BufferTarget[m_type], offset, size, data);
|
||||
}
|
||||
else
|
||||
{
|
||||
nzUInt8* ptr = mapBuffer(m_type, (size == m_parent->GetSize()) ? nzBufferAccess_DiscardAndWrite : nzBufferAccess_WriteOnly, offset, size);
|
||||
if (!ptr)
|
||||
{
|
||||
NazaraError("Failed to map buffer");
|
||||
return false;
|
||||
}
|
||||
|
||||
std::memcpy(ptr, data, size);
|
||||
|
||||
if (glUnmapBuffer(NzOpenGL::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(NzOpenGL::BufferTarget[m_type], m_parent->GetSize(), nullptr, NzOpenGL::BufferUsage[m_parent->GetStorage()]);
|
||||
|
||||
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(NzOpenGL::BufferTarget[m_type], previous);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void* NzHardwareBuffer::GetPointer()
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool NzHardwareBuffer::IsHardware() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
void* NzHardwareBuffer::Map(nzBufferAccess access, unsigned int offset, unsigned int size)
|
||||
{
|
||||
NzContext::EnsureContext();
|
||||
|
||||
// Pour ne pas perturber le rendu, on interfère pas avec le binding déjà présent
|
||||
GLuint previous;
|
||||
glGetIntegerv(NzOpenGL::BufferTargetBinding[m_type], reinterpret_cast<GLint*>(&previous));
|
||||
|
||||
if (previous != m_buffer)
|
||||
glBindBuffer(NzOpenGL::BufferTarget[m_type], m_buffer);
|
||||
|
||||
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)
|
||||
glBindBuffer(NzOpenGL::BufferTarget[m_type], previous);
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
bool NzHardwareBuffer::Unmap()
|
||||
{
|
||||
NzContext::EnsureContext();
|
||||
|
||||
GLuint previous;
|
||||
glGetIntegerv(NzOpenGL::BufferTargetBinding[m_type], reinterpret_cast<GLint*>(&previous));
|
||||
|
||||
if (previous != m_buffer)
|
||||
glBindBuffer(NzOpenGL::BufferTarget[m_type], m_buffer);
|
||||
|
||||
if (glUnmapBuffer(NzOpenGL::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(NzOpenGL::BufferTarget[m_type], m_parent->GetSize(), nullptr, NzOpenGL::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(NzOpenGL::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(NzOpenGL::BufferTarget[m_type], previous);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,102 +1,98 @@
|
|||
// 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/OcclusionQuery.hpp>
|
||||
#include <Nazara/Core/Error.hpp>
|
||||
#include <Nazara/Renderer/Config.hpp>
|
||||
#include <Nazara/Renderer/Context.hpp>
|
||||
#include <Nazara/Renderer/Renderer.hpp>
|
||||
#include <stdexcept>
|
||||
#include <Nazara/Renderer/Debug.hpp>
|
||||
|
||||
NzOcclusionQuery::NzOcclusionQuery() :
|
||||
m_id(0)
|
||||
{
|
||||
#if NAZARA_RENDERER_SAFE
|
||||
if (IsSupported())
|
||||
{
|
||||
#endif
|
||||
NzContext::EnsureContext();
|
||||
|
||||
glGenQueries(1, reinterpret_cast<GLuint*>(&m_id));
|
||||
#if NAZARA_RENDERER_SAFE
|
||||
}
|
||||
else
|
||||
{
|
||||
NazaraError("Occlusion queries not supported");
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef NAZARA_DEBUG
|
||||
if (!m_id)
|
||||
{
|
||||
NazaraError("Failed to create occlusion query");
|
||||
throw std::runtime_error("Constructor failed");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
NzOcclusionQuery::~NzOcclusionQuery()
|
||||
{
|
||||
if (m_id)
|
||||
{
|
||||
NzContext::EnsureContext();
|
||||
|
||||
GLuint query = static_cast<GLuint>(m_id);
|
||||
glDeleteQueries(1, &query);
|
||||
}
|
||||
}
|
||||
|
||||
void NzOcclusionQuery::Begin()
|
||||
{
|
||||
#ifdef NAZARA_DEBUG
|
||||
if (NzContext::GetCurrent() == nullptr)
|
||||
{
|
||||
NazaraError("No active context");
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
glBeginQuery(GL_SAMPLES_PASSED, m_id);
|
||||
}
|
||||
|
||||
void NzOcclusionQuery::End()
|
||||
{
|
||||
#ifdef NAZARA_DEBUG
|
||||
if (NzContext::GetCurrent() == nullptr)
|
||||
{
|
||||
NazaraError("No active context");
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
glEndQuery(GL_SAMPLES_PASSED);
|
||||
}
|
||||
|
||||
unsigned int NzOcclusionQuery::GetResult() const
|
||||
{
|
||||
NzContext::EnsureContext();
|
||||
|
||||
GLuint result;
|
||||
glGetQueryObjectuiv(m_id, GL_QUERY_RESULT, &result);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool NzOcclusionQuery::IsResultAvailable() const
|
||||
{
|
||||
NzContext::EnsureContext();
|
||||
|
||||
GLint available;
|
||||
glGetQueryObjectiv(m_id, GL_QUERY_RESULT_AVAILABLE, &available);
|
||||
|
||||
return available == GL_TRUE;
|
||||
}
|
||||
|
||||
bool NzOcclusionQuery::IsSupported()
|
||||
{
|
||||
return NzRenderer::HasCapability(nzRendererCap_OcclusionQuery);
|
||||
}
|
||||
// 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/OcclusionQuery.hpp>
|
||||
#include <Nazara/Core/Error.hpp>
|
||||
#include <Nazara/Renderer/Config.hpp>
|
||||
#include <Nazara/Renderer/Context.hpp>
|
||||
#include <Nazara/Renderer/Renderer.hpp>
|
||||
#include <stdexcept>
|
||||
#include <Nazara/Renderer/Debug.hpp>
|
||||
|
||||
NzOcclusionQuery::NzOcclusionQuery() :
|
||||
m_id(0)
|
||||
{
|
||||
if (IsSupported())
|
||||
{
|
||||
NzContext::EnsureContext();
|
||||
|
||||
glGenQueries(1, reinterpret_cast<GLuint*>(&m_id));
|
||||
}
|
||||
else
|
||||
{
|
||||
NazaraError("Occlusion queries not supported");
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef NAZARA_DEBUG
|
||||
if (!m_id)
|
||||
{
|
||||
NazaraError("Failed to create occlusion query");
|
||||
throw std::runtime_error("Constructor failed");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
NzOcclusionQuery::~NzOcclusionQuery()
|
||||
{
|
||||
if (m_id)
|
||||
{
|
||||
NzContext::EnsureContext();
|
||||
|
||||
GLuint query = static_cast<GLuint>(m_id);
|
||||
glDeleteQueries(1, &query);
|
||||
}
|
||||
}
|
||||
|
||||
void NzOcclusionQuery::Begin()
|
||||
{
|
||||
#ifdef NAZARA_DEBUG
|
||||
if (NzContext::GetCurrent() == nullptr)
|
||||
{
|
||||
NazaraError("No active context");
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
glBeginQuery(GL_SAMPLES_PASSED, m_id);
|
||||
}
|
||||
|
||||
void NzOcclusionQuery::End()
|
||||
{
|
||||
#ifdef NAZARA_DEBUG
|
||||
if (NzContext::GetCurrent() == nullptr)
|
||||
{
|
||||
NazaraError("No active context");
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
glEndQuery(GL_SAMPLES_PASSED);
|
||||
}
|
||||
|
||||
unsigned int NzOcclusionQuery::GetResult() const
|
||||
{
|
||||
NzContext::EnsureContext();
|
||||
|
||||
GLuint result;
|
||||
glGetQueryObjectuiv(m_id, GL_QUERY_RESULT, &result);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool NzOcclusionQuery::IsResultAvailable() const
|
||||
{
|
||||
NzContext::EnsureContext();
|
||||
|
||||
GLint available;
|
||||
glGetQueryObjectiv(m_id, GL_QUERY_RESULT_AVAILABLE, &available);
|
||||
|
||||
return available == GL_TRUE;
|
||||
}
|
||||
|
||||
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
|
||||
// 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/RenderWindow.hpp>
|
||||
#include <Nazara/Core/Error.hpp>
|
||||
#include <Nazara/Core/Thread.hpp>
|
||||
#include <Nazara/Renderer/Context.hpp>
|
||||
#include <Nazara/Renderer/Texture.hpp>
|
||||
#include <stdexcept>
|
||||
#include <Nazara/Renderer/Debug.hpp>
|
||||
|
||||
NzRenderWindow::NzRenderWindow(NzVideoMode mode, const NzString& title, nzUInt32 style, const NzContextParameters& parameters)
|
||||
{
|
||||
Create(mode, title, style, parameters);
|
||||
|
||||
#ifdef NAZARA_DEBUG
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraError("Failed to create render window");
|
||||
throw std::runtime_error("Constructor failed");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
NzRenderWindow::NzRenderWindow(NzWindowHandle handle, const NzContextParameters& parameters)
|
||||
{
|
||||
Create(handle, parameters);
|
||||
|
||||
#ifdef NAZARA_DEBUG
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraError("Failed to create render window");
|
||||
throw std::runtime_error("Constructor failed");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
NzRenderWindow::~NzRenderWindow()
|
||||
{
|
||||
// Nécessaire si NzWindow::Destroy est appelé par son destructeur
|
||||
OnWindowDestroying();
|
||||
}
|
||||
|
||||
bool NzRenderWindow::CopyToImage(NzImage* image)
|
||||
{
|
||||
#if NAZARA_RENDERER_SAFE
|
||||
if (!m_context)
|
||||
{
|
||||
NazaraError("Window has not been created");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!image)
|
||||
{
|
||||
NazaraError("Image must be valid");
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!m_context->SetActive(true))
|
||||
{
|
||||
NazaraError("Failed to activate context");
|
||||
return false;
|
||||
}
|
||||
|
||||
NzVector2ui size = GetSize();
|
||||
|
||||
if (!image->Create(nzImageType_2D, nzPixelFormat_RGBA8, size.x, size.y, 1, 1))
|
||||
{
|
||||
NazaraError("Failed to create image");
|
||||
return false;
|
||||
}
|
||||
|
||||
nzUInt8* pixels = image->GetPixels();
|
||||
glReadPixels(0, 0, size.x, size.y, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
|
||||
|
||||
image->FlipVertically();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool NzRenderWindow::CopyToTexture(NzTexture* texture)
|
||||
{
|
||||
#if NAZARA_RENDERER_SAFE
|
||||
if (!m_context)
|
||||
{
|
||||
NazaraError("Window has not been created");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!texture)
|
||||
{
|
||||
NazaraError("Texture must be valid");
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!m_context->SetActive(true))
|
||||
{
|
||||
NazaraError("Failed to activate context");
|
||||
return false;
|
||||
}
|
||||
|
||||
NzVector2ui size = GetSize();
|
||||
|
||||
if (!texture->Create(nzImageType_2D, nzPixelFormat_RGBA8, size.x, size.y, 1, 1, true))
|
||||
{
|
||||
NazaraError("Failed to create texture");
|
||||
return false;
|
||||
}
|
||||
|
||||
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, size.x, size.y);
|
||||
|
||||
texture->Unlock();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool NzRenderWindow::Create(NzVideoMode mode, const NzString& title, nzUInt32 style, const NzContextParameters& parameters)
|
||||
{
|
||||
m_parameters = parameters;
|
||||
return NzWindow::Create(mode, title, style);
|
||||
}
|
||||
|
||||
bool NzRenderWindow::Create(NzWindowHandle handle, const NzContextParameters& parameters)
|
||||
{
|
||||
m_parameters = parameters;
|
||||
return NzWindow::Create(handle);
|
||||
}
|
||||
|
||||
void NzRenderWindow::Display()
|
||||
{
|
||||
if (m_framerateLimit > 0)
|
||||
{
|
||||
int remainingTime = 1000/m_framerateLimit - m_clock.GetMilliseconds();
|
||||
if (remainingTime > 0)
|
||||
NzThread::Sleep(remainingTime);
|
||||
|
||||
m_clock.Restart();
|
||||
}
|
||||
|
||||
if (m_context && m_parameters.doubleBuffered)
|
||||
m_context->SwapBuffers();
|
||||
}
|
||||
|
||||
void NzRenderWindow::EnableVerticalSync(bool enabled)
|
||||
{
|
||||
if (m_context)
|
||||
{
|
||||
#if defined(NAZARA_PLATFORM_WINDOWS)
|
||||
if (!m_context->SetActive(true))
|
||||
{
|
||||
NazaraError("Failed to activate context");
|
||||
return;
|
||||
}
|
||||
|
||||
if (wglSwapInterval)
|
||||
wglSwapInterval(enabled ? 1 : 0);
|
||||
else
|
||||
#elif defined(NAZARA_PLATFORM_LINUX)
|
||||
if (!m_context->SetActive(true))
|
||||
{
|
||||
NazaraError("Failed to activate context");
|
||||
return;
|
||||
}
|
||||
|
||||
if (glXSwapInterval)
|
||||
glXSwapInterval(enabled ? 1 : 0);
|
||||
else
|
||||
#else
|
||||
#error Vertical Sync is not supported on this platform
|
||||
#endif
|
||||
NazaraError("Vertical Sync is not supported on this platform");
|
||||
}
|
||||
else
|
||||
NazaraError("No context");
|
||||
}
|
||||
|
||||
NzContextParameters NzRenderWindow::GetContextParameters() const
|
||||
{
|
||||
if (m_context)
|
||||
return m_context->GetParameters();
|
||||
else
|
||||
{
|
||||
NazaraError("Window not created/context not initialized");
|
||||
return NzContextParameters();
|
||||
}
|
||||
}
|
||||
|
||||
unsigned int NzRenderWindow::GetHeight() const
|
||||
{
|
||||
return NzWindow::GetHeight();
|
||||
}
|
||||
|
||||
NzRenderTargetParameters NzRenderWindow::GetParameters() const
|
||||
{
|
||||
if (m_context)
|
||||
{
|
||||
const NzContextParameters& parameters = m_context->GetParameters();
|
||||
return NzRenderTargetParameters(parameters.antialiasingLevel, parameters.depthBits, parameters.stencilBits);
|
||||
}
|
||||
else
|
||||
{
|
||||
NazaraError("Window not created/context not initialized");
|
||||
return NzRenderTargetParameters();
|
||||
}
|
||||
}
|
||||
|
||||
unsigned int NzRenderWindow::GetWidth() const
|
||||
{
|
||||
return NzWindow::GetWidth();
|
||||
}
|
||||
|
||||
bool NzRenderWindow::HasContext() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool NzRenderWindow::IsValid() const
|
||||
{
|
||||
return m_impl != nullptr && m_context != nullptr;
|
||||
}
|
||||
|
||||
void NzRenderWindow::SetFramerateLimit(unsigned int limit)
|
||||
{
|
||||
m_framerateLimit = limit;
|
||||
}
|
||||
|
||||
bool NzRenderWindow::Activate()
|
||||
{
|
||||
if (m_context->SetActive(true))
|
||||
{
|
||||
glDrawBuffer((m_parameters.doubleBuffered) ? GL_BACK : GL_FRONT);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
NazaraError("Failed to activate window's context");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void NzRenderWindow::OnWindowDestroying()
|
||||
{
|
||||
if (m_context)
|
||||
{
|
||||
delete m_context;
|
||||
m_context = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
bool NzRenderWindow::OnWindowCreated()
|
||||
{
|
||||
m_parameters.doubleBuffered = true;
|
||||
m_parameters.window = GetHandle();
|
||||
|
||||
m_context = new NzContext;
|
||||
if (!m_context->Create(m_parameters))
|
||||
{
|
||||
NazaraError("Failed not create context");
|
||||
delete m_context;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
EnableVerticalSync(false);
|
||||
|
||||
#if NAZARA_RENDERER_ACTIVATE_RENDERWINDOW_ON_CREATION
|
||||
if (!SetActive(true)) // Les fenêtres s'activent à la création
|
||||
NazaraWarning("Failed to activate window");
|
||||
#endif
|
||||
|
||||
m_clock.Restart();
|
||||
|
||||
return true;
|
||||
}
|
||||
// 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/RenderWindow.hpp>
|
||||
#include <Nazara/Core/Error.hpp>
|
||||
#include <Nazara/Core/Thread.hpp>
|
||||
#include <Nazara/Renderer/Context.hpp>
|
||||
#include <Nazara/Renderer/Texture.hpp>
|
||||
#include <stdexcept>
|
||||
#include <Nazara/Renderer/Debug.hpp>
|
||||
|
||||
NzRenderWindow::NzRenderWindow(NzVideoMode mode, const NzString& title, nzUInt32 style, const NzContextParameters& parameters)
|
||||
{
|
||||
Create(mode, title, style, parameters);
|
||||
|
||||
#ifdef NAZARA_DEBUG
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraError("Failed to create render window");
|
||||
throw std::runtime_error("Constructor failed");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
NzRenderWindow::NzRenderWindow(NzWindowHandle handle, const NzContextParameters& parameters)
|
||||
{
|
||||
Create(handle, parameters);
|
||||
|
||||
#ifdef NAZARA_DEBUG
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraError("Failed to create render window");
|
||||
throw std::runtime_error("Constructor failed");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
NzRenderWindow::~NzRenderWindow()
|
||||
{
|
||||
// Nécessaire si NzWindow::Destroy est appelé par son destructeur
|
||||
OnWindowDestroy();
|
||||
}
|
||||
|
||||
bool NzRenderWindow::CopyToImage(NzImage* image)
|
||||
{
|
||||
#if NAZARA_RENDERER_SAFE
|
||||
if (!m_context)
|
||||
{
|
||||
NazaraError("Window has not been created");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!image)
|
||||
{
|
||||
NazaraError("Image must be valid");
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!m_context->SetActive(true))
|
||||
{
|
||||
NazaraError("Failed to activate context");
|
||||
return false;
|
||||
}
|
||||
|
||||
NzVector2ui size = GetSize();
|
||||
|
||||
if (!image->Create(nzImageType_2D, nzPixelFormat_RGBA8, size.x, size.y, 1, 1))
|
||||
{
|
||||
NazaraError("Failed to create image");
|
||||
return false;
|
||||
}
|
||||
|
||||
nzUInt8* pixels = image->GetPixels();
|
||||
glReadPixels(0, 0, size.x, size.y, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
|
||||
|
||||
image->FlipVertically();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool NzRenderWindow::CopyToTexture(NzTexture* texture)
|
||||
{
|
||||
#if NAZARA_RENDERER_SAFE
|
||||
if (!m_context)
|
||||
{
|
||||
NazaraError("Window has not been created");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!texture)
|
||||
{
|
||||
NazaraError("Texture must be valid");
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!m_context->SetActive(true))
|
||||
{
|
||||
NazaraError("Failed to activate context");
|
||||
return false;
|
||||
}
|
||||
|
||||
NzVector2ui size = GetSize();
|
||||
|
||||
if (!texture->Create(nzImageType_2D, nzPixelFormat_RGBA8, size.x, size.y, 1, 1, true))
|
||||
{
|
||||
NazaraError("Failed to create texture");
|
||||
return false;
|
||||
}
|
||||
|
||||
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, size.x, size.y);
|
||||
|
||||
texture->Unlock();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool NzRenderWindow::Create(NzVideoMode mode, const NzString& title, nzUInt32 style, const NzContextParameters& parameters)
|
||||
{
|
||||
m_parameters = parameters;
|
||||
return NzWindow::Create(mode, title, style);
|
||||
}
|
||||
|
||||
bool NzRenderWindow::Create(NzWindowHandle handle, const NzContextParameters& parameters)
|
||||
{
|
||||
m_parameters = parameters;
|
||||
return NzWindow::Create(handle);
|
||||
}
|
||||
|
||||
void NzRenderWindow::Display()
|
||||
{
|
||||
if (m_framerateLimit > 0)
|
||||
{
|
||||
int remainingTime = 1000/m_framerateLimit - m_clock.GetMilliseconds();
|
||||
if (remainingTime > 0)
|
||||
NzThread::Sleep(remainingTime);
|
||||
|
||||
m_clock.Restart();
|
||||
}
|
||||
|
||||
if (m_context && m_parameters.doubleBuffered)
|
||||
m_context->SwapBuffers();
|
||||
}
|
||||
|
||||
void NzRenderWindow::EnableVerticalSync(bool enabled)
|
||||
{
|
||||
if (m_context)
|
||||
{
|
||||
#if defined(NAZARA_PLATFORM_WINDOWS)
|
||||
if (!m_context->SetActive(true))
|
||||
{
|
||||
NazaraError("Failed to activate context");
|
||||
return;
|
||||
}
|
||||
|
||||
if (wglSwapInterval)
|
||||
wglSwapInterval(enabled ? 1 : 0);
|
||||
else
|
||||
#elif defined(NAZARA_PLATFORM_LINUX)
|
||||
if (!m_context->SetActive(true))
|
||||
{
|
||||
NazaraError("Failed to activate context");
|
||||
return;
|
||||
}
|
||||
|
||||
if (glXSwapInterval)
|
||||
glXSwapInterval(enabled ? 1 : 0);
|
||||
else
|
||||
#else
|
||||
#error Vertical Sync is not supported on this platform
|
||||
#endif
|
||||
NazaraError("Vertical Sync is not supported on this platform");
|
||||
}
|
||||
else
|
||||
NazaraError("No context");
|
||||
}
|
||||
|
||||
unsigned int NzRenderWindow::GetHeight() const
|
||||
{
|
||||
return NzWindow::GetHeight();
|
||||
}
|
||||
|
||||
NzRenderTargetParameters NzRenderWindow::GetParameters() const
|
||||
{
|
||||
if (m_context)
|
||||
{
|
||||
const NzContextParameters& parameters = m_context->GetParameters();
|
||||
return NzRenderTargetParameters(parameters.antialiasingLevel, parameters.depthBits, parameters.stencilBits);
|
||||
}
|
||||
else
|
||||
{
|
||||
NazaraError("Window not created/context not initialized");
|
||||
return NzRenderTargetParameters();
|
||||
}
|
||||
}
|
||||
|
||||
unsigned int NzRenderWindow::GetWidth() const
|
||||
{
|
||||
return NzWindow::GetWidth();
|
||||
}
|
||||
|
||||
bool NzRenderWindow::IsRenderable() const
|
||||
{
|
||||
return m_impl != nullptr; // Si m_impl est valide, alors m_context l'est aussi
|
||||
}
|
||||
|
||||
void NzRenderWindow::SetFramerateLimit(unsigned int limit)
|
||||
{
|
||||
m_framerateLimit = limit;
|
||||
}
|
||||
|
||||
NzContextParameters NzRenderWindow::GetContextParameters() const
|
||||
{
|
||||
if (m_context)
|
||||
return m_context->GetParameters();
|
||||
else
|
||||
{
|
||||
NazaraError("Window not created/context not initialized");
|
||||
return NzContextParameters();
|
||||
}
|
||||
}
|
||||
|
||||
bool NzRenderWindow::HasContext() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool NzRenderWindow::Activate()
|
||||
{
|
||||
if (m_context->SetActive(true))
|
||||
{
|
||||
glDrawBuffer((m_parameters.doubleBuffered) ? GL_BACK : GL_FRONT);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
NazaraError("Failed to activate window's context");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool NzRenderWindow::OnWindowCreated()
|
||||
{
|
||||
m_parameters.doubleBuffered = true;
|
||||
m_parameters.window = GetHandle();
|
||||
|
||||
m_context = new NzContext;
|
||||
if (!m_context->Create(m_parameters))
|
||||
{
|
||||
NazaraError("Failed not create context");
|
||||
delete m_context;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
EnableVerticalSync(false);
|
||||
|
||||
if (!SetActive(true)) // Les fenêtres s'activent à la création
|
||||
NazaraWarning("Failed to activate window");
|
||||
|
||||
m_clock.Restart();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void NzRenderWindow::OnWindowDestroy()
|
||||
{
|
||||
if (m_context)
|
||||
{
|
||||
delete m_context;
|
||||
m_context = nullptr;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
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
|
||||
// This file is part of the "Nazara Engine - Renderer module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
// Code inspiré de NeHe (Lesson1) et de la SFML par Laurent Gomila
|
||||
|
||||
#include <Nazara/Renderer/OpenGL.hpp>
|
||||
#include <Nazara/Renderer/Win32/ContextImpl.hpp>
|
||||
#include <Nazara/Core/Error.hpp>
|
||||
#include <Nazara/Core/LockGuard.hpp>
|
||||
#include <Nazara/Core/Mutex.hpp>
|
||||
#include <Nazara/Renderer/Context.hpp>
|
||||
#include <cstring>
|
||||
#include <Nazara/Renderer/Debug.hpp>
|
||||
|
||||
NzContextImpl::NzContextImpl()
|
||||
{
|
||||
}
|
||||
|
||||
bool NzContextImpl::Activate()
|
||||
{
|
||||
return wglMakeCurrent(m_deviceContext, m_context);
|
||||
}
|
||||
|
||||
bool NzContextImpl::Create(NzContextParameters& parameters)
|
||||
{
|
||||
if (parameters.window)
|
||||
{
|
||||
m_window = static_cast<HWND>(parameters.window);
|
||||
m_ownsWindow = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_window = CreateWindowA("STATIC", nullptr, WS_DISABLED | WS_POPUP, 0, 0, 1, 1, nullptr, nullptr, GetModuleHandle(nullptr), nullptr);
|
||||
if (!m_window)
|
||||
{
|
||||
NazaraError("Failed to create window");
|
||||
return false;
|
||||
}
|
||||
|
||||
ShowWindow(m_window, SW_HIDE);
|
||||
m_ownsWindow = true;
|
||||
}
|
||||
|
||||
m_deviceContext = GetDC(m_window);
|
||||
if (!m_deviceContext)
|
||||
{
|
||||
NazaraError("Failed to get device context");
|
||||
Destroy();
|
||||
return false;
|
||||
}
|
||||
|
||||
int pixelFormat = 0;
|
||||
if (parameters.antialiasingLevel > 0)
|
||||
{
|
||||
if (wglChoosePixelFormat)
|
||||
{
|
||||
bool valid;
|
||||
UINT numFormats;
|
||||
|
||||
int attributes[] = {
|
||||
WGL_DRAW_TO_WINDOW_ARB, GL_TRUE,
|
||||
WGL_SUPPORT_OPENGL_ARB, GL_TRUE,
|
||||
WGL_ACCELERATION_ARB, WGL_FULL_ACCELERATION_ARB,
|
||||
WGL_COLOR_BITS_ARB, (parameters.bitsPerPixel == 32) ? 24 : parameters.bitsPerPixel,
|
||||
WGL_ALPHA_BITS_ARB, (parameters.bitsPerPixel == 32) ? 8 : 0,
|
||||
WGL_DEPTH_BITS_ARB, parameters.depthBits,
|
||||
WGL_STENCIL_BITS_ARB, parameters.stencilBits,
|
||||
WGL_DOUBLE_BUFFER_ARB, (parameters.doubleBuffered) ? GL_TRUE : GL_FALSE,
|
||||
WGL_SAMPLE_BUFFERS_ARB, GL_TRUE,
|
||||
WGL_SAMPLES_ARB, parameters.antialiasingLevel,
|
||||
0, 0
|
||||
};
|
||||
|
||||
do
|
||||
{
|
||||
valid = wglChoosePixelFormat(m_deviceContext, attributes, nullptr, 1, &pixelFormat, &numFormats);
|
||||
}
|
||||
while ((!valid || numFormats == 0) && --attributes[19] > 0);
|
||||
|
||||
if (!valid)
|
||||
{
|
||||
NazaraWarning("Could not find a format matching requirements, disabling antialiasing...");
|
||||
pixelFormat = 0;
|
||||
}
|
||||
|
||||
parameters.antialiasingLevel = attributes[19];
|
||||
}
|
||||
else
|
||||
{
|
||||
NazaraWarning("Antialiasing is not supported");
|
||||
parameters.antialiasingLevel = 0;
|
||||
}
|
||||
}
|
||||
|
||||
PIXELFORMATDESCRIPTOR descriptor;
|
||||
ZeroMemory(&descriptor, sizeof(PIXELFORMATDESCRIPTOR));
|
||||
descriptor.nSize = sizeof(PIXELFORMATDESCRIPTOR);
|
||||
descriptor.nVersion = 1;
|
||||
|
||||
if (pixelFormat == 0)
|
||||
{
|
||||
descriptor.cColorBits = parameters.bitsPerPixel;
|
||||
descriptor.cDepthBits = parameters.depthBits;
|
||||
descriptor.cStencilBits = parameters.stencilBits;
|
||||
descriptor.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL;
|
||||
descriptor.iPixelType = PFD_TYPE_RGBA;
|
||||
|
||||
if (parameters.bitsPerPixel == 32)
|
||||
descriptor.cAlphaBits = 8;
|
||||
|
||||
if (parameters.doubleBuffered)
|
||||
descriptor.dwFlags |= PFD_DOUBLEBUFFER;
|
||||
|
||||
pixelFormat = ChoosePixelFormat(m_deviceContext, &descriptor);
|
||||
if (pixelFormat == 0)
|
||||
{
|
||||
NazaraError("Failed to choose pixel format");
|
||||
Destroy();
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!SetPixelFormat(m_deviceContext, pixelFormat, &descriptor))
|
||||
{
|
||||
NazaraError("Failed to set pixel format");
|
||||
Destroy();
|
||||
return false;
|
||||
}
|
||||
|
||||
// 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)
|
||||
{
|
||||
parameters.bitsPerPixel = descriptor.cColorBits + descriptor.cAlphaBits;
|
||||
parameters.depthBits = descriptor.cDepthBits;
|
||||
parameters.stencilBits = descriptor.cDepthBits;
|
||||
}
|
||||
else
|
||||
NazaraWarning("Failed to get context's parameters");
|
||||
|
||||
HGLRC shareContext = (parameters.shared) ? static_cast<NzContextImpl*>(parameters.shareContext->m_impl)->m_context : nullptr;
|
||||
|
||||
m_context = nullptr;
|
||||
if (wglCreateContextAttribs)
|
||||
{
|
||||
int attributes[4*2+1];
|
||||
int* attrib = attributes;
|
||||
|
||||
*attrib++ = WGL_CONTEXT_MAJOR_VERSION_ARB;
|
||||
*attrib++ = parameters.majorVersion;
|
||||
|
||||
*attrib++ = WGL_CONTEXT_MINOR_VERSION_ARB;
|
||||
*attrib++ = parameters.minorVersion;
|
||||
|
||||
int flags = 0;
|
||||
|
||||
if (parameters.majorVersion >= 3)
|
||||
{
|
||||
*attrib++ = WGL_CONTEXT_PROFILE_MASK_ARB;
|
||||
if (parameters.compatibilityProfile)
|
||||
*attrib++ = WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB;
|
||||
else
|
||||
{
|
||||
*attrib++ = WGL_CONTEXT_CORE_PROFILE_BIT_ARB;
|
||||
|
||||
flags |= WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB;
|
||||
}
|
||||
}
|
||||
|
||||
if (parameters.debugMode)
|
||||
flags |= WGL_CONTEXT_DEBUG_BIT_ARB;
|
||||
|
||||
if (flags)
|
||||
{
|
||||
*attrib++ = WGL_CONTEXT_FLAGS_ARB;
|
||||
*attrib++ = flags;
|
||||
}
|
||||
|
||||
*attrib++ = 0;
|
||||
|
||||
m_context = wglCreateContextAttribs(m_deviceContext, shareContext, attributes);
|
||||
}
|
||||
|
||||
if (!m_context)
|
||||
{
|
||||
m_context = wglCreateContext(m_deviceContext);
|
||||
|
||||
if (shareContext)
|
||||
{
|
||||
// wglShareLists n'est pas thread-safe (source: SFML)
|
||||
static NzMutex mutex;
|
||||
NzLockGuard lock(mutex);
|
||||
|
||||
if (!wglShareLists(shareContext, m_context))
|
||||
NazaraWarning("Failed to share the context: " + NzGetLastSystemError());
|
||||
}
|
||||
}
|
||||
|
||||
if (!m_context)
|
||||
{
|
||||
NazaraError("Failed to create context");
|
||||
Destroy();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void NzContextImpl::Destroy()
|
||||
{
|
||||
if (m_context)
|
||||
wglDeleteContext(m_context);
|
||||
|
||||
if (m_deviceContext)
|
||||
ReleaseDC(m_window, m_deviceContext);
|
||||
|
||||
if (m_ownsWindow)
|
||||
DestroyWindow(m_window);
|
||||
}
|
||||
|
||||
void NzContextImpl::SwapBuffers()
|
||||
{
|
||||
::SwapBuffers(m_deviceContext);
|
||||
}
|
||||
|
||||
bool NzContextImpl::Desactivate()
|
||||
{
|
||||
return wglMakeCurrent(nullptr, nullptr);
|
||||
}
|
||||
|
||||
// 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
|
||||
|
||||
// Code inspiré de NeHe (Lesson1) et de la SFML par Laurent Gomila
|
||||
|
||||
#include <Nazara/Renderer/OpenGL.hpp>
|
||||
#include <Nazara/Renderer/Win32/ContextImpl.hpp>
|
||||
#include <Nazara/Core/Error.hpp>
|
||||
#include <Nazara/Core/LockGuard.hpp>
|
||||
#include <Nazara/Core/Mutex.hpp>
|
||||
#include <Nazara/Renderer/Context.hpp>
|
||||
#include <cstring>
|
||||
#include <Nazara/Renderer/Debug.hpp>
|
||||
|
||||
NzContextImpl::NzContextImpl()
|
||||
{
|
||||
}
|
||||
|
||||
bool NzContextImpl::Activate()
|
||||
{
|
||||
return wglMakeCurrent(m_deviceContext, m_context);
|
||||
}
|
||||
|
||||
bool NzContextImpl::Create(NzContextParameters& parameters)
|
||||
{
|
||||
if (parameters.window)
|
||||
{
|
||||
m_window = static_cast<HWND>(parameters.window);
|
||||
m_ownsWindow = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_window = CreateWindowA("STATIC", nullptr, WS_DISABLED | WS_POPUP, 0, 0, 1, 1, nullptr, nullptr, GetModuleHandle(nullptr), nullptr);
|
||||
if (!m_window)
|
||||
{
|
||||
NazaraError("Failed to create window");
|
||||
return false;
|
||||
}
|
||||
|
||||
ShowWindow(m_window, SW_HIDE);
|
||||
m_ownsWindow = true;
|
||||
}
|
||||
|
||||
m_deviceContext = GetDC(m_window);
|
||||
if (!m_deviceContext)
|
||||
{
|
||||
NazaraError("Failed to get device context");
|
||||
Destroy();
|
||||
return false;
|
||||
}
|
||||
|
||||
int pixelFormat = 0;
|
||||
if (parameters.antialiasingLevel > 0)
|
||||
{
|
||||
if (wglChoosePixelFormat)
|
||||
{
|
||||
bool valid;
|
||||
UINT numFormats;
|
||||
|
||||
int attributes[] = {
|
||||
WGL_DRAW_TO_WINDOW_ARB, GL_TRUE,
|
||||
WGL_SUPPORT_OPENGL_ARB, GL_TRUE,
|
||||
WGL_ACCELERATION_ARB, WGL_FULL_ACCELERATION_ARB,
|
||||
WGL_COLOR_BITS_ARB, (parameters.bitsPerPixel == 32) ? 24 : parameters.bitsPerPixel,
|
||||
WGL_ALPHA_BITS_ARB, (parameters.bitsPerPixel == 32) ? 8 : 0,
|
||||
WGL_DEPTH_BITS_ARB, parameters.depthBits,
|
||||
WGL_STENCIL_BITS_ARB, parameters.stencilBits,
|
||||
WGL_DOUBLE_BUFFER_ARB, (parameters.doubleBuffered) ? GL_TRUE : GL_FALSE,
|
||||
WGL_SAMPLE_BUFFERS_ARB, GL_TRUE,
|
||||
WGL_SAMPLES_ARB, parameters.antialiasingLevel,
|
||||
0, 0
|
||||
};
|
||||
|
||||
do
|
||||
{
|
||||
valid = wglChoosePixelFormat(m_deviceContext, attributes, nullptr, 1, &pixelFormat, &numFormats);
|
||||
}
|
||||
while ((!valid || numFormats == 0) && --attributes[19] > 0);
|
||||
|
||||
if (!valid)
|
||||
{
|
||||
NazaraWarning("Could not find a format matching requirements, disabling antialiasing...");
|
||||
pixelFormat = 0;
|
||||
}
|
||||
|
||||
parameters.antialiasingLevel = attributes[19];
|
||||
}
|
||||
else
|
||||
{
|
||||
NazaraWarning("Antialiasing is not supported");
|
||||
parameters.antialiasingLevel = 0;
|
||||
}
|
||||
}
|
||||
|
||||
PIXELFORMATDESCRIPTOR descriptor;
|
||||
ZeroMemory(&descriptor, sizeof(PIXELFORMATDESCRIPTOR));
|
||||
descriptor.nSize = sizeof(PIXELFORMATDESCRIPTOR);
|
||||
descriptor.nVersion = 1;
|
||||
|
||||
if (pixelFormat == 0)
|
||||
{
|
||||
descriptor.cColorBits = parameters.bitsPerPixel;
|
||||
descriptor.cDepthBits = parameters.depthBits;
|
||||
descriptor.cStencilBits = parameters.stencilBits;
|
||||
descriptor.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL;
|
||||
descriptor.iPixelType = PFD_TYPE_RGBA;
|
||||
|
||||
if (parameters.bitsPerPixel == 32)
|
||||
descriptor.cAlphaBits = 8;
|
||||
|
||||
if (parameters.doubleBuffered)
|
||||
descriptor.dwFlags |= PFD_DOUBLEBUFFER;
|
||||
|
||||
pixelFormat = ChoosePixelFormat(m_deviceContext, &descriptor);
|
||||
if (pixelFormat == 0)
|
||||
{
|
||||
NazaraError("Failed to choose pixel format");
|
||||
Destroy();
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!SetPixelFormat(m_deviceContext, pixelFormat, &descriptor))
|
||||
{
|
||||
NazaraError("Failed to set pixel format");
|
||||
Destroy();
|
||||
return false;
|
||||
}
|
||||
|
||||
// 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)
|
||||
{
|
||||
parameters.bitsPerPixel = descriptor.cColorBits + descriptor.cAlphaBits;
|
||||
parameters.depthBits = descriptor.cDepthBits;
|
||||
parameters.stencilBits = descriptor.cDepthBits;
|
||||
}
|
||||
else
|
||||
NazaraWarning("Failed to get context's parameters");
|
||||
|
||||
HGLRC shareContext = (parameters.shared) ? static_cast<NzContextImpl*>(parameters.shareContext->m_impl)->m_context : nullptr;
|
||||
|
||||
m_context = nullptr;
|
||||
if (wglCreateContextAttribs)
|
||||
{
|
||||
int attributes[4*2+1];
|
||||
int* attrib = attributes;
|
||||
|
||||
*attrib++ = WGL_CONTEXT_MAJOR_VERSION_ARB;
|
||||
*attrib++ = parameters.majorVersion;
|
||||
|
||||
*attrib++ = WGL_CONTEXT_MINOR_VERSION_ARB;
|
||||
*attrib++ = parameters.minorVersion;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
if (parameters.debugMode)
|
||||
{
|
||||
*attrib++ = WGL_CONTEXT_FLAGS_ARB;
|
||||
*attrib++ = WGL_CONTEXT_DEBUG_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
|
||||
}
|
||||
|
||||
*attrib++ = 0;
|
||||
|
||||
m_context = wglCreateContextAttribs(m_deviceContext, shareContext, attributes);
|
||||
}
|
||||
|
||||
if (!m_context)
|
||||
{
|
||||
m_context = wglCreateContext(m_deviceContext);
|
||||
|
||||
if (shareContext)
|
||||
{
|
||||
// wglShareLists n'est pas thread-safe (source: SFML)
|
||||
static NzMutex mutex;
|
||||
NzLockGuard lock(mutex);
|
||||
|
||||
if (!wglShareLists(shareContext, m_context))
|
||||
NazaraWarning("Failed to share the context: " + NzGetLastSystemError());
|
||||
}
|
||||
}
|
||||
|
||||
if (!m_context)
|
||||
{
|
||||
NazaraError("Failed to create context");
|
||||
Destroy();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void NzContextImpl::Destroy()
|
||||
{
|
||||
if (m_context)
|
||||
{
|
||||
if (wglGetCurrentContext() == m_context)
|
||||
wglMakeCurrent(nullptr, nullptr);
|
||||
|
||||
wglDeleteContext(m_context);
|
||||
m_context = nullptr;
|
||||
}
|
||||
|
||||
if (m_deviceContext)
|
||||
{
|
||||
ReleaseDC(m_window, m_deviceContext);
|
||||
m_deviceContext = nullptr;
|
||||
}
|
||||
|
||||
if (m_ownsWindow)
|
||||
{
|
||||
DestroyWindow(m_window);
|
||||
m_window = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void NzContextImpl::SwapBuffers()
|
||||
{
|
||||
::SwapBuffers(m_deviceContext);
|
||||
}
|
||||
|
||||
bool NzContextImpl::Desactivate()
|
||||
{
|
||||
return wglMakeCurrent(nullptr, nullptr);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,317 +1,342 @@
|
|||
// Copyright (C) 2012 Jérôme Leclercq
|
||||
// This file is part of the "Nazara Engine - Utility module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#include <Nazara/Utility/Animation.hpp>
|
||||
#include <Nazara/Core/Error.hpp>
|
||||
#include <Nazara/Utility/Config.hpp>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include <Nazara/Utility/Debug.hpp>
|
||||
|
||||
struct NzAnimationImpl
|
||||
{
|
||||
std::map<NzString, unsigned int> sequenceMap;
|
||||
std::vector<NzSequence> sequences;
|
||||
nzAnimationType type;
|
||||
unsigned int frameCount;
|
||||
};
|
||||
|
||||
bool NzAnimationParams::IsValid() const
|
||||
{
|
||||
if (startFrame > endFrame)
|
||||
{
|
||||
NazaraError("Start frame must be lower than end frame");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
NzAnimation::~NzAnimation()
|
||||
{
|
||||
Destroy();
|
||||
}
|
||||
|
||||
unsigned int NzAnimation::AddSequence(const NzSequence& sequence)
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraError("Animation not created");
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
unsigned int index = m_impl->sequences.size();
|
||||
|
||||
if (!sequence.name.IsEmpty())
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
auto it = m_impl->sequenceMap.find(sequence.name);
|
||||
if (it != m_impl->sequenceMap.end())
|
||||
{
|
||||
NazaraError("Sequence name \"" + sequence.name + "\" is already used");
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
m_impl->sequenceMap[sequence.name] = index;
|
||||
}
|
||||
|
||||
m_impl->sequences.push_back(sequence);
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
bool NzAnimation::Create(nzAnimationType type, unsigned int frameCount)
|
||||
{
|
||||
Destroy();
|
||||
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (type == nzAnimationType_Static)
|
||||
{
|
||||
NazaraError("Invalid type");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (frameCount == 0)
|
||||
{
|
||||
NazaraError("Frame count must be over zero");
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
m_impl = new NzAnimationImpl;
|
||||
m_impl->frameCount = frameCount;
|
||||
m_impl->type = type;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void NzAnimation::Destroy()
|
||||
{
|
||||
if (m_impl)
|
||||
{
|
||||
delete m_impl;
|
||||
m_impl = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned int NzAnimation::GetFrameCount() const
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraError("Animation not created");
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
return m_impl->frameCount;
|
||||
}
|
||||
|
||||
NzSequence* NzAnimation::GetSequence(const NzString& sequenceName)
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraError("Animation not created");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto it = m_impl->sequenceMap.find(sequenceName);
|
||||
if (it == m_impl->sequenceMap.end())
|
||||
{
|
||||
NazaraError("Sequence not found");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return &m_impl->sequences[it->second];
|
||||
#else
|
||||
return &m_impl->sequences[m_impl->sequenceMap[sequenceName]];
|
||||
#endif
|
||||
}
|
||||
|
||||
NzSequence* NzAnimation::GetSequence(unsigned int index)
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraError("Animation not created");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (index >= m_impl->sequences.size())
|
||||
{
|
||||
NazaraError("Sequence index out of range (" + NzString::Number(index) + " >= " + NzString::Number(m_impl->sequences.size()) + ')');
|
||||
return nullptr;
|
||||
}
|
||||
#endif
|
||||
|
||||
return &m_impl->sequences[index];
|
||||
}
|
||||
|
||||
const NzSequence* NzAnimation::GetSequence(const NzString& sequenceName) const
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraError("Animation not created");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto it = m_impl->sequenceMap.find(sequenceName);
|
||||
if (it == m_impl->sequenceMap.end())
|
||||
{
|
||||
NazaraError("Sequence not found");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return &m_impl->sequences[it->second];
|
||||
#else
|
||||
return &m_impl->sequences[m_impl->sequenceMap[sequenceName]];
|
||||
#endif
|
||||
}
|
||||
|
||||
const NzSequence* NzAnimation::GetSequence(unsigned int index) const
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraError("Animation not created");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (index >= m_impl->sequences.size())
|
||||
{
|
||||
NazaraError("Sequence index out of range (" + NzString::Number(index) + " >= " + NzString::Number(m_impl->sequences.size()) + ')');
|
||||
return nullptr;
|
||||
}
|
||||
#endif
|
||||
|
||||
return &m_impl->sequences[index];
|
||||
}
|
||||
|
||||
unsigned int NzAnimation::GetSequenceCount() const
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraError("Animation not created");
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
return m_impl->sequences.size();
|
||||
}
|
||||
|
||||
nzAnimationType NzAnimation::GetType() const
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraError("Animation not created");
|
||||
return nzAnimationType_Static; // Ce qui est une valeur invalide pour NzAnimation
|
||||
}
|
||||
#endif
|
||||
|
||||
return m_impl->type;
|
||||
}
|
||||
|
||||
bool NzAnimation::HasSequence(const NzString& sequenceName) const
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraError("Animation not created");
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
return m_impl->sequenceMap.find(sequenceName) != m_impl->sequenceMap.end();
|
||||
}
|
||||
|
||||
bool NzAnimation::HasSequence(unsigned int index) const
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraError("Animation not created");
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
return index >= m_impl->sequences.size();
|
||||
}
|
||||
|
||||
bool NzAnimation::IsValid() const
|
||||
{
|
||||
return m_impl != nullptr;
|
||||
}
|
||||
|
||||
bool NzAnimation::LoadFromFile(const NzString& filePath, const NzAnimationParams& params)
|
||||
{
|
||||
return NzAnimationLoader::LoadFromFile(this, filePath, params);
|
||||
}
|
||||
|
||||
bool NzAnimation::LoadFromMemory(const void* data, std::size_t size, const NzAnimationParams& params)
|
||||
{
|
||||
return NzAnimationLoader::LoadFromMemory(this, data, size, params);
|
||||
}
|
||||
|
||||
bool NzAnimation::LoadFromStream(NzInputStream& stream, const NzAnimationParams& params)
|
||||
{
|
||||
return NzAnimationLoader::LoadFromStream(this, stream, params);
|
||||
}
|
||||
|
||||
void NzAnimation::RemoveSequence(const NzString& identifier)
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraError("Animation not created");
|
||||
return;
|
||||
}
|
||||
|
||||
auto it = m_impl->sequenceMap.find(identifier);
|
||||
if (it == m_impl->sequenceMap.end())
|
||||
{
|
||||
NazaraError("SubMesh not found");
|
||||
return;
|
||||
}
|
||||
|
||||
unsigned int index = it->second;
|
||||
#else
|
||||
unsigned int index = m_impl->sequenceMap[identifier];
|
||||
#endif
|
||||
|
||||
auto it2 = m_impl->sequences.begin();
|
||||
std::advance(it2, index);
|
||||
|
||||
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;
|
||||
// Copyright (C) 2012 Jérôme Leclercq
|
||||
// This file is part of the "Nazara Engine - Utility module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#include <Nazara/Utility/Animation.hpp>
|
||||
#include <Nazara/Core/Error.hpp>
|
||||
#include <Nazara/Utility/Config.hpp>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include <Nazara/Utility/Debug.hpp>
|
||||
|
||||
struct NzAnimationImpl
|
||||
{
|
||||
std::map<NzString, unsigned int> sequenceMap;
|
||||
std::vector<NzSequence> sequences;
|
||||
nzAnimationType type;
|
||||
unsigned int frameCount;
|
||||
};
|
||||
|
||||
bool NzAnimationParams::IsValid() const
|
||||
{
|
||||
if (startFrame > endFrame)
|
||||
{
|
||||
NazaraError("Start frame must be lower than end frame");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
NzAnimation::~NzAnimation()
|
||||
{
|
||||
Destroy();
|
||||
}
|
||||
|
||||
bool NzAnimation::AddSequence(const NzSequence& sequence)
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraError("Animation not created");
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
unsigned int index = m_impl->sequences.size();
|
||||
|
||||
if (!sequence.name.IsEmpty())
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
auto it = m_impl->sequenceMap.find(sequence.name);
|
||||
if (it != m_impl->sequenceMap.end())
|
||||
{
|
||||
NazaraError("Sequence name \"" + sequence.name + "\" is already used");
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
m_impl->sequenceMap[sequence.name] = index;
|
||||
}
|
||||
|
||||
m_impl->sequences.push_back(sequence);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool NzAnimation::Create(nzAnimationType type, unsigned int frameCount)
|
||||
{
|
||||
Destroy();
|
||||
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (type == nzAnimationType_Static)
|
||||
{
|
||||
NazaraError("Invalid type");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (frameCount == 0)
|
||||
{
|
||||
NazaraError("Frame count must be over zero");
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
m_impl = new NzAnimationImpl;
|
||||
m_impl->frameCount = frameCount;
|
||||
m_impl->type = type;
|
||||
|
||||
NotifyCreated();
|
||||
return true;
|
||||
}
|
||||
|
||||
void NzAnimation::Destroy()
|
||||
{
|
||||
if (m_impl)
|
||||
{
|
||||
NotifyDestroy();
|
||||
|
||||
delete m_impl;
|
||||
m_impl = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned int NzAnimation::GetFrameCount() const
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraError("Animation not created");
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
return m_impl->frameCount;
|
||||
}
|
||||
|
||||
NzSequence* NzAnimation::GetSequence(const NzString& sequenceName)
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraError("Animation not created");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto it = m_impl->sequenceMap.find(sequenceName);
|
||||
if (it == m_impl->sequenceMap.end())
|
||||
{
|
||||
NazaraError("Sequence not found");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return &m_impl->sequences[it->second];
|
||||
#else
|
||||
return &m_impl->sequences[m_impl->sequenceMap[sequenceName]];
|
||||
#endif
|
||||
}
|
||||
|
||||
NzSequence* NzAnimation::GetSequence(unsigned int index)
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraError("Animation not created");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (index >= m_impl->sequences.size())
|
||||
{
|
||||
NazaraError("Sequence index out of range (" + NzString::Number(index) + " >= " + NzString::Number(m_impl->sequences.size()) + ')');
|
||||
return nullptr;
|
||||
}
|
||||
#endif
|
||||
|
||||
return &m_impl->sequences[index];
|
||||
}
|
||||
|
||||
const NzSequence* NzAnimation::GetSequence(const NzString& sequenceName) const
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraError("Animation not created");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto it = m_impl->sequenceMap.find(sequenceName);
|
||||
if (it == m_impl->sequenceMap.end())
|
||||
{
|
||||
NazaraError("Sequence not found");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return &m_impl->sequences[it->second];
|
||||
#else
|
||||
return &m_impl->sequences[m_impl->sequenceMap[sequenceName]];
|
||||
#endif
|
||||
}
|
||||
|
||||
const NzSequence* NzAnimation::GetSequence(unsigned int index) const
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraError("Animation not created");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (index >= m_impl->sequences.size())
|
||||
{
|
||||
NazaraError("Sequence index out of range (" + NzString::Number(index) + " >= " + NzString::Number(m_impl->sequences.size()) + ')');
|
||||
return nullptr;
|
||||
}
|
||||
#endif
|
||||
|
||||
return &m_impl->sequences[index];
|
||||
}
|
||||
|
||||
unsigned int NzAnimation::GetSequenceCount() const
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraError("Animation not created");
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
return m_impl->sequences.size();
|
||||
}
|
||||
|
||||
int NzAnimation::GetSequenceIndex(const NzString& sequenceName) const
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraError("Animation not created");
|
||||
return -1;
|
||||
}
|
||||
|
||||
auto it = m_impl->sequenceMap.find(sequenceName);
|
||||
if (it == m_impl->sequenceMap.end())
|
||||
{
|
||||
NazaraError("Sequence not found");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return it->second;
|
||||
#else
|
||||
return m_impl->sequenceMap[sequenceName];
|
||||
#endif
|
||||
}
|
||||
|
||||
nzAnimationType NzAnimation::GetType() const
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraError("Animation not created");
|
||||
return nzAnimationType_Static; // Ce qui est une valeur invalide pour NzAnimation
|
||||
}
|
||||
#endif
|
||||
|
||||
return m_impl->type;
|
||||
}
|
||||
|
||||
bool NzAnimation::HasSequence(const NzString& sequenceName) const
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraError("Animation not created");
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
return m_impl->sequenceMap.find(sequenceName) != m_impl->sequenceMap.end();
|
||||
}
|
||||
|
||||
bool NzAnimation::HasSequence(unsigned int index) const
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraError("Animation not created");
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
return index >= m_impl->sequences.size();
|
||||
}
|
||||
|
||||
bool NzAnimation::IsValid() const
|
||||
{
|
||||
return m_impl != nullptr;
|
||||
}
|
||||
|
||||
bool NzAnimation::LoadFromFile(const NzString& filePath, const NzAnimationParams& params)
|
||||
{
|
||||
return NzAnimationLoader::LoadFromFile(this, filePath, params);
|
||||
}
|
||||
|
||||
bool NzAnimation::LoadFromMemory(const void* data, std::size_t size, const NzAnimationParams& params)
|
||||
{
|
||||
return NzAnimationLoader::LoadFromMemory(this, data, size, params);
|
||||
}
|
||||
|
||||
bool NzAnimation::LoadFromStream(NzInputStream& stream, const NzAnimationParams& params)
|
||||
{
|
||||
return NzAnimationLoader::LoadFromStream(this, stream, params);
|
||||
}
|
||||
|
||||
void NzAnimation::RemoveSequence(const NzString& identifier)
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraError("Animation not created");
|
||||
return;
|
||||
}
|
||||
|
||||
auto it = m_impl->sequenceMap.find(identifier);
|
||||
if (it == m_impl->sequenceMap.end())
|
||||
{
|
||||
NazaraError("Sequence not found");
|
||||
return;
|
||||
}
|
||||
|
||||
int index = it->second;
|
||||
#else
|
||||
int index = m_impl->sequenceMap[identifier];
|
||||
#endif
|
||||
|
||||
auto it2 = m_impl->sequences.begin();
|
||||
std::advance(it2, index);
|
||||
|
||||
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
|
||||
// This file is part of the "Nazara Engine - Utility module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#include <Nazara/Utility/Buffer.hpp>
|
||||
#include <Nazara/Core/Error.hpp>
|
||||
#include <Nazara/Utility/BufferImpl.hpp>
|
||||
#include <Nazara/Utility/Config.hpp>
|
||||
#include <Nazara/Utility/SoftwareBuffer.hpp>
|
||||
#include <cstring>
|
||||
#include <stdexcept>
|
||||
#include <Nazara/Utility/Debug.hpp>
|
||||
|
||||
namespace
|
||||
{
|
||||
NzBufferImpl* SoftwareBufferFunction(NzBuffer* parent, nzBufferType type)
|
||||
{
|
||||
return new NzSoftwareBuffer(parent, type);
|
||||
}
|
||||
}
|
||||
|
||||
NzBuffer::NzBuffer(nzBufferType type) :
|
||||
m_type(type),
|
||||
m_typeSize(0),
|
||||
m_impl(nullptr),
|
||||
m_length(0)
|
||||
{
|
||||
}
|
||||
|
||||
NzBuffer::NzBuffer(nzBufferType type, unsigned int length, nzUInt8 typeSize, nzBufferStorage storage, nzBufferUsage usage) :
|
||||
m_type(type),
|
||||
m_impl(nullptr)
|
||||
{
|
||||
Create(length, typeSize, storage, usage);
|
||||
|
||||
#ifdef NAZARA_DEBUG
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraError("Failed to create buffer");
|
||||
throw std::runtime_error("Constructor failed");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
NzBuffer::~NzBuffer()
|
||||
{
|
||||
Destroy();
|
||||
}
|
||||
|
||||
bool NzBuffer::CopyContent(NzBuffer& buffer)
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraError("Buffer must be valid");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!buffer.IsValid())
|
||||
{
|
||||
NazaraError("Source buffer must be valid");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!buffer.GetTypeSize() != m_typeSize)
|
||||
{
|
||||
NazaraError("Source buffer type size does not match buffer type size");
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
void* ptr = buffer.Map(nzBufferAccess_ReadOnly);
|
||||
if (!ptr)
|
||||
{
|
||||
NazaraError("Failed to map source buffer");
|
||||
return false;
|
||||
}
|
||||
|
||||
bool r = Fill(ptr, 0, buffer.GetLength());
|
||||
|
||||
if (!buffer.Unmap())
|
||||
NazaraWarning("Failed to unmap source buffer");
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
bool NzBuffer::Create(unsigned int length, nzUInt8 typeSize, nzBufferStorage storage, nzBufferUsage usage)
|
||||
{
|
||||
Destroy();
|
||||
|
||||
// On tente d'abord de faire un buffer hardware, si supporté
|
||||
if (s_bufferFunctions[storage])
|
||||
{
|
||||
NzBufferImpl* impl = s_bufferFunctions[storage](this, m_type);
|
||||
if (!impl->Create(length*typeSize, usage))
|
||||
{
|
||||
NazaraError("Failed to create buffer");
|
||||
delete impl;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
m_impl = impl;
|
||||
}
|
||||
else
|
||||
{
|
||||
NazaraError("Buffer storage not supported");
|
||||
return false;
|
||||
}
|
||||
|
||||
m_length = length;
|
||||
m_typeSize = typeSize;
|
||||
m_storage = storage;
|
||||
m_usage = usage;
|
||||
|
||||
// Si on arrive ici c'est que tout s'est bien passé.
|
||||
return true;
|
||||
}
|
||||
|
||||
void NzBuffer::Destroy()
|
||||
{
|
||||
if (m_impl)
|
||||
{
|
||||
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
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraError("Buffer not valid");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (offset+length > m_length)
|
||||
{
|
||||
NazaraError("Exceeding buffer size");
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
return m_impl->Fill(data, offset*m_typeSize, ((length == 0) ? m_length-offset : length)*m_typeSize);
|
||||
}
|
||||
|
||||
NzBufferImpl* NzBuffer::GetImpl() const
|
||||
{
|
||||
return m_impl;
|
||||
}
|
||||
|
||||
unsigned int NzBuffer::GetLength() const
|
||||
{
|
||||
return m_length;
|
||||
}
|
||||
|
||||
void* NzBuffer::GetPointer()
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraError("Buffer not valid");
|
||||
return nullptr;
|
||||
}
|
||||
#endif
|
||||
|
||||
return m_impl->GetPointer();
|
||||
}
|
||||
|
||||
const void* NzBuffer::GetPointer() const
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraError("Buffer not valid");
|
||||
return nullptr;
|
||||
}
|
||||
#endif
|
||||
|
||||
return m_impl->GetPointer();
|
||||
}
|
||||
|
||||
unsigned int NzBuffer::GetSize() const
|
||||
{
|
||||
return m_length*m_typeSize;
|
||||
}
|
||||
|
||||
nzBufferStorage NzBuffer::GetStorage() const
|
||||
{
|
||||
return m_storage;
|
||||
}
|
||||
|
||||
nzBufferType NzBuffer::GetType() const
|
||||
{
|
||||
return m_type;
|
||||
}
|
||||
|
||||
nzUInt8 NzBuffer::GetTypeSize() const
|
||||
{
|
||||
return m_typeSize;
|
||||
}
|
||||
|
||||
nzBufferUsage NzBuffer::GetUsage() const
|
||||
{
|
||||
return m_usage;
|
||||
}
|
||||
|
||||
bool NzBuffer::IsHardware() const
|
||||
{
|
||||
return m_storage == nzBufferStorage_Hardware;
|
||||
}
|
||||
|
||||
bool NzBuffer::IsValid() const
|
||||
{
|
||||
return m_impl != nullptr;
|
||||
}
|
||||
|
||||
void* NzBuffer::Map(nzBufferAccess access, unsigned int offset, unsigned int length)
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraError("Buffer not valid");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (offset+length > m_length)
|
||||
{
|
||||
NazaraError("Exceeding buffer size");
|
||||
return nullptr;
|
||||
}
|
||||
#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
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraError("Buffer not valid");
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (m_storage == storage)
|
||||
return true;
|
||||
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!IsSupported(storage))
|
||||
{
|
||||
NazaraError("Storage not supported");
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
void* ptr = m_impl->Map(nzBufferAccess_ReadOnly, 0, m_length*m_typeSize);
|
||||
if (!ptr)
|
||||
{
|
||||
NazaraError("Failed to map buffer");
|
||||
return false;
|
||||
}
|
||||
|
||||
NzBufferImpl* impl = s_bufferFunctions[storage](this, m_type);
|
||||
if (!impl->Create(m_length*m_typeSize, m_usage))
|
||||
{
|
||||
NazaraError("Failed to create buffer");
|
||||
delete impl;
|
||||
|
||||
if (!m_impl->Unmap())
|
||||
NazaraWarning("Failed to unmap buffer");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!impl->Fill(ptr, 0, m_length*m_typeSize))
|
||||
{
|
||||
NazaraError("Failed to fill buffer");
|
||||
impl->Destroy();
|
||||
delete impl;
|
||||
|
||||
if (!m_impl->Unmap())
|
||||
NazaraWarning("Failed to unmap buffer");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
m_impl->Unmap();
|
||||
m_impl->Destroy();
|
||||
|
||||
delete m_impl;
|
||||
m_impl = impl;
|
||||
|
||||
m_storage = storage;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool NzBuffer::Unmap()
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraError("Buffer not valid");
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
return m_impl->Unmap();
|
||||
}
|
||||
|
||||
bool NzBuffer::IsSupported(nzBufferStorage storage)
|
||||
{
|
||||
return s_bufferFunctions[storage] != nullptr;
|
||||
}
|
||||
|
||||
void NzBuffer::SetBufferFunction(nzBufferStorage storage, BufferFunction func)
|
||||
{
|
||||
s_bufferFunctions[storage] = func;
|
||||
}
|
||||
|
||||
bool NzBuffer::Initialize()
|
||||
{
|
||||
s_bufferFunctions[nzBufferStorage_Software] = SoftwareBufferFunction;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void NzBuffer::Uninitialize()
|
||||
{
|
||||
std::memset(s_bufferFunctions, 0, (nzBufferStorage_Max+1)*sizeof(NzBuffer::BufferFunction));
|
||||
}
|
||||
|
||||
NzBuffer::BufferFunction NzBuffer::s_bufferFunctions[nzBufferStorage_Max+1] = {0};
|
||||
// Copyright (C) 2012 Jérôme Leclercq
|
||||
// This file is part of the "Nazara Engine - Utility module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#include <Nazara/Utility/Buffer.hpp>
|
||||
#include <Nazara/Core/Error.hpp>
|
||||
#include <Nazara/Utility/BufferImpl.hpp>
|
||||
#include <Nazara/Utility/Config.hpp>
|
||||
#include <Nazara/Utility/SoftwareBuffer.hpp>
|
||||
#include <cstring>
|
||||
#include <stdexcept>
|
||||
#include <Nazara/Utility/Debug.hpp>
|
||||
|
||||
namespace
|
||||
{
|
||||
NzBufferImpl* SoftwareBufferFunction(NzBuffer* parent, nzBufferType type)
|
||||
{
|
||||
return new NzSoftwareBuffer(parent, type);
|
||||
}
|
||||
}
|
||||
|
||||
NzBuffer::NzBuffer(nzBufferType type) :
|
||||
m_type(type),
|
||||
m_typeSize(0),
|
||||
m_impl(nullptr),
|
||||
m_length(0)
|
||||
{
|
||||
}
|
||||
|
||||
NzBuffer::NzBuffer(nzBufferType type, unsigned int length, nzUInt8 typeSize, nzBufferStorage storage, nzBufferUsage usage) :
|
||||
m_type(type),
|
||||
m_impl(nullptr)
|
||||
{
|
||||
Create(length, typeSize, storage, usage);
|
||||
|
||||
#ifdef NAZARA_DEBUG
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraError("Failed to create buffer");
|
||||
throw std::runtime_error("Constructor failed");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
NzBuffer::~NzBuffer()
|
||||
{
|
||||
Destroy();
|
||||
}
|
||||
|
||||
bool NzBuffer::CopyContent(NzBuffer& buffer)
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraError("Buffer must be valid");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!buffer.IsValid())
|
||||
{
|
||||
NazaraError("Source buffer must be valid");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!buffer.GetTypeSize() != m_typeSize)
|
||||
{
|
||||
NazaraError("Source buffer type size does not match buffer type size");
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
void* ptr = buffer.Map(nzBufferAccess_ReadOnly);
|
||||
if (!ptr)
|
||||
{
|
||||
NazaraError("Failed to map source buffer");
|
||||
return false;
|
||||
}
|
||||
|
||||
bool r = Fill(ptr, 0, buffer.GetLength());
|
||||
|
||||
if (!buffer.Unmap())
|
||||
NazaraWarning("Failed to unmap source buffer");
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
bool NzBuffer::Create(unsigned int length, nzUInt8 typeSize, nzBufferStorage storage, nzBufferUsage usage)
|
||||
{
|
||||
Destroy();
|
||||
|
||||
// On tente d'abord de faire un buffer hardware, si supporté
|
||||
if (s_bufferFunctions[storage])
|
||||
{
|
||||
NzBufferImpl* impl = s_bufferFunctions[storage](this, m_type);
|
||||
if (!impl->Create(length*typeSize, usage))
|
||||
{
|
||||
NazaraError("Failed to create buffer");
|
||||
delete impl;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
m_impl = impl;
|
||||
}
|
||||
else
|
||||
{
|
||||
NazaraError("Buffer storage not supported");
|
||||
return false;
|
||||
}
|
||||
|
||||
m_length = length;
|
||||
m_typeSize = typeSize;
|
||||
m_storage = storage;
|
||||
m_usage = usage;
|
||||
|
||||
NotifyCreated();
|
||||
return true; // Si on arrive ici c'est que tout s'est bien passé.
|
||||
}
|
||||
|
||||
void NzBuffer::Destroy()
|
||||
{
|
||||
if (m_impl)
|
||||
{
|
||||
NotifyDestroy();
|
||||
|
||||
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
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraError("Buffer not valid");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (offset+length > m_length)
|
||||
{
|
||||
NazaraError("Exceeding buffer size");
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
return m_impl->Fill(data, offset*m_typeSize, ((length == 0) ? m_length-offset : length)*m_typeSize);
|
||||
}
|
||||
|
||||
NzBufferImpl* NzBuffer::GetImpl() const
|
||||
{
|
||||
return m_impl;
|
||||
}
|
||||
|
||||
unsigned int NzBuffer::GetLength() const
|
||||
{
|
||||
return m_length;
|
||||
}
|
||||
|
||||
void* NzBuffer::GetPointer()
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraError("Buffer not valid");
|
||||
return nullptr;
|
||||
}
|
||||
#endif
|
||||
|
||||
return m_impl->GetPointer();
|
||||
}
|
||||
|
||||
const void* NzBuffer::GetPointer() const
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraError("Buffer not valid");
|
||||
return nullptr;
|
||||
}
|
||||
#endif
|
||||
|
||||
return m_impl->GetPointer();
|
||||
}
|
||||
|
||||
unsigned int NzBuffer::GetSize() const
|
||||
{
|
||||
return m_length*m_typeSize;
|
||||
}
|
||||
|
||||
nzBufferStorage NzBuffer::GetStorage() const
|
||||
{
|
||||
return m_storage;
|
||||
}
|
||||
|
||||
nzBufferType NzBuffer::GetType() const
|
||||
{
|
||||
return m_type;
|
||||
}
|
||||
|
||||
nzUInt8 NzBuffer::GetTypeSize() const
|
||||
{
|
||||
return m_typeSize;
|
||||
}
|
||||
|
||||
nzBufferUsage NzBuffer::GetUsage() const
|
||||
{
|
||||
return m_usage;
|
||||
}
|
||||
|
||||
bool NzBuffer::IsHardware() const
|
||||
{
|
||||
return m_storage == nzBufferStorage_Hardware;
|
||||
}
|
||||
|
||||
bool NzBuffer::IsValid() const
|
||||
{
|
||||
return m_impl != nullptr;
|
||||
}
|
||||
|
||||
void* NzBuffer::Map(nzBufferAccess access, unsigned int offset, unsigned int length)
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraError("Buffer not valid");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (offset+length > m_length)
|
||||
{
|
||||
NazaraError("Exceeding buffer size");
|
||||
return nullptr;
|
||||
}
|
||||
#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
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraError("Buffer not valid");
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (m_storage == storage)
|
||||
return true;
|
||||
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!IsSupported(storage))
|
||||
{
|
||||
NazaraError("Storage not supported");
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
void* ptr = m_impl->Map(nzBufferAccess_ReadOnly, 0, m_length*m_typeSize);
|
||||
if (!ptr)
|
||||
{
|
||||
NazaraError("Failed to map buffer");
|
||||
return false;
|
||||
}
|
||||
|
||||
NzBufferImpl* impl = s_bufferFunctions[storage](this, m_type);
|
||||
if (!impl->Create(m_length*m_typeSize, m_usage))
|
||||
{
|
||||
NazaraError("Failed to create buffer");
|
||||
delete impl;
|
||||
|
||||
if (!m_impl->Unmap())
|
||||
NazaraWarning("Failed to unmap buffer");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!impl->Fill(ptr, 0, m_length*m_typeSize))
|
||||
{
|
||||
NazaraError("Failed to fill buffer");
|
||||
impl->Destroy();
|
||||
delete impl;
|
||||
|
||||
if (!m_impl->Unmap())
|
||||
NazaraWarning("Failed to unmap buffer");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
m_impl->Unmap();
|
||||
m_impl->Destroy();
|
||||
|
||||
delete m_impl;
|
||||
m_impl = impl;
|
||||
|
||||
m_storage = storage;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool NzBuffer::Unmap()
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraError("Buffer not valid");
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
return m_impl->Unmap();
|
||||
}
|
||||
|
||||
bool NzBuffer::IsSupported(nzBufferStorage storage)
|
||||
{
|
||||
return s_bufferFunctions[storage] != nullptr;
|
||||
}
|
||||
|
||||
void NzBuffer::SetBufferFunction(nzBufferStorage storage, BufferFunction func)
|
||||
{
|
||||
s_bufferFunctions[storage] = func;
|
||||
}
|
||||
|
||||
bool NzBuffer::Initialize()
|
||||
{
|
||||
s_bufferFunctions[nzBufferStorage_Software] = SoftwareBufferFunction;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void NzBuffer::Uninitialize()
|
||||
{
|
||||
std::memset(s_bufferFunctions, 0, (nzBufferStorage_Max+1)*sizeof(NzBuffer::BufferFunction));
|
||||
}
|
||||
|
||||
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
|
||||
// This file is part of the "Nazara Engine - Utility module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#include <Nazara/Utility/Loaders/MD2.hpp>
|
||||
#include <Nazara/Core/Endianness.hpp>
|
||||
#include <Nazara/Core/Error.hpp>
|
||||
#include <Nazara/Core/File.hpp>
|
||||
#include <Nazara/Core/InputStream.hpp>
|
||||
#include <Nazara/Core/MemoryStream.hpp>
|
||||
#include <Nazara/Math/Basic.hpp>
|
||||
#include <Nazara/Utility/Mesh.hpp>
|
||||
#include <Nazara/Utility/Loaders/MD2/Constants.hpp>
|
||||
#include <Nazara/Utility/Loaders/MD2/Mesh.hpp>
|
||||
#include <cstddef>
|
||||
#include <cstring>
|
||||
#include <Nazara/Utility/Debug.hpp>
|
||||
|
||||
namespace
|
||||
{
|
||||
bool NzLoader_MD2_Check(NzInputStream& stream, const NzMeshParams& parameters)
|
||||
{
|
||||
NazaraUnused(parameters);
|
||||
|
||||
nzUInt32 magic[2];
|
||||
if (stream.Read(&magic[0], 2*sizeof(nzUInt32)) != 2*sizeof(nzUInt32))
|
||||
return false;
|
||||
|
||||
#if defined(NAZARA_BIG_ENDIAN)
|
||||
NzByteSwap(&magic[0], sizeof(nzUInt32));
|
||||
NzByteSwap(&magic[1], sizeof(nzUInt32));
|
||||
#endif
|
||||
|
||||
return magic[0] == md2Ident && magic[1] == 8;
|
||||
}
|
||||
|
||||
bool NzLoader_MD2_Load(NzMesh* mesh, NzInputStream& stream, const NzMeshParams& parameters)
|
||||
{
|
||||
md2_header header;
|
||||
if (stream.Read(&header, sizeof(md2_header)) != sizeof(md2_header))
|
||||
{
|
||||
NazaraError("Failed to read header");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Les fichiers MD2 sont en little endian
|
||||
#if defined(NAZARA_BIG_ENDIAN)
|
||||
NzByteSwap(&header.ident, sizeof(nzUInt32));
|
||||
#endif
|
||||
|
||||
if (header.ident != md2Ident)
|
||||
{
|
||||
NazaraError("Invalid MD2 file");
|
||||
return false;
|
||||
}
|
||||
|
||||
#if defined(NAZARA_BIG_ENDIAN)
|
||||
NzByteSwap(&header.version, sizeof(nzUInt32));
|
||||
#endif
|
||||
|
||||
if (header.version != 8)
|
||||
{
|
||||
NazaraError("Bad version number (" + NzString::Number(header.version) + ')');
|
||||
return false;
|
||||
}
|
||||
|
||||
#if defined(NAZARA_BIG_ENDIAN)
|
||||
NzByteSwap(&header.skinwidth, sizeof(nzUInt32));
|
||||
NzByteSwap(&header.skinheight, sizeof(nzUInt32));
|
||||
NzByteSwap(&header.framesize, sizeof(nzUInt32));
|
||||
NzByteSwap(&header.num_skins, sizeof(nzUInt32));
|
||||
NzByteSwap(&header.num_vertices, sizeof(nzUInt32));
|
||||
NzByteSwap(&header.num_st, sizeof(nzUInt32));
|
||||
NzByteSwap(&header.num_tris, sizeof(nzUInt32));
|
||||
NzByteSwap(&header.num_glcmds, sizeof(nzUInt32));
|
||||
NzByteSwap(&header.num_frames, sizeof(nzUInt32));
|
||||
NzByteSwap(&header.offset_skins, sizeof(nzUInt32));
|
||||
NzByteSwap(&header.offset_st, sizeof(nzUInt32));
|
||||
NzByteSwap(&header.offset_tris, sizeof(nzUInt32));
|
||||
NzByteSwap(&header.offset_frames, sizeof(nzUInt32));
|
||||
NzByteSwap(&header.offset_glcmds, sizeof(nzUInt32));
|
||||
NzByteSwap(&header.offset_end, sizeof(nzUInt32));
|
||||
#endif
|
||||
|
||||
if (stream.GetSize() < header.offset_end)
|
||||
{
|
||||
NazaraError("Incomplete MD2 file");
|
||||
return false;
|
||||
}
|
||||
|
||||
/// Création du mesh
|
||||
// Animé ou statique, c'est la question
|
||||
bool animated;
|
||||
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));
|
||||
|
||||
if (parameters.loadAnimations && startFrame != endFrame)
|
||||
animated = true;
|
||||
else
|
||||
animated = false;
|
||||
|
||||
if (!mesh->Create((animated) ? nzAnimationType_Keyframe : nzAnimationType_Static)) // Ne devrait pas échouer
|
||||
{
|
||||
NazaraInternalError("Failed to create mesh");
|
||||
return false;
|
||||
}
|
||||
|
||||
/// Chargement des skins
|
||||
if (header.num_skins > 0)
|
||||
{
|
||||
stream.SetCursorPos(header.offset_skins);
|
||||
{
|
||||
char skin[68];
|
||||
for (unsigned int i = 0; i < header.num_skins; ++i)
|
||||
{
|
||||
stream.Read(skin, 68*sizeof(char));
|
||||
mesh->AddSkin(skin);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Chargement des animmations
|
||||
if (animated)
|
||||
{
|
||||
NzAnimation* animation = new NzAnimation;
|
||||
if (animation->Create(nzAnimationType_Keyframe, endFrame-startFrame+1))
|
||||
{
|
||||
// Décodage des séquences
|
||||
NzString frameName;
|
||||
|
||||
NzSequence sequence;
|
||||
sequence.framePerSecond = 10; // Par défaut pour les animations MD2
|
||||
|
||||
char name[16], last[16];
|
||||
stream.SetCursorPos(header.offset_frames + startFrame*header.framesize + offsetof(md2_frame, name));
|
||||
stream.Read(last, 16*sizeof(char));
|
||||
|
||||
int pos = std::strlen(last)-1;
|
||||
for (unsigned int j = 0; j < 2; ++j)
|
||||
{
|
||||
if (!std::isdigit(last[pos]))
|
||||
break;
|
||||
|
||||
pos--;
|
||||
}
|
||||
last[pos+1] = '\0';
|
||||
|
||||
unsigned int numFrames = 0;
|
||||
for (unsigned int i = startFrame; i <= endFrame; ++i)
|
||||
{
|
||||
stream.SetCursorPos(header.offset_frames + i*header.framesize + offsetof(md2_frame, name));
|
||||
stream.Read(name, 16*sizeof(char));
|
||||
|
||||
pos = std::strlen(name)-1;
|
||||
for (unsigned int j = 0; j < 2; ++j)
|
||||
{
|
||||
if (!std::isdigit(name[pos]))
|
||||
break;
|
||||
|
||||
pos--;
|
||||
}
|
||||
name[pos+1] = '\0';
|
||||
|
||||
if (std::strcmp(name, last) != 0) // Si les deux frames n'ont pas le même nom
|
||||
{
|
||||
// Alors on enregistre la séquence
|
||||
sequence.firstFrame = i-numFrames;
|
||||
sequence.lastFrame = i-1;
|
||||
sequence.name = last;
|
||||
animation->AddSequence(sequence);
|
||||
|
||||
std::strcpy(last, name);
|
||||
|
||||
numFrames = 0;
|
||||
}
|
||||
|
||||
numFrames++;
|
||||
}
|
||||
|
||||
// On ajoute la dernière frame (Qui n'a pas été traitée par la boucle)
|
||||
sequence.firstFrame = endFrame-numFrames;
|
||||
sequence.lastFrame = endFrame;
|
||||
sequence.name = last;
|
||||
animation->AddSequence(sequence);
|
||||
|
||||
mesh->SetAnimation(animation);
|
||||
animation->SetPersistent(false);
|
||||
}
|
||||
else
|
||||
NazaraInternalError("Failed to create animaton");
|
||||
}
|
||||
|
||||
/// Chargement des submesh
|
||||
// Actuellement le loader ne charge qu'un submesh
|
||||
// TODO: Utiliser les commandes OpenGL pour accélérer le rendu
|
||||
NzMD2Mesh* subMesh = new NzMD2Mesh(mesh);
|
||||
if (!subMesh->Create(header, stream, parameters))
|
||||
{
|
||||
NazaraError("Failed to create MD2 mesh");
|
||||
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();
|
||||
}
|
||||
// Copyright (C) 2012 Jérôme Leclercq
|
||||
// This file is part of the "Nazara Engine - Utility module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#include <Nazara/Utility/Loaders/MD2.hpp>
|
||||
#include <Nazara/Core/Endianness.hpp>
|
||||
#include <Nazara/Core/Error.hpp>
|
||||
#include <Nazara/Core/File.hpp>
|
||||
#include <Nazara/Core/InputStream.hpp>
|
||||
#include <Nazara/Core/MemoryStream.hpp>
|
||||
#include <Nazara/Math/Basic.hpp>
|
||||
#include <Nazara/Utility/Mesh.hpp>
|
||||
#include <Nazara/Utility/Loaders/MD2/Constants.hpp>
|
||||
#include <Nazara/Utility/Loaders/MD2/Mesh.hpp>
|
||||
#include <cstddef>
|
||||
#include <cstring>
|
||||
#include <Nazara/Utility/Debug.hpp>
|
||||
|
||||
namespace
|
||||
{
|
||||
bool NzLoader_MD2_Check(NzInputStream& stream, const NzMeshParams& parameters)
|
||||
{
|
||||
NazaraUnused(parameters);
|
||||
|
||||
nzUInt32 magic[2];
|
||||
if (stream.Read(&magic[0], 2*sizeof(nzUInt32)) != 2*sizeof(nzUInt32))
|
||||
return false;
|
||||
|
||||
#if defined(NAZARA_BIG_ENDIAN)
|
||||
NzByteSwap(&magic[0], sizeof(nzUInt32));
|
||||
NzByteSwap(&magic[1], sizeof(nzUInt32));
|
||||
#endif
|
||||
|
||||
return magic[0] == md2Ident && magic[1] == 8;
|
||||
}
|
||||
|
||||
bool NzLoader_MD2_Load(NzMesh* mesh, NzInputStream& stream, const NzMeshParams& parameters)
|
||||
{
|
||||
md2_header header;
|
||||
if (stream.Read(&header, sizeof(md2_header)) != sizeof(md2_header))
|
||||
{
|
||||
NazaraError("Failed to read header");
|
||||
return false;
|
||||
}
|
||||
|
||||
#if defined(NAZARA_BIG_ENDIAN)
|
||||
NzByteSwap(&header.skinwidth, sizeof(nzUInt32));
|
||||
NzByteSwap(&header.skinheight, sizeof(nzUInt32));
|
||||
NzByteSwap(&header.framesize, sizeof(nzUInt32));
|
||||
NzByteSwap(&header.num_skins, sizeof(nzUInt32));
|
||||
NzByteSwap(&header.num_vertices, sizeof(nzUInt32));
|
||||
NzByteSwap(&header.num_st, sizeof(nzUInt32));
|
||||
NzByteSwap(&header.num_tris, sizeof(nzUInt32));
|
||||
NzByteSwap(&header.num_glcmds, sizeof(nzUInt32));
|
||||
NzByteSwap(&header.num_frames, sizeof(nzUInt32));
|
||||
NzByteSwap(&header.offset_skins, sizeof(nzUInt32));
|
||||
NzByteSwap(&header.offset_st, sizeof(nzUInt32));
|
||||
NzByteSwap(&header.offset_tris, sizeof(nzUInt32));
|
||||
NzByteSwap(&header.offset_frames, sizeof(nzUInt32));
|
||||
NzByteSwap(&header.offset_glcmds, sizeof(nzUInt32));
|
||||
NzByteSwap(&header.offset_end, sizeof(nzUInt32));
|
||||
#endif
|
||||
|
||||
if (stream.GetSize() < header.offset_end)
|
||||
{
|
||||
NazaraError("Incomplete MD2 file");
|
||||
return false;
|
||||
}
|
||||
|
||||
/// Création du mesh
|
||||
// Animé ou statique, c'est la question
|
||||
bool animated;
|
||||
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));
|
||||
|
||||
if (parameters.loadAnimations && startFrame != endFrame)
|
||||
animated = true;
|
||||
else
|
||||
animated = false;
|
||||
|
||||
if (!mesh->Create((animated) ? nzAnimationType_Keyframe : nzAnimationType_Static)) // Ne devrait jamais échouer
|
||||
{
|
||||
NazaraInternalError("Failed to create mesh");
|
||||
return false;
|
||||
}
|
||||
|
||||
/// Chargement des skins
|
||||
if (header.num_skins > 0)
|
||||
{
|
||||
stream.SetCursorPos(header.offset_skins);
|
||||
{
|
||||
char skin[68];
|
||||
for (unsigned int i = 0; i < header.num_skins; ++i)
|
||||
{
|
||||
stream.Read(skin, 68*sizeof(char));
|
||||
mesh->AddSkin(skin);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Chargement des animmations
|
||||
if (animated)
|
||||
{
|
||||
NzAnimation* animation = new NzAnimation;
|
||||
if (animation->Create(nzAnimationType_Keyframe, endFrame-startFrame+1))
|
||||
{
|
||||
// Décodage des séquences
|
||||
NzString frameName;
|
||||
|
||||
NzSequence sequence;
|
||||
sequence.framePerSecond = 10; // Par défaut pour les animations MD2
|
||||
|
||||
char name[16], last[16];
|
||||
stream.SetCursorPos(header.offset_frames + startFrame*header.framesize + offsetof(md2_frame, name));
|
||||
stream.Read(last, 16*sizeof(char));
|
||||
|
||||
int pos = std::strlen(last)-1;
|
||||
for (unsigned int j = 0; j < 2; ++j)
|
||||
{
|
||||
if (!std::isdigit(last[pos]))
|
||||
break;
|
||||
|
||||
pos--;
|
||||
}
|
||||
last[pos+1] = '\0';
|
||||
|
||||
unsigned int numFrames = 0;
|
||||
for (unsigned int i = startFrame; i <= endFrame; ++i)
|
||||
{
|
||||
stream.SetCursorPos(header.offset_frames + i*header.framesize + offsetof(md2_frame, name));
|
||||
stream.Read(name, 16*sizeof(char));
|
||||
|
||||
pos = std::strlen(name)-1;
|
||||
for (unsigned int j = 0; j < 2; ++j)
|
||||
{
|
||||
if (!std::isdigit(name[pos]))
|
||||
break;
|
||||
|
||||
pos--;
|
||||
}
|
||||
name[pos+1] = '\0';
|
||||
|
||||
if (std::strcmp(name, last) != 0) // Si les deux frames n'ont pas le même nom
|
||||
{
|
||||
// Alors on enregistre la séquence
|
||||
sequence.firstFrame = i-numFrames;
|
||||
sequence.lastFrame = i-1;
|
||||
sequence.name = last;
|
||||
animation->AddSequence(sequence);
|
||||
|
||||
std::strcpy(last, name);
|
||||
|
||||
numFrames = 0;
|
||||
}
|
||||
|
||||
numFrames++;
|
||||
}
|
||||
|
||||
// On ajoute la dernière frame (Qui n'a pas été traitée par la boucle)
|
||||
sequence.firstFrame = endFrame-numFrames;
|
||||
sequence.lastFrame = endFrame;
|
||||
sequence.name = last;
|
||||
animation->AddSequence(sequence);
|
||||
|
||||
mesh->SetAnimation(animation);
|
||||
animation->SetPersistent(false);
|
||||
}
|
||||
else
|
||||
NazaraInternalError("Failed to create animaton");
|
||||
}
|
||||
|
||||
/// Chargement des submesh
|
||||
// Actuellement le loader ne charge qu'un submesh
|
||||
// TODO: Utiliser les commandes OpenGL pour accélérer le rendu
|
||||
NzMD2Mesh* subMesh = new NzMD2Mesh(mesh);
|
||||
if (!subMesh->Create(header, stream, parameters))
|
||||
{
|
||||
NazaraError("Failed to create MD2 mesh");
|
||||
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
|
||||
// This file is part of the "Nazara Engine - Utility module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#include <Nazara/Utility/Loaders/MD2/Mesh.hpp>
|
||||
#include <Nazara/Core/InputStream.hpp>
|
||||
#include <Nazara/Math/Matrix4.hpp>
|
||||
#include <Nazara/Utility/IndexBuffer.hpp>
|
||||
#include <Nazara/Utility/Mesh.hpp>
|
||||
#include <Nazara/Utility/VertexBuffer.hpp>
|
||||
#include <Nazara/Utility/Debug.hpp>
|
||||
|
||||
NzMD2Mesh::NzMD2Mesh(const NzMesh* parent) :
|
||||
NzKeyframeMesh(parent),
|
||||
m_frames(nullptr),
|
||||
m_indexBuffer(nullptr),
|
||||
m_vertexBuffer(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
NzMD2Mesh::~NzMD2Mesh()
|
||||
{
|
||||
Destroy();
|
||||
}
|
||||
|
||||
bool NzMD2Mesh::Create(const md2_header& header, NzInputStream& stream, const NzMeshParams& parameters)
|
||||
{
|
||||
Destroy();
|
||||
|
||||
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));
|
||||
|
||||
m_frameCount = endFrame - startFrame + 1;
|
||||
m_vertexCount = header.num_tris*3;
|
||||
|
||||
/// Chargement des vertices
|
||||
std::vector<md2_texCoord> texCoords(header.num_st);
|
||||
std::vector<md2_triangle> triangles(header.num_tris);
|
||||
|
||||
// Lecture des coordonnées de texture
|
||||
stream.SetCursorPos(header.offset_st);
|
||||
stream.Read(&texCoords[0], header.num_st*sizeof(md2_texCoord));
|
||||
|
||||
#if defined(NAZARA_BIG_ENDIAN)
|
||||
for (unsigned int i = 0; i < header.num_st; ++i)
|
||||
{
|
||||
NzByteSwap(&texCoords[i].u, sizeof(nzInt16));
|
||||
NzByteSwap(&texCoords[i].v, sizeof(nzInt16));
|
||||
}
|
||||
#endif
|
||||
|
||||
stream.SetCursorPos(header.offset_tris);
|
||||
stream.Read(&triangles[0], header.num_tris*sizeof(md2_triangle));
|
||||
|
||||
#if defined(NAZARA_BIG_ENDIAN)
|
||||
for (unsigned int i = 0; i < header.num_tris; ++i)
|
||||
{
|
||||
NzByteSwap(&triangles[i].vertices[0], sizeof(nzUInt16));
|
||||
NzByteSwap(&texCoords[i].texCoords[0], sizeof(nzUInt16));
|
||||
|
||||
NzByteSwap(&triangles[i].vertices[1], sizeof(nzUInt16));
|
||||
NzByteSwap(&texCoords[i].texCoords[1], sizeof(nzUInt16));
|
||||
|
||||
NzByteSwap(&triangles[i].vertices[2], sizeof(nzUInt16));
|
||||
NzByteSwap(&texCoords[i].texCoords[2], sizeof(nzUInt16));
|
||||
}
|
||||
#endif
|
||||
|
||||
stream.SetCursorPos(header.offset_frames + header.framesize*startFrame);
|
||||
|
||||
md2_frame frame;
|
||||
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
|
||||
NzMatrix4f rotationMatrix = NzMatrix4f::Rotate(NzEulerAnglesf(90.f, -90.f, 0.f));
|
||||
|
||||
unsigned int stride = s_declaration.GetStride(nzElementStream_VertexData);
|
||||
|
||||
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.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));
|
||||
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.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];
|
||||
|
||||
NzVector3f max, min;
|
||||
for (unsigned int t = 0; t < header.num_tris; ++t)
|
||||
{
|
||||
for (unsigned int v = 0; v < 3; ++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);
|
||||
min.MakeFloor(vertex);
|
||||
|
||||
m_frames[i].normal[t*3+v] = vert.n;
|
||||
m_frames[i].vertices[t*3+v] = vertex;
|
||||
}
|
||||
}
|
||||
|
||||
m_frames[i].aabb.SetExtends(min, max);
|
||||
}
|
||||
|
||||
m_indexBuffer = nullptr; // Pas d'indexbuffer pour l'instant
|
||||
m_vertexBuffer = new NzVertexBuffer(m_vertexCount, (3+3+2)*sizeof(float), parameters.storage, nzBufferUsage_Dynamic);
|
||||
|
||||
nzUInt8* ptr = reinterpret_cast<nzUInt8*>(m_vertexBuffer->Map(nzBufferAccess_WriteOnly));
|
||||
if (!ptr)
|
||||
{
|
||||
NazaraError("Failed to map vertex buffer");
|
||||
Destroy();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// On avance jusqu'aux premières coordonnées de texture
|
||||
ptr += s_declaration.GetElement(nzElementStream_VertexData, nzElementUsage_TexCoord)->offset;
|
||||
for (unsigned int t = 0; t < header.num_tris; ++t)
|
||||
{
|
||||
for (unsigned int v = 0; v < 3; ++v)
|
||||
{
|
||||
const md2_texCoord& texC = texCoords[triangles[t].texCoords[v]];
|
||||
|
||||
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);
|
||||
|
||||
ptr += stride;
|
||||
}
|
||||
}
|
||||
|
||||
if (!m_vertexBuffer->Unmap())
|
||||
{
|
||||
NazaraError("Failed to unmap buffer");
|
||||
Destroy();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
m_vertexBuffer->AddResourceReference();
|
||||
m_vertexBuffer->SetPersistent(false);
|
||||
|
||||
AnimateImpl(0, 0, 0.f);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void NzMD2Mesh::Destroy()
|
||||
{
|
||||
if (m_frames)
|
||||
{
|
||||
for (unsigned int i = 0; i < m_frameCount; ++i)
|
||||
{
|
||||
delete[] m_frames[i].normal;
|
||||
delete[] m_frames[i].vertices;
|
||||
}
|
||||
|
||||
delete[] m_frames;
|
||||
m_frames = nullptr;
|
||||
}
|
||||
|
||||
if (m_indexBuffer)
|
||||
{
|
||||
m_indexBuffer->RemoveResourceReference();
|
||||
m_indexBuffer = nullptr;
|
||||
}
|
||||
|
||||
if (m_vertexBuffer)
|
||||
{
|
||||
m_vertexBuffer->RemoveResourceReference();
|
||||
m_vertexBuffer = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
const NzAxisAlignedBox& NzMD2Mesh::GetAABB() const
|
||||
{
|
||||
return m_aabb;
|
||||
}
|
||||
|
||||
nzAnimationType NzMD2Mesh::GetAnimationType() const
|
||||
{
|
||||
if (m_frameCount > 1)
|
||||
return nzAnimationType_Keyframe;
|
||||
else
|
||||
return nzAnimationType_Static;
|
||||
}
|
||||
|
||||
unsigned int NzMD2Mesh::GetFrameCount() const
|
||||
{
|
||||
return m_frameCount;
|
||||
}
|
||||
|
||||
const NzIndexBuffer* NzMD2Mesh::GetIndexBuffer() const
|
||||
{
|
||||
return nullptr;
|
||||
//return m_indexBuffer;
|
||||
}
|
||||
|
||||
nzPrimitiveType NzMD2Mesh::GetPrimitiveType() const
|
||||
{
|
||||
return nzPrimitiveType_TriangleList;
|
||||
}
|
||||
|
||||
const NzVertexBuffer* NzMD2Mesh::GetVertexBuffer() const
|
||||
{
|
||||
return m_vertexBuffer;
|
||||
}
|
||||
|
||||
const NzVertexDeclaration* NzMD2Mesh::GetVertexDeclaration() const
|
||||
{
|
||||
return &s_declaration;
|
||||
}
|
||||
|
||||
void NzMD2Mesh::Initialize()
|
||||
{
|
||||
NzVertexElement elements[3];
|
||||
elements[0].offset = 0;
|
||||
elements[0].type = nzElementType_Float3;
|
||||
elements[0].usage = nzElementUsage_Position;
|
||||
|
||||
elements[1].offset = 3*sizeof(float);
|
||||
elements[1].type = nzElementType_Float3;
|
||||
elements[1].usage = nzElementUsage_Normal;
|
||||
|
||||
elements[2].offset = 3*sizeof(float) + 3*sizeof(float);
|
||||
elements[2].type = nzElementType_Float2;
|
||||
elements[2].usage = nzElementUsage_TexCoord;
|
||||
|
||||
s_declaration.Create(elements, 3);
|
||||
}
|
||||
|
||||
void NzMD2Mesh::Uninitialize()
|
||||
{
|
||||
s_declaration.Destroy();
|
||||
}
|
||||
|
||||
void NzMD2Mesh::AnimateImpl(unsigned int frameA, unsigned int frameB, float interpolation)
|
||||
{
|
||||
nzUInt8* ptr = reinterpret_cast<nzUInt8*>(m_vertexBuffer->Map(nzBufferAccess_WriteOnly));
|
||||
if (!ptr)
|
||||
{
|
||||
NazaraError("Failed to map vertex buffer");
|
||||
return;
|
||||
}
|
||||
|
||||
unsigned int stride = s_declaration.GetStride(nzElementStream_VertexData);
|
||||
unsigned int positionOffset = s_declaration.GetElement(nzElementStream_VertexData, nzElementUsage_Position)->offset;
|
||||
unsigned int normalOffset = s_declaration.GetElement(nzElementStream_VertexData, nzElementUsage_Normal)->offset;
|
||||
|
||||
Frame* fA = &m_frames[frameA];
|
||||
Frame* fB = &m_frames[frameB];
|
||||
for (unsigned int i = 0; i < m_vertexCount; ++i)
|
||||
{
|
||||
NzVector3f* position = reinterpret_cast<NzVector3f*>(ptr + positionOffset);
|
||||
NzVector3f* normal = reinterpret_cast<NzVector3f*>(ptr + normalOffset);
|
||||
|
||||
*position = fA->vertices[i] + interpolation * (fB->vertices[i] - fA->vertices[i]);
|
||||
*normal = md2Normals[fA->normal[i]] + interpolation * (md2Normals[fB->normal[i]] - md2Normals[fA->normal[i]]);
|
||||
|
||||
ptr += stride;
|
||||
}
|
||||
|
||||
if (!m_vertexBuffer->Unmap())
|
||||
NazaraWarning("Failed to unmap vertex buffer, expect mesh corruption");
|
||||
|
||||
// Interpolation de l'AABB
|
||||
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;
|
||||
// Copyright (C) 2012 Jérôme Leclercq
|
||||
// This file is part of the "Nazara Engine - Utility module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#include <Nazara/Utility/Loaders/MD2/Mesh.hpp>
|
||||
#include <Nazara/Core/InputStream.hpp>
|
||||
#include <Nazara/Math/Matrix4.hpp>
|
||||
#include <Nazara/Utility/IndexBuffer.hpp>
|
||||
#include <Nazara/Utility/Mesh.hpp>
|
||||
#include <Nazara/Utility/VertexBuffer.hpp>
|
||||
#include <Nazara/Utility/Debug.hpp>
|
||||
|
||||
NzMD2Mesh::NzMD2Mesh(const NzMesh* parent) :
|
||||
NzKeyframeMesh(parent),
|
||||
m_frames(nullptr),
|
||||
m_indexBuffer(nullptr),
|
||||
m_vertexBuffer(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
NzMD2Mesh::~NzMD2Mesh()
|
||||
{
|
||||
Destroy();
|
||||
}
|
||||
|
||||
bool NzMD2Mesh::Create(const md2_header& header, NzInputStream& stream, const NzMeshParams& parameters)
|
||||
{
|
||||
Destroy();
|
||||
|
||||
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));
|
||||
|
||||
m_frameCount = endFrame - startFrame + 1;
|
||||
m_vertexCount = header.num_tris * 3;
|
||||
|
||||
/// Chargement des vertices
|
||||
std::vector<md2_texCoord> texCoords(header.num_st);
|
||||
std::vector<md2_triangle> triangles(header.num_tris);
|
||||
|
||||
// Lecture des coordonnées de texture
|
||||
stream.SetCursorPos(header.offset_st);
|
||||
stream.Read(&texCoords[0], header.num_st*sizeof(md2_texCoord));
|
||||
|
||||
#if defined(NAZARA_BIG_ENDIAN)
|
||||
for (unsigned int i = 0; i < header.num_st; ++i)
|
||||
{
|
||||
NzByteSwap(&texCoords[i].u, sizeof(nzInt16));
|
||||
NzByteSwap(&texCoords[i].v, sizeof(nzInt16));
|
||||
}
|
||||
#endif
|
||||
|
||||
stream.SetCursorPos(header.offset_tris);
|
||||
stream.Read(&triangles[0], header.num_tris*sizeof(md2_triangle));
|
||||
|
||||
#if defined(NAZARA_BIG_ENDIAN)
|
||||
for (unsigned int i = 0; i < header.num_tris; ++i)
|
||||
{
|
||||
NzByteSwap(&triangles[i].vertices[0], sizeof(nzUInt16));
|
||||
NzByteSwap(&texCoords[i].texCoords[0], sizeof(nzUInt16));
|
||||
|
||||
NzByteSwap(&triangles[i].vertices[1], sizeof(nzUInt16));
|
||||
NzByteSwap(&texCoords[i].texCoords[1], sizeof(nzUInt16));
|
||||
|
||||
NzByteSwap(&triangles[i].vertices[2], sizeof(nzUInt16));
|
||||
NzByteSwap(&texCoords[i].texCoords[2], sizeof(nzUInt16));
|
||||
}
|
||||
#endif
|
||||
|
||||
stream.SetCursorPos(header.offset_frames + header.framesize*startFrame);
|
||||
|
||||
md2_frame frame;
|
||||
frame.vertices.resize(header.num_vertices);
|
||||
|
||||
// Pour que le modèle soit correctement aligné, on génère un quaternion que nous appliquerons à chacune des vertices
|
||||
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);
|
||||
|
||||
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.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));
|
||||
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.z, sizeof(float));
|
||||
#endif
|
||||
|
||||
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)
|
||||
{
|
||||
for (unsigned int v = 0; v < 3; ++v)
|
||||
{
|
||||
const md2_vertex& vert = frame.vertices[triangles[t].vertices[v]];
|
||||
|
||||
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);
|
||||
|
||||
// On fait en sorte d'avoir deux vertices de délimitation, définissant un rectangle dans l'espace
|
||||
max.Maximize(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].normal[index] = vert.n;
|
||||
m_frames[i].vertices[index] = vertex;
|
||||
}
|
||||
}
|
||||
|
||||
m_frames[i].aabb.SetExtends(min, max);
|
||||
}
|
||||
|
||||
m_indexBuffer = nullptr; // Pas d'indexbuffer pour l'instant
|
||||
m_vertexBuffer = new NzVertexBuffer(m_vertexCount, (3+3+2)*sizeof(float), parameters.storage, nzBufferUsage_Dynamic);
|
||||
|
||||
nzUInt8* ptr = reinterpret_cast<nzUInt8*>(m_vertexBuffer->Map(nzBufferAccess_WriteOnly));
|
||||
if (!ptr)
|
||||
{
|
||||
NazaraError("Failed to map vertex buffer");
|
||||
Destroy();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// On avance jusqu'aux dernières coordonnées de texture et on les définit dans l'ordre inverse
|
||||
ptr += s_declaration.GetElement(nzElementStream_VertexData, nzElementUsage_TexCoord)->offset + stride * (m_vertexCount-1);
|
||||
for (unsigned int t = 0; t < header.num_tris; ++t)
|
||||
{
|
||||
for (unsigned int v = 0; v < 3; ++v)
|
||||
{
|
||||
const md2_texCoord& texC = texCoords[triangles[t].texCoords[v]];
|
||||
|
||||
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);
|
||||
|
||||
ptr -= stride;
|
||||
}
|
||||
}
|
||||
|
||||
if (!m_vertexBuffer->Unmap())
|
||||
{
|
||||
NazaraError("Failed to unmap buffer");
|
||||
Destroy();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
m_vertexBuffer->AddResourceReference();
|
||||
m_vertexBuffer->SetPersistent(false);
|
||||
|
||||
AnimateImpl(0, 0, 0.f);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void NzMD2Mesh::Destroy()
|
||||
{
|
||||
if (m_frames)
|
||||
{
|
||||
for (unsigned int i = 0; i < m_frameCount; ++i)
|
||||
{
|
||||
delete[] m_frames[i].normal;
|
||||
delete[] m_frames[i].vertices;
|
||||
}
|
||||
|
||||
delete[] m_frames;
|
||||
m_frames = nullptr;
|
||||
}
|
||||
|
||||
if (m_indexBuffer)
|
||||
{
|
||||
m_indexBuffer->RemoveResourceReference();
|
||||
m_indexBuffer = nullptr;
|
||||
}
|
||||
|
||||
if (m_vertexBuffer)
|
||||
{
|
||||
m_vertexBuffer->RemoveResourceReference();
|
||||
m_vertexBuffer = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
const NzAxisAlignedBox& NzMD2Mesh::GetAABB() const
|
||||
{
|
||||
return m_aabb;
|
||||
}
|
||||
|
||||
nzAnimationType NzMD2Mesh::GetAnimationType() const
|
||||
{
|
||||
if (m_frameCount > 1)
|
||||
return nzAnimationType_Keyframe;
|
||||
else
|
||||
return nzAnimationType_Static;
|
||||
}
|
||||
|
||||
unsigned int NzMD2Mesh::GetFrameCount() const
|
||||
{
|
||||
return m_frameCount;
|
||||
}
|
||||
|
||||
const NzIndexBuffer* NzMD2Mesh::GetIndexBuffer() const
|
||||
{
|
||||
return nullptr;
|
||||
//return m_indexBuffer;
|
||||
}
|
||||
|
||||
nzPrimitiveType NzMD2Mesh::GetPrimitiveType() const
|
||||
{
|
||||
return nzPrimitiveType_TriangleList;
|
||||
}
|
||||
|
||||
const NzVertexBuffer* NzMD2Mesh::GetVertexBuffer() const
|
||||
{
|
||||
return m_vertexBuffer;
|
||||
}
|
||||
|
||||
const NzVertexDeclaration* NzMD2Mesh::GetVertexDeclaration() const
|
||||
{
|
||||
return &s_declaration;
|
||||
}
|
||||
|
||||
void NzMD2Mesh::Initialize()
|
||||
{
|
||||
NzVertexElement elements[3];
|
||||
elements[0].offset = 0;
|
||||
elements[0].type = nzElementType_Float3;
|
||||
elements[0].usage = nzElementUsage_Position;
|
||||
|
||||
elements[1].offset = 3*sizeof(float);
|
||||
elements[1].type = nzElementType_Float3;
|
||||
elements[1].usage = nzElementUsage_Normal;
|
||||
|
||||
elements[2].offset = 3*sizeof(float) + 3*sizeof(float);
|
||||
elements[2].type = nzElementType_Float2;
|
||||
elements[2].usage = nzElementUsage_TexCoord;
|
||||
|
||||
s_declaration.Create(elements, 3);
|
||||
}
|
||||
|
||||
void NzMD2Mesh::Uninitialize()
|
||||
{
|
||||
s_declaration.Destroy();
|
||||
}
|
||||
|
||||
void NzMD2Mesh::AnimateImpl(unsigned int frameA, unsigned int frameB, float interpolation)
|
||||
{
|
||||
nzUInt8* ptr = reinterpret_cast<nzUInt8*>(m_vertexBuffer->Map(nzBufferAccess_WriteOnly));
|
||||
if (!ptr)
|
||||
{
|
||||
NazaraError("Failed to map vertex buffer");
|
||||
return;
|
||||
}
|
||||
|
||||
unsigned int stride = s_declaration.GetStride(nzElementStream_VertexData);
|
||||
unsigned int positionOffset = s_declaration.GetElement(nzElementStream_VertexData, nzElementUsage_Position)->offset;
|
||||
unsigned int normalOffset = s_declaration.GetElement(nzElementStream_VertexData, nzElementUsage_Normal)->offset;
|
||||
|
||||
Frame* fA = &m_frames[frameA];
|
||||
Frame* fB = &m_frames[frameB];
|
||||
for (unsigned int i = 0; i < m_vertexCount; ++i)
|
||||
{
|
||||
NzVector3f* position = reinterpret_cast<NzVector3f*>(ptr + positionOffset);
|
||||
NzVector3f* normal = reinterpret_cast<NzVector3f*>(ptr + normalOffset);
|
||||
|
||||
*position = fA->vertices[i] + interpolation * (fB->vertices[i] - fA->vertices[i]);
|
||||
*normal = md2Normals[fA->normal[i]] + interpolation * (md2Normals[fB->normal[i]] - md2Normals[fA->normal[i]]);
|
||||
|
||||
ptr += stride;
|
||||
}
|
||||
|
||||
if (!m_vertexBuffer->Unmap())
|
||||
NazaraWarning("Failed to unmap vertex buffer, expect mesh corruption");
|
||||
|
||||
// Interpolation de l'AABB
|
||||
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
|
||||
// This file is part of the "Nazara Engine - Utility module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#include <Nazara/Utility/Loaders/PCX.hpp>
|
||||
#include <Nazara/Core/Endianness.hpp>
|
||||
#include <Nazara/Core/Error.hpp>
|
||||
#include <Nazara/Core/File.hpp>
|
||||
#include <Nazara/Core/InputStream.hpp>
|
||||
#include <Nazara/Core/MemoryStream.hpp>
|
||||
#include <Nazara/Utility/Image.hpp>
|
||||
#include <Nazara/Utility/Debug.hpp>
|
||||
|
||||
// Auteur du loader original : David Henry
|
||||
|
||||
namespace
|
||||
{
|
||||
struct pcx_header
|
||||
{
|
||||
nzUInt8 manufacturer;
|
||||
nzUInt8 version;
|
||||
nzUInt8 encoding;
|
||||
nzUInt8 bitsPerPixel;
|
||||
|
||||
nzUInt16 xmin, ymin;
|
||||
nzUInt16 xmax, ymax;
|
||||
nzUInt16 horzRes, vertRes;
|
||||
|
||||
nzUInt8 palette[48];
|
||||
nzUInt8 reserved;
|
||||
nzUInt8 numColorPlanes;
|
||||
|
||||
nzUInt16 bytesPerScanLine;
|
||||
nzUInt16 paletteType;
|
||||
nzUInt16 horzSize, vertSize;
|
||||
|
||||
nzUInt8 padding[54];
|
||||
};
|
||||
|
||||
bool NzLoader_PCX_Check(NzInputStream& stream, const NzImageParams& parameters)
|
||||
{
|
||||
NazaraUnused(parameters);
|
||||
|
||||
nzUInt8 manufacturer;
|
||||
if (stream.Read(&manufacturer, 1) != 1)
|
||||
return false;
|
||||
|
||||
return manufacturer == 0x0a;
|
||||
}
|
||||
|
||||
bool NzLoader_PCX_Load(NzImage* image, NzInputStream& stream, const NzImageParams& parameters)
|
||||
{
|
||||
NazaraUnused(parameters);
|
||||
|
||||
pcx_header header;
|
||||
if (stream.Read(&header, sizeof(pcx_header)) != sizeof(pcx_header))
|
||||
{
|
||||
NazaraError("Failed to read header");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (header.manufacturer != 0x0a)
|
||||
{
|
||||
NazaraError("Bad version number (" + NzString::Number(header.manufacturer) + ')');
|
||||
return false;
|
||||
}
|
||||
|
||||
#if defined(NAZARA_BIG_ENDIAN)
|
||||
// Les fichiers PCX sont en little endian
|
||||
NzByteSwap(&header.xmin, sizeof(nzUInt16));
|
||||
NzByteSwap(&header.ymin, sizeof(nzUInt16));
|
||||
NzByteSwap(&header.xmax, sizeof(nzUInt16));
|
||||
NzByteSwap(&header.ymax, sizeof(nzUInt16));
|
||||
NzByteSwap(&header.horzRes, sizeof(nzUInt16));
|
||||
NzByteSwap(&header.vertRes, sizeof(nzUInt16));
|
||||
|
||||
NzByteSwap(&header.bytesPerScanLine, sizeof(nzUInt16));
|
||||
NzByteSwap(&header.paletteType, sizeof(nzUInt16));
|
||||
NzByteSwap(&header.horzSize, sizeof(nzUInt16));
|
||||
NzByteSwap(&header.vertSize, sizeof(nzUInt16));
|
||||
#endif
|
||||
|
||||
unsigned int bitCount = header.bitsPerPixel * header.numColorPlanes;
|
||||
unsigned int width = header.xmax - header.xmin+1;
|
||||
unsigned int height = header.ymax - header.ymin+1;
|
||||
|
||||
if (!image->Create(nzImageType_2D, nzPixelFormat_RGB8, width, height, 1, (parameters.levelCount > 0) ? parameters.levelCount : 1))
|
||||
{
|
||||
NazaraError("Failed to create image");
|
||||
return false;
|
||||
}
|
||||
|
||||
nzUInt8* pixels = image->GetPixels();
|
||||
|
||||
int rle_value = 0;
|
||||
unsigned int rle_count = 0;
|
||||
|
||||
switch (bitCount)
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
for (unsigned int y = 0; y < height; ++y)
|
||||
{
|
||||
nzUInt8* ptr = &pixels[y * width * 3];
|
||||
int bytes = header.bytesPerScanLine;
|
||||
|
||||
/* decode line number y */
|
||||
while (bytes--)
|
||||
{
|
||||
if (rle_count == 0)
|
||||
{
|
||||
if (!stream.Read(&rle_value, 1))
|
||||
{
|
||||
NazaraError("Failed to read stream (byte " + NzString::Number(stream.GetCursorPos()) + ')');
|
||||
return false;
|
||||
}
|
||||
|
||||
if (rle_value < 0xc0)
|
||||
rle_count = 1;
|
||||
else
|
||||
{
|
||||
rle_count = rle_value - 0xc0;
|
||||
if (!stream.Read(&rle_value, 1))
|
||||
{
|
||||
NazaraError("Failed to read stream (byte " + NzString::Number(stream.GetCursorPos()) + ')');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
rle_count--;
|
||||
|
||||
for (int i = 7; i >= 0; --i)
|
||||
{
|
||||
int colorIndex = ((rle_value & (1 << i)) > 0);
|
||||
|
||||
*ptr++ = header.palette[colorIndex * 3 + 0];
|
||||
*ptr++ = header.palette[colorIndex * 3 + 1];
|
||||
*ptr++ = header.palette[colorIndex * 3 + 2];
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case 4:
|
||||
{
|
||||
nzUInt8* colorIndex = new nzUInt8[width];
|
||||
nzUInt8* line = new nzUInt8[header.bytesPerScanLine];
|
||||
|
||||
for (unsigned int y = 0; y < height; ++y)
|
||||
{
|
||||
nzUInt8* ptr = &pixels[y * width * 3];
|
||||
|
||||
std::memset(colorIndex, 0, width);
|
||||
|
||||
for (unsigned int c = 0; c < 4; ++c)
|
||||
{
|
||||
nzUInt8* pLine = line;
|
||||
int bytes = header.bytesPerScanLine;
|
||||
|
||||
/* decode line number y */
|
||||
while (bytes--)
|
||||
{
|
||||
if (rle_count == 0)
|
||||
{
|
||||
if (!stream.Read(&rle_value, 1))
|
||||
{
|
||||
NazaraError("Failed to read stream (byte " + NzString::Number(stream.GetCursorPos()) + ')');
|
||||
delete[] colorIndex;
|
||||
delete[] line;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (rle_value < 0xc0)
|
||||
rle_count = 1;
|
||||
else
|
||||
{
|
||||
rle_count = rle_value - 0xc0;
|
||||
if (!stream.Read(&rle_value, 1))
|
||||
{
|
||||
NazaraError("Failed to read stream (byte " + NzString::Number(stream.GetCursorPos()) + ')');
|
||||
delete[] colorIndex;
|
||||
delete[] line;
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
rle_count--;
|
||||
*(pLine++) = rle_value;
|
||||
}
|
||||
|
||||
/* compute line's color indexes */
|
||||
for (unsigned int x = 0; x < width; ++x)
|
||||
{
|
||||
if (line[x / 8] & (128 >> (x % 8)))
|
||||
colorIndex[x] += (1 << c);
|
||||
}
|
||||
}
|
||||
|
||||
/* decode scan line. color index => rgb */
|
||||
for (unsigned int x = 0; x < width; ++x)
|
||||
{
|
||||
*ptr++ = header.palette[colorIndex[x] * 3 + 0];
|
||||
*ptr++ = header.palette[colorIndex[x] * 3 + 1];
|
||||
*ptr++ = header.palette[colorIndex[x] * 3 + 2];
|
||||
}
|
||||
}
|
||||
|
||||
/* release memory */
|
||||
delete[] colorIndex;
|
||||
delete[] line;
|
||||
break;
|
||||
}
|
||||
|
||||
case 8:
|
||||
{
|
||||
nzUInt8 palette[768];
|
||||
|
||||
/* the palette is contained in the last 769 bytes of the file */
|
||||
unsigned int curPos = stream.GetCursorPos();
|
||||
stream.SetCursorPos(stream.GetSize()-769);
|
||||
nzUInt8 magic;
|
||||
if (!stream.Read(&magic, 1))
|
||||
{
|
||||
NazaraError("Failed to read stream (byte " + NzString::Number(stream.GetCursorPos()) + ')');
|
||||
return false;
|
||||
}
|
||||
|
||||
/* first byte must be equal to 0x0c (12) */
|
||||
if (magic != 0x0c)
|
||||
{
|
||||
NazaraError("Colormap's first byte must be 0x0c (0x" + NzString::Number(magic, 16) + ')');
|
||||
return false;
|
||||
}
|
||||
|
||||
/* read palette */
|
||||
if (stream.Read(palette, 768) != 768)
|
||||
{
|
||||
NazaraError("Failed to read palette");
|
||||
return false;
|
||||
}
|
||||
|
||||
stream.SetCursorPos(curPos);
|
||||
|
||||
/* read pixel data */
|
||||
for (unsigned int y = 0; y < height; ++y)
|
||||
{
|
||||
nzUInt8* ptr = &pixels[y * width * 3];
|
||||
int bytes = header.bytesPerScanLine;
|
||||
|
||||
/* decode line number y */
|
||||
while (bytes--)
|
||||
{
|
||||
if (rle_count == 0)
|
||||
{
|
||||
if (!stream.Read(&rle_value, 1))
|
||||
{
|
||||
NazaraError("Failed to read stream (byte " + NzString::Number(stream.GetCursorPos()) + ')');
|
||||
return false;
|
||||
}
|
||||
|
||||
if (rle_value < 0xc0)
|
||||
rle_count = 1;
|
||||
else
|
||||
{
|
||||
rle_count = rle_value - 0xc0;
|
||||
if (!stream.Read(&rle_value, 1))
|
||||
{
|
||||
NazaraError("Failed to read stream (byte " + NzString::Number(stream.GetCursorPos()) + ')');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
rle_count--;
|
||||
|
||||
*ptr++ = palette[rle_value * 3 + 0];
|
||||
*ptr++ = palette[rle_value * 3 + 1];
|
||||
*ptr++ = palette[rle_value * 3 + 2];
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case 24:
|
||||
{
|
||||
for (unsigned int y = 0; y < height; ++y)
|
||||
{
|
||||
/* for each color plane */
|
||||
for (int c = 0; c < 3; ++c)
|
||||
{
|
||||
nzUInt8* ptr = &pixels[y * width * 4];
|
||||
int bytes = header.bytesPerScanLine;
|
||||
|
||||
/* decode line number y */
|
||||
while (bytes--)
|
||||
{
|
||||
if (rle_count == 0)
|
||||
{
|
||||
if (!stream.Read(&rle_value, 1))
|
||||
{
|
||||
NazaraError("Failed to read stream (byte " + NzString::Number(stream.GetCursorPos()) + ')');
|
||||
return false;
|
||||
}
|
||||
|
||||
if (rle_value < 0xc0)
|
||||
rle_count = 1;
|
||||
else
|
||||
{
|
||||
rle_count = rle_value - 0xc0;
|
||||
if (!stream.Read(&rle_value, 1))
|
||||
{
|
||||
NazaraError("Failed to read stream (byte " + NzString::Number(stream.GetCursorPos()) + ')');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
rle_count--;
|
||||
ptr[c] = static_cast<nzUInt8>(rle_value);
|
||||
ptr += 3;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
NazaraError("Failed to load " + NzString::Number(bitCount) + " bitcount pcx files");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (parameters.loadFormat != nzPixelFormat_Undefined)
|
||||
image->Convert(parameters.loadFormat);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
void NzLoaders_PCX_Register()
|
||||
{
|
||||
NzImageLoader::RegisterLoader("pcx", NzLoader_PCX_Check, NzLoader_PCX_Load);
|
||||
}
|
||||
|
||||
void NzLoaders_PCX_Unregister()
|
||||
{
|
||||
NzImageLoader::UnregisterLoader("pcx", NzLoader_PCX_Check, NzLoader_PCX_Load);
|
||||
}
|
||||
// Copyright (C) 2012 Jérôme Leclercq
|
||||
// This file is part of the "Nazara Engine - Utility module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#include <Nazara/Utility/Loaders/PCX.hpp>
|
||||
#include <Nazara/Core/Endianness.hpp>
|
||||
#include <Nazara/Core/Error.hpp>
|
||||
#include <Nazara/Core/File.hpp>
|
||||
#include <Nazara/Core/InputStream.hpp>
|
||||
#include <Nazara/Core/MemoryStream.hpp>
|
||||
#include <Nazara/Utility/Image.hpp>
|
||||
#include <Nazara/Utility/Debug.hpp>
|
||||
|
||||
// Auteur du loader original : David Henry
|
||||
|
||||
namespace
|
||||
{
|
||||
struct pcx_header
|
||||
{
|
||||
nzUInt8 manufacturer;
|
||||
nzUInt8 version;
|
||||
nzUInt8 encoding;
|
||||
nzUInt8 bitsPerPixel;
|
||||
|
||||
nzUInt16 xmin, ymin;
|
||||
nzUInt16 xmax, ymax;
|
||||
nzUInt16 horzRes, vertRes;
|
||||
|
||||
nzUInt8 palette[48];
|
||||
nzUInt8 reserved;
|
||||
nzUInt8 numColorPlanes;
|
||||
|
||||
nzUInt16 bytesPerScanLine;
|
||||
nzUInt16 paletteType;
|
||||
nzUInt16 horzSize, vertSize;
|
||||
|
||||
nzUInt8 padding[54];
|
||||
};
|
||||
|
||||
bool NzLoader_PCX_Check(NzInputStream& stream, const NzImageParams& parameters)
|
||||
{
|
||||
NazaraUnused(parameters);
|
||||
|
||||
nzUInt8 manufacturer;
|
||||
if (stream.Read(&manufacturer, 1) != 1)
|
||||
return false;
|
||||
|
||||
return manufacturer == 0x0a;
|
||||
}
|
||||
|
||||
bool NzLoader_PCX_Load(NzImage* image, NzInputStream& stream, const NzImageParams& parameters)
|
||||
{
|
||||
NazaraUnused(parameters);
|
||||
|
||||
pcx_header header;
|
||||
if (stream.Read(&header, sizeof(pcx_header)) != sizeof(pcx_header))
|
||||
{
|
||||
NazaraError("Failed to read header");
|
||||
return false;
|
||||
}
|
||||
|
||||
#if defined(NAZARA_BIG_ENDIAN)
|
||||
// Les fichiers PCX sont en little endian
|
||||
NzByteSwap(&header.xmin, sizeof(nzUInt16));
|
||||
NzByteSwap(&header.ymin, sizeof(nzUInt16));
|
||||
NzByteSwap(&header.xmax, sizeof(nzUInt16));
|
||||
NzByteSwap(&header.ymax, sizeof(nzUInt16));
|
||||
NzByteSwap(&header.horzRes, sizeof(nzUInt16));
|
||||
NzByteSwap(&header.vertRes, sizeof(nzUInt16));
|
||||
|
||||
NzByteSwap(&header.bytesPerScanLine, sizeof(nzUInt16));
|
||||
NzByteSwap(&header.paletteType, sizeof(nzUInt16));
|
||||
NzByteSwap(&header.horzSize, sizeof(nzUInt16));
|
||||
NzByteSwap(&header.vertSize, sizeof(nzUInt16));
|
||||
#endif
|
||||
|
||||
unsigned int bitCount = header.bitsPerPixel * header.numColorPlanes;
|
||||
unsigned int width = header.xmax - header.xmin+1;
|
||||
unsigned int height = header.ymax - header.ymin+1;
|
||||
|
||||
if (!image->Create(nzImageType_2D, nzPixelFormat_RGB8, width, height, 1, (parameters.levelCount > 0) ? parameters.levelCount : 1))
|
||||
{
|
||||
NazaraError("Failed to create image");
|
||||
return false;
|
||||
}
|
||||
|
||||
nzUInt8* pixels = image->GetPixels();
|
||||
|
||||
int rle_value = 0;
|
||||
unsigned int rle_count = 0;
|
||||
|
||||
switch (bitCount)
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
for (unsigned int y = 0; y < height; ++y)
|
||||
{
|
||||
nzUInt8* ptr = &pixels[y * width * 3];
|
||||
int bytes = header.bytesPerScanLine;
|
||||
|
||||
/* decode line number y */
|
||||
while (bytes--)
|
||||
{
|
||||
if (rle_count == 0)
|
||||
{
|
||||
if (!stream.Read(&rle_value, 1))
|
||||
{
|
||||
NazaraError("Failed to read stream (byte " + NzString::Number(stream.GetCursorPos()) + ')');
|
||||
return false;
|
||||
}
|
||||
|
||||
if (rle_value < 0xc0)
|
||||
rle_count = 1;
|
||||
else
|
||||
{
|
||||
rle_count = rle_value - 0xc0;
|
||||
if (!stream.Read(&rle_value, 1))
|
||||
{
|
||||
NazaraError("Failed to read stream (byte " + NzString::Number(stream.GetCursorPos()) + ')');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
rle_count--;
|
||||
|
||||
for (int i = 7; i >= 0; --i)
|
||||
{
|
||||
int colorIndex = ((rle_value & (1 << i)) > 0);
|
||||
|
||||
*ptr++ = header.palette[colorIndex * 3 + 0];
|
||||
*ptr++ = header.palette[colorIndex * 3 + 1];
|
||||
*ptr++ = header.palette[colorIndex * 3 + 2];
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case 4:
|
||||
{
|
||||
nzUInt8* colorIndex = new nzUInt8[width];
|
||||
nzUInt8* line = new nzUInt8[header.bytesPerScanLine];
|
||||
|
||||
for (unsigned int y = 0; y < height; ++y)
|
||||
{
|
||||
nzUInt8* ptr = &pixels[y * width * 3];
|
||||
|
||||
std::memset(colorIndex, 0, width);
|
||||
|
||||
for (unsigned int c = 0; c < 4; ++c)
|
||||
{
|
||||
nzUInt8* pLine = line;
|
||||
int bytes = header.bytesPerScanLine;
|
||||
|
||||
/* decode line number y */
|
||||
while (bytes--)
|
||||
{
|
||||
if (rle_count == 0)
|
||||
{
|
||||
if (!stream.Read(&rle_value, 1))
|
||||
{
|
||||
NazaraError("Failed to read stream (byte " + NzString::Number(stream.GetCursorPos()) + ')');
|
||||
delete[] colorIndex;
|
||||
delete[] line;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (rle_value < 0xc0)
|
||||
rle_count = 1;
|
||||
else
|
||||
{
|
||||
rle_count = rle_value - 0xc0;
|
||||
if (!stream.Read(&rle_value, 1))
|
||||
{
|
||||
NazaraError("Failed to read stream (byte " + NzString::Number(stream.GetCursorPos()) + ')');
|
||||
delete[] colorIndex;
|
||||
delete[] line;
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
rle_count--;
|
||||
*(pLine++) = rle_value;
|
||||
}
|
||||
|
||||
/* compute line's color indexes */
|
||||
for (unsigned int x = 0; x < width; ++x)
|
||||
{
|
||||
if (line[x / 8] & (128 >> (x % 8)))
|
||||
colorIndex[x] += (1 << c);
|
||||
}
|
||||
}
|
||||
|
||||
/* decode scan line. color index => rgb */
|
||||
for (unsigned int x = 0; x < width; ++x)
|
||||
{
|
||||
*ptr++ = header.palette[colorIndex[x] * 3 + 0];
|
||||
*ptr++ = header.palette[colorIndex[x] * 3 + 1];
|
||||
*ptr++ = header.palette[colorIndex[x] * 3 + 2];
|
||||
}
|
||||
}
|
||||
|
||||
/* release memory */
|
||||
delete[] colorIndex;
|
||||
delete[] line;
|
||||
break;
|
||||
}
|
||||
|
||||
case 8:
|
||||
{
|
||||
nzUInt8 palette[768];
|
||||
|
||||
/* the palette is contained in the last 769 bytes of the file */
|
||||
unsigned int curPos = stream.GetCursorPos();
|
||||
stream.SetCursorPos(stream.GetSize()-769);
|
||||
nzUInt8 magic;
|
||||
if (!stream.Read(&magic, 1))
|
||||
{
|
||||
NazaraError("Failed to read stream (byte " + NzString::Number(stream.GetCursorPos()) + ')');
|
||||
return false;
|
||||
}
|
||||
|
||||
/* first byte must be equal to 0x0c (12) */
|
||||
if (magic != 0x0c)
|
||||
{
|
||||
NazaraError("Colormap's first byte must be 0x0c (0x" + NzString::Number(magic, 16) + ')');
|
||||
return false;
|
||||
}
|
||||
|
||||
/* read palette */
|
||||
if (stream.Read(palette, 768) != 768)
|
||||
{
|
||||
NazaraError("Failed to read palette");
|
||||
return false;
|
||||
}
|
||||
|
||||
stream.SetCursorPos(curPos);
|
||||
|
||||
/* read pixel data */
|
||||
for (unsigned int y = 0; y < height; ++y)
|
||||
{
|
||||
nzUInt8* ptr = &pixels[y * width * 3];
|
||||
int bytes = header.bytesPerScanLine;
|
||||
|
||||
/* decode line number y */
|
||||
while (bytes--)
|
||||
{
|
||||
if (rle_count == 0)
|
||||
{
|
||||
if (!stream.Read(&rle_value, 1))
|
||||
{
|
||||
NazaraError("Failed to read stream (byte " + NzString::Number(stream.GetCursorPos()) + ')');
|
||||
return false;
|
||||
}
|
||||
|
||||
if (rle_value < 0xc0)
|
||||
rle_count = 1;
|
||||
else
|
||||
{
|
||||
rle_count = rle_value - 0xc0;
|
||||
if (!stream.Read(&rle_value, 1))
|
||||
{
|
||||
NazaraError("Failed to read stream (byte " + NzString::Number(stream.GetCursorPos()) + ')');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
rle_count--;
|
||||
|
||||
*ptr++ = palette[rle_value * 3 + 0];
|
||||
*ptr++ = palette[rle_value * 3 + 1];
|
||||
*ptr++ = palette[rle_value * 3 + 2];
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case 24:
|
||||
{
|
||||
for (unsigned int y = 0; y < height; ++y)
|
||||
{
|
||||
/* for each color plane */
|
||||
for (int c = 0; c < 3; ++c)
|
||||
{
|
||||
nzUInt8* ptr = &pixels[y * width * 4];
|
||||
int bytes = header.bytesPerScanLine;
|
||||
|
||||
/* decode line number y */
|
||||
while (bytes--)
|
||||
{
|
||||
if (rle_count == 0)
|
||||
{
|
||||
if (!stream.Read(&rle_value, 1))
|
||||
{
|
||||
NazaraError("Failed to read stream (byte " + NzString::Number(stream.GetCursorPos()) + ')');
|
||||
return false;
|
||||
}
|
||||
|
||||
if (rle_value < 0xc0)
|
||||
rle_count = 1;
|
||||
else
|
||||
{
|
||||
rle_count = rle_value - 0xc0;
|
||||
if (!stream.Read(&rle_value, 1))
|
||||
{
|
||||
NazaraError("Failed to read stream (byte " + NzString::Number(stream.GetCursorPos()) + ')');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
rle_count--;
|
||||
ptr[c] = static_cast<nzUInt8>(rle_value);
|
||||
ptr += 3;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
NazaraError("Failed to load " + NzString::Number(bitCount) + " bitcount pcx files");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (parameters.loadFormat != nzPixelFormat_Undefined)
|
||||
image->Convert(parameters.loadFormat);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
void NzLoaders_PCX_Register()
|
||||
{
|
||||
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
|
||||
// This file is part of the "Nazara Engine - Utility module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#include <Nazara/Utility/StaticMesh.hpp>
|
||||
#include <Nazara/Core/Error.hpp>
|
||||
#include <stdexcept>
|
||||
#include <Nazara/Utility/Debug.hpp>
|
||||
|
||||
NzStaticMesh::NzStaticMesh(const NzMesh* parent) :
|
||||
NzSubMesh(parent)
|
||||
{
|
||||
}
|
||||
|
||||
NzStaticMesh::NzStaticMesh(const NzMesh* parent, const NzVertexDeclaration* vertexDeclaration, NzVertexBuffer* vertexBuffer, NzIndexBuffer* indexBuffer) :
|
||||
NzSubMesh(parent)
|
||||
{
|
||||
#ifdef NAZARA_DEBUG
|
||||
if (!Create(vertexDeclaration, vertexBuffer, indexBuffer))
|
||||
{
|
||||
NazaraError("Failed to create mesh");
|
||||
throw std::runtime_error("Constructor failed");
|
||||
}
|
||||
#else
|
||||
Create(vertexDeclaration, vertexBuffer, indexBuffer);
|
||||
#endif
|
||||
}
|
||||
|
||||
NzStaticMesh::~NzStaticMesh()
|
||||
{
|
||||
Destroy();
|
||||
}
|
||||
|
||||
bool NzStaticMesh::Create(const NzVertexDeclaration* vertexDeclaration, NzVertexBuffer* vertexBuffer, NzIndexBuffer* indexBuffer)
|
||||
{
|
||||
Destroy();
|
||||
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!vertexDeclaration)
|
||||
{
|
||||
NazaraError("Vertex declaration is null");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!vertexBuffer)
|
||||
{
|
||||
NazaraError("Vertex buffer is null");
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (indexBuffer)
|
||||
{
|
||||
m_indexBuffer = indexBuffer;
|
||||
m_indexBuffer->AddResourceReference();
|
||||
}
|
||||
|
||||
m_vertexBuffer = vertexBuffer;
|
||||
m_vertexBuffer->AddResourceReference();
|
||||
|
||||
m_vertexDeclaration = vertexDeclaration;
|
||||
m_vertexDeclaration->AddResourceReference();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void NzStaticMesh::Destroy()
|
||||
{
|
||||
m_aabb.SetNull();
|
||||
|
||||
if (m_indexBuffer)
|
||||
{
|
||||
m_indexBuffer->RemoveResourceReference();
|
||||
m_indexBuffer = nullptr;
|
||||
}
|
||||
|
||||
if (m_vertexBuffer)
|
||||
{
|
||||
m_vertexBuffer->RemoveResourceReference();
|
||||
m_vertexBuffer = nullptr;
|
||||
}
|
||||
|
||||
if (m_vertexDeclaration)
|
||||
{
|
||||
m_vertexDeclaration->RemoveResourceReference();
|
||||
m_vertexDeclaration = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
bool NzStaticMesh::GenerateAABB()
|
||||
{
|
||||
if (!m_aabb.IsNull())
|
||||
return true;
|
||||
|
||||
const NzVertexElement* position = m_vertexDeclaration->GetElement(nzElementStream_VertexData, nzElementUsage_Position);
|
||||
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
|
||||
nzUInt8* buffer = reinterpret_cast<nzUInt8*>(m_vertexBuffer->Map(nzBufferAccess_ReadOnly));
|
||||
if (!buffer)
|
||||
{
|
||||
NazaraWarning("Failed to lock vertex buffer");
|
||||
return false;
|
||||
}
|
||||
|
||||
buffer += position->offset;
|
||||
unsigned int stride = m_vertexDeclaration->GetStride(nzElementStream_VertexData);
|
||||
unsigned int vertexCount = m_vertexBuffer->GetVertexCount();
|
||||
for (unsigned int i = 0; i < vertexCount; ++i)
|
||||
{
|
||||
m_aabb.ExtendTo(*reinterpret_cast<NzVector3f*>(buffer));
|
||||
|
||||
buffer += stride;
|
||||
}
|
||||
|
||||
if (!m_vertexBuffer->Unmap())
|
||||
NazaraWarning("Failed to unmap vertex buffer");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
const NzAxisAlignedBox& NzStaticMesh::GetAABB() const
|
||||
{
|
||||
return m_aabb;
|
||||
}
|
||||
|
||||
nzAnimationType NzStaticMesh::GetAnimationType() const
|
||||
{
|
||||
return nzAnimationType_Static;
|
||||
}
|
||||
|
||||
unsigned int NzStaticMesh::GetFrameCount() const
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
const NzIndexBuffer* NzStaticMesh::GetIndexBuffer() const
|
||||
{
|
||||
return m_indexBuffer;
|
||||
}
|
||||
|
||||
nzPrimitiveType NzStaticMesh::GetPrimitiveType() const
|
||||
{
|
||||
return m_primitiveType;
|
||||
}
|
||||
|
||||
const NzVertexBuffer* NzStaticMesh::GetVertexBuffer() const
|
||||
{
|
||||
return m_vertexBuffer;
|
||||
}
|
||||
|
||||
const NzVertexDeclaration* NzStaticMesh::GetVertexDeclaration() const
|
||||
{
|
||||
return m_vertexDeclaration;
|
||||
}
|
||||
|
||||
bool NzStaticMesh::IsAnimated() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool NzStaticMesh::IsValid() const
|
||||
{
|
||||
return m_vertexBuffer != nullptr && m_vertexDeclaration != nullptr;
|
||||
}
|
||||
|
||||
void NzStaticMesh::SetAABB(const NzAxisAlignedBox& aabb)
|
||||
{
|
||||
m_aabb = aabb;
|
||||
}
|
||||
|
||||
void NzStaticMesh::SetPrimitiveType(nzPrimitiveType primitiveType)
|
||||
{
|
||||
m_primitiveType = primitiveType;
|
||||
}
|
||||
|
||||
void NzStaticMesh::AnimateImpl(unsigned int frameA, unsigned int frameB, float interpolation)
|
||||
{
|
||||
NazaraUnused(frameA);
|
||||
NazaraUnused(frameB);
|
||||
NazaraUnused(interpolation);
|
||||
|
||||
// Le safe mode est censé nous protéger de cet appel
|
||||
NazaraError("Static mesh have no animation, please enable safe mode");
|
||||
}
|
||||
// Copyright (C) 2012 Jérôme Leclercq
|
||||
// This file is part of the "Nazara Engine - Utility module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#include <Nazara/Utility/StaticMesh.hpp>
|
||||
#include <Nazara/Core/Error.hpp>
|
||||
#include <stdexcept>
|
||||
#include <Nazara/Utility/Debug.hpp>
|
||||
|
||||
NzStaticMesh::NzStaticMesh(const NzMesh* parent) :
|
||||
NzSubMesh(parent)
|
||||
{
|
||||
}
|
||||
|
||||
NzStaticMesh::NzStaticMesh(const NzMesh* parent, const NzVertexDeclaration* vertexDeclaration, NzVertexBuffer* vertexBuffer, NzIndexBuffer* indexBuffer) :
|
||||
NzSubMesh(parent)
|
||||
{
|
||||
#ifdef NAZARA_DEBUG
|
||||
if (!Create(vertexDeclaration, vertexBuffer, indexBuffer))
|
||||
{
|
||||
NazaraError("Failed to create mesh");
|
||||
throw std::runtime_error("Constructor failed");
|
||||
}
|
||||
#else
|
||||
Create(vertexDeclaration, vertexBuffer, indexBuffer);
|
||||
#endif
|
||||
}
|
||||
|
||||
NzStaticMesh::~NzStaticMesh()
|
||||
{
|
||||
Destroy();
|
||||
}
|
||||
|
||||
bool NzStaticMesh::Create(const NzVertexDeclaration* vertexDeclaration, NzVertexBuffer* vertexBuffer, NzIndexBuffer* indexBuffer)
|
||||
{
|
||||
Destroy();
|
||||
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!vertexDeclaration)
|
||||
{
|
||||
NazaraError("Invalid vertex declaration");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!vertexBuffer)
|
||||
{
|
||||
NazaraError("Invalid vertex buffer");
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (indexBuffer)
|
||||
indexBuffer->AddResourceListener(this);
|
||||
|
||||
m_indexBuffer = indexBuffer;
|
||||
|
||||
m_vertexBuffer = vertexBuffer;
|
||||
m_vertexBuffer->AddResourceListener(this);
|
||||
|
||||
m_vertexDeclaration = vertexDeclaration;
|
||||
m_vertexDeclaration->AddResourceListener(this);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void NzStaticMesh::Destroy()
|
||||
{
|
||||
m_aabb.SetNull();
|
||||
|
||||
if (m_indexBuffer)
|
||||
{
|
||||
m_indexBuffer->RemoveResourceListener(this);
|
||||
m_indexBuffer = nullptr;
|
||||
}
|
||||
|
||||
if (m_vertexBuffer)
|
||||
{
|
||||
m_vertexBuffer->RemoveResourceListener(this);
|
||||
m_vertexBuffer = nullptr;
|
||||
}
|
||||
|
||||
if (m_vertexDeclaration)
|
||||
{
|
||||
m_vertexDeclaration->RemoveResourceListener(this);
|
||||
m_vertexDeclaration = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
bool NzStaticMesh::GenerateAABB()
|
||||
{
|
||||
if (!m_aabb.IsNull())
|
||||
return true;
|
||||
|
||||
const NzVertexElement* position = m_vertexDeclaration->GetElement(nzElementStream_VertexData, nzElementUsage_Position);
|
||||
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
|
||||
nzUInt8* buffer = reinterpret_cast<nzUInt8*>(m_vertexBuffer->Map(nzBufferAccess_ReadOnly));
|
||||
if (!buffer)
|
||||
{
|
||||
NazaraWarning("Failed to lock vertex buffer");
|
||||
return false;
|
||||
}
|
||||
|
||||
buffer += position->offset;
|
||||
unsigned int stride = m_vertexDeclaration->GetStride(nzElementStream_VertexData);
|
||||
unsigned int vertexCount = m_vertexBuffer->GetVertexCount();
|
||||
for (unsigned int i = 0; i < vertexCount; ++i)
|
||||
{
|
||||
m_aabb.ExtendTo(*reinterpret_cast<NzVector3f*>(buffer));
|
||||
|
||||
buffer += stride;
|
||||
}
|
||||
|
||||
if (!m_vertexBuffer->Unmap())
|
||||
NazaraWarning("Failed to unmap vertex buffer");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
const NzAxisAlignedBox& NzStaticMesh::GetAABB() const
|
||||
{
|
||||
return m_aabb;
|
||||
}
|
||||
|
||||
nzAnimationType NzStaticMesh::GetAnimationType() const
|
||||
{
|
||||
return nzAnimationType_Static;
|
||||
}
|
||||
|
||||
unsigned int NzStaticMesh::GetFrameCount() const
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
const NzIndexBuffer* NzStaticMesh::GetIndexBuffer() const
|
||||
{
|
||||
return m_indexBuffer;
|
||||
}
|
||||
|
||||
nzPrimitiveType NzStaticMesh::GetPrimitiveType() const
|
||||
{
|
||||
return m_primitiveType;
|
||||
}
|
||||
|
||||
const NzVertexBuffer* NzStaticMesh::GetVertexBuffer() const
|
||||
{
|
||||
return m_vertexBuffer;
|
||||
}
|
||||
|
||||
const NzVertexDeclaration* NzStaticMesh::GetVertexDeclaration() const
|
||||
{
|
||||
return m_vertexDeclaration;
|
||||
}
|
||||
|
||||
bool NzStaticMesh::IsAnimated() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool NzStaticMesh::IsValid() const
|
||||
{
|
||||
return m_vertexBuffer != nullptr && m_vertexDeclaration != nullptr;
|
||||
}
|
||||
|
||||
void NzStaticMesh::SetAABB(const NzAxisAlignedBox& aabb)
|
||||
{
|
||||
m_aabb = aabb;
|
||||
}
|
||||
|
||||
void NzStaticMesh::SetPrimitiveType(nzPrimitiveType primitiveType)
|
||||
{
|
||||
m_primitiveType = primitiveType;
|
||||
}
|
||||
|
||||
void NzStaticMesh::AnimateImpl(unsigned int frameA, unsigned int frameB, float interpolation)
|
||||
{
|
||||
NazaraUnused(frameA);
|
||||
NazaraUnused(frameB);
|
||||
NazaraUnused(interpolation);
|
||||
|
||||
// Le safe mode est censé nous protéger de cet appel
|
||||
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
|
||||
// This file is part of the "Nazara Engine - Utility module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#include <Nazara/Utility/VertexDeclaration.hpp>
|
||||
#include <Nazara/Core/Error.hpp>
|
||||
#include <Nazara/Utility/Config.hpp>
|
||||
#include <algorithm>
|
||||
#include <cstring>
|
||||
#include <stdexcept>
|
||||
#include <vector>
|
||||
|
||||
#if NAZARA_UTILITY_THREADSAFE && NAZARA_THREADSAFETY_VERTEXDECLARATION
|
||||
#include <Nazara/Core/ThreadSafety.hpp>
|
||||
#else
|
||||
#include <Nazara/Core/ThreadSafetyOff.hpp>
|
||||
#endif
|
||||
|
||||
#include <Nazara/Utility/Debug.hpp>
|
||||
|
||||
namespace
|
||||
{
|
||||
const unsigned int size[] =
|
||||
{
|
||||
sizeof(nzUInt32), // nzElementType_Color
|
||||
1*sizeof(double), // nzElementType_Double1
|
||||
2*sizeof(double), // nzElementType_Double2
|
||||
3*sizeof(double), // nzElementType_Double3
|
||||
4*sizeof(double), // nzElementType_Double4
|
||||
1*sizeof(float), // nzElementType_Float1
|
||||
2*sizeof(float), // nzElementType_Float2
|
||||
3*sizeof(float), // nzElementType_Float3
|
||||
4*sizeof(float) // nzElementType_Float4
|
||||
};
|
||||
|
||||
bool VertexElementCompare(const NzVertexElement& elementA, const NzVertexElement& elementB)
|
||||
{
|
||||
// Nous classons d'abord par stream
|
||||
if (elementA.stream == elementB.stream)
|
||||
{
|
||||
// Ensuite par usage
|
||||
if (elementA.usage == elementB.usage)
|
||||
// Et finalement par usageIndex
|
||||
return elementA.usageIndex < elementB.usageIndex;
|
||||
else
|
||||
return elementA.usage < elementB.usage;
|
||||
}
|
||||
else
|
||||
return elementA.stream < elementB.stream;
|
||||
}
|
||||
}
|
||||
|
||||
struct NzVertexDeclarationImpl
|
||||
{
|
||||
std::vector<NzVertexElement> elements;
|
||||
int elementPos[nzElementStream_Max+1][nzElementUsage_Max+1];
|
||||
int streamPos[nzElementStream_Max+1];
|
||||
unsigned int stride[nzElementStream_Max+1] = {0};
|
||||
|
||||
unsigned short refCount = 1;
|
||||
NazaraMutex(mutex)
|
||||
};
|
||||
|
||||
NzVertexDeclaration::NzVertexDeclaration(const NzVertexElement* elements, unsigned int elementCount)
|
||||
{
|
||||
#ifdef NAZARA_DEBUG
|
||||
if (!Create(elements, elementCount))
|
||||
{
|
||||
NazaraError("Failed to create declaration");
|
||||
throw std::runtime_error("Constructor failed");
|
||||
}
|
||||
#else
|
||||
Create(elements, elementCount);
|
||||
#endif
|
||||
}
|
||||
|
||||
NzVertexDeclaration::NzVertexDeclaration(const NzVertexDeclaration& declaration) :
|
||||
NzResource(),
|
||||
m_sharedImpl(declaration.m_sharedImpl)
|
||||
{
|
||||
if (m_sharedImpl)
|
||||
{
|
||||
NazaraMutexLock(m_sharedImpl->mutex);
|
||||
m_sharedImpl->refCount++;
|
||||
NazaraMutexUnlock(m_sharedImpl->mutex);
|
||||
}
|
||||
}
|
||||
|
||||
NzVertexDeclaration::NzVertexDeclaration(NzVertexDeclaration&& declaration) noexcept :
|
||||
m_sharedImpl(declaration.m_sharedImpl)
|
||||
{
|
||||
declaration.m_sharedImpl = nullptr;
|
||||
}
|
||||
|
||||
NzVertexDeclaration::~NzVertexDeclaration()
|
||||
{
|
||||
Destroy();
|
||||
}
|
||||
|
||||
bool NzVertexDeclaration::Create(const NzVertexElement* elements, unsigned int elementCount)
|
||||
{
|
||||
Destroy();
|
||||
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!elements || elementCount == 0)
|
||||
{
|
||||
NazaraError("No element");
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
NzVertexDeclarationImpl* impl = new NzVertexDeclarationImpl;
|
||||
std::memset(&impl->elementPos, -1, (nzElementStream_Max+1)*(nzElementUsage_Max+1)*sizeof(int));
|
||||
std::memset(&impl->streamPos, -1, (nzElementStream_Max+1)*sizeof(int));
|
||||
|
||||
// On copie et trie les éléments
|
||||
impl->elements.resize(elementCount);
|
||||
std::memcpy(&impl->elements[0], elements, elementCount*sizeof(NzVertexElement));
|
||||
std::sort(impl->elements.begin(), impl->elements.end(), VertexElementCompare);
|
||||
|
||||
for (unsigned int i = 0; i < elementCount; ++i)
|
||||
{
|
||||
NzVertexElement& current = impl->elements[i];
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
// Notre tableau étant trié, s'il y a collision, les deux éléments identiques se suivent...
|
||||
if (i > 0)
|
||||
{
|
||||
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)
|
||||
{
|
||||
// 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));
|
||||
delete impl;
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (current.usageIndex == 0)
|
||||
impl->elementPos[current.stream][current.usage] = i;
|
||||
|
||||
if (impl->streamPos[current.stream] == -1)
|
||||
impl->streamPos[current.stream] = i; // Premier élément du stream (via le triage)
|
||||
|
||||
impl->stride[current.stream] += size[current.type];
|
||||
}
|
||||
|
||||
#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
|
||||
|
||||
m_sharedImpl = impl;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void NzVertexDeclaration::Destroy()
|
||||
{
|
||||
if (!m_sharedImpl)
|
||||
return;
|
||||
|
||||
NazaraMutexLock(m_sharedImpl->mutex);
|
||||
bool freeSharedImpl = (--m_sharedImpl->refCount == 0);
|
||||
NazaraMutexUnlock(m_sharedImpl->mutex);
|
||||
|
||||
if (freeSharedImpl)
|
||||
delete m_sharedImpl;
|
||||
|
||||
m_sharedImpl = nullptr;
|
||||
}
|
||||
|
||||
const NzVertexElement* NzVertexDeclaration::GetElement(unsigned int i) const
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!m_sharedImpl)
|
||||
{
|
||||
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()) + ')');
|
||||
return nullptr;
|
||||
}
|
||||
#endif
|
||||
|
||||
return &m_sharedImpl->elements[i];
|
||||
}
|
||||
|
||||
const NzVertexElement* NzVertexDeclaration::GetElement(nzElementStream stream, unsigned int i) const
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!m_sharedImpl)
|
||||
{
|
||||
NazaraError("Declaration not created");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
int streamPos = m_sharedImpl->streamPos[stream];
|
||||
if (streamPos == -1)
|
||||
{
|
||||
NazaraError("Declaration has no stream 0x" + NzString::Number(stream, 16));
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
unsigned int upperLimit = GetElementCount(stream);
|
||||
if (i >= upperLimit)
|
||||
{
|
||||
NazaraError("Element index out of range (" + NzString::Number(i) + " >= " + NzString::Number(upperLimit) + ')');
|
||||
return nullptr;
|
||||
}
|
||||
#endif
|
||||
|
||||
return &m_sharedImpl->elements[m_sharedImpl->streamPos[stream]+i];
|
||||
}
|
||||
|
||||
const NzVertexElement* NzVertexDeclaration::GetElement(nzElementStream stream, nzElementUsage usage, unsigned int usageIndex) const
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!m_sharedImpl)
|
||||
{
|
||||
NazaraError("Declaration not created");
|
||||
return nullptr;
|
||||
}
|
||||
#endif
|
||||
|
||||
int elementPos = m_sharedImpl->elementPos[stream][usage];
|
||||
if (elementPos == -1)
|
||||
return nullptr;
|
||||
|
||||
elementPos += usageIndex;
|
||||
if (static_cast<unsigned int>(elementPos) >= m_sharedImpl->elements.size())
|
||||
return nullptr;
|
||||
|
||||
NzVertexElement& element = m_sharedImpl->elements[elementPos];
|
||||
if (element.stream != stream || element.usage != usage || element.usageIndex != usageIndex)
|
||||
return nullptr;
|
||||
|
||||
return &element;
|
||||
}
|
||||
|
||||
unsigned int NzVertexDeclaration::GetElementCount() const
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!m_sharedImpl)
|
||||
{
|
||||
NazaraError("Declaration not created");
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
return m_sharedImpl->elements.size();
|
||||
}
|
||||
|
||||
unsigned int NzVertexDeclaration::GetElementCount(nzElementStream stream) const
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!m_sharedImpl)
|
||||
{
|
||||
NazaraError("Declaration not created");
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
int streamPos = m_sharedImpl->streamPos[stream];
|
||||
if (streamPos == -1)
|
||||
return 0;
|
||||
|
||||
unsigned int upperLimit = 0;
|
||||
if (stream == nzElementStream_Max)
|
||||
upperLimit = m_sharedImpl->elements.size();
|
||||
else
|
||||
{
|
||||
for (unsigned int upperStream = stream+1; upperStream <= nzElementStream_Max; ++upperStream)
|
||||
{
|
||||
if (m_sharedImpl->streamPos[upperStream] != -1)
|
||||
{
|
||||
upperLimit = m_sharedImpl->streamPos[upperStream];
|
||||
break;
|
||||
}
|
||||
else if (upperStream == nzElementStream_Max) // Dernier stream, toujours pas de limite
|
||||
upperLimit = m_sharedImpl->elements.size();
|
||||
}
|
||||
}
|
||||
|
||||
return upperLimit-streamPos;
|
||||
}
|
||||
|
||||
unsigned int NzVertexDeclaration::GetStride(nzElementStream stream) const
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!m_sharedImpl)
|
||||
{
|
||||
NazaraError("Declaration not created");
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
return m_sharedImpl->stride[stream];
|
||||
}
|
||||
|
||||
bool NzVertexDeclaration::HasStream(nzElementStream stream) const
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!m_sharedImpl)
|
||||
{
|
||||
NazaraError("Declaration not created");
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
return m_sharedImpl->streamPos[stream] != -1;
|
||||
}
|
||||
|
||||
bool NzVertexDeclaration::IsValid() const
|
||||
{
|
||||
return m_sharedImpl != nullptr;
|
||||
}
|
||||
|
||||
NzVertexDeclaration& NzVertexDeclaration::operator=(const NzVertexDeclaration& declaration)
|
||||
{
|
||||
Destroy();
|
||||
|
||||
m_sharedImpl = declaration.m_sharedImpl;
|
||||
if (m_sharedImpl)
|
||||
{
|
||||
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;
|
||||
}
|
||||
// Copyright (C) 2012 Jérôme Leclercq
|
||||
// This file is part of the "Nazara Engine - Utility module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#include <Nazara/Utility/VertexDeclaration.hpp>
|
||||
#include <Nazara/Core/Error.hpp>
|
||||
#include <Nazara/Utility/Config.hpp>
|
||||
#include <algorithm>
|
||||
#include <cstring>
|
||||
#include <stdexcept>
|
||||
#include <vector>
|
||||
|
||||
#if NAZARA_UTILITY_THREADSAFE && NAZARA_THREADSAFETY_VERTEXDECLARATION
|
||||
#include <Nazara/Core/ThreadSafety.hpp>
|
||||
#else
|
||||
#include <Nazara/Core/ThreadSafetyOff.hpp>
|
||||
#endif
|
||||
|
||||
#include <Nazara/Utility/Debug.hpp>
|
||||
|
||||
namespace
|
||||
{
|
||||
const unsigned int elementCount[] =
|
||||
{
|
||||
4, // nzElementType_Color
|
||||
1, // nzElementType_Double1
|
||||
2, // nzElementType_Double2
|
||||
3, // nzElementType_Double3
|
||||
4, // nzElementType_Double4
|
||||
1, // nzElementType_Float1
|
||||
2, // nzElementType_Float2
|
||||
3, // nzElementType_Float3
|
||||
4 // nzElementType_Float4
|
||||
};
|
||||
|
||||
const unsigned int elementSize[] =
|
||||
{
|
||||
4*sizeof(nzUInt8), // nzElementType_Color
|
||||
1*sizeof(double), // nzElementType_Double1
|
||||
2*sizeof(double), // nzElementType_Double2
|
||||
3*sizeof(double), // nzElementType_Double3
|
||||
4*sizeof(double), // nzElementType_Double4
|
||||
1*sizeof(float), // nzElementType_Float1
|
||||
2*sizeof(float), // nzElementType_Float2
|
||||
3*sizeof(float), // nzElementType_Float3
|
||||
4*sizeof(float) // nzElementType_Float4
|
||||
};
|
||||
|
||||
bool VertexElementCompare(const NzVertexElement& elementA, const NzVertexElement& elementB)
|
||||
{
|
||||
// Nous classons d'abord par stream
|
||||
if (elementA.stream == elementB.stream)
|
||||
{
|
||||
// Ensuite par usage
|
||||
if (elementA.usage == elementB.usage)
|
||||
// Et finalement par usageIndex
|
||||
return elementA.usageIndex < elementB.usageIndex;
|
||||
else
|
||||
return elementA.usage < elementB.usage;
|
||||
}
|
||||
else
|
||||
return elementA.stream < elementB.stream;
|
||||
}
|
||||
}
|
||||
|
||||
struct NzVertexDeclarationImpl
|
||||
{
|
||||
std::vector<NzVertexElement> elements;
|
||||
int elementPos[nzElementStream_Max+1][nzElementUsage_Max+1];
|
||||
int streamPos[nzElementStream_Max+1];
|
||||
unsigned int stride[nzElementStream_Max+1] = {0};
|
||||
|
||||
unsigned short refCount = 1;
|
||||
NazaraMutex(mutex)
|
||||
};
|
||||
|
||||
NzVertexDeclaration::NzVertexDeclaration(const NzVertexElement* elements, unsigned int elementCount)
|
||||
{
|
||||
#ifdef NAZARA_DEBUG
|
||||
if (!Create(elements, elementCount))
|
||||
{
|
||||
NazaraError("Failed to create declaration");
|
||||
throw std::runtime_error("Constructor failed");
|
||||
}
|
||||
#else
|
||||
Create(elements, elementCount);
|
||||
#endif
|
||||
}
|
||||
|
||||
NzVertexDeclaration::NzVertexDeclaration(const NzVertexDeclaration& declaration) :
|
||||
NzResource(),
|
||||
m_sharedImpl(declaration.m_sharedImpl)
|
||||
{
|
||||
if (m_sharedImpl)
|
||||
{
|
||||
NazaraMutexLock(m_sharedImpl->mutex);
|
||||
m_sharedImpl->refCount++;
|
||||
NazaraMutexUnlock(m_sharedImpl->mutex);
|
||||
}
|
||||
}
|
||||
|
||||
NzVertexDeclaration::NzVertexDeclaration(NzVertexDeclaration&& declaration) noexcept :
|
||||
m_sharedImpl(declaration.m_sharedImpl)
|
||||
{
|
||||
declaration.m_sharedImpl = nullptr;
|
||||
}
|
||||
|
||||
NzVertexDeclaration::~NzVertexDeclaration()
|
||||
{
|
||||
Destroy();
|
||||
}
|
||||
|
||||
bool NzVertexDeclaration::Create(const NzVertexElement* elements, unsigned int elementCount)
|
||||
{
|
||||
Destroy();
|
||||
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!elements || elementCount == 0)
|
||||
{
|
||||
NazaraError("No element");
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
NzVertexDeclarationImpl* impl = new NzVertexDeclarationImpl;
|
||||
std::memset(&impl->elementPos, -1, (nzElementStream_Max+1)*(nzElementUsage_Max+1)*sizeof(int));
|
||||
std::memset(&impl->streamPos, -1, (nzElementStream_Max+1)*sizeof(int));
|
||||
|
||||
// On copie et trie les éléments
|
||||
impl->elements.resize(elementCount);
|
||||
std::memcpy(&impl->elements[0], elements, elementCount*sizeof(NzVertexElement));
|
||||
std::sort(impl->elements.begin(), impl->elements.end(), VertexElementCompare);
|
||||
|
||||
for (unsigned int i = 0; i < elementCount; ++i)
|
||||
{
|
||||
NzVertexElement& current = impl->elements[i];
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
// Notre tableau étant trié, s'il y a collision, les deux éléments identiques se suivent...
|
||||
if (i > 0)
|
||||
{
|
||||
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)
|
||||
{
|
||||
// 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));
|
||||
delete impl;
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (current.usageIndex == 0)
|
||||
impl->elementPos[current.stream][current.usage] = i;
|
||||
|
||||
if (impl->streamPos[current.stream] == -1)
|
||||
impl->streamPos[current.stream] = i; // Premier élément du stream (via le triage)
|
||||
|
||||
impl->stride[current.stream] += elementSize[current.type];
|
||||
}
|
||||
|
||||
#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
|
||||
|
||||
m_sharedImpl = impl;
|
||||
|
||||
NotifyCreated();
|
||||
return true;
|
||||
}
|
||||
|
||||
void NzVertexDeclaration::Destroy()
|
||||
{
|
||||
if (!m_sharedImpl)
|
||||
return;
|
||||
|
||||
NotifyDestroy();
|
||||
|
||||
NazaraMutexLock(m_sharedImpl->mutex);
|
||||
bool freeSharedImpl = (--m_sharedImpl->refCount == 0);
|
||||
NazaraMutexUnlock(m_sharedImpl->mutex);
|
||||
|
||||
if (freeSharedImpl)
|
||||
delete m_sharedImpl;
|
||||
|
||||
m_sharedImpl = nullptr;
|
||||
}
|
||||
|
||||
const NzVertexElement* NzVertexDeclaration::GetElement(unsigned int i) const
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!m_sharedImpl)
|
||||
{
|
||||
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()) + ')');
|
||||
return nullptr;
|
||||
}
|
||||
#endif
|
||||
|
||||
return &m_sharedImpl->elements[i];
|
||||
}
|
||||
|
||||
const NzVertexElement* NzVertexDeclaration::GetElement(nzElementStream stream, unsigned int i) const
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!m_sharedImpl)
|
||||
{
|
||||
NazaraError("Declaration not created");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
int streamPos = m_sharedImpl->streamPos[stream];
|
||||
if (streamPos == -1)
|
||||
{
|
||||
NazaraError("Declaration has no stream 0x" + NzString::Number(stream, 16));
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
unsigned int upperLimit = GetElementCount(stream);
|
||||
if (i >= upperLimit)
|
||||
{
|
||||
NazaraError("Element index out of range (" + NzString::Number(i) + " >= " + NzString::Number(upperLimit) + ')');
|
||||
return nullptr;
|
||||
}
|
||||
#endif
|
||||
|
||||
return &m_sharedImpl->elements[m_sharedImpl->streamPos[stream]+i];
|
||||
}
|
||||
|
||||
const NzVertexElement* NzVertexDeclaration::GetElement(nzElementStream stream, nzElementUsage usage, unsigned int usageIndex) const
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!m_sharedImpl)
|
||||
{
|
||||
NazaraError("Declaration not created");
|
||||
return nullptr;
|
||||
}
|
||||
#endif
|
||||
|
||||
int elementPos = m_sharedImpl->elementPos[stream][usage];
|
||||
if (elementPos == -1)
|
||||
return nullptr;
|
||||
|
||||
elementPos += usageIndex;
|
||||
if (static_cast<unsigned int>(elementPos) >= m_sharedImpl->elements.size())
|
||||
return nullptr;
|
||||
|
||||
NzVertexElement& element = m_sharedImpl->elements[elementPos];
|
||||
if (element.stream != stream || element.usage != usage || element.usageIndex != usageIndex)
|
||||
return nullptr;
|
||||
|
||||
return &element;
|
||||
}
|
||||
|
||||
unsigned int NzVertexDeclaration::GetElementCount() const
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!m_sharedImpl)
|
||||
{
|
||||
NazaraError("Declaration not created");
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
return m_sharedImpl->elements.size();
|
||||
}
|
||||
|
||||
unsigned int NzVertexDeclaration::GetElementCount(nzElementStream stream) const
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!m_sharedImpl)
|
||||
{
|
||||
NazaraError("Declaration not created");
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
int streamPos = m_sharedImpl->streamPos[stream];
|
||||
if (streamPos == -1)
|
||||
return 0;
|
||||
|
||||
unsigned int upperLimit = 0;
|
||||
if (stream == nzElementStream_Max)
|
||||
upperLimit = m_sharedImpl->elements.size();
|
||||
else
|
||||
{
|
||||
for (unsigned int upperStream = stream+1; upperStream <= nzElementStream_Max; ++upperStream)
|
||||
{
|
||||
if (m_sharedImpl->streamPos[upperStream] != -1)
|
||||
{
|
||||
upperLimit = m_sharedImpl->streamPos[upperStream];
|
||||
break;
|
||||
}
|
||||
else if (upperStream == nzElementStream_Max) // Dernier stream, toujours pas de limite
|
||||
upperLimit = m_sharedImpl->elements.size();
|
||||
}
|
||||
}
|
||||
|
||||
return upperLimit-streamPos;
|
||||
}
|
||||
|
||||
unsigned int NzVertexDeclaration::GetStride(nzElementStream stream) const
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!m_sharedImpl)
|
||||
{
|
||||
NazaraError("Declaration not created");
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
return m_sharedImpl->stride[stream];
|
||||
}
|
||||
|
||||
bool NzVertexDeclaration::HasStream(nzElementStream stream) const
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!m_sharedImpl)
|
||||
{
|
||||
NazaraError("Declaration not created");
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
return m_sharedImpl->streamPos[stream] != -1;
|
||||
}
|
||||
|
||||
bool NzVertexDeclaration::IsValid() const
|
||||
{
|
||||
return m_sharedImpl != nullptr;
|
||||
}
|
||||
|
||||
NzVertexDeclaration& NzVertexDeclaration::operator=(const NzVertexDeclaration& declaration)
|
||||
{
|
||||
Destroy();
|
||||
|
||||
m_sharedImpl = declaration.m_sharedImpl;
|
||||
if (m_sharedImpl)
|
||||
{
|
||||
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