Merge branch 'master' of https://github.com/DigitalPulseSoftware/NazaraEngine
Former-commit-id: 3878bde4d067ef921783f256b582af8f6463c19b [formerly 029a8e9081b66daf20a78ba7331a496d89145f44] Former-commit-id: 47009b49149da0186169afc538618f2ab2973f89
This commit is contained in:
commit
51533fabe9
|
|
@ -7,11 +7,21 @@
|
||||||
|
|
||||||
namespace Nz
|
namespace Nz
|
||||||
{
|
{
|
||||||
|
/*!
|
||||||
|
* \ingroup audio
|
||||||
|
* \brief Mixes channels in mono
|
||||||
|
*
|
||||||
|
* \param input Input buffer with multiples channels
|
||||||
|
* \param output Output butter for mono
|
||||||
|
* \param channelCount Number of channels
|
||||||
|
* \param frameCount Number of frames
|
||||||
|
*
|
||||||
|
* \remark The input buffer may be the same as the output one
|
||||||
|
*/
|
||||||
template<typename T>
|
template<typename T>
|
||||||
void MixToMono(T* input, T* output, unsigned int channelCount, unsigned int frameCount)
|
void MixToMono(T* input, T* output, unsigned int channelCount, unsigned int frameCount)
|
||||||
{
|
{
|
||||||
///DOC: Le buffer d'entrée peut être le même que le buffer de sortie
|
// To avoid overflow, we use, as an accumulator, a type which is large enough: (u)int 64 bits for integers, double for floatings
|
||||||
// Pour éviter l'overflow, on utilise comme accumulateur un type assez grand, (u)int 64 bits pour les entiers, double pour les flottants
|
|
||||||
typedef typename std::conditional<std::is_unsigned<T>::value, UInt64, Int64>::type BiggestInt;
|
typedef typename std::conditional<std::is_unsigned<T>::value, UInt64, Int64>::type BiggestInt;
|
||||||
typedef typename std::conditional<std::is_integral<T>::value, BiggestInt, double>::type Biggest;
|
typedef typename std::conditional<std::is_integral<T>::value, BiggestInt, double>::type Biggest;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -27,18 +27,23 @@
|
||||||
#ifndef NAZARA_CONFIG_AUDIO_HPP
|
#ifndef NAZARA_CONFIG_AUDIO_HPP
|
||||||
#define NAZARA_CONFIG_AUDIO_HPP
|
#define NAZARA_CONFIG_AUDIO_HPP
|
||||||
|
|
||||||
/// Modifier la configuration d'un module nécessite une recompilation quasi-intégrale de celui-ci et de ceux en héritant
|
/*!
|
||||||
|
* \defgroup audio (NazaraAudio) Audio module
|
||||||
|
* Audio/System module including classes to handle music, sound, etc...
|
||||||
|
*/
|
||||||
|
|
||||||
// Utilise un manager de mémoire pour gérer les allocations dynamiques (détecte les leaks au prix d'allocations/libérations dynamiques plus lentes)
|
/// Each modification of a parameter needs a recompilation of the module
|
||||||
|
|
||||||
|
// Use the MemoryManager to manage dynamic allocations (can detect memory leak but allocations/frees are slower)
|
||||||
#define NAZARA_AUDIO_MANAGE_MEMORY 0
|
#define NAZARA_AUDIO_MANAGE_MEMORY 0
|
||||||
|
|
||||||
// Active les tests de sécurité supplémentaires (Teste notamment les arguments des fonctions, conseillé pour le développement)
|
// Activate the security tests based on the code (Advised for development)
|
||||||
#define NAZARA_AUDIO_SAFE 1
|
#define NAZARA_AUDIO_SAFE 1
|
||||||
|
|
||||||
// Le nombre de buffers utilisés lors du streaming d'objets audio (Au moins deux)
|
// The number of buffers used for audio streaming (At least two)
|
||||||
#define NAZARA_AUDIO_STREAMED_BUFFER_COUNT 2
|
#define NAZARA_AUDIO_STREAMED_BUFFER_COUNT 2
|
||||||
|
|
||||||
/// Vérification des valeurs et types de certaines constantes
|
/// Checking the values and types of certain constants
|
||||||
#include <Nazara/Audio/ConfigCheck.hpp>
|
#include <Nazara/Audio/ConfigCheck.hpp>
|
||||||
|
|
||||||
#if !defined(NAZARA_STATIC)
|
#if !defined(NAZARA_STATIC)
|
||||||
|
|
|
||||||
|
|
@ -7,12 +7,12 @@
|
||||||
#ifndef NAZARA_CONFIG_CHECK_AUDIO_HPP
|
#ifndef NAZARA_CONFIG_CHECK_AUDIO_HPP
|
||||||
#define NAZARA_CONFIG_CHECK_AUDIO_HPP
|
#define NAZARA_CONFIG_CHECK_AUDIO_HPP
|
||||||
|
|
||||||
/// Ce fichier sert à vérifier la valeur des constantes du fichier Config.hpp
|
/// This file is used to check the constant values defined in Config.hpp
|
||||||
|
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
#define NazaraCheckTypeAndVal(name, type, op, val, err) static_assert(std::is_ ##type <decltype(name)>::value && name op val, #type err)
|
#define NazaraCheckTypeAndVal(name, type, op, val, err) static_assert(std::is_ ##type <decltype(name)>::value && name op val, #type err)
|
||||||
|
|
||||||
// On force la valeur de MANAGE_MEMORY en mode debug
|
// We force the value of MANAGE_MEMORY in debug
|
||||||
#if defined(NAZARA_DEBUG) && !NAZARA_AUDIO_MANAGE_MEMORY
|
#if defined(NAZARA_DEBUG) && !NAZARA_AUDIO_MANAGE_MEMORY
|
||||||
#undef NAZARA_AUDIO_MANAGE_MEMORY
|
#undef NAZARA_AUDIO_MANAGE_MEMORY
|
||||||
#define NAZARA_AUDIO_MANAGE_MEMORY 0
|
#define NAZARA_AUDIO_MANAGE_MEMORY 0
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
// This file is part of the "Nazara Engine - Audio module"
|
// This file is part of the "Nazara Engine - Audio module"
|
||||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||||
|
|
||||||
// On suppose que Debug.hpp a déjà été inclus, tout comme Config.hpp
|
// We assume that Debug.hpp has already been included, same thing for Config.hpp
|
||||||
#if NAZARA_AUDIO_MANAGE_MEMORY
|
#if NAZARA_AUDIO_MANAGE_MEMORY
|
||||||
#undef delete
|
#undef delete
|
||||||
#undef new
|
#undef new
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ namespace Nz
|
||||||
{
|
{
|
||||||
AudioFormat_Unknown = -1,
|
AudioFormat_Unknown = -1,
|
||||||
|
|
||||||
// La valeur entière est le nombre de canaux possédés par ce format
|
// The integer value is the number of channels used by the format
|
||||||
AudioFormat_Mono = 1,
|
AudioFormat_Mono = 1,
|
||||||
AudioFormat_Stereo = 2,
|
AudioFormat_Stereo = 2,
|
||||||
AudioFormat_Quad = 4,
|
AudioFormat_Quad = 4,
|
||||||
|
|
|
||||||
|
|
@ -15,18 +15,18 @@
|
||||||
#include <Nazara/Core/String.hpp>
|
#include <Nazara/Core/String.hpp>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
// Inclusion des headers OpenAL
|
// Inclusion of OpenAL headers
|
||||||
|
|
||||||
// Étant donné que les headers OpenAL ne nous permettent pas de n'avoir que les signatures sans les pointeurs de fonctions
|
// OpenAL headers does not allow us to only get the signatures without the pointers to the functions
|
||||||
// Et que je ne souhaite pas les modifier, je suis contraint de les placer dans un espace de nom différent pour ensuite
|
// And I do no want to modify them, I'm obliged to put them in a different namespace
|
||||||
// remettre dans l'espace global les choses intéressantes (les typedef notamment)
|
// to put only interesting things back in the global namespace (specially typedef)
|
||||||
namespace OpenALDetail
|
namespace OpenALDetail
|
||||||
{
|
{
|
||||||
#include <AL/al.h>
|
#include <AL/al.h>
|
||||||
#include <AL/alc.h>
|
#include <AL/alc.h>
|
||||||
}
|
}
|
||||||
|
|
||||||
// Si quelqu'un a une meilleure idée ...
|
// If someone has a better idea ...
|
||||||
using OpenALDetail::ALboolean;
|
using OpenALDetail::ALboolean;
|
||||||
using OpenALDetail::ALbyte;
|
using OpenALDetail::ALbyte;
|
||||||
using OpenALDetail::ALchar;
|
using OpenALDetail::ALchar;
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,13 @@
|
||||||
|
|
||||||
namespace Nz
|
namespace Nz
|
||||||
{
|
{
|
||||||
|
/*!
|
||||||
|
* \brief Creates a new sound buffer from the arguments
|
||||||
|
* \return A reference to the newly created sound buffer
|
||||||
|
*
|
||||||
|
* \param args Arguments for the sound buffer
|
||||||
|
*/
|
||||||
|
|
||||||
template<typename... Args>
|
template<typename... Args>
|
||||||
SoundBufferRef SoundBuffer::New(Args&&... args)
|
SoundBufferRef SoundBuffer::New(Args&&... args)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@
|
||||||
#include <Nazara/Audio/Enums.hpp>
|
#include <Nazara/Audio/Enums.hpp>
|
||||||
#include <Nazara/Math/Vector3.hpp>
|
#include <Nazara/Math/Vector3.hpp>
|
||||||
|
|
||||||
///TODO: Faire hériter SoundEmitter de Node
|
///TODO: Inherit SoundEmitter from Node
|
||||||
|
|
||||||
namespace Nz
|
namespace Nz
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
#define NazaraCheckTypeAndVal(name, type, op, val, err) static_assert(std::is_ ##type <decltype(name)>::value && name op val, #type err)
|
#define NazaraCheckTypeAndVal(name, type, op, val, err) static_assert(std::is_ ##type <decltype(name)>::value && name op val, #type err)
|
||||||
|
|
||||||
// We fore the value of MANAGE_MEMORY in debug
|
// We force the value of MANAGE_MEMORY in debug
|
||||||
#if defined(NAZARA_DEBUG) && !NAZARA_CORE_MANAGE_MEMORY
|
#if defined(NAZARA_DEBUG) && !NAZARA_CORE_MANAGE_MEMORY
|
||||||
#undef NAZARA_CORE_MANAGE_MEMORY
|
#undef NAZARA_CORE_MANAGE_MEMORY
|
||||||
#define NAZARA_CORE_MANAGE_MEMORY 0
|
#define NAZARA_CORE_MANAGE_MEMORY 0
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,17 @@
|
||||||
|
|
||||||
namespace Nz
|
namespace Nz
|
||||||
{
|
{
|
||||||
|
/*!
|
||||||
|
* \ingroup core
|
||||||
|
* \class Nz::HandledObject<T>
|
||||||
|
* \brief Core class that represents a handled object
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Constructs a HandledObject object by assignation
|
||||||
|
*
|
||||||
|
* \param object HandledObject to assign into this
|
||||||
|
*/
|
||||||
template<typename T>
|
template<typename T>
|
||||||
HandledObject<T>::HandledObject(const HandledObject& object)
|
HandledObject<T>::HandledObject(const HandledObject& object)
|
||||||
{
|
{
|
||||||
|
|
@ -17,6 +28,11 @@ namespace Nz
|
||||||
// Don't copy anything, we're a copy of the object, we have no handle right now
|
// Don't copy anything, we're a copy of the object, we have no handle right now
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Constructs a HandledObject object by move semantic
|
||||||
|
*
|
||||||
|
* \param object HandledObject to move into this
|
||||||
|
*/
|
||||||
template<typename T>
|
template<typename T>
|
||||||
HandledObject<T>::HandledObject(HandledObject&& object) :
|
HandledObject<T>::HandledObject(HandledObject&& object) :
|
||||||
m_handles(std::move(object.m_handles))
|
m_handles(std::move(object.m_handles))
|
||||||
|
|
@ -25,18 +41,33 @@ namespace Nz
|
||||||
handle->OnObjectMoved(static_cast<T*>(this));
|
handle->OnObjectMoved(static_cast<T*>(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Destructs the object and calls UnregisterAllHandles
|
||||||
|
*
|
||||||
|
* \see UnregisterAllHandles
|
||||||
|
*/
|
||||||
template<typename T>
|
template<typename T>
|
||||||
HandledObject<T>::~HandledObject()
|
HandledObject<T>::~HandledObject()
|
||||||
{
|
{
|
||||||
UnregisterAllHandles();
|
UnregisterAllHandles();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Creates a ObjectHandle for this
|
||||||
|
* \return ObjectHandle to this
|
||||||
|
*/
|
||||||
template<typename T>
|
template<typename T>
|
||||||
ObjectHandle<T> HandledObject<T>::CreateHandle()
|
ObjectHandle<T> HandledObject<T>::CreateHandle()
|
||||||
{
|
{
|
||||||
return ObjectHandle<T>(static_cast<T*>(this));
|
return ObjectHandle<T>(static_cast<T*>(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Sets the reference of the HandledObject with the handle from another
|
||||||
|
* \return A reference to this
|
||||||
|
*
|
||||||
|
* \param object The other HandledObject
|
||||||
|
*/
|
||||||
template<typename T>
|
template<typename T>
|
||||||
HandledObject<T>& HandledObject<T>::operator=(const HandledObject& object)
|
HandledObject<T>& HandledObject<T>::operator=(const HandledObject& object)
|
||||||
{
|
{
|
||||||
|
|
@ -44,6 +75,12 @@ namespace Nz
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Moves the HandledObject into this
|
||||||
|
* \return A reference to this
|
||||||
|
*
|
||||||
|
* \param object HandledObject to move in this
|
||||||
|
*/
|
||||||
template<typename T>
|
template<typename T>
|
||||||
HandledObject<T>& HandledObject<T>::operator=(HandledObject&& object)
|
HandledObject<T>& HandledObject<T>::operator=(HandledObject&& object)
|
||||||
{
|
{
|
||||||
|
|
@ -54,13 +91,22 @@ namespace Nz
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Registers a handle
|
||||||
|
*
|
||||||
|
* \param handle Handle to register
|
||||||
|
*
|
||||||
|
* \remark One handle can only be registered once, errors can occur if it's more than once
|
||||||
|
*/
|
||||||
template<typename T>
|
template<typename T>
|
||||||
void HandledObject<T>::RegisterHandle(ObjectHandle<T>* handle)
|
void HandledObject<T>::RegisterHandle(ObjectHandle<T>* handle)
|
||||||
{
|
{
|
||||||
///DOC: Un handle ne doit être enregistré qu'une fois, des erreurs se produisent s'il l'est plus d'une fois
|
|
||||||
m_handles.push_back(handle);
|
m_handles.push_back(handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Unregisters all handles
|
||||||
|
*/
|
||||||
template<typename T>
|
template<typename T>
|
||||||
void HandledObject<T>::UnregisterAllHandles()
|
void HandledObject<T>::UnregisterAllHandles()
|
||||||
{
|
{
|
||||||
|
|
@ -71,10 +117,17 @@ namespace Nz
|
||||||
m_handles.clear();
|
m_handles.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Unregisters a handle
|
||||||
|
*
|
||||||
|
* \param handle Handle to unregister
|
||||||
|
*
|
||||||
|
* \remark One handle can only be unregistered once, crash can occur if it's more than once
|
||||||
|
* \remark Produces a NazaraAssert if handle not registered
|
||||||
|
*/
|
||||||
template<typename T>
|
template<typename T>
|
||||||
void HandledObject<T>::UnregisterHandle(ObjectHandle<T>* handle) noexcept
|
void HandledObject<T>::UnregisterHandle(ObjectHandle<T>* handle) noexcept
|
||||||
{
|
{
|
||||||
///DOC: Un handle ne doit être libéré qu'une fois, et doit faire partie de la liste, sous peine de crash
|
|
||||||
auto it = std::find(m_handles.begin(), m_handles.end(), handle);
|
auto it = std::find(m_handles.begin(), m_handles.end(), handle);
|
||||||
NazaraAssert(it != m_handles.end(), "Handle not registered");
|
NazaraAssert(it != m_handles.end(), "Handle not registered");
|
||||||
|
|
||||||
|
|
@ -83,6 +136,14 @@ namespace Nz
|
||||||
m_handles.pop_back();
|
m_handles.pop_back();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Updates one handle with another
|
||||||
|
*
|
||||||
|
* \param oldHandle Old handle to replace
|
||||||
|
* \param newHandle New handle to take place
|
||||||
|
*
|
||||||
|
* \remark Produces a NazaraAssert if handle not registered
|
||||||
|
*/
|
||||||
template<typename T>
|
template<typename T>
|
||||||
void HandledObject<T>::UpdateHandle(ObjectHandle<T>* oldHandle, ObjectHandle<T>* newHandle) noexcept
|
void HandledObject<T>::UpdateHandle(ObjectHandle<T>* oldHandle, ObjectHandle<T>* newHandle) noexcept
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -9,12 +9,26 @@
|
||||||
|
|
||||||
namespace Nz
|
namespace Nz
|
||||||
{
|
{
|
||||||
|
/*!
|
||||||
|
* \ingroup core
|
||||||
|
* \class Nz::ObjectHandle
|
||||||
|
* \brief Core class that represents a object handle
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Constructs a ObjectHandle object by default
|
||||||
|
*/
|
||||||
template<typename T>
|
template<typename T>
|
||||||
ObjectHandle<T>::ObjectHandle() :
|
ObjectHandle<T>::ObjectHandle() :
|
||||||
m_object(nullptr)
|
m_object(nullptr)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Constructs a ObjectHandle object with a pointer to an object
|
||||||
|
*
|
||||||
|
* \param object Pointer to handle like an object (can be nullptr)
|
||||||
|
*/
|
||||||
template<typename T>
|
template<typename T>
|
||||||
ObjectHandle<T>::ObjectHandle(T* object) :
|
ObjectHandle<T>::ObjectHandle(T* object) :
|
||||||
ObjectHandle()
|
ObjectHandle()
|
||||||
|
|
@ -22,59 +36,97 @@ namespace Nz
|
||||||
Reset(object);
|
Reset(object);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Constructs a ObjectHandle object by assignation
|
||||||
|
*
|
||||||
|
* \param handle ObjectHandle to assign into this
|
||||||
|
*/
|
||||||
template<typename T>
|
template<typename T>
|
||||||
ObjectHandle<T>::ObjectHandle(const ObjectHandle<T>& handle) :
|
ObjectHandle<T>::ObjectHandle(const ObjectHandle& handle) :
|
||||||
ObjectHandle()
|
ObjectHandle()
|
||||||
{
|
{
|
||||||
Reset(handle);
|
Reset(handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Constructs a ObjectHandle object by move semantic
|
||||||
|
*
|
||||||
|
* \param handle ObjectHandle to move into this
|
||||||
|
*/
|
||||||
template<typename T>
|
template<typename T>
|
||||||
ObjectHandle<T>::ObjectHandle(ObjectHandle<T>&& handle) noexcept :
|
ObjectHandle<T>::ObjectHandle(ObjectHandle&& handle) noexcept :
|
||||||
ObjectHandle()
|
ObjectHandle()
|
||||||
{
|
{
|
||||||
Reset(std::move(handle));
|
Reset(std::move(handle));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Destructs the object and calls reset with nullptr
|
||||||
|
*
|
||||||
|
* \see Reset
|
||||||
|
*/
|
||||||
template<typename T>
|
template<typename T>
|
||||||
ObjectHandle<T>::~ObjectHandle()
|
ObjectHandle<T>::~ObjectHandle()
|
||||||
{
|
{
|
||||||
Reset(nullptr);
|
Reset(nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Gets the underlying object
|
||||||
|
* \return Underlying object
|
||||||
|
*/
|
||||||
template<typename T>
|
template<typename T>
|
||||||
T* ObjectHandle<T>::GetObject() const
|
T* ObjectHandle<T>::GetObject() const
|
||||||
{
|
{
|
||||||
return m_object;
|
return m_object;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Checks whether the object is valid
|
||||||
|
* \return true if object is not nullptr
|
||||||
|
*/
|
||||||
template<typename T>
|
template<typename T>
|
||||||
bool ObjectHandle<T>::IsValid() const
|
bool ObjectHandle<T>::IsValid() const
|
||||||
{
|
{
|
||||||
return m_object != nullptr;
|
return m_object != nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Resets the content of the ObjectHandle with another object
|
||||||
|
*
|
||||||
|
* \param object Object to handle
|
||||||
|
*/
|
||||||
template<typename T>
|
template<typename T>
|
||||||
void ObjectHandle<T>::Reset(T* object)
|
void ObjectHandle<T>::Reset(T* object)
|
||||||
{
|
{
|
||||||
// Si nous avions déjà une entité, nous devons l'informer que nous ne pointons plus sur elle
|
// If we already have an entity, we must alert it that we are not pointing to it anymore
|
||||||
if (m_object)
|
if (m_object)
|
||||||
m_object->UnregisterHandle(this);
|
m_object->UnregisterHandle(this);
|
||||||
|
|
||||||
m_object = object;
|
m_object = object;
|
||||||
if (m_object)
|
if (m_object)
|
||||||
// On informe la nouvelle entité que nous pointons sur elle
|
// We alert the new entity that we are pointing to it
|
||||||
m_object->RegisterHandle(this);
|
m_object->RegisterHandle(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Resets the content of this with another object
|
||||||
|
*
|
||||||
|
* \param handle New object to handle
|
||||||
|
*/
|
||||||
template<typename T>
|
template<typename T>
|
||||||
void ObjectHandle<T>::Reset(const ObjectHandle<T>& handle)
|
void ObjectHandle<T>::Reset(const ObjectHandle& handle)
|
||||||
{
|
{
|
||||||
Reset(handle.GetObject());
|
Reset(handle.GetObject());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Resets the content of this with another object by move semantic
|
||||||
|
*
|
||||||
|
* \param handle New object to handle to move into this
|
||||||
|
*/
|
||||||
template<typename T>
|
template<typename T>
|
||||||
void ObjectHandle<T>::Reset(ObjectHandle<T>&& handle) noexcept
|
void ObjectHandle<T>::Reset(ObjectHandle&& handle) noexcept
|
||||||
{
|
{
|
||||||
if (m_object)
|
if (m_object)
|
||||||
m_object->UnregisterHandle(this);
|
m_object->UnregisterHandle(this);
|
||||||
|
|
@ -87,12 +139,18 @@ namespace Nz
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Swaps the content of the two ObjectHandle
|
||||||
|
* \return A reference to this
|
||||||
|
*
|
||||||
|
* \param handle ObjectHandle to swap
|
||||||
|
*/
|
||||||
template<typename T>
|
template<typename T>
|
||||||
ObjectHandle<T>& ObjectHandle<T>::Swap(ObjectHandle<T>& handle)
|
ObjectHandle<T>& ObjectHandle<T>::Swap(ObjectHandle& handle)
|
||||||
{
|
{
|
||||||
// Comme nous inversons les handles, nous devons prévenir les entités
|
// As we swap the two handles, we must alert the entities
|
||||||
// La version par défaut de swap (à base de move) aurait fonctionné,
|
// The default version with swap (move) would be working,
|
||||||
// mais en enregistrant les handles une fois de plus que nécessaire (à cause de la copie temporaire).
|
// but will register handles one more time (due to temporary copy).
|
||||||
if (m_object)
|
if (m_object)
|
||||||
{
|
{
|
||||||
m_object->UnregisterHandle(this);
|
m_object->UnregisterHandle(this);
|
||||||
|
|
@ -105,11 +163,15 @@ namespace Nz
|
||||||
handle.m_object->RegisterHandle(this);
|
handle.m_object->RegisterHandle(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
// On effectue l'échange
|
// We do the swap
|
||||||
std::swap(m_object, handle.m_object);
|
std::swap(m_object, handle.m_object);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Gives a string representation
|
||||||
|
* \return A string representation of the object "ObjectHandle(object representation) or Null"
|
||||||
|
*/
|
||||||
template<typename T>
|
template<typename T>
|
||||||
Nz::String ObjectHandle<T>::ToString() const
|
Nz::String ObjectHandle<T>::ToString() const
|
||||||
{
|
{
|
||||||
|
|
@ -125,24 +187,44 @@ namespace Nz
|
||||||
return ss;
|
return ss;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Converts the ObjectHandle to bool
|
||||||
|
* \return true if reference is not nullptr
|
||||||
|
*
|
||||||
|
* \see IsValid
|
||||||
|
*/
|
||||||
template<typename T>
|
template<typename T>
|
||||||
ObjectHandle<T>::operator bool() const
|
ObjectHandle<T>::operator bool() const
|
||||||
{
|
{
|
||||||
return IsValid();
|
return IsValid();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Dereferences the ObjectHandle
|
||||||
|
* \return Underlying pointer
|
||||||
|
*/
|
||||||
template<typename T>
|
template<typename T>
|
||||||
ObjectHandle<T>::operator T*() const
|
ObjectHandle<T>::operator T*() const
|
||||||
{
|
{
|
||||||
return m_object;
|
return m_object;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Dereferences the ObjectHandle
|
||||||
|
* \return Underlying pointer
|
||||||
|
*/
|
||||||
template<typename T>
|
template<typename T>
|
||||||
T* ObjectHandle<T>::operator->() const
|
T* ObjectHandle<T>::operator->() const
|
||||||
{
|
{
|
||||||
return m_object;
|
return m_object;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Assigns the entity into this
|
||||||
|
* \return A reference to this
|
||||||
|
*
|
||||||
|
* \param entity Pointer to handle like an object (can be nullptr)
|
||||||
|
*/
|
||||||
template<typename T>
|
template<typename T>
|
||||||
ObjectHandle<T>& ObjectHandle<T>::operator=(T* entity)
|
ObjectHandle<T>& ObjectHandle<T>::operator=(T* entity)
|
||||||
{
|
{
|
||||||
|
|
@ -151,22 +233,37 @@ namespace Nz
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Sets the handle of the ObjectHandle with the handle from another
|
||||||
|
* \return A reference to this
|
||||||
|
*
|
||||||
|
* \param handle The other ObjectHandle
|
||||||
|
*/
|
||||||
template<typename T>
|
template<typename T>
|
||||||
ObjectHandle<T>& ObjectHandle<T>::operator=(const ObjectHandle<T>& handle)
|
ObjectHandle<T>& ObjectHandle<T>::operator=(const ObjectHandle& handle)
|
||||||
{
|
{
|
||||||
Reset(handle);
|
Reset(handle);
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Moves the ObjectHandle into this
|
||||||
|
* \return A reference to this
|
||||||
|
*
|
||||||
|
* \param handle ObjectHandle to move in this
|
||||||
|
*/
|
||||||
template<typename T>
|
template<typename T>
|
||||||
ObjectHandle<T>& ObjectHandle<T>::operator=(ObjectHandle<T>&& handle) noexcept
|
ObjectHandle<T>& ObjectHandle<T>::operator=(ObjectHandle&& handle) noexcept
|
||||||
{
|
{
|
||||||
Reset(std::move(handle));
|
Reset(std::move(handle));
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Action to do on object destruction
|
||||||
|
*/
|
||||||
template<typename T>
|
template<typename T>
|
||||||
void ObjectHandle<T>::OnObjectDestroyed()
|
void ObjectHandle<T>::OnObjectDestroyed()
|
||||||
{
|
{
|
||||||
|
|
@ -174,6 +271,9 @@ namespace Nz
|
||||||
m_object = nullptr;
|
m_object = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Action to do on object move
|
||||||
|
*/
|
||||||
template<typename T>
|
template<typename T>
|
||||||
void ObjectHandle<T>::OnObjectMoved(T* newObject)
|
void ObjectHandle<T>::OnObjectMoved(T* newObject)
|
||||||
{
|
{
|
||||||
|
|
@ -181,114 +281,247 @@ namespace Nz
|
||||||
m_object = newObject;
|
m_object = newObject;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Output operator
|
||||||
|
* \return The stream
|
||||||
|
*
|
||||||
|
* \param out The stream
|
||||||
|
* \param handle The ObjectHandle to output
|
||||||
|
*/
|
||||||
template<typename T>
|
template<typename T>
|
||||||
std::ostream& operator<<(std::ostream& out, const ObjectHandle<T>& handle)
|
std::ostream& operator<<(std::ostream& out, const ObjectHandle<T>& handle)
|
||||||
{
|
{
|
||||||
return handle.ToString();
|
return handle.ToString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Checks whether the first object handle is equal to the second object handle
|
||||||
|
* \return true if it is the case
|
||||||
|
*
|
||||||
|
* \param first ObjectHandle to compare in left hand side
|
||||||
|
* \param second ObjectHandle to compare in right hand side
|
||||||
|
*/
|
||||||
template<typename T>
|
template<typename T>
|
||||||
bool operator==(const ObjectHandle<T>& lhs, const ObjectHandle<T>& rhs)
|
bool operator==(const ObjectHandle<T>& lhs, const ObjectHandle<T>& rhs)
|
||||||
{
|
{
|
||||||
return lhs.GetObject() == rhs.GetObject();
|
return lhs.GetObject() == rhs.GetObject();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Checks whether the object is equal to the second object handle
|
||||||
|
* \return true if it is the case
|
||||||
|
*
|
||||||
|
* \param first Object to compare in left hand side
|
||||||
|
* \param second ObjectHandle to compare in right hand side
|
||||||
|
*/
|
||||||
template<typename T>
|
template<typename T>
|
||||||
bool operator==(const T& lhs, const ObjectHandle<T>& rhs)
|
bool operator==(const T& lhs, const ObjectHandle<T>& rhs)
|
||||||
{
|
{
|
||||||
return &lhs == rhs.GetObject();
|
return &lhs == rhs.GetObject();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Checks whether the object handle is equal to the second object
|
||||||
|
* \return true if it is the case
|
||||||
|
*
|
||||||
|
* \param first ObjectHandle to compare in left hand side
|
||||||
|
* \param second Object to compare in right hand side
|
||||||
|
*/
|
||||||
template<typename T>
|
template<typename T>
|
||||||
bool operator==(const ObjectHandle<T>& lhs, const T& rhs)
|
bool operator==(const ObjectHandle<T>& lhs, const T& rhs)
|
||||||
{
|
{
|
||||||
return lhs.GetObject() == &rhs;
|
return lhs.GetObject() == &rhs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Checks whether the first object handle is equal to the second object handle
|
||||||
|
* \return false if it is the case
|
||||||
|
*
|
||||||
|
* \param first ObjectHandle to compare in left hand side
|
||||||
|
* \param second ObjectHandle to compare in right hand side
|
||||||
|
*/
|
||||||
template<typename T>
|
template<typename T>
|
||||||
bool operator!=(const ObjectHandle<T>& lhs, const ObjectHandle<T>& rhs)
|
bool operator!=(const ObjectHandle<T>& lhs, const ObjectHandle<T>& rhs)
|
||||||
{
|
{
|
||||||
return !(lhs == rhs);
|
return !(lhs == rhs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Checks whether the object is equal to the second object handle
|
||||||
|
* \return false if it is the case
|
||||||
|
*
|
||||||
|
* \param first Object to compare in left hand side
|
||||||
|
* \param second ObjectHandle to compare in right hand side
|
||||||
|
*/
|
||||||
template<typename T>
|
template<typename T>
|
||||||
bool operator!=(const T& lhs, const ObjectHandle<T>& rhs)
|
bool operator!=(const T& lhs, const ObjectHandle<T>& rhs)
|
||||||
{
|
{
|
||||||
return !(lhs == rhs);
|
return !(lhs == rhs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Checks whether the object handle is equal to the second object
|
||||||
|
* \return false if it is the case
|
||||||
|
*
|
||||||
|
* \param first ObjectHandle to compare in left hand side
|
||||||
|
* \param second Object to compare in right hand side
|
||||||
|
*/
|
||||||
template<typename T>
|
template<typename T>
|
||||||
bool operator!=(const ObjectHandle<T>& lhs, const T& rhs)
|
bool operator!=(const ObjectHandle<T>& lhs, const T& rhs)
|
||||||
{
|
{
|
||||||
return !(lhs == rhs);
|
return !(lhs == rhs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Checks whether the first object handle is less than the second object handle
|
||||||
|
* \return true if it is the case
|
||||||
|
*
|
||||||
|
* \param first ObjectHandle to compare in left hand side
|
||||||
|
* \param second ObjectHandle to compare in right hand side
|
||||||
|
*/
|
||||||
template<typename T>
|
template<typename T>
|
||||||
bool operator<(const ObjectHandle<T>& lhs, const ObjectHandle<T>& rhs)
|
bool operator<(const ObjectHandle<T>& lhs, const ObjectHandle<T>& rhs)
|
||||||
{
|
{
|
||||||
return lhs.m_object < rhs.m_object;
|
return lhs.m_object < rhs.m_object;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Checks whether the first object handle is less than the second object handle
|
||||||
|
* \return true if it is the case
|
||||||
|
*
|
||||||
|
* \param first ObjectHandle to compare in left hand side
|
||||||
|
* \param second ObjectHandle to compare in right hand side
|
||||||
|
*/
|
||||||
template<typename T>
|
template<typename T>
|
||||||
bool operator<(const T& lhs, const ObjectHandle<T>& rhs)
|
bool operator<(const T& lhs, const ObjectHandle<T>& rhs)
|
||||||
{
|
{
|
||||||
return &lhs < rhs.m_object;
|
return &lhs < rhs.m_object;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Checks whether the first object handle is less than the second object handle
|
||||||
|
* \return true if it is the case
|
||||||
|
*
|
||||||
|
* \param first ObjectHandle to compare in left hand side
|
||||||
|
* \param second ObjectHandle to compare in right hand side
|
||||||
|
*/
|
||||||
template<typename T>
|
template<typename T>
|
||||||
bool operator<(const ObjectHandle<T>& lhs, const T& rhs)
|
bool operator<(const ObjectHandle<T>& lhs, const T& rhs)
|
||||||
{
|
{
|
||||||
return lhs.m_object < &rhs;
|
return lhs.m_object < &rhs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Checks whether the first object handle is less or equal than the second object handle
|
||||||
|
* \return true if it is the case
|
||||||
|
*
|
||||||
|
* \param first ObjectHandle to compare in left hand side
|
||||||
|
* \param second ObjectHandle to compare in right hand side
|
||||||
|
*/
|
||||||
template<typename T>
|
template<typename T>
|
||||||
bool operator<=(const ObjectHandle<T>& lhs, const ObjectHandle<T>& rhs)
|
bool operator<=(const ObjectHandle<T>& lhs, const ObjectHandle<T>& rhs)
|
||||||
{
|
{
|
||||||
return !(lhs > rhs);
|
return !(lhs > rhs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Checks whether the first object handle is less or equal than the second object handle
|
||||||
|
* \return true if it is the case
|
||||||
|
*
|
||||||
|
* \param first ObjectHandle to compare in left hand side
|
||||||
|
* \param second ObjectHandle to compare in right hand side
|
||||||
|
*/
|
||||||
template<typename T>
|
template<typename T>
|
||||||
bool operator<=(const T& lhs, const ObjectHandle<T>& rhs)
|
bool operator<=(const T& lhs, const ObjectHandle<T>& rhs)
|
||||||
{
|
{
|
||||||
return !(lhs > rhs);
|
return !(lhs > rhs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Checks whether the first object handle is less or equal than the second object handle
|
||||||
|
* \return true if it is the case
|
||||||
|
*
|
||||||
|
* \param first ObjectHandle to compare in left hand side
|
||||||
|
* \param second ObjectHandle to compare in right hand side
|
||||||
|
*/
|
||||||
template<typename T>
|
template<typename T>
|
||||||
bool operator<=(const ObjectHandle<T>& lhs, const T& rhs)
|
bool operator<=(const ObjectHandle<T>& lhs, const T& rhs)
|
||||||
{
|
{
|
||||||
return !(lhs > rhs);
|
return !(lhs > rhs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Checks whether the first object handle is greather than the second object handle
|
||||||
|
* \return true if it is the case
|
||||||
|
*
|
||||||
|
* \param first ObjectHandle to compare in left hand side
|
||||||
|
* \param second ObjectHandle to compare in right hand side
|
||||||
|
*/
|
||||||
template<typename T>
|
template<typename T>
|
||||||
bool operator>(const ObjectHandle<T>& lhs, const ObjectHandle<T>& rhs)
|
bool operator>(const ObjectHandle<T>& lhs, const ObjectHandle<T>& rhs)
|
||||||
{
|
{
|
||||||
return rhs < lhs;
|
return rhs < lhs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Checks whether the first object handle is greather than the second object handle
|
||||||
|
* \return true if it is the case
|
||||||
|
*
|
||||||
|
* \param first ObjectHandle to compare in left hand side
|
||||||
|
* \param second ObjectHandle to compare in right hand side
|
||||||
|
*/
|
||||||
template<typename T>
|
template<typename T>
|
||||||
bool operator>(const T& lhs, const ObjectHandle<T>& rhs)
|
bool operator>(const T& lhs, const ObjectHandle<T>& rhs)
|
||||||
{
|
{
|
||||||
return rhs < lhs;
|
return rhs < lhs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Checks whether the first object handle is greather than the second object handle
|
||||||
|
* \return true if it is the case
|
||||||
|
*
|
||||||
|
* \param first ObjectHandle to compare in left hand side
|
||||||
|
* \param second ObjectHandle to compare in right hand side
|
||||||
|
*/
|
||||||
template<typename T>
|
template<typename T>
|
||||||
bool operator>(const ObjectHandle<T>& lhs, const T& rhs)
|
bool operator>(const ObjectHandle<T>& lhs, const T& rhs)
|
||||||
{
|
{
|
||||||
return rhs < lhs;
|
return rhs < lhs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Checks whether the first object handle is greather or equal than the second object handle
|
||||||
|
* \return true if it is the case
|
||||||
|
*
|
||||||
|
* \param first ObjectHandle to compare in left hand side
|
||||||
|
* \param second ObjectHandle to compare in right hand side
|
||||||
|
*/
|
||||||
template<typename T>
|
template<typename T>
|
||||||
bool operator>=(const ObjectHandle<T>& lhs, const ObjectHandle<T>& rhs)
|
bool operator>=(const ObjectHandle<T>& lhs, const ObjectHandle<T>& rhs)
|
||||||
{
|
{
|
||||||
return !(lhs < rhs);
|
return !(lhs < rhs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Checks whether the first object handle is greather or equal than the second object handle
|
||||||
|
* \return true if it is the case
|
||||||
|
*
|
||||||
|
* \param first ObjectHandle to compare in left hand side
|
||||||
|
* \param second ObjectHandle to compare in right hand side
|
||||||
|
*/
|
||||||
template<typename T>
|
template<typename T>
|
||||||
bool operator>=(const T& lhs, const ObjectHandle<T>& rhs)
|
bool operator>=(const T& lhs, const ObjectHandle<T>& rhs)
|
||||||
{
|
{
|
||||||
return !(lhs < rhs);
|
return !(lhs < rhs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Checks whether the first object handle is greather or equal than the second object handle
|
||||||
|
* \return true if it is the case
|
||||||
|
*
|
||||||
|
* \param first ObjectHandle to compare in left hand side
|
||||||
|
* \param second ObjectHandle to compare in right hand side
|
||||||
|
*/
|
||||||
template<typename T>
|
template<typename T>
|
||||||
bool operator>=(const ObjectHandle<T>& lhs, const T& rhs)
|
bool operator>=(const ObjectHandle<T>& lhs, const T& rhs)
|
||||||
{
|
{
|
||||||
|
|
@ -301,6 +534,12 @@ namespace Nz
|
||||||
|
|
||||||
namespace std
|
namespace std
|
||||||
{
|
{
|
||||||
|
/*!
|
||||||
|
* \brief Swaps two ObjectHandle, specialisation of std
|
||||||
|
*
|
||||||
|
* \param lhs First object handle
|
||||||
|
* \param rhs Second object handle
|
||||||
|
*/
|
||||||
template<typename T>
|
template<typename T>
|
||||||
void swap(Nz::ObjectHandle<T>& lhs, Nz::ObjectHandle<T>& rhs)
|
void swap(Nz::ObjectHandle<T>& lhs, Nz::ObjectHandle<T>& rhs)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -50,6 +50,8 @@ namespace Nz
|
||||||
void SetParameter(const String& name, void* value);
|
void SetParameter(const String& name, void* value);
|
||||||
void SetParameter(const String& name, void* value, Destructor destructor);
|
void SetParameter(const String& name, void* value, Destructor destructor);
|
||||||
|
|
||||||
|
String ToString() const;
|
||||||
|
|
||||||
ParameterList& operator=(const ParameterList& list);
|
ParameterList& operator=(const ParameterList& list);
|
||||||
ParameterList& operator=(ParameterList&&) = default;
|
ParameterList& operator=(ParameterList&&) = default;
|
||||||
|
|
||||||
|
|
@ -73,7 +75,7 @@ namespace Nz
|
||||||
ParameterType type;
|
ParameterType type;
|
||||||
union Value
|
union Value
|
||||||
{
|
{
|
||||||
// On définit un constructeur/destructeur vide, permettant de mettre des classes dans l'union
|
// We define an empty constructor/destructor, to be able to put classes in the union
|
||||||
Value() {}
|
Value() {}
|
||||||
Value(const Value&) {} // Placeholder
|
Value(const Value&) {} // Placeholder
|
||||||
~Value() {}
|
~Value() {}
|
||||||
|
|
@ -98,4 +100,6 @@ namespace Nz
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::ostream& operator<<(std::ostream& out, const Nz::ParameterList& parameterList);
|
||||||
|
|
||||||
#endif // NAZARA_PARAMETERLIST_HPP
|
#endif // NAZARA_PARAMETERLIST_HPP
|
||||||
|
|
|
||||||
|
|
@ -66,7 +66,7 @@ namespace Nz
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
File file(path); // Ouvert seulement en cas de besoin
|
File file(path); // Open only if needed
|
||||||
|
|
||||||
bool found = false;
|
bool found = false;
|
||||||
for (Loader& loader : Type::s_loaders)
|
for (Loader& loader : Type::s_loaders)
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,10 @@
|
||||||
|
|
||||||
namespace Nz
|
namespace Nz
|
||||||
{
|
{
|
||||||
|
/*!
|
||||||
|
* \brief Constructs a Billboard object by default
|
||||||
|
*/
|
||||||
|
|
||||||
inline Billboard::Billboard()
|
inline Billboard::Billboard()
|
||||||
{
|
{
|
||||||
SetColor(Color::White);
|
SetColor(Color::White);
|
||||||
|
|
@ -15,6 +19,12 @@ namespace Nz
|
||||||
SetSize(64.f, 64.f);
|
SetSize(64.f, 64.f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Constructs a Billboard object with a reference to a material
|
||||||
|
*
|
||||||
|
* \param material Reference to a material
|
||||||
|
*/
|
||||||
|
|
||||||
inline Billboard::Billboard(MaterialRef material)
|
inline Billboard::Billboard(MaterialRef material)
|
||||||
{
|
{
|
||||||
SetColor(Color::White);
|
SetColor(Color::White);
|
||||||
|
|
@ -23,6 +33,12 @@ namespace Nz
|
||||||
SetSize(64.f, 64.f);
|
SetSize(64.f, 64.f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Constructs a Billboard object with a pointer to a texture
|
||||||
|
*
|
||||||
|
* \param texture Pointer to a texture
|
||||||
|
*/
|
||||||
|
|
||||||
inline Billboard::Billboard(Texture* texture)
|
inline Billboard::Billboard(Texture* texture)
|
||||||
{
|
{
|
||||||
SetColor(Color::White);
|
SetColor(Color::White);
|
||||||
|
|
@ -31,6 +47,12 @@ namespace Nz
|
||||||
SetTexture(texture, true);
|
SetTexture(texture, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Constructs a Billboard object by assignation
|
||||||
|
*
|
||||||
|
* \param billboard Billboard to copy into this
|
||||||
|
*/
|
||||||
|
|
||||||
inline Billboard::Billboard(const Billboard& billboard) :
|
inline Billboard::Billboard(const Billboard& billboard) :
|
||||||
InstancedRenderable(billboard),
|
InstancedRenderable(billboard),
|
||||||
m_color(billboard.m_color),
|
m_color(billboard.m_color),
|
||||||
|
|
@ -41,31 +63,61 @@ namespace Nz
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Gets the color of the billboard
|
||||||
|
* \return Current color
|
||||||
|
*/
|
||||||
|
|
||||||
inline const Color& Billboard::GetColor() const
|
inline const Color& Billboard::GetColor() const
|
||||||
{
|
{
|
||||||
return m_color;
|
return m_color;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Gets the material of the billboard
|
||||||
|
* \return Current material
|
||||||
|
*/
|
||||||
|
|
||||||
inline const MaterialRef& Billboard::GetMaterial() const
|
inline const MaterialRef& Billboard::GetMaterial() const
|
||||||
{
|
{
|
||||||
return m_material;
|
return m_material;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Gets the rotation of the billboard
|
||||||
|
* \return Current rotation
|
||||||
|
*/
|
||||||
|
|
||||||
inline float Billboard::GetRotation() const
|
inline float Billboard::GetRotation() const
|
||||||
{
|
{
|
||||||
return m_rotation;
|
return m_rotation;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Gets the size of the billboard
|
||||||
|
* \return Current size
|
||||||
|
*/
|
||||||
|
|
||||||
inline const Vector2f& Billboard::GetSize() const
|
inline const Vector2f& Billboard::GetSize() const
|
||||||
{
|
{
|
||||||
return m_size;
|
return m_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Sets the color of the billboard
|
||||||
|
*
|
||||||
|
* \param color Color for the billboard
|
||||||
|
*/
|
||||||
|
|
||||||
inline void Billboard::SetColor(const Color& color)
|
inline void Billboard::SetColor(const Color& color)
|
||||||
{
|
{
|
||||||
m_color = color;
|
m_color = color;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Sets the default material of the billboard (just default material)
|
||||||
|
*/
|
||||||
|
|
||||||
inline void Billboard::SetDefaultMaterial()
|
inline void Billboard::SetDefaultMaterial()
|
||||||
{
|
{
|
||||||
MaterialRef material = Material::New();
|
MaterialRef material = Material::New();
|
||||||
|
|
@ -75,6 +127,13 @@ namespace Nz
|
||||||
SetMaterial(std::move(material));
|
SetMaterial(std::move(material));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Sets the material of the billboard
|
||||||
|
*
|
||||||
|
* \param material Material for the billboard
|
||||||
|
* \param resizeBillboard Should billboard be resized to the material size (diffuse map)
|
||||||
|
*/
|
||||||
|
|
||||||
inline void Billboard::SetMaterial(MaterialRef material, bool resizeBillboard)
|
inline void Billboard::SetMaterial(MaterialRef material, bool resizeBillboard)
|
||||||
{
|
{
|
||||||
m_material = std::move(material);
|
m_material = std::move(material);
|
||||||
|
|
@ -86,25 +145,51 @@ namespace Nz
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Sets the rotation of the billboard
|
||||||
|
*
|
||||||
|
* \param rotation Rotation for the billboard
|
||||||
|
*/
|
||||||
|
|
||||||
inline void Billboard::SetRotation(float rotation)
|
inline void Billboard::SetRotation(float rotation)
|
||||||
{
|
{
|
||||||
m_rotation = rotation;
|
m_rotation = rotation;
|
||||||
m_sinCos.Set(std::sin(m_rotation), std::cos(m_rotation));
|
m_sinCos.Set(std::sin(m_rotation), std::cos(m_rotation));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Sets the size of the billboard
|
||||||
|
*
|
||||||
|
* \param size Size for the billboard
|
||||||
|
*/
|
||||||
|
|
||||||
inline void Billboard::SetSize(const Vector2f& size)
|
inline void Billboard::SetSize(const Vector2f& size)
|
||||||
{
|
{
|
||||||
m_size = size;
|
m_size = size;
|
||||||
|
|
||||||
// On invalide la bounding box
|
// We invalidate the bounding volume
|
||||||
InvalidateBoundingVolume();
|
InvalidateBoundingVolume();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Sets the size of the billboard
|
||||||
|
*
|
||||||
|
* \param sizeX Size in X for the billboard
|
||||||
|
* \param sizeY Size in Y for the billboard
|
||||||
|
*/
|
||||||
|
|
||||||
inline void Billboard::SetSize(float sizeX, float sizeY)
|
inline void Billboard::SetSize(float sizeX, float sizeY)
|
||||||
{
|
{
|
||||||
SetSize(Vector2f(sizeX, sizeY));
|
SetSize(Vector2f(sizeX, sizeY));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Sets the texture of the billboard
|
||||||
|
*
|
||||||
|
* \param texture Texture for the billboard
|
||||||
|
* \param resizeBillboard Should billboard be resized to the texture size
|
||||||
|
*/
|
||||||
|
|
||||||
inline void Billboard::SetTexture(TextureRef texture, bool resizeBillboard)
|
inline void Billboard::SetTexture(TextureRef texture, bool resizeBillboard)
|
||||||
{
|
{
|
||||||
if (!m_material)
|
if (!m_material)
|
||||||
|
|
@ -118,6 +203,13 @@ namespace Nz
|
||||||
m_material->SetDiffuseMap(std::move(texture));
|
m_material->SetDiffuseMap(std::move(texture));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Sets the current billboard with the content of the other one
|
||||||
|
* \return A reference to this
|
||||||
|
*
|
||||||
|
* \param billboard The other Billboard
|
||||||
|
*/
|
||||||
|
|
||||||
inline Billboard& Billboard::operator=(const Billboard& billboard)
|
inline Billboard& Billboard::operator=(const Billboard& billboard)
|
||||||
{
|
{
|
||||||
InstancedRenderable::operator=(billboard);
|
InstancedRenderable::operator=(billboard);
|
||||||
|
|
@ -131,6 +223,13 @@ namespace Nz
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Creates a new billboard from the arguments
|
||||||
|
* \return A reference to the newly created billboard
|
||||||
|
*
|
||||||
|
* \param args Arguments for the billboard
|
||||||
|
*/
|
||||||
|
|
||||||
template<typename... Args>
|
template<typename... Args>
|
||||||
BillboardRef Billboard::New(Args&&... args)
|
BillboardRef Billboard::New(Args&&... args)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,13 @@
|
||||||
|
|
||||||
namespace Nz
|
namespace Nz
|
||||||
{
|
{
|
||||||
|
/*!
|
||||||
|
* \brief Creates a new color background from the arguments
|
||||||
|
* \return A reference to the newly created color background
|
||||||
|
*
|
||||||
|
* \param args Arguments for the color background
|
||||||
|
*/
|
||||||
|
|
||||||
template<typename... Args>
|
template<typename... Args>
|
||||||
ColorBackgroundRef ColorBackground::New(Args&&... args)
|
ColorBackgroundRef ColorBackground::New(Args&&... args)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -27,23 +27,28 @@
|
||||||
#ifndef NAZARA_CONFIG_GRAPHICS_HPP
|
#ifndef NAZARA_CONFIG_GRAPHICS_HPP
|
||||||
#define NAZARA_CONFIG_GRAPHICS_HPP
|
#define NAZARA_CONFIG_GRAPHICS_HPP
|
||||||
|
|
||||||
/// Chaque modification d'un paramètre du module nécessite une recompilation de celui-ci
|
/*!
|
||||||
|
* \defgroup graphics (NazaraGraphics) Graphics module
|
||||||
|
* Graphics/System module including classes to handle graphical elements...
|
||||||
|
*/
|
||||||
|
|
||||||
// À partir de combien d'instances d'un même mesh/matériau l'instancing doit-il être utilisé ?
|
/// Each modification of a paramater of the module needs a recompilation of the unit
|
||||||
|
|
||||||
|
// How much instances are need of a same mesh/material to enable instancing ?
|
||||||
#define NAZARA_GRAPHICS_INSTANCING_MIN_INSTANCES_COUNT 10
|
#define NAZARA_GRAPHICS_INSTANCING_MIN_INSTANCES_COUNT 10
|
||||||
|
|
||||||
// Utilise un manager de mémoire pour gérer les allocations dynamiques (détecte les leaks au prix d'allocations/libérations dynamiques plus lentes)
|
// Use the MemoryManager to manage dynamic allocations (can detect memory leak but allocations/frees are slower)
|
||||||
#define NAZARA_GRAPHICS_MANAGE_MEMORY 0
|
#define NAZARA_GRAPHICS_MANAGE_MEMORY 0
|
||||||
|
|
||||||
// Active les tests de sécurité basés sur le code (Conseillé pour le développement)
|
// Activate the security tests based on the code (Advised for development)
|
||||||
#define NAZARA_GRAPHICS_SAFE 1
|
#define NAZARA_GRAPHICS_SAFE 1
|
||||||
|
|
||||||
/// Chaque modification d'un paramètre ci-dessous implique une modification (souvent mineure) du code
|
/// Each modification of a parameter following implies a modification (often minor) of the code
|
||||||
|
|
||||||
// Le nombre maximum de lumières qu'un shader standard supportera
|
// The maximum number of lights in a standard shader
|
||||||
#define NAZARA_GRAPHICS_MAX_LIGHT_PER_PASS 3
|
#define NAZARA_GRAPHICS_MAX_LIGHT_PER_PASS 3
|
||||||
|
|
||||||
/// Vérification des valeurs et types de certaines constantes
|
/// Checking the values and types of certain constants
|
||||||
#include <Nazara/Graphics/ConfigCheck.hpp>
|
#include <Nazara/Graphics/ConfigCheck.hpp>
|
||||||
|
|
||||||
#if defined(NAZARA_STATIC)
|
#if defined(NAZARA_STATIC)
|
||||||
|
|
|
||||||
|
|
@ -7,12 +7,12 @@
|
||||||
#ifndef NAZARA_CONFIG_CHECK_GRAPHICS_HPP
|
#ifndef NAZARA_CONFIG_CHECK_GRAPHICS_HPP
|
||||||
#define NAZARA_CONFIG_CHECK_GRAPHICS_HPP
|
#define NAZARA_CONFIG_CHECK_GRAPHICS_HPP
|
||||||
|
|
||||||
/// Ce fichier sert à vérifier la valeur des constantes du fichier Config.hpp
|
/// This file is used to check the constant values defined in Config.hpp
|
||||||
|
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
#define NazaraCheckTypeAndVal(name, type, op, val, err) static_assert(std::is_ ##type <decltype(name)>::value && name op val, #type err)
|
#define NazaraCheckTypeAndVal(name, type, op, val, err) static_assert(std::is_ ##type <decltype(name)>::value && name op val, #type err)
|
||||||
|
|
||||||
// On force la valeur de MANAGE_MEMORY en mode debug
|
// We fore the value of MANAGE_MEMORY in debug
|
||||||
#if defined(NAZARA_DEBUG) && !NAZARA_GRAPHICS_MANAGE_MEMORY
|
#if defined(NAZARA_DEBUG) && !NAZARA_GRAPHICS_MANAGE_MEMORY
|
||||||
#undef NAZARA_GRAPHICS_MANAGE_MEMORY
|
#undef NAZARA_GRAPHICS_MANAGE_MEMORY
|
||||||
#define NAZARA_GRAPHICS_MANAGE_MEMORY 0
|
#define NAZARA_GRAPHICS_MANAGE_MEMORY 0
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
// This file is part of the "Nazara Engine - Graphics module"
|
// This file is part of the "Nazara Engine - Graphics module"
|
||||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||||
|
|
||||||
// On suppose que Debug.hpp a déjà été inclus, tout comme Config.hpp
|
// We suppose that Debug.hpp is already included, same goes for Config.hpp
|
||||||
#if NAZARA_GRAPHICS_MANAGE_MEMORY
|
#if NAZARA_GRAPHICS_MANAGE_MEMORY
|
||||||
#undef delete
|
#undef delete
|
||||||
#undef new
|
#undef new
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,7 @@ namespace Nz
|
||||||
float GetBrightThreshold() const;
|
float GetBrightThreshold() const;
|
||||||
Texture* GetTexture(unsigned int i) const;
|
Texture* GetTexture(unsigned int i) const;
|
||||||
|
|
||||||
bool Process(const SceneData& sceneData, unsigned int firstWorkTexture, unsigned secondWorkTexture) const;
|
bool Process(const SceneData& sceneData, unsigned int firstWorkTexture, unsigned int secondWorkTexture) const;
|
||||||
bool Resize(const Vector2ui& dimensions);
|
bool Resize(const Vector2ui& dimensions);
|
||||||
|
|
||||||
void SetBlurPassCount(unsigned int passCount);
|
void SetBlurPassCount(unsigned int passCount);
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@ namespace Nz
|
||||||
DeferredDOFPass();
|
DeferredDOFPass();
|
||||||
virtual ~DeferredDOFPass();
|
virtual ~DeferredDOFPass();
|
||||||
|
|
||||||
bool Process(const SceneData& sceneData, unsigned int firstWorkTexture, unsigned secondWorkTexture) const;
|
bool Process(const SceneData& sceneData, unsigned int firstWorkTexture, unsigned int secondWorkTexture) const;
|
||||||
bool Resize(const Vector2ui& dimensions);
|
bool Resize(const Vector2ui& dimensions);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@ namespace Nz
|
||||||
DeferredFXAAPass();
|
DeferredFXAAPass();
|
||||||
virtual ~DeferredFXAAPass();
|
virtual ~DeferredFXAAPass();
|
||||||
|
|
||||||
bool Process(const SceneData& sceneData, unsigned int firstWorkTexture, unsigned secondWorkTexture) const;
|
bool Process(const SceneData& sceneData, unsigned int firstWorkTexture, unsigned int secondWorkTexture) const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
RenderStates m_states;
|
RenderStates m_states;
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@ namespace Nz
|
||||||
DeferredFinalPass();
|
DeferredFinalPass();
|
||||||
virtual ~DeferredFinalPass();
|
virtual ~DeferredFinalPass();
|
||||||
|
|
||||||
bool Process(const SceneData& sceneData, unsigned int firstWorkTexture, unsigned secondWorkTexture) const;
|
bool Process(const SceneData& sceneData, unsigned int firstWorkTexture, unsigned int secondWorkTexture) const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
RenderStates m_states;
|
RenderStates m_states;
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@ namespace Nz
|
||||||
DeferredFogPass();
|
DeferredFogPass();
|
||||||
virtual ~DeferredFogPass();
|
virtual ~DeferredFogPass();
|
||||||
|
|
||||||
bool Process(const SceneData& sceneData, unsigned int firstWorkTexture, unsigned secondWorkTexture) const;
|
bool Process(const SceneData& sceneData, unsigned int firstWorkTexture, unsigned int secondWorkTexture) const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
RenderStates m_states;
|
RenderStates m_states;
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@ namespace Nz
|
||||||
virtual ~DeferredForwardPass();
|
virtual ~DeferredForwardPass();
|
||||||
|
|
||||||
void Initialize(DeferredRenderTechnique* technique);
|
void Initialize(DeferredRenderTechnique* technique);
|
||||||
bool Process(const SceneData& sceneData, unsigned int workTexture, unsigned sceneTexture) const;
|
bool Process(const SceneData& sceneData, unsigned int workTexture, unsigned int sceneTexture) const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
const ForwardRenderTechnique* m_forwardTechnique;
|
const ForwardRenderTechnique* m_forwardTechnique;
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@ namespace Nz
|
||||||
DeferredGeometryPass();
|
DeferredGeometryPass();
|
||||||
virtual ~DeferredGeometryPass();
|
virtual ~DeferredGeometryPass();
|
||||||
|
|
||||||
bool Process(const SceneData& sceneData, unsigned int firstWorkTexture, unsigned secondWorkTexture) const;
|
bool Process(const SceneData& sceneData, unsigned int firstWorkTexture, unsigned int secondWorkTexture) const;
|
||||||
bool Resize(const Vector2ui& dimensions);
|
bool Resize(const Vector2ui& dimensions);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,7 @@ namespace Nz
|
||||||
|
|
||||||
bool IsLightMeshesDrawingEnabled() const;
|
bool IsLightMeshesDrawingEnabled() const;
|
||||||
|
|
||||||
bool Process(const SceneData& sceneData, unsigned int firstWorkTexture, unsigned secondWorkTexture) const;
|
bool Process(const SceneData& sceneData, unsigned int firstWorkTexture, unsigned int secondWorkTexture) const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
LightUniforms m_directionalLightUniforms;
|
LightUniforms m_directionalLightUniforms;
|
||||||
|
|
|
||||||
|
|
@ -38,7 +38,7 @@ namespace Nz
|
||||||
|
|
||||||
bool IsEnabled() const;
|
bool IsEnabled() const;
|
||||||
|
|
||||||
virtual bool Process(const SceneData& sceneData, unsigned int workTexture, unsigned sceneTexture) const = 0;
|
virtual bool Process(const SceneData& sceneData, unsigned int workTexture, unsigned int sceneTexture) const = 0;
|
||||||
virtual bool Resize(const Vector2ui& GBufferSize);
|
virtual bool Resize(const Vector2ui& GBufferSize);
|
||||||
|
|
||||||
DeferredRenderPass& operator=(const DeferredRenderPass&) = delete;
|
DeferredRenderPass& operator=(const DeferredRenderPass&) = delete;
|
||||||
|
|
|
||||||
|
|
@ -67,7 +67,7 @@ namespace Nz
|
||||||
};
|
};
|
||||||
|
|
||||||
std::map<RenderPassType, std::map<int, std::unique_ptr<DeferredRenderPass>>, RenderPassComparator> m_passes;
|
std::map<RenderPassType, std::map<int, std::unique_ptr<DeferredRenderPass>>, RenderPassComparator> m_passes;
|
||||||
ForwardRenderTechnique m_forwardTechnique; // Doit être initialisé avant la RenderQueue
|
ForwardRenderTechnique m_forwardTechnique; // Must be initialized before the RenderQueue
|
||||||
DeferredRenderQueue m_renderQueue;
|
DeferredRenderQueue m_renderQueue;
|
||||||
mutable RenderBufferRef m_depthStencilBuffer;
|
mutable RenderBufferRef m_depthStencilBuffer;
|
||||||
mutable RenderTexture m_GBufferRTT;
|
mutable RenderTexture m_GBufferRTT;
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,14 @@
|
||||||
|
|
||||||
namespace Nz
|
namespace Nz
|
||||||
{
|
{
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Checks whether the material is suitable to fit in the render queue
|
||||||
|
* \return true If it is the case
|
||||||
|
*
|
||||||
|
* \param material Material to verify
|
||||||
|
*/
|
||||||
|
|
||||||
bool DepthRenderQueue::IsMaterialSuitable(const Material* material) const
|
bool DepthRenderQueue::IsMaterialSuitable(const Material* material) const
|
||||||
{
|
{
|
||||||
NazaraAssert(material, "Invalid material");
|
NazaraAssert(material, "Invalid material");
|
||||||
|
|
|
||||||
|
|
@ -128,7 +128,7 @@ namespace Nz
|
||||||
SceneNodeType_Max = SceneNodeType_User
|
SceneNodeType_Max = SceneNodeType_User
|
||||||
};
|
};
|
||||||
|
|
||||||
// Ces paramètres sont indépendants du matériau: ils peuvent être demandés à tout moment
|
// These parameters are independant of the material: they can not be asked for the moment
|
||||||
enum ShaderFlags
|
enum ShaderFlags
|
||||||
{
|
{
|
||||||
ShaderFlags_None = 0,
|
ShaderFlags_None = 0,
|
||||||
|
|
|
||||||
|
|
@ -159,6 +159,7 @@ namespace Nz
|
||||||
std::map<int, Layer> layers;
|
std::map<int, Layer> layers;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
BillboardData* GetBillboardData(int renderOrder, const Material* material, unsigned int count);
|
||||||
Layer& GetLayer(int i); ///TODO: Inline
|
Layer& GetLayer(int i); ///TODO: Inline
|
||||||
|
|
||||||
void OnIndexBufferInvalidation(const IndexBuffer* indexBuffer);
|
void OnIndexBufferInvalidation(const IndexBuffer* indexBuffer);
|
||||||
|
|
|
||||||
|
|
@ -31,7 +31,7 @@ namespace Nz
|
||||||
AbstractRenderQueue* GetRenderQueue() override;
|
AbstractRenderQueue* GetRenderQueue() override;
|
||||||
RenderTechniqueType GetType() const override;
|
RenderTechniqueType GetType() const override;
|
||||||
|
|
||||||
void SetMaxLightPassPerObject(unsigned int passCount);
|
void SetMaxLightPassPerObject(unsigned int maxLightPassPerObject);
|
||||||
|
|
||||||
static bool Initialize();
|
static bool Initialize();
|
||||||
static void Uninitialize();
|
static void Uninitialize();
|
||||||
|
|
@ -70,11 +70,11 @@ namespace Nz
|
||||||
LightUniforms lightUniforms;
|
LightUniforms lightUniforms;
|
||||||
bool hasLightUniforms;
|
bool hasLightUniforms;
|
||||||
|
|
||||||
/// Moins coûteux en mémoire que de stocker un LightUniforms par index de lumière,
|
/// Less costly in memory than storing a LightUniforms by index of light,
|
||||||
/// à voir si ça fonctionne chez tout le monde
|
/// this may not work everywhere
|
||||||
int lightOffset; // "Distance" entre Lights[0].type et Lights[1].type
|
int lightOffset; // "Distance" between Lights[0].type and Lights[1].type
|
||||||
|
|
||||||
// Autre uniformes
|
// Other uniforms
|
||||||
int eyePosition;
|
int eyePosition;
|
||||||
int sceneAmbient;
|
int sceneAmbient;
|
||||||
int textureOverlay;
|
int textureOverlay;
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,16 @@
|
||||||
|
|
||||||
namespace Nz
|
namespace Nz
|
||||||
{
|
{
|
||||||
|
/*!
|
||||||
|
* \brief Sens the uniforms for light
|
||||||
|
*
|
||||||
|
* \param shader Shader to send uniforms to
|
||||||
|
* \param uniforms Uniforms to send
|
||||||
|
* \param index Index of the light
|
||||||
|
* \param uniformOffset Offset for the uniform
|
||||||
|
* \param availableTextureUnit Unit texture available
|
||||||
|
*/
|
||||||
|
|
||||||
inline void ForwardRenderTechnique::SendLightUniforms(const Shader* shader, const LightUniforms& uniforms, unsigned int index, unsigned int uniformOffset, UInt8 availableTextureUnit) const
|
inline void ForwardRenderTechnique::SendLightUniforms(const Shader* shader, const LightUniforms& uniforms, unsigned int index, unsigned int uniformOffset, UInt8 availableTextureUnit) const
|
||||||
{
|
{
|
||||||
// If anyone got a better idea..
|
// If anyone got a better idea..
|
||||||
|
|
@ -104,6 +114,14 @@ namespace Nz
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Computes the score for directional light
|
||||||
|
* \return 0.f
|
||||||
|
*
|
||||||
|
* \param object Sphere symbolising the object
|
||||||
|
* \param light Light to compute
|
||||||
|
*/
|
||||||
|
|
||||||
inline float ForwardRenderTechnique::ComputeDirectionalLightScore(const Spheref& object, const AbstractRenderQueue::DirectionalLight& light)
|
inline float ForwardRenderTechnique::ComputeDirectionalLightScore(const Spheref& object, const AbstractRenderQueue::DirectionalLight& light)
|
||||||
{
|
{
|
||||||
NazaraUnused(object);
|
NazaraUnused(object);
|
||||||
|
|
@ -113,18 +131,42 @@ namespace Nz
|
||||||
return 0.f;
|
return 0.f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Computes the score for point light
|
||||||
|
* \return Distance to the light
|
||||||
|
*
|
||||||
|
* \param object Sphere symbolising the object
|
||||||
|
* \param light Light to compute
|
||||||
|
*/
|
||||||
|
|
||||||
inline float ForwardRenderTechnique::ComputePointLightScore(const Spheref& object, const AbstractRenderQueue::PointLight& light)
|
inline float ForwardRenderTechnique::ComputePointLightScore(const Spheref& object, const AbstractRenderQueue::PointLight& light)
|
||||||
{
|
{
|
||||||
///TODO: Compute a score depending on the light luminosity
|
///TODO: Compute a score depending on the light luminosity
|
||||||
return object.SquaredDistance(light.position);
|
return object.SquaredDistance(light.position);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Computes the score for spot light
|
||||||
|
* \return Distance to the light
|
||||||
|
*
|
||||||
|
* \param object Sphere symbolising the object
|
||||||
|
* \param light Light to compute
|
||||||
|
*/
|
||||||
|
|
||||||
inline float ForwardRenderTechnique::ComputeSpotLightScore(const Spheref& object, const AbstractRenderQueue::SpotLight& light)
|
inline float ForwardRenderTechnique::ComputeSpotLightScore(const Spheref& object, const AbstractRenderQueue::SpotLight& light)
|
||||||
{
|
{
|
||||||
///TODO: Compute a score depending on the light luminosity and spot direction
|
///TODO: Compute a score depending on the light luminosity and spot direction
|
||||||
return object.SquaredDistance(light.position);
|
return object.SquaredDistance(light.position);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Checks whether the directional light is suitable for the computations
|
||||||
|
* \return true if light is enoughly close
|
||||||
|
*
|
||||||
|
* \param object Sphere symbolising the object
|
||||||
|
* \param light Light to compute
|
||||||
|
*/
|
||||||
|
|
||||||
inline bool ForwardRenderTechnique::IsDirectionalLightSuitable(const Spheref& object, const AbstractRenderQueue::DirectionalLight& light)
|
inline bool ForwardRenderTechnique::IsDirectionalLightSuitable(const Spheref& object, const AbstractRenderQueue::DirectionalLight& light)
|
||||||
{
|
{
|
||||||
NazaraUnused(object);
|
NazaraUnused(object);
|
||||||
|
|
@ -134,12 +176,28 @@ namespace Nz
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Checks whether the point light is suitable for the computations
|
||||||
|
* \return true if light is enoughly close
|
||||||
|
*
|
||||||
|
* \param object Sphere symbolising the object
|
||||||
|
* \param light Light to compute
|
||||||
|
*/
|
||||||
|
|
||||||
inline bool ForwardRenderTechnique::IsPointLightSuitable(const Spheref& object, const AbstractRenderQueue::PointLight& light)
|
inline bool ForwardRenderTechnique::IsPointLightSuitable(const Spheref& object, const AbstractRenderQueue::PointLight& light)
|
||||||
{
|
{
|
||||||
// If the object is too far away from this point light, there is not way it could light it
|
// If the object is too far away from this point light, there is not way it could light it
|
||||||
return object.SquaredDistance(light.position) <= light.radius * light.radius;
|
return object.SquaredDistance(light.position) <= light.radius * light.radius;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Checks whether the spot light is suitable for the computations
|
||||||
|
* \return true if light is enoughly close
|
||||||
|
*
|
||||||
|
* \param object Sphere symbolising the object
|
||||||
|
* \param light Light to compute
|
||||||
|
*/
|
||||||
|
|
||||||
inline bool ForwardRenderTechnique::IsSpotLightSuitable(const Spheref& object, const AbstractRenderQueue::SpotLight& light)
|
inline bool ForwardRenderTechnique::IsSpotLightSuitable(const Spheref& object, const AbstractRenderQueue::SpotLight& light)
|
||||||
{
|
{
|
||||||
///TODO: Exclude spot lights based on their direction and outer angle?
|
///TODO: Exclude spot lights based on their direction and outer angle?
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,12 @@
|
||||||
|
|
||||||
namespace Nz
|
namespace Nz
|
||||||
{
|
{
|
||||||
|
/*!
|
||||||
|
* \brief Constructs a InstancedRenderable object by assignation
|
||||||
|
*
|
||||||
|
* \param renderable InstancedRenderable to copy into this
|
||||||
|
*/
|
||||||
|
|
||||||
inline InstancedRenderable::InstancedRenderable(const InstancedRenderable& renderable) :
|
inline InstancedRenderable::InstancedRenderable(const InstancedRenderable& renderable) :
|
||||||
RefCounted(),
|
RefCounted(),
|
||||||
m_boundingVolume(renderable.m_boundingVolume),
|
m_boundingVolume(renderable.m_boundingVolume),
|
||||||
|
|
@ -11,22 +17,43 @@ namespace Nz
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Ensures that the bounding volume is up to date
|
||||||
|
*/
|
||||||
|
|
||||||
inline void InstancedRenderable::EnsureBoundingVolumeUpdated() const
|
inline void InstancedRenderable::EnsureBoundingVolumeUpdated() const
|
||||||
{
|
{
|
||||||
if (!m_boundingVolumeUpdated)
|
if (!m_boundingVolumeUpdated)
|
||||||
UpdateBoundingVolume();
|
UpdateBoundingVolume();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Invalidates the bounding volume
|
||||||
|
*/
|
||||||
|
|
||||||
inline void InstancedRenderable::InvalidateBoundingVolume()
|
inline void InstancedRenderable::InvalidateBoundingVolume()
|
||||||
{
|
{
|
||||||
m_boundingVolumeUpdated = false;
|
m_boundingVolumeUpdated = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Invalidates the instance data based on flags
|
||||||
|
*
|
||||||
|
* \param flags Flags to invalidate
|
||||||
|
*/
|
||||||
|
|
||||||
inline void InstancedRenderable::InvalidateInstanceData(UInt32 flags)
|
inline void InstancedRenderable::InvalidateInstanceData(UInt32 flags)
|
||||||
{
|
{
|
||||||
OnInstancedRenderableInvalidateData(this, flags);
|
OnInstancedRenderableInvalidateData(this, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Sets the current instanced renderable with the content of the other one
|
||||||
|
* \return A reference to this
|
||||||
|
*
|
||||||
|
* \param renderable The other InstancedRenderable
|
||||||
|
*/
|
||||||
|
|
||||||
inline InstancedRenderable& InstancedRenderable::operator=(const InstancedRenderable& renderable)
|
inline InstancedRenderable& InstancedRenderable::operator=(const InstancedRenderable& renderable)
|
||||||
{
|
{
|
||||||
m_boundingVolume = renderable.m_boundingVolume;
|
m_boundingVolume = renderable.m_boundingVolume;
|
||||||
|
|
@ -35,6 +62,10 @@ namespace Nz
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Updates the bounding volume
|
||||||
|
*/
|
||||||
|
|
||||||
inline void InstancedRenderable::UpdateBoundingVolume() const
|
inline void InstancedRenderable::UpdateBoundingVolume() const
|
||||||
{
|
{
|
||||||
MakeBoundingVolume();
|
MakeBoundingVolume();
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,10 @@
|
||||||
|
|
||||||
namespace Nz
|
namespace Nz
|
||||||
{
|
{
|
||||||
|
/*!
|
||||||
|
* \brief Constructs a Light object by default
|
||||||
|
*/
|
||||||
|
|
||||||
inline Light::Light(const Light& light) :
|
inline Light::Light(const Light& light) :
|
||||||
Renderable(light),
|
Renderable(light),
|
||||||
m_color(light.m_color),
|
m_color(light.m_color),
|
||||||
|
|
@ -28,6 +32,12 @@ namespace Nz
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Enables shadow casting
|
||||||
|
*
|
||||||
|
* \param castShadows Should shadows be cast
|
||||||
|
*/
|
||||||
|
|
||||||
inline void Light::EnableShadowCasting(bool castShadows)
|
inline void Light::EnableShadowCasting(bool castShadows)
|
||||||
{
|
{
|
||||||
if (m_shadowCastingEnabled != castShadows)
|
if (m_shadowCastingEnabled != castShadows)
|
||||||
|
|
@ -37,72 +47,141 @@ namespace Nz
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Ensures that the shadow map is up to date
|
||||||
|
*/
|
||||||
|
|
||||||
inline void Light::EnsureShadowMapUpdate() const
|
inline void Light::EnsureShadowMapUpdate() const
|
||||||
{
|
{
|
||||||
if (!m_shadowMapUpdated)
|
if (!m_shadowMapUpdated)
|
||||||
UpdateShadowMap();
|
UpdateShadowMap();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Gets the ambient factor
|
||||||
|
* \return Current ambient factor
|
||||||
|
*/
|
||||||
|
|
||||||
inline float Light::GetAmbientFactor() const
|
inline float Light::GetAmbientFactor() const
|
||||||
{
|
{
|
||||||
return m_ambientFactor;
|
return m_ambientFactor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Gets the light attenuation (in 1 / R^2)
|
||||||
|
* \return Attenuation
|
||||||
|
*/
|
||||||
|
|
||||||
inline float Light::GetAttenuation() const
|
inline float Light::GetAttenuation() const
|
||||||
{
|
{
|
||||||
return m_attenuation;
|
return m_attenuation;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Gets the color of the light
|
||||||
|
* \return Light color
|
||||||
|
*/
|
||||||
|
|
||||||
inline Color Light::GetColor() const
|
inline Color Light::GetColor() const
|
||||||
{
|
{
|
||||||
return m_color;
|
return m_color;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Gets the diffuse factor
|
||||||
|
* \return Current diffuse factor
|
||||||
|
*/
|
||||||
|
|
||||||
inline float Light::GetDiffuseFactor() const
|
inline float Light::GetDiffuseFactor() const
|
||||||
{
|
{
|
||||||
return m_diffuseFactor;
|
return m_diffuseFactor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Gets the inner angle in spot light
|
||||||
|
* \return Inner angle
|
||||||
|
*/
|
||||||
|
|
||||||
inline float Light::GetInnerAngle() const
|
inline float Light::GetInnerAngle() const
|
||||||
{
|
{
|
||||||
return m_innerAngle;
|
return m_innerAngle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Gets the cosine inner angle in spot light
|
||||||
|
* \return Cosine inner angle
|
||||||
|
*/
|
||||||
|
|
||||||
inline float Light::GetInnerAngleCosine() const
|
inline float Light::GetInnerAngleCosine() const
|
||||||
{
|
{
|
||||||
return m_innerAngleCosine;
|
return m_innerAngleCosine;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Gets the inverse of the radius
|
||||||
|
* \return Inverse of the radius
|
||||||
|
*/
|
||||||
|
|
||||||
inline float Light::GetInvRadius() const
|
inline float Light::GetInvRadius() const
|
||||||
{
|
{
|
||||||
return m_invRadius;
|
return m_invRadius;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Gets the type of the light
|
||||||
|
* \return Light type
|
||||||
|
*/
|
||||||
|
|
||||||
inline LightType Light::GetLightType() const
|
inline LightType Light::GetLightType() const
|
||||||
{
|
{
|
||||||
return m_type;
|
return m_type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Gets the outer angle in spot light
|
||||||
|
* \return Outer angle
|
||||||
|
*/
|
||||||
|
|
||||||
inline float Light::GetOuterAngle() const
|
inline float Light::GetOuterAngle() const
|
||||||
{
|
{
|
||||||
return m_outerAngle;
|
return m_outerAngle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Gets the cosine outer angle in spot light
|
||||||
|
* \return Cosine outer angle
|
||||||
|
*/
|
||||||
|
|
||||||
inline float Light::GetOuterAngleCosine() const
|
inline float Light::GetOuterAngleCosine() const
|
||||||
{
|
{
|
||||||
return m_outerAngleCosine;
|
return m_outerAngleCosine;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Gets the tangent outer angle in spot light
|
||||||
|
* \return Tangent outer angle
|
||||||
|
*/
|
||||||
|
|
||||||
inline float Light::GetOuterAngleTangent() const
|
inline float Light::GetOuterAngleTangent() const
|
||||||
{
|
{
|
||||||
return m_outerAngleTangent;
|
return m_outerAngleTangent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Gets the radius of the light
|
||||||
|
* \return Light radius
|
||||||
|
*/
|
||||||
|
|
||||||
inline float Light::GetRadius() const
|
inline float Light::GetRadius() const
|
||||||
{
|
{
|
||||||
return m_radius;
|
return m_radius;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Gets the shadow map
|
||||||
|
* \return Reference to the shadow map texture
|
||||||
|
*/
|
||||||
|
|
||||||
inline TextureRef Light::GetShadowMap() const
|
inline TextureRef Light::GetShadowMap() const
|
||||||
{
|
{
|
||||||
EnsureShadowMapUpdate();
|
EnsureShadowMapUpdate();
|
||||||
|
|
@ -110,47 +189,97 @@ namespace Nz
|
||||||
return m_shadowMap;
|
return m_shadowMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Gets the format of the shadow map
|
||||||
|
* \return Shadow map format
|
||||||
|
*/
|
||||||
|
|
||||||
inline PixelFormatType Light::GetShadowMapFormat() const
|
inline PixelFormatType Light::GetShadowMapFormat() const
|
||||||
{
|
{
|
||||||
return m_shadowMapFormat;
|
return m_shadowMapFormat;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Gets the size of the shadow map
|
||||||
|
* \return Shadow map size
|
||||||
|
*/
|
||||||
|
|
||||||
inline const Vector2ui& Light::GetShadowMapSize() const
|
inline const Vector2ui& Light::GetShadowMapSize() const
|
||||||
{
|
{
|
||||||
return m_shadowMapSize;
|
return m_shadowMapSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Checks whether the shadow casting is enabled
|
||||||
|
* \return true If it is the case
|
||||||
|
*/
|
||||||
|
|
||||||
inline bool Light::IsShadowCastingEnabled() const
|
inline bool Light::IsShadowCastingEnabled() const
|
||||||
{
|
{
|
||||||
return m_shadowCastingEnabled;
|
return m_shadowCastingEnabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Sets the ambient factor
|
||||||
|
*
|
||||||
|
* \param factor Ambient factor
|
||||||
|
*/
|
||||||
|
|
||||||
inline void Light::SetAmbientFactor(float factor)
|
inline void Light::SetAmbientFactor(float factor)
|
||||||
{
|
{
|
||||||
m_ambientFactor = factor;
|
m_ambientFactor = factor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Sets the light attenuation (in 1 / R^2)
|
||||||
|
*
|
||||||
|
* \param attenuation Light attenuation
|
||||||
|
*/
|
||||||
|
|
||||||
inline void Light::SetAttenuation(float attenuation)
|
inline void Light::SetAttenuation(float attenuation)
|
||||||
{
|
{
|
||||||
m_attenuation = attenuation;
|
m_attenuation = attenuation;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Sets the color of the light
|
||||||
|
*
|
||||||
|
* \param color Light color
|
||||||
|
*/
|
||||||
|
|
||||||
inline void Light::SetColor(const Color& color)
|
inline void Light::SetColor(const Color& color)
|
||||||
{
|
{
|
||||||
m_color = color;
|
m_color = color;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Sets the diffuse factor
|
||||||
|
*
|
||||||
|
* \param factor Diffuse factor
|
||||||
|
*/
|
||||||
|
|
||||||
inline void Light::SetDiffuseFactor(float factor)
|
inline void Light::SetDiffuseFactor(float factor)
|
||||||
{
|
{
|
||||||
m_diffuseFactor = factor;
|
m_diffuseFactor = factor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Sets the inner angle in spot light
|
||||||
|
* \return innerAngle Inner angle
|
||||||
|
*/
|
||||||
|
|
||||||
inline void Light::SetInnerAngle(float innerAngle)
|
inline void Light::SetInnerAngle(float innerAngle)
|
||||||
{
|
{
|
||||||
m_innerAngle = innerAngle;
|
m_innerAngle = innerAngle;
|
||||||
m_innerAngleCosine = std::cos(DegreeToRadian(m_innerAngle));
|
m_innerAngleCosine = std::cos(DegreeToRadian(m_innerAngle));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Sets the type of light
|
||||||
|
*
|
||||||
|
* \param type Light type
|
||||||
|
*/
|
||||||
|
|
||||||
inline void Light::SetLightType(LightType type)
|
inline void Light::SetLightType(LightType type)
|
||||||
{
|
{
|
||||||
m_type = type;
|
m_type = type;
|
||||||
|
|
@ -158,6 +287,13 @@ namespace Nz
|
||||||
InvalidateShadowMap();
|
InvalidateShadowMap();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Sets the outer angle in spot light
|
||||||
|
* \return outerAngle Outer angle
|
||||||
|
*
|
||||||
|
* \remark Invalidates the bounding volume
|
||||||
|
*/
|
||||||
|
|
||||||
inline void Light::SetOuterAngle(float outerAngle)
|
inline void Light::SetOuterAngle(float outerAngle)
|
||||||
{
|
{
|
||||||
m_outerAngle = outerAngle;
|
m_outerAngle = outerAngle;
|
||||||
|
|
@ -167,6 +303,13 @@ namespace Nz
|
||||||
InvalidateBoundingVolume();
|
InvalidateBoundingVolume();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Sets the radius of the light
|
||||||
|
* \return radius Light radius
|
||||||
|
*
|
||||||
|
* \remark Invalidates the bounding volume
|
||||||
|
*/
|
||||||
|
|
||||||
inline void Light::SetRadius(float radius)
|
inline void Light::SetRadius(float radius)
|
||||||
{
|
{
|
||||||
m_radius = radius;
|
m_radius = radius;
|
||||||
|
|
@ -176,6 +319,15 @@ namespace Nz
|
||||||
InvalidateBoundingVolume();
|
InvalidateBoundingVolume();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Sets the shadow map format
|
||||||
|
*
|
||||||
|
* \param shadowFormat Shadow map format
|
||||||
|
*
|
||||||
|
* \remark Invalidates the shadow map
|
||||||
|
* \remark Produces a NazaraAssert if format is not a depth type
|
||||||
|
*/
|
||||||
|
|
||||||
inline void Light::SetShadowMapFormat(PixelFormatType shadowFormat)
|
inline void Light::SetShadowMapFormat(PixelFormatType shadowFormat)
|
||||||
{
|
{
|
||||||
NazaraAssert(PixelFormat::GetContent(shadowFormat) == PixelFormatContent_DepthStencil, "Shadow format type is not a depth format");
|
NazaraAssert(PixelFormat::GetContent(shadowFormat) == PixelFormatContent_DepthStencil, "Shadow format type is not a depth format");
|
||||||
|
|
@ -185,6 +337,15 @@ namespace Nz
|
||||||
InvalidateShadowMap();
|
InvalidateShadowMap();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Sets the size of the shadow map
|
||||||
|
*
|
||||||
|
* \param size Shadow map size
|
||||||
|
*
|
||||||
|
* \remark Invalidates the shadow map
|
||||||
|
* \remark Produces a NazaraAssert if size is zero
|
||||||
|
*/
|
||||||
|
|
||||||
inline void Light::SetShadowMapSize(const Vector2ui& size)
|
inline void Light::SetShadowMapSize(const Vector2ui& size)
|
||||||
{
|
{
|
||||||
NazaraAssert(size.x > 0 && size.y > 0, "Shadow map size must have a positive size");
|
NazaraAssert(size.x > 0 && size.y > 0, "Shadow map size must have a positive size");
|
||||||
|
|
@ -194,6 +355,15 @@ namespace Nz
|
||||||
InvalidateShadowMap();
|
InvalidateShadowMap();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Sets the current light with the content of the other one
|
||||||
|
* \return A reference to this
|
||||||
|
*
|
||||||
|
* \param light The other Light
|
||||||
|
*
|
||||||
|
* \remark Invalidates the shadow map
|
||||||
|
*/
|
||||||
|
|
||||||
inline Light& Light::operator=(const Light& light)
|
inline Light& Light::operator=(const Light& light)
|
||||||
{
|
{
|
||||||
Renderable::operator=(light);
|
Renderable::operator=(light);
|
||||||
|
|
@ -218,6 +388,10 @@ namespace Nz
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Invalidates the shadow map
|
||||||
|
*/
|
||||||
|
|
||||||
inline void Light::InvalidateShadowMap()
|
inline void Light::InvalidateShadowMap()
|
||||||
{
|
{
|
||||||
m_shadowMapUpdated = false;
|
m_shadowMapUpdated = false;
|
||||||
|
|
|
||||||
|
|
@ -151,7 +151,7 @@ namespace Nz
|
||||||
|
|
||||||
inline Material& operator=(const Material& material);
|
inline Material& operator=(const Material& material);
|
||||||
|
|
||||||
static MaterialRef GetDefault();
|
inline static MaterialRef GetDefault();
|
||||||
template<typename... Args> static MaterialRef New(Args&&... args);
|
template<typename... Args> static MaterialRef New(Args&&... args);
|
||||||
|
|
||||||
// Signals:
|
// Signals:
|
||||||
|
|
|
||||||
|
|
@ -7,11 +7,21 @@
|
||||||
|
|
||||||
namespace Nz
|
namespace Nz
|
||||||
{
|
{
|
||||||
|
/*!
|
||||||
|
* \brief Constructs a Material object by default
|
||||||
|
*/
|
||||||
|
|
||||||
inline Material::Material()
|
inline Material::Material()
|
||||||
{
|
{
|
||||||
Reset();
|
Reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Constructs a Material object by assignation
|
||||||
|
*
|
||||||
|
* \param material Material to copy into this
|
||||||
|
*/
|
||||||
|
|
||||||
inline Material::Material(const Material& material) :
|
inline Material::Material(const Material& material) :
|
||||||
RefCounted(),
|
RefCounted(),
|
||||||
Resource(material)
|
Resource(material)
|
||||||
|
|
@ -19,11 +29,26 @@ namespace Nz
|
||||||
Copy(material);
|
Copy(material);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Destructs the object and calls OnMaterialRelease
|
||||||
|
*
|
||||||
|
* \see OnMaterialRelease
|
||||||
|
*/
|
||||||
|
|
||||||
inline Material::~Material()
|
inline Material::~Material()
|
||||||
{
|
{
|
||||||
OnMaterialRelease(this);
|
OnMaterialRelease(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Enables a renderer parameter
|
||||||
|
*
|
||||||
|
* \param renderParameter Parameter for the rendering
|
||||||
|
* \param enable Should the parameter be enabled
|
||||||
|
*
|
||||||
|
* \remark Produces a NazaraAssert if enumeration is invalid
|
||||||
|
*/
|
||||||
|
|
||||||
inline void Material::Enable(RendererParameter renderParameter, bool enable)
|
inline void Material::Enable(RendererParameter renderParameter, bool enable)
|
||||||
{
|
{
|
||||||
NazaraAssert(renderParameter <= RendererParameter_Max, "Renderer parameter out of enum");
|
NazaraAssert(renderParameter <= RendererParameter_Max, "Renderer parameter out of enum");
|
||||||
|
|
@ -31,6 +56,14 @@ namespace Nz
|
||||||
m_states.parameters[renderParameter] = enable;
|
m_states.parameters[renderParameter] = enable;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Enables the alpha test
|
||||||
|
*
|
||||||
|
* \param alphaTest Should the parameter be enabled
|
||||||
|
*
|
||||||
|
* \remark Invalidates the shaders
|
||||||
|
*/
|
||||||
|
|
||||||
inline void Material::EnableAlphaTest(bool alphaTest)
|
inline void Material::EnableAlphaTest(bool alphaTest)
|
||||||
{
|
{
|
||||||
m_alphaTestEnabled = alphaTest;
|
m_alphaTestEnabled = alphaTest;
|
||||||
|
|
@ -38,12 +71,26 @@ namespace Nz
|
||||||
InvalidateShaders();
|
InvalidateShaders();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Enables the depth sorting
|
||||||
|
*
|
||||||
|
* \param depthSorting Should the parameter be enabled
|
||||||
|
*/
|
||||||
|
|
||||||
inline void Material::EnableDepthSorting(bool depthSorting)
|
inline void Material::EnableDepthSorting(bool depthSorting)
|
||||||
{
|
{
|
||||||
// Has no influence on shaders
|
// Has no influence on shaders
|
||||||
m_depthSortingEnabled = depthSorting;
|
m_depthSortingEnabled = depthSorting;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Enables the lighting
|
||||||
|
*
|
||||||
|
* \param lighting Should the parameter be enabled
|
||||||
|
*
|
||||||
|
* \remark Invalidates the shaders
|
||||||
|
*/
|
||||||
|
|
||||||
inline void Material::EnableLighting(bool lighting)
|
inline void Material::EnableLighting(bool lighting)
|
||||||
{
|
{
|
||||||
m_lightingEnabled = lighting;
|
m_lightingEnabled = lighting;
|
||||||
|
|
@ -51,12 +98,26 @@ namespace Nz
|
||||||
InvalidateShaders();
|
InvalidateShaders();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Enables the shadow casting
|
||||||
|
*
|
||||||
|
* \param castShadows Should shadow casting be enabled
|
||||||
|
*/
|
||||||
|
|
||||||
inline void Material::EnableShadowCasting(bool castShadows)
|
inline void Material::EnableShadowCasting(bool castShadows)
|
||||||
{
|
{
|
||||||
// Has no influence on shaders
|
// Has no influence on shaders
|
||||||
m_shadowCastingEnabled = castShadows;
|
m_shadowCastingEnabled = castShadows;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Enables the shadow on receiving object
|
||||||
|
*
|
||||||
|
* \param receiveShadow Should receiving object have shadows enabled
|
||||||
|
*
|
||||||
|
* \remark Invalidates the shaders
|
||||||
|
*/
|
||||||
|
|
||||||
inline void Material::EnableShadowReceive(bool receiveShadows)
|
inline void Material::EnableShadowReceive(bool receiveShadows)
|
||||||
{
|
{
|
||||||
m_shadowReceiveEnabled = receiveShadows;
|
m_shadowReceiveEnabled = receiveShadows;
|
||||||
|
|
@ -64,6 +125,14 @@ namespace Nz
|
||||||
InvalidateShaders();
|
InvalidateShaders();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Enables the transformation
|
||||||
|
*
|
||||||
|
* \param transform Should the parameter be enabled
|
||||||
|
*
|
||||||
|
* \remark Invalidates the shaders
|
||||||
|
*/
|
||||||
|
|
||||||
inline void Material::EnableTransform(bool transform)
|
inline void Material::EnableTransform(bool transform)
|
||||||
{
|
{
|
||||||
m_transformEnabled = transform;
|
m_transformEnabled = transform;
|
||||||
|
|
@ -71,91 +140,183 @@ namespace Nz
|
||||||
InvalidateShaders();
|
InvalidateShaders();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Gets the alpha map
|
||||||
|
* \return Constant reference to the current texture
|
||||||
|
*/
|
||||||
|
|
||||||
inline const TextureRef& Material::GetAlphaMap() const
|
inline const TextureRef& Material::GetAlphaMap() const
|
||||||
{
|
{
|
||||||
return m_alphaMap;
|
return m_alphaMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Gets the alpha threshold
|
||||||
|
* \return The threshold value for the alpha
|
||||||
|
*/
|
||||||
|
|
||||||
inline float Material::GetAlphaThreshold() const
|
inline float Material::GetAlphaThreshold() const
|
||||||
{
|
{
|
||||||
return m_alphaThreshold;
|
return m_alphaThreshold;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Gets the ambient color
|
||||||
|
* \return Ambient color
|
||||||
|
*/
|
||||||
|
|
||||||
inline Color Material::GetAmbientColor() const
|
inline Color Material::GetAmbientColor() const
|
||||||
{
|
{
|
||||||
return m_ambientColor;
|
return m_ambientColor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Gets the function to compare depth
|
||||||
|
* \return Function comparing the depth of two materials
|
||||||
|
*/
|
||||||
|
|
||||||
inline RendererComparison Material::GetDepthFunc() const
|
inline RendererComparison Material::GetDepthFunc() const
|
||||||
{
|
{
|
||||||
return m_states.depthFunc;
|
return m_states.depthFunc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Gets the depth material
|
||||||
|
* \return Constant reference to the depth material
|
||||||
|
*/
|
||||||
|
|
||||||
inline const MaterialRef& Material::GetDepthMaterial() const
|
inline const MaterialRef& Material::GetDepthMaterial() const
|
||||||
{
|
{
|
||||||
return m_depthMaterial;
|
return m_depthMaterial;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Gets the diffuse color
|
||||||
|
* \return Diffuse color
|
||||||
|
*/
|
||||||
|
|
||||||
inline Color Material::GetDiffuseColor() const
|
inline Color Material::GetDiffuseColor() const
|
||||||
{
|
{
|
||||||
return m_diffuseColor;
|
return m_diffuseColor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Gets the diffuse sampler
|
||||||
|
* \return Reference to the current texture sampler for the diffuse
|
||||||
|
*/
|
||||||
|
|
||||||
inline TextureSampler& Material::GetDiffuseSampler()
|
inline TextureSampler& Material::GetDiffuseSampler()
|
||||||
{
|
{
|
||||||
return m_diffuseSampler;
|
return m_diffuseSampler;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Gets the diffuse sampler
|
||||||
|
* \return Constant reference to the current texture sampler for the diffuse
|
||||||
|
*/
|
||||||
|
|
||||||
inline const TextureSampler& Material::GetDiffuseSampler() const
|
inline const TextureSampler& Material::GetDiffuseSampler() const
|
||||||
{
|
{
|
||||||
return m_diffuseSampler;
|
return m_diffuseSampler;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Gets the diffuse map
|
||||||
|
* \return Constant reference to the texture
|
||||||
|
*/
|
||||||
|
|
||||||
const TextureRef& Material::GetDiffuseMap() const
|
const TextureRef& Material::GetDiffuseMap() const
|
||||||
{
|
{
|
||||||
return m_diffuseMap;
|
return m_diffuseMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Gets the dst in blend
|
||||||
|
* \return Function for dst blending
|
||||||
|
*/
|
||||||
|
|
||||||
inline BlendFunc Material::GetDstBlend() const
|
inline BlendFunc Material::GetDstBlend() const
|
||||||
{
|
{
|
||||||
return m_states.dstBlend;
|
return m_states.dstBlend;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Gets the emissive map
|
||||||
|
* \return Constant reference to the texture
|
||||||
|
*/
|
||||||
|
|
||||||
inline const TextureRef& Material::GetEmissiveMap() const
|
inline const TextureRef& Material::GetEmissiveMap() const
|
||||||
{
|
{
|
||||||
return m_emissiveMap;
|
return m_emissiveMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Gets the face culling
|
||||||
|
* \return Current face culling side
|
||||||
|
*/
|
||||||
|
|
||||||
inline FaceSide Material::GetFaceCulling() const
|
inline FaceSide Material::GetFaceCulling() const
|
||||||
{
|
{
|
||||||
return m_states.faceCulling;
|
return m_states.faceCulling;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Gets the face filling
|
||||||
|
* \return Current face filling
|
||||||
|
*/
|
||||||
|
|
||||||
inline FaceFilling Material::GetFaceFilling() const
|
inline FaceFilling Material::GetFaceFilling() const
|
||||||
{
|
{
|
||||||
return m_states.faceFilling;
|
return m_states.faceFilling;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Gets the height map
|
||||||
|
* \return Constant reference to the texture
|
||||||
|
*/
|
||||||
|
|
||||||
inline const TextureRef& Material::GetHeightMap() const
|
inline const TextureRef& Material::GetHeightMap() const
|
||||||
{
|
{
|
||||||
return m_heightMap;
|
return m_heightMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Gets the normal map
|
||||||
|
* \return Constant reference to the texture
|
||||||
|
*/
|
||||||
|
|
||||||
inline const TextureRef& Material::GetNormalMap() const
|
inline const TextureRef& Material::GetNormalMap() const
|
||||||
{
|
{
|
||||||
return m_normalMap;
|
return m_normalMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Gets the render states
|
||||||
|
* \return Constant reference to the render states
|
||||||
|
*/
|
||||||
|
|
||||||
inline const RenderStates& Material::GetRenderStates() const
|
inline const RenderStates& Material::GetRenderStates() const
|
||||||
{
|
{
|
||||||
return m_states;
|
return m_states;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Gets the shader of this material
|
||||||
|
* \return Constant pointer to the ubershader used
|
||||||
|
*/
|
||||||
|
|
||||||
inline const UberShader* Material::GetShader() const
|
inline const UberShader* Material::GetShader() const
|
||||||
{
|
{
|
||||||
return m_uberShader;
|
return m_uberShader;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Gets the shader instance based on the flag
|
||||||
|
* \return Constant pointer to the ubershader instance
|
||||||
|
*
|
||||||
|
* \param flags Flag of the shader
|
||||||
|
*/
|
||||||
|
|
||||||
inline const UberShaderInstance* Material::GetShaderInstance(UInt32 flags) const
|
inline const UberShaderInstance* Material::GetShaderInstance(UInt32 flags) const
|
||||||
{
|
{
|
||||||
const ShaderInstance& instance = m_shaders[flags];
|
const ShaderInstance& instance = m_shaders[flags];
|
||||||
|
|
@ -165,81 +326,165 @@ namespace Nz
|
||||||
return instance.uberInstance;
|
return instance.uberInstance;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Gets the shininess
|
||||||
|
* \return Current shininess
|
||||||
|
*/
|
||||||
|
|
||||||
inline float Material::GetShininess() const
|
inline float Material::GetShininess() const
|
||||||
{
|
{
|
||||||
return m_shininess;
|
return m_shininess;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Gets the specular color
|
||||||
|
* \return Specular color
|
||||||
|
*/
|
||||||
|
|
||||||
inline Color Material::GetSpecularColor() const
|
inline Color Material::GetSpecularColor() const
|
||||||
{
|
{
|
||||||
return m_specularColor;
|
return m_specularColor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Gets the specular map
|
||||||
|
* \return Constant reference to the texture
|
||||||
|
*/
|
||||||
|
|
||||||
inline const TextureRef& Material::GetSpecularMap() const
|
inline const TextureRef& Material::GetSpecularMap() const
|
||||||
{
|
{
|
||||||
return m_specularMap;
|
return m_specularMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Gets the specular sampler
|
||||||
|
* \return Reference to the current texture sampler for the specular
|
||||||
|
*/
|
||||||
|
|
||||||
inline TextureSampler& Material::GetSpecularSampler()
|
inline TextureSampler& Material::GetSpecularSampler()
|
||||||
{
|
{
|
||||||
return m_specularSampler;
|
return m_specularSampler;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Gets the specular sampler
|
||||||
|
* \return Constant reference to the current texture sampler for the specular
|
||||||
|
*/
|
||||||
|
|
||||||
inline const TextureSampler& Material::GetSpecularSampler() const
|
inline const TextureSampler& Material::GetSpecularSampler() const
|
||||||
{
|
{
|
||||||
return m_specularSampler;
|
return m_specularSampler;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Gets the src in blend
|
||||||
|
* \return Function for src blending
|
||||||
|
*/
|
||||||
|
|
||||||
inline BlendFunc Material::GetSrcBlend() const
|
inline BlendFunc Material::GetSrcBlend() const
|
||||||
{
|
{
|
||||||
return m_states.srcBlend;
|
return m_states.srcBlend;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Checks whether this material has an alpha map
|
||||||
|
* \return true If it is the case
|
||||||
|
*/
|
||||||
|
|
||||||
inline bool Material::HasAlphaMap() const
|
inline bool Material::HasAlphaMap() const
|
||||||
{
|
{
|
||||||
return m_alphaMap.IsValid();
|
return m_alphaMap.IsValid();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Checks whether this material has a depth material
|
||||||
|
* \return true If it is the case
|
||||||
|
*/
|
||||||
|
|
||||||
inline bool Material::HasDepthMaterial() const
|
inline bool Material::HasDepthMaterial() const
|
||||||
{
|
{
|
||||||
return m_depthMaterial.IsValid();
|
return m_depthMaterial.IsValid();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Checks whether this material has a diffuse map
|
||||||
|
* \return true If it is the case
|
||||||
|
*/
|
||||||
|
|
||||||
inline bool Material::HasDiffuseMap() const
|
inline bool Material::HasDiffuseMap() const
|
||||||
{
|
{
|
||||||
return m_diffuseMap.IsValid();
|
return m_diffuseMap.IsValid();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Checks whether this material has a emissive map
|
||||||
|
* \return true If it is the case
|
||||||
|
*/
|
||||||
|
|
||||||
inline bool Material::HasEmissiveMap() const
|
inline bool Material::HasEmissiveMap() const
|
||||||
{
|
{
|
||||||
return m_emissiveMap.IsValid();
|
return m_emissiveMap.IsValid();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Checks whether this material has a height map
|
||||||
|
* \return true If it is the case
|
||||||
|
*/
|
||||||
|
|
||||||
inline bool Material::HasHeightMap() const
|
inline bool Material::HasHeightMap() const
|
||||||
{
|
{
|
||||||
return m_heightMap.IsValid();
|
return m_heightMap.IsValid();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Checks whether this material has a normal map
|
||||||
|
* \return true If it is the case
|
||||||
|
*/
|
||||||
|
|
||||||
inline bool Material::HasNormalMap() const
|
inline bool Material::HasNormalMap() const
|
||||||
{
|
{
|
||||||
return m_normalMap.IsValid();
|
return m_normalMap.IsValid();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Checks whether this material has a specular map
|
||||||
|
* \return true If it is the case
|
||||||
|
*/
|
||||||
|
|
||||||
inline bool Material::HasSpecularMap() const
|
inline bool Material::HasSpecularMap() const
|
||||||
{
|
{
|
||||||
return m_specularMap.IsValid();
|
return m_specularMap.IsValid();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Checks whether this material has alpha test enabled
|
||||||
|
* \return true If it is the case
|
||||||
|
*/
|
||||||
|
|
||||||
inline bool Material::IsAlphaTestEnabled() const
|
inline bool Material::IsAlphaTestEnabled() const
|
||||||
{
|
{
|
||||||
return m_alphaTestEnabled;
|
return m_alphaTestEnabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Checks whether this material has depth sorting enabled
|
||||||
|
* \return true If it is the case
|
||||||
|
*/
|
||||||
|
|
||||||
inline bool Material::IsDepthSortingEnabled() const
|
inline bool Material::IsDepthSortingEnabled() const
|
||||||
{
|
{
|
||||||
return m_depthSortingEnabled;
|
return m_depthSortingEnabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Checks whether this material has the render parameter enabled
|
||||||
|
* \return true If it is the case
|
||||||
|
*
|
||||||
|
* \param parameter Parameter for the rendering
|
||||||
|
*
|
||||||
|
* \remark Produces a NazaraAssert if enumeration is invalid
|
||||||
|
*/
|
||||||
|
|
||||||
inline bool Material::IsEnabled(RendererParameter parameter) const
|
inline bool Material::IsEnabled(RendererParameter parameter) const
|
||||||
{
|
{
|
||||||
NazaraAssert(parameter <= RendererParameter_Max, "Renderer parameter out of enum");
|
NazaraAssert(parameter <= RendererParameter_Max, "Renderer parameter out of enum");
|
||||||
|
|
@ -247,41 +492,93 @@ namespace Nz
|
||||||
return m_states.parameters[parameter];
|
return m_states.parameters[parameter];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Checks whether this material has lightning enabled
|
||||||
|
* \return true If it is the case
|
||||||
|
*/
|
||||||
|
|
||||||
inline bool Material::IsLightingEnabled() const
|
inline bool Material::IsLightingEnabled() const
|
||||||
{
|
{
|
||||||
return m_lightingEnabled;
|
return m_lightingEnabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Checks whether this material cast shadow
|
||||||
|
* \return true If it is the case
|
||||||
|
*/
|
||||||
|
|
||||||
inline bool Material::IsShadowCastingEnabled() const
|
inline bool Material::IsShadowCastingEnabled() const
|
||||||
{
|
{
|
||||||
return m_shadowCastingEnabled;
|
return m_shadowCastingEnabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Checks whether this material receive shadow
|
||||||
|
* \return true If it is the case
|
||||||
|
*/
|
||||||
|
|
||||||
inline bool Material::IsShadowReceiveEnabled() const
|
inline bool Material::IsShadowReceiveEnabled() const
|
||||||
{
|
{
|
||||||
return m_shadowReceiveEnabled;
|
return m_shadowReceiveEnabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Checks whether this material has transformation enabled
|
||||||
|
* \return true If it is the case
|
||||||
|
*/
|
||||||
|
|
||||||
inline bool Material::IsTransformEnabled() const
|
inline bool Material::IsTransformEnabled() const
|
||||||
{
|
{
|
||||||
return m_transformEnabled;
|
return m_transformEnabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Loads the material from file
|
||||||
|
* \return true if loading is successful
|
||||||
|
*
|
||||||
|
* \param filePath Path to the file
|
||||||
|
* \param params Parameters for the material
|
||||||
|
*/
|
||||||
|
|
||||||
inline bool Material::LoadFromFile(const String& filePath, const MaterialParams& params)
|
inline bool Material::LoadFromFile(const String& filePath, const MaterialParams& params)
|
||||||
{
|
{
|
||||||
return MaterialLoader::LoadFromFile(this, filePath, params);
|
return MaterialLoader::LoadFromFile(this, filePath, params);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Loads the material from memory
|
||||||
|
* \return true if loading is successful
|
||||||
|
*
|
||||||
|
* \param data Raw memory
|
||||||
|
* \param size Size of the memory
|
||||||
|
* \param params Parameters for the material
|
||||||
|
*/
|
||||||
|
|
||||||
inline bool Material::LoadFromMemory(const void* data, std::size_t size, const MaterialParams& params)
|
inline bool Material::LoadFromMemory(const void* data, std::size_t size, const MaterialParams& params)
|
||||||
{
|
{
|
||||||
return MaterialLoader::LoadFromMemory(this, data, size, params);
|
return MaterialLoader::LoadFromMemory(this, data, size, params);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Loads the material from stream
|
||||||
|
* \return true if loading is successful
|
||||||
|
*
|
||||||
|
* \param stream Stream to the material
|
||||||
|
* \param params Parameters for the material
|
||||||
|
*/
|
||||||
|
|
||||||
inline bool Material::LoadFromStream(Stream& stream, const MaterialParams& params)
|
inline bool Material::LoadFromStream(Stream& stream, const MaterialParams& params)
|
||||||
{
|
{
|
||||||
return MaterialLoader::LoadFromStream(this, stream, params);
|
return MaterialLoader::LoadFromStream(this, stream, params);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Sets the alpha map by name
|
||||||
|
* \return true If successful
|
||||||
|
*
|
||||||
|
* \param textureName Named texture
|
||||||
|
*/
|
||||||
|
|
||||||
inline bool Material::SetAlphaMap(const String& textureName)
|
inline bool Material::SetAlphaMap(const String& textureName)
|
||||||
{
|
{
|
||||||
TextureRef texture = TextureLibrary::Query(textureName);
|
TextureRef texture = TextureLibrary::Query(textureName);
|
||||||
|
|
@ -299,6 +596,15 @@ namespace Nz
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Sets the alpha map with a reference to a texture
|
||||||
|
* \return true If successful
|
||||||
|
*
|
||||||
|
* \param alphaMap Texture
|
||||||
|
*
|
||||||
|
* \remark Invalidates the shaders
|
||||||
|
*/
|
||||||
|
|
||||||
inline void Material::SetAlphaMap(TextureRef alphaMap)
|
inline void Material::SetAlphaMap(TextureRef alphaMap)
|
||||||
{
|
{
|
||||||
m_alphaMap = std::move(alphaMap);
|
m_alphaMap = std::move(alphaMap);
|
||||||
|
|
@ -306,31 +612,69 @@ namespace Nz
|
||||||
InvalidateShaders();
|
InvalidateShaders();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Sets the alpha threshold
|
||||||
|
*
|
||||||
|
* \param alphaThreshold Threshold for the alpha
|
||||||
|
*/
|
||||||
|
|
||||||
inline void Material::SetAlphaThreshold(float alphaThreshold)
|
inline void Material::SetAlphaThreshold(float alphaThreshold)
|
||||||
{
|
{
|
||||||
m_alphaThreshold = alphaThreshold;
|
m_alphaThreshold = alphaThreshold;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Sets the color for ambient
|
||||||
|
*
|
||||||
|
* \param ambient Color for ambient
|
||||||
|
*/
|
||||||
|
|
||||||
inline void Material::SetAmbientColor(const Color& ambient)
|
inline void Material::SetAmbientColor(const Color& ambient)
|
||||||
{
|
{
|
||||||
m_ambientColor = ambient;
|
m_ambientColor = ambient;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Sets the depth functor
|
||||||
|
*
|
||||||
|
* \param depthFunc
|
||||||
|
*/
|
||||||
|
|
||||||
inline void Material::SetDepthFunc(RendererComparison depthFunc)
|
inline void Material::SetDepthFunc(RendererComparison depthFunc)
|
||||||
{
|
{
|
||||||
m_states.depthFunc = depthFunc;
|
m_states.depthFunc = depthFunc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Sets the depth material
|
||||||
|
* \return true If successful
|
||||||
|
*
|
||||||
|
* \param depthMaterial Material for depth
|
||||||
|
*/
|
||||||
|
|
||||||
inline void Material::SetDepthMaterial(MaterialRef depthMaterial)
|
inline void Material::SetDepthMaterial(MaterialRef depthMaterial)
|
||||||
{
|
{
|
||||||
m_depthMaterial = std::move(depthMaterial);
|
m_depthMaterial = std::move(depthMaterial);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Sets the color for diffuse
|
||||||
|
*
|
||||||
|
* \param diffuse Color for diffuse
|
||||||
|
*/
|
||||||
|
|
||||||
inline void Material::SetDiffuseColor(const Color& diffuse)
|
inline void Material::SetDiffuseColor(const Color& diffuse)
|
||||||
{
|
{
|
||||||
m_diffuseColor = diffuse;
|
m_diffuseColor = diffuse;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Sets the diffuse map by name
|
||||||
|
* \return true If successful
|
||||||
|
*
|
||||||
|
* \param textureName Named texture
|
||||||
|
*/
|
||||||
|
|
||||||
inline bool Material::SetDiffuseMap(const String& textureName)
|
inline bool Material::SetDiffuseMap(const String& textureName)
|
||||||
{
|
{
|
||||||
TextureRef texture = TextureLibrary::Query(textureName);
|
TextureRef texture = TextureLibrary::Query(textureName);
|
||||||
|
|
@ -348,6 +692,15 @@ namespace Nz
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Sets the diffuse map with a reference to a texture
|
||||||
|
* \return true If successful
|
||||||
|
*
|
||||||
|
* \param diffuseMap Texture
|
||||||
|
*
|
||||||
|
* \remark Invalidates the shaders
|
||||||
|
*/
|
||||||
|
|
||||||
inline void Material::SetDiffuseMap(TextureRef diffuseMap)
|
inline void Material::SetDiffuseMap(TextureRef diffuseMap)
|
||||||
{
|
{
|
||||||
m_diffuseMap = std::move(diffuseMap);
|
m_diffuseMap = std::move(diffuseMap);
|
||||||
|
|
@ -355,16 +708,35 @@ namespace Nz
|
||||||
InvalidateShaders();
|
InvalidateShaders();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Sets the diffuse sampler
|
||||||
|
*
|
||||||
|
* \param sampler Diffuse sample
|
||||||
|
*/
|
||||||
|
|
||||||
inline void Material::SetDiffuseSampler(const TextureSampler& sampler)
|
inline void Material::SetDiffuseSampler(const TextureSampler& sampler)
|
||||||
{
|
{
|
||||||
m_diffuseSampler = sampler;
|
m_diffuseSampler = sampler;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Sets the dst in blend
|
||||||
|
*
|
||||||
|
* \param func Function for dst blending
|
||||||
|
*/
|
||||||
|
|
||||||
inline void Material::SetDstBlend(BlendFunc func)
|
inline void Material::SetDstBlend(BlendFunc func)
|
||||||
{
|
{
|
||||||
m_states.dstBlend = func;
|
m_states.dstBlend = func;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Sets the emissive map by name
|
||||||
|
* \return true If successful
|
||||||
|
*
|
||||||
|
* \param textureName Named texture
|
||||||
|
*/
|
||||||
|
|
||||||
inline bool Material::SetEmissiveMap(const String& textureName)
|
inline bool Material::SetEmissiveMap(const String& textureName)
|
||||||
{
|
{
|
||||||
TextureRef texture = TextureLibrary::Query(textureName);
|
TextureRef texture = TextureLibrary::Query(textureName);
|
||||||
|
|
@ -382,6 +754,15 @@ namespace Nz
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Sets the emissive map with a reference to a texture
|
||||||
|
* \return true If successful
|
||||||
|
*
|
||||||
|
* \param emissiveMap Texture
|
||||||
|
*
|
||||||
|
* \remark Invalidates the shaders
|
||||||
|
*/
|
||||||
|
|
||||||
inline void Material::SetEmissiveMap(TextureRef emissiveMap)
|
inline void Material::SetEmissiveMap(TextureRef emissiveMap)
|
||||||
{
|
{
|
||||||
m_emissiveMap = std::move(emissiveMap);
|
m_emissiveMap = std::move(emissiveMap);
|
||||||
|
|
@ -389,16 +770,35 @@ namespace Nz
|
||||||
InvalidateShaders();
|
InvalidateShaders();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Sets the face culling
|
||||||
|
*
|
||||||
|
* \param faceSide Face to cull
|
||||||
|
*/
|
||||||
|
|
||||||
inline void Material::SetFaceCulling(FaceSide faceSide)
|
inline void Material::SetFaceCulling(FaceSide faceSide)
|
||||||
{
|
{
|
||||||
m_states.faceCulling = faceSide;
|
m_states.faceCulling = faceSide;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Sets the face filling
|
||||||
|
*
|
||||||
|
* \param filling Face to fill
|
||||||
|
*/
|
||||||
|
|
||||||
inline void Material::SetFaceFilling(FaceFilling filling)
|
inline void Material::SetFaceFilling(FaceFilling filling)
|
||||||
{
|
{
|
||||||
m_states.faceFilling = filling;
|
m_states.faceFilling = filling;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Sets the height map by name
|
||||||
|
* \return true If successful
|
||||||
|
*
|
||||||
|
* \param textureName Named texture
|
||||||
|
*/
|
||||||
|
|
||||||
inline bool Material::SetHeightMap(const String& textureName)
|
inline bool Material::SetHeightMap(const String& textureName)
|
||||||
{
|
{
|
||||||
TextureRef texture = TextureLibrary::Query(textureName);
|
TextureRef texture = TextureLibrary::Query(textureName);
|
||||||
|
|
@ -416,6 +816,15 @@ namespace Nz
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Sets the height map with a reference to a texture
|
||||||
|
* \return true If successful
|
||||||
|
*
|
||||||
|
* \param heightMap Texture
|
||||||
|
*
|
||||||
|
* \remark Invalidates the shaders
|
||||||
|
*/
|
||||||
|
|
||||||
inline void Material::SetHeightMap(TextureRef heightMap)
|
inline void Material::SetHeightMap(TextureRef heightMap)
|
||||||
{
|
{
|
||||||
m_heightMap = std::move(heightMap);
|
m_heightMap = std::move(heightMap);
|
||||||
|
|
@ -423,6 +832,13 @@ namespace Nz
|
||||||
InvalidateShaders();
|
InvalidateShaders();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Sets the normal map by name
|
||||||
|
* \return true If successful
|
||||||
|
*
|
||||||
|
* \param textureName Named texture
|
||||||
|
*/
|
||||||
|
|
||||||
inline bool Material::SetNormalMap(const String& textureName)
|
inline bool Material::SetNormalMap(const String& textureName)
|
||||||
{
|
{
|
||||||
TextureRef texture = TextureLibrary::Query(textureName);
|
TextureRef texture = TextureLibrary::Query(textureName);
|
||||||
|
|
@ -440,6 +856,15 @@ namespace Nz
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Sets the normal map with a reference to a texture
|
||||||
|
* \return true If successful
|
||||||
|
*
|
||||||
|
* \param normalMap Texture
|
||||||
|
*
|
||||||
|
* \remark Invalidates the shaders
|
||||||
|
*/
|
||||||
|
|
||||||
inline void Material::SetNormalMap(TextureRef normalMap)
|
inline void Material::SetNormalMap(TextureRef normalMap)
|
||||||
{
|
{
|
||||||
m_normalMap = std::move(normalMap);
|
m_normalMap = std::move(normalMap);
|
||||||
|
|
@ -447,11 +872,25 @@ namespace Nz
|
||||||
InvalidateShaders();
|
InvalidateShaders();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Sets the render states
|
||||||
|
*
|
||||||
|
* \param states States for the rendering
|
||||||
|
*/
|
||||||
|
|
||||||
inline void Material::SetRenderStates(const RenderStates& states)
|
inline void Material::SetRenderStates(const RenderStates& states)
|
||||||
{
|
{
|
||||||
m_states = states;
|
m_states = states;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Sets the shader with a constant reference to a ubershader
|
||||||
|
*
|
||||||
|
* \param uberShader Uber shader to apply
|
||||||
|
*
|
||||||
|
* \remark Invalidates the shaders
|
||||||
|
*/
|
||||||
|
|
||||||
inline void Material::SetShader(UberShaderConstRef uberShader)
|
inline void Material::SetShader(UberShaderConstRef uberShader)
|
||||||
{
|
{
|
||||||
m_uberShader = std::move(uberShader);
|
m_uberShader = std::move(uberShader);
|
||||||
|
|
@ -459,6 +898,13 @@ namespace Nz
|
||||||
InvalidateShaders();
|
InvalidateShaders();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Sets the shader by name
|
||||||
|
* \return true If successful
|
||||||
|
*
|
||||||
|
* \param uberShaderName Named shader
|
||||||
|
*/
|
||||||
|
|
||||||
inline bool Material::SetShader(const String& uberShaderName)
|
inline bool Material::SetShader(const String& uberShaderName)
|
||||||
{
|
{
|
||||||
UberShaderConstRef uberShader = UberShaderLibrary::Get(uberShaderName);
|
UberShaderConstRef uberShader = UberShaderLibrary::Get(uberShaderName);
|
||||||
|
|
@ -469,16 +915,35 @@ namespace Nz
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Sets the shininess of the material
|
||||||
|
*
|
||||||
|
* \param shininess Value of the shininess
|
||||||
|
*/
|
||||||
|
|
||||||
inline void Material::SetShininess(float shininess)
|
inline void Material::SetShininess(float shininess)
|
||||||
{
|
{
|
||||||
m_shininess = shininess;
|
m_shininess = shininess;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Sets the color for specular
|
||||||
|
*
|
||||||
|
* \param specular Color
|
||||||
|
*/
|
||||||
|
|
||||||
inline void Material::SetSpecularColor(const Color& specular)
|
inline void Material::SetSpecularColor(const Color& specular)
|
||||||
{
|
{
|
||||||
m_specularColor = specular;
|
m_specularColor = specular;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Sets the specular map by name
|
||||||
|
* \return true If successful
|
||||||
|
*
|
||||||
|
* \param textureName Named texture
|
||||||
|
*/
|
||||||
|
|
||||||
inline bool Material::SetSpecularMap(const String& textureName)
|
inline bool Material::SetSpecularMap(const String& textureName)
|
||||||
{
|
{
|
||||||
TextureRef texture = TextureLibrary::Query(textureName);
|
TextureRef texture = TextureLibrary::Query(textureName);
|
||||||
|
|
@ -496,6 +961,15 @@ namespace Nz
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Sets the specular map with a reference to a texture
|
||||||
|
* \return true If successful
|
||||||
|
*
|
||||||
|
* \param specularMap Texture
|
||||||
|
*
|
||||||
|
* \remark Invalidates the shaders
|
||||||
|
*/
|
||||||
|
|
||||||
inline void Material::SetSpecularMap(TextureRef specularMap)
|
inline void Material::SetSpecularMap(TextureRef specularMap)
|
||||||
{
|
{
|
||||||
m_specularMap = std::move(specularMap);
|
m_specularMap = std::move(specularMap);
|
||||||
|
|
@ -503,16 +977,35 @@ namespace Nz
|
||||||
InvalidateShaders();
|
InvalidateShaders();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Sets the specular sampler
|
||||||
|
*
|
||||||
|
* \param sampler Specular sample
|
||||||
|
*/
|
||||||
|
|
||||||
inline void Material::SetSpecularSampler(const TextureSampler& sampler)
|
inline void Material::SetSpecularSampler(const TextureSampler& sampler)
|
||||||
{
|
{
|
||||||
m_specularSampler = sampler;
|
m_specularSampler = sampler;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Sets the src in blend
|
||||||
|
*
|
||||||
|
* \param func Function for src blending
|
||||||
|
*/
|
||||||
|
|
||||||
inline void Material::SetSrcBlend(BlendFunc func)
|
inline void Material::SetSrcBlend(BlendFunc func)
|
||||||
{
|
{
|
||||||
m_states.srcBlend = func;
|
m_states.srcBlend = func;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Sets the current material with the content of the other one
|
||||||
|
* \return A reference to this
|
||||||
|
*
|
||||||
|
* \param material The other Material
|
||||||
|
*/
|
||||||
|
|
||||||
inline Material& Material::operator=(const Material& material)
|
inline Material& Material::operator=(const Material& material)
|
||||||
{
|
{
|
||||||
Resource::operator=(material);
|
Resource::operator=(material);
|
||||||
|
|
@ -521,17 +1014,33 @@ namespace Nz
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Gets the default material
|
||||||
|
* \return Reference to the default material
|
||||||
|
*/
|
||||||
|
|
||||||
inline MaterialRef Material::GetDefault()
|
inline MaterialRef Material::GetDefault()
|
||||||
{
|
{
|
||||||
return s_defaultMaterial;
|
return s_defaultMaterial;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Invalidates the shaders
|
||||||
|
*/
|
||||||
|
|
||||||
inline void Material::InvalidateShaders()
|
inline void Material::InvalidateShaders()
|
||||||
{
|
{
|
||||||
for (ShaderInstance& instance : m_shaders)
|
for (ShaderInstance& instance : m_shaders)
|
||||||
instance.uberInstance = nullptr;
|
instance.uberInstance = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Creates a new material from the arguments
|
||||||
|
* \return A reference to the newly created material
|
||||||
|
*
|
||||||
|
* \param args Arguments for the material
|
||||||
|
*/
|
||||||
|
|
||||||
template<typename... Args>
|
template<typename... Args>
|
||||||
MaterialRef Material::New(Args&&... args)
|
MaterialRef Material::New(Args&&... args)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -68,8 +68,6 @@ namespace Nz
|
||||||
bool SetMaterial(unsigned int skinIndex, const String& subMeshName, Material* material);
|
bool SetMaterial(unsigned int skinIndex, const String& subMeshName, Material* material);
|
||||||
void SetMaterial(unsigned int skinIndex, unsigned int matIndex, Material* material);
|
void SetMaterial(unsigned int skinIndex, unsigned int matIndex, Material* material);
|
||||||
virtual void SetMesh(Mesh* mesh);
|
virtual void SetMesh(Mesh* mesh);
|
||||||
bool SetSequence(const String& sequenceName);
|
|
||||||
void SetSequence(unsigned int sequenceIndex);
|
|
||||||
void SetSkin(unsigned int skin);
|
void SetSkin(unsigned int skin);
|
||||||
void SetSkinCount(unsigned int skinCount);
|
void SetSkinCount(unsigned int skinCount);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,13 @@
|
||||||
|
|
||||||
namespace Nz
|
namespace Nz
|
||||||
{
|
{
|
||||||
|
/*!
|
||||||
|
* \brief Creates a new Model from the arguments
|
||||||
|
* \return A reference to the newly created model
|
||||||
|
*
|
||||||
|
* \param args Arguments for the model
|
||||||
|
*/
|
||||||
|
|
||||||
template<typename... Args>
|
template<typename... Args>
|
||||||
ModelRef Model::New(Args&&... args)
|
ModelRef Model::New(Args&&... args)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -62,9 +62,9 @@ namespace Nz
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** -Lynix:
|
** -Lynix:
|
||||||
** Il serait aussi possible de préciser le stride de façon indépendante, ce que je ne permets pas
|
** It would be also possible to precise the stride by an independant way, what I don't allow
|
||||||
** pour décomplexifier l'interface en enlevant quelque chose que je juge inutile.
|
** to decomplexify the interface of something I consider useless.
|
||||||
** Si vous pensez que ça peut être utile, n'hésitez pas à me le faire savoir !
|
** If you think that could be useful, don't hesitate to make me aware !
|
||||||
*/
|
*/
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,10 +7,20 @@
|
||||||
|
|
||||||
namespace Nz
|
namespace Nz
|
||||||
{
|
{
|
||||||
|
/*!
|
||||||
|
* \brief Gets a pointer to iterate through same components
|
||||||
|
* \return SparsePtr pointing to same components
|
||||||
|
*
|
||||||
|
* \param component Component to get in the declaration
|
||||||
|
*
|
||||||
|
* \remark The same components are not continguous but separated by sizeof(ParticleSize)
|
||||||
|
* \remark Produces a NazaraError if component is disabled
|
||||||
|
*/
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
SparsePtr<T> ParticleMapper::GetComponentPtr(ParticleComponent component)
|
SparsePtr<T> ParticleMapper::GetComponentPtr(ParticleComponent component)
|
||||||
{
|
{
|
||||||
// Ensuite le composant qui nous intéresse
|
// Then the component that are interesting
|
||||||
bool enabled;
|
bool enabled;
|
||||||
ComponentType type;
|
ComponentType type;
|
||||||
unsigned int offset;
|
unsigned int offset;
|
||||||
|
|
@ -18,7 +28,7 @@ namespace Nz
|
||||||
|
|
||||||
if (enabled)
|
if (enabled)
|
||||||
{
|
{
|
||||||
///TODO: Vérifier le rapport entre le type de l'attribut et le type template ?
|
///TODO: Check the ratio between the type of the attribute and the template type ?
|
||||||
return SparsePtr<T>(m_ptr + offset, m_declaration->GetStride());
|
return SparsePtr<T>(m_ptr + offset, m_declaration->GetStride());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
@ -28,10 +38,20 @@ namespace Nz
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Gets a pointer to iterate through same components
|
||||||
|
* \return SparsePtr pointing to same components
|
||||||
|
*
|
||||||
|
* \param component Component to get in the declaration
|
||||||
|
*
|
||||||
|
* \remark The same components are not continguous but separated by sizeof(ParticleSize)
|
||||||
|
* \remark Produces a NazaraError if component is disabled
|
||||||
|
*/
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
SparsePtr<const T> ParticleMapper::GetComponentPtr(ParticleComponent component) const
|
SparsePtr<const T> ParticleMapper::GetComponentPtr(ParticleComponent component) const
|
||||||
{
|
{
|
||||||
// Ensuite le composant qui nous intéresse
|
// Then the component that are interesting
|
||||||
bool enabled;
|
bool enabled;
|
||||||
ComponentType type;
|
ComponentType type;
|
||||||
unsigned int offset;
|
unsigned int offset;
|
||||||
|
|
@ -39,7 +59,7 @@ namespace Nz
|
||||||
|
|
||||||
if (enabled)
|
if (enabled)
|
||||||
{
|
{
|
||||||
///TODO: Vérifier le rapport entre le type de l'attribut et le type template ?
|
///TODO: Check the ratio between the type of the attribute and the template type ?
|
||||||
return SparsePtr<const T>(m_ptr + offset, m_declaration->GetStride());
|
return SparsePtr<const T>(m_ptr + offset, m_declaration->GetStride());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
||||||
|
|
@ -4,17 +4,31 @@
|
||||||
|
|
||||||
namespace Nz
|
namespace Nz
|
||||||
{
|
{
|
||||||
|
/*!
|
||||||
|
* \brief Ensures that the bounding volume is up to date
|
||||||
|
*/
|
||||||
|
|
||||||
inline void Renderable::EnsureBoundingVolumeUpdated() const
|
inline void Renderable::EnsureBoundingVolumeUpdated() const
|
||||||
{
|
{
|
||||||
if (!m_boundingVolumeUpdated)
|
if (!m_boundingVolumeUpdated)
|
||||||
UpdateBoundingVolume();
|
UpdateBoundingVolume();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Invalidates the bounding volume
|
||||||
|
*/
|
||||||
|
|
||||||
inline void Renderable::InvalidateBoundingVolume()
|
inline void Renderable::InvalidateBoundingVolume()
|
||||||
{
|
{
|
||||||
m_boundingVolumeUpdated = false;
|
m_boundingVolumeUpdated = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Updates the bounding volume by a matrix
|
||||||
|
*
|
||||||
|
* \param transformMatrix Matrix transformation for our bounding volume
|
||||||
|
*/
|
||||||
|
|
||||||
inline void Renderable::UpdateBoundingVolume() const
|
inline void Renderable::UpdateBoundingVolume() const
|
||||||
{
|
{
|
||||||
MakeBoundingVolume();
|
MakeBoundingVolume();
|
||||||
|
|
|
||||||
|
|
@ -7,31 +7,62 @@
|
||||||
|
|
||||||
namespace Nz
|
namespace Nz
|
||||||
{
|
{
|
||||||
|
/*!
|
||||||
|
* \brief Gets the movement offset
|
||||||
|
* \return Offset of the movement
|
||||||
|
*/
|
||||||
|
|
||||||
inline const Vector3f& Nz::SkyboxBackground::GetMovementOffset() const
|
inline const Vector3f& Nz::SkyboxBackground::GetMovementOffset() const
|
||||||
{
|
{
|
||||||
return m_movementOffset;
|
return m_movementOffset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Gets the movement scale
|
||||||
|
* \return Scale of the movement
|
||||||
|
*/
|
||||||
|
|
||||||
inline float SkyboxBackground::GetMovementScale() const
|
inline float SkyboxBackground::GetMovementScale() const
|
||||||
{
|
{
|
||||||
return m_movementScale;
|
return m_movementScale;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Gets the texture of the background
|
||||||
|
* \return Texture of the background
|
||||||
|
*/
|
||||||
|
|
||||||
inline const TextureRef& SkyboxBackground::GetTexture() const
|
inline const TextureRef& SkyboxBackground::GetTexture() const
|
||||||
{
|
{
|
||||||
return m_texture;
|
return m_texture;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Gets the texture sampler of the background
|
||||||
|
* \return A reference to the texture sampler of the background
|
||||||
|
*/
|
||||||
|
|
||||||
inline TextureSampler& SkyboxBackground::GetTextureSampler()
|
inline TextureSampler& SkyboxBackground::GetTextureSampler()
|
||||||
{
|
{
|
||||||
return m_sampler;
|
return m_sampler;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Gets the texture sampler of the background
|
||||||
|
* \return A constant reference to the texture sampler of the background
|
||||||
|
*/
|
||||||
|
|
||||||
inline const TextureSampler& SkyboxBackground::GetTextureSampler() const
|
inline const TextureSampler& SkyboxBackground::GetTextureSampler() const
|
||||||
{
|
{
|
||||||
return m_sampler;
|
return m_sampler;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Sets the movement offset
|
||||||
|
*
|
||||||
|
* \param offset Offset of the movement
|
||||||
|
*/
|
||||||
|
|
||||||
inline void SkyboxBackground::SetMovementOffset(const Vector3f& offset)
|
inline void SkyboxBackground::SetMovementOffset(const Vector3f& offset)
|
||||||
{
|
{
|
||||||
NazaraAssert(std::isfinite(offset.x) && std::isfinite(offset.y) && std::isfinite(offset.z), "Offset must be a finite vector");
|
NazaraAssert(std::isfinite(offset.x) && std::isfinite(offset.y) && std::isfinite(offset.z), "Offset must be a finite vector");
|
||||||
|
|
@ -39,6 +70,12 @@ namespace Nz
|
||||||
m_movementOffset = offset;
|
m_movementOffset = offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Sets the movement scale
|
||||||
|
*
|
||||||
|
* \param scale Scale of the movement
|
||||||
|
*/
|
||||||
|
|
||||||
inline void SkyboxBackground::SetMovementScale(float scale)
|
inline void SkyboxBackground::SetMovementScale(float scale)
|
||||||
{
|
{
|
||||||
NazaraAssert(std::isfinite(scale), "Scale must be a finite value");
|
NazaraAssert(std::isfinite(scale), "Scale must be a finite value");
|
||||||
|
|
@ -46,6 +83,12 @@ namespace Nz
|
||||||
m_movementScale = scale;
|
m_movementScale = scale;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Sets the texture of the background
|
||||||
|
*
|
||||||
|
* \param cubemapTexture Texture of the background
|
||||||
|
*/
|
||||||
|
|
||||||
inline void SkyboxBackground::SetTexture(TextureRef cubemapTexture)
|
inline void SkyboxBackground::SetTexture(TextureRef cubemapTexture)
|
||||||
{
|
{
|
||||||
NazaraAssert(!cubemapTexture || cubemapTexture->IsValid(), "Invalid texture");
|
NazaraAssert(!cubemapTexture || cubemapTexture->IsValid(), "Invalid texture");
|
||||||
|
|
@ -54,11 +97,24 @@ namespace Nz
|
||||||
m_texture = std::move(cubemapTexture);
|
m_texture = std::move(cubemapTexture);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Sets the texture sampler of the background
|
||||||
|
*
|
||||||
|
* \param sampler Texture sampler of the background
|
||||||
|
*/
|
||||||
|
|
||||||
void SkyboxBackground::SetTextureSampler(const TextureSampler& sampler)
|
void SkyboxBackground::SetTextureSampler(const TextureSampler& sampler)
|
||||||
{
|
{
|
||||||
m_sampler = sampler;
|
m_sampler = sampler;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Creates a new skybox background from the arguments
|
||||||
|
* \return A reference to the newly created skybox background
|
||||||
|
*
|
||||||
|
* \param args Arguments for the skybox background
|
||||||
|
*/
|
||||||
|
|
||||||
template<typename... Args>
|
template<typename... Args>
|
||||||
SkyboxBackgroundRef SkyboxBackground::New(Args&&... args)
|
SkyboxBackgroundRef SkyboxBackground::New(Args&&... args)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,10 @@
|
||||||
|
|
||||||
namespace Nz
|
namespace Nz
|
||||||
{
|
{
|
||||||
|
/*!
|
||||||
|
* \brief Constructs a Sprite object by default
|
||||||
|
*/
|
||||||
|
|
||||||
inline Sprite::Sprite() :
|
inline Sprite::Sprite() :
|
||||||
m_color(Color::White),
|
m_color(Color::White),
|
||||||
m_textureCoords(0.f, 0.f, 1.f, 1.f),
|
m_textureCoords(0.f, 0.f, 1.f, 1.f),
|
||||||
|
|
@ -16,6 +20,12 @@ namespace Nz
|
||||||
SetDefaultMaterial();
|
SetDefaultMaterial();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Constructs a Sprite object with a reference to a material
|
||||||
|
*
|
||||||
|
* \param material Reference to a material
|
||||||
|
*/
|
||||||
|
|
||||||
inline Sprite::Sprite(MaterialRef material) :
|
inline Sprite::Sprite(MaterialRef material) :
|
||||||
m_color(Color::White),
|
m_color(Color::White),
|
||||||
m_textureCoords(0.f, 0.f, 1.f, 1.f),
|
m_textureCoords(0.f, 0.f, 1.f, 1.f),
|
||||||
|
|
@ -24,6 +34,12 @@ namespace Nz
|
||||||
SetMaterial(std::move(material), true);
|
SetMaterial(std::move(material), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Constructs a Sprite object with a pointer to a texture
|
||||||
|
*
|
||||||
|
* \param texture Pointer to a texture
|
||||||
|
*/
|
||||||
|
|
||||||
inline Sprite::Sprite(Texture* texture) :
|
inline Sprite::Sprite(Texture* texture) :
|
||||||
m_color(Color::White),
|
m_color(Color::White),
|
||||||
m_textureCoords(0.f, 0.f, 1.f, 1.f),
|
m_textureCoords(0.f, 0.f, 1.f, 1.f),
|
||||||
|
|
@ -32,6 +48,12 @@ namespace Nz
|
||||||
SetTexture(texture, true);
|
SetTexture(texture, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Constructs a Sprite object by assignation
|
||||||
|
*
|
||||||
|
* \param sprite Sprite to copy into this
|
||||||
|
*/
|
||||||
|
|
||||||
inline Sprite::Sprite(const Sprite& sprite) :
|
inline Sprite::Sprite(const Sprite& sprite) :
|
||||||
InstancedRenderable(sprite),
|
InstancedRenderable(sprite),
|
||||||
m_color(sprite.m_color),
|
m_color(sprite.m_color),
|
||||||
|
|
@ -41,26 +63,52 @@ namespace Nz
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Gets the color of the sprite
|
||||||
|
* \return Current color
|
||||||
|
*/
|
||||||
|
|
||||||
inline const Color& Sprite::GetColor() const
|
inline const Color& Sprite::GetColor() const
|
||||||
{
|
{
|
||||||
return m_color;
|
return m_color;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Gets the material of the sprite
|
||||||
|
* \return Current material
|
||||||
|
*/
|
||||||
|
|
||||||
inline const MaterialRef& Sprite::GetMaterial() const
|
inline const MaterialRef& Sprite::GetMaterial() const
|
||||||
{
|
{
|
||||||
return m_material;
|
return m_material;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Gets the size of the sprite
|
||||||
|
* \return Current size
|
||||||
|
*/
|
||||||
|
|
||||||
inline const Vector2f& Sprite::GetSize() const
|
inline const Vector2f& Sprite::GetSize() const
|
||||||
{
|
{
|
||||||
return m_size;
|
return m_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Gets the texture coordinates of the sprite
|
||||||
|
* \return Current texture coordinates
|
||||||
|
*/
|
||||||
|
|
||||||
inline const Rectf& Sprite::GetTextureCoords() const
|
inline const Rectf& Sprite::GetTextureCoords() const
|
||||||
{
|
{
|
||||||
return m_textureCoords;
|
return m_textureCoords;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Sets the color of the billboard
|
||||||
|
*
|
||||||
|
* \param color Color for the billboard
|
||||||
|
*/
|
||||||
|
|
||||||
inline void Sprite::SetColor(const Color& color)
|
inline void Sprite::SetColor(const Color& color)
|
||||||
{
|
{
|
||||||
m_color = color;
|
m_color = color;
|
||||||
|
|
@ -68,6 +116,10 @@ namespace Nz
|
||||||
InvalidateVertices();
|
InvalidateVertices();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Sets the default material of the sprite (just default material)
|
||||||
|
*/
|
||||||
|
|
||||||
inline void Sprite::SetDefaultMaterial()
|
inline void Sprite::SetDefaultMaterial()
|
||||||
{
|
{
|
||||||
MaterialRef material = Material::New();
|
MaterialRef material = Material::New();
|
||||||
|
|
@ -77,6 +129,13 @@ namespace Nz
|
||||||
SetMaterial(std::move(material));
|
SetMaterial(std::move(material));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Sets the material of the sprite
|
||||||
|
*
|
||||||
|
* \param material Material for the sprite
|
||||||
|
* \param resizeSprite Should sprite be resized to the material size (diffuse map)
|
||||||
|
*/
|
||||||
|
|
||||||
inline void Sprite::SetMaterial(MaterialRef material, bool resizeSprite)
|
inline void Sprite::SetMaterial(MaterialRef material, bool resizeSprite)
|
||||||
{
|
{
|
||||||
m_material = std::move(material);
|
m_material = std::move(material);
|
||||||
|
|
@ -88,6 +147,12 @@ namespace Nz
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Sets the size of the sprite
|
||||||
|
*
|
||||||
|
* \param size Size for the sprite
|
||||||
|
*/
|
||||||
|
|
||||||
inline void Sprite::SetSize(const Vector2f& size)
|
inline void Sprite::SetSize(const Vector2f& size)
|
||||||
{
|
{
|
||||||
m_size = size;
|
m_size = size;
|
||||||
|
|
@ -97,11 +162,25 @@ namespace Nz
|
||||||
InvalidateVertices();
|
InvalidateVertices();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Sets the size of the sprite
|
||||||
|
*
|
||||||
|
* \param sizeX Size in X for the sprite
|
||||||
|
* \param sizeY Size in Y for the sprite
|
||||||
|
*/
|
||||||
|
|
||||||
inline void Sprite::SetSize(float sizeX, float sizeY)
|
inline void Sprite::SetSize(float sizeX, float sizeY)
|
||||||
{
|
{
|
||||||
SetSize(Vector2f(sizeX, sizeY));
|
SetSize(Vector2f(sizeX, sizeY));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Sets the texture of the sprite
|
||||||
|
*
|
||||||
|
* \param texture Texture for the sprite
|
||||||
|
* \param resizeSprite Should sprite be resized to the texture size
|
||||||
|
*/
|
||||||
|
|
||||||
inline void Sprite::SetTexture(TextureRef texture, bool resizeSprite)
|
inline void Sprite::SetTexture(TextureRef texture, bool resizeSprite)
|
||||||
{
|
{
|
||||||
if (!m_material)
|
if (!m_material)
|
||||||
|
|
@ -115,12 +194,27 @@ namespace Nz
|
||||||
m_material->SetDiffuseMap(std::move(texture));
|
m_material->SetDiffuseMap(std::move(texture));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Sets the texture coordinates of the sprite
|
||||||
|
*
|
||||||
|
* \param coords Texture coordinates
|
||||||
|
*/
|
||||||
|
|
||||||
inline void Sprite::SetTextureCoords(const Rectf& coords)
|
inline void Sprite::SetTextureCoords(const Rectf& coords)
|
||||||
{
|
{
|
||||||
m_textureCoords = coords;
|
m_textureCoords = coords;
|
||||||
InvalidateVertices();
|
InvalidateVertices();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Sets the texture rectangle of the sprite
|
||||||
|
*
|
||||||
|
* \param rect Rectangles symbolizing the size of the texture
|
||||||
|
*
|
||||||
|
* \remark Produces a NazaraAssert if material is invalid
|
||||||
|
* \remark Produces a NazaraAssert if material has no diffuse map
|
||||||
|
*/
|
||||||
|
|
||||||
inline void Sprite::SetTextureRect(const Rectui& rect)
|
inline void Sprite::SetTextureRect(const Rectui& rect)
|
||||||
{
|
{
|
||||||
NazaraAssert(m_material, "Sprite has no material");
|
NazaraAssert(m_material, "Sprite has no material");
|
||||||
|
|
@ -134,6 +228,13 @@ namespace Nz
|
||||||
SetTextureCoords(Rectf(invWidth * rect.x, invHeight * rect.y, invWidth * rect.width, invHeight * rect.height));
|
SetTextureCoords(Rectf(invWidth * rect.x, invHeight * rect.y, invWidth * rect.width, invHeight * rect.height));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Sets the current sprite with the content of the other one
|
||||||
|
* \return A reference to this
|
||||||
|
*
|
||||||
|
* \param sprite The other Sprite
|
||||||
|
*/
|
||||||
|
|
||||||
inline Sprite& Sprite::operator=(const Sprite& sprite)
|
inline Sprite& Sprite::operator=(const Sprite& sprite)
|
||||||
{
|
{
|
||||||
InstancedRenderable::operator=(sprite);
|
InstancedRenderable::operator=(sprite);
|
||||||
|
|
@ -143,18 +244,29 @@ namespace Nz
|
||||||
m_textureCoords = sprite.m_textureCoords;
|
m_textureCoords = sprite.m_textureCoords;
|
||||||
m_size = sprite.m_size;
|
m_size = sprite.m_size;
|
||||||
|
|
||||||
// On ne copie pas les sommets finaux car il est très probable que nos paramètres soient modifiés et qu'ils doivent être régénérés de toute façon
|
// We do not copy final vertices because it's highly probable that our parameters are modified and they must be regenerated
|
||||||
InvalidateBoundingVolume();
|
InvalidateBoundingVolume();
|
||||||
InvalidateVertices();
|
InvalidateVertices();
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Invalidates the vertices
|
||||||
|
*/
|
||||||
|
|
||||||
inline void Sprite::InvalidateVertices()
|
inline void Sprite::InvalidateVertices()
|
||||||
{
|
{
|
||||||
InvalidateInstanceData(0);
|
InvalidateInstanceData(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Creates a new sprite from the arguments
|
||||||
|
* \return A reference to the newly created sprite
|
||||||
|
*
|
||||||
|
* \param args Arguments for the sprite
|
||||||
|
*/
|
||||||
|
|
||||||
template<typename... Args>
|
template<typename... Args>
|
||||||
SpriteRef Sprite::New(Args&&... args)
|
SpriteRef Sprite::New(Args&&... args)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,10 @@
|
||||||
|
|
||||||
namespace Nz
|
namespace Nz
|
||||||
{
|
{
|
||||||
|
/*!
|
||||||
|
* \brief Constructs a TextSprite object by default
|
||||||
|
*/
|
||||||
|
|
||||||
inline TextSprite::TextSprite() :
|
inline TextSprite::TextSprite() :
|
||||||
m_color(Color::White),
|
m_color(Color::White),
|
||||||
m_scale(1.f)
|
m_scale(1.f)
|
||||||
|
|
@ -14,12 +18,24 @@ namespace Nz
|
||||||
SetDefaultMaterial();
|
SetDefaultMaterial();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Constructs a TextSprite object with a drawer
|
||||||
|
*
|
||||||
|
* \param drawer Drawer used to compose text on the sprite
|
||||||
|
*/
|
||||||
|
|
||||||
inline TextSprite::TextSprite(const AbstractTextDrawer& drawer) :
|
inline TextSprite::TextSprite(const AbstractTextDrawer& drawer) :
|
||||||
TextSprite()
|
TextSprite()
|
||||||
{
|
{
|
||||||
Update(drawer);
|
Update(drawer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Constructs a TextSprite object by assignation
|
||||||
|
*
|
||||||
|
* \param sprite TextSprite to copy into this
|
||||||
|
*/
|
||||||
|
|
||||||
inline TextSprite::TextSprite(const TextSprite& sprite) :
|
inline TextSprite::TextSprite(const TextSprite& sprite) :
|
||||||
InstancedRenderable(sprite),
|
InstancedRenderable(sprite),
|
||||||
m_renderInfos(sprite.m_renderInfos),
|
m_renderInfos(sprite.m_renderInfos),
|
||||||
|
|
@ -40,6 +56,10 @@ namespace Nz
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Clears the data
|
||||||
|
*/
|
||||||
|
|
||||||
inline void TextSprite::Clear()
|
inline void TextSprite::Clear()
|
||||||
{
|
{
|
||||||
m_atlases.clear();
|
m_atlases.clear();
|
||||||
|
|
@ -48,21 +68,42 @@ namespace Nz
|
||||||
m_renderInfos.clear();
|
m_renderInfos.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Gets the color of the text sprite
|
||||||
|
* \return Current color
|
||||||
|
*/
|
||||||
|
|
||||||
inline const Color& TextSprite::GetColor() const
|
inline const Color& TextSprite::GetColor() const
|
||||||
{
|
{
|
||||||
return m_color;
|
return m_color;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Gets the material of the text sprite
|
||||||
|
* \return Current material
|
||||||
|
*/
|
||||||
|
|
||||||
inline const MaterialRef& TextSprite::GetMaterial() const
|
inline const MaterialRef& TextSprite::GetMaterial() const
|
||||||
{
|
{
|
||||||
return m_material;
|
return m_material;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Gets the current scale of the text sprite
|
||||||
|
* \return Current scale
|
||||||
|
*/
|
||||||
|
|
||||||
inline float TextSprite::GetScale() const
|
inline float TextSprite::GetScale() const
|
||||||
{
|
{
|
||||||
return m_scale;
|
return m_scale;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Sets the color of the text sprite
|
||||||
|
*
|
||||||
|
* \param color Color for the text sprite
|
||||||
|
*/
|
||||||
|
|
||||||
inline void TextSprite::SetColor(const Color& color)
|
inline void TextSprite::SetColor(const Color& color)
|
||||||
{
|
{
|
||||||
m_color = color;
|
m_color = color;
|
||||||
|
|
@ -70,6 +111,11 @@ namespace Nz
|
||||||
InvalidateVertices();
|
InvalidateVertices();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Sets the default material of the text sprite (just default material)
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
inline void TextSprite::SetDefaultMaterial()
|
inline void TextSprite::SetDefaultMaterial()
|
||||||
{
|
{
|
||||||
MaterialRef material = Material::New();
|
MaterialRef material = Material::New();
|
||||||
|
|
@ -83,11 +129,23 @@ namespace Nz
|
||||||
SetMaterial(material);
|
SetMaterial(material);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Sets the material of the text sprite
|
||||||
|
*
|
||||||
|
* \param material Material for the text sprite
|
||||||
|
*/
|
||||||
|
|
||||||
inline void TextSprite::SetMaterial(MaterialRef material)
|
inline void TextSprite::SetMaterial(MaterialRef material)
|
||||||
{
|
{
|
||||||
m_material = std::move(material);
|
m_material = std::move(material);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Sets the current scale of the text sprite
|
||||||
|
*
|
||||||
|
* \param scale Scale of the text sprite
|
||||||
|
*/
|
||||||
|
|
||||||
inline void TextSprite::SetScale(float scale)
|
inline void TextSprite::SetScale(float scale)
|
||||||
{
|
{
|
||||||
m_scale = scale;
|
m_scale = scale;
|
||||||
|
|
@ -95,10 +153,12 @@ namespace Nz
|
||||||
InvalidateVertices();
|
InvalidateVertices();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void TextSprite::InvalidateVertices()
|
/*!
|
||||||
{
|
* \brief Sets the current text sprite with the content of the other one
|
||||||
InvalidateInstanceData(0);
|
* \return A reference to this
|
||||||
}
|
*
|
||||||
|
* \param text sprite The other TextSprite
|
||||||
|
*/
|
||||||
|
|
||||||
inline TextSprite& TextSprite::operator=(const TextSprite& text)
|
inline TextSprite& TextSprite::operator=(const TextSprite& text)
|
||||||
{
|
{
|
||||||
|
|
@ -130,6 +190,22 @@ namespace Nz
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Invalidates the vertices
|
||||||
|
*/
|
||||||
|
|
||||||
|
inline void TextSprite::InvalidateVertices()
|
||||||
|
{
|
||||||
|
InvalidateInstanceData(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Creates a new text sprite from the arguments
|
||||||
|
* \return A reference to the newly created text sprite
|
||||||
|
*
|
||||||
|
* \param args Arguments for the text sprite
|
||||||
|
*/
|
||||||
|
|
||||||
template<typename... Args>
|
template<typename... Args>
|
||||||
TextSpriteRef TextSprite::New(Args&&... args)
|
TextSpriteRef TextSprite::New(Args&&... args)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -7,11 +7,22 @@
|
||||||
|
|
||||||
namespace Nz
|
namespace Nz
|
||||||
{
|
{
|
||||||
|
/*!
|
||||||
|
* \brief Gets the texture of the background
|
||||||
|
* \return Texture of the background
|
||||||
|
*/
|
||||||
|
|
||||||
inline const TextureRef& TextureBackground::GetTexture() const
|
inline const TextureRef& TextureBackground::GetTexture() const
|
||||||
{
|
{
|
||||||
return m_texture;
|
return m_texture;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Sets the texture of the background
|
||||||
|
*
|
||||||
|
* \param texture Texture of the background
|
||||||
|
*/
|
||||||
|
|
||||||
inline void TextureBackground::SetTexture(TextureRef texture)
|
inline void TextureBackground::SetTexture(TextureRef texture)
|
||||||
{
|
{
|
||||||
NazaraAssert(!texture || texture->IsValid(), "Invalid texture");
|
NazaraAssert(!texture || texture->IsValid(), "Invalid texture");
|
||||||
|
|
@ -19,6 +30,13 @@ namespace Nz
|
||||||
m_texture = std::move(texture);
|
m_texture = std::move(texture);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Creates a new texture background from the arguments
|
||||||
|
* \return A reference to the newly created texture background
|
||||||
|
*
|
||||||
|
* \param args Arguments for the texture background
|
||||||
|
*/
|
||||||
|
|
||||||
template<typename... Args>
|
template<typename... Args>
|
||||||
TextureBackgroundRef TextureBackground::New(Args&&... args)
|
TextureBackgroundRef TextureBackground::New(Args&&... args)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -491,8 +491,8 @@ namespace Nz
|
||||||
*
|
*
|
||||||
* \remark If volume is infinite, IntersectionSide_Intersecting is returned
|
* \remark If volume is infinite, IntersectionSide_Intersecting is returned
|
||||||
* \remark If volume is null, IntersectionSide_Outside is returned
|
* \remark If volume is null, IntersectionSide_Outside is returned
|
||||||
* \remark If enumeration of the volume is not defined in Extend, a NazaraError is thrown and false is returned
|
* \remark If enumeration of the volume is not defined in Extend, a NazaraError is thrown and IntersectionSide_Outside is returned
|
||||||
* \remark If enumeration of the intersection is not defined in IntersectionSide, a NazaraError is thrown and false is returned. This should not never happen for a user of the library
|
* \remark If enumeration of the intersection is not defined in IntersectionSide, a NazaraError is thrown and IntersectionSide_Outside is returned. This should not never happen for a user of the library
|
||||||
*/
|
*/
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
|
|
|
||||||
|
|
@ -485,7 +485,7 @@ namespace Nz
|
||||||
template<typename T>
|
template<typename T>
|
||||||
T Sphere<T>::SquaredDistance(const Vector3<T>& point) const
|
T Sphere<T>::SquaredDistance(const Vector3<T>& point) const
|
||||||
{
|
{
|
||||||
return Vector3f::Distance(point, GetPosition()) - radius * radius;
|
return Vector3f::SquaredDistance(point, GetPosition() + (point - GetPosition()).Normalize() * radius);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
|
|
||||||
|
|
@ -6,31 +6,62 @@
|
||||||
|
|
||||||
namespace Nz
|
namespace Nz
|
||||||
{
|
{
|
||||||
|
/*!
|
||||||
|
* \brief Gets the last error
|
||||||
|
* \return Socket error
|
||||||
|
*/
|
||||||
|
|
||||||
inline SocketError AbstractSocket::GetLastError() const
|
inline SocketError AbstractSocket::GetLastError() const
|
||||||
{
|
{
|
||||||
return m_lastError;
|
return m_lastError;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Gets the internal socket handle
|
||||||
|
* \return Socket handle
|
||||||
|
*/
|
||||||
|
|
||||||
inline SocketHandle AbstractSocket::GetNativeHandle() const
|
inline SocketHandle AbstractSocket::GetNativeHandle() const
|
||||||
{
|
{
|
||||||
return m_handle;
|
return m_handle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Gets the internal state
|
||||||
|
* \return Socket state
|
||||||
|
*/
|
||||||
|
|
||||||
inline SocketState AbstractSocket::GetState() const
|
inline SocketState AbstractSocket::GetState() const
|
||||||
{
|
{
|
||||||
return m_state;
|
return m_state;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Gets the internal type
|
||||||
|
* \return Socket type
|
||||||
|
*/
|
||||||
|
|
||||||
inline SocketType AbstractSocket::GetType() const
|
inline SocketType AbstractSocket::GetType() const
|
||||||
{
|
{
|
||||||
return m_type;
|
return m_type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Checks whether the blocking is enabled
|
||||||
|
* \return true If successful
|
||||||
|
*/
|
||||||
|
|
||||||
inline bool AbstractSocket::IsBlockingEnabled() const
|
inline bool AbstractSocket::IsBlockingEnabled() const
|
||||||
{
|
{
|
||||||
return m_isBlockingEnabled;
|
return m_isBlockingEnabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Updates the state of the socket
|
||||||
|
*
|
||||||
|
* \param newState Next state for the socket
|
||||||
|
*/
|
||||||
|
|
||||||
inline void AbstractSocket::UpdateState(SocketState newState)
|
inline void AbstractSocket::UpdateState(SocketState newState)
|
||||||
{
|
{
|
||||||
if (m_state != newState)
|
if (m_state != newState)
|
||||||
|
|
|
||||||
|
|
@ -27,17 +27,22 @@
|
||||||
#ifndef NAZARA_CONFIG_NETWORK_HPP
|
#ifndef NAZARA_CONFIG_NETWORK_HPP
|
||||||
#define NAZARA_CONFIG_NETWORK_HPP
|
#define NAZARA_CONFIG_NETWORK_HPP
|
||||||
|
|
||||||
/// Chaque modification d'un paramètre du module nécessite une recompilation de celui-ci
|
/*!
|
||||||
|
* \defgroup network (NazaraNetwork) Network module
|
||||||
|
* Network/System module including classes to handle networking elements...
|
||||||
|
*/
|
||||||
|
|
||||||
// Utilise le MemoryManager pour gérer les allocations dynamiques (détecte les leaks au prix d'allocations/libérations dynamiques plus lentes)
|
/// Each modification of a paramater of the module needs a recompilation of the unit
|
||||||
|
|
||||||
|
// Use the MemoryManager to manage dynamic allocations (can detect memory leak but allocations/frees are slower)
|
||||||
#define NAZARA_NETWORK_MANAGE_MEMORY 0
|
#define NAZARA_NETWORK_MANAGE_MEMORY 0
|
||||||
|
|
||||||
// Active les tests de sécurité basés sur le code (Conseillé pour le développement)
|
// Activate the security tests based on the code (Advised for development)
|
||||||
#define NAZARA_NETWORK_SAFE 1
|
#define NAZARA_NETWORK_SAFE 1
|
||||||
|
|
||||||
/// Chaque modification d'un paramètre ci-dessous implique une modification (souvent mineure) du code
|
/// Each modification of a parameter following implies a modification (often minor) of the code
|
||||||
|
|
||||||
/// Vérification des valeurs et types de certaines constantes
|
/// Checking the values and types of certain constants
|
||||||
#include <Nazara/Network/ConfigCheck.hpp>
|
#include <Nazara/Network/ConfigCheck.hpp>
|
||||||
|
|
||||||
#if defined(NAZARA_STATIC)
|
#if defined(NAZARA_STATIC)
|
||||||
|
|
|
||||||
|
|
@ -7,11 +7,11 @@
|
||||||
#ifndef NAZARA_CONFIG_CHECK_NETWORK_HPP
|
#ifndef NAZARA_CONFIG_CHECK_NETWORK_HPP
|
||||||
#define NAZARA_CONFIG_CHECK_NETWORK_HPP
|
#define NAZARA_CONFIG_CHECK_NETWORK_HPP
|
||||||
|
|
||||||
/// Ce fichier sert à vérifier la valeur des constantes du fichier Config.hpp
|
/// This file is used to check the constant values defined in Config.hpp
|
||||||
|
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
|
|
||||||
// On force la valeur de MANAGE_MEMORY en mode debug
|
// We fore the value of MANAGE_MEMORY in debug
|
||||||
#if defined(NAZARA_DEBUG) && !NAZARA_NETWORK_MANAGE_MEMORY
|
#if defined(NAZARA_DEBUG) && !NAZARA_NETWORK_MANAGE_MEMORY
|
||||||
#undef NAZARA_NETWORK_MANAGE_MEMORY
|
#undef NAZARA_NETWORK_MANAGE_MEMORY
|
||||||
#define NAZARA_NETWORK_MANAGE_MEMORY 0
|
#define NAZARA_NETWORK_MANAGE_MEMORY 0
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
// This file is part of the "Nazara Engine - Network module"
|
// This file is part of the "Nazara Engine - Network module"
|
||||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||||
|
|
||||||
// On suppose que Debug.hpp a déjà été inclus, tout comme Config.hpp
|
// We suppose that Debug.hpp is already included, same goes for Config.hpp
|
||||||
#if NAZARA_NETWORK_MANAGE_MEMORY
|
#if NAZARA_NETWORK_MANAGE_MEMORY
|
||||||
#undef delete
|
#undef delete
|
||||||
#undef new
|
#undef new
|
||||||
|
|
|
||||||
|
|
@ -9,11 +9,22 @@
|
||||||
|
|
||||||
namespace Nz
|
namespace Nz
|
||||||
{
|
{
|
||||||
|
/*!
|
||||||
|
* \brief Constructs a IpAddress object by default
|
||||||
|
*/
|
||||||
|
|
||||||
inline IpAddress::IpAddress() :
|
inline IpAddress::IpAddress() :
|
||||||
m_isValid(false)
|
m_isValid(false)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Constructs a IpAddress object with an IP and a port
|
||||||
|
*
|
||||||
|
* \param ip IPv4 address
|
||||||
|
* \param port Port of the IP
|
||||||
|
*/
|
||||||
|
|
||||||
inline IpAddress::IpAddress(const IPv4& ip, UInt16 port) :
|
inline IpAddress::IpAddress(const IPv4& ip, UInt16 port) :
|
||||||
m_ipv4(ip),
|
m_ipv4(ip),
|
||||||
m_protocol(NetProtocol_IPv4),
|
m_protocol(NetProtocol_IPv4),
|
||||||
|
|
@ -22,6 +33,13 @@ namespace Nz
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Constructs a IpAddress object with an IP and a port
|
||||||
|
*
|
||||||
|
* \param ip IPv6 address
|
||||||
|
* \param port Port of the IP
|
||||||
|
*/
|
||||||
|
|
||||||
inline IpAddress::IpAddress(const IPv6& ip, UInt16 port) :
|
inline IpAddress::IpAddress(const IPv6& ip, UInt16 port) :
|
||||||
m_ipv6(ip),
|
m_ipv6(ip),
|
||||||
m_protocol(NetProtocol_IPv6),
|
m_protocol(NetProtocol_IPv6),
|
||||||
|
|
@ -30,46 +48,100 @@ namespace Nz
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Constructs a IpAddress object with an IP and a port
|
||||||
|
*
|
||||||
|
* \param ip IPv4 address (a.b.c.d)
|
||||||
|
* \param port Port of the IP
|
||||||
|
*/
|
||||||
|
|
||||||
inline IpAddress::IpAddress(const UInt8& a, const UInt8& b, const UInt8& c, const UInt8& d, UInt16 port) :
|
inline IpAddress::IpAddress(const UInt8& a, const UInt8& b, const UInt8& c, const UInt8& d, UInt16 port) :
|
||||||
IpAddress(IPv4{a, b, c, d}, port)
|
IpAddress(IPv4{a, b, c, d}, port)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Constructs a IpAddress object with an IP and a port
|
||||||
|
*
|
||||||
|
* \param ip IPv6 address (a.b.c.d.e.f.g.h)
|
||||||
|
* \param port Port of the IP
|
||||||
|
*/
|
||||||
|
|
||||||
inline IpAddress::IpAddress(const UInt16& a, const UInt16& b, const UInt16& c, const UInt16& d, const UInt16& e, const UInt16& f, const UInt16& g, const UInt16& h, UInt16 port) :
|
inline IpAddress::IpAddress(const UInt16& a, const UInt16& b, const UInt16& c, const UInt16& d, const UInt16& e, const UInt16& f, const UInt16& g, const UInt16& h, UInt16 port) :
|
||||||
IpAddress(IPv6{a, b, c, d, e, f, g, h}, port)
|
IpAddress(IPv6{a, b, c, d, e, f, g, h}, port)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Constructs a IpAddress object with a C-string
|
||||||
|
*
|
||||||
|
* \param address Hostname or textual IP address
|
||||||
|
*/
|
||||||
|
|
||||||
inline IpAddress::IpAddress(const char* address)
|
inline IpAddress::IpAddress(const char* address)
|
||||||
{
|
{
|
||||||
BuildFromAddress(address);
|
BuildFromAddress(address);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Constructs a IpAddress object with a string
|
||||||
|
*
|
||||||
|
* \param address Hostname or textual IP address
|
||||||
|
*/
|
||||||
|
|
||||||
inline IpAddress::IpAddress(const String& address)
|
inline IpAddress::IpAddress(const String& address)
|
||||||
{
|
{
|
||||||
BuildFromAddress(address.GetConstBuffer());
|
BuildFromAddress(address.GetConstBuffer());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Gets the port
|
||||||
|
* \return Port attached to the IP address
|
||||||
|
*/
|
||||||
|
|
||||||
inline UInt16 IpAddress::GetPort() const
|
inline UInt16 IpAddress::GetPort() const
|
||||||
{
|
{
|
||||||
return m_port;
|
return m_port;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Gets the net protocol
|
||||||
|
* \return Protocol attached to the IP address
|
||||||
|
*/
|
||||||
|
|
||||||
inline NetProtocol IpAddress::GetProtocol() const
|
inline NetProtocol IpAddress::GetProtocol() const
|
||||||
{
|
{
|
||||||
return m_protocol;
|
return m_protocol;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Checks whether the IP address is valid
|
||||||
|
* \return true If successful
|
||||||
|
*/
|
||||||
|
|
||||||
inline bool IpAddress::IsValid() const
|
inline bool IpAddress::IsValid() const
|
||||||
{
|
{
|
||||||
return m_isValid;
|
return m_isValid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Sets the port
|
||||||
|
*
|
||||||
|
* \param port Port attached to the IP address
|
||||||
|
*/
|
||||||
|
|
||||||
inline void IpAddress::SetPort(UInt16 port)
|
inline void IpAddress::SetPort(UInt16 port)
|
||||||
{
|
{
|
||||||
m_port = port;
|
m_port = port;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Converts IpAddress to IPv4
|
||||||
|
* \return Corresponding IPv4
|
||||||
|
*
|
||||||
|
* \remark Produces a NazaraAssert if net protocol is not IPv4
|
||||||
|
*/
|
||||||
|
|
||||||
inline IpAddress::IPv4 IpAddress::ToIPv4() const
|
inline IpAddress::IPv4 IpAddress::ToIPv4() const
|
||||||
{
|
{
|
||||||
NazaraAssert(m_isValid && m_protocol == NetProtocol_IPv4, "Address is not a valid IPv4");
|
NazaraAssert(m_isValid && m_protocol == NetProtocol_IPv4, "Address is not a valid IPv4");
|
||||||
|
|
@ -77,6 +149,13 @@ namespace Nz
|
||||||
return m_ipv4;
|
return m_ipv4;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Converts IpAddress to IPv6
|
||||||
|
* \return Corresponding IPv6
|
||||||
|
*
|
||||||
|
* \remark Produces a NazaraAssert if net protocol is not IPv6
|
||||||
|
*/
|
||||||
|
|
||||||
inline IpAddress::IPv6 IpAddress::ToIPv6() const
|
inline IpAddress::IPv6 IpAddress::ToIPv6() const
|
||||||
{
|
{
|
||||||
NazaraAssert(m_isValid && m_protocol == NetProtocol_IPv6, "IP is not a valid IPv6");
|
NazaraAssert(m_isValid && m_protocol == NetProtocol_IPv6, "IP is not a valid IPv6");
|
||||||
|
|
@ -84,6 +163,13 @@ namespace Nz
|
||||||
return m_ipv6;
|
return m_ipv6;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Converts IpAddress to UInt32
|
||||||
|
* \return Corresponding UInt32
|
||||||
|
*
|
||||||
|
* \remark Produces a NazaraAssert if net protocol is not IPv4
|
||||||
|
*/
|
||||||
|
|
||||||
inline UInt32 IpAddress::ToUInt32() const
|
inline UInt32 IpAddress::ToUInt32() const
|
||||||
{
|
{
|
||||||
NazaraAssert(m_isValid && m_protocol == NetProtocol_IPv4, "Address is not a valid IPv4");
|
NazaraAssert(m_isValid && m_protocol == NetProtocol_IPv4, "Address is not a valid IPv4");
|
||||||
|
|
@ -94,17 +180,40 @@ namespace Nz
|
||||||
UInt32(m_ipv4[3]) << 0;
|
UInt32(m_ipv4[3]) << 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Converts IpAddress to boolean
|
||||||
|
* \return true If IpAddress is valid
|
||||||
|
*
|
||||||
|
* \see IsValid
|
||||||
|
*/
|
||||||
|
|
||||||
inline IpAddress::operator bool() const
|
inline IpAddress::operator bool() const
|
||||||
{
|
{
|
||||||
return IsValid();
|
return IsValid();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Output operator
|
||||||
|
* \return The stream
|
||||||
|
*
|
||||||
|
* \param out The stream
|
||||||
|
* \param address The address to output
|
||||||
|
*/
|
||||||
|
|
||||||
inline std::ostream& operator<<(std::ostream& out, const IpAddress& address)
|
inline std::ostream& operator<<(std::ostream& out, const IpAddress& address)
|
||||||
{
|
{
|
||||||
out << "IpAddress(" << address.ToString() << ')';
|
out << "IpAddress(" << address.ToString() << ')';
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Compares the IpAddress to other one
|
||||||
|
* \return true if the ip addresses are the same
|
||||||
|
*
|
||||||
|
* \param first First ip address to compare
|
||||||
|
* \param second Second ip address to compare with
|
||||||
|
*/
|
||||||
|
|
||||||
inline bool operator==(const IpAddress& first, const IpAddress& second)
|
inline bool operator==(const IpAddress& first, const IpAddress& second)
|
||||||
{
|
{
|
||||||
// We need to check the validity of each address before comparing them
|
// We need to check the validity of each address before comparing them
|
||||||
|
|
@ -146,11 +255,27 @@ namespace Nz
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Compares the IpAddress to other one
|
||||||
|
* \return false if the ip addresses are the same
|
||||||
|
*
|
||||||
|
* \param first First ip address to compare
|
||||||
|
* \param second Second ip address to compare with
|
||||||
|
*/
|
||||||
|
|
||||||
inline bool operator!=(const IpAddress& first, const IpAddress& second)
|
inline bool operator!=(const IpAddress& first, const IpAddress& second)
|
||||||
{
|
{
|
||||||
return !operator==(first, second);
|
return !operator==(first, second);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Compares the IpAddress to other one
|
||||||
|
* \return true if this ip address is inferior to the other one
|
||||||
|
*
|
||||||
|
* \param first First ip address to compare
|
||||||
|
* \param second Second ip address to compare with
|
||||||
|
*/
|
||||||
|
|
||||||
inline bool operator<(const IpAddress& first, const IpAddress& second)
|
inline bool operator<(const IpAddress& first, const IpAddress& second)
|
||||||
{
|
{
|
||||||
// If the second address is invalid, there's no way we're lower than it
|
// If the second address is invalid, there's no way we're lower than it
|
||||||
|
|
@ -196,16 +321,40 @@ namespace Nz
|
||||||
return false; //< Same address
|
return false; //< Same address
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Compares the IpAddress to other one
|
||||||
|
* \return true if this ip address is inferior or equal to the other one
|
||||||
|
*
|
||||||
|
* \param first First ip address to compare
|
||||||
|
* \param second Second ip address to compare with
|
||||||
|
*/
|
||||||
|
|
||||||
inline bool operator<=(const IpAddress& first, const IpAddress& second)
|
inline bool operator<=(const IpAddress& first, const IpAddress& second)
|
||||||
{
|
{
|
||||||
return !operator<(second, first);
|
return !operator<(second, first);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Compares the IpAddress to other one
|
||||||
|
* \return true if this ip address is greather to the other one
|
||||||
|
*
|
||||||
|
* \param first First ip address to compare
|
||||||
|
* \param second Second ip address to compare with
|
||||||
|
*/
|
||||||
|
|
||||||
inline bool operator>(const IpAddress& first, const IpAddress& second)
|
inline bool operator>(const IpAddress& first, const IpAddress& second)
|
||||||
{
|
{
|
||||||
return second < first;
|
return second < first;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Compares the IpAddress to other one
|
||||||
|
* \return true if this ip address is greather or equal to the other one
|
||||||
|
*
|
||||||
|
* \param first First ip address to compare
|
||||||
|
* \param second Second ip address to compare with
|
||||||
|
*/
|
||||||
|
|
||||||
inline bool operator>=(const IpAddress& first, const IpAddress& second)
|
inline bool operator>=(const IpAddress& first, const IpAddress& second)
|
||||||
{
|
{
|
||||||
return !operator<(first, second);
|
return !operator<(first, second);
|
||||||
|
|
@ -217,6 +366,13 @@ namespace std
|
||||||
template<>
|
template<>
|
||||||
struct hash<Nz::IpAddress>
|
struct hash<Nz::IpAddress>
|
||||||
{
|
{
|
||||||
|
/*!
|
||||||
|
* \brief Converts IpAddress to hash
|
||||||
|
* \return Hash of the IpAddress
|
||||||
|
*
|
||||||
|
* \param ip IpAddress to hash
|
||||||
|
*/
|
||||||
|
|
||||||
size_t operator()(const Nz::IpAddress& ip) const
|
size_t operator()(const Nz::IpAddress& ip) const
|
||||||
{
|
{
|
||||||
if (!ip)
|
if (!ip)
|
||||||
|
|
@ -224,7 +380,7 @@ namespace std
|
||||||
|
|
||||||
// This is SDBM adapted for IP addresses, tested to generate the least collisions possible
|
// This is SDBM adapted for IP addresses, tested to generate the least collisions possible
|
||||||
// (It doesn't mean it cannot be improved though)
|
// (It doesn't mean it cannot be improved though)
|
||||||
std::size_t h = 0;
|
std::size_t hash = 0;
|
||||||
switch (ip.GetProtocol())
|
switch (ip.GetProtocol())
|
||||||
{
|
{
|
||||||
case Nz::NetProtocol_Any:
|
case Nz::NetProtocol_Any:
|
||||||
|
|
@ -233,20 +389,20 @@ namespace std
|
||||||
|
|
||||||
case Nz::NetProtocol_IPv4:
|
case Nz::NetProtocol_IPv4:
|
||||||
{
|
{
|
||||||
h = ip.ToUInt32() + (h << 6) + (h << 16) - h;
|
hash = ip.ToUInt32() + (hash << 6) + (hash << 16) - hash;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Nz::NetProtocol_IPv6:
|
case Nz::NetProtocol_IPv6:
|
||||||
{
|
{
|
||||||
Nz::IpAddress::IPv6 v6 = ip.ToIPv6();
|
Nz::IpAddress::IPv6 v6 = ip.ToIPv6();
|
||||||
for (std::size_t i = 0; i < v6.size(); i++)
|
for (std::size_t i = 0; i < v6.size(); i++)
|
||||||
h = v6[i] + (h << 6) + (h << 16) - h;
|
hash = v6[i] + (hash << 6) + (hash << 16) - hash;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return ip.GetPort() + (h << 6) + (h << 16) - h;
|
return ip.GetPort() + (hash << 6) + (hash << 16) - hash;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,21 +9,46 @@
|
||||||
|
|
||||||
namespace Nz
|
namespace Nz
|
||||||
{
|
{
|
||||||
|
/*!
|
||||||
|
* \brief Constructs a NetPacket object by default
|
||||||
|
*/
|
||||||
|
|
||||||
inline NetPacket::NetPacket() :
|
inline NetPacket::NetPacket() :
|
||||||
m_netCode(NetCode_Invalid)
|
m_netCode(NetCode_Invalid)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Constructs a NetPacket object with a packet number and a minimal capacity
|
||||||
|
*
|
||||||
|
* \param netCode Packet number
|
||||||
|
* \param minCapacity Minimal capacity of the packet
|
||||||
|
*/
|
||||||
|
|
||||||
inline NetPacket::NetPacket(UInt16 netCode, std::size_t minCapacity)
|
inline NetPacket::NetPacket(UInt16 netCode, std::size_t minCapacity)
|
||||||
{
|
{
|
||||||
Reset(netCode, minCapacity);
|
Reset(netCode, minCapacity);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Constructs a NetPacket object with a packet number and raw memory
|
||||||
|
*
|
||||||
|
* \param netCode Packet number
|
||||||
|
* \param ptr Raw memory
|
||||||
|
* \param size Size of the memory
|
||||||
|
*/
|
||||||
|
|
||||||
inline NetPacket::NetPacket(UInt16 netCode, const void* ptr, std::size_t size)
|
inline NetPacket::NetPacket(UInt16 netCode, const void* ptr, std::size_t size)
|
||||||
{
|
{
|
||||||
Reset(netCode, ptr, size);
|
Reset(netCode, ptr, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Constructs a NetPacket object with another one by move semantic
|
||||||
|
*
|
||||||
|
* \param packet NetPacket to move into this
|
||||||
|
*/
|
||||||
|
|
||||||
inline NetPacket::NetPacket(NetPacket&& packet) :
|
inline NetPacket::NetPacket(NetPacket&& packet) :
|
||||||
ByteStream(std::move(packet)),
|
ByteStream(std::move(packet)),
|
||||||
m_buffer(std::move(packet.m_buffer)),
|
m_buffer(std::move(packet.m_buffer)),
|
||||||
|
|
@ -35,12 +60,23 @@ namespace Nz
|
||||||
SetStream(&m_memoryStream);
|
SetStream(&m_memoryStream);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Destructs the object
|
||||||
|
*/
|
||||||
|
|
||||||
inline NetPacket::~NetPacket()
|
inline NetPacket::~NetPacket()
|
||||||
{
|
{
|
||||||
FlushBits(); //< Needs to be done here as the stream will be freed before ByteStream calls it
|
FlushBits(); //< Needs to be done here as the stream will be freed before ByteStream calls it
|
||||||
FreeStream();
|
FreeStream();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Gets the raw buffer
|
||||||
|
* \return Constant raw buffer
|
||||||
|
*
|
||||||
|
* \remark Produces a NazaraAssert if internal buffer is invalid
|
||||||
|
*/
|
||||||
|
|
||||||
inline const UInt8* NetPacket::GetConstData() const
|
inline const UInt8* NetPacket::GetConstData() const
|
||||||
{
|
{
|
||||||
NazaraAssert(m_buffer, "Invalid buffer");
|
NazaraAssert(m_buffer, "Invalid buffer");
|
||||||
|
|
@ -48,6 +84,13 @@ namespace Nz
|
||||||
return m_buffer->GetConstBuffer();
|
return m_buffer->GetConstBuffer();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Gets the raw buffer
|
||||||
|
* \return Raw buffer
|
||||||
|
*
|
||||||
|
* \remark Produces a NazaraAssert if internal buffer is invalid
|
||||||
|
*/
|
||||||
|
|
||||||
inline UInt8* NetPacket::GetData() const
|
inline UInt8* NetPacket::GetData() const
|
||||||
{
|
{
|
||||||
NazaraAssert(m_buffer, "Invalid buffer");
|
NazaraAssert(m_buffer, "Invalid buffer");
|
||||||
|
|
@ -55,6 +98,11 @@ namespace Nz
|
||||||
return m_buffer->GetBuffer();
|
return m_buffer->GetBuffer();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Gets the size of the data
|
||||||
|
* \return Size of the data
|
||||||
|
*/
|
||||||
|
|
||||||
inline size_t NetPacket::GetDataSize() const
|
inline size_t NetPacket::GetDataSize() const
|
||||||
{
|
{
|
||||||
if (m_buffer)
|
if (m_buffer)
|
||||||
|
|
@ -63,22 +111,46 @@ namespace Nz
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Gets the packet number
|
||||||
|
* \return Packet number
|
||||||
|
*/
|
||||||
|
|
||||||
inline UInt16 NetPacket::GetNetCode() const
|
inline UInt16 NetPacket::GetNetCode() const
|
||||||
{
|
{
|
||||||
return m_netCode;
|
return m_netCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Resets the packet
|
||||||
|
*/
|
||||||
|
|
||||||
inline void NetPacket::Reset()
|
inline void NetPacket::Reset()
|
||||||
{
|
{
|
||||||
FreeStream();
|
FreeStream();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Resets the packet with a packet number and a minimal capacity
|
||||||
|
*
|
||||||
|
* \param netCode Packet number
|
||||||
|
* \param minCapacity Minimal capacity of the packet
|
||||||
|
*/
|
||||||
|
|
||||||
inline void NetPacket::Reset(UInt16 netCode, std::size_t minCapacity)
|
inline void NetPacket::Reset(UInt16 netCode, std::size_t minCapacity)
|
||||||
{
|
{
|
||||||
InitStream(HeaderSize + minCapacity, HeaderSize, OpenMode_ReadWrite);
|
InitStream(HeaderSize + minCapacity, HeaderSize, OpenMode_ReadWrite);
|
||||||
m_netCode = netCode;
|
m_netCode = netCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Resets the packet with a packet number and raw memory
|
||||||
|
*
|
||||||
|
* \param netCode Packet number
|
||||||
|
* \param ptr Raw memory
|
||||||
|
* \param size Size of the memory
|
||||||
|
*/
|
||||||
|
|
||||||
inline void NetPacket::Reset(UInt16 netCode, const void* ptr, std::size_t size)
|
inline void NetPacket::Reset(UInt16 netCode, const void* ptr, std::size_t size)
|
||||||
{
|
{
|
||||||
InitStream(HeaderSize + size, HeaderSize, OpenMode_ReadOnly);
|
InitStream(HeaderSize + size, HeaderSize, OpenMode_ReadOnly);
|
||||||
|
|
@ -88,6 +160,14 @@ namespace Nz
|
||||||
m_netCode = netCode;
|
m_netCode = netCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Resizes the packet
|
||||||
|
*
|
||||||
|
* \param newSize Size for the resizing operation
|
||||||
|
*
|
||||||
|
* \remark Produces a NazaraAssert if internal buffer is invalid
|
||||||
|
*/
|
||||||
|
|
||||||
inline void NetPacket::Resize(std::size_t newSize)
|
inline void NetPacket::Resize(std::size_t newSize)
|
||||||
{
|
{
|
||||||
NazaraAssert(m_buffer, "Invalid buffer");
|
NazaraAssert(m_buffer, "Invalid buffer");
|
||||||
|
|
@ -95,11 +175,24 @@ namespace Nz
|
||||||
m_buffer->Resize(newSize);
|
m_buffer->Resize(newSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Sets the packet number
|
||||||
|
*
|
||||||
|
* \param netCode Packet number
|
||||||
|
*/
|
||||||
|
|
||||||
inline void NetPacket::SetNetCode(UInt16 netCode)
|
inline void NetPacket::SetNetCode(UInt16 netCode)
|
||||||
{
|
{
|
||||||
m_netCode = netCode;
|
m_netCode = netCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Moves the NetPacket into this
|
||||||
|
* \return A reference to this
|
||||||
|
*
|
||||||
|
* \param packet NetPacket to move in this
|
||||||
|
*/
|
||||||
|
|
||||||
inline NetPacket& Nz::NetPacket::operator=(NetPacket&& packet)
|
inline NetPacket& Nz::NetPacket::operator=(NetPacket&& packet)
|
||||||
{
|
{
|
||||||
FreeStream();
|
FreeStream();
|
||||||
|
|
|
||||||
|
|
@ -8,31 +8,66 @@
|
||||||
|
|
||||||
namespace Nz
|
namespace Nz
|
||||||
{
|
{
|
||||||
|
/*!
|
||||||
|
* \brief Closes the connection
|
||||||
|
*/
|
||||||
|
|
||||||
inline void RUdpConnection::Close()
|
inline void RUdpConnection::Close()
|
||||||
{
|
{
|
||||||
m_socket.Close();
|
m_socket.Close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Disconnects the connection
|
||||||
|
*
|
||||||
|
* \see Close
|
||||||
|
*/
|
||||||
|
|
||||||
inline void RUdpConnection::Disconnect()
|
inline void RUdpConnection::Disconnect()
|
||||||
{
|
{
|
||||||
Close();
|
Close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Gets the bound address
|
||||||
|
* \return IpAddress we are linked to
|
||||||
|
*/
|
||||||
|
|
||||||
inline IpAddress RUdpConnection::GetBoundAddress() const
|
inline IpAddress RUdpConnection::GetBoundAddress() const
|
||||||
{
|
{
|
||||||
return m_socket.GetBoundAddress();
|
return m_socket.GetBoundAddress();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Gets the port of the bound address
|
||||||
|
* \return Port we are linked to
|
||||||
|
*/
|
||||||
|
|
||||||
inline UInt16 RUdpConnection::GetBoundPort() const
|
inline UInt16 RUdpConnection::GetBoundPort() const
|
||||||
{
|
{
|
||||||
return m_socket.GetBoundPort();
|
return m_socket.GetBoundPort();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Gets the last error
|
||||||
|
* \return Socket error
|
||||||
|
*/
|
||||||
|
|
||||||
inline SocketError RUdpConnection::GetLastError() const
|
inline SocketError RUdpConnection::GetLastError() const
|
||||||
{
|
{
|
||||||
return m_lastError;
|
return m_lastError;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Listens to a socket
|
||||||
|
* \return true If successfully bound
|
||||||
|
*
|
||||||
|
* \param protocol Net protocol to listen to
|
||||||
|
* \param port Port to listen to
|
||||||
|
*
|
||||||
|
* \remark Produces a NazaraAssert if protocol is unknown or any
|
||||||
|
*/
|
||||||
|
|
||||||
inline bool RUdpConnection::Listen(NetProtocol protocol, UInt16 port)
|
inline bool RUdpConnection::Listen(NetProtocol protocol, UInt16 port)
|
||||||
{
|
{
|
||||||
NazaraAssert(protocol != NetProtocol_Any, "Any protocol not supported for Listen"); //< TODO
|
NazaraAssert(protocol != NetProtocol_Any, "Any protocol not supported for Listen"); //< TODO
|
||||||
|
|
@ -59,16 +94,36 @@ namespace Nz
|
||||||
return Listen(any);
|
return Listen(any);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Sets the protocol id
|
||||||
|
*
|
||||||
|
* \param protocolId Protocol ID like NNet
|
||||||
|
*/
|
||||||
|
|
||||||
inline void RUdpConnection::SetProtocolId(UInt32 protocolId)
|
inline void RUdpConnection::SetProtocolId(UInt32 protocolId)
|
||||||
{
|
{
|
||||||
m_protocol = protocolId;
|
m_protocol = protocolId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Sets the time before ack
|
||||||
|
*
|
||||||
|
* \param Time before acking to send many together (in ms)
|
||||||
|
*/
|
||||||
|
|
||||||
inline void RUdpConnection::SetTimeBeforeAck(UInt32 ms)
|
inline void RUdpConnection::SetTimeBeforeAck(UInt32 ms)
|
||||||
{
|
{
|
||||||
m_forceAckSendTime = ms * 1000; //< Store in microseconds for easier handling
|
m_forceAckSendTime = ms * 1000; //< Store in microseconds for easier handling
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Computes the difference of sequence
|
||||||
|
* \return Delta between the two sequences
|
||||||
|
*
|
||||||
|
* \param sequence First sequence
|
||||||
|
* \param sequence2 Second sequence
|
||||||
|
*/
|
||||||
|
|
||||||
inline unsigned int RUdpConnection::ComputeSequenceDifference(SequenceIndex sequence, SequenceIndex sequence2)
|
inline unsigned int RUdpConnection::ComputeSequenceDifference(SequenceIndex sequence, SequenceIndex sequence2)
|
||||||
{
|
{
|
||||||
unsigned int difference;
|
unsigned int difference;
|
||||||
|
|
@ -77,9 +132,16 @@ namespace Nz
|
||||||
else
|
else
|
||||||
difference = sequence - sequence2;
|
difference = sequence - sequence2;
|
||||||
|
|
||||||
return 0;
|
return difference;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Checks whether the peer has pending packets
|
||||||
|
* \return true If it is the case
|
||||||
|
*
|
||||||
|
* \param peer Data relative to the peer
|
||||||
|
*/
|
||||||
|
|
||||||
inline bool RUdpConnection::HasPendingPackets(PeerData& peer)
|
inline bool RUdpConnection::HasPendingPackets(PeerData& peer)
|
||||||
{
|
{
|
||||||
for (unsigned int priority = PacketPriority_Highest; priority <= PacketPriority_Lowest; ++priority)
|
for (unsigned int priority = PacketPriority_Highest; priority <= PacketPriority_Lowest; ++priority)
|
||||||
|
|
@ -94,6 +156,14 @@ namespace Nz
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Checks whether the ack is more recent
|
||||||
|
* \return true If it is the case
|
||||||
|
*
|
||||||
|
* \param ack First sequence
|
||||||
|
* \param ack2 Second sequence
|
||||||
|
*/
|
||||||
|
|
||||||
inline bool RUdpConnection::IsAckMoreRecent(SequenceIndex ack, SequenceIndex ack2)
|
inline bool RUdpConnection::IsAckMoreRecent(SequenceIndex ack, SequenceIndex ack2)
|
||||||
{
|
{
|
||||||
constexpr SequenceIndex maxDifference = std::numeric_limits<SequenceIndex>::max() / 2;
|
constexpr SequenceIndex maxDifference = std::numeric_limits<SequenceIndex>::max() / 2;
|
||||||
|
|
@ -106,6 +176,13 @@ namespace Nz
|
||||||
return false; ///< Same ack
|
return false; ///< Same ack
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Checks whether the connection is reliable
|
||||||
|
* \return true If it is the case
|
||||||
|
*
|
||||||
|
* \remark Produces a NazaraError if enumeration is invalid
|
||||||
|
*/
|
||||||
|
|
||||||
inline bool RUdpConnection::IsReliable(PacketReliability reliability)
|
inline bool RUdpConnection::IsReliable(PacketReliability reliability)
|
||||||
{
|
{
|
||||||
switch (reliability)
|
switch (reliability)
|
||||||
|
|
@ -122,6 +199,14 @@ namespace Nz
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Simulates the loss of packets on network
|
||||||
|
*
|
||||||
|
* \param packetLoss Ratio of packet loss according to bernoulli distribution
|
||||||
|
*
|
||||||
|
* \remark Produces a NazaraAssert if packetLoss is not in between 0.0 and 1.0
|
||||||
|
*/
|
||||||
|
|
||||||
inline void RUdpConnection::SimulateNetwork(double packetLoss)
|
inline void RUdpConnection::SimulateNetwork(double packetLoss)
|
||||||
{
|
{
|
||||||
NazaraAssert(packetLoss >= 0.0 && packetLoss <= 1.0, "Packet loss must be in range [0..1]");
|
NazaraAssert(packetLoss >= 0.0 && packetLoss <= 1.0, "Packet loss must be in range [0..1]");
|
||||||
|
|
|
||||||
|
|
@ -79,8 +79,8 @@ namespace Nz
|
||||||
PendingPacket m_pendingPacket;
|
PendingPacket m_pendingPacket;
|
||||||
UInt64 m_keepAliveInterval;
|
UInt64 m_keepAliveInterval;
|
||||||
UInt64 m_keepAliveTime;
|
UInt64 m_keepAliveTime;
|
||||||
bool m_isKeepAliveEnabled;
|
|
||||||
bool m_isLowDelayEnabled;
|
bool m_isLowDelayEnabled;
|
||||||
|
bool m_isKeepAliveEnabled;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,10 @@
|
||||||
|
|
||||||
namespace Nz
|
namespace Nz
|
||||||
{
|
{
|
||||||
|
/*!
|
||||||
|
* \brief Constructs a TcpClient object by default
|
||||||
|
*/
|
||||||
|
|
||||||
inline TcpClient::TcpClient() :
|
inline TcpClient::TcpClient() :
|
||||||
AbstractSocket(SocketType_TCP),
|
AbstractSocket(SocketType_TCP),
|
||||||
Stream(StreamOption_Sequential),
|
Stream(StreamOption_Sequential),
|
||||||
|
|
@ -17,31 +21,62 @@ namespace Nz
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Disconnects the connection
|
||||||
|
*
|
||||||
|
* \see Close
|
||||||
|
*/
|
||||||
|
|
||||||
inline void TcpClient::Disconnect()
|
inline void TcpClient::Disconnect()
|
||||||
{
|
{
|
||||||
Close();
|
Close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Gets the interval between two keep alive pings
|
||||||
|
* \return Interval in milliseconds between two pings
|
||||||
|
*/
|
||||||
|
|
||||||
inline UInt64 TcpClient::GetKeepAliveInterval() const
|
inline UInt64 TcpClient::GetKeepAliveInterval() const
|
||||||
{
|
{
|
||||||
return m_keepAliveInterval;
|
return m_keepAliveInterval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Gets the time before expiration of connection
|
||||||
|
* \return Time in milliseconds before expiration
|
||||||
|
*/
|
||||||
|
|
||||||
inline UInt64 TcpClient::GetKeepAliveTime() const
|
inline UInt64 TcpClient::GetKeepAliveTime() const
|
||||||
{
|
{
|
||||||
return m_keepAliveTime;
|
return m_keepAliveTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Gets the remote address
|
||||||
|
* \return Address of peer
|
||||||
|
*/
|
||||||
|
|
||||||
inline IpAddress TcpClient::GetRemoteAddress() const
|
inline IpAddress TcpClient::GetRemoteAddress() const
|
||||||
{
|
{
|
||||||
return m_peerAddress;
|
return m_peerAddress;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Checks whether low delay is enabled
|
||||||
|
* \return true If it is the case
|
||||||
|
*/
|
||||||
|
|
||||||
inline bool TcpClient::IsLowDelayEnabled() const
|
inline bool TcpClient::IsLowDelayEnabled() const
|
||||||
{
|
{
|
||||||
return m_isLowDelayEnabled;
|
return m_isLowDelayEnabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Checks whether the keep alive flag is enabled
|
||||||
|
* \return true If it is the case
|
||||||
|
*/
|
||||||
|
|
||||||
inline bool TcpClient::IsKeepAliveEnabled() const
|
inline bool TcpClient::IsKeepAliveEnabled() const
|
||||||
{
|
{
|
||||||
return m_isKeepAliveEnabled;
|
return m_isKeepAliveEnabled;
|
||||||
|
|
|
||||||
|
|
@ -7,27 +7,58 @@
|
||||||
|
|
||||||
namespace Nz
|
namespace Nz
|
||||||
{
|
{
|
||||||
|
/*!
|
||||||
|
* \brief Constructs a TcpServer object by default
|
||||||
|
*/
|
||||||
|
|
||||||
inline TcpServer::TcpServer() :
|
inline TcpServer::TcpServer() :
|
||||||
AbstractSocket(SocketType_TCP)
|
AbstractSocket(SocketType_TCP)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Constructs a TcpServer object with another one by move semantic
|
||||||
|
*
|
||||||
|
* \param tcpServer TcpServer to move into this
|
||||||
|
*/
|
||||||
|
|
||||||
inline TcpServer::TcpServer(TcpServer&& tcpServer) :
|
inline TcpServer::TcpServer(TcpServer&& tcpServer) :
|
||||||
AbstractSocket(std::move(tcpServer)),
|
AbstractSocket(std::move(tcpServer)),
|
||||||
m_boundAddress(std::move(tcpServer.m_boundAddress))
|
m_boundAddress(std::move(tcpServer.m_boundAddress))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Gets the bound address
|
||||||
|
* \return IpAddress we are linked to
|
||||||
|
*/
|
||||||
|
|
||||||
inline IpAddress TcpServer::GetBoundAddress() const
|
inline IpAddress TcpServer::GetBoundAddress() const
|
||||||
{
|
{
|
||||||
return m_boundAddress;
|
return m_boundAddress;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Gets the port of the bound address
|
||||||
|
* \return Port we are linked to
|
||||||
|
*/
|
||||||
|
|
||||||
inline UInt16 TcpServer::GetBoundPort() const
|
inline UInt16 TcpServer::GetBoundPort() const
|
||||||
{
|
{
|
||||||
return m_boundAddress.GetPort();
|
return m_boundAddress.GetPort();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Listens to a socket
|
||||||
|
* \return State of the socket
|
||||||
|
*
|
||||||
|
* \param protocol Net protocol to listen to
|
||||||
|
* \param port Port to listen to
|
||||||
|
* \param queueSize Size of the queue
|
||||||
|
*
|
||||||
|
* \remark Produces a NazaraAssert if protocol is unknown or any
|
||||||
|
*/
|
||||||
|
|
||||||
inline SocketState TcpServer::Listen(NetProtocol protocol, UInt16 port, unsigned int queueSize)
|
inline SocketState TcpServer::Listen(NetProtocol protocol, UInt16 port, unsigned int queueSize)
|
||||||
{
|
{
|
||||||
NazaraAssert(protocol != NetProtocol_Any, "Any protocol not supported for Listen"); //< TODO
|
NazaraAssert(protocol != NetProtocol_Any, "Any protocol not supported for Listen"); //< TODO
|
||||||
|
|
|
||||||
|
|
@ -49,7 +49,6 @@ namespace Nz
|
||||||
void OnOpened() override;
|
void OnOpened() override;
|
||||||
|
|
||||||
IpAddress m_boundAddress;
|
IpAddress m_boundAddress;
|
||||||
SocketState m_state;
|
|
||||||
bool m_isBroadCastingEnabled;
|
bool m_isBroadCastingEnabled;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,24 +6,46 @@
|
||||||
|
|
||||||
namespace Nz
|
namespace Nz
|
||||||
{
|
{
|
||||||
|
/*!
|
||||||
|
* \brief Constructs a UdpSocket object by default
|
||||||
|
*/
|
||||||
|
|
||||||
inline UdpSocket::UdpSocket() :
|
inline UdpSocket::UdpSocket() :
|
||||||
AbstractSocket(SocketType_UDP)
|
AbstractSocket(SocketType_UDP)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Constructs a UdpSocket object with a net protocol
|
||||||
|
*
|
||||||
|
* \param protocol Net protocol to use
|
||||||
|
*/
|
||||||
|
|
||||||
inline UdpSocket::UdpSocket(NetProtocol protocol) :
|
inline UdpSocket::UdpSocket(NetProtocol protocol) :
|
||||||
UdpSocket()
|
UdpSocket()
|
||||||
{
|
{
|
||||||
Create(protocol);
|
Create(protocol);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Constructs a UdpSocket object with another one by move semantic
|
||||||
|
*
|
||||||
|
* \param udpSocket UdpSocket to move into this
|
||||||
|
*/
|
||||||
|
|
||||||
inline UdpSocket::UdpSocket(UdpSocket&& udpSocket) :
|
inline UdpSocket::UdpSocket(UdpSocket&& udpSocket) :
|
||||||
AbstractSocket(std::move(udpSocket)),
|
AbstractSocket(std::move(udpSocket)),
|
||||||
m_boundAddress(std::move(udpSocket.m_boundAddress)),
|
m_boundAddress(std::move(udpSocket.m_boundAddress))
|
||||||
m_state(udpSocket.m_state)
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Binds a specific port
|
||||||
|
* \return State of the socket
|
||||||
|
*
|
||||||
|
* \param port Port to bind
|
||||||
|
*/
|
||||||
|
|
||||||
inline SocketState UdpSocket::Bind(UInt16 port)
|
inline SocketState UdpSocket::Bind(UInt16 port)
|
||||||
{
|
{
|
||||||
IpAddress any;
|
IpAddress any;
|
||||||
|
|
@ -47,6 +69,13 @@ namespace Nz
|
||||||
return Bind(any);
|
return Bind(any);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Creates a UDP socket
|
||||||
|
* \return true If successful
|
||||||
|
*
|
||||||
|
* \param protocol Net protocol to use
|
||||||
|
*/
|
||||||
|
|
||||||
bool UdpSocket::Create(NetProtocol protocol)
|
bool UdpSocket::Create(NetProtocol protocol)
|
||||||
{
|
{
|
||||||
NazaraAssert(protocol != NetProtocol_Unknown, "Invalid protocol");
|
NazaraAssert(protocol != NetProtocol_Unknown, "Invalid protocol");
|
||||||
|
|
@ -54,21 +83,41 @@ namespace Nz
|
||||||
return Open(protocol);
|
return Open(protocol);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Gets the bound address
|
||||||
|
* \return IpAddress we are linked to
|
||||||
|
*/
|
||||||
|
|
||||||
inline IpAddress UdpSocket::GetBoundAddress() const
|
inline IpAddress UdpSocket::GetBoundAddress() const
|
||||||
{
|
{
|
||||||
return m_boundAddress;
|
return m_boundAddress;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Gets the port of the bound address
|
||||||
|
* \return Port we are linked to
|
||||||
|
*/
|
||||||
|
|
||||||
inline UInt16 UdpSocket::GetBoundPort() const
|
inline UInt16 UdpSocket::GetBoundPort() const
|
||||||
{
|
{
|
||||||
return m_boundAddress.GetPort();
|
return m_boundAddress.GetPort();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Gets the state of the socket
|
||||||
|
* \return State of the socket
|
||||||
|
*/
|
||||||
|
|
||||||
inline SocketState UdpSocket::GetState() const
|
inline SocketState UdpSocket::GetState() const
|
||||||
{
|
{
|
||||||
return m_state;
|
return m_state;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Checks whether the broadcasting is enabled
|
||||||
|
* \return true If it is the case
|
||||||
|
*/
|
||||||
|
|
||||||
inline bool UdpSocket::IsBroadcastingEnabled() const
|
inline bool UdpSocket::IsBroadcastingEnabled() const
|
||||||
{
|
{
|
||||||
return m_isBroadCastingEnabled;
|
return m_isBroadCastingEnabled;
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,21 @@
|
||||||
|
|
||||||
namespace Nz
|
namespace Nz
|
||||||
{
|
{
|
||||||
|
/*!
|
||||||
|
* \ingroup audio
|
||||||
|
* \class Nz::Audio
|
||||||
|
* \brief Audio class that represents the module initializer of Audio
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Gets the format of the audio
|
||||||
|
* \return AudioFormat Enumeration type for the format
|
||||||
|
*
|
||||||
|
* \param channelCount Number of channels
|
||||||
|
*
|
||||||
|
* \remark Produces a NazaraError if the number of channels is erroneous (3 or 5) and AudioFormat_Unknown is returned
|
||||||
|
*/
|
||||||
|
|
||||||
AudioFormat Audio::GetAudioFormat(unsigned int channelCount)
|
AudioFormat Audio::GetAudioFormat(unsigned int channelCount)
|
||||||
{
|
{
|
||||||
switch (channelCount)
|
switch (channelCount)
|
||||||
|
|
@ -34,11 +49,21 @@ namespace Nz
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Gets the factor of the doppler effect
|
||||||
|
* \return Global factor of the doppler effect
|
||||||
|
*/
|
||||||
|
|
||||||
float Audio::GetDopplerFactor()
|
float Audio::GetDopplerFactor()
|
||||||
{
|
{
|
||||||
return alGetFloat(AL_DOPPLER_FACTOR);
|
return alGetFloat(AL_DOPPLER_FACTOR);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Gets the global volume
|
||||||
|
* \return Float between [0, inf) with 100.f being the default
|
||||||
|
*/
|
||||||
|
|
||||||
float Audio::GetGlobalVolume()
|
float Audio::GetGlobalVolume()
|
||||||
{
|
{
|
||||||
ALfloat gain = 0.f;
|
ALfloat gain = 0.f;
|
||||||
|
|
@ -47,6 +72,13 @@ namespace Nz
|
||||||
return gain * 100.f;
|
return gain * 100.f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Gets the direction of the listener
|
||||||
|
* \return Direction of the listener, in front of the listener
|
||||||
|
*
|
||||||
|
* \see GetListenerRotation
|
||||||
|
*/
|
||||||
|
|
||||||
Vector3f Audio::GetListenerDirection()
|
Vector3f Audio::GetListenerDirection()
|
||||||
{
|
{
|
||||||
ALfloat orientation[6];
|
ALfloat orientation[6];
|
||||||
|
|
@ -55,6 +87,13 @@ namespace Nz
|
||||||
return Vector3f(orientation[0], orientation[1], orientation[2]);
|
return Vector3f(orientation[0], orientation[1], orientation[2]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Gets the position of the listener
|
||||||
|
* \return Position of the listener
|
||||||
|
*
|
||||||
|
* \see GetListenerVelocity
|
||||||
|
*/
|
||||||
|
|
||||||
Vector3f Audio::GetListenerPosition()
|
Vector3f Audio::GetListenerPosition()
|
||||||
{
|
{
|
||||||
Vector3f position;
|
Vector3f position;
|
||||||
|
|
@ -63,6 +102,11 @@ namespace Nz
|
||||||
return position;
|
return position;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Gets the rotation of the listener
|
||||||
|
* \return Rotation of the listener
|
||||||
|
*/
|
||||||
|
|
||||||
Quaternionf Audio::GetListenerRotation()
|
Quaternionf Audio::GetListenerRotation()
|
||||||
{
|
{
|
||||||
ALfloat orientation[6];
|
ALfloat orientation[6];
|
||||||
|
|
@ -73,6 +117,13 @@ namespace Nz
|
||||||
return Quaternionf::RotationBetween(Vector3f::Forward(), forward);
|
return Quaternionf::RotationBetween(Vector3f::Forward(), forward);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Gets the velocity of the listener
|
||||||
|
* \return Velocity of the listener
|
||||||
|
*
|
||||||
|
* \see GetListenerPosition
|
||||||
|
*/
|
||||||
|
|
||||||
Vector3f Audio::GetListenerVelocity()
|
Vector3f Audio::GetListenerVelocity()
|
||||||
{
|
{
|
||||||
Vector3f velocity;
|
Vector3f velocity;
|
||||||
|
|
@ -81,20 +132,33 @@ namespace Nz
|
||||||
return velocity;
|
return velocity;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Gets the speed of sound
|
||||||
|
* \return Speed of sound
|
||||||
|
*/
|
||||||
|
|
||||||
float Audio::GetSpeedOfSound()
|
float Audio::GetSpeedOfSound()
|
||||||
{
|
{
|
||||||
return alGetFloat(AL_SPEED_OF_SOUND);
|
return alGetFloat(AL_SPEED_OF_SOUND);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Initializes the Audio module
|
||||||
|
* \return true if initialization is successful
|
||||||
|
*
|
||||||
|
* \remark Produces a NazaraError if initialization of modules Core, OpenAL or SoundBuffer failed
|
||||||
|
* \remark Produces a NazaraNotice
|
||||||
|
*/
|
||||||
|
|
||||||
bool Audio::Initialize()
|
bool Audio::Initialize()
|
||||||
{
|
{
|
||||||
if (s_moduleReferenceCounter > 0)
|
if (IsInitialized())
|
||||||
{
|
{
|
||||||
s_moduleReferenceCounter++;
|
s_moduleReferenceCounter++;
|
||||||
return true; // Déjà initialisé
|
return true; // Already initialized
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialisation des dépendances
|
// Initialisation of dependencies
|
||||||
if (!Core::Initialize())
|
if (!Core::Initialize())
|
||||||
{
|
{
|
||||||
NazaraError("Failed to initialize core module");
|
NazaraError("Failed to initialize core module");
|
||||||
|
|
@ -103,10 +167,10 @@ namespace Nz
|
||||||
|
|
||||||
s_moduleReferenceCounter++;
|
s_moduleReferenceCounter++;
|
||||||
|
|
||||||
// Initialisation du module
|
// Initialisation of the module
|
||||||
CallOnExit onExit(Audio::Uninitialize);
|
CallOnExit onExit(Audio::Uninitialize);
|
||||||
|
|
||||||
// Initialisation d'OpenAL
|
// Initialisation of OpenAL
|
||||||
if (!OpenAL::Initialize())
|
if (!OpenAL::Initialize())
|
||||||
{
|
{
|
||||||
NazaraError("Failed to initialize OpenAL");
|
NazaraError("Failed to initialize OpenAL");
|
||||||
|
|
@ -119,7 +183,7 @@ namespace Nz
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Définition de l'orientation par défaut
|
// Definition of the orientation by default
|
||||||
SetListenerDirection(Vector3f::Forward());
|
SetListenerDirection(Vector3f::Forward());
|
||||||
|
|
||||||
// Loaders
|
// Loaders
|
||||||
|
|
@ -131,6 +195,13 @@ namespace Nz
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Checks whether the format is supported by the engine
|
||||||
|
* \return true if it is the case
|
||||||
|
*
|
||||||
|
* \param format Format to check
|
||||||
|
*/
|
||||||
|
|
||||||
bool Audio::IsFormatSupported(AudioFormat format)
|
bool Audio::IsFormatSupported(AudioFormat format)
|
||||||
{
|
{
|
||||||
if (format == AudioFormat_Unknown)
|
if (format == AudioFormat_Unknown)
|
||||||
|
|
@ -139,21 +210,46 @@ namespace Nz
|
||||||
return OpenAL::AudioFormat[format] != 0;
|
return OpenAL::AudioFormat[format] != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Checks whether the module is initialized
|
||||||
|
* \return true if module is initialized
|
||||||
|
*/
|
||||||
|
|
||||||
bool Audio::IsInitialized()
|
bool Audio::IsInitialized()
|
||||||
{
|
{
|
||||||
return s_moduleReferenceCounter != 0;
|
return s_moduleReferenceCounter != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Sets the factor of the doppler effect
|
||||||
|
*
|
||||||
|
* \param dopplerFactor Global factor of the doppler effect
|
||||||
|
*/
|
||||||
|
|
||||||
void Audio::SetDopplerFactor(float dopplerFactor)
|
void Audio::SetDopplerFactor(float dopplerFactor)
|
||||||
{
|
{
|
||||||
alDopplerFactor(dopplerFactor);
|
alDopplerFactor(dopplerFactor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Sets the global volume
|
||||||
|
*
|
||||||
|
* \param volume Float between [0, inf) with 100.f being the default
|
||||||
|
*/
|
||||||
|
|
||||||
void Audio::SetGlobalVolume(float volume)
|
void Audio::SetGlobalVolume(float volume)
|
||||||
{
|
{
|
||||||
alListenerf(AL_GAIN, volume * 0.01f);
|
alListenerf(AL_GAIN, volume * 0.01f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Sets the direction of the listener
|
||||||
|
*
|
||||||
|
* \param direction Direction of the listener, in front of the listener
|
||||||
|
*
|
||||||
|
* \see SetListenerDirection, SetListenerRotation
|
||||||
|
*/
|
||||||
|
|
||||||
void Audio::SetListenerDirection(const Vector3f& direction)
|
void Audio::SetListenerDirection(const Vector3f& direction)
|
||||||
{
|
{
|
||||||
Vector3f up = Vector3f::Up();
|
Vector3f up = Vector3f::Up();
|
||||||
|
|
@ -167,6 +263,14 @@ namespace Nz
|
||||||
alListenerfv(AL_ORIENTATION, orientation);
|
alListenerfv(AL_ORIENTATION, orientation);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Sets the direction of the listener
|
||||||
|
*
|
||||||
|
* \param (dirX, dirY, dirZ) Direction of the listener, in front of the listener
|
||||||
|
*
|
||||||
|
* \see SetListenerDirection, SetListenerRotation
|
||||||
|
*/
|
||||||
|
|
||||||
void Audio::SetListenerDirection(float dirX, float dirY, float dirZ)
|
void Audio::SetListenerDirection(float dirX, float dirY, float dirZ)
|
||||||
{
|
{
|
||||||
Vector3f up = Vector3f::Up();
|
Vector3f up = Vector3f::Up();
|
||||||
|
|
@ -180,16 +284,38 @@ namespace Nz
|
||||||
alListenerfv(AL_ORIENTATION, orientation);
|
alListenerfv(AL_ORIENTATION, orientation);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Sets the position of the listener
|
||||||
|
*
|
||||||
|
* \param position Position of the listener
|
||||||
|
*
|
||||||
|
* \see SetListenerVelocity
|
||||||
|
*/
|
||||||
|
|
||||||
void Audio::SetListenerPosition(const Vector3f& position)
|
void Audio::SetListenerPosition(const Vector3f& position)
|
||||||
{
|
{
|
||||||
alListenerfv(AL_POSITION, position);
|
alListenerfv(AL_POSITION, position);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Sets the position of the listener
|
||||||
|
*
|
||||||
|
* \param (x, y, z) Position of the listener
|
||||||
|
*
|
||||||
|
* \see SetListenerVelocity
|
||||||
|
*/
|
||||||
|
|
||||||
void Audio::SetListenerPosition(float x, float y, float z)
|
void Audio::SetListenerPosition(float x, float y, float z)
|
||||||
{
|
{
|
||||||
alListener3f(AL_POSITION, x, y, z);
|
alListener3f(AL_POSITION, x, y, z);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Sets the rotation of the listener
|
||||||
|
*
|
||||||
|
* \param rotation Rotation of the listener
|
||||||
|
*/
|
||||||
|
|
||||||
void Audio::SetListenerRotation(const Quaternionf& rotation)
|
void Audio::SetListenerRotation(const Quaternionf& rotation)
|
||||||
{
|
{
|
||||||
Vector3f forward = rotation * Vector3f::Forward();
|
Vector3f forward = rotation * Vector3f::Forward();
|
||||||
|
|
@ -204,33 +330,61 @@ namespace Nz
|
||||||
alListenerfv(AL_ORIENTATION, orientation);
|
alListenerfv(AL_ORIENTATION, orientation);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Sets the velocity of the listener
|
||||||
|
*
|
||||||
|
* \param velocity Velocity of the listener
|
||||||
|
*
|
||||||
|
* \see SetListenerPosition
|
||||||
|
*/
|
||||||
|
|
||||||
void Audio::SetListenerVelocity(const Vector3f& velocity)
|
void Audio::SetListenerVelocity(const Vector3f& velocity)
|
||||||
{
|
{
|
||||||
alListenerfv(AL_VELOCITY, velocity);
|
alListenerfv(AL_VELOCITY, velocity);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Sets the velocity of the listener
|
||||||
|
*
|
||||||
|
* \param (velX, velY, velZ) Velocity of the listener
|
||||||
|
*
|
||||||
|
* \see SetListenerPosition
|
||||||
|
*/
|
||||||
|
|
||||||
void Audio::SetListenerVelocity(float velX, float velY, float velZ)
|
void Audio::SetListenerVelocity(float velX, float velY, float velZ)
|
||||||
{
|
{
|
||||||
alListener3f(AL_VELOCITY, velX, velY, velZ);
|
alListener3f(AL_VELOCITY, velX, velY, velZ);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Sets the speed of sound
|
||||||
|
*
|
||||||
|
* \param speed Speed of sound
|
||||||
|
*/
|
||||||
|
|
||||||
void Audio::SetSpeedOfSound(float speed)
|
void Audio::SetSpeedOfSound(float speed)
|
||||||
{
|
{
|
||||||
alSpeedOfSound(speed);
|
alSpeedOfSound(speed);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Uninitializes the Audio module
|
||||||
|
*
|
||||||
|
* \remark Produces a NazaraNotice
|
||||||
|
*/
|
||||||
|
|
||||||
void Audio::Uninitialize()
|
void Audio::Uninitialize()
|
||||||
{
|
{
|
||||||
if (s_moduleReferenceCounter != 1)
|
if (s_moduleReferenceCounter != 1)
|
||||||
{
|
{
|
||||||
// Le module est soit encore utilisé, soit pas initialisé
|
// The module is still in use, or can not be uninitialized
|
||||||
if (s_moduleReferenceCounter > 1)
|
if (s_moduleReferenceCounter > 1)
|
||||||
s_moduleReferenceCounter--;
|
s_moduleReferenceCounter--;
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Libération du module
|
// Free of module
|
||||||
s_moduleReferenceCounter = 0;
|
s_moduleReferenceCounter = 0;
|
||||||
|
|
||||||
// Loaders
|
// Loaders
|
||||||
|
|
@ -241,7 +395,7 @@ namespace Nz
|
||||||
|
|
||||||
NazaraNotice("Uninitialized: Audio module");
|
NazaraNotice("Uninitialized: Audio module");
|
||||||
|
|
||||||
// Libération des dépendances
|
// Free of dependencies
|
||||||
Core::Uninitialize();
|
Core::Uninitialize();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,19 @@
|
||||||
|
|
||||||
namespace Nz
|
namespace Nz
|
||||||
{
|
{
|
||||||
|
/*!
|
||||||
|
* \ingroup audio
|
||||||
|
* \class Nz::Music
|
||||||
|
* \brief Audio class that represents a music
|
||||||
|
*
|
||||||
|
* \remark Module Audio needs to be initialized to use this class
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Checks whether the parameters for the loading of the music are correct
|
||||||
|
* \return true If parameters are valid
|
||||||
|
*/
|
||||||
|
|
||||||
bool MusicParams::IsValid() const
|
bool MusicParams::IsValid() const
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
|
|
@ -32,11 +45,26 @@ namespace Nz
|
||||||
unsigned int sampleRate;
|
unsigned int sampleRate;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Destructs the object and calls Destroy
|
||||||
|
*
|
||||||
|
* \see Destroy
|
||||||
|
*/
|
||||||
|
|
||||||
Music::~Music()
|
Music::~Music()
|
||||||
{
|
{
|
||||||
Destroy();
|
Destroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Creates a music with a sound stream
|
||||||
|
* \return true if creation was succesful
|
||||||
|
*
|
||||||
|
* \param soundStream Sound stream which is the source for the music
|
||||||
|
*
|
||||||
|
* \remark Produces a NazaraError if soundStream is invalid with NAZARA_AUDIO_SAFE defined
|
||||||
|
*/
|
||||||
|
|
||||||
bool Music::Create(SoundStream* soundStream)
|
bool Music::Create(SoundStream* soundStream)
|
||||||
{
|
{
|
||||||
NazaraAssert(soundStream, "Invalid stream");
|
NazaraAssert(soundStream, "Invalid stream");
|
||||||
|
|
@ -48,7 +76,7 @@ namespace Nz
|
||||||
m_impl = new MusicImpl;
|
m_impl = new MusicImpl;
|
||||||
m_impl->sampleRate = soundStream->GetSampleRate();
|
m_impl->sampleRate = soundStream->GetSampleRate();
|
||||||
m_impl->audioFormat = OpenAL::AudioFormat[format];
|
m_impl->audioFormat = OpenAL::AudioFormat[format];
|
||||||
m_impl->chunkSamples.resize(format * m_impl->sampleRate); // Une seconde de samples
|
m_impl->chunkSamples.resize(format * m_impl->sampleRate); // One second of samples
|
||||||
m_impl->stream.reset(soundStream);
|
m_impl->stream.reset(soundStream);
|
||||||
|
|
||||||
SetPlayingOffset(0);
|
SetPlayingOffset(0);
|
||||||
|
|
@ -56,6 +84,10 @@ namespace Nz
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Destroys the current music and frees resources
|
||||||
|
*/
|
||||||
|
|
||||||
void Music::Destroy()
|
void Music::Destroy()
|
||||||
{
|
{
|
||||||
if (m_impl)
|
if (m_impl)
|
||||||
|
|
@ -67,6 +99,14 @@ namespace Nz
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Enables the looping of the music
|
||||||
|
*
|
||||||
|
* \param loop Should music loop
|
||||||
|
*
|
||||||
|
* \remark Produces a NazaraError if there is no music with NAZARA_AUDIO_SAFE defined
|
||||||
|
*/
|
||||||
|
|
||||||
void Music::EnableLooping(bool loop)
|
void Music::EnableLooping(bool loop)
|
||||||
{
|
{
|
||||||
#if NAZARA_AUDIO_SAFE
|
#if NAZARA_AUDIO_SAFE
|
||||||
|
|
@ -80,6 +120,13 @@ namespace Nz
|
||||||
m_impl->loop = loop;
|
m_impl->loop = loop;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Gets the duration of the music
|
||||||
|
* \return Duration of the music in milliseconds
|
||||||
|
*
|
||||||
|
* \remark Produces a NazaraError if there is no music with NAZARA_AUDIO_SAFE defined
|
||||||
|
*/
|
||||||
|
|
||||||
UInt32 Music::GetDuration() const
|
UInt32 Music::GetDuration() const
|
||||||
{
|
{
|
||||||
#if NAZARA_AUDIO_SAFE
|
#if NAZARA_AUDIO_SAFE
|
||||||
|
|
@ -93,6 +140,13 @@ namespace Nz
|
||||||
return m_impl->stream->GetDuration();
|
return m_impl->stream->GetDuration();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Gets the format of the music
|
||||||
|
* \return Enumeration of type AudioFormat (mono, stereo, ...)
|
||||||
|
*
|
||||||
|
* \remark Produces a NazaraError if there is no music with NAZARA_AUDIO_SAFE defined
|
||||||
|
*/
|
||||||
|
|
||||||
AudioFormat Music::GetFormat() const
|
AudioFormat Music::GetFormat() const
|
||||||
{
|
{
|
||||||
#if NAZARA_AUDIO_SAFE
|
#if NAZARA_AUDIO_SAFE
|
||||||
|
|
@ -106,6 +160,13 @@ namespace Nz
|
||||||
return m_impl->stream->GetFormat();
|
return m_impl->stream->GetFormat();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Gets the current offset in the music
|
||||||
|
* \return Offset in milliseconds (works with entire seconds)
|
||||||
|
*
|
||||||
|
* \remark Produces a NazaraError if there is no music with NAZARA_AUDIO_SAFE defined
|
||||||
|
*/
|
||||||
|
|
||||||
UInt32 Music::GetPlayingOffset() const
|
UInt32 Music::GetPlayingOffset() const
|
||||||
{
|
{
|
||||||
#if NAZARA_AUDIO_SAFE
|
#if NAZARA_AUDIO_SAFE
|
||||||
|
|
@ -125,6 +186,13 @@ namespace Nz
|
||||||
return static_cast<UInt32>((1000ULL * (samples + (m_impl->processedSamples / m_impl->stream->GetFormat()))) / m_impl->sampleRate);
|
return static_cast<UInt32>((1000ULL * (samples + (m_impl->processedSamples / m_impl->stream->GetFormat()))) / m_impl->sampleRate);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Gets the number of samples in the music
|
||||||
|
* \return Count of samples (number of seconds * sample rate * channel count)
|
||||||
|
*
|
||||||
|
* \remark Produces a NazaraError if there is no music with NAZARA_AUDIO_SAFE defined
|
||||||
|
*/
|
||||||
|
|
||||||
UInt32 Music::GetSampleCount() const
|
UInt32 Music::GetSampleCount() const
|
||||||
{
|
{
|
||||||
#if NAZARA_AUDIO_SAFE
|
#if NAZARA_AUDIO_SAFE
|
||||||
|
|
@ -138,6 +206,13 @@ namespace Nz
|
||||||
return m_impl->stream->GetSampleCount();
|
return m_impl->stream->GetSampleCount();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Gets the rates of sample in the music
|
||||||
|
* \return Rate of sample in Hertz (Hz)
|
||||||
|
*
|
||||||
|
* \remark Produces a NazaraError if there is no music with NAZARA_AUDIO_SAFE defined
|
||||||
|
*/
|
||||||
|
|
||||||
UInt32 Music::GetSampleRate() const
|
UInt32 Music::GetSampleRate() const
|
||||||
{
|
{
|
||||||
#if NAZARA_AUDIO_SAFE
|
#if NAZARA_AUDIO_SAFE
|
||||||
|
|
@ -151,6 +226,14 @@ namespace Nz
|
||||||
return m_impl->sampleRate;
|
return m_impl->sampleRate;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Gets the status of the music
|
||||||
|
* \return Enumeration of type SoundStatus (Playing, Stopped, ...)
|
||||||
|
*
|
||||||
|
* \remark If the music is not playing, Stopped is returned
|
||||||
|
* \remark Produces a NazaraError if there is no music with NAZARA_AUDIO_SAFE defined
|
||||||
|
*/
|
||||||
|
|
||||||
SoundStatus Music::GetStatus() const
|
SoundStatus Music::GetStatus() const
|
||||||
{
|
{
|
||||||
#if NAZARA_AUDIO_SAFE
|
#if NAZARA_AUDIO_SAFE
|
||||||
|
|
@ -163,13 +246,20 @@ namespace Nz
|
||||||
|
|
||||||
SoundStatus status = GetInternalStatus();
|
SoundStatus status = GetInternalStatus();
|
||||||
|
|
||||||
// Pour compenser les éventuels retards (ou le laps de temps entre Play() et la mise en route du thread)
|
// To compensate any delays (or the timelaps between Play() and the thread startup)
|
||||||
if (m_impl->streaming && status == SoundStatus_Stopped)
|
if (m_impl->streaming && status == SoundStatus_Stopped)
|
||||||
status = SoundStatus_Playing;
|
status = SoundStatus_Playing;
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Checks whether the music is looping
|
||||||
|
* \return true if it is the case
|
||||||
|
*
|
||||||
|
* \remark Produces a NazaraError if there is no music with NAZARA_AUDIO_SAFE defined
|
||||||
|
*/
|
||||||
|
|
||||||
bool Music::IsLooping() const
|
bool Music::IsLooping() const
|
||||||
{
|
{
|
||||||
#if NAZARA_AUDIO_SAFE
|
#if NAZARA_AUDIO_SAFE
|
||||||
|
|
@ -183,26 +273,61 @@ namespace Nz
|
||||||
return m_impl->loop;
|
return m_impl->loop;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Loads the music from file
|
||||||
|
* \return true if loading is successful
|
||||||
|
*
|
||||||
|
* \param filePath Path to the file
|
||||||
|
* \param params Parameters for the music
|
||||||
|
*/
|
||||||
|
|
||||||
bool Music::OpenFromFile(const String& filePath, const MusicParams& params)
|
bool Music::OpenFromFile(const String& filePath, const MusicParams& params)
|
||||||
{
|
{
|
||||||
return MusicLoader::LoadFromFile(this, filePath, params);
|
return MusicLoader::LoadFromFile(this, filePath, params);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Loads the music from memory
|
||||||
|
* \return true if loading is successful
|
||||||
|
*
|
||||||
|
* \param data Raw memory
|
||||||
|
* \param size Size of the memory
|
||||||
|
* \param params Parameters for the music
|
||||||
|
*/
|
||||||
|
|
||||||
bool Music::OpenFromMemory(const void* data, std::size_t size, const MusicParams& params)
|
bool Music::OpenFromMemory(const void* data, std::size_t size, const MusicParams& params)
|
||||||
{
|
{
|
||||||
return MusicLoader::LoadFromMemory(this, data, size, params);
|
return MusicLoader::LoadFromMemory(this, data, size, params);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Loads the music from stream
|
||||||
|
* \return true if loading is successful
|
||||||
|
*
|
||||||
|
* \param stream Stream to the music
|
||||||
|
* \param params Parameters for the music
|
||||||
|
*/
|
||||||
|
|
||||||
bool Music::OpenFromStream(Stream& stream, const MusicParams& params)
|
bool Music::OpenFromStream(Stream& stream, const MusicParams& params)
|
||||||
{
|
{
|
||||||
return MusicLoader::LoadFromStream(this, stream, params);
|
return MusicLoader::LoadFromStream(this, stream, params);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Pauses the music
|
||||||
|
*/
|
||||||
|
|
||||||
void Music::Pause()
|
void Music::Pause()
|
||||||
{
|
{
|
||||||
alSourcePause(m_source);
|
alSourcePause(m_source);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Plays the music
|
||||||
|
*
|
||||||
|
* \remark Produces a NazaraError if there is no music with NAZARA_AUDIO_SAFE defined
|
||||||
|
*/
|
||||||
|
|
||||||
void Music::Play()
|
void Music::Play()
|
||||||
{
|
{
|
||||||
#if NAZARA_AUDIO_SAFE
|
#if NAZARA_AUDIO_SAFE
|
||||||
|
|
@ -238,6 +363,14 @@ namespace Nz
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Sets the playing offset for the music
|
||||||
|
*
|
||||||
|
* \param offset Offset in the music in milliseconds
|
||||||
|
*
|
||||||
|
* \remark Produces a NazaraError if there is no music with NAZARA_AUDIO_SAFE defined
|
||||||
|
*/
|
||||||
|
|
||||||
void Music::SetPlayingOffset(UInt32 offset)
|
void Music::SetPlayingOffset(UInt32 offset)
|
||||||
{
|
{
|
||||||
#if NAZARA_AUDIO_SAFE
|
#if NAZARA_AUDIO_SAFE
|
||||||
|
|
@ -260,6 +393,12 @@ namespace Nz
|
||||||
Play();
|
Play();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Stops the music
|
||||||
|
*
|
||||||
|
* \remark Produces a NazaraError if there is no music with NAZARA_AUDIO_SAFE defined
|
||||||
|
*/
|
||||||
|
|
||||||
void Music::Stop()
|
void Music::Stop()
|
||||||
{
|
{
|
||||||
#if NAZARA_AUDIO_SAFE
|
#if NAZARA_AUDIO_SAFE
|
||||||
|
|
@ -277,6 +416,13 @@ namespace Nz
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Fills the buffer and queues it up
|
||||||
|
* \return true if operation was successful
|
||||||
|
*
|
||||||
|
* \param buffer Index of the buffer
|
||||||
|
*/
|
||||||
|
|
||||||
bool Music::FillAndQueueBuffer(unsigned int buffer)
|
bool Music::FillAndQueueBuffer(unsigned int buffer)
|
||||||
{
|
{
|
||||||
unsigned int sampleCount = m_impl->chunkSamples.size();
|
unsigned int sampleCount = m_impl->chunkSamples.size();
|
||||||
|
|
@ -304,27 +450,31 @@ namespace Nz
|
||||||
alSourceQueueBuffers(m_source, 1, &buffer);
|
alSourceQueueBuffers(m_source, 1, &buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
return sampleRead != sampleCount; // Fin du stream (N'arrive pas en cas de loop)
|
return sampleRead != sampleCount; // End of stream (Does not happen when looping)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Thread function for the music
|
||||||
|
*/
|
||||||
|
|
||||||
void Music::MusicThread()
|
void Music::MusicThread()
|
||||||
{
|
{
|
||||||
// Allocation des buffers de streaming
|
// Allocation of streaming buffers
|
||||||
ALuint buffers[NAZARA_AUDIO_STREAMED_BUFFER_COUNT];
|
ALuint buffers[NAZARA_AUDIO_STREAMED_BUFFER_COUNT];
|
||||||
alGenBuffers(NAZARA_AUDIO_STREAMED_BUFFER_COUNT, buffers);
|
alGenBuffers(NAZARA_AUDIO_STREAMED_BUFFER_COUNT, buffers);
|
||||||
|
|
||||||
for (unsigned int i = 0; i < NAZARA_AUDIO_STREAMED_BUFFER_COUNT; ++i)
|
for (unsigned int i = 0; i < NAZARA_AUDIO_STREAMED_BUFFER_COUNT; ++i)
|
||||||
{
|
{
|
||||||
if (FillAndQueueBuffer(buffers[i]))
|
if (FillAndQueueBuffer(buffers[i]))
|
||||||
break; // Nous avons atteint la fin du stream, inutile de rajouter des buffers
|
break; // We have reached the end of the stream, there is no use to add new buffers
|
||||||
}
|
}
|
||||||
|
|
||||||
alSourcePlay(m_source);
|
alSourcePlay(m_source);
|
||||||
|
|
||||||
// Boucle de lecture (remplissage de nouveaux buffers au fur et à mesure)
|
// Reading loop (Filling new buffers as playing)
|
||||||
while (m_impl->streaming)
|
while (m_impl->streaming)
|
||||||
{
|
{
|
||||||
// La lecture s'est arrêtée, nous avons atteint la fin du stream
|
// The reading has stopped, we have reached the end of the stream
|
||||||
SoundStatus status = GetInternalStatus();
|
SoundStatus status = GetInternalStatus();
|
||||||
if (status == SoundStatus_Stopped)
|
if (status == SoundStatus_Stopped)
|
||||||
{
|
{
|
||||||
|
|
@ -334,7 +484,7 @@ namespace Nz
|
||||||
|
|
||||||
Nz::LockGuard lock(m_impl->bufferLock);
|
Nz::LockGuard lock(m_impl->bufferLock);
|
||||||
|
|
||||||
// On traite les buffers lus
|
// We treat read buffers
|
||||||
ALint processedCount = 0;
|
ALint processedCount = 0;
|
||||||
alGetSourcei(m_source, AL_BUFFERS_PROCESSED, &processedCount);
|
alGetSourcei(m_source, AL_BUFFERS_PROCESSED, &processedCount);
|
||||||
while (processedCount--)
|
while (processedCount--)
|
||||||
|
|
@ -355,14 +505,14 @@ namespace Nz
|
||||||
|
|
||||||
lock.Unlock();
|
lock.Unlock();
|
||||||
|
|
||||||
// On retourne dormir un peu
|
// We go back to sleep
|
||||||
Thread::Sleep(50);
|
Thread::Sleep(50);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Arrêt de la lecture du son (dans le cas où ça ne serait pas déjà fait)
|
// Stop playing of the sound (in the case where it has not been already done)
|
||||||
alSourceStop(m_source);
|
alSourceStop(m_source);
|
||||||
|
|
||||||
// On supprime les buffers du stream
|
// We delete buffers from the stream
|
||||||
ALint queuedBufferCount;
|
ALint queuedBufferCount;
|
||||||
alGetSourcei(m_source, AL_BUFFERS_QUEUED, &queuedBufferCount);
|
alGetSourcei(m_source, AL_BUFFERS_QUEUED, &queuedBufferCount);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,14 @@ namespace Nz
|
||||||
ALCcontext* s_context = nullptr;
|
ALCcontext* s_context = nullptr;
|
||||||
unsigned int s_version;
|
unsigned int s_version;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Parses the devices
|
||||||
|
* \return Number of devices
|
||||||
|
*
|
||||||
|
* \param deviceString String for the device (input / output)
|
||||||
|
* \param devices List of names of the devices
|
||||||
|
*/
|
||||||
|
|
||||||
std::size_t ParseDevices(const char* deviceString, std::vector<String>& devices)
|
std::size_t ParseDevices(const char* deviceString, std::vector<String>& devices)
|
||||||
{
|
{
|
||||||
if (!deviceString)
|
if (!deviceString)
|
||||||
|
|
@ -41,35 +49,77 @@ namespace Nz
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \ingroup audio
|
||||||
|
* \class Nz::OpenAL
|
||||||
|
* \brief Audio class that represents the link with OpenAL
|
||||||
|
*
|
||||||
|
* \remark This class is meant to be used by Module Audio
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Gets the entry for the function name
|
||||||
|
* \return Pointer to the function
|
||||||
|
*
|
||||||
|
* \param entryPoint Name of the entry
|
||||||
|
*
|
||||||
|
* \remark This does not produces a NazaraError if entry does not exist
|
||||||
|
*/
|
||||||
|
|
||||||
OpenALFunc OpenAL::GetEntry(const String& entryPoint)
|
OpenALFunc OpenAL::GetEntry(const String& entryPoint)
|
||||||
{
|
{
|
||||||
return LoadEntry(entryPoint.GetConstBuffer(), false);
|
return LoadEntry(entryPoint.GetConstBuffer(), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Gets the name of the renderer
|
||||||
|
* \return Name of the renderer
|
||||||
|
*/
|
||||||
|
|
||||||
String OpenAL::GetRendererName()
|
String OpenAL::GetRendererName()
|
||||||
{
|
{
|
||||||
return s_rendererName;
|
return s_rendererName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Gets the name of the vendor
|
||||||
|
* \return Name of the vendor
|
||||||
|
*/
|
||||||
|
|
||||||
String OpenAL::GetVendorName()
|
String OpenAL::GetVendorName()
|
||||||
{
|
{
|
||||||
return s_vendorName;
|
return s_vendorName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Gets the version of OpenAL
|
||||||
|
* \return Version of OpenAL
|
||||||
|
*/
|
||||||
|
|
||||||
unsigned int OpenAL::GetVersion()
|
unsigned int OpenAL::GetVersion()
|
||||||
{
|
{
|
||||||
return s_version;
|
return s_version;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Initializes the module OpenAL
|
||||||
|
* \return true if initialization is successful
|
||||||
|
*
|
||||||
|
* \param openDevice True to get information from the device
|
||||||
|
*
|
||||||
|
* \remark Produces a NazaraError if one of the entry failed
|
||||||
|
* \remark Produces a NazaraError if opening device failed with openDevice parameter set to true
|
||||||
|
*/
|
||||||
|
|
||||||
bool OpenAL::Initialize(bool openDevice)
|
bool OpenAL::Initialize(bool openDevice)
|
||||||
{
|
{
|
||||||
if (s_library.IsLoaded())
|
if (IsInitialized())
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
#if defined(NAZARA_PLATFORM_WINDOWS)
|
#if defined(NAZARA_PLATFORM_WINDOWS)
|
||||||
///FIXME: Est-ce qu'OpenAL Soft est une meilleure implémentation que Creative ?
|
///FIXME: Is OpenAL Soft a better implementation than Creative ?
|
||||||
/// Si on pouvait se résigner à utiliser OpenAL Soft tout le temps, cela nous permettrait d'utiliser les extensions sonores
|
/// If we could use OpenAL Soft everytime, this would allow us to use sonorous extensions
|
||||||
/// et de donner plus de possibilités techniques au niveau de l'audio.
|
/// and give us more technical possibilities with audio
|
||||||
const char* libs[] = {
|
const char* libs[] = {
|
||||||
"soft_oal.dll",
|
"soft_oal.dll",
|
||||||
"wrap_oal.dll",
|
"wrap_oal.dll",
|
||||||
|
|
@ -217,11 +267,23 @@ namespace Nz
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Checks whether the module is initialized
|
||||||
|
* \return true if it is the case
|
||||||
|
*/
|
||||||
|
|
||||||
bool OpenAL::IsInitialized()
|
bool OpenAL::IsInitialized()
|
||||||
{
|
{
|
||||||
return s_library.IsLoaded();
|
return s_library.IsLoaded();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Queries the input devices
|
||||||
|
* \return Number of devices
|
||||||
|
*
|
||||||
|
* \param devices List of names of the input devices
|
||||||
|
*/
|
||||||
|
|
||||||
std::size_t OpenAL::QueryInputDevices(std::vector<String>& devices)
|
std::size_t OpenAL::QueryInputDevices(std::vector<String>& devices)
|
||||||
{
|
{
|
||||||
const char* deviceString = reinterpret_cast<const char*>(alcGetString(nullptr, ALC_CAPTURE_DEVICE_SPECIFIER));
|
const char* deviceString = reinterpret_cast<const char*>(alcGetString(nullptr, ALC_CAPTURE_DEVICE_SPECIFIER));
|
||||||
|
|
@ -231,6 +293,13 @@ namespace Nz
|
||||||
return ParseDevices(deviceString, devices);
|
return ParseDevices(deviceString, devices);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Queries the output devices
|
||||||
|
* \return Number of devices
|
||||||
|
*
|
||||||
|
* \param devices List of names of the output devices
|
||||||
|
*/
|
||||||
|
|
||||||
std::size_t OpenAL::QueryOutputDevices(std::vector<String>& devices)
|
std::size_t OpenAL::QueryOutputDevices(std::vector<String>& devices)
|
||||||
{
|
{
|
||||||
const char* deviceString = reinterpret_cast<const char*>(alcGetString(nullptr, ALC_ALL_DEVICES_SPECIFIER));
|
const char* deviceString = reinterpret_cast<const char*>(alcGetString(nullptr, ALC_ALL_DEVICES_SPECIFIER));
|
||||||
|
|
@ -240,6 +309,13 @@ namespace Nz
|
||||||
return ParseDevices(deviceString, devices);
|
return ParseDevices(deviceString, devices);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Sets the active device
|
||||||
|
* \return true if device is successfully opened
|
||||||
|
*
|
||||||
|
* \param deviceName Name of the device
|
||||||
|
*/
|
||||||
|
|
||||||
bool OpenAL::SetDevice(const String& deviceName)
|
bool OpenAL::SetDevice(const String& deviceName)
|
||||||
{
|
{
|
||||||
s_deviceName = deviceName;
|
s_deviceName = deviceName;
|
||||||
|
|
@ -253,6 +329,10 @@ namespace Nz
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Uninitializes the module
|
||||||
|
*/
|
||||||
|
|
||||||
void OpenAL::Uninitialize()
|
void OpenAL::Uninitialize()
|
||||||
{
|
{
|
||||||
CloseDevice();
|
CloseDevice();
|
||||||
|
|
@ -262,8 +342,14 @@ namespace Nz
|
||||||
s_library.Unload();
|
s_library.Unload();
|
||||||
}
|
}
|
||||||
|
|
||||||
///ATTENTION: La valeur entière est le nombre de canaux possédés par ce format
|
///WARNING: The integer value is the number of canals owned by the format
|
||||||
ALenum OpenAL::AudioFormat[AudioFormat_Max+1] = {0}; // Valeur ajoutées au chargement d'OpenAL
|
ALenum OpenAL::AudioFormat[AudioFormat_Max+1] = {0}; // Added values with loading of OpenAL
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Closes the device
|
||||||
|
*
|
||||||
|
* \remark Produces a NazaraWarning if you try to close an active device
|
||||||
|
*/
|
||||||
|
|
||||||
void OpenAL::CloseDevice()
|
void OpenAL::CloseDevice()
|
||||||
{
|
{
|
||||||
|
|
@ -277,24 +363,31 @@ namespace Nz
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!alcCloseDevice(s_device))
|
if (!alcCloseDevice(s_device))
|
||||||
// Nous n'avons pas pu fermer le device, ce qui signifie qu'il est en cours d'utilisation
|
// We could not close the close, this means that it's still in use
|
||||||
NazaraWarning("Failed to close device");
|
NazaraWarning("Failed to close device");
|
||||||
|
|
||||||
s_device = nullptr;
|
s_device = nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Opens the device
|
||||||
|
* \return true if open is successful
|
||||||
|
*
|
||||||
|
* \remark Produces a NazaraError if it could not create the context
|
||||||
|
*/
|
||||||
|
|
||||||
bool OpenAL::OpenDevice()
|
bool OpenAL::OpenDevice()
|
||||||
{
|
{
|
||||||
// Initialisation du module
|
// Initialisation of the module
|
||||||
s_device = alcOpenDevice(s_deviceName.IsEmpty() ? nullptr : s_deviceName.GetConstBuffer()); // On choisit le device par défaut
|
s_device = alcOpenDevice(s_deviceName.IsEmpty() ? nullptr : s_deviceName.GetConstBuffer()); // We choose the default device
|
||||||
if (!s_device)
|
if (!s_device)
|
||||||
{
|
{
|
||||||
NazaraError("Failed to open default device");
|
NazaraError("Failed to open default device");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Un seul contexte nous suffira
|
// One context is enough
|
||||||
s_context = alcCreateContext(s_device, nullptr);
|
s_context = alcCreateContext(s_device, nullptr);
|
||||||
if (!s_context)
|
if (!s_context)
|
||||||
{
|
{
|
||||||
|
|
@ -341,7 +434,7 @@ namespace Nz
|
||||||
s_version = 0;
|
s_version = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// On complète le tableau de formats
|
// We complete the formats table
|
||||||
AudioFormat[AudioFormat_Mono] = AL_FORMAT_MONO16;
|
AudioFormat[AudioFormat_Mono] = AL_FORMAT_MONO16;
|
||||||
AudioFormat[AudioFormat_Stereo] = AL_FORMAT_STEREO16;
|
AudioFormat[AudioFormat_Stereo] = AL_FORMAT_STEREO16;
|
||||||
|
|
||||||
|
|
@ -359,6 +452,16 @@ namespace Nz
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Loads the entry for the function name
|
||||||
|
* \return Pointer to the function
|
||||||
|
*
|
||||||
|
* \param name Name of the entry
|
||||||
|
* \param throwException Should throw exception if failed ?
|
||||||
|
*
|
||||||
|
* \remark Produces a std::runtime_error if entry does not exist and throwException is set to true
|
||||||
|
*/
|
||||||
|
|
||||||
OpenALFunc OpenAL::LoadEntry(const char* name, bool throwException)
|
OpenALFunc OpenAL::LoadEntry(const char* name, bool throwException)
|
||||||
{
|
{
|
||||||
OpenALFunc entry = reinterpret_cast<OpenALFunc>(s_library.GetSymbol(name));
|
OpenALFunc entry = reinterpret_cast<OpenALFunc>(s_library.GetSymbol(name));
|
||||||
|
|
|
||||||
|
|
@ -14,32 +14,76 @@
|
||||||
|
|
||||||
namespace Nz
|
namespace Nz
|
||||||
{
|
{
|
||||||
|
/*!
|
||||||
|
* \ingroup audio
|
||||||
|
* \class Nz::Sound
|
||||||
|
* \brief Audio class that represents a sound
|
||||||
|
*
|
||||||
|
* \remark Module Audio needs to be initialized to use this class
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Constructs a Sound object
|
||||||
|
*
|
||||||
|
* \param soundBuffer Buffer to read sound from
|
||||||
|
*/
|
||||||
|
|
||||||
Sound::Sound(const SoundBuffer* soundBuffer)
|
Sound::Sound(const SoundBuffer* soundBuffer)
|
||||||
{
|
{
|
||||||
SetBuffer(soundBuffer);
|
SetBuffer(soundBuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Constructs a Sound object which is a copy of another
|
||||||
|
*
|
||||||
|
* \param sound Sound to copy
|
||||||
|
*/
|
||||||
|
|
||||||
Sound::Sound(const Sound& sound) :
|
Sound::Sound(const Sound& sound) :
|
||||||
SoundEmitter(sound)
|
SoundEmitter(sound)
|
||||||
{
|
{
|
||||||
SetBuffer(sound.m_buffer);
|
SetBuffer(sound.m_buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Destructs the object and calls Stop
|
||||||
|
*
|
||||||
|
* \see Stop
|
||||||
|
*/
|
||||||
|
|
||||||
Sound::~Sound()
|
Sound::~Sound()
|
||||||
{
|
{
|
||||||
Stop();
|
Stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Enables the looping of the music
|
||||||
|
*
|
||||||
|
* \param loop Should sound loop
|
||||||
|
*/
|
||||||
|
|
||||||
void Sound::EnableLooping(bool loop)
|
void Sound::EnableLooping(bool loop)
|
||||||
{
|
{
|
||||||
alSourcei(m_source, AL_LOOPING, loop);
|
alSourcei(m_source, AL_LOOPING, loop);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Gets the internal buffer
|
||||||
|
* \return Internal buffer
|
||||||
|
*/
|
||||||
|
|
||||||
const SoundBuffer* Sound::GetBuffer() const
|
const SoundBuffer* Sound::GetBuffer() const
|
||||||
{
|
{
|
||||||
return m_buffer;
|
return m_buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Gets the duration of the sound
|
||||||
|
* \return Duration of the music in milliseconds
|
||||||
|
*
|
||||||
|
* \remark Produces a NazaraError if there is no buffer
|
||||||
|
*/
|
||||||
|
|
||||||
UInt32 Sound::GetDuration() const
|
UInt32 Sound::GetDuration() const
|
||||||
{
|
{
|
||||||
NazaraAssert(m_buffer, "Invalid sound buffer");
|
NazaraAssert(m_buffer, "Invalid sound buffer");
|
||||||
|
|
@ -47,6 +91,11 @@ namespace Nz
|
||||||
return m_buffer->GetDuration();
|
return m_buffer->GetDuration();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Gets the current offset in the sound
|
||||||
|
* \return Offset in milliseconds (works with entire seconds)
|
||||||
|
*/
|
||||||
|
|
||||||
UInt32 Sound::GetPlayingOffset() const
|
UInt32 Sound::GetPlayingOffset() const
|
||||||
{
|
{
|
||||||
ALint samples = 0;
|
ALint samples = 0;
|
||||||
|
|
@ -55,11 +104,21 @@ namespace Nz
|
||||||
return static_cast<UInt32>(1000ULL * samples / m_buffer->GetSampleRate());
|
return static_cast<UInt32>(1000ULL * samples / m_buffer->GetSampleRate());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Gets the status of the music
|
||||||
|
* \return Enumeration of type SoundStatus (Playing, Stopped, ...)
|
||||||
|
*/
|
||||||
|
|
||||||
SoundStatus Sound::GetStatus() const
|
SoundStatus Sound::GetStatus() const
|
||||||
{
|
{
|
||||||
return GetInternalStatus();
|
return GetInternalStatus();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Checks whether the sound is looping
|
||||||
|
* \return true if it is the case
|
||||||
|
*/
|
||||||
|
|
||||||
bool Sound::IsLooping() const
|
bool Sound::IsLooping() const
|
||||||
{
|
{
|
||||||
ALint loop;
|
ALint loop;
|
||||||
|
|
@ -68,16 +127,36 @@ namespace Nz
|
||||||
return loop != AL_FALSE;
|
return loop != AL_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Checks whether the sound is playable
|
||||||
|
* \return true if it is the case
|
||||||
|
*/
|
||||||
|
|
||||||
bool Sound::IsPlayable() const
|
bool Sound::IsPlayable() const
|
||||||
{
|
{
|
||||||
return m_buffer != nullptr;
|
return m_buffer != nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Checks whether the sound is playing
|
||||||
|
* \return true if it is the case
|
||||||
|
*/
|
||||||
|
|
||||||
bool Sound::IsPlaying() const
|
bool Sound::IsPlaying() const
|
||||||
{
|
{
|
||||||
return GetStatus() == SoundStatus_Playing;
|
return GetStatus() == SoundStatus_Playing;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Loads the sound from file
|
||||||
|
* \return true if loading is successful
|
||||||
|
*
|
||||||
|
* \param filePath Path to the file
|
||||||
|
* \param params Parameters for the sound
|
||||||
|
*
|
||||||
|
* \remark Produces a NazaraError if loading failed
|
||||||
|
*/
|
||||||
|
|
||||||
bool Sound::LoadFromFile(const String& filePath, const SoundBufferParams& params)
|
bool Sound::LoadFromFile(const String& filePath, const SoundBufferParams& params)
|
||||||
{
|
{
|
||||||
SoundBufferRef buffer = SoundBuffer::New();
|
SoundBufferRef buffer = SoundBuffer::New();
|
||||||
|
|
@ -91,6 +170,17 @@ namespace Nz
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Loads the sound from memory
|
||||||
|
* \return true if loading is successful
|
||||||
|
*
|
||||||
|
* \param data Raw memory
|
||||||
|
* \param size Size of the memory
|
||||||
|
* \param params Parameters for the sound
|
||||||
|
*
|
||||||
|
* \remark Produces a NazaraError if loading failed
|
||||||
|
*/
|
||||||
|
|
||||||
bool Sound::LoadFromMemory(const void* data, std::size_t size, const SoundBufferParams& params)
|
bool Sound::LoadFromMemory(const void* data, std::size_t size, const SoundBufferParams& params)
|
||||||
{
|
{
|
||||||
SoundBufferRef buffer = SoundBuffer::New();
|
SoundBufferRef buffer = SoundBuffer::New();
|
||||||
|
|
@ -104,6 +194,16 @@ namespace Nz
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Loads the sound from stream
|
||||||
|
* \return true if loading is successful
|
||||||
|
*
|
||||||
|
* \param stream Stream to the sound
|
||||||
|
* \param params Parameters for the sound
|
||||||
|
*
|
||||||
|
* \remark Produces a NazaraError if loading failed
|
||||||
|
*/
|
||||||
|
|
||||||
bool Sound::LoadFromStream(Stream& stream, const SoundBufferParams& params)
|
bool Sound::LoadFromStream(Stream& stream, const SoundBufferParams& params)
|
||||||
{
|
{
|
||||||
SoundBufferRef buffer = SoundBuffer::New();
|
SoundBufferRef buffer = SoundBuffer::New();
|
||||||
|
|
@ -117,15 +217,25 @@ namespace Nz
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Pauses the sound
|
||||||
|
*/
|
||||||
|
|
||||||
void Sound::Pause()
|
void Sound::Pause()
|
||||||
{
|
{
|
||||||
alSourcePause(m_source);
|
alSourcePause(m_source);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Plays the music
|
||||||
|
*
|
||||||
|
* \remark Produces a NazaraError if the sound is not playable with NAZARA_AUDIO_SAFE defined
|
||||||
|
*/
|
||||||
|
|
||||||
void Sound::Play()
|
void Sound::Play()
|
||||||
{
|
{
|
||||||
#if NAZARA_AUDIO_SAFE
|
#if NAZARA_AUDIO_SAFE
|
||||||
if (!m_buffer)
|
if (!IsPlayable())
|
||||||
{
|
{
|
||||||
NazaraError("Invalid sound buffer");
|
NazaraError("Invalid sound buffer");
|
||||||
return;
|
return;
|
||||||
|
|
@ -135,6 +245,14 @@ namespace Nz
|
||||||
alSourcePlay(m_source);
|
alSourcePlay(m_source);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Sets the internal buffer
|
||||||
|
*
|
||||||
|
* \param buffer Internal buffer
|
||||||
|
*
|
||||||
|
* \remark Produces a NazaraError if buffer is invalid with NAZARA_AUDIO_SAFE defined
|
||||||
|
*/
|
||||||
|
|
||||||
void Sound::SetBuffer(const SoundBuffer* buffer)
|
void Sound::SetBuffer(const SoundBuffer* buffer)
|
||||||
{
|
{
|
||||||
#if NAZARA_AUDIO_SAFE
|
#if NAZARA_AUDIO_SAFE
|
||||||
|
|
@ -158,11 +276,21 @@ namespace Nz
|
||||||
alSourcei(m_source, AL_BUFFER, AL_NONE);
|
alSourcei(m_source, AL_BUFFER, AL_NONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Sets the playing offset for the sound
|
||||||
|
*
|
||||||
|
* \param offset Offset in the sound in milliseconds
|
||||||
|
*/
|
||||||
|
|
||||||
void Sound::SetPlayingOffset(UInt32 offset)
|
void Sound::SetPlayingOffset(UInt32 offset)
|
||||||
{
|
{
|
||||||
alSourcei(m_source, AL_SAMPLE_OFFSET, static_cast<ALint>(offset/1000.f * m_buffer->GetSampleRate()));
|
alSourcei(m_source, AL_SAMPLE_OFFSET, static_cast<ALint>(offset/1000.f * m_buffer->GetSampleRate()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Stops the sound
|
||||||
|
*/
|
||||||
|
|
||||||
void Sound::Stop()
|
void Sound::Stop()
|
||||||
{
|
{
|
||||||
alSourceStop(m_source);
|
alSourceStop(m_source);
|
||||||
|
|
|
||||||
|
|
@ -12,10 +12,23 @@
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include <Nazara/Audio/Debug.hpp>
|
#include <Nazara/Audio/Debug.hpp>
|
||||||
|
|
||||||
///FIXME: Adapter la création
|
///FIXME: Adapt the creation
|
||||||
|
|
||||||
namespace Nz
|
namespace Nz
|
||||||
{
|
{
|
||||||
|
/*!
|
||||||
|
* \ingroup audio
|
||||||
|
* \class Nz::SoundBuffer
|
||||||
|
* \brief Audio class that represents a buffer for sound
|
||||||
|
*
|
||||||
|
* \remark Module Audio needs to be initialized to use this class
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Checks whether the parameters for the buffer' sound are correct
|
||||||
|
* \return true If parameters are valid
|
||||||
|
*/
|
||||||
|
|
||||||
bool SoundBufferParams::IsValid() const
|
bool SoundBufferParams::IsValid() const
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
|
|
@ -31,6 +44,20 @@ namespace Nz
|
||||||
UInt32 sampleRate;
|
UInt32 sampleRate;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Constructs a SoundBuffer object
|
||||||
|
*
|
||||||
|
* \param format Format for the audio
|
||||||
|
* \param sampleCount Number of samples
|
||||||
|
* \param sampleRate Rate of samples
|
||||||
|
* \param samples Samples raw data
|
||||||
|
*
|
||||||
|
* \remark Produces a NazaraError if creation went wrong with NAZARA_AUDIO_SAFE defined
|
||||||
|
* \remark Produces a std::runtime_error if creation went wrong with NAZARA_AUDIO_SAFE defined
|
||||||
|
*
|
||||||
|
* \see Create
|
||||||
|
*/
|
||||||
|
|
||||||
SoundBuffer::SoundBuffer(AudioFormat format, unsigned int sampleCount, unsigned int sampleRate, const Int16* samples)
|
SoundBuffer::SoundBuffer(AudioFormat format, unsigned int sampleCount, unsigned int sampleRate, const Int16* samples)
|
||||||
{
|
{
|
||||||
Create(format, sampleCount, sampleRate, samples);
|
Create(format, sampleCount, sampleRate, samples);
|
||||||
|
|
@ -44,6 +71,12 @@ namespace Nz
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Destructs the object and calls Destroy
|
||||||
|
*
|
||||||
|
* \see Destroy
|
||||||
|
*/
|
||||||
|
|
||||||
SoundBuffer::~SoundBuffer()
|
SoundBuffer::~SoundBuffer()
|
||||||
{
|
{
|
||||||
OnSoundBufferRelease(this);
|
OnSoundBufferRelease(this);
|
||||||
|
|
@ -51,6 +84,19 @@ namespace Nz
|
||||||
Destroy();
|
Destroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Creates the SoundBuffer object
|
||||||
|
* \return true if creation is successful
|
||||||
|
*
|
||||||
|
* \param format Format for the audio
|
||||||
|
* \param sampleCount Number of samples
|
||||||
|
* \param sampleRate Rate of samples
|
||||||
|
* \param samples Samples raw data
|
||||||
|
*
|
||||||
|
* \remark Produces a NazaraError if creation went wrong with NAZARA_AUDIO_SAFE defined,
|
||||||
|
* this could happen if parameters are invalid or creation of OpenAL buffers failed
|
||||||
|
*/
|
||||||
|
|
||||||
bool SoundBuffer::Create(AudioFormat format, unsigned int sampleCount, unsigned int sampleRate, const Int16* samples)
|
bool SoundBuffer::Create(AudioFormat format, unsigned int sampleCount, unsigned int sampleRate, const Int16* samples)
|
||||||
{
|
{
|
||||||
Destroy();
|
Destroy();
|
||||||
|
|
@ -81,7 +127,7 @@ namespace Nz
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// On vide le stack d'erreurs
|
// We empty the error stack
|
||||||
while (alGetError() != AL_NO_ERROR);
|
while (alGetError() != AL_NO_ERROR);
|
||||||
|
|
||||||
ALuint buffer;
|
ALuint buffer;
|
||||||
|
|
@ -115,6 +161,10 @@ namespace Nz
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Destroys the current sound buffer and frees resources
|
||||||
|
*/
|
||||||
|
|
||||||
void SoundBuffer::Destroy()
|
void SoundBuffer::Destroy()
|
||||||
{
|
{
|
||||||
if (m_impl)
|
if (m_impl)
|
||||||
|
|
@ -126,6 +176,13 @@ namespace Nz
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Gets the duration of the sound buffer
|
||||||
|
* \return Duration of the sound buffer in milliseconds
|
||||||
|
*
|
||||||
|
* \remark Produces a NazaraError if there is no sound buffer with NAZARA_AUDIO_SAFE defined
|
||||||
|
*/
|
||||||
|
|
||||||
UInt32 SoundBuffer::GetDuration() const
|
UInt32 SoundBuffer::GetDuration() const
|
||||||
{
|
{
|
||||||
#if NAZARA_AUDIO_SAFE
|
#if NAZARA_AUDIO_SAFE
|
||||||
|
|
@ -139,6 +196,13 @@ namespace Nz
|
||||||
return m_impl->duration;
|
return m_impl->duration;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Gets the format of the sound buffer
|
||||||
|
* \return Enumeration of type AudioFormat (mono, stereo, ...)
|
||||||
|
*
|
||||||
|
* \remark Produces a NazaraError if there is no sound buffer with NAZARA_AUDIO_SAFE defined
|
||||||
|
*/
|
||||||
|
|
||||||
AudioFormat SoundBuffer::GetFormat() const
|
AudioFormat SoundBuffer::GetFormat() const
|
||||||
{
|
{
|
||||||
#if NAZARA_AUDIO_SAFE
|
#if NAZARA_AUDIO_SAFE
|
||||||
|
|
@ -152,6 +216,13 @@ namespace Nz
|
||||||
return m_impl->format;
|
return m_impl->format;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Gets the internal raw samples
|
||||||
|
* \return Pointer to raw data
|
||||||
|
*
|
||||||
|
* \remark Produces a NazaraError if there is no sound buffer with NAZARA_AUDIO_SAFE defined
|
||||||
|
*/
|
||||||
|
|
||||||
const Int16* SoundBuffer::GetSamples() const
|
const Int16* SoundBuffer::GetSamples() const
|
||||||
{
|
{
|
||||||
#if NAZARA_AUDIO_SAFE
|
#if NAZARA_AUDIO_SAFE
|
||||||
|
|
@ -165,6 +236,13 @@ namespace Nz
|
||||||
return m_impl->samples.get();
|
return m_impl->samples.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Gets the number of samples in the sound buffer
|
||||||
|
* \return Count of samples (number of seconds * sample rate * channel count)
|
||||||
|
*
|
||||||
|
* \remark Produces a NazaraError if there is no sound buffer with NAZARA_AUDIO_SAFE defined
|
||||||
|
*/
|
||||||
|
|
||||||
unsigned int SoundBuffer::GetSampleCount() const
|
unsigned int SoundBuffer::GetSampleCount() const
|
||||||
{
|
{
|
||||||
#if NAZARA_AUDIO_SAFE
|
#if NAZARA_AUDIO_SAFE
|
||||||
|
|
@ -178,6 +256,13 @@ namespace Nz
|
||||||
return m_impl->sampleCount;
|
return m_impl->sampleCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Gets the rates of sample in the sound buffer
|
||||||
|
* \return Rate of sample in Hertz (Hz)
|
||||||
|
*
|
||||||
|
* \remark Produces a NazaraError if there is no sound buffer with NAZARA_AUDIO_SAFE defined
|
||||||
|
*/
|
||||||
|
|
||||||
unsigned int SoundBuffer::GetSampleRate() const
|
unsigned int SoundBuffer::GetSampleRate() const
|
||||||
{
|
{
|
||||||
#if NAZARA_AUDIO_SAFE
|
#if NAZARA_AUDIO_SAFE
|
||||||
|
|
@ -191,31 +276,75 @@ namespace Nz
|
||||||
return m_impl->sampleRate;
|
return m_impl->sampleRate;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Checks whether the sound buffer is valid
|
||||||
|
* \return true if it is the case
|
||||||
|
*/
|
||||||
|
|
||||||
bool SoundBuffer::IsValid() const
|
bool SoundBuffer::IsValid() const
|
||||||
{
|
{
|
||||||
return m_impl != nullptr;
|
return m_impl != nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Loads the sound buffer from file
|
||||||
|
* \return true if loading is successful
|
||||||
|
*
|
||||||
|
* \param filePath Path to the file
|
||||||
|
* \param params Parameters for the sound buffer
|
||||||
|
*/
|
||||||
|
|
||||||
bool SoundBuffer::LoadFromFile(const String& filePath, const SoundBufferParams& params)
|
bool SoundBuffer::LoadFromFile(const String& filePath, const SoundBufferParams& params)
|
||||||
{
|
{
|
||||||
return SoundBufferLoader::LoadFromFile(this, filePath, params);
|
return SoundBufferLoader::LoadFromFile(this, filePath, params);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Loads the sound buffer from memory
|
||||||
|
* \return true if loading is successful
|
||||||
|
*
|
||||||
|
* \param data Raw memory
|
||||||
|
* \param size Size of the memory
|
||||||
|
* \param params Parameters for the sound buffer
|
||||||
|
*/
|
||||||
|
|
||||||
bool SoundBuffer::LoadFromMemory(const void* data, std::size_t size, const SoundBufferParams& params)
|
bool SoundBuffer::LoadFromMemory(const void* data, std::size_t size, const SoundBufferParams& params)
|
||||||
{
|
{
|
||||||
return SoundBufferLoader::LoadFromMemory(this, data, size, params);
|
return SoundBufferLoader::LoadFromMemory(this, data, size, params);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Loads the sound buffer from stream
|
||||||
|
* \return true if loading is successful
|
||||||
|
*
|
||||||
|
* \param stream Stream to the sound buffer
|
||||||
|
* \param params Parameters for the sound buffer
|
||||||
|
*/
|
||||||
|
|
||||||
bool SoundBuffer::LoadFromStream(Stream& stream, const SoundBufferParams& params)
|
bool SoundBuffer::LoadFromStream(Stream& stream, const SoundBufferParams& params)
|
||||||
{
|
{
|
||||||
return SoundBufferLoader::LoadFromStream(this, stream, params);
|
return SoundBufferLoader::LoadFromStream(this, stream, params);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Checks whether the format is supported by the engine
|
||||||
|
* \return true if it is the case
|
||||||
|
*
|
||||||
|
* \param format Format to check
|
||||||
|
*/
|
||||||
|
|
||||||
bool SoundBuffer::IsFormatSupported(AudioFormat format)
|
bool SoundBuffer::IsFormatSupported(AudioFormat format)
|
||||||
{
|
{
|
||||||
return Audio::IsFormatSupported(format);
|
return Audio::IsFormatSupported(format);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Gets the internal OpenAL buffer
|
||||||
|
* \return The index of the OpenAL buffer
|
||||||
|
*
|
||||||
|
* \remark Produces a NazaraError if there is no sound buffer with NAZARA_AUDIO_SAFE defined
|
||||||
|
*/
|
||||||
|
|
||||||
unsigned int SoundBuffer::GetOpenALBuffer() const
|
unsigned int SoundBuffer::GetOpenALBuffer() const
|
||||||
{
|
{
|
||||||
#ifdef NAZARA_DEBUG
|
#ifdef NAZARA_DEBUG
|
||||||
|
|
@ -229,6 +358,13 @@ namespace Nz
|
||||||
return m_impl->buffer;
|
return m_impl->buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Initializes the libraries and managers
|
||||||
|
* \return true if initialization is successful
|
||||||
|
*
|
||||||
|
* \remark Produces a NazaraError if sub-initialization failed
|
||||||
|
*/
|
||||||
|
|
||||||
bool SoundBuffer::Initialize()
|
bool SoundBuffer::Initialize()
|
||||||
{
|
{
|
||||||
if (!SoundBufferLibrary::Initialize())
|
if (!SoundBufferLibrary::Initialize())
|
||||||
|
|
@ -246,6 +382,10 @@ namespace Nz
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Uninitializes the libraries and managers
|
||||||
|
*/
|
||||||
|
|
||||||
void SoundBuffer::Uninitialize()
|
void SoundBuffer::Uninitialize()
|
||||||
{
|
{
|
||||||
SoundBufferManager::Uninitialize();
|
SoundBufferManager::Uninitialize();
|
||||||
|
|
|
||||||
|
|
@ -11,11 +11,32 @@
|
||||||
|
|
||||||
namespace Nz
|
namespace Nz
|
||||||
{
|
{
|
||||||
|
/*!
|
||||||
|
* \ingroup audio
|
||||||
|
* \class Nz::SoundEmitter
|
||||||
|
* \brief Audio class that represents a sound source, that emits sound
|
||||||
|
*
|
||||||
|
* \remark Module Audio needs to be initialized to use this class
|
||||||
|
* \remark This class is abstract
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Constructs a SoundEmitter object
|
||||||
|
*/
|
||||||
|
|
||||||
SoundEmitter::SoundEmitter()
|
SoundEmitter::SoundEmitter()
|
||||||
{
|
{
|
||||||
alGenSources(1, &m_source);
|
alGenSources(1, &m_source);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Constructs a SoundEmitter object which is a copy of another
|
||||||
|
*
|
||||||
|
* \param emitter SoundEmitter to copy
|
||||||
|
*
|
||||||
|
* \remark Position and velocity are not copied
|
||||||
|
*/
|
||||||
|
|
||||||
SoundEmitter::SoundEmitter(const SoundEmitter& emitter)
|
SoundEmitter::SoundEmitter(const SoundEmitter& emitter)
|
||||||
{
|
{
|
||||||
alGenSources(1, &m_source);
|
alGenSources(1, &m_source);
|
||||||
|
|
@ -23,20 +44,35 @@ namespace Nz
|
||||||
SetAttenuation(emitter.GetAttenuation());
|
SetAttenuation(emitter.GetAttenuation());
|
||||||
SetMinDistance(emitter.GetMinDistance());
|
SetMinDistance(emitter.GetMinDistance());
|
||||||
SetPitch(emitter.GetPitch());
|
SetPitch(emitter.GetPitch());
|
||||||
// Pas de copie de position ou de vitesse
|
// No copy for position or velocity
|
||||||
SetVolume(emitter.GetVolume());
|
SetVolume(emitter.GetVolume());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Destructs the object
|
||||||
|
*/
|
||||||
|
|
||||||
SoundEmitter::~SoundEmitter()
|
SoundEmitter::~SoundEmitter()
|
||||||
{
|
{
|
||||||
alDeleteSources(1, &m_source);
|
alDeleteSources(1, &m_source);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Enables spatialization
|
||||||
|
*
|
||||||
|
* \param spatialization True if spatialization is enabled
|
||||||
|
*/
|
||||||
|
|
||||||
void SoundEmitter::EnableSpatialization(bool spatialization)
|
void SoundEmitter::EnableSpatialization(bool spatialization)
|
||||||
{
|
{
|
||||||
alSourcei(m_source, AL_SOURCE_RELATIVE, !spatialization);
|
alSourcei(m_source, AL_SOURCE_RELATIVE, !spatialization);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Gets the attenuation
|
||||||
|
* \return Amount that your sound will drop off as by the inverse square law
|
||||||
|
*/
|
||||||
|
|
||||||
float SoundEmitter::GetAttenuation() const
|
float SoundEmitter::GetAttenuation() const
|
||||||
{
|
{
|
||||||
ALfloat attenuation;
|
ALfloat attenuation;
|
||||||
|
|
@ -45,6 +81,11 @@ namespace Nz
|
||||||
return attenuation;
|
return attenuation;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Gets the minimum distance to hear
|
||||||
|
* \return Distance to begin to hear
|
||||||
|
*/
|
||||||
|
|
||||||
float SoundEmitter::GetMinDistance() const
|
float SoundEmitter::GetMinDistance() const
|
||||||
{
|
{
|
||||||
ALfloat distance;
|
ALfloat distance;
|
||||||
|
|
@ -53,6 +94,11 @@ namespace Nz
|
||||||
return distance;
|
return distance;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Gets the pitch
|
||||||
|
* \return Pitch of the sound
|
||||||
|
*/
|
||||||
|
|
||||||
float SoundEmitter::GetPitch() const
|
float SoundEmitter::GetPitch() const
|
||||||
{
|
{
|
||||||
ALfloat pitch;
|
ALfloat pitch;
|
||||||
|
|
@ -61,6 +107,11 @@ namespace Nz
|
||||||
return pitch;
|
return pitch;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Gets the position of the emitter
|
||||||
|
* \return Position of the sound
|
||||||
|
*/
|
||||||
|
|
||||||
Vector3f SoundEmitter::GetPosition() const
|
Vector3f SoundEmitter::GetPosition() const
|
||||||
{
|
{
|
||||||
Vector3f position;
|
Vector3f position;
|
||||||
|
|
@ -69,6 +120,11 @@ namespace Nz
|
||||||
return position;
|
return position;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Gets the velocity of the emitter
|
||||||
|
* \return Velocity of the sound
|
||||||
|
*/
|
||||||
|
|
||||||
Vector3f SoundEmitter::GetVelocity() const
|
Vector3f SoundEmitter::GetVelocity() const
|
||||||
{
|
{
|
||||||
Vector3f velocity;
|
Vector3f velocity;
|
||||||
|
|
@ -77,6 +133,11 @@ namespace Nz
|
||||||
return velocity;
|
return velocity;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Gets the volume of the emitter
|
||||||
|
* \param volume Float between [0, inf) with 100.f being the default
|
||||||
|
*/
|
||||||
|
|
||||||
float SoundEmitter::GetVolume() const
|
float SoundEmitter::GetVolume() const
|
||||||
{
|
{
|
||||||
ALfloat gain;
|
ALfloat gain;
|
||||||
|
|
@ -85,6 +146,11 @@ namespace Nz
|
||||||
return gain * 100.f;
|
return gain * 100.f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Checks whether the sound emitter has spatialization enabled
|
||||||
|
* \return true if it the case
|
||||||
|
*/
|
||||||
|
|
||||||
bool SoundEmitter::IsSpatialized() const
|
bool SoundEmitter::IsSpatialized() const
|
||||||
{
|
{
|
||||||
ALint relative;
|
ALint relative;
|
||||||
|
|
@ -93,46 +159,99 @@ namespace Nz
|
||||||
return relative == AL_FALSE;
|
return relative == AL_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Sets the attenuation
|
||||||
|
*
|
||||||
|
* \param attenuation Amount that your sound will drop off as by the inverse square law
|
||||||
|
*/
|
||||||
|
|
||||||
void SoundEmitter::SetAttenuation(float attenuation)
|
void SoundEmitter::SetAttenuation(float attenuation)
|
||||||
{
|
{
|
||||||
alSourcef(m_source, AL_ROLLOFF_FACTOR, attenuation);
|
alSourcef(m_source, AL_ROLLOFF_FACTOR, attenuation);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Sets the minimum distance to hear
|
||||||
|
*
|
||||||
|
* \param minDistance to begin to hear
|
||||||
|
*/
|
||||||
|
|
||||||
void SoundEmitter::SetMinDistance(float minDistance)
|
void SoundEmitter::SetMinDistance(float minDistance)
|
||||||
{
|
{
|
||||||
alSourcef(m_source, AL_REFERENCE_DISTANCE, minDistance);
|
alSourcef(m_source, AL_REFERENCE_DISTANCE, minDistance);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Sets the pitch
|
||||||
|
*
|
||||||
|
* \param pitch of the sound
|
||||||
|
*/
|
||||||
|
|
||||||
void SoundEmitter::SetPitch(float pitch)
|
void SoundEmitter::SetPitch(float pitch)
|
||||||
{
|
{
|
||||||
alSourcef(m_source, AL_PITCH, pitch);
|
alSourcef(m_source, AL_PITCH, pitch);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Sets the position of the emitter
|
||||||
|
*
|
||||||
|
* \param position Position of the sound
|
||||||
|
*/
|
||||||
|
|
||||||
void SoundEmitter::SetPosition(const Vector3f& position)
|
void SoundEmitter::SetPosition(const Vector3f& position)
|
||||||
{
|
{
|
||||||
alSourcefv(m_source, AL_POSITION, position);
|
alSourcefv(m_source, AL_POSITION, position);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Sets the position of the emitter
|
||||||
|
*
|
||||||
|
* \param position Position of the sound with (x, y, z)
|
||||||
|
*/
|
||||||
|
|
||||||
void SoundEmitter::SetPosition(float x, float y, float z)
|
void SoundEmitter::SetPosition(float x, float y, float z)
|
||||||
{
|
{
|
||||||
alSource3f(m_source, AL_POSITION, x, y, z);
|
alSource3f(m_source, AL_POSITION, x, y, z);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Sets the velocity of the emitter
|
||||||
|
*
|
||||||
|
* \param velocity Velocity of the sound
|
||||||
|
*/
|
||||||
|
|
||||||
void SoundEmitter::SetVelocity(const Vector3f& velocity)
|
void SoundEmitter::SetVelocity(const Vector3f& velocity)
|
||||||
{
|
{
|
||||||
alSourcefv(m_source, AL_VELOCITY, velocity);
|
alSourcefv(m_source, AL_VELOCITY, velocity);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Sets the velocity of the emitter
|
||||||
|
*
|
||||||
|
* \param velocity Velocity with (velX, velY, velZ)
|
||||||
|
*/
|
||||||
|
|
||||||
void SoundEmitter::SetVelocity(float velX, float velY, float velZ)
|
void SoundEmitter::SetVelocity(float velX, float velY, float velZ)
|
||||||
{
|
{
|
||||||
alSource3f(m_source, AL_VELOCITY, velX, velY, velZ);
|
alSource3f(m_source, AL_VELOCITY, velX, velY, velZ);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Sets the volume of the emitter
|
||||||
|
*
|
||||||
|
* \param volume Float between [0, inf) with 100.f being the default
|
||||||
|
*/
|
||||||
|
|
||||||
void SoundEmitter::SetVolume(float volume)
|
void SoundEmitter::SetVolume(float volume)
|
||||||
{
|
{
|
||||||
alSourcef(m_source, AL_GAIN, volume * 0.01f);
|
alSourcef(m_source, AL_GAIN, volume * 0.01f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Gets the status of the sound emitter
|
||||||
|
* \return Enumeration of type SoundStatus (Playing, Stopped, ...)
|
||||||
|
*/
|
||||||
|
|
||||||
SoundStatus SoundEmitter::GetInternalStatus() const
|
SoundStatus SoundEmitter::GetInternalStatus() const
|
||||||
{
|
{
|
||||||
ALint state;
|
ALint state;
|
||||||
|
|
|
||||||
|
|
@ -6,5 +6,13 @@
|
||||||
|
|
||||||
namespace Nz
|
namespace Nz
|
||||||
{
|
{
|
||||||
|
/*!
|
||||||
|
* \ingroup audio
|
||||||
|
* \class Nz::SoundStream
|
||||||
|
* \brief Audio class that represents a sound stream
|
||||||
|
*
|
||||||
|
* \remark This class is abstract
|
||||||
|
*/
|
||||||
|
|
||||||
SoundStream::~SoundStream() = default;
|
SoundStream::~SoundStream() = default;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,7 @@ namespace Nz
|
||||||
|
|
||||||
bool Core::Initialize()
|
bool Core::Initialize()
|
||||||
{
|
{
|
||||||
if (s_moduleReferenceCounter > 0)
|
if (IsInitialized())
|
||||||
{
|
{
|
||||||
s_moduleReferenceCounter++;
|
s_moduleReferenceCounter++;
|
||||||
return true; // Already initialized
|
return true; // Already initialized
|
||||||
|
|
|
||||||
|
|
@ -906,5 +906,5 @@ namespace Nz
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -607,6 +607,54 @@ namespace Nz
|
||||||
parameter.value.ptrVal = value;
|
parameter.value.ptrVal = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Gives a string representation
|
||||||
|
* \return A string representation of the object: "ParameterList(Name: Type(value), ...)"
|
||||||
|
*/
|
||||||
|
String ParameterList::ToString() const
|
||||||
|
{
|
||||||
|
StringStream ss;
|
||||||
|
|
||||||
|
ss << "ParameterList(";
|
||||||
|
for (auto it = m_parameters.cbegin(); it != m_parameters.cend();)
|
||||||
|
{
|
||||||
|
ss << it->first << ": ";
|
||||||
|
switch (it->second.type)
|
||||||
|
{
|
||||||
|
case ParameterType_Boolean:
|
||||||
|
ss << "Boolean(" << String::Boolean(it->second.value.boolVal) << ")";
|
||||||
|
break;
|
||||||
|
case ParameterType_Color:
|
||||||
|
ss << "Color(" << it->second.value.colorVal.ToString() << ")";
|
||||||
|
break;
|
||||||
|
case ParameterType_Float:
|
||||||
|
ss << "Float(" << it->second.value.floatVal << ")";
|
||||||
|
break;
|
||||||
|
case ParameterType_Integer:
|
||||||
|
ss << "Integer(" << it->second.value.intVal << ")";
|
||||||
|
break;
|
||||||
|
case ParameterType_String:
|
||||||
|
ss << "String(" << it->second.value.stringVal << ")";
|
||||||
|
break;
|
||||||
|
case ParameterType_Pointer:
|
||||||
|
ss << "Pointer(" << String::Pointer(it->second.value.ptrVal) << ")";
|
||||||
|
break;
|
||||||
|
case ParameterType_Userdata:
|
||||||
|
ss << "Userdata(" << String::Pointer(it->second.value.userdataVal->ptr) << ")";
|
||||||
|
break;
|
||||||
|
case ParameterType_None:
|
||||||
|
ss << "None";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (++it != m_parameters.cend())
|
||||||
|
ss << ", ";
|
||||||
|
}
|
||||||
|
ss << ")";
|
||||||
|
|
||||||
|
return ss;
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Sets a userdata parameter named `name`
|
* \brief Sets a userdata parameter named `name`
|
||||||
*
|
*
|
||||||
|
|
@ -724,3 +772,17 @@ namespace Nz
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Output operator
|
||||||
|
* \return The stream
|
||||||
|
*
|
||||||
|
* \param out The stream
|
||||||
|
* \param parameterList The ParameterList to output
|
||||||
|
*/
|
||||||
|
|
||||||
|
std::ostream& operator<<(std::ostream& out, const Nz::ParameterList& parameterList)
|
||||||
|
{
|
||||||
|
out << parameterList.ToString();
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -143,7 +143,18 @@ namespace Nz
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
mode_t permissions; // TODO : get permission from first file
|
mode_t permissions;
|
||||||
|
struct stat sb;
|
||||||
|
if (fstat(fd1, &sb) == -1) // get permission from first file
|
||||||
|
{
|
||||||
|
NazaraWarning("Could not get permissions of source file");
|
||||||
|
permissions = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
permissions = sb.st_mode & ~S_IFMT; // S_IFMT: bit mask for the file type bit field -> ~S_IFMT: general permissions
|
||||||
|
}
|
||||||
|
|
||||||
int fd2 = open64(targetPath.GetConstBuffer(), O_WRONLY | O_TRUNC, permissions);
|
int fd2 = open64(targetPath.GetConstBuffer(), O_WRONLY | O_TRUNC, permissions);
|
||||||
if (fd2 == -1)
|
if (fd2 == -1)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,14 @@
|
||||||
|
|
||||||
namespace Nz
|
namespace Nz
|
||||||
{
|
{
|
||||||
|
/*!
|
||||||
|
* \ingroup graphics
|
||||||
|
* \class Nz::AbstractBackground
|
||||||
|
* \brief Graphics class that represents the background for our scene
|
||||||
|
*
|
||||||
|
* \remark This class is abstract
|
||||||
|
*/
|
||||||
|
|
||||||
AbstractBackground::~AbstractBackground() = default;
|
AbstractBackground::~AbstractBackground() = default;
|
||||||
|
|
||||||
BackgroundLibrary::LibraryMap AbstractBackground::s_library;
|
BackgroundLibrary::LibraryMap AbstractBackground::s_library;
|
||||||
|
|
|
||||||
|
|
@ -7,23 +7,55 @@
|
||||||
|
|
||||||
namespace Nz
|
namespace Nz
|
||||||
{
|
{
|
||||||
|
/*!
|
||||||
|
* \ingroup graphics
|
||||||
|
* \class Nz::AbstractRenderQueue
|
||||||
|
* \brief Graphics class that represents the rendering queue for our scene
|
||||||
|
*
|
||||||
|
* \remark This class is abstract
|
||||||
|
*/
|
||||||
|
|
||||||
AbstractRenderQueue::~AbstractRenderQueue() = default;
|
AbstractRenderQueue::~AbstractRenderQueue() = default;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Adds a directional light to the rendering queue
|
||||||
|
*
|
||||||
|
* \param light Directional light
|
||||||
|
*/
|
||||||
|
|
||||||
void AbstractRenderQueue::AddDirectionalLight(const DirectionalLight& light)
|
void AbstractRenderQueue::AddDirectionalLight(const DirectionalLight& light)
|
||||||
{
|
{
|
||||||
directionalLights.push_back(light);
|
directionalLights.push_back(light);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Adds a point light to the rendering queue
|
||||||
|
*
|
||||||
|
* \param light Point light
|
||||||
|
*/
|
||||||
|
|
||||||
void AbstractRenderQueue::AddPointLight(const PointLight& light)
|
void AbstractRenderQueue::AddPointLight(const PointLight& light)
|
||||||
{
|
{
|
||||||
pointLights.push_back(light);
|
pointLights.push_back(light);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Adds a spot light to the rendering queue
|
||||||
|
*
|
||||||
|
* \param light Spot light
|
||||||
|
*/
|
||||||
|
|
||||||
void AbstractRenderQueue::AddSpotLight(const SpotLight& light)
|
void AbstractRenderQueue::AddSpotLight(const SpotLight& light)
|
||||||
{
|
{
|
||||||
spotLights.push_back(light);
|
spotLights.push_back(light);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Clears the rendering queue
|
||||||
|
*
|
||||||
|
* \param fully Should everything be cleared ?
|
||||||
|
*/
|
||||||
|
|
||||||
void AbstractRenderQueue::Clear(bool fully)
|
void AbstractRenderQueue::Clear(bool fully)
|
||||||
{
|
{
|
||||||
NazaraUnused(fully);
|
NazaraUnused(fully);
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,18 @@
|
||||||
|
|
||||||
namespace Nz
|
namespace Nz
|
||||||
{
|
{
|
||||||
|
/*!
|
||||||
|
* \ingroup graphics
|
||||||
|
* \class Nz::AbstractRenderTechnique
|
||||||
|
* \brief Graphics class that represents the rendering technique for our scene
|
||||||
|
*
|
||||||
|
* \remark This class is abstract
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Constructs a AbstractRenderTechnique object
|
||||||
|
*/
|
||||||
|
|
||||||
AbstractRenderTechnique::AbstractRenderTechnique() :
|
AbstractRenderTechnique::AbstractRenderTechnique() :
|
||||||
m_instancingEnabled(true)
|
m_instancingEnabled(true)
|
||||||
{
|
{
|
||||||
|
|
@ -17,16 +29,34 @@ namespace Nz
|
||||||
|
|
||||||
AbstractRenderTechnique::~AbstractRenderTechnique() = default;
|
AbstractRenderTechnique::~AbstractRenderTechnique() = default;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Enables the instancing
|
||||||
|
*
|
||||||
|
* \param instancing Should instancing be enabled
|
||||||
|
*
|
||||||
|
* \remark This may improve performances
|
||||||
|
*/
|
||||||
|
|
||||||
void AbstractRenderTechnique::EnableInstancing(bool instancing)
|
void AbstractRenderTechnique::EnableInstancing(bool instancing)
|
||||||
{
|
{
|
||||||
m_instancingEnabled = instancing;
|
m_instancingEnabled = instancing;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Gets the name of the actual technique
|
||||||
|
* \return Name of the technique being used
|
||||||
|
*/
|
||||||
|
|
||||||
String AbstractRenderTechnique::GetName() const
|
String AbstractRenderTechnique::GetName() const
|
||||||
{
|
{
|
||||||
return RenderTechniques::ToString(GetType());
|
return RenderTechniques::ToString(GetType());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Checks whether the instancing is enabled
|
||||||
|
* \return true If it is the case
|
||||||
|
*/
|
||||||
|
|
||||||
bool AbstractRenderTechnique::IsInstancingEnabled() const
|
bool AbstractRenderTechnique::IsInstancingEnabled() const
|
||||||
{
|
{
|
||||||
return m_instancingEnabled;
|
return m_instancingEnabled;
|
||||||
|
|
|
||||||
|
|
@ -7,5 +7,13 @@
|
||||||
|
|
||||||
namespace Nz
|
namespace Nz
|
||||||
{
|
{
|
||||||
|
/*!
|
||||||
|
* \ingroup graphics
|
||||||
|
* \class Nz::AbstractViewer
|
||||||
|
* \brief Graphics class that represents the viewer for our scene
|
||||||
|
*
|
||||||
|
* \remark This class is abstract
|
||||||
|
*/
|
||||||
|
|
||||||
AbstractViewer::~AbstractViewer() = default;
|
AbstractViewer::~AbstractViewer() = default;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,19 @@
|
||||||
|
|
||||||
namespace Nz
|
namespace Nz
|
||||||
{
|
{
|
||||||
|
/*!
|
||||||
|
* \ingroup graphics
|
||||||
|
* \class Nz::Billboard
|
||||||
|
* \brief Graphics class that represents a billboard, a 2D surface which simulates a 3D object
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Adds this billboard to the render queue
|
||||||
|
*
|
||||||
|
* \param renderQueue Queue to be added
|
||||||
|
* \param instanceData Data used for instance
|
||||||
|
*/
|
||||||
|
|
||||||
void Billboard::AddToRenderQueue(AbstractRenderQueue* renderQueue, const InstanceData& instanceData) const
|
void Billboard::AddToRenderQueue(AbstractRenderQueue* renderQueue, const InstanceData& instanceData) const
|
||||||
{
|
{
|
||||||
if (!m_material)
|
if (!m_material)
|
||||||
|
|
@ -20,6 +33,10 @@ namespace Nz
|
||||||
renderQueue->AddBillboard(instanceData.renderOrder, m_material, instanceData.transformMatrix.GetTranslation(), m_size, m_sinCos, m_color);
|
renderQueue->AddBillboard(instanceData.renderOrder, m_material, instanceData.transformMatrix.GetTranslation(), m_size, m_sinCos, m_color);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* \brief Makes the bounding volume of this billboard
|
||||||
|
*/
|
||||||
|
|
||||||
void Billboard::MakeBoundingVolume() const
|
void Billboard::MakeBoundingVolume() const
|
||||||
{
|
{
|
||||||
constexpr float sqrt2 = float(M_SQRT2);
|
constexpr float sqrt2 = float(M_SQRT2);
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,11 @@ namespace Nz
|
||||||
{
|
{
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
|
/*!
|
||||||
|
* \brief Defines render states
|
||||||
|
* \return RenderStates for the color background
|
||||||
|
*/
|
||||||
|
|
||||||
RenderStates BuildRenderStates()
|
RenderStates BuildRenderStates()
|
||||||
{
|
{
|
||||||
RenderStates states;
|
RenderStates states;
|
||||||
|
|
@ -24,6 +29,18 @@ namespace Nz
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \ingroup graphics
|
||||||
|
* \class Nz::ColorBackground
|
||||||
|
* \brief Graphics class that represents a background with uniform color
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Constructs a ColorBackground object with a color
|
||||||
|
*
|
||||||
|
* \param color Uniform color (by default Black)
|
||||||
|
*/
|
||||||
|
|
||||||
ColorBackground::ColorBackground(const Color& color) :
|
ColorBackground::ColorBackground(const Color& color) :
|
||||||
m_color(color)
|
m_color(color)
|
||||||
{
|
{
|
||||||
|
|
@ -38,6 +55,12 @@ namespace Nz
|
||||||
m_vertexDepthUniform = shader->GetUniformLocation("VertexDepth");
|
m_vertexDepthUniform = shader->GetUniformLocation("VertexDepth");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Draws this relatively to the viewer
|
||||||
|
*
|
||||||
|
* \param viewer Viewer for the background
|
||||||
|
*/
|
||||||
|
|
||||||
void ColorBackground::Draw(const AbstractViewer* viewer) const
|
void ColorBackground::Draw(const AbstractViewer* viewer) const
|
||||||
{
|
{
|
||||||
NazaraUnused(viewer);
|
NazaraUnused(viewer);
|
||||||
|
|
@ -55,16 +78,32 @@ namespace Nz
|
||||||
Renderer::DrawFullscreenQuad();
|
Renderer::DrawFullscreenQuad();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Gets the background type
|
||||||
|
* \return Type of background
|
||||||
|
*/
|
||||||
|
|
||||||
BackgroundType ColorBackground::GetBackgroundType() const
|
BackgroundType ColorBackground::GetBackgroundType() const
|
||||||
{
|
{
|
||||||
return BackgroundType_Color;
|
return BackgroundType_Color;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Gets the color of the background
|
||||||
|
* \return Background color
|
||||||
|
*/
|
||||||
|
|
||||||
Color ColorBackground::GetColor() const
|
Color ColorBackground::GetColor() const
|
||||||
{
|
{
|
||||||
return m_color;
|
return m_color;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Sets the color of the background
|
||||||
|
*
|
||||||
|
* \param color Background color
|
||||||
|
*/
|
||||||
|
|
||||||
void ColorBackground::SetColor(const Color& color)
|
void ColorBackground::SetColor(const Color& color)
|
||||||
{
|
{
|
||||||
m_color = color;
|
m_color = color;
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,16 @@
|
||||||
|
|
||||||
namespace Nz
|
namespace Nz
|
||||||
{
|
{
|
||||||
|
/*!
|
||||||
|
* \ingroup graphics
|
||||||
|
* \class Nz::DeferredBloomPass
|
||||||
|
* \brief Graphics class that represents the pass for bloom in deferred rendering
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Constructs a DeferredBloomPass object by default
|
||||||
|
*/
|
||||||
|
|
||||||
DeferredBloomPass::DeferredBloomPass() :
|
DeferredBloomPass::DeferredBloomPass() :
|
||||||
m_uniformUpdated(false),
|
m_uniformUpdated(false),
|
||||||
m_brightLuminance(0.8f),
|
m_brightLuminance(0.8f),
|
||||||
|
|
@ -32,26 +42,55 @@ namespace Nz
|
||||||
|
|
||||||
DeferredBloomPass::~DeferredBloomPass() = default;
|
DeferredBloomPass::~DeferredBloomPass() = default;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Gets the number of pass for blur
|
||||||
|
* \return Number of pass for blur
|
||||||
|
*/
|
||||||
|
|
||||||
unsigned int DeferredBloomPass::GetBlurPassCount() const
|
unsigned int DeferredBloomPass::GetBlurPassCount() const
|
||||||
{
|
{
|
||||||
return m_blurPassCount;
|
return m_blurPassCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Gets the coefficiant for luminosity
|
||||||
|
* \return Luminosity of bright elements
|
||||||
|
*/
|
||||||
|
|
||||||
float DeferredBloomPass::GetBrightLuminance() const
|
float DeferredBloomPass::GetBrightLuminance() const
|
||||||
{
|
{
|
||||||
return m_brightLuminance;
|
return m_brightLuminance;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Gets the coefficiant for the middle grey
|
||||||
|
* \return Luminosity of grey elements
|
||||||
|
*/
|
||||||
|
|
||||||
float DeferredBloomPass::GetBrightMiddleGrey() const
|
float DeferredBloomPass::GetBrightMiddleGrey() const
|
||||||
{
|
{
|
||||||
return m_brightMiddleGrey;
|
return m_brightMiddleGrey;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Gets the coefficiant for things to be bright
|
||||||
|
* \return Threshold for bright elements
|
||||||
|
*/
|
||||||
|
|
||||||
float DeferredBloomPass::GetBrightThreshold() const
|
float DeferredBloomPass::GetBrightThreshold() const
|
||||||
{
|
{
|
||||||
return m_brightThreshold;
|
return m_brightThreshold;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Gets the ith texture
|
||||||
|
* \return Texture computed
|
||||||
|
*
|
||||||
|
* \param i Index of the texture
|
||||||
|
*
|
||||||
|
* \remark Produces a NazaraError with NAZARA_GRAPHICS_SAFE defined if index is invalid
|
||||||
|
*/
|
||||||
|
|
||||||
Texture* DeferredBloomPass::GetTexture(unsigned int i) const
|
Texture* DeferredBloomPass::GetTexture(unsigned int i) const
|
||||||
{
|
{
|
||||||
#if NAZARA_GRAPHICS_SAFE
|
#if NAZARA_GRAPHICS_SAFE
|
||||||
|
|
@ -65,7 +104,16 @@ namespace Nz
|
||||||
return m_bloomTextures[i];
|
return m_bloomTextures[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DeferredBloomPass::Process(const SceneData& sceneData, unsigned int firstWorkTexture, unsigned secondWorkTexture) const
|
/*!
|
||||||
|
* \brief Processes the work on the data while working with textures
|
||||||
|
* \return true
|
||||||
|
*
|
||||||
|
* \param sceneData Data for the scene
|
||||||
|
* \param firstWorkTexture Index of the first texture to work with
|
||||||
|
* \param firstWorkTexture Index of the second texture to work with
|
||||||
|
*/
|
||||||
|
|
||||||
|
bool DeferredBloomPass::Process(const SceneData& sceneData, unsigned int firstWorkTexture, unsigned int secondWorkTexture) const
|
||||||
{
|
{
|
||||||
NazaraUnused(sceneData);
|
NazaraUnused(sceneData);
|
||||||
|
|
||||||
|
|
@ -124,6 +172,13 @@ namespace Nz
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Resizes the texture sizes
|
||||||
|
* \return true If successful
|
||||||
|
*
|
||||||
|
* \param dimensions Dimensions for the compute texture
|
||||||
|
*/
|
||||||
|
|
||||||
bool DeferredBloomPass::Resize(const Vector2ui& dimensions)
|
bool DeferredBloomPass::Resize(const Vector2ui& dimensions)
|
||||||
{
|
{
|
||||||
DeferredRenderPass::Resize(dimensions);
|
DeferredRenderPass::Resize(dimensions);
|
||||||
|
|
@ -145,23 +200,47 @@ namespace Nz
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Sets the number of pass for blur
|
||||||
|
*
|
||||||
|
* \param passCount Number of pass for blur
|
||||||
|
*/
|
||||||
|
|
||||||
void DeferredBloomPass::SetBlurPassCount(unsigned int passCount)
|
void DeferredBloomPass::SetBlurPassCount(unsigned int passCount)
|
||||||
{
|
{
|
||||||
m_blurPassCount = passCount; // N'est pas une uniforme
|
m_blurPassCount = passCount; // N'est pas une uniforme
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Sets the coefficiant for luminosity
|
||||||
|
*
|
||||||
|
* \param luminance Luminosity of bright elements
|
||||||
|
*/
|
||||||
|
|
||||||
void DeferredBloomPass::SetBrightLuminance(float luminance)
|
void DeferredBloomPass::SetBrightLuminance(float luminance)
|
||||||
{
|
{
|
||||||
m_brightLuminance = luminance;
|
m_brightLuminance = luminance;
|
||||||
m_uniformUpdated = false;
|
m_uniformUpdated = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Sets the coefficiant for the middle grey
|
||||||
|
*
|
||||||
|
* \param middleGrey Luminosity of grey elements
|
||||||
|
*/
|
||||||
|
|
||||||
void DeferredBloomPass::SetBrightMiddleGrey(float middleGrey)
|
void DeferredBloomPass::SetBrightMiddleGrey(float middleGrey)
|
||||||
{
|
{
|
||||||
m_brightMiddleGrey = middleGrey;
|
m_brightMiddleGrey = middleGrey;
|
||||||
m_uniformUpdated = false;
|
m_uniformUpdated = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Sets the coefficiant for things to be bright
|
||||||
|
*
|
||||||
|
* \param threshold Threshold for bright elements
|
||||||
|
*/
|
||||||
|
|
||||||
void DeferredBloomPass::SetBrightThreshold(float threshold)
|
void DeferredBloomPass::SetBrightThreshold(float threshold)
|
||||||
{
|
{
|
||||||
m_brightThreshold = threshold;
|
m_brightThreshold = threshold;
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,10 @@ namespace Nz
|
||||||
{
|
{
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
|
/*!
|
||||||
|
* \brief Builds the shader for the depth of field
|
||||||
|
* \return Reference to the shader newly created
|
||||||
|
*/
|
||||||
// http://digitalerr0r.wordpress.com/2009/05/16/xna-shader-programming-tutorial-20-depth-of-field/
|
// http://digitalerr0r.wordpress.com/2009/05/16/xna-shader-programming-tutorial-20-depth-of-field/
|
||||||
ShaderRef BuildDepthOfFieldShader()
|
ShaderRef BuildDepthOfFieldShader()
|
||||||
{
|
{
|
||||||
|
|
@ -92,6 +96,16 @@ namespace Nz
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \ingroup graphics
|
||||||
|
* \class Nz::DeferredDOFPass
|
||||||
|
* \brief Graphics class that represents the pass for depth of field in deferred rendering
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Constructs a DeferredDOFPass object by default
|
||||||
|
*/
|
||||||
|
|
||||||
DeferredDOFPass::DeferredDOFPass()
|
DeferredDOFPass::DeferredDOFPass()
|
||||||
{
|
{
|
||||||
m_dofShader = BuildDepthOfFieldShader();
|
m_dofShader = BuildDepthOfFieldShader();
|
||||||
|
|
@ -118,7 +132,16 @@ namespace Nz
|
||||||
|
|
||||||
DeferredDOFPass::~DeferredDOFPass() = default;
|
DeferredDOFPass::~DeferredDOFPass() = default;
|
||||||
|
|
||||||
bool DeferredDOFPass::Process(const SceneData& sceneData, unsigned int firstWorkTexture, unsigned secondWorkTexture) const
|
/*!
|
||||||
|
* \brief Processes the work on the data while working with textures
|
||||||
|
* \return true
|
||||||
|
*
|
||||||
|
* \param sceneData Data for the scene
|
||||||
|
* \param firstWorkTexture Index of the first texture to work with
|
||||||
|
* \param firstWorkTexture Index of the second texture to work with
|
||||||
|
*/
|
||||||
|
|
||||||
|
bool DeferredDOFPass::Process(const SceneData& sceneData, unsigned int firstWorkTexture, unsigned int secondWorkTexture) const
|
||||||
{
|
{
|
||||||
NazaraUnused(sceneData);
|
NazaraUnused(sceneData);
|
||||||
|
|
||||||
|
|
@ -162,6 +185,13 @@ namespace Nz
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Resizes the texture sizes
|
||||||
|
* \return true If successful
|
||||||
|
*
|
||||||
|
* \param dimensions Dimensions for the compute texture
|
||||||
|
*/
|
||||||
|
|
||||||
bool DeferredDOFPass::Resize(const Vector2ui& dimensions)
|
bool DeferredDOFPass::Resize(const Vector2ui& dimensions)
|
||||||
{
|
{
|
||||||
DeferredRenderPass::Resize(dimensions);
|
DeferredRenderPass::Resize(dimensions);
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,16 @@
|
||||||
|
|
||||||
namespace Nz
|
namespace Nz
|
||||||
{
|
{
|
||||||
|
/*!
|
||||||
|
* \ingroup graphics
|
||||||
|
* \class Nz::DeferredFXAAPass
|
||||||
|
* \brief Graphics class that represents the pass for FXAA in deferred rendering
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Constructs a DeferredFXAAPass object by default
|
||||||
|
*/
|
||||||
|
|
||||||
DeferredFXAAPass::DeferredFXAAPass()
|
DeferredFXAAPass::DeferredFXAAPass()
|
||||||
{
|
{
|
||||||
m_fxaaShader = ShaderLibrary::Get("DeferredFXAA");
|
m_fxaaShader = ShaderLibrary::Get("DeferredFXAA");
|
||||||
|
|
@ -23,7 +33,16 @@ namespace Nz
|
||||||
|
|
||||||
DeferredFXAAPass::~DeferredFXAAPass() = default;
|
DeferredFXAAPass::~DeferredFXAAPass() = default;
|
||||||
|
|
||||||
bool DeferredFXAAPass::Process(const SceneData& sceneData, unsigned int firstWorkTexture, unsigned secondWorkTexture) const
|
/*!
|
||||||
|
* \brief Processes the work on the data while working with textures
|
||||||
|
* \return true
|
||||||
|
*
|
||||||
|
* \param sceneData Data for the scene
|
||||||
|
* \param firstWorkTexture Index of the first texture to work with
|
||||||
|
* \param firstWorkTexture Index of the second texture to work with
|
||||||
|
*/
|
||||||
|
|
||||||
|
bool DeferredFXAAPass::Process(const SceneData& sceneData, unsigned int firstWorkTexture, unsigned int secondWorkTexture) const
|
||||||
{
|
{
|
||||||
NazaraUnused(sceneData);
|
NazaraUnused(sceneData);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,16 @@
|
||||||
|
|
||||||
namespace Nz
|
namespace Nz
|
||||||
{
|
{
|
||||||
|
/*!
|
||||||
|
* \ingroup graphics
|
||||||
|
* \class Nz::DeferredFinalPass
|
||||||
|
* \brief Graphics class that represents the final pass in deferred rendering
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Constructs a DeferredFinalPass object by default
|
||||||
|
*/
|
||||||
|
|
||||||
DeferredFinalPass::DeferredFinalPass()
|
DeferredFinalPass::DeferredFinalPass()
|
||||||
{
|
{
|
||||||
m_pointSampler.SetAnisotropyLevel(1);
|
m_pointSampler.SetAnisotropyLevel(1);
|
||||||
|
|
@ -34,7 +44,16 @@ namespace Nz
|
||||||
|
|
||||||
DeferredFinalPass::~DeferredFinalPass() = default;
|
DeferredFinalPass::~DeferredFinalPass() = default;
|
||||||
|
|
||||||
bool DeferredFinalPass::Process(const SceneData& sceneData, unsigned int firstWorkTexture, unsigned secondWorkTexture) const
|
/*!
|
||||||
|
* \brief Processes the work on the data while working with textures
|
||||||
|
* \return true
|
||||||
|
*
|
||||||
|
* \param sceneData Data for the scene
|
||||||
|
* \param firstWorkTexture Index of the first texture to work with
|
||||||
|
* \param firstWorkTexture Index of the second texture to work with
|
||||||
|
*/
|
||||||
|
|
||||||
|
bool DeferredFinalPass::Process(const SceneData& sceneData, unsigned int firstWorkTexture, unsigned int secondWorkTexture) const
|
||||||
{
|
{
|
||||||
NazaraAssert(sceneData.viewer, "Invalid viewer");
|
NazaraAssert(sceneData.viewer, "Invalid viewer");
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,11 @@ namespace Nz
|
||||||
{
|
{
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
|
/*!
|
||||||
|
* \brief Builds the shader for the fog
|
||||||
|
* \return Reference to the shader newly created
|
||||||
|
*/
|
||||||
|
|
||||||
ShaderRef BuildFogShader()
|
ShaderRef BuildFogShader()
|
||||||
{
|
{
|
||||||
/*const UInt8 fragmentSource[] = {
|
/*const UInt8 fragmentSource[] = {
|
||||||
|
|
@ -117,6 +122,16 @@ namespace Nz
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \ingroup graphics
|
||||||
|
* \class Nz::DeferredFogPass
|
||||||
|
* \brief Graphics class that represents the pass for fog in deferred rendering
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Constructs a DeferredFogPass object by default
|
||||||
|
*/
|
||||||
|
|
||||||
DeferredFogPass::DeferredFogPass()
|
DeferredFogPass::DeferredFogPass()
|
||||||
{
|
{
|
||||||
m_pointSampler.SetAnisotropyLevel(1);
|
m_pointSampler.SetAnisotropyLevel(1);
|
||||||
|
|
@ -131,7 +146,16 @@ namespace Nz
|
||||||
|
|
||||||
DeferredFogPass::~DeferredFogPass() = default;
|
DeferredFogPass::~DeferredFogPass() = default;
|
||||||
|
|
||||||
bool DeferredFogPass::Process( const SceneData& sceneData, unsigned int firstWorkTexture, unsigned secondWorkTexture) const
|
/*!
|
||||||
|
* \brief Processes the work on the data while working with textures
|
||||||
|
* \return true
|
||||||
|
*
|
||||||
|
* \param sceneData Data for the scene
|
||||||
|
* \param firstWorkTexture Index of the first texture to work with
|
||||||
|
* \param firstWorkTexture Index of the second texture to work with
|
||||||
|
*/
|
||||||
|
|
||||||
|
bool DeferredFogPass::Process( const SceneData& sceneData, unsigned int firstWorkTexture, unsigned int secondWorkTexture) const
|
||||||
{
|
{
|
||||||
NazaraAssert(sceneData.viewer, "Invalid viewer");
|
NazaraAssert(sceneData.viewer, "Invalid viewer");
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -13,9 +13,21 @@
|
||||||
|
|
||||||
namespace Nz
|
namespace Nz
|
||||||
{
|
{
|
||||||
|
/*!
|
||||||
|
* \ingroup graphics
|
||||||
|
* \class Nz::DeferredForwardPass
|
||||||
|
* \brief Graphics class that represents the forward pass in deferred rendering
|
||||||
|
*/
|
||||||
|
|
||||||
DeferredForwardPass::DeferredForwardPass() = default;
|
DeferredForwardPass::DeferredForwardPass() = default;
|
||||||
DeferredForwardPass::~DeferredForwardPass() = default;
|
DeferredForwardPass::~DeferredForwardPass() = default;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Initializes the deferred forward pass which needs the forward technique
|
||||||
|
*
|
||||||
|
* \param technique Rendering technique
|
||||||
|
*/
|
||||||
|
|
||||||
void DeferredForwardPass::Initialize(DeferredRenderTechnique* technique)
|
void DeferredForwardPass::Initialize(DeferredRenderTechnique* technique)
|
||||||
{
|
{
|
||||||
DeferredRenderPass::Initialize(technique);
|
DeferredRenderPass::Initialize(technique);
|
||||||
|
|
@ -23,7 +35,16 @@ namespace Nz
|
||||||
m_forwardTechnique = technique->GetForwardTechnique();
|
m_forwardTechnique = technique->GetForwardTechnique();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DeferredForwardPass::Process(const SceneData& sceneData, unsigned int workTexture, unsigned sceneTexture) const
|
/*!
|
||||||
|
* \brief Processes the work on the data while working with textures
|
||||||
|
* \return true
|
||||||
|
*
|
||||||
|
* \param sceneData Data for the scene
|
||||||
|
* \param firstWorkTexture Index of the first texture to work with
|
||||||
|
* \param firstWorkTexture Index of the second texture to work with
|
||||||
|
*/
|
||||||
|
|
||||||
|
bool DeferredForwardPass::Process(const SceneData& sceneData, unsigned int workTexture, unsigned int sceneTexture) const
|
||||||
{
|
{
|
||||||
NazaraAssert(sceneData.viewer, "Invalid viewer");
|
NazaraAssert(sceneData.viewer, "Invalid viewer");
|
||||||
NazaraUnused(workTexture);
|
NazaraUnused(workTexture);
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,16 @@
|
||||||
|
|
||||||
namespace Nz
|
namespace Nz
|
||||||
{
|
{
|
||||||
|
/*!
|
||||||
|
* \ingroup graphics
|
||||||
|
* \class Nz::DeferredGeometryPass
|
||||||
|
* \brief Graphics class that represents the pass for geometries in deferred rendering
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Constructs a DeferredGeometryPass object by default
|
||||||
|
*/
|
||||||
|
|
||||||
DeferredGeometryPass::DeferredGeometryPass()
|
DeferredGeometryPass::DeferredGeometryPass()
|
||||||
{
|
{
|
||||||
m_clearShader = ShaderLibrary::Get("DeferredGBufferClear");
|
m_clearShader = ShaderLibrary::Get("DeferredGBufferClear");
|
||||||
|
|
@ -31,7 +41,16 @@ namespace Nz
|
||||||
|
|
||||||
DeferredGeometryPass::~DeferredGeometryPass() = default;
|
DeferredGeometryPass::~DeferredGeometryPass() = default;
|
||||||
|
|
||||||
bool DeferredGeometryPass::Process(const SceneData& sceneData, unsigned int firstWorkTexture, unsigned secondWorkTexture) const
|
/*!
|
||||||
|
* \brief Processes the work on the data while working with textures
|
||||||
|
* \return false
|
||||||
|
*
|
||||||
|
* \param sceneData Data for the scene
|
||||||
|
* \param firstWorkTexture Index of the first texture to work with
|
||||||
|
* \param firstWorkTexture Index of the second texture to work with
|
||||||
|
*/
|
||||||
|
|
||||||
|
bool DeferredGeometryPass::Process(const SceneData& sceneData, unsigned int firstWorkTexture, unsigned int secondWorkTexture) const
|
||||||
{
|
{
|
||||||
NazaraAssert(sceneData.viewer, "Invalid viewer");
|
NazaraAssert(sceneData.viewer, "Invalid viewer");
|
||||||
NazaraUnused(firstWorkTexture);
|
NazaraUnused(firstWorkTexture);
|
||||||
|
|
@ -72,22 +91,22 @@ namespace Nz
|
||||||
|
|
||||||
bool useInstancing = instancingEnabled && matEntry.instancingEnabled;
|
bool useInstancing = instancingEnabled && matEntry.instancingEnabled;
|
||||||
|
|
||||||
// On commence par récupérer le programme du matériau
|
// We begin by getting the program for materials
|
||||||
UInt32 flags = ShaderFlags_Deferred;
|
UInt32 flags = ShaderFlags_Deferred;
|
||||||
if (useInstancing)
|
if (useInstancing)
|
||||||
flags |= ShaderFlags_Instancing;
|
flags |= ShaderFlags_Instancing;
|
||||||
|
|
||||||
const Shader* shader = material->Apply(flags);
|
const Shader* shader = material->Apply(flags);
|
||||||
|
|
||||||
// Les uniformes sont conservées au sein d'un programme, inutile de les renvoyer tant qu'il ne change pas
|
// The uniforms are conserved in our program, there's no point to send them back if they don't change
|
||||||
if (shader != lastShader)
|
if (shader != lastShader)
|
||||||
{
|
{
|
||||||
// Index des uniformes dans le shader
|
// Index of uniforms in the shader
|
||||||
shaderUniforms = GetShaderUniforms(shader);
|
shaderUniforms = GetShaderUniforms(shader);
|
||||||
|
|
||||||
// Couleur ambiante de la scène
|
// Ambient color for the scene
|
||||||
shader->SendColor(shaderUniforms->sceneAmbient, sceneData.ambientColor);
|
shader->SendColor(shaderUniforms->sceneAmbient, sceneData.ambientColor);
|
||||||
// Position de la caméra
|
// Position of the camera
|
||||||
shader->SendVector(shaderUniforms->eyePosition, sceneData.viewer->GetEyePosition());
|
shader->SendVector(shaderUniforms->eyePosition, sceneData.viewer->GetEyePosition());
|
||||||
|
|
||||||
lastShader = shader;
|
lastShader = shader;
|
||||||
|
|
@ -105,7 +124,7 @@ namespace Nz
|
||||||
const IndexBuffer* indexBuffer = meshData.indexBuffer;
|
const IndexBuffer* indexBuffer = meshData.indexBuffer;
|
||||||
const VertexBuffer* vertexBuffer = meshData.vertexBuffer;
|
const VertexBuffer* vertexBuffer = meshData.vertexBuffer;
|
||||||
|
|
||||||
// Gestion du draw call avant la boucle de rendu
|
// Handle draw call before rendering loop
|
||||||
Renderer::DrawCall drawFunc;
|
Renderer::DrawCall drawFunc;
|
||||||
Renderer::DrawCallInstanced instancedDrawFunc;
|
Renderer::DrawCallInstanced instancedDrawFunc;
|
||||||
unsigned int indexCount;
|
unsigned int indexCount;
|
||||||
|
|
@ -128,33 +147,33 @@ namespace Nz
|
||||||
|
|
||||||
if (useInstancing)
|
if (useInstancing)
|
||||||
{
|
{
|
||||||
// On récupère le buffer d'instancing du Renderer et on le configure pour fonctionner avec des matrices
|
// We get the buffer for instance of Renderer and we configure it to work with matrices
|
||||||
VertexBuffer* instanceBuffer = Renderer::GetInstanceBuffer();
|
VertexBuffer* instanceBuffer = Renderer::GetInstanceBuffer();
|
||||||
instanceBuffer->SetVertexDeclaration(VertexDeclaration::Get(VertexLayout_Matrix4));
|
instanceBuffer->SetVertexDeclaration(VertexDeclaration::Get(VertexLayout_Matrix4));
|
||||||
|
|
||||||
const Matrix4f* instanceMatrices = &instances[0];
|
const Matrix4f* instanceMatrices = &instances[0];
|
||||||
unsigned int instanceCount = instances.size();
|
unsigned int instanceCount = instances.size();
|
||||||
unsigned int maxInstanceCount = instanceBuffer->GetVertexCount(); // Le nombre de matrices que peut contenir le buffer
|
unsigned int maxInstanceCount = instanceBuffer->GetVertexCount(); // The number of matrices that can be hold in the buffer
|
||||||
|
|
||||||
while (instanceCount > 0)
|
while (instanceCount > 0)
|
||||||
{
|
{
|
||||||
// On calcule le nombre d'instances que l'on pourra afficher cette fois-ci (Selon la taille du buffer d'instancing)
|
// We compute the number of instances that we will be able to show this time (Depending on the instance buffer size)
|
||||||
unsigned int renderedInstanceCount = std::min(instanceCount, maxInstanceCount);
|
unsigned int renderedInstanceCount = std::min(instanceCount, maxInstanceCount);
|
||||||
instanceCount -= renderedInstanceCount;
|
instanceCount -= renderedInstanceCount;
|
||||||
|
|
||||||
// On remplit l'instancing buffer avec nos matrices world
|
// We fill the instancing buffer with our world matrices
|
||||||
instanceBuffer->Fill(instanceMatrices, 0, renderedInstanceCount, true);
|
instanceBuffer->Fill(instanceMatrices, 0, renderedInstanceCount, true);
|
||||||
instanceMatrices += renderedInstanceCount;
|
instanceMatrices += renderedInstanceCount;
|
||||||
|
|
||||||
// Et on affiche
|
// And we show
|
||||||
instancedDrawFunc(renderedInstanceCount, meshData.primitiveMode, 0, indexCount);
|
instancedDrawFunc(renderedInstanceCount, meshData.primitiveMode, 0, indexCount);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Sans instancing, on doit effectuer un draw call pour chaque instance
|
// Without instancing, we must do one draw call for each instance
|
||||||
// Cela reste néanmoins plus rapide que l'instancing en dessous d'un certain nombre d'instances
|
// This may be faster than instancing under a threshold
|
||||||
// À cause du temps de modification du buffer d'instancing
|
// Due to the time to modify the instancing buffer
|
||||||
for (const Matrix4f& matrix : instances)
|
for (const Matrix4f& matrix : instances)
|
||||||
{
|
{
|
||||||
Renderer::SetMatrix(MatrixType_World, matrix);
|
Renderer::SetMatrix(MatrixType_World, matrix);
|
||||||
|
|
@ -167,16 +186,23 @@ namespace Nz
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Et on remet à zéro les données
|
// Abd we set it back data to zero
|
||||||
matEntry.enabled = false;
|
matEntry.enabled = false;
|
||||||
matEntry.instancingEnabled = false;
|
matEntry.instancingEnabled = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return false; // On ne fait que remplir le G-Buffer, les work texture ne sont pas affectées
|
return false; // We only fill the G-Buffer, the work texture are unchanged
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Resizes the texture sizes
|
||||||
|
* \return true If successful
|
||||||
|
*
|
||||||
|
* \param dimensions Dimensions for the compute texture
|
||||||
|
*/
|
||||||
|
|
||||||
bool DeferredGeometryPass::Resize(const Vector2ui& dimensions)
|
bool DeferredGeometryPass::Resize(const Vector2ui& dimensions)
|
||||||
{
|
{
|
||||||
DeferredRenderPass::Resize(dimensions);
|
DeferredRenderPass::Resize(dimensions);
|
||||||
|
|
@ -241,6 +267,13 @@ namespace Nz
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Gets the uniforms of a shader
|
||||||
|
* \return Uniforms of the shader
|
||||||
|
*
|
||||||
|
* \param shader Shader to get uniforms from
|
||||||
|
*/
|
||||||
|
|
||||||
const DeferredGeometryPass::ShaderUniforms* DeferredGeometryPass::GetShaderUniforms(const Shader* shader) const
|
const DeferredGeometryPass::ShaderUniforms* DeferredGeometryPass::GetShaderUniforms(const Shader* shader) const
|
||||||
{
|
{
|
||||||
auto it = m_shaderUniforms.find(shader);
|
auto it = m_shaderUniforms.find(shader);
|
||||||
|
|
@ -260,6 +293,12 @@ namespace Nz
|
||||||
return &it->second;
|
return &it->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Handle the invalidation of a shader
|
||||||
|
*
|
||||||
|
* \param shader Shader being invalidated
|
||||||
|
*/
|
||||||
|
|
||||||
void DeferredGeometryPass::OnShaderInvalidated(const Shader* shader) const
|
void DeferredGeometryPass::OnShaderInvalidated(const Shader* shader) const
|
||||||
{
|
{
|
||||||
m_shaderUniforms.erase(shader);
|
m_shaderUniforms.erase(shader);
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,16 @@
|
||||||
|
|
||||||
namespace Nz
|
namespace Nz
|
||||||
{
|
{
|
||||||
|
/*!
|
||||||
|
* \ingroup graphics
|
||||||
|
* \class Nz::DeferredPhongLightingPass
|
||||||
|
* \brief Graphics class that represents the pass for phong lighting in deferred rendering
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Constructs a DeferredPhongLightingPass object by default
|
||||||
|
*/
|
||||||
|
|
||||||
DeferredPhongLightingPass::DeferredPhongLightingPass() :
|
DeferredPhongLightingPass::DeferredPhongLightingPass() :
|
||||||
m_lightMeshesDrawing(false)
|
m_lightMeshesDrawing(false)
|
||||||
{
|
{
|
||||||
|
|
@ -21,7 +31,7 @@ namespace Nz
|
||||||
m_directionalLightShaderSceneAmbientLocation = m_directionalLightShader->GetUniformLocation("SceneAmbient");
|
m_directionalLightShaderSceneAmbientLocation = m_directionalLightShader->GetUniformLocation("SceneAmbient");
|
||||||
|
|
||||||
m_directionalLightUniforms.ubo = false;
|
m_directionalLightUniforms.ubo = false;
|
||||||
m_directionalLightUniforms.locations.type = -1; // Type déjà connu
|
m_directionalLightUniforms.locations.type = -1; // Type already known
|
||||||
m_directionalLightUniforms.locations.color = m_directionalLightShader->GetUniformLocation("LightColor");
|
m_directionalLightUniforms.locations.color = m_directionalLightShader->GetUniformLocation("LightColor");
|
||||||
m_directionalLightUniforms.locations.factors = m_directionalLightShader->GetUniformLocation("LightFactors");
|
m_directionalLightUniforms.locations.factors = m_directionalLightShader->GetUniformLocation("LightFactors");
|
||||||
m_directionalLightUniforms.locations.parameters1 = m_directionalLightShader->GetUniformLocation("LightDirection");
|
m_directionalLightUniforms.locations.parameters1 = m_directionalLightShader->GetUniformLocation("LightDirection");
|
||||||
|
|
@ -56,16 +66,36 @@ namespace Nz
|
||||||
|
|
||||||
DeferredPhongLightingPass::~DeferredPhongLightingPass() = default;
|
DeferredPhongLightingPass::~DeferredPhongLightingPass() = default;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Enables the drawing of meshes with light
|
||||||
|
*
|
||||||
|
* \param enable Should meshes with light parameter be drawed
|
||||||
|
*/
|
||||||
|
|
||||||
void DeferredPhongLightingPass::EnableLightMeshesDrawing(bool enable)
|
void DeferredPhongLightingPass::EnableLightMeshesDrawing(bool enable)
|
||||||
{
|
{
|
||||||
m_lightMeshesDrawing = enable;
|
m_lightMeshesDrawing = enable;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Checks whether the drawing of meshes with light is enabled
|
||||||
|
* \return true If it is the case
|
||||||
|
*/
|
||||||
|
|
||||||
bool DeferredPhongLightingPass::IsLightMeshesDrawingEnabled() const
|
bool DeferredPhongLightingPass::IsLightMeshesDrawingEnabled() const
|
||||||
{
|
{
|
||||||
return m_lightMeshesDrawing;
|
return m_lightMeshesDrawing;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Processes the work on the data while working with textures
|
||||||
|
* \return true
|
||||||
|
*
|
||||||
|
* \param sceneData Data for the scene
|
||||||
|
* \param firstWorkTexture Index of the first texture to work with
|
||||||
|
* \param firstWorkTexture Index of the second texture to work with
|
||||||
|
*/
|
||||||
|
|
||||||
bool DeferredPhongLightingPass::Process(const SceneData& sceneData, unsigned int firstWorkTexture, unsigned secondWorkTexture) const
|
bool DeferredPhongLightingPass::Process(const SceneData& sceneData, unsigned int firstWorkTexture, unsigned secondWorkTexture) const
|
||||||
{
|
{
|
||||||
NazaraAssert(sceneData.viewer, "Invalid viewer");
|
NazaraAssert(sceneData.viewer, "Invalid viewer");
|
||||||
|
|
@ -151,12 +181,12 @@ namespace Nz
|
||||||
m_pointSpotLightShader->SendVector(m_pointSpotLightUniforms.locations.parameters1, Vector4f(light.position, light.attenuation));
|
m_pointSpotLightShader->SendVector(m_pointSpotLightUniforms.locations.parameters1, Vector4f(light.position, light.attenuation));
|
||||||
m_pointSpotLightShader->SendVector(m_pointSpotLightUniforms.locations.parameters2, Vector4f(0.f, 0.f, 0.f, light.invRadius));
|
m_pointSpotLightShader->SendVector(m_pointSpotLightUniforms.locations.parameters2, Vector4f(0.f, 0.f, 0.f, light.invRadius));
|
||||||
|
|
||||||
lightMatrix.SetScale(Vector3f(light.radius * 1.1f)); // Pour corriger les imperfections liées à la sphère
|
lightMatrix.SetScale(Vector3f(light.radius * 1.1f)); // To correct imperfections due to the sphere
|
||||||
lightMatrix.SetTranslation(light.position);
|
lightMatrix.SetTranslation(light.position);
|
||||||
|
|
||||||
Renderer::SetMatrix(MatrixType_World, lightMatrix);
|
Renderer::SetMatrix(MatrixType_World, lightMatrix);
|
||||||
|
|
||||||
// Rendu de la sphère dans le stencil buffer
|
// Sphere rendering in the stencil buffer
|
||||||
Renderer::Enable(RendererParameter_ColorWrite, false);
|
Renderer::Enable(RendererParameter_ColorWrite, false);
|
||||||
Renderer::Enable(RendererParameter_DepthBuffer, true);
|
Renderer::Enable(RendererParameter_DepthBuffer, true);
|
||||||
Renderer::Enable(RendererParameter_FaceCulling, false);
|
Renderer::Enable(RendererParameter_FaceCulling, false);
|
||||||
|
|
@ -166,7 +196,7 @@ namespace Nz
|
||||||
|
|
||||||
Renderer::DrawIndexedPrimitives(PrimitiveMode_TriangleList, 0, indexBuffer->GetIndexCount());
|
Renderer::DrawIndexedPrimitives(PrimitiveMode_TriangleList, 0, indexBuffer->GetIndexCount());
|
||||||
|
|
||||||
// Rendu de la sphère comme zone d'effet
|
// Sphere rendering as effect zone
|
||||||
Renderer::Enable(RendererParameter_ColorWrite, true);
|
Renderer::Enable(RendererParameter_ColorWrite, true);
|
||||||
Renderer::Enable(RendererParameter_DepthBuffer, false);
|
Renderer::Enable(RendererParameter_DepthBuffer, false);
|
||||||
Renderer::Enable(RendererParameter_FaceCulling, true);
|
Renderer::Enable(RendererParameter_FaceCulling, true);
|
||||||
|
|
@ -192,7 +222,7 @@ namespace Nz
|
||||||
Renderer::SetShader(shader);
|
Renderer::SetShader(shader);
|
||||||
for (const auto& light : m_renderQueue->pointLights)
|
for (const auto& light : m_renderQueue->pointLights)
|
||||||
{
|
{
|
||||||
lightMatrix.SetScale(Vector3f(light.radius * 1.1f)); // Pour corriger les imperfections liées à la sphère
|
lightMatrix.SetScale(Vector3f(light.radius * 1.1f)); // To correct imperfections due to the sphere
|
||||||
lightMatrix.SetTranslation(light.position);
|
lightMatrix.SetTranslation(light.position);
|
||||||
|
|
||||||
Renderer::SetMatrix(MatrixType_World, lightMatrix);
|
Renderer::SetMatrix(MatrixType_World, lightMatrix);
|
||||||
|
|
@ -230,7 +260,7 @@ namespace Nz
|
||||||
|
|
||||||
Renderer::SetMatrix(MatrixType_World, lightMatrix);
|
Renderer::SetMatrix(MatrixType_World, lightMatrix);
|
||||||
|
|
||||||
// Rendu de la sphère dans le stencil buffer
|
// Sphere rendering in the stencil buffer
|
||||||
Renderer::Enable(RendererParameter_ColorWrite, false);
|
Renderer::Enable(RendererParameter_ColorWrite, false);
|
||||||
Renderer::Enable(RendererParameter_DepthBuffer, true);
|
Renderer::Enable(RendererParameter_DepthBuffer, true);
|
||||||
Renderer::Enable(RendererParameter_FaceCulling, false);
|
Renderer::Enable(RendererParameter_FaceCulling, false);
|
||||||
|
|
@ -240,7 +270,7 @@ namespace Nz
|
||||||
|
|
||||||
Renderer::DrawIndexedPrimitives(PrimitiveMode_TriangleList, 0, indexBuffer->GetIndexCount());
|
Renderer::DrawIndexedPrimitives(PrimitiveMode_TriangleList, 0, indexBuffer->GetIndexCount());
|
||||||
|
|
||||||
// Rendu de la sphère comme zone d'effet
|
// Sphere rendering as effect zone
|
||||||
Renderer::Enable(RendererParameter_ColorWrite, true);
|
Renderer::Enable(RendererParameter_ColorWrite, true);
|
||||||
Renderer::Enable(RendererParameter_DepthBuffer, false);
|
Renderer::Enable(RendererParameter_DepthBuffer, false);
|
||||||
Renderer::Enable(RendererParameter_FaceCulling, true);
|
Renderer::Enable(RendererParameter_FaceCulling, true);
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,16 @@
|
||||||
|
|
||||||
namespace Nz
|
namespace Nz
|
||||||
{
|
{
|
||||||
|
/*!
|
||||||
|
* \ingroup graphics
|
||||||
|
* \class Nz::DeferredRenderPass
|
||||||
|
* \brief Graphics class that represents the pass for rendering in deferred rendering
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Constructs a DeferredRenderPass object by default
|
||||||
|
*/
|
||||||
|
|
||||||
DeferredRenderPass::DeferredRenderPass() :
|
DeferredRenderPass::DeferredRenderPass() :
|
||||||
m_enabled(true)
|
m_enabled(true)
|
||||||
{
|
{
|
||||||
|
|
@ -16,11 +26,23 @@ namespace Nz
|
||||||
|
|
||||||
DeferredRenderPass::~DeferredRenderPass() = default;
|
DeferredRenderPass::~DeferredRenderPass() = default;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Enables the deferred rendering
|
||||||
|
*
|
||||||
|
* \param enable Should deferred rendering be activated
|
||||||
|
*/
|
||||||
|
|
||||||
void DeferredRenderPass::Enable(bool enable)
|
void DeferredRenderPass::Enable(bool enable)
|
||||||
{
|
{
|
||||||
m_enabled = enable;
|
m_enabled = enable;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Initializes the deferred forward pass which needs the deferred technique
|
||||||
|
*
|
||||||
|
* \param technique Rendering technique
|
||||||
|
*/
|
||||||
|
|
||||||
void DeferredRenderPass::Initialize(DeferredRenderTechnique* technique)
|
void DeferredRenderPass::Initialize(DeferredRenderTechnique* technique)
|
||||||
{
|
{
|
||||||
m_deferredTechnique = technique;
|
m_deferredTechnique = technique;
|
||||||
|
|
@ -37,11 +59,23 @@ namespace Nz
|
||||||
m_workTextures[i] = technique->GetWorkTexture(i);
|
m_workTextures[i] = technique->GetWorkTexture(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Checks whether the deferred rendering is enabled
|
||||||
|
* \return true If it the case
|
||||||
|
*/
|
||||||
|
|
||||||
bool DeferredRenderPass::IsEnabled() const
|
bool DeferredRenderPass::IsEnabled() const
|
||||||
{
|
{
|
||||||
return m_enabled;
|
return m_enabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Resizes the texture sizes
|
||||||
|
* \return true If successful
|
||||||
|
*
|
||||||
|
* \param dimensions Dimensions for the compute texture
|
||||||
|
*/
|
||||||
|
|
||||||
bool DeferredRenderPass::Resize(const Vector2ui& dimensions)
|
bool DeferredRenderPass::Resize(const Vector2ui& dimensions)
|
||||||
{
|
{
|
||||||
m_dimensions = dimensions;
|
m_dimensions = dimensions;
|
||||||
|
|
|
||||||
|
|
@ -8,69 +8,207 @@
|
||||||
#include <Nazara/Graphics/Light.hpp>
|
#include <Nazara/Graphics/Light.hpp>
|
||||||
#include <Nazara/Graphics/Debug.hpp>
|
#include <Nazara/Graphics/Debug.hpp>
|
||||||
|
|
||||||
///TODO: Rendre les billboards via Deferred Shading si possible
|
///TODO: Render billboards using Deferred Shading if possible
|
||||||
|
|
||||||
namespace Nz
|
namespace Nz
|
||||||
{
|
{
|
||||||
|
/*!
|
||||||
|
* \ingroup graphics
|
||||||
|
* \class Nz::DeferredRenderQueue
|
||||||
|
* \brief Graphics class that represents the rendering queue for deferred rendering
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Constructs a DeferredRenderQueue object with the rendering queue of forward rendering
|
||||||
|
*
|
||||||
|
* \param forwardQueue Queue of data to render
|
||||||
|
*/
|
||||||
|
|
||||||
DeferredRenderQueue::DeferredRenderQueue(ForwardRenderQueue* forwardQueue) :
|
DeferredRenderQueue::DeferredRenderQueue(ForwardRenderQueue* forwardQueue) :
|
||||||
m_forwardQueue(forwardQueue)
|
m_forwardQueue(forwardQueue)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Adds billboard to the queue
|
||||||
|
*
|
||||||
|
* \param renderOrder Order of rendering
|
||||||
|
* \param material Material of the billboard
|
||||||
|
* \param position Position of the billboard
|
||||||
|
* \param size Sizes of the billboard
|
||||||
|
* \param sinCos Rotation of the billboard
|
||||||
|
* \param color Color of the billboard
|
||||||
|
*/
|
||||||
|
|
||||||
void DeferredRenderQueue::AddBillboard(int renderOrder, const Material* material, const Vector3f& position, const Vector2f& size, const Vector2f& sinCos, const Color& color)
|
void DeferredRenderQueue::AddBillboard(int renderOrder, const Material* material, const Vector3f& position, const Vector2f& size, const Vector2f& sinCos, const Color& color)
|
||||||
{
|
{
|
||||||
m_forwardQueue->AddBillboard(renderOrder, material, position, size, sinCos, color);
|
m_forwardQueue->AddBillboard(renderOrder, material, position, size, sinCos, color);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Adds multiple billboards to the queue
|
||||||
|
*
|
||||||
|
* \param renderOrder Order of rendering
|
||||||
|
* \param material Material of the billboards
|
||||||
|
* \param count Number of billboards
|
||||||
|
* \param positionPtr Position of the billboards
|
||||||
|
* \param sizePtr Sizes of the billboards
|
||||||
|
* \param sinCosPtr Rotation of the billboards if null, Vector2f(0.f, 1.f) is used
|
||||||
|
* \param colorPtr Color of the billboards if null, Color::White is used
|
||||||
|
*/
|
||||||
|
|
||||||
void DeferredRenderQueue::AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr<const Vector3f> positionPtr, SparsePtr<const Vector2f> sizePtr, SparsePtr<const Vector2f> sinCosPtr, SparsePtr<const Color> colorPtr)
|
void DeferredRenderQueue::AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr<const Vector3f> positionPtr, SparsePtr<const Vector2f> sizePtr, SparsePtr<const Vector2f> sinCosPtr, SparsePtr<const Color> colorPtr)
|
||||||
{
|
{
|
||||||
m_forwardQueue->AddBillboards(renderOrder, material, count, positionPtr, sizePtr, sinCosPtr, colorPtr);
|
m_forwardQueue->AddBillboards(renderOrder, material, count, positionPtr, sizePtr, sinCosPtr, colorPtr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Adds multiple billboards to the queue
|
||||||
|
*
|
||||||
|
* \param renderOrder Order of rendering
|
||||||
|
* \param material Material of the billboards
|
||||||
|
* \param count Number of billboards
|
||||||
|
* \param positionPtr Position of the billboards
|
||||||
|
* \param sizePtr Sizes of the billboards
|
||||||
|
* \param sinCosPtr Rotation of the billboards if null, Vector2f(0.f, 1.f) is used
|
||||||
|
* \param alphaPtr Alpha parameters of the billboards if null, 1.f is used
|
||||||
|
*/
|
||||||
|
|
||||||
void DeferredRenderQueue::AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr<const Vector3f> positionPtr, SparsePtr<const Vector2f> sizePtr, SparsePtr<const Vector2f> sinCosPtr, SparsePtr<const float> alphaPtr)
|
void DeferredRenderQueue::AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr<const Vector3f> positionPtr, SparsePtr<const Vector2f> sizePtr, SparsePtr<const Vector2f> sinCosPtr, SparsePtr<const float> alphaPtr)
|
||||||
{
|
{
|
||||||
m_forwardQueue->AddBillboards(renderOrder, material, count, positionPtr, sizePtr, sinCosPtr, alphaPtr);
|
m_forwardQueue->AddBillboards(renderOrder, material, count, positionPtr, sizePtr, sinCosPtr, alphaPtr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Adds multiple billboards to the queue
|
||||||
|
*
|
||||||
|
* \param renderOrder Order of rendering
|
||||||
|
* \param material Material of the billboards
|
||||||
|
* \param count Number of billboards
|
||||||
|
* \param positionPtr Position of the billboards
|
||||||
|
* \param sizePtr Sizes of the billboards
|
||||||
|
* \param anglePtr Rotation of the billboards if null, 0.f is used
|
||||||
|
* \param colorPtr Color of the billboards if null, Color::White is used
|
||||||
|
*/
|
||||||
|
|
||||||
void DeferredRenderQueue::AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr<const Vector3f> positionPtr, SparsePtr<const Vector2f> sizePtr, SparsePtr<const float> anglePtr, SparsePtr<const Color> colorPtr)
|
void DeferredRenderQueue::AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr<const Vector3f> positionPtr, SparsePtr<const Vector2f> sizePtr, SparsePtr<const float> anglePtr, SparsePtr<const Color> colorPtr)
|
||||||
{
|
{
|
||||||
m_forwardQueue->AddBillboards(renderOrder, material, count, positionPtr, sizePtr, anglePtr, colorPtr);
|
m_forwardQueue->AddBillboards(renderOrder, material, count, positionPtr, sizePtr, anglePtr, colorPtr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Adds multiple billboards to the queue
|
||||||
|
*
|
||||||
|
* \param renderOrder Order of rendering
|
||||||
|
* \param material Material of the billboards
|
||||||
|
* \param count Number of billboards
|
||||||
|
* \param positionPtr Position of the billboards
|
||||||
|
* \param sizePtr Sizes of the billboards
|
||||||
|
* \param anglePtr Rotation of the billboards if null, 0.f is used
|
||||||
|
* \param alphaPtr Alpha parameters of the billboards if null, 1.f is used
|
||||||
|
*/
|
||||||
|
|
||||||
void DeferredRenderQueue::AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr<const Vector3f> positionPtr, SparsePtr<const Vector2f> sizePtr, SparsePtr<const float> anglePtr, SparsePtr<const float> alphaPtr)
|
void DeferredRenderQueue::AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr<const Vector3f> positionPtr, SparsePtr<const Vector2f> sizePtr, SparsePtr<const float> anglePtr, SparsePtr<const float> alphaPtr)
|
||||||
{
|
{
|
||||||
m_forwardQueue->AddBillboards(renderOrder, material, count, positionPtr, sizePtr, anglePtr, alphaPtr);
|
m_forwardQueue->AddBillboards(renderOrder, material, count, positionPtr, sizePtr, anglePtr, alphaPtr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Adds multiple billboards to the queue
|
||||||
|
*
|
||||||
|
* \param renderOrder Order of rendering
|
||||||
|
* \param material Material of the billboards
|
||||||
|
* \param count Number of billboards
|
||||||
|
* \param positionPtr Position of the billboards
|
||||||
|
* \param sizePtr Size of the billboards
|
||||||
|
* \param sinCosPtr Rotation of the billboards if null, Vector2f(0.f, 1.f) is used
|
||||||
|
* \param colorPtr Color of the billboards if null, Color::White is used
|
||||||
|
*/
|
||||||
|
|
||||||
void DeferredRenderQueue::AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr<const Vector3f> positionPtr, SparsePtr<const float> sizePtr, SparsePtr<const Vector2f> sinCosPtr, SparsePtr<const Color> colorPtr)
|
void DeferredRenderQueue::AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr<const Vector3f> positionPtr, SparsePtr<const float> sizePtr, SparsePtr<const Vector2f> sinCosPtr, SparsePtr<const Color> colorPtr)
|
||||||
{
|
{
|
||||||
m_forwardQueue->AddBillboards(renderOrder, material, count, positionPtr, sizePtr, sinCosPtr, colorPtr);
|
m_forwardQueue->AddBillboards(renderOrder, material, count, positionPtr, sizePtr, sinCosPtr, colorPtr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Adds multiple billboards to the queue
|
||||||
|
*
|
||||||
|
* \param renderOrder Order of rendering
|
||||||
|
* \param material Material of the billboards
|
||||||
|
* \param count Number of billboards
|
||||||
|
* \param positionPtr Position of the billboards
|
||||||
|
* \param sizePtr Size of the billboards
|
||||||
|
* \param sinCosPtr Rotation of the billboards if null, Vector2f(0.f, 1.f) is used
|
||||||
|
* \param alphaPtr Alpha parameters of the billboards if null, 1.f is used
|
||||||
|
*/
|
||||||
|
|
||||||
void DeferredRenderQueue::AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr<const Vector3f> positionPtr, SparsePtr<const float> sizePtr, SparsePtr<const Vector2f> sinCosPtr, SparsePtr<const float> alphaPtr)
|
void DeferredRenderQueue::AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr<const Vector3f> positionPtr, SparsePtr<const float> sizePtr, SparsePtr<const Vector2f> sinCosPtr, SparsePtr<const float> alphaPtr)
|
||||||
{
|
{
|
||||||
m_forwardQueue->AddBillboards(renderOrder, material, count, positionPtr, sizePtr, sinCosPtr, alphaPtr);
|
m_forwardQueue->AddBillboards(renderOrder, material, count, positionPtr, sizePtr, sinCosPtr, alphaPtr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Adds multiple billboards to the queue
|
||||||
|
*
|
||||||
|
* \param renderOrder Order of rendering
|
||||||
|
* \param material Material of the billboards
|
||||||
|
* \param count Number of billboards
|
||||||
|
* \param positionPtr Position of the billboards
|
||||||
|
* \param sizePtr Size of the billboards
|
||||||
|
* \param anglePtr Rotation of the billboards if null, 0.f is used
|
||||||
|
* \param colorPtr Color of the billboards if null, Color::White is used
|
||||||
|
*/
|
||||||
|
|
||||||
void DeferredRenderQueue::AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr<const Vector3f> positionPtr, SparsePtr<const float> sizePtr, SparsePtr<const float> anglePtr, SparsePtr<const Color> colorPtr)
|
void DeferredRenderQueue::AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr<const Vector3f> positionPtr, SparsePtr<const float> sizePtr, SparsePtr<const float> anglePtr, SparsePtr<const Color> colorPtr)
|
||||||
{
|
{
|
||||||
m_forwardQueue->AddBillboards(renderOrder, material, count, positionPtr, sizePtr, anglePtr, colorPtr);
|
m_forwardQueue->AddBillboards(renderOrder, material, count, positionPtr, sizePtr, anglePtr, colorPtr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Adds multiple billboards to the queue
|
||||||
|
*
|
||||||
|
* \param renderOrder Order of rendering
|
||||||
|
* \param material Material of the billboards
|
||||||
|
* \param count Number of billboards
|
||||||
|
* \param positionPtr Position of the billboards
|
||||||
|
* \param sizePtr Size of the billboards
|
||||||
|
* \param anglePtr Rotation of the billboards if null, 0.f is used
|
||||||
|
* \param alphaPtr Alpha parameters of the billboards if null, 1.f is used
|
||||||
|
*/
|
||||||
|
|
||||||
void DeferredRenderQueue::AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr<const Vector3f> positionPtr, SparsePtr<const float> sizePtr, SparsePtr<const float> anglePtr, SparsePtr<const float> alphaPtr)
|
void DeferredRenderQueue::AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr<const Vector3f> positionPtr, SparsePtr<const float> sizePtr, SparsePtr<const float> anglePtr, SparsePtr<const float> alphaPtr)
|
||||||
{
|
{
|
||||||
m_forwardQueue->AddBillboards(renderOrder, material, count, positionPtr, sizePtr, anglePtr, alphaPtr);
|
m_forwardQueue->AddBillboards(renderOrder, material, count, positionPtr, sizePtr, anglePtr, alphaPtr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Adds drawable to the queue
|
||||||
|
*
|
||||||
|
* \param renderOrder Order of rendering
|
||||||
|
* \param drawable Drawable user defined
|
||||||
|
*
|
||||||
|
* \remark Produces a NazaraError if drawable is invalid
|
||||||
|
*/
|
||||||
|
|
||||||
void DeferredRenderQueue::AddDrawable(int renderOrder, const Drawable* drawable)
|
void DeferredRenderQueue::AddDrawable(int renderOrder, const Drawable* drawable)
|
||||||
{
|
{
|
||||||
m_forwardQueue->AddDrawable(renderOrder, drawable);
|
m_forwardQueue->AddDrawable(renderOrder, drawable);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Adds mesh to the queue
|
||||||
|
*
|
||||||
|
* \param renderOrder Order of rendering
|
||||||
|
* \param material Material of the mesh
|
||||||
|
* \param meshData Data of the mesh
|
||||||
|
* \param meshAABB Box of the mesh
|
||||||
|
* \param transformMatrix Matrix of the mesh
|
||||||
|
*/
|
||||||
|
|
||||||
void DeferredRenderQueue::AddMesh(int renderOrder, const Material* material, const MeshData& meshData, const Boxf& meshAABB, const Matrix4f& transformMatrix)
|
void DeferredRenderQueue::AddMesh(int renderOrder, const Material* material, const MeshData& meshData, const Boxf& meshAABB, const Matrix4f& transformMatrix)
|
||||||
{
|
{
|
||||||
if (material->IsEnabled(RendererParameter_Blend))
|
if (material->IsEnabled(RendererParameter_Blend))
|
||||||
// Un matériau transparent ? J'aime pas, va voir dans la forward queue si j'y suis
|
// One transparent material ? I don't like it, go see if I'm in the forward queue
|
||||||
m_forwardQueue->AddMesh(renderOrder, material, meshData, meshAABB, transformMatrix);
|
m_forwardQueue->AddMesh(renderOrder, material, meshData, meshAABB, transformMatrix);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -103,21 +241,37 @@ namespace Nz
|
||||||
it2 = meshMap.insert(std::make_pair(meshData, std::move(instanceEntry))).first;
|
it2 = meshMap.insert(std::make_pair(meshData, std::move(instanceEntry))).first;
|
||||||
}
|
}
|
||||||
|
|
||||||
// On ajoute la matrice à la liste des instances de cet objet
|
// We add matrices to the list of instances of this object
|
||||||
std::vector<Matrix4f>& instances = it2->second.instances;
|
std::vector<Matrix4f>& instances = it2->second.instances;
|
||||||
instances.push_back(transformMatrix);
|
instances.push_back(transformMatrix);
|
||||||
|
|
||||||
// Avons-nous suffisamment d'instances pour que le coût d'utilisation de l'instancing soit payé ?
|
// Do we have enough instances to perform instancing ?
|
||||||
if (instances.size() >= NAZARA_GRAPHICS_INSTANCING_MIN_INSTANCES_COUNT)
|
if (instances.size() >= NAZARA_GRAPHICS_INSTANCING_MIN_INSTANCES_COUNT)
|
||||||
entry.instancingEnabled = true; // Apparemment oui, activons l'instancing avec ce matériau
|
entry.instancingEnabled = true; // Thus we can activate it
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Adds sprites to the queue
|
||||||
|
*
|
||||||
|
* \param renderOrder Order of rendering
|
||||||
|
* \param material Material of the sprites
|
||||||
|
* \param vertices Buffer of data for the sprites
|
||||||
|
* \param spriteCount Number of sprites
|
||||||
|
* \param overlay Texture of the sprites
|
||||||
|
*/
|
||||||
|
|
||||||
void DeferredRenderQueue::AddSprites(int renderOrder, const Material* material, const VertexStruct_XYZ_Color_UV* vertices, unsigned int spriteCount, const Texture* overlay)
|
void DeferredRenderQueue::AddSprites(int renderOrder, const Material* material, const VertexStruct_XYZ_Color_UV* vertices, unsigned int spriteCount, const Texture* overlay)
|
||||||
{
|
{
|
||||||
m_forwardQueue->AddSprites(renderOrder, material, vertices, spriteCount, overlay);
|
m_forwardQueue->AddSprites(renderOrder, material, vertices, spriteCount, overlay);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Clears the queue
|
||||||
|
*
|
||||||
|
* \param fully Should everything be cleared or we can keep layers
|
||||||
|
*/
|
||||||
|
|
||||||
void DeferredRenderQueue::Clear(bool fully)
|
void DeferredRenderQueue::Clear(bool fully)
|
||||||
{
|
{
|
||||||
AbstractRenderQueue::Clear(fully);
|
AbstractRenderQueue::Clear(fully);
|
||||||
|
|
@ -137,6 +291,13 @@ namespace Nz
|
||||||
m_forwardQueue->Clear(fully);
|
m_forwardQueue->Clear(fully);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Gets the ith layer
|
||||||
|
* \return Reference to the ith layer for the queue
|
||||||
|
*
|
||||||
|
* \param i Index of the layer
|
||||||
|
*/
|
||||||
|
|
||||||
DeferredRenderQueue::Layer& DeferredRenderQueue::GetLayer(unsigned int i)
|
DeferredRenderQueue::Layer& DeferredRenderQueue::GetLayer(unsigned int i)
|
||||||
{
|
{
|
||||||
auto it = layers.find(i);
|
auto it = layers.find(i);
|
||||||
|
|
@ -149,6 +310,12 @@ namespace Nz
|
||||||
return layer;
|
return layer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Handle the invalidation of an index buffer
|
||||||
|
*
|
||||||
|
* \param indexBuffer Index buffer being invalidated
|
||||||
|
*/
|
||||||
|
|
||||||
void DeferredRenderQueue::OnIndexBufferInvalidation(const IndexBuffer* indexBuffer)
|
void DeferredRenderQueue::OnIndexBufferInvalidation(const IndexBuffer* indexBuffer)
|
||||||
{
|
{
|
||||||
for (auto& pair : layers)
|
for (auto& pair : layers)
|
||||||
|
|
@ -170,6 +337,12 @@ namespace Nz
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Handle the invalidation of a material
|
||||||
|
*
|
||||||
|
* \param material Material being invalidated
|
||||||
|
*/
|
||||||
|
|
||||||
void DeferredRenderQueue::OnMaterialInvalidation(const Material* material)
|
void DeferredRenderQueue::OnMaterialInvalidation(const Material* material)
|
||||||
{
|
{
|
||||||
for (auto& pair : layers)
|
for (auto& pair : layers)
|
||||||
|
|
@ -180,6 +353,12 @@ namespace Nz
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Handle the invalidation of a vertex buffer
|
||||||
|
*
|
||||||
|
* \param vertexBuffer Vertex buffer being invalidated
|
||||||
|
*/
|
||||||
|
|
||||||
void DeferredRenderQueue::OnVertexBufferInvalidation(const VertexBuffer* vertexBuffer)
|
void DeferredRenderQueue::OnVertexBufferInvalidation(const VertexBuffer* vertexBuffer)
|
||||||
{
|
{
|
||||||
for (auto& pair : layers)
|
for (auto& pair : layers)
|
||||||
|
|
@ -201,6 +380,14 @@ namespace Nz
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Functor to compare two batched model with material
|
||||||
|
* \return true If first material is "smaller" than the second one
|
||||||
|
*
|
||||||
|
* \param mat1 First material to compare
|
||||||
|
* \param mat2 Second material to compare
|
||||||
|
*/
|
||||||
|
|
||||||
bool DeferredRenderQueue::BatchedModelMaterialComparator::operator()(const Material* mat1, const Material* mat2) const
|
bool DeferredRenderQueue::BatchedModelMaterialComparator::operator()(const Material* mat1, const Material* mat2) const
|
||||||
{
|
{
|
||||||
const UberShader* uberShader1 = mat1->GetShader();
|
const UberShader* uberShader1 = mat1->GetShader();
|
||||||
|
|
@ -221,6 +408,14 @@ namespace Nz
|
||||||
return mat1 < mat2;
|
return mat1 < mat2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Functor to compare two mesh data
|
||||||
|
* \return true If first mesh is "smaller" than the second one
|
||||||
|
*
|
||||||
|
* \param data1 First mesh to compare
|
||||||
|
* \param data2 Second mesh to compare
|
||||||
|
*/
|
||||||
|
|
||||||
bool DeferredRenderQueue::MeshDataComparator::operator()(const MeshData& data1, const MeshData& data2) const
|
bool DeferredRenderQueue::MeshDataComparator::operator()(const MeshData& data1, const MeshData& data2) const
|
||||||
{
|
{
|
||||||
const Buffer* buffer1;
|
const Buffer* buffer1;
|
||||||
|
|
|
||||||
|
|
@ -79,6 +79,17 @@ namespace Nz
|
||||||
|
|
||||||
static_assert(sizeof(RenderPassPriority) / sizeof(unsigned int) == RenderPassType_Max + 1, "Render pass priority array is incomplete");
|
static_assert(sizeof(RenderPassPriority) / sizeof(unsigned int) == RenderPassType_Max + 1, "Render pass priority array is incomplete");
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Registers the deferred shader
|
||||||
|
* \return Reference to the newly created shader
|
||||||
|
*
|
||||||
|
* \param name Name of the shader
|
||||||
|
* \param fragmentSource Raw data to fragment shader
|
||||||
|
* \param fragmentSourceLength Size of the fragment source
|
||||||
|
* \param vertexStage Stage of the shader
|
||||||
|
* \param err Pointer to string to contain error message
|
||||||
|
*/
|
||||||
|
|
||||||
inline ShaderRef RegisterDeferredShader(const String& name, const UInt8* fragmentSource, unsigned int fragmentSourceLength, const ShaderStage& vertexStage, String* err)
|
inline ShaderRef RegisterDeferredShader(const String& name, const UInt8* fragmentSource, unsigned int fragmentSourceLength, const ShaderStage& vertexStage, String* err)
|
||||||
{
|
{
|
||||||
ErrorFlags errFlags(ErrorFlag_Silent | ErrorFlag_ThrowExceptionDisabled);
|
ErrorFlags errFlags(ErrorFlag_Silent | ErrorFlag_ThrowExceptionDisabled);
|
||||||
|
|
@ -109,6 +120,18 @@ namespace Nz
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \ingroup graphics
|
||||||
|
* \class Nz::DeferredRenderTechnique
|
||||||
|
* \brief Graphics class that represents the technique used in deferred rendering
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Constructs a DeferredRenderTechnique object by default
|
||||||
|
*
|
||||||
|
* \remark Produces a NazaraError if one pass could not be created
|
||||||
|
*/
|
||||||
|
|
||||||
DeferredRenderTechnique::DeferredRenderTechnique() :
|
DeferredRenderTechnique::DeferredRenderTechnique() :
|
||||||
m_renderQueue(static_cast<ForwardRenderQueue*>(m_forwardTechnique.GetRenderQueue())),
|
m_renderQueue(static_cast<ForwardRenderQueue*>(m_forwardTechnique.GetRenderQueue())),
|
||||||
m_GBufferSize(0U)
|
m_GBufferSize(0U)
|
||||||
|
|
@ -204,11 +227,27 @@ namespace Nz
|
||||||
|
|
||||||
DeferredRenderTechnique::~DeferredRenderTechnique() = default;
|
DeferredRenderTechnique::~DeferredRenderTechnique() = default;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Clears the data
|
||||||
|
*
|
||||||
|
* \param sceneData Data of the scene
|
||||||
|
*/
|
||||||
|
|
||||||
void DeferredRenderTechnique::Clear(const SceneData& sceneData) const
|
void DeferredRenderTechnique::Clear(const SceneData& sceneData) const
|
||||||
{
|
{
|
||||||
NazaraUnused(sceneData);
|
NazaraUnused(sceneData);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Draws the data of the scene
|
||||||
|
* \return true If successful
|
||||||
|
*
|
||||||
|
* \param sceneData Data of the scene
|
||||||
|
*
|
||||||
|
* \remark Produces a NazaraAssert if viewer of the scene is invalid
|
||||||
|
* \remark Produces a NazaraError if updating viewport dimensions failed
|
||||||
|
*/
|
||||||
|
|
||||||
bool DeferredRenderTechnique::Draw(const SceneData& sceneData) const
|
bool DeferredRenderTechnique::Draw(const SceneData& sceneData) const
|
||||||
{
|
{
|
||||||
NazaraAssert(sceneData.viewer, "Invalid viewer");
|
NazaraAssert(sceneData.viewer, "Invalid viewer");
|
||||||
|
|
@ -242,6 +281,14 @@ namespace Nz
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Enables a pass
|
||||||
|
*
|
||||||
|
* \param renderPass Enumeration for the pass
|
||||||
|
* \param position Position of the pass
|
||||||
|
* \param enable Should the pass be enabled
|
||||||
|
*/
|
||||||
|
|
||||||
void DeferredRenderTechnique::EnablePass(RenderPassType renderPass, int position, bool enable)
|
void DeferredRenderTechnique::EnablePass(RenderPassType renderPass, int position, bool enable)
|
||||||
{
|
{
|
||||||
auto it = m_passes.find(renderPass);
|
auto it = m_passes.find(renderPass);
|
||||||
|
|
@ -253,11 +300,25 @@ namespace Nz
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Gets the stencil buffer
|
||||||
|
* \return Pointer to the rendering buffer
|
||||||
|
*/
|
||||||
|
|
||||||
RenderBuffer* DeferredRenderTechnique::GetDepthStencilBuffer() const
|
RenderBuffer* DeferredRenderTechnique::GetDepthStencilBuffer() const
|
||||||
{
|
{
|
||||||
return m_depthStencilBuffer;
|
return m_depthStencilBuffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Gets the G-buffer
|
||||||
|
* \return Pointer to the ith texture
|
||||||
|
*
|
||||||
|
* \param i Index of the G-buffer
|
||||||
|
*
|
||||||
|
* \remark Produces a NazaraError with NAZARA_GRAPHICS_SAFE defined if index is invalid
|
||||||
|
*/
|
||||||
|
|
||||||
Texture* DeferredRenderTechnique::GetGBuffer(unsigned int i) const
|
Texture* DeferredRenderTechnique::GetGBuffer(unsigned int i) const
|
||||||
{
|
{
|
||||||
#if NAZARA_GRAPHICS_SAFE
|
#if NAZARA_GRAPHICS_SAFE
|
||||||
|
|
@ -271,16 +332,34 @@ namespace Nz
|
||||||
return m_GBuffer[i];
|
return m_GBuffer[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Gets the rendering texture of the G-buffer
|
||||||
|
* \return Pointer to the rendering buffer
|
||||||
|
*/
|
||||||
|
|
||||||
RenderTexture* DeferredRenderTechnique::GetGBufferRTT() const
|
RenderTexture* DeferredRenderTechnique::GetGBufferRTT() const
|
||||||
{
|
{
|
||||||
return &m_GBufferRTT;
|
return &m_GBufferRTT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Gets the forward technique
|
||||||
|
* \return Constant pointer to the forward technique
|
||||||
|
*/
|
||||||
|
|
||||||
const ForwardRenderTechnique* DeferredRenderTechnique::GetForwardTechnique() const
|
const ForwardRenderTechnique* DeferredRenderTechnique::GetForwardTechnique() const
|
||||||
{
|
{
|
||||||
return &m_forwardTechnique;
|
return &m_forwardTechnique;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Gets the pass
|
||||||
|
* \return Pointer to the deferred render pass
|
||||||
|
*
|
||||||
|
* \param renderPass Enumeration for the pass
|
||||||
|
* \param position Position of the pass
|
||||||
|
*/
|
||||||
|
|
||||||
DeferredRenderPass* DeferredRenderTechnique::GetPass(RenderPassType renderPass, int position)
|
DeferredRenderPass* DeferredRenderTechnique::GetPass(RenderPassType renderPass, int position)
|
||||||
{
|
{
|
||||||
auto it = m_passes.find(renderPass);
|
auto it = m_passes.find(renderPass);
|
||||||
|
|
@ -294,21 +373,45 @@ namespace Nz
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Gets the render queue
|
||||||
|
* \return Pointer to the render queue
|
||||||
|
*/
|
||||||
|
|
||||||
AbstractRenderQueue* DeferredRenderTechnique::GetRenderQueue()
|
AbstractRenderQueue* DeferredRenderTechnique::GetRenderQueue()
|
||||||
{
|
{
|
||||||
return &m_renderQueue;
|
return &m_renderQueue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Gets the type of the current technique
|
||||||
|
* \return Type of the render technique
|
||||||
|
*/
|
||||||
|
|
||||||
RenderTechniqueType DeferredRenderTechnique::GetType() const
|
RenderTechniqueType DeferredRenderTechnique::GetType() const
|
||||||
{
|
{
|
||||||
return RenderTechniqueType_DeferredShading;
|
return RenderTechniqueType_DeferredShading;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Gets the render texture used to work
|
||||||
|
* \return Pointer to the rendering texture
|
||||||
|
*/
|
||||||
|
|
||||||
RenderTexture* DeferredRenderTechnique::GetWorkRTT() const
|
RenderTexture* DeferredRenderTechnique::GetWorkRTT() const
|
||||||
{
|
{
|
||||||
return &m_workRTT;
|
return &m_workRTT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Gets the ith texture to work
|
||||||
|
* \return Pointer to the texture
|
||||||
|
*
|
||||||
|
* \param i Index of the texture used to work
|
||||||
|
*
|
||||||
|
* \remark Produces a NazaraError with NAZARA_GRAPHICS_SAFE defined if index is invalid
|
||||||
|
*/
|
||||||
|
|
||||||
Texture* DeferredRenderTechnique::GetWorkTexture(unsigned int i) const
|
Texture* DeferredRenderTechnique::GetWorkTexture(unsigned int i) const
|
||||||
{
|
{
|
||||||
#if NAZARA_GRAPHICS_SAFE
|
#if NAZARA_GRAPHICS_SAFE
|
||||||
|
|
@ -322,6 +425,14 @@ namespace Nz
|
||||||
return m_workTextures[i];
|
return m_workTextures[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Checks whether the pass is enable
|
||||||
|
* \return true If it is the case
|
||||||
|
*
|
||||||
|
* \param renderPass Enumeration for the pass
|
||||||
|
* \param position Position of the pass
|
||||||
|
*/
|
||||||
|
|
||||||
bool DeferredRenderTechnique::IsPassEnabled(RenderPassType renderPass, int position)
|
bool DeferredRenderTechnique::IsPassEnabled(RenderPassType renderPass, int position)
|
||||||
{
|
{
|
||||||
auto it = m_passes.find(renderPass);
|
auto it = m_passes.find(renderPass);
|
||||||
|
|
@ -335,9 +446,17 @@ namespace Nz
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Resets the pass
|
||||||
|
* \return Pointer to the new deferred render pass
|
||||||
|
*
|
||||||
|
* \param renderPass Enumeration for the pass
|
||||||
|
* \param position Position of the pass
|
||||||
|
*/
|
||||||
|
|
||||||
DeferredRenderPass* DeferredRenderTechnique::ResetPass(RenderPassType renderPass, int position)
|
DeferredRenderPass* DeferredRenderTechnique::ResetPass(RenderPassType renderPass, int position)
|
||||||
{
|
{
|
||||||
std::unique_ptr<DeferredRenderPass> smartPtr; // Nous évite un leak en cas d'exception
|
std::unique_ptr<DeferredRenderPass> smartPtr; // We avoid to leak in case of exception
|
||||||
|
|
||||||
switch (renderPass)
|
switch (renderPass)
|
||||||
{
|
{
|
||||||
|
|
@ -386,6 +505,14 @@ namespace Nz
|
||||||
return smartPtr.release();
|
return smartPtr.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Sets the pass
|
||||||
|
*
|
||||||
|
* \param relativeTo Enumeration for the pass
|
||||||
|
* \param position Position of the pass
|
||||||
|
* \param pass Render pass to set
|
||||||
|
*/
|
||||||
|
|
||||||
void DeferredRenderTechnique::SetPass(RenderPassType relativeTo, int position, DeferredRenderPass* pass)
|
void DeferredRenderTechnique::SetPass(RenderPassType relativeTo, int position, DeferredRenderPass* pass)
|
||||||
{
|
{
|
||||||
if (pass)
|
if (pass)
|
||||||
|
|
@ -400,12 +527,26 @@ namespace Nz
|
||||||
m_passes[relativeTo].erase(position);
|
m_passes[relativeTo].erase(position);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Checks whether the technique is supported
|
||||||
|
* \return true if it is the case
|
||||||
|
*/
|
||||||
|
|
||||||
bool DeferredRenderTechnique::IsSupported()
|
bool DeferredRenderTechnique::IsSupported()
|
||||||
{
|
{
|
||||||
// Depuis qu'OpenGL 3.3 est la version minimale, le Renderer supporte ce qu'il faut, mais par acquis de conscience...
|
// Since OpenGL 3.3 is the minimal version, the Renderer supports what it needs, but we are never sure...
|
||||||
return Renderer::GetMaxColorAttachments() >= 4 && Renderer::GetMaxRenderTargets() >= 4;
|
return Renderer::GetMaxColorAttachments() >= 4 && Renderer::GetMaxRenderTargets() >= 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Resizes the texture sizes used for the render technique
|
||||||
|
* \return true If successful
|
||||||
|
*
|
||||||
|
* \param dimensions Dimensions for the render technique
|
||||||
|
*
|
||||||
|
* \param Produces a NazaraError if one pass could not be resized
|
||||||
|
*/
|
||||||
|
|
||||||
bool DeferredRenderTechnique::Resize(const Vector2ui& dimensions) const
|
bool DeferredRenderTechnique::Resize(const Vector2ui& dimensions) const
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
|
@ -427,6 +568,13 @@ namespace Nz
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Initializes the deferred render technique
|
||||||
|
* \return true If successful
|
||||||
|
*
|
||||||
|
* \remark Produces a NazaraError if one shader creation failed
|
||||||
|
*/
|
||||||
|
|
||||||
bool DeferredRenderTechnique::Initialize()
|
bool DeferredRenderTechnique::Initialize()
|
||||||
{
|
{
|
||||||
const char vertexSource_Basic[] =
|
const char vertexSource_Basic[] =
|
||||||
|
|
@ -560,6 +708,10 @@ namespace Nz
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Uninitializes the deferred render technique
|
||||||
|
*/
|
||||||
|
|
||||||
void DeferredRenderTechnique::Uninitialize()
|
void DeferredRenderTechnique::Uninitialize()
|
||||||
{
|
{
|
||||||
ShaderLibrary::Unregister("DeferredGBufferClear");
|
ShaderLibrary::Unregister("DeferredGBufferClear");
|
||||||
|
|
@ -571,6 +723,14 @@ namespace Nz
|
||||||
ShaderLibrary::Unregister("DeferredGaussianBlur");
|
ShaderLibrary::Unregister("DeferredGaussianBlur");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Functor to compare two render pass
|
||||||
|
* \return true If first render pass is "smaller" than the second one
|
||||||
|
*
|
||||||
|
* \param pass1 First render pass to compare
|
||||||
|
* \param pass2 Second render pass to compare
|
||||||
|
*/
|
||||||
|
|
||||||
bool DeferredRenderTechnique::RenderPassComparator::operator()(RenderPassType pass1, RenderPassType pass2) const
|
bool DeferredRenderTechnique::RenderPassComparator::operator()(RenderPassType pass1, RenderPassType pass2) const
|
||||||
{
|
{
|
||||||
return RenderPassPriority[pass1] < RenderPassPriority[pass2];
|
return RenderPassPriority[pass1] < RenderPassPriority[pass2];
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,16 @@
|
||||||
|
|
||||||
namespace Nz
|
namespace Nz
|
||||||
{
|
{
|
||||||
|
/*!
|
||||||
|
* \ingroup graphics
|
||||||
|
* \class Nz::DepthRenderQueue
|
||||||
|
* \brief Graphics class that represents the rendering queue for depth rendering
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Constructs a DepthRenderTechnique object by default
|
||||||
|
*/
|
||||||
|
|
||||||
DepthRenderQueue::DepthRenderQueue()
|
DepthRenderQueue::DepthRenderQueue()
|
||||||
{
|
{
|
||||||
// Material
|
// Material
|
||||||
|
|
@ -18,6 +28,19 @@ namespace Nz
|
||||||
//m_baseMaterial->SetFaceCulling(FaceSide_Front);
|
//m_baseMaterial->SetFaceCulling(FaceSide_Front);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Adds billboard to the queue
|
||||||
|
*
|
||||||
|
* \param renderOrder Order of rendering
|
||||||
|
* \param material Material of the billboard
|
||||||
|
* \param position Position of the billboard
|
||||||
|
* \param size Sizes of the billboard
|
||||||
|
* \param sinCos Rotation of the billboard
|
||||||
|
* \param color Color of the billboard
|
||||||
|
*
|
||||||
|
* \remark Produces a NazaraAssert if material is invalid
|
||||||
|
*/
|
||||||
|
|
||||||
void DepthRenderQueue::AddBillboard(int renderOrder, const Material* material, const Vector3f& position, const Vector2f& size, const Vector2f& sinCos, const Color& color)
|
void DepthRenderQueue::AddBillboard(int renderOrder, const Material* material, const Vector3f& position, const Vector2f& size, const Vector2f& sinCos, const Color& color)
|
||||||
{
|
{
|
||||||
NazaraAssert(material, "Invalid material");
|
NazaraAssert(material, "Invalid material");
|
||||||
|
|
@ -34,6 +57,20 @@ namespace Nz
|
||||||
ForwardRenderQueue::AddBillboard(0, material, position, size, sinCos, color);
|
ForwardRenderQueue::AddBillboard(0, material, position, size, sinCos, color);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Adds multiple billboards to the queue
|
||||||
|
*
|
||||||
|
* \param renderOrder Order of rendering
|
||||||
|
* \param material Material of the billboards
|
||||||
|
* \param count Number of billboards
|
||||||
|
* \param positionPtr Position of the billboards
|
||||||
|
* \param sizePtr Sizes of the billboards
|
||||||
|
* \param sinCosPtr Rotation of the billboards if null, Vector2f(0.f, 1.f) is used
|
||||||
|
* \param colorPtr Color of the billboards if null, Color::White is used
|
||||||
|
*
|
||||||
|
* \remark Produces a NazaraAssert if material is invalid
|
||||||
|
*/
|
||||||
|
|
||||||
void DepthRenderQueue::AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr<const Vector3f> positionPtr, SparsePtr<const Vector2f> sizePtr, SparsePtr<const Vector2f> sinCosPtr, SparsePtr<const Color> colorPtr)
|
void DepthRenderQueue::AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr<const Vector3f> positionPtr, SparsePtr<const Vector2f> sizePtr, SparsePtr<const Vector2f> sinCosPtr, SparsePtr<const Color> colorPtr)
|
||||||
{
|
{
|
||||||
NazaraAssert(material, "Invalid material");
|
NazaraAssert(material, "Invalid material");
|
||||||
|
|
@ -50,6 +87,20 @@ namespace Nz
|
||||||
ForwardRenderQueue::AddBillboards(0, material, count, positionPtr, sizePtr, sinCosPtr, colorPtr);
|
ForwardRenderQueue::AddBillboards(0, material, count, positionPtr, sizePtr, sinCosPtr, colorPtr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Adds multiple billboards to the queue
|
||||||
|
*
|
||||||
|
* \param renderOrder Order of rendering
|
||||||
|
* \param material Material of the billboards
|
||||||
|
* \param count Number of billboards
|
||||||
|
* \param positionPtr Position of the billboards
|
||||||
|
* \param sizePtr Sizes of the billboards
|
||||||
|
* \param sinCosPtr Rotation of the billboards if null, Vector2f(0.f, 1.f) is used
|
||||||
|
* \param alphaPtr Alpha parameters of the billboards if null, 1.f is used
|
||||||
|
*
|
||||||
|
* \remark Produces a NazaraAssert if material is invalid
|
||||||
|
*/
|
||||||
|
|
||||||
void DepthRenderQueue::AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr<const Vector3f> positionPtr, SparsePtr<const Vector2f> sizePtr, SparsePtr<const Vector2f> sinCosPtr, SparsePtr<const float> alphaPtr)
|
void DepthRenderQueue::AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr<const Vector3f> positionPtr, SparsePtr<const Vector2f> sizePtr, SparsePtr<const Vector2f> sinCosPtr, SparsePtr<const float> alphaPtr)
|
||||||
{
|
{
|
||||||
NazaraAssert(material, "Invalid material");
|
NazaraAssert(material, "Invalid material");
|
||||||
|
|
@ -66,6 +117,20 @@ namespace Nz
|
||||||
ForwardRenderQueue::AddBillboards(0, material, count, positionPtr, sizePtr, sinCosPtr, alphaPtr);
|
ForwardRenderQueue::AddBillboards(0, material, count, positionPtr, sizePtr, sinCosPtr, alphaPtr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Adds multiple billboards to the queue
|
||||||
|
*
|
||||||
|
* \param renderOrder Order of rendering
|
||||||
|
* \param material Material of the billboards
|
||||||
|
* \param count Number of billboards
|
||||||
|
* \param positionPtr Position of the billboards
|
||||||
|
* \param sizePtr Sizes of the billboards
|
||||||
|
* \param anglePtr Rotation of the billboards if null, 0.f is used
|
||||||
|
* \param colorPtr Color of the billboards if null, Color::White is used
|
||||||
|
*
|
||||||
|
* \remark Produces a NazaraAssert if material is invalid
|
||||||
|
*/
|
||||||
|
|
||||||
void DepthRenderQueue::AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr<const Vector3f> positionPtr, SparsePtr<const Vector2f> sizePtr, SparsePtr<const float> anglePtr, SparsePtr<const Color> colorPtr)
|
void DepthRenderQueue::AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr<const Vector3f> positionPtr, SparsePtr<const Vector2f> sizePtr, SparsePtr<const float> anglePtr, SparsePtr<const Color> colorPtr)
|
||||||
{
|
{
|
||||||
NazaraAssert(material, "Invalid material");
|
NazaraAssert(material, "Invalid material");
|
||||||
|
|
@ -82,6 +147,20 @@ namespace Nz
|
||||||
ForwardRenderQueue::AddBillboards(0, material, count, positionPtr, sizePtr, anglePtr, colorPtr);
|
ForwardRenderQueue::AddBillboards(0, material, count, positionPtr, sizePtr, anglePtr, colorPtr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Adds multiple billboards to the queue
|
||||||
|
*
|
||||||
|
* \param renderOrder Order of rendering
|
||||||
|
* \param material Material of the billboards
|
||||||
|
* \param count Number of billboards
|
||||||
|
* \param positionPtr Position of the billboards
|
||||||
|
* \param sizePtr Sizes of the billboards
|
||||||
|
* \param anglePtr Rotation of the billboards if null, 0.f is used
|
||||||
|
* \param alphaPtr Alpha parameters of the billboards if null, 1.f is used
|
||||||
|
*
|
||||||
|
* \remark Produces a NazaraAssert if material is invalid
|
||||||
|
*/
|
||||||
|
|
||||||
void DepthRenderQueue::AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr<const Vector3f> positionPtr, SparsePtr<const Vector2f> sizePtr, SparsePtr<const float> anglePtr, SparsePtr<const float> alphaPtr)
|
void DepthRenderQueue::AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr<const Vector3f> positionPtr, SparsePtr<const Vector2f> sizePtr, SparsePtr<const float> anglePtr, SparsePtr<const float> alphaPtr)
|
||||||
{
|
{
|
||||||
NazaraAssert(material, "Invalid material");
|
NazaraAssert(material, "Invalid material");
|
||||||
|
|
@ -98,6 +177,20 @@ namespace Nz
|
||||||
ForwardRenderQueue::AddBillboards(0, material, count, positionPtr, sizePtr, anglePtr, alphaPtr);
|
ForwardRenderQueue::AddBillboards(0, material, count, positionPtr, sizePtr, anglePtr, alphaPtr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Adds multiple billboards to the queue
|
||||||
|
*
|
||||||
|
* \param renderOrder Order of rendering
|
||||||
|
* \param material Material of the billboards
|
||||||
|
* \param count Number of billboards
|
||||||
|
* \param positionPtr Position of the billboards
|
||||||
|
* \param sizePtr Size of the billboards
|
||||||
|
* \param sinCosPtr Rotation of the billboards if null, Vector2f(0.f, 1.f) is used
|
||||||
|
* \param colorPtr Color of the billboards if null, Color::White is used
|
||||||
|
*
|
||||||
|
* \remark Produces a NazaraAssert if material is invalid
|
||||||
|
*/
|
||||||
|
|
||||||
void DepthRenderQueue::AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr<const Vector3f> positionPtr, SparsePtr<const float> sizePtr, SparsePtr<const Vector2f> sinCosPtr, SparsePtr<const Color> colorPtr)
|
void DepthRenderQueue::AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr<const Vector3f> positionPtr, SparsePtr<const float> sizePtr, SparsePtr<const Vector2f> sinCosPtr, SparsePtr<const Color> colorPtr)
|
||||||
{
|
{
|
||||||
NazaraAssert(material, "Invalid material");
|
NazaraAssert(material, "Invalid material");
|
||||||
|
|
@ -114,6 +207,20 @@ namespace Nz
|
||||||
ForwardRenderQueue::AddBillboards(0, material, count, positionPtr, sizePtr, sinCosPtr, colorPtr);
|
ForwardRenderQueue::AddBillboards(0, material, count, positionPtr, sizePtr, sinCosPtr, colorPtr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Adds multiple billboards to the queue
|
||||||
|
*
|
||||||
|
* \param renderOrder Order of rendering
|
||||||
|
* \param material Material of the billboards
|
||||||
|
* \param count Number of billboards
|
||||||
|
* \param positionPtr Position of the billboards
|
||||||
|
* \param sizePtr Size of the billboards
|
||||||
|
* \param sinCosPtr Rotation of the billboards if null, Vector2f(0.f, 1.f) is used
|
||||||
|
* \param alphaPtr Alpha parameters of the billboards if null, 1.f is used
|
||||||
|
*
|
||||||
|
* \remark Produces a NazaraAssert if material is invalid
|
||||||
|
*/
|
||||||
|
|
||||||
void DepthRenderQueue::AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr<const Vector3f> positionPtr, SparsePtr<const float> sizePtr, SparsePtr<const Vector2f> sinCosPtr, SparsePtr<const float> alphaPtr)
|
void DepthRenderQueue::AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr<const Vector3f> positionPtr, SparsePtr<const float> sizePtr, SparsePtr<const Vector2f> sinCosPtr, SparsePtr<const float> alphaPtr)
|
||||||
{
|
{
|
||||||
NazaraAssert(material, "Invalid material");
|
NazaraAssert(material, "Invalid material");
|
||||||
|
|
@ -130,6 +237,20 @@ namespace Nz
|
||||||
ForwardRenderQueue::AddBillboards(0, material, count, positionPtr, sizePtr, sinCosPtr, alphaPtr);
|
ForwardRenderQueue::AddBillboards(0, material, count, positionPtr, sizePtr, sinCosPtr, alphaPtr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Adds multiple billboards to the queue
|
||||||
|
*
|
||||||
|
* \param renderOrder Order of rendering
|
||||||
|
* \param material Material of the billboards
|
||||||
|
* \param count Number of billboards
|
||||||
|
* \param positionPtr Position of the billboards
|
||||||
|
* \param sizePtr Size of the billboards
|
||||||
|
* \param anglePtr Rotation of the billboards if null, 0.f is used
|
||||||
|
* \param colorPtr Color of the billboards if null, Color::White is used
|
||||||
|
*
|
||||||
|
* \remark Produces a NazaraAssert if material is invalid
|
||||||
|
*/
|
||||||
|
|
||||||
void DepthRenderQueue::AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr<const Vector3f> positionPtr, SparsePtr<const float> sizePtr, SparsePtr<const float> anglePtr, SparsePtr<const Color> colorPtr)
|
void DepthRenderQueue::AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr<const Vector3f> positionPtr, SparsePtr<const float> sizePtr, SparsePtr<const float> anglePtr, SparsePtr<const Color> colorPtr)
|
||||||
{
|
{
|
||||||
NazaraAssert(material, "Invalid material");
|
NazaraAssert(material, "Invalid material");
|
||||||
|
|
@ -146,6 +267,20 @@ namespace Nz
|
||||||
ForwardRenderQueue::AddBillboards(0, material, count, positionPtr, sizePtr, anglePtr, colorPtr);
|
ForwardRenderQueue::AddBillboards(0, material, count, positionPtr, sizePtr, anglePtr, colorPtr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Adds multiple billboards to the queue
|
||||||
|
*
|
||||||
|
* \param renderOrder Order of rendering
|
||||||
|
* \param material Material of the billboards
|
||||||
|
* \param count Number of billboards
|
||||||
|
* \param positionPtr Position of the billboards
|
||||||
|
* \param sizePtr Size of the billboards
|
||||||
|
* \param anglePtr Rotation of the billboards if null, 0.f is used
|
||||||
|
* \param alphaPtr Alpha parameters of the billboards if null, 1.f is used
|
||||||
|
*
|
||||||
|
* \remark Produces a NazaraAssert if material is invalid
|
||||||
|
*/
|
||||||
|
|
||||||
void DepthRenderQueue::AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr<const Vector3f> positionPtr, SparsePtr<const float> sizePtr, SparsePtr<const float> anglePtr, SparsePtr<const float> alphaPtr)
|
void DepthRenderQueue::AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr<const Vector3f> positionPtr, SparsePtr<const float> sizePtr, SparsePtr<const float> anglePtr, SparsePtr<const float> alphaPtr)
|
||||||
{
|
{
|
||||||
NazaraAssert(material, "Invalid material");
|
NazaraAssert(material, "Invalid material");
|
||||||
|
|
@ -162,12 +297,32 @@ namespace Nz
|
||||||
ForwardRenderQueue::AddBillboards(0, material, count, positionPtr, sizePtr, anglePtr, alphaPtr);
|
ForwardRenderQueue::AddBillboards(0, material, count, positionPtr, sizePtr, anglePtr, alphaPtr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Adds a direcitonal light to the queue
|
||||||
|
*
|
||||||
|
* \param light Light to add
|
||||||
|
*
|
||||||
|
* \remark Produces a NazaraAssert
|
||||||
|
*/
|
||||||
|
|
||||||
void DepthRenderQueue::AddDirectionalLight(const DirectionalLight& light)
|
void DepthRenderQueue::AddDirectionalLight(const DirectionalLight& light)
|
||||||
{
|
{
|
||||||
NazaraAssert(false, "Depth render queue doesn't handle lights");
|
NazaraAssert(false, "Depth render queue doesn't handle lights");
|
||||||
NazaraUnused(light);
|
NazaraUnused(light);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Adds mesh to the queue
|
||||||
|
*
|
||||||
|
* \param renderOrder Order of rendering
|
||||||
|
* \param material Material of the mesh
|
||||||
|
* \param meshData Data of the mesh
|
||||||
|
* \param meshAABB Box of the mesh
|
||||||
|
* \param transformMatrix Matrix of the mesh
|
||||||
|
*
|
||||||
|
* \remark Produces a NazaraAssert if material is invalid
|
||||||
|
*/
|
||||||
|
|
||||||
void DepthRenderQueue::AddMesh(int renderOrder, const Material* material, const MeshData& meshData, const Boxf& meshAABB, const Matrix4f& transformMatrix)
|
void DepthRenderQueue::AddMesh(int renderOrder, const Material* material, const MeshData& meshData, const Boxf& meshAABB, const Matrix4f& transformMatrix)
|
||||||
{
|
{
|
||||||
NazaraAssert(material, "Invalid material");
|
NazaraAssert(material, "Invalid material");
|
||||||
|
|
@ -185,18 +340,46 @@ namespace Nz
|
||||||
ForwardRenderQueue::AddMesh(0, material, meshData, meshAABB, transformMatrix);
|
ForwardRenderQueue::AddMesh(0, material, meshData, meshAABB, transformMatrix);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Adds a point light to the queue
|
||||||
|
*
|
||||||
|
* \param light Light to add
|
||||||
|
*
|
||||||
|
* \remark Produces a NazaraAssert
|
||||||
|
*/
|
||||||
|
|
||||||
void DepthRenderQueue::AddPointLight(const PointLight& light)
|
void DepthRenderQueue::AddPointLight(const PointLight& light)
|
||||||
{
|
{
|
||||||
NazaraAssert(false, "Depth render queue doesn't handle lights");
|
NazaraAssert(false, "Depth render queue doesn't handle lights");
|
||||||
NazaraUnused(light);
|
NazaraUnused(light);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Adds a spot light to the queue
|
||||||
|
*
|
||||||
|
* \param light Light to add
|
||||||
|
*
|
||||||
|
* \remark Produces a NazaraAssert
|
||||||
|
*/
|
||||||
|
|
||||||
void DepthRenderQueue::AddSpotLight(const SpotLight& light)
|
void DepthRenderQueue::AddSpotLight(const SpotLight& light)
|
||||||
{
|
{
|
||||||
NazaraAssert(false, "Depth render queue doesn't handle lights");
|
NazaraAssert(false, "Depth render queue doesn't handle lights");
|
||||||
NazaraUnused(light);
|
NazaraUnused(light);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Adds sprites to the queue
|
||||||
|
*
|
||||||
|
* \param renderOrder Order of rendering
|
||||||
|
* \param material Material of the sprites
|
||||||
|
* \param vertices Buffer of data for the sprites
|
||||||
|
* \param spriteCount Number of sprites
|
||||||
|
* \param overlay Texture of the sprites
|
||||||
|
*
|
||||||
|
* \remark Produces a NazaraAssert if material is invalid
|
||||||
|
*/
|
||||||
|
|
||||||
void DepthRenderQueue::AddSprites(int renderOrder, const Material* material, const VertexStruct_XYZ_Color_UV* vertices, unsigned int spriteCount, const Texture* overlay)
|
void DepthRenderQueue::AddSprites(int renderOrder, const Material* material, const VertexStruct_XYZ_Color_UV* vertices, unsigned int spriteCount, const Texture* overlay)
|
||||||
{
|
{
|
||||||
NazaraAssert(material, "Invalid material");
|
NazaraAssert(material, "Invalid material");
|
||||||
|
|
|
||||||
|
|
@ -37,6 +37,16 @@ namespace Nz
|
||||||
unsigned int s_vertexBufferSize = 4 * 1024 * 1024; // 4 MiB
|
unsigned int s_vertexBufferSize = 4 * 1024 * 1024; // 4 MiB
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \ingroup graphics
|
||||||
|
* \class Nz::DepthRenderTechnique
|
||||||
|
* \brief Graphics class that represents the technique used in depth rendering
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Constructs a DepthRenderTechnique object by default
|
||||||
|
*/
|
||||||
|
|
||||||
DepthRenderTechnique::DepthRenderTechnique() :
|
DepthRenderTechnique::DepthRenderTechnique() :
|
||||||
m_vertexBuffer(BufferType_Vertex)
|
m_vertexBuffer(BufferType_Vertex)
|
||||||
{
|
{
|
||||||
|
|
@ -48,6 +58,12 @@ namespace Nz
|
||||||
m_spriteBuffer.Reset(VertexDeclaration::Get(VertexLayout_XYZ_Color_UV), &m_vertexBuffer);
|
m_spriteBuffer.Reset(VertexDeclaration::Get(VertexLayout_XYZ_Color_UV), &m_vertexBuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Clears the data
|
||||||
|
*
|
||||||
|
* \param sceneData Data of the scene
|
||||||
|
*/
|
||||||
|
|
||||||
void DepthRenderTechnique::Clear(const SceneData& sceneData) const
|
void DepthRenderTechnique::Clear(const SceneData& sceneData) const
|
||||||
{
|
{
|
||||||
Renderer::Enable(RendererParameter_DepthBuffer, true);
|
Renderer::Enable(RendererParameter_DepthBuffer, true);
|
||||||
|
|
@ -59,6 +75,13 @@ namespace Nz
|
||||||
// sceneData.background->Draw(sceneData.viewer);
|
// sceneData.background->Draw(sceneData.viewer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Draws the data of the scene
|
||||||
|
* \return true If successful
|
||||||
|
*
|
||||||
|
* \param sceneData Data of the scene
|
||||||
|
*/
|
||||||
|
|
||||||
bool DepthRenderTechnique::Draw(const SceneData& sceneData) const
|
bool DepthRenderTechnique::Draw(const SceneData& sceneData) const
|
||||||
{
|
{
|
||||||
for (auto& pair : m_renderQueue.layers)
|
for (auto& pair : m_renderQueue.layers)
|
||||||
|
|
@ -81,16 +104,33 @@ namespace Nz
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Gets the render queue
|
||||||
|
* \return Pointer to the render queue
|
||||||
|
*/
|
||||||
|
|
||||||
AbstractRenderQueue* DepthRenderTechnique::GetRenderQueue()
|
AbstractRenderQueue* DepthRenderTechnique::GetRenderQueue()
|
||||||
{
|
{
|
||||||
return &m_renderQueue;
|
return &m_renderQueue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Gets the type of the current technique
|
||||||
|
* \return Type of the render technique
|
||||||
|
*/
|
||||||
|
|
||||||
RenderTechniqueType DepthRenderTechnique::GetType() const
|
RenderTechniqueType DepthRenderTechnique::GetType() const
|
||||||
{
|
{
|
||||||
return RenderTechniqueType_Depth;
|
return RenderTechniqueType_Depth;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Initializes the depth render technique
|
||||||
|
* \return true If successful
|
||||||
|
*
|
||||||
|
* \remark Produces a NazaraError if one shader creation failed
|
||||||
|
*/
|
||||||
|
|
||||||
bool DepthRenderTechnique::Initialize()
|
bool DepthRenderTechnique::Initialize()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
|
@ -149,12 +189,23 @@ namespace Nz
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Uninitializes the depth render technique
|
||||||
|
*/
|
||||||
|
|
||||||
void DepthRenderTechnique::Uninitialize()
|
void DepthRenderTechnique::Uninitialize()
|
||||||
{
|
{
|
||||||
s_quadIndexBuffer.Reset();
|
s_quadIndexBuffer.Reset();
|
||||||
s_quadVertexBuffer.Reset();
|
s_quadVertexBuffer.Reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Draws basic sprites
|
||||||
|
*
|
||||||
|
* \param sceneData Data of the scene
|
||||||
|
* \param layer Layer of the rendering
|
||||||
|
*/
|
||||||
|
|
||||||
void DepthRenderTechnique::DrawBasicSprites(const SceneData& sceneData, ForwardRenderQueue::Layer& layer) const
|
void DepthRenderTechnique::DrawBasicSprites(const SceneData& sceneData, ForwardRenderQueue::Layer& layer) const
|
||||||
{
|
{
|
||||||
const Shader* lastShader = nullptr;
|
const Shader* lastShader = nullptr;
|
||||||
|
|
@ -180,7 +231,7 @@ namespace Nz
|
||||||
unsigned int spriteChainCount = spriteChainVector.size();
|
unsigned int spriteChainCount = spriteChainVector.size();
|
||||||
if (spriteChainCount > 0)
|
if (spriteChainCount > 0)
|
||||||
{
|
{
|
||||||
// On commence par appliquer du matériau (et récupérer le shader ainsi activé)
|
// We begin to apply the material (and get the shader activated doing so)
|
||||||
UInt32 flags = 0;
|
UInt32 flags = 0;
|
||||||
if (overlay)
|
if (overlay)
|
||||||
flags |= ShaderFlags_TextureOverlay;
|
flags |= ShaderFlags_TextureOverlay;
|
||||||
|
|
@ -195,26 +246,26 @@ namespace Nz
|
||||||
Renderer::SetTextureSampler(overlayUnit, material->GetDiffuseSampler());
|
Renderer::SetTextureSampler(overlayUnit, material->GetDiffuseSampler());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Les uniformes sont conservées au sein d'un programme, inutile de les renvoyer tant qu'il ne change pas
|
// Uniforms are conserved in our program, there's no point to send them back until they change
|
||||||
if (shader != lastShader)
|
if (shader != lastShader)
|
||||||
{
|
{
|
||||||
// Index des uniformes dans le shader
|
// Index of uniforms in the shader
|
||||||
shaderUniforms = GetShaderUniforms(shader);
|
shaderUniforms = GetShaderUniforms(shader);
|
||||||
|
|
||||||
// Overlay
|
// Overlay
|
||||||
shader->SendInteger(shaderUniforms->textureOverlay, overlayUnit);
|
shader->SendInteger(shaderUniforms->textureOverlay, overlayUnit);
|
||||||
// Position de la caméra
|
// Position of the camera
|
||||||
shader->SendVector(shaderUniforms->eyePosition, Renderer::GetMatrix(MatrixType_ViewProj).GetTranslation());
|
shader->SendVector(shaderUniforms->eyePosition, Renderer::GetMatrix(MatrixType_ViewProj).GetTranslation());
|
||||||
|
|
||||||
lastShader = shader;
|
lastShader = shader;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int spriteChain = 0; // Quelle chaîne de sprite traitons-nous
|
unsigned int spriteChain = 0; // Which chain of sprites are we treating
|
||||||
unsigned int spriteChainOffset = 0; // À quel offset dans la dernière chaîne nous sommes-nous arrêtés
|
unsigned int spriteChainOffset = 0; // Where was the last offset where we stopped in the last chain
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
// On ouvre le buffer en écriture
|
// We open the buffer in writing mode
|
||||||
BufferMapper<VertexBuffer> vertexMapper(m_spriteBuffer, BufferAccess_DiscardAndWrite);
|
BufferMapper<VertexBuffer> vertexMapper(m_spriteBuffer, BufferAccess_DiscardAndWrite);
|
||||||
VertexStruct_XYZ_Color_UV* vertices = reinterpret_cast<VertexStruct_XYZ_Color_UV*>(vertexMapper.GetPointer());
|
VertexStruct_XYZ_Color_UV* vertices = reinterpret_cast<VertexStruct_XYZ_Color_UV*>(vertexMapper.GetPointer());
|
||||||
|
|
||||||
|
|
@ -232,7 +283,7 @@ namespace Nz
|
||||||
spriteCount += count;
|
spriteCount += count;
|
||||||
spriteChainOffset += count;
|
spriteChainOffset += count;
|
||||||
|
|
||||||
// Avons-nous traité la chaîne entière ?
|
// Have we treated the entire chain ?
|
||||||
if (spriteChainOffset == currentChain.spriteCount)
|
if (spriteChainOffset == currentChain.spriteCount)
|
||||||
{
|
{
|
||||||
spriteChain++;
|
spriteChain++;
|
||||||
|
|
@ -257,6 +308,13 @@ namespace Nz
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Draws billboards
|
||||||
|
*
|
||||||
|
* \param sceneData Data of the scene
|
||||||
|
* \param layer Layer of the rendering
|
||||||
|
*/
|
||||||
|
|
||||||
void DepthRenderTechnique::DrawBillboards(const SceneData& sceneData, ForwardRenderQueue::Layer& layer) const
|
void DepthRenderTechnique::DrawBillboards(const SceneData& sceneData, ForwardRenderQueue::Layer& layer) const
|
||||||
{
|
{
|
||||||
const Shader* lastShader = nullptr;
|
const Shader* lastShader = nullptr;
|
||||||
|
|
@ -278,16 +336,16 @@ namespace Nz
|
||||||
unsigned int billboardCount = billboardVector.size();
|
unsigned int billboardCount = billboardVector.size();
|
||||||
if (billboardCount > 0)
|
if (billboardCount > 0)
|
||||||
{
|
{
|
||||||
// On commence par appliquer du matériau (et récupérer le shader ainsi activé)
|
// We begin to apply the material (and get the shader activated doing so)
|
||||||
const Shader* shader = material->Apply(ShaderFlags_Billboard | ShaderFlags_Instancing | ShaderFlags_VertexColor);
|
const Shader* shader = material->Apply(ShaderFlags_Billboard | ShaderFlags_Instancing | ShaderFlags_VertexColor);
|
||||||
|
|
||||||
// Les uniformes sont conservées au sein d'un programme, inutile de les renvoyer tant qu'il ne change pas
|
// Uniforms are conserved in our program, there's no point to send them back until they change
|
||||||
if (shader != lastShader)
|
if (shader != lastShader)
|
||||||
{
|
{
|
||||||
// Index des uniformes dans le shader
|
// Index of uniforms in the shader
|
||||||
shaderUniforms = GetShaderUniforms(shader);
|
shaderUniforms = GetShaderUniforms(shader);
|
||||||
|
|
||||||
// Position de la caméra
|
// Position of the camera
|
||||||
shader->SendVector(shaderUniforms->eyePosition, Renderer::GetMatrix(MatrixType_ViewProj).GetTranslation());
|
shader->SendVector(shaderUniforms->eyePosition, Renderer::GetMatrix(MatrixType_ViewProj).GetTranslation());
|
||||||
|
|
||||||
lastShader = shader;
|
lastShader = shader;
|
||||||
|
|
@ -325,16 +383,16 @@ namespace Nz
|
||||||
unsigned int billboardCount = billboardVector.size();
|
unsigned int billboardCount = billboardVector.size();
|
||||||
if (billboardCount > 0)
|
if (billboardCount > 0)
|
||||||
{
|
{
|
||||||
// On commence par appliquer du matériau (et récupérer le shader ainsi activé)
|
// We begin to apply the material (and get the shader activated doing so)
|
||||||
const Shader* shader = material->Apply(ShaderFlags_Billboard | ShaderFlags_VertexColor);
|
const Shader* shader = material->Apply(ShaderFlags_Billboard | ShaderFlags_VertexColor);
|
||||||
|
|
||||||
// Les uniformes sont conservées au sein d'un programme, inutile de les renvoyer tant qu'il ne change pas
|
// Uniforms are conserved in our program, there's no point to send them back until they change
|
||||||
if (shader != lastShader)
|
if (shader != lastShader)
|
||||||
{
|
{
|
||||||
// Index des uniformes dans le shader
|
// Index of uniforms in the shader
|
||||||
shaderUniforms = GetShaderUniforms(shader);
|
shaderUniforms = GetShaderUniforms(shader);
|
||||||
|
|
||||||
// Position de la caméra
|
// Position of the camera
|
||||||
shader->SendVector(shaderUniforms->eyePosition, Renderer::GetMatrix(MatrixType_ViewProj).GetTranslation());
|
shader->SendVector(shaderUniforms->eyePosition, Renderer::GetMatrix(MatrixType_ViewProj).GetTranslation());
|
||||||
|
|
||||||
lastShader = shader;
|
lastShader = shader;
|
||||||
|
|
@ -396,6 +454,13 @@ namespace Nz
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Draws opaques models
|
||||||
|
*
|
||||||
|
* \param sceneData Data of the scene
|
||||||
|
* \param layer Layer of the rendering
|
||||||
|
*/
|
||||||
|
|
||||||
void DepthRenderTechnique::DrawOpaqueModels(const SceneData& sceneData, ForwardRenderQueue::Layer& layer) const
|
void DepthRenderTechnique::DrawOpaqueModels(const SceneData& sceneData, ForwardRenderQueue::Layer& layer) const
|
||||||
{
|
{
|
||||||
const Shader* lastShader = nullptr;
|
const Shader* lastShader = nullptr;
|
||||||
|
|
@ -415,14 +480,14 @@ namespace Nz
|
||||||
|
|
||||||
bool instancing = m_instancingEnabled && matEntry.instancingEnabled;
|
bool instancing = m_instancingEnabled && matEntry.instancingEnabled;
|
||||||
|
|
||||||
// On commence par appliquer du matériau (et récupérer le shader ainsi activé)
|
// We begin to apply the material (and get the shader activated doing so)
|
||||||
UInt8 freeTextureUnit;
|
UInt8 freeTextureUnit;
|
||||||
const Shader* shader = material->Apply((instancing) ? ShaderFlags_Instancing : 0, 0, &freeTextureUnit);
|
const Shader* shader = material->Apply((instancing) ? ShaderFlags_Instancing : 0, 0, &freeTextureUnit);
|
||||||
|
|
||||||
// Les uniformes sont conservées au sein d'un programme, inutile de les renvoyer tant qu'il ne change pas
|
// Uniforms are conserved in our program, there's no point to send them back until they change
|
||||||
if (shader != lastShader)
|
if (shader != lastShader)
|
||||||
{
|
{
|
||||||
// Index des uniformes dans le shader
|
// Index of uniforms in the shader
|
||||||
shaderUniforms = GetShaderUniforms(shader);
|
shaderUniforms = GetShaderUniforms(shader);
|
||||||
lastShader = shader;
|
lastShader = shader;
|
||||||
}
|
}
|
||||||
|
|
@ -441,7 +506,7 @@ namespace Nz
|
||||||
const IndexBuffer* indexBuffer = meshData.indexBuffer;
|
const IndexBuffer* indexBuffer = meshData.indexBuffer;
|
||||||
const VertexBuffer* vertexBuffer = meshData.vertexBuffer;
|
const VertexBuffer* vertexBuffer = meshData.vertexBuffer;
|
||||||
|
|
||||||
// Gestion du draw call avant la boucle de rendu
|
// Handle draw call before rendering loop
|
||||||
Renderer::DrawCall drawFunc;
|
Renderer::DrawCall drawFunc;
|
||||||
Renderer::DrawCallInstanced instancedDrawFunc;
|
Renderer::DrawCallInstanced instancedDrawFunc;
|
||||||
unsigned int indexCount;
|
unsigned int indexCount;
|
||||||
|
|
@ -464,33 +529,33 @@ namespace Nz
|
||||||
|
|
||||||
if (instancing)
|
if (instancing)
|
||||||
{
|
{
|
||||||
// On calcule le nombre d'instances que l'on pourra afficher cette fois-ci (Selon la taille du buffer d'instancing)
|
// We compute the number of instances that we will be able to draw this time (depending on the instancing buffer size)
|
||||||
VertexBuffer* instanceBuffer = Renderer::GetInstanceBuffer();
|
VertexBuffer* instanceBuffer = Renderer::GetInstanceBuffer();
|
||||||
instanceBuffer->SetVertexDeclaration(VertexDeclaration::Get(VertexLayout_Matrix4));
|
instanceBuffer->SetVertexDeclaration(VertexDeclaration::Get(VertexLayout_Matrix4));
|
||||||
|
|
||||||
const Matrix4f* instanceMatrices = &instances[0];
|
const Matrix4f* instanceMatrices = &instances[0];
|
||||||
unsigned int instanceCount = instances.size();
|
unsigned int instanceCount = instances.size();
|
||||||
unsigned int maxInstanceCount = instanceBuffer->GetVertexCount(); // Le nombre maximum d'instances en une fois
|
unsigned int maxInstanceCount = instanceBuffer->GetVertexCount(); // The maximum number of instances in one batch
|
||||||
|
|
||||||
while (instanceCount > 0)
|
while (instanceCount > 0)
|
||||||
{
|
{
|
||||||
// On calcule le nombre d'instances que l'on pourra afficher cette fois-ci (Selon la taille du buffer d'instancing)
|
// We compute the number of instances that we will be able to draw this time (depending on the instancing buffer size)
|
||||||
unsigned int renderedInstanceCount = std::min(instanceCount, maxInstanceCount);
|
unsigned int renderedInstanceCount = std::min(instanceCount, maxInstanceCount);
|
||||||
instanceCount -= renderedInstanceCount;
|
instanceCount -= renderedInstanceCount;
|
||||||
|
|
||||||
// On remplit l'instancing buffer avec nos matrices world
|
// We fill the instancing buffer with our world matrices
|
||||||
instanceBuffer->Fill(instanceMatrices, 0, renderedInstanceCount, true);
|
instanceBuffer->Fill(instanceMatrices, 0, renderedInstanceCount, true);
|
||||||
instanceMatrices += renderedInstanceCount;
|
instanceMatrices += renderedInstanceCount;
|
||||||
|
|
||||||
// Et on affiche
|
// And we draw
|
||||||
instancedDrawFunc(renderedInstanceCount, meshData.primitiveMode, 0, indexCount);
|
instancedDrawFunc(renderedInstanceCount, meshData.primitiveMode, 0, indexCount);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Sans instancing, on doit effectuer un draw call pour chaque instance
|
// Without instancing, we must do a draw call for each instance
|
||||||
// Cela reste néanmoins plus rapide que l'instancing en dessous d'un certain nombre d'instances
|
// This may be faster than instancing under a certain number
|
||||||
// À cause du temps de modification du buffer d'instancing
|
// Due to the time to modify the instancing buffer
|
||||||
for (const Matrix4f& matrix : instances)
|
for (const Matrix4f& matrix : instances)
|
||||||
{
|
{
|
||||||
Renderer::SetMatrix(MatrixType_World, matrix);
|
Renderer::SetMatrix(MatrixType_World, matrix);
|
||||||
|
|
@ -502,13 +567,20 @@ namespace Nz
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Et on remet à zéro les données
|
// And we set the data back to zero
|
||||||
matEntry.enabled = false;
|
matEntry.enabled = false;
|
||||||
matEntry.instancingEnabled = false;
|
matEntry.instancingEnabled = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Gets the shader uniforms
|
||||||
|
* \return Uniforms of the shader
|
||||||
|
*
|
||||||
|
* \param shader Shader to get uniforms from
|
||||||
|
*/
|
||||||
|
|
||||||
const DepthRenderTechnique::ShaderUniforms* DepthRenderTechnique::GetShaderUniforms(const Shader* shader) const
|
const DepthRenderTechnique::ShaderUniforms* DepthRenderTechnique::GetShaderUniforms(const Shader* shader) const
|
||||||
{
|
{
|
||||||
auto it = m_shaderUniforms.find(shader);
|
auto it = m_shaderUniforms.find(shader);
|
||||||
|
|
@ -527,6 +599,12 @@ namespace Nz
|
||||||
return &it->second;
|
return &it->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Handle the invalidation of a shader
|
||||||
|
*
|
||||||
|
* \param shader Shader being invalidated
|
||||||
|
*/
|
||||||
|
|
||||||
void DepthRenderTechnique::OnShaderInvalidated(const Shader* shader) const
|
void DepthRenderTechnique::OnShaderInvalidated(const Shader* shader) const
|
||||||
{
|
{
|
||||||
m_shaderUniforms.erase(shader);
|
m_shaderUniforms.erase(shader);
|
||||||
|
|
|
||||||
|
|
@ -7,5 +7,13 @@
|
||||||
|
|
||||||
namespace Nz
|
namespace Nz
|
||||||
{
|
{
|
||||||
|
/*!
|
||||||
|
* \ingroup graphics
|
||||||
|
* \class Nz::Drawable
|
||||||
|
* \brief Graphics class that represents something drawable for our scene
|
||||||
|
*
|
||||||
|
* \remark This class is abstract
|
||||||
|
*/
|
||||||
|
|
||||||
Drawable::~Drawable() = default;
|
Drawable::~Drawable() = default;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,12 @@ namespace Nz
|
||||||
String filePath;
|
String filePath;
|
||||||
if (matData.GetStringParameter(MaterialData::FilePath, &filePath))
|
if (matData.GetStringParameter(MaterialData::FilePath, &filePath))
|
||||||
{
|
{
|
||||||
|
if (!File::Exists(filePath))
|
||||||
|
{
|
||||||
|
NazaraWarning("Shader name does not refer to an existing file, \".tga\" is used by default");
|
||||||
|
filePath += ".tga";
|
||||||
|
}
|
||||||
|
|
||||||
MaterialRef material = Material::New();
|
MaterialRef material = Material::New();
|
||||||
if (material->LoadFromFile(filePath, parameters.material))
|
if (material->LoadFromFile(filePath, parameters.material))
|
||||||
model->SetMaterial(i, std::move(material));
|
model->SetMaterial(i, std::move(material));
|
||||||
|
|
|
||||||
|
|
@ -7,10 +7,29 @@
|
||||||
#include <Nazara/Graphics/Light.hpp>
|
#include <Nazara/Graphics/Light.hpp>
|
||||||
#include <Nazara/Graphics/Debug.hpp>
|
#include <Nazara/Graphics/Debug.hpp>
|
||||||
|
|
||||||
///TODO: Remplacer les sinus/cosinus par une lookup table (va booster les perfs d'un bon x10)
|
///TODO: Replace sinus/cosinus by a lookup table (which will lead to a speed up about 10x)
|
||||||
|
|
||||||
namespace Nz
|
namespace Nz
|
||||||
{
|
{
|
||||||
|
/*!
|
||||||
|
* \ingroup graphics
|
||||||
|
* \class Nz::ForwardRenderQueue
|
||||||
|
* \brief Graphics class that represents the rendering queue for forward rendering
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Adds billboard to the queue
|
||||||
|
*
|
||||||
|
* \param renderOrder Order of rendering
|
||||||
|
* \param material Material of the billboard
|
||||||
|
* \param position Position of the billboard
|
||||||
|
* \param size Sizes of the billboard
|
||||||
|
* \param sinCos Rotation of the billboard
|
||||||
|
* \param color Color of the billboard
|
||||||
|
*
|
||||||
|
* \remark Produces a NazaraAssert if material is invalid
|
||||||
|
*/
|
||||||
|
|
||||||
void ForwardRenderQueue::AddBillboard(int renderOrder, const Material* material, const Vector3f& position, const Vector2f& size, const Vector2f& sinCos, const Color& color)
|
void ForwardRenderQueue::AddBillboard(int renderOrder, const Material* material, const Vector3f& position, const Vector2f& size, const Vector2f& sinCos, const Color& color)
|
||||||
{
|
{
|
||||||
NazaraAssert(material, "Invalid material");
|
NazaraAssert(material, "Invalid material");
|
||||||
|
|
@ -32,37 +51,33 @@ namespace Nz
|
||||||
billboardVector.push_back(BillboardData{color, position, size, sinCos});
|
billboardVector.push_back(BillboardData{color, position, size, sinCos});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Adds multiple billboards to the queue
|
||||||
|
*
|
||||||
|
* \param renderOrder Order of rendering
|
||||||
|
* \param material Material of the billboards
|
||||||
|
* \param count Number of billboards
|
||||||
|
* \param positionPtr Position of the billboards
|
||||||
|
* \param sizePtr Sizes of the billboards
|
||||||
|
* \param sinCosPtr Rotation of the billboards if null, Vector2f(0.f, 1.f) is used
|
||||||
|
* \param colorPtr Color of the billboards if null, Color::White is used
|
||||||
|
*
|
||||||
|
* \remark Produces a NazaraAssert if material is invalid
|
||||||
|
*/
|
||||||
|
|
||||||
void ForwardRenderQueue::AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr<const Vector3f> positionPtr, SparsePtr<const Vector2f> sizePtr, SparsePtr<const Vector2f> sinCosPtr, SparsePtr<const Color> colorPtr)
|
void ForwardRenderQueue::AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr<const Vector3f> positionPtr, SparsePtr<const Vector2f> sizePtr, SparsePtr<const Vector2f> sinCosPtr, SparsePtr<const Color> colorPtr)
|
||||||
{
|
{
|
||||||
NazaraAssert(material, "Invalid material");
|
NazaraAssert(material, "Invalid material");
|
||||||
|
|
||||||
///DOC: sinCosPtr et colorPtr peuvent être nuls, ils seont remplacés respectivement par Vector2f(0.f, 1.f) et Color::White
|
|
||||||
Vector2f defaultSinCos(0.f, 1.f); // sin(0) = 0, cos(0) = 1
|
Vector2f defaultSinCos(0.f, 1.f); // sin(0) = 0, cos(0) = 1
|
||||||
|
|
||||||
if (!sinCosPtr)
|
if (!sinCosPtr)
|
||||||
sinCosPtr.Reset(&defaultSinCos, 0); // L'astuce ici est de mettre le stride sur zéro, rendant le pointeur immobile
|
sinCosPtr.Reset(&defaultSinCos, 0); // The trick here is to put the stride to zero, which leads the pointer to be immobile
|
||||||
|
|
||||||
if (!colorPtr)
|
if (!colorPtr)
|
||||||
colorPtr.Reset(&Color::White, 0); // Pareil
|
colorPtr.Reset(&Color::White, 0); // Same
|
||||||
|
|
||||||
auto& billboards = GetLayer(renderOrder).billboards;
|
BillboardData* billboardData = GetBillboardData(renderOrder, material, count);
|
||||||
|
|
||||||
auto it = billboards.find(material);
|
|
||||||
if (it == billboards.end())
|
|
||||||
{
|
|
||||||
BatchedBillboardEntry entry;
|
|
||||||
entry.materialReleaseSlot.Connect(material->OnMaterialRelease, this, &ForwardRenderQueue::OnMaterialInvalidation);
|
|
||||||
|
|
||||||
it = billboards.insert(std::make_pair(material, std::move(entry))).first;
|
|
||||||
}
|
|
||||||
|
|
||||||
BatchedBillboardEntry& entry = it->second;
|
|
||||||
|
|
||||||
auto& billboardVector = entry.billboards;
|
|
||||||
unsigned int prevSize = billboardVector.size();
|
|
||||||
billboardVector.resize(prevSize + count);
|
|
||||||
|
|
||||||
BillboardData* billboardData = &billboardVector[prevSize];
|
|
||||||
for (unsigned int i = 0; i < count; ++i)
|
for (unsigned int i = 0; i < count; ++i)
|
||||||
{
|
{
|
||||||
billboardData->center = *positionPtr++;
|
billboardData->center = *positionPtr++;
|
||||||
|
|
@ -73,39 +88,35 @@ namespace Nz
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Adds multiple billboards to the queue
|
||||||
|
*
|
||||||
|
* \param renderOrder Order of rendering
|
||||||
|
* \param material Material of the billboards
|
||||||
|
* \param count Number of billboards
|
||||||
|
* \param positionPtr Position of the billboards
|
||||||
|
* \param sizePtr Sizes of the billboards
|
||||||
|
* \param sinCosPtr Rotation of the billboards if null, Vector2f(0.f, 1.f) is used
|
||||||
|
* \param alphaPtr Alpha parameters of the billboards if null, 1.f is used
|
||||||
|
*
|
||||||
|
* \remark Produces a NazaraAssert if material is invalid
|
||||||
|
*/
|
||||||
|
|
||||||
void ForwardRenderQueue::AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr<const Vector3f> positionPtr, SparsePtr<const Vector2f> sizePtr, SparsePtr<const Vector2f> sinCosPtr, SparsePtr<const float> alphaPtr)
|
void ForwardRenderQueue::AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr<const Vector3f> positionPtr, SparsePtr<const Vector2f> sizePtr, SparsePtr<const Vector2f> sinCosPtr, SparsePtr<const float> alphaPtr)
|
||||||
{
|
{
|
||||||
NazaraAssert(material, "Invalid material");
|
NazaraAssert(material, "Invalid material");
|
||||||
|
|
||||||
///DOC: sinCosPtr et alphaPtr peuvent être nuls, ils seront remplacés respectivement par Vector2f(0.f, 1.f) et Color::White
|
|
||||||
Vector2f defaultSinCos(0.f, 1.f); // sin(0) = 0, cos(0) = 1
|
Vector2f defaultSinCos(0.f, 1.f); // sin(0) = 0, cos(0) = 1
|
||||||
|
|
||||||
if (!sinCosPtr)
|
if (!sinCosPtr)
|
||||||
sinCosPtr.Reset(&defaultSinCos, 0); // L'astuce ici est de mettre le stride sur zéro, rendant le pointeur immobile
|
sinCosPtr.Reset(&defaultSinCos, 0); // The trick here is to put the stride to zero, which leads the pointer to be immobile
|
||||||
|
|
||||||
float defaultAlpha = 1.f;
|
float defaultAlpha = 1.f;
|
||||||
|
|
||||||
if (!alphaPtr)
|
if (!alphaPtr)
|
||||||
alphaPtr.Reset(&defaultAlpha, 0); // Pareil
|
alphaPtr.Reset(&defaultAlpha, 0); // Same
|
||||||
|
|
||||||
auto& billboards = GetLayer(renderOrder).billboards;
|
BillboardData* billboardData = GetBillboardData(renderOrder, material, count);
|
||||||
|
|
||||||
auto it = billboards.find(material);
|
|
||||||
if (it == billboards.end())
|
|
||||||
{
|
|
||||||
BatchedBillboardEntry entry;
|
|
||||||
entry.materialReleaseSlot.Connect(material->OnMaterialRelease, this, &ForwardRenderQueue::OnMaterialInvalidation);
|
|
||||||
|
|
||||||
it = billboards.insert(std::make_pair(material, std::move(entry))).first;
|
|
||||||
}
|
|
||||||
|
|
||||||
BatchedBillboardEntry& entry = it->second;
|
|
||||||
|
|
||||||
auto& billboardVector = entry.billboards;
|
|
||||||
unsigned int prevSize = billboardVector.size();
|
|
||||||
billboardVector.resize(prevSize + count);
|
|
||||||
|
|
||||||
BillboardData* billboardData = &billboardVector[prevSize];
|
|
||||||
for (unsigned int i = 0; i < count; ++i)
|
for (unsigned int i = 0; i < count; ++i)
|
||||||
{
|
{
|
||||||
billboardData->center = *positionPtr++;
|
billboardData->center = *positionPtr++;
|
||||||
|
|
@ -116,37 +127,33 @@ namespace Nz
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Adds multiple billboards to the queue
|
||||||
|
*
|
||||||
|
* \param renderOrder Order of rendering
|
||||||
|
* \param material Material of the billboards
|
||||||
|
* \param count Number of billboards
|
||||||
|
* \param positionPtr Position of the billboards
|
||||||
|
* \param sizePtr Sizes of the billboards
|
||||||
|
* \param anglePtr Rotation of the billboards if null, 0.f is used
|
||||||
|
* \param colorPtr Color of the billboards if null, Color::White is used
|
||||||
|
*
|
||||||
|
* \remark Produces a NazaraAssert if material is invalid
|
||||||
|
*/
|
||||||
|
|
||||||
void ForwardRenderQueue::AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr<const Vector3f> positionPtr, SparsePtr<const Vector2f> sizePtr, SparsePtr<const float> anglePtr, SparsePtr<const Color> colorPtr)
|
void ForwardRenderQueue::AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr<const Vector3f> positionPtr, SparsePtr<const Vector2f> sizePtr, SparsePtr<const float> anglePtr, SparsePtr<const Color> colorPtr)
|
||||||
{
|
{
|
||||||
NazaraAssert(material, "Invalid material");
|
NazaraAssert(material, "Invalid material");
|
||||||
|
|
||||||
///DOC: sinCosPtr et colorPtr peuvent être nuls, ils seront remplacés respectivement par Vector2f(0.f, 1.f) et Color::White
|
|
||||||
float defaultRotation = 0.f;
|
float defaultRotation = 0.f;
|
||||||
|
|
||||||
if (!anglePtr)
|
if (!anglePtr)
|
||||||
anglePtr.Reset(&defaultRotation, 0); // L'astuce ici est de mettre le stride sur zéro, rendant le pointeur immobile
|
anglePtr.Reset(&defaultRotation, 0); // The trick here is to put the stride to zero, which leads the pointer to be immobile
|
||||||
|
|
||||||
if (!colorPtr)
|
if (!colorPtr)
|
||||||
colorPtr.Reset(&Color::White, 0); // Pareil
|
colorPtr.Reset(&Color::White, 0); // Same
|
||||||
|
|
||||||
auto& billboards = GetLayer(renderOrder).billboards;
|
BillboardData* billboardData = GetBillboardData(renderOrder, material, count);
|
||||||
|
|
||||||
auto it = billboards.find(material);
|
|
||||||
if (it == billboards.end())
|
|
||||||
{
|
|
||||||
BatchedBillboardEntry entry;
|
|
||||||
entry.materialReleaseSlot.Connect(material->OnMaterialRelease, this, &ForwardRenderQueue::OnMaterialInvalidation);
|
|
||||||
|
|
||||||
it = billboards.insert(std::make_pair(material, std::move(entry))).first;
|
|
||||||
}
|
|
||||||
|
|
||||||
BatchedBillboardEntry& entry = it->second;
|
|
||||||
|
|
||||||
auto& billboardVector = entry.billboards;
|
|
||||||
unsigned int prevSize = billboardVector.size();
|
|
||||||
billboardVector.resize(prevSize + count);
|
|
||||||
|
|
||||||
BillboardData* billboardData = &billboardVector[prevSize];
|
|
||||||
for (unsigned int i = 0; i < count; ++i)
|
for (unsigned int i = 0; i < count; ++i)
|
||||||
{
|
{
|
||||||
float sin = std::sin(ToRadians(*anglePtr));
|
float sin = std::sin(ToRadians(*anglePtr));
|
||||||
|
|
@ -161,39 +168,35 @@ namespace Nz
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Adds multiple billboards to the queue
|
||||||
|
*
|
||||||
|
* \param renderOrder Order of rendering
|
||||||
|
* \param material Material of the billboards
|
||||||
|
* \param count Number of billboards
|
||||||
|
* \param positionPtr Position of the billboards
|
||||||
|
* \param sizePtr Sizes of the billboards
|
||||||
|
* \param anglePtr Rotation of the billboards if null, 0.f is used
|
||||||
|
* \param alphaPtr Alpha parameters of the billboards if null, 1.f is used
|
||||||
|
*
|
||||||
|
* \remark Produces a NazaraAssert if material is invalid
|
||||||
|
*/
|
||||||
|
|
||||||
void ForwardRenderQueue::AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr<const Vector3f> positionPtr, SparsePtr<const Vector2f> sizePtr, SparsePtr<const float> anglePtr, SparsePtr<const float> alphaPtr)
|
void ForwardRenderQueue::AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr<const Vector3f> positionPtr, SparsePtr<const Vector2f> sizePtr, SparsePtr<const float> anglePtr, SparsePtr<const float> alphaPtr)
|
||||||
{
|
{
|
||||||
NazaraAssert(material, "Invalid material");
|
NazaraAssert(material, "Invalid material");
|
||||||
|
|
||||||
///DOC: sinCosPtr et alphaPtr peuvent être nuls, ils seront remplacés respectivement par Vector2f(0.f, 1.f) et Color::White
|
|
||||||
float defaultRotation = 0.f;
|
float defaultRotation = 0.f;
|
||||||
|
|
||||||
if (!anglePtr)
|
if (!anglePtr)
|
||||||
anglePtr.Reset(&defaultRotation, 0); // L'astuce ici est de mettre le stride sur zéro, rendant le pointeur immobile
|
anglePtr.Reset(&defaultRotation, 0); // The trick here is to put the stride to zero, which leads the pointer to be immobile
|
||||||
|
|
||||||
float defaultAlpha = 1.f;
|
float defaultAlpha = 1.f;
|
||||||
|
|
||||||
if (!alphaPtr)
|
if (!alphaPtr)
|
||||||
alphaPtr.Reset(&defaultAlpha, 0); // Pareil
|
alphaPtr.Reset(&defaultAlpha, 0); // Same
|
||||||
|
|
||||||
auto& billboards = GetLayer(renderOrder).billboards;
|
BillboardData* billboardData = GetBillboardData(renderOrder, material, count);
|
||||||
|
|
||||||
auto it = billboards.find(material);
|
|
||||||
if (it == billboards.end())
|
|
||||||
{
|
|
||||||
BatchedBillboardEntry entry;
|
|
||||||
entry.materialReleaseSlot.Connect(material->OnMaterialRelease, this, &ForwardRenderQueue::OnMaterialInvalidation);
|
|
||||||
|
|
||||||
it = billboards.insert(std::make_pair(material, std::move(entry))).first;
|
|
||||||
}
|
|
||||||
|
|
||||||
BatchedBillboardEntry& entry = it->second;
|
|
||||||
|
|
||||||
auto& billboardVector = entry.billboards;
|
|
||||||
unsigned int prevSize = billboardVector.size();
|
|
||||||
billboardVector.resize(prevSize + count);
|
|
||||||
|
|
||||||
BillboardData* billboardData = &billboardVector[prevSize];
|
|
||||||
for (unsigned int i = 0; i < count; ++i)
|
for (unsigned int i = 0; i < count; ++i)
|
||||||
{
|
{
|
||||||
float sin = std::sin(ToRadians(*anglePtr));
|
float sin = std::sin(ToRadians(*anglePtr));
|
||||||
|
|
@ -208,37 +211,33 @@ namespace Nz
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Adds multiple billboards to the queue
|
||||||
|
*
|
||||||
|
* \param renderOrder Order of rendering
|
||||||
|
* \param material Material of the billboards
|
||||||
|
* \param count Number of billboards
|
||||||
|
* \param positionPtr Position of the billboards
|
||||||
|
* \param sizePtr Size of the billboards
|
||||||
|
* \param sinCosPtr Rotation of the billboards if null, Vector2f(0.f, 1.f) is used
|
||||||
|
* \param colorPtr Color of the billboards if null, Color::White is used
|
||||||
|
*
|
||||||
|
* \remark Produces a NazaraAssert if material is invalid
|
||||||
|
*/
|
||||||
|
|
||||||
void ForwardRenderQueue::AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr<const Vector3f> positionPtr, SparsePtr<const float> sizePtr, SparsePtr<const Vector2f> sinCosPtr, SparsePtr<const Color> colorPtr)
|
void ForwardRenderQueue::AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr<const Vector3f> positionPtr, SparsePtr<const float> sizePtr, SparsePtr<const Vector2f> sinCosPtr, SparsePtr<const Color> colorPtr)
|
||||||
{
|
{
|
||||||
NazaraAssert(material, "Invalid material");
|
NazaraAssert(material, "Invalid material");
|
||||||
|
|
||||||
///DOC: sinCosPtr et colorPtr peuvent être nuls, ils seront remplacés respectivement par Vector2f(0.f, 1.f) et Color::White
|
|
||||||
Vector2f defaultSinCos(0.f, 1.f); // sin(0) = 0, cos(0) = 1
|
Vector2f defaultSinCos(0.f, 1.f); // sin(0) = 0, cos(0) = 1
|
||||||
|
|
||||||
if (!sinCosPtr)
|
if (!sinCosPtr)
|
||||||
sinCosPtr.Reset(&defaultSinCos, 0); // L'astuce ici est de mettre le stride sur zéro, rendant le pointeur immobile
|
sinCosPtr.Reset(&defaultSinCos, 0); // The trick here is to put the stride to zero, which leads the pointer to be immobile
|
||||||
|
|
||||||
if (!colorPtr)
|
if (!colorPtr)
|
||||||
colorPtr.Reset(&Color::White, 0); // Pareil
|
colorPtr.Reset(&Color::White, 0); // Same
|
||||||
|
|
||||||
auto& billboards = GetLayer(renderOrder).billboards;
|
BillboardData* billboardData = GetBillboardData(renderOrder, material, count);
|
||||||
|
|
||||||
auto it = billboards.find(material);
|
|
||||||
if (it == billboards.end())
|
|
||||||
{
|
|
||||||
BatchedBillboardEntry entry;
|
|
||||||
entry.materialReleaseSlot.Connect(material->OnMaterialRelease, this, &ForwardRenderQueue::OnMaterialInvalidation);
|
|
||||||
|
|
||||||
it = billboards.insert(std::make_pair(material, std::move(entry))).first;
|
|
||||||
}
|
|
||||||
|
|
||||||
BatchedBillboardEntry& entry = it->second;
|
|
||||||
|
|
||||||
auto& billboardVector = entry.billboards;
|
|
||||||
unsigned int prevSize = billboardVector.size();
|
|
||||||
billboardVector.resize(prevSize + count);
|
|
||||||
|
|
||||||
BillboardData* billboardData = &billboardVector[prevSize];
|
|
||||||
for (unsigned int i = 0; i < count; ++i)
|
for (unsigned int i = 0; i < count; ++i)
|
||||||
{
|
{
|
||||||
billboardData->center = *positionPtr++;
|
billboardData->center = *positionPtr++;
|
||||||
|
|
@ -249,39 +248,35 @@ namespace Nz
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Adds multiple billboards to the queue
|
||||||
|
*
|
||||||
|
* \param renderOrder Order of rendering
|
||||||
|
* \param material Material of the billboards
|
||||||
|
* \param count Number of billboards
|
||||||
|
* \param positionPtr Position of the billboards
|
||||||
|
* \param sizePtr Size of the billboards
|
||||||
|
* \param sinCosPtr Rotation of the billboards if null, Vector2f(0.f, 1.f) is used
|
||||||
|
* \param alphaPtr Alpha parameters of the billboards if null, 1.f is used
|
||||||
|
*
|
||||||
|
* \remark Produces a NazaraAssert if material is invalid
|
||||||
|
*/
|
||||||
|
|
||||||
void ForwardRenderQueue::AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr<const Vector3f> positionPtr, SparsePtr<const float> sizePtr, SparsePtr<const Vector2f> sinCosPtr, SparsePtr<const float> alphaPtr)
|
void ForwardRenderQueue::AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr<const Vector3f> positionPtr, SparsePtr<const float> sizePtr, SparsePtr<const Vector2f> sinCosPtr, SparsePtr<const float> alphaPtr)
|
||||||
{
|
{
|
||||||
NazaraAssert(material, "Invalid material");
|
NazaraAssert(material, "Invalid material");
|
||||||
|
|
||||||
///DOC: sinCosPtr et alphaPtr peuvent être nuls, ils seront remplacés respectivement par Vector2f(0.f, 1.f) et Color::White
|
|
||||||
Vector2f defaultSinCos(0.f, 1.f); // sin(0) = 0, cos(0) = 1
|
Vector2f defaultSinCos(0.f, 1.f); // sin(0) = 0, cos(0) = 1
|
||||||
|
|
||||||
if (!sinCosPtr)
|
if (!sinCosPtr)
|
||||||
sinCosPtr.Reset(&defaultSinCos, 0); // L'astuce ici est de mettre le stride sur zéro, rendant le pointeur immobile
|
sinCosPtr.Reset(&defaultSinCos, 0); // The trick here is to put the stride to zero, which leads the pointer to be immobile
|
||||||
|
|
||||||
float defaultAlpha = 1.f;
|
float defaultAlpha = 1.f;
|
||||||
|
|
||||||
if (!alphaPtr)
|
if (!alphaPtr)
|
||||||
alphaPtr.Reset(&defaultAlpha, 0); // Pareil
|
alphaPtr.Reset(&defaultAlpha, 0); // Same
|
||||||
|
|
||||||
auto& billboards = GetLayer(renderOrder).billboards;
|
BillboardData* billboardData = GetBillboardData(renderOrder, material, count);
|
||||||
|
|
||||||
auto it = billboards.find(material);
|
|
||||||
if (it == billboards.end())
|
|
||||||
{
|
|
||||||
BatchedBillboardEntry entry;
|
|
||||||
entry.materialReleaseSlot.Connect(material->OnMaterialRelease, this, &ForwardRenderQueue::OnMaterialInvalidation);
|
|
||||||
|
|
||||||
it = billboards.insert(std::make_pair(material, std::move(entry))).first;
|
|
||||||
}
|
|
||||||
|
|
||||||
BatchedBillboardEntry& entry = it->second;
|
|
||||||
|
|
||||||
auto& billboardVector = entry.billboards;
|
|
||||||
unsigned int prevSize = billboardVector.size();
|
|
||||||
billboardVector.resize(prevSize + count);
|
|
||||||
|
|
||||||
BillboardData* billboardData = &billboardVector[prevSize];
|
|
||||||
for (unsigned int i = 0; i < count; ++i)
|
for (unsigned int i = 0; i < count; ++i)
|
||||||
{
|
{
|
||||||
billboardData->center = *positionPtr++;
|
billboardData->center = *positionPtr++;
|
||||||
|
|
@ -292,37 +287,33 @@ namespace Nz
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Adds multiple billboards to the queue
|
||||||
|
*
|
||||||
|
* \param renderOrder Order of rendering
|
||||||
|
* \param material Material of the billboards
|
||||||
|
* \param count Number of billboards
|
||||||
|
* \param positionPtr Position of the billboards
|
||||||
|
* \param sizePtr Size of the billboards
|
||||||
|
* \param anglePtr Rotation of the billboards if null, 0.f is used
|
||||||
|
* \param colorPtr Color of the billboards if null, Color::White is used
|
||||||
|
*
|
||||||
|
* \remark Produces a NazaraAssert if material is invalid
|
||||||
|
*/
|
||||||
|
|
||||||
void ForwardRenderQueue::AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr<const Vector3f> positionPtr, SparsePtr<const float> sizePtr, SparsePtr<const float> anglePtr, SparsePtr<const Color> colorPtr)
|
void ForwardRenderQueue::AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr<const Vector3f> positionPtr, SparsePtr<const float> sizePtr, SparsePtr<const float> anglePtr, SparsePtr<const Color> colorPtr)
|
||||||
{
|
{
|
||||||
NazaraAssert(material, "Invalid material");
|
NazaraAssert(material, "Invalid material");
|
||||||
|
|
||||||
///DOC: sinCosPtr et colorPtr peuvent être nuls, ils seront remplacés respectivement par Vector2f(0.f, 1.f) et Color::White
|
|
||||||
float defaultRotation = 0.f;
|
float defaultRotation = 0.f;
|
||||||
|
|
||||||
if (!anglePtr)
|
if (!anglePtr)
|
||||||
anglePtr.Reset(&defaultRotation, 0); // L'astuce ici est de mettre le stride sur zéro, rendant le pointeur immobile
|
anglePtr.Reset(&defaultRotation, 0); // The trick here is to put the stride to zero, which leads the pointer to be immobile
|
||||||
|
|
||||||
if (!colorPtr)
|
if (!colorPtr)
|
||||||
colorPtr.Reset(&Color::White, 0); // Pareil
|
colorPtr.Reset(&Color::White, 0); // Same
|
||||||
|
|
||||||
auto& billboards = GetLayer(renderOrder).billboards;
|
BillboardData* billboardData = GetBillboardData(renderOrder, material, count);
|
||||||
|
|
||||||
auto it = billboards.find(material);
|
|
||||||
if (it == billboards.end())
|
|
||||||
{
|
|
||||||
BatchedBillboardEntry entry;
|
|
||||||
entry.materialReleaseSlot.Connect(material->OnMaterialRelease, this, &ForwardRenderQueue::OnMaterialInvalidation);
|
|
||||||
|
|
||||||
it = billboards.insert(std::make_pair(material, std::move(entry))).first;
|
|
||||||
}
|
|
||||||
|
|
||||||
BatchedBillboardEntry& entry = it->second;
|
|
||||||
|
|
||||||
auto& billboardVector = entry.billboards;
|
|
||||||
unsigned int prevSize = billboardVector.size();
|
|
||||||
billboardVector.resize(prevSize + count);
|
|
||||||
|
|
||||||
BillboardData* billboardData = &billboardVector[prevSize];
|
|
||||||
for (unsigned int i = 0; i < count; ++i)
|
for (unsigned int i = 0; i < count; ++i)
|
||||||
{
|
{
|
||||||
float sin = std::sin(ToRadians(*anglePtr));
|
float sin = std::sin(ToRadians(*anglePtr));
|
||||||
|
|
@ -337,39 +328,35 @@ namespace Nz
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Adds multiple billboards to the queue
|
||||||
|
*
|
||||||
|
* \param renderOrder Order of rendering
|
||||||
|
* \param material Material of the billboards
|
||||||
|
* \param count Number of billboards
|
||||||
|
* \param positionPtr Position of the billboards
|
||||||
|
* \param sizePtr Size of the billboards
|
||||||
|
* \param anglePtr Rotation of the billboards if null, 0.f is used
|
||||||
|
* \param alphaPtr Alpha parameters of the billboards if null, 1.f is used
|
||||||
|
*
|
||||||
|
* \remark Produces a NazaraAssert if material is invalid
|
||||||
|
*/
|
||||||
|
|
||||||
void ForwardRenderQueue::AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr<const Vector3f> positionPtr, SparsePtr<const float> sizePtr, SparsePtr<const float> anglePtr, SparsePtr<const float> alphaPtr)
|
void ForwardRenderQueue::AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr<const Vector3f> positionPtr, SparsePtr<const float> sizePtr, SparsePtr<const float> anglePtr, SparsePtr<const float> alphaPtr)
|
||||||
{
|
{
|
||||||
NazaraAssert(material, "Invalid material");
|
NazaraAssert(material, "Invalid material");
|
||||||
|
|
||||||
///DOC: sinCosPtr et alphaPtr peuvent être nuls, ils seront remplacés respectivement par Vector2f(0.f, 1.f) et Color::White
|
|
||||||
float defaultRotation = 0.f;
|
float defaultRotation = 0.f;
|
||||||
|
|
||||||
if (!anglePtr)
|
if (!anglePtr)
|
||||||
anglePtr.Reset(&defaultRotation, 0); // L'astuce ici est de mettre le stride sur zéro, rendant le pointeur immobile
|
anglePtr.Reset(&defaultRotation, 0); // The trick here is to put the stride to zero, which leads the pointer to be immobile
|
||||||
|
|
||||||
float defaultAlpha = 1.f;
|
float defaultAlpha = 1.f;
|
||||||
|
|
||||||
if (!alphaPtr)
|
if (!alphaPtr)
|
||||||
alphaPtr.Reset(&defaultAlpha, 0); // Pareil
|
alphaPtr.Reset(&defaultAlpha, 0); // Same
|
||||||
|
|
||||||
auto& billboards = GetLayer(renderOrder).billboards;
|
BillboardData* billboardData = GetBillboardData(renderOrder, material, count);
|
||||||
|
|
||||||
auto it = billboards.find(material);
|
|
||||||
if (it == billboards.end())
|
|
||||||
{
|
|
||||||
BatchedBillboardEntry entry;
|
|
||||||
entry.materialReleaseSlot.Connect(material->OnMaterialRelease, this, &ForwardRenderQueue::OnMaterialInvalidation);
|
|
||||||
|
|
||||||
it = billboards.insert(std::make_pair(material, std::move(entry))).first;
|
|
||||||
}
|
|
||||||
|
|
||||||
BatchedBillboardEntry& entry = it->second;
|
|
||||||
|
|
||||||
auto& billboardVector = entry.billboards;
|
|
||||||
unsigned int prevSize = billboardVector.size();
|
|
||||||
billboardVector.resize(prevSize + count);
|
|
||||||
|
|
||||||
BillboardData* billboardData = &billboardVector[prevSize];
|
|
||||||
for (unsigned int i = 0; i < count; ++i)
|
for (unsigned int i = 0; i < count; ++i)
|
||||||
{
|
{
|
||||||
float sin = std::sin(ToRadians(*anglePtr));
|
float sin = std::sin(ToRadians(*anglePtr));
|
||||||
|
|
@ -384,6 +371,15 @@ namespace Nz
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Adds drawable to the queue
|
||||||
|
*
|
||||||
|
* \param renderOrder Order of rendering
|
||||||
|
* \param drawable Drawable user defined
|
||||||
|
*
|
||||||
|
* \remark Produces a NazaraError if drawable is invalid
|
||||||
|
*/
|
||||||
|
|
||||||
void ForwardRenderQueue::AddDrawable(int renderOrder, const Drawable* drawable)
|
void ForwardRenderQueue::AddDrawable(int renderOrder, const Drawable* drawable)
|
||||||
{
|
{
|
||||||
#if NAZARA_GRAPHICS_SAFE
|
#if NAZARA_GRAPHICS_SAFE
|
||||||
|
|
@ -399,15 +395,29 @@ namespace Nz
|
||||||
otherDrawables.push_back(drawable);
|
otherDrawables.push_back(drawable);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Adds mesh to the queue
|
||||||
|
*
|
||||||
|
* \param renderOrder Order of rendering
|
||||||
|
* \param material Material of the mesh
|
||||||
|
* \param meshData Data of the mesh
|
||||||
|
* \param meshAABB Box of the mesh
|
||||||
|
* \param transformMatrix Matrix of the mesh
|
||||||
|
*
|
||||||
|
* \remark Produces a NazaraAssert if material is invalid
|
||||||
|
*/
|
||||||
|
|
||||||
void ForwardRenderQueue::AddMesh(int renderOrder, const Material* material, const MeshData& meshData, const Boxf& meshAABB, const Matrix4f& transformMatrix)
|
void ForwardRenderQueue::AddMesh(int renderOrder, const Material* material, const MeshData& meshData, const Boxf& meshAABB, const Matrix4f& transformMatrix)
|
||||||
{
|
{
|
||||||
|
NazaraAssert(material, "Invalid material");
|
||||||
|
|
||||||
if (material->IsEnabled(RendererParameter_Blend))
|
if (material->IsEnabled(RendererParameter_Blend))
|
||||||
{
|
{
|
||||||
Layer& currentLayer = GetLayer(renderOrder);
|
Layer& currentLayer = GetLayer(renderOrder);
|
||||||
auto& transparentModels = currentLayer.transparentModels;
|
auto& transparentModels = currentLayer.transparentModels;
|
||||||
auto& transparentModelData = currentLayer.transparentModelData;
|
auto& transparentModelData = currentLayer.transparentModelData;
|
||||||
|
|
||||||
// Le matériau est transparent, nous devons rendre ce mesh d'une autre façon (après le rendu des objets opaques et en les triant)
|
// The material is transparent, we must draw this mesh using another way (after the rendering of opages objects while sorting them)
|
||||||
unsigned int index = transparentModelData.size();
|
unsigned int index = transparentModelData.size();
|
||||||
transparentModelData.resize(index+1);
|
transparentModelData.resize(index+1);
|
||||||
|
|
||||||
|
|
@ -455,14 +465,28 @@ namespace Nz
|
||||||
std::vector<Matrix4f>& instances = it2->second.instances;
|
std::vector<Matrix4f>& instances = it2->second.instances;
|
||||||
instances.push_back(transformMatrix);
|
instances.push_back(transformMatrix);
|
||||||
|
|
||||||
// Avons-nous suffisamment d'instances pour que le coût d'utilisation de l'instancing soit payé ?
|
// Do we have enough instances to perform instancing ?
|
||||||
if (instances.size() >= NAZARA_GRAPHICS_INSTANCING_MIN_INSTANCES_COUNT)
|
if (instances.size() >= NAZARA_GRAPHICS_INSTANCING_MIN_INSTANCES_COUNT)
|
||||||
entry.instancingEnabled = true; // Apparemment oui, activons l'instancing avec ce matériau
|
entry.instancingEnabled = true; // Thus we can activate it
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Adds sprites to the queue
|
||||||
|
*
|
||||||
|
* \param renderOrder Order of rendering
|
||||||
|
* \param material Material of the sprites
|
||||||
|
* \param vertices Buffer of data for the sprites
|
||||||
|
* \param spriteCount Number of sprites
|
||||||
|
* \param overlay Texture of the sprites
|
||||||
|
*
|
||||||
|
* \remark Produces a NazaraAssert if material is invalid
|
||||||
|
*/
|
||||||
|
|
||||||
void ForwardRenderQueue::AddSprites(int renderOrder, const Material* material, const VertexStruct_XYZ_Color_UV* vertices, unsigned int spriteCount, const Texture* overlay)
|
void ForwardRenderQueue::AddSprites(int renderOrder, const Material* material, const VertexStruct_XYZ_Color_UV* vertices, unsigned int spriteCount, const Texture* overlay)
|
||||||
{
|
{
|
||||||
|
NazaraAssert(material, "Invalid material");
|
||||||
|
|
||||||
Layer& currentLayer = GetLayer(renderOrder);
|
Layer& currentLayer = GetLayer(renderOrder);
|
||||||
auto& basicSprites = currentLayer.basicSprites;
|
auto& basicSprites = currentLayer.basicSprites;
|
||||||
|
|
||||||
|
|
@ -494,6 +518,12 @@ namespace Nz
|
||||||
spriteVector.push_back(SpriteChain_XYZ_Color_UV({vertices, spriteCount}));
|
spriteVector.push_back(SpriteChain_XYZ_Color_UV({vertices, spriteCount}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Clears the queue
|
||||||
|
*
|
||||||
|
* \param fully Should everything be cleared or we can keep layers
|
||||||
|
*/
|
||||||
|
|
||||||
void ForwardRenderQueue::Clear(bool fully)
|
void ForwardRenderQueue::Clear(bool fully)
|
||||||
{
|
{
|
||||||
AbstractRenderQueue::Clear(fully);
|
AbstractRenderQueue::Clear(fully);
|
||||||
|
|
@ -518,15 +548,21 @@ namespace Nz
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Sorts the object according to the viewer position, furthest to nearest
|
||||||
|
*
|
||||||
|
* \param viewer Viewer of the scene
|
||||||
|
*/
|
||||||
|
|
||||||
void ForwardRenderQueue::Sort(const AbstractViewer* viewer)
|
void ForwardRenderQueue::Sort(const AbstractViewer* viewer)
|
||||||
{
|
{
|
||||||
Planef nearPlane = viewer->GetFrustum().GetPlane(FrustumPlane_Near);
|
Planef nearPlane = viewer->GetFrustum().GetPlane(FrustumPlane_Near);
|
||||||
Vector3f viewerPos = viewer->GetEyePosition();
|
Vector3f viewerPos = viewer->GetEyePosition();
|
||||||
Vector3f viewerNormal = viewer->GetForward();
|
Vector3f viewerNormal = viewer->GetForward();
|
||||||
|
|
||||||
for (auto& layerPair : layers)
|
for (auto& pair : layers)
|
||||||
{
|
{
|
||||||
Layer& layer = layerPair.second;
|
Layer& layer = pair.second;
|
||||||
|
|
||||||
std::sort(layer.transparentModels.begin(), layer.transparentModels.end(), [&layer, &nearPlane, &viewerNormal] (unsigned int index1, unsigned int index2)
|
std::sort(layer.transparentModels.begin(), layer.transparentModels.end(), [&layer, &nearPlane, &viewerNormal] (unsigned int index1, unsigned int index2)
|
||||||
{
|
{
|
||||||
|
|
@ -557,6 +593,43 @@ namespace Nz
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Gets the billboard data
|
||||||
|
* \return Pointer to the data of the billboards
|
||||||
|
*
|
||||||
|
* \param renderOrder Order of rendering
|
||||||
|
* \param material Material of the billboard
|
||||||
|
*/
|
||||||
|
|
||||||
|
ForwardRenderQueue::BillboardData* ForwardRenderQueue::GetBillboardData(int renderOrder, const Material* material, unsigned int count)
|
||||||
|
{
|
||||||
|
auto& billboards = GetLayer(renderOrder).billboards;
|
||||||
|
|
||||||
|
auto it = billboards.find(material);
|
||||||
|
if (it == billboards.end())
|
||||||
|
{
|
||||||
|
BatchedBillboardEntry entry;
|
||||||
|
entry.materialReleaseSlot.Connect(material->OnMaterialRelease, this, &ForwardRenderQueue::OnMaterialInvalidation);
|
||||||
|
|
||||||
|
it = billboards.insert(std::make_pair(material, std::move(entry))).first;
|
||||||
|
}
|
||||||
|
|
||||||
|
BatchedBillboardEntry& entry = it->second;
|
||||||
|
|
||||||
|
auto& billboardVector = entry.billboards;
|
||||||
|
unsigned int prevSize = billboardVector.size();
|
||||||
|
billboardVector.resize(prevSize + count);
|
||||||
|
|
||||||
|
return &billboardVector[prevSize];
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Gets the ith layer
|
||||||
|
* \return Reference to the ith layer for the queue
|
||||||
|
*
|
||||||
|
* \param i Index of the layer
|
||||||
|
*/
|
||||||
|
|
||||||
ForwardRenderQueue::Layer& ForwardRenderQueue::GetLayer(int i)
|
ForwardRenderQueue::Layer& ForwardRenderQueue::GetLayer(int i)
|
||||||
{
|
{
|
||||||
auto it = layers.find(i);
|
auto it = layers.find(i);
|
||||||
|
|
@ -569,6 +642,12 @@ namespace Nz
|
||||||
return layer;
|
return layer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Handle the invalidation of an index buffer
|
||||||
|
*
|
||||||
|
* \param indexBuffer Index buffer being invalidated
|
||||||
|
*/
|
||||||
|
|
||||||
void ForwardRenderQueue::OnIndexBufferInvalidation(const IndexBuffer* indexBuffer)
|
void ForwardRenderQueue::OnIndexBufferInvalidation(const IndexBuffer* indexBuffer)
|
||||||
{
|
{
|
||||||
for (auto& pair : layers)
|
for (auto& pair : layers)
|
||||||
|
|
@ -590,6 +669,12 @@ namespace Nz
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Handle the invalidation of a material
|
||||||
|
*
|
||||||
|
* \param material Material being invalidated
|
||||||
|
*/
|
||||||
|
|
||||||
void ForwardRenderQueue::OnMaterialInvalidation(const Material* material)
|
void ForwardRenderQueue::OnMaterialInvalidation(const Material* material)
|
||||||
{
|
{
|
||||||
for (auto& pair : layers)
|
for (auto& pair : layers)
|
||||||
|
|
@ -602,6 +687,12 @@ namespace Nz
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Handle the invalidation of a texture
|
||||||
|
*
|
||||||
|
* \param texture Texture being invalidated
|
||||||
|
*/
|
||||||
|
|
||||||
void ForwardRenderQueue::OnTextureInvalidation(const Texture* texture)
|
void ForwardRenderQueue::OnTextureInvalidation(const Texture* texture)
|
||||||
{
|
{
|
||||||
for (auto& pair : layers)
|
for (auto& pair : layers)
|
||||||
|
|
@ -615,6 +706,12 @@ namespace Nz
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Handle the invalidation of a vertex buffer
|
||||||
|
*
|
||||||
|
* \param vertexBuffer Vertex buffer being invalidated
|
||||||
|
*/
|
||||||
|
|
||||||
void ForwardRenderQueue::OnVertexBufferInvalidation(const VertexBuffer* vertexBuffer)
|
void ForwardRenderQueue::OnVertexBufferInvalidation(const VertexBuffer* vertexBuffer)
|
||||||
{
|
{
|
||||||
for (auto& pair : layers)
|
for (auto& pair : layers)
|
||||||
|
|
@ -635,6 +732,14 @@ namespace Nz
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Functor to compare two batched billboard with material
|
||||||
|
* \return true If first material is "smaller" than the second one
|
||||||
|
*
|
||||||
|
* \param mat1 First material to compare
|
||||||
|
* \param mat2 Second material to compare
|
||||||
|
*/
|
||||||
|
|
||||||
bool ForwardRenderQueue::BatchedBillboardComparator::operator()(const Material* mat1, const Material* mat2) const
|
bool ForwardRenderQueue::BatchedBillboardComparator::operator()(const Material* mat1, const Material* mat2) const
|
||||||
{
|
{
|
||||||
const UberShader* uberShader1 = mat1->GetShader();
|
const UberShader* uberShader1 = mat1->GetShader();
|
||||||
|
|
@ -655,6 +760,14 @@ namespace Nz
|
||||||
return mat1 < mat2;
|
return mat1 < mat2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Functor to compare two batched model with material
|
||||||
|
* \return true If first material is "smaller" than the second one
|
||||||
|
*
|
||||||
|
* \param mat1 First material to compare
|
||||||
|
* \param mat2 Second material to compare
|
||||||
|
*/
|
||||||
|
|
||||||
bool ForwardRenderQueue::BatchedModelMaterialComparator::operator()(const Material* mat1, const Material* mat2) const
|
bool ForwardRenderQueue::BatchedModelMaterialComparator::operator()(const Material* mat1, const Material* mat2) const
|
||||||
{
|
{
|
||||||
const UberShader* uberShader1 = mat1->GetShader();
|
const UberShader* uberShader1 = mat1->GetShader();
|
||||||
|
|
@ -675,6 +788,14 @@ namespace Nz
|
||||||
return mat1 < mat2;
|
return mat1 < mat2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Functor to compare two batched sprites with material
|
||||||
|
* \return true If first material is "smaller" than the second one
|
||||||
|
*
|
||||||
|
* \param mat1 First material to compare
|
||||||
|
* \param mat2 Second material to compare
|
||||||
|
*/
|
||||||
|
|
||||||
bool ForwardRenderQueue::BatchedSpriteMaterialComparator::operator()(const Material* mat1, const Material* mat2)
|
bool ForwardRenderQueue::BatchedSpriteMaterialComparator::operator()(const Material* mat1, const Material* mat2)
|
||||||
{
|
{
|
||||||
const UberShader* uberShader1 = mat1->GetShader();
|
const UberShader* uberShader1 = mat1->GetShader();
|
||||||
|
|
@ -695,6 +816,14 @@ namespace Nz
|
||||||
return mat1 < mat2;
|
return mat1 < mat2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Functor to compare two mesh data
|
||||||
|
* \return true If first mesh is "smaller" than the second one
|
||||||
|
*
|
||||||
|
* \param data1 First mesh to compare
|
||||||
|
* \param data2 Second mesh to compare
|
||||||
|
*/
|
||||||
|
|
||||||
bool ForwardRenderQueue::MeshDataComparator::operator()(const MeshData& data1, const MeshData& data2) const
|
bool ForwardRenderQueue::MeshDataComparator::operator()(const MeshData& data1, const MeshData& data2) const
|
||||||
{
|
{
|
||||||
const Buffer* buffer1;
|
const Buffer* buffer1;
|
||||||
|
|
|
||||||
|
|
@ -37,6 +37,16 @@ namespace Nz
|
||||||
unsigned int s_vertexBufferSize = 4 * 1024 * 1024; // 4 MiB
|
unsigned int s_vertexBufferSize = 4 * 1024 * 1024; // 4 MiB
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \ingroup graphics
|
||||||
|
* \class Nz::ForwardRenderTechnique
|
||||||
|
* \brief Graphics class that represents the technique used in forward rendering
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Constructs a ForwardRenderTechnique object by default
|
||||||
|
*/
|
||||||
|
|
||||||
ForwardRenderTechnique::ForwardRenderTechnique() :
|
ForwardRenderTechnique::ForwardRenderTechnique() :
|
||||||
m_vertexBuffer(BufferType_Vertex),
|
m_vertexBuffer(BufferType_Vertex),
|
||||||
m_maxLightPassPerObject(3)
|
m_maxLightPassPerObject(3)
|
||||||
|
|
@ -49,6 +59,12 @@ namespace Nz
|
||||||
m_spriteBuffer.Reset(VertexDeclaration::Get(VertexLayout_XYZ_Color_UV), &m_vertexBuffer);
|
m_spriteBuffer.Reset(VertexDeclaration::Get(VertexLayout_XYZ_Color_UV), &m_vertexBuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Clears the data
|
||||||
|
*
|
||||||
|
* \param sceneData Data of the scene
|
||||||
|
*/
|
||||||
|
|
||||||
void ForwardRenderTechnique::Clear(const SceneData& sceneData) const
|
void ForwardRenderTechnique::Clear(const SceneData& sceneData) const
|
||||||
{
|
{
|
||||||
Renderer::Enable(RendererParameter_DepthBuffer, true);
|
Renderer::Enable(RendererParameter_DepthBuffer, true);
|
||||||
|
|
@ -59,6 +75,15 @@ namespace Nz
|
||||||
sceneData.background->Draw(sceneData.viewer);
|
sceneData.background->Draw(sceneData.viewer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Draws the data of the scene
|
||||||
|
* \return true If successful
|
||||||
|
*
|
||||||
|
* \param sceneData Data of the scene
|
||||||
|
*
|
||||||
|
* \remark Produces a NazaraAssert if viewer of the scene is invalid
|
||||||
|
*/
|
||||||
|
|
||||||
bool ForwardRenderTechnique::Draw(const SceneData& sceneData) const
|
bool ForwardRenderTechnique::Draw(const SceneData& sceneData) const
|
||||||
{
|
{
|
||||||
NazaraAssert(sceneData.viewer, "Invalid viewer");
|
NazaraAssert(sceneData.viewer, "Invalid viewer");
|
||||||
|
|
@ -88,26 +113,54 @@ namespace Nz
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Gets the maximum number of lights available per pass per object
|
||||||
|
* \return Maximum number of light simulatenously per object
|
||||||
|
*/
|
||||||
|
|
||||||
unsigned int ForwardRenderTechnique::GetMaxLightPassPerObject() const
|
unsigned int ForwardRenderTechnique::GetMaxLightPassPerObject() const
|
||||||
{
|
{
|
||||||
return m_maxLightPassPerObject;
|
return m_maxLightPassPerObject;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Gets the render queue
|
||||||
|
* \return Pointer to the render queue
|
||||||
|
*/
|
||||||
|
|
||||||
AbstractRenderQueue* ForwardRenderTechnique::GetRenderQueue()
|
AbstractRenderQueue* ForwardRenderTechnique::GetRenderQueue()
|
||||||
{
|
{
|
||||||
return &m_renderQueue;
|
return &m_renderQueue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Gets the type of the current technique
|
||||||
|
* \return Type of the render technique
|
||||||
|
*/
|
||||||
|
|
||||||
RenderTechniqueType ForwardRenderTechnique::GetType() const
|
RenderTechniqueType ForwardRenderTechnique::GetType() const
|
||||||
{
|
{
|
||||||
return RenderTechniqueType_BasicForward;
|
return RenderTechniqueType_BasicForward;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ForwardRenderTechnique::SetMaxLightPassPerObject(unsigned int passCount)
|
/*!
|
||||||
|
* \brief Sets the maximum number of lights available per pass per object
|
||||||
|
*
|
||||||
|
* \param passCount Maximum number of light simulatenously per object
|
||||||
|
*/
|
||||||
|
|
||||||
|
void ForwardRenderTechnique::SetMaxLightPassPerObject(unsigned int maxLightPassPerObject)
|
||||||
{
|
{
|
||||||
m_maxLightPassPerObject = passCount;
|
m_maxLightPassPerObject = maxLightPassPerObject;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Initializes the forward render technique
|
||||||
|
* \return true If successful
|
||||||
|
*
|
||||||
|
* \remark Produces a NazaraError if one shader creation failed
|
||||||
|
*/
|
||||||
|
|
||||||
bool ForwardRenderTechnique::Initialize()
|
bool ForwardRenderTechnique::Initialize()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
|
@ -130,10 +183,10 @@ namespace Nz
|
||||||
*indices++ = i * 4 + 1;
|
*indices++ = i * 4 + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
mapper.Unmap(); // Inutile de garder le buffer ouvert plus longtemps
|
mapper.Unmap(); // No point to keep the buffer open any longer
|
||||||
|
|
||||||
// Quad buffer (utilisé pour l'instancing de billboard et de sprites)
|
// Quad buffer (used for instancing of billboards and sprites)
|
||||||
//Note: Les UV sont calculés dans le shader
|
//Note: UV are computed in the shader
|
||||||
s_quadVertexBuffer.Reset(VertexDeclaration::Get(VertexLayout_XY), 4, DataStorage_Hardware, BufferUsage_Static);
|
s_quadVertexBuffer.Reset(VertexDeclaration::Get(VertexLayout_XY), 4, DataStorage_Hardware, BufferUsage_Static);
|
||||||
|
|
||||||
float vertices[2 * 4] = {
|
float vertices[2 * 4] = {
|
||||||
|
|
@ -145,14 +198,14 @@ namespace Nz
|
||||||
|
|
||||||
s_quadVertexBuffer.FillRaw(vertices, 0, sizeof(vertices));
|
s_quadVertexBuffer.FillRaw(vertices, 0, sizeof(vertices));
|
||||||
|
|
||||||
// Déclaration lors du rendu des billboards par sommet
|
// Declaration used when rendering the vertex billboards
|
||||||
s_billboardVertexDeclaration.EnableComponent(VertexComponent_Color, ComponentType_Color, NazaraOffsetOf(BillboardPoint, color));
|
s_billboardVertexDeclaration.EnableComponent(VertexComponent_Color, ComponentType_Color, NazaraOffsetOf(BillboardPoint, color));
|
||||||
s_billboardVertexDeclaration.EnableComponent(VertexComponent_Position, ComponentType_Float3, NazaraOffsetOf(BillboardPoint, position));
|
s_billboardVertexDeclaration.EnableComponent(VertexComponent_Position, ComponentType_Float3, NazaraOffsetOf(BillboardPoint, position));
|
||||||
s_billboardVertexDeclaration.EnableComponent(VertexComponent_TexCoord, ComponentType_Float2, NazaraOffsetOf(BillboardPoint, uv));
|
s_billboardVertexDeclaration.EnableComponent(VertexComponent_TexCoord, ComponentType_Float2, NazaraOffsetOf(BillboardPoint, uv));
|
||||||
s_billboardVertexDeclaration.EnableComponent(VertexComponent_Userdata0, ComponentType_Float4, NazaraOffsetOf(BillboardPoint, size)); // Englobe sincos
|
s_billboardVertexDeclaration.EnableComponent(VertexComponent_Userdata0, ComponentType_Float4, NazaraOffsetOf(BillboardPoint, size)); // Includes sincos
|
||||||
|
|
||||||
// Declaration utilisée lors du rendu des billboards par instancing
|
// Declaration used when rendering the billboards with intancing
|
||||||
// L'avantage ici est la copie directe (std::memcpy) des données de la RenderQueue vers le buffer GPU
|
// The main advantage is the direct copy (std::memcpy) of data in the RenderQueue to the GPU buffer
|
||||||
s_billboardInstanceDeclaration.EnableComponent(VertexComponent_InstanceData0, ComponentType_Float3, NazaraOffsetOf(ForwardRenderQueue::BillboardData, center));
|
s_billboardInstanceDeclaration.EnableComponent(VertexComponent_InstanceData0, ComponentType_Float3, NazaraOffsetOf(ForwardRenderQueue::BillboardData, center));
|
||||||
s_billboardInstanceDeclaration.EnableComponent(VertexComponent_InstanceData1, ComponentType_Float4, NazaraOffsetOf(ForwardRenderQueue::BillboardData, size)); // Englobe sincos
|
s_billboardInstanceDeclaration.EnableComponent(VertexComponent_InstanceData1, ComponentType_Float4, NazaraOffsetOf(ForwardRenderQueue::BillboardData, size)); // Englobe sincos
|
||||||
s_billboardInstanceDeclaration.EnableComponent(VertexComponent_InstanceData2, ComponentType_Color, NazaraOffsetOf(ForwardRenderQueue::BillboardData, color));
|
s_billboardInstanceDeclaration.EnableComponent(VertexComponent_InstanceData2, ComponentType_Color, NazaraOffsetOf(ForwardRenderQueue::BillboardData, color));
|
||||||
|
|
@ -169,12 +222,23 @@ namespace Nz
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Uninitializes the forward render technique
|
||||||
|
*/
|
||||||
|
|
||||||
void ForwardRenderTechnique::Uninitialize()
|
void ForwardRenderTechnique::Uninitialize()
|
||||||
{
|
{
|
||||||
s_quadIndexBuffer.Reset();
|
s_quadIndexBuffer.Reset();
|
||||||
s_quadVertexBuffer.Reset();
|
s_quadVertexBuffer.Reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Chooses the nearest lights for one object
|
||||||
|
*
|
||||||
|
* \param object Sphere symbolising the object
|
||||||
|
* \param includeDirectionalLights Should directional lights be included in the computation
|
||||||
|
*/
|
||||||
|
|
||||||
void ForwardRenderTechnique::ChooseLights(const Spheref& object, bool includeDirectionalLights) const
|
void ForwardRenderTechnique::ChooseLights(const Spheref& object, bool includeDirectionalLights) const
|
||||||
{
|
{
|
||||||
m_lights.clear();
|
m_lights.clear();
|
||||||
|
|
@ -213,6 +277,15 @@ namespace Nz
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Draws basic sprites
|
||||||
|
*
|
||||||
|
* \param sceneData Data of the scene
|
||||||
|
* \param layer Layer of the rendering
|
||||||
|
*
|
||||||
|
* \remark Produces a NazaraAssert is viewer is invalid
|
||||||
|
*/
|
||||||
|
|
||||||
void ForwardRenderTechnique::DrawBasicSprites(const SceneData& sceneData, ForwardRenderQueue::Layer& layer) const
|
void ForwardRenderTechnique::DrawBasicSprites(const SceneData& sceneData, ForwardRenderQueue::Layer& layer) const
|
||||||
{
|
{
|
||||||
NazaraAssert(sceneData.viewer, "Invalid viewer");
|
NazaraAssert(sceneData.viewer, "Invalid viewer");
|
||||||
|
|
@ -240,7 +313,7 @@ namespace Nz
|
||||||
unsigned int spriteChainCount = spriteChainVector.size();
|
unsigned int spriteChainCount = spriteChainVector.size();
|
||||||
if (spriteChainCount > 0)
|
if (spriteChainCount > 0)
|
||||||
{
|
{
|
||||||
// On commence par appliquer du matériau (et récupérer le shader ainsi activé)
|
// We begin to apply the material (and get the shader activated doing so)
|
||||||
UInt32 flags = ShaderFlags_VertexColor;
|
UInt32 flags = ShaderFlags_VertexColor;
|
||||||
if (overlay)
|
if (overlay)
|
||||||
flags |= ShaderFlags_TextureOverlay;
|
flags |= ShaderFlags_TextureOverlay;
|
||||||
|
|
@ -255,28 +328,28 @@ namespace Nz
|
||||||
Renderer::SetTextureSampler(overlayUnit, material->GetDiffuseSampler());
|
Renderer::SetTextureSampler(overlayUnit, material->GetDiffuseSampler());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Les uniformes sont conservées au sein d'un programme, inutile de les renvoyer tant qu'il ne change pas
|
// Uniforms are conserved in our program, there's no point to send them back until they change
|
||||||
if (shader != lastShader)
|
if (shader != lastShader)
|
||||||
{
|
{
|
||||||
// Index des uniformes dans le shader
|
// Index of uniforms in the shader
|
||||||
shaderUniforms = GetShaderUniforms(shader);
|
shaderUniforms = GetShaderUniforms(shader);
|
||||||
|
|
||||||
// Couleur ambiante de la scène
|
// Ambiant color of the scene
|
||||||
shader->SendColor(shaderUniforms->sceneAmbient, sceneData.ambientColor);
|
shader->SendColor(shaderUniforms->sceneAmbient, sceneData.ambientColor);
|
||||||
// Overlay
|
// Overlay
|
||||||
shader->SendInteger(shaderUniforms->textureOverlay, overlayUnit);
|
shader->SendInteger(shaderUniforms->textureOverlay, overlayUnit);
|
||||||
// Position de la caméra
|
// Position of the camera
|
||||||
shader->SendVector(shaderUniforms->eyePosition, sceneData.viewer->GetEyePosition());
|
shader->SendVector(shaderUniforms->eyePosition, sceneData.viewer->GetEyePosition());
|
||||||
|
|
||||||
lastShader = shader;
|
lastShader = shader;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int spriteChain = 0; // Quelle chaîne de sprite traitons-nous
|
unsigned int spriteChain = 0; // Which chain of sprites are we treating
|
||||||
unsigned int spriteChainOffset = 0; // À quel offset dans la dernière chaîne nous sommes-nous arrêtés
|
unsigned int spriteChainOffset = 0; // Where was the last offset where we stopped in the last chain
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
// On ouvre le buffer en écriture
|
// We open the buffer in writing mode
|
||||||
BufferMapper<VertexBuffer> vertexMapper(m_spriteBuffer, BufferAccess_DiscardAndWrite);
|
BufferMapper<VertexBuffer> vertexMapper(m_spriteBuffer, BufferAccess_DiscardAndWrite);
|
||||||
VertexStruct_XYZ_Color_UV* vertices = static_cast<VertexStruct_XYZ_Color_UV*>(vertexMapper.GetPointer());
|
VertexStruct_XYZ_Color_UV* vertices = static_cast<VertexStruct_XYZ_Color_UV*>(vertexMapper.GetPointer());
|
||||||
|
|
||||||
|
|
@ -294,7 +367,7 @@ namespace Nz
|
||||||
spriteCount += count;
|
spriteCount += count;
|
||||||
spriteChainOffset += count;
|
spriteChainOffset += count;
|
||||||
|
|
||||||
// Avons-nous traité la chaîne entière ?
|
// Have we treated the entire chain ?
|
||||||
if (spriteChainOffset == currentChain.spriteCount)
|
if (spriteChainOffset == currentChain.spriteCount)
|
||||||
{
|
{
|
||||||
spriteChain++;
|
spriteChain++;
|
||||||
|
|
@ -313,12 +386,21 @@ namespace Nz
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// On remet à zéro
|
// We set it back to zero
|
||||||
matEntry.enabled = false;
|
matEntry.enabled = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Draws billboards
|
||||||
|
*
|
||||||
|
* \param sceneData Data of the scene
|
||||||
|
* \param layer Layer of the rendering
|
||||||
|
*
|
||||||
|
* \remark Produces a NazaraAssert is viewer is invalid
|
||||||
|
*/
|
||||||
|
|
||||||
void ForwardRenderTechnique::DrawBillboards(const SceneData& sceneData, ForwardRenderQueue::Layer& layer) const
|
void ForwardRenderTechnique::DrawBillboards(const SceneData& sceneData, ForwardRenderQueue::Layer& layer) const
|
||||||
{
|
{
|
||||||
NazaraAssert(sceneData.viewer, "Invalid viewer");
|
NazaraAssert(sceneData.viewer, "Invalid viewer");
|
||||||
|
|
@ -342,18 +424,18 @@ namespace Nz
|
||||||
unsigned int billboardCount = billboardVector.size();
|
unsigned int billboardCount = billboardVector.size();
|
||||||
if (billboardCount > 0)
|
if (billboardCount > 0)
|
||||||
{
|
{
|
||||||
// On commence par appliquer du matériau (et récupérer le shader ainsi activé)
|
// We begin to apply the material (and get the shader activated doing so)
|
||||||
const Shader* shader = material->Apply(ShaderFlags_Billboard | ShaderFlags_Instancing | ShaderFlags_VertexColor);
|
const Shader* shader = material->Apply(ShaderFlags_Billboard | ShaderFlags_Instancing | ShaderFlags_VertexColor);
|
||||||
|
|
||||||
// Les uniformes sont conservées au sein d'un programme, inutile de les renvoyer tant qu'il ne change pas
|
// Uniforms are conserved in our program, there's no point to send them back until they change
|
||||||
if (shader != lastShader)
|
if (shader != lastShader)
|
||||||
{
|
{
|
||||||
// Index des uniformes dans le shader
|
// Index of uniforms in the shader
|
||||||
shaderUniforms = GetShaderUniforms(shader);
|
shaderUniforms = GetShaderUniforms(shader);
|
||||||
|
|
||||||
// Couleur ambiante de la scène
|
// Ambiant color of the scene
|
||||||
shader->SendColor(shaderUniforms->sceneAmbient, sceneData.ambientColor);
|
shader->SendColor(shaderUniforms->sceneAmbient, sceneData.ambientColor);
|
||||||
// Position de la caméra
|
// Position of the camera
|
||||||
shader->SendVector(shaderUniforms->eyePosition, sceneData.viewer->GetEyePosition());
|
shader->SendVector(shaderUniforms->eyePosition, sceneData.viewer->GetEyePosition());
|
||||||
|
|
||||||
lastShader = shader;
|
lastShader = shader;
|
||||||
|
|
@ -391,18 +473,18 @@ namespace Nz
|
||||||
unsigned int billboardCount = billboardVector.size();
|
unsigned int billboardCount = billboardVector.size();
|
||||||
if (billboardCount > 0)
|
if (billboardCount > 0)
|
||||||
{
|
{
|
||||||
// On commence par appliquer du matériau (et récupérer le shader ainsi activé)
|
// We begin to apply the material (and get the shader activated doing so)
|
||||||
const Shader* shader = material->Apply(ShaderFlags_Billboard | ShaderFlags_VertexColor);
|
const Shader* shader = material->Apply(ShaderFlags_Billboard | ShaderFlags_VertexColor);
|
||||||
|
|
||||||
// Les uniformes sont conservées au sein d'un programme, inutile de les renvoyer tant qu'il ne change pas
|
// Uniforms are conserved in our program, there's no point to send them back until they change
|
||||||
if (shader != lastShader)
|
if (shader != lastShader)
|
||||||
{
|
{
|
||||||
// Index des uniformes dans le shader
|
// Index of uniforms in the shader
|
||||||
shaderUniforms = GetShaderUniforms(shader);
|
shaderUniforms = GetShaderUniforms(shader);
|
||||||
|
|
||||||
// Couleur ambiante de la scène
|
// Ambiant color of the scene
|
||||||
shader->SendColor(shaderUniforms->sceneAmbient, sceneData.ambientColor);
|
shader->SendColor(shaderUniforms->sceneAmbient, sceneData.ambientColor);
|
||||||
// Position de la caméra
|
// Position of the camera
|
||||||
shader->SendVector(shaderUniforms->eyePosition, sceneData.viewer->GetEyePosition());
|
shader->SendVector(shaderUniforms->eyePosition, sceneData.viewer->GetEyePosition());
|
||||||
|
|
||||||
lastShader = shader;
|
lastShader = shader;
|
||||||
|
|
@ -464,6 +546,15 @@ namespace Nz
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Draws opaques models
|
||||||
|
*
|
||||||
|
* \param sceneData Data of the scene
|
||||||
|
* \param layer Layer of the rendering
|
||||||
|
*
|
||||||
|
* \remark Produces a NazaraAssert is viewer is invalid
|
||||||
|
*/
|
||||||
|
|
||||||
void ForwardRenderTechnique::DrawOpaqueModels(const SceneData& sceneData, ForwardRenderQueue::Layer& layer) const
|
void ForwardRenderTechnique::DrawOpaqueModels(const SceneData& sceneData, ForwardRenderQueue::Layer& layer) const
|
||||||
{
|
{
|
||||||
NazaraAssert(sceneData.viewer, "Invalid viewer");
|
NazaraAssert(sceneData.viewer, "Invalid viewer");
|
||||||
|
|
@ -483,25 +574,25 @@ namespace Nz
|
||||||
{
|
{
|
||||||
const Material* material = matIt.first;
|
const Material* material = matIt.first;
|
||||||
|
|
||||||
// Nous utilisons de l'instancing que lorsqu'aucune lumière (autre que directionnelle) n'est active
|
// We only use instancing when no light (other than directional) is active
|
||||||
// Ceci car l'instancing n'est pas compatible avec la recherche des lumières les plus proches
|
// This is because instancing is not compatible with the search of nearest lights
|
||||||
// (Le deferred shading n'a pas ce problème)
|
// Deferred shading does not have this problem
|
||||||
bool noPointSpotLight = m_renderQueue.pointLights.empty() && m_renderQueue.spotLights.empty();
|
bool noPointSpotLight = m_renderQueue.pointLights.empty() && m_renderQueue.spotLights.empty();
|
||||||
bool instancing = m_instancingEnabled && (!material->IsLightingEnabled() || noPointSpotLight) && matEntry.instancingEnabled;
|
bool instancing = m_instancingEnabled && (!material->IsLightingEnabled() || noPointSpotLight) && matEntry.instancingEnabled;
|
||||||
|
|
||||||
// On commence par appliquer du matériau (et récupérer le shader ainsi activé)
|
// We begin to apply the material (and get the shader activated doing so)
|
||||||
UInt8 freeTextureUnit;
|
UInt8 freeTextureUnit;
|
||||||
const Shader* shader = material->Apply((instancing) ? ShaderFlags_Instancing : 0, 0, &freeTextureUnit);
|
const Shader* shader = material->Apply((instancing) ? ShaderFlags_Instancing : 0, 0, &freeTextureUnit);
|
||||||
|
|
||||||
// Les uniformes sont conservées au sein d'un programme, inutile de les renvoyer tant qu'il ne change pas
|
// Uniforms are conserved in our program, there's no point to send them back until they change
|
||||||
if (shader != lastShader)
|
if (shader != lastShader)
|
||||||
{
|
{
|
||||||
// Index des uniformes dans le shader
|
// Index of uniforms in the shader
|
||||||
shaderUniforms = GetShaderUniforms(shader);
|
shaderUniforms = GetShaderUniforms(shader);
|
||||||
|
|
||||||
// Couleur ambiante de la scène
|
// Ambiant color of the scene
|
||||||
shader->SendColor(shaderUniforms->sceneAmbient, sceneData.ambientColor);
|
shader->SendColor(shaderUniforms->sceneAmbient, sceneData.ambientColor);
|
||||||
// Position de la caméra
|
// Position of the camera
|
||||||
shader->SendVector(shaderUniforms->eyePosition, sceneData.viewer->GetEyePosition());
|
shader->SendVector(shaderUniforms->eyePosition, sceneData.viewer->GetEyePosition());
|
||||||
|
|
||||||
lastShader = shader;
|
lastShader = shader;
|
||||||
|
|
@ -521,7 +612,7 @@ namespace Nz
|
||||||
const IndexBuffer* indexBuffer = meshData.indexBuffer;
|
const IndexBuffer* indexBuffer = meshData.indexBuffer;
|
||||||
const VertexBuffer* vertexBuffer = meshData.vertexBuffer;
|
const VertexBuffer* vertexBuffer = meshData.vertexBuffer;
|
||||||
|
|
||||||
// Gestion du draw call avant la boucle de rendu
|
// Handle draw call before rendering loop
|
||||||
Renderer::DrawCall drawFunc;
|
Renderer::DrawCall drawFunc;
|
||||||
Renderer::DrawCallInstanced instancedDrawFunc;
|
Renderer::DrawCallInstanced instancedDrawFunc;
|
||||||
unsigned int indexCount;
|
unsigned int indexCount;
|
||||||
|
|
@ -544,12 +635,12 @@ namespace Nz
|
||||||
|
|
||||||
if (instancing)
|
if (instancing)
|
||||||
{
|
{
|
||||||
// On calcule le nombre d'instances que l'on pourra afficher cette fois-ci (Selon la taille du buffer d'instancing)
|
// We compute the number of instances that we will be able to draw this time (depending on the instancing buffer size)
|
||||||
VertexBuffer* instanceBuffer = Renderer::GetInstanceBuffer();
|
VertexBuffer* instanceBuffer = Renderer::GetInstanceBuffer();
|
||||||
instanceBuffer->SetVertexDeclaration(VertexDeclaration::Get(VertexLayout_Matrix4));
|
instanceBuffer->SetVertexDeclaration(VertexDeclaration::Get(VertexLayout_Matrix4));
|
||||||
|
|
||||||
// Avec l'instancing, impossible de sélectionner les lumières pour chaque objet
|
// With instancing, impossible to select the lights for each object
|
||||||
// Du coup, il n'est activé que pour les lumières directionnelles
|
// So, it's only activated for directional lights
|
||||||
unsigned int lightCount = m_renderQueue.directionalLights.size();
|
unsigned int lightCount = m_renderQueue.directionalLights.size();
|
||||||
unsigned int lightIndex = 0;
|
unsigned int lightIndex = 0;
|
||||||
RendererComparison oldDepthFunc = Renderer::GetDepthFunc();
|
RendererComparison oldDepthFunc = Renderer::GetDepthFunc();
|
||||||
|
|
@ -564,10 +655,10 @@ namespace Nz
|
||||||
|
|
||||||
if (pass == 1)
|
if (pass == 1)
|
||||||
{
|
{
|
||||||
// Pour additionner le résultat des calculs de lumière
|
// To add the result of light computations
|
||||||
// Aucune chance d'interférer avec les paramètres du matériau car nous ne rendons que les objets opaques
|
// We won't interfeer with materials parameters because we only render opaques objects
|
||||||
// (Autrement dit, sans blending)
|
// (A.K.A., without blending)
|
||||||
// Quant à la fonction de profondeur, elle ne doit être appliquée que la première fois
|
// About the depth function, it must be applied only the first time
|
||||||
Renderer::Enable(RendererParameter_Blend, true);
|
Renderer::Enable(RendererParameter_Blend, true);
|
||||||
Renderer::SetBlendFunc(BlendFunc_One, BlendFunc_One);
|
Renderer::SetBlendFunc(BlendFunc_One, BlendFunc_One);
|
||||||
Renderer::SetDepthFunc(RendererComparison_Equal);
|
Renderer::SetDepthFunc(RendererComparison_Equal);
|
||||||
|
|
@ -577,30 +668,30 @@ namespace Nz
|
||||||
for (unsigned int i = 0; i < NAZARA_GRAPHICS_MAX_LIGHT_PER_PASS; ++i)
|
for (unsigned int i = 0; i < NAZARA_GRAPHICS_MAX_LIGHT_PER_PASS; ++i)
|
||||||
SendLightUniforms(shader, shaderUniforms->lightUniforms, lightIndex++, shaderUniforms->lightOffset * i, freeTextureUnit + i);
|
SendLightUniforms(shader, shaderUniforms->lightUniforms, lightIndex++, shaderUniforms->lightOffset * i, freeTextureUnit + i);
|
||||||
|
|
||||||
// Et on passe à l'affichage
|
// And we give them to draw
|
||||||
drawFunc(meshData.primitiveMode, 0, indexCount);
|
drawFunc(meshData.primitiveMode, 0, indexCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
const Matrix4f* instanceMatrices = &instances[0];
|
const Matrix4f* instanceMatrices = &instances[0];
|
||||||
unsigned int instanceCount = instances.size();
|
unsigned int instanceCount = instances.size();
|
||||||
unsigned int maxInstanceCount = instanceBuffer->GetVertexCount(); // Le nombre maximum d'instances en une fois
|
unsigned int maxInstanceCount = instanceBuffer->GetVertexCount(); // Maximum number of instance in one batch
|
||||||
|
|
||||||
while (instanceCount > 0)
|
while (instanceCount > 0)
|
||||||
{
|
{
|
||||||
// On calcule le nombre d'instances que l'on pourra afficher cette fois-ci (Selon la taille du buffer d'instancing)
|
// We compute the number of instances that we will be able to draw this time (depending on the instancing buffer size)
|
||||||
unsigned int renderedInstanceCount = std::min(instanceCount, maxInstanceCount);
|
unsigned int renderedInstanceCount = std::min(instanceCount, maxInstanceCount);
|
||||||
instanceCount -= renderedInstanceCount;
|
instanceCount -= renderedInstanceCount;
|
||||||
|
|
||||||
// On remplit l'instancing buffer avec nos matrices world
|
// We fill the instancing buffer with our world matrices
|
||||||
instanceBuffer->Fill(instanceMatrices, 0, renderedInstanceCount, true);
|
instanceBuffer->Fill(instanceMatrices, 0, renderedInstanceCount, true);
|
||||||
instanceMatrices += renderedInstanceCount;
|
instanceMatrices += renderedInstanceCount;
|
||||||
|
|
||||||
// Et on affiche
|
// And we draw
|
||||||
instancedDrawFunc(renderedInstanceCount, meshData.primitiveMode, 0, indexCount);
|
instancedDrawFunc(renderedInstanceCount, meshData.primitiveMode, 0, indexCount);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// On n'oublie pas de désactiver le blending pour ne pas interférer sur le reste du rendu
|
// We don't forget to disable the blending to avoid to interfeer with the rest of the rendering
|
||||||
Renderer::Enable(RendererParameter_Blend, false);
|
Renderer::Enable(RendererParameter_Blend, false);
|
||||||
Renderer::SetDepthFunc(oldDepthFunc);
|
Renderer::SetDepthFunc(oldDepthFunc);
|
||||||
}
|
}
|
||||||
|
|
@ -617,7 +708,7 @@ namespace Nz
|
||||||
|
|
||||||
Renderer::SetMatrix(MatrixType_World, matrix);
|
Renderer::SetMatrix(MatrixType_World, matrix);
|
||||||
unsigned int lightIndex = 0;
|
unsigned int lightIndex = 0;
|
||||||
RendererComparison oldDepthFunc = Renderer::GetDepthFunc(); // Dans le cas où nous aurions à le changer
|
RendererComparison oldDepthFunc = Renderer::GetDepthFunc(); // In the case where we have to change it
|
||||||
|
|
||||||
unsigned int passCount = (lightCount == 0) ? 1 : (lightCount - 1) / NAZARA_GRAPHICS_MAX_LIGHT_PER_PASS + 1;
|
unsigned int passCount = (lightCount == 0) ? 1 : (lightCount - 1) / NAZARA_GRAPHICS_MAX_LIGHT_PER_PASS + 1;
|
||||||
for (unsigned int pass = 0; pass < passCount; ++pass)
|
for (unsigned int pass = 0; pass < passCount; ++pass)
|
||||||
|
|
@ -626,10 +717,10 @@ namespace Nz
|
||||||
|
|
||||||
if (pass == 1)
|
if (pass == 1)
|
||||||
{
|
{
|
||||||
// Pour additionner le résultat des calculs de lumière
|
// To add the result of light computations
|
||||||
// Aucune chance d'interférer avec les paramètres du matériau car nous ne rendons que les objets opaques
|
// We won't interfeer with materials parameters because we only render opaques objects
|
||||||
// (Autrement dit, sans blending)
|
// (A.K.A., without blending)
|
||||||
// Quant à la fonction de profondeur, elle ne doit être appliquée que la première fois
|
// About the depth function, it must be applied only the first time
|
||||||
Renderer::Enable(RendererParameter_Blend, true);
|
Renderer::Enable(RendererParameter_Blend, true);
|
||||||
Renderer::SetBlendFunc(BlendFunc_One, BlendFunc_One);
|
Renderer::SetBlendFunc(BlendFunc_One, BlendFunc_One);
|
||||||
Renderer::SetDepthFunc(RendererComparison_Equal);
|
Renderer::SetDepthFunc(RendererComparison_Equal);
|
||||||
|
|
@ -639,7 +730,7 @@ namespace Nz
|
||||||
for (unsigned int i = 0; i < NAZARA_GRAPHICS_MAX_LIGHT_PER_PASS; ++i)
|
for (unsigned int i = 0; i < NAZARA_GRAPHICS_MAX_LIGHT_PER_PASS; ++i)
|
||||||
SendLightUniforms(shader, shaderUniforms->lightUniforms, lightIndex++, shaderUniforms->lightOffset*i, freeTextureUnit + i);
|
SendLightUniforms(shader, shaderUniforms->lightUniforms, lightIndex++, shaderUniforms->lightOffset*i, freeTextureUnit + i);
|
||||||
|
|
||||||
// Et on passe à l'affichage
|
// And we draw
|
||||||
drawFunc(meshData.primitiveMode, 0, indexCount);
|
drawFunc(meshData.primitiveMode, 0, indexCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -649,9 +740,9 @@ namespace Nz
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Sans instancing, on doit effectuer un draw call pour chaque instance
|
// Without instancing, we must do a draw call for each instance
|
||||||
// Cela reste néanmoins plus rapide que l'instancing en dessous d'un certain nombre d'instances
|
// This may be faster than instancing under a certain number
|
||||||
// À cause du temps de modification du buffer d'instancing
|
// Due to the time to modify the instancing buffer
|
||||||
for (const Matrix4f& matrix : instances)
|
for (const Matrix4f& matrix : instances)
|
||||||
{
|
{
|
||||||
Renderer::SetMatrix(MatrixType_World, matrix);
|
Renderer::SetMatrix(MatrixType_World, matrix);
|
||||||
|
|
@ -664,13 +755,22 @@ namespace Nz
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Et on remet à zéro les données
|
// And we set the data back to zero
|
||||||
matEntry.enabled = false;
|
matEntry.enabled = false;
|
||||||
matEntry.instancingEnabled = false;
|
matEntry.instancingEnabled = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Draws transparent models
|
||||||
|
*
|
||||||
|
* \param sceneData Data of the scene
|
||||||
|
* \param layer Layer of the rendering
|
||||||
|
*
|
||||||
|
* \remark Produces a NazaraAssert is viewer is invalid
|
||||||
|
*/
|
||||||
|
|
||||||
void ForwardRenderTechnique::DrawTransparentModels(const SceneData& sceneData, ForwardRenderQueue::Layer& layer) const
|
void ForwardRenderTechnique::DrawTransparentModels(const SceneData& sceneData, ForwardRenderQueue::Layer& layer) const
|
||||||
{
|
{
|
||||||
NazaraAssert(sceneData.viewer, "Invalid viewer");
|
NazaraAssert(sceneData.viewer, "Invalid viewer");
|
||||||
|
|
@ -683,25 +783,25 @@ namespace Nz
|
||||||
{
|
{
|
||||||
const ForwardRenderQueue::TransparentModelData& modelData = layer.transparentModelData[index];
|
const ForwardRenderQueue::TransparentModelData& modelData = layer.transparentModelData[index];
|
||||||
|
|
||||||
// Matériau
|
// Material
|
||||||
const Material* material = modelData.material;
|
const Material* material = modelData.material;
|
||||||
|
|
||||||
// On commence par appliquer du matériau (et récupérer le shader ainsi activé)
|
// We begin to apply the material (and get the shader activated doing so)
|
||||||
UInt8 freeTextureUnit;
|
UInt8 freeTextureUnit;
|
||||||
const Shader* shader = material->Apply(0, 0, &freeTextureUnit);
|
const Shader* shader = material->Apply(0, 0, &freeTextureUnit);
|
||||||
|
|
||||||
// Les uniformes sont conservées au sein d'un programme, inutile de les renvoyer tant qu'il ne change pas
|
// Uniforms are conserved in our program, there's no point to send them back until they change
|
||||||
if (shader != lastShader)
|
if (shader != lastShader)
|
||||||
{
|
{
|
||||||
// Index des uniformes dans le shader
|
// Index of uniforms in the shader
|
||||||
shaderUniforms = GetShaderUniforms(shader);
|
shaderUniforms = GetShaderUniforms(shader);
|
||||||
|
|
||||||
// Couleur ambiante de la scène
|
// Ambiant color of the scene
|
||||||
shader->SendColor(shaderUniforms->sceneAmbient, sceneData.ambientColor);
|
shader->SendColor(shaderUniforms->sceneAmbient, sceneData.ambientColor);
|
||||||
// Position de la caméra
|
// Position of the camera
|
||||||
shader->SendVector(shaderUniforms->eyePosition, sceneData.viewer->GetEyePosition());
|
shader->SendVector(shaderUniforms->eyePosition, sceneData.viewer->GetEyePosition());
|
||||||
|
|
||||||
// On envoie les lumières directionnelles s'il y a (Les mêmes pour tous)
|
// We send the directional lights if there is one (same for all)
|
||||||
if (shaderUniforms->hasLightUniforms)
|
if (shaderUniforms->hasLightUniforms)
|
||||||
{
|
{
|
||||||
lightCount = std::min(m_renderQueue.directionalLights.size(), static_cast<decltype(m_renderQueue.directionalLights.size())>(NAZARA_GRAPHICS_MAX_LIGHT_PER_PASS));
|
lightCount = std::min(m_renderQueue.directionalLights.size(), static_cast<decltype(m_renderQueue.directionalLights.size())>(NAZARA_GRAPHICS_MAX_LIGHT_PER_PASS));
|
||||||
|
|
@ -720,7 +820,7 @@ namespace Nz
|
||||||
const IndexBuffer* indexBuffer = meshData.indexBuffer;
|
const IndexBuffer* indexBuffer = meshData.indexBuffer;
|
||||||
const VertexBuffer* vertexBuffer = meshData.vertexBuffer;
|
const VertexBuffer* vertexBuffer = meshData.vertexBuffer;
|
||||||
|
|
||||||
// Gestion du draw call avant la boucle de rendu
|
// Handle draw call before the rendering loop
|
||||||
Renderer::DrawCall drawFunc;
|
Renderer::DrawCall drawFunc;
|
||||||
unsigned int indexCount;
|
unsigned int indexCount;
|
||||||
|
|
||||||
|
|
@ -754,6 +854,13 @@ namespace Nz
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Gets the shader uniforms
|
||||||
|
* \return Uniforms of the shader
|
||||||
|
*
|
||||||
|
* \param shader Shader to get uniforms from
|
||||||
|
*/
|
||||||
|
|
||||||
const ForwardRenderTechnique::ShaderUniforms* ForwardRenderTechnique::GetShaderUniforms(const Shader* shader) const
|
const ForwardRenderTechnique::ShaderUniforms* ForwardRenderTechnique::GetShaderUniforms(const Shader* shader) const
|
||||||
{
|
{
|
||||||
auto it = m_shaderUniforms.find(shader);
|
auto it = m_shaderUniforms.find(shader);
|
||||||
|
|
@ -795,6 +902,12 @@ namespace Nz
|
||||||
return &it->second;
|
return &it->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Handle the invalidation of a shader
|
||||||
|
*
|
||||||
|
* \param shader Shader being invalidated
|
||||||
|
*/
|
||||||
|
|
||||||
void ForwardRenderTechnique::OnShaderInvalidated(const Shader* shader) const
|
void ForwardRenderTechnique::OnShaderInvalidated(const Shader* shader) const
|
||||||
{
|
{
|
||||||
m_shaderUniforms.erase(shader);
|
m_shaderUniforms.erase(shader);
|
||||||
|
|
|
||||||
|
|
@ -28,15 +28,29 @@
|
||||||
|
|
||||||
namespace Nz
|
namespace Nz
|
||||||
{
|
{
|
||||||
|
/*!
|
||||||
|
* \ingroup graphics
|
||||||
|
* \class Nz::Graphics
|
||||||
|
* \brief Graphics class that represents the module initializer of Graphics
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Initializes the Graphics module
|
||||||
|
* \return true if initialization is successful
|
||||||
|
*
|
||||||
|
* \remark Produces a NazaraNotice
|
||||||
|
* \remark Produces a NazaraError if one submodule failed
|
||||||
|
*/
|
||||||
|
|
||||||
bool Graphics::Initialize()
|
bool Graphics::Initialize()
|
||||||
{
|
{
|
||||||
if (s_moduleReferenceCounter > 0)
|
if (IsInitialized())
|
||||||
{
|
{
|
||||||
s_moduleReferenceCounter++;
|
s_moduleReferenceCounter++;
|
||||||
return true; // Déjà initialisé
|
return true; // Already initialized
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialisation des dépendances
|
// Initialisation of dependances
|
||||||
if (!Renderer::Initialize())
|
if (!Renderer::Initialize())
|
||||||
{
|
{
|
||||||
NazaraError("Failed to initialize Renderer module");
|
NazaraError("Failed to initialize Renderer module");
|
||||||
|
|
@ -45,7 +59,7 @@ namespace Nz
|
||||||
|
|
||||||
s_moduleReferenceCounter++;
|
s_moduleReferenceCounter++;
|
||||||
|
|
||||||
// Initialisation du module
|
// Initialisation of the module
|
||||||
CallOnExit onExit(Graphics::Uninitialize);
|
CallOnExit onExit(Graphics::Uninitialize);
|
||||||
|
|
||||||
if (!Material::Initialize())
|
if (!Material::Initialize())
|
||||||
|
|
@ -96,7 +110,7 @@ namespace Nz
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Loaders génériques
|
// Generic loaders
|
||||||
Loaders::RegisterMesh();
|
Loaders::RegisterMesh();
|
||||||
Loaders::RegisterTexture();
|
Loaders::RegisterTexture();
|
||||||
|
|
||||||
|
|
@ -133,43 +147,54 @@ namespace Nz
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Checks whether the module is initialized
|
||||||
|
* \return true if module is initialized
|
||||||
|
*/
|
||||||
|
|
||||||
bool Graphics::IsInitialized()
|
bool Graphics::IsInitialized()
|
||||||
{
|
{
|
||||||
return s_moduleReferenceCounter != 0;
|
return s_moduleReferenceCounter != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Uninitializes the Core module
|
||||||
|
*
|
||||||
|
* \remark Produces a NazaraNotice
|
||||||
|
*/
|
||||||
|
|
||||||
void Graphics::Uninitialize()
|
void Graphics::Uninitialize()
|
||||||
{
|
{
|
||||||
if (s_moduleReferenceCounter != 1)
|
if (s_moduleReferenceCounter != 1)
|
||||||
{
|
{
|
||||||
// Le module est soit encore utilisé, soit pas initialisé
|
// The module is still in use, or can not be uninitialized
|
||||||
if (s_moduleReferenceCounter > 1)
|
if (s_moduleReferenceCounter > 1)
|
||||||
s_moduleReferenceCounter--;
|
s_moduleReferenceCounter--;
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Libération du module
|
// Free of module
|
||||||
s_moduleReferenceCounter = 0;
|
s_moduleReferenceCounter = 0;
|
||||||
|
|
||||||
// Libération de l'atlas s'il vient de nous
|
// Free of atlas if it is ours
|
||||||
std::shared_ptr<AbstractAtlas> defaultAtlas = Font::GetDefaultAtlas();
|
std::shared_ptr<AbstractAtlas> defaultAtlas = Font::GetDefaultAtlas();
|
||||||
if (defaultAtlas && defaultAtlas->GetStorage() & DataStorage_Hardware)
|
if (defaultAtlas && defaultAtlas->GetStorage() & DataStorage_Hardware)
|
||||||
{
|
{
|
||||||
Font::SetDefaultAtlas(nullptr);
|
Font::SetDefaultAtlas(nullptr);
|
||||||
|
|
||||||
// La police par défaut peut faire vivre un atlas hardware après la libération du module (ce qui va être problématique)
|
// The default police can make live one hardware atlas after the free of a module (which could be problematic)
|
||||||
// du coup, si la police par défaut utilise un atlas hardware, on lui enlève.
|
// So, if the default police use a hardware atlas, we stole it.
|
||||||
// Je n'aime pas cette solution mais je n'en ai pas de meilleure sous la main pour l'instant
|
// I don't like this solution, but I don't have any better
|
||||||
if (!defaultAtlas.unique())
|
if (!defaultAtlas.unique())
|
||||||
{
|
{
|
||||||
// Encore au moins une police utilise l'atlas
|
// Still at least one police use the atlas
|
||||||
Font* defaultFont = Font::GetDefault();
|
Font* defaultFont = Font::GetDefault();
|
||||||
defaultFont->SetAtlas(nullptr);
|
defaultFont->SetAtlas(nullptr);
|
||||||
|
|
||||||
if (!defaultAtlas.unique())
|
if (!defaultAtlas.unique())
|
||||||
{
|
{
|
||||||
// Toujours pas seuls propriétaires ? Ah ben zut.
|
// Still not the only one to own it ? Then crap.
|
||||||
NazaraWarning("Default font atlas uses hardware storage and is still used");
|
NazaraWarning("Default font atlas uses hardware storage and is still used");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -195,7 +220,7 @@ namespace Nz
|
||||||
|
|
||||||
NazaraNotice("Uninitialized: Graphics module");
|
NazaraNotice("Uninitialized: Graphics module");
|
||||||
|
|
||||||
// Libération des dépendances
|
// Free of dependances
|
||||||
Renderer::Uninitialize();
|
Renderer::Uninitialize();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -9,11 +9,32 @@
|
||||||
|
|
||||||
namespace Nz
|
namespace Nz
|
||||||
{
|
{
|
||||||
|
/*!
|
||||||
|
* \ingroup graphics
|
||||||
|
* \class Nz::GuillotineTextureAtlas
|
||||||
|
* \brief Graphics class that represents an atlas texture for guillotine
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Gets the underlying data storage
|
||||||
|
* \return Value of the enumeration of the underlying data storage
|
||||||
|
*/
|
||||||
|
|
||||||
UInt32 GuillotineTextureAtlas::GetStorage() const
|
UInt32 GuillotineTextureAtlas::GetStorage() const
|
||||||
{
|
{
|
||||||
return DataStorage_Hardware;
|
return DataStorage_Hardware;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Resizes the image
|
||||||
|
* \return Updated texture
|
||||||
|
*
|
||||||
|
* \param oldImage Old image to resize
|
||||||
|
* \param size New image size
|
||||||
|
*
|
||||||
|
* \remark Produces a NazaraError if resize failed
|
||||||
|
*/
|
||||||
|
|
||||||
AbstractImage* GuillotineTextureAtlas::ResizeImage(AbstractImage* oldImage, const Vector2ui& size) const
|
AbstractImage* GuillotineTextureAtlas::ResizeImage(AbstractImage* oldImage, const Vector2ui& size) const
|
||||||
{
|
{
|
||||||
std::unique_ptr<Texture> newTexture(new Texture);
|
std::unique_ptr<Texture> newTexture(new Texture);
|
||||||
|
|
@ -23,8 +44,8 @@ namespace Nz
|
||||||
{
|
{
|
||||||
Texture* oldTexture = static_cast<Texture*>(oldImage);
|
Texture* oldTexture = static_cast<Texture*>(oldImage);
|
||||||
|
|
||||||
// Copie des anciennes données
|
// Copy of old data
|
||||||
///TODO: Copie de texture à texture
|
///TODO: Copy from texture to texture
|
||||||
Image image;
|
Image image;
|
||||||
if (!oldTexture->Download(&image))
|
if (!oldTexture->Download(&image))
|
||||||
{
|
{
|
||||||
|
|
@ -43,8 +64,7 @@ namespace Nz
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Si on arrive ici c'est que la taille demandée est trop grande pour la carte graphique
|
// If we are here, it is that the size is too big for the graphic card or we don't have enough
|
||||||
// ou que nous manquons de mémoire
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,16 +7,43 @@
|
||||||
|
|
||||||
namespace Nz
|
namespace Nz
|
||||||
{
|
{
|
||||||
|
/*!
|
||||||
|
* \ingroup graphics
|
||||||
|
* \class Nz::InstancedRenderable
|
||||||
|
* \brief Graphics class that represents an instancer renderable
|
||||||
|
*
|
||||||
|
* \remark This class is abstract
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Destructs the object and calls OnInstancedRenderableRelease
|
||||||
|
*
|
||||||
|
* \see OnInstancedRenderableRelease
|
||||||
|
*/
|
||||||
|
|
||||||
InstancedRenderable::~InstancedRenderable()
|
InstancedRenderable::~InstancedRenderable()
|
||||||
{
|
{
|
||||||
OnInstancedRenderableRelease(this);
|
OnInstancedRenderableRelease(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Culls the instanced if not in the frustum
|
||||||
|
* \return true If instanced is in the frustum
|
||||||
|
*
|
||||||
|
* \param frustum Symbolizing the field of view
|
||||||
|
* \param transformMatrix Matrix transformation for our object
|
||||||
|
*/
|
||||||
|
|
||||||
bool InstancedRenderable::Cull(const Frustumf& frustum, const InstanceData& instanceData) const
|
bool InstancedRenderable::Cull(const Frustumf& frustum, const InstanceData& instanceData) const
|
||||||
{
|
{
|
||||||
return frustum.Contains(instanceData.volume);
|
return frustum.Contains(instanceData.volume);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Gets the bounding volume
|
||||||
|
* \return Bounding volume of the instanced
|
||||||
|
*/
|
||||||
|
|
||||||
const BoundingVolumef& InstancedRenderable::GetBoundingVolume() const
|
const BoundingVolumef& InstancedRenderable::GetBoundingVolume() const
|
||||||
{
|
{
|
||||||
EnsureBoundingVolumeUpdated();
|
EnsureBoundingVolumeUpdated();
|
||||||
|
|
@ -24,11 +51,30 @@ namespace Nz
|
||||||
return m_boundingVolume;
|
return m_boundingVolume;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Invalidates data for instanced
|
||||||
|
*
|
||||||
|
* \param instanceData Pointer to data of instances
|
||||||
|
* \param flags Flags for the instances
|
||||||
|
*
|
||||||
|
* \remark Produces a NazaraAssert if instanceData is invalid
|
||||||
|
*/
|
||||||
|
|
||||||
void InstancedRenderable::InvalidateData(InstanceData* instanceData, UInt32 flags) const
|
void InstancedRenderable::InvalidateData(InstanceData* instanceData, UInt32 flags) const
|
||||||
{
|
{
|
||||||
|
NazaraAssert(instanceData, "Invalid instance data");
|
||||||
|
|
||||||
instanceData->flags |= flags;
|
instanceData->flags |= flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Updates the bounding volume
|
||||||
|
*
|
||||||
|
* \param instanceData Pointer to data of instances
|
||||||
|
*
|
||||||
|
* \remark Produces a NazaraAssert if instanceData is invalid
|
||||||
|
*/
|
||||||
|
|
||||||
void InstancedRenderable::UpdateBoundingVolume(InstanceData* instanceData) const
|
void InstancedRenderable::UpdateBoundingVolume(InstanceData* instanceData) const
|
||||||
{
|
{
|
||||||
NazaraAssert(instanceData, "Invalid instance data");
|
NazaraAssert(instanceData, "Invalid instance data");
|
||||||
|
|
@ -37,6 +83,14 @@ namespace Nz
|
||||||
instanceData->volume.Update(instanceData->transformMatrix);
|
instanceData->volume.Update(instanceData->transformMatrix);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Updates the instance data
|
||||||
|
*
|
||||||
|
* \param instanceData Pointer to data of instances
|
||||||
|
*
|
||||||
|
* \remark Produces a NazaraAssert if instanceData is invalid
|
||||||
|
*/
|
||||||
|
|
||||||
void InstancedRenderable::UpdateData(InstanceData* instanceData) const
|
void InstancedRenderable::UpdateData(InstanceData* instanceData) const
|
||||||
{
|
{
|
||||||
NazaraAssert(instanceData, "Invalid instance data");
|
NazaraAssert(instanceData, "Invalid instance data");
|
||||||
|
|
|
||||||
|
|
@ -13,11 +13,23 @@
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <Nazara/Graphics/Debug.hpp>
|
#include <Nazara/Graphics/Debug.hpp>
|
||||||
|
|
||||||
///TODO: Utilisation des UBOs
|
///TODO: Use of UBOs
|
||||||
///TODO: Scale ?
|
///TODO: Scale ?
|
||||||
|
|
||||||
namespace Nz
|
namespace Nz
|
||||||
{
|
{
|
||||||
|
/*!
|
||||||
|
* \ingroup graphics
|
||||||
|
* \class Nz::Light
|
||||||
|
* \brief Graphics class that represents a light
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Constructs a Light object with a type
|
||||||
|
*
|
||||||
|
* \param type Type of the light
|
||||||
|
*/
|
||||||
|
|
||||||
Light::Light(LightType type) :
|
Light::Light(LightType type) :
|
||||||
m_type(type),
|
m_type(type),
|
||||||
m_shadowMapFormat(PixelFormatType_Depth16),
|
m_shadowMapFormat(PixelFormatType_Depth16),
|
||||||
|
|
@ -34,6 +46,15 @@ namespace Nz
|
||||||
SetRadius(5.f);
|
SetRadius(5.f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Adds this light to the render queue
|
||||||
|
*
|
||||||
|
* \param renderQueue Queue to be added
|
||||||
|
* \param transformMatrix Matrix transformation for this light
|
||||||
|
*
|
||||||
|
* \remark Produces a NazaraError if type is invalid
|
||||||
|
*/
|
||||||
|
|
||||||
void Light::AddToRenderQueue(AbstractRenderQueue* renderQueue, const Matrix4f& transformMatrix) const
|
void Light::AddToRenderQueue(AbstractRenderQueue* renderQueue, const Matrix4f& transformMatrix) const
|
||||||
{
|
{
|
||||||
static Matrix4f biasMatrix(0.5f, 0.f, 0.f, 0.f,
|
static Matrix4f biasMatrix(0.5f, 0.f, 0.f, 0.f,
|
||||||
|
|
@ -100,16 +121,36 @@ namespace Nz
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Clones this light
|
||||||
|
* \return Pointer to newly allocated Light
|
||||||
|
*/
|
||||||
|
|
||||||
Light* Light::Clone() const
|
Light* Light::Clone() const
|
||||||
{
|
{
|
||||||
return new Light(*this);
|
return new Light(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Creates a default light
|
||||||
|
* \return Pointer to newly allocated light
|
||||||
|
*/
|
||||||
|
|
||||||
Light* Light::Create() const
|
Light* Light::Create() const
|
||||||
{
|
{
|
||||||
return new Light;
|
return new Light;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Culls the light if not in the frustum
|
||||||
|
* \return true If light is in the frustum
|
||||||
|
*
|
||||||
|
* \param frustum Symbolizing the field of view
|
||||||
|
* \param transformMatrix Matrix transformation for our object
|
||||||
|
*
|
||||||
|
* \remark Produces a NazaraError if type is invalid
|
||||||
|
*/
|
||||||
|
|
||||||
bool Light::Cull(const Frustumf& frustum, const Matrix4f& transformMatrix) const
|
bool Light::Cull(const Frustumf& frustum, const Matrix4f& transformMatrix) const
|
||||||
{
|
{
|
||||||
switch (m_type)
|
switch (m_type)
|
||||||
|
|
@ -128,6 +169,14 @@ namespace Nz
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Updates the bounding volume by a matrix
|
||||||
|
*
|
||||||
|
* \param transformMatrix Matrix transformation for our bounding volume
|
||||||
|
*
|
||||||
|
* \remark Produces a NazaraError if type is invalid
|
||||||
|
*/
|
||||||
|
|
||||||
void Light::UpdateBoundingVolume(const Matrix4f& transformMatrix)
|
void Light::UpdateBoundingVolume(const Matrix4f& transformMatrix)
|
||||||
{
|
{
|
||||||
switch (m_type)
|
switch (m_type)
|
||||||
|
|
@ -149,6 +198,12 @@ namespace Nz
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* \brief Makes the bounding volume of this light
|
||||||
|
*
|
||||||
|
* \remark Produces a NazaraError if type is invalid
|
||||||
|
*/
|
||||||
|
|
||||||
void Light::MakeBoundingVolume() const
|
void Light::MakeBoundingVolume() const
|
||||||
{
|
{
|
||||||
switch (m_type)
|
switch (m_type)
|
||||||
|
|
@ -166,19 +221,19 @@ namespace Nz
|
||||||
|
|
||||||
case LightType_Spot:
|
case LightType_Spot:
|
||||||
{
|
{
|
||||||
// On forme une boite sur l'origine
|
// We make a box center in the origin
|
||||||
Boxf box(Vector3f::Zero());
|
Boxf box(Vector3f::Zero());
|
||||||
|
|
||||||
// On calcule le reste des points
|
// We compute the other points
|
||||||
Vector3f base(Vector3f::Forward() * m_radius);
|
Vector3f base(Vector3f::Forward() * m_radius);
|
||||||
|
|
||||||
// Il nous faut maintenant le rayon du cercle projeté à cette distance
|
// Now we need the radius of the projected circle depending on the distance
|
||||||
// Tangente = Opposé/Adjaçent <=> Opposé = Adjaçent*Tangente
|
// Tangent = Opposite/Adjacent <=> Opposite = Adjacent * Tangent
|
||||||
float radius = m_radius * m_outerAngleTangent;
|
float radius = m_radius * m_outerAngleTangent;
|
||||||
Vector3f lExtend = Vector3f::Left() * radius;
|
Vector3f lExtend = Vector3f::Left() * radius;
|
||||||
Vector3f uExtend = Vector3f::Up() * radius;
|
Vector3f uExtend = Vector3f::Up() * radius;
|
||||||
|
|
||||||
// Et on ajoute ensuite les quatres extrémités de la pyramide
|
// And we add the four extremities of our pyramid
|
||||||
box.ExtendTo(base + lExtend + uExtend);
|
box.ExtendTo(base + lExtend + uExtend);
|
||||||
box.ExtendTo(base + lExtend - uExtend);
|
box.ExtendTo(base + lExtend - uExtend);
|
||||||
box.ExtendTo(base - lExtend + uExtend);
|
box.ExtendTo(base - lExtend + uExtend);
|
||||||
|
|
@ -194,6 +249,10 @@ namespace Nz
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Updates the shadow map
|
||||||
|
*/
|
||||||
|
|
||||||
void Light::UpdateShadowMap() const
|
void Light::UpdateShadowMap() const
|
||||||
{
|
{
|
||||||
if (m_shadowCastingEnabled)
|
if (m_shadowCastingEnabled)
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||||
|
|
||||||
#ifndef NAZARA_RENDERER_OPENGL
|
#ifndef NAZARA_RENDERER_OPENGL
|
||||||
#define NAZARA_RENDERER_OPENGL // Nécessaire pour inclure les headers OpenGL
|
#define NAZARA_RENDERER_OPENGL // Mandatory to include the OpenGL headers
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <Nazara/Graphics/Material.hpp>
|
#include <Nazara/Graphics/Material.hpp>
|
||||||
|
|
@ -36,6 +36,17 @@ namespace Nz
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \ingroup graphics
|
||||||
|
* \class Nz::Material
|
||||||
|
* \brief Graphics class that represents a material
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Checks whether the parameters for the material are correct
|
||||||
|
* \return true If parameters are valid
|
||||||
|
*/
|
||||||
|
|
||||||
bool MaterialParams::IsValid() const
|
bool MaterialParams::IsValid() const
|
||||||
{
|
{
|
||||||
if (!UberShaderLibrary::Has(shaderName))
|
if (!UberShaderLibrary::Has(shaderName))
|
||||||
|
|
@ -44,6 +55,15 @@ namespace Nz
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Applies shader to the material
|
||||||
|
* \return Constant pointer to the shader
|
||||||
|
*
|
||||||
|
* \param shaderFlags Flags for the shader
|
||||||
|
* \param textureUnit Unit for the texture GL_TEXTURE"i"
|
||||||
|
* \param lastUsedUnit Optional argument to get the last texture unit
|
||||||
|
*/
|
||||||
|
|
||||||
const Shader* Material::Apply(UInt32 shaderFlags, UInt8 textureUnit, UInt8* lastUsedUnit) const
|
const Shader* Material::Apply(UInt32 shaderFlags, UInt8 textureUnit, UInt8* lastUsedUnit) const
|
||||||
{
|
{
|
||||||
const ShaderInstance& instance = m_shaders[shaderFlags];
|
const ShaderInstance& instance = m_shaders[shaderFlags];
|
||||||
|
|
@ -123,6 +143,13 @@ namespace Nz
|
||||||
return instance.shader;
|
return instance.shader;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Builds the material from parameters
|
||||||
|
*
|
||||||
|
* \param matData Data information for the material
|
||||||
|
* \param matParams Parameters for the material
|
||||||
|
*/
|
||||||
|
|
||||||
void Material::BuildFromParameters(const ParameterList& matData, const MaterialParams& matParams)
|
void Material::BuildFromParameters(const ParameterList& matData, const MaterialParams& matParams)
|
||||||
{
|
{
|
||||||
Color color;
|
Color color;
|
||||||
|
|
@ -283,6 +310,10 @@ namespace Nz
|
||||||
SetShader(matParams.shaderName);
|
SetShader(matParams.shaderName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Resets the material, cleans everything
|
||||||
|
*/
|
||||||
|
|
||||||
void Material::Reset()
|
void Material::Reset()
|
||||||
{
|
{
|
||||||
OnMaterialReset(this);
|
OnMaterialReset(this);
|
||||||
|
|
@ -319,9 +350,15 @@ namespace Nz
|
||||||
SetShader("Basic");
|
SetShader("Basic");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Copies the other material
|
||||||
|
*
|
||||||
|
* \param material Material to copy into this
|
||||||
|
*/
|
||||||
|
|
||||||
void Material::Copy(const Material& material)
|
void Material::Copy(const Material& material)
|
||||||
{
|
{
|
||||||
// Copie des états de base
|
// Copy of base states
|
||||||
m_alphaTestEnabled = material.m_alphaTestEnabled;
|
m_alphaTestEnabled = material.m_alphaTestEnabled;
|
||||||
m_alphaThreshold = material.m_alphaThreshold;
|
m_alphaThreshold = material.m_alphaThreshold;
|
||||||
m_ambientColor = material.m_ambientColor;
|
m_ambientColor = material.m_ambientColor;
|
||||||
|
|
@ -337,7 +374,7 @@ namespace Nz
|
||||||
m_states = material.m_states;
|
m_states = material.m_states;
|
||||||
m_transformEnabled = material.m_transformEnabled;
|
m_transformEnabled = material.m_transformEnabled;
|
||||||
|
|
||||||
// Copie des références de texture
|
// Copy of reference to the textures
|
||||||
m_alphaMap = material.m_alphaMap;
|
m_alphaMap = material.m_alphaMap;
|
||||||
m_depthMaterial = material.m_depthMaterial;
|
m_depthMaterial = material.m_depthMaterial;
|
||||||
m_diffuseMap = material.m_diffuseMap;
|
m_diffuseMap = material.m_diffuseMap;
|
||||||
|
|
@ -347,10 +384,16 @@ namespace Nz
|
||||||
m_specularMap = material.m_specularMap;
|
m_specularMap = material.m_specularMap;
|
||||||
m_uberShader = material.m_uberShader;
|
m_uberShader = material.m_uberShader;
|
||||||
|
|
||||||
// On copie les instances de shader par la même occasion
|
// We copy the instances of the shader too
|
||||||
std::memcpy(&m_shaders[0], &material.m_shaders[0], (ShaderFlags_Max + 1) * sizeof(ShaderInstance));
|
std::memcpy(&m_shaders[0], &material.m_shaders[0], (ShaderFlags_Max + 1) * sizeof(ShaderInstance));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Generates the shader based on flag
|
||||||
|
*
|
||||||
|
* \param flags Flag for the shaer
|
||||||
|
*/
|
||||||
|
|
||||||
void Material::GenerateShader(UInt32 flags) const
|
void Material::GenerateShader(UInt32 flags) const
|
||||||
{
|
{
|
||||||
ParameterList list;
|
ParameterList list;
|
||||||
|
|
@ -396,6 +439,13 @@ namespace Nz
|
||||||
#undef CacheUniform
|
#undef CacheUniform
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Initializes the material librairies
|
||||||
|
* \return true If successful
|
||||||
|
*
|
||||||
|
* \remark Produces a NazaraError if the material library failed to be initialized
|
||||||
|
*/
|
||||||
|
|
||||||
bool Material::Initialize()
|
bool Material::Initialize()
|
||||||
{
|
{
|
||||||
if (!MaterialLibrary::Initialize())
|
if (!MaterialLibrary::Initialize())
|
||||||
|
|
@ -462,6 +512,10 @@ namespace Nz
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Uninitializes the material librairies
|
||||||
|
*/
|
||||||
|
|
||||||
void Material::Uninitialize()
|
void Material::Uninitialize()
|
||||||
{
|
{
|
||||||
s_defaultMaterial.Reset();
|
s_defaultMaterial.Reset();
|
||||||
|
|
|
||||||
|
|
@ -12,11 +12,26 @@
|
||||||
|
|
||||||
namespace Nz
|
namespace Nz
|
||||||
{
|
{
|
||||||
|
/*!
|
||||||
|
* \ingroup graphics
|
||||||
|
* \class Nz::Model
|
||||||
|
* \brief Graphics class that represents a model
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Constructs a ModelParameters object by default
|
||||||
|
*/
|
||||||
|
|
||||||
ModelParameters::ModelParameters()
|
ModelParameters::ModelParameters()
|
||||||
{
|
{
|
||||||
material.shaderName = "PhongLighting";
|
material.shaderName = "PhongLighting";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Checks whether the parameters for the model are correct
|
||||||
|
* \return true If parameters are valid
|
||||||
|
*/
|
||||||
|
|
||||||
bool ModelParameters::IsValid() const
|
bool ModelParameters::IsValid() const
|
||||||
{
|
{
|
||||||
if (loadMaterials && !material.IsValid())
|
if (loadMaterials && !material.IsValid())
|
||||||
|
|
@ -25,6 +40,10 @@ namespace Nz
|
||||||
return mesh.IsValid();
|
return mesh.IsValid();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Constructs a Model object by default
|
||||||
|
*/
|
||||||
|
|
||||||
Model::Model() :
|
Model::Model() :
|
||||||
m_matCount(0),
|
m_matCount(0),
|
||||||
m_skin(0),
|
m_skin(0),
|
||||||
|
|
@ -32,11 +51,24 @@ namespace Nz
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Destructs the object and calls Reset
|
||||||
|
*
|
||||||
|
* \see Reset
|
||||||
|
*/
|
||||||
|
|
||||||
Model::~Model()
|
Model::~Model()
|
||||||
{
|
{
|
||||||
Reset();
|
Reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Adds this model to the render queue
|
||||||
|
*
|
||||||
|
* \param renderQueue Queue to be added
|
||||||
|
* \param instanceData Data used for this instance
|
||||||
|
*/
|
||||||
|
|
||||||
void Model::AddToRenderQueue(AbstractRenderQueue* renderQueue, const InstanceData& instanceData) const
|
void Model::AddToRenderQueue(AbstractRenderQueue* renderQueue, const InstanceData& instanceData) const
|
||||||
{
|
{
|
||||||
unsigned int submeshCount = m_mesh->GetSubMeshCount();
|
unsigned int submeshCount = m_mesh->GetSubMeshCount();
|
||||||
|
|
@ -54,6 +86,17 @@ namespace Nz
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Gets the material of the named submesh
|
||||||
|
* \return Pointer to the current material
|
||||||
|
*
|
||||||
|
* \param subMeshName Name of the subMesh
|
||||||
|
*
|
||||||
|
* \remark Produces a NazaraError with NAZARA_GRAPHICS_SAFE if there is no mesh
|
||||||
|
* \remark Produces a NazaraError if there is no subMesh with that name
|
||||||
|
* \remark Produces a NazaraError if material is invalid
|
||||||
|
*/
|
||||||
|
|
||||||
Material* Model::GetMaterial(const String& subMeshName) const
|
Material* Model::GetMaterial(const String& subMeshName) const
|
||||||
{
|
{
|
||||||
#if NAZARA_GRAPHICS_SAFE
|
#if NAZARA_GRAPHICS_SAFE
|
||||||
|
|
@ -81,6 +124,15 @@ namespace Nz
|
||||||
return m_materials[m_skin * m_matCount + matIndex];
|
return m_materials[m_skin * m_matCount + matIndex];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Gets the material by index
|
||||||
|
* \return Pointer to the current material
|
||||||
|
*
|
||||||
|
* \param matIndex Index of the material
|
||||||
|
*
|
||||||
|
* \remark Produces a NazaraError if index is invalid
|
||||||
|
*/
|
||||||
|
|
||||||
Material* Model::GetMaterial(unsigned int matIndex) const
|
Material* Model::GetMaterial(unsigned int matIndex) const
|
||||||
{
|
{
|
||||||
#if NAZARA_GRAPHICS_SAFE
|
#if NAZARA_GRAPHICS_SAFE
|
||||||
|
|
@ -94,6 +146,18 @@ namespace Nz
|
||||||
return m_materials[m_skin * m_matCount + matIndex];
|
return m_materials[m_skin * m_matCount + matIndex];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Gets the material by index of the named submesh
|
||||||
|
* \return Pointer to the current material
|
||||||
|
*
|
||||||
|
* \param skinIndex Index of the skin
|
||||||
|
* \param subMeshName Name of the subMesh
|
||||||
|
*
|
||||||
|
* \remark Produces a NazaraError with NAZARA_GRAPHICS_SAFE defined if skinIndex is invalid
|
||||||
|
* \remark Produces a NazaraError if there is no subMesh with that name
|
||||||
|
* \remark Produces a NazaraError if material index is invalid
|
||||||
|
*/
|
||||||
|
|
||||||
Material* Model::GetMaterial(unsigned int skinIndex, const String& subMeshName) const
|
Material* Model::GetMaterial(unsigned int skinIndex, const String& subMeshName) const
|
||||||
{
|
{
|
||||||
#if NAZARA_GRAPHICS_SAFE
|
#if NAZARA_GRAPHICS_SAFE
|
||||||
|
|
@ -121,6 +185,17 @@ namespace Nz
|
||||||
return m_materials[skinIndex * m_matCount + matIndex];
|
return m_materials[skinIndex * m_matCount + matIndex];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Gets the material by index with skin
|
||||||
|
* \return Pointer to the current material
|
||||||
|
*
|
||||||
|
* \param skinIndex Index of the skin
|
||||||
|
* \param matIndex Index of the material
|
||||||
|
*
|
||||||
|
* \remark Produces a NazaraError with NAZARA_GRAPHICS_SAFE defined if skinIndex is invalid
|
||||||
|
* \remark Produces a NazaraError with NAZARA_GRAPHICS_SAFE defined if matIndex is invalid
|
||||||
|
*/
|
||||||
|
|
||||||
Material* Model::GetMaterial(unsigned int skinIndex, unsigned int matIndex) const
|
Material* Model::GetMaterial(unsigned int skinIndex, unsigned int matIndex) const
|
||||||
{
|
{
|
||||||
#if NAZARA_GRAPHICS_SAFE
|
#if NAZARA_GRAPHICS_SAFE
|
||||||
|
|
@ -140,46 +215,100 @@ namespace Nz
|
||||||
return m_materials[skinIndex * m_matCount + matIndex];
|
return m_materials[skinIndex * m_matCount + matIndex];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Gets the number of materials
|
||||||
|
* \return Current number of materials
|
||||||
|
*/
|
||||||
|
|
||||||
unsigned int Model::GetMaterialCount() const
|
unsigned int Model::GetMaterialCount() const
|
||||||
{
|
{
|
||||||
return m_matCount;
|
return m_matCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Gets the mesh
|
||||||
|
* \return Current mesh
|
||||||
|
*/
|
||||||
|
|
||||||
Mesh* Model::GetMesh() const
|
Mesh* Model::GetMesh() const
|
||||||
{
|
{
|
||||||
return m_mesh;
|
return m_mesh;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Gets the skin
|
||||||
|
* \return Current skin
|
||||||
|
*/
|
||||||
|
|
||||||
unsigned int Model::GetSkin() const
|
unsigned int Model::GetSkin() const
|
||||||
{
|
{
|
||||||
return m_skin;
|
return m_skin;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Gets the number of skins
|
||||||
|
* \return Current number of skins
|
||||||
|
*/
|
||||||
|
|
||||||
unsigned int Model::GetSkinCount() const
|
unsigned int Model::GetSkinCount() const
|
||||||
{
|
{
|
||||||
return m_skinCount;
|
return m_skinCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Checks whether the model is animated
|
||||||
|
* \return false
|
||||||
|
*/
|
||||||
|
|
||||||
bool Model::IsAnimated() const
|
bool Model::IsAnimated() const
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Loads the model from file
|
||||||
|
* \return true if loading is successful
|
||||||
|
*
|
||||||
|
* \param filePath Path to the file
|
||||||
|
* \param params Parameters for the model
|
||||||
|
*/
|
||||||
|
|
||||||
bool Model::LoadFromFile(const String& filePath, const ModelParameters& params)
|
bool Model::LoadFromFile(const String& filePath, const ModelParameters& params)
|
||||||
{
|
{
|
||||||
return ModelLoader::LoadFromFile(this, filePath, params);
|
return ModelLoader::LoadFromFile(this, filePath, params);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Loads the model from memory
|
||||||
|
* \return true if loading is successful
|
||||||
|
*
|
||||||
|
* \param data Raw memory
|
||||||
|
* \param size Size of the memory
|
||||||
|
* \param params Parameters for the model
|
||||||
|
*/
|
||||||
|
|
||||||
bool Model::LoadFromMemory(const void* data, std::size_t size, const ModelParameters& params)
|
bool Model::LoadFromMemory(const void* data, std::size_t size, const ModelParameters& params)
|
||||||
{
|
{
|
||||||
return ModelLoader::LoadFromMemory(this, data, size, params);
|
return ModelLoader::LoadFromMemory(this, data, size, params);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Loads the model from stream
|
||||||
|
* \return true if loading is successful
|
||||||
|
*
|
||||||
|
* \param stream Stream to the model
|
||||||
|
* \param params Parameters for the model
|
||||||
|
*/
|
||||||
|
|
||||||
bool Model::LoadFromStream(Stream& stream, const ModelParameters& params)
|
bool Model::LoadFromStream(Stream& stream, const ModelParameters& params)
|
||||||
{
|
{
|
||||||
return ModelLoader::LoadFromStream(this, stream, params);
|
return ModelLoader::LoadFromStream(this, stream, params);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Resets the model, cleans everything
|
||||||
|
*/
|
||||||
|
|
||||||
void Model::Reset()
|
void Model::Reset()
|
||||||
{
|
{
|
||||||
m_matCount = 0;
|
m_matCount = 0;
|
||||||
|
|
@ -192,6 +321,17 @@ namespace Nz
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Sets the material of the named submesh
|
||||||
|
* \return true If successful
|
||||||
|
*
|
||||||
|
* \param subMeshName Name of the subMesh
|
||||||
|
* \param material Pointer to the material
|
||||||
|
*
|
||||||
|
* \remark Produces a NazaraError if there is no subMesh with that name
|
||||||
|
* \remark Produces a NazaraError if material index is invalid
|
||||||
|
*/
|
||||||
|
|
||||||
bool Model::SetMaterial(const String& subMeshName, Material* material)
|
bool Model::SetMaterial(const String& subMeshName, Material* material)
|
||||||
{
|
{
|
||||||
SubMesh* subMesh = m_mesh->GetSubMesh(subMeshName);
|
SubMesh* subMesh = m_mesh->GetSubMesh(subMeshName);
|
||||||
|
|
@ -218,6 +358,16 @@ namespace Nz
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Sets the material by index
|
||||||
|
* \return true If successful
|
||||||
|
*
|
||||||
|
* \param matIndex Index of the material
|
||||||
|
* \param material Pointer to the material
|
||||||
|
*
|
||||||
|
* \remark Produces a NazaraError with if NAZARA_GRAPHICS_SAFE defined index is invalid
|
||||||
|
*/
|
||||||
|
|
||||||
void Model::SetMaterial(unsigned int matIndex, Material* material)
|
void Model::SetMaterial(unsigned int matIndex, Material* material)
|
||||||
{
|
{
|
||||||
#if NAZARA_GRAPHICS_SAFE
|
#if NAZARA_GRAPHICS_SAFE
|
||||||
|
|
@ -236,6 +386,19 @@ namespace Nz
|
||||||
m_materials[index] = Material::GetDefault();
|
m_materials[index] = Material::GetDefault();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Sets the material by index of the named submesh
|
||||||
|
* \return true If successful
|
||||||
|
*
|
||||||
|
* \param skinIndex Index of the skin
|
||||||
|
* \param subMeshName Name of the subMesh
|
||||||
|
* \param material Pointer to the material
|
||||||
|
*
|
||||||
|
* \remark Produces a NazaraError with NAZARA_GRAPHICS_SAFE defined if skinIndex is invalid
|
||||||
|
* \remark Produces a NazaraError if there is no subMesh with that name
|
||||||
|
* \remark Produces a NazaraError if material index is invalid
|
||||||
|
*/
|
||||||
|
|
||||||
bool Model::SetMaterial(unsigned int skinIndex, const String& subMeshName, Material* material)
|
bool Model::SetMaterial(unsigned int skinIndex, const String& subMeshName, Material* material)
|
||||||
{
|
{
|
||||||
#if NAZARA_GRAPHICS_SAFE
|
#if NAZARA_GRAPHICS_SAFE
|
||||||
|
|
@ -270,6 +433,18 @@ namespace Nz
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Sets the material by index with skin
|
||||||
|
* \return true If successful
|
||||||
|
*
|
||||||
|
* \param skinIndex Index of the skin
|
||||||
|
* \param matIndex Index of the material
|
||||||
|
* \param material Pointer to the material
|
||||||
|
*
|
||||||
|
* \remark Produces a NazaraError with NAZARA_GRAPHICS_SAFE defined if skinIndex is invalid
|
||||||
|
* \remark Produces a NazaraError with NAZARA_GRAPHICS_SAFE defined if matIndex is invalid
|
||||||
|
*/
|
||||||
|
|
||||||
void Model::SetMaterial(unsigned int skinIndex, unsigned int matIndex, Material* material)
|
void Model::SetMaterial(unsigned int skinIndex, unsigned int matIndex, Material* material)
|
||||||
{
|
{
|
||||||
#if NAZARA_GRAPHICS_SAFE
|
#if NAZARA_GRAPHICS_SAFE
|
||||||
|
|
@ -294,6 +469,14 @@ namespace Nz
|
||||||
m_materials[index] = Material::GetDefault();
|
m_materials[index] = Material::GetDefault();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Sets the mesh
|
||||||
|
*
|
||||||
|
* \param pointer to the mesh
|
||||||
|
*
|
||||||
|
* \remark Produces a NazaraError with NAZARA_GRAPHICS_SAFE defined if mesh is invalid
|
||||||
|
*/
|
||||||
|
|
||||||
void Model::SetMesh(Mesh* mesh)
|
void Model::SetMesh(Mesh* mesh)
|
||||||
{
|
{
|
||||||
#if NAZARA_GRAPHICS_SAFE
|
#if NAZARA_GRAPHICS_SAFE
|
||||||
|
|
@ -323,6 +506,14 @@ namespace Nz
|
||||||
InvalidateBoundingVolume();
|
InvalidateBoundingVolume();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Sets the skin
|
||||||
|
*
|
||||||
|
* \param skin Skin to use
|
||||||
|
*
|
||||||
|
* \remark Produces a NazaraError if skin is invalid
|
||||||
|
*/
|
||||||
|
|
||||||
void Model::SetSkin(unsigned int skin)
|
void Model::SetSkin(unsigned int skin)
|
||||||
{
|
{
|
||||||
#if NAZARA_GRAPHICS_SAFE
|
#if NAZARA_GRAPHICS_SAFE
|
||||||
|
|
@ -336,6 +527,14 @@ namespace Nz
|
||||||
m_skin = skin;
|
m_skin = skin;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Sets the number of skins
|
||||||
|
*
|
||||||
|
* \param skinCount Number of skins
|
||||||
|
*
|
||||||
|
* \remark Produces a NazaraError if skinCount equals zero
|
||||||
|
*/
|
||||||
|
|
||||||
void Model::SetSkinCount(unsigned int skinCount)
|
void Model::SetSkinCount(unsigned int skinCount)
|
||||||
{
|
{
|
||||||
#if NAZARA_GRAPHICS_SAFE
|
#if NAZARA_GRAPHICS_SAFE
|
||||||
|
|
@ -350,6 +549,10 @@ namespace Nz
|
||||||
m_skinCount = skinCount;
|
m_skinCount = skinCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* \brief Makes the bounding volume of this billboard
|
||||||
|
*/
|
||||||
|
|
||||||
void Model::MakeBoundingVolume() const
|
void Model::MakeBoundingVolume() const
|
||||||
{
|
{
|
||||||
if (m_mesh)
|
if (m_mesh)
|
||||||
|
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue