(Scene) Added CreateNode and Clear methods
Former-commit-id: de92f4a4be45e5cbd1d2d83191300e0b46764f0e
This commit is contained in:
parent
cf12552358
commit
0a7711d85b
|
|
@ -84,7 +84,7 @@ int main()
|
||||||
// Ensuite, nous allons rajouter un modèle à notre scène.
|
// Ensuite, nous allons rajouter un modèle à notre scène.
|
||||||
// Les modèles représentent, globalement, tout ce qui est visible en trois dimensions.
|
// Les modèles représentent, globalement, tout ce qui est visible en trois dimensions.
|
||||||
// Nous choisirons ici un vaisseau spatial (Quoi de mieux pour une scène spatiale ?)
|
// Nous choisirons ici un vaisseau spatial (Quoi de mieux pour une scène spatiale ?)
|
||||||
NzModel spaceship;
|
NzModel* spaceship = scene.CreateNode<NzModel>(); // Création depuis la scène
|
||||||
|
|
||||||
// Une structure permettant de paramétrer le chargement des modèles
|
// Une structure permettant de paramétrer le chargement des modèles
|
||||||
NzModelParameters params;
|
NzModelParameters params;
|
||||||
|
|
@ -101,7 +101,7 @@ int main()
|
||||||
|
|
||||||
// On charge ensuite le modèle depuis son fichier
|
// On charge ensuite le modèle depuis son fichier
|
||||||
// Le moteur va charger le fichier et essayer de retrouver les fichiers associés (comme les matériaux, textures, ...)
|
// Le moteur va charger le fichier et essayer de retrouver les fichiers associés (comme les matériaux, textures, ...)
|
||||||
if (!spaceship.LoadFromFile("resources/Spaceship/spaceship.obj", params))
|
if (!spaceship->LoadFromFile("resources/Spaceship/spaceship.obj", params))
|
||||||
{
|
{
|
||||||
std::cout << "Failed to load spaceship" << std::endl;
|
std::cout << "Failed to load spaceship" << std::endl;
|
||||||
std::getchar();
|
std::getchar();
|
||||||
|
|
@ -111,7 +111,7 @@ int main()
|
||||||
|
|
||||||
// Nous voulons afficher quelques statistiques relatives au modèle, comme le nombre de sommets et de triangles
|
// Nous voulons afficher quelques statistiques relatives au modèle, comme le nombre de sommets et de triangles
|
||||||
// Pour cela, nous devons accéder au mesh (maillage 3D)
|
// Pour cela, nous devons accéder au mesh (maillage 3D)
|
||||||
NzMesh* mesh = spaceship.GetMesh();
|
NzMesh* mesh = spaceship->GetMesh();
|
||||||
|
|
||||||
std::cout << mesh->GetVertexCount() << " sommets" << std::endl;
|
std::cout << mesh->GetVertexCount() << " sommets" << std::endl;
|
||||||
std::cout << mesh->GetTriangleCount() << " triangles" << std::endl;
|
std::cout << mesh->GetTriangleCount() << " triangles" << std::endl;
|
||||||
|
|
@ -119,7 +119,7 @@ int main()
|
||||||
// En revanche, le format OBJ ne précise pas l'utilisation d'une normal map, nous devons donc la charger manuellement
|
// En revanche, le format OBJ ne précise pas l'utilisation d'une normal map, nous devons donc la charger manuellement
|
||||||
// Pour commencer on récupère le matériau du mesh, celui-ci en possède plusieurs mais celui qui nous intéresse,
|
// Pour commencer on récupère le matériau du mesh, celui-ci en possède plusieurs mais celui qui nous intéresse,
|
||||||
// celui de la coque, est le second (Cela est bien entendu lié au modèle en lui-même)
|
// celui de la coque, est le second (Cela est bien entendu lié au modèle en lui-même)
|
||||||
NzMaterial* material = spaceship.GetMaterial(1);
|
NzMaterial* material = spaceship->GetMaterial(1);
|
||||||
|
|
||||||
// On lui indique ensuite le chemin vers la normal map
|
// On lui indique ensuite le chemin vers la normal map
|
||||||
if (!material->SetNormalMap("resources/Spaceship/Texture/normal.png"))
|
if (!material->SetNormalMap("resources/Spaceship/Texture/normal.png"))
|
||||||
|
|
@ -129,10 +129,6 @@ int main()
|
||||||
std::cout << "Failed to load normal map" << std::endl;
|
std::cout << "Failed to load normal map" << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Il nous reste à attacher le modèle à la scène, ce qui se fait simplement via cet appel
|
|
||||||
spaceship.SetParent(scene);
|
|
||||||
// Et voilà, à partir de maintenant le modèle fait partie de la hiérarchie de la scène, et sera donc rendu avec cette dernière
|
|
||||||
|
|
||||||
// Nous avons besoin également d'une caméra, pour des raisons évidentes, celle-ci sera à l'écart du modèle
|
// Nous avons besoin également d'une caméra, pour des raisons évidentes, celle-ci sera à l'écart du modèle
|
||||||
// regardant dans sa direction.
|
// regardant dans sa direction.
|
||||||
|
|
||||||
|
|
@ -164,18 +160,15 @@ int main()
|
||||||
// -PointLight: Lumière située à un endroit précis, envoyant de la lumière finie dans toutes les directions
|
// -PointLight: Lumière située à un endroit précis, envoyant de la lumière finie dans toutes les directions
|
||||||
// -SpotLight: Lumière située à un endroit précis, envoyant de la lumière vers un endroit donné, avec un angle de diffusion
|
// -SpotLight: Lumière située à un endroit précis, envoyant de la lumière vers un endroit donné, avec un angle de diffusion
|
||||||
|
|
||||||
// Nous choisissons une lumière directionnelle représentant la nébuleuse de notre skybox
|
// Nous créons une lumière directionnelle pour représenter la nébuleuse de notre skybox
|
||||||
NzLight nebulaLight(nzLightType_Directional);
|
NzLight* nebulaLight = scene.CreateNode<NzLight>(nzLightType_Directional);
|
||||||
|
|
||||||
// Il nous faut ensuite configurer la lumière
|
// Il nous faut ensuite configurer la lumière
|
||||||
// Pour commencer, sa couleur, la nébuleuse étant d'une couleur jaune, j'ai choisi ces valeurs
|
// Pour commencer, sa couleur, la nébuleuse étant d'une couleur jaune, j'ai choisi ces valeurs
|
||||||
nebulaLight.SetColor(NzColor(255, 182, 90));
|
nebulaLight->SetColor(NzColor(255, 182, 90));
|
||||||
|
|
||||||
// Nous appliquons ensuite une rotation de sorte que la lumière dans la même direction que la nébuleuse
|
// Nous appliquons ensuite une rotation de sorte que la lumière dans la même direction que la nébuleuse
|
||||||
nebulaLight.SetRotation(NzEulerAnglesf(0.f, 102.f, 0.f));
|
nebulaLight->SetRotation(NzEulerAnglesf(0.f, 102.f, 0.f));
|
||||||
|
|
||||||
// Et nous ajoutons la lumière à la scène
|
|
||||||
nebulaLight.SetParent(scene);
|
|
||||||
|
|
||||||
// Nous allons maintenant créer la fenêtre, dans laquelle nous ferons nos rendus
|
// Nous allons maintenant créer la fenêtre, dans laquelle nous ferons nos rendus
|
||||||
// Celle-ci demande des paramètres plus complexes
|
// Celle-ci demande des paramètres plus complexes
|
||||||
|
|
|
||||||
|
|
@ -10,12 +10,14 @@
|
||||||
#include <Nazara/Prerequesites.hpp>
|
#include <Nazara/Prerequesites.hpp>
|
||||||
#include <Nazara/Core/Clock.hpp>
|
#include <Nazara/Core/Clock.hpp>
|
||||||
#include <Nazara/Core/Color.hpp>
|
#include <Nazara/Core/Color.hpp>
|
||||||
|
#include <Nazara/Core/String.hpp>
|
||||||
#include <Nazara/Core/Updatable.hpp>
|
#include <Nazara/Core/Updatable.hpp>
|
||||||
#include <Nazara/Graphics/AbstractBackground.hpp>
|
#include <Nazara/Graphics/AbstractBackground.hpp>
|
||||||
#include <Nazara/Graphics/AbstractRenderTechnique.hpp>
|
#include <Nazara/Graphics/AbstractRenderTechnique.hpp>
|
||||||
#include <Nazara/Graphics/SceneRoot.hpp>
|
#include <Nazara/Graphics/SceneRoot.hpp>
|
||||||
#include <Nazara/Math/Frustum.hpp>
|
#include <Nazara/Math/Frustum.hpp>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <unordered_map>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
class NzAbstractRenderQueue;
|
class NzAbstractRenderQueue;
|
||||||
|
|
@ -37,6 +39,12 @@ class NAZARA_API NzScene
|
||||||
|
|
||||||
void AddToVisibilityList(NzUpdatable* object);
|
void AddToVisibilityList(NzUpdatable* object);
|
||||||
|
|
||||||
|
template<typename T, typename... Args> T* CreateNode(Args&&... args);
|
||||||
|
template<typename T, typename... Args> T* CreateNode(const NzString& name, Args&&... args);
|
||||||
|
template<typename T, typename... Args> T* CreateNode(const NzString& name, const NzString& templateNodeName);
|
||||||
|
|
||||||
|
void Clear();
|
||||||
|
|
||||||
void Cull();
|
void Cull();
|
||||||
void Draw();
|
void Draw();
|
||||||
|
|
||||||
|
|
@ -78,10 +86,13 @@ class NAZARA_API NzScene
|
||||||
operator const NzSceneNode&() const;
|
operator const NzSceneNode&() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
bool RegisterSceneNode(const NzString& name, NzSceneNode* node);
|
||||||
void RecursiveFrustumCull(NzAbstractRenderQueue* renderQueue, const NzFrustumf& frustum, NzNode* node);
|
void RecursiveFrustumCull(NzAbstractRenderQueue* renderQueue, const NzFrustumf& frustum, NzNode* node);
|
||||||
|
|
||||||
mutable std::unique_ptr<NzAbstractBackground> m_background;
|
mutable std::unique_ptr<NzAbstractBackground> m_background;
|
||||||
mutable std::unique_ptr<NzAbstractRenderTechnique> m_renderTechnique;
|
mutable std::unique_ptr<NzAbstractRenderTechnique> m_renderTechnique;
|
||||||
|
std::unordered_map<NzString, NzSceneNode*> m_nodeMap;
|
||||||
|
std::vector<std::unique_ptr<NzSceneNode>> m_nodes;
|
||||||
std::vector<NzUpdatable*> m_updateList;
|
std::vector<NzUpdatable*> m_updateList;
|
||||||
std::vector<NzUpdatable*> m_visibleUpdateList;
|
std::vector<NzUpdatable*> m_visibleUpdateList;
|
||||||
NzClock m_updateClock;
|
NzClock m_updateClock;
|
||||||
|
|
@ -96,4 +107,6 @@ class NAZARA_API NzScene
|
||||||
unsigned int m_updatePerSecond;
|
unsigned int m_updatePerSecond;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#include <Nazara/Graphics/Scene.inl>
|
||||||
|
|
||||||
#endif // NAZARA_SCENE_HPP
|
#endif // NAZARA_SCENE_HPP
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,107 @@
|
||||||
|
// Copyright (C) 2015 Jérôme Leclercq
|
||||||
|
// This file is part of the "Nazara Engine - Graphics module"
|
||||||
|
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||||
|
|
||||||
|
#include <Nazara/Graphics/Enums.hpp>
|
||||||
|
#include <Nazara/Graphics/Debug.hpp>
|
||||||
|
|
||||||
|
///TODO: Déplacer vers SceneNode et exposer
|
||||||
|
|
||||||
|
// Pour être sûr que ce code soit à jour
|
||||||
|
static_assert(nzSceneNodeType_Max == 6, "Please update the code below");
|
||||||
|
|
||||||
|
class NzLight;
|
||||||
|
class NzModel;
|
||||||
|
class NzParticleEmitter;
|
||||||
|
class NzSceneRoot;
|
||||||
|
class NzSprite;
|
||||||
|
class NzTextSprite;
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
constexpr nzSceneNodeType NzImplGetType()
|
||||||
|
{
|
||||||
|
return nzSceneNodeType_User;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<>
|
||||||
|
inline constexpr nzSceneNodeType NzImplGetType<NzLight>()
|
||||||
|
{
|
||||||
|
return nzSceneNodeType_Light;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<>
|
||||||
|
inline constexpr nzSceneNodeType NzImplGetType<NzModel>()
|
||||||
|
{
|
||||||
|
return nzSceneNodeType_Model;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<>
|
||||||
|
inline constexpr nzSceneNodeType NzImplGetType<NzParticleEmitter>()
|
||||||
|
{
|
||||||
|
return nzSceneNodeType_ParticleEmitter;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<>
|
||||||
|
inline constexpr nzSceneNodeType NzImplGetType<NzSceneRoot>()
|
||||||
|
{
|
||||||
|
return nzSceneNodeType_Root;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<>
|
||||||
|
inline constexpr nzSceneNodeType NzImplGetType<NzSprite>()
|
||||||
|
{
|
||||||
|
return nzSceneNodeType_Sprite;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<>
|
||||||
|
inline constexpr nzSceneNodeType NzImplGetType<NzTextSprite>()
|
||||||
|
{
|
||||||
|
return nzSceneNodeType_TextSprite;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<typename T, typename... Args>
|
||||||
|
T* NzScene::CreateNode(Args&&... args)
|
||||||
|
{
|
||||||
|
std::unique_ptr<T> node(new T(std::forward<Args>(args)...));
|
||||||
|
if (!RegisterSceneNode(NzString(), node.get()))
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
return node.release();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T, typename... Args>
|
||||||
|
T* NzScene::CreateNode(const NzString& name, Args&&... args)
|
||||||
|
{
|
||||||
|
std::unique_ptr<T> node(new T(std::forward<Args>(args)...));
|
||||||
|
if (!RegisterSceneNode(name, node.get()))
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
return node.release();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T, typename... Args>
|
||||||
|
T* NzScene::CreateNode(const NzString& name, const NzString& templateNodeName)
|
||||||
|
{
|
||||||
|
auto it = m_nodeMap.find(templateNodeName);
|
||||||
|
if (it == m_nodeMap.end())
|
||||||
|
{
|
||||||
|
NazaraError("Node \"" + templateNodeName + "\" is not registred");
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
NzSceneNode* sceneNode = it->second;
|
||||||
|
if (NzImplGetType<T>() != sceneNode->GetSceneNodeType())
|
||||||
|
{
|
||||||
|
NazaraError("Scene node type of T (" + NzString::Number(NzImplGetType<T>()) + ") doesn't match template scene node type (" + NzString::Number(sceneNode->GetSceneNodeType()) + ")");
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<T> node(static_cast<T*>(sceneNode)->Copy());
|
||||||
|
if (!RegisterSceneNode(name, node.get()))
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
return node.release();
|
||||||
|
}
|
||||||
|
|
||||||
|
#include <Nazara/Graphics/DebugOff.hpp>
|
||||||
|
|
@ -29,6 +29,12 @@ void NzScene::AddToVisibilityList(NzUpdatable* object)
|
||||||
m_visibleUpdateList.push_back(object);
|
m_visibleUpdateList.push_back(object);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NzScene::Clear()
|
||||||
|
{
|
||||||
|
m_nodeMap.clear();
|
||||||
|
m_nodes.clear();
|
||||||
|
}
|
||||||
|
|
||||||
void NzScene::Cull()
|
void NzScene::Cull()
|
||||||
{
|
{
|
||||||
#if NAZARA_GRAPHICS_SAFE
|
#if NAZARA_GRAPHICS_SAFE
|
||||||
|
|
@ -48,8 +54,6 @@ void NzScene::Cull()
|
||||||
RecursiveFrustumCull(renderQueue, m_viewer->GetFrustum(), &m_root);
|
RecursiveFrustumCull(renderQueue, m_viewer->GetFrustum(), &m_root);
|
||||||
|
|
||||||
///TODO: Occlusion culling
|
///TODO: Occlusion culling
|
||||||
|
|
||||||
///TODO: Light culling
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void NzScene::Draw()
|
void NzScene::Draw()
|
||||||
|
|
@ -77,7 +81,7 @@ void NzScene::Draw()
|
||||||
if (m_renderTechniqueRanking > 0)
|
if (m_renderTechniqueRanking > 0)
|
||||||
{
|
{
|
||||||
m_renderTechnique.reset(NzRenderTechniques::GetByRanking(m_renderTechniqueRanking-1, &m_renderTechniqueRanking));
|
m_renderTechnique.reset(NzRenderTechniques::GetByRanking(m_renderTechniqueRanking-1, &m_renderTechniqueRanking));
|
||||||
NazaraError("Render technique \"" + oldName + "\" failed, fallback to \"" + m_renderTechnique->GetName() + '"');
|
NazaraError("Render technique \"" + oldName + "\" failed, falling back to \"" + m_renderTechnique->GetName() + '"');
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -333,6 +337,25 @@ NzScene::operator const NzSceneNode&() const
|
||||||
return m_root;
|
return m_root;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool NzScene::RegisterSceneNode(const NzString& name, NzSceneNode* node)
|
||||||
|
{
|
||||||
|
if (!name.IsEmpty())
|
||||||
|
{
|
||||||
|
if (m_nodeMap.find(name) != m_nodeMap.end())
|
||||||
|
{
|
||||||
|
NazaraError("Node " + name + " is already registred");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_nodeMap[name] = node;
|
||||||
|
}
|
||||||
|
|
||||||
|
node->SetParent(m_root, true);
|
||||||
|
|
||||||
|
m_nodes.emplace_back(node);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void NzScene::RecursiveFrustumCull(NzAbstractRenderQueue* renderQueue, const NzFrustumf& frustum, NzNode* node)
|
void NzScene::RecursiveFrustumCull(NzAbstractRenderQueue* renderQueue, const NzFrustumf& frustum, NzNode* node)
|
||||||
{
|
{
|
||||||
for (NzNode* child : node->GetChilds())
|
for (NzNode* child : node->GetChilds())
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue